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

athrxx at users.sourceforge.net athrxx at users.sourceforge.net
Sun Feb 1 20:27:01 CET 2009


Revision: 36178
          http://scummvm.svn.sourceforge.net/scummvm/?rev=36178&view=rev
Author:   athrxx
Date:     2009-02-01 19:27:01 +0000 (Sun, 01 Feb 2009)

Log Message:
-----------


Modified Paths:
--------------
    scummvm/trunk/engines/kyra/gui.h
    scummvm/trunk/engines/kyra/gui_lol.cpp
    scummvm/trunk/engines/kyra/items_lol.cpp
    scummvm/trunk/engines/kyra/kyra_v1.cpp
    scummvm/trunk/engines/kyra/lol.cpp
    scummvm/trunk/engines/kyra/lol.h
    scummvm/trunk/engines/kyra/module.mk
    scummvm/trunk/engines/kyra/scene_lol.cpp
    scummvm/trunk/engines/kyra/screen_lol.cpp
    scummvm/trunk/engines/kyra/screen_lol.h
    scummvm/trunk/engines/kyra/script_lol.cpp
    scummvm/trunk/engines/kyra/script_tim.cpp
    scummvm/trunk/engines/kyra/script_tim.h
    scummvm/trunk/engines/kyra/sound.cpp
    scummvm/trunk/engines/kyra/sound.h
    scummvm/trunk/engines/kyra/staticres.cpp

Added Paths:
-----------
    scummvm/trunk/engines/kyra/gui_lol.h
    scummvm/trunk/engines/kyra/text_lol.cpp
    scummvm/trunk/engines/kyra/text_lol.h

Modified: scummvm/trunk/engines/kyra/gui.h
===================================================================
--- scummvm/trunk/engines/kyra/gui.h	2009-02-01 14:56:19 UTC (rev 36177)
+++ scummvm/trunk/engines/kyra/gui.h	2009-02-01 19:27:01 UTC (rev 36178)
@@ -158,6 +158,13 @@
 
 	// utilities for thumbnail creation
 	virtual void createScreenThumbnail(Graphics::Surface &dst) = 0;
+
+	// LOL tim player specific
+	virtual void drawDialogueBox(int numStr, const char *s1, const char *s2, const char *s3) {}
+	virtual uint16 processDialogue() { return 0; }
+	virtual void update() {}
+	virtual char *getTableString(int id) { return 0; }
+
 protected:
 	KyraEngine_v1 *_vm;
 	Screen *_screen;

Modified: scummvm/trunk/engines/kyra/gui_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/gui_lol.cpp	2009-02-01 14:56:19 UTC (rev 36177)
+++ scummvm/trunk/engines/kyra/gui_lol.cpp	2009-02-01 19:27:01 UTC (rev 36178)
@@ -25,6 +25,7 @@
 
 #include "kyra/lol.h"
 #include "kyra/screen_lol.h"
+#include "kyra/gui_lol.h"
 
 namespace Kyra {
 
@@ -35,7 +36,7 @@
 		// copy compass shape
 		static const int cx[] = { 112, 152, 224 };
 		_screen->copyRegion(cx[_lang], 32, 288, 0, 32, 32, 2, 2, Screen::CR_NO_P_CHECK);
-		_updateUnk2 = -1;
+		_compassDirection = -1;
 	}
 
 	if (_screen->_drawGuiFlag & 0x1000)
@@ -51,28 +52,27 @@
 	}
 
 	if (_screen->_drawGuiFlag & 0x800)
-		turnOnLamp();
+		resetLampStatus();
 
-	//mouseDimUnk()
 	gui_drawScene(2);
 
 	gui_drawAllCharPortraitsWithStats();
 	gui_drawInventory();
 	gui_drawMoneyBox(_screen->_curPage);
+
 	_screen->setCurPage(cp);
 	_screen->hideMouse();
 	_screen->copyPage(2, 0);
-	//mouseDimUnk
 	_screen->showMouse();
 }
 
 void LoLEngine::gui_drawScene(int pageNum) {
-	if (/*_charFlagUnk == 1 && */_weaponsDisabled == false && _unkDrawLevelBool && _vcnBlocks)
+	if (!(_updateFlags & 1) && _weaponsDisabled == false && _unkDrawLevelBool && _vcnBlocks)
 		drawScene(pageNum);
 }
 
 void LoLEngine::gui_drawInventory() {
-	if (!_unkInventFlag || !_updateCharV6) {
+	if (!_hideControls || !_hideInventory) {
 		for (int i = 0; i < 9; i++)
 			gui_drawInventoryItem(i);
 	}
@@ -89,8 +89,8 @@
 
 	_screen->hideMouse();
 	_screen->drawShape(_screen->_curPage, _gameShapes[4], x, 179, 0, flag);
-	if (_inventoryItemIndex[index])
-		_screen->drawShape(_screen->_curPage, getItemIconShapePtr(_inventoryItemIndex[index]), x + 1, 180, 0, 0);
+	if (_inventory[index])
+		_screen->drawShape(_screen->_curPage, getItemIconShapePtr(_inventory[index]), x + 1, 180, 0, 0);
 	_screen->showMouse();
 }
 
@@ -134,13 +134,13 @@
 }
 
 void LoLEngine::gui_drawCharPortraitWithStats(int charNum) {
-	if (!(_characters[charNum].flags & 1) || _charFlagUnk & 2)
+	if (!(_characters[charNum].flags & 1) || _updateFlags & 2)
 		return;
 
 	Screen::FontId tmpFid = _screen->setFont(Screen::FID_6_FNT);
 	int cp = _screen->setCurPage(6);
 
-	gui_drawPortraitBox(0, 0, 66, 34, 1, 1, -1);
+	gui_drawBox(0, 0, 66, 34, 1, 1, -1);
 	gui_drawCharFaceShape(0, 0, 1, _screen->_curPage);
 
 	gui_drawLiveMagicBar(33, 32, _characters[charNum].magicPointsCur, 0, _characters[charNum].magicPointsMax, 5, 32, 162, 1, 0);
@@ -165,22 +165,22 @@
 			_screen->drawGridBox(44, (spellLevels << 3) + 1, 22, 32 - (spellLevels << 3), 1);
 	} else {
 		// magic submenu closed
-		int shapeNum = -1;		
-		/*if (_characters[charNum].items[0]) {
-			int u8 = _itemProperties[_itemsInPlay[_characters[charNum].items[0]].itemPropertyIndex].unk8 & 0xff;
-			if (u8 > shapeNum)
-				shapeNum = u8;
-		}*/
+		int handIndex = 0;		
+		if (_characters[charNum].items[0]) {
+			if (_itemProperties[_itemsInPlay[_characters[charNum].items[0]].itemPropertyIndex].unk8 != -1)
+				handIndex = _itemsInPlay[_characters[charNum].items[0]].itemPropertyIndex;
+		}
+		
+		handIndex =  _gameShapeMap[_itemProperties[handIndex].shpIndex << 1];
+		if (handIndex == 0x5a) { // draw raceClassSex specific hand shape
+			handIndex = _characters[charNum].raceClassSex - 1;
+			if (handIndex < 0)
+				handIndex = 0;
+			handIndex += 68;
+		}
 
-		shapeNum = _gameShapeMap[_itemProperties[_itemsInPlay[_characters[charNum].items[0]].itemPropertyIndex].shpIndex];
-		if (shapeNum == 0x5a) { // draw raceClassSex specific hand shape
-			shapeNum = _characters[charNum].raceClassSex - 1;
-			if (shapeNum < 0)
-				shapeNum = 0;
-			shapeNum += 68;
-		}
 		// draw hand/weapon
-		_screen->drawShape(_screen->_curPage, _gameShapes[shapeNum], 44, 0, 0, 0);
+		_screen->drawShape(_screen->_curPage, _gameShapes[handIndex], 44, 0, 0, 0);
 		// draw magic symbol
 		_screen->drawShape(_screen->_curPage, _gameShapes[72 + _characters[charNum].field_41], 44, 17, 0, 0);
 
@@ -189,7 +189,7 @@
 	}	
 
 	uint16 f = _characters[charNum].flags & 0x314C;
-	if ((f == 0 && (f != 4 || _characters[charNum].weaponHit == 0)) || _weaponsDisabled)
+	if ((f == 0 && _weaponsDisabled) || (f && (f != 4 || _characters[charNum].weaponHit == 0 || _weaponsDisabled)))
 		_screen->drawGridBox(44, 0, 22, 34, 1);
 
 	if (_characters[charNum].weaponHit) {
@@ -202,7 +202,7 @@
 	if (!cp)
 		_screen->hideMouse();
 
-	uint8 col = (charNum != _unkDrawPortraitIndex || countActiveCharacters() == 1) ? 1 : 212;
+	uint8 col = (charNum != _selectedCharacter || countActiveCharacters() == 1) ? 1 : 212;
 	_screen->drawBox(0, 0, 65, 33, col);
 
 	_screen->copyRegion(0, 0, _activeCharsXpos[charNum], 143, 66, 34, _screen->_curPage, cp, Screen::CR_NO_P_CHECK);
@@ -214,7 +214,7 @@
 	_screen->setFont(tmpFid);
 }
 
-void LoLEngine::gui_drawPortraitBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor) {
+void LoLEngine::gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor) {
 	w--; h--;
 	if (fillColor != -1)
 		_screen->fillRect(x + 1, y + 1, x + w - 1, y + h - 1, fillColor);
@@ -334,12 +334,12 @@
 	if (!(_screen->_drawGuiFlag & 0x4000))
 		return;
 
-	if (_updateUnk2 == -1) {
+	if (_compassDirection == -1) {
 		_compassDirectionIndex = -1;
-		_updateUnk2 = _currentDirection << 6;
+		_compassDirection = _currentDirection << 6;
 	}
 
-	int t = ((_updateUnk2 + 4) >> 3) & 0x1f;
+	int t = ((_compassDirection + 4) >> 3) & 0x1f;
 
 	if (t == _compassDirectionIndex)
 		return;
@@ -352,12 +352,502 @@
 	const CompassDef *c = &_compassDefs[t];
 
 	_screen->drawShape(_screen->_curPage, _gameShapes[22 + _lang], 294, 3, 0, 0);
-	_screen->drawShape(_screen->_curPage, _gameShapes[25 + c->shapeIndex], 298 + c->x, c->y + 9, 0, c->flags | 0x300);
+	_screen->drawShape(_screen->_curPage, _gameShapes[25 + c->shapeIndex], 298 + c->x, c->y + 9, 0, c->flags | 0x300, _screen->_paletteOverlay1, 1);
 	_screen->drawShape(_screen->_curPage, _gameShapes[25 + c->shapeIndex], 299 + c->x, c->y + 8, 0, c->flags);
 
 	if (!_screen->_curPage)
 		_screen->showMouse();
 }
 
+int LoLEngine::gui_enableControls() {
+	_floatingMouseArrowControl = 0;
+
+	if (!_hideControls) {
+		for (int i = 76; i < 85; i++)
+			gui_disableArrowButton(i, 2);
+	}
+
+	gui_toggleFightButtons(false);
+	return 1;
+}
+
+int LoLEngine::gui_disableControls(int controlMode) {
+	if (_hideControls)
+		return 0;
+
+	_floatingMouseArrowControl = (controlMode & 2) ? 2 : 1;
+
+	gui_toggleFightButtons(true);
+
+	for (int i = 76; i < 85; i++)
+		gui_disableArrowButton(i, ((controlMode & 2) && (i > 78)) ? 2 : 3);
+
+	return 1;
+}
+
+void LoLEngine::gui_disableArrowButton(int shapeIndex, int mode) {
+	static const int16 arrowButtonX[] = { 0x000C, 0x0021, 0x0122, 0x000C, 0x0021, 0x0036, 0x000C, 0x0021, 0x0036 };
+	static const int16 arrowButtonY[] = { 0x00B4, 0x00B4, 0x0020, 0x0084, 0x0084, 0x0084, 0x0096, 0x0096, 0x0096 };
+
+	if (shapeIndex == 78 && !(_screen->_drawGuiFlag & 0x1000))
+		return;
+
+	if (_hideControls && _hideInventory)
+		return;
+
+	if (mode == 0)
+		shapeIndex = _lastArrowButtonShape;
+
+	int pageNum = 0;
+
+	int16 x1 = arrowButtonX[shapeIndex - 76];
+	int16 y1 = arrowButtonY[shapeIndex - 76];
+	int16 x2 = 0;
+	int16 y2 = 0;
+	uint32 t = 0;
+
+	switch (mode) {
+		case 1:
+			mode = 0x100;
+			_lastArrowButtonShape = shapeIndex;
+			break;
+
+		case 0:
+			if (!_lastArrowButtonShape)
+				return;
+
+			t = _system->getMillis();
+			if (_arrowButtonTimer > t)
+				delay(_arrowButtonTimer - t);
+
+		case 2:
+			mode = 0;
+			_lastArrowButtonShape = 0;
+			break;
+
+		case 3:
+			mode = 0;
+			_lastArrowButtonShape = 0;
+			pageNum = 6;
+
+			x2 = x1;
+			y2 = y1;
+			x1 = 0;
+			y1 = 0;
+			break;
+
+		default:
+			break;
+	}
+
+	_screen->drawShape(pageNum, _gameShapes[shapeIndex], x1, y1, 0, mode, _screen->_paletteOverlay1, 1);
+	
+	if (pageNum != 6)
+		return;
+
+	int cp = _screen->setCurPage(6);
+
+	_screen->drawGridBox(x1, y1, _gameShapes[shapeIndex][3], _gameShapes[shapeIndex][2], 1);
+	_screen->copyRegion(x1, y1, x2, y2, _gameShapes[shapeIndex][3], _gameShapes[shapeIndex][2], pageNum, 0, Screen::CR_NO_P_CHECK);
+
+	_screen->setCurPage(cp);
+
+	_arrowButtonTimer = _system->getMillis() + 6 * _tickLength;
+}
+
+void LoLEngine::gui_toggleFightButtons(bool disable) {
+	for (int i = 0; i < 3; i++) {
+		if (!(_characters[i].flags & 1))
+			continue;
+
+		if (disable)
+			_characters[i].flags |= 0x2000;
+		else
+			_characters[i].flags &= 0xdfff;
+
+		if (disable && !textEnabled()) {
+			int u = _selectedCharacter;
+			_selectedCharacter = 99;
+			int f = _updateFlags;
+			_updateFlags &= 0xfffd;
+
+			gui_drawCharPortraitWithStats(i);
+
+			_updateFlags = f;
+			_selectedCharacter = u;
+		} else {
+			gui_drawCharPortraitWithStats(i);
+		}
+	}	
+}
+
+int LoLEngine::clickedUpArrow(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedDownArrow(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedLeftArrow(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedRightArrow(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedTurnLeftArrow(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedTurnRightArrow(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedAttackButton(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedMagicButton(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedUnk9(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedScreen(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedPortraitLeft(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedLiveMagicBarsLeft(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedPortraitEtcRight(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedUnk14(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedUnk15(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedUnk16(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedUnk17(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedInventorySlot(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedInventoryScroll(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedUnk20(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedUnk21(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedScroll(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedUnk23(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedUnk24(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedUnk25(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedOptions(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedRestParty(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedUnk28(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedUnk29(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedUnk30(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedUnk31(Button *button) {
+	return 1;
+}
+
+int LoLEngine::clickedUnk32(Button *button) {
+	return 1;
+}
+
+GUI_LoL::GUI_LoL(LoLEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) {
+	memset(_dialogueButtonString, 0, 3 * sizeof(const char*));
+	_dialogueButtonPosX = _dialogueButtonPosY = _dialogueNumButtons = _dialogueButtonXoffs = _dialogueHighlightedButton = 0;
+	_scrollUpFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::scrollUp);
+	_scrollDownFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::scrollDown);
+}
+
+int GUI_LoL::processButtonList(Button *list, uint16 inputFlag, int8 mouseWheel) {
+	if ((inputFlag & 0xFF) == 199)
+		_pressFlag = true;
+	else if ((inputFlag & 0xFF) == 200)
+		_pressFlag = false;
+
+	int returnValue = 0;
+	while (list) {
+		/*if (list->flags & 8) {
+			list = list->nextButton;
+			continue;
+		}
+
+		if (mouseWheel && list->mouseWheel == mouseWheel && list->buttonCallback) {
+			if ((*list->buttonCallback.get())(list))
+				break;
+		}
+
+		int x = list->x;
+		int y = list->y;
+		assert(_screen->getScreenDim(list->dimTableIndex) != 0);
+
+		if (x < 0)
+			x += _screen->getScreenDim(list->dimTableIndex)->w << 3;
+		x += _screen->getScreenDim(list->dimTableIndex)->sx << 3;
+
+		if (y < 0)
+			y += _screen->getScreenDim(list->dimTableIndex)->h;
+		y += _screen->getScreenDim(list->dimTableIndex)->sy;
+
+		if (_vm->_mouseX >= x && _vm->_mouseY >= y && x + list->width >= _vm->_mouseX && y + list->height >= _vm->_mouseY) {
+			int processMouseClick = 0;
+			if (list->flags & 0x400) {
+				if ((inputFlag & 0xFF) == 199 || _pressFlag) {
+					if (!(list->flags2 & 1)) {
+						list->flags2 |= 1;
+						list->flags2 |= 4;
+						processButton(list);
+						_screen->updateScreen();
+						inputFlag = 0;
+					}
+				} else if ((inputFlag & 0xFF) == 200) {
+					if (list->flags2 & 1) {
+						list->flags2 &= 0xFFFE;
+						processButton(list);
+						processMouseClick = 1;
+						inputFlag = 0;
+					}
+				}
+			}
+
+			if (processMouseClick) {
+				if (list->buttonCallback) {
+					if ((*list->buttonCallback.get())(list))
+						break;
+				}
+			}
+		} else {
+			if (list->flags2 & 1) {
+				list->flags2 &= 0xFFFE;
+				processButton(list);
+			}
+
+			if (list->flags2 & 4) {
+				list->flags2 &= 0xFFFB;
+				processButton(list);
+				_screen->updateScreen();
+			}
+		}
+
+		list = list->nextButton;*/
+	}
+
+	if (!returnValue)
+		returnValue = inputFlag & 0xFF;
+
+	return returnValue;
+}
+
+void GUI_LoL::drawDialogueBox(int numStr, const char *s1, const char *s2, const char *s3) {
+	if (numStr == 1 && _vm->_speechFlag) {
+		_screen->setScreenDim(5);
+		_dialogueButtonString[0] = _dialogueButtonString[1] = _dialogueButtonString[2] = 0;
+	} else {
+		_screen->setScreenDim(5);
+		_dialogueNumButtons = numStr;
+		_dialogueButtonString[0] = s1;
+		_dialogueButtonString[1] = s2;
+		_dialogueButtonString[2] = s3;
+		_dialogueHighlightedButton = 0;
+
+		const ScreenDim *d = _screen->getScreenDim(5);
+		_dialogueButtonPosY = d->sy + d->h - 9;
+
+		if (numStr == 1) {
+			_dialogueButtonXoffs = 0;
+			_dialogueButtonPosX = d->sx + d->w - 77;			
+		} else {			
+			_dialogueButtonXoffs = d->w / numStr;
+			_dialogueButtonPosX = d->sx + (_dialogueButtonXoffs >> 1) - 37;
+		}
+
+		drawDialogueButtons();
+	}
+
+	if (!_vm->shouldQuit())
+		_vm->removeInputTop();
+}
+
+void GUI_LoL::drawDialogueButtons() {
+	int cp = _screen->setCurPage(0);
+	Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+
+	int x = _dialogueButtonPosX;
+
+	for (int i = 0; i < _dialogueNumButtons; i++) {
+		_vm->gui_drawBox(x, _dialogueButtonPosY, 74, 9, 136, 251, -1);
+		_screen->printText(_dialogueButtonString[i], x + 37 - (_screen->getTextWidth(_dialogueButtonString[i])) / 2,
+			_dialogueButtonPosY + 2, _dialogueHighlightedButton == i ? 144 : 254, 0);
+		x += _dialogueButtonXoffs;
+	}
+	_screen->setFont(of);
+	_screen->setCurPage(cp);
+}
+
+uint16 GUI_LoL::processDialogue() {
+	int df = _dialogueHighlightedButton;
+	int res = 0;
+	int x = _dialogueButtonPosX;
+
+	for (int i = 0; i < _dialogueNumButtons; i++) {
+		if (_vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, x, _dialogueButtonPosY, x + 74, _dialogueButtonPosY + 9)) {
+			_dialogueHighlightedButton = i;
+			break;
+		}
+		x += _dialogueButtonXoffs;
+	}
+
+	if (_dialogueNumButtons == 0) {
+		int e = _vm->checkInput(0, false) & 0xCF;
+		_vm->removeInputTop();
+		
+		if (e == 200) {
+			_vm->snd_dialogueSpeechUpdate(1);
+			//_dlgTimer = 0;
+		}
+
+		if (_vm->snd_characterSpeaking() != 2) {
+			//if (_dlgTimer < _system->getMillis()) {
+				res = 1;
+				if (!_vm->shouldQuit())
+					_vm->removeInputTop();
+			//}
+		}
+	} else {
+		int e = _vm->checkInput(0, false);
+		_vm->removeInputTop();
+		switch (e) {
+			case 100:
+			case 101:
+				_vm->snd_dialogueSpeechUpdate(1);
+				//_dlgTimer = 0;
+				res = _dialogueHighlightedButton + 1;
+				break;
+
+			case 110:
+			case 111:
+				if (_dialogueNumButtons > 1 && _dialogueHighlightedButton > 0)
+					_dialogueHighlightedButton--;
+				break;
+
+			case 112:
+			case 113:
+				if (_dialogueNumButtons > 1 && _dialogueHighlightedButton < (_dialogueNumButtons - 1))
+					_dialogueHighlightedButton++;
+				break;
+
+			case 200:
+			case 300:
+				x = _dialogueButtonPosX;
+				
+				for (int i = 0; i < _dialogueNumButtons; i++) {
+					if (_vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, x, _dialogueButtonPosY, x + 74, _dialogueButtonPosY + 9)) {
+						_dialogueHighlightedButton = i;
+						res = _dialogueHighlightedButton + 1;
+						break;
+					}
+					x += _dialogueButtonXoffs;
+				}
+
+				break;
+
+			default:
+				break;
+		}
+	}
+
+	if (df != _dialogueHighlightedButton)
+		drawDialogueButtons();
+	
+	if (res == 0)
+		return 0;
+
+	_vm->updatePortraits();
+
+	if (!_vm->textEnabled() && _vm->_hideControls) {
+		_screen->setScreenDim(5);
+		const ScreenDim *d = _screen->getScreenDim(5);
+		_screen->hideMouse();
+		_screen->fillRect(d->sx, d->sy + d->h - 9, d->sx + d->w - 1, d->sy + d->h - 1, d->unkA);
+		_screen->showMouse();
+	} else {
+		const ScreenDim *d = _screen->_curDim;
+		_screen->hideMouse();
+		_screen->fillRect(d->sx, d->sy, d->sx + d->w - 2, d->sy + d->h - 1, d->unkA);
+		_screen->clearDim(4);
+		_screen->setScreenDim(4);
+		_screen->showMouse();
+		//_screen->setDialogueColumn(8, 0);
+		//_screen->setDialogueLine(8, 0);
+	}
+
+	return res;
+}
+
+char *GUI_LoL::getTableString(int id) {
+	return (char *) _vm->getLangString(id);
+}
+
+void GUI_LoL::update() {
+	_vm->update();
+}
+
 } // end of namespace Kyra
 

Added: scummvm/trunk/engines/kyra/gui_lol.h
===================================================================
--- scummvm/trunk/engines/kyra/gui_lol.h	                        (rev 0)
+++ scummvm/trunk/engines/kyra/gui_lol.h	2009-02-01 19:27:01 UTC (rev 36178)
@@ -0,0 +1,94 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef KYRA_GUI_LOL_H
+#define KYRA_GUI_LOL_H
+
+#include "kyra/gui.h"
+
+namespace Kyra {
+
+class LoLEngine;
+class Screen_LoL;
+
+class GUI_LoL : public GUI {
+	friend class LoLEngine;
+public:
+	GUI_LoL(LoLEngine *vm);
+
+	void initStaticData();
+
+	// button specific
+	void processButton(Button *button) {}
+	int processButtonList(Button *buttonList, uint16 inputFlags, int8 mouseWheel);
+
+	// utilities for thumbnail creation
+	void createScreenThumbnail(Graphics::Surface &dst) {}
+
+	// tim player specific
+	void drawDialogueBox(int numStr, const char *s1, const char *s2, const char *s3);
+	uint16 processDialogue();
+	void update();
+	char *getTableString(int id);
+
+private:
+	LoLEngine *_vm;
+	Screen_LoL *_screen;
+
+	bool _pressFlag;
+
+	int scrollUp(Button *button) { return 0; }
+	int scrollDown(Button *button) { return 0; }
+
+	Button *getButtonListData() { return 0; }
+	Button *getScrollUpButton() { return 0; }
+	Button *getScrollDownButton() { return 0; }
+
+	Button::Callback _scrollUpFunctor;
+	Button::Callback _scrollDownFunctor;
+	Button::Callback getScrollUpButtonHandler() const { return _scrollUpFunctor; }
+	Button::Callback getScrollDownButtonHandler() const { return _scrollDownFunctor; }
+
+	uint8 defaultColor1() const { return 0; }
+	uint8 defaultColor2() const { return 0; }
+
+	const char *getMenuTitle(const Menu &menu) { return 0; }
+	const char *getMenuItemTitle(const MenuItem &menuItem) { return 0; }
+	const char *getMenuItemLabel(const MenuItem &menuItem) { return 0; }
+
+	void drawDialogueButtons();
+
+	const char *_dialogueButtonString[3];
+	uint16 _dialogueButtonPosX;
+	uint16 _dialogueButtonPosY;
+	int _dialogueNumButtons;
+	uint16 _dialogueButtonXoffs;
+	int _dialogueHighlightedButton;
+};
+
+} // end of namespace Kyra
+
+#endif
+


Property changes on: scummvm/trunk/engines/kyra/gui_lol.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Modified: scummvm/trunk/engines/kyra/items_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/items_lol.cpp	2009-02-01 14:56:19 UTC (rev 36177)
+++ scummvm/trunk/engines/kyra/items_lol.cpp	2009-02-01 19:27:01 UTC (rev 36178)
@@ -62,8 +62,8 @@
 
 		if (redraw) {
 			gui_drawMoneyBox(6);
-			//if (credits)
-			//	TODO: delay/update
+			if (credits)
+				update();
 		}
 		credits -= t;
 	}
@@ -153,18 +153,18 @@
 	_itemsInPlay[itemIndex].shpCurFrame_flg |= 0x8000;
 }
 
-void *LoLEngine::cmzGetItemOffset(uint16 index) {
+CLevelItem *LoLEngine::findItem(uint16 index) {
 	if (index & 0x8000)
-		return &_lvlBuffer[index & 0x7fff];
+		return &_cLevelItems[index & 0x7fff];
 	else
-		return &_itemsInPlay[index];
+		return (CLevelItem *)&_itemsInPlay[index];
 }
 
-void LoLEngine::runItemScript(int reg1, int slot, int reg0, int reg3, int reg4) {
+void LoLEngine::runItemScript(int reg1, int item, int reg0, int reg3, int reg4) {
 	EMCState scriptState;
 	memset(&scriptState, 0, sizeof(EMCState));
 
-	uint8 func = slot ? _itemProperties[_itemsInPlay[slot].itemPropertyIndex].itemScriptFunc : 3;
+	uint8 func = item ? _itemProperties[_itemsInPlay[item].itemPropertyIndex].itemScriptFunc : 3;
 	if (func == 0xff)
 		return;
 
@@ -173,7 +173,7 @@
 
 	scriptState.regs[0] = reg0;
 	scriptState.regs[1] = reg1;
-	scriptState.regs[2] = slot;
+	scriptState.regs[2] = item;
 	scriptState.regs[3] = reg3;
 	scriptState.regs[4] = reg4;
 

Modified: scummvm/trunk/engines/kyra/kyra_v1.cpp
===================================================================
--- scummvm/trunk/engines/kyra/kyra_v1.cpp	2009-02-01 14:56:19 UTC (rev 36177)
+++ scummvm/trunk/engines/kyra/kyra_v1.cpp	2009-02-01 19:27:01 UTC (rev 36178)
@@ -257,6 +257,29 @@
 					_debugger->attach();
 				else if (event.kbd.keycode == 'q')
 					quitGame();
+			} else {
+				switch(event.kbd.keycode) {
+					case Common::KEYCODE_SPACE:
+						keys = 100;
+						break;
+					case Common::KEYCODE_RETURN:
+						keys = 101;
+						break;
+					case Common::KEYCODE_UP:
+						keys = 110;
+						break;
+					case Common::KEYCODE_RIGHT:
+						keys = 111;
+						break;
+					case Common::KEYCODE_DOWN:
+						keys = 112;
+						break;
+					case Common::KEYCODE_LEFT:
+						keys = 113;
+						break;
+					default:
+						break;
+				}
 			}
 			break;
 
@@ -275,6 +298,15 @@
 			breakLoop = true;
 			} break;
 
+		case Common::EVENT_RBUTTONDOWN:
+		case Common::EVENT_RBUTTONUP: {
+			Common::Point pos = getMousePos();
+			_mouseX = pos.x;
+			_mouseY = pos.y;
+			keys = (event.type == Common::EVENT_RBUTTONDOWN ? 299 : (300 | 0x800));
+			breakLoop = true;
+			} break;
+
 		case Common::EVENT_WHEELUP:
 			mouseWheel = -1;
 			break;

Modified: scummvm/trunk/engines/kyra/lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/lol.cpp	2009-02-01 14:56:19 UTC (rev 36177)
+++ scummvm/trunk/engines/kyra/lol.cpp	2009-02-01 19:27:01 UTC (rev 36178)
@@ -29,6 +29,9 @@
 #include "kyra/sound.h"
 #include "kyra/util.h"
 
+#include "sound/voc.h"
+#include "sound/audiostream.h"
+
 #include "common/endian.h"
 #include "base/version.h"
 
@@ -36,6 +39,8 @@
 
 LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(system, flags) {
 	_screen = 0;
+	_gui = 0;
+	_dlg = 0;
 
 	switch (_flags.lang) {
 	case Common::EN_ANY:
@@ -66,6 +71,7 @@
 	_lastMusicTrack = -1;
 	_lastSfxTrack = -1;
 	_curTlkFile = -1;
+	_lastSpeaker = _lastSpeechId = -1;
 
 	memset(_moneyColumnHeight, 0, 5);
 	_credits = 0;
@@ -73,9 +79,9 @@
 	_itemsInPlay = 0;
 	_itemProperties = 0;
 	_itemInHand = 0;
-	memset(_inventoryItemIndex, 0, 48);
+	memset(_inventory, 0, 48);
 	_inventoryCurItem = 0;
-	_unkInventFlag = 0;
+	_hideControls = 0;
 
 	_itemIconShapes = _itemShapes = _gameShapes = _thrownShapes = _iceShapes = _fireballShapes = 0;
 	_levelShpList = _levelDatList = 0;
@@ -87,16 +93,18 @@
 	_charSelection = -1;
 	_characters = 0;
 	_spellProperties = 0;
-	_charFlagUnk = 0;
+	_updateFlags = 0;
 	_selectedSpell = 0;
-	_updateCharNum = _updateCharV1 = _updateCharV2 = _updateCharV3 = _updateCharV4 = _updateCharV5 = _updateCharV6 = 0;
-	_updateCharTime = _updatePortraitNext = 0;
+	_updateCharNum = _updateCharV1 = _updateCharV2 = _updateCharV3 = _updateCharV4 = _restorePalette = _hideInventory = 0;
+	_palUpdateTimer = _updatePortraitNext = 0;
 	_lampStatusTimer = 0xffffffff;
 
 	_weaponsDisabled = false;
-	_unkDrawPortraitIndex = 0;
+	_lastArrowButtonShape = 0;
+	_arrowButtonTimer = 0;
+	_selectedCharacter = 0;
 	_unkFlag = 0;
-	_scriptBoolSkipExec = _boolScriptFuncDone = false;
+	_scriptBoolSkipExec = _sceneUpdateRequired = false;
 	_unkScriptByte = 0;
 	_currentDirection = 0;
 	_currentBlock = 0;
@@ -106,16 +114,16 @@
 	_wllShapeMap = 0;
 	_lvlShapeTop = _lvlShapeBottom = _lvlShapeLeftRight = 0;
 	_levelBlockProperties = 0;
-	_lvlBuffer = 0;
-	_lvl415 = 0;
+	_cLevelItems = 0;
+	_monsterProperties = 0;
 	_lvlBlockIndex = _lvlShapeIndex = 0;
 	_unkDrawLevelBool = true;
 	_vcnBlocks = 0;
 	_vcnShift = 0;
 	_vcnExpTable = 0;
 	_vmpPtr = 0;
-	_tlcTable2 = 0;
-	_tlcTable1 = 0;
+	_trueLightTable2 = 0;
+	_trueLightTable1 = 0;
 	_levelShapeProperties = 0;
 	_levelShapes = 0;
 	_blockDrawingBuffer = 0;
@@ -125,8 +133,10 @@
 	_lampOilStatus = _brightness = _lampStatusUnk = 0;
 	_tempBuffer5120 = 0;
 	_tmpData136 = 0;
-	_lvlBuffer = 0;
+	_cLevelItems = 0;
 	_unkGameFlag = 0;
+	_lastMouseRegion = 0;
+	_preSeq_X1 = _preSeq_Y1 = _preSeq_X2 = _preSeq_Y2 = 0;
 
 	_dscUnk1 = 0;
 	_dscShapeIndex = 0;
@@ -155,8 +165,16 @@
 	_curMusicFileIndex = -1;
 
 	_sceneDrawVar1 = _sceneDrawVar2 = _sceneDrawVar3 = _wllProcessFlag = 0;
-	_unkCmzU1 = _unkCmzU2 = 0;
+	_partyPosX = _partyPosY = 0;
 	_shpDmX = _shpDmY = _dmScaleW = _dmScaleH = 0;
+
+	_intFlag3 = 3;
+	_floatingMouseArrowControl = 0;
+
+	memset(_activeTim, 0, 10 * sizeof(TIM*));
+	memset(_activeVoiceFile, 0, sizeof(_activeVoiceFile));
+		
+	//_dlgAnimCallback = &TextDisplayer_LoL::portraitAnimation1;
 }
 
 LoLEngine::~LoLEngine() {
@@ -166,7 +184,9 @@
 	delete[] _levelLangFile;
 
 	delete _screen;
+	delete _gui;
 	delete _tim;
+	delete _dlg;
 
 	delete[]  _itemsInPlay;
 	delete[]  _itemProperties;
@@ -224,6 +244,11 @@
 		delete *i;
 	_timIntroOpcodes.clear();
 
+	for (Common::Array<const TIMOpcode*>::iterator i = _timIngameOpcodes.begin(); i != _timIngameOpcodes.end(); ++i)
+		delete *i;
+	_timIngameOpcodes.clear();
+
+
 	delete[] _wllVmpMap;
 	delete[] _wllShapeMap;
 	delete[] _wllBuffer3;
@@ -234,17 +259,17 @@
 	delete[] _lvlShapeLeftRight;
 	delete[] _tempBuffer5120;
 	delete[] _tmpData136;
-	delete[] _lvlBuffer;
+	delete[] _cLevelItems;
 	delete[] _levelBlockProperties;
-	delete[] _lvl415;
+	delete[] _monsterProperties;
 
 	delete[] _levelFileData;
 	delete[] _vcnExpTable;
 	delete[] _vcnBlocks;
 	delete[] _vcnShift;
 	delete[] _vmpPtr;
-	delete[] _tlcTable2;
-	delete[] _tlcTable1;
+	delete[] _trueLightTable2;
+	delete[] _trueLightTable1;
 	delete[] _levelShapeProperties;
 	delete[] _blockDrawingBuffer;
 	delete[] _sceneWindowBuffer;
@@ -271,6 +296,10 @@
 	return _screen;
 }
 
+GUI *LoLEngine::gui() const {
+	return _gui;
+}
+
 Common::Error LoLEngine::init() {
 	_screen = new Screen_LoL(this, _system);
 	assert(_screen);
@@ -279,9 +308,16 @@
 	KyraEngine_v1::init();
 	initStaticResource();
 
+	_gui = new GUI_LoL(this);
+	assert(_gui);
+	_gui->initStaticData();
+	initButtonList();
+
 	_tim = new TIMInterpreter(this, _screen, _system);
 	assert(_tim);
 
+	_dlg = new TextDisplayer_LoL(this, _screen);
+
 	_screen->setAnimBlockPtr(10000);
 	_screen->setScreenDim(0);
 
@@ -294,8 +330,7 @@
 	if (!_sound->init())
 		error("Couldn't init sound");
 
-	_unkAudioSpecOffs = 0x48;
-	_unkLangAudio = _lang ? true : false;
+	_speechFlag = speechEnabled() ? 0x48 : 0;
 
 	_wllVmpMap = new uint8[80];
 	memset(_wllVmpMap, 0, 80);
@@ -324,10 +359,10 @@
 
 	_levelBlockProperties = new LevelBlockProperty[1025];
 	memset(_levelBlockProperties, 0, 1025 * sizeof(LevelBlockProperty));
-	_lvlBuffer = new LVL[30];
-	memset(_lvlBuffer, 0, 30 * sizeof(LVL));
-	_lvl415 = new uint8[415];
-	memset(_lvl415, 0, 415);
+	_cLevelItems = new CLevelItem[30];
+	memset(_cLevelItems, 0, 30 * sizeof(CLevelItem));
+	_monsterProperties = new MonsterProperty[5];
+	memset(_monsterProperties, 0, 5 * sizeof(MonsterProperty));
 
 	_vcnExpTable = new uint8[128];
 	for (int i = 0; i < 128; i++)
@@ -363,11 +398,10 @@
 }
 
 Common::Error LoLEngine::go() {
-	if (!saveFileLoadable(0)) {
-		setupPrologueData(true);
+	setupPrologueData(true);
+
+	if (!saveFileLoadable(0))
 		showIntro();
-		setupPrologueData(false);
-	}
 
 	preInit();
 
@@ -400,7 +434,6 @@
 		case 1:		// Show intro
 			setupPrologueData(true);
 			showIntro();
-			setupPrologueData(true);
 			break;
 
 		case 2:		// "Lore of the Lands" (only CD version)
@@ -425,21 +458,27 @@
 	if (processSelection == 0) {
 		setupPrologueData(true);
 		_sound->loadSoundFile("LOREINTR");
-		_sound->playTrack(6);
+		_sound->playTrack(6);		
 		/*int character = */chooseCharacter();
 		_sound->playTrack(1);
 		_screen->fadeToBlack();
-		setupPrologueData(true);
 	}
 
+	setupPrologueData(false);
+
 	if (!shouldQuit() && (processSelection == 0 || processSelection == 3))
 		startup();
 
 	if (!shouldQuit() && processSelection == 0)
 		startupNew();
 
-	if (!shouldQuit() && (processSelection == 0 || processSelection == 3))
+	if (!shouldQuit() && (processSelection == 0 || processSelection == 3)) {
+		//_dlgAnimCallback = &TextDisplayer_LoL::portraitAnimation2;
+		_screen->_fadeFlag = 3;
+		_sceneUpdateRequired = true;
+		setUnkFlags(1);
 		runLoop();
+	}
 
 	return Common::kNoError;
 }
@@ -449,45 +488,31 @@
 void LoLEngine::preInit() {
 	debugC(9, kDebugLevelMain, "LoLEngine::preInit()");
 
-	if (!_res->loadFileList("FILEDATA.FDT"))
-		error("Couldn't load file list: 'FILEDATA.FDT'");
+	_res->loadPakFile("GENERAL.PAK");
+	if (_flags.isTalkie)
+		_res->loadPakFile("STARTUP.PAK");
 
 	_screen->loadFont(Screen::FID_9_FNT, "FONT9P.FNT");
 	_screen->loadFont(Screen::FID_6_FNT, "FONT6P.FNT");
 
-	uint8 *pal = _screen->getPalette(0);
-	memset(pal, 0, 768);
-	_screen->setScreenPalette(pal);
-
-	// TODO: We need to check if the SYSEX events of intro and ingame differ.
-	// If they differ, we really need to setup the proper ingame SYSEX when starting
-	// the game. But the proper place to do it would not be in this function.
-	/*if (_sound->getMusicType() == Sound::kMidiMT32 || _sound->getSfxType() == Sound::kMidiMT32) {
-		_sound->loadSoundFile("LOLSYSEX");
-		_sound->playTrack(0);
-
-		while (_sound->isPlaying() && !shouldQuit())
-			delay(10);
-	}*/
-
-	if (shouldQuit())
-		return;
-
-	_eventList.clear();
-
 	loadTalkFile(0);
 
 	char filename[32];
 	snprintf(filename, sizeof(filename), "LANDS.%s", _languageExt[_lang]);
 	_res->exists(filename, true);
 	_landsFile = _res->fileData(filename, 0);
-
-	initializeCursors();
+	loadItemIconShapes();
 }
 
-void LoLEngine::initializeCursors() {
-	debugC(9, kDebugLevelMain, "LoLEngine::initializeCursors()");
+void LoLEngine::loadItemIconShapes() {
+	debugC(9, kDebugLevelMain, "LoLEngine::loadItemIconShapes()");
 
+	if (_itemIconShapes) {
+		for (int i = 0; i < _numItemIconShapes; i++)
+			delete[]  _itemIconShapes[i];
+		delete[] _itemIconShapes;
+	}
+
 	_screen->loadBitmap("ITEMICN.SHP", 3, 3, 0);
 	const uint8 *shp = _screen->getCPagePtr(3);
 	_numItemIconShapes = READ_LE_UINT16(shp);
@@ -512,6 +537,12 @@
 	_screen->setMouseCursor(o, o, getItemIconShapePtr(_itemInHand));
 }
 
+bool LoLEngine::posWithinRect(int mouseX, int mouseY, int x1, int y1, int x2, int y2) {
+	if (mouseX < x1 || mouseX > x2 || mouseY < y1 || mouseY > y2)
+		return false;
+	return true;
+}
+
 uint8 *LoLEngine::getItemIconShapePtr(int index) {
 	int ix = _itemProperties[_itemsInPlay[index].itemPropertyIndex].shpIndex;
 	if (_itemProperties[_itemsInPlay[index].itemPropertyIndex].flags & 0x200)
@@ -585,6 +616,7 @@
 	memset(_screen->getPalette(1), 0, 0x300);
 	memset(_screen->getPalette(2), 0, 0x300);
 
+	loadItemIconShapes();
 	_screen->setMouseCursor(0, 0, _itemIconShapes[0x85]);
 
 	_screen->loadBitmap("ITEMSHP.SHP", 3, 3, 0);
@@ -629,19 +661,29 @@
 	runInitScript("ONETIME.INF", 0);
 	_emc->load("ITEM.INF", &_itemScript, &_opcodes);
 
-	_tlcTable1 = new uint8[256];
-	_tlcTable2 = new uint8[5120];
+	_trueLightTable1 = new uint8[256];
+	_trueLightTable2 = new uint8[5120];
 	
 	_loadSuppFilesFlag = 1;
 
+	_dlg->setAnimParameters("<MORE>", 10, 31, 0);
+	_dlg->setAnimFlag(true);
+
+	_screen->_dimLineCount = 0;
+
+	// reconfigure TIM player for ingame scripts
+	_tim->toggleDialogueSpeech(speechEnabled());
+	_tim->toggleRefresh(true);
+
 	setMouseCursorToItemInHand();
 }
 
 void LoLEngine::startupNew() {
 	_selectedSpell = 0;
-	_updateUnk2 = _compassDirectionIndex = -1;
-	/*
-	_unk3 = -1;*/
+	_compassUnk = 0;
+	_compassDirection = _compassDirectionIndex = -1;
+
+	_lastMouseRegion = -1;
 	_unkGameFlag |= 0x1B;
 	/*
 	_unk5 = 1;
@@ -651,11 +693,12 @@
 	_currentLevel = 1;
 
 	giveCredits(41, 0);
-	_inventoryItemIndex[0] = makeItem(0xd8, 0, 0);
-	_inventoryItemIndex[1] = makeItem(0xd9, 0, 0);
-	_inventoryItemIndex[2] = makeItem(0xda, 0, 0);
+	_inventory[0] = makeItem(0xd8, 0, 0);
+	_inventory[1] = makeItem(0xd9, 0, 0);
+	_inventory[2] = makeItem(0xda, 0, 0);
 
 	memset(_availableSpells, -1, 7);
+	_availableSpells[0] = 0;
 	setupScreenDims();
 
 	//memset(_unkWordArraySize8, 0x100, 8);
@@ -670,21 +713,80 @@
 	_screen->showMouse();
 }
 
+int LoLEngine::setUnkFlags(int unk) {
+	if (unk < 1 || unk > 14)
+		return 0;
+
+	int r = (_intFlag3 & (2 << unk)) ? 1 : 0;
+	_intFlag3 |= (2 << unk);
+
+	return r;
+}
+
+int LoLEngine::removeUnkFlags(int unk) {
+	if (unk < 1 || unk > 14)
+		return 0;
+
+	int r = (_intFlag3 & (2 << unk)) ? 1 : 0;
+	_intFlag3 &= ~(2 << unk);
+
+	return r;
+}
+
 void LoLEngine::runLoop() {
-	_screen->updateScreen();
+	setUnkFlags(2);
 
 	bool _runFlag = true;
+	_unkFlag |= 0x800;
+
 	while (!shouldQuit() && _runFlag) {
-		checkInput(0, false);
-		removeInputTop();
-		_screen->updateScreen();
-		_system->delayMillis(10);
+		if (_nextScriptFunc) {
+			runResidentScript(_nextScriptFunc, 2);
+			_nextScriptFunc = 0;
+		}
+
+		//processUnkAnimStructs();
+		//checkFloatingPointerRegions();
+		//processCharacters();
+		checkInput(0, true);
+		
+		update();
+
+		if (_sceneUpdateRequired)
+			gui_drawScene(0);
+		else
+			runLoopSub4(0);
+
+		/*if (_partyDeathFlag != -1) {
+			checkForPartyDeath(_partyDeathFlag);
+			_partyDeathFlag = -1;
+		}*/
+
+		_system->delayMillis(_tickLength);
 	}
 }
 
+void LoLEngine::update() {
+	updateWsaAnimations();
+
+	if (_updateCharNum != -1 && _system->getMillis() > _updatePortraitNext)
+		updatePortraitWithStats();
+
+	if (_screen->_drawGuiFlag & 0x800 || !(_updateFlags & 4))
+		updateLampStatus();
+
+	if (_screen->_drawGuiFlag & 0x4000 && !(_updateFlags & 4) && (_compassDirection == -1 || (_currentDirection << 6) != _compassDirection || _compassUnk))
+		updateCompass();
+
+	snd_characterSpeaking();
+	restorePaletteEntry();
+
+	_screen->updateScreen();
+}
+
 #pragma mark - Localization
 
-const char *LoLEngine::getLangString(uint16 id) {
+char *LoLEngine::getLangString(uint16 id) {
 	debugC(9, kDebugLevelMain, "LoLEngine::getLangString(0x%.04X)", id);
 
 	if (id == 0xFFFF)
@@ -701,7 +803,7 @@
 	if (!buffer)
 		return 0;
 
-	const char *string = (const char *)getTableEntry(buffer, realId);
+	char *string = (char *)getTableEntry(buffer, realId);
 
 	char *srcBuffer = _stringBuffer[_lastUsedStringBuffer];
 	Util::decodeString1(string, srcBuffer);
@@ -780,12 +882,39 @@
 		memset(_screen->getPalette(1), 0, 768);
 	} else {
 		delete _chargenWSA; _chargenWSA = 0;
+		
+		if (!_res->loadFileList("FILEDATA.FDT"))
+			error("Couldn't load file list: 'FILEDATA.FDT'");
+
+		uint8 *pal = _screen->getPalette(0);
+		memset(pal, 0, 768);
+		_screen->setScreenPalette(pal);
+
+		// TODO: We need to check if the SYSEX events of intro and ingame differ.
+		// If they differ, we really need to setup the proper ingame SYSEX when starting
+		// the game. But the proper place to do it would not be in this function.
+		/*if (_sound->getMusicType() == Sound::kMidiMT32 || _sound->getSfxType() == Sound::kMidiMT32) {
+			_sound->loadSoundFile("LOLSYSEX");
+			_sound->playTrack(0);
+
+			while (_sound->isPlaying() && !shouldQuit())
+				delay(10);
+		}*/
+
+		if (shouldQuit())
+			return;
+
+		_eventList.clear();
 	}
 }
 
 void LoLEngine::showIntro() {
 	debugC(9, kDebugLevelMain, "LoLEngine::showIntro()");
 
+	uint8 *pal = _screen->getPalette(0);
+	memset(pal, 0, 768);
+	_screen->setScreenPalette(pal);
+
 	TIM *intro = _tim->load("LOLINTRO.TIM", &_timIntroOpcodes);
 
 	_screen->loadFont(Screen::FID_8_FNT, "NEW8P.FNT");
@@ -828,6 +957,9 @@
 	_tim->unload(intro);
 	_tim->clearLangData();
 
+	for (int i = 0; i < TIM::kWSASlots; i++)
+		_tim->freeAnimStruct(i);
+
 	_screen->fadePalette(_screen->getPalette(1), 30, 0);
 }
 
@@ -1236,10 +1368,9 @@
 
 	i = 0;
 	for (; i < 11; i++) {
-		uint16 *tmp = &_characters[numChars].items[i];
-		if (*tmp) {
-			*tmp = makeItem(*tmp, 0, 0);
-			runItemScript(numChars, *tmp, 0x80, 0, 0);
+		if (_characters[numChars].items[i]) {
+			_characters[numChars].items[i] = makeItem(_characters[numChars].items[i], 0, 0);
+			runItemScript(numChars, _characters[numChars].items[i], 0x80, 0, 0);
 		}
 	}
 
@@ -1301,7 +1432,7 @@
 		y = 144;
 		redraw = true;
 	} else if (_updateCharV2 == 1) {
-		if (_unkLangAudio) {
+		if (textEnabled()) {
 			x = 90;
 			y = 130;
 		} else {
@@ -1309,7 +1440,7 @@
 			y = 144;
 		}
 	} else if (_updateCharV2 == 2) {
-		if (_unkLangAudio) {
+		if (textEnabled()) {
 			x = 16;
 			y = 134;
 		} else {
@@ -1325,11 +1456,10 @@
 		f -= 5;
 	f += 7;
 
-	if (_unkAudioSpecOffs) {
-		//TODO
-		//if (unk() == 2)
-		//	_updateCharV1 = 2;
-		//else
+	if (_speechFlag) {
+		if (snd_characterSpeaking() == 2)
+			_updateCharV1 = 2;
+		else
 			_updateCharV1 = 1;
 	}
 
@@ -1367,24 +1497,44 @@
 
 void LoLEngine::updatePortraitUnkTimeSub(int unk1, int unk2) {
 	if (_updateCharV4 == unk1 || !unk1) {
-		_updateCharV5 = 1;
-		_updateCharTime = _system->getMillis();
+		_restorePalette = 1;
+		_palUpdateTimer = _system->getMillis();
 	}
 
 	if (!unk2)
 		return;
 
 	updatePortraits();
-	if (_updateCharV6) {
+	if (_hideInventory) {
 		_screen->hideMouse();
 		_screen->clearDim(3);
 		_screen->showMouse();
 	}
 	
-	_updateCharV5 = 0;
+	_restorePalette = 0;
 	//initGuiUnk(11);
 }
 
+void LoLEngine::charCallback4(int redraw) {
+	for (int i = 0; i < 3; i++) {
+		if (!(_characters[i].flags & 1) || (_characters[i].flags & 8) || (_characters[i].curFaceFrame > 1))
+			continue;
+
+		if (_characters[i].curFaceFrame == 1) {
+			_characters[i].curFaceFrame = 0;
+			gui_drawCharPortraitWithStats(i);
+			_characters[i].rand = _rnd.getRandomNumberRng(1, 12);
+		} else {
+			_characters[i].rand--;
+			if (_characters[i].rand <= 0 && !redraw) {
+				_characters[i].curFaceFrame = 1;
+				gui_drawCharPortraitWithStats(i);
+				//resetAnimStructs(9, 0, 1);
+			}
+		}
+	}
+}
+
 void LoLEngine::setCharFaceFrame(int charNum, int frameNum) {
 	_characters[charNum].curFaceFrame = frameNum;
 }
@@ -1402,32 +1552,224 @@
 }
 
 void LoLEngine::setupScreenDims() {
-	if (_unkLangAudio)
+	if (textEnabled()) {
 		_screen->modifyScreenDim(4, 11, 124, 28, 45);
-	else
+		_screen->modifyScreenDim(5, 85, 123, 233, 54);
+	} else {
 		_screen->modifyScreenDim(4, 11, 124, 28, 9);
-	_screen->modifyScreenDim(5, 85, 123, 233, 18);
+		_screen->modifyScreenDim(5, 85, 123, 233, 18);
+	}	
 }
 
+void LoLEngine::initDialogueSequence(int controlMode) {
+	unkHideInventory();
+	gui_prepareForSequence(112, 0, 176, 120, controlMode);
+
+	_updateFlags |= 3;
+
+	_dlg->setupField(true);
+	_dlg->expandField();
+	setupScreenDims();
+	gui_disableControls(controlMode);
+}
+
+void LoLEngine::toggleSelectedCharacterFrame(bool mode) {
+	if (countActiveCharacters() == 1)
+		return;
+
+	int col = mode ? 212 : 1;
+
+	int cp = _screen->setCurPage(0);
+	int x = _activeCharsXpos[_selectedCharacter];
+
+	_screen->drawBox(x, 143, x + 65, 176, col);
+	_screen->setCurPage(cp);
+}
+
+void LoLEngine::unkHideInventory() {
+	_hideInventory = 1;
+
+	if (!textEnabled() || !(_hideControls & 2)) 
+		charCallback4(1);
+
+	removeUnkFlags(2);
+}
+
+void LoLEngine::gui_prepareForSequence(int x, int y, int w, int h, int unk) {
+	//resetGuiUnk(x, y, w, h, unk);
+
+	_preSeq_X1 = x;
+	_preSeq_Y1 = y;
+	_preSeq_X2 = x + w;
+	_preSeq_Y2 = y + h;
+
+	int mouseOffs = _itemInHand ? 10 : 0;
+	_screen->setMouseCursor(mouseOffs, mouseOffs, getItemIconShapePtr(_itemInHand));
+
+	_lastMouseRegion = -1;
+
+	if (w == 320) {
+		setLampMode(0);
+		_lampStatusSuspended = true;
+	}
+}
+
+void LoLEngine::restoreSceneAfterDialogueSequence(int redraw) {
+	gui_enableControls();
+	_dlg->setupField(false);
+	_updateFlags &= 0xffdf;
+
+	//loadLevel_initGui()
+
+	for (int i = 0; i < 6; i++)
+		_tim->freeAnimStruct(i);
+
+	_updateFlags = 0;
+
+	if (redraw) {
+		if (_screen->_fadeFlag != 2)
+			_screen->fadeClearSceneWindow(10);
+		gui_drawPlayField();
+		_screen->setPaletteBrightness(_screen->_currentPalette, _brightness, _lampOilStatus);
+		_screen->_fadeFlag = 0;
+	}
+
+	_hideInventory = 0;
+}
+
+void LoLEngine::restorePaletteEntry() {
+	if (!_restorePalette)
+		return;
+
+	_screen->copyColour(192, 252, _system->getMillis() - _palUpdateTimer, 60 * _tickLength);
+
+	if (_hideInventory)
+		return;
+
+	_screen->clearDim(3);
+
+	///initGuiUnk(11);
+
+	_restorePalette = 0;
+}
+
+void LoLEngine::updateWsaAnimations() {
+	if (_updateFlags & 8)
+		return;
+
+	//TODO
+}
+
 void LoLEngine::loadTalkFile(int index) {
 	char file[8];
-	
+
 	if (index == _curTlkFile)
 		return;
 
-	if (_curTlkFile >= 0) {
+	if (_curTlkFile > 0 && index > 0) {
 		snprintf(file, sizeof(file), "%02d.TLK", _curTlkFile);
 		_res->unloadPakFile(file);
 	}
 
+	if (index > 0)
+		_curTlkFile = index;
+
 	snprintf(file, sizeof(file), "%02d.TLK", index);
 	_res->loadPakFile(file);
+}
+
+bool LoLEngine::snd_playCharacterSpeech(int id, int8 speaker, int) {
+	if (!_speechFlag)
+		return true;
+
+	if (speaker < 65) {
+		if (_characters[speaker].flags & 1)
+			speaker = (int) _characters[speaker].name[0];
+		else
+			speaker = 0;
+	}
+
+	if (_lastSpeechId == id && speaker == _lastSpeaker)
+		return true;
+
+	_lastSpeechId = id;
+	_lastSpeaker = speaker;
+
+	Common::List<const char*> playList;
+
+	char pattern1[8];
+	char pattern2[5];
+	char file1[13];
+	char file2[13];
+
+	snprintf(pattern2, sizeof(pattern2), "%02d", id & 0x4000 ? 0 : _curTlkFile);
+
+	if (id & 0x4000) {
+		snprintf(pattern1, sizeof(pattern1), "%03X", id & 0x3fff);
+	} else if (id < 1000) {
+		snprintf(pattern1, sizeof(pattern1), "%03d", id);		
+	} else {
+		snprintf(pattern1, sizeof(pattern1), "@%04d", id - 1000);
+	}
+
+	for (char i = '0'; i != -1; i++) {
+		snprintf(file1, sizeof(file1), "%s%c%c.%s", pattern1, (char)speaker, i, pattern2);
+		snprintf(file2, sizeof(file2), "%s%c%c.%s", pattern1, '_', i, pattern2);
+		if (_res->exists(file1)) {
+			char *f = new char[strlen(file1) + 1];
+			strcpy(f, file1);
+			playList.push_back(f);
+		} else if (_res->exists(file2)) {
+			char *f = new char[strlen(file2) + 1];
+			strcpy(f, file2);
+			playList.push_back(f);
+		} else {
+			i = -2;
+		}
+	}
+
+	if (playList.empty())
+		return false;
+
+	do {
+		update();
+		if (snd_characterSpeaking() == 0)
+			break;
+	} while (_sound->voiceIsPlaying());
+
+	strcpy(_activeVoiceFile, *playList.begin());
+	_tim->setActiveSpeechFile(_activeVoiceFile);
+
+	_sound->voicePlayFromList(playList);
+		
+	for (Common::List<const char*>::iterator i = playList.begin(); i != playList.end(); i++)
+		delete []*i;
+	playList.clear();
+
+	_tim->setDialogueCompleteFlag(0);
+
+	return true;
+}
+
+int LoLEngine::snd_characterSpeaking() {
+	if (_sound->voiceIsPlaying(_activeVoiceFile))
+		return 2;
+		
+	_lastSpeechId = _lastSpeaker = -1;
 	
-	_curTlkFile = index;
+	return 1;
 }
 
-void LoLEngine::snd_playVoiceFile(int) {
+int LoLEngine::snd_dialogueSpeechUpdate(int finish) {
+	if (!_sound->voiceIsPlaying(_activeVoiceFile))
+		return -1;
+	
+	//_dlgTimer = 0;
 
+	if (finish)
+		_tim->setDialogueCompleteFlag(1);
+	
+	return 1;
 }
 
 void LoLEngine::snd_playSoundEffect(int track, int volume) {
@@ -1508,5 +1850,14 @@
 	return snd_playTrack(-1);
 }
 
+void LoLEngine::runLoopSub4(int a) {
+	cmzS7(a, _currentBlock);
+}
+
+void LoLEngine::calcCoordinates(uint16 & x, uint16 & y, int block, uint16 xOffs, uint16 yOffs) {
+	x = (block & 0x1f) << 8 | xOffs;
+	y = ((block & 0xffe0) << 3) | yOffs;
+}
+
 } // end of namespace Kyra
 

Modified: scummvm/trunk/engines/kyra/lol.h
===================================================================
--- scummvm/trunk/engines/kyra/lol.h	2009-02-01 14:56:19 UTC (rev 36177)
+++ scummvm/trunk/engines/kyra/lol.h	2009-02-01 19:27:01 UTC (rev 36178)
@@ -29,6 +29,9 @@
 #include "kyra/kyra_v1.h"
 #include "kyra/script_tim.h"
 #include "kyra/script.h"
+#include "kyra/sound.h"
+#include "kyra/gui_lol.h"
+#include "kyra/text_lol.h"
 
 #include "common/list.h"
 
@@ -107,20 +110,35 @@
 	uint8 flags;
 };
 
-struct LVL {
+struct MonsterProperty {
+	uint8 id;
+	uint8 maxWidth;
+	uint16 unk[9];
+	uint16 *pos;
+	uint16 unk2[8];
+	uint16 unk3[8];
+	uint16 unk4[2];
+	uint8 b;
+	uint16 unk5[2];
+	uint16 unk6[5];
+	uint8 unk7[4];
+	uint8 unk8[3];
+};
+
+struct CLevelItem {
 	uint16 itemIndexUnk;
-	uint8 field_2;
-	uint16 field_3;
+	uint8 unk2;
+	uint16 unk3;
 	uint16 blockPropertyIndex;
 	uint16 p_1a;
 	uint16 p_1b;
 	int8 level;
-	uint16 p_2a;
-	uint16 p_2b;
-	uint8 field_10;
-	uint8 field_11;
-	uint8 field_12;
-	uint8 field_13;
+	uint16 itemPosX;
+	uint16 itemPosY;
+	uint8 field10;
+	uint16 anon8;
+	uint8 anon9;
+
 	uint8 field_14;
 	uint8 field_15;
 	uint8 field_16;
@@ -132,7 +150,7 @@
 	int16 field_1D;
 	uint8 field_1F;
 	uint8 field_20;
-	uint8 *offs_lvl415;
+	MonsterProperty *monsters;
 	uint8 field_25;
 	uint8 field_26;
 	uint8 field_27;
@@ -145,6 +163,34 @@
 	uint8 field_2E;
 };
 
+struct ItemInPlay {
+	uint16 itemIndexUnk;
+	uint8 unk2;
+	uint16 unk3;
+	uint16 blockPropertyIndex;
+	uint16 p_1a;
+	uint16 p_1b;
+	int8 level;
+	uint16 itemPropertyIndex;
+	uint16 shpCurFrame_flg;
+	uint8 field10;
+	uint16 anon8;
+	uint8 anon9;
+};
+
+struct ItemProperty {
+	uint16 nameStringId;
+	uint8 shpIndex;
+	uint16 flags;
+	uint16 unk5;
+	uint8 itemScriptFunc;
+	int8 unk8;
+	uint8 unk9;
+	uint8 unkA;
+	uint16 unkB;
+	uint8 unkD;
+};
+
 struct LevelShapeProperty {
 	uint16 shapeIndex[10];
 	uint8 scaleFlag[10];
@@ -161,26 +207,31 @@
 	uint8 flags;
 };
 
-struct ScriptOffsUnkStruct {
-	uint8 field_0;
-	uint8 field_1;
-	uint8 field_2;
-	uint8 field_3;
-	uint8 field_4;
-	uint8 field_5;
-	uint8 field_6;
-	uint8 field_7;
-	uint8 field_8;
+struct ButtonDef {
+	uint16 buttonflags;
+	uint8 clickedShapeId;
+	uint8 unk1;
+	uint16 unk2;
+	int16 x;
+	int16 y;
+	uint16 w;
+	uint16 h;
+	uint16 index;
+	uint16 flag;
 };
 
 class LoLEngine : public KyraEngine_v1 {
+friend class GUI_LoL;
+friend class TextDisplayer_LoL;
 public:
 	LoLEngine(OSystem *system, const GameFlags &flags);
 	~LoLEngine();
 
 	Screen *screen();
+	GUI *gui() const;
 private:
 	Screen_LoL *_screen;
+	GUI_LoL *_gui;
 	TIMInterpreter *_tim;
 
 	Common::Error init();
@@ -190,19 +241,29 @@
 	void initStaticResource();
 	void preInit();
 
-	void initializeCursors();
+	void loadItemIconShapes();
 	int mainMenu();
 
 	void startup();
 	void startupNew();
 
+	// main loop
 	void runLoop();
+	void update();
+	
+	int setUnkFlags(int unk);
+	int removeUnkFlags(int unk);
 
+	int _intFlag3;
+	
 	// mouse
 	void setMouseCursorToIcon(int icon);
 	void setMouseCursorToItemInHand();
 	uint8 *getItemIconShapePtr(int index);
+	bool posWithinRect(int mouseX, int mouseY, int x1, int y1, int x2, int y2);
 
+	int _floatingMouseArrowControl;
+
 	// intro
 	void setupPrologueData(bool load);
 
@@ -257,20 +318,25 @@
 
 	// sound
 	void loadTalkFile(int index);
-	void snd_playVoiceFile(int);
+	void snd_playVoiceFile(int track) {}
+	bool snd_playCharacterSpeech(int id, int8 speaker, int);
+	int snd_characterSpeaking();
+	int snd_dialogueSpeechUpdate(int finish);
 	void snd_playSoundEffect(int track, int volume);
 	void snd_loadSoundFile(int track);
 	int snd_playTrack(int track);
 	int snd_stopMusic();
 
+	int _lastSpeechId;
+	int _lastSpeaker;
+	char _activeVoiceFile[13];
 	int _lastSfxTrack;
 	int _lastMusicTrack;
 	int _curMusicFileIndex;
 	char _curMusicFileExt;
-	int _curTlkFile;	
 
-	int _unkAudioSpecOffs;
-	bool _unkLangAudio;
+	int _curTlkFile;
+	int _speechFlag;
 
 	char **_ingameSoundList;
 	int _ingameSoundListSize;
@@ -289,7 +355,7 @@
 	void gui_drawScene(int pageNum);
 	void gui_drawAllCharPortraitsWithStats();
 	void gui_drawCharPortraitWithStats(int charNum);
-	void gui_drawPortraitBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor);
+	void gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor);
 	void gui_drawCharFaceShape(int charNum, int x, int y, int pageNum);
 	void gui_drawLiveMagicBar(int x, int y, int curPoints, int unk, int maxPoints, int w, int h, int col1, int col2, int flag);
 	void gui_drawMoneyBox(int pageNum);
@@ -298,14 +364,63 @@
 	void gui_drawCompass();
 	void gui_drawScroll();
 
+	int gui_enableControls();
+	int gui_disableControls(int controlMode);
+	void gui_disableArrowButton(int shapeIndex, int mode);
+	void gui_toggleFightButtons(bool disable);
+	void gui_prepareForSequence(int x, int y, int w, int h, int unk);
+
 	bool _weaponsDisabled;
-	int _unkDrawPortraitIndex;
-	int _updateUnk2;
+	int _lastArrowButtonShape;
+	uint32 _arrowButtonTimer;
+	int _selectedCharacter;
+	int _compassDirection;
+	int _compassUnk;
 	int _compassDirectionIndex;
 
 	const CompassDef *_compassDefs;
 	int _compassDefsSize;
 
+	void initButtonList();
+	ButtonDef *_buttonData;
+	Button *_buttonList;
+
+	int clickedUpArrow(Button *button);
+	int clickedDownArrow(Button *button);
+	int clickedLeftArrow(Button *button);
+	int clickedRightArrow(Button *button);
+	int clickedTurnLeftArrow(Button *button);
+	int clickedTurnRightArrow(Button *button);
+	int clickedAttackButton(Button *button);
+	int clickedMagicButton(Button *button);
+	int clickedUnk9(Button *button);
+	int clickedScreen(Button *button);
+	int clickedPortraitLeft(Button *button);
+	int clickedLiveMagicBarsLeft(Button *button);
+	int clickedPortraitEtcRight(Button *button);
+	int clickedUnk14(Button *button);
+	int clickedUnk15(Button *button);
+	int clickedUnk16(Button *button);
+	int clickedUnk17(Button *button);
+	int clickedInventorySlot(Button *button);
+	int clickedInventoryScroll(Button *button);
+	int clickedUnk20(Button *button);
+	int clickedUnk21(Button *button);
+	int clickedScroll(Button *button);
+	int clickedUnk23(Button *button);
+	int clickedUnk24(Button *button);
+	int clickedUnk25(Button *button);
+	int clickedOptions(Button *button);
+	int clickedRestParty(Button *button);
+	int clickedUnk28(Button *button);
+	int clickedUnk29(Button *button);
+	int clickedUnk30(Button *button);
+	int clickedUnk31(Button *button);
+	int clickedUnk32(Button *button);
+
+	// text
+	TextDisplayer_LoL *_dlg;
+
 	// emc scripts
 	void runInitScript(const char *filename, int func);
 	void runInfScript(const char *filename);
@@ -318,7 +433,7 @@
 	uint8 _unkScriptByte;
 	uint16 _currentDirection;
 	uint16 _currentBlock;
-	bool _boolScriptFuncDone;
+	bool _sceneUpdateRequired;
 	int16 _scriptExecutedFuncs[18];
 	uint16 _gameFlags[15];
 	uint16 _unkEMC46[16];
@@ -338,17 +453,32 @@
 	int olol_loadLevelShapes(EMCState *script);
 	int olol_closeLevelShapeFile(EMCState *script);
 	int olol_loadDoorShapes(EMCState *script);
+	int olol_initAnimStruct(EMCState *script);
+	int olol_freeAnimStruct(EMCState *script);
 	int olol_setMusicTrack(EMCState *script);
 	int olol_getUnkArrayVal(EMCState *script);
 	int olol_setUnkArrayVal(EMCState *script);
 	int olol_setGlobalVar(EMCState *script);
 	int olol_mapShapeToBlock(EMCState *script);
 	int olol_resetBlockShapeAssignment(EMCState *script);
+	int olol_loadMonsterProperties(EMCState *script);
+	int olol_loadTimScript(EMCState *script);
+	int olol_runTimScript(EMCState *script);
+	int olol_releaseTimScript(EMCState *script);
+	int olol_initDialogueSequence(EMCState *script);
+	int olol_restoreSceneAfterDialogueSequence(EMCState *script);
 	int olol_loadLangFile(EMCState *script);
+	int olol_stopTimScript(EMCState *script);
 	int olol_loadSoundFile(EMCState *script);
 	int olol_setPaletteBrightness(EMCState *script);
+	int olol_playDialogueTalkText(EMCState *script);
+	int olol_setNextFunc(EMCState *script);
 	int olol_assignCustomSfx(EMCState *script);
 
+	// tim scripts
+	TIMInterpreter::Animation *initTimAnimStruct(int index, const char *filename, int x, int y, uint16 copyPara, uint16 wsaFlags);
+	TIM *_activeTim[10];
+	
 	// tim opcode
 	void setupOpcodeTable();
 
@@ -359,6 +489,8 @@
 	int tlol_processWsaFrame(const TIM *tim, const uint16 *param);
 	int tlol_displayText(const TIM *tim, const uint16 *param);
 
+	Common::Array<const TIMOpcode*> _timIngameOpcodes;
+
 	// translation
 	int _lang;
 
@@ -368,13 +500,19 @@
 	int _lastUsedStringBuffer;
 	char _stringBuffer[5][512];	// TODO: The original used a size of 512, it looks a bit large.
 								// Maybe we can someday reduce the size.
-	const char *getLangString(uint16 id);
+	char *getLangString(uint16 id);
 	uint8 *getTableEntry(uint8 *buffer, uint16 id);
 
 	static const char * const _languageExt[];
 
 	// graphics
 	void setupScreenDims();
+	void initDialogueSequence(int controlMode);
+	void unkHideInventory();
+	void restoreSceneAfterDialogueSequence(int redraw);
+	void toggleSelectedCharacterFrame(bool mode);
+	void restorePaletteEntry();
+	void updateWsaAnimations();
 
 	uint8 **_itemIconShapes;
 	int _numItemIconShapes;
@@ -405,21 +543,21 @@
 	void updatePortraitWithStats();
 	void updatePortraits();
 	void updatePortraitUnkTimeSub(int unk1, int unk2);
-
+	void charCallback4(int redraw);
 	void setCharFaceFrame(int charNum, int frameNum);
 	void faceFrameRefresh(int charNum);
 
 	LoLCharacter *_characters;
 	uint16 _activeCharsXpos[3];
-	int _charFlagUnk;
+	int _updateFlags;
 	int _updateCharNum;
 	int _updateCharV1;
 	int _updateCharV2;
 	int _updateCharV3;
 	int _updateCharV4;
-	int _updateCharV5;
-	int _updateCharV6;
-	uint32 _updateCharTime;
+	int _restorePalette;
+	int _hideInventory;
+	uint32 _palUpdateTimer;
 	uint32 _updatePortraitNext;
 
 	int _loadLevelFlag;
@@ -433,19 +571,30 @@
 	const LoLCharacter *_charDefaults;
 	int _charDefaultsSize;
 
+	// lamp
+	void resetLampStatus();
+	void setLampMode(bool lampOn);
+	void updateLampStatus();
+
+	int _lampOilStatus;
+	int _brightness;
+	int _lampStatusUnk;
+	uint32 _lampStatusTimer;
+	bool _lampStatusSuspended;
+
 	// level
 	void loadLevel(int index);
 	void addLevelItems();
 	int initCmzWithScript(int block);
-	void initCMZ1(LVL *l, int a);
-	void initCMZ2(LVL *l, uint16 a, uint16 b);
-	int cmzS1(uint16 a, uint16 b, uint16 c, uint16 d);
-	void cmzS2(LVL *l, int a);
-	void cmzS3(LVL *l);
+	void initCMZ1(CLevelItem *l, int a);
+	void initCMZ2(CLevelItem *l, uint16 a, uint16 b);
+	int cmzS1(uint16 x1, uint16 y1, uint16 x2, uint16 y2);
+	void cmzS2(CLevelItem *l, int a);
+	void cmzS3(CLevelItem *l);
 	void cmzS4(uint16 &itemIndex, int a);
 	int cmzS5(uint16 a, uint16 b);
 	void cmzS6(uint16 &itemIndex, int a);
-	void cmzS7(int itemIndex, int a);
+	void cmzS7(int a, int block);
 	void loadLevelWLL(int index, bool mapShapes);
 	void moveItemToBlock(uint16 *cmzItemIndex, uint16 item);
 	int assignLevelShapes(int index);
@@ -484,17 +633,15 @@
 	void drawScriptShapes(int pageNum);
 	void updateSceneWindow();
 
-	void turnOnLamp();
-	void updateLampStatus();
+	void updateCompass();
 
 	void moveParty(uint16 direction, int unk1, int unk2, int unk3);
 	uint16 calcNewBlockPostion(uint16 curBlock, uint16 direction);
 
-	void setLF1(uint16 & a, uint16 & b, int block, uint16 d, uint16 e);
 	void setLF2(int block);
 	
 	int _unkFlag;
-	int _scriptFuncIndex;
+	int _nextScriptFunc;
 	uint8 _currentLevel;
 	bool _loadLevelFlag2;
 	int _lvlBlockIndex;
@@ -520,16 +667,11 @@
 	int _sceneDrawVar3;
 	int _wllProcessFlag;
 
-	uint8 *_tlcTable2;
-	uint8 *_tlcTable1;
+	uint8 *_trueLightTable2;
+	uint8 *_trueLightTable1;
 
 	int _loadSuppFilesFlag;
 
-	int _lampOilStatus;
-	int _brightness;
-	int _lampStatusUnk;
-	uint32 _lampStatusTimer;
-
 	uint8 *_wllVmpMap;
 	int8 *_wllShapeMap;
 	uint8 *_wllBuffer3;
@@ -542,11 +684,11 @@
 
 	LevelBlockProperty *_levelBlockProperties;
 	LevelBlockProperty *_curBlockCaps[18];
-	LVL *_lvlBuffer;
-	uint8 *_lvl415;
+	CLevelItem *_cLevelItems;
+	MonsterProperty *_monsterProperties;
 
-	uint16 _unkCmzU1;
-	uint16 _unkCmzU2;
+	uint16 _partyPosX;
+	uint16 _partyPosY;
 	
 	Common::SeekableReadStream *_lvlShpFileHandle;
 	uint16 _lvlShpNum;
@@ -559,6 +701,8 @@
 	int16 _dmScaleW;
 	int16 _dmScaleH;
 
+	int _lastMouseRegion;
+	int _preSeq_X1, _preSeq_Y1,	_preSeq_X2, _preSeq_Y2;
 	uint8 _unkGameFlag;
 
 	uint8 *_tempBuffer5120;
@@ -616,39 +760,11 @@
 	int _sceneDrawPage2;
 
 	// items
-	struct ItemInPlay {
-		uint16 itemIndexUnk;
-		uint8 unk2;
-		uint16 unk3;
-		uint16 blockPropertyIndex;
-		uint16 unk7;
-		uint16 anonymous_4;
-		int8 level;
-		uint16 itemPropertyIndex;
-		uint16 shpCurFrame_flg;
-		uint8 field10;
-		uint16 anon8;
-		uint8 anon9;
-	};
-
-	struct ItemProperty {
-		uint16 nameStringId;
-		uint8 shpIndex;
-		uint16 flags;
-		uint16 unk5;
-		uint8 itemScriptFunc;
-		uint8 unk8;
-		uint8 unk9;
-		uint8 unkA;
-		uint16 unkB;
-		uint8 unkD;
-	};
-
 	void giveCredits(int credits, int redraw);
 	int makeItem(int itemIndex, int curFrame, int flags);
 	bool testUnkItemFlags(int itemIndex);
 	void clearItemTableEntry(int itemIndex);
-	void *cmzGetItemOffset(uint16 index);
+	CLevelItem *findItem(uint16 index);
 	void runItemScript(int reg1, int item, int reg0, int reg3, int reg4);
 
 	uint8 _moneyColumnHeight[5];
@@ -658,12 +774,16 @@
 	ItemProperty *_itemProperties;
 
 	int _itemInHand;
-	uint16 _inventoryItemIndex[48];
+	uint16 _inventory[48];
 	int _inventoryCurItem;
-	int _unkInventFlag;
+	int _hideControls;
 
 	EMCData _itemScript;
 
+	// misc
+	void runLoopSub4(int a);
+	void calcCoordinates(uint16 & x, uint16 & y, int block, uint16 xOffs, uint16 yOffs);
+
 	// spells
 	int8 _availableSpells[7];
 	int _selectedSpell;

Modified: scummvm/trunk/engines/kyra/module.mk
===================================================================
--- scummvm/trunk/engines/kyra/module.mk	2009-02-01 14:56:19 UTC (rev 36177)
+++ scummvm/trunk/engines/kyra/module.mk	2009-02-01 19:27:01 UTC (rev 36178)
@@ -65,6 +65,7 @@
 	staticres.o \
 	text.o \
 	text_lok.o \
+	text_lol.o \
 	text_hof.o \
 	text_mr.o \
 	timer.o \

Modified: scummvm/trunk/engines/kyra/scene_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/scene_lol.cpp	2009-02-01 14:56:19 UTC (rev 36177)
+++ scummvm/trunk/engines/kyra/scene_lol.cpp	2009-02-01 19:27:01 UTC (rev 36178)
@@ -35,7 +35,7 @@
 void LoLEngine::loadLevel(int index) {
 	_unkFlag |= 0x800;
 	setMouseCursorToIcon(0x85);
-	_scriptFuncIndex = 0;
+	_nextScriptFunc = 0;
 
 	snd_stopMusic();
 
@@ -57,7 +57,7 @@
 	// TODO
 	
 	_currentLevel = index;
-	_charFlagUnk = 0;
+	_updateFlags = 0;
 
 	// TODO
 
@@ -111,32 +111,33 @@
 int LoLEngine::initCmzWithScript(int block) {
 	int i = _levelBlockProperties[block].itemIndex;
 	int cnt = 0;
+	CLevelItem *t = 0;
 
-	while (i) {
-		void *t = cmzGetItemOffset(i);
-		i = (i & 0x8000) ? ((LVL*)t)->itemIndexUnk : ((ItemInPlay*)t)->itemIndexUnk;
+	while (i) {		
+		t = findItem(i);
+		i = t->itemIndexUnk;
 		if (!(i & 0x8000))
 			continue;
 
 		i &= 0x7fff;
-		LVL *l = &_lvlBuffer[i];
+		t = &_cLevelItems[i];
 
 		cnt++;
-		initCMZ1(l, 14);
+		initCMZ1(t, 14);
 
-		checkScriptUnk(l->blockPropertyIndex);
+		checkScriptUnk(t->blockPropertyIndex);
 
-		initCMZ2(l, 0, 0);
+		initCMZ2(t, 0, 0);
 	}
 	return cnt;
 }
 
-void LoLEngine::initCMZ1(LVL *l, int a) {
+void LoLEngine::initCMZ1(CLevelItem *l, int a) {
 	if (l->field_14 == 13 && a != 14)
 		return;
 	if (a == 7) {
-		l->p_2a = _unkCmzU1;
-		l->p_2b = _unkCmzU2;
+		l->itemPosX = _partyPosX;
+		l->itemPosY = _partyPosX;
 	}
 
 	if (l->field_14 == 1 && a == 7) {
@@ -145,9 +146,9 @@
 				continue;
 			l->field_14 = a;
 			l->field_15 = 0;
-			l->p_2a = _unkCmzU1;
-			l->p_2b = _unkCmzU2;
-			cmzS2(l, cmzS1(l->p_1a, l->p_1b, l->p_2a, l->p_2b));
+			l->itemPosX = _partyPosX;
+			l->itemPosY = _partyPosY;
+			cmzS2(l, cmzS1(l->p_1a, l->p_1b, l->itemPosX, l->itemPosY));
 		}		
 	} else {
 		l->field_14 = a;
@@ -168,7 +169,7 @@
 
 }
 
-void LoLEngine::initCMZ2(LVL *l, uint16 a, uint16 b) {
+void LoLEngine::initCMZ2(CLevelItem *l, uint16 a, uint16 b) {
 	bool cont = true;
 	int t = l->blockPropertyIndex;
 	if (l->blockPropertyIndex) {
@@ -184,7 +185,7 @@
 	if (l->p_1a != a || l->p_1b != b) {
 		l->p_1a = a;
 		l->p_1b = b;
-		l->field_13 = (++l->field_13) & 3;
+		l->anon9 = (++l->anon9) & 3;
 	}
 
 	if (l->blockPropertyIndex == 0)
@@ -193,34 +194,64 @@
 	cmzS6(_levelBlockProperties[l->blockPropertyIndex].itemIndex, ((uint16)l->field_16) | 0x8000);
 	_levelBlockProperties[l->blockPropertyIndex].field_8 = 5;
 	checkScriptUnk(l->blockPropertyIndex);
-	uint8 *v = l->offs_lvl415;
 	
-	if (v[80] == 0 || cont == false)
+	if (l->monsters->unk8[0] == 0 || cont == false)
 		return;
 
-	if ((!(READ_LE_UINT16(&v[62]) & 0x100) || ((l->field_13 & 1) == 0)) && l->blockPropertyIndex == t)
+	if ((!(l->monsters->unk5[0] & 0x100) || ((l->anon9 & 1) == 0)) && l->blockPropertyIndex == t)
 		return;
 
 	if (l->blockPropertyIndex != t)
 		runResidentScriptCustom(l->blockPropertyIndex, 0x800, -1, l->field_16, 0, 0);
 
-	if (_charFlagUnk & 1)
+	if (_updateFlags & 1)
 		return;
 
-	cmzS7(l->offs_lvl415[50], l->blockPropertyIndex);
+	cmzS7(l->monsters->unk3[5], l->blockPropertyIndex);
 }
 
-int LoLEngine::cmzS1(uint16 a, uint16 b, uint16 c, uint16 d) {
-	// TODO
+int LoLEngine::cmzS1(uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
+	int16 r = 0;
+	int16 t1 = y1 - y2;
+	if (t1 < 0) {
+		r++;
+		t1 = -t1;
+	}
 
-	return 0;
+	r <<= 1;
+
+	int16 t2 = x2 - x1;
+
+	if (t2 < 0) {
+		r++;
+		t2 = -t2;
+	}
+
+	uint8 f = 0;
+	
+	if (t2 >= t1) {
+		if (t2 > t1)
+			f = 1;
+		SWAP(t1, t2);		
+	}
+
+	r = (r << 1) | f;
+	
+	t1 = (t1 + 1) >> 1;
+
+	f = 0;
+	f = (t2 > t1) ? 1 : 0;
+	r = (r << 1) | f;
+
+	static const uint8 Retv[] = { 1, 2, 1, 0, 7, 6, 7, 0, 3, 2, 3, 4, 5, 6, 5, 4};
+	return Retv[r];
 }
 
-void LoLEngine::cmzS2(LVL *l, int a) {
+void LoLEngine::cmzS2(CLevelItem *l, int a) {
 	// TODO
 }
 
-void LoLEngine::cmzS3(LVL *l) {
+void LoLEngine::cmzS3(CLevelItem *l) {
 	// TODO
 }
 
@@ -237,7 +268,7 @@
 	// TODO
 }
 
-void LoLEngine::cmzS7(int itemIndex, int a) {
+void LoLEngine::cmzS7(int a, int block) {
 	if (!(_unkGameFlag & 1))
 		return;
 
@@ -245,24 +276,28 @@
 }
 
 void LoLEngine::moveItemToBlock(uint16 *cmzItemIndex, uint16 item) {
-	uint16 *tmp = 0;
-	while (*cmzItemIndex & 0x8000) {
-		tmp = (uint16*) cmzGetItemOffset(*cmzItemIndex);
-		cmzItemIndex = tmp;
+	CLevelItem *tmp = 0;
+
+	while (*cmzItemIndex & 0x8000) {		
+		tmp = findItem(*cmzItemIndex);
+		cmzItemIndex = &tmp->itemIndexUnk;
 	}
-	uint16 *t = (uint16*) cmzGetItemOffset(*cmzItemIndex);
 
-	((ItemInPlay*)t)->level = -1;
+	tmp = findItem(item);
+	tmp->level = -1;
+
 	uint16 ix = *cmzItemIndex;
 
 	if (ix == item)
 		return;
 
 	*cmzItemIndex = item;
-	cmzItemIndex = t;
+	cmzItemIndex = &tmp->itemIndexUnk;
 
-	while (*cmzItemIndex)
-		cmzItemIndex = (uint16*) cmzGetItemOffset(*cmzItemIndex);
+	while (*cmzItemIndex) {
+		tmp = findItem(*cmzItemIndex);
+		cmzItemIndex = &tmp->itemIndexUnk;
+	}
 
 	*cmzItemIndex = ix;
 }
@@ -394,10 +429,10 @@
 		_levelBlockProperties[i].flags = *t++;
 
 	for (int i = 0; i < 30; i++) {
-		if (_lvlBuffer[i].blockPropertyIndex) {
-			_lvlBuffer[i].blockPropertyIndex = 0;
-			_lvlBuffer[i].offs_lvl415 = _lvl415 + _lvlBuffer[i].field_20;
-			initCMZ2(&_lvlBuffer[i], _lvlBuffer[i].p_1a, _lvlBuffer[i].p_1b);
+		if (_cLevelItems[i].blockPropertyIndex) {
+			_cLevelItems[i].blockPropertyIndex = 0;
+			_cLevelItems[i].monsters = _monsterProperties + _cLevelItems[i].field_20;
+			initCMZ2(&_cLevelItems[i], _cLevelItems[i].p_1a, _cLevelItems[i].p_1b);
 		}
 	}
 		
@@ -413,15 +448,15 @@
 	//int r = 0;
 	
 	for (int i = 0; i < 30; i++) {
-		if (_lvlBuffer[i].field_14 >= 14 || _lvlBuffer[i].blockPropertyIndex == 0 || _lvlBuffer[i].field_1D <= 0)
+		if (_cLevelItems[i].field_14 >= 14 || _cLevelItems[i].blockPropertyIndex == 0 || _cLevelItems[i].field_1D <= 0)
 			continue;
 
-		int t = (val * _lvlBuffer[i].field_1D) >> 8;
-		_lvlBuffer[i].field_1D = t;
+		int t = (val * _cLevelItems[i].field_1D) >> 8;
+		_cLevelItems[i].field_1D = t;
 		if (index2 < index1)
-			_lvlBuffer[i].field_1D++;
-		if (_lvlBuffer[i].field_1D == 0)
-			_lvlBuffer[i].field_1D = 1;
+			_cLevelItems[i].field_1D++;
+		if (_cLevelItems[i].field_1D == 0)
+			_cLevelItems[i].field_1D = 1;
 	}
 }
 
@@ -475,7 +510,7 @@
 		memset(_monsterPalettes[pos + i], 0, size);
 	}
 
-	/*for (int i = 0; i < 4; i++) {
+	for (int i = 0; i < 4; i++) {
 		for (int ii = 0; ii < 16; ii++) {
 			uint8 **of = &_buf4[(monsterIndex << 7) + (i << 5) + (ii << 1)];
 			int s = (i << 4) + ii + 17;
@@ -483,7 +518,7 @@
 			
 			////TODO
 		}
-	}*/
+	}
 	_monsterUnk[monsterIndex] = b & 0xff;
 
 	uint8 *tsh = _screen->makeShapeCopy(p, 16);
@@ -678,8 +713,8 @@
 	char tname[13];
 	snprintf(tname, sizeof(tname), "LEVEL%.02d.TLC", _currentLevel);
 	Common::SeekableReadStream *s = _res->createReadStream(tname);
-	s->read(_tlcTable1, 256);
-	s->read(_tlcTable2, 5120);
+	s->read(_trueLightTable1, 256);
+	s->read(_trueLightTable2, 5120);
 	delete s;
 
 	_loadSuppFilesFlag = 1;
@@ -689,10 +724,10 @@
 	for (int i = 0; i < 1024; i++) {
 		_levelBlockProperties[i].field_8 = 5;
 		uint16 id = _levelBlockProperties[i].itemIndex;
-		LVL *r = 0;
+		CLevelItem *r = 0;
 
 		while (id & 0x8000) {
-			r = (LVL*)cmzGetItemOffset(id);
+			r = (CLevelItem*)findItem(id);
 			assert(r);
 			id = r->itemIndexUnk;
 		}
@@ -711,9 +746,9 @@
 }
 
 void LoLEngine::resetLvlBuffer() {
-	memset(_lvlBuffer, 0, 30 * sizeof(LVL));
+	memset(_cLevelItems, 0, 30 * sizeof(CLevelItem));
 	for (int i = 0; i < 30; i++)
-		_lvlBuffer[i].field_14 = 0x10;
+		_cLevelItems[i].field_14 = 0x10;
 }
 
 void LoLEngine::resetBlockProperties() {
@@ -739,17 +774,26 @@
 	return true;
 }
 
-void LoLEngine::turnOnLamp() {
+void LoLEngine::resetLampStatus() {
 	_screen->_drawGuiFlag |= 0x400;
 	_lampOilStatus = 255;
 	updateLampStatus();
 }
 
+void LoLEngine::setLampMode(bool lampOn) {
+	_screen->_drawGuiFlag &= 0xFBFF;
+	if (!(_screen->_drawGuiFlag & 0x800) || !lampOn)
+		return;
+
+	_screen->drawShape(0, _gameShapes[43], 291, 56, 0, 0);
+	_lampOilStatus = 8;
+}
+
 void LoLEngine::updateLampStatus() {
 	uint8 newLampOilStatus = 0;
 	uint8 tmp2 = 0;
 
-	if ((_charFlagUnk & 4) || !(_screen->_drawGuiFlag & 0x800))
+	if ((_updateFlags & 4) || !(_screen->_drawGuiFlag & 0x800))
 		return;
 
 	if (!_brightness || !_lampStatusUnk) {
@@ -790,6 +834,10 @@
 	_lampOilStatus = newLampOilStatus;
 }
 
+void LoLEngine::updateCompass() {
+	
+}
+
 void LoLEngine::moveParty(uint16 direction, int unk1, int unk2, int unk3) {
 	// TODO
 	_currentBlock = calcNewBlockPostion(_currentBlock, direction);
@@ -801,12 +849,6 @@
 	return (curBlock + blockPosTable[direction]) & 0x3ff;
 }
 
-void LoLEngine::setLF1(uint16 & a, uint16 & b, int block, uint16 d, uint16 e) {
-	a = block & 0x1f;
-	a = ((a >> 8) | ((a & 0xff) << 8)) | d;
-	b = ((block & 0xffe0) << 3) | e;
-}
-
 void LoLEngine::setLF2(int block) {
 	if (!(_screen->_drawGuiFlag & 0x1000))
 		return;		
@@ -833,23 +875,24 @@
 	drawVcnBlocks(_vcnBlocks, _blockDrawingBuffer, _vcnShift, _sceneDrawPage1);
 	drawSceneShapes();
 
-	if (pageNum) {
+	if (!pageNum) {
 		drawScriptShapes(_sceneDrawPage1);
-		_screen->copyRegion(112, 112, 0, 0, 176, 120, _sceneDrawPage1, _sceneDrawPage2);
-		_screen->copyRegion(112, 112, 0, 0, 176, 120, _sceneDrawPage1, 0);
+		_screen->copyRegion(112, 0, 112, 0, 176, 120, _sceneDrawPage1, _sceneDrawPage2, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(112, 0, 112, 0, 176, 120, _sceneDrawPage1, 0, Screen::CR_NO_P_CHECK);
 		_sceneDrawPage1 ^= _sceneDrawPage2;
 		_sceneDrawPage2 ^= _sceneDrawPage1;
 		_sceneDrawPage1 ^= _sceneDrawPage2;
 	}
 
+	runLoopSub4(0);
 	gui_drawCompass();
 
-	_boolScriptFuncDone = false;
+	_sceneUpdateRequired = false;
 }
 
 void LoLEngine::updateSceneWindow() {
 	_screen->hideMouse();
-	_screen->copyRegion(112, 0, 112, 0, 176, 120, 0, _sceneDrawPage2);
+	_screen->copyRegion(112, 0, 112, 0, 176, 120, 0, _sceneDrawPage2, Screen::CR_NO_P_CHECK);
 	_screen->showMouse();
 }
 
@@ -1427,9 +1470,9 @@
 
 	if (flg & 0x1000) {
 		if (table)
-			_screen->drawShape(_sceneDrawPage1, shape, x, y, 13, flg | 0x9104, table, ovl, 1, _tlcTable1, _tlcTable2, _dmScaleW, _dmScaleH);			
+			_screen->drawShape(_sceneDrawPage1, shape, x, y, 13, flg | 0x9104, table, ovl, 1, _trueLightTable1, _trueLightTable2, _dmScaleW, _dmScaleH);			
 		else
-			_screen->drawShape(_sceneDrawPage1, shape, x, y, 13, flg | 0x1104, ovl, 1, _tlcTable1, _tlcTable2, _dmScaleW, _dmScaleH);			
+			_screen->drawShape(_sceneDrawPage1, shape, x, y, 13, flg | 0x1104, ovl, 1, _trueLightTable1, _trueLightTable2, _dmScaleW, _dmScaleH);			
 	} else {
 		if (table)
 			_screen->drawShape(_sceneDrawPage1, shape, x, y, 13, flg | 0x8104, table, ovl, 1, _dmScaleW, _dmScaleH);

Modified: scummvm/trunk/engines/kyra/screen_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/screen_lol.cpp	2009-02-01 14:56:19 UTC (rev 36177)
+++ scummvm/trunk/engines/kyra/screen_lol.cpp	2009-02-01 19:27:01 UTC (rev 36178)
@@ -44,6 +44,8 @@
 	
 	_fadeFlag = 2;
 	_drawGuiFlag = 0;
+	_curDimIndex = 0;
+	_dimLineCount = 0;
 }
 
 Screen_LoL::~Screen_LoL() {
@@ -63,6 +65,8 @@
 	debugC(9, kDebugLevelScreen, "Screen_LoL::setScreenDim(%d)", dim);
 	assert(dim < _screenDimTableCount);
 	_curDim = _customDimTable[dim] ? (const ScreenDim *)_customDimTable[dim] : &_screenDimTable[dim];
+	_curDimIndex = dim;
+	_dimLineCount = 0;
 }
 
 const ScreenDim *Screen_LoL::getScreenDim(int dim) {
@@ -89,6 +93,7 @@
 
 void Screen_LoL::clearCurDim() {
 	fillRect(_curDim->sx << 3, _curDim->sy, ((_curDim->sx + _curDim->w) << 3) - 1, (_curDim->sy + _curDim->h) - 1, _curDim->unkA);
+	_dimLineCount = 0;
 }
 
 void Screen_LoL::fprintString(const char *format, int x, int y, uint8 col1, uint8 col2, uint16 flags, ...) {
@@ -277,6 +282,22 @@
 	}
 }
 
+void Screen_LoL::fadeClearSceneWindow(int delay) {
+	if (_fadeFlag == 1)
+		return;
+	
+	uint8 *tpal = new uint8[768];
+
+	memcpy(tpal, _currentPalette, 768);
+	memset(tpal, 0, 384);
+	loadSpecialColours(tpal);
+	fadePalette(tpal, delay);
+	fillRect(112, 0, 288, 120, 0);
+	delete[] tpal;
+
+	_fadeFlag = 1;
+}
+
 void Screen_LoL::fadeToBlack(int delay, const UpdateFunctor *upFunc) {
 	Screen::fadeToBlack(delay, upFunc);
 	_fadeFlag = 2;
@@ -290,7 +311,7 @@
 
 void Screen_LoL::generateBrightnessPalette(uint8 *src, uint8 *dst, int brightness, int modifier) {
 	memcpy(dst, src, 0x300);
-	setPaletteColoursSpecial(dst);
+	loadSpecialColours(dst);
 	brightness = (8 - brightness) << 5;
 	if (modifier >= 0 && modifier < 8 && _drawGuiFlag & 0x800) {
 		brightness = 256 - ((((modifier & 0xfffe) << 5) * (256 - brightness)) >> 8);
@@ -304,12 +325,57 @@
 	}
 }
 
-void Screen_LoL::setPaletteColoursSpecial(uint8 *palette) {
-	const uint8 src[] = { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00 };
-	palette += 0x240;
-	memcpy(palette, src, 12);	
+void Screen_LoL::loadSpecialColours(uint8 *destPalette) {
+	memcpy(destPalette + 0x240, _screenPalette + 0x240, 12);	
 }
 
+void Screen_LoL::loadColour254(uint8 *destPalEntry) {
+	memcpy(destPalEntry, _screenPalette + 0x2fa, 3);
+}
+
+bool Screen_LoL::copyColour(int dstColorIndex, int srcColorIndex, uint32 time1, uint32 time2) {
+	uint8 *s = _screenPalette + 3 * dstColorIndex;
+	uint8 *e = _screenPalette + 3 * srcColorIndex;
+	uint8 *p = getPalette(1) + 3 * dstColorIndex;
+
+	bool res = false;
+
+	uint16 t1 = 0;
+	uint16 t2 = 0;
+	int32 t3 = 0;
+
+	uint8 tmpPalEntry[3];
+
+	for (int i = 0; i < 3; i++) {
+		if (time1 < time2) {
+			t1 = *e & 0x3f;
+			t2 = *s & 0x3f;
+
+			t3 = t1 - t2;
+			if (!t3)
+				res = true;
+
+			t3 = (((((t3 << 8) / time2) * time1) >> 8) & 0xffff) + t2;
+		} else {
+			t1 = *e & 0x3f;
+			*p = t3 = t1;
+			res = false;
+		}
+
+		tmpPalEntry[i] = t3 & 0xff;
+		s++;
+		e++;
+		p++;
+	}
+
+	uint8 tpal[768];
+	memcpy(tpal, _screenPalette, 768);
+	memcpy(tpal + dstColorIndex * 3, tmpPalEntry, 3);
+	setScreenPalette(tpal);
+
+	return res;
+}
+
 uint8 Screen_LoL::getShapePaletteSize(const uint8 *shp) {
 	debugC(9, kDebugLevelScreen, "Screen_LoL::getShapePaletteSize(%p)", (const void *)shp);
 

Modified: scummvm/trunk/engines/kyra/screen_lol.h
===================================================================
--- scummvm/trunk/engines/kyra/screen_lol.h	2009-02-01 14:56:19 UTC (rev 36177)
+++ scummvm/trunk/engines/kyra/screen_lol.h	2009-02-01 19:27:01 UTC (rev 36178)
@@ -39,6 +39,7 @@
 
 	void setScreenDim(int dim);
 	const ScreenDim *getScreenDim(int dim);
+	int curDimIndex() { return _curDimIndex; }
 	void modifyScreenDim(int dim, int x, int y, int w, int h);
 	void clearDim(int dim);
 	void clearCurDim();
@@ -47,15 +48,17 @@
 	void fprintStringIntro(const char *format, int x, int y, uint8 c1, uint8 c2, uint8 c3, uint16 flags, ...);
 
 	void drawGridBox(int x, int y, int w, int h, int col);
+	void fadeClearSceneWindow(int delay);
 
 	void fadeToBlack(int delay=0x54, const UpdateFunctor *upFunc = 0);
 	void setPaletteBrightness(uint8 *palDst, int brightness, int modifier);
 	void generateBrightnessPalette(uint8 *palSrc, uint8 *palDst, int brightness, int modifier);
-	void setPaletteColoursSpecial(uint8 *palette);
+	void loadSpecialColours(uint8 *destPalette);
+	void loadColour254(uint8 *destPalEntry);
+	bool copyColour(int dstColorIndex, int srcColorIndex, uint32 time1, uint32 time2);
 
 	void generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool skipSpecialColours);
 	uint8 *generateLevelOverlay(const uint8 *srcPal, uint8 *ovl, int opColor, int weight);
-
 	uint8 *getLevelOverlay(int index) { return _levelOverlays[index]; }
 
 	uint8 getShapePaletteSize(const uint8 *shp);
@@ -65,6 +68,7 @@
 	uint8 *_grayOverlay;
 	int _fadeFlag;
 	int _drawGuiFlag;
+	int _dimLineCount;
 
 private:
 	LoLEngine *_vm;
@@ -73,6 +77,7 @@
 	static const int _screenDimTableCount;
 
 	ScreenDim **_customDimTable;
+	int _curDimIndex;
 
 	uint8 *_levelOverlays[8];
 };

Modified: scummvm/trunk/engines/kyra/script_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/script_lol.cpp	2009-02-01 14:56:19 UTC (rev 36177)
+++ scummvm/trunk/engines/kyra/script_lol.cpp	2009-02-01 19:27:01 UTC (rev 36178)
@@ -85,18 +85,18 @@
 }
 
 bool LoLEngine::checkScriptUnk(int func) {
-	if (_boolScriptFuncDone)
+	if (_sceneUpdateRequired)
 		return true;
 
 	for (int i = 0; i < 15; i++) {
 		if (_scriptExecutedFuncs[i] == func) {
-			_boolScriptFuncDone = true;
+			_sceneUpdateRequired = true;
 			return true;
 		}
 	}
 
 	if (_currentBlock == func){
-		_boolScriptFuncDone = true;
+		_sceneUpdateRequired = true;
 		return true;
 	}
 
@@ -182,9 +182,9 @@
 	case 0:
 		return i->blockPropertyIndex;
 	case 1:
-		return i->unk7;
+		return i->p_1a;
 	case 2:
-		return i->anonymous_4;
+		return i->p_1b;
 	case 3:
 		return i->level;
 	case 4:
@@ -228,35 +228,45 @@
 	switch (stackPos(1)) {
 	case 0:
 		return c->flags;
+
 	case 1:
 		return c->raceClassSex;
-	case 2:
-	case 3:
-	case 4:
-	default:
-		break;
+
 	case 5:
 		return c->hitPointsCur;
+
 	case 6:
 		return c->hitPointsMax;
+
 	case 7:
 		return c->magicPointsCur;
+
 	case 8:
 		return c->magicPointsMax;
+
 	case 9:
 		return c->field_37;
+
 	case 10:
 		return c->items[d];
+
 	case 11:
 		return c->field_66[d] + c->field_69[d];
+
 	case 12:
 		return c->field_27[d];
+
 	case 13:
 		return (d & 0x80) ? c->field_25 : c->field_17[d];
+
 	case 14:
 		return c->field_69[d];
+
 	case 15:
 		return c->id;
+
+	default:
+		break;
 	}
 
 	return 0;
@@ -275,40 +285,60 @@
 	// fall through please add "// fall through" at the end of the
 	// case.
 	switch (stackPos(1)) {
+
 	case 0:
 		c->flags = e;
+		break;
+
 	case 1:
 		c->raceClassSex = e & 0x0f;
-	case 2:
-	case 3:
-	case 4:
-	default:
 		break;
+
 	case 5:
 		//// TODO
 		break;
+
 	case 6:
 		c->hitPointsMax = e;
+		break;
+
 	case 7:
 		//// TODO
 		break;
+
 	case 8:
 		c->magicPointsMax = e;
+		break;
+
 	case 9:
 		c->field_37 = e;
+		break;
+
 	case 10:
 		c->items[d] = 0;
+		break;
+
 	case 11:
 		c->field_66[d] = e;
+		break;
+
 	case 12:
 		c->field_27[d] = e;
+		break;
+
 	case 13:
 		if (d & 0x80)
 			c->field_25 = e;
 		else
 			c->field_17[d] = e;
+		break;
+
 	case 14:
 		c->field_69[d] = e;
+		break;
+
+	default:
+		break;
 	}
 
 	return 0;
@@ -360,6 +390,18 @@
 	return 1;
 }
 
+int LoLEngine::olol_initAnimStruct(EMCState *script) {
+	if (initTimAnimStruct(stackPos(1), stackPosString(0), stackPos(2), stackPos(3), stackPos(4), stackPos(5)))
+		return 1;
+	return 0;
+}
+
+int LoLEngine::olol_freeAnimStruct(EMCState *script) {
+	if (_tim->freeAnimStruct(stackPos(0)))
+		return 1;
+	return 0;
+}
+
 int LoLEngine::olol_setMusicTrack(EMCState *script) {
 	_curMusicTheme = stackPos(0);
 	return 1;
@@ -382,7 +424,7 @@
 	switch (stackPos(0)) {
 	case 0:
 		_currentBlock = b;
-		setLF1(_unkCmzU1, _unkCmzU2, _currentBlock, 0x80, 0x80);
+		calcCoordinates(_partyPosX, _partyPosY, _currentBlock, 0x80, 0x80);
 		setLF2(_currentBlock);			
 		break;
 	case 1:
@@ -405,8 +447,14 @@
 	case 7:			
 		break;
 	case 8:
-		_charFlagUnk = b;
-		//TODO
+		_updateFlags = b;
+		if (b == 1) {
+			if (!textEnabled() || !(_hideControls & 2))
+				charCallback4(1);
+			removeUnkFlags(2);
+		} else {
+			setUnkFlags(2);
+		}
 		break;
 	case 9:
 		_lampStatusUnk = b & 0xff;
@@ -441,6 +489,95 @@
 	return 1;
 }
 
+int LoLEngine::olol_loadMonsterProperties(EMCState *script) {
+	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadMonsterProperties(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)",
+		(const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5),
+		stackPos(6), stackPos(7), stackPos(8), stackPos(9), stackPos(10), stackPos(11), stackPos(12), stackPos(13),
+		stackPos(14), stackPos(15), stackPos(16), stackPos(17), stackPos(18), stackPos(19), stackPos(20),
+		stackPos(21), stackPos(22), stackPos(23), stackPos(24), stackPos(25), stackPos(26),	stackPos(27),
+		stackPos(28), stackPos(29), stackPos(30), stackPos(31), stackPos(32), stackPos(33), stackPos(34),
+		stackPos(35), stackPos(36), stackPos(37), stackPos(38), stackPos(39), stackPos(40), stackPos(41));
+
+	MonsterProperty *l = &_monsterProperties[stackPos(0) * 83];
+	l->id = stackPos(1) & 0xff;
+
+	int shpWidthMax = 0;
+
+	for (int i = 0; i < 16; i++) {
+		uint8 m = _monsterShapes[(l->id << 4) + i][3];
+		if (m > shpWidthMax)
+			shpWidthMax = m;	
+	}
+
+	l->maxWidth = shpWidthMax;
+
+	l->unk[0] = (stackPos(2) << 8) / 100;
+	l->unk[1] = 256;
+	l->unk[2] = (stackPos(3) << 8) / 100;
+	l->unk[3] = stackPos(4);
+	l->unk[4] = (stackPos(5) << 8) / 100;
+	l->unk[5] = (stackPos(6) << 8) / 100;
+	l->unk[6] = (stackPos(7) << 8) / 100;
+	l->unk[7] = (stackPos(8) << 8) / 100;
+	l->unk[8] = 0;
+
+	for (int i = 0; i < 8; i++) {
+		l->unk2[i] = stackPos(9 + i);
+		l->unk3[i] = (stackPos(17 + i) << 8) / 100;
+	}
+
+	l->pos = &l->unk[0];
+	l->unk4[0] = stackPos(25);
+	l->unk4[1] = stackPos(26);
+	l->b = 1;
+	l->unk5[0] = stackPos(27);
+	l->unk5[1] = stackPos(28);
+	// FIXME???
+	l->unk5[1] = stackPos(29);
+	//
+
+	for (int i = 0; i < 5; i++)
+		l->unk6[2 + i] = stackPos(30 + i);
+
+	for (int i = 0; i < 2; i++) {
+		l->unk7[i] = stackPos(35 + i);
+		l->unk7[i + 2] = stackPos(37 + i);
+	}
+
+	for (int i = 0; i < 3; i++)
+		l->unk8[2 + i] = stackPos(39 + i);
+
+	return 1;
+}
+
+int LoLEngine::olol_loadTimScript(EMCState *script) {
+	if (_activeTim[stackPos(0)])
+		return 1;	
+	char file[13];
+	snprintf(file, sizeof(file), "%s.TIM", stackPosString(1));
+	_activeTim[stackPos(0)] = _tim->load(file, &_timIngameOpcodes);
+	return 1;
+}
+
+int LoLEngine::olol_runTimScript(EMCState *script) {
+	return _tim->exec(_activeTim[stackPos(0)], stackPos(1));
+}
+
+int LoLEngine::olol_releaseTimScript(EMCState *script) {
+	_tim->unload(_activeTim[stackPos(0)]);
+	return 1;
+}
+
+int LoLEngine::olol_initDialogueSequence(EMCState *script) {
+	initDialogueSequence(stackPos(0));
+	return 1;
+}
+
+int LoLEngine::olol_restoreSceneAfterDialogueSequence(EMCState *script) {
+	restoreSceneAfterDialogueSequence(stackPos(0));
+	return 1;
+}
+
 int LoLEngine::olol_loadLangFile(EMCState *script) {
 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadLangFile(%p) (%s)", (const void *)script, stackPosString(0));
 	char filename[13];
@@ -451,6 +588,11 @@
 	return 1;
 }
 
+int LoLEngine::olol_stopTimScript(EMCState *script) {
+	_tim->stopAllFuncs(_activeTim[stackPos(0)]);
+	return 1;
+}
+
 int LoLEngine::olol_loadSoundFile(EMCState *script) {
 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadSoundFile(%p) (%d)", (const void *)script, stackPos(0));
 	snd_loadSoundFile(stackPos(0));
@@ -466,6 +608,23 @@
 	return old;
 }
 
+int LoLEngine::olol_playDialogueTalkText(EMCState *script) {
+	int track = stackPos(0);
+	
+	if (!snd_playCharacterSpeech(track, 0, 0) || textEnabled()) {
+		char *s = getLangString(track);
+		_dlg->play(4, s, script, 0, 1);
+	}
+
+	return 1;
+}
+
+int LoLEngine::olol_setNextFunc(EMCState *script) {
+	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setNextFunc(%p) (%d)", (const void *)script, stackPos(0));
+	_nextScriptFunc = stackPos(0);
+	return 1;
+}
+
 int LoLEngine::olol_assignCustomSfx(EMCState *script) {
 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_assignCustomSfx(%p) (%s, %d)", (const void *)script, stackPosString(0), stackPos(1));
 	const char *c = stackPosString(0);
@@ -484,6 +643,37 @@
 
 #pragma mark -
 
+TIMInterpreter::Animation *LoLEngine::initTimAnimStruct(int index, const char *filename, int x, int y, uint16 copyPara, uint16 wsaFlags) {
+	TIMInterpreter::Animation *a = _tim->initAnimStructIntern(index, filename, x, y, copyPara, wsaFlags);
+
+	_tim->setWsaDrawPage2(0);
+
+	if (wsaFlags & 1) {
+		if (_screen->_fadeFlag != 1)
+			_screen->fadeClearSceneWindow(10);
+		memcpy(_screen->getPalette(3) + 384, _screen->_currentPalette + 384, 384);
+	} else if (wsaFlags & 2) {
+		_screen->fadeToBlack(10);
+	}
+
+	if (wsaFlags & 7) {
+		_screen->hideMouse();
+		a->wsa->setDrawPage(0);
+		a->wsa->setX(x);
+		a->wsa->setY(y);
+		a->wsa->displayFrame(0, 0);
+		_screen->showMouse();
+	}
+
+	if (wsaFlags & 3) {
+		_screen->loadSpecialColours(_screen->getPalette(3));
+		_screen->fadePalette(_screen->getPalette(3), 10);
+		_screen->_fadeFlag = 0;
+	}
+
+	return a;
+}
+
 int LoLEngine::tlol_setupPaletteFade(const TIM *tim, const uint16 *param) {
 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::t2_playSoundEffect(%p, %p) (%d)", (const void*)tim, (const void*)param, param[0]);
 	_screen->getFadeParams(_screen->getPalette(0), param[0], _tim->_palDelayInc, _tim->_palDiff);
@@ -595,9 +785,9 @@
 
 	// 0x18
 	Opcode(olol_loadDoorShapes);
+	Opcode(olol_initAnimStruct);
 	OpcodeUnImpl();
-	OpcodeUnImpl();
-	OpcodeUnImpl();
+	Opcode(olol_freeAnimStruct);
 
 	// 0x1C
 	OpcodeUnImpl();
@@ -651,7 +841,7 @@
 	OpcodeUnImpl();
 	OpcodeUnImpl();
 	OpcodeUnImpl();
-	OpcodeUnImpl();
+	Opcode(olol_loadMonsterProperties);
 
 	// 0x40
 	OpcodeUnImpl();
@@ -674,14 +864,14 @@
 	// 0x4C
 	OpcodeUnImpl();
 	OpcodeUnImpl();
-	OpcodeUnImpl();
-	OpcodeUnImpl();
+	Opcode(olol_loadTimScript);
+	Opcode(olol_runTimScript);
 
 	// 0x50
+	Opcode(olol_releaseTimScript);
+	Opcode(olol_initDialogueSequence);
+	Opcode(olol_restoreSceneAfterDialogueSequence);
 	OpcodeUnImpl();
-	OpcodeUnImpl();
-	OpcodeUnImpl();
-	OpcodeUnImpl();
 
 	// 0x54
 	OpcodeUnImpl();
@@ -691,9 +881,9 @@
 
 	// 0x58
 	OpcodeUnImpl();
+	Opcode(olol_stopTimScript);
 	OpcodeUnImpl();
 	OpcodeUnImpl();
-	OpcodeUnImpl();
 
 	// 0x5C
 	OpcodeUnImpl();
@@ -740,14 +930,14 @@
 	// 0x78
 	OpcodeUnImpl();
 	OpcodeUnImpl();
+	Opcode(olol_playDialogueTalkText);
 	OpcodeUnImpl();
-	OpcodeUnImpl();
 
 	// 0x7C
+	Opcode(olol_setNextFunc);
 	OpcodeUnImpl();
 	OpcodeUnImpl();
 	OpcodeUnImpl();
-	OpcodeUnImpl();
 
 	// 0x80
 	OpcodeUnImpl();
@@ -846,7 +1036,6 @@
 	OpcodeUnImpl();
 
 	Common::Array<const TIMOpcode*> *timTable = 0;
-
 	SetTimOpcodeTable(_timIntroOpcodes);
 
 	// 0x00
@@ -860,6 +1049,35 @@
 	OpcodeTim(tlol_displayText);
 	OpcodeTimUnImpl();
 	OpcodeTimUnImpl();
+
+	SetTimOpcodeTable(_timIngameOpcodes);
+
+	// 0x00
+	OpcodeTimUnImpl();
+	OpcodeTimUnImpl();
+	OpcodeTimUnImpl();
+	OpcodeTimUnImpl();
+
+	// 0x04
+	OpcodeTimUnImpl();
+	OpcodeTimUnImpl();
+	OpcodeTimUnImpl();
+	OpcodeTimUnImpl();
+
+	// 0x08
+	OpcodeTimUnImpl();
+	OpcodeTimUnImpl();
+	OpcodeTimUnImpl();
+	OpcodeTimUnImpl();
+
+	// 0x0C
+	OpcodeTimUnImpl();
+	OpcodeTimUnImpl();
+	OpcodeTimUnImpl();
+	OpcodeTimUnImpl();
+
+	// 0x10
+	OpcodeTimUnImpl();
 }
 
 } // end of namespace Kyra

Modified: scummvm/trunk/engines/kyra/script_tim.cpp
===================================================================
--- scummvm/trunk/engines/kyra/script_tim.cpp	2009-02-01 14:56:19 UTC (rev 36177)
+++ scummvm/trunk/engines/kyra/script_tim.cpp	2009-02-01 19:27:01 UTC (rev 36178)
@@ -28,6 +28,7 @@
 #include "kyra/resource.h"
 #include "kyra/sound.h"
 #include "kyra/wsamovie.h"
+#include "kyra/gui_lol.h"
 
 #include "common/endian.h"
 
@@ -37,7 +38,7 @@
 #define COMMAND(x) { &TIMInterpreter::x, #x }
 #define COMMAND_UNIMPL() { 0, 0 }
 #define cmd_return(n) cmd_return_##n
-	static const CommandEntry commandProcs[] = {
+	static const CommandEntry commandProcsHOF[] = {
 		// 0x00
 		COMMAND(cmd_initFunc0),
 		COMMAND(cmd_stopCurFunc),
@@ -74,22 +75,69 @@
 		COMMAND(cmd_initFuncNow),
 		COMMAND(cmd_stopFuncNow),
 		// 0x1C
+		COMMAND(cmd_processDialogue),
+		COMMAND(cmd_dialogueBox),
+		COMMAND(cmd_return(n1))
+	};
+
+	static const CommandEntry commandProcsLOL[] = {
+		// 0x00
+		COMMAND(cmd_initFunc0),
+		COMMAND(cmd_stopAllFuncs),
+		COMMAND(cmd_initWSA),
+		COMMAND(cmd_uninitWSA),
+		// 0x04
+		COMMAND(cmd_initFunc),
+		COMMAND(cmd_stopFunc),
+		COMMAND(cmd_wsaDisplayFrame),
+		COMMAND_UNIMPL(),
+		// 0x08
+		COMMAND(cmd_loadVocFile),
+		COMMAND(cmd_unloadVocFile),
+		COMMAND(cmd_playVocFile),
+		COMMAND_UNIMPL(),
+		// 0x0C
+		COMMAND(cmd_loadSoundFile),
 		COMMAND(cmd_return(1)),
+		COMMAND(cmd_playMusicTrack),
+		COMMAND_UNIMPL(),
+		// 0x10
 		COMMAND(cmd_return(1)),
+		COMMAND(cmd_return(1)),
+		COMMAND_UNIMPL(),
+		COMMAND_UNIMPL(),
+		// 0x14
+		COMMAND(cmd_setLoopIp),
+		COMMAND(cmd_continueLoop),
+		COMMAND(cmd_resetLoopIp),
+		COMMAND(cmd_resetAllRuntimes),
+		// 0x18
+		COMMAND(cmd_return(1)),
+		COMMAND(cmd_execOpcode),
+		COMMAND(cmd_initFuncNow),
+		COMMAND(cmd_stopFuncNow),
+		// 0x1C
+		COMMAND(cmd_processDialogue),
+		COMMAND(cmd_dialogueBox),
 		COMMAND(cmd_return(n1))
 	};
 #undef cmd_return
 
-	_commands = commandProcs;
-	_commandsSize = ARRAYSIZE(commandProcs);
+	_commands = vm->game() == GI_LOL ? commandProcsLOL : commandProcsHOF ;
+	_commandsSize = vm->game() == GI_LOL ? ARRAYSIZE(commandProcsLOL) : ARRAYSIZE(commandProcsHOF);
 
 	memset(&_animations, 0, sizeof(_animations));
 	_langData = 0;
 	_textDisplayed = false;
 	_textAreaBuffer = new uint8[320*40];
 	assert(_textAreaBuffer);
+	_dlgSpeechEnabled = false;
+	_refresh = false;
+	_drawPage2 = 8;
 
-	_palDelayInc = _palDiff = _palDelayAcc = 0;
+	_palDelayInc = _palDiff = _palDelayAcc = 0;	
+	_dialogueComplete = 0;
+	_activeVoiceFile = 0;
 }
 
 TIMInterpreter::~TIMInterpreter() {
@@ -159,9 +207,9 @@
 	_langData = _vm->resource()->fileData(filename, 0);
 }
 
-void TIMInterpreter::exec(TIM *tim, bool loop) {
+int TIMInterpreter::exec(TIM *tim, bool loop) {
 	if (!tim)
-		return;
+		return 0;
 
 	_currentTim = tim;
 	if (!_currentTim->func[0].ip) {
@@ -170,14 +218,37 @@
 	}
 
 	do {
+		if (_refresh)
+			_vm->gui()->update();
 		for (_currentFunc = 0; _currentFunc < TIM::kCountFuncs; ++_currentFunc) {
 			TIM::Function &cur = _currentTim->func[_currentFunc];
 
 			if (_currentTim->procFunc != -1)
 				execCommand(28, &_currentTim->procParam);
 
-			bool running = true;
+			if (_refresh)
+				_vm->gui()->update();
+
+			if (_dlgSpeechEnabled && _currentTim->procParam > 1 && cur.loopIp) {
+				if (!_vm->sound()->voiceIsPlaying(_activeVoiceFile)) {
+					cur.loopIp = 0;
+					_currentTim->dlgFunc = _currentFunc;
+					advanceToOpcode(21);
+					_currentTim->dlgFunc = -1;
+				}
+			}
+
+			bool running = true;			
+			int cnt = 0;
 			while (cur.ip && cur.nextTime <= _system->getMillis() && running) {
+				if (cnt++ > 0) {
+					if (_currentTim->procFunc != -1)
+						execCommand(28, &_currentTim->procParam);
+
+					if (_refresh)
+						_vm->gui()->update();
+				}
+
 				int8 opcode = int8(cur.ip[2] & 0xFF);
 
 				switch (execCommand(opcode, cur.ip + 3)) {
@@ -193,6 +264,7 @@
 
 				case -3:
 					_currentTim->procFunc = _currentFunc;
+					_currentTim->dlgFunc = -1;
 					break;
 
 				case 22:
@@ -206,13 +278,20 @@
 				if (cur.ip) {
 					cur.ip += cur.ip[0];
 					cur.lastTime = cur.nextTime;
-					cur.nextTime += cur.ip[1] * _vm->tickLength();
+					cur.nextTime += (cur.ip[1] ) * _vm->tickLength();
 				}
 			}
 		}
-	} while (loop);
+	} while (loop && !_vm->shouldQuit());
+
+	return _currentTim->clickedButton;
 }
 
+void TIMInterpreter::stopAllFuncs(TIM *tim) {
+	for (int i = 0; i < TIM::kCountFuncs; ++i)
+		tim->func[i].ip = 0;
+}
+
 void TIMInterpreter::refreshTimersAfterPause(uint32 elapsedTime) {
 	if (!_currentTim)
 		return;
@@ -342,6 +421,7 @@
 	anim->x = x;
 	anim->y = y;
 	anim->wsaCopyParams = wsaFlags;
+	_drawPage2 = 8;
 
 	uint16 wsaOpenFlags = ((wsaFlags & 0x10) != 0) ? 2 : 0;
 
@@ -367,7 +447,7 @@
 			_screen->checkedPageUpdate(8, 4);
 			_screen->updateScreen();
 		}
-
+		
 		if (wsaFlags & 4) {
 			snprintf(file, 32, "%s.CPS", filename);
 
@@ -410,6 +490,41 @@
 	return anim;
 }
 
+TIMInterpreter::Animation *TIMInterpreter::initAnimStructIntern(int index, const char *filename, int x, int y, uint16 copyPara, uint16 wsaFlags) {
+	Animation *anim = &_animations[index];
+	anim->x = x;
+	anim->y = y;
+	anim->wsaCopyParams = wsaFlags;
+
+	uint16 wsaOpenFlags = 0;
+	if (wsaFlags & 0x10)
+		wsaOpenFlags |= 2;
+	if (wsaFlags & 8)
+		wsaOpenFlags |= 1;
+
+	char file[32];
+	snprintf(file, 32, "%s.WSA", filename);
+
+	if (_vm->resource()->exists(file)) {
+		anim->wsa = new WSAMovie_v2(_vm, _screen);
+		assert(anim->wsa);
+		anim->wsa->open(file, wsaOpenFlags, _screen->getPalette(3));
+	}
+
+	return anim;
+}
+
+int TIMInterpreter::freeAnimStruct(int index) {
+	Animation *anim = &_animations[index];
+	if (!anim)
+		return 0;
+
+	delete anim->wsa;
+	memset(anim, 0, sizeof(Animation));
+
+	return 1;
+}
+
 char *TIMInterpreter::getTableEntry(uint idx) {
 	if (!_langData)
 		return 0;
@@ -424,6 +539,22 @@
 		return (const char *)(_langData + READ_LE_UINT16(_langData + (idx<<1)));
 }
 
+void TIMInterpreter::advanceToOpcode(int opcode) {
+	TIM::Function *f = &_currentTim->func[_currentTim->dlgFunc];
+	uint16 len = f->ip[0];
+
+	while ((f->ip[2] & 0xFF) != opcode) {
+		if ((f->ip[2] & 0xFF) == 1) {
+			f->ip[0] = len;
+			break;
+		}
+		len = f->ip[0];
+		f->ip += len;
+	}
+
+	f->nextTime = _system->getMillis();
+}
+
 int TIMInterpreter::execCommand(int cmd, const uint16 *param) {
 	if (cmd < 0 || cmd >= _commandsSize) {
 		warning("Calling unimplemented TIM command %d from file '%s'", cmd, _currentTim->filename);
@@ -519,8 +650,10 @@
 
 	anim.wsa->setX(anim.x);
 	anim.wsa->setY(anim.y);
-	anim.wsa->setDrawPage((anim.wsaCopyParams & 0x4000) != 0 ? 2 : 8);
+	anim.wsa->setDrawPage((anim.wsaCopyParams & 0x4000) != 0 ? 2 : _drawPage2);
 	anim.wsa->displayFrame(frame, anim.wsaCopyParams & 0xF0FF, 0, 0);
+	if (!_drawPage2)
+		_screen->updateScreen();
 	return 1;
 }
 
@@ -573,7 +706,14 @@
 }
 
 int TIMInterpreter::cmd_setLoopIp(const uint16 *param) {
-	_currentTim->func[_currentFunc].loopIp = _currentTim->func[_currentFunc].ip;
+	if (_dlgSpeechEnabled) {
+		if (_vm->sound()->voiceIsPlaying(_activeVoiceFile))
+			_currentTim->func[_currentFunc].loopIp = _currentTim->func[_currentFunc].ip;
+		else
+			advanceToOpcode(21);
+	} else {
+		_currentTim->func[_currentFunc].loopIp = _currentTim->func[_currentFunc].ip;
+	}
 	return 1;
 }
 
@@ -585,14 +725,16 @@
 
 	func.ip = func.loopIp;
 
-	uint16 factor = param[0];
-	if (factor) {
-		const uint32 random = _vm->_rnd.getRandomNumberRng(0, 0x8000);
-		uint32 waitTime = (random * factor) / 0x8000;
-		func.nextTime += waitTime * _vm->tickLength();
+	if (!_vm->sound()->voiceIsPlaying(_activeVoiceFile)) {
+		uint16 factor = param[0];
+		if (factor) {
+			const uint32 random = _vm->_rnd.getRandomNumberRng(0, 0x8000);
+			uint32 waitTime = (random * factor) / 0x8000;
+			func.nextTime += waitTime * _vm->tickLength();
+		}
 	}
 
-	return 1;
+	return -2;
 }
 
 int TIMInterpreter::cmd_resetLoopIp(const uint16 *param) {
@@ -645,5 +787,59 @@
 	return 1;
 }
 
+int TIMInterpreter::cmd_stopAllFuncs(const uint16 *param) {
+	while (_currentTim->dlgFunc == -1 && _currentTim->clickedButton == 0 && !_vm->shouldQuit()) {
+		_vm->gui()->update();
+		_currentTim->clickedButton = _vm->gui()->processDialogue();
+	}
+
+	for (int i = 0; i < TIM::kCountFuncs; ++i)
+		_currentTim->func[i].ip = 0;
+
+	return -1;
+}
+
+int TIMInterpreter::cmd_processDialogue(const uint16 *param) {
+	int res = _vm->gui()->processDialogue();
+	if (!res ||!_currentTim->procParam)
+		return 0;
+
+	if (_vm->sound()->voiceIsPlaying(_activeVoiceFile))
+		_dialogueComplete = 0;
+
+	_currentTim->func[_currentTim->procFunc].loopIp = 0;
+	_currentTim->dlgFunc = _currentTim->procFunc;
+	_currentTim->procFunc = -1;
+	_currentTim->clickedButton = res;
+
+	if (_currentTim->procParam)
+		advanceToOpcode(21);	
+
+	return res;
+}
+
+int TIMInterpreter::cmd_dialogueBox(const uint16 *param) {
+	uint16 func = *param;
+	assert(func < TIM::kCountFuncs);
+	_currentTim->procParam = func;
+	_currentTim->clickedButton = 0;
+
+	const char *tmpStr[3];
+	int cnt = 0;
+
+	for (int i = 1; i < 4; i++) {
+		if (param[i] != 0xffff) {
+			tmpStr[i-1] = _vm->gui()->getTableString(param[i]);
+			cnt++;
+		} else {
+			tmpStr[i-1] = 0;
+		}
+	}
+
+	_vm->gui()->drawDialogueBox(cnt, tmpStr[0], tmpStr[1], tmpStr[2]);
+
+	return -3;
+}
+
 } // end of namespace Kyra
 

Modified: scummvm/trunk/engines/kyra/script_tim.h
===================================================================
--- scummvm/trunk/engines/kyra/script_tim.h	2009-02-01 14:56:19 UTC (rev 36177)
+++ scummvm/trunk/engines/kyra/script_tim.h	2009-02-01 19:27:01 UTC (rev 36178)
@@ -42,6 +42,9 @@
 struct TIM {
 	char filename[13];
 
+	uint16 clickedButton;
+	int16 dlgFunc;
+
 	int16 procFunc;
 	uint16 procParam;
 
@@ -50,14 +53,14 @@
 	};
 
 	struct Function {
-		const uint16 *ip;
+		uint16 *ip;
 
 		uint32 lastTime;
 		uint32 nextTime;
 
-		const uint16 *loopIp;
+		uint16 *loopIp;
 
-		const uint16 *avtl;
+		uint16 *avtl;
 	} func[kCountFuncs];
 
 	enum {
@@ -92,16 +95,26 @@
 	TIM *load(const char *filename, const Common::Array<const TIMOpcode*> *opcodes);
 	void unload(TIM *&tim) const;
 
+	Animation *initAnimStructIntern(int index, const char *filename, int x, int y, uint16 copyPara, uint16 wsaFlags);
+	int freeAnimStruct(int index);
+
 	void setLangData(const char *filename);
 	void clearLangData() { delete[] _langData; _langData = 0; }
 
+	void toggleDialogueSpeech(bool enable) { _dlgSpeechEnabled = enable; }
+	void toggleRefresh(bool enable) { _refresh = enable; }
+	void setWsaDrawPage2(int pageNum) { _drawPage2 = pageNum; }
+	void setDialogueCompleteFlag(int val) { _dialogueComplete = val; }
+	void setActiveSpeechFile(const char *filename) { _activeVoiceFile = filename; }
+
 	const char *getCTableEntry(uint idx) const;
 
 	void resetFinishedFlag() { _finished = false; }
 	bool finished() const { return _finished; }
 
-	void exec(TIM *tim, bool loop);
+	int exec(TIM *tim, bool loop);
 	void stopCurFunc() { if (_currentTim) cmd_stopCurFunc(0); }
+	void stopAllFuncs(TIM *tim);
 
 	void refreshTimersAfterPause(uint32 elapsedTime);
 
@@ -109,6 +122,7 @@
 	void setupTextPalette(uint index, int fadePalette);
 
 	int _palDelayInc, _palDiff, _palDelayAcc;
+
 private:
 	KyraEngine_v1 *_vm;
 	Screen_v2 *_screen;
@@ -121,10 +135,9 @@
 
 	Common::String _vocFiles[120];
 
+	Animation *initAnimStruct(int index, const char *filename, int x, int y, int, int offscreenBuffer, uint16 wsaFlags);
 	Animation _animations[TIM::kWSASlots];
 
-	Animation *initAnimStruct(int index, const char *filename, int x, int y, int, int offscreenBuffer, uint16 wsaFlags);
-
 	char _audioFilename[32];
 
 	uint8 *_langData;
@@ -132,6 +145,14 @@
 	bool _textDisplayed;
 	uint8 *_textAreaBuffer;
 
+	bool _dlgSpeechEnabled;
+	bool _refresh;
+	int _drawPage2;
+
+	int _dialogueComplete;
+	const char *_activeVoiceFile;
+
+	void advanceToOpcode(int del);
 	int execCommand(int cmd, const uint16 *param);
 
 	typedef int (TIMInterpreter::*CommandProc)(const uint16 *);
@@ -163,6 +184,11 @@
 	int cmd_execOpcode(const uint16 *param);
 	int cmd_initFuncNow(const uint16 *param);
 	int cmd_stopFuncNow(const uint16 *param);
+
+	int cmd_stopAllFuncs(const uint16 *param);
+	int cmd_processDialogue(const uint16 *param);
+	int cmd_dialogueBox(const uint16 *param);
+
 #define cmd_return(n, v) \
 	int cmd_return_##n(const uint16 *) { return v; }
 

Modified: scummvm/trunk/engines/kyra/sound.cpp
===================================================================
--- scummvm/trunk/engines/kyra/sound.cpp	2009-02-01 14:56:19 UTC (rev 36177)
+++ scummvm/trunk/engines/kyra/sound.cpp	2009-02-01 19:27:01 UTC (rev 36178)
@@ -115,6 +115,29 @@
 	return audioStream->getTotalPlayTime();
 }
 
+void Sound::voicePlayFromList(Common::List<const char*> fileList) {
+	int h = 0;
+	while (_mixer->isSoundHandleActive(_soundChannels[h].channelHandle) && h < kNumChannelHandles)
+		h++;
+	if (h >= kNumChannelHandles)
+		return;
+
+	Audio::AppendableAudioStream *out = Audio::makeAppendableAudioStream(22050, Audio::Mixer::FLAG_AUTOFREE | Audio::Mixer::FLAG_UNSIGNED);
+	
+	for (Common::List<const char*>::iterator i = fileList.begin(); i != fileList.end(); i++) {
+		int size;
+		int rate;
+		uint8 *file = _vm->resource()->fileData(*i, (uint32*)&size);
+		Common::MemoryReadStream vocStream(file, (uint32)size);
+		uint8 *data = Audio::loadVOCFromStream(vocStream, size, rate);
+		out->queueBuffer(data, size);		
+	}
+	out->finish();
+	
+	_soundChannels[h].file = *fileList.begin();
+	_mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &_soundChannels[h].channelHandle, out);
+}
+
 void Sound::voiceStop(const char *file) {
 	if (!file) {
 		for (int h = 0; h < kNumChannelHandles; h++) {

Modified: scummvm/trunk/engines/kyra/sound.h
===================================================================
--- scummvm/trunk/engines/kyra/sound.h	2009-02-01 14:56:19 UTC (rev 36177)
+++ scummvm/trunk/engines/kyra/sound.h	2009-02-01 19:27:01 UTC (rev 36178)
@@ -197,6 +197,14 @@
 	virtual int32 voicePlay(const char *file, bool isSfx = false);
 
 	/**
+	 * Queues the specified voice files in an AppendableAudioStream
+	 * and plays them.
+	 *
+	 * @param fileList:	files to be played
+	 */
+	virtual void voicePlayFromList(Common::List<const char*> fileList);
+
+	/**
 	 * Checks if a voice is being played.
 	 *
 	 * @return true when playing, else false

Modified: scummvm/trunk/engines/kyra/staticres.cpp
===================================================================
--- scummvm/trunk/engines/kyra/staticres.cpp	2009-02-01 14:56:19 UTC (rev 36177)
+++ scummvm/trunk/engines/kyra/staticres.cpp	2009-02-01 19:27:01 UTC (rev 36178)
@@ -40,6 +40,7 @@
 #include "kyra/gui_lok.h"
 #include "kyra/gui_hof.h"
 #include "kyra/gui_mr.h"
+#include "kyra/gui_lol.h"
 
 namespace Kyra {
 
@@ -2622,6 +2623,14 @@
 
 // lands of lore static res
 
+void GUI_LoL::initStaticData() {
+
+}
+
+void LoLEngine::initButtonList() {
+	
+}
+
 const ScreenDim Screen_LoL::_screenDimTable[] = {
 	{ 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 },	// Taken from Intro
 	{ 0x08, 0x48, 0x18, 0x38, 0xFE, 0x01, 0x00, 0x00 },

Added: scummvm/trunk/engines/kyra/text_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/text_lol.cpp	                        (rev 0)
+++ scummvm/trunk/engines/kyra/text_lol.cpp	2009-02-01 19:27:01 UTC (rev 36178)
@@ -0,0 +1,573 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "kyra/lol.h"
+#include "kyra/screen_lol.h"
+#include "kyra/util.h"
+
+namespace Kyra {
+
+TextDisplayer_LoL::TextDisplayer_LoL(LoLEngine *vm, Screen_LoL *screen) : _vm(vm), _screen(screen),
+	_scriptParameter(0), _stringLength(0), _animWidth(0), _animColour1(0), _animColour2(0), _animFlag(true),
+	_printFlag(false), _lineWidth(0), _numChars(0), _numCharsPrinted(0), _posX(0), _posY(0), _colour1(0), _colour2(0) {
+	
+	memset(_stringParameters, 0, 15 * sizeof(char*));
+	_buffer = new char[600];
+	memset(_buffer, 0, 600);
+
+	_out = new char[1024];
+	memset(_out, 0, 1024);
+
+	_backupBuffer = new char[40];
+	memset(_out, 0, 40);
+
+	_currentLine = new char[85];

@@ Diff output truncated at 100000 characters. @@

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list