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

vinterstum at users.sourceforge.net vinterstum at users.sourceforge.net
Sat Feb 11 00:33:01 CET 2006


Revision: 20493
Author:   vinterstum
Date:     2006-02-11 00:31:13 -0800 (Sat, 11 Feb 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm?rev=20493&view=rev

Log Message:
-----------
Kyra cleanup path step 2

* Moved more code out of kyra.cpp.
  Specifically moved Kyra1 specific sequence helper functions to sequence.cpp 
  (and updateKyragemFading() from animator.cpp for the same reason),
  and some generic animation functions to animator.cpp. This is mainly
  in preparation for Kyra2.
* Additionally, cleaned up my last bugfix a little bit :)

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/saveload.cpp
    scummvm/trunk/kyra/scene.cpp
    scummvm/trunk/kyra/script_v1.cpp
    scummvm/trunk/kyra/sequences.cpp
    scummvm/trunk/kyra/sprites.cpp
    scummvm/trunk/kyra/text.cpp
    scummvm/trunk/kyra/timer.cpp
Modified: scummvm/trunk/kyra/animator.cpp
===================================================================
--- scummvm/trunk/kyra/animator.cpp	2006-02-11 08:25:20 UTC (rev 20492)
+++ scummvm/trunk/kyra/animator.cpp	2006-02-11 08:31:13 UTC (rev 20493)
@@ -36,10 +36,6 @@
 	_system = system;
 	_screenObjects = _actors = _items = _sprites = _objectQueue = 0;
 	_noDrawShapesFlag = 0;
-	
-	memset(&_kyragemFadingState, 0, sizeof(_kyragemFadingState));
-	_kyragemFadingState.gOffset = 0x13;
-	_kyragemFadingState.bOffset = 0x13;
 }
 
 ScreenAnimator::~ScreenAnimator() {
@@ -54,6 +50,8 @@
 	_actors = _screenObjects;
 	_sprites = &_screenObjects[actors_];
 	_items = &_screenObjects[actors_ + items_];
+	_brandonDrawFrame = 113;
+
 	_initOk = true;
 }
 
@@ -271,17 +269,17 @@
 						
 					int tempX = 0, tempY = 0;
 					if (curObject->flags & 0x1) {
-						tempX = (xOffsetTable1[curObject->index] * _vm->_brandonScaleX) >> 8;
+						tempX = (xOffsetTable1[curObject->index] * _brandonScaleX) >> 8;
 						tempY = yOffsetTable1[curObject->index];
 					} else {
-						tempX = (xOffsetTable2[curObject->index] * _vm->_brandonScaleX) >> 8;
+						tempX = (xOffsetTable2[curObject->index] * _brandonScaleX) >> 8;
 						tempY = yOffsetTable2[curObject->index];
 					}
-					tempY = (tempY * _vm->_brandonScaleY) >> 8;
+					tempY = (tempY * _brandonScaleY) >> 8;
 					xpos += tempX;
 					ypos += tempY;
 					
-					if (_vm->_scaleMode && _vm->_brandonScaleX != 256) {
+					if (_vm->_scaleMode && _brandonScaleX != 256) {
 						++xpos;
 					}
 					
@@ -301,14 +299,14 @@
 							if (!(flagUnk3 & 0x100) && (flagUnk2 & 0x4000)) {
 								tempFlags = curObject->flags & 1;
 								tempFlags |= 0x900 | flagUnk1 | 0x4000;
-								_screen->drawShape(drawPage, _vm->_shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _vm->_brandonPoisonFlagsGFX, int(1), int(_vm->_brandonInvFlag), drawLayer, _vm->_brandonScaleX, _vm->_brandonScaleY);
+								_screen->drawShape(drawPage, _vm->_shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _vm->_brandonPoisonFlagsGFX, int(1), int(_vm->_brandonInvFlag), drawLayer, _brandonScaleX, _brandonScaleY);
 							} else {
 								if (!(flagUnk2 & 0x4000)) {
 									tempFlags = curObject->flags & 1;
 									tempFlags |= 0x900 | flagUnk1;
 								}
 								
-								_screen->drawShape(drawPage, _vm->_shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _vm->_brandonPoisonFlagsGFX, int(1), drawLayer, _vm->_brandonScaleX, _vm->_brandonScaleY);
+								_screen->drawShape(drawPage, _vm->_shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _vm->_brandonPoisonFlagsGFX, int(1), drawLayer, _brandonScaleX, _brandonScaleY);
 							}
 						}
 					} else {
@@ -348,11 +346,11 @@
 					}
 				} else {
 					if (flagUnk3 & 0x100) {
-						_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x104, (uint8*)_vm->_brandonPoisonFlagsGFX, int(1), drawLayer, _vm->_brandonScaleX, _vm->_brandonScaleY);
+						_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x104, (uint8*)_vm->_brandonPoisonFlagsGFX, int(1), drawLayer, _brandonScaleX, _brandonScaleY);
 					} else if (flagUnk3 & 0x4000) {
-						_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4004, int(_vm->_brandonInvFlag), drawLayer, _vm->_brandonScaleX, _vm->_brandonScaleY);
+						_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4004, int(_vm->_brandonInvFlag), drawLayer, _brandonScaleX, _brandonScaleY);
 					} else {
-						_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4, drawLayer, _vm->_brandonScaleX, _vm->_brandonScaleY);
+						_screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4, drawLayer, _brandonScaleX, _brandonScaleY);
 					}
 				}
 			} else {
@@ -442,8 +440,8 @@
 	animObj->animFrameNumber = -1;
 	animObj->x1 = currentRoom->itemsXPos[index];
 	animObj->y1 = currentRoom->itemsYPos[index];
-	animObj->x1 -= _vm->fetchAnimWidth(animObj->sceneAnimPtr, _vm->_scaleTable[animObj->drawY]) >> 1;
-	animObj->y1 -= _vm->fetchAnimHeight(animObj->sceneAnimPtr, _vm->_scaleTable[animObj->drawY]);
+	animObj->x1 -= fetchAnimWidth(animObj->sceneAnimPtr, _vm->_scaleTable[animObj->drawY]) >> 1;
+	animObj->y1 -= fetchAnimHeight(animObj->sceneAnimPtr, _vm->_scaleTable[animObj->drawY]);
 	animObj->x2 = animObj->x1;
 	animObj->y2 = animObj->y1;
 	animObj->width2 = 0;
@@ -565,73 +563,129 @@
 	}
 }
 
-void ScreenAnimator::updateKyragemFading() {
-	static const uint8 kyraGemPalette[0x28] = {
-		0x3F, 0x3B, 0x38, 0x34, 0x32, 0x2F, 0x2C, 0x29, 0x25, 0x22,
-		0x1F, 0x1C, 0x19, 0x16, 0x12, 0x0F, 0x0C, 0x0A, 0x06, 0x03,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-	};
+void ScreenAnimator::makeBrandonFaceMouse() {
+	debug(9, "ScreenAnimator::makeBrandonFaceMouse()");
+	if (_vm->mouseX() >= _vm->_currentCharacter->x1) {
+		_vm->_currentCharacter->facing = 3;
+	} else {
+		_vm->_currentCharacter->facing = 5;
+	}
+	animRefreshNPC(0);
+	updateAllObjectShapes();
+}
+
+int16 ScreenAnimator::fetchAnimWidth(const uint8 *shape, int16 mult) {
+	debug(9, "ScreenAnimator::fetchAnimWidth(0x%X, %d)", shape, mult);
+	if (_vm->features() & GF_TALKIE)
+		shape += 2;
+	return (((int16)READ_LE_UINT16((shape+3))) * mult) >> 8;
+}
+
+int16 ScreenAnimator::fetchAnimHeight(const uint8 *shape, int16 mult) {
+	debug(9, "ScreenAnimator::fetchAnimHeight(0x%X, %d)", shape, mult);
+	if (_vm->features() & GF_TALKIE)
+		shape += 2;
+	return (int16)(((int8)*(shape+2)) * mult) >> 8;
+}
+
+void ScreenAnimator::setBrandonAnimSeqSize(int width, int height) {
+	debug(9, "ScreenAnimator::setBrandonAnimSeqSize(%d, %d)", width, height);
+	restoreAllObjectBackgrounds();
+	_brandonAnimSeqSizeWidth = _actors[0].width;
+	_brandonAnimSeqSizeHeight = _actors[0].height;
+	_actors[0].width = width + 1;
+	_actors[0].height = height;
+	preserveAllBackgrounds();
+}
+
+void ScreenAnimator::resetBrandonAnimSeqSize() {
+	debug(9, "ScreenAnimator::resetBrandonAnimSeqSize()");
+	restoreAllObjectBackgrounds();
+	_actors[0].width = _brandonAnimSeqSizeWidth;
+	_actors[0].height = _brandonAnimSeqSizeHeight;
+	preserveAllBackgrounds();
+}
+
+void ScreenAnimator::animRefreshNPC(int character) {
+	debug(9, "ScreenAnimator::animRefreshNPC(%d)", character);
+	AnimObject *animObj = &_actors[character];
+	Character *ch = &_vm->characterList()[character];
+
+	animObj->refreshFlag = 1;
+	animObj->bkgdChangeFlag = 1;
+	int facing = ch->facing;
+	if (facing >= 1 && facing <= 3) {
+		animObj->flags |= 1;
+	} else if (facing >= 5 && facing <= 7) {
+		animObj->flags &= 0xFFFFFFFE;
+	}
 	
-	if (_system->getMillis() < _kyragemFadingState.timerCount)
-		return;
+	animObj->drawY = ch->y1;
+	animObj->sceneAnimPtr = _vm->shapes()[4+ch->currentAnimFrame];
+	animObj->animFrameNumber = ch->currentAnimFrame;
+	if (character == 0) {
+		if (_vm->brandonStatus() & 10) {
+			animObj->animFrameNumber = 88;
+			ch->currentAnimFrame = 88;
+		}
+		if (_vm->brandonStatus() & 2) {
+			animObj->animFrameNumber = _brandonDrawFrame;
+			ch->currentAnimFrame = _brandonDrawFrame;
+			animObj->sceneAnimPtr = _vm->shapes()[4+_brandonDrawFrame];
+			if (_vm->_brandonStatusBit0x02Flag) {
+				++_brandonDrawFrame;
+				if (_brandonDrawFrame >= 122)
+					_brandonDrawFrame = 113;
+					_vm->_brandonStatusBit0x02Flag = 0;
+			}
+		}
+	}
 	
-	_kyragemFadingState.timerCount = _system->getMillis() + 4 * _vm->tickLength();
-	int palPos = 684;
-	for (int i = 0; i < 20; ++i) {
-		_screen->_currentPalette[palPos++] = kyraGemPalette[i + _kyragemFadingState.rOffset];
-		_screen->_currentPalette[palPos++] = kyraGemPalette[i + _kyragemFadingState.gOffset];
-		_screen->_currentPalette[palPos++] = kyraGemPalette[i + _kyragemFadingState.bOffset];
+	int xOffset = _vm->_defaultShapeTable[ch->currentAnimFrame-7].xOffset;
+	int yOffset = _vm->_defaultShapeTable[ch->currentAnimFrame-7].yOffset;
+	
+	if (_vm->_scaleMode) {
+		animObj->x1 = ch->x1;
+		animObj->y1 = ch->y1;
+		
+		_brandonScaleX = _vm->_scaleTable[ch->y1];
+		_brandonScaleY = _vm->_scaleTable[ch->y1];
+
+		animObj->x1 += (_brandonScaleX * xOffset) >> 8;
+		animObj->y1 += (_brandonScaleY * yOffset) >> 8;
+	} else {
+		animObj->x1 = ch->x1 + xOffset;
+		animObj->y1 = ch->y1 + yOffset;
 	}
-	_screen->setScreenPalette(_screen->_currentPalette);
-	_updateScreen = true;
-	switch (_kyragemFadingState.nextOperation) {
-		case 0:
-			--_kyragemFadingState.bOffset;
-			if (_kyragemFadingState.bOffset >= 1)
-				return;
-			_kyragemFadingState.nextOperation = 1;
-			break;
+	animObj->width2 = 4;
+	animObj->height2 = 3;
 
-		case 1:
-			++_kyragemFadingState.rOffset;
-			if (_kyragemFadingState.rOffset < 19)
-				return;
-			_kyragemFadingState.nextOperation = 2;
-			break;
+	refreshObject(animObj);
+}
 
-		case 2:
-			--_kyragemFadingState.gOffset;
-			if (_kyragemFadingState.gOffset >= 1)
-				return;
-			_kyragemFadingState.nextOperation = 3;
-			break;
-		
-		case 3:
-			++_kyragemFadingState.bOffset;
-			if (_kyragemFadingState.bOffset < 19)
-				return;
-			_kyragemFadingState.nextOperation = 4;
-			break;
-		
-		case 4:
-			--_kyragemFadingState.rOffset;
-			if (_kyragemFadingState.rOffset >= 1)
-				return;
-			_kyragemFadingState.nextOperation = 5;
-			break;
-		
-		case 5:
-			++_kyragemFadingState.gOffset;
-			if (_kyragemFadingState.gOffset < 19)
-				return;
-			_kyragemFadingState.nextOperation = 0;
-			break;
-			
-		default:
-			break;
+void ScreenAnimator::setCharacterDefaultFrame(int character) {
+	debug(9, "ScreenAnimator::setCharacterDefaultFrame()");
+	static uint16 initFrameTable[] = {
+		7, 41, 77, 0, 0
+	};
+	assert(character < ARRAYSIZE(initFrameTable));
+	Character *edit = &_vm->characterList()[character];
+	edit->sceneId = 0xFFFF;
+	edit->facing = 0;
+	edit->currentAnimFrame = initFrameTable[character];
+	// edit->unk6 = 1;
+}
+
+void ScreenAnimator::setCharactersHeight() {
+	debug(9, "ScreenAnimator::setCharactersHeight()");
+	static int8 initHeightTable[] = {
+		48, 40, 48, 47, 56,
+		44, 42, 47, 38, 35,
+		40
+	};
+	for (int i = 0; i < 11; ++i) {
+		_vm->characterList()[i].height = initHeightTable[i];
 	}
-	
-	_kyragemFadingState.timerCount = _system->getMillis() + 120 * _vm->tickLength();
 }
+
 } // end of namespace Kyra

Modified: scummvm/trunk/kyra/animator.h
===================================================================
--- scummvm/trunk/kyra/animator.h	2006-02-11 08:25:20 UTC (rev 20492)
+++ scummvm/trunk/kyra/animator.h	2006-02-11 08:31:13 UTC (rev 20493)
@@ -76,15 +76,27 @@
 	void animRemoveGameItem(int index);
 	void animAddGameItem(int index, uint16 sceneId);
 	void animAddNPC(int character);
+	void animRefreshNPC(int character);
 
 	void clearQueue() { _objectQueue = 0; }
 	void addObjectToQueue(AnimObject *object);
 	void refreshObject(AnimObject *object);
 	
-	void updateKyragemFading();
+	void makeBrandonFaceMouse();
+	void setBrandonAnimSeqSize(int width, int height);
+	void resetBrandonAnimSeqSize();
+	void setCharacterDefaultFrame(int character);
+	void setCharactersHeight();
 
+	int16 fetchAnimWidth(const uint8 *shape, int16 mult);
+	int16 fetchAnimHeight(const uint8 *shape, int16 mult);
+
 	int _noDrawShapesFlag;
 	bool _updateScreen;
+	uint16 _brandonDrawFrame;
+	int _brandonScaleX;
+	int _brandonScaleY;
+
 protected:
 	KyraEngine *_vm;
 	Screen *_screen;
@@ -104,14 +116,10 @@
 	void preserveOrRestoreBackground(AnimObject *obj, bool restore);
 
 	AnimObject *_objectQueue;
+
+	int _brandonAnimSeqSizeWidth;
+	int _brandonAnimSeqSizeHeight;
 	
-	struct KyragemState {
-		uint16 nextOperation;
-		uint16 rOffset;
-		uint16 gOffset;
-		uint16 bOffset;
-		uint32 timerCount;
-	} _kyragemFadingState;
 };
 } // end of namespace Kyra
 

Modified: scummvm/trunk/kyra/gui.cpp
===================================================================
--- scummvm/trunk/kyra/gui.cpp	2006-02-11 08:25:20 UTC (rev 20492)
+++ scummvm/trunk/kyra/gui.cpp	2006-02-11 08:31:13 UTC (rev 20493)
@@ -128,7 +128,7 @@
 	}
 	if (!queryGameFlag(0x55+jewel)) {
 		assert(_blackJewel);
-		makeBrandonFaceMouse();
+		_animator->makeBrandonFaceMouse();
 		drawJewelPress(jewel, 1);
 		if (_features & GF_TALKIE) {
 			snd_voiceWaitForFinish();

Modified: scummvm/trunk/kyra/kyra.cpp
===================================================================
--- scummvm/trunk/kyra/kyra.cpp	2006-02-11 08:25:20 UTC (rev 20492)
+++ scummvm/trunk/kyra/kyra.cpp	2006-02-11 08:31:13 UTC (rev 20493)
@@ -409,7 +409,6 @@
 	_brandonStatusBit = 0;
 	_brandonStatusBit0x02Flag = _brandonStatusBit0x20Flag = 10;
 	_brandonPosX = _brandonPosY = -1;
-	_brandonDrawFrame = 113;
 	_deathHandler = 0xFF;
 	_poisonDeathCounter = 0;
 	
@@ -453,7 +452,10 @@
 	_lastDisplayedPanPage = 0;
 	memset(_panPagesTable, 0, sizeof(_panPagesTable));
 	_finalA = _finalB = _finalC = 0;
-	
+	memset(&_kyragemFadingState, 0, sizeof(_kyragemFadingState));	
+	_kyragemFadingState.gOffset = 0x13;
+	_kyragemFadingState.bOffset = 0x13;
+
 	memset(_specialPalettes, 0, sizeof(_specialPalettes));
 	_mousePressFlag = false;
 	
@@ -561,10 +563,10 @@
 	loadMouseShapes();
 	_currentCharacter = &_characterList[0];
 	for (int i = 1; i < 5; ++i)
-		setCharacterDefaultFrame(i);
+		_animator->setCharacterDefaultFrame(i);
 	for (int i = 5; i <= 10; ++i)
 		setCharactersPositions(i);
-	setCharactersHeight();
+	_animator->setCharactersHeight();
 	resetBrandonPoisonFlags();
 	_maskBuffer = _screen->getPagePtr(5);
 	_screen->_curPage = 0;
@@ -639,7 +641,7 @@
 		_skipFlag = false;
 
 		if (_currentCharacter->sceneId == 210) {
-			_animator->updateKyragemFading();
+			updateKyragemFading();
 			if (seq_playEnd()) {
 				if (_deathHandler != 8)
 					break;
@@ -655,11 +657,11 @@
 		
 		if (_brandonStatusBit & 2) {
 			if (_brandonStatusBit0x02Flag)
-				animRefreshNPC(0);
+				_animator->animRefreshNPC(0);
 		}
 		if (_brandonStatusBit & 0x20) {
 			if (_brandonStatusBit0x20Flag) {
-				animRefreshNPC(0);
+				_animator->animRefreshNPC(0);
 				_brandonStatusBit0x20Flag = 0;
 			}
 		}
@@ -758,7 +760,7 @@
 			_animator->updateAllObjectShapes();
 
 		if (_currentCharacter && _currentCharacter->sceneId == 210) {
-			_animator->updateKyragemFading();
+			updateKyragemFading();
 		}
 
 		if (amount > 0 && !_skipFlag) {
@@ -806,197 +808,16 @@
 		_sprites->updateSceneAnims();
 		_animator->updateAllObjectShapes();
 		if (_currentCharacter->sceneId == 210) {
-			_animator->updateKyragemFading();
+			updateKyragemFading();
 			seq_playEnd();
 		}
 	}
 }
 
-void KyraEngine::setCharacterDefaultFrame(int character) {
-	static uint16 initFrameTable[] = {
-		7, 41, 77, 0, 0
-	};
-	assert(character < ARRAYSIZE(initFrameTable));
-	Character *edit = &_characterList[character];
-	edit->sceneId = 0xFFFF;
-	edit->facing = 0;
-	edit->currentAnimFrame = initFrameTable[character];
-	// edit->unk6 = 1;
-}
-
-void KyraEngine::setCharactersHeight() {
-	static int8 initHeightTable[] = {
-		48, 40, 48, 47, 56,
-		44, 42, 47, 38, 35,
-		40
-	};
-	for (int i = 0; i < 11; ++i) {
-		_characterList[i].height = initHeightTable[i];
-	}
-}
-
-int KyraEngine::setGameFlag(int flag) {
-	_flagsTable[flag >> 3] |= (1 << (flag & 7));
-	return 1;
-}
-
-int KyraEngine::queryGameFlag(int flag) {
-	return ((_flagsTable[flag >> 3] >> (flag & 7)) & 1);
-}
-
-int KyraEngine::resetGameFlag(int flag) {
-	_flagsTable[flag >> 3] &= ~(1 << (flag & 7));
-	return 0;
-}
-
 #pragma mark -
 #pragma mark - Animation/shape specific code
 #pragma mark -
 
-void KyraEngine::animRefreshNPC(int character) {
-	debug(9, "KyraEngine::animRefreshNPC(%d)", character);
-	AnimObject *animObj = &_animator->actors()[character];
-	Character *ch = &_characterList[character];
-
-	animObj->refreshFlag = 1;
-	animObj->bkgdChangeFlag = 1;
-	int facing = ch->facing;
-	if (facing >= 1 && facing <= 3) {
-		animObj->flags |= 1;
-	} else if (facing >= 5 && facing <= 7) {
-		animObj->flags &= 0xFFFFFFFE;
-	}
-	
-	animObj->drawY = ch->y1;
-	animObj->sceneAnimPtr = _shapes[4+ch->currentAnimFrame];
-	animObj->animFrameNumber = ch->currentAnimFrame;
-	if (character == 0) {
-		if (_brandonStatusBit & 10) {
-			animObj->animFrameNumber = 88;
-			ch->currentAnimFrame = 88;
-		}
-		if (_brandonStatusBit & 2) {
-			animObj->animFrameNumber = _brandonDrawFrame;
-			ch->currentAnimFrame = _brandonDrawFrame;
-			animObj->sceneAnimPtr = _shapes[4+_brandonDrawFrame];
-			if (_brandonStatusBit0x02Flag) {
-				++_brandonDrawFrame;
-				if (_brandonDrawFrame >= 122)
-					_brandonDrawFrame = 113;
-					_brandonStatusBit0x02Flag = 0;
-			}
-		}
-	}
-	
-	int xOffset = _defaultShapeTable[ch->currentAnimFrame-7].xOffset;
-	int yOffset = _defaultShapeTable[ch->currentAnimFrame-7].yOffset;
-	
-	if (_scaleMode) {
-		animObj->x1 = ch->x1;
-		animObj->y1 = ch->y1;
-		
-		_brandonScaleX = _scaleTable[ch->y1];
-		_brandonScaleY = _scaleTable[ch->y1];
-
-		animObj->x1 += (_brandonScaleX * xOffset) >> 8;
-		animObj->y1 += (_brandonScaleY * yOffset) >> 8;
-	} else {
-		animObj->x1 = ch->x1 + xOffset;
-		animObj->y1 = ch->y1 + yOffset;
-	}
-	animObj->width2 = 4;
-	animObj->height2 = 3;
-
-	_animator->refreshObject(animObj);
-}
-
-void KyraEngine::drawJewelPress(int jewel, int drawSpecial) {
-	debug(9, "KyraEngine::drawJewelPress(%d, %d)", jewel, drawSpecial);
-	_screen->hideMouse();
-	int shape = 0;
-	if (drawSpecial) {
-		shape = 0x14E;
-	} else {
-		shape = jewel + 0x149;
-	}
-	snd_playSoundEffect(0x45);
-	_screen->drawShape(0, _shapes[4+shape], _amuletX2[jewel], _amuletY2[jewel], 0, 0);
-	_screen->updateScreen();
-	delayWithTicks(2);
-	if (drawSpecial) {
-		shape = 0x148;
-	} else {
-		shape = jewel + 0x143;
-	}
-	_screen->drawShape(0, _shapes[4+shape], _amuletX2[jewel], _amuletY2[jewel], 0, 0);
-	_screen->updateScreen();
-	_screen->showMouse();
-}
-
-void KyraEngine::drawJewelsFadeOutStart() {
-	debug(9, "KyraEngine::drawJewelsFadeOutStart()");
-	static const uint16 jewelTable1[] = { 0x164, 0x15F, 0x15A, 0x155, 0x150, 0xFFFF };
-	static const uint16 jewelTable2[] = { 0x163, 0x15E, 0x159, 0x154, 0x14F, 0xFFFF };
-	static const uint16 jewelTable3[] = { 0x166, 0x160, 0x15C, 0x157, 0x152, 0xFFFF };
-	static const uint16 jewelTable4[] = { 0x165, 0x161, 0x15B, 0x156, 0x151, 0xFFFF };
-	for (int i = 0; jewelTable1[i] != 0xFFFF; ++i) {
-		if (queryGameFlag(0x57)) {
-			_screen->drawShape(0, _shapes[4+jewelTable1[i]], _amuletX2[2], _amuletY2[2], 0, 0);
-		}
-		if (queryGameFlag(0x59)) {
-			_screen->drawShape(0, _shapes[4+jewelTable3[i]], _amuletX2[4], _amuletY2[4], 0, 0);
-		}
-		if (queryGameFlag(0x56)) {
-			_screen->drawShape(0, _shapes[4+jewelTable2[i]], _amuletX2[1], _amuletY2[1], 0, 0);
-		}
-		if (queryGameFlag(0x58)) {
-			_screen->drawShape(0, _shapes[4+jewelTable4[i]], _amuletX2[3], _amuletY2[3], 0, 0);
-		}
-		_screen->updateScreen();
-		delayWithTicks(3);
-	}
-}
-
-void KyraEngine::drawJewelsFadeOutEnd(int jewel) {
-	debug(9, "KyraEngine::drawJewelsFadeOutEnd(%d)", jewel);
-	static const uint16 jewelTable[] = { 0x153, 0x158, 0x15D, 0x162, 0x148, 0xFFFF };
-	int newDelay = 0;
-	switch (jewel-1) {
-		case 2:
-			if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) {
-				newDelay = 18900;
-			} else {
-				newDelay = 8100;
-			}
-			break;
-			
-		default:
-			newDelay = 3600;
-			break;
-	}
-	setGameFlag(0xF1);
-	setTimerCountdown(19, newDelay);
-	_screen->hideMouse();
-	for (int i = 0; jewelTable[i] != 0xFFFF; ++i) {
-		uint16 shape = jewelTable[i];
-		if (queryGameFlag(0x57)) {
-			_screen->drawShape(0, _shapes[4+shape], _amuletX2[2], _amuletY2[2], 0, 0);
-		}
-		if (queryGameFlag(0x59)) {
-			_screen->drawShape(0, _shapes[4+shape], _amuletX2[4], _amuletY2[4], 0, 0);
-		}
-		if (queryGameFlag(0x56)) {
-			_screen->drawShape(0, _shapes[4+shape], _amuletX2[1], _amuletY2[1], 0, 0);
-		}
-		if (queryGameFlag(0x58)) {
-			_screen->drawShape(0, _shapes[4+shape], _amuletX2[3], _amuletY2[3], 0, 0);
-		}
-		_screen->updateScreen();
-		delayWithTicks(3);
-	}
-	_screen->showMouse();
-}
-
 void KyraEngine::setupShapes123(const Shape *shapeTable, int endShape, int flags) {
 	debug(9, "KyraEngine::setupShapes123(0x%X, startShape, flags)", shapeTable, endShape, flags);
 	for (int i = 123; i <= 172; ++i) {
@@ -1033,23 +854,6 @@
 	}
 }
 
-void KyraEngine::setBrandonAnimSeqSize(int width, int height) {
-	debug(9, "KyraEngine::setBrandonAnimSeqSize(%d, %d)", width, height);
-	_animator->restoreAllObjectBackgrounds();
-	_brandonAnimSeqSizeWidth = _animator->actors()[0].width;
-	_brandonAnimSeqSizeHeight = _animator->actors()[0].height;
-	_animator->actors()[0].width = width + 1;
-	_animator->actors()[0].height = height;
-	_animator->preserveAllBackgrounds();
-}
-
-void KyraEngine::resetBrandonAnimSeqSize() {
-	_animator->restoreAllObjectBackgrounds();
-	_animator->actors()[0].width = _brandonAnimSeqSizeWidth;
-	_animator->actors()[0].height = _brandonAnimSeqSizeHeight;
-	_animator->preserveAllBackgrounds();
-}
-
 #pragma mark -
 #pragma mark - Misc stuff
 #pragma mark -
@@ -1059,29 +863,18 @@
 	return new WSAMovieV1(this);
 }
 
-int16 KyraEngine::fetchAnimWidth(const uint8 *shape, int16 mult) {
-	debug(9, "KyraEngine::fetchAnimWidth(0x%X, %d)", shape, mult);
-	if (_features & GF_TALKIE)
-		shape += 2;
-	return (((int16)READ_LE_UINT16((shape+3))) * mult) >> 8;
+int KyraEngine::setGameFlag(int flag) {
+	_flagsTable[flag >> 3] |= (1 << (flag & 7));
+	return 1;
 }
 
-int16 KyraEngine::fetchAnimHeight(const uint8 *shape, int16 mult) {
-	debug(9, "KyraEngine::fetchAnimHeight(0x%X, %d)", shape, mult);
-	if (_features & GF_TALKIE)
-		shape += 2;
-	return (int16)(((int8)*(shape+2)) * mult) >> 8;
+int KyraEngine::queryGameFlag(int flag) {
+	return ((_flagsTable[flag >> 3] >> (flag & 7)) & 1);
 }
 
-void KyraEngine::makeBrandonFaceMouse() {
-	debug(9, "KyraEngine::makeBrandonFaceMouse()");
-	if (_mouseX >= _currentCharacter->x1) {
-		_currentCharacter->facing = 3;
-	} else {
-		_currentCharacter->facing = 5;
-	}
-	animRefreshNPC(0);
-	_animator->updateAllObjectShapes();
+int KyraEngine::resetGameFlag(int flag) {
+	_flagsTable[flag >> 3] &= ~(1 << (flag & 7));
+	return 0;
 }
 
 void KyraEngine::setBrandonPoisonFlags(int reset) {
@@ -1107,494 +900,6 @@
 	}
 }
 
-void KyraEngine::setupPanPages() {
-	debug(9, "KyraEngine::setupPanPages()");
-	loadBitmap("bead.cps", 3, 3, 0);
-	for (int i = 0; i <= 19; ++i) {
-		_panPagesTable[i] = _seq->setPanPages(3, i);
-	}
-}
-
-void KyraEngine::freePanPages() {
-	debug(9, "KyraEngine::freePanPages()");
-	delete _endSequenceBackUpRect;
-	_endSequenceBackUpRect = 0;
-	for (int i = 0; i <= 19; ++i) {
-		free(_panPagesTable[i]);
-		_panPagesTable[i] = NULL;
-	}
-}
-
-void KyraEngine::closeFinalWsa() {
-	debug(9, "KyraEngine::closeFinalWsa()");
-	delete _finalA;
-	_finalA = 0;
-	delete _finalB;
-	_finalB = 0;
-	delete _finalC;
-	_finalC = 0;
-	freePanPages();
-	_endSequenceNeedLoading = 1;
-}
-
-int KyraEngine::handleMalcolmFlag() {
-	debug(9, "KyraEngine::handleMalcolmFlag()");
-	static uint16 frame = 0;
-	static uint32 timer1 = 0;
-	static uint32 timer2 = 0;
-	
-	switch (_malcolmFlag) {
-		case 1:
-			frame = 0;
-			_malcolmFlag = 2;
-			timer2 = 0;
-		case 2:
-			if (_system->getMillis() >= timer2) {
-				_finalA->_x = 8;
-				_finalA->_y = 46;
-				_finalA->_drawPage = 0;
-				_finalA->displayFrame(frame);
-				_screen->updateScreen();
-				timer2 = _system->getMillis() + 8 * _tickLength;
-				++frame;
-				if (frame > 13) {
-					_malcolmFlag = 3;
-					timer1 = _system->getMillis() + 180 * _tickLength;
-				}
-			}
-			break;
-		
-		case 3:
-			if (_system->getMillis() < timer1) {
-				if (_system->getMillis() >= timer2) {
-					frame = _rnd.getRandomNumberRng(14, 17);
-					_finalA->_x = 8;
-					_finalA->_y = 46;
-					_finalA->_drawPage = 0;
-					_finalA->displayFrame(frame);
-					_screen->updateScreen();
-					timer2 = _system->getMillis() + 8 * _tickLength;
-				}
-			} else {
-				_malcolmFlag = 4;
-				frame = 18;
-			}
-			break;
-		
-		case 4:
-			if (_system->getMillis() >= timer2) {
-				_finalA->_x = 8;
-				_finalA->_y = 46;
-				_finalA->_drawPage = 0;
-				_finalA->displayFrame(frame);
-				_screen->updateScreen();
-				timer2 = _system->getMillis() + 8 * _tickLength;
-				++frame;
-				if (frame > 25) {
-					frame = 26;
-					_malcolmFlag = 5;
-					_beadStateVar = 1;
-				}
-			}
-			break;
-		
-		case 5:
-			if (_system->getMillis() >= timer2) {
-				_finalA->_x = 8;
-				_finalA->_y = 46;
-				_finalA->_drawPage = 0;
-				_finalA->displayFrame(frame);
-				_screen->updateScreen();
-				timer2 = _system->getMillis() + 8 * _tickLength;
-				++frame;
-				if (frame > 31) {
-					frame = 32;
-					_malcolmFlag = 6;
-				}
-			}
-			break;
-			
-		case 6:
-			if (_unkEndSeqVar4) {
-				if (frame <= 33 && _system->getMillis() >= timer2) {
-					_finalA->_x = 8;
-					_finalA->_y = 46;
-					_finalA->_drawPage = 0;
-					_finalA->displayFrame(frame);
-					_screen->updateScreen();
-					timer2 = _system->getMillis() + 8 * _tickLength;
-					++frame;
-					if (frame > 33) {
-						_malcolmFlag = 7;
-						frame = 32;
-						_unkEndSeqVar5 = 0;
-					}
-				}
-			}
-			break;
-		
-		case 7:
-			if (_unkEndSeqVar5 == 1) {
-				_malcolmFlag = 8;
-				frame = 34;
-			} else if (_unkEndSeqVar5 == 2) {
-				_malcolmFlag = 3;
-				timer1 = _system->getMillis() + 180 * _tickLength;
-			}
-			break;
-		
-		case 8:
-			if (_system->getMillis() >= timer2) {
-				_finalA->_x = 8;
-				_finalA->_y = 46;
-				_finalA->_drawPage = 0;
-				_finalA->displayFrame(frame);
-				_screen->updateScreen();
-				timer2 = _system->getMillis() + 8 * _tickLength;
-				++frame;
-				if (frame > 37) {
-					_malcolmFlag = 0;
-					_deathHandler = 8;
-					return 1;
-				}
-			}
-			break;
-		
-		case 9:
-			snd_playSoundEffect(12);
-			snd_playSoundEffect(12);
-			_finalC->_x = 16;
-			_finalC->_y = 50;
-			_finalC->_drawPage = 0;
-			for (int i = 0; i < 18; ++i) {
-				timer2 = _system->getMillis() + 4 * _tickLength;
-				_finalC->displayFrame(i);
-				_screen->updateScreen();
-				while (_system->getMillis() < timer2) {}
-			}
-			snd_playWanderScoreViaMap(51, 1);
-			delay(60*_tickLength);
-			_malcolmFlag = 0;
-			return 1;
-			break;
-		
-		case 10:
-			if (!_beadStateVar) {
-				handleBeadState();
-				_screen->bitBlitRects();
-				assert(_veryClever);
-				_text->printTalkTextMessage(_veryClever[0], 60, 31, 5, 0, 2);
-				timer2 = _system->getMillis() + 180 * _tickLength;
-				_malcolmFlag = 11;
-			}
-			break;
-		
-		case 11:
-			if (_system->getMillis() >= timer2) {
-				_text->restoreTalkTextMessageBkgd(2, 0);
-				_malcolmFlag = 3;
-				timer1 = _system->getMillis() + 180 * _tickLength;
-			}
-			break;
-		
-		default:
-			break;
-	}
-	
-	return 0;
-}
-
-int KyraEngine::handleBeadState() {
-	debug(9, "KyraEngine::handleBeadState()");
-	static uint32 timer1 = 0;
-	static uint32 timer2 = 0;
-	static BeadState beadState1 = { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-	static BeadState beadState2 = {  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-	
-	static const int table1[] = {
-		-1, -2, -4, -5, -6, -7, -6, -5,
-		-4, -2, -1,  0,  1,  2,  4,  5,
-		 6,  7,  6,  5,  4,  2,  1,  0, 0
-	};
-	static const int table2[] = {
-		0, 0, 1, 1, 2, 2, 3, 3,
-		4, 4, 5, 5, 5, 5, 4, 4,
-		3, 3, 2, 2, 1, 1, 0, 0,
-		0, 0, 0, 0, 0, 0, 0, 0,
-		0, 0, 0, 0, 0, 0, 0, 0,
-		0, 0, 0, 0, 0, 0, 0, 0, 0
-	};
-	
-	switch (_beadStateVar) {
-		case 0:
-			if (beadState1.x != -1 && _endSequenceBackUpRect) {
-				_screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
-				_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
-			} else {
-				beadState1.x = -1;
-				beadState1.tableIndex = 0;
-				timer1 = 0;
-				timer2 = 0;
-				_lastDisplayedPanPage = 0;
-				return 1;
-			}
-		
-		case 1:
-			if (beadState1.x != -1) {
-				if (_endSequenceBackUpRect) {
-					_screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
-					_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
-				}
-				beadState1.x = -1;
-				beadState1.tableIndex = 0;
-			}
-			_beadStateVar = 2;
-			break;
-		
-		case 2:
-			if (_system->getMillis() >= timer1) {
-				int x = 0, y = 0;
-				timer1 = _system->getMillis() + 4 * _tickLength;
-				if (beadState1.x == -1) {
-					assert(_panPagesTable);
-					beadState1.width2 = fetchAnimWidth(_panPagesTable[19], 256);
-					beadState1.width = ((beadState1.width2 + 7) >> 3) + 1;
-					beadState1.height = fetchAnimHeight(_panPagesTable[19], 256);
-					if (!_endSequenceBackUpRect) {
-						_endSequenceBackUpRect = new uint8[(beadState1.width * beadState1.height) << 3];
-						assert(_endSequenceBackUpRect);
-						memset(_endSequenceBackUpRect, 0, ((beadState1.width * beadState1.height) << 3) * sizeof(uint8));
-					}
-					x = beadState1.x = 60;
-					y = beadState1.y = 40;
-					initBeadState(x, y, x, 25, 8, &beadState2);
-				} else {
-					if (processBead(beadState1.x, beadState1.y, x, y, &beadState2)) {
-						_beadStateVar = 3;
-						timer2 = _system->getMillis() + 240 * _tickLength;
-						_unkEndSeqVar4 = 0;
-						beadState1.dstX = beadState1.x;
-						beadState1.dstY = beadState1.y;
-						return 0;
-					} else {
-						_screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
-						_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
-						beadState1.x = x;
-						beadState1.y = y;
-					}
-				}
-				_screen->copyCurPageBlock(x >> 3, y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
-				_screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], x, y, 0, 0);
-				if (_lastDisplayedPanPage > 17)
-					_lastDisplayedPanPage = 0;
-				_screen->addBitBlitRect(x, y, beadState1.width2, beadState1.height);
-			}
-			break;
-		
-		case 3:
-			if (_system->getMillis() >= timer1) {
-				timer1 = _system->getMillis() + 4 * _tickLength;
-				_screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
-				_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
-				beadState1.x = beadState1.dstX + table1[beadState1.tableIndex];
-				beadState1.y = beadState1.dstY + table2[beadState1.tableIndex];
-				_screen->copyCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
-				_screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], beadState1.x, beadState1.y, 0, 0);
-				if (_lastDisplayedPanPage >= 17) {
-					_lastDisplayedPanPage = 0;
-				}
-				_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
-				++beadState1.tableIndex;
-				if (beadState1.tableIndex > 24) {
-					beadState1.tableIndex = 0;
-					_unkEndSeqVar4 = 1;
-				}
-				if (_system->getMillis() > timer2 && _malcolmFlag == 7 && !_unkAmuletVar && !_text->printed()) {
-					snd_playSoundEffect(0x0B);
-					if (_currentCharacter->x1 > 233 && _currentCharacter->x1 < 305 && _currentCharacter->y1 > 85 && _currentCharacter->y1 < 105 &&
-						(_brandonStatusBit & 0x20)) {
-						beadState1.unk8 = 290;
-						beadState1.unk9 = 40;
-						_beadStateVar = 5;
-					} else {
-						_beadStateVar = 4;
-						beadState1.unk8 = _currentCharacter->x1 - 4;
-						beadState1.unk9 = _currentCharacter->y1 - 30;
-					}
-					
-					if (_text->printed()) {
-						_text->restoreTalkTextMessageBkgd(2, 0);
-					}
-					initBeadState(beadState1.x, beadState1.y, beadState1.unk8, beadState1.unk9, 6, &beadState2);
-					_lastDisplayedPanPage = 18;
-				}
-			}
-			break;
-			
-		case 4:
-			if (_system->getMillis() >= timer1) {
-				int x = 0, y = 0;
-				timer1 = _system->getMillis();
-				if (processBead(beadState1.x, beadState1.y, x, y, &beadState2)) {
-					if (_brandonStatusBit & 20) {
-						_unkEndSeqVar5 = 2;
-						_beadStateVar = 6;
-					} else {
-						snd_playWanderScoreViaMap(52, 1);
-						snd_playSoundEffect(0x0C);
-						_unkEndSeqVar5 = 1;
-						_beadStateVar = 0;
-					}
-				} else {
-					_screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
-					_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
-					beadState1.x = x;
-					beadState1.y = y;
-					_screen->copyCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
-					_screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], x, y, 0, 0);
-					if (_lastDisplayedPanPage > 17) {
-						_lastDisplayedPanPage = 0;
-					}
-					_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
-				}
-			}
-			break;
-		
-		case 5:
-			if (_system->getMillis() >= timer1) {
-				timer1 = _system->getMillis();
-				int x = 0, y = 0;
-				if (processBead(beadState1.x, beadState1.y, x, y, &beadState2)) {
-					if (beadState1.dstX == 290) {
-						_screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
-						uint32 nextRun = 0;
-						_finalB->_x = 224;
-						_finalB->_y = 8;
-						_finalB->_drawPage = 0;
-						for (int i = 0; i < 8; ++i) {
-							nextRun = _system->getMillis() + _tickLength;
-							_finalB->displayFrame(i);
-							_screen->updateScreen();
-							while (_system->getMillis() < nextRun) {}
-						}
-						snd_playSoundEffect(0x0D);
-						for (int i = 7; i >= 0; --i) {
-							nextRun = _system->getMillis() + _tickLength;
-							_finalB->displayFrame(i);
-							_screen->updateScreen();
-							while (_system->getMillis() < nextRun) {}
-						}
-						initBeadState(beadState1.x, beadState1.y, 63, 60, 6, &beadState2);
-					} else {
-						_screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
-						_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
-						beadState1.x = -1;
-						beadState1.tableIndex = 0;
-						_beadStateVar = 0;
-						_malcolmFlag = 9;
-					}
-				} else {
-					_screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
-					_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
-					beadState1.x = x;
-					beadState1.y = y;
-					_screen->copyCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
-					_screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], x, y, 0, 0);
-					if (_lastDisplayedPanPage > 17) {
-						_lastDisplayedPanPage = 0;
-					}
-					_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
-				}
-			}
-			break;
-		
-		case 6:
-			_screen->drawShape(2, _panPagesTable[19], beadState1.x, beadState1.y, 0, 0);
-			_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
-			_beadStateVar = 0;
-			break;
-		
-		default:
-			break;
-	}
-	return 0;
-}
-
-void KyraEngine::initBeadState(int x, int y, int x2, int y2, int unk, BeadState *ptr) {
-	debug(9, "KyraEngine::initBeadState(%d, %d, %d, %d, %d, 0x%X)", x, y, x2, y2, unk, ptr);
-	ptr->unk9 = unk;
-	int xDiff = x2 - x;
-	int yDiff = y2 - y;
-	int unk1 = 0, unk2 = 0;
-	if (xDiff > 0) {
-		unk1 = 1;
-	} else if (xDiff == 0) {
-		unk1 = 0;
-	} else {
-		unk1 = -1;
-	}
-	
-	if (yDiff > 0) {
-		unk2 = 1;
-	} else if (yDiff == 0) {
-		unk2 = 0;
-	} else {
-		unk2 = -1;
-	}
-	
-	xDiff = abs(xDiff);
-	yDiff = abs(yDiff);
-	
-	ptr->y = 0;
-	ptr->x = 0;
-	ptr->width = xDiff;
-	ptr->height = yDiff;
-	ptr->dstX = x2;
-	ptr->dstY = y2;
-	ptr->width2 = unk1;
-	ptr->unk8 = unk2;
-}
-
-int KyraEngine::processBead(int x, int y, int &x2, int &y2, BeadState *ptr) {
-	debug(9, "KyraEngine::processBead(%d, %d, 0x%X, 0x%X, 0x%X)", x, y, &x2, &y2, ptr);
-	if (x == ptr->dstX && y == ptr->dstY) {
-		return 1;
-	}
-	
-	int xPos = x, yPos = y;
-	if (ptr->width >= ptr->height) {
-		for (int i = 0; i < ptr->unk9; ++i) {
-			ptr->y += ptr->height;
-			if (ptr->y >= ptr->width) {
-				ptr->y -= ptr->width;
-				yPos += ptr->unk8;
-			}
-			xPos += ptr->width2;
-		}
-	} else {
-		for (int i = 0; i < ptr->unk9; ++i) {
-			ptr->x += ptr->width;
-			if (ptr->x >= ptr->height) {
-				ptr->x -= ptr->height;
-				xPos += ptr->width2;
-			}
-			yPos += ptr->unk8;
-		}
-	}
-	
-	int temp = abs(x - ptr->dstX);
-	if (ptr->unk9 > temp) {
-		xPos = ptr->dstX;
-	}
-	temp = abs(y - ptr->dstY);
-	if (ptr->unk9 > temp) {
-		yPos = ptr->dstY;
-	}
-	x2 = xPos;
-	y2 = yPos;
-	return 0;
-}
-
 #pragma mark -
 #pragma mark - Input
 #pragma mark -

Modified: scummvm/trunk/kyra/kyra.h
===================================================================
--- scummvm/trunk/kyra/kyra.h	2006-02-11 08:25:20 UTC (rev 20492)
+++ scummvm/trunk/kyra/kyra.h	2006-02-11 08:31:13 UTC (rev 20493)
@@ -248,13 +248,14 @@
 	uint32 features() const { return _features; }
 
 	uint8 **shapes() { return _shapes; }
-	
+	Character *currentCharacter() { return _currentCharacter; }
+	Character *characterList() { return _characterList; }
+	uint16 brandonStatus() { return _brandonStatusBit; }
+
+	int _paletteChanged;
 	Common::RandomSource _rnd;
 	int16 _northExitHeight;
 
-	Character *_currentCharacter;
-	int _paletteChanged;
-
 	typedef void (KyraEngine::*IntroProc)();
 	typedef int (KyraEngine::*OpcodeProc)(ScriptState *script);
 
@@ -291,9 +292,6 @@
 
 	void waitTicks(int ticks);
 	void delayWithTicks(int ticks);
-	void animRefreshNPC(int character);
-	int16 fetchAnimWidth(const uint8 *shape, int16 mult);
-	int16 fetchAnimHeight(const uint8 *shape, int16 mult);
 	
 	void saveGame(const char *fileName, const char *saveName);
 	void loadGame(const char *fileName);
@@ -475,9 +473,7 @@
 	void waitForChatToFinish(int16 chatDuration, char *str, uint8 charNum);
 	void characterSays(char *chatStr, int8 charNum, int8 chatDuration);
 
-	void setCharacterDefaultFrame(int character);
 	void setCharactersPositions(int character);
-	void setCharactersHeight();
 	int setGameFlag(int flag);
 	int queryGameFlag(int flag);
 	int resetGameFlag(int flag);
@@ -515,7 +511,6 @@
 	void destroyMouseItem();
 	void setMouseItem(int item);
 	void wipeDownMouseItem(int xpos, int ypos);
-	void makeBrandonFaceMouse();
 	void setBrandonPoisonFlags(int reset);
 	void resetBrandonPoisonFlags();
 
@@ -551,8 +546,6 @@
 	void drawJewelsFadeOutEnd(int jewel);
 	void setupShapes123(const Shape *shapeTable, int endShape, int flags);
 	void freeShapes123();
-	void setBrandonAnimSeqSize(int width, int height);
-	void resetBrandonAnimSeqSize();
 
 	void seq_demo();
 	void seq_intro();
@@ -580,6 +573,7 @@
 	void seq_brandonToStone();
 	void seq_playEnding();
 	void seq_playCredits();
+	void updateKyragemFading();
 	
 	void snd_setSoundEffectFile(int file);
 	
@@ -698,10 +692,7 @@
 	int _unkScreenVar1, _unkScreenVar2, _unkScreenVar3;
 	int _beadStateVar;
 	int _unkAmuletVar;
-	
-	int _brandonAnimSeqSizeWidth;
-	int _brandonAnimSeqSizeHeight;
-	
+		
 	int _malcolmFlag;
 	int _endSequenceSkipFlag;
 	int _endSequenceNeedLoading;
@@ -744,9 +735,6 @@
 	uint8 _poisonDeathCounter;
 	int _brandonPosX;
 	int _brandonPosY;
-	int _brandonScaleX;
-	int _brandonScaleY;
-	uint16 _brandonDrawFrame;
 
 	uint16 _currentChatPartnerBackupFrame;
 	uint16 _currentCharAnimFrame;
@@ -808,6 +796,7 @@
 	ScriptData *_scriptClickData;
 	
 	Character *_characterList;
+	Character *_currentCharacter;
 	
 	Button *_buttonList;
 	Button *_menuButtonList;
@@ -821,6 +810,14 @@
 	const char *_specialSavegameString;
 	KeyboardEvent _keyboardEvent;
 
+	struct KyragemState {
+		uint16 nextOperation;
+		uint16 rOffset;
+		uint16 gOffset;
+		uint16 bOffset;
+		uint32 timerCount;
+	} _kyragemFadingState;
+
 	uint8 *_seq_Forest;
 	uint8 *_seq_KallakWriting;
 	uint8 *_seq_KyrandiaLogo;

Modified: scummvm/trunk/kyra/saveload.cpp
===================================================================
--- scummvm/trunk/kyra/saveload.cpp	2006-02-11 08:25:20 UTC (rev 20492)
+++ scummvm/trunk/kyra/saveload.cpp	2006-02-11 08:31:13 UTC (rev 20493)
@@ -128,7 +128,7 @@
 	in->read(_brandonPoisonFlagsGFX, 256);
 	_brandonInvFlag = in->readSint16BE();
 	_poisonDeathCounter = in->readByte();
-	_brandonDrawFrame = in->readUint16BE();
+	_animator->_brandonDrawFrame = in->readUint16BE();
 
 	for (int i = 0; i < 32; i++) {
 		_timers[i].active = in->readByte();
@@ -193,14 +193,14 @@
 	}
 	
 	createMouseItem(_itemInHand);
-	setBrandonAnimSeqSize(5, 48);
+	_animator->setBrandonAnimSeqSize(5, 48);
 	_animator->_noDrawShapesFlag = 1;
 	enterNewScene(_currentCharacter->sceneId, _currentCharacter->facing, 0, 0, 1);
 	_animator->_noDrawShapesFlag = 0;
 	
 	_currentCharacter->x1 = brandonX;
 	_currentCharacter->y1 = brandonY;
-	animRefreshNPC(0);
+	_animator->animRefreshNPC(0);
 	_animator->restoreAllObjectBackgrounds();
 	_animator->preserveAnyChangedBackgrounds();
 	_animator->prepDrawAllObjects();
@@ -276,7 +276,7 @@
 	out->write(_brandonPoisonFlagsGFX, 256);
 	out->writeSint16BE(_brandonInvFlag);
 	out->writeByte(_poisonDeathCounter);
-	out->writeUint16BE(_brandonDrawFrame);
+	out->writeUint16BE(_animator->_brandonDrawFrame);
 
 	for (int i = 0; i < 32; i++) {
 		out->writeByte(_timers[i].active);

Modified: scummvm/trunk/kyra/scene.cpp
===================================================================
--- scummvm/trunk/kyra/scene.cpp	2006-02-11 08:25:20 UTC (rev 20492)
+++ scummvm/trunk/kyra/scene.cpp	2006-02-11 08:31:13 UTC (rev 20493)
@@ -297,7 +297,7 @@
 	updateTextFade();
 
 	if (_currentCharacter->sceneId == 210) {
-		_animator->updateKyragemFading();
+		updateKyragemFading();
 	}
 }
 
@@ -411,7 +411,7 @@
 			ch->currentAnimFrame = 88;
 	}
 	
-	animRefreshNPC(character);
+	_animator->animRefreshNPC(character);
 }
 
 int KyraEngine::getOppositeFacingDirection(int dir) {
@@ -694,11 +694,11 @@
 		curAnimState->x1 = _currentCharacter->x1;
 		curAnimState->y1 = _currentCharacter->y1;
 		
-		_brandonScaleX = _scaleTable[_currentCharacter->y1];
-		_brandonScaleY = _scaleTable[_currentCharacter->y1];
+		_animator->_brandonScaleX = _scaleTable[_currentCharacter->y1];
+		_animator->_brandonScaleY = _scaleTable[_currentCharacter->y1];
 		
-		curAnimState->x1 += (_brandonScaleX * xOffset) >> 8;
-		curAnimState->y1 += (_brandonScaleY * yOffset) >> 8;
+		curAnimState->x1 += (_animator->_brandonScaleX * xOffset) >> 8;
+		curAnimState->y1 += (_animator->_brandonScaleY * yOffset) >> 8;
 	} else {
 		curAnimState->x1 = _currentCharacter->x1 + xOffset;
 		curAnimState->y1 = _currentCharacter->y1 + yOffset;
@@ -734,11 +734,11 @@
 			curAnimState->x1 = ch->x1;
 			curAnimState->y1 = ch->y1;
 		
-			_brandonScaleX = _scaleTable[ch->y1];
-			_brandonScaleY = _scaleTable[ch->y1];
+			_animator->_brandonScaleX = _scaleTable[ch->y1];
+			_animator->_brandonScaleY = _scaleTable[ch->y1];
 		
-			curAnimState->x1 += (_brandonScaleX * xOffset) >> 8;
-			curAnimState->y1 += (_brandonScaleY * yOffset) >> 8;
+			curAnimState->x1 += (_animator->_brandonScaleX * xOffset) >> 8;
+			curAnimState->y1 += (_animator->_brandonScaleY * yOffset) >> 8;
 		} else {
 			curAnimState->x1 = ch->x1 + xOffset;
 			curAnimState->y1 = ch->y1 + yOffset;
@@ -809,8 +809,8 @@
 			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->x1 -= (_animator->fetchAnimWidth(curAnimState->sceneAnimPtr, _scaleTable[curAnimState->drawY])) >> 1;
+			curAnimState->y1 -= _animator->fetchAnimHeight(curAnimState->sceneAnimPtr, _scaleTable[curAnimState->drawY]);
 			
 			curAnimState->x2 = curAnimState->x1;
 			curAnimState->y2 = curAnimState->y1;
@@ -953,7 +953,7 @@
 		if (_abortWalkFlag) {
 			*table = 8;
 			_currentCharacter->currentAnimFrame = 7;
-			animRefreshNPC(0);
+			_animator->animRefreshNPC(0);
 			_animator->updateAllObjectShapes();
 			processInput(_mouseX, _mouseY);
 			return 0;
@@ -1012,7 +1012,7 @@
 			_animator->updateAllObjectShapes();
 			updateTextFade();
 			if (_currentCharacter->sceneId == 210) {
-				_animator->updateKyragemFading();
+				updateKyragemFading();
 				if (seq_playEnd() || _beadStateVar == 4 || _beadStateVar == 5) {
 					*table = 8;
 					running = false;
@@ -1027,7 +1027,7 @@
 	if (frameReset && !(_brandonStatusBit & 2)) {
 		_currentCharacter->currentAnimFrame = 7;
 	}
-	animRefreshNPC(0);
+	_animator->animRefreshNPC(0);
 	_animator->updateAllObjectShapes();
 	return returnValue;
 }
@@ -1089,7 +1089,7 @@
 			}
 			
 			_currentCharacter->facing = facing;
-			animRefreshNPC(0);
+			_animator->animRefreshNPC(0);
 			_animator->updateAllObjectShapes();
 			enterNewScene(sceneId, facing, unk1, unk2, 0);
 			resetGameFlag(0xEE);

Modified: scummvm/trunk/kyra/script_v1.cpp
===================================================================
--- scummvm/trunk/kyra/script_v1.cpp	2006-02-11 08:25:20 UTC (rev 20492)
+++ scummvm/trunk/kyra/script_v1.cpp	2006-02-11 08:31:13 UTC (rev 20493)
@@ -555,11 +555,11 @@
 	if (changeScaleMode) {
 		curAnim->x1 = _currentCharacter->x1;
 		curAnim->y1 = _currentCharacter->y1;
-		_brandonScaleY = _scaleTable[_currentCharacter->y1];
-		_brandonScaleX = _brandonScaleY;
+		_animator->_brandonScaleY = _scaleTable[_currentCharacter->y1];
+		_animator->_brandonScaleX = _animator->_brandonScaleY;
 		
-		int animWidth = fetchAnimWidth(curAnim->sceneAnimPtr, _brandonScaleX) >> 1;
-		int animHeight = fetchAnimHeight(curAnim->sceneAnimPtr, _brandonScaleY);
+		int animWidth = _animator->fetchAnimWidth(curAnim->sceneAnimPtr, _animator->_brandonScaleX) >> 1;
+		int animHeight = _animator->fetchAnimHeight(curAnim->sceneAnimPtr, _animator->_brandonScaleY);
 		
 		animWidth = (xOffset * animWidth) /  width;
 		animHeight = (yOffset * animHeight) / height;
@@ -576,7 +576,7 @@
 		_scaleMode = 1;
 	}
 	
-	animRefreshNPC(0);
+	_animator->animRefreshNPC(0);
 	_animator->preserveAllBackgrounds();
 	_animator->prepDrawAllObjects();
 	_animator->copyChangedObjectsForward(0);
@@ -662,7 +662,7 @@
 		_characterList[character].currentAnimFrame = newAnimFrame;
 	}
 	_characterList[character].facing = facing;
-	animRefreshNPC(character);
+	_animator->animRefreshNPC(character);
 	_animator->preserveAllBackgrounds();
 	_animator->prepDrawAllObjects();
 	_animator->copyChangedObjectsForward(0);
@@ -795,7 +795,7 @@
 	if (newFacing != -1) {
 		_characterList[character].facing = newFacing;
 	}
-	animRefreshNPC(character);
+	_animator->animRefreshNPC(character);
 	if (updateShapes) {
 		_animator->updateAllObjectShapes();
 	}
@@ -1543,7 +1543,7 @@
 	int scaleEnd = scale >> 1;
 	for (; scaleEnd <= scale; --scale) {
 		_scaleTable[_currentCharacter->y1] = scale;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(1);
 	}
 	delayWithTicks(delayTime); // XXX
@@ -1565,7 +1565,7 @@
 	_scaleMode = 1;
 	for (int curScale = scale >> 1; curScale <= scale; ++curScale) {
 		_scaleTable[_currentCharacter->y1] = curScale;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(1);
 	}
 	_scaleTable[_currentCharacter->y1] = scaleValue;
@@ -1575,8 +1575,8 @@
 
 int KyraEngine::cmd_setBrandonScaleXAndY(ScriptState *script) {
 	debug(3, "cmd_setBrandonScaleXAndY(0x%X) (%d, %d)", script, stackPos(0), stackPos(1));
-	_brandonScaleX = stackPos(0);
-	_brandonScaleY = stackPos(1);
+	_animator->_brandonScaleX = stackPos(0);
+	_animator->_brandonScaleY = stackPos(1);
 	return 0;
 }
 

Modified: scummvm/trunk/kyra/sequences.cpp
===================================================================
--- scummvm/trunk/kyra/sequences.cpp	2006-02-11 08:25:20 UTC (rev 20492)
+++ scummvm/trunk/kyra/sequences.cpp	2006-02-11 08:31:13 UTC (rev 20493)
@@ -297,21 +297,21 @@
 	checkAmuletAnimFlags();
 	assert(_healingShapeTable);
 	setupShapes123(_healingShapeTable, 22, 0);
-	setBrandonAnimSeqSize(3, 48);
+	_animator->setBrandonAnimSeqSize(3, 48);
 	snd_playSoundEffect(0x53);
 	for (int i = 123; i <= 144; ++i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(8);
 	}
 	for (int i = 125; i >= 123; --i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(8);
 	}
-	resetBrandonAnimSeqSize();
+	_animator->resetBrandonAnimSeqSize();
 	_currentCharacter->currentAnimFrame = 7;
-	animRefreshNPC(0);
+	_animator->animRefreshNPC(0);
 	freeShapes123();
 	_screen->showMouse();
 }
@@ -323,16 +323,16 @@
 	assert(_healingShape2Table);
 	setupShapes123(_healingShape2Table, 30, 0);
 	resetBrandonPoisonFlags();
-	setBrandonAnimSeqSize(3, 48);
+	_animator->setBrandonAnimSeqSize(3, 48);
 	snd_playSoundEffect(0x50);
 	for (int i = 123; i <= 152; ++i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(8);
 	}
-	resetBrandonAnimSeqSize();
+	_animator->resetBrandonAnimSeqSize();
 	_currentCharacter->currentAnimFrame = 7;
-	animRefreshNPC(0);
+	_animator->animRefreshNPC(0);
 	freeShapes123();
 	_screen->showMouse();
 	assert(_poisonGone);
@@ -391,19 +391,19 @@
 	checkAmuletAnimFlags();
 	assert(_posionDeathShapeTable);
 	setupShapes123(_posionDeathShapeTable, 20, 0);
-	setBrandonAnimSeqSize(8, 48);
+	_animator->setBrandonAnimSeqSize(8, 48);
 	
 	_currentCharacter->currentAnimFrame = 124;
-	animRefreshNPC(0);
+	_animator->animRefreshNPC(0);
 	delayWithTicks(30);
 	
 	_currentCharacter->currentAnimFrame = 123;
-	animRefreshNPC(0);
+	_animator->animRefreshNPC(0);
 	delayWithTicks(30);
 	
 	for (int i = 125; i <= 139; ++i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(8);
 	}
 	
@@ -411,13 +411,13 @@
 	
 	for (int i = 140; i <= 142; ++i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(8);
 	}
 	
 	delayWithTicks(60);
 	
-	resetBrandonAnimSeqSize();
+	_animator->resetBrandonAnimSeqSize();
 	freeShapes123();
 	_animator->restoreAllObjectBackgrounds();
 	_currentCharacter->x1 = _currentCharacter->x2 = -1;
@@ -431,10 +431,10 @@
 	_screen->hideMouse();
 	checkAmuletAnimFlags();
 	setupShapes123(_fluteAnimShapeTable, 36, 0);
-	setBrandonAnimSeqSize(3, 75);
+	_animator->setBrandonAnimSeqSize(3, 75);
 	for (int i = 123; i <= 130; ++i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(2);
 	}
 	
@@ -456,18 +456,18 @@
 	
 	for (int i = 131; i <= 158; ++i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(delayTime);
 	}
 	
 	for (int i = 126; i >= 123; --i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(delayTime);
 	}
-	resetBrandonAnimSeqSize();
+	_animator->resetBrandonAnimSeqSize();
 	_currentCharacter->currentAnimFrame = 7;
-	animRefreshNPC(0);
+	_animator->animRefreshNPC(0);
 	freeShapes123();
 	_screen->showMouse();
 	
@@ -496,31 +496,29 @@
 	assert(_winterScroll1Table);
 	assert(_winterScroll2Table);
 	setupShapes123(_winterScrollTable, 7, 0);
-	setBrandonAnimSeqSize(5, 66);
+	_animator->setBrandonAnimSeqSize(5, 66);
 	
 	for (int i = 123; i <= 129; ++i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(8);
 	}
 	
 	freeShapes123();
 	snd_playSoundEffect(0x20);
 
-	uint8 endEncode, midpoint, endpoint;
+	uint8 numFrames, midpoint;
 	if (_features & GF_TALKIE) {
-		endEncode = 18;
-		midpoint = 135;
-		endpoint = 140;
+		numFrames = 18;
+		midpoint = 136;
 	} else {
-		endEncode = 35;
-		midpoint = 146;
-		endpoint = 157;
+		numFrames = 35;
+		midpoint = 147;
 	}
-	setupShapes123(_winterScroll1Table, endEncode, 0);
-	for (int i = 123; i <= midpoint; ++i) {
+	setupShapes123(_winterScroll1Table, numFrames, 0);
+	for (int i = 123; i < midpoint; ++i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(8);
 	}
 	
@@ -533,9 +531,9 @@
 		setGameFlag(0xA2);
 	}
 	
-	for (int i = midpoint+1; i <= endpoint; ++i) {
+	for (int i = midpoint; i < 123 + numFrames; ++i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(8);
 	}
 	
@@ -560,13 +558,13 @@
 	
 	for (int i = 123; i <= 126; ++i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(8);
 	}
 	
-	resetBrandonAnimSeqSize();
+	_animator->resetBrandonAnimSeqSize();
 	_currentCharacter->currentAnimFrame = 7;
-	animRefreshNPC(0);
+	_animator->animRefreshNPC(0);
 	freeShapes123();
 	_screen->showMouse();
 }
@@ -577,11 +575,11 @@
 	checkAmuletAnimFlags();
 	assert(_winterScrollTable);
 	setupShapes123(_winterScrollTable, 7, 0);
-	setBrandonAnimSeqSize(5, 66);
+	_animator->setBrandonAnimSeqSize(5, 66);
 	
 	for (int i = 123; i <= 128; ++i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(8);
 	}
 	
@@ -589,13 +587,13 @@
 	
 	for (int i = 127; i >= 123; --i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(8);
 	}
 	
-	resetBrandonAnimSeqSize();
+	_animator->resetBrandonAnimSeqSize();
 	_currentCharacter->currentAnimFrame = 7;
-	animRefreshNPC(0);
+	_animator->animRefreshNPC(0);
 	freeShapes123();
 	_screen->showMouse();
 }
@@ -618,7 +616,7 @@
 	snd_playSoundEffect(0x77);
 	_brandonInvFlag = 0;
 	while (_brandonInvFlag <= 0x100) {
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(10);
 		_brandonInvFlag += 0x10;
 	}
@@ -633,7 +631,7 @@
 	snd_playSoundEffect(0x77);
 	_brandonInvFlag = 0x100;
 	while (_brandonInvFlag >= 0) {
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(10);
 		_brandonInvFlag -= 0x10;
 	}
@@ -647,17 +645,17 @@
 	_screen->hideMouse();
 	assert(_brandonToWispTable);
 	setupShapes123(_brandonToWispTable, 26, 0);
-	setBrandonAnimSeqSize(5, 48);
+	_animator->setBrandonAnimSeqSize(5, 48);
 	_brandonStatusBit &= 0xFFFD;
 	snd_playSoundEffect(0x6C);
 	for (int i = 138; i >= 123; --i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(8);
 	}
-	setBrandonAnimSeqSize(4, 48);
+	_animator->setBrandonAnimSeqSize(4, 48);
 	_currentCharacter->currentAnimFrame = 7;
-	animRefreshNPC(0);
+	_animator->animRefreshNPC(0);
 	if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) {
 		_screen->fadeSpecialPalette(31, 234, 13, 4);
 	} else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) {
@@ -680,11 +678,11 @@
 	checkAmuletAnimFlags();
 	assert(_brandonToWispTable);
 	setupShapes123(_brandonToWispTable, 26, 0);
-	setBrandonAnimSeqSize(5, 48);
+	_animator->setBrandonAnimSeqSize(5, 48);
 	snd_playSoundEffect(0x6C);
 	for (int i = 123; i <= 138; ++i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(8);
 	}
 	_brandonStatusBit |= 2;
@@ -693,10 +691,10 @@
 	} else {
 		setTimerCountdown(14, 7200);
 	}
-	_brandonDrawFrame = 113;
+	_animator->_brandonDrawFrame = 113;
 	_brandonStatusBit0x02Flag = 1;
 	_currentCharacter->currentAnimFrame = 113;
-	animRefreshNPC(0);
+	_animator->animRefreshNPC(0);
 	_animator->updateAllObjectShapes();
 	if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) {
 		_screen->fadeSpecialPalette(30, 234, 13, 4);
@@ -727,11 +725,11 @@
 	setGameFlag(0xEE);
 	assert(_magicAnimationTable);
 	setupShapes123(_magicAnimationTable, 5, 0);
-	setBrandonAnimSeqSize(8, 49);
+	_animator->setBrandonAnimSeqSize(8, 49);
 	snd_playSoundEffect(0x15);
 	for (int i = 123; i <= 127; ++i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(8);
 	}
 	
@@ -739,12 +737,12 @@
 	
 	for (int i = 127; i >= 123; --i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(10);
 	}
-	resetBrandonAnimSeqSize();
+	_animator->resetBrandonAnimSeqSize();
 	_currentCharacter->currentAnimFrame = 7;
-	animRefreshNPC(0);
+	_animator->animRefreshNPC(0);
 	freeShapes123();
 	_screen->showMouse();
 }
@@ -796,23 +794,23 @@
 	_screen->hideMouse();
 	checkAmuletAnimFlags();
 	_currentCharacter->facing = 5;
-	animRefreshNPC(0);
+	_animator->animRefreshNPC(0);
 	assert(_drinkAnimationTable);
 	setupShapes123(_drinkAnimationTable, 9, flags);
-	setBrandonAnimSeqSize(5, 54);
+	_animator->setBrandonAnimSeqSize(5, 54);
 	
 	for (int i = 123; i <= 131; ++i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(5);
 	}	
 	snd_playSoundEffect(0x34);
 	for (int i = 0; i < 2; ++i) {
 		_currentCharacter->currentAnimFrame = 130;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(7);
 		_currentCharacter->currentAnimFrame = 131;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(7);
 	}
 	
@@ -822,13 +820,13 @@
 	
 	for (int i = 131; i >= 123; --i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(5);
 	}
 	
-	resetBrandonAnimSeqSize();	
+	_animator->resetBrandonAnimSeqSize();	
 	_currentCharacter->currentAnimFrame = 7;
-	animRefreshNPC(0);
+	_animator->animRefreshNPC(0);
 	freeShapes123();
 	_screen->showMouse();
 }
@@ -923,13 +921,13 @@
 	_screen->hideMouse();
 	assert(_brandonStoneTable);
 	setupShapes123(_brandonStoneTable, 14, 0);
-	setBrandonAnimSeqSize(5, 51);
+	_animator->setBrandonAnimSeqSize(5, 51);
 	for (int i = 123; i <= 136; ++i) {
 		_currentCharacter->currentAnimFrame = i;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		delayWithTicks(8);
 	}
-	resetBrandonAnimSeqSize();
+	_animator->resetBrandonAnimSeqSize();
 	freeShapes123();
 	_screen->showMouse();
 }
@@ -984,4 +982,649 @@
 	return _quitFlag || _abortIntroFlag;
 }
 
+int KyraEngine::handleMalcolmFlag() {
+	debug(9, "KyraEngine::handleMalcolmFlag()");
+	static uint16 frame = 0;
+	static uint32 timer1 = 0;
+	static uint32 timer2 = 0;
+	
+	switch (_malcolmFlag) {
+		case 1:
+			frame = 0;
+			_malcolmFlag = 2;
+			timer2 = 0;
+		case 2:
+			if (_system->getMillis() >= timer2) {
+				_finalA->_x = 8;
+				_finalA->_y = 46;
+				_finalA->_drawPage = 0;
+				_finalA->displayFrame(frame);
+				_screen->updateScreen();
+				timer2 = _system->getMillis() + 8 * _tickLength;
+				++frame;
+				if (frame > 13) {
+					_malcolmFlag = 3;
+					timer1 = _system->getMillis() + 180 * _tickLength;
+				}
+			}
+			break;
+		
+		case 3:
+			if (_system->getMillis() < timer1) {
+				if (_system->getMillis() >= timer2) {
+					frame = _rnd.getRandomNumberRng(14, 17);
+					_finalA->_x = 8;
+					_finalA->_y = 46;
+					_finalA->_drawPage = 0;
+					_finalA->displayFrame(frame);
+					_screen->updateScreen();
+					timer2 = _system->getMillis() + 8 * _tickLength;
+				}
+			} else {
+				_malcolmFlag = 4;
+				frame = 18;
+			}
+			break;
+		
+		case 4:
+			if (_system->getMillis() >= timer2) {
+				_finalA->_x = 8;
+				_finalA->_y = 46;
+				_finalA->_drawPage = 0;
+				_finalA->displayFrame(frame);
+				_screen->updateScreen();
+				timer2 = _system->getMillis() + 8 * _tickLength;
+				++frame;
+				if (frame > 25) {
+					frame = 26;
+					_malcolmFlag = 5;
+					_beadStateVar = 1;
+				}
+			}
+			break;
+		
+		case 5:
+			if (_system->getMillis() >= timer2) {
+				_finalA->_x = 8;
+				_finalA->_y = 46;
+				_finalA->_drawPage = 0;
+				_finalA->displayFrame(frame);
+				_screen->updateScreen();
+				timer2 = _system->getMillis() + 8 * _tickLength;
+				++frame;
+				if (frame > 31) {
+					frame = 32;
+					_malcolmFlag = 6;
+				}
+			}
+			break;
+			
+		case 6:
+			if (_unkEndSeqVar4) {
+				if (frame <= 33 && _system->getMillis() >= timer2) {
+					_finalA->_x = 8;
+					_finalA->_y = 46;
+					_finalA->_drawPage = 0;
+					_finalA->displayFrame(frame);
+					_screen->updateScreen();
+					timer2 = _system->getMillis() + 8 * _tickLength;
+					++frame;
+					if (frame > 33) {
+						_malcolmFlag = 7;
+						frame = 32;
+						_unkEndSeqVar5 = 0;
+					}
+				}
+			}
+			break;
+		
+		case 7:
+			if (_unkEndSeqVar5 == 1) {
+				_malcolmFlag = 8;
+				frame = 34;
+			} else if (_unkEndSeqVar5 == 2) {
+				_malcolmFlag = 3;
+				timer1 = _system->getMillis() + 180 * _tickLength;
+			}
+			break;
+		
+		case 8:
+			if (_system->getMillis() >= timer2) {
+				_finalA->_x = 8;
+				_finalA->_y = 46;
+				_finalA->_drawPage = 0;
+				_finalA->displayFrame(frame);
+				_screen->updateScreen();
+				timer2 = _system->getMillis() + 8 * _tickLength;
+				++frame;
+				if (frame > 37) {
+					_malcolmFlag = 0;
+					_deathHandler = 8;
+					return 1;
+				}
+			}
+			break;
+		
+		case 9:
+			snd_playSoundEffect(12);
+			snd_playSoundEffect(12);
+			_finalC->_x = 16;
+			_finalC->_y = 50;
+			_finalC->_drawPage = 0;
+			for (int i = 0; i < 18; ++i) {
+				timer2 = _system->getMillis() + 4 * _tickLength;
+				_finalC->displayFrame(i);
+				_screen->updateScreen();
+				while (_system->getMillis() < timer2) {}
+			}
+			snd_playWanderScoreViaMap(51, 1);
+			delay(60*_tickLength);
+			_malcolmFlag = 0;
+			return 1;
+			break;
+		
+		case 10:
+			if (!_beadStateVar) {
+				handleBeadState();
+				_screen->bitBlitRects();
+				assert(_veryClever);
+				_text->printTalkTextMessage(_veryClever[0], 60, 31, 5, 0, 2);
+				timer2 = _system->getMillis() + 180 * _tickLength;
+				_malcolmFlag = 11;
+			}
+			break;
+		
+		case 11:
+			if (_system->getMillis() >= timer2) {
+				_text->restoreTalkTextMessageBkgd(2, 0);
+				_malcolmFlag = 3;
+				timer1 = _system->getMillis() + 180 * _tickLength;
+			}
+			break;
+		
+		default:
+			break;
+	}
+	
+	return 0;
+}
+
+int KyraEngine::handleBeadState() {
+	debug(9, "KyraEngine::handleBeadState()");
+	static uint32 timer1 = 0;
+	static uint32 timer2 = 0;
+	static BeadState beadState1 = { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+	static BeadState beadState2 = {  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+	
+	static const int table1[] = {
+		-1, -2, -4, -5, -6, -7, -6, -5,
+		-4, -2, -1,  0,  1,  2,  4,  5,
+		 6,  7,  6,  5,  4,  2,  1,  0, 0
+	};
+	static const int table2[] = {
+		0, 0, 1, 1, 2, 2, 3, 3,
+		4, 4, 5, 5, 5, 5, 4, 4,
+		3, 3, 2, 2, 1, 1, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0, 0
+	};
+	
+	switch (_beadStateVar) {
+		case 0:
+			if (beadState1.x != -1 && _endSequenceBackUpRect) {
+				_screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+				_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
+			} else {
+				beadState1.x = -1;
+				beadState1.tableIndex = 0;
+				timer1 = 0;
+				timer2 = 0;
+				_lastDisplayedPanPage = 0;
+				return 1;
+			}
+		
+		case 1:
+			if (beadState1.x != -1) {
+				if (_endSequenceBackUpRect) {
+					_screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+					_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
+				}
+				beadState1.x = -1;
+				beadState1.tableIndex = 0;
+			}
+			_beadStateVar = 2;
+			break;
+		
+		case 2:
+			if (_system->getMillis() >= timer1) {
+				int x = 0, y = 0;
+				timer1 = _system->getMillis() + 4 * _tickLength;
+				if (beadState1.x == -1) {
+					assert(_panPagesTable);
+					beadState1.width2 = _animator->fetchAnimWidth(_panPagesTable[19], 256);
+					beadState1.width = ((beadState1.width2 + 7) >> 3) + 1;
+					beadState1.height = _animator->fetchAnimHeight(_panPagesTable[19], 256);
+					if (!_endSequenceBackUpRect) {
+						_endSequenceBackUpRect = new uint8[(beadState1.width * beadState1.height) << 3];
+						assert(_endSequenceBackUpRect);
+						memset(_endSequenceBackUpRect, 0, ((beadState1.width * beadState1.height) << 3) * sizeof(uint8));
+					}
+					x = beadState1.x = 60;
+					y = beadState1.y = 40;
+					initBeadState(x, y, x, 25, 8, &beadState2);
+				} else {
+					if (processBead(beadState1.x, beadState1.y, x, y, &beadState2)) {
+						_beadStateVar = 3;
+						timer2 = _system->getMillis() + 240 * _tickLength;
+						_unkEndSeqVar4 = 0;
+						beadState1.dstX = beadState1.x;
+						beadState1.dstY = beadState1.y;
+						return 0;
+					} else {
+						_screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+						_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
+						beadState1.x = x;
+						beadState1.y = y;
+					}
+				}
+				_screen->copyCurPageBlock(x >> 3, y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+				_screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], x, y, 0, 0);
+				if (_lastDisplayedPanPage > 17)
+					_lastDisplayedPanPage = 0;
+				_screen->addBitBlitRect(x, y, beadState1.width2, beadState1.height);
+			}
+			break;
+		
+		case 3:
+			if (_system->getMillis() >= timer1) {
+				timer1 = _system->getMillis() + 4 * _tickLength;
+				_screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+				_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
+				beadState1.x = beadState1.dstX + table1[beadState1.tableIndex];
+				beadState1.y = beadState1.dstY + table2[beadState1.tableIndex];
+				_screen->copyCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+				_screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], beadState1.x, beadState1.y, 0, 0);
+				if (_lastDisplayedPanPage >= 17) {
+					_lastDisplayedPanPage = 0;
+				}
+				_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
+				++beadState1.tableIndex;
+				if (beadState1.tableIndex > 24) {
+					beadState1.tableIndex = 0;
+					_unkEndSeqVar4 = 1;
+				}
+				if (_system->getMillis() > timer2 && _malcolmFlag == 7 && !_unkAmuletVar && !_text->printed()) {
+					snd_playSoundEffect(0x0B);
+					if (_currentCharacter->x1 > 233 && _currentCharacter->x1 < 305 && _currentCharacter->y1 > 85 && _currentCharacter->y1 < 105 &&
+						(_brandonStatusBit & 0x20)) {
+						beadState1.unk8 = 290;
+						beadState1.unk9 = 40;
+						_beadStateVar = 5;
+					} else {
+						_beadStateVar = 4;
+						beadState1.unk8 = _currentCharacter->x1 - 4;
+						beadState1.unk9 = _currentCharacter->y1 - 30;
+					}
+					
+					if (_text->printed()) {
+						_text->restoreTalkTextMessageBkgd(2, 0);
+					}
+					initBeadState(beadState1.x, beadState1.y, beadState1.unk8, beadState1.unk9, 6, &beadState2);
+					_lastDisplayedPanPage = 18;
+				}
+			}
+			break;
+			
+		case 4:
+			if (_system->getMillis() >= timer1) {
+				int x = 0, y = 0;
+				timer1 = _system->getMillis();
+				if (processBead(beadState1.x, beadState1.y, x, y, &beadState2)) {
+					if (_brandonStatusBit & 20) {
+						_unkEndSeqVar5 = 2;
+						_beadStateVar = 6;
+					} else {
+						snd_playWanderScoreViaMap(52, 1);
+						snd_playSoundEffect(0x0C);
+						_unkEndSeqVar5 = 1;
+						_beadStateVar = 0;
+					}
+				} else {
+					_screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+					_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
+					beadState1.x = x;
+					beadState1.y = y;
+					_screen->copyCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+					_screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], x, y, 0, 0);
+					if (_lastDisplayedPanPage > 17) {
+						_lastDisplayedPanPage = 0;
+					}
+					_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
+				}
+			}
+			break;
+		
+		case 5:
+			if (_system->getMillis() >= timer1) {
+				timer1 = _system->getMillis();
+				int x = 0, y = 0;
+				if (processBead(beadState1.x, beadState1.y, x, y, &beadState2)) {
+					if (beadState1.dstX == 290) {
+						_screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+						uint32 nextRun = 0;
+						_finalB->_x = 224;
+						_finalB->_y = 8;
+						_finalB->_drawPage = 0;
+						for (int i = 0; i < 8; ++i) {
+							nextRun = _system->getMillis() + _tickLength;
+							_finalB->displayFrame(i);
+							_screen->updateScreen();
+							while (_system->getMillis() < nextRun) {}
+						}
+						snd_playSoundEffect(0x0D);
+						for (int i = 7; i >= 0; --i) {
+							nextRun = _system->getMillis() + _tickLength;
+							_finalB->displayFrame(i);
+							_screen->updateScreen();
+							while (_system->getMillis() < nextRun) {}
+						}
+						initBeadState(beadState1.x, beadState1.y, 63, 60, 6, &beadState2);
+					} else {
+						_screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+						_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
+						beadState1.x = -1;
+						beadState1.tableIndex = 0;
+						_beadStateVar = 0;
+						_malcolmFlag = 9;
+					}
+				} else {
+					_screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+					_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
+					beadState1.x = x;
+					beadState1.y = y;
+					_screen->copyCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+					_screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], x, y, 0, 0);
+					if (_lastDisplayedPanPage > 17) {
+						_lastDisplayedPanPage = 0;
+					}
+					_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
+				}
+			}
+			break;
+		
+		case 6:
+			_screen->drawShape(2, _panPagesTable[19], beadState1.x, beadState1.y, 0, 0);
+			_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
+			_beadStateVar = 0;
+			break;
+		
+		default:
+			break;
+	}
+	return 0;
+}
+
+void KyraEngine::initBeadState(int x, int y, int x2, int y2, int unk, BeadState *ptr) {
+	debug(9, "KyraEngine::initBeadState(%d, %d, %d, %d, %d, 0x%X)", x, y, x2, y2, unk, ptr);
+	ptr->unk9 = unk;
+	int xDiff = x2 - x;
+	int yDiff = y2 - y;
+	int unk1 = 0, unk2 = 0;
+	if (xDiff > 0) {
+		unk1 = 1;
+	} else if (xDiff == 0) {
+		unk1 = 0;
+	} else {
+		unk1 = -1;
+	}
+	
+	if (yDiff > 0) {
+		unk2 = 1;
+	} else if (yDiff == 0) {
+		unk2 = 0;
+	} else {
+		unk2 = -1;
+	}
+	
+	xDiff = abs(xDiff);
+	yDiff = abs(yDiff);
+	
+	ptr->y = 0;
+	ptr->x = 0;
+	ptr->width = xDiff;
+	ptr->height = yDiff;
+	ptr->dstX = x2;
+	ptr->dstY = y2;
+	ptr->width2 = unk1;
+	ptr->unk8 = unk2;
+}
+
+int KyraEngine::processBead(int x, int y, int &x2, int &y2, BeadState *ptr) {
+	debug(9, "KyraEngine::processBead(%d, %d, 0x%X, 0x%X, 0x%X)", x, y, &x2, &y2, ptr);
+	if (x == ptr->dstX && y == ptr->dstY) {
+		return 1;
+	}
+	
+	int xPos = x, yPos = y;
+	if (ptr->width >= ptr->height) {
+		for (int i = 0; i < ptr->unk9; ++i) {
+			ptr->y += ptr->height;
+			if (ptr->y >= ptr->width) {
+				ptr->y -= ptr->width;
+				yPos += ptr->unk8;
+			}
+			xPos += ptr->width2;
+		}
+	} else {
+		for (int i = 0; i < ptr->unk9; ++i) {
+			ptr->x += ptr->width;
+			if (ptr->x >= ptr->height) {
+				ptr->x -= ptr->height;
+				xPos += ptr->width2;
+			}
+			yPos += ptr->unk8;
+		}
+	}
+	
+	int temp = abs(x - ptr->dstX);
+	if (ptr->unk9 > temp) {
+		xPos = ptr->dstX;
+	}
+	temp = abs(y - ptr->dstY);
+	if (ptr->unk9 > temp) {
+		yPos = ptr->dstY;
+	}
+	x2 = xPos;
+	y2 = yPos;
+	return 0;
+}
+
+void KyraEngine::setupPanPages() {
+	debug(9, "KyraEngine::setupPanPages()");
+	loadBitmap("bead.cps", 3, 3, 0);
+	for (int i = 0; i <= 19; ++i) {
+		_panPagesTable[i] = _seq->setPanPages(3, i);
+	}
+}
+
+void KyraEngine::freePanPages() {
+	debug(9, "KyraEngine::freePanPages()");
+	delete _endSequenceBackUpRect;
+	_endSequenceBackUpRect = 0;
+	for (int i = 0; i <= 19; ++i) {
+		free(_panPagesTable[i]);
+		_panPagesTable[i] = NULL;
+	}
+}
+
+void KyraEngine::closeFinalWsa() {
+	debug(9, "KyraEngine::closeFinalWsa()");
+	delete _finalA;
+	_finalA = 0;
+	delete _finalB;
+	_finalB = 0;
+	delete _finalC;
+	_finalC = 0;
+	freePanPages();
+	_endSequenceNeedLoading = 1;
+}
+
+void KyraEngine::updateKyragemFading() {
+	static const uint8 kyraGemPalette[0x28] = {
+		0x3F, 0x3B, 0x38, 0x34, 0x32, 0x2F, 0x2C, 0x29, 0x25, 0x22,
+		0x1F, 0x1C, 0x19, 0x16, 0x12, 0x0F, 0x0C, 0x0A, 0x06, 0x03,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	};
+	
+	if (_system->getMillis() < _kyragemFadingState.timerCount)
+		return;
+	
+	_kyragemFadingState.timerCount = _system->getMillis() + 4 * _tickLength;
+	int palPos = 684;
+	for (int i = 0; i < 20; ++i) {
+		_screen->_currentPalette[palPos++] = kyraGemPalette[i + _kyragemFadingState.rOffset];
+		_screen->_currentPalette[palPos++] = kyraGemPalette[i + _kyragemFadingState.gOffset];
+		_screen->_currentPalette[palPos++] = kyraGemPalette[i + _kyragemFadingState.bOffset];
+	}
+	_screen->setScreenPalette(_screen->_currentPalette);
+	_animator->_updateScreen = true;
+	switch (_kyragemFadingState.nextOperation) {
+		case 0:
+			--_kyragemFadingState.bOffset;
+			if (_kyragemFadingState.bOffset >= 1)
+				return;
+			_kyragemFadingState.nextOperation = 1;
+			break;
+
+		case 1:
+			++_kyragemFadingState.rOffset;
+			if (_kyragemFadingState.rOffset < 19)
+				return;
+			_kyragemFadingState.nextOperation = 2;
+			break;
+
+		case 2:
+			--_kyragemFadingState.gOffset;
+			if (_kyragemFadingState.gOffset >= 1)
+				return;
+			_kyragemFadingState.nextOperation = 3;
+			break;
+		
+		case 3:
+			++_kyragemFadingState.bOffset;
+			if (_kyragemFadingState.bOffset < 19)
+				return;
+			_kyragemFadingState.nextOperation = 4;
+			break;
+		
+		case 4:
+			--_kyragemFadingState.rOffset;
+			if (_kyragemFadingState.rOffset >= 1)
+				return;
+			_kyragemFadingState.nextOperation = 5;
+			break;
+		
+		case 5:
+			++_kyragemFadingState.gOffset;
+			if (_kyragemFadingState.gOffset < 19)
+				return;
+			_kyragemFadingState.nextOperation = 0;
+			break;
+			
+		default:
+			break;
+	}
+	
+	_kyragemFadingState.timerCount = _system->getMillis() + 120 * _tickLength;
+}
+
+void KyraEngine::drawJewelPress(int jewel, int drawSpecial) {
+	debug(9, "KyraEngine::drawJewelPress(%d, %d)", jewel, drawSpecial);
+	_screen->hideMouse();
+	int shape = 0;
+	if (drawSpecial) {
+		shape = 0x14E;
+	} else {
+		shape = jewel + 0x149;
+	}
+	snd_playSoundEffect(0x45);
+	_screen->drawShape(0, _shapes[4+shape], _amuletX2[jewel], _amuletY2[jewel], 0, 0);
+	_screen->updateScreen();
+	delayWithTicks(2);
+	if (drawSpecial) {
+		shape = 0x148;
+	} else {
+		shape = jewel + 0x143;
+	}
+	_screen->drawShape(0, _shapes[4+shape], _amuletX2[jewel], _amuletY2[jewel], 0, 0);
+	_screen->updateScreen();
+	_screen->showMouse();
+}
+
+void KyraEngine::drawJewelsFadeOutStart() {
+	debug(9, "KyraEngine::drawJewelsFadeOutStart()");
+	static const uint16 jewelTable1[] = { 0x164, 0x15F, 0x15A, 0x155, 0x150, 0xFFFF };
+	static const uint16 jewelTable2[] = { 0x163, 0x15E, 0x159, 0x154, 0x14F, 0xFFFF };
+	static const uint16 jewelTable3[] = { 0x166, 0x160, 0x15C, 0x157, 0x152, 0xFFFF };
+	static const uint16 jewelTable4[] = { 0x165, 0x161, 0x15B, 0x156, 0x151, 0xFFFF };
+	for (int i = 0; jewelTable1[i] != 0xFFFF; ++i) {
+		if (queryGameFlag(0x57)) {
+			_screen->drawShape(0, _shapes[4+jewelTable1[i]], _amuletX2[2], _amuletY2[2], 0, 0);
+		}
+		if (queryGameFlag(0x59)) {
+			_screen->drawShape(0, _shapes[4+jewelTable3[i]], _amuletX2[4], _amuletY2[4], 0, 0);
+		}
+		if (queryGameFlag(0x56)) {
+			_screen->drawShape(0, _shapes[4+jewelTable2[i]], _amuletX2[1], _amuletY2[1], 0, 0);
+		}
+		if (queryGameFlag(0x58)) {
+			_screen->drawShape(0, _shapes[4+jewelTable4[i]], _amuletX2[3], _amuletY2[3], 0, 0);
+		}
+		_screen->updateScreen();
+		delayWithTicks(3);
+	}
+}
+
+void KyraEngine::drawJewelsFadeOutEnd(int jewel) {
+	debug(9, "KyraEngine::drawJewelsFadeOutEnd(%d)", jewel);
+	static const uint16 jewelTable[] = { 0x153, 0x158, 0x15D, 0x162, 0x148, 0xFFFF };
+	int newDelay = 0;
+	switch (jewel-1) {
+		case 2:
+			if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) {
+				newDelay = 18900;
+			} else {
+				newDelay = 8100;
+			}
+			break;
+			
+		default:
+			newDelay = 3600;
+			break;
+	}
+	setGameFlag(0xF1);
+	setTimerCountdown(19, newDelay);
+	_screen->hideMouse();
+	for (int i = 0; jewelTable[i] != 0xFFFF; ++i) {
+		uint16 shape = jewelTable[i];
+		if (queryGameFlag(0x57)) {
+			_screen->drawShape(0, _shapes[4+shape], _amuletX2[2], _amuletY2[2], 0, 0);
+		}
+		if (queryGameFlag(0x59)) {
+			_screen->drawShape(0, _shapes[4+shape], _amuletX2[4], _amuletY2[4], 0, 0);
+		}
+		if (queryGameFlag(0x56)) {
+			_screen->drawShape(0, _shapes[4+shape], _amuletX2[1], _amuletY2[1], 0, 0);
+		}
+		if (queryGameFlag(0x58)) {
+			_screen->drawShape(0, _shapes[4+shape], _amuletX2[3], _amuletY2[3], 0, 0);
+		}
+		_screen->updateScreen();
+		delayWithTicks(3);
+	}
+	_screen->showMouse();
+}
+
 } // end of namespace Kyra

Modified: scummvm/trunk/kyra/sprites.cpp
===================================================================
--- scummvm/trunk/kyra/sprites.cpp	2006-02-11 08:25:20 UTC (rev 20492)
+++ scummvm/trunk/kyra/sprites.cpp	2006-02-11 08:31:13 UTC (rev 20493)
@@ -318,21 +318,21 @@
 				data += 2;
 				debug(6, "func: Set Brandon's X coordinate");
 				debug(6, "X %i", READ_LE_UINT16(data));
-				_engine->_currentCharacter->x1 = READ_LE_UINT16(data);
+				_engine->currentCharacter()->x1 = READ_LE_UINT16(data);
 				data += 2;
 				break;
 			case 0xFFAE:
 				data += 2;
 				debug(6, "func: Set Brandon's Y coordinate");
 				debug(6, "Y %i", READ_LE_UINT16(data));
-				_engine->_currentCharacter->y1 = READ_LE_UINT16(data);
+				_engine->currentCharacter()->y1 = READ_LE_UINT16(data);
 				data += 2;
 				break;
 			case 0xFFAF:
 				data += 2;
 				debug(6, "func: Set Brandon's sprite");
 				debug(6, "Sprite %i", READ_LE_UINT16(data));
-				_engine->_currentCharacter->currentAnimFrame = READ_LE_UINT16(data);
+				_engine->currentCharacter()->currentAnimFrame = READ_LE_UINT16(data);
 				data += 2;
 				break;
 			case 0xFFAA:
@@ -342,7 +342,7 @@
 			case 0xFFAB:
 				data += 2;
 				debug(6, "func: Update Brandon's sprite");
-				_engine->animRefreshNPC(0);
+				_engine->animator()->animRefreshNPC(0);
 				_engine->animator()->flagAllObjectsForRefresh();
 				_engine->animator()->updateAllObjectShapes();
 				break;

Modified: scummvm/trunk/kyra/text.cpp
===================================================================
--- scummvm/trunk/kyra/text.cpp	2006-02-11 08:25:20 UTC (rev 20492)
+++ scummvm/trunk/kyra/text.cpp	2006-02-11 08:31:13 UTC (rev 20493)
@@ -74,8 +74,8 @@
 			hasUpdatedNPCs = true;
 			disableTimer(15);
 			_currHeadShape = 4;
-			animRefreshNPC(0);
-			animRefreshNPC(_talkingCharNum);
+			_animator->animRefreshNPC(0);
+			_animator->animRefreshNPC(_talkingCharNum);
 
 			if (_charSayUnk2 != -1) {
 				_animator->sprites()[_charSayUnk2].active = 0;
@@ -144,7 +144,7 @@
 	if (convoInitialized != 0) {
 		_talkingCharNum = -1;
 		_currentCharacter->currentAnimFrame = 7;
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		_animator->updateAllObjectShapes();
 	}
 }
@@ -154,11 +154,11 @@
 
 	if (charNum > 0 && charNum < 5) {
 		_characterList[charNum].currentAnimFrame = _currentChatPartnerBackupFrame;
-		animRefreshNPC(charNum);
+		_animator->animRefreshNPC(charNum);
 	}
 
 	_currentCharacter->currentAnimFrame = 7;
-	animRefreshNPC(0);
+	_animator->animRefreshNPC(0);
 	_animator->updateAllObjectShapes();
 }
 
@@ -173,7 +173,7 @@
 	else
 		_currentCharacter->currentAnimFrame = _currentCharAnimFrame;
 
-	animRefreshNPC(0);
+	_animator->animRefreshNPC(0);
 	_animator->updateAllObjectShapes();
 }
 
@@ -208,7 +208,7 @@
 		else
 			_currentCharacter->currentAnimFrame = 16;
 
-		animRefreshNPC(0);
+		_animator->animRefreshNPC(0);
 		_animator->updateAllObjectShapes();
 	}
 
@@ -250,7 +250,7 @@
 		_characterList[charNum].currentAnimFrame = startAnimFrames[charNum];
 		_charSayUnk3 = charNum;
 		_talkingCharNum = charNum;
-		animRefreshNPC(charNum);
+		_animator->animRefreshNPC(charNum);
 	}
 
 	char *processedString = _text->preprocessString(chatStr);

Modified: scummvm/trunk/kyra/timer.cpp
===================================================================
--- scummvm/trunk/kyra/timer.cpp	2006-02-11 08:25:20 UTC (rev 20492)
+++ scummvm/trunk/kyra/timer.cpp	2006-02-11 08:31:13 UTC (rev 20493)
@@ -22,6 +22,8 @@
 
 #include "kyra/kyra.h"
 #include "kyra/screen.h"
+#include "kyra/animator.h"
+
 #include "common/system.h"
 
 namespace Kyra {
@@ -151,8 +153,8 @@
 	if (frameTable[currentFrame] == -1)
 		currentFrame = 0;
 
-	animRefreshNPC(0);
-	animRefreshNPC(_talkingCharNum);
+	_animator->animRefreshNPC(0);
+	_animator->animRefreshNPC(_talkingCharNum);
 }
 
 void KyraEngine::timerSetFlags1(int timerNum) {







More information about the Scummvm-git-logs mailing list