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

athrxx at users.sourceforge.net athrxx at users.sourceforge.net
Sun Jan 18 18:04:24 CET 2009


Revision: 35903
          http://scummvm.svn.sourceforge.net/scummvm/?rev=35903&view=rev
Author:   athrxx
Date:     2009-01-18 17:04:24 +0000 (Sun, 18 Jan 2009)

Log Message:
-----------
LOL: Some drawing code and some opcodes so that the first scene will show up. Playing is not possible. This is still somewhat messy since a lot of stuff hasn't been figured out yet.

Modified Paths:
--------------
    scummvm/trunk/dists/engine-data/kyra.dat
    scummvm/trunk/engines/kyra/lol.cpp
    scummvm/trunk/engines/kyra/lol.h
    scummvm/trunk/engines/kyra/module.mk
    scummvm/trunk/engines/kyra/resource.h
    scummvm/trunk/engines/kyra/screen_lol.cpp
    scummvm/trunk/engines/kyra/screen_lol.h
    scummvm/trunk/engines/kyra/screen_v2.cpp
    scummvm/trunk/engines/kyra/screen_v2.h
    scummvm/trunk/engines/kyra/script.h
    scummvm/trunk/engines/kyra/staticres.cpp
    scummvm/trunk/tools/create_kyradat/create_kyradat.cpp
    scummvm/trunk/tools/create_kyradat/create_kyradat.h
    scummvm/trunk/tools/create_kyradat/lol_demo.h
    scummvm/trunk/tools/create_kyradat/misc.h

Added Paths:
-----------
    scummvm/trunk/engines/kyra/gui_lol.cpp
    scummvm/trunk/engines/kyra/items_lol.cpp
    scummvm/trunk/engines/kyra/scene_lol.cpp
    scummvm/trunk/engines/kyra/script_lol.cpp
    scummvm/trunk/tools/create_kyradat/lol_cd.h

Modified: scummvm/trunk/dists/engine-data/kyra.dat
===================================================================
(Binary files differ)

Added: scummvm/trunk/engines/kyra/gui_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/gui_lol.cpp	                        (rev 0)
+++ scummvm/trunk/engines/kyra/gui_lol.cpp	2009-01-18 17:04:24 UTC (rev 35903)
@@ -0,0 +1,361 @@
+/* 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"
+
+namespace Kyra {
+
+void LoLEngine::gui_drawPlayField() {
+	_screen->loadBitmap("PLAYFLD.CPS", 3, 3, 0);
+
+	if (_screen->_drawGuiFlag & 0x4000) {
+		// 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;
+	}
+
+	if (_screen->_drawGuiFlag & 0x1000)
+		// draw automap book
+		_screen->drawShape(2, _gameShapes[78], 289, 32, 0, 0);
+
+	int cp = _screen->setCurPage(2);
+
+	if (_screen->_drawGuiFlag & 0x2000) {
+		gui_drawScroll();
+	} else {
+		_selectedSpell = 0;
+	}
+
+	if (_screen->_drawGuiFlag & 0x800)
+		turnOnLamp();
+
+	//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)
+		drawScene(pageNum);
+}
+
+void LoLEngine::gui_drawInventory() {
+	if (!_unkInventFlag || !_updateCharV6) {
+		for (int i = 0; i < 9; i++)
+			gui_drawInventoryItem(i);
+	}
+}
+
+void LoLEngine::gui_drawInventoryItem(int index) {
+	static const uint16 inventoryXpos[] = { 0x6A, 0x7F, 0x94, 0xA9, 0xBE, 0xD3, 0xE8, 0xFD, 0x112 };
+	int x = inventoryXpos[index];
+	int item = _inventoryCurItem + index;
+	if (item > 48)
+		item -= 48;
+
+	int flag = item & 1 ? 0 : 1;
+
+	_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);
+	_screen->showMouse();
+}
+
+void LoLEngine::gui_drawScroll() {
+	_screen->copyRegion(112, 0, 12, 0, 87, 15, 2, 2, Screen::CR_NO_P_CHECK);
+	int h = 0;
+	
+	for (int i = 0; i < 7; i++) {
+		if (_availableSpells[i] != -1)
+			h += 9;
+	}
+
+	if (h == 18)
+		h = 27;
+
+	if (h) {		
+		_screen->copyRegion(201, 1, 17, 15, 6, h, 2, 2, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(208, 1, 89, 15, 6, h, 2, 2, Screen::CR_NO_P_CHECK);
+		_screen->fillRect(21, 15, 89, h + 15, 206);
+	}
+
+	_screen->copyRegion(112, 16, 12, h + 15, 87, 14, 2, 2, Screen::CR_NO_P_CHECK);
+
+	int y = 15;
+	for (int i = 0; i < 7; i++) {
+		if (_availableSpells[i] == -1)
+			continue;
+		uint8 col = (i == _selectedSpell) ? 132 : 1;
+		_screen->fprintString(getLangString(_spellProperties[_availableSpells[i]].spellNameCode), 24, y, col, 0, 0);
+		y += 9;
+	}
+}
+
+void LoLEngine::gui_drawAllCharPortraitsWithStats() {
+	int numChars = countActiveCharacters();
+	if (!numChars)
+		return;
+
+	for (int i = 0; i < numChars; i++)
+		gui_drawCharPortraitWithStats(i);
+}
+
+void LoLEngine::gui_drawCharPortraitWithStats(int charNum) {
+	if (!(_characters[charNum].flags & 1) || _charFlagUnk & 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_drawCharFaceShape(0, 0, 1, _screen->_curPage);
+
+	gui_drawLiveMagicBar(33, 32, _characters[charNum].magicPointsCur, 0, _characters[charNum].magicPointsMax, 5, 32, 162, 1, 0);
+	gui_drawLiveMagicBar(39, 32, _characters[charNum].hitPointsCur, 0, _characters[charNum].hitPointsMax, 5, 32, 154, 1, 1);
+
+	_screen->printText(getLangString(0x4253), 33, 1, 160, 0);
+	_screen->printText(getLangString(0x4254), 39, 1, 152, 0);
+
+	int spellLevels = 0;
+	for (int i = 0; i < 4; i++) {
+		if (_spellProperties[_availableSpells[_selectedSpell]].mpRequired[i] <= _characters[charNum].magicPointsCur &&
+			_spellProperties[_availableSpells[_selectedSpell] + 1].unkArr[i] <= _characters[charNum].hitPointsCur)
+				spellLevels++;
+	}
+
+	if (_characters[charNum].flags & 0x10) {
+		// magic submenu open
+		_screen->drawShape(_screen->_curPage, _gameShapes[73], 44, 0, 0, 0);
+		if (spellLevels < 4)
+			_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;
+		}*/
+
+		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);
+		// draw magic symbol
+		_screen->drawShape(_screen->_curPage, _gameShapes[72 + _characters[charNum].field_41], 44, 17, 0, 0);
+
+		if (spellLevels == 0)
+			_screen->drawGridBox(44, 17, 22, 15, 1);
+	}	
+
+	uint16 f = _characters[charNum].flags & 0x314C;
+	if ((f == 0 && (f != 4 || _characters[charNum].weaponHit == 0)) || _weaponsDisabled)
+		_screen->drawGridBox(44, 0, 22, 34, 1);
+
+	if (_characters[charNum].weaponHit) {
+		_screen->drawShape(_screen->_curPage, _gameShapes[34], 44, 0, 0, 0);
+		_screen->fprintString("%d", 57, 7, 254, 0, 1, _characters[charNum].weaponHit);
+	}
+	if (_characters[charNum].damageSuffered) 
+		_screen->fprintString("%d", 17, 28, 254, 0, 1, _characters[charNum].damageSuffered);
+
+	if (!cp)
+		_screen->hideMouse();
+
+	uint8 col = (charNum != _unkDrawPortraitIndex || 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);
+
+	if (!cp)
+		_screen->showMouse();
+
+	_screen->setCurPage(cp);
+	_screen->setFont(tmpFid);
+}
+
+void LoLEngine::gui_drawPortraitBox(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);
+
+	_screen->drawClippedLine(x + 1, y, x + w, y, frameColor2);
+	_screen->drawClippedLine(x + w, y, x + w, y + h - 1, frameColor2);
+	_screen->drawClippedLine(x, y, x, y + h, frameColor1);
+	_screen->drawClippedLine(x, y + h, x + w, y + h, frameColor1);		
+}
+
+void LoLEngine::gui_drawCharFaceShape(int charNum, int x, int y, int pageNum) {
+	if (_characters[charNum].curFaceFrame < 7 && _characters[charNum].nextFaceFrame)
+		_characters[charNum].curFaceFrame = _characters[charNum].nextFaceFrame;
+
+	if (_characters[charNum].nextFaceFrame == 0 && _characters[charNum].curFaceFrame > 1 && _characters[charNum].curFaceFrame < 7)
+		_characters[charNum].curFaceFrame = _characters[charNum].nextFaceFrame;
+
+	int frm = (_characters[charNum].flags & 0x1108 && _characters[charNum].curFaceFrame < 7) ? 1 : _characters[charNum].curFaceFrame;
+
+	if (_characters[charNum].hitPointsCur <= (_characters[charNum].hitPointsMax >> 1))
+		frm += 14;
+
+	if (!pageNum)
+		_screen->hideMouse();
+
+	_screen->drawShape(pageNum, _characterFaceShapes[frm][charNum], x, y, 0, 0x100, _screen->_paletteOverlay2, (_characters[charNum].flags & 0x80 ? 1 : 0));
+
+	if (_characters[charNum].flags & 0x40)
+		// draw spider web
+		_screen->drawShape(pageNum, _gameShapes[21], x, y, 0, 0);
+
+	if (!pageNum)
+		_screen->showMouse();
+}
+
+void LoLEngine::gui_drawLiveMagicBar(int x, int y, int curPoints, int unk, int maxPoints, int w, int h, int col1, int col2, int flag) {
+	w--;
+	h--;
+
+	if (maxPoints < 1)
+		return;
+
+	int t = (curPoints < 1) ? 0 : curPoints;
+	curPoints = (maxPoints < t) ? maxPoints : t;
+
+	int barHeight = (curPoints * h) / maxPoints;
+
+	if (barHeight < 1 && curPoints < 1)
+		barHeight = 1;
+
+	_screen->drawClippedLine(x - 1, y - h, x - 1, y, 1);
+
+	if (flag) {
+		t = maxPoints >> 1;
+		if (t > curPoints)
+			col1 = 144;
+		t = maxPoints >> 2;
+		if (t > curPoints)
+			col1 = 132;
+	}
+
+	if (barHeight > 0)
+		_screen->fillRect(x, y - barHeight, x + w, y, col1);
+
+	if (barHeight < h)
+		_screen->fillRect(x, y - h, x + w, y - barHeight, col2);
+
+	if (unk > 0 && unk < maxPoints)
+		_screen->drawBox(x, y - barHeight, x + w, y, col1 - 2);
+}
+
+void LoLEngine::calcCharPortraitXpos() {
+	int nc = countActiveCharacters();
+
+	// TODO
+
+	int t = (235 - (nc * 66)) / (nc + 1);
+	for (int i = 0; i < nc; i++)
+		_activeCharsXpos[i] = i * 66 + t * (i + 1) + 83;	
+}
+
+void LoLEngine::gui_drawMoneyBox(int pageNum) {
+	static const uint16 moneyX[] = { 0x128, 0x134, 0x12b, 0x131, 0x12e};
+	static const uint16 moneyY[] = { 0x73, 0x73, 0x74, 0x74, 0x75};
+
+	int backupPage = _screen->_curPage;
+	_screen->_curPage = pageNum;
+
+	_screen->fillRect(292, 97, 316, 118, 252, pageNum);
+
+	for (int i = 0; i < 5; i++) {
+		if (!_moneyColumnHeight[i])
+			continue;
+
+		uint8 h = _moneyColumnHeight[i] - 1;
+		_screen->drawClippedLine(moneyX[i], moneyY[i], moneyX[i], moneyY[i] - h, 0xd2);
+		_screen->drawClippedLine(moneyX[i] + 1, moneyY[i], moneyX[i] + 1, moneyY[i] - h, 0xd1);
+		_screen->drawClippedLine(moneyX[i] + 2, moneyY[i], moneyX[i] + 2, moneyY[i] - h, 0xd0);
+		_screen->drawClippedLine(moneyX[i] + 3, moneyY[i], moneyX[i] + 3, moneyY[i] - h, 0xd1);
+		_screen->drawClippedLine(moneyX[i] + 4, moneyY[i], moneyX[i] + 4, moneyY[i] - h, 0xd2);
+	}
+
+	Screen::FontId backupFont = _screen->setFont(Screen::FID_6_FNT);
+	_screen->fprintString("%d", 305, 98, 254, 0, 1, _credits); 
+
+	_screen->setFont(backupFont);
+	_screen->_curPage = backupPage;
+
+	if (pageNum == 6) {
+		_screen->hideMouse();
+		_screen->copyRegion(292, 97, 292, 97, 25, 22, 6, 0);
+		_screen->showMouse();
+	}
+}
+
+void LoLEngine::gui_drawCompass() {
+	if (!(_screen->_drawGuiFlag & 0x4000))
+		return;
+
+	if (_updateUnk2 == -1) {
+		_compassDirectionIndex = -1;
+		_updateUnk2 = _unkPara2 << 6;
+	}
+
+	int t = ((_updateUnk2 + 4) >> 3) & 0x1f;
+
+	if (t == _compassDirectionIndex)
+		return;
+
+	_compassDirectionIndex = t;
+
+	if (!_screen->_curPage)
+		_screen->hideMouse();
+
+	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], 299 + c->x, c->y + 8, 0, c->flags);
+
+	if (!_screen->_curPage)
+		_screen->showMouse();
+}
+
+} // end of namespace Kyra
+


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

Added: scummvm/trunk/engines/kyra/items_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/items_lol.cpp	                        (rev 0)
+++ scummvm/trunk/engines/kyra/items_lol.cpp	2009-01-18 17:04:24 UTC (rev 35903)
@@ -0,0 +1,186 @@
+/* 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"
+
+namespace Kyra {
+
+void LoLEngine::giveCredits(int credits, int redraw) {
+	static const uint8 stashSetupData[] = { 4, 4, 4, 4, 2, 2, 2, 3, 3, 0, 1, 1 };
+
+	if (redraw)
+		snd_playSoundEffect(0x65, 0xff);
+
+	int t = credits / 30;
+	if (!t)
+		t = 1;
+
+	int cnt = 0;
+
+	while (credits) {
+		if (t > credits)
+			t = credits;
+
+		if (_credits < 60 && t >= 0) {
+			cnt = 0;
+
+			do {
+				if (_credits < 60) {
+					int d = stashSetupData[_credits % 12] - _credits / 12;
+					if (d < 0)
+						d += 5;
+					_moneyColumnHeight[d]++;
+				}
+				_credits++;
+			} while(++cnt < t);
+		} else if (_credits >= 60) {
+			_credits += t;
+		}
+
+		if (redraw) {
+			gui_drawMoneyBox(6);
+			//if (credits)
+			//	TODO: delay/update
+		}
+		credits -= t;
+	}
+}
+
+int LoLEngine::makeItem(int itemIndex, int curFrame, int flags) {
+	int cnt = 0;
+	int r = 0;
+	int i = 1;
+
+	for (; i < 400; i++) {
+		if (_itemsInPlay[i].shpCurFrame_flg & 0x8000) {
+			cnt = 0;
+			break;
+		}
+
+		if (_itemsInPlay[i].level < 1 || _itemsInPlay[i].level > 29 || _itemsInPlay[i].level == _currentLevel)
+			continue;
+
+		int diff = ABS(_currentLevel - _itemsInPlay[i].level);
+		
+		if (diff <= cnt)
+			continue;
+
+		bool t = false;
+		int ii = i;
+		while (ii && !t) {
+			t = testUnkItemFlags(ii);
+			if (t)
+				break;
+			else
+				ii = _itemsInPlay[ii - 1].itemIndexUnk;				
+		}
+
+		if (t) {
+			cnt = diff;
+			r = i;
+		}
+	}
+
+	int slot = i;
+	if (cnt) {
+		slot = r;
+		if (testUnkItemFlags(r)) {
+			if (_itemsInPlay[r].itemIndexUnk)
+				_itemsInPlay[_itemsInPlay[r].itemIndexUnk].level = _itemsInPlay[r].level;
+			clearItemTableEntry(r);
+			slot = r;
+		} else {
+			int ii = _itemsInPlay[slot].itemIndexUnk;
+			while(ii) {				
+				if (testUnkItemFlags(ii)) {
+					_itemsInPlay[slot].itemIndexUnk = _itemsInPlay[ii].itemIndexUnk;
+					clearItemTableEntry(ii);
+					slot = ii;
+					break;
+				} else {
+					slot = ii;
+				}
+				ii = _itemsInPlay[slot].itemIndexUnk;
+			}
+		}
+	}
+
+	memset(&_itemsInPlay[slot], 0, sizeof(ItemInPlay));
+	
+	_itemsInPlay[slot].itemPropertyIndex = itemIndex;
+	_itemsInPlay[slot].shpCurFrame_flg = (curFrame & 0x1fff) | flags;
+	_itemsInPlay[slot].level = -1;
+
+	return slot;
+}
+
+bool LoLEngine::testUnkItemFlags(int itemIndex) {
+	if (!(_itemsInPlay[itemIndex].shpCurFrame_flg & 0x4000))
+		return false;
+
+	if (_itemProperties[_itemsInPlay[itemIndex].itemPropertyIndex].flags & 4)
+		return false;
+
+	return true;
+
+}
+
+void LoLEngine::clearItemTableEntry(int itemIndex) {
+	memset(&_itemsInPlay[itemIndex], 0, sizeof(ItemInPlay));
+	_itemsInPlay[itemIndex].shpCurFrame_flg |= 0x8000;
+}
+
+void *LoLEngine::cmzGetItemOffset(uint16 index) {
+	if (index & 0x8000)
+		return &_lvlBuffer[index & 0x7fff];
+	else
+		return &_itemsInPlay[index];
+}
+
+void LoLEngine::runItemScript(int reg1, int slot, int reg0, int reg3, int reg4) {
+	EMCState scriptState;
+	memset(&scriptState, 0, sizeof(EMCState));
+
+	uint8 func = slot ? _itemProperties[_itemsInPlay[slot].itemPropertyIndex].itemScriptFunc : 3;
+	if (func == 0xff)
+		return;
+
+	_emc->init(&scriptState, &_itemScript);
+	_emc->start(&scriptState, func);
+
+	scriptState.regs[0] = reg0;
+	scriptState.regs[1] = reg1;
+	scriptState.regs[2] = slot;
+	scriptState.regs[3] = reg3;
+	scriptState.regs[4] = reg4;
+
+	while (_emc->isValid(&scriptState))
+		_emc->run(&scriptState);
+}
+
+} // end of namespace Kyra
+
+


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

Modified: scummvm/trunk/engines/kyra/lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/lol.cpp	2009-01-18 16:49:03 UTC (rev 35902)
+++ scummvm/trunk/engines/kyra/lol.cpp	2009-01-18 17:04:24 UTC (rev 35903)
@@ -58,26 +58,205 @@
 		break;
 	}
 
-	memset(_shapes, 0, sizeof(_shapes));
-
 	_chargenWSA = 0;
 	_lastUsedStringBuffer = 0;
 	_landsFile = 0;
+	_levelLangFile = 0;
+
+	_lastSfxTrack = -1;
+
+	memset(_moneyColumnHeight, 0, 5);
+	_credits = 0;
+
+	_itemsInPlay = 0;
+	_itemProperties = 0;
+	_itemInHand = 0;
+	memset(_inventoryItemIndex, 0, 48);
+	_inventoryCurItem = 0;
+	_unkInventFlag = 0;
+
+	_itemIconShapes = _itemShapes = _gameShapes = _thrownShapes = _iceShapes = _fireballShapes = 0;
+	_levelShpList = _levelDatList = 0;
+	_monsterShapes = _monsterPalettes = 0;
+	_buf4 = 0;
+	_gameShapeMap = 0;
+	memset(_monsterUnk, 0, 3);
+
+	_charSelection = -1;
+	_characters = 0;
+	_spellProperties = 0;
+	_charFlagUnk = 0;
+	_selectedSpell = 0;
+	_updateCharNum = _updateCharV1 = _updateCharV2 = _updateCharV3 = _updateCharV4 = _updateCharV5 = _updateCharV6 = 0;
+	_updateCharTime = _updatePortraitNext = 0;
+	_lampStatusTimer = 0xffffffff;
+
+	_weaponsDisabled = false;
+	_unkDrawPortraitIndex = 0;
+	_unkFlag = 0;
+	_scriptBoolSkipExec = _boolScriptFuncDone = false;
+	_unkScriptByte = 0;
+	_unkPara2 = 0;
+	_currentBlock = 0;
+	memset(_scriptExecutedFuncs, 0, 18 * sizeof(uint16));
+
+	_wllVmpMap = _wllBuffer3 = _wllBuffer4 = _wllBuffer5 = 0;
+	_wllShapeMap = 0;
+	_lvlShapeTop = _lvlShapeBottom = _lvlShapeLeftRight = 0;
+	_cmzBuffer = 0;
+	_lvlBuffer = 0;
+	_lvl415 = 0;
+	_lvlBlockIndex = _lvlShapeIndex = 0;
+	_unkDrawLevelBool = true;
+	_vcnBlocks = 0;
+	_vcnShift = 0;
+	_vcnExpTable = 0;
+	_vmpPtr = 0;
+	_tlcTable2 = 0;
+	_tlcTable1 = 0;
+	_levelShapeProperties = 0;
+	_levelShapes = 0;
+	_blockDrawingBuffer = 0;
+	_sceneWindowBuffer = 0;
+	memset (_doorShapes, 0, 2 * sizeof(uint8*));
+
+	_lampOilStatus = _brightness = _lampStatusUnk = 0;
+	_tempBuffer5120 = 0;
+	_lvlBuffer = 0;
+	_unkGameFlag = 0;
+
+	_dscUnk1 = 0;
+	_dscShapeIndex = 0;
+	_dscOvlMap = 0;	
+	_dscShapeScaleW = 0;
+	_dscShapeScaleH = 0;
+	_dscShapeX = 0;
+	_dscShapeY = 0;
+	_dscTileIndex = 0;	
+	_dscUnk2 = 0;
+	_dscDoorShpIndex = 0;
+	_dscDim1 = 0;
+	_dscDim2 = 0;
+	_dscBlockMap = _dscDoor1 = _dscDoor2 = _dscShapeOvlIndex = 0;
+	_dscBlockIndex = 0;
+	_dscDimMap = 0;
+	_dscDoorX = _dscDoorY = 0;
+	_dscDoor4 = 0;
+
+	_ingameSoundList = 0;
+	_ingameSoundListSize = 0;
+
+	_sceneDrawVar1 = _sceneDrawVar2 = _sceneDrawVar3 = _wllProcessFlag = 0;
+	_unkCmzU1 = _unkCmzU2 = 0;
+	_shpDoorX = _shpDoorY = _doorScaleW = _doorScaleH = 0;
 }
 
 LoLEngine::~LoLEngine() {
 	setupPrologueData(false);
 
-	for (uint i = 0; i < ARRAYSIZE(_shapes); ++i)
-		delete[] _shapes[i];
 	delete[] _landsFile;
+	delete[] _levelLangFile;
 
 	delete _screen;
 	delete _tim;
 
+	delete [] _itemsInPlay;
+	delete [] _itemProperties;
+
+	delete [] _characters;
+
+	if (_itemIconShapes) {
+		for (int i = 0; i < _numItemIconShapes; i++)
+			delete [] _itemIconShapes[i];
+		delete []_itemIconShapes;
+	}
+	if (_itemShapes) {
+		for (int i = 0; i < _numItemShapes; i++)
+			delete [] _itemShapes[i];
+		delete []_itemShapes;
+	}
+	if (_gameShapes) {
+		for (int i = 0; i < _numGameShapes; i++)
+			delete [] _gameShapes[i];
+		delete []_gameShapes;
+	}
+	if (_thrownShapes) {
+		for (int i = 0; i < _numThrownShapes; i++)
+			delete [] _thrownShapes[i];
+		delete []_thrownShapes;
+	}
+	if (_iceShapes) {
+		for (int i = 0; i < _numIceShapes; i++)
+			delete [] _iceShapes[i];
+		delete []_iceShapes;
+	}
+	if (_fireballShapes) {
+		for (int i = 0; i < _numFireballShapes; i++)
+			delete [] _fireballShapes[i];
+		delete []_fireballShapes;
+	}
+
+	if (_monsterShapes) {
+		for (int i = 0; i < 48; i++)
+			delete [] _monsterShapes[i];
+		delete []_monsterShapes;
+	}
+	if (_monsterPalettes) {
+		for (int i = 0; i < 48; i++)
+			delete [] _monsterPalettes[i];
+		delete []_monsterPalettes;
+	}
+	if (_buf4) {
+		for (int i = 0; i < 384; i++)
+			delete [] _buf4[i];
+		delete []_buf4;
+	}
+
 	for (Common::Array<const TIMOpcode*>::iterator i = _timIntroOpcodes.begin(); i != _timIntroOpcodes.end(); ++i)
 		delete *i;
 	_timIntroOpcodes.clear();
+
+	delete []_wllVmpMap;
+	delete []_wllShapeMap;
+	delete []_wllBuffer3;
+	delete []_wllBuffer4;
+	delete []_wllBuffer5;
+	delete []_lvlShapeTop;
+	delete []_lvlShapeBottom;
+	delete []_lvlShapeLeftRight;
+	delete []_tempBuffer5120;
+	delete []_lvlBuffer;
+	delete []_cmzBuffer;
+	delete []_lvl415;
+
+	delete []_lvlShpHeader;
+	delete []_levelFileData;
+	delete []_vcnExpTable;
+	delete []_vcnBlocks;
+	delete []_vcnShift;
+	delete []_vmpPtr;
+	delete []_tlcTable2;
+	delete []_tlcTable1;
+	delete []_levelShapeProperties;
+	delete []_blockDrawingBuffer;
+	delete []_sceneWindowBuffer;
+
+	if (_levelShapes) {
+		for (int i = 0; i < 400; i++)
+			delete [] _levelShapes[i];
+		delete []_levelShapes;
+	}
+
+	for (int i = 0; i < 2; i++)
+		delete _doorShapes[i];
+	
+	delete _lvlShpFileHandle;
+
+	if (_ingameSoundList) {
+		for (int i = 0; i < _ingameSoundListSize; i++)
+			delete []_ingameSoundList[i];
+		delete []_ingameSoundList;	
+	}
 }
 
 Screen *LoLEngine::screen() {
@@ -90,6 +269,7 @@
 	_screen->setResolution();
 
 	KyraEngine_v1::init();
+	initStaticResource();
 
 	_tim = new TIMInterpreter(this, _screen, _system);
 	assert(_tim);
@@ -97,9 +277,77 @@
 	_screen->setAnimBlockPtr(10000);
 	_screen->setScreenDim(0);
 
+	_itemsInPlay = new ItemInPlay[401];
+	memset(_itemsInPlay, 0, sizeof(ItemInPlay) * 400);
+
+	_characters = new LoLCharacter[4];
+	memset(_characters, 0, sizeof(LoLCharacter) * 3);
+
 	if (!_sound->init())
 		error("Couldn't init sound");
 
+	_unkAudioSpecOffs = 0x48;
+	_unkLangAudio = _lang ? true : false;
+
+	_wllVmpMap = new uint8[80];
+	memset(_wllVmpMap, 0, 80);
+	_wllShapeMap = new int8[80];
+	memset(_wllShapeMap, 0, 80);
+	_wllBuffer3 = new uint8[80];
+	memset(_wllBuffer3, 0, 80);
+	_wllBuffer4 = new uint8[80];
+	memset(_wllBuffer4, 0, 80);
+	_wllBuffer5 = new uint8[80];
+	memset(_wllBuffer5, 0, 80);
+	_lvlShapeTop = new int16[18];
+	memset(_lvlShapeTop, 0, 18 * sizeof(int16));
+	_lvlShapeBottom = new int16[18];
+	memset(_lvlShapeBottom, 0, 18 * sizeof(int16));
+	_lvlShapeLeftRight = new int16[36];
+	memset(_lvlShapeLeftRight, 0, 36 * sizeof(int16));
+	_levelShapeProperties = new LevelShapeProperty[100];
+	memset(_levelShapeProperties, 0, 100 * sizeof(LevelShapeProperty));
+	_levelShapes = new uint8*[400];
+	memset(_levelShapes, 0, 400 * sizeof(uint8*));
+	_blockDrawingBuffer = new uint16[1320];
+	memset(_blockDrawingBuffer, 0, 1320 * sizeof(uint16));
+	_sceneWindowBuffer = new uint8[21120];
+	memset(_sceneWindowBuffer, 0, 21120);
+
+	_cmzBuffer = new CMZ[1025];
+	memset(_cmzBuffer, 0, 1025 * sizeof(CMZ));
+	_lvlBuffer = new LVL[30];
+	memset(_lvlBuffer, 0, 30 * sizeof(LVL));
+	_lvl415 = new uint8[415];
+	memset(_lvl415, 0, 415);
+
+	_vcnExpTable = new uint8[128];
+	for (int i = 0; i < 128; i++)
+		_vcnExpTable[i] = i & 0x0f;
+
+	_tempBuffer5120 = new uint8[5120];
+	memset(_tempBuffer5120, 0, 5120);
+
+	memset(_gameFlags, 0, 15 * sizeof(uint16));
+
+	_lvlShpHeader = 0;
+	_levelFileData = 0;
+	_lvlShpFileHandle = 0;
+
+	_sceneDrawPage1 = 2;
+	_sceneDrawPage2 = 6;
+
+	_monsterShapes = new uint8*[48];
+	memset(_monsterShapes, 0, 48 * sizeof(uint8*));
+	_monsterPalettes = new uint8*[48];
+	memset(_monsterPalettes, 0, 48 * sizeof(uint8*));
+
+	_buf4 = new uint8*[384];
+	memset(_buf4, 0, 384 * sizeof(uint8*));
+	memset(&_scriptData, 0, sizeof(EMCData));
+	
+	_levelFlagUnk = 0;
+
 	return Common::kNoError;
 }
 
@@ -171,10 +419,17 @@
 		_sound->playTrack(1);
 		_screen->fadeToBlack();
 		setupPrologueData(true);
-	} else if (processSelection == 3) {
-		//XXX
 	}
 
+	if (!shouldQuit() && (processSelection == 0 || processSelection == 3))
+		startup();
+
+	if (!shouldQuit() && processSelection == 0)
+		startupNew();
+
+	if (!shouldQuit() && (processSelection == 0 || processSelection == 3))
+		runLoop();
+
 	return Common::kNoError;
 }
 
@@ -223,10 +478,37 @@
 	debugC(9, kDebugLevelMain, "LoLEngine::initializeCursors()");
 
 	_screen->loadBitmap("ITEMICN.SHP", 3, 3, 0);
-	_shapes[0] = _screen->makeShapeCopy(_screen->getCPagePtr(3), 0);
-	_screen->setMouseCursor(0, 0, _shapes[0]);
+	const uint8 *shp = _screen->getCPagePtr(3);
+	_numItemIconShapes = READ_LE_UINT16(shp);
+	_itemIconShapes = new uint8*[_numItemIconShapes];
+	for (int i = 0; i < _numItemIconShapes; i++)
+		_itemIconShapes[i] = _screen->makeShapeCopy(shp, i);
+
+	_screen->setMouseCursor(0, 0, _itemIconShapes[0]);
 }
 
+void LoLEngine::setMouseCursorToIcon(int icon) {
+	_screen->_drawGuiFlag |= 0x200;
+	int i = _itemProperties[_itemsInPlay[_itemInHand].itemPropertyIndex].shpIndex;
+	if (i == icon)
+		return;
+	_screen->setMouseCursor(0, 0, _itemIconShapes[icon]);
+}
+
+void LoLEngine::setMouseCursorToItemInHand() {
+	_screen->_drawGuiFlag &= 0xFDFF;
+	int o = (_itemInHand == 0) ? 0 : 10;
+	_screen->setMouseCursor(o, o, getItemIconShapePtr(_itemInHand));
+}
+
+uint8 *LoLEngine::getItemIconShapePtr(int index) {
+	int ix = _itemProperties[_itemsInPlay[index].itemPropertyIndex].shpIndex;
+	if (_itemProperties[_itemsInPlay[index].itemPropertyIndex].flags & 0x200)
+		ix += (_itemsInPlay[index].shpCurFrame_flg & 0x1fff) - 1;
+	
+	return _itemIconShapes[ix];
+}
+
 int LoLEngine::mainMenu() {
 	debugC(9, kDebugLevelMain, "LoLEngine::mainMenu()");
 
@@ -275,6 +557,120 @@
 	return selection;
 }
 
+void LoLEngine::startup() {
+	_screen->clearPage(0);
+	_screen->loadBitmap("PLAYFLD.CPS", 3, 3, _screen->_currentPalette);
+
+	uint8 *tmpPal = new uint8[0x300];
+	memcpy(tmpPal, _screen->_currentPalette, 0x300);
+	memset(_screen->_currentPalette, 0x3f, 0x180);
+	memcpy(_screen->_currentPalette + 3, tmpPal + 3, 3);
+	memset(_screen->_currentPalette + 0x240, 0x3f, 12);
+	_screen->generateOverlay(_screen->_currentPalette, _screen->_paletteOverlay1, 1, 6);
+	_screen->generateOverlay(_screen->_currentPalette, _screen->_paletteOverlay2, 0x90, 0x41);
+	memcpy(_screen->_currentPalette, tmpPal, 0x300);
+	delete []tmpPal;
+
+	memset(_screen->getPalette(1), 0, 0x300);
+	memset(_screen->getPalette(2), 0, 0x300);
+
+	_screen->setMouseCursor(0, 0, _itemIconShapes[0x85]);
+
+	_screen->loadBitmap("ITEMSHP.SHP", 3, 3, 0);
+	const uint8 *shp = _screen->getCPagePtr(3);
+	_numItemShapes = READ_LE_UINT16(shp);
+	_itemShapes = new uint8*[_numItemShapes];
+	for (int i = 0; i < _numItemShapes; i++)
+		_itemShapes[i] = _screen->makeShapeCopy(shp, i);
+
+	_screen->loadBitmap("GAMESHP.SHP", 3, 3, 0);
+	shp = _screen->getCPagePtr(3);
+	_numGameShapes = READ_LE_UINT16(shp);
+	_gameShapes = new uint8*[_numGameShapes];
+	for (int i = 0; i < _numGameShapes; i++)
+		_gameShapes[i] = _screen->makeShapeCopy(shp, i);
+
+	_screen->loadBitmap("THROWN.SHP", 3, 3, 0);
+	shp = _screen->getCPagePtr(3);
+	_numThrownShapes = READ_LE_UINT16(shp);
+	_thrownShapes = new uint8*[_numThrownShapes];
+	for (int i = 0; i < _numThrownShapes; i++)
+		_thrownShapes[i] = _screen->makeShapeCopy(shp, i);
+
+	_screen->loadBitmap("ICE.SHP", 3, 3, 0);
+	shp = _screen->getCPagePtr(3);
+	_numIceShapes = READ_LE_UINT16(shp);
+	_iceShapes = new uint8*[_numIceShapes];
+	for (int i = 0; i < _numIceShapes; i++)
+		_iceShapes[i] = _screen->makeShapeCopy(shp, i);
+
+	_screen->loadBitmap("FIREBALL.SHP", 3, 3, 0);
+	shp = _screen->getCPagePtr(3);
+	_numFireballShapes = READ_LE_UINT16(shp);
+	_fireballShapes = new uint8*[_numFireballShapes];
+	for (int i = 0; i < _numFireballShapes; i++)
+		_fireballShapes[i] = _screen->makeShapeCopy(shp, i);
+
+	memset(_itemsInPlay, 0, 400 * sizeof(ItemInPlay));
+	for (int i = 0; i < 400; i++)
+		_itemsInPlay[i].shpCurFrame_flg |= 0x8000;
+
+	runInitScript("ONETIME.INF", 0);
+	_emc->load("ITEM.INF", &_itemScript, &_opcodes);
+
+	_tlcTable1 = new uint8[256];
+	_tlcTable2 = new uint8[5120];
+	
+	_loadSuppFilesFlag = 1;
+
+	setMouseCursorToItemInHand();
+}
+
+void LoLEngine::startupNew() {
+	_selectedSpell = 0;
+	_updateUnk2 = _compassDirectionIndex = -1;
+	/*
+	_unk3 = -1;*/
+	_unkGameFlag |= 0x1B;
+	/*
+	_unk5 = 1;
+	_unk6 = 1;
+	_unk7 = 1
+	_unk8 = 1*/
+	_currentLevel = 1;
+
+	giveCredits(41, 0);
+	_inventoryItemIndex[0] = makeItem(0xd8, 0, 0);
+	_inventoryItemIndex[1] = makeItem(0xd9, 0, 0);
+	_inventoryItemIndex[2] = makeItem(0xda, 0, 0);
+
+	memset(_availableSpells, -1, 7);
+	setupScreenDims();
+
+	//memset(_unkWordArraySize8, 0x100, 8);
+
+	static int selectIds[] = { -9, -1, -8, -5 };
+	addCharacter(selectIds[_charSelection]);
+
+	// TODO 
+
+	loadLevel(1);
+
+	_screen->showMouse();
+}
+
+void LoLEngine::runLoop() {
+	_screen->updateScreen();
+
+	bool _runFlag = true;
+	while (!shouldQuit() && _runFlag) {
+		checkInput(0, false);
+		removeInputTop();
+		_screen->updateScreen();
+		_system->delayMillis(10);
+	}
+}
+
 #pragma mark - Localization
 
 const char *LoLEngine::getLangString(uint16 id) {
@@ -363,7 +759,7 @@
 		_chargenWSA = new WSAMovie_v2(this, _screen);
 		assert(_chargenWSA);
 
-		_charSelection = -1;
+		//_charSelection = -1;
 		_charSelectionInfoResult = -1;
 
 		_selectionAnimFrames[0] = _selectionAnimFrames[2] = 0;
@@ -414,6 +810,7 @@
 	}
 	_screen->showMouse();
 	_sound->voiceStop();
+	_sound->beginFadeOut();
 
 	_eventList.clear();
 
@@ -807,14 +1204,535 @@
 	return -1;
 }
 
+bool LoLEngine::addCharacter(int id) {
+	int numChars = countActiveCharacters();
+	if (numChars == 4)
+		return false;
+
+	int i = 0;
+	for (; i < _charDefaultsSize; i++) {
+		if (_charDefaults[i].id == id) {
+			memcpy(&_characters[numChars], &_charDefaults[i], sizeof(LoLCharacter));
+			break;
+		}
+	}
+	if (i == _charDefaultsSize)
+		return false;
+
+	loadCharFaceShapes(numChars, id);
+
+	_characters[numChars].rand = _rnd.getRandomNumberRng(1, 12);
+
+	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);
+		}
+	}
+
+	calcCharPortraitXpos();
+	if (numChars > 0)
+		initCharacter(numChars, 2, 6, 0);
+
+	return true;
+}
+
+void LoLEngine::initCharacter(int charNum, int firstFaceFrame, int unk2, int redraw) {
+	_characters[charNum].nextFaceFrame = firstFaceFrame;
+	if (firstFaceFrame || unk2)
+		initCharacterUnkSub(charNum, 6, unk2, 1);
+	if (redraw)
+		gui_drawCharPortraitWithStats(charNum);
+}
+
+void LoLEngine::initCharacterUnkSub(int charNum, int unk1, int unk2, int unk3) {
+	for (int i = 0; i < 5; i++) {
+		if (_characters[charNum].arrayUnk1[i] == 0 || (unk3 && _characters[charNum].arrayUnk1[i] == unk1)) {
+			_characters[charNum].arrayUnk1[i] = unk1;
+			_characters[charNum].arrayUnk2[i] = unk2;
+
+			// TODO
+
+			break;
+		}
+	}
+}
+
+int LoLEngine::countActiveCharacters() {
+	int i = 0;
+	while (_characters[i].flags & 1)
+		i++;
+	return i;
+}
+
+void LoLEngine::loadCharFaceShapes(int charNum, int id) {
+	if (id < 0)
+		id = -id;
+
+	char file[] = "FACE%02d.SHP";
+	sprintf(file, "FACE%02d.SHP", id);
+	_screen->loadBitmap(file, 3, 3, 0);
+
+	const uint8 *p = _screen->getCPagePtr(3);
+	for (int i = 0; i < 40; i++)
+		_characterFaceShapes[i][charNum] = _screen->makeShapeCopy(p, i);
+}
+
+void LoLEngine::updatePortraitWithStats() {
+	int x = 0;
+	int y = 0;
+	bool redraw = false;
+
+	if (_updateCharV2 == 0) {
+		x = _activeCharsXpos[_updateCharNum];
+		y = 144;
+		redraw = true;
+	} else if (_updateCharV2 == 1) {
+		if (_unkLangAudio) {
+			x = 90;
+			y = 130;
+		} else {
+			x = _activeCharsXpos[_updateCharNum];
+			y = 144;
+		}
+	} else if (_updateCharV2 == 2) {
+		if (_unkLangAudio) {
+			x = 16;
+			y = 134;
+		} else {
+			x = _activeCharsXpos[_updateCharNum] + 10;
+			y = 145;
+		}
+	}
+
+	int f = _rnd.getRandomNumberRng(1, 6) - 1;
+	if (f == _characters[_updateCharNum].curFaceFrame)
+		f++;
+	if (f > 5)
+		f -= 5;
+	f += 7;
+
+	if (_unkAudioSpecOffs) {
+		//TODO
+		//if (unk() == 2)
+		//	_updateCharV1 = 2;
+		//else
+			_updateCharV1 = 1;
+	}
+
+	if (--_updateCharV1) {
+		setCharFaceFrame(_updateCharNum, f);
+		if (redraw)
+			gui_drawCharPortraitWithStats(_updateCharNum);
+		else
+			gui_drawCharFaceShape(_updateCharNum, x, y, 0);
+		_updatePortraitNext = _system->getMillis() + 10 * _tickLength;
+	} else if (_updateCharV1 == 0 && _updateCharV3 != 0) {
+		faceFrameRefresh(_updateCharNum);
+		if (redraw) {
+			gui_drawCharPortraitWithStats(_updateCharNum);
+			updatePortraitUnkTimeSub(0, 0);
+		} else {
+			gui_drawCharFaceShape(_updateCharNum, x, y, 0);
+		}
+		_updateCharNum = -1;
+	}
+}
+
+void LoLEngine::updatePortraits() {
+	if (_updateCharNum == -1)
+		return;
+
+	_updateCharV1 = _updateCharV3 = 1;
+	updatePortraitWithStats();
+	_updateCharV1 = 1;
+	_updateCharNum = -1;
+
+	if (!_updateCharV2)
+		updatePortraitUnkTimeSub(0, 0);
+}
+
+void LoLEngine::updatePortraitUnkTimeSub(int unk1, int unk2) {
+	if (_updateCharV4 == unk1 || !unk1) {
+		_updateCharV5 = 1;
+		_updateCharTime = _system->getMillis();
+	}
+
+	if (!unk2)
+		return;
+
+	updatePortraits();
+	if (_updateCharV6) {
+		_screen->hideMouse();
+		_screen->clearDim(3);
+		_screen->showMouse();
+	}
+	
+	_updateCharV5 = 0;
+	//initGuiUnk(11);
+}
+
+void LoLEngine::setCharFaceFrame(int charNum, int frameNum) {
+	_characters[charNum].curFaceFrame = frameNum;
+}
+
+void LoLEngine::faceFrameRefresh(int charNum) {
+	if (_characters[charNum].curFaceFrame == 1)
+		initCharacter(charNum, 0, 0, 0);
+	else if (_characters[charNum].curFaceFrame == 6)
+		if (_characters[charNum].nextFaceFrame != 5)
+			initCharacter(charNum, 0, 0, 0);
+		else
+			_characters[charNum].curFaceFrame = 5;
+	else
+		_characters[charNum].curFaceFrame = 0;
+}
+
+void LoLEngine::setupScreenDims() {
+	if (_unkLangAudio)
+		_screen->modifyScreenDim(4, 11, 124, 28, 45);
+	else
+		_screen->modifyScreenDim(4, 11, 124, 28, 9);
+	_screen->modifyScreenDim(5, 85, 123, 233, 18);
+}
+
+void LoLEngine::snd_playSoundEffect(int track, int volume) {
+	debugC(9, kDebugLevelMain | kDebugLevelSound, "LoLEngine::snd_playSoundEffect(%d, %d)", track, volume);
+
+	if (track == 1 && (_lastSfxTrack == -1 || _lastSfxTrack == 1))
+		return;
+
+	_lastSfxTrack = track;
+
+	int16 volIndex = (int16)READ_LE_UINT16(&_ingameSoundIndex[track * 2 + 1]);
+
+	if (volIndex > 0)
+		volIndex = (volIndex * volume) >> 8;
+	else
+		volIndex *= -1;
+
+	// volume TODO
+
+	int16 vocIndex = (int16)READ_LE_UINT16(&_ingameSoundIndex[track * 2]);
+	if (vocIndex != -1) {
+		_sound->voicePlay(_ingameSoundList[vocIndex], true);
+	} else if (_flags.platform == Common::kPlatformPC) {
+		if (_sound->getSfxType() == Sound::kMidiMT32)
+			track = track < _ingameMT32SoundIndexSize ? _ingameMT32SoundIndex[track] - 1 : -1;
+		else if (_sound->getSfxType() == Sound::kMidiGM)
+			track = track < _ingameGMSoundIndexSize ? _ingameGMSoundIndex[track] - 1: -1;
+
+		if (track != -1)
+			KyraEngine_v1::snd_playSoundEffect(track);
+	}
+}
+
 #pragma mark - Opcodes
 
+typedef Common::Functor1Mem<EMCState*, int, LoLEngine> OpcodeV2;
+#define SetOpcodeTable(x) table = &x;
+#define Opcode(x) table->push_back(new OpcodeV2(this, &LoLEngine::x))
+#define OpcodeUnImpl() table->push_back(new OpcodeV2(this, 0))
+
 typedef Common::Functor2Mem<const TIM *, const uint16 *, int, LoLEngine> TIMOpcodeLoL;
 #define SetTimOpcodeTable(x) timTable = &x;
 #define OpcodeTim(x) timTable->push_back(new TIMOpcodeLoL(this, &LoLEngine::x))
 #define OpcodeTimUnImpl() timTable->push_back(new TIMOpcodeLoL(this, 0))
 
 void LoLEngine::setupOpcodeTable() {
+	Common::Array<const Opcode*> *table = 0;
+
+	SetOpcodeTable(_opcodes);
+	// 0x00
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	Opcode(o1_getRand);
+
+	// 0x04
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	Opcode(o2_setGameFlag);
+
+	// 0x08
+	Opcode(o2_testGameFlag);
+	Opcode(o2_loadLevelSupplemenaryFiles);
+	Opcode(o2_loadCmzFile);
+	Opcode(o2_loadMonsterShapes);
+
+	// 0x0C
+	OpcodeUnImpl();
+	Opcode(o2_allocItemPropertiesBuffer);
+	Opcode(o2_setItemProperty);
+	Opcode(o2_makeItem);
+
+	// 0x10
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	Opcode(o2_getItemPara);
+	Opcode(o2_getCharacterStat);
+
+	// 0x14
+	Opcode(o2_setCharacterStat);
+	Opcode(o2_loadLevelShapes);
+	Opcode(o2_closeLevelShapeFile);
+	OpcodeUnImpl();
+
+	// 0x18
+	Opcode(o2_loadDoorShapes);
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x1C
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x20
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x24
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x28
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x2C
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x30
+	Opcode(o2_setGlobalVar);
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x34
+	OpcodeUnImpl();
+	Opcode(o2_mapShapeToBlock);
+	Opcode(o2_resetBlockShapeAssignment);
+	OpcodeUnImpl();
+
+	// 0x38
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x3C
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x40
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x44
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x48
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x4C
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x50
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x54
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x58
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x5C
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x60
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x64
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x68
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	Opcode(o2_setPaletteBrightness);
+
+	// 0x6C
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x70
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x74
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x78
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x7C
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x80
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x84
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x88
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x8C
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x90
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x94
+	Opcode(o2_assignCustomSfx);
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x98
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0x9C
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0xA0
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0xA4
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0xA8
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0xAC
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0xB0
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0xB4
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0xB8
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
+	// 0xBC
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+
 	Common::Array<const TIMOpcode*> *timTable = 0;
 
 	SetTimOpcodeTable(_timIntroOpcodes);

Modified: scummvm/trunk/engines/kyra/lol.h
===================================================================
--- scummvm/trunk/engines/kyra/lol.h	2009-01-18 16:49:03 UTC (rev 35902)
+++ scummvm/trunk/engines/kyra/lol.h	2009-01-18 17:04:24 UTC (rev 35903)
@@ -28,6 +28,7 @@
 
 #include "kyra/kyra_v1.h"
 #include "kyra/script_tim.h"
+#include "kyra/script.h"
 
 #include "common/list.h"
 
@@ -37,6 +38,143 @@
 class WSAMovie_v2;
 struct Button;
 
+struct LoLCharacter {
+	uint16 flags;
+	char name[11];
+	uint8 raceClassSex;
+	int16 id;
+	uint8 curFaceFrame;
+	uint8 nextFaceFrame;
+	uint16 field_12;
+	uint16 field_14;
+	uint8 field_16;
+	uint16 field_17[5];
+	uint16 field_21;
+	uint16 field_23;
+	uint16 field_25;
+	uint16 field_27[2];
+	uint8 field_2B;
+	uint16 field_2C;
+	uint16 field_2E;
+	uint16 field_30;
+	uint16 field_32;
+	uint16 field_34;
+	uint8 field_36;
+	uint16 field_37;
+	uint16 hitPointsCur;
+	uint16 hitPointsMax;
+	uint16 magicPointsCur;
+	uint16 magicPointsMax;
+	uint8 field_41;
+	uint16 damageSuffered;
+	uint16 weaponHit;
+	uint16 field_46;
+	uint16 field_48;
+	uint16 field_4A;
+	uint16 field_4C;
+	uint16 rand;
+	uint16 items[11];
+	uint8 field_66[3];
+	uint8 field_69[3];
+	uint8 field_6C;
+	uint8 field_6D;
+	uint16 field_6E;
+	uint16 field_70;
+	uint16 field_72;
+	uint16 field_74;
+	uint16 field_76;
+	uint8 arrayUnk2[5];
+	uint8 arrayUnk1[5];
+};
+
+struct SpellProperty {
+	uint16 field_0;
+	uint16 unkArr[4];
+	uint16 field_A;
+	uint16 field_C;
+	uint16 field_E;
+	uint16 spellNameCode;
+	uint16 mpRequired[4];
+	uint16 field_1A;
+};
+
+struct CMZ {
+	uint8 unk[4];
+	uint16 itemIndex;
+	uint8 field_6;
+	uint8 field_7;
+	uint8 field_8;
+	uint8 flags;
+};
+
+struct LVL {
+	uint8 field_0;
+	uint8 field_1;
+	uint8 field_2;
+	uint8 field_3;
+	uint8 field_4;
+	uint16 cmzIndex;
+	uint16 p_1a;
+	uint16 p_1b;
+	uint8 field_B;
+	uint16 p_2a;
+	uint16 p_2b;
+	uint8 field_10;
+	uint8 field_11;
+	uint8 field_12;
+	uint8 field_13;
+	uint8 field_14;
+	uint8 field_15;
+	uint8 field_16;
+	uint8 field_17;
+	uint8 field_18;
+	uint16 field_19;
+	uint8 field_1B;
+	uint8 field_1C;
+	int16 field_1D;
+	uint8 field_1F;
+	uint8 field_20;
+	uint8 *offs_lvl415;
+	uint8 field_25;
+	uint8 field_26;
+	uint8 field_27;
+	uint8 field_28;
+	uint8 field_29;
+	uint8 field_2A;
+	uint8 field_2B;
+	uint8 field_2C;
+	uint8 field_2D;
+	uint8 field_2E;
+};
+
+struct LevelShapeProperty {
+	uint16 shapeIndex[10];
+	uint8 scaleFlag[10];
+	uint16 shapeX[10];
+	uint16 shapeY[10];
+	int8 next;
+	uint8 flags;
+};
+
+struct CompassDef {
+	uint8 shapeIndex;
+	int8 x;
+	int8 y;
+	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;
+};
+
 class LoLEngine : public KyraEngine_v1 {
 public:
 	LoLEngine(OSystem *system, const GameFlags &flags);
@@ -51,12 +189,22 @@
 	Common::Error go();
 
 	// initialization
+	void initStaticResource();
 	void preInit();
 
 	void initializeCursors();
-
 	int mainMenu();
 
+	void startup();
+	void startupNew();
+
+	void runLoop();
+
+	// mouse
+	void setMouseCursorToIcon(int icon);
+	void setMouseCursorToItemInHand();
+	uint8 *getItemIconShapePtr(int index);
+
 	// intro
 	void setupPrologueData(bool load);
 
@@ -111,8 +259,84 @@
 
 	// sound
 	void snd_playVoiceFile(int) { /* XXX */ }
+	void snd_playSoundEffect(int track, int volume);
 
-	// opcode
+	int _lastSfxTrack;
+
+	int _unkAudioSpecOffs;
+	bool _unkLangAudio;
+
+	char **_ingameSoundList;
+	int _ingameSoundListSize;
+
+	const uint16 *_ingameSoundIndex;
+	int _ingameSoundIndexSize;
+	const uint8 *_ingameGMSoundIndex;
+	int _ingameGMSoundIndexSize;
+	const uint8 *_ingameMT32SoundIndex;
+	int _ingameMT32SoundIndexSize;
+
+	// gui
+	void gui_drawPlayField();
+	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_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);
+	void gui_drawInventory();
+	void gui_drawInventoryItem(int index);
+	void gui_drawCompass();
+	void gui_drawScroll();
+
+	bool _weaponsDisabled;
+	int _unkDrawPortraitIndex;
+	int _updateUnk2;
+	int _compassDirectionIndex;
+
+	const CompassDef *_compassDefs;
+	int _compassDefsSize;
+
+	// emc scripts
+	void runInitScript(const char *filename, int func);
+	void runInfScript(const char *filename);
+	void runResidentScript(int func, int reg0);
+	void runResidentScriptCustom(int func, int reg0, int reg1, int reg2, int reg3, int reg4);
+	bool checkScriptUnk(int func);
+	
+	EMCData _scriptData;
+	bool _scriptBoolSkipExec;
+	uint8 _unkScriptByte;
+	uint16 _unkPara2;
+	uint16 _currentBlock;
+	bool _boolScriptFuncDone;
+	int16 _scriptExecutedFuncs[18];
+
+	uint16 _gameFlags[15];
+
+	// emc opcode
+	int o2_setGameFlag(EMCState *script);
+	int o2_testGameFlag(EMCState *script);
+	int o2_loadLevelSupplemenaryFiles(EMCState *script);
+	int o2_loadCmzFile(EMCState *script);
+	int o2_loadMonsterShapes(EMCState *script);
+	int o2_allocItemPropertiesBuffer(EMCState *script);
+	int o2_setItemProperty(EMCState *script);
+	int o2_makeItem(EMCState *script);	
+	int o2_getItemPara(EMCState *script);
+	int o2_getCharacterStat(EMCState *script);
+	int o2_setCharacterStat(EMCState *script);
+	int o2_loadLevelShapes(EMCState *script);
+	int o2_closeLevelShapeFile(EMCState *script);
+	int o2_loadDoorShapes(EMCState *script);
+	int o2_setGlobalVar(EMCState *script);
+	int o2_mapShapeToBlock(EMCState *script);
+	int o2_resetBlockShapeAssignment(EMCState *script);
+	int o2_setPaletteBrightness(EMCState *script);
+	int o2_assignCustomSfx(EMCState *script);
+
+	// tim opcode
 	void setupOpcodeTable();
 
 	Common::Array<const TIMOpcode*> _timIntroOpcodes;
@@ -126,6 +350,7 @@
 	int _lang;
 
 	uint8 *_landsFile;
+	uint8 *_levelLangFile;
 
 	int _lastUsedStringBuffer;
 	char _stringBuffer[5][512];	// TODO: The original used a size of 512, it looks a bit large.
@@ -136,8 +361,295 @@
 	static const char * const _languageExt[];
 
 	// graphics
-	uint8 *_shapes[138];
+	void setupScreenDims();
 
+	uint8 **_itemIconShapes;
+	int _numItemIconShapes;
+	uint8 **_itemShapes;
+	int _numItemShapes;
+	uint8 **_gameShapes;
+	int _numGameShapes;
+	uint8 **_thrownShapes;
+	int _numThrownShapes;
+	uint8 **_iceShapes;
+	int _numIceShapes;
+	uint8 **_fireballShapes;
+	int _numFireballShapes;
+
+	const int8 *_gameShapeMap;
+	int _gameShapeMapSize;
+
+	uint8 *_characterFaceShapes[40][3];
+
+	// characters
+	bool addCharacter(int id);
+	void initCharacter(int charNum, int firstFaceFrame, int unk2, int redraw);
+	void initCharacterUnkSub(int charNum, int unk1, int unk2, int unk3);
+	int countActiveCharacters();
+	void loadCharFaceShapes(int charNum, int id);
+	void calcCharPortraitXpos();
+
+	void updatePortraitWithStats();
+	void updatePortraits();
+	void updatePortraitUnkTimeSub(int unk1, int unk2);
+
+	void setCharFaceFrame(int charNum, int frameNum);
+	void faceFrameRefresh(int charNum);
+
+	LoLCharacter *_characters;
+	uint16 _activeCharsXpos[3];
+	int _charFlagUnk;
+	int _updateCharNum;
+	int _updateCharV1;
+	int _updateCharV2;
+	int _updateCharV3;
+	int _updateCharV4;
+	int _updateCharV5;
+	int _updateCharV6;
+	uint32 _updateCharTime;
+	uint32 _updatePortraitNext;
+
+	int _loadLevelFlag;
+	int _levelFlagUnk;
+
+	uint8 **_monsterShapes;
+	uint8 **_monsterPalettes;
+	uint8 **_buf4;
+	uint8 _monsterUnk[3];
+
+	const LoLCharacter *_charDefaults;
+	int _charDefaultsSize;
+
+	// 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 cmzS4(uint16 &itemIndex, int a);
+	int cmzS5(uint16 a, uint16 b);
+	void cmzS6(uint16 &itemIndex, int a);
+	void cmzS7(int itemIndex, int a);
+	void loadLevelWLL(int index, bool mapShapes);
+	void moveItemToCMZ(uint16 *cmzItemIndex, uint16 item);
+	int assignLevelShapes(int index);
+	uint8 *getLevelShapes(int index);
+	void loadLevelCMZ(int index);
+	void loadCMZ_Sub(int index1, int index2);
+	void loadCmzFile(const char *file);
+	void loadMonsterShapes(const char *file, int monsterIndex, int b);
+	void releaseMonsterShapes(int monsterIndex);
+	void loadLevelShpDat(const char *shpFile, const char *datFile, bool flag);
+	void loadLevelSupplemenaryFiles(const char *file, int specialColor, int weight, int vcnLen, int vmpLen, const char *langFile);
+
+	void drawScene(int pageNum);
+
+	void generateBlockDrawingBuffer(int block, int b);
+	void generateBlockDrawingBufferF0(int16 wllOffset, uint8 wllIndex, uint8 wllVmpIndex, int16 vmpOffset, uint8 len, uint8 numEntries);
+	void generateBlockDrawingBufferF1(int16 wllOffset, uint8 wllIndex, uint8 wllVmpIndex, int16 vmpOffset, uint8 len, uint8 numEntries);
+	bool testWllBuffer5Value(int index);
+	void assignBlockCaps(int a, int b);
+
+	void drawVcnBlocks(uint8 *vcnBlocks, uint16 *blockDrawingBuffer, uint8 *vcnShift, int pageNum);
+	void drawSceneShapes();
+	void setLevelShapesDim(int index, int16 &x1, int16 &x2, int dim);
+	void scaleLevelShapesDim(int index, int16 &y1, int16 &y2, int dim);
+	void drawLevelModifyScreenDim(int dim, int16 x1, int16 y1, int16 x2, int16 y2);
+	void drawDecorations(int index);
+	void drawIceShapes(int index, int iceShapeIndex);
+	void drawDoor(uint8 *shape, uint8 *table, int index, int unk2, int w, int h, int flags);
+	void drawDoorShapes(uint8 *shape, uint8 *table, int x, int y, int flags, const uint8 *ovl);
+	void drawScriptShapes(int pageNum);
+	void updateSceneWindow();
+
+	void turnOnLamp();
+	void updateLampStatus();
+
+	void setLF1(uint16 & a, uint16 & b, int block, uint16 d, uint16 e);
+	void setLF2(int block);
+	
+	int _unkFlag;
+	int _scriptFuncIndex;
+	uint8 _currentLevel;
+	bool _loadLevelFlag2;
+	int _lvlBlockIndex;
+	int _lvlShapeIndex;
+	bool _unkDrawLevelBool;
+	uint8 *_vcnBlocks;
+	uint8 *_vcnShift;
+	uint8 *_vcnExpTable;
+	uint16 *_vmpPtr;
+	uint16 *_blockDrawingBuffer;
+	uint8 *_sceneWindowBuffer;
+	LevelShapeProperty *_levelShapeProperties;
+	uint8 **_levelShapes;
+
+	char _lastSuppFile[12];
+	char _lastSuppLangFile[12];
+	char *_lastSuppLangFilePtr;
+	int _lastSpecialColor;
+	int _lastSpecialColorWeight;
+
+	int _sceneDrawVar1;
+	int _sceneDrawVar2;
+	int _sceneDrawVar3;
+	int _wllProcessFlag;
+
+	uint8 *_tlcTable2;
+	uint8 *_tlcTable1;
+
+	int _loadSuppFilesFlag;
+
+	int _lampOilStatus;
+	int _brightness;
+	int _lampStatusUnk;
+	uint32 _lampStatusTimer;
+
+	uint8 *_wllVmpMap;
+	int8 *_wllShapeMap;
+	uint8 *_wllBuffer3;
+	uint8 *_wllBuffer4;
+	uint8 *_wllBuffer5;
+
+	int16 *_lvlShapeTop;
+	int16 *_lvlShapeBottom;
+	int16 *_lvlShapeLeftRight;
+
+	CMZ *_cmzBuffer;
+	CMZ *_curBlockCaps[18];
+	LVL *_lvlBuffer;
+	uint8 *_lvl415;
+
+	uint16 _unkCmzU1;
+	uint16 _unkCmzU2;
+	
+	Common::SeekableReadStream *_lvlShpFileHandle;
+	uint16 _lvlShpNum;
+	uint32 *_lvlShpHeader;
+	uint16 _levelFileDataSize;
+	LevelShapeProperty *_levelFileData;
+
+	uint8 *_doorShapes[2];
+	int16 _shpDoorX;
+	int16 _shpDoorY;
+	int16 _doorScaleW;
+	int16 _doorScaleH;
+
+	uint8 _unkGameFlag;
+
+	uint8 *_tempBuffer5120;
+	
+	const char *const * _levelDatList;
+	int _levelDatListSize;
+	const char *const * _levelShpList;
+	int _levelShpListSize;
+
+	const int8 *_dscUnk1;
+	int _dscUnk1Size;
+	const int8 *_dscShapeIndex;
+	int _dscShapeIndexSize;
+	const uint8 *_dscOvlMap;
+	int _dscOvlMapSize;
+	const uint16 *_dscShapeScaleW;
+	int _dscShapeScaleWSize;
+	const uint16 *_dscShapeScaleH;
+	int _dscShapeScaleHSize;
+	const int16 *_dscShapeX;
+	int _dscShapeXSize;
+	const int8 *_dscShapeY;
+	int _dscShapeYSize;
+	const uint8 *_dscTileIndex;
+	int _dscTileIndexSize;
+	const uint8 *_dscUnk2;
+	int _dscUnk2Size;
+	const uint8 *_dscDoorShpIndex;
+	int _dscDoorShpIndexSize;
+	const int8 *_dscDim1;
+	int _dscDim1Size;
+	const int8 *_dscDim2;
+	int _dscDim2Size;
+	const uint8 *_dscBlockMap;
+	int _dscBlockMapSize;
+	const uint8 *_dscDimMap;
+	int _dscDimMapSize;
+	const uint8 *_dscDoor2;
+	int _dscDoor2Size;
+	const uint16 *_dscDoorScaleTable;
+	int _dscDoorScaleTableSize;
+	const uint16 *_dscDoor4;
+	int _dscDoor4Size;
+	const uint8 *_dscShapeOvlIndex;
+	int _dscShapeOvlIndexSize;
+	const int8 *_dscBlockIndex;
+	int _dscBlockIndexSize;
+	const uint8 *_dscDoor1;
+	int _dscDoor1Size;
+	const int16 *_dscDoorX;
+	int _dscDoorXSize;
+	const int16 *_dscDoorY;
+	int _dscDoorYSize;
+	
+	int _sceneDrawPage1;
+	int _sceneDrawPage2;
+
+	// items
+	struct ItemInPlay {
+		uint16 itemIndexUnk;
+		uint8 unk2;
+		uint16 unk3;
+		uint16 cmzIndex;
+		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);
+	void runItemScript(int reg1, int item, int reg0, int reg3, int reg4);
+
+	uint8 _moneyColumnHeight[5];
+	uint16 _credits;
+
+	ItemInPlay *_itemsInPlay;
+	ItemProperty *_itemProperties;
+
+	int _itemInHand;
+	uint16 _inventoryItemIndex[48];
+	int _inventoryCurItem;
+	int _unkInventFlag;
+
+	EMCData _itemScript;
+
+	// spells
+	int8 _availableSpells[7];
+	int _selectedSpell;
+	const SpellProperty *_spellProperties;
+	int _spellPropertiesSize;
+
 	// unneeded
 	void setWalkspeed(uint8) {}
 	void setHandItem(uint16) {}

Modified: scummvm/trunk/engines/kyra/module.mk
===================================================================
--- scummvm/trunk/engines/kyra/module.mk	2009-01-18 16:49:03 UTC (rev 35902)
+++ scummvm/trunk/engines/kyra/module.mk	2009-01-18 17:04:24 UTC (rev 35903)
@@ -12,10 +12,12 @@
 	gui_v2.o \
 	gui_hof.o \
 	gui_mr.o \
+	gui_lol.o \
 	items_lok.o \
 	items_v2.o \
 	items_hof.o \
 	items_mr.o \
+	items_lol.o \
 	kyra_v1.o \
 	kyra_lok.o \
 	kyra_v2.o \
@@ -33,6 +35,7 @@
 	scene_v2.o \
 	scene_hof.o \
 	scene_mr.o \
+	scene_lol.o \
 	screen.o \
 	screen_lok.o \
 	screen_lol.o \
@@ -44,6 +47,7 @@
 	script_v2.o \
 	script_hof.o \
 	script_mr.o \
+	script_lol.o \
 	script.o \
 	script_tim.o \
 	seqplayer.o \

Modified: scummvm/trunk/engines/kyra/resource.h
===================================================================
--- scummvm/trunk/engines/kyra/resource.h	2009-01-18 16:49:03 UTC (rev 35902)
+++ scummvm/trunk/engines/kyra/resource.h	2009-01-18 17:04:24 UTC (rev 35903)
@@ -39,6 +39,7 @@
 
 #include "kyra/kyra_v1.h"
 #include "kyra/kyra_hof.h"
+#include "kyra/lol.h"
 
 namespace Kyra {
 
@@ -210,6 +211,40 @@
 	k3ItemMagicTable,
 	k3ItemStringMap,
 
+	lolCharacterDefs,
+	lolIngameSfxFiles,
+	lolIngameSfxIndex,
+	lolIngameGMSfxIndex,
+	lolIngameMT32SfxIndex,
+	lolSpellProperties,
+	lolGameShapeMap,
+	lolLevelShpList,
+	lolLevelDatList,
+	lolCompassDefs,
+
+	lolDscUnk1,
+	lolDscShapeIndex,
+	lolDscOvlMap,
+	lolDscScaleWidthData,
+	lolDscScaleHeightData,
+	lolDscX,
+	lolDscY,
+	lolDscTileIndex,
+	lolDscUnk2,
+	lolDscDoorShapeIndex,
+	lolDscDimData1,
+	lolDscDimData2,
+	lolDscBlockMap,
+	lolDscDimMap,
+	lolDscDoor1,
+	lolDscDoor2,
+	lolDscDoorScale,
+	lolDscDoor4,
+	lolDscDoorX,
+	lolDscDoorY,
+	lolDscOvlIndex,
+	lolDscBlockIndex,
+
 	kMaxResIDs
 };
 
@@ -236,6 +271,10 @@
 	const HofSeqData *loadHofSequenceData(int id, int &entries);
 	const ItemAnimData_v1 *loadShapeAnimData_v1(int id, int &entries);
 	const ItemAnimData_v2 *loadShapeAnimData_v2(int id, int &entries);
+	const LoLCharacter *loadCharData(int id, int &entries);
+	const SpellProperty *loadSpellData(int id, int &entries);
+	const CompassDef *loadCompassData(int id, int &entries);
+	const uint16 *loadRawDataBe16(int id, int &entries);
 
 	// use '-1' to prefetch/unload all ids
 	// prefetchId retruns false if only on of the resources
@@ -267,6 +306,10 @@
 	bool loadHofSequenceData(const char *filename, void *&ptr, int &size);
 	bool loadShapeAnimData_v1(const char *filename, void *&ptr, int &size);
 	bool loadShapeAnimData_v2(const char *filename, void *&ptr, int &size);
+	bool loadCharData(const char *filename, void *&ptr, int &size);
+	bool loadSpellData(const char *filename, void *&ptr, int &size);
+	bool loadCompassData(const char *filename, void *&ptr, int &size);
+	bool loadRawDataBe16(const char *filename, void *&ptr, int &size);	
 
 	void freeRawData(void *&ptr, int &size);
 	void freeStringTable(void *&ptr, int &size);
@@ -276,6 +319,10 @@
 	void freeHofSequenceData(void *&ptr, int &size);
 	void freeHofShapeAnimDataV1(void *&ptr, int &size);
 	void freeHofShapeAnimDataV2(void *&ptr, int &size);
+	void freeCharData(void *&ptr, int &size);
+	void freeSpellData(void *&ptr, int &size);
+	void freeCompassData(void *&ptr, int &size);
+	void freeRawDataBe16(void *&ptr, int &size);
 
 	const char *getFilename(const char *name);
 	Common::SeekableReadStream *getFile(const char *name);
@@ -290,7 +337,12 @@
 
 		k2SeqData,
 		k2ShpAnimDataV1,
-		k2ShpAnimDataV2
+		k2ShpAnimDataV2,
+
+		lolCharData,
+		lolSpellData,
+		lolCompassData,
+		lolRawDataBe16
 	};
 
 	struct BuiltinRes {

Added: scummvm/trunk/engines/kyra/scene_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/scene_lol.cpp	                        (rev 0)
+++ scummvm/trunk/engines/kyra/scene_lol.cpp	2009-01-18 17:04:24 UTC (rev 35903)
@@ -0,0 +1,1369 @@
+/* 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/resource.h"
+
+#include "common/endian.h"
+
+namespace Kyra {
+
+void LoLEngine::loadLevel(int index) {
+	_unkFlag |= 0x800;
+	setMouseCursorToIcon(0x85);
+	_scriptFuncIndex = 0;
+
+	// TODO
+
+	updatePortraits();
+
+	for (int i = 0; i < 400; i++) {
+		delete [] _levelShapes[i];
+		_levelShapes[i] = 0;
+	}
+
+	_emc->unload(&_scriptData);
+
+	_currentLevel = index;
+	_charFlagUnk = 0;
+
+	releaseMonsterShapes(0);
+	releaseMonsterShapes(1);
+
+	//TODO
+
+	//loadTalkFile(index);
+	loadLevelWLL(index, true);
+	_loadLevelFlag = 1;
+
+	char filename[] = "level%d.ini";
+	sprintf(filename, "level%d.ini", index);
+	
+	int f = _levelFlagUnk & (1 << ((index + 0xff) & 0xff));
+
+	runInitScript(filename, f ? 0 : 1);
+
+	if (f)
+		loadLevelCMZ(index);
+
+	sprintf(filename, "level%d.inf", index);
+	runInfScript(filename);
+
+	addLevelItems();
+	initCmzWithScript(_currentBlock);
+
+	_screen->generateGrayOverlay(_screen->_currentPalette, _screen->_grayOverlay,32, 16, 0, 0, 128, true);
+
+	_loadLevelFlag2 = false;
+	if (_screen->_fadeFlag == 3)
+		_screen->fadeToBlack(10);
+
+	gui_drawPlayField();
+
+	_screen->setPaletteBrightness(_screen->_currentPalette, _brightness, _lampOilStatus);
+	setMouseCursorToItemInHand();
+	//TODO
+}
+
+void LoLEngine::addLevelItems() {
+	for (int i = 0; i < 400; i++) {
+		if (_itemsInPlay[i].level != _currentLevel)
+			continue;
+
+		moveItemToCMZ(&_cmzBuffer[_itemsInPlay[i].cmzIndex].itemIndex, i);
+
+		_cmzBuffer[_itemsInPlay[i].cmzIndex].field_8 = 5;
+		_itemsInPlay[i].unk2 = 0;
+	}
+}
+
+int LoLEngine::initCmzWithScript(int block) {
+	int i = _cmzBuffer[block].itemIndex;
+	int cnt = 0;
+
+	while (i) {
+		void *t = cmzGetItemOffset(i);
+		i = (i & 0x8000) ? ((LVL*)t)->field_0 : ((ItemInPlay*)t)->itemIndexUnk;
+		if (!(i & 0x8000))
+			continue;
+
+		i &= 0x7fff;
+		LVL *l = &_lvlBuffer[i];
+
+		cnt++;
+		initCMZ1(l, 14);
+
+		checkScriptUnk(l->cmzIndex);
+
+		initCMZ2(l, 0, 0);
+	}
+	return cnt;
+}
+
+void LoLEngine::initCMZ1(LVL *l, int a) {
+	if (l->field_14 == 13 && a != 14)
+		return;
+	if (a == 7) {
+		l->p_2a = _unkCmzU1;
+		l->p_2b = _unkCmzU2;
+	}
+
+	if (l->field_14 == 1 && a == 7) {
+		for (int i = 0; i < 30; i++) {
+			if (l->field_14 != 1)
+				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));
+		}		
+	} else {
+		l->field_14 = a;
+		l->field_15 = 0;
+		if (a == 14)
+			l->field_1D = 0;
+		if (a == 13 && (l->field_19 & 0x20)) {
+			l->field_14 = 0;
+			cmzS3(l);
+			if (_currentLevel != 29)
+				initCMZ1(l, 14);
+			runResidentScriptCustom(0x404, -1, l->field_16, l->field_16, 0, 0);
+			checkScriptUnk(l->cmzIndex);
+			if (l->field_14 == 14)
+				initCMZ2(l, 0, 0);
+		}
+	}
+
+}
+
+void LoLEngine::initCMZ2(LVL *l, uint16 a, uint16 b) {
+	bool cont = true;
+	int t = l->cmzIndex;
+	if (l->cmzIndex) {
+		cmzS4(_cmzBuffer[l->cmzIndex].itemIndex, ((uint16)l->field_16) | 0x8000);
+		_cmzBuffer[l->cmzIndex].field_8 = 5;
+		checkScriptUnk(l->cmzIndex);
+	} else {
+		cont = false;
+	}
+	
+	l->cmzIndex = cmzS5(a, b);
+	
+	if (l->p_1a != a || l->p_1b != b) {
+		l->p_1a = a;
+		l->p_1b = b;
+		l->field_13 = (++l->field_13) & 3;
+	}
+
+	if (l->cmzIndex == 0)
+		return;
+
+	cmzS6(_cmzBuffer[l->cmzIndex].itemIndex, ((uint16)l->field_16) | 0x8000);
+	_cmzBuffer[l->cmzIndex].field_8 = 5;
+	checkScriptUnk(l->cmzIndex);
+	uint8 *v = l->offs_lvl415;
+	
+	if (v[80] == 0 || cont == false)
+		return;
+
+	if ((!(READ_LE_UINT16(&v[62]) & 0x100) || ((l->field_13 & 1) == 0)) && l->cmzIndex == t)
+		return;
+
+	if (l->cmzIndex != t)
+		runResidentScriptCustom(l->cmzIndex, 0x800, -1, l->field_16, 0, 0);
+
+	if (_charFlagUnk & 1)
+		return;
+
+	cmzS7(l->offs_lvl415[50], l->cmzIndex);
+}
+
+int LoLEngine::cmzS1(uint16 a, uint16 b, uint16 c, uint16 d) {
+	// TODO
+
+	return 0;
+}
+
+void LoLEngine::cmzS2(LVL *l, int a) {
+	// TODO
+}
+
+void LoLEngine::cmzS3(LVL *l) {
+	// TODO
+}
+
+void LoLEngine::cmzS4(uint16 &itemIndex, int a) {
+	// TODO
+}
+
+int LoLEngine::cmzS5(uint16 a, uint16 b) {
+	// TODO
+	return 0;
+}
+
+void LoLEngine::cmzS6(uint16 &itemIndex, int a) {
+	// TODO
+}
+
+void LoLEngine::cmzS7(int itemIndex, int a) {
+	if (!(_unkGameFlag & 1))
+		return;
+
+	// TODO
+}
+
+void LoLEngine::moveItemToCMZ(uint16 *cmzItemIndex, uint16 item) {
+	uint16 *tmp = 0;
+	while (*cmzItemIndex & 0x8000) {
+		tmp = (uint16*) cmzGetItemOffset(*cmzItemIndex);
+		cmzItemIndex = tmp;
+	}
+	uint16 *t = (uint16*) cmzGetItemOffset(*cmzItemIndex);
+
+	((ItemInPlay*)t)->level = -1;
+	uint16 ix = *cmzItemIndex;
+
+	if (ix == item)
+		return;
+
+	*cmzItemIndex = item;
+	cmzItemIndex = t;
+
+	while (*cmzItemIndex)
+		cmzItemIndex = (uint16*) cmzGetItemOffset(*cmzItemIndex);
+
+	*cmzItemIndex = ix;
+}
+
+void LoLEngine::loadLevelWLL(int index, bool mapShapes) {
+	char filename[] = "level%00d.wll";
+	sprintf(filename, "level%00d.wll", index);
+
+	uint32 size;
+	uint8 *file = _res->fileData(filename, &size);
+
+	uint16 c = READ_LE_UINT16(file);
+	loadLevelShpDat(_levelShpList[c], _levelDatList[c], false);
+
+	uint8 *d = file + 2;
+	size = (size - 2) / 12;
+	for (uint32 i = 0; i < size; i++) {
+		c = READ_LE_UINT16(d);
+		d += 2;
+		_wllVmpMap[c] = *d;
+		d += 2;
+
+		if (mapShapes) {
+			int16 sh = (int16) READ_LE_UINT16(d);
+			if (sh > 0)				
+				_wllShapeMap[c] = assignLevelShapes(sh);
+			else
+				_wllShapeMap[c] = *d;
+		}
+		d += 2;
+		_wllBuffer3[c] = *d;
+		d += 2;
+		_wllBuffer5[c] = *d;
+		d += 2;
+		_wllBuffer4[c] = *d;
+		d += 2;		
+	}
+
+	delete []file;
+
+	delete _lvlShpFileHandle;
+	_lvlShpFileHandle = 0;	
+}
+
+int LoLEngine::assignLevelShapes(int index) {
+	uint16 *p1 = (uint16 *) _tempBuffer5120;
+	uint16 *p2 = (uint16 *) (_tempBuffer5120 + 4000);
+
+	uint16 r = p2[index];
+	if (r)
+		return r;
+
+	uint16 o = _lvlBlockIndex++;
+
+	memcpy(&_levelShapeProperties[o], &_levelFileData[index], sizeof(LevelShapeProperty));
+	
+	for (int i = 0; i < 10; i++) {
+		uint16 t = _levelShapeProperties[o].shapeIndex[i];
+		if (t == 0xffff)
+			continue;
+
+		uint16 pv = p1[t];
+		if (pv) {
+			_levelShapeProperties[o].shapeIndex[i] = pv;
+		} else {
+			_levelShapes[_lvlShapeIndex] = getLevelShapes(t);
+			p1[t] = _lvlShapeIndex;
+			_levelShapeProperties[o].shapeIndex[i] = _lvlShapeIndex++;
+		}
+	}
+
+	p2[index] = o;
+	if (_levelShapeProperties[o].next)
+		_levelShapeProperties[o].next = assignLevelShapes(_levelShapeProperties[o].next);
+
+	return o;
+}
+
+uint8 *LoLEngine::getLevelShapes(int shapeIndex) {
+	if (_lvlShpNum <= shapeIndex)
+		return 0;
+
+	uint32 offs = _lvlShpHeader[shapeIndex] + 2;
+	_lvlShpFileHandle->seek(offs, 0);
+
+	uint8 tmp[16];
+	_lvlShpFileHandle->read(tmp, 16);
+	uint16 size = _screen->getShapeSize(tmp);
+
+	_lvlShpFileHandle->seek(offs, 0);
+	uint8 *res = new uint8[size];
+	_lvlShpFileHandle->read(res, size);
+	
+	return res;
+}
+
+void LoLEngine::loadLevelCMZ(int index) {
+	//char filename[] = "_LEVEL%d.TMP";
+	//sprintf(filename, "_LEVEL%d.TMP", index);
+	// TODO ???
+	memset(_tempBuffer5120, 0, 5120);
+	uint16 tmpLvlVal = 0;
+
+
+	char filename[] = "level%d.cmz";
+	sprintf(filename, "level%d.cmz", index);
+	
+	_screen->loadBitmap(filename, 3, 3, 0);
+	const uint8 *p = _screen->getCPagePtr(2);
+	uint16 len = READ_LE_UINT16(p + 4);
+
+	uint8 *cmzdata = new uint8[0x1000];
+
+	for (int i = 0; i < 1024; i++)
+		 memcpy(&cmzdata[i << 2], &p[i * len + 6], 4);
+
+	memset(_cmzBuffer, 0, 1024 * sizeof(CMZ));
+
+	uint8 *c = cmzdata;
+	uint8 *t = _tempBuffer5120;
+
+	for (int i = 0; i < 1024; i++) {
+		for (int ii = 0; ii < 4; ii++)
+			_cmzBuffer[i].unk[ii] = *c++ ^ *t++;
+	}
+
+	for (int i = 0; i < 1024; i++)
+		_cmzBuffer[i].flags = *t++;
+
+	for (int i = 0; i < 30; i++) {
+		if (_lvlBuffer[i].cmzIndex) {
+			_lvlBuffer[i].cmzIndex = 0;
+			_lvlBuffer[i].offs_lvl415 = _lvl415 + _lvlBuffer[i].field_20;
+			initCMZ2(&_lvlBuffer[i], _lvlBuffer[i].p_1a, _lvlBuffer[i].p_1b);
+		}
+	}
+		
+	loadCMZ_Sub(tmpLvlVal, (_unkGameFlag & 0x30) >> 4);
+
+	delete []cmzdata;
+}
+
+void LoLEngine::loadCMZ_Sub(int index1, int index2) {
+	static const int table[] = { 0x66, 0x100, 0x180, 0x100, 0x100, 0xC0, 0x140, 0x100, 0x80, 0x80, 0x100, 0x100 };
+	int val = (table[index2] << 8) / table[index1];
+
+	//int r = 0;
+	
+	for (int i = 0; i < 30; i++) {
+		if (_lvlBuffer[i].field_14 >= 14 || _lvlBuffer[i].cmzIndex == 0 || _lvlBuffer[i].field_1D <= 0)
+			continue;
+
+		int t = (val * _lvlBuffer[i].field_1D) >> 8;
+		_lvlBuffer[i].field_1D = t;
+		if (index2 < index1)
+			_lvlBuffer[i].field_1D++;
+		if (_lvlBuffer[i].field_1D == 0)
+			_lvlBuffer[i].field_1D = 1;
+	}
+}
+
+void LoLEngine::loadCmzFile(const char *file) {
+	memset(_cmzBuffer, 0, 1024 * sizeof(CMZ));
+	_screen->loadBitmap(file, 2, 2, 0);
+	const uint8 *h = _screen->getCPagePtr(2);
+	uint16 len = READ_LE_UINT16(&h[4]);
+	const uint8 *p = h + 6;
+	
+	for (int i = 0; i < 1024; i++) {
+		for (int ii = 0; ii < 4; ii++)
+			_cmzBuffer[i].unk[ii] = p[i * len + ii];
+
+		_cmzBuffer[i].field_8 = 5;
+
+		if (_wllBuffer4[_cmzBuffer[i].unk[0]] == 17) {
+			_cmzBuffer[i].flags &= 0xef;
+			_cmzBuffer[i].flags |= 0x20;
+		}
+	}
+}
+
+void LoLEngine::loadMonsterShapes(const char *file, int monsterIndex, int b) {
+	releaseMonsterShapes(monsterIndex);
+	_screen->loadBitmap(file, 3, 3, 0);
+
+	const uint8 *p = _screen->getCPagePtr(2);
+	const uint8 *ts[16];
+
+	for (int i = 0; i < 16; i++) {
+		ts[i] = _screen->getPtrToShape(p, i);
+
+		bool replaced = false;
+		int pos = monsterIndex << 4;
+		
+		for (int ii = 0; ii < i; ii++) {
+			if (ts[i] != ts[ii])
+				continue;
+
+			_monsterShapes[pos + i] = _monsterShapes[pos + ii];
+			replaced = true;
+			break;			
+		}
+
+		if (!replaced)
+			_monsterShapes[pos + i] = _screen->makeShapeCopy(p, i);
+
+		int size = _screen->getShapePaletteSize(_monsterShapes[pos + i]) << 3;
+		_monsterPalettes[pos + i] = new uint8[size];
+		memset(_monsterPalettes[pos + i], 0, size);
+	}
+
+	/*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;
+			*of = _screen->makeShapeCopy(p, s);
+			////TODO
+		}
+	}*/
+	_monsterUnk[monsterIndex] = b & 0xff;
+
+	uint8 *tsh = _screen->makeShapeCopy(p, 16);
+
+	_screen->clearPage(3);
+	_screen->drawShape(2, tsh, 0, 0, 0, 0);
+
+	uint8 *tmpPal1 = new uint8[64];
+	uint8 *tmpPal2 = new uint8[256];
+	uint16 *tmpPal3 = new uint16[256];
+	memset (tmpPal1, 0, 64);
+	memset (tmpPal2, 0, 256);
+	memset (tmpPal3, 0xff, 512);
+
+	for (int i = 0; i < 64; i++) {
+		tmpPal1[i] = *p;
+		p += 320;
+	}
+
+	p = _screen->getCPagePtr(2);
+
+	for (int i = 0; i < 16; i++) {
+		int pos = (monsterIndex << 4) + i;
+		memcpy(tmpPal2, _monsterShapes[pos] + 10, 256);
+		uint8 numCol = *tmpPal2;
+		
+		for (int ii = 0; ii < numCol; ii++) {
+			uint8 *cl = (uint8*)memchr(tmpPal1, tmpPal2[1 + ii], 64);
+			if (!cl)
+				continue;			
+			tmpPal3[ii] = (uint16) (cl - tmpPal1);
+		}
+
+		for (int ii = 0; ii < 8; ii++) {
+			memcpy(tmpPal2, _monsterShapes[pos] + 10, 256);
+			for (int iii = 0; iii < numCol; iii++) {
+				if (tmpPal3[iii] == 0xffff)
+					continue;
+				if (p[tmpPal3[iii] * 320 + ii + 1])
+					tmpPal2[1 + iii] = p[tmpPal3[iii] * 320 + ii + 1];
+			}
+			memcpy(_monsterPalettes[pos] + ii * numCol, &tmpPal2[1], numCol);
+		}
+	}
+
+	delete []tmpPal1;
+	delete []tmpPal2;
+	delete []tmpPal3;
+	delete [] tsh;
+}
+
+void LoLEngine::releaseMonsterShapes(int monsterIndex) {
+	for (int i = 0; i < 16; i++) {
+		int pos = (monsterIndex << 4) + i;
+		if (_monsterShapes[pos]) {
+			delete []_monsterShapes[pos];
+			_monsterShapes[pos] = 0;
+		}
+
+		if (_monsterPalettes[pos]) {
+			delete []_monsterPalettes[pos];
+			_monsterPalettes[pos] = 0;
+		}		
+	}
+}
+
+void LoLEngine::loadLevelShpDat(const char *shpFile, const char *datFile, bool flag) {
+	memset(_tempBuffer5120, 0, 5120);
+
+	_lvlShpFileHandle = _res->getFileStream(shpFile);
+	_lvlShpNum = _lvlShpFileHandle->readUint16LE();
+	delete []_lvlShpHeader;
+	_lvlShpHeader = new uint32[_lvlShpNum];
+	for (int i = 0; i < _lvlShpNum; i++)
+		_lvlShpHeader[i] = _lvlShpFileHandle->readUint32LE();
+
+	Common::SeekableReadStream *s = _res->getFileStream(datFile);
+
+	_levelFileDataSize = s->readUint16LE();
+	delete []_levelFileData;
+	_levelFileData = new LevelShapeProperty[_levelFileDataSize];
+	for (int i = 0; i < _levelFileDataSize; i++) {
+		LevelShapeProperty * l = &_levelFileData[i];
+		for (int ii = 0; ii < 10; ii++)
+			l->shapeIndex[ii] = s->readUint16LE();
+		for (int ii = 0; ii < 10; ii++)
+			l->scaleFlag[ii] = s->readByte();
+		for (int ii = 0; ii < 10; ii++)
+			l->shapeX[ii] = s->readUint16LE();
+		for (int ii = 0; ii < 10; ii++)
+			l->shapeY[ii] = s->readUint16LE();
+		l->next = s->readByte();
+		l->flags = s->readByte();
+	}
+
+	delete []s;
+
+	if (!flag) {
+		_lvlBlockIndex = 1;
+		_lvlShapeIndex = 1;
+	}
+}
+
+void LoLEngine::loadLevelSupplemenaryFiles(const char *file, int specialColor, int weight, int vcnLen, int vmpLen, const char *langFile) {
+	if (file) {
+		_lastSpecialColor = specialColor;
+		_lastSpecialColorWeight = weight;
+		strcpy(_lastSuppFile, file);
+		if (langFile) {
+			strcpy(_lastSuppLangFile, langFile);
+			_lastSuppLangFilePtr = _lastSuppLangFile;
+		} else {
+			_lastSuppLangFilePtr = 0;
+		}
+	}
+	
+	char fname[] = "            ";
+	sprintf(fname, "%s.%s", _lastSuppFile, "VCN");
+
+	_screen->loadBitmap(fname, 3, 3, 0);
+	const uint8 *v = _screen->getCPagePtr(2);
+	int tlen = READ_LE_UINT16(v);
+	v += 2;
+
+	if (vcnLen == -1)
+		vcnLen = tlen << 5;
+
+	if (_vcnBlocks)
+		delete []_vcnBlocks;
+	_vcnBlocks = new uint8[vcnLen];
+
+	if (_vcnShift)
+		delete []_vcnShift;
+	_vcnShift = new uint8[tlen];
+
+	memcpy(_vcnShift, v, tlen);
+	v += tlen;
+	
+	memcpy(_vcnExpTable, v, 128);
+	v += 128;
+	
+	if (_lastSuppLangFilePtr) {
+		if (_levelLangFile)
+			delete []_levelLangFile;
+		_levelLangFile = _res->fileData(_lastSuppLangFilePtr, 0);
+	}
+
+	memcpy(_screen->_currentPalette, v, 384);
+	v += 384;
+	/*uint8 tmpPal = new uint8[384];
+	memcpy(tmpPal, _screen->_currentPalette + 384, 384);
+	memset(_screen->_currentPalette + 384, 0xff, 384);
+	memcpy(_screen->_currentPalette + 384, tmpPal, 384);*/
+	
+	//loadSwampIceCol();
+
+	memcpy(_vcnBlocks, v, vcnLen);
+	v += vcnLen;
+
+	sprintf(fname, "%s.%s", _lastSuppFile, "VMP");
+	_screen->loadBitmap(fname, 3, 3, 0);
+	v = _screen->getCPagePtr(2);
+
+	if (vmpLen == -1)
+		vmpLen = READ_LE_UINT16(v);
+	v += 2;
+
+	if (_vmpPtr)
+		delete []_vmpPtr;
+	_vmpPtr = new uint16[vmpLen];
+
+	for (int i = 0; i < vmpLen; i++)
+		_vmpPtr[i] = READ_LE_UINT16(&v[i << 1]);
+
+	for (int i = 0; i < 7; i++) {
+		weight = 100 - (i * _lastSpecialColorWeight);
+		weight = (weight > 0) ? (weight * 255) / 100 : 0;
+		_screen->generateLevelOverlay(_screen->_currentPalette, _screen->getLevelOverlay(i), _lastSpecialColor, weight);
+
+		for (int ii = 0; ii < 128; ii++) {
+			if (_screen->getLevelOverlay(i)[ii] == 255)
+				_screen->getLevelOverlay(i)[ii] = 0;
+		}
+
+		for (int ii = 128; ii < 256; ii++)
+			_screen->getLevelOverlay(i)[ii] = ii & 0xff;
+	}
+
+	for (int i = 0; i < 256; i++)
+		_screen->getLevelOverlay(7)[i] = i & 0xff;
+
+	_loadSuppFilesFlag = 0;
+	_screen->generateBrightnessPalette(_screen->_currentPalette, _screen->getPalette(1), _brightness, _lampOilStatus);
+
+	char tname[] = "LEVEL%02d.TLC";
+	sprintf(tname, "LEVEL%02d.TLC", _currentLevel);
+	Common::SeekableReadStream *s = _res->getFileStream(tname);
+	s->read(_tlcTable1, 256);
+	s->read(_tlcTable2, 5120);
+	delete []s;
+
+	_loadSuppFilesFlag = 1;
+}
+
+void LoLEngine::turnOnLamp() {
+	_screen->_drawGuiFlag |= 0x400;
+	_lampOilStatus = 255;
+	updateLampStatus();
+}
+
+void LoLEngine::updateLampStatus() {
+	uint8 newLampOilStatus = 0;
+	uint8 tmp2 = 0;
+
+	if ((_charFlagUnk & 4) || !(_screen->_drawGuiFlag & 0x800))
+		return;
+
+	if (!_brightness || !_lampStatusUnk) {
+		newLampOilStatus = 8;
+		if (newLampOilStatus != _lampOilStatus && _screen->_fadeFlag == 0)
+			_screen->setPaletteBrightness(_screen->_currentPalette, _lampOilStatus, newLampOilStatus);			
+	} else {
+		tmp2 = (_lampStatusUnk < 100) ? _lampStatusUnk : 100;
+		newLampOilStatus = (3 - (tmp2 - 1) / 25) << 1;
+
+		if (_lampOilStatus == 255) {
+			if (_screen->_fadeFlag == 0)
+					_screen->setPaletteBrightness(_screen->_currentPalette, _brightness, newLampOilStatus);
+			_lampStatusTimer = _system->getMillis() + (10 + _rnd.getRandomNumberRng(1, 30)) * _tickLength;
+		} else {
+			if ((_lampOilStatus & 0xfe) == (newLampOilStatus & 0xfe)) {
+				if (_system->getMillis() <= _lampStatusTimer) {
+					newLampOilStatus = _lampOilStatus;
+				} else {
+					newLampOilStatus = _lampOilStatus ^ 1;
+					_lampStatusTimer = _system->getMillis() + (10 + _rnd.getRandomNumberRng(1, 30)) * _tickLength;
+				}
+			} else {
+				if (_screen->_fadeFlag == 0)
+					_screen->setPaletteBrightness(_screen->_currentPalette, _lampOilStatus, newLampOilStatus);
+			}
+		}
+	}
+
+	if (newLampOilStatus == _lampOilStatus)
+		return;
+
+	_screen->hideMouse();
+
+	_screen->drawShape(_screen->_curPage, _gameShapes[35 + newLampOilStatus], 291, 56, 0, 0);
+	_screen->showMouse();
+
+	_lampOilStatus = newLampOilStatus;
+}
+
+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;		
+	_cmzBuffer[block].flags |= 7;
+	// TODO
+}
+
+void LoLEngine::drawScene(int pageNum) {
+	if (pageNum && pageNum != _sceneDrawPage1) {
+		_sceneDrawPage1 ^= _sceneDrawPage2;
+		_sceneDrawPage2 ^= _sceneDrawPage1;
+		_sceneDrawPage1 ^= _sceneDrawPage2;
+		updateSceneWindow();
+	}
+
+	if (pageNum && pageNum != _sceneDrawPage1) {
+		_sceneDrawPage1 ^= _sceneDrawPage2;
+		_sceneDrawPage2 ^= _sceneDrawPage1;
+		_sceneDrawPage1 ^= _sceneDrawPage2;
+		updateSceneWindow();
+	}
+
+	generateBlockDrawingBuffer(_currentBlock, _unkPara2);
+	drawVcnBlocks(_vcnBlocks, _blockDrawingBuffer, _vcnShift, _sceneDrawPage1);
+	drawSceneShapes();
+
+	if (pageNum) {
+		drawScriptShapes(_sceneDrawPage1);
+		_screen->copyRegion(112, 112, 0, 0, 176, 120, _sceneDrawPage1, _sceneDrawPage2);
+		_screen->copyRegion(112, 112, 0, 0, 176, 120, _sceneDrawPage1, 0);
+		_sceneDrawPage1 ^= _sceneDrawPage2;
+		_sceneDrawPage2 ^= _sceneDrawPage1;
+		_sceneDrawPage1 ^= _sceneDrawPage2;
+	}
+
+	gui_drawCompass();
+
+	_boolScriptFuncDone = false;
+}
+
+void LoLEngine::updateSceneWindow() {
+	_screen->hideMouse();
+	_screen->copyRegion(112, 0, 112, 0, 176, 120, 0, _sceneDrawPage2);
+	_screen->showMouse();
+}
+
+void LoLEngine::generateBlockDrawingBuffer(int block, int b) {
+	_sceneDrawVar1 = _dscBlockMap[_unkPara2];
+	_sceneDrawVar2 = _dscBlockMap[_unkPara2 + 4];
+	_sceneDrawVar3 = _dscBlockMap[_unkPara2 + 8];
+
+	memset(_blockDrawingBuffer, 0, 660 * sizeof(uint16));
+
+	_wllProcessFlag = ((block >> 5) + (block & 0x1f) + _unkPara2) & 1;
+
+	if (_wllProcessFlag)
+		generateBlockDrawingBufferF1(0, 15, 1, -330, 22, 15);
+	else
+		generateBlockDrawingBufferF0(0, 15, 1, -330, 22, 15);
+
+	assignBlockCaps(block, b);
+
+	uint8 t = _curBlockCaps[0]->unk[_sceneDrawVar2];
+	if (t)
+		generateBlockDrawingBufferF0(-2, 3, t, 102, 3, 5);
+
+	t = _curBlockCaps[6]->unk[_sceneDrawVar3];
+	if (t)
+		generateBlockDrawingBufferF1(21, 3, t, 102, 3, 5);
+
+	t = _curBlockCaps[1]->unk[_sceneDrawVar2];
+	uint8 t2 = _curBlockCaps[2]->unk[_sceneDrawVar1];
+
+	if (testWllBuffer5Value(t) && !(_wllBuffer5[t2] & 8))
+		generateBlockDrawingBufferF0(2, 3, t, 102, 3, 5);
+	else if (t && (_wllBuffer5[t2] & 8))
+		generateBlockDrawingBufferF0(2, 3, t2, 102, 3, 5);
+
+	t = _curBlockCaps[5]->unk[_sceneDrawVar3];
+	t2 = _curBlockCaps[4]->unk[_sceneDrawVar1];
+
+	if (testWllBuffer5Value(t) && !(_wllBuffer5[t2] & 8))
+		generateBlockDrawingBufferF1(17, 3, t, 102, 3, 5);
+	else if(t && (_wllBuffer5[t2] & 8))
+		generateBlockDrawingBufferF1(17, 3, t2, 102, 3, 5);
+
+	t = _curBlockCaps[2]->unk[_sceneDrawVar2];
+	if (t)
+		generateBlockDrawingBufferF0(8, 3, t, 97, 1, 5);
+
+	t = _curBlockCaps[4]->unk[_sceneDrawVar3];
+	if (t)
+		generateBlockDrawingBufferF1(13, 3, t, 97, 1, 5);
+
+	t = _curBlockCaps[1]->unk[_sceneDrawVar1];
+	if (testWllBuffer5Value(t))
+		generateBlockDrawingBufferF0(-4, 3, t, 129, 6, 5);
+
+	t = _curBlockCaps[5]->unk[_sceneDrawVar1];
+	if (testWllBuffer5Value(t))
+		generateBlockDrawingBufferF0(20, 3, t, 129, 6, 5);
+
+	t = _curBlockCaps[2]->unk[_sceneDrawVar1];
+	if (testWllBuffer5Value(t))
+		generateBlockDrawingBufferF0(2, 3, t, 129, 6, 5);
+
+	t = _curBlockCaps[4]->unk[_sceneDrawVar1];
+	if (testWllBuffer5Value(t))
+		generateBlockDrawingBufferF0(14, 3, t, 129, 6, 5);
+
+	t = _curBlockCaps[3]->unk[_sceneDrawVar1];
+	if (t)
+		generateBlockDrawingBufferF0(8, 3, t, 129, 6, 5);
+
+	t = _curBlockCaps[7]->unk[_sceneDrawVar2];
+	if (t)
+		generateBlockDrawingBufferF0(0, 3, t, 117, 2, 6);
+
+	t = _curBlockCaps[11]->unk[_sceneDrawVar3];
+	if (t)
+		generateBlockDrawingBufferF1(20, 3, t, 117, 2, 6);
+
+	t = _curBlockCaps[8]->unk[_sceneDrawVar2];
+	if (t)
+		generateBlockDrawingBufferF0(6, 2, t, 81, 2, 8);
+
+	t = _curBlockCaps[10]->unk[_sceneDrawVar3];
+	if (t)
+		generateBlockDrawingBufferF1(14, 2, t, 81, 2, 8);
+
+	t = _curBlockCaps[8]->unk[_sceneDrawVar1];
+	if (testWllBuffer5Value(t))
+		generateBlockDrawingBufferF0(-4, 2, t, 159, 10, 8);
+
+	t = _curBlockCaps[10]->unk[_sceneDrawVar1];
+	if (testWllBuffer5Value(t))
+		generateBlockDrawingBufferF0(16, 2, t, 159, 10, 8);
+
+	t = _curBlockCaps[9]->unk[_sceneDrawVar1];
+	if (t)
+		generateBlockDrawingBufferF0(6, 2, t, 159, 10, 8);
+
+	t = _curBlockCaps[12]->unk[_sceneDrawVar2];
+	if (t)
+		generateBlockDrawingBufferF0(3, 1, t, 45, 3, 12);
+
+	t = _curBlockCaps[14]->unk[_sceneDrawVar3];
+	if (t)
+		generateBlockDrawingBufferF1(16, 1, t, 45, 3, 12);
+
+	t = _curBlockCaps[12]->unk[_sceneDrawVar1];
+	if (!(_wllBuffer5[t] & 8))
+		generateBlockDrawingBufferF0(-13, 1, t, 239, 16, 12);
+
+	t = _curBlockCaps[14]->unk[_sceneDrawVar1];
+	if (!(_wllBuffer5[t] & 8))
+		generateBlockDrawingBufferF0(19, 1, t, 239, 16, 12);
+
+	t = _curBlockCaps[13]->unk[_sceneDrawVar1];
+	if (t)
+		generateBlockDrawingBufferF0(3, 1, t, 239, 16, 12);
+
+	t = _curBlockCaps[15]->unk[_sceneDrawVar2];
+	t2 = _curBlockCaps[17]->unk[_sceneDrawVar3];
+	if (t)
+		generateBlockDrawingBufferF0(0, 0, t, 0, 3, 15);
+	if (t2)
+		generateBlockDrawingBufferF1(19, 0, t, 0, 3, 15);
+}
+
+void LoLEngine::generateBlockDrawingBufferF0(int16 wllOffset, uint8 wllIndex, uint8 wllVmpIndex, int16 vmpOffset, uint8 len, uint8 numEntries) {
+	if (!_wllVmpMap[wllVmpIndex])
+		return;
+
+	uint16 *vmp = &_vmpPtr[(_wllVmpMap[wllVmpIndex] - 1) * 431 + vmpOffset + 330];
+
+	for (int i = 0; i < numEntries; i++) {
+		uint16 *bl = &_blockDrawingBuffer[(wllIndex + i) * 22 + wllOffset];
+		for (int ii = 0; ii < len; ii++) {
+			if ((wllOffset + ii >= 0) && (wllOffset + ii < 22) && *vmp)
+				*bl = *vmp;
+			bl++;
+			vmp++;
+		}
+	}
+}
+
+void LoLEngine::generateBlockDrawingBufferF1(int16 wllOffset, uint8 wllIndex, uint8 wllVmpIndex, int16 vmpOffset, uint8 len, uint8 numEntries) {
+	if (!_wllVmpMap[wllVmpIndex])
+		return;
+
+	uint16 *vmp = &_vmpPtr[(_wllVmpMap[wllVmpIndex] - 1) * 431 + vmpOffset + 330];
+
+	for (int i = 0; i < numEntries; i++) {
+		for (int ii = 0; ii < len; ii++) {
+			if ((wllOffset + ii >= 0) && (wllOffset + ii < 22)) {
+				uint16 t = vmp[len * i + len - 1 - ii];
+				if (t) {				
+					if (t & 04000)
+						t -= 0x4000;
+					else
+						t |= 0x4000;
+
+					_blockDrawingBuffer[(wllIndex + i) * 22 + wllOffset + ii] = t;
+				}
+			}
+		}
+	}
+}
+
+bool LoLEngine::testWllBuffer5Value(int index) {
+	if (!index || (_wllBuffer5[index] & 8))
+		return false;
+	return true;
+}
+
+void LoLEngine::assignBlockCaps(int a, int b) {
+	for (int i = 0; i < 18; i++) {
+		uint16 t = (a + _dscBlockIndex[b * 18 + i]) & 0x3ff;
+		_scriptExecutedFuncs[i] = t;
+
+		_curBlockCaps[i] = &_cmzBuffer[t];
+		_lvlShapeLeftRight[i] = _lvlShapeLeftRight[18 + i] = -1;
+	}
+}
+
+void LoLEngine::drawVcnBlocks(uint8 *vcnBlocks, uint16 *blockDrawingBuffer, uint8 *vcnShift, int pageNum) {
+	uint8 *d = _sceneWindowBuffer;	
+	
+	for (int y = 0; y < 15; y++) {
+		for (int x = 0; x < 22; x++) {
+			bool flag = false;
+			int remainder = 0;
+
+			uint16 vcnOffset = *blockDrawingBuffer++;
+
+			if (vcnOffset & 0x8000) {
+				remainder = vcnOffset - 0x8000;
+				vcnOffset = 0;
+			}
+
+			if (vcnOffset & 0x4000) {
+				flag = true;
+				vcnOffset &= 0x3fff;
+			}
+
+			if (!vcnOffset) {
+				vcnOffset = blockDrawingBuffer[329];
+				if (vcnOffset & 0x4000) {
+					flag = true;
+					vcnOffset &= 0x3fff;
+				}
+			}
+	
+			uint8 shift = vcnShift[vcnOffset];
+			uint8 *src = &vcnBlocks[vcnOffset << 5];
+
+			if (flag) {				
+				for (int blockY = 0; blockY < 8; blockY++) {
+					src += 3;
+					for (int blockX = 0; blockX < 4; blockX++) {
+						uint8 t = *src--;
+						*d++ = _vcnExpTable[(t & 0x0f) | shift];
+						*d++ = _vcnExpTable[(t >> 4) | shift];
+					}
+					src += 5;
+					d += 168;
+				}
+			} else {
+				for (int blockY = 0; blockY < 8; blockY++) {
+					for (int blockX = 0; blockX < 4; blockX++) {
+						uint8 t = *src++;
+						*d++ = _vcnExpTable[(t >> 4) | shift];
+						*d++ = _vcnExpTable[(t & 0x0f) | shift];
+					}
+					d += 168;
+				}				
+			}
+			d -= 1400;
+
+			if (remainder) {
+				d -= 8;
+				flag = false;
+
+				if (remainder & 0x4000) {
+					remainder &= 0x3fff;
+					flag = true;
+				}
+
+				shift = vcnShift[remainder];
+				src = &vcnBlocks[remainder << 5];
+
+				if (flag) {	
+					for (int blockY = 0; blockY < 8; blockY++) {
+						src += 3;
+						for (int blockX = 0; blockX < 4; blockX++) {
+							uint8 t = *src--;
+							uint8 h = _vcnExpTable[(t & 0x0f) | shift];
+							uint8 l = _vcnExpTable[(t >> 4) | shift];
+							if (h) 
+								*d = h;
+							d++;
+							if (l) 
+								*d = l;
+							d++;
+						}
+						src += 5;
+						d += 168;
+					}
+				} else {
+					for (int blockY = 0; blockY < 8; blockY++) {
+						for (int blockX = 0; blockX < 4; blockX++) {
+							uint8 t = *src++;
+							uint8 h = _vcnExpTable[(t >> 4) | shift]; 
+							uint8 l = _vcnExpTable[(t & 0x0f) | shift];
+							if (h) 
+								*d = h;
+							d++;
+							if (l) 
+								*d = l;
+							d++;
+						}
+						d += 168;
+					}
+				}
+				d -= 1400;
+			}
+		}
+		d += 1232;
+	}
+
+	_screen->copyBlockToPage(pageNum, 112, 0, 176, 120, _sceneWindowBuffer);
+}
+
+void LoLEngine::drawSceneShapes() {
+	for (int i = 0; i < 18; i++) {
+		uint8 t = _dscTileIndex[i];
+		uint8 s = _curBlockCaps[t]->unk[_sceneDrawVar1];
+
+		int16 x1 = 0;
+		int16 x2 = 0;
+
+		int16 dimY1 = 0;
+		int16 dimY2 = 0;
+
+		setLevelShapesDim(t, x1, x2, 13);
+
+		if (x2 <= x1)
+			continue;
+
+		drawDecorations(t);
+
+		uint16 w = _wllBuffer5[s];
+
+		if (i == 16)
+			w |= 0x80;
+
+		drawIceShapes(t, 0);
+
+		//if (_curBlockCaps[t]->itemIndex && (w & 0x80))
+			//sub_3AA55(t);
+
+		drawIceShapes(t, 1);
+
+		if (!(w & 8))
+			continue;
+
+		uint16 v = 20 * (s - _dscUnk2[s]);
+		
+		scaleLevelShapesDim(t, dimY1, dimY2, 13);
+		drawDoor(_doorShapes[_dscDoorShpIndex[s]], 0, t, 10, 0, -v, 2);
+		setLevelShapesDim(t, dimY1, dimY2, 13);
+	}
+}
+
+void LoLEngine::setLevelShapesDim(int index, int16 &x1, int16 &x2, int dim) {
+	if (_lvlShapeLeftRight[index << 1] == -1) {
+		x1 = 0;
+		x2 = 22;
+
+		int16 y1 = 0;
+		int16 y2 = 120;
+
+		int m = index * 18;
+
+		for (int i = 0; i < 18; i++) {
+			uint8 d = _curBlockCaps[i]->unk[_sceneDrawVar1];
+			uint8 a = _wllBuffer5[d];
+
+			if (a & 8) {
+				int t = _dscDim2[(m + i) << 1];
+
+				if (t > x1) {
+					x1 = t;
+					if (!(a & 0x10))
+						scaleLevelShapesDim(index, y1, y2, -1);
+				}
+
+				t = _dscDim2[((m + i) << 1) + 1];
+				
+				if (t < x2) {
+					x2 = t;
+					if (!(a & 0x10))
+						scaleLevelShapesDim(index, y1, y2, -1);
+				}
+			} else {
+				int t = _dscDim1[m + i];
+				
+				if (!_wllVmpMap[d] || t == -40)
+					continue;
+
+				if (t == -41) {
+					x1 = 22;
+					x2 = 0;
+					break;
+				}
+
+				if (t > 0 && x2 > t)
+					x2 = t;
+
+				if (t < 0 && x1 < -t)
+					x1 = -t;
+			}
+			
+			if (x2 < x1)
+				break;
+		}
+		
+		x1 += 14;
+		x2 += 14;
+
+		_lvlShapeTop[index] = y1;
+		_lvlShapeBottom[index] = y2;
+		_lvlShapeLeftRight[index << 1] = x1;
+		_lvlShapeLeftRight[(index << 1) + 1] = x2;
+	} else {
+		x1 = _lvlShapeLeftRight[index << 1];
+		x2 = _lvlShapeLeftRight[(index << 1) + 1];
+	}
+
+	drawLevelModifyScreenDim(dim, x1, 0, x2, 15);
+}
+
+void LoLEngine::scaleLevelShapesDim(int index, int16 &y1, int16 &y2, int dim) {
+	static const int8 dscY1[] = { 0x1E, 0x18, 0x10, 0x00 };
+	static const int8 dscY2[] = { 0x3B, 0x47, 0x56, 0x78 };
+
+	uint8 a = _dscDimMap[index];
+
+	if (dim == -1 && a != 3)
+		a++;
+
+	y1 = dscY1[a];
+	y2 = dscY2[a];
+
+	if (dim == -1)
+		return;
+
+	const ScreenDim *cDim = _screen->getScreenDim(dim);
+
+	_screen->modifyScreenDim(dim, cDim->sx, y1, cDim->w, y2 - y1);
+}
+
+void LoLEngine::drawLevelModifyScreenDim(int dim, int16 x1, int16 y1, int16 x2, int16 y2) {
+	_screen->modifyScreenDim(dim, x1, y1 << 3, x2 - x1, (y2 - y1) << 3);
+}
+
+void LoLEngine::drawDecorations(int index) {
+	for (int i = 1; i >= 0; i--) {
+		int s = index * 2 + i;
+		uint16 scaleW = _dscShapeScaleW[s];
+		uint16 scaleH = _dscShapeScaleH[s];
+		int8 ix = _dscShapeIndex[s];
+		uint8 shpIx = ABS(ix);
+		uint8 ovlIndex = _dscShapeOvlIndex[_dscDimMap[index] * 5] + 2;
+		if (ovlIndex > 7)
+			ovlIndex = 7;
+
+		if (!scaleW || !scaleH)
+			continue;
+
+		uint8 d = (_unkPara2 + _dscUnk1[s]) & 3;
+		int8 l = _wllShapeMap[_curBlockCaps[index]->unk[d]];
+
+		uint8 *shapeData = 0;
+
+		int x = 0;
+		int y = 0;
+		int flags = 0;
+
+		while (l > 0) {
+			if ((_levelShapeProperties[l].flags & 8) && index != 3 && index != 9 && index != 13) {
+				l = _levelShapeProperties[l].next;
+				continue;
+			}
+
+			if (_dscOvlMap[shpIx] == 1 && ((_levelShapeProperties[l].flags & 2) || ((_levelShapeProperties[l].flags & 4) && _wllProcessFlag)))
+				ix = -ix;
+
+			int xOffs = 0;
+			int yOffs = 0;
+			uint8 *ovl = 0;
+
+			if (_levelShapeProperties[l].scaleFlag[shpIx] & 1) {
+				xOffs = _levelShapeProperties[l].shapeX[shpIx];
+				yOffs = _levelShapeProperties[l].shapeY[shpIx];
+				shpIx = _dscOvlMap[shpIx];
+				ovl = _screen->getLevelOverlay(ovlIndex);
+			} else if (_levelShapeProperties[l].shapeIndex[shpIx] != 0xffff) {
+				scaleW = scaleH = 0x100;
+				ovl = _screen->getLevelOverlay(7);
+			}
+
+			if (_levelShapeProperties[l].shapeIndex[shpIx] != 0xffff) {
+				shapeData = _levelShapes[_levelShapeProperties[l].shapeIndex[shpIx]];
+				if (shapeData) {
+					if (ix < 0) {
+						x = _dscShapeX[s] + xOffs + ((_levelShapeProperties[l].shapeX[shpIx] * scaleW) >> 8);
+						if (ix == _dscShapeIndex[s]) {
+							x = _dscShapeX[s] - ((_levelShapeProperties[l].shapeX[shpIx] * scaleW) >> 8) -
+								_screen->getShapeScaledWidth(shapeData, scaleW) - xOffs;
+						}
+						flags = 0x105;
+					} else {
+						x = _dscShapeX[s] + xOffs + ((_levelShapeProperties[l].shapeX[shpIx] * scaleW) >> 8);
+						flags = 0x104;
+					}
+
+					y = _dscShapeY[s] + yOffs + ((_levelShapeProperties[l].shapeY[shpIx] * scaleH) >> 8);
+					_screen->drawShape(_sceneDrawPage1, shapeData, x + 112, y, 13, flags, ovl, 1, scaleW, scaleH);
+
+					if ((_levelShapeProperties[l].flags & 1) && (shpIx >= 0) && (shpIx < 4)) {
+						//draw shadow
+						x += (_screen->getShapeScaledWidth(shapeData, scaleW));
+						flags ^= 1;
+						_screen->drawShape(_sceneDrawPage1, shapeData, x + 112, y, 13, flags, ovl, 1, scaleW, scaleH);
+					}
+				}
+			}
+
+			l = _levelShapeProperties[l].next;
+			shpIx = (_dscShapeIndex[s] < 0) ? -_dscShapeIndex[s] : _dscShapeIndex[s];
+		}
+	}
+}
+
+void LoLEngine::drawIceShapes(int index, int iceShapeIndex) {
+	uint8 f = _curBlockCaps[index]->flags;
+	if (!(f & 0xf0))
+		return;
+}
+
+void LoLEngine::drawDoor(uint8 *shape, uint8 *table, int index, int unk2, int w, int h, int flags) {
+	uint8 c = _dscDoor1[(_unkPara2 << 5) + unk2];
+	int r = (c / 5) + 5 * _dscDimMap[index];
+	uint16 d = _dscDoor2[r];
+	uint16 t = (index << 5) + c;
+
+	_shpDoorY = _dscDoorY[t] + 120;
+
+	if (flags & 1) {
+		// TODO
+	}
+
+	int u = 0;
+
+	if (flags & 2) {		
+		uint8 w = _dscDimMap[index];		
+		_doorScaleW = _dscDoorScaleTable[w << 1];
+		_doorScaleH = _dscDoorScaleTable[(w << 1) + 1];
+		u = _dscDoor4[w];
+	}
+
+	d += 2;
+
+	if (!_doorScaleW || !_doorScaleH)
+		return;
+
+	int s = _screen->getShapeScaledHeight(shape, _doorScaleH) >> 1;
+
+	if (w)
+		w = (w * _doorScaleW) >> 8;
+
+	if (h)
+		h = (h * _doorScaleH) >> 8;
+
+	_shpDoorX = _dscDoorX[t] + w + 200;
+	_shpDoorY = _shpDoorY + 4 - s + h - u;
+
+	if (d > 7)
+		d = 7;
+
+	uint8 *ovl = _screen->getLevelOverlay(d);
+	int doorScaledWitdh = _screen->getShapeScaledWidth(shape, _doorScaleW);
+	
+	_shpDoorX -= (doorScaledWitdh >> 1);
+	_shpDoorY -= s;
+
+	drawDoorShapes(shape, table, _shpDoorX, _shpDoorY, flags, ovl);
+}
+
+void LoLEngine::drawDoorShapes(uint8 *shape, uint8 *table, int x, int y, int flags, const uint8 *ovl) {
+	int flg = 0;
+
+	if (flags & 0x10)
+		flg |= 1;
+
+	if (flags & 0x20)
+		flg |= 0x1000;
+
+	if (flags & 0x40)
+		flg |= 2;
+
+	if (flg & 0x1000) {
+		if (table)
+			_screen->drawShape(_sceneDrawPage1, shape, x, y, 13, flg | 0x9104, table, ovl, 1, _tlcTable1, _tlcTable2, _doorScaleW, _doorScaleH);			
+		else
+			_screen->drawShape(_sceneDrawPage1, shape, x, y, 13, flg | 0x1104, ovl, 1, _tlcTable1, _tlcTable2, _doorScaleW, _doorScaleH);			
+	} else {
+		if (table)
+			_screen->drawShape(_sceneDrawPage1, shape, x, y, 13, flg | 0x8104, table, ovl, 1, _doorScaleW, _doorScaleH);
+		else
+			_screen->drawShape(_sceneDrawPage1, shape, x, y, 13, flg | 0x104, ovl, 1, _doorScaleW, _doorScaleH);
+	}
+}
+
+void LoLEngine::drawScriptShapes(int pageNum) {
+	// TODO
+}
+
+} // end of namespace Kyra
+


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

Modified: scummvm/trunk/engines/kyra/screen_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/screen_lol.cpp	2009-01-18 16:49:03 UTC (rev 35902)
+++ scummvm/trunk/engines/kyra/screen_lol.cpp	2009-01-18 17:04:24 UTC (rev 35903)
@@ -29,20 +29,68 @@
 namespace Kyra {
 
 Screen_LoL::Screen_LoL(LoLEngine *vm, OSystem *system) : Screen_v2(vm, system), _vm(vm) {
+	_customDimTable = new ScreenDim*[_screenDimTableCount];
+	memset(_customDimTable, 0, sizeof(ScreenDim*) * _screenDimTableCount);
+
+	_paletteOverlay1 = new uint8[0x100];
+	_paletteOverlay2 = new uint8[0x100];
+	_grayOverlay = new uint8[0x100];
+	memset(_paletteOverlay1, 0, 0x100);
+	memset(_paletteOverlay2, 0, 0x100);
+	memset(_grayOverlay, 0, 0x100);
+
+	for (int i = 0; i < 8; i++)
+		_levelOverlays[i] = new uint8[256];
+	
+	_fadeFlag = 2;
+	_drawGuiFlag = 0;
 }
 
+Screen_LoL::~Screen_LoL() {
+	for (int i = 0; i < _screenDimTableCount; i++)
+		delete _customDimTable[i];
+	delete []_customDimTable;
+
+	for (int i = 0; i < 8; i++)
+		delete []_levelOverlays[i];
+
+	delete []_paletteOverlay1;
+	delete []_paletteOverlay2;
+	delete []_grayOverlay;
+}
+
 void Screen_LoL::setScreenDim(int dim) {
 	debugC(9, kDebugLevelScreen, "Screen_LoL::setScreenDim(%d)", dim);
 	assert(dim < _screenDimTableCount);
-	_curDim = &_screenDimTable[dim];
+	_curDim = _customDimTable[dim] ? (const ScreenDim *)_customDimTable[dim] : &_screenDimTable[dim];
 }
 
 const ScreenDim *Screen_LoL::getScreenDim(int dim) {
 	debugC(9, kDebugLevelScreen, "Screen_LoL::getScreenDim(%d)", dim);
 	assert(dim < _screenDimTableCount);
-	return &_screenDimTable[dim];
+	return _customDimTable[dim] ? (const ScreenDim *)_customDimTable[dim] : &_screenDimTable[dim];
 }
 
+void Screen_LoL::modifyScreenDim(int dim, int x, int y, int w, int h) {
+	delete _customDimTable[dim];
+	_customDimTable[dim] = new ScreenDim;
+	memcpy(_customDimTable[dim], &_screenDimTable[dim], sizeof(ScreenDim));
+	_customDimTable[dim]->sx = x;
+	_customDimTable[dim]->sy = y;
+	_customDimTable[dim]->w = w;
+	_customDimTable[dim]->h = h;
+	setScreenDim(dim);
+}
+
+void Screen_LoL::clearDim(int dim) {
+	const ScreenDim *tmp = getScreenDim(dim);
+	fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 1, (tmp->sy + tmp->h) - 1, tmp->unkA);
+}
+
+void Screen_LoL::clearCurDim() {
+	fillRect(_curDim->sx << 3, _curDim->sy, ((_curDim->sx + _curDim->w) << 3) - 1, (_curDim->sy + _curDim->h) - 1, _curDim->unkA);
+}
+
 void Screen_LoL::fprintString(const char *format, int x, int y, uint8 col1, uint8 col2, uint16 flags, ...) {
 	debugC(9, kDebugLevelScreen, "Screen_LoL::fprintString('%s', %d, %d, %d, %d, %d, ...)", format, x, y, col1, col2, flags);
 	if (!format)
@@ -95,5 +143,178 @@
 	printText(buffer, x, y, c1, c2);
 }
 
+void Screen_LoL::generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool skipSpecialColours) {
+	uint8 tmpPal[768];
+
+	for (int i = 0; i != lastColor; i++) {
+		int v = (((srcPal[3 * i] & 0x3f) * factor) / 0x40) + addR;
+		tmpPal[3 * i] = (v > 0x3f) ? 0x3f : v & 0xff;
+		v = (((srcPal[3 * i + 1] & 0x3f) * factor) / 0x40) + addG;
+		tmpPal[3 * i + 1] = (v > 0x3f) ? 0x3f : v & 0xff;
+		v = (((srcPal[3 * i + 2] & 0x3f) * factor) / 0x40) + addB;
+		tmpPal[3 * i + 2] = (v > 0x3f) ? 0x3f : v & 0xff;
+	}
+
+	for (int i = 0; i < lastColor; i++)
+		grayOverlay[i] = findLeastDifferentColor(tmpPal + 3 * i, srcPal, lastColor, skipSpecialColours);
+}
+
+uint8 *Screen_LoL::generateLevelOverlay(const uint8 *srcPal, uint8 *ovl, int opColor, int weight) {
+	if (!srcPal || !ovl)
+		return ovl;
+
+	if (weight > 255)
+		weight = 255;
+
+	uint16 r = srcPal[opColor * 3];
+	uint16 g = srcPal[opColor * 3 + 1];
+	uint16 b = srcPal[opColor * 3 + 2];
+
+	uint8 *d = ovl;
+	*d++ = 0;
+
+	for (int i = 1; i != 255; i++) {
+		uint16 a = srcPal[i * 3];
+		uint8 dr = a - ((((a - r) * (weight >> 1)) << 1) >> 8);
+		a = srcPal[i * 3 + 1];
+		uint8 dg = a - ((((a - g) * (weight >> 1)) << 1) >> 8);
+		a = srcPal[i * 3 + 2];
+		uint8 db = a - ((((a - b) * (weight >> 1)) << 1) >> 8);
+
+		int l = opColor;
+		int m = 0x7fff;
+		int ii = 127;
+		int x = 1;
+		const uint8 *s = srcPal + 3;
+
+		do {
+			if (i == x) {
+				s += 3;
+			} else {
+				int t = *s++ - dr;
+				int c = t * t;
+				t = *s++ - dg;
+				c += (t * t);
+				t = *s++ - db;
+				c += (t * t);
+
+				if (!c) {
+					l = x;
+					break;
+				}
+
+				if (c <= m) {
+					m = c;
+					l = x;
+				}				
+			}
+			x++;
+		} while (--ii);
+
+		*d++ = l & 0xff;
+	}
+
+	return ovl;	
+}
+
+void Screen_LoL::drawGridBox(int x, int y, int w, int h, int col) {
+	if (w <= 0 || x >= 320 || h <= 0 || y >= 200)
+		return;
+
+	if (x < 0) {
+		x += w;
+		if (x <= 0)
+			return;
+		w = x;
+		x = 0;		
+	}
+
+	int tmp = x + w;
+	if (tmp >= 320) {
+		w = 320 - x;
+	}
+
+	int pitch = 320 - w;
+
+	if (y < 0) {
+		y += h;
+		if (y <= 0)
+			return;
+		h = y;
+		y = 0;		
+	}
+
+	tmp = y + h;
+	if (tmp >= 200) {
+		h = 200 - y;
+	}
+
+	tmp = (y + x) & 1;
+	uint8 *p = getPagePtr(_curPage) + y * 320 + x;
+	uint8 s = (tmp >> 8) & 1;
+
+	w >>= 1;
+	int w2 = w;
+	
+	while (h--) {
+		if (w) {
+			while (w--) {
+				*(p + tmp) = col;
+				p += 2;
+			}
+		} else {
+			w = 1;
+		}
+
+		if (s == 1) {
+			if (tmp == 0)
+				*p = col;
+			p++;
+		}
+		tmp ^= 1;
+		p += pitch;
+		w = w2;
+	}
+}
+
+void Screen_LoL::fadeToBlack(int delay, const UpdateFunctor *upFunc) {
+	Screen::fadeToBlack(delay, upFunc);
+	_fadeFlag = 2;
+}
+
+void Screen_LoL::setPaletteBrightness(uint8 *palette, int brightness, int modifier) {
+	generateBrightnessPalette(palette, getPalette(1), brightness, modifier);
+	fadePalette(getPalette(1), 5, 0);
+	_fadeFlag = 0;
+}
+
+void Screen_LoL::generateBrightnessPalette(uint8 *src, uint8 *dst, int brightness, int modifier) {
+	memcpy(dst, src, 0x300);
+	setPaletteColoursSpecial(dst);
+	brightness = (8 - brightness) << 5;
+	if (modifier >= 0 && modifier < 8 && _drawGuiFlag & 0x800) {
+		brightness = 256 - ((((modifier & 0xfffe) << 5) * (256 - brightness)) >> 8);
+		if (brightness < 0)
+			brightness = 0;
+	}
+	
+	for (int i = 0; i < 384; i++) {
+		uint16 c = (dst[i] * brightness) >> 8;
+		dst[i] = c & 0xff;
+	}
+}
+
+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);	
+}
+
+uint8 Screen_LoL::getShapePaletteSize(const uint8 *shp) {
+	debugC(9, kDebugLevelScreen, "Screen_LoL::getShapePaletteSize(%p)", (const void *)shp);
+
+	return shp[10];
+}
+
 } // end of namespace Kyra
 

Modified: scummvm/trunk/engines/kyra/screen_lol.h
===================================================================
--- scummvm/trunk/engines/kyra/screen_lol.h	2009-01-18 16:49:03 UTC (rev 35902)
+++ scummvm/trunk/engines/kyra/screen_lol.h	2009-01-18 17:04:24 UTC (rev 35903)
@@ -35,17 +35,46 @@
 class Screen_LoL : public Screen_v2 {
 public:
 	Screen_LoL(LoLEngine *vm, OSystem *system);
+	~Screen_LoL();
 
 	void setScreenDim(int dim);
 	const ScreenDim *getScreenDim(int dim);
+	void modifyScreenDim(int dim, int x, int y, int w, int h);
+	void clearDim(int dim);
+	void clearCurDim();
 
 	void fprintString(const char *format, int x, int y, uint8 col1, uint8 col2, uint16 flags, ...);
 	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 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 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);
+
+	uint8 *_paletteOverlay1;
+	uint8 *_paletteOverlay2;
+	uint8 *_grayOverlay;
+	int _fadeFlag;
+	int _drawGuiFlag;
+
 private:
 	LoLEngine *_vm;
 
 	static const ScreenDim _screenDimTable[];
 	static const int _screenDimTableCount;
+
+	ScreenDim **_customDimTable;
+
+	uint8 *_levelOverlays[8];
 };
 
 } // end of namespace Kyra

Modified: scummvm/trunk/engines/kyra/screen_v2.cpp
===================================================================
--- scummvm/trunk/engines/kyra/screen_v2.cpp	2009-01-18 16:49:03 UTC (rev 35902)
+++ scummvm/trunk/engines/kyra/screen_v2.cpp	2009-01-18 17:04:24 UTC (rev 35903)
@@ -90,11 +90,14 @@
 	}
 }
 
-int Screen_v2::findLeastDifferentColor(const uint8 *paletteEntry, const uint8 *palette, uint16 numColors) {
+int Screen_v2::findLeastDifferentColor(const uint8 *paletteEntry, const uint8 *palette, uint16 numColors, bool skipSpecialColours) {
 	int m = 0x7fff;
 	int r = 0x101;
 
 	for (int i = 0; i < numColors; i++) {
+		if (skipSpecialColours && i >= 0xc0 && i <= 0xc3)
+			continue;
+
 		int v = paletteEntry[0] - *palette++;
 		int c = v * v;
 		v = paletteEntry[1] - *palette++;

Modified: scummvm/trunk/engines/kyra/screen_v2.h
===================================================================
--- scummvm/trunk/engines/kyra/screen_v2.h	2009-01-18 16:49:03 UTC (rev 35902)
+++ scummvm/trunk/engines/kyra/screen_v2.h	2009-01-18 17:04:24 UTC (rev 35903)
@@ -45,7 +45,7 @@
 	// palette handling
 	uint8 *generateOverlay(const uint8 *palette, uint8 *buffer, int color, uint16 factor);

@@ 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