[Scummvm-cvs-logs] SF.net SVN: scummvm: [20437] scummvm/trunk/kyra

vinterstum at users.sourceforge.net vinterstum at users.sourceforge.net
Wed Feb 8 23:39:03 CET 2006


Revision: 20437
Author:   vinterstum
Date:     2006-02-08 23:37:19 -0800 (Wed, 08 Feb 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm?rev=20437&view=rev

Log Message:
-----------
Moved tons of code out of kyra.cpp, and removed three redundant functions (two stubs
to sound functions, and one duplicate function (one with 'posion' in the name, one with 'poison').

The bulk of the moved code is moved to the newly created files items.cpp, scene.cpp and
sequences.cpp

 

Modified Paths:
--------------
    scummvm/trunk/kyra/animator.cpp
    scummvm/trunk/kyra/animator.h
    scummvm/trunk/kyra/gui.cpp
    scummvm/trunk/kyra/kyra.cpp
    scummvm/trunk/kyra/kyra.h
    scummvm/trunk/kyra/module.mk
    scummvm/trunk/kyra/resource.cpp
    scummvm/trunk/kyra/screen.cpp
    scummvm/trunk/kyra/screen.h
    scummvm/trunk/kyra/script_v1.cpp
    scummvm/trunk/kyra/seqplayer.cpp
    scummvm/trunk/kyra/sound.cpp
    scummvm/trunk/kyra/staticres.cpp
    scummvm/trunk/kyra/text.cpp

Added Paths:
-----------
    scummvm/trunk/kyra/items.cpp
    scummvm/trunk/kyra/scene.cpp
    scummvm/trunk/kyra/sequences.cpp
Modified: scummvm/trunk/kyra/animator.cpp
===================================================================
--- scummvm/trunk/kyra/animator.cpp	2006-02-09 04:58:21 UTC (rev 20436)
+++ scummvm/trunk/kyra/animator.cpp	2006-02-09 07:37:19 UTC (rev 20437)
@@ -65,6 +65,48 @@
 	}
 }
 
+void ScreenAnimator::initAnimStateList() {
+	AnimObject *animStates = _screenObjects;
+	animStates[0].index = 0;
+	animStates[0].active = 1;
+	animStates[0].flags = 0x800;
+	animStates[0].background = _vm->_shapes[2];
+	animStates[0].rectSize = _screen->getRectSize(4, 48);
+	animStates[0].width = 4;
+	animStates[0].height = 48;
+	animStates[0].width2 = 4;
+	animStates[0].height2 = 3;
+	
+	for (int i = 1; i <= 4; ++i) {
+		animStates[i].index = i;
+		animStates[i].active = 0;
+		animStates[i].flags = 0x800;
+		animStates[i].background = _vm->_shapes[3];
+		animStates[i].rectSize = _screen->getRectSize(4, 64);
+		animStates[i].width = 4;
+		animStates[i].height = 48;
+		animStates[i].width2 = 4;
+		animStates[i].height2 = 3;
+	}
+	
+	for (int i = 5; i < 16; ++i) {
+		animStates[i].index = i;
+		animStates[i].active = 0;
+		animStates[i].flags = 0;
+	}
+	
+	for (int i = 16; i < 28; ++i) {
+		animStates[i].index = i;
+		animStates[i].flags = 0;
+		animStates[i].background = _vm->_shapes[349+i];
+		animStates[i].rectSize = _screen->getRectSize(3, 24);
+		animStates[i].width = 3;
+		animStates[i].height = 16;
+		animStates[i].width2 = 0;
+		animStates[i].height2 = 0;
+	}
+}
+
 void ScreenAnimator::preserveAllBackgrounds() {
 	debug(9, "ScreenAnimator::preserveAllBackgrounds()");
 	uint8 curPage = _screen->_curPage;

Modified: scummvm/trunk/kyra/animator.h
===================================================================
--- scummvm/trunk/kyra/animator.h	2006-02-09 04:58:21 UTC (rev 20436)
+++ scummvm/trunk/kyra/animator.h	2006-02-09 07:37:19 UTC (rev 20437)
@@ -62,6 +62,7 @@
 	AnimObject *items() { return _items; }
 	AnimObject *sprites() { return _sprites; }
 
+	void initAnimStateList();
 	void preserveAllBackgrounds();
 	void flagAllObjectsForBkgdChange();
 	void flagAllObjectsForRefresh();

Modified: scummvm/trunk/kyra/gui.cpp
===================================================================
--- scummvm/trunk/kyra/gui.cpp	2006-02-09 04:58:21 UTC (rev 20436)
+++ scummvm/trunk/kyra/gui.cpp	2006-02-09 07:37:19 UTC (rev 20437)
@@ -29,6 +29,14 @@
 #include "common/system.h"
 
 namespace Kyra {
+
+void KyraEngine::initMainButtonList() {
+	_buttonList = &_buttonData[0];
+	for (int i = 0; _buttonDataListPtr[i]; ++i) {
+		_buttonList = initButton(_buttonList, _buttonDataListPtr[i]);
+	}
+}
+
 Button *KyraEngine::initButton(Button *list, Button *newButton) {
 	if (!newButton)
 		return list;

Added: scummvm/trunk/kyra/items.cpp
===================================================================
--- scummvm/trunk/kyra/items.cpp	                        (rev 0)
+++ scummvm/trunk/kyra/items.cpp	2006-02-09 07:37:19 UTC (rev 20437)
@@ -0,0 +1,981 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "kyra/kyra.h"
+#include "kyra/seqplayer.h"
+#include "kyra/screen.h"
+#include "kyra/resource.h"
+#include "kyra/sound.h"
+#include "kyra/sprites.h"
+#include "kyra/wsamovie.h"
+#include "kyra/animator.h"
+#include "kyra/text.h"
+
+#include "common/system.h"
+#include "common/savefile.h"
+
+namespace Kyra {
+
+int KyraEngine::findDuplicateItemShape(int shape) {
+	static uint8 dupTable[] = {
+		0x48, 0x46, 0x49, 0x47, 0x4a, 0x46, 0x4b, 0x47,
+		0x4c, 0x46, 0x4d, 0x47, 0x5b, 0x5a, 0x5c, 0x5a,
+		0x5d, 0x5a, 0x5e, 0x5a, 0xFF, 0xFF
+	};
+
+	int i = 0;
+
+	while (dupTable[i] != 0xFF) {
+		if (dupTable[i] == shape)
+			return dupTable[i+1];
+		i += 2;
+	}
+	return -1;
+}
+
+void KyraEngine::addToNoDropRects(int x, int y, int w, int h) {
+	debug(9, "KyraEngine::addToNoDropRects(%d, %d, %d, %d)", x, y, w, h);
+	for (int rect = 0; rect < 11; ++rect) {
+		if (_noDropRects[rect].x == -1) {
+			_noDropRects[rect].x = x;
+			_noDropRects[rect].y = y;
+			_noDropRects[rect].x2 = x + w - 1;
+			_noDropRects[rect].y2 = y + h - 1;
+			break;
+		}
+	}
+}
+
+void KyraEngine::clearNoDropRects() {
+	debug(9, "KyraEngine::clearNoDropRects()");
+	memset(_noDropRects, -1, sizeof(_noDropRects));
+}
+
+byte KyraEngine::findFreeItemInScene(int scene) {
+	debug(9, "KyraEngine::findFreeItemInScene(%d)", scene);
+	assert(scene < _roomTableSize);
+	Room *room = &_roomTable[scene];
+	for (int i = 0; i < 12; ++i) {
+		if (room->itemsTable[i] == 0xFF)
+			return i;
+	}
+	return 0xFF;
+}
+
+byte KyraEngine::findItemAtPos(int x, int y) {
+	debug(9, "KyraEngine::findItemAtPos(%d, %d)", x, y);
+	assert(_currentCharacter->sceneId < _roomTableSize);
+	const uint8 *itemsTable = _roomTable[_currentCharacter->sceneId].itemsTable;
+	const uint16 *xposOffset = _roomTable[_currentCharacter->sceneId].itemsXPos;
+	const uint8 *yposOffset = _roomTable[_currentCharacter->sceneId].itemsYPos;
+	
+	int highestYPos = -1;
+	byte returnValue = 0xFF;
+	
+	for (int i = 0; i < 12; ++i) {
+		if (*itemsTable != 0xFF) {
+			int xpos = *xposOffset - 11;
+			int xpos2 = *xposOffset + 10;
+			if (x > xpos && x < xpos2) {
+				assert(*itemsTable < ARRAYSIZE(_itemTable));
+				int itemHeight = _itemTable[*itemsTable].height;
+				int ypos = *yposOffset + 3;
+				int ypos2 = ypos - itemHeight - 3;
+				
+				if (y > ypos2 && ypos > y) {
+					if (highestYPos <= ypos) {
+						returnValue = i;
+						highestYPos = ypos;
+					}
+				}
+			}
+		}
+		++xposOffset;
+		++yposOffset;
+		++itemsTable;
+	}
+	
+	return returnValue;
+}
+
+void KyraEngine::placeItemInGenericMapScene(int item, int index) {
+	debug(9, "KyraEngine::placeItemInGenericMapScene(%d, %d)", item, index);
+	static const uint16 itemMapSceneMinTable[] = {
+		0x0000, 0x0011, 0x006D, 0x0025, 0x00C7, 0x0000
+	};
+	static const uint16 itemMapSceneMaxTable[] = {
+		0x0010, 0x0024, 0x00C6, 0x006C, 0x00F5, 0x0000
+	};
+	
+	int minValue = itemMapSceneMinTable[index];
+	int maxValue = itemMapSceneMaxTable[index];
+	
+	while (true) {
+		int room = _rnd.getRandomNumberRng(minValue, maxValue);
+		assert(room < _roomTableSize);
+		int nameIndex = _roomTable[room].nameIndex;
+		bool placeItem = false;
+		
+		switch (nameIndex) {
+			case 0:  case 1:   case 2:   case 3:
+			case 4:  case 5:   case 6:   case 11:
+			case 12: case 16:  case 17:  case 20:
+			case 22: case 23:  case 25:  case 26:
+			case 27: case 31:  case 33:  case 34:
+			case 36: case 37:  case 58:  case 59:
+			case 60: case 61:  case 83:  case 84:
+			case 85: case 104: case 105: case 106:
+				placeItem = true;
+			break;
+			
+			case 51:
+				if (room != 46) {
+					placeItem = true;
+					break;
+				}		
+			default:
+				placeItem = false;
+			break;
+		}
+		
+		if (placeItem) {
+			Room *roomPtr = &_roomTable[room];
+			if (roomPtr->northExit == 0xFFFF && roomPtr->eastExit == 0xFFFF && roomPtr->southExit == 0xFFFF && roomPtr->westExit == 0xFFFF) {
+				placeItem = false;
+			} else if (_currentCharacter->sceneId == room) {
+				placeItem = false;
+			}
+		}
+		
+		if (placeItem) {
+			if (!processItemDrop(room, item, -1, -1, 2, 0))
+				continue;
+			break;
+		}
+	}
+}
+
+void KyraEngine::createMouseItem(int item) {
+	debug(9, "KyraEngine::createMouseItem(%d)", item);
+	_screen->hideMouse();
+	setMouseItem(item);
+	_itemInHand = item;
+	_screen->showMouse();
+}
+
+void KyraEngine::destroyMouseItem() {
+	debug(9, "KyraEngine::destroyMouseItem()");
+	_screen->hideMouse();
+	_screen->setMouseCursor(1, 1, _shapes[4]);
+	_itemInHand = -1;
+	_screen->showMouse();
+}
+
+void KyraEngine::setMouseItem(int item) {
+	debug(9, "KyraEngine::setMouseItem(%d)", item);
+	if (item == -1) {
+		_screen->setMouseCursor(1, 1, _shapes[10]);
+	} else {
+		_screen->setMouseCursor(8, 15, _shapes[220+item]);
+	}
+}
+
+void KyraEngine::wipeDownMouseItem(int xpos, int ypos) {
+	debug(9, "KyraEngine::wipeDownMouseItem(%d, %d)", xpos, ypos);
+	if (_itemInHand == -1)
+		return;
+	xpos -= 8;
+	ypos -= 15;
+	_screen->hideMouse();
+	_screen->backUpRect1(xpos, ypos);
+	int y = ypos;
+	int height = 16;
+	
+	while (height >= 0) {
+		_screen->restoreRect1(xpos, ypos);
+		_screen->setNewShapeHeight(_shapes[220+_itemInHand], height);
+		uint32 nextTime = _system->getMillis() + 1 * _tickLength;
+		_screen->drawShape(0, _shapes[220+_itemInHand], xpos, y, 0, 0);
+		_screen->updateScreen();
+		y += 2;
+		height -= 2;
+		while (_system->getMillis() < nextTime) {}
+	}	
+	_screen->restoreRect1(xpos, ypos);
+	_screen->resetShapeHeight(_shapes[220+_itemInHand]);
+	destroyMouseItem();
+	_screen->showMouse();
+}
+
+void KyraEngine::setupSceneItems() {
+	debug(9, "KyraEngine::setupSceneItems()");
+	uint16 sceneId = _currentCharacter->sceneId;
+	assert(sceneId < _roomTableSize);
+	Room *currentRoom = &_roomTable[sceneId];
+	for (int i = 0; i < 12; ++i) {
+		uint8 item = currentRoom->itemsTable[i];
+		if (item == 0xFF || !currentRoom->needInit[i]) {
+			continue;
+		}
+		
+		int xpos = 0;
+		int ypos = 0;
+		
+		if (currentRoom->itemsXPos[i] == 0xFFFF) {
+			xpos = currentRoom->itemsXPos[i] = _rnd.getRandomNumberRng(24, 296);
+			ypos = currentRoom->itemsYPos[i] = _rnd.getRandomNumberRng(_northExitHeight & 0xFF, 130);
+		} else {
+			xpos = currentRoom->itemsXPos[i];
+			ypos = currentRoom->itemsYPos[i];
+		}
+		
+		_lastProcessedItem = i;
+		
+		int stop = 0;
+		while (!stop) {
+			stop = processItemDrop(sceneId, item, xpos, ypos, 3, 0);
+			if (!stop) {
+				xpos = currentRoom->itemsXPos[i] = _rnd.getRandomNumberRng(24, 296);
+				ypos = currentRoom->itemsYPos[i] = _rnd.getRandomNumberRng(_northExitHeight & 0xFF, 130);
+				if (countItemsInScene(sceneId) >= 12) {
+					break;
+				}
+			} else {
+				currentRoom->needInit[i] = 0;
+			}
+		}
+	}
+}
+
+int KyraEngine::countItemsInScene(uint16 sceneId) {
+	debug(9, "KyraEngine::countItemsInScene(%d)", sceneId);
+	assert(sceneId < _roomTableSize);
+	Room *currentRoom = &_roomTable[sceneId];
+	
+	int items = 0;
+	
+	for (int i = 0; i < 12; ++i) {
+		if (currentRoom->itemsTable[i] != 0xFF) {
+			++items;
+		}
+	}
+	
+	return items;
+}
+
+int KyraEngine::processItemDrop(uint16 sceneId, uint8 item, int x, int y, int unk1, int unk2) {
+	debug(9, "KyraEngine::processItemDrop(%d, %d, %d, %d, %d, %d)", sceneId, item, x, y, unk1, unk2);
+	int freeItem = -1;
+	uint8 itemIndex = findItemAtPos(x, y);
+	if (unk1) {
+		itemIndex = 0xFF;
+	}
+	
+	if (itemIndex != 0xFF) {
+		exchangeItemWithMouseItem(sceneId, itemIndex);
+		return 0;
+	}
+	
+	assert(sceneId < _roomTableSize);
+	Room *currentRoom = &_roomTable[sceneId];
+	
+	if (unk1 != 3) {
+		for (int i = 0; i < 12; ++i) {
+			if (currentRoom->itemsTable[i] == 0xFF) {
+				freeItem = i;
+				break;
+			}
+		}
+	} else {
+		freeItem = _lastProcessedItem;
+	}
+
+	if (freeItem == -1) {
+		return 0;
+	}
+	
+	if (sceneId != _currentCharacter->sceneId) {
+		addItemToRoom(sceneId, item, freeItem, x, y);
+		return 1;
+	}
+	
+	int itemHeight = _itemTable[item].height;
+	_lastProcessedItemHeight = itemHeight;
+	
+	if (x == -1 && x == -1) {
+		x = _rnd.getRandomNumberRng(16, 304);
+		y = _rnd.getRandomNumberRng(_northExitHeight & 0xFF, 135);
+	}
+	
+	int xpos = x;
+	int ypos = y;
+	int destY = -1;
+	int destX = -1;
+	int running = 1;
+
+	while (running) {
+		if ((_northExitHeight & 0xFF) <= ypos) {
+			bool running2 = true;
+			
+			if (_screen->getDrawLayer(xpos, ypos) > 1) {
+				if (((_northExitHeight >> 8) & 0xFF) != ypos) {
+					running2 = false;
+				}
+			}
+			
+			if (_screen->getDrawLayer2(xpos, ypos, itemHeight) > 1) {
+				if (((_northExitHeight >> 8) & 0xFF) != ypos) {
+					running2 = false;
+				}
+			}
+			
+			if (!isDropable(xpos, ypos)) {
+				if (((_northExitHeight >> 8) & 0xFF) != ypos) {
+					running2 = false;
+				}
+			}
+			
+			int xpos2 = xpos;
+			int xpos3 = xpos;
+			
+			while (running2) {
+				if (isDropable(xpos2, ypos)) {
+					if (_screen->getDrawLayer2(xpos2, ypos, itemHeight) < 7) {
+						if (findItemAtPos(xpos2, ypos) == 0xFF) {
+							destX = xpos2;
+							destY = ypos;
+							running = 0;
+							running2 = false;
+						}
+					}
+				}
+				
+				if (isDropable(xpos3, ypos)) {
+					if (_screen->getDrawLayer2(xpos3, ypos, itemHeight) < 7) {
+						if (findItemAtPos(xpos3, ypos) == 0xFF) {
+							destX = xpos3;
+							destY = ypos;
+							running = 0;
+							running2 = false;
+						}
+					}
+				}
+				
+				if (!running2)
+					continue;
+				
+				xpos2 -= 2;
+				if (xpos2 < 16) {
+					xpos2 = 16;
+				}
+				
+				xpos3 += 2;
+				if (xpos3 > 304) {
+					xpos3 = 304;
+				}
+				
+				if (xpos2 > 16)
+					continue;
+				if (xpos3 < 304)
+					continue;
+				running2 = false;
+			}
+		}
+		
+		if (((_northExitHeight >> 8) & 0xFF) == ypos) {
+			running = 0;
+			destY -= _rnd.getRandomNumberRng(0, 3);
+			
+			if ((_northExitHeight & 0xFF) < destY) {
+				continue;
+			}
+			
+			destY = (_northExitHeight & 0xFF) + 1;
+			continue;
+		}		
+		ypos += 2;
+		if (((_northExitHeight >> 8) & 0xFF) >= ypos) {
+			continue;
+		}
+		ypos = (_northExitHeight >> 8) & 0xFF;
+	}
+	
+	if (destX == -1 || destY == -1) {
+		return 0;
+	}
+	
+	if (unk1 == 3) {
+		currentRoom->itemsXPos[freeItem] = destX;
+		currentRoom->itemsYPos[freeItem] = destY;
+		return 1;
+	}
+	
+	if (unk1 == 2) {
+		itemSpecialFX(x, y, item);
+	}
+	
+	if (unk1 == 0) {
+		destroyMouseItem();
+	}
+	
+	itemDropDown(x, y, destX, destY, freeItem, item);
+	
+	if (unk1 == 0 && unk2 != 0) {
+		assert(_itemList && _droppedList);
+		updateSentenceCommand(_itemList[item], _droppedList[0], 179);
+	}
+	
+	return 1;
+}
+
+void KyraEngine::exchangeItemWithMouseItem(uint16 sceneId, int itemIndex) {
+	debug(9, "KyraEngine::exchangeItemWithMouseItem(%d, %d)", sceneId, itemIndex);
+	_screen->hideMouse();
+	_animator->animRemoveGameItem(itemIndex);
+	assert(sceneId < _roomTableSize);
+	Room *currentRoom = &_roomTable[sceneId];
+	
+	int item = currentRoom->itemsTable[itemIndex];
+	currentRoom->itemsTable[itemIndex] = _itemInHand;
+	_itemInHand = item;
+	_animator->animAddGameItem(itemIndex, sceneId);
+	snd_playSoundEffect(53);
+	
+	setMouseItem(_itemInHand);
+	assert(_itemList && _takenList);
+	updateSentenceCommand(_itemList[_itemInHand], _takenList[1], 179);
+	_screen->showMouse();
+	clickEventHandler2();
+}
+
+void KyraEngine::addItemToRoom(uint16 sceneId, uint8 item, int itemIndex, int x, int y) {
+	debug(9, "KyraEngine::addItemToRoom(%d, %d, %d, %d, %d)", sceneId, item, itemIndex, x, y);
+	assert(sceneId < _roomTableSize);
+	Room *currentRoom = &_roomTable[sceneId];
+	currentRoom->itemsTable[itemIndex] = item;
+	currentRoom->itemsXPos[itemIndex] = x;
+	currentRoom->itemsYPos[itemIndex] = y;
+	currentRoom->needInit[itemIndex] = 1;
+}
+
+int KyraEngine::checkNoDropRects(int x, int y) {
+	debug(9, "KyraEngine::checkNoDropRects(%d, %d)", x, y);
+	if (_lastProcessedItemHeight < 1 || _lastProcessedItemHeight > 16) {
+		_lastProcessedItemHeight = 16;
+	}
+	if (_noDropRects[0].x == -1) {
+		return 0;
+	}
+	
+	for (int i = 0; i < 11; ++i) {
+		if (_noDropRects[i].x == -1) {
+			break;
+		}
+		
+		int xpos = _noDropRects[i].x;
+		int ypos = _noDropRects[i].y;
+		int xpos2 = _noDropRects[i].x2;
+		int ypos2 = _noDropRects[i].y2;
+		
+		if (xpos > x + 16)
+			continue;
+		if (xpos2 < x)
+			continue;
+		if (y < ypos)
+			continue;
+		if (ypos2 < y - _lastProcessedItemHeight)
+			continue;
+		return 1;
+	}
+	
+	return 0;
+}
+
+int KyraEngine::isDropable(int x, int y) {
+	debug(9, "KyraEngine::isDropable(%d, %d)", x, y);
+	x -= 8;
+	y -= 1;
+	
+	if (checkNoDropRects(x, y)) {
+		return 0;
+	}
+	
+	for (int xpos = x; xpos < x + 16; ++xpos) {
+		if (_screen->getShapeFlag1(xpos, y) == 0) {
+			return 0;
+		}
+	}	
+	return 1;
+}
+
+void KyraEngine::itemDropDown(int x, int y, int destX, int destY, byte freeItem, int item) {
+	debug(9, "KyraEngine::itemDropDown(%d, %d, %d, %d, %d, %d)", x, y, destX, destY, freeItem, item);
+	assert(_currentCharacter->sceneId < _roomTableSize);
+	Room *currentRoom = &_roomTable[_currentCharacter->sceneId];
+	if (x == destX && y == destY) {
+		currentRoom->itemsXPos[freeItem] = destX;
+		currentRoom->itemsYPos[freeItem] = destY;
+		currentRoom->itemsTable[freeItem] = item;
+		snd_playSoundEffect(0x32);
+		_animator->animAddGameItem(freeItem, _currentCharacter->sceneId);
+		return;
+	}
+	_screen->hideMouse();
+	if (y <= destY) {
+		int tempY = y;
+		int addY = 2;
+		int drawX = x - 8;
+		int drawY = 0;
+		
+		_screen->backUpRect0(drawX, y - 16);
+		
+		while (tempY < destY) {
+			_screen->restoreRect0(drawX, tempY - 16);
+			tempY += addY;
+			if (tempY > destY) {
+				tempY = destY;
+			}
+			++addY;
+			drawY = tempY - 16;
+			_screen->backUpRect0(drawX, drawY);
+			uint32 nextTime = _system->getMillis() + 1 * _tickLength;
+			_screen->drawShape(0, _shapes[220+item], drawX, drawY, 0, 0);
+			_screen->updateScreen();
+			while (_system->getMillis() < nextTime) {
+				if ((nextTime - _system->getMillis()) >= 10)
+					delay(10);
+			}
+		}
+		
+		bool skip = false;
+		if (x == destX) {
+			if (destY - y <= 16) {
+				skip = true;
+			}
+		}
+		
+		if (!skip) {
+			snd_playSoundEffect(0x47);
+			if (addY < 6)
+				addY = 6;
+			
+			int xDiff = (destX - x) << 4;
+			xDiff /= addY;
+			int startAddY = addY;
+			addY >>= 1;
+			if (destY - y <= 8) {
+				addY >>= 1;
+			}
+			addY = -addY;
+			int unkX = x << 4;
+			while (--startAddY) {
+				drawX = (unkX >> 4) - 8;
+				drawY = tempY - 16;
+				_screen->restoreRect0(drawX, drawY);
+				tempY += addY;
+				unkX += xDiff;
+				if (tempY > destY) {
+					tempY = destY;
+				}
+				++addY;
+				drawX = (unkX >> 4) - 8;
+				drawY = tempY - 16;
+				_screen->backUpRect0(drawX, drawY);
+				uint32 nextTime = _system->getMillis() + 1 * _tickLength;
+				_screen->drawShape(0, _shapes[220+item], drawX, drawY, 0, 0);
+				_screen->updateScreen();
+				while (_system->getMillis() < nextTime) {
+					if ((nextTime - _system->getMillis()) >= 10)
+						delay(10);
+				}
+			}
+			_screen->restoreRect0(drawX, drawY);
+		} else {
+			_screen->restoreRect0(drawX, tempY - 16);
+		}
+	}
+	currentRoom->itemsXPos[freeItem] = destX;
+	currentRoom->itemsYPos[freeItem] = destY;
+	currentRoom->itemsTable[freeItem] = item;
+	snd_playSoundEffect(0x32);
+	_animator->animAddGameItem(freeItem, _currentCharacter->sceneId);
+	_screen->showMouse();
+}
+
+void KyraEngine::dropItem(int unk1, int item, int x, int y, int unk2) {
+	debug(9, "KyraEngine::dropItem(%d, %d, %d, %d, %d)", unk1, item, x, y, unk2);
+	if (processItemDrop(_currentCharacter->sceneId, item, x, y, unk1, unk2))
+		return;
+	snd_playSoundEffect(54);
+	if (12 == countItemsInScene(_currentCharacter->sceneId)) {
+		assert(_noDropList);
+		drawSentenceCommand(_noDropList[0], 6);
+	} else {
+		assert(_noDropList);
+		drawSentenceCommand(_noDropList[1], 6);
+	}
+}
+
+void KyraEngine::itemSpecialFX(int x, int y, int item) {
+	debug(9, "KyraEngine::itemSpecialFX(%d, %d, %d)", x, y, item);
+	if (item == 41) {
+		itemSpecialFX1(x, y, item);
+	} else {
+		itemSpecialFX2(x, y, item);
+	}
+}
+
+void KyraEngine::itemSpecialFX1(int x, int y, int item) {
+	debug(9, "KyraEngine::itemSpecialFX1(%d, %d, %d)", x, y, item);
+	uint8 *shape = _shapes[220+item];
+	x -= 8;
+	int startY = y;
+	y -= 15;
+	_screen->hideMouse();
+	_screen->backUpRect0(x, y);
+	for (int i = 1; i <= 16; ++i) {
+		_screen->setNewShapeHeight(shape, i);
+		--startY;
+		_screen->restoreRect0(x, y);
+		uint32 nextTime = _system->getMillis() + 1 * _tickLength;
+		_screen->drawShape(0, shape, x, startY, 0, 0);
+		_screen->updateScreen();
+		while (_system->getMillis() < nextTime) {
+			if ((nextTime - _system->getMillis()) >= 10)
+				delay(10);
+		}
+	}
+	_screen->restoreRect0(x, y);
+	_screen->showMouse();
+}
+
+void KyraEngine::itemSpecialFX2(int x, int y, int item) {
+	debug(9, "KyraEngine::itemSpecialFX2(%d, %d, %d)", x, y, item);
+	x -= 8;
+	y -= 15;
+	int yAdd = (int8)(((16 - _itemTable[item].height) >> 1) & 0xFF);
+	_screen->backUpRect0(x, y);
+	if (item >= 80 && item <= 89) {
+		snd_playSoundEffect(55);
+	}
+	
+	for (int i = 201; i <= 205; ++i) {
+		_screen->restoreRect0(x, y);
+		uint32 nextTime = _system->getMillis() + 3 * _tickLength;
+		_screen->drawShape(0, _shapes[4+i], x, y + yAdd, 0, 0);
+		_screen->updateScreen();
+		while (_system->getMillis() < nextTime) {
+			if ((nextTime - _system->getMillis()) >= 10)
+				delay(10);
+		}
+	}
+	
+	for (int i = 204; i >= 201; --i) {
+		_screen->restoreRect0(x, y);
+		uint32 nextTime = _system->getMillis() + 3 * _tickLength;
+		_screen->drawShape(0, _shapes[220+item], x, y, 0, 0);
+		_screen->drawShape(0, _shapes[4+i], x, y + yAdd, 0, 0);
+		_screen->updateScreen();
+		while (_system->getMillis() < nextTime) {
+			if ((nextTime - _system->getMillis()) >= 10)
+				delay(10);
+		}
+	}
+	_screen->restoreRect0(x, y);
+}
+
+void KyraEngine::magicOutMouseItem(int animIndex, int itemPos) {
+	debug(9, "KyraEngine::magicOutMouseItem(%d, %d)", animIndex, itemPos);
+	int videoPageBackUp = _screen->_curPage;
+	_screen->_curPage = 0;
+	int x = 0, y = 0;
+	if (itemPos == -1) {
+		x = _mouseX - 12;
+		y = _mouseY - 18;
+	} else {
+		x = _itemPosX[itemPos] - 4;
+		y = _itemPosY[itemPos] - 3;
+	}
+	
+	if (_itemInHand == -1 && itemPos == -1) {
+		return;
+	}
+	
+	int tableIndex = 0, loopStart = 0, maxLoops = 0;
+	if (animIndex == 0) {
+		tableIndex = _rnd.getRandomNumberRng(0, 5);
+		loopStart = 35;
+		maxLoops = 9;
+	} else if (animIndex == 1) {
+		tableIndex = _rnd.getRandomNumberRng(0, 11);
+		loopStart = 115;
+		maxLoops = 8;
+	} else if (animIndex == 2) {
+		tableIndex = 0;
+		loopStart = 124;
+		maxLoops = 4;
+	} else {
+		tableIndex = -1;
+	}
+	
+	if (animIndex == 2) {
+		snd_playSoundEffect(0x5E);
+	} else {
+		snd_playSoundEffect(0x37);
+	}
+	_screen->hideMouse();
+	_screen->backUpRect1(x, y);
+
+	for (int shape = _magicMouseItemStartFrame[animIndex]; shape <= _magicMouseItemEndFrame[animIndex]; ++shape) {
+		_screen->restoreRect1(x, y);
+		uint32 nextTime = _system->getMillis() + 4 * _tickLength;
+		_screen->drawShape(0, _shapes[220+_itemInHand], x + 4, y + 3, 0, 0);
+		if (tableIndex == -1) {
+			_screen->drawShape(0, _shapes[4+shape], x, y, 0, 0);
+		} else {
+			specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops);
+		}
+		_screen->updateScreen();
+		while (_system->getMillis() < nextTime) {
+			if (nextTime - _system->getMillis() >= 10)
+				delay(10);
+		}
+	}
+	
+	if (itemPos != -1) {
+		_screen->restoreRect1(x, y);
+		_screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, 12, 0);
+		_screen->backUpRect1(x, y);
+	}
+	
+	for (int shape = _magicMouseItemStartFrame2[animIndex]; shape <= _magicMouseItemEndFrame2[animIndex]; ++shape) {
+		_screen->restoreRect1(x, y);
+		uint32 nextTime = _system->getMillis() + 4 * _tickLength;
+		_screen->drawShape(0, _shapes[220+_itemInHand], x + 4, y + 3, 0, 0);
+		if (tableIndex == -1) {
+			_screen->drawShape(0, _shapes[4+shape], x, y, 0, 0);
+		} else {
+			specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops);
+		}
+		_screen->updateScreen();
+		while (_system->getMillis() < nextTime) {
+			if (nextTime - _system->getMillis() >= 10)
+				delay(10);
+		}
+	}
+	_screen->restoreRect1(x, y);
+	if (itemPos == -1) {
+		_screen->setMouseCursor(1, 1, _shapes[4]);
+		_itemInHand = -1;
+	} else {
+		_characterList[0].inventoryItems[itemPos] = 0xFF;
+		_screen->hideMouse();
+		_screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, 12, 0);
+		_screen->showMouse();
+	}
+	_screen->showMouse();
+	_screen->_curPage = videoPageBackUp;
+}
+
+void KyraEngine::magicInMouseItem(int animIndex, int item, int itemPos) {
+	debug(9, "KyraEngine::magicInMouseItem(%d, %d, %d)", animIndex, item, itemPos);
+	int videoPageBackUp = _screen->_curPage;
+	_screen->_curPage = 0;
+	int x = 0, y = 0;
+	if (itemPos == -1) {
+		x = _mouseX - 12;
+		y = _mouseY - 18;
+	} else {
+		x = _itemPosX[itemPos] - 4;
+		y = _itemPosX[itemPos] - 3;
+	}
+	if (item < 0)
+		return;
+
+	int tableIndex = -1, loopStart = 0, maxLoops = 0;
+	if (animIndex == 0) {
+		tableIndex = _rnd.getRandomNumberRng(0, 5);
+		loopStart = 35;
+		maxLoops = 9;
+	} else if (animIndex == 1) {
+		tableIndex = _rnd.getRandomNumberRng(0, 11);
+		loopStart = 115;
+		maxLoops = 8;
+	} else if (animIndex == 2) {
+		tableIndex = 0;
+		loopStart = 124;
+		maxLoops = 4;
+	}
+	
+	_screen->hideMouse();
+	_screen->backUpRect1(x, y);
+	if (animIndex == 2) {
+		snd_playSoundEffect(0x5E);
+	} else {
+		snd_playSoundEffect(0x37);
+	}
+	
+	for (int shape = _magicMouseItemStartFrame[animIndex]; shape <= _magicMouseItemEndFrame[animIndex]; ++shape) {
+		_screen->restoreRect1(x, y);
+		uint32 nextTime = _system->getMillis() + 4 * _tickLength;
+		if (tableIndex == -1) {
+			_screen->drawShape(0, _shapes[4+shape], x, y, 0, 0);
+		} else {
+			specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops);
+		}
+		_screen->updateScreen();
+		while (_system->getMillis() < nextTime) {
+			if (nextTime - _system->getMillis() >= 10)
+				delay(10);
+		}
+	}
+	
+	for (int shape = _magicMouseItemStartFrame2[animIndex]; shape <= _magicMouseItemEndFrame2[animIndex]; ++shape) {
+		_screen->restoreRect1(x, y);
+		uint32 nextTime = _system->getMillis() + 4 * _tickLength;
+		if (tableIndex == -1) {
+			_screen->drawShape(0, _shapes[4+shape], x, y, 0, 0);
+		} else {
+			specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops);
+		}
+		_screen->updateScreen();
+		while (_system->getMillis() < nextTime) {
+			if (nextTime - _system->getMillis() >= 10)
+				delay(10);
+		}
+	}
+	_screen->restoreRect1(x, y);
+	if (itemPos == -1) {
+		_screen->setMouseCursor(8, 15, _shapes[220+item]);
+		_itemInHand = item;
+	} else {
+		_characterList[0].inventoryItems[itemPos] = item;
+		_screen->hideMouse();
+		_screen->drawShape(0, _shapes[220+item], _itemPosX[itemPos], _itemPosY[itemPos], 0, 0);
+		_screen->showMouse();
+	}
+	_screen->showMouse();
+	_screen->_curPage = videoPageBackUp;
+}
+
+void KyraEngine::specialMouseItemFX(int shape, int x, int y, int animIndex, int tableIndex, int loopStart, int maxLoops) {
+	debug(9, "KyraEngine::specialMouseItemFX(%d, %d, %d, %d, %d, %d, %d)", shape, x, y, animIndex, tableIndex, loopStart, maxLoops);
+	static const uint8 table1[] = {
+		0x23, 0x45, 0x55, 0x72, 0x84, 0xCF, 0x00, 0x00
+	};
+	static const uint8 table2[] = {
+		0x73, 0xB5, 0x80, 0x21, 0x13, 0x39, 0x45, 0x55, 0x62, 0xB4, 0xCF, 0xD8
+	};
+	static const uint8 table3[] = {
+		0x7C, 0xD0, 0x74, 0x84, 0x87, 0x00, 0x00, 0x00
+	};
+	int tableValue = 0;
+	if (animIndex == 0) {
+		tableValue = table1[tableIndex];
+	} else if (animIndex == 1) {
+		tableValue = table2[tableIndex];
+	} else if (animIndex == 2) {
+		tableValue = table3[tableIndex];
+	} else {
+		return;
+	}
+	processSpecialMouseItemFX(shape, x, y, tableValue, loopStart, maxLoops);
+}
+
+void KyraEngine::processSpecialMouseItemFX(int shape, int x, int y, int tableValue, int loopStart, int maxLoops) {
+	debug(9, "KyraEngine::processSpecialMouseItemFX(%d, %d, %d, %d, %d, %d)", shape, x, y, tableValue, loopStart, maxLoops);
+	uint8 shapeColorTable[16];
+	uint8 *shapePtr = _shapes[4+shape] + 10;
+	if (_features & GF_TALKIE)
+		shapePtr += 2;
+	for (int i = 0; i < 16; ++i) {
+		shapeColorTable[i] = shapePtr[i];
+	}
+	for (int i = loopStart; i < loopStart + maxLoops; ++i) {
+		for (int i2 = 0; i2 < 16; ++i2) {
+			if (shapePtr[i2] == i) {
+				shapeColorTable[i2] = (i + tableValue) - loopStart;
+			}
+		}
+	}
+	_screen->drawShape(0, _shapes[4+shape], x, y, 0, 0x8000, shapeColorTable);
+}
+
+void KyraEngine::updatePlayerItemsForScene() {
+	debug(9, "KyraEngine::updatePlayerItemsForScene()");
+	if (_itemInHand >= 29 && _itemInHand < 33) {
+		++_itemInHand;
+		if (_itemInHand > 33)
+			_itemInHand = 33;
+		_screen->hideMouse();
+		_screen->setMouseCursor(8, 15, _shapes[220+_itemInHand]);
+		_screen->showMouse();
+	}
+	
+	bool redraw = false;
+	for (int i = 0; i < 10; ++i) {
+		uint8 item = _currentCharacter->inventoryItems[i];
+		if (item >= 29 && item < 33) {
+			++item;
+			if (item > 33)
+				item = 33;
+			_currentCharacter->inventoryItems[i] = item;
+			redraw = true;
+		}
+	}
+	
+	if (redraw) {
+		_screen->hideMouse();
+		redrawInventory(0);
+		_screen->showMouse();
+	}
+	
+	if (_itemInHand == 33) {
+		magicOutMouseItem(2, -1);
+	}
+	
+	_screen->hideMouse();
+	for (int i = 0; i < 10; ++i) {
+		uint8 item = _currentCharacter->inventoryItems[i];
+		if (item == 33) {
+			magicOutMouseItem(2, i);
+		}
+	}
+	_screen->showMouse();
+}
+
+void KyraEngine::redrawInventory(int page) {
+	int videoPageBackUp = _screen->_curPage;
+	_screen->_curPage = page;
+	_screen->hideMouse();
+	for (int i = 0; i < 10; ++i) {
+		_screen->fillRect(_itemPosX[i], _itemPosY[i], _itemPosX[i] + 15, _itemPosY[i] + 15, 12, page);
+		if (_currentCharacter->inventoryItems[i] != 0xFF) {
+			uint8 item = _currentCharacter->inventoryItems[i];
+			_screen->drawShape(page, _shapes[220+item], _itemPosX[i], _itemPosY[i], 0, 0);
+		}
+	}
+	_screen->showMouse();
+	_screen->_curPage = videoPageBackUp;
+	_screen->updateScreen();
+}
+
+} // end of namespace Kyra

Modified: scummvm/trunk/kyra/kyra.cpp
===================================================================
--- scummvm/trunk/kyra/kyra.cpp	2006-02-09 04:58:21 UTC (rev 20436)
+++ scummvm/trunk/kyra/kyra.cpp	2006-02-09 07:37:19 UTC (rev 20437)
@@ -466,8 +466,6 @@
 	for (int i = 0; i < ARRAYSIZE(_sceneAnimTable); ++i) {
 		free(_sceneAnimTable[i]);
 	}
-	free(_unkPtr1);
-	free(_unkPtr2);
 }
 
 void KyraEngine::errorString(const char *buf1, char *buf2) {
@@ -518,7 +516,7 @@
 	for (int i = 5; i <= 10; ++i)
 		setCharactersPositions(i);
 	setCharactersHeight();
-	resetBrandonPosionFlags();
+	resetBrandonPoisonFlags();
 	_maskBuffer = _screen->getPagePtr(5);
 	_screen->_curPage = 0;
 	// XXX
@@ -526,10 +524,6 @@
 		int size = _screen->getRectSize(3, 24);
 		_shapes[365+i] = (byte*)malloc(size);
 	}
-	_unkPtr1 = (uint8*)malloc(_screen->getRectSize(1, 144));
-	memset(_unkPtr1, 0, _screen->getRectSize(1, 144));
-	_unkPtr2 = (uint8*)malloc(_screen->getRectSize(1, 144));
-	memset(_unkPtr2, 0, _screen->getRectSize(1, 144));
 	_shapes[0] = (uint8*)malloc(_screen->getRectSize(3, 24));
 	memset(_shapes[0], 0, _screen->getRectSize(3, 24));
 	_shapes[1] = (uint8*)malloc(_screen->getRectSize(4, 32));
@@ -556,7 +550,7 @@
 	loadPalette("PALETTE.COL", _screen->_currentPalette);
 
 	// XXX
-	initAnimStateList();
+	_animator->initAnimStateList();
 	setCharactersInDefaultScene();
 
 	_gameSpeed = 50;
@@ -752,48 +746,6 @@
 	_system->quit();
 }
 
-void KyraEngine::loadPalette(const char *filename, uint8 *palData) {
-	debug(9, "KyraEngine::loadPalette('%s' 0x%X)", filename, palData);
-	uint32 fileSize = 0;
-	uint8 *srcData = _res->fileData(filename, &fileSize);
-
-	if (palData && fileSize) {
-		debug(9, "Loading a palette of size %i from '%s'", fileSize, filename);
-		memcpy(palData, srcData, fileSize);
-	}
-	delete [] srcData;
-}
-
-void KyraEngine::loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData) {
-	debug(9, "KyraEngine::copyBitmap('%s', %d, %d, 0x%X)", filename, tempPage, dstPage, palData);
-	uint32 fileSize;
-	uint8 *srcData = _res->fileData(filename, &fileSize);
-	uint8 compType = srcData[2];
-	uint32 imgSize = READ_LE_UINT32(srcData + 4);
-	uint16 palSize = READ_LE_UINT16(srcData + 8);
-	if (palData && palSize) {
-		debug(9, "Loading a palette of size %i from %s", palSize, filename);
-		memcpy(palData, srcData + 10, palSize);		
-	}
-	uint8 *srcPtr = srcData + 10 + palSize;
-	uint8 *dstData = _screen->getPagePtr(dstPage);
-	switch (compType) {
-	case 0:
-		memcpy(dstData, srcPtr, imgSize);
-		break;
-	case 3:
-		Screen::decodeFrame3(srcPtr, dstData, imgSize);
-		break;
-	case 4:
-		Screen::decodeFrame4(srcPtr, dstData, imgSize);
-		break;
-	default:
-		error("Unhandled bitmap compression %d", compType);
-		break;
-	}
-	delete[] srcData;
-}
-
 void KyraEngine::waitTicks(int ticks) {
 	debug(9, "KyraEngine::waitTicks(%d)", ticks);
 	const uint32 end = _system->getMillis() + ticks * 1000 / 60;
@@ -834,1225 +786,6 @@
 	}
 }
 
-void KyraEngine::seq_demo() {
-	debug(9, "KyraEngine::seq_demo()");
-
-	snd_playTheme(MUSIC_INTRO, 2);
-
-	loadBitmap("START.CPS", 7, 7, _screen->_currentPalette);
-	_screen->copyRegion(0, 0, 0, 0, 320, 200, 6, 0);
-	_system->copyRectToScreen(_screen->getPagePtr(0), 320, 0, 0, 320, 200);
-	_screen->fadeFromBlack();
-	waitTicks(60);
-	_screen->fadeToBlack();
-
-	_screen->clearPage(0);
-	loadBitmap("TOP.CPS", 7, 7, NULL);
-	loadBitmap("BOTTOM.CPS", 5, 5, _screen->_currentPalette);
-	_screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 0);
-	_screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 0);
-	_system->copyRectToScreen(_screen->getPagePtr(0), 320, 0, 0, 320, 200);
-	_screen->fadeFromBlack();
-	
-	_seq->playSequence(_seq_WestwoodLogo, true);
-	waitTicks(60);
-
-	_seq->playSequence(_seq_KyrandiaLogo, true);
-
-	_screen->fadeToBlack();
-	_screen->clearPage(2);
-	_screen->clearPage(0);
-
-	_seq->playSequence(_seq_Demo1, true);
-
-	_screen->clearPage(0);
-	_seq->playSequence(_seq_Demo2, true);
-
-	_screen->clearPage(0);
-	_seq->playSequence(_seq_Demo3, true);
-
-	_screen->clearPage(0);
-	_seq->playSequence(_seq_Demo4, true);
-
-	_screen->clearPage(0);
-	loadBitmap("FINAL.CPS", 7, 7, _screen->_currentPalette);
-	_screen->_curPage = 0;
-	_screen->copyRegion(0, 0, 0, 0, 320, 200, 6, 0);
-	_system->copyRectToScreen(_screen->getPagePtr(0), 320, 0, 0, 320, 200);
-	_screen->fadeFromBlack();
-	waitTicks(60);
-	_screen->fadeToBlack();
-	_sound->stopMusic();
-}
-
-void KyraEngine::seq_intro() {
-	debug(9, "KyraEngine::seq_intro()");
-	if (_features & GF_TALKIE) {
-		_res->loadPakFile("INTRO.VRM");
-	}
-	
-	static const IntroProc introProcTable[] = {
-		&KyraEngine::seq_introLogos,
-		&KyraEngine::seq_introStory,
-		&KyraEngine::seq_introMalcolmTree,
-		&KyraEngine::seq_introKallakWriting,
-		&KyraEngine::seq_introKallakMalcolm
-	};
-
-	Common::InSaveFile *in;
-	if ((in = _saveFileMan->openForLoading(getSavegameFilename(0)))) {
-		delete in;
-		_skipIntroFlag = true;
-	} else
-		_skipIntroFlag = false;
-
-	_seq->setCopyViewOffs(true);
-	_screen->setFont(Screen::FID_8_FNT);
-	snd_playTheme(MUSIC_INTRO, 2);
- 	snd_setSoundEffectFile(MUSIC_INTRO);
-	_text->setTalkCoords(144);
-	for (int i = 0; i < ARRAYSIZE(introProcTable) && !seq_skipSequence(); ++i) {
-		(this->*introProcTable[i])();
-	}
-	_text->setTalkCoords(136);
-	waitTicks(30);
-	_seq->setCopyViewOffs(false);
-	_sound->stopMusic();
-	if (_features & GF_TALKIE) {
-		_res->unloadPakFile("INTRO.VRM");
-	}
-	res_unloadResources(RES_INTRO | RES_OUTRO);
-}
-
-void KyraEngine::seq_introLogos() {
-	debug(9, "KyraEngine::seq_introLogos()");
-	_screen->clearPage(0);
-	loadBitmap("TOP.CPS", 7, 7, NULL);
-	loadBitmap("BOTTOM.CPS", 5, 5, _screen->_currentPalette);
-	_screen->_curPage = 0;
-	_screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 0);
-	_screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 0);
-	_system->copyRectToScreen(_screen->getPagePtr(0), 320, 0, 0, 320, 200);
-	_screen->fadeFromBlack();
-	
-	if (_seq->playSequence(_seq_WestwoodLogo, _skipIntroFlag)) {
-		_screen->fadeToBlack();
-		_screen->clearPage(0);
-		return;
-	}
-	waitTicks(60);
-	if (_seq->playSequence(_seq_KyrandiaLogo, _skipIntroFlag)) {
-		_screen->fadeToBlack();
-		_screen->clearPage(0);
-		return;
-	}
-	_screen->fillRect(0, 179, 319, 199, 0);
-
-	int y1 = 8;
-	int h1 = 175;
-	int y2 = 176;
-	int h2 = 0;
-	_screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 2);
-	_screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 2);
-	do {
-		if (h1 > 0) {
-			_screen->copyRegion(0, y1, 0, 8, 320, h1, 2, 0);
-		}
-		++y1;
-		--h1;
-		if (h2 > 0) {
-			_screen->copyRegion(0, 64, 0, y2, 320, h2, 4, 0);
-		}
-		--y2;
-		++h2;
-		_screen->updateScreen();
-		waitTicks(1);
-	} while (y2 >= 64);
-
-	_seq->playSequence(_seq_Forest, true);
-}
-
-void KyraEngine::seq_introStory() {
-	debug(9, "KyraEngine::seq_introStory()");
-	_screen->clearPage(3);
-	_screen->clearPage(0);
-	if ((_features & GF_ENGLISH) && (_features & GF_TALKIE)) {
-		loadBitmap("TEXT_ENG.CPS", 3, 3, 0);
-	} else if (_features & GF_GERMAN) {
-		loadBitmap("TEXT_GER.CPS", 3, 3, 0);
-	} else if (_features & GF_FRENCH) {
-		loadBitmap("TEXT_FRE.CPS", 3, 3, 0);
-	} else if (_features & GF_SPANISH) {
-		loadBitmap("TEXT_SPA.CPS", 3, 3, 0);
-	} else if ((_features & GF_ENGLISH) && (_features & GF_FLOPPY)) {
-		loadBitmap("TEXT.CPS", 3, 3, 0);
-	} else {
-		warning("no story graphics file found");
-	}
-	_screen->copyRegion(0, 0, 0, 0, 320, 200, 3, 0);
-	_screen->updateScreen();
-	waitTicks(360);
-}
-
-void KyraEngine::seq_introMalcolmTree() {
-	debug(9, "KyraEngine::seq_introMalcolmTree()");
-	_screen->_curPage = 0;
-	_screen->clearPage(3);
-	_seq->playSequence(_seq_MalcolmTree, true);
-}
-
-void KyraEngine::seq_introKallakWriting() {
-	debug(9, "KyraEngine::seq_introKallakWriting()");
-	_seq->makeHandShapes();
-	_screen->setAnimBlockPtr(5060);
-	_screen->_charWidth = -2;
-	_screen->clearPage(3);
-	_seq->playSequence(_seq_KallakWriting, true);
-}
-
-void KyraEngine::seq_introKallakMalcolm() {
-	debug(9, "KyraEngine::seq_introKallakMalcolm()");
-	_screen->clearPage(3);
-	_seq->playSequence(_seq_KallakMalcolm, true);
-}
-
-void KyraEngine::seq_createAmuletJewel(int jewel, int page, int noSound, int drawOnly) {
-	debug(9, "seq_createAmuletJewel(%d, %d, %d, %d)", jewel, page, noSound, drawOnly);
-	static const uint16 specialJewelTable[] = {
-		0x167, 0x162, 0x15D, 0x158, 0x153, 0xFFFF
-	};
-	static const uint16 specialJewelTable1[] = {
-		0x14F, 0x154, 0x159, 0x15E, 0x163, 0xFFFF
-	};
-	static const uint16 specialJewelTable2[] = {
-		0x150, 0x155, 0x15A, 0x15F, 0x164, 0xFFFF
-	};
-	static const uint16 specialJewelTable3[] = {
-		0x151, 0x156, 0x15B, 0x160, 0x165, 0xFFFF
-	};
-	static const uint16 specialJewelTable4[] = {
-		0x152, 0x157, 0x15C, 0x161, 0x166, 0xFFFF
-	};
-	if (!noSound)
-		snd_playSoundEffect(0x5F);
-	_screen->hideMouse();
-	if (!drawOnly) {
-		for (int i = 0; specialJewelTable[i] != 0xFFFF; ++i) {
-			_screen->drawShape(page, _shapes[4+specialJewelTable[i]], _amuletX2[jewel], _amuletY2[jewel], 0, 0);
-			_screen->updateScreen();
-			delayWithTicks(3);
-		}
-		
-		const uint16 *opcodes = 0;
-		switch (jewel - 1) {
-			case 0:
-				opcodes = specialJewelTable1;
-				break;
-				
-			case 1:
-				opcodes = specialJewelTable2;
-				break;
-				
-			case 2:
-				opcodes = specialJewelTable3;
-				break;
-				
-			case 3:
-				opcodes = specialJewelTable4;
-				break;
-		}
-		
-		if (opcodes) {
-			for (int i = 0; opcodes[i] != 0xFFFF; ++i) {
-				_screen->drawShape(page, _shapes[4+opcodes[i]], _amuletX2[jewel], _amuletY2[jewel], 0, 0);
-				_screen->updateScreen();
-				delayWithTicks(3);
-			}
-		}
-	}
-	_screen->drawShape(page, _shapes[327+jewel], _amuletX2[jewel], _amuletY2[jewel], 0, 0);
-	_screen->updateScreen();
-	_screen->showMouse();
-	setGameFlag(0x55+jewel);
-}
-
-void KyraEngine::seq_brandonHealing() {
-	debug(9, "seq_brandonHealing()");
-	if (!(_deathHandler & 8))
-		return;
-	if (_currentCharacter->sceneId == 210) {
-		if (_beadStateVar == 4 || _beadStateVar == 6)
-			return;
-	}
-	_screen->hideMouse();
-	checkAmuletAnimFlags();
-	assert(_healingShapeTable);
-	setupShapes123(_healingShapeTable, 22, 0);
-	setBrandonAnimSeqSize(3, 48);
-	snd_playSoundEffect(0x53);
-	for (int i = 123; i <= 144; ++i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(8);
-	}
-	for (int i = 125; i >= 123; --i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(8);
-	}
-	resetBrandonAnimSeqSize();
-	_currentCharacter->currentAnimFrame = 7;
-	animRefreshNPC(0);
-	freeShapes123();
-	_screen->showMouse();
-}
-
-void KyraEngine::seq_brandonHealing2() {
-	debug(9, "seq_brandonHealing2()");
-	_screen->hideMouse();
-	checkAmuletAnimFlags();
-	assert(_healingShape2Table);
-	setupShapes123(_healingShape2Table, 30, 0);
-	resetBrandonPoisonFlags();
-	setBrandonAnimSeqSize(3, 48);
-	snd_playSoundEffect(0x50);
-	for (int i = 123; i <= 152; ++i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(8);
-	}
-	resetBrandonAnimSeqSize();
-	_currentCharacter->currentAnimFrame = 7;
-	animRefreshNPC(0);
-	freeShapes123();
-	_screen->showMouse();
-	assert(_poisonGone);
-	if (_features & GF_TALKIE) {
-		snd_voiceWaitForFinish();
-		snd_playVoiceFile(2010);
-	}
-	characterSays(_poisonGone[0], 0, -2);
-	if (_features & GF_TALKIE) {
-		snd_voiceWaitForFinish();
-		snd_playVoiceFile(2011);
-	}
-	characterSays(_poisonGone[1], 0, -2);
-}
-
-void KyraEngine::seq_poisonDeathNow(int now) {
-	debug(9, "seq_poisonDeathNow(%d)", now);
-	if (!(_brandonStatusBit & 1))
-		return;
-	++_poisonDeathCounter;
-	if (now)
-		_poisonDeathCounter = 2;
-	if (_poisonDeathCounter >= 2) {
-		snd_playWanderScoreViaMap(1, 1);
-		assert(_thePoison);
-		if (_features & GF_TALKIE) {
-			snd_voiceWaitForFinish();
-			snd_playVoiceFile(7000);
-		}
-		characterSays(_thePoison[0], 0, -2);
-		if (_features & GF_TALKIE) {
-			snd_voiceWaitForFinish();
-			snd_playVoiceFile(7001);
-		}
-		characterSays(_thePoison[1], 0, -2);
-		seq_poisonDeathNowAnim();
-		_deathHandler = 3;
-	} else {
-		assert(_thePoison);
-		if (_features & GF_TALKIE) {
-			snd_voiceWaitForFinish();
-			snd_playVoiceFile(7002);
-		}
-		characterSays(_thePoison[2], 0, -2);
-		if (_features & GF_TALKIE) {
-			snd_voiceWaitForFinish();
-			snd_playVoiceFile(7004);
-		}
-		characterSays(_thePoison[3], 0, -2);
-	}
-}
-
-void KyraEngine::seq_poisonDeathNowAnim() {
-	debug(9, "seq_poisonDeathNowAnim()");
-	_screen->hideMouse();
-	checkAmuletAnimFlags();
-	assert(_posionDeathShapeTable);
-	setupShapes123(_posionDeathShapeTable, 20, 0);
-	setBrandonAnimSeqSize(8, 48);
-	
-	_currentCharacter->currentAnimFrame = 124;
-	animRefreshNPC(0);
-	delayWithTicks(30);
-	
-	_currentCharacter->currentAnimFrame = 123;
-	animRefreshNPC(0);
-	delayWithTicks(30);
-	
-	for (int i = 125; i <= 139; ++i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(8);
-	}
-	
-	delayWithTicks(60);
-	
-	for (int i = 140; i <= 142; ++i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(8);
-	}
-	
-	delayWithTicks(60);
-	
-	resetBrandonAnimSeqSize();
-	freeShapes123();
-	_animator->restoreAllObjectBackgrounds();
-	_currentCharacter->x1 = _currentCharacter->x2 = -1;
-	_currentCharacter->y1 = _currentCharacter->y2 = -1;
-	_animator->preserveAllBackgrounds();
-	_screen->showMouse();
-}
-
-void KyraEngine::seq_playFluteAnimation() {
-	debug(9, "seq_playFluteAnimation()");
-	_screen->hideMouse();
-	checkAmuletAnimFlags();
-	setupShapes123(_fluteAnimShapeTable, 36, 0);
-	setBrandonAnimSeqSize(3, 75);
-	for (int i = 123; i <= 130; ++i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(2);
-	}
-	
-	int delayTime = 0, soundType = 0;
-	if (queryGameFlag(0x85)) {
-		snd_playSoundEffect(0x63);
-		delayTime = 9;
-		soundType = 3;
-	} else if (!queryGameFlag(0x86)) {
-		snd_playSoundEffect(0x61);
-		delayTime = 2;
-		soundType = 1;
-		setGameFlag(0x86);
-	} else {
-		snd_playSoundEffect(0x62);
-		delayTime = 2;
-		soundType = 2;
-	}
-	
-	for (int i = 131; i <= 158; ++i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(delayTime);
-	}
-	
-	for (int i = 126; i >= 123; --i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(delayTime);
-	}
-	resetBrandonAnimSeqSize();
-	_currentCharacter->currentAnimFrame = 7;
-	animRefreshNPC(0);
-	freeShapes123();
-	_screen->showMouse();
-	
-	if (soundType == 1) {
-		assert(_fluteString);
-		if (_features & GF_TALKIE) {
-			snd_voiceWaitForFinish();
-			snd_playVoiceFile(1000);
-		}
-		characterSays(_fluteString[0], 0, -2);
-	} else if (soundType == 2) {
-		assert(_fluteString);
-		if (_features & GF_TALKIE) {
-			snd_voiceWaitForFinish();
-			snd_playVoiceFile(1001);
-		}
-		characterSays(_fluteString[1], 0, -2);
-	}
-}
-
-void KyraEngine::seq_winterScroll1() {
-	debug(9, "seq_winterScroll1()");
-	_screen->hideMouse();
-	checkAmuletAnimFlags();
-	assert(_winterScrollTable);
-	assert(_winterScroll1Table);
-	assert(_winterScroll2Table);
-	setupShapes123(_winterScrollTable, 7, 0);
-	setBrandonAnimSeqSize(5, 66);
-	
-	for (int i = 123; i <= 129; ++i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(8);
-	}
-	
-	freeShapes123();
-	snd_playSoundEffect(0x20);
-	setupShapes123(_winterScroll1Table, 35, 0);
-	
-	for (int i = 123; i <= 146; ++i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(8);
-	}
-	
-	if (_currentCharacter->sceneId == 41 && !queryGameFlag(0xA2)) {
-		snd_playSoundEffect(0x20);
-		_sprites->_anims[0].play = false;
-		_animator->sprites()[0].active = 0;
-		_sprites->_anims[1].play = true;
-		_animator->sprites()[1].active = 1;
-		setGameFlag(0xA2);
-	}
-	
-	for (int i = 147; i <= 157; ++i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(8);
-	}
-	
-	if (_currentCharacter->sceneId == 117 && !queryGameFlag(0xB3)) {
-		for (int i = 0; i <= 7; ++i) {
-			_sprites->_anims[i].play = false;
-			_animator->sprites()[i].active = 0;
-		}
-		uint8 tmpPal[768];
-		memcpy(tmpPal, _screen->_currentPalette, 768);
-		memcpy(&tmpPal[684], palTable2()[0], 60);
-		_screen->fadePalette(tmpPal, 72);
-		memcpy(&_screen->_currentPalette[684], palTable2()[0], 60);
-		_screen->setScreenPalette(_screen->_currentPalette);
-		setGameFlag(0xB3);
-	} else {
-		delayWithTicks(120);
-	}
-	
-	freeShapes123();
-	setupShapes123(_winterScroll2Table, 4, 0);
-	
-	for (int i = 123; i <= 126; ++i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(8);
-	}
-	
-	resetBrandonAnimSeqSize();
-	_currentCharacter->currentAnimFrame = 7;
-	animRefreshNPC(0);
-	freeShapes123();
-	_screen->showMouse();
-}
-
-void KyraEngine::seq_winterScroll2() {
-	debug(9, "seq_winterScroll2()");	
-	_screen->hideMouse();
-	checkAmuletAnimFlags();
-	assert(_winterScrollTable);
-	setupShapes123(_winterScrollTable, 7, 0);
-	setBrandonAnimSeqSize(5, 66);
-	
-	for (int i = 123; i <= 128; ++i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(8);
-	}
-	
-	delayWithTicks(120);
-	
-	for (int i = 127; i >= 123; --i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(8);
-	}
-	
-	resetBrandonAnimSeqSize();
-	_currentCharacter->currentAnimFrame = 7;
-	animRefreshNPC(0);
-	freeShapes123();
-	_screen->showMouse();
-}
-
-void KyraEngine::seq_makeBrandonInv() {
-	debug(9, "seq_makeBrandonInv()");
-	if (_deathHandler == 8)
-		return;
-
-	if (_currentCharacter->sceneId == 210) {
-		if (_beadStateVar == 4 || _beadStateVar == 6)
-			return;
-	}
-	
-	_screen->hideMouse();
-	checkAmuletAnimFlags();
-	_brandonStatusBit |= 0x20;
-	setTimerCountdown(18, 2700);
-	_brandonStatusBit |= 0x40;
-	snd_playSoundEffect(0x77);
-	_brandonInvFlag = 0;
-	while (_brandonInvFlag <= 0x100) {
-		animRefreshNPC(0);
-		delayWithTicks(10);
-		_brandonInvFlag += 0x10;
-	}
-	_brandonStatusBit &= 0xFFBF;
-	_screen->showMouse();
-}
-
-void KyraEngine::seq_makeBrandonNormal() {
-	debug(9, "seq_makeBrandonNormal()");
-	_screen->hideMouse();
-	_brandonStatusBit |= 0x40;
-	snd_playSoundEffect(0x77);
-	_brandonInvFlag = 0x100;
-	while (_brandonInvFlag >= 0) {
-		animRefreshNPC(0);
-		delayWithTicks(10);
-		_brandonInvFlag -= 0x10;
-	}
-	_brandonInvFlag = 0;
-	_brandonStatusBit &= 0xFF9F;
-	_screen->showMouse();
-}
-
-void KyraEngine::seq_makeBrandonNormal2() {
-	debug(9, "seq_makeBrandonNormal2()");
-	_screen->hideMouse();
-	assert(_brandonToWispTable);
-	setupShapes123(_brandonToWispTable, 26, 0);
-	setBrandonAnimSeqSize(5, 48);
-	_brandonStatusBit &= 0xFFFD;
-	snd_playSoundEffect(0x6C);
-	for (int i = 138; i >= 123; --i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(8);
-	}
-	setBrandonAnimSeqSize(4, 48);
-	_currentCharacter->currentAnimFrame = 7;
-	animRefreshNPC(0);
-	if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) {
-		_screen->fadeSpecialPalette(31, 234, 13, 4);
-	} else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) {
-		_screen->fadeSpecialPalette(14, 228, 15, 4);
-	}
-	freeShapes123();
-	_screen->showMouse();
-}
-
-void KyraEngine::seq_makeBrandonWisp() {
-	debug(9, "seq_makeBrandonWisp()");
-	if (_deathHandler == 8)
-		return;
-	
-	if (_currentCharacter->sceneId == 210) {
-		if (_beadStateVar == 4 || _beadStateVar == 6)
-			return;
-	}	
-	_screen->hideMouse();
-	checkAmuletAnimFlags();
-	assert(_brandonToWispTable);
-	setupShapes123(_brandonToWispTable, 26, 0);
-	setBrandonAnimSeqSize(5, 48);
-	snd_playSoundEffect(0x6C);
-	for (int i = 123; i <= 138; ++i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(8);
-	}
-	_brandonStatusBit |= 2;
-	if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) {
-		setTimerCountdown(14, 18000);
-	} else {
-		setTimerCountdown(14, 7200);
-	}
-	_brandonDrawFrame = 113;
-	_brandonStatusBit0x02Flag = 1;
-	_currentCharacter->currentAnimFrame = 113;
-	animRefreshNPC(0);
-	_animator->updateAllObjectShapes();
-	if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) {
-		_screen->fadeSpecialPalette(30, 234, 13, 4);
-	} else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) {
-		_screen->fadeSpecialPalette(14, 228, 15, 4);
-	}
-	freeShapes123();
-	_screen->showMouse();
-}
-
-void KyraEngine::seq_dispelMagicAnimation() {
-	debug(9, "seq_dispelMagicAnimation()");
-	if (_deathHandler == 8)
-		return;
-	if (_currentCharacter->sceneId == 210) {
-		if (_beadStateVar == 4 || _beadStateVar == 6)
-			return;
-	}
-	_screen->hideMouse();
-	if (_currentCharacter->sceneId == 210 && _currentCharacter->sceneId < 160)
-		_currentCharacter->facing = 3;
-	if (_malcolmFlag == 7 && _beadStateVar == 3) {
-		_beadStateVar = 6;
-		_unkEndSeqVar5 = 2;
-		_malcolmFlag = 10;
-	}
-	checkAmuletAnimFlags();
-	setGameFlag(0xEE);
-	assert(_magicAnimationTable);
-	setupShapes123(_magicAnimationTable, 5, 0);
-	setBrandonAnimSeqSize(8, 49);
-	snd_playSoundEffect(0x15);
-	for (int i = 123; i <= 127; ++i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(8);
-	}
-	
-	delayWithTicks(120);
-	
-	for (int i = 127; i >= 123; --i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(10);
-	}
-	resetBrandonAnimSeqSize();
-	_currentCharacter->currentAnimFrame = 7;
-	animRefreshNPC(0);
-	freeShapes123();
-	_screen->showMouse();
-}
-
-void KyraEngine::seq_fillFlaskWithWater(int item, int type) {
-	debug(9, "seq_fillFlaskWithWater(%d, %d)", item, type);
-	int newItem = -1;
-	static const uint8 flaskTable1[] = { 0x46, 0x48, 0x4A, 0x4C };
-	static const uint8 flaskTable2[] = { 0x47, 0x49, 0x4B, 0x4D };
-	
-	if (item >= 60 && item <= 77) {
-		assert(_flaskFull);
-		if (_features & GF_TALKIE) {
-			snd_voiceWaitForFinish();
-			snd_playVoiceFile(8006);
-		}
-		characterSays(_flaskFull[0], 0, -2);
-	} else if (item == 78) {
-		assert(type >= 0 && type < ARRAYSIZE(flaskTable1));
-		newItem = flaskTable1[type];
-	} else if (item == 79) {
-		assert(type >= 0 && type < ARRAYSIZE(flaskTable2));
-		newItem = flaskTable2[type];
-	}
-	
-	if (newItem == -1)
-		return;
-	
-	_screen->hideMouse();
-	setMouseItem(newItem);
-	_screen->showMouse();
-	_itemInHand = newItem;
-	assert(_fullFlask);
-	assert(type < _fullFlask_Size && type >= 0);
-	if (_features & GF_TALKIE) {
-		snd_voiceWaitForFinish();
-		static const uint16 voiceEntries[] = {
-			0x1F40, 0x1F41, 0x1F42, 0x1F45
-		};
-		assert(type < ARRAYSIZE(voiceEntries));
-		snd_playVoiceFile(voiceEntries[type]);
-	}
-	characterSays(_fullFlask[type], 0, -2);
-}
-
-void KyraEngine::seq_playDrinkPotionAnim(int unk1, int unk2, int flags) {
-	debug(9, "KyraEngine::seq_playDrinkPotionAnim(%d, %d, %d)", unk1, unk2, flags);
-	// XXX
-	_screen->hideMouse();
-	checkAmuletAnimFlags();
-	_currentCharacter->facing = 5;
-	animRefreshNPC(0);
-	assert(_drinkAnimationTable);
-	setupShapes123(_drinkAnimationTable, 9, flags);
-	setBrandonAnimSeqSize(5, 54);
-	
-	for (int i = 123; i <= 131; ++i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(5);
-	}	
-	snd_playSoundEffect(0x34);
-	for (int i = 0; i < 2; ++i) {
-		_currentCharacter->currentAnimFrame = 130;
-		animRefreshNPC(0);
-		delayWithTicks(7);
-		_currentCharacter->currentAnimFrame = 131;
-		animRefreshNPC(0);
-		delayWithTicks(7);
-	}
-	
-	if (unk2) {
-		// XXX
-	}
-	
-	for (int i = 131; i >= 123; --i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(5);
-	}
-	
-	resetBrandonAnimSeqSize();	
-	_currentCharacter->currentAnimFrame = 7;
-	animRefreshNPC(0);
-	freeShapes123();
-	_screen->showMouse();
-}
-
-int KyraEngine::seq_playEnd() {
-	debug(9, "KyraEngine::seq_playEnd()");
-	if (_endSequenceSkipFlag) {
-		return 0;
-	}
-	if (_deathHandler == 8) {
-		return 0;
-	}
-	_screen->_curPage = 2;
-	if (_endSequenceNeedLoading) {
-		snd_playWanderScoreViaMap(50, 1);
-		setupPanPages();
-		_finalA = new WSAMovieV1(this);
-		assert(_finalA);
-		_finalA->open("finala.wsa", 1, 0);
-		_finalB = new WSAMovieV1(this);
-		assert(_finalB);
-		_finalB->open("finalb.wsa", 1, 0);
-		_finalC = new WSAMovieV1(this);
-		assert(_finalC);
-		_endSequenceNeedLoading = 0;
-		_finalC->open("finalc.wsa", 1, 0);
-		_screen->_curPage = 0;
-		_beadStateVar = 0;
-		_malcolmFlag = 0;
-		// wired stuff with _unkEndSeqVar2 which needs timer handling
-		_screen->copyRegion(312, 0, 312, 0, 8, 136, 0, 2);
-	}
-	if (handleMalcolmFlag()) {
-		_beadStateVar = 0;
-		_malcolmFlag = 12;
-		handleMalcolmFlag();
-		handleBeadState();
-		closeFinalWsa();
-		if (_deathHandler == 8) {
-			_screen->_curPage = 0;
-			checkAmuletAnimFlags();
-			seq_brandonToStone();
-			waitTicks(60);
-			return 1;
-		} else {
-			_endSequenceSkipFlag = 1;
-			if (_text->printed()) {
-				_text->restoreTalkTextMessageBkgd(2, 0);
-			}
-			_screen->_curPage = 0;
-			_screen->hideMouse();
-			_screen->fadeSpecialPalette(32, 228, 20, 60);
-			waitTicks(60);
-			loadBitmap("GEMHEAL.CPS", 3, 3, _screen->_currentPalette);
-			_screen->setScreenPalette(_screen->_currentPalette);
-			_screen->shuffleScreen(8, 8, 304, 128, 2, 0, 1, 0);
-			uint32 nextTime = _system->getMillis() + 120 * _tickLength;
-			_finalA = new WSAMovieV1(this);
-			assert(_finalA);
-			_finalA->open("finald.wsa", 1, 0);
-			_finalA->_x = _finalA->_y = 8;
-			_finalA->_drawPage = 0;
-			while (_system->getMillis() < nextTime) {}
-			snd_playSoundEffect(0x40);
-			for (int i = 0; i < 22; ++i) {
-				while (_system->getMillis() < nextTime) {}
-				if (i == 4) {
-					snd_playSoundEffect(0x3E);
-				} else if (i == 20) {
-					snd_playSoundEffect(0x0E);
-				}
-				nextTime = _system->getMillis() + 8 * _tickLength;
-				_finalA->displayFrame(i);
-				_screen->updateScreen();
-			}
-			delete _finalA;
-			_finalA = 0;
-			seq_playEnding();
-			return 1;
-		}
-	} else {
-		handleBeadState();
-		_screen->bitBlitRects();
-		_screen->updateScreen();
-		_screen->_curPage = 0;
-	}
-	return 0;
-}
-
-void KyraEngine::seq_brandonToStone() {
-	debug(9, "KyraEngine::seq_brandonToStone()");
-	_screen->hideMouse();
-	assert(_brandonStoneTable);
-	setupShapes123(_brandonStoneTable, 14, 0);
-	setBrandonAnimSeqSize(5, 51);
-	for (int i = 123; i <= 136; ++i) {
-		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
-		delayWithTicks(8);
-	}
-	resetBrandonAnimSeqSize();
-	freeShapes123();
-	_screen->showMouse();
-}
-
-void KyraEngine::seq_playEnding() {
-	debug(9, "KyraEngine::seq_playEnding()");
-	_screen->hideMouse();
-	res_unloadResources(RES_INGAME);
-	res_loadResources(RES_OUTRO);
-	loadBitmap("REUNION.CPS", 3, 3, _screen->_currentPalette);
-	_screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0);
-	_screen->_curPage = 0;
-	// XXX
-	assert(_homeString);
-	drawSentenceCommand(_homeString[0], 179);
-	_screen->_curPage = 0;
-	_screen->fadeToBlack();
-	_seq->playSequence(_seq_Reunion, false);
-	_screen->fadeToBlack();
-	_screen->showMouse();
-	seq_playCredits();
-}
-
-void KyraEngine::seq_playCredits() {
-	debug(9, "KyraEngine::seq_playCredits()");
-	static const uint8 colorMap[] = { 0, 0, 0xC, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-	_screen->hideMouse();
-	uint32 sz = 0;
-	if (_features & GF_FLOPPY) {
-		_screen->loadFont(Screen::FID_CRED6_FNT, _res->fileData("CREDIT6.FNT", &sz));
-		_screen->loadFont(Screen::FID_CRED8_FNT, _res->fileData("CREDIT8.FNT", &sz));
-	}
-	loadBitmap("CHALET.CPS", 2, 2, _screen->_currentPalette);
-	_screen->setScreenPalette(_screen->_currentPalette);
-	_screen->setCurPage(0);
-	_screen->clearCurPage();
-	_screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0);
-	_screen->setTextColorMap(colorMap);
-	_screen->_charWidth = -1;
-	snd_playWanderScoreViaMap(53, 1);
-	// delete
-	_screen->updateScreen();
-	// XXX
-	waitTicks(120); // wait until user presses escape normally
-	_screen->fadeToBlack();
-	_screen->clearCurPage();
-	_screen->showMouse();
-}
-
-bool KyraEngine::seq_skipSequence() const {
-	debug(9, "KyraEngine::seq_skipSequence()");
-	return _quitFlag || _abortIntroFlag;
-}
-
-void KyraEngine::snd_playTheme(int file, int track) {
-	debug(9, "KyraEngine::snd_playTheme(%d)", file);
-	assert(file < _xmidiFilesCount);
-	_curMusicTheme = _newMusicTheme = file;
-	_sound->playMusic(_xmidiFiles[file]);
-	_sound->playTrack(track, false);
-}
-
-void KyraEngine::snd_playTrack(int track, bool looping) {
-	debug(9, "KyraEngine::snd_playTrack(%d, %d)", track, looping);
-	_sound->playTrack(track, looping);
-}
-
-void KyraEngine::snd_setSoundEffectFile(int file) {
-	debug(9, "KyraEngine::snd_setSoundEffectFile(%d)", file);
-	assert(file < _xmidiFilesCount);
-	_sound->loadSoundEffectFile(_xmidiFiles[file]);
-}
-
-void KyraEngine::snd_playSoundEffect(int track) {
-	debug(9, "KyraEngine::snd_playSoundEffect(%d)", track);
-	if (track == 49) {
-		snd_playWanderScoreViaMap(56, 1);
-	} else {
-		_sound->playSoundEffect(track);
-	}
-}
-
-void KyraEngine::snd_playWanderScoreViaMap(int command, int restart) {
-	debug(9, "KyraEngine::snd_playWanderScoreViaMap(%d, %d)", command, restart);
-	static const int8 soundTable[] = {
-		-1,   0,  -1,   1,   0,   3,   0,   2,
-		 0,   4,   1,   2,   1,   3,   1,   4,
-		 1, 0x5C,   1,   6,   1,   7,   2,   2,
-		 2,   3,   2,   4,   2,   5,   2,   6,
-		 2,   7,   3,   3,   3,   4,   1,   8,
-		 1,   9,   4,   2,   4,   3,   4,   4,
-		 4,   5,   4,   6,   4,   7,   4,   8,
-		 1, 0x0B,   1, 0x0C,   1, 0x0E,   1, 0x0D,
-		 4,   9,   5, 0x0C,   6,   2,   6,   6,
-		 6,   7,   6,   8,   6,   9,   6,   3,
-		 6,   4,   6,   5,   7,   2,   7,   3,
-		 7,   4,   7,   5,   7,   6,   7,   7,
-		 7,   8,   7,   9,   8,   2,   8,   3,
-		 8,   4,   8,   5,   6, 0x0B,   5, 0x0B
-	};
-	//if (!_disableSound) {
-	//	XXX
-	//}
-	assert(command*2+1 < ARRAYSIZE(soundTable));
-	if (_curMusicTheme != soundTable[command*2]+1) {
-		if (soundTable[command*2] != -1) {
-			snd_playTheme(soundTable[command*2]+1);
-		}
-	}
-	
-	if (restart)
-		_lastMusicCommand = -1;
-	
-	if (command != 1) {
-		if (_lastMusicCommand != command) {
-			_lastMusicCommand = command;
-			snd_playTrack(soundTable[command*2+1], true);
-		}
-	} else {
-		_lastMusicCommand = 1;
-		_sound->beginFadeOut();
-	}
-}
-
-void KyraEngine::snd_playVoiceFile(int id) {
-	debug(9, "KyraEngine::snd_playVoiceFile(%d)", id);
-	char vocFile[9];
-	assert(id >= 0 && id < 9999);
-	sprintf(vocFile, "%03d.VOC", id);
-	_sound->voicePlay(vocFile);
-}
-
-bool KyraEngine::snd_voicePlaying() {
-	return _sound->voiceIsPlaying();
-}
-
-void KyraEngine::snd_voiceWaitForFinish(bool ingame) {
-	debug(9, "KyraEngine::snd_voiceWaitForFinish(%d)", ingame);
-	while (snd_voicePlaying() && !_fastMode) {
-		if (ingame) {
-			delay(10, true);
-		} else {
-			_system->delayMillis(10);
-		}
-	}
-}
-
-void KyraEngine::snd_startTrack() {
-	debug(9, "KyraEngine::snd_startTrack()");
-	_sound->startTrack();
-}
-
-void KyraEngine::snd_haltTrack() {
-	debug(9, "KyraEngine::snd_haltTrack()");
-	_sound->haltTrack();
-}
-
-void KyraEngine::loadMouseShapes() {
-	loadBitmap("MOUSE.CPS", 3, 3, 0);
-	_screen->_curPage = 2;
-	_shapes[4] = _screen->encodeShape(0, 0, 8, 10, 0);
-	_shapes[5] = _screen->encodeShape(0, 0x17, 0x20, 7, 0);
-	_shapes[6] = _screen->encodeShape(0x50, 0x12, 0x10, 9, 0);
-	_shapes[7] = _screen->encodeShape(0x60, 0x12, 0x10, 11, 0);
-	_shapes[8] = _screen->encodeShape(0x70, 0x12, 0x10, 9, 0);
-	_shapes[9] = _screen->encodeShape(0x80, 0x12, 0x10, 11, 0);
-	_shapes[10] = _screen->encodeShape(0x90, 0x12, 0x10, 10, 0);
-	_shapes[364] = _screen->encodeShape(0x28, 0, 0x10, 13, 0);
-	_screen->setMouseCursor(1, 1, 0);
-	_screen->setMouseCursor(1, 1, _shapes[4]);
-	_screen->setShapePages(5, 3);
-}
-
-void KyraEngine::loadCharacterShapes() {
-	int curImage = 0xFF;
-	int videoPage = _screen->_curPage;
-	_screen->_curPage = 2;
-	for (int i = 0; i < 115; ++i) {	
-		assert(i < _defaultShapeTableSize);
-		Shape *shape = &_defaultShapeTable[i];
-		if (shape->imageIndex == 0xFF) {
-			_shapes[i+7+4] = 0;
-			continue;
-		}
-		if (shape->imageIndex != curImage) {
-			assert(shape->imageIndex < _characterImageTableSize);
-			loadBitmap(_characterImageTable[shape->imageIndex], 3, 3, 0);
-			curImage = shape->imageIndex;
-		}
-		_shapes[i+7+4] = _screen->encodeShape(shape->x<<3, shape->y, shape->w<<3, shape->h, 1);
-	}
-	_screen->_curPage = videoPage;
-}
-
-void KyraEngine::loadSpecialEffectShapes() {
-	loadBitmap("EFFECTS.CPS", 3, 3, 0);
-	_screen->_curPage = 2;
- 
-	int currShape; 
-	for (currShape = 173; currShape < 183; currShape++)
-		_shapes[4 + currShape] = _screen->encodeShape((currShape-173) * 24, 0, 24, 24, 1);
- 
-	for (currShape = 183; currShape < 190; currShape++)
-		_shapes[4 + currShape] = _screen->encodeShape((currShape-183) * 24, 24, 24, 24, 1);
- 
-	for (currShape = 190; currShape < 201; currShape++)
-		_shapes[4 + currShape] = _screen->encodeShape((currShape-190) * 24, 48, 24, 24, 1);
- 
-	for (currShape = 201; currShape < 206; currShape++)
-		_shapes[4 + currShape] = _screen->encodeShape((currShape-201) * 16, 106, 16, 16, 1);
-}
-
-int KyraEngine::findDuplicateItemShape(int shape) {
-	static uint8 dupTable[] = {
-		0x48, 0x46, 0x49, 0x47, 0x4a, 0x46, 0x4b, 0x47,
-		0x4c, 0x46, 0x4d, 0x47, 0x5b, 0x5a, 0x5c, 0x5a,
-		0x5d, 0x5a, 0x5e, 0x5a, 0xFF, 0xFF
-	};
-
-	int i = 0;
-
-	while (dupTable[i] != 0xFF) {
-		if (dupTable[i] == shape)
-			return dupTable[i+1];
-		i += 2;
-	}
-	return -1;
-}
-
-void KyraEngine::loadItems() {
-	int shape;
-
-	loadBitmap("JEWELS3.CPS", 3, 3, 0);
-	_screen->_curPage = 2;
-
-	_shapes[327] = 0;
-
-	for (shape = 1; shape < 6; shape++ )
-		_shapes[327 + shape] = _screen->encodeShape((shape - 1) * 32, 0, 32, 17, 0);
-
-	for (shape = 330; shape <= 334; shape++)
-		_shapes[4 + shape] = _screen->encodeShape((shape-330) * 32, 102, 32, 17, 0);
-
-	for (shape = 335; shape <= 339; shape++)
-		_shapes[4 + shape] = _screen->encodeShape((shape-335) * 32, 17,  32, 17, 0);
-
-	for (shape = 340; shape <= 344; shape++)
-		_shapes[4 + shape] = _screen->encodeShape((shape-340) * 32, 34,  32, 17, 0);
-
-	for (shape = 345; shape <= 349; shape++)
-		_shapes[4 + shape] = _screen->encodeShape((shape-345) * 32, 51,  32, 17, 0);
-
-	for (shape = 350; shape <= 354; shape++)
-		_shapes[4 + shape] = _screen->encodeShape((shape-350) * 32, 68,  32, 17, 0);
-
-	for (shape = 355; shape <= 359; shape++)
-		_shapes[4 + shape] = _screen->encodeShape((shape-355) * 32, 85,  32, 17, 0);
-
-
-	loadBitmap("ITEMS.CPS", 3, 3, 0);
-	_screen->_curPage = 2;
-
-	for (int i = 0; i < 107; i++) {
-		shape = findDuplicateItemShape(i);
-
-		if (shape != -1)
-			_shapes[220 + i] = _shapes[220 + shape];
-		else
-			_shapes[220 + i] = _screen->encodeShape( (i % 20) * 16, i/20 * 16, 16, 16, 0);
-	}
-
-	uint32 size;
-	uint8 *fileData = _res->fileData("_ITEM_HT.DAT", &size);
-	assert(fileData);
-
-	for (int i = 0; i < 107; i++) {
-		_itemTable[i].height = fileData[i];
-		_itemTable[i].unk1 = _itemTable[i].unk2 = 0;
-	}
-
-	delete[] fileData;
-}
-
-void KyraEngine::loadButtonShapes() {
-	loadBitmap("BUTTONS2.CPS", 3, 3, 0);
-	_screen->_curPage = 2;
-	_scrollUpButton.process0PtrShape = _screen->encodeShape(0, 0, 24, 14, 1);
-	_scrollUpButton.process1PtrShape = _screen->encodeShape(24, 0, 24, 14, 1);
-	_scrollUpButton.process2PtrShape = _screen->encodeShape(48, 0, 24, 14, 1);
-	_scrollDownButton.process0PtrShape = _screen->encodeShape(0, 15, 24, 14, 1);
-	_scrollDownButton.process1PtrShape = _screen->encodeShape(24, 15, 24, 14, 1);
-	_scrollDownButton.process2PtrShape = _screen->encodeShape(48, 15, 24, 14, 1);
-	_screen->_curPage = 0;
-}
-
-void KyraEngine::initMainButtonList() {
-	_buttonList = &_buttonData[0];
-	for (int i = 0; _buttonDataListPtr[i]; ++i) {
-		_buttonList = initButton(_buttonList, _buttonDataListPtr[i]);
-	}
-}
-
-void KyraEngine::loadMainScreen(int page) {
-	if ((_features & GF_ENGLISH) && (_features & GF_TALKIE)) 
-		loadBitmap("MAIN_ENG.CPS", page, page, 0);
-	else if(_features & GF_FRENCH)
-		loadBitmap("MAIN_FRE.CPS", page, page, 0);
-	else if(_features & GF_GERMAN)
-		loadBitmap("MAIN_GER.CPS", page, page, 0);
-	else if ((_features & GF_ENGLISH) && (_features & GF_FLOPPY))
-		loadBitmap("MAIN15.CPS", page, page, 0);
-	else if (_features & GF_SPANISH)
-		loadBitmap("MAIN_SPA.CPS", page, page, 0);
-	else
-		warning("no main graphics file found");
-	
-	uint8 *_pageSrc = _screen->getPagePtr(page);
-	uint8 *_pageDst = _screen->getPagePtr(0);
-	memcpy(_pageDst, _pageSrc, 320*200);
-}
-
-void KyraEngine::setCharactersInDefaultScene() {
-	static const uint32 defaultSceneTable[][4] = {
-		{ 0xFFFF, 0x0004, 0x0003, 0xFFFF },
-		{ 0xFFFF, 0x0022, 0xFFFF, 0x0000 },
-		{ 0xFFFF, 0x001D, 0x0021, 0xFFFF },
-		{ 0xFFFF, 0x0000, 0x0000, 0xFFFF }
-	};
-	
-	for (int i = 1; i < 5; ++i) {
-		Character *cur = &_characterList[i];
-		//cur->field_20 = 0;
-		const uint32 *curTable = defaultSceneTable[i-1];
-		cur->sceneId = curTable[0];
-		if (cur->sceneId == _currentCharacter->sceneId) {
-			//++cur->field_20;
-			cur->sceneId = curTable[1/*cur->field_20*/];
-		}
-		//cur->field_23 = curTable[cur->field_20+1];
-	}
-}
-
 void KyraEngine::setCharacterDefaultFrame(int character) {
 	static uint16 initFrameTable[] = {
 		7, 41, 77, 0, 0
@@ -2065,22 +798,6 @@
 	// edit->unk6 = 1;
 }
 
-void KyraEngine::setCharactersPositions(int character) {
-	static uint16 initXPosTable[] = {
-		0x3200, 0x0024, 0x2230, 0x2F00, 0x0020, 0x002B,
-		0x00CA, 0x00F0, 0x0082, 0x00A2, 0x0042
-	};
-	static uint8 initYPosTable[] = {
-		0x00, 0xA2, 0x00, 0x42, 0x00,
-		0x67, 0x67, 0x60, 0x5A, 0x71,
-		0x76
-	};
-	assert(character < ARRAYSIZE(initXPosTable));
-	Character *edit = &_characterList[character];
-	edit->x1 = edit->x2 = initXPosTable[character];
-	edit->y1 = edit->y2 = initYPosTable[character];
-}
-
 void KyraEngine::setCharactersHeight() {
 	static int8 initHeightTable[] = {
 		48, 40, 48, 47, 56,
@@ -2106,2184 +823,7 @@
 	return 0;
 }
 
-void KyraEngine::enterNewScene(int sceneId, int facing, int unk1, int unk2, int brandonAlive) {
-	debug(9, "KyraEngine::enterNewScene(%d, %d, %d, %d, %d)", sceneId, facing, unk1, unk2, brandonAlive);
-	int unkVar1 = 1;
-	_screen->hideMouse();
-	_handleInput = false;
-	_abortWalkFlag = false;
-	_abortWalkFlag2 = false;
-	if (_currentCharacter->sceneId == 7 && sceneId == 24) {
-		_newMusicTheme = 3;
-	} else if (_currentCharacter->sceneId == 25 && sceneId == 109) {
-		_newMusicTheme = 4;
-	} else if (_currentCharacter->sceneId == 120 && sceneId == 37) {
-		_newMusicTheme = 5;
-	} else if (_currentCharacter->sceneId == 52 && sceneId == 199) {
-		_newMusicTheme = 6;
-	} else if (_currentCharacter->sceneId == 37 && sceneId == 120) {
-		_newMusicTheme = 4;
-	} else if (_currentCharacter->sceneId == 109 && sceneId == 25) {
-		_newMusicTheme = 3;
-	} else if (_currentCharacter->sceneId == 24 && sceneId == 7) {
-		_newMusicTheme = 2;
-	}
-	if (_newMusicTheme != _curMusicTheme) {
-		snd_playTheme(_newMusicTheme);
-	}
-	
-	switch (_currentCharacter->sceneId) {
-		case 1:
-			if (sceneId == 0) {
-				moveCharacterToPos(0, 0, _currentCharacter->x1, 84);
-				unkVar1 = 0;
-			}
-		break;
-		
-		case 3:
-			if (sceneId == 2) {
-				moveCharacterToPos(0, 6, 155, _currentCharacter->y1);
-				unkVar1 = 0;
-			}
-		break;
-		
-		case 26:
-			if (sceneId == 27) {
-				moveCharacterToPos(0, 6, 155, _currentCharacter->y1);
-				unkVar1 = 0;
-			}
-		break;
-		
-		case 44:
-			if (sceneId == 45) {
-				moveCharacterToPos(0, 2, 192, _currentCharacter->y1);
-				unkVar1 = 0;
-			}
-		break;
-		
-		default:
-		break;
-	}
-	
-	if (unkVar1 && unk1) {
-		int xpos = _currentCharacter->x1;
-		int ypos = _currentCharacter->y1;
-		switch (facing) {
-			case 0:
-				ypos = _currentCharacter->y1 - 6;
-			break;
-			
-			case 2:
-				xpos = 336;
-			break;
-			
-			case 4:
-				ypos = 143;
-			break;
-			
-			case 6:
-				xpos = -16;
-			break;
-			
-			default:
-			break;
-		}
-		
-		moveCharacterToPos(0, facing, xpos, ypos);
-	}
-	
-	for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) {
-		_movieObjects[i]->close();
-	}
-	
-	if (!brandonAlive) {
-		_scriptInterpreter->initScript(_scriptClick, _scriptClickData);
-		_scriptInterpreter->startScript(_scriptClick, 5);
-		while (_scriptInterpreter->validScript(_scriptClick)) {
-			_scriptInterpreter->runScript(_scriptClick);
-		}
-	}
-	
-	memset(_entranceMouseCursorTracks, 0xFFFF, sizeof(uint16)*4);
-	_currentCharacter->sceneId = sceneId;
-	
-	assert(sceneId < _roomTableSize);
-	assert(_roomTable[sceneId].nameIndex < _roomFilenameTableSize);
-
-	Room *currentRoom = &_roomTable[sceneId];
-	
-	if (_currentRoom != 0xFFFF && (_features & GF_TALKIE)) {
-		char file[32];
-		assert(_currentRoom < _roomTableSize);
-		int tableId = _roomTable[_currentRoom].nameIndex;
-		assert(tableId < _roomFilenameTableSize);
-		strcpy(file, _roomFilenameTable[tableId]);
-		strcat(file, ".VRM");
-		_res->unloadPakFile(file);
-	}
-	
-	_currentRoom = sceneId;
-	
-	int tableId = _roomTable[_currentCharacter->sceneId].nameIndex;
-	char fileNameBuffer[32];
-	strcpy(fileNameBuffer, _roomFilenameTable[tableId]);
-	strcat(fileNameBuffer, ".DAT");
-	_sprites->loadDAT(fileNameBuffer, _sceneExits);
-	_sprites->setupSceneAnims();
-	_scriptInterpreter->unloadScript(_scriptClickData);
-	loadSceneMSC();
-	
-	if ((_features & GF_TALKIE)) {
-		strcpy(fileNameBuffer, _roomFilenameTable[tableId]);
-		strcat(fileNameBuffer, ".VRM");
-		_res->loadPakFile(fileNameBuffer);
-	}
-	
-	_walkBlockNorth = currentRoom->northExit;
-	_walkBlockEast = currentRoom->eastExit;
-	_walkBlockSouth = currentRoom->southExit;
-	_walkBlockWest = currentRoom->westExit;
-	
-	if (_walkBlockNorth == 0xFFFF) {
-		blockOutRegion(0, 0, 320, (_northExitHeight & 0xFF)+3);
-	}
-	if (_walkBlockEast == 0xFFFF) {
-		blockOutRegion(312, 0, 8, 139);
-	}
-	if (_walkBlockSouth == 0xFFFF) {
-		blockOutRegion(0, 135, 320, 8);
-	}
-	if (_walkBlockWest == 0xFFFF) {
-		blockOutRegion(0, 0, 8, 139);
-	}
-	
-	if (!brandonAlive) {
-		updatePlayerItemsForScene();
-	}
-
-	startSceneScript(brandonAlive);
-	setupSceneItems();
-	
-	initSceneData(facing, unk2, brandonAlive);
-	
-	_loopFlag2 = 0;
-	_screen->showMouse();
-	if (!brandonAlive) {
-		seq_poisonDeathNow(0);
-	}
-	updateMousePointer(true);
-	_changedScene = true;
-}
-
-void KyraEngine::transcendScenes(int roomIndex, int roomName) {
-	debug(9, "KyraEngine::transcendScenes(%d, %d)", roomIndex, roomName);
-	assert(roomIndex < _roomTableSize);
-	if (_features & GF_TALKIE) {
-		char file[32];
-		assert(roomIndex < _roomTableSize);
-		int tableId = _roomTable[roomIndex].nameIndex;
-		assert(tableId < _roomFilenameTableSize);
-		strcpy(file, _roomFilenameTable[tableId]);
-		strcat(file, ".VRM");
-		_res->unloadPakFile(file);
-	}
-	_roomTable[roomIndex].nameIndex = roomName;
-	_unkScreenVar2 = 1;
-	_unkScreenVar3 = 1;
-	_unkScreenVar1 = 0;
-	_brandonPosX = _currentCharacter->x1;
-	_brandonPosY = _currentCharacter->y1;
-	enterNewScene(roomIndex, _currentCharacter->facing, 0, 0, 0);
-	_unkScreenVar1 = 1;
-	_unkScreenVar2 = 0;
-	_unkScreenVar3 = 0;
-}
-
-void KyraEngine::setSceneFile(int roomIndex, int roomName) {
-	debug(9, "KyraEngine::setSceneFile(%d, %d)", roomIndex, roomName);
-	assert(roomIndex < _roomTableSize);
-	_roomTable[roomIndex].nameIndex = roomName;
-}
-
-void KyraEngine::moveCharacterToPos(int character, int facing, int xpos, int ypos) {
-	debug(9, "KyraEngine::moveCharacterToPos(%d, %d, %d, %d)", character, facing, xpos, ypos);
-	Character *ch = &_characterList[character];
-	ch->facing = facing;
-	_screen->hideMouse();
-	xpos = (int16)(xpos & 0xFFFC);
-	ypos = (int16)(ypos & 0xFFFE);
-	disableTimer(19);
-	disableTimer(14);
-	disableTimer(18);
-	uint32 nextFrame = 0;
-	switch (facing) {
-		case 0:
-			while (ypos < ch->y1) {
-				nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis();
-				setCharacterPositionWithUpdate(character);
-				while (_system->getMillis() < nextFrame) { updateGameTimers(); }
-			}
-			break;
-		
-		case 2:	
-			while (ch->x1 < xpos) {
-				nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis();
-				setCharacterPositionWithUpdate(character);
-				while (_system->getMillis() < nextFrame) { updateGameTimers(); }
-			}
-			break;
-		
-		case 4:
-			while (ypos > ch->y1) {
-				nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis();
-				setCharacterPositionWithUpdate(character);
-				while (_system->getMillis() < nextFrame) { updateGameTimers(); }
-			}
-			break;
-		
-		case 6:
-			while (ch->x1 > xpos) {
-				nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis();
-				setCharacterPositionWithUpdate(character);
-				while (_system->getMillis() < nextFrame) { updateGameTimers(); }
-			}
-			break;
-		
-		default:
-			break;
-	}
-	enableTimer(19);
-	enableTimer(14);
-	enableTimer(18);
-	_screen->showMouse();
-}
-
-void KyraEngine::setCharacterPositionWithUpdate(int character) {
-	debug(9, "KyraEngine::setCharacterPositionWithUpdate(%d)", character);
-	setCharacterPosition(character, 0);
-	_sprites->updateSceneAnims();
-	updateGameTimers();
-	_animator->updateAllObjectShapes();
-	updateTextFade();
-
-	if (_currentCharacter->sceneId == 210) {
-		_animator->updateKyragemFading();
-	}
-}
-
-int KyraEngine::setCharacterPosition(int character, int *facingTable) {
-	debug(9, "KyraEngine::setCharacterPosition(%d, 0x%X)", character, facingTable);
-	if (character == 0) {
-		_currentCharacter->x1 += _charXPosTable[_currentCharacter->facing];
-		_currentCharacter->y1 += _charYPosTable[_currentCharacter->facing];
-		setCharacterPositionHelper(0, facingTable);
-		return 1;
-	} else {
-		_characterList[character].x1 += _charXPosTable[_characterList[character].facing];
-		_characterList[character].y1 += _charYPosTable[_characterList[character].facing];
-		if (_characterList[character].sceneId == _currentCharacter->sceneId) {
-			setCharacterPositionHelper(character, 0);
-		}
-	}
-	return 0;
-}
-
-void KyraEngine::setCharacterPositionHelper(int character, int *facingTable) {
-	debug(9, "KyraEngine::setCharacterPositionHelper(%d, 0x%X)", character, facingTable);
-	Character *ch = &_characterList[character];
-	++ch->currentAnimFrame;
-	int facing = ch->facing;
-	if (facingTable) {
-		if (*facingTable != *(facingTable - 1)) {
-			if (*(facingTable - 1) == *(facingTable + 1)) {
-				facing = getOppositeFacingDirection(*(facingTable - 1));
-				*facingTable = *(facingTable - 1);
-			}
-		}
-	}
-	
-	static uint8 facingIsZero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-	static uint8 facingIsFour[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-	
-	if (facing == 0) {
-		++facingIsZero[character];
-	} else {
-		bool resetTables = false;
-		if (facing != 7) {
-			if (facing - 1 != 0) {
-				if (facing != 4) {
-					if (facing == 3 || facing == 5) {
-						if (facingIsFour[character] > 2) {
-							facing = 4;
-						}
-						resetTables = true;
-					}
-				} else {
-					++facingIsFour[character];
-				}
-			} else {
-				if (facingIsZero[character] > 2) {
-					facing = 0;
-				}
-				resetTables = true;
-			}
-		} else {
-			if (facingIsZero[character] > 2) {
-				facing = 0;
-			}
-			resetTables = true;
-		}
-		
-		if (resetTables) {
-			facingIsZero[character] = 0;
-			facingIsFour[character] = 0;
-		}
-	}
-	
-	static const uint16 maxAnimationFrame[] = {
-		0x000F, 0x0031, 0x0055, 0x0000, 0x0000, 0x0000,
-		0x0008, 0x002A, 0x004E, 0x0000, 0x0000, 0x0000,
-		0x0022, 0x0046, 0x006A, 0x0000, 0x0000, 0x0000,
-		0x001D, 0x0041, 0x0065, 0x0000, 0x0000, 0x0000,
-		0x001F, 0x0043, 0x0067, 0x0000, 0x0000, 0x0000,
-		0x0028, 0x004C, 0x0070, 0x0000, 0x0000, 0x0000,
-		0x0023, 0x0047, 0x006B, 0x0000, 0x0000, 0x0000
-	};
-	
-	if (facing == 0) {
-		if (maxAnimationFrame[36+character] > ch->currentAnimFrame) {
-			ch->currentAnimFrame = maxAnimationFrame[36+character];
-		}
-		if (maxAnimationFrame[30+character] < ch->currentAnimFrame) {
-			ch->currentAnimFrame = maxAnimationFrame[36+character];
-		}
-	} else if (facing == 4) {
-		if (maxAnimationFrame[18+character] > ch->currentAnimFrame) {
-			ch->currentAnimFrame = maxAnimationFrame[18+character];
-		}
-		if (maxAnimationFrame[12+character] < ch->currentAnimFrame) {
-			ch->currentAnimFrame = maxAnimationFrame[18+character];
-		}
-	} else {
-		if (maxAnimationFrame[18+character] < ch->currentAnimFrame) {
-			ch->currentAnimFrame = maxAnimationFrame[30+character];
-		}
-		if (maxAnimationFrame[character] == ch->currentAnimFrame) {
-			ch->currentAnimFrame = maxAnimationFrame[6+character];
-		}
-		if (maxAnimationFrame[character] < ch->currentAnimFrame) {
-			ch->currentAnimFrame = maxAnimationFrame[6+character]+2;
-		}
-	}
-	
-	if (character == 0) {
-		if (_brandonStatusBit & 0x10)
-			ch->currentAnimFrame = 88;
-	}
-	
-	animRefreshNPC(character);
-}
-
-int KyraEngine::getOppositeFacingDirection(int dir) {
-	debug(9, "KyraEngine::getOppositeFacingDirection(%d)", dir);
-	switch (dir) {
-		case 0:
-			return 2;
-			break;
-			
-		case 1:
-			return 1;
-			break;
-			
-		case 3:
-			return 7;
-			break;
-			
-		case 4:
-			return 6;
-			break;
-			
-		case 5:
-			return 5;
-			break;
-			
-		case 6:
-			return 4;
-			break;
-			
-		case 7:
-			return 3;
-			break;
-			
-		default:
-			break;
-	}
-	return 0;
-}
-
-void KyraEngine::loadSceneMSC() {
-	assert(_currentCharacter->sceneId < _roomTableSize);
-	int tableId = _roomTable[_currentCharacter->sceneId].nameIndex;
-	assert(tableId < _roomFilenameTableSize);
-	char fileNameBuffer[32];
-	strcpy(fileNameBuffer, _roomFilenameTable[tableId]);
-	strcat(fileNameBuffer, ".MSC");
-	_screen->fillRect(0, 0, 319, 199, 0, 5);
-	loadBitmap(fileNameBuffer, 3, 5, 0);
-}
-
-// maybe move these two functions to Screen
-void KyraEngine::blockInRegion(int x, int y, int width, int height) {
-	debug(9, "KyraEngine::blockInRegion(%d, %d, %d, %d)", x, y, width, height);
-	assert(_screen->_shapePages[0]);
-	byte *toPtr = _screen->_shapePages[0] + (y * 320 + x);
-	for (int i = 0; i < height; ++i) {
-		byte *backUpTo = toPtr;
-		for (int i2 = 0; i2 < width; ++i2) {
-			*toPtr++ &= 0x7F;
-		}
-		toPtr = (backUpTo + 320);
-	}
-}
-
-void KyraEngine::blockOutRegion(int x, int y, int width, int height) {
-	debug(9, "KyraEngine::blockOutRegion(%d, %d, %d, %d)", x, y, width, height);
-	assert(_screen->_shapePages[0]);
-	byte *toPtr = _screen->_shapePages[0] + (y * 320 + x);
-	for (int i = 0; i < height; ++i) {
-		byte *backUpTo = toPtr;
-		for (int i2 = 0; i2 < width; ++i2) {
-			*toPtr++ |= 0x80;
-		}
-		toPtr = (backUpTo + 320);
-	}
-}
-
-void KyraEngine::startSceneScript(int brandonAlive) {
-	debug(9, "KyraEngine::startSceneScript(%d)", brandonAlive);
-	assert(_currentCharacter->sceneId < _roomTableSize);
-	int tableId = _roomTable[_currentCharacter->sceneId].nameIndex;
-	assert(tableId < _roomFilenameTableSize);
-	char fileNameBuffer[32];
-	strcpy(fileNameBuffer, _roomFilenameTable[tableId]);
-	strcat(fileNameBuffer, ".CPS");
-	loadBitmap(fileNameBuffer, 3, 3, 0);
-	_sprites->loadSceneShapes();
-	_exitListPtr = 0;
-
-	_screen->setScreenPalette(_screen->_currentPalette);
-	
-	_scaleMode = 1;	
-	for (int i = 0; i < 145; ++i) {
-		_scaleTable[i] = 256;
-	}
-	
-	clearNoDropRects();
-	_scriptInterpreter->initScript(_scriptClick, _scriptClickData);
-	strcpy(fileNameBuffer, _roomFilenameTable[tableId]);
-	strcat(fileNameBuffer, ".EMC");
-	_scriptInterpreter->unloadScript(_scriptClickData);
-	_scriptInterpreter->loadScript(fileNameBuffer, _scriptClickData, _opcodeTable, _opcodeTableSize, 0);
-	_scriptInterpreter->startScript(_scriptClick, 0);
-	_scriptClick->variables[0] = _currentCharacter->sceneId;
-	_scriptClick->variables[7] = brandonAlive;
-	
-	while (_scriptInterpreter->validScript(_scriptClick)) {
-		_scriptInterpreter->runScript(_scriptClick);
-	}
-}
-
-void KyraEngine::initSceneData(int facing, int unk1, int brandonAlive) {
-	debug(9, "KyraEngine::initSceneData(%d, %d, %d)", facing, unk1, brandonAlive);
-	
-	int16 xpos2 = 0;
-	int setFacing = 1;
-	
-	int16 xpos = 0, ypos = 0;
-	
-	if (_brandonPosX == -1 && _brandonPosY == -1) {
-		switch (facing+1) {
-			case 0:
-				xpos = ypos = -1;
-			break;
-			
-			case 1: case 2: case 8:
-				xpos = _sceneExits.southXPos;
-				ypos = _sceneExits.southYPos;
-				break;
-			
-			case 3:
-				xpos = _sceneExits.westXPos;
-				ypos = _sceneExits.westYPos;
-				break;
-			
-			case 4: case 5: case 6:
-				xpos = _sceneExits.northXPos;
-				ypos = _sceneExits.northYPos;
-				break;
-			
-			case 7:
-				xpos = _sceneExits.eastXPos;
-				ypos = _sceneExits.eastYPos;
-				break;
-			
-			default:
-			break;
-		}
-		
-		if ((uint8)(_northExitHeight & 0xFF) + 2 >= ypos) {
-			ypos = (_northExitHeight & 0xFF) + 4;
-		}
-		if (xpos >= 308) {
-			xpos = 304;
-		}
-		if ((uint8)(_northExitHeight >> 8) - 2 <= ypos) {
-			ypos = (_northExitHeight >> 8) - 4;
-		}
-		if (xpos <= 12) {
-			xpos = 16;
-		}
-	}
-	
-	if (_brandonPosX > -1) {
-		xpos = _brandonPosX;
-	}
-	if (_brandonPosY > -1) {
-		ypos = _brandonPosY;
-	}
-	
-	int16 ypos2 = 0;
-	if (_brandonPosX > -1 && _brandonPosY > -1) {
-		switch (_currentCharacter->sceneId) {
-			case 1:
-				_currentCharacter->x1 = xpos;
-				_currentCharacter->x2 = xpos;
-				_currentCharacter->y1 = ypos;
-				_currentCharacter->y2 = ypos;
-				facing = 4;
-				xpos2 = 192;
-				ypos2 = 104;
-				setFacing = 0;
-				unk1 = 1;
-				break;
-				
-			case 3:
-				_currentCharacter->x1 = xpos;
-				_currentCharacter->x2 = xpos;
-				_currentCharacter->y1 = ypos;
-				_currentCharacter->y2 = ypos;
-				facing = 2;
-				xpos2 = 204;
-				ypos2 = 94;
-				setFacing = 0;
-				unk1 = 1;
-				break;
-				
-			case 26:
-				_currentCharacter->x1 = xpos;
-				_currentCharacter->x2 = xpos;
-				_currentCharacter->y1 = ypos;
-				_currentCharacter->y2 = ypos;
-				facing = 2;
-				xpos2 = 192;
-				ypos2 = 128;
-				setFacing = 0;
-				unk1 = 1;
-				break;
-				
-			case 44:
-				_currentCharacter->x1 = xpos;
-				_currentCharacter->x2 = xpos;
-				_currentCharacter->y1 = ypos;
-				_currentCharacter->y2 = ypos;
-				facing = 6;
-				xpos2 = 156;
-				ypos2 = 96;
-				setFacing = 0;
-				unk1 = 1;
-				break;
-				
-			case 37:
-				_currentCharacter->x1 = xpos;
-				_currentCharacter->x2 = xpos;
-				_currentCharacter->y1 = ypos;
-				_currentCharacter->y2 = ypos;
-				facing = 2;
-				xpos2 = 148;
-				ypos2 = 114;
-				setFacing = 0;
-				unk1 = 1;
-				break;
-				
-			default:
-				break;
-		}
-	}
-	
-	_brandonPosX = _brandonPosY = -1;
-	
-	if (unk1 && setFacing) {
-		ypos2 = ypos;
-		xpos2 = xpos;
-		switch (facing) {
-			case 0:
-				ypos = 142;
-				break;
-				
-			case 2:
-				xpos = -16;
-				break;
-				
-			case 4:
-				ypos = (uint8)(_northExitHeight & 0xFF) - 4;
-				break;
-				
-			case 6:
-				xpos = 336;
-				break;
-				
-			default:
-				break;
-		}
-	}
-	
-	xpos2 = (int16)(xpos2 & 0xFFFC);
-	ypos2 = (int16)(ypos2 & 0xFFFE);
-	xpos = (int16)(xpos & 0xFFFC);
-	ypos = (int16)(ypos & 0xFFFE);
-	_currentCharacter->facing = facing;
-	_currentCharacter->x1 = xpos;
-	_currentCharacter->x2 = xpos;
-	_currentCharacter->y1 = ypos;
-	_currentCharacter->y2 = ypos;
-	
-	initSceneObjectList(brandonAlive);
-	
-	if (unk1 && brandonAlive == 0) {
-		moveCharacterToPos(0, facing, xpos2, ypos2);
-	}
-	
-	_scriptClick->variables[4] = _itemInHand;
-	_scriptClick->variables[7] = brandonAlive;
-	_scriptInterpreter->startScript(_scriptClick, 3);
-	while (_scriptInterpreter->validScript(_scriptClick)) {
-		_scriptInterpreter->runScript(_scriptClick);
-	}
-}
-
-void KyraEngine::resetBrandonPosionFlags() {
-	_brandonStatusBit = 0;
-	for (int i = 0; i < 256; ++i) {
-		_brandonPoisonFlagsGFX[i] = i;
-	}
-}
-
-void KyraEngine::initAnimStateList() {
-	AnimObject *animStates = _animator->objects();
-	animStates[0].index = 0;
-	animStates[0].active = 1;
-	animStates[0].flags = 0x800;
-	animStates[0].background = _shapes[2];
-	animStates[0].rectSize = _screen->getRectSize(4, 48);
-	animStates[0].width = 4;
-	animStates[0].height = 48;
-	animStates[0].width2 = 4;
-	animStates[0].height2 = 3;
-	
-	for (int i = 1; i <= 4; ++i) {
-		animStates[i].index = i;
-		animStates[i].active = 0;
-		animStates[i].flags = 0x800;
-		animStates[i].background = _shapes[3];
-		animStates[i].rectSize = _screen->getRectSize(4, 64);
-		animStates[i].width = 4;
-		animStates[i].height = 48;
-		animStates[i].width2 = 4;
-		animStates[i].height2 = 3;
-	}
-	
-	for (int i = 5; i < 16; ++i) {
-		animStates[i].index = i;
-		animStates[i].active = 0;
-		animStates[i].flags = 0;
-	}
-	
-	for (int i = 16; i < 28; ++i) {
-		animStates[i].index = i;
-		animStates[i].flags = 0;
-		animStates[i].background = _shapes[349+i];
-		animStates[i].rectSize = _screen->getRectSize(3, 24);
-		animStates[i].width = 3;
-		animStates[i].height = 16;
-		animStates[i].width2 = 0;
-		animStates[i].height2 = 0;
-	}
-}
-
-void KyraEngine::initSceneObjectList(int brandonAlive) {
-	debug(9, "KyraEngine::initSceneObjectList(%d)", brandonAlive);
-	for (int i = 0; i < 28; ++i) {
-		_animator->actors()[i].active = 0;
-	}
-	
-	int startAnimFrame = 0;
-	
-	AnimObject *curAnimState = _animator->actors();
-	curAnimState->active = 1;
-	curAnimState->drawY = _currentCharacter->y1;
-	curAnimState->sceneAnimPtr = _shapes[4+_currentCharacter->currentAnimFrame];
-	curAnimState->animFrameNumber = _currentCharacter->currentAnimFrame;
-	startAnimFrame = _currentCharacter->currentAnimFrame-7;
-	int xOffset = _defaultShapeTable[startAnimFrame].xOffset;
-	int yOffset = _defaultShapeTable[startAnimFrame].yOffset;
-	if (_scaleMode) {
-		curAnimState->x1 = _currentCharacter->x1;
-		curAnimState->y1 = _currentCharacter->y1;
-		
-		_brandonScaleX = _scaleTable[_currentCharacter->y1];
-		_brandonScaleY = _scaleTable[_currentCharacter->y1];
-		
-		curAnimState->x1 += (_brandonScaleX * xOffset) >> 8;
-		curAnimState->y1 += (_brandonScaleY * yOffset) >> 8;
-	} else {
-		curAnimState->x1 = _currentCharacter->x1 + xOffset;
-		curAnimState->y1 = _currentCharacter->y1 + yOffset;
-	}
-	curAnimState->x2 = curAnimState->x1;
-	curAnimState->y2 = curAnimState->y1;
-	curAnimState->refreshFlag = 1;
-	curAnimState->bkgdChangeFlag = 1;
-	_animator->clearQueue();
-	_animator->addObjectToQueue(curAnimState);
-	
-	int listAdded = 0;
-	int addedObjects = 1;
-	
-	for (int i = 1; i < 5; ++i) {
-		Character *ch = &_characterList[i];
-		curAnimState = &_animator->actors()[addedObjects];
-		if (ch->sceneId != _currentCharacter->sceneId) {
-			curAnimState->active = 0;
-			curAnimState->refreshFlag = 0;
-			curAnimState->bkgdChangeFlag = 0;
-			++addedObjects;
-			continue;
-		}
-		
-		curAnimState->drawY = ch->y1;
-		curAnimState->sceneAnimPtr = _shapes[4+ch->currentAnimFrame];
-		curAnimState->animFrameNumber = ch->currentAnimFrame;
-		startAnimFrame = ch->currentAnimFrame-7;
-		xOffset = _defaultShapeTable[startAnimFrame].xOffset;
-		yOffset = _defaultShapeTable[startAnimFrame].yOffset;
-		if (_scaleMode) {
-			curAnimState->x1 = ch->x1;
-			curAnimState->y1 = ch->y1;
-		
-			_brandonScaleX = _scaleTable[ch->y1];
-			_brandonScaleY = _scaleTable[ch->y1];
-		
-			curAnimState->x1 += (_brandonScaleX * xOffset) >> 8;
-			curAnimState->y1 += (_brandonScaleY * yOffset) >> 8;
-		} else {
-			curAnimState->x1 = ch->x1 + xOffset;
-			curAnimState->y1 = ch->y1 + yOffset;
-		}
-		curAnimState->x2 = curAnimState->x1;
-		curAnimState->y2 = curAnimState->y1;
-		curAnimState->active = 1;
-		curAnimState->refreshFlag = 1;
-		curAnimState->bkgdChangeFlag = 1;
-		
-		if (ch->facing >= 1 && ch->facing <= 3) {
-			curAnimState->flags |= 1;
-		} else if (ch->facing >= 5 && ch->facing <= 7) {
-			curAnimState->flags &= 0xFFFFFFFE;
-		}
-		
-		_animator->addObjectToQueue(curAnimState);
-		
-		++addedObjects;
-		++listAdded;
-		if (listAdded < 2)
-			i = 5;
-	}
-	
-	for (int i = 0; i < 11; ++i) {
-		curAnimState = &_animator->sprites()[i];
-
-		if (_sprites->_anims[i].play) {
-			curAnimState->active = 1;
-			curAnimState->refreshFlag = 1;
-			curAnimState->bkgdChangeFlag = 1;
-		}
-		else {
-			curAnimState->active = 0;
-			curAnimState->refreshFlag = 0;
-			curAnimState->bkgdChangeFlag = 0;
-		}
-		curAnimState->height = _sprites->_anims[i].height;
-		curAnimState->height2 = _sprites->_anims[i].height2;
-		curAnimState->width = _sprites->_anims[i].width + 1;
-		curAnimState->width2 = _sprites->_anims[i].width2;
-		curAnimState->drawY = _sprites->_anims[i].drawY;
-		curAnimState->x1 = curAnimState->x2 = _sprites->_anims[i].x;
-		curAnimState->y1 = curAnimState->y2 = _sprites->_anims[i].y;
-		curAnimState->background = _sprites->_anims[i].background;
-		curAnimState->sceneAnimPtr = _sprites->_sceneShapes[_sprites->_anims[i].sprite];
-		
-		if(_sprites->_anims[i].unk2)
-			curAnimState->flags = 0x800;
-		else
-			curAnimState->flags = 0;
-
-		if (_sprites->_anims[i].flipX)
-			curAnimState->flags |= 0x1;
-		
-		_animator->addObjectToQueue(curAnimState);
-	}
-	
-	for (int i = 0; i < 12; ++i) {
-		curAnimState = &_animator->items()[i];
-		Room *curRoom = &_roomTable[_currentCharacter->sceneId];
-		byte curItem = curRoom->itemsTable[i];
-		if (curItem != 0xFF) {
-			curAnimState->drawY = curRoom->itemsYPos[i];
-			curAnimState->sceneAnimPtr = _shapes[220+curItem];
-			curAnimState->animFrameNumber = (int16)0xFFFF;
-			curAnimState->y1 = curRoom->itemsYPos[i];
-			curAnimState->x1 = curRoom->itemsXPos[i];
-			
-			curAnimState->x1 -= (fetchAnimWidth(curAnimState->sceneAnimPtr, _scaleTable[curAnimState->drawY])) >> 1;
-			curAnimState->y1 -= fetchAnimHeight(curAnimState->sceneAnimPtr, _scaleTable[curAnimState->drawY]);
-			
-			curAnimState->x2 = curAnimState->x1;
-			curAnimState->y2 = curAnimState->y1;
-			
-			curAnimState->active = 1;
-			curAnimState->refreshFlag = 1;
-			curAnimState->bkgdChangeFlag = 1;
-			
-			_animator->addObjectToQueue(curAnimState);
-		} else {
-			curAnimState->active = 0;
-			curAnimState->refreshFlag = 0;
-			curAnimState->bkgdChangeFlag = 0;
-		}
-	}
-	
-	_animator->preserveAnyChangedBackgrounds();
-	curAnimState = _animator->actors();
-	curAnimState->bkgdChangeFlag = 1;
-	curAnimState->refreshFlag = 1;
-	for (int i = 1; i < 28; ++i) {
-		curAnimState = &_animator->objects()[i];
-		if (curAnimState->active) {
-			curAnimState->bkgdChangeFlag = 1;
-			curAnimState->refreshFlag = 1;
-		}
-	}
-	_animator->restoreAllObjectBackgrounds();
-	_animator->preserveAnyChangedBackgrounds();
-	_animator->prepDrawAllObjects();
-	initSceneScreen(brandonAlive);
-	_animator->copyChangedObjectsForward(0);
-}
-
-void KyraEngine::initSceneScreen(int brandonAlive) {
-	// XXX (Pointless?) Palette stuff
-	if (_unkScreenVar2 == 1) {
-		_screen->shuffleScreen(8, 8, 304, 128, 2, 0, _unkScreenVar3, false);
-	} else {
-		_screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0);
-	}
-	_screen->updateScreen();
-	// XXX More (pointless?) palette stuff
-
-	if (!_scriptInterpreter->startScript(_scriptClick, 2))
-		error("Could not start script function 2 of scene script");
-
-	_scriptClick->variables[7] = brandonAlive;
-
-	while (_scriptInterpreter->validScript(_scriptClick))
-		_scriptInterpreter->runScript(_scriptClick);
-
-	setTextFadeTimerCountdown(-1);
-	if (_currentCharacter->sceneId == 210) {
-		if (_itemInHand != -1)
-			magicOutMouseItem(2, -1);
-		
-		_screen->hideMouse();
-		for (int i = 0; i < 10; ++i) {
-			if (_currentCharacter->inventoryItems[i] != 0xFF)
-				magicOutMouseItem(2, i);
-		}
-		_screen->showMouse();
-	}
-}
-
 #pragma mark -
-#pragma mark - Text handling
-#pragma mark -
-
-void KyraEngine::waitForChatToFinish(int16 chatDuration, char *chatStr, uint8 charNum) {
-	debug(9, "KyraEngine::waitForChatToFinish(%i, %s, %i)", chatDuration, chatStr, charNum); 
-	bool hasUpdatedNPCs = false;
-	bool runLoop = true;
-	uint8 currPage;
-	OSystem::Event event;
-	int16 delayTime;
-
-	//while( towns_isEscKeyPressed() )
-		//towns_getKey();
-
-	uint32 timeToEnd = strlen(chatStr) * 8 * _tickLength + _system->getMillis();
-
-	if (chatDuration != -1 ) {
-		switch (_configTalkspeed) {
-			case 0: chatDuration *= 2;
-					break;
-			case 2: chatDuration /= 4;
-					break;
-			case 3: chatDuration = -1;
-		}
-	}
-
-	if (chatDuration != -1)
-		chatDuration *= _tickLength;
-
-	disableTimer(14);
-	disableTimer(18);
-	disableTimer(19);
-
-	uint32 timeAtStart = _system->getMillis();
-	uint32 loopStart;
-	while (runLoop) {
-		loopStart = _system->getMillis();
-		if (_currentCharacter->sceneId == 210)
-			if (seq_playEnd())
-				break;
-
-		if (_system->getMillis() > timeToEnd && !hasUpdatedNPCs) {
-			hasUpdatedNPCs = true;
-			disableTimer(15);
-			_currHeadShape = 4;
-			animRefreshNPC(0);
-			animRefreshNPC(_talkingCharNum);
-
-			if (_charSayUnk2 != -1) {
-				_animator->sprites()[_charSayUnk2].active = 0;
-				_sprites->_anims[_charSayUnk2].play = false;
-				_charSayUnk2 = -1;
-			}
-		}
-
-		updateGameTimers();
-		_sprites->updateSceneAnims();
-		_animator->restoreAllObjectBackgrounds();
-		_animator->preserveAnyChangedBackgrounds();
-		_animator->prepDrawAllObjects();
-
-		currPage = _screen->_curPage;
-		_screen->_curPage = 2;
-		_text->printCharacterText(chatStr, charNum, _characterList[charNum].x1);
-		_screen->_curPage = currPage;
-
-		_animator->copyChangedObjectsForward(0);
-		updateTextFade();
-
-		if ((chatDuration < (int16)(_system->getMillis() - timeAtStart)) && chatDuration != -1)
-			break;
-
-		while (_system->pollEvent(event)) {
-			switch (event.type) {
-			case OSystem::EVENT_KEYDOWN:
-				if (event.kbd.keycode == '.')
-					runLoop = false;
-				break;
-			case OSystem::EVENT_QUIT:
-				quitGame();
-			case OSystem::EVENT_LBUTTONDOWN:
-				runLoop = false;
-				break;
-			default:
-				break;
-			}
-		}
-		
-		if (_fastMode)
-			runLoop = false;
-
-		delayTime = (loopStart + _gameSpeed) - _system->getMillis();
-		if (delayTime > 0)
-			_system->delayMillis(delayTime);
-	}
-
-	enableTimer(14);
-	enableTimer(15);
-	enableTimer(18);
-	enableTimer(19);
-	//clearKyrandiaButtonIO();
-}
-
-void KyraEngine::endCharacterChat(int8 charNum, int16 convoInitialized) {
-	_charSayUnk3 = -1;
-
-	if (charNum > 4 && charNum < 11) {
-		//TODO: weird _game_inventory stuff here
-		warning("STUB: endCharacterChat() for high charnums");
-	}
-
-	if (convoInitialized != 0) {
-		_talkingCharNum = -1;
-		_currentCharacter->currentAnimFrame = 7;
-		animRefreshNPC(0);
-		_animator->updateAllObjectShapes();
-	}
-}
-
-void KyraEngine::restoreChatPartnerAnimFrame(int8 charNum) {
-	_talkingCharNum = -1;
-
-	if (charNum > 0 && charNum < 5) {
-		_characterList[charNum].currentAnimFrame = _currentChatPartnerBackupFrame;
-		animRefreshNPC(charNum);
-	}
-
-	_currentCharacter->currentAnimFrame = 7;
-	animRefreshNPC(0);
-	_animator->updateAllObjectShapes();
-}
-
-void KyraEngine::backupChatPartnerAnimFrame(int8 charNum) {
-	_talkingCharNum = 0;
-
-	if (charNum < 5 && charNum > 0) 
-		_currentChatPartnerBackupFrame = _characterList[charNum].currentAnimFrame;
-
-	if (_scaleMode != 0)
-		_currentCharacter->currentAnimFrame = 7;
-	else
-		_currentCharacter->currentAnimFrame = _currentCharAnimFrame;
-
-	animRefreshNPC(0);
-	_animator->updateAllObjectShapes();
-}
-
-int8 KyraEngine::getChatPartnerNum() {
-	uint8 sceneTable[] = {0x2, 0x5, 0x2D, 0x7, 0x1B, 0x8, 0x22, 0x9, 0x30, 0x0A};
-	int pos = 0;
-	int partner = -1;
-
-	for (int i = 1; i < 6; i++) {
-		if (_currentCharacter->sceneId == sceneTable[pos]) {
-			partner = sceneTable[pos+1];
-			break;
-		}
-		pos += 2;
-	}
-
-	for (int i = 1; i < 5; i++) {
-		if (_characterList[i].sceneId == _currentCharacter->sceneId) {
-			partner = i;
-			break;
-		}
-	}
-	return partner;
-}
-
-int KyraEngine::initCharacterChat(int8 charNum) {
-	if (_talkingCharNum == -1) {
-		_talkingCharNum = 0;
-
-		if (_scaleMode != 0)
-			_currentCharacter->currentAnimFrame = 7;
-		else
-			_currentCharacter->currentAnimFrame = 16;
-
-		animRefreshNPC(0);
-		_animator->updateAllObjectShapes();
-	}
-
-	_charSayUnk2 = -1;
-	_animator->flagAllObjectsForBkgdChange();
-	_animator->restoreAllObjectBackgrounds();
-
-	if (charNum > 4 && charNum < 11) {
-		// TODO: Fill in weird _game_inventory stuff here
-		warning("STUB: initCharacterChat() for high charnums");
-	}
-
-	_animator->flagAllObjectsForRefresh();
-	_animator->flagAllObjectsForBkgdChange();
-	_animator->preserveAnyChangedBackgrounds();
-	_charSayUnk3 = charNum;
-
-	return 1;
-}
-
-void KyraEngine::characterSays(char *chatStr, int8 charNum, int8 chatDuration) {
-	debug(9, "KyraEngine::characterSays('%s', %i, %d)", chatStr, charNum, chatDuration);
-	uint8 startAnimFrames[] =  { 0x10, 0x32, 0x56, 0x0, 0x0, 0x0 };
-
-	uint16 chatTicks;
-	int16 convoInitialized;
-	int8 chatPartnerNum;
-
-	if (_currentCharacter->sceneId == 210)
-		return;
-
-	convoInitialized = initCharacterChat(charNum);	
-	chatPartnerNum = getChatPartnerNum();
-
-	if (chatPartnerNum != -1 && chatPartnerNum < 5)
-		backupChatPartnerAnimFrame(chatPartnerNum);
-
-	if (charNum < 5) {
-		_characterList[charNum].currentAnimFrame = startAnimFrames[charNum];
-		_charSayUnk3 = charNum;
-		_talkingCharNum = charNum;
-		animRefreshNPC(charNum);
-	}
-
-	char *processedString = _text->preprocessString(chatStr);
-	int lineNum = _text->buildMessageSubstrings(processedString);
-
-	int16 yPos = _characterList[charNum].y1;
-	yPos -= _scaleTable[charNum] * _characterList[charNum].height;
-	yPos -= 8;
-	yPos -= lineNum * 10;
-
-	if (yPos < 11)
-		yPos = 11;
-
-	if (yPos > 100)
-		yPos = 100;
-
-	_text->_talkMessageY = yPos;
-	_text->_talkMessageH = lineNum * 10;
-	_animator->restoreAllObjectBackgrounds();
-
-	_screen->copyRegion(12, _text->_talkMessageY, 12, 136, 308, _text->_talkMessageH, 2, 2);
-	_screen->hideMouse();
-
-	_text->printCharacterText(processedString, charNum, _characterList[charNum].x1);
-	_screen->showMouse();
-
-	if (chatDuration == -2)
-		chatTicks = strlen(processedString) * 9;
-	else
-		chatTicks = chatDuration;
-
-	waitForChatToFinish(chatTicks, chatStr, charNum);
-
-	_animator->restoreAllObjectBackgrounds();
-
-	_screen->copyRegion(12, 136, 12, _text->_talkMessageY, 308, _text->_talkMessageH, 2, 2);
-	_animator->preserveAllBackgrounds();
-	_animator->prepDrawAllObjects();
-	_screen->hideMouse();
-
-	_screen->copyRegion(12, _text->_talkMessageY, 12, _text->_talkMessageY, 308, _text->_talkMessageH, 2, 0);
-	_screen->showMouse();
-	_animator->flagAllObjectsForRefresh();
-	_animator->copyChangedObjectsForward(0);
-
-	if (chatPartnerNum != -1 && chatPartnerNum < 5)
-		restoreChatPartnerAnimFrame(chatPartnerNum);
-
-	endCharacterChat(charNum, convoInitialized);
-}
-
-void KyraEngine::drawSentenceCommand(char *sentence, int color) {
-	debug(9, "KyraEngine::drawSentenceCommand('%s', %i)", sentence, color);
-	_screen->hideMouse();
-	_screen->fillRect(8, 143, 311, 152, 12);
-
-	if (_startSentencePalIndex != color || _fadeText != false) {
-		_currSentenceColor[0] = _screen->_currentPalette[765] = _screen->_currentPalette[color*3];
-		_currSentenceColor[1] = _screen->_currentPalette[766] = _screen->_currentPalette[color*3+1];
-		_currSentenceColor[2] = _screen->_currentPalette[767] = _screen->_currentPalette[color*3+2];
-	
-		_screen->setScreenPalette(_screen->_currentPalette);
-		_startSentencePalIndex = 0;
-	}
-
-	_text->printText(sentence, 8, 143, 0xFF, 12, 0);
-	_screen->showMouse();
-	setTextFadeTimerCountdown(15);
-	_fadeText = false;
-}
-
-void KyraEngine::updateSentenceCommand(char *str1, char *str2, int color) {
-	debug(9, "KyraEngine::updateSentenceCommand('%s', '%s', %i)", str1, str2, color);
-	char sentenceCommand[500];
-	strncpy(sentenceCommand, str1, 500);
-	if (str2)
-		strncat(sentenceCommand, str2, 500 - strlen(sentenceCommand));
-
-	drawSentenceCommand(sentenceCommand, color);
-	_screen->updateScreen();
-}
-
-void KyraEngine::updateTextFade() {
-	debug(9, "KyraEngine::updateTextFade()");
-	if (!_fadeText)
-		return;
-	
-	bool finished = false;
-	for (int i = 0; i < 3; i++)
-		if (_currSentenceColor[i] > 4)
-			_currSentenceColor[i] -= 4;
-		else
-			if (_currSentenceColor[i]) {
-				_currSentenceColor[i] = 0;
-				finished = true;
-			}
-		
-	_screen->_currentPalette[765] = _currSentenceColor[0];
-	_screen->_currentPalette[766] = _currSentenceColor[1];
-	_screen->_currentPalette[767] = _currSentenceColor[2];
-	_screen->setScreenPalette(_screen->_currentPalette);
-
-	if (finished) {
-		_fadeText = false;
-		_startSentencePalIndex = -1;
-	}
-}
-
-#pragma mark -
-#pragma mark - Item handling
-#pragma mark -
-
-void KyraEngine::addToNoDropRects(int x, int y, int w, int h) {
-	debug(9, "KyraEngine::addToNoDropRects(%d, %d, %d, %d)", x, y, w, h);
-	for (int rect = 0; rect < 11; ++rect) {
-		if (_noDropRects[rect].x == -1) {
-			_noDropRects[rect].x = x;
-			_noDropRects[rect].y = y;
-			_noDropRects[rect].x2 = x + w - 1;
-			_noDropRects[rect].y2 = y + h - 1;
-			break;
-		}
-	}
-}
-
-void KyraEngine::clearNoDropRects() {
-	debug(9, "KyraEngine::clearNoDropRects()");
-	memset(_noDropRects, -1, sizeof(_noDropRects));
-}
-
-byte KyraEngine::findFreeItemInScene(int scene) {
-	debug(9, "KyraEngine::findFreeItemInScene(%d)", scene);
-	assert(scene < _roomTableSize);
-	Room *room = &_roomTable[scene];
-	for (int i = 0; i < 12; ++i) {
-		if (room->itemsTable[i] == 0xFF)
-			return i;
-	}
-	return 0xFF;
-}
-
-byte KyraEngine::findItemAtPos(int x, int y) {
-	debug(9, "KyraEngine::findItemAtPos(%d, %d)", x, y);
-	assert(_currentCharacter->sceneId < _roomTableSize);
-	const uint8 *itemsTable = _roomTable[_currentCharacter->sceneId].itemsTable;
-	const uint16 *xposOffset = _roomTable[_currentCharacter->sceneId].itemsXPos;
-	const uint8 *yposOffset = _roomTable[_currentCharacter->sceneId].itemsYPos;
-	
-	int highestYPos = -1;
-	byte returnValue = 0xFF;
-	
-	for (int i = 0; i < 12; ++i) {
-		if (*itemsTable != 0xFF) {
-			int xpos = *xposOffset - 11;
-			int xpos2 = *xposOffset + 10;
-			if (x > xpos && x < xpos2) {
-				assert(*itemsTable < ARRAYSIZE(_itemTable));
-				int itemHeight = _itemTable[*itemsTable].height;
-				int ypos = *yposOffset + 3;
-				int ypos2 = ypos - itemHeight - 3;
-				
-				if (y > ypos2 && ypos > y) {
-					if (highestYPos <= ypos) {
-						returnValue = i;
-						highestYPos = ypos;
-					}
-				}
-			}
-		}
-		++xposOffset;
-		++yposOffset;
-		++itemsTable;
-	}
-	
-	return returnValue;
-}
-
-void KyraEngine::placeItemInGenericMapScene(int item, int index) {
-	debug(9, "KyraEngine::placeItemInGenericMapScene(%d, %d)", item, index);
-	static const uint16 itemMapSceneMinTable[] = {
-		0x0000, 0x0011, 0x006D, 0x0025, 0x00C7, 0x0000
-	};
-	static const uint16 itemMapSceneMaxTable[] = {
-		0x0010, 0x0024, 0x00C6, 0x006C, 0x00F5, 0x0000
-	};
-	
-	int minValue = itemMapSceneMinTable[index];
-	int maxValue = itemMapSceneMaxTable[index];
-	
-	while (true) {
-		int room = _rnd.getRandomNumberRng(minValue, maxValue);
-		assert(room < _roomTableSize);
-		int nameIndex = _roomTable[room].nameIndex;
-		bool placeItem = false;
-		
-		switch (nameIndex) {
-			case 0:  case 1:   case 2:   case 3:
-			case 4:  case 5:   case 6:   case 11:
-			case 12: case 16:  case 17:  case 20:
-			case 22: case 23:  case 25:  case 26:
-			case 27: case 31:  case 33:  case 34:
-			case 36: case 37:  case 58:  case 59:
-			case 60: case 61:  case 83:  case 84:
-			case 85: case 104: case 105: case 106:
-				placeItem = true;
-			break;
-			
-			case 51:
-				if (room != 46) {
-					placeItem = true;
-					break;
-				}		
-			default:
-				placeItem = false;
-			break;
-		}
-		
-		if (placeItem) {
-			Room *roomPtr = &_roomTable[room];
-			if (roomPtr->northExit == 0xFFFF && roomPtr->eastExit == 0xFFFF && roomPtr->southExit == 0xFFFF && roomPtr->westExit == 0xFFFF) {
-				placeItem = false;
-			} else if (_currentCharacter->sceneId == room) {
-				placeItem = false;
-			}
-		}
-		
-		if (placeItem) {
-			if (!processItemDrop(room, item, -1, -1, 2, 0))
-				continue;
-			break;
-		}
-	}
-}
-
-void KyraEngine::createMouseItem(int item) {
-	debug(9, "KyraEngine::createMouseItem(%d)", item);
-	_screen->hideMouse();
-	setMouseItem(item);
-	_itemInHand = item;
-	_screen->showMouse();
-}
-
-void KyraEngine::destroyMouseItem() {
-	debug(9, "KyraEngine::destroyMouseItem()");
-	_screen->hideMouse();
-	_screen->setMouseCursor(1, 1, _shapes[4]);
-	_itemInHand = -1;
-	_screen->showMouse();
-}
-
-void KyraEngine::setMouseItem(int item) {
-	debug(9, "KyraEngine::setMouseItem(%d)", item);
-	if (item == -1) {
-		_screen->setMouseCursor(1, 1, _shapes[10]);
-	} else {
-		_screen->setMouseCursor(8, 15, _shapes[220+item]);
-	}
-}
-
-void KyraEngine::wipeDownMouseItem(int xpos, int ypos) {
-	debug(9, "KyraEngine::wipeDownMouseItem(%d, %d)", xpos, ypos);
-	if (_itemInHand == -1)
-		return;
-	xpos -= 8;
-	ypos -= 15;
-	_screen->hideMouse();
-	backUpRect1(xpos, ypos);
-	int y = ypos;
-	int height = 16;
-	
-	while (height >= 0) {
-		restoreRect1(xpos, ypos);
-		_screen->setNewShapeHeight(_shapes[220+_itemInHand], height);
-		uint32 nextTime = _system->getMillis() + 1 * _tickLength;
-		_screen->drawShape(0, _shapes[220+_itemInHand], xpos, y, 0, 0);
-		_screen->updateScreen();
-		y += 2;
-		height -= 2;
-		while (_system->getMillis() < nextTime) {}
-	}	
-	restoreRect1(xpos, ypos);
-	_screen->resetShapeHeight(_shapes[220+_itemInHand]);
-	destroyMouseItem();
-	_screen->showMouse();
-}
-
-void KyraEngine::setupSceneItems() {
-	debug(9, "KyraEngine::setupSceneItems()");
-	uint16 sceneId = _currentCharacter->sceneId;
-	assert(sceneId < _roomTableSize);
-	Room *currentRoom = &_roomTable[sceneId];
-	for (int i = 0; i < 12; ++i) {
-		uint8 item = currentRoom->itemsTable[i];
-		if (item == 0xFF || !currentRoom->needInit[i]) {
-			continue;
-		}
-		
-		int xpos = 0;
-		int ypos = 0;
-		
-		if (currentRoom->itemsXPos[i] == 0xFFFF) {
-			xpos = currentRoom->itemsXPos[i] = _rnd.getRandomNumberRng(24, 296);
-			ypos = currentRoom->itemsYPos[i] = _rnd.getRandomNumberRng(_northExitHeight & 0xFF, 130);
-		} else {
-			xpos = currentRoom->itemsXPos[i];
-			ypos = currentRoom->itemsYPos[i];
-		}
-		
-		_lastProcessedItem = i;
-		
-		int stop = 0;
-		while (!stop) {
-			stop = processItemDrop(sceneId, item, xpos, ypos, 3, 0);
-			if (!stop) {
-				xpos = currentRoom->itemsXPos[i] = _rnd.getRandomNumberRng(24, 296);
-				ypos = currentRoom->itemsYPos[i] = _rnd.getRandomNumberRng(_northExitHeight & 0xFF, 130);
-				if (countItemsInScene(sceneId) >= 12) {
-					break;
-				}
-			} else {
-				currentRoom->needInit[i] = 0;
-			}
-		}
-	}
-}
-
-int KyraEngine::countItemsInScene(uint16 sceneId) {
-	debug(9, "KyraEngine::countItemsInScene(%d)", sceneId);
-	assert(sceneId < _roomTableSize);
-	Room *currentRoom = &_roomTable[sceneId];
-	
-	int items = 0;
-	
-	for (int i = 0; i < 12; ++i) {
-		if (currentRoom->itemsTable[i] != 0xFF) {
-			++items;
-		}
-	}
-	
-	return items;
-}
-
-int KyraEngine::processItemDrop(uint16 sceneId, uint8 item, int x, int y, int unk1, int unk2) {
-	debug(9, "KyraEngine::processItemDrop(%d, %d, %d, %d, %d, %d)", sceneId, item, x, y, unk1, unk2);
-	int freeItem = -1;
-	uint8 itemIndex = findItemAtPos(x, y);
-	if (unk1) {
-		itemIndex = 0xFF;
-	}
-	
-	if (itemIndex != 0xFF) {
-		exchangeItemWithMouseItem(sceneId, itemIndex);
-		return 0;
-	}
-	
-	assert(sceneId < _roomTableSize);
-	Room *currentRoom = &_roomTable[sceneId];
-	
-	if (unk1 != 3) {
-		for (int i = 0; i < 12; ++i) {
-			if (currentRoom->itemsTable[i] == 0xFF) {
-				freeItem = i;
-				break;
-			}
-		}
-	} else {
-		freeItem = _lastProcessedItem;
-	}
-
-	if (freeItem == -1) {
-		return 0;
-	}
-	
-	if (sceneId != _currentCharacter->sceneId) {
-		addItemToRoom(sceneId, item, freeItem, x, y);
-		return 1;
-	}
-	
-	int itemHeight = _itemTable[item].height;
-	_lastProcessedItemHeight = itemHeight;
-	
-	if (x == -1 && x == -1) {
-		x = _rnd.getRandomNumberRng(16, 304);
-		y = _rnd.getRandomNumberRng(_northExitHeight & 0xFF, 135);
-	}
-	
-	int xpos = x;
-	int ypos = y;
-	int destY = -1;
-	int destX = -1;
-	int running = 1;
-
-	while (running) {
-		if ((_northExitHeight & 0xFF) <= ypos) {
-			bool running2 = true;
-			
-			if (getDrawLayer(xpos, ypos) > 1) {
-				if (((_northExitHeight >> 8) & 0xFF) != ypos) {
-					running2 = false;
-				}
-			}
-			
-			if (getDrawLayer2(xpos, ypos, itemHeight) > 1) {
-				if (((_northExitHeight >> 8) & 0xFF) != ypos) {
-					running2 = false;
-				}
-			}
-			
-			if (!isDropable(xpos, ypos)) {
-				if (((_northExitHeight >> 8) & 0xFF) != ypos) {
-					running2 = false;
-				}
-			}
-			
-			int xpos2 = xpos;
-			int xpos3 = xpos;
-			
-			while (running2) {
-				if (isDropable(xpos2, ypos)) {
-					if (getDrawLayer2(xpos2, ypos, itemHeight) < 7) {
-						if (findItemAtPos(xpos2, ypos) == 0xFF) {
-							destX = xpos2;
-							destY = ypos;
-							running = 0;
-							running2 = false;
-						}
-					}
-				}
-				
-				if (isDropable(xpos3, ypos)) {
-					if (getDrawLayer2(xpos3, ypos, itemHeight) < 7) {
-						if (findItemAtPos(xpos3, ypos) == 0xFF) {
-							destX = xpos3;
-							destY = ypos;
-							running = 0;
-							running2 = false;
-						}
-					}
-				}
-				
-				if (!running2)
-					continue;
-				
-				xpos2 -= 2;
-				if (xpos2 < 16) {
-					xpos2 = 16;
-				}
-				
-				xpos3 += 2;
-				if (xpos3 > 304) {
-					xpos3 = 304;
-				}
-				
-				if (xpos2 > 16)
-					continue;
-				if (xpos3 < 304)
-					continue;
-				running2 = false;
-			}
-		}
-		
-		if (((_northExitHeight >> 8) & 0xFF) == ypos) {
-			running = 0;
-			destY -= _rnd.getRandomNumberRng(0, 3);
-			
-			if ((_northExitHeight & 0xFF) < destY) {
-				continue;
-			}
-			
-			destY = (_northExitHeight & 0xFF) + 1;
-			continue;
-		}		
-		ypos += 2;
-		if (((_northExitHeight >> 8) & 0xFF) >= ypos) {
-			continue;
-		}
-		ypos = (_northExitHeight >> 8) & 0xFF;
-	}
-	
-	if (destX == -1 || destY == -1) {
-		return 0;
-	}
-	
-	if (unk1 == 3) {
-		currentRoom->itemsXPos[freeItem] = destX;
-		currentRoom->itemsYPos[freeItem] = destY;
-		return 1;
-	}
-	
-	if (unk1 == 2) {
-		itemSpecialFX(x, y, item);
-	}
-	
-	if (unk1 == 0) {
-		destroyMouseItem();
-	}
-	
-	itemDropDown(x, y, destX, destY, freeItem, item);
-	
-	if (unk1 == 0 && unk2 != 0) {
-		assert(_itemList && _droppedList);
-		updateSentenceCommand(_itemList[item], _droppedList[0], 179);
-	}
-	
-	return 1;
-}
-
-void KyraEngine::exchangeItemWithMouseItem(uint16 sceneId, int itemIndex) {
-	debug(9, "KyraEngine::exchangeItemWithMouseItem(%d, %d)", sceneId, itemIndex);
-	_screen->hideMouse();
-	_animator->animRemoveGameItem(itemIndex);
-	assert(sceneId < _roomTableSize);
-	Room *currentRoom = &_roomTable[sceneId];
-	
-	int item = currentRoom->itemsTable[itemIndex];
-	currentRoom->itemsTable[itemIndex] = _itemInHand;
-	_itemInHand = item;
-	_animator->animAddGameItem(itemIndex, sceneId);
-	snd_playSoundEffect(53);
-	
-	setMouseItem(_itemInHand);
-	assert(_itemList && _takenList);
-	updateSentenceCommand(_itemList[_itemInHand], _takenList[1], 179);
-	_screen->showMouse();
-	clickEventHandler2();
-}
-
-void KyraEngine::addItemToRoom(uint16 sceneId, uint8 item, int itemIndex, int x, int y) {
-	debug(9, "KyraEngine::addItemToRoom(%d, %d, %d, %d, %d)", sceneId, item, itemIndex, x, y);
-	assert(sceneId < _roomTableSize);
-	Room *currentRoom = &_roomTable[sceneId];
-	currentRoom->itemsTable[itemIndex] = item;
-	currentRoom->itemsXPos[itemIndex] = x;
-	currentRoom->itemsYPos[itemIndex] = y;
-	currentRoom->needInit[itemIndex] = 1;
-}
-
-int KyraEngine::checkNoDropRects(int x, int y) {
-	debug(9, "KyraEngine::checkNoDropRects(%d, %d)", x, y);
-	if (_lastProcessedItemHeight < 1 || _lastProcessedItemHeight > 16) {
-		_lastProcessedItemHeight = 16;
-	}
-	if (_noDropRects[0].x == -1) {
-		return 0;
-	}
-	
-	for (int i = 0; i < 11; ++i) {
-		if (_noDropRects[i].x == -1) {
-			break;
-		}
-		
-		int xpos = _noDropRects[i].x;
-		int ypos = _noDropRects[i].y;
-		int xpos2 = _noDropRects[i].x2;
-		int ypos2 = _noDropRects[i].y2;
-		
-		if (xpos > x + 16)
-			continue;
-		if (xpos2 < x)
-			continue;
-		if (y < ypos)
-			continue;
-		if (ypos2 < y - _lastProcessedItemHeight)
-			continue;
-		return 1;
-	}
-	
-	return 0;
-}
-
-int KyraEngine::isDropable(int x, int y) {
-	debug(9, "KyraEngine::isDropable(%d, %d)", x, y);
-	x -= 8;
-	y -= 1;
-	
-	if (checkNoDropRects(x, y)) {
-		return 0;
-	}
-	
-	for (int xpos = x; xpos < x + 16; ++xpos) {
-		if (_screen->getShapeFlag1(xpos, y) == 0) {
-			return 0;
-		}
-	}	
-	return 1;
-}
-
-void KyraEngine::itemDropDown(int x, int y, int destX, int destY, byte freeItem, int item) {
-	debug(9, "KyraEngine::itemDropDown(%d, %d, %d, %d, %d, %d)", x, y, destX, destY, freeItem, item);
-	assert(_currentCharacter->sceneId < _roomTableSize);
-	Room *currentRoom = &_roomTable[_currentCharacter->sceneId];
-	if (x == destX && y == destY) {
-		currentRoom->itemsXPos[freeItem] = destX;
-		currentRoom->itemsYPos[freeItem] = destY;
-		currentRoom->itemsTable[freeItem] = item;
-		snd_playSoundEffect(0x32);
-		_animator->animAddGameItem(freeItem, _currentCharacter->sceneId);
-		return;
-	}
-	_screen->hideMouse();
-	if (y <= destY) {
-		int tempY = y;
-		int addY = 2;
-		int drawX = x - 8;
-		int drawY = 0;
-		
-		backUpRect0(drawX, y - 16);
-		
-		while (tempY < destY) {
-			restoreRect0(drawX, tempY - 16);
-			tempY += addY;
-			if (tempY > destY) {
-				tempY = destY;
-			}
-			++addY;
-			drawY = tempY - 16;
-			backUpRect0(drawX, drawY);
-			uint32 nextTime = _system->getMillis() + 1 * _tickLength;
-			_screen->drawShape(0, _shapes[220+item], drawX, drawY, 0, 0);
-			_screen->updateScreen();
-			while (_system->getMillis() < nextTime) {
-				if ((nextTime - _system->getMillis()) >= 10)
-					delay(10);
-			}
-		}
-		
-		bool skip = false;
-		if (x == destX) {
-			if (destY - y <= 16) {
-				skip = true;
-			}
-		}
-		
-		if (!skip) {
-			snd_playSoundEffect(0x47);
-			if (addY < 6)
-				addY = 6;
-			
-			int xDiff = (destX - x) << 4;
-			xDiff /= addY;
-			int startAddY = addY;
-			addY >>= 1;
-			if (destY - y <= 8) {
-				addY >>= 1;
-			}
-			addY = -addY;
-			int unkX = x << 4;
-			while (--startAddY) {
-				drawX = (unkX >> 4) - 8;
-				drawY = tempY - 16;
-				restoreRect0(drawX, drawY);
-				tempY += addY;
-				unkX += xDiff;
-				if (tempY > destY) {
-					tempY = destY;
-				}
-				++addY;
-				drawX = (unkX >> 4) - 8;
-				drawY = tempY - 16;
-				backUpRect0(drawX, drawY);
-				uint32 nextTime = _system->getMillis() + 1 * _tickLength;
-				_screen->drawShape(0, _shapes[220+item], drawX, drawY, 0, 0);
-				_screen->updateScreen();
-				while (_system->getMillis() < nextTime) {
-					if ((nextTime - _system->getMillis()) >= 10)
-						delay(10);
-				}
-			}
-			restoreRect0(drawX, drawY);
-		} else {
-			restoreRect0(drawX, tempY - 16);
-		}
-	}
-	currentRoom->itemsXPos[freeItem] = destX;
-	currentRoom->itemsYPos[freeItem] = destY;
-	currentRoom->itemsTable[freeItem] = item;
-	snd_playSoundEffect(0x32);
-	_animator->animAddGameItem(freeItem, _currentCharacter->sceneId);
-	_screen->showMouse();
-}
-
-void KyraEngine::dropItem(int unk1, int item, int x, int y, int unk2) {
-	debug(9, "KyraEngine::dropItem(%d, %d, %d, %d, %d)", unk1, item, x, y, unk2);
-	if (processItemDrop(_currentCharacter->sceneId, item, x, y, unk1, unk2))
-		return;
-	snd_playSoundEffect(54);
-	if (12 == countItemsInScene(_currentCharacter->sceneId)) {
-		assert(_noDropList);
-		drawSentenceCommand(_noDropList[0], 6);
-	} else {
-		assert(_noDropList);
-		drawSentenceCommand(_noDropList[1], 6);
-	}
-}
-
-void KyraEngine::itemSpecialFX(int x, int y, int item) {
-	debug(9, "KyraEngine::itemSpecialFX(%d, %d, %d)", x, y, item);
-	if (item == 41) {
-		itemSpecialFX1(x, y, item);
-	} else {
-		itemSpecialFX2(x, y, item);
-	}
-}
-
-void KyraEngine::itemSpecialFX1(int x, int y, int item) {
-	debug(9, "KyraEngine::itemSpecialFX1(%d, %d, %d)", x, y, item);
-	uint8 *shape = _shapes[220+item];
-	x -= 8;
-	int startY = y;
-	y -= 15;
-	_screen->hideMouse();
-	backUpRect0(x, y);
-	for (int i = 1; i <= 16; ++i) {
-		_screen->setNewShapeHeight(shape, i);
-		--startY;
-		restoreRect0(x, y);
-		uint32 nextTime = _system->getMillis() + 1 * _tickLength;
-		_screen->drawShape(0, shape, x, startY, 0, 0);
-		_screen->updateScreen();
-		while (_system->getMillis() < nextTime) {
-			if ((nextTime - _system->getMillis()) >= 10)
-				delay(10);
-		}
-	}
-	restoreRect0(x, y);
-	_screen->showMouse();
-}
-
-void KyraEngine::itemSpecialFX2(int x, int y, int item) {
-	debug(9, "KyraEngine::itemSpecialFX2(%d, %d, %d)", x, y, item);
-	x -= 8;
-	y -= 15;
-	int yAdd = (int8)(((16 - _itemTable[item].height) >> 1) & 0xFF);
-	backUpRect0(x, y);
-	if (item >= 80 && item <= 89) {
-		snd_playSoundEffect(55);
-	}
-	
-	for (int i = 201; i <= 205; ++i) {
-		restoreRect0(x, y);
-		uint32 nextTime = _system->getMillis() + 3 * _tickLength;
-		_screen->drawShape(0, _shapes[4+i], x, y + yAdd, 0, 0);
-		_screen->updateScreen();
-		while (_system->getMillis() < nextTime) {
-			if ((nextTime - _system->getMillis()) >= 10)
-				delay(10);
-		}
-	}
-	
-	for (int i = 204; i >= 201; --i) {
-		restoreRect0(x, y);
-		uint32 nextTime = _system->getMillis() + 3 * _tickLength;
-		_screen->drawShape(0, _shapes[220+item], x, y, 0, 0);
-		_screen->drawShape(0, _shapes[4+i], x, y + yAdd, 0, 0);
-		_screen->updateScreen();
-		while (_system->getMillis() < nextTime) {
-			if ((nextTime - _system->getMillis()) >= 10)
-				delay(10);
-		}
-	}
-	restoreRect0(x, y);
-}
-
-void KyraEngine::magicOutMouseItem(int animIndex, int itemPos) {
-	debug(9, "KyraEngine::magicOutMouseItem(%d, %d)", animIndex, itemPos);
-	int videoPageBackUp = _screen->_curPage;
-	_screen->_curPage = 0;
-	int x = 0, y = 0;
-	if (itemPos == -1) {
-		x = _mouseX - 12;
-		y = _mouseY - 18;
-	} else {
-		x = _itemPosX[itemPos] - 4;
-		y = _itemPosY[itemPos] - 3;
-	}
-	
-	if (_itemInHand == -1 && itemPos == -1) {
-		return;
-	}
-	
-	int tableIndex = 0, loopStart = 0, maxLoops = 0;
-	if (animIndex == 0) {
-		tableIndex = _rnd.getRandomNumberRng(0, 5);
-		loopStart = 35;
-		maxLoops = 9;
-	} else if (animIndex == 1) {
-		tableIndex = _rnd.getRandomNumberRng(0, 11);
-		loopStart = 115;
-		maxLoops = 8;
-	} else if (animIndex == 2) {
-		tableIndex = 0;
-		loopStart = 124;
-		maxLoops = 4;
-	} else {
-		tableIndex = -1;
-	}
-	
-	if (animIndex == 2) {
-		snd_playSoundEffect(0x5E);
-	} else {
-		snd_playSoundEffect(0x37);
-	}
-	_screen->hideMouse();
-	backUpRect1(x, y);
-
-	for (int shape = _magicMouseItemStartFrame[animIndex]; shape <= _magicMouseItemEndFrame[animIndex]; ++shape) {
-		restoreRect1(x, y);
-		uint32 nextTime = _system->getMillis() + 4 * _tickLength;
-		_screen->drawShape(0, _shapes[220+_itemInHand], x + 4, y + 3, 0, 0);
-		if (tableIndex == -1) {
-			_screen->drawShape(0, _shapes[4+shape], x, y, 0, 0);
-		} else {
-			specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops);
-		}
-		_screen->updateScreen();
-		while (_system->getMillis() < nextTime) {
-			if (nextTime - _system->getMillis() >= 10)
-				delay(10);
-		}
-	}
-	
-	if (itemPos != -1) {
-		restoreRect1(x, y);
-		_screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, 12, 0);
-		backUpRect1(x, y);
-	}
-	
-	for (int shape = _magicMouseItemStartFrame2[animIndex]; shape <= _magicMouseItemEndFrame2[animIndex]; ++shape) {
-		restoreRect1(x, y);
-		uint32 nextTime = _system->getMillis() + 4 * _tickLength;
-		_screen->drawShape(0, _shapes[220+_itemInHand], x + 4, y + 3, 0, 0);
-		if (tableIndex == -1) {
-			_screen->drawShape(0, _shapes[4+shape], x, y, 0, 0);
-		} else {
-			specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops);
-		}
-		_screen->updateScreen();
-		while (_system->getMillis() < nextTime) {
-			if (nextTime - _system->getMillis() >= 10)
-				delay(10);
-		}
-	}
-	restoreRect1(x, y);
-	if (itemPos == -1) {
-		_screen->setMouseCursor(1, 1, _shapes[4]);
-		_itemInHand = -1;
-	} else {
-		_characterList[0].inventoryItems[itemPos] = 0xFF;
-		_screen->hideMouse();
-		_screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, 12, 0);
-		_screen->showMouse();
-	}
-	_screen->showMouse();
-	_screen->_curPage = videoPageBackUp;
-}
-
-void KyraEngine::magicInMouseItem(int animIndex, int item, int itemPos) {
-	debug(9, "KyraEngine::magicInMouseItem(%d, %d, %d)", animIndex, item, itemPos);
-	int videoPageBackUp = _screen->_curPage;
-	_screen->_curPage = 0;
-	int x = 0, y = 0;
-	if (itemPos == -1) {
-		x = _mouseX - 12;
-		y = _mouseY - 18;
-	} else {
-		x = _itemPosX[itemPos] - 4;
-		y = _itemPosX[itemPos] - 3;
-	}
-	if (item < 0)
-		return;
-
-	int tableIndex = -1, loopStart = 0, maxLoops = 0;
-	if (animIndex == 0) {
-		tableIndex = _rnd.getRandomNumberRng(0, 5);
-		loopStart = 35;
-		maxLoops = 9;
-	} else if (animIndex == 1) {
-		tableIndex = _rnd.getRandomNumberRng(0, 11);
-		loopStart = 115;
-		maxLoops = 8;
-	} else if (animIndex == 2) {
-		tableIndex = 0;
-		loopStart = 124;
-		maxLoops = 4;
-	}
-	
-	_screen->hideMouse();
-	backUpRect1(x, y);
-	if (animIndex == 2) {
-		snd_playSoundEffect(0x5E);
-	} else {
-		snd_playSoundEffect(0x37);
-	}
-	
-	for (int shape = _magicMouseItemStartFrame[animIndex]; shape <= _magicMouseItemEndFrame[animIndex]; ++shape) {
-		restoreRect1(x, y);
-		uint32 nextTime = _system->getMillis() + 4 * _tickLength;
-		if (tableIndex == -1) {
-			_screen->drawShape(0, _shapes[4+shape], x, y, 0, 0);
-		} else {
-			specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops);
-		}
-		_screen->updateScreen();
-		while (_system->getMillis() < nextTime) {
-			if (nextTime - _system->getMillis() >= 10)
-				delay(10);
-		}
-	}
-	
-	for (int shape = _magicMouseItemStartFrame2[animIndex]; shape <= _magicMouseItemEndFrame2[animIndex]; ++shape) {
-		restoreRect1(x, y);
-		uint32 nextTime = _system->getMillis() + 4 * _tickLength;
-		if (tableIndex == -1) {
-			_screen->drawShape(0, _shapes[4+shape], x, y, 0, 0);
-		} else {
-			specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops);
-		}
-		_screen->updateScreen();
-		while (_system->getMillis() < nextTime) {
-			if (nextTime - _system->getMillis() >= 10)
-				delay(10);
-		}
-	}
-	restoreRect1(x, y);
-	if (itemPos == -1) {
-		_screen->setMouseCursor(8, 15, _shapes[220+item]);
-		_itemInHand = item;
-	} else {
-		_characterList[0].inventoryItems[itemPos] = item;
-		_screen->hideMouse();
-		_screen->drawShape(0, _shapes[220+item], _itemPosX[itemPos], _itemPosY[itemPos], 0, 0);
-		_screen->showMouse();
-	}
-	_screen->showMouse();
-	_screen->_curPage = videoPageBackUp;
-}
-
-void KyraEngine::specialMouseItemFX(int shape, int x, int y, int animIndex, int tableIndex, int loopStart, int maxLoops) {
-	debug(9, "KyraEngine::specialMouseItemFX(%d, %d, %d, %d, %d, %d, %d)", shape, x, y, animIndex, tableIndex, loopStart, maxLoops);
-	static const uint8 table1[] = {
-		0x23, 0x45, 0x55, 0x72, 0x84, 0xCF, 0x00, 0x00
-	};
-	static const uint8 table2[] = {
-		0x73, 0xB5, 0x80, 0x21, 0x13, 0x39, 0x45, 0x55, 0x62, 0xB4, 0xCF, 0xD8
-	};
-	static const uint8 table3[] = {
-		0x7C, 0xD0, 0x74, 0x84, 0x87, 0x00, 0x00, 0x00
-	};
-	int tableValue = 0;
-	if (animIndex == 0) {
-		tableValue = table1[tableIndex];
-	} else if (animIndex == 1) {
-		tableValue = table2[tableIndex];
-	} else if (animIndex == 2) {
-		tableValue = table3[tableIndex];
-	} else {
-		return;
-	}
-	processSpecialMouseItemFX(shape, x, y, tableValue, loopStart, maxLoops);
-}
-
-void KyraEngine::processSpecialMouseItemFX(int shape, int x, int y, int tableValue, int loopStart, int maxLoops) {
-	debug(9, "KyraEngine::processSpecialMouseItemFX(%d, %d, %d, %d, %d, %d)", shape, x, y, tableValue, loopStart, maxLoops);
-	uint8 shapeColorTable[16];
-	uint8 *shapePtr = _shapes[4+shape] + 10;
-	if (_features & GF_TALKIE)
-		shapePtr += 2;
-	for (int i = 0; i < 16; ++i) {
-		shapeColorTable[i] = shapePtr[i];
-	}
-	for (int i = loopStart; i < loopStart + maxLoops; ++i) {
-		for (int i2 = 0; i2 < 16; ++i2) {
-			if (shapePtr[i2] == i) {
-				shapeColorTable[i2] = (i + tableValue) - loopStart;
-			}
-		}
-	}
-	_screen->drawShape(0, _shapes[4+shape], x, y, 0, 0x8000, shapeColorTable);
-}
-
-void KyraEngine::updatePlayerItemsForScene() {
-	debug(9, "KyraEngine::updatePlayerItemsForScene()");
-	if (_itemInHand >= 29 && _itemInHand < 33) {
-		++_itemInHand;
-		if (_itemInHand > 33)
-			_itemInHand = 33;
-		_screen->hideMouse();
-		_screen->setMouseCursor(8, 15, _shapes[220+_itemInHand]);
-		_screen->showMouse();
-	}
-	
-	bool redraw = false;
-	for (int i = 0; i < 10; ++i) {
-		uint8 item = _currentCharacter->inventoryItems[i];
-		if (item >= 29 && item < 33) {
-			++item;
-			if (item > 33)
-				item = 33;
-			_currentCharacter->inventoryItems[i] = item;
-			redraw = true;
-		}
-	}
-	
-	if (redraw) {
-		_screen->hideMouse();
-		redrawInventory(0);
-		_screen->showMouse();
-	}
-	
-	if (_itemInHand == 33) {
-		magicOutMouseItem(2, -1);
-	}
-	
-	_screen->hideMouse();
-	for (int i = 0; i < 10; ++i) {
-		uint8 item = _currentCharacter->inventoryItems[i];
-		if (item == 33) {
-			magicOutMouseItem(2, i);
-		}
-	}
-	_screen->showMouse();
-}
-
-void KyraEngine::redrawInventory(int page) {
-	int videoPageBackUp = _screen->_curPage;
-	_screen->_curPage = page;
-	_screen->hideMouse();
-	for (int i = 0; i < 10; ++i) {
-		_screen->fillRect(_itemPosX[i], _itemPosY[i], _itemPosX[i] + 15, _itemPosY[i] + 15, 12, page);
-		if (_currentCharacter->inventoryItems[i] != 0xFF) {
-			uint8 item = _currentCharacter->inventoryItems[i];
-			_screen->drawShape(page, _shapes[220+item], _itemPosX[i], _itemPosY[i], 0, 0);
-		}
-	}
-	_screen->showMouse();
-	_screen->_curPage = videoPageBackUp;
-	_screen->updateScreen();
-}
-
-#pragma mark -
 #pragma mark - Animation/shape specific code
 #pragma mark -
 
@@ -4507,126 +1047,6 @@
 	return (int16)(((int8)*(shape+2)) * mult) >> 8;
 }
 
-void KyraEngine::rectClip(int &x, int &y, int w, int h) {
-	if (x < 0) {
-		x = 0;
-	} else if (x + w >= 320) {
-		x = 320 - w;
-	}
-	if (y < 0) {
-		y = 0;
-	} else if (y + h >= 200) {
-		y = 200 - h;
-	}
-}
-
-void KyraEngine::backUpRect0(int xpos, int ypos) {
-	debug(9, "KyraEngine::backUpRect0(%d, %d)", xpos, ypos);
-	rectClip(xpos, ypos, 3<<3, 24);
-	_screen->copyRegionToBuffer(_screen->_curPage, xpos, ypos, 3<<3, 24, _shapes[0]);
-}
-
-void KyraEngine::restoreRect0(int xpos, int ypos) {
-	debug(9, "KyraEngine::restoreRect0(%d, %d)", xpos, ypos);
-	rectClip(xpos, ypos, 3<<3, 24);
-	_screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 3<<3, 24, _shapes[0]);
-}
-
-void KyraEngine::backUpRect1(int xpos, int ypos) {
-	debug(9, "KyraEngine::backUpRect1(%d, %d)", xpos, ypos);
-	rectClip(xpos, ypos, 4<<3, 32);
-	_screen->copyRegionToBuffer(_screen->_curPage, xpos, ypos, 4<<3, 32, _shapes[1]);
-}
-
-void KyraEngine::restoreRect1(int xpos, int ypos) {
-	debug(9, "KyraEngine::restoreRect1(%d, %d)", xpos, ypos);
-	rectClip(xpos, ypos, 4<<3, 32);
-	_screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 4<<3, 32, _shapes[1]);
-}
-
-int KyraEngine::getDrawLayer(int x, int y) {
-	debug(9, "KyraEngine::getDrawLayer(%d, %d)", x, y);
-	int xpos = x - 8;
-	int ypos = y - 1;
-	int layer = 1;
-	for (int curX = xpos; curX < xpos + 16; ++curX) {
-		int tempLayer = _screen->getShapeFlag2(curX, ypos);
-		if (layer < tempLayer) {
-			layer = tempLayer;
-		}
-		if (layer >= 7) {
-			return 7;
-		}
-	}
-	return layer;
-}
-
-int KyraEngine::getDrawLayer2(int x, int y, int height) {
-	debug(9, "KyraEngine::getDrawLayer2(%d, %d, %d)", x, y, height);
-	int xpos = x - 8;
-	int ypos = y - 1;
-	int layer = 1;
-	
-	for (int useX = xpos; useX < xpos + 16; ++useX) {
-		for (int useY = ypos - height; useY < ypos; ++useY) {
-			int tempLayer = _screen->getShapeFlag2(useX, useY);
-			if (tempLayer > layer) {
-				layer = tempLayer;
-			}
-			
-			if (tempLayer >= 7) {
-				return 7;
-			}
-		}
-	}	
-	return layer;
-}
-
-void KyraEngine::copyBackgroundBlock(int x, int page, int flag) {
-	debug(9, "KyraEngine::copyBackgroundBlock(%d, %d, %d)", x, page, flag);
-	
-	if (x < 1)
-		return;
-	
-	int height = 128;
-	if (flag)
-		height += 8;	
-	if (!(x & 1))
-		++x;
-	if (x == 19)
-		x = 17;
-	uint8 *ptr1 = _unkPtr1;
-	uint8 *ptr2 = _unkPtr2;
-	int oldVideoPage = _screen->_curPage;
-	_screen->_curPage = page;
-	
-	int curX = x;
-	_screen->hideMouse();
-	_screen->copyRegionToBuffer(_screen->_curPage, 8, 8, 8, height, ptr2);
-	for (int i = 0; i < 19; ++i) {
-		int tempX = curX + 1;
-		_screen->copyRegionToBuffer(_screen->_curPage, tempX<<3, 8, 8, height, ptr1);
-		_screen->copyBlockToPage(_screen->_curPage, tempX<<3, 8, 8, height, ptr2);
-		int newXPos = curX + x;
-		if (newXPos > 37) {
-			newXPos = newXPos % 38;
-		}
-		tempX = newXPos + 1;
-		_screen->copyRegionToBuffer(_screen->_curPage, tempX<<3, 8, 8, height, ptr2);
-		_screen->copyBlockToPage(_screen->_curPage, tempX<<3, 8, 8, height, ptr1);
-		curX += x*2;
-		if (curX > 37) {
-			curX = curX % 38;
-		}
-	}
-	_screen->showMouse();
-	_screen->_curPage = oldVideoPage;
-}
-
-void KyraEngine::copyBackgroundBlock2(int x) {
-	copyBackgroundBlock(x, 4, 1);
-}
-
 void KyraEngine::makeBrandonFaceMouse() {
 	debug(9, "KyraEngine::makeBrandonFaceMouse()");
 	if (_mouseX >= _currentCharacter->x1) {
@@ -5150,674 +1570,6 @@
 }
 
 #pragma mark -
-#pragma mark - Pathfinder
-#pragma mark -
-
-int KyraEngine::findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize) {
-	debug(9, "KyraEngine::findWay(%d, %d, %d, %d, 0x%X, %d)", x, y, toX, toY, 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;
-	return getMoveTableSize(moveTable);
-}
-
-int KyraEngine::findSubPath(int x, int y, int toX, int toY, int *moveTable, int start, int end) {
-	debug(9, "KyraEngine::findSubPath(%d, %d, %d, %d, 0x%X, %d, %d)", x, y, toX, toY, 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) {
-	debug(9, "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];
-}
-
-void KyraEngine::changePosTowardsFacing(int &x, int &y, int facing) {
-	debug(9, "KyraEngine::changePosTowardsFacing(%d, %d, %d)", x, y, facing);
-	x += _addXPosTable[facing];
-	y += _addYPosTable[facing];
-}
-
-bool KyraEngine::lineIsPassable(int x, int y) {
-	debug(9, "KyraEngine::lineIsPassable(%d, %d)", x, y);
-	if (queryGameFlag(0xEF)) {
-		if (_currentCharacter->sceneId == 5)
-			return true;
-	}
-	
-	if (_pathfinderFlag & 2) {
-		if (x >= 312)
-			return false;
-	}
-	
-	if (_pathfinderFlag & 4) {
-		if (y >= 136)
-			return false;
-	}
-	
-	if (_pathfinderFlag & 8) {
-		if (x < 8)
-			return false;
-	}
-	
-	if (_pathfinderFlag2) {
-		if (x <= 8 || x >= 312)
-			return true;
-		if (y < (_northExitHeight & 0xFF) || y > 135)
-			return true;
-	}
-	
-	if (y > 137) {
-		return false;
-	}
-	
-	int ypos = 8;
-	if (_scaleMode) {
-		ypos = (_scaleTable[y] >> 5) + 1;
-		if (8 < ypos)
-			ypos = 8;
-	}
-	
-	x -= (ypos >> 1);
-	if (y < 0)
-		y = 0;
-	
-	int xpos = x;
-	int xtemp = xpos + ypos - 1;
-	if (x < 0)
-		xpos = 0;
-		
-	if (xtemp > 319)
-		xtemp = 319;
-
-	for (; xpos < xtemp; ++xpos) {
-		if (!_screen->getShapeFlag1(xpos, y))
-			return false;
-	}
-	return true;
-}
-
-int KyraEngine::getMoveTableSize(int *moveTable) {
-	debug(9, "KyraEngine::getMoveTableSize(0x%X)", moveTable);
-	int retValue = 0;
-	if (moveTable[0] == 8)
-		return 0;
-	
-	static const int facingTable[] = {
-		4, 5, 6, 7, 0, 1, 2, 3
-	};
-	static const int unkTable[] = {
-		-1, -1,  1,  2, -1,  6,  7, -1,
-		-1, -1, -1, -1,  2, -1,  0, -1,
-		 1, -1, -1, -1,  3,  4, -1,  0,
-		 2, -1, -1, -1, -1, -1,  4, -1,
-		-1,  2,  3, -1, -1, -1,  5,  6,
-		 6, -1,  4, -1, -1, -1, -1, -1,
-		 7,  0, -1,  4,  5, -1, -1, -1,
-		-1, -1,  0, -1,  6, -1, -1, -1
-	};
-	
-	int *oldPosition = moveTable;
-	int *tempPosition = moveTable;
-	int *curPosition = moveTable + 1;
-	retValue = 1;
-
-	while (*curPosition != 8) {
-		if (*oldPosition == facingTable[*curPosition]) {
-			retValue -= 2;
-			*oldPosition = 9;
-			*curPosition = 9;
-			
-			while (tempPosition != moveTable) {
-				--tempPosition;
-				if (*tempPosition != 9)
-					break;
-			}
-			
-			if (tempPosition == moveTable && *tempPosition == 9) {
-				while (*tempPosition != 8 && *tempPosition == 9) {
-					++tempPosition;
-				}
-				if (*tempPosition == 8) {
-					return 0;
-				}
-			}
-			
-			oldPosition = tempPosition;
-			curPosition = oldPosition+1;
-			while (*curPosition != 8 && *curPosition == 9) {
-				++curPosition;
-			}
-			continue;
-		}
-		
-		if (unkTable[*curPosition+((*oldPosition)*8)] != -1) {
-			--retValue;
-			*oldPosition = unkTable[*curPosition+((*oldPosition)*8)];
-			*curPosition = 9;
-			
-			if (tempPosition != oldPosition) {
-				curPosition = oldPosition;
-				oldPosition = tempPosition;
-				while (true) {
-					if (tempPosition == moveTable) {
-						break;
-					}
-					--tempPosition;
-					if (*tempPosition != 9) {
-						break;
-					}
-				}
-			} else {
-				while (true) {
-					++curPosition;
-					if (*curPosition != 9) {
-						break;
-					}
-				}
-			}
-			continue;
-		}
-		
-		tempPosition = oldPosition;
-		oldPosition = curPosition;
-		++retValue;
-		while (true) {
-			++curPosition;
-			if (*curPosition != 9) {
-				break;
-			}
-		}
-	}
-
-	return retValue;
-}
-
-#pragma mark -
-#pragma mark - Scene handling
-#pragma mark -
-
-int KyraEngine::handleSceneChange(int xpos, int ypos, int unk1, int frameReset) {
-	debug(9, "KyraEngine::handleSceneChange(%d, %d, %d, %d)", xpos, ypos, unk1, frameReset);
-	if (queryGameFlag(0xEF)) {
-		unk1 = 0;
-	}
-	int sceneId = _currentCharacter->sceneId;
-	_pathfinderFlag = 0;
-	if (xpos < 12) {
-		if (_roomTable[sceneId].westExit != 0xFFFF) {
-			xpos = 12;
-			ypos = _sceneExits.westYPos;
-			_pathfinderFlag = 7;
-		}
-	} else if(xpos >= 308) {
-		if (_roomTable[sceneId].eastExit != 0xFFFF) {
-			xpos = 307;
-			ypos = _sceneExits.eastYPos;
-			_pathfinderFlag = 13;
-		}
-	}
-	
-	if (ypos <= (_northExitHeight&0xFF)+2) {
-		if (_roomTable[sceneId].northExit != 0xFFFF) {
-			xpos = _sceneExits.northXPos;
-			ypos = _northExitHeight & 0xFF;
-			_pathfinderFlag = 14;
-		}
-	} else if (ypos >= 136) {
-		if (_roomTable[sceneId].southExit != 0xFFFF) {
-			xpos = _sceneExits.southXPos;
-			ypos = 136;
-			_pathfinderFlag = 11;
-		}
-	}
-	
-	int temp = xpos - _currentCharacter->x1;
-	if (ABS(temp) < 4) {
-		temp = ypos - _currentCharacter->y1;
-		if (ABS(temp) < 2) {
-			return 0;
-		}
-	}
-	
-	int x = (int16)(_currentCharacter->x1 & 0xFFFC);
-	int y = (int16)(_currentCharacter->y1 & 0xFFFE);
-	xpos = (int16)(xpos & 0xFFFC);
-	ypos = (int16)(ypos & 0xFFFE);
-	int ret = findWay(x, y, xpos, ypos, _movFacingTable, 150);
-	_pathfinderFlag = 0;
-	if (ret >= _lastFindWayRet) {
-		_lastFindWayRet = ret;
-	}
-	if (ret == 0x7D00 || ret == 0) {
-		return 0;
-	}
-	return processSceneChange(_movFacingTable, unk1, frameReset);
-}
-
-int KyraEngine::processSceneChange(int *table, int unk1, int frameReset) {
-	debug(9, "KyraEngine::processSceneChange(0x%X, %d, %d)", table, unk1, frameReset);
-	if (queryGameFlag(0xEF)) {
-		unk1 = 0;
-	}
-	int *tableStart = table;
-	_sceneChangeState = 0;
-	_loopFlag2 = 0;
-	bool running = true;
-	int returnValue = 0;
-	uint32 nextFrame = 0;
-	_abortWalkFlag = false;
-	_mousePressFlag = false;
-
-	while (running) {
-		if (_abortWalkFlag) {
-			*table = 8;
-			_currentCharacter->currentAnimFrame = 7;
-			animRefreshNPC(0);
-			_animator->updateAllObjectShapes();
-			processInput(_mouseX, _mouseY);
-			return 0;
-		}
-		bool forceContinue = false;
-		switch (*table) {
-			case 0: case 1: case 2:
-			case 3: case 4: case 5:
-			case 6: case 7:
-				_currentCharacter->facing = getOppositeFacingDirection(*table);
-				break;
-			
-			case 8:
-				forceContinue = true;
-				running = false;
-				break;
-			
-			default:
-				++table;
-				forceContinue = true;
-				break;
-		}
-		
-		returnValue = changeScene(_currentCharacter->facing);
-		if (returnValue) {
-			running = false;
-			_abortWalkFlag = false;
-		}
-		
-		if (unk1) {
-			if (_mousePressFlag) {
-				running = false;
-				_sceneChangeState = 1;
-			}
-		}
-		
-		if (forceContinue || !running) {
-			continue;
-		}
-		
-		int temp = 0;
-		if (table == tableStart || table[1] == 8) {
-			temp = setCharacterPosition(0, 0);
-		} else {
-			temp = setCharacterPosition(0, table);
-		}
-		if (temp) {
-			++table;
-		}
-		
-		nextFrame = getTimerDelay(5) * _tickLength + _system->getMillis();
-		while (_system->getMillis() < nextFrame) {
-			_sprites->updateSceneAnims();
-			updateMousePointer();
-			updateGameTimers();
-			_animator->updateAllObjectShapes();
-			updateTextFade();
-			if (_currentCharacter->sceneId == 210) {
-				_animator->updateKyragemFading();
-				if (seq_playEnd() || _beadStateVar == 4 || _beadStateVar == 5) {
-					*table = 8;
-					running = false;
-					break;
-				}
-			}
-			if ((nextFrame - _system->getMillis()) >= 10)
-				delay(10);
-		}
-	}
-	
-	if (frameReset && !(_brandonStatusBit & 2)) {
-		_currentCharacter->currentAnimFrame = 7;
-	}
-	animRefreshNPC(0);
-	_animator->updateAllObjectShapes();
-	return returnValue;
-}
-
-int KyraEngine::changeScene(int facing) {
-	debug(9, "KyraEngine::changeScene(%d)", facing);
-	if (queryGameFlag(0xEF)) {
-		if (_currentCharacter->sceneId == 5) {
-			return 0;
-		}
-	}
-	
-	int xpos = _charXPosTable[facing] + _currentCharacter->x1;
-	int ypos = _charYPosTable[facing] + _currentCharacter->y1;
-	
-	if (xpos >= 12 && xpos <= 308) {
-		if (!lineIsPassable(xpos, ypos))
-			return false;
-	}
-	
-	if (_exitListPtr) {
-		int16 *ptr = _exitListPtr;
-		// this loop should be only entered on time, seems to be some hack in the original
-		while (true) {
-			if (*ptr == -1)
-				break;
-			
-			if (*ptr > _currentCharacter->x1 || _currentCharacter->y1 < ptr[1] || _currentCharacter->x1 > ptr[2] || _currentCharacter->y1 > ptr[3]) {
-				ptr += 10;
-				break;
-			}
-			_brandonPosX = ptr[6];
-			_brandonPosY = ptr[7];
-			uint16 sceneId = ptr[5];
-			facing = ptr[4];
-			int unk1 = ptr[8];
-			int unk2 = ptr[9];
-			if (sceneId == 0xFFFF) {
-				switch (facing) {
-					case 0:
-						sceneId = _roomTable[_currentCharacter->sceneId].northExit;
-						break;
-						
-					case 2:
-						sceneId = _roomTable[_currentCharacter->sceneId].eastExit;
-						break;
-					
-					case 4:
-						sceneId = _roomTable[_currentCharacter->sceneId].southExit;
-						break;
-						
-					case 6:
-						sceneId = _roomTable[_currentCharacter->sceneId].westExit;
-						break;
-						
-					default:
-						break;
-				}
-			}
-			
-			_currentCharacter->facing = facing;
-			animRefreshNPC(0);
-			_animator->updateAllObjectShapes();
-			enterNewScene(sceneId, facing, unk1, unk2, 0);
-			resetGameFlag(0xEE);
-			return 1;
-		}
-	}
-	
-	int returnValue = 0;
-	facing = 0;
-	
-	if ((_northExitHeight & 0xFF) + 2 >= ypos || (_northExitHeight & 0xFF) + 2 >= _currentCharacter->y1) {
-		facing = 0;
-		returnValue = 1;
-	}
-	
-	if (xpos >= 308 || (_currentCharacter->x1 + 4) >= 308) {
-		facing = 2;
-		returnValue = 1;
-	}
-	
-	if (((_northExitHeight >> 8) & 0xFF) - 2 < ypos || ((_northExitHeight >> 8) & 0xFF) - 2 < _currentCharacter->y1) {
-		facing = 4;
-		returnValue = 1;
-	}
-	
-	if (xpos <= 12 || _currentCharacter->y1 <= 12) {
-		facing = 6;
-		returnValue = 1;
-	}
-	
-	if (!returnValue)
-		return 0;
-	
-	uint16 sceneId = 0xFFFF;
-	switch (facing) {
-		case 0:
-			sceneId = _roomTable[_currentCharacter->sceneId].northExit;
-			break;
-		
-		case 2:
-			sceneId = _roomTable[_currentCharacter->sceneId].eastExit;
-			break;
-		
-		case 4:
-			sceneId = _roomTable[_currentCharacter->sceneId].southExit;
-			break;
-		
-		default:
-			sceneId = _roomTable[_currentCharacter->sceneId].westExit;
-			break;
-	}
-	
-	if (sceneId == 0xFFFF)
-		return 0;
-
-	enterNewScene(sceneId, facing, 1, 1, 0);
-	return returnValue;
-}
-
-#pragma mark -
 #pragma mark - Input
 #pragma mark -
 

Modified: scummvm/trunk/kyra/kyra.h
===================================================================
--- scummvm/trunk/kyra/kyra.h	2006-02-09 04:58:21 UTC (rev 20436)
+++ scummvm/trunk/kyra/kyra.h	2006-02-09 07:37:19 UTC (rev 20437)
@@ -245,6 +245,8 @@
 
 	uint8 game() const { return _game; }
 	uint32 features() const { return _features; }
+
+	uint8 **shapes() { return _shapes; }
 	
 	Common::RandomSource _rnd;
 	int16 _northExitHeight;
@@ -268,9 +270,7 @@
 	void loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData);
 
 	void snd_playTheme(int file, int track = 0);
-	void snd_playTrack(int track, bool looping = false);
 	void snd_playVoiceFile(int id);
-	bool snd_voicePlaying();
 	void snd_voiceWaitForFinish(bool ingame = true);
 	void snd_playSoundEffect(int track);
 	void snd_playWanderScoreViaMap(int command, int restart);
@@ -489,8 +489,6 @@
 	void setCharacterPositionHelper(int character, int *facingTable);
 	int getOppositeFacingDirection(int dir);
 	void loadSceneMSC();
-	void blockInRegion(int x, int y, int width, int height);
-	void blockOutRegion(int x, int y, int width, int height);
 	void startSceneScript(int brandonAlive);
 	void setupSceneItems();
 	void initSceneData(int facing, int unk1, int brandonAlive);
@@ -515,13 +513,6 @@
 	void destroyMouseItem();
 	void setMouseItem(int item);
 	void wipeDownMouseItem(int xpos, int ypos);
-	void rectClip(int &x, int &y, int w, int h);
-	void backUpRect0(int xpos, int ypos);
-	void restoreRect0(int xpos, int ypos);
-	void backUpRect1(int xpos, int ypos);
-	void restoreRect1(int xpos, int ypos);
-	void copyBackgroundBlock(int x, int page, int flag);
-	void copyBackgroundBlock2(int x);
 	void makeBrandonFaceMouse();
 	void setBrandonPoisonFlags(int reset);
 	void resetBrandonPoisonFlags();
@@ -539,8 +530,6 @@
 	int processItemDrop(uint16 sceneId, uint8 item, int x, int y, int unk1, int unk2);
 	void exchangeItemWithMouseItem(uint16 sceneId, int itemIndex);
 	void addItemToRoom(uint16 sceneId, uint8 item, int itemIndex, int x, int y);
-	int getDrawLayer(int x, int y);
-	int getDrawLayer2(int x, int y, int height);
 	int checkNoDropRects(int x, int y);
 	int isDropable(int x, int y);
 	void itemDropDown(int x, int y, int destX, int destY, byte freeItem, int item);
@@ -590,8 +579,6 @@
 	void seq_playEnding();
 	void seq_playCredits();
 	
-	void snd_startTrack();
-	void snd_haltTrack();
 	void snd_setSoundEffectFile(int file);
 	
 	static OpcodeProc _opcodeTable[];
@@ -623,8 +610,6 @@
 	void initMainButtonList();
 	void loadMainScreen(int page = 3);
 	void setCharactersInDefaultScene();
-	void resetBrandonPosionFlags();
-	void initAnimStateList();
 	void setupPanPages();
 	void freePanPages();
 	void closeFinalWsa();
@@ -700,7 +685,6 @@
 	bool _abortWalkFlag2;
 	bool _mousePressFlag;
 	uint8 _flagsTable[53];
-	uint8 *_unkPtr1, *_unkPtr2;
 	uint8 *_shapes[377];
 	uint16 _gameSpeed;
 	uint16 _tickLength;

Modified: scummvm/trunk/kyra/module.mk
===================================================================
--- scummvm/trunk/kyra/module.mk	2006-02-09 04:58:21 UTC (rev 20436)
+++ scummvm/trunk/kyra/module.mk	2006-02-09 07:37:19 UTC (rev 20437)
@@ -14,6 +14,9 @@
 	kyra/debugger.o \
 	kyra/animator.o \
 	kyra/gui.o \
+	kyra/sequences.o \
+	kyra/items.o \
+	kyra/scene.o \
 	kyra/text.o \
 	kyra/timer.o \
 	kyra/saveload.o

Modified: scummvm/trunk/kyra/resource.cpp
===================================================================
--- scummvm/trunk/kyra/resource.cpp	2006-02-09 04:58:21 UTC (rev 20436)
+++ scummvm/trunk/kyra/resource.cpp	2006-02-09 07:37:19 UTC (rev 20437)
@@ -24,6 +24,7 @@
 #include "kyra/resource.h"
 #include "kyra/script.h"
 #include "kyra/wsamovie.h"
+#include "kyra/screen.h"
 
 namespace Kyra {
 Resource::Resource(KyraEngine* engine) {
@@ -279,5 +280,48 @@
 	}
 	return 0;
 }
+
+void KyraEngine::loadPalette(const char *filename, uint8 *palData) {
+	debug(9, "KyraEngine::loadPalette('%s' 0x%X)", filename, palData);
+	uint32 fileSize = 0;
+	uint8 *srcData = _res->fileData(filename, &fileSize);
+
+	if (palData && fileSize) {
+		debug(9, "Loading a palette of size %i from '%s'", fileSize, filename);
+		memcpy(palData, srcData, fileSize);
+	}
+	delete [] srcData;
+}
+
+void KyraEngine::loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData) {
+	debug(9, "KyraEngine::copyBitmap('%s', %d, %d, 0x%X)", filename, tempPage, dstPage, palData);
+	uint32 fileSize;
+	uint8 *srcData = _res->fileData(filename, &fileSize);
+	uint8 compType = srcData[2];
+	uint32 imgSize = READ_LE_UINT32(srcData + 4);
+	uint16 palSize = READ_LE_UINT16(srcData + 8);
+	if (palData && palSize) {
+		debug(9, "Loading a palette of size %i from %s", palSize, filename);
+		memcpy(palData, srcData + 10, palSize);		
+	}
+	uint8 *srcPtr = srcData + 10 + palSize;
+	uint8 *dstData = _screen->getPagePtr(dstPage);
+	switch (compType) {
+	case 0:
+		memcpy(dstData, srcPtr, imgSize);
+		break;
+	case 3:
+		Screen::decodeFrame3(srcPtr, dstData, imgSize);
+		break;
+	case 4:
+		Screen::decodeFrame4(srcPtr, dstData, imgSize);
+		break;
+	default:
+		error("Unhandled bitmap compression %d", compType);
+		break;
+	}
+	delete[] srcData;
+}
+
 } // end of namespace Kyra
 

Added: scummvm/trunk/kyra/scene.cpp
===================================================================
--- scummvm/trunk/kyra/scene.cpp	                        (rev 0)
+++ scummvm/trunk/kyra/scene.cpp	2006-02-09 07:37:19 UTC (rev 20437)
@@ -0,0 +1,1579 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "kyra/kyra.h"
+#include "kyra/seqplayer.h"
+#include "kyra/screen.h"
+#include "kyra/resource.h"
+#include "kyra/sound.h"
+#include "kyra/sprites.h"
+#include "kyra/wsamovie.h"
+#include "kyra/animator.h"
+#include "kyra/text.h"
+#include "kyra/script.h"
+
+#include "common/system.h"
+#include "common/savefile.h"
+
+namespace Kyra {
+
+void KyraEngine::enterNewScene(int sceneId, int facing, int unk1, int unk2, int brandonAlive) {
+	debug(9, "KyraEngine::enterNewScene(%d, %d, %d, %d, %d)", sceneId, facing, unk1, unk2, brandonAlive);
+	int unkVar1 = 1;
+	_screen->hideMouse();
+	_handleInput = false;
+	_abortWalkFlag = false;
+	_abortWalkFlag2 = false;
+	if (_currentCharacter->sceneId == 7 && sceneId == 24) {
+		_newMusicTheme = 3;
+	} else if (_currentCharacter->sceneId == 25 && sceneId == 109) {
+		_newMusicTheme = 4;
+	} else if (_currentCharacter->sceneId == 120 && sceneId == 37) {
+		_newMusicTheme = 5;
+	} else if (_currentCharacter->sceneId == 52 && sceneId == 199) {
+		_newMusicTheme = 6;
+	} else if (_currentCharacter->sceneId == 37 && sceneId == 120) {
+		_newMusicTheme = 4;
+	} else if (_currentCharacter->sceneId == 109 && sceneId == 25) {
+		_newMusicTheme = 3;
+	} else if (_currentCharacter->sceneId == 24 && sceneId == 7) {
+		_newMusicTheme = 2;
+	}
+	if (_newMusicTheme != _curMusicTheme) {
+		snd_playTheme(_newMusicTheme);
+	}
+	
+	switch (_currentCharacter->sceneId) {
+		case 1:
+			if (sceneId == 0) {
+				moveCharacterToPos(0, 0, _currentCharacter->x1, 84);
+				unkVar1 = 0;
+			}
+		break;
+		
+		case 3:
+			if (sceneId == 2) {
+				moveCharacterToPos(0, 6, 155, _currentCharacter->y1);
+				unkVar1 = 0;
+			}
+		break;
+		
+		case 26:
+			if (sceneId == 27) {
+				moveCharacterToPos(0, 6, 155, _currentCharacter->y1);
+				unkVar1 = 0;
+			}
+		break;
+		
+		case 44:
+			if (sceneId == 45) {
+				moveCharacterToPos(0, 2, 192, _currentCharacter->y1);
+				unkVar1 = 0;
+			}
+		break;
+		
+		default:
+		break;
+	}
+	
+	if (unkVar1 && unk1) {
+		int xpos = _currentCharacter->x1;
+		int ypos = _currentCharacter->y1;
+		switch (facing) {
+			case 0:
+				ypos = _currentCharacter->y1 - 6;
+			break;
+			
+			case 2:
+				xpos = 336;
+			break;
+			
+			case 4:
+				ypos = 143;
+			break;
+			
+			case 6:
+				xpos = -16;
+			break;
+			
+			default:
+			break;
+		}
+		
+		moveCharacterToPos(0, facing, xpos, ypos);
+	}
+	
+	for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) {
+		_movieObjects[i]->close();
+	}
+	
+	if (!brandonAlive) {
+		_scriptInterpreter->initScript(_scriptClick, _scriptClickData);
+		_scriptInterpreter->startScript(_scriptClick, 5);
+		while (_scriptInterpreter->validScript(_scriptClick)) {
+			_scriptInterpreter->runScript(_scriptClick);
+		}
+	}
+	
+	memset(_entranceMouseCursorTracks, 0xFFFF, sizeof(uint16)*4);
+	_currentCharacter->sceneId = sceneId;
+	
+	assert(sceneId < _roomTableSize);
+	assert(_roomTable[sceneId].nameIndex < _roomFilenameTableSize);
+
+	Room *currentRoom = &_roomTable[sceneId];
+	
+	if (_currentRoom != 0xFFFF && (_features & GF_TALKIE)) {
+		char file[32];
+		assert(_currentRoom < _roomTableSize);
+		int tableId = _roomTable[_currentRoom].nameIndex;
+		assert(tableId < _roomFilenameTableSize);
+		strcpy(file, _roomFilenameTable[tableId]);
+		strcat(file, ".VRM");
+		_res->unloadPakFile(file);
+	}
+	
+	_currentRoom = sceneId;
+	
+	int tableId = _roomTable[_currentCharacter->sceneId].nameIndex;
+	char fileNameBuffer[32];
+	strcpy(fileNameBuffer, _roomFilenameTable[tableId]);
+	strcat(fileNameBuffer, ".DAT");
+	_sprites->loadDAT(fileNameBuffer, _sceneExits);
+	_sprites->setupSceneAnims();
+	_scriptInterpreter->unloadScript(_scriptClickData);
+	loadSceneMSC();
+	
+	if ((_features & GF_TALKIE)) {
+		strcpy(fileNameBuffer, _roomFilenameTable[tableId]);
+		strcat(fileNameBuffer, ".VRM");
+		_res->loadPakFile(fileNameBuffer);
+	}
+	
+	_walkBlockNorth = currentRoom->northExit;
+	_walkBlockEast = currentRoom->eastExit;
+	_walkBlockSouth = currentRoom->southExit;
+	_walkBlockWest = currentRoom->westExit;
+	
+	if (_walkBlockNorth == 0xFFFF) {
+		_screen->blockOutRegion(0, 0, 320, (_northExitHeight & 0xFF)+3);
+	}
+	if (_walkBlockEast == 0xFFFF) {
+		_screen->blockOutRegion(312, 0, 8, 139);
+	}
+	if (_walkBlockSouth == 0xFFFF) {
+		_screen->blockOutRegion(0, 135, 320, 8);
+	}
+	if (_walkBlockWest == 0xFFFF) {
+		_screen->blockOutRegion(0, 0, 8, 139);
+	}
+	
+	if (!brandonAlive) {
+		updatePlayerItemsForScene();
+	}
+
+	startSceneScript(brandonAlive);
+	setupSceneItems();
+	
+	initSceneData(facing, unk2, brandonAlive);
+	
+	_loopFlag2 = 0;
+	_screen->showMouse();
+	if (!brandonAlive) {
+		seq_poisonDeathNow(0);
+	}
+	updateMousePointer(true);
+	_changedScene = true;
+}
+
+void KyraEngine::transcendScenes(int roomIndex, int roomName) {
+	debug(9, "KyraEngine::transcendScenes(%d, %d)", roomIndex, roomName);
+	assert(roomIndex < _roomTableSize);
+	if (_features & GF_TALKIE) {
+		char file[32];
+		assert(roomIndex < _roomTableSize);
+		int tableId = _roomTable[roomIndex].nameIndex;
+		assert(tableId < _roomFilenameTableSize);
+		strcpy(file, _roomFilenameTable[tableId]);
+		strcat(file, ".VRM");
+		_res->unloadPakFile(file);
+	}
+	_roomTable[roomIndex].nameIndex = roomName;
+	_unkScreenVar2 = 1;
+	_unkScreenVar3 = 1;
+	_unkScreenVar1 = 0;
+	_brandonPosX = _currentCharacter->x1;
+	_brandonPosY = _currentCharacter->y1;
+	enterNewScene(roomIndex, _currentCharacter->facing, 0, 0, 0);
+	_unkScreenVar1 = 1;
+	_unkScreenVar2 = 0;
+	_unkScreenVar3 = 0;
+}
+
+void KyraEngine::setSceneFile(int roomIndex, int roomName) {
+	debug(9, "KyraEngine::setSceneFile(%d, %d)", roomIndex, roomName);
+	assert(roomIndex < _roomTableSize);
+	_roomTable[roomIndex].nameIndex = roomName;
+}
+
+void KyraEngine::moveCharacterToPos(int character, int facing, int xpos, int ypos) {
+	debug(9, "KyraEngine::moveCharacterToPos(%d, %d, %d, %d)", character, facing, xpos, ypos);
+	Character *ch = &_characterList[character];
+	ch->facing = facing;
+	_screen->hideMouse();
+	xpos = (int16)(xpos & 0xFFFC);
+	ypos = (int16)(ypos & 0xFFFE);
+	disableTimer(19);
+	disableTimer(14);
+	disableTimer(18);
+	uint32 nextFrame = 0;
+	switch (facing) {
+		case 0:
+			while (ypos < ch->y1) {
+				nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis();
+				setCharacterPositionWithUpdate(character);
+				while (_system->getMillis() < nextFrame) { updateGameTimers(); }
+			}
+			break;
+		
+		case 2:	
+			while (ch->x1 < xpos) {
+				nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis();
+				setCharacterPositionWithUpdate(character);
+				while (_system->getMillis() < nextFrame) { updateGameTimers(); }
+			}
+			break;
+		
+		case 4:
+			while (ypos > ch->y1) {
+				nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis();
+				setCharacterPositionWithUpdate(character);
+				while (_system->getMillis() < nextFrame) { updateGameTimers(); }
+			}
+			break;
+		
+		case 6:
+			while (ch->x1 > xpos) {
+				nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis();
+				setCharacterPositionWithUpdate(character);
+				while (_system->getMillis() < nextFrame) { updateGameTimers(); }
+			}
+			break;
+		
+		default:
+			break;
+	}
+	enableTimer(19);
+	enableTimer(14);
+	enableTimer(18);
+	_screen->showMouse();
+}
+
+void KyraEngine::setCharacterPositionWithUpdate(int character) {
+	debug(9, "KyraEngine::setCharacterPositionWithUpdate(%d)", character);
+	setCharacterPosition(character, 0);
+	_sprites->updateSceneAnims();
+	updateGameTimers();
+	_animator->updateAllObjectShapes();
+	updateTextFade();
+
+	if (_currentCharacter->sceneId == 210) {
+		_animator->updateKyragemFading();
+	}
+}
+
+int KyraEngine::setCharacterPosition(int character, int *facingTable) {
+	debug(9, "KyraEngine::setCharacterPosition(%d, 0x%X)", character, facingTable);
+	if (character == 0) {
+		_currentCharacter->x1 += _charXPosTable[_currentCharacter->facing];
+		_currentCharacter->y1 += _charYPosTable[_currentCharacter->facing];
+		setCharacterPositionHelper(0, facingTable);
+		return 1;
+	} else {
+		_characterList[character].x1 += _charXPosTable[_characterList[character].facing];
+		_characterList[character].y1 += _charYPosTable[_characterList[character].facing];
+		if (_characterList[character].sceneId == _currentCharacter->sceneId) {
+			setCharacterPositionHelper(character, 0);
+		}
+	}
+	return 0;
+}
+
+void KyraEngine::setCharacterPositionHelper(int character, int *facingTable) {
+	debug(9, "KyraEngine::setCharacterPositionHelper(%d, 0x%X)", character, facingTable);
+	Character *ch = &_characterList[character];
+	++ch->currentAnimFrame;
+	int facing = ch->facing;
+	if (facingTable) {
+		if (*facingTable != *(facingTable - 1)) {
+			if (*(facingTable - 1) == *(facingTable + 1)) {
+				facing = getOppositeFacingDirection(*(facingTable - 1));
+				*facingTable = *(facingTable - 1);
+			}
+		}
+	}
+	
+	static uint8 facingIsZero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+	static uint8 facingIsFour[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+	
+	if (facing == 0) {
+		++facingIsZero[character];
+	} else {
+		bool resetTables = false;
+		if (facing != 7) {
+			if (facing - 1 != 0) {
+				if (facing != 4) {
+					if (facing == 3 || facing == 5) {
+						if (facingIsFour[character] > 2) {
+							facing = 4;
+						}
+						resetTables = true;
+					}
+				} else {
+					++facingIsFour[character];
+				}
+			} else {
+				if (facingIsZero[character] > 2) {
+					facing = 0;
+				}
+				resetTables = true;
+			}
+		} else {
+			if (facingIsZero[character] > 2) {
+				facing = 0;
+			}
+			resetTables = true;
+		}
+		
+		if (resetTables) {
+			facingIsZero[character] = 0;
+			facingIsFour[character] = 0;
+		}
+	}
+	
+	static const uint16 maxAnimationFrame[] = {
+		0x000F, 0x0031, 0x0055, 0x0000, 0x0000, 0x0000,
+		0x0008, 0x002A, 0x004E, 0x0000, 0x0000, 0x0000,
+		0x0022, 0x0046, 0x006A, 0x0000, 0x0000, 0x0000,
+		0x001D, 0x0041, 0x0065, 0x0000, 0x0000, 0x0000,
+		0x001F, 0x0043, 0x0067, 0x0000, 0x0000, 0x0000,
+		0x0028, 0x004C, 0x0070, 0x0000, 0x0000, 0x0000,
+		0x0023, 0x0047, 0x006B, 0x0000, 0x0000, 0x0000
+	};
+	
+	if (facing == 0) {
+		if (maxAnimationFrame[36+character] > ch->currentAnimFrame) {
+			ch->currentAnimFrame = maxAnimationFrame[36+character];
+		}
+		if (maxAnimationFrame[30+character] < ch->currentAnimFrame) {
+			ch->currentAnimFrame = maxAnimationFrame[36+character];
+		}
+	} else if (facing == 4) {
+		if (maxAnimationFrame[18+character] > ch->currentAnimFrame) {
+			ch->currentAnimFrame = maxAnimationFrame[18+character];
+		}
+		if (maxAnimationFrame[12+character] < ch->currentAnimFrame) {
+			ch->currentAnimFrame = maxAnimationFrame[18+character];
+		}
+	} else {
+		if (maxAnimationFrame[18+character] < ch->currentAnimFrame) {
+			ch->currentAnimFrame = maxAnimationFrame[30+character];
+		}
+		if (maxAnimationFrame[character] == ch->currentAnimFrame) {
+			ch->currentAnimFrame = maxAnimationFrame[6+character];
+		}
+		if (maxAnimationFrame[character] < ch->currentAnimFrame) {
+			ch->currentAnimFrame = maxAnimationFrame[6+character]+2;
+		}
+	}
+	
+	if (character == 0) {
+		if (_brandonStatusBit & 0x10)
+			ch->currentAnimFrame = 88;
+	}
+	
+	animRefreshNPC(character);
+}
+
+int KyraEngine::getOppositeFacingDirection(int dir) {
+	debug(9, "KyraEngine::getOppositeFacingDirection(%d)", dir);
+	switch (dir) {
+		case 0:
+			return 2;
+			break;
+			
+		case 1:
+			return 1;
+			break;
+			
+		case 3:
+			return 7;
+			break;
+			
+		case 4:
+			return 6;
+			break;
+			
+		case 5:
+			return 5;
+			break;
+			
+		case 6:
+			return 4;
+			break;
+			
+		case 7:
+			return 3;
+			break;
+			
+		default:
+			break;
+	}
+	return 0;
+}
+
+void KyraEngine::loadSceneMSC() {
+	assert(_currentCharacter->sceneId < _roomTableSize);
+	int tableId = _roomTable[_currentCharacter->sceneId].nameIndex;
+	assert(tableId < _roomFilenameTableSize);
+	char fileNameBuffer[32];
+	strcpy(fileNameBuffer, _roomFilenameTable[tableId]);
+	strcat(fileNameBuffer, ".MSC");
+	_screen->fillRect(0, 0, 319, 199, 0, 5);
+	loadBitmap(fileNameBuffer, 3, 5, 0);
+}
+
+void KyraEngine::startSceneScript(int brandonAlive) {
+	debug(9, "KyraEngine::startSceneScript(%d)", brandonAlive);
+	assert(_currentCharacter->sceneId < _roomTableSize);
+	int tableId = _roomTable[_currentCharacter->sceneId].nameIndex;
+	assert(tableId < _roomFilenameTableSize);
+	char fileNameBuffer[32];
+	strcpy(fileNameBuffer, _roomFilenameTable[tableId]);
+	strcat(fileNameBuffer, ".CPS");
+	loadBitmap(fileNameBuffer, 3, 3, 0);
+	_sprites->loadSceneShapes();
+	_exitListPtr = 0;
+
+	_screen->setScreenPalette(_screen->_currentPalette);
+	
+	_scaleMode = 1;	
+	for (int i = 0; i < 145; ++i) {
+		_scaleTable[i] = 256;
+	}
+	
+	clearNoDropRects();
+	_scriptInterpreter->initScript(_scriptClick, _scriptClickData);
+	strcpy(fileNameBuffer, _roomFilenameTable[tableId]);
+	strcat(fileNameBuffer, ".EMC");
+	_scriptInterpreter->unloadScript(_scriptClickData);
+	_scriptInterpreter->loadScript(fileNameBuffer, _scriptClickData, _opcodeTable, _opcodeTableSize, 0);
+	_scriptInterpreter->startScript(_scriptClick, 0);
+	_scriptClick->variables[0] = _currentCharacter->sceneId;
+	_scriptClick->variables[7] = brandonAlive;
+	
+	while (_scriptInterpreter->validScript(_scriptClick)) {
+		_scriptInterpreter->runScript(_scriptClick);
+	}
+}
+
+void KyraEngine::initSceneData(int facing, int unk1, int brandonAlive) {
+	debug(9, "KyraEngine::initSceneData(%d, %d, %d)", facing, unk1, brandonAlive);
+	
+	int16 xpos2 = 0;
+	int setFacing = 1;
+	
+	int16 xpos = 0, ypos = 0;
+	
+	if (_brandonPosX == -1 && _brandonPosY == -1) {
+		switch (facing+1) {
+			case 0:
+				xpos = ypos = -1;
+			break;
+			
+			case 1: case 2: case 8:
+				xpos = _sceneExits.southXPos;
+				ypos = _sceneExits.southYPos;
+				break;
+			
+			case 3:
+				xpos = _sceneExits.westXPos;
+				ypos = _sceneExits.westYPos;
+				break;
+			
+			case 4: case 5: case 6:
+				xpos = _sceneExits.northXPos;
+				ypos = _sceneExits.northYPos;
+				break;
+			
+			case 7:
+				xpos = _sceneExits.eastXPos;
+				ypos = _sceneExits.eastYPos;
+				break;
+			
+			default:
+			break;
+		}
+		
+		if ((uint8)(_northExitHeight & 0xFF) + 2 >= ypos) {
+			ypos = (_northExitHeight & 0xFF) + 4;
+		}
+		if (xpos >= 308) {
+			xpos = 304;
+		}
+		if ((uint8)(_northExitHeight >> 8) - 2 <= ypos) {
+			ypos = (_northExitHeight >> 8) - 4;
+		}
+		if (xpos <= 12) {
+			xpos = 16;
+		}
+	}
+	
+	if (_brandonPosX > -1) {
+		xpos = _brandonPosX;
+	}
+	if (_brandonPosY > -1) {
+		ypos = _brandonPosY;
+	}
+	
+	int16 ypos2 = 0;
+	if (_brandonPosX > -1 && _brandonPosY > -1) {
+		switch (_currentCharacter->sceneId) {
+			case 1:
+				_currentCharacter->x1 = xpos;
+				_currentCharacter->x2 = xpos;
+				_currentCharacter->y1 = ypos;
+				_currentCharacter->y2 = ypos;
+				facing = 4;
+				xpos2 = 192;
+				ypos2 = 104;
+				setFacing = 0;
+				unk1 = 1;
+				break;
+				
+			case 3:
+				_currentCharacter->x1 = xpos;
+				_currentCharacter->x2 = xpos;
+				_currentCharacter->y1 = ypos;
+				_currentCharacter->y2 = ypos;
+				facing = 2;
+				xpos2 = 204;
+				ypos2 = 94;
+				setFacing = 0;
+				unk1 = 1;
+				break;
+				
+			case 26:
+				_currentCharacter->x1 = xpos;
+				_currentCharacter->x2 = xpos;
+				_currentCharacter->y1 = ypos;
+				_currentCharacter->y2 = ypos;
+				facing = 2;
+				xpos2 = 192;
+				ypos2 = 128;
+				setFacing = 0;
+				unk1 = 1;
+				break;
+				
+			case 44:
+				_currentCharacter->x1 = xpos;
+				_currentCharacter->x2 = xpos;
+				_currentCharacter->y1 = ypos;
+				_currentCharacter->y2 = ypos;
+				facing = 6;
+				xpos2 = 156;
+				ypos2 = 96;
+				setFacing = 0;
+				unk1 = 1;
+				break;
+				
+			case 37:
+				_currentCharacter->x1 = xpos;
+				_currentCharacter->x2 = xpos;
+				_currentCharacter->y1 = ypos;
+				_currentCharacter->y2 = ypos;
+				facing = 2;
+				xpos2 = 148;
+				ypos2 = 114;
+				setFacing = 0;
+				unk1 = 1;
+				break;
+				
+			default:
+				break;
+		}
+	}
+	
+	_brandonPosX = _brandonPosY = -1;
+	
+	if (unk1 && setFacing) {
+		ypos2 = ypos;
+		xpos2 = xpos;
+		switch (facing) {
+			case 0:
+				ypos = 142;
+				break;
+				
+			case 2:
+				xpos = -16;
+				break;
+				
+			case 4:
+				ypos = (uint8)(_northExitHeight & 0xFF) - 4;
+				break;
+				
+			case 6:
+				xpos = 336;
+				break;
+				
+			default:
+				break;
+		}
+	}
+	
+	xpos2 = (int16)(xpos2 & 0xFFFC);
+	ypos2 = (int16)(ypos2 & 0xFFFE);
+	xpos = (int16)(xpos & 0xFFFC);
+	ypos = (int16)(ypos & 0xFFFE);
+	_currentCharacter->facing = facing;
+	_currentCharacter->x1 = xpos;
+	_currentCharacter->x2 = xpos;
+	_currentCharacter->y1 = ypos;
+	_currentCharacter->y2 = ypos;
+	
+	initSceneObjectList(brandonAlive);
+	
+	if (unk1 && brandonAlive == 0) {
+		moveCharacterToPos(0, facing, xpos2, ypos2);
+	}
+	
+	_scriptClick->variables[4] = _itemInHand;
+	_scriptClick->variables[7] = brandonAlive;
+	_scriptInterpreter->startScript(_scriptClick, 3);
+	while (_scriptInterpreter->validScript(_scriptClick)) {
+		_scriptInterpreter->runScript(_scriptClick);
+	}
+}
+
+void KyraEngine::initSceneObjectList(int brandonAlive) {
+	debug(9, "KyraEngine::initSceneObjectList(%d)", brandonAlive);
+	for (int i = 0; i < 28; ++i) {
+		_animator->actors()[i].active = 0;
+	}
+	
+	int startAnimFrame = 0;
+	
+	AnimObject *curAnimState = _animator->actors();
+	curAnimState->active = 1;
+	curAnimState->drawY = _currentCharacter->y1;
+	curAnimState->sceneAnimPtr = _shapes[4+_currentCharacter->currentAnimFrame];
+	curAnimState->animFrameNumber = _currentCharacter->currentAnimFrame;
+	startAnimFrame = _currentCharacter->currentAnimFrame-7;
+	int xOffset = _defaultShapeTable[startAnimFrame].xOffset;
+	int yOffset = _defaultShapeTable[startAnimFrame].yOffset;
+	if (_scaleMode) {
+		curAnimState->x1 = _currentCharacter->x1;
+		curAnimState->y1 = _currentCharacter->y1;
+		
+		_brandonScaleX = _scaleTable[_currentCharacter->y1];
+		_brandonScaleY = _scaleTable[_currentCharacter->y1];
+		
+		curAnimState->x1 += (_brandonScaleX * xOffset) >> 8;
+		curAnimState->y1 += (_brandonScaleY * yOffset) >> 8;
+	} else {
+		curAnimState->x1 = _currentCharacter->x1 + xOffset;
+		curAnimState->y1 = _currentCharacter->y1 + yOffset;
+	}
+	curAnimState->x2 = curAnimState->x1;
+	curAnimState->y2 = curAnimState->y1;
+	curAnimState->refreshFlag = 1;
+	curAnimState->bkgdChangeFlag = 1;
+	_animator->clearQueue();
+	_animator->addObjectToQueue(curAnimState);
+	
+	int listAdded = 0;
+	int addedObjects = 1;
+	
+	for (int i = 1; i < 5; ++i) {
+		Character *ch = &_characterList[i];
+		curAnimState = &_animator->actors()[addedObjects];
+		if (ch->sceneId != _currentCharacter->sceneId) {
+			curAnimState->active = 0;
+			curAnimState->refreshFlag = 0;
+			curAnimState->bkgdChangeFlag = 0;
+			++addedObjects;
+			continue;
+		}
+		
+		curAnimState->drawY = ch->y1;
+		curAnimState->sceneAnimPtr = _shapes[4+ch->currentAnimFrame];
+		curAnimState->animFrameNumber = ch->currentAnimFrame;
+		startAnimFrame = ch->currentAnimFrame-7;
+		xOffset = _defaultShapeTable[startAnimFrame].xOffset;
+		yOffset = _defaultShapeTable[startAnimFrame].yOffset;
+		if (_scaleMode) {
+			curAnimState->x1 = ch->x1;
+			curAnimState->y1 = ch->y1;
+		
+			_brandonScaleX = _scaleTable[ch->y1];
+			_brandonScaleY = _scaleTable[ch->y1];
+		
+			curAnimState->x1 += (_brandonScaleX * xOffset) >> 8;
+			curAnimState->y1 += (_brandonScaleY * yOffset) >> 8;
+		} else {
+			curAnimState->x1 = ch->x1 + xOffset;
+			curAnimState->y1 = ch->y1 + yOffset;
+		}
+		curAnimState->x2 = curAnimState->x1;
+		curAnimState->y2 = curAnimState->y1;
+		curAnimState->active = 1;
+		curAnimState->refreshFlag = 1;
+		curAnimState->bkgdChangeFlag = 1;
+		
+		if (ch->facing >= 1 && ch->facing <= 3) {
+			curAnimState->flags |= 1;
+		} else if (ch->facing >= 5 && ch->facing <= 7) {
+			curAnimState->flags &= 0xFFFFFFFE;
+		}
+		
+		_animator->addObjectToQueue(curAnimState);
+		
+		++addedObjects;
+		++listAdded;
+		if (listAdded < 2)
+			i = 5;
+	}
+	
+	for (int i = 0; i < 11; ++i) {
+		curAnimState = &_animator->sprites()[i];
+
+		if (_sprites->_anims[i].play) {
+			curAnimState->active = 1;
+			curAnimState->refreshFlag = 1;
+			curAnimState->bkgdChangeFlag = 1;
+		}
+		else {
+			curAnimState->active = 0;
+			curAnimState->refreshFlag = 0;
+			curAnimState->bkgdChangeFlag = 0;
+		}
+		curAnimState->height = _sprites->_anims[i].height;
+		curAnimState->height2 = _sprites->_anims[i].height2;
+		curAnimState->width = _sprites->_anims[i].width + 1;
+		curAnimState->width2 = _sprites->_anims[i].width2;
+		curAnimState->drawY = _sprites->_anims[i].drawY;
+		curAnimState->x1 = curAnimState->x2 = _sprites->_anims[i].x;
+		curAnimState->y1 = curAnimState->y2 = _sprites->_anims[i].y;
+		curAnimState->background = _sprites->_anims[i].background;
+		curAnimState->sceneAnimPtr = _sprites->_sceneShapes[_sprites->_anims[i].sprite];
+		
+		if(_sprites->_anims[i].unk2)
+			curAnimState->flags = 0x800;
+		else
+			curAnimState->flags = 0;
+
+		if (_sprites->_anims[i].flipX)
+			curAnimState->flags |= 0x1;
+		
+		_animator->addObjectToQueue(curAnimState);
+	}
+	
+	for (int i = 0; i < 12; ++i) {
+		curAnimState = &_animator->items()[i];
+		Room *curRoom = &_roomTable[_currentCharacter->sceneId];
+		byte curItem = curRoom->itemsTable[i];
+		if (curItem != 0xFF) {
+			curAnimState->drawY = curRoom->itemsYPos[i];
+			curAnimState->sceneAnimPtr = _shapes[220+curItem];
+			curAnimState->animFrameNumber = (int16)0xFFFF;
+			curAnimState->y1 = curRoom->itemsYPos[i];
+			curAnimState->x1 = curRoom->itemsXPos[i];
+			
+			curAnimState->x1 -= (fetchAnimWidth(curAnimState->sceneAnimPtr, _scaleTable[curAnimState->drawY])) >> 1;
+			curAnimState->y1 -= fetchAnimHeight(curAnimState->sceneAnimPtr, _scaleTable[curAnimState->drawY]);
+			
+			curAnimState->x2 = curAnimState->x1;
+			curAnimState->y2 = curAnimState->y1;
+			
+			curAnimState->active = 1;
+			curAnimState->refreshFlag = 1;
+			curAnimState->bkgdChangeFlag = 1;
+			
+			_animator->addObjectToQueue(curAnimState);
+		} else {
+			curAnimState->active = 0;
+			curAnimState->refreshFlag = 0;
+			curAnimState->bkgdChangeFlag = 0;
+		}
+	}
+	
+	_animator->preserveAnyChangedBackgrounds();
+	curAnimState = _animator->actors();
+	curAnimState->bkgdChangeFlag = 1;
+	curAnimState->refreshFlag = 1;
+	for (int i = 1; i < 28; ++i) {
+		curAnimState = &_animator->objects()[i];
+		if (curAnimState->active) {
+			curAnimState->bkgdChangeFlag = 1;
+			curAnimState->refreshFlag = 1;
+		}
+	}
+	_animator->restoreAllObjectBackgrounds();
+	_animator->preserveAnyChangedBackgrounds();
+	_animator->prepDrawAllObjects();
+	initSceneScreen(brandonAlive);
+	_animator->copyChangedObjectsForward(0);
+}
+
+void KyraEngine::initSceneScreen(int brandonAlive) {
+	// XXX (Pointless?) Palette stuff
+	if (_unkScreenVar2 == 1) {
+		_screen->shuffleScreen(8, 8, 304, 128, 2, 0, _unkScreenVar3, false);
+	} else {
+		_screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0);
+	}
+	_screen->updateScreen();
+	// XXX More (pointless?) palette stuff
+
+	if (!_scriptInterpreter->startScript(_scriptClick, 2))
+		error("Could not start script function 2 of scene script");
+
+	_scriptClick->variables[7] = brandonAlive;
+
+	while (_scriptInterpreter->validScript(_scriptClick))
+		_scriptInterpreter->runScript(_scriptClick);
+
+	setTextFadeTimerCountdown(-1);
+	if (_currentCharacter->sceneId == 210) {
+		if (_itemInHand != -1)
+			magicOutMouseItem(2, -1);
+		
+		_screen->hideMouse();
+		for (int i = 0; i < 10; ++i) {
+			if (_currentCharacter->inventoryItems[i] != 0xFF)
+				magicOutMouseItem(2, i);
+		}
+		_screen->showMouse();
+	}
+}
+
+int KyraEngine::handleSceneChange(int xpos, int ypos, int unk1, int frameReset) {
+	debug(9, "KyraEngine::handleSceneChange(%d, %d, %d, %d)", xpos, ypos, unk1, frameReset);
+	if (queryGameFlag(0xEF)) {
+		unk1 = 0;
+	}
+	int sceneId = _currentCharacter->sceneId;
+	_pathfinderFlag = 0;
+	if (xpos < 12) {
+		if (_roomTable[sceneId].westExit != 0xFFFF) {
+			xpos = 12;
+			ypos = _sceneExits.westYPos;
+			_pathfinderFlag = 7;
+		}
+	} else if(xpos >= 308) {
+		if (_roomTable[sceneId].eastExit != 0xFFFF) {
+			xpos = 307;
+			ypos = _sceneExits.eastYPos;
+			_pathfinderFlag = 13;
+		}
+	}
+	
+	if (ypos <= (_northExitHeight&0xFF)+2) {
+		if (_roomTable[sceneId].northExit != 0xFFFF) {
+			xpos = _sceneExits.northXPos;
+			ypos = _northExitHeight & 0xFF;
+			_pathfinderFlag = 14;
+		}
+	} else if (ypos >= 136) {
+		if (_roomTable[sceneId].southExit != 0xFFFF) {
+			xpos = _sceneExits.southXPos;
+			ypos = 136;
+			_pathfinderFlag = 11;
+		}
+	}
+	
+	int temp = xpos - _currentCharacter->x1;
+	if (ABS(temp) < 4) {
+		temp = ypos - _currentCharacter->y1;
+		if (ABS(temp) < 2) {
+			return 0;
+		}
+	}
+	
+	int x = (int16)(_currentCharacter->x1 & 0xFFFC);
+	int y = (int16)(_currentCharacter->y1 & 0xFFFE);
+	xpos = (int16)(xpos & 0xFFFC);
+	ypos = (int16)(ypos & 0xFFFE);
+	int ret = findWay(x, y, xpos, ypos, _movFacingTable, 150);
+	_pathfinderFlag = 0;
+	if (ret >= _lastFindWayRet) {
+		_lastFindWayRet = ret;
+	}
+	if (ret == 0x7D00 || ret == 0) {
+		return 0;
+	}
+	return processSceneChange(_movFacingTable, unk1, frameReset);
+}
+
+int KyraEngine::processSceneChange(int *table, int unk1, int frameReset) {
+	debug(9, "KyraEngine::processSceneChange(0x%X, %d, %d)", table, unk1, frameReset);
+	if (queryGameFlag(0xEF)) {
+		unk1 = 0;
+	}
+	int *tableStart = table;
+	_sceneChangeState = 0;
+	_loopFlag2 = 0;
+	bool running = true;
+	int returnValue = 0;
+	uint32 nextFrame = 0;
+	_abortWalkFlag = false;
+	_mousePressFlag = false;
+
+	while (running) {
+		if (_abortWalkFlag) {
+			*table = 8;
+			_currentCharacter->currentAnimFrame = 7;
+			animRefreshNPC(0);
+			_animator->updateAllObjectShapes();
+			processInput(_mouseX, _mouseY);
+			return 0;
+		}
+		bool forceContinue = false;
+		switch (*table) {
+			case 0: case 1: case 2:
+			case 3: case 4: case 5:
+			case 6: case 7:
+				_currentCharacter->facing = getOppositeFacingDirection(*table);
+				break;
+			
+			case 8:
+				forceContinue = true;
+				running = false;
+				break;
+			
+			default:
+				++table;
+				forceContinue = true;
+				break;
+		}
+		
+		returnValue = changeScene(_currentCharacter->facing);
+		if (returnValue) {
+			running = false;
+			_abortWalkFlag = false;
+		}
+		
+		if (unk1) {
+			if (_mousePressFlag) {
+				running = false;
+				_sceneChangeState = 1;
+			}
+		}
+		
+		if (forceContinue || !running) {
+			continue;
+		}
+		
+		int temp = 0;
+		if (table == tableStart || table[1] == 8) {
+			temp = setCharacterPosition(0, 0);
+		} else {
+			temp = setCharacterPosition(0, table);
+		}
+		if (temp) {
+			++table;
+		}
+		
+		nextFrame = getTimerDelay(5) * _tickLength + _system->getMillis();
+		while (_system->getMillis() < nextFrame) {
+			_sprites->updateSceneAnims();
+			updateMousePointer();
+			updateGameTimers();
+			_animator->updateAllObjectShapes();
+			updateTextFade();
+			if (_currentCharacter->sceneId == 210) {
+				_animator->updateKyragemFading();
+				if (seq_playEnd() || _beadStateVar == 4 || _beadStateVar == 5) {
+					*table = 8;
+					running = false;
+					break;
+				}
+			}
+			if ((nextFrame - _system->getMillis()) >= 10)
+				delay(10);
+		}
+	}
+	
+	if (frameReset && !(_brandonStatusBit & 2)) {
+		_currentCharacter->currentAnimFrame = 7;
+	}
+	animRefreshNPC(0);
+	_animator->updateAllObjectShapes();
+	return returnValue;
+}
+
+int KyraEngine::changeScene(int facing) {
+	debug(9, "KyraEngine::changeScene(%d)", facing);
+	if (queryGameFlag(0xEF)) {
+		if (_currentCharacter->sceneId == 5) {
+			return 0;
+		}
+	}
+	
+	int xpos = _charXPosTable[facing] + _currentCharacter->x1;
+	int ypos = _charYPosTable[facing] + _currentCharacter->y1;
+	
+	if (xpos >= 12 && xpos <= 308) {
+		if (!lineIsPassable(xpos, ypos))
+			return false;
+	}
+	
+	if (_exitListPtr) {
+		int16 *ptr = _exitListPtr;
+		// this loop should be only entered on time, seems to be some hack in the original
+		while (true) {
+			if (*ptr == -1)
+				break;
+			
+			if (*ptr > _currentCharacter->x1 || _currentCharacter->y1 < ptr[1] || _currentCharacter->x1 > ptr[2] || _currentCharacter->y1 > ptr[3]) {
+				ptr += 10;
+				break;
+			}
+			_brandonPosX = ptr[6];
+			_brandonPosY = ptr[7];
+			uint16 sceneId = ptr[5];
+			facing = ptr[4];
+			int unk1 = ptr[8];
+			int unk2 = ptr[9];
+			if (sceneId == 0xFFFF) {
+				switch (facing) {
+					case 0:
+						sceneId = _roomTable[_currentCharacter->sceneId].northExit;
+						break;
+						
+					case 2:
+						sceneId = _roomTable[_currentCharacter->sceneId].eastExit;
+						break;
+					
+					case 4:
+						sceneId = _roomTable[_currentCharacter->sceneId].southExit;
+						break;
+						
+					case 6:
+						sceneId = _roomTable[_currentCharacter->sceneId].westExit;
+						break;
+						
+					default:
+						break;
+				}
+			}
+			
+			_currentCharacter->facing = facing;
+			animRefreshNPC(0);
+			_animator->updateAllObjectShapes();
+			enterNewScene(sceneId, facing, unk1, unk2, 0);
+			resetGameFlag(0xEE);
+			return 1;
+		}
+	}
+	
+	int returnValue = 0;
+	facing = 0;
+	
+	if ((_northExitHeight & 0xFF) + 2 >= ypos || (_northExitHeight & 0xFF) + 2 >= _currentCharacter->y1) {
+		facing = 0;
+		returnValue = 1;
+	}
+	
+	if (xpos >= 308 || (_currentCharacter->x1 + 4) >= 308) {
+		facing = 2;
+		returnValue = 1;
+	}
+	
+	if (((_northExitHeight >> 8) & 0xFF) - 2 < ypos || ((_northExitHeight >> 8) & 0xFF) - 2 < _currentCharacter->y1) {
+		facing = 4;
+		returnValue = 1;
+	}
+	
+	if (xpos <= 12 || _currentCharacter->y1 <= 12) {
+		facing = 6;
+		returnValue = 1;
+	}
+	
+	if (!returnValue)
+		return 0;
+	
+	uint16 sceneId = 0xFFFF;
+	switch (facing) {
+		case 0:
+			sceneId = _roomTable[_currentCharacter->sceneId].northExit;
+			break;
+		
+		case 2:
+			sceneId = _roomTable[_currentCharacter->sceneId].eastExit;
+			break;
+		
+		case 4:
+			sceneId = _roomTable[_currentCharacter->sceneId].southExit;
+			break;
+		
+		default:
+			sceneId = _roomTable[_currentCharacter->sceneId].westExit;
+			break;
+	}
+	
+	if (sceneId == 0xFFFF)
+		return 0;
+
+	enterNewScene(sceneId, facing, 1, 1, 0);
+	return returnValue;
+}
+
+void KyraEngine::setCharactersInDefaultScene() {
+	static const uint32 defaultSceneTable[][4] = {
+		{ 0xFFFF, 0x0004, 0x0003, 0xFFFF },
+		{ 0xFFFF, 0x0022, 0xFFFF, 0x0000 },
+		{ 0xFFFF, 0x001D, 0x0021, 0xFFFF },
+		{ 0xFFFF, 0x0000, 0x0000, 0xFFFF }
+	};
+	
+	for (int i = 1; i < 5; ++i) {
+		Character *cur = &_characterList[i];
+		//cur->field_20 = 0;
+		const uint32 *curTable = defaultSceneTable[i-1];
+		cur->sceneId = curTable[0];
+		if (cur->sceneId == _currentCharacter->sceneId) {
+			//++cur->field_20;
+			cur->sceneId = curTable[1/*cur->field_20*/];
+		}
+		//cur->field_23 = curTable[cur->field_20+1];
+	}
+}
+
+void KyraEngine::setCharactersPositions(int character) {
+	static uint16 initXPosTable[] = {
+		0x3200, 0x0024, 0x2230, 0x2F00, 0x0020, 0x002B,
+		0x00CA, 0x00F0, 0x0082, 0x00A2, 0x0042
+	};
+	static uint8 initYPosTable[] = {
+		0x00, 0xA2, 0x00, 0x42, 0x00,
+		0x67, 0x67, 0x60, 0x5A, 0x71,
+		0x76
+	};
+	assert(character < ARRAYSIZE(initXPosTable));
+	Character *edit = &_characterList[character];
+	edit->x1 = edit->x2 = initXPosTable[character];
+	edit->y1 = edit->y2 = initYPosTable[character];
+}
+
+#pragma mark -
+#pragma mark - Pathfinder
+#pragma mark -
+
+int KyraEngine::findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize) {
+	debug(9, "KyraEngine::findWay(%d, %d, %d, %d, 0x%X, %d)", x, y, toX, toY, 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;
+	return getMoveTableSize(moveTable);
+}
+
+int KyraEngine::findSubPath(int x, int y, int toX, int toY, int *moveTable, int start, int end) {
+	debug(9, "KyraEngine::findSubPath(%d, %d, %d, %d, 0x%X, %d, %d)", x, y, toX, toY, 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) {
+	debug(9, "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];
+}
+
+void KyraEngine::changePosTowardsFacing(int &x, int &y, int facing) {
+	debug(9, "KyraEngine::changePosTowardsFacing(%d, %d, %d)", x, y, facing);
+	x += _addXPosTable[facing];
+	y += _addYPosTable[facing];
+}
+
+bool KyraEngine::lineIsPassable(int x, int y) {
+	debug(9, "KyraEngine::lineIsPassable(%d, %d)", x, y);
+	if (queryGameFlag(0xEF)) {
+		if (_currentCharacter->sceneId == 5)
+			return true;
+	}
+	
+	if (_pathfinderFlag & 2) {
+		if (x >= 312)
+			return false;
+	}
+	
+	if (_pathfinderFlag & 4) {
+		if (y >= 136)
+			return false;
+	}
+	
+	if (_pathfinderFlag & 8) {
+		if (x < 8)
+			return false;
+	}
+	
+	if (_pathfinderFlag2) {
+		if (x <= 8 || x >= 312)
+			return true;
+		if (y < (_northExitHeight & 0xFF) || y > 135)
+			return true;
+	}
+	
+	if (y > 137) {
+		return false;
+	}
+	
+	int ypos = 8;
+	if (_scaleMode) {
+		ypos = (_scaleTable[y] >> 5) + 1;
+		if (8 < ypos)
+			ypos = 8;
+	}
+	
+	x -= (ypos >> 1);
+	if (y < 0)
+		y = 0;
+	
+	int xpos = x;
+	int xtemp = xpos + ypos - 1;
+	if (x < 0)
+		xpos = 0;
+		
+	if (xtemp > 319)
+		xtemp = 319;
+
+	for (; xpos < xtemp; ++xpos) {
+		if (!_screen->getShapeFlag1(xpos, y))
+			return false;
+	}
+	return true;
+}
+
+int KyraEngine::getMoveTableSize(int *moveTable) {
+	debug(9, "KyraEngine::getMoveTableSize(0x%X)", 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

Modified: scummvm/trunk/kyra/screen.cpp
===================================================================
--- scummvm/trunk/kyra/screen.cpp	2006-02-09 04:58:21 UTC (rev 20436)
+++ scummvm/trunk/kyra/screen.cpp	2006-02-09 07:37:19 UTC (rev 20437)
@@ -71,6 +71,11 @@
 	memset(_bitBlitRects, 0, sizeof(Rect)*BITBLIT_RECTS);
 	_bitBlitNum = 0;
 	memset(_saveLoadPage, 0, sizeof(_saveLoadPage));
+
+	_unkPtr1 = (uint8*)malloc(getRectSize(1, 144));
+	memset(_unkPtr1, 0, getRectSize(1, 144));
+	_unkPtr2 = (uint8*)malloc(getRectSize(1, 144));
+	memset(_unkPtr2, 0, getRectSize(1, 144));
 }
 
 Screen::~Screen() {
@@ -94,6 +99,9 @@
 		delete [] _saveLoadPage[i];
 		_saveLoadPage[i] = 0;
 	}
+
+	free(_unkPtr1);
+	free(_unkPtr2);
 }
 
 void Screen::updateScreen() {
@@ -1916,4 +1924,150 @@
 	_saveLoadPage[page/2] = 0;
 }
 
+void Screen::blockInRegion(int x, int y, int width, int height) {
+	debug(9, "Screen::blockInRegion(%d, %d, %d, %d)", x, y, width, height);
+	assert(_shapePages[0]);
+	byte *toPtr = _shapePages[0] + (y * 320 + x);
+	for (int i = 0; i < height; ++i) {
+		byte *backUpTo = toPtr;
+		for (int i2 = 0; i2 < width; ++i2) {
+			*toPtr++ &= 0x7F;
+		}
+		toPtr = (backUpTo + 320);
+	}
+}
+
+void Screen::blockOutRegion(int x, int y, int width, int height) {
+	debug(9, "Screen::blockOutRegion(%d, %d, %d, %d)", x, y, width, height);
+	assert(_shapePages[0]);
+	byte *toPtr = _shapePages[0] + (y * 320 + x);
+	for (int i = 0; i < height; ++i) {
+		byte *backUpTo = toPtr;
+		for (int i2 = 0; i2 < width; ++i2) {
+			*toPtr++ |= 0x80;
+		}
+		toPtr = (backUpTo + 320);
+	}
+}
+
+void Screen::rectClip(int &x, int &y, int w, int h) {
+	if (x < 0) {
+		x = 0;
+	} else if (x + w >= 320) {
+		x = 320 - w;
+	}
+	if (y < 0) {
+		y = 0;
+	} else if (y + h >= 200) {
+		y = 200 - h;
+	}
+}
+
+void Screen::backUpRect0(int xpos, int ypos) {
+	debug(9, "Screen::backUpRect0(%d, %d)", xpos, ypos);
+	rectClip(xpos, ypos, 3<<3, 24);
+	copyRegionToBuffer(_curPage, xpos, ypos, 3<<3, 24, _vm->shapes()[0]);
+}
+
+void Screen::restoreRect0(int xpos, int ypos) {
+	debug(9, "Screen::restoreRect0(%d, %d)", xpos, ypos);
+	rectClip(xpos, ypos, 3<<3, 24);
+	copyBlockToPage(_curPage, xpos, ypos, 3<<3, 24, _vm->shapes()[0]);
+}
+
+void Screen::backUpRect1(int xpos, int ypos) {
+	debug(9, "Screen::backUpRect1(%d, %d)", xpos, ypos);
+	rectClip(xpos, ypos, 4<<3, 32);
+	copyRegionToBuffer(_curPage, xpos, ypos, 4<<3, 32, _vm->shapes()[1]);
+}
+
+void Screen::restoreRect1(int xpos, int ypos) {
+	debug(9, "Screen::restoreRect1(%d, %d)", xpos, ypos);
+	rectClip(xpos, ypos, 4<<3, 32);
+	copyBlockToPage(_curPage, xpos, ypos, 4<<3, 32, _vm->shapes()[1]);
+}
+
+int Screen::getDrawLayer(int x, int y) {
+	debug(9, "Screen::getDrawLayer(%d, %d)", x, y);
+	int xpos = x - 8;
+	int ypos = y - 1;
+	int layer = 1;
+	for (int curX = xpos; curX < xpos + 16; ++curX) {
+		int tempLayer = getShapeFlag2(curX, ypos);
+		if (layer < tempLayer) {
+			layer = tempLayer;
+		}
+		if (layer >= 7) {
+			return 7;
+		}
+	}
+	return layer;
+}
+
+int Screen::getDrawLayer2(int x, int y, int height) {
+	debug(9, "Screen::getDrawLayer2(%d, %d, %d)", x, y, height);
+	int xpos = x - 8;
+	int ypos = y - 1;
+	int layer = 1;
+	
+	for (int useX = xpos; useX < xpos + 16; ++useX) {
+		for (int useY = ypos - height; useY < ypos; ++useY) {
+			int tempLayer = getShapeFlag2(useX, useY);
+			if (tempLayer > layer) {
+				layer = tempLayer;
+			}
+			
+			if (tempLayer >= 7) {
+				return 7;
+			}
+		}
+	}	
+	return layer;
+}
+
+void Screen::copyBackgroundBlock(int x, int page, int flag) {
+	debug(9, "Screen::copyBackgroundBlock(%d, %d, %d)", x, page, flag);
+	
+	if (x < 1)
+		return;
+	
+	int height = 128;
+	if (flag)
+		height += 8;	
+	if (!(x & 1))
+		++x;
+	if (x == 19)
+		x = 17;
+	uint8 *ptr1 = _unkPtr1;
+	uint8 *ptr2 = _unkPtr2;
+	int oldVideoPage = _curPage;
+	_curPage = page;
+	
+	int curX = x;
+	hideMouse();
+	copyRegionToBuffer(_curPage, 8, 8, 8, height, ptr2);
+	for (int i = 0; i < 19; ++i) {
+		int tempX = curX + 1;
+		copyRegionToBuffer(_curPage, tempX<<3, 8, 8, height, ptr1);
+		copyBlockToPage(_curPage, tempX<<3, 8, 8, height, ptr2);
+		int newXPos = curX + x;
+		if (newXPos > 37) {
+			newXPos = newXPos % 38;
+		}
+		tempX = newXPos + 1;
+		copyRegionToBuffer(_curPage, tempX<<3, 8, 8, height, ptr2);
+		copyBlockToPage(_curPage, tempX<<3, 8, 8, height, ptr1);
+		curX += x*2;
+		if (curX > 37) {
+			curX = curX % 38;
+		}
+	}
+	showMouse();
+	_curPage = oldVideoPage;
+}
+
+void Screen::copyBackgroundBlock2(int x) {
+	copyBackgroundBlock(x, 4, 1);
+}
+
 } // End of namespace Kyra

Modified: scummvm/trunk/kyra/screen.h
===================================================================
--- scummvm/trunk/kyra/screen.h	2006-02-09 04:58:21 UTC (rev 20436)
+++ scummvm/trunk/kyra/screen.h	2006-02-09 07:37:19 UTC (rev 20437)
@@ -149,6 +149,19 @@
 	void loadPageFromDisk(const char *file, int page);
 	void deletePageFromDisk(int page);
 
+	void blockInRegion(int x, int y, int width, int height);
+	void blockOutRegion(int x, int y, int width, int height);
+
+	void backUpRect0(int xpos, int ypos);
+	void restoreRect0(int xpos, int ypos);
+	void backUpRect1(int xpos, int ypos);
+	void restoreRect1(int xpos, int ypos);
+	void copyBackgroundBlock(int x, int page, int flag);
+	void copyBackgroundBlock2(int x);
+	void rectClip(int &x, int &y, int w, int h);
+	int getDrawLayer(int x, int y);
+	int getDrawLayer2(int x, int y, int height);
+
 	int _charWidth;
 	int _charOffset;
 	int _curPage;
@@ -181,6 +194,7 @@
 	
 	Rect *_bitBlitRects;
 	int _bitBlitNum;
+	uint8 *_unkPtr1, *_unkPtr2;
 
 	OSystem *_system;
 	KyraEngine *_vm;

Modified: scummvm/trunk/kyra/script_v1.cpp
===================================================================
--- scummvm/trunk/kyra/script_v1.cpp	2006-02-09 04:58:21 UTC (rev 20436)
+++ scummvm/trunk/kyra/script_v1.cpp	2006-02-09 07:37:19 UTC (rev 20437)
@@ -112,13 +112,13 @@
 
 int KyraEngine::cmd_blockInWalkableRegion(ScriptState *script) {
 	debug(3, "cmd_blockInWalkableRegion(0x%X) (%d, %d, %d, %d)", script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
-	blockInRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1);
+	_screen->blockInRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1);
 	return 0;
 }
 
 int KyraEngine::cmd_blockOutWalkableRegion(ScriptState *script) {
 	debug(3, "cmd_blockOutWalkableRegion(0x%X) (%d, %d, %d, %d)", script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
-	blockOutRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1);
+	_screen->blockOutRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1);
 	return 0;
 }
 
@@ -1113,8 +1113,8 @@
 
 int KyraEngine::cmd_bkgdScrollSceneAndMasksRight(ScriptState *script) {
 	debug(3, "cmd_bkgdScrollSceneAndMasksRight(0x%X) (%d)", script, stackPos(0));
-	copyBackgroundBlock(stackPos(0), 2, 0);
-	copyBackgroundBlock2(stackPos(0));
+	_screen->copyBackgroundBlock(stackPos(0), 2, 0);
+	_screen->copyBackgroundBlock2(stackPos(0));
 	// update the whole screen
 	_screen->copyRegion(7, 7, 7, 7, 305, 129, 3, 0);
 	_screen->updateScreen();

Modified: scummvm/trunk/kyra/seqplayer.cpp
===================================================================
--- scummvm/trunk/kyra/seqplayer.cpp	2006-02-09 04:58:21 UTC (rev 20436)
+++ scummvm/trunk/kyra/seqplayer.cpp	2006-02-09 07:37:19 UTC (rev 20437)
@@ -408,7 +408,7 @@
 		} else if (msg == 1) {
 			_sound->beginFadeOut();
 		} else {
-			_vm->snd_playTrack(msg);
+			_sound->playTrack(msg);
 		}
 //	}
 }
@@ -635,4 +635,5 @@
 	return seqSkippedFlag;
 }
 
+
 } // End of namespace Kyra

Added: scummvm/trunk/kyra/sequences.cpp
===================================================================
--- scummvm/trunk/kyra/sequences.cpp	                        (rev 0)
+++ scummvm/trunk/kyra/sequences.cpp	2006-02-09 07:37:19 UTC (rev 20437)
@@ -0,0 +1,968 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "kyra/kyra.h"
+#include "kyra/seqplayer.h"
+#include "kyra/screen.h"
+#include "kyra/resource.h"
+#include "kyra/sound.h"
+#include "kyra/sprites.h"
+#include "kyra/wsamovie.h"
+#include "kyra/animator.h"
+#include "kyra/text.h"
+
+#include "common/system.h"
+#include "common/savefile.h"
+
+namespace Kyra {
+
+void KyraEngine::seq_demo() {
+	debug(9, "KyraEngine::seq_demo()");
+
+	snd_playTheme(MUSIC_INTRO, 2);
+
+	loadBitmap("START.CPS", 7, 7, _screen->_currentPalette);
+	_screen->copyRegion(0, 0, 0, 0, 320, 200, 6, 0);
+	_system->copyRectToScreen(_screen->getPagePtr(0), 320, 0, 0, 320, 200);
+	_screen->fadeFromBlack();
+	waitTicks(60);
+	_screen->fadeToBlack();
+
+	_screen->clearPage(0);
+	loadBitmap("TOP.CPS", 7, 7, NULL);
+	loadBitmap("BOTTOM.CPS", 5, 5, _screen->_currentPalette);
+	_screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 0);
+	_screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 0);
+	_system->copyRectToScreen(_screen->getPagePtr(0), 320, 0, 0, 320, 200);
+	_screen->fadeFromBlack();
+	
+	_seq->playSequence(_seq_WestwoodLogo, true);
+	waitTicks(60);
+
+	_seq->playSequence(_seq_KyrandiaLogo, true);
+
+	_screen->fadeToBlack();
+	_screen->clearPage(2);
+	_screen->clearPage(0);
+
+	_seq->playSequence(_seq_Demo1, true);
+
+	_screen->clearPage(0);
+	_seq->playSequence(_seq_Demo2, true);
+
+	_screen->clearPage(0);
+	_seq->playSequence(_seq_Demo3, true);
+
+	_screen->clearPage(0);
+	_seq->playSequence(_seq_Demo4, true);
+
+	_screen->clearPage(0);
+	loadBitmap("FINAL.CPS", 7, 7, _screen->_currentPalette);
+	_screen->_curPage = 0;
+	_screen->copyRegion(0, 0, 0, 0, 320, 200, 6, 0);
+	_system->copyRectToScreen(_screen->getPagePtr(0), 320, 0, 0, 320, 200);
+	_screen->fadeFromBlack();
+	waitTicks(60);
+	_screen->fadeToBlack();
+	_sound->stopMusic();
+}
+
+void KyraEngine::seq_intro() {
+	debug(9, "KyraEngine::seq_intro()");
+	if (_features & GF_TALKIE) {
+		_res->loadPakFile("INTRO.VRM");
+	}
+	
+	static const IntroProc introProcTable[] = {
+		&KyraEngine::seq_introLogos,
+		&KyraEngine::seq_introStory,
+		&KyraEngine::seq_introMalcolmTree,
+		&KyraEngine::seq_introKallakWriting,
+		&KyraEngine::seq_introKallakMalcolm
+	};
+
+	Common::InSaveFile *in;
+	if ((in = _saveFileMan->openForLoading(getSavegameFilename(0)))) {
+		delete in;
+		_skipIntroFlag = true;
+	} else
+		_skipIntroFlag = false;
+
+	_seq->setCopyViewOffs(true);
+	_screen->setFont(Screen::FID_8_FNT);
+	snd_playTheme(MUSIC_INTRO, 2);
+ 	snd_setSoundEffectFile(MUSIC_INTRO);
+	_text->setTalkCoords(144);
+	for (int i = 0; i < ARRAYSIZE(introProcTable) && !seq_skipSequence(); ++i) {
+		(this->*introProcTable[i])();
+	}
+	_text->setTalkCoords(136);
+	waitTicks(30);
+	_seq->setCopyViewOffs(false);
+	_sound->stopMusic();
+	if (_features & GF_TALKIE) {
+		_res->unloadPakFile("INTRO.VRM");
+	}
+	res_unloadResources(RES_INTRO | RES_OUTRO);
+}
+
+void KyraEngine::seq_introLogos() {
+	debug(9, "KyraEngine::seq_introLogos()");
+	_screen->clearPage(0);
+	loadBitmap("TOP.CPS", 7, 7, NULL);
+	loadBitmap("BOTTOM.CPS", 5, 5, _screen->_currentPalette);
+	_screen->_curPage = 0;
+	_screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 0);
+	_screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 0);
+	_system->copyRectToScreen(_screen->getPagePtr(0), 320, 0, 0, 320, 200);
+	_screen->fadeFromBlack();
+	
+	if (_seq->playSequence(_seq_WestwoodLogo, _skipIntroFlag)) {
+		_screen->fadeToBlack();
+		_screen->clearPage(0);
+		return;
+	}
+	waitTicks(60);
+	if (_seq->playSequence(_seq_KyrandiaLogo, _skipIntroFlag)) {
+		_screen->fadeToBlack();
+		_screen->clearPage(0);
+		return;
+	}
+	_screen->fillRect(0, 179, 319, 199, 0);
+
+	int y1 = 8;
+	int h1 = 175;
+	int y2 = 176;
+	int h2 = 0;
+	_screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 2);
+	_screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 2);
+	do {
+		if (h1 > 0) {
+			_screen->copyRegion(0, y1, 0, 8, 320, h1, 2, 0);
+		}
+		++y1;
+		--h1;
+		if (h2 > 0) {
+			_screen->copyRegion(0, 64, 0, y2, 320, h2, 4, 0);
+		}
+		--y2;
+		++h2;
+		_screen->updateScreen();
+		waitTicks(1);
+	} while (y2 >= 64);
+
+	_seq->playSequence(_seq_Forest, true);
+}
+
+void KyraEngine::seq_introStory() {
+	debug(9, "KyraEngine::seq_introStory()");
+	_screen->clearPage(3);
+	_screen->clearPage(0);
+	if ((_features & GF_ENGLISH) && (_features & GF_TALKIE)) {
+		loadBitmap("TEXT_ENG.CPS", 3, 3, 0);
+	} else if (_features & GF_GERMAN) {
+		loadBitmap("TEXT_GER.CPS", 3, 3, 0);
+	} else if (_features & GF_FRENCH) {
+		loadBitmap("TEXT_FRE.CPS", 3, 3, 0);
+	} else if (_features & GF_SPANISH) {
+		loadBitmap("TEXT_SPA.CPS", 3, 3, 0);
+	} else if ((_features & GF_ENGLISH) && (_features & GF_FLOPPY)) {
+		loadBitmap("TEXT.CPS", 3, 3, 0);
+	} else {
+		warning("no story graphics file found");
+	}
+	_screen->copyRegion(0, 0, 0, 0, 320, 200, 3, 0);
+	_screen->updateScreen();
+	waitTicks(360);
+}
+
+void KyraEngine::seq_introMalcolmTree() {
+	debug(9, "KyraEngine::seq_introMalcolmTree()");
+	_screen->_curPage = 0;
+	_screen->clearPage(3);
+	_seq->playSequence(_seq_MalcolmTree, true);
+}
+
+void KyraEngine::seq_introKallakWriting() {
+	debug(9, "KyraEngine::seq_introKallakWriting()");
+	_seq->makeHandShapes();
+	_screen->setAnimBlockPtr(5060);
+	_screen->_charWidth = -2;
+	_screen->clearPage(3);
+	_seq->playSequence(_seq_KallakWriting, true);
+}
+
+void KyraEngine::seq_introKallakMalcolm() {
+	debug(9, "KyraEngine::seq_introKallakMalcolm()");
+	_screen->clearPage(3);
+	_seq->playSequence(_seq_KallakMalcolm, true);
+}
+
+void KyraEngine::seq_createAmuletJewel(int jewel, int page, int noSound, int drawOnly) {
+	debug(9, "seq_createAmuletJewel(%d, %d, %d, %d)", jewel, page, noSound, drawOnly);
+	static const uint16 specialJewelTable[] = {
+		0x167, 0x162, 0x15D, 0x158, 0x153, 0xFFFF
+	};
+	static const uint16 specialJewelTable1[] = {
+		0x14F, 0x154, 0x159, 0x15E, 0x163, 0xFFFF
+	};
+	static const uint16 specialJewelTable2[] = {
+		0x150, 0x155, 0x15A, 0x15F, 0x164, 0xFFFF
+	};
+	static const uint16 specialJewelTable3[] = {
+		0x151, 0x156, 0x15B, 0x160, 0x165, 0xFFFF
+	};
+	static const uint16 specialJewelTable4[] = {
+		0x152, 0x157, 0x15C, 0x161, 0x166, 0xFFFF
+	};
+	if (!noSound)
+		snd_playSoundEffect(0x5F);
+	_screen->hideMouse();
+	if (!drawOnly) {
+		for (int i = 0; specialJewelTable[i] != 0xFFFF; ++i) {
+			_screen->drawShape(page, _shapes[4+specialJewelTable[i]], _amuletX2[jewel], _amuletY2[jewel], 0, 0);
+			_screen->updateScreen();
+			delayWithTicks(3);
+		}
+		
+		const uint16 *opcodes = 0;
+		switch (jewel - 1) {
+			case 0:
+				opcodes = specialJewelTable1;
+				break;
+				
+			case 1:
+				opcodes = specialJewelTable2;
+				break;
+				
+			case 2:
+				opcodes = specialJewelTable3;
+				break;
+				
+			case 3:
+				opcodes = specialJewelTable4;
+				break;
+		}
+		
+		if (opcodes) {
+			for (int i = 0; opcodes[i] != 0xFFFF; ++i) {
+				_screen->drawShape(page, _shapes[4+opcodes[i]], _amuletX2[jewel], _amuletY2[jewel], 0, 0);
+				_screen->updateScreen();
+				delayWithTicks(3);
+			}
+		}
+	}
+	_screen->drawShape(page, _shapes[327+jewel], _amuletX2[jewel], _amuletY2[jewel], 0, 0);
+	_screen->updateScreen();
+	_screen->showMouse();
+	setGameFlag(0x55+jewel);
+}
+
+void KyraEngine::seq_brandonHealing() {
+	debug(9, "seq_brandonHealing()");
+	if (!(_deathHandler & 8))
+		return;
+	if (_currentCharacter->sceneId == 210) {
+		if (_beadStateVar == 4 || _beadStateVar == 6)
+			return;
+	}
+	_screen->hideMouse();
+	checkAmuletAnimFlags();
+	assert(_healingShapeTable);
+	setupShapes123(_healingShapeTable, 22, 0);
+	setBrandonAnimSeqSize(3, 48);
+	snd_playSoundEffect(0x53);
+	for (int i = 123; i <= 144; ++i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(8);
+	}
+	for (int i = 125; i >= 123; --i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(8);
+	}
+	resetBrandonAnimSeqSize();
+	_currentCharacter->currentAnimFrame = 7;
+	animRefreshNPC(0);
+	freeShapes123();
+	_screen->showMouse();
+}
+
+void KyraEngine::seq_brandonHealing2() {
+	debug(9, "seq_brandonHealing2()");
+	_screen->hideMouse();
+	checkAmuletAnimFlags();
+	assert(_healingShape2Table);
+	setupShapes123(_healingShape2Table, 30, 0);
+	resetBrandonPoisonFlags();
+	setBrandonAnimSeqSize(3, 48);
+	snd_playSoundEffect(0x50);
+	for (int i = 123; i <= 152; ++i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(8);
+	}
+	resetBrandonAnimSeqSize();
+	_currentCharacter->currentAnimFrame = 7;
+	animRefreshNPC(0);
+	freeShapes123();
+	_screen->showMouse();
+	assert(_poisonGone);
+	if (_features & GF_TALKIE) {
+		snd_voiceWaitForFinish();
+		snd_playVoiceFile(2010);
+	}
+	characterSays(_poisonGone[0], 0, -2);
+	if (_features & GF_TALKIE) {
+		snd_voiceWaitForFinish();
+		snd_playVoiceFile(2011);
+	}
+	characterSays(_poisonGone[1], 0, -2);
+}
+
+void KyraEngine::seq_poisonDeathNow(int now) {
+	debug(9, "seq_poisonDeathNow(%d)", now);
+	if (!(_brandonStatusBit & 1))
+		return;
+	++_poisonDeathCounter;
+	if (now)
+		_poisonDeathCounter = 2;
+	if (_poisonDeathCounter >= 2) {
+		snd_playWanderScoreViaMap(1, 1);
+		assert(_thePoison);
+		if (_features & GF_TALKIE) {
+			snd_voiceWaitForFinish();
+			snd_playVoiceFile(7000);
+		}
+		characterSays(_thePoison[0], 0, -2);
+		if (_features & GF_TALKIE) {
+			snd_voiceWaitForFinish();
+			snd_playVoiceFile(7001);
+		}
+		characterSays(_thePoison[1], 0, -2);
+		seq_poisonDeathNowAnim();
+		_deathHandler = 3;
+	} else {
+		assert(_thePoison);
+		if (_features & GF_TALKIE) {
+			snd_voiceWaitForFinish();
+			snd_playVoiceFile(7002);
+		}
+		characterSays(_thePoison[2], 0, -2);
+		if (_features & GF_TALKIE) {
+			snd_voiceWaitForFinish();
+			snd_playVoiceFile(7004);
+		}
+		characterSays(_thePoison[3], 0, -2);
+	}
+}
+
+void KyraEngine::seq_poisonDeathNowAnim() {
+	debug(9, "seq_poisonDeathNowAnim()");
+	_screen->hideMouse();
+	checkAmuletAnimFlags();
+	assert(_posionDeathShapeTable);
+	setupShapes123(_posionDeathShapeTable, 20, 0);
+	setBrandonAnimSeqSize(8, 48);
+	
+	_currentCharacter->currentAnimFrame = 124;
+	animRefreshNPC(0);
+	delayWithTicks(30);
+	
+	_currentCharacter->currentAnimFrame = 123;
+	animRefreshNPC(0);
+	delayWithTicks(30);
+	
+	for (int i = 125; i <= 139; ++i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(8);
+	}
+	
+	delayWithTicks(60);
+	
+	for (int i = 140; i <= 142; ++i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(8);
+	}
+	
+	delayWithTicks(60);
+	
+	resetBrandonAnimSeqSize();
+	freeShapes123();
+	_animator->restoreAllObjectBackgrounds();
+	_currentCharacter->x1 = _currentCharacter->x2 = -1;
+	_currentCharacter->y1 = _currentCharacter->y2 = -1;
+	_animator->preserveAllBackgrounds();
+	_screen->showMouse();
+}
+
+void KyraEngine::seq_playFluteAnimation() {
+	debug(9, "seq_playFluteAnimation()");
+	_screen->hideMouse();
+	checkAmuletAnimFlags();
+	setupShapes123(_fluteAnimShapeTable, 36, 0);
+	setBrandonAnimSeqSize(3, 75);
+	for (int i = 123; i <= 130; ++i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(2);
+	}
+	
+	int delayTime = 0, soundType = 0;
+	if (queryGameFlag(0x85)) {
+		snd_playSoundEffect(0x63);
+		delayTime = 9;
+		soundType = 3;
+	} else if (!queryGameFlag(0x86)) {
+		snd_playSoundEffect(0x61);
+		delayTime = 2;
+		soundType = 1;
+		setGameFlag(0x86);
+	} else {
+		snd_playSoundEffect(0x62);
+		delayTime = 2;
+		soundType = 2;
+	}
+	
+	for (int i = 131; i <= 158; ++i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(delayTime);
+	}
+	
+	for (int i = 126; i >= 123; --i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(delayTime);
+	}
+	resetBrandonAnimSeqSize();
+	_currentCharacter->currentAnimFrame = 7;
+	animRefreshNPC(0);
+	freeShapes123();
+	_screen->showMouse();
+	
+	if (soundType == 1) {
+		assert(_fluteString);
+		if (_features & GF_TALKIE) {
+			snd_voiceWaitForFinish();
+			snd_playVoiceFile(1000);
+		}
+		characterSays(_fluteString[0], 0, -2);
+	} else if (soundType == 2) {
+		assert(_fluteString);
+		if (_features & GF_TALKIE) {
+			snd_voiceWaitForFinish();
+			snd_playVoiceFile(1001);
+		}
+		characterSays(_fluteString[1], 0, -2);
+	}
+}
+
+void KyraEngine::seq_winterScroll1() {
+	debug(9, "seq_winterScroll1()");
+	_screen->hideMouse();
+	checkAmuletAnimFlags();
+	assert(_winterScrollTable);
+	assert(_winterScroll1Table);
+	assert(_winterScroll2Table);
+	setupShapes123(_winterScrollTable, 7, 0);
+	setBrandonAnimSeqSize(5, 66);
+	
+	for (int i = 123; i <= 129; ++i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(8);
+	}
+	
+	freeShapes123();
+	snd_playSoundEffect(0x20);
+	setupShapes123(_winterScroll1Table, 35, 0);
+	
+	for (int i = 123; i <= 146; ++i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(8);
+	}
+	
+	if (_currentCharacter->sceneId == 41 && !queryGameFlag(0xA2)) {
+		snd_playSoundEffect(0x20);
+		_sprites->_anims[0].play = false;
+		_animator->sprites()[0].active = 0;
+		_sprites->_anims[1].play = true;
+		_animator->sprites()[1].active = 1;
+		setGameFlag(0xA2);
+	}
+	
+	for (int i = 147; i <= 157; ++i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(8);
+	}
+	
+	if (_currentCharacter->sceneId == 117 && !queryGameFlag(0xB3)) {
+		for (int i = 0; i <= 7; ++i) {
+			_sprites->_anims[i].play = false;
+			_animator->sprites()[i].active = 0;
+		}
+		uint8 tmpPal[768];
+		memcpy(tmpPal, _screen->_currentPalette, 768);
+		memcpy(&tmpPal[684], palTable2()[0], 60);
+		_screen->fadePalette(tmpPal, 72);
+		memcpy(&_screen->_currentPalette[684], palTable2()[0], 60);
+		_screen->setScreenPalette(_screen->_currentPalette);
+		setGameFlag(0xB3);
+	} else {
+		delayWithTicks(120);
+	}
+	
+	freeShapes123();
+	setupShapes123(_winterScroll2Table, 4, 0);
+	
+	for (int i = 123; i <= 126; ++i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(8);
+	}
+	
+	resetBrandonAnimSeqSize();
+	_currentCharacter->currentAnimFrame = 7;
+	animRefreshNPC(0);
+	freeShapes123();
+	_screen->showMouse();
+}
+
+void KyraEngine::seq_winterScroll2() {
+	debug(9, "seq_winterScroll2()");	
+	_screen->hideMouse();
+	checkAmuletAnimFlags();
+	assert(_winterScrollTable);
+	setupShapes123(_winterScrollTable, 7, 0);
+	setBrandonAnimSeqSize(5, 66);
+	
+	for (int i = 123; i <= 128; ++i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(8);
+	}
+	
+	delayWithTicks(120);
+	
+	for (int i = 127; i >= 123; --i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(8);
+	}
+	
+	resetBrandonAnimSeqSize();
+	_currentCharacter->currentAnimFrame = 7;
+	animRefreshNPC(0);
+	freeShapes123();
+	_screen->showMouse();
+}
+
+void KyraEngine::seq_makeBrandonInv() {
+	debug(9, "seq_makeBrandonInv()");
+	if (_deathHandler == 8)
+		return;
+
+	if (_currentCharacter->sceneId == 210) {
+		if (_beadStateVar == 4 || _beadStateVar == 6)
+			return;
+	}
+	
+	_screen->hideMouse();
+	checkAmuletAnimFlags();
+	_brandonStatusBit |= 0x20;
+	setTimerCountdown(18, 2700);
+	_brandonStatusBit |= 0x40;
+	snd_playSoundEffect(0x77);
+	_brandonInvFlag = 0;
+	while (_brandonInvFlag <= 0x100) {
+		animRefreshNPC(0);
+		delayWithTicks(10);
+		_brandonInvFlag += 0x10;
+	}
+	_brandonStatusBit &= 0xFFBF;
+	_screen->showMouse();
+}
+
+void KyraEngine::seq_makeBrandonNormal() {
+	debug(9, "seq_makeBrandonNormal()");
+	_screen->hideMouse();
+	_brandonStatusBit |= 0x40;
+	snd_playSoundEffect(0x77);
+	_brandonInvFlag = 0x100;
+	while (_brandonInvFlag >= 0) {
+		animRefreshNPC(0);
+		delayWithTicks(10);
+		_brandonInvFlag -= 0x10;
+	}
+	_brandonInvFlag = 0;
+	_brandonStatusBit &= 0xFF9F;
+	_screen->showMouse();
+}
+
+void KyraEngine::seq_makeBrandonNormal2() {
+	debug(9, "seq_makeBrandonNormal2()");
+	_screen->hideMouse();
+	assert(_brandonToWispTable);
+	setupShapes123(_brandonToWispTable, 26, 0);
+	setBrandonAnimSeqSize(5, 48);
+	_brandonStatusBit &= 0xFFFD;
+	snd_playSoundEffect(0x6C);
+	for (int i = 138; i >= 123; --i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(8);
+	}
+	setBrandonAnimSeqSize(4, 48);
+	_currentCharacter->currentAnimFrame = 7;
+	animRefreshNPC(0);
+	if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) {
+		_screen->fadeSpecialPalette(31, 234, 13, 4);
+	} else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) {
+		_screen->fadeSpecialPalette(14, 228, 15, 4);
+	}
+	freeShapes123();
+	_screen->showMouse();
+}
+
+void KyraEngine::seq_makeBrandonWisp() {
+	debug(9, "seq_makeBrandonWisp()");
+	if (_deathHandler == 8)
+		return;
+	
+	if (_currentCharacter->sceneId == 210) {
+		if (_beadStateVar == 4 || _beadStateVar == 6)
+			return;
+	}	
+	_screen->hideMouse();
+	checkAmuletAnimFlags();
+	assert(_brandonToWispTable);
+	setupShapes123(_brandonToWispTable, 26, 0);
+	setBrandonAnimSeqSize(5, 48);
+	snd_playSoundEffect(0x6C);
+	for (int i = 123; i <= 138; ++i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(8);
+	}
+	_brandonStatusBit |= 2;
+	if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) {
+		setTimerCountdown(14, 18000);
+	} else {
+		setTimerCountdown(14, 7200);
+	}
+	_brandonDrawFrame = 113;
+	_brandonStatusBit0x02Flag = 1;
+	_currentCharacter->currentAnimFrame = 113;
+	animRefreshNPC(0);
+	_animator->updateAllObjectShapes();
+	if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) {
+		_screen->fadeSpecialPalette(30, 234, 13, 4);
+	} else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) {
+		_screen->fadeSpecialPalette(14, 228, 15, 4);
+	}
+	freeShapes123();
+	_screen->showMouse();
+}
+
+void KyraEngine::seq_dispelMagicAnimation() {
+	debug(9, "seq_dispelMagicAnimation()");
+	if (_deathHandler == 8)
+		return;
+	if (_currentCharacter->sceneId == 210) {
+		if (_beadStateVar == 4 || _beadStateVar == 6)
+			return;
+	}
+	_screen->hideMouse();
+	if (_currentCharacter->sceneId == 210 && _currentCharacter->sceneId < 160)
+		_currentCharacter->facing = 3;
+	if (_malcolmFlag == 7 && _beadStateVar == 3) {
+		_beadStateVar = 6;
+		_unkEndSeqVar5 = 2;
+		_malcolmFlag = 10;
+	}
+	checkAmuletAnimFlags();
+	setGameFlag(0xEE);
+	assert(_magicAnimationTable);
+	setupShapes123(_magicAnimationTable, 5, 0);
+	setBrandonAnimSeqSize(8, 49);
+	snd_playSoundEffect(0x15);
+	for (int i = 123; i <= 127; ++i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(8);
+	}
+	
+	delayWithTicks(120);
+	
+	for (int i = 127; i >= 123; --i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(10);
+	}
+	resetBrandonAnimSeqSize();
+	_currentCharacter->currentAnimFrame = 7;
+	animRefreshNPC(0);
+	freeShapes123();
+	_screen->showMouse();
+}
+
+void KyraEngine::seq_fillFlaskWithWater(int item, int type) {
+	debug(9, "seq_fillFlaskWithWater(%d, %d)", item, type);
+	int newItem = -1;
+	static const uint8 flaskTable1[] = { 0x46, 0x48, 0x4A, 0x4C };
+	static const uint8 flaskTable2[] = { 0x47, 0x49, 0x4B, 0x4D };
+	
+	if (item >= 60 && item <= 77) {
+		assert(_flaskFull);
+		if (_features & GF_TALKIE) {
+			snd_voiceWaitForFinish();
+			snd_playVoiceFile(8006);
+		}
+		characterSays(_flaskFull[0], 0, -2);
+	} else if (item == 78) {
+		assert(type >= 0 && type < ARRAYSIZE(flaskTable1));
+		newItem = flaskTable1[type];
+	} else if (item == 79) {
+		assert(type >= 0 && type < ARRAYSIZE(flaskTable2));
+		newItem = flaskTable2[type];
+	}
+	
+	if (newItem == -1)
+		return;
+	
+	_screen->hideMouse();
+	setMouseItem(newItem);
+	_screen->showMouse();
+	_itemInHand = newItem;
+	assert(_fullFlask);
+	assert(type < _fullFlask_Size && type >= 0);
+	if (_features & GF_TALKIE) {
+		snd_voiceWaitForFinish();
+		static const uint16 voiceEntries[] = {
+			0x1F40, 0x1F41, 0x1F42, 0x1F45
+		};
+		assert(type < ARRAYSIZE(voiceEntries));
+		snd_playVoiceFile(voiceEntries[type]);
+	}
+	characterSays(_fullFlask[type], 0, -2);
+}
+
+void KyraEngine::seq_playDrinkPotionAnim(int unk1, int unk2, int flags) {
+	debug(9, "KyraEngine::seq_playDrinkPotionAnim(%d, %d, %d)", unk1, unk2, flags);
+	// XXX
+	_screen->hideMouse();
+	checkAmuletAnimFlags();
+	_currentCharacter->facing = 5;
+	animRefreshNPC(0);
+	assert(_drinkAnimationTable);
+	setupShapes123(_drinkAnimationTable, 9, flags);
+	setBrandonAnimSeqSize(5, 54);
+	
+	for (int i = 123; i <= 131; ++i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(5);
+	}	
+	snd_playSoundEffect(0x34);
+	for (int i = 0; i < 2; ++i) {
+		_currentCharacter->currentAnimFrame = 130;
+		animRefreshNPC(0);
+		delayWithTicks(7);
+		_currentCharacter->currentAnimFrame = 131;
+		animRefreshNPC(0);
+		delayWithTicks(7);
+	}
+	
+	if (unk2) {
+		// XXX
+	}
+	
+	for (int i = 131; i >= 123; --i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(5);
+	}
+	
+	resetBrandonAnimSeqSize();	
+	_currentCharacter->currentAnimFrame = 7;
+	animRefreshNPC(0);
+	freeShapes123();
+	_screen->showMouse();
+}
+
+int KyraEngine::seq_playEnd() {
+	debug(9, "KyraEngine::seq_playEnd()");
+	if (_endSequenceSkipFlag) {
+		return 0;
+	}
+	if (_deathHandler == 8) {
+		return 0;
+	}
+	_screen->_curPage = 2;
+	if (_endSequenceNeedLoading) {
+		snd_playWanderScoreViaMap(50, 1);
+		setupPanPages();
+		_finalA = new WSAMovieV1(this);
+		assert(_finalA);
+		_finalA->open("finala.wsa", 1, 0);
+		_finalB = new WSAMovieV1(this);
+		assert(_finalB);
+		_finalB->open("finalb.wsa", 1, 0);
+		_finalC = new WSAMovieV1(this);
+		assert(_finalC);
+		_endSequenceNeedLoading = 0;
+		_finalC->open("finalc.wsa", 1, 0);
+		_screen->_curPage = 0;
+		_beadStateVar = 0;
+		_malcolmFlag = 0;
+		// wired stuff with _unkEndSeqVar2 which needs timer handling
+		_screen->copyRegion(312, 0, 312, 0, 8, 136, 0, 2);
+	}
+	if (handleMalcolmFlag()) {
+		_beadStateVar = 0;
+		_malcolmFlag = 12;
+		handleMalcolmFlag();
+		handleBeadState();
+		closeFinalWsa();
+		if (_deathHandler == 8) {
+			_screen->_curPage = 0;
+			checkAmuletAnimFlags();
+			seq_brandonToStone();
+			waitTicks(60);
+			return 1;
+		} else {
+			_endSequenceSkipFlag = 1;
+			if (_text->printed()) {
+				_text->restoreTalkTextMessageBkgd(2, 0);
+			}
+			_screen->_curPage = 0;
+			_screen->hideMouse();
+			_screen->fadeSpecialPalette(32, 228, 20, 60);
+			waitTicks(60);
+			loadBitmap("GEMHEAL.CPS", 3, 3, _screen->_currentPalette);
+			_screen->setScreenPalette(_screen->_currentPalette);
+			_screen->shuffleScreen(8, 8, 304, 128, 2, 0, 1, 0);
+			uint32 nextTime = _system->getMillis() + 120 * _tickLength;
+			_finalA = new WSAMovieV1(this);
+			assert(_finalA);
+			_finalA->open("finald.wsa", 1, 0);
+			_finalA->_x = _finalA->_y = 8;
+			_finalA->_drawPage = 0;
+			while (_system->getMillis() < nextTime) {}
+			snd_playSoundEffect(0x40);
+			for (int i = 0; i < 22; ++i) {
+				while (_system->getMillis() < nextTime) {}
+				if (i == 4) {
+					snd_playSoundEffect(0x3E);
+				} else if (i == 20) {
+					snd_playSoundEffect(0x0E);
+				}
+				nextTime = _system->getMillis() + 8 * _tickLength;
+				_finalA->displayFrame(i);
+				_screen->updateScreen();
+			}
+			delete _finalA;
+			_finalA = 0;
+			seq_playEnding();
+			return 1;
+		}
+	} else {
+		handleBeadState();
+		_screen->bitBlitRects();
+		_screen->updateScreen();
+		_screen->_curPage = 0;
+	}
+	return 0;
+}
+
+void KyraEngine::seq_brandonToStone() {
+	debug(9, "KyraEngine::seq_brandonToStone()");
+	_screen->hideMouse();
+	assert(_brandonStoneTable);
+	setupShapes123(_brandonStoneTable, 14, 0);
+	setBrandonAnimSeqSize(5, 51);
+	for (int i = 123; i <= 136; ++i) {
+		_currentCharacter->currentAnimFrame = i;
+		animRefreshNPC(0);
+		delayWithTicks(8);
+	}
+	resetBrandonAnimSeqSize();
+	freeShapes123();
+	_screen->showMouse();
+}
+
+void KyraEngine::seq_playEnding() {
+	debug(9, "KyraEngine::seq_playEnding()");
+	_screen->hideMouse();
+	res_unloadResources(RES_INGAME);
+	res_loadResources(RES_OUTRO);
+	loadBitmap("REUNION.CPS", 3, 3, _screen->_currentPalette);
+	_screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0);
+	_screen->_curPage = 0;
+	// XXX
+	assert(_homeString);
+	drawSentenceCommand(_homeString[0], 179);
+	_screen->_curPage = 0;
+	_screen->fadeToBlack();
+	_seq->playSequence(_seq_Reunion, false);
+	_screen->fadeToBlack();
+	_screen->showMouse();
+	seq_playCredits();
+}
+
+void KyraEngine::seq_playCredits() {
+	debug(9, "KyraEngine::seq_playCredits()");
+	static const uint8 colorMap[] = { 0, 0, 0xC, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+	_screen->hideMouse();
+	uint32 sz = 0;
+	if (_features & GF_FLOPPY) {
+		_screen->loadFont(Screen::FID_CRED6_FNT, _res->fileData("CREDIT6.FNT", &sz));
+		_screen->loadFont(Screen::FID_CRED8_FNT, _res->fileData("CREDIT8.FNT", &sz));
+	}
+	loadBitmap("CHALET.CPS", 2, 2, _screen->_currentPalette);
+	_screen->setScreenPalette(_screen->_currentPalette);
+	_screen->setCurPage(0);
+	_screen->clearCurPage();
+	_screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0);
+	_screen->setTextColorMap(colorMap);
+	_screen->_charWidth = -1;
+	snd_playWanderScoreViaMap(53, 1);
+	// delete
+	_screen->updateScreen();
+	// XXX
+	waitTicks(120); // wait until user presses escape normally
+	_screen->fadeToBlack();
+	_screen->clearCurPage();
+	_screen->showMouse();
+}
+
+bool KyraEngine::seq_skipSequence() const {
+	debug(9, "KyraEngine::seq_skipSequence()");
+	return _quitFlag || _abortIntroFlag;
+}
+
+} // end of namespace Kyra

Modified: scummvm/trunk/kyra/sound.cpp
===================================================================
--- scummvm/trunk/kyra/sound.cpp	2006-02-09 04:58:21 UTC (rev 20436)
+++ scummvm/trunk/kyra/sound.cpp	2006-02-09 07:37:19 UTC (rev 20437)
@@ -345,4 +345,89 @@
 bool SoundPC::voiceIsPlaying() {
 	return _mixer->isSoundHandleActive(_vocHandle);
 }
+
+void KyraEngine::snd_playTheme(int file, int track) {
+	debug(9, "KyraEngine::snd_playTheme(%d)", file);
+	assert(file < _xmidiFilesCount);
+	_curMusicTheme = _newMusicTheme = file;
+	_sound->playMusic(_xmidiFiles[file]);
+	_sound->playTrack(track, false);
+}
+
+void KyraEngine::snd_setSoundEffectFile(int file) {
+	debug(9, "KyraEngine::snd_setSoundEffectFile(%d)", file);
+	assert(file < _xmidiFilesCount);
+	_sound->loadSoundEffectFile(_xmidiFiles[file]);
+}
+
+void KyraEngine::snd_playSoundEffect(int track) {
+	debug(9, "KyraEngine::snd_playSoundEffect(%d)", track);
+	if (track == 49) {
+		snd_playWanderScoreViaMap(56, 1);
+	} else {
+		_sound->playSoundEffect(track);
+	}
+}
+
+void KyraEngine::snd_playWanderScoreViaMap(int command, int restart) {
+	debug(9, "KyraEngine::snd_playWanderScoreViaMap(%d, %d)", command, restart);
+	static const int8 soundTable[] = {
+		-1,   0,  -1,   1,   0,   3,   0,   2,
+		 0,   4,   1,   2,   1,   3,   1,   4,
+		 1, 0x5C,   1,   6,   1,   7,   2,   2,
+		 2,   3,   2,   4,   2,   5,   2,   6,
+		 2,   7,   3,   3,   3,   4,   1,   8,
+		 1,   9,   4,   2,   4,   3,   4,   4,
+		 4,   5,   4,   6,   4,   7,   4,   8,
+		 1, 0x0B,   1, 0x0C,   1, 0x0E,   1, 0x0D,
+		 4,   9,   5, 0x0C,   6,   2,   6,   6,
+		 6,   7,   6,   8,   6,   9,   6,   3,
+		 6,   4,   6,   5,   7,   2,   7,   3,
+		 7,   4,   7,   5,   7,   6,   7,   7,
+		 7,   8,   7,   9,   8,   2,   8,   3,
+		 8,   4,   8,   5,   6, 0x0B,   5, 0x0B
+	};
+	//if (!_disableSound) {
+	//	XXX
+	//}
+	assert(command*2+1 < ARRAYSIZE(soundTable));
+	if (_curMusicTheme != soundTable[command*2]+1) {
+		if (soundTable[command*2] != -1) {
+			snd_playTheme(soundTable[command*2]+1);
+		}
+	}
+	
+	if (restart)
+		_lastMusicCommand = -1;
+	
+	if (command != 1) {
+		if (_lastMusicCommand != command) {
+			_lastMusicCommand = command;
+			_sound->playTrack(soundTable[command*2+1], true);
+		}
+	} else {
+		_lastMusicCommand = 1;
+		_sound->beginFadeOut();
+	}
+}
+
+void KyraEngine::snd_playVoiceFile(int id) {
+	debug(9, "KyraEngine::snd_playVoiceFile(%d)", id);
+	char vocFile[9];
+	assert(id >= 0 && id < 9999);
+	sprintf(vocFile, "%03d.VOC", id);
+	_sound->voicePlay(vocFile);
+}
+
+void KyraEngine::snd_voiceWaitForFinish(bool ingame) {
+	debug(9, "KyraEngine::snd_voiceWaitForFinish(%d)", ingame);
+	while (_sound->voiceIsPlaying() && !_fastMode) {
+		if (ingame) {
+			delay(10, true);
+		} else {
+			_system->delayMillis(10);
+		}
+	}
+}
+
 } // end of namespace Kyra

Modified: scummvm/trunk/kyra/staticres.cpp
===================================================================
--- scummvm/trunk/kyra/staticres.cpp	2006-02-09 04:58:21 UTC (rev 20436)
+++ scummvm/trunk/kyra/staticres.cpp	2006-02-09 07:37:19 UTC (rev 20437)
@@ -453,6 +453,146 @@
 	*string = 0;
 }
 
+void KyraEngine::loadMouseShapes() {
+	loadBitmap("MOUSE.CPS", 3, 3, 0);
+	_screen->_curPage = 2;
+	_shapes[4] = _screen->encodeShape(0, 0, 8, 10, 0);
+	_shapes[5] = _screen->encodeShape(0, 0x17, 0x20, 7, 0);
+	_shapes[6] = _screen->encodeShape(0x50, 0x12, 0x10, 9, 0);
+	_shapes[7] = _screen->encodeShape(0x60, 0x12, 0x10, 11, 0);
+	_shapes[8] = _screen->encodeShape(0x70, 0x12, 0x10, 9, 0);
+	_shapes[9] = _screen->encodeShape(0x80, 0x12, 0x10, 11, 0);
+	_shapes[10] = _screen->encodeShape(0x90, 0x12, 0x10, 10, 0);
+	_shapes[364] = _screen->encodeShape(0x28, 0, 0x10, 13, 0);
+	_screen->setMouseCursor(1, 1, 0);
+	_screen->setMouseCursor(1, 1, _shapes[4]);
+	_screen->setShapePages(5, 3);
+}
+
+void KyraEngine::loadCharacterShapes() {
+	int curImage = 0xFF;
+	int videoPage = _screen->_curPage;
+	_screen->_curPage = 2;
+	for (int i = 0; i < 115; ++i) {	
+		assert(i < _defaultShapeTableSize);
+		Shape *shape = &_defaultShapeTable[i];
+		if (shape->imageIndex == 0xFF) {
+			_shapes[i+7+4] = 0;
+			continue;
+		}
+		if (shape->imageIndex != curImage) {
+			assert(shape->imageIndex < _characterImageTableSize);
+			loadBitmap(_characterImageTable[shape->imageIndex], 3, 3, 0);
+			curImage = shape->imageIndex;
+		}
+		_shapes[i+7+4] = _screen->encodeShape(shape->x<<3, shape->y, shape->w<<3, shape->h, 1);
+	}
+	_screen->_curPage = videoPage;
+}
+
+void KyraEngine::loadSpecialEffectShapes() {
+	loadBitmap("EFFECTS.CPS", 3, 3, 0);
+	_screen->_curPage = 2;
+ 
+	int currShape; 
+	for (currShape = 173; currShape < 183; currShape++)
+		_shapes[4 + currShape] = _screen->encodeShape((currShape-173) * 24, 0, 24, 24, 1);
+ 
+	for (currShape = 183; currShape < 190; currShape++)
+		_shapes[4 + currShape] = _screen->encodeShape((currShape-183) * 24, 24, 24, 24, 1);
+ 
+	for (currShape = 190; currShape < 201; currShape++)
+		_shapes[4 + currShape] = _screen->encodeShape((currShape-190) * 24, 48, 24, 24, 1);
+ 
+	for (currShape = 201; currShape < 206; currShape++)
+		_shapes[4 + currShape] = _screen->encodeShape((currShape-201) * 16, 106, 16, 16, 1);
+}
+
+void KyraEngine::loadItems() {
+	int shape;
+
+	loadBitmap("JEWELS3.CPS", 3, 3, 0);
+	_screen->_curPage = 2;
+
+	_shapes[327] = 0;
+
+	for (shape = 1; shape < 6; shape++ )
+		_shapes[327 + shape] = _screen->encodeShape((shape - 1) * 32, 0, 32, 17, 0);
+
+	for (shape = 330; shape <= 334; shape++)
+		_shapes[4 + shape] = _screen->encodeShape((shape-330) * 32, 102, 32, 17, 0);
+
+	for (shape = 335; shape <= 339; shape++)
+		_shapes[4 + shape] = _screen->encodeShape((shape-335) * 32, 17,  32, 17, 0);
+
+	for (shape = 340; shape <= 344; shape++)
+		_shapes[4 + shape] = _screen->encodeShape((shape-340) * 32, 34,  32, 17, 0);
+
+	for (shape = 345; shape <= 349; shape++)
+		_shapes[4 + shape] = _screen->encodeShape((shape-345) * 32, 51,  32, 17, 0);
+
+	for (shape = 350; shape <= 354; shape++)
+		_shapes[4 + shape] = _screen->encodeShape((shape-350) * 32, 68,  32, 17, 0);
+
+	for (shape = 355; shape <= 359; shape++)
+		_shapes[4 + shape] = _screen->encodeShape((shape-355) * 32, 85,  32, 17, 0);
+
+
+	loadBitmap("ITEMS.CPS", 3, 3, 0);
+	_screen->_curPage = 2;
+
+	for (int i = 0; i < 107; i++) {
+		shape = findDuplicateItemShape(i);
+
+		if (shape != -1)
+			_shapes[220 + i] = _shapes[220 + shape];
+		else
+			_shapes[220 + i] = _screen->encodeShape( (i % 20) * 16, i/20 * 16, 16, 16, 0);
+	}
+
+	uint32 size;
+	uint8 *fileData = _res->fileData("_ITEM_HT.DAT", &size);
+	assert(fileData);
+
+	for (int i = 0; i < 107; i++) {
+		_itemTable[i].height = fileData[i];
+		_itemTable[i].unk1 = _itemTable[i].unk2 = 0;
+	}
+
+	delete[] fileData;
+}
+
+void KyraEngine::loadButtonShapes() {
+	loadBitmap("BUTTONS2.CPS", 3, 3, 0);
+	_screen->_curPage = 2;
+	_scrollUpButton.process0PtrShape = _screen->encodeShape(0, 0, 24, 14, 1);
+	_scrollUpButton.process1PtrShape = _screen->encodeShape(24, 0, 24, 14, 1);
+	_scrollUpButton.process2PtrShape = _screen->encodeShape(48, 0, 24, 14, 1);
+	_scrollDownButton.process0PtrShape = _screen->encodeShape(0, 15, 24, 14, 1);
+	_scrollDownButton.process1PtrShape = _screen->encodeShape(24, 15, 24, 14, 1);
+	_scrollDownButton.process2PtrShape = _screen->encodeShape(48, 15, 24, 14, 1);
+	_screen->_curPage = 0;
+}
+
+void KyraEngine::loadMainScreen(int page) {
+	if ((_features & GF_ENGLISH) && (_features & GF_TALKIE)) 
+		loadBitmap("MAIN_ENG.CPS", page, page, 0);
+	else if(_features & GF_FRENCH)
+		loadBitmap("MAIN_FRE.CPS", page, page, 0);
+	else if(_features & GF_GERMAN)
+		loadBitmap("MAIN_GER.CPS", page, page, 0);
+	else if ((_features & GF_ENGLISH) && (_features & GF_FLOPPY))
+		loadBitmap("MAIN15.CPS", page, page, 0);
+	else if (_features & GF_SPANISH)
+		loadBitmap("MAIN_SPA.CPS", page, page, 0);
+	else
+		warning("no main graphics file found");
+	
+	uint8 *_pageSrc = _screen->getPagePtr(page);
+	uint8 *_pageDst = _screen->getPagePtr(0);
+	memcpy(_pageDst, _pageSrc, 320*200);
+}
+
 const ScreenDim Screen::_screenDimTable[] = {
 	{ 0x00, 0x00, 0x28, 0xC8, 0x0F, 0x0C, 0x00, 0x00 },
 	{ 0x08, 0x48, 0x18, 0x38, 0x0F, 0x0C, 0x00, 0x00 },

Modified: scummvm/trunk/kyra/text.cpp
===================================================================
--- scummvm/trunk/kyra/text.cpp	2006-02-09 04:58:21 UTC (rev 20436)
+++ scummvm/trunk/kyra/text.cpp	2006-02-09 07:37:19 UTC (rev 20437)
@@ -21,10 +21,342 @@
 
 #include "common/stdafx.h"
 
+#include "kyra/kyra.h"
 #include "kyra/screen.h"
 #include "kyra/text.h"
+#include "kyra/animator.h"
+#include "kyra/sprites.h"
 
+#include "common/system.h"
+
 namespace Kyra {
+
+void KyraEngine::waitForChatToFinish(int16 chatDuration, char *chatStr, uint8 charNum) {
+	debug(9, "KyraEngine::waitForChatToFinish(%i, %s, %i)", chatDuration, chatStr, charNum); 
+	bool hasUpdatedNPCs = false;
+	bool runLoop = true;
+	uint8 currPage;
+	OSystem::Event event;
+	int16 delayTime;
+
+	//while( towns_isEscKeyPressed() )
+		//towns_getKey();
+
+	uint32 timeToEnd = strlen(chatStr) * 8 * _tickLength + _system->getMillis();
+
+	if (chatDuration != -1 ) {
+		switch (_configTalkspeed) {
+			case 0: chatDuration *= 2;
+					break;
+			case 2: chatDuration /= 4;
+					break;
+			case 3: chatDuration = -1;
+		}
+	}
+
+	if (chatDuration != -1)
+		chatDuration *= _tickLength;
+
+	disableTimer(14);
+	disableTimer(18);
+	disableTimer(19);
+
+	uint32 timeAtStart = _system->getMillis();
+	uint32 loopStart;
+	while (runLoop) {
+		loopStart = _system->getMillis();
+		if (_currentCharacter->sceneId == 210)
+			if (seq_playEnd())
+				break;
+
+		if (_system->getMillis() > timeToEnd && !hasUpdatedNPCs) {
+			hasUpdatedNPCs = true;
+			disableTimer(15);
+			_currHeadShape = 4;
+			animRefreshNPC(0);
+			animRefreshNPC(_talkingCharNum);
+
+			if (_charSayUnk2 != -1) {
+				_animator->sprites()[_charSayUnk2].active = 0;
+				_sprites->_anims[_charSayUnk2].play = false;
+				_charSayUnk2 = -1;
+			}
+		}
+
+		updateGameTimers();
+		_sprites->updateSceneAnims();
+		_animator->restoreAllObjectBackgrounds();
+		_animator->preserveAnyChangedBackgrounds();
+		_animator->prepDrawAllObjects();
+
+		currPage = _screen->_curPage;
+		_screen->_curPage = 2;
+		_text->printCharacterText(chatStr, charNum, _characterList[charNum].x1);
+		_screen->_curPage = currPage;
+
+		_animator->copyChangedObjectsForward(0);
+		updateTextFade();
+
+		if ((chatDuration < (int16)(_system->getMillis() - timeAtStart)) && chatDuration != -1)
+			break;
+
+		while (_system->pollEvent(event)) {
+			switch (event.type) {
+			case OSystem::EVENT_KEYDOWN:
+				if (event.kbd.keycode == '.')
+					runLoop = false;
+				break;
+			case OSystem::EVENT_QUIT:
+				quitGame();
+			case OSystem::EVENT_LBUTTONDOWN:
+				runLoop = false;
+				break;
+			default:
+				break;
+			}
+		}
+		
+		if (_fastMode)
+			runLoop = false;
+
+		delayTime = (loopStart + _gameSpeed) - _system->getMillis();
+		if (delayTime > 0)
+			_system->delayMillis(delayTime);
+	}
+
+	enableTimer(14);
+	enableTimer(15);
+	enableTimer(18);
+	enableTimer(19);
+	//clearKyrandiaButtonIO();
+}
+
+void KyraEngine::endCharacterChat(int8 charNum, int16 convoInitialized) {
+	_charSayUnk3 = -1;
+
+	if (charNum > 4 && charNum < 11) {
+		//TODO: weird _game_inventory stuff here
+		warning("STUB: endCharacterChat() for high charnums");
+	}
+
+	if (convoInitialized != 0) {
+		_talkingCharNum = -1;
+		_currentCharacter->currentAnimFrame = 7;
+		animRefreshNPC(0);
+		_animator->updateAllObjectShapes();
+	}
+}
+
+void KyraEngine::restoreChatPartnerAnimFrame(int8 charNum) {
+	_talkingCharNum = -1;
+
+	if (charNum > 0 && charNum < 5) {
+		_characterList[charNum].currentAnimFrame = _currentChatPartnerBackupFrame;
+		animRefreshNPC(charNum);
+	}
+
+	_currentCharacter->currentAnimFrame = 7;
+	animRefreshNPC(0);
+	_animator->updateAllObjectShapes();
+}
+
+void KyraEngine::backupChatPartnerAnimFrame(int8 charNum) {
+	_talkingCharNum = 0;
+
+	if (charNum < 5 && charNum > 0) 
+		_currentChatPartnerBackupFrame = _characterList[charNum].currentAnimFrame;
+
+	if (_scaleMode != 0)
+		_currentCharacter->currentAnimFrame = 7;
+	else
+		_currentCharacter->currentAnimFrame = _currentCharAnimFrame;
+
+	animRefreshNPC(0);
+	_animator->updateAllObjectShapes();
+}
+
+int8 KyraEngine::getChatPartnerNum() {
+	uint8 sceneTable[] = {0x2, 0x5, 0x2D, 0x7, 0x1B, 0x8, 0x22, 0x9, 0x30, 0x0A};
+	int pos = 0;
+	int partner = -1;
+
+	for (int i = 1; i < 6; i++) {
+		if (_currentCharacter->sceneId == sceneTable[pos]) {
+			partner = sceneTable[pos+1];
+			break;
+		}
+		pos += 2;
+	}
+
+	for (int i = 1; i < 5; i++) {
+		if (_characterList[i].sceneId == _currentCharacter->sceneId) {
+			partner = i;
+			break;
+		}
+	}
+	return partner;
+}
+
+int KyraEngine::initCharacterChat(int8 charNum) {
+	if (_talkingCharNum == -1) {
+		_talkingCharNum = 0;
+
+		if (_scaleMode != 0)
+			_currentCharacter->currentAnimFrame = 7;
+		else
+			_currentCharacter->currentAnimFrame = 16;
+
+		animRefreshNPC(0);
+		_animator->updateAllObjectShapes();
+	}
+
+	_charSayUnk2 = -1;
+	_animator->flagAllObjectsForBkgdChange();
+	_animator->restoreAllObjectBackgrounds();
+
+	if (charNum > 4 && charNum < 11) {
+		// TODO: Fill in weird _game_inventory stuff here
+		warning("STUB: initCharacterChat() for high charnums");
+	}
+
+	_animator->flagAllObjectsForRefresh();
+	_animator->flagAllObjectsForBkgdChange();
+	_animator->preserveAnyChangedBackgrounds();
+	_charSayUnk3 = charNum;
+
+	return 1;
+}
+
+void KyraEngine::characterSays(char *chatStr, int8 charNum, int8 chatDuration) {
+	debug(9, "KyraEngine::characterSays('%s', %i, %d)", chatStr, charNum, chatDuration);
+	uint8 startAnimFrames[] =  { 0x10, 0x32, 0x56, 0x0, 0x0, 0x0 };
+
+	uint16 chatTicks;
+	int16 convoInitialized;
+	int8 chatPartnerNum;
+
+	if (_currentCharacter->sceneId == 210)
+		return;
+
+	convoInitialized = initCharacterChat(charNum);	
+	chatPartnerNum = getChatPartnerNum();
+
+	if (chatPartnerNum != -1 && chatPartnerNum < 5)
+		backupChatPartnerAnimFrame(chatPartnerNum);
+
+	if (charNum < 5) {
+		_characterList[charNum].currentAnimFrame = startAnimFrames[charNum];
+		_charSayUnk3 = charNum;
+		_talkingCharNum = charNum;
+		animRefreshNPC(charNum);
+	}
+
+	char *processedString = _text->preprocessString(chatStr);
+	int lineNum = _text->buildMessageSubstrings(processedString);
+
+	int16 yPos = _characterList[charNum].y1;
+	yPos -= _scaleTable[charNum] * _characterList[charNum].height;
+	yPos -= 8;
+	yPos -= lineNum * 10;
+
+	if (yPos < 11)
+		yPos = 11;
+
+	if (yPos > 100)
+		yPos = 100;
+
+	_text->_talkMessageY = yPos;
+	_text->_talkMessageH = lineNum * 10;
+	_animator->restoreAllObjectBackgrounds();
+
+	_screen->copyRegion(12, _text->_talkMessageY, 12, 136, 308, _text->_talkMessageH, 2, 2);
+	_screen->hideMouse();
+
+	_text->printCharacterText(processedString, charNum, _characterList[charNum].x1);
+	_screen->showMouse();
+
+	if (chatDuration == -2)
+		chatTicks = strlen(processedString) * 9;
+	else
+		chatTicks = chatDuration;
+
+	waitForChatToFinish(chatTicks, chatStr, charNum);
+
+	_animator->restoreAllObjectBackgrounds();
+
+	_screen->copyRegion(12, 136, 12, _text->_talkMessageY, 308, _text->_talkMessageH, 2, 2);
+	_animator->preserveAllBackgrounds();
+	_animator->prepDrawAllObjects();
+	_screen->hideMouse();
+
+	_screen->copyRegion(12, _text->_talkMessageY, 12, _text->_talkMessageY, 308, _text->_talkMessageH, 2, 0);
+	_screen->showMouse();
+	_animator->flagAllObjectsForRefresh();
+	_animator->copyChangedObjectsForward(0);
+
+	if (chatPartnerNum != -1 && chatPartnerNum < 5)
+		restoreChatPartnerAnimFrame(chatPartnerNum);
+
+	endCharacterChat(charNum, convoInitialized);
+}
+
+void KyraEngine::drawSentenceCommand(char *sentence, int color) {
+	debug(9, "KyraEngine::drawSentenceCommand('%s', %i)", sentence, color);
+	_screen->hideMouse();
+	_screen->fillRect(8, 143, 311, 152, 12);
+
+	if (_startSentencePalIndex != color || _fadeText != false) {
+		_currSentenceColor[0] = _screen->_currentPalette[765] = _screen->_currentPalette[color*3];
+		_currSentenceColor[1] = _screen->_currentPalette[766] = _screen->_currentPalette[color*3+1];
+		_currSentenceColor[2] = _screen->_currentPalette[767] = _screen->_currentPalette[color*3+2];
+	
+		_screen->setScreenPalette(_screen->_currentPalette);
+		_startSentencePalIndex = 0;
+	}
+
+	_text->printText(sentence, 8, 143, 0xFF, 12, 0);
+	_screen->showMouse();
+	setTextFadeTimerCountdown(15);
+	_fadeText = false;
+}
+
+void KyraEngine::updateSentenceCommand(char *str1, char *str2, int color) {
+	debug(9, "KyraEngine::updateSentenceCommand('%s', '%s', %i)", str1, str2, color);
+	char sentenceCommand[500];
+	strncpy(sentenceCommand, str1, 500);
+	if (str2)
+		strncat(sentenceCommand, str2, 500 - strlen(sentenceCommand));
+
+	drawSentenceCommand(sentenceCommand, color);
+	_screen->updateScreen();
+}
+
+void KyraEngine::updateTextFade() {
+	debug(9, "KyraEngine::updateTextFade()");
+	if (!_fadeText)
+		return;
+	
+	bool finished = false;
+	for (int i = 0; i < 3; i++)
+		if (_currSentenceColor[i] > 4)
+			_currSentenceColor[i] -= 4;
+		else
+			if (_currSentenceColor[i]) {
+				_currSentenceColor[i] = 0;
+				finished = true;
+			}
+		
+	_screen->_currentPalette[765] = _currSentenceColor[0];
+	_screen->_currentPalette[766] = _currSentenceColor[1];
+	_screen->_currentPalette[767] = _currSentenceColor[2];
+	_screen->setScreenPalette(_screen->_currentPalette);
+
+	if (finished) {
+		_fadeText = false;
+		_startSentencePalIndex = -1;
+	}
+}
+
 TextDisplayer::TextDisplayer(Screen *screen) {
 	_screen = screen;
 







More information about the Scummvm-git-logs mailing list