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

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Thu Jul 31 12:47:16 CEST 2008


Revision: 33463
          http://scummvm.svn.sourceforge.net/scummvm/?rev=33463&view=rev
Author:   lordhoto
Date:     2008-07-31 10:47:15 +0000 (Thu, 31 Jul 2008)

Log Message:
-----------
Committed slightly modified patch #2029395 "KYRA: Lands of Lore Intro + Character selection".

Modified Paths:
--------------
    scummvm/trunk/engines/kyra/detection.cpp
    scummvm/trunk/engines/kyra/kyra_hof.cpp
    scummvm/trunk/engines/kyra/kyra_v1.h
    scummvm/trunk/engines/kyra/module.mk
    scummvm/trunk/engines/kyra/resource.cpp
    scummvm/trunk/engines/kyra/screen_v2.cpp
    scummvm/trunk/engines/kyra/screen_v2.h
    scummvm/trunk/engines/kyra/script_tim.cpp
    scummvm/trunk/engines/kyra/script_tim.h
    scummvm/trunk/engines/kyra/sound_adlib.cpp
    scummvm/trunk/engines/kyra/staticres.cpp

Added Paths:
-----------
    scummvm/trunk/engines/kyra/lol.cpp
    scummvm/trunk/engines/kyra/lol.h
    scummvm/trunk/engines/kyra/screen_lol.cpp
    scummvm/trunk/engines/kyra/screen_lol.h

Modified: scummvm/trunk/engines/kyra/detection.cpp
===================================================================
--- scummvm/trunk/engines/kyra/detection.cpp	2008-07-30 21:58:44 UTC (rev 33462)
+++ scummvm/trunk/engines/kyra/detection.cpp	2008-07-31 10:47:15 UTC (rev 33463)
@@ -26,6 +26,7 @@
 #include "kyra/kyra_lok.h"
 #include "kyra/kyra_hof.h"
 #include "kyra/kyra_mr.h"
+#include "kyra/lol.h"
 
 #include "common/config-manager.h"
 #include "common/advancedDetector.h"
@@ -64,6 +65,8 @@
 #define KYRA3_CD_INS_FLAGS FLAGS(false, false, true, false, true, false, Kyra::GI_KYRA3)
 #define KYRA3_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, true, false, Kyra::GI_KYRA3)
 
+#define LOL_CD_FLAGS FLAGS(false, false, true, false, false, false, Kyra::GI_LOL)
+
 const KYRAGameDescription adGameDescs[] = {
 	{
 		{
@@ -700,6 +703,56 @@
 		},
 		KYRA3_CD_FAN_FLAGS(Common::IT_ITA, Common::FR_FRA)
 	},
+	
+	// Lands of Lore CD
+	{
+		{
+			"lol",
+			"CD",
+			{
+				{ "GENERAL.PAK", 0, "05a4f588fb81dc9c0ef1f2ec20d89e24", -1 },
+				{ "L01.PAK", 0, "759a0ac26808d77ea968bd392355ba1d", -1 },
+				{ 0, 0, 0, 0 }
+			},
+			Common::EN_ANY,
+			Common::kPlatformPC,
+			Common::ADGF_DROPLANGUAGE | Common::ADGF_CD
+		},
+		LOL_CD_FLAGS
+	},
+	
+	{
+		{
+			"lol",
+			"CD",
+			{
+				{ "GENERAL.PAK", 0, "05a4f588fb81dc9c0ef1f2ec20d89e24", -1 },
+				{ "L01.PAK", 0, "759a0ac26808d77ea968bd392355ba1d", -1 },
+				{ 0, 0, 0, 0 }
+			},
+			Common::DE_DEU,
+			Common::kPlatformPC,
+			Common::ADGF_DROPLANGUAGE | Common::ADGF_CD
+		},
+		LOL_CD_FLAGS
+	},
+	
+	{
+		{
+			"lol",
+			"CD",
+			{
+				{ "GENERAL.PAK", 0, "05a4f588fb81dc9c0ef1f2ec20d89e24", -1 },
+				{ "L01.PAK", 0, "759a0ac26808d77ea968bd392355ba1d", -1 },
+				{ 0, 0, 0, 0 }
+			},
+			Common::FR_FRA,
+			Common::kPlatformPC,
+			Common::ADGF_DROPLANGUAGE | Common::ADGF_CD
+		},
+		LOL_CD_FLAGS
+	},
+	
 	{ AD_TABLE_END_MARKER, FLAGS(0, 0, 0, 0, 0, 0, 0) }
 };
 
@@ -707,6 +760,7 @@
 	{ "kyra1", "The Legend of Kyrandia" },
 	{ "kyra2", "The Legend of Kyrandia: The Hand of Fate" },
 	{ "kyra3", "The Legend of Kyrandia: Malcolm's Revenge" },
+	{ "lol", "Lands of Lore: The Throne of Chaos" },
 	{ 0, 0 }
 };
 
@@ -779,6 +833,9 @@
 	case Kyra::GI_KYRA3:
 		*engine = new Kyra::KyraEngine_MR(syst, flags);
 		break;
+	case Kyra::GI_LOL:
+		*engine = new Kyra::LoLEngine(syst, flags);
+		break;
 	default:
 		res = false;
 		warning("Kyra engine: unknown gameID");

Modified: scummvm/trunk/engines/kyra/kyra_hof.cpp
===================================================================
--- scummvm/trunk/engines/kyra/kyra_hof.cpp	2008-07-30 21:58:44 UTC (rev 33462)
+++ scummvm/trunk/engines/kyra/kyra_hof.cpp	2008-07-31 10:47:15 UTC (rev 33463)
@@ -230,7 +230,7 @@
 	_gui = new GUI_HoF(this);
 	assert(_gui);
 	_gui->initStaticData();
-	_tim = new TIMInterpreter(this, _system);
+	_tim = new TIMInterpreter(this, _screen, _system);
 	assert(_tim);
 
 	if (_flags.isDemo && !_flags.isTalkie) {

Modified: scummvm/trunk/engines/kyra/kyra_v1.h
===================================================================
--- scummvm/trunk/engines/kyra/kyra_v1.h	2008-07-30 21:58:44 UTC (rev 33462)
+++ scummvm/trunk/engines/kyra/kyra_v1.h	2008-07-31 10:47:15 UTC (rev 33463)
@@ -64,7 +64,8 @@
 enum {
 	GI_KYRA1 = 0,
 	GI_KYRA2 = 1,
-	GI_KYRA3 = 2
+	GI_KYRA3 = 2,
+	GI_LOL = 4
 };
 
 struct AudioDataStruct {

Added: scummvm/trunk/engines/kyra/lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/lol.cpp	                        (rev 0)
+++ scummvm/trunk/engines/kyra/lol.cpp	2008-07-31 10:47:15 UTC (rev 33463)
@@ -0,0 +1,806 @@
+/* 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 "kyra/sound.h"
+
+#include "common/endian.h"
+
+namespace Kyra {
+
+LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(system, flags) {
+	_screen = 0;
+	
+	switch (_flags.lang) {
+	case Common::EN_ANY:
+	case Common::EN_USA:
+	case Common::EN_GRB:
+		_lang = 0;
+		break;
+
+	case Common::FR_FRA:
+		_lang = 1;
+		break;
+
+	case Common::DE_DEU:
+		_lang = 2;
+		break;
+
+	default:
+		warning("unsupported language, switching back to English");
+		_lang = 0;
+		break;
+	}
+	
+	_chargenWSA = 0;
+}
+
+LoLEngine::~LoLEngine() {
+	setupPrologueData(false);
+
+	delete _screen;
+	delete _tim;
+	
+	for (Common::Array<const TIMOpcode*>::iterator i = _timIntroOpcodes.begin(); i != _timIntroOpcodes.end(); ++i)
+		delete *i;
+	_timIntroOpcodes.clear();
+}
+
+Screen *LoLEngine::screen() {
+	return _screen;
+}
+
+int LoLEngine::init() {
+	_screen = new Screen_LoL(this, _system);
+	assert(_screen);
+	_screen->setResolution();
+
+	KyraEngine_v1::init();
+	
+	_tim = new TIMInterpreter(this, _screen, _system);
+	assert(_tim);
+	
+	_screen->setAnimBlockPtr(10000);
+	_screen->setScreenDim(0);
+
+	return 0;
+}
+
+int LoLEngine::go() {
+	setupPrologueData(true);
+	showIntro();
+	_sound->playTrack(6);
+	/*int character = */chooseCharacter();
+	_sound->playTrack(1);
+	_screen->fadeToBlack();
+	setupPrologueData(false);
+
+	return 0;
+}
+
+#pragma mark - Input
+
+int LoLEngine::checkInput(Button *buttonList, bool mainLoop) {
+	debugC(9, kDebugLevelMain, "LoLEngine::checkInput(%p, %d)", (const void*)buttonList, mainLoop);
+	updateInput();
+
+	int keys = 0;
+	int8 mouseWheel = 0;
+
+	while (_eventList.size()) {
+		Common::Event event = *_eventList.begin();
+		bool breakLoop = false;
+
+		switch (event.type) {
+		case Common::EVENT_KEYDOWN:
+			/*if (event.kbd.keycode >= '1' && event.kbd.keycode <= '9' &&
+					(event.kbd.flags == Common::KBD_CTRL || event.kbd.flags == Common::KBD_ALT) && mainLoop) {
+				const char *saveLoadSlot = getSavegameFilename(9 - (event.kbd.keycode - '0') + 990);
+
+				if (event.kbd.flags == Common::KBD_CTRL) {
+					loadGame(saveLoadSlot);
+					_eventList.clear();
+					breakLoop = true;
+				} else {
+					char savegameName[14];
+					sprintf(savegameName, "Quicksave %d", event.kbd.keycode - '0');
+					saveGame(saveLoadSlot, savegameName);
+				}
+			} else if (event.kbd.flags == Common::KBD_CTRL) {
+				if (event.kbd.keycode == 'd')
+					_debugger->attach();
+			}*/
+			break;
+
+		case Common::EVENT_MOUSEMOVE: {
+			Common::Point pos = getMousePos();
+			_mouseX = pos.x;
+			_mouseY = pos.y;
+			} break;
+
+		case Common::EVENT_LBUTTONDOWN:
+		case Common::EVENT_LBUTTONUP: {
+			Common::Point pos = getMousePos();
+			_mouseX = pos.x;
+			_mouseY = pos.y;
+			keys = (event.type == Common::EVENT_LBUTTONDOWN ? 199 : (200 | 0x800));
+			breakLoop = true;
+			} break;
+
+		case Common::EVENT_WHEELUP:
+			mouseWheel = -1;
+			break;
+
+		case Common::EVENT_WHEELDOWN:
+			mouseWheel = 1;
+			break;
+
+		default:
+			break;
+		}
+
+		//if (_debugger->isAttached())
+		//	_debugger->onFrame();
+
+		if (breakLoop)
+			break;
+
+		_eventList.erase(_eventList.begin());
+	}
+
+	return /*gui_v2()->processButtonList(buttonList, keys | 0x8000, mouseWheel)*/keys;
+}
+
+void LoLEngine::updateInput() {
+	Common::Event event;
+
+	while (_eventMan->pollEvent(event)) {
+		switch (event.type) {
+		case Common::EVENT_QUIT:
+			_quitFlag = true;
+			break;
+
+		case Common::EVENT_KEYDOWN:
+			if (event.kbd.keycode == '.' || event.kbd.keycode == Common::KEYCODE_ESCAPE)
+				_eventList.push_back(Event(event, true));
+			else if (event.kbd.keycode == 'q' && event.kbd.flags == Common::KBD_CTRL)
+				_quitFlag = true;
+			else
+				_eventList.push_back(event);
+			break;
+
+		case Common::EVENT_LBUTTONDOWN:
+			_eventList.push_back(Event(event, true));
+			break;
+
+		case Common::EVENT_MOUSEMOVE:
+			_screen->updateScreen();
+			// fall through
+
+		case Common::EVENT_LBUTTONUP:
+		case Common::EVENT_WHEELUP:
+		case Common::EVENT_WHEELDOWN:
+			_eventList.push_back(event);
+			break;
+
+		default:
+			break;
+		}
+	}
+}
+
+void LoLEngine::removeInputTop() {
+	if (!_eventList.empty())
+		_eventList.erase(_eventList.begin());
+}
+
+bool LoLEngine::skipFlag() const {
+	for (Common::List<Event>::const_iterator i = _eventList.begin(); i != _eventList.end(); ++i) {
+		if (i->causedSkip)
+			return true;
+	}
+	return false;
+}
+
+void LoLEngine::resetSkipFlag(bool removeEvent) {
+	for (Common::List<Event>::iterator i = _eventList.begin(); i != _eventList.end(); ++i) {
+		if (i->causedSkip) {
+			if (removeEvent)
+				_eventList.erase(i);
+			else
+				i->causedSkip = false;
+			return;
+		}
+	}
+}
+
+#pragma mark - Intro
+
+void LoLEngine::setupPrologueData(bool load) {
+	static const char * const fileList[] = {
+		"xxx/general.pak",
+		"xxx/introvoc.pak",
+		"xxx/startup.pak",
+		"xxx/intro1.pak",
+		"xxx/intro2.pak",
+		"xxx/intro3.pak",
+		"xxx/intro4.pak",
+		"xxx/intro5.pak",
+		"xxx/intro6.pak",
+		"xxx/intro7.pak",
+		"xxx/intro8.pak",
+		"xxx/intro9.pak"
+	};
+
+	char filename[32];
+	for (uint i = 0; i < ARRAYSIZE(fileList); ++i) {
+		strcpy(filename, fileList[i]);
+		memcpy(filename, _languageExt[_lang], 3);
+
+		if (load) {
+			if (!_res->loadPakFile(filename))
+				error("Couldn't load file: '%s'", filename);
+		} else {
+			_res->unloadPakFile(filename);
+		}
+	}
+	
+	if (load) {
+		_chargenWSA = new WSAMovie_v2(this, _screen);
+		assert(_chargenWSA);
+
+		_charSelection = -1;
+		_charSelectionInfoResult = -1;
+
+		_selectionAnimFrames[0] = _selectionAnimFrames[2] = 0;
+		_selectionAnimFrames[1] = _selectionAnimFrames[3] = 1;
+
+		memset(_selectionAnimTimers, 0, sizeof(_selectionAnimTimers));
+		memset(_screen->getPalette(1), 0, 768);
+	} else {
+		delete _chargenWSA; _chargenWSA = 0;
+	}
+}
+
+void LoLEngine::showIntro() {
+	debugC(9, kDebugLevelMain, "LoLEngine::showIntro()");
+
+	TIM *intro = _tim->load("LOLINTRO.TIM", &_timIntroOpcodes);
+
+	_screen->loadFont(Screen::FID_8_FNT, "NEW8P.FNT");
+	_screen->loadFont(Screen::FID_INTRO_FNT, "INTRO.FNT");
+	_screen->setFont(Screen::FID_8_FNT);
+
+	_tim->resetFinishedFlag();
+	_tim->setLangData("LOLINTRO.DIP");
+
+	_screen->hideMouse();
+
+	uint32 palNextFadeStep = 0;
+	while (!_tim->finished() && !_quitFlag && !skipFlag()) {
+		updateInput();
+		_tim->exec(intro, false);
+		_screen->checkedPageUpdate(8, 4);
+
+		if (_tim->_palDiff) {
+			if (palNextFadeStep < _system->getMillis()) {
+				_tim->_palDelayAcc += _tim->_palDelayInc;
+				palNextFadeStep = _system->getMillis() + ((_tim->_palDelayAcc >> 8) * _tickLength);
+				_tim->_palDelayAcc &= 0xFF;
+
+				if (!_screen->fadePalStep(_screen->getPalette(0), _tim->_palDiff)) {
+					_screen->setScreenPalette(_screen->getPalette(0));
+					_tim->_palDiff = 0;
+				}
+			}
+		}
+
+		_system->delayMillis(10);
+		_screen->updateScreen();
+	}
+	_screen->showMouse();
+	_sound->voiceStop();
+	
+	// HACK: Remove all input events
+	_eventList.clear();
+	
+	_tim->unload(intro);
+	_tim->clearLangData();
+	
+	_screen->fadePalette(_screen->getPalette(1), 30, 0);
+}
+
+int LoLEngine::chooseCharacter() {
+	debugC(9, kDebugLevelMain, "LoLEngine::chooseCharacter()");
+
+	_tim->setLangData("LOLINTRO.DIP");
+	
+	_screen->loadFont(Screen::FID_9_FNT, "FONT9P.FNT");
+
+	_screen->loadBitmap("ITEMICN.SHP", 3, 3, 0);
+	_screen->setMouseCursor(0, 0, _screen->getPtrToShape(_screen->getCPagePtr(3), 0));
+
+	while (!_screen->isMouseVisible())
+		_screen->showMouse();
+
+	_screen->loadBitmap("CHAR.CPS", 2, 2, _screen->getPalette(0));
+	_screen->loadBitmap("BACKGRND.CPS", 4, 4, _screen->getPalette(0));
+	
+	if (!_chargenWSA->open("CHARGEN.WSA", 1, 0))
+		error("Couldn't load CHARGEN.WSA");
+	_chargenWSA->setX(113);
+	_chargenWSA->setY(0);
+	_chargenWSA->setDrawPage(2);
+	_chargenWSA->displayFrame(0, 0, 0, 0);
+
+	_screen->setFont(Screen::FID_9_FNT);
+	_screen->_curPage = 2;
+	
+	for (int i = 0; i < 4; ++i)
+		_screen->fprintStringIntro(_charPreviews[i].name, _charPreviews[i].x + 16, _charPreviews[i].y + 36, 0xC0, 0x00, 0x9C, 0x120);
+
+	for (int i = 0; i < 4; ++i) {
+		_screen->fprintStringIntro("%d", _charPreviews[i].x + 21, _charPreviews[i].y + 48, 0x98, 0x00, 0x9C, 0x220, _charPreviews[i].attrib[0]);
+		_screen->fprintStringIntro("%d", _charPreviews[i].x + 21, _charPreviews[i].y + 56, 0x98, 0x00, 0x9C, 0x220, _charPreviews[i].attrib[1]);
+		_screen->fprintStringIntro("%d", _charPreviews[i].x + 21, _charPreviews[i].y + 64, 0x98, 0x00, 0x9C, 0x220, _charPreviews[i].attrib[2]);
+	}
+	
+	_screen->fprintStringIntro(_tim->getCTableEntry(51), 36, 173, 0x98, 0x00, 0x9C, 0x20);
+	_screen->fprintStringIntro(_tim->getCTableEntry(53), 36, 181, 0x98, 0x00, 0x9C, 0x20);
+	_screen->fprintStringIntro(_tim->getCTableEntry(55), 36, 189, 0x98, 0x00, 0x9C, 0x20);
+	
+	_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->_curPage = 0;
+	
+	_screen->fadePalette(_screen->getPalette(0), 30, 0);
+	
+	bool kingIntro = true;
+	while (!_quitFlag) {
+		if (kingIntro)
+			kingSelectionIntro();
+
+		if (_charSelection < 0)
+			processCharacterSelection();
+
+		if (_quitFlag)
+			break;
+
+		if (_charSelection == 100) {
+			kingIntro = true;
+			_charSelection = -1;
+			continue;
+		}
+
+		_screen->copyRegion(0, 0, 0, 0, 112, 120, 4, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		_screen->showMouse();
+
+		if (selectionCharInfo(_charSelection) == -1) {
+			_charSelection = -1;
+			kingIntro = false;
+		} else {
+			break;
+		}
+	}
+
+	if (_quitFlag)
+		return -1;
+
+	uint32 waitTime = _system->getMillis() + 420 * _tickLength;
+	while (waitTime > _system->getMillis() && !skipFlag() && !_quitFlag) {
+		updateInput();
+		_system->delayMillis(10);
+	}
+
+	// HACK: Remove all input events
+	_eventList.clear();
+
+	_tim->clearLangData();
+
+	return _charSelection;
+}
+
+void LoLEngine::kingSelectionIntro() {
+	debugC(9, kDebugLevelMain, "LoLEngine::kingSelectionIntro()");
+	
+	_screen->copyRegion(0, 0, 0, 0, 112, 120, 4, 0, Screen::CR_NO_P_CHECK);
+	int y = 38;
+	
+	_screen->fprintStringIntro(_tim->getCTableEntry(57), 8, y, 0x32, 0x00, 0x9C, 0x20);
+	_screen->fprintStringIntro(_tim->getCTableEntry(58), 8, y + 10, 0x32, 0x00, 0x9C, 0x20);
+	_screen->fprintStringIntro(_tim->getCTableEntry(59), 8, y + 20, 0x32, 0x00, 0x9C, 0x20);
+	_screen->fprintStringIntro(_tim->getCTableEntry(60), 8, y + 30, 0x32, 0x00, 0x9C, 0x20);
+	_screen->fprintStringIntro(_tim->getCTableEntry(61), 8, y + 40, 0x32, 0x00, 0x9C, 0x20);
+
+	_sound->voicePlay("KING01");
+	
+	_chargenWSA->setX(113);
+	_chargenWSA->setY(0);
+	_chargenWSA->setDrawPage(0);
+	
+	int index = 4;
+	while (_sound->voiceIsPlaying("KING01") && _charSelection == -1 && !_quitFlag && !skipFlag()) {
+		index = MAX(index, 4);
+
+		_chargenWSA->displayFrame(_chargenFrameTable[index], 0, 0, 0);
+		_screen->copyRegion(_selectionPosTable[_selectionChar1IdxTable[index]*2+0], _selectionPosTable[_selectionChar1IdxTable[index]*2+1], _charPreviews[0].x, _charPreviews[0].y, 32, 32, 4, 0);
+		_screen->copyRegion(_selectionPosTable[_selectionChar2IdxTable[index]*2+0], _selectionPosTable[_selectionChar2IdxTable[index]*2+1], _charPreviews[1].x, _charPreviews[1].y, 32, 32, 4, 0);
+		_screen->copyRegion(_selectionPosTable[_selectionChar3IdxTable[index]*2+0], _selectionPosTable[_selectionChar3IdxTable[index]*2+1], _charPreviews[2].x, _charPreviews[2].y, 32, 32, 4, 0);
+		_screen->copyRegion(_selectionPosTable[_selectionChar4IdxTable[index]*2+0], _selectionPosTable[_selectionChar4IdxTable[index]*2+1], _charPreviews[3].x, _charPreviews[3].y, 32, 32, 4, 0);
+		_screen->updateScreen();
+
+		uint32 waitEnd = _system->getMillis() + 7 * _tickLength;
+		while (waitEnd > _system->getMillis() && _charSelection == -1 && !_quitFlag && !skipFlag()) {
+			_charSelection = getCharSelection();
+			_system->delayMillis(10);
+		}
+
+		index = (index + 1) % 22;
+	}
+	
+	resetSkipFlag();
+	
+	_chargenWSA->displayFrame(0x10, 0, 0, 0);
+	_screen->updateScreen();
+	_sound->voiceStop("KING01");
+}
+
+void LoLEngine::kingSelectionReminder() {
+	debugC(9, kDebugLevelMain, "LoLEngine::kingSelectionReminder()");
+	
+	_screen->copyRegion(0, 0, 0, 0, 112, 120, 4, 0, Screen::CR_NO_P_CHECK);
+	int y = 48;
+	
+	_screen->fprintStringIntro(_tim->getCTableEntry(62), 8, y, 0x32, 0x00, 0x9C, 0x20);
+	_screen->fprintStringIntro(_tim->getCTableEntry(63), 8, y + 10, 0x32, 0x00, 0x9C, 0x20);
+	
+	_sound->voicePlay("KING02");
+	
+	_chargenWSA->setX(113);
+	_chargenWSA->setY(0);
+	_chargenWSA->setDrawPage(0);
+	
+	int index = 0;
+	while (_sound->voiceIsPlaying("KING02") && _charSelection == -1 && !_quitFlag && index < 15) {
+		_chargenWSA->displayFrame(_chargenFrameTable[index+9], 0, 0, 0);
+		_screen->copyRegion(_selectionPosTable[_reminderChar1IdxTable[index]*2+0], _selectionPosTable[_reminderChar1IdxTable[index]*2+1], _charPreviews[0].x, _charPreviews[0].y, 32, 32, 4, 0);
+		_screen->copyRegion(_selectionPosTable[_reminderChar2IdxTable[index]*2+0], _selectionPosTable[_reminderChar2IdxTable[index]*2+1], _charPreviews[1].x, _charPreviews[1].y, 32, 32, 4, 0);
+		_screen->copyRegion(_selectionPosTable[_reminderChar3IdxTable[index]*2+0], _selectionPosTable[_reminderChar3IdxTable[index]*2+1], _charPreviews[2].x, _charPreviews[2].y, 32, 32, 4, 0);
+		_screen->copyRegion(_selectionPosTable[_reminderChar4IdxTable[index]*2+0], _selectionPosTable[_reminderChar4IdxTable[index]*2+1], _charPreviews[3].x, _charPreviews[3].y, 32, 32, 4, 0);
+		_screen->updateScreen();
+
+		uint32 waitEnd = _system->getMillis() + 8 * _tickLength;
+		while (waitEnd > _system->getMillis() && !_quitFlag) {
+			_charSelection = getCharSelection();
+			_system->delayMillis(10);
+		}
+
+		index = (index + 1) % 22;
+	}
+
+	_sound->voiceStop("KING02");
+}
+
+void LoLEngine::kingSelectionOutro() {
+	debugC(9, kDebugLevelMain, "LoLEngine::kingSelectionOutro()");
+
+	_sound->voicePlay("KING03");
+
+	_chargenWSA->setX(113);
+	_chargenWSA->setY(0);
+	_chargenWSA->setDrawPage(0);
+
+	int index = 0;
+	while (_sound->voiceIsPlaying("KING03") && !_quitFlag && !skipFlag()) {
+		index = MAX(index, 4);
+
+		_chargenWSA->displayFrame(_chargenFrameTable[index], 0, 0, 0);
+		_screen->updateScreen();
+
+		uint32 waitEnd = _system->getMillis() + 8 * _tickLength;
+		while (waitEnd > _system->getMillis() && !_quitFlag && !skipFlag()) {
+			updateInput();
+			_system->delayMillis(10);
+		}
+
+		index = (index + 1) % 22;
+	}
+
+	resetSkipFlag();
+
+	_chargenWSA->displayFrame(0x10, 0, 0, 0);
+	_screen->updateScreen();
+	_sound->voiceStop("KING03");
+}
+
+void LoLEngine::processCharacterSelection() {
+	debugC(9, kDebugLevelMain, "LoLEngine::processCharacterSelection()");
+	
+	_charSelection = -1;
+	while (!_quitFlag && _charSelection == -1) {
+		uint32 nextKingMessage = _system->getMillis() + 900 * _tickLength;
+
+		while (nextKingMessage > _system->getMillis() && _charSelection == -1 && !_quitFlag) {
+			updateSelectionAnims();
+			_charSelection = getCharSelection();
+			_system->delayMillis(10);
+		}
+
+		if (_charSelection == -1)
+			kingSelectionReminder();
+	}
+}
+
+void LoLEngine::updateSelectionAnims() {
+	debugC(9, kDebugLevelMain, "LoLEngine::updateSelectionAnims()");
+
+	for (int i = 0; i < 4; ++i) {
+		if (_system->getMillis() < _selectionAnimTimers[i])
+			continue;
+
+		const int index = _selectionAnimIndexTable[_selectionAnimFrames[i] + i * 2];
+		_screen->copyRegion(_selectionPosTable[index*2+0], _selectionPosTable[index*2+1], _charPreviews[i].x, _charPreviews[i].y, 32, 32, 4, 0);
+
+		int delayTime = 0;
+		if (_selectionAnimFrames[i] == 1)
+			delayTime = _rnd.getRandomNumberRng(0, 31) + 80;
+		else
+			delayTime = _rnd.getRandomNumberRng(0, 3) + 10;
+
+		_selectionAnimTimers[i] = _system->getMillis() + delayTime * _tickLength;
+		_selectionAnimFrames[i] = (_selectionAnimFrames[i] + 1) % 2;
+	}
+
+	_screen->updateScreen();
+}
+
+int LoLEngine::selectionCharInfo(int character) {
+	debugC(9, kDebugLevelMain, "LoLEngine::selectionCharInfo(%d)", character);
+	if (character < 0)
+		return -1;
+
+	char filename[16];
+	char vocFilename[6];
+	strcpy(vocFilename, "000X0");
+
+	switch (character) {
+	case 0:
+		strcpy(filename, "face09.shp");
+		vocFilename[3] = 'A';
+		break;
+	
+	case 1:
+		strcpy(filename, "face01.shp");
+		vocFilename[3] = 'M';
+		break;
+	
+	case 2:
+		strcpy(filename, "face08.shp");
+		vocFilename[3] = 'K';
+		break;
+	
+	case 3:
+		strcpy(filename, "face05.shp");
+		vocFilename[3] = 'C';
+		break;
+	
+	default:
+		break;
+	};
+
+	_screen->loadBitmap(filename, 9, 9, 0);
+	_screen->copyRegion(0, 122, 0, 122, 320, 78, 4, 0, Screen::CR_NO_P_CHECK);
+	_screen->copyRegion(_charPreviews[character].x - 3, _charPreviews[character].y - 3, 8, 127, 38, 38, 2, 0);
+
+	static const uint8 charSelectInfoIdx[] = { 0x1D, 0x22, 0x27, 0x2C };
+	const int idx = charSelectInfoIdx[character];
+
+	_screen->fprintStringIntro(_tim->getCTableEntry(idx+0), 50, 127, 0x53, 0x00, 0xCF, 0x20);
+	_screen->fprintStringIntro(_tim->getCTableEntry(idx+1), 50, 137, 0x53, 0x00, 0xCF, 0x20);
+	_screen->fprintStringIntro(_tim->getCTableEntry(idx+2), 50, 147, 0x53, 0x00, 0xCF, 0x20);
+	_screen->fprintStringIntro(_tim->getCTableEntry(idx+3), 50, 157, 0x53, 0x00, 0xCF, 0x20);
+	_screen->fprintStringIntro(_tim->getCTableEntry(idx+4), 50, 167, 0x53, 0x00, 0xCF, 0x20);
+	
+	_screen->fprintStringIntro(_tim->getCTableEntry(69), 100, 168, 0x32, 0x00, 0xCF, 0x20);
+	
+	selectionCharInfoIntro(vocFilename);
+	if (_charSelectionInfoResult == -1) {
+		while (_charSelectionInfoResult == -1) {
+			_charSelectionInfoResult = selectionCharAccept();
+			_system->delayMillis(10);
+		}
+	}
+	
+	if (_charSelectionInfoResult != 1) {
+		_charSelectionInfoResult = -1;
+		_screen->copyRegion(0, 122, 0, 122, 320, 78, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		return -1;
+	}
+
+	_screen->copyRegion(48, 127, 48, 127, 272, 60, 4, 0, Screen::CR_NO_P_CHECK);
+	_screen->hideMouse();
+	_screen->copyRegion(48, 127, 48, 160, 272, 35, 4, 0, Screen::CR_NO_P_CHECK);
+	_screen->copyRegion(0, 0, 0, 0, 112, 120, 4, 0, Screen::CR_NO_P_CHECK);
+
+	_screen->fprintStringIntro(_tim->getCTableEntry(64), 3, 28, 0x32, 0x00, 0x9C, 0x20);
+	_screen->fprintStringIntro(_tim->getCTableEntry(65), 3, 38, 0x32, 0x00, 0x9C, 0x20);
+	_screen->fprintStringIntro(_tim->getCTableEntry(66), 3, 48, 0x32, 0x00, 0x9C, 0x20);
+	_screen->fprintStringIntro(_tim->getCTableEntry(67), 3, 58, 0x32, 0x00, 0x9C, 0x20);
+	_screen->fprintStringIntro(_tim->getCTableEntry(68), 3, 68, 0x32, 0x00, 0x9C, 0x20);
+
+	resetSkipFlag();
+	kingSelectionOutro();	
+	return character;
+}
+
+void LoLEngine::selectionCharInfoIntro(char *file) {
+	debugC(9, kDebugLevelMain, "LoLEngine::selectionCharInfoIntro(%p)", (const void *)file);
+	int index = 0;
+	file[4] = '0';
+	
+	while (_charSelectionInfoResult == -1 && !_quitFlag) {
+		if (!_sound->voicePlay(file))
+			break;
+
+		int i = 0;
+		while (_sound->voiceIsPlaying(file) && _charSelectionInfoResult == -1 && !_quitFlag) {
+			_screen->drawShape(0, _screen->getPtrToShape(_screen->getCPagePtr(9), _charInfoFrameTable[i]), 11, 130, 0, 0);
+			_screen->updateScreen();
+
+			uint32 nextFrame = _system->getMillis() + 8 * _tickLength;
+			while (nextFrame > _system->getMillis() && _charSelectionInfoResult == -1) {
+				_charSelectionInfoResult = selectionCharAccept();
+				_system->delayMillis(10);
+			}
+
+			i = (i + 1) % 32;
+		}
+
+		_sound->voiceStop(file);
+		file[4] = ++index + '0';
+	}
+
+	_screen->drawShape(0, _screen->getPtrToShape(_screen->getCPagePtr(9), 0), 11, 130, 0, 0);
+	_screen->updateScreen();
+}
+
+int LoLEngine::getCharSelection() {
+	int inputFlag = checkInput() & 0xCF;
+	removeInputTop();
+
+	if (inputFlag == 200) {
+		for (int i = 0; i < 4; ++i) {
+			if (_charPreviews[i].x <= _mouseX && _mouseX <= _charPreviews[i].x + 31 &&
+				_charPreviews[i].y <= _mouseY && _mouseY <= _charPreviews[i].y + 31)
+				return i;
+		}
+	}
+	
+	return -1;
+}
+
+int LoLEngine::selectionCharAccept() {
+	int inputFlag = checkInput() & 0xCF;
+	removeInputTop();
+	
+	if (inputFlag == 200) {
+		if (88 <= _mouseX && _mouseX <= 128 && 180 <= _mouseY && _mouseY <= 194)
+			return 1;
+		if (196 <= _mouseX && _mouseX <= 236 && 180 <= _mouseY && _mouseY <= 194)
+			return 0;
+	}
+	
+	return -1;
+}
+
+#pragma mark - Opcodes
+
+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 TIMOpcode*> *timTable = 0;
+
+	SetTimOpcodeTable(_timIntroOpcodes);
+	
+	// 0x00
+	OpcodeTim(tlol_setupPaletteFade);
+	OpcodeTimUnImpl();
+	OpcodeTim(tlol_loadPalette);
+	OpcodeTim(tlol_setupPaletteFadeEx);
+	
+	// 0x04
+	OpcodeTim(tlol_processWsaFrame);
+	OpcodeTim(tlol_displayText);
+	OpcodeTimUnImpl();
+	OpcodeTimUnImpl();
+}
+
+#pragma mark -
+
+int LoLEngine::tlol_setupPaletteFade(const TIM *tim, const uint16 *param) {
+	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::t2_playSoundEffect(%p, %p) (%d)", (const void*)tim, (const void*)param, param[0]);
+	_screen->getFadeParams(_screen->getPalette(0), param[0], _tim->_palDelayInc, _tim->_palDiff);
+	_tim->_palDelayAcc = 0;
+	return 1;
+}
+
+int LoLEngine::tlol_loadPalette(const TIM *tim, const uint16 *param) {
+	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_loadPalette(%p, %p) (%d)", (const void*)tim, (const void*)param, param[0]);
+	const char *palFile = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[0]<<1)));
+	_res->loadFileToBuf(palFile, _screen->getPalette(0), 768);
+	return 1;
+}
+
+int LoLEngine::tlol_setupPaletteFadeEx(const TIM *tim, const uint16 *param) {
+	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_setupPaletteFadeEx(%p, %p) (%d)", (const void*)tim, (const void*)param, param[0]);
+	memcpy(_screen->getPalette(0), _screen->getPalette(1), 768);
+
+	_screen->getFadeParams(_screen->getPalette(0), param[0], _tim->_palDelayInc, _tim->_palDiff);
+	_tim->_palDelayAcc = 0;
+	return 1;
+}
+
+int LoLEngine::tlol_processWsaFrame(const TIM *tim, const uint16 *param) {
+	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_processWsaFrame(%p, %p) (%d, %d, %d, %d, %d)",
+		(const void*)tim, (const void*)param, param[0], param[1], param[2], param[3], param[4]);
+	TIMInterpreter::Animation *anim = (TIMInterpreter::Animation *)tim->wsa[param[0]].anim;
+	const int frame = param[1];
+	const int x2 = param[2];
+	const int y2 = param[3];
+	const int factor = MAX<int>(0, (int16)param[4]);
+	
+	const int x1 = anim->x;
+	const int y1 = anim->y;
+	
+	int w1 = anim->wsa->width();
+	int h1 = anim->wsa->height();
+	int w2 = (w1 * factor) / 100;
+	int h2 = (h1 * factor) / 100;
+	
+	anim->wsa->setDrawPage(2);
+	anim->wsa->setX(x1);
+	anim->wsa->setY(y1);
+	anim->wsa->displayFrame(frame, anim->wsaCopyParams & 0xF0FF, 0, 0);
+	_screen->wsaFrameAnimationStep(x1, y1, x2, y2, w1, h1, w2, h2, 2, 8, 0);
+	_screen->checkedPageUpdate(8, 4);
+	_screen->updateScreen();
+
+	return 1;
+}
+
+int LoLEngine::tlol_displayText(const TIM *tim, const uint16 *param) {
+	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_displayText(%p, %p) (%d, %d)", (const void*)tim, (const void*)param, param[0], (int16)param[1]);
+	_tim->displayText(param[0], param[1]);
+	return 1;
+}
+
+} // end of namespace Kyra
+


Property changes on: scummvm/trunk/engines/kyra/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/lol.h
===================================================================
--- scummvm/trunk/engines/kyra/lol.h	                        (rev 0)
+++ scummvm/trunk/engines/kyra/lol.h	2008-07-31 10:47:15 UTC (rev 33463)
@@ -0,0 +1,155 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+ 
+#ifndef KYRA_LOL_H
+#define KYRA_LOL_H
+
+#include "kyra/kyra_v1.h"
+#include "kyra/script_tim.h"
+
+#include "common/list.h"
+
+namespace Kyra {
+
+class Screen_LoL;
+class WSAMovie_v2;
+struct Button;
+
+class LoLEngine : public KyraEngine_v1 {
+public:
+	LoLEngine(OSystem *system, const GameFlags &flags);
+	~LoLEngine();
+	
+	Screen *screen();
+private:
+	Screen_LoL *_screen;
+	TIMInterpreter *_tim;
+
+	int init();
+	int go();
+
+	// input
+	void updateInput();
+	int checkInput(Button *buttonList = 0, bool mainLoop = false);
+	void removeInputTop();
+
+	int _mouseX, _mouseY;
+
+	struct Event {
+		Common::Event event;
+		bool causedSkip;
+
+		Event() : event(), causedSkip(false) {}
+		Event(Common::Event e) : event(e), causedSkip(false) {}
+		Event(Common::Event e, bool skip) : event(e), causedSkip(skip) {}
+
+		operator Common::Event() const { return event; }
+	};
+	Common::List<Event> _eventList;
+
+	virtual bool skipFlag() const;
+	virtual void resetSkipFlag(bool removeEvent = true);
+
+	// intro
+	void setupPrologueData(bool load);
+
+	void showIntro();
+	
+	struct CharacterPrev {
+		const char *name;
+		int x, y;
+		int attrib[3];
+	};
+	
+	static const CharacterPrev _charPreviews[];
+
+	WSAMovie_v2 *_chargenWSA;
+	static const uint8 _chargenFrameTable[];
+	int chooseCharacter();
+
+	void kingSelectionIntro();
+	void kingSelectionReminder();
+	void kingSelectionOutro();
+	void processCharacterSelection();
+	void updateSelectionAnims();
+	int selectionCharInfo(int character);
+	void selectionCharInfoIntro(char *file);
+	
+	int getCharSelection();
+	int selectionCharAccept();
+	
+	int _charSelection;
+	int _charSelectionInfoResult;
+	
+	uint32 _selectionAnimTimers[4];
+	uint8 _selectionAnimFrames[4];
+	static const uint8 _selectionAnimIndexTable[];
+	
+	static const uint16 _selectionPosTable[];
+
+	static const uint8 _selectionChar1IdxTable[];
+	static const uint8 _selectionChar2IdxTable[];
+	static const uint8 _selectionChar3IdxTable[];
+	static const uint8 _selectionChar4IdxTable[];
+	
+	static const uint8 _reminderChar1IdxTable[];
+	static const uint8 _reminderChar2IdxTable[];
+	static const uint8 _reminderChar3IdxTable[];
+	static const uint8 _reminderChar4IdxTable[];
+	
+	static const uint8 _charInfoFrameTable[];
+
+	// timer
+	void setupTimers() {}
+
+	// sound
+	void snd_playVoiceFile(int) { /* XXX */ }
+
+	// opcode
+	void setupOpcodeTable();
+
+	Common::Array<const TIMOpcode*> _timIntroOpcodes;
+	int tlol_setupPaletteFade(const TIM *tim, const uint16 *param);
+	int tlol_loadPalette(const TIM *tim, const uint16 *param);
+	int tlol_setupPaletteFadeEx(const TIM *tim, const uint16 *param);
+	int tlol_processWsaFrame(const TIM *tim, const uint16 *param);
+	int tlol_displayText(const TIM *tim, const uint16 *param);
+	
+	// translation
+	int _lang;
+
+	static const char * const _languageExt[];
+	
+	// unneeded
+	void setWalkspeed(uint8) {}
+	void setHandItem(uint16) {}
+	void removeHandItem() {}
+	bool lineIsPassable(int, int) { return false; }
+};
+
+} // end of namespace Kyra
+
+#endif
+


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

Modified: scummvm/trunk/engines/kyra/module.mk
===================================================================
--- scummvm/trunk/engines/kyra/module.mk	2008-07-30 21:58:44 UTC (rev 33462)
+++ scummvm/trunk/engines/kyra/module.mk	2008-07-31 10:47:15 UTC (rev 33463)
@@ -21,6 +21,7 @@
 	kyra_v2.o \
 	kyra_hof.o \
 	kyra_mr.o \
+	lol.o \
 	resource.o \
 	saveload.o \
 	saveload_lok.o \
@@ -33,6 +34,7 @@
 	scene_mr.o \
 	screen.o \
 	screen_lok.o \
+	screen_lol.o \
 	screen_v2.o \
 	screen_hof.o \
 	screen_mr.o \

Modified: scummvm/trunk/engines/kyra/resource.cpp
===================================================================
--- scummvm/trunk/engines/kyra/resource.cpp	2008-07-30 21:58:44 UTC (rev 33462)
+++ scummvm/trunk/engines/kyra/resource.cpp	2008-07-31 10:47:15 UTC (rev 33463)
@@ -55,10 +55,12 @@
 	if (!dir.exists() || !dir.isDirectory())
 		error("invalid game path '%s'", dir.getPath().c_str());
 
-	if (!loadPakFile(StaticResource::staticDataFilename()) || !StaticResource::checkKyraDat()) {
-		Common::String errorMessage = "You're missing the '" + StaticResource::staticDataFilename() + "' file or it got corrupted, (re)get it from the ScummVM website";
-		_vm->GUIErrorMessage(errorMessage);
-		error(errorMessage.c_str());
+	if (_vm->game() != GI_LOL) {
+		if (!loadPakFile(StaticResource::staticDataFilename()) || !StaticResource::checkKyraDat()) {
+			Common::String errorMessage = "You're missing the '" + StaticResource::staticDataFilename() + "' file or it got corrupted, (re)get it from the ScummVM website";
+			_vm->GUIErrorMessage(errorMessage);
+			error(errorMessage.c_str());
+		}
 	}
 
 	if (_vm->game() == GI_KYRA1) {
@@ -99,6 +101,8 @@
 		loadFileList("FILEDATA.FDT");
 
 		return true;
+	} else if (_vm->game() == GI_LOL) {
+		return true;
 	}
 
 	FSList fslist;
@@ -1120,7 +1124,7 @@
 
 void FileExpander::generateTables(uint8 srcIndex, uint8 dstIndex, uint8 dstIndex2, int cnt) {
 	const uint8 *tbl1 = _tables[srcIndex];
-	const uint8 *tbl2 = _tables[dstIndex];
+	uint8 *tbl2 = _tables[dstIndex];
 	const uint8 *tbl3 = dstIndex2 == 0xff ? 0 : _tables[dstIndex2];
 
 	if (!cnt)
@@ -1185,7 +1189,7 @@
 		}		
 	}
 
-	memset((void*) tbl2, 0, 512);
+	memset(tbl2, 0, 512);
 
 	cnt--;
 	s = tbl1 + cnt;

Added: scummvm/trunk/engines/kyra/screen_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/screen_lol.cpp	                        (rev 0)
+++ scummvm/trunk/engines/kyra/screen_lol.cpp	2008-07-31 10:47:15 UTC (rev 33463)
@@ -0,0 +1,69 @@
+/* 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/screen_lol.h"
+#include "kyra/lol.h"
+
+namespace Kyra {
+
+Screen_LoL::Screen_LoL(LoLEngine *vm, OSystem *system) : Screen_v2(vm, system), _vm(vm) {
+}
+
+void Screen_LoL::setScreenDim(int dim) {
+	debugC(9, kDebugLevelScreen, "Screen_LoL::setScreenDim(%d)", dim);
+	assert(dim < _screenDimTableCount);
+	_curDim = &_screenDimTable[dim];
+}
+
+const ScreenDim *Screen_LoL::getScreenDim(int dim) {
+	debugC(9, kDebugLevelScreen, "Screen_LoL::getScreenDim(%d)", dim);
+	assert(dim < _screenDimTableCount);
+	return &_screenDimTable[dim];
+}
+
+void Screen_LoL::fprintStringIntro(const char *format, int x, int y, uint8 c1, uint8 c2, uint8 c3, uint16 flags, ...) {
+	debugC(9, kDebugLevelScreen, "Screen_LoL::fprintStringIntro('%s', %d, %d, %d, %d, %d, %d, ...)", format, x, y, c1, c2, c3, flags);
+	char buffer[400];
+
+	va_list args;
+	va_start(args, flags);
+	vsprintf(buffer, format, args);	
+	va_end(args);
+	
+	if ((flags & 0x0F00) == 0x100)
+		x -= getTextWidth(buffer) >> 1;
+	if ((flags & 0x0F00) == 0x200)
+		x -= getTextWidth(buffer);
+
+	if ((flags & 0x00F0) == 0x20) {
+		printText(buffer, x-1, y, c3, c2);
+		printText(buffer, x, y+1, c3, c2);
+	}
+
+	printText(buffer, x, y, c1, c2);
+}
+
+} // end of namespace Kyra
+


Property changes on: scummvm/trunk/engines/kyra/screen_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/screen_lol.h
===================================================================
--- scummvm/trunk/engines/kyra/screen_lol.h	                        (rev 0)
+++ scummvm/trunk/engines/kyra/screen_lol.h	2008-07-31 10:47:15 UTC (rev 33463)
@@ -0,0 +1,53 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef KYRA_SCREEN_LOL_H
+#define KYRA_SCREEN_LOL_H
+
+#include "kyra/screen_v2.h"
+
+namespace Kyra {
+
+class LoLEngine;
+
+class Screen_LoL : public Screen_v2 {
+public:
+	Screen_LoL(LoLEngine *vm, OSystem *system);
+	
+	void setScreenDim(int dim);
+	const ScreenDim *getScreenDim(int dim);
+
+	void fprintStringIntro(const char *format, int x, int y, uint8 c1, uint8 c2, uint8 c3, uint16 flags, ...);
+private:
+	LoLEngine *_vm;
+
+	static const ScreenDim _screenDimTable[];
+	static const int _screenDimTableCount;
+};
+
+} // end of namespace Kyra
+
+#endif
+


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

Modified: scummvm/trunk/engines/kyra/screen_v2.cpp
===================================================================
--- scummvm/trunk/engines/kyra/screen_v2.cpp	2008-07-30 21:58:44 UTC (rev 33462)
+++ scummvm/trunk/engines/kyra/screen_v2.cpp	2008-07-31 10:47:15 UTC (rev 33463)
@@ -485,5 +485,27 @@
 	return (w1 == -1) ? false : true;
 }
 
+void Screen_v2::checkedPageUpdate(int srcPage, int dstPage) {
+	debugC(9, kDebugLevelScreen, "Screen_v2::checkedPageUpdate(%d, %d)", srcPage, dstPage);
+	
+	const uint32 *src = (const uint32 *)getPagePtr(srcPage);
+	uint32 *dst = (uint32 *)getPagePtr(dstPage);
+	uint32 *page0 = (uint32 *)getPagePtr(0);
+	
+	bool updated = false;
+	
+	for (int y = 0; y < 200; ++y) {
+		for (int x = 0; x < 80; ++x, ++src, ++dst, ++page0) {
+			if (*src != *dst) {
+				updated = true;
+				*dst = *page0 = *src;
+			}
+		}
+	}
+
+	if (updated)
+		addDirtyRect(0, 0, 320, 200);
+}
+
 } // end of namespace Kyra
 

Modified: scummvm/trunk/engines/kyra/screen_v2.h
===================================================================
--- scummvm/trunk/engines/kyra/screen_v2.h	2008-07-30 21:58:44 UTC (rev 33462)
+++ scummvm/trunk/engines/kyra/screen_v2.h	2008-07-31 10:47:15 UTC (rev 33463)
@@ -40,6 +40,8 @@
 	void copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src,
 					int unk1, const uint8 *unkPtr1, const uint8 *unkPtr2);
 
+	void checkedPageUpdate(int srcPage, int dstPage);
+
 	// palette handling
 	uint8 *generateOverlay(const uint8 *palette, uint8 *buffer, int color, uint16 factor);
 	void applyOverlay(int x, int y, int w, int h, int pageNum, const uint8 *overlay);

Modified: scummvm/trunk/engines/kyra/script_tim.cpp
===================================================================
--- scummvm/trunk/engines/kyra/script_tim.cpp	2008-07-30 21:58:44 UTC (rev 33462)
+++ scummvm/trunk/engines/kyra/script_tim.cpp	2008-07-31 10:47:15 UTC (rev 33463)
@@ -26,12 +26,14 @@
 #include "kyra/script_tim.h"
 #include "kyra/script.h"
 #include "kyra/resource.h"
+#include "kyra/sound.h"
+#include "kyra/wsamovie.h"
 
 #include "common/endian.h"
 
 namespace Kyra {
 
-TIMInterpreter::TIMInterpreter(KyraEngine_v1 *vm, OSystem *system) : _vm(vm), _system(system), _currentTim(0) {
+TIMInterpreter::TIMInterpreter(KyraEngine_v1 *vm, Screen_v2 *screen, OSystem *system) : _vm(vm), _screen(screen), _system(system), _currentTim(0) {
 #define COMMAND(x) { &TIMInterpreter::x, #x }
 #define COMMAND_UNIMPL() { 0, 0 }
 #define cmd_return(n) cmd_return_##n
@@ -39,32 +41,32 @@
 		// 0x00
 		COMMAND(cmd_initFunc0),
 		COMMAND(cmd_stopCurFunc),
-		COMMAND_UNIMPL(),
-		COMMAND_UNIMPL(),
+		COMMAND(cmd_initWSA),
+		COMMAND(cmd_uninitWSA),
 		// 0x04
 		COMMAND(cmd_initFunc),
 		COMMAND(cmd_stopFunc),
+		COMMAND(cmd_wsaDisplayFrame),
 		COMMAND_UNIMPL(),
-		COMMAND_UNIMPL(),
 		// 0x08
+		COMMAND(cmd_loadVocFile),
+		COMMAND(cmd_unloadVocFile),
+		COMMAND(cmd_playVocFile),
 		COMMAND_UNIMPL(),
-		COMMAND_UNIMPL(),
-		COMMAND_UNIMPL(),
-		COMMAND_UNIMPL(),
 		// 0x0C
+		COMMAND(cmd_loadSoundFile),
+		COMMAND(cmd_return(1)),
+		COMMAND(cmd_playMusicTrack),
 		COMMAND_UNIMPL(),
-		COMMAND_UNIMPL(),
-		COMMAND_UNIMPL(),
-		COMMAND_UNIMPL(),
 		// 0x10
+		COMMAND(cmd_return(1)),
+		COMMAND(cmd_return(1)),
 		COMMAND_UNIMPL(),
 		COMMAND_UNIMPL(),
-		COMMAND_UNIMPL(),
-		COMMAND_UNIMPL(),
 		// 0x14
-		COMMAND_UNIMPL(),
-		COMMAND_UNIMPL(),
-		COMMAND_UNIMPL(),
+		COMMAND(cmd_setLoopIp),
+		COMMAND(cmd_continueLoop),
+		COMMAND(cmd_resetLoopIp),
 		COMMAND(cmd_resetAllRuntimes),
 		// 0x18
 		COMMAND(cmd_return(1)),
@@ -80,8 +82,21 @@
 
 	_commands = commandProcs;
 	_commandsSize = ARRAYSIZE(commandProcs);
+	
+	memset(&_animations, 0, sizeof(_animations));
+	_langData = 0;
+	_textDisplayed = false;
+	_textAreaBuffer = new uint8[320*40];
+	assert(_textAreaBuffer);
+	
+	_palDelayInc = _palDiff = _palDelayAcc = 0;
 }
 
+TIMInterpreter::~TIMInterpreter() {
+	delete[] _langData;
+	delete[] _textAreaBuffer;
+}
+
 TIM *TIMInterpreter::load(const char *filename, const Common::Array<const TIMOpcode*> *opcodes) {
 	if (!_vm->resource()->exists(filename))
 		return 0;
@@ -139,6 +154,11 @@
 	tim = 0;
 }
 
+void TIMInterpreter::setLangData(const char *filename) {
+	delete[] _langData;
+	_langData = _vm->resource()->fileData(filename, 0);
+}
+
 void TIMInterpreter::exec(TIM *tim, bool loop) {
 	if (!tim)
 		return;
@@ -175,6 +195,10 @@
 					_currentTim->procFunc = _currentFunc;
 					break;
 
+				case 22:
+					cur.loopIp = 0;
+					break;
+
 				default:
 					break;
 				}
@@ -201,6 +225,205 @@
 	}
 }
 
+void TIMInterpreter::displayText(uint16 textId, int16 flags) {
+	char *text = getTableEntry(textId);
+
+	if (_textDisplayed) {
+		_screen->copyBlockToPage(0, 0, 160, 320, 40, _textAreaBuffer);
+		_textDisplayed = false;
+	}
+
+	if (!text)
+		return;
+	if (!text[0])
+		return;
+
+	char filename[16];
+	memset(filename, 0, sizeof(filename));
+
+	if (text[0] == '$') {
+		const char *end = strchr(text+1, '$');
+		if (end)
+			memcpy(filename, text+1, end-1-text);
+	}
+
+	if (filename[0])
+		_vm->sound()->voicePlay(filename);
+
+	if (text[0] == '$')
+		text = strchr(text + 1, '$') + 1;
+
+	setupTextPalette((flags < 0) ? 1 : flags, 0);
+
+	if (flags < 0) {
+		static const uint8 colorMap[] = { 0x00, 0xF0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+		_screen->setFont(Screen::FID_8_FNT);
+		_screen->setTextColorMap(colorMap);
+		_screen->_charWidth = -2;
+	}
+
+	_screen->_charOffset = -4;
+	_screen->copyRegionToBuffer(0, 0, 160, 320, 40, _textAreaBuffer);
+	_textDisplayed = true;
+
+	char backupChar = 0;
+	char *str = text;
+	int heightAdd = 0;
+
+	while (str[0]) {
+		char *nextLine = strchr(str, '\r');
+
+		backupChar = 0;
+		if (nextLine) {
+			backupChar = nextLine[0];
+			nextLine[0] = '\0';
+		}
+
+		int width = _screen->getTextWidth(str);
+
+		if (flags >= 0)
+			_screen->printText(str, (320 - width) >> 1, 160 + heightAdd, 0xF0, 0x00);
+		else
+			_screen->printText(str, (320 - width) >> 1, 188, 0xF0, 0x00);
+
+		heightAdd += _screen->getFontHeight();
+		str += strlen(str);
+
+		if (backupChar) {
+			nextLine[0] = backupChar;
+			++str;
+		}
+	}
+
+	_screen->_charOffset = 0;
+
+	if (flags < 0) {
+		static const uint8 colorMap[] = { 0x00, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0x00, 0x00, 0x00, 0x00 };
+
+		_screen->setFont(Screen::FID_INTRO_FNT);
+		_screen->setTextColorMap(colorMap);
+		_screen->_charWidth = 0;
+	}
+}
+
+void TIMInterpreter::setupTextPalette(uint index, int fadePalette) {
+	static const uint16 palTable[] = {
+		0x00, 0x00, 0x00,
+		0x64, 0x64, 0x64,
+		0x61, 0x51, 0x30,
+		0x29, 0x48, 0x64,
+		0x00, 0x4B, 0x3B,
+		0x64, 0x1E, 0x1E,
+	};
+
+	for (int i = 0; i < 15; ++i) {
+		uint8 *palette = _screen->getPalette(0) + (240 + i) * 3;
+
+		uint8 c1 = (((15 - i) << 2) * palTable[index*3+0]) / 100;
+		uint8 c2 = (((15 - i) << 2) * palTable[index*3+1]) / 100;
+		uint8 c3 = (((15 - i) << 2) * palTable[index*3+2]) / 100;
+
+		palette[0] = c1;
+		palette[1] = c2;
+		palette[2] = c3;
+	}
+	
+	if (!fadePalette && !_palDiff) {
+		_screen->setScreenPalette(_screen->getPalette(0));
+	} else {
+		_screen->getFadeParams(_screen->getPalette(0), fadePalette, _palDelayInc, _palDiff);
+		_palDelayAcc = 0;
+	}
+}
+
+TIMInterpreter::Animation *TIMInterpreter::initAnimStruct(int index, const char *filename, int x, int y, int, int offscreenBuffer, uint16 wsaFlags) {
+	Animation *anim = &_animations[index];
+	anim->x = x;
+	anim->y = y;
+	anim->wsaCopyParams = wsaFlags;
+
+	uint16 wsaOpenFlags = ((wsaFlags & 0x10) != 0) ? 2 : 0;
+
+	char file[32];
+	snprintf(file, 32, "%s.WSA", filename);
+	
+	if (_vm->resource()->exists(file)) {
+		anim->wsa = new WSAMovie_v2(_vm, _screen);
+		assert(anim->wsa);
+
+		anim->wsa->open(file, wsaOpenFlags, (index == 1) ? _screen->getPalette(0) : 0);
+	}
+	
+	if (anim->wsa && anim->wsa->opened()) {
+		if (x == -1)
+			anim->x = x = 0;
+		if (y == -1)
+			anim->y = y = 0;
+
+		if (wsaFlags & 2) {
+			_screen->fadePalette(_screen->getPalette(1), 15, 0);
+			_screen->clearPage(8);
+			_screen->checkedPageUpdate(8, 4);
+			_screen->updateScreen();
+		}
+
+		if (wsaFlags & 4) {
+			snprintf(file, 32, "%s.CPS", filename);
+
+			if (_vm->resource()->exists(file)) {
+				_screen->loadBitmap(file, 3, 3, _screen->getPalette(0));
+				_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 8, Screen::CR_NO_P_CHECK);
+				_screen->checkedPageUpdate(8, 4);
+				_screen->updateScreen();
+			}
+
+			anim->wsa->setX(x);
+			anim->wsa->setY(y);
+			anim->wsa->setDrawPage(0);
+			anim->wsa->displayFrame(0, 0, 0, 0);
+		} 
+
+		if (wsaFlags & 2)
+			_screen->fadePalette(_screen->getPalette(0), 30, 0);
+	} else {
+		if (wsaFlags & 2) {
+			_screen->fadePalette(_screen->getPalette(1), 15, 0);
+			_screen->clearPage(8);
+			_screen->checkedPageUpdate(8, 4);
+			_screen->updateScreen();
+		}
+
+		snprintf(file, 32, "%s.CPS", filename);
+
+		if (_vm->resource()->exists(file)) {
+			_screen->loadBitmap(file, 3, 3, _screen->getPalette(0));
+			_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 8, Screen::CR_NO_P_CHECK);
+			_screen->checkedPageUpdate(8, 4);
+			_screen->updateScreen();
+		}
+
+		if (wsaFlags & 2)
+			_screen->fadePalette(_screen->getPalette(0), 30, 0);
+	}
+	
+	return anim;
+}
+
+char *TIMInterpreter::getTableEntry(uint idx) {
+	if (!_langData)
+		return 0;
+	else
+		return (char *)(_langData + READ_LE_UINT16(_langData + (idx<<1)));
+}
+
+const char *TIMInterpreter::getCTableEntry(uint idx) const {
+	if (!_langData)
+		return 0;
+	else
+		return (const char *)(_langData + READ_LE_UINT16(_langData + (idx<<1)));
+}
+
 int TIMInterpreter::execCommand(int cmd, const uint16 *param) {
 	if (cmd < 0 || cmd >= _commandsSize) {
 		warning("Calling unimplemented TIM command %d from file '%s'", cmd, _currentTim->filename);
@@ -212,11 +435,14 @@
 		return 0;
 	}
 
-	debugC(5, kDebugLevelScript, "TIMInterpreter::%s(%p)", _commands[cmd].desc, (const void*)param);
+	debugC(5, kDebugLevelScript, "TIMInterpreter::%s(%p)", _commands[cmd].desc, (const void* )param);
 	return (this->*_commands[cmd].proc)(param);
 }
 
 int TIMInterpreter::cmd_initFunc0(const uint16 *param) {
+	for (int i = 0; i < TIM::kWSASlots; ++i)
+		memset(&_currentTim->wsa[i], 0, sizeof(TIM::WSASlot));
+
 	_currentTim->func[0].ip = _currentTim->func[0].avtl;
 	_currentTim->func[0].lastTime = _system->getMillis();
 	return 1;
@@ -230,6 +456,46 @@
 	return -2;
 }
 
+int TIMInterpreter::cmd_initWSA(const uint16 *param) {
+	const int index = param[0];
+
+	TIM::WSASlot &slot = _currentTim->wsa[index];
+	
+	slot.x = int16(param[2]);
+	slot.y = int16(param[3]);
+	slot.offscreen = param[4];
+	slot.wsaFlags = param[5];
+	const char *filename = (const char *)(_currentTim->text + READ_LE_UINT16(_currentTim->text + (param[1]<<1)));
+	
+	slot.anim = initAnimStruct(index, filename, slot.x, slot.y, 10, slot.offscreen, slot.wsaFlags);
+	return 1;
+}
+
+int TIMInterpreter::cmd_uninitWSA(const uint16 *param) {
+	const int index = param[0];
+
+	TIM::WSASlot &slot = _currentTim->wsa[index];
+	
+	if (!slot.anim)
+		return 0;
+	
+	Animation &anim = _animations[index];
+	
+	if (slot.offscreen) {
+		delete anim.wsa;
+		anim.wsa = 0;
+		slot.anim = 0;
+	} else {
+		//XXX
+
+		delete anim.wsa;
+		memset(&anim, 0, sizeof(Animation));
+		memset(&slot, 0, sizeof(TIM::WSASlot));
+	}
+	
+	return 1;
+}
+
 int TIMInterpreter::cmd_initFunc(const uint16 *param) {
 	uint16 func = *param;
 	assert(func < TIM::kCountFuncs);
@@ -247,6 +513,97 @@
 	return 1;
 }
 
+int TIMInterpreter::cmd_wsaDisplayFrame(const uint16 *param) {
+	Animation &anim = _animations[param[0]];
+	const int frame = param[1];
+	
+	anim.wsa->setX(anim.x);
+	anim.wsa->setY(anim.y);
+	anim.wsa->setDrawPage((anim.wsaCopyParams & 0x4000) != 0 ? 2 : 8);
+	anim.wsa->displayFrame(frame, anim.wsaCopyParams & 0xF0FF, 0, 0);
+	return 1;
+}
+
+int TIMInterpreter::cmd_displayText(const uint16 *param) {
+	displayText(param[0], param[1]);
+	return 1;
+}
+
+int TIMInterpreter::cmd_loadVocFile(const uint16 *param) {
+	const int stringId = param[0];
+	const int index = param[1];
+
+	_vocFiles[index] = (const char *)(_currentTim->text + READ_LE_UINT16(_currentTim->text + (stringId << 1)));
+	for (int i = 0; i < 4; ++i)
+		_vocFiles[index].deleteLastChar();
+	return 1;
+}
+
+int TIMInterpreter::cmd_unloadVocFile(const uint16 *param) {
+	const int index = param[0];
+	_vocFiles[index].clear();
+	return 1;
+}
+
+int TIMInterpreter::cmd_playVocFile(const uint16 *param) {
+	const int index = param[0];
+	const int volume = (param[1] * 255) / 100;
+
+	if (index < ARRAYSIZE(_vocFiles) && !_vocFiles[index].empty())
+		_vm->sound()->voicePlay(_vocFiles[index].c_str()/*, volume*/, true);
+	else
+		_vm->snd_playSoundEffect(index, volume);
+	
+	return 1;
+}
+
+int TIMInterpreter::cmd_loadSoundFile(const uint16 *param) {
+	const char *file = (const char *)(_currentTim->text + READ_LE_UINT16(_currentTim->text + (param[0]<<1)));
+	
+	static char * fileList[] = { 0 };
+	fileList[0] = _audioFilename;
+	static AudioDataStruct audioList = { fileList, 1, 0, 0 };
+
+	strncpy(_audioFilename, file, sizeof(_audioFilename));
+
+	_vm->sound()->setSoundList(&audioList);
+	_vm->sound()->loadSoundFile(0);
+	return 1;
+}
+
+int TIMInterpreter::cmd_playMusicTrack(const uint16 *param) {
+	_vm->sound()->playTrack(param[0]);
+	return 1;
+}
+
+int TIMInterpreter::cmd_setLoopIp(const uint16 *param) {
+	_currentTim->func[_currentFunc].loopIp = _currentTim->func[_currentFunc].ip;
+	return 1;
+}
+
+int TIMInterpreter::cmd_continueLoop(const uint16 *param) {
+	TIM::Function &func = _currentTim->func[_currentFunc];
+	
+	if (!func.loopIp)
+		return -2;
+
+	func.ip = func.loopIp;
+
+	uint16 factor = param[0];
+	if (factor) {
+		const uint32 random = _vm->_rnd.getRandomNumberRng(0, 0x8000);
+		uint32 waitTime = (random * factor) / 0x8000;
+		func.nextTime += waitTime * _vm->tickLength();
+	}
+	
+	return 1;
+}
+
+int TIMInterpreter::cmd_resetLoopIp(const uint16 *param) {
+	_currentTim->func[_currentFunc].loopIp = 0;
+	return 1;
+}
+
 int TIMInterpreter::cmd_resetAllRuntimes(const uint16 *param) {
 	for (int i = 0; i < TIM::kCountFuncs; ++i) {
 		if (_currentTim->func[i].ip)
@@ -256,17 +613,25 @@
 }
 
 int TIMInterpreter::cmd_execOpcode(const uint16 *param) {
+	const uint16 opcode = *param++;
+
 	if (!_currentTim->opcodes) {
-		warning("Trying to execute TIM opcode without opcode list");
+		warning("Trying to execute TIM opcode %d without opcode list (file '%s')", opcode, _currentTim->filename);
+		fflush(stderr); fflush(stdout);
 		return 0;
 	}
 
-	uint16 opcode = *param++;
 	if (opcode > _currentTim->opcodes->size()) {
 		warning("Calling unimplemented TIM opcode(0x%.02X/%d) from file '%s'", opcode, opcode, _currentTim->filename);
 		return 0;
 	}
 
+	if (!(*_currentTim->opcodes)[opcode]->isValid()) {
+		warning("Calling unimplemented TIM opcode(0x%.02X/%d) from file '%s'", opcode, opcode, _currentTim->filename);
+		fflush(stderr);
+		return 0;
+	}
+
 	return (*(*_currentTim->opcodes)[opcode])(_currentTim, param);
 }
 

Modified: scummvm/trunk/engines/kyra/script_tim.h
===================================================================
--- scummvm/trunk/engines/kyra/script_tim.h	2008-07-30 21:58:44 UTC (rev 33462)
+++ scummvm/trunk/engines/kyra/script_tim.h	2008-07-31 10:47:15 UTC (rev 33463)
@@ -30,9 +30,12 @@
 
 #include "common/array.h"
 #include "common/func.h"
+#include "common/str.h"
 
 namespace Kyra {
 
+class WSAMovie_v2;
+class Screen_v2;
 struct TIM;
 typedef Common::Functor2<const TIM*, const uint16*, int> TIMOpcode;
 
@@ -52,9 +55,23 @@
 		uint32 lastTime;
 		uint32 nextTime;
 
+		const uint16 *loopIp;
+
 		const uint16 *avtl;
 	} func[kCountFuncs];
 
+	enum {
+		kWSASlots = 10
+	};
+
+	struct WSASlot {
+		void *anim;
+
+		int16 x, y;
+		uint16 wsaFlags;
+		uint16 offscreen;
+	} wsa[kWSASlots];
+
 	uint16 *avtl;
 	uint8 *text;
 
@@ -63,10 +80,22 @@
 
 class TIMInterpreter {
 public:
-	TIMInterpreter(KyraEngine_v1 *vm, OSystem *system);
+	struct Animation {
+		WSAMovie_v2 *wsa;
+		int16 x, y;
+		uint16 wsaCopyParams;
+	};
 
+	TIMInterpreter(KyraEngine_v1 *vm, Screen_v2 *screen, OSystem *system);
+	~TIMInterpreter();
+
 	TIM *load(const char *filename, const Common::Array<const TIMOpcode*> *opcodes);
 	void unload(TIM *&tim) const;
+	
+	void setLangData(const char *filename);
+	void clearLangData() { delete[] _langData; _langData = 0; }
+	
+	const char *getCTableEntry(uint idx) const;
 
 	void resetFinishedFlag() { _finished = false; }
 	bool finished() const { return _finished; }
@@ -74,10 +103,15 @@
 	void exec(TIM *tim, bool loop);
 	void stopCurFunc() { if (_currentTim) cmd_stopCurFunc(0); }
 
-	void play(const char *filename);
 	void refreshTimersAfterPause(uint32 elapsedTime);
+	
+	void displayText(uint16 textId, int16 flags);
+	void setupTextPalette(uint index, int fadePalette);
+
+	int _palDelayInc, _palDiff, _palDelayAcc;
 private:
 	KyraEngine_v1 *_vm;
+	Screen_v2 *_screen;
 	OSystem *_system;
 
 	TIM *_currentTim;
@@ -85,6 +119,19 @@
 
 	bool _finished;
 	
+	Common::String _vocFiles[120];
+	
+	Animation _animations[TIM::kWSASlots];
+	
+	Animation *initAnimStruct(int index, const char *filename, int x, int y, int, int offscreenBuffer, uint16 wsaFlags);
+	
+	char _audioFilename[32];
+	
+	uint8 *_langData;
+	char *getTableEntry(uint idx);
+	bool _textDisplayed;
+	uint8 *_textAreaBuffer;
+
 	int execCommand(int cmd, const uint16 *param);
 
 	typedef int (TIMInterpreter::*CommandProc)(const uint16 *);
@@ -98,8 +145,20 @@
 
 	int cmd_initFunc0(const uint16 *param);
 	int cmd_stopCurFunc(const uint16 *param);
+	int cmd_initWSA(const uint16 *param);
+	int cmd_uninitWSA(const uint16 *param);
 	int cmd_initFunc(const uint16 *param);
 	int cmd_stopFunc(const uint16 *param);
+	int cmd_wsaDisplayFrame(const uint16 *param);
+	int cmd_displayText(const uint16 *param);
+	int cmd_loadVocFile(const uint16 *param);
+	int cmd_unloadVocFile(const uint16 *param);
+	int cmd_playVocFile(const uint16 *param);
+	int cmd_loadSoundFile(const uint16 *param);
+	int cmd_playMusicTrack(const uint16 *param);
+	int cmd_setLoopIp(const uint16 *param);
+	int cmd_continueLoop(const uint16 *param);
+	int cmd_resetLoopIp(const uint16 *param);
 	int cmd_resetAllRuntimes(const uint16 *param);
 	int cmd_execOpcode(const uint16 *param);
 	int cmd_initFuncNow(const uint16 *param);

Modified: scummvm/trunk/engines/kyra/sound_adlib.cpp
===================================================================
--- scummvm/trunk/engines/kyra/sound_adlib.cpp	2008-07-30 21:58:44 UTC (rev 33462)
+++ scummvm/trunk/engines/kyra/sound_adlib.cpp	2008-07-31 10:47:15 UTC (rev 33463)
@@ -235,6 +235,10 @@
 	// * One for instruments, starting at offset 500.
 
 	uint8 *getProgram(int progId) {
+		uint16 offset = READ_LE_UINT16(_soundData + 2 * progId);
+		//TODO: Check in LoL CD Adlib driver
+		if (offset == 0xFFFF)
+			return 0;
 		return _soundData + READ_LE_UINT16(_soundData + 2 * progId);
 	}
 
@@ -1282,6 +1286,9 @@
 		return 0;
 
 	uint8 *ptr = getProgram(value);
+	//TODO: Check in LoL CD Adlib driver
+	if (!ptr)
+		return 0;
 	uint8 chan = *ptr++;
 	uint8 priority = *ptr++;
 
@@ -2213,7 +2220,7 @@
 SoundAdlibPC::SoundAdlibPC(KyraEngine_v1 *vm, Audio::Mixer *mixer)
 	: Sound(vm, mixer), _driver(0), _trackEntries(), _soundDataPtr(0) {
 	memset(_trackEntries, 0, sizeof(_trackEntries));
-	_v2 = (_vm->gameFlags().gameID == GI_KYRA2);
+	_v2 = (_vm->gameFlags().gameID == GI_KYRA2) || (_vm->gameFlags().gameID == GI_LOL);
 	_driver = new AdlibDriver(mixer, _v2);
 	assert(_driver);
 

Modified: scummvm/trunk/engines/kyra/staticres.cpp
===================================================================
--- scummvm/trunk/engines/kyra/staticres.cpp	2008-07-30 21:58:44 UTC (rev 33462)
+++ scummvm/trunk/engines/kyra/staticres.cpp	2008-07-31 10:47:15 UTC (rev 33463)
@@ -23,16 +23,17 @@
  *
  */
 
-
 #include "common/endian.h"
 #include "common/md5.h"
 #include "kyra/kyra_v1.h"
 #include "kyra/kyra_lok.h"
+#include "kyra/lol.h"
 #include "kyra/kyra_v2.h"
 #include "kyra/kyra_hof.h"
 #include "kyra/kyra_mr.h"
 #include "kyra/screen.h"
 #include "kyra/screen_lok.h"
+#include "kyra/screen_lol.h"
 #include "kyra/screen_hof.h"
 #include "kyra/screen_mr.h"
 #include "kyra/resource.h"
@@ -287,8 +288,10 @@
 	} else if (_vm->game() == GI_KYRA3) {
 		_builtIn = 0;
 		_filenameTable = kyra3StaticRes;
+	} else if (_vm->game() == GI_LOL) {
+		return true;
 	} else {
-		error("unknown game ID");
+		error("StaticResource: Unknown game ID");
 	}
 
 	char errorBuffer[100];
@@ -2236,5 +2239,105 @@
 	-1, -2, 2, 2, -6, -6, -6, 0
 };
 
+// lands of lore static res
+
+const ScreenDim Screen_LoL::_screenDimTable[] = {
+	{ 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 }
+};
+
+const int Screen_LoL::_screenDimTableCount = ARRAYSIZE(Screen_LoL::_screenDimTable);
+
+const char * const LoLEngine::_languageExt[] = {
+	"ENG",
+	"FRE",
+	"GER"
+};
+
+const LoLEngine::CharacterPrev LoLEngine::_charPreviews[] = {
+	{ "Ak\'shel", 0x060, 0x7F, { 0x0F, 0x08, 0x05 } },
+	{  "Michael", 0x09A, 0x7F, { 0x06, 0x0A, 0x0F } },
+	{   "Kieran", 0x0D4, 0x7F, { 0x08, 0x06, 0x08 } },
+	{   "Conrad", 0x10F, 0x7F, { 0x0A, 0x0C, 0x0A } }
+};
+
+const uint8 LoLEngine::_chargenFrameTable[] = {
+	0x00, 0x01, 0x02, 0x03, 0x04,
+	0x05, 0x04, 0x03, 0x02, 0x01,
+	0x00, 0x00, 0x01, 0x02, 0x03,
+	0x04, 0x05, 0x06, 0x07, 0x08,
+	0x09, 0x0A, 0x0B, 0x0C, 0x0D,
+	0x0E, 0x0F, 0x10, 0x11, 0x12
+};
+
+const uint16 LoLEngine::_selectionPosTable[] = {
+	0x6F, 0x00, 0x8F, 0x00, 0xAF, 0x00,  0xCF, 0x00,
+	0xEF, 0x00, 0x6F, 0x20, 0x8F, 0x20,  0xAF, 0x20,
+	0xCF, 0x20, 0xEF, 0x20, 0x6F, 0x40,  0x8F, 0x40,
+	0xAF, 0x40, 0xCF, 0x40, 0xEF, 0x40, 0x10F, 0x00
+};
+
+const uint8 LoLEngine::_selectionChar1IdxTable[] = {
+	0, 0, 5, 5, 5, 5, 5, 5,
+	5, 5, 5, 0, 0, 5, 5, 5,
+	5, 5, 5, 5, 0, 0, 5, 5,
+	5, 5, 5
+};
+
+const uint8 LoLEngine::_selectionChar2IdxTable[] = {
+	1, 1, 6, 6, 1, 1, 6, 6,
+	6, 6, 6, 6, 6, 1, 1, 6,
+	6, 6, 1, 1, 6, 6, 6, 6,
+	6, 6, 6
+};
+
+const uint8 LoLEngine::_selectionChar3IdxTable[] = {
+	2, 2, 7, 7, 7, 7, 2, 2,
+	7, 7, 7, 7, 7, 7, 7, 2,
+	2, 7, 7, 7, 7, 2, 2, 7,
+	7, 7, 7
+};
+
+const uint8 LoLEngine::_selectionChar4IdxTable[] = {
+	3, 3, 8, 8, 8, 8, 3, 3,
+	8, 8, 3, 3, 8, 8, 8, 8,
+	8, 8, 8, 8, 8, 3, 3, 8,
+	8, 8, 8
+};
+
+const uint8 LoLEngine::_reminderChar1IdxTable[] = {
+	4, 4, 4, 5, 5, 5, 5, 5,
+	5, 5, 5, 5, 5, 5, 5, 5,
+	5
+};
+
+const uint8 LoLEngine::_reminderChar2IdxTable[] = {
+	9, 9, 9, 6, 6, 6, 6, 6,
+	6, 6, 6, 6, 6, 6, 6, 6,
+	6
+};
+
+const uint8 LoLEngine::_reminderChar3IdxTable[] = {
+	0xE, 0xE, 0xE, 0x7, 0x7, 0x7, 0x7, 0x7,
+	0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
+	0x7
+};
+
+const uint8 LoLEngine::_reminderChar4IdxTable[] = {
+	0xF, 0xF, 0xF, 0x8, 0x8, 0x8, 0x8, 0x8,
+	0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
+	0x8
+};
+
+const uint8 LoLEngine::_selectionAnimIndexTable[] = {
+	0, 5, 1, 6, 2, 7, 3, 8
+};
+
+const uint8 LoLEngine::_charInfoFrameTable[] = {
+	0x0, 0x7, 0x8, 0x9, 0xA, 0xB, 0xA, 0x9,
+	0x8, 0x7, 0x0, 0x0, 0x7, 0x8, 0x9, 0xA,
+	0xB, 0xA, 0x9, 0x8, 0x7, 0x0, 0x0, 0x7,
+	0x8, 0x9, 0xA, 0xB, 0xA, 0x9, 0x8, 0x7
+};
+
 } // End of namespace Kyra
 


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