diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvmcvs/kyra/debugger.cpp scummvm/kyra/debugger.cpp
--- ./scummvmcvs/kyra/debugger.cpp	1970-01-01 01:00:00.000000000 +0100
+++ scummvm/kyra/debugger.cpp	2005-12-08 22:07:57.000000000 +0100
@@ -0,0 +1,177 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2003-2005 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.
+ *
+ */
+
+#include "common/stdafx.h"
+#include "common/config-manager.h"
+#include "common/debugger.cpp"
+#include "kyra/debugger.h"
+#include "kyra/kyra.h"
+#include "kyra/screen.h"
+
+namespace Kyra {
+
+Debugger::Debugger(KyraEngine *vm)
+	: Common::Debugger<Debugger>() {
+	_vm = vm;
+
+	DCmd_Register("continue",			&Debugger::cmd_Exit);
+	DCmd_Register("exit",				&Debugger::cmd_Exit);
+	DCmd_Register("help",				&Debugger::cmd_Help);
+	DCmd_Register("quit",				&Debugger::cmd_Exit);
+	DCmd_Register("enter",				&Debugger::cmd_EnterRoom);
+	DCmd_Register("rooms",				&Debugger::cmd_ListRooms);
+	DCmd_Register("flags",				&Debugger::cmd_ListFlags);
+	DCmd_Register("toggleflag",			&Debugger::cmd_ToggleFlag);
+	DCmd_Register("queryflag",			&Debugger::cmd_QueryFlag);
+	DCmd_Register("timers",				&Debugger::cmd_ListTimers);
+	DCmd_Register("settimercountdown",	&Debugger::cmd_SetTimerCountdown);
+}
+
+void Debugger::preEnter() {
+	//_vm->midi.pause(1);
+}
+
+void Debugger::postEnter() {
+	//_vm->midi.pause(0);
+}
+
+bool Debugger::cmd_EnterRoom(int argc, const char **argv) {
+	uint direction = 0;
+	if (argc > 1) {
+		uint room = atoi(argv[1]);
+
+		if (argc > 2)
+			direction = atoi(argv[2]);
+		else {
+			if (_vm->_roomTable[room].northExit != 0xff)
+				direction = 3;
+			else if (_vm->_roomTable[room].eastExit != 0xff)
+				direction = 4;
+			else if (_vm->_roomTable[room].southExit != 0xff)
+				direction = 1;
+			else if (_vm->_roomTable[room].westExit != 0xff)
+				direction = 2;
+		}
+
+		// Dirty way of hiding the debug console while the room entry scripts are running,
+		// otherwise the graphics didn't update.
+		_vm->_system->hideOverlay();
+		_vm->_currentCharacter->facing = direction;
+		
+		_vm->enterNewScene(room, _vm->_currentCharacter->facing, 0, 0, 1);
+		_vm->_system->showOverlay();
+		return false;
+	}
+
+	DebugPrintf("Syntax: room <roomnum> <direction>\n");
+	return true;
+}
+
+bool Debugger::cmd_Exit(int argc, const char **argv) {
+	_detach_now = true;
+	return false;
+}
+
+bool Debugger::cmd_Help(int argc, const char **argv) {
+	// console normally has 39 line width
+	// wrap around nicely
+	int width = 0, size, i;
+
+	DebugPrintf("Commands are:\n");
+	for (i = 0 ; i < _dcmd_count ; i++) {
+		size = strlen(_dcmds[i].name) + 1;
+
+		if ((width + size) >= 39) {
+			DebugPrintf("\n");
+			width = size;
+		} else
+			width += size;
+
+		DebugPrintf("%s ", _dcmds[i].name);
+	}
+	DebugPrintf("\n");
+	return true;
+}
+
+bool Debugger::cmd_ListRooms(int argc, const char **argv) {
+	for (int i = 0; i < _vm->_roomTableSize; i++) {
+		DebugPrintf("%-3i: %-10s", i, _vm->_roomFilenameTable[_vm->_roomTable[i].nameIndex]);
+		if (!(i % 8)) 
+			DebugPrintf("\n");
+	}
+	DebugPrintf("\n");
+	DebugPrintf("Current room: %i\n", _vm->_currentRoom);
+	return true;
+}
+
+bool Debugger::cmd_ListFlags(int argc, const char **argv) {
+	for (int i = 0; i < (int)sizeof(_vm->_flagsTable)*8; i++) {
+		DebugPrintf("(%-3i): %-5i", i, _vm->queryGameFlag(i));
+		if (!(i % 10)) 
+			DebugPrintf("\n");
+	}
+	DebugPrintf("\n");
+	return true;
+}
+
+bool Debugger::cmd_ToggleFlag(int argc, const char **argv) {
+	if (argc > 1) {
+		uint flag = atoi(argv[1]);
+		if (_vm->queryGameFlag(flag))
+			_vm->resetGameFlag(flag);
+		else
+			_vm->setGameFlag(flag);
+		DebugPrintf("Flag %i is now %i\n", flag, _vm->queryGameFlag(flag)); 
+	} else
+		DebugPrintf("Syntax: toggleflag <flag>\n");
+
+	return true;
+}
+
+bool Debugger::cmd_QueryFlag(int argc, const char **argv) {
+	if (argc > 1) {
+		uint flag = atoi(argv[1]);
+		DebugPrintf("Flag %i is %i\n", flag, _vm->queryGameFlag(flag)); 
+	} else
+		DebugPrintf("Syntax: queryflag <flag>\n");
+
+	return true;
+}
+
+bool Debugger::cmd_ListTimers(int argc, const char **argv) {
+	for (int i = 0; i < ARRAYSIZE(_vm->_timers); i++)
+		DebugPrintf("Timer %-2i: Active: %-3s Countdown: %-6i\n", i, _vm->_timers[i].active ? "Yes" : "No", _vm->_timers[i].countdown);
+
+	return true;
+}
+
+bool Debugger::cmd_SetTimerCountdown(int argc, const char **argv) {
+	if (argc > 2) {
+		uint timer = atoi(argv[1]);
+		uint countdown = atoi(argv[2]);
+		_vm->setTimerCountdown(timer, countdown);	
+		DebugPrintf("Timer %i now has countdown %i\n", timer, _vm->_timers[timer].countdown); 
+	} else
+		DebugPrintf("Syntax: settimercountdown <timer> <countdown>\n");
+
+	return true;
+}
+
+} // End of namespace Kyra
+
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvmcvs/kyra/debugger.h scummvm/kyra/debugger.h
--- ./scummvmcvs/kyra/debugger.h	1970-01-01 01:00:00.000000000 +0100
+++ scummvm/kyra/debugger.h	2005-12-05 16:53:36.000000000 +0100
@@ -0,0 +1,53 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2003-2005 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.
+ *
+ */
+
+#ifndef KYRA_DEBUGGER_H
+#define KYRA_DEBUGGER_H
+
+#include "common/debugger.h"
+
+namespace Kyra {
+
+class KyraEngine;
+
+class Debugger : public Common::Debugger<Debugger> {
+public:
+	Debugger(KyraEngine *vm);
+	virtual ~Debugger() {}  // we need this for __SYMBIAN32__ archaic gcc/UIQ
+
+protected:
+	KyraEngine *_vm;
+
+	virtual void preEnter();
+	virtual void postEnter();
+
+	bool cmd_Exit(int argc, const char **argv);
+	bool cmd_Help(int argc, const char **argv);
+	bool cmd_EnterRoom(int argc, const char **argv);
+	bool cmd_ListRooms(int argc, const char **argv);
+	bool cmd_ListFlags(int argc, const char **argv);
+	bool cmd_ToggleFlag(int argc, const char **argv);
+	bool cmd_QueryFlag(int argc, const char **argv);
+	bool cmd_ListTimers(int argc, const char **argv);
+	bool cmd_SetTimerCountdown(int argc, const char **argv);
+};
+
+} // End of namespace Kyra
+
+#endif
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvmcvs/kyra/kyra.cpp scummvm/kyra/kyra.cpp
--- ./scummvmcvs/kyra/kyra.cpp	2005-12-08 18:19:17.000000000 +0100
+++ scummvm/kyra/kyra.cpp	2005-12-08 23:13:31.000000000 +0100
@@ -44,6 +44,7 @@
 #include "kyra/sound.h"
 #include "kyra/sprites.h"
 #include "kyra/wsamovie.h"
+#include "kyra/debugger.h"
 
 using namespace Kyra;
 
@@ -308,6 +309,8 @@
 	assert(_scriptClick);
 	memset(_scriptClick, 0, sizeof(ScriptState));
 	
+	_debugger = new Debugger(this);
+	assert(_debugger);	
 	memset(_shapes, 0, sizeof(_shapes));
 	memset(_wsaObjects, 0, sizeof(_wsaObjects));
 
@@ -320,10 +323,13 @@
 	_talkMessageY = 0xC;
 	_talkMessageH = 0;
 	_talkMessagePrinted = false;
-	_charSayUnk1 = -1;
+	_talkingCharNum = -1;
 	_charSayUnk3 = -1;
 	_mouseX = _mouseY = -1;
-	
+	memset(_currSentenceColor, 0, 3);
+	_startSentencePalIndex = -1;
+	_fadeText = false;
+
 	_brandonPosX = _brandonPosY = -1;
 	_brandonDrawFrame = 113;
 	
@@ -353,6 +359,7 @@
 }
 
 KyraEngine::~KyraEngine() {
+	delete _debugger;
 	delete _sprites;
 	delete _screen;
 	delete _res;
@@ -501,6 +508,8 @@
 			case OSystem::EVENT_KEYDOWN:
 				if (event.kbd.keycode == 'q' || event.kbd.keycode == 27) {
 					_quitFlag = true;
+				} else if (event.kbd.keycode == 'd' && !_debugger->isAttached()) {
+					_debugger->attach();
 				}
 				break;
 			case OSystem::EVENT_MOUSEMOVE:
@@ -523,6 +532,10 @@
 				break;
 			}
 		}
+
+		if (_debugger->isAttached())
+			_debugger->onFrame();
+
 		_sprites->updateSceneAnims();
 		updateAllObjectShapes();
 
@@ -541,12 +554,11 @@
 
 	while (!_quitFlag) {
 		int32 frameTime = (int32)_system->getMillis();
-
 		updateMousePointer();
 		updateGameTimers();
 		_sprites->updateSceneAnims();
 		updateAllObjectShapes();
-		// XXX call processPalette
+		updateTextFade();
 
 		_handleInput = true;
 		delay((frameTime + _gameSpeed) - _system->getMillis());
@@ -1186,9 +1198,10 @@
 	
 	memset(_entranceMouseCursorTracks, 0xFFFF, sizeof(uint16)*4);
 	_currentCharacter->sceneId = sceneId;
-	assert(sceneId < _roomFilenameTableSize);
 	
 	assert(sceneId < _roomTableSize);
+	assert(_roomTable[sceneId].nameIndex < _roomFilenameTableSize);
+
 	Room *currentRoom = &_roomTable[sceneId];
 	
 	if (_currentRoom != 0xFFFF && (_features & GF_TALKIE)) {
@@ -1203,9 +1216,7 @@
 	
 	_currentRoom = sceneId;
 	
-	assert(_currentCharacter->sceneId < _roomTableSize);
 	int tableId = _roomTable[_currentCharacter->sceneId].nameIndex;
-	assert(tableId < _roomFilenameTableSize);
 	char fileNameBuffer[32];
 	strcpy(fileNameBuffer, _roomFilenameTable[tableId]);
 	strcat(fileNameBuffer, ".DAT");
@@ -1241,9 +1252,10 @@
 	if (!brandonAlive) {
 		// XXX
 	}
-	
+
 	startSceneScript(brandonAlive);
 	setupSceneItems();
+	
 	initSceneData(facing, unk2, brandonAlive);
 	
 	_loopFlag2 = 0;
@@ -1312,7 +1324,8 @@
 	_sprites->updateSceneAnims();
 	updateGameTimers();
 	updateAllObjectShapes();
-	// XXX processPalette
+	updateTextFade();
+
 	if (_currentCharacter->sceneId == 210) {
 		// XXX game_updateKyragemFading
 	}
@@ -1953,6 +1966,7 @@
 	while (_scriptInterpreter->validScript(_scriptClick))
 		_scriptInterpreter->runScript(_scriptClick);
 
+	setTextFadeTimerCountdown(-1);
 	if (_currentCharacter->sceneId == 0xD2) {
 		// XXX
 	}
@@ -2185,9 +2199,9 @@
 		if (_system->getMillis() > timeToEnd && !hasUpdatedNPCs) {
 			hasUpdatedNPCs = true;
 			disableTimer(15);
-			_charSayUnk4 = 4;
+			_currHeadShape = 4;
 			animRefreshNPC(0);
-			animRefreshNPC(_charSayUnk1);
+			animRefreshNPC(_talkingCharNum);
 
 			if (_charSayUnk2 != -1) {
 				_sprites->_animObjects[_charSayUnk2].active = 0;
@@ -2208,7 +2222,7 @@
 		_screen->_curPage = currPage;
 
 		copyChangedObjectsForward(0);
-		//processPalette();
+		updateTextFade();
 
 		if ((chatDuration < (int16)(_system->getMillis() - timeAtStart)) && chatDuration != -1)
 			break;
@@ -2249,7 +2263,7 @@
 	}
 
 	if (convoInitialized != 0) {
-		_charSayUnk1 = -1;
+		_talkingCharNum = -1;
 		_currentCharacter->currentAnimFrame = 7;
 		animRefreshNPC(0);
 		updateAllObjectShapes();
@@ -2257,7 +2271,7 @@
 }
 
 void KyraEngine::restoreChatPartnerAnimFrame(int8 charNum) {
-	_charSayUnk1 = -1;
+	_talkingCharNum = -1;
 
 	if (charNum > 0 && charNum < 5) {
 		_characterList[charNum].currentAnimFrame = _currentChatPartnerBackupFrame;
@@ -2270,7 +2284,7 @@
 }
 
 void KyraEngine::backupChatPartnerAnimFrame(int8 charNum) {
-	_charSayUnk1 = 0;
+	_talkingCharNum = 0;
 
 	if (charNum < 5 && charNum > 0) 
 		_currentChatPartnerBackupFrame = _characterList[charNum].currentAnimFrame;
@@ -2307,8 +2321,8 @@
 }
 
 int KyraEngine::initCharacterChat(int8 charNum) {
-	if (_charSayUnk1 == -1) {
-		_charSayUnk1 = 0;
+	if (_talkingCharNum == -1) {
+		_talkingCharNum = 0;
 
 		if (_scaleMode != 0)
 			_currentCharacter->currentAnimFrame = 7;
@@ -2375,7 +2389,7 @@
 	if (charNum < 5) {
 		_characterList[charNum].currentAnimFrame = startAnimFrames[charNum];
 		_charSayUnk3 = charNum;
-		_charSayUnk1 = charNum;
+		_talkingCharNum = charNum;
 		animRefreshNPC(charNum);
 	}
 
@@ -2428,17 +2442,64 @@
 	endCharacterChat(charNum, convoInitialized);
 }
 
-void KyraEngine::drawSentenceCommand(char *sentence, int unk1) {
+void KyraEngine::drawSentenceCommand(char *sentence, int color) {
+	debug(9, "drawSentenceCommand('%s', %i)", sentence, color);
 	_screen->hideMouse();
 	_screen->fillRect(8, 143, 311, 152, 12);
-	// XXX: palette stuff
+
+	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;
+	}
 
 	printText(sentence, 8, 143, 0xFF, 12, 0);
 	_screen->showMouse();
-	//setTextFadeTimerCountdown(_textFadeTimerCountdown);
-	//_palScrollEnabled = 0;
+	setTextFadeTimerCountdown(15);
+	_fadeText = false;
+}
+
+void KyraEngine::updateSentenceCommand(char *str1, char *str2, int color) {
+	debug(9, "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);
+}
+
+void KyraEngine::updateTextFade() {
+	debug(9, "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 -
@@ -3131,7 +3192,7 @@
 			}
 			
 			// talking head functionallity
-			if (_charSayUnk1 != -1) {
+			if (_talkingCharNum != -1) {
 				const int16 baseAnimFrameTable1[] = { 0x11, 0x35, 0x59, 0x00, 0x00, 0x00 };
 				const int16 baseAnimFrameTable2[] = { 0x15, 0x39, 0x5D, 0x00, 0x00, 0x00 };
 				const int8 xOffsetTable1[] = { 2, 4, 0, 5, 2, 0, 0, 0 };
@@ -3141,7 +3202,7 @@
 				if (curObject->index == 0 || curObject->index <= 4) {
 					int shapesIndex = 0;
 					if (curObject->index == _charSayUnk3) {
-						shapesIndex = _charSayUnk4 + baseAnimFrameTable1[curObject->index];
+						shapesIndex = _currHeadShape + baseAnimFrameTable1[curObject->index];
 					} else {
 						shapesIndex = baseAnimFrameTable2[curObject->index];
 						int temp2 = 0;
@@ -4076,7 +4137,7 @@
 			updateMousePointer();
 			updateGameTimers();
 			updateAllObjectShapes();
-			// XXX processPalette
+			updateTextFade();
 			if (_currentCharacter->sceneId == 210) {
 				// XXX updateKyragemFading
 				// XXX playEnd
@@ -4217,7 +4278,7 @@
 #pragma mark -
 
 void KyraEngine::setupTimers() {
-	debug(9, "KyraEngine::setupTimers()");
+	debug(9, "setupTimers()");
 	memset(_timers, 0, sizeof(_timers));
 
 	for (int i = 0; i < 34; i++)
@@ -4226,7 +4287,7 @@
 	_timers[0].func = _timers[1].func = _timers[2].func = _timers[3].func = _timers[4].func = 0; //Unused.
 	_timers[5].func = _timers[6].func = _timers[7].func = _timers[8].func = _timers[9].func = 0; //_nullsub51;
 	_timers[10].func = _timers[11].func = _timers[12].func = _timers[13].func = 0; //_nullsub50;
-	_timers[14].func = &KyraEngine::timerCheckAnimFlag2;; //_nullsub52;
+	_timers[14].func = &KyraEngine::timerCheckAnimFlag2; //_nullsub52;
 	_timers[15].func = &KyraEngine::timerUpdateHeadAnims; //_nullsub48;
 	_timers[16].func = &KyraEngine::timerSetFlags1; //_nullsub47;
 	_timers[17].func = 0; //sub_15120;
@@ -4243,7 +4304,7 @@
 	_timers[28].func = 0; //offset _timerDummy6
 	_timers[29].func = 0; //offset _timerDummy7, 
 	_timers[30].func = 0; //offset _timerDummy8, 
-	_timers[31].func = 0; //sub_151F8;
+	_timers[31].func = &KyraEngine::timerFadeText; //sub_151F8;
 	_timers[32].func = 0; //_nullsub61;
 	_timers[33].func = 0; //_nullsub62;
 
@@ -4270,20 +4331,8 @@
 	_timers[33].countdown = 3;
 }
 
-void KyraEngine::setTimer19() {
-	debug(9, "KyraEngine::setTimer19()");
-	if (_brandonStatusBit & 2) {
-		// XXX call sub_3F9C
-		setTimerCountdown(19, 300);
-	} else if (_brandonStatusBit & 0x20) {
-		// XXX call sub_4110
-		setTimerCountdown(19, 300);
-	}
-}
-
 void KyraEngine::updateGameTimers() {
-	debug(9, "KyraEngine::updateGameTimers()");
-	void (Kyra::KyraEngine::*callback)(int timerNum);
+	debug(9, "updateGameTimers()");
 	
 	if (_system->getMillis() < _timerNextRun)
 		return;
@@ -4293,13 +4342,8 @@
 	for (int i = 0; i < 34; i++) {
 		if (_timers[i].active && _timers[i].countdown > -1) {
 			if (_timers[i].nextRun <=_system->getMillis()) {
-				if (i < 5)
-					callback = 0;
-				else
-					callback = _timers[i].func;
-
-				if (callback)
-					(*this.*callback)(i);
+				if (i > 4 && _timers[i].func)
+					(*this.*_timers[i].func)(i);
 
 				_timers[i].nextRun = _system->getMillis() + _timers[i].countdown * _tickLength;
 
@@ -4311,16 +4355,17 @@
 }
 
 void KyraEngine::clearNextEventTickCount() {
-	debug(9, "KyraEngine::clearNextEventTickCount()");
+	debug(9, "clearNextEventTickCount()");
 	_timerNextRun = 0;
 }
 
 int16 KyraEngine::getTimerDelay(uint8 timer) {
+	debug(9, "getTimerDelay(%i)", timer);
 	return _timers[timer].countdown;
 }
 
-void KyraEngine::setTimerCountdown(uint8 timer, int16 countdown) {
-	debug(9, "KyraEngine::setTimerCountdown(%i, %i)", timer, countdown);
+void KyraEngine::setTimerCountdown(uint8 timer, int32 countdown) {
+	debug(9, "setTimerCountdown(%i, %i)", timer, countdown);
 	_timers[timer].countdown = countdown;
 
 	uint32 nextRun = _system->getMillis() + countdown;
@@ -4329,36 +4374,36 @@
 }
 
 void KyraEngine::enableTimer(uint8 timer) {
-	debug(9, "KyraEngine::enableTimer(%i)", timer);
+	debug(9, "enableTimer(%i)", timer);
 	_timers[timer].active = 1;
 }
 
 void KyraEngine::disableTimer(uint8 timer) {
-	debug(9, "KyraEngine::disableTimer(%i)", timer);
+	debug(9, "disableTimer(%i)", timer);
 	_timers[timer].active = 0;
 }
 
 void KyraEngine::timerUpdateHeadAnims(int timerNum) {
-	debug(9, "KyraEngine::timerUpdateHeadAnims(%i)", timerNum);
+	debug(9, "timerUpdateHeadAnims(%i)", timerNum);
 	static int8 currentFrame = 0;
 	static const int8 frameTable[] = {4, 5, 4, 5, 4, 5, 0, 1, 4, 5,
 								4, 4, 6, 4, 8, 1, 9, 4, -1};
 
-	if (_charSayUnk1 < 0)
+	if (_talkingCharNum < 0)
 		return;
 
-	_charSayUnk4 = frameTable[currentFrame];
+	_currHeadShape = frameTable[currentFrame];
 	currentFrame++;
 
 	if (frameTable[currentFrame] == -1)
 		currentFrame = 0;
 
 	animRefreshNPC(0);
-	animRefreshNPC(_charSayUnk1);
+	animRefreshNPC(_talkingCharNum);
 }
 
 void KyraEngine::timerSetFlags1(int timerNum) {
-	debug(9, "KyraEngine::timerSetFlags(%i)", timerNum);
+	debug(9, "timerSetFlags(%i)", timerNum);
 	if (_currentCharacter->sceneId == 0x1C)
 		return;
 
@@ -4376,29 +4421,43 @@
 	}
 }
 
+void KyraEngine::timerFadeText(int timerNum) {
+	debug(9, "timerFadeText(%i)", timerNum);
+	_fadeText = true;
+}
+
+void KyraEngine::setTextFadeTimerCountdown(int16 countdown) {
+	debug(9, "setTextFadeTimerCountdown(%i)", countdown);
+	//if (countdown == -1)
+		//countdown = 32000;
+
+	setTimerCountdown(31, countdown*60);
+}
+
 void KyraEngine::timerSetFlags2(int timerNum) {
+	debug(9, "timerSetFlags2(%i)", timerNum);
 	if (!((uint32*)(_flagsTable+0x2D))[timerNum])
 		((uint32*)(_flagsTable+0x2D))[timerNum] = 1;	
 }
 
 void KyraEngine::timerCheckAnimFlag1(int timerNum) {
-	debug(9, "KyraEngine::timerCheckAnimFlag1(%i)", timerNum);
+	debug(9, "timerCheckAnimFlag1(%i)", timerNum);
 	if (_brandonStatusBit & 0x20) {
-		checkSpecialAnimFlags();
+		checkAmuletAnimFlags();
 		setTimerCountdown(18, -1);
 	}
 }
 
 void KyraEngine::timerCheckAnimFlag2(int timerNum) {
-	debug(9, "KyraEngine::timerCheckAnimFlag1(%i)", timerNum);
+	debug(9, "timerCheckAnimFlag1(%i)", timerNum);
 	if (_brandonStatusBit & 0x2) {
-		checkSpecialAnimFlags();
+		checkAmuletAnimFlags();
 		setTimerCountdown(14, -1);
 	}
 }
 
-void KyraEngine::checkSpecialAnimFlags() {
-	debug(9, "KyraEngine::checkSpecialAnimFlags()");
+void KyraEngine::checkAmuletAnimFlags() {
+	debug(9, "checkSpecialAnimFlags()");
 	if (_brandonStatusBit & 2) {
 		warning("STUB: playSpecialAnim1");
 		// XXX
@@ -4413,13 +4472,15 @@
 }
 
 void KyraEngine::timerRedrawAmulet(int timerNum) {
+	debug(9, "timerRedrawAmulet(%i)", timerNum);
 	if (queryGameFlag(241)) {
 		drawAmulet();
-		setTimerCountdown(0x13, -1);
+		setTimerCountdown(19, -1);
 	}
 }
 
 void KyraEngine::drawAmulet() {
+	debug(9, "drawAmulet()");
 	static const int16 amuletTable1[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x150, 0x155, 0x15A, 0x15F, 0x164, 0x145, -1};
 	static const int16 amuletTable3[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x14F, 0x154, 0x159, 0x15E, 0x163, 0x144, -1};
 	static const int16 amuletTable2[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x152, 0x157, 0x15C, 0x161, 0x166, 0x147, -1};
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvmcvs/kyra/kyra.h scummvm/kyra/kyra.h
--- ./scummvmcvs/kyra/kyra.h	2005-12-08 18:19:18.000000000 +0100
+++ scummvm/kyra/kyra.h	2005-12-08 23:11:05.000000000 +0100
@@ -142,17 +142,19 @@
 struct ScriptState;
 struct ScriptData;
 class ScriptHelper;
+class Debugger;
 class KyraEngine;
 
 struct Timer {
 	bool active;
-	int16 countdown;
+	int32 countdown;
 	uint32 nextRun;
 	void (KyraEngine::*func)(int timerNum);
 };
 
 class KyraEngine : public Engine {
 	friend class MusicPlayer;
+	friend class Debugger;
 public:
 
 	enum {
@@ -202,10 +204,12 @@
 	void printTalkTextMessage(const char *text, int x, int y, uint8 color, int srcPage, int dstPage);
 	void restoreTalkTextMessageBkgd(int srcPage, int dstPage);
 	void drawSentenceCommand(char *sentence, int unk1);
+	void updateSentenceCommand(char *str1, char *str2, int unk1);
+	void updateTextFade();
 
 	void updateGameTimers();
 	void clearNextEventTickCount();
-	void setTimerCountdown(uint8 timer, int16 countdown);
+	void setTimerCountdown(uint8 timer, int32 countdown);
 	int16 getTimerDelay(uint8 timer);
 	void enableTimer(uint8 timer);
 	void disableTimer(uint8 timer);
@@ -532,10 +536,11 @@
 	void timerSetFlags2(int timerNum);
 	void timerCheckAnimFlag1(int timerNum);
 	void timerCheckAnimFlag2(int timerNum);
-	void checkSpecialAnimFlags();
+	void checkAmuletAnimFlags();
 	void timerRedrawAmulet(int timerNum);
+	void timerFadeText(int timerNum);
 	void drawAmulet();
-
+	void setTextFadeTimerCountdown(int16 countdown);
 	uint8 _game;
 	bool _fastMode;
 	bool _quitFlag;
@@ -605,10 +610,13 @@
 	int _lastFindWayRet;
 	int *_movFacingTable;
 	
-	int8 _charSayUnk1;
+	int8 _talkingCharNum;
 	int8 _charSayUnk2;
 	int8 _charSayUnk3;
-	int8 _charSayUnk4;
+	int8 _currHeadShape;
+	uint8 _currSentenceColor[3];
+	int8 _startSentencePalIndex;
+	bool _fadeText;
 
 	uint8 _configTalkspeed;
 	AnimObject *_objectQueue;
@@ -626,6 +634,7 @@
 	SeqPlayer *_seq;
 	Sprites *_sprites;
 	ScriptHelper *_scriptInterpreter;
+	Debugger *_debugger;
 	
 	ScriptState *_scriptMain;
 	ScriptData *_npcScriptData;
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvmcvs/kyra/module.mk scummvm/kyra/module.mk
--- ./scummvmcvs/kyra/module.mk	2005-10-06 13:57:02.000000000 +0200
+++ scummvm/kyra/module.mk	2005-12-05 11:56:17.000000000 +0100
@@ -10,7 +10,8 @@
 	kyra/sound.o \
 	kyra/staticres.o \
 	kyra/sprites.o \
-	kyra/wsamovie.o
+	kyra/wsamovie.o \
+	kyra/debugger.o
 
 MODULE_DIRS += \
 	kyra
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvmcvs/kyra/script_v1.cpp scummvm/kyra/script_v1.cpp
--- ./scummvmcvs/kyra/script_v1.cpp	2005-12-08 18:19:18.000000000 +0100
+++ scummvm/kyra/script_v1.cpp	2005-12-08 23:16:46.000000000 +0100
@@ -573,7 +573,8 @@
 
 int KyraEngine::cmd_pauseSeconds(ScriptState *script) {
 	debug(3, "cmd_pauseSeconds(0x%X) (%d)", script, stackPos(0));
-	delay(stackPos(0)*1000);
+	if (stackPos(0) > 0)
+		delay(stackPos(0)*1000);
 	return 0;
 }
 
@@ -600,7 +601,7 @@
 
 int KyraEngine::cmd_forceBrandonToNormal(ScriptState *script) {
 	debug(3, "cmd_forceBrandonToNormal(0x%X) ()", script);
-	setTimer19();
+	checkAmuletAnimFlags();
 	return 0;
 }
 
@@ -657,8 +658,7 @@
 		if (wsaFrame >= wsa_getNumFrames(_wsaObjects[wsaIndex]))
 			running = false;
 		
-		// XXX
-		waitTicks(waitTime);
+		delay(waitTime * _tickLength);
 		if (worldUpdate) {
 			_sprites->updateSceneAnims();
 			updateAllObjectShapes();
@@ -680,10 +680,7 @@
 	int wsaIndex = stackPos(4);
 	_screen->hideMouse();
 	wsa_play(_wsaObjects[wsaIndex], frame, xpos, ypos, 0);
-	// XXX
-	waitTicks(waitTime);
-	_sprites->updateSceneAnims();
-	updateAllObjectShapes();
+	delay(waitTime * _tickLength);
 	_screen->updateScreen();
 	_screen->showMouse();
 	return 0;
@@ -878,8 +875,7 @@
 	
 	_screen->hideMouse();
 	wsa_play(_wsaObjects[wsaIndex], frame, xpos, ypos, 2);
-	// XXX
-	waitTicks(waitTime);
+	delay(waitTime*_tickLength);
 	_sprites->updateSceneAnims();
 	updateAllObjectShapes();
 	_screen->showMouse();
@@ -906,20 +902,16 @@
 			int frame = startFrame;
 			while (endFrame >= frame) {
 				wsa_play(_wsaObjects[wsaIndex], frame, xpos, ypos, 0);
-				// XXX
-				waitTicks(waitTime);
-				_sprites->updateSceneAnims();
-				updateAllObjectShapes();
+				delay(waitTime * _tickLength);
+				_screen->updateScreen();
 				++frame;
 			}
 		} else {
 			int frame = endFrame;
 			while (startFrame <= frame) {
 				wsa_play(_wsaObjects[wsaIndex], frame, xpos, ypos, 0);
-				// XXX
-				waitTicks(waitTime);
-				_sprites->updateSceneAnims();
-				updateAllObjectShapes();
+				delay(waitTime * _tickLength);
+				_screen->updateScreen();
 				--frame;
 			}
 		}
@@ -1128,7 +1120,7 @@
 			updateMousePointer();
 			updateGameTimers();
 			updateAllObjectShapes();
-			// XXX processPalette();
+			updateTextFade();
 			if ((nextFrame - _system->getMillis()) >= 10)
 				delay(10);
 		}
@@ -1497,8 +1489,8 @@
 }
 
 int KyraEngine::cmd_protectCommandLine(ScriptState *script) {
-	warning("STUB: cmd_protectCommandLine");
-	return 0;
+	debug(3, "cmd_protectCommandLine(0x%X) (%d)", script, stackPos(0));
+	return stackPos(0);
 }
 
 int KyraEngine::cmd_pauseMusicSeconds(ScriptState *script) {
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvmcvs/kyra/sprites.cpp scummvm/kyra/sprites.cpp
--- ./scummvmcvs/kyra/sprites.cpp	2005-11-19 00:55:31.000000000 +0100
+++ scummvm/kyra/sprites.cpp	2005-12-08 22:36:47.000000000 +0100
@@ -344,7 +344,7 @@
 				data += 2;
 				debug(5, "func: Play sound");
 				debug(5, "Sound index %i", READ_LE_UINT16(data));
-				_engine->snd_playSoundEffect(READ_LE_UINT16(data));
+				//_engine->snd_playVoiceFile(READ_LE_UINT16(data));
 				data += 2;
 				break;
 			case 0xFFB1:
@@ -363,8 +363,8 @@
 				data += 2;
 				debug(5, "Percentage %i", READ_LE_UINT16(data));
 				rndNr = _rnd.getRandomNumber(100);
-				if (rndNr <= READ_LE_UINT16(data))
-					_engine->snd_playSoundEffect(sound);
+				//if (rndNr <= READ_LE_UINT16(data))
+					//_engine->snd_playVoiceFile(sound);
 				data += 2;
 				break;
 			case 0xFFA7:
