diff options
| -rw-r--r-- | engines/kyra/gui.cpp | 19 | ||||
| -rw-r--r-- | engines/kyra/gui.h | 9 | ||||
| -rw-r--r-- | engines/kyra/kyra_hof.cpp | 63 | ||||
| -rw-r--r-- | engines/kyra/kyra_hof.h | 2 | ||||
| -rw-r--r-- | engines/kyra/kyra_mr.cpp | 6 | ||||
| -rw-r--r-- | engines/kyra/lol.cpp | 211 | ||||
| -rw-r--r-- | engines/kyra/lol.h | 18 | ||||
| -rw-r--r-- | engines/kyra/module.mk | 1 | ||||
| -rw-r--r-- | engines/kyra/sequences_hof.cpp | 6 | ||||
| -rw-r--r-- | engines/kyra/staticres.cpp | 14 | 
10 files changed, 260 insertions, 89 deletions
| diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp index b316d727bd..f03f028b98 100644 --- a/engines/kyra/gui.cpp +++ b/engines/kyra/gui.cpp @@ -441,10 +441,11 @@ int MainMenu::handle(int dim) {  	memset(colorMap, 0, sizeof(colorMap));  	_screen->setTextColorMap(colorMap); -	Screen::FontId oldFont = _screen->setFont(Screen::FID_8_FNT); +	Screen::FontId oldFont = _screen->setFont(_static.font);  	int charWidthBackUp = _screen->_charWidth; -	_screen->_charWidth = -2; +	if (_vm->game() != GI_LOL) +		_screen->_charWidth = -2;  	_screen->setScreenDim(dim);  	while (!_screen->isMouseVisible()) @@ -473,7 +474,7 @@ int MainMenu::handle(int dim) {  	int fh = _screen->getFontHeight();  	int textPos = ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3; -	Common::Rect menuRect(x + 16, y + 4, x + width - 16, y + 4 + fh * 4); +	Common::Rect menuRect(x + 16, y + 4, x + width - 16, y + 4 + fh * _static.menuTable[3]);  	while (!_vm->shouldQuit()) {  		updateAnimation(); @@ -484,18 +485,18 @@ int MainMenu::handle(int dim) {  			int item = (mouse.y - menuRect.top) / fh;  			if (item != selected) { -				printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.colorNormal, 0, 5); -				printString(_static.strings[item], textPos, menuRect.top + item * fh, _static.colorFlash, 0, 5); +				printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.menuTable[5], 0, 5); +				printString(_static.strings[item], textPos, menuRect.top + item * fh, _static.menuTable[6], 0, 5);  				selected = item;  			}  			if (mousePressed) {  				for (int i = 0; i < 3; i++) { -					printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.colorNormal, 0, 5); +					printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.menuTable[5], 0, 5);  					_screen->updateScreen();  					_system->delayMillis(50); -					printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.colorFlash, 0, 5); +					printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.menuTable[6], 0, 5);  					_screen->updateScreen();  					_system->delayMillis(50);  				} @@ -562,8 +563,8 @@ void MainMenu::printString(const char *format, int x, int y, int col1, int col2,  		x -= _screen->getTextWidth(string);  	if (flags & 4) { -		_screen->printText(string, x - 1, y, 240, col2); -		_screen->printText(string, x, y + 1, 240, col2); +		_screen->printText(string, x - 1, y, _static.altColor, col2); +		_screen->printText(string, x, y + 1, _static.altColor, col2);  	}  	if (flags & 8) { diff --git a/engines/kyra/gui.h b/engines/kyra/gui.h index 8115d91e7a..2ee764bfbe 100644 --- a/engines/kyra/gui.h +++ b/engines/kyra/gui.h @@ -27,6 +27,7 @@  #define KYRA_GUI_H  #include "kyra/kyra_v1.h" +#include "kyra/screen.h"  #include "common/ptr.h"  #include "common/array.h" @@ -217,11 +218,13 @@ public:  	};  	struct StaticData { -		const char *strings[4]; +		const char *strings[5]; -		uint8 menuTable[11]; +		uint8 menuTable[7];  		uint8 colorTable[4]; -		uint8 colorNormal, colorFlash; + +		Screen::FontId font; +		uint8 altColor;  	};  	void init(StaticData data, Animation anim); diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp index efe3394885..316e341a14 100644 --- a/engines/kyra/kyra_hof.cpp +++ b/engines/kyra/kyra_hof.cpp @@ -34,6 +34,7 @@  #include "kyra/text_hof.h"  #include "kyra/timer.h"  #include "kyra/debugger.h" +#include "kyra/util.h"  #include "common/system.h"  #include "common/config-manager.h" @@ -888,8 +889,8 @@ char *KyraEngine_HoF::getTableString(int id, uint8 *buffer, int decode) {  	char *string = (char*)getTableEntry(buffer, id);  	if (decode && _flags.lang != Common::JA_JPN) { -		decodeString1(string, _internStringBuf); -		decodeString2(_internStringBuf, _internStringBuf); +		Util::decodeString1(string, _internStringBuf); +		Util::decodeString2(_internStringBuf, _internStringBuf);  		string = _internStringBuf;  	} @@ -903,64 +904,6 @@ const char *KyraEngine_HoF::getChapterString(int id) {  	return getTableString(id, _chapterBuffer, 1);  } -int KyraEngine_HoF::decodeString1(const char *src, char *dst) { -	static const uint8 decodeTable1[] = { -		0x20, 0x65, 0x74, 0x61, 0x69, 0x6E, 0x6F, 0x73, 0x72, 0x6C, 0x68, -		0x63, 0x64, 0x75, 0x70, 0x6D -	}; - -	static const uint8 decodeTable2[] = { -		0x74, 0x61, 0x73, 0x69, 0x6F, 0x20, 0x77, 0x62, 0x20, 0x72, 0x6E, -		0x73, 0x64, 0x61, 0x6C, 0x6D, 0x68, 0x20, 0x69, 0x65, 0x6F, 0x72, -		0x61, 0x73, 0x6E, 0x72, 0x74, 0x6C, 0x63, 0x20, 0x73, 0x79, 0x6E, -		0x73, 0x74, 0x63, 0x6C, 0x6F, 0x65, 0x72, 0x20, 0x64, 0x74, 0x67, -		0x65, 0x73, 0x69, 0x6F, 0x6E, 0x72, 0x20, 0x75, 0x66, 0x6D, 0x73, -		0x77, 0x20, 0x74, 0x65, 0x70, 0x2E, 0x69, 0x63, 0x61, 0x65, 0x20, -		0x6F, 0x69, 0x61, 0x64, 0x75, 0x72, 0x20, 0x6C, 0x61, 0x65, 0x69, -		0x79, 0x6F, 0x64, 0x65, 0x69, 0x61, 0x20, 0x6F, 0x74, 0x72, 0x75, -		0x65, 0x74, 0x6F, 0x61, 0x6B, 0x68, 0x6C, 0x72, 0x20, 0x65, 0x69, -		0x75, 0x2C, 0x2E, 0x6F, 0x61, 0x6E, 0x73, 0x72, 0x63, 0x74, 0x6C, -		0x61, 0x69, 0x6C, 0x65, 0x6F, 0x69, 0x72, 0x61, 0x74, 0x70, 0x65, -		0x61, 0x6F, 0x69, 0x70, 0x20, 0x62, 0x6D -	}; - -	int size = 0; -	uint cChar = 0; -	while ((cChar = *src++) != 0) { -		if (cChar & 0x80) { -			cChar &= 0x7F; -			int index = (cChar & 0x78) >> 3; -			*dst++ = decodeTable1[index]; -			++size; -			assert(cChar < sizeof(decodeTable2)); -			cChar = decodeTable2[cChar]; -		} - -		*dst++ = cChar; -		++size; -	} - -	*dst++ = 0; -	return size; -} - -void KyraEngine_HoF::decodeString2(const char *src, char *dst) { -	if (!src || !dst) -		return; - -	char out = 0; -	while ((out = *src) != 0) { -		if (*src == 0x1B) { -			++src; -			out = *src + 0x7F; -		} -		*dst++ = out; -		++src; -	} - -	*dst = 0; -} -  #pragma mark -  void KyraEngine_HoF::showMessageFromCCode(int id, int16 palIndex, int) { diff --git a/engines/kyra/kyra_hof.h b/engines/kyra/kyra_hof.h index a3f78b8465..31dc38b110 100644 --- a/engines/kyra/kyra_hof.h +++ b/engines/kyra/kyra_hof.h @@ -551,8 +551,6 @@ protected:  	uint8 *getTableEntry(uint8 *buffer, int id);  	char *getTableString(int id, uint8 *buffer, int decode);  	const char *getChapterString(int id); -	int decodeString1(const char *src, char *dst); -	void decodeString2(const char *src, char *dst);  	void changeFileExtension(char *buffer); diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp index 823b253534..6e5bba3dc0 100644 --- a/engines/kyra/kyra_mr.cpp +++ b/engines/kyra/kyra_mr.cpp @@ -337,10 +337,10 @@ void KyraEngine_MR::initMainMenu() {  	_menu = new MainMenu(this);  	MainMenu::StaticData data = { -		{ _mainMenuStrings[_lang*4+0], _mainMenuStrings[_lang*4+1], _mainMenuStrings[_lang*4+2], _mainMenuStrings[_lang*4+3] }, -		{ 0x01, 0x04, 0x0C, 0x04, 0x00, 0x80, 0xFF, 0x00, 0x01, 0x02, 0x03 }, +		{ _mainMenuStrings[_lang*4+0], _mainMenuStrings[_lang*4+1], _mainMenuStrings[_lang*4+2], _mainMenuStrings[_lang*4+3], 0 }, +		{ 0x01, 0x04, 0x0C, 0x04, 0x00, 0x80, 0xFF },  		{ 0x16, 0x19, 0x1A, 0x16 }, -		0x80, 0xFF +		Screen::FID_8_FNT, 240  	};  	if (_flags.lang == Common::ES_ESP) { diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index 9dfb7994e1..1c70fe96d3 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -27,6 +27,7 @@  #include "kyra/screen_lol.h"  #include "kyra/resource.h"  #include "kyra/sound.h" +#include "kyra/util.h"  #include "common/endian.h" @@ -55,13 +56,19 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy  		_lang = 0;  		break;  	} + +	memset(_shapes, 0, sizeof(_shapes));  	_chargenWSA = 0; +	_lastUsedStringBuffer = 0;  }  LoLEngine::~LoLEngine() {  	setupPrologueData(false); +	for (uint i = 0; i < ARRAYSIZE(_shapes); ++i) +		delete[] _shapes[i]; +  	delete _screen;  	delete _tim; @@ -94,20 +101,206 @@ Common::Error LoLEngine::init() {  }  Common::Error LoLEngine::go() { -	setupPrologueData(true); -	showIntro(); -	_sound->playTrack(6); -	/*int character = */chooseCharacter(); -	_sound->playTrack(1); -	_screen->fadeToBlack(); -	setupPrologueData(false); +	bool hasSave = saveFileLoadable(0); + +	if (!hasSave) { +		setupPrologueData(true); +		showIntro(); +		setupPrologueData(false); +	} + +	preInit(); + +	int processSelection = -1; +	while (!shouldQuit() && processSelection == -1) { +		_screen->loadBitmap("TITLE.CPS", 2, 2, _screen->getPalette(0)); +		_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); +		_screen->fadePalette(_screen->getPalette(0), 0x1E); + +		int selection = mainMenu(); + +		switch (selection) { +		case 0:		// New game +			processSelection = 0; +			break; + +		case 1:		// Show intro +			setupPrologueData(true); +			_screen->hideMouse(); +			showIntro(); +			_screen->showMouse(); +			setupPrologueData(false); +			break; + +		case 2:		// "Lore of the Lands" +			break; + +		case 3:		// Load game +			// For now fall through +			//processSelection = 3; +			//break; + +		case 4:		// Quit game +		default: +			quitGame(); +			break; +		} +	} + +	if (processSelection == -1) +		return Common::kNoError; + +	if (processSelection == 0) { +		// Unlike the original, we add a nice fade to black +		memset(_screen->getPalette(0), 0, 768); +		_screen->fadePalette(_screen->getPalette(0), 0x54); + +		setupPrologueData(true); +		_sound->loadSoundFile("LOREINTR"); +		_sound->playTrack(6); +		/*int character = */chooseCharacter(); +		_sound->playTrack(1); +		_screen->fadeToBlack(); +		setupPrologueData(false); +	} else if (processSelection == 3) { +		//XXX +	}  	return Common::kNoError;  } +#pragma mark - Initialization + +void LoLEngine::preInit() { +	debugC(9, kDebugLevelMain, "LoLEngine::preInit()"); + +	_res->loadFileList("FILEDATA.FDT"); +	_screen->loadFont(Screen::FID_9_FNT, "FONT9P.FNT"); +	_screen->loadFont(Screen::FID_6_FNT, "FONT6P.FNT"); + +	uint8 *pal = _screen->getPalette(0); +	memset(pal, 0, 768); +	_screen->setScreenPalette(pal); + +	/*if (_sound->getMusicType() == Sound::kMidiMT32 || _sound->getSfxType() == Sound::kMidiMT32) { +		_sound->loadSoundFile("LOLSYSEX"); +		_sound->playTrack(0); + +		while (_sound->isPlaying() && !shouldQuit()) +			delay(10); +	}*/ + +	if (shouldQuit()) +		return; + +	_eventList.clear(); + +	//loadTalkFile(0); +	 +	char filename[32]; +	snprintf(filename, sizeof(filename), "LANDS.%s", _languageExt[_lang]);	 +	_landsFile = _res->fileData(filename, 0); + +	initializeCursors(); + +	/*_screen->setFont(Screen::FID_6_FNT); +	_screen->fprintString("V CD1.02 D", 260, 301, 0x67, 0x00, 0x04);*/ +	_screen->setFont(Screen::FID_9_FNT); +} + +void LoLEngine::initializeCursors() { +	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]); +} + + +int LoLEngine::mainMenu() { +	debugC(9, kDebugLevelMain, "LoLEngine::mainMenu()"); + +	bool hasSave = saveFileLoadable(0); + +	MainMenu::StaticData data = { +		{ 0, 0, 0, 0, 0 },  +		{ 0x01, 0x04, 0x0C, 0x04, 0x00, 0x3D, 0x9F }, +		{ 0x2C, 0x19, 0x48, 0x2C }, +		Screen::FID_9_FNT, 1 +	}; + +	if (hasSave) +		++data.menuTable[3]; + +	static const uint16 mainMenuStrings[2][5] = { +		{ 0x4248, 0x4249, 0x42DD, 0x424A, 0x0000 }, +		{ 0x4248, 0x4249, 0x42DD, 0x4001, 0x424A } +	}; + +	for (int i = 0; i < 5; ++i) { +		if (hasSave) +			data.strings[i] = getLangString(mainMenuStrings[1][i]);		 +		else +			data.strings[i] = getLangString(mainMenuStrings[0][i]);		 +	} + +	MainMenu *menu = new MainMenu(this); +	assert(menu); +	menu->init(data, MainMenu::Animation()); + +	int selection = menu->handle(hasSave ? 12 : 6); +	delete menu; + +	if (!hasSave && selection == 3) +		selection = 4; + +	return selection; +} + +#pragma mark - Localization + +const char *LoLEngine::getLangString(uint16 id) { +	debugC(9, kDebugLevelMain, "LoLEngine::getLangString(0x%.04X)", id); + +	if (id == 0xFFFF) +		return 0; + +	uint16 realId = id & 0x3FFF; +	uint8 *buffer = 0; + +	if (id & 0x4000) +		buffer = _landsFile; +	else +		buffer = 0;	// TODO + +	if (!buffer) +		return 0; + +	const char *string = (const char *)getTableEntry(buffer, realId); + +	char *srcBuffer = _stringBuffer[_lastUsedStringBuffer]; +	Util::decodeString1(string, srcBuffer); +	Util::decodeString2(srcBuffer, srcBuffer); + +	++_lastUsedStringBuffer; +	_lastUsedStringBuffer %= ARRAYSIZE(_stringBuffer); + +	return srcBuffer; +} + +uint8 *LoLEngine::getTableEntry(uint8 *buffer, uint16 id) { +	debugC(9, kDebugLevelMain, "LoLEngine::getTableEntry(%p, %d)", (const void *)buffer, id); +	if (!buffer) +		return 0; + +	return buffer + READ_LE_UINT16(buffer + (id<<1)); +} +  #pragma mark - Intro  void LoLEngine::setupPrologueData(bool load) { +	debugC(9, kDebugLevelMain, "LoLEngine::setupPrologueData(%d)", load); +  	static const char * const fileList[] = {  		"GENERAL.PAK", "INTROVOC.PAK", "STARTUP.PAK", "INTRO1.PAK",  		"INTRO2.PAK", "INTRO3.PAK", "INTRO4.PAK", "INTRO5.PAK", @@ -132,6 +325,9 @@ void LoLEngine::setupPrologueData(bool load) {  			_res->unloadPakFile(filename);  		}  	} + +	_screen->clearPage(0); +	_screen->clearPage(3);  	if (load) {  		_chargenWSA = new WSAMovie_v2(this, _screen); @@ -189,7 +385,6 @@ void LoLEngine::showIntro() {  	_screen->showMouse();  	_sound->voiceStop(); -	// HACK: Remove all input events  	_eventList.clear();  	_tim->unload(intro); diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index 9e5f29902e..a984fdc36f 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -50,6 +50,13 @@ private:  	Common::Error init();  	Common::Error go(); +	// initialization +	void preInit(); + +	void initializeCursors(); + +	int mainMenu(); +  	// intro  	void setupPrologueData(bool load); @@ -118,7 +125,18 @@ private:  	// translation  	int _lang; +	uint8 *_landsFile; + +	int _lastUsedStringBuffer; +	char _stringBuffer[5][512];	// TODO: The original used a size of 512, it looks a bit large. +								// Maybe we can someday reduce the size. +	const char *getLangString(uint16 id); +	uint8 *getTableEntry(uint8 *buffer, uint16 id); +  	static const char * const _languageExt[]; + +	// graphics +	uint8 *_shapes[138];  	// unneeded  	void setWalkspeed(uint8) {} diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk index 8169b7b33f..18ab2ecdb5 100644 --- a/engines/kyra/module.mk +++ b/engines/kyra/module.mk @@ -67,6 +67,7 @@ MODULE_OBJS := \  	timer_lok.o \  	timer_hof.o \  	timer_mr.o \ +	util.o \  	vqa.o \  	wsamovie.o diff --git a/engines/kyra/sequences_hof.cpp b/engines/kyra/sequences_hof.cpp index 718c8dadfa..7d0feaed16 100644 --- a/engines/kyra/sequences_hof.cpp +++ b/engines/kyra/sequences_hof.cpp @@ -2853,10 +2853,10 @@ void KyraEngine_HoF::seq_init() {  		} while (getShapePtr(numShp));  	} else {	  		MainMenu::StaticData data = { -			{ _sequenceStrings[97], _sequenceStrings[96], _sequenceStrings[95], _sequenceStrings[98] }, -			{ 0x01, 0x04, 0x0C, 0x04, 0x00, 0xd7, 0xd6, 0x00, 0x01, 0x02, 0x03 }, +			{ _sequenceStrings[97], _sequenceStrings[96], _sequenceStrings[95], _sequenceStrings[98], 0 }, +			{ 0x01, 0x04, 0x0C, 0x04, 0x00, 0xd7, 0xd6 },  			{ 0xd8, 0xda, 0xd9, 0xd8 }, -			0xd7, 0xd6 +			Screen::FID_8_FNT, 240  		};  		_menu = new MainMenu(this);  		_menu->init(data, MainMenu::Animation()); diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index bd94fe3f25..ca03451201 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -2357,7 +2357,19 @@ const int8 KyraEngine_MR::_albumWSAY[] = {  // lands of lore static res  const ScreenDim Screen_LoL::_screenDimTable[] = { -	{ 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 } +	{ 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 },	// Taken from Intro +	{ 0x08, 0x48, 0x18, 0x38, 0xFE, 0x01, 0x00, 0x00 }, +	{ 0x0E, 0x00, 0x16, 0x78, 0xFE, 0x01, 0x00, 0x00 }, +	{ 0x0B, 0x7B, 0x1C, 0x12, 0xFE, 0xFC, 0x00, 0x00 }, +	{ 0x0B, 0x7B, 0x1C, 0x2D, 0xFE, 0xFC, 0x00, 0x00 }, +	{ 0x55, 0x7B, 0xE9, 0x37, 0xFE, 0xFC, 0x00, 0x00 }, +	{ 0x0B, 0x8C, 0x10, 0x2B, 0x3D, 0x01, 0x00, 0x00 },	// Main menu box (3 entries) +	{ 0x04, 0x59, 0x20, 0x3C, 0x00, 0x00, 0x00, 0x00 }, +	{ 0x05, 0x6E, 0x1E, 0x0C, 0xFE, 0x01, 0x00, 0x00 }, +	{ 0x07, 0x19, 0x1A, 0x97, 0x00, 0x00, 0x00, 0x00 }, +	{ 0x03, 0x1E, 0x22, 0x8C, 0x00, 0x00, 0x00, 0x00 }, +	{ 0x02, 0x48, 0x24, 0x34, 0x00, 0x00, 0x00, 0x00 }, +	{ 0x0B, 0x8C, 0x10, 0x33, 0x3D, 0x01, 0x00, 0x00 }	// Main menu box (4 entries)  };  const int Screen_LoL::_screenDimTableCount = ARRAYSIZE(Screen_LoL::_screenDimTable); | 
