[Scummvm-cvs-logs] scummvm master -> 2e517cc9ec65a535d580fee607b9b920e41a3019

lordhoto lordhoto at gmail.com
Mon Dec 26 16:29:55 CET 2011


This automated email contains information about 72 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
77a81a80b4 KYRA: (AdLib Driver) - implement sound effects volume
f2a1ff3f78 KYRA: (AdLib Driver) - fix invalid memory write issue
4098feff57 KYRA: (AdLib Driver) - allow sound trigger query
86a8f694c0 KYRA: (AdLib Driver) - rename some variables to make more sense
93321ca485 KYRA: (AdLib Driver) - fix secondary effect
2da431aa65 KYRA: (AdLib Driver) - increase versions and add necessary EOB modifications
2bcae2451a KYRA: (AdLib Driver) - prevent squashing of sounds during halt track execution
814c78e84e KYRA: (AdLib Driver) - fix queue handling for Eob
9feb674e11 KYRA: (EOB) - update kyradat tool
540d081a6f KYRA: (EOB) - initial code base commit
ff8a030c37 KYRA: (EOB) - fix EOB1 spell definitions
aa031bf98e KYRA: (EOB) - minor code size reduction
80ece6caae KYRA: (EOB) - replace snprintf/sprintf
089ad94b68 KYRA: (EOB) - minor cleanup
77d210765a KYRA: (EOB) - add some static res (flight object data) to kyra.dat
9a6be57afd KYRA: (EOB) - implement explodeObject()
adbf14c3c4 KYRA: (EOB) - update static resources (menu strings)
c8665d06bc KYRA: (EOB) - fix some warnings and add some menu code
514c77625f KYRA: (EOB) - fix out of bounds mem access
6853452bcb KYRA: (EOB) - fix shift key input
894df5a4ac KYRA: (EOB) - extended saveload caps
69ad70afbb KYRA: (EOB) - allow returning to the main menu from character generation via ESC
045d08986d KYRA: (EOB) - start implementing camp menu
97e5036bf0 KYRA: (EOB) - more work on ingame menus
e29f639791 KYRA: (EOB) - fix monster distance attack bug
8d4034f428 KYRA: (EOB) - add static resources for memorize/pray menu
d7f2720b57 KYRA: (EOB) - match eob code with 3f2b5b9e8b9196c9d0e573abf8f8350ec4034b1d
b7f7635876 KYRA: (EOB) - implement memorize/pray spells menu
76bfcf834d KYRA: (EOB) - some refactoring
c53589bcda KYRA: (EOB) - implement load menu
5baabf037d KYRA: (EOB) - implement save menu
db83458330 KYRA: (EOB) - implement scribe scroll menu
9140fd8e91 KYRA: (EOB) - implement party resting
c302b3e43b KYRA: (EOB) - fix various bugs and implement some spells
0e4c184e28 KYRA: (EOB) - implement some gui functionality, some bug fixes, etc.
84900e8e50 KYRA: (EOB) - add turn undead spell, add some screen fades, fix some bugs
48f83b7bb4 KYRA: (EOB) - implement npc sequences and fix some bugs
aab9e62247 KYRA: (EOB) - some more sequence code and bug fixes
bac0caeb0f KYRA: (EOB) - lots of fixes towards EOB1 playability
fc5b29fdbc KYRA: (EOB) - implemented some spells and fixed more bugs
359f3efd03 KYRA: (EOB) - add some spells
0d54aff632 KYRA: (EOB) - add EOB 1 intro
b288889c97 KYRA: (EOB) - implement wall of force spell
b3c8173bd4 KYRA: (EOB) - extend save/load dialogue to support 990 slots
f7032c126d KYRA: (EOB) - fix some bugs
c35de374df KYRA: (EOB) - lots of bug fixes, mostly for EOB II
2448d885e4 KYRA: (EOB) - complete EOBII playability
816b40ebf8 KYRA: (EOB) - add debugger, etc.
68ed8b9598 KYRA: (EOB) - fix some valgrind warnings
ac1aa43ca8 KYRA: (EOB) - fix char generator regression + cleanup
1cbd566930 KYRA: (EOB) - fix invalid string access
532f8f33f2 KYRA: (EOB) - fix mem leak
812ea181b8 KYRA: (EOB) - cleanup
a944990a68 KYRA: (EOB) - rename some saving throw related data
5837e0f94e KYRA: (EOB) - make sure that the music stops after character generation in Eob 1
49c111f8ca KYRA: (EOB) - ignore 'EYE.PAK' file in resource loader
aac7e16afa KYRA: (EOB) - fix some more bugs
8b618e46df KYRA: (EOB/LOL) - cleanup common code
6c8fb30cbd KYRA: (EOB) - fix static resource loading for EOB when LOL is disabled
4c6302943b KYRA: implement Screen::decodeFrame1()
36d85a315f KYRA: (EOB) - rename some files for a better match with the contained code
4e4f4164be KYRA: (EOB) - fix eob2 sequence text fading
0aa3238523 KYRA: (EOB/LOL) - rename some vars
8716ed1703 KYRA: (EOB/LOL) - again fix static resource loading for EOB when LOL is disabled
60330556ff KYRA: (EOB/LOL) - move eob/lol specific screen code to new class
0c7fbd788b KYRA: (EOB) - remove unneeded virtual declarations in screen.h
692f9ee6d5 KYRA: whitespace cleanup
40b1b794ae KYRA: make bool variable const (again)
53e1bf21ec KYRA: (EOB) - get rid of loadVGAPalette7bit()
c0e782fd0b KYRA: (EOB) - Start implementing EOB1 party transfer (not working yet)
d807b3d42b KYRA: (EOB) - implement EOB1 party transfer
2e517cc9ec KYRA: (EOB) - add EOB copyright strings to KyraMetaEngine::getOriginalCopyright()


Commit: 77a81a80b4157acd7e8e580c2648ec3b3ef6bc64
    https://github.com/scummvm/scummvm/commit/77a81a80b4157acd7e8e580c2648ec3b3ef6bc64
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:09-08:00

Commit Message:
KYRA: (AdLib Driver) - implement sound effects volume

(also make internal driver version more flexible)

Changed paths:
    engines/kyra/sound.cpp
    engines/kyra/sound.h
    engines/kyra/sound_adlib.cpp
    engines/kyra/sound_adlib.h
    engines/kyra/sound_amiga.cpp
    engines/kyra/sound_intern.h
    engines/kyra/sound_midi.cpp
    engines/kyra/sound_towns.cpp



diff --git a/engines/kyra/sound.cpp b/engines/kyra/sound.cpp
index a1af1ad..9325513 100644
--- a/engines/kyra/sound.cpp
+++ b/engines/kyra/sound.cpp
@@ -229,8 +229,8 @@ bool MixedSoundDriver::isPlaying() const {
 	return _music->isPlaying() | _sfx->isPlaying();
 }
 
-void MixedSoundDriver::playSoundEffect(uint8 track) {
-	_sfx->playSoundEffect(track);
+void MixedSoundDriver::playSoundEffect(uint8 track, uint8 volume) {
+	_sfx->playSoundEffect(track, volume);
 }
 
 void MixedSoundDriver::stopAllSoundEffects() {
diff --git a/engines/kyra/sound.h b/engines/kyra/sound.h
index f3de565..88454e4 100644
--- a/engines/kyra/sound.h
+++ b/engines/kyra/sound.h
@@ -128,7 +128,7 @@ public:
 	 *
 	 * @param track sound effect id
 	 */
-	virtual void playSoundEffect(uint8 track) = 0;
+	virtual void playSoundEffect(uint8 track, uint8 volume = 0xff) = 0;
 
 	/**
 	 * Stop playback of all sfx tracks.
@@ -273,7 +273,7 @@ public:
 	virtual void haltTrack();
 	virtual bool isPlaying() const;
 
-	virtual void playSoundEffect(uint8 track);
+	virtual void playSoundEffect(uint8 track, uint8 volume = 0xff);
 
 	virtual void stopAllSoundEffects();
 
diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp
index b04abea..c31cf80 100644
--- a/engines/kyra/sound_adlib.cpp
+++ b/engines/kyra/sound_adlib.cpp
@@ -57,12 +57,12 @@ namespace Kyra {
 
 class AdLibDriver : public Audio::AudioStream {
 public:
-	AdLibDriver(Audio::Mixer *mixer, bool v2);
+	AdLibDriver(Audio::Mixer *mixer, int version);
 	~AdLibDriver();
 
 	void initDriver();
 	void setSoundData(uint8 *data);
-	void queueTrack(int track);
+	void queueTrack(int track, int volume);
 	bool isChannelPlaying(int channel) const;
 	void stopAllChannels();
 	int getSoundTrigger() const { return _soundTrigger; }
@@ -223,7 +223,7 @@ private:
 	}
 
 	uint8 *getInstrument(int instrumentId) {
-		return _soundData + READ_LE_UINT16(_soundData + (_v2 ? 1000 : 500) + 2 * instrumentId);
+		return _soundData + READ_LE_UINT16(_soundData + ((_version == 2) ? 1000 : 500) + 2 * instrumentId);
 	}
 
 	void setupPrograms();
@@ -358,11 +358,16 @@ private:
 
 	uint8 *_soundData;
 
+	struct QueueEntry {
+		uint8 *data;
+		uint8 volume;
+	};
+
+	QueueEntry _programQueue[16];
 	int _programStartTimeout;
-	uint8 *_programQueue[16];
 	int _programQueueStart, _programQueueEnd;
 
-	void adjustSfxData(uint8 *data);
+	void adjustSfxData(uint8 *data, int volume);
 	uint8 *_sfxPointer;
 	int _sfxPriority;
 	int _sfxVelocity;
@@ -394,13 +399,13 @@ private:
 
 	uint8 _musicVolume, _sfxVolume;
 
-	bool _v2;
+	int _version;
 };
 
-AdLibDriver::AdLibDriver(Audio::Mixer *mixer, bool v2) {
+AdLibDriver::AdLibDriver(Audio::Mixer *mixer, int version) {
 	setupParserOpcodeTable();
 
-	_v2 = v2;
+	_version = version;
 
 	_mixer = mixer;
 
@@ -467,7 +472,7 @@ void AdLibDriver::setMusicVolume(uint8 volume) {
 	}
 
 	// For now we use the music volume for both sfx and music in Kyra1.
-	if (!_v2) {
+	if (_version < 2) {
 		_sfxVolume = volume;
 
 		for (uint i = 6; i < 9; ++i) {
@@ -484,8 +489,8 @@ void AdLibDriver::setMusicVolume(uint8 volume) {
 }
 
 void AdLibDriver::setSfxVolume(uint8 volume) {
-	// We only support sfx volume in v2 games.
-	if (!_v2)
+	// We only support sfx volume in version 2 games.
+	if (_version < 2)
 		return;
 
 	Common::StackLock lock(_mutex);
@@ -525,20 +530,21 @@ void AdLibDriver::setSoundData(uint8 *data) {
 	_soundData = data;
 }
 
-void AdLibDriver::queueTrack(int track) {
+void AdLibDriver::queueTrack(int track, int volume) {
 	Common::StackLock lock(_mutex);
 
 	uint8 *trackData = getProgram(track);
 	if (!trackData)
 		return;
 
-	if (_programQueueEnd == _programQueueStart && _programQueue[_programQueueEnd] != 0) {
+	if (_programQueueEnd == _programQueueStart && _programQueue[_programQueueEnd].data != 0) {
 		warning("AdLibDriver: Program queue full, dropping track %d", track);
 		return;
 	}
 
-	_programQueue[_programQueueEnd++] = trackData;
-	_programQueueEnd &= 15;
+	_programQueue[_programQueueEnd].data = trackData;
+	_programQueue[_programQueueEnd].volume = volume;
+	_programQueueEnd = (_programQueueEnd + 1) & 15;
 }
 
 bool AdLibDriver::isChannelPlaying(int channel) const {
@@ -588,13 +594,13 @@ void AdLibDriver::setupPrograms() {
 	if (_programQueueStart == _programQueueEnd)
 		return;
 
-	uint8 *ptr = _programQueue[_programQueueStart];
+	uint8 *ptr = _programQueue[_programQueueStart].data;
 	// Clear the queue entry
-	_programQueue[_programQueueStart] = 0;
+	_programQueue[_programQueueStart].data = 0;
 	_programQueueStart = (_programQueueStart + 1) & 15;
 
 	// Adjust data in case we hit a sound effect.
-	adjustSfxData(ptr);
+	adjustSfxData(ptr, _programQueue[_programQueueStart].volume);
 
 	const int chan = *ptr++;
 	const int priority = *ptr++;
@@ -626,7 +632,7 @@ void AdLibDriver::setupPrograms() {
 	}
 }
 
-void AdLibDriver::adjustSfxData(uint8 *ptr) {
+void AdLibDriver::adjustSfxData(uint8 *ptr, int volume) {
 	// Check whether we need to reset the data of an old sfx which has been
 	// started.
 	if (_sfxPointer) {
@@ -647,21 +653,16 @@ void AdLibDriver::adjustSfxData(uint8 *ptr) {
 	_sfxPriority = ptr[1];
 	_sfxVelocity = ptr[3];
 
-	// In the cases I've seen, the mysterious fourth byte has been
-	// the parameter for the update_setExtraLevel3() callback.
-	//
-	// The extra level is part of the channels "total level", which
-	// is a six-bit value where larger values means softer volume.
-	//
-	// So what seems to be happening here is that sounds which are
-	// started by this function are given a slightly lower priority
-	// and a slightly higher (i.e. softer) extra level 3 than they
-	// would have if they were started from anywhere else. Strange.
-
 	// Adjust the values.
-	int newVal = ((((ptr[3]) + 63) * 0xFF) >> 8) & 0xFF;
-	ptr[3] = -newVal + 63;
-	ptr[1] = ((ptr[1] * 0xFF) >> 8) & 0xFF;
+	if (_version >= 1) {
+		int newVal = ((((ptr[3]) + 63) * volume) >> 8) & 0xFF;
+		ptr[3] = -newVal + 63;
+		ptr[1] = ((ptr[1] * volume) >> 8) & 0xFF;
+	} else {
+		int newVal = ((_sfxVelocity << 2) ^ 0xff) * volume;
+		ptr[3] = (newVal >> 10) ^ 0x3f;
+		ptr[1] = newVal >> 11;
+	}	
 }
 
 // A few words on opcode parsing and timing:
@@ -2238,20 +2239,20 @@ const int SoundAdLibPC::_kyra1NumSoundTriggers = ARRAYSIZE(SoundAdLibPC::_kyra1S
 SoundAdLibPC::SoundAdLibPC(KyraEngine_v1 *vm, Audio::Mixer *mixer)
 	: Sound(vm, mixer), _driver(0), _trackEntries(), _soundDataPtr(0) {
 	memset(_trackEntries, 0, sizeof(_trackEntries));
-	_v2 = (_vm->game() == GI_KYRA2) || (_vm->game() == GI_LOL && !_vm->gameFlags().isDemo);
-	_driver = new AdLibDriver(mixer, _v2);
+	_version = ((_vm->game() == GI_KYRA2) || (_vm->game() == GI_LOL && !_vm->gameFlags().isDemo)) ? 2 : 1;
+	_driver = new AdLibDriver(mixer, _version);
 	assert(_driver);
 
 	_sfxPlayingSound = -1;
 	_soundFileLoaded.clear();
 
-	if (_v2) {
+	if (_version == 1) {
+		_soundTriggers = _kyra1SoundTriggers;
+		_numSoundTriggers = _kyra1NumSoundTriggers;
+	} else {
 		// TODO: Figure out if Kyra 2 uses sound triggers at all.
 		_soundTriggers = 0;
 		_numSoundTriggers = 0;
-	} else {
-		_soundTriggers = _kyra1SoundTriggers;
-		_numSoundTriggers = _kyra1NumSoundTriggers;
 	}
 }
 
@@ -2307,13 +2308,13 @@ void SoundAdLibPC::playTrack(uint8 track) {
 			_driver->setSyncJumpMask(0x000F);
 		else
 			_driver->setSyncJumpMask(0);
-		play(track);
+		play(track, 0xff);
 	}
 }
 
 void SoundAdLibPC::haltTrack() {
-	play(0);
-	play(0);
+	play(0, 0);
+	play(0, 0);
 	//_vm->_system->delayMillis(3 * 60);
 }
 
@@ -2321,27 +2322,27 @@ bool SoundAdLibPC::isPlaying() const {
 	return _driver->isChannelPlaying(0);
 }
 
-void SoundAdLibPC::playSoundEffect(uint8 track) {
+void SoundAdLibPC::playSoundEffect(uint8 track, uint8 volume) {
 	if (_sfxEnabled)
-		play(track);
+		play(track, volume);
 }
 
-void SoundAdLibPC::play(uint8 track) {
+void SoundAdLibPC::play(uint8 track, uint8 volume) {
 	uint16 soundId = 0;
 
-	if (_v2)
+	if (_version == 2)
 		soundId = READ_LE_UINT16(&_trackEntries[track<<1]);
 	else
 		soundId = _trackEntries[track];
 
-	if ((soundId == 0xFFFF && _v2) || (soundId == 0xFF && !_v2) || !_soundDataPtr)
+	if ((soundId == 0xFFFF && _version == 2) || (soundId == 0xFF && _version < 2) || !_soundDataPtr)
 		return;
 
-	_driver->queueTrack(soundId);
+	_driver->queueTrack(soundId, volume);
 }
 
 void SoundAdLibPC::beginFadeOut() {
-	play(1);
+	play(1, 0xff);
 }
 
 void SoundAdLibPC::loadSoundFile(uint file) {
@@ -2377,7 +2378,7 @@ void SoundAdLibPC::internalLoadFile(Common::String file) {
 	int soundDataSize = fileSize;
 	uint8 *p = fileData;
 
-	if (_v2) {
+	if (_version == 2) {
 		memcpy(_trackEntries, p, 500);
 		p += 500;
 		soundDataSize -= 500;
diff --git a/engines/kyra/sound_adlib.h b/engines/kyra/sound_adlib.h
index 923a4cb..06ec951 100644
--- a/engines/kyra/sound_adlib.h
+++ b/engines/kyra/sound_adlib.h
@@ -76,17 +76,17 @@ public:
 	virtual void haltTrack();
 	virtual bool isPlaying() const;
 
-	virtual void playSoundEffect(uint8 track);
+	virtual void playSoundEffect(uint8 track, uint8 volume = 0xff);
 
 	virtual void beginFadeOut();
 private:
 	void internalLoadFile(Common::String file);
 
-	void play(uint8 track);
+	void play(uint8 track, uint8 volume);
 
 	AdLibDriver *_driver;
 
-	bool _v2;
+	int _version;
 	uint8 _trackEntries[500];
 	uint8 *_soundDataPtr;
 	int _sfxPlayingSound;
diff --git a/engines/kyra/sound_amiga.cpp b/engines/kyra/sound_amiga.cpp
index dfb0aa8..ec2748d 100644
--- a/engines/kyra/sound_amiga.cpp
+++ b/engines/kyra/sound_amiga.cpp
@@ -173,7 +173,7 @@ void SoundAmiga::beginFadeOut() {
 	_driver->setVolume(0x40);
 }
 
-void SoundAmiga::playSoundEffect(uint8 track) {
+void SoundAmiga::playSoundEffect(uint8 track, uint8) {
 	debugC(5, kDebugLevelSound, "SoundAmiga::playSoundEffect(%d)", track);
 	const AmigaSfxTable *sfx = 0;
 	bool pan = false;
diff --git a/engines/kyra/sound_intern.h b/engines/kyra/sound_intern.h
index be3c09d..427bef6 100644
--- a/engines/kyra/sound_intern.h
+++ b/engines/kyra/sound_intern.h
@@ -67,7 +67,7 @@ public:
 	void haltTrack();
 	bool isPlaying() const;
 
-	void playSoundEffect(uint8 track);
+	void playSoundEffect(uint8 track, uint8 volume = 0xff);
 	void stopAllSoundEffects();
 
 	void beginFadeOut();
@@ -116,7 +116,7 @@ public:
 	void playTrack(uint8 track);
 	void haltTrack();
 
-	void playSoundEffect(uint8);
+	void playSoundEffect(uint8 track, uint8 volume = 0xff);
 	void stopAllSoundEffects();
 
 	void beginFadeOut();
@@ -166,7 +166,7 @@ public:
 	void beginFadeOut();
 
 	int32 voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volume, bool isSfx) { return -1; }
-	void playSoundEffect(uint8);
+	void playSoundEffect(uint8 track, uint8 volume = 0xff);
 
 	void updateVolumeSettings();
 
@@ -195,7 +195,7 @@ public:
 	void beginFadeOut();
 
 	int32 voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volume, bool isSfx);
-	void playSoundEffect(uint8 track);
+	void playSoundEffect(uint8 track, uint8 volume = 0xff);
 
 	void updateVolumeSettings();
 
@@ -304,7 +304,7 @@ public:
 	void beginFadeOut();
 
 	int32 voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volume, bool isSfx) { return -1; }
-	void playSoundEffect(uint8);
+	void playSoundEffect(uint8 track, uint8 volume = 0xff);
 
 protected:
 	Audio::MaxTrax *_driver;
diff --git a/engines/kyra/sound_midi.cpp b/engines/kyra/sound_midi.cpp
index 1a5c2f9..0004395 100644
--- a/engines/kyra/sound_midi.cpp
+++ b/engines/kyra/sound_midi.cpp
@@ -684,7 +684,7 @@ bool SoundMidiPC::isPlaying() const {
 	return _music->isPlaying();
 }
 
-void SoundMidiPC::playSoundEffect(uint8 track) {
+void SoundMidiPC::playSoundEffect(uint8 track, uint8) {
 	if (!_sfxEnabled)
 		return;
 
diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp
index c851842..b77c307 100644
--- a/engines/kyra/sound_towns.cpp
+++ b/engines/kyra/sound_towns.cpp
@@ -125,7 +125,7 @@ void SoundTowns::loadSoundFile(uint file) {
 	_sfxFileData = _vm->resource()->fileData(fileListEntry(file), 0);
 }
 
-void SoundTowns::playSoundEffect(uint8 track) {
+void SoundTowns::playSoundEffect(uint8 track, uint8) {
 	if (!_sfxEnabled || !_sfxFileData)
 		return;
 
@@ -446,7 +446,7 @@ void SoundPC98::beginFadeOut() {
 	haltTrack();
 }
 
-void SoundPC98::playSoundEffect(uint8 track) {
+void SoundPC98::playSoundEffect(uint8 track, uint8) {
 	if (!_sfxTrackData)
 		return;
 
@@ -650,7 +650,7 @@ int32 SoundTownsPC98_v2::voicePlay(const char *file, Audio::SoundHandle *handle,
 	return 1;
 }
 
-void SoundTownsPC98_v2::playSoundEffect(uint8 track) {
+void SoundTownsPC98_v2::playSoundEffect(uint8 track, uint8) {
 	if (!_useFmSfx || !_sfxTrackData)
 		return;
 


Commit: f2a1ff3f7842757d369db23652b39ed3f2a22144
    https://github.com/scummvm/scummvm/commit/f2a1ff3f7842757d369db23652b39ed3f2a22144
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:09-08:00

Commit Message:
KYRA: (AdLib Driver) - fix invalid memory write issue

Changed paths:
    engines/kyra/sound_adlib.cpp



diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp
index c31cf80..9e47367 100644
--- a/engines/kyra/sound_adlib.cpp
+++ b/engines/kyra/sound_adlib.cpp
@@ -524,7 +524,7 @@ void AdLibDriver::setSoundData(uint8 *data) {
 
 	if (_soundData) {
 		delete[] _soundData;
-		_soundData = 0;
+		_soundData = _sfxPointer = 0;
 	}
 
 	_soundData = data;


Commit: 4098feff57239102a7519e5b7bc1ef8f41465dc2
    https://github.com/scummvm/scummvm/commit/4098feff57239102a7519e5b7bc1ef8f41465dc2
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:09-08:00

Commit Message:
KYRA: (AdLib Driver) - allow sound trigger query

Changed paths:
    engines/kyra/sound.h
    engines/kyra/sound_adlib.cpp
    engines/kyra/sound_adlib.h



diff --git a/engines/kyra/sound.h b/engines/kyra/sound.h
index 88454e4..63cec48 100644
--- a/engines/kyra/sound.h
+++ b/engines/kyra/sound.h
@@ -217,6 +217,16 @@ public:
 	 * Stops playback of the current voice.
 	 */
 	void voiceStop(const Audio::SoundHandle *handle = 0);
+
+	/**
+	 * Receive notifications from a song at certain points.
+	 */
+	virtual int checkTrigger() { return 0; }
+
+	/**
+	 * Reset sound trigger.
+	 */
+	virtual void resetTrigger() {}
 protected:
 	const char *fileListEntry(int file) const { return (_soundDataList != 0 && file >= 0 && file < _soundDataList->fileListLen) ? _soundDataList->fileList[file] : ""; }
 	int fileListLen() const { return _soundDataList->fileListLen; }
diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp
index 9e47367..d3b72cb 100644
--- a/engines/kyra/sound_adlib.cpp
+++ b/engines/kyra/sound_adlib.cpp
@@ -66,6 +66,7 @@ public:
 	bool isChannelPlaying(int channel) const;
 	void stopAllChannels();
 	int getSoundTrigger() const { return _soundTrigger; }
+	void resetSoundTrigger() { _soundTrigger = 0; }
 
 	void callback();
 
@@ -2345,6 +2346,14 @@ void SoundAdLibPC::beginFadeOut() {
 	play(1, 0xff);
 }
 
+int SoundAdLibPC::checkTrigger() {
+	return _driver->getSoundTrigger();
+}
+
+void SoundAdLibPC::resetTrigger() {
+	_driver->resetSoundTrigger();
+}
+
 void SoundAdLibPC::loadSoundFile(uint file) {
 	internalLoadFile(fileListEntry(file));
 }
diff --git a/engines/kyra/sound_adlib.h b/engines/kyra/sound_adlib.h
index 06ec951..8492f3b 100644
--- a/engines/kyra/sound_adlib.h
+++ b/engines/kyra/sound_adlib.h
@@ -79,6 +79,9 @@ public:
 	virtual void playSoundEffect(uint8 track, uint8 volume = 0xff);
 
 	virtual void beginFadeOut();
+
+	virtual int checkTrigger();
+	virtual void resetTrigger();
 private:
 	void internalLoadFile(Common::String file);
 


Commit: 86a8f694c0c09ccb5825fc7591a1303e638b2451
    https://github.com/scummvm/scummvm/commit/86a8f694c0c09ccb5825fc7591a1303e638b2451
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:09-08:00

Commit Message:
KYRA: (AdLib Driver) - rename some variables to make more sense

Changed paths:
    engines/kyra/sound_adlib.cpp



diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp
index d3b72cb..0bc682d 100644
--- a/engines/kyra/sound_adlib.cpp
+++ b/engines/kyra/sound_adlib.cpp
@@ -107,7 +107,7 @@ private:
 	// These variables have not yet been named, but some of them are partly
 	// known nevertheless:
 	//
-	// unk16 - Sound-related. Possibly some sort of pitch bend.
+	// pitchBend - Sound-related. Possibly some sort of pitch bend.
 	// unk18 - Sound-effect. Used for secondaryEffect1()
 	// unk19 - Sound-effect. Used for secondaryEffect1()
 	// unk20 - Sound-effect. Used for secondaryEffect1()
@@ -176,7 +176,7 @@ private:
 		uint16 offset;
 		uint8 tempoReset;
 		uint8 rawNote;
-		int8 unk16;
+		int8 pitchBend;
 		uint8 volumeModifier;
 	};
 
@@ -280,7 +280,7 @@ private:
 	int updateCallback38(uint8 *&dataptr, Channel &channel, uint8 value);
 	int updateCallback39(uint8 *&dataptr, Channel &channel, uint8 value);
 	int update_removePrimaryEffect2(uint8 *&dataptr, Channel &channel, uint8 value);
-	int updateCallback41(uint8 *&dataptr, Channel &channel, uint8 value);
+	int update_pitchBend(uint8 *&dataptr, Channel &channel, uint8 value);
 	int update_resetToGlobalTempo(uint8 *&dataptr, Channel &channel, uint8 value);
 	int update_nop(uint8 *&dataptr, Channel &channel, uint8 value);
 	int update_setDurationRandomness(uint8 *&dataptr, Channel &channel, uint8 value);
@@ -318,7 +318,7 @@ private:
 	// _unkValue18     - Unknown. Rhythm section volume?
 	// _unkValue19     - Unknown. Rhythm section volume?
 	// _unkValue20     - Unknown. Rhythm section volume?
-	// _unkTable[]     - Probably frequences for the 12-tone scale.
+	// _freqTable[]     - Probably frequences for the 12-tone scale.
 	// _unkTable2[]    - Unknown. Currently only used by updateCallback46()
 	// _unkTable2_1[]  - One of the tables in _unkTable2[]
 	// _unkTable2_2[]  - One of the tables in _unkTable2[]
@@ -385,12 +385,12 @@ private:
 	const uint8 *_tablePtr2;
 
 	static const uint8 _regOffset[];
-	static const uint16 _unkTable[];
+	static const uint16 _freqTable[];
 	static const uint8 *const _unkTable2[];
 	static const uint8 _unkTable2_1[];
 	static const uint8 _unkTable2_2[];
 	static const uint8 _unkTable2_3[];
-	static const uint8 _unkTables[][32];
+	static const uint8 _pitchBendTables[][32];
 
 	uint16 _syncJumpMask;
 
@@ -975,20 +975,20 @@ void AdLibDriver::setupNote(uint8 rawNote, Channel &channel, bool flag) {
 	// octave bits, and that could possibly have been used in some sound.
 	// But as it is now, I can't see any way it would happen.
 
-	uint16 freq = _unkTable[note] + channel.baseFreq;
+	uint16 freq = _freqTable[note] + channel.baseFreq;
 
 	// When called from callback 41, the behavior is slightly different:
-	// We adjust the frequency, even when channel.unk16 is 0.
+	// We adjust the frequency, even when channel.pitchBend is 0.
 
-	if (channel.unk16 || flag) {
+	if (channel.pitchBend || flag) {
 		const uint8 *table;
 
-		if (channel.unk16 >= 0) {
-			table = _unkTables[(channel.rawNote & 0x0F) + 2];
-			freq += table[channel.unk16];
+		if (channel.pitchBend >= 0) {
+			table = _pitchBendTables[(channel.rawNote & 0x0F) + 2];
+			freq += table[channel.pitchBend];
 		} else {
-			table = _unkTables[channel.rawNote & 0x0F];
-			freq -= table[-channel.unk16];
+			table = _pitchBendTables[channel.rawNote & 0x0F];
+			freq -= table[-channel.pitchBend];
 		}
 	}
 
@@ -1670,8 +1670,8 @@ int AdLibDriver::update_removePrimaryEffect2(uint8 *&dataptr, Channel &channel,
 	return 0;
 }
 
-int AdLibDriver::updateCallback41(uint8 *&dataptr, Channel &channel, uint8 value) {
-	channel.unk16 = value;
+int AdLibDriver::update_pitchBend(uint8 *&dataptr, Channel &channel, uint8 value) {
+	channel.pitchBend = value;
 	setupNote(channel.rawNote, channel, true);
 	return 0;
 }
@@ -2022,7 +2022,7 @@ void AdLibDriver::setupParserOpcodeTable() {
 
 		// 56
 		COMMAND(update_stopChannel),
-		COMMAND(updateCallback41),
+		COMMAND(update_pitchBend),
 		COMMAND(update_resetToGlobalTempo),
 		COMMAND(update_nop),
 
@@ -2063,11 +2063,10 @@ const uint8 AdLibDriver::_regOffset[] = {
 	0x12
 };
 
-// Given the size of this table, and the range of its values, it's probably the
-// F-Numbers (10 bits) for the notes of the 12-tone scale. However, it does not
-// match the table in the AdLib documentation I've seen.
+//These are the F-Numbers (10 bits) for the notes of the 12-tone scale.
+// However, it does not match the table in the AdLib documentation I've seen.
 
-const uint16 AdLibDriver::_unkTable[] = {
+const uint16 AdLibDriver::_freqTable[] = {
 	0x0134, 0x0147, 0x015A, 0x016F, 0x0184, 0x019C, 0x01B4, 0x01CE, 0x01E9,
 	0x0207, 0x0225, 0x0246
 };
@@ -2145,13 +2144,11 @@ const uint8 AdLibDriver::_unkTable2_3[] = {
 };
 
 // This table is used to modify the frequency of the notes, depending on the
-// note value and unk16. In theory, we could very well try to access memory
-// outside this table, but in reality that probably won't happen.
+// note value and the pitch bend value. In theory, we could very well try to
+// access memory outside this table, but in reality that probably won't happen.
 //
-// This could be some sort of pitch bend, but I have yet to see it used for
-// anything so it's hard to say.
 
-const uint8 AdLibDriver::_unkTables[][32] = {
+const uint8 AdLibDriver::_pitchBendTables[][32] = {
 	// 0
 	{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08,
 	  0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,


Commit: 93321ca4850c4859c71ec02420874101529bddce
    https://github.com/scummvm/scummvm/commit/93321ca4850c4859c71ec02420874101529bddce
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:09-08:00

Commit Message:
KYRA: (AdLib Driver) - fix secondary effect

Changed paths:
    engines/kyra/sound_adlib.cpp



diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp
index 0bc682d..2bce5a2 100644
--- a/engines/kyra/sound_adlib.cpp
+++ b/engines/kyra/sound_adlib.cpp
@@ -1428,7 +1428,21 @@ int AdLibDriver::update_setupSecondaryEffect1(uint8 *&dataptr, Channel &channel,
 	channel.unk19 = value;
 	channel.unk20 = channel.unk21 = *dataptr++;
 	channel.unk22 = *dataptr++;
-	channel.offset = READ_LE_UINT16(dataptr); dataptr += 2;
+	// WORKAROUND: The original code reads a true offset which later gets translated via xlat (in
+	// the current segment). This means that the outcome depends on the sound data offset.
+	// Unfortunately this offset is different in most implementations of the audio driver and
+	// probably also different from the offset assumed by the sequencer.
+	// It seems that the driver assumes an offset of 191 which is wrong for all the game driver
+	// implementations.
+	// This bug has probably not been noticed, since the effect is hardly used and the sounds are
+	// not necessarily worse. I noticed the difference between ScummVM and DOSBox for the EOB II
+	// teleporter sound. I also found the location of the table which is supposed to be used here
+	// (simple enough: it is located at the end of the track after the 0x88 ending opcode).
+	// Teleporters in EOB I and II now sound exactly the same which I am sure was the intended way,
+	// since the sound data is exactly the same.
+	// In DOSBox the teleporters will sound different in EOB I and II, due to different sound
+	// data offsets.
+	channel.offset = READ_LE_UINT16(dataptr) - 191; dataptr += 2;
 	channel.secondaryEffect = &AdLibDriver::secondaryEffect1;
 	return 0;
 }


Commit: 2da431aa65da25388963687d398f4a40f2aeee73
    https://github.com/scummvm/scummvm/commit/2da431aa65da25388963687d398f4a40f2aeee73
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:09-08:00

Commit Message:
KYRA: (AdLib Driver) - increase versions and add necessary EOB modifications

Changed paths:
    engines/kyra/kyra_v1.h
    engines/kyra/sound_adlib.cpp



diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h
index 5a9feb0..24a3b35 100644
--- a/engines/kyra/kyra_v1.h
+++ b/engines/kyra/kyra_v1.h
@@ -134,7 +134,9 @@ enum {
 	GI_KYRA1 = 0,
 	GI_KYRA2 = 1,
 	GI_KYRA3 = 2,
-	GI_LOL = 4
+	GI_LOL = 4,
+	GI_EOB1 = 5,
+	GI_EOB2 = 6
 };
 
 struct AudioDataStruct {
diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp
index 2bce5a2..983d3b6 100644
--- a/engines/kyra/sound_adlib.cpp
+++ b/engines/kyra/sound_adlib.cpp
@@ -224,7 +224,7 @@ private:
 	}
 
 	uint8 *getInstrument(int instrumentId) {
-		return _soundData + READ_LE_UINT16(_soundData + ((_version == 2) ? 1000 : 500) + 2 * instrumentId);
+		return getProgram(_numPrograms + instrumentId);
 	}
 
 	void setupPrograms();
@@ -400,6 +400,7 @@ private:
 
 	uint8 _musicVolume, _sfxVolume;
 
+	int _numPrograms;
 	int _version;
 };
 
@@ -407,6 +408,7 @@ AdLibDriver::AdLibDriver(Audio::Mixer *mixer, int version) {
 	setupParserOpcodeTable();
 
 	_version = version;
+	_numPrograms = (_version == 1) ? 150 : ((_version == 4) ? 500 : 250);
 
 	_mixer = mixer;
 
@@ -472,8 +474,8 @@ void AdLibDriver::setMusicVolume(uint8 volume) {
 		writeOPL(0x43 + regOffset, calculateOpLevel2(chan));
 	}
 
-	// For now we use the music volume for both sfx and music in Kyra1.
-	if (_version < 2) {
+	// For now we use the music volume for both sfx and music in Kyra1 and Eob
+	if (_version < 4) {
 		_sfxVolume = volume;
 
 		for (uint i = 6; i < 9; ++i) {
@@ -490,8 +492,8 @@ void AdLibDriver::setMusicVolume(uint8 volume) {
 }
 
 void AdLibDriver::setSfxVolume(uint8 volume) {
-	// We only support sfx volume in version 2 games.
-	if (_version < 2)
+	// We only support sfx volume in version 4 games.
+	if (_version < 4)
 		return;
 
 	Common::StackLock lock(_mutex);
@@ -655,15 +657,17 @@ void AdLibDriver::adjustSfxData(uint8 *ptr, int volume) {
 	_sfxVelocity = ptr[3];
 
 	// Adjust the values.
-	if (_version >= 1) {
-		int newVal = ((((ptr[3]) + 63) * volume) >> 8) & 0xFF;
-		ptr[3] = -newVal + 63;
-		ptr[1] = ((ptr[1] * volume) >> 8) & 0xFF;
-	} else {
-		int newVal = ((_sfxVelocity << 2) ^ 0xff) * volume;
-		ptr[3] = (newVal >> 10) ^ 0x3f;
-		ptr[1] = newVal >> 11;
-	}	
+	if (volume != 0xff) {
+		if (_version >= 3) {
+			int newVal = ((((ptr[3]) + 63) * volume) >> 8) & 0xFF;
+			ptr[3] = -newVal + 63;
+			ptr[1] = ((ptr[1] * volume) >> 8) & 0xFF;
+		} else {
+			int newVal = ((_sfxVelocity << 2) ^ 0xff) * volume;
+			ptr[3] = (newVal >> 10) ^ 0x3f;
+			ptr[1] = newVal >> 11;
+		}
+	}
 }
 
 // A few words on opcode parsing and timing:
@@ -1368,7 +1372,10 @@ int AdLibDriver::update_setNoteSpacing(uint8 *&dataptr, Channel &channel, uint8
 int AdLibDriver::update_jump(uint8 *&dataptr, Channel &channel, uint8 value) {
 	--dataptr;
 	int16 add = READ_LE_UINT16(dataptr); dataptr += 2;
-	dataptr += add;
+	if (_version == 1)
+		dataptr = _soundData + add - 191;
+	else
+		dataptr += add;
 	if (_syncJumpMask & (1 << (&channel - _channels)))
 		channel.lock = true;
 	return 0;
@@ -1378,7 +1385,10 @@ int AdLibDriver::update_jumpToSubroutine(uint8 *&dataptr, Channel &channel, uint
 	--dataptr;
 	int16 add = READ_LE_UINT16(dataptr); dataptr += 2;
 	channel.dataptrStack[channel.dataptrStackPos++] = dataptr;
-	dataptr += add;
+	if (_version < 3)
+		dataptr = _soundData + add - 191;
+	else
+		dataptr += add;
 	return 0;
 }
 
@@ -2251,21 +2261,36 @@ const int SoundAdLibPC::_kyra1NumSoundTriggers = ARRAYSIZE(SoundAdLibPC::_kyra1S
 SoundAdLibPC::SoundAdLibPC(KyraEngine_v1 *vm, Audio::Mixer *mixer)
 	: Sound(vm, mixer), _driver(0), _trackEntries(), _soundDataPtr(0) {
 	memset(_trackEntries, 0, sizeof(_trackEntries));
-	_version = ((_vm->game() == GI_KYRA2) || (_vm->game() == GI_LOL && !_vm->gameFlags().isDemo)) ? 2 : 1;
-	_driver = new AdLibDriver(mixer, _version);
-	assert(_driver);
 
+	_soundTriggers = 0;
+	_numSoundTriggers = 0;
 	_sfxPlayingSound = -1;
 	_soundFileLoaded.clear();
 
-	if (_version == 1) {
+	switch (vm->game()) {
+	case GI_LOL:
+		_version = _vm->gameFlags().isDemo ? 3 : 4;
+		break;
+	case GI_KYRA2:
+		_version = 4;
+		break;
+	case GI_KYRA1:
+		_version = 3;
 		_soundTriggers = _kyra1SoundTriggers;
 		_numSoundTriggers = _kyra1NumSoundTriggers;
-	} else {
-		// TODO: Figure out if Kyra 2 uses sound triggers at all.
-		_soundTriggers = 0;
-		_numSoundTriggers = 0;
+		break;
+	case GI_EOB2:
+		_version = 2;
+		break;
+	case GI_EOB1:
+		_version = 1;
+		break;
+	default:
+		break;
 	}
+
+	_driver = new AdLibDriver(mixer, _version);
+	assert(_driver);
 }
 
 SoundAdLibPC::~SoundAdLibPC() {
@@ -2342,12 +2367,12 @@ void SoundAdLibPC::playSoundEffect(uint8 track, uint8 volume) {
 void SoundAdLibPC::play(uint8 track, uint8 volume) {
 	uint16 soundId = 0;
 
-	if (_version == 2)
+	if (_version == 4)
 		soundId = READ_LE_UINT16(&_trackEntries[track<<1]);
 	else
 		soundId = _trackEntries[track];
 
-	if ((soundId == 0xFFFF && _version == 2) || (soundId == 0xFF && _version < 2) || !_soundDataPtr)
+	if ((soundId == 0xFFFF && _version == 4) || (soundId == 0xFF && _version < 4) || !_soundDataPtr)
 		return;
 
 	_driver->queueTrack(soundId, volume);
@@ -2374,7 +2399,7 @@ void SoundAdLibPC::loadSoundFile(Common::String file) {
 }
 
 void SoundAdLibPC::internalLoadFile(Common::String file) {
-	file += ".ADL";
+	file += ((_version == 1) ? ".DAT" : ".ADL");
 	if (_soundFileLoaded == file)
 		return;
 
@@ -2398,7 +2423,7 @@ void SoundAdLibPC::internalLoadFile(Common::String file) {
 	int soundDataSize = fileSize;
 	uint8 *p = fileData;
 
-	if (_version == 2) {
+	if (_version == 4) {
 		memcpy(_trackEntries, p, 500);
 		p += 500;
 		soundDataSize -= 500;


Commit: 2bcae2451a9e5e59c2ad30e5c8560d9b8e117501
    https://github.com/scummvm/scummvm/commit/2bcae2451a9e5e59c2ad30e5c8560d9b8e117501
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:10-08:00

Commit Message:
KYRA: (AdLib Driver) - prevent squashing of sounds during halt track execution

This patch makes sure that the stopping track (track 0) does not squash sounds which get queued during the execution of the stopping track. This seems to be a hardware problem (original driver implementation not suitable for modern machines).

Changed paths:
    engines/kyra/sound_adlib.cpp



diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp
index 983d3b6..94a285d 100644
--- a/engines/kyra/sound_adlib.cpp
+++ b/engines/kyra/sound_adlib.cpp
@@ -360,13 +360,17 @@ private:
 	uint8 *_soundData;
 
 	struct QueueEntry {
+		QueueEntry() : data(0), id(0), volume(0) {}
+		QueueEntry(uint8 *ptr, uint8 track, uint8 vol) : data(ptr), id(track), volume(vol) {}
 		uint8 *data;
+		uint8 id;
 		uint8 volume;
 	};
 
 	QueueEntry _programQueue[16];
 	int _programStartTimeout;
 	int _programQueueStart, _programQueueEnd;
+	bool _retrySounds;
 
 	void adjustSfxData(uint8 *data, int volume);
 	uint8 *_sfxPointer;
@@ -450,6 +454,7 @@ AdLibDriver::AdLibDriver(Audio::Mixer *mixer, int version) {
 	_sfxPointer = 0;
 
 	_programQueueStart = _programQueueEnd = 0;
+	_retrySounds = false;
 }
 
 AdLibDriver::~AdLibDriver() {
@@ -545,8 +550,7 @@ void AdLibDriver::queueTrack(int track, int volume) {
 		return;
 	}
 
-	_programQueue[_programQueueEnd].data = trackData;
-	_programQueue[_programQueueEnd].volume = volume;
+	_programQueue[_programQueueEnd] = QueueEntry(trackData, track, volume);
 	_programQueueEnd = (_programQueueEnd + 1) & 15;
 }
 
@@ -570,6 +574,7 @@ void AdLibDriver::stopAllChannels() {
 		if (channel != 9)
 			noteOff(chan);
 	}
+	_retrySounds = false;
 }
 
 // timer callback
@@ -598,13 +603,25 @@ void AdLibDriver::setupPrograms() {
 		return;
 
 	uint8 *ptr = _programQueue[_programQueueStart].data;
-	// Clear the queue entry
-	_programQueue[_programQueueStart].data = 0;
-	_programQueueStart = (_programQueueStart + 1) & 15;
+
+	// The AdLib driver (in its old versions used for EOB) is not suitable for modern (fast) CPUs.
+	// The stop sound track (track 0 which has a priority of 50) will often still be busy when the
+	// next sound (with a lower priority) starts which will cause that sound to be skipped. We simply
+	// restart incoming sounds during stop sound execution.
+	// UPDATE: This stilly applies after introduction of the _programQueue.
+	QueueEntry retrySound;
+	if (_version < 3 && _programQueue[_programQueueStart].id == 0)
+		_retrySounds = true;
+	else if (_retrySounds)
+		retrySound = _programQueue[_programQueueStart];
 
 	// Adjust data in case we hit a sound effect.
 	adjustSfxData(ptr, _programQueue[_programQueueStart].volume);
 
+	// Clear the queue entry
+	_programQueue[_programQueueStart].data = 0;
+	_programQueueStart = (_programQueueStart + 1) & 15;
+
 	const int chan = *ptr++;
 	const int priority = *ptr++;
 
@@ -632,6 +649,13 @@ void AdLibDriver::setupPrograms() {
 		// This is (probably) required to assure that the sfx are started with
 		// the correct priority and velocity.
 		_programStartTimeout = 2;
+
+		retrySound = QueueEntry();
+	}
+
+	if (retrySound.data) {
+		debugC(9, kDebugLevelSound, "AdLibDriver::setupPrograms(): WORKAROUND - Restarting skipped sound %d)", retrySound.id);
+		queueTrack(retrySound.id, retrySound.volume);
 	}
 }
 


Commit: 814c78e84ea4d75b2ac3442227120d4d14e7b18b
    https://github.com/scummvm/scummvm/commit/814c78e84ea4d75b2ac3442227120d4d14e7b18b
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:10-08:00

Commit Message:
KYRA: (AdLib Driver) - fix queue handling for Eob

Huge numbers of sound effects get started as soon as a couple of monsters are around. If we start dropping sound when the queue is full, we won't have any sounds in these situations, but we'll get tons of useless warnings instead.

Changed paths:
    engines/kyra/sound_adlib.cpp



diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp
index 94a285d..e99990e 100644
--- a/engines/kyra/sound_adlib.cpp
+++ b/engines/kyra/sound_adlib.cpp
@@ -545,7 +545,9 @@ void AdLibDriver::queueTrack(int track, int volume) {
 	if (!trackData)
 		return;
 
-	if (_programQueueEnd == _programQueueStart && _programQueue[_programQueueEnd].data != 0) {
+	// Don't drop tracks in Eob. The queue is always full there if a couple of monsters are around.
+	// If we drop the incoming tracks we get no sound effects, but tons of warnings instead.
+	if (_version >= 3 && _programQueueEnd == _programQueueStart && _programQueue[_programQueueEnd].data != 0) {
 		warning("AdLibDriver: Program queue full, dropping track %d", track);
 		return;
 	}


Commit: 9feb674e1189f115e3a7d2cd052efd9ef3e5fba4
    https://github.com/scummvm/scummvm/commit/9feb674e1189f115e3a7d2cd052efd9ef3e5fba4
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:10-08:00

Commit Message:
KYRA: (EOB) - update kyradat tool

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/extract.cpp
    devtools/create_kyradat/extract.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index 627b517..5c923be 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -215,6 +215,247 @@ const ExtractFilename extractFilenames[] = {
 	{ k3ItemMagicTable, k3TypeRaw16to8, false },
 	{ k3ItemStringMap, kTypeRawData, false },
 
+	// EYE OF THE BEHOLDER COMMON
+	{ kEobBaseChargenStrings1, kTypeStringList, true },
+	{ kEobBaseChargenStrings2, kTypeStringList, true },
+	{ kEobBaseChargenStartLevels, kTypeRawData, false },
+	{ kEobBaseChargenStatStrings, kTypeStringList, true},
+	{ kEobBaseChargenRaceSexStrings, kTypeStringList, true },
+	{ kEobBaseChargenClassStrings, kTypeStringList, true },
+	{ kEobBaseChargenAlignmentStrings, kTypeStringList, true },
+	{ kEobBaseChargenEnterGameStrings, kTypeStringList, true },
+	{ kEobBaseChargenClassMinStats, k3TypeRaw16to8, false },
+	{ kEobBaseChargenRaceMinStats, k3TypeRaw16to8, false },
+	{ kEobBaseChargenRaceMaxStats, kLolTypeRaw16, false },
+
+	{ kEobBaseConstModTable1, kTypeRawData, false },
+	{ kEobBaseConstModTable2, kTypeRawData, false },
+	{ kEobBaseConstModTable3, kTypeRawData, false },
+	{ kEobBaseConstModTable4, kTypeRawData, false },
+	{ kEobBaseConstModLvlIndex, kTypeRawData, false },
+	{ kEobBaseConstModDiv, kTypeRawData, false },
+	{ kEobBaseConstModExt, kTypeRawData, false },
+
+	{ kEobBasePryDoorStrings, kTypeStringList, true },
+	{ kEobBaseWarningStrings, kTypeStringList, true },
+	{ kEobBaseItemSuffixStrings, kTypeStringList, true },
+	{ kEobBaseItemExtraStrings, kTypeStringList, true },
+	{ kEobBaseTakenStrings, kTypeStringList, true },
+	{ kEobBasePotionEffectStrings, kTypeStringList, true },
+
+	{ kEobBaseYesNoStrings, kTypeStringList, true },
+	{ kLolEobCommonMoreStrings, kTypeStringList, true },
+	{ kEobBaseNpcMaxStrings, kTypeStringList, true },
+	{ kEobBaseOkStrings, kTypeStringList, true },
+	{ kEobBaseNpcJoinStrings, kTypeStringList, true },
+	{ kEobBaseCancelStrings, kTypeStringList, true },
+	{ kEobBaseAbortStrings, kTypeStringList, true },
+
+	{ kEobBaseCharGuiStringsHp, kTypeStringList, true },
+	{ kEobBaseCharGuiStringsWp1, kTypeStringList, true },
+	{ kEobBaseCharGuiStringsWp2, kTypeStringList, true },
+	{ kEobBaseCharGuiStringsWr, kTypeStringList, true },
+	{ kEobBaseCharGuiStringsSt1, kTypeStringList, true },
+	{ kEobBaseCharGuiStringsSt2, kTypeStringList, true },
+	{ kEobBaseCharGuiStringsIn, kTypeStringList, true },
+
+	{ kEobBaseCharStatusStrings7, kTypeStringList, true },
+	{ kEobBaseCharStatusStrings81, kTypeStringList, true },
+	{ kEobBaseCharStatusStrings82, kTypeStringList, true },
+	{ kEobBaseCharStatusStrings9, kTypeStringList, true },
+	{ kEobBaseCharStatusStrings12, kTypeStringList, true },
+	{ kEobBaseCharStatusStrings131, kTypeStringList, true },
+	{ kEobBaseCharStatusStrings132, kTypeStringList, true },
+
+	{ kEobBaseLevelGainStrings, kTypeStringList, true },
+	{ kEobBaseExperienceTable0, kLolTypeRaw32, false },
+	{ kEobBaseExperienceTable1, kLolTypeRaw32, false },
+	{ kEobBaseExperienceTable2, kLolTypeRaw32, false },
+	{ kEobBaseExperienceTable3, kLolTypeRaw32, false },
+	{ kEobBaseExperienceTable4, kLolTypeRaw32, false },
+
+	{ kEobBaseWllFlagPreset, kTypeRawData, false },
+	{ kEobBaseDscShapeCoords, kLolTypeRaw16, false },
+	{ kEobBaseDscDoorScaleOffs, kTypeRawData, false },
+	{ kEobBaseDscDoorScaleMult1, kTypeRawData, false },
+	{ kEobBaseDscDoorScaleMult2, kTypeRawData, false },
+	{ kEobBaseDscDoorScaleMult3, kTypeRawData, false },
+	{ kEobBaseDscDoorScaleMult4, kTypeRawData, false },
+	{ kEobBaseDscDoorScaleMult5, kTypeRawData, false },
+	{ kEobBaseDscDoorScaleMult6, kTypeRawData, false },
+	{ kEobBaseDscDoorType5Offs, kTypeRawData, false },
+	{ kEobBaseDscDoorY1, kTypeRawData, false },
+	{ kEobBaseDscDoorY3, kTypeRawData, false },
+	{ kEobBaseDscDoorY4, kTypeRawData, false },
+	{ kEobBaseDscDoorY5, kTypeRawData, false },
+	{ kEobBaseDscDoorY6, kTypeRawData, false },
+	{ kEobBaseDscDoorCoordsExt, kLolTypeRaw16, false },
+
+	{ kEobBaseDscItemPosIndex, kTypeRawData, false },
+	{ kEobBaseDscItemShpX, kLolTypeRaw16, false },
+	{ kEobBaseDscItemPosUnk, kTypeRawData, false },
+	{ kEobBaseDscItemTileIndex, kTypeRawData, false },
+	{ kEobBaseDscItemShapeMap, kTypeRawData, false },
+	{ kEobBaseDscTelptrShpCoords, kTypeRawData, false },
+
+	{ kEobBaseDscMonsterFrmOffsTbl1, kTypeRawData, false },
+	{ kEobBaseDscMonsterFrmOffsTbl2, kTypeRawData, false },
+
+	{ kEobBaseInvSlotX, kLolTypeRaw16, false },
+	{ kEobBaseInvSlotY, kTypeRawData, false },
+	{ kEobBaseSlotValidationFlags, kLolTypeRaw16, false },
+	{ kEobBaseDrawObjPosIndex, kTypeRawData, false },
+	{ kEobBaseFlightObjFlipIndex, kTypeRawData, false },
+	{ kEobBaseFlightObjShpMap, kTypeRawData, false },
+	{ kEobBaseFlightObjSclIndex, kTypeRawData, false },
+
+	{ kEobBaseBookNumbers, kTypeStringList, true },
+	{ kEobBaseMageSpellsList, kTypeStringList, true },
+	{ kEobBaseClericSpellsList, kTypeStringList, true },
+	{ kEobBaseSpellNames, kTypeStringList, true },
+
+	{ kEobBaseMagicStrings1, kTypeStringList, true },
+	{ kEobBaseMagicStrings2, kTypeStringList, true },
+	{ kEobBaseMagicStrings3, kTypeStringList, true },
+	{ kEobBaseMagicStrings4, kTypeStringList, true },
+	{ kEobBaseMagicStrings5, kTypeStringList, false },
+	{ kEobBaseMagicStrings6, kTypeStringList, true },
+	{ kEobBaseMagicStrings7, kTypeStringList, true },
+	{ kEobBaseMagicStrings8, kTypeStringList, true },
+
+	{ kEobBaseSparkDefSteps, kTypeRawData, false },
+	{ kEobBaseSparkDefSubSteps, kTypeRawData, false },
+	{ kEobBaseSparkDefShift, kTypeRawData, false },
+	{ kEobBaseSparkDefAdd, kTypeRawData, false },
+	{ kEobBaseSparkDefX, k3TypeRaw16to8, false },
+	{ kEobBaseSparkDefY, kTypeRawData, false },
+	{ kEobBaseSparkOfFlags1, kLolTypeRaw32, false },
+	{ kEobBaseSparkOfFlags2, kLolTypeRaw32, false },
+	{ kEobBaseSparkOfShift, kTypeRawData, false },
+	{ kEobBaseSparkOfX, kTypeRawData, false },
+	{ kEobBaseSparkOfY, kTypeRawData, false },
+	{ kEobBaseSpellProperties, kTypeRawData, false },
+	{ kEobBaseMagicFlightProps, kTypeRawData, false },
+
+	// EYE OF THE BEHOLDER I
+	{ kEob1MainMenuStrings, kTypeStringList, true },
+	{ kEob1DoorShapeDefs, kTypeRawData, false },
+	{ kEob1DoorSwitchShapeDefs, kTypeRawData, false },
+	{ kEob1DoorSwitchCoords, kTypeRawData, false },
+	{ kEob1MonsterProperties, kTypeRawData, false },
+	{ kEob1MonsterDistAttType10, kTypeRawData, false },
+	{ kEob1MonsterDistAttSfx10, kTypeRawData, false },
+	{ kEob1MonsterDistAttType17, kTypeRawData, false },
+	{ kEob1MonsterDistAttSfx17, kTypeRawData, false },
+
+	// EYE OF THE BEHOLDER II
+	{ kEob2MainMenuStrings, kTypeStringList, true },
+
+	{ kEob2IntroStrings, k2TypeSfxList, true },
+	{ kEob2IntroCPSFiles, kTypeStringList, true },
+	{ kEob2IntroSeqData00, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData01, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData02, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData03, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData04, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData05, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData06, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData07, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData08, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData09, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData10, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData11, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData12, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData13, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData14, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData15, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData16, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData17, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData18, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData19, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData20, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData21, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData22, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData23, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData24, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData25, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData26, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData27, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData28, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData29, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData30, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData31, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData32, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData33, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData34, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData35, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData36, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData37, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData38, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData39, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData40, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData41, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData42, kEob2TypeSeqData, false },
+ 	{ kEob2IntroSeqData43, kEob2TypeSeqData, false },
+	{ kEob2IntroShapes00, kEob2TypeShapeData, false },
+ 	{ kEob2IntroShapes01, kEob2TypeShapeData, false },
+ 	{ kEob2IntroShapes04, kEob2TypeShapeData, false },
+ 	{ kEob2IntroShapes07, kEob2TypeShapeData, false },
+
+	{ kEob2FinaleStrings, k2TypeSfxList, true },
+	{ kEob2CreditsData, kTypeRawData, true },
+	{ kEob2FinaleCPSFiles, kTypeStringList, true },
+	{ kEob2FinaleSeqData00, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData01, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData02, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData03, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData04, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData05, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData06, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData07, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData08, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData09, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData10, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData11, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData12, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData13, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData14, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData15, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData16, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData17, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData18, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData19, kEob2TypeSeqData, false },
+ 	{ kEob2FinaleSeqData20, kEob2TypeSeqData, false },
+	{ kEob2FinaleShapes00, kEob2TypeShapeData, false },
+ 	{ kEob2FinaleShapes03, kEob2TypeShapeData, false },
+ 	{ kEob2FinaleShapes07, kEob2TypeShapeData, false },
+ 	{ kEob2FinaleShapes09, kEob2TypeShapeData, false },
+ 	{ kEob2FinaleShapes10, kEob2TypeShapeData, false },
+	{ kEob2NpcShapeData, kTypeRawData, false },
+	{ kEobBaseClassModifierFlags, kTypeRawData, false },
+	{ kEobBaseMonsterStepTable01, kTypeRawData, false },
+	{ kEobBaseMonsterStepTable02, kTypeRawData, false },
+	{ kEobBaseMonsterStepTable1, kTypeRawData, false },
+	{ kEobBaseMonsterStepTable2, k3TypeRaw16to8, false },
+	{ kEobBaseMonsterStepTable3, k3TypeRaw16to8, false },
+	{ kEobBaseMonsterCloseAttPosTable1, kTypeRawData, false },
+	{ kEobBaseMonsterCloseAttPosTable21, kTypeRawData, false },
+	{ kEobBaseMonsterCloseAttPosTable22, kTypeRawData, false },
+	{ kEobBaseMonsterCloseAttUnkTable, kTypeRawData, false },
+	{ kEobBaseMonsterCloseAttChkTable1, kTypeRawData, false },
+	{ kEobBaseMonsterCloseAttChkTable2, kTypeRawData, false },
+	{ kEobBaseMonsterCloseAttDstTable1, kTypeRawData, false },
+	{ kEobBaseMonsterCloseAttDstTable2, kTypeRawData, false },
+	{ kEobBaseMonsterProximityTable, kTypeRawData, false },
+	{ kEobBaseFindBlockMonstersTable, kTypeRawData, false },
+	{ kEobBaseMonsterDirChangeTable, kTypeRawData, false },
+	{ kEobBaseMonsterDistAttStrings, kTypeStringList, true },
+	{ kEobBaseEncodeMonsterDefs, kLolTypeRaw16, false },
+	{ kEobBaseNpcPresets, kEobTypeNpcData, false },
+	{ kEob2Npc1Strings, kTypeStringList, true },
+	{ kEob2Npc2Strings, kTypeStringList, true },
+	{ kEob2MonsterDustStrings, kTypeStringList, true },
+
 	// LANDS OF LORE
 
 	// Ingame
@@ -251,25 +492,25 @@ const ExtractFilename extractFilenames[] = {
 	{ kLolItemPrices, kLolTypeRaw16, false },
 	{ kLolStashSetup, kTypeRawData, false },
 
-	{ kLolDscUnk1, kTypeRawData, false },
-	{ kLolDscShapeIndex, kTypeRawData, false },
+	{ kLolDscWalls, kTypeRawData, false },
+	{ kLolEobCommonDscShapeIndex, kTypeRawData, false },
 	{ kLolDscOvlMap, kTypeRawData, false },
 	{ kLolDscScaleWidthData, kLolTypeRaw16, false },
 	{ kLolDscScaleHeightData, kLolTypeRaw16, false },
-	{ kLolDscX, kLolTypeRaw16, false },
+	{ kLolEobCommonDscX, kLolTypeRaw16, false },
 	{ kLolDscY, kTypeRawData, false },
-	{ kLolDscTileIndex, kTypeRawData, false },
-	{ kLolDscUnk2, kTypeRawData, false },
-	{ kLolDscDoorShapeIndex, kTypeRawData, false },
-	{ kLolDscDimData1, kTypeRawData, false },
-	{ kLolDscDimData2, kTypeRawData, false },
-	{ kLolDscBlockMap, kTypeRawData, false },
-	{ kLolDscDimMap, kTypeRawData, false },
+	{ kLolEobCommonDscTileIndex, kTypeRawData, false },
+	{ kLolEobCommonDscUnk2, kTypeRawData, false },
+	{ kLolEobCommonDscDoorShapeIndex, kTypeRawData, false },
+	{ kLolEobCommonDscDimData1, kTypeRawData, false },
+	{ kLolEobCommonDscDimData2, kTypeRawData, false },
+	{ kLolEobCommonDscBlockMap, kTypeRawData, false },
+	{ kLolEobCommonDscDimMap, kTypeRawData, false },
 	{ kLolDscDoorScale, kLolTypeRaw16, false },
 	{ kLolDscOvlIndex, k3TypeRaw16to8, false },
-	{ kLolDscBlockIndex, kTypeRawData, false },
+	{ kLolEobCommonDscBlockIndex, kTypeRawData, false },
 	{ kLolDscDoor4, kLolTypeRaw16, false },
-	{ kLolDscDoor1, kTypeRawData, false },
+	{ kLolEobCommonDscDoorY2, kTypeRawData, false },
 	{ kLolDscDoorX, kLolTypeRaw16, false },
 	{ kLolDscDoorY, kLolTypeRaw16, false },
 
@@ -326,7 +567,9 @@ const TypeTable gameTable[] = {
 	{ kKyra1, 0 },
 	{ kKyra2, 1 },
 	{ kKyra3, 2 },
-	{ kLol, 3 },
+	{ kEob1, 3 },
+	{ kEob2, 4 },
+	{ kLol, 5 },
 	{ -1, -1 }
 };
 
@@ -980,6 +1223,445 @@ const char *getIdString(const int id) {
 		return "k3ItemMagicTable";
 	case k3ItemStringMap:
 		return "k3ItemStringMap";
+	case kEobBaseChargenStrings1:
+		return "kEobBaseChargenStrings1";
+	case kEobBaseChargenStrings2:
+		return "kEobBaseChargenStrings2";
+	case kEobBaseChargenStartLevels:
+		return "kEobBaseChargenStartLevels";
+	case kEobBaseChargenStatStrings:
+		return "kEobBaseChargenStatStrings";
+	case kEobBaseChargenRaceSexStrings:
+		return "kEobBaseChargenRaceSexStrings";
+	case kEobBaseChargenClassStrings:
+		return "kEobBaseChargenClassStrings";
+	case kEobBaseChargenAlignmentStrings:
+		return "kEobBaseChargenAlignmentStrings";
+	case kEobBaseChargenEnterGameStrings:
+		return "kEobBaseChargenEnterGameStrings";
+	case kEobBaseChargenClassMinStats:
+		return "kEobBaseChargenClassMinStats";
+	case kEobBaseChargenRaceMinStats:
+		return "kEobBaseChargenRaceMinStats";
+	case kEobBaseChargenRaceMaxStats:
+		return "kEobBaseChargenRaceMaxStats";
+	case kEobBaseConstModTable1:
+		return "kEobBaseConstModTable1";
+	case kEobBaseConstModTable2:
+		return "kEobBaseConstModTable2";
+	case kEobBaseConstModTable3:
+		return "kEobBaseConstModTable3";
+	case kEobBaseConstModTable4:
+		return "kEobBaseConstModTable4";
+	case kEobBaseConstModLvlIndex:
+		return "kEobBaseConstModLvlIndex";
+	case kEobBaseConstModDiv:
+		return "kEobBaseConstModDiv";
+	case kEobBaseConstModExt:
+		return "kEobBaseConstModExt";
+	case kEobBasePryDoorStrings:
+		return "kEobBasePryDoorStrings";
+	case kEobBaseWarningStrings:
+		return "kEobBaseWarningStrings";
+	case kEobBaseItemSuffixStrings:
+		return "kEobBaseItemSuffixStrings";
+	case kEobBaseItemExtraStrings:
+		return "kEobBaseItemExtraStrings";
+	case kEobBaseTakenStrings:
+		return "kEobBaseTakenStrings";
+	case kEobBasePotionEffectStrings:
+		return "kEobBasePotionEffectStrings";
+	case kEobBaseYesNoStrings:
+		return "kEobBaseYesNoStrings";
+	case kLolEobCommonMoreStrings:
+		return "kLolEobCommonMoreStrings";
+	case kEobBaseNpcMaxStrings:
+		return "kEobBaseNpcMaxStrings";
+	case kEobBaseOkStrings:
+		return "kEobBaseOkStrings";
+	case kEobBaseNpcJoinStrings:
+		return "kEobBaseNpcJoinStrings";		
+	case kEobBaseCancelStrings:
+		return "kEobBaseCancelStrings";
+	case kEobBaseAbortStrings:
+		return "kEobBaseAbortStrings";
+	case kEobBaseCharGuiStringsHp:
+		return "kEobBaseCharGuiStringsHp";
+	case kEobBaseCharGuiStringsWp1:
+		return "kEobBaseCharGuiStringsWp1";
+	case kEobBaseCharGuiStringsWp2:
+		return "kEobBaseCharGuiStringsWp2";
+	case kEobBaseCharGuiStringsWr:
+		return "kEobBaseCharGuiStringsWr";
+	case kEobBaseCharGuiStringsSt1:
+		return "kEobBaseCharGuiStringsSt1";
+	case kEobBaseCharGuiStringsSt2:
+		return "kEobBaseCharGuiStringsSt2";
+	case kEobBaseCharGuiStringsIn:
+		return "kEobBaseCharGuiStringsIn";
+	case kEobBaseCharStatusStrings7:
+		return "kEobBaseCharStatusStrings7";
+	case kEobBaseCharStatusStrings81:
+		return "kEobBaseCharStatusStrings81";
+	case kEobBaseCharStatusStrings82:
+		return "kEobBaseCharStatusStrings82";
+	case kEobBaseCharStatusStrings9:
+		return "kEobBaseCharStatusStrings9";
+	case kEobBaseCharStatusStrings12:
+		return "kEobBaseCharStatusStrings12";
+	case kEobBaseCharStatusStrings131:
+		return "kEobBaseCharStatusStrings131";
+	case kEobBaseCharStatusStrings132:
+		return "kEobBaseCharStatusStrings132";
+	case kEobBaseLevelGainStrings:
+		return "kEobBaseLevelGainStrings";
+	case kEobBaseExperienceTable0:
+		return "kEobBaseExperienceTable0";
+	case kEobBaseExperienceTable1:
+		return "kEobBaseExperienceTable1";
+	case kEobBaseExperienceTable2:
+		return "kEobBaseExperienceTable2";
+	case kEobBaseExperienceTable3:
+		return "kEobBaseExperienceTable3";
+	case kEobBaseExperienceTable4:
+		return "kEobBaseExperienceTable4";
+	case kEobBaseWllFlagPreset:
+		return "kEobBaseWllFlagPreset";
+	case kEobBaseDscShapeCoords:
+		return "kEobBaseDscShapeCoords";
+	case kEobBaseDscDoorScaleOffs:
+		return "kEobBaseDscDoorScaleOffs";
+	case kEobBaseDscDoorScaleMult1:
+		return "kEobBaseDscDoorScaleMult1";
+	case kEobBaseDscDoorScaleMult2:
+		return "kEobBaseDscDoorScaleMult2";
+	case kEobBaseDscDoorScaleMult3:
+		return "kEobBaseDscDoorScaleMult3";
+	case kEobBaseDscDoorScaleMult4:
+		return "kEobBaseDscDoorScaleMult4";
+	case kEobBaseDscDoorScaleMult5:
+		return "kEobBaseDscDoorScaleMult5";
+	case kEobBaseDscDoorScaleMult6:
+		return "kEobBaseDscDoorScaleMult6";
+	case kEobBaseDscDoorType5Offs:
+		return "kEobBaseDscDoorType5Offs";
+	case kEobBaseDscDoorY1:
+		return "kEobBaseDscDoorY1";
+	case kEobBaseDscDoorY3:
+		return "kEobBaseDscDoorY3";
+	case kEobBaseDscDoorY4:
+		return "kEobBaseDscDoorY4";
+	case kEobBaseDscDoorY5:
+		return "kEobBaseDscDoorY5";
+	case kEobBaseDscDoorY6:
+		return "kEobBaseDscDoorY6";
+	case kEobBaseDscDoorCoordsExt:
+		return "kEobBaseDscDoorCoordsExt";
+	case kEobBaseDscItemPosIndex:
+		return "kEobBaseDscItemPosIndex";
+	case kEobBaseDscItemShpX:
+		return "kEobBaseDscItemShpX";
+	case kEobBaseDscItemPosUnk:
+		return "kEobBaseDscItemPosUnk";
+	case kEobBaseDscItemTileIndex:
+		return "kEobBaseDscItemTileIndex";
+	case kEobBaseDscItemShapeMap:
+		return "kEobBaseDscItemShapeMap";
+	case kEobBaseDscMonsterFrmOffsTbl1:
+		return "kEobBaseDscMonsterFrmOffsTbl1";
+	case kEobBaseDscMonsterFrmOffsTbl2:
+		return "kEobBaseDscMonsterFrmOffsTbl2";
+	case kEobBaseInvSlotX:
+		return "kEobBaseInvSlotX";
+	case kEobBaseInvSlotY:
+		return "kEobBaseInvSlotY";
+	case kEobBaseSlotValidationFlags:
+		return "kEobBaseSlotValidationFlags";
+	case kEobBaseDrawObjPosIndex:
+		return "kEobBaseDrawObjPosIndex";
+	case kEobBaseFlightObjFlipIndex:
+		return "kEobBaseFlightObjFlipIndex";
+	case kEobBaseFlightObjShpMap:
+		return "kEobBaseFlightObjShpMap";
+	case kEobBaseFlightObjSclIndex:
+		return "kEobBaseFlightObjSclIndex";
+	case kEobBaseDscTelptrShpCoords:
+		return "kEobBaseDscTelptrShpCoords";	
+	case kEobBaseBookNumbers:
+		return "kEobBaseBookNumbers";
+	case kEobBaseMageSpellsList:
+		return "kEobBaseMageSpellsList";
+	case kEobBaseClericSpellsList:
+		return "kEobBaseClericSpellsList";
+	case kEobBaseSpellNames:
+		return "kEobBaseSpellNames";
+
+	case kEobBaseMagicStrings1:
+		return "kEobBaseMagicStrings1";
+	case kEobBaseMagicStrings2:
+		return "kEobBaseMagicStrings2";
+	case kEobBaseMagicStrings3:
+		return "kEobBaseMagicStrings3";
+	case kEobBaseMagicStrings4:
+		return "kEobBaseMagicStrings4";
+	case kEobBaseMagicStrings5:
+		return "kEobBaseMagicStrings5";
+	case kEobBaseMagicStrings6:
+		return "kEobBaseMagicStrings6";
+	case kEobBaseMagicStrings7:
+		return "kEobBaseMagicStrings7";
+	case kEobBaseMagicStrings8:
+		return "kEobBaseMagicStrings8";
+	case kEobBaseSparkDefSteps:
+		return "kEobBaseSparkDefSteps";
+	case kEobBaseSparkDefSubSteps:
+		return "kEobBaseSparkDefSubSteps";
+	case kEobBaseSparkDefShift:
+		return "kEobBaseSparkDefShift";
+	case kEobBaseSparkDefAdd:
+		return "kEobBaseSparkDefAdd";
+	case kEobBaseSparkDefX:
+		return "kEobBaseSparkDefX";
+	case kEobBaseSparkDefY:
+		return "kEobBaseSparkDefY";
+	case kEobBaseSparkOfFlags1:
+		return "kEobBaseSparkOfFlags1";
+	case kEobBaseSparkOfFlags2:
+		return "kEobBaseSparkOfFlags2";
+	case kEobBaseSparkOfShift:
+		return "kEobBaseSparkOfShift";
+	case kEobBaseSparkOfX:
+		return "kEobBaseSparkOfX";
+	case kEobBaseSparkOfY:
+		return "kEobBaseSparkOfY";
+	case kEobBaseSpellProperties:
+		return "kEobBaseSpellProperties";
+	case kEobBaseMagicFlightProps:
+		return "kEobBaseMagicFlightProps";
+	case kEob1MainMenuStrings:
+		return "kEob1MainMenuStrings";
+	case kEob1DoorShapeDefs:
+		return "kEob1DoorShapeDefs";
+	case kEob1DoorSwitchCoords:
+		return "kEob1DoorSwitchCoords";
+	case kEob1MonsterProperties:
+		return "kEob1MonsterProperties";
+	case kEob1MonsterDistAttType10:
+		return "kEob1MonsterDistAttType10";
+	case kEob1MonsterDistAttSfx10:
+		return "kEob1MonsterDistAttSfx10";
+	case kEob1MonsterDistAttType17:
+		return "kEob1MonsterDistAttType17";
+	case kEob1MonsterDistAttSfx17:
+		return "kEob1MonsterDistAttSfx17";
+	case kEob2MainMenuStrings:
+		return "kEob2MainMenuStrings";
+	case kEob2IntroStrings:
+		return "kEob2IntroStrings";
+	case kEob2IntroCPSFiles:
+		return "kEob2IntroCPSFiles";
+	case kEob2IntroSeqData00:
+		return "kEob2IntroSeqData00";
+ 	case kEob2IntroSeqData01:
+		return "kEob2IntroSeqData01";
+ 	case kEob2IntroSeqData02:
+		return "kEob2IntroSeqData02";
+ 	case kEob2IntroSeqData03:
+		return "kEob2IntroSeqData03";
+ 	case kEob2IntroSeqData04:
+		return "kEob2IntroSeqData04";
+ 	case kEob2IntroSeqData05:
+		return "kEob2IntroSeqData05";
+ 	case kEob2IntroSeqData06:
+		return "kEob2IntroSeqData06";
+ 	case kEob2IntroSeqData07:
+		return "kEob2IntroSeqData07";
+ 	case kEob2IntroSeqData08:
+		return "kEob2IntroSeqData08";
+ 	case kEob2IntroSeqData09:
+		return "kEob2IntroSeqData09";
+ 	case kEob2IntroSeqData10:
+		return "kEob2IntroSeqData10";
+ 	case kEob2IntroSeqData11:
+		return "kEob2IntroSeqData11";
+ 	case kEob2IntroSeqData12:
+		return "kEob2IntroSeqData12";
+ 	case kEob2IntroSeqData13:
+		return "kEob2IntroSeqData13";
+ 	case kEob2IntroSeqData14:
+		return "kEob2IntroSeqData14";
+ 	case kEob2IntroSeqData15:
+		return "kEob2IntroSeqData15";
+ 	case kEob2IntroSeqData16:
+		return "kEob2IntroSeqData16";
+ 	case kEob2IntroSeqData17:
+		return "kEob2IntroSeqData17";
+ 	case kEob2IntroSeqData18:
+		return "kEob2IntroSeqData18";
+ 	case kEob2IntroSeqData19:
+		return "kEob2IntroSeqData19";
+ 	case kEob2IntroSeqData20:
+		return "kEob2IntroSeqData20";
+ 	case kEob2IntroSeqData21:
+		return "kEob2IntroSeqData21";
+ 	case kEob2IntroSeqData22:
+		return "kEob2IntroSeqData22";
+ 	case kEob2IntroSeqData23:
+		return "kEob2IntroSeqData23";
+ 	case kEob2IntroSeqData24:
+		return "kEob2IntroSeqData24";
+ 	case kEob2IntroSeqData25:
+		return "kEob2IntroSeqData25";
+ 	case kEob2IntroSeqData26:
+		return "kEob2IntroSeqData26";
+ 	case kEob2IntroSeqData27:
+		return "kEob2IntroSeqData27";
+ 	case kEob2IntroSeqData28:
+		return "kEob2IntroSeqData28";
+ 	case kEob2IntroSeqData29:
+		return "kEob2IntroSeqData29";
+ 	case kEob2IntroSeqData30:
+		return "kEob2IntroSeqData30";
+ 	case kEob2IntroSeqData31:
+		return "kEob2IntroSeqData31";
+ 	case kEob2IntroSeqData32:
+		return "kEob2IntroSeqData32";
+ 	case kEob2IntroSeqData33:
+		return "kEob2IntroSeqData33";
+ 	case kEob2IntroSeqData34:
+		return "kEob2IntroSeqData34";
+ 	case kEob2IntroSeqData35:
+		return "kEob2IntroSeqData35";
+ 	case kEob2IntroSeqData36:
+		return "kEob2IntroSeqData36";
+ 	case kEob2IntroSeqData37:
+		return "kEob2IntroSeqData37";
+ 	case kEob2IntroSeqData38:
+		return "kEob2IntroSeqData38";
+ 	case kEob2IntroSeqData39:
+		return "kEob2IntroSeqData39";
+ 	case kEob2IntroSeqData40:
+		return "kEob2IntroSeqData40";
+ 	case kEob2IntroSeqData41:
+		return "kEob2IntroSeqData41";
+ 	case kEob2IntroSeqData42:
+		return "kEob2IntroSeqData42";
+ 	case kEob2IntroSeqData43:
+		return "kEob2IntroSeqData43";
+ 	case kEob2IntroShapes00:
+		return "kEob2IntroShapes00";
+ 	case kEob2IntroShapes01:
+		return "kEob2IntroShapes01";
+ 	case kEob2IntroShapes04:
+		return "kEob2IntroShapes04";
+ 	case kEob2IntroShapes07:
+		return "kEob2IntroShapes07";
+	case kEob2FinaleStrings:
+		return "kEob2FinaleStrings";
+	case kEob2CreditsData:
+		return "kEob2CreditsData";
+	case kEob2FinaleCPSFiles:
+		return "kEob2FinaleCPSFiles";		
+ 	case kEob2FinaleSeqData00:
+		return "kEob2FinaleSeqData00";
+ 	case kEob2FinaleSeqData01:
+		return "kEob2FinaleSeqData01";
+ 	case kEob2FinaleSeqData02:
+		return "kEob2FinaleSeqData02";
+ 	case kEob2FinaleSeqData03:
+		return "kEob2FinaleSeqData03";
+ 	case kEob2FinaleSeqData04:
+		return "kEob2FinaleSeqData04";
+ 	case kEob2FinaleSeqData05:
+		return "kEob2FinaleSeqData05";
+ 	case kEob2FinaleSeqData06:
+		return "kEob2FinaleSeqData06";
+ 	case kEob2FinaleSeqData07:
+		return "kEob2FinaleSeqData07";
+ 	case kEob2FinaleSeqData08:
+		return "kEob2FinaleSeqData08";
+ 	case kEob2FinaleSeqData09:
+		return "kEob2FinaleSeqData09";
+ 	case kEob2FinaleSeqData10:
+		return "kEob2FinaleSeqData10";
+ 	case kEob2FinaleSeqData11:
+		return "kEob2FinaleSeqData11";
+ 	case kEob2FinaleSeqData12:
+		return "kEob2FinaleSeqData12";
+ 	case kEob2FinaleSeqData13:
+		return "kEob2FinaleSeqData13";
+ 	case kEob2FinaleSeqData14:
+		return "kEob2FinaleSeqData14";
+ 	case kEob2FinaleSeqData15:
+		return "kEob2FinaleSeqData15";
+ 	case kEob2FinaleSeqData16:
+		return "kEob2FinaleSeqData16";
+ 	case kEob2FinaleSeqData17:
+		return "kEob2FinaleSeqData17";
+ 	case kEob2FinaleSeqData18:
+		return "kEob2FinaleSeqData18";
+ 	case kEob2FinaleSeqData19:
+		return "kEob2FinaleSeqData19";
+ 	case kEob2FinaleSeqData20:
+		return "kEob2FinaleSeqData20";	
+ 	case kEob2FinaleShapes00:
+		return "kEob2FinaleShapes00";
+ 	case kEob2FinaleShapes03:
+		return "kEob2FinaleShapes03";
+ 	case kEob2FinaleShapes07:
+		return "kEob2FinaleShapes07";
+ 	case kEob2FinaleShapes09:
+		return "kEob2FinaleShapes09";
+ 	case kEob2FinaleShapes10:
+		return "kEob2FinaleShapes10";
+	case kEob2NpcShapeData:
+		return "kEob2NpcShapeData";
+	case kEobBaseClassModifierFlags:
+		return "kEobBaseClassModifierFlags";
+	case kEobBaseMonsterStepTable01:
+		return "kEobBaseMonsterStepTable01";
+	case kEobBaseMonsterStepTable02:
+		return "kEobBaseMonsterStepTable02";
+	case kEobBaseMonsterStepTable1:
+		return "kEobBaseMonsterStepTable1";
+	case kEobBaseMonsterStepTable2:
+		return "kEobBaseMonsterStepTable2";
+	case kEobBaseMonsterStepTable3:
+		return "kEobBaseMonsterStepTable3";
+	case kEobBaseMonsterCloseAttPosTable1:
+		return "kEobBaseMonsterCloseAttPosTable1";
+	case kEobBaseMonsterCloseAttPosTable21:
+		return "kEobBaseMonsterCloseAttPosTable21";
+	case kEobBaseMonsterCloseAttPosTable22:
+		return "kEobBaseMonsterCloseAttPosTable22";
+	case kEobBaseMonsterCloseAttUnkTable:
+		return "kEobBaseMonsterCloseAttUnkTable";
+	case kEobBaseMonsterCloseAttChkTable1:
+		return "kEobBaseMonsterCloseAttChkTable1";
+	case kEobBaseMonsterCloseAttChkTable2:
+		return "kEobBaseMonsterCloseAttChkTable2";
+	case kEobBaseMonsterCloseAttDstTable1:
+		return "kEobBaseMonsterCloseAttDstTable1";
+	case kEobBaseMonsterCloseAttDstTable2:
+		return "kEobBaseMonsterCloseAttDstTable2";
+	case kEobBaseMonsterProximityTable:
+		return "kEobBaseMonsterProximityTable";
+	case kEobBaseFindBlockMonstersTable:
+		return "kEobBaseFindBlockMonstersTable";
+	case kEobBaseMonsterDirChangeTable:
+		return "kEobBaseMonsterDirChangeTable";
+	case kEobBaseMonsterDistAttStrings:
+		return "kEobBaseMonsterDistAttStrings";
+	case kEobBaseEncodeMonsterDefs:
+		return "kEobBaseEncodeMonsterDefs";
+	case kEobBaseNpcPresets:
+		return "kEobBaseNpcPresets";
+	case kEob2Npc1Strings:
+		return "kEob2Npc1Strings";
+	case kEob2Npc2Strings:
+		return "kEob2Npc2Strings";
+	case kEob2MonsterDustStrings:
+		return "kEob2MonsterDustStrings";
 	case kLolIngamePakFiles:
 		return "kLolIngamePakFiles";
 	case kLolCharacterDefs:
@@ -1042,40 +1724,40 @@ const char *getIdString(const int id) {
 		return "kLolItemPrices";
 	case kLolStashSetup:
 		return "kLolStashSetup";
-	case kLolDscUnk1:
-		return "kLolDscUnk1";
-	case kLolDscShapeIndex:
-		return "kLolDscShapeIndex";
+	case kLolDscWalls:
+		return "kLolDscWalls";
+	case kLolEobCommonDscShapeIndex:
+		return "kLolEobCommonDscShapeIndex";
 	case kLolDscOvlMap:
 		return "kLolDscOvlMap";
 	case kLolDscScaleWidthData:
 		return "kLolDscScaleWidthData";
 	case kLolDscScaleHeightData:
 		return "kLolDscScaleHeightData";
-	case kLolDscX:
-		return "kLolDscX";
+	case kLolEobCommonDscX:
+		return "kLolEobCommonDscX";
 	case kLolDscY:
 		return "kLolDscY";
-	case kLolDscTileIndex:
-		return "kLolDscTileIndex";
-	case kLolDscUnk2:
-		return "kLolDscUnk2";
-	case kLolDscDoorShapeIndex:
-		return "kLolDscDoorShapeIndex";
-	case kLolDscDimData1:
-		return "kLolDscDimData1";
-	case kLolDscDimData2:
-		return "kLolDscDimData2";
-	case kLolDscBlockMap:
-		return "kLolDscBlockMap";
-	case kLolDscDimMap:
-		return "kLolDscDimMap";
+	case kLolEobCommonDscTileIndex:
+		return "kLolEobCommonDscTileIndex";
+	case kLolEobCommonDscUnk2:
+		return "kLolEobCommonDscUnk2";
+	case kLolEobCommonDscDoorShapeIndex:
+		return "kLolEobCommonDscDoorShapeIndex";
+	case kLolEobCommonDscDimData1:
+		return "kLolEobCommonDscDimData1";
+	case kLolEobCommonDscDimData2:
+		return "kLolEobCommonDscDimData2";
+	case kLolEobCommonDscBlockMap:
+		return "kLolEobCommonDscBlockMap";
+	case kLolEobCommonDscDimMap:
+		return "kLolEobCommonDscDimMap";
 	case kLolDscOvlIndex:
 		return "kLolDscOvlIndex";
-	case kLolDscBlockIndex:
-		return "kLolDscBlockIndex";
-	case kLolDscDoor1:
-		return "kLolDscDoor1";
+	case kLolEobCommonDscBlockIndex:
+		return "kLolEobCommonDscBlockIndex";
+	case kLolEobCommonDscDoorY2:
+		return "kLolEobCommonDscDoorY2";
 	case kLolDscDoorScale:
 		return "kLolDscDoorScale";
 	case kLolDscDoor4:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index cabf657..be40dff 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -179,6 +179,264 @@ enum kExtractID {
 	k3ItemMagicTable,
 	k3ItemStringMap,
 
+	kLolEobCommonMoreStrings,
+	kLolEobCommonDscShapeIndex,
+	kLolEobCommonDscX,
+	kLolEobCommonDscTileIndex,
+	kLolEobCommonDscUnk2,
+	kLolEobCommonDscDoorShapeIndex,
+	kLolEobCommonDscDimData1,
+	kLolEobCommonDscDimData2,
+	kLolEobCommonDscBlockMap,
+	kLolEobCommonDscDimMap,
+	kLolEobCommonDscDoorY2,
+	kLolEobCommonDscBlockIndex,
+
+	kEobBaseChargenStrings1,
+	kEobBaseChargenStrings2,
+	kEobBaseChargenStartLevels,
+	kEobBaseChargenStatStrings,
+	kEobBaseChargenRaceSexStrings,
+	kEobBaseChargenClassStrings,
+	kEobBaseChargenAlignmentStrings,
+	kEobBaseChargenEnterGameStrings,
+	kEobBaseChargenClassMinStats,
+	kEobBaseChargenRaceMinStats,
+	kEobBaseChargenRaceMaxStats,
+
+	kEobBaseConstModTable1,
+	kEobBaseConstModTable2,
+	kEobBaseConstModTable3,
+	kEobBaseConstModTable4,
+	kEobBaseConstModLvlIndex,
+	kEobBaseConstModDiv,
+	kEobBaseConstModExt,
+
+	kEobBasePryDoorStrings,
+	kEobBaseWarningStrings,
+	kEobBaseItemSuffixStrings,
+	kEobBaseItemExtraStrings,
+	kEobBaseTakenStrings,
+	kEobBasePotionEffectStrings,
+
+	kEobBaseYesNoStrings,
+	kEobBaseNpcMaxStrings,
+	kEobBaseOkStrings,
+	kEobBaseNpcJoinStrings,
+	kEobBaseCancelStrings,
+	kEobBaseAbortStrings,
+
+	kEobBaseCharGuiStringsHp,
+	kEobBaseCharGuiStringsWp1,
+	kEobBaseCharGuiStringsWp2,
+	kEobBaseCharGuiStringsWr,
+	kEobBaseCharGuiStringsSt1,
+	kEobBaseCharGuiStringsSt2,
+	kEobBaseCharGuiStringsIn,
+
+	kEobBaseCharStatusStrings7,
+	kEobBaseCharStatusStrings81,
+	kEobBaseCharStatusStrings82,
+	kEobBaseCharStatusStrings9,
+	kEobBaseCharStatusStrings12,
+	kEobBaseCharStatusStrings131,
+	kEobBaseCharStatusStrings132,
+
+	kEobBaseLevelGainStrings,
+	kEobBaseExperienceTable0,
+	kEobBaseExperienceTable1,
+	kEobBaseExperienceTable2,
+	kEobBaseExperienceTable3,
+	kEobBaseExperienceTable4,
+
+	kEobBaseClassModifierFlags,
+
+	kEobBaseMonsterStepTable01,
+	kEobBaseMonsterStepTable02,
+	kEobBaseMonsterStepTable1,
+	kEobBaseMonsterStepTable2,
+	kEobBaseMonsterStepTable3,
+	kEobBaseMonsterCloseAttPosTable1,
+	kEobBaseMonsterCloseAttPosTable21,
+	kEobBaseMonsterCloseAttPosTable22,
+	kEobBaseMonsterCloseAttUnkTable,
+	kEobBaseMonsterCloseAttChkTable1,
+	kEobBaseMonsterCloseAttChkTable2,
+	kEobBaseMonsterCloseAttDstTable1,
+	kEobBaseMonsterCloseAttDstTable2,
+
+	kEobBaseMonsterProximityTable,
+	kEobBaseFindBlockMonstersTable,
+	kEobBaseMonsterDirChangeTable,
+	kEobBaseMonsterDistAttStrings,
+
+	kEobBaseEncodeMonsterDefs,
+	kEobBaseNpcPresets,
+
+	kEobBaseWllFlagPreset,
+	kEobBaseDscShapeCoords,
+
+	kEobBaseDscDoorScaleOffs,
+	kEobBaseDscDoorScaleMult1,
+	kEobBaseDscDoorScaleMult2,
+	kEobBaseDscDoorScaleMult3,
+	kEobBaseDscDoorScaleMult4,
+	kEobBaseDscDoorScaleMult5,
+	kEobBaseDscDoorScaleMult6,
+	kEobBaseDscDoorType5Offs,
+	kEobBaseDscDoorY1,
+	kEobBaseDscDoorY3,
+	kEobBaseDscDoorY4,
+	kEobBaseDscDoorY5,
+	kEobBaseDscDoorY6,
+	kEobBaseDscDoorCoordsExt,
+
+	kEobBaseDscItemPosIndex,
+	kEobBaseDscItemShpX,
+	kEobBaseDscItemPosUnk,
+	kEobBaseDscItemTileIndex,
+	kEobBaseDscItemShapeMap,
+
+	kEobBaseDscMonsterFrmOffsTbl1,
+	kEobBaseDscMonsterFrmOffsTbl2,
+
+	kEobBaseInvSlotX,
+	kEobBaseInvSlotY,
+	kEobBaseSlotValidationFlags,
+	kEobBaseDrawObjPosIndex,
+	kEobBaseFlightObjFlipIndex,
+	kEobBaseFlightObjShpMap,
+	kEobBaseFlightObjSclIndex,
+
+	kEobBaseDscTelptrShpCoords,
+
+	kEobBaseBookNumbers,
+	kEobBaseMageSpellsList,
+	kEobBaseClericSpellsList,
+	kEobBaseSpellNames,
+	kEobBaseMagicStrings1,
+	kEobBaseMagicStrings2,
+	kEobBaseMagicStrings3,
+	kEobBaseMagicStrings4,
+	kEobBaseMagicStrings5,
+	kEobBaseMagicStrings6,
+	kEobBaseMagicStrings7,
+	kEobBaseMagicStrings8,
+
+	kEobBaseSparkDefSteps,
+	kEobBaseSparkDefSubSteps,
+	kEobBaseSparkDefShift,
+	kEobBaseSparkDefAdd,
+	kEobBaseSparkDefX,
+	kEobBaseSparkDefY,
+	kEobBaseSparkOfFlags1,
+	kEobBaseSparkOfFlags2,
+	kEobBaseSparkOfShift,
+	kEobBaseSparkOfX,
+	kEobBaseSparkOfY,
+
+	kEobBaseSpellProperties,
+	kEobBaseMagicFlightProps,
+
+	kEob1MainMenuStrings,
+	kEob1DoorShapeDefs,
+	kEob1DoorSwitchShapeDefs,
+	kEob1DoorSwitchCoords,
+	kEob1MonsterProperties,
+
+	kEob1MonsterDistAttType10,
+	kEob1MonsterDistAttSfx10,
+	kEob1MonsterDistAttType17,
+	kEob1MonsterDistAttSfx17,
+
+
+	kEob2MainMenuStrings,
+	kEob2IntroStrings,
+	kEob2IntroCPSFiles,
+	kEob2IntroSeqData00,
+ 	kEob2IntroSeqData01,
+ 	kEob2IntroSeqData02,
+ 	kEob2IntroSeqData03,
+ 	kEob2IntroSeqData04,
+ 	kEob2IntroSeqData05,
+ 	kEob2IntroSeqData06,
+ 	kEob2IntroSeqData07,
+ 	kEob2IntroSeqData08,
+ 	kEob2IntroSeqData09,
+ 	kEob2IntroSeqData10,
+ 	kEob2IntroSeqData11,
+ 	kEob2IntroSeqData12,
+ 	kEob2IntroSeqData13,
+ 	kEob2IntroSeqData14,
+ 	kEob2IntroSeqData15,
+ 	kEob2IntroSeqData16,
+ 	kEob2IntroSeqData17,
+ 	kEob2IntroSeqData18,
+ 	kEob2IntroSeqData19,
+ 	kEob2IntroSeqData20,
+ 	kEob2IntroSeqData21,
+ 	kEob2IntroSeqData22,
+ 	kEob2IntroSeqData23,
+ 	kEob2IntroSeqData24,
+ 	kEob2IntroSeqData25,
+ 	kEob2IntroSeqData26,
+ 	kEob2IntroSeqData27,
+ 	kEob2IntroSeqData28,
+ 	kEob2IntroSeqData29,
+ 	kEob2IntroSeqData30,
+ 	kEob2IntroSeqData31,
+ 	kEob2IntroSeqData32,
+ 	kEob2IntroSeqData33,
+ 	kEob2IntroSeqData34,
+ 	kEob2IntroSeqData35,
+ 	kEob2IntroSeqData36,
+ 	kEob2IntroSeqData37,
+ 	kEob2IntroSeqData38,
+ 	kEob2IntroSeqData39,
+ 	kEob2IntroSeqData40,
+ 	kEob2IntroSeqData41,
+ 	kEob2IntroSeqData42,
+ 	kEob2IntroSeqData43,
+	kEob2IntroShapes00,
+ 	kEob2IntroShapes01,
+ 	kEob2IntroShapes04,
+ 	kEob2IntroShapes07,
+
+	kEob2FinaleStrings,
+	kEob2CreditsData,
+	kEob2FinaleCPSFiles,
+	kEob2FinaleSeqData00,
+ 	kEob2FinaleSeqData01,
+ 	kEob2FinaleSeqData02,
+ 	kEob2FinaleSeqData03,
+ 	kEob2FinaleSeqData04,
+ 	kEob2FinaleSeqData05,
+ 	kEob2FinaleSeqData06,
+ 	kEob2FinaleSeqData07,
+ 	kEob2FinaleSeqData08,
+ 	kEob2FinaleSeqData09,
+ 	kEob2FinaleSeqData10,
+ 	kEob2FinaleSeqData11,
+ 	kEob2FinaleSeqData12,
+ 	kEob2FinaleSeqData13,
+ 	kEob2FinaleSeqData14,
+ 	kEob2FinaleSeqData15,
+ 	kEob2FinaleSeqData16,
+ 	kEob2FinaleSeqData17,
+ 	kEob2FinaleSeqData18,
+ 	kEob2FinaleSeqData19,
+ 	kEob2FinaleSeqData20,
+	kEob2FinaleShapes00,
+ 	kEob2FinaleShapes03,
+ 	kEob2FinaleShapes07,
+ 	kEob2FinaleShapes09,
+ 	kEob2FinaleShapes10,
+
+	kEob2NpcShapeData,
+	kEob2Npc1Strings,
+	kEob2Npc2Strings,
+	kEob2MonsterDustStrings,
+
 	kLolIngamePakFiles,
 	kLolCharacterDefs,
 	kLolIngameSfxFiles,
@@ -212,27 +470,17 @@ enum kExtractID {
 	kLolItemPrices,
 	kLolStashSetup,
 
-	kLolDscUnk1,
-	kLolDscShapeIndex,
+	kLolDscWalls,
 	kLolDscOvlMap,
 	kLolDscScaleWidthData,
 	kLolDscScaleHeightData,
-	kLolDscX,
 	kLolDscY,
-	kLolDscTileIndex,
-	kLolDscUnk2,
-	kLolDscDoorShapeIndex,
-	kLolDscDimData1,
-	kLolDscDimData2,
-	kLolDscBlockMap,
-	kLolDscDimMap,
-	kLolDscDoor1,
+
 	kLolDscDoorScale,
 	kLolDscDoor4,
 	kLolDscDoorX,
 	kLolDscDoorY,
-	kLolDscOvlIndex,
-	kLolDscBlockIndex,
+	kLolDscOvlIndex,	
 
 	kLolScrollXTop,
 	kLolScrollYTop,
@@ -284,7 +532,9 @@ enum kGame {
 	kKyra1 = 0,
 	kKyra2,
 	kKyra3,
-	kLol
+	kLol,
+	kEob1,
+	kEob2,
 };
 
 struct Game {
diff --git a/devtools/create_kyradat/extract.cpp b/devtools/create_kyradat/extract.cpp
index 371f2f4..c9ece82 100644
--- a/devtools/create_kyradat/extract.cpp
+++ b/devtools/create_kyradat/extract.cpp
@@ -52,6 +52,9 @@ bool extractRaw16(PAKFile &out, const ExtractInformation *info, const byte *data
 bool extractRaw32(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
 bool extractLolButtonDefs(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
 
+bool extractEob2SeqData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
+bool extractEob2ShapeData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
+bool extractEobNpcData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
 // Extraction type table
 
 const ExtractType extractTypeTable[] = {
@@ -81,6 +84,10 @@ const ExtractType extractTypeTable[] = {
 	{ kLolTypeRaw32, extractRaw32 },
 	{ kLolTypeButtonDef, extractLolButtonDefs },
 
+	{ kEob2TypeSeqData, extractEob2SeqData },
+	{ kEob2TypeShapeData, extractEob2ShapeData },
+	{ kEobTypeNpcData, extractEobNpcData },
+
 	{ -1, 0 }
 };
 
@@ -111,6 +118,9 @@ const TypeTable typeTable[] = {
 	{ kLolTypeSpellData, 9 },
 	{ kLolTypeCompassData, 10 },
 	{ kLolTypeFlightShpData, 11 },
+	{ kEob2TypeSeqData, 15 },
+	{ kEob2TypeShapeData, 16 },
+	{ kEobTypeNpcData, 17},
 	{ -1, 1 }
 };
 
@@ -1037,6 +1047,124 @@ bool extractLolButtonDefs(PAKFile &out, const ExtractInformation *info, const by
 	return out.addFile(filename, buffer, outsize);
 }
 
+bool extractEob2SeqData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) {
+	int num = size / 11;
+	uint8 *buffer = new uint8[size];
+	const uint8 *src = data;
+	uint8 *dst = buffer;
+
+	for (int i = 0; i < num; i++) {
+		memcpy(dst, src, 2);
+		src += 2; dst += 2;
+		WRITE_BE_UINT16(dst, READ_LE_UINT16(src));
+		src += 2; dst += 2;
+		memcpy(dst, src, 7);
+		src += 7; dst += 7;
+	}
+
+	return out.addFile(filename, buffer, size);
+}
+
+bool extractEob2ShapeData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) {
+	int num = size / 6;
+	uint8 *buffer = new uint8[size];
+	const uint8 *src = data;
+	uint8 *dst = buffer;
+
+	for (int i = 0; i < num; i++) {
+		WRITE_BE_UINT16(dst, READ_LE_UINT16(src));
+		src += 2; dst += 2;
+		memcpy(dst, src, 4);
+		src += 4; dst += 4;
+	}
+
+	return out.addFile(filename, buffer, size);
+}
+
+bool extractEobNpcData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) {
+	// We use one extraction routine for both EOB 1 and EOB 2 (in spite of the data format differences)
+	// since it is easy enough to generate a common output usable by both engines
+	
+	uint8 *buffer = 0;
+	uint32 outsize = 0;
+	
+	if (info->game == kEob1) {
+		uint16 num = size / 243;
+		outsize = num * 111 + 2;
+		buffer = new uint8[outsize];
+		const uint8 *src = data;
+		uint8 *dst = buffer;
+
+		WRITE_BE_UINT16(dst, num);
+		dst += 2;
+
+		for (int i = 0; i < num; i++) {
+			memcpy(dst, src, 27);
+			src += 27; dst += 27;
+			WRITE_BE_UINT16(dst, *src++);
+			dst += 2;
+			WRITE_BE_UINT16(dst, *src++);
+			dst += 2;
+			memcpy(dst, src, 10);
+			src += 10; dst += 10;
+			WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
+			src += 4; dst += 4;
+			WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
+			src += 4; dst += 4;
+			WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
+			src += 4; dst += 4;
+			// skipping lots of zero space
+			src += 60;
+			WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
+			src += 4; dst += 4;
+			for (int ii = 0; ii < 27; ii++) {
+				WRITE_BE_UINT16(dst, READ_LE_UINT16(src));
+				src += 2; dst += 2;
+			}			
+			// skipping more zero space
+			src += 70;
+		}
+	} else {
+		uint16 num = size / 345;
+		outsize = num * 111 + 2;
+		buffer = new uint8[outsize];
+		const uint8 *src = data;
+		uint8 *dst = buffer;
+
+		WRITE_BE_UINT16(dst, num);
+		dst += 2;
+
+		for (int i = 0; i < num; i++) {
+			memcpy(dst, src, 27);
+			src += 27; dst += 27;
+			WRITE_BE_UINT16(dst, READ_LE_UINT16(src));
+			src += 2; dst += 2;
+			WRITE_BE_UINT16(dst, READ_LE_UINT16(src));
+			src += 2; dst += 2;
+			memcpy(dst, src, 10);
+			src += 10; dst += 10;
+			WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
+			src += 4; dst += 4;
+			WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
+			src += 4; dst += 4;
+			WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
+			src += 4; dst += 4;
+			// skipping lots of zero space
+			src += 164;
+			WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
+			src += 4; dst += 4;
+			for (int ii = 0; ii < 27; ii++) {
+				WRITE_BE_UINT16(dst, READ_LE_UINT16(src));
+				src += 2; dst += 2;
+			}
+			// skipping more zero space
+			src += 70;
+		}
+	}
+
+	return out.addFile(filename, buffer, outsize);
+}
+
 bool extractMrShapeAnimData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) {
 	int outsize = 1;
 	uint8 *buffer = new uint8[size + 1];
diff --git a/devtools/create_kyradat/extract.h b/devtools/create_kyradat/extract.h
index a449274..c91e5de 100644
--- a/devtools/create_kyradat/extract.h
+++ b/devtools/create_kyradat/extract.h
@@ -53,7 +53,11 @@ enum kExtractType {
 	kLolTypeCharData,
 	kLolTypeSpellData,
 	kLolTypeCompassData,
-	kLolTypeFlightShpData
+	kLolTypeFlightShpData,
+
+	kEob2TypeSeqData,
+	kEob2TypeShapeData,
+	kEobTypeNpcData
 };
 
 struct ExtractInformation {
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 86f3535..8e410dc 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -96,6 +96,18 @@ const Game kyra3Games[] = {
 	GAME_DUMMY_ENTRY
 };
 
+const Game eob1Games[] = {
+	{ kEob1, { EN_ANY, -1, -1 }, kPlatformPC, kNoSpecial, { "1bde1dd37b40ab6de8ad11be33a44c5a", 0 } },
+	{ kEob1, { DE_DEU, -1, -1 }, kPlatformPC, kNoSpecial, { "0fa3c6e00a81171b9f2adb3fdeb8eea3", 0 } },
+	GAME_DUMMY_ENTRY
+};
+
+const Game eob2Games[] = {
+	{ kEob2, { EN_ANY, -1, -1 }, kPlatformPC, kNoSpecial, { "e006d031c2d854f748947f777e0c59b0", 0 } },
+	{ kEob2, { DE_DEU, -1, -1 }, kPlatformPC, kNoSpecial, { "6c6c4168deb2a4cb3dee3f1be2d39746", 0 } },
+	GAME_DUMMY_ENTRY
+};
+
 const Game lolGames[] = {
 	// DOS demo
 	{ kLol, { EN_ANY, -1, -1 }, kPlatformPC, kDemoVersion, { "30bb5af87d38adb47d3e6ce06b1cb042", 0 } },
@@ -122,6 +134,8 @@ const Game * const gameDescs[] = {
 	kyra2Games,
 	kyra3Games,
 	lolGames,
+	eob1Games,
+	eob2Games,
 	0
 };
 
@@ -505,7 +519,6 @@ const int kyra1TownsNeed[] = {
 	k1ConfigStrings,
 
 	k1TownsMusicFadeTable,
-	k1TownsMusicFadeTable,
 	k1TownsSFXwdTable,
 	k1TownsSFXbtTable,
 	k1TownsCDATable,
@@ -796,23 +809,23 @@ const int lolFloppyNeed[] = {
 	kLolLevelDatList,
 	kLolCompassDefs,
 	kLolStashSetup,
-	kLolDscUnk1,
-	kLolDscShapeIndex,
+	kLolDscWalls,
+	kLolEobCommonDscShapeIndex,
 	kLolDscOvlMap,
 	kLolDscScaleWidthData,
 	kLolDscScaleHeightData,
-	kLolDscX,
+	kLolEobCommonDscX,
 	kLolDscY,
-	kLolDscTileIndex,
-	kLolDscUnk2,
-	kLolDscDoorShapeIndex,
-	kLolDscDimData1,
-	kLolDscDimData2,
-	kLolDscBlockMap,
-	kLolDscDimMap,
+	kLolEobCommonDscTileIndex,
+	kLolEobCommonDscUnk2,
+	kLolEobCommonDscDoorShapeIndex,
+	kLolEobCommonDscDimData1,
+	kLolEobCommonDscDimData2,
+	kLolEobCommonDscBlockMap,
+	kLolEobCommonDscDimMap,
 	kLolDscOvlIndex,
-	kLolDscBlockIndex,
-	kLolDscDoor1,
+	kLolEobCommonDscBlockIndex,
+	kLolEobCommonDscDoorY2,
 	kLolDscDoorScale,
 	kLolDscDoor4,
 	kLolDscDoorX,
@@ -876,23 +889,23 @@ const int lolPC98Need[] = {
 	kLolLevelDatList,
 	kLolCompassDefs,
 	kLolStashSetup,
-	kLolDscUnk1,
-	kLolDscShapeIndex,
+	kLolDscWalls,
+	kLolEobCommonDscShapeIndex,
 	kLolDscOvlMap,
 	kLolDscScaleWidthData,
 	kLolDscScaleHeightData,
-	kLolDscX,
+	kLolEobCommonDscX,
 	kLolDscY,
-	kLolDscTileIndex,
-	kLolDscUnk2,
-	kLolDscDoorShapeIndex,
-	kLolDscDimData1,
-	kLolDscDimData2,
-	kLolDscBlockMap,
-	kLolDscDimMap,
+	kLolEobCommonDscTileIndex,
+	kLolEobCommonDscUnk2,
+	kLolEobCommonDscDoorShapeIndex,
+	kLolEobCommonDscDimData1,
+	kLolEobCommonDscDimData2,
+	kLolEobCommonDscBlockMap,
+	kLolEobCommonDscDimMap,
 	kLolDscOvlIndex,
-	kLolDscBlockIndex,
-	kLolDscDoor1,
+	kLolEobCommonDscBlockIndex,
+	kLolEobCommonDscDoorY2,
 	kLolDscDoorScale,
 	kLolDscDoor4,
 	kLolDscDoorX,
@@ -961,23 +974,23 @@ const int lolCDNeed[] = {
 	kLolCompassDefs,
 	kLolItemPrices,
 	kLolStashSetup,
-	kLolDscUnk1,
-	kLolDscShapeIndex,
+	kLolDscWalls,
+	kLolEobCommonDscShapeIndex,
 	kLolDscOvlMap,
 	kLolDscScaleWidthData,
 	kLolDscScaleHeightData,
-	kLolDscX,
+	kLolEobCommonDscX,
 	kLolDscY,
-	kLolDscTileIndex,
-	kLolDscUnk2,
-	kLolDscDoorShapeIndex,
-	kLolDscDimData1,
-	kLolDscDimData2,
-	kLolDscBlockMap,
-	kLolDscDimMap,
+	kLolEobCommonDscTileIndex,
+	kLolEobCommonDscUnk2,
+	kLolEobCommonDscDoorShapeIndex,
+	kLolEobCommonDscDimData1,
+	kLolEobCommonDscDimData2,
+	kLolEobCommonDscBlockMap,
+	kLolEobCommonDscDimMap,
 	kLolDscOvlIndex,
-	kLolDscBlockIndex,
-	kLolDscDoor1,
+	kLolEobCommonDscBlockIndex,
+	kLolEobCommonDscDoorY2,
 	kLolDscDoorScale,
 	kLolDscDoor4,
 	kLolDscDoorX,
@@ -1020,6 +1033,402 @@ const int lolDemoNeed[] = {
 	-1
 };
 
+const int eob1FloppyNeed[] = {
+	kEobBaseChargenStrings1,
+	kEobBaseChargenStrings2,
+	kEobBaseChargenStartLevels,
+	kEobBaseChargenStatStrings,
+	kEobBaseChargenRaceSexStrings,
+	kEobBaseChargenClassStrings,
+	kEobBaseChargenAlignmentStrings,
+	kEobBaseChargenEnterGameStrings,
+	kEobBaseChargenClassMinStats,
+	kEobBaseChargenRaceMinStats,
+	kEobBaseChargenRaceMaxStats,
+
+	kEobBaseConstModTable1,
+	kEobBaseConstModTable2,
+	kEobBaseConstModTable3,
+	kEobBaseConstModTable4,
+	kEobBaseConstModLvlIndex,
+	kEobBaseConstModDiv,
+	kEobBaseConstModExt,
+
+	kEob1MainMenuStrings,
+	kEob1DoorShapeDefs,
+	kEob1DoorSwitchShapeDefs,
+	kEob1DoorSwitchCoords,
+	kEob1MonsterProperties,
+	kEob1MonsterDistAttType10,
+	kEob1MonsterDistAttSfx10,
+	kEob1MonsterDistAttType17,
+	kEob1MonsterDistAttSfx17,
+
+	kEobBasePryDoorStrings,
+	kEobBaseWarningStrings,
+	kEobBaseItemSuffixStrings,
+	kEobBaseItemExtraStrings,
+	kEobBaseTakenStrings,
+	kEobBasePotionEffectStrings,
+
+	kEobBaseYesNoStrings,
+	kLolEobCommonMoreStrings,
+	kEobBaseNpcMaxStrings,
+	kEobBaseNpcJoinStrings,
+	kEobBaseCancelStrings,
+
+	kEobBaseCharGuiStringsHp,
+	kEobBaseCharGuiStringsWp1,
+	kEobBaseCharGuiStringsWr,
+	kEobBaseCharGuiStringsSt1,
+	kEobBaseCharGuiStringsIn,
+
+	kEobBaseCharStatusStrings7,
+	kEobBaseCharStatusStrings81,
+	kEobBaseCharStatusStrings9,
+	kEobBaseCharStatusStrings131,
+
+	kEobBaseLevelGainStrings,
+	kEobBaseExperienceTable0,
+	kEobBaseExperienceTable1,
+	kEobBaseExperienceTable2,
+	kEobBaseExperienceTable3,
+	kEobBaseExperienceTable4,
+
+	kEobBaseBookNumbers,
+	kEobBaseMageSpellsList,
+	kEobBaseClericSpellsList,
+	kEobBaseSpellNames,
+	kEobBaseMagicStrings1,
+	kEobBaseMagicStrings2,
+	kEobBaseMagicStrings3,
+	kEobBaseMagicStrings4,
+	kEobBaseMagicStrings5,
+	kEobBaseMagicStrings6,
+	kEobBaseMagicStrings7,
+	kEobBaseMagicStrings8,
+
+	kEobBaseSparkDefSteps,
+	kEobBaseSparkDefSubSteps,
+	kEobBaseSparkDefShift,
+	kEobBaseSparkDefAdd,
+	kEobBaseSparkDefX,
+	kEobBaseSparkDefY,
+	kEobBaseSparkOfFlags1,
+	kEobBaseSparkOfFlags2,
+	kEobBaseSparkOfShift,
+	kEobBaseSparkOfX,
+	kEobBaseSparkOfY,
+
+	kEobBaseSpellProperties,
+	kEobBaseMagicFlightProps,
+
+	kLolEobCommonDscDoorShapeIndex,
+	kEobBaseWllFlagPreset,
+	kEobBaseDscShapeCoords,
+	kEobBaseDscDoorScaleOffs,
+	kEobBaseDscDoorScaleMult1,
+	kEobBaseDscDoorScaleMult2,
+	kEobBaseDscDoorScaleMult3,
+	kEobBaseDscDoorScaleMult4,
+	kEobBaseDscDoorScaleMult5,
+	kEobBaseDscDoorScaleMult6,
+	kEobBaseDscDoorY1,
+	kLolEobCommonDscDoorY2,
+	kEobBaseDscDoorY3,
+	kEobBaseDscDoorY4,
+	kEobBaseDscDoorY5,
+	kEobBaseDscDoorY6,
+	kEobBaseDscDoorCoordsExt,
+
+	kEobBaseDscItemPosIndex,
+	kEobBaseDscItemShpX,
+	kEobBaseDscItemPosUnk,
+	kEobBaseDscItemTileIndex,
+	kEobBaseDscItemShapeMap,
+	kEobBaseDscTelptrShpCoords,
+
+	kEobBaseDscMonsterFrmOffsTbl1,
+	kEobBaseDscMonsterFrmOffsTbl2,
+
+	kEobBaseInvSlotX,
+	kEobBaseInvSlotY,
+	kEobBaseSlotValidationFlags,
+	kEobBaseDrawObjPosIndex,
+	kEobBaseFlightObjFlipIndex,
+	kEobBaseFlightObjShpMap,
+	kEobBaseFlightObjSclIndex,
+
+	kLolEobCommonDscShapeIndex,
+	kLolEobCommonDscX,
+	kLolEobCommonDscTileIndex,
+	kLolEobCommonDscUnk2,	
+	kLolEobCommonDscDimData1,
+	kLolEobCommonDscDimData2,
+	kLolEobCommonDscBlockMap,
+	kLolEobCommonDscDimMap,	
+	kLolEobCommonDscBlockIndex,
+
+	kEobBaseClassModifierFlags,
+
+	kEobBaseMonsterStepTable01,
+	//kEobBaseMonsterStepTable1,
+	kEobBaseMonsterStepTable2,
+	kEobBaseMonsterStepTable3,
+	kEobBaseMonsterCloseAttPosTable1,
+	kEobBaseMonsterCloseAttPosTable21,
+	//kEobBaseMonsterCloseAttUnkTable,
+	kEobBaseMonsterCloseAttChkTable1,
+	kEobBaseMonsterCloseAttChkTable2,
+	kEobBaseMonsterCloseAttDstTable1,
+	kEobBaseMonsterCloseAttDstTable2,
+
+	kEobBaseMonsterProximityTable,
+	kEobBaseFindBlockMonstersTable,
+	kEobBaseMonsterDirChangeTable,
+	kEobBaseMonsterDistAttStrings,
+	kEobBaseEncodeMonsterDefs,
+	kEobBaseNpcPresets,
+	//kEob1Npc1Strings,
+	//kEob1Npc2Strings,
+	-1
+};
+
+const int eob2FloppyNeed[] = {
+	kEobBaseChargenStrings1,
+	kEobBaseChargenStrings2,
+	kEobBaseChargenStartLevels,
+	kEobBaseChargenStatStrings,
+	kEobBaseChargenRaceSexStrings,
+	kEobBaseChargenClassStrings,
+	kEobBaseChargenAlignmentStrings,
+	kEobBaseChargenEnterGameStrings,
+	kEobBaseChargenClassMinStats,
+	kEobBaseChargenRaceMinStats,
+	kEobBaseChargenRaceMaxStats,
+
+	kEobBaseConstModTable1,
+	kEobBaseConstModTable2,
+	kEobBaseConstModTable3,
+	kEobBaseConstModTable4,
+	kEobBaseConstModLvlIndex,
+	kEobBaseConstModDiv,
+	kEobBaseConstModExt,
+
+	kEobBasePryDoorStrings,
+	kEobBaseWarningStrings,
+	kEobBaseItemSuffixStrings,
+	kEobBaseItemExtraStrings,
+	kEobBaseTakenStrings,
+	kEobBasePotionEffectStrings,
+
+	kEobBaseYesNoStrings,
+	kLolEobCommonMoreStrings,
+	kEobBaseNpcMaxStrings,
+	kEobBaseOkStrings,
+	kEobBaseNpcJoinStrings,
+	kEobBaseCancelStrings,
+	kEobBaseAbortStrings,
+
+	kEobBaseCharGuiStringsHp,
+	kEobBaseCharGuiStringsWp2,
+	kEobBaseCharGuiStringsWr,
+	kEobBaseCharGuiStringsSt2,
+	kEobBaseCharGuiStringsIn,
+
+	kEobBaseCharStatusStrings7,
+	kEobBaseCharStatusStrings82,
+	kEobBaseCharStatusStrings9,
+	kEobBaseCharStatusStrings12,
+	kEobBaseCharStatusStrings132,
+
+	kEobBaseLevelGainStrings,
+	kEobBaseExperienceTable0,
+	kEobBaseExperienceTable1,
+	kEobBaseExperienceTable2,
+	kEobBaseExperienceTable3,
+	kEobBaseExperienceTable4,
+
+	kEobBaseBookNumbers,
+	kEobBaseMageSpellsList,
+	kEobBaseClericSpellsList,
+	kEobBaseSpellNames,
+	kEobBaseMagicStrings1,
+	kEobBaseMagicStrings2,
+	kEobBaseMagicStrings3,
+	kEobBaseMagicStrings4,
+	kEobBaseMagicStrings5,
+	kEobBaseMagicStrings6,
+	kEobBaseMagicStrings7,
+	kEobBaseMagicStrings8,
+
+	kEobBaseSparkDefSteps,
+	kEobBaseSparkDefSubSteps,
+	kEobBaseSparkDefShift,
+	kEobBaseSparkDefAdd,
+	kEobBaseSparkDefX,
+	kEobBaseSparkDefY,
+	kEobBaseSparkOfFlags1,
+	kEobBaseSparkOfFlags2,
+	kEobBaseSparkOfShift,
+	kEobBaseSparkOfX,
+	kEobBaseSparkOfY,
+
+	kEobBaseSpellProperties,
+	kEobBaseMagicFlightProps,
+
+	kLolEobCommonDscDoorShapeIndex,
+	kEobBaseWllFlagPreset,
+	kEobBaseDscShapeCoords,
+
+	kEobBaseDscDoorScaleOffs,
+	kEobBaseDscDoorScaleMult1,
+	kEobBaseDscDoorScaleMult2,
+	kEobBaseDscDoorScaleMult3,
+	kEobBaseDscDoorType5Offs,
+	kEobBaseDscDoorY1,
+	kLolEobCommonDscDoorY2,
+
+	kEobBaseDscItemPosIndex,
+	kEobBaseDscItemShpX,
+	kEobBaseDscItemPosUnk,
+	kEobBaseDscItemTileIndex,
+	kEobBaseDscItemShapeMap,
+	kEobBaseDscTelptrShpCoords,
+
+	kEobBaseDscMonsterFrmOffsTbl1,
+	kEobBaseDscMonsterFrmOffsTbl2,
+
+	kEobBaseInvSlotX,
+	kEobBaseInvSlotY,
+	kEobBaseSlotValidationFlags,
+	kEobBaseDrawObjPosIndex,
+	kEobBaseFlightObjFlipIndex,
+	kEobBaseFlightObjShpMap,
+	kEobBaseFlightObjSclIndex,
+
+	kEob2MainMenuStrings,
+
+	kEob2IntroStrings,
+	kEob2IntroCPSFiles,
+	kEob2IntroSeqData00,
+ 	kEob2IntroSeqData01,
+ 	kEob2IntroSeqData02,
+ 	kEob2IntroSeqData03,
+ 	kEob2IntroSeqData04,
+ 	kEob2IntroSeqData05,
+ 	kEob2IntroSeqData06,
+ 	kEob2IntroSeqData07,
+ 	kEob2IntroSeqData08,
+ 	kEob2IntroSeqData09,
+ 	kEob2IntroSeqData10,
+ 	kEob2IntroSeqData11,
+ 	kEob2IntroSeqData12,
+ 	kEob2IntroSeqData13,
+ 	kEob2IntroSeqData14,
+ 	kEob2IntroSeqData15,
+ 	kEob2IntroSeqData16,
+ 	kEob2IntroSeqData17,
+ 	kEob2IntroSeqData18,
+ 	kEob2IntroSeqData19,
+ 	kEob2IntroSeqData20,
+ 	kEob2IntroSeqData21,
+ 	kEob2IntroSeqData22,
+ 	kEob2IntroSeqData23,
+ 	kEob2IntroSeqData24,
+ 	kEob2IntroSeqData25,
+ 	kEob2IntroSeqData26,
+ 	kEob2IntroSeqData27,
+ 	kEob2IntroSeqData28,
+ 	kEob2IntroSeqData29,
+ 	kEob2IntroSeqData30,
+ 	kEob2IntroSeqData31,
+ 	kEob2IntroSeqData32,
+ 	kEob2IntroSeqData33,
+ 	kEob2IntroSeqData34,
+ 	kEob2IntroSeqData35,
+ 	kEob2IntroSeqData36,
+ 	kEob2IntroSeqData37,
+ 	kEob2IntroSeqData38,
+ 	kEob2IntroSeqData39,
+ 	kEob2IntroSeqData40,
+ 	kEob2IntroSeqData41,
+ 	kEob2IntroSeqData42,
+ 	kEob2IntroSeqData43,
+
+	kEob2IntroShapes00,
+ 	kEob2IntroShapes01,
+ 	kEob2IntroShapes04,
+ 	kEob2IntroShapes07,
+
+	kEob2FinaleStrings,
+	kEob2CreditsData,
+	kEob2FinaleCPSFiles,
+	kEob2FinaleSeqData00,
+ 	kEob2FinaleSeqData01,
+ 	kEob2FinaleSeqData02,
+ 	kEob2FinaleSeqData03,
+ 	kEob2FinaleSeqData04,
+ 	kEob2FinaleSeqData05,
+ 	kEob2FinaleSeqData06,
+ 	kEob2FinaleSeqData07,
+ 	kEob2FinaleSeqData08,
+ 	kEob2FinaleSeqData09,
+ 	kEob2FinaleSeqData10,
+ 	kEob2FinaleSeqData11,
+ 	kEob2FinaleSeqData12,
+ 	kEob2FinaleSeqData13,
+ 	kEob2FinaleSeqData14,
+ 	kEob2FinaleSeqData15,
+ 	kEob2FinaleSeqData16,
+ 	kEob2FinaleSeqData17,
+ 	kEob2FinaleSeqData18,
+ 	kEob2FinaleSeqData19,
+ 	kEob2FinaleSeqData20,
+	kEob2FinaleShapes00,
+ 	kEob2FinaleShapes03,
+ 	kEob2FinaleShapes07,
+ 	kEob2FinaleShapes09,
+ 	kEob2FinaleShapes10,
+
+	kEob2NpcShapeData,
+	kEobBaseClassModifierFlags,
+
+	kEobBaseMonsterStepTable02,
+	kEobBaseMonsterStepTable1,
+	kEobBaseMonsterStepTable2,
+	kEobBaseMonsterStepTable3,
+	kEobBaseMonsterCloseAttPosTable1,
+	kEobBaseMonsterCloseAttPosTable22,
+	kEobBaseMonsterCloseAttUnkTable,
+	kEobBaseMonsterCloseAttChkTable1,
+	kEobBaseMonsterCloseAttChkTable2,
+	kEobBaseMonsterCloseAttDstTable1,
+	kEobBaseMonsterCloseAttDstTable2,
+	
+	kEobBaseMonsterProximityTable,
+	kEobBaseFindBlockMonstersTable,
+	kEobBaseMonsterDirChangeTable,
+	kEobBaseMonsterDistAttStrings,
+	kEobBaseEncodeMonsterDefs,
+	kEobBaseNpcPresets,
+	kEob2Npc1Strings,
+	kEob2Npc2Strings,
+	kEob2MonsterDustStrings,
+
+	kLolEobCommonDscShapeIndex,
+	kLolEobCommonDscX,
+	kLolEobCommonDscTileIndex,
+	kLolEobCommonDscUnk2,
+	kLolEobCommonDscDimData1,
+	kLolEobCommonDscDimData2,
+	kLolEobCommonDscBlockMap,
+	kLolEobCommonDscDimMap,	
+	kLolEobCommonDscBlockIndex,
+
+	-1
+};
+
 struct GameNeed {
 	int game;
 	int platform;
@@ -1064,6 +1473,10 @@ const GameNeed gameNeedTable[] = {
 
 	{ kLol, kPlatformPC, kTalkieVersion, lolCDNeed },
 
+	{ kEob1, kPlatformPC, kNoSpecial, eob1FloppyNeed },
+
+	{ kEob2, kPlatformPC, kNoSpecial, eob2FloppyNeed },
+
 	{ -1, -1, -1, 0 }
 };
 
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index 8042dca..da861fb 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -1331,6 +1331,1231 @@ const ExtractEntrySearchData k3ItemStringMapProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEobBaseChargenStrings1Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x000000CA, 0x00003BC8, { { 0x27, 0xEA, 0xE3, 0x0D, 0x55, 0xB3, 0x69, 0x3E, 0xC2, 0x66, 0x58, 0x64, 0xAA, 0xC2, 0x80, 0x58 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x000000C3, 0x000038F6, { { 0x20, 0x68, 0xAB, 0xD4, 0xBF, 0x49, 0x04, 0xC0, 0x91, 0xB4, 0x71, 0xB0, 0xB6, 0xC9, 0x11, 0xF0 } } } }, // EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x000000C7, 0x00003ADB, { { 0x0D, 0x03, 0x7A, 0xE6, 0x7D, 0x41, 0x89, 0x49, 0x0C, 0xB6, 0xD0, 0x4F, 0xEA, 0x1E, 0x54, 0xFF } } } }, // EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseChargenStrings2Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000004B, 0x000011AE, { { 0x28, 0x98, 0x4C, 0xA3, 0x98, 0xB0, 0xA2, 0x17, 0x9C, 0x80, 0x4F, 0x3F, 0x58, 0x3B, 0x2C, 0xFB } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x0000004E, 0x0000129D, { { 0xED, 0xF3, 0x36, 0x16, 0xE2, 0x1B, 0x32, 0x95, 0xFE, 0xE8, 0x3E, 0x7D, 0xE6, 0x32, 0x34, 0xD4 } } } }, // EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x0000004A, 0x00001267, { { 0xD6, 0xE2, 0x27, 0x6A, 0x6F, 0x7E, 0xB4, 0xCE, 0xA8, 0xE9, 0x79, 0x31, 0x5C, 0x13, 0xA1, 0x8F } } } }, // EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseChargenStartLevelsProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000003C, 0x00000054, { { 0xAB, 0x68, 0x74, 0x3E, 0x0D, 0x45, 0xA3, 0x50, 0xA7, 0x72, 0x6A, 0xDF, 0x9C, 0x23, 0x98, 0x74 } } } },	// EOB 1
+	{ UNK_LANG, kPlatformUnknown, { 0x0000003C, 0x000000B1, { { 0xFD, 0x3F, 0x6B, 0xB5, 0xE4, 0xEE, 0x32, 0x3B, 0xBD, 0x72, 0x37, 0x88, 0x52, 0x84, 0xBD, 0xC6 } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseChargenStatStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000055, 0x000015D6, { { 0xB8, 0x29, 0x4B, 0xA4, 0x4F, 0x45, 0x16, 0x1A, 0x07, 0x28, 0x14, 0x86, 0x1B, 0xDF, 0xAC, 0xDF } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000056, 0x000015F9, { { 0xBB, 0x5A, 0x7D, 0xCF, 0xC3, 0x90, 0x9A, 0xB3, 0x73, 0xB2, 0x4D, 0x46, 0xB8, 0x89, 0x7D, 0xAE } } } }, // EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000053, 0x0000159A, { { 0x1D, 0xA6, 0x84, 0xDB, 0xC5, 0x81, 0xC7, 0xF0, 0x1C, 0xA4, 0xE3, 0x10, 0x4F, 0x8A, 0xF3, 0xCE } } } }, // EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseChargenRaceSexStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000098, 0x00002572, { { 0x8D, 0xF9, 0xDE, 0x92, 0xFC, 0xA8, 0xFC, 0xE9, 0x0A, 0x98, 0x6D, 0xA4, 0x6F, 0x21, 0xCD, 0xF4 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x000000AA, 0x00002A1E, { { 0x8E, 0xAF, 0x4B, 0x20, 0xEA, 0xFE, 0x71, 0x8E, 0x8B, 0x4B, 0x46, 0x62, 0x91, 0x48, 0x08, 0xAF } } } }, // EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000098, 0x00002502, { { 0xA4, 0x8B, 0x20, 0xF5, 0x97, 0xFE, 0x34, 0x6D, 0x9F, 0xF0, 0xA8, 0xE9, 0xE8, 0xFA, 0x23, 0x9B } } } }, // EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseChargenClassStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x000000D5, 0x000035A7, { { 0xAF, 0x89, 0x9A, 0x11, 0x9A, 0x8D, 0x39, 0x6F, 0x26, 0x41, 0x4E, 0x20, 0xAD, 0x91, 0xC5, 0xDA } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x000000FA, 0x00003FD8, { { 0xBD, 0x78, 0xF7, 0xEC, 0x9D, 0x9A, 0x3A, 0x22, 0xAB, 0xD9, 0x10, 0xAD, 0x8E, 0x1D, 0x4D, 0xDE } } } }, // EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x000000E4, 0x00003BE5, { { 0xDE, 0x1B, 0x25, 0x4F, 0xE6, 0xD0, 0xB5, 0x95, 0xD0, 0xA6, 0x69, 0xE6, 0x53, 0xB8, 0x20, 0x1E } } } }, // EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseChargenAlignmentStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000078, 0x00001F44, { { 0xBB, 0x52, 0x3C, 0xA6, 0x79, 0x87, 0xDC, 0xB8, 0x21, 0x7A, 0xA0, 0x17, 0x45, 0xEA, 0xF2, 0x50 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x0000008A, 0x00002423, { { 0xA3, 0x36, 0x0D, 0x64, 0x33, 0xFD, 0x54, 0xA5, 0xA9, 0xD7, 0xFA, 0x34, 0x39, 0xAD, 0x6A, 0x98 } } } }, // EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x0000007F, 0x000021F8, { { 0xBD, 0xB2, 0x06, 0xF9, 0xC9, 0x36, 0x5D, 0x91, 0x43, 0x08, 0x3A, 0x2C, 0x5F, 0x1C, 0xF3, 0x9C } } } }, // EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseChargenEnterGameStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000020, 0x00000A0E, { { 0x98, 0x7F, 0x2C, 0x2E, 0xBB, 0x5E, 0xAA, 0xD0, 0x72, 0xF5, 0xBC, 0x4A, 0x34, 0x5B, 0xB4, 0xF5 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000021, 0x00000AB6, { { 0x02, 0x7F, 0x19, 0x5A, 0xA9, 0xB7, 0x8C, 0xE2, 0xF7, 0x35, 0xB0, 0xD8, 0xA8, 0x0C, 0x24, 0x44 } } } }, // EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x0000001E, 0x00000925, { { 0xDA, 0x83, 0x00, 0xD2, 0x94, 0xF0, 0xD8, 0xFC, 0x3D, 0xA8, 0xD2, 0x4E, 0xF2, 0xD7, 0x2B, 0x7E } } } }, // EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseChargenClassMinStatsProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x000000B4, 0x00000165, { { 0x83, 0x5E, 0x91, 0x10, 0x4D, 0x75, 0x6B, 0xF9, 0x45, 0x1B, 0x65, 0x13, 0x37, 0x3E, 0xC0, 0xAE } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseChargenRaceMinStatsProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000048, 0x000000B2, { { 0x08, 0xF0, 0x8F, 0x22, 0x9D, 0xD8, 0xBE, 0x52, 0x70, 0x7C, 0xCA, 0x8D, 0xB2, 0xF5, 0xC6, 0xB8 } } } },	
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseChargenRaceMaxStatsProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000048, 0x00000479, { { 0xBD, 0xA0, 0x8C, 0xC2, 0x05, 0xCA, 0x0D, 0x4B, 0x82, 0x9B, 0x3D, 0xB5, 0x4B, 0xDB, 0xD2, 0xC1 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseConstModTable1Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000032, 0x00000214, { { 0x3D, 0x89, 0x30, 0x0A, 0x5C, 0x4A, 0x0F, 0xC3, 0xC7, 0x6B, 0x72, 0x7C, 0x12, 0x51, 0x8D, 0x8E } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseConstModTable2Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000019, 0x000000E7, { { 0xF4, 0x0D, 0xDF, 0xA3, 0x23, 0x71, 0x76, 0x2A, 0xC5, 0x6F, 0xF1, 0x59, 0x5F, 0x45, 0x73, 0x05 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseConstModTable3Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000023, 0x00000155, { { 0x42, 0x98, 0x84, 0x00, 0x70, 0x8A, 0x7B, 0x26, 0xC0, 0x96, 0xA3, 0x28, 0x41, 0x36, 0x4B, 0x21 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseConstModTable4Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000001E, 0x0000013B, { { 0xAB, 0x84, 0x2B, 0x0A, 0xC2, 0x46, 0xFF, 0x83, 0x03, 0xF8, 0x3F, 0x32, 0x53, 0xA2, 0x95, 0x65 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseConstModLvlIndexProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000006, 0x00000070, { { 0x57, 0x48, 0x5F, 0x75, 0x79, 0xD4, 0xAA, 0x7D, 0xB7, 0xEB, 0x19, 0x9F, 0xCF, 0x99, 0x29, 0x29 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseConstModDivProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000006, 0x00000012, { { 0x50, 0x29, 0x51, 0x65, 0x0B, 0xF1, 0xCC, 0xDA, 0x2C, 0xA4, 0x7E, 0xEE, 0x20, 0xB0, 0x29, 0xB1 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseConstModExtProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000006, 0x00000030, { { 0x07, 0x7D, 0x61, 0x1C, 0x95, 0xEC, 0x9A, 0xCE, 0xA1, 0x29, 0x83, 0x2F, 0xCA, 0x95, 0x95, 0xF5 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBasePryDoorStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x000000E8, 0x00004D9F, { { 0xDE, 0x01, 0x69, 0x00, 0x0B, 0x32, 0xFA, 0x20, 0xB8, 0x11, 0xD6, 0xD9, 0xE2, 0xEA, 0xF5, 0xE8 } } } },	// EOB 1
+	{ EN_ANY, kPlatformUnknown, { 0x000000D2, 0x000043D2, { { 0x82, 0x3C, 0xF4, 0x4A, 0x87, 0x84, 0xFE, 0xF9, 0xBA, 0xC6, 0x67, 0x3A, 0x0D, 0x0F, 0x76, 0x78 } } } },	// EOB 2
+	{ DE_DEU, kPlatformUnknown, { 0x00000128, 0x0000657C, { { 0xA3, 0xC8, 0x48, 0xA7, 0x1F, 0x75, 0xDF, 0xB0, 0x37, 0xDA, 0x75, 0x2E, 0x9F, 0x4E, 0x45, 0xB0 } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x000000D9, 0x00004769, { { 0x24, 0x59, 0x00, 0x8F, 0x9A, 0x3E, 0x95, 0xAB, 0x14, 0x9A, 0x3B, 0x19, 0x34, 0xDB, 0x9B, 0x18 } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseWarningStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000052, 0x00001A7B, { { 0x81, 0x7A, 0xDF, 0xD2, 0x4F, 0xA7, 0x92, 0xA7, 0x44, 0xE5, 0x22, 0x73, 0xF6, 0xB3, 0x29, 0x5C } } } },	// EOB 1
+	{ EN_ANY, kPlatformUnknown, { 0x00000085, 0x00002B5C, { { 0xF1, 0xCE, 0x7C, 0x53, 0xEF, 0x5B, 0x59, 0x71, 0xA9, 0xEB, 0x00, 0xBA, 0xB7, 0x59, 0xC5, 0x2E } } } },	// EOB 2
+	{ DE_DEU, kPlatformUnknown, { 0x0000005F, 0x00001FD2, { { 0xBA, 0x85, 0x97, 0x63, 0x84, 0x80, 0x79, 0x44, 0x50, 0x99, 0x1A, 0x01, 0x37, 0x37, 0x0E, 0xD1 } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000096, 0x000032BF, { { 0x07, 0x95, 0x91, 0x1A, 0x1B, 0xC8, 0xA3, 0xEE, 0x76, 0x0A, 0x48, 0x11, 0x37, 0x6F, 0xBA, 0x05 } } } },	// EOB 1
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseItemSuffixStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x000000BF, 0x00004241, { { 0x5B, 0x5E, 0xD4, 0x55, 0x86, 0x18, 0x9B, 0x99, 0x5D, 0x39, 0x5A, 0x3F, 0xF7, 0xF0, 0x3B, 0x42 } } } },	// EOB 1
+	{ EN_ANY, kPlatformUnknown, { 0x000000CC, 0x00004708, { { 0xF9, 0x04, 0x46, 0x9D, 0xD3, 0xF4, 0xFA, 0xE2, 0x12, 0x79, 0xBB, 0x00, 0x20, 0xE7, 0xB7, 0x35 } } } },	// EOB 2
+	{ DE_DEU, kPlatformUnknown, { 0x000000CA, 0x000047A4, { { 0x89, 0x01, 0x88, 0x85, 0x19, 0x6A, 0xEE, 0xC9, 0x62, 0x65, 0x7E, 0xB7, 0xE6, 0x27, 0xB0, 0x53 } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000109, 0x00005CAF, { { 0xB0, 0x39, 0xF9, 0xAE, 0x04, 0x3A, 0x96, 0xED, 0x55, 0x0E, 0xB4, 0x0F, 0x53, 0x62, 0x6D, 0xD6 } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseItemExtraStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000161, 0x000072D6, { { 0x15, 0xD3, 0x0A, 0x45, 0xCD, 0xD7, 0xC5, 0x93, 0x17, 0x3E, 0x1A, 0x0D, 0xAD, 0x50, 0xC2, 0x5E } } } },	// EOB 1
+	{ EN_ANY, kPlatformUnknown, { 0x00000221, 0x0000B466, { { 0x6E, 0x24, 0x2C, 0xCE, 0x32, 0xC4, 0xF4, 0x4F, 0xC1, 0x79, 0x9A, 0x1C, 0x61, 0xB2, 0x08, 0x4F } } } },	// EOB 2
+	{ DE_DEU, kPlatformUnknown, { 0x00000191, 0x000087C3, { { 0x3B, 0x27, 0x8D, 0xFF, 0x88, 0x2D, 0x0D, 0x92, 0x47, 0xC5, 0x50, 0xB5, 0x36, 0x01, 0xCC, 0x58 } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000281, 0x0000D8BF, { { 0x7D, 0xB7, 0x06, 0x9D, 0x1E, 0x1D, 0x87, 0xAF, 0xD4, 0x40, 0xAF, 0xF9, 0xCD, 0xE3, 0x1E, 0x02 } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseTakenStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000009, 0x0000026E, { { 0x3B, 0x73, 0x70, 0x2E, 0x22, 0x90, 0x0D, 0xC1, 0xDE, 0x32, 0x11, 0xCC, 0x97, 0xBA, 0xA3, 0x58 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x0000000F, 0x000004ED, { { 0x8D, 0x12, 0x1E, 0x91, 0xD3, 0xF4, 0x34, 0x15, 0xC7, 0x4F, 0xE7, 0x23, 0x5B, 0xE8, 0x66, 0xB7 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBasePotionEffectStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000065, 0x0000248F, { { 0x4F, 0x60, 0x7F, 0xA7, 0x6F, 0x81, 0xD4, 0xAA, 0x68, 0xD5, 0xAA, 0xBE, 0xBC, 0xD4, 0x92, 0x3A } } } },	// EOB 1
+	{ EN_ANY, kPlatformUnknown, { 0x0000005D, 0x0000219D, { { 0x87, 0x60, 0x9F, 0xF3, 0x1B, 0x30, 0x4B, 0x2B, 0xE4, 0x94, 0xEF, 0x22, 0xEA, 0x36, 0xE4, 0x7F } } } },	// EOB 2
+	{ DE_DEU, kPlatformUnknown, { 0x0000006E, 0x00002840, { { 0x04, 0xF8, 0x53, 0x38, 0x09, 0xD8, 0x58, 0xFC, 0x5F, 0xE9, 0x69, 0xFB, 0x9C, 0x0D, 0x92, 0x2E } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000059, 0x000020D2, { { 0xB6, 0xA1, 0x57, 0xD6, 0x46, 0xE3, 0xCF, 0x04, 0x5A, 0xC8, 0xBB, 0x59, 0x8D, 0xE3, 0x6F, 0xBF } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseYesNoStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000007, 0x0000022E, { { 0xF1, 0x30, 0x61, 0xA7, 0x20, 0x71, 0x3B, 0x75, 0xBE, 0xA7, 0xD6, 0x78, 0x34, 0xF7, 0x19, 0x06 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000008, 0x00000275, { { 0xAF, 0x3E, 0xC5, 0x5A, 0x60, 0x34, 0x9B, 0x39, 0x37, 0x9E, 0xE2, 0x17, 0x23, 0x8E, 0x23, 0x23 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kLolEobCommonMoreStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000005, 0x00000133, { { 0xA6, 0x1A, 0x3A, 0xB8, 0xCC, 0x92, 0xB8, 0xBE, 0x28, 0xD6, 0x64, 0x8F, 0x0A, 0x2A, 0x39, 0xCD } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000005, 0x0000012C, { { 0x82, 0x30, 0x00, 0xD6, 0xFA, 0x53, 0x17, 0x69, 0x64, 0xCA, 0xFE, 0x0F, 0x92, 0xEF, 0x87, 0x7A } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseNpcMaxStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000052, 0x00001D23, { { 0x95, 0xB0, 0xBF, 0xF9, 0xE6, 0x8C, 0xCF, 0x9B, 0x36, 0xE3, 0x81, 0x22, 0x1E, 0x68, 0x9E, 0xBE } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000064, 0x00002341, { { 0xC0, 0xA6, 0xCD, 0x5E, 0x8E, 0xFA, 0x89, 0xE4, 0x98, 0xE5, 0x3D, 0x13, 0x6B, 0xE7, 0x8F, 0x6E } } } },	// Eob 1
+	{ DE_DEU, kPlatformUnknown, { 0x0000003E, 0x00001613, { { 0x4E, 0x31, 0x7F, 0xC4, 0xC7, 0x9C, 0xB5, 0x7D, 0x36, 0x85, 0xD8, 0x81, 0xE2, 0x06, 0xF9, 0xAE } } } },	// Eob 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseOkStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000003, 0x0000009A, { { 0x88, 0xD2, 0x76, 0x1C, 0x80, 0x02, 0xC5, 0x5B, 0x35, 0x57, 0x0E, 0xEB, 0xCA, 0xD6, 0xC9, 0x2E } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000003, 0x0000009A, { { 0x88, 0xD2, 0x76, 0x1C, 0x80, 0x02, 0xC5, 0x5B, 0x35, 0x57, 0x0E, 0xEB, 0xCA, 0xD6, 0xC9, 0x2E } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseNpcJoinStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000015, 0x000006C7, { { 0x5A, 0xBF, 0xA2, 0x3E, 0x36, 0xC4, 0x23, 0xC8, 0xA8, 0x86, 0x06, 0x80, 0xAF, 0xB1, 0xDD, 0xAB } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000020, 0x00000A93, { { 0x4A, 0xFD, 0x70, 0xB7, 0x7A, 0x0B, 0x7C, 0x32, 0x07, 0x5A, 0x4A, 0xC7, 0x84, 0x9D, 0x2D, 0xF3 } } } },	// Eob 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000018, 0x00000848, { { 0xC9, 0xEE, 0x71, 0x04, 0xA2, 0xA5, 0x52, 0x87, 0x7C, 0x6D, 0x3C, 0x15, 0x7D, 0x41, 0xE0, 0xE7 } } } },	// Eob 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseCancelStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000007, 0x000001A6, { { 0x21, 0xED, 0xF9, 0x71, 0xEF, 0x74, 0xD7, 0x9E, 0xF3, 0x02, 0xE5, 0x03, 0x06, 0xDE, 0xD5, 0x09 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x0000000A, 0x0000027A, { { 0xBD, 0x88, 0xB2, 0xA0, 0xAF, 0x8D, 0xFE, 0x5B, 0xAC, 0xDF, 0xB5, 0x9F, 0xA0, 0x23, 0x6E, 0xAE } } } },	// Eob 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000006, 0x00000145, { { 0x22, 0x45, 0x35, 0xC6, 0x28, 0x00, 0x22, 0xAA, 0xD1, 0x15, 0x48, 0xE6, 0xE5, 0x62, 0x73, 0x37 } } } },	// Eob 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseAbortStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000006, 0x00000178, { { 0xDD, 0xEC, 0x68, 0x6D, 0x2E, 0x10, 0x34, 0x94, 0x46, 0x25, 0xF9, 0xAB, 0x29, 0x27, 0x32, 0xA8 } } } }, 
+	{ DE_DEU, kPlatformUnknown, { 0x00000006, 0x00000145, { { 0x22, 0x45, 0x35, 0xC6, 0x28, 0x00, 0x22, 0xAA, 0xD1, 0x15, 0x48, 0xE6, 0xE5, 0x62, 0x73, 0x37 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseCharGuiStringsHpProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000000F, 0x00000352, { { 0x9C, 0x13, 0x3D, 0x2A, 0x68, 0x11, 0x81, 0xA4, 0x77, 0x54, 0x47, 0x43, 0xA1, 0xDA, 0x55, 0x50 } } } }, 
+	{ DE_DEU, kPlatformUnknown, { 0x0000000E, 0x000002AC, { { 0xBB, 0xD5, 0x36, 0xB2, 0x8A, 0x60, 0x78, 0x04, 0x46, 0x2D, 0x35, 0x59, 0x3E, 0x42, 0xB9, 0x83 } } } },	// Eob 1
+	{ DE_DEU, kPlatformUnknown, { 0x0000000E, 0x000002B8, { { 0x77, 0x76, 0xA0, 0x38, 0xE9, 0xB6, 0x0C, 0x43, 0xFE, 0x5A, 0x51, 0xC7, 0x1B, 0x59, 0xD3, 0x63 } } } },	// Eob 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseCharGuiStringsWp1Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000000A, 0x00000253, { { 0x1D, 0xF4, 0xB9, 0x56, 0xE6, 0x16, 0x7D, 0x08, 0xA4, 0x00, 0x1E, 0x1A, 0x60, 0x49, 0xE9, 0x29 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x0000000A, 0x00000236, { { 0x17, 0xEC, 0x54, 0xA0, 0x43, 0xFB, 0x52, 0x66, 0xC5, 0x44, 0x1B, 0xDF, 0x95, 0x47, 0x62, 0xB3 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseCharGuiStringsWp2Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000000F, 0x00000371, { { 0x42, 0xF4, 0x52, 0x60, 0x20, 0xFC, 0x34, 0x94, 0x49, 0x1E, 0x67, 0x54, 0xB5, 0x6A, 0x97, 0x2A } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000010, 0x000003D6, { { 0x10, 0xD1, 0x77, 0x6C, 0xCD, 0x00, 0x94, 0xC7, 0xD0, 0x53, 0x47, 0x9F, 0x70, 0x77, 0x50, 0xD1 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseCharGuiStringsWrProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000014, 0x00000477, { { 0xAA, 0x26, 0xD5, 0xFD, 0xE6, 0x16, 0x53, 0x19, 0x39, 0x46, 0xEB, 0xCD, 0x88, 0xEC, 0x5E, 0xCB } } } }, 
+	{ DE_DEU, kPlatformUnknown, { 0x00000015, 0x000004A4, { { 0x53, 0x54, 0x37, 0x35, 0x27, 0x1F, 0xB9, 0x09, 0x9C, 0xE9, 0x5E, 0x11, 0xBD, 0x8F, 0x15, 0xAE } } } },	// Eob 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000011, 0x00000402, { { 0xE0, 0x92, 0xF4, 0x49, 0xB7, 0x74, 0xBB, 0xEB, 0x90, 0x0D, 0x75, 0x65, 0xBB, 0xF6, 0xB6, 0xE9 } } } },	// Eob 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseCharGuiStringsSt1Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000003B, 0x0000104B, { { 0xC0, 0xD9, 0x0F, 0x7B, 0x6D, 0x17, 0x02, 0xBD, 0x7B, 0xB1, 0x76, 0x72, 0xA1, 0xEE, 0x5E, 0xAD } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000039, 0x00000F69, { { 0x09, 0x42, 0x35, 0x47, 0x48, 0x50, 0x05, 0x09, 0x3B, 0x81, 0x14, 0x01, 0xF9, 0xB5, 0x04, 0xB2 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseCharGuiStringsSt2Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000045, 0x000012E7, { { 0x49, 0x48, 0x30, 0x73, 0xDA, 0x42, 0xDB, 0xB9, 0xF4, 0x07, 0x00, 0x26, 0x96, 0x1F, 0x02, 0x4E } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000042, 0x0000114D, { { 0x88, 0x6E, 0x45, 0xF9, 0xAE, 0xEF, 0xE8, 0x54, 0x9C, 0xEF, 0xD2, 0x73, 0x78, 0x41, 0xD9, 0xAF } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseCharGuiStringsInProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000023, 0x000008CB, { { 0xF0, 0xE9, 0xF1, 0x05, 0x47, 0x3A, 0x5D, 0xCA, 0x9F, 0x75, 0x9D, 0x51, 0x9E, 0xEC, 0x9B, 0x67 } } } }, 
+	{ DE_DEU, kPlatformUnknown, { 0x00000020, 0x00000810, { { 0xF5, 0x39, 0x1E, 0x0E, 0x65, 0xEF, 0x09, 0xF2, 0x8D, 0x90, 0xC4, 0xF6, 0x8A, 0xED, 0xAD, 0xDF } } } },	// Eob 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000023, 0x00000940, { { 0xAB, 0xF6, 0xE4, 0xD4, 0x07, 0x07, 0xDA, 0x92, 0x71, 0xE2, 0x73, 0x1F, 0x06, 0xE3, 0x12, 0xEB } } } },	// Eob 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseCharStatusStrings7Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000022, 0x00000B95, { { 0xCB, 0xB7, 0x16, 0x77, 0x9C, 0xEB, 0x70, 0x83, 0xB2, 0xBE, 0xF7, 0x67, 0xB1, 0xE9, 0xD0, 0x5E } } } },	// EOB 1 + 2
+	{ DE_DEU, kPlatformUnknown, { 0x0000002B, 0x00000EE3, { { 0xC8, 0x81, 0x23, 0xC3, 0x03, 0xBD, 0x4C, 0xF5, 0x41, 0x47, 0xFA, 0x32, 0xA0, 0x98, 0x0A, 0x8E } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000023, 0x00000C68, { { 0xF5, 0x55, 0x09, 0xD8, 0x73, 0xF8, 0xF0, 0xE3, 0x14, 0xCD, 0x78, 0x84, 0x58, 0xB0, 0x64, 0x5B } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseCharStatusStrings81Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000021, 0x00000B03, { { 0x44, 0xFC, 0xC2, 0x23, 0x4B, 0x78, 0xA8, 0xF8, 0xA5, 0x46, 0x5B, 0x89, 0x1F, 0x9D, 0x4E, 0xFA } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000020, 0x00000A52, { { 0x81, 0xDA, 0x22, 0x8A, 0xD3, 0x7D, 0xE7, 0xF5, 0x39, 0x6A, 0x62, 0x41, 0xE5, 0x8D, 0x45, 0x20 } } } },	// EOB 1
+};
+
+const ExtractEntrySearchData kEobBaseCharStatusStrings82Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000023, 0x00000B0F, { { 0xBD, 0xED, 0xFE, 0xFD, 0x40, 0x95, 0x42, 0x21, 0x1F, 0x55, 0x67, 0x65, 0xA8, 0xC3, 0x99, 0xA1 } } } },	// EOB 2
+	{ DE_DEU, kPlatformUnknown, { 0x0000001A, 0x00000789, { { 0x8C, 0xF3, 0xB8, 0x3C, 0x6E, 0x85, 0xED, 0xD6, 0x2B, 0xD7, 0xAE, 0x8A, 0xFC, 0x25, 0x5E, 0x8F } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseCharStatusStrings9Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000001C, 0x00000952, { { 0x2F, 0x41, 0x17, 0x95, 0xF8, 0xC8, 0x4E, 0x88, 0xC6, 0x83, 0x38, 0x9B, 0xAB, 0x23, 0x48, 0xB9 } } } },	// EOB 1 + 2
+	{ DE_DEU, kPlatformUnknown, { 0x0000001D, 0x0000099F, { { 0x5E, 0xB4, 0xBE, 0xA9, 0x0C, 0xB2, 0xF2, 0x4E, 0x63, 0xF8, 0x7B, 0x98, 0x67, 0x2D, 0xC9, 0xBF } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x0000001E, 0x00000A52, { { 0xD4, 0x65, 0x3F, 0x35, 0xDD, 0x8A, 0x33, 0x44, 0x2F, 0x8C, 0xAC, 0x2F, 0xEC, 0x96, 0x5B, 0x02 } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseCharStatusStrings12Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000010, 0x00000503, { { 0x81, 0x22, 0xE9, 0x0F, 0xA5, 0xEA, 0xFE, 0xB5, 0xB6, 0x43, 0x36, 0x22, 0x87, 0x24, 0x2C, 0x40 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000014, 0x00000683, { { 0x5A, 0xF8, 0xAA, 0x16, 0x97, 0xBE, 0xD5, 0x22, 0xCE, 0x3F, 0xBC, 0x00, 0x44, 0xC1, 0x27, 0xD3 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseCharStatusStrings131Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000000B, 0x0000027A, { { 0x70, 0x1A, 0x83, 0x35, 0x0A, 0x51, 0xEA, 0x27, 0x6E, 0xCD, 0xEB, 0xAD, 0x20, 0x74, 0x28, 0x7D } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x0000000C, 0x000002EE, { { 0xFE, 0xF9, 0x45, 0xE7, 0x89, 0x7B, 0xA4, 0x82, 0x90, 0x63, 0x91, 0x5B, 0x9E, 0x83, 0x80, 0x10 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseCharStatusStrings132Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000000D, 0x00000286, { { 0x00, 0x1E, 0x11, 0xCC, 0x57, 0xFA, 0xEF, 0x2A, 0x0A, 0xFF, 0xFF, 0xE9, 0x3E, 0xA3, 0x62, 0x21 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x0000000A, 0x0000018A, { { 0x10, 0x54, 0x6F, 0xC3, 0x08, 0xC4, 0xD2, 0xBB, 0x34, 0x0A, 0x04, 0x65, 0x49, 0xFC, 0x5E, 0x15 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseLevelGainStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000002A, 0x00000CC9, { { 0xF2, 0x1F, 0xDF, 0xE0, 0xA5, 0x86, 0x46, 0xF4, 0xFC, 0x71, 0xB0, 0x22, 0x32, 0x46, 0x71, 0xB6 } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000029, 0x00000D38, { { 0x18, 0xA3, 0xFD, 0xCC, 0xF2, 0x68, 0x18, 0x9E, 0x80, 0x5A, 0xC0, 0x22, 0xFD, 0x15, 0x83, 0x84 } } } },	// EOB 1
+	{ EN_ANY, kPlatformUnknown, { 0x0000001C, 0x0000078C, { { 0x15, 0x70, 0x37, 0xE4, 0x0B, 0x50, 0x32, 0xCA, 0xAE, 0xF6, 0x81, 0xD0, 0x98, 0x9B, 0x36, 0x8A } } } },	// EOB 2
+	{ DE_DEU, kPlatformUnknown, { 0x0000001F, 0x000008E3, { { 0x07, 0x2C, 0x51, 0x5E, 0x47, 0xAA, 0xCC, 0x27, 0x77, 0xD8, 0x17, 0x59, 0x6B, 0xBE, 0xF5, 0x87 } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseExperienceTable0Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000C9E, { { 0xDB, 0x47, 0xD9, 0x0D, 0x6E, 0x68, 0x04, 0xE4, 0x17, 0xCB, 0x60, 0x89, 0x35, 0x3E, 0xA9, 0xEE } } } },	// Eob 1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00000E24, { { 0xBC, 0xF3, 0x96, 0x8A, 0xD5, 0x0C, 0xAA, 0x94, 0xBB, 0xB5, 0x08, 0x73, 0xF8, 0x5C, 0xF0, 0xA9 } } } }, // Eob 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseExperienceTable1Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000C80, { { 0x35, 0x45, 0x0D, 0x4F, 0xE0, 0x84, 0xA2, 0x1B, 0xB0, 0x0D, 0x60, 0x4D, 0x1D, 0xD5, 0x6C, 0x72 } } } },	// Eob 1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00000E6F, { { 0xBD, 0x3F, 0x42, 0x54, 0x75, 0x41, 0xAA, 0x58, 0x0D, 0xD8, 0xC0, 0x07, 0x63, 0x35, 0x83, 0x6B } } } }, // Eob 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseExperienceTable2Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x00000E10, { { 0xA5, 0x4D, 0xCB, 0xF3, 0x5F, 0x89, 0x71, 0x24, 0x6F, 0x70, 0xCA, 0x51, 0xAA, 0x1C, 0x0A, 0x97 } } } },	// Eob 1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00001149, { { 0xF9, 0xF1, 0x7E, 0x6B, 0xB2, 0xFE, 0x04, 0xC4, 0x29, 0x3D, 0xE3, 0x42, 0x5D, 0x92, 0x77, 0x53 } } } }, // Eob 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseExperienceTable3Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000ADC, { { 0x42, 0x2E, 0x2E, 0xF5, 0xF8, 0x65, 0x69, 0x28, 0x50, 0x67, 0x43, 0xDF, 0x91, 0x67, 0x9B, 0x09 } } } },	// Eob 1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00000C94, { { 0x67, 0x09, 0x98, 0x19, 0x1F, 0x6B, 0x4D, 0xEB, 0x1D, 0x4D, 0x55, 0xA8, 0xFF, 0xD1, 0xAB, 0xE1 } } } }, // Eob 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseExperienceTable4Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000DA7, { { 0x45, 0x58, 0x34, 0xC9, 0x09, 0x61, 0xD7, 0xE1, 0xF8, 0x68, 0x80, 0xBC, 0xEF, 0x7A, 0x24, 0x03 } } } },	// Eob 1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00000FE1, { { 0x26, 0x7F, 0x83, 0x53, 0x4A, 0xC6, 0xA2, 0x7B, 0xD2, 0xFB, 0x73, 0xB2, 0x08, 0x0A, 0xF7, 0xFD } } } }, // Eob 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseWllFlagPresetProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000019, 0x00000BD9, { { 0xBE, 0x5A, 0xA6, 0xC8, 0xE4, 0x04, 0x4C, 0x32, 0x35, 0x61, 0x48, 0x73, 0x29, 0xA9, 0x99, 0x54 } } } },	// Eob 1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000019, 0x00000BC9, { { 0x56, 0xC0, 0x66, 0x4D, 0xE1, 0x3A, 0x27, 0x89, 0x9D, 0x73, 0x63, 0x93, 0x08, 0x2B, 0x13, 0xBC } } } }, // Eob 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscShapeCoordsProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000168, 0x0000F206, { { 0xB8, 0xDF, 0x10, 0xBB, 0x06, 0xA1, 0x46, 0xC6, 0xD2, 0xE3, 0xD7, 0x64, 0x4A, 0xC6, 0x40, 0xC0 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscDoorScaleOffsProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000020, 0x0000010F, { { 0x7B, 0x7D, 0x03, 0xDE, 0x33, 0x95, 0xB8, 0xFD, 0xAD, 0x72, 0x44, 0x7D, 0x47, 0xFE, 0x04, 0x3D } } } },	// Eob1
+	{ UNK_LANG, kPlatformPC, { 0x00000035, 0x00000139, { { 0x74, 0x63, 0x18, 0xE7, 0xAB, 0xA4, 0x22, 0xCF, 0x32, 0x19, 0x28, 0x9E, 0x7F, 0x97, 0xA7, 0x37 } } } },	// Eob2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscDoorScaleMult1Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000026, { { 0x5D, 0x17, 0xFB, 0x6A, 0x7F, 0x51, 0x55, 0xFB, 0x55, 0xB9, 0x50, 0xB0, 0x7F, 0xE4, 0xDF, 0x67 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscDoorScaleMult2Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000006, { { 0x98, 0xD8, 0xF8, 0x0C, 0x98, 0xC4, 0xF1, 0x87, 0x59, 0x32, 0x78, 0x31, 0xFA, 0x98, 0x8A, 0x43 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscDoorScaleMult3Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000013, { { 0xEE, 0xB6, 0xA5, 0x6E, 0x0C, 0x8E, 0xAB, 0x38, 0xD9, 0x23, 0xC6, 0x21, 0xB3, 0x7E, 0x97, 0x78 } } } },	// EOB 1
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000019, { { 0x86, 0xD8, 0x04, 0xD2, 0x66, 0x6F, 0x43, 0x24, 0x2E, 0x93, 0xB9, 0xAE, 0xEB, 0x44, 0xCA, 0x48 } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscDoorScaleMult4Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000006, { { 0x98, 0xD8, 0xF8, 0x0C, 0x98, 0xC4, 0xF1, 0x87, 0x59, 0x32, 0x78, 0x31, 0xFA, 0x98, 0x8A, 0x43 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscDoorScaleMult5Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000020, { { 0x37, 0xA1, 0x0D, 0x64, 0xD6, 0x1E, 0xBA, 0xA3, 0xD9, 0x0A, 0x6C, 0xAB, 0x6B, 0xA3, 0x59, 0x24 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscDoorScaleMult6Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000006, { { 0x98, 0xD8, 0xF8, 0x0C, 0x98, 0xC4, 0xF1, 0x87, 0x59, 0x32, 0x78, 0x31, 0xFA, 0x98, 0x8A, 0x43 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscDoorType5OffsProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x00000012, { { 0x73, 0xBB, 0x61, 0xD6, 0xA7, 0x75, 0xC8, 0x7B, 0xD6, 0xA4, 0x53, 0x1B, 0x54, 0xE9, 0x30, 0x3F } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscDoorY1Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x000000D7, { { 0x25, 0xAE, 0xF4, 0x99, 0xE8, 0x97, 0x47, 0xAE, 0x75, 0xF3, 0xA9, 0x70, 0x4C, 0x70, 0xF3, 0x11 } } } },	// EOB 1
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x000000D8, { { 0xB4, 0xAA, 0x0D, 0x91, 0x58, 0x22, 0x16, 0xCF, 0xC5, 0x9D, 0x8D, 0xA1, 0xB4, 0x40, 0x83, 0x0E } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscDoorY3Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000058, { { 0xF0, 0x3C, 0x3B, 0x97, 0x10, 0x95, 0x89, 0x18, 0x3B, 0xA9, 0xE8, 0x77, 0x9B, 0x10, 0xDC, 0xF1 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscDoorY4Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000076, { { 0x84, 0xB6, 0x8F, 0x7E, 0x9A, 0x17, 0xAC, 0x59, 0xB1, 0x4C, 0xDE, 0x11, 0xA6, 0x95, 0xE3, 0x76 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscDoorY5Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x000000D9, { { 0x5D, 0x27, 0x1D, 0xD6, 0x5F, 0x98, 0xF9, 0x7D, 0x65, 0x7B, 0xE0, 0x67, 0x34, 0xA0, 0xE8, 0x30 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscDoorY6Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x000000D9, { { 0x4D, 0x15, 0x4A, 0xF1, 0x17, 0x09, 0xC1, 0xA6, 0x08, 0x4A, 0xCD, 0xB2, 0x68, 0xC2, 0x59, 0x52 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscDoorCoordsExtProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000048, 0x00000C8E, { { 0x2E, 0x0E, 0xB2, 0xAC, 0xE7, 0x0F, 0xDF, 0x38, 0xDF, 0x92, 0xB7, 0xB5, 0xA2, 0xFD, 0x40, 0x2D } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscItemPosIndexProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000010, 0x00000018, { { 0x74, 0x90, 0x47, 0xE6, 0xFB, 0xC0, 0x34, 0xDF, 0x92, 0x5B, 0xA1, 0xCB, 0x06, 0x33, 0xCA, 0x6B } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscItemShpXProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000024, 0x00000F2C, { { 0x9E, 0x22, 0x3F, 0x8F, 0x31, 0x83, 0xF7, 0x7C, 0x59, 0x60, 0x7C, 0x0A, 0xEB, 0xD2, 0x18, 0x85 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscItemPosUnkProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000012, 0x00000433, { { 0xA4, 0x7B, 0x08, 0x07, 0x81, 0xEA, 0x4F, 0x99, 0x77, 0x74, 0x93, 0x65, 0xBF, 0x0C, 0x3B, 0x94 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscItemTileIndexProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000012, 0x00000D23, { { 0x0E, 0x17, 0xE1, 0x1F, 0x34, 0x7D, 0x30, 0xF6, 0xAE, 0x0B, 0xAC, 0x9D, 0x21, 0xB6, 0x97, 0xCC } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscItemShapeMapProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000005A, 0x00000B23, { { 0x41, 0x4A, 0x95, 0x7F, 0x82, 0x85, 0x28, 0x55, 0xD4, 0xD5, 0xD6, 0xD8, 0xA9, 0xAE, 0xF4, 0xC0 } } } },	// Eob 1
+	{ UNK_LANG, kPlatformPC, { 0x00000071, 0x00000860, { { 0xEA, 0x5D, 0x33, 0xB6, 0x38, 0x30, 0x65, 0x29, 0x7F, 0x08, 0x89, 0x04, 0xC5, 0x97, 0x76, 0xCB } } } },	// Eob 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscTelptrShpCoordsProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000009C, 0x00000EBE, { { 0x2D, 0x1D, 0x74, 0x39, 0x29, 0xC3, 0x6F, 0x53, 0xD9, 0xA5, 0x4B, 0x9F, 0xD6, 0xDD, 0x73, 0xE9 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscMonsterFrmOffsTbl1Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000020, 0x00001000, { { 0x98, 0x27, 0x57, 0x25, 0x3B, 0x04, 0x7D, 0x14, 0x3A, 0xD4, 0xA2, 0x5D, 0xBA, 0x04, 0x45, 0xAC } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDscMonsterFrmOffsTbl2Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000020, 0x00000828, { { 0x7E, 0x8A, 0x0C, 0xEB, 0x5C, 0xBC, 0x6C, 0xBD, 0xD2, 0x48, 0x08, 0xCC, 0xF7, 0x7B, 0x81, 0x03 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseInvSlotXProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000036, 0x000010BF, { { 0x50, 0x6E, 0x67, 0x2B, 0x7D, 0x6C, 0xF2, 0x21, 0x73, 0xA2, 0xD5, 0xBB, 0xCE, 0x3B, 0x71, 0xAA } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseInvSlotYProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000001B, 0x00000A5B, { { 0x47, 0x55, 0x7D, 0x84, 0x45, 0x91, 0xC4, 0x44, 0x10, 0xD5, 0x39, 0xC4, 0xC8, 0x4F, 0x01, 0xA4 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseSlotValidationFlagsProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000036, 0x00001F6B, { { 0x87, 0x4F, 0x9A, 0x97, 0x20, 0x20, 0xB2, 0xA6, 0xF7, 0xC2, 0x5F, 0xAA, 0x17, 0xEA, 0xB4, 0x50 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseDrawObjPosIndexProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000014, 0x00000028, { { 0x44, 0x46, 0x8C, 0x94, 0x76, 0x24, 0x08, 0xC7, 0x1F, 0x1B, 0x10, 0xD7, 0xDF, 0x18, 0x6C, 0x0D } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseFlightObjFlipIndexProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000010, 0x00000008, { { 0xEB, 0xF0, 0x27, 0x7E, 0xA8, 0x09, 0x3A, 0x95, 0x3B, 0x71, 0x2A, 0x43, 0x2E, 0xCF, 0x22, 0x0B } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseFlightObjShpMapProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000058, 0x000051BD, { { 0xC3, 0xD2, 0xD1, 0xE5, 0x78, 0xEE, 0xA7, 0xAA, 0x71, 0xD1, 0xDD, 0xDF, 0x40, 0xBB, 0xAF, 0x66 } } } },	// EOB 1
+	{ UNK_LANG, kPlatformPC, { 0x0000002D, 0x000025E6, { { 0x64, 0x26, 0x3D, 0xDC, 0x6C, 0x1A, 0xFC, 0x36, 0x9E, 0x5A, 0xBF, 0x64, 0xAD, 0xF4, 0xA3, 0x5D } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseFlightObjSclIndexProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000048, 0x00002A0E, { { 0xAC, 0xBB, 0x7D, 0x73, 0x98, 0xF4, 0x1E, 0x4A, 0x77, 0xF0, 0x98, 0x75, 0x11, 0xBF, 0xF7, 0xD5 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseBookNumbersProvider[] = {
+	{ EN_ANY, kPlatformPC, { 0x00000020, 0x00000AC8, { { 0x35, 0x05, 0x37, 0x4C, 0x05, 0x74, 0x04, 0x08, 0xAD, 0xA3, 0x64, 0xBF, 0xC0, 0x67, 0xF2, 0xF7 } } } },
+	{ DE_DEU, kPlatformPC, { 0x00000028, 0x00000E5D, { { 0x80, 0x98, 0x05, 0x54, 0x84, 0x90, 0xD3, 0xB3, 0x9B, 0xFB, 0x8F, 0xB9, 0xA0, 0x43, 0xAA, 0xFD } } } },
+	{ EN_ANY, kPlatformPC, { 0x00000020, 0x00000AC8, { { 0x35, 0x05, 0x37, 0x4C, 0x05, 0x74, 0x04, 0x08, 0xAD, 0xA3, 0x64, 0xBF, 0xC0, 0x67, 0xF2, 0xF7 } } } },
+	{ DE_DEU, kPlatformPC, { 0x00000022, 0x00000BCA, { { 0x93, 0x0E, 0xE0, 0x6D, 0xDD, 0x40, 0xBC, 0x89, 0x67, 0xBD, 0x8A, 0xCB, 0xD2, 0xCF, 0x78, 0x8D } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMageSpellsListProvider[] = {
+	{ EN_ANY, kPlatformPC, { 0x00000122, 0x00006304, { { 0xD7, 0x14, 0x28, 0x83, 0x04, 0xC3, 0x42, 0x5A, 0x15, 0x49, 0x91, 0x12, 0x1D, 0x49, 0x17, 0x5B } } } },
+	{ DE_DEU, kPlatformPC, { 0x0000013A, 0x00007155, { { 0x94, 0x45, 0xB9, 0x15, 0x57, 0x6E, 0xC6, 0x70, 0x66, 0x5F, 0xA7, 0x90, 0xA0, 0xC7, 0xC9, 0xE9 } } } },
+	{ EN_ANY, kPlatformPC, { 0x00000195, 0x00008AC0, { { 0x55, 0xB8, 0x75, 0x35, 0x09, 0x23, 0x83, 0x11, 0x22, 0xF8, 0x23, 0x1E, 0x8F, 0x08, 0x57, 0x66 } } } },
+	{ DE_DEU, kPlatformPC, { 0x0000019A, 0x0000929F, { { 0xB3, 0xA0, 0x2D, 0x3B, 0xF3, 0x72, 0x9B, 0x75, 0xA3, 0xC4, 0xD8, 0x72, 0x4B, 0xDE, 0x69, 0x82 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseClericSpellsListProvider[] = {
+	{ EN_ANY, kPlatformPC, { 0x0000013B, 0x00006BE6, { { 0x34, 0x63, 0x0B, 0xBA, 0xED, 0xC2, 0x9B, 0x31, 0xC3, 0x65, 0x51, 0xFF, 0xEF, 0xD8, 0x25, 0x92 } } } },
+	{ DE_DEU, kPlatformPC, { 0x0000016D, 0x00007E74, { { 0x6E, 0xDE, 0x28, 0xE6, 0x13, 0x3D, 0xA6, 0x42, 0x80, 0xAB, 0xE7, 0xED, 0xAD, 0xC8, 0x62, 0x48 } } } },
+	{ EN_ANY, kPlatformPC, { 0x00000164, 0x000079B3, { { 0x93, 0x16, 0x25, 0xFB, 0x76, 0xFF, 0xBC, 0x70, 0x9A, 0xB7, 0x93, 0xFC, 0x2E, 0xC3, 0x61, 0x7F } } } },
+	{ DE_DEU, kPlatformPC, { 0x0000018B, 0x00008BB1, { { 0x8C, 0x21, 0xED, 0xE0, 0x1F, 0xF1, 0xDB, 0x72, 0xC4, 0x46, 0x36, 0x50, 0x16, 0xD5, 0xA8, 0x68 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseSpellNamesProvider[] = {
+	{ EN_ANY, kPlatformPC, { 0x0000029A, 0x0000F1C8, { { 0xCA, 0xE1, 0x30, 0xDC, 0xAB, 0xD1, 0x87, 0xE8, 0x51, 0xA2, 0xA2, 0x1C, 0x23, 0x4A, 0x34, 0x58 } } } },
+	{ DE_DEU, kPlatformPC, { 0x000002D3, 0x0001080D, { { 0x5F, 0xDB, 0x9E, 0x48, 0x30, 0x03, 0xE1, 0x8E, 0xC7, 0xDC, 0x98, 0x10, 0xCE, 0xA1, 0x28, 0x31 } } } },
+	{ EN_ANY, kPlatformPC, { 0x00000366, 0x00013B1A, { { 0x15, 0xCB, 0x0E, 0xA9, 0x4E, 0x78, 0x30, 0x99, 0xA1, 0xCF, 0xF7, 0x05, 0xAB, 0x00, 0x66, 0x82 } } } },
+	{ DE_DEU, kPlatformPC, { 0x000003BA, 0x0001626B, { { 0x0E, 0x4F, 0xF6, 0xFB, 0x78, 0x5E, 0x03, 0xE7, 0x82, 0xC4, 0xE2, 0x7B, 0xD9, 0xB2, 0xD7, 0xB2 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMagicStrings1Provider[] = {
+	{ EN_ANY, kPlatformPC, { 0x00000084, 0x000029B0, { { 0xC6, 0x90, 0x19, 0x61, 0xA1, 0x66, 0xF6, 0x03, 0x7A, 0x1F, 0x10, 0x00, 0xCA, 0x8F, 0x69, 0x3B } } } },
+	{ DE_DEU, kPlatformPC, { 0x0000009D, 0x000033E4, { { 0x4B, 0xCF, 0x40, 0xCE, 0x0F, 0x86, 0x98, 0x36, 0x03, 0x59, 0xFE, 0x32, 0xFA, 0x4C, 0x14, 0x75 } } } },
+	{ EN_ANY, kPlatformPC, { 0x00000085, 0x000029BD, { { 0xAB, 0x22, 0x4A, 0x70, 0xBB, 0x29, 0xB8, 0xBD, 0xAF, 0xC5, 0x0D, 0x1F, 0x23, 0x38, 0xBD, 0x06 } } } },
+	{ DE_DEU, kPlatformPC, { 0x0000008C, 0x00002D68, { { 0x4B, 0x0A, 0x09, 0x22, 0xF7, 0x77, 0x82, 0x4B, 0xFE, 0x0B, 0xF1, 0x8F, 0x1C, 0xEA, 0x1A, 0x0C } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMagicStrings2Provider[] = {
+	{ EN_ANY, kPlatformPC, { 0x00000051, 0x00001AD6, { { 0x28, 0x18, 0x2B, 0xF0, 0x0E, 0xC6, 0xEB, 0x01, 0xB0, 0x9A, 0x0A, 0x65, 0x05, 0xCB, 0x8F, 0x41 } } } },
+	{ DE_DEU, kPlatformPC, { 0x0000004F, 0x00001A82, { { 0x77, 0x85, 0x17, 0x25, 0x07, 0x72, 0x4A, 0x7F, 0x4F, 0x39, 0x6C, 0xDD, 0xB6, 0x70, 0x11, 0x02 } } } },
+	{ EN_ANY, kPlatformPC, { 0x00000090, 0x00002E35, { { 0x39, 0xD7, 0xA3, 0x21, 0xF0, 0xB7, 0x93, 0x9D, 0xDD, 0xEE, 0x33, 0xC2, 0x05, 0xE6, 0xE3, 0x63 } } } },
+	{ DE_DEU, kPlatformPC, { 0x000000A1, 0x0000365C, { { 0x9A, 0x2D, 0xDB, 0x38, 0xB3, 0xF4, 0x0E, 0xF4, 0x36, 0x87, 0x60, 0xAE, 0xF8, 0x7E, 0xCA, 0x8A } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMagicStrings3Provider[] = {
+	{ EN_ANY, kPlatformPC, { 0x0000008D, 0x00002DC8, { { 0x35, 0x5E, 0xDD, 0x32, 0x2D, 0x55, 0x1E, 0xBC, 0x93, 0x49, 0x55, 0x48, 0x8F, 0xCD, 0x87, 0xEB } } } },
+	{ DE_DEU, kPlatformPC, { 0x000000A8, 0x0000381C, { { 0x12, 0x95, 0x55, 0x57, 0x2B, 0xA0, 0x1A, 0x75, 0xD3, 0x43, 0xFF, 0x3E, 0x00, 0xB6, 0xEC, 0x35 } } } },
+	{ EN_ANY, kPlatformPC, { 0x00000088, 0x00002CD4, { { 0xD8, 0xBA, 0x5D, 0x14, 0x92, 0x84, 0x5A, 0x07, 0xC6, 0x76, 0xDF, 0x11, 0x1D, 0x84, 0x7A, 0x98 } } } },
+	{ DE_DEU, kPlatformPC, { 0x00000081, 0x00002B14, { { 0xC8, 0xB7, 0x77, 0xBC, 0x3A, 0xB6, 0xDC, 0xB7, 0x00, 0xF3, 0x06, 0xEB, 0x77, 0x10, 0x7C, 0x7E } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMagicStrings4Provider[] = {
+	{ EN_ANY, kPlatformPC, { 0x00000017, 0x0000071C, { { 0x96, 0x50, 0xA8, 0x08, 0x1B, 0x2D, 0x0C, 0xF6, 0x90, 0x6A, 0xE7, 0x9F, 0x65, 0xCC, 0x71, 0xA0 } } } },
+	{ DE_DEU, kPlatformPC, { 0x0000001B, 0x00000840, { { 0xA2, 0xCF, 0x81, 0x3E, 0x87, 0xA8, 0x10, 0x1B, 0x44, 0x8D, 0x5B, 0x8B, 0xAE, 0x23, 0x30, 0xD3 } } } },
+	{ EN_ANY, kPlatformPC, { 0x0000000C, 0x000003A5, { { 0x72, 0x64, 0xBD, 0x1C, 0xED, 0x05, 0x28, 0xFC, 0x94, 0x4B, 0x8F, 0x3C, 0x38, 0x08, 0x77, 0xED } } } },
+	{ DE_DEU, kPlatformPC, { 0x00000010, 0x0000054E, { { 0xD9, 0x97, 0xA8, 0x24, 0x27, 0x7B, 0x01, 0x3F, 0x03, 0xBA, 0x2A, 0x43, 0x81, 0x8F, 0x97, 0x03 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMagicStrings5Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000008, 0x0000016C, { { 0xCF, 0x5B, 0x04, 0xAB, 0x1A, 0xAF, 0xDD, 0x56, 0xAC, 0xF6, 0x23, 0x86, 0x33, 0x06, 0x5A, 0xC6 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMagicStrings6Provider[] = {
+	{ EN_ANY, kPlatformPC, { 0x00000029, 0x00000DA4, { { 0x5C, 0x6F, 0xA1, 0xC2, 0x56, 0xDE, 0xFE, 0xD5, 0x01, 0xFB, 0x65, 0x00, 0x24, 0xD1, 0x49, 0x7B } } } },
+	{ DE_DEU, kPlatformPC, { 0x00000032, 0x00001211, { { 0x13, 0xBC, 0xF1, 0x03, 0x49, 0xDB, 0x16, 0xA5, 0xC3, 0x7C, 0xBF, 0x14, 0x8F, 0x40, 0x07, 0x8E } } } },
+	{ EN_ANY, kPlatformPC, { 0x00000030, 0x00000FF5, { { 0xE4, 0x2B, 0xB9, 0xF0, 0x26, 0x3D, 0x30, 0xCD, 0xEF, 0xCD, 0xF5, 0xC0, 0x4E, 0xA4, 0xC4, 0x92 } } } },
+	{ DE_DEU, kPlatformPC, { 0x00000029, 0x00000E6D, { { 0xE1, 0xBD, 0x4B, 0x42, 0x17, 0xA2, 0xB6, 0x6C, 0xF2, 0x7F, 0xEB, 0x41, 0x2C, 0x82, 0x8C, 0x76 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMagicStrings7Provider[] = {
+	{ EN_ANY, kPlatformPC, { 0x00000014, 0x00000406, { { 0xBD, 0xE1, 0x0A, 0x75, 0xD1, 0x18, 0xF7, 0x08, 0x2D, 0x2B, 0x65, 0x36, 0xA7, 0x59, 0x2E, 0x13 } } } },
+	{ DE_DEU, kPlatformPC, { 0x0000000F, 0x000001E5, { { 0x1F, 0xC9, 0x46, 0x8B, 0x41, 0xAD, 0xAD, 0x2B, 0x5A, 0xA9, 0xAB, 0x94, 0x9A, 0x1E, 0x36, 0xAC } } } },
+	{ EN_ANY, kPlatformPC, { 0x00000065, 0x000021AF, { { 0x76, 0x35, 0xAE, 0x1D, 0xC2, 0x54, 0x36, 0x11, 0x4D, 0x3E, 0x96, 0x11, 0xB2, 0xDC, 0x15, 0x20 } } } },
+	{ DE_DEU, kPlatformPC, { 0x0000006F, 0x000026BA, { { 0xC9, 0x46, 0xD7, 0xF3, 0xF2, 0x5F, 0xF4, 0xB1, 0x22, 0xC8, 0x30, 0x16, 0x8E, 0x75, 0x4D, 0xA8 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMagicStrings8Provider[] = {
+	{ EN_ANY, kPlatformPC, { 0x00000056, 0x00001C95, { { 0x7E, 0x43, 0x73, 0xEC, 0x94, 0x0D, 0xF8, 0x1B, 0xF3, 0x1A, 0x62, 0x19, 0x96, 0x6A, 0x2C, 0xB5 } } } },
+	{ DE_DEU, kPlatformPC, { 0x00000061, 0x0000213B, { { 0xE2, 0x3B, 0xA7, 0xB7, 0xE6, 0xA5, 0x0D, 0x0F, 0xE0, 0x94, 0x9B, 0xAE, 0xE1, 0x11, 0x97, 0x93 } } } },
+	{ EN_ANY, kPlatformPC, { 0x00000085, 0x00002C0E, { { 0x6A, 0xEC, 0xF2, 0x5F, 0xA6, 0x3F, 0xB1, 0x1A, 0x74, 0x49, 0x5A, 0x47, 0xB0, 0x7A, 0xE6, 0x99 } } } },
+	{ DE_DEU, kPlatformPC, { 0x00000096, 0x0000342E, { { 0x83, 0x48, 0x3B, 0xED, 0x73, 0x02, 0x03, 0xCA, 0xA9, 0x4D, 0x40, 0x0F, 0xDE, 0x17, 0x7D, 0x40 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseSparkDefStepsProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000008, 0x000002FD, { { 0xB5, 0x6F, 0x31, 0x5F, 0xC6, 0x47, 0xE9, 0x23, 0x0E, 0x73, 0xBF, 0x77, 0xC7, 0xEE, 0xDB, 0x27 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseSparkDefSubStepsProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x000000FF, { { 0x18, 0x27, 0x73, 0x45, 0x26, 0x58, 0x81, 0x82, 0x70, 0x86, 0x7A, 0x0D, 0xDE, 0xC1, 0x08, 0x52 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseSparkDefShiftProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x0000000C, { { 0xCC, 0xDC, 0x78, 0xF9, 0xFE, 0x88, 0xF3, 0x87, 0xFD, 0x08, 0xE8, 0x8A, 0x38, 0xD5, 0x4C, 0x53 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseSparkDefAddProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000008, 0x0000007F, { { 0x7F, 0x86, 0x2E, 0x14, 0xDB, 0x36, 0xED, 0x99, 0xD9, 0xCE, 0xAF, 0x11, 0xC2, 0x89, 0x21, 0x6B } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseSparkDefXProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000000C, 0x000000A5, { { 0x77, 0xD7, 0xE0, 0x2D, 0xD4, 0x25, 0x94, 0x6E, 0x59, 0x3B, 0xAF, 0x9B, 0x16, 0x4F, 0x6D, 0x4C } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseSparkDefYProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x00000138, { { 0xB9, 0xA2, 0x72, 0x01, 0x2A, 0xD7, 0x61, 0xAB, 0x02, 0x57, 0x87, 0xC8, 0x86, 0x83, 0xDF, 0xB3 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseSparkOfFlags1Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000002C, 0x00000BF4, { { 0x94, 0x8C, 0x1B, 0x77, 0xBF, 0x3A, 0x51, 0x17, 0x89, 0x16, 0xD0, 0x74, 0x95, 0xBD, 0x85, 0x98 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseSparkOfFlags2Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000040, 0x000003FC, { { 0x40, 0x13, 0x5A, 0x9D, 0xBD, 0x29, 0x2E, 0x9C, 0xC1, 0xE7, 0xD4, 0xC9, 0x26, 0xFA, 0xF2, 0x70 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseSparkOfShiftProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000010, 0x000000F0, { { 0xC5, 0xC8, 0x91, 0x7E, 0x78, 0x2F, 0xF1, 0xE5, 0xE0, 0x06, 0xB2, 0x39, 0xDC, 0x0D, 0x7A, 0x5F } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseSparkOfXProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000010, 0x00000528, { { 0x58, 0xE6, 0x24, 0x6A, 0xD3, 0xA4, 0xEF, 0x58, 0x4A, 0x9C, 0x32, 0x31, 0x4C, 0x61, 0xBC, 0x1C } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseSparkOfYProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000010, 0x000002D4, { { 0x74, 0x31, 0xFE, 0x7C, 0x38, 0x16, 0x0C, 0x05, 0x64, 0xAB, 0x8A, 0x69, 0xEA, 0x66, 0x29, 0x2F } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseSpellPropertiesProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x000003EF, 0x0000BE7A, { { 0x10, 0xEA, 0x14, 0x26, 0xE2, 0xFC, 0xA1, 0xCB, 0xD9, 0x80, 0xFE, 0x9F, 0x69, 0x58, 0x4A, 0xCA } } } },
+	{ UNK_LANG, kPlatformPC, { 0x000003EF, 0x00008FCE, { { 0xC9, 0x36, 0xDD, 0x7B, 0x05, 0x6E, 0x92, 0xBA, 0x2B, 0x39, 0x87, 0xA7, 0x3A, 0x7E, 0xB0, 0xAD } } } },
+	{ UNK_LANG, kPlatformPC, { 0x000006D6, 0x0000CA78, { { 0xEB, 0x3B, 0x9F, 0xFD, 0x4E, 0x3F, 0x5C, 0xDE, 0xC6, 0xBA, 0xFE, 0x83, 0xB4, 0x10, 0x6D, 0x95 } } } },
+	{ UNK_LANG, kPlatformPC, { 0x000006D6, 0x0000EC32, { { 0x52, 0xAE, 0x4D, 0xC2, 0x24, 0xC8, 0xD3, 0xBE, 0x09, 0x45, 0x98, 0x38, 0x17, 0x7D, 0xFF, 0xE4 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMagicFlightPropsProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000060, 0x0000166F, { { 0x38, 0x30, 0xCA, 0x07, 0x64, 0xBA, 0xC4, 0xA4, 0x4F, 0x75, 0xB4, 0x84, 0x3A, 0x92, 0xFD, 0xE3 } } } },
+	{ UNK_LANG, kPlatformPC, { 0x00000038, 0x00000DDC, { { 0x23, 0x32, 0x8D, 0x34, 0x4F, 0x72, 0x37, 0xE1, 0x0C, 0x1B, 0x47, 0x17, 0x5D, 0xDF, 0xDB, 0xF5 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1MainMenuStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000037, 0x00000D79, { { 0x1D, 0x72, 0x7F, 0x8F, 0xEB, 0x4A, 0xBF, 0x82, 0xB7, 0xB5, 0x9D, 0xB0, 0x7B, 0xDA, 0xEC, 0xEE } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000034, 0x00000C6F, { { 0xF2, 0x5F, 0xBE, 0xFB, 0x27, 0x1C, 0x91, 0x33, 0x25, 0x09, 0xC1, 0xA0, 0x27, 0x89, 0xD7, 0xD5 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1DoorShapeDefsProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000060, 0x00000F8A, { { 0x95, 0x53, 0x1B, 0x07, 0x64, 0x81, 0x0E, 0x04, 0xC0, 0xDA, 0xB5, 0x74, 0x57, 0x04, 0x10, 0xE2 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1DoorSwitchShapeDefsProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000060, 0x0000119E, { { 0xA4, 0xE6, 0x96, 0x36, 0x59, 0x05, 0xB8, 0x57, 0xF4, 0x6D, 0x79, 0x1D, 0x29, 0x52, 0xA0, 0xEE } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1DoorSwitchCoordsProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000030, 0x000007F7, { { 0x85, 0x20, 0x98, 0x20, 0xE1, 0xD6, 0xA5, 0xBD, 0x9E, 0x59, 0x63, 0x6A, 0xEF, 0xEF, 0x80, 0x19 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1MonsterPropertiesProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000252, 0x000038E5, { { 0x5E, 0xD7, 0xEF, 0x3B, 0xD5, 0xDA, 0x2A, 0x09, 0x78, 0xF6, 0xD8, 0x57, 0x68, 0xB4, 0x90, 0xCA } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1MonsterDistAttType10Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000000F, { { 0x01, 0x1B, 0x9C, 0x51, 0xC9, 0xA2, 0x10, 0xBB, 0xA7, 0x82, 0xD4, 0x91, 0x7E, 0x84, 0x54, 0x93 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1MonsterDistAttSfx10Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000029B, { { 0xA2, 0x9F, 0x2E, 0xDE, 0x15, 0x23, 0x78, 0xDD, 0x26, 0x98, 0x6E, 0xA3, 0x77, 0xEA, 0xB5, 0x80 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1MonsterDistAttType17Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000079, { { 0x8E, 0x13, 0x54, 0x9D, 0x54, 0xF6, 0xC9, 0x6E, 0x10, 0xF1, 0xC0, 0xE9, 0x66, 0xDD, 0x95, 0xED } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1MonsterDistAttSfx17Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x000000F5, { { 0xA9, 0x90, 0x41, 0x0D, 0xB5, 0xE0, 0x28, 0xFD, 0x0A, 0xC3, 0xF9, 0xEC, 0xC8, 0x47, 0xC1, 0x57 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2MainMenuStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000005F, 0x000017BE, { { 0x77, 0x8A, 0x50, 0x9F, 0x42, 0xD8, 0x00, 0x05, 0x60, 0x2A, 0x80, 0x25, 0x00, 0xDC, 0x7C, 0x92 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x0000005E, 0x000017F3, { { 0xD0, 0x93, 0x2E, 0x5F, 0x9D, 0xDB, 0xC4, 0xFB, 0x9E, 0x9F, 0x14, 0xD6, 0xB4, 0xBE, 0x3D, 0x0C } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000321, 0x0000DBC3, { { 0x11, 0x9B, 0x54, 0xB3, 0x34, 0xF0, 0xB5, 0xE1, 0xFA, 0x6A, 0x31, 0x02, 0x59, 0x29, 0xCA, 0x94 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x0000038E, 0x0001119C, { { 0x92, 0x63, 0x18, 0xDD, 0x9F, 0x62, 0xF5, 0xBC, 0x3D, 0x93, 0xDC, 0x6E, 0xE5, 0xBE, 0x8C, 0x0B } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroCPSFilesProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x000000A2, 0x0000296A, { { 0xE9, 0x28, 0x4A, 0x6E, 0xAA, 0x44, 0xF4, 0xD7, 0xD1, 0x29, 0xBF, 0x90, 0x6B, 0x82, 0xD1, 0x77 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x000000A2, 0x0000296B, { { 0x03, 0xA2, 0x0A, 0xAB, 0x76, 0x78, 0x04, 0x88, 0x6A, 0xE0, 0x36, 0x8B, 0x3A, 0x87, 0x44, 0xC8 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData00Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000037, 0x000003E1, { { 0x38, 0xC2, 0x0F, 0xE1, 0x43, 0x6A, 0xE8, 0x7C, 0x82, 0x65, 0x9B, 0x4A, 0x9F, 0x83, 0xCD, 0xC8 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData01Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000037, 0x000003A3, { { 0x84, 0x44, 0xF4, 0x46, 0x4E, 0x2B, 0xD7, 0xC6, 0xAD, 0x14, 0xF1, 0x9E, 0x8A, 0xBE, 0x7B, 0x42 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData02Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000037, 0x00000446, { { 0x0C, 0xCA, 0x41, 0x0C, 0x89, 0x59, 0xD5, 0x28, 0x9A, 0xDC, 0x51, 0x1C, 0x0B, 0x8C, 0xD2, 0xDB } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData03Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x0000010E, { { 0xAB, 0x48, 0x64, 0x02, 0xB3, 0xF3, 0x6C, 0x82, 0x9D, 0x37, 0x5F, 0x52, 0x0F, 0x5B, 0xDF, 0x96 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData04Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000021, 0x00000149, { { 0x3B, 0xAC, 0x14, 0x51, 0xDF, 0x5D, 0x22, 0x15, 0x46, 0x4E, 0xCD, 0xF3, 0xD4, 0x61, 0x29, 0x4A } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData05Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x0000010E, { { 0x28, 0x29, 0x5F, 0x31, 0x23, 0x53, 0xBA, 0xD7, 0x24, 0xB9, 0x21, 0x70, 0x84, 0x8A, 0x1C, 0x2E } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData06Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x000000B0, 0x00001365, { { 0x91, 0x28, 0x2F, 0x10, 0x45, 0x4D, 0xCF, 0x3E, 0x70, 0x1E, 0xD4, 0xBA, 0x0E, 0x70, 0xDE, 0xD0 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData07Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000037, 0x000003C4, { { 0x8C, 0x72, 0xDE, 0x4F, 0x92, 0x52, 0x0A, 0xED, 0xF4, 0x79, 0xD6, 0x3D, 0x8F, 0x59, 0x9D, 0x69 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData08Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000042, 0x00000442, { { 0xD2, 0x91, 0x51, 0xEB, 0x91, 0x13, 0x43, 0xCE, 0x7E, 0x60, 0xB8, 0xFF, 0xA7, 0xE2, 0x4C, 0x11 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData09Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x000004BC, { { 0xD6, 0xC7, 0x44, 0x2E, 0xE7, 0x2A, 0x44, 0x09, 0x39, 0xC3, 0xD3, 0xA8, 0x02, 0xC8, 0xA0, 0x19 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData10Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000006E, 0x00000C12, { { 0x91, 0xDB, 0x41, 0x7A, 0x4F, 0x7C, 0x7B, 0x83, 0x32, 0x13, 0x68, 0xF6, 0x58, 0x79, 0xDA, 0x99 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData11Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x000000B0, 0x0000073C, { { 0x17, 0x1F, 0x4D, 0x05, 0x3F, 0x14, 0x2E, 0x77, 0xD3, 0xDB, 0x78, 0x67, 0xBB, 0x18, 0xDC, 0x85 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData12Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000021, 0x00000228, { { 0xC9, 0x50, 0x68, 0x51, 0xD0, 0xC1, 0x5D, 0xD4, 0xFF, 0x08, 0x28, 0xDE, 0xC4, 0x41, 0x8C, 0xDB } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData13Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x00000340, { { 0x03, 0xCA, 0x5D, 0xD1, 0x15, 0xFA, 0x60, 0xD7, 0x70, 0x64, 0x3D, 0x44, 0x08, 0xB8, 0xDB, 0xAD } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData14Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000042, 0x000007C0, { { 0x82, 0xA9, 0x0B, 0x90, 0x9D, 0x65, 0x1E, 0xC7, 0x03, 0x5E, 0xB7, 0xDF, 0x6E, 0x1F, 0xED, 0xD6 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData15Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x00000504, { { 0xA7, 0x91, 0x4F, 0xAD, 0xB1, 0x77, 0x80, 0x3A, 0xC7, 0xDE, 0x35, 0x7A, 0x96, 0x16, 0xD2, 0x13 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData16Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000079, 0x00000B3D, { { 0xCC, 0x63, 0x5A, 0x11, 0xEE, 0x8A, 0xAE, 0x3A, 0x14, 0xC3, 0xBC, 0xDA, 0xAF, 0x1D, 0xD4, 0x2C } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData17Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000084, 0x00000911, { { 0x09, 0x1C, 0x4B, 0xD9, 0x0B, 0x2A, 0xD6, 0xC1, 0xE3, 0x8D, 0xFE, 0x43, 0x8F, 0x2E, 0x21, 0x51 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData18Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000058, 0x000008FA, { { 0xFE, 0x58, 0xD9, 0x67, 0x78, 0x97, 0xE2, 0xCD, 0x82, 0xB8, 0xC9, 0xC0, 0x1F, 0xCA, 0x7C, 0xF5 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData19Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000009A, 0x00000D6B, { { 0xA1, 0xDD, 0x7B, 0x8B, 0x25, 0xA5, 0x96, 0x5A, 0x33, 0x5E, 0x80, 0x5F, 0xA5, 0xBB, 0xAC, 0x11 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData20Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000009A, 0x00000D6C, { { 0x19, 0xF9, 0x93, 0x1D, 0x01, 0xEE, 0x7C, 0x8B, 0x6C, 0x3E, 0x35, 0x2C, 0x5C, 0x88, 0xCD, 0xB6 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData21Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000009A, 0x00000D83, { { 0xCB, 0x4F, 0x21, 0x29, 0x63, 0x5B, 0x8C, 0xF2, 0xBA, 0x03, 0x49, 0xD1, 0xAF, 0x22, 0xB0, 0xD5 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData22Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000200, { { 0x66, 0xEE, 0x45, 0xB1, 0x87, 0x66, 0xC4, 0x55, 0xCE, 0x60, 0x0C, 0x5B, 0xBB, 0x3C, 0x7D, 0x33 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData23Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x0000020D, { { 0xC4, 0x49, 0xE2, 0x5B, 0x2E, 0x17, 0x68, 0xC4, 0xBA, 0x20, 0xEC, 0xB1, 0xEB, 0x1A, 0xFB, 0xE0 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData24Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000214, { { 0xF1, 0x46, 0x82, 0xEF, 0x6D, 0xCA, 0x68, 0xA2, 0xF3, 0x55, 0x63, 0xD2, 0x13, 0x25, 0x19, 0xF7 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData25Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000256, { { 0x8F, 0xB9, 0xCD, 0xB8, 0x58, 0xCB, 0x90, 0x03, 0xFC, 0xB6, 0x95, 0x6F, 0x52, 0xF8, 0x7D, 0x19 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData26Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000263, { { 0x7A, 0x37, 0x07, 0xC4, 0x67, 0x72, 0x1F, 0xCB, 0xAC, 0x98, 0x46, 0x9A, 0xF3, 0x5F, 0xBA, 0x78 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData27Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x0000026A, { { 0x80, 0x11, 0xEE, 0x44, 0xDA, 0xE1, 0x26, 0x1F, 0x14, 0x7E, 0x93, 0x99, 0x44, 0x44, 0x9F, 0x85 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData28Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x000001F6, { { 0x45, 0xA1, 0xA5, 0xEC, 0x85, 0x06, 0xE2, 0x91, 0x28, 0xE0, 0xBB, 0x53, 0x74, 0x44, 0xD9, 0xA6 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData29Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x000001F9, { { 0x3F, 0x03, 0x2F, 0x8B, 0xFB, 0x6A, 0x97, 0x05, 0xED, 0xBB, 0xD6, 0xA0, 0xF5, 0x7A, 0x6D, 0x08 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData30Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000204, { { 0xA1, 0x37, 0x57, 0xC3, 0x72, 0x08, 0x98, 0xA6, 0xF4, 0x5E, 0x58, 0x9E, 0xF3, 0x11, 0x88, 0x1E } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData31Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000212, { { 0x19, 0xCC, 0x6F, 0xA8, 0x29, 0xB5, 0x3B, 0x15, 0x2F, 0x2C, 0x43, 0xED, 0x7A, 0xF5, 0xC5, 0x69 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData32Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000037, 0x000006C9, { { 0xBF, 0x65, 0xBA, 0x3F, 0x44, 0xEE, 0xB0, 0x5C, 0x8B, 0xBD, 0x15, 0xAB, 0x03, 0xD1, 0x55, 0x21 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData33Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000009A, 0x00001585, { { 0xB5, 0x44, 0x06, 0xC9, 0xE8, 0x27, 0x75, 0x6E, 0x63, 0x77, 0xE9, 0xA9, 0x68, 0x73, 0xF5, 0x78 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData34Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000058, 0x00000B43, { { 0x52, 0xB4, 0x1E, 0x14, 0x88, 0xBD, 0x8A, 0xD7, 0x38, 0xDF, 0x25, 0xB0, 0xAF, 0xAE, 0x76, 0xE1 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData35Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000037, 0x000005A4, { { 0xFB, 0x82, 0xE7, 0xB2, 0x54, 0xDB, 0xB5, 0xE1, 0xCE, 0xFB, 0xD1, 0x23, 0x39, 0x8F, 0xA1, 0x0D } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData36Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000042, 0x00000572, { { 0x2C, 0x16, 0xD9, 0xBE, 0xDB, 0xBA, 0x04, 0xCA, 0x97, 0xB5, 0x88, 0x43, 0xA8, 0x62, 0xE2, 0x04 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData37Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x0000024E, { { 0xFF, 0x28, 0xD8, 0x62, 0xC6, 0xAD, 0x48, 0xC7, 0x31, 0x84, 0x6C, 0xBA, 0x9F, 0x4D, 0x15, 0xDA } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData38Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x000001D9, 0x00001FB1, { { 0x16, 0xB0, 0xDF, 0x86, 0x8C, 0xB3, 0x52, 0xEF, 0x21, 0x04, 0x22, 0x6D, 0xC0, 0x03, 0xB8, 0xC6 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData39Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000004D, 0x00000582, { { 0x11, 0x6C, 0xBB, 0xF6, 0x1B, 0x3C, 0xAE, 0xAA, 0x40, 0x27, 0x3F, 0x86, 0x33, 0x92, 0xCB, 0xA9 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData40Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000160, 0x000010A2, { { 0xD9, 0x9D, 0xF1, 0x7D, 0xE1, 0x7C, 0x61, 0xC0, 0xD4, 0xD3, 0x05, 0x0C, 0x79, 0xDD, 0xDB, 0xD1 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData41Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000037, 0x00000355, { { 0x92, 0x85, 0xBE, 0x5A, 0x38, 0x08, 0xF3, 0xDF, 0xC6, 0x56, 0x74, 0xC3, 0x0B, 0x3F, 0x72, 0x4D } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData42Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000021, 0x0000010B, { { 0x68, 0xF8, 0x1D, 0x74, 0x6D, 0x32, 0x1E, 0x3A, 0x1C, 0xD1, 0x1D, 0x4B, 0x89, 0x3D, 0x5F, 0x2B } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroSeqData43Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000037, 0x00000116, { { 0xD5, 0x46, 0xCB, 0x3F, 0x27, 0xBD, 0x2B, 0xD6, 0x35, 0x69, 0x9E, 0x0A, 0x28, 0xDA, 0xC9, 0x84 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroShapes00Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000005A, 0x00000A86, { { 0xF9, 0xD5, 0xD2, 0x93, 0xBC, 0xC4, 0x86, 0x3F, 0x83, 0x0D, 0xDB, 0x38, 0x60, 0x6E, 0xA7, 0xDA } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroShapes01Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000000C, 0x0000009B, { { 0xAA, 0xDD, 0x25, 0x21, 0x57, 0x6A, 0xB7, 0xEB, 0xDA, 0xFD, 0x72, 0x3B, 0xCA, 0x68, 0xDB, 0x34 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroShapes04Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000003C, 0x00000417, { { 0x13, 0x95, 0x81, 0x46, 0x84, 0x36, 0xF2, 0xFC, 0xDE, 0x15, 0x85, 0x81, 0xB3, 0x9A, 0x9D, 0x20 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroShapes07Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000006C, 0x000021F1, { { 0x6F, 0x7C, 0x28, 0xBB, 0xC3, 0x52, 0xE4, 0x13, 0xB4, 0xE9, 0xA4, 0x47, 0x9A, 0xBE, 0x19, 0xDA } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000031C, 0x0000E287, { { 0x1E, 0x73, 0x93, 0x79, 0xB7, 0xF8, 0x17, 0xEE, 0xE4, 0xFC, 0xF0, 0x34, 0x9D, 0x06, 0x4F, 0x55 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x0000039F, 0x00011660, { { 0xBC, 0x1D, 0x95, 0x20, 0x32, 0xF5, 0x83, 0xCF, 0xF7, 0x11, 0xE4, 0x1D, 0x89, 0x47, 0xF0, 0x65 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2CreditsDataProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000090C, 0x00023464, { { 0x55, 0x31, 0x9D, 0x60, 0x2C, 0xA1, 0x0B, 0xF9, 0xED, 0x46, 0xDF, 0x44, 0x1A, 0x9F, 0xB1, 0xB0 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000B11, 0x0002BBD7, { { 0x46, 0x24, 0x78, 0xE9, 0xCE, 0x75, 0x45, 0x7B, 0x3B, 0xAA, 0x15, 0xD8, 0x5B, 0xCB, 0x06, 0x3A } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleCPSFilesProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000009C, 0x00002853, { { 0x1F, 0xB9, 0x3D, 0x48, 0x47, 0x31, 0x0D, 0xA8, 0x92, 0x52, 0xD1, 0x54, 0x48, 0x42, 0x47, 0xBD } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x0000009C, 0x00002878, { { 0x48, 0x3B, 0x7A, 0xC2, 0x9C, 0xEC, 0x10, 0x07, 0xD1, 0xB6, 0x9E, 0x89, 0xE9, 0xE1, 0xBF, 0xBF } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData00Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000079, 0x00000B66, { { 0x9B, 0x8C, 0x17, 0xFA, 0xD2, 0x4F, 0x4B, 0x0E, 0x3A, 0x43, 0xB1, 0x86, 0x0C, 0xDC, 0x73, 0xAB } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData01Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000063, 0x00000A03, { { 0xBB, 0x31, 0xEA, 0x35, 0xFB, 0x99, 0x4C, 0x3E, 0x72, 0xBD, 0x36, 0x6B, 0x5C, 0x03, 0x19, 0x7F } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData02Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x000007C2, { { 0xF6, 0x83, 0x37, 0x58, 0x3C, 0x59, 0x84, 0x8F, 0x97, 0x80, 0xE2, 0xD8, 0xFD, 0x77, 0xA9, 0x54 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData03Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000042, 0x0000092B, { { 0x47, 0xE4, 0x34, 0xE8, 0x72, 0xCC, 0xA4, 0x4A, 0xA4, 0x8F, 0xBA, 0xBC, 0x0C, 0x04, 0x18, 0xAF } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData04Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000058, 0x0000080B, { { 0x16, 0xDB, 0x77, 0x4C, 0x8E, 0xFD, 0x44, 0xF6, 0x5E, 0x28, 0x0B, 0x74, 0x93, 0x45, 0x8F, 0xD9 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData05Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000004D, 0x00000C72, { { 0x6C, 0x57, 0x56, 0x7E, 0x87, 0x10, 0x9C, 0xE7, 0x69, 0xAC, 0x3B, 0x3F, 0xF6, 0x43, 0x5C, 0xD4 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData06Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000264, { { 0x48, 0x49, 0x5D, 0x78, 0xE2, 0xF1, 0x0D, 0x87, 0xEE, 0xEE, 0xD1, 0xA1, 0xC6, 0x64, 0xCA, 0x13 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData07Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000042, 0x00000ABE, { { 0xFE, 0xA9, 0x5D, 0x87, 0xAF, 0x55, 0x04, 0x92, 0x41, 0xD3, 0xAD, 0x1D, 0xFF, 0x03, 0x81, 0x3C } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData08Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000021, 0x000004D8, { { 0x4E, 0xA7, 0xCC, 0x0B, 0x1B, 0x48, 0x22, 0x09, 0x33, 0xF7, 0x23, 0xF1, 0xF5, 0x9F, 0xA5, 0x7B } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData09Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000058, 0x000004BE, { { 0xF6, 0xEA, 0xA0, 0x7F, 0x54, 0x61, 0x79, 0x4C, 0x71, 0xD7, 0x9B, 0xA6, 0xC3, 0x45, 0xEE, 0x3E } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData10Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000009A, 0x00000FC4, { { 0xA9, 0xFB, 0x31, 0x55, 0xB8, 0x28, 0x63, 0xC3, 0x4B, 0x9E, 0x7D, 0x41, 0xC7, 0x1F, 0x2F, 0xBD } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData11Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x000000C6, 0x0000166B, { { 0xCC, 0x16, 0x50, 0xFF, 0xFF, 0xD5, 0xAE, 0x03, 0x40, 0xA3, 0x9A, 0x1F, 0xF8, 0x8E, 0x23, 0x7A } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData12Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x000000FD, 0x00001A69, { { 0x6A, 0x80, 0x89, 0x7E, 0xFC, 0xE4, 0x01, 0xF5, 0xA2, 0x11, 0xE7, 0x26, 0x20, 0x96, 0x62, 0x7B } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData13Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x000000FD, 0x00001886, { { 0xF9, 0x5B, 0x62, 0xDD, 0xAB, 0x14, 0x35, 0x77, 0x53, 0x05, 0xDB, 0xC5, 0xFD, 0x4D, 0x4F, 0x12 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData14Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000108, 0x00001895, { { 0x22, 0xA1, 0x88, 0x69, 0xF9, 0x1C, 0xA2, 0x64, 0x44, 0xCD, 0x00, 0xFA, 0xB1, 0x94, 0xEB, 0x3A } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData15Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x000000D1, 0x000016E5, { { 0xD8, 0xE9, 0xA5, 0xEE, 0x54, 0x1B, 0x3E, 0x32, 0xDA, 0x78, 0x90, 0xC2, 0x54, 0xFC, 0xD5, 0x39 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData16Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000008F, 0x00000C69, { { 0xBC, 0x41, 0xE5, 0xAF, 0x89, 0xE2, 0x54, 0x12, 0x9E, 0xB0, 0x5F, 0x28, 0xFF, 0x92, 0x9D, 0x89 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData17Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x000000DC, 0x0000170D, { { 0x7A, 0x7B, 0x74, 0xCB, 0x68, 0xC2, 0xFF, 0xC7, 0xBE, 0x47, 0xE9, 0x43, 0xF7, 0x15, 0x8D, 0x59 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData18Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000134, 0x00002651, { { 0x71, 0x26, 0x47, 0x0D, 0x7C, 0x96, 0x45, 0x0B, 0x82, 0xD0, 0x37, 0xB9, 0xD4, 0xD0, 0x84, 0xFC } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData19Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000004D, 0x000009C3, { { 0xDA, 0x96, 0xDF, 0x16, 0xEB, 0x5D, 0x49, 0xA4, 0x3F, 0xD3, 0x31, 0xBE, 0x49, 0x72, 0xF2, 0x71 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleSeqData20Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000021, 0x000003D8, { { 0xD9, 0xC8, 0x58, 0x4B, 0x7D, 0x79, 0x86, 0xCB, 0xEB, 0x77, 0xC2, 0xD4, 0xB7, 0xB4, 0xE9, 0x6A } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleShapes00Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000018, 0x0000071C, { { 0xE8, 0x67, 0xCB, 0x76, 0x6D, 0x49, 0xC2, 0x05, 0x0D, 0xAD, 0xB6, 0x83, 0x35, 0xB3, 0xBE, 0xE5 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleShapes03Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000012, 0x00000571, { { 0x91, 0xEC, 0xAC, 0x12, 0x08, 0x33, 0xDA, 0x7C, 0xBD, 0x51, 0x64, 0xE3, 0xAE, 0x43, 0x75, 0x14 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleShapes07Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000018, 0x00000166, { { 0xED, 0x6E, 0x0C, 0x85, 0x13, 0x6F, 0xAC, 0xEB, 0xCA, 0x74, 0x2E, 0x2D, 0x0E, 0xCE, 0x17, 0xD6 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleShapes09Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000036, 0x00000898, { { 0xEB, 0xB0, 0xD9, 0xC4, 0xB6, 0xBC, 0xE3, 0xAF, 0xB2, 0x5D, 0xE3, 0xCE, 0xF7, 0x26, 0x07, 0xE5 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleShapes10Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000018, 0x0000017F, { { 0x0F, 0x37, 0x94, 0xA6, 0xCE, 0x23, 0xE3, 0x2E, 0x5E, 0x2B, 0x78, 0x5B, 0x66, 0xC8, 0xE5, 0x96 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2NpcShapeDataProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000018, 0x0000045D, { { 0x69, 0xE0, 0x5E, 0x86, 0xEB, 0x7D, 0x25, 0x95, 0xC2, 0xA0, 0xE9, 0xD5, 0x3A, 0x4A, 0x65, 0xBC } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseClassModifierFlagsProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000000F, 0x00000059, { { 0x17, 0x2B, 0x23, 0x14, 0x0F, 0x9D, 0x94, 0xD3, 0xBF, 0x94, 0x83, 0x0B, 0x79, 0xDB, 0xC0, 0xA9 } } } }, // EOB 1
+	{ UNK_LANG, kPlatformUnknown, { 0x0000000F, 0x00000083, { { 0x54, 0x68, 0xF4, 0x07, 0x3E, 0x2A, 0xD4, 0x06, 0xF3, 0x10, 0x88, 0x6C, 0xE3, 0x34, 0x08, 0x30 } } } }, // EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMonsterStepTable01Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000004, 0x00000200, { { 0x26, 0x86, 0x10, 0x04, 0xC1, 0x48, 0xDD, 0xC0, 0x9F, 0x92, 0xD6, 0x20, 0x38, 0x36, 0xE2, 0xDD } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMonsterStepTable02Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000008, 0x00000400, { { 0x6E, 0x53, 0x3C, 0x7A, 0x11, 0x46, 0x8B, 0xDC, 0x73, 0x24, 0xF8, 0x13, 0xCB, 0x6C, 0x9B, 0xE6 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMonsterStepTable1Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000400, { { 0x8B, 0x4C, 0x6B, 0x86, 0x93, 0xDA, 0x82, 0x1B, 0x04, 0x23, 0x92, 0x5B, 0x79, 0xB9, 0xFB, 0x06 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMonsterStepTable2Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000601, { { 0xE4, 0x36, 0x12, 0x93, 0x44, 0xDE, 0x6E, 0xA0, 0x4B, 0x98, 0x4B, 0x47, 0x87, 0xE3, 0x40, 0xD4 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMonsterStepTable3Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000010, 0x000007F8, { { 0x00, 0x0C, 0xB0, 0xDA, 0xE1, 0xC8, 0x45, 0x11, 0x57, 0xE4, 0x72, 0xD2, 0x32, 0xC6, 0x16, 0x2B } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMonsterCloseAttPosTable1Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000004, 0x00000006, { { 0x4F, 0x9D, 0x50, 0xDA, 0xA1, 0x75, 0xB0, 0xD5, 0x90, 0xCA, 0xFF, 0x3E, 0xB5, 0xE8, 0x0D, 0xAA } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMonsterCloseAttPosTable21Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000008, 0x0000000C, { { 0x6A, 0xED, 0x15, 0xCE, 0x69, 0x54, 0x7D, 0x7B, 0x6D, 0xCE, 0xC7, 0x2A, 0x01, 0xD7, 0xDC, 0xB0 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMonsterCloseAttPosTable22Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000018, { { 0x6D, 0xB9, 0x69, 0x4A, 0xE3, 0x72, 0x03, 0x5B, 0x5A, 0xBB, 0x15, 0x4A, 0xDA, 0xFB, 0x99, 0x87 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMonsterCloseAttUnkTableProvider[] = {////
+	{ UNK_LANG, kPlatformUnknown, { 0x0000000C, 0x000007FE, { { 0xF0, 0xCB, 0x3A, 0x53, 0xDD, 0x59, 0x04, 0x87, 0x6F, 0x1B, 0x5A, 0x13, 0xBA, 0x78, 0x62, 0xEC } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMonsterCloseAttChkTable1Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000008, { { 0x93, 0x27, 0x19, 0xA7, 0xA7, 0x49, 0x0E, 0xC9, 0xED, 0x5C, 0x8F, 0x9F, 0xC2, 0x34, 0x62, 0x07 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMonsterCloseAttChkTable2Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000008, { { 0xEB, 0xF0, 0x27, 0x7E, 0xA8, 0x09, 0x3A, 0x95, 0x3B, 0x71, 0x2A, 0x43, 0x2E, 0xCF, 0x22, 0x0B } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMonsterCloseAttDstTable1Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000018, { { 0x1E, 0xC9, 0x6C, 0x5D, 0xDF, 0xD4, 0xC0, 0x87, 0xAD, 0xEE, 0x86, 0x29, 0xD5, 0x3E, 0x8D, 0xB4 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMonsterCloseAttDstTable2Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000078, { { 0x4C, 0xA8, 0x2A, 0x53, 0xB3, 0xAA, 0x52, 0x96, 0x1D, 0xE8, 0x37, 0xDB, 0x4A, 0x77, 0xD8, 0x5B } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMonsterProximityTableProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000020, 0x00000030, { { 0x25, 0xFC, 0xA3, 0xEB, 0x44, 0x93, 0x9B, 0x33, 0xB5, 0x86, 0xC4, 0xCB, 0x17, 0xEF, 0x2D, 0x47 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseFindBlockMonstersTableProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000040, 0x00000088, { { 0x6F, 0xEE, 0x8B, 0x4C, 0x21, 0xF0, 0xC6, 0x4F, 0x1D, 0x05, 0x95, 0x41, 0xD7, 0xD6, 0x52, 0x66 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMonsterDirChangeTableProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000030, 0x0000180C, { { 0xCD, 0xBB, 0xFD, 0xAB, 0xFB, 0x1D, 0x5C, 0x0F, 0xA2, 0xAC, 0x32, 0xA9, 0xA1, 0x93, 0x2D, 0x1C } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMonsterDistAttStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000076, 0x00002965, { { 0x1A, 0x22, 0x50, 0x04, 0x27, 0x05, 0xE9, 0x61, 0xF9, 0x0A, 0xF0, 0x50, 0x01, 0x0E, 0x65, 0xB4 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x0000008C, 0x00003274, { { 0xE7, 0x24, 0x17, 0x13, 0x4F, 0xB3, 0xF9, 0xB7, 0x90, 0xFA, 0x3D, 0xFF, 0xA7, 0xFB, 0x3F, 0x1F } } } },
+	{ EN_ANY, kPlatformUnknown, { 0x00000054, 0x00001D03, { { 0xEB, 0x07, 0xD4, 0x22, 0xFD, 0xA0, 0x77, 0x80, 0x22, 0x04, 0x2E, 0x27, 0x7F, 0x64, 0x99, 0x4E } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000062, 0x000023E0, { { 0xB8, 0x03, 0x5C, 0x31, 0xCC, 0x18, 0xCD, 0x8D, 0x60, 0xD1, 0xFB, 0x5B, 0x66, 0xC2, 0x9A, 0x4C } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseEncodeMonsterDefsProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000150, 0x00001ACB, { { 0x73, 0x67, 0x5B, 0x64, 0x22, 0xDB, 0x08, 0x3A, 0xCD, 0xEB, 0x30, 0x28, 0xBD, 0xAD, 0xF8, 0x9B } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseNpcPresetsProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000088B, 0x000038D0, { { 0x2E, 0xAE, 0xF0, 0x2A, 0x71, 0x6F, 0x7C, 0x5C, 0xF5, 0xAF, 0xB8, 0xBB, 0x47, 0xE5, 0xB6, 0xC3 } } } }, // EOB 1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000816, 0x00002C8E, { { 0xAB, 0xEE, 0x18, 0x0E, 0x59, 0xF6, 0xE0, 0x26, 0x93, 0xAB, 0x3B, 0x23, 0x29, 0x7A, 0x2C, 0x97 } } } }, // EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2Npc1StringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000000B, 0x000003B9, { { 0xB1, 0x67, 0x80, 0x21, 0x92, 0xDD, 0xFA, 0x4C, 0x4D, 0x64, 0x7C, 0x05, 0x08, 0xDC, 0x55, 0xFD } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x0000000D, 0x0000049E, { { 0x2D, 0x78, 0xF6, 0x20, 0x30, 0xEC, 0x62, 0x6E, 0x58, 0xF7, 0xC7, 0x6D, 0xD7, 0xBD, 0x70, 0x76 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2Npc2StringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000012, 0x0000064C, { { 0xB0, 0x66, 0x0D, 0xDE, 0x16, 0xEB, 0x5E, 0x51, 0xAF, 0x4D, 0x19, 0xD1, 0x1E, 0x0B, 0xCB, 0xD6 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000018, 0x000008FF, { { 0x59, 0x29, 0x01, 0x6F, 0xF0, 0x49, 0xC8, 0x57, 0x3E, 0x70, 0x01, 0x7E, 0x5E, 0xF2, 0xEB, 0x35 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2MonsterDustStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000001F, 0x00000AD7, { { 0x2B, 0x66, 0x27, 0xFD, 0xC6, 0x17, 0x0B, 0x6B, 0xFC, 0x7D, 0x7F, 0xD2, 0xC4, 0x12, 0x8F, 0x33 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x0000001F, 0x00000A91, { { 0x1D, 0x7D, 0xEE, 0xB8, 0x9B, 0x37, 0x2E, 0x64, 0x13, 0xB6, 0x39, 0xED, 0x88, 0xB6, 0x8B, 0xD7 } } } },
+	EXTRACT_END_ENTRY
+};
+
 const ExtractEntrySearchData kLolIngamePakFilesProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000088, 0x0000224F, { { 0xDA, 0x24, 0x18, 0xA3, 0xEF, 0x16, 0x70, 0x8F, 0xA8, 0xC2, 0x2E, 0xC2, 0xED, 0x39, 0x03, 0xD1 } } } },
 	{ UNK_LANG, kPlatformPC98, { 0x00000084, 0x00002125, { { 0x7A, 0x89, 0xE2, 0x36, 0xEC, 0x6F, 0x52, 0x2B, 0xEF, 0xBA, 0x3D, 0x28, 0x54, 0xDA, 0xFB, 0x72 } } } },
@@ -1532,14 +2757,17 @@ const ExtractEntrySearchData kLolStashSetupProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscUnk1Provider[] = {
+const ExtractEntrySearchData kLolDscWallsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000024, 0x00000A2A, { { 0xAC, 0x4E, 0x73, 0x2C, 0xB0, 0xEE, 0x24, 0x0E, 0x66, 0x8D, 0x48, 0xE5, 0xCA, 0x6B, 0x7F, 0x7F } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscShapeIndexProvider[] = {
+const ExtractEntrySearchData kLolEobCommonDscShapeIndexProvider[] = {
+	// LOL:
 	{ UNK_LANG, kPlatformUnknown, { 0x00000024, 0x00000728, { { 0x14, 0xBA, 0x6D, 0x5C, 0x7D, 0x20, 0x0D, 0x35, 0xA7, 0xB0, 0x8D, 0x2F, 0x1D, 0x2A, 0x49, 0xA4 } } } },
+	// EOB:
+	{ UNK_LANG, kPlatformUnknown, { 0x00000024, 0x00000632, { { 0xBE, 0x3E, 0x84, 0x71, 0x89, 0x04, 0xC9, 0x1D, 0xCF, 0xE4, 0x3B, 0xD8, 0x2A, 0xF4, 0x0F, 0x54 } } } },
 
 	EXTRACT_END_ENTRY
 };
@@ -1552,7 +2780,6 @@ const ExtractEntrySearchData kLolDscOvlMapProvider[] = {
 
 const ExtractEntrySearchData kLolDscScaleWidthDataProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000048, 0x00000ABE, { { 0x28, 0x9A, 0xAA, 0x16, 0xC4, 0xFD, 0x52, 0xA9, 0x76, 0x98, 0x72, 0x0C, 0x2D, 0xE4, 0xB0, 0x57 } } } },
-
 	EXTRACT_END_ENTRY
 };
 
@@ -1562,8 +2789,11 @@ const ExtractEntrySearchData kLolDscScaleHeightDataProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscXProvider[] = {
+const ExtractEntrySearchData kLolEobCommonDscXProvider[] = {
+	// LOL
 	{ UNK_LANG, kPlatformUnknown, { 0x00000048, 0x00001468, { { 0x55, 0xC5, 0x30, 0x76, 0x0A, 0xDC, 0xEC, 0xAB, 0x68, 0x9B, 0x61, 0xF0, 0x58, 0x78, 0x56, 0xA6 } } } },
+	// EOB
+	{ UNK_LANG, kPlatformUnknown, { 0x00000024, 0x00000BFA, { { 0x5F, 0x86, 0x9B, 0xDA, 0x5D, 0x6E, 0xC0, 0xB9, 0x29, 0x82, 0xA5, 0xD7, 0xC9, 0x34, 0x90, 0x63 } } } },
 
 	EXTRACT_END_ENTRY
 };
@@ -1574,43 +2804,46 @@ const ExtractEntrySearchData kLolDscYProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscTileIndexProvider[] = {
+const ExtractEntrySearchData kLolEobCommonDscTileIndexProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000012, 0x00000099, { { 0x18, 0xD9, 0x39, 0x27, 0x5B, 0x34, 0xAE, 0x7C, 0xA9, 0xA9, 0xDB, 0x42, 0x49, 0x61, 0x6B, 0x37 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscUnk2Provider[] = {
+const ExtractEntrySearchData kLolEobCommonDscUnk2Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000017, 0x000000D2, { { 0xDE, 0xDA, 0x75, 0x15, 0x2B, 0xDC, 0x90, 0x3F, 0xC9, 0x92, 0x04, 0x01, 0x23, 0x7A, 0xDA, 0x2E } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscDoorShapeIndexProvider[] = {
-	{ UNK_LANG, kPlatformUnknown, { 0x00000017, 0x0000000A, { { 0x2E, 0xC4, 0xA1, 0x47, 0x7C, 0xAE, 0xAD, 0xD8, 0x8A, 0x72, 0x95, 0x2F, 0x18, 0xC5, 0x08, 0x19 } } } },
-
+const ExtractEntrySearchData kLolEobCommonDscDoorShapeIndexProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000017, 0x0000000A, { { 0x2E, 0xC4, 0xA1, 0x47, 0x7C, 0xAE, 0xAD, 0xD8, 0x8A, 0x72, 0x95, 0x2F, 0x18, 0xC5, 0x08, 0x19 } } } }, // LOL
+	{ UNK_LANG, kPlatformUnknown, { 0x00000020, 0x00000021, { { 0xE3, 0x00, 0x85, 0x1C, 0x13, 0xCE, 0x5D, 0xA7, 0xA2, 0x93, 0x9B, 0x56, 0x1A, 0x0C, 0x43, 0x3E } } } }, // EOB 1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000035, 0x0000000B, { { 0xC2, 0xBC, 0xCA, 0x95, 0x69, 0xE8, 0x3F, 0x1F, 0xC2, 0x1C, 0x37, 0x90, 0x63, 0x8F, 0xE6, 0x1D } } } }, // EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscDimData1Provider[] = {
+const ExtractEntrySearchData kLolEobCommonDscDimData1Provider[] = {
+	// LOL
 	{ UNK_LANG, kPlatformUnknown, { 0x00000144, 0x0001007D, { { 0x18, 0x3D, 0xA5, 0xF7, 0x1A, 0x5A, 0x90, 0xA7, 0x4E, 0x66, 0x1A, 0x4E, 0x0C, 0x69, 0x58, 0x31 } } } },
-
+	// EOB
+	{ UNK_LANG, kPlatformUnknown, { 0x00000144, 0x00010115, { { 0x89, 0x37, 0x1C, 0x85, 0x53, 0xEE, 0xC0, 0xEC, 0x17, 0x26, 0x0B, 0xE5, 0xCC, 0x9C, 0x30, 0x58 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscDimData2Provider[] = {
-	{ UNK_LANG, kPlatformUnknown, { 0x00000289, 0x00001BC2, { { 0x7F, 0x9D, 0xD3, 0x5A, 0x57, 0x73, 0xEA, 0x37, 0x44, 0x5E, 0x1A, 0x88, 0xFB, 0xE8, 0xE8, 0x8F } } } },
+const ExtractEntrySearchData kLolEobCommonDscDimData2Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000288, 0x00001BC2, { { 0x30, 0xD1, 0xD1, 0x35, 0x74, 0x2C, 0x86, 0x81, 0x23, 0xE2, 0x05, 0xCE, 0x75, 0x60, 0x3C, 0x55 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscBlockMapProvider[] = {
+const ExtractEntrySearchData kLolEobCommonDscBlockMapProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000000C, 0x00000012, { { 0x01, 0xEE, 0x32, 0xA6, 0x71, 0x15, 0x8D, 0xFB, 0x33, 0xF2, 0xD6, 0x8A, 0x30, 0x00, 0x10, 0x4B } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscDimMapProvider[] = {
+const ExtractEntrySearchData kLolEobCommonDscDimMapProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000012, 0x00000014, { { 0x4D, 0x53, 0x2E, 0xF2, 0xA3, 0xF9, 0xE2, 0xEC, 0x44, 0xBE, 0x5F, 0x04, 0x91, 0xF8, 0xE1, 0x04 } } } },
 
 	EXTRACT_END_ENTRY
@@ -1622,15 +2855,15 @@ const ExtractEntrySearchData kLolDscOvlIndexProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscBlockIndexProvider[] = {
+const ExtractEntrySearchData kLolEobCommonDscBlockIndexProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000048, 0x00002200, { { 0xF4, 0x8B, 0x32, 0xC3, 0xD3, 0xFB, 0x46, 0xF2, 0xB8, 0x3A, 0x58, 0x39, 0x94, 0x57, 0x97, 0x4B } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscDoor1Provider[] = {
-	{ UNK_LANG, kPlatformUnknown, { 0x00000080, 0x00000348, { { 0xC6, 0x58, 0x8B, 0xFE, 0x18, 0x72, 0x47, 0xF1, 0xB6, 0x3A, 0x0F, 0xFB, 0x3D, 0x99, 0x74, 0xD0 } } } },
-
+const ExtractEntrySearchData kLolEobCommonDscDoorY2Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000080, 0x00000348, { { 0xC6, 0x58, 0x8B, 0xFE, 0x18, 0x72, 0x47, 0xF1, 0xB6, 0x3A, 0x0F, 0xFB, 0x3D, 0x99, 0x74, 0xD0 } } } }, // LOL
+	{ UNK_LANG, kPlatformUnknown, { 0x00000004, 0x00000046, { { 0x35, 0x36, 0xBC, 0xD8, 0x63, 0x25, 0x31, 0xA9, 0x61, 0x8E, 0xF6, 0x54, 0x4A, 0x79, 0x17, 0xF8 } } } }, // EOB
 	EXTRACT_END_ENTRY
 };
 
@@ -1933,7 +3166,248 @@ const ExtractEntry extractProviders[] = {
 	{ k3SfxMap, k3SfxMapProvider },
 	{ k3ItemAnimData, k3ItemAnimDataProvider },
 	{ k3ItemMagicTable, k3ItemMagicTableProvider },
-	{ k3ItemStringMap, k3ItemStringMapProvider },
+	{ k3ItemStringMap, k3ItemStringMapProvider },	
+	
+	{ kEobBaseChargenStrings1, kEobBaseChargenStrings1Provider },
+	{ kEobBaseChargenStrings2, kEobBaseChargenStrings2Provider },
+	{ kEobBaseChargenStartLevels, kEobBaseChargenStartLevelsProvider },
+	{ kEobBaseChargenStatStrings, kEobBaseChargenStatStringsProvider },
+	{ kEobBaseChargenRaceSexStrings, kEobBaseChargenRaceSexStringsProvider },
+	{ kEobBaseChargenClassStrings, kEobBaseChargenClassStringsProvider },
+	{ kEobBaseChargenAlignmentStrings, kEobBaseChargenAlignmentStringsProvider },
+	{ kEobBaseChargenEnterGameStrings, kEobBaseChargenEnterGameStringsProvider },
+	{ kEobBaseChargenClassMinStats, kEobBaseChargenClassMinStatsProvider },
+	{ kEobBaseChargenRaceMinStats, kEobBaseChargenRaceMinStatsProvider },
+	{ kEobBaseChargenRaceMaxStats, kEobBaseChargenRaceMaxStatsProvider },
+
+	{ kEobBaseConstModTable1, kEobBaseConstModTable1Provider },
+	{ kEobBaseConstModTable2, kEobBaseConstModTable2Provider },
+	{ kEobBaseConstModTable3, kEobBaseConstModTable3Provider },
+	{ kEobBaseConstModTable4, kEobBaseConstModTable4Provider },
+	{ kEobBaseConstModLvlIndex, kEobBaseConstModLvlIndexProvider },
+	{ kEobBaseConstModDiv, kEobBaseConstModDivProvider },
+	{ kEobBaseConstModExt, kEobBaseConstModExtProvider },
+	
+	{ kEobBasePryDoorStrings, kEobBasePryDoorStringsProvider },
+	{ kEobBaseWarningStrings, kEobBaseWarningStringsProvider },
+	{ kEobBaseItemSuffixStrings, kEobBaseItemSuffixStringsProvider },
+	{ kEobBaseItemExtraStrings, kEobBaseItemExtraStringsProvider },
+	{ kEobBaseTakenStrings, kEobBaseTakenStringsProvider },
+	{ kEobBasePotionEffectStrings, kEobBasePotionEffectStringsProvider },
+
+	{ kEobBaseYesNoStrings, kEobBaseYesNoStringsProvider },
+	{ kLolEobCommonMoreStrings, kLolEobCommonMoreStringsProvider },
+	{ kEobBaseNpcMaxStrings, kEobBaseNpcMaxStringsProvider },
+	{ kEobBaseOkStrings, kEobBaseOkStringsProvider },
+	{ kEobBaseNpcJoinStrings, kEobBaseNpcJoinStringsProvider },
+	{ kEobBaseCancelStrings, kEobBaseCancelStringsProvider },
+	{ kEobBaseAbortStrings, kEobBaseAbortStringsProvider },
+
+	{ kEobBaseCharGuiStringsHp, kEobBaseCharGuiStringsHpProvider },
+	{ kEobBaseCharGuiStringsWp1, kEobBaseCharGuiStringsWp1Provider },
+	{ kEobBaseCharGuiStringsWp2, kEobBaseCharGuiStringsWp2Provider },
+	{ kEobBaseCharGuiStringsWr, kEobBaseCharGuiStringsWrProvider },
+	{ kEobBaseCharGuiStringsSt1, kEobBaseCharGuiStringsSt1Provider },
+	{ kEobBaseCharGuiStringsSt2, kEobBaseCharGuiStringsSt2Provider },
+	{ kEobBaseCharGuiStringsIn, kEobBaseCharGuiStringsInProvider },
+
+	{ kEobBaseCharStatusStrings7, kEobBaseCharStatusStrings7Provider },
+	{ kEobBaseCharStatusStrings81, kEobBaseCharStatusStrings81Provider },
+	{ kEobBaseCharStatusStrings82, kEobBaseCharStatusStrings82Provider },
+	{ kEobBaseCharStatusStrings9, kEobBaseCharStatusStrings9Provider },
+	{ kEobBaseCharStatusStrings12, kEobBaseCharStatusStrings12Provider },
+	{ kEobBaseCharStatusStrings131, kEobBaseCharStatusStrings131Provider },
+	{ kEobBaseCharStatusStrings132, kEobBaseCharStatusStrings132Provider },
+
+	{ kEobBaseLevelGainStrings, kEobBaseLevelGainStringsProvider },
+	{ kEobBaseExperienceTable0, kEobBaseExperienceTable0Provider },
+	{ kEobBaseExperienceTable1, kEobBaseExperienceTable1Provider },
+	{ kEobBaseExperienceTable2, kEobBaseExperienceTable2Provider },
+	{ kEobBaseExperienceTable3, kEobBaseExperienceTable3Provider },
+	{ kEobBaseExperienceTable4, kEobBaseExperienceTable4Provider },
+
+	{ kEobBaseWllFlagPreset, kEobBaseWllFlagPresetProvider },
+	{ kEobBaseDscShapeCoords, kEobBaseDscShapeCoordsProvider },
+	{ kEobBaseDscDoorScaleOffs, kEobBaseDscDoorScaleOffsProvider },
+	{ kEobBaseDscDoorScaleMult1, kEobBaseDscDoorScaleMult1Provider },
+	{ kEobBaseDscDoorScaleMult2, kEobBaseDscDoorScaleMult2Provider },
+	{ kEobBaseDscDoorScaleMult3, kEobBaseDscDoorScaleMult3Provider },
+	{ kEobBaseDscDoorScaleMult4, kEobBaseDscDoorScaleMult4Provider },
+	{ kEobBaseDscDoorScaleMult5, kEobBaseDscDoorScaleMult5Provider },
+	{ kEobBaseDscDoorScaleMult6, kEobBaseDscDoorScaleMult6Provider },
+	{ kEobBaseDscDoorType5Offs, kEobBaseDscDoorType5OffsProvider },
+	{ kEobBaseDscDoorY1, kEobBaseDscDoorY1Provider },
+	{ kEobBaseDscDoorY3, kEobBaseDscDoorY3Provider },
+	{ kEobBaseDscDoorY4, kEobBaseDscDoorY4Provider },
+	{ kEobBaseDscDoorY5, kEobBaseDscDoorY5Provider },
+	{ kEobBaseDscDoorY6, kEobBaseDscDoorY6Provider },
+	{ kEobBaseDscDoorCoordsExt, kEobBaseDscDoorCoordsExtProvider },
+	{ kEobBaseDscItemPosIndex, kEobBaseDscItemPosIndexProvider },
+	{ kEobBaseDscItemShpX, kEobBaseDscItemShpXProvider },
+	{ kEobBaseDscItemPosUnk, kEobBaseDscItemPosUnkProvider },
+	{ kEobBaseDscItemTileIndex, kEobBaseDscItemTileIndexProvider },
+	{ kEobBaseDscItemShapeMap, kEobBaseDscItemShapeMapProvider },
+	{ kEobBaseDscTelptrShpCoords, kEobBaseDscTelptrShpCoordsProvider },
+
+	{ kEobBaseDscMonsterFrmOffsTbl1, kEobBaseDscMonsterFrmOffsTbl1Provider },
+	{ kEobBaseDscMonsterFrmOffsTbl2, kEobBaseDscMonsterFrmOffsTbl2Provider },
+
+	{ kEobBaseInvSlotX, kEobBaseInvSlotXProvider },
+	{ kEobBaseInvSlotY, kEobBaseInvSlotYProvider },
+	{ kEobBaseSlotValidationFlags, kEobBaseSlotValidationFlagsProvider },
+	{ kEobBaseDrawObjPosIndex, kEobBaseDrawObjPosIndexProvider },
+	{ kEobBaseFlightObjFlipIndex, kEobBaseFlightObjFlipIndexProvider },
+	{ kEobBaseFlightObjShpMap, kEobBaseFlightObjShpMapProvider },
+	{ kEobBaseFlightObjSclIndex, kEobBaseFlightObjSclIndexProvider },
+
+	{ kEobBaseBookNumbers, kEobBaseBookNumbersProvider },
+	{ kEobBaseMageSpellsList, kEobBaseMageSpellsListProvider },
+	{ kEobBaseClericSpellsList, kEobBaseClericSpellsListProvider },
+	{ kEobBaseSpellNames, kEobBaseSpellNamesProvider },
+	{ kEobBaseMagicStrings1, kEobBaseMagicStrings1Provider },
+	{ kEobBaseMagicStrings2, kEobBaseMagicStrings2Provider },
+	{ kEobBaseMagicStrings3, kEobBaseMagicStrings3Provider },
+	{ kEobBaseMagicStrings4, kEobBaseMagicStrings4Provider },
+	{ kEobBaseMagicStrings5, kEobBaseMagicStrings5Provider },
+	{ kEobBaseMagicStrings6, kEobBaseMagicStrings6Provider },
+	{ kEobBaseMagicStrings7, kEobBaseMagicStrings7Provider },
+	{ kEobBaseMagicStrings8, kEobBaseMagicStrings8Provider },
+	
+	{ kEobBaseSparkDefSteps, kEobBaseSparkDefStepsProvider },
+	{ kEobBaseSparkDefSubSteps, kEobBaseSparkDefSubStepsProvider },
+	{ kEobBaseSparkDefShift, kEobBaseSparkDefShiftProvider },
+	{ kEobBaseSparkDefAdd, kEobBaseSparkDefAddProvider },
+	{ kEobBaseSparkDefX, kEobBaseSparkDefXProvider },
+	{ kEobBaseSparkDefY, kEobBaseSparkDefYProvider },
+	{ kEobBaseSparkOfFlags1, kEobBaseSparkOfFlags1Provider },
+	{ kEobBaseSparkOfFlags2, kEobBaseSparkOfFlags2Provider },
+	{ kEobBaseSparkOfShift, kEobBaseSparkOfShiftProvider },
+	{ kEobBaseSparkOfX, kEobBaseSparkOfXProvider },
+	{ kEobBaseSparkOfY, kEobBaseSparkOfYProvider },
+
+	{ kEobBaseSpellProperties, kEobBaseSpellPropertiesProvider },
+	{ kEobBaseMagicFlightProps, kEobBaseMagicFlightPropsProvider },
+
+	{ kEob1MainMenuStrings, kEob1MainMenuStringsProvider },
+	{ kEob1DoorShapeDefs, kEob1DoorShapeDefsProvider },
+	{ kEob1DoorSwitchShapeDefs, kEob1DoorSwitchShapeDefsProvider },
+	{ kEob1DoorSwitchCoords, kEob1DoorSwitchCoordsProvider },
+	{ kEob1MonsterProperties, kEob1MonsterPropertiesProvider },
+
+	{ kEob1MonsterDistAttType10, kEob1MonsterDistAttType10Provider },
+	{ kEob1MonsterDistAttSfx10, kEob1MonsterDistAttSfx10Provider },
+	{ kEob1MonsterDistAttType17, kEob1MonsterDistAttType17Provider },
+	{ kEob1MonsterDistAttSfx17, kEob1MonsterDistAttSfx17Provider },
+
+	{ kEob2MainMenuStrings, kEob2MainMenuStringsProvider },
+	{ kEob2IntroStrings, kEob2IntroStringsProvider },
+	{ kEob2IntroCPSFiles, kEob2IntroCPSFilesProvider },
+	{ kEob2IntroSeqData00, kEob2IntroSeqData00Provider },
+ 	{ kEob2IntroSeqData01, kEob2IntroSeqData01Provider },
+ 	{ kEob2IntroSeqData02, kEob2IntroSeqData02Provider },
+ 	{ kEob2IntroSeqData03, kEob2IntroSeqData03Provider },
+ 	{ kEob2IntroSeqData04, kEob2IntroSeqData04Provider },
+ 	{ kEob2IntroSeqData05, kEob2IntroSeqData05Provider },
+ 	{ kEob2IntroSeqData06, kEob2IntroSeqData06Provider },
+ 	{ kEob2IntroSeqData07, kEob2IntroSeqData07Provider },
+ 	{ kEob2IntroSeqData08, kEob2IntroSeqData08Provider },
+ 	{ kEob2IntroSeqData09, kEob2IntroSeqData09Provider },
+ 	{ kEob2IntroSeqData10, kEob2IntroSeqData10Provider },
+ 	{ kEob2IntroSeqData11, kEob2IntroSeqData11Provider },
+ 	{ kEob2IntroSeqData12, kEob2IntroSeqData12Provider },
+ 	{ kEob2IntroSeqData13, kEob2IntroSeqData13Provider },
+ 	{ kEob2IntroSeqData14, kEob2IntroSeqData14Provider },
+ 	{ kEob2IntroSeqData15, kEob2IntroSeqData15Provider },
+ 	{ kEob2IntroSeqData16, kEob2IntroSeqData16Provider },
+ 	{ kEob2IntroSeqData17, kEob2IntroSeqData17Provider },
+ 	{ kEob2IntroSeqData18, kEob2IntroSeqData18Provider },
+ 	{ kEob2IntroSeqData19, kEob2IntroSeqData19Provider },
+ 	{ kEob2IntroSeqData20, kEob2IntroSeqData20Provider },
+ 	{ kEob2IntroSeqData21, kEob2IntroSeqData21Provider },
+ 	{ kEob2IntroSeqData22, kEob2IntroSeqData22Provider },
+ 	{ kEob2IntroSeqData23, kEob2IntroSeqData23Provider },
+ 	{ kEob2IntroSeqData24, kEob2IntroSeqData24Provider },
+ 	{ kEob2IntroSeqData25, kEob2IntroSeqData25Provider },
+ 	{ kEob2IntroSeqData26, kEob2IntroSeqData26Provider },
+ 	{ kEob2IntroSeqData27, kEob2IntroSeqData27Provider },
+ 	{ kEob2IntroSeqData28, kEob2IntroSeqData28Provider },
+ 	{ kEob2IntroSeqData29, kEob2IntroSeqData29Provider },
+ 	{ kEob2IntroSeqData30, kEob2IntroSeqData30Provider },
+ 	{ kEob2IntroSeqData31, kEob2IntroSeqData31Provider },
+ 	{ kEob2IntroSeqData32, kEob2IntroSeqData32Provider },
+ 	{ kEob2IntroSeqData33, kEob2IntroSeqData33Provider },
+ 	{ kEob2IntroSeqData34, kEob2IntroSeqData34Provider },
+ 	{ kEob2IntroSeqData35, kEob2IntroSeqData35Provider },
+ 	{ kEob2IntroSeqData36, kEob2IntroSeqData36Provider },
+ 	{ kEob2IntroSeqData37, kEob2IntroSeqData37Provider },
+ 	{ kEob2IntroSeqData38, kEob2IntroSeqData38Provider },
+ 	{ kEob2IntroSeqData39, kEob2IntroSeqData39Provider },
+ 	{ kEob2IntroSeqData40, kEob2IntroSeqData40Provider },
+ 	{ kEob2IntroSeqData41, kEob2IntroSeqData41Provider },
+ 	{ kEob2IntroSeqData42, kEob2IntroSeqData42Provider },
+ 	{ kEob2IntroSeqData43, kEob2IntroSeqData43Provider },
+	{ kEob2IntroShapes00, kEob2IntroShapes00Provider },
+ 	{ kEob2IntroShapes01, kEob2IntroShapes01Provider },
+ 	{ kEob2IntroShapes04, kEob2IntroShapes04Provider },
+ 	{ kEob2IntroShapes07, kEob2IntroShapes07Provider },
+
+	{ kEob2FinaleStrings, kEob2FinaleStringsProvider },
+	{ kEob2CreditsData, kEob2CreditsDataProvider },
+	{ kEob2FinaleCPSFiles, kEob2FinaleCPSFilesProvider },
+	{ kEob2FinaleSeqData00, kEob2FinaleSeqData00Provider },
+ 	{ kEob2FinaleSeqData01, kEob2FinaleSeqData01Provider },
+ 	{ kEob2FinaleSeqData02, kEob2FinaleSeqData02Provider },
+ 	{ kEob2FinaleSeqData03, kEob2FinaleSeqData03Provider },
+ 	{ kEob2FinaleSeqData04, kEob2FinaleSeqData04Provider },
+ 	{ kEob2FinaleSeqData05, kEob2FinaleSeqData05Provider },
+ 	{ kEob2FinaleSeqData06, kEob2FinaleSeqData06Provider },
+ 	{ kEob2FinaleSeqData07, kEob2FinaleSeqData07Provider },
+ 	{ kEob2FinaleSeqData08, kEob2FinaleSeqData08Provider },
+ 	{ kEob2FinaleSeqData09, kEob2FinaleSeqData09Provider },
+ 	{ kEob2FinaleSeqData10, kEob2FinaleSeqData10Provider },
+ 	{ kEob2FinaleSeqData11, kEob2FinaleSeqData11Provider },
+ 	{ kEob2FinaleSeqData12, kEob2FinaleSeqData12Provider },
+ 	{ kEob2FinaleSeqData13, kEob2FinaleSeqData13Provider },
+ 	{ kEob2FinaleSeqData14, kEob2FinaleSeqData14Provider },
+ 	{ kEob2FinaleSeqData15, kEob2FinaleSeqData15Provider },
+ 	{ kEob2FinaleSeqData16, kEob2FinaleSeqData16Provider },
+ 	{ kEob2FinaleSeqData17, kEob2FinaleSeqData17Provider },
+ 	{ kEob2FinaleSeqData18, kEob2FinaleSeqData18Provider },
+ 	{ kEob2FinaleSeqData19, kEob2FinaleSeqData19Provider },
+ 	{ kEob2FinaleSeqData20, kEob2FinaleSeqData20Provider },
+	{ kEob2FinaleShapes00, kEob2FinaleShapes00Provider },
+ 	{ kEob2FinaleShapes03, kEob2FinaleShapes03Provider },
+ 	{ kEob2FinaleShapes07, kEob2FinaleShapes07Provider },
+ 	{ kEob2FinaleShapes09, kEob2FinaleShapes09Provider },
+ 	{ kEob2FinaleShapes10, kEob2FinaleShapes10Provider },
+
+	{ kEob2NpcShapeData, kEob2NpcShapeDataProvider },
+	{ kEobBaseClassModifierFlags, kEobBaseClassModifierFlagsProvider },
+
+	{ kEobBaseMonsterStepTable01, kEobBaseMonsterStepTable01Provider },
+	{ kEobBaseMonsterStepTable02, kEobBaseMonsterStepTable02Provider },
+	{ kEobBaseMonsterStepTable1, kEobBaseMonsterStepTable1Provider },
+	{ kEobBaseMonsterStepTable2, kEobBaseMonsterStepTable2Provider },
+	{ kEobBaseMonsterStepTable3, kEobBaseMonsterStepTable3Provider },
+	{ kEobBaseMonsterCloseAttPosTable1, kEobBaseMonsterCloseAttPosTable1Provider },
+	{ kEobBaseMonsterCloseAttPosTable21, kEobBaseMonsterCloseAttPosTable21Provider },
+	{ kEobBaseMonsterCloseAttPosTable22, kEobBaseMonsterCloseAttPosTable22Provider },
+	{ kEobBaseMonsterCloseAttUnkTable, kEobBaseMonsterCloseAttUnkTableProvider },
+	{ kEobBaseMonsterCloseAttChkTable1, kEobBaseMonsterCloseAttChkTable1Provider },
+	{ kEobBaseMonsterCloseAttChkTable2, kEobBaseMonsterCloseAttChkTable2Provider },
+	{ kEobBaseMonsterCloseAttDstTable1, kEobBaseMonsterCloseAttDstTable1Provider },
+	{ kEobBaseMonsterCloseAttDstTable2, kEobBaseMonsterCloseAttDstTable2Provider },
+	
+	{ kEobBaseMonsterProximityTable, kEobBaseMonsterProximityTableProvider },
+	{ kEobBaseFindBlockMonstersTable, kEobBaseFindBlockMonstersTableProvider },
+	{ kEobBaseMonsterDirChangeTable, kEobBaseMonsterDirChangeTableProvider },
+	{ kEobBaseMonsterDistAttStrings, kEobBaseMonsterDistAttStringsProvider },
+	{ kEobBaseEncodeMonsterDefs, kEobBaseEncodeMonsterDefsProvider },
+	{ kEobBaseNpcPresets, kEobBaseNpcPresetsProvider },
+	{ kEob2Npc1Strings, kEob2Npc1StringsProvider },
+	{ kEob2Npc2Strings, kEob2Npc2StringsProvider },
+	{ kEob2MonsterDustStrings, kEob2MonsterDustStringsProvider },
+	
 	{ kLolIngamePakFiles, kLolIngamePakFilesProvider },
 	{ kLolCharacterDefs, kLolCharacterDefsProvider },
 	{ kLolIngameSfxFiles, kLolIngameSfxFilesProvider },
@@ -1965,23 +3439,23 @@ const ExtractEntry extractProviders[] = {
 	{ kLolCompassDefs, kLolCompassDefsProvider },
 	{ kLolItemPrices, kLolItemPricesProvider },
 	{ kLolStashSetup, kLolStashSetupProvider },
-	{ kLolDscUnk1, kLolDscUnk1Provider },
-	{ kLolDscShapeIndex, kLolDscShapeIndexProvider },
+	{ kLolDscWalls, kLolDscWallsProvider },
+	{ kLolEobCommonDscShapeIndex, kLolEobCommonDscShapeIndexProvider },
 	{ kLolDscOvlMap, kLolDscOvlMapProvider },
 	{ kLolDscScaleWidthData, kLolDscScaleWidthDataProvider },
 	{ kLolDscScaleHeightData, kLolDscScaleHeightDataProvider },
-	{ kLolDscX, kLolDscXProvider },
+	{ kLolEobCommonDscX, kLolEobCommonDscXProvider },
 	{ kLolDscY, kLolDscYProvider },
-	{ kLolDscTileIndex, kLolDscTileIndexProvider },
-	{ kLolDscUnk2, kLolDscUnk2Provider },
-	{ kLolDscDoorShapeIndex, kLolDscDoorShapeIndexProvider },
-	{ kLolDscDimData1, kLolDscDimData1Provider },
-	{ kLolDscDimData2, kLolDscDimData2Provider },
-	{ kLolDscBlockMap, kLolDscBlockMapProvider },
-	{ kLolDscDimMap, kLolDscDimMapProvider },
+	{ kLolEobCommonDscTileIndex, kLolEobCommonDscTileIndexProvider },
+	{ kLolEobCommonDscUnk2, kLolEobCommonDscUnk2Provider },
+	{ kLolEobCommonDscDoorShapeIndex, kLolEobCommonDscDoorShapeIndexProvider },
+	{ kLolEobCommonDscDimData1, kLolEobCommonDscDimData1Provider },
+	{ kLolEobCommonDscDimData2, kLolEobCommonDscDimData2Provider },
+	{ kLolEobCommonDscBlockMap, kLolEobCommonDscBlockMapProvider },
+	{ kLolEobCommonDscDimMap, kLolEobCommonDscDimMapProvider },
 	{ kLolDscOvlIndex, kLolDscOvlIndexProvider },
-	{ kLolDscBlockIndex, kLolDscBlockIndexProvider },
-	{ kLolDscDoor1, kLolDscDoor1Provider },
+	{ kLolEobCommonDscBlockIndex, kLolEobCommonDscBlockIndexProvider },
+	{ kLolEobCommonDscDoorY2, kLolEobCommonDscDoorY2Provider },
 	{ kLolDscDoorScale, kLolDscDoorScaleProvider },
 	{ kLolDscDoor4, kLolDscDoor4Provider },
 	{ kLolDscDoorX, kLolDscDoorXProvider },


Commit: 540d081a6fd4daa31f746ddf30ccc91fb88ea04b
    https://github.com/scummvm/scummvm/commit/540d081a6fd4daa31f746ddf30ccc91fb88ea04b
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:10-08:00

Commit Message:
KYRA: (EOB) - initial code base commit

Changed paths:
  A engines/kyra/chargen.cpp
  A engines/kyra/eob1.cpp
  A engines/kyra/eob1.h
  A engines/kyra/eob2.cpp
  A engines/kyra/eob2.h
  A engines/kyra/eobcommon.cpp
  A engines/kyra/eobcommon.h
  A engines/kyra/gui_eob.cpp
  A engines/kyra/gui_eob.h
  A engines/kyra/items_eob.cpp
  A engines/kyra/loleobbase.cpp
  A engines/kyra/loleobbase.h
  A engines/kyra/magic_eob.cpp
  A engines/kyra/saveload_eob.cpp
  A engines/kyra/scene_eob.cpp
  A engines/kyra/screen_eob.cpp
  A engines/kyra/screen_eob.h
  A engines/kyra/script_eob.cpp
  A engines/kyra/script_eob.h
  A engines/kyra/sequences_eob1.cpp
  A engines/kyra/sequences_eob2.cpp
  A engines/kyra/sprites_eob.cpp
  A engines/kyra/staticres_eob.cpp
  A engines/kyra/text_eob.cpp
  A engines/kyra/text_eob.h
  A engines/kyra/timer_eob.cpp
    configure
    engines/engines.mk
    engines/kyra/detection.cpp
    engines/kyra/detection_tables.h
    engines/kyra/gui.h
    engines/kyra/gui_lol.cpp
    engines/kyra/gui_lol.h
    engines/kyra/kyra_hof.cpp
    engines/kyra/kyra_hof.h
    engines/kyra/kyra_mr.cpp
    engines/kyra/kyra_mr.h
    engines/kyra/kyra_v1.cpp
    engines/kyra/kyra_v1.h
    engines/kyra/kyra_v2.h
    engines/kyra/lol.cpp
    engines/kyra/lol.h
    engines/kyra/module.mk
    engines/kyra/resource.cpp
    engines/kyra/resource.h
    engines/kyra/resource_intern.cpp
    engines/kyra/saveload_lol.cpp
    engines/kyra/scene_lol.cpp
    engines/kyra/screen.cpp
    engines/kyra/screen.h
    engines/kyra/script.cpp
    engines/kyra/script.h
    engines/kyra/script_hof.cpp
    engines/kyra/script_lok.cpp
    engines/kyra/script_lol.cpp
    engines/kyra/script_mr.cpp
    engines/kyra/script_tim.cpp
    engines/kyra/script_tim.h
    engines/kyra/sound.cpp
    engines/kyra/sound_lol.cpp
    engines/kyra/sprites_lol.cpp
    engines/kyra/staticres.cpp
    engines/kyra/staticres_lol.cpp
    engines/kyra/text_lol.cpp
    engines/kyra/text_lol.h
    engines/kyra/timer.cpp
    engines/kyra/timer_lol.cpp



diff --git a/configure b/configure
index 7bdf38f..f01c009 100755
--- a/configure
+++ b/configure
@@ -94,8 +94,9 @@ add_engine gob "Gobli*ns" yes
 add_engine groovie "Groovie" yes "groovie2"
 add_engine groovie2 "Groovie 2 games" no
 add_engine hugo "Hugo Trilogy" yes
-add_engine kyra "Legend of Kyrandia" yes "lol"
+add_engine kyra "Legend of Kyrandia" yes "lol eob"
 add_engine lol "Lands of Lore" yes
+add_engine eob "Eye of the Beholder" no
 add_engine lastexpress "The Last Express" no
 add_engine lure "Lure of the Temptress" yes
 add_engine made "MADE" yes
diff --git a/engines/engines.mk b/engines/engines.mk
index 5280bf9..9939506 100644
--- a/engines/engines.mk
+++ b/engines/engines.mk
@@ -87,6 +87,10 @@ MODULES += engines/kyra
 ifdef ENABLE_LOL
 DEFINES += -DENABLE_LOL
 endif
+
+ifdef ENABLE_EOB
+DEFINES += -DENABLE_EOB
+endif
 endif
 
 ifdef ENABLE_LASTEXPRESS
diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
new file mode 100644
index 0000000..4a0e035
--- /dev/null
+++ b/engines/kyra/chargen.cpp
@@ -0,0 +1,1495 @@
+/* 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.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/eobcommon.h"
+#include "kyra/resource.h"
+#include "kyra/sound_intern.h"
+
+namespace Kyra {
+
+class CharacterGenerator {
+public:
+	CharacterGenerator(EobCoreEngine *vm, Screen_Eob *screen);
+	~CharacterGenerator();
+
+	void start(EobCharacter *characters, uint8 ***faceShapes);
+
+private:
+	void init();
+	void initButtonsFromList(int first, int numButtons);
+	void initButton(int index, int x, int y, int w, int h, int keyCode);
+	void checkForCompleteParty();
+	void toggleSpecialButton(int index, int bodyCustom, int pageNum);
+	void processSpecialButton(int index);
+	void highlightBoxFrame(int index);
+	int viewDeleteCharacter();
+	void createPartyMember();
+	int raceSexMenu();
+	int classMenu(int raceSex);
+	int alignmentMenu(int cClass);
+	void updateMagicShapes();
+	void generateStats(int index);
+	void modifyMenu();
+	void statsAndFacesMenu();
+	void faceSelectMenu();
+	int getNextFreeFaceShape(int shpIndex, int charSex, int step, int8 *selectedPortraits);
+	void processFaceMenuSelection(int index);
+	void printStats(int index, int mode);
+	void processNameInput(int index, int len, int textColor);
+	int rollDice();
+	int modifyStat(int index, int8 *stat1, int8 *stat2);
+	int getMaxHp(int cclass, int constitution, int level1, int level2, int level3);
+	int getMinHp(int cclass, int constitution, int level1, int level2, int level3);
+	void finish();
+
+	uint8 **_chargenMagicShapes;
+	uint8 **_chargenButtonLabels;
+	int _activeBox;
+	int _magicShapesBox;
+	int _updateBoxIndex;
+	int _updateBoxColorIndex;
+	int _updateBoxShapesIndex;
+	int _lastUpdateBoxShapesIndex;
+	uint32 _chargenBoxTimer;
+	uint32 _chargenMagicShapeTimer;
+	int8 _chargenSelectedPortraits[4];
+	int8 _chargenSelectedPortraits2[4];
+
+	uint16 _chargenMinStats[7];
+	uint16 _chargenMaxStats[7];
+
+	const char *const *_chargenStrings1;
+	const char *const *_chargenStrings2;
+	const char *const *_chargenStatStrings;
+	const char *const *_chargenRaceSexStrings;
+	const char *const *_chargenClassStrings;
+	const char *const *_chargenAlignmentStrings;
+	const char *const *_chargenEnterGameStrings;
+
+	const uint8 *_chargenStartLevels;
+	const uint8 *_chargenClassMinStats;
+	const uint8 *_chargenRaceMinStats;
+	const uint16 *_chargenRaceMaxStats;
+
+	static const EobChargenButtonDef _chargenButtonDefs[];
+	static const CreatePartyModButton _chargenModButtons[];
+	static const EobRect8 _chargenButtonBodyCoords[];
+	static const EobRect16 _chargenPortraitBoxFrames[];
+	static const int16 _chargenBoxX[];
+	static const int16 _chargenBoxY[];
+	static const int16 _chargenNameFieldX[];
+	static const int16 _chargenNameFieldY[];
+
+	static const int32 _classMenuMasks[];
+	static const int32 _alignmentMenuMasks[];
+
+	static const int16 _raceModifiers[];
+
+	EobCharacter *_characters;
+	uint8 **_faceShapes;
+
+	EobCoreEngine *_vm;
+	Screen_Eob *_screen;
+};
+
+void EobCoreEngine::startCharacterGeneration() {
+	CharacterGenerator(this, _screen).start(_characters, &_faceShapes);
+}
+
+CharacterGenerator::CharacterGenerator(EobCoreEngine *vm, Screen_Eob *screen) : _vm(vm), _screen(screen),
+	_characters(0), _faceShapes(0), _chargenMagicShapes(0), _chargenButtonLabels(0), _updateBoxIndex(-1),
+	_chargenBoxTimer(0), _chargenMagicShapeTimer(0), _updateBoxColorIndex(0), _updateBoxShapesIndex(0),
+	_lastUpdateBoxShapesIndex(0), _magicShapesBox(6), _activeBox(0) {
+
+	_chargenStatStrings = _vm->_chargenStatStrings;
+	_chargenRaceSexStrings = _vm->_chargenRaceSexStrings;
+	_chargenClassStrings = _vm->_chargenClassStrings;
+	_chargenAlignmentStrings = _vm->_chargenAlignmentStrings;
+
+	memset(_chargenSelectedPortraits, -1, sizeof(_chargenSelectedPortraits));
+	memset(_chargenSelectedPortraits2, 0, sizeof(_chargenSelectedPortraits2));
+	memset(_chargenMinStats, 0, sizeof(_chargenMinStats));
+	memset(_chargenMaxStats, 0, sizeof(_chargenMaxStats));
+
+	int temp;
+	_chargenStrings1 = _vm->staticres()->loadStrings(kEobBaseChargenStrings1, temp);
+	_chargenStrings2 = _vm->staticres()->loadStrings(kEobBaseChargenStrings2, temp);
+	_chargenStartLevels = _vm->staticres()->loadRawData(kEobBaseChargenStartLevels, temp);
+	_chargenEnterGameStrings = _vm->staticres()->loadStrings(kEobBaseChargenEnterGameStrings, temp);
+	_chargenClassMinStats = _vm->staticres()->loadRawData(kEobBaseChargenClassMinStats, temp);
+	_chargenRaceMinStats = _vm->staticres()->loadRawData(kEobBaseChargenRaceMinStats, temp);
+	_chargenRaceMaxStats = _vm->staticres()->loadRawDataBe16(kEobBaseChargenRaceMaxStats, temp);
+}
+
+CharacterGenerator::~CharacterGenerator() {
+	if (_chargenMagicShapes) {
+		for (int i = 0; i < 10; i++)
+			delete[] _chargenMagicShapes[i];
+		delete[] _chargenMagicShapes;
+	}
+
+	if (_chargenButtonLabels) {
+		for (int i = 0; i < 10; i++)
+			delete[] _chargenButtonLabels[i];
+		delete[] _chargenButtonLabels;
+	}
+}
+
+void CharacterGenerator::start(EobCharacter *characters, uint8 ***faceShapes) {
+	if (!characters && !faceShapes)
+		return;
+
+	_characters = characters;
+	_faceShapes = *faceShapes;
+
+	_vm->sound()->playTrack(0);
+
+	_vm->delay(_vm->_tickLength);
+
+	init();
+
+	_screen->setScreenDim(2);
+
+	checkForCompleteParty();
+	initButtonsFromList(0, 5);
+
+	_vm->sound()->playTrack(_vm->game() == GI_EOB1 ? 20 : 13);
+	_activeBox = 0;
+
+	for (bool loop = true; loop && (!_vm->shouldQuit()); ) {
+		highlightBoxFrame(_activeBox + 6);
+		_vm->sound()->process();
+		int inputFlag = _vm->checkInput(_vm->_activeButtons, false, 0);
+		_vm->removeInputTop();
+
+		if (inputFlag) {
+			if (inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT])
+				_activeBox ^= 1;
+			else if (inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN])
+				_activeBox ^= 2;
+			highlightBoxFrame(-1);
+		}
+
+		if (inputFlag & 0x8000) {
+			inputFlag = (inputFlag & 0x0f) - 1;
+			if (inputFlag == 4) {
+				loop = false;
+			} else {
+				_activeBox = inputFlag;
+				inputFlag = 43;
+			}
+		}
+
+		if (inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP5]) {
+			highlightBoxFrame(-1);
+			if (_characters[_activeBox].name[0]) {
+				int b = _activeBox;
+				if (viewDeleteCharacter())
+					loop = false;
+				if (b != _activeBox && !_characters[_activeBox].name[0])
+					createPartyMember();
+			} else {
+				createPartyMember();
+			}
+
+			initButtonsFromList(0, 5);
+			checkForCompleteParty();
+		}
+
+		if (loop == false) {
+			for (int i = 0; i < 4; i++) {
+				if (!_characters[i].name[0])
+					loop = true;
+			}
+		}
+	}
+
+	if (!_vm->shouldQuit()) {
+		processSpecialButton(15);
+		finish();
+	}
+
+	_vm->sound()->playTrack(15);
+
+	*faceShapes = _faceShapes;
+}
+
+void CharacterGenerator::init() {
+	_screen->loadEobBitmap("CHARGENA", 3, 3);
+	if (_faceShapes) {
+		for (int i = 0; i < 44; i++)
+			delete[] _faceShapes[i];
+		delete[] _faceShapes;
+	}
+
+	_faceShapes = new uint8*[44];
+	for (int i = 0; i < 44; i++)
+		_faceShapes[i] = _screen->encodeShape((i % 10) << 2, (i / 10) << 5, 4, 32, true);
+	_screen->_curPage = 0;
+
+	_screen->loadEobCpsFileToPage("CHARGEN", 0, 3, 3, 0);
+	_screen->loadEobBitmap("CHARGENB", 3, 3);
+	if (_chargenMagicShapes) {
+		for (int i = 0; i < 10; i++)
+			delete[] _chargenMagicShapes[i];
+		delete[] _chargenMagicShapes;
+	}
+
+	_chargenMagicShapes = new uint8*[10];
+	for (int i = 0; i < 10; i++)
+		_chargenMagicShapes[i] = _screen->encodeShape(i << 2, 0, 4, 32, true);
+
+	_chargenButtonLabels = new uint8*[17];
+	for (int i = 0; i < 17; i++) {
+		const CreatePartyModButton *c = &_chargenModButtons[i];
+		_chargenButtonLabels[i] = c->labelW? _screen->encodeShape(c->encodeLabelX, c->encodeLabelY, c->labelW, c->labelH, true) : 0;
+	}
+
+	_screen->copyPage(3, 2);
+	_screen->_curPage = 0;
+	_screen->copyRegion(144, 64, 0, 0, 180, 128, 0, 2, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+}
+
+void CharacterGenerator::initButtonsFromList(int first, int numButtons) {
+	_vm->gui_resetButtonList();
+
+	for (int i = 0; i < numButtons; i++) {
+		const EobChargenButtonDef *e = &_chargenButtonDefs[first + i];
+		initButton(i, e->x, e->y, e->w, e->h, e->keyCode);
+	}
+
+	_vm->gui_notifyButtonListChanged();
+}
+
+void CharacterGenerator::initButton(int index, int x, int y, int w, int h, int keyCode) {
+	Button *b = 0;
+	int cnt = 1;
+
+	if (_vm->_activeButtons) {
+		Button *n = _vm->_activeButtons;
+		while (n->nextButton) {
+			++cnt;
+			n = n->nextButton;
+		}
+
+		++cnt;
+		b = n->nextButton = &_vm->_activeButtonData[cnt];
+	} else {
+		b = &_vm->_activeButtonData[0];
+		_vm->_activeButtons = b;
+	}
+
+	*b = Button();
+	b->flags = 0x1100;
+	b->data0Val2 = 12;
+	b->data1Val2 = b->data2Val2 = 15;
+	b->data3Val2 = 8;
+
+	b->index = index + 1;
+	b->x = x << 3;
+	b->y = y;
+	b->width = w;
+	b->height = h;
+	b->keyCode = keyCode;
+	b->keyCode2 = keyCode + 0x100;
+}
+
+void CharacterGenerator::checkForCompleteParty() {
+	_screen->copyRegion(0, 0, 160, 0, 160, 128, 2, 2, Screen::CR_NO_P_CHECK);
+	int cp = _screen->setCurPage(2);
+	_screen->printShadedText(_chargenStrings1[8], 168, 16, 15, 0);
+	_screen->setCurPage(cp);
+	_screen->copyRegion(160, 0, 144, 64, 160, 128, 2, 0, Screen::CR_NO_P_CHECK);
+
+	int numChars = 0;
+	for (int i = 0; i < 4; i++) {
+		if (_characters[i].name[0])
+			numChars++;
+	}
+
+	if (numChars == 4) {
+		_screen->setCurPage(2);
+		_screen->printShadedText(_chargenStrings1[0], 168, 61, 15, 0);
+		_screen->setCurPage(0);
+		_screen->copyRegion(168, 61, 152, 125, 136, 40, 2, 0, Screen::CR_NO_P_CHECK);
+		toggleSpecialButton(15, 0, 0);
+	} else {
+		toggleSpecialButton(14, 0, 0);
+	}
+
+	_screen->updateScreen();
+}
+
+void CharacterGenerator::toggleSpecialButton(int index, int bodyCustom, int pageNum) {
+	if (index >= 17)
+		return;
+
+	const CreatePartyModButton *c = &_chargenModButtons[index];
+	const EobRect8 *p = &_chargenButtonBodyCoords[c->bodyIndex + bodyCustom];
+
+	int x2 = 20;
+	int y2 = 0;
+
+	if (pageNum) {
+		x2 = c->destX + 2;
+		y2 = c->destY - 64;
+	}
+
+	_screen->copyRegion(p->x << 3, p->y, x2 << 3, y2, p->w << 3, p->h, 2, 2, Screen::CR_NO_P_CHECK);
+	if (c->labelW)
+		_screen->drawShape(2, _chargenButtonLabels[index], (x2 << 3) + c->labelX, y2 + c->labelY, 0);
+
+	if (pageNum == 2)
+		return;
+
+	_screen->copyRegion(160, 0, c->destX << 3, c->destY, p->w << 3, p->h, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+}
+
+void CharacterGenerator::processSpecialButton(int index) {
+	toggleSpecialButton(index, 1, 0);
+	_vm->sound()->playSoundEffect(76);
+	_vm->_system->delayMillis(80);
+	toggleSpecialButton(index, 0, 0);
+}
+
+void CharacterGenerator::highlightBoxFrame(int index) {
+	static const uint8 colorTable[] = { 0x0F, 0xB0, 0xB2, 0xB4, 0xB6,
+		0xB8, 0xBA, 0xBC, 0x0C, 0xBC, 0xBA, 0xB8, 0xB6, 0xB4, 0xB2, 0xB0, 0x00
+	};
+
+	if (_updateBoxIndex == index) {
+		if (_updateBoxIndex == -1)
+			return;
+
+		if (_vm->_system->getMillis() <= _chargenBoxTimer)
+			return;
+
+		if (!colorTable[_updateBoxColorIndex])
+			_updateBoxColorIndex = 0;
+
+		const EobRect16 *r = &_chargenPortraitBoxFrames[_updateBoxIndex];
+		_screen->drawBox(r->x1, r->y1, r->x2, r->y2, colorTable[_updateBoxColorIndex++]);
+		_screen->updateScreen();
+
+		_chargenBoxTimer = _vm->_system->getMillis() + _vm->_tickLength;
+
+	} else {
+		if (_updateBoxIndex != -1) {
+			const EobRect16 *r = &_chargenPortraitBoxFrames[_updateBoxIndex];
+			_screen->drawBox(r->x1, r->y1, r->x2, r->y2, 12);
+			_screen->updateScreen();
+		}
+
+		_updateBoxColorIndex = 0;
+		_updateBoxIndex = index;
+		_chargenBoxTimer = _vm->_system->getMillis();
+	}
+}
+
+int CharacterGenerator::viewDeleteCharacter() {
+	initButtonsFromList(0, 7);
+	_vm->removeInputTop();
+
+	highlightBoxFrame(-1);
+	printStats(_activeBox, 2);
+
+	int res = 0;
+	for (bool loop = true; loop && _characters[_activeBox].name[0] && !_vm->shouldQuit(); ) {
+		highlightBoxFrame(_activeBox + 6);
+		_vm->sound()->process();
+
+		int inputFlag = _vm->checkInput(_vm->_activeButtons, false, 0);
+		int cbx = _activeBox;
+		_vm->removeInputTop();
+
+		if (inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP5] || inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE]) {
+			processSpecialButton(9);
+			res = 0;
+			loop = false;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT]) {
+			cbx ^= 1;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN]) {
+			cbx ^= 2;
+		}
+
+		if (inputFlag & 0x8000) {
+			inputFlag = (inputFlag & 0x0f) - 1;
+			if (inputFlag == 4) {
+				res = 1;
+				loop = false;
+			} else if (inputFlag == 5) {
+				processSpecialButton(9);
+				res = 0;
+				loop = false;
+			} else if (inputFlag == 6) {
+				if (_characters[_activeBox].name[0]) {
+					processSpecialButton(16);
+					_characters[_activeBox].name[0] = 0;
+					processNameInput(_activeBox, 1, 12);
+					processFaceMenuSelection(_activeBox + 50);
+				}
+			} else {
+				cbx = inputFlag;
+			}
+		}
+
+		if (loop == false)
+			highlightBoxFrame(-1);
+
+		if (!_characters[cbx].name[0])
+			loop = false;
+
+		if (cbx != _activeBox) {
+			_activeBox = cbx;
+			highlightBoxFrame(-1);
+			if (loop)
+				printStats(_activeBox, 2);
+		}
+	}
+
+	return res;
+}
+
+void CharacterGenerator::createPartyMember() {
+	_screen->setScreenDim(2);
+	_chargenBoxTimer = 0;
+
+	for (int i = 0; i != 3 && !_vm->shouldQuit(); i++) {
+		bool bck = false;
+
+		switch (i) {
+		case 0:
+			_characters[_activeBox].raceSex = raceSexMenu();
+			break;
+		case 1:
+			_characters[_activeBox].cClass = classMenu(_characters[_activeBox].raceSex);
+			if (_characters[_activeBox].cClass == _vm->_keyMap[Common::KEYCODE_ESCAPE])
+				bck = true;
+			break;
+		case 2:
+			_characters[_activeBox].alignment = alignmentMenu(_characters[_activeBox].cClass);
+			if (_characters[_activeBox].alignment == _vm->_keyMap[Common::KEYCODE_ESCAPE])
+				bck = true;
+			break;
+		default:
+			break;
+		}
+
+		if (bck)
+			i -= 2;
+	};
+
+	if (!_vm->shouldQuit()) {
+		generateStats(_activeBox);
+		statsAndFacesMenu();
+
+		for (_characters[_activeBox].name[0] = 0; _characters[_activeBox].name[0] == 0 && !_vm->shouldQuit(); ) {
+			processFaceMenuSelection(_chargenMinStats[6]);
+			printStats(_activeBox, 0);
+			_screen->printShadedText(_chargenStrings2[11], 149, 100, 9, 0);
+			if (!_vm->shouldQuit())
+				processNameInput(_activeBox, _vm->_gui->getTextInput(_characters[_activeBox].name, 24, 100, 10, 15, 0, 8), 2);
+		}
+	}
+}
+
+int CharacterGenerator::raceSexMenu() {
+	_screen->drawBox(_chargenBoxX[_activeBox], _chargenBoxY[_activeBox], _chargenBoxX[_activeBox] + 32, _chargenBoxY[_activeBox] + 33, 12);
+	_screen->copyRegion(0, 0, 144, 64, 160, 128, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->printShadedText(_chargenStrings2[8], 147, 67, 9, 0);
+	_vm->removeInputTop();
+
+	_vm->_gui->setupMenu(1, 0, _chargenRaceSexStrings, -1, 0, 0);
+	int16 res = -1;
+
+	while (res == -1 && !_vm->shouldQuit()) {
+		res = _vm->_gui->handleMenu(1, _chargenRaceSexStrings, 0, -1, 0);
+		updateMagicShapes();
+	}
+
+	return res;
+}
+
+int CharacterGenerator::classMenu(int raceSex) {
+	int32 itemsMask = -1;
+
+	for (int i = 0; i < 4; i++) {
+		// check for evil characters
+		if (_characters[i].name[0] && _characters[i].alignment > 5)
+			itemsMask = 0xFFFB;
+	}
+
+	_vm->removeInputTop();
+	updateMagicShapes();
+
+	_screen->copyRegion(0, 0, 144, 64, 160, 128, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->printShadedText(_chargenStrings2[9], 147, 67, 9, 0);
+
+	toggleSpecialButton(5, 0, 0);
+
+	itemsMask &=_classMenuMasks[raceSex / 2];
+	_vm->_gui->setupMenu(2, 15, _chargenClassStrings, itemsMask, 0, 0);
+
+	_vm->_mouseX = _vm->_mouseY = 0;
+	int16 res = -1;
+
+	while (res == -1 && !_vm->shouldQuit()) {
+		updateMagicShapes();
+
+		int in = _vm->checkInput(0, false, 0) & 0xff;
+		Common::Point mp = _vm->getMousePos();
+
+		if (in == _vm->_keyMap[Common::KEYCODE_ESCAPE] || _vm->_gui->_menuLastInFlags == _vm->_keyMap[Common::KEYCODE_ESCAPE] || _vm->_gui->_menuLastInFlags == _vm->_keyMap[Common::KEYCODE_b]) {
+			res = _vm->_keyMap[Common::KEYCODE_ESCAPE];
+		} else if (_vm->posWithinRect(mp.x, mp.y, 264, 171, 303, 187)) {
+			if (in == 199 || in == 201)
+				res = _vm->_keyMap[Common::KEYCODE_ESCAPE];
+			else
+				_vm->removeInputTop();
+		} else {
+			res = _vm->_gui->handleMenu(2, _chargenClassStrings, 0, itemsMask, 0);
+		}
+	}
+
+	_vm->removeInputTop();
+
+	if (res == _vm->_keyMap[Common::KEYCODE_ESCAPE])
+		processSpecialButton(5);
+
+	return res;
+}
+
+int CharacterGenerator::alignmentMenu(int cClass) {
+	int32 itemsMask = -1;
+
+	for (int i = 0; i < 4; i++) {
+		// check for paladins
+		if (_characters[i].name[0] && _characters[i].cClass == 2)
+			itemsMask = 0xFE3F;
+	}
+
+	_vm->removeInputTop();
+	updateMagicShapes();
+
+	_screen->copyRegion(0, 0, 144, 64, 160, 128, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->printShadedText(_chargenStrings2[10], 147, 67, 9, 0);
+
+	toggleSpecialButton(5, 0, 0);
+
+	itemsMask &=_alignmentMenuMasks[cClass];
+	_vm->_gui->setupMenu(3, 9, _chargenAlignmentStrings, itemsMask, 0, 0);
+
+	_vm->_mouseX = _vm->_mouseY = 0;
+	int16 res = -1;
+
+	while (res == -1 && !_vm->shouldQuit()) {
+		updateMagicShapes();
+
+		int in = _vm->checkInput(0, false, 0) & 0xff;
+		Common::Point mp = _vm->getMousePos();
+
+		if (in == _vm->_keyMap[Common::KEYCODE_ESCAPE] || _vm->_gui->_menuLastInFlags == _vm->_keyMap[Common::KEYCODE_ESCAPE] || _vm->_gui->_menuLastInFlags == _vm->_keyMap[Common::KEYCODE_b]) {
+			res = _vm->_keyMap[Common::KEYCODE_ESCAPE];
+		} else if (_vm->posWithinRect(mp.x, mp.y, 264, 171, 303, 187)) {
+			if (in == 199 || in == 201)
+				res = _vm->_keyMap[Common::KEYCODE_ESCAPE];
+			else
+				_vm->removeInputTop();
+		} else {
+			res = _vm->_gui->handleMenu(3, _chargenAlignmentStrings, 0, itemsMask, 0);
+		}
+	}
+
+	_vm->removeInputTop();
+
+	if (res == _vm->_keyMap[Common::KEYCODE_ESCAPE])
+		processSpecialButton(5);
+
+	return res;
+}
+
+void CharacterGenerator::updateMagicShapes() {
+	_vm->sound()->process();
+
+	if (_magicShapesBox != _activeBox) {
+		_chargenMagicShapeTimer = 0;
+		_magicShapesBox = _activeBox;
+	}
+
+	if (_chargenMagicShapeTimer < _vm->_system->getMillis()) {
+		if (++_updateBoxShapesIndex > 9)
+			_updateBoxShapesIndex = 0;
+		_chargenMagicShapeTimer = _vm->_system->getMillis() + 2 * _vm->_tickLength;
+	}
+
+	if (_updateBoxShapesIndex == _lastUpdateBoxShapesIndex)
+		return;
+
+	_screen->copyRegion(_activeBox << 5, 128, 288, 128, 32, 32, 2, 2, Screen::CR_NO_P_CHECK);
+	_screen->drawShape(2, _chargenMagicShapes[_updateBoxShapesIndex], 288, 128, 0);
+	_screen->copyRegion(288, 128, _chargenBoxX[_activeBox], _chargenBoxY[_activeBox] + 1, 32, 32, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+
+	_lastUpdateBoxShapesIndex = _updateBoxShapesIndex;
+}
+
+void CharacterGenerator::generateStats(int index) {
+	EobCharacter *c = &_characters[index];
+
+	for (int i = 0; i < 3; i++) {
+		c->level[i] = _chargenStartLevels[(c->cClass << 2) + i];
+		c->experience[i] = (_vm->game() == GI_EOB2 ? 69000 : 5000) / _chargenStartLevels[(c->cClass << 2) + 3];
+	}
+
+	int rc = c->raceSex >> 1;
+	for (int i = 0; i < 6; i++) {
+		_chargenMinStats[i] = MAX(_chargenClassMinStats[c->cClass * 6 + i], _chargenRaceMinStats[rc * 6 + i]);
+		_chargenMaxStats[i] = _chargenRaceMaxStats[rc * 6 + i];
+	}
+
+	if (_vm->_charClassModUnk[c->cClass])
+		_chargenMaxStats[0] = 18;
+
+	uint16 sv[6];
+	for (int i = 0; i < 6; i++) {
+		sv[i] = MAX<uint16>(rollDice() + _raceModifiers[rc * 6 + i], _chargenMinStats[i]);
+		if (!i && sv[i] == 18)
+			sv[i] |= (uint16)(_vm->rollDice(1, 100) << 8);
+		if (sv[i] > _chargenMaxStats[i])
+			sv[i] = _chargenMaxStats[i];
+	}
+
+	c->strengthCur = c->strengthMax = sv[0] & 0xff;
+	c->strengthExtCur = c->strengthExtMax = sv[0] >> 8;
+	c->intelligenceCur = c->intelligenceMax = sv[1] & 0xff;
+	c->wisdomCur = c->wisdomMax = sv[2] & 0xff;
+	c->dexterityCur = c->dexterityMax = sv[3] & 0xff;
+	c->constitutionCur = c->constitutionMax = sv[4] & 0xff;
+	c->charismaCur = c->charismaMax = sv[5] & 0xff;
+	c->armorClass = 10 + _vm->getDexterityArmorClassModifier(sv[3] & 0xff);
+	c->hitPointsCur = 0;
+
+	for (int l = 0; l < 3; l++) {
+		for (int i = 0; i < c->level[l]; i++)
+			c->hitPointsCur += _vm->generateCharacterHitpointsByLevel(index, 1 << l);
+	}
+
+	c->hitPointsMax = c->hitPointsCur;
+}
+
+void CharacterGenerator::modifyMenu() {
+	_vm->removeInputTop();
+	printStats(_activeBox, 3);
+
+	EobCharacter *c = &_characters[_activeBox];
+	int8 hpLO = c->hitPointsCur;
+
+	for (int i = 0; i >= 0 && i < 7; ) {
+		switch (i) {
+		case 0:
+			i = modifyStat(i, &c->strengthCur, &c->strengthExtCur);
+			break;
+		case 1:
+			i = modifyStat(i, &c->intelligenceCur, 0);
+			break;
+		case 2:
+			i = modifyStat(i, &c->wisdomCur, 0);
+			break;
+		case 3:
+			i = modifyStat(i, &c->dexterityCur, 0);
+			break;
+		case 4:
+			i = modifyStat(i, &c->constitutionCur, 0);
+			break;
+		case 5:
+			i = modifyStat(i, &c->charismaCur, 0);
+			break;
+		case 6:
+			hpLO = c->hitPointsCur;
+			i = modifyStat(i, &hpLO, 0);
+			c->hitPointsCur = hpLO;
+			break;
+		default:
+			break;
+		}
+
+		if (i == -2 || _vm->shouldQuit())
+			break;
+		else if (i < 0)
+			i = 6;
+		i %= 7;
+
+		printStats(_activeBox, 3);
+	}
+
+	printStats(_activeBox, 1);
+}
+
+void CharacterGenerator::statsAndFacesMenu() {
+	faceSelectMenu();
+	printStats(_activeBox, 1);
+	initButtonsFromList(27, 4);
+	_vm->removeInputTop();
+	int in = 0;
+
+	while (!in && !_vm->shouldQuit()) {
+		updateMagicShapes();
+		in = _vm->checkInput(_vm->_activeButtons, false, 0);
+		_vm->removeInputTop();
+
+		if (in == 0x8001) {
+			processSpecialButton(4);
+			updateMagicShapes();
+			generateStats(_activeBox);
+			in = -1;
+		} else if (in == 0x8002) {
+			processSpecialButton(7);
+			modifyMenu();
+			in = -1;
+		} else if (in == 0x8003) {
+			processSpecialButton(8);
+			faceSelectMenu();
+			in = -1;
+		} else if (in == 0x8004 || in == _vm->_keyMap[Common::KEYCODE_KP5]) {
+			processSpecialButton(6);
+			in = 1;
+		} else {
+			in = 0;
+		}
+
+		if (in & 0x8000) {
+			printStats(_activeBox, 1);
+			initButtonsFromList(27, 4);
+			in = 0;
+		}
+	}
+
+	highlightBoxFrame(6 + _activeBox);
+	highlightBoxFrame(-1);
+}
+
+void CharacterGenerator::faceSelectMenu() {
+	int8 sp[4];
+	memcpy(sp, _chargenSelectedPortraits2, sizeof(sp));
+	_vm->removeInputTop();
+	initButtonsFromList(21, 6);
+
+	int charSex = _characters[_activeBox].raceSex % 2;
+	int8 shp = charSex ? 26 : 0;
+
+	printStats(_activeBox, 4);
+	toggleSpecialButton(12, 0, 0);
+	toggleSpecialButton(13, 0, 0);
+	highlightBoxFrame(-1);
+
+	shp = getNextFreeFaceShape(shp, charSex, 1, _chargenSelectedPortraits);
+
+	int res = -1;
+	int box = 1;
+
+	while (res == -1 && !_vm->shouldQuit()) {
+		int8 shpOld = shp;
+
+		for (int i = 0; i < 4; i++) {
+			sp[i] = shp;
+			_screen->drawShape(0, _faceShapes[sp[i]], 176 + (i << 5), 66, 0);
+			shp = getNextFreeFaceShape(shp + 1, charSex, 1, _chargenSelectedPortraits);
+		}
+
+		shp = shpOld;
+		int in = 0;
+
+		while (!in && !_vm->shouldQuit()) {
+			updateMagicShapes();
+			in = _vm->checkInput(_vm->_activeButtons, false, 0);
+			_vm->removeInputTop();
+
+			highlightBoxFrame(box + 10);
+
+			if (in == 0x8002 || in == _vm->_keyMap[Common::KEYCODE_RIGHT]) {
+				processSpecialButton(13);
+				in = 2;
+			} else if (in > 0x8002 && in < 0x8007) {
+				box = (in & 7) - 3;
+				in = 3;
+			} else if (in == 0x8001 || in == _vm->_keyMap[Common::KEYCODE_LEFT]) {
+				processSpecialButton(12);
+				in = 1;
+			} else if (in == _vm->_keyMap[Common::KEYCODE_RETURN] || in == _vm->_keyMap[Common::KEYCODE_KP5]) {
+				in = 3;
+			} else if (in & 0x8000) {
+				in &= 0xff;
+			} else {
+				in = 0;
+			}
+		}
+
+		highlightBoxFrame(-1);
+
+		if (in == 1)
+			shp = getNextFreeFaceShape(shp - 1, charSex, -1, _chargenSelectedPortraits);
+		else if (in == 2)
+			shp = getNextFreeFaceShape(shp + 1, charSex, 1, _chargenSelectedPortraits);
+		else if (in == 3)
+			res = box;
+	}
+
+	if (!_vm->shouldQuit()) {
+		highlightBoxFrame(-1);
+		updateMagicShapes();
+
+		_chargenSelectedPortraits[_activeBox] = sp[res];
+		_characters[_activeBox].portrait = sp[res];
+		_characters[_activeBox].faceShape = _faceShapes[sp[res]];
+
+		printStats(_activeBox, 1);
+	}
+}
+
+int CharacterGenerator::getNextFreeFaceShape(int shpIndex, int charSex, int step, int8 *selectedPortraits) {
+	int shpCur = ((shpIndex < 0) ? 43 : shpIndex) % 44;
+	bool notUsable = false;
+
+	do {
+		notUsable = false;
+		for (int i = 0; i < 4; i++) {
+			if (_characters[i].name[0] && selectedPortraits[i] == shpCur)
+				notUsable = true;
+		}
+
+		if ((charSex && (shpCur < 26)) || (!charSex && (shpCur > 28)))
+			notUsable = true;
+
+		if (notUsable) {
+			shpCur += step;
+			shpCur = ((shpCur < 0) ? 43 : shpCur) % 44;
+		}
+	} while (notUsable);
+
+	return shpCur;
+}
+
+void CharacterGenerator::processFaceMenuSelection(int index) {
+	highlightBoxFrame(-1);
+	if (index <= 48)
+		_screen->drawShape(0, _characters[_activeBox].faceShape, _chargenBoxX[_activeBox], _chargenBoxY[_activeBox] + 1, 0);
+	else
+		toggleSpecialButton(index - 50, 0, 0);
+}
+
+void CharacterGenerator::printStats(int index, int mode) {
+	_screen->copyRegion(0, 0, 160, 0, 160, 128, 2, 2, Screen::CR_NO_P_CHECK);
+	_screen->_curPage = 2;
+
+	EobCharacter *c = &_characters[index];
+
+	if (mode != 4)
+		_screen->drawShape(2, c->faceShape, 224, 2, 0);
+
+	_screen->printShadedText(c->name, 160 + ((20 - strlen(c->name)) << 2), 35, 15, 0);
+	_screen->printShadedText(_chargenRaceSexStrings[c->raceSex], 160 + ((20 - strlen(_chargenRaceSexStrings[c->raceSex])) << 2), 45, 15, 0);
+	_screen->printShadedText(_chargenClassStrings[c->cClass], 160 + ((20 - strlen(_chargenClassStrings[c->cClass])) << 2), 54, 15, 0);
+
+	for (int i = 0; i < 6; i++)
+		_screen->printShadedText(_chargenStatStrings[i], 163, (i + 8) << 3, 15, 0);
+
+	_screen->printShadedText(_chargenStrings1[2], 248, 64, 15, 0);
+
+	char str[22];
+	snprintf(str, 22,  _chargenStrings1[3], _vm->getCharStrength(c->strengthCur, c->strengthExtCur), c->intelligenceCur, c->wisdomCur, c->dexterityCur, c->constitutionCur, c->charismaCur);
+	_screen->printShadedText(str, 192, 64, 15, 0);
+
+	snprintf(str, 22, _chargenStrings1[4], c->armorClass, c->hitPointsMax);
+	_screen->printShadedText(str, 280, 64, 15, 0);
+
+	const char *lvlStr = c->level[2] ? _chargenStrings1[7] : (c->level[1] ? _chargenStrings1[6] : _chargenStrings1[5]);
+	snprintf(str, 22, lvlStr, c->level[0], c->level[1], c->level[2]);
+	_screen->printShadedText(str, 280, 80, 15, 0);
+
+	switch (mode) {
+	case 1:
+		toggleSpecialButton(4, 0, 2);
+		toggleSpecialButton(7, 0, 2);
+		toggleSpecialButton(8, 0, 2);
+		toggleSpecialButton(6, 0, 2);
+		break;
+
+	case 2:
+		toggleSpecialButton(16, 0, 2);
+		toggleSpecialButton(9, 0, 2);
+		break;
+
+	case 3:
+		toggleSpecialButton(10, 0, 2);
+		toggleSpecialButton(11, 0, 2);
+		toggleSpecialButton(9, 0, 2);
+		break;
+
+	default:
+		break;
+	}
+
+	_screen->copyRegion(160, 0, 144, 64, 160, 128, 2, 0, Screen::CR_NO_P_CHECK);
+
+	if (mode != 3)
+		_screen->updateScreen();
+
+	_screen->_curPage = 0;
+}
+
+void CharacterGenerator::processNameInput(int index, int len, int textColor) {
+	Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+
+	// WORKAROUND for bug in original code:
+	len = strlen(_characters[index].name);
+
+	int xOffs = (60 - _screen->getFontWidth() * len) >> 1;
+	_screen->printText(_chargenStrings1[1], _chargenNameFieldX[index], _chargenNameFieldY[index], 12, 12);
+	_screen->printText(_characters[index].name, _chargenNameFieldX[index] + xOffs, _chargenNameFieldY[index], textColor, 0);
+	_screen->updateScreen();
+	_screen->setFont(of);
+}
+
+int CharacterGenerator::rollDice() {
+	int res = 0;
+	int min = 10;
+
+	for (int i = 0; i < 4; i++) {
+		int d = _vm->rollDice(1, 6, 0);
+		res += d;
+		if (d < min)
+			min = d;
+	}
+
+	res -= min;
+	return res;
+}
+
+int CharacterGenerator::modifyStat(int index, int8 *stat1, int8 *stat2) {
+	uint8 *s1 = (uint8*) stat1;
+	uint8 *s2 = (uint8*) stat2;
+
+	initButtonsFromList(31, 10);
+	Button *b = _vm->gui_getButton(_vm->_activeButtons, index + 1);
+
+	printStats(_activeBox, 3);
+	_vm->removeInputTop();
+
+	char statStr[6];
+	if (index)
+		snprintf(statStr, 6, "%d", *s1);
+	else
+		snprintf(statStr, 6, "%s", _vm->getCharStrength(*s1, *s2));
+
+	_screen->copyRegion(b->x - 112, b->y - 64, b->x + 32, b->y, 40, b->height, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->printShadedText(statStr, b->x + 32, b->y, 6, 0);
+	_screen->updateScreen();
+
+	EobCharacter *c = &_characters[_activeBox];
+
+	int ci = index;
+	uint8 v2 = s2 ? *s2 : 0;
+
+	if (index == 6) {
+		_chargenMaxStats[6] = getMaxHp(c->cClass, c->constitutionCur, c->level[0], c->level[1], c->level[2]);
+		_chargenMinStats[6] = getMinHp(c->cClass, c->constitutionCur, c->level[0], c->level[1], c->level[2]);
+	}
+
+	for (bool loop = true; loop && !_vm->shouldQuit(); ) {
+		uint8 v1 = *s1;
+		updateMagicShapes();
+		int	inputFlag = _vm->checkInput(_vm->_activeButtons, false, 0);
+		_vm->removeInputTop();
+
+		if (inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_MINUS] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP_MINUS] || inputFlag == 0x8009) {
+			processSpecialButton(11);
+			v1--;
+
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP6] || inputFlag == _vm->_keyMap[Common::KEYCODE_PLUS] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP_PLUS] || inputFlag == 0x8008) {
+			processSpecialButton(10);
+			v1++;
+
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP8]) {
+			ci = --ci % 7;
+			loop = false;
+
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP2]) {
+			ci = ++ci % 7;
+			loop = false;
+
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_o] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP5] || inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE] || inputFlag == 0x800A) {
+			processSpecialButton(9);
+			loop = false;
+			ci = -2;
+
+		} else if (inputFlag & 0x8000) {
+			inputFlag = (inputFlag & 0x0f) - 1;
+			if (index != inputFlag) {
+				ci = inputFlag;
+				loop = false;
+			}
+		}
+
+		if (v1 == *s1)
+			continue;
+
+		if (!index) {
+			while (v1 > 18) {
+				v1--;
+				v2++;
+			}
+			while (v2 > 0 && v1 < 18) {
+				v1++;
+				v2--;
+			}
+
+			v1 = CLIP<uint8>(v1, _chargenMinStats[index], _chargenMaxStats[index] & 0xff);
+			v2 = (v1 == 18 && _chargenMaxStats[index] >= 19) ? CLIP<uint8>(v2, 0, 100) : 0;
+			if (s2)
+				*s2 = v2;
+			else
+				error("CharacterGenerator::modifyStat:...");
+		} else {
+			v1 = CLIP<uint8>(v1, _chargenMinStats[index], _chargenMaxStats[index]);
+		}
+
+		*s1 = v1;
+
+		if (index == 6)
+			_characters[_activeBox].hitPointsMax = v1;
+
+		if (index)
+			snprintf(statStr, 6, "%d", *s1);
+		else
+			snprintf(statStr, 6, "%s", _vm->getCharStrength(*s1, *s2));
+
+		_screen->copyRegion(b->x - 112, b->y - 64, b->x + 32, b->y, 40, b->height, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->printShadedText(statStr, b->x + 32, b->y, 6, 0);
+		_screen->updateScreen();
+
+		if (index == 4) {
+			int oldVal = c->hitPointsCur;
+			_chargenMaxStats[6] = getMaxHp(c->cClass, c->constitutionCur, c->level[0], c->level[1], c->level[2]);
+			_chargenMinStats[6] = getMinHp(c->cClass, c->constitutionCur, c->level[0], c->level[1], c->level[2]);
+			c->hitPointsMax = c->hitPointsCur = CLIP<int16>(c->hitPointsCur, _chargenMinStats[6], _chargenMaxStats[6]);
+
+			if (c->hitPointsCur != oldVal) {
+				snprintf(statStr, 6, "%d", c->hitPointsCur);
+				_screen->copyRegion(120, 72, 264, 136, 40, 8, 2, 0, Screen::CR_NO_P_CHECK);
+				_screen->printShadedText(statStr, 264, 136, 15, 0);
+				_screen->updateScreen();
+			}
+
+		} else if (index == 3) {
+			int oldVal = c->armorClass;
+			c->armorClass = _vm->getDexterityArmorClassModifier(v1) + 10;
+
+			if (c->armorClass != oldVal) {
+				snprintf(statStr, 6, "%d", c->armorClass);
+				_screen->copyRegion(120, 64, 264, 128, 40, 8, 2, 0, Screen::CR_NO_P_CHECK);
+				_screen->printShadedText(statStr, 264, 128, 15, 0);
+				_screen->updateScreen();
+			}
+		}
+
+		if (loop = false) {
+			if (index)
+				snprintf(statStr, 6, "%d", *s1);
+			else
+				snprintf(statStr, 6, "%s", _vm->getCharStrength(*s1, *s2));
+			_screen->printText(statStr, b->x + 32, b->y, 15, 0);
+			_screen->updateScreen();
+		}
+	}
+
+	return ci;
+}
+
+int CharacterGenerator::getMaxHp(int cclass, int constitution, int level1, int level2, int level3) {
+	int res = 0;
+	constitution = _vm->getClassAndConstHitpointsModifier(cclass, constitution);
+
+	int m = _vm->getClassHpIncreaseType(cclass, 0);
+	if (m != -1)
+		res = _vm->getModifiedHpLimits(m, constitution, level1, false);
+
+	m = _vm->getClassHpIncreaseType(cclass, 1);
+	if (m != -1)
+		res += _vm->getModifiedHpLimits(m, constitution, level2, false);
+
+	m = _vm->getClassHpIncreaseType(cclass, 2);
+	if (m != -1)
+		res += _vm->getModifiedHpLimits(m, constitution, level3, false);
+
+	res /= _vm->_numLevelsPerClass[cclass];
+
+	return res;
+}
+
+int CharacterGenerator::getMinHp(int cclass, int constitution, int level1, int level2, int level3) {
+	int res = 0;
+	constitution = _vm->getClassAndConstHitpointsModifier(cclass, constitution);
+
+	int m = _vm->getClassHpIncreaseType(cclass, 0);
+	if (m != -1)
+		res = _vm->getModifiedHpLimits(m, constitution, level1, true);
+
+	m = _vm->getClassHpIncreaseType(cclass, 1);
+	if (m != -1)
+		res += _vm->getModifiedHpLimits(m, constitution, level2, true);
+
+	m = _vm->getClassHpIncreaseType(cclass, 2);
+	if (m != -1)
+		res += _vm->getModifiedHpLimits(m, constitution, level3, true);
+
+	res /= _vm->_numLevelsPerClass[cclass];
+
+	return res;
+}
+
+void CharacterGenerator::finish() {
+	_screen->copyRegion(0, 0, 160, 0, 160, 128, 2, 2, Screen::CR_NO_P_CHECK);
+	int cp = _screen->setCurPage(2);
+	_screen->printShadedText(_chargenEnterGameStrings[0], 168, 32, 15, 0);
+	_screen->setCurPage(cp);
+	_screen->copyRegion(160, 0, 144, 64, 160, 128, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+
+	if (_vm->game() == GI_EOB1) {
+		static const int8 classDefaultItemsList[] = { 1, 17, 2, 17, 46, -1, 4, -1, 5, -1, 6, 2, 7, -1, 8, -1, 9, 21, 10, 2, 31, 2 };
+		static const int8 classDefaultItemsListIndex[] = { 4, 8, 0, -1, 4, 3, 0, -1, 4, 10, 0, 8, 3, 6, 1, -1, 2, 7, 0, -1,
+			4, 5, 0, -1, 4, 7, 0, 8, 4, 5, 0, 8, 4, 6, 8, 8, 4, 6, 5, 8, 3, 6, 5, -1, 2, 7, 5, 0, 4, 6, 7, 0, 4, 3, 7, 0, 2, 6, 7, 1 };
+
+		_characters[0].inventory[2] = _vm->duplicateItem(35);
+
+		for (int i = 0; i < 4; i++) {
+			EobCharacter *c = &_characters[i];
+			c->flags = 1;
+			c->food = 100;
+			c->id = i;
+			c->inventory[3] = _vm->duplicateItem(10);
+
+			for (int ii = 0; ii < 4; ii++) {
+				int l = classDefaultItemsListIndex[(c->cClass << 2) + ii] << 1;
+				if (classDefaultItemsList[l] == -1)
+					continue;
+
+				int d = classDefaultItemsList[l];
+				int slot = classDefaultItemsList[l + 1];
+
+				if (slot < 0) {
+					slot = 0;
+					if (c->inventory[slot])
+						slot++;
+					if (c->inventory[slot])
+						slot++;
+				}
+
+				if (slot != 2 && c->inventory[slot])
+					continue;
+
+				if (d == 5 && (c->raceSex >> 1) == 3)
+					d = 36;
+
+				if (slot == 2) {
+					while (c->inventory[slot])
+						slot++;
+				}
+
+				c->inventory[slot] = _vm->duplicateItem(d);
+			}
+
+			_vm->recalcArmorClass(i);
+		}
+
+	} else {
+		static const uint8 classDefaultItemsListIndex[] = { 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 3, 2, 0, 0, 2 };
+		static const int8 itemList0[] = { 3, 36, 0, 17, -1, 0, 0, 56, 1, 17, 31, 0, 1, 23, 1, 17, 31, 1, 1 };
+		static const int8 itemList1[] = { 1, 2, 0, 17, -1, 0, 0 };
+		static const int8 itemList2[] = { 2, 56, 1, 17, 31, 0, 1, 23, 1, 17, 31, 0, 1 };
+		static const int8 itemList3[] = { 2, 1, 1, 17, 31, 1, 1, 1, 0, 17, 31, 2, 1 };
+		static const int8 *itemList[] = { itemList0, itemList1, itemList2, itemList3 };
+
+		for (int i = 0; i < 4; i++) {
+			EobCharacter *c = &_characters[i];
+			c->flags = 1;
+			c->food = 100;
+			c->id = i;
+			const int8 *df = itemList[classDefaultItemsListIndex[c->cClass]];
+			int v1 = _vm->rollDice(1, *df++, -1);
+
+			df = &df[v1 * 6];
+			for (int ii = 0; ii < 2; ii++) {
+				if (df[0] == -1)
+					break;
+				_vm->createInventoryItem(c, df[0], df[1], df[2]);
+				df = &df[3];
+			}
+
+			uint16 m = _vm->_classModifierFlags[c->cClass];
+			v1 = _vm->rollDice(1, 2, -1);
+
+			int ival = 0;
+			int itype = 0;
+
+			if (m & 0x31) {
+				if ((c->raceSex >> 1) == 3) {
+					itype = 22;
+					ival = 1;
+				} else {
+					if (v1 == 0) {
+						itype = 5;
+						ival = 1;
+					} else {
+						itype = 34;
+					}
+				}
+			} else if (m & 0x04) {
+				itype = 26;
+				if (v1 != 0)
+					ival = 1;
+			} else if (m & 0x08) {
+				ival = 1;
+				itype = ((c->raceSex >> 1) == 3) ? 22 : 5;
+			} else {
+				if (v1 == 0) {
+					itype = 3;
+				} else {
+					itype = 4;
+					ival = 1;
+				}
+			}
+
+			_vm->createInventoryItem(c, itype, ival, 0);
+			_vm->createInventoryItem(c, 10, -1, 2);
+			_vm->createInventoryItem(c, 10, -1, 2);
+			_vm->createInventoryItem(c, 24, 2, 2);
+
+			if (_vm->_classModifierFlags[c->cClass] & 2) {
+				_vm->createInventoryItem(c, 7, -1, 1);
+				_vm->createInventoryItem(c, 21, 4, 2);
+				_vm->createInventoryItem(c, 21, 13, 2);
+			}
+
+			if (_vm->_classModifierFlags[c->cClass] & 0x14) {
+				if (c->cClass == 2)
+					_vm->createInventoryItem(c, 27, -1, 1);
+				else
+					_vm->createInventoryItem(c, 8, -1, 1);
+
+				_vm->createInventoryItem(c, 20, 49, 1);
+			}
+
+			if (_vm->_classModifierFlags[c->cClass] & 8)
+				_vm->createInventoryItem(c, 6, -1, 1);
+
+			if (i == 0)
+				_vm->createInventoryItem(c, 93, -1, 2);
+
+			_vm->recalcArmorClass(i);
+		}
+	}
+
+	for (int i = 0; i < 4; i++) {
+		if (_vm->_classModifierFlags[_characters[i].cClass] & 2)
+			_characters[i].mageSpellsAvailabilityFlags = (_vm->game() == GI_EOB2) ? 0x81CB6 : 0x26C;
+
+		if (_vm->_classModifierFlags[_characters[i].cClass] & 0x14 && _vm->game() == GI_EOB2) {
+			// Cleric: Turn Undead
+			_characters[i].clericSpells[0] = 29;
+		}
+	}
+
+	for (int i = 0; i < 4; i++) {
+		EobCharacter *c = &_characters[i];
+		c->strengthMax = c->strengthCur;
+		c->strengthExtMax = c->strengthExtCur;
+		c->intelligenceMax = c->intelligenceCur;
+		c->wisdomMax = c->wisdomCur;
+		c->dexterityMax = c->dexterityCur;
+		c->constitutionMax = c->constitutionCur;
+		c->charismaMax = c->charismaCur;
+		c->hitPointsMax = c->hitPointsCur;
+	}
+
+	_vm->gui_resetButtonList();
+
+	if (_faceShapes) {
+		for (int i = 0; i < 44; i++) {
+			bool del = true;
+			for (int ii = 0; ii < 4; ii++) {
+				if (_characters[ii].faceShape == _faceShapes[i])
+					del = false;
+			}
+			if (del)
+				delete[] _faceShapes[i];
+		}
+		delete[] _faceShapes;
+		_faceShapes = 0;
+	}
+
+	if (_chargenMagicShapes) {
+		for (int i = 0; i < 10; i++)
+			delete[] _chargenMagicShapes[i];
+		delete[] _chargenMagicShapes;
+		_chargenMagicShapes = 0;
+	}
+
+	if (_chargenButtonLabels) {
+		for (int i = 0; i < 10; i++)
+			delete[] _chargenButtonLabels[i];
+		delete[] _chargenButtonLabels;
+		_chargenButtonLabels = 0;
+	}
+}
+
+const EobChargenButtonDef CharacterGenerator::_chargenButtonDefs[] = {
+	{ 0x01, 0x37, 0x31, 0x32, 0x70 },
+	{ 0x09, 0x37, 0x31, 0x32, 0x71 },
+	{ 0x01, 0x77, 0x31, 0x32, 0x72 },
+	{ 0x09, 0x77, 0x31, 0x32, 0x73 },
+	{ 0x03, 0xB5, 0x53, 0x10, 0x1A },
+	{ 0x21, 0xAC, 0x26, 0x10, 0x19 },
+	{ 0x1C, 0xAC, 0x26, 0x10, 0x21 },
+	{ 0x21, 0xAC, 0x26, 0x10, 0x32 },
+	{ 0x13, 0x50, 0x9A, 0x08, 0x00 },
+	{ 0x13, 0x58, 0x9A, 0x08, 0x00 },
+	{ 0x13, 0x60, 0x9A, 0x08, 0x00 },
+	{ 0x13, 0x68, 0x9A, 0x08, 0x00 },
+	{ 0x13, 0x70, 0x9A, 0x08, 0x00 },
+	{ 0x13, 0x78, 0x9A, 0x08, 0x00 },
+	{ 0x13, 0x80, 0x9A, 0x08, 0x00 },
+	{ 0x13, 0x88, 0x9A, 0x08, 0x00 },
+	{ 0x13, 0x90, 0x9A, 0x08, 0x00 },
+	{ 0x13, 0x98, 0x9A, 0x08, 0x00 },
+	{ 0x13, 0xA0, 0x9A, 0x08, 0x00 },
+	{ 0x13, 0xA8, 0x9A, 0x08, 0x00 },
+	{ 0x13, 0xB0, 0x9A, 0x08, 0x00 },
+	{ 0x12, 0x42, 0x20, 0x10, 0x00 },
+	{ 0x12, 0x52, 0x20, 0x10, 0x00 },
+	{ 0x16, 0x42, 0x20, 0x20, 0x00 },
+	{ 0x1A, 0x42, 0x20, 0x20, 0x00 },
+	{ 0x1E, 0x42, 0x20, 0x20, 0x00 },
+	{ 0x22, 0x42, 0x20, 0x20, 0x00 },
+	{ 0x1C, 0x9C, 0x26, 0x10, 0x14 },
+	{ 0x21, 0x9C, 0x26, 0x10, 0x34 },
+	{ 0x1C, 0xAC, 0x26, 0x10, 0x22 },
+	{ 0x21, 0xAC, 0x26, 0x10, 0x26 },
+	{ 0x12, 0x80, 0x35, 0x08, 0x00 },
+	{ 0x12, 0x88, 0x35, 0x08, 0x00 },
+	{ 0x12, 0x90, 0x35, 0x08, 0x00 },
+	{ 0x12, 0x98, 0x35, 0x08, 0x00 },
+	{ 0x12, 0xA0, 0x35, 0x08, 0x00 },
+	{ 0x12, 0xA8, 0x35, 0x08, 0x00 },
+	{ 0x1D, 0x88, 0x35, 0x08, 0x00 },
+	{ 0x1B, 0xAC, 0x15, 0x10, 0x0D },
+	{ 0x1E, 0xAC, 0x15, 0x10, 0x0C },
+	{ 0x21, 0xAC, 0x25, 0x10, 0x19 }
+};
+
+const CreatePartyModButton CharacterGenerator::_chargenModButtons[] = {
+	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40 },
+	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0A, 0x40 },
+	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x80 },
+	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0A, 0x80 },
+	{ 0x00, 0xC0, 0x04, 0x05, 0x07, 0x05, 0x08, 0x1C, 0x9C },
+	{ 0x04, 0xC0, 0x03, 0x05, 0x0A, 0x05, 0x08, 0x21, 0xAC },
+	{ 0x07, 0xC0, 0x03, 0x05, 0x0B, 0x05, 0x08, 0x21, 0xAC },
+	{ 0x0A, 0xC0, 0x04, 0x05, 0x06, 0x05, 0x08, 0x21, 0x9C },
+	{ 0x18, 0xC0, 0x03, 0x05, 0x09, 0x05, 0x08, 0x1C, 0xAC },
+	{ 0x0E, 0xC0, 0x02, 0x05, 0x0F, 0x05, 0x08, 0x21, 0xAC },
+	{ 0x10, 0xC0, 0x01, 0x05, 0x09, 0x05, 0x04, 0x1B, 0xAC },
+	{ 0x11, 0xC0, 0x01, 0x01, 0x09, 0x07, 0x04, 0x1E, 0xAC },
+	{ 0x12, 0xC0, 0x03, 0x07, 0x07, 0x04, 0x06, 0x12, 0x42 },
+	{ 0x15, 0xC0, 0x03, 0x07, 0x07, 0x04, 0x06, 0x12, 0x52 },
+	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x03, 0xB5 },
+	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x03, 0xB5 },
+	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x1C, 0xAC }
+};
+
+const EobRect8 CharacterGenerator::_chargenButtonBodyCoords[] = {
+	{ 0x00, 0x80, 0x04, 0x20 },
+	{ 0x04, 0x80, 0x04, 0x20 },
+	{ 0x08, 0x80, 0x04, 0x20 },
+	{ 0x0C, 0x80, 0x04, 0x20 },
+	{ 0x0E, 0xA0, 0x03, 0x10 },
+	{ 0x0B, 0xA0, 0x03, 0x10 },
+	{ 0x10, 0x80, 0x04, 0x10 },
+	{ 0x10, 0x90, 0x04, 0x10 },
+	{ 0x11, 0xA0, 0x05, 0x10 },
+	{ 0x11, 0xB0, 0x05, 0x10 },
+	{ 0x16, 0xA0, 0x05, 0x10 },
+	{ 0x16, 0xB0, 0x05, 0x10 },
+	{ 0x00, 0xA0, 0x0B, 0x10 },
+	{ 0x14, 0x80, 0x0B, 0x10 },
+	{ 0x14, 0x90, 0x0B, 0x10 }
+};
+
+const EobRect16 CharacterGenerator::_chargenPortraitBoxFrames[] = {
+	{ 0x00B7, 0x0001, 0x00F7, 0x0034 },
+	{ 0x00FF, 0x0001, 0x013F, 0x0034 },
+	{ 0x00B7, 0x0035, 0x00F7, 0x0068 },
+	{ 0x00FF, 0x0035, 0x013F, 0x0068 },
+	{ 0x00B7, 0x0069, 0x00F7, 0x009C },
+	{ 0x00FF, 0x0069, 0x013F, 0x009C },
+	{ 0x0010, 0x003F, 0x0030, 0x0060 },
+	{ 0x0050, 0x003F, 0x0070, 0x0060 },
+	{ 0x0010, 0x007F, 0x0030, 0x00A0 },
+	{ 0x0050, 0x007F, 0x0070, 0x00A0 },
+	{ 0x00B0, 0x0042, 0x00D0, 0x0061 },
+	{ 0x00D0, 0x0042, 0x00F0, 0x0061 },
+	{ 0x00F0, 0x0042, 0x0110, 0x0061 },
+	{ 0x0110, 0x0042, 0x0130, 0x0061 },
+	{ 0x0004, 0x0018, 0x0024, 0x0039 },
+	{ 0x00A3, 0x0018, 0x00C3, 0x0039 },
+	{ 0x0004, 0x0040, 0x0024, 0x0061 },
+	{ 0x00A3, 0x0040, 0x00C3, 0x0061 },
+	{ 0x0004, 0x0068, 0x0024, 0x0089 },
+	{ 0x00A3, 0x0068, 0x00C3, 0x0089 }
+};
+
+const int16 CharacterGenerator::_chargenBoxX[] = { 0x10, 0x50, 0x10, 0x50 };
+const int16 CharacterGenerator::_chargenBoxY[] = { 0x3F, 0x3F, 0x7F, 0x7F };
+const int16 CharacterGenerator::_chargenNameFieldX[] = { 0x02, 0x42, 0x02, 0x42 };
+const int16 CharacterGenerator::_chargenNameFieldY[] = { 0x6B, 0x6B, 0xAB, 0xAB };
+
+const int32 CharacterGenerator::_classMenuMasks[] = {
+	0x003F, 0x07BB, 0x77FB, 0x00F1, 0x08F1, 0x00B1
+};
+
+const int32 CharacterGenerator::_alignmentMenuMasks[] = {
+	0x01FF, 0x0007, 0x0001, 0x01FF,	0x01FF, 0x01FE, 0x01FF, 0x01FE,
+	0x01FF, 0x01FE, 0x01FE, 0x01FE, 0x01FF,	0x0007,	0x01FF
+};
+
+const int16 CharacterGenerator::_raceModifiers[] = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0,	1, -1, 0, 1, -1, 0, 0, 0, -1, 0, 0, 1, 0, 0
+};
+
+}	// End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp
index 68eb082..44fbc0f 100644
--- a/engines/kyra/detection.cpp
+++ b/engines/kyra/detection.cpp
@@ -17,12 +17,15 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
  */
 
 #include "kyra/kyra_lok.h"
 #include "kyra/lol.h"
 #include "kyra/kyra_hof.h"
 #include "kyra/kyra_mr.h"
+#include "kyra/eob1.h"
+#include "kyra/eob2.h"
 
 #include "common/config-manager.h"
 #include "common/system.h"
@@ -129,6 +132,14 @@ bool KyraMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGame
 		*engine = new Kyra::LoLEngine(syst, flags);
 		break;
 #endif // ENABLE_LOL
+#ifdef ENABLE_EOB
+	case Kyra::GI_EOB1:
+		*engine = new Kyra::EobEngine(syst, flags);
+		break;
+	case Kyra::GI_EOB2:
+		*engine = new Kyra::DarkMoonEngine(syst, flags);
+		break;
+#endif // ENABLE_EOB
 	default:
 		res = false;
 		warning("Kyra engine: unknown gameID");
diff --git a/engines/kyra/detection_tables.h b/engines/kyra/detection_tables.h
index ebf7c8e..50a154d 100644
--- a/engines/kyra/detection_tables.h
+++ b/engines/kyra/detection_tables.h
@@ -57,6 +57,9 @@ namespace {
 #define LOL_DEMO_FLAGS FLAGS(true, true, false, false, false, false, false, false, Kyra::GI_LOL)
 #define LOL_KYRA2_DEMO_FLAGS FLAGS(true, false, false, false, false, false, false, false, Kyra::GI_KYRA2)
 
+#define EOB_FLAGS FLAGS(false, false, false, false, false, false, false, false, Kyra::GI_EOB1)
+#define EOB2_FLAGS FLAGS(false, false, false, false, false, false, false, false, Kyra::GI_EOB2)
+
 const KYRAGameDescription adGameDescs[] = {
 	/* disable these targets until they get supported
 	{
@@ -1439,6 +1442,73 @@ const KYRAGameDescription adGameDescs[] = {
 		LOL_KYRA2_DEMO_FLAGS
 	},
 #endif // ENABLE_LOL
+#ifdef ENABLE_EOB
+
+	{
+		{
+			"eob",
+			0,
+			{
+				{ "EOBDATA2.PAK", 0, "feaf0345086b3a1d931352f4b0ad8feb", -1 },
+				{ 0, 0, 0, 0 }
+			},
+			Common::EN_ANY,
+			Common::kPlatformPC,
+			ADGF_NO_FLAGS,
+			GUIO3(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIPCSPK)
+		},
+		EOB_FLAGS
+	},
+
+	{
+		{
+			"eob",
+			0,
+			{
+				{ "SHINDIA.CPS", 0, "383b0c7ba0903eae5d04cad28ce90aaf", -1 },
+				{ 0, 0, 0, 0 }
+			},
+			Common::DE_DEU,
+			Common::kPlatformPC,
+			ADGF_NO_FLAGS,
+			GUIO3(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIPCSPK)
+		},
+		EOB_FLAGS
+	},
+
+	{
+		{
+			"eob2",
+			0,
+			{
+				{ "LEVEL15.INF", 0, "10f19eab75c73d0476dc58bcf70fff7a", -1 },
+				{ 0, 0, 0, 0 }
+			},
+			Common::EN_ANY,
+			Common::kPlatformPC,
+			ADGF_NO_FLAGS,
+			GUIO3(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIPCSPK)
+		},
+		EOB2_FLAGS
+	},
+
+	{
+		{
+			"eob2",
+			0,
+			{
+				{ "LEVEL15.INF", 0, "ce54243ad1ca4447f521340428da2c91", -1 },
+				{ 0, 0, 0, 0 }
+			},
+			Common::DE_DEU,
+			Common::kPlatformPC,
+			ADGF_NO_FLAGS,
+			GUIO3(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIPCSPK)
+		},
+		EOB2_FLAGS
+	},
+#endif // ENABLE_EOB
+
 	{ AD_TABLE_END_MARKER, FLAGS(0, 0, 0, 0, 0, 0, 0, 0, 0) }
 };
 
@@ -1449,6 +1519,10 @@ const PlainGameDescriptor gameList[] = {
 #ifdef ENABLE_LOL
 	{ "lol", "Lands of Lore: The Throne of Chaos" },
 #endif // ENABLE_LOL
+#ifdef ENABLE_EOB
+	{ "eob", "Eye of the Beholder" },
+	{ "eob2", "Eye of the Beholder II: The Legend of Darkmoon" },
+#endif // ENABLE_EOB
 	{ 0, 0 }
 };
 
diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
new file mode 100644
index 0000000..993d06a
--- /dev/null
+++ b/engines/kyra/eob1.cpp
@@ -0,0 +1,242 @@
+/* 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.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/eob1.h"
+#include "kyra/resource.h"
+
+namespace Kyra {
+
+EobEngine::EobEngine(OSystem *system, const GameFlags &flags) : EobCoreEngine(system, flags) {
+	_numSpells = 53;
+}
+
+EobEngine::~EobEngine() {
+	delete[] _itemsOverlay;
+}
+
+Common::Error EobEngine::init() {
+	Common::Error err = EobCoreEngine::init();
+	if (err.getCode() != Common::kNoError)
+		return err;
+
+	initStaticResource();
+
+	_itemsOverlay = _res->fileData("ITEMRMP.VGA", 0);
+
+	_bkgColor_1 = 132;
+	_color1_1 = 135;
+	_color2_1 = 130;
+	_color4 = 133;
+	_color5 = 133;
+	_color6 = 180;
+	_color7 = 177;
+	_color8 = 184;
+
+	_color14 = _color8;
+	_color13 = _color7;
+	_color12 = _color6;
+
+	_screen->modifyScreenDim(7, 0x01, 0xB3, 0x22, 0x12);
+	_screen->modifyScreenDim(9, 0x01, 0x7D, 0x26, 0x3F);
+	_screen->modifyScreenDim(12, 0x01, 0x04, 0x14, 0xA0);
+
+	_scriptTimersCount = 1;
+
+	return Common::kNoError;
+}
+
+void EobEngine::startupNew() {
+	_currentLevel = 1;
+	_currentSub = 0;
+	loadLevel(1, 0);
+	_currentBlock = 490;
+	_currentDirection = 0;
+	setHandItem(0);
+}
+
+void EobEngine::startupLoad() {
+	updateHandItemCursor();
+	loadLevel(_currentLevel, _currentSub);
+	_saveLoadMode = 0;
+}
+
+void EobEngine::npcSequence(int npcIndex) {
+
+
+}
+
+void EobEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
+	EobItem *itm = &_items[_characters[charIndex].inventory[slot]];
+	if (itm->type == 48) {
+		int charges = itm->flags & 0x3f;
+		if (--charges)
+			--itm->flags;
+		else
+			deleteInventoryItem(charIndex, slot);
+	} else if (itm->type == 34 || itm->type == 35) {
+		deleteInventoryItem(charIndex, slot);
+	}
+}
+
+void EobEngine::replaceMonster(int unit, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem) {
+	if (_levelBlockProperties[block].flags & 7)
+		return;
+
+	for (int i = 0; i < 30; i++) {
+		if (_monsters[i].hitPointsCur <= 0) {
+			initMonster(i, unit, block, pos, dir, type, shpIndex, mode, h2, randItem, fixedItem);;
+			break;
+		}
+	}
+}
+
+void EobEngine::loadDoorShapes(int doorType1, int shapeId1, int doorType2, int shapeId2) {
+	_screen->loadEobBitmap("DOOR", 5, 3);
+	_screen->_curPage = 2;
+
+	if (doorType1 != 0xff) {
+		for (int i = 0; i < 3; i++) {
+			const uint8 *enc = &_doorShapeEncodeDefs[(doorType1 * 3 + i) << 2];
+			_doorShapes[shapeId1 + i] = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
+			enc = &_doorSwitchShapeEncodeDefs[(doorType1 * 3 + i) << 2];
+			_doorSwitches[shapeId1 + i].shp = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
+			_doorSwitches[shapeId1 + i].x = _doorSwitchCoords[doorType1 << 1];
+			_doorSwitches[shapeId1 + i].y = _doorSwitchCoords[(doorType1 << 1) + 1];
+		}
+	}
+
+	if (doorType2 != 0xff) {
+		for (int i = 0; i < 3; i++) {
+			const uint8 *enc = &_doorShapeEncodeDefs[(doorType2 * 3 + i) << 2];
+			_doorShapes[shapeId2 + i] = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
+			enc = &_doorSwitchShapeEncodeDefs[(doorType2 * 3 + i) << 2];
+			_doorSwitches[shapeId2 + i].shp = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
+			_doorSwitches[shapeId2 + i].x = _doorSwitchCoords[doorType2 << 1];
+			_doorSwitches[shapeId2 + i].y = _doorSwitchCoords[(doorType2 << 1) + 1];
+		}
+	}
+
+	_screen->_curPage = 0;
+}
+
+void EobEngine::drawDoorIntern(int type, int index, int x, int y, int w, int wall, int mDim, int16 y1, int16 y2) {
+	int shapeIndex = type + 2 - mDim;
+	uint8 *shp = _doorShapes[shapeIndex];
+
+	int d1 = 0;
+	int d2 = 0;
+	int v = 0;
+	const ScreenDim *td = _screen->getScreenDim(5);
+
+	switch (_currentLevel) {
+		case 4:
+		case 5:
+		case 6:
+			y = _dscDoorY2[mDim] - shp[1];
+			d1 = _dscDoorCoordsExt[index << 1] >> 3;
+			d2 = _dscDoorCoordsExt[(index << 1) + 1] >> 3;
+			if (_shpDmX1 > d1)
+				d1 = _shpDmX1;
+			if (_shpDmX2 < d2)
+				d2 = _shpDmX2;
+			_screen->modifyScreenDim(5, d1, td->sy, d2 - d1, td->h);
+			v = ((wall < 30) ? (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult3[mDim] : _dscDoorScaleMult4[mDim]) * -1;
+			v -= (shp[2] << 3);
+			drawBlockObject(0, 2, shp, x + v, y, 5);
+			v += (shp[2] << 3);
+			drawBlockObject(1, 2, shp, x - v, y, 5);
+			if (_wllShapeMap[wall] == -1)
+				drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w - v, _doorSwitches[shapeIndex].y, 5);
+			break;
+
+		case 7:
+		case 8:
+		case 9:
+			y = _dscDoorY3[mDim] - _doorShapes[shapeIndex + 3][1];
+			d1 = x - (_doorShapes[shapeIndex + 3][2] << 2);
+			x -= (shp[2] << 2);
+			drawBlockObject(0, 2, _doorShapes[shapeIndex + 3], d1, y, 5);
+			scaleLevelShapesDim(index, y1, y2, 5);
+			y = _dscDoorY3[mDim] - ((wall < 30) ? (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult1[mDim] : _dscDoorScaleMult2[mDim]);
+			drawBlockObject(0, 2, shp, x, y, 5);
+			if (_wllShapeMap[wall] == -1)
+				drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
+			break;
+
+		case 10:
+		case 11:
+			v = ((wall < 30) ? (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult5[mDim] : _dscDoorScaleMult6[mDim]) * -1;
+			x -= (shp[2] << 2);
+			y = _dscDoorY3[mDim] + v;
+			drawBlockObject(0, 2, shp, x, y + v, 5);
+			v >>= 4;
+			y = _dscDoorY5[mDim];
+			drawBlockObject(0, 2, _doorShapes[shapeIndex + 3], x, y - v, 5);
+			if (_wllShapeMap[wall] == -1)
+				drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
+			break;
+
+		default:
+			y = (_currentLevel == 12 ? _dscDoorY6[mDim] : _dscDoorY1[mDim]) - shp[1];
+			x -= (shp[2] << 2);
+			y -= (wall >= 30 ? _dscDoorScaleMult2[mDim] : (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult1[mDim]);
+			drawBlockObject(0, 2, shp, x, y, 5);
+
+			if (_wllShapeMap[wall] == -1)
+				drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
+			break;
+	}
+}
+
+uint32 EobEngine::convertSpellFlagToEob2Format(uint32 flag, int ignoreInvisibility) {
+	uint32 res = 0;
+	if (flag & 0x01)
+		res |= 0x20;
+	if (flag & 0x02)
+		res |= 0x400;
+	if (flag & 0x04)
+		res |= 0x80;
+	if (flag & 0x08)
+		res |= 0x40;
+	if (ignoreInvisibility)
+		res |= 0x100;
+	return res;
+}
+
+uint32 EobEngine::convertCharacterEffectFlagToEob2Format(uint32 flag) {
+	uint32 res = 0;
+	if (flag & 0x02)
+		res |= 0x08;
+	if (flag & 0x04)
+		res |= 0x40;
+	if (flag & 0x80)
+		res |= 0x2000;
+	if (flag & 0x100)
+		res |= 0x4000;
+	return res;
+}
+
+}	// End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/eob1.h b/engines/kyra/eob1.h
new file mode 100644
index 0000000..27a060f
--- /dev/null
+++ b/engines/kyra/eob1.h
@@ -0,0 +1,96 @@
+/* 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.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#ifndef KYRA_EOB1_H
+#define KYRA_EOB1_H
+
+#include "kyra/eobcommon.h"
+
+namespace Kyra {
+
+class EobEngine : public EobCoreEngine {
+friend class GUI_Eob;
+public:
+	EobEngine(OSystem *system, const GameFlags &flags);
+	~EobEngine();
+
+private:
+	// Init / Release
+	Common::Error init();
+	void initStaticResource();
+	void initSpells();
+
+	// Main Menu
+	int mainMenu();
+	int mainMenuLoop();
+
+	// Main loop
+	void startupNew();
+	void startupLoad();
+
+	// Intro/Outro
+	void seq_playOpeningCredits();
+	void seq_playIntro();
+	void seq_playFinale();
+
+	// characters
+	void npcSequence(int npcIndex);
+
+	//const char *const *_npc1Strings;
+	//const char *const *_npc2Strings;
+
+	// items
+	void updateUsedCharacterHandItem(int charIndex, int slot);
+
+	// Monsters
+	void replaceMonster(int unit, uint16 block, int d, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem);
+
+	// Level
+	void loadDoorShapes(int doorType1, int shapeId1, int doorType2, int shapeId2);
+	void drawDoorIntern(int type, int index, int x, int y, int w, int wall, int mDim, int16 y1, int16 y2);
+
+	const int16 *_dscDoorCoordsExt;
+	const uint8 *_dscDoorScaleMult4;
+	const uint8 *_dscDoorScaleMult5;
+	const uint8 *_dscDoorScaleMult6;
+	const uint8 *_dscDoorY3;
+	const uint8 *_dscDoorY4;
+	const uint8 *_dscDoorY5;
+	const uint8 *_dscDoorY6;
+
+	const uint8 *_doorShapeEncodeDefs;
+	const uint8 *_doorSwitchShapeEncodeDefs;
+	const uint8 *_doorSwitchCoords;
+
+	// Misc
+	uint32 convertSpellFlagToEob2Format(uint32 flag, int ignoreInvisibility);
+	uint32 convertCharacterEffectFlagToEob2Format(uint32 flag);
+};
+
+
+}	// End of namespace Kyra
+
+#endif
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
new file mode 100644
index 0000000..120ad15
--- /dev/null
+++ b/engines/kyra/eob2.cpp
@@ -0,0 +1,437 @@
+/* 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.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/eob2.h"
+#include "kyra/resource.h"
+#include "kyra/sound.h"
+
+namespace Kyra {
+
+DarkMoonEngine::DarkMoonEngine(OSystem *system, const GameFlags &flags) : EobCoreEngine(system, flags) {
+	_seqIntro = _seqFinale = 0;
+	_shapesIntro = _shapesFinale = 0;
+	_dscDoorType5Offs = 0;
+	_numSpells = 70;
+}
+
+DarkMoonEngine::~DarkMoonEngine() {
+	delete[] _seqIntro;
+	delete[] _seqFinale;
+	delete[] _shapesIntro;
+	delete[] _shapesFinale;
+}
+
+Common::Error DarkMoonEngine::init() {
+	Common::Error err = EobCoreEngine::init();
+	if (err.getCode() != Common::kNoError)
+		return err;
+
+	initStaticResource();
+
+	_monsterProps = new EobMonsterProperty[10];
+
+	_bkgColor_1 = 183;
+	_color1_1 = 186;
+	_color2_1 = 181;
+	_color4 = 133;
+	_color5 = 184;
+	_color6 = 183;
+	_color7 = 181;
+	_color8 = 186;
+	_color12 = 180;
+	_color13 = 177;
+	_color14 = 182;
+
+	return Common::kNoError;
+}
+
+void DarkMoonEngine::startupNew() {
+	_currentLevel = 4;
+	_currentSub = 0;
+	loadLevel(4, 0);
+	_currentBlock = 171;
+	_currentDirection = 2;
+	setHandItem(0);
+}
+
+void DarkMoonEngine::startupLoad() {
+	updateHandItemCursor();
+	loadLevel(_currentLevel, _currentSub);
+	_saveLoadMode = 0;
+}
+
+void DarkMoonEngine::npcSequence(int npcIndex) {
+	_screen->loadEobBitmap("OUTTAKE", 5, 3);
+	_screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 6, Screen::CR_NO_P_CHECK);
+	const uint8 *shpDef = &_npcShpData[npcIndex << 3];
+
+	for (int i = npcIndex; i != 255; i = shpDef[7]) {
+		shpDef = &_npcShpData[i << 3];
+		_screen->_curPage = 2;
+		const uint8 *shp = _screen->encodeShape(READ_LE_UINT16(shpDef), shpDef[2], shpDef[3], shpDef[4]);
+		_screen->_curPage = 0;
+		_screen->drawShape(0, shp, 88 + shpDef[5] - (shp[2] << 2), 104 + shpDef[6] - shp[1], 5);
+		delete[] shp;
+	}
+
+	Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
+	_screen->loadFileDataToPage(s, 5, 32000);
+	delete s;
+
+	gui_drawBox(0, 121, 320, 79, _color1_1, _color2_1, _bkgColor_1);
+	_txt->setupField(9, true);
+	_txt->resetPageBreakString();
+
+	if (npcIndex == 0) {
+		snd_playSoundEffect(57);
+		if (npcJoinDialogue(0, 1, 3, 2))
+			setScriptFlag(0x40);
+	} else if (npcIndex == 1) {
+		snd_playSoundEffect(53);
+		gui_drawDialogueBox();
+
+		_txt->printDialogueText(4, 0);
+		int r = runDialogue(-1, 0, _npc1Strings[0], _npc1Strings[1]) - 1;
+
+		if (r == 0) {
+			_sound->playTrack(0);
+			delay(3 * _tickLength);
+			snd_playSoundEffect(91);
+			npcJoinDialogue(1, 5, 6, 7);
+		} else if (r == 1) {
+			setScriptFlag(0x20);
+		}
+
+	} else if (npcIndex == 2) {
+		snd_playSoundEffect(55);
+		gui_drawDialogueBox();
+
+		_txt->printDialogueText(8, 0);
+		int r = runDialogue(-1, 0, _npc2Strings[0], _npc2Strings[1]) - 1;
+
+		if (r == 0) {
+			if (rollDice(1, 2, -1))
+				_txt->printDialogueText(9, _okStrings[0]);
+			else
+				npcJoinDialogue(2, 102, 103, 104);
+			setScriptFlag(8);
+		} else if (r == 1) {
+			_currentDirection = 0;
+		}
+	}
+
+	_txt->removePageBreakFlag();
+	gui_restorePlayField();
+}
+
+void DarkMoonEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
+	EobItem *itm = &_items[_characters[charIndex].inventory[slot]];
+	if (itm->type == 48 || itm->type == 62) {
+		if (itm->value == 5)
+			return;
+		int charges = itm->flags & 0x3f;
+		if (--charges)
+			--itm->flags;
+		else
+			deleteInventoryItem(charIndex, slot);
+	} else if (itm->type == 26 || itm->type == 34 || itm->type == 35) {
+		deleteInventoryItem(charIndex, slot);
+	}
+}
+
+void DarkMoonEngine::generateMonsterPalettes(const char *file, int16 monsterIndex) {
+	int cp = _screen->setCurPage(2);
+	_screen->loadEobBitmap(file, 3, 3);
+	uint8 tmpPal[16];
+	uint8 newPal[16];
+
+	for (int i = 0; i < 6; i++) {
+		int dci = monsterIndex + i;
+		memcpy(tmpPal, _monsterShapes[dci] + 4, 16);
+		int colx = 302 + 3 * i;
+
+		for (int ii = 0; ii < 16; ii++) {
+			uint8 col = _screen->getPagePixel(_screen->_curPage, colx, 184 + ii);
+
+			int iii = 0;
+			for (; iii < 16; iii++) {
+				if (tmpPal[iii] == col) {
+					newPal[ii] = iii;
+					break;
+				}
+			}
+
+			if (iii == 16)
+				newPal[ii] = 0;
+		}
+
+		for (int ii = 1; ii < 3; ii++) {
+			memcpy(tmpPal, _monsterShapes[dci] + 4, 16);
+
+			for (int iii = 0; iii < 16; iii++) {
+				uint8 col = _screen->getPagePixel(_screen->_curPage, colx + ii, 184 + iii);
+				if (newPal[iii])
+					tmpPal[newPal[iii]] = col;
+			}
+
+			int c = i;
+			if (monsterIndex >= 18)
+				c += 6;
+
+			c = (c << 1) + (ii - 1);
+			memcpy(_monsterPalettes[c], tmpPal, 16);
+		}
+	}
+
+	_screen->setCurPage(cp);
+}
+
+void DarkMoonEngine::loadMonsterDecoration(const char *file, int16 monsterIndex) {
+	char filename[13];
+	snprintf(filename, 13, "%s.dcr", file);
+
+	Common::SeekableReadStream *s = _res->createReadStream(filename);
+	if (!s)
+		return;
+
+	int len = s->readUint16LE();
+
+	for (int i = 0; i < len; i++) {
+		for (int ii = 0; ii < 6; ii++) {
+			uint8 dc[6];
+			s->read(dc, 6);
+			if (!dc[2] || !dc[3])
+				continue;
+
+			SpriteDecoration *m = &_monsterDecorations[i * 6 + ii + monsterIndex];
+
+			m->shp = _screen->encodeShape(dc[0], dc[1], dc[2], dc[3]);
+			m->x = dc[4];
+			m->y = dc[5];
+		}
+	}
+
+	delete s;
+}
+
+void DarkMoonEngine::replaceMonster(int unit, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem) {
+	uint8 flg = _levelBlockProperties[block].flags & 7;
+
+	if (flg == 7 || _currentBlock == block || (flg && (_monsterProps[type].u30 || pos == 4)))
+		return;
+
+	for (int i = 0; i < 30; i++) {
+		if (_monsters[i].block != block)
+			continue;
+		if (_monsters[i].pos == 4 || _monsterProps[_monsters[i].type].u30)
+			return;
+	}
+
+	int index = -1;
+	int maxDist = 0;
+
+	for (int i = 0; i < 30; i++) {
+		if (_monsters[i].hitPointsCur <= 0) {
+			index = i;
+			break;
+		}
+
+		if (_monsters[i].flags & 0x40)
+			continue;
+
+		int dist = getBlockDistance(_monsters[i].block, _currentBlock);
+
+		if (dist > maxDist) {
+			maxDist = dist;
+			index = i;
+		}
+	}
+
+	if (index == -1)
+		return;
+
+	if (_monsters[index].hitPointsCur > 0)
+		killMonster(&_monsters[index], false);
+
+	initMonster(index, unit, block, pos, dir, type, shpIndex, mode, h2, randItem, fixedItem);
+}
+
+const uint8 *DarkMoonEngine::loadDoorShapes(const char *filename, int doorIndex, const uint8 *shapeDefs) {
+	_screen->loadEobBitmap(filename, 3, 3);
+	for (int i = 0; i < 3; i++) {
+		_doorShapes[doorIndex * 3 + i] = _screen->encodeShape(READ_LE_UINT16(shapeDefs), READ_LE_UINT16(shapeDefs + 2), READ_LE_UINT16(shapeDefs + 4), READ_LE_UINT16(shapeDefs + 6));
+		shapeDefs += 8;
+	}
+
+	for (int i = 0; i < 2; i++) {
+		_doorSwitches[doorIndex * 3 + i].shp = _screen->encodeShape(READ_LE_UINT16(shapeDefs), READ_LE_UINT16(shapeDefs + 2), READ_LE_UINT16(shapeDefs + 4), READ_LE_UINT16(shapeDefs + 6));
+		shapeDefs += 8;
+		_doorSwitches[doorIndex * 3 + i].x = *shapeDefs;
+		shapeDefs += 2;
+		_doorSwitches[doorIndex * 3 + i]. y= *shapeDefs;
+		shapeDefs += 2;
+	}
+	_screen->_curPage = 0;
+	return shapeDefs;
+}
+
+void DarkMoonEngine::drawDoorIntern(int type, int, int x, int y, int w, int wall, int mDim, int16, int16) {
+	int shapeIndex = type * 3 + 2 - mDim;
+	uint8 *shp = _doorShapes[shapeIndex];
+
+	if ((_doorType[type] == 0) || (_doorType[type] == 1)) {
+		y = _dscDoorY1[mDim] - shp[1];
+		x -= (shp[2] << 2);
+
+		if (_doorType[type] == 1) {
+			drawBlockObject(0, 2, shp, x, y, 5);
+			shp = _doorShapes[3 + shapeIndex];
+		}
+
+		y -= ((wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult1[mDim]);
+
+		if (_specialWallTypes[wall] == 5)
+			y -= _dscDoorType5Offs[shapeIndex];
+
+	} else if (_doorType[type] == 2) {
+		x -= (shp[2] << 2);
+		y = _dscDoorY2[mDim] - ((wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult3[mDim]);
+	}
+
+	drawBlockObject(0, 2, shp, x, y, 5);
+
+	if (_wllShapeMap[wall] == -1 && !_noDoorSwitch[type])
+		drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
+}
+
+void DarkMoonEngine::drawLightningColumn() {
+	int f = rollDice(1, 2, -1);
+	int y = 0;
+
+	for (int i = 0; i < 6; i++) {
+		f ^= 1;
+		drawBlockObject(f, 2, _lightningColumnShape, 72, y, 5);
+		y += 64;
+	}
+}
+
+int DarkMoonEngine::resurrectionSelectDialogue() {
+	int cnt = 0;
+	const char *namesList[10];
+	memset(namesList, 0, 10 * sizeof(const char*));
+	int8 indexList[10];
+
+	for (int i = 0; i < 6; i++) {
+		if (!testCharacter(i, 1))
+			continue;
+		if (_characters[i].hitPointsCur != -10)
+			continue;
+
+		namesList[cnt] = _characters[i].name;
+		indexList[cnt++] = i;
+	}
+
+	for (int i = 0; i < 6; i++) {
+		if (!testCharacter(i, 1))
+			continue;
+
+		for (int ii = 0; ii < 27; ii++) {
+			uint16 inv = _characters[i].inventory[ii];
+			if (!inv)
+				continue;
+
+			if (_items[inv].type != 33)
+				continue;
+
+			namesList[cnt] = _npcPreset[_items[inv].value - 1].name;
+			indexList[cnt++] = -_items[inv].value;
+		}
+	}
+
+	if (_itemInHand) {
+		if (_items[_itemInHand].type == 33) {
+			namesList[cnt] = _npcPreset[_items[_itemInHand].value - 1].name;
+			indexList[cnt++] = -_items[_itemInHand].value;
+		}
+	}
+
+	namesList[cnt] = _abortStrings[0];
+	indexList[cnt++] = 99;
+
+	int r = indexList[runDialogue(-1, 1, namesList[0], namesList[1], namesList[2], namesList[3], namesList[4], namesList[5], namesList[6], namesList[7], namesList[8]) - 1];
+	if (r == 99)
+		return 0;
+
+	if (r < 0) {
+		r = -r;
+		if (prepareForNewPartyMember(33, r))
+			initNpc(r - 1);
+	} else {
+		_characters[r].hitPointsCur = 1;
+	}
+
+	return 1;
+}
+
+int DarkMoonEngine::charSelectDialogue() {
+	int cnt = 0;
+	const char *namesList[7];
+	memset(namesList, 0, 7 * sizeof(const char*));
+
+	for (int i = 0; i < 6; i++) {
+		if (!testCharacter(i, 3))
+			continue;
+		namesList[cnt++] = _characters[i].name;
+	}
+
+	namesList[cnt++] = _abortStrings[0];
+
+	int r = runDialogue(-1, 1, namesList[0], namesList[1], namesList[2], namesList[3], namesList[4], namesList[5], namesList[6], 0) - 1;
+	if (r == cnt - 1)
+		return 99;
+
+	for (cnt = 0; cnt < 6; cnt++) {
+		if (!testCharacter(cnt, 3))
+			continue;
+		if (--r < 0)
+			break;
+	}
+	return cnt;
+}
+
+void DarkMoonEngine::characterLevelGain(int charIndex) {
+	EobCharacter *c = &_characters[charIndex];
+	int s = _numLevelsPerClass[c->cClass];
+	for (int i = 0; i < s; i++) {
+		uint32 er = getRequiredExperience(c->cClass, i, c->level[i] + 1);
+		if (er == 0xffffffff)
+			continue;
+
+		increaseCharacterExperience(charIndex, er - c->experience[i]);
+	}
+}
+
+}	// End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/eob2.h b/engines/kyra/eob2.h
new file mode 100644
index 0000000..a36ec0e
--- /dev/null
+++ b/engines/kyra/eob2.h
@@ -0,0 +1,119 @@
+/* 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.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#ifndef KYRA_EOB2_H
+#define KYRA_EOB2_H
+
+#include "kyra/eobcommon.h"
+
+namespace Kyra {
+
+class DarkmoonSequenceHelper;
+
+struct EobSequenceStep {
+	uint8 command;
+	uint8 obj;
+	int16 x1;
+	uint8 y1;
+	uint8 delay;
+	uint8 pal;
+	uint8 x2;
+	uint8 y2;
+	uint8 w;
+	uint8 h;
+};
+
+class DarkMoonEngine : public EobCoreEngine {
+friend class GUI_Eob;
+friend class DarkmoonSequenceHelper;
+public:
+	DarkMoonEngine(OSystem *system, const GameFlags &flags);
+	~DarkMoonEngine();
+
+private:
+	// Init / Release
+	Common::Error init();
+	void initStaticResource();
+	void initSpells();
+
+	// Main Menu
+	int mainMenu();
+	int mainMenuLoop();
+
+	// Main loop
+	void startupNew();
+	void startupLoad();
+
+	// Intro/Outro
+	void seq_playIntro();
+	void seq_playFinale();
+	void seq_playCredits(DarkmoonSequenceHelper *sq, const uint8 *data, int sd, int backupPage, int tempPage, int speed);
+
+	const char * const*_introStrings;
+	const char * const *_cpsFilesIntro;
+	const EobSequenceStep **_seqIntro;
+	const EobShapeDef **_shapesIntro;
+
+	const char * const*_finaleStrings;
+	const uint8 *_creditsData;
+	const char * const *_cpsFilesFinale;
+	const EobSequenceStep **_seqFinale;
+	const EobShapeDef **_shapesFinale;
+
+	static const char *_palFilesIntro[];
+	static const char *_palFilesFinale[];
+
+	// characters
+	void npcSequence(int npcIndex);
+
+	const uint8 *_npcShpData;
+	const char *const *_npc1Strings;
+	const char *const *_npc2Strings;
+
+	// items
+	void updateUsedCharacterHandItem(int charIndex, int slot);
+
+	// Monsters
+	void generateMonsterPalettes(const char *file, int16 monsterIndex);
+	void loadMonsterDecoration(const char *file, int16 monsterIndex);
+	void replaceMonster(int unit, uint16 block, int d, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem);
+
+	// Level
+	const uint8 *loadDoorShapes(const char *filename, int doorIndex, const uint8 *shapeDefs);
+	void drawDoorIntern(int type, int, int x, int y, int w, int wall, int mDim, int16, int16);
+
+	const uint8 *_dscDoorType5Offs;
+
+	// misc
+	void drawLightningColumn();
+	int resurrectionSelectDialogue();
+	int charSelectDialogue();
+	void characterLevelGain(int charIndex);
+};
+
+}	// End of namespace Kyra
+
+#endif
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
new file mode 100644
index 0000000..d82a3dd
--- /dev/null
+++ b/engines/kyra/eobcommon.cpp
@@ -0,0 +1,1845 @@
+/* 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.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "common/config-manager.h"
+
+#include "audio/mididrv.h"
+#include "audio/mixer.h"
+
+#include "kyra/loleobbase.h"
+#include "kyra/resource.h"
+#include "kyra/sound_intern.h"
+#include "kyra/script_eob.h"
+#include "kyra/timer.h"
+
+namespace Kyra {
+
+EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBaseEngine(system, flags), _numLargeItemShapes(flags.gameID == GI_EOB1 ? 14 : 11),
+	_numSmallItemShapes(flags.gameID == GI_EOB1 ? 23 : 26), _numThrownItemShapes(flags.gameID == GI_EOB1 ? 12 : 9), _numItemIconShapes(flags.gameID == GI_EOB1 ? 89 : 112),
+	_teleporterWallId(flags.gameID == GI_EOB1 ? 52 : 44) {
+	_screen = 0;
+	_gui = 0;
+
+	//_runLoopUnk2 = 0;
+	//_runLoopTimerUnk = 0;
+	_playFinale = false;
+	_runFlag = true;
+	_saveLoadMode = 0;
+	_updateHandItemCursor = false;
+
+	_largeItemShapes = _smallItemShapes = _thrownItemShapes = _spellShapes = _firebeamShapes = _itemIconShapes =
+		_wallOfForceShapes = _teleporterShapes = _sparkShapes = _compassShapes = 0;
+	_redSplatShape = _greenSplatShape = _deadCharShape = _disabledCharGrid = _blackBoxSmallGrid =
+		_weaponSlotGrid = _blackBoxWideGrid = _lightningColumnShape = 0;
+	_tempIconShape = 0;
+
+	_monsterDustStrings = 0;
+	_monsterDistAttType10 = 0;
+	_monsterDistAttSfx10 = 0;
+	_monsterDistAttType17 = 0;
+	_monsterDistAttSfx17 = 0;
+
+	_faceShapes = 0;
+	_characters = 0;
+	_items = 0;
+	_itemTypes = 0;
+	_itemNames = 0;
+	_itemInHand = -1;
+	_numItems = _numItemNames = 0;
+
+	_castScrollSlot = 0;
+	_currentSub = 0;
+
+	_itemsOverlay = 0;
+
+	_partyEffectFlags = 0;
+	_lastUsedItem = 0;
+
+	_levelDecorationRects = 0;
+	_doorSwitches = 0;
+	_monsterProps = 0;
+	_monsterDecorations = 0;
+	_monsterOvl1 = _monsterOvl2 = 0;
+	_monsters = 0;
+	_dstMonsterIndex = 0;
+	_inflictMonsterDamageUnk = 0;
+
+	_teleporterPulse = 0;
+
+	_dscShapeCoords = 0;
+	_dscItemPosIndex = 0;
+	_dscItemShpX = 0;
+	_dscItemScaleIndex = 0;
+	_dscItemTileIndex = 0;
+	_dscItemShapeMap = 0;
+	_dscDoorScaleOffs = 0;
+	_dscDoorScaleMult1 = 0;
+	_dscDoorScaleMult2 = 0;
+	_dscDoorScaleMult3 = 0;
+	_dscDoorY1 = 0;
+
+	_color9 = 17;
+	_color10 = 23;
+	_color11 = 20;
+
+	_exchangeCharacterId = -1;
+	_charExchangeSwap = 0;
+	_hpBarGraphs = true;
+
+	memset(_dialogueLastBitmap, 0, 13);
+	_dlgUnk1 = 0;
+	_moveCounter = 0;
+	_partyResting = false;
+
+	_flyingObjects = 0;
+
+	_inf = 0;
+	_stepCounter = 0;
+	_stepsUntilScriptCall = 0;
+	_scriptTimersMode = 3;
+	_currentDirection = 0;
+
+	_openBookSpellLevel = 0;
+	_openBookSpellSelectedItem = 0;
+	_openBookSpellListOffset = 0;
+	_openBookChar = _openBookCharBackup = 0;
+	_openBookType = _openBookTypeBackup = 0;
+	_openBookSpellList = 0;
+	_openBookAvailableSpells = 0;
+	_activeSpellCaster = 0;
+	_activeSpellCasterPos = 0;
+	_activeSpell = 0;
+	_returnAfterSpellCallback = false;
+	_spells = 0;
+	_spellAnimBuffer = 0;
+	_clericSpellOffset = 0;
+}
+
+EobCoreEngine::~EobCoreEngine() {
+	releaseItemsAndDecorationsShapes();
+	releaseTempData();
+
+	if (_faceShapes) {
+		for (int i = 0; i < 44; i++) {
+			if (_characters) {
+				for (int ii = 0; ii < 6; ii++) {
+					if (_characters[ii].faceShape == _faceShapes[i])
+						_characters[ii].faceShape = 0;
+				}
+			}
+			delete[] _faceShapes[i];
+			_faceShapes[i] = 0;
+		}
+		delete[] _faceShapes;
+	}
+
+	if (_characters) {
+		for (int i = 0; i < 6; i++)
+			delete[] _characters[i].faceShape;
+	}
+
+	delete[] _characters;
+	delete[] _items;
+	delete[] _itemTypes;
+	if (_itemNames) {
+		for (int i = 0; i < 130; i++)
+			delete _itemNames[i];
+	}
+	delete[] _itemNames;
+	delete[] _flyingObjects;
+
+	delete[] _monsterOvl1;
+	delete[] _monsterOvl2;
+	delete[] _monsters;
+
+	if (_monsterDecorations) {
+		releaseMonsterShapes(0, 36);
+		delete[] _monsterShapes;
+		delete[] _monsterDecorations;
+
+		for (int i = 0; i < 24; i++)
+			delete[] _monsterPalettes[i];
+		delete[] _monsterPalettes;
+	}
+
+	delete[] _monsterProps;
+
+	if (_doorSwitches) {
+		releaseDoorShapes();
+		delete[] _doorSwitches;
+	}
+
+	releaseDecorations();
+	delete[] _levelDecorationRects;
+
+	delete[] _spells;
+	delete[] _spellAnimBuffer;
+
+	delete _gui;
+	_gui = 0;
+	delete _inf;
+	delete _timer;
+	_timer = 0;
+}
+
+Common::Error EobCoreEngine::init() {
+	// In EOB the timer proc is directly invoked via interrupt 0x1c, 18.2 times per second.
+	// This makes a tick length of 54.94.
+	_tickLength = 55;
+
+	_screen = new Screen_Eob(this, _system);
+
+	assert(_screen);
+	_screen->setResolution();
+
+	// Setup mixer
+	_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
+	_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
+	_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
+
+	//MidiDriverType midiDriver = MidiDriver::detectDevice(MDT_PCSPK | MDT_ADLIB);
+	_sound = new SoundAdLibPC(this, _mixer);
+	assert(_sound);
+
+	if (_sound)
+		_sound->updateVolumeSettings();
+
+	_res = new Resource(this);
+	assert(_res);
+	_res->reset();
+
+	if (!screen()->init())
+		error("screen()->init() failed");
+
+	if (ConfMan.hasKey("save_slot")) {
+		_gameToLoad = ConfMan.getInt("save_slot");
+		if (!saveFileLoadable(_gameToLoad))
+			_gameToLoad = -1;
+	}
+
+	setupKeyMap();
+	_gui = new GUI_Eob(this);
+	_txt = new TextDisplayer_Eob(this, _screen);
+	_inf = new EobInfProcessor(this, _screen);
+
+	_screen->loadFont(Screen::FID_6_FNT, "FONT6.FNT");
+	_screen->loadFont(Screen::FID_8_FNT, "FONT8.FNT");
+
+	_activeButtons = 0;
+
+	_staticres = new StaticResource(this);
+	assert(_staticres);
+	if (!_staticres->init())
+		error("_staticres->init() failed");
+
+	Common::Error err = LolEobBaseEngine::init();
+	if (err.getCode() != Common::kNoError)
+		return err;
+
+	initButtonData();
+	initStaticResource();
+	initSpells();
+
+	_timer = new TimerManager(this, _system);
+	assert(_timer);
+	setupTimers();
+
+	_wllVmpMap[1] = 1;
+	_wllVmpMap[2] = 2;
+	memset(&_wllVmpMap[3], 3, 20);
+	_wllVmpMap[23] = 4;
+	_wllVmpMap[24] = 5;
+
+	memcpy(_wllWallFlags, _wllFlagPreset, _wllFlagPresetSize);
+
+	memset(&_specialWallTypes[3], 1, 5);
+	memset(&_specialWallTypes[13], 1, 5);
+	_specialWallTypes[8] = _specialWallTypes[18] = 6;
+
+	memset(&_wllShapeMap[3], -1, 5);
+	memset(&_wllShapeMap[13], -1, 5);
+
+	_wllVcnOffset = 16;
+
+	_monsters = new EobMonsterInPlay[30];
+	memset(_monsters, 0, 30 * sizeof(EobMonsterInPlay));
+
+	_characters = new EobCharacter[6];
+	memset(_characters, 0, sizeof(EobCharacter) * 6);
+
+	_items = new EobItem[600];
+	memset(_items, 0, sizeof(EobItem) * 600);
+
+	_itemNames = new char*[130];
+	for (int i = 0; i < 130; i++) {
+		_itemNames[i] = new char[35];
+		memset(_itemNames[i], 0, 35);
+	}
+
+	_flyingObjects = new EobFlyingObject[10];
+	memset(_flyingObjects, 0, 10 * sizeof(EobFlyingObject));
+
+	_spellAnimBuffer = new uint8[4096];
+	memset(_spellAnimBuffer, 0, 4096);
+
+	memset(_doorType, 0, sizeof(_doorType));
+	memset(_noDoorSwitch, 0, sizeof(_noDoorSwitch));
+
+	_monsterShapes = new uint8*[36];
+	memset(_monsterShapes, 0, 36 * sizeof(uint8*));
+	_monsterDecorations = new SpriteDecoration[36];
+	memset(_monsterDecorations, 0, 36 * sizeof(SpriteDecoration));
+	_monsterPalettes = new uint8*[24];
+	for (int i = 0; i < 24; i++)
+		_monsterPalettes[i] = new uint8[16];
+
+	_doorSwitches = new SpriteDecoration[6];
+	memset(_doorSwitches, 0, 6 * sizeof(SpriteDecoration));
+
+	_monsterOvl1 = new uint8[16];
+	_monsterOvl2 = new uint8[16];
+	memset(_monsterOvl1, 15, 16 * sizeof(uint8));
+	memset(_monsterOvl2, 13, 16 * sizeof(uint8));
+	_monsterOvl1[0] = _monsterOvl2[0] = 0;
+
+	return Common::kNoError;
+}
+
+Common::Error EobCoreEngine::go() {
+	_txt->removePageBreakFlag();
+	_screen->loadPalette("palette.col", _screen->getPalette(0));
+	_screen->setScreenPalette(_screen->getPalette(0));
+	_screen->setFont(Screen::FID_8_FNT);
+
+	loadItemsAndDecorationsShapes();
+	_screen->setMouseCursor(0, 0, _itemIconShapes[0]);
+	_screen->showMouse();
+
+	//initPlayBuffers
+
+	loadItemDefs();
+
+	int action = 0;
+
+	if (_gameToLoad != -1) {
+		if (loadGameState(_gameToLoad).getCode() != Common::kNoError)
+			error("Couldn't load game slot %d on startup", _gameToLoad);
+		_gameToLoad = -1;
+	} else {
+		action = mainMenu();
+	}
+
+	if (action == -1) {
+		// load game
+		_saveLoadMode = -1;
+		startupLoad();
+	} else if (action == -2) {
+		// new game
+		startCharacterGeneration();
+		startupNew();
+	} else if (action == -3) {
+		// transfer party
+	}
+
+	if (!shouldQuit() && action > -3) {
+		runLoop();
+
+		if (_playFinale)
+			seq_playFinale();
+	}
+
+	return Common::kNoError;
+}
+
+void EobCoreEngine::runLoop() {
+	_envAudioTimer = _system->getMillis() + (rollDice(1, 10, 3) * 18 * _tickLength);
+	///
+	// startupSub1
+	//
+	//
+	_updateFlags = 0;
+	//_unkCharacterId = 0;
+	_flashShapeTimer = 0;
+	_drawSceneTimer = _system->getMillis();
+	//_unkBBBBBBBBBBBBBBBB = 1;
+	gui_setPlayFieldButtons();
+	//
+
+	_screen->_curPage = 0;
+	gui_drawPlayField(0);
+
+	_screen->setFont(Screen::FID_6_FNT);
+
+	_screen->_curPage = 0;
+	gui_drawAllCharPortraitsWithStats();
+
+	drawScene(1);
+
+	_screen->setScreenDim(7);
+
+	//_runLoopUnk2 = _currentBlock;
+	_runFlag = true;
+
+	while (!shouldQuit() && _runFlag) {
+		//_runLoopUnk2 = _currentBlock;
+		updateCharacterEvents(true);
+		checkInput(_activeButtons, true);
+		removeInputTop();
+
+		if (_updateHandItemCursor) {
+			_updateHandItemCursor = false;
+			setHandItem(_itemInHand);
+		}
+
+		_timer->update();
+		updateScriptTimers();
+
+		if (_sceneUpdateRequired)
+			drawScene(1);
+
+		if (_envAudioTimer >= _system->getMillis())
+			continue;
+
+		_envAudioTimer = _system->getMillis() + (rollDice(1, 10, 3) * 18 * _tickLength);
+		snd_processEnvironmentalSoundEffect(rollDice(1, 2, -1) ? 27 : 28, _currentBlock + rollDice(1, 12, -1));
+		updateEnvironmentalSfx(0);
+	}
+}
+
+bool EobCoreEngine::updateCharacterEvents(bool a) {
+	int numChars = 0;
+	for (int i = 0; i < 6; i++)
+		numChars += testCharacter(i, 13);
+
+	if (numChars)
+		return false;
+
+	if (!a)
+		return true;
+
+
+	gui_drawAllCharPortraitsWithStats();
+
+	///	TODO
+	/// if (checkScriptFlag(0x10))
+	/// j_dranThoseFools()
+
+	///	TODO
+
+	///	TODO
+
+
+	return false;
+}
+
+void EobCoreEngine::loadItemsAndDecorationsShapes() {
+	releaseItemsAndDecorationsShapes();
+	_screen->setCurPage(2);
+
+	_screen->loadBitmap("ITEML1.CPS", 5, 3, 0);
+	_largeItemShapes = new const uint8*[_numLargeItemShapes];
+	int div = (_flags.gameID == GI_EOB1) ? 3 : 8;
+	int mul = (_flags.gameID == GI_EOB1) ? 64 : 24;
+
+	for (int i = 0; i < _numLargeItemShapes; i++)
+		_largeItemShapes[i] = _screen->encodeShape((i / div) << 3, (i % div) * mul, 8, 24);
+
+	_screen->loadBitmap("ITEMS1.CPS", 5, 3, 0);
+	_smallItemShapes = new const uint8*[_numSmallItemShapes];
+	for (int i = 0; i < _numSmallItemShapes; i++)
+		_smallItemShapes[i] = _screen->encodeShape((i / div) << 2, (i % div) * mul, 4, 24);
+
+	_screen->loadBitmap("THROWN.CPS", 5, 3, 0);
+	_thrownItemShapes = new const uint8*[_numThrownItemShapes];
+	for (int i = 0; i < _numThrownItemShapes; i++)
+		_thrownItemShapes[i] = _screen->encodeShape((i / div) << 2, (i % div) * mul, 4, 24);
+
+	_spellShapes = new const uint8*[4];
+	for (int i = 0; i < 4; i++)
+		_spellShapes[i] = _screen->encodeShape(8, i << 5, 6, 32);
+
+	_firebeamShapes = new const uint8*[3];
+	_firebeamShapes[0] = _screen->encodeShape(16, 0, 4, 24);
+	_firebeamShapes[1] = _screen->encodeShape(16, 24, 4, 24);
+	_firebeamShapes[2] = _screen->encodeShape(16, 48, 3, 24);
+	_redSplatShape = _screen->encodeShape(16, _flags.gameID == GI_EOB1 ? 144 : 72, 5, 24);
+	_greenSplatShape = _screen->encodeShape(16, _flags.gameID == GI_EOB1 ? 168 : 96, 5, 16);
+
+	_screen->loadBitmap("ITEMICN.CPS", 5, 3, 0);
+	_itemIconShapes = new const uint8*[_numItemIconShapes];
+	for (int i = 0; i < _numItemIconShapes; i++)
+		_itemIconShapes[i] = _screen->encodeShape((i % 0x14) << 1, (i / 0x14) << 4, 2, 0x10);
+	_tempIconShape = new uint8[300];
+
+	_screen->loadBitmap("DECORATE.CPS", 5, 3, 0);
+
+	if (_flags.gameID == GI_EOB2) {
+		_lightningColumnShape = _screen->encodeShape(18, 88, 4, 64);
+		_wallOfForceShapes = new const uint8*[6];
+		for (int i = 0; i < 6; i++)
+			_wallOfForceShapes[i] = _screen->encodeShape(_wallOfForceShapeDefs[(i << 2)], _wallOfForceShapeDefs[(i << 2) + 1], _wallOfForceShapeDefs[(i << 2) + 2], _wallOfForceShapeDefs[(i << 2) + 3]);
+	}
+
+	_teleporterShapes = new const uint8*[6];
+	for (int i = 0; i < 6; i++)
+		_teleporterShapes[i] = _screen->encodeShape(_teleporterShapeDefs[(i << 2)], _teleporterShapeDefs[(i << 2) + 1], _teleporterShapeDefs[(i << 2) + 2], _teleporterShapeDefs[(i << 2) + 3]);
+	_sparkShapes = new const uint8*[3];
+	_sparkShapes[0] = _screen->encodeShape(29, 0, 2, 16);
+	_sparkShapes[1] = _screen->encodeShape(31, 0, 2, 16);
+	_sparkShapes[2] = _screen->encodeShape(33, 0, 2, 16);
+	_deadCharShape = _screen->encodeShape(0, 88, 4, 32);
+	_disabledCharGrid = _screen->encodeShape(4, 88, 4, 32);
+	_blackBoxSmallGrid = _screen->encodeShape(9, 88, 2, 8);
+	_weaponSlotGrid = _screen->encodeShape(8, 88, 4, 16);
+	_blackBoxWideGrid = _screen->encodeShape(8, 104, 4, 8);
+
+	static const uint8 dHeight[] = { 17, 10, 10 };
+	static const uint8 dY[] = { 120, 137, 147 };
+
+	_compassShapes = new const uint8*[12];
+	for (int y = 0; y < 3; y++) {
+		for (int x = 0; x < 4; x++)
+			_compassShapes[(y << 2) + x] = _screen->encodeShape(x * 3, dY[y], 3, dHeight[y]);
+	}
+}
+
+void EobCoreEngine::releaseItemsAndDecorationsShapes() {
+	if (_largeItemShapes) {
+		for (int i = 0; i < _numLargeItemShapes; i++) {
+			if (_largeItemShapes[i])
+				delete[] _largeItemShapes[i];
+		}
+		delete[] _largeItemShapes;
+	}
+
+	if (_smallItemShapes) {
+		for (int i = 0; i < _numSmallItemShapes; i++) {
+			if (_smallItemShapes[i])
+				delete[] _smallItemShapes[i];
+		}
+		delete[] _smallItemShapes;
+	}
+
+	if (_thrownItemShapes) {
+		for (int i = 0; i < _numThrownItemShapes; i++) {
+			if (_thrownItemShapes[i])
+				delete[] _thrownItemShapes[i];
+		}
+		delete[] _thrownItemShapes;
+	}
+
+	if (_spellShapes) {
+		for (int i = 0; i < 4; i++) {
+			if (_spellShapes[i])
+				delete [] _spellShapes[i];
+		}
+		delete[] _spellShapes;
+	}
+
+	if (_itemIconShapes) {
+		for (int i = 0; i < _numItemIconShapes; i++) {
+			if (_itemIconShapes[i])
+				delete[] _itemIconShapes[i];
+		}
+		delete[] _itemIconShapes;
+	}
+	delete[] _tempIconShape;
+
+	if (_sparkShapes) {
+		for (int i = 0; i < 3; i++) {
+			if (_sparkShapes[i])
+				delete[] _sparkShapes[i];
+		}
+		delete[] _sparkShapes;
+	}
+
+	if (_wallOfForceShapes) {
+		for (int i = 0; i < 6; i++) {
+			if (_wallOfForceShapes[i])
+				delete[] _wallOfForceShapes[i];
+		}
+		delete[] _wallOfForceShapes;
+	}
+
+	if (_teleporterShapes) {
+		for (int i = 0; i < 6; i++) {
+			if (_teleporterShapes[i])
+				delete[] _teleporterShapes[i];
+		}
+		delete[] _teleporterShapes;
+	}
+
+	if (_compassShapes) {
+		for (int i = 0; i < 12; i++) {
+			if (_compassShapes[i])
+				delete[] _compassShapes[i];
+		}
+		delete[] _compassShapes;
+	}
+
+	if (_firebeamShapes) {
+		for (int i = 0; i < 3; i++) {
+			if (_firebeamShapes[i])
+				delete[] _firebeamShapes[i];
+		}
+		delete []_firebeamShapes;
+	}
+
+	delete[] _deadCharShape;
+	delete[] _disabledCharGrid;
+	delete[] _blackBoxSmallGrid;
+	delete[] _weaponSlotGrid;
+	delete[] _blackBoxWideGrid;
+	delete[] _lightningColumnShape;
+}
+
+void EobCoreEngine::setHandItem(Item itemIndex) {
+	if (itemIndex == -1)
+		return;
+
+	if (_screen->curDimIndex() == 7 && itemIndex) {
+		printFullItemName(itemIndex);
+		_txt->printMessage(_takenStrings[0]);
+	}
+
+	_itemInHand = itemIndex;
+	int icon = _items[_itemInHand].icon;
+	const uint8 *shp = _itemIconShapes[icon];
+
+	if (icon && (_items[_itemInHand].flags & 0x80) && ((_flags.gameID == GI_EOB2 && (_partyEffectFlags & 2)) || (_flags.gameID == GI_EOB1 && (_partyEffectFlags & 0x10000)))) {
+		memcpy(_tempIconShape, shp, 300);
+		if (_flags.gameID == GI_EOB1)
+			_screen->replaceShapePalette(_tempIconShape, &_itemsOverlay[icon << 4]);
+		else
+			_screen->applyShapeOverlay(_tempIconShape, 3);
+		shp = _tempIconShape;
+	}
+
+	int mouseOffs = itemIndex ? 8 : 0;
+	_screen->setMouseCursor(mouseOffs, mouseOffs, shp);
+}
+
+int EobCoreEngine::getDexterityArmorClassModifier(int dexterity) {
+	static const int mod[] = { 5, 5, 5, 4, 3, 2, 1, 0, 0,
+		0, 0, 0, 0, 0, 0, -1, -2, -3, -4, -4, -5, -5, -5, -6, -6 };
+	return mod[dexterity];
+}
+
+int EobCoreEngine::generateCharacterHitpointsByLevel(int charIndex, int levelIndex) {
+	EobCharacter *c = &_characters[charIndex];
+	int m = getClassAndConstHitpointsModifier(c->cClass, c->constitutionCur);
+
+	int h = 0;
+
+	for (int i = 0; i < 3; i++) {
+		if (!(levelIndex & (1 << i)))
+			continue;
+
+		int d = getClassHpIncreaseType(c->cClass, i);
+
+		if (c->level[i] <= _hpIncrPerLevel[6 + i])
+			h += rollDice(1, (d >= 0) ? _hpIncrPerLevel[d] : 0);
+		else
+			h += _hpIncrPerLevel[12 + i];
+
+		h += m;
+	}
+
+	h /= _numLevelsPerClass[c->cClass];
+
+	if (h < 1)
+		h = 1;
+
+	return h;
+}
+
+int EobCoreEngine::getClassAndConstHitpointsModifier(int cclass, int constitution) {
+	int res = _hpConstModifiers[constitution];
+
+	if (res <= 2 || (_classModifierFlags[cclass] & 0x31))
+		return res;
+
+	return 2;
+}
+
+int EobCoreEngine::getClassHpIncreaseType(int cclass, int levelIndex) {
+	return _classHpIncreaseType[cclass * 3 + levelIndex];
+}
+
+int EobCoreEngine::getModifiedHpLimits(int hpModifier, int constModifier, int level, bool mode) {
+	int s = _hpIncrPerLevel[6 + hpModifier] > level ? level : _hpIncrPerLevel[6 + hpModifier];
+	int res = s;
+
+	if (!mode)
+		res *= (hpModifier >= 0 ? _hpIncrPerLevel[hpModifier] : 0);
+
+	if (level > s) {
+		s = level - s;
+		res += (s * _hpIncrPerLevel[12 + hpModifier]);
+	}
+
+	if (!mode || (constModifier > 0))
+		res += (level * constModifier);
+
+	return res;
+}
+
+const char *EobCoreEngine::getCharStrength(int str, int strExt) {
+	if (strExt) {
+		if (strExt == 100)
+			strExt = 0;
+		snprintf(_strenghtStr, 6, "%d/%02d", str, strExt);
+	} else {
+		snprintf(_strenghtStr, 6, "%d", str);
+	}
+
+	return _strenghtStr;
+}
+
+int EobCoreEngine::testCharacter(int index, int flags) {
+	if (index == -1)
+		return 0;
+
+	EobCharacter *c = &_characters[index];
+	int res = 1;
+
+	if (flags & 1)
+		res &= (c->flags & 1);
+
+	if (flags & 2)
+		res &= ((c->hitPointsCur <= -10) || (c->flags & 8)) ? 0 : 1;
+
+	if (flags & 4)
+		res &= ((c->hitPointsCur <= 0) || (c->flags & 8)) ? 0 : 1;
+
+	if (flags & 8)
+		res &= (c->flags & 12) ? 0 : 1;
+
+	if (flags & 0x20)
+		res &= (c->flags & 4) ? 0 : 1;
+
+	if (flags & 0x10)
+		res &= (c->flags & 2) ? 0 : 1;
+
+	if (flags & 0x40)
+		res &= (c->food <= 0) ? 0 : 1;
+
+	return res;
+}
+
+int EobCoreEngine::getNextValidCharIndex(int curCharIndex, int searchStep) {
+	do {
+		curCharIndex += searchStep;
+		if (curCharIndex < 0)
+			curCharIndex = 5;
+		if (curCharIndex > 5)
+			curCharIndex = 0;
+	} while (!testCharacter(curCharIndex, 1));
+
+	return curCharIndex;
+}
+
+void EobCoreEngine::recalcArmorClass(int index) {
+	EobCharacter *c = &_characters[index];
+	int acm = getDexterityArmorClassModifier(c->dexterityCur);
+	c->armorClass = 10 + acm;
+
+	static uint8 slot[] = { 17, 0, 1, 18 };
+	for (int i = 0; i < 4; i++) {
+		int itm = c->inventory[slot[i]];
+		if (!itm)
+			continue;
+
+		if (i == 2) {
+			if (!validateWeaponSlotItem(index, 1))
+				continue;
+		}
+
+		int tp = _items[itm].type;
+
+		if (!(_itemTypes[tp].allowedClasses & _classModifierFlags[c->cClass]) || (_itemTypes[tp].extraProperties & 0x7f) || (i >= 1 && i <= 2 && tp != 27 && !(_flags.gameID == GI_EOB2 && tp == 57)))
+			continue;
+
+		c->armorClass += _itemTypes[tp].armorClass;
+		c->armorClass -= _items[itm].value;
+	}
+
+	if (!_items[c->inventory[17]].value) {
+		int8 m1 = 0;
+		int8 m2 = 0;
+
+		if (c->inventory[25]) {
+			if (!(_itemTypes[_items[c->inventory[25]].type].extraProperties & 0x7f))
+				m1 = _items[c->inventory[25]].value;
+		}
+
+		if (c->inventory[26]) {
+			if (!(_itemTypes[_items[c->inventory[26]].type].extraProperties & 0x7f))
+				m2 = _items[c->inventory[26]].value;
+		}
+
+		c->armorClass -= MAX(m1, m2);
+	}
+
+	if (c->effectsRemainder[0] > 0) {
+		if (c->armorClass <= (acm + 6))
+			c->effectsRemainder[0] = 0;
+		else
+			c->armorClass = (acm + 6);
+	}
+
+	// shield
+	if ((c->effectFlags & 8) && (c->armorClass > 4))
+		c->armorClass = 4;
+
+	// magical vestment
+	if (c->effectFlags & 0x4000) {
+		int8 m1 = 5;
+
+		if (getCharacterClericPaladinLevel(index) > 5)
+			m1 += ((getCharacterClericPaladinLevel(index) - 5) / 3);
+
+		if (c->armorClass > m1)
+			c->armorClass = m1;
+	}
+
+	if (c->armorClass < -10)
+		c->armorClass = -10;
+}
+
+int EobCoreEngine::validateWeaponSlotItem(int index, int slot) {
+	EobCharacter *c = &_characters[index];
+	int itm1 = c->inventory[0];
+	int r = itemUsableByCharacter(index, itm1);
+	int tp1 = _items[itm1].type;
+
+	if (!slot)
+		return (!itm1 || r) ? 1 : 0;
+
+	int itm2 = c->inventory[1];
+	r = itemUsableByCharacter(index, itm2);
+	int tp2 = _items[itm2].type;
+
+	if (itm1 && _itemTypes[tp1].requiredHands == 2)
+		return 0;
+
+	if (!itm2)
+		return 1;
+
+	int f = (_itemTypes[tp2].extraProperties & 0x7f);
+	if (f <= 0 || f > 3)
+		return r;
+
+	if (_itemTypes[tp2].requiredHands)
+		return 0;
+
+	return r;
+}
+
+int EobCoreEngine::getCharacterClericPaladinLevel(int index) {
+	if (_castScrollSlot)
+		return 9;
+
+	if (index == -1)
+		return (_currentLevel < 7) ? 5 : 9;
+
+	int l = getLevelIndexForHpIncType(2, _characters[index].cClass);
+	if (l > -1)
+		return _characters[index].level[l];
+
+	l = getLevelIndexForHpIncType(4, _characters[index].cClass);
+	if (l > -1) {
+		if (_characters[index].level[l] > 8)
+			return _characters[index].level[l] - 8;
+	}
+
+	return 1;
+}
+
+int EobCoreEngine::getCharacterMageLevel(int index) {
+	if (_castScrollSlot)
+		return 9;
+
+	if (index == -1)
+		return (_currentLevel < 7) ? 5 : 9;
+
+	int l = getLevelIndexForHpIncType(1, _characters[index].cClass);
+	return (l > -1) ? _characters[index].level[l] : 1;
+}
+
+int EobCoreEngine::getLevelIndexForHpIncType(int hpIncType, int cClass) {
+	if (getClassHpIncreaseType(cClass, 0) == hpIncType)
+		return 0;
+
+	if (getClassHpIncreaseType(cClass, 1) == hpIncType)
+		return 1;
+
+	if (getClassHpIncreaseType(cClass, 2) == hpIncType)
+		return 2;
+
+	return -1;
+}
+
+int EobCoreEngine::countCharactersWithSpecificItems(int16 itemType, int16 itemValue) {
+	int res = 0;
+	for (int i = 0; i < 6; i++) {
+		if (!testCharacter(i, 1))
+			continue;
+		if (checkCharacterInventoryForItem(i, itemType, itemValue) != -1)
+			res++;
+	}
+	return res;
+}
+
+int EobCoreEngine::checkCharacterInventoryForItem(int character, int16 itemType, int16 itemValue) {
+	for (int i = 0; i < 27; i++) {
+		uint16 inv = _characters[character].inventory[i];
+		if (!inv)
+			continue;
+		if (_items[inv].type != itemType && itemType != -1)
+			continue;
+		if (_items[inv].value == itemValue || itemValue == -1)
+			return i;
+	}
+	return -1;
+}
+
+void EobCoreEngine::modifyCharacterHitpoints(int character, int16 points) {
+	if (!testCharacter(character, 3))
+		return;
+
+	EobCharacter *c = &_characters[character];
+	c->hitPointsCur += points;
+	if (c->hitPointsCur > c->hitPointsMax)
+		c->hitPointsCur = c->hitPointsMax;
+
+	gui_drawHitpoints(character);
+	gui_drawCharPortraitWithStats(character);
+}
+
+void EobCoreEngine::neutralizePoison(int character) {
+	_characters[character].flags &= ~2;
+	_characters[character].effectFlags &= ~0x2000;
+	deleteCharEventTimer(character, -34);
+	gui_drawCharPortraitWithStats(character);
+}
+
+void EobCoreEngine::initNpc(int npcIndex) {
+	EobCharacter *c = _characters;
+	int i = 0;
+	for (; i < 6; i++) {
+		if (!(_characters[i].flags & 1)) {
+			c = &_characters[i];
+			break;
+		}
+	}
+
+	delete[] c->faceShape;
+	memcpy(c, &_npcPreset[npcIndex], sizeof(EobCharacter));
+	recalcArmorClass(i);
+
+	for (i = 0; i < 25; i++) {
+		if (!c->inventory[i])
+			continue;
+		c->inventory[i] = duplicateItem(c->inventory[i]);
+	}
+
+	_screen->loadEobBitmap(_flags.gameID == GI_EOB2 ? "OUTPORTS" : "OUTTAKE", 3, 3);
+	_screen->_curPage = 2;
+	c->faceShape = _screen->encodeShape(npcIndex << 2, _flags.gameID == GI_EOB2 ? 0 : 160, 4, 32, true);
+	_screen->_curPage = 0;
+}
+
+int EobCoreEngine::npcJoinDialogue(int npcIndex, int queryJoinTextId, int confirmJoinTextId, int noJoinTextId) {
+	gui_drawDialogueBox();
+	_txt->printDialogueText(queryJoinTextId, 0);
+
+	int r = runDialogue(-1, 0, _yesNoStrings[0], _yesNoStrings[1]) - 1;
+	if (r == 0) {
+		if (confirmJoinTextId == -1) {
+			char tmp[35];
+			snprintf(tmp, 35, _npcJoinStrings[0], _npcPreset[npcIndex].name);
+			_txt->printDialogueText(tmp, true);
+		} else {
+			_txt->printDialogueText(confirmJoinTextId, _okStrings[0]);
+		}
+
+		if (prepareForNewPartyMember(33, npcIndex + 1))
+			initNpc(npcIndex);
+
+	} else if (r == 1) {
+		_txt->printDialogueText(noJoinTextId, _okStrings[0]);
+	}
+
+	return r ^ 1;
+}
+
+int EobCoreEngine::prepareForNewPartyMember(int16 itemType, int16 itemValue) {
+	int numChars = 0;
+	for (int i = 0; i < 6; i++)
+		numChars += (_characters[i].flags & 1);
+
+	if (numChars < 6) {
+		deletePartyItem(itemType, itemValue);
+	} else {
+		gui_drawDialogueBox();
+		_txt->printDialogueText(_npcMaxStrings[0]);
+		int r = runDialogue(-1, 1, _characters[0].name, _characters[1].name, _characters[2].name, _characters[3].name,
+			_characters[4].name, _characters[5].name, _abortStrings[0], 0, 0) - 1;
+
+		if (r == 6)
+			return 0;
+
+		deletePartyItem(itemType, itemValue);
+		removeCharacterFromParty(r);
+	}
+
+	return 1;
+}
+
+void EobCoreEngine::removeCharacterFromParty(int charIndex) {
+	EobCharacter *c = &_characters[charIndex];
+	c->flags = 0;
+
+	for (int i = 0; i < 27; i++) {
+		if (i == 16 || !c->inventory[i])
+			continue;
+
+		setItemPosition((Item*)&_levelBlockProperties[_currentBlock & 0x3ff].drawObjects, _currentBlock, c->inventory[i], _dropItemDirIndex[(_currentDirection << 2) + rollDice(1, 2, -1)]);
+		c->inventory[i] = 0;
+	}
+
+	while (c->inventory[16])
+		setItemPosition((Item*)&_levelBlockProperties[_currentBlock & 0x3ff].drawObjects, _currentBlock, getQueuedItem(&c->inventory[16], 0, -1), _dropItemDirIndex[(_currentDirection << 2) + rollDice(1, 2, -1)]);
+
+	c->inventory[16] = 0;
+
+	if (_updateCharNum == charIndex)
+		_updateCharNum = 0;
+
+	setupCharacterTimers();
+}
+
+void EobCoreEngine::increasePartyExperience(int16 points) {
+	int cnt = 0;
+	for (int i = 0; i < 6; i++) {
+		if (testCharacter(i, 3))
+			cnt++;
+	}
+
+	if (cnt <= 0)
+		return;
+
+	points /= cnt;
+
+	for (int i = 0; i < 6; i++) {
+		if (!testCharacter(i, 3))
+			continue;
+		increaseCharacterExperience(i, points);
+	}
+}
+
+void EobCoreEngine::increaseCharacterExperience(int charIndex, int32 points) {
+	int cl = _characters[charIndex].cClass;
+	points /= _numLevelsPerClass[cl];
+
+	for (int i = 0; i < 3; i++) {
+		if (getClassHpIncreaseType(cl, i) == -1)
+			continue;
+		_characters[charIndex].experience[i] += points;
+
+		uint32 er = getRequiredExperience(cl, i, _characters[charIndex].level[i] + 1);
+		if (er == 0xffffffff)
+			continue;
+
+		if (_characters[charIndex].experience[i] >= er)
+			increaseCharacterLevel(charIndex, i);
+	}
+}
+
+uint32 EobCoreEngine::getRequiredExperience(int cClass, int levelIndex, int level) {
+	cClass = getClassHpIncreaseType(cClass, levelIndex);
+	if (cClass == -1)
+		return 0xffffffff;
+
+	const uint32 *tbl = _expRequirementTables[cClass];
+	return tbl[level - 1];
+}
+
+void EobCoreEngine::increaseCharacterLevel(int charIndex, int levelIndex) {
+	_characters[charIndex].level[levelIndex]++;
+	int hpInc = generateCharacterHitpointsByLevel(charIndex, levelIndex);
+	_characters[charIndex].hitPointsCur += hpInc;
+	_characters[charIndex].hitPointsMax += hpInc;
+
+	gui_drawCharPortraitWithStats(charIndex);
+	_txt->printMessage(_levelGainStrings[0], -1, _characters[charIndex].name);
+	snd_playSoundEffect(23);
+}
+
+void EobCoreEngine::setWeaponSlotStatus(int charIndex, int mode, int slot) {
+	if (mode == 0 || mode == 2)
+		_characters[charIndex].disabledSlots ^= (1 << slot);
+	else if (mode != 1)
+		return;
+
+	_characters[charIndex].slotStatus[slot] = 0;
+	gui_drawCharPortraitWithStats(charIndex);
+}
+
+void EobCoreEngine::setupDialogueButtons(int presetfirst, int numStr, const char *str1, ...) {
+	_dialogueNumButtons = numStr;
+	_dialogueButtonString[0] = str1;
+	_dialogueHighlightedButton = 0;
+
+	va_list args;
+	va_start(args, str1);
+	const char **s5p = va_arg(args, const char**);
+	va_end(args);
+	for (int i = 1; i < numStr; i++) {
+		if (s5p[i - 1])
+			_dialogueButtonString[i] = s5p[i - 1];
+		else
+			_dialogueNumButtons = numStr = i;
+	}
+
+	static const uint16 prsX[] = { 59, 166, 4, 112, 220, 4, 112, 220, 4, 112, 220, 4, 112, 220 };
+	static const uint8 prsY[] = { 0, 0, 0, 0, 0, 12, 12, 12, 24, 24, 24, 36, 36, 36 };
+
+	const ScreenDim *dm = screen()->_curDim;
+	int yOffs = (_txt->lineCount() + 1) * _screen->getFontHeight() + dm->sy + 4;
+
+	_dialogueButtonPosX = &prsX[presetfirst];
+	_dialogueButtonPosY = &prsY[presetfirst];
+	_dialogueButtonYoffs = yOffs;
+
+	drawDialogueButtons();
+
+	if (!shouldQuit())
+		removeInputTop();
+}
+
+void EobCoreEngine::initDialogueSequence() {
+	_dlgUnk1 = -1;
+	_txt->setWaitButtonMode(0);
+	_dialogueField = true;
+
+	_dialogueLastBitmap[0] = 0;
+
+	_txt->resetPageBreakString();
+	gui_updateControls();
+
+	_sound->playTrack(0);
+	Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
+	_screen->loadFileDataToPage(s, 5, 32000);
+	_txt->setupField(9, 0);
+	delete s;
+}
+
+void EobCoreEngine::restoreAfterDialogueSequence() {
+	_txt->allowPageBreak(false);
+	_dialogueField = false;
+
+	_dialogueLastBitmap[0] = 0;
+
+	gui_restorePlayField();
+	_screen->setScreenDim(7);
+
+	if (_flags.gameID == GI_EOB2)
+		_sound->playTrack(2);
+
+	_sceneUpdateRequired = true;
+}
+
+void EobCoreEngine::drawSequenceBitmap(const char *file, int destRect, int x1, int y1, int flags) {
+	static const uint8 frameX[] = { 1, 0 };
+	static const uint8 frameY[] = { 8, 0 };
+	static const uint8 frameW[] = { 20, 40 };
+	static const uint8 frameH[] = { 96, 121 };
+
+	int page = ((flags & 2) || destRect) ? 0 : 6;
+
+	if (scumm_stricmp(_dialogueLastBitmap, file)) {
+		if (!destRect) {
+			if (!(flags & 1)) {
+				_screen->loadEobCpsFileToPage("BORDER", 0, 3, 3, 2);
+				_screen->copyRegion(0, 0, 0, 0, 184, 121, 2, page, Screen::CR_NO_P_CHECK);
+			} else {
+				_screen->copyRegion(0, 0, 0, 0, 184, 121, 0, page, Screen::CR_NO_P_CHECK);
+			}
+
+			if (!page)
+				_screen->copyRegion(0, 0, 0, 0, 184, 121, 2, 6, Screen::CR_NO_P_CHECK);
+		}
+
+		_screen->loadEobCpsFileToPage(file, 0, 3, 3, 2);
+		strcpy(_dialogueLastBitmap, file);
+	}
+
+	if (flags & 2)
+		_screen->crossFadeRegion(x1 << 3, y1, frameX[destRect] << 3, frameY[destRect], frameW[destRect] << 3, frameH[destRect], 2, page);
+	else
+		_screen->copyRegion(x1 << 3, y1, frameX[destRect] << 3, frameY[destRect], frameW[destRect] << 3, frameH[destRect], 2, page, Screen::CR_NO_P_CHECK);
+
+	if (page == 6)
+		_screen->copyRegion(0, 0, 0, 0, 184, 121, 6, 0, Screen::CR_NO_P_CHECK);
+
+	_screen->updateScreen();
+}
+
+int EobCoreEngine::runDialogue(int dialogueTextId, int style, const char *button1, ...) {
+	if (dialogueTextId != -1)
+		txt()->printDialogueText(dialogueTextId, 0);
+
+	va_list args;
+	va_start(args, button1);
+	if (style)
+		setupDialogueButtons(2, 9, button1, args);
+	else
+		setupDialogueButtons(0, 2, button1, args);
+	va_end(args);
+
+	int res = 0;
+	while (res == 0 && !shouldQuit())
+		res = processDialogue();
+
+	gui_drawDialogueBox();
+
+	return res;
+}
+
+void EobCoreEngine::delay(uint32 millis, bool, bool) {
+	while (millis && !shouldQuit() && !skipFlag()) {
+		updateInput();
+		uint32 step = MIN<uint32>(millis, (_tickLength / 5));
+		_system->delayMillis(step);
+		millis -= step;
+	}
+}
+
+void EobCoreEngine::displayParchment(int id) {
+	_txt->setWaitButtonMode(1);
+	_txt->resetPageBreakString();
+	gui_updateControls();
+
+	if (id >= 0) {
+		// display text
+		Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
+		_screen->loadFileDataToPage(s, 5, 32000);
+		gui_drawBox(0, 0, 176, 175, _color1_1, _color2_1, _bkgColor_1);
+		_txt->setupField(12, 1);
+		if (_flags.gameID == GI_EOB2)
+			id++;
+		_txt->printDialogueText(id, _okStrings[0]);
+
+	} else {
+		// display bitmap
+		id = -id - 1;
+		static const uint8 x[] = { 0, 20, 0 };
+		static const uint8 y[] = { 0, 0, 96 };
+		drawSequenceBitmap("MAP", 0, x[id], y[id], 0);
+
+		removeInputTop();
+		while (!shouldQuit()) {
+			delay(_tickLength);
+			if (checkInput(0) & 0xff)
+				break;
+			removeInputTop();
+		}
+		removeInputTop();
+	}
+
+	restoreAfterDialogueSequence();
+}
+
+void EobCoreEngine::useSlotWeapon(int charIndex, int slotIndex, int item) {
+	EobCharacter *c = &_characters[charIndex];
+	int tp = item ? _items[item].type : 0;
+
+	if (c->effectFlags & 0x40)
+		removeCharacterEffect(10, charIndex, 1); // remove invisibility effect
+
+	int ep = _itemTypes[tp].extraProperties & 0x7f;
+	int8 inflict = 0;
+
+	if (ep == 1) {
+		inflict = closeDistanceAttack(charIndex, item);
+		if (!inflict)
+			inflict = -1;
+		snd_playSoundEffect(32);
+	} else if (ep == 2) {
+		inflict = thrownAttack(charIndex, slotIndex, item);
+	} else if (ep == 3) {
+		inflict = bowAttack(charIndex, item);
+		gui_drawCharPortraitWithStats(charIndex);
+	}
+
+	if (inflict > 0) {
+		if (_items[item].flags & 8) {
+			c->hitPointsCur += inflict;
+			gui_drawCharPortraitWithStats(charIndex);
+		}
+
+		if (_items[item].flags & 0x10)
+			c->inventory[slotIndex] = 0;
+
+		inflictMonsterDamage(&_monsters[_dstMonsterIndex], inflict, true);
+	}
+
+	c->disabledSlots ^= (1 << slotIndex);
+	c->slotStatus[slotIndex] = inflict;
+
+	gui_drawCharPortraitWithStats(charIndex);
+	setCharEventTimer(charIndex, 18, inflict >= -2 ? slotIndex + 2 : slotIndex, 1);
+}
+
+int EobCoreEngine::closeDistanceAttack(int charIndex, int item) {
+	if (charIndex > 1)
+		return -3;
+
+	uint16 d = calcNewBlockPosition(_currentBlock, _currentDirection);
+	int r = getClosestMonsterPos(charIndex, d);
+
+	if (r == -1) {
+		uint8 w = _specialWallTypes[_levelBlockProperties[d].walls[_sceneDrawVarDown]];
+		if (w == 0xff) {
+			if (_flags.gameID == GI_EOB1) {
+				_levelBlockProperties[d].walls[_sceneDrawVarDown]++;
+				_levelBlockProperties[d].walls[_sceneDrawVarDown ^ 2]++;
+
+			} else {
+				for (int i = 0; i < 4; i++) {
+					if (_specialWallTypes[_levelBlockProperties[d].walls[i]] == 0xff)
+						_levelBlockProperties[d].walls[i]++;
+				}
+			}
+			_sceneUpdateRequired = true;
+
+		} else if ((_flags.gameID == GI_EOB1) || (_flags.gameID == GI_EOB2 && w != 8 && w != 9)) {
+			return -1;
+		}
+
+		return (_flags.gameID == GI_EOB2 && ((_itemTypes[_items[item].type].allowedClasses & 4) || !item)) ? -5 : -2;
+
+	} else {
+		if (_monsters[r].flags & 0x20) {
+			killMonster(&_monsters[r], 1);
+			_txt->printMessage(_monsterDustStrings[0]);
+			return -2;
+		}
+
+		if (!characterAttackHitTest(charIndex, r, item, 1))
+			return -1;
+
+		uint16 flg = 0x100;
+
+		if ((_flags.gameID == GI_EOB1 && _items[item].type > 51 && _items[item].type < 57) || (_flags.gameID == GI_EOB2 && isMagicWeapon(item)))
+			flg |= 1;
+
+		_dstMonsterIndex = r;
+		return calcCloseDistanceMonsterDamage(&_monsters[r], charIndex, item, 1, flg, 5, 3);
+	}
+
+	return 0;
+}
+
+int EobCoreEngine::thrownAttack(int charIndex, int slotIndex, int item) {
+	int d = charIndex > 3 ? charIndex - 2 : charIndex;
+	if (!launchObject(charIndex, item, _currentBlock, _dropItemDirIndex[(_currentDirection << 2) + d], _currentDirection, _items[item].type))
+		return 0;
+
+	snd_playSoundEffect(11);
+	_characters[charIndex].inventory[slotIndex] = 0;
+	reloadWeaponSlot(charIndex, slotIndex, -1, 0);
+	_sceneUpdateRequired = true;
+	return 0;
+}
+
+int EobCoreEngine::bowAttack(int charIndex, int item) {
+	return 0;
+}
+
+void EobCoreEngine::inflictMonsterDamage(EobMonsterInPlay *m, int damage, bool giveExperience) {
+	m->hitPointsCur -= damage;
+	m->flags = (m->flags & 0xf7) | 1;
+
+	if (_monsterProps[m->type].flags & 0x2000) {
+		inflictMonsterDamage_s1(m);
+		checkSceneUpdateNeed(m->block);
+		m->hitPointsCur = 0;
+	} else {
+		if (checkSceneUpdateNeed(m->block)) {
+			m->flags |= 2;
+			if (_inflictMonsterDamageUnk)
+				return;
+			flashMonsterShape(m);
+		}
+	}
+
+	if (m->hitPointsCur <= 0)
+		killMonster(m, giveExperience);
+	else if (getBlockDistance(m->block, _currentBlock) < 4)
+		m->dest = _currentBlock;
+}
+
+void EobCoreEngine::calcAndInflictMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int b, int damageType) {
+	int dmg = calcCloseDistanceMonsterDamage(m, times, pips, offs, flags, b, damageType);
+	if (dmg > 0)
+		inflictMonsterDamage(m, dmg, flags & 0x800 ? true : false);
+}
+
+void EobCoreEngine::calcAndInflictCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flg, int a, int damageType) {
+	int dmg = calcCharacterDamage(charIndex, times, itemOrPips, useStrModifierOrBase, flg, a, damageType);
+	if (dmg)
+		inflictCharacterDamage(charIndex, dmg);
+}
+
+int EobCoreEngine::calcCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flg, int a, int damageType) {
+	int s = (flg & 0x100) ? calcDamageModifers(times, 0, itemOrPips, _items[itemOrPips].type, useStrModifierOrBase) : rollDice(times, itemOrPips, useStrModifierOrBase);
+	EobCharacter *c = &_characters[charIndex];
+
+	if (a != 5) {
+		if (checkUnkConstModifiers(c, _charClassModUnk[c->cClass], c->level[0], a, c->raceSex))
+			s = recalcDamageModifier(damageType, s);
+	}
+
+	if ((flg & 0x110) == 0x110) {
+		if (!calcDamageCheckItemType(_items[itemOrPips].type))
+			s = 1;
+	}
+
+	if (flg & 4) {
+		if (checkInventoryForRings(charIndex, 3))
+			s = 0;
+	}
+
+	if (flg & 0x400) {
+		if (c->effectFlags & 0x2000)
+			s = 0;
+		else
+			_txt->printMessage(_characterStatusStrings8[0], -1, c->name);
+	}
+
+	return s;
+}
+
+void EobCoreEngine::inflictCharacterDamage(int charIndex, int damage) {
+	EobCharacter *c = &_characters[charIndex];
+	if (!testCharacter(charIndex, 3))
+		return;
+
+	if (c->effectsRemainder[3])
+		c->effectsRemainder[3] = (damage < c->effectsRemainder[3]) ? (c->effectsRemainder[3] - damage) : 0;
+
+	c->hitPointsCur -= damage;
+	c->damageTaken = damage;
+
+	if (c->hitPointsCur > -10) {
+		snd_playSoundEffect(21);
+	} else {
+		c->hitPointsCur = -10;
+		c->flags &= 1;
+		c->food = 0;
+		removeAllCharacterEffects(charIndex);
+		snd_playSoundEffect(22);
+	}
+
+	if (c->effectsRemainder[0]) {
+		c->effectsRemainder[0] = (damage < c->effectsRemainder[0]) ? (c->effectsRemainder[0] - damage) : 0;
+		if (!c->effectsRemainder[0])
+			removeCharacterEffect(1, charIndex, 1);
+	}
+
+	if (_currentControlMode)
+		gui_drawFaceShape(charIndex);
+	else
+		gui_drawCharPortraitWithStats(charIndex);
+
+	if (c->hitPointsCur <= 0 && _updateFlags == 1 && charIndex == _openBookChar) {
+		Button b;
+		clickedSpellbookAbort(&b);
+	}
+
+	setCharEventTimer(charIndex, 18, 6, 1);
+}
+
+bool EobCoreEngine::characterAttackHitTest(int charIndex, int monsterIndex, int item, int attackType) {
+	if (charIndex < 0)
+		return true;
+
+	int p = item ? (_flags.gameID == GI_EOB1 ? _items[item].type : (_itemTypes[_items[item].type].extraProperties & 0x7f)) : 0;
+
+	if (_monsters[monsterIndex].flags & 0x20)
+		return true;// EOB 2 only ?
+
+	int t = _monsters[monsterIndex].type;
+	int d = (p < 1 || p > 3) ? 0 : _items[item].value;
+
+	if (_flags.gameID == GI_EOB2) {
+		if ((p > 0 && p < 4) || !item ){
+			if (((_monsterProps[t].statusFlags & 0x200) && (d <= 0)) || ((_monsterProps[t].statusFlags & 0x1000) && (d <= 1)))
+				return false;
+		}
+	}
+
+	d += (attackType ? getStrHitChanceModifier(charIndex) : getDexHitChanceModifier(charIndex));
+
+	int m = getMonsterAcHitChanceModifier(charIndex, _monsterProps[t].armorClass) - d;
+	int s = rollDice(1, 20);
+
+	_monsters[monsterIndex].flags |= 1;
+
+	if (_flags.gameID == GI_EOB1) {
+		if (_partyEffectFlags & 0x30)
+			s++;
+		if (_characters[charIndex].effectFlags & 0x40)
+			s++;
+	} else if ((_partyEffectFlags & 0x8400) || (_characters[charIndex].effectFlags & 0x1000)) {
+		s++;
+	}
+
+	s = CLIP(s, 1, 20);
+
+	return s < m ? false : true;
+}
+
+bool EobCoreEngine::monsterAttackHitTest(EobMonsterInPlay *m, int charIndex) {
+	int tp = m->type;
+	EobMonsterProperty *p = &_monsterProps[tp];
+
+	int r = rollDice(1, 20);
+	if (r != 20) {
+		if (_characters[charIndex].effectFlags & 0x800)
+			r -= 2;
+		if (_characters[charIndex].effectFlags & 0x10)
+			r -= 2;
+		if (_partyEffectFlags & 0x8000)
+			r--;
+	}
+
+	return ((r == 20) || (r >= (p->hitChance - _characters[charIndex].armorClass)));
+}
+
+bool EobCoreEngine::flyingObjectMonsterHit(EobFlyingObject *fo, int monsterIndex) {
+	if (fo->attackerId != -1) {
+		if (!characterAttackHitTest(fo->attackerId, monsterIndex, fo->item, 0))
+			return false;
+	}
+	calcAndInflictMonsterDamage(&_monsters[monsterIndex], fo->attackerId, fo->item, 0, (fo->attackerId == -1) ? 0x110: 0x910, 5, 3);
+	return true;
+}
+
+bool EobCoreEngine::flyingObjectPartyHit(EobFlyingObject *fo) {
+	int ps = _dscItemPosIndex[(_currentDirection << 2) + (_items[fo->item].pos & 3)];
+	bool res = false;
+
+	bool b = ((_currentDirection == fo->direction || _currentDirection == (fo->direction ^ 2)) && ps > 2);
+	int s = ps << 1;
+	if (ps > 2)
+		s += rollDice(1, 2, -1);
+
+	static const int8 charId[] = { 0, -1, 1, -1, 2, 4, 3, 5 };
+
+	for (int i = 0; i < 2; i++) {
+		int c = charId[s];
+		s ^= 1;
+		if (!testCharacter(c, 3))
+			continue;
+		calcAndInflictCharacterDamage(c, -1, fo->item, 0, 0x110, 5, 3);
+		res = true;
+		if (ps < 2 || b == 0)
+			break;
+	}
+
+	return res;
+}
+
+void EobCoreEngine::monsterCloseAttack(EobMonsterInPlay *m) {
+	int first = _monsterCloseAttDstTable1[(_currentDirection << 2) + m->dir] * 12;
+	int v = (m->pos == 4) ? rollDice(1, 2, -1) : _monsterCloseAttChkTable2[(m->dir << 2) + m->pos];
+	if (!v)
+		first += 6;
+
+	int last = first + 6;
+	for (int i = first; i < last; i++) {
+		int c = _monsterCloseAttDstTable2[i];
+		if (!testCharacter(c, 3))
+			continue;
+
+		// Character Invisibility
+		if ((_characters[c].effectFlags & 0x140) && (rollDice(1, 20) >= 5))
+			continue;
+
+		int dmg = 0;
+		for (int ii = 0; ii < _monsterProps[m->type].attacksPerRound; ii++) {
+			if (!monsterAttackHitTest(m, c))
+				continue;
+			dmg += rollDice(_monsterProps[m->type].dmgDc[ii].times, _monsterProps[m->type].dmgDc[ii].pips, _monsterProps[m->type].dmgDc[ii].base);
+		}
+
+		if (dmg > 0) {
+			if ((_monsterProps[m->type].flags & 0x80) && rollDice(1, 4, -1) != 3) {
+				int slot = rollDice(1, 27, -1);
+				for (int iii = 0; iii < 27; iii++) {
+					Item itm = _characters[c].inventory[slot];
+					if (!itm || !(_itemTypes[_items[itm].type].extraProperties & 0x80)) {
+						if (++slot == 27)
+							slot = 0;
+						continue;
+					}
+
+					_characters[c].inventory[slot] = 0;
+					_txt->printMessage(_itemExtraStrings[(_characters[c].raceSex & 1) ^ 1], -1, _characters[c].name);
+					printFullItemName(itm);
+					_txt->printMessage(_itemExtraStrings[2]);
+				}
+				gui_drawCharPortraitWithStats(c);
+			}
+
+			inflictCharacterDamage(c, dmg);
+
+			if (_monsterProps[m->type].flags & 0x10) {
+				statusAttack(c, 2, _monsterSpecAttStrings[_flags.gameID == GI_EOB1 ? 3 : 2], 0, 1, 8, 1);
+				_characters[c].effectFlags &= ~0x2000;
+			}
+
+			if (_monsterProps[m->type].flags & 0x20)
+				statusAttack(c, 4, _monsterSpecAttStrings[_flags.gameID == GI_EOB1 ? 4 : 3], 2, 5, 9, 1);
+
+			if (_monsterProps[m->type].flags & 0x8000)
+				statusAttack(c, 8, _monsterSpecAttStrings[4], 2, 0, 0, 1);
+
+		}
+
+		if (!(_monsterProps[m->type].flags & 0x4000))
+			return;
+	}
+}
+
+void EobCoreEngine::monsterSpellCast(EobMonsterInPlay *m, int type) {
+	launchMagicObject(-1, type, m->block, m->pos, m->dir);
+	snd_processEnvironmentalSoundEffect(_spells[_magicFlightObjectProperties[type << 2]].sound, m->block);
+}
+
+void EobCoreEngine::statusAttack(int charIndex, int attackStatusFlags, const char *attackStatusString, int a, uint32 effectDuration, int restoreEvent, int noRefresh) {
+	EobCharacter *c = &_characters[charIndex];
+	if ((c->flags & attackStatusFlags) && noRefresh)
+		return;
+	if (!testCharacter(charIndex, 3))
+		return;
+
+	if (a != 5 && specialAttackConstTest(charIndex, a))
+		return;
+
+	if (attackStatusFlags & 8) {
+		removeAllCharacterEffects(charIndex);
+		c->flags = (c->flags & 1) | 8;
+	} else {
+		c->flags |= attackStatusFlags;
+	}
+
+	if ((attackStatusFlags & 0x0c) && (_openBookChar == charIndex) && _updateFlags) {
+		Button b;
+		clickedSpellbookAbort(&b);
+	}
+
+	if (effectDuration)
+		setCharEventTimer(charIndex, effectDuration * 546, restoreEvent, 1);
+
+	gui_drawCharPortraitWithStats(charIndex);
+	_txt->printMessage(_characterStatusStrings13[0], -1, c->name, attackStatusString);
+}
+
+int EobCoreEngine::calcCloseDistanceMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int b, int damageType) {
+	int s = flags & 0x100 ? calcDamageModifers(times, m, pips, _items[pips].type, offs) : rollDice(times, pips, offs);
+	EobMonsterProperty *p = &_monsterProps[m->type];
+
+	if (b == 5) {
+		if (checkUnkConstModifiers(m, 0, p->level, b, 6))
+			s = recalcDamageModifier(damageType, s);
+	}
+
+	if ((flags & 0x110) == 0x110) {
+		if (!calcDamageCheckItemType(_items[pips].type))
+			s = 1;
+	}
+
+	if ((flags & 0x100) && ((_flags.gameID == GI_EOB2 && (p->statusFlags & 0x100)) || (_flags.gameID == GI_EOB1 && (p->flags & 4))) && (!(_itemTypes[_items[pips].type].allowedClasses & 4 /* bug in original code ??*/)))
+		s >>= 1;
+
+	if (p->statusFlags & 0x2000) {
+		if (flags & 0x100) {
+			if (_items[pips].value < 3)
+				s >>= 2;
+			if (_items[pips].value == 3)
+				s >>= 1;
+			if (s == 0)
+				s = _items[pips].value;
+
+		} else {
+			s >>= 1;
+		}
+	}
+
+	if (flags & 1) {
+		if (checkMonsterDamageEvasion(m))
+			s = 0;
+	}
+
+	if (_flags.gameID == GI_EOB1)
+		return s;
+
+	static const uint16 damageImmunityFlags[] = { 0x01, 0x10, 0x02, 0x20, 0x80, 0x400, 0x20, 0x800, 0x40, 0x80, 0x400, 0x40 };
+	for (int i = 0; i < 12; i += 2) {
+		if ((flags & damageImmunityFlags[i]) && (p->statusFlags & damageImmunityFlags[i + 1]))
+			s = 0;
+	}
+
+	return s;
+}
+
+int EobCoreEngine::calcDamageModifers(int charIndex, EobMonsterInPlay *m, int item, int itemType, int useStrModifier) {
+	int s = (useStrModifier && (charIndex != -1)) ? getStrDamageModifier(charIndex) : 0;
+	if (item) {
+		EobItemType *p = &_itemTypes[itemType];
+		int t = m ? m->type : 0;
+		s += ((m && (_monsterProps[t].flags & 1)) ?	rollDice(p->dmgNumDiceL, p->dmgNumPipsL, p->dmgIncS /* bug in original code ? */) :
+			rollDice(p->dmgNumDiceS, p->dmgNumPipsS, p->dmgIncS));
+		s += _items[item].value;
+	} else {
+		s += rollDice(1, 2);
+	}
+
+	return (s < 0) ? 0 : s;
+}
+
+bool EobCoreEngine::checkUnkConstModifiers(void *target, int hpModifier, int level, int b, int race) {
+	static const int8 constMod[] = { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5 };
+
+	if (b == 5)
+		return false;
+
+	int s = getConstModifierTableValue(hpModifier, level, b);
+	if (((race == 3 || race == 5) && (b == 4 || b == 1 || b == 0)) || (race == 4 && (b == 4 || b == 1))) {
+		EobCharacter *c = (EobCharacter*)target;
+		s -= constMod[c->constitutionCur];
+	}
+
+	return rollDice(1, 20) < s ? false : true;
+}
+
+bool EobCoreEngine::specialAttackConstTest(int charIndex, int b) {
+	return checkUnkConstModifiers(&_characters[charIndex], _charClassModUnk[_characters[charIndex].cClass], _characters[charIndex].level[0], b, _characters[charIndex].raceSex >> 1);
+}
+
+int EobCoreEngine::getConstModifierTableValue(int hpModifier, int level, int b) {
+	const uint8 *tbl = _constModTables[hpModifier];
+	if (_constModLevelIndex[hpModifier] < level)
+		level = _constModLevelIndex[hpModifier];
+	level /= _constModDiv[hpModifier];
+	level += (_constModExt[hpModifier] * b);
+
+	return tbl[level];
+}
+
+bool EobCoreEngine::calcDamageCheckItemType(int itemType) {
+	itemType = _itemTypes[itemType].extraProperties & 0x7f;
+	return (itemType == 2 || itemType == 3) ? true : false;
+}
+
+int EobCoreEngine::recalcDamageModifier(int damageType, int dmgModifier) {
+	if (damageType == 3)
+		return 0;
+
+	if (damageType == 0 || damageType == 1)
+		return dmgModifier >> 1;
+
+	return dmgModifier;
+}
+
+bool EobCoreEngine::checkMonsterDamageEvasion(EobMonsterInPlay *m) {
+	return rollDice(1, 100) < _monsterProps[m->type].dmgModifierEvade ? true : false;
+}
+
+int EobCoreEngine::getStrHitChanceModifier(int charIndex) {
+	static const int8 strExtLimit[] = { 1, 51, 76, 91, 100 };
+	static const int8 strExtMod[] = { 1, 2, 2, 2, 3 };
+	static const int8 strMod[] = { -4, -3, -3, -2, -2, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 3, 3, 4, 4, 5, 6, 7 };
+
+	int r = strMod[_characters[charIndex].strengthCur - 1];
+	if (_characters[charIndex].strengthExtCur) {
+		for (int i = 0; i < 5; i++) {
+			if (_characters[charIndex].strengthExtCur >= strExtLimit[i])
+				r = strExtMod[i];
+		}
+	}
+
+	return r;
+}
+
+int EobCoreEngine::getStrDamageModifier(int charIndex) {
+	static const int8 strExtLimit[] = { 1, 51, 76, 91, 100 };
+	static const int8 strExtMod[] = { 3, 3, 4, 5, 6 };
+	static const int8 strMod[] = { -3, -2, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 7, 8, 9, 10, 11, 12, 14 };
+
+	int r = strMod[_characters[charIndex].strengthCur - 1];
+	if (_characters[charIndex].strengthExtCur) {
+		for (int i = 0; i < 5; i++) {
+			if (_characters[charIndex].strengthExtCur >= strExtLimit[i])
+				r = strExtMod[i];
+		}
+	}
+
+	return r;
+}
+
+int EobCoreEngine::getDexHitChanceModifier(int charIndex) {
+	static const int8 dexMod[] = { -5, -4, -3, -2, -1, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 3, 4, 4, 4 };
+	return dexMod[_characters[charIndex].dexterityCur - 1];
+}
+
+int EobCoreEngine::getMonsterAcHitChanceModifier(int charIndex, int monsterAc) {
+	static const uint8 mod1[] = { 1, 3, 3, 2 };
+	static const uint8 mod2[] = { 1, 1, 2, 1 };
+
+	int l = _characters[charIndex].level[0] - 1;
+	int cm = _charClassModUnk[_characters[charIndex].cClass];
+
+	return (20 - ((l / mod1[cm]) * mod2[cm])) - monsterAc;
+}
+
+void EobCoreEngine::inflictMonsterDamage_s1(EobMonsterInPlay *m) {
+
+}
+
+void EobCoreEngine::snd_playSoundEffect(int id, int volume) {
+	if (id < 1 || id > 119 || shouldQuit())
+		return;
+
+	_sound->playSoundEffect(id, volume);
+}
+
+}	// End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
new file mode 100644
index 0000000..201c1df
--- /dev/null
+++ b/engines/kyra/eobcommon.h
@@ -0,0 +1,977 @@
+/* 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.
+ *
+ */
+
+#ifndef KYRA_EOBCOMMON_H
+#define KYRA_EOBCOMMON_H
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+#include "kyra/loleobbase.h"
+#endif // (ENABLE_EOB || ENABLE_LOL)
+
+#ifdef ENABLE_EOB
+
+namespace Kyra {
+
+struct EobShapeDef {
+	int16 index;
+	uint8 x, y, w, h;
+};
+
+struct CreatePartyModButton {
+	uint8 encodeLabelX;
+	uint8 encodeLabelY;
+	uint8 labelW;
+	uint8 labelH;
+	uint8 labelX;
+	uint8 labelY;
+	uint8 bodyIndex;
+	uint8 destX;
+	uint8 destY;
+};
+
+struct EobRect8 {
+	uint8 x;
+	uint8 y;
+	uint8 w;
+	uint8 h;
+};
+
+struct EobRect16 {
+	int16 x1;
+	int16 y1;
+	uint16 x2;
+	uint16 y2;
+};
+
+struct EobChargenButtonDef {
+	uint8 x;
+	uint8 y;
+	uint8 w;
+	uint8 h;
+	uint8 keyCode;
+};
+
+struct EobGuiButtonDef {
+	uint8 keyCode;
+	uint8 keyCode2;
+	uint16 flags;
+	uint16 x;
+	uint8 y;
+	uint16 w;
+	uint8 h;
+	Button::Callback buttonCallback;
+	uint16 arg;
+};
+
+struct EobCharacter {
+	uint8 id;
+	uint8 flags;
+	char name[11];
+	int8 strengthCur;
+	int8 strengthMax;
+	int8 strengthExtCur;
+	int8 strengthExtMax;
+	int8 intelligenceCur;
+	int8 intelligenceMax;
+	int8 wisdomCur;
+	int8 wisdomMax;
+	int8 dexterityCur;
+	int8 dexterityMax;
+	int8 constitutionCur;
+	int8 constitutionMax;
+	int8 charismaCur;
+	int8 charismaMax;
+	int16 hitPointsCur;
+	int16 hitPointsMax;
+	int8 armorClass;
+	uint8 disabledSlots;
+	uint8 raceSex;
+	uint8 cClass;
+	uint8 alignment;
+	int8 portrait;
+	uint8 food;
+	uint8 level[3];
+	uint32 experience[3];
+	uint8 *faceShape;
+
+	int8 mageSpells[80];
+	int8 clericSpells[80];
+	uint32 mageSpellsAvailabilityFlags;
+
+	Item inventory[27];
+	uint32 timers[10];
+	int8 events[10];
+	uint8 effectsRemainder[4];
+	uint32 effectFlags;
+	uint8 damageTaken;
+	int8 slotStatus[5];
+};
+
+struct EobItem {
+	uint8 nameUnid;
+	uint8 nameId;
+	uint8 flags;
+	int8 icon;
+	int8 type;
+	int8 pos;
+	int16 block;
+	Item next;
+	Item prev;
+	uint8 level;
+	int8 value;
+};
+
+struct EobItemType {
+	uint16 invFlags;
+	uint16 handFlags;
+	int8 armorClass;
+	int8 allowedClasses;
+	int8 requiredHands;
+	int8 dmgNumDiceS;
+	int8 dmgNumPipsS;
+	int8 dmgIncS;
+	int8 dmgNumDiceL;
+	int8 dmgNumPipsL;
+	int8 dmgIncL;
+	uint8 unk1;
+	uint16 extraProperties;
+};
+
+struct SpriteDecoration {
+	uint8 *shp;
+	uint8 x;
+	uint8 y;
+};
+
+struct EobMonsterProperty {
+	int8 armorClass;
+	int8 hitChance;
+	uint8 level;
+	uint8 hpDcTimes;
+	uint8 hpDcPips;
+	uint8 hpDcBase;
+	uint8 attacksPerRound;
+	struct DmgDc {
+		uint8 times;
+		uint8 pips;
+		int8 base;
+	} dmgDc[3];
+	uint16 statusFlags;
+	uint16 flags;
+	int32 u22;
+	int32 experience;
+
+	uint8 u30;
+	uint8 sound1;
+	uint8 sound2;
+	uint8 numRemoteAttacks;
+	uint8 remoteWeaponChangeMode;
+	uint8 numRemoteWeapons;
+
+	int8 remoteWeapons[5];
+
+	uint8 u41;
+	uint8 dmgModifierEvade;
+
+	uint8 decorations[3];
+};
+
+struct EobMonsterInPlay {
+	uint8 type;
+	uint8 unit;
+	uint16 block;
+	uint8 pos;
+	int8 dir;
+	uint8 animStep;
+	uint8 shpIndex;
+	int8 mode;
+	int8 f_9;
+	int8 curAttackFrame;
+	uint8 f_b;
+	int16 hitPointsMax;
+	int16 hitPointsCur;
+	uint16 dest;
+	uint16 randItem;
+	uint16 fixedItem;
+	uint8 flags;
+	uint8 idleAnimState;
+	uint8 curRemoteWeapon;
+	uint8 numRemoteAttacks;
+	int8 palette;
+	uint8 directionChanged;
+	uint8 stepsTillRemoteAttack;
+	uint8 sub;
+};
+
+struct ScriptTimer {
+	uint16 func;
+	uint16 ticks;
+	uint32 next;
+};
+
+struct EobFlyingObject {
+	uint8 enable;
+	uint8 objectType;
+	int16 attackerId;
+	Item item;
+	uint16 curBlock;
+	uint16 u2;
+	uint8 u1;
+	uint8 direction;
+	uint8 distance;
+	int8 callBackIndex;
+	uint8 curPos;
+	uint8 flags;
+	uint8 unused;
+};
+
+class EobInfProcessor;
+
+class EobCoreEngine : public LolEobBaseEngine {
+friend class TextDisplayer_Eob;
+friend class GUI_Eob;
+friend class EobInfProcessor;
+friend class DarkmoonSequenceHelper;
+friend class CharacterGenerator;
+public:
+	EobCoreEngine(OSystem *system, const GameFlags &flags);
+	virtual ~EobCoreEngine();
+
+	Screen *screen() { return _screen; }
+	GUI *gui() const { return _gui; }
+
+protected:
+	// Startup
+	virtual Common::Error init();
+	Common::Error go();
+
+	// Main Menu, Intro, Finale
+	virtual int mainMenu() = 0;
+	virtual void seq_playFinale() = 0;
+	bool _playFinale;
+
+	//Init
+	void loadItemsAndDecorationsShapes();
+	void releaseItemsAndDecorationsShapes();
+
+	void initButtonData();
+	void initStaticResource();
+	virtual void initSpells();
+
+	const uint8 **_largeItemShapes;
+	const uint8 **_smallItemShapes;
+	const uint8 **_thrownItemShapes;
+	const int _numLargeItemShapes;
+	const int _numSmallItemShapes;
+	const int _numThrownItemShapes;
+	const int _numItemIconShapes;
+
+	const uint8 **_spellShapes;
+	const uint8 **_firebeamShapes;
+	const uint8 *_redSplatShape;
+	const uint8 *_greenSplatShape;
+	const uint8 **_wallOfForceShapes;
+	const uint8 **_teleporterShapes;
+	const uint8 **_sparkShapes;
+	const uint8 *_deadCharShape;
+	const uint8 *_disabledCharGrid;
+	const uint8 *_blackBoxSmallGrid;
+	const uint8 *_weaponSlotGrid;
+	const uint8 *_blackBoxWideGrid;
+	const uint8 *_lightningColumnShape;
+
+	uint8 *_tempIconShape;
+	uint8 *_itemsOverlay;
+
+	static const uint8 _teleporterShapeDefs[];
+	static const uint8 _wallOfForceShapeDefs[];
+
+	const char *const *_mainMenuStrings;
+
+	// Main loop
+	virtual void startupNew() = 0;
+	virtual void startupLoad() = 0;
+	void runLoop();
+	void update() { screen()->updateScreen(); }
+	bool updateCharacterEvents(bool a);
+
+	bool _runFlag;
+	//int _runLoopUnk2;
+
+	// Create Party
+	void startCharacterGeneration();
+
+	uint8 **_faceShapes;
+
+	static const int8 _classHpIncreaseType[];
+	static const uint8 _hpIncrPerLevel[];
+	static const uint8 _numLevelsPerClass[];
+	static const int16 _hpConstModifiers[];
+	static const uint8 _charClassModUnk[];
+
+	const uint8 *_classModifierFlags;
+
+	// timers
+	void setupTimers();
+	void setCharEventTimer(int charIndex, uint32 countdown, int evnt, int updateExistingTimer);
+	void deleteCharEventTimer(int charIndex, int evnt);
+	void setupCharacterTimers();
+
+	void timerProcessMonsters(int timerNum);
+	void timerSpecialCharacterUpdate(int timerNum);
+	void timerProcessFlyingObjects(int timerNum);
+	void timerProcessCharacterExchange(int timerNum);
+	void timerUpdateTeleporters(int timerNum);
+	void timerUpdateFoodStatus(int timerNum);
+	void timerUpdateMonsterIdleAnim(int timerNum);
+
+	uint8 getClock2Timer(int index) { return index < _numClock2Timers ? _clock2Timers[index] : 0; }
+	uint8 getNumClock2Timers()  { return _numClock2Timers; }
+
+	static const uint8 _clock2Timers[];
+	static const uint8 _numClock2Timers;
+
+	// Mouse
+	void setHandItem(Item itemIndex);
+	void updateHandItemCursor() { _updateHandItemCursor = true; }
+	bool _updateHandItemCursor;
+
+	// Characters
+	int getDexterityArmorClassModifier(int dexterity);
+	int generateCharacterHitpointsByLevel(int charIndex, int levelIndex);
+	int getClassAndConstHitpointsModifier(int cclass, int constitution);
+	int getClassHpIncreaseType(int cclass, int levelIndex);
+	int getModifiedHpLimits(int hpModifier, int constModifier, int level, bool mode);
+	const char *getCharStrength(int str, int strExt);
+	int testCharacter(int index, int flags);
+	int getNextValidCharIndex(int curCharIndex, int searchStep);
+
+	void recalcArmorClass(int index);
+	int validateWeaponSlotItem(int index, int slot);
+	int getCharacterClericPaladinLevel(int index);
+	int getCharacterMageLevel(int index);
+	int getLevelIndexForHpIncType(int unk, int cClass);
+
+	int countCharactersWithSpecificItems(int16 itemType, int16 itemValue);
+	int checkCharacterInventoryForItem(int character, int16 itemType, int16 itemValue);
+	void modifyCharacterHitpoints(int character, int16 points);
+	void neutralizePoison(int character);
+
+	virtual void npcSequence(int npcIndex) = 0;
+	void initNpc(int npcIndex);
+	int npcJoinDialogue(int npcIndex, int queryJoinTextId, int confirmJoinTextId, int noJoinTextId);
+	int prepareForNewPartyMember(int16 itemType, int16 itemValue);
+	void removeCharacterFromParty(int charIndex);
+
+	void increasePartyExperience(int16 points);
+	void increaseCharacterExperience(int charIndex, int32 points);
+	uint32 getRequiredExperience(int cClass, int levelIndex, int level);
+	void increaseCharacterLevel(int charIndex, int levelIndex);
+
+	void setWeaponSlotStatus(int charIndex, int mode, int slot);
+
+	EobCharacter *_characters;
+	char _strenghtStr[6];
+	int _castScrollSlot;
+	int _exchangeCharacterId;
+
+	const char *const *_levelGainStrings;
+	const uint32 *_expRequirementTables[6];
+
+	const uint8 *_constModTables[6];
+	const uint8 *_constModLevelIndex;
+	const uint8 *_constModDiv;
+	const uint8 *_constModExt;
+
+	const EobCharacter *_npcPreset;
+	bool _partyResting;
+
+	// Items
+	void loadItemDefs();
+	Item duplicateItem(Item itemIndex);
+	void setItemPosition(Item *itemQueue, int block, Item item, int pos);
+	void createInventoryItem(EobCharacter *c, Item itemIndex, int itemValue, int preferedInventorySlot);
+	int deleteInventoryItem(int charIndex, int slot);
+	void deleteBlockItem(uint16 block, int type);
+	int validateInventorySlotForItem(Item item, int charIndex, int slot);
+	void deletePartyItem(Item itemType, int16 itemValue);
+	virtual void updateUsedCharacterHandItem(int charIndex, int slot) = 0;
+	int itemUsableByCharacter(int charIndex, Item item);
+	int countQueuedItems(Item itemQueue, int16 id, int16 type, int count, int includeFlyingItems);
+	int getQueuedItem(Item *items, int pos, int id);
+	void printFullItemName(Item item);
+	void identifyQueuedItems(Item itemQueue);
+	void drawItemIconShape(int pageNum, Item itemId, int x, int y);
+	bool isMagicWeapon(Item itemIndex);
+	bool checkInventoryForRings(int charIndex, int itemValue);
+	void eatItemInHand(int charIndex);
+
+	bool launchObject(int charIndex, Item item, uint16 startBlock, int startPos, int dir, int type);
+	void launchMagicObject(int charIndex, int type, uint16 startBlock, int startPos, int dir);
+	bool updateObjectFlight(EobFlyingObject *fo, int block, int pos);
+	bool updateFlyingObjectHitTest(EobFlyingObject *fo, int block, int pos);
+	void updateFlyingObject_s3(EobFlyingObject *fo);
+	void endObjectFlight(EobFlyingObject *fo);
+	void checkFlyingObjects();
+
+	void reloadWeaponSlot(int charIndex, int slotIndex, int itemType, int arrowOrDagger);
+
+	EobItem *_items;
+	uint16 _numItems;
+	EobItemType *_itemTypes;
+	char **_itemNames;
+	uint16 _numItemNames;
+	uint32 _partyEffectFlags;
+	Item _lastUsedItem;
+
+	const uint16 *_slotValidationFlags;
+
+	EobFlyingObject *_flyingObjects;
+	const uint8 *_drawObjPosIndex;
+	const uint8 *_flightObjFlipIndex;
+	const int8 *_flightObjShpMap;
+	const int8 *_flightObjSclIndex;
+
+	// Monsters
+	void loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex);
+	void releaseMonsterShapes(int first, int num);
+	virtual void generateMonsterPalettes(const char *file, int16 monsterIndex) {}
+	virtual void loadMonsterDecoration(const char *file, int16 monsterIndex) {}
+	const uint8 *loadMonsterProperties(const uint8 *data);
+	const uint8 *loadActiveMonsterData(const uint8 *data, int level);
+	void initMonster(int index, int unit, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int i, int randItem, int fixedItem);
+	void placeMonster(EobMonsterInPlay *m, uint16 block, int dir);
+	virtual void replaceMonster(int b, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem) = 0;
+	void killMonster(EobMonsterInPlay *m, bool giveExperience);
+	int countSpecificMonsters(int type);
+	void updateAttackingMonsterFlags();
+
+	const int8 *getMonsterBlockPositions(uint16 block);
+	int getClosestMonsterPos(int charIndex, int block);
+
+	bool blockHasMonsters(uint16 block);
+	bool isMonsterOnPos(EobMonsterInPlay *m, uint16 block, int pos, int checkPos4);
+	const int16 *findBlockMonsters(uint16 block, int pos, int dir, int blockDamage, int singleTargetCheckAdjacent);
+
+	void drawBlockObject(int flipped, int page, const uint8 *shape, int x, int y, int sd, uint8 *ovl = 0);
+	void drawMonsterShape(const uint8 *shape, int x, int y, int flipped, int flags, int palIndex);
+	void flashMonsterShape(EobMonsterInPlay *m);
+	void updateAllMonsterShapes();
+	void drawBlockItems(int index);
+	void drawDoor(int index);
+	virtual void drawDoorIntern(int type, int index, int x, int y, int w, int wall, int mDim, int16 y1, int16 y2) = 0;
+	void drawMonsters(int index);
+	void drawWallOfForce(int index);
+	void drawFlyingObjects(int index);
+	void drawTeleporter(int index);
+
+	void updateMonsters(int unit);
+	void updateMonsterDest(EobMonsterInPlay *m);
+	void updateMonsterDest2(EobMonsterInPlay *m);
+	void turnFriendlyMonstersHostile();
+	int getNextMonsterDirection(int curBlock, int destBlock);
+	int getNextMonsterPos(EobMonsterInPlay *m, int block);
+	int findFreeMonsterPos(int block, int size);
+	void updateMoveMonster(EobMonsterInPlay *m);
+	bool updateMonsterTryDistanceAttack(EobMonsterInPlay *m);
+	bool updateMonsterTryCloseAttack(EobMonsterInPlay *m, int block);
+	void walkMonster(EobMonsterInPlay *m, int destBlock);
+	bool walkMonsterNextStep(EobMonsterInPlay *m, int destBlock, int direction);
+	void updateMonsterFollowPath(EobMonsterInPlay *m, int turnSteps);
+	void updateMonstersStraying(EobMonsterInPlay *m, int a);
+	void updateMonsters_mode710(EobMonsterInPlay *m);
+	void setBlockMonsterDirection(int block, int dir);
+
+	uint8 *_monsterOvl1;
+	uint8 *_monsterOvl2;
+
+	SpriteDecoration *_monsterDecorations;
+	EobMonsterProperty *_monsterProps;
+
+	EobMonsterInPlay *_monsters;
+
+	const int8 *_monsterStepTable0;
+	const int8 *_monsterStepTable1;
+	const int8 *_monsterStepTable2;
+	const int8 *_monsterStepTable3;
+	const uint8 *_monsterCloseAttPosTable1;
+	const uint8 *_monsterCloseAttPosTable2;
+	const int8 *_monsterCloseAttUnkTable;
+	const uint8 *_monsterCloseAttChkTable1;
+	const uint8 *_monsterCloseAttChkTable2;
+	const uint8 *_monsterCloseAttDstTable1;
+	const uint8 *_monsterCloseAttDstTable2;
+
+	const uint8 *_monsterProximityTable;
+	const uint8 *_findBlockMonstersTable;
+	const char *const *_monsterDustStrings;
+
+	const uint8 *_monsterDistAttType10;
+	const uint8 *_monsterDistAttSfx10;
+	const uint8 *_monsterDistAttType17;
+	const uint8 *_monsterDistAttSfx17;
+	const char *const *_monsterSpecAttStrings;
+
+	const int8 *_monsterFrmOffsTable1;
+	const int8 *_monsterFrmOffsTable2;
+
+	const uint16 *_encodeMonsterShpTable;
+	const uint8 _teleporterWallId;
+
+	const int8 *_monsterDirChangeTable;
+
+	// Level
+	void loadLevel(int level, int func);
+	const char *initLevelData(int func);
+	void addLevelItems();
+	void loadVcnData(const char *file, const char */*nextFile*/);
+	void loadBlockProperties(const char *mazFile);
+	void loadDecorations(const char *cpsFile, const char *decFile);
+	void assignWallsAndDecorations(int wallIndex, int vmpIndex, int decDataIndex, int specialType, int flags);
+	void releaseDecorations();
+	void releaseDoorShapes();
+	void toggleWallState(int wall, int flags);
+	virtual void loadDoorShapes(int doorType1, int shapeId1, int doorType2, int shapeId2) {}
+	virtual const uint8 *loadDoorShapes(const char *filename, int doorIndex, const uint8*shapeDefs) { return (const uint8*)filename; }
+
+	void drawScene(int update);
+	void drawSceneShapes();
+	void drawDecorations(int index);
+
+	int calcNewBlockPositionAndTestPassability(uint16 curBlock, uint16 direction);
+	void notifyBlockNotPassable();
+	void moveParty(uint16 block);
+
+	int clickedDoorSwitch(uint16 block, uint16 direction);
+	int clickedDoorPry(uint16 block, uint16 direction);
+	int clickedDoorNoPry(uint16 block, uint16 direction);
+	int clickedNiche(uint16 block, uint16 direction);
+
+	int specialWallAction(int block, int direction);
+
+	void openDoor(int block);
+	void closeDoor(int block);
+
+	int16 _doorType[2];
+	int16 _noDoorSwitch[2];
+
+	EobRect8 *_levelDecorationRects;
+	SpriteDecoration *_doorSwitches;
+
+	int8 _currentSub;
+	char _curGfxFile[13];
+
+	uint32 _drawSceneTimer;
+	uint32 _flashShapeTimer;
+	uint32 _envAudioTimer;
+	uint16 _teleporterPulse;
+
+	const int16 *_dscShapeCoords;
+
+	const uint8 *_dscItemPosIndex;
+	const int16 *_dscItemShpX;
+	const uint8 *_dscItemScaleIndex;
+	const uint8 *_dscItemTileIndex;
+	const uint8 *_dscItemShapeMap;
+
+	const uint8 *_dscDoorScaleOffs;
+	const uint8 *_dscDoorScaleMult1;
+	const uint8 *_dscDoorScaleMult2;
+	const uint8 *_dscDoorScaleMult3;
+	const uint8 *_dscDoorY1;
+
+	const uint8 *_wllFlagPreset;
+	int _wllFlagPresetSize;
+	const uint8 *_teleporterShapeCoords;
+
+	// Script
+	void runLevelScript(int block, int flags);
+	void setScriptFlag(int flag);
+	bool checkScriptFlag(int flag);
+
+	const uint8 *initScriptTimers(const uint8 *pos);
+	void updateScriptTimers();
+
+	EobInfProcessor *_inf;
+	int _stepCounter;
+	int _stepsUntilScriptCall;
+	ScriptTimer _scriptTimers[5];
+	int _scriptTimersCount;
+	uint8 _scriptTimersMode;
+
+	// Gui
+	void gui_drawPlayField(int pageNum);
+	void gui_restorePlayField();
+	void gui_drawAllCharPortraitsWithStats();
+	void gui_drawCharPortraitWithStats(int index);
+	void gui_drawFaceShape(int index);
+	void gui_drawWeaponSlot(int charIndex, int slot);
+	void gui_drawWeaponSlotStatus(int x, int y, int status);
+	void gui_drawHitpoints(int index);
+	void gui_drawFoodStatusGraph(int index);
+	void gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32 curVal, int32 maxVal, int col1, int col2);
+	void gui_drawCharPortraitStatusFrame(int index);
+	void gui_drawInventoryItem(int slot, int special, int pageNum);
+	void gui_drawCompass(bool force);
+	void gui_drawDialogueBox();
+	void gui_drawSpellbook();
+	void gui_drawSpellbookScrollArrow(int x, int y, int direction);
+	void gui_updateSlotAfterScrollUse();
+	void gui_updateControls();
+	void gui_toggleButtons();
+	void gui_setPlayFieldButtons();
+	void gui_setInventoryButtons();
+	void gui_setStatsListButtons();
+	void gui_setSwapCharacterButtons();
+	void gui_setCastOnWhomButtons();
+	void gui_initButton(int index, int x = -1, int y = -1, int val = -1);
+	Button *gui_getButton(Button *buttonList, int index);
+
+	int clickedInventoryNextPage(Button *button);
+	int clickedPortraitRestore(Button *button);
+	int clickedCharPortraitDefault(Button *button);
+	int clickedCamp(Button *button);
+	int clickedSceneDropPickupItem(Button *button);
+	int clickedCharPortrait2(Button *button);
+	int clickedWeaponSlot(Button *button);
+	int clickedCharNameLabelRight(Button *button);
+	int clickedInventorySlot(Button *button);
+	int clickedEatItem(Button *button);
+	int clickedInventoryPrevChar(Button *button);
+	int clickedInventoryNextChar(Button *button);
+	int clickedSpellbookTab(Button *button);
+	int clickedSpellbookList(Button *button);
+	int clickedCastSpellOnCharacter(Button *button);
+	int clickedUpArrow(Button *button);
+	int clickedDownArrow(Button *button);
+	int clickedLeftArrow(Button *button);
+	int clickedRightArrow(Button *button);
+	int clickedTurnLeftArrow(Button *button);
+	int clickedTurnRightArrow(Button *button);
+	int clickedAbortCharSwitch(Button *button);
+	int clickedSceneThrowItem(Button *button);
+	int clickedSceneSpecial(Button *button);
+	int clickedSpellbookAbort(Button *button);
+	int clickedSpellbookScroll(Button *button);
+	int clickedUnk(Button *button);
+
+	void gui_processCharPortraitClick(int index);
+	void gui_processWeaponSlotClickLeft(int charIndex, int slotIndex);
+	void gui_processWeaponSlotClickRight(int charIndex, int slotIndex);
+	void gui_processInventorySlotClick(int slot);
+
+	static const int16 _buttonList1[];
+	int _buttonList1Size;
+	static const int16 _buttonList2[];
+	int _buttonList2Size;
+	static const int16 _buttonList3[];
+	int _buttonList3Size;
+	static const int16 _buttonList4[];
+	int _buttonList4Size;
+	static const int16 _buttonList5[];
+	int _buttonList5Size;
+	static const int16 _buttonList6[];
+	int _buttonList6Size;
+	static const int16 _buttonList7[];
+	int _buttonList7Size;
+	static const int16 _buttonList8[];
+	int _buttonList8Size;
+
+	const EobGuiButtonDef *_buttonDefs;
+	const char *const *_characterGuiStringsHp;
+	const char *const *_characterGuiStringsWp;
+	const char *const *_characterGuiStringsWr;
+	const char *const *_characterGuiStringsSt;
+	const char *const *_characterGuiStringsIn;
+
+	const char *const *_characterStatusStrings7;
+	const char *const *_characterStatusStrings8;
+	const char *const *_characterStatusStrings9;
+	const char *const *_characterStatusStrings12;
+	const char *const *_characterStatusStrings13;
+
+	const uint16 *_inventorySlotsX;
+	const uint8 *_inventorySlotsY;
+	const uint8 **_compassShapes;
+	uint8 _charExchangeSwap;
+	bool _hpBarGraphs;
+
+	// text
+	void setupDialogueButtons(int presetfirst, int numStr, const char *str1, ...);
+	void initDialogueSequence();
+	void restoreAfterDialogueSequence();
+	void drawSequenceBitmap(const char *file, int destRect, int x1, int y1, int flags);
+	int runDialogue(int dialogueTextId, int style, const char *button1, ...);
+
+	char _dialogueLastBitmap[13];
+	int _dlgUnk1;
+	int _moveCounter;
+
+	uint8 _color4;
+	uint8 _color5;
+	uint8 _color6;
+	uint8 _color7;
+	uint8 _color8;
+	uint8 _color9;
+	uint8 _color10;
+	uint8 _color11;
+	uint8 _color12;
+	uint8 _color13;
+	uint8 _color14;
+
+	const char *const *_chargenStatStrings;
+	const char *const *_chargenRaceSexStrings;
+	const char *const *_chargenClassStrings;
+	const char *const *_chargenAlignmentStrings;
+
+	const char *const *_pryDoorStrings;
+	const char *const *_warningStrings;
+	const char *const *_itemExtraStrings;
+	const char *const *_itemSuffixStrings;
+	const char *const *_takenStrings;
+	const char *const *_potionEffectStrings;
+
+	const char *const *_yesNoStrings;
+	const char *const *_npcMaxStrings;
+	const char *const *_okStrings;
+	const char *const *_npcJoinStrings;
+	const char *const *_cancelStrings;
+	const char *const *_abortStrings;
+
+	// misc
+	void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false);
+	void displayParchment(int id);
+
+	virtual void drawLightningColumn() {}
+	virtual int resurrectionSelectDialogue() { return -1; }
+	virtual int charSelectDialogue() { return -1; }
+	virtual void characterLevelGain(int charIndex) {}
+
+	Common::Error loadGameState(int slot);
+	Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail);
+
+	void *generateMonsterTempData(LevelTempData *tmp);
+	void *generateFlyingObjectTempData(LevelTempData *tmp);
+	void restoreMonsterTempData(LevelTempData *tmp);
+	void restoreFlyingObjectTempData(LevelTempData *tmp);
+	void releaseMonsterTempData(LevelTempData *tmp);
+	void releaseFlyingObjectTempData(LevelTempData *tmp);
+
+	int _saveLoadMode;
+
+	Screen_Eob *_screen;
+	GUI_Eob *_gui;
+
+	// fight
+	void useSlotWeapon(int charIndex, int slotIndex, int item);
+	int closeDistanceAttack(int charIndex, int item);
+	int thrownAttack(int charIndex, int slotIndex, int item);
+	int bowAttack(int charIndex, int item);
+
+	void inflictMonsterDamage(EobMonsterInPlay *m, int damage, bool giveExperience);
+	void calcAndInflictMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int b, int damageType);
+	void calcAndInflictCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flg, int a, int damageType);
+	int calcCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flg, int a, int damageType) ;
+	void inflictCharacterDamage(int charIndex, int damage);
+
+	bool characterAttackHitTest(int charIndex, int monsterIndex, int item, int attackType);
+	bool monsterAttackHitTest(EobMonsterInPlay *m, int charIndex);
+	bool flyingObjectMonsterHit(EobFlyingObject *fo, int monsterIndex);
+	bool flyingObjectPartyHit(EobFlyingObject *fo);
+
+	void monsterCloseAttack(EobMonsterInPlay *m);
+	void monsterSpellCast(EobMonsterInPlay *m, int type);
+	void statusAttack(int charIndex, int attackStatusFlags, const char *attackStatusString, int a, uint32 effectDuration, int restoreEvent, int noRefresh);
+
+	int calcCloseDistanceMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int b, int damageType);
+	int calcDamageModifers(int charIndex, EobMonsterInPlay *m, int item, int itemType, int useStrModifier);
+	bool checkUnkConstModifiers(void *target, int hpModifier, int level, int b, int race);
+	bool specialAttackConstTest(int charIndex, int b);
+	int getConstModifierTableValue(int hpModifier, int level, int b);
+	bool calcDamageCheckItemType(int itemType);
+	int recalcDamageModifier(int damageType, int dmgModifier);
+	bool checkMonsterDamageEvasion(EobMonsterInPlay *m);
+	int getStrHitChanceModifier(int charIndex);
+	int getStrDamageModifier(int charIndex);
+	int getDexHitChanceModifier(int charIndex);
+	int getMonsterAcHitChanceModifier(int charIndex, int monsterAc);
+	void inflictMonsterDamage_s1(EobMonsterInPlay *m);
+
+	int _dstMonsterIndex;
+	int _inflictMonsterDamageUnk;
+	int16 _foundMonstersArray[5];
+
+	// magic
+	void useMagicBookOrSymbol(int charIndex, int type);
+	void useMagicScroll(int charIndex, int type, int weaponSlot);
+	void usePotion(int charIndex, int weaponSlot);
+
+	void castSpell(int spell, int weaponSlot);
+	void removeCharacterEffect(int spell, int charIndex, int showWarning);
+	void removeAllCharacterEffects(int charIndex);
+	void castOnWhomDialogue();
+	void startSpell(int spell);
+
+	void sparkEffectDefensive(int charIndex);
+	void sparkEffectOffensive();
+	void setSpellEventTimer(int spell, int timerBaseFactor, int timerLength, int timerLevelFactor, int updateExistingTimer);
+
+	bool magicObjectHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level);
+
+	void spellCallback_start_empty() {}
+	bool spellCallback_end_empty(EobFlyingObject *fo) { return true; }
+	void spellCallback_start_armor();
+	void spellCallback_start_burningHands();
+	void spellCallback_start_detectMagic();
+	bool spellCallback_end_detectMagic(EobFlyingObject *fo);
+	void spellCallback_start_magicMissile();
+	bool spellCallback_end_magicMissile(EobFlyingObject *fo);
+	void spellCallback_start_shockingGrasp();
+	bool spellCallback_end_shockingGraspFlameBlade(EobFlyingObject *fo);
+	void spellCallback_start_improvedIdentify();
+	void spellCallback_start_melfsAcidArrow();
+	bool spellCallback_end_melfsAcidArrow(EobFlyingObject *fo);
+	void spellCallback_start_dispelMagic();
+	void spellCallback_start_fireball();
+	bool spellCallback_end_fireball(EobFlyingObject *fo);
+	void spellCallback_start_flameArrow();
+	bool spellCallback_end_flameArrow(EobFlyingObject *fo);
+	void spellCallback_start_holdPerson();
+	bool spellCallback_end_holdPerson(EobFlyingObject *fo);
+	void spellCallback_start_lightningBolt();
+	bool spellCallback_end_lightningBolt(EobFlyingObject *fo);
+	void spellCallback_start_vampiricTouch();
+	bool spellCallback_end_vampiricTouch(EobFlyingObject *fo);
+	void spellCallback_start_fear();
+	void spellCallback_start_iceStorm();
+	bool spellCallback_end_iceStorm(EobFlyingObject *fo);
+	void spellCallback_start_removeCurse();
+	void spellCallback_start_coneOfCold();
+	void spellCallback_start_holdMonster();
+	bool spellCallback_end_holdMonster(EobFlyingObject *fo);
+	void spellCallback_start_wallOfForce();
+	void spellCallback_start_disintegrate();
+	void spellCallback_start_fleshToStone();
+	void spellCallback_start_stoneToFlesh();
+	void spellCallback_start_trueSeeing();
+	bool spellCallback_end_trueSeeing(EobFlyingObject *fo);
+	void spellCallback_start_slayLiving();
+	void spellCallback_start_powerWordStun();
+	void spellCallback_start_causeLightWounds();
+	void spellCallback_start_cureLightWounds();
+	void spellCallback_start_aid();
+	bool spellCallback_end_aid(EobFlyingObject *fo);
+	void spellCallback_start_flameBlade();
+	void spellCallback_start_slowPoison();
+	bool spellCallback_end_slowPoison(EobFlyingObject *fo);
+	void spellCallback_start_createFood();
+	void spellCallback_start_removeParalysis();
+	void spellCallback_start_causeSeriousWounds();
+	void spellCallback_start_cureSeriousWounds();
+	void spellCallback_start_neutralizePoison();
+	void spellCallback_start_causeCriticalWounds();
+	void spellCallback_start_cureCriticalWounds();
+	void spellCallback_start_flameStrike();
+	bool spellCallback_end_flameStrike(EobFlyingObject *fo);
+	void spellCallback_start_raiseDead();
+	void spellCallback_start_harm();
+	void spellCallback_start_heal();
+	void spellCallback_start_layOnHands();
+	void spellCallback_start_turnUndead();
+	bool spellCallback_end_unk1Passive(EobFlyingObject *fo);
+	bool spellCallback_end_unk2Passive(EobFlyingObject *fo);
+	bool spellCallback_end_deathSpellPassive(EobFlyingObject *fo);
+	bool spellCallback_end_disintegratePassive(EobFlyingObject *fo);
+	bool spellCallback_end_causeCriticalWoundsPassive(EobFlyingObject *fo);
+	bool spellCallback_end_fleshToStonePassive(EobFlyingObject *fo);
+
+	int8 _openBookSpellLevel;
+	int8 _openBookSpellSelectedItem;
+	int8 _openBookSpellListOffset;
+	uint8 _openBookChar;
+	uint8 _openBookType;
+	uint8 _openBookCharBackup;
+	uint8 _openBookTypeBackup;
+	const char *const *_openBookSpellList;
+	int8 *_openBookAvailableSpells;
+	uint8 _activeSpellCaster;
+	uint8 _activeSpellCasterPos;
+	uint8 _activeSpell;
+	bool _returnAfterSpellCallback;
+
+	typedef void (EobCoreEngine::*SpellStartCallback)();
+	typedef bool (EobCoreEngine::*SpellEndCallback)(EobFlyingObject *fo);
+
+	struct EobSpell {
+		const char *name;
+		SpellStartCallback startCallback;
+		uint16 flags;
+		const uint16 *timingPara;
+		SpellEndCallback endCallback;
+		uint8 sound;
+		uint32 effectFlags;
+		uint16 damageFlags;
+	};
+
+	EobSpell *_spells;
+	int _numSpells;
+
+	const char *const *_bookNumbers;
+	const char *const *_mageSpellList;
+	int _mageSpellListSize;
+	int _clericSpellOffset;
+	const char *const *_clericSpellList;
+	const char *const *_spellNames;
+	const char *const *_magicStrings1;
+	const char *const *_magicStrings2;
+	const char *const *_magicStrings3;
+	const char *const *_magicStrings4;
+	const char *const *_magicStrings5;
+	const char *const *_magicStrings6;
+	const char *const *_magicStrings7;
+	const char *const *_magicStrings8;
+
+	uint8 *_spellAnimBuffer;
+
+	const uint8 *_sparkEffectDefSteps;
+	const uint8 *_sparkEffectDefSubSteps;
+	const uint8 *_sparkEffectDefShift;
+	const uint8 *_sparkEffectDefAdd;
+	const uint8 *_sparkEffectDefX;
+	const uint8 *_sparkEffectDefY;
+	const uint32 *_sparkEffectOfFlags1;
+	const uint32 *_sparkEffectOfFlags2;
+	const uint8 *_sparkEffectOfShift;
+	const uint8 *_sparkEffectOfX;
+	const uint8 *_sparkEffectOfY;
+
+	const uint8 *_magicFlightObjectProperties;
+
+	// sound
+	void snd_playSoundEffect(int id, int volume=0xFF);
+};
+
+}	// End of namespace Kyra
+
+#endif // ENABLE_EOB
+
+#endif
\ No newline at end of file
diff --git a/engines/kyra/gui.h b/engines/kyra/gui.h
index 6e9606f..04fc9b5 100644
--- a/engines/kyra/gui.h
+++ b/engines/kyra/gui.h
@@ -40,10 +40,10 @@ struct Button {
 	typedef Common::Functor1<Button *, int> CallbackFunctor;
 	typedef Common::SharedPtr<CallbackFunctor> Callback;
 
-	Button() : nextButton(0), index(0), keyCode(0), keyCode2(0), data0Val1(0), data1Val1(0), data2Val1(0), flags(0),
+	Button() : nextButton(0), index(0), keyCode(0), keyCode2(0), data0Val1(0), data1Val1(0), data2Val1(0), data3Val1(0), flags(0),
 	    data0ShapePtr(0), data1ShapePtr(0), data2ShapePtr(0), data0Callback(), data1Callback(), data2Callback(),
 	    dimTableIndex(0), x(0), y(0), width(0), height(0), data0Val2(0), data0Val3(0), data1Val2(0), data1Val3(0),
-	    data2Val2(0), data2Val3(0), flags2(0), mouseWheel(0), buttonCallback(), arg(0) {}
+	    data2Val2(0), data2Val3(0), data3Val2(0), data3Val3(0), flags2(0), mouseWheel(0), buttonCallback(), arg(0) {}
 
 	Button *nextButton;
 	uint16 index;
@@ -54,6 +54,7 @@ struct Button {
 	byte data0Val1;
 	byte data1Val1;
 	byte data2Val1;
+	byte data3Val1;
 
 	uint16 flags;
 
@@ -78,6 +79,9 @@ struct Button {
 	uint8 data2Val2;
 	uint8 data2Val3;
 
+	uint8 data3Val2;
+	uint8 data3Val3;
+
 	uint16 flags2;
 
 	int8 mouseWheel;
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
new file mode 100644
index 0000000..9aafb76
--- /dev/null
+++ b/engines/kyra/gui_eob.cpp
@@ -0,0 +1,2165 @@
+/* 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.
+ *
+ */
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#include "kyra/eobcommon.h"
+#include "kyra/gui_eob.h"
+#include "kyra/timer.h"
+#include "kyra/util.h"
+
+#include "common/system.h"
+
+namespace Kyra {
+
+void LolEobBaseEngine::removeInputTop() {
+	if (!_eventList.empty()) {
+		if (_eventList.begin()->event.type == Common::EVENT_LBUTTONDOWN)
+			_mouseClick = 1;
+		else if (_eventList.begin()->event.type == Common::EVENT_RBUTTONDOWN)
+			_mouseClick = 2;
+		else
+			_mouseClick = 0;
+
+		_eventList.erase(_eventList.begin());
+	}
+}
+
+void LolEobBaseEngine::gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor) {
+	w--; h--;
+	if (fillColor != -1)
+		screen()->fillRect(x + 1, y + 1, x + w - 1, y + h - 1, fillColor);
+
+	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 LolEobBaseEngine::gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32 cur, int32 max, int col1, int col2) {
+	if (max < 1)
+		return;
+	if (cur < 0)
+		cur = 0;
+
+	int32 e = MIN(cur, max);
+
+	if (!--w)
+		return;
+	if (!--h)
+		return;
+
+	int32 t = (e * w) / max;
+
+	if (!t && e)
+		t++;
+
+	if (t)
+		screen()->fillRect(x, y, x + t - 1, y + h, col1);
+
+	if (t < w && col2)
+		screen()->fillRect(x + t, y, x + w, y + h, col2);
+}
+
+void LolEobBaseEngine::gui_initButtonsFromList(const int16 *list) {
+	while (*list != -1)
+		gui_initButton(*list++);
+}
+
+void LolEobBaseEngine::gui_resetButtonList() {
+	for (uint i = 0; i < ARRAYSIZE(_activeButtonData); ++i)
+		_activeButtonData[i].nextButton = 0;
+
+	gui_notifyButtonListChanged();
+	_activeButtons = 0;
+}
+
+void LolEobBaseEngine::gui_notifyButtonListChanged() {
+	if (gui()) {
+		if (!_buttonListChanged && !_preserveEvents)
+			removeInputTop();
+		_buttonListChanged = true;
+	}
+}
+
+bool LolEobBaseEngine::clickedShape(int shapeIndex) {
+	if (_clickedSpecialFlag != 0x40)
+		return true;
+
+	for (; shapeIndex; shapeIndex = _levelDecorationProperties[shapeIndex].next) {
+		if (_flags.gameID != GI_LOL)
+			shapeIndex--;
+
+		uint16 s = _levelDecorationProperties[shapeIndex].shapeIndex[1];
+
+		if (s == 0xffff)
+			continue;
+
+		int w = _flags.gameID == GI_LOL ? _levelDecorationShapes[s][3] : (_levelDecorationShapes[s][2] << 3);
+		int h = _levelDecorationShapes[s][_flags.gameID == GI_LOL ? 2 : 1];
+		int x = _levelDecorationProperties[shapeIndex].shapeX[1] + _clickedShapeXOffs;
+		int y = _levelDecorationProperties[shapeIndex].shapeY[1] + _clickedShapeYOffs;
+
+		if (_levelDecorationProperties[shapeIndex].flags & 1) {
+			if (_flags.gameID == GI_LOL)
+				w <<= 1;
+			else
+				x = 176 - x - w;
+		}
+
+		if (posWithinRect(_mouseX, _mouseY, x - 4, y - 4, x + w + 8, y + h + 8))
+			return true;
+	}
+
+	return false;
+}
+
+#ifdef ENABLE_EOB
+
+Button *EobCoreEngine::gui_getButton(Button *buttonList, int index) {
+	while (buttonList) {
+		if (buttonList->index == index)
+			return buttonList;
+		buttonList = buttonList->nextButton;
+	}
+
+	return 0;
+}
+
+void EobCoreEngine::gui_drawPlayField(int pageNum) {
+	_screen->loadEobCpsFileToPage("PLAYFLD", 0, 5, 3, 2);
+	int cp = _screen->setCurPage(2);
+	gui_drawCompass(true);
+
+	if (pageNum && !_sceneDrawPage1)
+		drawScene(0);
+
+	_screen->setCurPage(cp);
+	_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+
+	_screen->loadEobCpsFileToPage("INVENT", 0, 5, 3, 2);
+}
+
+void EobCoreEngine::gui_restorePlayField() {
+	loadVcnData(0, 0);
+	_screen->_curPage = 0;
+	gui_drawPlayField(1);
+	gui_drawAllCharPortraitsWithStats();
+}
+
+void EobCoreEngine::gui_drawAllCharPortraitsWithStats() {
+	for (int i = 0; i < 6; i++)
+		gui_drawCharPortraitWithStats(i);
+}
+
+void EobCoreEngine::gui_drawCharPortraitWithStats(int index) {
+	if (!testCharacter(index, 1))
+		return;
+
+	static const uint16 charPortraitPosX[] = { 8, 80, 184, 256 };
+	static const uint16 charPortraitPosY[] = { 2, 54, 106 };
+
+	EobCharacter *c = &_characters[index];
+	int txtCol1 = 12;
+	int txtCol2 = 15;
+
+	if ((_flags.gameID == GI_EOB1 && c->flags & 6) || (_flags.gameID == GI_EOB2 && c->flags & 0x0e)) {
+		txtCol1 = 8;
+		txtCol2 = 6;
+	}
+
+	char tmpStr[10];
+
+	if (_currentControlMode == 0) {
+		int x2 = charPortraitPosX[index & 1];
+		int y2 = charPortraitPosY[index >> 1];
+		Screen::FontId cf = _screen->setFont(Screen::FID_6_FNT);
+
+		_screen->copyRegion(176, 168, x2 , y2, 64, 24, 2, 2, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(240, 168, x2, y2 + 24, 64, 26, 2, 2, Screen::CR_NO_P_CHECK);
+		int cp = _screen->setCurPage(2);
+
+		if (index == _exchangeCharacterId)
+			_screen->printText(_characterGuiStringsSt[0], x2 + 2, y2 + 2, 8, _bkgColor_1);
+		else
+			_screen->printText(c->name, x2 + 2, y2 + 2, txtCol1, _bkgColor_1);
+
+		gui_drawFaceShape(index);
+		gui_drawWeaponSlot(index, 0);
+		gui_drawWeaponSlot(index, 1);
+		gui_drawHitpoints(index);
+
+		if (testCharacter(index, 2))
+			gui_drawCharPortraitStatusFrame(index);
+
+		if (c->damageTaken > 0) {
+			_screen->drawShape(2, _redSplatShape, x2 + 13, y2 + 30, 0);
+			sprintf(tmpStr, "%d", c->damageTaken);
+			_screen->printText(tmpStr, x2 + 34 - (strlen(tmpStr) * 3), y2 + 42, 15, 0);
+		}
+
+		_screen->setCurPage(cp);
+		_screen->setFont(cf);
+
+		if (!cp) {
+			_screen->copyRegion(x2, y2, charPortraitPosX[2 + (index & 1)], y2, 64, 50, 2, 0, Screen::CR_NO_P_CHECK);
+			_screen->updateScreen();
+		}
+	} else if ((_currentControlMode == 1 || _currentControlMode == 2) && index == _updateCharNum) {
+		_screen->copyRegion(176, 0, 0, 0, 144, 168, 2, 2, Screen::CR_NO_P_CHECK);
+		_screen->_curPage = 2;
+		gui_drawFaceShape(index);
+		_screen->printShadedText(c->name, 219, 6, txtCol2, _bkgColor_1);
+		gui_drawHitpoints(index);
+		gui_drawFoodStatusGraph(index);
+
+		if (_currentControlMode == 1) {
+			if (c->hitPointsCur == -10)
+				_screen->printShadedText(_characterGuiStringsSt[1], 247, 158, 6, _color6);
+			else if (c->hitPointsCur < 1)
+				_screen->printShadedText(_characterGuiStringsSt[2], 226, 158, 6, _color6);
+			else if (c->effectFlags & (_flags.gameID == GI_EOB1 ? 0x80 : 0x2000))
+				_screen->printShadedText(_characterGuiStringsSt[3], 220, 158, 6, _color6);
+			else if (c->flags & 2)
+				_screen->printShadedText(_characterGuiStringsSt[4], 235, 158, 6, _color6);
+			else if (c->flags & 4)
+				_screen->printShadedText(_characterGuiStringsSt[5], 232, 158, 6, _color6);
+			else if (c->flags & 8)
+				_screen->printShadedText(_characterGuiStringsSt[6], 232, 158, 6, _color6);
+
+			for (int i = 0; i < 27; i++)
+				gui_drawInventoryItem(i, 0, 2);
+			gui_drawInventoryItem(16, 1, 2);
+
+		} else {
+			static const uint16 cm2X1[] = { 179, 272, 301 };
+			static const uint16 cm2Y1[] = { 36, 51, 51 };
+			static const uint16 cm2X2[] = { 271, 300, 318 };
+			static const uint16 cm2Y2[] = { 165, 165, 147 };
+
+			for (int i = 0; i < 3; i++)
+				_screen->fillRect(cm2X1[i], cm2Y1[i], cm2X2[i], cm2Y2[i], _color6);
+
+			_screen->printShadedText(_characterGuiStringsIn[0], 183, 42, 15, _color6);
+			_screen->printText(_chargenClassStrings[c->cClass], 183, 55, 12, _color6);
+			_screen->printText(_chargenAlignmentStrings[c->alignment], 183, 62, 12, _color6);
+			_screen->printText(_chargenRaceSexStrings[c->raceSex], 183, 69, 12, _color6);
+
+			for (int i = 0; i < 6; i++)
+				_screen->printText(_chargenStatStrings[6 + i], 183, 82 + i * 7, 12, _color6);
+
+			_screen->printText(_characterGuiStringsIn[1], 183, 124, 12, _color6);
+			_screen->printText(_characterGuiStringsIn[2], 239, 138, 12, _color6);
+			_screen->printText(_characterGuiStringsIn[3], 278, 138, 12, _color6);
+
+			_screen->printText(getCharStrength(c->strengthCur, c->strengthExtCur), 275, 82, 15, _color6);
+			sprintf(tmpStr, "%d", c->intelligenceCur);
+			_screen->printText(tmpStr, 275, 89, 15, _color6);
+			sprintf(tmpStr, "%d", c->wisdomCur);
+			_screen->printText(tmpStr, 275, 96, 15, _color6);
+			sprintf(tmpStr, "%d", c->dexterityCur);
+			_screen->printText(tmpStr, 275, 103, 15, _color6);
+			sprintf(tmpStr, "%d", c->constitutionCur);
+			_screen->printText(tmpStr, 275, 110, 15, _color6);
+			sprintf(tmpStr, "%d", c->charismaCur);
+			_screen->printText(tmpStr, 275, 117, 15, _color6);
+			sprintf(tmpStr, "%d", c->armorClass);
+			_screen->printText(tmpStr, 275, 124, 15, _color6);
+
+			for (int i = 0; i < 3; i++) {
+				int t = getClassHpIncreaseType(c->cClass, i);
+				if (t == -1)
+					continue;
+
+				_screen->printText(_chargenClassStrings[t + 15], 180, 145 + 7 * i, 12, _color6);
+				sprintf(tmpStr, "%d", c->experience[i]);
+				_screen->printText(tmpStr, 251 - strlen(tmpStr) * 3, 145 + 7 * i, 15, _color6);
+				sprintf(tmpStr, "%d", c->level[i]);
+				_screen->printText(tmpStr, 286 - strlen(tmpStr) * 3, 145 + 7 * i, 15, _color6);
+			}
+		}
+
+		_screen->_curPage = 0;
+		_screen->copyRegion(176, 0, 176, 0, 144, 168, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(0, 0, 176, 0, 144, 168, 2, 2, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+	}
+}
+
+void EobCoreEngine::gui_drawFaceShape(int index) {
+	if (!testCharacter(index, 1))
+		return;
+
+	static const uint8 xCoords[] = { 8, 80 };
+	static const uint8 yCoords[] = { 11, 63, 115 };
+
+	int x = xCoords[index & 1];
+	int y = yCoords[index >> 1];
+
+	if (!_screen->_curPage)
+		x += 176;
+
+	if (_currentControlMode) {
+		if (_updateCharNum != index)
+			return;
+
+		x = 181;
+		y = 3;
+	}
+
+	EobCharacter *c = &_characters[index];
+
+	if (c->hitPointsCur == -10) {
+		_screen->drawShape(_screen->_curPage, _deadCharShape, x, y, 0);
+		return;
+	}
+
+	if (_flags.gameID == GI_EOB1) {
+		if (c->effectFlags & 4) {
+			_screen->fillRect(x, y, x + 31, y + 31, 12);
+			return;
+		}
+	} else {
+		if (c->effectFlags & 0x140) {
+			_screen->setFadeTableIndex(1);
+			_screen->setShapeFadeMode(1, true);
+		}
+
+		if (c->flags & 2) {
+			_screen->setFadeTableIndex(0);
+			_screen->setShapeFadeMode(1, true);
+		}
+
+		if (c->flags & 8) {
+			_screen->setFadeTableIndex(2);
+			_screen->setShapeFadeMode(1, true);
+		}
+	}
+
+	_screen->drawShape(_screen->_curPage, c->faceShape, x, y, 0);
+
+	if (c->hitPointsCur < 1)
+		_screen->drawShape(_screen->_curPage, _disabledCharGrid, x, y, 0);
+
+	//if ((c->flags & 2) || (c->flags & 8) || (c->effectFlags & 0x140)) {
+		_screen->setFadeTableIndex(4);
+		_screen->setShapeFadeMode(1, false);
+	//}
+}
+
+void EobCoreEngine::gui_drawWeaponSlot(int charIndex, int slot) {
+	static const uint8 xCoords[] = { 40, 112 };
+	static const uint8 yCoords[] = { 11, 27, 63, 79, 115, 131 };
+
+	int x = xCoords[charIndex & 1];
+	int y = yCoords[(charIndex & 6) + slot];
+
+	if (!_screen->_curPage)
+		x += 176;
+
+	int itm = _characters[charIndex].inventory[slot];
+	gui_drawBox(x, y, 31, 16, _color1_1, _color2_1, _bkgColor_1);
+
+	if (_characters[charIndex].slotStatus[slot]) {
+		gui_drawWeaponSlotStatus(x, y, _characters[charIndex].slotStatus[slot]);
+		return;
+	}
+
+	if (itm)
+		drawItemIconShape(_screen->_curPage, itm, x + 8, y);
+	else if (!slot && checkScriptFlag(0x8000))
+		_screen->drawShape(_screen->_curPage, _itemIconShapes[103], x + 8, y, 0);
+	else
+		_screen->drawShape(_screen->_curPage, _itemIconShapes[85], x + 8, y, 0);
+
+	if ((_characters[charIndex].disabledSlots & (1 << slot)) || !validateWeaponSlotItem(charIndex, slot) || (_characters[charIndex].hitPointsCur <= 0) || (_characters[charIndex].flags & 0x0c))
+		_screen->drawShape(_screen->_curPage, _weaponSlotGrid, x, y, 0);
+}
+
+void EobCoreEngine::gui_drawWeaponSlotStatus(int x, int y, int status) {
+	char tmpStr[6];
+	char tmpStr2[6];
+	tmpStr2[0] = 0;
+
+	if (status > -3 || status == -5)
+		_screen->drawShape(_screen->_curPage, _greenSplatShape, x - 1, y, 0);
+	else
+		gui_drawBox(x, y, 31, 16, _color9, _color10, _color11);
+
+	switch (status + 5) {
+		case 0:
+			strcpy(tmpStr, _characterGuiStringsWp[2]);
+			break;
+		case 1:
+			strcpy(tmpStr, _characterGuiStringsWr[2]);
+			strcpy(tmpStr2, _characterGuiStringsWr[3]);
+			break;
+		case 2:
+			strcpy(tmpStr, _characterGuiStringsWr[0]);
+			strcpy(tmpStr2, _characterGuiStringsWr[1]);
+			break;
+		case 3:
+			strcpy(tmpStr, _characterGuiStringsWp[1]);
+			break;
+		case 4:
+			strcpy(tmpStr, _characterGuiStringsWp[0]);
+			break;
+		default:
+			snprintf(tmpStr, 6, "%d", status);
+			break;
+	}
+
+	if (tmpStr2[0]) {
+		_screen->printText(tmpStr, x + (16 - strlen(tmpStr) * 3), y + 2, 15, 0);
+		_screen->printText(tmpStr2, x + (16 - strlen(tmpStr) * 3), y + 9, 15, 0);
+	} else {
+		_screen->printText(tmpStr, x + (16 - strlen(tmpStr) * 3), y + 5, 15, 0);
+	}
+}
+
+void EobCoreEngine::gui_drawHitpoints(int index) {
+	if (!testCharacter(index, 1))
+		return;
+
+	if (_currentControlMode && (index != _updateCharNum))
+		return;
+
+	static const uint8 xCoords[] = { 23, 95 };
+	static const uint8 yCoords[] = { 46, 98, 150 };
+	static const uint8 barColor[] = { 3, 5, 8 };
+
+	int x = xCoords[index & 1];
+	int y = yCoords[index >> 1];
+	int w = 38;
+	int h = 3;
+
+	if (!_screen->_curPage)
+		x += 176;
+
+	if (_currentControlMode) {
+		x = 250;
+		y = 16;
+		w = 51;
+		h = 5;
+	}
+
+	EobCharacter *c = &_characters[index];
+
+	if (_hpBarGraphs) {
+		int bgCur = c->hitPointsCur + 10;
+		int bgMax = c->hitPointsMax + 10;
+		int col = ((bgMax / 3) > bgCur) ? 1 : 0;
+		if (bgCur <= 10)
+			col = 2;
+
+		if (!_currentControlMode)
+			_screen->printText(_characterGuiStringsHp[0], x - 13, y - 1, 12, 0);
+
+
+		gui_drawHorizontalBarGraph(x, y, w, h, bgCur, bgMax, barColor[col], _color5);
+
+	} else {
+		char tmpString[12];
+		snprintf(tmpString, 12, _characterGuiStringsHp[1], c->hitPointsCur, c->hitPointsMax);
+
+		if (!_currentControlMode) {
+			x -= 13;
+			y -= 1;
+		}
+
+		_screen->printText(tmpString, x, y, 12, _bkgColor_1);
+	}
+}
+
+void EobCoreEngine::gui_drawFoodStatusGraph(int index) {
+	if (!_currentControlMode)
+		return;
+
+	if (!testCharacter(index, 1))
+		return;
+
+	EobCharacter *c = &_characters[index];
+	if (!(c->flags & 1))
+		return;
+
+	if (index != _updateCharNum)
+		return;
+
+	uint8 col = c->food < 20 ? 8 : (c->food < 33 ? 5 : 3);
+	gui_drawHorizontalBarGraph(250, 25, 51, 5, c->food, 100, col, _color5);
+}
+
+void EobCoreEngine::gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32 curVal, int32 maxVal, int col1, int col2) {
+	gui_drawBox(x - 1, y - 1, w + 3, h + 2, _color2_1, _color1_1, -1);
+	LolEobBaseEngine::gui_drawHorizontalBarGraph(x, y, w + 2, h, curVal, maxVal, col1, col2);
+}
+
+void EobCoreEngine::gui_drawCharPortraitStatusFrame(int index) {
+	uint8 boxColor = ((_partyEffectFlags & 0x20000) | (_partyEffectFlags & 0xffff)) ? 4 : 6;
+
+	static const uint8 xCoords[] = { 8, 80 };
+	static const uint8 yCoords[] = { 2, 54, 106 };
+	int x = xCoords[index & 1];
+	int y = yCoords[index >> 1];
+
+	if (!_screen->_curPage)
+		x += 176;
+
+	EobCharacter *c = &_characters[index];
+
+	int v8 = (_flags.gameID == GI_EOB2 && ((c->effectFlags & 0x4818) || c->effectsRemainder[0] || c->effectsRemainder[1] || ((_partyEffectFlags & 0x20000) | (_partyEffectFlags & 0xffff)))) ||
+		(_flags.gameID == GI_EOB1 && ((c->effectFlags & 0x302) || c->effectsRemainder[0] || c->effectsRemainder[1])) ? 1 : 0;
+	int vA = (_flags.gameID == GI_EOB2 && ((((c->effectFlags & 0x3000) | (c->effectFlags & 0x10000)) || (_partyEffectFlags & 0x8420)))) ||
+		(_flags.gameID == GI_EOB1 && ((c->effectFlags & 0x4c8) || _partyEffectFlags & 300000))? 1 : 0;
+
+	if (v8 || vA) {
+		if (v8 && !vA) {
+			_screen->drawBox(x, y, x + 63, y + 49, boxColor);
+			return;
+		}
+
+		if (vA && !v8) {
+			_screen->drawBox(x, y, x + 63, y + 49, 5);
+			return;
+		}
+
+		int iX= x;
+		int iY= y;
+
+		for (int i = 0; i < 64; i += 16) {
+			x = iX + i;
+			if (v8) {
+				_screen->drawClippedLine(x, y, x + 7, y, boxColor);
+				_screen->drawClippedLine(x + 8, y + 49, x + 15, y + 49, boxColor);
+			}
+			if (vA) {
+				_screen->drawClippedLine(x + 8, y, x + 15, y, 5);
+				_screen->drawClippedLine(x, y + 49, x + 7, y + 49, 5);
+			}
+		}
+
+		x = iX;
+
+		for (int i = 1; i < 48; i += 12) {
+			y = iY + i - 1;
+
+			if (vA) {
+				_screen->drawClippedLine(x, y + 1, x, y + 6, 5);
+				_screen->drawClippedLine(x + 63, y + 7, x + 63, y + 12, 5);
+			}
+			if (v8) {
+				_screen->drawClippedLine(x, y + 7, x, y + 12, boxColor);
+				_screen->drawClippedLine(x + 63, y + 1, x + 63, y + 6, boxColor);
+			}
+		}
+
+	} else {
+		_screen->drawClippedLine(x, y, x + 62, y, _color1_1);
+		_screen->drawClippedLine(x, y + 49, x + 62, y + 49, _color2_1);
+		_screen->drawClippedLine(x - 1, y, x - 1, y + 50, 12);
+		_screen->drawClippedLine(x + 63, y, x + 63, y + 50, 12);
+	}
+}
+
+void EobCoreEngine::gui_drawInventoryItem(int slot, int special, int pageNum) {
+	int x = _inventorySlotsX[slot];
+	int y = _inventorySlotsY[slot];
+
+	int item = _characters[_updateCharNum].inventory[slot];
+	int cp = _screen->setCurPage(pageNum);
+
+	if (special) {
+		int wh = (slot == 25 || slot == 26) ? 10 : 18;
+		gui_drawBox(x - 1, y - 1, wh, wh, _color1_1, _color2_1, slot == 16 ? -1 : _bkgColor_1);
+
+		if (slot == 16) {
+			_screen->fillRect(227, 65, 238, 69, 12);
+			int cnt = countQueuedItems(_characters[_updateCharNum].inventory[slot], -1, -1, 1, 1);
+			x = cnt >= 10 ? 227 : 233;
+			char str[3];
+			snprintf(str, 3, "%d", cnt);
+			_screen->printText(str, x, 65, 15, 0);
+		}
+	}
+
+	if (slot != 16 && item) {
+		if (slot == 25 || slot == 26) {
+			x -= 4;
+			y -= 4;
+		}
+		drawItemIconShape(pageNum, item, x, y);
+	}
+	_screen->_curPage = cp;
+	_screen->updateScreen();
+}
+
+void EobCoreEngine::gui_drawCompass(bool force) {
+	if (_currentDirection == _compassDirection && !force)
+		return;
+
+	static const uint8 shpX[2][3] = { { 0x70, 0x4D, 0x95 }, { 0x72, 0x4F, 0x97 } };
+	static const uint8 shpY[2][3] = { { 0x7F, 0x9A, 0x9A }, { 0x83, 0x9E, 0x9E } };
+	int g = _flags.gameID == GI_EOB1 ? 0 : 1;
+
+	for (int i = 0; i < 3; i++)
+		_screen->drawShape(_screen->_curPage, _compassShapes[(i << 2) + _currentDirection], shpX[g][i], shpY[g][i], 0);
+
+	_compassDirection = _currentDirection;
+}
+
+void EobCoreEngine::gui_drawDialogueBox() {
+	gui_drawBox(0, 121, 320, 79, _color1_1, _color2_1, _bkgColor_1);
+	txt()->clearCurDim();
+}
+
+void EobCoreEngine::gui_drawSpellbook() {
+	_screen->setCurPage(2);
+	int numTab = (_flags.gameID == GI_EOB1) ? 5 : 6;
+	_screen->copyRegion(64, 121, 64, 121, 112, 56, 0, 2, Screen::CR_NO_P_CHECK);
+
+	for (int i = 0; i < numTab; i++) {
+		int col1 = _color14;
+		int col2 = _color13;
+		int col3 = _color12;
+
+		if (i == _openBookSpellLevel) {
+			col1 =  _color1_1;
+			col2 =  _color2_1;
+			col3 =  _bkgColor_1;
+		}
+
+		if (_flags.gameID == GI_EOB1) {
+			gui_drawBox(i * 21 + 71, 122, 21, 9, col1, col2, col3);
+			_screen->printText(_magicStrings7[i], i * 21 + 73, 123, 12, 0);
+		} else {
+			gui_drawBox(i * 18 + 68, 121, 18, 9, col1, col2, col3);
+			char val[3];
+			sprintf(val, "%d", i + 1);
+			_screen->printText(val, i * 18 + 75, 123, 12, 0);
+		}
+	}
+
+	if (_flags.gameID == GI_EOB1)
+		gui_drawBox(71, 131, 105, 44, _color1_1, _color2_1, _bkgColor_1);
+	else {
+		gui_drawBox(68, 130, 108, 47, _color1_1, _color2_1, _bkgColor_1);
+		gui_drawBox(68, 168, 78, 9, _color8, _color7, _color6);
+		gui_drawBox(146, 168, 14, 9, _color8, _color7, _color6);
+		gui_drawBox(160, 168, 16, 9, _color8, _color7, _color6);
+		gui_drawSpellbookScrollArrow(150, 169, 0);
+		gui_drawSpellbookScrollArrow(165, 169, 1);
+	}
+
+	int textCol1 = 15;
+	int textCol2 = 8;
+	int textXa = 74;
+	int textXs = 71;
+	int textY = 170;
+	int col3 = _bkgColor_1;
+
+	if (_flags.gameID == GI_EOB1) {
+		textCol2 = 11;
+		textXa = textXs = 73;
+		textY = 168;
+	}
+
+	for (int i = 0; i < 7; i++) {
+		int d = _openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellListOffset + i];
+		if (_openBookSpellSelectedItem == i) {
+			if (d >= 0 && i < 6 && (i + _openBookSpellListOffset) < 9) {
+				_screen->printText(_openBookSpellList[d], textXs, 132 + 6 * i, textCol1, textCol2);
+			} else if (i == 6) {
+				if (_flags.gameID == GI_EOB2)
+					_screen->fillRect(69, 169, 144, 175, textCol2);
+				_screen->printText(_magicStrings1[0], textXa, textY, textCol1, textCol2);
+			}
+		} else {
+			if (d >= 0 && i < 6 && (i + _openBookSpellListOffset) < 9)
+				_screen->printText(_openBookSpellList[d], textXs, 132 + 6 * i, textCol1, col3);
+			else
+				_screen->printText(_magicStrings1[0], textXa, textY, 12, _color6);
+		}
+	}
+
+	if (_characters[_openBookChar].disabledSlots & 4) {
+		static const uint8 xpos[] = { 0x44, 0x62, 0x80, 0x90 };
+		static const uint8 ypos[] = { 0x82, 0x92, 0x98 };
+		for (int yc = 0; yc < 3; yc++) {
+			for (int xc = 0; xc < 4; xc++)
+				_screen->drawShape(_screen->_curPage, _weaponSlotGrid, xpos[xc], ypos[yc], 0);
+		}
+	}
+
+	if (_openBookAvailableSpells[_openBookSpellLevel * 10 + 6] <= 0)
+		_screen->drawShape(2, _blackBoxWideGrid, 146, 168, 0);
+
+	_screen->setCurPage(0);
+	_screen->copyRegion(64, 121, 64, 121, 112, 56, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+}
+
+void EobCoreEngine::gui_drawSpellbookScrollArrow(int x, int y, int direction) {
+	static const uint8 x1[] = { 0, 2, 1, 0, 2, 2 };
+	static const uint8 x2[] = { 2, 4, 5, 6, 4, 4 };
+	if (direction) {
+		_screen->setPagePixel(_screen->_curPage, x + 3, y + 5, 12);
+		for (int i = 1; i < 6; i++)
+			_screen->drawClippedLine(x + x1[i], (5 - i) + y, x + x2[i], (5 - i) + y, 12);
+	} else {
+		_screen->setPagePixel(_screen->_curPage, x + 3, y, 12);
+		for (int i = 1; i < 6; i++)
+			_screen->drawClippedLine(x + x1[i], y + i, x + x2[i], y + i, 12);
+	}
+}
+
+void EobCoreEngine::gui_updateSlotAfterScrollUse() {
+	_characters[_openBookChar].disabledSlots ^= (1 << (--_castScrollSlot));
+	setCharEventTimer(_openBookChar, 18, _castScrollSlot + 2, 1);
+	gui_drawCharPortraitWithStats(_openBookChar);
+	_openBookChar = _openBookCharBackup;
+	_openBookType = _openBookTypeBackup;
+	_castScrollSlot = 0;
+	gui_toggleButtons();
+}
+
+void EobCoreEngine::gui_updateControls() {
+	Button b;
+	if (_currentControlMode)
+		clickedPortraitRestore(&b);
+	if (_updateFlags)
+		clickedSpellbookAbort(&b);
+}
+
+void EobCoreEngine::gui_toggleButtons() {
+	if (_currentControlMode == 0)
+		gui_setPlayFieldButtons();
+	else if (_currentControlMode == 1)
+		gui_setInventoryButtons();
+	else if (_currentControlMode == 2)
+		gui_setStatsListButtons();
+}
+
+void EobCoreEngine::gui_setPlayFieldButtons() {
+	gui_resetButtonList();
+	gui_initButtonsFromList(_updateFlags ? _buttonList2 : _buttonList1);
+}
+
+void EobCoreEngine::gui_setInventoryButtons() {
+	gui_resetButtonList();
+	gui_initButtonsFromList(_updateFlags ? _buttonList5 : _buttonList3);
+}
+
+void EobCoreEngine::gui_setStatsListButtons() {
+	gui_resetButtonList();
+	gui_initButtonsFromList(_updateFlags ? _buttonList6 : _buttonList4);
+}
+
+void EobCoreEngine::gui_setSwapCharacterButtons() {
+	gui_resetButtonList();
+	gui_initButtonsFromList(_buttonList7);
+}
+
+void EobCoreEngine::gui_setCastOnWhomButtons() {
+	gui_resetButtonList();
+	gui_initButtonsFromList(_buttonList8);
+}
+
+void EobCoreEngine::gui_initButton(int index, int, int, int) {
+	Button *b = 0;
+	int cnt = 1;
+
+	if (_flags.gameID == GI_EOB1 && index > 92)
+		return;
+
+	if (_activeButtons) {
+		Button *n = _activeButtons;
+		while (n->nextButton) {
+			++cnt;
+			n = n->nextButton;
+		}
+
+		++cnt;
+		b = n->nextButton = &_activeButtonData[cnt];
+	} else {
+		b = &_activeButtonData[0];
+		_activeButtons = b;
+	}
+
+	*b = Button();
+	b->data0Val2 = 12;
+	b->data1Val2 = b->data2Val2 = 15;
+	b->data3Val2 = 8;
+
+	b->index = index + 1;
+
+	const EobGuiButtonDef *d = &_buttonDefs[index];
+
+	if (_flags.gameID == GI_EOB1) {
+		// EOB1 spellbook modifications
+		if (index > 61 && index < 67)
+			d = &_buttonDefs[index + 33];
+		if (index == 88)
+			d = &_buttonDefs[index + 12];
+	}
+
+	b->x = d->x;
+	b->y = d->y;
+	b->width = d->w;
+	b->height = d->h;
+
+	// EOB1 spellbook modifications
+	if (_flags.gameID == GI_EOB1 && ((index > 66 && index < 73) || (index > 76 && index < 79)))
+		b->y++;
+
+	b->flags = d->flags;
+	b->keyCode = d->keyCode;
+	b->keyCode2 = d->keyCode2;
+	b->arg = d->arg;
+	b->buttonCallback = d->buttonCallback;
+}
+
+int EobCoreEngine::clickedCharPortraitDefault(Button *button) {
+	if (!testCharacter(button->arg, 1))
+		return 1;
+
+	gui_processCharPortraitClick(button->arg);
+	return 0;
+}
+
+int EobCoreEngine::clickedCamp(Button *button) {
+	return button->arg;
+}
+
+int EobCoreEngine::clickedSceneDropPickupItem(Button *button) {
+	uint16 block = _currentBlock;
+	if (button->arg > 1) {
+		block = calcNewBlockPosition(_currentBlock, _currentDirection);
+		int f = _wllWallFlags[_levelBlockProperties[block].walls[_sceneDrawVarDown]];
+		if (!(f & 0x0b))
+			return 1;
+	}
+	int d = _dropItemDirIndex[(_currentDirection << 2) + button->arg];
+
+	if (_itemInHand) {
+		setItemPosition((Item*)&_levelBlockProperties[block & 0x3ff].drawObjects, block, _itemInHand, d);
+		setHandItem(0);
+		runLevelScript(block, 4);
+	} else {
+		d = getQueuedItem((Item*)&_levelBlockProperties[block].drawObjects, d, -1);
+		if (!d)
+			return 1;
+		setHandItem(d);
+		runLevelScript(block, 8);
+	}
+
+	_sceneUpdateRequired = true;
+	return 1;
+}
+
+int EobCoreEngine::clickedCharPortrait2(Button *button) {
+	if (!_gui->_progress) {
+		if (!testCharacter(button->arg, 1))
+			return button->index;
+	}
+
+	_currentControlMode = 1;
+	if (!_gui->_progress)
+		_updateCharNum = button->arg;
+
+	_screen->copyRegion(176, 0, 0, 0, 144, 168, 0, 5, Screen::CR_NO_P_CHECK);
+	gui_drawCharPortraitWithStats(_updateCharNum);
+	gui_setInventoryButtons();
+
+	return button->index;
+}
+
+int EobCoreEngine::clickedWeaponSlot(Button *button) {
+	if (!testCharacter(button->arg, 1))
+		return 1;
+
+	static const uint8 sY[] = { 24, 24, 80, 80, 136, 136 };
+	int slot = sY[button->arg] > _mouseY ? 0 : 1;
+
+	if ((_gui->_flagsMouseLeft & 0x7f) == 1)
+		gui_processWeaponSlotClickLeft(button->arg, slot);
+	else
+		gui_processWeaponSlotClickRight(button->arg, slot);
+
+	return 1;
+}
+
+int EobCoreEngine::clickedCharNameLabelRight(Button *button) {
+	if (!testCharacter(button->arg, 1))
+		return button->index;
+
+	if (_updateFlags) {
+		Button b;
+		clickedSpellbookAbort(&b);
+	}
+
+	if (_exchangeCharacterId == -1) {
+		_exchangeCharacterId = button->arg;
+		gui_setSwapCharacterButtons();
+		gui_drawCharPortraitWithStats(_exchangeCharacterId);
+		enableTimer(0);
+	} else {
+		int d = _exchangeCharacterId;
+		_exchangeCharacterId = -1;
+
+		EobCharacter temp;
+		memcpy(&temp, &_characters[d], sizeof(EobCharacter));
+		memcpy(&_characters[d], &_characters[button->arg], sizeof(EobCharacter));
+		memcpy(&_characters[button->arg], &temp, sizeof(EobCharacter));
+
+		_timer->disable(0);
+		gui_drawCharPortraitWithStats(d);
+		gui_processCharPortraitClick(button->arg);
+		gui_drawCharPortraitWithStats(button->arg);
+		gui_setPlayFieldButtons();
+		setupCharacterTimers();
+	}
+
+	return button->index;
+}
+
+int EobCoreEngine::clickedInventorySlot(Button *button) {
+	gui_processInventorySlotClick(button->arg);
+	return button->index;
+}
+
+int EobCoreEngine::clickedEatItem(Button *button) {
+	eatItemInHand(_updateCharNum);
+	return button->index;
+}
+
+int EobCoreEngine::clickedInventoryPrevChar(Button *button) {
+	if (_gui->_progress == 1)
+		_updateCharNum = 0;
+	else if (_gui->_progress == 2)
+		_updateCharNum = 1;
+	else
+		_updateCharNum = getNextValidCharIndex(_updateCharNum, -1);
+
+	gui_drawCharPortraitWithStats(_updateCharNum);
+	return button->index;
+}
+
+int EobCoreEngine::clickedInventoryNextChar(Button *button) {
+	int oldVal = _updateCharNum;
+	int v = button->arg == 2 ? 2 : 0;
+
+	if (_gui->_progress == 1)
+		_updateCharNum = v + 2;
+	else if (_gui->_progress == 2)
+		_updateCharNum = v + 3;
+	else
+		_updateCharNum = getNextValidCharIndex(_updateCharNum, 1);
+
+	if (!testCharacter(_updateCharNum, 1)) {
+		_updateCharNum = oldVal;
+		return 1;
+	}
+
+	gui_drawCharPortraitWithStats(_updateCharNum);
+	return button->index;
+}
+
+int EobCoreEngine::clickedSpellbookTab(Button *button) {
+	_openBookSpellLevel = button->arg;
+	_openBookSpellListOffset = 0;
+
+	for (_openBookSpellSelectedItem = 0; _openBookSpellSelectedItem < 6; _openBookSpellSelectedItem++) {
+		if (_openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellSelectedItem] > 0)
+			break;
+	}
+
+	gui_drawSpellbook();
+
+	_characters[_openBookChar].slotStatus[3] = _openBookSpellLevel;
+	_characters[_openBookChar].slotStatus[2] = _openBookSpellSelectedItem;
+	_characters[_openBookChar].slotStatus[4] = _openBookSpellListOffset;
+
+	return button->index;
+}
+
+int EobCoreEngine::clickedSpellbookList(Button *button) {
+	int listIndex = button->arg;
+	bool spellLevelAvailable = false;
+
+	if (listIndex == 6) {
+		for (int i = 0; i < 10; i++) {
+			if (_openBookAvailableSpells[_openBookSpellLevel * 10 + i] > 0) {
+				spellLevelAvailable = true;
+				break;
+			}
+		}
+		if (!spellLevelAvailable)
+			return button->index;
+
+		int v = (_gui->_progress == 1) ? -1 : ((_gui->_progress == 2) ? 1 : 0);
+
+		_openBookSpellSelectedItem += _openBookSpellListOffset;
+		if (_openBookSpellSelectedItem == 12 || (_openBookSpellSelectedItem == 6 && _openBookSpellListOffset == 0))
+			_openBookSpellSelectedItem = 9;
+
+		do {
+			_openBookSpellSelectedItem += v;
+			int s = (_openBookSpellSelectedItem >= 0) ? _openBookSpellSelectedItem : 9;
+			_openBookSpellSelectedItem = (s <= 9) ? s : 0;
+		} while (_openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellSelectedItem] <= 0 && _openBookSpellSelectedItem != 9);
+
+		if (_openBookSpellSelectedItem >= 6) {
+			_openBookSpellListOffset = 6;
+			if (_openBookSpellSelectedItem == 9)
+				_openBookSpellSelectedItem = 6;
+			else
+				_openBookSpellSelectedItem -= 6;
+		} else {
+			_openBookSpellListOffset = 0;
+		}
+
+		if (_openBookSpellListOffset == 6 && _openBookAvailableSpells[_openBookSpellLevel * 10 + 6] <= 0)
+			_openBookSpellListOffset = 0;
+
+		gui_drawSpellbook();
+
+	} else {
+		if (listIndex == 7 || _openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellListOffset + listIndex] > 0) {
+			if (listIndex < 6) {
+				if (_openBookSpellListOffset + listIndex < 9)
+					_openBookSpellSelectedItem= listIndex;
+				else if (listIndex != 7)
+					return button->index;
+			} else if (listIndex != 7) {
+				return button->index;
+			}
+
+			if (_openBookSpellSelectedItem < 6 && ((_openBookSpellSelectedItem + _openBookSpellListOffset) < 9)) {
+				if (_characters[_openBookChar].disabledSlots & 4)
+					return button->index;
+
+				gui_drawSpellbook();
+
+				int s = _openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellListOffset + _openBookSpellSelectedItem];
+				if (_openBookType == 1)
+					s += _mageSpellListSize;
+
+				castSpell(s, 0);
+
+			} else if ((_openBookSpellSelectedItem == 6 && listIndex == 7) || (_openBookSpellSelectedItem != 6 && listIndex == 6) ) {
+				Button b;
+				clickedSpellbookAbort(&b);
+			}
+		}
+	}
+
+	_characters[_openBookChar].slotStatus[2] = _openBookSpellSelectedItem;
+	_characters[_openBookChar].slotStatus[4] = _openBookSpellListOffset;
+	return button->index;
+}
+
+int EobCoreEngine::clickedCastSpellOnCharacter(Button *button) {
+	_activeSpellCaster = button->arg;
+
+	if (_activeSpellCaster == 255) {
+		_txt->printMessage(_magicStrings3[1]);
+		snd_playSoundEffect(79);
+		if (_castScrollSlot) {
+			gui_updateSlotAfterScrollUse();
+		} else {
+			gui_toggleButtons();
+			gui_drawSpellbook();
+		}
+	} else {
+		if (_characters[_activeSpellCaster].flags & 1)
+			startSpell(_activeSpell);
+	}
+
+	return button->index;
+}
+
+int EobCoreEngine::clickedInventoryNextPage(Button *button) {
+	if (_currentControlMode == 2) {
+		gui_setInventoryButtons();
+		_currentControlMode = 1;
+	} else {
+		gui_setStatsListButtons();
+		_currentControlMode = 2;
+	}
+
+	gui_drawCharPortraitWithStats(_updateCharNum);
+	return button->index;
+}
+
+int EobCoreEngine::clickedPortraitRestore(Button *button) {
+	_currentControlMode = 0;
+	_screen->_curPage = 2;
+	_screen->copyRegion(0, 0, 0, 0, 144, 168, 5, _screen->_curPage, Screen::CR_NO_P_CHECK);
+	gui_drawAllCharPortraitsWithStats();
+	_screen->_curPage = 0;
+	_screen->copyRegion(0, 0, 176, 0, 144, 168, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	gui_setPlayFieldButtons();
+	return button->index;
+}
+
+int EobCoreEngine::clickedUpArrow(Button *button) {
+	int b = calcNewBlockPositionAndTestPassability(_currentBlock, _currentDirection);
+
+	if (b == -1) {
+		notifyBlockNotPassable();
+	} else {
+		moveParty(b);
+		_sceneDefaultUpdate = 1;
+	}
+
+	return button->index;
+}
+
+int EobCoreEngine::clickedDownArrow(Button *button) {
+	int b = calcNewBlockPositionAndTestPassability(_currentBlock, (_currentDirection + 2) & 3);
+
+	if (b == -1) {
+		notifyBlockNotPassable();
+	} else {
+		moveParty(b);
+		_sceneDefaultUpdate = 1;
+	}
+
+	return button->index;
+}
+
+int EobCoreEngine::clickedLeftArrow(Button *button) {
+	int b = calcNewBlockPositionAndTestPassability(_currentBlock, (_currentDirection - 1) & 3);
+
+	if (b == -1) {
+		notifyBlockNotPassable();
+	} else {
+		moveParty(b);
+		_sceneDefaultUpdate = 1;
+	}
+
+	return button->index;
+}
+
+int EobCoreEngine::clickedRightArrow(Button *button) {
+	int b = calcNewBlockPositionAndTestPassability(_currentBlock, (_currentDirection + 1) & 3);
+
+	if (b == -1) {
+		notifyBlockNotPassable();
+	} else {
+		moveParty(b);
+		_sceneDefaultUpdate = 1;
+	}
+
+	return button->index;
+}
+
+int EobCoreEngine::clickedTurnLeftArrow(Button *button) {
+	_currentDirection = (_currentDirection - 1) & 3;
+	//_keybControlUnk = -1;
+	_sceneDefaultUpdate = 1;
+	_sceneUpdateRequired = true;
+	return button->index;
+}
+
+int EobCoreEngine::clickedTurnRightArrow(Button *button) {
+	_currentDirection = (_currentDirection + 1) & 3;
+	//_keybControlUnk = -1;
+	_sceneDefaultUpdate = 1;
+	_sceneUpdateRequired = true;
+	return button->index;
+}
+
+int EobCoreEngine::clickedAbortCharSwitch(Button *button) {
+	_timer->disable(0);
+	int c = _exchangeCharacterId;
+	_exchangeCharacterId = -1;
+	gui_drawCharPortraitWithStats(c);
+	gui_setPlayFieldButtons();
+	return button->index;
+}
+
+int EobCoreEngine::clickedSceneThrowItem(Button *button) {
+	if (!_itemInHand)
+		return button->index;
+
+	if (launchObject(_updateCharNum, _itemInHand, _currentBlock, _dropItemDirIndex[(_currentDirection << 2) + button->arg], _currentDirection, _items[_itemInHand].type)) {
+		setHandItem(0);
+		_sceneUpdateRequired = true;
+	}
+
+	return button->index;
+}
+
+int EobCoreEngine::clickedSceneSpecial(Button *button) {
+	_clickedSpecialFlag = 0x40;
+	return specialWallAction(calcNewBlockPosition(_currentBlock, _currentDirection), _currentDirection);
+}
+
+int EobCoreEngine::clickedSpellbookAbort(Button *button) {
+	_updateFlags = 0;
+	_screen->copyRegion(0, 0, 64, 121, 112, 56, 10, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	gui_drawCompass(true);
+	gui_toggleButtons();
+	return button->index;
+}
+
+int EobCoreEngine::clickedSpellbookScroll(Button *button) {
+	if (_openBookAvailableSpells[_openBookSpellLevel * 10] > 0) {
+		_openBookSpellListOffset ^= 6;
+		_openBookSpellSelectedItem = 0;
+	} else {
+		_openBookSpellListOffset = 6;
+	}
+
+	_characters[_openBookChar].slotStatus[2] = _openBookSpellSelectedItem;
+	_characters[_openBookChar].slotStatus[4] = _openBookSpellListOffset;
+
+	gui_drawSpellbook();
+
+	return button->index;
+}
+
+int EobCoreEngine::clickedUnk(Button *button) {
+	return button->index;
+}
+
+void EobCoreEngine::gui_processCharPortraitClick(int index) {
+	if (index == _updateCharNum)
+		return;
+
+	int a = _updateCharNum;
+	_updateCharNum = index;
+
+	gui_drawCharPortraitWithStats(a);
+	gui_drawCharPortraitWithStats(index);
+}
+
+void EobCoreEngine::gui_processWeaponSlotClickLeft(int charIndex, int slotIndex) {
+	int itm = _characters[charIndex].inventory[slotIndex];
+	if (_items[itm].flags & 0x20)
+		return;
+
+	int ih = _itemInHand;
+	int t = _items[ih].type;
+	uint16 v = (ih) ? _itemTypes[t].invFlags : 0xffff;
+
+	if (v & _slotValidationFlags[slotIndex]) {
+		setHandItem(itm);
+		_characters[charIndex].inventory[slotIndex] = ih;
+		gui_drawCharPortraitWithStats(charIndex);
+	}
+
+	recalcArmorClass(charIndex);
+}
+
+void EobCoreEngine::gui_processWeaponSlotClickRight(int charIndex, int slotIndex) {
+	const char * const *strs = &_itemExtraStrings[_flags.gameID == GI_EOB1 ? 17 : (_flags.lang == Common::DE_DEU ? 26 : 22)];
+
+	if (!testCharacter(charIndex, 0x0d))
+		return;
+
+	uint16 itm = _characters[charIndex].inventory[slotIndex];
+	int wslot = slotIndex < 2 ? slotIndex : -1;
+
+	if (slotIndex < 2 && (!validateWeaponSlotItem(charIndex, slotIndex) || (!_currentControlMode && (_characters[charIndex].disabledSlots & (1 << slotIndex)))))
+		return;
+
+	if (!itemUsableByCharacter(charIndex, itm))
+		_txt->printMessage(strs[0], -1, _characters[charIndex].name);
+
+	if (!itm && slotIndex > 1)
+		return;
+
+	int8 tp = _items[itm].type;
+	int8 vl = _items[itm].value;
+	uint8 ep = _itemTypes[tp].extraProperties & 0x7f;
+
+	switch (ep) {
+		case 0:
+		case 16:
+			// Item automatically used when worn
+			_txt->printMessage(strs[1]);
+			break;
+
+		case 1:
+		case 2:
+		case 3:
+			// Weapons
+			if (!_currentControlMode)
+				useSlotWeapon(charIndex, slotIndex, itm);
+			break;
+
+		case 4:
+		case 8:
+		case 12:
+		case 13:
+		case 15:
+			// Item not used that way
+			_txt->printMessage(strs[2]);
+			break;
+
+		case 5:
+		case 6:
+			// Cleric holy symbol / mage spell book
+			if (!_currentControlMode)
+				useMagicBookOrSymbol(charIndex, ep == 6 ? 1 : 0);
+			break;
+
+		case 7:
+			// Food ration
+			/* don't do anything if mouse control is enabled */
+			//eatItemInHand(charIndex);
+			break;
+
+		case 10:
+			if (_flags.gameID == GI_EOB1)
+				vl += _clericSpellOffset;
+		case 9:
+			// Mage/Cleric Scroll
+			if (!_currentControlMode)
+				useMagicScroll(charIndex, vl, wslot);
+			break;
+
+		case 11:
+			// Letters, Notes, Maps
+			displayParchment(vl);
+			break;
+
+		case 14:
+			// Potion
+			usePotion(charIndex, wslot);
+			break;
+
+		case 18:
+			ep = ep;
+			break;
+
+		case 19:
+			// eob2 horn
+			ep = ep;
+			break;
+
+		case 20:
+			if (vl == 1)
+				inflictCharacterDamage(charIndex, 200);
+			else
+				useMagicScroll(charIndex, 55, wslot);
+			deleteInventoryItem(charIndex, wslot);
+			break;
+
+		default:
+			break;
+	}
+
+	if (ep == 1 && charIndex >= 2)
+		return;
+
+	_lastUsedItem = itm;
+	runLevelScript(calcNewBlockPosition(_currentBlock, _currentDirection), 0x100);
+	_lastUsedItem = 0;
+}
+
+void EobCoreEngine::gui_processInventorySlotClick(int slot) {
+	int itm = _characters[_updateCharNum].inventory[slot];
+	int ih = _itemInHand;
+	if (!validateInventorySlotForItem(ih, _updateCharNum, slot))
+		return;
+
+	if (slot == 16) {
+		if (ih) {
+			setItemPosition(&_characters[_updateCharNum].inventory[16], -2, ih, 0);
+			gui_drawInventoryItem(slot, 1, 0);
+			setHandItem(0);
+
+		} else {
+			itm = getQueuedItem(&_characters[_updateCharNum].inventory[16], 0, -1);
+			gui_drawInventoryItem(slot, 1, 0);
+			setHandItem(itm);
+		}
+
+	} else {
+		setHandItem(itm);
+		_characters[_updateCharNum].inventory[slot] = ih;
+		gui_drawInventoryItem(slot, 1, 0);
+		recalcArmorClass(_updateCharNum);
+	}
+}
+
+GUI_Eob::GUI_Eob(EobCoreEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) {
+	_scrollUpFunctor = _scrollDownFunctor = BUTTON_FUNCTOR(GUI_Eob, this, 0);
+
+	_redrawButtonFunctor = BUTTON_FUNCTOR(GUI, this, &GUI::redrawButtonCallback);
+	_redrawShadedButtonFunctor = BUTTON_FUNCTOR(GUI, this, &GUI::redrawShadedButtonCallback);
+
+	_specialProcessButton = _backupButtonList = 0;
+	_flagsMouseLeft = _flagsMouseRight = _flagsModifier = 0;
+	_backupButtonList = 0;
+	_progress = 0;
+	_prcButtonUnk3 = 1;
+	_cflag = 0xffff;
+
+	_menuLineSpacing = 0;
+	_menuUnk1 = 0;
+	_menuLastInFlags = 0;
+	_menuCur = 0;
+	_menuNumItems = 0;
+}
+
+void GUI_Eob::processButton(Button *button) {
+	if (!button->data0Val1 && !button->data2Val1 && !button->data1Val1)
+		return;
+
+	if ((button->flags & 0x18) == 0x18)
+		return;
+
+	int sd = button->dimTableIndex;
+	const ScreenDim *dm = _screen->getScreenDim(sd);
+
+	int fx = button->x;
+	if (fx < 0)
+		fx += (dm->w << 3);
+
+	int sx = fx + (dm->sx << 3);
+
+	int fy = button->y;
+	if (fy < 0)
+		fy += dm->h;
+
+	int sy = fy + dm->sy;
+
+	uint16 fw = button->width;
+	uint16 fh = button->height;
+
+	uint8 col1 = button->data1Val1;
+	uint8 col2 = button->data1Val3;
+
+	int fx2 = sx + fw - 1;
+	int fy2 = sy + fh - 1;
+
+	if (button->flags2 & 1) {
+		if (button->data1Val1 == 1) {
+			if (button->data0Val1 == 1) {
+				_screen->drawShape(_screen->_curPage, button->data1ShapePtr, fx, fy, sd);
+			} else if (button->data0Val1 == 2) {
+				if (!(button->flags2 & 4))
+					_screen->printText((const char*) button->data1ShapePtr, sx, sy, col1, col2);
+			} else if (button->data0Val1 == 3) {
+				// nullsub (at least EOBII)
+			} else if (button->data0Val1 == 4) {
+				if (button->data1Callback)
+					(*button->data1Callback.get())(button);
+			}
+		} else if (button->data1Val1 == 2) {
+			if (!(button->flags2 & 4))
+				_screen->drawBox(sx, sy, fx2, fy2, col1);
+		} else if (button->data1Val1 == 3) {
+			// nullsub (at least EOBII)
+		} else if (button->data1Val1 == 4) {
+			if (button->data1Callback)
+				(*button->data1Callback.get())(button);
+		}
+	}
+
+	if (button->flags2 & 4) {
+		if (button->data2Val1 == 1) {
+			if (button->data0Val1 == 1) {
+				_screen->drawShape(_screen->_curPage, button->data2ShapePtr, fx, fy, sd);
+			} else if (button->data0Val1 == 2) {
+				if (button->flags2 & 1)
+					_screen->printText((const char*) button->data2ShapePtr, sx, sy, button->data3Val2, button->data3Val3);
+				else
+					_screen->printText((const char*) button->data2ShapePtr, sx, sy, button->data2Val2, button->data2Val3);
+			} else if (button->data0Val1 == 3) {
+				// nullsub (at least EOBII)
+			} else if (button->data0Val1 == 4) {
+				if (button->data2Callback)
+					(*button->data2Callback.get())(button);
+			}
+		} else if (button->data2Val1 == 2) {
+			_screen->drawBox(sx, sy, fx2, fy2, (button->flags2 & 1) ? button->data3Val2 : button->data2Val2);
+		} else if (button->data2Val1 == 3) {
+			// nullsub (at least EOBII)
+		} else if (button->data2Val1 == 4) {
+			if (button->data2Callback)
+				(*button->data2Callback.get())(button);
+		}
+	}
+
+	if (!(button->flags2 & 5)) {
+		if (button->data0Val1 == 1) {
+			_screen->drawShape(_screen->_curPage, button->data0ShapePtr, fx, fy, sd);
+		} else if (button->data0Val1 == 2) {
+			_screen->printText((const char*) button->data0ShapePtr, sx, sy, button->data0Val2, button->data0Val3);
+		} else if (button->data0Val1 == 3) {
+			// nullsub (at least EOBII)
+		} else if (button->data0Val1 == 4) {
+			if (button->data0Callback)
+				(*button->data0Callback.get())(button);
+		} else if (button->data0Val1 == 5) {
+			_screen->drawBox(sx, sy, fx2, fy2, button->data0Val2);
+		} else {
+			if (!button->data0Val1) {
+				if(button->data1Val1 == 2 || button->data2Val1 == 2) {
+					_screen->drawBox(sx, sy, fx2, fy2, button->data0Val2);
+				} else {
+					// nullsub (at least EOBII)
+				}
+			}
+		}
+	}
+}
+
+int GUI_Eob::processButtonList(Kyra::Button *buttonList, uint16 inputFlags, int8 mouseWheel) {
+	_progress = 0;
+	uint16 in = inputFlags & 0xff;
+	uint16 buttonReleaseFlag = 0;
+	bool clickEvt = false;
+
+	_flagsMouseLeft = (_vm->_mouseClick == 1) ? 2 : 4;
+	_flagsMouseRight = (_vm->_mouseClick == 2) ? 2 : 4;
+	_vm->_mouseClick = 0;
+
+	if (in >= 199 && in <= 202) {
+		buttonReleaseFlag = (inputFlags & 0x800) ? 3 : 1;
+		if (in < 201)
+			_flagsMouseLeft = buttonReleaseFlag;
+		else
+			_flagsMouseRight = buttonReleaseFlag;
+
+		////////////////////////////
+		if (!buttonList && !(inputFlags & 0x800))
+			return inputFlags & 0xff;
+		////////////////////////////
+
+		inputFlags = 0;
+		clickEvt = true;
+	} else {
+		inputFlags &= 0xff;
+	}
+
+	uint16 result = 0;
+	bool runLoop = true;
+
+	if (!buttonList)
+		return inputFlags;
+
+	if (_vm->_buttonListChanged || (buttonList != _backupButtonList)) {
+		_backupButtonList = buttonList;
+		_flagsModifier = 0;
+
+		while (runLoop) {
+			processButton(buttonList);
+			_flagsModifier |= (buttonList->flags & 0xAA04);
+
+			// UNUSED
+			//if (buttonList->flags2 & 0x20) {
+				// if (_processButtonListExtraCallback)
+				//	this->*_processButtonListExtraCallback(buttonList);
+			//}
+
+			if (buttonList->nextButton)
+				buttonList = buttonList->nextButton;
+			else
+				runLoop = false;
+		}
+
+		_vm->_buttonListChanged = false;
+
+		_specialProcessButton = 0;
+		_prcButtonUnk3 = 1;
+		_cflag = 0xffff;
+	}
+
+	int sd = 0;
+	const ScreenDim *dm = _screen->getScreenDim(sd);
+
+	int x1 = dm->sx << 3;
+	int y1 = dm->sy;
+	int w1 = dm->w << 3;
+	int h1 = dm->h;
+
+	uint16 v8 = 0;
+	uint16 v18 = 0;
+	uint16 v16 = 0;
+
+	if (_specialProcessButton)
+		buttonList = _specialProcessButton;
+
+	while (runLoop) {
+		if (buttonList->flags & 8) {
+			buttonList = buttonList->nextButton;
+			runLoop = buttonList ? true : false;
+			continue;
+		}
+
+		int vc = 0;
+		int v6 = 0;
+		uint16 iFlag = buttonList->index | 0x8000;
+		uint16 flgs2 = buttonList->flags2;
+		uint16 flgs = buttonList->flags;
+
+		if (flgs2 & 1)
+			flgs2 |= 8;
+		else
+			flgs2 &= 0xfff7;
+
+		if (flgs2 & 4)
+			flgs2 |= 0x10;
+		else
+			flgs2 &= 0xffef;
+
+		uint16 vL = 0;
+		uint16 vR = 0;
+
+		if (inputFlags) {
+			if (buttonList->keyCode == in) {
+				_progress = 1;
+				_flagsMouseLeft = 1;
+				flgs2 ^= 1;
+				result = iFlag;
+				v6 = 1;
+			} else if (buttonList->keyCode2 == in) {
+				_progress = 2;
+				_flagsMouseRight = 1;
+				result = iFlag;
+				v6 = 1;
+			}
+		} else if (_flagsModifier || clickEvt) {
+			vL = flgs & 0xf00;
+			vR = flgs & 0xf000;
+
+			if (_prcButtonUnk3) {
+				if (sd != buttonList->dimTableIndex) {
+					sd = buttonList->dimTableIndex;
+					dm = _screen->getScreenDim(sd);
+					x1 = dm->sx << 3;
+					y1 = dm->sy;
+					w1 = dm->w << 3;
+					h1 = dm->h;
+				}
+
+				int x2 = x1;
+				if (buttonList->x < 0)
+					x2 += w1;
+				x2 += buttonList->x;
+
+				int y2 = y1;
+				if (buttonList->y < 0)
+					y2 += h1;
+				y2 += buttonList->y;
+
+				if (_vm->_mouseX >= x2 && _vm->_mouseX <= (x2 + buttonList->width) && _vm->_mouseY >= y2 && _vm->_mouseY <= (y2 + buttonList->height)) {
+					flgs2 |= 2;
+
+					if (vL) {
+						switch (_flagsMouseLeft - 1) {
+						case 0:
+							v18 = 1;
+
+							if ((flgs & 4) && buttonList->data2Val1) {
+								flgs2 |= 4;
+								vc = 1;
+							} else {
+								flgs2 &= 0xfffb;
+							}
+
+							if (flgs & 0x100) {
+								v6 = 1;
+								if (!(flgs & 1)) {
+									flgs2 ^= 1;
+									result = iFlag;
+								}
+							}
+
+							if (flgs & 0x40) {
+								_specialProcessButton = buttonList;
+								v8 = 1;
+							}
+
+							_cflag = flgs;
+							break;
+
+						case 1:
+							if (flgs != _cflag)
+								break;
+
+							if ((flgs & 4) && buttonList->data2Val1) {
+								flgs2 |= 4;
+								vc = 1;
+							} else {
+								flgs2 &= 0xfffb;
+							}
+
+							if (!(flgs & 0x200))
+								break;
+
+							v6 = 1;
+
+							if (flgs & 1)
+								break;
+
+							flgs2 |= 1;
+							result = iFlag;
+							break;
+
+						case 2:
+							if (_cflag != flgs)
+								break;
+
+							if (flgs & 0x400) {
+								v6 = 1;
+								if (flgs & 1) {
+									flgs2 ^= 1;
+									result = iFlag;
+								}
+							}
+
+							if ((flgs & 2) && (flgs2 & 1))
+								flgs2 &= 0xfffe;
+							break;
+
+						case 3:
+							if ((flgs & 4) || (!buttonList->data2Val1))
+								flgs2 &= 0xfffb;
+							else
+								flgs2 |= 4;
+
+							if (flgs & 0x800) {
+								v6 = 1;
+								break;
+							}
+
+							if ((flgs & 2) && (flgs2 & 1))
+								flgs2 &= 0xfffe;
+							break;
+
+						default:
+							break;
+						}
+					}
+
+					if (vR && !v6 && !vc) {
+						switch (_flagsMouseRight - 1) {
+						case 0:
+							v18 = 1;
+
+							if ((flgs & 4) && buttonList->data2Val1)
+								flgs2 |= 4;
+							else
+								flgs2 &= 0xfffb;
+
+							if (flgs & 0x1000) {
+								v6 = 1;
+								if (!(flgs & 1)) {
+									flgs2 ^= 1;
+									result = iFlag;
+								}
+							}
+
+							if (flgs & 0x40) {
+								_specialProcessButton = buttonList;
+								v8 = 1;
+							}
+
+							_cflag = flgs;
+							break;
+
+						case 1:
+							if (flgs != _cflag)
+								break;
+
+							if ((flgs & 4) && buttonList->data2Val1)
+								flgs2 |= 4;
+							else
+								flgs2 &= 0xfffb;
+
+							if (!(flgs & 0x2000))
+								break;
+
+							v6 = 1;
+
+							if (flgs & 1)
+								break;
+
+							flgs2 |= 1;
+							result = iFlag;
+							break;
+						case 2:
+							if (_cflag != flgs)
+								break;
+
+							if (flgs & 0x4000) {
+								v6 = 1;
+								if (flgs & 1) {
+									flgs2 ^= 1;
+									result = iFlag;
+								}
+							}
+
+							if ((flgs & 2) && (flgs2 & 1))
+								flgs2 &= 0xfffe;
+							break;
+
+						case 3:
+							if ((flgs & 4) || (!buttonList->data2Val1))
+								flgs2 &= 0xfffb;
+							else
+								flgs2 |= 4;
+
+							if (flgs & 0x8000) {
+								v6 = 1;
+								break;
+							}
+
+							if ((flgs & 2) && (flgs2 & 1))
+								flgs2 &= 0xfffe;
+							break;
+
+						default:
+							break;
+						}
+					}
+				} else { // if (_vm->_mouseX >= x2 && _vm->_mouseX <= (x2 + buttonList->width)....)
+					flgs2 &= 0xfff9;
+
+					if ((flgs & 0x40) && (!(flgs & 0x80)) && _specialProcessButton && !v8) {
+						static const uint16 flagsTable[] = { 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000 };
+
+						if (vL) {
+							v16 = flagsTable[_flagsMouseLeft - 1];
+							if (v16 & flgs)
+								v6 = 1;
+						}
+
+						if (vR && !v6) {
+							v16 = flagsTable[_flagsMouseRight + 3];
+							if (v16 & flgs)
+								v6 = 1;
+						}
+
+						if (!v6) {
+							_specialProcessButton = 0;
+							_prcButtonUnk3 = 1;
+						}
+					}
+
+					if ((flgs & 2) && (flgs2 & 1))
+						flgs2 &= 0xfffe;
+				} // end if (_vm->_mouseX >= x2 && _vm->_mouseX <= (x2 + buttonList->width)....)
+			} // end if (_prcButtonUnk3)
+		} // end if (_flagsModifier || clickEvt)
+
+		buttonList->flags = flgs;
+		buttonList->flags2 = flgs2;
+
+		bool f21 = (flgs2 & 8) ? true : false;
+		bool f22 = (flgs2 & 1) ? true : false;
+		bool f23 = (flgs2 & 0x10) ? true : false;
+		bool f24 = (flgs2 & 4) ? true : false;
+
+		if (f21 != f22 || f23 != f24)
+			processButton(buttonList);
+
+		if (v6 && buttonList->buttonCallback)
+			runLoop = ((*buttonList->buttonCallback.get())(buttonList)) ? false : true;
+
+		if ((flgs2 & 2) && (flgs & 0x20))
+			runLoop = false;
+
+		if (_specialProcessButton && ((vL && _flagsMouseLeft == 3) || (vR && _flagsMouseRight == 3))) {
+			_specialProcessButton = 0;
+			_prcButtonUnk3 = 1;
+			runLoop = false;
+		}
+
+		if (_specialProcessButton && !v8)
+			runLoop = false;
+
+		buttonList = buttonList->nextButton;
+		if (!buttonList)
+			runLoop = false;
+	};
+
+	if ((_flagsMouseLeft == 1 || _flagsMouseRight == 1) && !v18)
+		_cflag = 0xffff;
+
+	if (!result)
+		result = inputFlags;
+
+	return result;
+}
+
+void GUI_Eob::setupMenu(int sd, int maxItem, const char *const *strings, int32 menuItemsMask, int unk, int lineSpacing) {
+	initMenuItemsMask(sd, maxItem, menuItemsMask, unk);
+
+	const ScreenDim *dm = _screen->getScreenDim(19 + sd);
+	int x = (_screen->_curDim->sx + dm->sx) << 3;
+	int y = _screen->_curDim->sy + dm->sy;
+
+	int v = getMenuItem(_menuCur, menuItemsMask, unk);
+
+	for (int i = 0; i < _menuNumItems; i++) {
+		int item = getMenuItem(i, menuItemsMask, unk);
+		int ty = y + i * (lineSpacing + _screen->getFontHeight());
+		_screen->printShadedText(strings[item], x, ty, dm->unkA, 0);
+		if (item == v)
+			_screen->printText(strings[item], x, ty, dm->unkC, 0);
+	}
+
+	_screen->updateScreen();
+	_menuLineSpacing = lineSpacing;
+	_menuUnk1 = 0;
+	_menuLastInFlags = 0;
+	_vm->removeInputTop();
+}
+
+int GUI_Eob::handleMenu(int sd, const char *const *strings, void *b, int32 menuItemsMask, int unk) {
+	const ScreenDim *dm = _screen->getScreenDim(19 + sd);
+	int h = _menuNumItems - 1;
+	int currentItem = _menuCur % _menuNumItems;
+	int newItem = currentItem;
+	int result = -1;
+	int lineH = (_menuLineSpacing + _screen->getFontHeight());
+	int lineS1 = _menuLineSpacing >> 1;
+	int x = (_screen->_curDim->sx + dm->sx) << 3;
+	int y = _screen->_curDim->sy + dm->sy;
+
+	int inFlag = _vm->checkInput(0, false, 0) & 0x8ff;
+	_vm->removeInputTop();
+	Common::Point mousePos = _vm->getMousePos();
+
+	int x1 = (_screen->_curDim->sx << 3) + (dm->sx * _screen->getFontWidth());
+	int y1 = _screen->_curDim->sy + dm->sy - lineS1;
+	int x2 = x1 + (dm->w * _screen->getFontWidth()) - 1;
+	int y2 = y1 + _menuNumItems * lineH - 1;
+	if (_vm->posWithinRect(mousePos.x, mousePos.y, x1, y1, x2, y2))
+		newItem = (mousePos.y - y1) / lineH;
+
+	if (inFlag == 199 || inFlag == 201) {
+		if (_vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, x1, y1, x2, y2))
+			result = newItem = (_vm->_mouseY - y1) / lineH;
+	} else if (inFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inFlag == _vm->_keyMap[Common::KEYCODE_KP5]) {
+		result = newItem;
+	} else if (inFlag == _vm->_keyMap[Common::KEYCODE_HOME] || inFlag == _vm->_keyMap[Common::KEYCODE_KP7] || inFlag == _vm->_keyMap[Common::KEYCODE_PAGEUP] || inFlag == _vm->_keyMap[Common::KEYCODE_KP9]) {
+		newItem = 0;
+	} else if (inFlag == _vm->_keyMap[Common::KEYCODE_END] || inFlag == _vm->_keyMap[Common::KEYCODE_KP1] || inFlag == _vm->_keyMap[Common::KEYCODE_PAGEDOWN] || inFlag == _vm->_keyMap[Common::KEYCODE_KP3]) {
+		newItem = h;
+	} else if (inFlag == _vm->_keyMap[Common::KEYCODE_UP] || inFlag == _vm->_keyMap[Common::KEYCODE_KP8]) {
+		if (--newItem < 0)
+			newItem = h;
+	} else if (inFlag == _vm->_keyMap[Common::KEYCODE_DOWN] || inFlag == _vm->_keyMap[Common::KEYCODE_KP2]) {
+		if (++newItem > h)
+			newItem = 0;
+	} else {
+		_menuLastInFlags = inFlag;
+	}
+
+	if (newItem != currentItem) {
+		_screen->printText(strings[getMenuItem(currentItem, menuItemsMask, unk)], x, y + currentItem * lineH , dm->unkA, 0);
+		_screen->printText(strings[getMenuItem(newItem,  menuItemsMask, unk)], x, y + newItem * lineH , dm->unkC, 0);
+		_screen->updateScreen();
+	}
+
+	if (result != -1) {
+		result = getMenuItem(result, menuItemsMask, unk);
+		menuFlashSelection(strings[result], x, y + newItem * lineH, dm->unkA, dm->unkC, 0);
+	}
+
+	_menuCur = newItem;
+
+	return result;
+}
+
+void GUI_Eob::initMenuItemsMask(int menuId, int maxItem, int32 menuItemsMask, int unk) {
+	if (menuItemsMask == -1) {
+		_menuNumItems = _screen->getScreenDim(19 + menuId)->h;
+		_menuCur = _screen->getScreenDim(19 + menuId)->unk8;
+		return;
+	}
+
+	_menuNumItems = 0;
+
+	for (int i = 0; i < maxItem; i++) {
+		if (menuItemsMask & (1 << (i + unk)))
+			_menuNumItems++;
+	}
+
+	_menuCur = 0;
+}
+
+int GUI_Eob::getMenuItem(int index, int32 menuItemsMask, int unk) {
+	if (menuItemsMask == -1)
+		return index;
+
+	int res = 0;
+	int i = index;
+
+	for (; i; res++) {
+		if (menuItemsMask & (1 << (res + unk)))
+			i--;
+	}
+
+	while (!(menuItemsMask & (1 << (res + unk))))
+		res++;
+
+	return res;
+}
+
+void GUI_Eob::menuFlashSelection(const char *str, int x, int y, int color1, int color2, int color3) {
+	for (int i = 0; i < 3; i++) {
+		_screen->printText(str, x, y, color2, color3);
+		_screen->updateScreen();
+		_vm->_system->delayMillis(32);
+		_screen->printText(str, x, y, color1, color3);
+		_screen->updateScreen();
+		_vm->_system->delayMillis(32);
+	}
+}
+
+int GUI_Eob::getTextInput(char *dest, int x, int y, int destMaxLen, int textColor1, int textColor2, int cursorColor) {
+	uint8 cursorState = 1;
+	char sufx[] = " ";
+
+	int len = strlen(dest);
+	if (len > destMaxLen) {
+		len = destMaxLen;
+		dest[destMaxLen] = 0;
+	}
+
+	int pos = len;
+	if (len >= destMaxLen)
+		pos--;
+
+	_screen->copyRegion((x - 1) << 3, y, 0, 191, (destMaxLen + 2) << 3, 9, 0, 2, Screen::CR_NO_P_CHECK);
+	_screen->printShadedText(dest, x << 3, y, textColor1, textColor2);
+
+	uint32 next = _vm->_system->getMillis() + 2 * _vm->_tickLength;
+	sufx[0] = (pos < len) ? dest[pos] : 32;
+	_screen->printText(sufx, (x + pos) << 3, y, textColor1, cursorColor);
+
+	int in = 0;
+
+	do {
+		in = 0;
+		_keyPressed.reset();
+
+		while (!in) {
+			if (next <= _vm->_system->getMillis()) {
+				if (cursorState) {
+					_screen->copyRegion((pos + 1) << 3, 191, (x + pos) << 3, y, 8, 9, 2, 0, Screen::CR_NO_P_CHECK);
+					_screen->printShadedText(sufx, (x + pos) << 3, y, textColor1, textColor2);
+				} else {
+					_screen->printText(sufx, (x + pos) << 3, y, textColor1, cursorColor);
+				}
+
+				_screen->updateScreen();
+				cursorState ^= 1;
+				next = _vm->_system->getMillis() + 2 * _vm->_tickLength;
+			}
+
+			_vm->updateInput();
+			for (Common::List<KyraEngine_v1::Event>::const_iterator evt = _vm->_eventList.begin(); evt != _vm->_eventList.end(); ++evt) {
+				if (evt->event.type == Common::EVENT_KEYDOWN) {
+					_keyPressed = evt->event.kbd;
+					in = _keyPressed.ascii;
+				}
+			}
+			_vm->removeInputTop();
+		}
+
+		if (_keyPressed.keycode == Common::KEYCODE_BACKSPACE) {
+			if (pos >= len && len > 0) {
+				dest[--len] = 0;
+				pos--;
+
+			} else if (pos > 0) {
+				for (int i = pos; i < destMaxLen; i++)
+					dest[i - 1] = dest[i];
+				dest[--len] = 0;
+				pos--;
+			}
+
+		} else if (_keyPressed.keycode == Common::KEYCODE_LEFT || _keyPressed.keycode == Common::KEYCODE_KP4) {
+			if (pos > 0)
+				pos--;
+
+		} else if (_keyPressed.keycode == Common::KEYCODE_RIGHT || _keyPressed.keycode == Common::KEYCODE_KP6) {
+			if (pos < len && pos < (destMaxLen - 1))
+				pos++;
+
+		} else if (in > 31 && in < 126) {
+			if (!(in == 32 && pos == 0)) {
+				if (in >= 97 && in <= 122)
+					in -=32;
+
+				if (pos < len) {
+					for (int i = destMaxLen - 1; i >= pos; i--)
+						dest[i + 1] = dest[i];
+
+					dest[pos++] = in;
+
+					if (len == destMaxLen)
+						dest[len] = 0;
+
+				} else {
+					if (pos == destMaxLen) {
+						pos--;
+						len--;
+					}
+
+					dest[pos++] = in;
+					dest[pos] = 0;
+				}
+
+				if (++len > destMaxLen)
+					len = destMaxLen;
+
+				if (pos > (destMaxLen - 1))
+					pos = (destMaxLen - 1);
+			}
+		}
+
+		_screen->copyRegion(0, 191, (x - 1) << 3, y, (destMaxLen + 2) << 3, 9, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->printShadedText(dest, x << 3, y, textColor1, textColor2);
+		sufx[0] = (pos < len) ? dest[pos] : 32;
+
+		if (cursorState)
+			_screen->printText(sufx, (x + pos) << 3, y, textColor1, cursorColor);
+		else
+			_screen->printShadedText(sufx, (x + pos) << 3, y, textColor1, textColor2);
+		_screen->updateScreen();
+
+	} while (_keyPressed.keycode != Common::KEYCODE_RETURN && _keyPressed.keycode != Common::KEYCODE_ESCAPE);
+
+	return _keyPressed.keycode == Common::KEYCODE_ESCAPE ? -1 : len;
+}
+
+#endif // ENABLE_EOB
+
+}	// End of namespace Kyra
+
+#endif // defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h
new file mode 100644
index 0000000..82e9476
--- /dev/null
+++ b/engines/kyra/gui_eob.h
@@ -0,0 +1,130 @@
+/* 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.
+ *
+ */
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#ifndef KYRA_GUI_EOB_H
+#define KYRA_GUI_EOB_H
+
+#include "kyra/gui.h"
+
+#ifdef ENABLE_EOB
+
+namespace Kyra {
+
+class DarkMoonEngine;
+class Screen_Eob;
+
+class GUI_Eob : public GUI {
+	friend class EobCoreEngine;
+	friend class CharacterGenerator;
+public:
+	GUI_Eob(EobCoreEngine *vm);
+
+	void initStaticData() {}
+
+	// button specific
+	void processButton(Button *button);
+	int processButtonList(Button *buttonList, uint16 inputFlags, int8 mouseWheel);
+
+	int redrawShadedButtonCallback(Button *button) { return 0; }
+	int redrawButtonCallback(Button *button) { return 0; }
+
+	void setupMenu(int sd, int maxItem, const char *const *strings, int32 menuItemsMask, int unk, int lineSpacing);
+	int handleMenu(int sd, const char *const *strings, void *b, int32 menuItemsMask, int unk);
+	int getMenuItem(int index, int32 menuItemsMask, int unk);
+	void menuFlashSelection(const char *str, int x, int y, int color1, int color2, int color3);
+
+	int getTextInput(char *dest, int x, int y, int destMaxLen, int textColor1, int textColor2, int cursorColor);
+
+	//int runMenu(Menu &menu);
+
+	// utilities for thumbnail creation
+	void createScreenThumbnail(Graphics::Surface &dst) {}
+
+private:
+	void initMenuItemsMask(int menuId, int maxItem, int32 menuItemsMask, int unk);
+
+	//void backupPage0();
+	//void restorePage0();
+
+	//void setupSavegameNames(Menu &menu, int num);
+	//void printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 flags);
+
+	//int getMenuCenterStringX(const char *str, int x1, int x2);
+
+	int getInput();
+
+	Button *getButtonListData() { return _menuButtons; }
+	Button *getScrollUpButton() { return &_scrollUpButton; }
+	Button *getScrollDownButton() { return &_scrollDownButton; }
+
+	Button::Callback getScrollUpButtonHandler() const { return _scrollUpFunctor; }
+	Button::Callback getScrollDownButtonHandler() const { return _scrollDownFunctor; }
+
+	uint8 defaultColor1() const { return 0xFE; }
+	uint8 defaultColor2() const { return 0x00; }
+
+	const char *getMenuTitle(const Menu &menu) { return 0; }
+	const char *getMenuItemTitle(const MenuItem &menuItem) { return 0; }
+	const char *getMenuItemLabel(const MenuItem &menuItem) { return 0; }
+
+	Button _menuButtons[10];
+	Button _scrollUpButton;
+	Button _scrollDownButton;
+	//Menu _mainMenu, _gameOptions, _audioOptions, _choiceMenu, _loadMenu, _saveMenu, _deleteMenu, _savenameMenu, _deathMenu;
+	//Menu *_currentMenu, *_lastMenu, *_newMenu;
+	//int _menuResult;
+	//char *_saveDescription;
+
+	EobCoreEngine *_vm;
+	Screen_Eob *_screen;
+
+	bool _pressFlag;
+
+	Button *_specialProcessButton;
+	Button *_backupButtonList;
+	uint16 _flagsMouseLeft;
+	uint16 _flagsMouseRight;
+	uint16 _flagsModifier;
+	uint16 _progress;
+	uint16 _prcButtonUnk3; /// ALWAYS 1?? REMOVE ??
+	uint16 _cflag;
+
+	Button::Callback _scrollUpFunctor;
+	Button::Callback _scrollDownFunctor;
+
+	int _menuLineSpacing;
+	int _menuUnk1;
+	int _menuLastInFlags;
+
+	int _menuCur;
+	int _menuNumItems;
+};
+
+}	// End of namespace Kyra
+
+#endif // ENABLE_EOB
+
+#endif
+
+#endif // ENABLE_EOB || ENABLE_LOL
diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp
index 5bef3cd..08ce0bd 100644
--- a/engines/kyra/gui_lol.cpp
+++ b/engines/kyra/gui_lol.cpp
@@ -32,6 +32,7 @@
 #include "common/savefile.h"
 #include "common/system.h"
 #include "common/config-manager.h"
+
 #include "graphics/scaler.h"
 
 #include "base/version.h"
@@ -213,9 +214,9 @@ void LoLEngine::gui_displayCharInventory(int charNum) {
 		}
 
 		if (_flags.use16ColorMode)
-			gui_drawBarGraph(154, 66 + i * 8, 34, 5, b, e, 0x88, 0);
+			gui_drawHorizontalBarGraph(154, 66 + i * 8, 34, 5, b, e, 0x88, 0);
 		else
-			gui_drawBarGraph(154, 64 + i * 10, 34, 5, b, e, 132, 0);
+			gui_drawHorizontalBarGraph(154, 64 + i * 10, 34, 5, b, e, 132, 0);
 	}
 
 	_screen->drawClippedLine(14, 120, 194, 120, 1);
@@ -343,31 +344,6 @@ void LoLEngine::gui_drawCharInventoryItem(int itemIndex) {
 		_screen->drawShape(_screen->_curPage, getItemIconShapePtr(i), x + 1, y + 1, 0, 0);
 }
 
-void LoLEngine::gui_drawBarGraph(int x, int y, int w, int h, int32 cur, int32 max, int col1, int col2) {
-	if (max < 1)
-		return;
-	if (cur < 0)
-		cur = 0;
-
-	int32 e = MIN(cur, max);
-
-	if (!--w)
-		return;
-	if (!--h)
-		return;
-
-	int32 t = (e * w) / max;
-
-	if (!t && e)
-		t++;
-
-	if (t)
-		_screen->fillRect(x, y, x + t - 1, y + h, col1);
-
-	if (t < w && col2)
-		_screen->fillRect(x + t, y, x + w, y + h, col2);
-}
-
 void LoLEngine::gui_drawAllCharPortraitsWithStats() {
 	int numChars = countActiveCharacters();
 	if (!numChars)
@@ -460,17 +436,6 @@ void LoLEngine::gui_drawCharPortraitWithStats(int charNum) {
 	_screen->setFont(tmpFid);
 }
 
-void LoLEngine::gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor) {
-	w--; h--;
-	if (fillColor != -1)
-		_screen->fillRect(x + 1, y + 1, x + w - 1, y + h - 1, fillColor);
-
-	_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].tempFaceFrame)
 		_characters[charNum].curFaceFrame = _characters[charNum].tempFaceFrame;
@@ -853,19 +818,6 @@ void LoLEngine::gui_triggerEvent(int eventType) {
 	_preserveEvents = true;
 }
 
-void LoLEngine::removeInputTop() {
-	if (!_eventList.empty()) {
-		if (_eventList.begin()->event.type == Common::EVENT_LBUTTONDOWN)
-			_gui->_mouseClick = 1;
-		else if (_eventList.begin()->event.type == Common::EVENT_RBUTTONDOWN)
-			_gui->_mouseClick = 2;
-		else
-			_gui->_mouseClick = 0;
-
-		_eventList.erase(_eventList.begin());
-	}
-}
-
 void LoLEngine::gui_enableDefaultPlayfieldButtons() {
 	gui_resetButtonList();
 	gui_initButtonsFromList(_buttonList1);
@@ -911,19 +863,6 @@ void LoLEngine::gui_enableCharInventoryButtons(int charNum) {
 	gui_setFaceFramesControlButtons(21, 0);
 }
 
-void LoLEngine::gui_resetButtonList() {
-	for (uint i = 0; i < ARRAYSIZE(_activeButtonData); ++i)
-		_activeButtonData[i].nextButton = 0;
-
-	gui_notifyButtonListChanged();
-	_activeButtons = 0;
-}
-
-void LoLEngine::gui_initButtonsFromList(const int16 *list) {
-	while (*list != -1)
-		gui_initButton(*list++);
-}
-
 void LoLEngine::gui_setFaceFramesControlButtons(int index, int xOffs) {
 	int c = countActiveCharacters();
 	for (int i = 0; i < c; i++)
@@ -1009,14 +948,6 @@ void LoLEngine::gui_initButton(int index, int x, int y, int val) {
 	b->buttonCallback = _buttonCallbacks[index];
 }
 
-void LoLEngine::gui_notifyButtonListChanged() {
-	if (_gui) {
-		if (!_gui->_buttonListChanged && !_preserveEvents)
-			removeInputTop();
-		_gui->_buttonListChanged = true;
-	}
-}
-
 int LoLEngine::clickedUpArrow(Button *button) {
 	if (button->arg && !_floatingCursorsEnabled)
 		return 0;
@@ -1333,7 +1264,6 @@ int LoLEngine::clickedExitCharInventory(Button *button) {
 int LoLEngine::clickedSceneDropItem(Button *button) {
 	static const uint8 offsX[] = { 0x40, 0xC0, 0x40, 0xC0 };
 	static const uint8 offsY[] = { 0x40, 0x40, 0xC0, 0xC0 };
-	static const uint8 dirIndex[] = { 0, 1, 2, 3, 1, 3, 0, 2, 3, 2, 1, 0, 2, 0, 3, 1 };
 
 	if ((_updateFlags & 1) || !_itemInHand)
 		return 0;
@@ -1348,7 +1278,7 @@ int LoLEngine::clickedSceneDropItem(Button *button) {
 
 	uint16 x = 0;
 	uint16 y = 0;
-	int i = dirIndex[(_currentDirection << 2) + button->arg];
+	int i = _dropItemDirIndex[(_currentDirection << 2) + button->arg];
 
 	calcCoordinates(x, y, block, offsX[i], offsY[i]);
 	setItemPosition(_itemInHand, x, y, 0, 1);
@@ -1917,9 +1847,7 @@ GUI_LoL::GUI_LoL(LoLEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) {
 
 	_specialProcessButton = _backUpButtonList = 0;
 	_flagsModifier = 0;
-	_mouseClick = 0;
 	_sliderSfx = 11;
-	_buttonListChanged = false;
 	_savegameList = 0;
 	_savegameListSize = 0;
 }
@@ -2015,18 +1943,18 @@ int GUI_LoL::processButtonList(Button *buttonList, uint16 inputFlag, int8 mouseW
 	if (!buttonList)
 		return inputFlag & 0x7FFF;
 
-	if (_backUpButtonList != buttonList || _buttonListChanged) {
+	if (_backUpButtonList != buttonList || _vm->_buttonListChanged) {
 		_specialProcessButton = 0;
 
 		_flagsModifier = 0;
-		if (_mouseClick == 1)
+		if (_vm->_mouseClick == 1)
 			_flagsModifier |= 0x200;
-		if (_mouseClick == 2)
+		if (_vm->_mouseClick == 2)
 			_flagsModifier |= 0x2000;
-		_mouseClick = 0;
+		_vm->_mouseClick = 0;
 
 		_backUpButtonList = buttonList;
-		_buttonListChanged = false;
+		_vm->_buttonListChanged = false;
 
 		while (buttonList) {
 			processButton(buttonList);
diff --git a/engines/kyra/gui_lol.h b/engines/kyra/gui_lol.h
index af48740..9c0c4e2 100644
--- a/engines/kyra/gui_lol.h
+++ b/engines/kyra/gui_lol.h
@@ -162,9 +162,7 @@ private:
 
 	Button *_specialProcessButton;
 	Button *_backUpButtonList;
-	bool _buttonListChanged;
 	uint16 _flagsModifier;
-	uint8 _mouseClick;
 
 	int _savegameOffset;
 	int _sliderSfx;
diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
new file mode 100644
index 0000000..4f6982a
--- /dev/null
+++ b/engines/kyra/items_eob.cpp
@@ -0,0 +1,614 @@
+/* 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.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/eobcommon.h"
+#include "kyra/resource.h"
+#include "kyra/sound.h"
+
+namespace Kyra {
+
+void EobCoreEngine::loadItemDefs() {
+	Common::SeekableReadStream *s = _res->createReadStream("item.dat");
+	_numItems = s->readUint16LE();
+
+	for (int i = 0; i < 600; i++)
+		_items[i].block = -1;
+
+	for (int i = 0; i < _numItems; i++) {
+		_items[i].nameUnid = s->readByte();
+		_items[i].nameId = s->readByte();
+		_items[i].flags = s->readByte();
+		_items[i].icon = s->readSByte();
+		_items[i].type = s->readSByte();
+		_items[i].pos = s->readSByte();
+		_items[i].block = s->readSint16LE();
+		_items[i].next = s->readSint16LE();
+		_items[i].prev = s->readSint16LE();
+		_items[i].level = s->readSByte();
+		_items[i].value = s->readSByte();
+	}
+
+	_numItemNames = s->readUint16LE();
+	for (int i = 0; i < _numItemNames; i++)
+		s->read(_itemNames[i], 35);
+
+	delete s;
+
+	s = _res->createReadStream("itemtype.dat");
+	uint16 numTypes = s->readUint16LE();
+
+	_itemTypes = new EobItemType[numTypes];
+	memset(_itemTypes, 0, sizeof(EobItemType) * numTypes);
+
+	for (int i = 0; i < numTypes; i++) {
+		_itemTypes[i].invFlags = s->readUint16LE();
+		_itemTypes[i].handFlags = s->readUint16LE();
+		_itemTypes[i].armorClass = s->readSByte();
+		_itemTypes[i].allowedClasses = s->readSByte();
+		_itemTypes[i].requiredHands = s->readSByte();
+		_itemTypes[i].dmgNumDiceS = s->readSByte();
+		_itemTypes[i].dmgNumPipsS = s->readSByte();
+		_itemTypes[i].dmgIncS = s->readSByte();
+		_itemTypes[i].dmgNumDiceL = s->readSByte();
+		_itemTypes[i].dmgNumPipsL = s->readSByte();
+		_itemTypes[i].dmgIncL = s->readSByte();
+		_itemTypes[i].unk1 = s->readByte();
+		_itemTypes[i].extraProperties = s->readUint16LE();
+	}
+
+	delete s;
+}
+
+Kyra::Item EobCoreEngine::duplicateItem(Item itemIndex) {
+	EobItem *itm = &_items[itemIndex];
+
+	if (itm->block == -1)
+		return 0;
+
+	Item i = 1;
+	bool foundSlot = false;
+
+	for (; i < 600; i++) {
+		if (_items[i].block == -1) {
+			foundSlot = true;
+			break;
+		}
+	}
+
+	if (!foundSlot)
+		return 0;
+
+	memcpy(&_items[i], &_items[itemIndex], sizeof(EobItem));
+	return i;
+}
+
+void EobCoreEngine::setItemPosition(Item *itemQueue, int block, Item item, int pos) {
+	if (!item)
+		return;
+
+	EobItem *itm = &_items[item];
+	itm->pos = pos;
+	itm->block = block;
+	itm->level = block < 0 ? 0xff : _currentLevel;
+
+	if (!*itemQueue) {
+		*itemQueue = itm->next = itm->prev = item;
+	} else {
+		EobItem *itmQ = &_items[*itemQueue];
+		EobItem *itmQN = &_items[itmQ->next];
+		itm->prev = itmQN->prev;
+		itm->next = itmQ->next;
+		*itemQueue = itmQN->prev = itmQ->next = item;
+	}
+}
+
+void EobCoreEngine::createInventoryItem(EobCharacter *c, Item itemIndex, int itemValue, int preferedInventorySlot) {
+	if (itemIndex <= 0)
+		return;
+
+	itemIndex = duplicateItem(itemIndex);
+	_items[itemIndex].flags |= 0x40;
+
+	if (itemValue != -1)
+		_items[itemIndex].value = itemValue;
+
+	if (itemValue && ((_itemTypes[_items[itemIndex].type].extraProperties & 0x7f) < 4))
+		_items[itemIndex].flags |= 0x80;
+
+	if (c->inventory[preferedInventorySlot]) {
+		for (int i = 2; i < 16; i++) {
+			if (!c->inventory[i]) {
+				c->inventory[i] = itemIndex;
+				return;
+			}
+		}
+	} else {
+		c->inventory[preferedInventorySlot] = itemIndex;
+	}
+}
+
+int EobCoreEngine::deleteInventoryItem(int charIndex, int slot) {
+	int itm = (slot == -1) ? _itemInHand : _characters[charIndex].inventory[slot];
+	_items[itm].block = -1;
+
+	if (slot == -1) {
+		setHandItem(0);
+	} else {
+		_characters[charIndex].inventory[slot] = 0;
+
+		if (_currentControlMode == 1)
+			gui_drawInventoryItem(slot, 1, 0);
+
+		if (_currentControlMode == 0)
+			gui_drawCharPortraitWithStats(charIndex);
+	}
+
+	return _items[itm].value;
+}
+
+void EobCoreEngine::deleteBlockItem(uint16 block, int type) {
+	uint16 itm = _levelBlockProperties[block].drawObjects;
+	if (!itm)
+		return;	
+	
+	for (uint16 i2 = itm, i = 0; itm != i2 || !i; i++ ) {
+		if (type == _items[itm].type || type == -1) {
+			_items[itm].block = -1;
+			_items[itm].level = 0;
+			uint16 i3 = itm;
+			itm = _items[itm].prev;
+			_items[i3].prev = _items[i3].next = 0;
+		} else {
+			uint16 i3 = itm;
+			itm = _items[itm].prev;
+			_items[i3].prev = _items[i3].next = 0;
+			setItemPosition((Item*)&_levelBlockProperties[block].drawObjects, block, i3, _items[i3].pos);
+		}
+	}
+}
+
+int EobCoreEngine::validateInventorySlotForItem(Item item, int charIndex, int slot) {
+	if (item < 0)
+		return 0;
+
+	int offset = (_flags.gameID == GI_EOB1) ? 11 : (_flags.lang == Common::DE_DEU ? 16 : 12);
+
+	if (slot == 17 && item && !itemUsableByCharacter(charIndex, item)) {
+		_txt->printMessage(_itemExtraStrings[offset], -1, _characters[charIndex].name);
+		return 0;
+	}
+
+	int itm = _characters[charIndex].inventory[slot];
+	int ex = _itemTypes[_items[itm].type].extraProperties & 0x7f;
+
+	if (slot < 2 && _items[itm].flags & 0x20 && ex > 0 && ex < 4) {
+		_txt->printMessage(_itemExtraStrings[offset + 1], -1, _characters[charIndex].name);
+		return 0;
+	}
+
+	uint16 v = item ? _itemTypes[_items[item].type].invFlags : 0xffff;
+	if (v & _slotValidationFlags[slot])
+		return 1;
+
+	_txt->printMessage(_itemExtraStrings[offset + (_flags.gameID == GI_EOB1 ? 1 : 2)]);
+	return 0;
+}
+
+void EobCoreEngine::deletePartyItem(Item itemType, int16 itemValue) {
+	for (int i = 0; i < 6; i++) {
+		if (!testCharacter(i, 1))
+			continue;
+
+		EobCharacter *c = &_characters[i];
+		int slot = checkCharacterInventoryForItem(i, itemType, itemValue);
+
+		if (slot == -1)
+			continue;
+
+		int itm = c->inventory[slot];
+		_items[itm].block = -1;
+		c->inventory[slot] = 0;
+
+		if (_currentControlMode == 0 && slot < 2 && i < 5)
+			gui_drawWeaponSlot(i, slot);
+
+		if (_currentControlMode == 1 && i == _updateCharNum)
+			gui_drawInventoryItem(slot, 1, 0);
+	}
+}
+
+int EobCoreEngine::itemUsableByCharacter(int charIndex, Item item) {
+	if (!item)
+		return 1;
+
+	return (_itemTypes[_items[item].type].allowedClasses & _classModifierFlags[_characters[charIndex].cClass]);
+}
+
+int EobCoreEngine::countQueuedItems(Item itemQueue, int16 id, int16 type, int count, int includeFlyingItems) {
+	uint16 o1 = itemQueue;
+	uint16 o2 = o1;
+	
+	if (!o1)
+		return 0;
+
+	int res = 0;
+		
+	for (bool forceLoop = true; o1 != o2 || forceLoop; o1 = _items[o1].prev) {
+		EobItem *itm = &_items[o1];
+		forceLoop = false;
+		if (id != -1 || type != -1) {
+			if ((id != -1 || (id == -1 && type != itm->type)) && (type != -1) || (id != o1))
+				continue;
+		}
+
+		if (!includeFlyingItems) {
+			if (itm->pos > 3 && itm->pos < 8)
+				continue;
+		}
+
+		if (!count)
+			return o1;
+		
+		res++;		
+	}
+
+	return res;
+}
+
+int EobCoreEngine::getQueuedItem(Item *items, int pos, int id) {
+	Item o1 = *items;
+	Item o2 = o1;
+
+	if (!o1)
+		return 0;
+
+	EobItem *itm = &_items[o1];
+	
+	for (bool forceLoop = true; o1 != o2 || forceLoop; o1 = itm->prev) {
+		itm = &_items[o1];
+		forceLoop = false;
+		if ((id != -1 || (id == -1 && itm->pos != pos)) && id != o1)
+			continue;
+		
+		Item n = itm->next;
+		Item p = itm->prev;
+		_items[n].prev = p;
+		_items[p].next = n;
+		itm->next = itm->prev = itm->block = 0;
+		itm->level = 0;
+		if (o1 == *items)
+			*items = p;
+		if (o1 == *items)
+			*items = 0;
+
+		return o1;
+	}
+
+	return 0;
+}
+
+void EobCoreEngine::printFullItemName(Item item) {
+	EobItem *itm = &_items[item];
+	const char *nameUnid = _itemNames[itm->nameUnid];
+	const char *nameId = _itemNames[itm->nameId];
+	uint8 f = _itemTypes[itm->type].extraProperties & 0x7f;
+	int8 v = itm->value;
+	
+	const char *tstr2 = 0;
+	const char *tstr3 = 0;
+	int e = 0;
+
+	char tmpString[61];
+
+	if ((itm->flags & 0x40) && !strlen(nameId)) {
+		switch (f) {
+			case 0:
+			case 1:
+			case 2:
+			case 3:
+				if (v == 0)
+					strcpy(tmpString, nameUnid);
+				else if (v < 0)
+					sprintf(tmpString, _itemExtraStrings[3], v, nameUnid);
+				else
+					sprintf(tmpString, _itemExtraStrings[4], v, nameUnid);
+				break;
+
+			case 9:
+				tstr2 = _itemExtraStrings[5];
+				tstr3 = _spells[v].name;
+				e = 1;
+				break;
+
+			case 10:
+				tstr2 = _itemExtraStrings[6];
+				tstr3 = _spells[_flags.gameID == GI_EOB1 ? (_clericSpellOffset + v) : v].name;
+				e = 1;
+				break;
+
+			case 14:
+				tstr2 = _itemExtraStrings[8];
+				tstr3 = _itemSuffixStrings[8];
+				break;
+
+			case 16:
+				tstr2 = _itemExtraStrings[7];
+				tstr3 = _itemSuffixStrings[v + 6];
+				e = 0;
+				break;
+
+			case 18:
+				if (v == 5) {
+					tstr2 = _itemExtraStrings[_flags.lang == Common::EN_ANY ? 9 : 10];
+					e = 1;
+				} else {
+					tstr2 = _itemExtraStrings[9];
+					e = 0;
+				}
+				tstr3 = _itemSuffixStrings[v + (_flags.lang == Common::EN_ANY ? 11 : 15)];
+				break;
+
+			default:
+				strcpy(tmpString, nameUnid);
+				break;
+		}
+	
+
+		if (tstr3) {
+			if (!tstr2) {
+				sprintf(tmpString, _itemExtraStrings[_flags.lang == Common::EN_ANY ? 10 : 11], tstr3);
+			} else {
+				if (e == 1) {
+					if (tstr2 == _itemExtraStrings[12])
+						sprintf(tmpString, _itemExtraStrings[_flags.lang == Common::EN_ANY ? 11 : 14], tstr2, tstr3);
+					else
+						sprintf(tmpString, _itemExtraStrings[_flags.gameID == GI_EOB1 ? 10 : (_flags.lang == Common::EN_ANY ? 11 : 13)], tstr2, tstr3);
+				} else {
+					sprintf(tmpString, _itemExtraStrings[_flags.gameID == GI_EOB1 ? 10 : (_flags.lang == Common::EN_ANY ? 11 : 15)], tstr2, tstr3);
+				}
+			}
+		}
+	} else {
+		strcpy(tmpString, (itm->flags & 0x40) ? nameId : nameUnid);
+	}
+
+	_txt->printMessage(tmpString);
+}
+
+void EobCoreEngine::identifyQueuedItems(Item itemQueue) {
+	if (!itemQueue)
+		return;
+
+	Item first = itemQueue;
+	do {
+		_items[itemQueue].flags |= 0x40;
+		itemQueue = _items[itemQueue].prev;
+
+	} while (first != itemQueue);
+}
+
+void EobCoreEngine::drawItemIconShape(int pageNum, Item itemId, int x, int y) {
+	int icn = _items[itemId].icon;
+	bool applyBluePal = ((_partyEffectFlags & 2) && (_items[itemId].flags & 0x80)) ? true : false;
+
+	if (applyBluePal) {
+		_screen->setFadeTableIndex(3);
+		_screen->setShapeFadeMode(1, true);
+	}
+
+	_screen->drawShape(pageNum, _itemIconShapes[icn], x, y, 0);
+
+	if (applyBluePal) {
+		_screen->setFadeTableIndex(4);
+		_screen->setShapeFadeMode(1, false);
+	}
+}
+
+bool EobCoreEngine::isMagicWeapon(Item itemIndex) {
+	return (_items[itemIndex].type > 10 && _items[itemIndex].type < 18);
+}
+
+bool EobCoreEngine::checkInventoryForRings(int charIndex, int itemValue) {
+	for (int i = 25; i <= 26; i++) {
+		int itm = _characters[charIndex].inventory[i];
+		if (itm && _items[itm].type == 47 && _items[itm].value == itemValue)
+			return true;
+	}
+	return false;
+}
+
+void EobCoreEngine::eatItemInHand(int charIndex) {
+	EobCharacter *c = &_characters[charIndex];
+	if (!testCharacter(charIndex, 5)) {
+		_txt->printMessage(_warningStrings[1], -1, c->name);
+	} else if (_itemInHand && _items[_itemInHand].type != 31) {
+		_txt->printMessage(_warningStrings[3]);
+	} else if (_items[_itemInHand].value == -1) {
+		_txt->printMessage(_warningStrings[2]);
+		snd_playSoundEffect(79);
+	} else {
+		c->food += _items[_itemInHand].value;
+		if (c->food > 100)
+			c->food = 100;
+
+		_items[_itemInHand].block = -1;
+		setHandItem(0);
+		gui_drawFoodStatusGraph(charIndex);
+		_screen->updateScreen();
+		snd_playSoundEffect(9);
+	}	
+}
+
+bool EobCoreEngine::launchObject(int charIndex, Item item, uint16 startBlock, int startPos, int dir, int type) {
+	EobFlyingObject *t = _flyingObjects;
+	int slot = 0;
+	for (; slot < 10; slot++) {
+		if (!t->enable)
+			break;
+		t++;
+	}
+
+	if (slot == 10)
+		return false;
+
+	setItemPosition((Item*)&_levelBlockProperties[startBlock].drawObjects, startBlock, item, startPos | 4);
+
+	t->enable = 1;
+	t->u2 = 1;
+	t->flags = 0;
+	t->direction = dir;
+	t->distance = 12;
+	t->curBlock = startBlock;
+	t->curPos = startPos;
+	t->item = item;
+	t->objectType = type;
+	t->attackerId = charIndex;
+	t->callBackIndex = 0;
+
+	snd_playSoundEffect(type == 7 ? 26 : 11);	
+	return true;
+}
+
+void EobCoreEngine::launchMagicObject(int charIndex, int type, uint16 startBlock, int startPos, int dir) {
+	EobFlyingObject *t = _flyingObjects;
+	int slot = 0;
+	for (; slot < 10; slot++) {
+		if (!t->enable)
+			break;
+		t++;
+	}
+
+	if (slot == 10)
+		return;
+
+	t->enable = 2;
+	t->u2 = 1;
+	t->flags = _magicFlightObjectProperties[(type << 2) + 2];
+	t->direction = dir;
+	t->distance = _magicFlightObjectProperties[(type << 2) + 1];
+	t->curBlock = startBlock;
+	t->curPos = startPos;
+	t->item = type;
+	t->objectType = _magicFlightObjectProperties[(type << 2) + 3];
+	t->attackerId = charIndex;
+	t->u2 = 1;
+	t->callBackIndex = _magicFlightObjectProperties[type << 2];
+	_sceneUpdateRequired = true;
+}
+
+bool EobCoreEngine::updateObjectFlight(EobFlyingObject *fo, int block, int pos) {
+	uint8 wallFlags = _wllWallFlags[_levelBlockProperties[block].walls[fo->direction ^ 2]];
+	if (fo->enable == 1) {
+		if ((wallFlags & 1) || (fo->u2) || ((wallFlags & 2) && (_dscItemShapeMap[_items[fo->item].icon] >= 15))) {
+			getQueuedItem((Item*)&_levelBlockProperties[fo->curBlock].drawObjects, 0, fo->item);
+			setItemPosition((Item*)&_levelBlockProperties[block].drawObjects, block, fo->item, pos | 4);
+			fo->curBlock = block;
+			fo->curPos = pos;
+			fo->distance--;	
+			return true;
+
+		} else {
+			_clickedSpecialFlag = 0x10;
+			specialWallAction(block, fo->direction);
+			return false;
+		}
+
+	} else {
+		if (!(wallFlags & 1) && (fo->curBlock != block))
+			return false;
+		fo->curBlock = block;
+		fo->curPos = pos;
+		if (fo->distance != 255)
+			fo->distance--;		
+	}
+	return true;
+}
+
+bool EobCoreEngine::updateFlyingObjectHitTest(EobFlyingObject *fo, int block, int pos) {
+	if (fo->u2 && (fo->curBlock != _currentBlock || fo->attackerId >= 0) && (!blockHasMonsters(block) || fo->attackerId < 0))
+		return false;
+
+	if (fo->enable == 2) {
+		if (fo->callBackIndex)
+			return (this->*_spells[fo->callBackIndex].endCallback)(fo);
+	}
+
+	if (blockHasMonsters(block)) {
+		for (int i = 0; i < 30; i++) {
+			if (!isMonsterOnPos(&_monsters[i], block, pos, 1))
+				continue;
+			if (flyingObjectMonsterHit(fo, i))
+				return true;
+		}
+
+	} else if (block == _currentBlock) {
+		return flyingObjectPartyHit(fo);
+	}
+
+	return false;
+}
+
+void EobCoreEngine::updateFlyingObject_s3(EobFlyingObject *fo) {
+
+}
+
+void EobCoreEngine::endObjectFlight(EobFlyingObject *fo) {
+	if (fo->enable == 1) {
+		_items[fo->item].pos &= 3;
+		runLevelScript(fo->curBlock, 4);
+		updateEnvironmentalSfx(18);
+	}
+	memset(fo, 0, sizeof(EobFlyingObject));
+}
+
+void EobCoreEngine::checkFlyingObjects() {
+	for (int i = 0; i < 10; i++) {
+		EobFlyingObject *fo = &_flyingObjects[i];
+		if (!fo->enable)
+			continue;
+		if (updateFlyingObjectHitTest(fo, fo->curBlock, fo->curPos))
+			endObjectFlight(fo);
+	}
+}
+
+void EobCoreEngine::reloadWeaponSlot(int charIndex, int slotIndex, int itemType, int arrowOrDagger) {
+	if (arrowOrDagger && _characters[charIndex].inventory[16]) {
+		_characters[charIndex].inventory[slotIndex] = getQueuedItem(&_characters[charIndex].inventory[16], 0, -1);
+	} else {
+		for (int i = 24; i >= 22; i--) {
+			if (!_characters[charIndex].inventory[i])
+				continue;
+			if (_items[_characters[charIndex].inventory[i]].type == itemType && itemType != -1)
+				continue;
+			_characters[charIndex].inventory[slotIndex] = _characters[charIndex].inventory[i];
+			_characters[charIndex].inventory[i] = 0;
+			return;
+		}
+	}
+}
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB
+
diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp
index 34bde7f..df595b6 100644
--- a/engines/kyra/kyra_hof.cpp
+++ b/engines/kyra/kyra_hof.cpp
@@ -171,7 +171,7 @@ KyraEngine_HoF::~KyraEngine_HoF() {
 		delete[] _conversationState[i];
 	delete[] _conversationState;
 
-	for (Common::Array<const TIMOpcode *>::iterator i = _timOpcodes.begin(); i != _timOpcodes.end(); ++i)
+	for (Common::Array<const TIMOpcode*>::iterator i = _timOpcodes.begin(); i != _timOpcodes.end(); ++i)
 		delete *i;
 	_timOpcodes.clear();
 }
diff --git a/engines/kyra/kyra_hof.h b/engines/kyra/kyra_hof.h
index 916cac0..a6add50 100644
--- a/engines/kyra/kyra_hof.h
+++ b/engines/kyra/kyra_hof.h
@@ -656,7 +656,7 @@ protected:
 	int t2_resetChat(const TIM *tim, const uint16 *param);
 	int t2_playSoundEffect(const TIM *tim, const uint16 *param);
 
-	Common::Array<const TIMOpcode *> _timOpcodes;
+	Common::Array<const TIMOpcode*> _timOpcodes;
 
 	// sound
 	int _oldTalkFile;
diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp
index 39ed0d0..4e07c8f 100644
--- a/engines/kyra/kyra_mr.cpp
+++ b/engines/kyra/kyra_mr.cpp
@@ -183,7 +183,7 @@ KyraEngine_MR::~KyraEngine_MR() {
 	delete[] _sceneStrings;
 	delete[] _talkObjectList;
 
-	for (Common::Array<const Opcode *>::iterator i = _opcodesDialog.begin(); i != _opcodesDialog.end(); ++i)
+	for (Common::Array<const Opcode*>::iterator i = _opcodesDialog.begin(); i != _opcodesDialog.end(); ++i)
 		delete *i;
 	_opcodesDialog.clear();
 
diff --git a/engines/kyra/kyra_mr.h b/engines/kyra/kyra_mr.h
index 473c037..38ff271 100644
--- a/engines/kyra/kyra_mr.h
+++ b/engines/kyra/kyra_mr.h
@@ -463,7 +463,7 @@ private:
 
 	void npcChatSequence(const char *str, int object, int vocHigh, int vocLow);
 
-	Common::Array<const Opcode *> _opcodesDialog;
+	Common::Array<const Opcode*> _opcodesDialog;
 
 	int o3d_updateAnim(EMCState *script);
 	int o3d_delay(EMCState *script);
diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp
index dbdcda2..f5ef0d0 100644
--- a/engines/kyra/kyra_v1.cpp
+++ b/engines/kyra/kyra_v1.cpp
@@ -211,7 +211,7 @@ Common::Error KyraEngine_v1::init() {
 }
 
 KyraEngine_v1::~KyraEngine_v1() {
-	for (Common::Array<const Opcode *>::iterator i = _opcodes.begin(); i != _opcodes.end(); ++i)
+	for (Common::Array<const Opcode*>::iterator i = _opcodes.begin(); i != _opcodes.end(); ++i)
 		delete *i;
 	_opcodes.clear();
 	_keyMap.clear();
@@ -354,14 +354,14 @@ int KyraEngine_v1::checkInput(Button *buttonList, bool mainLoop, int eventFlag)
 }
 
 void KyraEngine_v1::setupKeyMap() {
-	struct KeyMapEntry {
+	struct KeyCodeMapEntry {
 		Common::KeyCode kcScummVM;
 		int16 kcDOS;
 		int16 kcPC98;
 	};
 
 #define KC(x) Common::KEYCODE_##x
-	static const KeyMapEntry keys[] = {
+	static const KeyCodeMapEntry keys[] = {
 		{ KC(SPACE), 61, 53 },
 		{ KC(RETURN), 43, 29 },
 		{ KC(UP), 96, 68 },
@@ -377,13 +377,48 @@ void KyraEngine_v1::setupKeyMap() {
 		{ KC(KP7), 91, 67 },
 		{ KC(PAGEUP), 101, 69 },
 		{ KC(KP9), 101, 69 },
+		{ KC(END), 93, 0/*unknown*/ },
+		{ KC(KP1), 93, 0/*unknown*/ },
+		{ KC(PAGEDOWN), 103, 0/*unknown*/ },
+		{ KC(KP3), 103, 0/*unknown*/ },
 		{ KC(F1), 112, 99 },
 		{ KC(F2), 113, 100 },
 		{ KC(F3), 114, 101 },
+		{ KC(F4), 115, 102 },
+		{ KC(F5), 116, 103 },
+		{ KC(F6), 117, 104 },
+		{ KC(a), 31, 31 },
+		{ KC(b), 50, 50 },
+		{ KC(c), 48, 48 },
+		{ KC(d), 33, 33 },
+		{ KC(e), 19, 19 },
+		{ KC(f), 34, 34 },
+		{ KC(i), 24, 24 },
+		{ KC(k), 38, 38 },
+		{ KC(m), 52, 52 },
+		{ KC(n), 51, 51 },
 		{ KC(o), 25, 25 },
+		{ KC(p), 26, 26 },
 		{ KC(r), 20, 20 },
+		{ KC(s), 32, 32 },
+		{ KC(w), 18, 18 },
+		{ KC(y), 22, 22 },
+		{ KC(z), 46, 46 },		
+		{ KC(1), 2, 0/*unknown*/ },
+		{ KC(2), 3, 0/*unknown*/ },
+		{ KC(3), 4, 0/*unknown*/ },
+		{ KC(4), 5, 0/*unknown*/ },
+		{ KC(5), 6, 0/*unknown*/ },
+		{ KC(6), 7, 0/*unknown*/ },
+		{ KC(7), 8, 0/*unknown*/ },
 		{ KC(SLASH), 55, 55 },
 		{ KC(ESCAPE), 110, 1 },
+		{ KC(MINUS), 12, 0/*unknown*/ },
+		{ KC(KP_MINUS), 105, 0/*unknown*/ },
+		{ KC(PLUS), 13, 0/*unknown*/ },
+		{ KC(KP_PLUS), 106, 0/*unknown*/ },
+		{ KC(COMMA), 53, 0/*unknown*/ },
+		{ KC(PERIOD), 54, 0/*unknown*/ }
 	};
 #undef KC
 
diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h
index 24a3b35..40f9074 100644
--- a/engines/kyra/kyra_v1.h
+++ b/engines/kyra/kyra_v1.h
@@ -323,7 +323,7 @@ protected:
 
 	// opcode
 	virtual void setupOpcodeTable() = 0;
-	Common::Array<const Opcode *> _opcodes;
+	Common::Array<const Opcode*> _opcodes;
 
 	int o1_queryGameFlag(EMCState *script);
 	int o1_setGameFlag(EMCState *script);
diff --git a/engines/kyra/kyra_v2.h b/engines/kyra/kyra_v2.h
index 56391d1..7896748 100644
--- a/engines/kyra/kyra_v2.h
+++ b/engines/kyra/kyra_v2.h
@@ -252,7 +252,7 @@ protected:
 	virtual void uninitAnimationShapes(int count, uint8 *filedata) = 0;
 
 	// Shapes
-	typedef Common::HashMap<int, uint8 *> ShapeMap;
+	typedef Common::HashMap<int, uint8*> ShapeMap;
 	ShapeMap _gameShapes;
 
 	uint8 *getShapePtr(int index) const;
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 1209005..6cb3b51 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -42,10 +42,9 @@ namespace Kyra {
 
 const char *const LoLEngine::kKeymapName = "lol";
 
-LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(system, flags) {
+LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : LolEobBaseEngine(system, flags) {
 	_screen = 0;
 	_gui = 0;
-	_txt = 0;
 	_tim = 0;
 
 	_lang = 0;
@@ -97,15 +96,11 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
 	memset(_inventory, 0, sizeof(_inventory));
 	memset(_charStatusFlags, 0, sizeof(_charStatusFlags));
 	_inventoryCurItem = 0;
-	_currentControlMode = 0;
-	_specialSceneFlag = 0;
 	_lastCharInventory = -1;
 	_emcLastItem = -1;
 
 	_itemIconShapes = _itemShapes = _gameShapes = _thrownShapes = _effectShapes = _fireballShapes = _healShapes = _healiShapes = 0;
 	_levelShpList = _levelDatList = 0;
-	_monsterShapes = _monsterPalettes = 0;
-	_monsterShapesEx = 0;
 	_gameShapeMap = 0;
 	memset(_monsterAnimType, 0, 3);
 	_healOverlay = 0;
@@ -116,10 +111,8 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
 	_charSelection = -1;
 	_characters = 0;
 	_spellProperties = 0;
-	_updateFlags = 0;
 	_selectedSpell = 0;
-	_updateCharNum = _updatePortraitSpeechAnimDuration = _portraitSpeechAnimMode = _resetPortraitAfterSpeechAnim = _textColorFlag = _needSceneRestore = 0;
-	_fadeText = false;
+	_updateCharNum = _portraitSpeechAnimMode = _textColorFlag = 0;
 	_palUpdateTimer = _updatePortraitNext = 0;
 	_lampStatusTimer = 0xffffffff;
 
@@ -128,66 +121,42 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
 	_lastButtonShape = 0;
 	_buttonPressTimer = 0;
 	_selectedCharacter = 0;
-	_suspendScript = _sceneUpdateRequired = false;
+	_suspendScript = false;
 	_scriptDirection = 0;
-	_currentDirection = 0;
-	_currentBlock = 0;
-	_compassDirection = _compassDirectionIndex = -1;
+	_compassDirectionIndex = -1;
 	_compassStep = 0;
-	memset(_visibleBlockIndex, 0, sizeof(_visibleBlockIndex));
 
 	_smoothScrollModeNormal = 1;
-	_wllVmpMap = _specialWallTypes = _wllBuffer4 = _wllWallFlags = 0;
-	_wllShapeMap = 0;
-	_lvlShapeTop = _lvlShapeBottom = _lvlShapeLeftRight = 0;
-	_levelBlockProperties = 0;
+	_wllAutomapData = 0;
+	_sceneXoffset = 112;
+	_sceneShpDim = 13;
 	_monsters = 0;
 	_monsterProperties = 0;
-	_lvlBlockIndex = _lvlShapeIndex = 0;
+	_lvlShapeIndex = 0;
 	_partyAwake = true;
-	_vcnBlocks = 0;
-	_vcnShift = 0;
-	_vcnExpTable = 0;
-	_vmpPtr = 0;
-	_vcfBlocks = 0;
 	_transparencyTable2 = 0;
 	_transparencyTable1 = 0;
-	_levelShapeProperties = 0;
-	_levelShapes = 0;
 	_specialGuiShape = 0;
 	_specialGuiShapeX = _specialGuiShapeY = _specialGuiShapeMirrorFlag = 0;
-	_blockDrawingBuffer = 0;
-	_sceneWindowBuffer = 0;
-	memset(_doorShapes, 0, sizeof(_doorShapes));
 	memset(_characterFaceShapes, 0, sizeof(_characterFaceShapes));
 
 	_lampEffect = _brightness = _lampOilStatus = 0;
 	_lampStatusSuspended = false;
-	_blockBrightness = 0;
 	_tempBuffer5120 = 0;
 	_flyingObjects = 0;
 	_monsters = 0;
 	_lastMouseRegion = 0;
-	_objectLastDirection = _monsterStepCounter = _monsterStepMode = 0;
+	_objectLastDirection = 0;
 	_monsterCurBlock = 0;
 	_seqWindowX1 = _seqWindowY1 = _seqWindowX2 = _seqWindowY2 = _seqTrigger = 0;
 	_spsWindowX = _spsWindowY = _spsWindowW = _spsWindowH = 0;
 
-	_dscUnk1 = 0;
-	_dscShapeIndex = 0;
+	_dscWalls = 0;
 	_dscOvlMap = 0;
 	_dscShapeScaleW = 0;
-	_dscShapeScaleH = 0;
-	_dscShapeX = 0;
+	_dscShapeScaleH = 0;	
 	_dscShapeY = 0;
-	_dscTileIndex = 0;
-	_dscUnk2 = 0;
-	_dscDoorShpIndex = 0;
-	_dscDim1 = 0;
-	_dscDim2 = 0;
-	_dscBlockMap = _dscDoor1 = _dscShapeOvlIndex = 0;
-	_dscBlockIndex = 0;
-	_dscDimMap = 0;
+	_dscShapeOvlIndex = 0;	
 	_dscDoorMonsterX = _dscDoorMonsterY = 0;
 	_dscDoor4 = 0;
 
@@ -198,29 +167,24 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
 	_curMusicTheme = -1;
 	_curMusicFileExt = 0;
 	_curMusicFileIndex = -1;
-	_environmentSfx = _environmentSfxVol = _envSfxDistThreshold = 0;
 	_envSfxUseQueue = false;
 	_envSfxNumTracksInQueue = 0;
 	memset(_envSfxQueuedTracks, 0, sizeof(_envSfxQueuedTracks));
 	memset(_envSfxQueuedBlocks, 0, sizeof(_envSfxQueuedBlocks));
 
-	_sceneDrawVarDown = _sceneDrawVarRight = _sceneDrawVarLeft = _wllProcessFlag = 0;
 	_partyPosX = _partyPosY = 0;
 	_shpDmX = _shpDmY = _dmScaleW = _dmScaleH = 0;
 
 	_floatingCursorControl = _currentFloatingCursor = 0;
 
 	memset(_activeTim, 0, sizeof(_activeTim));
-	memset(_openDoorState, 0, sizeof(_openDoorState));
 	memset(&_activeSpell, 0, sizeof(_activeSpell));
 
-	_activeVoiceFileTotalTime = 0;
 	_pageBuffer1 = _pageBuffer2 = 0;
 
 	memset(_charStatsTemp, 0, sizeof(_charStatsTemp));
 
 	_compassBroken = _drainMagic = 0;
-	_dialogueField = false;
 
 	_buttonData = 0;
 	_activeButtons = 0;
@@ -228,8 +192,6 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
 	_preserveEvents = false;
 	_buttonList1 = _buttonList2 = _buttonList3 = _buttonList4 = _buttonList5 = _buttonList6 = _buttonList7 = _buttonList8 = 0;
 
-	memset(_lvlTempData, 0, sizeof(_lvlTempData));
-
 	_mapOverlay = 0;
 	_automapShapes = 0;
 	_defaultLegendData = 0;
@@ -250,6 +212,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
 
 LoLEngine::~LoLEngine() {
 	setupPrologueData(false);
+	releaseTempData();
 
 #ifdef ENABLE_KEYMAPPER
 	_eventMan->getKeymapper()->cleanupGameKeymaps();
@@ -264,8 +227,6 @@ LoLEngine::~LoLEngine() {
 	_gui = 0;
 	delete _tim;
 	_tim = 0;
-	delete _txt;
-	_txt = 0;
 
 	delete[] _itemsInPlay;
 	delete[] _itemProperties;
@@ -322,64 +283,47 @@ LoLEngine::~LoLEngine() {
 		delete[] _healiShapes;
 	}
 
-	for (int i = 0; i < 3; i++)
-		releaseMonsterShapes(i);
+	if (_monsterDecorationShapes) {
+		for (int i = 0; i < 3; i++)
+			releaseMonsterShapes(i);
 
-	delete[] _monsterShapes;
-	delete[] _monsterPalettes;
-	delete[] _monsterShapesEx;
+		delete[] _monsterShapes;
+		_monsterShapes = 0;
+		delete[] _monsterPalettes;
+		_monsterPalettes = 0;
+		delete[] _monsterDecorationShapes;
+		_monsterDecorationShapes = 0;
+	}
+
+	for (int i = 0; i < 6; i++) {
+		delete[] _doorShapes[i];
+		_doorShapes[i] = 0;
+	}
 
 	delete[] _automapShapes;
 
-	for (Common::Array<const TIMOpcode *>::iterator i = _timIntroOpcodes.begin(); i != _timIntroOpcodes.end(); ++i)
+	for (Common::Array<const TIMOpcode*>::iterator i = _timIntroOpcodes.begin(); i != _timIntroOpcodes.end(); ++i)
 		delete *i;
 	_timIntroOpcodes.clear();
 
-	for (Common::Array<const TIMOpcode *>::iterator i = _timOutroOpcodes.begin(); i != _timOutroOpcodes.end(); ++i)
+	for (Common::Array<const TIMOpcode*>::iterator i = _timOutroOpcodes.begin(); i != _timOutroOpcodes.end(); ++i)
 		delete *i;
 	_timOutroOpcodes.clear();
 
-	for (Common::Array<const TIMOpcode *>::iterator i = _timIngameOpcodes.begin(); i != _timIngameOpcodes.end(); ++i)
+	for (Common::Array<const TIMOpcode*>::iterator i = _timIngameOpcodes.begin(); i != _timIngameOpcodes.end(); ++i)
 		delete *i;
 	_timIngameOpcodes.clear();
 
-
-	delete[] _wllVmpMap;
-	delete[] _wllShapeMap;
-	delete[] _specialWallTypes;
-	delete[] _wllBuffer4;
-	delete[] _wllWallFlags;
-	delete[] _lvlShapeTop;
-	delete[] _lvlShapeBottom;
-	delete[] _lvlShapeLeftRight;
+	delete[] _wllAutomapData;
 	delete[] _tempBuffer5120;
 	delete[] _flyingObjects;
 	delete[] _monsters;
-	delete[] _levelBlockProperties;
 	delete[] _monsterProperties;
 
-	delete[] _levelFileData;
-	delete[] _vcnExpTable;
-	delete[] _vcnBlocks;
-	delete[] _vcnShift;
-	delete[] _vmpPtr;
-	delete[] _vcfBlocks;
 	delete[] _transparencyTable2;
 	delete[] _transparencyTable1;
-	delete[] _levelShapeProperties;
-	delete[] _blockDrawingBuffer;
-	delete[] _sceneWindowBuffer;
 	delete[] _lightningProps;
 
-	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) {
@@ -388,16 +332,6 @@ LoLEngine::~LoLEngine() {
 		delete[] _ingameSoundList;
 	}
 
-	for (int i = 0; i < 29; i++) {
-		if (_lvlTempData[i]) {
-			delete[] _lvlTempData[i]->wallsXorData;
-			delete[] _lvlTempData[i]->flags;
-			delete[] _lvlTempData[i]->monsters;
-			delete[] _lvlTempData[i]->flyingObjects;
-			delete _lvlTempData[i];
-		}
-	}
-
 	for (int i = 0; i < 3; i++) {
 		for (int ii = 0; ii < 40; ii++)
 			delete[] _characterFaceShapes[ii][i];
@@ -409,7 +343,7 @@ LoLEngine::~LoLEngine() {
 	delete[] _mapCursorOverlay;
 	delete[] _mapOverlay;
 
-	for (Common::Array<const SpellProc *>::iterator i = _spellProcs.begin(); i != _spellProcs.end(); ++i)
+	for (Common::Array<const SpellProc*>::iterator i = _spellProcs.begin(); i != _spellProcs.end(); ++i)
 		delete *i;
 	_spellProcs.clear();
 
@@ -440,13 +374,18 @@ Common::Error LoLEngine::init() {
 	KyraEngine_v1::init();
 	initStaticResource();
 
-	_envSfxDistThreshold = _sound->getSfxType() == Sound::kAdLib ? 15 : 3;
-
 	_gui = new GUI_LoL(this);
 	assert(_gui);
 	_gui->initStaticData();
 
 	_txt = new TextDisplayer_LoL(this, _screen);
+	_dialogueButtonLabelCol1 = 144;
+	_dialogueButtonLabelCol2 = 254;
+	_dialogueButtonW = 74;
+	_dialogueButtonH = 9;
+	_bkgColor_1 = -1;
+	_color1_1 = 136;
+	_color2_1 = 251;
 
 	_screen->setAnimBlockPtr(10000);
 	_screen->setScreenDim(0);
@@ -465,41 +404,15 @@ Common::Error LoLEngine::init() {
 	if (!_sound->init())
 		error("Couldn't init sound");
 
-	_wllVmpMap = new uint8[80];
-	memset(_wllVmpMap, 0, 80);
-	_wllShapeMap = new int8[80];
-	memset(_wllShapeMap, 0, 80);
-	_specialWallTypes = new uint8[80];
-	memset(_specialWallTypes, 0, 80);
-	_wllBuffer4 = new uint8[80];
-	memset(_wllBuffer4, 0, 80);
-	_wllWallFlags = new uint8[80];
-	memset(_wllWallFlags, 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);
-
-	_levelBlockProperties = new LevelBlockProperty[1025];
-	memset(_levelBlockProperties, 0, 1025 * sizeof(LevelBlockProperty));
-	_monsters = new MonsterInPlay[30];
-	memset(_monsters, 0, 30 * sizeof(MonsterInPlay));
-	_monsterProperties = new MonsterProperty[5];
-	memset(_monsterProperties, 0, 5 * sizeof(MonsterProperty));
-
-	_vcnExpTable = new uint8[128];
-	for (int i = 0; i < 128; i++)
-		_vcnExpTable[i] = i & 0x0f;
+	LolEobBaseEngine::init();
+	
+	_wllAutomapData = new uint8[80];
+	memset(_wllAutomapData, 0, 80);
+
+	_monsters = new LolMonsterInPlay[30];
+	memset(_monsters, 0, 30 * sizeof(LolMonsterInPlay));
+	_monsterProperties = new LolMonsterProperty[5];
+	memset(_monsterProperties, 0, 5 * sizeof(LolMonsterProperty));
 
 	_tempBuffer5120 = new uint8[5120];
 	memset(_tempBuffer5120, 0, 5120);
@@ -509,25 +422,26 @@ Common::Error LoLEngine::init() {
 
 	memset(_globalScriptVars, 0, sizeof(_globalScriptVars));
 
-	_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 *));
+	_clickedShapeXOffs = 136;
+	_clickedShapeYOffs = 8;
+	_clickedSpecialFlag = 0x40;
 
-	_monsterShapesEx = new uint8 *[576];
-	memset(_monsterShapesEx, 0, 576 * sizeof(uint8 *));
+	_monsterShapes = new uint8*[48];
+	memset(_monsterShapes, 0, 48 * sizeof(uint8*));
+	_monsterPalettes = new uint8*[48];
+	memset(_monsterPalettes, 0, 48 * sizeof(uint8*));
+	_monsterDecorationShapes = new uint8*[576];
+	memset(_monsterDecorationShapes, 0, 576 * sizeof(uint8*));
 	memset(&_scriptData, 0, sizeof(EMCData));
 
-	_hasTempDataFlags = 0;
 	_activeMagicMenu = -1;
 
-	_automapShapes = new const uint8 *[109];
+	_automapShapes = new const uint8*[109];
 	_mapOverlay = new uint8[256];
 
 	memset(_availableSpells, -1, 8);
@@ -687,7 +601,7 @@ void LoLEngine::loadItemIconShapes() {
 	_screen->loadBitmap("ITEMICN.SHP", 3, 3, 0);
 	const uint8 *shp = _screen->getCPagePtr(3);
 	_numItemIconShapes = READ_LE_UINT16(shp);
-	_itemIconShapes = new uint8 *[_numItemIconShapes];
+	_itemIconShapes = new uint8*[_numItemIconShapes];
 	for (int i = 0; i < _numItemIconShapes; i++)
 		_itemIconShapes[i] = _screen->makeShapeCopy(shp, i);
 
@@ -697,7 +611,7 @@ void LoLEngine::loadItemIconShapes() {
 		_screen->loadBitmap("GAMESHP.SHP", 3, 3, 0);
 		shp = _screen->getCPagePtr(3);
 		_numGameShapes = READ_LE_UINT16(shp);
-		_gameShapes = new uint8 *[_numGameShapes];
+		_gameShapes = new uint8*[_numGameShapes];
 		for (int i = 0; i < _numGameShapes; i++)
 			_gameShapes[i] = _screen->makeShapeCopy(shp, i);
 	}
@@ -717,12 +631,6 @@ void LoLEngine::setMouseCursorToItemInHand() {
 	_screen->setMouseCursor(o, o, getItemIconShapePtr(_itemInHand));
 }
 
-bool LoLEngine::posWithinRect(int mouseX, int mouseY, int x1, int y1, int x2, int y2) {
-	if (mouseX < x1 || mouseX > x2 || mouseY < y1 || mouseY > y2)
-		return false;
-	return true;
-}
-
 void LoLEngine::checkFloatingPointerRegions() {
 	if (!_floatingCursorsEnabled)
 		return;
@@ -877,42 +785,42 @@ void LoLEngine::startup() {
 	_screen->loadBitmap("ITEMSHP.SHP", 3, 3, 0);
 	const uint8 *shp = _screen->getCPagePtr(3);
 	_numItemShapes = READ_LE_UINT16(shp);
-	_itemShapes = new uint8 *[_numItemShapes];
+	_itemShapes = new uint8*[_numItemShapes];
 	for (int i = 0; i < _numItemShapes; i++)
 		_itemShapes[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];
+	_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);
 	_numEffectShapes = READ_LE_UINT16(shp);
-	_effectShapes = new uint8 *[_numEffectShapes];
+	_effectShapes = new uint8*[_numEffectShapes];
 	for (int i = 0; i < _numEffectShapes; i++)
 		_effectShapes[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];
+	_fireballShapes = new uint8*[_numFireballShapes];
 	for (int i = 0; i < _numFireballShapes; i++)
 		_fireballShapes[i] = _screen->makeShapeCopy(shp, i);
 
 	_screen->loadBitmap("HEAL.SHP", 3, 3, 0);
 	shp = _screen->getCPagePtr(3);
 	_numHealShapes = READ_LE_UINT16(shp);
-	_healShapes = new uint8 *[_numHealShapes];
+	_healShapes = new uint8*[_numHealShapes];
 	for (int i = 0; i < _numHealShapes; i++)
 		_healShapes[i] = _screen->makeShapeCopy(shp, i);
 
 	_screen->loadBitmap("HEALI.SHP", 3, 3, 0);
 	shp = _screen->getCPagePtr(3);
 	_numHealiShapes = READ_LE_UINT16(shp);
-	_healiShapes = new uint8 *[_numHealiShapes];
+	_healiShapes = new uint8*[_numHealiShapes];
 	for (int i = 0; i < _numHealiShapes; i++)
 		_healiShapes[i] = _screen->makeShapeCopy(shp, i);
 
@@ -969,10 +877,9 @@ void LoLEngine::runLoop() {
 
 	enableSysTimer(2);
 
-	bool _runFlag = true;
 	_flagsTable[73] |= 0x08;
 
-	while (!shouldQuit() && _runFlag) {
+	while (!shouldQuit()) {
 		if (_gameToLoad != -1) {
 			// FIXME: Instead of throwing away the error returned by
 			// loadGameState, we should use it / augment it.
@@ -1784,44 +1691,6 @@ void LoLEngine::fadeText() {
 	_fadeText = false;
 }
 
-void LoLEngine::transformRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage) {
-	uint16 *p1 = (uint16 *)_tempBuffer5120;
-	uint16 *p2 = (uint16 *)(_tempBuffer5120 + 640);
-
-	for (int i = 0; i < w; i++)
-		p1[i] = i;
-
-	for (int i = 0; i < h; i++)
-		p2[i] = i;
-
-	for (int i = 0; i < w; i++)
-		SWAP(p1[_rnd.getRandomNumberRng(0, w - 1)], p1[i]);
-
-	for (int i = 0; i < h; i++)
-		SWAP(p2[_rnd.getRandomNumberRng(0, h - 1)], p2[i]);
-
-	for (int i = 0; i < h; i++) {
-		int i2 = i;
-
-		for (int ii = 0; ii < w; ii++) {
-			int dx1 = x1 + p1[ii];
-			int dy1 = y1 + p2[i2];
-			int dx2 = x2 + p1[ii];
-			int dy2 = y2 + p2[i2];
-
-			if (++i2 == h)
-				i2 = 0;
-
-			_screen->setPagePixel(dstPage, dx2, dy2, _screen->getPagePixel(srcPage, dx1, dy1));
-		}
-
-		if (!dstPage && (i & 5) == 5) {
-			updateInput();
-			_screen->updateScreen();
-		}
-	}
-}
-
 void LoLEngine::setPaletteBrightness(const Palette &srcPal, int brightness, int modifier) {
 	generateBrightnessPalette(srcPal, _screen->getPalette(1), brightness, modifier);
 	_screen->fadePalette(_screen->getPalette(1), 5, 0);
@@ -2040,7 +1909,46 @@ int LoLEngine::playCharacterScriptChat(int charId, int mode, int restorePortrait
 	return 1;
 }
 
-void LoLEngine::giveItemToMonster(MonsterInPlay *monster, Item item) {
+void LoLEngine::setupDialogueButtons(int numStr, const char *s1, const char *s2, const char *s3) {
+	screen()->setScreenDim(5);
+
+	if (numStr == 1 && speechEnabled()) {
+		_dialogueNumButtons = 0;
+		_dialogueButtonString[0] = _dialogueButtonString[1] = _dialogueButtonString[2] = 0;
+	} else {
+		_dialogueNumButtons = numStr;
+		_dialogueButtonString[0] = s1;
+		_dialogueButtonString[1] = s2;
+		_dialogueButtonString[2] = s3;
+		_dialogueHighlightedButton = 0;
+		
+		const ScreenDim *d = screen()->getScreenDim(5);
+
+		static uint16 posX[3];
+		static uint8 posY[3];
+
+		memset(posY, d->sy + d->h - 9, 3);
+
+		_dialogueButtonPosX = posX;
+		_dialogueButtonPosY = posY;
+
+		if (numStr == 1) {
+			posX[0] = posX[1] = posX[2] = d->sx + d->w - (_dialogueButtonW + 3);
+		} else {
+			int xOffs = d->w / numStr;
+			posX[0] = d->sx + (xOffs >> 1) - 37;
+			posX[1] = posX[0] + xOffs; 
+			posX[2] = posX[1] + xOffs;		
+		}
+
+		drawDialogueButtons();
+	}
+
+	if (!shouldQuit())
+		removeInputTop();
+}
+
+void LoLEngine::giveItemToMonster(LolMonsterInPlay *monster, Item item) {
 	uint16 *c = &monster->assignedItems;
 	while (*c)
 		c = &_itemsInPlay[*c].nextAssignedObject;
@@ -2049,7 +1957,7 @@ void LoLEngine::giveItemToMonster(MonsterInPlay *monster, Item item) {
 }
 
 const uint16 *LoLEngine::getCharacterOrMonsterStats(int id) {
-	return (id & 0x8000) ? (const uint16 *)_monsters[id & 0x7fff].properties->fightingStats : _characters[id].defaultModifiers;
+	return (id & 0x8000) ? (const uint16*)_monsters[id & 0x7fff].properties->fightingStats : _characters[id].defaultModifiers;
 }
 
 uint16 *LoLEngine::getCharacterOrMonsterItemsMight(int id) {
@@ -2073,21 +1981,6 @@ void LoLEngine::delay(uint32 millis, bool doUpdate, bool) {
 	}
 }
 
-int LoLEngine::rollDice(int times, int pips) {
-	if (times <= 0 || pips <= 0)
-		return 0;
-
-	int res = 0;
-	while (times--)
-		res += _rnd.getRandomNumberRng(1, pips);
-
-	return res;
-}
-
-void LoLEngine::updateEnvironmentalSfx(int soundId) {
-	snd_processEnvironmentalSoundEffect(soundId, _currentBlock);
-}
-
 // spells
 
 int LoLEngine::castSpell(int charNum, int spellType, int spellLevel) {
@@ -2502,7 +2395,7 @@ int LoLEngine::processMagicIce(int charNum, int spellLevel) {
 			int might = rollDice(iceDamageMin[spellLevel], iceDamageMax[spellLevel]) + iceDamageAdd[spellLevel];
 			int dmg = calcInflictableDamagePerItem(charNum, 0, might, 3, 2);
 
-			MonsterInPlay *m = &_monsters[o & 0x7fff];
+			LolMonsterInPlay *m = &_monsters[o & 0x7fff];
 			if (m->hitPoints <= dmg) {
 				increaseExperience(charNum, 2, m->hitPoints);
 				o = m->nextAssignedObject;
@@ -2581,7 +2474,7 @@ int LoLEngine::processMagicFireball(int charNum, int spellLevel) {
 			while (o & 0x8000) {
 				static const uint8 fireballDamage[] = { 20, 40, 80, 100 };
 				int dmg = calcInflictableDamagePerItem(charNum, o, fireballDamage[spellLevel], 4, 1);
-				MonsterInPlay *m = &_monsters[o & 0x7fff];
+				LolMonsterInPlay *m = &_monsters[o & 0x7fff];
 				o = m->nextAssignedObject;
 				_envSfxUseQueue = true;
 				inflictDamage(m->id | 0x8000, dmg, charNum, 2, 4);
@@ -2746,7 +2639,7 @@ int LoLEngine::processMagicHandOfFate(int spellLevel) {
 				uint16 o = _levelBlockProperties[b1].assignedObjects;
 				while (o & 0x8000) {
 					uint16 o2 = o;
-					MonsterInPlay *m = &_monsters[o & 0x7fff];
+					LolMonsterInPlay *m = &_monsters[o & 0x7fff];
 					o = findObject(o)->nextAssignedObject;
 					int nX = 0;
 					int nY = 0;
@@ -3015,7 +2908,7 @@ int LoLEngine::processMagicVaelansCube() {
 
 	uint16 o = _levelBlockProperties[bl].assignedObjects;
 	while (o & 0x8000) {
-		MonsterInPlay *m = &_monsters[o & 0x7fff];
+		LolMonsterInPlay *m = &_monsters[o & 0x7fff];
 		if (m->properties->flags & 0x1000) {
 			inflictDamage(o, 100, 0xffff, 0, 0x80);
 			v = 1;
@@ -3495,7 +3388,7 @@ int LoLEngine::calcInflictableDamage(int16 attacker, int16 target, int hitType)
 }
 
 int LoLEngine::inflictDamage(uint16 target, int damage, uint16 attacker, int skill, int flags) {
-	MonsterInPlay *m = 0;
+	LolMonsterInPlay *m = 0;
 	LoLCharacter *c = 0;
 
 	if (target & 0x8000) {
@@ -3712,7 +3605,7 @@ void LoLEngine::checkForPartyDeath() {
 	}
 }
 
-void LoLEngine::applyMonsterAttackSkill(MonsterInPlay *monster, int16 target, int16 damage) {
+void LoLEngine::applyMonsterAttackSkill(LolMonsterInPlay *monster, int16 target, int16 damage) {
 	if (rollDice(1, 100) > monster->properties->attackSkillChance)
 		return;
 
@@ -3782,7 +3675,7 @@ void LoLEngine::applyMonsterAttackSkill(MonsterInPlay *monster, int16 target, in
 	}
 }
 
-void LoLEngine::applyMonsterDefenseSkill(MonsterInPlay *monster, int16 attacker, int flags, int skill, int damage) {
+void LoLEngine::applyMonsterDefenseSkill(LolMonsterInPlay *monster, int16 attacker, int flags, int skill, int damage) {
 	if (rollDice(1, 100) > monster->properties->defenseSkillChance)
 		return;
 
@@ -4041,7 +3934,7 @@ uint16 LoLEngine::getNearestMonsterFromCharacterForBlock(uint16 block, int charN
 	int o = _levelBlockProperties[block].assignedObjects;
 
 	while (o & 0x8000) {
-		MonsterInPlay *m = &_monsters[o & 0x7fff];
+		LolMonsterInPlay *m = &_monsters[o & 0x7fff];
 		if (m->mode >= 13) {
 			o = m->nextAssignedObject;
 			continue;
@@ -4107,7 +4000,7 @@ void LoLEngine::displayAutomap() {
 
 	_currentMapLevel = _currentLevel;
 	uint8 *tmpWll = new uint8[80];
-	memcpy(tmpWll, _wllBuffer4, 80);
+	memcpy(tmpWll, _wllAutomapData, 80);
 
 	_screen->loadBitmap("parch.cps", 2, 2, &_screen->getPalette(3));
 	_screen->loadBitmap("autobut.shp", 3, 5, 0);
@@ -4188,7 +4081,7 @@ void LoLEngine::displayAutomap() {
 
 	_screen->fadeToBlack(10);
 	loadLevelWallData(_currentLevel, false);
-	memcpy(_wllBuffer4, tmpWll, 80);
+	memcpy(_wllAutomapData, tmpWll, 80);
 	delete[] tmpWll;
 	restoreBlockTempData(_currentLevel);
 	addLevelItems();
@@ -4229,7 +4122,7 @@ bool LoLEngine::updateAutoMapIntern(uint16 block, uint16 x, uint16 y, int16 xOff
 	uint16 b = block + blockPosTable[6 + xOffs];
 
 	if (fx != -1) {
-		if (_wllBuffer4[_levelBlockProperties[b].walls[fx]] & 0xc0)
+		if (_wllAutomapData[_levelBlockProperties[b].walls[fx]] & 0xc0)
 			return false;
 	}
 
@@ -4237,13 +4130,13 @@ bool LoLEngine::updateAutoMapIntern(uint16 block, uint16 x, uint16 y, int16 xOff
 	b = block + blockPosTable[9 + yOffs];
 
 	if (fy != -1) {
-		if (_wllBuffer4[_levelBlockProperties[b].walls[fy]] & 0xc0)
+		if (_wllAutomapData[_levelBlockProperties[b].walls[fy]] & 0xc0)
 			return false;
 	}
 
 	b = block + blockPosTable[6 + xOffs] + blockPosTable[9 + yOffs];
 
-	if ((fx != -1) && (fy != -1) && (_wllBuffer4[_levelBlockProperties[b].walls[fx]] & 0xc0) && (_wllBuffer4[_levelBlockProperties[b].walls[fy]] & 0xc0))
+	if ((fx != -1) && (fy != -1) && (_wllAutomapData[_levelBlockProperties[b].walls[fx]] & 0xc0) && (_wllAutomapData[_levelBlockProperties[b].walls[fy]] & 0xc0))
 		return false;
 
 	_levelBlockProperties[b].flags |= 7;
@@ -4252,7 +4145,7 @@ bool LoLEngine::updateAutoMapIntern(uint16 block, uint16 x, uint16 y, int16 xOff
 }
 
 void LoLEngine::loadMapLegendData(int level) {
-	uint16 *legendData = (uint16 *)_tempBuffer5120;
+	uint16 *legendData= (uint16*)_tempBuffer5120;
 	for (int i = 0; i < 32; i++) {
 		legendData[i * 6] = 0xffff;
 		legendData[i * 6 + 5] = 0xffff;
@@ -4306,7 +4199,7 @@ void LoLEngine::drawMapPage(int pageNum) {
 
 		for (; bl < 1024; bl++) {
 			uint8 *w = _levelBlockProperties[bl].walls;
-			if ((_levelBlockProperties[bl].flags & 7) == 7 && (!(_wllBuffer4[w[0]] & 0xc0)) && (!(_wllBuffer4[w[2]] & 0xc0)) && (!(_wllBuffer4[w[1]] & 0xc0))&& (!(_wllBuffer4[w[3]] & 0xc0))) {
+			if ((_levelBlockProperties[bl].flags & 7) == 7 && (!(_wllAutomapData[w[0]] & 0xc0)) && (!(_wllAutomapData[w[2]] & 0xc0)) && (!(_wllAutomapData[w[1]] & 0xc0))&& (!(_wllAutomapData[w[3]] & 0xc0))) {
 				uint16 b0 = calcNewBlockPosition(bl, 0);
 				uint16 b2 = calcNewBlockPosition(bl, 2);
 				uint16 b1 = calcNewBlockPosition(bl, 1);
@@ -4323,25 +4216,25 @@ void LoLEngine::drawMapPage(int pageNum) {
 				// draw north wall
 				drawMapBlockWall(b3, w31, sx, sy, 3);
 				drawMapShape(w31, sx, sy, 3);
-				if (_wllBuffer4[w31] & 0xc0)
+				if (_wllAutomapData[w31] & 0xc0)
 					_screen->copyBlockAndApplyOverlay(_screen->_curPage, sx, sy, _screen->_curPage, sx, sy, 1, 6, 0, _mapOverlay);
 
 				// draw west wall
 				drawMapBlockWall(b1, w13, sx, sy, 1);
 				drawMapShape(w13, sx, sy, 1);
-				if (_wllBuffer4[w13] & 0xc0)
+				if (_wllAutomapData[w13] & 0xc0)
 					_screen->copyBlockAndApplyOverlay(_screen->_curPage, sx + 6, sy, _screen->_curPage, sx + 6, sy, 1, 6, 0, _mapOverlay);
 
 				// draw east wall
 				drawMapBlockWall(b0, w02, sx, sy, 0);
 				drawMapShape(w02, sx, sy, 0);
-				if (_wllBuffer4[w02] & 0xc0)
+				if (_wllAutomapData[w02] & 0xc0)
 					_screen->copyBlockAndApplyOverlay(_screen->_curPage, sx, sy, _screen->_curPage, sx, sy, 7, 1, 0, _mapOverlay);
 
 				//draw south wall
 				drawMapBlockWall(b2, w20, sx, sy, 2);
 				drawMapShape(w20, sx, sy, 2);
-				if (_wllBuffer4[w20] & 0xc0)
+				if (_wllAutomapData[w20] & 0xc0)
 					_screen->copyBlockAndApplyOverlay(_screen->_curPage, sx, sy + 5, _screen->_curPage, sx, sy + 5, 7, 1, 0, _mapOverlay);
 			}
 
@@ -4362,7 +4255,7 @@ void LoLEngine::drawMapPage(int pageNum) {
 		sx = mapGetStartPosX();
 		sy = mapGetStartPosY();
 
-		uint16 *legendData = (uint16 *)_tempBuffer5120;
+		uint16 *legendData = (uint16*)_tempBuffer5120;
 		uint8 yOffset = _flags.use16ColorMode ? 4 : 0;
 
 		for (int ii = 0; ii < 32; ii++)  {
@@ -4508,7 +4401,7 @@ void LoLEngine::redrawMapCursor() {
 }
 
 void LoLEngine::drawMapBlockWall(uint16 block, uint8 wall, int x, int y, int direction) {
-	if (((1 << direction) & _levelBlockProperties[block].flags) || ((_wllBuffer4[wall] & 0x1f) != 13))
+	if (((1 << direction) & _levelBlockProperties[block].flags) || ((_wllAutomapData[wall] & 0x1f) != 13))
 		return;
 
 	int cp = _screen->_curPage;
@@ -4518,7 +4411,7 @@ void LoLEngine::drawMapBlockWall(uint16 block, uint8 wall, int x, int y, int dir
 }
 
 void LoLEngine::drawMapShape(uint8 wall, int x, int y, int direction) {
-	int l = _wllBuffer4[wall] & 0x1f;
+	int l = _wllAutomapData[wall] & 0x1f;
 	if (l == 0x1f)
 		return;
 
@@ -4611,48 +4504,7 @@ void LoLEngine::printMapExitButtonText() {
 	_screen->setCurPage(cp);
 }
 
-void LoLEngine::generateTempData() {
-	int l = _currentLevel - 1;
-	if (_lvlTempData[l]) {
-		delete[] _lvlTempData[l]->wallsXorData;
-		delete[] _lvlTempData[l]->flags;
-		delete[] _lvlTempData[l]->monsters;
-		delete[] _lvlTempData[l]->flyingObjects;
-		delete _lvlTempData[l];
-	}
-
-	_lvlTempData[l] = new LevelTempData;
 
-	_lvlTempData[l]->wallsXorData = new uint8[4096];
-	_lvlTempData[l]->flags = new uint8[1024];
-	_lvlTempData[l]->monsters = new MonsterInPlay[30];
-	_lvlTempData[l]->flyingObjects = new FlyingObject[8];
-
-	Common::String filename = Common::String::format("LEVEL%d.CMZ", _currentLevel);
-
-	_screen->loadBitmap(filename.c_str(), 15, 15, 0);
-	const uint8 *p = _screen->getCPagePtr(14);
-	uint16 len = READ_LE_UINT16(p + 4);
-	p += 6;
-
-	memset(_lvlTempData[l]->wallsXorData, 0, 4096);
-	memset(_lvlTempData[l]->flags, 0, 1024);
-	uint8 *d = _lvlTempData[l]->wallsXorData;
-	uint8 *df = _lvlTempData[l]->flags;
-
-	for (int i = 0; i < 1024; i++) {
-		for (int ii = 0; ii < 4; ii++)
-			*d++ = p[i * len + ii] ^ _levelBlockProperties[i].walls[ii];
-		*df++ = _levelBlockProperties[i].flags;
-	}
-
-	memcpy(_lvlTempData[l]->monsters, _monsters,  sizeof(MonsterInPlay) * 30);
-	memcpy(_lvlTempData[l]->flyingObjects, _flyingObjects,  sizeof(FlyingObject) * 8);
-
-	_lvlTempData[l]->monsterDifficulty =_monsterDifficulty;
-
-	_hasTempDataFlags |= (1 << l);
-}
 
 } // End of namespace Kyra
 
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index eb2f6cf..20519b7 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -25,7 +25,7 @@
 #ifndef KYRA_LOL_H
 #define KYRA_LOL_H
 
-#include "kyra/kyra_v1.h"
+#include "kyra/loleobbase.h"
 #include "kyra/script_tim.h"
 #include "kyra/script.h"
 #include "kyra/gui_lol.h"
@@ -86,15 +86,7 @@ struct SpellProperty {
 	uint16 flags;
 };
 
-struct LevelBlockProperty {
-	uint8 walls[4];
-	uint16 assignedObjects;
-	uint16 drawObjects;
-	uint8 direction;
-	uint8 flags;
-};
-
-struct MonsterProperty {
+struct LolMonsterProperty {
 	uint8 shapeIndex;
 	uint8 maxWidth;
 	uint16 fightingStats[9];
@@ -116,7 +108,7 @@ struct MonsterProperty {
 	uint8 sounds[3];
 };
 
-struct MonsterInPlay {
+struct LolMonsterInPlay {
 	uint16 nextAssignedObject;
 	uint16 nextDrawObject;
 	uint8 flyingHeight;
@@ -142,7 +134,7 @@ struct MonsterInPlay {
 	int16 hitPoints;
 	uint8 speedTick;
 	uint8 type;
-	MonsterProperty *properties;
+	LolMonsterProperty *properties;
 	uint8 numDistAttacks;
 	uint8 curDistWeapon;
 	int8 distAttackTick;
@@ -179,15 +171,6 @@ struct ItemProperty {
 	uint8 unkD;
 };
 
-struct LevelShapeProperty {
-	uint16 shapeIndex[10];
-	uint8 scaleFlag[10];
-	int16 shapeX[10];
-	int16 shapeY[10];
-	int8 next;
-	uint8 flags;
-};
-
 struct CompassDef {
 	uint8 shapeIndex;
 	int8 x;
@@ -195,7 +178,7 @@ struct CompassDef {
 	uint8 flags;
 };
 
-struct ButtonDef {
+struct LoLButtonDef {
 	uint16 buttonflags;
 	uint16 keyCode;
 	uint16 keyCode2;
@@ -207,12 +190,6 @@ struct ButtonDef {
 	uint16 screenDim;
 };
 
-struct OpenDoorState {
-	uint16 block;
-	int8 wall;
-	int8 state;
-};
-
 struct ActiveSpell {
 	uint8 spell;
 	const SpellProperty *p;
@@ -245,14 +222,6 @@ struct FlyingObjectShape {
 	uint8 flipFlags;
 };
 
-struct LevelTempData {
-	uint8 *wallsXorData;
-	uint8 *flags;
-	MonsterInPlay *monsters;
-	FlyingObject *flyingObjects;
-	uint8 monsterDifficulty;
-};
-
 struct MapLegendData {
 	uint8 shapeIndex;
 	bool enable;
@@ -296,7 +265,7 @@ struct MistOfDoomAnimData {
 	uint8 sound;
 };
 
-class LoLEngine : public KyraEngine_v1 {
+class LoLEngine : public LolEobBaseEngine {
 friend class GUI_LoL;
 friend class TextDisplayer_LoL;
 friend class TIMInterpreter_LoL;
@@ -305,7 +274,7 @@ friend class Debugger_LoL;
 friend class HistoryPlayer;
 public:
 	LoLEngine(OSystem *system, const GameFlags &flags);
-	~LoLEngine();
+	virtual ~LoLEngine();
 
 	virtual void initKeymap();
 
@@ -348,13 +317,11 @@ private:
 	// main loop
 	void runLoop();
 	void update();
-	void updateEnvironmentalSfx(int soundId);
 
 	// mouse
 	void setMouseCursorToIcon(int icon);
 	void setMouseCursorToItemInHand();
 	uint8 *getItemIconShapePtr(int index);
-	bool posWithinRect(int mouseX, int mouseY, int x1, int y1, int x2, int y2);
 
 	void checkFloatingPointerRegions();
 	int _floatingCursorControl;
@@ -443,11 +410,7 @@ private:
 
 	// timers
 	void setupTimers();
-	void enableTimer(int id);
-	void enableSysTimer(int sysTimer);
-	void disableSysTimer(int sysTimer);
 
-	void timerProcessDoors(int timerNum);
 	void timerProcessMonsters(int timerNum);
 	void timerSpecialCharacterUpdate(int timerNum);
 	void timerProcessFlyingObjects(int timerNum);
@@ -457,6 +420,9 @@ private:
 	void timerUpdateLampState(int timerNum);
 	void timerFadeMessageText(int timerNum);
 
+	uint8 getClock2Timer(int index) { return index < _numClock2Timers ? _clock2Timers[index] : 0; }
+	uint8 getNumClock2Timers()  { return _numClock2Timers; }
+
 	static const uint8 _clock2Timers[];
 	static const uint8 _numClock2Timers;
 
@@ -470,7 +436,7 @@ private:
 	int snd_updateCharacterSpeech();
 	void snd_stopSpeech(bool setFlag);
 	void snd_playSoundEffect(int track, int volume);
-	void snd_processEnvironmentalSoundEffect(int soundId, int block);
+	bool snd_processEnvironmentalSoundEffect(int soundId, int block);
 	void snd_queueEnvironmentalSoundEffect(int soundId, int block);
 	void snd_playQueuedEffects();
 	void snd_loadSoundFile(int track);
@@ -479,21 +445,17 @@ private:
 
 	int _lastSpeechId;
 	int _lastSpeaker;
-	uint32 _activeVoiceFileTotalTime;
 	int _lastSfxTrack;
 	int _lastMusicTrack;
 	int _curMusicFileIndex;
 	char _curMusicFileExt;
-	int _environmentSfx;
-	int _environmentSfxVol;
-	int _envSfxDistThreshold;
 	bool _envSfxUseQueue;
 	int _envSfxNumTracksInQueue;
 	uint16 _envSfxQueuedTracks[10];
 	uint16 _envSfxQueuedBlocks[10];
 	int _nextSpeechId;
 	int _nextSpeaker;
-	typedef Common::List<Audio::SeekableAudioStream *> SpeechList;
+	typedef Common::List<Audio::SeekableAudioStream*> SpeechList;
 	SpeechList _speechList;
 
 	int _curTlkFile;
@@ -502,9 +464,7 @@ private:
 	int _ingameSoundListSize;
 
 	const uint8 *_musicTrackMap;
-	int _musicTrackMapSize;
 	const uint16 *_ingameSoundIndex;
-	int _ingameSoundIndexSize;
 	const uint8 *_ingameGMSoundIndex;
 	int _ingameGMSoundIndexSize;
 	const uint8 *_ingameMT32SoundIndex;
@@ -519,7 +479,6 @@ private:
 	void gui_drawScene(int pageNum);
 	void gui_drawAllCharPortraitsWithStats();
 	void gui_drawCharPortraitWithStats(int charNum);
-	void gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor);
 	void gui_drawCharFaceShape(int charNum, int x, int y, int pageNum);
 	void gui_highlightPortraitFrame(int charNum);
 	void gui_drawLiveMagicBar(int x, int y, int curPoints, int unk, int maxPoints, int w, int h, int col1, int col2, int flag);
@@ -534,7 +493,6 @@ private:
 	void gui_printCharacterStats(int index, int redraw, int value);
 	void gui_changeCharacterStats(int charNum);
 	void gui_drawCharInventoryItem(int itemIndex);
-	void gui_drawBarGraph(int x, int y, int w, int h, int32 curVal, int32 maxVal, int col1, int col2);
 
 	int gui_enableControls();
 	int gui_disableControls(int controlMode);
@@ -548,37 +506,27 @@ private:
 	int _lastButtonShape;
 	uint32 _buttonPressTimer;
 	int _selectedCharacter;
-	int _compassDirection;
 	int _compassStep;
 	int _compassDirectionIndex;
 	uint32 _compassTimer;
 	int _charInventoryUnk;
 
 	const CompassDef *_compassDefs;
-	int _compassDefsSize;
 
 	void gui_updateInput();
 	void gui_triggerEvent(int eventType);
-	void removeInputTop();
 	void gui_enableDefaultPlayfieldButtons();
 	void gui_enableSequenceButtons(int x, int y, int w, int h, int enableFlags);
 	void gui_specialSceneRestoreButtons();
 	void gui_enableCharInventoryButtons(int charNum);
 
-	void gui_resetButtonList();
-	void gui_initButtonsFromList(const int16 *list);
 	void gui_setFaceFramesControlButtons(int index, int xOffs);
 	void gui_initCharInventorySpecialButtons(int charNum);
 	void gui_initMagicScrollButtons();
 	void gui_initMagicSubmenu(int charNum);
 	void gui_initButton(int index, int x = -1, int y = -1, int val = -1);
-	void gui_notifyButtonListChanged();
 
-	Common::Array<Button::Callback> _buttonCallbacks;
-	Button *_activeButtons;
-	Button _activeButtonData[70];
-	ButtonDef _sceneWindowButton;
-	bool _preserveEvents;
+	LoLButtonDef _sceneWindowButton;
 
 	int clickedUpArrow(Button *button);
 	int clickedDownArrow(Button *button);
@@ -613,45 +561,34 @@ private:
 	int clickedLamp(Button *button);
 	int clickedStatusIcon(Button *button);
 
-	const ButtonDef *_buttonData;
-	int _buttonDataSize;
+	Common::Array<Button::Callback> _buttonCallbacks;
+	const LoLButtonDef *_buttonData;
 	const int16 *_buttonList1;
-	int _buttonList1Size;
 	const int16 *_buttonList2;
-	int _buttonList2Size;
 	const int16 *_buttonList3;
-	int _buttonList3Size;
 	const int16 *_buttonList4;
-	int _buttonList4Size;
 	const int16 *_buttonList5;
-	int _buttonList5Size;
 	const int16 *_buttonList6;
-	int _buttonList6Size;
 	const int16 *_buttonList7;
-	int _buttonList7Size;
 	const int16 *_buttonList8;
-	int _buttonList8Size;
 
 	// text
 	int characterSays(int track, int charId, bool redraw);
 	int playCharacterScriptChat(int charId, int mode, int restorePortrait, char *str, EMCState *script, const uint16 *paramList, int16 paramIndex);
+	void setupDialogueButtons(int numStr, const char *s1, const char *s2, const char *s3);
 
 	TextDisplayer_LoL *_txt;
+	TextDisplayer_Eob *txt() { return _txt; }
 
 	// emc scripts
 	void runInitScript(const char *filename, int optionalFunc);
 	void runInfScript(const char *filename);
 	void runLevelScript(int block, int flags);
 	void runLevelScriptCustom(int block, int flags, int charNum, int item, int reg3, int reg4);
-	bool checkSceneUpdateNeed(int func);
 
 	EMCData _scriptData;
 	bool _suspendScript;
 	uint16 _scriptDirection;
-	uint16 _currentDirection;
-	uint16 _currentBlock;
-	bool _sceneUpdateRequired;
-	int16 _visibleBlockIndex[18];
 	int16 _globalScriptVars[24];
 
 	// emc opcode
@@ -702,7 +639,7 @@ private:
 	int olol_checkEquippedItemScriptFlags(EMCState *script);
 	int olol_setDoorState(EMCState *script);
 	int olol_updateBlockAnimations(EMCState *script);
-	int olol_mapShapeToBlock(EMCState *script);
+	int olol_assignLevelDecorationShape(EMCState *script);
 	int olol_resetBlockShapeAssignment(EMCState *script);
 	int olol_copyRegion(EMCState *script);
 	int olol_initMonster(EMCState *script);
@@ -716,7 +653,7 @@ private:
 	int olol_battleHitSkillTest(EMCState *script);
 	int olol_inflictDamage(EMCState *script);
 	int olol_moveMonster(EMCState *script);
-	int olol_dialogueBox(EMCState *script);
+	int olol_setupDialogueButtons(EMCState *script);
 	int olol_giveTakeMoney(EMCState *script);
 	int olol_checkMoney(EMCState *script);
 	int olol_setScriptTimer(EMCState *script);
@@ -792,7 +729,7 @@ private:
 	int olol_assignCustomSfx(EMCState *script);
 	int olol_findAssignedMonster(EMCState *script);
 	int olol_checkBlockForMonster(EMCState *script);
-	int olol_transformRegion(EMCState *script);
+	int olol_crossFadeRegion(EMCState *script);
 	int olol_calcCoordinatesAddDirectionOffset(EMCState *script);
 	int olol_resetPortraitsAndDisableSysTimer(EMCState *script);
 	int olol_enableSysTimer(EMCState *script);
@@ -820,7 +757,7 @@ private:
 	int olol_shakeScene(EMCState *script);
 	int olol_gasExplosion(EMCState *script);
 	int olol_calcNewBlockPosition(EMCState *script);
-	int olol_fadeScene(EMCState *script);
+	int olol_crossFadeScene(EMCState *script);
 	int olol_updateDrawPage2(EMCState *script);
 	int olol_setMouseCursor(EMCState *script);
 	int olol_characterSays(EMCState *script);
@@ -834,14 +771,14 @@ private:
 	// tim opcode
 	void setupOpcodeTable();
 
-	Common::Array<const TIMOpcode *> _timIntroOpcodes;
+	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);
 
-	Common::Array<const TIMOpcode *> _timOutroOpcodes;
+	Common::Array<const TIMOpcode*> _timOutroOpcodes;
 	int tlol_fadeInScene(const TIM *tim, const uint16 *param);
 	int tlol_unusedResourceFunc(const TIM *tim, const uint16 *param);
 	int tlol_fadeInPalette(const TIM *tim, const uint16 *param);
@@ -850,7 +787,7 @@ private:
 	int tlol_delayForChat(const TIM *tim, const uint16 *param);
 	int tlol_fadeOutSound(const TIM *tim, const uint16 *param);
 
-	Common::Array<const TIMOpcode *> _timIngameOpcodes;
+	Common::Array<const TIMOpcode*> _timIngameOpcodes;
 	int tlol_initSceneWindowDialogue(const TIM *tim, const uint16 *param);
 	int tlol_restoreAfterSceneWindowDialogue(const TIM *tim, const uint16 *param);
 	int tlol_giveItem(const TIM *tim, const uint16 *param);
@@ -900,7 +837,6 @@ private:
 	void createTransparencyTables();
 	void updateSequenceBackgroundAnimations();
 
-	bool _dialogueField;
 	uint8 **_itemIconShapes;
 	int _numItemIconShapes;
 	uint8 **_itemShapes;
@@ -913,7 +849,6 @@ private:
 	int _numEffectShapes;
 
 	const int8 *_gameShapeMap;
-	int _gameShapeMapSize;
 
 	uint8 *_characterFaceShapes[40][3];
 
@@ -942,19 +877,13 @@ private:
 
 	LoLCharacter *_characters;
 	uint16 _activeCharsXpos[3];
-	int _updateFlags;
-	int _updateCharNum;
-	int _updatePortraitSpeechAnimDuration;
+
 	int _portraitSpeechAnimMode;
-	int _resetPortraitAfterSpeechAnim;
 	int _textColorFlag;
-	bool _fadeText;
-	int _needSceneRestore;
 	uint32 _palUpdateTimer;
 	uint32 _updatePortraitNext;
 
 	int _loadLevelFlag;
-	int _hasTempDataFlags;
 	int _activeMagicMenu;
 	uint16 _scriptCharacterCycle;
 	int _charStatsTemp[5];
@@ -963,15 +892,10 @@ private:
 	int _charDefaultsSize;
 
 	const uint16 *_charDefsMan;
-	int _charDefsManSize;
 	const uint16 *_charDefsWoman;
-	int _charDefsWomanSize;
 	const uint16 *_charDefsKieran;
-	int _charDefsKieranSize;
 	const uint16 *_charDefsAkshel;
-	int _charDefsAkshelSize;
 	const int32 *_expRequirements;
-	int _expRequirementsSize;
 
 	// lamp
 	void resetLampStatus();
@@ -983,16 +907,14 @@ private:


Commit: ff8a030c379e70d9f90ece071ff9a63495db36cf
    https://github.com/scummvm/scummvm/commit/ff8a030c379e70d9f90ece071ff9a63495db36cf
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:10-08:00

Commit Message:
KYRA: (EOB) - fix EOB1 spell definitions

Changed paths:
    engines/kyra/staticres_eob.cpp



diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 88bfbd8..557bacb 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -942,22 +942,66 @@ void EobEngine::initStaticResource() {
 void EobEngine::initSpells() {
 	EobCoreEngine::initSpells();
 
-	static const uint32 eflags[] = {
-		0x0000, 0x0001, 0x0000, 0x0002, 0x0000, 0x0000, 0x0008, 0x0000, 0x0040, 0x0000,
-		0x0000,	0x0000 /*stinking cloud*/, 0x0000, 0x0000, 0x0000 /*flame arrow*/, 0x10000,0x0000, 0x0040, 0x0000, 0x0000,
-		0x0000, 0x0000, 0x0000 /*stone skin*/, 0x0000 /*cloud kill*/, 0x0000, 0x0000, 0x0400, 0x0000, 0x0000, 0x0002,
-		0x0800,	0x0000, 0x0000, 0x0000, 0x2000, 0x0000, 0x0000, 0x4000, 0x8000, 0x0000,
-		0x0000, 0x0000,	0x0000,	0x0800, 0x0000 /*Prot From Lightning*/, 0x0000,	0x0000,	0x0000, 0x0000, 0x0000,
-		0x0000,	0x0000, 0x0000
+	struct FlagTableEntry {
+		uint16 typeFlag;
+		uint32 effectFlag;
+		uint8 damageFlag;
 	};
 
-	static const uint8 dflags[] = {
-		0x00, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00,
-		0x11, 0x00 /*stinking cloud*/, 0x00, 0x21, 0x11 /*flame arrow*/, 0x00, 0x00, 0x00, 0x03, 0x01,
-		0x00, 0x41, 0x00 /*stone skin*/, 0x00 /*cloud kill*/, 0x41, 0x00, 0x00, 0x00, 0x01, 0x00,
-		0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x01,	0x00, 0x00, 0x00 /*Prot From Lightning*/, 0x00,	0x01, 0x21, 0x00, 0x00,
-		0x00, 0x00, 0x00
+	static const FlagTableEntry flagTable[] = {
+		{ 0x0000, 0x000000, 0x00 },	// dummy
+		{ 0x0033, 0x000001, 0x00 },	// armor
+		{ 0x0100, 0x000000, 0x21 },	// burning hands
+		{ 0x004c, 0x000002, 0x00 },	// detect magic
+		{ 0x0100, 0x000000, 0x01 },	// magic missile
+		{ 0x0000, 0x000000, 0x00 },	// dummy
+		{ 0x008b, 0x000008, 0x00 },	// shield
+		{ 0x0488, 0x000000, 0x03 },	// shocking grasp
+		{ 0x0021, 0x000040, 0x00 },	// invisibility
+		{ 0x0000, 0x000000, 0x00 },	// dummy
+		{ 0x0100, 0x000000, 0x11 },	// melf's acid arrow
+		{ 0x0000, 0x000000, 0x00 },	// STINKING CLOUD
+		{ 0x1000, 0x000000, 0x00 },	// dispel magic
+		{ 0x0100, 0x000000, 0x21 },	// fireball
+		{ 0x0100, 0x000000, 0x11 },	// FLAME ARROW
+		{ 0x0248, 0x010000, 0x00 },	// haste
+		{ 0x0100, 0x000000, 0x00 },	// hold person
+		{ 0x0240, 0x000040, 0x00 },	// inv 10'
+		{ 0x0100, 0x000000, 0x03 },	// lightning bolt
+		{ 0x0488, 0x000000, 0x01 },	// vampiric touch
+		{ 0x0100, 0x000000, 0x00 },	// fear
+		{ 0x0100, 0x000000, 0x41 },	// ice storm
+		{ 0x0000, 0x000000, 0x00 },	// STONE SKIN
+		{ 0x0000, 0x000000, 0x00 },	// CLOUD KILL
+		{ 0x0100, 0x000000, 0x41 },	// cone of cold
+		{ 0x0100, 0x000000, 0x00 },	// hold monster
+		{ 0x005c, 0x000400, 0x00 },	// bless
+		{ 0x0020, 0x000000, 0x00 },	// cure light wounds
+		{ 0x0100, 0x000000, 0x01 },	// cause light wounds
+		{ 0x004c, 0x000002, 0x00 },	// detect magic
+		{ 0x0029, 0x000800, 0x00 },	// prot from evil
+		{ 0x0039, 0x000000, 0x00 },	// aid
+		{ 0x2408, 0x000000, 0x21 },	// flame blade
+		{ 0x0100, 0x000000, 0x00 },	// hold person
+		{ 0x0028, 0x002000, 0x00 },	// slow poison
+		{ 0x0040, 0x000000, 0x00 },	// create food
+		{ 0x1000, 0x000000, 0x00 },	// dispel magic
+		{ 0x0099, 0x004000, 0x00 },	// magical vestment
+		{ 0x004c, 0x008000, 0x00 },	// prayer
+		{ 0x0040, 0x000000, 0x00 },	// remove paralysis
+		{ 0x0020, 0x000000, 0x00 },	// cure serious
+		{ 0x0100, 0x000000, 0x01 },	// cause serious
+		{ 0x0020, 0x000000, 0x00 },	// neutralize poison
+		{ 0x0248, 0x000800, 0x00 },	// prot from evil 10'
+		{ 0x0000, 0x000000, 0x00 },	// PROT FROM LIGHTNING
+		{ 0x0020, 0x000000, 0x00 },	// cure critical
+		{ 0x0100, 0x000000, 0x01 },	// cause critical
+		{ 0x0100, 0x000000, 0x21 },	// flame strike
+		{ 0x0020, 0x000000, 0x00 },	// raise dead
+		{ 0x0020, 0x000000, 0x00 },	// lay on hands
+		{ 0x0000, 0x000000, 0x00 },	// obj hit passive
+		{ 0x0000, 0x000000, 0x00 },	// disintegrate passive
+		{ 0x0000, 0x000000, 0x00 }	// death spell passive
 	};
 
 	int temp;
@@ -967,9 +1011,9 @@ void EobEngine::initSpells() {
 	for (int i = 0; i < _numSpells; i++) {
 		EobSpell *s = &_spells[i];
 		src += 4;
-		s->flags = convertSpellFlagToEob2Format(src[0], src[14]);
-		s->damageFlags = dflags[i];
-		s->effectFlags = eflags[i];
+		s->flags = flagTable[i].typeFlag;/*convertSpellFlagToEob2Format(src[0], src[14]);*/
+		s->damageFlags = flagTable[i].damageFlag;
+		s->effectFlags = flagTable[i].effectFlag;
 		s->sound = src[13];
 		src += 15;
 	}


Commit: aa031bf98ef1b6da485122fabef1178f6101aded
    https://github.com/scummvm/scummvm/commit/aa031bf98ef1b6da485122fabef1178f6101aded
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:10-08:00

Commit Message:
KYRA: (EOB) - minor code size reduction

Changed paths:
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/lol.cpp
    engines/kyra/lol.h
    engines/kyra/loleobbase.cpp
    engines/kyra/loleobbase.h
    engines/kyra/saveload_eob.cpp
    engines/kyra/saveload_lol.cpp



diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index d82a3dd..12a0a0d 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -297,8 +297,9 @@ Common::Error EobCoreEngine::init() {
 		memset(_itemNames[i], 0, 35);
 	}
 
-	_flyingObjects = new EobFlyingObject[10];
-	memset(_flyingObjects, 0, 10 * sizeof(EobFlyingObject));
+	_flyingObjects = new EobFlyingObject[_numFlyingObjects];
+	_flyingObjectsPtr = _flyingObjects;
+	memset(_flyingObjects, 0, _numFlyingObjects * sizeof(EobFlyingObject));
 
 	_spellAnimBuffer = new uint8[4096];
 	memset(_spellAnimBuffer, 0, 4096);
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 201c1df..1ad7b91 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -228,22 +228,6 @@ struct ScriptTimer {
 	uint32 next;
 };
 
-struct EobFlyingObject {
-	uint8 enable;
-	uint8 objectType;
-	int16 attackerId;
-	Item item;
-	uint16 curBlock;
-	uint16 u2;
-	uint8 u1;
-	uint8 direction;
-	uint8 distance;
-	int8 callBackIndex;
-	uint8 curPos;
-	uint8 flags;
-	uint8 unused;
-};
-
 class EobInfProcessor;
 
 class EobCoreEngine : public LolEobBaseEngine {
@@ -770,11 +754,8 @@ protected:
 	Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail);
 
 	void *generateMonsterTempData(LevelTempData *tmp);
-	void *generateFlyingObjectTempData(LevelTempData *tmp);
 	void restoreMonsterTempData(LevelTempData *tmp);
-	void restoreFlyingObjectTempData(LevelTempData *tmp);
 	void releaseMonsterTempData(LevelTempData *tmp);
-	void releaseFlyingObjectTempData(LevelTempData *tmp);
 
 	int _saveLoadMode;
 
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 6cb3b51..ebe6ea6 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -417,8 +417,10 @@ Common::Error LoLEngine::init() {
 	_tempBuffer5120 = new uint8[5120];
 	memset(_tempBuffer5120, 0, 5120);
 
-	_flyingObjects = new FlyingObject[8];
-	memset(_flyingObjects, 0, 8 * sizeof(FlyingObject));
+	_flyingObjects = new FlyingObject[_numFlyingObjects];
+	_flyingObjectsPtr = _flyingObjects;
+	_flyingObjectStructSize = sizeof(FlyingObject);
+	memset(_flyingObjects, 0, _numFlyingObjects * sizeof(FlyingObject));
 
 	memset(_globalScriptVars, 0, sizeof(_globalScriptVars));
 
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index 20519b7..f4fcbeb 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -1299,12 +1299,9 @@ private:
 	Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail);
 
 	void *generateMonsterTempData(LevelTempData *tmp);
-	void *generateFlyingObjectTempData(LevelTempData *tmp);
 	void restoreBlockTempData(int levelIndex);
 	void restoreMonsterTempData(LevelTempData *tmp);
-	void restoreFlyingObjectTempData(LevelTempData *tmp);
 	void releaseMonsterTempData(LevelTempData *tmp);
-	void releaseFlyingObjectTempData(LevelTempData *tmp);
 
 	Graphics::Surface *generateSaveThumbnail() const;
 };
diff --git a/engines/kyra/loleobbase.cpp b/engines/kyra/loleobbase.cpp
index 05b683b..1c4068d 100644
--- a/engines/kyra/loleobbase.cpp
+++ b/engines/kyra/loleobbase.cpp
@@ -29,7 +29,7 @@
 
 namespace Kyra {
 
-LolEobBaseEngine::LolEobBaseEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(system, flags) {
+LolEobBaseEngine::LolEobBaseEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(system, flags), _numFlyingObjects(_flags.gameID == GI_LOL ? 8 : 10) {
 	_txt = 0;
 	_mouseClick = 0;
 	_preserveEvents = _buttonListChanged = false;
@@ -75,6 +75,9 @@ LolEobBaseEngine::LolEobBaseEngine(OSystem *system, const GameFlags &flags) : Ky
 	_updateFlags = _clickedSpecialFlag = 0;
 	_sceneDefaultUpdate = 0;
 	_sceneUpdateRequired = false;
+	
+	_flyingObjectsPtr = 0;
+	_flyingObjectStructSize = sizeof(EobFlyingObject);
 
 	_clickedShapeXOffs = _clickedShapeYOffs = 0;
 
diff --git a/engines/kyra/loleobbase.h b/engines/kyra/loleobbase.h
index 042f9c0..43a8646 100644
--- a/engines/kyra/loleobbase.h
+++ b/engines/kyra/loleobbase.h
@@ -63,6 +63,22 @@ struct LevelTempData {
 	uint8 monsterDifficulty;
 };
 
+struct EobFlyingObject {
+	uint8 enable;
+	uint8 objectType;
+	int16 attackerId;
+	Item item;	
+	uint16 curBlock;
+	uint16 u2;
+	uint8 u1;
+	uint8 direction;
+	uint8 distance;
+	int8 callBackIndex;
+	uint8 curPos;
+	uint8 flags;
+	uint8 unused;
+};
+
 class LolEobBaseEngine : public KyraEngine_v1 {
 friend class TextDisplayer_Eob;
 public:
@@ -289,13 +305,16 @@ protected:
 	void restoreBlockTempData(int levelIndex);
 	void releaseTempData();
 	virtual void *generateMonsterTempData(LevelTempData *tmp) = 0;
-	virtual void *generateFlyingObjectTempData(LevelTempData *tmp) = 0;
 	virtual void restoreMonsterTempData(LevelTempData *tmp) = 0;
-	virtual void restoreFlyingObjectTempData(LevelTempData *tmp) = 0;
 	virtual void releaseMonsterTempData(LevelTempData *tmp) = 0;
-	virtual void releaseFlyingObjectTempData(LevelTempData *tmp) = 0;
+	void restoreFlyingObjectTempData(LevelTempData *tmp);
+	void *generateFlyingObjectTempData(LevelTempData *tmp);
+	void releaseFlyingObjectTempData(LevelTempData *tmp);
 
 	LevelTempData *_lvlTempData[29];
+	const int _numFlyingObjects;
+	uint32 _flyingObjectStructSize;
+	void *_flyingObjectsPtr;
 
 	// sound
 	virtual bool snd_processEnvironmentalSoundEffect(int soundId, int block);
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index 3b3964b..90192a4 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -127,6 +127,23 @@ void LolEobBaseEngine::releaseTempData() {
 	}
 }
 
+void *LolEobBaseEngine::generateFlyingObjectTempData(LevelTempData *tmp) {
+	assert(_flyingObjectStructSize == sizeof(EobFlyingObject));
+	EobFlyingObject *f = new EobFlyingObject[_numFlyingObjects];
+	memcpy(f, _flyingObjectsPtr,  sizeof(EobFlyingObject) * _numFlyingObjects);
+	return f;
+}
+
+void LolEobBaseEngine::restoreFlyingObjectTempData(LevelTempData *tmp) {
+	assert(_flyingObjectStructSize == sizeof(EobFlyingObject));
+	memcpy(_flyingObjectsPtr, tmp->flyingObjects, sizeof(EobFlyingObject) * _numFlyingObjects);
+}
+
+void LolEobBaseEngine::releaseFlyingObjectTempData(LevelTempData *tmp) {
+	EobFlyingObject *p = (EobFlyingObject*)tmp->flyingObjects;
+	delete[] p;
+}
+
 #ifdef ENABLE_EOB
 
 Common::Error EobCoreEngine::loadGameState(int slot) {
@@ -269,7 +286,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 		_lvlTempData[i]->flags = new uint16[1024];
 		EobMonsterInPlay *lm = new EobMonsterInPlay[30];
 		 _lvlTempData[i]->monsters = lm;
-		EobFlyingObject *lf = new EobFlyingObject[10];
+		EobFlyingObject *lf = new EobFlyingObject[_numFlyingObjects];
 		_lvlTempData[i]->flyingObjects = lf;
 		LevelTempData *l = _lvlTempData[i];
 
@@ -305,7 +322,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 			m->sub = in.readByte();
 		}
 
-		for (int ii = 0; ii < 10; ii++) {
+		for (int ii = 0; ii < _numFlyingObjects; ii++) {
 			EobFlyingObject *m = &lf[ii];
 			m->enable = in.readByte();
 			m->objectType = in.readByte();
@@ -481,7 +498,7 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName,
 			out->writeByte(m->sub);
 		}
 
-		for (int ii = 0; ii < 10; ii++) {
+		for (int ii = 0; ii < _numFlyingObjects; ii++) {
 			EobFlyingObject *m = &lf[ii];
 			out->writeByte(m->enable);
 			out->writeByte(m->objectType);
@@ -519,29 +536,15 @@ void *EobCoreEngine::generateMonsterTempData(LevelTempData *tmp) {
 	return m;
 }
 
-void *EobCoreEngine::generateFlyingObjectTempData(LevelTempData *tmp) {
-	EobFlyingObject *f = new EobFlyingObject[10];
-	memcpy(f, _flyingObjects,  sizeof(EobFlyingObject) * 10);
-	return f;
-}
-
 void EobCoreEngine::restoreMonsterTempData(LevelTempData *tmp) {
 	memcpy(_monsters, tmp->monsters, sizeof(EobMonsterInPlay) * 30);
 }
 
-void EobCoreEngine::restoreFlyingObjectTempData(LevelTempData *tmp) {
-	memcpy(_flyingObjects, tmp->flyingObjects, sizeof(EobFlyingObject) * 10);
-}
-
 void EobCoreEngine::releaseMonsterTempData(LevelTempData *tmp) {
 	EobMonsterInPlay *p = (EobMonsterInPlay*)tmp->monsters;
 	delete[] p;
 }
 
-void EobCoreEngine::releaseFlyingObjectTempData(LevelTempData *tmp) {
-
-}
-
 #endif // ENABLE_EOB
 
 }	// End of namespace Kyra
diff --git a/engines/kyra/saveload_lol.cpp b/engines/kyra/saveload_lol.cpp
index 7d8e6c3..33097a8 100644
--- a/engines/kyra/saveload_lol.cpp
+++ b/engines/kyra/saveload_lol.cpp
@@ -195,7 +195,7 @@ Common::Error LoLEngine::loadGameState(int slot) {
 		_lvlTempData[i]->flags = new uint16[1024];
 		LolMonsterInPlay *lm = new LolMonsterInPlay[30];
 		 _lvlTempData[i]->monsters = lm;
-		FlyingObject *lf = new FlyingObject[8];
+		FlyingObject *lf = new FlyingObject[_numFlyingObjects];
 		_lvlTempData[i]->flyingObjects = lf;
 		LevelTempData *l = _lvlTempData[i];
 
@@ -236,7 +236,7 @@ Common::Error LoLEngine::loadGameState(int slot) {
 			in.read(m->equipmentShapes, 4);
 		}
 
-		for (int ii = 0; ii < 8; ii++) {
+		for (int ii = 0; ii < _numFlyingObjects; ii++) {
 			FlyingObject *m = &lf[ii];
 			m->enable = in.readByte();
 			m->objectType = in.readByte();
@@ -420,7 +420,7 @@ Common::Error LoLEngine::saveGameStateIntern(int slot, const char *saveName, con
 			out->write(m->equipmentShapes, 4);
 		}
 
-		for (int ii = 0; ii < 8; ii++) {
+		for (int ii = 0; ii < _numFlyingObjects; ii++) {
 			FlyingObject *m = &lf[ii];
 			out->writeByte(m->enable);
 			out->writeByte(m->objectType);
@@ -489,12 +489,6 @@ void *LoLEngine::generateMonsterTempData(LevelTempData *tmp) {
 	return m;
 }
 
-void *LoLEngine::generateFlyingObjectTempData(LevelTempData *tmp) {
-	FlyingObject *f = new FlyingObject[8];
-	memcpy(f, _flyingObjects,  sizeof(FlyingObject) * 8);
-	return f;
-}
-
 void LoLEngine::restoreTempDataAdjustMonsterStrength(int index) {
 	if (_lvlTempData[index]->monsterDifficulty == _monsterDifficulty)
 		return;
@@ -525,20 +519,11 @@ void LoLEngine::restoreMonsterTempData(LevelTempData *tmp) {
 	}
 }
 
-void LoLEngine::restoreFlyingObjectTempData(LevelTempData *tmp) {
-	memcpy(_flyingObjects, tmp->flyingObjects, sizeof(FlyingObject) * 8);
-}
-
 void LoLEngine::releaseMonsterTempData(LevelTempData *tmp) {
 	LolMonsterInPlay *p = (LolMonsterInPlay*)tmp->monsters;
 	delete[] p;
 }
 
-void LoLEngine::releaseFlyingObjectTempData(LevelTempData *tmp) {
-	FlyingObject *p = (FlyingObject*)tmp->flyingObjects;
-	delete[] p;
-}
-
 } // End of namespace Kyra
 
 #endif // ENABLE_LOL


Commit: 80ece6caaef652e4d0f618ab793c11b00fcf9441
    https://github.com/scummvm/scummvm/commit/80ece6caaef652e4d0f618ab793c11b00fcf9441
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:10-08:00

Commit Message:
KYRA: (EOB) - replace snprintf/sprintf

Changed paths:
    engines/kyra/chargen.cpp
    engines/kyra/eob2.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/items_eob.cpp
    engines/kyra/saveload_eob.cpp
    engines/kyra/scene_eob.cpp
    engines/kyra/screen_eob.cpp
    engines/kyra/sound_towns.cpp
    engines/kyra/text_eob.cpp
    engines/kyra/text_lol.cpp



diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index 4a0e035..59b46b5 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -918,16 +918,15 @@ void CharacterGenerator::printStats(int index, int mode) {
 
 	_screen->printShadedText(_chargenStrings1[2], 248, 64, 15, 0);
 
-	char str[22];
-	snprintf(str, 22,  _chargenStrings1[3], _vm->getCharStrength(c->strengthCur, c->strengthExtCur), c->intelligenceCur, c->wisdomCur, c->dexterityCur, c->constitutionCur, c->charismaCur);
-	_screen->printShadedText(str, 192, 64, 15, 0);
+	Common::String str = Common::String::format(_chargenStrings1[3], _vm->getCharStrength(c->strengthCur, c->strengthExtCur).c_str(), c->intelligenceCur, c->wisdomCur, c->dexterityCur, c->constitutionCur, c->charismaCur);
+	_screen->printShadedText(str.c_str(), 192, 64, 15, 0);
 
-	snprintf(str, 22, _chargenStrings1[4], c->armorClass, c->hitPointsMax);
-	_screen->printShadedText(str, 280, 64, 15, 0);
+	str = Common::String::format(_chargenStrings1[4], c->armorClass, c->hitPointsMax);
+	_screen->printShadedText(str.c_str(), 280, 64, 15, 0);
 
 	const char *lvlStr = c->level[2] ? _chargenStrings1[7] : (c->level[1] ? _chargenStrings1[6] : _chargenStrings1[5]);
-	snprintf(str, 22, lvlStr, c->level[0], c->level[1], c->level[2]);
-	_screen->printShadedText(str, 280, 80, 15, 0);
+	str = Common::String::format(lvlStr, c->level[0], c->level[1], c->level[2]);
+	_screen->printShadedText(str.c_str(), 280, 80, 15, 0);
 
 	switch (mode) {
 	case 1:
@@ -998,14 +997,10 @@ int CharacterGenerator::modifyStat(int index, int8 *stat1, int8 *stat2) {
 	printStats(_activeBox, 3);
 	_vm->removeInputTop();
 
-	char statStr[6];
-	if (index)
-		snprintf(statStr, 6, "%d", *s1);
-	else
-		snprintf(statStr, 6, "%s", _vm->getCharStrength(*s1, *s2));
+	Common::String statStr = index ? Common::String::format("%d", *s1) : _vm->getCharStrength(*s1, *s2);
 
 	_screen->copyRegion(b->x - 112, b->y - 64, b->x + 32, b->y, 40, b->height, 2, 0, Screen::CR_NO_P_CHECK);
-	_screen->printShadedText(statStr, b->x + 32, b->y, 6, 0);
+	_screen->printShadedText(statStr.c_str(), b->x + 32, b->y, 6, 0);
 	_screen->updateScreen();
 
 	EobCharacter *c = &_characters[_activeBox];
@@ -1081,13 +1076,10 @@ int CharacterGenerator::modifyStat(int index, int8 *stat1, int8 *stat2) {
 		if (index == 6)
 			_characters[_activeBox].hitPointsMax = v1;
 
-		if (index)
-			snprintf(statStr, 6, "%d", *s1);
-		else
-			snprintf(statStr, 6, "%s", _vm->getCharStrength(*s1, *s2));
+		statStr = index ? Common::String::format("%d", *s1) : _vm->getCharStrength(*s1, *s2);
 
 		_screen->copyRegion(b->x - 112, b->y - 64, b->x + 32, b->y, 40, b->height, 2, 0, Screen::CR_NO_P_CHECK);
-		_screen->printShadedText(statStr, b->x + 32, b->y, 6, 0);
+		_screen->printShadedText(statStr.c_str(), b->x + 32, b->y, 6, 0);
 		_screen->updateScreen();
 
 		if (index == 4) {
@@ -1097,9 +1089,9 @@ int CharacterGenerator::modifyStat(int index, int8 *stat1, int8 *stat2) {
 			c->hitPointsMax = c->hitPointsCur = CLIP<int16>(c->hitPointsCur, _chargenMinStats[6], _chargenMaxStats[6]);
 
 			if (c->hitPointsCur != oldVal) {
-				snprintf(statStr, 6, "%d", c->hitPointsCur);
+				statStr = Common::String::format("%d", c->hitPointsCur);
 				_screen->copyRegion(120, 72, 264, 136, 40, 8, 2, 0, Screen::CR_NO_P_CHECK);
-				_screen->printShadedText(statStr, 264, 136, 15, 0);
+				_screen->printShadedText(statStr.c_str(), 264, 136, 15, 0);
 				_screen->updateScreen();
 			}
 
@@ -1108,19 +1100,16 @@ int CharacterGenerator::modifyStat(int index, int8 *stat1, int8 *stat2) {
 			c->armorClass = _vm->getDexterityArmorClassModifier(v1) + 10;
 
 			if (c->armorClass != oldVal) {
-				snprintf(statStr, 6, "%d", c->armorClass);
+				statStr = Common::String::format("%d", c->armorClass);
 				_screen->copyRegion(120, 64, 264, 128, 40, 8, 2, 0, Screen::CR_NO_P_CHECK);
-				_screen->printShadedText(statStr, 264, 128, 15, 0);
+				_screen->printShadedText(statStr.c_str(), 264, 128, 15, 0);
 				_screen->updateScreen();
 			}
 		}
 
 		if (loop = false) {
-			if (index)
-				snprintf(statStr, 6, "%d", *s1);
-			else
-				snprintf(statStr, 6, "%s", _vm->getCharStrength(*s1, *s2));
-			_screen->printText(statStr, b->x + 32, b->y, 15, 0);
+			statStr = index ? Common::String::format("%d", *s1) : _vm->getCharStrength(*s1, *s2);
+			_screen->printText(statStr.c_str(), b->x + 32, b->y, 15, 0);
 			_screen->updateScreen();
 		}
 	}
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index 120ad15..5af5049 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -208,10 +208,7 @@ void DarkMoonEngine::generateMonsterPalettes(const char *file, int16 monsterInde
 }
 
 void DarkMoonEngine::loadMonsterDecoration(const char *file, int16 monsterIndex) {
-	char filename[13];
-	snprintf(filename, 13, "%s.dcr", file);
-
-	Common::SeekableReadStream *s = _res->createReadStream(filename);
+	Common::SeekableReadStream *s = _res->createReadStream(Common::String::format("%s.dcr", file));
 	if (!s)
 		return;
 
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 12a0a0d..97b871c 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -706,13 +706,13 @@ int EobCoreEngine::getModifiedHpLimits(int hpModifier, int constModifier, int le
 	return res;
 }
 
-const char *EobCoreEngine::getCharStrength(int str, int strExt) {
+Common::String EobCoreEngine::getCharStrength(int str, int strExt) {
 	if (strExt) {
 		if (strExt == 100)
 			strExt = 0;
-		snprintf(_strenghtStr, 6, "%d/%02d", str, strExt);
+		_strenghtStr = Common::String::format("%d/%02d", str, strExt);
 	} else {
-		snprintf(_strenghtStr, 6, "%d", str);
+		_strenghtStr = Common::String::format("%d", str);
 	}
 
 	return _strenghtStr;
@@ -979,9 +979,8 @@ int EobCoreEngine::npcJoinDialogue(int npcIndex, int queryJoinTextId, int confir
 	int r = runDialogue(-1, 0, _yesNoStrings[0], _yesNoStrings[1]) - 1;
 	if (r == 0) {
 		if (confirmJoinTextId == -1) {
-			char tmp[35];
-			snprintf(tmp, 35, _npcJoinStrings[0], _npcPreset[npcIndex].name);
-			_txt->printDialogueText(tmp, true);
+			Common::String tmp = Common::String::format(_npcJoinStrings[0], _npcPreset[npcIndex].name);
+			_txt->printDialogueText(tmp.c_str(), true);
 		} else {
 			_txt->printDialogueText(confirmJoinTextId, _okStrings[0]);
 		}
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 1ad7b91..e88ab84 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -345,7 +345,7 @@ protected:
 	int getClassAndConstHitpointsModifier(int cclass, int constitution);
 	int getClassHpIncreaseType(int cclass, int levelIndex);
 	int getModifiedHpLimits(int hpModifier, int constModifier, int level, bool mode);
-	const char *getCharStrength(int str, int strExt);
+	Common::String getCharStrength(int str, int strExt);
 	int testCharacter(int index, int flags);
 	int getNextValidCharIndex(int curCharIndex, int searchStep);
 
@@ -374,7 +374,7 @@ protected:
 	void setWeaponSlotStatus(int charIndex, int mode, int slot);
 
 	EobCharacter *_characters;
-	char _strenghtStr[6];
+	Common::String _strenghtStr;
 	int _castScrollSlot;
 	int _exchangeCharacterId;
 
@@ -525,7 +525,7 @@ protected:
 
 	// Level
 	void loadLevel(int level, int func);
-	const char *initLevelData(int func);
+	Common::String initLevelData(int func);
 	void addLevelItems();
 	void loadVcnData(const char *file, const char */*nextFile*/);
 	void loadBlockProperties(const char *mazFile);
@@ -562,7 +562,7 @@ protected:
 	SpriteDecoration *_doorSwitches;
 
 	int8 _currentSub;
-	char _curGfxFile[13];
+	Common::String _curGfxFile;
 
 	uint32 _drawSceneTimer;
 	uint32 _flashShapeTimer;
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 9aafb76..34ab190 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -188,8 +188,6 @@ void EobCoreEngine::gui_drawCharPortraitWithStats(int index) {
 		txtCol2 = 6;
 	}
 
-	char tmpStr[10];
-
 	if (_currentControlMode == 0) {
 		int x2 = charPortraitPosX[index & 1];
 		int y2 = charPortraitPosY[index >> 1];
@@ -214,8 +212,8 @@ void EobCoreEngine::gui_drawCharPortraitWithStats(int index) {
 
 		if (c->damageTaken > 0) {
 			_screen->drawShape(2, _redSplatShape, x2 + 13, y2 + 30, 0);
-			sprintf(tmpStr, "%d", c->damageTaken);
-			_screen->printText(tmpStr, x2 + 34 - (strlen(tmpStr) * 3), y2 + 42, 15, 0);
+			Common::String tmpStr = Common::String::format("%d", c->damageTaken);
+			_screen->printText(tmpStr.c_str(), x2 + 34 - tmpStr.size() * 3, y2 + 42, 15, 0);
 		}
 
 		_screen->setCurPage(cp);
@@ -272,19 +270,13 @@ void EobCoreEngine::gui_drawCharPortraitWithStats(int index) {
 			_screen->printText(_characterGuiStringsIn[2], 239, 138, 12, _color6);
 			_screen->printText(_characterGuiStringsIn[3], 278, 138, 12, _color6);
 
-			_screen->printText(getCharStrength(c->strengthCur, c->strengthExtCur), 275, 82, 15, _color6);
-			sprintf(tmpStr, "%d", c->intelligenceCur);
-			_screen->printText(tmpStr, 275, 89, 15, _color6);
-			sprintf(tmpStr, "%d", c->wisdomCur);
-			_screen->printText(tmpStr, 275, 96, 15, _color6);
-			sprintf(tmpStr, "%d", c->dexterityCur);
-			_screen->printText(tmpStr, 275, 103, 15, _color6);
-			sprintf(tmpStr, "%d", c->constitutionCur);
-			_screen->printText(tmpStr, 275, 110, 15, _color6);
-			sprintf(tmpStr, "%d", c->charismaCur);
-			_screen->printText(tmpStr, 275, 117, 15, _color6);
-			sprintf(tmpStr, "%d", c->armorClass);
-			_screen->printText(tmpStr, 275, 124, 15, _color6);
+			_screen->printText(getCharStrength(c->strengthCur, c->strengthExtCur).c_str(), 275, 82, 15, _color6);
+			_screen->printText(Common::String::format("%d", c->intelligenceCur).c_str(), 275, 89, 15, _color6);
+			_screen->printText(Common::String::format("%d", c->wisdomCur).c_str(), 275, 96, 15, _color6);
+			_screen->printText(Common::String::format("%d", c->dexterityCur).c_str(), 275, 103, 15, _color6);
+			_screen->printText(Common::String::format("%d", c->constitutionCur).c_str(), 275, 110, 15, _color6);
+			_screen->printText(Common::String::format("%d", c->charismaCur).c_str(), 275, 117, 15, _color6);
+			_screen->printText(Common::String::format("%d", c->armorClass).c_str(), 275, 124, 15, _color6);
 
 			for (int i = 0; i < 3; i++) {
 				int t = getClassHpIncreaseType(c->cClass, i);
@@ -292,10 +284,10 @@ void EobCoreEngine::gui_drawCharPortraitWithStats(int index) {
 					continue;
 
 				_screen->printText(_chargenClassStrings[t + 15], 180, 145 + 7 * i, 12, _color6);
-				sprintf(tmpStr, "%d", c->experience[i]);
-				_screen->printText(tmpStr, 251 - strlen(tmpStr) * 3, 145 + 7 * i, 15, _color6);
-				sprintf(tmpStr, "%d", c->level[i]);
-				_screen->printText(tmpStr, 286 - strlen(tmpStr) * 3, 145 + 7 * i, 15, _color6);
+				Common::String tmpStr = Common::String::format("%d", c->experience[i]);
+				_screen->printText(tmpStr.c_str(), 251 - tmpStr.size() * 3, 145 + 7 * i, 15, _color6);
+				tmpStr = Common::String::format("%d", c->level[i]);
+				_screen->printText(tmpStr.c_str(), 286 - tmpStr.size() * 3, 145 + 7 * i, 15, _color6);
 			}
 		}
 
@@ -397,10 +389,9 @@ void EobCoreEngine::gui_drawWeaponSlot(int charIndex, int slot) {
 }
 
 void EobCoreEngine::gui_drawWeaponSlotStatus(int x, int y, int status) {
-	char tmpStr[6];
-	char tmpStr2[6];
-	tmpStr2[0] = 0;
-
+	Common::String tmpStr;
+	Common::String tmpStr2;
+	
 	if (status > -3 || status == -5)
 		_screen->drawShape(_screen->_curPage, _greenSplatShape, x - 1, y, 0);
 	else
@@ -408,32 +399,32 @@ void EobCoreEngine::gui_drawWeaponSlotStatus(int x, int y, int status) {
 
 	switch (status + 5) {
 		case 0:
-			strcpy(tmpStr, _characterGuiStringsWp[2]);
+			tmpStr = _characterGuiStringsWp[2];
 			break;
 		case 1:
-			strcpy(tmpStr, _characterGuiStringsWr[2]);
-			strcpy(tmpStr2, _characterGuiStringsWr[3]);
+			tmpStr = _characterGuiStringsWr[2];
+			tmpStr2 = _characterGuiStringsWr[3];
 			break;
 		case 2:
-			strcpy(tmpStr, _characterGuiStringsWr[0]);
-			strcpy(tmpStr2, _characterGuiStringsWr[1]);
+			tmpStr = _characterGuiStringsWr[0];
+			tmpStr2 = _characterGuiStringsWr[1];
 			break;
 		case 3:
-			strcpy(tmpStr, _characterGuiStringsWp[1]);
+			tmpStr = _characterGuiStringsWp[1];
 			break;
 		case 4:
-			strcpy(tmpStr, _characterGuiStringsWp[0]);
+			tmpStr = _characterGuiStringsWp[0];
 			break;
 		default:
-			snprintf(tmpStr, 6, "%d", status);
+			tmpStr = Common::String::format("%d", status);
 			break;
 	}
 
-	if (tmpStr2[0]) {
-		_screen->printText(tmpStr, x + (16 - strlen(tmpStr) * 3), y + 2, 15, 0);
-		_screen->printText(tmpStr2, x + (16 - strlen(tmpStr) * 3), y + 9, 15, 0);
+	if (!tmpStr2.empty()) {
+		_screen->printText(tmpStr.c_str(), x + (16 - tmpStr.size() * 3), y + 2, 15, 0);
+		_screen->printText(tmpStr2.c_str(), x + (16 - tmpStr.size() * 3), y + 9, 15, 0);
 	} else {
-		_screen->printText(tmpStr, x + (16 - strlen(tmpStr) * 3), y + 5, 15, 0);
+		_screen->printText(tmpStr.c_str(), x + (16 - tmpStr.size() * 3), y + 5, 15, 0);
 	}
 }
 
@@ -479,15 +470,14 @@ void EobCoreEngine::gui_drawHitpoints(int index) {
 		gui_drawHorizontalBarGraph(x, y, w, h, bgCur, bgMax, barColor[col], _color5);
 
 	} else {
-		char tmpString[12];
-		snprintf(tmpString, 12, _characterGuiStringsHp[1], c->hitPointsCur, c->hitPointsMax);
+		Common::String tmpString = Common::String::format(_characterGuiStringsHp[1], c->hitPointsCur, c->hitPointsMax);
 
 		if (!_currentControlMode) {
 			x -= 13;
 			y -= 1;
 		}
 
-		_screen->printText(tmpString, x, y, 12, _bkgColor_1);
+		_screen->printText(tmpString.c_str(), x, y, 12, _bkgColor_1);
 	}
 }
 
@@ -596,9 +586,8 @@ void EobCoreEngine::gui_drawInventoryItem(int slot, int special, int pageNum) {
 			_screen->fillRect(227, 65, 238, 69, 12);
 			int cnt = countQueuedItems(_characters[_updateCharNum].inventory[slot], -1, -1, 1, 1);
 			x = cnt >= 10 ? 227 : 233;
-			char str[3];
-			snprintf(str, 3, "%d", cnt);
-			_screen->printText(str, x, 65, 15, 0);
+			Common::String str = Common::String::format("%d", cnt);
+			_screen->printText(str.c_str(), x, 65, 15, 0);
 		}
 	}
 
@@ -653,9 +642,7 @@ void EobCoreEngine::gui_drawSpellbook() {
 			_screen->printText(_magicStrings7[i], i * 21 + 73, 123, 12, 0);
 		} else {
 			gui_drawBox(i * 18 + 68, 121, 18, 9, col1, col2, col3);
-			char val[3];
-			sprintf(val, "%d", i + 1);
-			_screen->printText(val, i * 18 + 75, 123, 12, 0);
+			_screen->printText(Common::String::format("%d", i + 1).c_str(), i * 18 + 75, 123, 12, 0);
 		}
 	}
 
diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
index 4f6982a..9e87b7c 100644
--- a/engines/kyra/items_eob.cpp
+++ b/engines/kyra/items_eob.cpp
@@ -319,7 +319,7 @@ void EobCoreEngine::printFullItemName(Item item) {
 	const char *tstr3 = 0;
 	int e = 0;
 
-	char tmpString[61];
+	Common::String tmpString;
 
 	if ((itm->flags & 0x40) && !strlen(nameId)) {
 		switch (f) {
@@ -328,11 +328,11 @@ void EobCoreEngine::printFullItemName(Item item) {
 			case 2:
 			case 3:
 				if (v == 0)
-					strcpy(tmpString, nameUnid);
+					tmpString = nameUnid;
 				else if (v < 0)
-					sprintf(tmpString, _itemExtraStrings[3], v, nameUnid);
+					tmpString = Common::String::format(_itemExtraStrings[3], v, nameUnid);
 				else
-					sprintf(tmpString, _itemExtraStrings[4], v, nameUnid);
+					tmpString = Common::String::format(_itemExtraStrings[4], v, nameUnid);
 				break;
 
 			case 9:
@@ -370,30 +370,30 @@ void EobCoreEngine::printFullItemName(Item item) {
 				break;
 
 			default:
-				strcpy(tmpString, nameUnid);
+				tmpString = nameUnid;
 				break;
 		}
 	
 
 		if (tstr3) {
 			if (!tstr2) {
-				sprintf(tmpString, _itemExtraStrings[_flags.lang == Common::EN_ANY ? 10 : 11], tstr3);
+				tmpString = Common::String::format(_itemExtraStrings[_flags.lang == Common::EN_ANY ? 10 : 11], tstr3);
 			} else {
 				if (e == 1) {
 					if (tstr2 == _itemExtraStrings[12])
-						sprintf(tmpString, _itemExtraStrings[_flags.lang == Common::EN_ANY ? 11 : 14], tstr2, tstr3);
+						tmpString = Common::String::format(_itemExtraStrings[_flags.lang == Common::EN_ANY ? 11 : 14], tstr2, tstr3);
 					else
-						sprintf(tmpString, _itemExtraStrings[_flags.gameID == GI_EOB1 ? 10 : (_flags.lang == Common::EN_ANY ? 11 : 13)], tstr2, tstr3);
+						tmpString = Common::String::format(_itemExtraStrings[_flags.gameID == GI_EOB1 ? 10 : (_flags.lang == Common::EN_ANY ? 11 : 13)], tstr2, tstr3);
 				} else {
-					sprintf(tmpString, _itemExtraStrings[_flags.gameID == GI_EOB1 ? 10 : (_flags.lang == Common::EN_ANY ? 11 : 15)], tstr2, tstr3);
+					tmpString = Common::String::format(_itemExtraStrings[_flags.gameID == GI_EOB1 ? 10 : (_flags.lang == Common::EN_ANY ? 11 : 15)], tstr2, tstr3);
 				}
 			}
 		}
 	} else {
-		strcpy(tmpString, (itm->flags & 0x40) ? nameId : nameUnid);
+		tmpString = (itm->flags & 0x40) ? nameId : nameUnid;
 	}
 
-	_txt->printMessage(tmpString);
+	_txt->printMessage(tmpString.c_str());
 }
 
 void EobCoreEngine::identifyQueuedItems(Item itemQueue) {
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index 90192a4..ee91b65 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -47,16 +47,13 @@ void LolEobBaseEngine::generateTempData() {
 	_lvlTempData[l]->wallsXorData = new uint8[4096];
 	_lvlTempData[l]->flags = new uint16[1024];
 
-	char filename[13];
 	const uint8 *p = 0;
 	const uint8 *p2 = 0;
 	if (_flags.gameID == GI_LOL) {
-		snprintf(filename, sizeof(filename), "LEVEL%d.CMZ", _currentLevel);
-		screen()->loadBitmap(filename, 15, 15, 0);
+		screen()->loadBitmap(Common::String::format("LEVEL%d.CMZ", _currentLevel).c_str(), 15, 15, 0);
 		p = screen()->getCPagePtr(14);
 	} else {
-		snprintf(filename, sizeof(filename), "LEVEL%d.MAZ", _currentLevel);
-		p2 = p = _res->fileData(filename, 0);
+		p2 = p = _res->fileData(Common::String::format("LEVEL%d.MAZ", _currentLevel).c_str(), 0);
 	}
 
 	uint16 len = READ_LE_UINT16(p + 4);
@@ -82,16 +79,13 @@ void LolEobBaseEngine::generateTempData() {
 
 void LolEobBaseEngine::restoreBlockTempData(int levelIndex) {
 	int l = levelIndex - 1;
-	char filename[13];
 	const uint8 *p = 0;
 	const uint8 *p2 = 0;
 	if (_flags.gameID == GI_LOL) {
-		snprintf(filename, sizeof(filename), "LEVEL%d.CMZ", levelIndex);
-		screen()->loadBitmap(filename, 3, 3, 0);
+		screen()->loadBitmap(Common::String::format("LEVEL%d.CMZ", levelIndex).c_str(), 3, 3, 0);
 		p = screen()->getCPagePtr(2);
 	} else {
-		snprintf(filename, sizeof(filename), "LEVEL%d.MAZ", levelIndex);
-		p2 = p = _res->fileData(filename, 0);
+		p2 = p = _res->fileData(Common::String::format("LEVEL%d.MAZ", levelIndex).c_str(), 0);
 	}
 
 	uint16 len = READ_LE_UINT16(p + 4);
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index 90aa9ff..f8f527c 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -621,28 +621,23 @@ void EobCoreEngine::loadLevel(int level, int sub) {
 	_currentLevel = level;
 	_currentSub = sub;
 
-	char file[13];
-	snprintf(file, 13, "LEVEL%d.INF", level);
-
-	Common::SeekableReadStream *s = _res->createReadStream(file);
-	if (!s) {
-		snprintf(file, 13, "LEVEL%d.DRO", level);
-		s = _res->createReadStream(file);
-	}
-
-	if (!s) {
-		snprintf(file, 13, "LEVEL%d.ELO", level);
-		s = _res->createReadStream(file);
+	Common::String file;
+	Common::SeekableReadStream *s = 0;
+	static const char *suffix[] = { "INF", "DRO", "ELO", 0 };
+	
+	for (const char *const *sf = suffix; *sf && !s; sf++) {
+		file = Common::String::format("LEVEL%d.%s", level, *sf);
+		s = _res->createReadStream(file.c_str());
 	}
 
 	if (!s)
-		error("Failed loading level file LEVEL%d.INF/DRO/ELO", level);
+		error("Failed to load level file LEVEL%d.INF/DRO/ELO", level);
 
 	if (s->readUint16LE() + 2 == s->size()) {
 		if (s->readUint16LE() == 4) {
 			delete s;
 			s = 0;
-			_screen->loadBitmap(file, 5, 5, 0);
+			_screen->loadBitmap(file.c_str(), 5, 5, 0);
 		}
 	}
 
@@ -652,7 +647,7 @@ void EobCoreEngine::loadLevel(int level, int sub) {
 		delete s;
 	}
 
-	const char *gfxFile = initLevelData(sub);
+	Common::String gfxFile = initLevelData(sub);
 
 	const uint8 *data = _screen->getCPagePtr(5);
 	const uint8 *pos = data + READ_LE_UINT16(data);
@@ -694,7 +689,7 @@ void EobCoreEngine::loadLevel(int level, int sub) {
 		pos += 2;
 	}
 
-	loadVcnData(gfxFile, 0);
+	loadVcnData(gfxFile.c_str(), 0);
 	_screen->loadEobCpsFileToPage("INVENT", 0, 5, 3, 2);
 
 	enableSysTimer(2);
@@ -703,13 +698,12 @@ void EobCoreEngine::loadLevel(int level, int sub) {
 	_screen->setCurPage(0);
 }
 
-const char *EobCoreEngine::initLevelData(int sub){
+Common::String EobCoreEngine::initLevelData(int sub){
 	const uint8 *data = _screen->getCPagePtr(5) + 2;
 	const uint8 *pos = data;
 
 	int slen = (_flags.gameID == GI_EOB1) ? 12 : 13;
 
-	char tmpStr[13];
 	_sound->playTrack(0);
 
 	for (int i = 0; i < sub; i++)
@@ -723,8 +717,7 @@ const char *EobCoreEngine::initLevelData(int sub){
 		loadBlockProperties((const char*)pos);
 		pos += slen;
 
-		snprintf(tmpStr, slen, "%s.VMP", (const char*) pos);
-		Common::SeekableReadStream *s = _res->createReadStream(tmpStr);
+		Common::SeekableReadStream *s = _res->createReadStream(Common::String::format("%s.VMP", (const char*)pos).c_str());
 		uint16 size = s->readUint16LE();
 		delete[] _vmpPtr;
 		_vmpPtr = new uint16[size];
@@ -732,12 +725,12 @@ const char *EobCoreEngine::initLevelData(int sub){
 			_vmpPtr[i] = s->readUint16LE();
 		delete s;
 
-		snprintf(tmpStr, 13, "%s.PAL", (const char*) pos);
-		strcpy(_curGfxFile, (const char*) pos);
+		Common::String tmpStr = Common::String::format("%s.PAL", (const char*) pos);
+		_curGfxFile = (const char*) pos;
 		pos += slen;
 
 		if (*pos++ != 0xff && _flags.gameID == GI_EOB2) {
-			snprintf(tmpStr, 13, "%s.PAL", (const char*) pos);
+			tmpStr = Common::String::format("%s.PAL", (const char*) pos);
 			pos += 13;
 		}
 
@@ -749,7 +742,7 @@ const char *EobCoreEngine::initLevelData(int sub){
 			_screen->setShapeFadeMode(1, false);
 		} ////////////////////
 		else
-			_screen->loadPalette(tmpStr, _screen->getPalette(0));
+			_screen->loadPalette(tmpStr.c_str(), _screen->getPalette(0));
 		////////////////////7
 
 		Palette backupPal(256);
@@ -856,10 +849,8 @@ void EobCoreEngine::addLevelItems() {
 void EobCoreEngine::loadVcnData(const char *file, const char*/*nextFile*/) {
 	if (file)
 		strcpy(_lastBlockDataFile, file);
-
-	char fname[13];
-	snprintf(fname, sizeof(fname), "%s.VCN", _lastBlockDataFile);
-	_screen->loadBitmap(fname, 3, 3, 0);
+	
+	_screen->loadBitmap(Common::String::format("%s.VCN", _lastBlockDataFile).c_str(), 3, 3, 0);
 	const uint8 *v = _screen->getCPagePtr(2);
 	uint32 tlen = READ_LE_UINT16(v) << 5;
 	v += 2;
diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp
index eb5a524..f095b04 100644
--- a/engines/kyra/screen_eob.cpp
+++ b/engines/kyra/screen_eob.cpp
@@ -146,15 +146,13 @@ void Screen_Eob::loadEobBitmap(const char *file, int tempPage, int destPage) {
 }
 
 void Screen_Eob::loadEobCpsFileToPage(const char *file, const uint8 *ditheringData, int tempPage, int destPage, int copyToPage) {
-	char tmp[13];
-	sprintf(tmp, "%s.CPS", file);
-
+	Common::String tmp = Common::String::format("%s.CPS", file);
 	Common::SeekableReadStream *s = _vm->resource()->createReadStream(tmp);
 	bool loadAlternative = false;
 	if (s) {
 		// This additional check is necessary since some localized versions of EOB II seem to contain invalid (size zero) cps files
 		if (s->size())
-			loadBitmap(tmp, tempPage, destPage, 0);
+			loadBitmap(tmp.c_str(), tempPage, destPage, 0);
 		else
 			loadAlternative = true;
 
@@ -164,7 +162,7 @@ void Screen_Eob::loadEobCpsFileToPage(const char *file, const uint8 *ditheringDa
 	}
 
 	if (loadAlternative) {
-		tmp[0] = 'X';
+		tmp.setChar('X', 0);
 		s = _vm->resource()->createReadStream(tmp);
 		if (!s)
 			error("Screen_Eob::loadEobCpsFileToPage(): CPS file loading failed.");
diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp
index b77c307..2f996de 100644
--- a/engines/kyra/sound_towns.cpp
+++ b/engines/kyra/sound_towns.cpp
@@ -414,14 +414,9 @@ void SoundPC98::playTrack(uint8 track) {
 
 	beginFadeOut();
 
-	char musicfile[13];
-	sprintf(musicfile, fileListEntry(0), track);
-	if (fileListLen() == 1)
-		sprintf(musicfile, fileListEntry(0), track);
-	else
-		strcpy(musicfile, fileListEntry(track));
+	Common::String musicFile = fileListLen() == 1 ? Common::String::format(fileListEntry(0), track) : fileListEntry(track);
 	delete[] _musicTrackData;
-	_musicTrackData = _vm->resource()->fileData(musicfile, 0);
+	_musicTrackData = _vm->resource()->fileData(musicFile.c_str(), 0);
 	if (_musicEnabled)
 		_driver->loadMusicData(_musicTrackData);
 
@@ -537,17 +532,12 @@ void SoundTownsPC98_v2::playTrack(uint8 track) {
 
 	beginFadeOut();
 
-	char musicfile[13];
-	if (fileListLen() == 1) {
-		sprintf(musicfile, fileListEntry(0), track);
-	} else {
-		strcpy(musicfile, fileListEntry(track));
-		if (!musicfile[0])
-			return;
-	}
+	Common::String musicFile = fileListLen() == 1 ? Common::String::format(fileListEntry(0), track) : fileListEntry(track);
+	if (musicFile.empty())
+		return;
 	delete[] _musicTrackData;
 
-	_musicTrackData = _vm->resource()->fileData(musicfile, 0);
+	_musicTrackData = _vm->resource()->fileData(musicFile.c_str(), 0);
 	_driver->loadMusicData(_musicTrackData, true);
 
 	if (_musicEnabled == 2 && trackNum != -1) {
@@ -592,11 +582,9 @@ int32 SoundTownsPC98_v2::voicePlay(const char *file, Audio::SoundHandle *handle,
 			return 0;
 	}
 
-	char filename[13];
-	const char *pattern = _vm->game() == GI_LOL ? patternLOL : patternHOF;
-	sprintf(filename, pattern, file);
+	Common::String fileName = Common::String::format( _vm->game() == GI_LOL ? patternLOL : patternHOF, file);
 
-	uint8 *data = _vm->resource()->fileData(filename, 0);
+	uint8 *data = _vm->resource()->fileData(fileName.c_str(), 0);
 	uint8 *src = data;
 	if (!src)
 		return 0;
diff --git a/engines/kyra/text_eob.cpp b/engines/kyra/text_eob.cpp
index dc53ae2..0d9bf9d 100644
--- a/engines/kyra/text_eob.cpp
+++ b/engines/kyra/text_eob.cpp
@@ -125,7 +125,7 @@ void TextDisplayer_Eob::displayText(char *str, ...) {
 
 		if (!_tempString2 && c == '%') {
 			if (a == 'd') {
-				snprintf(_scriptParaString, 11, "%d", va_arg(args, int));
+				strcpy(_scriptParaString, Common::String::format("%d", va_arg(args, int)).c_str());
 				_tempString2 = _scriptParaString;
 			} else if (a == 's') {
 				_tempString2 = va_arg(args, char *);
@@ -471,8 +471,7 @@ void TextDisplayer_Eob::printMessage(const char *str, int textColor, ...) {
 
 	displayText(_dialogueBuffer);
 
-	//if (textColor != -1)
-		_textDimData[screen()->curDimIndex()].color1 = tc;
+	_textDimData[screen()->curDimIndex()].color1 = tc;
 
 	if (!screen()->_curPage)
 		screen()->updateScreen();
diff --git a/engines/kyra/text_lol.cpp b/engines/kyra/text_lol.cpp
index 3127e6d..da1efa3 100644
--- a/engines/kyra/text_lol.cpp
+++ b/engines/kyra/text_lol.cpp
@@ -303,7 +303,7 @@ void TextDisplayer_LoL::preprocessString(char *str, EMCState *script, const uint
 
 		switch (para) {
 		case 'a':
-			snprintf(dst, 7, "%d", _scriptTextParameter);
+			strcpy(dst, Common::String::format("%d", _scriptTextParameter).c_str());
 			dst += strlen(dst);
 			break;
 
@@ -321,7 +321,7 @@ void TextDisplayer_LoL::preprocessString(char *str, EMCState *script, const uint
 		case 'd':
 		case 'u':
 		case 'x':
-			snprintf(dst, 7, "%d", script ? script->stack[script->sp + paramIndex] : paramList[paramIndex]);
+			strcpy(dst, Common::String::format("%d", script ? script->stack[script->sp + paramIndex] : paramList[paramIndex]).c_str());
 			dst += strlen(dst);
 			break;
 


Commit: 089ad94b681df8f4493cecc0ba7bc2d3d31b8ddb
    https://github.com/scummvm/scummvm/commit/089ad94b681df8f4493cecc0ba7bc2d3d31b8ddb
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:10-08:00

Commit Message:
KYRA: (EOB) - minor cleanup

Changed paths:
    engines/kyra/scene_eob.cpp



diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index f8f527c..be106a9 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -627,7 +627,7 @@ void EobCoreEngine::loadLevel(int level, int sub) {
 	
 	for (const char *const *sf = suffix; *sf && !s; sf++) {
 		file = Common::String::format("LEVEL%d.%s", level, *sf);
-		s = _res->createReadStream(file.c_str());
+		s = _res->createReadStream(file);
 	}
 
 	if (!s)
@@ -717,7 +717,7 @@ Common::String EobCoreEngine::initLevelData(int sub){
 		loadBlockProperties((const char*)pos);
 		pos += slen;
 
-		Common::SeekableReadStream *s = _res->createReadStream(Common::String::format("%s.VMP", (const char*)pos).c_str());
+		Common::SeekableReadStream *s = _res->createReadStream(Common::String::format("%s.VMP", (const char*)pos));
 		uint16 size = s->readUint16LE();
 		delete[] _vmpPtr;
 		_vmpPtr = new uint16[size];


Commit: 77d210765a2e1e299d2321863f5cc543b64ee1bb
    https://github.com/scummvm/scummvm/commit/77d210765a2e1e299d2321863f5cc543b64ee1bb
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:11-08:00

Commit Message:
KYRA: (EOB) - add some static res (flight object data) to kyra.dat

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/lol.cpp
    engines/kyra/loleobbase.cpp
    engines/kyra/resource.h
    engines/kyra/staticres_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index 5c923be..d20b004 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -322,6 +322,13 @@ const ExtractFilename extractFilenames[] = {
 	{ kEobBaseMagicStrings6, kTypeStringList, true },
 	{ kEobBaseMagicStrings7, kTypeStringList, true },
 	{ kEobBaseMagicStrings8, kTypeStringList, true },
+	
+	{ kEobBaseFlightObjAnimTiles, kTypeRawData, false },
+	{ kEobBaseFlightObjAnimIndex, kTypeRawData, false },
+	{ kEobBaseFlightObjAnimDim, kTypeRawData, false },
+	{ kEobBaseFlightObjAnimTbl1, kTypeRawData, false },
+	{ kEobBaseFlightObjAnimTbl2, kTypeRawData, false },
+	{ kEobBaseFlightObjAnimTbl3, kTypeRawData, false },
 
 	{ kEobBaseSparkDefSteps, kTypeRawData, false },
 	{ kEobBaseSparkDefSubSteps, kTypeRawData, false },
@@ -1412,6 +1419,18 @@ const char *getIdString(const int id) {
 		return "kEobBaseMagicStrings7";
 	case kEobBaseMagicStrings8:
 		return "kEobBaseMagicStrings8";
+	case kEobBaseFlightObjAnimTiles:
+		return "kEobBaseFlightObjAnimTiles";
+	case kEobBaseFlightObjAnimIndex:
+		return "kEobBaseFlightObjAnimIndex";
+	case kEobBaseFlightObjAnimDim:
+		return "kEobBaseFlightObjAnimDim";
+	case kEobBaseFlightObjAnimTbl1:
+		return "kEobBaseFlightObjAnimTbl1";
+	case kEobBaseFlightObjAnimTbl2:
+		return "kEobBaseFlightObjAnimTbl2";
+	case kEobBaseFlightObjAnimTbl3:
+		return "kEobBaseFlightObjAnimTbl3";
 	case kEobBaseSparkDefSteps:
 		return "kEobBaseSparkDefSteps";
 	case kEobBaseSparkDefSubSteps:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index be40dff..d1355a8 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -323,6 +323,13 @@ enum kExtractID {
 	kEobBaseMagicStrings7,
 	kEobBaseMagicStrings8,
 
+	kEobBaseFlightObjAnimTiles,
+	kEobBaseFlightObjAnimIndex,
+	kEobBaseFlightObjAnimDim,
+	kEobBaseFlightObjAnimTbl1,
+	kEobBaseFlightObjAnimTbl2,
+	kEobBaseFlightObjAnimTbl3,
+
 	kEobBaseSparkDefSteps,
 	kEobBaseSparkDefSubSteps,
 	kEobBaseSparkDefShift,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 8e410dc..9936d5f 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1108,6 +1108,12 @@ const int eob1FloppyNeed[] = {
 	kEobBaseMagicStrings7,
 	kEobBaseMagicStrings8,
 
+	kEobBaseFlightObjAnimIndex,
+	kEobBaseFlightObjAnimDim,
+	kEobBaseFlightObjAnimTbl1,
+	kEobBaseFlightObjAnimTbl2,
+	kEobBaseFlightObjAnimTbl3,
+
 	kEobBaseSparkDefSteps,
 	kEobBaseSparkDefSubSteps,
 	kEobBaseSparkDefShift,
@@ -1262,6 +1268,13 @@ const int eob2FloppyNeed[] = {
 	kEobBaseMagicStrings7,
 	kEobBaseMagicStrings8,
 
+	kEobBaseFlightObjAnimTiles,
+	kEobBaseFlightObjAnimIndex,
+	kEobBaseFlightObjAnimDim,
+	kEobBaseFlightObjAnimTbl1,
+	kEobBaseFlightObjAnimTbl2,
+	kEobBaseFlightObjAnimTbl3,
+
 	kEobBaseSparkDefSteps,
 	kEobBaseSparkDefSubSteps,
 	kEobBaseSparkDefShift,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index da861fb..6dcfdac 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -1907,6 +1907,34 @@ const ExtractEntrySearchData kEobBaseMagicStrings8Provider[] = {
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEobBaseFlightObjAnimTilesProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000012, 0x0000000C, { { 0x98, 0x29, 0x54, 0xCD, 0xED, 0xAC, 0x7B, 0x61, 0x8D, 0x4F, 0x19, 0xE8, 0xA6, 0xB1, 0x51, 0x80 } } } },
+	EXTRACT_END_ENTRY
+};
+const ExtractEntrySearchData kEobBaseFlightObjAnimIndexProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000009, 0x00000005, { { 0xFE, 0xEA, 0xC4, 0x54, 0x62, 0x7E, 0x43, 0x6E, 0x89, 0x48, 0x03, 0xE7, 0x47, 0xBF, 0x7D, 0x9D } } } }, // EOB 1
+	{ UNK_LANG, kPlatformPC, { 0x0000000E, 0x00000004, { { 0x63, 0x27, 0x19, 0x17, 0xBD, 0xC3, 0x8A, 0xA7, 0x1E, 0xF7, 0xD1, 0x78, 0x39, 0x3B, 0xD4, 0x4F } } } }, // EOB 2
+	EXTRACT_END_ENTRY
+};
+const ExtractEntrySearchData kEobBaseFlightObjAnimDimProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000034, { { 0x27, 0xC5, 0x09, 0x97, 0x8E, 0xD4, 0xF1, 0x8D, 0x77, 0xEB, 0x1D, 0x34, 0x55, 0xB2, 0x48, 0x38 } } } },
+	EXTRACT_END_ENTRY
+};
+const ExtractEntrySearchData kEobBaseFlightObjAnimTbl1Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000000D, 0x0000005D, { { 0x49, 0xC4, 0x47, 0x55, 0xDC, 0x25, 0x08, 0x03, 0x3D, 0x23, 0xAD, 0x09, 0x5F, 0x9C, 0x34, 0x06 } } } },
+	EXTRACT_END_ENTRY
+};
+const ExtractEntrySearchData kEobBaseFlightObjAnimTbl2Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000005C, { { 0xAB, 0x6A, 0x97, 0x35, 0xCC, 0x13, 0xC4, 0x17, 0x0B, 0xF2, 0xD3, 0xFD, 0xA2, 0x1C, 0x6C, 0xA8 } } } },
+	EXTRACT_END_ENTRY
+};
+const ExtractEntrySearchData kEobBaseFlightObjAnimTbl3Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000000B, 0x00000032, { { 0x59, 0x23, 0xB9, 0xBE, 0x0E, 0xFA, 0xEB, 0xDD, 0x82, 0x68, 0x5B, 0xB0, 0xBE, 0x9B, 0x1D, 0x8E } } } },
+	EXTRACT_END_ENTRY
+};
+
+
+
 const ExtractEntrySearchData kEobBaseSparkDefStepsProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000008, 0x000002FD, { { 0xB5, 0x6F, 0x31, 0x5F, 0xC6, 0x47, 0xE9, 0x23, 0x0E, 0x73, 0xBF, 0x77, 0xC7, 0xEE, 0xDB, 0x27 } } } },
 	EXTRACT_END_ENTRY
@@ -3272,6 +3300,13 @@ const ExtractEntry extractProviders[] = {
 	{ kEobBaseMagicStrings6, kEobBaseMagicStrings6Provider },
 	{ kEobBaseMagicStrings7, kEobBaseMagicStrings7Provider },
 	{ kEobBaseMagicStrings8, kEobBaseMagicStrings8Provider },
+
+	{ kEobBaseFlightObjAnimTiles, kEobBaseFlightObjAnimTilesProvider },
+	{ kEobBaseFlightObjAnimIndex, kEobBaseFlightObjAnimIndexProvider },
+	{ kEobBaseFlightObjAnimDim, kEobBaseFlightObjAnimDimProvider },
+	{ kEobBaseFlightObjAnimTbl1, kEobBaseFlightObjAnimTbl1Provider },
+	{ kEobBaseFlightObjAnimTbl2, kEobBaseFlightObjAnimTbl2Provider },
+	{ kEobBaseFlightObjAnimTbl3, kEobBaseFlightObjAnimTbl3Provider },
 	
 	{ kEobBaseSparkDefSteps, kEobBaseSparkDefStepsProvider },
 	{ kEobBaseSparkDefSubSteps, kEobBaseSparkDefSubStepsProvider },
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 97b871c..49f07ac 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -246,8 +246,6 @@ Common::Error EobCoreEngine::init() {
 	_screen->loadFont(Screen::FID_6_FNT, "FONT6.FNT");
 	_screen->loadFont(Screen::FID_8_FNT, "FONT8.FNT");
 
-	_activeButtons = 0;
-
 	_staticres = new StaticResource(this);
 	assert(_staticres);
 	if (!_staticres->init())
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index e88ab84..e2873cb 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -435,6 +435,13 @@ protected:
 	const int8 *_flightObjShpMap;
 	const int8 *_flightObjSclIndex;
 
+	const uint8 *_flightObjAnimTiles;
+	const uint8 *_flightObjAnimIndex;
+	const uint8 *_flightObjAnimDim;
+	const uint8 *_flightObjAnimTbl1;
+	const uint8 *_flightObjAnimTbl2;
+	const uint8 *_flightObjAnimTbl3;
+
 	// Monsters
 	void loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex);
 	void releaseMonsterShapes(int first, int num);
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index ebe6ea6..7a4a3ec 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -187,8 +187,6 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : LolEobBaseEngine
 	_compassBroken = _drainMagic = 0;
 
 	_buttonData = 0;
-	_activeButtons = 0;
-	gui_resetButtonList();
 	_preserveEvents = false;
 	_buttonList1 = _buttonList2 = _buttonList3 = _buttonList4 = _buttonList5 = _buttonList6 = _buttonList7 = _buttonList8 = 0;
 
diff --git a/engines/kyra/loleobbase.cpp b/engines/kyra/loleobbase.cpp
index 1c4068d..02ffbea 100644
--- a/engines/kyra/loleobbase.cpp
+++ b/engines/kyra/loleobbase.cpp
@@ -36,6 +36,7 @@ LolEobBaseEngine::LolEobBaseEngine(OSystem *system, const GameFlags &flags) : Ky
 
 	_sceneXoffset = 0;
 	_sceneShpDim = 5;
+	
 	_activeButtons = 0;
 
 	_currentLevel = 0;
@@ -150,6 +151,8 @@ LolEobBaseEngine::~LolEobBaseEngine() {
 }
 
 Common::Error LolEobBaseEngine::init() {
+	gui_resetButtonList();
+
 	_levelDecorationProperties = new LevelDecorationProperty[100];
 	memset(_levelDecorationProperties, 0, 100 * sizeof(LevelDecorationProperty));
 	_levelDecorationShapes = new uint8*[400];
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 2c484b4..3e9ba09 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -396,6 +396,13 @@ enum KyraResources {
 	kEobBaseMagicStrings7,
 	kEobBaseMagicStrings8,
 
+	kEobBaseFlightObjAnimTiles,
+	kEobBaseFlightObjAnimIndex,
+	kEobBaseFlightObjAnimDim,
+	kEobBaseFlightObjAnimTbl1,
+	kEobBaseFlightObjAnimTbl2,
+	kEobBaseFlightObjAnimTbl3,
+
 	kEobBaseSparkDefSteps,
 	kEobBaseSparkDefSubSteps,
 	kEobBaseSparkDefShift,
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 557bacb..e25508f 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -459,6 +459,13 @@ void EobCoreEngine::initStaticResource() {
 	_magicStrings7 = _staticres->loadStrings(kEobBaseMagicStrings7, temp);
 	_magicStrings8 = _staticres->loadStrings(kEobBaseMagicStrings8, temp);
 
+	_flightObjAnimTiles = _staticres->loadRawData(kEobBaseFlightObjAnimTiles, temp);
+	_flightObjAnimIndex = _staticres->loadRawData(kEobBaseFlightObjAnimIndex, temp);
+	_flightObjAnimDim = _staticres->loadRawData(kEobBaseFlightObjAnimDim, temp);
+	_flightObjAnimTbl1 = _staticres->loadRawData(kEobBaseFlightObjAnimTbl1, temp);
+	_flightObjAnimTbl2 = _staticres->loadRawData(kEobBaseFlightObjAnimTbl2, temp);
+	_flightObjAnimTbl3 = _staticres->loadRawData(kEobBaseFlightObjAnimTbl3, temp);
+
 	_sparkEffectDefSteps = _staticres->loadRawData(kEobBaseSparkDefSteps, temp);
 	_sparkEffectDefSubSteps = _staticres->loadRawData(kEobBaseSparkDefSubSteps, temp);
 	_sparkEffectDefShift = _staticres->loadRawData(kEobBaseSparkDefShift, temp);


Commit: 9a6be57afd843b0cae09633b3745b104034100fa
    https://github.com/scummvm/scummvm/commit/9a6be57afd843b0cae09633b3745b104034100fa
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:11-08:00

Commit Message:
KYRA: (EOB) - implement explodeObject()

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/items_eob.cpp
    engines/kyra/lol.h
    engines/kyra/loleobbase.cpp
    engines/kyra/loleobbase.h
    engines/kyra/magic_eob.cpp
    engines/kyra/resource.h
    engines/kyra/scene_eob.cpp
    engines/kyra/scene_lol.cpp
    engines/kyra/screen_eob.cpp
    engines/kyra/screen_eob.h
    engines/kyra/staticres_eob.cpp
    engines/kyra/timer_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index d20b004..d27b5c1 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -318,17 +318,17 @@ const ExtractFilename extractFilenames[] = {
 	{ kEobBaseMagicStrings2, kTypeStringList, true },
 	{ kEobBaseMagicStrings3, kTypeStringList, true },
 	{ kEobBaseMagicStrings4, kTypeStringList, true },
-	{ kEobBaseMagicStrings5, kTypeStringList, false },
 	{ kEobBaseMagicStrings6, kTypeStringList, true },
 	{ kEobBaseMagicStrings7, kTypeStringList, true },
 	{ kEobBaseMagicStrings8, kTypeStringList, true },
 	
-	{ kEobBaseFlightObjAnimTiles, kTypeRawData, false },
-	{ kEobBaseFlightObjAnimIndex, kTypeRawData, false },
-	{ kEobBaseFlightObjAnimDim, kTypeRawData, false },
-	{ kEobBaseFlightObjAnimTbl1, kTypeRawData, false },
-	{ kEobBaseFlightObjAnimTbl2, kTypeRawData, false },
-	{ kEobBaseFlightObjAnimTbl3, kTypeRawData, false },
+	{ kEobBaseExpObjectTlMode, kTypeRawData, false },
+	{ kEobBaseExpObjectTblIndex, kTypeRawData, false },
+	{ kEobBaseExpObjectShpStart, kTypeRawData, false },
+	{ kEobBaseExpObjectTbl1, kTypeRawData, false },
+	{ kEobBaseExpObjectTbl2, kTypeRawData, false },
+	{ kEobBaseExpObjectTbl3, kTypeRawData, false },
+	{ kEobBaseExpObjectY, k3TypeRaw16to8, false },
 
 	{ kEobBaseSparkDefSteps, kTypeRawData, false },
 	{ kEobBaseSparkDefSubSteps, kTypeRawData, false },
@@ -1411,26 +1411,26 @@ const char *getIdString(const int id) {
 		return "kEobBaseMagicStrings3";
 	case kEobBaseMagicStrings4:
 		return "kEobBaseMagicStrings4";
-	case kEobBaseMagicStrings5:
-		return "kEobBaseMagicStrings5";
 	case kEobBaseMagicStrings6:
 		return "kEobBaseMagicStrings6";
 	case kEobBaseMagicStrings7:
 		return "kEobBaseMagicStrings7";
 	case kEobBaseMagicStrings8:
 		return "kEobBaseMagicStrings8";
-	case kEobBaseFlightObjAnimTiles:
-		return "kEobBaseFlightObjAnimTiles";
-	case kEobBaseFlightObjAnimIndex:
-		return "kEobBaseFlightObjAnimIndex";
-	case kEobBaseFlightObjAnimDim:
-		return "kEobBaseFlightObjAnimDim";
-	case kEobBaseFlightObjAnimTbl1:
-		return "kEobBaseFlightObjAnimTbl1";
-	case kEobBaseFlightObjAnimTbl2:
-		return "kEobBaseFlightObjAnimTbl2";
-	case kEobBaseFlightObjAnimTbl3:
-		return "kEobBaseFlightObjAnimTbl3";
+	case kEobBaseExpObjectTlMode:
+		return "kEobBaseExpObjectTlMode";
+	case kEobBaseExpObjectTblIndex:
+		return "kEobBaseExpObjectTblIndex";
+	case kEobBaseExpObjectShpStart:
+		return "kEobBaseExpObjectShpStart";
+	case kEobBaseExpObjectTbl1:
+		return "kEobBaseExpObjectTbl1";
+	case kEobBaseExpObjectTbl2:
+		return "kEobBaseExpObjectTbl2";
+	case kEobBaseExpObjectTbl3:
+		return "kEobBaseExpObjectTbl3";
+	case kEobBaseExpObjectY:
+		return "kEobBaseExpObjectY";
 	case kEobBaseSparkDefSteps:
 		return "kEobBaseSparkDefSteps";
 	case kEobBaseSparkDefSubSteps:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index d1355a8..7ecc4b2 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -318,17 +318,17 @@ enum kExtractID {
 	kEobBaseMagicStrings2,
 	kEobBaseMagicStrings3,
 	kEobBaseMagicStrings4,
-	kEobBaseMagicStrings5,
 	kEobBaseMagicStrings6,
 	kEobBaseMagicStrings7,
 	kEobBaseMagicStrings8,
 
-	kEobBaseFlightObjAnimTiles,
-	kEobBaseFlightObjAnimIndex,
-	kEobBaseFlightObjAnimDim,
-	kEobBaseFlightObjAnimTbl1,
-	kEobBaseFlightObjAnimTbl2,
-	kEobBaseFlightObjAnimTbl3,
+	kEobBaseExpObjectTlMode,
+	kEobBaseExpObjectTblIndex,
+	kEobBaseExpObjectShpStart,
+	kEobBaseExpObjectTbl1,
+	kEobBaseExpObjectTbl2,
+	kEobBaseExpObjectTbl3,
+	kEobBaseExpObjectY,
 
 	kEobBaseSparkDefSteps,
 	kEobBaseSparkDefSubSteps,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 9936d5f..d4c4186 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1103,16 +1103,16 @@ const int eob1FloppyNeed[] = {
 	kEobBaseMagicStrings2,
 	kEobBaseMagicStrings3,
 	kEobBaseMagicStrings4,
-	kEobBaseMagicStrings5,
 	kEobBaseMagicStrings6,
 	kEobBaseMagicStrings7,
 	kEobBaseMagicStrings8,
 
-	kEobBaseFlightObjAnimIndex,
-	kEobBaseFlightObjAnimDim,
-	kEobBaseFlightObjAnimTbl1,
-	kEobBaseFlightObjAnimTbl2,
-	kEobBaseFlightObjAnimTbl3,
+	kEobBaseExpObjectTblIndex,
+	kEobBaseExpObjectShpStart,
+	kEobBaseExpObjectTbl1,
+	kEobBaseExpObjectTbl2,
+	kEobBaseExpObjectTbl3,
+	kEobBaseExpObjectY,
 
 	kEobBaseSparkDefSteps,
 	kEobBaseSparkDefSubSteps,
@@ -1263,17 +1263,17 @@ const int eob2FloppyNeed[] = {
 	kEobBaseMagicStrings2,
 	kEobBaseMagicStrings3,
 	kEobBaseMagicStrings4,
-	kEobBaseMagicStrings5,
 	kEobBaseMagicStrings6,
 	kEobBaseMagicStrings7,
 	kEobBaseMagicStrings8,
 
-	kEobBaseFlightObjAnimTiles,
-	kEobBaseFlightObjAnimIndex,
-	kEobBaseFlightObjAnimDim,
-	kEobBaseFlightObjAnimTbl1,
-	kEobBaseFlightObjAnimTbl2,
-	kEobBaseFlightObjAnimTbl3,
+	kEobBaseExpObjectTlMode,
+	kEobBaseExpObjectTblIndex,
+	kEobBaseExpObjectShpStart,
+	kEobBaseExpObjectTbl1,
+	kEobBaseExpObjectTbl2,
+	kEobBaseExpObjectTbl3,
+	kEobBaseExpObjectY,
 
 	kEobBaseSparkDefSteps,
 	kEobBaseSparkDefSubSteps,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index 6dcfdac..fe4b18a 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -1878,11 +1878,6 @@ const ExtractEntrySearchData kEobBaseMagicStrings4Provider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMagicStrings5Provider[] = {
-	{ UNK_LANG, kPlatformPC, { 0x00000008, 0x0000016C, { { 0xCF, 0x5B, 0x04, 0xAB, 0x1A, 0xAF, 0xDD, 0x56, 0xAC, 0xF6, 0x23, 0x86, 0x33, 0x06, 0x5A, 0xC6 } } } },
-	EXTRACT_END_ENTRY
-};
-
 const ExtractEntrySearchData kEobBaseMagicStrings6Provider[] = {
 	{ EN_ANY, kPlatformPC, { 0x00000029, 0x00000DA4, { { 0x5C, 0x6F, 0xA1, 0xC2, 0x56, 0xDE, 0xFE, 0xD5, 0x01, 0xFB, 0x65, 0x00, 0x24, 0xD1, 0x49, 0x7B } } } },
 	{ DE_DEU, kPlatformPC, { 0x00000032, 0x00001211, { { 0x13, 0xBC, 0xF1, 0x03, 0x49, 0xDB, 0x16, 0xA5, 0xC3, 0x7C, 0xBF, 0x14, 0x8F, 0x40, 0x07, 0x8E } } } },
@@ -1907,33 +1902,36 @@ const ExtractEntrySearchData kEobBaseMagicStrings8Provider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseFlightObjAnimTilesProvider[] = {
+const ExtractEntrySearchData kEobBaseExpObjectTlModeProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000012, 0x0000000C, { { 0x98, 0x29, 0x54, 0xCD, 0xED, 0xAC, 0x7B, 0x61, 0x8D, 0x4F, 0x19, 0xE8, 0xA6, 0xB1, 0x51, 0x80 } } } },
 	EXTRACT_END_ENTRY
 };
-const ExtractEntrySearchData kEobBaseFlightObjAnimIndexProvider[] = {
+const ExtractEntrySearchData kEobBaseExpObjectTblIndexProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000009, 0x00000005, { { 0xFE, 0xEA, 0xC4, 0x54, 0x62, 0x7E, 0x43, 0x6E, 0x89, 0x48, 0x03, 0xE7, 0x47, 0xBF, 0x7D, 0x9D } } } }, // EOB 1
 	{ UNK_LANG, kPlatformPC, { 0x0000000E, 0x00000004, { { 0x63, 0x27, 0x19, 0x17, 0xBD, 0xC3, 0x8A, 0xA7, 0x1E, 0xF7, 0xD1, 0x78, 0x39, 0x3B, 0xD4, 0x4F } } } }, // EOB 2
 	EXTRACT_END_ENTRY
 };
-const ExtractEntrySearchData kEobBaseFlightObjAnimDimProvider[] = {
+const ExtractEntrySearchData kEobBaseExpObjectShpStartProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000034, { { 0x27, 0xC5, 0x09, 0x97, 0x8E, 0xD4, 0xF1, 0x8D, 0x77, 0xEB, 0x1D, 0x34, 0x55, 0xB2, 0x48, 0x38 } } } },
 	EXTRACT_END_ENTRY
 };
-const ExtractEntrySearchData kEobBaseFlightObjAnimTbl1Provider[] = {
+const ExtractEntrySearchData kEobBaseExpObjectTbl1Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000000D, 0x0000005D, { { 0x49, 0xC4, 0x47, 0x55, 0xDC, 0x25, 0x08, 0x03, 0x3D, 0x23, 0xAD, 0x09, 0x5F, 0x9C, 0x34, 0x06 } } } },
 	EXTRACT_END_ENTRY
 };
-const ExtractEntrySearchData kEobBaseFlightObjAnimTbl2Provider[] = {
+const ExtractEntrySearchData kEobBaseExpObjectTbl2Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000005C, { { 0xAB, 0x6A, 0x97, 0x35, 0xCC, 0x13, 0xC4, 0x17, 0x0B, 0xF2, 0xD3, 0xFD, 0xA2, 0x1C, 0x6C, 0xA8 } } } },
 	EXTRACT_END_ENTRY
 };
-const ExtractEntrySearchData kEobBaseFlightObjAnimTbl3Provider[] = {
+const ExtractEntrySearchData kEobBaseExpObjectTbl3Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000000B, 0x00000032, { { 0x59, 0x23, 0xB9, 0xBE, 0x0E, 0xFA, 0xEB, 0xDD, 0x82, 0x68, 0x5B, 0xB0, 0xBE, 0x9B, 0x1D, 0x8E } } } },
 	EXTRACT_END_ENTRY
 };
 
-
+const ExtractEntrySearchData kEobBaseExpObjectYProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000008, 0x0000016C, { { 0xCF, 0x5B, 0x04, 0xAB, 0x1A, 0xAF, 0xDD, 0x56, 0xAC, 0xF6, 0x23, 0x86, 0x33, 0x06, 0x5A, 0xC6 } } } },
+	EXTRACT_END_ENTRY
+};
 
 const ExtractEntrySearchData kEobBaseSparkDefStepsProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000008, 0x000002FD, { { 0xB5, 0x6F, 0x31, 0x5F, 0xC6, 0x47, 0xE9, 0x23, 0x0E, 0x73, 0xBF, 0x77, 0xC7, 0xEE, 0xDB, 0x27 } } } },
@@ -3296,17 +3294,17 @@ const ExtractEntry extractProviders[] = {
 	{ kEobBaseMagicStrings2, kEobBaseMagicStrings2Provider },
 	{ kEobBaseMagicStrings3, kEobBaseMagicStrings3Provider },
 	{ kEobBaseMagicStrings4, kEobBaseMagicStrings4Provider },
-	{ kEobBaseMagicStrings5, kEobBaseMagicStrings5Provider },
 	{ kEobBaseMagicStrings6, kEobBaseMagicStrings6Provider },
 	{ kEobBaseMagicStrings7, kEobBaseMagicStrings7Provider },
 	{ kEobBaseMagicStrings8, kEobBaseMagicStrings8Provider },
 
-	{ kEobBaseFlightObjAnimTiles, kEobBaseFlightObjAnimTilesProvider },
-	{ kEobBaseFlightObjAnimIndex, kEobBaseFlightObjAnimIndexProvider },
-	{ kEobBaseFlightObjAnimDim, kEobBaseFlightObjAnimDimProvider },
-	{ kEobBaseFlightObjAnimTbl1, kEobBaseFlightObjAnimTbl1Provider },
-	{ kEobBaseFlightObjAnimTbl2, kEobBaseFlightObjAnimTbl2Provider },
-	{ kEobBaseFlightObjAnimTbl3, kEobBaseFlightObjAnimTbl3Provider },
+	{ kEobBaseExpObjectTlMode, kEobBaseExpObjectTlModeProvider },
+	{ kEobBaseExpObjectTblIndex, kEobBaseExpObjectTblIndexProvider },
+	{ kEobBaseExpObjectShpStart, kEobBaseExpObjectShpStartProvider },
+	{ kEobBaseExpObjectTbl1, kEobBaseExpObjectTbl1Provider },
+	{ kEobBaseExpObjectTbl2, kEobBaseExpObjectTbl2Provider },
+	{ kEobBaseExpObjectTbl3, kEobBaseExpObjectTbl3Provider },
+	{ kEobBaseExpObjectY, kEobBaseExpObjectYProvider },
 	
 	{ kEobBaseSparkDefSteps, kEobBaseSparkDefStepsProvider },
 	{ kEobBaseSparkDefSubSteps, kEobBaseSparkDefSubStepsProvider },
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 49f07ac..d40620c 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -22,17 +22,17 @@
 
 #ifdef ENABLE_EOB
 
-#include "common/config-manager.h"
-
-#include "audio/mididrv.h"
-#include "audio/mixer.h"
-
 #include "kyra/loleobbase.h"
 #include "kyra/resource.h"
 #include "kyra/sound_intern.h"
 #include "kyra/script_eob.h"
 #include "kyra/timer.h"
 
+#include "common/config-manager.h"
+
+#include "audio/mididrv.h"
+#include "audio/mixer.h"
+
 namespace Kyra {
 
 EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBaseEngine(system, flags), _numLargeItemShapes(flags.gameID == GI_EOB1 ? 14 : 11),
@@ -229,6 +229,11 @@ Common::Error EobCoreEngine::init() {
 	assert(_res);
 	_res->reset();
 
+	_staticres = new StaticResource(this);
+	assert(_staticres);
+	if (!_staticres->init())
+		error("_staticres->init() failed");
+
 	if (!screen()->init())
 		error("screen()->init() failed");
 
@@ -246,11 +251,6 @@ Common::Error EobCoreEngine::init() {
 	_screen->loadFont(Screen::FID_6_FNT, "FONT6.FNT");
 	_screen->loadFont(Screen::FID_8_FNT, "FONT8.FNT");
 
-	_staticres = new StaticResource(this);
-	assert(_staticres);
-	if (!_staticres->init())
-		error("_staticres->init() failed");
-
 	Common::Error err = LolEobBaseEngine::init();
 	if (err.getCode() != Common::kNoError)
 		return err;
@@ -1383,7 +1383,7 @@ void EobCoreEngine::inflictMonsterDamage(EobMonsterInPlay *m, int damage, bool g
 	m->flags = (m->flags & 0xf7) | 1;
 
 	if (_monsterProps[m->type].flags & 0x2000) {
-		inflictMonsterDamage_s1(m);
+		explodeMonster(m);
 		checkSceneUpdateNeed(m->block);
 		m->hitPointsCur = 0;
 	} else {
@@ -1827,8 +1827,16 @@ int EobCoreEngine::getMonsterAcHitChanceModifier(int charIndex, int monsterAc) {
 	return (20 - ((l / mod1[cm]) * mod2[cm])) - monsterAc;
 }
 
-void EobCoreEngine::inflictMonsterDamage_s1(EobMonsterInPlay *m) {
-
+void EobCoreEngine::explodeMonster(EobMonsterInPlay *m) {
+	m->flags |= 2;
+	if (getBlockDistance(m->block, _currentBlock) < 2) {
+		explodeObject(0, _currentBlock, 2);
+		for (int i = 0; i < 6; i++)
+			calcAndInflictCharacterDamage(i, 6, 6, 0, 8, 1, 0);
+	} else {
+		explodeObject(0, m->block, 2);
+	}
+	m->flags &= ~2;
 }
 
 void EobCoreEngine::snd_playSoundEffect(int id, int volume) {
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index e2873cb..8b28e86 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -413,7 +413,7 @@ protected:
 	void launchMagicObject(int charIndex, int type, uint16 startBlock, int startPos, int dir);
 	bool updateObjectFlight(EobFlyingObject *fo, int block, int pos);
 	bool updateFlyingObjectHitTest(EobFlyingObject *fo, int block, int pos);
-	void updateFlyingObject_s3(EobFlyingObject *fo);
+	void explodeObject(EobFlyingObject *fo, int block, Item item);
 	void endObjectFlight(EobFlyingObject *fo);
 	void checkFlyingObjects();
 
@@ -435,12 +435,15 @@ protected:
 	const int8 *_flightObjShpMap;
 	const int8 *_flightObjSclIndex;
 
-	const uint8 *_flightObjAnimTiles;
-	const uint8 *_flightObjAnimIndex;
-	const uint8 *_flightObjAnimDim;
-	const uint8 *_flightObjAnimTbl1;
-	const uint8 *_flightObjAnimTbl2;
-	const uint8 *_flightObjAnimTbl3;
+	const uint8 *_expObjectTlMode;
+	const uint8 *_expObjectTblIndex;
+	const uint8 *_expObjectShpStart;
+	const uint8 *_expObjectAnimTbl1;
+	int _expObjectAnimTbl1Size;
+	const uint8 *_expObjectAnimTbl2;
+	int _expObjectAnimTbl2Size;
+	const uint8 *_expObjectAnimTbl3;
+	int _expObjectAnimTbl3Size;
 
 	// Monsters
 	void loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex);
@@ -545,7 +548,7 @@ protected:
 	virtual const uint8 *loadDoorShapes(const char *filename, int doorIndex, const uint8*shapeDefs) { return (const uint8*)filename; }
 
 	void drawScene(int update);
-	void drawSceneShapes();
+	void drawSceneShapes(int start = 0);
 	void drawDecorations(int index);
 
 	int calcNewBlockPositionAndTestPassability(uint16 curBlock, uint16 direction);
@@ -802,8 +805,8 @@ protected:
 	int getStrDamageModifier(int charIndex);
 	int getDexHitChanceModifier(int charIndex);
 	int getMonsterAcHitChanceModifier(int charIndex, int monsterAc);
-	void inflictMonsterDamage_s1(EobMonsterInPlay *m);
-
+	void explodeMonster(EobMonsterInPlay *m);
+	
 	int _dstMonsterIndex;
 	int _inflictMonsterDamageUnk;
 	int16 _foundMonstersArray[5];
@@ -933,7 +936,6 @@ protected:
 	const char *const *_magicStrings2;
 	const char *const *_magicStrings3;
 	const char *const *_magicStrings4;
-	const char *const *_magicStrings5;
 	const char *const *_magicStrings6;
 	const char *const *_magicStrings7;
 	const char *const *_magicStrings8;
diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
index 9e87b7c..e536b67 100644
--- a/engines/kyra/items_eob.cpp
+++ b/engines/kyra/items_eob.cpp
@@ -569,8 +569,69 @@ bool EobCoreEngine::updateFlyingObjectHitTest(EobFlyingObject *fo, int block, in
 	return false;
 }
 
-void EobCoreEngine::updateFlyingObject_s3(EobFlyingObject *fo) {
+void EobCoreEngine::explodeObject(EobFlyingObject *fo, int block, Item item) {
+	if (_partyResting) {
+		snd_processEnvironmentalSoundEffect(35, _currentBlock);
+		return;
+	}
+
+	const uint8 *table = (_expObjectTblIndex[item] == 0) ? _expObjectAnimTbl1 : ((_expObjectTblIndex[item] == 1) ? _expObjectAnimTbl2 : _expObjectAnimTbl3);
+	int tableSize = (_expObjectTblIndex[item] == 0) ? _expObjectAnimTbl1Size : ((_expObjectTblIndex[item] == 1) ? _expObjectAnimTbl2Size : _expObjectAnimTbl3Size);
+
+	int tl = 0;
+	for (; tl < 18; tl++) {
+		if (_visibleBlockIndex[tl] == block)
+			break;
+	}
+
+	if (tl == 18)
+		return;
+
+	int b = _expObjectTlMode ? _expObjectTlMode[tl] : 2;
+
+	if (b == 0 || (b == 1 && (fo->direction & 1) == (_currentDirection & 1))) {
+		snd_processEnvironmentalSoundEffect(35, _currentBlock);
+		return;
+	}
 
+	uint8 dm = _dscDimMap[tl];
+	int16 x1 = 0;
+	int16 x2 = 0;
+
+	setLevelShapesDim(tl, x1, x2, 5);
+	
+	if (x2 < x1)
+		return;
+
+	if (fo)
+		fo->enable = 0;
+
+	drawScene(1);
+
+	if (fo)
+		fo->enable = 2;
+
+	_screen->fillRect(0, 0, 176, 120, 0, 2);
+	uint8 col = _screen->getPagePixel(2, 0, 0);
+	drawSceneShapes(_expObjectShpStart[dm]);
+
+	setLevelShapesDim(tl, x1, x2, 5);
+	_screen->updateScreen();
+
+	_screen->setGfxParameters(_dscShapeCoords[(tl * 5 + 4) << 1] + 88, 48, col);
+	snd_processEnvironmentalSoundEffect(35, _currentBlock);
+
+	disableSysTimer(2);
+	if (dm == 0) {
+		_screen->drawExplosion(3, 147, 35, 20, 7, table, tableSize);
+	} else if (dm == 1) {
+		_screen->drawExplosion(2, 147, 35, 20, 7, table, tableSize);
+	} else if (dm == 2) {
+		_screen->drawExplosion(1, 147, 35, 20, 7, table, tableSize);
+	} else if (dm == 3) {
+		_screen->drawExplosion(0, 460, 50, 20, 4, table, tableSize);
+	}
+	enableSysTimer(2);
 }
 
 void EobCoreEngine::endObjectFlight(EobFlyingObject *fo) {
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index f4fcbeb..8ddba86 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -928,7 +928,7 @@ private:
 
 	void drawScene(int pageNum);
 
-	void drawSceneShapes();
+	void drawSceneShapes(int start = 0);
 	void drawDecorations(int index);
 	void drawBlockEffects(int index, int type);
 	void drawSpecialGuiShape(int pageNum);
diff --git a/engines/kyra/loleobbase.cpp b/engines/kyra/loleobbase.cpp
index 02ffbea..a7a47b6 100644
--- a/engines/kyra/loleobbase.cpp
+++ b/engines/kyra/loleobbase.cpp
@@ -195,8 +195,8 @@ Common::Error LolEobBaseEngine::init() {
 	return Common::kNoError;
 }
 
-bool LolEobBaseEngine::posWithinRect(int mouseX, int mouseY, int x1, int y1, int x2, int y2) {
-	if (mouseX < x1 || mouseX > x2 || mouseY < y1 || mouseY > y2)
+bool LolEobBaseEngine::posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2) {
+	if (posX < x1 || posX > x2 || posY < y1 || posY > y2)
 		return false;
 	return true;
 }
diff --git a/engines/kyra/loleobbase.h b/engines/kyra/loleobbase.h
index 43a8646..831c644 100644
--- a/engines/kyra/loleobbase.h
+++ b/engines/kyra/loleobbase.h
@@ -113,7 +113,7 @@ protected:
 	void timerProcessDoors(int timerNum);
 
 	// mouse
-	bool posWithinRect(int mouseX, int mouseY, int x1, int y1, int x2, int y2);
+	bool posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2);
 	virtual void setHandItem(Item itemIndex) = 0;
 
 	// Characters
@@ -143,7 +143,7 @@ protected:
 	virtual void loadBlockProperties(const char *file) = 0;
 
 	virtual void drawScene(int pageNum) = 0;
-	virtual void drawSceneShapes() = 0;
+	virtual void drawSceneShapes(int start) = 0;
 	virtual void drawDecorations(int index) = 0;
 
 	void setLevelShapesDim(int index, int16 &x1, int16 &x2, int dim);
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index aefe20c..16e8996 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -482,7 +482,7 @@ bool EobCoreEngine::magicObjectHit(EobFlyingObject *fo, int dcTimes, int dcPips,
 	}
 
 	if (res && (fo->flags & 0x40))
-		updateFlyingObject_s3(fo);
+		explodeObject(fo, fo->curBlock, fo->item);
 	else if ((_flags.gameID == GI_EOB1 && fo->item == 5) || (_flags.gameID == GI_EOB2 && fo->item == 4))
 		res = false;
 
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 3e9ba09..2f93add 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -391,17 +391,17 @@ enum KyraResources {
 	kEobBaseMagicStrings2,
 	kEobBaseMagicStrings3,
 	kEobBaseMagicStrings4,
-	kEobBaseMagicStrings5,
 	kEobBaseMagicStrings6,
 	kEobBaseMagicStrings7,
 	kEobBaseMagicStrings8,
 
-	kEobBaseFlightObjAnimTiles,
-	kEobBaseFlightObjAnimIndex,
-	kEobBaseFlightObjAnimDim,
-	kEobBaseFlightObjAnimTbl1,
-	kEobBaseFlightObjAnimTbl2,
-	kEobBaseFlightObjAnimTbl3,
+	kEobBaseExpObjectTlMode,
+	kEobBaseExpObjectTblIndex,
+	kEobBaseExpObjectShpStart,
+	kEobBaseExpObjectTbl1,
+	kEobBaseExpObjectTbl2,
+	kEobBaseExpObjectTbl3,
+	kEobBaseExpObjectY,
 
 	kEobBaseSparkDefSteps,
 	kEobBaseSparkDefSubSteps,
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index be106a9..a8ca966 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -1037,8 +1037,8 @@ void EobCoreEngine::drawScene(int update) {
 	_sceneUpdateRequired = false;
 }
 
-void EobCoreEngine::drawSceneShapes() {
-	for (int i = 0; i < 18; i++) {
+void EobCoreEngine::drawSceneShapes(int start) {
+	for (int i = start; i < 18; i++) {
 		uint8 t = _dscTileIndex[i];
 		uint8 s = _visibleBlocks[t]->walls[_sceneDrawVarDown];
 
diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp
index c2b16ca..998fb73 100644
--- a/engines/kyra/scene_lol.cpp
+++ b/engines/kyra/scene_lol.cpp
@@ -1386,7 +1386,7 @@ void LoLEngine::setDefaultButtonState() {
 	_lampStatusSuspended = false;
 }
 
-void LoLEngine::drawSceneShapes() {
+void LoLEngine::drawSceneShapes(int) {
 	for (int i = 0; i < 18; i++) {
 		uint8 t = _dscTileIndex[i];
 		uint8 s = _visibleBlocks[t]->walls[_sceneDrawVarDown];
diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp
index f095b04..b93ab3e 100644
--- a/engines/kyra/screen_eob.cpp
+++ b/engines/kyra/screen_eob.cpp
@@ -42,6 +42,8 @@ Screen_Eob::Screen_Eob(EobCoreEngine *vm, OSystem *system) : Screen(vm, system)
 	_fadeData = 0;
 	_fadeDataIndex = 0;
 	_dsX1 = _dsX2 = _dsY1 = _dsY2 = 0;
+	_gfxX = _gfxY = 0;
+	_gfxCol = 0;
 	_customDimTable = 0;
 	_dsTempPage = 0;
 }
@@ -57,6 +59,8 @@ bool Screen_Eob::init() {
 		_customDimTable = new ScreenDim*[_screenDimTableCount];
 		memset(_customDimTable, 0, sizeof(ScreenDim *)* _screenDimTableCount);
 
+		int temp;
+		_gfxMaxY = _vm->staticres()->loadRawData(kEobBaseExpObjectY, temp);
 		_fadeData = _vm->resource()->fileData("FADING.DAT", 0);
 
 		if (!_fadeData) {
@@ -605,25 +609,6 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
 	}
 }
 
-void Screen_Eob::drawShapeSetPixel(uint8 * dst, uint8 c) {
-	if (_shapeFadeMode[0]) {
-		if (_shapeFadeMode[1]) {
-			c = *dst;
-		} else {
-			_shapeFadeInternal &= 7;
-            c = *(dst + _shapeFadeInternal++);
-		}
-	}
-
-	if (_shapeFadeMode[1]) {
-		uint8 cnt = _shapeFadeMode[1];
-		while (cnt--)
-			c = _fadeData[_fadeDataIndex + c];
-	}
-
-	*dst = c;
-}
-
 const uint8 *Screen_Eob::scaleShape(const uint8 *shapeData, int steps) {
 	setShapeFadeMode(1, steps ? true : false);
 
@@ -700,24 +685,133 @@ void Screen_Eob::applyShapeOverlay(uint8 *shp, int ovlIndex) {
 		shp[i] = ovl[shp[i]];
 }
 
-void Screen_Eob::scaleShapeProcessLine(uint8 *&dst, const uint8 *&src) {
-	for (int i = 0; i < _dsDiv; i++) {
-		*dst++ = *src++;
-		*dst++ = READ_BE_UINT16(src) >> 4;
-		src += 2;
+void Screen_Eob::setShapeFrame(int x1, int y1, int x2, int y2) {
+	_dsX1 = x1;
+	_dsY1 = y1;
+	_dsX2 = x2;
+	_dsY2 = y2;
+}
+
+void Screen_Eob::setShapeFadeMode (uint8 i, bool b) {
+	if (!i || i == 1)
+		_shapeFadeMode[i] = b;
+}
+
+void Screen_Eob::setGfxParameters(int x, int y, int col) {
+	_gfxX = x;
+	_gfxY = y;
+	_gfxCol = col;
+}
+
+void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize, int aspectRatio, const uint8 *colorTable, int colorTableSize) {
+	int ymin = 0;
+	int ymax = _gfxMaxY[scale];
+	int xmin = -100;
+	int xmax = 276;
+
+	if (scale)
+		--scale;
+
+	hideMouse();
+
+	const ScreenDim *dm = getScreenDim(5);
+	int rX1 = dm->sx << 3;
+	int rY1 = dm->sy;
+	int rX2 = rX1 + (dm->w << 3);
+	int rY2 = rY1 + dm->h - 1;
+	
+	int16 gx2 = _gfxX;
+	int16 gy2 = _gfxY;
+
+	uint8 *ptr1 = _dsTempPage;
+	int16 *ptr2 = (int16*)_dsTempPage;
+	int16 *ptr3 = (int16*)&_dsTempPage[300];
+	int16 *ptr4 = (int16*)&_dsTempPage[600];
+	int16 *ptr5 = (int16*)&_dsTempPage[900];
+	int16 *ptr6 = (int16*)&_dsTempPage[1200];
+	int16 *ptr7 = (int16*)&_dsTempPage[1500];
+	int16 *ptr8 = (int16*)&_dsTempPage[1800];
+
+	if (numSteps > 150)
+		numSteps = 150;
+
+	for (int i = 0; i < numSteps; i++) {
+		ptr2[i] = ptr3[i] = 0;
+		ptr4[i] = _vm->_rnd.getRandomNumberRng(0, radius) - (radius >> 1);
+		ptr5[i] = _vm->_rnd.getRandomNumberRng(0, radius) - (radius >> 1) - (radius >> (8 - aspectRatio));
+		ptr7[i] = _vm->_rnd.getRandomNumberRng(1024/stepSize, 2048/stepSize);
+		ptr8[i] = scale << 8;
 	}
 
-	if (_dsRem == 1) {
-		*dst++ = *src++;
-		*dst++ = _dsScaleTmp;
+	for (int l = 2; l;) {
+		if (l != 2) {
+			for (int i = numSteps - 1; i >= 0; i--) {
+				uint32 end = _system->getMillis() + 1;
+				int16 px = ((ptr2[i] >> 6) >> scale) + gx2;
+				int16 py = ((ptr3[i] >> 6) >> scale) + gy2;
+				if (py > ymax)
+					py = ymax;
+				if (posWithinRect(px, py, rX1, rY1, rX2, rY2)) {
+					setPagePixel(0, px, py, ptr6[i]);
+					if (i % 5 == 0)  {
+						updateScreen();
+						uint32 cur = _system->getMillis();
+						if (end > cur)
+						_system->delayMillis(end - cur);
+					}
+				}
+			}			
+		}
 
-	} if (_dsRem == 2) {
-		*dst++ = (src[0] & 0xf0) | (src[1] >> 4);
-		src += 2;
-		*dst++ = _dsScaleTmp;
-		*dst++ = _dsScaleTmp;
-		*dst++ = _dsScaleTmp;
+		l = 0;
+
+		for (int i = 0; i < numSteps; i++) {
+			uint32 end = _system->getMillis() + 1;
+			if (ptr4[i] <= 0)
+				ptr4[i]++;
+			else
+				ptr4[i]--;
+			ptr2[i] += ptr4[i];
+			ptr5[i] += 5;
+			ptr3[i] += ptr5[i];
+			ptr8[i] += ptr7[i];
+				
+			int16 px = ((ptr2[i] >> 6) >> scale) + gx2;
+			int16 py = ((ptr3[i] >> 6) >> scale) + gy2;
+			if (py >= ymax || py < ymin)
+				ptr5[i] = -(ptr5[i] >> 1);
+			if (px >= xmax || px < xmin)
+				ptr4[i] = -(ptr4[i] >> 1);
+
+			if (py > ymax)
+				py = ymax;
+			
+			int pxVal1 = 0;
+			if (posWithinRect(px, py, 0, 0, 319, 199)) {
+				pxVal1 = getPagePixel(2, px, py);
+				ptr6[i] = getPagePixel(0, px, py);
+			}
+
+			assert((ptr8[i] >> 8) < colorTableSize);
+			int pxVal2 = colorTable[ptr8[i] >> 8];
+			if (pxVal2) {
+				l = 1;
+				if (pxVal1 == _gfxCol && posWithinRect(px, py, rX1, rY1, rX2, rY2)) {
+					setPagePixel(0, px, py, pxVal2);
+					if (i % 5 == 0)  {
+						updateScreen();
+						uint32 cur = _system->getMillis();
+						if (end > cur)
+						_system->delayMillis(end - cur);
+					}
+				}
+			} else {
+				ptr7[i] = 0;
+			}
+		}
 	}
+	
+	showMouse();
 }
 
 void Screen_Eob::fadeTextColor(Palette *pal, int color1, int rate) {
@@ -778,6 +872,14 @@ bool Screen_Eob::delayedFadePalStep(Palette *fadePal, Palette *destPal, int rate
 	return res;
 }
 
+int Screen_Eob::getRectSize(int w, int h) {
+	return w * h;
+}
+
+void Screen_Eob::setFadeTableIndex(int index) {
+	_fadeDataIndex = (CLIP(index, 0, 7) << 8);
+}
+
 void Screen_Eob::createFadeTable(uint8 *palData, uint8 *dst, uint8 rootColor, uint8 weight) {
 	if (!palData)
 		return;
@@ -821,6 +923,55 @@ void Screen_Eob::createFadeTable(uint8 *palData, uint8 *dst, uint8 rootColor, ui
 	}
 }
 
+uint8 *Screen_Eob::getFadeTable(int index) {
+	return (index >= 0 && index < 5) ? &_fadeData[index << 8] : 0;
+}
+
+void Screen_Eob::drawShapeSetPixel(uint8 * dst, uint8 c) {
+	if (_shapeFadeMode[0]) {
+		if (_shapeFadeMode[1]) {
+			c = *dst;
+		} else {
+			_shapeFadeInternal &= 7;
+            c = *(dst + _shapeFadeInternal++);
+		}
+	}
+
+	if (_shapeFadeMode[1]) {
+		uint8 cnt = _shapeFadeMode[1];
+		while (cnt--)
+			c = _fadeData[_fadeDataIndex + c];
+	}
+
+	*dst = c;
+}
+
+void Screen_Eob::scaleShapeProcessLine(uint8 *&dst, const uint8 *&src) {
+	for (int i = 0; i < _dsDiv; i++) {
+		*dst++ = *src++;
+		*dst++ = READ_BE_UINT16(src) >> 4;
+		src += 2;
+	}
+
+	if (_dsRem == 1) {
+		*dst++ = *src++;
+		*dst++ = _dsScaleTmp;
+
+	} if (_dsRem == 2) {
+		*dst++ = (src[0] & 0xf0) | (src[1] >> 4);
+		src += 2;
+		*dst++ = _dsScaleTmp;
+		*dst++ = _dsScaleTmp;
+		*dst++ = _dsScaleTmp;
+	}
+}
+
+bool Screen_Eob::posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2) {
+	if (posX < x1 || posX > x2 || posY < y1 || posY > y2)
+		return false;
+	return true;
+}
+
 OldDOSFont::OldDOSFont() {
 	_data = 0;
 	_width = _height = _numGlyphs = 0;
diff --git a/engines/kyra/screen_eob.h b/engines/kyra/screen_eob.h
index 038ba85..19cbdb5 100644
--- a/engines/kyra/screen_eob.h
+++ b/engines/kyra/screen_eob.h
@@ -61,20 +61,32 @@ public:
 	void replaceShapePalette(uint8 *shp, const uint8 *pal);
 	void applyShapeOverlay(uint8 *shp, int ovlIndex);
 
-	void setShapeFrame(int x1, int y1, int x2, int y2) { _dsX1 = x1; _dsY1 = y1; _dsX2 = x2; _dsY2 = y2; }
-	void setShapeFadeMode (uint8 i, bool b) { if (!i || i == 1) _shapeFadeMode[i] = b; }
+	void setShapeFrame(int x1, int y1, int x2, int y2);
+	void setShapeFadeMode (uint8 i, bool b);
+
+	void setGfxParameters(int x, int y, int col);
+	void drawExplosion(int scale, int radius, int numSteps, int stepSize, int aspectRatio, const uint8 *colorTable, int colorTableSize);
 
 	void fadeTextColor(Palette *pal, int color1, int fadeTextColor);
 	bool delayedFadePalStep(Palette *fadePal, Palette *destPal, int rate);
 
 	void setTextColorMap(const uint8 *cmap) {}
-	int getRectSize(int w, int h) { return w * h; }
+	int getRectSize(int w, int h);
 
-	void setFadeTableIndex(int index) { _fadeDataIndex = (CLIP(index, 0, 7) << 8); }
+	void setFadeTableIndex(int index);
 	void createFadeTable(uint8 *palData, uint8 *dst, uint8 rootColor, uint8 weight);
-	uint8 *getFadeTable(int index) { return (index >= 0 && index < 5) ? &_fadeData[index << 8] : 0; }
+	uint8 *getFadeTable(int index);
+
+private:
+	void drawShapeSetPixel(uint8 *dst, uint8 c);
+	void scaleShapeProcessLine(uint8 *&dst, const uint8 *&src);
+	bool posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2);
+
+	int _dsDiv, _dsRem, _dsScaleTmp;
+	int16 _gfxX, _gfxY;
+	uint8 _gfxCol;
+	const uint8 *_gfxMaxY;
 
-protected:
 	int16 _dsX1, _dsX2, _dsY1, _dsY2;
 	bool _shapeFadeMode[2];
 	uint16 _shapeFadeInternal;
@@ -87,13 +99,7 @@ protected:
 	static const int _screenDimTableCount;
 
 	ScreenDim **_customDimTable;
-	int _curDimIndex;
-
-private:
-	void drawShapeSetPixel(uint8 *dst, uint8 c);
-	void scaleShapeProcessLine(uint8 *&dst, const uint8 *&src);
-
-	int _dsDiv, _dsRem, _dsScaleTmp;
+	int _curDimIndex;	
 };
 
 }	// End of namespace Kyra
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index e25508f..a291a48 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -454,17 +454,16 @@ void EobCoreEngine::initStaticResource() {
 	_magicStrings2 = _staticres->loadStrings(kEobBaseMagicStrings2, temp);
 	_magicStrings3 = _staticres->loadStrings(kEobBaseMagicStrings3, temp);
 	_magicStrings4 = _staticres->loadStrings(kEobBaseMagicStrings4, temp);
-	_magicStrings5 = _staticres->loadStrings(kEobBaseMagicStrings5, temp);
 	_magicStrings6 = _staticres->loadStrings(kEobBaseMagicStrings6, temp);
 	_magicStrings7 = _staticres->loadStrings(kEobBaseMagicStrings7, temp);
 	_magicStrings8 = _staticres->loadStrings(kEobBaseMagicStrings8, temp);
 
-	_flightObjAnimTiles = _staticres->loadRawData(kEobBaseFlightObjAnimTiles, temp);
-	_flightObjAnimIndex = _staticres->loadRawData(kEobBaseFlightObjAnimIndex, temp);
-	_flightObjAnimDim = _staticres->loadRawData(kEobBaseFlightObjAnimDim, temp);
-	_flightObjAnimTbl1 = _staticres->loadRawData(kEobBaseFlightObjAnimTbl1, temp);
-	_flightObjAnimTbl2 = _staticres->loadRawData(kEobBaseFlightObjAnimTbl2, temp);
-	_flightObjAnimTbl3 = _staticres->loadRawData(kEobBaseFlightObjAnimTbl3, temp);
+	_expObjectTlMode = _staticres->loadRawData(kEobBaseExpObjectTlMode, temp);
+	_expObjectTblIndex = _staticres->loadRawData(kEobBaseExpObjectTblIndex, temp);
+	_expObjectShpStart = _staticres->loadRawData(kEobBaseExpObjectShpStart, temp);
+	_expObjectAnimTbl1 = _staticres->loadRawData(kEobBaseExpObjectTbl1, _expObjectAnimTbl1Size);
+	_expObjectAnimTbl2 = _staticres->loadRawData(kEobBaseExpObjectTbl2, _expObjectAnimTbl2Size);
+	_expObjectAnimTbl3 = _staticres->loadRawData(kEobBaseExpObjectTbl3, _expObjectAnimTbl3Size);
 
 	_sparkEffectDefSteps = _staticres->loadRawData(kEobBaseSparkDefSteps, temp);
 	_sparkEffectDefSubSteps = _staticres->loadRawData(kEobBaseSparkDefSubSteps, temp);
diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp
index 92c7f34..70b89be 100644
--- a/engines/kyra/timer_eob.cpp
+++ b/engines/kyra/timer_eob.cpp
@@ -232,7 +232,7 @@ void EobCoreEngine::timerProcessFlyingObjects(int timerNum) {
 		} else {
 			if (fo->flags & 0x20) {
 				if (!updateFlyingObjectHitTest(fo, fo->curBlock, fo->curPos))
-					updateFlyingObject_s3(fo);
+					explodeObject(fo, fo->curBlock, fo->item);
 			}
 			endFlight = true;
 		}


Commit: adbf14c3c480890dfb155b896d1805e102311aa9
    https://github.com/scummvm/scummvm/commit/adbf14c3c480890dfb155b896d1805e102311aa9
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:11-08:00

Commit Message:
KYRA: (EOB) - update static resources (menu strings)

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/resource.h
    engines/kyra/staticres_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index d27b5c1..d28e5b2 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -251,6 +251,26 @@ const ExtractFilename extractFilenames[] = {
 	{ kEobBaseCancelStrings, kTypeStringList, true },
 	{ kEobBaseAbortStrings, kTypeStringList, true },
 
+	{ kEobBaseMenuStringsMain, kTypeStringList, true },
+	{ kEobBaseMenuStringsSaveLoad, kTypeStringList, true },
+	{ kEobBaseMenuStringsOnOff, kTypeStringList, true },
+	{ kEobBaseMenuStringsSpells, kTypeStringList, true },
+	{ kEobBaseMenuStringsRest, kTypeStringList, true },
+	{ kEobBaseMenuStringsDrop, kTypeStringList, true },
+	{ kEobBaseMenuStringsExit, kTypeStringList, true },
+	{ kEobBaseMenuStringsStarve, kTypeStringList, true },
+	{ kEobBaseMenuStringsScribe, kTypeStringList, true },
+	{ kEobBaseMenuStringsDrop2, kTypeStringList, true },
+	{ kEobBaseMenuStringsHead, kTypeStringList, true },
+	{ kEobBaseMenuStringsPoison, kTypeStringList, true },
+	{ kEobBaseMenuStringsMgc, kTypeStringList, true },
+	{ kEobBaseMenuStringsPrefs, kTypeStringList, true },
+	{ kEobBaseMenuStringsRest2, kTypeStringList, true },
+	{ kEobBaseMenuStringsDefeat, kTypeStringList, true },
+	{ kEobBaseMenuStringsTransfer, kTypeStringList, true },
+	{ kEobBaseMenuStringsSpec, kTypeStringList, true },
+	{ kEobBaseMenuStringsSpellNo, kTypeStringList, false },
+	
 	{ kEobBaseCharGuiStringsHp, kTypeStringList, true },
 	{ kEobBaseCharGuiStringsWp1, kTypeStringList, true },
 	{ kEobBaseCharGuiStringsWp2, kTypeStringList, true },
@@ -1292,6 +1312,44 @@ const char *getIdString(const int id) {
 		return "kEobBaseCancelStrings";
 	case kEobBaseAbortStrings:
 		return "kEobBaseAbortStrings";
+	case kEobBaseMenuStringsMain:
+		return "kEobBaseMenuStringsMain";
+	case kEobBaseMenuStringsSaveLoad:
+		return "kEobBaseMenuStringsSaveLoad";
+	case kEobBaseMenuStringsOnOff:
+		return "kEobBaseMenuStringsOnOff";
+	case kEobBaseMenuStringsSpells:
+		return "kEobBaseMenuStringsSpells";
+	case kEobBaseMenuStringsRest:
+		return "kEobBaseMenuStringsRest";
+	case kEobBaseMenuStringsDrop:
+		return "kEobBaseMenuStringsDrop";
+	case kEobBaseMenuStringsExit:
+		return "kEobBaseMenuStringsExit";
+	case kEobBaseMenuStringsStarve:
+		return "kEobBaseMenuStringsStarve";
+	case kEobBaseMenuStringsScribe:
+		return "kEobBaseMenuStringsScribe";
+	case kEobBaseMenuStringsDrop2:
+		return "kEobBaseMenuStringsDrop2";
+	case kEobBaseMenuStringsHead:
+		return "kEobBaseMenuStringsHead";
+	case kEobBaseMenuStringsPoison:
+		return "kEobBaseMenuStringsPoison";
+	case kEobBaseMenuStringsMgc:
+		return "kEobBaseMenuStringsMgc";
+	case kEobBaseMenuStringsPrefs:
+		return "kEobBaseMenuStringsPrefs";
+	case kEobBaseMenuStringsRest2:
+		return "kEobBaseMenuStringsRest2";
+	case kEobBaseMenuStringsDefeat:
+		return "kEobBaseMenuStringsDefeat";
+	case kEobBaseMenuStringsTransfer:
+		return "kEobBaseMenuStringsTransfer";
+	case kEobBaseMenuStringsSpec:
+		return "kEobBaseMenuStringsSpec";
+	case kEobBaseMenuStringsSpellNo:
+		return "kEobBaseMenuStringsSpellNo";
 	case kEobBaseCharGuiStringsHp:
 		return "kEobBaseCharGuiStringsHp";
 	case kEobBaseCharGuiStringsWp1:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index 7ecc4b2..e9c2c57 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -226,6 +226,26 @@ enum kExtractID {
 	kEobBaseCancelStrings,
 	kEobBaseAbortStrings,
 
+	kEobBaseMenuStringsMain,
+	kEobBaseMenuStringsSaveLoad,
+	kEobBaseMenuStringsOnOff,
+	kEobBaseMenuStringsSpells,
+	kEobBaseMenuStringsRest,
+	kEobBaseMenuStringsDrop,
+	kEobBaseMenuStringsExit,
+	kEobBaseMenuStringsStarve,
+	kEobBaseMenuStringsScribe,
+	kEobBaseMenuStringsDrop2,
+	kEobBaseMenuStringsHead,
+	kEobBaseMenuStringsPoison,
+	kEobBaseMenuStringsMgc,
+	kEobBaseMenuStringsPrefs,
+	kEobBaseMenuStringsRest2,
+	kEobBaseMenuStringsDefeat,
+	kEobBaseMenuStringsTransfer,
+	kEobBaseMenuStringsSpec,
+	kEobBaseMenuStringsSpellNo,
+
 	kEobBaseCharGuiStringsHp,
 	kEobBaseCharGuiStringsWp1,
 	kEobBaseCharGuiStringsWp2,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index d4c4186..e99c6a8 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1077,6 +1077,23 @@ const int eob1FloppyNeed[] = {
 	kEobBaseNpcJoinStrings,
 	kEobBaseCancelStrings,
 
+	kEobBaseMenuStringsMain,
+	kEobBaseMenuStringsSaveLoad,
+	kEobBaseMenuStringsOnOff,
+	kEobBaseMenuStringsSpells,
+	kEobBaseMenuStringsRest,
+	kEobBaseMenuStringsDrop,
+	kEobBaseMenuStringsExit,
+	kEobBaseMenuStringsStarve,
+	kEobBaseMenuStringsScribe,
+	kEobBaseMenuStringsDrop2,
+	kEobBaseMenuStringsHead,
+	kEobBaseMenuStringsPoison,
+	kEobBaseMenuStringsMgc,
+	kEobBaseMenuStringsPrefs,
+	kEobBaseMenuStringsRest2,
+	kEobBaseMenuStringsDefeat,
+	
 	kEobBaseCharGuiStringsHp,
 	kEobBaseCharGuiStringsWp1,
 	kEobBaseCharGuiStringsWr,
@@ -1236,6 +1253,26 @@ const int eob2FloppyNeed[] = {
 	kEobBaseCancelStrings,
 	kEobBaseAbortStrings,
 
+	kEobBaseMenuStringsMain,
+	kEobBaseMenuStringsSaveLoad,
+	kEobBaseMenuStringsOnOff,
+	kEobBaseMenuStringsSpells,
+	kEobBaseMenuStringsRest,
+	kEobBaseMenuStringsDrop,
+	kEobBaseMenuStringsExit,
+	kEobBaseMenuStringsStarve,
+	kEobBaseMenuStringsScribe,
+	kEobBaseMenuStringsDrop2,
+	kEobBaseMenuStringsHead,
+	kEobBaseMenuStringsPoison,
+	kEobBaseMenuStringsMgc,
+	kEobBaseMenuStringsPrefs,
+	kEobBaseMenuStringsRest2,
+	kEobBaseMenuStringsDefeat,
+	kEobBaseMenuStringsTransfer,
+	kEobBaseMenuStringsSpec,
+	kEobBaseMenuStringsSpellNo,
+
 	kEobBaseCharGuiStringsHp,
 	kEobBaseCharGuiStringsWp2,
 	kEobBaseCharGuiStringsWr,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index fe4b18a..811d74b 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -1527,6 +1527,140 @@ const ExtractEntrySearchData kEobBaseAbortStringsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEobBaseMenuStringsMainProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000067, 0x0000245E, { { 0xD9, 0xE0, 0x74, 0x9D, 0x43, 0x96, 0xDC, 0x3B, 0xDF, 0x90, 0x03, 0xDE, 0x91, 0xE6, 0xA0, 0x1E } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x00000068, 0x000025D9, { { 0x17, 0xEB, 0xAB, 0x4F, 0x95, 0xD1, 0x7F, 0xEB, 0xF4, 0x92, 0x42, 0xD1, 0xD2, 0xA8, 0xC4, 0xA8 } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x00000069, 0x0000265B, { { 0x4C, 0xA9, 0x38, 0x28, 0xE1, 0xD0, 0xE3, 0x35, 0xBB, 0xDC, 0xFB, 0x6B, 0xAB, 0xB1, 0x62, 0x88 } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsSaveLoadProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000077, 0x00002513, { { 0x70, 0xD9, 0x48, 0xC2, 0x3A, 0x38, 0x1D, 0xD0, 0x8B, 0x90, 0x08, 0x8D, 0x80, 0xF5, 0x24, 0x59 } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x00000086, 0x00002D2F, { { 0x2B, 0x48, 0x5C, 0x78, 0xF9, 0xB9, 0xD6, 0xA8, 0x1D, 0xF4, 0x97, 0xAC, 0xF1, 0x09, 0x26, 0xA7 } } } }, // EOB1
+	{ EN_ANY, kPlatformUnknown, { 0x000000A9, 0x00003850, { { 0xC3, 0x09, 0x7B, 0x18, 0xD6, 0x08, 0x0E, 0x2A, 0xB6, 0x66, 0x43, 0x14, 0xD7, 0x59, 0x34, 0xF7 } } } }, // EOB2
+	{ DE_DEU, kPlatformUnknown, { 0x000000A2, 0x00003942, { { 0x6E, 0x10, 0x87, 0x4B, 0x80, 0xE8, 0x89, 0xC4, 0x31, 0xDC, 0xAC, 0xA9, 0xA3, 0x8D, 0x79, 0x41 } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsOnOffProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000007, 0x00000178, { { 0x4D, 0xA7, 0x13, 0x00, 0x05, 0xF2, 0x44, 0xCB, 0xF7, 0x12, 0x72, 0x54, 0xDE, 0x35, 0x04, 0xEC } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x00000007, 0x00000178, { { 0xC7, 0x6F, 0x60, 0x72, 0x47, 0x89, 0x47, 0xF0, 0x29, 0x57, 0x45, 0x41, 0xD5, 0x80, 0x40, 0x7B } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsSpellsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x000001EF, 0x0000A0D0, { { 0xBA, 0x80, 0x5C, 0xAB, 0x93, 0x19, 0x53, 0x45, 0x17, 0xBC, 0x86, 0x5B, 0x1B, 0x01, 0x3E, 0x98 } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x000001EA, 0x00009DE0, { { 0x00, 0xB0, 0x1F, 0xE7, 0x16, 0x48, 0x51, 0x25, 0xE5, 0xD8, 0xA1, 0x31, 0x13, 0x81, 0x8D, 0xB6 } } } }, // EOB1
+	{ EN_ANY, kPlatformUnknown, { 0x000001FB, 0x0000A658, { { 0xAD, 0x6A, 0xFE, 0x13, 0xE5, 0xEA, 0x6A, 0xD1, 0xC9, 0x80, 0x1C, 0xEE, 0xD7, 0x2A, 0xF8, 0xB2 } } } }, // EOB2
+	{ DE_DEU, kPlatformUnknown, { 0x00000222, 0x0000B1C9, { { 0x24, 0xC8, 0x9B, 0x51, 0xEE, 0x45, 0x14, 0xFC, 0x1B, 0xE4, 0x37, 0x8B, 0xEC, 0x94, 0xD9, 0x0B } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsRestProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x000000B3, 0x00003CED, { { 0x82, 0xF9, 0xA1, 0x74, 0xE6, 0x95, 0xA4, 0xFC, 0xE6, 0x5E, 0xB4, 0x43, 0x7D, 0x10, 0xFD, 0x12 } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x000000B3, 0x00003BE4, { { 0x7F, 0xE8, 0xFE, 0xA4, 0xD9, 0x5C, 0x49, 0x66, 0x38, 0x8F, 0x84, 0xB8, 0xF5, 0x03, 0xCD, 0x70 } } } }, // EOB
+	{ DE_DEU, kPlatformUnknown, { 0x000000C0, 0x000040A6, { { 0x05, 0x97, 0x45, 0x72, 0xE2, 0x33, 0xBE, 0xDE, 0x56, 0x26, 0x26, 0x15, 0x3A, 0x56, 0x93, 0xFD } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsDropProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000002E, 0x00000FCA, { { 0x88, 0xCB, 0xD2, 0xB3, 0xDA, 0x36, 0x97, 0x3D, 0xB8, 0x75, 0xFF, 0x36, 0xE1, 0x4E, 0xF4, 0x6D } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x00000039, 0x0000131E, { { 0x74, 0x0B, 0xE9, 0x04, 0x76, 0x26, 0xD2, 0xE8, 0x03, 0x48, 0x38, 0x18, 0xAC, 0x19, 0xBD, 0x7E } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x00000033, 0x0000119C, { { 0x8F, 0x2B, 0xC3, 0x01, 0xB2, 0xDE, 0x1F, 0xC6, 0x82, 0xC3, 0x58, 0x7C, 0x50, 0x23, 0x37, 0x65 } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsExitProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000002B, 0x00000E3D, { { 0x1C, 0xD6, 0x39, 0xA9, 0xC7, 0x3D, 0x32, 0x4A, 0xF2, 0xAE, 0xEC, 0x08, 0x6F, 0xC7, 0xA6, 0x7B } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x0000002D, 0x00000E68, { { 0x4B, 0x2F, 0x65, 0x39, 0x69, 0xE7, 0x3D, 0x7B, 0x10, 0x15, 0x6F, 0x1F, 0xD8, 0x8E, 0xEA, 0x55 } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x00000026, 0x00000CBD, { { 0x0C, 0x5D, 0xE4, 0xD2, 0x6F, 0xA3, 0x91, 0xDA, 0x5F, 0xE2, 0x57, 0x77, 0x74, 0x22, 0xE7, 0x85 } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsStarveProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000003D, 0x0000150C, { { 0x40, 0xEB, 0x79, 0xC3, 0x99, 0x4C, 0xEA, 0xCD, 0x8A, 0xB4, 0x54, 0xB8, 0xAA, 0xEC, 0xAD, 0x4F } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x00000037, 0x00001296, { { 0x51, 0x3C, 0x90, 0x91, 0x4E, 0x1C, 0x73, 0x2F, 0x0C, 0x7A, 0x6D, 0x03, 0x1E, 0x54, 0x65, 0xF1 } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x00000030, 0x00001057, { { 0xF3, 0x5E, 0xFC, 0xC3, 0x9D, 0xB5, 0xFE, 0x4E, 0x66, 0x9D, 0x6A, 0xC6, 0x61, 0xC8, 0x0A, 0x17 } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsScribeProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000103, 0x000055E1, { { 0x1B, 0x56, 0xD2, 0x78, 0x3F, 0x67, 0x7A, 0x5B, 0xB6, 0x2B, 0x70, 0x3D, 0x6A, 0xBB, 0x08, 0x0A } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x0000010C, 0x00005B1C, { { 0xD7, 0xBF, 0x37, 0x21, 0xA2, 0x63, 0x8C, 0x6A, 0x02, 0x92, 0x13, 0x32, 0xD6, 0xA6, 0x1C, 0xDC } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x00000100, 0x0000560F, { { 0x69, 0x15, 0x2C, 0x2D, 0xE7, 0x40, 0x4A, 0xE0, 0x86, 0x0D, 0xC8, 0x66, 0x87, 0x1C, 0x27, 0x0B } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsDrop2Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000084, 0x00002ACE, { { 0xAB, 0x78, 0x42, 0x29, 0xFB, 0xC5, 0x34, 0x96, 0x9D, 0x8A, 0x21, 0x46, 0xE7, 0x6B, 0x06, 0xBA } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x0000008C, 0x00002D02, { { 0x11, 0x3F, 0x0C, 0xB2, 0xBF, 0xA7, 0x39, 0x23, 0xDC, 0x00, 0xB4, 0xEA, 0x5E, 0xFE, 0x40, 0xB7 } } } }, // EOB1
+	{ EN_ANY, kPlatformUnknown, { 0x0000008E, 0x00002FFB, { { 0xCE, 0x7A, 0xCC, 0xA4, 0x02, 0x54, 0x1A, 0x78, 0xF1, 0xFC, 0xE6, 0x6C, 0x76, 0xCD, 0xFD, 0x9E } } } }, // EOB2
+	{ DE_DEU, kPlatformUnknown, { 0x00000090, 0x000031CE, { { 0x01, 0x72, 0x59, 0xBE, 0x62, 0x72, 0xD4, 0x99, 0x76, 0xC9, 0x92, 0x0E, 0xE9, 0x1A, 0xCD, 0x65 } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsHeadProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000021, 0x00000B27, { { 0x04, 0x06, 0x01, 0xF8, 0x50, 0x54, 0x11, 0x61, 0xFF, 0xB4, 0xE1, 0x97, 0xFA, 0x08, 0xAA, 0x1B } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x00000024, 0x00000CF5, { { 0x96, 0xD6, 0xB5, 0xB0, 0x2E, 0x71, 0xA4, 0x0A, 0x34, 0x41, 0x94, 0x02, 0x2F, 0xB0, 0x4C, 0x36 } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x00000025, 0x00000D92, { { 0xE4, 0x73, 0x2D, 0x29, 0xAD, 0x30, 0xE5, 0x8D, 0xAE, 0xC6, 0xD7, 0xF5, 0x35, 0xD8, 0xA4, 0x98 } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsPoisonProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000002E, 0x00001077, { { 0x14, 0x7E, 0xFC, 0xE0, 0x88, 0xFE, 0x86, 0xA8, 0x96, 0x94, 0xB1, 0x71, 0x90, 0x47, 0x2D, 0x78 } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x00000036, 0x000013A2, { { 0x18, 0xD9, 0x1D, 0xE5, 0x3D, 0xFD, 0x52, 0xB6, 0x18, 0x17, 0x61, 0xE8, 0xA5, 0x32, 0x9F, 0xA8 } } } }, // EOB1
+	{ EN_ANY, kPlatformUnknown, { 0x0000002D, 0x00001006, { { 0xD6, 0x0B, 0x11, 0x79, 0xAD, 0x61, 0x5B, 0x3A, 0x72, 0x7D, 0x53, 0x6F, 0xA9, 0x08, 0x73, 0xDC } } } }, // EOB2
+	{ DE_DEU, kPlatformUnknown, { 0x00000035, 0x000013BE, { { 0x73, 0x38, 0x76, 0x2C, 0x42, 0x87, 0x43, 0x7E, 0x8E, 0x4C, 0x41, 0x57, 0x3F, 0x04, 0xBA, 0x11 } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsMgcProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000020, 0x00000857, { { 0xD1, 0x9E, 0xBF, 0xF7, 0xCF, 0xF7, 0xD0, 0x94, 0x14, 0x56, 0xD2, 0x4F, 0x59, 0x91, 0x57, 0x52 } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x00000020, 0x0000086C, { { 0x12, 0x36, 0x84, 0x2F, 0x00, 0xAD, 0x12, 0x42, 0x3A, 0xA2, 0xC5, 0xC9, 0x59, 0x90, 0x64, 0x5F } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x00000021, 0x0000090B, { { 0x26, 0xA7, 0x58, 0x7C, 0x0C, 0x9E, 0x67, 0xB9, 0x05, 0xE6, 0x91, 0x59, 0xE3, 0xDF, 0x9C, 0x52 } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsPrefsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000041, 0x00001392, { { 0xB1, 0x7E, 0xE3, 0x73, 0xB2, 0xA2, 0x63, 0x39, 0x20, 0xE8, 0xF3, 0x38, 0x45, 0xB6, 0xAC, 0xC8 } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x00000045, 0x000015F6, { { 0x53, 0xBA, 0x7E, 0x6D, 0x24, 0x88, 0x2C, 0x19, 0x10, 0x71, 0x6F, 0xAB, 0x85, 0x8E, 0x97, 0xF6 } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x0000003D, 0x00001246, { { 0x03, 0xFB, 0x7C, 0x80, 0x33, 0x45, 0x6C, 0x27, 0x89, 0x7B, 0x7C, 0xAC, 0x7A, 0xE1, 0xDE, 0x49 } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsRest2Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000076, 0x00002530, { { 0xAD, 0x7A, 0x80, 0x8B, 0x97, 0x65, 0x67, 0xB2, 0x67, 0xE3, 0xF8, 0xDA, 0x0B, 0x9A, 0x61, 0x26 } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x00000082, 0x000029A1, { { 0x02, 0x83, 0xBC, 0x56, 0xB4, 0xFE, 0xF0, 0x03, 0x3D, 0xFD, 0x2C, 0x3B, 0x14, 0x8F, 0x44, 0x1B } } } }, // EOB
+	{ EN_ANY, kPlatformUnknown, { 0x000000A5, 0x000033C9, { { 0xC4, 0x69, 0x00, 0x7B, 0x93, 0x98, 0x0E, 0xD1, 0x94, 0xF8, 0x39, 0x19, 0xBA, 0x53, 0x37, 0x35 } } } }, // EOB2
+	{ DE_DEU, kPlatformUnknown, { 0x000000A4, 0x000033C1, { { 0x3B, 0x3A, 0x01, 0x8F, 0x3F, 0x9E, 0xC2, 0xC7, 0x70, 0xF8, 0x9C, 0x84, 0x6D, 0xFE, 0xC2, 0x40 } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsDefeatProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000006D, 0x00002643, { { 0x94, 0xBA, 0xAC, 0xA4, 0x87, 0x6A, 0xEA, 0x7D, 0x98, 0x6E, 0x09, 0x82, 0xE0, 0x16, 0x65, 0x4F } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x0000006A, 0x00002456, { { 0xE0, 0x9A, 0x10, 0xE2, 0x73, 0x42, 0xF6, 0x79, 0xCB, 0x65, 0xA2, 0x50, 0xF0, 0x2B, 0xFD, 0x9B } } } }, // EOB1
+	{ EN_ANY, kPlatformUnknown, { 0x00000056, 0x00001E4F, { { 0x97, 0x07, 0x5F, 0xA2, 0x0D, 0x58, 0xD2, 0xDF, 0xD6, 0x04, 0xA2, 0x16, 0x0B, 0x1F, 0x7E, 0x23 } } } }, // EOB2
+	{ DE_DEU, kPlatformUnknown, { 0x00000042, 0x000016B1, { { 0xCA, 0x57, 0xDC, 0x2B, 0xC6, 0xC7, 0x78, 0x1E, 0x84, 0x0A, 0x10, 0x88, 0xCA, 0xCD, 0xFF, 0x89 } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsTransferProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000114, 0x00005E09, { { 0xBF, 0xCE, 0x7F, 0xE4, 0x17, 0x15, 0xC6, 0x10, 0xDF, 0x16, 0xF9, 0x3C, 0xDA, 0x29, 0xA0, 0xA6 } } } }, // EOB2
+	{ DE_DEU, kPlatformUnknown, { 0x000000D1, 0x00004811, { { 0x2E, 0x00, 0xD1, 0xA6, 0x9F, 0x53, 0xC5, 0x4B, 0x25, 0x4A, 0xAC, 0x9E, 0x11, 0x6C, 0x58, 0x5E } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsSpecProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000006F, 0x00002785, { { 0xAE, 0xC7, 0x88, 0x89, 0x39, 0xB8, 0xF7, 0xB4, 0xD5, 0x82, 0xBC, 0x46, 0xA1, 0xCB, 0x04, 0x1F } } } }, // EOB2
+	{ DE_DEU, kPlatformUnknown, { 0x00000075, 0x00002871, { { 0xB4, 0x38, 0x0F, 0x94, 0x8B, 0xB1, 0x8D, 0xA3, 0xF8, 0xDA, 0x37, 0x75, 0x6F, 0x39, 0x3E, 0xB5 } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsSpellNoProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000006, 0x000000A5, { { 0x0D, 0x4A, 0x8B, 0x40, 0x70, 0x79, 0xCD, 0xB3, 0x0F, 0x5A, 0x5A, 0x3F, 0x6E, 0xE8, 0xF9, 0x74 } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
 const ExtractEntrySearchData kEobBaseCharGuiStringsHpProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000000F, 0x00000352, { { 0x9C, 0x13, 0x3D, 0x2A, 0x68, 0x11, 0x81, 0xA4, 0x77, 0x54, 0x47, 0x43, 0xA1, 0xDA, 0x55, 0x50 } } } }, 
 	{ DE_DEU, kPlatformUnknown, { 0x0000000E, 0x000002AC, { { 0xBB, 0xD5, 0x36, 0xB2, 0x8A, 0x60, 0x78, 0x04, 0x46, 0x2D, 0x35, 0x59, 0x3E, 0x42, 0xB9, 0x83 } } } },	// Eob 1
@@ -3229,6 +3363,26 @@ const ExtractEntry extractProviders[] = {
 	{ kEobBaseCancelStrings, kEobBaseCancelStringsProvider },
 	{ kEobBaseAbortStrings, kEobBaseAbortStringsProvider },
 
+	{ kEobBaseMenuStringsMain, kEobBaseMenuStringsMainProvider },
+	{ kEobBaseMenuStringsSaveLoad, kEobBaseMenuStringsSaveLoadProvider },
+	{ kEobBaseMenuStringsOnOff, kEobBaseMenuStringsOnOffProvider },
+	{ kEobBaseMenuStringsSpells, kEobBaseMenuStringsSpellsProvider },
+	{ kEobBaseMenuStringsRest, kEobBaseMenuStringsRestProvider },
+	{ kEobBaseMenuStringsDrop, kEobBaseMenuStringsDropProvider },
+	{ kEobBaseMenuStringsExit, kEobBaseMenuStringsExitProvider },
+	{ kEobBaseMenuStringsStarve, kEobBaseMenuStringsStarveProvider },
+	{ kEobBaseMenuStringsScribe, kEobBaseMenuStringsScribeProvider },
+	{ kEobBaseMenuStringsDrop2, kEobBaseMenuStringsDrop2Provider },
+	{ kEobBaseMenuStringsHead, kEobBaseMenuStringsHeadProvider },
+	{ kEobBaseMenuStringsPoison, kEobBaseMenuStringsPoisonProvider },
+	{ kEobBaseMenuStringsMgc, kEobBaseMenuStringsMgcProvider },
+	{ kEobBaseMenuStringsPrefs, kEobBaseMenuStringsPrefsProvider },
+	{ kEobBaseMenuStringsRest2, kEobBaseMenuStringsRest2Provider },
+	{ kEobBaseMenuStringsDefeat, kEobBaseMenuStringsDefeatProvider },
+	{ kEobBaseMenuStringsTransfer, kEobBaseMenuStringsTransferProvider },
+	{ kEobBaseMenuStringsSpec, kEobBaseMenuStringsSpecProvider },
+	{ kEobBaseMenuStringsSpellNo, kEobBaseMenuStringsSpellNoProvider },
+
 	{ kEobBaseCharGuiStringsHp, kEobBaseCharGuiStringsHpProvider },
 	{ kEobBaseCharGuiStringsWp1, kEobBaseCharGuiStringsWp1Provider },
 	{ kEobBaseCharGuiStringsWp2, kEobBaseCharGuiStringsWp2Provider },
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 8b28e86..9ead3c2 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -956,6 +956,28 @@ protected:
 
 	const uint8 *_magicFlightObjectProperties;
 
+	// Menu
+	const char *const *_menuStringsMain;
+	const char *const *_menuStringsSaveLoad;
+	const char *const *_menuStringsOnOff;
+	const char *const *_menuStringsSpells;
+	const char *const *_menuStringsRest;
+	const char *const *_menuStringsDrop;
+	const char *const *_menuStringsExit;
+	const char *const *_menuStringsStarve;
+	const char *const *_menuStringsScribe;
+	const char *const *_menuStringsDrop2;
+	const char *const *_menuStringsHead;
+	const char *const *_menuStringsPoison;
+	const char *const *_menuStringsMgc;
+	const char *const *_menuStringsPrefs;
+	const char *const *_menuStringsRest2;
+	const char *const *_menuStringsDefeat;
+
+	const char *const *_menuStringsTransfer;
+	const char *const *_menuStringsSpec;
+	const char *const *_menuStringsSpellNo;
+
 	// sound
 	void snd_playSoundEffect(int id, int volume=0xFF);
 };
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 34ab190..02af458 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -834,6 +834,29 @@ int EobCoreEngine::clickedCharPortraitDefault(Button *button) {
 }
 
 int EobCoreEngine::clickedCamp(Button *button) {
+	gui_updateControls();
+	disableSysTimer(2);
+	int cd = _screen->curDimIndex();
+
+	for (int i = 0; i < 6; i++) {
+		if (!testCharacter(i, 1))
+			continue;
+		_characters[i].damageTaken = 0;
+		_characters[i].slotStatus[0] = _characters[i].slotStatus[1] = 0;
+		gui_drawCharPortraitWithStats(i);
+	}
+
+	_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 14, Screen::CR_NO_P_CHECK);
+	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+	
+
+	_screen->setFont(of);
+	_screen->setCurPage(0);
+	_screen->setScreenDim(cd);
+
+	enableSysTimer(2);	
+	updateCharacterEvents(true);
+
 	return button->arg;
 }
 
@@ -1317,13 +1340,14 @@ void EobCoreEngine::gui_processWeaponSlotClickRight(int charIndex, int slotIndex
 
 		case 7:
 			// Food ration
-			/* don't do anything if mouse control is enabled */
-			//eatItemInHand(charIndex);
+			// Don't do anything if mouse control is enabled (we don't support anything else)
+			// eatItemInHand(charIndex);
 			break;
 
 		case 10:
 			if (_flags.gameID == GI_EOB1)
 				vl += _clericSpellOffset;
+			// drop through
 		case 9:
 			// Mage/Cleric Scroll
 			if (!_currentControlMode)
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 2f93add..90a3e74 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -299,6 +299,26 @@ enum KyraResources {
 	kEobBaseCancelStrings,
 	kEobBaseAbortStrings,
 
+	kEobBaseMenuStringsMain,
+	kEobBaseMenuStringsSaveLoad,
+	kEobBaseMenuStringsOnOff,
+	kEobBaseMenuStringsSpells,
+	kEobBaseMenuStringsRest,
+	kEobBaseMenuStringsDrop,
+	kEobBaseMenuStringsExit,
+	kEobBaseMenuStringsStarve,
+	kEobBaseMenuStringsScribe,
+	kEobBaseMenuStringsDrop2,
+	kEobBaseMenuStringsHead,
+	kEobBaseMenuStringsPoison,
+	kEobBaseMenuStringsMgc,
+	kEobBaseMenuStringsPrefs,
+	kEobBaseMenuStringsRest2,
+	kEobBaseMenuStringsDefeat,
+	kEobBaseMenuStringsTransfer,
+	kEobBaseMenuStringsSpec,
+	kEobBaseMenuStringsSpellNo,
+
 	kEobBaseCharGuiStringsHp,
 	kEobBaseCharGuiStringsWp1,
 	kEobBaseCharGuiStringsWp2,
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index a291a48..da4e675 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -366,6 +366,26 @@ void EobCoreEngine::initStaticResource() {
 	_cancelStrings = _staticres->loadStrings(kEobBaseCancelStrings, temp);
 	_abortStrings = _staticres->loadStrings(_flags.gameID == GI_EOB2 ? kEobBaseAbortStrings : kEobBaseCancelStrings, temp);
 
+	_menuStringsMain = _staticres->loadStrings(kEobBaseMenuStringsMain, temp);
+	_menuStringsSaveLoad = _staticres->loadStrings(kEobBaseMenuStringsSaveLoad, temp);
+	_menuStringsOnOff = _staticres->loadStrings(kEobBaseMenuStringsOnOff, temp);
+	_menuStringsSpells = _staticres->loadStrings(kEobBaseMenuStringsSpells, temp);
+	_menuStringsRest = _staticres->loadStrings(kEobBaseMenuStringsRest, temp);
+	_menuStringsDrop = _staticres->loadStrings(kEobBaseMenuStringsDrop, temp);
+	_menuStringsExit = _staticres->loadStrings(kEobBaseMenuStringsExit, temp);
+	_menuStringsStarve = _staticres->loadStrings(kEobBaseMenuStringsStarve, temp);
+	_menuStringsScribe = _staticres->loadStrings(kEobBaseMenuStringsScribe, temp);
+	_menuStringsDrop2 = _staticres->loadStrings(kEobBaseMenuStringsDrop2, temp);
+	_menuStringsHead = _staticres->loadStrings(kEobBaseMenuStringsHead, temp);
+	_menuStringsPoison = _staticres->loadStrings(kEobBaseMenuStringsPoison, temp);
+	_menuStringsMgc = _staticres->loadStrings(kEobBaseMenuStringsMgc, temp);
+	_menuStringsPrefs = _staticres->loadStrings(kEobBaseMenuStringsPrefs, temp);
+	_menuStringsRest2 = _staticres->loadStrings(kEobBaseMenuStringsRest2, temp);
+	_menuStringsDefeat = _staticres->loadStrings(kEobBaseMenuStringsDefeat, temp);
+	_menuStringsTransfer = _staticres->loadStrings(kEobBaseMenuStringsTransfer, temp);
+	_menuStringsSpec = _staticres->loadStrings(kEobBaseMenuStringsSpec, temp);
+	_menuStringsSpellNo = _staticres->loadStrings(kEobBaseMenuStringsSpellNo, temp);
+
 	_characterGuiStringsHp = _staticres->loadStrings(kEobBaseCharGuiStringsHp, temp);
 	_characterGuiStringsWp = _staticres->loadStrings(_flags.gameID == GI_EOB2 ? kEobBaseCharGuiStringsWp2 : kEobBaseCharGuiStringsWp1, temp);
 	_characterGuiStringsWr = _staticres->loadStrings(kEobBaseCharGuiStringsWr, temp);


Commit: c8665d06bc59b695cb6c444b1e3c24104b69dec4
    https://github.com/scummvm/scummvm/commit/c8665d06bc59b695cb6c444b1e3c24104b69dec4
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:11-08:00

Commit Message:
KYRA: (EOB) - fix some warnings and add some menu code

Changed paths:
    engines/kyra/chargen.cpp
    engines/kyra/eob2.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/gui_eob.h
    engines/kyra/items_eob.cpp
    engines/kyra/loleobbase.cpp
    engines/kyra/loleobbase.h
    engines/kyra/magic_eob.cpp
    engines/kyra/scene_eob.cpp
    engines/kyra/screen_eob.cpp
    engines/kyra/sequences_eob1.cpp
    engines/kyra/sequences_eob2.cpp
    engines/kyra/sprites_eob.cpp



diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index 59b46b5..17ee920 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -1028,11 +1028,11 @@ int CharacterGenerator::modifyStat(int index, int8 *stat1, int8 *stat2) {
 			v1++;
 
 		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP8]) {
-			ci = --ci % 7;
+			ci = (ci - 1) % 7;
 			loop = false;
 
 		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP2]) {
-			ci = ++ci % 7;
+			ci = (ci + 1) % 7;
 			loop = false;
 
 		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_o] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP5] || inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE] || inputFlag == 0x800A) {
@@ -1107,7 +1107,7 @@ int CharacterGenerator::modifyStat(int index, int8 *stat1, int8 *stat2) {
 			}
 		}
 
-		if (loop = false) {
+		if (loop == false) {
 			statStr = index ? Common::String::format("%d", *s1) : _vm->getCharStrength(*s1, *s2);
 			_screen->printText(statStr.c_str(), b->x + 32, b->y, 15, 0);
 			_screen->updateScreen();
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index 5af5049..45df528 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -200,6 +200,7 @@ void DarkMoonEngine::generateMonsterPalettes(const char *file, int16 monsterInde
 				c += 6;
 
 			c = (c << 1) + (ii - 1);
+			assert(c < 24);
 			memcpy(_monsterPalettes[c], tmpPal, 16);
 		}
 	}
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index d40620c..b7f3170 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -40,13 +40,14 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_teleporterWallId(flags.gameID == GI_EOB1 ? 52 : 44) {
 	_screen = 0;
 	_gui = 0;
-
+TTTTT=false;
 	//_runLoopUnk2 = 0;
 	//_runLoopTimerUnk = 0;
 	_playFinale = false;
 	_runFlag = true;
 	_saveLoadMode = 0;
 	_updateHandItemCursor = false;
+	_configMouse = true;
 
 	_largeItemShapes = _smallItemShapes = _thrownItemShapes = _spellShapes = _firebeamShapes = _itemIconShapes =
 		_wallOfForceShapes = _teleporterShapes = _sparkShapes = _compassShapes = 0;
@@ -54,6 +55,8 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 		_weaponSlotGrid = _blackBoxWideGrid = _lightningColumnShape = 0;
 	_tempIconShape = 0;
 
+	_menuStringsPrefsTemp = 0;
+
 	_monsterDustStrings = 0;
 	_monsterDistAttType10 = 0;
 	_monsterDistAttSfx10 = 0;
@@ -105,7 +108,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 
 	_exchangeCharacterId = -1;
 	_charExchangeSwap = 0;
-	_hpBarGraphs = true;
+	_configHpBarGraphs = true;
 
 	memset(_dialogueLastBitmap, 0, 13);
 	_dlgUnk1 = 0;
@@ -140,6 +143,12 @@ EobCoreEngine::~EobCoreEngine() {
 	releaseItemsAndDecorationsShapes();
 	releaseTempData();
 
+	if (_menuStringsPrefsTemp) {
+		for (int i = 0; i < 4; i++)
+			delete _menuStringsPrefsTemp[i];
+		delete[] _menuStringsPrefsTemp;
+	}
+
 	if (_faceShapes) {
 		for (int i = 0; i < 44; i++) {
 			if (_characters) {
@@ -259,6 +268,9 @@ Common::Error EobCoreEngine::init() {
 	initStaticResource();
 	initSpells();
 
+	_menuStringsPrefsTemp = new char*[4];
+	memset(_menuStringsPrefsTemp, 0, 4 * sizeof(char*));
+
 	_timer = new TimerManager(this, _system);
 	assert(_timer);
 	setupTimers();
@@ -373,17 +385,13 @@ Common::Error EobCoreEngine::go() {
 
 void EobCoreEngine::runLoop() {
 	_envAudioTimer = _system->getMillis() + (rollDice(1, 10, 3) * 18 * _tickLength);
-	///
-	// startupSub1
-	//
-	//
+	
 	_updateFlags = 0;
-	//_unkCharacterId = 0;
+	_updateCharNum = 0;
 	_flashShapeTimer = 0;
 	_drawSceneTimer = _system->getMillis();
-	//_unkBBBBBBBBBBBBBBBB = 1;
+	//__unkB__ = 1;
 	gui_setPlayFieldButtons();
-	//
 
 	_screen->_curPage = 0;
 	gui_drawPlayField(0);
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 9ead3c2..5e34dc3 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -71,8 +71,8 @@ struct EobChargenButtonDef {
 };
 
 struct EobGuiButtonDef {
-	uint8 keyCode;
-	uint8 keyCode2;
+	uint16 keyCode;
+	uint16 keyCode2;
 	uint16 flags;
 	uint16 x;
 	uint8 y;
@@ -547,7 +547,7 @@ protected:
 	virtual void loadDoorShapes(int doorType1, int shapeId1, int doorType2, int shapeId2) {}
 	virtual const uint8 *loadDoorShapes(const char *filename, int doorIndex, const uint8*shapeDefs) { return (const uint8*)filename; }
 
-	void drawScene(int update);
+	void drawScene(int refresh);
 	void drawSceneShapes(int start = 0);
 	void drawDecorations(int index);
 
@@ -707,7 +707,7 @@ protected:
 	const uint8 *_inventorySlotsY;
 	const uint8 **_compassShapes;
 	uint8 _charExchangeSwap;
-	bool _hpBarGraphs;
+	bool _configHpBarGraphs;
 
 	// text
 	void setupDialogueButtons(int presetfirst, int numStr, const char *str1, ...);
@@ -957,6 +957,10 @@ protected:
 	const uint8 *_magicFlightObjectProperties;
 
 	// Menu
+	char **_menuStringsPrefsTemp;
+
+	bool _configMouse;
+
 	const char *const *_menuStringsMain;
 	const char *const *_menuStringsSaveLoad;
 	const char *const *_menuStringsOnOff;
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 02af458..56c5acd 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -456,7 +456,7 @@ void EobCoreEngine::gui_drawHitpoints(int index) {
 
 	EobCharacter *c = &_characters[index];
 
-	if (_hpBarGraphs) {
+	if (_configHpBarGraphs) {
 		int bgCur = c->hitPointsCur + 10;
 		int bgMax = c->hitPointsMax + 10;
 		int col = ((bgMax / 3) > bgCur) ? 1 : 0;
@@ -849,10 +849,32 @@ int EobCoreEngine::clickedCamp(Button *button) {
 	_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 14, Screen::CR_NO_P_CHECK);
 	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
 	
+	for (int i = 0; i < 4; i++) {
+		delete _menuStringsPrefsTemp[i];
+		_menuStringsPrefsTemp[i] = new char[strlen(_menuStringsPrefs[i]) + 8];
+	}
 
+	Common::strlcpy(_menuStringsPrefsTemp[0], Common::String::format(_menuStringsPrefs[0], _menuStringsOnOff[_configMusic ? 0 : 1]).c_str(), strlen(_menuStringsPrefs[0]) + 8);
+	Common::strlcpy(_menuStringsPrefsTemp[1], Common::String::format(_menuStringsPrefs[1], _menuStringsOnOff[_configSounds ? 0 : 1]).c_str(), strlen(_menuStringsPrefs[1]) + 8);
+	Common::strlcpy(_menuStringsPrefsTemp[2], Common::String::format(_menuStringsPrefs[2], _menuStringsOnOff[_configHpBarGraphs ? 0 : 1]).c_str(), strlen(_menuStringsPrefs[2]) + 8);
+	Common::strlcpy(_menuStringsPrefsTemp[3], Common::String::format(_menuStringsPrefs[3], _menuStringsOnOff[_configMouse ? 0 : 1]).c_str(), strlen(_menuStringsPrefs[3]) + 8);
+	
 	_screen->setFont(of);
-	_screen->setCurPage(0);
+	_screen->copyRegion(0, 0, 0, 120, 176, 24, 14, 2, Screen::CR_NO_P_CHECK);
 	_screen->setScreenDim(cd);
+	drawScene(0);
+
+	//for (int i = 0; i < 6; i++)
+	//	cleanupCharacterSpellList(i);
+
+	_screen->setCurPage(0);
+	const ScreenDim *dm = _screen->getScreenDim(10);
+	_screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK);	
+	
+	//if (displayInv)
+	//	_screen->loadEobCpsFileToPage("INVENT", 0, 5, 3, 2);
+	
+	_screen->updateScreen();
 
 	enableSysTimer(2);	
 	updateCharacterEvents(true);
@@ -1548,7 +1570,7 @@ int GUI_Eob::processButtonList(Kyra::Button *buttonList, uint16 inputFlags, int8
 	uint16 in = inputFlags & 0xff;
 	uint16 buttonReleaseFlag = 0;
 	bool clickEvt = false;
-
+	_vm->TTTTT = true;
 	_flagsMouseLeft = (_vm->_mouseClick == 1) ? 2 : 4;
 	_flagsMouseRight = (_vm->_mouseClick == 2) ? 2 : 4;
 	_vm->_mouseClick = 0;
@@ -1919,7 +1941,7 @@ int GUI_Eob::processButtonList(Kyra::Button *buttonList, uint16 inputFlags, int8
 
 	if (!result)
 		result = inputFlags;
-
+_vm->	TTTTT=false;
 	return result;
 }
 
diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h
index 82e9476..2ad69e7 100644
--- a/engines/kyra/gui_eob.h
+++ b/engines/kyra/gui_eob.h
@@ -49,6 +49,7 @@ public:
 	int redrawShadedButtonCallback(Button *button) { return 0; }
 	int redrawButtonCallback(Button *button) { return 0; }
 
+	// general menu handling (main menu, character generation, ingame menus, etc.)
 	void setupMenu(int sd, int maxItem, const char *const *strings, int32 menuItemsMask, int unk, int lineSpacing);
 	int handleMenu(int sd, const char *const *strings, void *b, int32 menuItemsMask, int unk);
 	int getMenuItem(int index, int32 menuItemsMask, int unk);
@@ -56,7 +57,7 @@ public:
 
 	int getTextInput(char *dest, int x, int y, int destMaxLen, int textColor1, int textColor2, int cursorColor);
 
-	//int runMenu(Menu &menu);
+	// int runMenu(Menu &menu);
 
 	// utilities for thumbnail creation
 	void createScreenThumbnail(Graphics::Surface &dst) {}
diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
index e536b67..f9b5212 100644
--- a/engines/kyra/items_eob.cpp
+++ b/engines/kyra/items_eob.cpp
@@ -258,8 +258,8 @@ int EobCoreEngine::countQueuedItems(Item itemQueue, int16 id, int16 type, int co
 		EobItem *itm = &_items[o1];
 		forceLoop = false;
 		if (id != -1 || type != -1) {
-			if ((id != -1 || (id == -1 && type != itm->type)) && (type != -1) || (id != o1))
-				continue;
+			if (((id != -1 ) || (id == -1 && type != itm->type)) && ((type != -1) || (type == -1 && id != o1)))
+				continue;			
 		}
 
 		if (!includeFlyingItems) {
diff --git a/engines/kyra/loleobbase.cpp b/engines/kyra/loleobbase.cpp
index a7a47b6..7db1a4a 100644
--- a/engines/kyra/loleobbase.cpp
+++ b/engines/kyra/loleobbase.cpp
@@ -260,7 +260,7 @@ uint16 LolEobBaseEngine::processDialogue() {
 		if (e)
 			gui_notifyButtonListChanged();
 
-		if (_flags.gameID == GI_LOL && (e == 200 || e == 202) || _flags.gameID != GI_LOL && (e == 199 || e == 201)) {
+		if ((_flags.gameID == GI_LOL && (e == 200 || e == 202)) || (_flags.gameID != GI_LOL && (e == 199 || e == 201))) {
 			for (int i = 0; i < _dialogueNumButtons; i++) {
 				int x = _dialogueButtonPosX[i];
 				int y = (gameFlags().use16ColorMode ? ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) & ~7) - 1 : (_dialogueButtonYoffs + _dialogueButtonPosY[i]));
diff --git a/engines/kyra/loleobbase.h b/engines/kyra/loleobbase.h
index 831c644..1be2a8b 100644
--- a/engines/kyra/loleobbase.h
+++ b/engines/kyra/loleobbase.h
@@ -253,6 +253,7 @@ protected:
 
 	Button *_activeButtons;
 	Button _activeButtonData[70];
+bool TTTTT;
 
 	uint8 _mouseClick;
 	bool _preserveEvents;
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 16e8996..2c83c26 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -175,13 +175,14 @@ void EobCoreEngine::castSpell(int spell, int weaponSlot) {
 				memmove(&_openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellListOffset + _openBookSpellSelectedItem], &_openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellListOffset + _openBookSpellSelectedItem + 1], 8 - (_openBookSpellListOffset + _openBookSpellSelectedItem));
 			_openBookAvailableSpells[_openBookSpellLevel * 10 + 8] = -tmp;
 			if (_openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellListOffset + _openBookSpellSelectedItem] < 0) {
-				if (--_openBookSpellSelectedItem == -1)
+				if (--_openBookSpellSelectedItem == -1) {
 					if (_openBookSpellListOffset) {
 						_openBookSpellListOffset = 0;
 						_openBookSpellSelectedItem = 5;
 					} else {
 						_openBookSpellSelectedItem = 6;
 					}
+				}
 			}
 		} else if (weaponSlot != -1) {
 			updateUsedCharacterHandItem(_openBookChar, weaponSlot);
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index a8ca966..56bf352 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -989,13 +989,13 @@ void EobCoreEngine::toggleWallState(int wall, int toggle) {
 	}
 }
 
-void EobCoreEngine::drawScene(int update) {
+void EobCoreEngine::drawScene(int refresh) {
 	generateBlockDrawingBuffer();
 	drawVcnBlocks();
 	drawSceneShapes();
 
 	if (_sceneDrawPage2) {
-		if (update)
+		if (refresh)
 			_screen->fillRect(0, 0, 176, 120, 12);
 
 		_screen->setScreenPalette(_screen->getPalette(0));
@@ -1018,15 +1018,15 @@ void EobCoreEngine::drawScene(int update) {
 		delayUntil(_drawSceneTimer);
 	}
 
-	if (update && !_partyResting)
+	if (refresh && !_partyResting)
 		_screen->copyRegion(0, 0, 0, 0, 176, 120, 2, 0, Screen::CR_NO_P_CHECK);
 
 	updateEnvironmentalSfx(0);
 
-	if (!_dialogueField && update && !_updateFlags)
+	if (!_dialogueField && refresh && !_updateFlags)
 		gui_drawCompass(false);
 
-	if (update && !_partyResting)
+	if (refresh && !_partyResting)
 		_screen->updateScreen();
 
 	if (_sceneDefaultUpdate) {
diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp
index b93ab3e..f6b0eaf 100644
--- a/engines/kyra/screen_eob.cpp
+++ b/engines/kyra/screen_eob.cpp
@@ -508,7 +508,7 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
 							break;
 
 					if (!*(src-1) || i < marginLeft)
-						marginLeft = ++marginLeft - *src++;
+						marginLeft = marginLeft + 1 - *src++;
 					else
 						marginLeft = 0;
 
@@ -723,7 +723,6 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize
 	int16 gx2 = _gfxX;
 	int16 gy2 = _gfxY;
 
-	uint8 *ptr1 = _dsTempPage;
 	int16 *ptr2 = (int16*)_dsTempPage;
 	int16 *ptr3 = (int16*)&_dsTempPage[300];
 	int16 *ptr4 = (int16*)&_dsTempPage[600];
diff --git a/engines/kyra/sequences_eob1.cpp b/engines/kyra/sequences_eob1.cpp
index 0606742..7e15a7a 100644
--- a/engines/kyra/sequences_eob1.cpp
+++ b/engines/kyra/sequences_eob1.cpp
@@ -37,8 +37,7 @@ int EobEngine::mainMenu() {
 	int menuChoice = 4;
 
 	Screen::FontId of = _screen->_currentFont;
-	Common::SeekableReadStream *s = 0;
-
+	
 	while (menuChoice >= 0 && !shouldQuit()) {
 		switch (menuChoice) {
 			case 0:
diff --git a/engines/kyra/sequences_eob2.cpp b/engines/kyra/sequences_eob2.cpp
index 708e9cd..07dd523 100644
--- a/engines/kyra/sequences_eob2.cpp
+++ b/engines/kyra/sequences_eob2.cpp
@@ -70,8 +70,6 @@ private:
 	Screen_Eob *_screen;
 	Mode _mode;
 
-	uint8 _notifier;
-
 	const char *const *_strings;
 	const char *const *_cpsFiles;
 	const char *const *_palFiles;
@@ -1259,7 +1257,7 @@ void DarkmoonSequenceHelper::delay(uint32 ticks) {
 
 void DarkmoonSequenceHelper::waitForSongNotifier(int index, bool introUpdateAnim) {
 	int seq = 0;
-	while (_notifier < index && !(_vm->skipFlag() || _vm->shouldQuit())) {
+	while (_vm->sound()->checkTrigger() < index && !(_vm->skipFlag() || _vm->shouldQuit())) {
 		if (introUpdateAnim) {
 			runSequence(30 | seq);
 			seq ^= 1;
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index aac3c27..1fa89ea 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -387,18 +387,18 @@ void EobCoreEngine::flashMonsterShape(EobMonsterInPlay *m) {
 
 void EobCoreEngine::updateAllMonsterShapes() {
 	drawScene(1);
-	bool update = false;
+	bool updateShp = false;
 
 	for (EobMonsterInPlay *m = _monsters; m < &_monsters[30]; m++) {
 		if (m->flags & 2) {
 			m->flags &= ~2;
-			update = true;
+			updateShp = true;
 			if (m->hitPointsCur <= 0)
 				killMonster(m, true);
 		}
 	}
 
-	if (update) {
+	if (updateShp) {
 		_sceneUpdateRequired = true;
 		_flashShapeTimer = _system->getMillis() + _tickLength;
 	} else {
@@ -995,7 +995,7 @@ bool EobCoreEngine::updateMonsterTryDistanceAttack(EobMonsterInPlay *m) {
 					statusAttack(i, 4, _monsterSpecAttStrings[1], 1, 5, 9, 1);
 			}
 		} else {
-			Item itm = duplicateItem(-s);
+			itm = duplicateItem(-s);
 			if (itm) {
 				if (launchObject(-1, itm, m->block, m->pos, m->dir, _items[itm].type))
 					_items[itm].block = -1;
@@ -1240,7 +1240,7 @@ void EobCoreEngine::setBlockMonsterDirection(int block, int dir) {
 		if (_monsters[i].block != block || _monsters[i].dir == dir)
 			continue;
 		_monsters[i].dir = dir;
-		_monsters[i].directionChanged == 1;
+		_monsters[i].directionChanged = 1;
 	}
 }
 


Commit: 514c77625f3f4d60ca463c1af34fc0672c75df45
    https://github.com/scummvm/scummvm/commit/514c77625f3f4d60ca463c1af34fc0672c75df45
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:11-08:00

Commit Message:
KYRA: (EOB) - fix out of bounds mem access

Changed paths:
    engines/kyra/items_eob.cpp



diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
index f9b5212..98cd634 100644
--- a/engines/kyra/items_eob.cpp
+++ b/engines/kyra/items_eob.cpp
@@ -58,8 +58,8 @@ void EobCoreEngine::loadItemDefs() {
 	s = _res->createReadStream("itemtype.dat");
 	uint16 numTypes = s->readUint16LE();
 
-	_itemTypes = new EobItemType[numTypes];
-	memset(_itemTypes, 0, sizeof(EobItemType) * numTypes);
+	_itemTypes = new EobItemType[65];
+	memset(_itemTypes, 0, sizeof(EobItemType) * 65);
 
 	for (int i = 0; i < numTypes; i++) {
 		_itemTypes[i].invFlags = s->readUint16LE();


Commit: 6853452bcbed083aa84638f11e4ce04ca189f0a1
    https://github.com/scummvm/scummvm/commit/6853452bcbed083aa84638f11e4ce04ca189f0a1
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:11-08:00

Commit Message:
KYRA: (EOB) - fix shift key input

Changed paths:
    engines/kyra/eobcommon.cpp
    engines/kyra/gui_eob.cpp
    engines/kyra/kyra_v1.cpp
    engines/kyra/loleobbase.cpp
    engines/kyra/loleobbase.h



diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index b7f3170..89a20a0 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -40,7 +40,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_teleporterWallId(flags.gameID == GI_EOB1 ? 52 : 44) {
 	_screen = 0;
 	_gui = 0;
-TTTTT=false;
+	//_processingButtons=false;
 	//_runLoopUnk2 = 0;
 	//_runLoopTimerUnk = 0;
 	_playFinale = false;
@@ -411,7 +411,7 @@ void EobCoreEngine::runLoop() {
 	while (!shouldQuit() && _runFlag) {
 		//_runLoopUnk2 = _currentBlock;
 		updateCharacterEvents(true);
-		checkInput(_activeButtons, true);
+		checkInput(_activeButtons, true, 0);
 		removeInputTop();
 
 		if (_updateHandItemCursor) {
@@ -1269,7 +1269,7 @@ void EobCoreEngine::displayParchment(int id) {
 		removeInputTop();
 		while (!shouldQuit()) {
 			delay(_tickLength);
-			if (checkInput(0) & 0xff)
+			if (checkInput(0, false, 0) & 0xff)
 				break;
 			removeInputTop();
 		}
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 56c5acd..10eabe9 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -1570,7 +1570,7 @@ int GUI_Eob::processButtonList(Kyra::Button *buttonList, uint16 inputFlags, int8
 	uint16 in = inputFlags & 0xff;
 	uint16 buttonReleaseFlag = 0;
 	bool clickEvt = false;
-	_vm->TTTTT = true;
+	//_vm->_processingButtons = true;
 	_flagsMouseLeft = (_vm->_mouseClick == 1) ? 2 : 4;
 	_flagsMouseRight = (_vm->_mouseClick == 2) ? 2 : 4;
 	_vm->_mouseClick = 0;
@@ -1589,7 +1589,7 @@ int GUI_Eob::processButtonList(Kyra::Button *buttonList, uint16 inputFlags, int8
 
 		inputFlags = 0;
 		clickEvt = true;
-	} else {
+	} else if (inputFlags & 0x8000) {
 		inputFlags &= 0xff;
 	}
 
@@ -1668,13 +1668,13 @@ int GUI_Eob::processButtonList(Kyra::Button *buttonList, uint16 inputFlags, int8
 		uint16 vR = 0;
 
 		if (inputFlags) {
-			if (buttonList->keyCode == in) {
+			if (buttonList->keyCode == inputFlags) {
 				_progress = 1;
 				_flagsMouseLeft = 1;
 				flgs2 ^= 1;
 				result = iFlag;
 				v6 = 1;
-			} else if (buttonList->keyCode2 == in) {
+			} else if (buttonList->keyCode2 == inputFlags) {
 				_progress = 2;
 				_flagsMouseRight = 1;
 				result = iFlag;
@@ -1941,7 +1941,9 @@ int GUI_Eob::processButtonList(Kyra::Button *buttonList, uint16 inputFlags, int8
 
 	if (!result)
 		result = inputFlags;
-_vm->	TTTTT=false;
+	
+	//_vm->_processingButtons=false;
+
 	return result;
 }
 
diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp
index f5ef0d0..c1b9f2a 100644
--- a/engines/kyra/kyra_v1.cpp
+++ b/engines/kyra/kyra_v1.cpp
@@ -285,10 +285,13 @@ int KyraEngine_v1::checkInput(Button *buttonList, bool mainLoop, int eventFlag)
 				}
 			} else {
 				KeyMap::const_iterator keycode = _keyMap.find(event.kbd.keycode);
-				if (keycode != _keyMap.end())
+				if (keycode != _keyMap.end()) {
 					keys = keycode->_value;
-				else
+					if (event.kbd.flags & Common::KBD_SHIFT)
+						keys |= 0x100;
+				} else {
 					keys = 0;
+				}
 
 				// When we got an keypress, which we might need to handle,
 				// break the event loop and pass it to GUI code.
diff --git a/engines/kyra/loleobbase.cpp b/engines/kyra/loleobbase.cpp
index 7db1a4a..47a261b 100644
--- a/engines/kyra/loleobbase.cpp
+++ b/engines/kyra/loleobbase.cpp
@@ -255,7 +255,7 @@ uint16 LolEobBaseEngine::processDialogue() {
 				}
 		}
 	} else {
-		int e = checkInput(0, false) & 0xFF;
+		int e = checkInput(0, false, 0) & 0xFF;
 		removeInputTop();
 		if (e)
 			gui_notifyButtonListChanged();
diff --git a/engines/kyra/loleobbase.h b/engines/kyra/loleobbase.h
index 1be2a8b..a2c1382 100644
--- a/engines/kyra/loleobbase.h
+++ b/engines/kyra/loleobbase.h
@@ -253,7 +253,7 @@ protected:
 
 	Button *_activeButtons;
 	Button _activeButtonData[70];
-bool TTTTT;
+	//bool _processingButtons;
 
 	uint8 _mouseClick;
 	bool _preserveEvents;


Commit: 894df5a4ac97bc67cfe7fd9a7df17e541c505365
    https://github.com/scummvm/scummvm/commit/894df5a4ac97bc67cfe7fd9a7df17e541c505365
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:11-08:00

Commit Message:
KYRA: (EOB) - extended saveload caps

(also save/load inventory and spellbook display state)

Changed paths:
    engines/kyra/eob1.cpp
    engines/kyra/eob2.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/saveload_eob.cpp



diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
index 993d06a..3a6bd28 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -73,6 +73,7 @@ void EobEngine::startupNew() {
 	_currentBlock = 490;
 	_currentDirection = 0;
 	setHandItem(0);
+	EobCoreEngine::startupNew();
 }
 
 void EobEngine::startupLoad() {
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index 45df528..06e85a8 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -73,6 +73,7 @@ void DarkMoonEngine::startupNew() {
 	_currentBlock = 171;
 	_currentDirection = 2;
 	setHandItem(0);
+	EobCoreEngine::startupNew();
 }
 
 void DarkMoonEngine::startupLoad() {
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 89a20a0..e0fb584 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -383,26 +383,23 @@ Common::Error EobCoreEngine::go() {
 	return Common::kNoError;
 }
 
-void EobCoreEngine::runLoop() {
-	_envAudioTimer = _system->getMillis() + (rollDice(1, 10, 3) * 18 * _tickLength);
-	
-	_updateFlags = 0;
-	_updateCharNum = 0;
-	_flashShapeTimer = 0;
-	_drawSceneTimer = _system->getMillis();
-	//__unkB__ = 1;
+void EobCoreEngine::startupNew() {
 	gui_setPlayFieldButtons();
-
 	_screen->_curPage = 0;
 	gui_drawPlayField(0);
-
-	_screen->setFont(Screen::FID_6_FNT);
-
 	_screen->_curPage = 0;
 	gui_drawAllCharPortraitsWithStats();
-
 	drawScene(1);
+	_updateFlags = 0;
+	_updateCharNum = 0;
+}
 
+void EobCoreEngine::runLoop() {
+	_envAudioTimer = _system->getMillis() + (rollDice(1, 10, 3) * 18 * _tickLength);	
+	_flashShapeTimer = 0;
+	_drawSceneTimer = _system->getMillis();
+	//__unkB__ = 1;
+	_screen->setFont(Screen::FID_6_FNT);
 	_screen->setScreenDim(7);
 
 	//_runLoopUnk2 = _currentBlock;
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 5e34dc3..6632ae3 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -292,7 +292,7 @@ protected:
 	const char *const *_mainMenuStrings;
 
 	// Main loop
-	virtual void startupNew() = 0;
+	virtual void startupNew();
 	virtual void startupLoad() = 0;
 	void runLoop();
 	void update() { screen()->updateScreen(); }
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index ee91b65..18ddddd 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -229,6 +229,23 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 	_itemInHand = in.readSint16BE();
 	_hasTempDataFlags = in.readUint32BE();
 	_partyEffectFlags = in.readUint32BE();
+	
+	_updateFlags = in.readUint16BE();
+	_compassDirection = in.readUint16BE();
+	_currentControlMode = in.readUint16BE();
+	_updateCharNum = in.readUint16BE();
+	_openBookSpellLevel = in.readSByte();
+	_openBookSpellSelectedItem  = in.readSByte();
+	_openBookSpellListOffset = in.readSByte();
+	_openBookChar = in.readByte();
+	_openBookType = in.readByte();
+	_openBookCharBackup = in.readByte();
+	_openBookTypeBackup = in.readByte();
+	_activeSpellCaster = in.readByte();
+	_activeSpellCasterPos = in.readByte();
+	_activeSpell = in.readByte();
+	_returnAfterSpellCallback = in.readByte() ? true : false;
+
 	_inf->loadState(in);
 
 	for (int i = 0; i < 600; i++) {
@@ -336,15 +353,29 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 
 	if (_saveLoadMode != -1) {
 		loadLevel(_currentLevel, _currentSub);
-		gui_drawPlayField(0);
 		_sceneUpdateRequired = true;
-		_screen->setCurPage(0);
 		_screen->setFont(Screen::FID_6_FNT);
-		gui_drawAllCharPortraitsWithStats();
-		updateHandItemCursor();
 		_saveLoadMode = 1;
 	}
 
+	_screen->setCurPage(0);
+	gui_drawPlayField(0);
+
+	if (_currentControlMode)
+		_screen->copyRegion(176, 0, 0, 0, 144, 168, 0, 5, Screen::CR_NO_P_CHECK);
+
+	_screen->setCurPage(0);
+	gui_drawAllCharPortraitsWithStats();
+	drawScene(1);
+
+	if (_updateFlags) {
+		_updateFlags = 0;
+		useMagicBookOrSymbol(_openBookChar, _openBookType);
+	}
+
+	gui_toggleButtons();
+	updateHandItemCursor();
+
 	while (!_screen->isMouseVisible())
 		_screen->showMouse();
 
@@ -418,6 +449,23 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName,
 	out->writeSint16BE(_itemInHand);
 	out->writeUint32BE(_hasTempDataFlags);
 	out->writeUint32BE(_partyEffectFlags);
+	
+	out->writeUint16BE(_updateFlags);
+	out->writeUint16BE(_compassDirection);
+	out->writeUint16BE(_currentControlMode);
+	out->writeUint16BE(_updateCharNum);
+	out->writeSByte(_openBookSpellLevel);
+	out->writeSByte(_openBookSpellSelectedItem);
+	out->writeSByte(_openBookSpellListOffset);
+	out->writeByte(_openBookChar);
+	out->writeByte(_openBookType);
+	out->writeByte(_openBookCharBackup);
+	out->writeByte(_openBookTypeBackup);
+	out->writeByte(_activeSpellCaster);
+	out->writeByte(_activeSpellCasterPos);
+	out->writeByte(_activeSpell);
+	out->writeByte(_returnAfterSpellCallback ? 1 : 0);
+
 	_inf->saveState(out);
 
 	for (int i = 0; i < 600; i++) {


Commit: 69ad70afbb16f25f62432fb497e39c9d5633c10a
    https://github.com/scummvm/scummvm/commit/69ad70afbb16f25f62432fb497e39c9d5633c10a
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:11-08:00

Commit Message:
KYRA: (EOB) - allow returning to the main menu from character generation via ESC

Changed paths:
    engines/kyra/chargen.cpp
    engines/kyra/eob1.cpp
    engines/kyra/eob1.h
    engines/kyra/eob2.cpp
    engines/kyra/eob2.h
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/sequences_eob1.cpp
    engines/kyra/sequences_eob2.cpp



diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index 17ee920..fc3e874 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -33,7 +33,7 @@ public:
 	CharacterGenerator(EobCoreEngine *vm, Screen_Eob *screen);
 	~CharacterGenerator();
 
-	void start(EobCharacter *characters, uint8 ***faceShapes);
+	bool start(EobCharacter *characters, uint8 ***faceShapes);
 
 private:
 	void init();
@@ -113,8 +113,8 @@ private:
 	Screen_Eob *_screen;
 };
 
-void EobCoreEngine::startCharacterGeneration() {
-	CharacterGenerator(this, _screen).start(_characters, &_faceShapes);
+bool EobCoreEngine::startCharacterGeneration() {
+	return CharacterGenerator(this, _screen).start(_characters, &_faceShapes);
 }
 
 CharacterGenerator::CharacterGenerator(EobCoreEngine *vm, Screen_Eob *screen) : _vm(vm), _screen(screen),
@@ -156,9 +156,9 @@ CharacterGenerator::~CharacterGenerator() {
 	}
 }
 
-void CharacterGenerator::start(EobCharacter *characters, uint8 ***faceShapes) {
+bool CharacterGenerator::start(EobCharacter *characters, uint8 ***faceShapes) {
 	if (!characters && !faceShapes)
-		return;
+		return true;
 
 	_characters = characters;
 	_faceShapes = *faceShapes;
@@ -184,10 +184,15 @@ void CharacterGenerator::start(EobCharacter *characters, uint8 ***faceShapes) {
 		_vm->removeInputTop();
 
 		if (inputFlag) {
-			if (inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT])
+			if (inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT]) {
 				_activeBox ^= 1;
-			else if (inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN])
+			} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN]) {
 				_activeBox ^= 2;
+			} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE]) {
+				// Unlike the original we allow returning to the main menu
+				_vm->sound()->haltTrack();
+				return false;
+			}
 			highlightBoxFrame(-1);
 		}
 
@@ -233,6 +238,7 @@ void CharacterGenerator::start(EobCharacter *characters, uint8 ***faceShapes) {
 	_vm->sound()->playTrack(15);
 
 	*faceShapes = _faceShapes;
+	return true;
 }
 
 void CharacterGenerator::init() {
diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
index 3a6bd28..cdccd65 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -29,6 +29,7 @@ namespace Kyra {
 
 EobEngine::EobEngine(OSystem *system, const GameFlags &flags) : EobCoreEngine(system, flags) {
 	_numSpells = 53;
+	_menuChoiceInit = 4;
 }
 
 EobEngine::~EobEngine() {
diff --git a/engines/kyra/eob1.h b/engines/kyra/eob1.h
index 27a060f..8a959e9 100644
--- a/engines/kyra/eob1.h
+++ b/engines/kyra/eob1.h
@@ -44,6 +44,7 @@ private:
 	// Main Menu
 	int mainMenu();
 	int mainMenuLoop();
+	int _menuChoiceInit;
 
 	// Main loop
 	void startupNew();
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index 06e85a8..de8e90c 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -33,6 +33,7 @@ DarkMoonEngine::DarkMoonEngine(OSystem *system, const GameFlags &flags) : EobCor
 	_shapesIntro = _shapesFinale = 0;
 	_dscDoorType5Offs = 0;
 	_numSpells = 70;
+	_menuChoiceInit = 4;
 }
 
 DarkMoonEngine::~DarkMoonEngine() {
diff --git a/engines/kyra/eob2.h b/engines/kyra/eob2.h
index a36ec0e..3fabe44 100644
--- a/engines/kyra/eob2.h
+++ b/engines/kyra/eob2.h
@@ -60,6 +60,7 @@ private:
 	// Main Menu
 	int mainMenu();
 	int mainMenuLoop();
+	int _menuChoiceInit;
 
 	// Main loop
 	void startupNew();
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index e0fb584..3f9782a 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -350,27 +350,31 @@ Common::Error EobCoreEngine::go() {
 	//initPlayBuffers
 
 	loadItemDefs();
-
 	int action = 0;
 
-	if (_gameToLoad != -1) {
-		if (loadGameState(_gameToLoad).getCode() != Common::kNoError)
-			error("Couldn't load game slot %d on startup", _gameToLoad);
-		_gameToLoad = -1;
-	} else {
-		action = mainMenu();
-	}
-
-	if (action == -1) {
-		// load game
-		_saveLoadMode = -1;
-		startupLoad();
-	} else if (action == -2) {
-		// new game
-		startCharacterGeneration();
-		startupNew();
-	} else if (action == -3) {
-		// transfer party
+	for (bool repeatLoop = true; repeatLoop; repeatLoop ^= true) {
+		action = 0;
+
+		if (_gameToLoad != -1) {
+			if (loadGameState(_gameToLoad).getCode() != Common::kNoError)
+				error("Couldn't load game slot %d on startup", _gameToLoad);
+			_gameToLoad = -1;
+		} else {
+			action = mainMenu();
+		}
+
+		if (action == -1) {
+			// load game
+			_saveLoadMode = -1;
+			startupLoad();
+		} else if (action == -2) {
+			// new game
+			repeatLoop = startCharacterGeneration();
+			if (repeatLoop)
+				startupNew();
+		} else if (action == -3) {
+			// transfer party
+		}
 	}
 
 	if (!shouldQuit() && action > -3) {
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 6632ae3..4ad4ebf 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -302,7 +302,7 @@ protected:
 	//int _runLoopUnk2;
 
 	// Create Party
-	void startCharacterGeneration();
+	bool startCharacterGeneration();
 
 	uint8 **_faceShapes;
 
diff --git a/engines/kyra/sequences_eob1.cpp b/engines/kyra/sequences_eob1.cpp
index 7e15a7a..e835c12 100644
--- a/engines/kyra/sequences_eob1.cpp
+++ b/engines/kyra/sequences_eob1.cpp
@@ -34,7 +34,8 @@
 namespace Kyra {
 
 int EobEngine::mainMenu() {
-	int menuChoice = 4;
+	int menuChoice = _menuChoiceInit;
+	_menuChoiceInit = 0;
 
 	Screen::FontId of = _screen->_currentFont;
 	
diff --git a/engines/kyra/sequences_eob2.cpp b/engines/kyra/sequences_eob2.cpp
index 07dd523..c926eb6 100644
--- a/engines/kyra/sequences_eob2.cpp
+++ b/engines/kyra/sequences_eob2.cpp
@@ -86,7 +86,8 @@ private:
 };
 
 int DarkMoonEngine::mainMenu() {
-	int menuChoice = 4;
+	int menuChoice = _menuChoiceInit;
+	_menuChoiceInit = 0;
 
 	_sound->loadSoundFile("INTRO");
 	Screen::FontId of = _screen->_currentFont;


Commit: 045d08986d3accc3fc7d55d76eb550db01ad7fc7
    https://github.com/scummvm/scummvm/commit/045d08986d3accc3fc7d55d76eb550db01ad7fc7
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:11-08:00

Commit Message:
KYRA: (EOB) - start implementing camp menu

Changed paths:
    engines/kyra/chargen.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui.h
    engines/kyra/gui_eob.cpp
    engines/kyra/gui_eob.h
    engines/kyra/magic_eob.cpp
    engines/kyra/screen_eob.cpp
    engines/kyra/script_eob.cpp
    engines/kyra/staticres_eob.cpp



diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index fc3e874..03ab453 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -319,7 +319,7 @@ void CharacterGenerator::initButton(int index, int x, int y, int w, int h, int k
 	b->width = w;
 	b->height = h;
 	b->keyCode = keyCode;
-	b->keyCode2 = keyCode + 0x100;
+	b->keyCode2 = keyCode | 0x100;
 }
 
 void CharacterGenerator::checkForCompleteParty() {
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 3f9782a..d193bc0 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -55,8 +55,6 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 		_weaponSlotGrid = _blackBoxWideGrid = _lightningColumnShape = 0;
 	_tempIconShape = 0;
 
-	_menuStringsPrefsTemp = 0;
-
 	_monsterDustStrings = 0;
 	_monsterDistAttType10 = 0;
 	_monsterDistAttSfx10 = 0;
@@ -106,6 +104,8 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_color10 = 23;
 	_color11 = 20;
 
+	_menuDefs = 0;
+
 	_exchangeCharacterId = -1;
 	_charExchangeSwap = 0;
 	_configHpBarGraphs = true;
@@ -143,12 +143,6 @@ EobCoreEngine::~EobCoreEngine() {
 	releaseItemsAndDecorationsShapes();
 	releaseTempData();
 
-	if (_menuStringsPrefsTemp) {
-		for (int i = 0; i < 4; i++)
-			delete _menuStringsPrefsTemp[i];
-		delete[] _menuStringsPrefsTemp;
-	}
-
 	if (_faceShapes) {
 		for (int i = 0; i < 44; i++) {
 			if (_characters) {
@@ -207,6 +201,9 @@ EobCoreEngine::~EobCoreEngine() {
 
 	delete _gui;
 	_gui = 0;
+	delete[] _menuDefs;
+	_menuDefs = 0;
+
 	delete _inf;
 	delete _timer;
 	_timer = 0;
@@ -265,12 +262,10 @@ Common::Error EobCoreEngine::init() {
 		return err;
 
 	initButtonData();
+	initMenus();
 	initStaticResource();
 	initSpells();
 
-	_menuStringsPrefsTemp = new char*[4];
-	memset(_menuStringsPrefsTemp, 0, 4 * sizeof(char*));
-
 	_timer = new TimerManager(this, _system);
 	assert(_timer);
 	setupTimers();
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 4ad4ebf..a4fb0d7 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -228,6 +228,23 @@ struct ScriptTimer {
 	uint32 next;
 };
 
+struct EobMenuDef {
+	int8 titleStrId;
+	uint8 dim;
+	uint8 firstButtonStrId;
+	int8 numButtons;
+	int8 titleCol;
+};
+struct EobMenuButtonDef {
+	int8 labelId;
+	int16 x;
+	int8 y;
+	uint8 width;
+	uint8 height;
+	int16 keyCode;
+	int16 flags;
+};
+
 class EobInfProcessor;
 
 class EobCoreEngine : public LolEobBaseEngine {
@@ -258,8 +275,9 @@ protected:
 	void releaseItemsAndDecorationsShapes();
 
 	void initButtonData();
+	void initMenus();
 	void initStaticResource();
-	virtual void initSpells();
+	virtual void initSpells();	
 
 	const uint8 **_largeItemShapes;
 	const uint8 **_smallItemShapes;
@@ -825,6 +843,7 @@ protected:
 	void sparkEffectDefensive(int charIndex);
 	void sparkEffectOffensive();
 	void setSpellEventTimer(int spell, int timerBaseFactor, int timerLength, int timerLevelFactor, int updateExistingTimer);
+	void cleanupCharacterSpellList(int charIndex);
 
 	bool magicObjectHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level);
 
@@ -957,7 +976,8 @@ protected:
 	const uint8 *_magicFlightObjectProperties;
 
 	// Menu
-	char **_menuStringsPrefsTemp;
+	EobMenuDef *_menuDefs;
+	const EobMenuButtonDef *_menuButtonDefs;
 
 	bool _configMouse;
 
diff --git a/engines/kyra/gui.h b/engines/kyra/gui.h
index 04fc9b5..ad0e0d6 100644
--- a/engines/kyra/gui.h
+++ b/engines/kyra/gui.h
@@ -88,6 +88,8 @@ struct Button {
 
 	Callback buttonCallback;
 
+	const void *extButtonDef;
+
 	uint16 arg;
 };
 
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 10eabe9..9baed75 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -24,6 +24,7 @@
 
 #include "kyra/eobcommon.h"
 #include "kyra/gui_eob.h"
+#include "kyra/text_eob.h"
 #include "kyra/timer.h"
 #include "kyra/util.h"
 
@@ -847,25 +848,15 @@ int EobCoreEngine::clickedCamp(Button *button) {
 	}
 
 	_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 14, Screen::CR_NO_P_CHECK);
-	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
 	
-	for (int i = 0; i < 4; i++) {
-		delete _menuStringsPrefsTemp[i];
-		_menuStringsPrefsTemp[i] = new char[strlen(_menuStringsPrefs[i]) + 8];
-	}
-
-	Common::strlcpy(_menuStringsPrefsTemp[0], Common::String::format(_menuStringsPrefs[0], _menuStringsOnOff[_configMusic ? 0 : 1]).c_str(), strlen(_menuStringsPrefs[0]) + 8);
-	Common::strlcpy(_menuStringsPrefsTemp[1], Common::String::format(_menuStringsPrefs[1], _menuStringsOnOff[_configSounds ? 0 : 1]).c_str(), strlen(_menuStringsPrefs[1]) + 8);
-	Common::strlcpy(_menuStringsPrefsTemp[2], Common::String::format(_menuStringsPrefs[2], _menuStringsOnOff[_configHpBarGraphs ? 0 : 1]).c_str(), strlen(_menuStringsPrefs[2]) + 8);
-	Common::strlcpy(_menuStringsPrefsTemp[3], Common::String::format(_menuStringsPrefs[3], _menuStringsOnOff[_configMouse ? 0 : 1]).c_str(), strlen(_menuStringsPrefs[3]) + 8);
+	_gui->runCampMenu();	
 	
-	_screen->setFont(of);
 	_screen->copyRegion(0, 0, 0, 120, 176, 24, 14, 2, Screen::CR_NO_P_CHECK);
 	_screen->setScreenDim(cd);
 	drawScene(0);
 
-	//for (int i = 0; i < 6; i++)
-	//	cleanupCharacterSpellList(i);
+	for (int i = 0; i < 6; i++)
+		cleanupCharacterSpellList(i);
 
 	_screen->setCurPage(0);
 	const ScreenDim *dm = _screen->getScreenDim(10);
@@ -1447,18 +1438,30 @@ GUI_Eob::GUI_Eob(EobCoreEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) {
 	_redrawButtonFunctor = BUTTON_FUNCTOR(GUI, this, &GUI::redrawButtonCallback);
 	_redrawShadedButtonFunctor = BUTTON_FUNCTOR(GUI, this, &GUI::redrawShadedButtonCallback);
 
+	_menuStringsPrefsTemp = new char*[4];
+	memset(_menuStringsPrefsTemp, 0, 4 * sizeof(char*));
+
 	_specialProcessButton = _backupButtonList = 0;
 	_flagsMouseLeft = _flagsMouseRight = _flagsModifier = 0;
 	_backupButtonList = 0;
 	_progress = 0;
 	_prcButtonUnk3 = 1;
 	_cflag = 0xffff;
-
+	
 	_menuLineSpacing = 0;
 	_menuUnk1 = 0;
 	_menuLastInFlags = 0;
 	_menuCur = 0;
 	_menuNumItems = 0;
+	_menuButtons = 0;
+}
+
+GUI_Eob::~GUI_Eob() {
+	if (_menuStringsPrefsTemp) {
+		for (int i = 0; i < 4; i++)
+			delete _menuStringsPrefsTemp[i];
+		delete[] _menuStringsPrefsTemp;
+	}
 }
 
 void GUI_Eob::processButton(Button *button) {
@@ -2028,23 +2031,6 @@ int GUI_Eob::handleMenu(int sd, const char *const *strings, void *b, int32 menuI
 	return result;
 }
 
-void GUI_Eob::initMenuItemsMask(int menuId, int maxItem, int32 menuItemsMask, int unk) {
-	if (menuItemsMask == -1) {
-		_menuNumItems = _screen->getScreenDim(19 + menuId)->h;
-		_menuCur = _screen->getScreenDim(19 + menuId)->unk8;
-		return;
-	}
-
-	_menuNumItems = 0;
-
-	for (int i = 0; i < maxItem; i++) {
-		if (menuItemsMask & (1 << (i + unk)))
-			_menuNumItems++;
-	}
-
-	_menuCur = 0;
-}
-
 int GUI_Eob::getMenuItem(int index, int32 menuItemsMask, int unk) {
 	if (menuItemsMask == -1)
 		return index;
@@ -2074,6 +2060,172 @@ void GUI_Eob::menuFlashSelection(const char *str, int x, int y, int color1, int
 	}
 }
 
+int GUI_Eob::runCampMenu() {
+	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+	
+	Button *highlightButton = 0;
+	Button *prevHighlightButton = 0;
+	
+	int newMenu = 0;
+	int lastMenu = -1;
+	int e = 0;
+	int menuG = 0;
+	int menuH = 0;
+	_menuButtons = 0;
+
+	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
+		if (newMenu == 2)
+			updateOptionsStrings();
+		
+		if (newMenu != -1) {
+			releaseButtons(_menuButtons);
+
+			_vm->_menuDefs[0].titleStrId = newMenu ? 1 : 56;
+			if (newMenu == 2)
+				_vm->_menuDefs[2].titleStrId = 57;
+			else if (newMenu == 1)
+				_vm->_menuDefs[1].titleStrId = 58;
+			
+			_menuButtons = initMenu(newMenu);
+
+			if (newMenu != lastMenu) {
+				highlightButton = _menuButtons;
+				prevHighlightButton = 0;
+			}
+
+			lastMenu = newMenu;
+			newMenu = -1;
+		}
+		
+		int inputFlag = _vm->checkInput(_menuButtons, false, 0) & 0x80ff;
+		_vm->removeInputTop();
+		
+		if (inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE])
+			inputFlag = 0x8007;
+		else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP5] || inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
+			inputFlag = 0x8000 + prevHighlightButton->index;
+		}
+
+		Button *clickedButton = _vm->gui_getButton(_menuButtons, inputFlag & 0x7fff);
+
+		if (clickedButton) {
+			drawMenuButton(prevHighlightButton, false, false, true);
+			drawMenuButton(clickedButton, true, true, true);
+			_screen->updateScreen();
+			_vm->_system->delayMillis(80);
+			drawMenuButton(clickedButton, false, true, true);
+			_screen->updateScreen();
+			highlightButton = clickedButton;
+			prevHighlightButton = 0;
+		}
+
+		if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP3] || inputFlag == _vm->_keyMap[Common::KEYCODE_PAGEDOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP1] || inputFlag == _vm->_keyMap[Common::KEYCODE_END]) {
+			highlightButton = _vm->gui_getButton(_menuButtons, _vm->_menuDefs[lastMenu].firstButtonStrId + _vm->_menuDefs[lastMenu].numButtons);
+			inputFlag = _vm->_keyMap[Common::KEYCODE_UP];
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP7] || inputFlag == _vm->_keyMap[Common::KEYCODE_HOME] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP9] || inputFlag == _vm->_keyMap[Common::KEYCODE_PAGEUP]) {
+			highlightButton = _vm->gui_getButton(_menuButtons, _vm->_menuDefs[lastMenu].firstButtonStrId + 1);
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP8] || inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP2] || inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN]) {
+			if (prevHighlightButton) {
+				int dir = (inputFlag == _vm->_keyMap[Common::KEYCODE_UP]) ? -1 : 1;
+				int s = prevHighlightButton->index + dir;
+				int a = _vm->_menuDefs[lastMenu].firstButtonStrId + 1;
+				int b = a + _vm->_menuDefs[lastMenu].numButtons - 1;
+
+				do {
+					if (s < a)
+						s = b;
+					if (s > b)
+						s = a;
+					if (_vm->_menuButtonDefs[s - 1].flags & 2)
+						break;
+					s += dir;
+				} while(!_vm->shouldQuit());
+
+				highlightButton = _vm->gui_getButton(_menuButtons, s);
+			}
+			
+		} else if (inputFlag > 0x8001 && inputFlag < 0x8010) {
+			switch (inputFlag) {
+			case 0x8001:
+				break;
+			case 0x8002:
+				break;
+			case 0x8003:
+				break;
+			case 0x8004:
+				break;
+			case 0x8005:
+				newMenu = 2;
+				break;
+			case 0x8006:
+				newMenu = 1;
+				break;
+			case 0x8007:
+				if (menuH)
+					displayTextBox(44);
+				// fall through
+			case 0x800c:
+			case 0x800f:
+				if (lastMenu == 1 || lastMenu == 2)
+					newMenu = 0;
+				else if (inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE])
+					newMenu = 0;
+				else
+					runLoop = false;
+				break;
+			case 0x8008:
+				break;
+			case 0x8009:
+				break;
+			case 0x800a:
+				break;
+			case 0x800b:
+				break;
+			case 0x800d:
+				break;
+			case 0x800e:
+				break;
+			default:
+				break;
+			}
+			
+		} else {
+			Common::Point p = _vm->getMousePos();
+			for (Button *b = _menuButtons; b; b = b->nextButton) {
+				if ((b->arg & 2) && _vm->posWithinRect(p.x, p.y, b->x, b->y, b->x + b->width, b->y + b->height))
+					highlightButton = b;
+			}
+		}
+		
+		if (menuG || e) {
+			for (int i = 0; i < 6; i++) {
+				_vm->gui_drawCharPortraitWithStats(i);
+				_vm->cleanupCharacterSpellList(i);
+			}
+		}
+
+		menuG = e = 0;
+
+		if (prevHighlightButton != highlightButton && newMenu == -1 && runLoop) {
+			drawMenuButton(prevHighlightButton, false, false, true);
+			drawMenuButton(highlightButton, false, true, true);
+			_screen->updateScreen();
+			prevHighlightButton = highlightButton;
+		}
+	}
+
+	releaseButtons(_menuButtons);
+	_menuButtons = 0;
+	
+	_screen->setFont(of);
+
+	return 0;
+}
+
+int GUI_Eob::runLoadMenu(int x, int y) {
+	return 0;
+}
+
 int GUI_Eob::getTextInput(char *dest, int x, int y, int destMaxLen, int textColor1, int textColor2, int cursorColor) {
 	uint8 cursorState = 1;
 	char sufx[] = " ";
@@ -2192,6 +2344,185 @@ int GUI_Eob::getTextInput(char *dest, int x, int y, int destMaxLen, int textColo
 	return _keyPressed.keycode == Common::KEYCODE_ESCAPE ? -1 : len;
 }
 
+void GUI_Eob::initMenuItemsMask(int menuId, int maxItem, int32 menuItemsMask, int unk) {
+	if (menuItemsMask == -1) {
+		_menuNumItems = _screen->getScreenDim(19 + menuId)->h;
+		_menuCur = _screen->getScreenDim(19 + menuId)->unk8;
+		return;
+	}
+
+	_menuNumItems = 0;
+
+	for (int i = 0; i < maxItem; i++) {
+		if (menuItemsMask & (1 << (i + unk)))
+			_menuNumItems++;
+	}
+
+	_menuCur = 0;
+}
+
+Button *GUI_Eob::initMenu(int id) {
+	_screen->setCurPage(2);
+
+	EobMenuDef *m = &_vm->_menuDefs[id];
+
+	if (m->dim) {
+		const ScreenDim *dm = _screen->getScreenDim(m->dim);
+		_screen->fillRect(dm->sx << 3, dm->sy, ((dm->sx + dm->w) << 3) - 1, (dm->sy + dm->h) - 1, _vm->_bkgColor_1);
+		_screen->setScreenDim(m->dim);
+		drawMenuButtonBox(dm->sx << 3, dm->sy, dm->w << 3, dm->h, false, false);		
+	}
+
+	_screen->printShadedText(getMenuString(m->titleStrId), 5, 5, m->titleCol, 0);
+
+	Button *buttons = 0;
+	for (int i = 0; i < m->numButtons; i++) {
+		const EobMenuButtonDef *df = &_vm->_menuButtonDefs[m->firstButtonStrId + i];
+		Button *b = new Button;
+		b->index = m->firstButtonStrId + i + 1;		
+		b->data0Val2 = 12;
+		b->data1Val2 = b->data2Val2 = 15;
+		b->data3Val2 = 8;
+		b->flags = 0x1100;
+		b->keyCode = df->keyCode;
+		b->keyCode2 = df->keyCode | 0x100;
+		b->x = df->x;
+		b->y = df->y;
+		b->width = df->width;
+		b->height = df->height;
+		b->extButtonDef = df;
+		b->arg = df->flags;
+
+		drawMenuButton(b, false, false, false);
+		buttons = linkButton(buttons, b);
+	}
+
+	_screen->copyRegion(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, 2, 0, Screen::CR_NO_P_CHECK);
+	_vm->gui_notifyButtonListChanged();
+	_screen->setCurPage(0);
+	_screen->updateScreen();
+
+	return buttons;
+}
+
+void GUI_Eob::drawMenuButton(Button *b, bool clicked, bool highlight, bool noFill) {
+	if (!b)
+		return;
+	
+	EobMenuButtonDef *d = (EobMenuButtonDef*)b->extButtonDef;
+
+	if (d->flags & 1)
+		drawMenuButtonBox(b->x, b->y, b->width, b->height, clicked, noFill);
+
+	if (d->labelId) {
+		const char *s = getMenuString(d->labelId);
+		
+		int xOffs = 4;
+		int yOffs = 3;
+
+		if (d->flags & 4) {
+			xOffs = ((b->width - (strlen(s) << 3)) >> 1) + 1;
+			yOffs = (b->height - 7) >> 1;
+		}
+
+		if (noFill || clicked)
+			_screen->printText(s, b->x + xOffs, b->y + yOffs, highlight ? 6 : 15, 0);
+		else
+			_screen->printShadedText(s, b->x + xOffs, b->y + yOffs, highlight ? 6 : 15, 0);
+	}
+}
+
+void GUI_Eob::drawMenuButtonBox(int x, int y, int w, int h, bool clicked, bool noFill) {
+	uint8 col1 = _vm->_color1_1;
+	uint8 col2 = _vm->_color2_1;
+	
+	if (clicked)
+		col1 = col2 = _vm->_bkgColor_1;
+
+	_vm->gui_drawBox(x, y, w, h, col1, col2, -1);
+	_vm->gui_drawBox(x + 1, y + 1, w - 2, h - 2, _vm->_color1_1, _vm->_color2_1, noFill ? -1 : _vm->_bkgColor_1);
+}
+
+void GUI_Eob::displayTextBox(int id) {
+
+}
+
+void GUI_Eob::updateOptionsStrings() {
+	for (int i = 0; i < 4; i++) {
+		delete _menuStringsPrefsTemp[i];
+		_menuStringsPrefsTemp[i] = new char[strlen(_vm->_menuStringsPrefs[i]) + 8];
+	}
+
+	Common::strlcpy(_menuStringsPrefsTemp[0], Common::String::format(_vm->_menuStringsPrefs[0], _vm->_menuStringsOnOff[_vm->_configMusic ? 0 : 1]).c_str(), strlen(_vm->_menuStringsPrefs[0]) + 8);
+	Common::strlcpy(_menuStringsPrefsTemp[1], Common::String::format(_vm->_menuStringsPrefs[1], _vm->_menuStringsOnOff[_vm->_configSounds ? 0 : 1]).c_str(), strlen(_vm->_menuStringsPrefs[1]) + 8);
+	Common::strlcpy(_menuStringsPrefsTemp[2], Common::String::format(_vm->_menuStringsPrefs[2], _vm->_menuStringsOnOff[_vm->_configHpBarGraphs ? 0 : 1]).c_str(), strlen(_vm->_menuStringsPrefs[2]) + 8);
+	Common::strlcpy(_menuStringsPrefsTemp[3], Common::String::format(_vm->_menuStringsPrefs[3], _vm->_menuStringsOnOff[_vm->_configMouse ? 0 : 1]).c_str(), strlen(_vm->_menuStringsPrefs[3]) + 8);
+}
+
+const char *GUI_Eob::getMenuString(int id) {
+	if (id >= 69)
+		return _vm->_menuStringsTransfer[id - 69];
+	else if (id >= 67)
+		return _vm->_menuStringsDefeat[id - 67];
+	else if (id >= 63)
+		return _vm->_menuStringsSpec[id - 63];
+	else if (id >= 60)
+		return _vm->_menuStringsSpellNo[id - 60];
+	else if (id == 59)
+		return _vm->_menuStringsPoison[0];
+	else if (id >= 56)
+		return _vm->_menuStringsHead[id - 56];
+	else if (id >= 53)
+		return _vm->_menuStringsDrop2[id - 53];
+	else if (id >= 48)
+		return _vm->_menuStringsScribe[id - 48];
+	else if (id == 47)
+		_vm->_menuStringsStarve[0];
+	else if (id == 46)
+		_vm->_menuStringsExit[0];
+	else if (id == 45)
+		_vm->_menuStringsDrop[0];
+	else if (id >= 40)
+		return _vm->_menuStringsRest[id - 40];
+	else if (id >= 23)
+		return _vm->_menuStringsSpells[id - 23];
+	else if (id >= 21)
+		return _vm->_menuStringsOnOff[id - 21];
+	else if (id >= 17)
+		return _menuStringsPrefsTemp[id - 17];
+	else if (id >= 9)
+		return _vm->_menuStringsSaveLoad[id - 9];
+	else if (id >= 1)
+		return _vm->_menuStringsMain[id - 1];
+	return 0;
+}
+
+Button *GUI_Eob::linkButton(Button *list, Button *newbt) {
+	if (!list) {
+		list = newbt;
+		return list;
+	}
+
+	if (!newbt)
+		return list;
+
+	Button *resList = list;
+	while (list->nextButton)
+		list = list->nextButton;
+	list->nextButton = newbt;
+	newbt->nextButton = 0;
+
+	return resList;
+}
+
+void GUI_Eob::releaseButtons(Button *list) {
+	while (list) {
+		Button *n = list->nextButton;
+		delete list;
+		list = n;
+	}
+}
+
 #endif // ENABLE_EOB
 
 }	// End of namespace Kyra
diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h
index 2ad69e7..3eddee5 100644
--- a/engines/kyra/gui_eob.h
+++ b/engines/kyra/gui_eob.h
@@ -39,6 +39,7 @@ class GUI_Eob : public GUI {
 	friend class CharacterGenerator;
 public:
 	GUI_Eob(EobCoreEngine *vm);
+	virtual ~GUI_Eob();
 
 	void initStaticData() {}
 
@@ -49,15 +50,17 @@ public:
 	int redrawShadedButtonCallback(Button *button) { return 0; }
 	int redrawButtonCallback(Button *button) { return 0; }
 
-	// general menu handling (main menu, character generation, ingame menus, etc.)
+	// Non button based menu handling (main menu, character generation)
 	void setupMenu(int sd, int maxItem, const char *const *strings, int32 menuItemsMask, int unk, int lineSpacing);
-	int handleMenu(int sd, const char *const *strings, void *b, int32 menuItemsMask, int unk);
+	int handleMenu(int sd, const char *const *strings, void *b, int32 menuItemsMask, int unk);	
 	int getMenuItem(int index, int32 menuItemsMask, int unk);
 	void menuFlashSelection(const char *str, int x, int y, int color1, int color2, int color3);
 
-	int getTextInput(char *dest, int x, int y, int destMaxLen, int textColor1, int textColor2, int cursorColor);
+	// Button based menus (camp menu, options, save/load)
+	int runCampMenu();
+	int runLoadMenu(int x, int y);
 
-	// int runMenu(Menu &menu);
+	int getTextInput(char *dest, int x, int y, int destMaxLen, int textColor1, int textColor2, int cursorColor);
 
 	// utilities for thumbnail creation
 	void createScreenThumbnail(Graphics::Surface &dst) {}
@@ -73,7 +76,17 @@ private:
 
 	//int getMenuCenterStringX(const char *str, int x1, int x2);
 
-	int getInput();
+	//int getInput();
+	Button *initMenu(int id);
+	
+	void drawMenuButton(Button *b, bool clicked, bool highlight, bool noFill);
+	void drawMenuButtonBox(int x, int y, int w, int h, bool clicked, bool noFill);
+	void displayTextBox(int id);
+	void updateOptionsStrings();
+	const char *getMenuString(int id);
+
+	Button *linkButton(Button *list, Button *newbt);
+	void releaseButtons(Button *list);
 
 	Button *getButtonListData() { return _menuButtons; }
 	Button *getScrollUpButton() { return &_scrollUpButton; }
@@ -89,7 +102,8 @@ private:
 	const char *getMenuItemTitle(const MenuItem &menuItem) { return 0; }
 	const char *getMenuItemLabel(const MenuItem &menuItem) { return 0; }
 
-	Button _menuButtons[10];
+	//Button _menuButtons[10];
+	Button *_menuButtons;
 	Button _scrollUpButton;
 	Button _scrollDownButton;
 	//Menu _mainMenu, _gameOptions, _audioOptions, _choiceMenu, _loadMenu, _saveMenu, _deleteMenu, _savenameMenu, _deathMenu;
@@ -97,6 +111,8 @@ private:
 	//int _menuResult;
 	//char *_saveDescription;
 
+	char **_menuStringsPrefsTemp;
+
 	EobCoreEngine *_vm;
 	Screen_Eob *_screen;
 
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 2c83c26..8b6de92 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -415,6 +415,10 @@ void EobCoreEngine::setSpellEventTimer(int spell, int timerBaseFactor, int timer
 	setCharEventTimer(_activeSpellCaster, countdown, -spell, updateExistingTimer);
 }
 
+void EobCoreEngine::cleanupCharacterSpellList(int charIndex) {
+
+}
+
 bool EobCoreEngine::magicObjectHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level) {
 	int ignoreAttackerId = fo->flags & 0x10;
 	int singleTargetCheckAdjacent = fo->flags & 1;
diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp
index f6b0eaf..d3c2187 100644
--- a/engines/kyra/screen_eob.cpp
+++ b/engines/kyra/screen_eob.cpp
@@ -91,8 +91,9 @@ const ScreenDim *Screen_Eob::getScreenDim(int dim) {
 }
 
 void Screen_Eob::modifyScreenDim(int dim, int x, int y, int w, int h) {
-	delete _customDimTable[dim];
-	_customDimTable[dim] = new ScreenDim;
+	if (!_customDimTable[dim])
+		_customDimTable[dim] = new ScreenDim;
+
 	memcpy(_customDimTable[dim], &_screenDimTable[dim], sizeof(ScreenDim));
 	_customDimTable[dim]->sx = x;
 	_customDimTable[dim]->sy = y;
diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp
index 40656c5..ef3a623 100644
--- a/engines/kyra/script_eob.cpp
+++ b/engines/kyra/script_eob.cpp
@@ -80,7 +80,9 @@ EobInfProcessor::EobInfProcessor(EobCoreEngine *engine, Screen_Eob *screen) : _v
 	_commandMin(engine->game() == GI_EOB1 ? -27 : -31) {
 
 #define Opcode(x) _opcodes.push_back(new InfProc(this, &EobInfProcessor::x))
-#define OpcodeAlt(x, y) if (_vm->game() == GI_EOB1) Opcode(x); else Opcode(y);
+//#define OpcodeAltV(x, y) if (_vm->game() == GI_EOB1) Opcode(x); else Opcode(y);
+//#define OpcodeAlt(x) OpcodeAltV(x##_v1, x##_v2)
+#define OpcodeAlt(x) if (_vm->game() == GI_EOB1) Opcode(x##_v1); else Opcode(x##_v2);
 	Opcode(oeob_setWallType);
 	Opcode(oeob_toggleWallState);
 	Opcode(oeob_openDoor);
@@ -88,7 +90,7 @@ EobInfProcessor::EobInfProcessor(EobCoreEngine *engine, Screen_Eob *screen) : _v
 	Opcode(oeob_replaceMonster);
 	Opcode(oeob_movePartyOrObject);
 	Opcode(oeob_moveInventoryItemToBlock);
-	OpcodeAlt(oeob_printMessage_v1, oeob_printMessage_v2);
+	OpcodeAlt(oeob_printMessage);
 	Opcode(oeob_setFlags);
 	Opcode(oeob_playSoundEffect);
 	Opcode(oeob_removeFlags);
@@ -98,11 +100,11 @@ EobInfProcessor::EobInfProcessor(EobCoreEngine *engine, Screen_Eob *screen) : _v
 	Opcode(oeob_end);
 	Opcode(oeob_popPosAndReturn);
 	Opcode(oeob_pushPosAndJump);
-	OpcodeAlt(oeob_eval_v1, oeob_eval_v2);
+	OpcodeAlt(oeob_eval);
 	Opcode(oeob_deleteItem);
 	Opcode(oeob_loadNewLevelOrMonsters);
 	Opcode(oeob_increasePartyExperience);
-	OpcodeAlt(oeob_createItem_v1, oeob_createItem_v2);
+	OpcodeAlt(oeob_createItem);
 	Opcode(oeob_launchObject);
 	Opcode(oeob_changeDirection);
 	Opcode(oeob_identifyItems);
@@ -112,6 +114,7 @@ EobInfProcessor::EobInfProcessor(EobCoreEngine *engine, Screen_Eob *screen) : _v
 	Opcode(oeob_dialogue);
 	Opcode(oeob_specialEvent);
 #undef Opcode
+//#undef OpcodeAltV
 #undef OpcodeAlt
 
 	_scriptData = 0;
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index da4e675..bf06ba6 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -610,6 +610,64 @@ void EobCoreEngine::initButtonData() {
 	_buttonDefs = buttonDefs;
 }
 
+void EobCoreEngine::initMenus() {
+	static const EobMenuButtonDef buttonDefs[] = {
+		{  2,   12,  20, 158,  14,  20,  3  },
+		{  3,   12,  37, 158,  14,  52,  3  },
+		{  4,   12,  54, 158,  14,  26,  3  },
+		{  5,   12,  71, 158,  14,  32,  3  },
+		{  6,   12,  88, 158,  14,   0,  3  },
+		{  7,   12, 105, 158,  14,  35,  3  },
+		{  8,  128, 122,  40,  14,  19,  7  },
+		{  9,   12,  20, 158,  14,  39,  3  },
+		{  10,  12,  37, 158,  14,  32,  3  },
+		{  11,  12,  54, 158,  14,  33,  3  },
+		{  12,  12,  71, 158,  14,  17,  3  },
+		{  8,  128, 122,  40,  14,  19,  7  },
+		{  18,  12,  20, 158,  14,  32,  3  },
+		{  19,  12,  37, 158,  14,  50,  3  },
+		{  8,  128, 122,  40,  14,  19,  7  },
+		{  8,  128, 122,  40,  14,  19,  5  },
+		{  0,  184,   0,  64,  48, 112,  0  },
+		{  0,  256,   0,  64,  48, 113,  0  },
+		{  0,  184,  56,  64,  48, 114,  0  },
+		{  0,  256,  56,  64,  48, 115,  0  },
+		{  0,  184, 112,  64,  48, 116,  0  },
+		{  0,  256, 112,  64,  48, 117,  0  },
+		{  36,   8, 126,  48,  14,  48,  5  },
+		{  8,  128, 126,  40,  14,  19,  5  },
+		{  0,    0,  50, 168,  72,  61,  0  },
+		{  31,  11,  16,  20,  18,   2,  5  },
+		{  32,  38,  16,  20,  18,   3,  5  },
+		{  33,  65,  16,  20,  18,   4,  5  },
+		{  34,  92,  16,  20,  18,   5,  5  },
+		{  35, 119,  16,  20,  18,   6,  5  },
+		{  60, 146,  16,  20,  18,   7,  5  },
+		{  61, 150,  16,  20,  18,   8,  5  },
+		{  38,  16,  57,  32,  14,  22,  7  },
+		{  39, 128,  57,  32,  14,  51,  7  },
+		{  8,  128, 126,  40,  14,  19,  7  },
+		{  0,    0,  50, 168,  72,  61,  0  }
+	};
+
+	_menuButtonDefs = buttonDefs;
+
+	static const EobMenuDef menuDefs[] = {
+		{  1, 10,  0, 7,  9 },
+		{  1, 10,  7, 5,  9 },
+		{  1, 10, 12, 3,  9 },
+		{  0, 10, 15, 7, 15 },
+		{ 37, 10, 22, 9,  9 },
+		{  0, 11, 32, 2, 15 },
+		{ 48, 10, 34, 2,  9 }
+	};
+
+	delete[] _menuDefs;
+	_menuDefs = new EobMenuDef[ARRAYSIZE(menuDefs)];
+	memcpy(_menuDefs, menuDefs, sizeof(menuDefs));
+}
+
+
 void EobCoreEngine::initSpells() {
 #define mpn magicTimingParaAssign.push_back(0);
 #define mp1n if (_flags.gameID == GI_EOB1) magicTimingParaAssign.push_back(0);


Commit: 97e5036bf0022f1b5e2ce5a9fe3a11d5f3216b50
    https://github.com/scummvm/scummvm/commit/97e5036bf0022f1b5e2ce5a9fe3a11d5f3216b50
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:11-08:00

Commit Message:
KYRA: (EOB) - more work on ingame menus

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    engines/kyra/chargen.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui.cpp
    engines/kyra/gui.h
    engines/kyra/gui_eob.cpp
    engines/kyra/gui_eob.h
    engines/kyra/gui_lok.cpp
    engines/kyra/gui_lok.h
    engines/kyra/gui_lol.cpp
    engines/kyra/gui_lol.h
    engines/kyra/gui_v2.cpp
    engines/kyra/gui_v2.h
    engines/kyra/kyra_hof.h
    engines/kyra/kyra_lok.h
    engines/kyra/kyra_mr.h
    engines/kyra/kyra_v1.cpp
    engines/kyra/kyra_v1.h
    engines/kyra/lol.cpp
    engines/kyra/lol.h
    engines/kyra/loleobbase.h
    engines/kyra/resource.h
    engines/kyra/script_eob.cpp
    engines/kyra/script_eob.h
    engines/kyra/sequences_eob1.cpp
    engines/kyra/sequences_eob2.cpp
    engines/kyra/staticres_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index d28e5b2..96c8787 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -266,6 +266,8 @@ const ExtractFilename extractFilenames[] = {
 	{ kEobBaseMenuStringsMgc, kTypeStringList, true },
 	{ kEobBaseMenuStringsPrefs, kTypeStringList, true },
 	{ kEobBaseMenuStringsRest2, kTypeStringList, true },
+	{ kEobBaseMenuStringsRest3, kTypeStringList, true },
+	{ kEobBaseMenuStringsRest4, kTypeStringList, true },
 	{ kEobBaseMenuStringsDefeat, kTypeStringList, true },
 	{ kEobBaseMenuStringsTransfer, kTypeStringList, true },
 	{ kEobBaseMenuStringsSpec, kTypeStringList, true },
@@ -1342,6 +1344,10 @@ const char *getIdString(const int id) {
 		return "kEobBaseMenuStringsPrefs";
 	case kEobBaseMenuStringsRest2:
 		return "kEobBaseMenuStringsRest2";
+	case kEobBaseMenuStringsRest3:
+		return "kEobBaseMenuStringsRest3";
+	case kEobBaseMenuStringsRest4:
+		return "kEobBaseMenuStringsRest4";
 	case kEobBaseMenuStringsDefeat:
 		return "kEobBaseMenuStringsDefeat";
 	case kEobBaseMenuStringsTransfer:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index e9c2c57..fc57508 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -241,6 +241,8 @@ enum kExtractID {
 	kEobBaseMenuStringsMgc,
 	kEobBaseMenuStringsPrefs,
 	kEobBaseMenuStringsRest2,
+	kEobBaseMenuStringsRest3,
+	kEobBaseMenuStringsRest4,
 	kEobBaseMenuStringsDefeat,
 	kEobBaseMenuStringsTransfer,
 	kEobBaseMenuStringsSpec,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index e99c6a8..423c726 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1092,6 +1092,7 @@ const int eob1FloppyNeed[] = {
 	kEobBaseMenuStringsMgc,
 	kEobBaseMenuStringsPrefs,
 	kEobBaseMenuStringsRest2,
+	kEobBaseMenuStringsRest4,
 	kEobBaseMenuStringsDefeat,
 	
 	kEobBaseCharGuiStringsHp,
@@ -1268,6 +1269,8 @@ const int eob2FloppyNeed[] = {
 	kEobBaseMenuStringsMgc,
 	kEobBaseMenuStringsPrefs,
 	kEobBaseMenuStringsRest2,
+	kEobBaseMenuStringsRest3,
+	kEobBaseMenuStringsRest4,
 	kEobBaseMenuStringsDefeat,
 	kEobBaseMenuStringsTransfer,
 	kEobBaseMenuStringsSpec,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index 811d74b..b8b32bc 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -1629,10 +1629,24 @@ const ExtractEntrySearchData kEobBaseMenuStringsPrefsProvider[] = {
 };
 
 const ExtractEntrySearchData kEobBaseMenuStringsRest2Provider[] = {
-	{ EN_ANY, kPlatformUnknown, { 0x00000076, 0x00002530, { { 0xAD, 0x7A, 0x80, 0x8B, 0x97, 0x65, 0x67, 0xB2, 0x67, 0xE3, 0xF8, 0xDA, 0x0B, 0x9A, 0x61, 0x26 } } } }, // EOB1
-	{ DE_DEU, kPlatformUnknown, { 0x00000082, 0x000029A1, { { 0x02, 0x83, 0xBC, 0x56, 0xB4, 0xFE, 0xF0, 0x03, 0x3D, 0xFD, 0x2C, 0x3B, 0x14, 0x8F, 0x44, 0x1B } } } }, // EOB
-	{ EN_ANY, kPlatformUnknown, { 0x000000A5, 0x000033C9, { { 0xC4, 0x69, 0x00, 0x7B, 0x93, 0x98, 0x0E, 0xD1, 0x94, 0xF8, 0x39, 0x19, 0xBA, 0x53, 0x37, 0x35 } } } }, // EOB2
-	{ DE_DEU, kPlatformUnknown, { 0x000000A4, 0x000033C1, { { 0x3B, 0x3A, 0x01, 0x8F, 0x3F, 0x9E, 0xC2, 0xC7, 0x70, 0xF8, 0x9C, 0x84, 0x6D, 0xFE, 0xC2, 0x40 } } } }, // EOB2
+	{ EN_ANY, kPlatformUnknown, { 0x0000004D, 0x00001744, { { 0x63, 0xA5, 0x6F, 0x09, 0x6F, 0x5E, 0x4B, 0x89, 0xFF, 0x33, 0x63, 0xCB, 0xAA, 0x04, 0x59, 0x63 } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x0000004D, 0x00001769, { { 0x2C, 0xA9, 0x7D, 0x4C, 0xC5, 0x13, 0xE2, 0xEB, 0x89, 0x6C, 0xAE, 0x25, 0xC3, 0x3E, 0x56, 0x7E } } } }, // EOB1
+	{ EN_ANY, kPlatformUnknown, { 0x00000052, 0x000017F6, { { 0x7C, 0x49, 0xFC, 0x89, 0x90, 0x5D, 0xFF, 0x86, 0x86, 0xE9, 0xB2, 0x29, 0x60, 0xB2, 0x22, 0x7F } } } }, // EOB2
+	{ DE_DEU, kPlatformUnknown, { 0x0000004C, 0x000014FF, { { 0x0C, 0x94, 0x6D, 0x5A, 0x42, 0x68, 0xE0, 0xDC, 0xCD, 0xB9, 0x1A, 0x4A, 0xC1, 0xCC, 0xE6, 0x91 } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsRest3Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000002B, 0x00000DF4, { { 0x42, 0x90, 0x49, 0xA7, 0x2E, 0x61, 0x77, 0x7F, 0x9F, 0x53, 0xAD, 0x3C, 0x87, 0xE2, 0x0E, 0x36 } } } }, // EOB2
+	{ DE_DEU, kPlatformUnknown, { 0x00000027, 0x00000D45, { { 0x8D, 0xAB, 0xBF, 0x57, 0xF3, 0x2C, 0x3F, 0x93, 0xBF, 0x33, 0x58, 0x2D, 0x97, 0x78, 0x71, 0x7F } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMenuStringsRest4Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000029, 0x00000DEC, { { 0x1C, 0x86, 0x3D, 0x40, 0x2C, 0x5E, 0xCA, 0xA0, 0xA1, 0xB8, 0x23, 0x42, 0x9C, 0x6B, 0xFA, 0xBB } } } }, // EOB1
+	{ DE_DEU, kPlatformUnknown, { 0x00000034, 0x00001238, { { 0xE9, 0x95, 0x27, 0x79, 0x1C, 0x0D, 0xF5, 0x94, 0x92, 0xFC, 0xCA, 0x22, 0x17, 0xA8, 0x36, 0x96 } } } }, // EOB1
+	{ EN_ANY, kPlatformUnknown, { 0x0000002A, 0x00000DEB, { { 0x0E, 0xD3, 0xC5, 0xA9, 0x8B, 0x06, 0x57, 0xB0, 0x20, 0x1A, 0xEE, 0x42, 0x49, 0x2E, 0xA1, 0x50 } } } }, // EOB2
+	{ DE_DEU, kPlatformUnknown, { 0x00000033, 0x00001189, { { 0x56, 0x1B, 0x6B, 0x00, 0x47, 0xFD, 0x56, 0xD3, 0x12, 0x03, 0x79, 0x7D, 0xFF, 0x83, 0xCF, 0xAA } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
@@ -3378,6 +3392,8 @@ const ExtractEntry extractProviders[] = {
 	{ kEobBaseMenuStringsMgc, kEobBaseMenuStringsMgcProvider },
 	{ kEobBaseMenuStringsPrefs, kEobBaseMenuStringsPrefsProvider },
 	{ kEobBaseMenuStringsRest2, kEobBaseMenuStringsRest2Provider },
+	{ kEobBaseMenuStringsRest3, kEobBaseMenuStringsRest3Provider },
+	{ kEobBaseMenuStringsRest4, kEobBaseMenuStringsRest4Provider },
 	{ kEobBaseMenuStringsDefeat, kEobBaseMenuStringsDefeatProvider },
 	{ kEobBaseMenuStringsTransfer, kEobBaseMenuStringsTransferProvider },
 	{ kEobBaseMenuStringsSpec, kEobBaseMenuStringsSpecProvider },
diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index 03ab453..380cc12 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -42,7 +42,6 @@ private:
 	void checkForCompleteParty();
 	void toggleSpecialButton(int index, int bodyCustom, int pageNum);
 	void processSpecialButton(int index);
-	void highlightBoxFrame(int index);
 	int viewDeleteCharacter();
 	void createPartyMember();
 	int raceSexMenu();
@@ -67,11 +66,8 @@ private:
 	uint8 **_chargenButtonLabels;
 	int _activeBox;
 	int _magicShapesBox;
-	int _updateBoxIndex;
-	int _updateBoxColorIndex;
 	int _updateBoxShapesIndex;
 	int _lastUpdateBoxShapesIndex;
-	uint32 _chargenBoxTimer;
 	uint32 _chargenMagicShapeTimer;
 	int8 _chargenSelectedPortraits[4];
 	int8 _chargenSelectedPortraits2[4];
@@ -95,7 +91,6 @@ private:
 	static const EobChargenButtonDef _chargenButtonDefs[];
 	static const CreatePartyModButton _chargenModButtons[];
 	static const EobRect8 _chargenButtonBodyCoords[];
-	static const EobRect16 _chargenPortraitBoxFrames[];
 	static const int16 _chargenBoxX[];
 	static const int16 _chargenBoxY[];
 	static const int16 _chargenNameFieldX[];
@@ -118,9 +113,8 @@ bool EobCoreEngine::startCharacterGeneration() {
 }
 
 CharacterGenerator::CharacterGenerator(EobCoreEngine *vm, Screen_Eob *screen) : _vm(vm), _screen(screen),
-	_characters(0), _faceShapes(0), _chargenMagicShapes(0), _chargenButtonLabels(0), _updateBoxIndex(-1),
-	_chargenBoxTimer(0), _chargenMagicShapeTimer(0), _updateBoxColorIndex(0), _updateBoxShapesIndex(0),
-	_lastUpdateBoxShapesIndex(0), _magicShapesBox(6), _activeBox(0) {
+	_characters(0), _faceShapes(0), _chargenMagicShapes(0), _chargenButtonLabels(0), _chargenMagicShapeTimer(0),
+	_updateBoxShapesIndex(0), _lastUpdateBoxShapesIndex(0), _magicShapesBox(6), _activeBox(0) {
 
 	_chargenStatStrings = _vm->_chargenStatStrings;
 	_chargenRaceSexStrings = _vm->_chargenRaceSexStrings;
@@ -178,7 +172,7 @@ bool CharacterGenerator::start(EobCharacter *characters, uint8 ***faceShapes) {
 	_activeBox = 0;
 
 	for (bool loop = true; loop && (!_vm->shouldQuit()); ) {
-		highlightBoxFrame(_activeBox + 6);
+		_vm->_gui->highLightBoxFrame(_activeBox + 6);
 		_vm->sound()->process();
 		int inputFlag = _vm->checkInput(_vm->_activeButtons, false, 0);
 		_vm->removeInputTop();
@@ -193,7 +187,7 @@ bool CharacterGenerator::start(EobCharacter *characters, uint8 ***faceShapes) {
 				_vm->sound()->haltTrack();
 				return false;
 			}
-			highlightBoxFrame(-1);
+			_vm->_gui->highLightBoxFrame(-1);
 		}
 
 		if (inputFlag & 0x8000) {
@@ -207,7 +201,7 @@ bool CharacterGenerator::start(EobCharacter *characters, uint8 ***faceShapes) {
 		}
 
 		if (inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP5]) {
-			highlightBoxFrame(-1);
+			_vm->_gui->highLightBoxFrame(-1);
 			if (_characters[_activeBox].name[0]) {
 				int b = _activeBox;
 				if (viewDeleteCharacter())
@@ -381,50 +375,16 @@ void CharacterGenerator::processSpecialButton(int index) {
 	toggleSpecialButton(index, 0, 0);
 }
 
-void CharacterGenerator::highlightBoxFrame(int index) {
-	static const uint8 colorTable[] = { 0x0F, 0xB0, 0xB2, 0xB4, 0xB6,
-		0xB8, 0xBA, 0xBC, 0x0C, 0xBC, 0xBA, 0xB8, 0xB6, 0xB4, 0xB2, 0xB0, 0x00
-	};
-
-	if (_updateBoxIndex == index) {
-		if (_updateBoxIndex == -1)
-			return;
-
-		if (_vm->_system->getMillis() <= _chargenBoxTimer)
-			return;
-
-		if (!colorTable[_updateBoxColorIndex])
-			_updateBoxColorIndex = 0;
-
-		const EobRect16 *r = &_chargenPortraitBoxFrames[_updateBoxIndex];
-		_screen->drawBox(r->x1, r->y1, r->x2, r->y2, colorTable[_updateBoxColorIndex++]);
-		_screen->updateScreen();
-
-		_chargenBoxTimer = _vm->_system->getMillis() + _vm->_tickLength;
-
-	} else {
-		if (_updateBoxIndex != -1) {
-			const EobRect16 *r = &_chargenPortraitBoxFrames[_updateBoxIndex];
-			_screen->drawBox(r->x1, r->y1, r->x2, r->y2, 12);
-			_screen->updateScreen();
-		}
-
-		_updateBoxColorIndex = 0;
-		_updateBoxIndex = index;
-		_chargenBoxTimer = _vm->_system->getMillis();
-	}
-}
-
 int CharacterGenerator::viewDeleteCharacter() {
 	initButtonsFromList(0, 7);
 	_vm->removeInputTop();
 
-	highlightBoxFrame(-1);
+	_vm->_gui->highLightBoxFrame(-1);
 	printStats(_activeBox, 2);
 
 	int res = 0;
 	for (bool loop = true; loop && _characters[_activeBox].name[0] && !_vm->shouldQuit(); ) {
-		highlightBoxFrame(_activeBox + 6);
+		_vm->_gui->highLightBoxFrame(_activeBox + 6);
 		_vm->sound()->process();
 
 		int inputFlag = _vm->checkInput(_vm->_activeButtons, false, 0);
@@ -463,14 +423,14 @@ int CharacterGenerator::viewDeleteCharacter() {
 		}
 
 		if (loop == false)
-			highlightBoxFrame(-1);
+			_vm->_gui->highLightBoxFrame(-1);
 
 		if (!_characters[cbx].name[0])
 			loop = false;
 
 		if (cbx != _activeBox) {
 			_activeBox = cbx;
-			highlightBoxFrame(-1);
+			_vm->_gui->highLightBoxFrame(-1);
 			if (loop)
 				printStats(_activeBox, 2);
 		}
@@ -480,8 +440,8 @@ int CharacterGenerator::viewDeleteCharacter() {
 }
 
 void CharacterGenerator::createPartyMember() {
-	_screen->setScreenDim(2);
-	_chargenBoxTimer = 0;
+	_screen->setScreenDim(2);	
+	assert(_vm->_gui);
 
 	for (int i = 0; i != 3 && !_vm->shouldQuit(); i++) {
 		bool bck = false;
@@ -528,11 +488,11 @@ int CharacterGenerator::raceSexMenu() {
 	_screen->printShadedText(_chargenStrings2[8], 147, 67, 9, 0);
 	_vm->removeInputTop();
 
-	_vm->_gui->setupMenu(1, 0, _chargenRaceSexStrings, -1, 0, 0);
+	_vm->_gui->simpleMenu_setup(1, 0, _chargenRaceSexStrings, -1, 0, 0);
 	int16 res = -1;
 
 	while (res == -1 && !_vm->shouldQuit()) {
-		res = _vm->_gui->handleMenu(1, _chargenRaceSexStrings, 0, -1, 0);
+		res = _vm->_gui->simpleMenu_process(1, _chargenRaceSexStrings, 0, -1, 0);
 		updateMagicShapes();
 	}
 
@@ -557,7 +517,7 @@ int CharacterGenerator::classMenu(int raceSex) {
 	toggleSpecialButton(5, 0, 0);
 
 	itemsMask &=_classMenuMasks[raceSex / 2];
-	_vm->_gui->setupMenu(2, 15, _chargenClassStrings, itemsMask, 0, 0);
+	_vm->_gui->simpleMenu_setup(2, 15, _chargenClassStrings, itemsMask, 0, 0);
 
 	_vm->_mouseX = _vm->_mouseY = 0;
 	int16 res = -1;
@@ -576,7 +536,7 @@ int CharacterGenerator::classMenu(int raceSex) {
 			else
 				_vm->removeInputTop();
 		} else {
-			res = _vm->_gui->handleMenu(2, _chargenClassStrings, 0, itemsMask, 0);
+			res = _vm->_gui->simpleMenu_process(2, _chargenClassStrings, 0, itemsMask, 0);
 		}
 	}
 
@@ -606,7 +566,7 @@ int CharacterGenerator::alignmentMenu(int cClass) {
 	toggleSpecialButton(5, 0, 0);
 
 	itemsMask &=_alignmentMenuMasks[cClass];
-	_vm->_gui->setupMenu(3, 9, _chargenAlignmentStrings, itemsMask, 0, 0);
+	_vm->_gui->simpleMenu_setup(3, 9, _chargenAlignmentStrings, itemsMask, 0, 0);
 
 	_vm->_mouseX = _vm->_mouseY = 0;
 	int16 res = -1;
@@ -625,7 +585,7 @@ int CharacterGenerator::alignmentMenu(int cClass) {
 			else
 				_vm->removeInputTop();
 		} else {
-			res = _vm->_gui->handleMenu(3, _chargenAlignmentStrings, 0, itemsMask, 0);
+			res = _vm->_gui->simpleMenu_process(3, _chargenAlignmentStrings, 0, itemsMask, 0);
 		}
 	}
 
@@ -793,8 +753,8 @@ void CharacterGenerator::statsAndFacesMenu() {
 		}
 	}
 
-	highlightBoxFrame(6 + _activeBox);
-	highlightBoxFrame(-1);
+	_vm->_gui->highLightBoxFrame(6 + _activeBox);
+	_vm->_gui->highLightBoxFrame(-1);
 }
 
 void CharacterGenerator::faceSelectMenu() {
@@ -809,7 +769,7 @@ void CharacterGenerator::faceSelectMenu() {
 	printStats(_activeBox, 4);
 	toggleSpecialButton(12, 0, 0);
 	toggleSpecialButton(13, 0, 0);
-	highlightBoxFrame(-1);
+	_vm->_gui->highLightBoxFrame(-1);
 
 	shp = getNextFreeFaceShape(shp, charSex, 1, _chargenSelectedPortraits);
 
@@ -833,7 +793,7 @@ void CharacterGenerator::faceSelectMenu() {
 			in = _vm->checkInput(_vm->_activeButtons, false, 0);
 			_vm->removeInputTop();
 
-			highlightBoxFrame(box + 10);
+			_vm->_gui->highLightBoxFrame(box + 10);
 
 			if (in == 0x8002 || in == _vm->_keyMap[Common::KEYCODE_RIGHT]) {
 				processSpecialButton(13);
@@ -853,7 +813,7 @@ void CharacterGenerator::faceSelectMenu() {
 			}
 		}
 
-		highlightBoxFrame(-1);
+		_vm->_gui->highLightBoxFrame(-1);
 
 		if (in == 1)
 			shp = getNextFreeFaceShape(shp - 1, charSex, -1, _chargenSelectedPortraits);
@@ -864,7 +824,7 @@ void CharacterGenerator::faceSelectMenu() {
 	}
 
 	if (!_vm->shouldQuit()) {
-		highlightBoxFrame(-1);
+		_vm->_gui->highLightBoxFrame(-1);
 		updateMagicShapes();
 
 		_chargenSelectedPortraits[_activeBox] = sp[res];
@@ -899,7 +859,7 @@ int CharacterGenerator::getNextFreeFaceShape(int shpIndex, int charSex, int step
 }
 
 void CharacterGenerator::processFaceMenuSelection(int index) {
-	highlightBoxFrame(-1);
+	_vm->_gui->highLightBoxFrame(-1);
 	if (index <= 48)
 		_screen->drawShape(0, _characters[_activeBox].faceShape, _chargenBoxX[_activeBox], _chargenBoxY[_activeBox] + 1, 0);
 	else
@@ -1127,15 +1087,15 @@ int CharacterGenerator::getMaxHp(int cclass, int constitution, int level1, int l
 	int res = 0;
 	constitution = _vm->getClassAndConstHitpointsModifier(cclass, constitution);
 
-	int m = _vm->getClassHpIncreaseType(cclass, 0);
+	int m = _vm->getCharacterClassType(cclass, 0);
 	if (m != -1)
 		res = _vm->getModifiedHpLimits(m, constitution, level1, false);
 
-	m = _vm->getClassHpIncreaseType(cclass, 1);
+	m = _vm->getCharacterClassType(cclass, 1);
 	if (m != -1)
 		res += _vm->getModifiedHpLimits(m, constitution, level2, false);
 
-	m = _vm->getClassHpIncreaseType(cclass, 2);
+	m = _vm->getCharacterClassType(cclass, 2);
 	if (m != -1)
 		res += _vm->getModifiedHpLimits(m, constitution, level3, false);
 
@@ -1148,15 +1108,15 @@ int CharacterGenerator::getMinHp(int cclass, int constitution, int level1, int l
 	int res = 0;
 	constitution = _vm->getClassAndConstHitpointsModifier(cclass, constitution);
 
-	int m = _vm->getClassHpIncreaseType(cclass, 0);
+	int m = _vm->getCharacterClassType(cclass, 0);
 	if (m != -1)
 		res = _vm->getModifiedHpLimits(m, constitution, level1, true);
 
-	m = _vm->getClassHpIncreaseType(cclass, 1);
+	m = _vm->getCharacterClassType(cclass, 1);
 	if (m != -1)
 		res += _vm->getModifiedHpLimits(m, constitution, level2, true);
 
-	m = _vm->getClassHpIncreaseType(cclass, 2);
+	m = _vm->getCharacterClassType(cclass, 2);
 	if (m != -1)
 		res += _vm->getModifiedHpLimits(m, constitution, level3, true);
 
@@ -1443,7 +1403,7 @@ const EobRect8 CharacterGenerator::_chargenButtonBodyCoords[] = {
 	{ 0x14, 0x90, 0x0B, 0x10 }
 };
 
-const EobRect16 CharacterGenerator::_chargenPortraitBoxFrames[] = {
+const EobRect16 GUI_Eob::_highLightBoxFrames[] = {
 	{ 0x00B7, 0x0001, 0x00F7, 0x0034 },
 	{ 0x00FF, 0x0001, 0x013F, 0x0034 },
 	{ 0x00B7, 0x0035, 0x00F7, 0x0068 },
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index d193bc0..83a57cd 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -48,6 +48,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_saveLoadMode = 0;
 	_updateHandItemCursor = false;
 	_configMouse = true;
+	_resting = false;
 
 	_largeItemShapes = _smallItemShapes = _thrownItemShapes = _spellShapes = _firebeamShapes = _itemIconShapes =
 		_wallOfForceShapes = _teleporterShapes = _sparkShapes = _compassShapes = 0;
@@ -257,6 +258,8 @@ Common::Error EobCoreEngine::init() {
 	_screen->loadFont(Screen::FID_6_FNT, "FONT6.FNT");
 	_screen->loadFont(Screen::FID_8_FNT, "FONT8.FNT");
 
+	readSettings();
+
 	Common::Error err = LolEobBaseEngine::init();
 	if (err.getCode() != Common::kNoError)
 		return err;
@@ -365,7 +368,7 @@ Common::Error EobCoreEngine::go() {
 		} else if (action == -2) {
 			// new game
 			repeatLoop = startCharacterGeneration();
-			if (repeatLoop)
+			if (repeatLoop && !shouldQuit())
 				startupNew();
 		} else if (action == -3) {
 			// transfer party
@@ -382,6 +385,34 @@ Common::Error EobCoreEngine::go() {
 	return Common::kNoError;
 }
 
+void EobCoreEngine::registerDefaultSettings() {
+	KyraEngine_v1::registerDefaultSettings();
+	ConfMan.registerDefault("hpbargraphs", true);
+}
+
+void EobCoreEngine::readSettings() {
+	_configHpBarGraphs = ConfMan.getBool("hpbargraphs");
+	_configSounds = ConfMan.getBool("sfx_mute") ? 0 : 1;
+	_configMusic = _configSounds ? 1 : 0;
+
+	if (_sound)
+		_sound->enableSFX(_configSounds);
+}
+
+void EobCoreEngine::writeSettings() {
+	ConfMan.setBool("hpbargraphs", _configHpBarGraphs);
+	ConfMan.setBool("sfx_mute", _configSounds == 0);
+
+	if (_sound) {
+		if (!_configSounds)
+			_sound->beginFadeOut();
+		_sound->enableMusic(_configSounds ? 1 : 0);
+		_sound->enableSFX(_configSounds);
+	}
+
+	ConfMan.flushToDisk();
+}
+
 void EobCoreEngine::startupNew() {
 	gui_setPlayFieldButtons();
 	_screen->_curPage = 0;
@@ -659,7 +690,7 @@ int EobCoreEngine::generateCharacterHitpointsByLevel(int charIndex, int levelInd
 		if (!(levelIndex & (1 << i)))
 			continue;
 
-		int d = getClassHpIncreaseType(c->cClass, i);
+		int d = getCharacterClassType(c->cClass, i);
 
 		if (c->level[i] <= _hpIncrPerLevel[6 + i])
 			h += rollDice(1, (d >= 0) ? _hpIncrPerLevel[d] : 0);
@@ -686,8 +717,8 @@ int EobCoreEngine::getClassAndConstHitpointsModifier(int cclass, int constitutio
 	return 2;
 }
 
-int EobCoreEngine::getClassHpIncreaseType(int cclass, int levelIndex) {
-	return _classHpIncreaseType[cclass * 3 + levelIndex];
+int EobCoreEngine::getCharacterClassType(int cclass, int levelIndex) {
+	return _characterClassType[cclass * 3 + levelIndex];
 }
 
 int EobCoreEngine::getModifiedHpLimits(int hpModifier, int constModifier, int level, bool mode) {
@@ -867,11 +898,11 @@ int EobCoreEngine::getCharacterClericPaladinLevel(int index) {
 	if (index == -1)
 		return (_currentLevel < 7) ? 5 : 9;
 
-	int l = getLevelIndexForHpIncType(2, _characters[index].cClass);
+	int l = getCharacterLevelIndex(2, _characters[index].cClass);
 	if (l > -1)
 		return _characters[index].level[l];
 
-	l = getLevelIndexForHpIncType(4, _characters[index].cClass);
+	l = getCharacterLevelIndex(4, _characters[index].cClass);
 	if (l > -1) {
 		if (_characters[index].level[l] > 8)
 			return _characters[index].level[l] - 8;
@@ -887,18 +918,18 @@ int EobCoreEngine::getCharacterMageLevel(int index) {
 	if (index == -1)
 		return (_currentLevel < 7) ? 5 : 9;
 
-	int l = getLevelIndexForHpIncType(1, _characters[index].cClass);
+	int l = getCharacterLevelIndex(1, _characters[index].cClass);
 	return (l > -1) ? _characters[index].level[l] : 1;
 }
 
-int EobCoreEngine::getLevelIndexForHpIncType(int hpIncType, int cClass) {
-	if (getClassHpIncreaseType(cClass, 0) == hpIncType)
+int EobCoreEngine::getCharacterLevelIndex(int type, int cClass) {
+	if (getCharacterClassType(cClass, 0) == type)
 		return 0;
 
-	if (getClassHpIncreaseType(cClass, 1) == hpIncType)
+	if (getCharacterClassType(cClass, 1) == type)
 		return 1;
 
-	if (getClassHpIncreaseType(cClass, 2) == hpIncType)
+	if (getCharacterClassType(cClass, 2) == type)
 		return 2;
 
 	return -1;
@@ -1020,6 +1051,20 @@ int EobCoreEngine::prepareForNewPartyMember(int16 itemType, int16 itemValue) {
 	return 1;
 }
 
+void EobCoreEngine::dropCharacter(int charIndex) {
+	if (!testCharacter(charIndex, 1))
+		return;
+
+	removeCharacterFromParty(charIndex);
+	
+	if (charIndex < 5)
+		exchangeCharacters(charIndex, testCharacter(5, 1) ? 5 : 4);
+
+	gui_processCharPortraitClick(0);
+	gui_setPlayFieldButtons();
+	setupCharacterTimers();
+}
+
 void EobCoreEngine::removeCharacterFromParty(int charIndex) {
 	EobCharacter *c = &_characters[charIndex];
 	c->flags = 0;
@@ -1043,6 +1088,13 @@ void EobCoreEngine::removeCharacterFromParty(int charIndex) {
 	setupCharacterTimers();
 }
 
+void EobCoreEngine::exchangeCharacters(int charIndex1, int charIndex2) {
+	EobCharacter temp;
+	memcpy(&temp, &_characters[charIndex1], sizeof(EobCharacter));
+	memcpy(&_characters[charIndex1], &_characters[charIndex2], sizeof(EobCharacter));
+	memcpy(&_characters[charIndex2], &temp, sizeof(EobCharacter));
+}
+
 void EobCoreEngine::increasePartyExperience(int16 points) {
 	int cnt = 0;
 	for (int i = 0; i < 6; i++) {
@@ -1067,7 +1119,7 @@ void EobCoreEngine::increaseCharacterExperience(int charIndex, int32 points) {
 	points /= _numLevelsPerClass[cl];
 
 	for (int i = 0; i < 3; i++) {
-		if (getClassHpIncreaseType(cl, i) == -1)
+		if (getCharacterClassType(cl, i) == -1)
 			continue;
 		_characters[charIndex].experience[i] += points;
 
@@ -1081,7 +1133,7 @@ void EobCoreEngine::increaseCharacterExperience(int charIndex, int32 points) {
 }
 
 uint32 EobCoreEngine::getRequiredExperience(int cClass, int levelIndex, int level) {
-	cClass = getClassHpIncreaseType(cClass, levelIndex);
+	cClass = getCharacterClassType(cClass, levelIndex);
 	if (cClass == -1)
 		return 0xffffffff;
 
@@ -1275,6 +1327,28 @@ void EobCoreEngine::displayParchment(int id) {
 	restoreAfterDialogueSequence();
 }
 
+bool EobCoreEngine::restParty() {
+	if (_inf->preventRest()) {
+		assert(_menuStringsRest3[0]);
+		displayRestWarning(_menuStringsRest3[0]);
+		return true;
+	}
+
+	return true;
+}
+
+void EobCoreEngine::displayRestWarning(const char *str) {
+	int od = _screen->curDimIndex();
+	_screen->setScreenDim(7);
+	Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+	_screen->setCurPage(0);
+
+	_txt->printMessage(Common::String::format("\r%s\r", str).c_str());
+
+	_screen->setFont(of);
+	_screen->setScreenDim(od);
+}
+
 void EobCoreEngine::useSlotWeapon(int charIndex, int slotIndex, int item) {
 	EobCharacter *c = &_characters[charIndex];
 	int tp = item ? _items[item].type : 0;
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index a4fb0d7..ede25dd 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -55,13 +55,6 @@ struct EobRect8 {
 	uint8 h;
 };
 
-struct EobRect16 {
-	int16 x1;
-	int16 y1;
-	uint16 x2;
-	uint16 y2;
-};
-
 struct EobChargenButtonDef {
 	uint8 x;
 	uint8 y;
@@ -258,7 +251,7 @@ public:
 	virtual ~EobCoreEngine();
 
 	Screen *screen() { return _screen; }
-	GUI *gui() const { return _gui; }
+	GUI_v1 *gui() const { return _gui; }
 
 protected:
 	// Startup
@@ -270,14 +263,18 @@ protected:
 	virtual void seq_playFinale() = 0;
 	bool _playFinale;
 
-	//Init
+	//Init, config
 	void loadItemsAndDecorationsShapes();
 	void releaseItemsAndDecorationsShapes();
 
 	void initButtonData();
 	void initMenus();
 	void initStaticResource();
-	virtual void initSpells();	
+	virtual void initSpells();
+
+	void registerDefaultSettings();
+	void readSettings();
+	void writeSettings();
 
 	const uint8 **_largeItemShapes;
 	const uint8 **_smallItemShapes;
@@ -324,7 +321,7 @@ protected:
 
 	uint8 **_faceShapes;
 
-	static const int8 _classHpIncreaseType[];
+	static const int8 _characterClassType[];
 	static const uint8 _hpIncrPerLevel[];
 	static const uint8 _numLevelsPerClass[];
 	static const int16 _hpConstModifiers[];
@@ -361,7 +358,7 @@ protected:
 	int getDexterityArmorClassModifier(int dexterity);
 	int generateCharacterHitpointsByLevel(int charIndex, int levelIndex);
 	int getClassAndConstHitpointsModifier(int cclass, int constitution);
-	int getClassHpIncreaseType(int cclass, int levelIndex);
+	int getCharacterClassType(int cclass, int levelIndex);
 	int getModifiedHpLimits(int hpModifier, int constModifier, int level, bool mode);
 	Common::String getCharStrength(int str, int strExt);
 	int testCharacter(int index, int flags);
@@ -371,7 +368,7 @@ protected:
 	int validateWeaponSlotItem(int index, int slot);
 	int getCharacterClericPaladinLevel(int index);
 	int getCharacterMageLevel(int index);
-	int getLevelIndexForHpIncType(int unk, int cClass);
+	int getCharacterLevelIndex(int type, int cClass);
 
 	int countCharactersWithSpecificItems(int16 itemType, int16 itemValue);
 	int checkCharacterInventoryForItem(int character, int16 itemType, int16 itemValue);
@@ -382,7 +379,9 @@ protected:
 	void initNpc(int npcIndex);
 	int npcJoinDialogue(int npcIndex, int queryJoinTextId, int confirmJoinTextId, int noJoinTextId);
 	int prepareForNewPartyMember(int16 itemType, int16 itemValue);
+	void dropCharacter(int charIndex);
 	void removeCharacterFromParty(int charIndex);
+	void exchangeCharacters(int charIndex1, int charIndex2);
 
 	void increasePartyExperience(int16 points);
 	void increaseCharacterExperience(int charIndex, int32 points);
@@ -773,6 +772,9 @@ protected:
 	void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false);
 	void displayParchment(int id);
 
+	bool restParty();
+	void displayRestWarning(const char *str);
+
 	virtual void drawLightningColumn() {}
 	virtual int resurrectionSelectDialogue() { return -1; }
 	virtual int charSelectDialogue() { return -1; }
@@ -786,6 +788,7 @@ protected:
 	void releaseMonsterTempData(LevelTempData *tmp);
 
 	int _saveLoadMode;
+	bool _resting;
 
 	Screen_Eob *_screen;
 	GUI_Eob *_gui;
@@ -996,6 +999,8 @@ protected:
 	const char *const *_menuStringsMgc;
 	const char *const *_menuStringsPrefs;
 	const char *const *_menuStringsRest2;
+	const char *const *_menuStringsRest3;
+	const char *const *_menuStringsRest4;
 	const char *const *_menuStringsDefeat;
 
 	const char *const *_menuStringsTransfer;
diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp
index 27f09b6..3a5d798 100644
--- a/engines/kyra/gui.cpp
+++ b/engines/kyra/gui.cpp
@@ -30,15 +30,15 @@
 
 namespace Kyra {
 
-GUI::GUI(KyraEngine_v1 *kyra)
+GUI_v1::GUI_v1(KyraEngine_v1 *kyra)
 	: _vm(kyra), _screen(kyra->screen()), _text(kyra->text()) {
 	_menuButtonList = 0;
 
-	_redrawButtonFunctor = BUTTON_FUNCTOR(GUI, this, &GUI::redrawButtonCallback);
-	_redrawShadedButtonFunctor = BUTTON_FUNCTOR(GUI, this, &GUI::redrawShadedButtonCallback);
+	_redrawButtonFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::redrawButtonCallback);
+	_redrawShadedButtonFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::redrawShadedButtonCallback);
 }
 
-Button *GUI::addButtonToList(Button *list, Button *newButton) {
+Button *GUI_v1::addButtonToList(Button *list, Button *newButton) {
 	if (!newButton)
 		return list;
 
@@ -56,7 +56,7 @@ Button *GUI::addButtonToList(Button *list, Button *newButton) {
 	return list;
 }
 
-void GUI::initMenuLayout(Menu &menu) {
+void GUI_v1::initMenuLayout(Menu &menu) {
 	if (menu.x == -1)
 		menu.x = (320 - menu.width) >> 1;
 	if (menu.y == -1)
@@ -68,7 +68,7 @@ void GUI::initMenuLayout(Menu &menu) {
 	}
 }
 
-void GUI::initMenu(Menu &menu) {
+void GUI_v1::initMenu(Menu &menu) {
 	_menuButtonList = 0;
 
 	_screen->hideMouse();
@@ -197,7 +197,7 @@ void GUI::initMenu(Menu &menu) {
 	_screen->updateScreen();
 }
 
-void GUI::processHighlights(Menu &menu) {
+void GUI_v1::processHighlights(Menu &menu) {
 	int x1, y1, x2, y2;
 	Common::Point p = _vm->getMousePos();
 	int mouseX = p.x;
@@ -242,7 +242,7 @@ void GUI::processHighlights(Menu &menu) {
 	_screen->updateScreen();
 }
 
-void GUI::redrawText(const Menu &menu) {
+void GUI_v1::redrawText(const Menu &menu) {
 	int textX;
 	int i = menu.highlightedItem;
 
@@ -271,7 +271,7 @@ void GUI::redrawText(const Menu &menu) {
 	}
 }
 
-void GUI::redrawHighlight(const Menu &menu) {
+void GUI_v1::redrawHighlight(const Menu &menu) {
 	int textX;
 	int i = menu.highlightedItem;
 
@@ -301,12 +301,12 @@ void GUI::redrawHighlight(const Menu &menu) {
 	}
 }
 
-void GUI::updateAllMenuButtons() {
+void GUI_v1::updateAllMenuButtons() {
 	for (Button *cur = _menuButtonList; cur; cur = cur->nextButton)
 		updateMenuButton(cur);
 }
 
-void GUI::updateMenuButton(Button *button) {
+void GUI_v1::updateMenuButton(Button *button) {
 	if (!_displayMenu)
 		return;
 
@@ -316,7 +316,7 @@ void GUI::updateMenuButton(Button *button) {
 	_screen->showMouse();
 }
 
-void GUI::updateButton(Button *button) {
+void GUI_v1::updateButton(Button *button) {
 	if (!button || (button->flags & 8))
 		return;
 
@@ -337,7 +337,7 @@ void GUI::updateButton(Button *button) {
 	processButton(button);
 }
 
-int GUI::redrawButtonCallback(Button *button) {
+int GUI_v1::redrawButtonCallback(Button *button) {
 	if (!_displayMenu)
 		return 0;
 
@@ -351,7 +351,7 @@ int GUI::redrawButtonCallback(Button *button) {
 	return 0;
 }
 
-int GUI::redrawShadedButtonCallback(Button *button) {
+int GUI_v1::redrawShadedButtonCallback(Button *button) {
 	if (!_displayMenu)
 		return 0;
 
@@ -365,7 +365,7 @@ int GUI::redrawShadedButtonCallback(Button *button) {
 	return 0;
 }
 
-void GUI::updateSaveList(bool excludeQuickSaves) {
+void GUI_v1::updateSaveList(bool excludeQuickSaves) {
 	Common::String pattern = _vm->_targetName + ".???";
 	Common::StringArray saveFileList = _vm->_saveFileMan->listSavefiles(pattern);
 	_saveSlots.clear();
@@ -391,13 +391,13 @@ void GUI::updateSaveList(bool excludeQuickSaves) {
 	sortSaveSlots();
 }
 
-void GUI::sortSaveSlots() {
+void GUI_v1::sortSaveSlots() {
 	Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Less<int>());
 	if (_saveSlots.size() > 2)
 		Common::sort(_saveSlots.begin()+1, _saveSlots.end(), Common::Greater<int>());
 }
 
-int GUI::getNextSavegameSlot() {
+int GUI_v1::getNextSavegameSlot() {
 	Common::InSaveFile *in;
 
 	int start = _vm->game() == GI_LOL ? 0 : 1;
@@ -412,7 +412,7 @@ int GUI::getNextSavegameSlot() {
 	return 0;
 }
 
-void GUI::checkTextfieldInput() {
+void GUI_v1::checkTextfieldInput() {
 	Common::Event event;
 
 	uint32 now = _vm->_system->getMillis();
@@ -461,11 +461,11 @@ void GUI::checkTextfieldInput() {
 	_vm->_system->delayMillis(3);
 }
 
-void GUI::printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2) {
+void GUI_v1::printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2) {
 	_text->printText(str, x, y, c0, c1, c2);
 }
 
-int GUI::getMenuCenterStringX(const char *str, int x1, int x2) {
+int GUI_v1::getMenuCenterStringX(const char *str, int x1, int x2) {
 	return _text->getCenterStringX(str, x1, x2);
 }
 
diff --git a/engines/kyra/gui.h b/engines/kyra/gui.h
index ad0e0d6..597f088 100644
--- a/engines/kyra/gui.h
+++ b/engines/kyra/gui.h
@@ -146,10 +146,10 @@ struct Menu {
 class Screen;
 class TextDisplayer;
 
-class GUI {
+class GUI_v1 {
 public:
-	GUI(KyraEngine_v1 *vm);
-	virtual ~GUI() {}
+	GUI_v1(KyraEngine_v1 *vm);
+	virtual ~GUI_v1() {}
 
 	// button specific
 	virtual Button *addButtonToList(Button *list, Button *newButton);
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 9baed75..4d5a1bf 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -151,7 +151,7 @@ void EobCoreEngine::gui_drawPlayField(int pageNum) {
 	int cp = _screen->setCurPage(2);
 	gui_drawCompass(true);
 
-	if (pageNum && !_sceneDrawPage1)
+	if (pageNum && !_sceneDrawPage2)
 		drawScene(0);
 
 	_screen->setCurPage(cp);
@@ -280,7 +280,7 @@ void EobCoreEngine::gui_drawCharPortraitWithStats(int index) {
 			_screen->printText(Common::String::format("%d", c->armorClass).c_str(), 275, 124, 15, _color6);
 
 			for (int i = 0; i < 3; i++) {
-				int t = getClassHpIncreaseType(c->cClass, i);
+				int t = getCharacterClassType(c->cClass, i);
 				if (t == -1)
 					continue;
 
@@ -862,8 +862,8 @@ int EobCoreEngine::clickedCamp(Button *button) {
 	const ScreenDim *dm = _screen->getScreenDim(10);
 	_screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK);	
 	
-	//if (displayInv)
-	//	_screen->loadEobCpsFileToPage("INVENT", 0, 5, 3, 2);
+	/*if (reloadInv)
+		_screen->loadEobCpsFileToPage("INVENT", 0, 5, 3, 2);*/
 	
 	_screen->updateScreen();
 
@@ -948,11 +948,7 @@ int EobCoreEngine::clickedCharNameLabelRight(Button *button) {
 	} else {
 		int d = _exchangeCharacterId;
 		_exchangeCharacterId = -1;
-
-		EobCharacter temp;
-		memcpy(&temp, &_characters[d], sizeof(EobCharacter));
-		memcpy(&_characters[d], &_characters[button->arg], sizeof(EobCharacter));
-		memcpy(&_characters[button->arg], &temp, sizeof(EobCharacter));
+		exchangeCharacters(d, button->arg);
 
 		_timer->disable(0);
 		gui_drawCharPortraitWithStats(d);
@@ -1432,11 +1428,11 @@ void EobCoreEngine::gui_processInventorySlotClick(int slot) {
 	}
 }
 
-GUI_Eob::GUI_Eob(EobCoreEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) {
+GUI_Eob::GUI_Eob(EobCoreEngine *vm) : GUI_v1(vm), _vm(vm), _screen(vm->_screen) {
 	_scrollUpFunctor = _scrollDownFunctor = BUTTON_FUNCTOR(GUI_Eob, this, 0);
 
-	_redrawButtonFunctor = BUTTON_FUNCTOR(GUI, this, &GUI::redrawButtonCallback);
-	_redrawShadedButtonFunctor = BUTTON_FUNCTOR(GUI, this, &GUI::redrawShadedButtonCallback);
+	_redrawButtonFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::redrawButtonCallback);
+	_redrawShadedButtonFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::redrawShadedButtonCallback);
 
 	_menuStringsPrefsTemp = new char*[4];
 	memset(_menuStringsPrefsTemp, 0, 4 * sizeof(char*));
@@ -1453,7 +1449,12 @@ GUI_Eob::GUI_Eob(EobCoreEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) {
 	_menuLastInFlags = 0;
 	_menuCur = 0;
 	_menuNumItems = 0;
-	_menuButtons = 0;
+
+	_charSelectRedraw = false;
+	
+	_updateBoxIndex = -1;
+	_highLightBoxTimer = 0;
+	_updateBoxColorIndex = 0;
 }
 
 GUI_Eob::~GUI_Eob() {
@@ -1950,17 +1951,17 @@ int GUI_Eob::processButtonList(Kyra::Button *buttonList, uint16 inputFlags, int8
 	return result;
 }
 
-void GUI_Eob::setupMenu(int sd, int maxItem, const char *const *strings, int32 menuItemsMask, int unk, int lineSpacing) {
-	initMenuItemsMask(sd, maxItem, menuItemsMask, unk);
+void GUI_Eob::simpleMenu_setup(int sd, int maxItem, const char *const *strings, int32 menuItemsMask, int unk, int lineSpacing) {
+	simpleMenu_initMenuItemsMask(sd, maxItem, menuItemsMask, unk);
 
 	const ScreenDim *dm = _screen->getScreenDim(19 + sd);
 	int x = (_screen->_curDim->sx + dm->sx) << 3;
 	int y = _screen->_curDim->sy + dm->sy;
 
-	int v = getMenuItem(_menuCur, menuItemsMask, unk);
+	int v = simpleMenu_getMenuItem(_menuCur, menuItemsMask, unk);
 
 	for (int i = 0; i < _menuNumItems; i++) {
-		int item = getMenuItem(i, menuItemsMask, unk);
+		int item = simpleMenu_getMenuItem(i, menuItemsMask, unk);
 		int ty = y + i * (lineSpacing + _screen->getFontHeight());
 		_screen->printShadedText(strings[item], x, ty, dm->unkA, 0);
 		if (item == v)
@@ -1974,7 +1975,7 @@ void GUI_Eob::setupMenu(int sd, int maxItem, const char *const *strings, int32 m
 	_vm->removeInputTop();
 }
 
-int GUI_Eob::handleMenu(int sd, const char *const *strings, void *b, int32 menuItemsMask, int unk) {
+int GUI_Eob::simpleMenu_process(int sd, const char *const *strings, void *b, int32 menuItemsMask, int unk) {
 	const ScreenDim *dm = _screen->getScreenDim(19 + sd);
 	int h = _menuNumItems - 1;
 	int currentItem = _menuCur % _menuNumItems;
@@ -2016,14 +2017,14 @@ int GUI_Eob::handleMenu(int sd, const char *const *strings, void *b, int32 menuI
 	}
 
 	if (newItem != currentItem) {
-		_screen->printText(strings[getMenuItem(currentItem, menuItemsMask, unk)], x, y + currentItem * lineH , dm->unkA, 0);
-		_screen->printText(strings[getMenuItem(newItem,  menuItemsMask, unk)], x, y + newItem * lineH , dm->unkC, 0);
+		_screen->printText(strings[simpleMenu_getMenuItem(currentItem, menuItemsMask, unk)], x, y + currentItem * lineH , dm->unkA, 0);
+		_screen->printText(strings[simpleMenu_getMenuItem(newItem,  menuItemsMask, unk)], x, y + newItem * lineH , dm->unkC, 0);
 		_screen->updateScreen();
 	}
 
 	if (result != -1) {
-		result = getMenuItem(result, menuItemsMask, unk);
-		menuFlashSelection(strings[result], x, y + newItem * lineH, dm->unkA, dm->unkC, 0);
+		result = simpleMenu_getMenuItem(result, menuItemsMask, unk);
+		simpleMenu_flashSelection(strings[result], x, y + newItem * lineH, dm->unkA, dm->unkC, 0);
 	}
 
 	_menuCur = newItem;
@@ -2031,7 +2032,7 @@ int GUI_Eob::handleMenu(int sd, const char *const *strings, void *b, int32 menuI
 	return result;
 }
 
-int GUI_Eob::getMenuItem(int index, int32 menuItemsMask, int unk) {
+int GUI_Eob::simpleMenu_getMenuItem(int index, int32 menuItemsMask, int unk) {
 	if (menuItemsMask == -1)
 		return index;
 
@@ -2049,7 +2050,7 @@ int GUI_Eob::getMenuItem(int index, int32 menuItemsMask, int unk) {
 	return res;
 }
 
-void GUI_Eob::menuFlashSelection(const char *str, int x, int y, int color1, int color2, int color3) {
+void GUI_Eob::simpleMenu_flashSelection(const char *str, int x, int y, int color1, int color2, int color3) {
 	for (int i = 0; i < 3; i++) {
 		_screen->printText(str, x, y, color2, color3);
 		_screen->updateScreen();
@@ -2060,7 +2061,7 @@ void GUI_Eob::menuFlashSelection(const char *str, int x, int y, int color1, int
 	}
 }
 
-int GUI_Eob::runCampMenu() {
+void GUI_Eob::runCampMenu() {
 	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
 	
 	Button *highlightButton = 0;
@@ -2068,17 +2069,18 @@ int GUI_Eob::runCampMenu() {
 	
 	int newMenu = 0;
 	int lastMenu = -1;
-	int e = 0;
-	int menuG = 0;
-	int menuH = 0;
-	_menuButtons = 0;
+	bool redrawPortraits = false;
+	bool res = false;
+	_charSelectRedraw = false;
+	_vm->_resting = false;
+	Button *buttonList = 0;
 
 	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
 		if (newMenu == 2)
 			updateOptionsStrings();
 		
 		if (newMenu != -1) {
-			releaseButtons(_menuButtons);
+			releaseButtons(buttonList);
 
 			_vm->_menuDefs[0].titleStrId = newMenu ? 1 : 56;
 			if (newMenu == 2)
@@ -2086,10 +2088,10 @@ int GUI_Eob::runCampMenu() {
 			else if (newMenu == 1)
 				_vm->_menuDefs[1].titleStrId = 58;
 			
-			_menuButtons = initMenu(newMenu);
+			buttonList = initMenu(newMenu);
 
 			if (newMenu != lastMenu) {
-				highlightButton = _menuButtons;
+				highlightButton = buttonList;
 				prevHighlightButton = 0;
 			}
 
@@ -2097,7 +2099,7 @@ int GUI_Eob::runCampMenu() {
 			newMenu = -1;
 		}
 		
-		int inputFlag = _vm->checkInput(_menuButtons, false, 0) & 0x80ff;
+		int inputFlag = _vm->checkInput(buttonList, false, 0) & 0x80ff;
 		_vm->removeInputTop();
 		
 		if (inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE])
@@ -2106,7 +2108,7 @@ int GUI_Eob::runCampMenu() {
 			inputFlag = 0x8000 + prevHighlightButton->index;
 		}
 
-		Button *clickedButton = _vm->gui_getButton(_menuButtons, inputFlag & 0x7fff);
+		Button *clickedButton = _vm->gui_getButton(buttonList, inputFlag & 0x7fff);
 
 		if (clickedButton) {
 			drawMenuButton(prevHighlightButton, false, false, true);
@@ -2120,10 +2122,10 @@ int GUI_Eob::runCampMenu() {
 		}
 
 		if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP3] || inputFlag == _vm->_keyMap[Common::KEYCODE_PAGEDOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP1] || inputFlag == _vm->_keyMap[Common::KEYCODE_END]) {
-			highlightButton = _vm->gui_getButton(_menuButtons, _vm->_menuDefs[lastMenu].firstButtonStrId + _vm->_menuDefs[lastMenu].numButtons);
+			highlightButton = _vm->gui_getButton(buttonList, _vm->_menuDefs[lastMenu].firstButtonStrId + _vm->_menuDefs[lastMenu].numButtons);
 			inputFlag = _vm->_keyMap[Common::KEYCODE_UP];
 		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP7] || inputFlag == _vm->_keyMap[Common::KEYCODE_HOME] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP9] || inputFlag == _vm->_keyMap[Common::KEYCODE_PAGEUP]) {
-			highlightButton = _vm->gui_getButton(_menuButtons, _vm->_menuDefs[lastMenu].firstButtonStrId + 1);
+			highlightButton = _vm->gui_getButton(buttonList, _vm->_menuDefs[lastMenu].firstButtonStrId + 1);
 		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP8] || inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP2] || inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN]) {
 			if (prevHighlightButton) {
 				int dir = (inputFlag == _vm->_keyMap[Common::KEYCODE_UP]) ? -1 : 1;
@@ -2141,29 +2143,50 @@ int GUI_Eob::runCampMenu() {
 					s += dir;
 				} while(!_vm->shouldQuit());
 
-				highlightButton = _vm->gui_getButton(_menuButtons, s);
+				highlightButton = _vm->gui_getButton(buttonList, s);
 			}
 			
-		} else if (inputFlag > 0x8001 && inputFlag < 0x8010) {
+		} else if (inputFlag > 0x8000 && inputFlag < 0x8010) {
+			int i = 0;
+			int cnt = 0;
+
 			switch (inputFlag) {
 			case 0x8001:
+				if (_vm->restParty())
+					runLoop = false;
+				else
+					_vm->_resting = false;
+				redrawPortraits = true;
 				break;
+
 			case 0x8002:
+				runMemorizePrayMenu(selectCharacterDialogue(23), 0);
+				newMenu = 0;
 				break;
+
 			case 0x8003:
+				runMemorizePrayMenu(selectCharacterDialogue(26), 1);
+				newMenu = 0;
 				break;
+
 			case 0x8004:
+				scribeScrollDialogue();
+				newMenu = 0;
 				break;
+
 			case 0x8005:
 				newMenu = 2;
 				break;
+
 			case 0x8006:
 				newMenu = 1;
 				break;
+
 			case 0x8007:
-				if (menuH)
+				if (_vm->_resting)
 					displayTextBox(44);
 				// fall through
+
 			case 0x800c:
 			case 0x800f:
 				if (lastMenu == 1 || lastMenu == 2)
@@ -2173,38 +2196,74 @@ int GUI_Eob::runCampMenu() {
 				else
 					runLoop = false;
 				break;
+
 			case 0x8008:
+				// load
 				break;
+
 			case 0x8009:
+				// save
 				break;
+
 			case 0x800a:
+				for (; i < 6; i++) {
+					if (_vm->testCharacter(i, 1))
+						cnt++;
+				}
+
+				if (cnt > 4) {
+					_vm->dropCharacter(selectCharacterDialogue(53));
+					_vm->gui_drawPlayField(0);
+					res = true;
+					_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 14, Screen::CR_NO_P_CHECK);
+					_screen->setFont(Screen::FID_6_FNT);
+					_vm->gui_drawAllCharPortraitsWithStats();
+					_screen->setFont(Screen::FID_8_FNT);
+				} else {
+					displayTextBox(45);
+				}
+
+				newMenu = 0;
 				break;
+
 			case 0x800b:
+				if (confirmDialogue(46))
+					_vm->quitGame();
+				newMenu = 0;
 				break;
+
 			case 0x800d:
+				_vm->_configSounds ^= true;
+				_vm->_configMusic = _vm->_configSounds ? 1 : 0;
+				newMenu = 2;
 				break;
+
 			case 0x800e:
+				_vm->_configHpBarGraphs ^= true;
+				newMenu = 2;
+				redrawPortraits = true;
 				break;
+
 			default:
 				break;
 			}
 			
 		} else {
 			Common::Point p = _vm->getMousePos();
-			for (Button *b = _menuButtons; b; b = b->nextButton) {
+			for (Button *b = buttonList; b; b = b->nextButton) {
 				if ((b->arg & 2) && _vm->posWithinRect(p.x, p.y, b->x, b->y, b->x + b->width, b->y + b->height))
 					highlightButton = b;
 			}
 		}
 		
-		if (menuG || e) {
+		if (_charSelectRedraw || redrawPortraits) {
 			for (int i = 0; i < 6; i++) {
 				_vm->gui_drawCharPortraitWithStats(i);
 				_vm->cleanupCharacterSpellList(i);
 			}
 		}
 
-		menuG = e = 0;
+		_charSelectRedraw = redrawPortraits = false;
 
 		if (prevHighlightButton != highlightButton && newMenu == -1 && runLoop) {
 			drawMenuButton(prevHighlightButton, false, false, true);
@@ -2214,18 +2273,51 @@ int GUI_Eob::runCampMenu() {
 		}
 	}
 
-	releaseButtons(_menuButtons);
-	_menuButtons = 0;
+	releaseButtons(buttonList);
+	
+	_vm->writeSettings();
 	
 	_screen->setFont(of);
-
-	return 0;
 }
 
 int GUI_Eob::runLoadMenu(int x, int y) {
 	return 0;
 }
 
+void GUI_Eob::highLightBoxFrame(int box) {
+	static const uint8 colorTable[] = { 0x0F, 0xB0, 0xB2, 0xB4, 0xB6,
+		0xB8, 0xBA, 0xBC, 0x0C, 0xBC, 0xBA, 0xB8, 0xB6, 0xB4, 0xB2, 0xB0, 0x00
+	};
+
+	if (_updateBoxIndex == box) {
+		if (_updateBoxIndex == -1)
+			return;
+
+		if (_vm->_system->getMillis() <= _highLightBoxTimer)
+			return;
+
+		if (!colorTable[_updateBoxColorIndex])
+			_updateBoxColorIndex = 0;
+
+		const EobRect16 *r = &_highLightBoxFrames[_updateBoxIndex];
+		_screen->drawBox(r->x1, r->y1, r->x2, r->y2, colorTable[_updateBoxColorIndex++]);
+		_screen->updateScreen();
+
+		_highLightBoxTimer = _vm->_system->getMillis() + _vm->_tickLength;
+
+	} else {
+		if (_updateBoxIndex != -1) {
+			const EobRect16 *r = &_highLightBoxFrames[_updateBoxIndex];
+			_screen->drawBox(r->x1, r->y1, r->x2, r->y2, 12);
+			_screen->updateScreen();
+		}
+
+		_updateBoxColorIndex = 0;
+		_updateBoxIndex = box;
+		_highLightBoxTimer = _vm->_system->getMillis();
+	}
+}
+
 int GUI_Eob::getTextInput(char *dest, int x, int y, int destMaxLen, int textColor1, int textColor2, int cursorColor) {
 	uint8 cursorState = 1;
 	char sufx[] = " ";
@@ -2344,7 +2436,7 @@ int GUI_Eob::getTextInput(char *dest, int x, int y, int destMaxLen, int textColo
 	return _keyPressed.keycode == Common::KEYCODE_ESCAPE ? -1 : len;
 }
 
-void GUI_Eob::initMenuItemsMask(int menuId, int maxItem, int32 menuItemsMask, int unk) {
+void GUI_Eob::simpleMenu_initMenuItemsMask(int menuId, int maxItem, int32 menuItemsMask, int unk) {
 	if (menuItemsMask == -1) {
 		_menuNumItems = _screen->getScreenDim(19 + menuId)->h;
 		_menuCur = _screen->getScreenDim(19 + menuId)->unk8;
@@ -2361,6 +2453,253 @@ void GUI_Eob::initMenuItemsMask(int menuId, int maxItem, int32 menuItemsMask, in
 	_menuCur = 0;
 }
 
+void GUI_Eob::runSaveMenu() {
+
+}
+
+void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
+
+}
+
+void GUI_Eob::scribeScrollDialogue() {
+
+}
+
+bool GUI_Eob::confirmDialogue(int id) {
+	int od = _screen->curDimIndex();
+	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+
+	Button *buttonList = initMenu(5);
+	
+	_screen->printShadedText(getMenuString(id), (_screen->_curDim->sx + 1) << 3, _screen->_curDim->sy + 4, 15, 0);
+
+	int newHighlight = 0;
+	int lastHighlight = -1;
+	bool result = false;
+
+	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
+		if (newHighlight != lastHighlight) {
+			if (lastHighlight != -1)
+				drawMenuButton(_vm->gui_getButton(buttonList, lastHighlight + 33), false, false, true);
+			drawMenuButton(_vm->gui_getButton(buttonList, newHighlight + 33), false, true, true);
+			_screen->updateScreen();
+			lastHighlight = newHighlight;
+		}
+		
+		int inputFlag = _vm->checkInput(buttonList, false, 0) & 0x80ff;
+		_vm->removeInputTop();
+
+		if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP5] || inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
+			result = lastHighlight ? false : true;
+			inputFlag = 0x8021 + lastHighlight;
+			runLoop = false;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP6] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT]) {
+			newHighlight ^= 1;
+		} else if (inputFlag == 0x8021) {
+			result = true;
+			runLoop = false;
+		} else if (inputFlag == 0x8022) {
+			result = false;
+			runLoop = false;
+		} else {
+			Common::Point p = _vm->getMousePos();
+			for (Button *b = buttonList; b; b = b->nextButton) {
+				if ((b->arg & 2) && _vm->posWithinRect(p.x, p.y, b->x, b->y, b->x + b->width, b->y + b->height))
+					newHighlight = b->index - 33;
+			}
+		}
+
+		if (!runLoop) {
+			Button *b = _vm->gui_getButton(buttonList, lastHighlight + 33);
+			drawMenuButton(b, true, true, true);
+			_screen->updateScreen();
+			_vm->_system->delayMillis(80);
+			drawMenuButton(b, false, true, true);
+			_screen->updateScreen();
+		}
+	}
+
+	releaseButtons(buttonList);
+
+	_screen->setFont(of);
+	_screen->setScreenDim(od);
+
+	return result;
+}
+
+int GUI_Eob::selectCharacterDialogue(int id) {
+	uint8 flags = (id == 26) ? 0x14 : 0x02;
+	_vm->removeInputTop();
+
+	_charSelectRedraw = false;	
+	bool abort = false;
+	int count = 0;
+	int result = -1;
+	int found[6];
+
+	for (int i = 0; i < 6; i++) {
+		found[i] = -1;
+		
+		if (!_vm->testCharacter(i, 1))
+			continue;
+		
+		if (!(_vm->_classModifierFlags[_vm->_characters[i].cClass] & flags) && (id != 53))
+			continue;
+		
+		if (id != 53 && (!_vm->_characters[i].food || !_vm->testCharacter(i, 4))) {
+			abort = true;
+		} else {
+			found[i] = 0;
+			result = i;
+			count++;
+		} 
+	}
+
+	if (!count) {
+		int eid = 0;
+		if (id == 23)
+			eid = abort ? 28 : 72;
+		else if (id == 26)
+			eid = abort ? 27 : 73;
+		else if (id == 49)
+			eid = 52;
+
+		displayTextBox(eid);
+		return -1;
+	}
+
+	static const uint16 selX[] = { 184, 256, 184, 256, 184, 256 };
+	static const uint8 selY[] = { 2, 2, 54, 54, 106, 106};
+
+	for (int i = 0; i < 6; i++) {
+		if (found[i] != -1 || !_vm->testCharacter(i, 1))
+			continue;
+
+		_screen->drawShape(0, _vm->_blackBoxSmallGrid, selX[i], selY[i], 0);
+		_screen->drawShape(0, _vm->_blackBoxSmallGrid, selX[i] + 16, selY[i], 0);
+		_screen->drawShape(0, _vm->_blackBoxSmallGrid, selX[i] + 32, selY[i], 0);
+		_screen->drawShape(0, _vm->_blackBoxSmallGrid, selX[i] + 48, selY[i], 0);
+		_charSelectRedraw = true;
+	}
+
+	if (count == 1) {		
+		int l = _vm->getCharacterLevelIndex(4, _vm->_characters[result].cClass);
+
+		if (l == -1)
+			return result;
+
+		if (_vm->_characters[result].level[l] > 8)
+			return result;
+
+		displayTextBox(24);
+		return -1;
+	}
+
+	_vm->_menuDefs[3].titleStrId = id;
+	Button *buttonList = initMenu(3);
+
+	result = -2;
+	int hlCur = -1;
+	Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+
+	while (result == -2 && !_vm->shouldQuit()) {
+		int inputFlag = _vm->checkInput(buttonList, false, 0);
+		_vm->removeInputTop();
+		
+		highLightBoxFrame(hlCur);
+
+		if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP8] || inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_a] || inputFlag == _vm->_keyMap[Common::KEYCODE_w]) {
+			highLightBoxFrame(-1);
+			_vm->gui_drawCharPortraitWithStats(hlCur--);
+			if (hlCur < 0)
+				hlCur = 5;
+			while (found[hlCur]) {
+				if (--hlCur < 0)
+					hlCur = 5;
+			}
+
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP6] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP2] || inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_z] || inputFlag == _vm->_keyMap[Common::KEYCODE_s]) {
+			highLightBoxFrame(-1);
+			_vm->gui_drawCharPortraitWithStats(hlCur++);
+			if (hlCur == 6)
+				hlCur = 0;
+			while (found[hlCur]) {
+				if (++hlCur == 6)
+					hlCur = 0;
+			}
+
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP5] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
+			if (found >= 0)
+				result = hlCur;
+
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE] || inputFlag == 0x8010) {
+			_screen->setFont(Screen::FID_8_FNT);
+			drawMenuButton(buttonList, true, true, true);
+			_screen->updateScreen();
+			_vm->_system->delayMillis(80);
+			drawMenuButton(buttonList, false, false, true);
+			_screen->updateScreen();
+			_screen->setFont(Screen::FID_6_FNT);
+			result = -1;
+
+		} else if (inputFlag > 0x8010 && inputFlag < 0x8017) {
+			result = inputFlag - 0x8011;
+			if (found[result])
+				result = -2;
+		}
+	}
+
+	highLightBoxFrame(-1);
+	if (hlCur >= 0)
+		_vm->gui_drawCharPortraitWithStats(hlCur);
+
+	_screen->setFont(Screen::FID_8_FNT);
+
+	if (result != -1 && id != 53) {
+		if (flags == 0x14) {
+			if (_vm->_classModifierFlags[_vm->_characters[result].cClass] & 0x10 && _vm->_characters[result].level[0] < 9) {
+				displayTextBox(24);
+				result = -1;
+			}
+		} else {
+			if (_vm->checkCharacterInventoryForItem(result, 29, -1) == -1) {
+				displayTextBox(25);
+				result = -1;
+			}
+		}
+	}
+
+	releaseButtons(buttonList);
+	_screen->setFont(of);
+
+	return result;
+}
+
+void GUI_Eob::displayTextBox(int id) {
+	int op = _screen->setCurPage(2);
+	int od = _screen->curDimIndex();
+	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+	_screen->setClearScreenDim(11);
+	const ScreenDim *dm = _screen->getScreenDim(11);
+
+	drawMenuButtonBox(dm->sx << 3, dm->sy, dm->w << 3, dm->h, false, false);
+	_screen->printShadedText(getMenuString(id), (dm->sx << 3) + 5, dm->sy + 5, 15, 0);
+	_screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+
+	for (uint32 timeOut = _vm->_system->getMillis() + 1440; _vm->_system->getMillis() < timeOut && !_vm->shouldQuit(); ) {
+	 	int in = _vm->checkInput(0, false, 0);
+		_vm->removeInputTop();
+		if (in && !(in & 0x800))
+			break;
+		_vm->_system->delayMillis(4);
+	}
+
+	_screen->setCurPage(op);
+	_screen->setFont(of);
+	_screen->setScreenDim(od);
+}
+
 Button *GUI_Eob::initMenu(int id) {
 	_screen->setCurPage(2);
 
@@ -2443,10 +2782,6 @@ void GUI_Eob::drawMenuButtonBox(int x, int y, int w, int h, bool clicked, bool n
 	_vm->gui_drawBox(x + 1, y + 1, w - 2, h - 2, _vm->_color1_1, _vm->_color2_1, noFill ? -1 : _vm->_bkgColor_1);
 }
 
-void GUI_Eob::displayTextBox(int id) {
-
-}
-
 void GUI_Eob::updateOptionsStrings() {
 	for (int i = 0; i < 4; i++) {
 		delete _menuStringsPrefsTemp[i];
@@ -2460,6 +2795,8 @@ void GUI_Eob::updateOptionsStrings() {
 }
 
 const char *GUI_Eob::getMenuString(int id) {
+	static const char empty[] = "";
+
 	if (id >= 69)
 		return _vm->_menuStringsTransfer[id - 69];
 	else if (id >= 67)
@@ -2477,11 +2814,11 @@ const char *GUI_Eob::getMenuString(int id) {
 	else if (id >= 48)
 		return _vm->_menuStringsScribe[id - 48];
 	else if (id == 47)
-		_vm->_menuStringsStarve[0];
+		return _vm->_menuStringsStarve[0];
 	else if (id == 46)
-		_vm->_menuStringsExit[0];
+		return _vm->_menuStringsExit[0];
 	else if (id == 45)
-		_vm->_menuStringsDrop[0];
+		return _vm->_menuStringsDrop[0];
 	else if (id >= 40)
 		return _vm->_menuStringsRest[id - 40];
 	else if (id >= 23)
@@ -2494,7 +2831,7 @@ const char *GUI_Eob::getMenuString(int id) {
 		return _vm->_menuStringsSaveLoad[id - 9];
 	else if (id >= 1)
 		return _vm->_menuStringsMain[id - 1];
-	return 0;
+	return empty;
 }
 
 Button *GUI_Eob::linkButton(Button *list, Button *newbt) {
diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h
index 3eddee5..64f1c19 100644
--- a/engines/kyra/gui_eob.h
+++ b/engines/kyra/gui_eob.h
@@ -31,10 +31,17 @@
 
 namespace Kyra {
 
+struct EobRect16 {
+	int16 x1;
+	int16 y1;
+	uint16 x2;
+	uint16 y2;
+};
+
 class DarkMoonEngine;
 class Screen_Eob;
 
-class GUI_Eob : public GUI {
+class GUI_Eob : public GUI_v1 {
 	friend class EobCoreEngine;
 	friend class CharacterGenerator;
 public:
@@ -47,69 +54,49 @@ public:
 	void processButton(Button *button);
 	int processButtonList(Button *buttonList, uint16 inputFlags, int8 mouseWheel);
 
-	int redrawShadedButtonCallback(Button *button) { return 0; }
-	int redrawButtonCallback(Button *button) { return 0; }
-
 	// Non button based menu handling (main menu, character generation)
-	void setupMenu(int sd, int maxItem, const char *const *strings, int32 menuItemsMask, int unk, int lineSpacing);
-	int handleMenu(int sd, const char *const *strings, void *b, int32 menuItemsMask, int unk);	
-	int getMenuItem(int index, int32 menuItemsMask, int unk);
-	void menuFlashSelection(const char *str, int x, int y, int color1, int color2, int color3);
+	void simpleMenu_setup(int sd, int maxItem, const char *const *strings, int32 menuItemsMask, int unk, int lineSpacing);
+	int simpleMenu_process(int sd, const char *const *strings, void *b, int32 menuItemsMask, int unk);	
 
 	// Button based menus (camp menu, options, save/load)
-	int runCampMenu();
+	void runCampMenu();
 	int runLoadMenu(int x, int y);
 
+	void highLightBoxFrame(int box);
+
 	int getTextInput(char *dest, int x, int y, int destMaxLen, int textColor1, int textColor2, int cursorColor);
 
 	// utilities for thumbnail creation
 	void createScreenThumbnail(Graphics::Surface &dst) {}
 
-private:
-	void initMenuItemsMask(int menuId, int maxItem, int32 menuItemsMask, int unk);
-
-	//void backupPage0();
-	//void restorePage0();
+	// unused
+	int redrawShadedButtonCallback(Button *button) { return 0; }
+	int redrawButtonCallback(Button *button) { return 0; }
 
-	//void setupSavegameNames(Menu &menu, int num);
-	//void printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 flags);
+private:
+	int simpleMenu_getMenuItem(int index, int32 menuItemsMask, int unk);
+	void simpleMenu_flashSelection(const char *str, int x, int y, int color1, int color2, int color3);
+	void simpleMenu_initMenuItemsMask(int menuId, int maxItem, int32 menuItemsMask, int unk);
 
-	//int getMenuCenterStringX(const char *str, int x1, int x2);
+	void runSaveMenu();
+	void runMemorizePrayMenu(int charIndex, int spellType);
+	void scribeScrollDialogue();
 
-	//int getInput();
-	Button *initMenu(int id);
+	bool confirmDialogue(int id);
+	int selectCharacterDialogue(int id);
+	void displayTextBox(int id);
 	
+	Button *initMenu(int id);	
 	void drawMenuButton(Button *b, bool clicked, bool highlight, bool noFill);
 	void drawMenuButtonBox(int x, int y, int w, int h, bool clicked, bool noFill);
-	void displayTextBox(int id);
 	void updateOptionsStrings();
 	const char *getMenuString(int id);
 
 	Button *linkButton(Button *list, Button *newbt);
 	void releaseButtons(Button *list);
 
-	Button *getButtonListData() { return _menuButtons; }
-	Button *getScrollUpButton() { return &_scrollUpButton; }
-	Button *getScrollDownButton() { return &_scrollDownButton; }
-
-	Button::Callback getScrollUpButtonHandler() const { return _scrollUpFunctor; }
-	Button::Callback getScrollDownButtonHandler() const { return _scrollDownFunctor; }
-
-	uint8 defaultColor1() const { return 0xFE; }
-	uint8 defaultColor2() const { return 0x00; }
-
-	const char *getMenuTitle(const Menu &menu) { return 0; }
-	const char *getMenuItemTitle(const MenuItem &menuItem) { return 0; }
-	const char *getMenuItemLabel(const MenuItem &menuItem) { return 0; }
-
-	//Button _menuButtons[10];
-	Button *_menuButtons;
-	Button _scrollUpButton;
+	Button _scrollUpButton;//////////////////77
 	Button _scrollDownButton;
-	//Menu _mainMenu, _gameOptions, _audioOptions, _choiceMenu, _loadMenu, _saveMenu, _deleteMenu, _savenameMenu, _deathMenu;
-	//Menu *_currentMenu, *_lastMenu, *_newMenu;
-	//int _menuResult;
-	//char *_saveDescription;
 
 	char **_menuStringsPrefsTemp;
 
@@ -124,7 +111,7 @@ private:
 	uint16 _flagsMouseRight;
 	uint16 _flagsModifier;
 	uint16 _progress;
-	uint16 _prcButtonUnk3; /// ALWAYS 1?? REMOVE ??
+	uint16 _prcButtonUnk3;
 	uint16 _cflag;
 
 	Button::Callback _scrollUpFunctor;
@@ -136,6 +123,27 @@ private:
 
 	int _menuCur;
 	int _menuNumItems;
+	bool _charSelectRedraw;
+
+	int _updateBoxIndex;
+	int _updateBoxColorIndex;
+	uint32 _highLightBoxTimer;
+	static const EobRect16 _highLightBoxFrames[];
+
+	// unused
+	Button *getButtonListData() { return 0; }
+	Button *getScrollUpButton() { return &_scrollUpButton; }
+	Button *getScrollDownButton() { return &_scrollDownButton; }
+
+	Button::Callback getScrollUpButtonHandler() const { return _scrollUpFunctor; }
+	Button::Callback getScrollDownButtonHandler() const { return _scrollDownFunctor; }
+
+	uint8 defaultColor1() const { return 0xFE; }
+	uint8 defaultColor2() const { return 0x00; }
+
+	const char *getMenuTitle(const Menu &menu) { return 0; }
+	const char *getMenuItemTitle(const MenuItem &menuItem) { return 0; }
+	const char *getMenuItemLabel(const MenuItem &menuItem) { return 0; }
 };
 
 }	// End of namespace Kyra
diff --git a/engines/kyra/gui_lok.cpp b/engines/kyra/gui_lok.cpp
index 4a2d51f..6e0d108 100644
--- a/engines/kyra/gui_lok.cpp
+++ b/engines/kyra/gui_lok.cpp
@@ -184,7 +184,7 @@ int KyraEngine_LoK::buttonAmuletCallback(Button *caller) {
 
 #pragma mark -
 
-GUI_LoK::GUI_LoK(KyraEngine_LoK *vm, Screen_LoK *screen) : GUI(vm), _vm(vm), _screen(screen) {
+GUI_LoK::GUI_LoK(KyraEngine_LoK *vm, Screen_LoK *screen) : GUI_v1(vm), _vm(vm), _screen(screen) {
 	_lastScreenUpdate = 0;
 	_menu = 0;
 	_pressFlag = false;
diff --git a/engines/kyra/gui_lok.h b/engines/kyra/gui_lok.h
index 5a8d6ab..1d10603 100644
--- a/engines/kyra/gui_lok.h
+++ b/engines/kyra/gui_lok.h
@@ -92,7 +92,7 @@ namespace Kyra {
 
 class KyraEngine_LoK;
 
-class GUI_LoK : public GUI {
+class GUI_LoK : public GUI_v1 {
 	friend class KyraEngine_LoK;
 public:
 	GUI_LoK(KyraEngine_LoK *vm, Screen_LoK *screen);
diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp
index 08ce0bd..681caf9 100644
--- a/engines/kyra/gui_lol.cpp
+++ b/engines/kyra/gui_lol.cpp
@@ -1838,12 +1838,12 @@ int LoLEngine::clickedStatusIcon(Button *button) {
 	return 1;
 }
 
-GUI_LoL::GUI_LoL(LoLEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) {
+GUI_LoL::GUI_LoL(LoLEngine *vm) : GUI_v1(vm), _vm(vm), _screen(vm->_screen) {
 	_scrollUpFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::scrollUp);
 	_scrollDownFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::scrollDown);
 
-	_redrawButtonFunctor = BUTTON_FUNCTOR(GUI, this, &GUI::redrawButtonCallback);
-	_redrawShadedButtonFunctor = BUTTON_FUNCTOR(GUI, this, &GUI::redrawShadedButtonCallback);
+	_redrawButtonFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::redrawButtonCallback);
+	_redrawShadedButtonFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::redrawShadedButtonCallback);
 
 	_specialProcessButton = _backUpButtonList = 0;
 	_flagsModifier = 0;
diff --git a/engines/kyra/gui_lol.h b/engines/kyra/gui_lol.h
index 9c0c4e2..3a8135a 100644
--- a/engines/kyra/gui_lol.h
+++ b/engines/kyra/gui_lol.h
@@ -88,7 +88,7 @@ namespace Kyra {
 class LoLEngine;
 class Screen_LoL;
 
-class GUI_LoL : public GUI {
+class GUI_LoL : public GUI_v1 {
 	friend class LoLEngine;
 public:
 	GUI_LoL(LoLEngine *vm);
diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp
index c0477f2..a1d74fd 100644
--- a/engines/kyra/gui_v2.cpp
+++ b/engines/kyra/gui_v2.cpp
@@ -30,7 +30,7 @@
 
 namespace Kyra {
 
-GUI_v2::GUI_v2(KyraEngine_v2 *vm) : GUI(vm), _vm(vm), _screen(vm->screen_v2()) {
+GUI_v2::GUI_v2(KyraEngine_v2 *vm) : GUI_v1(vm), _vm(vm), _screen(vm->screen_v2()) {
 	_backUpButtonList = _specialProcessButton = 0;
 	_buttonListChanged = false;
 	_lastScreenUpdate = 0;
@@ -48,7 +48,7 @@ GUI_v2::GUI_v2(KyraEngine_v2 *vm) : GUI(vm), _vm(vm), _screen(vm->screen_v2()) {
 }
 
 Button *GUI_v2::addButtonToList(Button *list, Button *newButton) {
-	list = GUI::addButtonToList(list, newButton);
+	list = GUI_v1::addButtonToList(list, newButton);
 	_buttonListChanged = true;
 	return list;
 }
diff --git a/engines/kyra/gui_v2.h b/engines/kyra/gui_v2.h
index ef95c03..402766b 100644
--- a/engines/kyra/gui_v2.h
+++ b/engines/kyra/gui_v2.h
@@ -99,7 +99,7 @@ namespace Kyra {
 class KyraEngine_v2;
 class Screen_v2;
 
-class GUI_v2 : public GUI {
+class GUI_v2 : public GUI_v1 {
 public:
 	GUI_v2(KyraEngine_v2 *vm);
 
diff --git a/engines/kyra/kyra_hof.h b/engines/kyra/kyra_hof.h
index a6add50..3acefdd 100644
--- a/engines/kyra/kyra_hof.h
+++ b/engines/kyra/kyra_hof.h
@@ -199,7 +199,7 @@ public:
 
 	Screen *screen() { return _screen; }
 	Screen_v2 *screen_v2() const { return _screen; }
-	GUI *gui() const { return _gui; }
+	GUI_v1 *gui() const { return _gui; }
 	virtual TextDisplayer *text() { return _text; }
 	int language() const { return _lang; }
 protected:
diff --git a/engines/kyra/kyra_lok.h b/engines/kyra/kyra_lok.h
index e5fb3cd..3ecefba 100644
--- a/engines/kyra/kyra_lok.h
+++ b/engines/kyra/kyra_lok.h
@@ -109,7 +109,7 @@ public:
 
 	Screen *screen() { return _screen; }
 	Animator_LoK *animator() { return _animator; }
-	GUI *gui() const { return _gui; }
+	GUI_v1 *gui() const { return _gui; }
 	virtual Movie *createWSAMovie();
 
 	uint8 **shapes() { return _shapes; }
diff --git a/engines/kyra/kyra_mr.h b/engines/kyra/kyra_mr.h
index 38ff271..4b3e8b3 100644
--- a/engines/kyra/kyra_mr.h
+++ b/engines/kyra/kyra_mr.h
@@ -54,7 +54,7 @@ public:
 
 	Screen *screen() { return _screen; }
 	Screen_v2 *screen_v2() const { return _screen; }
-	GUI *gui() const { return _gui; }
+	GUI_v1 *gui() const { return _gui; }
 	SoundDigital *soundDigital() { return _soundDigital; }
 	int language() const { return _lang; }
 	bool heliumMode() const { return _configHelium; }
diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp
index c1b9f2a..72cc5bc 100644
--- a/engines/kyra/kyra_v1.cpp
+++ b/engines/kyra/kyra_v1.cpp
@@ -345,7 +345,7 @@ int KyraEngine_v1::checkInput(Button *buttonList, bool mainLoop, int eventFlag)
 		_eventList.erase(_eventList.begin());
 	}
 
-	GUI *guiInstance = gui();
+	GUI_v1 *guiInstance = gui();
 	if (guiInstance) {
 		if (keys)
 			return guiInstance->processButtonList(buttonList, keys | eventFlag, mouseWheel);
diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h
index 40f9074..3a4be46 100644
--- a/engines/kyra/kyra_v1.h
+++ b/engines/kyra/kyra_v1.h
@@ -176,14 +176,14 @@ class TextDisplayer;
 class StaticResource;
 class TimerManager;
 class Debugger;
-class GUI;
+class GUI_v1;
 
 struct Button;
 
 class KyraEngine_v1 : public Engine {
 friend class Debugger;
 friend class ::KyraMetaEngine;
-friend class GUI;
+friend class GUI_v1;
 friend class SoundMidiPC;    // For _eventMan
 public:
 	KyraEngine_v1(OSystem *system, const GameFlags &flags);
@@ -196,7 +196,7 @@ public:
 	Resource *resource() { return _res; }
 	virtual Screen *screen() = 0;
 	virtual TextDisplayer *text() { return _text; }
-	virtual GUI *gui() const { return 0; }
+	virtual GUI_v1 *gui() const { return 0; }
 	Sound *sound() { return _sound; }
 	StaticResource *staticres() { return _staticres; }
 	TimerManager *timer() { return _timer; }
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 7a4a3ec..8e978c1 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -357,7 +357,7 @@ Screen *LoLEngine::screen() {
 	return _screen;
 }
 
-GUI *LoLEngine::gui() const {
+GUI_v1 *LoLEngine::gui() const {
 	return _gui;
 }
 
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index 8ddba86..a33263f 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -279,7 +279,7 @@ public:
 	virtual void initKeymap();
 
 	Screen *screen();
-	GUI *gui() const;
+	GUI_v1 *gui() const;
 
 private:
 	Screen_LoL *_screen;
diff --git a/engines/kyra/loleobbase.h b/engines/kyra/loleobbase.h
index a2c1382..8bebfe4 100644
--- a/engines/kyra/loleobbase.h
+++ b/engines/kyra/loleobbase.h
@@ -86,7 +86,7 @@ public:
 	virtual ~LolEobBaseEngine();
 
 	virtual Screen *screen() = 0;
-	virtual GUI *gui() const = 0;
+	virtual GUI_v1 *gui() const = 0;
 
 protected:
 	// Startup
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 90a3e74..fa4dd10 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -314,6 +314,8 @@ enum KyraResources {
 	kEobBaseMenuStringsMgc,
 	kEobBaseMenuStringsPrefs,
 	kEobBaseMenuStringsRest2,
+	kEobBaseMenuStringsRest3,
+	kEobBaseMenuStringsRest4,
 	kEobBaseMenuStringsDefeat,
 	kEobBaseMenuStringsTransfer,
 	kEobBaseMenuStringsSpec,
diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp
index ef3a623..c514c8d 100644
--- a/engines/kyra/script_eob.cpp
+++ b/engines/kyra/script_eob.cpp
@@ -122,7 +122,7 @@ EobInfProcessor::EobInfProcessor(EobCoreEngine *engine, Screen_Eob *screen) : _v
 	_abortScript = 0;
 	_abortAfterSubroutine = 0;
 	_dlgResult = 0;
-	_script2 = 0;
+	_preventRest = 0;
 
 	_lastScriptFunc = 0;
 	_lastScriptSub = 0;
@@ -192,13 +192,13 @@ void EobInfProcessor::run(int func, int sub) {
 }
 
 void EobInfProcessor::loadState(Common::SeekableSubReadStreamEndian &in) {
-	_script2 = in.readByte();
+	_preventRest = in.readByte();
 	for (int i = 0; i < 18; i++)
 		_flagTable[i] = in.readUint16BE();
 }
 
 void EobInfProcessor::saveState(Common::OutSaveFile *out) {
-	out->writeByte(_script2);
+	out->writeByte(_preventRest);
 	for (int i = 0; i < 18; i++)
 		out->writeUint16BE(_flagTable[i]);
 }
@@ -521,7 +521,7 @@ int EobInfProcessor::oeob_setFlags(int8 *data) {
 
 	switch (*pos++) {
 	case -47:
-		_script2 = 0;
+		_preventRest = 0;
 		break;
 
 	case -28:
@@ -570,7 +570,7 @@ int EobInfProcessor::oeob_removeFlags(int8 *data) {
 
 	switch (a) {
 	case -47:
-		_script2 = 1;
+		_preventRest = 1;
 		break;
 
 	case -28:
diff --git a/engines/kyra/script_eob.h b/engines/kyra/script_eob.h
index 2b02807..322322a 100644
--- a/engines/kyra/script_eob.h
+++ b/engines/kyra/script_eob.h
@@ -43,7 +43,8 @@ public:
 	void run(int func, int sub);
 
 	void setFlag(int flag) { _flagTable[17] |= flag; }
-	bool checkFlag(int flag) { return (_flagTable[17] & flag) ? true : false; }
+	bool checkFlag(int flag) const { return (_flagTable[17] & flag) ? true : false; }
+	bool preventRest() const { return _preventRest ? true : false; }
 
 	void loadState(Common::SeekableSubReadStreamEndian &in);
 	void saveState(Common::OutSaveFile *out);
@@ -96,7 +97,7 @@ private:
 	uint8 _abortScript;
 	uint16 _abortAfterSubroutine;
 	int _dlgResult;
-	uint8 _script2;
+	uint8 _preventRest;
 
 	uint16 _lastScriptFunc;
 	uint16 _lastScriptSub;
diff --git a/engines/kyra/sequences_eob1.cpp b/engines/kyra/sequences_eob1.cpp
index e835c12..dcfabfe 100644
--- a/engines/kyra/sequences_eob1.cpp
+++ b/engines/kyra/sequences_eob1.cpp
@@ -94,10 +94,10 @@ int EobEngine::mainMenuLoop() {
 	int sel = -1;
 	do {
 		_screen->setScreenDim(28);
-		_gui->setupMenu(8, 0, _mainMenuStrings, -1, 0, 0);
+		_gui->simpleMenu_setup(8, 0, _mainMenuStrings, -1, 0, 0);
 
 		while (sel == -1 && !shouldQuit())
-			sel = _gui->handleMenu(8, _mainMenuStrings, 0, -1, 0);
+			sel = _gui->simpleMenu_process(8, _mainMenuStrings, 0, -1, 0);
 	} while ((sel < 0 || sel > 5) && !shouldQuit());
 
 	return sel + 1;
diff --git a/engines/kyra/sequences_eob2.cpp b/engines/kyra/sequences_eob2.cpp
index c926eb6..3765ee3 100644
--- a/engines/kyra/sequences_eob2.cpp
+++ b/engines/kyra/sequences_eob2.cpp
@@ -155,10 +155,10 @@ int DarkMoonEngine::mainMenuLoop() {
 	int sel = -1;
 	do {
 		_screen->setScreenDim(6);
-		_gui->setupMenu(6, 0, _mainMenuStrings, -1, 0, 0);
+		_gui->simpleMenu_setup(6, 0, _mainMenuStrings, -1, 0, 0);
 
 		while (sel == -1 && !shouldQuit())
-			sel = _gui->handleMenu(6, _mainMenuStrings, 0, -1, 0);
+			sel = _gui->simpleMenu_process(6, _mainMenuStrings, 0, -1, 0);
 	} while ((sel < 0 || sel > 5) && !shouldQuit());
 
 	return sel + 1;
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index bf06ba6..a974600 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -266,7 +266,7 @@ const uint8 EobCoreEngine::_hpIncrPerLevel[] = { 10, 4, 8, 6, 10, 10, 9, 10, 9,
 
 const uint8 EobCoreEngine::_numLevelsPerClass[] = { 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 2, 2, 3, 2, 2 };
 
-const int8 EobCoreEngine::_classHpIncreaseType[] = {
+const int8 EobCoreEngine::_characterClassType[] = {
 	0, -1, -1, 5, -1, -1, 4, -1, -1, 1, -1, -1, 2, -1, -1, 3, -1, -1,  0,
 	2, -1, 0, 3, -1, 0, 1, -1, 0, 1, 3, 3, 1, -1, 2, 3, -1, 0, 2,  1,  5,
 	2, -1, 2, 1, -1
@@ -381,6 +381,8 @@ void EobCoreEngine::initStaticResource() {
 	_menuStringsMgc = _staticres->loadStrings(kEobBaseMenuStringsMgc, temp);
 	_menuStringsPrefs = _staticres->loadStrings(kEobBaseMenuStringsPrefs, temp);
 	_menuStringsRest2 = _staticres->loadStrings(kEobBaseMenuStringsRest2, temp);
+	_menuStringsRest3 = _staticres->loadStrings(kEobBaseMenuStringsRest3, temp);
+	_menuStringsRest4 = _staticres->loadStrings(kEobBaseMenuStringsRest4, temp);
 	_menuStringsDefeat = _staticres->loadStrings(kEobBaseMenuStringsDefeat, temp);
 	_menuStringsTransfer = _staticres->loadStrings(kEobBaseMenuStringsTransfer, temp);
 	_menuStringsSpec = _staticres->loadStrings(kEobBaseMenuStringsSpec, temp);


Commit: e29f6397911265439fb229710bf17282c66d5f51
    https://github.com/scummvm/scummvm/commit/e29f6397911265439fb229710bf17282c66d5f51
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:12-08:00

Commit Message:
KYRA: (EOB) - fix monster distance attack bug

Changed paths:
    engines/kyra/items_eob.cpp
    engines/kyra/script_eob.cpp
    engines/kyra/sprites_eob.cpp



diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
index 98cd634..f7aed1b 100644
--- a/engines/kyra/items_eob.cpp
+++ b/engines/kyra/items_eob.cpp
@@ -99,7 +99,7 @@ Kyra::Item EobCoreEngine::duplicateItem(Item itemIndex) {
 	if (!foundSlot)
 		return 0;
 
-	memcpy(&_items[i], &_items[itemIndex], sizeof(EobItem));
+	memcpy(&_items[i], itm, sizeof(EobItem));
 	return i;
 }
 
diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp
index c514c8d..9e18a14 100644
--- a/engines/kyra/script_eob.cpp
+++ b/engines/kyra/script_eob.cpp
@@ -80,8 +80,6 @@ EobInfProcessor::EobInfProcessor(EobCoreEngine *engine, Screen_Eob *screen) : _v
 	_commandMin(engine->game() == GI_EOB1 ? -27 : -31) {
 
 #define Opcode(x) _opcodes.push_back(new InfProc(this, &EobInfProcessor::x))
-//#define OpcodeAltV(x, y) if (_vm->game() == GI_EOB1) Opcode(x); else Opcode(y);
-//#define OpcodeAlt(x) OpcodeAltV(x##_v1, x##_v2)
 #define OpcodeAlt(x) if (_vm->game() == GI_EOB1) Opcode(x##_v1); else Opcode(x##_v2);
 	Opcode(oeob_setWallType);
 	Opcode(oeob_toggleWallState);
@@ -114,7 +112,6 @@ EobInfProcessor::EobInfProcessor(EobCoreEngine *engine, Screen_Eob *screen) : _v
 	Opcode(oeob_dialogue);
 	Opcode(oeob_specialEvent);
 #undef Opcode
-//#undef OpcodeAltV
 #undef OpcodeAlt
 
 	_scriptData = 0;
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index 1fa89ea..109d244 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -941,7 +941,7 @@ bool EobCoreEngine::updateMonsterTryDistanceAttack(EobMonsterInPlay *m) {
 		case 11:
 			itm = duplicateItem(60);
 			if (itm) {
-				if (launchObject(-1, itm, m->block, m->pos, m->dir, _items[itm].type))
+				if (!launchObject(-1, itm, m->block, m->pos, m->dir, _items[itm].type))
 					_items[itm].block = -1;
 			}
 			break;
@@ -997,7 +997,7 @@ bool EobCoreEngine::updateMonsterTryDistanceAttack(EobMonsterInPlay *m) {
 		} else {
 			itm = duplicateItem(-s);
 			if (itm) {
-				if (launchObject(-1, itm, m->block, m->pos, m->dir, _items[itm].type))
+				if (!launchObject(-1, itm, m->block, m->pos, m->dir, _items[itm].type))
 					_items[itm].block = -1;
 			}
 		}


Commit: 8d4034f428062d82c981536365961971fef0243e
    https://github.com/scummvm/scummvm/commit/8d4034f428062d82c981536365961971fef0243e
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:12-08:00

Commit Message:
KYRA: (EOB) - add static resources for memorize/pray menu

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    engines/kyra/eobcommon.h
    engines/kyra/resource.h
    engines/kyra/staticres_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index 96c8787..066ae33 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -272,6 +272,13 @@ const ExtractFilename extractFilenames[] = {
 	{ kEobBaseMenuStringsTransfer, kTypeStringList, true },
 	{ kEobBaseMenuStringsSpec, kTypeStringList, true },
 	{ kEobBaseMenuStringsSpellNo, kTypeStringList, false },
+
+	{ kEobBaseSpellLevelsMage, kTypeRawData, false },
+	{ kEobBaseSpellLevelsCleric, kTypeRawData, false },
+	{ kEobBaseSpellMps1, kTypeRawData, false },
+	{ kEobBaseSpellMps2, kTypeRawData, false },
+	{ kEobBaseSpellMps3, kTypeRawData, false },
+	{ kEobBaseSpellMps4, kTypeRawData, false },
 	
 	{ kEobBaseCharGuiStringsHp, kTypeStringList, true },
 	{ kEobBaseCharGuiStringsWp1, kTypeStringList, true },
@@ -1356,6 +1363,18 @@ const char *getIdString(const int id) {
 		return "kEobBaseMenuStringsSpec";
 	case kEobBaseMenuStringsSpellNo:
 		return "kEobBaseMenuStringsSpellNo";
+	case kEobBaseSpellLevelsMage:
+		return "kEobBaseSpellLevelsMage";
+	case kEobBaseSpellLevelsCleric:
+		return "kEobBaseSpellLevelsCleric";
+	case kEobBaseSpellMps1:
+		return "kEobBaseSpellMps1";
+	case kEobBaseSpellMps2:
+		return "kEobBaseSpellMps2";
+	case kEobBaseSpellMps3:
+		return "kEobBaseSpellMps3";
+	case kEobBaseSpellMps4:
+		return "kEobBaseSpellMps4";
 	case kEobBaseCharGuiStringsHp:
 		return "kEobBaseCharGuiStringsHp";
 	case kEobBaseCharGuiStringsWp1:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index fc57508..3c27b55 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -248,6 +248,13 @@ enum kExtractID {
 	kEobBaseMenuStringsSpec,
 	kEobBaseMenuStringsSpellNo,
 
+	kEobBaseSpellLevelsMage,
+	kEobBaseSpellLevelsCleric,
+	kEobBaseSpellMps1,
+	kEobBaseSpellMps2,
+	kEobBaseSpellMps3,
+	kEobBaseSpellMps4,
+
 	kEobBaseCharGuiStringsHp,
 	kEobBaseCharGuiStringsWp1,
 	kEobBaseCharGuiStringsWp2,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 423c726..bf98deb 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1094,6 +1094,13 @@ const int eob1FloppyNeed[] = {
 	kEobBaseMenuStringsRest2,
 	kEobBaseMenuStringsRest4,
 	kEobBaseMenuStringsDefeat,
+
+	kEobBaseSpellLevelsMage,
+	kEobBaseSpellLevelsCleric,
+	kEobBaseSpellMps1,
+	kEobBaseSpellMps2,
+	kEobBaseSpellMps3,
+	kEobBaseSpellMps4,
 	
 	kEobBaseCharGuiStringsHp,
 	kEobBaseCharGuiStringsWp1,
@@ -1276,6 +1283,13 @@ const int eob2FloppyNeed[] = {
 	kEobBaseMenuStringsSpec,
 	kEobBaseMenuStringsSpellNo,
 
+	kEobBaseSpellLevelsMage,
+	kEobBaseSpellLevelsCleric,
+	kEobBaseSpellMps1,
+	kEobBaseSpellMps2,
+	kEobBaseSpellMps3,
+	kEobBaseSpellMps4,
+
 	kEobBaseCharGuiStringsHp,
 	kEobBaseCharGuiStringsWp2,
 	kEobBaseCharGuiStringsWr,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index b8b32bc..ae49b48 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -1675,6 +1675,42 @@ const ExtractEntrySearchData kEobBaseMenuStringsSpellNoProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEobBaseSpellLevelsMageProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000001A, 0x00000042, { { 0x4F, 0xA3, 0x70, 0x0F, 0x6D, 0xB4, 0xC2, 0xAF, 0x12, 0xB4, 0x2E, 0x26, 0xEF, 0x0B, 0x37, 0x92 } } } }, // EOB1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000023, 0x00000074, { { 0xBE, 0x10, 0xFA, 0xD9, 0xB3, 0xB0, 0x4E, 0x73, 0xC9, 0xA1, 0xE2, 0xCE, 0xE8, 0xEC, 0x85, 0x0F } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseSpellLevelsClericProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000019, 0x00000045, { { 0x9E, 0xDA, 0xF2, 0x94, 0x3E, 0x0B, 0xA0, 0x23, 0x08, 0x41, 0xD5, 0x3C, 0x61, 0x77, 0xFD, 0x78 } } } }, // EOB1
+	{ UNK_LANG, kPlatformUnknown, { 0x0000001D, 0x00000066, { { 0xDB, 0x7F, 0x93, 0xE2, 0x2E, 0xCF, 0x69, 0xCC, 0x2A, 0xEF, 0x7C, 0x1E, 0x92, 0x6B, 0x51, 0x4E } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseSpellMps1Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000032, 0x0000004C, { { 0x87, 0xDD, 0xD0, 0xF8, 0x52, 0x84, 0x26, 0xC4, 0x9C, 0x5D, 0x0E, 0x46, 0x1A, 0xE8, 0x19, 0xD6 } } } }, // EOB1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000088, 0x00000114, { { 0xA0, 0xB7, 0x2F, 0xED, 0x50, 0xE7, 0xC6, 0x11, 0xC9, 0x25, 0xB2, 0xB9, 0x81, 0xFB, 0xD8, 0x59 } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseSpellMps2Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000028, 0x0000001D, { { 0xA5, 0xCA, 0x1D, 0x96, 0xAE, 0x89, 0xBC, 0x7A, 0x32, 0x50, 0xCE, 0x44, 0x5D, 0x93, 0x25, 0x4B } } } }, // EOB1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000040, 0x0000001D, { { 0x07, 0x31, 0x0D, 0x12, 0x55, 0x11, 0x11, 0xB6, 0x68, 0xC7, 0xEE, 0xDE, 0xC6, 0xED, 0x82, 0x5A } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseSpellMps3Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000003C, 0x00000012, { { 0x96, 0x7E, 0x17, 0x9E, 0xFD, 0x39, 0xC9, 0x3A, 0xB7, 0x3E, 0x8D, 0xA8, 0xED, 0xA3, 0x07, 0xEB } } } }, // EOB1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000088, 0x0000002F, { { 0x19, 0x1A, 0x9B, 0x42, 0xA0, 0x67, 0x10, 0x1A, 0xAC, 0x00, 0x0F, 0xF7, 0xBE, 0x04, 0x61, 0x36 } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseSpellMps4Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000037, 0x0000005E, { { 0x61, 0x30, 0x1A, 0x74, 0x9B, 0x4C, 0x8C, 0x83, 0xD5, 0xE6, 0x39, 0x6E, 0xCA, 0x18, 0x16, 0x63 } } } }, // EOB1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000114, 0x00000102, { { 0x33, 0xEE, 0x32, 0x9C, 0xB2, 0xB3, 0x60, 0x66, 0x91, 0xE0, 0x90, 0x0E, 0x8F, 0xE1, 0xA5, 0x4A } } } }, // EOB2
+	EXTRACT_END_ENTRY
+};
+
 const ExtractEntrySearchData kEobBaseCharGuiStringsHpProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000000F, 0x00000352, { { 0x9C, 0x13, 0x3D, 0x2A, 0x68, 0x11, 0x81, 0xA4, 0x77, 0x54, 0x47, 0x43, 0xA1, 0xDA, 0x55, 0x50 } } } }, 
 	{ DE_DEU, kPlatformUnknown, { 0x0000000E, 0x000002AC, { { 0xBB, 0xD5, 0x36, 0xB2, 0x8A, 0x60, 0x78, 0x04, 0x46, 0x2D, 0x35, 0x59, 0x3E, 0x42, 0xB9, 0x83 } } } },	// Eob 1
@@ -3399,6 +3435,13 @@ const ExtractEntry extractProviders[] = {
 	{ kEobBaseMenuStringsSpec, kEobBaseMenuStringsSpecProvider },
 	{ kEobBaseMenuStringsSpellNo, kEobBaseMenuStringsSpellNoProvider },
 
+	{ kEobBaseSpellLevelsMage, kEobBaseSpellLevelsMageProvider },
+	{ kEobBaseSpellLevelsCleric, kEobBaseSpellLevelsClericProvider },
+	{ kEobBaseSpellMps1, kEobBaseSpellMps1Provider },
+	{ kEobBaseSpellMps2, kEobBaseSpellMps2Provider },
+	{ kEobBaseSpellMps3, kEobBaseSpellMps3Provider },
+	{ kEobBaseSpellMps4, kEobBaseSpellMps4Provider },
+
 	{ kEobBaseCharGuiStringsHp, kEobBaseCharGuiStringsHpProvider },
 	{ kEobBaseCharGuiStringsWp1, kEobBaseCharGuiStringsWp1Provider },
 	{ kEobBaseCharGuiStringsWp2, kEobBaseCharGuiStringsWp2Provider },
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index ede25dd..2e4df6a 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -1007,6 +1007,13 @@ protected:
 	const char *const *_menuStringsSpec;
 	const char *const *_menuStringsSpellNo;
 
+	const uint8 *_spellLevelsMage;
+	const uint8 *_spellLevelsCleric;
+	const uint8 *_spellLevelsMps1;
+	const uint8 *_spellLevelsMps2;
+	const uint8 *_spellLevelsMps3;
+	const uint8 *_spellLevelsMps4;
+
 	// sound
 	void snd_playSoundEffect(int id, int volume=0xFF);
 };
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index fa4dd10..5d9554c 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -321,6 +321,13 @@ enum KyraResources {
 	kEobBaseMenuStringsSpec,
 	kEobBaseMenuStringsSpellNo,
 
+	kEobBaseSpellLevelsMage,
+	kEobBaseSpellLevelsCleric,
+	kEobBaseSpellMps1,
+	kEobBaseSpellMps2,
+	kEobBaseSpellMps3,
+	kEobBaseSpellMps4,
+
 	kEobBaseCharGuiStringsHp,
 	kEobBaseCharGuiStringsWp1,
 	kEobBaseCharGuiStringsWp2,
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index a974600..7908bc2 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -388,6 +388,13 @@ void EobCoreEngine::initStaticResource() {
 	_menuStringsSpec = _staticres->loadStrings(kEobBaseMenuStringsSpec, temp);
 	_menuStringsSpellNo = _staticres->loadStrings(kEobBaseMenuStringsSpellNo, temp);
 
+	_spellLevelsMage = _staticres->loadRawData(kEobBaseSpellLevelsMage, temp);
+	_spellLevelsCleric = _staticres->loadRawData(kEobBaseSpellLevelsCleric, temp);
+	_spellLevelsMps1 = _staticres->loadRawData(kEobBaseSpellMps1, temp);
+	_spellLevelsMps2 = _staticres->loadRawData(kEobBaseSpellMps2, temp);
+	_spellLevelsMps3 = _staticres->loadRawData(kEobBaseSpellMps3, temp);
+	_spellLevelsMps4 = _staticres->loadRawData(kEobBaseSpellMps4, temp);
+
 	_characterGuiStringsHp = _staticres->loadStrings(kEobBaseCharGuiStringsHp, temp);
 	_characterGuiStringsWp = _staticres->loadStrings(_flags.gameID == GI_EOB2 ? kEobBaseCharGuiStringsWp2 : kEobBaseCharGuiStringsWp1, temp);
 	_characterGuiStringsWr = _staticres->loadStrings(kEobBaseCharGuiStringsWr, temp);


Commit: d7f2720b5709b1b4a93f81163752d2da148d2fd9
    https://github.com/scummvm/scummvm/commit/d7f2720b5709b1b4a93f81163752d2da148d2fd9
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:12-08:00

Commit Message:
KYRA: (EOB) - match eob code with 3f2b5b9e8b9196c9d0e573abf8f8350ec4034b1d

Changed paths:
    engines/kyra/eob1.cpp
    engines/kyra/eob2.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/gui_eob.h
    engines/kyra/saveload_eob.cpp



diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
index cdccd65..69071d3 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -78,7 +78,7 @@ void EobEngine::startupNew() {
 }
 
 void EobEngine::startupLoad() {
-	updateHandItemCursor();
+	setHandItem(_itemInHand);
 	loadLevel(_currentLevel, _currentSub);
 	_saveLoadMode = 0;
 }
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index de8e90c..56ef838 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -78,7 +78,7 @@ void DarkMoonEngine::startupNew() {
 }
 
 void DarkMoonEngine::startupLoad() {
-	updateHandItemCursor();
+	setHandItem(_itemInHand);
 	loadLevel(_currentLevel, _currentSub);
 	_saveLoadMode = 0;
 }
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 83a57cd..7ec988e 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -46,7 +46,6 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_playFinale = false;
 	_runFlag = true;
 	_saveLoadMode = 0;
-	_updateHandItemCursor = false;
 	_configMouse = true;
 	_resting = false;
 
@@ -441,11 +440,6 @@ void EobCoreEngine::runLoop() {
 		checkInput(_activeButtons, true, 0);
 		removeInputTop();
 
-		if (_updateHandItemCursor) {
-			_updateHandItemCursor = false;
-			setHandItem(_itemInHand);
-		}
-
 		_timer->update();
 		updateScriptTimers();
 
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 2e4df6a..8b97ab3 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -351,8 +351,6 @@ protected:
 
 	// Mouse
 	void setHandItem(Item itemIndex);
-	void updateHandItemCursor() { _updateHandItemCursor = true; }
-	bool _updateHandItemCursor;
 
 	// Characters
 	int getDexterityArmorClassModifier(int dexterity);
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 4d5a1bf..4fe5b6b 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -1951,17 +1951,17 @@ int GUI_Eob::processButtonList(Kyra::Button *buttonList, uint16 inputFlags, int8
 	return result;
 }
 
-void GUI_Eob::simpleMenu_setup(int sd, int maxItem, const char *const *strings, int32 menuItemsMask, int unk, int lineSpacing) {
-	simpleMenu_initMenuItemsMask(sd, maxItem, menuItemsMask, unk);
+void GUI_Eob::simpleMenu_setup(int sd, int maxItem, const char *const *strings, int32 menuItemsMask, int itemOffset, int lineSpacing) {
+	simpleMenu_initMenuItemsMask(sd, maxItem, menuItemsMask, itemOffset);
 
 	const ScreenDim *dm = _screen->getScreenDim(19 + sd);
 	int x = (_screen->_curDim->sx + dm->sx) << 3;
 	int y = _screen->_curDim->sy + dm->sy;
 
-	int v = simpleMenu_getMenuItem(_menuCur, menuItemsMask, unk);
+	int v = simpleMenu_getMenuItem(_menuCur, menuItemsMask, itemOffset);
 
 	for (int i = 0; i < _menuNumItems; i++) {
-		int item = simpleMenu_getMenuItem(i, menuItemsMask, unk);
+		int item = simpleMenu_getMenuItem(i, menuItemsMask, itemOffset);
 		int ty = y + i * (lineSpacing + _screen->getFontHeight());
 		_screen->printShadedText(strings[item], x, ty, dm->unkA, 0);
 		if (item == v)
@@ -1975,7 +1975,7 @@ void GUI_Eob::simpleMenu_setup(int sd, int maxItem, const char *const *strings,
 	_vm->removeInputTop();
 }
 
-int GUI_Eob::simpleMenu_process(int sd, const char *const *strings, void *b, int32 menuItemsMask, int unk) {
+int GUI_Eob::simpleMenu_process(int sd, const char *const *strings, void *b, int32 menuItemsMask, int itemOffset) {
 	const ScreenDim *dm = _screen->getScreenDim(19 + sd);
 	int h = _menuNumItems - 1;
 	int currentItem = _menuCur % _menuNumItems;
@@ -2017,13 +2017,13 @@ int GUI_Eob::simpleMenu_process(int sd, const char *const *strings, void *b, int
 	}
 
 	if (newItem != currentItem) {
-		_screen->printText(strings[simpleMenu_getMenuItem(currentItem, menuItemsMask, unk)], x, y + currentItem * lineH , dm->unkA, 0);
-		_screen->printText(strings[simpleMenu_getMenuItem(newItem,  menuItemsMask, unk)], x, y + newItem * lineH , dm->unkC, 0);
+		_screen->printText(strings[simpleMenu_getMenuItem(currentItem, menuItemsMask, itemOffset)], x, y + currentItem * lineH , dm->unkA, 0);
+		_screen->printText(strings[simpleMenu_getMenuItem(newItem,  menuItemsMask, itemOffset)], x, y + newItem * lineH , dm->unkC, 0);
 		_screen->updateScreen();
 	}
 
 	if (result != -1) {
-		result = simpleMenu_getMenuItem(result, menuItemsMask, unk);
+		result = simpleMenu_getMenuItem(result, menuItemsMask, itemOffset);
 		simpleMenu_flashSelection(strings[result], x, y + newItem * lineH, dm->unkA, dm->unkC, 0);
 	}
 
@@ -2032,7 +2032,7 @@ int GUI_Eob::simpleMenu_process(int sd, const char *const *strings, void *b, int
 	return result;
 }
 
-int GUI_Eob::simpleMenu_getMenuItem(int index, int32 menuItemsMask, int unk) {
+int GUI_Eob::simpleMenu_getMenuItem(int index, int32 menuItemsMask, int itemOffset) {
 	if (menuItemsMask == -1)
 		return index;
 
@@ -2040,11 +2040,11 @@ int GUI_Eob::simpleMenu_getMenuItem(int index, int32 menuItemsMask, int unk) {
 	int i = index;
 
 	for (; i; res++) {
-		if (menuItemsMask & (1 << (res + unk)))
+		if (menuItemsMask & (1 << (res + itemOffset)))
 			i--;
 	}
 
-	while (!(menuItemsMask & (1 << (res + unk))))
+	while (!(menuItemsMask & (1 << (res + itemOffset))))
 		res++;
 
 	return res;
@@ -2436,7 +2436,7 @@ int GUI_Eob::getTextInput(char *dest, int x, int y, int destMaxLen, int textColo
 	return _keyPressed.keycode == Common::KEYCODE_ESCAPE ? -1 : len;
 }
 
-void GUI_Eob::simpleMenu_initMenuItemsMask(int menuId, int maxItem, int32 menuItemsMask, int unk) {
+void GUI_Eob::simpleMenu_initMenuItemsMask(int menuId, int maxItem, int32 menuItemsMask, int itemOffset) {
 	if (menuItemsMask == -1) {
 		_menuNumItems = _screen->getScreenDim(19 + menuId)->h;
 		_menuCur = _screen->getScreenDim(19 + menuId)->unk8;
@@ -2446,7 +2446,7 @@ void GUI_Eob::simpleMenu_initMenuItemsMask(int menuId, int maxItem, int32 menuIt
 	_menuNumItems = 0;
 
 	for (int i = 0; i < maxItem; i++) {
-		if (menuItemsMask & (1 << (i + unk)))
+		if (menuItemsMask & (1 << (i + itemOffset)))
 			_menuNumItems++;
 	}
 
@@ -2462,7 +2462,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
 }
 
 void GUI_Eob::scribeScrollDialogue() {
-
+	
 }
 
 bool GUI_Eob::confirmDialogue(int id) {
diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h
index 64f1c19..bb446f7 100644
--- a/engines/kyra/gui_eob.h
+++ b/engines/kyra/gui_eob.h
@@ -74,7 +74,7 @@ public:
 	int redrawButtonCallback(Button *button) { return 0; }
 
 private:
-	int simpleMenu_getMenuItem(int index, int32 menuItemsMask, int unk);
+	int simpleMenu_getMenuItem(int index, int32 menuItemsMask, int itemOffset);
 	void simpleMenu_flashSelection(const char *str, int x, int y, int color1, int color2, int color3);
 	void simpleMenu_initMenuItemsMask(int menuId, int maxItem, int32 menuItemsMask, int unk);
 
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index 18ddddd..85b94cd 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -374,7 +374,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 	}
 
 	gui_toggleButtons();
-	updateHandItemCursor();
+	setHandItem(_itemInHand);
 
 	while (!_screen->isMouseVisible())
 		_screen->showMouse();


Commit: b7f7635876d3621b11d66cddca9babc1b5f1a1c6
    https://github.com/scummvm/scummvm/commit/b7f7635876d3621b11d66cddca9babc1b5f1a1c6
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:12-08:00

Commit Message:
KYRA: (EOB) - implement memorize/pray spells menu

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    engines/kyra/chargen.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/gui_eob.h
    engines/kyra/magic_eob.cpp
    engines/kyra/resource.h
    engines/kyra/saveload_eob.cpp
    engines/kyra/scene_eob.cpp
    engines/kyra/staticres_eob.cpp
    engines/kyra/timer_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index 066ae33..298d8b2 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -275,10 +275,10 @@ const ExtractFilename extractFilenames[] = {
 
 	{ kEobBaseSpellLevelsMage, kTypeRawData, false },
 	{ kEobBaseSpellLevelsCleric, kTypeRawData, false },
-	{ kEobBaseSpellMps1, kTypeRawData, false },
-	{ kEobBaseSpellMps2, kTypeRawData, false },
-	{ kEobBaseSpellMps3, kTypeRawData, false },
-	{ kEobBaseSpellMps4, kTypeRawData, false },
+	{ kEobBaseNumSpellsCleric, kTypeRawData, false },
+	{ kEobBaseNumSpellsWisAdj, kTypeRawData, false },
+	{ kEobBaseNumSpellsPal, kTypeRawData, false },
+	{ kEobBaseNumSpellsMage, kTypeRawData, false },
 	
 	{ kEobBaseCharGuiStringsHp, kTypeStringList, true },
 	{ kEobBaseCharGuiStringsWp1, kTypeStringList, true },
@@ -1367,14 +1367,14 @@ const char *getIdString(const int id) {
 		return "kEobBaseSpellLevelsMage";
 	case kEobBaseSpellLevelsCleric:
 		return "kEobBaseSpellLevelsCleric";
-	case kEobBaseSpellMps1:
-		return "kEobBaseSpellMps1";
-	case kEobBaseSpellMps2:
-		return "kEobBaseSpellMps2";
-	case kEobBaseSpellMps3:
-		return "kEobBaseSpellMps3";
-	case kEobBaseSpellMps4:
-		return "kEobBaseSpellMps4";
+	case kEobBaseNumSpellsCleric:
+		return "kEobBaseNumSpellsCleric";
+	case kEobBaseNumSpellsWisAdj:
+		return "kEobBaseNumSpellsWisAdj";
+	case kEobBaseNumSpellsPal:
+		return "kEobBaseNumSpellsPal";
+	case kEobBaseNumSpellsMage:
+		return "kEobBaseNumSpellsMage";
 	case kEobBaseCharGuiStringsHp:
 		return "kEobBaseCharGuiStringsHp";
 	case kEobBaseCharGuiStringsWp1:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index 3c27b55..e2702c4 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -250,10 +250,10 @@ enum kExtractID {
 
 	kEobBaseSpellLevelsMage,
 	kEobBaseSpellLevelsCleric,
-	kEobBaseSpellMps1,
-	kEobBaseSpellMps2,
-	kEobBaseSpellMps3,
-	kEobBaseSpellMps4,
+	kEobBaseNumSpellsCleric,
+	kEobBaseNumSpellsWisAdj,
+	kEobBaseNumSpellsPal,
+	kEobBaseNumSpellsMage,
 
 	kEobBaseCharGuiStringsHp,
 	kEobBaseCharGuiStringsWp1,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index bf98deb..f98f712 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1097,10 +1097,10 @@ const int eob1FloppyNeed[] = {
 
 	kEobBaseSpellLevelsMage,
 	kEobBaseSpellLevelsCleric,
-	kEobBaseSpellMps1,
-	kEobBaseSpellMps2,
-	kEobBaseSpellMps3,
-	kEobBaseSpellMps4,
+	kEobBaseNumSpellsCleric,
+	kEobBaseNumSpellsWisAdj,
+	kEobBaseNumSpellsPal,
+	kEobBaseNumSpellsMage,
 	
 	kEobBaseCharGuiStringsHp,
 	kEobBaseCharGuiStringsWp1,
@@ -1285,10 +1285,10 @@ const int eob2FloppyNeed[] = {
 
 	kEobBaseSpellLevelsMage,
 	kEobBaseSpellLevelsCleric,
-	kEobBaseSpellMps1,
-	kEobBaseSpellMps2,
-	kEobBaseSpellMps3,
-	kEobBaseSpellMps4,
+	kEobBaseNumSpellsCleric,
+	kEobBaseNumSpellsWisAdj,
+	kEobBaseNumSpellsPal,
+	kEobBaseNumSpellsMage,
 
 	kEobBaseCharGuiStringsHp,
 	kEobBaseCharGuiStringsWp2,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index ae49b48..b1f54d2 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -1687,25 +1687,25 @@ const ExtractEntrySearchData kEobBaseSpellLevelsClericProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSpellMps1Provider[] = {
+const ExtractEntrySearchData kEobBaseNumSpellsClericProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000032, 0x0000004C, { { 0x87, 0xDD, 0xD0, 0xF8, 0x52, 0x84, 0x26, 0xC4, 0x9C, 0x5D, 0x0E, 0x46, 0x1A, 0xE8, 0x19, 0xD6 } } } }, // EOB1
 	{ UNK_LANG, kPlatformUnknown, { 0x00000088, 0x00000114, { { 0xA0, 0xB7, 0x2F, 0xED, 0x50, 0xE7, 0xC6, 0x11, 0xC9, 0x25, 0xB2, 0xB9, 0x81, 0xFB, 0xD8, 0x59 } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSpellMps2Provider[] = {
+const ExtractEntrySearchData kEobBaseNumSpellsWisAdjProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000028, 0x0000001D, { { 0xA5, 0xCA, 0x1D, 0x96, 0xAE, 0x89, 0xBC, 0x7A, 0x32, 0x50, 0xCE, 0x44, 0x5D, 0x93, 0x25, 0x4B } } } }, // EOB1
 	{ UNK_LANG, kPlatformUnknown, { 0x00000040, 0x0000001D, { { 0x07, 0x31, 0x0D, 0x12, 0x55, 0x11, 0x11, 0xB6, 0x68, 0xC7, 0xEE, 0xDE, 0xC6, 0xED, 0x82, 0x5A } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSpellMps3Provider[] = {
+const ExtractEntrySearchData kEobBaseNumSpellsPalProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000003C, 0x00000012, { { 0x96, 0x7E, 0x17, 0x9E, 0xFD, 0x39, 0xC9, 0x3A, 0xB7, 0x3E, 0x8D, 0xA8, 0xED, 0xA3, 0x07, 0xEB } } } }, // EOB1
 	{ UNK_LANG, kPlatformUnknown, { 0x00000088, 0x0000002F, { { 0x19, 0x1A, 0x9B, 0x42, 0xA0, 0x67, 0x10, 0x1A, 0xAC, 0x00, 0x0F, 0xF7, 0xBE, 0x04, 0x61, 0x36 } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSpellMps4Provider[] = {
+const ExtractEntrySearchData kEobBaseNumSpellsMageProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000037, 0x0000005E, { { 0x61, 0x30, 0x1A, 0x74, 0x9B, 0x4C, 0x8C, 0x83, 0xD5, 0xE6, 0x39, 0x6E, 0xCA, 0x18, 0x16, 0x63 } } } }, // EOB1
 	{ UNK_LANG, kPlatformUnknown, { 0x00000114, 0x00000102, { { 0x33, 0xEE, 0x32, 0x9C, 0xB2, 0xB3, 0x60, 0x66, 0x91, 0xE0, 0x90, 0x0E, 0x8F, 0xE1, 0xA5, 0x4A } } } }, // EOB2
 	EXTRACT_END_ENTRY
@@ -3437,10 +3437,10 @@ const ExtractEntry extractProviders[] = {
 
 	{ kEobBaseSpellLevelsMage, kEobBaseSpellLevelsMageProvider },
 	{ kEobBaseSpellLevelsCleric, kEobBaseSpellLevelsClericProvider },
-	{ kEobBaseSpellMps1, kEobBaseSpellMps1Provider },
-	{ kEobBaseSpellMps2, kEobBaseSpellMps2Provider },
-	{ kEobBaseSpellMps3, kEobBaseSpellMps3Provider },
-	{ kEobBaseSpellMps4, kEobBaseSpellMps4Provider },
+	{ kEobBaseNumSpellsCleric, kEobBaseNumSpellsClericProvider },
+	{ kEobBaseNumSpellsWisAdj, kEobBaseNumSpellsWisAdjProvider },
+	{ kEobBaseNumSpellsPal, kEobBaseNumSpellsPalProvider },
+	{ kEobBaseNumSpellsMage, kEobBaseNumSpellsMageProvider },
 
 	{ kEobBaseCharGuiStringsHp, kEobBaseCharGuiStringsHpProvider },
 	{ kEobBaseCharGuiStringsWp1, kEobBaseCharGuiStringsWp1Provider },
diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index 380cc12..3147fbb 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -172,7 +172,7 @@ bool CharacterGenerator::start(EobCharacter *characters, uint8 ***faceShapes) {
 	_activeBox = 0;
 
 	for (bool loop = true; loop && (!_vm->shouldQuit()); ) {
-		_vm->_gui->highLightBoxFrame(_activeBox + 6);
+		_vm->_gui->updateBoxFrameHighLight(_activeBox + 6);
 		_vm->sound()->process();
 		int inputFlag = _vm->checkInput(_vm->_activeButtons, false, 0);
 		_vm->removeInputTop();
@@ -187,7 +187,7 @@ bool CharacterGenerator::start(EobCharacter *characters, uint8 ***faceShapes) {
 				_vm->sound()->haltTrack();
 				return false;
 			}
-			_vm->_gui->highLightBoxFrame(-1);
+			_vm->_gui->updateBoxFrameHighLight(-1);
 		}
 
 		if (inputFlag & 0x8000) {
@@ -201,7 +201,7 @@ bool CharacterGenerator::start(EobCharacter *characters, uint8 ***faceShapes) {
 		}
 
 		if (inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP5]) {
-			_vm->_gui->highLightBoxFrame(-1);
+			_vm->_gui->updateBoxFrameHighLight(-1);
 			if (_characters[_activeBox].name[0]) {
 				int b = _activeBox;
 				if (viewDeleteCharacter())
@@ -379,12 +379,12 @@ int CharacterGenerator::viewDeleteCharacter() {
 	initButtonsFromList(0, 7);
 	_vm->removeInputTop();
 
-	_vm->_gui->highLightBoxFrame(-1);
+	_vm->_gui->updateBoxFrameHighLight(-1);
 	printStats(_activeBox, 2);
 
 	int res = 0;
 	for (bool loop = true; loop && _characters[_activeBox].name[0] && !_vm->shouldQuit(); ) {
-		_vm->_gui->highLightBoxFrame(_activeBox + 6);
+		_vm->_gui->updateBoxFrameHighLight(_activeBox + 6);
 		_vm->sound()->process();
 
 		int inputFlag = _vm->checkInput(_vm->_activeButtons, false, 0);
@@ -423,14 +423,14 @@ int CharacterGenerator::viewDeleteCharacter() {
 		}
 
 		if (loop == false)
-			_vm->_gui->highLightBoxFrame(-1);
+			_vm->_gui->updateBoxFrameHighLight(-1);
 
 		if (!_characters[cbx].name[0])
 			loop = false;
 
 		if (cbx != _activeBox) {
 			_activeBox = cbx;
-			_vm->_gui->highLightBoxFrame(-1);
+			_vm->_gui->updateBoxFrameHighLight(-1);
 			if (loop)
 				printStats(_activeBox, 2);
 		}
@@ -753,8 +753,8 @@ void CharacterGenerator::statsAndFacesMenu() {
 		}
 	}
 
-	_vm->_gui->highLightBoxFrame(6 + _activeBox);
-	_vm->_gui->highLightBoxFrame(-1);
+	_vm->_gui->updateBoxFrameHighLight(6 + _activeBox);
+	_vm->_gui->updateBoxFrameHighLight(-1);
 }
 
 void CharacterGenerator::faceSelectMenu() {
@@ -769,7 +769,7 @@ void CharacterGenerator::faceSelectMenu() {
 	printStats(_activeBox, 4);
 	toggleSpecialButton(12, 0, 0);
 	toggleSpecialButton(13, 0, 0);
-	_vm->_gui->highLightBoxFrame(-1);
+	_vm->_gui->updateBoxFrameHighLight(-1);
 
 	shp = getNextFreeFaceShape(shp, charSex, 1, _chargenSelectedPortraits);
 
@@ -793,7 +793,7 @@ void CharacterGenerator::faceSelectMenu() {
 			in = _vm->checkInput(_vm->_activeButtons, false, 0);
 			_vm->removeInputTop();
 
-			_vm->_gui->highLightBoxFrame(box + 10);
+			_vm->_gui->updateBoxFrameHighLight(box + 10);
 
 			if (in == 0x8002 || in == _vm->_keyMap[Common::KEYCODE_RIGHT]) {
 				processSpecialButton(13);
@@ -813,7 +813,7 @@ void CharacterGenerator::faceSelectMenu() {
 			}
 		}
 
-		_vm->_gui->highLightBoxFrame(-1);
+		_vm->_gui->updateBoxFrameHighLight(-1);
 
 		if (in == 1)
 			shp = getNextFreeFaceShape(shp - 1, charSex, -1, _chargenSelectedPortraits);
@@ -824,7 +824,7 @@ void CharacterGenerator::faceSelectMenu() {
 	}
 
 	if (!_vm->shouldQuit()) {
-		_vm->_gui->highLightBoxFrame(-1);
+		_vm->_gui->updateBoxFrameHighLight(-1);
 		updateMagicShapes();
 
 		_chargenSelectedPortraits[_activeBox] = sp[res];
@@ -859,7 +859,7 @@ int CharacterGenerator::getNextFreeFaceShape(int shpIndex, int charSex, int step
 }
 
 void CharacterGenerator::processFaceMenuSelection(int index) {
-	_vm->_gui->highLightBoxFrame(-1);
+	_vm->_gui->updateBoxFrameHighLight(-1);
 	if (index <= 48)
 		_screen->drawShape(0, _characters[_activeBox].faceShape, _chargenBoxX[_activeBox], _chargenBoxY[_activeBox] + 1, 0);
 	else
@@ -1403,7 +1403,7 @@ const EobRect8 CharacterGenerator::_chargenButtonBodyCoords[] = {
 	{ 0x14, 0x90, 0x0B, 0x10 }
 };
 
-const EobRect16 GUI_Eob::_highLightBoxFrames[] = {
+const EobRect16 GUI_Eob::_updateBoxFrameHighLights[] = {
 	{ 0x00B7, 0x0001, 0x00F7, 0x0034 },
 	{ 0x00FF, 0x0001, 0x013F, 0x0034 },
 	{ 0x00B7, 0x0035, 0x00F7, 0x0068 },
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 7ec988e..04739c2 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -344,8 +344,6 @@ Common::Error EobCoreEngine::go() {
 	_screen->setMouseCursor(0, 0, _itemIconShapes[0]);
 	_screen->showMouse();
 
-	//initPlayBuffers
-
 	loadItemDefs();
 	int action = 0;
 
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 8b97ab3..27e0dc9 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -1006,11 +1006,13 @@ protected:
 	const char *const *_menuStringsSpellNo;
 
 	const uint8 *_spellLevelsMage;
+	int _spellLevelsMageSize;
 	const uint8 *_spellLevelsCleric;
-	const uint8 *_spellLevelsMps1;
-	const uint8 *_spellLevelsMps2;
-	const uint8 *_spellLevelsMps3;
-	const uint8 *_spellLevelsMps4;
+	int _spellLevelsClericSize;
+	const uint8 *_numSpellsCleric;
+	const uint8 *_numSpellsWisAdj;
+	const uint8 *_numSpellsPal;
+	const uint8 *_numSpellsMage;
 
 	// sound
 	void snd_playSoundEffect(int id, int volume=0xFF);
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 4fe5b6b..5d86b9c 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -1445,11 +1445,18 @@ GUI_Eob::GUI_Eob(EobCoreEngine *vm) : GUI_v1(vm), _vm(vm), _screen(vm->_screen)
 	_cflag = 0xffff;
 	
 	_menuLineSpacing = 0;
-	_menuUnk1 = 0;
+	//_menuUnk1 = 0;
 	_menuLastInFlags = 0;
 	_menuCur = 0;
 	_menuNumItems = 0;
 
+	_numPages = (_vm->game() == GI_EOB2) ? 8 : 5;
+	_numVisPages = (_vm->game() == GI_EOB2) ? 6 : 5;
+	_clericSpellAvltyFlags = (_vm->game() == GI_EOB2) ? 0xf7ffffff : 0x7bffff;
+	_paladinSpellAvltyFlags = (_vm->game() == GI_EOB2) ? 0xa9bbd1d : 0x800ff2;
+	_numAssignedSpellsOfType = new int8[72];
+	memset(_numAssignedSpellsOfType, 0, 72);
+
 	_charSelectRedraw = false;
 	
 	_updateBoxIndex = -1;
@@ -1463,6 +1470,8 @@ GUI_Eob::~GUI_Eob() {
 			delete _menuStringsPrefsTemp[i];
 		delete[] _menuStringsPrefsTemp;
 	}
+
+	delete[] _numAssignedSpellsOfType;
 }
 
 void GUI_Eob::processButton(Button *button) {
@@ -1970,7 +1979,7 @@ void GUI_Eob::simpleMenu_setup(int sd, int maxItem, const char *const *strings,
 
 	_screen->updateScreen();
 	_menuLineSpacing = lineSpacing;
-	_menuUnk1 = 0;
+	//_menuUnk1 = 0;
 	_menuLastInFlags = 0;
 	_vm->removeInputTop();
 }
@@ -2284,7 +2293,7 @@ int GUI_Eob::runLoadMenu(int x, int y) {
 	return 0;
 }
 
-void GUI_Eob::highLightBoxFrame(int box) {
+void GUI_Eob::updateBoxFrameHighLight(int box) {
 	static const uint8 colorTable[] = { 0x0F, 0xB0, 0xB2, 0xB4, 0xB6,
 		0xB8, 0xBA, 0xBC, 0x0C, 0xBC, 0xBA, 0xB8, 0xB6, 0xB4, 0xB2, 0xB0, 0x00
 	};
@@ -2299,7 +2308,7 @@ void GUI_Eob::highLightBoxFrame(int box) {
 		if (!colorTable[_updateBoxColorIndex])
 			_updateBoxColorIndex = 0;
 
-		const EobRect16 *r = &_highLightBoxFrames[_updateBoxIndex];
+		const EobRect16 *r = &_updateBoxFrameHighLights[_updateBoxIndex];
 		_screen->drawBox(r->x1, r->y1, r->x2, r->y2, colorTable[_updateBoxColorIndex++]);
 		_screen->updateScreen();
 
@@ -2307,7 +2316,7 @@ void GUI_Eob::highLightBoxFrame(int box) {
 
 	} else {
 		if (_updateBoxIndex != -1) {
-			const EobRect16 *r = &_highLightBoxFrames[_updateBoxIndex];
+			const EobRect16 *r = &_updateBoxFrameHighLights[_updateBoxIndex];
 			_screen->drawBox(r->x1, r->y1, r->x2, r->y2, 12);
 			_screen->updateScreen();
 		}
@@ -2458,9 +2467,283 @@ void GUI_Eob::runSaveMenu() {
 }
 
 void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
+	if (charIndex == -1)
+		return;
+
+	uint8 np[8];
+	memset(np, 0, sizeof(np));
+	uint32 avltyFlags = 0;
+	int li = 0;
+	int lv = 0;
+	
+	EobCharacter *c = &_vm->_characters[charIndex];
+	int8 wm = c->wisdomCur - 12;
+	if (wm < 0)
+		wm = 0;
+
+	if (spellType) {
+		li = _vm->getCharacterLevelIndex(2, c->cClass);
+		
+		if (li == -1) {
+			li = _vm->getCharacterLevelIndex(4, c->cClass);
+			
+			if (li != -1) {
+				lv = c->level[li] - 1;
+				if (lv < 0)
+					lv = 0;
+
+				for (int i = 0; i < _numPages; i++)
+					np[i] = _vm->_numSpellsPal[lv * _numPages + i];
+				
+				avltyFlags = _paladinSpellAvltyFlags;
+			}
+
+		} else {
+			lv = c->level[li] - 1;
+			for (int i = 0; i < _numPages; i++) {
+				np[i] = _vm->_numSpellsCleric[lv * _numPages + i];
+				if (np[i])
+					np[i] += _vm->_numSpellsWisAdj[wm * _numPages + i];
+			}
+			avltyFlags = _clericSpellAvltyFlags;
+		}
+
+	} else {
+		li = _vm->getCharacterLevelIndex(1, c->cClass);
+
+		if (li == -1) {
+			if (_vm->checkInventoryForRings(charIndex, 1)) {
+				np[3] <<= 1;
+				np[4] <<= 1;
+			}
+
+		} else {
+			lv = c->level[li] - 1;
+			for (int i = 0; i < _numPages; i++)
+				np[i] = _vm->_numSpellsMage[lv * _numPages + i];
+
+			avltyFlags = c->mageSpellsAvailabilityFlags;
+		}
+	}
+
+	int8 *menuSpellMap = new int8[88];
+	memset(menuSpellMap, 0, 88);
+	int8 *numAssignedSpellsPerBookPage = new int8[8];
+	memset(numAssignedSpellsPerBookPage, 0, 8);
+	memset(_numAssignedSpellsOfType, 0, 72);
+	int8 *lh = new int8[40];
+	memset(lh, 0, 40);
+
+	memcpy(lh, spellType ? _vm->_spellLevelsCleric : _vm->_spellLevelsMage, spellType ? _vm->_spellLevelsClericSize : _vm->_spellLevelsMageSize);
+	int8 *charSpellList = spellType ? c->clericSpells : c->mageSpells;
+
+	for (int i = 0; i < 80; i++) {
+		int8 s = charSpellList[i];
+		if (s == 0 || s == _vm->_spellLevelsClericSize)
+			continue;
+
+		if (s < 0)
+			s = -s;
+		else
+			_numAssignedSpellsOfType[s * 2 - 1]++;
+
+		s--;
+		_numAssignedSpellsOfType[s * 2]++;
+		numAssignedSpellsPerBookPage[lh[s] - 1]++;
+	}
+
+	for (int i = 0; i < 32; i++) {
+		if (!(avltyFlags & (1 << i)))
+			continue;
+		
+		int d = lh[i] - 1;
+		if (d < 0)
+			continue;
+
+		if (!spellType || (spellType && np[d])) {
+			menuSpellMap[d * 11]++;
+			menuSpellMap[d * 11 + menuSpellMap[d * 11]] = i + 1;
+		}
+	}
+
+	Button *buttonList = initMenu(4);
+
+	int lastHighLightText = -1;
+	int lastHighLightButton = -1;
+	int newHighLightButton = 0;
+	int newHighLightText = 0;
+	bool updateDesc = true;
+	bool updateList = true;
+
+	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
+		updateBoxFrameHighLight(charIndex);
+
+		if (newHighLightButton < 0)
+			newHighLightButton = 7;
+		if (newHighLightButton > 7)
+			newHighLightButton = 0;
+
+		Button *b = 0;
+
+		if (lastHighLightButton != newHighLightButton) {
+			if (lastHighLightButton >= 0)
+				drawMenuButton(_vm->gui_getButton(buttonList, lastHighLightButton + 26), false, false, true);
+			drawMenuButton(_vm->gui_getButton(buttonList, newHighLightButton + 26), false, true, true);
+			newHighLightText = 0;
+			lastHighLightText = -1;
+			lastHighLightButton = newHighLightButton;
+			updateDesc = updateList = true;
+		}
+
+		if (updateList) {
+			updateList = false;
+			_screen->setCurPage(2);
+			for (int ii = 1; ii < 9; ii++)
+				memorizePrayMenuPrintString(menuSpellMap[lastHighLightButton * 11 + ii], ii - 1, spellType, false, false);
+
+			_screen->setCurPage(0);
+			_screen->copyRegion(0, 50, 0, 50, 176, 72, 2, 0, Screen::CR_NO_P_CHECK);
+			lastHighLightText = -1;
+		}
+
+		if (updateDesc) {
+			updateDesc = false;
+			_screen->printShadedText(Common::String::format(_vm->_menuStringsMgc[1], np[lastHighLightButton] - numAssignedSpellsPerBookPage[lastHighLightButton], np[lastHighLightButton]).c_str(), 8, 38, 9, _vm->_bkgColor_1);		
+		}
+
+		if (newHighLightText < 0)
+			newHighLightText = menuSpellMap[lastHighLightButton * 11] - 1;
+
+		if (menuSpellMap[lastHighLightButton * 11] <= newHighLightText)
+			newHighLightText = 0;
+		
+		if (newHighLightText != lastHighLightText) {
+			memorizePrayMenuPrintString(menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1], lastHighLightText, spellType, true, false);
+			memorizePrayMenuPrintString(menuSpellMap[lastHighLightButton * 11 + newHighLightText + 1], newHighLightText, spellType, true, true);
+			lastHighLightText = newHighLightText;
+		}
+		
+		int inputFlag = _vm->checkInput(buttonList, false, 0) & 0x80ff;
+		_vm->removeInputTop();
+
+		if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP6] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT]) {
+			inputFlag = 0x801a + ((lastHighLightButton + 1) % _numVisPages);
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT]) {
+			inputFlag = lastHighLightButton ? 0x8019 + lastHighLightButton : 0x8019 + _numVisPages;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE]) {
+			inputFlag = 0x8018;
+		} else {
+			Common::Point p = _vm->getMousePos();
+			if (_vm->posWithinRect(p.x, p.y, 8, 50, 168, 122)) {
+				newHighLightText = (p.y - 50 ) / 9;
+				if (menuSpellMap[lastHighLightButton * 11] - 1 < newHighLightText)
+					newHighLightText = menuSpellMap[lastHighLightButton * 11] - 1;
+			}			
+		}
+
+		if (inputFlag & 0x8000) {
+			Button *b = _vm->gui_getButton(buttonList, inputFlag & 0x7fff);
+			drawMenuButton(b, true, true, true);
+			_screen->updateScreen();
+			_vm->_system->delayMillis(80);
+			drawMenuButton(b, false, false, true);
+			_screen->updateScreen();
+		}
 
+		if (inputFlag == 0x8019 || inputFlag == _vm->_keyMap[Common::KEYCODE_KP_PLUS] || inputFlag == _vm->_keyMap[Common::KEYCODE_PLUS] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP5] || inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
+			if (np[lastHighLightButton] > numAssignedSpellsPerBookPage[lastHighLightButton] && lastHighLightText != -1) {
+				_numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1] * 2 - 2]++;
+				numAssignedSpellsPerBookPage[lastHighLightButton]++;
+				memorizePrayMenuPrintString(menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1], lastHighLightText, spellType, false, true);
+				updateDesc = true;
+			}
+
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP_MINUS] || inputFlag == _vm->_keyMap[Common::KEYCODE_MINUS] /*|| inputFlag == _vm->_keyMap[Common::KEYCODE_*/) {
+			if (np[lastHighLightButton] && _numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1] * 2 - 2]) {
+				_numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1] * 2 - 2]--;
+				numAssignedSpellsPerBookPage[lastHighLightButton]--;
+				memorizePrayMenuPrintString(menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1], lastHighLightText, spellType, false, true);
+				updateDesc = true;
+			}
+
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP8]) {
+			newHighLightText = lastHighLightText - 1;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP2]) {
+			newHighLightText = lastHighLightText + 1;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_END] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP1]) {
+			newHighLightText = menuSpellMap[lastHighLightButton * 11] - 1;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_HOME] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP7]) {
+			newHighLightText = 0;
+		} else if (inputFlag == 0x8017) {
+			if (numAssignedSpellsPerBookPage[lastHighLightButton]) {
+				for (int i = 1; i <= menuSpellMap[lastHighLightButton * 11]; i++) {				
+					numAssignedSpellsPerBookPage[lastHighLightButton] -= _numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + i] * 2 - 2];
+					_numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + i] * 2 - 2] = 0;
+				}
+
+				updateDesc = updateList = true;
+			}
+
+		} else if (inputFlag == 0x8018) {
+			_vm->gui_drawAllCharPortraitsWithStats();
+			runLoop = false;
+
+		} else if (inputFlag & 0x8000) {
+			newHighLightButton = inputFlag - 0x801a;
+			if (newHighLightButton == lastHighLightButton)
+				drawMenuButton(_vm->gui_getButton(buttonList, inputFlag & 0x7fff), false, true, true);
+		}
+	}
+
+	releaseButtons(buttonList);
+	updateBoxFrameHighLight(-1);
+
+	_screen->setFont(Screen::FID_6_FNT);
+	_vm->gui_drawCharPortraitWithStats(charIndex);
+	_screen->setFont(Screen::FID_8_FNT);
+
+	memset(charSpellList, 0, 80);
+	if (spellType)
+		charSpellList[0] = _vm->_spellLevelsClericSize;
+
+	for (int i = 0; i < 32; i++) {
+		if (_numAssignedSpellsOfType[i * 2] < _numAssignedSpellsOfType[i * 2 + 1])
+			_numAssignedSpellsOfType[i * 2 + 1] = _numAssignedSpellsOfType[i * 2];
+
+		if (_numAssignedSpellsOfType[i * 2 + 1]) {
+			_numAssignedSpellsOfType[i * 2]--;
+			_numAssignedSpellsOfType[i * 2 + 1]--;
+
+			int pg = lh[i] - 1;
+			for (int ii = 0; ii < 10; ii++) {
+				if (!charSpellList[pg * 10 + ii]) {
+					charSpellList[pg * 10 + ii] = i + 1;
+					break;
+				}
+			}
+			i--;
+
+		} else if (_numAssignedSpellsOfType[i * 2]) {
+			_numAssignedSpellsOfType[i * 2]--;
+
+			_vm->_resting = true;
+			int pg = lh[i] - 1;
+			for (int ii = 0; ii < 10; ii++) {
+				if (!charSpellList[pg * 10 + ii]) {
+					charSpellList[pg * 10 + ii] = -(i + 1);
+					break;
+				}
+			}
+			i--;
+		}
+	}
+
+	delete[] menuSpellMap;
+	delete[] numAssignedSpellsPerBookPage;
+	delete[] lh;
 }
 
+
 void GUI_Eob::scribeScrollDialogue() {
 	
 }
@@ -2606,10 +2889,10 @@ int GUI_Eob::selectCharacterDialogue(int id) {
 		int inputFlag = _vm->checkInput(buttonList, false, 0);
 		_vm->removeInputTop();
 		
-		highLightBoxFrame(hlCur);
+		updateBoxFrameHighLight(hlCur);
 
 		if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP8] || inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_a] || inputFlag == _vm->_keyMap[Common::KEYCODE_w]) {
-			highLightBoxFrame(-1);
+			updateBoxFrameHighLight(-1);
 			_vm->gui_drawCharPortraitWithStats(hlCur--);
 			if (hlCur < 0)
 				hlCur = 5;
@@ -2619,7 +2902,7 @@ int GUI_Eob::selectCharacterDialogue(int id) {
 			}
 
 		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP6] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP2] || inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_z] || inputFlag == _vm->_keyMap[Common::KEYCODE_s]) {
-			highLightBoxFrame(-1);
+			updateBoxFrameHighLight(-1);
 			_vm->gui_drawCharPortraitWithStats(hlCur++);
 			if (hlCur == 6)
 				hlCur = 0;
@@ -2649,7 +2932,7 @@ int GUI_Eob::selectCharacterDialogue(int id) {
 		}
 	}
 
-	highLightBoxFrame(-1);
+	updateBoxFrameHighLight(-1);
 	if (hlCur >= 0)
 		_vm->gui_drawCharPortraitWithStats(hlCur);
 
@@ -2718,7 +3001,10 @@ Button *GUI_Eob::initMenu(int id) {
 	for (int i = 0; i < m->numButtons; i++) {
 		const EobMenuButtonDef *df = &_vm->_menuButtonDefs[m->firstButtonStrId + i];
 		Button *b = new Button;
-		b->index = m->firstButtonStrId + i + 1;		
+		b->index = m->firstButtonStrId + i + 1;
+		if (id == 4 && _vm->game() == GI_EOB1)
+			b->index -= 14;
+
 		b->data0Val2 = 12;
 		b->data1Val2 = b->data2Val2 = 15;
 		b->data3Val2 = 8;
@@ -2782,6 +3068,24 @@ void GUI_Eob::drawMenuButtonBox(int x, int y, int w, int h, bool clicked, bool n
 	_vm->gui_drawBox(x + 1, y + 1, w - 2, h - 2, _vm->_color1_1, _vm->_color2_1, noFill ? -1 : _vm->_bkgColor_1);
 }
 
+void GUI_Eob::memorizePrayMenuPrintString(int spellId, int bookPageIndex, int spellType, bool noFill, bool highLight) {
+	if (bookPageIndex < 0)
+		return;
+
+	int y = bookPageIndex * 9 + 50;
+
+	if (spellId) {
+		Common::String s(Common::String::format(_vm->_menuStringsMgc[0], spellType ? _vm->_clericSpellList[spellId] : _vm->_mageSpellList[spellId], _numAssignedSpellsOfType[spellId * 2 - 2]));
+		if (noFill)
+			_screen->printText(s.c_str(), 8, y, highLight ? 6 : 15, 0);
+		else
+			_screen->printShadedText(s.c_str(), 8, y, highLight ? 6 : 15, _vm->_bkgColor_1);
+
+	} else {
+		_screen->fillRect(6, y, 168, y + 8,  _vm->_bkgColor_1);
+	}
+}
+
 void GUI_Eob::updateOptionsStrings() {
 	for (int i = 0; i < 4; i++) {
 		delete _menuStringsPrefsTemp[i];
diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h
index bb446f7..6d4edfd 100644
--- a/engines/kyra/gui_eob.h
+++ b/engines/kyra/gui_eob.h
@@ -62,7 +62,7 @@ public:
 	void runCampMenu();
 	int runLoadMenu(int x, int y);
 
-	void highLightBoxFrame(int box);
+	void updateBoxFrameHighLight(int box);
 
 	int getTextInput(char *dest, int x, int y, int destMaxLen, int textColor1, int textColor2, int cursorColor);
 
@@ -89,6 +89,7 @@ private:
 	Button *initMenu(int id);	
 	void drawMenuButton(Button *b, bool clicked, bool highlight, bool noFill);
 	void drawMenuButtonBox(int x, int y, int w, int h, bool clicked, bool noFill);
+	void memorizePrayMenuPrintString(int spellId, int bookPageIndex, int spellType, bool noFill, bool highLight);
 	void updateOptionsStrings();
 	const char *getMenuString(int id);
 
@@ -118,9 +119,15 @@ private:
 	Button::Callback _scrollDownFunctor;
 
 	int _menuLineSpacing;
-	int _menuUnk1;
+	//int _menuUnk1;
 	int _menuLastInFlags;
 
+	uint8 _numPages;
+	uint8 _numVisPages;
+	int8 *_numAssignedSpellsOfType;
+	uint32 _clericSpellAvltyFlags;
+	uint32 _paladinSpellAvltyFlags;
+
 	int _menuCur;
 	int _menuNumItems;
 	bool _charSelectRedraw;
@@ -128,7 +135,7 @@ private:
 	int _updateBoxIndex;
 	int _updateBoxColorIndex;
 	uint32 _highLightBoxTimer;
-	static const EobRect16 _highLightBoxFrames[];
+	static const EobRect16 _updateBoxFrameHighLights[];
 
 	// unused
 	Button *getButtonListData() { return 0; }
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 8b6de92..77971da 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -201,6 +201,7 @@ void EobCoreEngine::castSpell(int spell, int weaponSlot) {
 }
 
 void EobCoreEngine::removeCharacterEffect(int spell, int charIndex, int showWarning) {
+	assert(spell >= 0);
 	EobCharacter *c = &_characters[charIndex];
 	EobSpell *s = &_spells[spell];
 
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 5d9554c..441199c 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -323,10 +323,10 @@ enum KyraResources {
 
 	kEobBaseSpellLevelsMage,
 	kEobBaseSpellLevelsCleric,
-	kEobBaseSpellMps1,
-	kEobBaseSpellMps2,
-	kEobBaseSpellMps3,
-	kEobBaseSpellMps4,
+	kEobBaseNumSpellsCleric,
+	kEobBaseNumSpellsWisAdj,
+	kEobBaseNumSpellsPal,
+	kEobBaseNumSpellsMage,
 
 	kEobBaseCharGuiStringsHp,
 	kEobBaseCharGuiStringsWp1,
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index 85b94cd..497be6f 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -352,6 +352,8 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 	}
 
 	if (_saveLoadMode != -1) {
+		if (_flags.gameID == GI_EOB1)
+			_screen->loadPalette("EOBPAL.COL", _screen->getPalette(0));
 		loadLevel(_currentLevel, _currentSub);
 		_sceneUpdateRequired = true;
 		_screen->setFont(Screen::FID_6_FNT);
@@ -395,7 +397,6 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName,
 
 	for (int i = 0; i < 6; i++) {
 		timerSpecialCharacterUpdate(0x30 + i);
-		uint32 ct = _system->getMillis();
 		EobCharacter *c = &_characters[i];
 
 		out->writeByte(c->id);
@@ -432,8 +433,9 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName,
 		out->writeUint32BE(c->mageSpellsAvailabilityFlags);
 		for (int ii = 0; ii < 27; ii++)
 			out->writeSint16BE(c->inventory[ii]);
+		uint32 ct = _system->getMillis();
 		for (int ii = 0; ii < 10; ii++)
-			out->writeUint32BE(c->timers[ii] ? c->timers[ii] - ct : 0);
+			out->writeUint32BE((c->timers[ii] && c->timers[ii] > ct) ? c->timers[ii] - ct : 0);
 
 		out->write(c->events, 10);
 		out->write(c->effectsRemainder, 4);
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index 56bf352..e92d813 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -740,10 +740,9 @@ Common::String EobCoreEngine::initLevelData(int sub){
 			pos += 11;
 			_screen->setShapeFadeMode(0, false);
 			_screen->setShapeFadeMode(1, false);
-		} ////////////////////
+		}
 		else
 			_screen->loadPalette(tmpStr.c_str(), _screen->getPalette(0));
-		////////////////////7
 
 		Palette backupPal(256);
 		backupPal.copy(_screen->getPalette(0), 224, 32, 224);
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 7908bc2..e348ef2 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -388,12 +388,12 @@ void EobCoreEngine::initStaticResource() {
 	_menuStringsSpec = _staticres->loadStrings(kEobBaseMenuStringsSpec, temp);
 	_menuStringsSpellNo = _staticres->loadStrings(kEobBaseMenuStringsSpellNo, temp);
 
-	_spellLevelsMage = _staticres->loadRawData(kEobBaseSpellLevelsMage, temp);
-	_spellLevelsCleric = _staticres->loadRawData(kEobBaseSpellLevelsCleric, temp);
-	_spellLevelsMps1 = _staticres->loadRawData(kEobBaseSpellMps1, temp);
-	_spellLevelsMps2 = _staticres->loadRawData(kEobBaseSpellMps2, temp);
-	_spellLevelsMps3 = _staticres->loadRawData(kEobBaseSpellMps3, temp);
-	_spellLevelsMps4 = _staticres->loadRawData(kEobBaseSpellMps4, temp);
+	_spellLevelsMage = _staticres->loadRawData(kEobBaseSpellLevelsMage, _spellLevelsMageSize);
+	_spellLevelsCleric = _staticres->loadRawData(kEobBaseSpellLevelsCleric, _spellLevelsClericSize);
+	_numSpellsCleric = _staticres->loadRawData(kEobBaseNumSpellsCleric, temp);
+	_numSpellsWisAdj = _staticres->loadRawData(kEobBaseNumSpellsWisAdj, temp);
+	_numSpellsPal = _staticres->loadRawData(kEobBaseNumSpellsPal, temp);
+	_numSpellsMage = _staticres->loadRawData(kEobBaseNumSpellsMage, temp);
 
 	_characterGuiStringsHp = _staticres->loadStrings(kEobBaseCharGuiStringsHp, temp);
 	_characterGuiStringsWp = _staticres->loadStrings(_flags.gameID == GI_EOB2 ? kEobBaseCharGuiStringsWp2 : kEobBaseCharGuiStringsWp1, temp);
@@ -656,7 +656,17 @@ void EobCoreEngine::initMenus() {
 		{  38,  16,  57,  32,  14,  22,  7  },
 		{  39, 128,  57,  32,  14,  51,  7  },
 		{  8,  128, 126,  40,  14,  19,  7  },
-		{  0,    0,  50, 168,  72,  61,  0  }
+		{  0,    0,  50, 168,  72,  61,  0  },
+		// EOB 1 memorize/pray menu:
+		{  36,   8, 126,  48,  14,  48,  5  },
+		{  8,  128, 126,  40,  14,  19,  5  },
+		{  0,    0,  50, 168,  72,  61,  0  },
+		{  31,   8,  16,  24,  20,   2,  5  },
+		{  32,  40,  16,  24,  20,   3,  5  },
+		{  33,  72,  16,  24,  20,   4,  5  },
+		{  34, 104,  16,  24,  20,   5,  5  },
+		{  35, 136,  16,  24,  20,   6,  5  },
+		{  31,   8,  16,  24,  20,   2,  5  }
 	};
 
 	_menuButtonDefs = buttonDefs;
@@ -674,6 +684,12 @@ void EobCoreEngine::initMenus() {
 	delete[] _menuDefs;
 	_menuDefs = new EobMenuDef[ARRAYSIZE(menuDefs)];
 	memcpy(_menuDefs, menuDefs, sizeof(menuDefs));
+	
+	if (_flags.gameID == GI_EOB1) {
+		// assign EOB 1 style memorize/pray menu
+		_menuDefs[4].numButtons = 8;
+		_menuDefs[4].firstButtonStrId = 36;
+	}
 }
 
 
diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp
index 70b89be..f6e8b63 100644
--- a/engines/kyra/timer_eob.cpp
+++ b/engines/kyra/timer_eob.cpp
@@ -264,7 +264,7 @@ void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
 		int evt = c->events[i];
 
 		if (evt < 0) {
-			removeCharacterEffect(evt, charIndex, 1);
+			removeCharacterEffect(-evt, charIndex, 1);
 			continue;
 		}
 


Commit: 76bfcf834d73a9578164842ed5ab8e1eff2814e8
    https://github.com/scummvm/scummvm/commit/76bfcf834d73a9578164842ed5ab8e1eff2814e8
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:12-08:00

Commit Message:
KYRA: (EOB) - some refactoring

Changed paths:
  A engines/kyra/gui_v1.cpp
  A engines/kyra/gui_v1.h
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui.cpp
    engines/kyra/gui.h
    engines/kyra/gui_eob.cpp
    engines/kyra/gui_eob.h
    engines/kyra/gui_lok.h
    engines/kyra/gui_lol.cpp
    engines/kyra/gui_lol.h
    engines/kyra/gui_v2.h
    engines/kyra/kyra_hof.h
    engines/kyra/kyra_lok.h
    engines/kyra/kyra_mr.h
    engines/kyra/kyra_v1.cpp
    engines/kyra/kyra_v1.h
    engines/kyra/kyra_v2.h
    engines/kyra/lol.cpp
    engines/kyra/lol.h
    engines/kyra/loleobbase.h
    engines/kyra/module.mk
    engines/kyra/staticres_eob.cpp



diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 04739c2..0cc2f5a 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -47,7 +47,6 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_runFlag = true;
 	_saveLoadMode = 0;
 	_configMouse = true;
-	_resting = false;
 
 	_largeItemShapes = _smallItemShapes = _thrownItemShapes = _spellShapes = _firebeamShapes = _itemIconShapes =
 		_wallOfForceShapes = _teleporterShapes = _sparkShapes = _compassShapes = 0;
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 27e0dc9..0f9210e 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -251,7 +251,7 @@ public:
 	virtual ~EobCoreEngine();
 
 	Screen *screen() { return _screen; }
-	GUI_v1 *gui() const { return _gui; }
+	GUI *gui() const { return _gui; }
 
 protected:
 	// Startup
@@ -786,8 +786,7 @@ protected:
 	void releaseMonsterTempData(LevelTempData *tmp);
 
 	int _saveLoadMode;
-	bool _resting;
-
+	
 	Screen_Eob *_screen;
 	GUI_Eob *_gui;
 
diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp
index 3a5d798..4746163 100644
--- a/engines/kyra/gui.cpp
+++ b/engines/kyra/gui.cpp
@@ -20,352 +20,33 @@
  *
  */
 
-#include "kyra/gui.h"
 
-#include "kyra/text.h"
-#include "kyra/wsamovie.h"
+#include "kyra/gui.h"
+#include "kyra/kyra_v1.h"
+#include "kyra/util.h"
 
 #include "common/savefile.h"
 #include "common/system.h"
 
-namespace Kyra {
-
-GUI_v1::GUI_v1(KyraEngine_v1 *kyra)
-	: _vm(kyra), _screen(kyra->screen()), _text(kyra->text()) {
-	_menuButtonList = 0;
-
-	_redrawButtonFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::redrawButtonCallback);
-	_redrawShadedButtonFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::redrawShadedButtonCallback);
-}
-
-Button *GUI_v1::addButtonToList(Button *list, Button *newButton) {
-	if (!newButton)
-		return list;
-
-	newButton->nextButton = 0;
-
-	if (list) {
-		Button *cur = list;
-		while (cur->nextButton)
-			cur = cur->nextButton;
-		cur->nextButton = newButton;
-	} else {
-		list = newButton;
-	}
-
-	return list;
-}
-
-void GUI_v1::initMenuLayout(Menu &menu) {
-	if (menu.x == -1)
-		menu.x = (320 - menu.width) >> 1;
-	if (menu.y == -1)
-		menu.y = (200 - menu.height) >> 1;
-
-	for (int i = 0; i < menu.numberOfItems; ++i) {
-		if (menu.item[i].x == -1)
-			menu.item[i].x = (menu.width - menu.item[i].width) >> 1;
-	}
-}
-
-void GUI_v1::initMenu(Menu &menu) {
-	_menuButtonList = 0;
-
-	_screen->hideMouse();
-
-	int textX;
-	int textY;
-
-	int menu_x2 = menu.width  + menu.x - 1;
-	int menu_y2 = menu.height + menu.y - 1;
-
-	_screen->fillRect(menu.x + 2, menu.y + 2, menu_x2 - 2, menu_y2 - 2, menu.bkgdColor);
-	_screen->drawShadedBox(menu.x, menu.y, menu_x2, menu_y2, menu.color1, menu.color2);
-
-	if (menu.titleX != -1)
-		textX = menu.titleX;
-	else
-		textX = getMenuCenterStringX(getMenuTitle(menu), menu.x, menu_x2);
 
-	textY = menu.y + menu.titleY;
-
-	if (_vm->game() == GI_LOL) {
-		printMenuText(getMenuTitle(menu), textX, textY, menu.textColor, 0, 9);
-	} else {
-		if (_vm->gameFlags().platform != Common::kPlatformAmiga)
-			printMenuText(getMenuTitle(menu), textX - 1, textY + 1, defaultColor1(), defaultColor2(), 0);
-		printMenuText(getMenuTitle(menu), textX, textY, menu.textColor, 0, 0);
-	}
-
-	int x1, y1, x2, y2;
-	for (int i = 0; i < menu.numberOfItems; ++i) {
-		if (!menu.item[i].enabled)
-			continue;
-
-		x1 = menu.x + menu.item[i].x;
-		y1 = menu.y + menu.item[i].y;
-
-		x2 = x1 + menu.item[i].width - 1;
-		y2 = y1 + menu.item[i].height - 1;
-
-		if (i < 7) {
-			Button *menuButtonData = getButtonListData() + i;
-			menuButtonData->nextButton = 0;
-			menuButtonData->x = x1;
-			menuButtonData->y = y1;
-			menuButtonData->width  = menu.item[i].width - 1;
-			menuButtonData->height = menu.item[i].height - 1;
-			menuButtonData->buttonCallback = menu.item[i].callback;
-			menuButtonData->keyCode = menu.item[i].keyCode;
-			menuButtonData->keyCode2 = 0;
-			menuButtonData->arg = menu.item[i].itemId;
-
-			_menuButtonList = addButtonToList(_menuButtonList, menuButtonData);
-		}
-
-		_screen->fillRect(x1, y1, x2, y2, menu.item[i].bkgdColor);
-		_screen->drawShadedBox(x1, y1, x2, y2, menu.item[i].color1, menu.item[i].color2);
-
-		if (getMenuItemTitle(menu.item[i])) {
-			if (menu.item[i].titleX != -1)
-				textX = x1 + menu.item[i].titleX + 3;
-			else
-				textX = getMenuCenterStringX(getMenuItemTitle(menu.item[i]), x1, x2);
-
-			textY = y1 + 2;
-			if (_vm->game() == GI_LOL) {
-				textY++;
-				if (i == menu.highlightedItem)
-					printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 8);
-				else
-					printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 8);
-			} else {
-				Screen::FontId of = _screen->_currentFont;
-				if (menu.item[i].saveSlot > 0)
-					_screen->setFont(Screen::FID_8_FNT);
-
-				if (_vm->gameFlags().platform != Common::kPlatformAmiga)
-					printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
-
-				if (i == menu.highlightedItem)
-					printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 0);
-				else
-					printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 0);
-
-				_screen->setFont(of);
-			}
-		}
-	}
-
-	for (int i = 0; i < menu.numberOfItems; ++i) {
-		if (getMenuItemLabel(menu.item[i])) {
-			if (_vm->game() == GI_LOL) {
-				menu.item[i].labelX = menu.item[i].x - 1;
-				menu.item[i].labelY = menu.item[i].y + 3;
-				printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX, menu.y + menu.item[i].labelY, menu.item[i].textColor, 0, 10);
-			} else {
-				if (_vm->gameFlags().platform != Common::kPlatformAmiga)
-					printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX - 1, menu.y + menu.item[i].labelY + 1, defaultColor1(), 0, 0);
-				printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX, menu.y + menu.item[i].labelY, menu.item[i].textColor, 0, 0);
-			}
-		}
-	}
-
-	if (menu.scrollUpButtonX != -1) {
-		Button *scrollUpButton = getScrollUpButton();
-		scrollUpButton->x = menu.scrollUpButtonX + menu.x;
-		scrollUpButton->y = menu.scrollUpButtonY + menu.y;
-		scrollUpButton->buttonCallback = getScrollUpButtonHandler();
-		scrollUpButton->nextButton = 0;
-		scrollUpButton->mouseWheel = -1;
-
-		_menuButtonList = addButtonToList(_menuButtonList, scrollUpButton);
-		updateMenuButton(scrollUpButton);
-
-		Button *scrollDownButton = getScrollDownButton();
-		scrollDownButton->x = menu.scrollDownButtonX + menu.x;
-		scrollDownButton->y = menu.scrollDownButtonY + menu.y;
-		scrollDownButton->buttonCallback = getScrollDownButtonHandler();
-		scrollDownButton->nextButton = 0;
-		scrollDownButton->mouseWheel = 1;
-
-		_menuButtonList = addButtonToList(_menuButtonList, scrollDownButton);
-		updateMenuButton(scrollDownButton);
-	}
-
-	_screen->showMouse();
-	_screen->updateScreen();
-}
-
-void GUI_v1::processHighlights(Menu &menu) {
-	int x1, y1, x2, y2;
-	Common::Point p = _vm->getMousePos();
-	int mouseX = p.x;
-	int mouseY = p.y;
-
-	if (_vm->game() == GI_LOL && menu.highlightedItem != 255) {
-		// LoL doesnt't have default highlighted items.
-		// We use a highlightedItem value of 255 for this.
-
-		// With LoL no highlighting should take place unless the
-		// mouse cursor moves over a button. The highlighting should end
-		// when the mouse cursor leaves the button.
-		if (menu.item[menu.highlightedItem].enabled)
-			redrawText(menu);
-	}
-
-	for (int i = 0; i < menu.numberOfItems; ++i) {
-		if (!menu.item[i].enabled)
-			continue;
-
-		x1 = menu.x + menu.item[i].x;
-		y1 = menu.y + menu.item[i].y;
-
-		x2 = x1 + menu.item[i].width;
-		y2 = y1 + menu.item[i].height;
-
-		if (mouseX > x1 && mouseX < x2 &&
-			mouseY > y1 && mouseY < y2) {
-
-			if (menu.highlightedItem != i || _vm->game() == GI_LOL) {
-				if (_vm->game() != GI_LOL) {
-					if (menu.item[menu.highlightedItem].enabled)
-						redrawText(menu);
-				}
-
-				menu.highlightedItem = i;
-				redrawHighlight(menu);
-			}
-		}
-	}
-
-	_screen->updateScreen();
-}
-
-void GUI_v1::redrawText(const Menu &menu) {
-	int textX;
-	int i = menu.highlightedItem;
-
-	int x1 = menu.x + menu.item[i].x;
-	int y1 = menu.y + menu.item[i].y;
-
-	int x2 = x1 + menu.item[i].width - 1;
-
-	if (menu.item[i].titleX >= 0)
-		textX = x1 + menu.item[i].titleX + 3;
-	else
-		textX = getMenuCenterStringX(getMenuItemTitle(menu.item[i]), x1, x2);
+namespace Kyra {
 
-	int textY = y1 + 2;
-	if (_vm->game() == GI_LOL) {
-		textY++;
-		printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 8);
-	} else {
-		Screen::FontId of = _screen->_currentFont;
-		if (menu.item[i].saveSlot > 0)
-			_screen->setFont(Screen::FID_8_FNT);
-		if (_vm->gameFlags().platform != Common::kPlatformAmiga)
-			printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
-		printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 0);
-		_screen->setFont(of);
-	}
+GUI::GUI(KyraEngine_v1 *kyra) : _vm(kyra), _screen(kyra->screen()) {
+	_savegameListUpdateNeeded = false;
+	_savegameListSize = 0;
+	_savegameList = 0;
 }
 
-void GUI_v1::redrawHighlight(const Menu &menu) {
-	int textX;
-	int i = menu.highlightedItem;
-
-	int x1 = menu.x + menu.item[i].x;
-	int y1 = menu.y + menu.item[i].y;
-
-	int x2 = x1 + menu.item[i].width - 1;
-
-	if (menu.item[i].titleX != -1)
-		textX = x1 + menu.item[i].titleX + 3;
-	else
-		textX = getMenuCenterStringX(getMenuItemTitle(menu.item[i]), x1, x2);
-
-	int textY = y1 + 2;
-
-	if (_vm->game() == GI_LOL) {
-		textY++;
-		printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 8);
-	} else {
-		Screen::FontId of = _screen->_currentFont;
-		if (menu.item[i].saveSlot > 0)
-			_screen->setFont(Screen::FID_8_FNT);
-		if (_vm->gameFlags().platform != Common::kPlatformAmiga)
-			printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
-		printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 0);
-		_screen->setFont(of);
+GUI::~GUI() {
+	if (_savegameList) {
+		for (int i = 0; i < _savegameListSize; i++)
+			delete[] _savegameList[i];
+		delete[] _savegameList;
+		_savegameList = 0;
 	}
 }
 
-void GUI_v1::updateAllMenuButtons() {
-	for (Button *cur = _menuButtonList; cur; cur = cur->nextButton)
-		updateMenuButton(cur);
-}
-
-void GUI_v1::updateMenuButton(Button *button) {
-	if (!_displayMenu)
-		return;
-
-	_screen->hideMouse();
-	updateButton(button);
-	_screen->updateScreen();
-	_screen->showMouse();
-}
-
-void GUI_v1::updateButton(Button *button) {
-	if (!button || (button->flags & 8))
-		return;
-
-	if (button->flags2 & 1)
-		button->flags2 &= 0xFFF7;
-	else
-		button->flags2 |= 8;
-
-	button->flags2 &= 0xFFFC;
-
-	if (button->flags2 & 4)
-		button->flags2 |= 0x10;
-	else
-		button->flags2 &= 0xEEEF;
-
-	button->flags2 &= 0xFFFB;
-
-	processButton(button);
-}
-
-int GUI_v1::redrawButtonCallback(Button *button) {
-	if (!_displayMenu)
-		return 0;
-
-	_screen->hideMouse();
-	if (_vm->gameFlags().platform == Common::kPlatformAmiga)
-		_screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 17);
-	else
-		_screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 0xF8);
-	_screen->showMouse();
-
-	return 0;
-}
-
-int GUI_v1::redrawShadedButtonCallback(Button *button) {
-	if (!_displayMenu)
-		return 0;
-
-	_screen->hideMouse();
-	if (_vm->gameFlags().platform == Common::kPlatformAmiga)
-		_screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 31, 18);
-	else
-		_screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 0xF9, 0xFA);
-	_screen->showMouse();
-
-	return 0;
-}
-
-void GUI_v1::updateSaveList(bool excludeQuickSaves) {
+void GUI::updateSaveList(bool excludeQuickSaves) {
 	Common::String pattern = _vm->_targetName + ".???";
 	Common::StringArray saveFileList = _vm->_saveFileMan->listSavefiles(pattern);
 	_saveSlots.clear();
@@ -391,13 +72,13 @@ void GUI_v1::updateSaveList(bool excludeQuickSaves) {
 	sortSaveSlots();
 }
 
-void GUI_v1::sortSaveSlots() {
+void GUI::sortSaveSlots() {
 	Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Less<int>());
 	if (_saveSlots.size() > 2)
 		Common::sort(_saveSlots.begin()+1, _saveSlots.end(), Common::Greater<int>());
 }
 
-int GUI_v1::getNextSavegameSlot() {
+int GUI::getNextSavegameSlot() {
 	Common::InSaveFile *in;
 
 	int start = _vm->game() == GI_LOL ? 0 : 1;
@@ -412,266 +93,47 @@ int GUI_v1::getNextSavegameSlot() {
 	return 0;
 }
 
-void GUI_v1::checkTextfieldInput() {
-	Common::Event event;
-
-	uint32 now = _vm->_system->getMillis();
-
-	bool running = true;
-	int keys = 0;
-	while (running && _vm->_eventMan->pollEvent(event)) {
-		switch (event.type) {
-		case Common::EVENT_KEYDOWN:
-			if (event.kbd.keycode == Common::KEYCODE_q && event.kbd.hasFlags(Common::KBD_CTRL))
-				_vm->quitGame();
-			else
-				_keyPressed = event.kbd;
-			running = false;
-			break;
-
-		case Common::EVENT_LBUTTONDOWN:
-		case Common::EVENT_LBUTTONUP: {
-			Common::Point pos = _vm->getMousePos();
-			_vm->_mouseX = pos.x;
-			_vm->_mouseY = pos.y;
-			keys = event.type == Common::EVENT_LBUTTONDOWN ? 199 : (200 | 0x800);
-			running = false;
-			} break;
-
-		case Common::EVENT_MOUSEMOVE: {
-			Common::Point pos = _vm->getMousePos();
-			_vm->_mouseX = pos.x;
-			_vm->_mouseY = pos.y;
-
-			_vm->_system->updateScreen();
-			_lastScreenUpdate = now;
-			} break;
-
-		default:
-			break;
-		}
-	}
-
-	if (now - _lastScreenUpdate > 50) {
-		_vm->_system->updateScreen();
-		_lastScreenUpdate = now;
-	}
-
-	processButtonList(_menuButtonList, keys | 0x8000, 0);
-	_vm->_system->delayMillis(3);
-}
-
-void GUI_v1::printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2) {
-	_text->printText(str, x, y, c0, c1, c2);
-}
-
-int GUI_v1::getMenuCenterStringX(const char *str, int x1, int x2) {
-	return _text->getCenterStringX(str, x1, x2);
-}
-
-#pragma mark -
-
-MainMenu::MainMenu(KyraEngine_v1 *vm) : _vm(vm), _screen(0) {
-	_screen = _vm->screen();
-	_nextUpdate = 0;
-	_system = g_system;
-}
-
-void MainMenu::init(StaticData data, Animation anim) {
-	_static = data;
-	_anim = anim;
-	_animIntern.curFrame = _anim.startFrame;
-	_animIntern.direction = 1;
-}
-
-void MainMenu::updateAnimation() {
-	if (_anim.anim) {
-		uint32 now = _system->getMillis();
-		if (now > _nextUpdate) {
-			_nextUpdate = now + _anim.delay * _vm->tickLength();
-
-			_anim.anim->displayFrame(_animIntern.curFrame, 0, 0, 0, 0, 0, 0);
-			_animIntern.curFrame += _animIntern.direction;
-			if (_animIntern.curFrame < _anim.startFrame) {
-				_animIntern.curFrame = _anim.startFrame;
-				_animIntern.direction = 1;
-			} else if (_animIntern.curFrame > _anim.endFrame) {
-				_animIntern.curFrame = _anim.endFrame;
-				_animIntern.direction = -1;
-			}
-		}
-	}
-
-	_screen->updateScreen();
-}
-
-bool MainMenu::getInput() {
-	Common::Event event;
-	Common::EventManager *eventMan = _vm->getEventManager();
-
-	bool updateScreen = false;
-
-	while (eventMan->pollEvent(event)) {
-		switch (event.type) {
-		case Common::EVENT_LBUTTONUP:
-			return true;
+void GUI::updateSavegameList() {
+	if (!_savegameListUpdateNeeded)
+		return;
 
-		case Common::EVENT_MOUSEMOVE:
-			updateScreen = true;
-			break;
+	_savegameListUpdateNeeded = false;
 
-		default:
-			break;
-		}
+	if (_savegameList) {
+		for (int i = 0; i < _savegameListSize; i++)
+			delete[] _savegameList[i];
+		delete[] _savegameList;
 	}
 
-	if (updateScreen)
-		_system->updateScreen();
-	return false;
-}
-
-int MainMenu::handle(int dim) {
-	int command = -1;
-
-	uint8 colorMap[16];
-	memset(colorMap, 0, sizeof(colorMap));
-	_screen->setTextColorMap(colorMap);
-
-	Screen::FontId oldFont = _screen->setFont(_static.font);
-	int charWidthBackUp = _screen->_charWidth;
-
-	if (_vm->game() != GI_LOL)
-		_screen->_charWidth = -2;
-	_screen->setScreenDim(dim);
-
-	int backUpX = _screen->_curDim->sx;
-	int backUpY = _screen->_curDim->sy;
-	int backUpWidth = _screen->_curDim->w;
-	int backUpHeight = _screen->_curDim->h;
-	_screen->copyRegion(backUpX, backUpY, backUpX, backUpY, backUpWidth, backUpHeight, 0, 3);
-
-	int x = _screen->_curDim->sx << 3;
-	int y = _screen->_curDim->sy;
-	int width = _screen->_curDim->w << 3;
-	int height =  _screen->_curDim->h;
-
-	drawBox(x, y, width, height, 1);
-	drawBox(x + 1, y + 1, width - 2, height - 2, 0);
+	updateSaveList(true);
+	_savegameListSize = _saveSlots.size();
 
-	int selected = 0;
+	if (_savegameListSize) {
+		Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Greater<int>());
 
-	draw(selected);
+		KyraEngine_v1::SaveHeader header;
+		Common::InSaveFile *in;
 
-	while (!_screen->isMouseVisible())
-		_screen->showMouse();
+		_savegameList = new char *[_savegameListSize];
 
-	int fh = _screen->getFontHeight();
-	if (_vm->gameFlags().lang == Common::JA_JPN)
-		fh++;
-
-	int textPos = ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3;
-
-	Common::Rect menuRect(x + 16, y + 4, x + width - 16, y + 4 + fh * _static.menuTable[3]);
-
-	while (!_vm->shouldQuit()) {
-		updateAnimation();
-		bool mousePressed = getInput();
-
-		Common::Point mouse = _vm->getMousePos();
-		if (menuRect.contains(mouse)) {
-			int item = (mouse.y - menuRect.top) / fh;
-
-			if (item != selected) {
-				printString("%s", textPos, menuRect.top + selected * fh, _static.menuTable[5], 0, 5, _static.strings[selected]);
-				printString("%s", textPos, menuRect.top + item * fh, _static.menuTable[6], 0, 5, _static.strings[item]);
-
-				selected = item;
-			}
-
-			if (mousePressed) {
-				for (int i = 0; i < 3; i++) {
-					printString("%s", textPos, menuRect.top + selected * fh, _static.menuTable[5], 0, 5, _static.strings[selected]);
-					_screen->updateScreen();
-					_system->delayMillis(50);
-					printString("%s", textPos, menuRect.top + selected * fh, _static.menuTable[6], 0, 5, _static.strings[selected]);
-					_screen->updateScreen();
-					_system->delayMillis(50);
-				}
-				command = item;
-				break;
+		for (int i = 0; i < _savegameListSize; i++) {
+			in = _vm->openSaveForReading(_vm->getSavegameFilename(i), header);
+			if (in) {
+				_savegameList[i] = new char[header.description.size() + 1];
+				Common::strlcpy(_savegameList[i], header.description.c_str(), header.description.size() + 1);
+				Util::convertISOToDOS(_savegameList[i]);
+				delete in;
+			} else {
+				_savegameList[i] = 0;
+				error("GUI::updateSavegameList(): Unexpected missing save file for slot: %d.", i);
 			}
 		}
-		_system->delayMillis(10);
-	}
-
-	if (_vm->shouldQuit())
-		command = -1;
 
-	_screen->copyRegion(backUpX, backUpY, backUpX, backUpY, backUpWidth, backUpHeight, 3, 0);
-	_screen->_charWidth = charWidthBackUp;
-	_screen->setFont(oldFont);
-
-	return command;
-}
-
-void MainMenu::draw(int select) {
-	int top = _screen->_curDim->sy;
-	top += _static.menuTable[1];
-	int fh = _screen->getFontHeight();
-	if (_vm->gameFlags().lang == Common::JA_JPN)
-		fh++;
-
-	for (int i = 0; i < _static.menuTable[3]; ++i) {
-		int curY = top + i * fh;
-		int color = (i == select) ? _static.menuTable[6] : _static.menuTable[5];
-		printString("%s", ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3, curY, color, 0, 5, _static.strings[i]);
+	} else {
+		_savegameList = 0;
 	}
 }
 
-void MainMenu::drawBox(int x, int y, int w, int h, int fill) {
-	--w; --h;
-
-	if (fill)
-		_screen->fillRect(x, y, x+w, y+h, _static.colorTable[0]);
-
-	_screen->drawClippedLine(x, y+h, x+w, y+h, _static.colorTable[1]);
-	_screen->drawClippedLine(x+w, y, x+w, y+h, _static.colorTable[1]);
-	_screen->drawClippedLine(x, y, x+w, y, _static.colorTable[2]);
-	_screen->drawClippedLine(x, y, x, y+h, _static.colorTable[2]);
-
-	_screen->setPagePixel(_screen->_curPage, x, y+h, _static.colorTable[3]);
-	_screen->setPagePixel(_screen->_curPage, x+w, y, _static.colorTable[3]);
-}
-
-void MainMenu::printString(const char *format, int x, int y, int col1, int col2, int flags, ...) {
-	if (!format)
-		return;
-
-	va_list vaList;
-	va_start(vaList, flags);
-	Common::String string = Common::String::vformat(format, vaList);
-	va_end(vaList);
-
-	if (flags & 1)
-		x -= _screen->getTextWidth(string.c_str()) >> 1;
-
-	if (flags & 2)
-		x -= _screen->getTextWidth(string.c_str());
-
-	if (_vm->gameFlags().use16ColorMode)
-		flags &= 3;
-
-	if (flags & 4) {
-		_screen->printText(string.c_str(), x - 1, y, _static.altColor, col2);
-		_screen->printText(string.c_str(), x, y + 1, _static.altColor, col2);
-	}
+} // End of namespace Kyra
 
-	if (flags & 8) {
-		_screen->printText(string.c_str(), x - 1, y, 227, col2);
-		_screen->printText(string.c_str(), x, y + 1, 227, col2);
-	}
 
-	_screen->printText(string.c_str(), x, y, col1, col2);
-}
-
-} // End of namespace Kyra
diff --git a/engines/kyra/gui.h b/engines/kyra/gui.h
index 597f088..efca845 100644
--- a/engines/kyra/gui.h
+++ b/engines/kyra/gui.h
@@ -93,118 +93,24 @@ struct Button {
 	uint16 arg;
 };
 
-struct MenuItem {
-	bool enabled;
-
-	const char *itemString;
-	uint16 itemId;
-
-	int16 x, y;
-	uint16 width, height;
-
-	uint8 textColor, highlightColor;
-
-	int16 titleX;
-
-	uint8 color1, color2;
-	uint8 bkgdColor;
-
-	Button::Callback callback;
-
-	int16 saveSlot;
-
-	const char *labelString;
-	uint16 labelId;
-	int16 labelX, labelY;
-
-	uint16 keyCode;
-};
-
-struct Menu {
-	int16 x, y;
-	uint16 width, height;
-
-	uint8 bkgdColor;
-	uint8 color1, color2;
-
-	const char *menuNameString;
-	uint16 menuNameId;
-
-	uint8 textColor;
-	int16 titleX, titleY;
-
-	uint8 highlightedItem;
-
-	uint8 numberOfItems;
-
-	int16 scrollUpButtonX, scrollUpButtonY;
-	int16 scrollDownButtonX, scrollDownButtonY;
-
-	MenuItem item[7];
-};
-
 class Screen;
 class TextDisplayer;
 
-class GUI_v1 {
+class GUI {
 public:
-	GUI_v1(KyraEngine_v1 *vm);
-	virtual ~GUI_v1() {}
+	GUI(KyraEngine_v1 *vm);
+	virtual ~GUI();
 
 	// button specific
-	virtual Button *addButtonToList(Button *list, Button *newButton);
-
 	virtual void processButton(Button *button) = 0;
 	virtual int processButtonList(Button *buttonList, uint16 inputFlags, int8 mouseWheel) = 0;
 
-	virtual int redrawShadedButtonCallback(Button *button);
-	virtual int redrawButtonCallback(Button *button);
-
-	// menu specific
-	virtual void initMenuLayout(Menu &menu);
-	void initMenu(Menu &menu);
-
-	void processHighlights(Menu &menu);
-
 	// utilities for thumbnail creation
 	virtual void createScreenThumbnail(Graphics::Surface &dst) = 0;
 
 protected:
 	KyraEngine_v1 *_vm;
 	Screen *_screen;
-	TextDisplayer *_text;
-
-	Button *_menuButtonList;
-	bool _displayMenu;
-	bool _displaySubMenu;
-	bool _cancelSubMenu;
-
-	virtual void printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2);
-	virtual int getMenuCenterStringX(const char *str, int x1, int x2);
-
-	Button::Callback _redrawShadedButtonFunctor;
-	Button::Callback _redrawButtonFunctor;
-
-	virtual Button *getButtonListData() = 0;
-	virtual Button *getScrollUpButton() = 0;
-	virtual Button *getScrollDownButton() = 0;
-
-	virtual Button::Callback getScrollUpButtonHandler() const = 0;
-	virtual Button::Callback getScrollDownButtonHandler() const = 0;
-
-	virtual uint8 defaultColor1() const = 0;
-	virtual uint8 defaultColor2() const = 0;
-
-	virtual const char *getMenuTitle(const Menu &menu) = 0;
-	virtual const char *getMenuItemTitle(const MenuItem &menuItem) = 0;
-	virtual const char *getMenuItemLabel(const MenuItem &menuItem) = 0;
-
-	void updateAllMenuButtons();
-	void updateMenuButton(Button *button);
-	virtual void updateButton(Button *button);
-
-	void redrawText(const Menu &menu);
-	void redrawHighlight(const Menu &menu);
 
 	// The engine expects a list of contiguous savegame indices.
 	// Since ScummVM's savegame indices aren't, we re-index them.
@@ -212,65 +118,18 @@ protected:
 	Common::Array<int> _saveSlots;
 	void updateSaveList(bool excludeQuickSaves = false);
 	int getNextSavegameSlot();
+	void updateSavegameList();
 
 	virtual void sortSaveSlots();
 
 	uint32 _lastScreenUpdate;
-	Common::KeyState _keyPressed;
-	void checkTextfieldInput();
-};
-
-class Movie;
+	char **_savegameList;
+	int _savegameListSize;
+	bool _savegameListUpdateNeeded;
 
-class MainMenu {
-public:
-	MainMenu(KyraEngine_v1 *vm);
-	virtual ~MainMenu() {}
-
-	struct Animation {
-		Animation() : anim(0), startFrame(0), endFrame(0), delay(0) {}
-
-		Movie *anim;
-		int startFrame;
-		int endFrame;
-		int delay;
-	};
-
-	struct StaticData {
-		const char *strings[5];
-
-		uint8 menuTable[7];
-		uint8 colorTable[4];
-
-		Screen::FontId font;
-		uint8 altColor;
-	};
-
-	void init(StaticData data, Animation anim);
-	int handle(int dim);
-private:
-	KyraEngine_v1 *_vm;
-	Screen *_screen;
-	OSystem *_system;
-
-	StaticData _static;
-	struct AnimIntern {
-		int curFrame;
-		int direction;
-	};
-	Animation _anim;
-	AnimIntern _animIntern;
-
-	uint32 _nextUpdate;
-
-	void updateAnimation();
-	void draw(int select);
-	void drawBox(int x, int y, int w, int h, int fill);
-	bool getInput();
-
-	void printString(const char *string, int x, int y, int col1, int col2, int flags, ...) GCC_PRINTF(2, 8);
+	Common::KeyState _keyPressed;
 };
 
-} // end of namesapce Kyra
+} // End of namespace Kyra
 
 #endif
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 5d86b9c..6eab4a0 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -29,6 +29,7 @@
 #include "kyra/util.h"
 
 #include "common/system.h"
+#include "common/savefile.h"
 
 namespace Kyra {
 
@@ -1428,12 +1429,9 @@ void EobCoreEngine::gui_processInventorySlotClick(int slot) {
 	}
 }
 
-GUI_Eob::GUI_Eob(EobCoreEngine *vm) : GUI_v1(vm), _vm(vm), _screen(vm->_screen) {
+GUI_Eob::GUI_Eob(EobCoreEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) {
 	_scrollUpFunctor = _scrollDownFunctor = BUTTON_FUNCTOR(GUI_Eob, this, 0);
 
-	_redrawButtonFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::redrawButtonCallback);
-	_redrawShadedButtonFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::redrawShadedButtonCallback);
-
 	_menuStringsPrefsTemp = new char*[4];
 	memset(_menuStringsPrefsTemp, 0, 4 * sizeof(char*));
 
@@ -1445,7 +1443,6 @@ GUI_Eob::GUI_Eob(EobCoreEngine *vm) : GUI_v1(vm), _vm(vm), _screen(vm->_screen)
 	_cflag = 0xffff;
 	
 	_menuLineSpacing = 0;
-	//_menuUnk1 = 0;
 	_menuLastInFlags = 0;
 	_menuCur = 0;
 	_menuNumItems = 0;
@@ -1462,6 +1459,7 @@ GUI_Eob::GUI_Eob(EobCoreEngine *vm) : GUI_v1(vm), _vm(vm), _screen(vm->_screen)
 	_updateBoxIndex = -1;
 	_highLightBoxTimer = 0;
 	_updateBoxColorIndex = 0;
+	_needRest = false;
 }
 
 GUI_Eob::~GUI_Eob() {
@@ -1979,7 +1977,6 @@ void GUI_Eob::simpleMenu_setup(int sd, int maxItem, const char *const *strings,
 
 	_screen->updateScreen();
 	_menuLineSpacing = lineSpacing;
-	//_menuUnk1 = 0;
 	_menuLastInFlags = 0;
 	_vm->removeInputTop();
 }
@@ -2081,7 +2078,7 @@ void GUI_Eob::runCampMenu() {
 	bool redrawPortraits = false;
 	bool res = false;
 	_charSelectRedraw = false;
-	_vm->_resting = false;
+	_needRest = false;
 	Button *buttonList = 0;
 
 	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
@@ -2164,7 +2161,7 @@ void GUI_Eob::runCampMenu() {
 				if (_vm->restParty())
 					runLoop = false;
 				else
-					_vm->_resting = false;
+					_needRest = false;
 				redrawPortraits = true;
 				break;
 
@@ -2192,7 +2189,7 @@ void GUI_Eob::runCampMenu() {
 				break;
 
 			case 0x8007:
-				if (_vm->_resting)
+				if (_needRest)
 					displayTextBox(44);
 				// fall through
 
@@ -2207,11 +2204,17 @@ void GUI_Eob::runCampMenu() {
 				break;
 
 			case 0x8008:
-				// load
+				if (runLoadMenu(0, 0))
+					runLoop = false;
+				else
+					newMenu = 1;
 				break;
 
 			case 0x8009:
-				// save
+				if (runSaveMenu(0, 0))
+					displayTextBox(14);
+				else
+					newMenu = 1;
 				break;
 
 			case 0x800a:
@@ -2289,8 +2292,21 @@ void GUI_Eob::runCampMenu() {
 	_screen->setFont(of);
 }
 
-int GUI_Eob::runLoadMenu(int x, int y) {
-	return 0;
+bool GUI_Eob::runLoadMenu(int x, int y) {
+	const ScreenDim *dm = _screen->getScreenDim(11);
+	int xo = dm->sx;
+	int yo = dm->sy;
+	bool result = false;
+	_savegameListUpdateNeeded = true;
+	
+	_screen->modifyScreenDim(11, dm->sx + (x >> 8), dm->sy + y, dm->w, dm->sy);
+	
+	updateSavegameList();
+	setupSaveMenuSlots();
+
+	_screen->modifyScreenDim(11, xo, yo, dm->w, dm->sy);
+
+	return result;
 }
 
 void GUI_Eob::updateBoxFrameHighLight(int box) {
@@ -2462,8 +2478,8 @@ void GUI_Eob::simpleMenu_initMenuItemsMask(int menuId, int maxItem, int32 menuIt
 	_menuCur = 0;
 }
 
-void GUI_Eob::runSaveMenu() {
-
+bool GUI_Eob::runSaveMenu(int x, int y) {
+	return true;
 }
 
 void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
@@ -2642,7 +2658,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
 		}
 
 		if (inputFlag & 0x8000) {
-			Button *b = _vm->gui_getButton(buttonList, inputFlag & 0x7fff);
+			b = _vm->gui_getButton(buttonList, inputFlag & 0x7fff);
 			drawMenuButton(b, true, true, true);
 			_screen->updateScreen();
 			_vm->_system->delayMillis(80);
@@ -2726,7 +2742,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
 		} else if (_numAssignedSpellsOfType[i * 2]) {
 			_numAssignedSpellsOfType[i * 2]--;
 
-			_vm->_resting = true;
+			_needRest = true;
 			int pg = lh[i] - 1;
 			for (int ii = 0; ii < 10; ii++) {
 				if (!charSpellList[pg * 10 + ii]) {
@@ -3164,6 +3180,10 @@ void GUI_Eob::releaseButtons(Button *list) {
 	}
 }
 
+void GUI_Eob::setupSaveMenuSlots() {
+
+}
+
 #endif // ENABLE_EOB
 
 }	// End of namespace Kyra
diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h
index 6d4edfd..c8e9744 100644
--- a/engines/kyra/gui_eob.h
+++ b/engines/kyra/gui_eob.h
@@ -41,7 +41,7 @@ struct EobRect16 {
 class DarkMoonEngine;
 class Screen_Eob;
 
-class GUI_Eob : public GUI_v1 {
+class GUI_Eob : public GUI {
 	friend class EobCoreEngine;
 	friend class CharacterGenerator;
 public:
@@ -58,9 +58,9 @@ public:
 	void simpleMenu_setup(int sd, int maxItem, const char *const *strings, int32 menuItemsMask, int unk, int lineSpacing);
 	int simpleMenu_process(int sd, const char *const *strings, void *b, int32 menuItemsMask, int unk);	
 
-	// Button based menus (camp menu, options, save/load)
+	// Button based menus (camp menu, load menu)
 	void runCampMenu();
-	int runLoadMenu(int x, int y);
+	bool runLoadMenu(int x, int y);
 
 	void updateBoxFrameHighLight(int box);
 
@@ -78,7 +78,7 @@ private:
 	void simpleMenu_flashSelection(const char *str, int x, int y, int color1, int color2, int color3);
 	void simpleMenu_initMenuItemsMask(int menuId, int maxItem, int32 menuItemsMask, int unk);
 
-	void runSaveMenu();
+	bool runSaveMenu(int x, int y);
 	void runMemorizePrayMenu(int charIndex, int spellType);
 	void scribeScrollDialogue();
 
@@ -96,6 +96,8 @@ private:
 	Button *linkButton(Button *list, Button *newbt);
 	void releaseButtons(Button *list);
 
+	void setupSaveMenuSlots();
+
 	Button _scrollUpButton;//////////////////77
 	Button _scrollDownButton;
 
@@ -119,7 +121,6 @@ private:
 	Button::Callback _scrollDownFunctor;
 
 	int _menuLineSpacing;
-	//int _menuUnk1;
 	int _menuLastInFlags;
 
 	uint8 _numPages;
@@ -127,6 +128,7 @@ private:
 	int8 *_numAssignedSpellsOfType;
 	uint32 _clericSpellAvltyFlags;
 	uint32 _paladinSpellAvltyFlags;
+	bool _needRest;
 
 	int _menuCur;
 	int _menuNumItems;
@@ -136,21 +138,6 @@ private:
 	int _updateBoxColorIndex;
 	uint32 _highLightBoxTimer;
 	static const EobRect16 _updateBoxFrameHighLights[];
-
-	// unused
-	Button *getButtonListData() { return 0; }
-	Button *getScrollUpButton() { return &_scrollUpButton; }
-	Button *getScrollDownButton() { return &_scrollDownButton; }
-
-	Button::Callback getScrollUpButtonHandler() const { return _scrollUpFunctor; }
-	Button::Callback getScrollDownButtonHandler() const { return _scrollDownFunctor; }
-
-	uint8 defaultColor1() const { return 0xFE; }
-	uint8 defaultColor2() const { return 0x00; }
-
-	const char *getMenuTitle(const Menu &menu) { return 0; }
-	const char *getMenuItemTitle(const MenuItem &menuItem) { return 0; }
-	const char *getMenuItemLabel(const MenuItem &menuItem) { return 0; }
 };
 
 }	// End of namespace Kyra
diff --git a/engines/kyra/gui_lok.h b/engines/kyra/gui_lok.h
index 1d10603..d3e0bea 100644
--- a/engines/kyra/gui_lok.h
+++ b/engines/kyra/gui_lok.h
@@ -23,7 +23,7 @@
 #ifndef KYRA_GUI_LOK_H
 #define KYRA_GUI_LOK_H
 
-#include "kyra/gui.h"
+#include "kyra/gui_v1.h"
 #include "kyra/screen_lok.h"
 
 namespace Kyra {
diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp
index 681caf9..ac3d16b 100644
--- a/engines/kyra/gui_lol.cpp
+++ b/engines/kyra/gui_lol.cpp
@@ -1848,8 +1848,6 @@ GUI_LoL::GUI_LoL(LoLEngine *vm) : GUI_v1(vm), _vm(vm), _screen(vm->_screen) {
 	_specialProcessButton = _backUpButtonList = 0;
 	_flagsModifier = 0;
 	_sliderSfx = 11;
-	_savegameList = 0;
-	_savegameListSize = 0;
 }
 
 void GUI_LoL::processButton(Button *button) {
@@ -2530,44 +2528,6 @@ void GUI_LoL::setupSaveMenuSlots(Menu &menu, int num) {
 	}
 }
 
-void GUI_LoL::updateSavegameList() {
-	if (!_savegameListUpdateNeeded)
-		return;
-
-	_savegameListUpdateNeeded = false;
-
-	if (_savegameList) {
-		for (int i = 0; i < _savegameListSize; i++)
-			delete[] _savegameList[i];
-		delete[] _savegameList;
-	}
-
-	updateSaveList(true);
-	_savegameListSize = _saveSlots.size();
-
-	if (_savegameListSize) {
-		LoLEngine::SaveHeader header;
-		Common::InSaveFile *in;
-
-		_savegameList = new char *[_savegameListSize];
-
-		for (int i = 0; i < _savegameListSize; i++) {
-			in = _vm->openSaveForReading(_vm->getSavegameFilename(_saveSlots[i]), header);
-			if (in) {
-				_savegameList[i] = new char[header.description.size() + 1];
-				Common::strlcpy(_savegameList[i], header.description.c_str(), header.description.size() + 1);
-				Util::convertISOToDOS(_savegameList[i]);
-				delete in;
-			} else {
-				_savegameList[i] = 0;
-				warning("GUI_LoL::updateSavegameList(): Unexpected missing save file for slot: %d.", _saveSlots[i]);
-			}
-		}
-	} else {
-		_savegameList = 0;
-	}
-}
-
 void GUI_LoL::sortSaveSlots() {
 	Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Greater<int>());
 }
diff --git a/engines/kyra/gui_lol.h b/engines/kyra/gui_lol.h
index 3a8135a..dbf54e4 100644
--- a/engines/kyra/gui_lol.h
+++ b/engines/kyra/gui_lol.h
@@ -25,7 +25,7 @@
 #ifndef KYRA_GUI_LOL_H
 #define KYRA_GUI_LOL_H
 
-#include "kyra/gui.h"
+#include "kyra/gui_v1.h"
 
 namespace Kyra {
 #define GUI_LOL_MENU(menu, a, b, c, d, e, f, g, i) \
@@ -112,7 +112,6 @@ private:
 	void restorePage0();
 
 	void setupSaveMenuSlots(Menu &menu, int num);
-	void updateSavegameList();
 
 	void printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 flags);
 	int getMenuCenterStringX(const char *str, int x1, int x2);
@@ -170,10 +169,6 @@ private:
 	Button::Callback _scrollUpFunctor;
 	Button::Callback _scrollDownFunctor;
 
-	char **_savegameList;
-	int _savegameListSize;
-	bool _savegameListUpdateNeeded;
-
 	virtual void sortSaveSlots();
 };
 
diff --git a/engines/kyra/gui_v1.cpp b/engines/kyra/gui_v1.cpp
new file mode 100644
index 0000000..c38c828
--- /dev/null
+++ b/engines/kyra/gui_v1.cpp
@@ -0,0 +1,630 @@
+/* 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.
+ *
+ */
+
+#include "kyra/gui_v1.h"
+
+#include "kyra/text.h"
+#include "kyra/wsamovie.h"
+
+#include "common/savefile.h"
+#include "common/system.h"
+
+namespace Kyra {
+
+GUI_v1::GUI_v1(KyraEngine_v1 *kyra) : GUI(kyra), _text(kyra->text()) {
+	_menuButtonList = 0;
+
+	_redrawButtonFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::redrawButtonCallback);
+	_redrawShadedButtonFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::redrawShadedButtonCallback);
+}
+
+Button *GUI_v1::addButtonToList(Button *list, Button *newButton) {
+	if (!newButton)
+		return list;
+
+	newButton->nextButton = 0;
+
+	if (list) {
+		Button *cur = list;
+		while (cur->nextButton)
+			cur = cur->nextButton;
+		cur->nextButton = newButton;
+	} else {
+		list = newButton;
+	}
+
+	return list;
+}
+
+void GUI_v1::initMenuLayout(Menu &menu) {
+	if (menu.x == -1)
+		menu.x = (320 - menu.width) >> 1;
+	if (menu.y == -1)
+		menu.y = (200 - menu.height) >> 1;
+
+	for (int i = 0; i < menu.numberOfItems; ++i) {
+		if (menu.item[i].x == -1)
+			menu.item[i].x = (menu.width - menu.item[i].width) >> 1;
+	}
+}
+
+void GUI_v1::initMenu(Menu &menu) {
+	_menuButtonList = 0;
+
+	_screen->hideMouse();
+
+	int textX;
+	int textY;
+
+	int menu_x2 = menu.width  + menu.x - 1;
+	int menu_y2 = menu.height + menu.y - 1;
+
+	_screen->fillRect(menu.x + 2, menu.y + 2, menu_x2 - 2, menu_y2 - 2, menu.bkgdColor);
+	_screen->drawShadedBox(menu.x, menu.y, menu_x2, menu_y2, menu.color1, menu.color2);
+
+	if (menu.titleX != -1)
+		textX = menu.titleX;
+	else
+		textX = getMenuCenterStringX(getMenuTitle(menu), menu.x, menu_x2);
+
+	textY = menu.y + menu.titleY;
+
+	if (_vm->game() == GI_LOL) {
+		printMenuText(getMenuTitle(menu), textX, textY, menu.textColor, 0, 9);
+	} else {
+		if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+			printMenuText(getMenuTitle(menu), textX - 1, textY + 1, defaultColor1(), defaultColor2(), 0);
+		printMenuText(getMenuTitle(menu), textX, textY, menu.textColor, 0, 0);
+	}
+
+	int x1, y1, x2, y2;
+	for (int i = 0; i < menu.numberOfItems; ++i) {
+		if (!menu.item[i].enabled)
+			continue;
+
+		x1 = menu.x + menu.item[i].x;
+		y1 = menu.y + menu.item[i].y;
+
+		x2 = x1 + menu.item[i].width - 1;
+		y2 = y1 + menu.item[i].height - 1;
+
+		if (i < 7) {
+			Button *menuButtonData = getButtonListData() + i;
+			menuButtonData->nextButton = 0;
+			menuButtonData->x = x1;
+			menuButtonData->y = y1;
+			menuButtonData->width  = menu.item[i].width - 1;
+			menuButtonData->height = menu.item[i].height - 1;
+			menuButtonData->buttonCallback = menu.item[i].callback;
+			menuButtonData->keyCode = menu.item[i].keyCode;
+			menuButtonData->keyCode2 = 0;
+			menuButtonData->arg = menu.item[i].itemId;
+
+			_menuButtonList = addButtonToList(_menuButtonList, menuButtonData);
+		}
+
+		_screen->fillRect(x1, y1, x2, y2, menu.item[i].bkgdColor);
+		_screen->drawShadedBox(x1, y1, x2, y2, menu.item[i].color1, menu.item[i].color2);
+
+		if (getMenuItemTitle(menu.item[i])) {
+			if (menu.item[i].titleX != -1)
+				textX = x1 + menu.item[i].titleX + 3;
+			else
+				textX = getMenuCenterStringX(getMenuItemTitle(menu.item[i]), x1, x2);
+
+			textY = y1 + 2;
+			if (_vm->game() == GI_LOL) {
+				textY++;
+				if (i == menu.highlightedItem)
+					printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 8);
+				else
+					printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 8);
+			} else {
+				Screen::FontId of = _screen->_currentFont;
+				if (menu.item[i].saveSlot > 0)
+					_screen->setFont(Screen::FID_8_FNT);
+
+				if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+					printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
+
+				if (i == menu.highlightedItem)
+					printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 0);
+				else
+					printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 0);
+
+				_screen->setFont(of);
+			}
+		}
+	}
+
+	for (int i = 0; i < menu.numberOfItems; ++i) {
+		if (getMenuItemLabel(menu.item[i])) {
+			if (_vm->game() == GI_LOL) {
+				menu.item[i].labelX = menu.item[i].x - 1;
+				menu.item[i].labelY = menu.item[i].y + 3;
+				printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX, menu.y + menu.item[i].labelY, menu.item[i].textColor, 0, 10);
+			} else {
+				if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+					printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX - 1, menu.y + menu.item[i].labelY + 1, defaultColor1(), 0, 0);
+				printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX, menu.y + menu.item[i].labelY, menu.item[i].textColor, 0, 0);
+			}
+		}
+	}
+
+	if (menu.scrollUpButtonX != -1) {
+		Button *scrollUpButton = getScrollUpButton();
+		scrollUpButton->x = menu.scrollUpButtonX + menu.x;
+		scrollUpButton->y = menu.scrollUpButtonY + menu.y;
+		scrollUpButton->buttonCallback = getScrollUpButtonHandler();
+		scrollUpButton->nextButton = 0;
+		scrollUpButton->mouseWheel = -1;
+
+		_menuButtonList = addButtonToList(_menuButtonList, scrollUpButton);
+		updateMenuButton(scrollUpButton);
+
+		Button *scrollDownButton = getScrollDownButton();
+		scrollDownButton->x = menu.scrollDownButtonX + menu.x;
+		scrollDownButton->y = menu.scrollDownButtonY + menu.y;
+		scrollDownButton->buttonCallback = getScrollDownButtonHandler();
+		scrollDownButton->nextButton = 0;
+		scrollDownButton->mouseWheel = 1;
+
+		_menuButtonList = addButtonToList(_menuButtonList, scrollDownButton);
+		updateMenuButton(scrollDownButton);
+	}
+
+	_screen->showMouse();
+	_screen->updateScreen();
+}
+
+void GUI_v1::processHighlights(Menu &menu) {
+	int x1, y1, x2, y2;
+	Common::Point p = _vm->getMousePos();
+	int mouseX = p.x;
+	int mouseY = p.y;
+
+	if (_vm->game() == GI_LOL && menu.highlightedItem != 255) {
+		// LoL doesnt't have default highlighted items.
+		// We use a highlightedItem value of 255 for this.
+
+		// With LoL no highlighting should take place unless the
+		// mouse cursor moves over a button. The highlighting should end
+		// when the mouse cursor leaves the button.
+		if (menu.item[menu.highlightedItem].enabled)
+			redrawText(menu);
+	}
+
+	for (int i = 0; i < menu.numberOfItems; ++i) {
+		if (!menu.item[i].enabled)
+			continue;
+
+		x1 = menu.x + menu.item[i].x;
+		y1 = menu.y + menu.item[i].y;
+
+		x2 = x1 + menu.item[i].width;
+		y2 = y1 + menu.item[i].height;
+
+		if (mouseX > x1 && mouseX < x2 &&
+			mouseY > y1 && mouseY < y2) {
+
+			if (menu.highlightedItem != i || _vm->game() == GI_LOL) {
+				if (_vm->game() != GI_LOL) {
+					if (menu.item[menu.highlightedItem].enabled)
+						redrawText(menu);
+				}
+
+				menu.highlightedItem = i;
+				redrawHighlight(menu);
+			}
+		}
+	}
+
+	_screen->updateScreen();
+}
+
+void GUI_v1::redrawText(const Menu &menu) {
+	int textX;
+	int i = menu.highlightedItem;
+
+	int x1 = menu.x + menu.item[i].x;
+	int y1 = menu.y + menu.item[i].y;
+
+	int x2 = x1 + menu.item[i].width - 1;
+
+	if (menu.item[i].titleX >= 0)
+		textX = x1 + menu.item[i].titleX + 3;
+	else
+		textX = getMenuCenterStringX(getMenuItemTitle(menu.item[i]), x1, x2);
+
+	int textY = y1 + 2;
+	if (_vm->game() == GI_LOL) {
+		textY++;
+		printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 8);
+	} else {
+		Screen::FontId of = _screen->_currentFont;
+		if (menu.item[i].saveSlot > 0)
+			_screen->setFont(Screen::FID_8_FNT);
+		if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+			printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
+		printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 0);
+		_screen->setFont(of);
+	}
+}
+
+void GUI_v1::redrawHighlight(const Menu &menu) {
+	int textX;
+	int i = menu.highlightedItem;
+
+	int x1 = menu.x + menu.item[i].x;
+	int y1 = menu.y + menu.item[i].y;
+
+	int x2 = x1 + menu.item[i].width - 1;
+
+	if (menu.item[i].titleX != -1)
+		textX = x1 + menu.item[i].titleX + 3;
+	else
+		textX = getMenuCenterStringX(getMenuItemTitle(menu.item[i]), x1, x2);
+
+	int textY = y1 + 2;
+
+	if (_vm->game() == GI_LOL) {
+		textY++;
+		printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 8);
+	} else {
+		Screen::FontId of = _screen->_currentFont;
+		if (menu.item[i].saveSlot > 0)
+			_screen->setFont(Screen::FID_8_FNT);
+		if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+			printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
+		printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 0);
+		_screen->setFont(of);
+	}
+}
+
+void GUI_v1::updateAllMenuButtons() {
+	for (Button *cur = _menuButtonList; cur; cur = cur->nextButton)
+		updateMenuButton(cur);
+}
+
+void GUI_v1::updateMenuButton(Button *button) {
+	if (!_displayMenu)
+		return;
+
+	_screen->hideMouse();
+	updateButton(button);
+	_screen->updateScreen();
+	_screen->showMouse();
+}
+
+void GUI_v1::updateButton(Button *button) {
+	if (!button || (button->flags & 8))
+		return;
+
+	if (button->flags2 & 1)
+		button->flags2 &= 0xFFF7;
+	else
+		button->flags2 |= 8;
+
+	button->flags2 &= 0xFFFC;
+
+	if (button->flags2 & 4)
+		button->flags2 |= 0x10;
+	else
+		button->flags2 &= 0xEEEF;
+
+	button->flags2 &= 0xFFFB;
+
+	processButton(button);
+}
+
+int GUI_v1::redrawButtonCallback(Button *button) {
+	if (!_displayMenu)
+		return 0;
+
+	_screen->hideMouse();
+	if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+		_screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 17);
+	else
+		_screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 0xF8);
+	_screen->showMouse();
+
+	return 0;
+}
+
+int GUI_v1::redrawShadedButtonCallback(Button *button) {
+	if (!_displayMenu)
+		return 0;
+
+	_screen->hideMouse();
+	if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+		_screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 31, 18);
+	else
+		_screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 0xF9, 0xFA);
+	_screen->showMouse();
+
+	return 0;
+}
+
+void GUI_v1::checkTextfieldInput() {
+	Common::Event event;
+
+	uint32 now = _vm->_system->getMillis();
+
+	bool running = true;
+	int keys = 0;
+	while (_vm->_eventMan->pollEvent(event) && running) {
+		switch (event.type) {
+		case Common::EVENT_KEYDOWN:
+			if (event.kbd.keycode == Common::KEYCODE_q && event.kbd.hasFlags(Common::KBD_CTRL))
+				_vm->quitGame();
+			else
+				_keyPressed = event.kbd;
+			running = false;
+			break;
+
+		case Common::EVENT_LBUTTONDOWN:
+		case Common::EVENT_LBUTTONUP: {
+			Common::Point pos = _vm->getMousePos();
+			_vm->_mouseX = pos.x;
+			_vm->_mouseY = pos.y;
+			keys = event.type == Common::EVENT_LBUTTONDOWN ? 199 : (200 | 0x800);
+			running = false;
+			} break;
+
+		case Common::EVENT_MOUSEMOVE: {
+			Common::Point pos = _vm->getMousePos();
+			_vm->_mouseX = pos.x;
+			_vm->_mouseY = pos.y;
+
+			_vm->_system->updateScreen();
+			_lastScreenUpdate = now;
+			} break;
+
+		default:
+			break;
+		}
+	}
+
+	if (now - _lastScreenUpdate > 50) {
+		_vm->_system->updateScreen();
+		_lastScreenUpdate = now;
+	}
+
+	processButtonList(_menuButtonList, keys | 0x8000, 0);
+	_vm->_system->delayMillis(3);
+}
+
+void GUI_v1::printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2) {
+	_text->printText(str, x, y, c0, c1, c2);
+}
+
+int GUI_v1::getMenuCenterStringX(const char *str, int x1, int x2) {
+	return _text->getCenterStringX(str, x1, x2);
+}
+
+#pragma mark -
+
+MainMenu::MainMenu(KyraEngine_v1 *vm) : _vm(vm), _screen(0) {
+	_screen = _vm->screen();
+	_nextUpdate = 0;
+	_system = g_system;
+}
+
+void MainMenu::init(StaticData data, Animation anim) {
+	_static = data;
+	_anim = anim;
+	_animIntern.curFrame = _anim.startFrame;
+	_animIntern.direction = 1;
+}
+
+void MainMenu::updateAnimation() {
+	if (_anim.anim) {
+		uint32 now = _system->getMillis();
+		if (now > _nextUpdate) {
+			_nextUpdate = now + _anim.delay * _vm->tickLength();
+
+			_anim.anim->displayFrame(_animIntern.curFrame, 0, 0, 0, 0, 0, 0);
+			_animIntern.curFrame += _animIntern.direction;
+			if (_animIntern.curFrame < _anim.startFrame) {
+				_animIntern.curFrame = _anim.startFrame;
+				_animIntern.direction = 1;
+			} else if (_animIntern.curFrame > _anim.endFrame) {
+				_animIntern.curFrame = _anim.endFrame;
+				_animIntern.direction = -1;
+			}
+		}
+	}
+
+	_screen->updateScreen();
+}
+
+bool MainMenu::getInput() {
+	Common::Event event;
+	Common::EventManager *eventMan = _vm->getEventManager();
+
+	bool updateScreen = false;
+
+	while (eventMan->pollEvent(event)) {
+		switch (event.type) {
+		case Common::EVENT_LBUTTONUP:
+			return true;
+
+		case Common::EVENT_MOUSEMOVE:
+			updateScreen = true;
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	if (updateScreen)
+		_system->updateScreen();
+	return false;
+}
+
+int MainMenu::handle(int dim) {
+	int command = -1;
+
+	uint8 colorMap[16];
+	memset(colorMap, 0, sizeof(colorMap));
+	_screen->setTextColorMap(colorMap);
+
+	Screen::FontId oldFont = _screen->setFont(_static.font);
+	int charWidthBackUp = _screen->_charWidth;
+
+	if (_vm->game() != GI_LOL)
+		_screen->_charWidth = -2;
+	_screen->setScreenDim(dim);
+
+	int backUpX = _screen->_curDim->sx;
+	int backUpY = _screen->_curDim->sy;
+	int backUpWidth = _screen->_curDim->w;
+	int backUpHeight = _screen->_curDim->h;
+	_screen->copyRegion(backUpX, backUpY, backUpX, backUpY, backUpWidth, backUpHeight, 0, 3);
+
+	int x = _screen->_curDim->sx << 3;
+	int y = _screen->_curDim->sy;
+	int width = _screen->_curDim->w << 3;
+	int height =  _screen->_curDim->h;
+
+	drawBox(x, y, width, height, 1);
+	drawBox(x + 1, y + 1, width - 2, height - 2, 0);
+
+	int selected = 0;
+
+	draw(selected);
+
+	while (!_screen->isMouseVisible())
+		_screen->showMouse();
+
+	int fh = _screen->getFontHeight();
+	if (_vm->gameFlags().lang == Common::JA_JPN)
+		fh++;
+
+	int textPos = ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3;
+
+	Common::Rect menuRect(x + 16, y + 4, x + width - 16, y + 4 + fh * _static.menuTable[3]);
+
+	while (!_vm->shouldQuit()) {
+		updateAnimation();
+		bool mousePressed = getInput();
+
+		Common::Point mouse = _vm->getMousePos();
+		if (menuRect.contains(mouse)) {
+			int item = (mouse.y - menuRect.top) / fh;
+
+			if (item != selected) {
+				printString("%s", textPos, menuRect.top + selected * fh, _static.menuTable[5], 0, 5, _static.strings[selected]);
+				printString("%s", textPos, menuRect.top + item * fh, _static.menuTable[6], 0, 5, _static.strings[item]);
+
+				selected = item;
+			}
+
+			if (mousePressed) {
+				for (int i = 0; i < 3; i++) {
+					printString("%s", textPos, menuRect.top + selected * fh, _static.menuTable[5], 0, 5, _static.strings[selected]);
+					_screen->updateScreen();
+					_system->delayMillis(50);
+					printString("%s", textPos, menuRect.top + selected * fh, _static.menuTable[6], 0, 5, _static.strings[selected]);
+					_screen->updateScreen();
+					_system->delayMillis(50);
+				}
+				command = item;
+				break;
+			}
+		}
+		_system->delayMillis(10);
+	}
+
+	if (_vm->shouldQuit())
+		command = -1;
+
+	_screen->copyRegion(backUpX, backUpY, backUpX, backUpY, backUpWidth, backUpHeight, 3, 0);
+	_screen->_charWidth = charWidthBackUp;
+	_screen->setFont(oldFont);
+
+	return command;
+}
+
+void MainMenu::draw(int select) {
+	int top = _screen->_curDim->sy;
+	top += _static.menuTable[1];
+	int fh = _screen->getFontHeight();
+	if (_vm->gameFlags().lang == Common::JA_JPN)
+		fh++;
+
+	for (int i = 0; i < _static.menuTable[3]; ++i) {
+		int curY = top + i * fh;
+		int color = (i == select) ? _static.menuTable[6] : _static.menuTable[5];
+		printString("%s", ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3, curY, color, 0, 5, _static.strings[i]);
+	}
+}
+
+void MainMenu::drawBox(int x, int y, int w, int h, int fill) {
+	--w; --h;
+
+	if (fill)
+		_screen->fillRect(x, y, x+w, y+h, _static.colorTable[0]);
+
+	_screen->drawClippedLine(x, y+h, x+w, y+h, _static.colorTable[1]);
+	_screen->drawClippedLine(x+w, y, x+w, y+h, _static.colorTable[1]);
+	_screen->drawClippedLine(x, y, x+w, y, _static.colorTable[2]);
+	_screen->drawClippedLine(x, y, x, y+h, _static.colorTable[2]);
+
+	_screen->setPagePixel(_screen->_curPage, x, y+h, _static.colorTable[3]);
+	_screen->setPagePixel(_screen->_curPage, x+w, y, _static.colorTable[3]);
+}
+
+void MainMenu::printString(const char *format, int x, int y, int col1, int col2, int flags, ...) {
+	if (!format)
+		return;
+
+	va_list vaList;
+	va_start(vaList, flags);
+	Common::String string = Common::String::vformat(format, vaList);
+	va_end(vaList);
+
+	if (flags & 1)
+		x -= _screen->getTextWidth(string.c_str()) >> 1;
+
+	if (flags & 2)
+		x -= _screen->getTextWidth(string.c_str());
+
+	if (_vm->gameFlags().use16ColorMode)
+		flags &= 3;
+
+	if (flags & 4) {
+		_screen->printText(string.c_str(), x - 1, y, _static.altColor, col2);
+		_screen->printText(string.c_str(), x, y + 1, _static.altColor, col2);
+	}
+
+	if (flags & 8) {
+		_screen->printText(string.c_str(), x - 1, y, 227, col2);
+		_screen->printText(string.c_str(), x, y + 1, 227, col2);
+	}
+
+	_screen->printText(string.c_str(), x, y, col1, col2);
+}
+
+} // End of namespace Kyra
+
diff --git a/engines/kyra/gui_v1.h b/engines/kyra/gui_v1.h
new file mode 100644
index 0000000..ec0d577
--- /dev/null
+++ b/engines/kyra/gui_v1.h
@@ -0,0 +1,198 @@
+/* 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.
+ *
+ */
+
+#ifndef KYRA_GUI_V1_H
+#define KYRA_GUI_V1_H
+
+#include "kyra/gui.h"
+
+namespace Kyra {
+
+struct MenuItem {
+	bool enabled;
+
+	const char *itemString;
+	uint16 itemId;
+
+	int16 x, y;
+	uint16 width, height;
+
+	uint8 textColor, highlightColor;
+
+	int16 titleX;
+
+	uint8 color1, color2;
+	uint8 bkgdColor;
+
+	Button::Callback callback;
+
+	int16 saveSlot;
+
+	const char *labelString;
+	uint16 labelId;
+	int16 labelX, labelY;
+
+	uint16 keyCode;
+};
+
+struct Menu {
+	int16 x, y;
+	uint16 width, height;
+
+	uint8 bkgdColor;
+	uint8 color1, color2;
+
+	const char *menuNameString;
+	uint16 menuNameId;
+
+	uint8 textColor;
+	int16 titleX, titleY;
+
+	uint8 highlightedItem;
+
+	uint8 numberOfItems;
+
+	int16 scrollUpButtonX, scrollUpButtonY;
+	int16 scrollDownButtonX, scrollDownButtonY;
+
+	MenuItem item[7];
+};
+
+class TextDisplayer;
+
+class GUI_v1 : public GUI {
+public:
+	GUI_v1(KyraEngine_v1 *vm);
+	virtual ~GUI_v1() {}
+
+	// button specific
+	virtual Button *addButtonToList(Button *list, Button *newButton);
+
+	virtual void processButton(Button *button) = 0;
+	virtual int processButtonList(Button *buttonList, uint16 inputFlags, int8 mouseWheel) = 0;
+
+	virtual int redrawShadedButtonCallback(Button *button);
+	virtual int redrawButtonCallback(Button *button);
+
+	// menu specific
+	virtual void initMenuLayout(Menu &menu);
+	void initMenu(Menu &menu);
+
+	void processHighlights(Menu &menu);
+
+	// utilities for thumbnail creation
+	virtual void createScreenThumbnail(Graphics::Surface &dst) = 0;
+
+protected:
+	TextDisplayer *_text;
+
+	Button *_menuButtonList;
+	bool _displayMenu;
+	bool _displaySubMenu;
+	bool _cancelSubMenu;
+
+	virtual void printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2);
+	virtual int getMenuCenterStringX(const char *str, int x1, int x2);
+
+	Button::Callback _redrawShadedButtonFunctor;
+	Button::Callback _redrawButtonFunctor;
+
+	virtual Button *getButtonListData() = 0;
+	virtual Button *getScrollUpButton() = 0;
+	virtual Button *getScrollDownButton() = 0;
+
+	virtual Button::Callback getScrollUpButtonHandler() const = 0;
+	virtual Button::Callback getScrollDownButtonHandler() const = 0;
+
+	virtual uint8 defaultColor1() const = 0;
+	virtual uint8 defaultColor2() const = 0;
+
+	virtual const char *getMenuTitle(const Menu &menu) = 0;
+	virtual const char *getMenuItemTitle(const MenuItem &menuItem) = 0;
+	virtual const char *getMenuItemLabel(const MenuItem &menuItem) = 0;
+
+	void updateAllMenuButtons();
+	void updateMenuButton(Button *button);
+	virtual void updateButton(Button *button);
+
+	void redrawText(const Menu &menu);
+	void redrawHighlight(const Menu &menu);
+
+	uint32 _lastScreenUpdate;
+	void checkTextfieldInput();
+};
+
+class Movie;
+
+class MainMenu {
+public:
+	MainMenu(KyraEngine_v1 *vm);
+	virtual ~MainMenu() {}
+
+	struct Animation {
+		Animation() : anim(0), startFrame(0), endFrame(0), delay(0) {}
+
+		Movie *anim;
+		int startFrame;
+		int endFrame;
+		int delay;
+	};
+
+	struct StaticData {
+		const char *strings[5];
+
+		uint8 menuTable[7];
+		uint8 colorTable[4];
+
+		Screen::FontId font;
+		uint8 altColor;
+	};
+
+	void init(StaticData data, Animation anim);
+	int handle(int dim);
+private:
+	KyraEngine_v1 *_vm;
+	Screen *_screen;
+	OSystem *_system;
+
+	StaticData _static;
+	struct AnimIntern {
+		int curFrame;
+		int direction;
+	};
+	Animation _anim;
+	AnimIntern _animIntern;
+
+	uint32 _nextUpdate;
+
+	void updateAnimation();
+	void draw(int select);
+	void drawBox(int x, int y, int w, int h, int fill);
+	bool getInput();
+
+	void printString(const char *string, int x, int y, int col1, int col2, int flags, ...) GCC_PRINTF(2, 8);
+};
+
+} // end of namesapce Kyra
+
+#endif
+
diff --git a/engines/kyra/gui_v2.h b/engines/kyra/gui_v2.h
index 402766b..bdbcce1 100644
--- a/engines/kyra/gui_v2.h
+++ b/engines/kyra/gui_v2.h
@@ -23,7 +23,7 @@
 #ifndef KYRA_GUI_V2_H
 #define KYRA_GUI_V2_H
 
-#include "kyra/gui.h"
+#include "kyra/gui_v1.h"
 
 namespace Kyra {
 
diff --git a/engines/kyra/kyra_hof.h b/engines/kyra/kyra_hof.h
index 3acefdd..a6add50 100644
--- a/engines/kyra/kyra_hof.h
+++ b/engines/kyra/kyra_hof.h
@@ -199,7 +199,7 @@ public:
 
 	Screen *screen() { return _screen; }
 	Screen_v2 *screen_v2() const { return _screen; }
-	GUI_v1 *gui() const { return _gui; }
+	GUI *gui() const { return _gui; }
 	virtual TextDisplayer *text() { return _text; }
 	int language() const { return _lang; }
 protected:
diff --git a/engines/kyra/kyra_lok.h b/engines/kyra/kyra_lok.h
index 3ecefba..e5fb3cd 100644
--- a/engines/kyra/kyra_lok.h
+++ b/engines/kyra/kyra_lok.h
@@ -109,7 +109,7 @@ public:
 
 	Screen *screen() { return _screen; }
 	Animator_LoK *animator() { return _animator; }
-	GUI_v1 *gui() const { return _gui; }
+	GUI *gui() const { return _gui; }
 	virtual Movie *createWSAMovie();
 
 	uint8 **shapes() { return _shapes; }
diff --git a/engines/kyra/kyra_mr.h b/engines/kyra/kyra_mr.h
index 4b3e8b3..38ff271 100644
--- a/engines/kyra/kyra_mr.h
+++ b/engines/kyra/kyra_mr.h
@@ -54,7 +54,7 @@ public:
 
 	Screen *screen() { return _screen; }
 	Screen_v2 *screen_v2() const { return _screen; }
-	GUI_v1 *gui() const { return _gui; }
+	GUI *gui() const { return _gui; }
 	SoundDigital *soundDigital() { return _soundDigital; }
 	int language() const { return _lang; }
 	bool heliumMode() const { return _configHelium; }
diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp
index 72cc5bc..c1b9f2a 100644
--- a/engines/kyra/kyra_v1.cpp
+++ b/engines/kyra/kyra_v1.cpp
@@ -345,7 +345,7 @@ int KyraEngine_v1::checkInput(Button *buttonList, bool mainLoop, int eventFlag)
 		_eventList.erase(_eventList.begin());
 	}
 
-	GUI_v1 *guiInstance = gui();
+	GUI *guiInstance = gui();
 	if (guiInstance) {
 		if (keys)
 			return guiInstance->processButtonList(buttonList, keys | eventFlag, mouseWheel);
diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h
index 3a4be46..f530c02 100644
--- a/engines/kyra/kyra_v1.h
+++ b/engines/kyra/kyra_v1.h
@@ -176,13 +176,14 @@ class TextDisplayer;
 class StaticResource;
 class TimerManager;
 class Debugger;
-class GUI_v1;
+class GUI;
 
 struct Button;
 
 class KyraEngine_v1 : public Engine {
 friend class Debugger;
 friend class ::KyraMetaEngine;
+friend class GUI;
 friend class GUI_v1;
 friend class SoundMidiPC;    // For _eventMan
 public:
@@ -196,7 +197,7 @@ public:
 	Resource *resource() { return _res; }
 	virtual Screen *screen() = 0;
 	virtual TextDisplayer *text() { return _text; }
-	virtual GUI_v1 *gui() const { return 0; }
+	virtual GUI *gui() const { return 0; }
 	Sound *sound() { return _sound; }
 	StaticResource *staticres() { return _staticres; }
 	TimerManager *timer() { return _timer; }
diff --git a/engines/kyra/kyra_v2.h b/engines/kyra/kyra_v2.h
index 7896748..3d7b9c4 100644
--- a/engines/kyra/kyra_v2.h
+++ b/engines/kyra/kyra_v2.h
@@ -24,7 +24,7 @@
 #define KYRA_KYRA_V2_H
 
 #include "kyra/kyra_v1.h"
-#include "kyra/gui.h"
+#include "kyra/gui_v1.h"
 #include "kyra/wsamovie.h"
 #include "kyra/item.h"
 
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 8e978c1..7a4a3ec 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -357,7 +357,7 @@ Screen *LoLEngine::screen() {
 	return _screen;
 }
 
-GUI_v1 *LoLEngine::gui() const {
+GUI *LoLEngine::gui() const {
 	return _gui;
 }
 
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index a33263f..8ddba86 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -279,7 +279,7 @@ public:
 	virtual void initKeymap();
 
 	Screen *screen();
-	GUI_v1 *gui() const;
+	GUI *gui() const;
 
 private:
 	Screen_LoL *_screen;
diff --git a/engines/kyra/loleobbase.h b/engines/kyra/loleobbase.h
index 8bebfe4..a2c1382 100644
--- a/engines/kyra/loleobbase.h
+++ b/engines/kyra/loleobbase.h
@@ -86,7 +86,7 @@ public:
 	virtual ~LolEobBaseEngine();
 
 	virtual Screen *screen() = 0;
-	virtual GUI_v1 *gui() const = 0;
+	virtual GUI *gui() const = 0;
 
 protected:
 	// Startup
diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk
index 50bcbdd..6eed6da 100644
--- a/engines/kyra/module.mk
+++ b/engines/kyra/module.mk
@@ -9,6 +9,7 @@ MODULE_OBJS := \
 	debugger.o \
 	detection.o \
 	gui.o \
+	gui_v1.o \
 	gui_lok.o \
 	gui_v2.o \
 	gui_hof.o \
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index e348ef2..6800a13 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -665,8 +665,7 @@ void EobCoreEngine::initMenus() {
 		{  32,  40,  16,  24,  20,   3,  5  },
 		{  33,  72,  16,  24,  20,   4,  5  },
 		{  34, 104,  16,  24,  20,   5,  5  },
-		{  35, 136,  16,  24,  20,   6,  5  },
-		{  31,   8,  16,  24,  20,   2,  5  }
+		{  35, 136,  16,  24,  20,   6,  5  }
 	};
 
 	_menuButtonDefs = buttonDefs;


Commit: c53589bcda2875154b2590f264838b1be728d1f3
    https://github.com/scummvm/scummvm/commit/c53589bcda2875154b2590f264838b1be728d1f3
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:12-08:00

Commit Message:
KYRA: (EOB) - implement load menu

(only 6 slots supported for now)

Changed paths:
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui.cpp
    engines/kyra/gui_eob.cpp
    engines/kyra/gui_eob.h
    engines/kyra/saveload_eob.cpp
    engines/kyra/sequences_eob2.cpp
    engines/kyra/staticres_eob.cpp



diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 0cc2f5a..2d5c4e6 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -359,8 +359,11 @@ Common::Error EobCoreEngine::go() {
 
 		if (action == -1) {
 			// load game
-			_saveLoadMode = -1;
-			startupLoad();
+			repeatLoop = _gui->runLoadMenu(72, 14);
+			if (repeatLoop && !shouldQuit()) {
+				_saveLoadMode = -1;
+				startupLoad();
+			}
 		} else if (action == -2) {
 			// new game
 			repeatLoop = startCharacterGeneration();
@@ -368,6 +371,7 @@ Common::Error EobCoreEngine::go() {
 				startupNew();
 		} else if (action == -3) {
 			// transfer party
+			repeatLoop = false;
 		}
 	}
 
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 0f9210e..eae03ac 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -786,7 +786,9 @@ protected:
 	void releaseMonsterTempData(LevelTempData *tmp);
 
 	int _saveLoadMode;
-	
+
+	const char * const *_saveLoadStrings;
+
 	Screen_Eob *_screen;
 	GUI_Eob *_gui;
 
@@ -999,6 +1001,7 @@ protected:
 	const char *const *_menuStringsRest3;
 	const char *const *_menuStringsRest4;
 	const char *const *_menuStringsDefeat;
+	const char *_errorSlotEmptyString;
 
 	const char *const *_menuStringsTransfer;
 	const char *const *_menuStringsSpec;
diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp
index 4746163..d03fa23 100644
--- a/engines/kyra/gui.cpp
+++ b/engines/kyra/gui.cpp
@@ -109,7 +109,12 @@ void GUI::updateSavegameList() {
 	_savegameListSize = _saveSlots.size();
 
 	if (_savegameListSize) {
-		Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Greater<int>());
+		if (_vm->game() == GI_EOB1 || _vm->game() == GI_EOB2) {
+			Common::sort(_saveSlots.begin(), _saveSlots.end(),  Common::Less<int>());
+			_savegameListSize = _saveSlots.back() + 1;
+		} else {
+			Common::sort(_saveSlots.begin(), _saveSlots.end(),  Common::Greater<int>());
+		}
 
 		KyraEngine_v1::SaveHeader header;
 		Common::InSaveFile *in;
@@ -125,7 +130,6 @@ void GUI::updateSavegameList() {
 				delete in;
 			} else {
 				_savegameList[i] = 0;
-				error("GUI::updateSavegameList(): Unexpected missing save file for slot: %d.", i);
 			}
 		}
 
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 6eab4a0..4eb2497 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -1435,6 +1435,15 @@ GUI_Eob::GUI_Eob(EobCoreEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) {
 	_menuStringsPrefsTemp = new char*[4];
 	memset(_menuStringsPrefsTemp, 0, 4 * sizeof(char*));
 
+	_saveSlotStringsTemp = new char*[6];
+	for (int i = 0; i < 6; i++) {
+		_saveSlotStringsTemp[i] = new char[20];
+		memset(_saveSlotStringsTemp[i], 0, 20);
+	}
+	_saveSlotIdTemp = new int16[6];
+	_savegameOffset = 0;
+	_saveSlotX = _saveSlotY = 0;
+
 	_specialProcessButton = _backupButtonList = 0;
 	_flagsMouseLeft = _flagsMouseRight = _flagsModifier = 0;
 	_backupButtonList = 0;
@@ -1469,6 +1478,14 @@ GUI_Eob::~GUI_Eob() {
 		delete[] _menuStringsPrefsTemp;
 	}
 
+	if (_saveSlotStringsTemp) {
+		for (int i = 0; i < 6; i++)
+			delete[] _saveSlotStringsTemp[i];
+		delete[] _saveSlotStringsTemp;
+	}
+
+	delete[] _saveSlotIdTemp;
+
 	delete[] _numAssignedSpellsOfType;
 }
 
@@ -2285,11 +2302,9 @@ void GUI_Eob::runCampMenu() {
 		}
 	}
 
+	_screen->setFont(of);
 	releaseButtons(buttonList);
-	
 	_vm->writeSettings();
-	
-	_screen->setFont(of);
 }
 
 bool GUI_Eob::runLoadMenu(int x, int y) {
@@ -2299,13 +2314,27 @@ bool GUI_Eob::runLoadMenu(int x, int y) {
 	bool result = false;
 	_savegameListUpdateNeeded = true;
 	
-	_screen->modifyScreenDim(11, dm->sx + (x >> 8), dm->sy + y, dm->w, dm->sy);
+	_screen->modifyScreenDim(11, dm->sx + (x >> 3), dm->sy + y, dm->w, dm->h);
 	
 	updateSavegameList();
-	setupSaveMenuSlots();
 
-	_screen->modifyScreenDim(11, xo, yo, dm->w, dm->sy);
+	for (bool runLoop = true; runLoop; ) {	
+		int slot = selectSaveSlotDialogue(x, y, 1);
+		if (slot > 5) {
+			runLoop = result = false;
+		} else if (slot >= 0) {
+			if (_saveSlotIdTemp[slot] == -1) {
+				messageDialogue(11, 65, 6);
+			} else {
+				if (_vm->loadGameState(_saveSlotIdTemp[slot]).getCode() != Common::kNoError)
+					messageDialogue(11, 16, 6);
+				runLoop = false;
+				result = true;
+			}
+		}
+	}
 
+	_screen->modifyScreenDim(11, xo, yo, dm->w, dm->h);
 	return result;
 }
 
@@ -2479,7 +2508,95 @@ void GUI_Eob::simpleMenu_initMenuItemsMask(int menuId, int maxItem, int32 menuIt
 }
 
 bool GUI_Eob::runSaveMenu(int x, int y) {
-	return true;
+	const ScreenDim *dm = _screen->getScreenDim(11);
+	int xo = dm->sx;
+	int yo = dm->sy;
+	bool result = false;
+	_savegameListUpdateNeeded = true;
+	
+	_screen->modifyScreenDim(11, dm->sx + (x >> 3), dm->sy + y, dm->w, dm->h);
+	
+	updateSavegameList();
+
+	/*for (bool runLoop = true; runLoop; ) {	
+		int slot = selectSaveSlotDialogue(x, y, 1);
+		if (slot > 5) {
+			runLoop = result = false;
+		} else if (slot >= 0) {
+			if (_saveSlotIdTemp[slot] == -1) {
+				messageDialogue(11, 65, 6);
+			} else {
+				if (_vm->loadGameState(_saveSlotIdTemp[slot]).getCode() != Common::kNoError)
+					messageDialogue(11, 16, 6);
+				runLoop = false;
+				result = true;
+			}
+		}
+	}*/
+
+	_screen->modifyScreenDim(11, xo, yo, dm->w, dm->h);
+	return result;
+}
+
+int GUI_Eob::selectSaveSlotDialogue(int x, int y, int id) {
+	assert (id < 2);
+
+	_saveSlotX = _saveSlotY = 0;
+	_screen->setCurPage(2);
+	
+	setupSaveMenuSlots();
+	drawMenuButtonBox(0, 0, 176, 144, false, false);
+	_screen->printShadedText(_vm->_saveLoadStrings[2 + id], 52, 5, 15, 0);
+	
+	for (int i = 0; i < 7; i++)
+		drawSaveSlotButton(i, 1, 15);
+
+	_screen->copyRegion(0, 0, x, y, 176, 144, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->setCurPage(0);
+	_screen->updateScreen();
+
+	_saveSlotX = x;
+	_saveSlotY = y;
+	int lastHighlight = -1;
+	int newHighlight = 0;
+	int slot = -1;
+
+	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {		
+		int inputFlag = _vm->checkInput(0, false, 0) & 0x8ff;
+		_vm->removeInputTop();
+
+		if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
+			runLoop = false;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP2]) {
+			if (++newHighlight > 6)
+				newHighlight = 0;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP8]) {
+			if (--newHighlight < 0)
+				newHighlight = 6;
+		} else {
+			slot = getHighlightSlot();
+			if (slot != -1) {
+				newHighlight = slot;
+				if (inputFlag == 199)
+					runLoop = false;
+			}
+		}
+
+		if (lastHighlight != newHighlight) {
+			drawSaveSlotButton(lastHighlight, 0, 15);
+			drawSaveSlotButton(newHighlight, 0, 6);
+			_screen->updateScreen();
+			lastHighlight = newHighlight;
+		}
+	}
+
+	drawSaveSlotButton(newHighlight, 2, 6);
+	_screen->updateScreen();
+	_vm->_system->delayMillis(80);
+	drawSaveSlotButton(newHighlight, 1, 6);
+	_screen->updateScreen();
+
+	return newHighlight;
 }
 
 void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
@@ -2674,7 +2791,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
 				updateDesc = true;
 			}
 
-		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP_MINUS] || inputFlag == _vm->_keyMap[Common::KEYCODE_MINUS] /*|| inputFlag == _vm->_keyMap[Common::KEYCODE_*/) {
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP_MINUS] || inputFlag == _vm->_keyMap[Common::KEYCODE_MINUS]) {
 			if (np[lastHighLightButton] && _numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1] * 2 - 2]) {
 				_numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1] * 2 - 2]--;
 				numAssignedSpellsPerBookPage[lastHighLightButton]--;
@@ -2826,6 +2943,47 @@ bool GUI_Eob::confirmDialogue(int id) {
 	return result;
 }
 
+void GUI_Eob::messageDialogue(int dim, int id, int buttonTextCol) {
+	static const char buttonText[] = "OK";
+
+	int od = _screen->curDimIndex();
+	_screen->setScreenDim(dim);
+	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+
+	drawTextBox(dim, id);
+	const ScreenDim *dm = _screen->getScreenDim(dim);
+	
+	int bx = ((dm->sx + dm->w) << 3) - ((strlen(buttonText) << 3) + 16);
+	int by = dm->sy + dm->h - 19;
+	int bw = (strlen(buttonText) << 3) + 7;
+
+	drawMenuButtonBox(bx, by, bw, 14, false, false);
+	_screen->printShadedText(buttonText, bx + 4, by + 3, buttonTextCol, 0);
+	_screen->updateScreen();
+
+	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
+		int inputFlag = _vm->checkInput(0, false, 0) & 0x8ff;
+		_vm->removeInputTop();
+
+		if (inputFlag == 199 || inputFlag == 201) {
+			Common::Point p = _vm->getMousePos();
+				if (_vm->posWithinRect(p.x, p.y, bx, by, bx + bw, by + 14))
+					runLoop = false;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_o]) {
+			runLoop = false;
+		}
+	}
+
+	drawMenuButtonBox(bx, by, bw, 14, true, true);
+	_screen->updateScreen();
+	_vm->_system->delayMillis(80);
+	drawMenuButtonBox(bx, by, bw, 14, false, true);
+	_screen->updateScreen();
+
+	_screen->setScreenDim(od);
+	_screen->setFont(of);
+}
+
 int GUI_Eob::selectCharacterDialogue(int id) {
 	uint8 flags = (id == 26) ? 0x14 : 0x02;
 	_vm->removeInputTop();
@@ -3084,6 +3242,48 @@ void GUI_Eob::drawMenuButtonBox(int x, int y, int w, int h, bool clicked, bool n
 	_vm->gui_drawBox(x + 1, y + 1, w - 2, h - 2, _vm->_color1_1, _vm->_color2_1, noFill ? -1 : _vm->_bkgColor_1);
 }
 
+void GUI_Eob::drawTextBox(int dim, int id) {
+	int od = _screen->curDimIndex();
+	_screen->setScreenDim(dim);
+	const ScreenDim *dm = _screen->getScreenDim(dim);
+	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+
+	if (dm->w <= 22 && dm->h <= 84)
+		_screen->copyRegion(dm->sx << 3, dm->sy, 0, dm->h, dm->w << 3, dm->h, 0, 2, Screen::CR_NO_P_CHECK);
+
+	_screen->setCurPage(2);
+
+	drawMenuButtonBox(0, 0, dm->w << 3, dm->h, false, false);
+	_screen->printShadedText(getMenuString(id), 5, 5, 15, 0);
+
+	_screen->setCurPage(0);
+	_screen->copyRegion(0, 0, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	_screen->setScreenDim(od);
+	_screen->setFont(of);
+}
+
+void GUI_Eob::drawSaveSlotButton(int slot, int redrawBox, int textCol) {
+	if (slot < 0)
+		return;
+
+	int x = _saveSlotX + 4;
+	int y = _saveSlotY + slot * 17 + 20;	
+	int w = 167;
+	const char *s = (slot < 6) ?_saveSlotStringsTemp[slot] : _vm->_saveLoadStrings[0];
+
+	if (slot >= 6 ) {
+		x = _saveSlotX + 118;
+		y = _saveSlotY + 126;
+		w = 53;
+	} 
+	
+	if (redrawBox)
+		drawMenuButtonBox(x, y, w, 14, (redrawBox - 1) ? true : false, false);
+
+	_screen->printShadedText(s, x + 4, y + 3, textCol, 0);
+}
+
 void GUI_Eob::memorizePrayMenuPrintString(int spellId, int bookPageIndex, int spellType, bool noFill, bool highLight) {
 	if (bookPageIndex < 0)
 		return;
@@ -3121,6 +3321,10 @@ const char *GUI_Eob::getMenuString(int id) {
 		return _vm->_menuStringsTransfer[id - 69];
 	else if (id >= 67)
 		return _vm->_menuStringsDefeat[id - 67];
+	else if (id == 66)
+		return _vm->_errorSlotEmptyString;
+	else if (id == 65)
+		return _vm->_errorSlotEmptyString;
 	else if (id >= 63)
 		return _vm->_menuStringsSpec[id - 63];
 	else if (id >= 60)
@@ -3181,7 +3385,35 @@ void GUI_Eob::releaseButtons(Button *list) {
 }
 
 void GUI_Eob::setupSaveMenuSlots() {
+	for (int i = 0; i < 6; ++i) {
+		if (_savegameOffset + i < _savegameListSize) {
+			if (_savegameList[i + _savegameOffset]) {
+				Common::strlcpy(_saveSlotStringsTemp[i], _savegameList[i + _savegameOffset], 20);
+				_saveSlotIdTemp[i] = i + _savegameOffset;
+				continue;
+			}
+		}
+		Common::strlcpy(_saveSlotStringsTemp[i], _vm->_saveLoadStrings[1], 20);
+		_saveSlotIdTemp[i] = -1;
+	}
+}
+
+int GUI_Eob::getHighlightSlot() {
+	int res = -1;
+	Common::Point p = _vm->getMousePos();
+	
+	for (int i = 0; i < 6; i++) {
+		int y = _saveSlotY + i * 17 + 20;
+		if (_vm->posWithinRect(p.x, p.y, _saveSlotX + 4, y, _saveSlotX + 167, y + 14)) {
+			res = i;
+			break;
+		}
+	}
+
+	if (_vm->posWithinRect(p.x, p.y, _saveSlotX + 118, _saveSlotY + 126, _saveSlotX + 171, _saveSlotY + 140))
+		res = 6;
 
+	return res;
 }
 
 #endif // ENABLE_EOB
diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h
index c8e9744..f866c9e 100644
--- a/engines/kyra/gui_eob.h
+++ b/engines/kyra/gui_eob.h
@@ -79,16 +79,20 @@ private:
 	void simpleMenu_initMenuItemsMask(int menuId, int maxItem, int32 menuItemsMask, int unk);
 
 	bool runSaveMenu(int x, int y);
+	int selectSaveSlotDialogue(int x, int y, int id);
 	void runMemorizePrayMenu(int charIndex, int spellType);
 	void scribeScrollDialogue();
 
 	bool confirmDialogue(int id);
+	void messageDialogue(int dim, int id, int buttonTextCol);
 	int selectCharacterDialogue(int id);
 	void displayTextBox(int id);
 	
 	Button *initMenu(int id);	
 	void drawMenuButton(Button *b, bool clicked, bool highlight, bool noFill);
 	void drawMenuButtonBox(int x, int y, int w, int h, bool clicked, bool noFill);
+	void drawTextBox(int dim, int id);
+	void drawSaveSlotButton(int slot, int redrawBox, int textCol);
 	void memorizePrayMenuPrintString(int spellId, int bookPageIndex, int spellType, bool noFill, bool highLight);
 	void updateOptionsStrings();
 	const char *getMenuString(int id);
@@ -97,11 +101,17 @@ private:
 	void releaseButtons(Button *list);
 
 	void setupSaveMenuSlots();
+	int getHighlightSlot();
 
 	Button _scrollUpButton;//////////////////77
 	Button _scrollDownButton;
 
 	char **_menuStringsPrefsTemp;
+	char **_saveSlotStringsTemp;
+	int16 *_saveSlotIdTemp;
+	int _savegameOffset;
+	int16 _saveSlotX;
+	int16 _saveSlotY;
 
 	EobCoreEngine *_vm;
 	Screen_Eob *_screen;
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index 497be6f..72bebf9 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -145,10 +145,8 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 
 	SaveHeader header;
 	Common::InSaveFile *saveFile = openSaveForReading(fileName, header);
-	if (!saveFile) {
-		//_txt->printMessage(2, "%s", getLangString(0x425d));
-		return Common::kNoError;
-	}
+	if (!saveFile)
+		return Common::Error(Common::kReadingFailed);
 
 	Common::SeekableSubReadStreamEndian in(saveFile, saveFile->pos(), saveFile->size(), !header.originalSave, DisposeAfterUse::YES);
 
diff --git a/engines/kyra/sequences_eob2.cpp b/engines/kyra/sequences_eob2.cpp
index 3765ee3..1cc4585 100644
--- a/engines/kyra/sequences_eob2.cpp
+++ b/engines/kyra/sequences_eob2.cpp
@@ -131,7 +131,7 @@ int DarkMoonEngine::mainMenu() {
 
 			case 3:
 				// transfer party
-				seq_playFinale();
+				//seq_playFinale();
 				menuChoice = -3;
 				break;
 
@@ -1030,7 +1030,7 @@ void DarkmoonSequenceHelper::runSequence(int index, int del) {
 			break;
 
 		case 1:
-			// draw shape, then restore beackground
+			// draw shape, then restore background
 			shapeW = _shapes[s->obj][2];
 			shapeH = _shapes[s->obj][3];
 
@@ -1107,7 +1107,7 @@ void DarkmoonSequenceHelper::runSequence(int index, int del) {
 			break;
 
 		case 5:
-			// copyregion
+			// copy region
 			if (_mode == DarkmoonSequenceHelper::kFinale && s->pal)
 				setPaletteWithoutTextColor(palIndex);
 
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 6800a13..6cc7606 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -506,6 +506,23 @@ void EobCoreEngine::initStaticResource() {
 	_sparkEffectOfX = _staticres->loadRawData(kEobBaseSparkOfX, temp);
 	_sparkEffectOfY = _staticres->loadRawData(kEobBaseSparkOfY, temp);
 	_magicFlightObjectProperties = _staticres->loadRawData(kEobBaseMagicFlightProps, temp);
+
+	// Hard code these strings, since EOB 1 doesn't have them in the original
+	// (because there is only one single save slot)
+	static const char *saveLoadStrings[3][4] = {
+		{	"Cancel",	"Empty Slot",	"Save Game",	"Load Game"		},
+		{	"Abbr.",	"Leerer Slot",	"Speichern",	"  Laden"		},
+		{	0,			0,				0,				0				}
+	};
+
+	static const char *errorSlotEmptyString[3] = {
+		"There is no game\rsaved in that slot!",
+		"Hier ist noch kein\rSpiel gespeichert!",
+		0
+	};
+	
+	_saveLoadStrings = saveLoadStrings[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
+	_errorSlotEmptyString = errorSlotEmptyString[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
 }
 
 void EobCoreEngine::initButtonData() {


Commit: 5baabf037df661e4730500ecebca6347031aa295
    https://github.com/scummvm/scummvm/commit/5baabf037df661e4730500ecebca6347031aa295
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:12-08:00

Commit Message:
KYRA: (EOB) - implement save menu

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    engines/kyra/eob1.cpp
    engines/kyra/eob1.h
    engines/kyra/eob2.cpp
    engines/kyra/eob2.h
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/gui_eob.h
    engines/kyra/magic_eob.cpp
    engines/kyra/resource.h
    engines/kyra/saveload_eob.cpp
    engines/kyra/staticres_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index 298d8b2..32280c6 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -272,6 +272,7 @@ const ExtractFilename extractFilenames[] = {
 	{ kEobBaseMenuStringsTransfer, kTypeStringList, true },
 	{ kEobBaseMenuStringsSpec, kTypeStringList, true },
 	{ kEobBaseMenuStringsSpellNo, kTypeStringList, false },
+	{ kEobBaseMenuYesNoStrings, kTypeStringList, true },
 
 	{ kEobBaseSpellLevelsMage, kTypeRawData, false },
 	{ kEobBaseSpellLevelsCleric, kTypeRawData, false },
@@ -1363,6 +1364,8 @@ const char *getIdString(const int id) {
 		return "kEobBaseMenuStringsSpec";
 	case kEobBaseMenuStringsSpellNo:
 		return "kEobBaseMenuStringsSpellNo";
+	case kEobBaseMenuYesNoStrings:
+		return "kEobBaseMenuYesNoStrings";
 	case kEobBaseSpellLevelsMage:
 		return "kEobBaseSpellLevelsMage";
 	case kEobBaseSpellLevelsCleric:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index e2702c4..be0d56a 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -247,6 +247,7 @@ enum kExtractID {
 	kEobBaseMenuStringsTransfer,
 	kEobBaseMenuStringsSpec,
 	kEobBaseMenuStringsSpellNo,
+	kEobBaseMenuYesNoStrings,
 
 	kEobBaseSpellLevelsMage,
 	kEobBaseSpellLevelsCleric,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index f98f712..124d6e3 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1094,6 +1094,7 @@ const int eob1FloppyNeed[] = {
 	kEobBaseMenuStringsRest2,
 	kEobBaseMenuStringsRest4,
 	kEobBaseMenuStringsDefeat,
+	kEobBaseMenuYesNoStrings,
 
 	kEobBaseSpellLevelsMage,
 	kEobBaseSpellLevelsCleric,
@@ -1282,6 +1283,7 @@ const int eob2FloppyNeed[] = {
 	kEobBaseMenuStringsTransfer,
 	kEobBaseMenuStringsSpec,
 	kEobBaseMenuStringsSpellNo,
+	kEobBaseMenuYesNoStrings,
 
 	kEobBaseSpellLevelsMage,
 	kEobBaseSpellLevelsCleric,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index b1f54d2..0e1d954 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -1675,6 +1675,12 @@ const ExtractEntrySearchData kEobBaseMenuStringsSpellNoProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEobBaseMenuYesNoStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000007, 0x000001EE, { { 0x8C, 0xF1, 0x35, 0x1F, 0xD6, 0x1F, 0xA4, 0xA1, 0xD6, 0xD6, 0x0A, 0x27, 0xB9, 0xFC, 0x9E, 0x62 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000008, 0x00000235, { { 0xC7, 0x06, 0xCF, 0xA8, 0xC0, 0xDE, 0xD4, 0x8C, 0x7F, 0xA2, 0x3A, 0xD3, 0x48, 0x51, 0x36, 0x89 } } } },
+	EXTRACT_END_ENTRY
+};
+
 const ExtractEntrySearchData kEobBaseSpellLevelsMageProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000001A, 0x00000042, { { 0x4F, 0xA3, 0x70, 0x0F, 0x6D, 0xB4, 0xC2, 0xAF, 0x12, 0xB4, 0x2E, 0x26, 0xEF, 0x0B, 0x37, 0x92 } } } }, // EOB1
 	{ UNK_LANG, kPlatformUnknown, { 0x00000023, 0x00000074, { { 0xBE, 0x10, 0xFA, 0xD9, 0xB3, 0xB0, 0x4E, 0x73, 0xC9, 0xA1, 0xE2, 0xCE, 0xE8, 0xEC, 0x85, 0x0F } } } }, // EOB2
@@ -3434,7 +3440,8 @@ const ExtractEntry extractProviders[] = {
 	{ kEobBaseMenuStringsTransfer, kEobBaseMenuStringsTransferProvider },
 	{ kEobBaseMenuStringsSpec, kEobBaseMenuStringsSpecProvider },
 	{ kEobBaseMenuStringsSpellNo, kEobBaseMenuStringsSpellNoProvider },
-
+	{ kEobBaseMenuYesNoStrings, kEobBaseMenuYesNoStringsProvider },
+	
 	{ kEobBaseSpellLevelsMage, kEobBaseSpellLevelsMageProvider },
 	{ kEobBaseSpellLevelsCleric, kEobBaseSpellLevelsClericProvider },
 	{ kEobBaseNumSpellsCleric, kEobBaseNumSpellsClericProvider },
diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
index 69071d3..3992b22 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -77,12 +77,6 @@ void EobEngine::startupNew() {
 	EobCoreEngine::startupNew();
 }
 
-void EobEngine::startupLoad() {
-	setHandItem(_itemInHand);
-	loadLevel(_currentLevel, _currentSub);
-	_saveLoadMode = 0;
-}
-
 void EobEngine::npcSequence(int npcIndex) {
 
 
diff --git a/engines/kyra/eob1.h b/engines/kyra/eob1.h
index 8a959e9..8181f32 100644
--- a/engines/kyra/eob1.h
+++ b/engines/kyra/eob1.h
@@ -48,7 +48,7 @@ private:
 
 	// Main loop
 	void startupNew();
-	void startupLoad();
+	void startupLoad() {}
 
 	// Intro/Outro
 	void seq_playOpeningCredits();
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index 56ef838..baed595 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -77,12 +77,6 @@ void DarkMoonEngine::startupNew() {
 	EobCoreEngine::startupNew();
 }
 
-void DarkMoonEngine::startupLoad() {
-	setHandItem(_itemInHand);
-	loadLevel(_currentLevel, _currentSub);
-	_saveLoadMode = 0;
-}
-
 void DarkMoonEngine::npcSequence(int npcIndex) {
 	_screen->loadEobBitmap("OUTTAKE", 5, 3);
 	_screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 6, Screen::CR_NO_P_CHECK);
diff --git a/engines/kyra/eob2.h b/engines/kyra/eob2.h
index 3fabe44..22193ce 100644
--- a/engines/kyra/eob2.h
+++ b/engines/kyra/eob2.h
@@ -64,7 +64,7 @@ private:
 
 	// Main loop
 	void startupNew();
-	void startupLoad();
+	void startupLoad() {}
 
 	// Intro/Outro
 	void seq_playIntro();
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 2d5c4e6..4c8d488 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -45,7 +45,6 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	//_runLoopTimerUnk = 0;
 	_playFinale = false;
 	_runFlag = true;
-	_saveLoadMode = 0;
 	_configMouse = true;
 
 	_largeItemShapes = _smallItemShapes = _thrownItemShapes = _spellShapes = _firebeamShapes = _itemIconShapes =
@@ -360,10 +359,8 @@ Common::Error EobCoreEngine::go() {
 		if (action == -1) {
 			// load game
 			repeatLoop = _gui->runLoadMenu(72, 14);
-			if (repeatLoop && !shouldQuit()) {
-				_saveLoadMode = -1;
+			if (repeatLoop && !shouldQuit())
 				startupLoad();
-			}
 		} else if (action == -2) {
 			// new game
 			repeatLoop = startCharacterGeneration();
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index eae03ac..e6b816e 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -785,8 +785,6 @@ protected:
 	void restoreMonsterTempData(LevelTempData *tmp);
 	void releaseMonsterTempData(LevelTempData *tmp);
 
-	int _saveLoadMode;
-
 	const char * const *_saveLoadStrings;
 
 	Screen_Eob *_screen;
@@ -1006,6 +1004,7 @@ protected:
 	const char *const *_menuStringsTransfer;
 	const char *const *_menuStringsSpec;
 	const char *const *_menuStringsSpellNo;
+	const char *const *_menuYesNoStrings;
 
 	const uint8 *_spellLevelsMage;
 	int _spellLevelsMageSize;
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 4eb2497..1d69a90 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -30,6 +30,7 @@
 
 #include "common/system.h"
 #include "common/savefile.h"
+#include "graphics/scaler.h"
 
 namespace Kyra {
 
@@ -849,9 +850,10 @@ int EobCoreEngine::clickedCamp(Button *button) {
 	}
 
 	_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 14, Screen::CR_NO_P_CHECK);
+	_screen->copyPage(0, 7);
 	
-	_gui->runCampMenu();	
-	
+	_gui->runCampMenu();
+
 	_screen->copyRegion(0, 0, 0, 120, 176, 24, 14, 2, Screen::CR_NO_P_CHECK);
 	_screen->setScreenDim(cd);
 	drawScene(0);
@@ -862,10 +864,7 @@ int EobCoreEngine::clickedCamp(Button *button) {
 	_screen->setCurPage(0);
 	const ScreenDim *dm = _screen->getScreenDim(10);
 	_screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK);	
-	
-	/*if (reloadInv)
-		_screen->loadEobCpsFileToPage("INVENT", 0, 5, 3, 2);*/
-	
+
 	_screen->updateScreen();
 
 	enableSysTimer(2);	
@@ -1430,7 +1429,7 @@ void EobCoreEngine::gui_processInventorySlotClick(int slot) {
 }
 
 GUI_Eob::GUI_Eob(EobCoreEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) {
-	_scrollUpFunctor = _scrollDownFunctor = BUTTON_FUNCTOR(GUI_Eob, this, 0);
+	//_scrollUpFunctor = _scrollDownFunctor = BUTTON_FUNCTOR(GUI_Eob, this, 0);
 
 	_menuStringsPrefsTemp = new char*[4];
 	memset(_menuStringsPrefsTemp, 0, 4 * sizeof(char*));
@@ -2230,8 +2229,7 @@ void GUI_Eob::runCampMenu() {
 			case 0x8009:
 				if (runSaveMenu(0, 0))
 					displayTextBox(14);
-				else
-					newMenu = 1;
+				newMenu = 1;
 				break;
 
 			case 0x800a:
@@ -2316,9 +2314,7 @@ bool GUI_Eob::runLoadMenu(int x, int y) {
 	
 	_screen->modifyScreenDim(11, dm->sx + (x >> 3), dm->sy + y, dm->w, dm->h);
 	
-	updateSavegameList();
-
-	for (bool runLoop = true; runLoop; ) {	
+	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {	
 		int slot = selectSaveSlotDialogue(x, y, 1);
 		if (slot > 5) {
 			runLoop = result = false;
@@ -2490,6 +2486,13 @@ int GUI_Eob::getTextInput(char *dest, int x, int y, int destMaxLen, int textColo
 	return _keyPressed.keycode == Common::KEYCODE_ESCAPE ? -1 : len;
 }
 
+void GUI_Eob::createScreenThumbnail(Graphics::Surface &dst) {
+	uint8 *screenPal = new uint8[768];
+	_screen->getRealPalette(0, screenPal);
+	::createThumbnail(&dst, _screen->getCPagePtr(7), Screen::SCREEN_W, Screen::SCREEN_H, screenPal);
+	delete[] screenPal;
+}
+
 void GUI_Eob::simpleMenu_initMenuItemsMask(int menuId, int maxItem, int32 menuItemsMask, int itemOffset) {
 	if (menuItemsMask == -1) {
 		_menuNumItems = _screen->getScreenDim(19 + menuId)->h;
@@ -2516,23 +2519,49 @@ bool GUI_Eob::runSaveMenu(int x, int y) {
 	
 	_screen->modifyScreenDim(11, dm->sx + (x >> 3), dm->sy + y, dm->w, dm->h);
 	
-	updateSavegameList();
-
-	/*for (bool runLoop = true; runLoop; ) {	
-		int slot = selectSaveSlotDialogue(x, y, 1);
+	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {	
+		int slot = selectSaveSlotDialogue(x, y, 0);
 		if (slot > 5) {
 			runLoop = result = false;
 		} else if (slot >= 0) {
-			if (_saveSlotIdTemp[slot] == -1) {
-				messageDialogue(11, 65, 6);
-			} else {
-				if (_vm->loadGameState(_saveSlotIdTemp[slot]).getCode() != Common::kNoError)
-					messageDialogue(11, 16, 6);
-				runLoop = false;
+			bool useSlot = (_saveSlotIdTemp[slot] == -1);
+			if (useSlot)
+				_saveSlotStringsTemp[slot][0] = 0;
+			else
+				useSlot = confirmDialogue2(11, 55, 1);
+			
+			if (!useSlot)
+				continue;
+
+			int fx = (x + 1) << 3;
+			int fy = y + slot * 17 + 23;
+			
+			for (int in = -1; in == -1 && !_vm->shouldQuit(); ) {
+				_screen->fillRect(fx - 2, fy, fx + 160, fy + 8, _vm->_bkgColor_1);
+				in = getTextInput(_saveSlotStringsTemp[slot], x + 1, fy, 19, 2, 0, 8);
+				if (!strlen(_saveSlotStringsTemp[slot])) {
+					messageDialogue(11, 54, 6);
+					in = -1;
+				}
+			};
+
+			_screen->fillRect(fx - 2, fy, fx + 160, fy + 8, _vm->_bkgColor_1);
+			_screen->printShadedText(_saveSlotStringsTemp[slot], (x + 1) << 3, fy, 15, 0);
+
+			Graphics::Surface thumb;
+			createScreenThumbnail(thumb);
+			Common::Error err = _vm->saveGameStateIntern(_savegameOffset + slot, _saveSlotStringsTemp[slot], &thumb);
+			thumb.free();
+
+			if (err.getCode() == Common::kNoError) {
+				_savegameListUpdateNeeded = true;			
 				result = true;
+			} else {
+				messageDialogue(11, 15, 6);
 			}
+			runLoop = false;			
 		}
-	}*/
+	}
 
 	_screen->modifyScreenDim(11, xo, yo, dm->w, dm->h);
 	return result;
@@ -2544,7 +2573,9 @@ int GUI_Eob::selectSaveSlotDialogue(int x, int y, int id) {
 	_saveSlotX = _saveSlotY = 0;
 	_screen->setCurPage(2);
 	
+	updateSavegameList();
 	setupSaveMenuSlots();
+
 	drawMenuButtonBox(0, 0, 176, 144, false, false);
 	_screen->printShadedText(_vm->_saveLoadStrings[2 + id], 52, 5, 15, 0);
 	
@@ -2943,6 +2974,74 @@ bool GUI_Eob::confirmDialogue(int id) {
 	return result;
 }
 
+bool GUI_Eob::confirmDialogue2(int dim, int id, int deflt) {
+	int od = _screen->curDimIndex();
+	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+	_screen->setScreenDim(dim);
+
+	drawTextBox(dim, id);
+
+	int16 x[2];
+	x[0] = (_screen->_curDim->sx << 3) + 8;
+	x[1] = (_screen->_curDim->sx + _screen->_curDim->w - 5) << 3;
+	int16 y = _screen->_curDim->sy + _screen->_curDim->h - 21;
+	int newHighlight = deflt ^ 1;
+	int lastHighlight = -1;
+	
+	for (int i = 0; i < 2; i++)
+		drawMenuButtonBox(x[i], y, 32, 14, false, false);
+
+	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
+		Common::Point p = _vm->getMousePos();
+		if (_vm->posWithinRect(p.x, p.y, x[0], y, x[0] + 32, y + 14))
+			newHighlight = 0;
+		else if (_vm->posWithinRect(p.x, p.y, x[1], y, x[1] + 32, y + 14))
+			newHighlight = 1;
+
+		int inputFlag = _vm->checkInput(0, false, 0) & 0x8ff;
+		_vm->removeInputTop();
+
+		if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
+			runLoop = false;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP6]) {
+			newHighlight ^= 1;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_n]) {
+			newHighlight = 1;
+			runLoop = false;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_y]) {
+			newHighlight = 0;
+			runLoop = false;
+		}  else if (inputFlag == 199 || inputFlag == 201) {
+			if (_vm->posWithinRect(p.x, p.y, x[0], y, x[0] + 32, y + 14)) {
+				newHighlight = 0;
+				runLoop = false;
+			} else if (_vm->posWithinRect(p.x, p.y, x[1], y, x[1] + 32, y + 14)) {
+				newHighlight = 1;
+				runLoop = false;
+			}
+		}
+
+		if (newHighlight != lastHighlight) {
+			for (int i = 0; i < 2; i++)				
+				_screen->printShadedText(_vm->_menuYesNoStrings[i], x[i] + 16 - (strlen(_vm->_menuYesNoStrings[i]) << 2) + 1, y + 3, i == newHighlight ? 6 : 15, 0);
+			_screen->updateScreen();
+			lastHighlight = newHighlight;
+		}
+	}
+
+	drawMenuButtonBox(x[newHighlight], y, 32, 14, true, true);
+	_screen->updateScreen();
+	_vm->_system->delayMillis(80);
+	drawMenuButtonBox(x[newHighlight], y, 32, 14, false, true);
+	_screen->updateScreen();
+
+	_screen->copyRegion(0, _screen->_curDim->h, _screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->setFont(of);
+	_screen->setScreenDim(od);
+	
+	return newHighlight ? false : true;
+}
+
 void GUI_Eob::messageDialogue(int dim, int id, int buttonTextCol) {
 	static const char buttonText[] = "OK";
 
@@ -2979,9 +3078,11 @@ void GUI_Eob::messageDialogue(int dim, int id, int buttonTextCol) {
 	_vm->_system->delayMillis(80);
 	drawMenuButtonBox(bx, by, bw, 14, false, true);
 	_screen->updateScreen();
-
+	
+	_screen->copyRegion(0, dm->h, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK);
 	_screen->setScreenDim(od);
 	_screen->setFont(of);
+	dm = _screen->getScreenDim(dim);
 }
 
 int GUI_Eob::selectCharacterDialogue(int id) {
diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h
index f866c9e..234f2f6 100644
--- a/engines/kyra/gui_eob.h
+++ b/engines/kyra/gui_eob.h
@@ -67,11 +67,7 @@ public:
 	int getTextInput(char *dest, int x, int y, int destMaxLen, int textColor1, int textColor2, int cursorColor);
 
 	// utilities for thumbnail creation
-	void createScreenThumbnail(Graphics::Surface &dst) {}
-
-	// unused
-	int redrawShadedButtonCallback(Button *button) { return 0; }
-	int redrawButtonCallback(Button *button) { return 0; }
+	void createScreenThumbnail(Graphics::Surface &dst);
 
 private:
 	int simpleMenu_getMenuItem(int index, int32 menuItemsMask, int itemOffset);
@@ -84,6 +80,7 @@ private:
 	void scribeScrollDialogue();
 
 	bool confirmDialogue(int id);
+	bool confirmDialogue2(int dim, int id, int deflt);
 	void messageDialogue(int dim, int id, int buttonTextCol);
 	int selectCharacterDialogue(int id);
 	void displayTextBox(int id);
@@ -127,8 +124,8 @@ private:
 	uint16 _prcButtonUnk3;
 	uint16 _cflag;
 
-	Button::Callback _scrollUpFunctor;
-	Button::Callback _scrollDownFunctor;
+	//Button::Callback _scrollUpFunctor;
+	//Button::Callback _scrollDownFunctor;
 
 	int _menuLineSpacing;
 	int _menuLastInFlags;
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 77971da..7a9750f 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -694,11 +694,11 @@ void EobCoreEngine::spellCallback_start_removeParalysis() {
 }
 
 void EobCoreEngine::spellCallback_start_causeSeriousWounds() {
-	modifyCharacterHitpoints(_activeSpellCaster, rollDice(2, 8, 1));
+	
 }
 
 void EobCoreEngine::spellCallback_start_cureSeriousWounds() {
-
+	modifyCharacterHitpoints(_activeSpellCaster, rollDice(2, 8, 1));
 }
 
 void EobCoreEngine::spellCallback_start_neutralizePoison() {
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 441199c..599539c 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -320,6 +320,7 @@ enum KyraResources {
 	kEobBaseMenuStringsTransfer,
 	kEobBaseMenuStringsSpec,
 	kEobBaseMenuStringsSpellNo,
+	kEobBaseMenuYesNoStrings,
 
 	kEobBaseSpellLevelsMage,
 	kEobBaseSpellLevelsCleric,
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index 72bebf9..a5b2a69 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -349,17 +349,14 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 		}
 	}
 
-	if (_saveLoadMode != -1) {
-		if (_flags.gameID == GI_EOB1)
-			_screen->loadPalette("EOBPAL.COL", _screen->getPalette(0));
-		loadLevel(_currentLevel, _currentSub);
-		_sceneUpdateRequired = true;
-		_screen->setFont(Screen::FID_6_FNT);
-		_saveLoadMode = 1;
-	}
+	if (_flags.gameID == GI_EOB1)
+		_screen->loadPalette("EOBPAL.COL", _screen->getPalette(0));
+	loadLevel(_currentLevel, _currentSub);
+	_sceneUpdateRequired = true;
+	_screen->setFont(Screen::FID_6_FNT);
 
 	_screen->setCurPage(0);
-	gui_drawPlayField(0);
+	gui_drawPlayField(0);	
 
 	if (_currentControlMode)
 		_screen->copyRegion(176, 0, 0, 0, 144, 168, 0, 5, Screen::CR_NO_P_CHECK);
@@ -373,6 +370,8 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 		useMagicBookOrSymbol(_openBookChar, _openBookType);
 	}
 
+	_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 14, Screen::CR_NO_P_CHECK);
+
 	gui_toggleButtons();
 	setHandItem(_itemInHand);
 
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 6cc7606..efc5b85 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -387,6 +387,7 @@ void EobCoreEngine::initStaticResource() {
 	_menuStringsTransfer = _staticres->loadStrings(kEobBaseMenuStringsTransfer, temp);
 	_menuStringsSpec = _staticres->loadStrings(kEobBaseMenuStringsSpec, temp);
 	_menuStringsSpellNo = _staticres->loadStrings(kEobBaseMenuStringsSpellNo, temp);
+	_menuYesNoStrings = _staticres->loadStrings(kEobBaseMenuYesNoStrings, temp);
 
 	_spellLevelsMage = _staticres->loadRawData(kEobBaseSpellLevelsMage, _spellLevelsMageSize);
 	_spellLevelsCleric = _staticres->loadRawData(kEobBaseSpellLevelsCleric, _spellLevelsClericSize);


Commit: db83458330310072c743d5acc7e1a470c888ec3b
    https://github.com/scummvm/scummvm/commit/db83458330310072c743d5acc7e1a470c888ec3b
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:12-08:00

Commit Message:
KYRA: (EOB) - implement scribe scroll menu

Changed paths:
    engines/kyra/gui_eob.cpp



diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 1d69a90..936567b 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -2909,7 +2909,125 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
 
 
 void GUI_Eob::scribeScrollDialogue() {
-	
+	int16 *scrollInvSlot = new int16[32];
+	int16 *scrollCharacter = new int16[32];
+	int16 *menuItems = new int16[6];
+	int numScrolls = 0;
+
+	for (int i = 0; i < 32; i++) {
+		for (int ii = 0; ii < 6; ii++) {
+			scrollInvSlot[i] = _vm->checkCharacterInventoryForItem(ii, 34, i + 1) + 1;
+			if (scrollInvSlot[i] > 0) {
+				numScrolls++;
+				scrollCharacter[i] = ii;
+				break;
+			}
+		}
+	}
+
+	if (numScrolls) {
+		int csel = selectCharacterDialogue(49);
+		if (csel != -1) {
+			
+			EobCharacter *c = &_vm->_characters[csel];
+			int s = 0;
+
+			for (int i = 0; i < 32 && s < 6; i++) {
+				if (!scrollInvSlot[i])
+					continue;
+
+				if (c->mageSpellsAvailabilityFlags & (1 << i))
+					scrollInvSlot[i] = 0;
+				else
+					menuItems[s++] = i + 1;
+			}
+
+			if (s) {
+				Button *buttonList = 0;
+				bool redraw = true;
+				int lastHighLight = -1;
+				int newHighLight = 0;
+
+				while (s && !_vm->shouldQuit()) {
+					if (redraw) {
+						s = 0;
+						for (int i = 0; i < 32 && s < 6; i++) {
+							if (!scrollInvSlot[i])
+								continue;
+							menuItems[s++] = i + 1;
+						}
+
+						if (!s)
+							break;
+
+						releaseButtons(buttonList);
+						buttonList = initMenu(6);
+
+						for (int i = 0; i < s; i++)
+							_screen->printShadedText(_vm->_mageSpellList[menuItems[i]], 8, 9 * i + 50, 15, 0);
+
+						redraw = false;
+						lastHighLight = -1;
+						newHighLight = 0;
+					}					
+
+					if (lastHighLight != newHighLight) {
+						if (lastHighLight >= 0)
+							_screen->printText(_vm->_mageSpellList[menuItems[lastHighLight]], 8, 9 * lastHighLight + 50, 15, 0);
+						lastHighLight = newHighLight;
+						_screen->printText(_vm->_mageSpellList[menuItems[lastHighLight]], 8, 9 * lastHighLight + 50, 6, 0);
+						_screen->updateScreen();
+					}
+
+					int inputFlag = _vm->checkInput(buttonList, false, 0);
+					_vm->removeInputTop();
+
+					if (inputFlag == 0) {
+						Common::Point p = _vm->getMousePos();
+						if (_vm->posWithinRect(p.x, p.y, 8, 50, 176, s * 9 + 49))
+							newHighLight = (p.y - 50) / 9;
+					} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP2] || inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN]) {
+						newHighLight = (newHighLight + 1) % s;
+					} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP8] || inputFlag == _vm->_keyMap[Common::KEYCODE_UP]) {
+						newHighLight = (newHighLight + s - 1) % s;
+					} else if (inputFlag == 0x8023 || inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE]) {
+						s = 0;
+					} else if (inputFlag == 0x8024) {
+						newHighLight = (_vm->_mouseY - 50) / 9;						
+						if (newHighLight >= 0 && newHighLight < s) {
+							inputFlag = _vm->_keyMap[Common::KEYCODE_SPACE];
+						} else {
+							inputFlag = 0;
+							newHighLight = lastHighLight;
+						}
+					}
+
+					if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP5])  {
+						int t = menuItems[newHighLight] - 1;
+						Item scItem = _vm->_characters[scrollCharacter[t]].inventory[scrollInvSlot[t] - 1];
+						c->mageSpellsAvailabilityFlags |= (1 << t);
+						_vm->_characters[scrollCharacter[t]].inventory[scrollInvSlot[t] - 1] = 0;
+						_vm->gui_drawCharPortraitWithStats(_vm->_characters[scrollCharacter[t]].id);
+						scrollInvSlot[t] = 0;
+						_vm->_items[scItem].block = -1;
+						redraw = true;
+						s--;
+					}
+				}
+
+				releaseButtons(buttonList);
+
+			} else {
+				displayTextBox(51);
+			}
+		}
+	} else {
+		displayTextBox(50);
+	}
+
+	delete[] menuItems;
+	delete[] scrollCharacter;
+	delete[] scrollInvSlot;
 }
 
 bool GUI_Eob::confirmDialogue(int id) {


Commit: 9140fd8e91882250e23e2e4b44bf3088f3da827a
    https://github.com/scummvm/scummvm/commit/9140fd8e91882250e23e2e4b44bf3088f3da827a
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:12-08:00

Commit Message:
KYRA: (EOB) - implement party resting

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    engines/kyra/chargen.cpp
    engines/kyra/eob1.cpp
    engines/kyra/eob1.h
    engines/kyra/eob2.cpp
    engines/kyra/eob2.h
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/gui_eob.h
    engines/kyra/items_eob.cpp
    engines/kyra/magic_eob.cpp
    engines/kyra/resource.h
    engines/kyra/saveload_eob.cpp
    engines/kyra/sequences_eob2.cpp
    engines/kyra/sprites_eob.cpp
    engines/kyra/staticres_eob.cpp
    engines/kyra/text_eob.cpp
    engines/kyra/timer.cpp
    engines/kyra/timer.h
    engines/kyra/timer_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index 32280c6..ac94166 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -492,7 +492,8 @@ const ExtractFilename extractFilenames[] = {
 	{ kEob2Npc1Strings, kTypeStringList, true },
 	{ kEob2Npc2Strings, kTypeStringList, true },
 	{ kEob2MonsterDustStrings, kTypeStringList, true },
-
+	{ kEob2DranFoolsStrings, kTypeStringList, true },
+	
 	// LANDS OF LORE
 
 	// Ingame
@@ -1767,6 +1768,8 @@ const char *getIdString(const int id) {
 		return "kEob2Npc2Strings";
 	case kEob2MonsterDustStrings:
 		return "kEob2MonsterDustStrings";
+	case kEob2DranFoolsStrings:
+		return "kEob2DranFoolsStrings";
 	case kLolIngamePakFiles:
 		return "kLolIngamePakFiles";
 	case kLolCharacterDefs:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index be0d56a..238a68a 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -474,6 +474,8 @@ enum kExtractID {
 	kEob2Npc2Strings,
 	kEob2MonsterDustStrings,
 
+	kEob2DranFoolsStrings,
+
 	kLolIngamePakFiles,
 	kLolCharacterDefs,
 	kLolIngameSfxFiles,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 124d6e3..ed99d26 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1484,6 +1484,7 @@ const int eob2FloppyNeed[] = {
 	kEob2Npc1Strings,
 	kEob2Npc2Strings,
 	kEob2MonsterDustStrings,
+	kEob2DranFoolsStrings,
 
 	kLolEobCommonDscShapeIndex,
 	kLolEobCommonDscX,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index 0e1d954..7457f4f 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -2772,6 +2772,12 @@ const ExtractEntrySearchData kEob2MonsterDustStringsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEob2DranFoolsStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000001A, 0x00000887, { { 0xA6, 0xB4, 0x45, 0x1B, 0x33, 0x54, 0x36, 0xAD, 0x1D, 0xB1, 0xDA, 0xC3, 0x12, 0x85, 0x3C, 0x58 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000012, 0x00000511, { { 0xEE, 0x21, 0xA8, 0x6E, 0xF7, 0xEC, 0x9A, 0x8D, 0xBA, 0x8D, 0xE3, 0x4A, 0x17, 0x15, 0xCA, 0x8C } } } },
+	EXTRACT_END_ENTRY
+};
+
 const ExtractEntrySearchData kLolIngamePakFilesProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000088, 0x0000224F, { { 0xDA, 0x24, 0x18, 0xA3, 0xEF, 0x16, 0x70, 0x8F, 0xA8, 0xC2, 0x2E, 0xC2, 0xED, 0x39, 0x03, 0xD1 } } } },
 	{ UNK_LANG, kPlatformPC98, { 0x00000084, 0x00002125, { { 0x7A, 0x89, 0xE2, 0x36, 0xEC, 0x6F, 0x52, 0x2B, 0xEF, 0xBA, 0x3D, 0x28, 0x54, 0xDA, 0xFB, 0x72 } } } },
@@ -3660,6 +3666,7 @@ const ExtractEntry extractProviders[] = {
 	{ kEob2Npc1Strings, kEob2Npc1StringsProvider },
 	{ kEob2Npc2Strings, kEob2Npc2StringsProvider },
 	{ kEob2MonsterDustStrings, kEob2MonsterDustStringsProvider },
+	{ kEob2DranFoolsStrings, kEob2DranFoolsStringsProvider },
 	
 	{ kLolIngamePakFiles, kLolIngamePakFilesProvider },
 	{ kLolCharacterDefs, kLolCharacterDefsProvider },
diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index 3147fbb..c8040ed 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -1270,10 +1270,10 @@ void CharacterGenerator::finish() {
 
 	for (int i = 0; i < 4; i++) {
 		if (_vm->_classModifierFlags[_characters[i].cClass] & 2)
-			_characters[i].mageSpellsAvailabilityFlags = (_vm->game() == GI_EOB2) ? 0x81CB6 : 0x26C;
+			_characters[i].mageSpellsAvailableFlags = (_vm->game() == GI_EOB2) ? 0x81CB6 : 0x26C;
 
 		if (_vm->_classModifierFlags[_characters[i].cClass] & 0x14 && _vm->game() == GI_EOB2) {
-			// Cleric: Turn Undead
+			// Cleric/Paladin: Add Turn Undead spell
 			_characters[i].clericSpells[0] = 29;
 		}
 	}
diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
index 3992b22..70031bf 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -24,6 +24,7 @@
 
 #include "kyra/eob1.h"
 #include "kyra/resource.h"
+#include "kyra/sound.h"
 
 namespace Kyra {
 
@@ -77,6 +78,10 @@ void EobEngine::startupNew() {
 	EobCoreEngine::startupNew();
 }
 
+void EobEngine::startupLoad() {
+	_sound->loadSoundFile("ADLIB");
+}
+
 void EobEngine::npcSequence(int npcIndex) {
 
 
diff --git a/engines/kyra/eob1.h b/engines/kyra/eob1.h
index 8181f32..8a959e9 100644
--- a/engines/kyra/eob1.h
+++ b/engines/kyra/eob1.h
@@ -48,7 +48,7 @@ private:
 
 	// Main loop
 	void startupNew();
-	void startupLoad() {}
+	void startupLoad();
 
 	// Intro/Outro
 	void seq_playOpeningCredits();
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index baed595..8f3a10c 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -271,6 +271,24 @@ void DarkMoonEngine::replaceMonster(int unit, uint16 block, int pos, int dir, in
 	initMonster(index, unit, block, pos, dir, type, shpIndex, mode, h2, randItem, fixedItem);
 }
 
+bool DarkMoonEngine::killMonsterExtra(EobMonsterInPlay *m) {
+	if (_currentLevel == 16 && _currentSub == 1 && (_monsterProps[m->type].flags & 4)) {
+		if (m->type) {
+			_playFinale = true;
+			_runFlag = false;
+		} else {
+			m->hitPointsCur = 150;
+			m->curRemoteWeapon = 0;
+			m->numRemoteAttacks = 255;
+			m->shpIndex++;
+			m->type++;
+			seq_dranDragonTransformation();
+		}
+		return false;
+	}
+	return true;
+}
+
 const uint8 *DarkMoonEngine::loadDoorShapes(const char *filename, int doorIndex, const uint8 *shapeDefs) {
 	_screen->loadEobBitmap(filename, 3, 3);
 	for (int i = 0; i < 3; i++) {
@@ -319,6 +337,24 @@ void DarkMoonEngine::drawDoorIntern(int type, int, int x, int y, int w, int wall
 		drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
 }
 
+void DarkMoonEngine::restParty_npc() {
+
+}
+
+bool DarkMoonEngine::restParty_extraAbortCondition() {
+	if (_currentLevel != 3)
+		return false;
+	
+	seq_nightmare();
+
+	return true;
+}
+
+void DarkMoonEngine::checkPartyStatusExtra() {
+	if (checkScriptFlag(0x10))
+		seq_dranFools();
+}
+
 void DarkMoonEngine::drawLightningColumn() {
 	int f = rollDice(1, 2, -1);
 	int y = 0;
diff --git a/engines/kyra/eob2.h b/engines/kyra/eob2.h
index 22193ce..93a3518 100644
--- a/engines/kyra/eob2.h
+++ b/engines/kyra/eob2.h
@@ -60,6 +60,7 @@ private:
 	// Main Menu
 	int mainMenu();
 	int mainMenuLoop();
+
 	int _menuChoiceInit;
 
 	// Main loop
@@ -85,6 +86,13 @@ private:
 	static const char *_palFilesIntro[];
 	static const char *_palFilesFinale[];
 
+	// Ingame sequence
+	void seq_nightmare();
+	void seq_dranFools();
+	void seq_dranDragonTransformation();
+
+	const char *const *_dranFoolsStrings;
+
 	// characters
 	void npcSequence(int npcIndex);
 
@@ -99,6 +107,7 @@ private:
 	void generateMonsterPalettes(const char *file, int16 monsterIndex);
 	void loadMonsterDecoration(const char *file, int16 monsterIndex);
 	void replaceMonster(int unit, uint16 block, int d, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem);
+	bool killMonsterExtra(EobMonsterInPlay *m);
 
 	// Level
 	const uint8 *loadDoorShapes(const char *filename, int doorIndex, const uint8 *shapeDefs);
@@ -106,7 +115,12 @@ private:
 
 	const uint8 *_dscDoorType5Offs;
 
+	// Rest party
+	void restParty_npc();
+	bool restParty_extraAbortCondition();
+
 	// misc
+	void checkPartyStatusExtra();
 	void drawLightningColumn();
 	int resurrectionSelectDialogue();
 	int charSelectDialogue();
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 4c8d488..eebe752 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -135,6 +135,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_spells = 0;
 	_spellAnimBuffer = 0;
 	_clericSpellOffset = 0;
+	_restPartyElapsedTime = 0;
 }
 
 EobCoreEngine::~EobCoreEngine() {
@@ -351,6 +352,7 @@ Common::Error EobCoreEngine::go() {
 		if (_gameToLoad != -1) {
 			if (loadGameState(_gameToLoad).getCode() != Common::kNoError)
 				error("Couldn't load game slot %d on startup", _gameToLoad);
+			startupLoad();
 			_gameToLoad = -1;
 		} else {
 			action = mainMenu();
@@ -434,7 +436,7 @@ void EobCoreEngine::runLoop() {
 
 	while (!shouldQuit() && _runFlag) {
 		//_runLoopUnk2 = _currentBlock;
-		updateCharacterEvents(true);
+		checkPartyStatus(true);
 		checkInput(_activeButtons, true, 0);
 		removeInputTop();
 
@@ -444,16 +446,18 @@ void EobCoreEngine::runLoop() {
 		if (_sceneUpdateRequired)
 			drawScene(1);
 
-		if (_envAudioTimer >= _system->getMillis())
+		if (_envAudioTimer >= _system->getMillis() || (_flags.gameID == GI_EOB1 && (_currentLevel == 0 || _currentLevel > 3)))
 			continue;
 
 		_envAudioTimer = _system->getMillis() + (rollDice(1, 10, 3) * 18 * _tickLength);
-		snd_processEnvironmentalSoundEffect(rollDice(1, 2, -1) ? 27 : 28, _currentBlock + rollDice(1, 12, -1));
+		snd_processEnvironmentalSoundEffect(_flags.gameID == GI_EOB1 ? 30 : (rollDice(1, 2, -1) ? 27 : 28), _currentBlock + rollDice(1, 12, -1));
 		updateEnvironmentalSfx(0);
+		//TODO
+		//EOB1__level_2_7__turnUndead();
 	}
 }
 
-bool EobCoreEngine::updateCharacterEvents(bool a) {
+bool EobCoreEngine::checkPartyStatus(bool handleDeath) {
 	int numChars = 0;
 	for (int i = 0; i < 6; i++)
 		numChars += testCharacter(i, 13);
@@ -461,21 +465,22 @@ bool EobCoreEngine::updateCharacterEvents(bool a) {
 	if (numChars)
 		return false;
 
-	if (!a)
+	if (!handleDeath)
 		return true;
 
-
 	gui_drawAllCharPortraitsWithStats();
+	checkPartyStatusExtra();
+
+	if (_gui->confirmDialogue2(14, 67, 1)) {
+		_screen->setFont(Screen::FID_8_FNT);
+		gui_updateControls();
+		if (_gui->runLoadMenu(0, 0)) {
+			_screen->setFont(Screen::FID_6_FNT);
+			return true;
+		}
+	}
 
-	///	TODO
-	/// if (checkScriptFlag(0x10))
-	/// j_dranThoseFools()
-
-	///	TODO
-
-	///	TODO
-
-
+	quitGame();
 	return false;
 }
 
@@ -932,13 +937,13 @@ int EobCoreEngine::countCharactersWithSpecificItems(int16 itemType, int16 itemVa
 	for (int i = 0; i < 6; i++) {
 		if (!testCharacter(i, 1))
 			continue;
-		if (checkCharacterInventoryForItem(i, itemType, itemValue) != -1)
+		if (checkInventoryForItem(i, itemType, itemValue) != -1)
 			res++;
 	}
 	return res;
 }
 
-int EobCoreEngine::checkCharacterInventoryForItem(int character, int16 itemType, int16 itemValue) {
+int EobCoreEngine::checkInventoryForItem(int character, int16 itemType, int16 itemValue) {
 	for (int i = 0; i < 27; i++) {
 		uint16 inv = _characters[character].inventory[i];
 		if (!inv)
@@ -1275,6 +1280,118 @@ int EobCoreEngine::runDialogue(int dialogueTextId, int style, const char *button
 	return res;
 }
 
+void EobCoreEngine::restParty_displayWarning(const char *str) {
+	int od = _screen->curDimIndex();
+	_screen->setScreenDim(7);
+	Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+	_screen->setCurPage(0);
+
+	_txt->printMessage(Common::String::format("\r%s\r", str).c_str());
+
+	_screen->setFont(of);
+	_screen->setScreenDim(od);
+}
+
+bool EobCoreEngine::restParty_updateMonsters() {
+	bool sfxEnabled = _sound->sfxEnabled();
+	bool musicEnabled = _sound->musicEnabled();
+	_sound->enableSFX(false);
+	_sound->enableMusic(false);
+
+	for (int i = 0; i < 5; i++) {
+		_partyResting = true;
+		Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+		int od = _screen->curDimIndex();
+		_screen->setScreenDim(7);
+		updateMonsters(0);
+		updateMonsters(1);
+		timerProcessFlyingObjects(0);
+		_screen->setScreenDim(od);
+		_screen->setFont(of);
+		_partyResting = false;
+
+		for (int ii = 0; ii < 30; ii++) {
+			if (_monsters[ii].mode == 8)
+				continue;
+			if (getBlockDistance(_currentBlock, _monsters[ii].block) >= 2)
+				continue;
+
+			restParty_displayWarning(_menuStringsRest4[0]);
+			_sound->enableSFX(sfxEnabled);
+			_sound->enableMusic(musicEnabled);
+			return true;
+		}
+	}
+	
+	_sound->enableSFX(sfxEnabled);
+	_sound->enableMusic(musicEnabled);
+	return false;
+}
+
+int EobCoreEngine::restParty_getCharacterWithLowestHp() {
+	int lhp = 900;
+	int res = -1;
+
+	for (int i = 0; i < 6; i++) {
+		if (!testCharacter(i, 3))
+			continue;
+		if (_characters[i].hitPointsCur >= _characters[i].hitPointsMax)
+			continue;
+		if (_characters[i].hitPointsCur < lhp) {
+			lhp = _characters[i].hitPointsCur;
+			res = i;
+		}
+	}
+
+	return res + 1;
+}
+
+bool EobCoreEngine::restParty_checkHealSpells(int charIndex) {
+	static const uint8 eob1healSpells[] = { 2, 15, 20 };
+	static const uint8 eob2healSpells[] = { 3, 16, 20 };
+	const uint8 *spells = _flags.gameID == GI_EOB1 ? eob1healSpells : eob2healSpells;
+	const int8 *list = _characters[charIndex].clericSpells;
+	
+	for (int i = 0; i < 80; i++) {
+		int s = list[i] < 0 ? -list[i] : list[i];
+		if (s == spells[0] || s == spells[1] || s == spells[2])
+			return true;
+	}
+
+	return false;
+}
+
+bool EobCoreEngine::restParty_checkSpellsToLearn() {
+	for (int i = 0; i < 6; i++) {
+		if (!testCharacter(i, 0x43))
+			continue;
+
+		if ((getCharacterLevelIndex(2, _characters[i].cClass) != -1 || getCharacterLevelIndex(4, _characters[i].cClass) != -1) && (checkInventoryForItem(i, 30, -1) != -1)) {
+			for (int ii = 0; ii < 80; ii++) {
+				if (_characters[i].clericSpells[ii] < 0)
+					return true;
+			}
+		}
+
+		if ((getCharacterLevelIndex(1, _characters[i].cClass) != -1) && (checkInventoryForItem(i, 29, -1) != -1)) {
+			for (int ii = 0; ii < 80; ii++) {
+				if (_characters[i].mageSpells[ii] < 0)
+					return true;
+			}
+		}
+	}
+
+	return false;
+}
+
+void EobCoreEngine::restParty_npc() {
+
+}
+
+bool EobCoreEngine::restParty_extraAbortCondition() {
+	return false;
+}
+
 void EobCoreEngine::delay(uint32 millis, bool, bool) {
 	while (millis && !shouldQuit() && !skipFlag()) {
 		updateInput();
@@ -1319,28 +1436,6 @@ void EobCoreEngine::displayParchment(int id) {
 	restoreAfterDialogueSequence();
 }
 
-bool EobCoreEngine::restParty() {
-	if (_inf->preventRest()) {
-		assert(_menuStringsRest3[0]);
-		displayRestWarning(_menuStringsRest3[0]);
-		return true;
-	}
-
-	return true;
-}
-
-void EobCoreEngine::displayRestWarning(const char *str) {
-	int od = _screen->curDimIndex();
-	_screen->setScreenDim(7);
-	Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
-	_screen->setCurPage(0);
-
-	_txt->printMessage(Common::String::format("\r%s\r", str).c_str());
-
-	_screen->setFont(of);
-	_screen->setScreenDim(od);
-}
-
 void EobCoreEngine::useSlotWeapon(int charIndex, int slotIndex, int item) {
 	EobCharacter *c = &_characters[charIndex];
 	int tp = item ? _items[item].type : 0;
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index e6b816e..0cf2e9d 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -108,7 +108,7 @@ struct EobCharacter {
 
 	int8 mageSpells[80];
 	int8 clericSpells[80];
-	uint32 mageSpellsAvailabilityFlags;
+	uint32 mageSpellsAvailableFlags;
 
 	Item inventory[27];
 	uint32 timers[10];
@@ -311,7 +311,7 @@ protected:
 	virtual void startupLoad() = 0;
 	void runLoop();
 	void update() { screen()->updateScreen(); }
-	bool updateCharacterEvents(bool a);
+	bool checkPartyStatus(bool handleDeath);
 
 	bool _runFlag;
 	//int _runLoopUnk2;
@@ -334,6 +334,7 @@ protected:
 	void setCharEventTimer(int charIndex, uint32 countdown, int evnt, int updateExistingTimer);
 	void deleteCharEventTimer(int charIndex, int evnt);
 	void setupCharacterTimers();
+	void manualAdvanceTimer(int sysTimer, uint32 millis);
 
 	void timerProcessMonsters(int timerNum);
 	void timerSpecialCharacterUpdate(int timerNum);
@@ -349,6 +350,8 @@ protected:
 	static const uint8 _clock2Timers[];
 	static const uint8 _numClock2Timers;
 
+	int32 _restPartyElapsedTime;
+
 	// Mouse
 	void setHandItem(Item itemIndex);
 
@@ -369,7 +372,7 @@ protected:
 	int getCharacterLevelIndex(int type, int cClass);
 
 	int countCharactersWithSpecificItems(int16 itemType, int16 itemValue);
-	int checkCharacterInventoryForItem(int character, int16 itemType, int16 itemValue);
+	int checkInventoryForItem(int character, int16 itemType, int16 itemValue);
 	void modifyCharacterHitpoints(int character, int16 points);
 	void neutralizePoison(int character);
 
@@ -471,6 +474,7 @@ protected:
 	void placeMonster(EobMonsterInPlay *m, uint16 block, int dir);
 	virtual void replaceMonster(int b, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem) = 0;
 	void killMonster(EobMonsterInPlay *m, bool giveExperience);
+	virtual bool killMonsterExtra(EobMonsterInPlay *m);
 	int countSpecificMonsters(int type);
 	void updateAttackingMonsterFlags();
 
@@ -533,7 +537,7 @@ protected:
 	const uint8 *_monsterProximityTable;
 	const uint8 *_findBlockMonstersTable;
 	const char *const *_monsterDustStrings;
-
+	
 	const uint8 *_monsterDistAttType10;
 	const uint8 *_monsterDistAttSfx10;
 	const uint8 *_monsterDistAttType17;
@@ -766,12 +770,19 @@ protected:
 	const char *const *_cancelStrings;
 	const char *const *_abortStrings;
 
+	// Rest party
+	void restParty_displayWarning(const char *str);
+	bool restParty_updateMonsters();
+	int restParty_getCharacterWithLowestHp();
+	bool restParty_checkHealSpells(int charIndex);
+	bool restParty_checkSpellsToLearn();
+	virtual void restParty_npc();
+	virtual bool restParty_extraAbortCondition();
+
 	// misc
 	void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false);
 	void displayParchment(int id);
-
-	bool restParty();
-	void displayRestWarning(const char *str);
+	virtual void checkPartyStatusExtra() {}
 
 	virtual void drawLightningColumn() {}
 	virtual int resurrectionSelectDialogue() { return -1; }
@@ -843,7 +854,7 @@ protected:
 	void sparkEffectDefensive(int charIndex);
 	void sparkEffectOffensive();
 	void setSpellEventTimer(int spell, int timerBaseFactor, int timerLength, int timerLevelFactor, int updateExistingTimer);
-	void cleanupCharacterSpellList(int charIndex);
+	void sortCharacterSpellList(int charIndex);
 
 	bool magicObjectHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level);
 
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 936567b..3a71642 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -24,6 +24,7 @@
 
 #include "kyra/eobcommon.h"
 #include "kyra/gui_eob.h"
+#include "kyra/script_eob.h"
 #include "kyra/text_eob.h"
 #include "kyra/timer.h"
 #include "kyra/util.h"
@@ -508,7 +509,7 @@ void EobCoreEngine::gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32
 }
 
 void EobCoreEngine::gui_drawCharPortraitStatusFrame(int index) {
-	uint8 boxColor = ((_partyEffectFlags & 0x20000) | (_partyEffectFlags & 0xffff)) ? 4 : 6;
+	uint8 redGreenColor = (_partyEffectFlags & 0x20000) ? 4 : 6;
 
 	static const uint8 xCoords[] = { 8, 80 };
 	static const uint8 yCoords[] = { 2, 54, 106 };
@@ -520,18 +521,16 @@ void EobCoreEngine::gui_drawCharPortraitStatusFrame(int index) {
 
 	EobCharacter *c = &_characters[index];
 
-	int v8 = (_flags.gameID == GI_EOB2 && ((c->effectFlags & 0x4818) || c->effectsRemainder[0] || c->effectsRemainder[1] || ((_partyEffectFlags & 0x20000) | (_partyEffectFlags & 0xffff)))) ||
-		(_flags.gameID == GI_EOB1 && ((c->effectFlags & 0x302) || c->effectsRemainder[0] || c->effectsRemainder[1])) ? 1 : 0;
-	int vA = (_flags.gameID == GI_EOB2 && ((((c->effectFlags & 0x3000) | (c->effectFlags & 0x10000)) || (_partyEffectFlags & 0x8420)))) ||
-		(_flags.gameID == GI_EOB1 && ((c->effectFlags & 0x4c8) || _partyEffectFlags & 300000))? 1 : 0;
+	bool redGreen = ((c->effectFlags & 0x4818) || (_partyEffectFlags & 0x20000) || c->effectsRemainder[0] || c->effectsRemainder[1]) ? true : false;
+	bool yellow = ((c->effectFlags & 0x13000) || (_partyEffectFlags & 0x8420) || c->effectsRemainder[0] || c->effectsRemainder[1]) ? true : false;
 
-	if (v8 || vA) {
-		if (v8 && !vA) {
-			_screen->drawBox(x, y, x + 63, y + 49, boxColor);
+	if (redGreen || yellow) {
+		if (redGreen && !yellow) {
+			_screen->drawBox(x, y, x + 63, y + 49, redGreenColor);
 			return;
 		}
 
-		if (vA && !v8) {
+		if (yellow && !redGreen) {
 			_screen->drawBox(x, y, x + 63, y + 49, 5);
 			return;
 		}
@@ -541,11 +540,11 @@ void EobCoreEngine::gui_drawCharPortraitStatusFrame(int index) {
 
 		for (int i = 0; i < 64; i += 16) {
 			x = iX + i;
-			if (v8) {
-				_screen->drawClippedLine(x, y, x + 7, y, boxColor);
-				_screen->drawClippedLine(x + 8, y + 49, x + 15, y + 49, boxColor);
+			if (redGreen) {
+				_screen->drawClippedLine(x, y, x + 7, y, redGreenColor);
+				_screen->drawClippedLine(x + 8, y + 49, x + 15, y + 49, redGreenColor);
 			}
-			if (vA) {
+			if (yellow) {
 				_screen->drawClippedLine(x + 8, y, x + 15, y, 5);
 				_screen->drawClippedLine(x, y + 49, x + 7, y + 49, 5);
 			}
@@ -556,13 +555,13 @@ void EobCoreEngine::gui_drawCharPortraitStatusFrame(int index) {
 		for (int i = 1; i < 48; i += 12) {
 			y = iY + i - 1;
 
-			if (vA) {
+			if (yellow) {
 				_screen->drawClippedLine(x, y + 1, x, y + 6, 5);
 				_screen->drawClippedLine(x + 63, y + 7, x + 63, y + 12, 5);
 			}
-			if (v8) {
-				_screen->drawClippedLine(x, y + 7, x, y + 12, boxColor);
-				_screen->drawClippedLine(x + 63, y + 1, x + 63, y + 6, boxColor);
+			if (redGreen) {
+				_screen->drawClippedLine(x, y + 7, x, y + 12, redGreenColor);
+				_screen->drawClippedLine(x + 63, y + 1, x + 63, y + 6, redGreenColor);
 			}
 		}
 
@@ -859,7 +858,7 @@ int EobCoreEngine::clickedCamp(Button *button) {
 	drawScene(0);
 
 	for (int i = 0; i < 6; i++)
-		cleanupCharacterSpellList(i);
+		sortCharacterSpellList(i);
 
 	_screen->setCurPage(0);
 	const ScreenDim *dm = _screen->getScreenDim(10);
@@ -867,8 +866,11 @@ int EobCoreEngine::clickedCamp(Button *button) {
 
 	_screen->updateScreen();
 
-	enableSysTimer(2);	
-	updateCharacterEvents(true);
+	enableSysTimer(2);
+	manualAdvanceTimer(2, _restPartyElapsedTime);
+	_restPartyElapsedTime = 0;
+
+	checkPartyStatus(true);
 
 	return button->arg;
 }
@@ -2174,11 +2176,12 @@ void GUI_Eob::runCampMenu() {
 
 			switch (inputFlag) {
 			case 0x8001:
-				if (_vm->restParty())
+				if (restParty())
 					runLoop = false;
 				else
 					_needRest = false;
 				redrawPortraits = true;
+				newMenu = 0;
 				break;
 
 			case 0x8002:
@@ -2286,7 +2289,7 @@ void GUI_Eob::runCampMenu() {
 		if (_charSelectRedraw || redrawPortraits) {
 			for (int i = 0; i < 6; i++) {
 				_vm->gui_drawCharPortraitWithStats(i);
-				_vm->cleanupCharacterSpellList(i);
+				_vm->sortCharacterSpellList(i);
 			}
 		}
 
@@ -2334,6 +2337,74 @@ bool GUI_Eob::runLoadMenu(int x, int y) {
 	return result;
 }
 
+bool GUI_Eob::confirmDialogue2(int dim, int id, int deflt) {
+	int od = _screen->curDimIndex();
+	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+	_screen->setScreenDim(dim);
+
+	drawTextBox(dim, id);
+
+	int16 x[2];
+	x[0] = (_screen->_curDim->sx << 3) + 8;
+	x[1] = (_screen->_curDim->sx + _screen->_curDim->w - 5) << 3;
+	int16 y = _screen->_curDim->sy + _screen->_curDim->h - 21;
+	int newHighlight = deflt ^ 1;
+	int lastHighlight = -1;
+	
+	for (int i = 0; i < 2; i++)
+		drawMenuButtonBox(x[i], y, 32, 14, false, false);
+
+	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
+		Common::Point p = _vm->getMousePos();
+		if (_vm->posWithinRect(p.x, p.y, x[0], y, x[0] + 32, y + 14))
+			newHighlight = 0;
+		else if (_vm->posWithinRect(p.x, p.y, x[1], y, x[1] + 32, y + 14))
+			newHighlight = 1;
+
+		int inputFlag = _vm->checkInput(0, false, 0) & 0x8ff;
+		_vm->removeInputTop();
+
+		if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
+			runLoop = false;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP6]) {
+			newHighlight ^= 1;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_n]) {
+			newHighlight = 1;
+			runLoop = false;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_y]) {
+			newHighlight = 0;
+			runLoop = false;
+		}  else if (inputFlag == 199 || inputFlag == 201) {
+			if (_vm->posWithinRect(p.x, p.y, x[0], y, x[0] + 32, y + 14)) {
+				newHighlight = 0;
+				runLoop = false;
+			} else if (_vm->posWithinRect(p.x, p.y, x[1], y, x[1] + 32, y + 14)) {
+				newHighlight = 1;
+				runLoop = false;
+			}
+		}
+
+		if (newHighlight != lastHighlight) {
+			for (int i = 0; i < 2; i++)				
+				_screen->printShadedText(_vm->_menuYesNoStrings[i], x[i] + 16 - (strlen(_vm->_menuYesNoStrings[i]) << 2) + 1, y + 3, i == newHighlight ? 6 : 15, 0);
+			_screen->updateScreen();
+			lastHighlight = newHighlight;
+		}
+	}
+
+	drawMenuButtonBox(x[newHighlight], y, 32, 14, true, true);
+	_screen->updateScreen();
+	_vm->_system->delayMillis(80);
+	drawMenuButtonBox(x[newHighlight], y, 32, 14, false, true);
+	_screen->updateScreen();
+
+	_screen->copyRegion(0, _screen->_curDim->h, _screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->setFont(of);
+	_screen->setScreenDim(od);
+	
+	return newHighlight ? false : true;
+}
+
 void GUI_Eob::updateBoxFrameHighLight(int box) {
 	static const uint8 colorTable[] = { 0x0F, 0xB0, 0xB2, 0xB4, 0xB6,
 		0xB8, 0xBA, 0xBC, 0x0C, 0xBC, 0xBA, 0xB8, 0xB6, 0xB4, 0xB2, 0xB0, 0x00
@@ -2686,7 +2757,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
 			for (int i = 0; i < _numPages; i++)
 				np[i] = _vm->_numSpellsMage[lv * _numPages + i];
 
-			avltyFlags = c->mageSpellsAvailabilityFlags;
+			avltyFlags = c->mageSpellsAvailableFlags;
 		}
 	}
 
@@ -2916,7 +2987,7 @@ void GUI_Eob::scribeScrollDialogue() {
 
 	for (int i = 0; i < 32; i++) {
 		for (int ii = 0; ii < 6; ii++) {
-			scrollInvSlot[i] = _vm->checkCharacterInventoryForItem(ii, 34, i + 1) + 1;
+			scrollInvSlot[i] = _vm->checkInventoryForItem(ii, 34, i + 1) + 1;
 			if (scrollInvSlot[i] > 0) {
 				numScrolls++;
 				scrollCharacter[i] = ii;
@@ -2936,7 +3007,7 @@ void GUI_Eob::scribeScrollDialogue() {
 				if (!scrollInvSlot[i])
 					continue;
 
-				if (c->mageSpellsAvailabilityFlags & (1 << i))
+				if (c->mageSpellsAvailableFlags & (1 << i))
 					scrollInvSlot[i] = 0;
 				else
 					menuItems[s++] = i + 1;
@@ -3005,7 +3076,7 @@ void GUI_Eob::scribeScrollDialogue() {
 					if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP5])  {
 						int t = menuItems[newHighLight] - 1;
 						Item scItem = _vm->_characters[scrollCharacter[t]].inventory[scrollInvSlot[t] - 1];
-						c->mageSpellsAvailabilityFlags |= (1 << t);
+						c->mageSpellsAvailableFlags |= (1 << t);
 						_vm->_characters[scrollCharacter[t]].inventory[scrollInvSlot[t] - 1] = 0;
 						_vm->gui_drawCharPortraitWithStats(_vm->_characters[scrollCharacter[t]].id);
 						scrollInvSlot[t] = 0;
@@ -3030,6 +3101,284 @@ void GUI_Eob::scribeScrollDialogue() {
 	delete[] scrollInvSlot;
 }
 
+bool GUI_Eob::restParty() {
+	static const int8 eob1healSpells[] = { 2, 15, 20, 24 };
+	static const int8 eob2healSpells[] = { 3, 16, 20, 28 };
+	const int8 *spells = _vm->game() == GI_EOB1 ? eob1healSpells : eob2healSpells;
+	
+	uint8 crs[6];
+	memset(crs, 0, 6);
+	int hours = 0;
+
+	if (_vm->_inf->preventRest()) {
+		assert(_vm->_menuStringsRest3[0]);
+		_vm->restParty_displayWarning(_vm->_menuStringsRest3[0]);
+		return true;
+	}
+
+	if (_vm->restParty_updateMonsters())
+		return true;
+
+	if (_vm->restParty_extraAbortCondition())
+		return true;
+
+	drawMenuButtonBox(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, false, false);
+
+	int nonPoisoned = 0;
+	for (int i = 0; i < 6; i++) {
+		if (!_vm->testCharacter(i, 1))
+			continue;
+		nonPoisoned |= _vm->testCharacter(i, 0x10);
+	}
+
+	if (!nonPoisoned) {
+		if (!confirmDialogue(59))
+			return false;
+	}
+
+	int8 *list = 0;
+	bool useHealers = false;
+	bool res = false;
+	bool restLoop = true;
+	bool restContinue = false;
+	int injured = _vm->restParty_getCharacterWithLowestHp();
+
+	if (injured > 0) {
+		for (int i = 0; i < 6; i++) {
+			if (!_vm->testCharacter(i, 13))
+				continue;
+			if (_vm->getCharacterLevelIndex(2, _vm->_characters[i].cClass) == -1 && _vm->getCharacterLevelIndex(4, _vm->_characters[i].cClass) == -1)
+				continue;
+			if (_vm->checkInventoryForItem(i, 30, -1) == -1)
+				continue;
+			if (_vm->restParty_checkHealSpells(i))
+				useHealers = confirmDialogue(40);
+		} 
+	}
+
+	_screen->setClearScreenDim(7);
+	_screen->setFont(Screen::FID_6_FNT);
+
+	restParty_updateRestTime(hours, true);
+
+	for (int l = 0; !res && restLoop && !_vm->shouldQuit(); ) {
+		l++;
+
+		// Regenerate spells
+		for (int i = 0; i < 6; i++) {
+			crs[i]++;
+
+			if (!_vm->_characters[i].food)
+				continue;
+			if (!_vm->testCharacter(i, 5))
+				continue;
+
+			if (_vm->checkInventoryForItem(i, 30, -1) != -1) {
+				list = _vm->_characters[i].clericSpells;
+
+				for (int ii = 0; ii < 80; ii++) {
+					if ((ii / 10 + 48) >= crs[i])
+						break;
+					
+					if (*list >= 0) {
+						list++;
+						continue;
+					}
+
+					*list *= -1;
+					crs[i] = 48;					
+					_vm->_txt->printMessage(Common::String::format(_vm->_menuStringsRest2[0], _vm->_characters[i].name, _vm->_spells[_vm->_mageSpellListSize + *list].name).c_str());
+					_vm->delay(80);
+					break;
+				}
+			}
+
+			if (_vm->checkInventoryForItem(i, 29, -1) != -1) {
+				list = _vm->_characters[i].mageSpells;
+
+				for (int ii = 0; ii < 80; ii++) {
+					if ((ii / 6 + 48) >= crs[i])
+						break;
+					
+					if (*list >= 0) {
+						list++;
+						continue;
+					}
+
+					*list *= -1;
+					crs[i] = 48;					
+					_vm->_txt->printMessage(Common::String::format(_vm->_menuStringsRest2[1], _vm->_characters[i].name, _vm->_spells[*list].name).c_str());
+					_vm->delay(80);
+					break;
+				}
+			}
+		}
+
+		// Heal party members
+		if (useHealers) {
+			for (int i = 0; i < 6 && injured; i++) {
+				if (_vm->getCharacterLevelIndex(2, _vm->_characters[i].cClass) == -1 && _vm->getCharacterLevelIndex(4, _vm->_characters[i].cClass) == -1)
+					continue;
+				if (_vm->checkInventoryForItem(i, 30, -1) == -1)
+					continue;
+				
+				list = 0;
+				if (crs[i] >= 48) {
+					for (int ii = 0; !list && ii < 3; ii++)
+						list = (int8*)memchr(_vm->_characters[i].clericSpells, -spells[ii], 80);
+				}
+
+				if (list)
+					break;
+
+				list = _vm->_characters[i].clericSpells;
+				for (int ii = 0; ii < 80 && injured; ii++) {
+					int healHp = 0;
+					if (*list == spells[0])
+						healHp = _vm->rollDice(1, 8, 0);
+					else if (*list == spells[1])
+						healHp = _vm->rollDice(2, 8, 1);
+					else if (*list == spells[2])
+						healHp = _vm->rollDice(3, 8, 3);
+
+					if (!healHp) {
+						list++;
+						continue;
+					}
+
+					*list *= -1;
+					list++;
+
+					crs[i] = 0;
+					injured--;
+
+					_vm->_txt->printMessage(Common::String::format(_vm->_menuStringsRest2[2], _vm->_characters[i].name, _vm->_characters[injured].name).c_str());
+					_vm->delay(80);
+
+					_vm->_characters[injured].hitPointsCur += healHp;
+					if (_vm->_characters[injured].hitPointsCur > _vm->_characters[injured].hitPointsMax)
+						_vm->_characters[injured].hitPointsCur = _vm->_characters[injured].hitPointsMax;
+
+					_vm->gui_drawCharPortraitWithStats(injured++);
+				}
+			}
+		}
+
+		if (l == 6) {
+			l = 0;
+			restParty_updateRestTime(++hours, false);
+			_vm->_restPartyElapsedTime += (32760 * _vm->_tickLength);
+
+			// Update poisoning
+			for (int i = 0; i < 6; i++) {
+				if (!_vm->testCharacter(i, 1))
+					continue;
+				if (_vm->testCharacter(i, 16))
+					continue;
+				_vm->inflictCharacterDamage(i, 10);
+				_vm->delayWithTicks(5);
+			}
+
+			if (!(hours % 8)) {
+				bool starving = false;
+				for (int i = 0; i < 6; i++) {
+					// Add Lay On Hands spell
+					if (_vm->_characters[i].cClass == 2) {
+						list = (int8*)memchr(_vm->_characters[i].clericSpells, spells[3], 10);
+						if (list) {
+							*list = spells[3];
+						} else {
+							list = (int8*)memchr(_vm->_characters[i].clericSpells, -spells[3], 10);
+							if (list) {
+								*list = spells[3];
+							} else if (!memchr(_vm->_characters[i].clericSpells, spells[3], 10)) {
+								list = (int8*)memchr(_vm->_characters[i].clericSpells, 0, 10);
+								*list = spells[3];
+							}
+						}
+					}
+
+					if (!_vm->testCharacter(i, 3))
+						continue;
+
+					// Update hitpoints and food status
+					if (_vm->_characters[i].food) {
+						if (_vm->_characters[i].hitPointsCur < _vm->_characters[i].hitPointsMax) {
+							_vm->_characters[i].hitPointsCur++;
+							_screen->setFont(Screen::FID_6_FNT);
+							_vm->gui_drawCharPortraitWithStats(i);
+						}
+
+						if (!_vm->checkInventoryForRings(i, 2)) {
+							if (_vm->_characters[i].food <= 5) {
+								_vm->_characters[i].food = 0;
+								starving = true;
+							} else {
+								_vm->_characters[i].food -= 5;
+							}
+						}
+					} else {
+						if ((hours % 24) || (_vm->_characters[i].hitPointsCur <= -10))
+							continue;
+						_vm->inflictCharacterDamage(i, 1);
+						starving = true;
+						_screen->setFont(Screen::FID_6_FNT);
+						_vm->gui_drawCharPortraitWithStats(i);
+					}
+				}
+				
+				if (starving) {
+					if (!confirmDialogue(47)) {
+						restContinue = false;
+						restLoop = false;
+					}
+					restParty_updateRestTime(hours, true);
+				}
+				injured = restLoop ? _vm->restParty_getCharacterWithLowestHp() : 0;
+			}
+		}
+
+		if (!_vm->restParty_checkSpellsToLearn() && restLoop && !restContinue && injured) {
+			restContinue = confirmDialogue(41);
+			restParty_updateRestTime(hours, true);
+			if (!restContinue)
+				restLoop = false;
+		}
+
+		int in = _vm->checkInput(0, false, 0);
+		_vm->removeInputTop();
+		if (in)
+			restLoop = false;
+
+		if (restLoop) {
+			res = _vm->restParty_updateMonsters();
+			if (!res)
+				res = _vm->checkPartyStatus(false);
+		}
+
+		if (!_vm->restParty_checkSpellsToLearn()) {
+			if (!restContinue) {
+				if (!useHealers)
+					restLoop = false;
+			}
+			if (!injured)
+				restLoop = false;
+		}
+	}
+
+	_vm->removeInputTop();
+	_screen->setScreenDim(4);
+	_screen->setFont(Screen::FID_8_FNT);
+
+	if (!injured && !res)
+		displayTextBox(43);
+
+	if (res && hours > 4)
+		_vm->restParty_npc();
+
+	return res;
+}
+
 bool GUI_Eob::confirmDialogue(int id) {
 	int od = _screen->curDimIndex();
 	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
@@ -3092,74 +3441,6 @@ bool GUI_Eob::confirmDialogue(int id) {
 	return result;
 }
 
-bool GUI_Eob::confirmDialogue2(int dim, int id, int deflt) {
-	int od = _screen->curDimIndex();
-	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
-	_screen->setScreenDim(dim);
-
-	drawTextBox(dim, id);
-
-	int16 x[2];
-	x[0] = (_screen->_curDim->sx << 3) + 8;
-	x[1] = (_screen->_curDim->sx + _screen->_curDim->w - 5) << 3;
-	int16 y = _screen->_curDim->sy + _screen->_curDim->h - 21;
-	int newHighlight = deflt ^ 1;
-	int lastHighlight = -1;
-	
-	for (int i = 0; i < 2; i++)
-		drawMenuButtonBox(x[i], y, 32, 14, false, false);
-
-	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
-		Common::Point p = _vm->getMousePos();
-		if (_vm->posWithinRect(p.x, p.y, x[0], y, x[0] + 32, y + 14))
-			newHighlight = 0;
-		else if (_vm->posWithinRect(p.x, p.y, x[1], y, x[1] + 32, y + 14))
-			newHighlight = 1;
-
-		int inputFlag = _vm->checkInput(0, false, 0) & 0x8ff;
-		_vm->removeInputTop();
-
-		if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
-			runLoop = false;
-		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP6]) {
-			newHighlight ^= 1;
-		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_n]) {
-			newHighlight = 1;
-			runLoop = false;
-		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_y]) {
-			newHighlight = 0;
-			runLoop = false;
-		}  else if (inputFlag == 199 || inputFlag == 201) {
-			if (_vm->posWithinRect(p.x, p.y, x[0], y, x[0] + 32, y + 14)) {
-				newHighlight = 0;
-				runLoop = false;
-			} else if (_vm->posWithinRect(p.x, p.y, x[1], y, x[1] + 32, y + 14)) {
-				newHighlight = 1;
-				runLoop = false;
-			}
-		}
-
-		if (newHighlight != lastHighlight) {
-			for (int i = 0; i < 2; i++)				
-				_screen->printShadedText(_vm->_menuYesNoStrings[i], x[i] + 16 - (strlen(_vm->_menuYesNoStrings[i]) << 2) + 1, y + 3, i == newHighlight ? 6 : 15, 0);
-			_screen->updateScreen();
-			lastHighlight = newHighlight;
-		}
-	}
-
-	drawMenuButtonBox(x[newHighlight], y, 32, 14, true, true);
-	_screen->updateScreen();
-	_vm->_system->delayMillis(80);
-	drawMenuButtonBox(x[newHighlight], y, 32, 14, false, true);
-	_screen->updateScreen();
-
-	_screen->copyRegion(0, _screen->_curDim->h, _screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, 2, 0, Screen::CR_NO_P_CHECK);
-	_screen->setFont(of);
-	_screen->setScreenDim(od);
-	
-	return newHighlight ? false : true;
-}
-
 void GUI_Eob::messageDialogue(int dim, int id, int buttonTextCol) {
 	static const char buttonText[] = "OK";
 
@@ -3338,7 +3619,7 @@ int GUI_Eob::selectCharacterDialogue(int id) {
 				result = -1;
 			}
 		} else {
-			if (_vm->checkCharacterInventoryForItem(result, 29, -1) == -1) {
+			if (_vm->checkInventoryForItem(result, 29, -1) == -1) {
 				displayTextBox(25);
 				result = -1;
 			}
@@ -3635,6 +3916,31 @@ int GUI_Eob::getHighlightSlot() {
 	return res;
 }
 
+void GUI_Eob::restParty_updateRestTime(int hours, bool init) {
+	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+	int od = _screen->curDimIndex();
+	_screen->setScreenDim(10);
+
+	if (init) {
+		_screen->setCurPage(0);
+		_vm->_txt->clearCurDim();
+		drawMenuButtonBox(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, false, false);
+		_screen->copyRegion(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, 0, 2, Screen::CR_NO_P_CHECK);
+		_screen->printShadedText(getMenuString(42), (_screen->_curDim->sx + 1) << 3, _screen->_curDim->sy + 5, 9, 0);
+	}
+
+	_screen->setCurPage(2);
+	_screen->printShadedText(Common::String::format(_vm->_menuStringsRest2[3], hours).c_str(), (_screen->_curDim->sx + 1) << 3, _screen->_curDim->sy + 20, 15, _vm->_bkgColor_1);
+	_screen->setCurPage(0);
+	_screen->copyRegion(((_screen->_curDim->sx + 1) << 3) - 1, _screen->_curDim->sy + 20, ((_screen->_curDim->sx + 1) << 3) - 1, _screen->_curDim->sy + 20, 144, 8, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	
+	_vm->delay(160);
+
+	_screen->setScreenDim(od);
+	_screen->setFont(of);
+}
+
 #endif // ENABLE_EOB
 
 }	// End of namespace Kyra
diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h
index 234f2f6..709c676 100644
--- a/engines/kyra/gui_eob.h
+++ b/engines/kyra/gui_eob.h
@@ -62,6 +62,7 @@ public:
 	void runCampMenu();
 	bool runLoadMenu(int x, int y);
 
+	bool confirmDialogue2(int dim, int id, int deflt);
 	void updateBoxFrameHighLight(int box);
 
 	int getTextInput(char *dest, int x, int y, int destMaxLen, int textColor1, int textColor2, int cursorColor);
@@ -78,9 +79,9 @@ private:
 	int selectSaveSlotDialogue(int x, int y, int id);
 	void runMemorizePrayMenu(int charIndex, int spellType);
 	void scribeScrollDialogue();
+	bool restParty();
 
 	bool confirmDialogue(int id);
-	bool confirmDialogue2(int dim, int id, int deflt);
 	void messageDialogue(int dim, int id, int buttonTextCol);
 	int selectCharacterDialogue(int id);
 	void displayTextBox(int id);
@@ -100,6 +101,8 @@ private:
 	void setupSaveMenuSlots();
 	int getHighlightSlot();
 
+	void restParty_updateRestTime(int hours, bool init);
+
 	Button _scrollUpButton;//////////////////77
 	Button _scrollDownButton;
 
diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
index f7aed1b..c6ec81a 100644
--- a/engines/kyra/items_eob.cpp
+++ b/engines/kyra/items_eob.cpp
@@ -221,7 +221,7 @@ void EobCoreEngine::deletePartyItem(Item itemType, int16 itemValue) {
 			continue;
 
 		EobCharacter *c = &_characters[i];
-		int slot = checkCharacterInventoryForItem(i, itemType, itemValue);
+		int slot = checkInventoryForItem(i, itemType, itemValue);
 
 		if (slot == -1)
 			continue;
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 7a9750f..fe770d4 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -235,7 +235,7 @@ void EobCoreEngine::removeCharacterEffect(int spell, int charIndex, int showWarn
 	if (showWarning) {
 		if (s->flags & 0x20A0)
 			gui_drawCharPortraitWithStats(charIndex);
-		else if (s->flags & 0x20A0)
+		else if (s->flags & 0x40)
 			gui_drawAllCharPortraitsWithStats();
 	}
 }
@@ -416,8 +416,40 @@ void EobCoreEngine::setSpellEventTimer(int spell, int timerBaseFactor, int timer
 	setCharEventTimer(_activeSpellCaster, countdown, -spell, updateExistingTimer);
 }
 
-void EobCoreEngine::cleanupCharacterSpellList(int charIndex) {
+void EobCoreEngine::sortCharacterSpellList(int charIndex) {
+	int8 *list = _characters[charIndex].mageSpells;
 
+	for (int i = 0; i < 16; ) {
+		bool p = false;
+		for (int ii = 0; ii < 9; ii++) {
+			int8 *pos = &list[ii];
+
+			int s1 = pos[0];
+			int s2 = pos[1];
+
+			if (s1 == 0)
+				s1 = 80;
+			else if (s1 < 0)
+				s1 = s1 * -1 + 40;
+
+			if (s2 == 0)
+				s2 = 80;
+			else if (s2 < 0)
+				s2 = s2 * -1 + 40;
+
+			if (s1 > s2) {
+				SWAP(pos[0], pos[1]);
+				p = true;
+			}
+		}
+
+		if (p)
+			continue;
+
+		list += 10;
+		if (++i == 8)
+			list = _characters[charIndex].clericSpells;
+	}
 }
 
 bool EobCoreEngine::magicObjectHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level) {
@@ -685,7 +717,7 @@ void EobCoreEngine::spellCallback_start_createFood() {
 	for (int i = 0; i < 6; i++) {
 		if (!testCharacter(i, 3))
 			continue;
-		_characters[_activeSpellCaster].food = 100;
+		_characters[i].food = 100;
 	}
 }
 
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 599539c..889865b 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -546,6 +546,8 @@ enum KyraResources {
 	kEob2Npc2Strings,
 	kEob2MonsterDustStrings,
 
+	kEob2DranFoolsStrings,
+
 	kLolIngamePakFiles,
 	kLolCharacterDefs,
 	kLolIngameSfxFiles,
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index a5b2a69..cde900b 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -185,7 +185,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 		c->faceShape = 0;
 		in.read(c->mageSpells, 80);
 		in.read(c->clericSpells, 80);
-		c->mageSpellsAvailabilityFlags = in.readUint32BE();
+		c->mageSpellsAvailableFlags = in.readUint32BE();
 		for (int ii = 0; ii < 27; ii++)
 			c->inventory[ii] = in.readSint16BE();
 		uint32 ct = _system->getMillis();
@@ -427,7 +427,7 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName,
 			out->writeUint32BE(c->experience[ii]);
 		out->write(c->mageSpells, 80);
 		out->write(c->clericSpells, 80);
-		out->writeUint32BE(c->mageSpellsAvailabilityFlags);
+		out->writeUint32BE(c->mageSpellsAvailableFlags);
 		for (int ii = 0; ii < 27; ii++)
 			out->writeSint16BE(c->inventory[ii]);
 		uint32 ct = _system->getMillis();
diff --git a/engines/kyra/sequences_eob2.cpp b/engines/kyra/sequences_eob2.cpp
index 1cc4585..8ff5581 100644
--- a/engines/kyra/sequences_eob2.cpp
+++ b/engines/kyra/sequences_eob2.cpp
@@ -1271,6 +1271,79 @@ void DarkmoonSequenceHelper::waitForSongNotifier(int index, bool introUpdateAnim
 	}
 }
 
+void DarkMoonEngine::seq_nightmare() {
+	Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+	_screen->copyRegion(0, 0, 0, 120, 176, 24, 14, 2, Screen::CR_NO_P_CHECK);
+
+	initDialogueSequence();
+	gui_drawDialogueBox();
+	
+	_txt->printDialogueText(99, 0);
+	snd_playSoundEffect(54);
+
+	static const int8 dreamSteps[] = { 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 3, 2, 1, 0, -1 };
+	static const uint8 seqX[] = { 0, 20, 0, 20 };
+	static const uint8 seqY[] = { 0, 0, 96, 96 };
+	static const uint8 seqDelay[] = { 12, 7, 7, 12 };
+
+	for (const int8 *i = dreamSteps; *i != -1; ++i) {
+		drawSequenceBitmap("DREAM", 0, seqX[*i], seqY[*i], 0);
+		delay(seqDelay[*i] * _tickLength);
+	}
+
+	_txt->printDialogueText(20, _okStrings[0]);
+	
+	restoreAfterDialogueSequence();
+
+	_screen->setFont(of);
+}
+
+void DarkMoonEngine::seq_dranFools() {
+	Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+
+	initDialogueSequence();
+	gui_drawDialogueBox();
+	
+	static const char file[] = "KHELDRAN";
+	_txt->printDialogueText(_dranFoolsStrings[0]);
+	drawSequenceBitmap(file, 0, 0, 0, 0);
+	_txt->printDialogueText(20, _moreStrings[0]);
+	snd_playSoundEffect(56);
+	drawSequenceBitmap(file, 0, 20, 0, 0);
+	delay(10 * _tickLength);
+	drawSequenceBitmap(file, 0, 0, 96, 0);
+	delay(10 * _tickLength);
+	drawSequenceBitmap(file, 0, 20, 96, 0);
+	delay(7 * _tickLength);
+	_txt->printDialogueText(76, _okStrings[0]);
+	
+	restoreAfterDialogueSequence();
+
+	_screen->setFont(of);
+}
+
+void DarkMoonEngine::seq_dranDragonTransformation() {
+	Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+
+	initDialogueSequence();
+	gui_drawDialogueBox();
+	
+	static const char file[] = "DRANX";
+	drawSequenceBitmap(file, 0, 0, 0, 0);
+	_txt->printDialogueText(120, _moreStrings[0]);
+	snd_playSoundEffect(56);
+	drawSequenceBitmap(file, 0, 20, 0, 0);
+	delay(7 * _tickLength);
+	drawSequenceBitmap(file, 0, 0, 96, 0);
+	delay(7 * _tickLength);
+	drawSequenceBitmap(file, 0, 20, 96, 0);
+	delay(18 * _tickLength);
+	
+	restoreAfterDialogueSequence();
+
+	_screen->setFont(of);
+}
+
 }	// End of namespace Kyra
 
 #endif // ENABLE_EOB
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index 109d244..8c492aa 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -224,20 +224,7 @@ void EobCoreEngine::killMonster(EobMonsterInPlay *m, bool giveExperience) {
 	if (giveExperience)
 		increasePartyExperience(_monsterProps[m->type].experience);
 
-	if ((_flags.gameID == GI_EOB2) && (_currentLevel == 16) && (_currentSub == 1) && (_monsterProps[m->type].flags & 4)) {
-		if (m->type) {
-			_playFinale = true;
-			_runFlag = false;
-		} else {
-			m->hitPointsCur = 150;
-			m->curRemoteWeapon = 0;
-			m->numRemoteAttacks = 255;
-			m->shpIndex++;
-			m->type++;
-			//// TODO
-			// dranDragonTransformation();
-		}
-	} else {
+	if (killMonsterExtra(m)) {
 		placeMonster(m, 0, -1);
 
 		if ((_flags.gameID == GI_EOB1) && (m->type == 21)) {
@@ -250,6 +237,10 @@ void EobCoreEngine::killMonster(EobMonsterInPlay *m, bool giveExperience) {
 	}
 }
 
+bool EobCoreEngine::killMonsterExtra(EobMonsterInPlay*) {
+	return true;
+}
+
 int EobCoreEngine::countSpecificMonsters(int type) {
 	int res = 0;
 	for (int i = 0; i < 30; i++) {
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index efc5b85..19789bb 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -157,7 +157,7 @@ bool StaticResource::loadEobNpcData(Common::SeekableReadStream &stream, void *&p
 		s->experience[0] = stream.readUint32BE();
 		s->experience[1] = stream.readUint32BE();
 		s->experience[2] = stream.readUint32BE();
-		s->mageSpellsAvailabilityFlags = stream.readUint32BE();
+		s->mageSpellsAvailableFlags = stream.readUint32BE();
 		for (int ii = 0; ii < 27; ii++)
 			s->inventory[i] = stream.readUint16BE();
 	}
@@ -1184,6 +1184,7 @@ void DarkMoonEngine::initStaticResource() {
 	_npc1Strings = _staticres->loadStrings(kEob2Npc1Strings, temp);
 	_npc2Strings = _staticres->loadStrings(kEob2Npc2Strings, temp);
 	_monsterDustStrings = _staticres->loadStrings(kEob2MonsterDustStrings, temp);
+	_dranFoolsStrings = _staticres->loadStrings(kEob2DranFoolsStrings, temp);
 }
 
 void DarkMoonEngine::initSpells() {
diff --git a/engines/kyra/text_eob.cpp b/engines/kyra/text_eob.cpp
index 0d9bf9d..c350666 100644
--- a/engines/kyra/text_eob.cpp
+++ b/engines/kyra/text_eob.cpp
@@ -445,9 +445,11 @@ void TextDisplayer_Eob::printDialogueText(int stringId, const char *pageBreakStr
 	displayText(_dialogueBuffer);
 
 	if (pageBreakString) {
-		strcpy(_pageBreakString, pageBreakString);
-		displayWaitButton();
-		resetPageBreakString();
+		if (pageBreakString[0]) {
+			strcpy(_pageBreakString, pageBreakString);
+			displayWaitButton();
+			resetPageBreakString();
+		}
 	}
 }
 
diff --git a/engines/kyra/timer.cpp b/engines/kyra/timer.cpp
index 2ab2b62..4722966 100644
--- a/engines/kyra/timer.cpp
+++ b/engines/kyra/timer.cpp
@@ -129,6 +129,26 @@ void TimerManager::update() {
 	}
 }
 
+void TimerManager::manualAdvance(uint32 millis) {
+	uint32 curTime = _system->getMillis();
+	for (Iterator pos = _timers.begin(); pos != _timers.end(); ++pos) {
+		if (pos->enabled == 1 && pos->countdown >= 0) {
+			pos->nextRun -= curTime;
+			while (pos->nextRun <= millis) {
+				if (pos->func && pos->func->isValid())
+					(*pos->func)(pos->id);
+
+				pos->lastUpdate = curTime;
+				pos->nextRun = pos->countdown * _vm->tickLength();
+				millis -= pos->nextRun;
+			}
+			pos->nextRun += curTime;
+			_nextRun = MIN(_nextRun, pos->nextRun);
+		}
+	}
+
+}
+
 void TimerManager::resync() {
 	const uint32 curTime = _isPaused ? _pauseStart : _system->getMillis();
 
diff --git a/engines/kyra/timer.h b/engines/kyra/timer.h
index 205be59..5e53d61 100644
--- a/engines/kyra/timer.h
+++ b/engines/kyra/timer.h
@@ -61,6 +61,8 @@ public:
 
 	void update();
 
+	void manualAdvance(uint32 millis);
+
 	void resetNextRun();
 
 	void setCountdown(uint8 id, int32 countdown);
diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp
index f6e8b63..00dc758 100644
--- a/engines/kyra/timer_eob.cpp
+++ b/engines/kyra/timer_eob.cpp
@@ -193,6 +193,23 @@ void EobCoreEngine::setupCharacterTimers() {
 	}
 }
 
+void EobCoreEngine::manualAdvanceTimer(int sysTimer, uint32 millis) {
+	if (sysTimer != 2)
+		return;
+
+	uint32 ct = _system->getMillis();
+	for (int i = 0; i < 6; i++) {
+		for (int ii = 0; ii < 10; ii++) {
+			if (_characters[i].timers[ii]) {
+				uint32 chrt = _characters[i].timers[ii] - ct;
+				_characters[i].timers[ii] = chrt > millis ? chrt - millis : 1;
+			}
+		}
+	}
+
+	_timer->manualAdvance(millis);
+}
+
 void EobCoreEngine::timerProcessCharacterExchange(int timerNum) {
 	_charExchangeSwap ^= 1;
 	if (_charExchangeSwap) {


Commit: c302b3e43b1d8cfe1eae669e01d3a0775d1f7b51
    https://github.com/scummvm/scummvm/commit/c302b3e43b1d8cfe1eae669e01d3a0775d1f7b51
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:13-08:00

Commit Message:
KYRA: (EOB) - fix various bugs and implement some spells

Changed paths:
    engines/kyra/eob2.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/items_eob.cpp
    engines/kyra/magic_eob.cpp
    engines/kyra/saveload_eob.cpp
    engines/kyra/scene_eob.cpp
    engines/kyra/sprites_eob.cpp
    engines/kyra/staticres_eob.cpp
    engines/kyra/timer.cpp
    engines/kyra/timer.h
    engines/kyra/timer_eob.cpp



diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index 8f3a10c..1931572 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -272,7 +272,7 @@ void DarkMoonEngine::replaceMonster(int unit, uint16 block, int pos, int dir, in
 }
 
 bool DarkMoonEngine::killMonsterExtra(EobMonsterInPlay *m) {
-	if (_currentLevel == 16 && _currentSub == 1 && (_monsterProps[m->type].flags & 4)) {
+	if (_currentLevel == 16 && _currentSub == 1 && (_monsterProps[m->type].capsFlags & 4)) {
 		if (m->type) {
 			_playFinale = true;
 			_runFlag = false;
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index eebe752..bb3848e 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -1547,7 +1547,7 @@ void EobCoreEngine::inflictMonsterDamage(EobMonsterInPlay *m, int damage, bool g
 	m->hitPointsCur -= damage;
 	m->flags = (m->flags & 0xf7) | 1;
 
-	if (_monsterProps[m->type].flags & 0x2000) {
+	if (_monsterProps[m->type].capsFlags & 0x2000) {
 		explodeMonster(m);
 		checkSceneUpdateNeed(m->block);
 		m->hitPointsCur = 0;
@@ -1762,7 +1762,7 @@ void EobCoreEngine::monsterCloseAttack(EobMonsterInPlay *m) {
 		}
 
 		if (dmg > 0) {
-			if ((_monsterProps[m->type].flags & 0x80) && rollDice(1, 4, -1) != 3) {
+			if ((_monsterProps[m->type].capsFlags & 0x80) && rollDice(1, 4, -1) != 3) {
 				int slot = rollDice(1, 27, -1);
 				for (int iii = 0; iii < 27; iii++) {
 					Item itm = _characters[c].inventory[slot];
@@ -1782,20 +1782,20 @@ void EobCoreEngine::monsterCloseAttack(EobMonsterInPlay *m) {
 
 			inflictCharacterDamage(c, dmg);
 
-			if (_monsterProps[m->type].flags & 0x10) {
+			if (_monsterProps[m->type].capsFlags & 0x10) {
 				statusAttack(c, 2, _monsterSpecAttStrings[_flags.gameID == GI_EOB1 ? 3 : 2], 0, 1, 8, 1);
 				_characters[c].effectFlags &= ~0x2000;
 			}
 
-			if (_monsterProps[m->type].flags & 0x20)
+			if (_monsterProps[m->type].capsFlags & 0x20)
 				statusAttack(c, 4, _monsterSpecAttStrings[_flags.gameID == GI_EOB1 ? 4 : 3], 2, 5, 9, 1);
 
-			if (_monsterProps[m->type].flags & 0x8000)
+			if (_monsterProps[m->type].capsFlags & 0x8000)
 				statusAttack(c, 8, _monsterSpecAttStrings[4], 2, 0, 0, 1);
 
 		}
 
-		if (!(_monsterProps[m->type].flags & 0x4000))
+		if (!(_monsterProps[m->type].capsFlags & 0x4000))
 			return;
 	}
 }
@@ -1848,7 +1848,7 @@ int EobCoreEngine::calcCloseDistanceMonsterDamage(EobMonsterInPlay *m, int times
 			s = 1;
 	}
 
-	if ((flags & 0x100) && ((_flags.gameID == GI_EOB2 && (p->statusFlags & 0x100)) || (_flags.gameID == GI_EOB1 && (p->flags & 4))) && (!(_itemTypes[_items[pips].type].allowedClasses & 4 /* bug in original code ??*/)))
+	if ((flags & 0x100) && ((_flags.gameID == GI_EOB2 && (p->statusFlags & 0x100)) || (_flags.gameID == GI_EOB1 && (p->capsFlags & 4))) && (!(_itemTypes[_items[pips].type].allowedClasses & 4 /* bug in original code ??*/)))
 		s >>= 1;
 
 	if (p->statusFlags & 0x2000) {
@@ -1866,7 +1866,7 @@ int EobCoreEngine::calcCloseDistanceMonsterDamage(EobMonsterInPlay *m, int times
 	}
 
 	if (flags & 1) {
-		if (checkMonsterDamageEvasion(m))
+		if (tryMonsterAttackEvasion(m))
 			s = 0;
 	}
 
@@ -1887,7 +1887,7 @@ int EobCoreEngine::calcDamageModifers(int charIndex, EobMonsterInPlay *m, int it
 	if (item) {
 		EobItemType *p = &_itemTypes[itemType];
 		int t = m ? m->type : 0;
-		s += ((m && (_monsterProps[t].flags & 1)) ?	rollDice(p->dmgNumDiceL, p->dmgNumPipsL, p->dmgIncS /* bug in original code ? */) :
+		s += ((m && (_monsterProps[t].capsFlags & 1)) ?	rollDice(p->dmgNumDiceL, p->dmgNumPipsL, p->dmgIncS /* bug in original code ? */) :
 			rollDice(p->dmgNumDiceS, p->dmgNumPipsS, p->dmgIncS));
 		s += _items[item].value;
 	} else {
@@ -1941,7 +1941,7 @@ int EobCoreEngine::recalcDamageModifier(int damageType, int dmgModifier) {
 	return dmgModifier;
 }
 
-bool EobCoreEngine::checkMonsterDamageEvasion(EobMonsterInPlay *m) {
+bool EobCoreEngine::tryMonsterAttackEvasion(EobMonsterInPlay *m) {
 	return rollDice(1, 100) < _monsterProps[m->type].dmgModifierEvade ? true : false;
 }
 
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 0cf2e9d..db56951 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -169,8 +169,8 @@ struct EobMonsterProperty {
 		int8 base;
 	} dmgDc[3];
 	uint16 statusFlags;
-	uint16 flags;
-	int32 u22;
+	uint32 capsFlags;
+	uint32 typeFlags;
 	int32 experience;
 
 	uint8 u30;
@@ -182,7 +182,7 @@ struct EobMonsterProperty {
 
 	int8 remoteWeapons[5];
 
-	uint8 u41;
+	uint8 tuResist;
 	uint8 dmgModifierEvade;
 
 	uint8 decorations[3];
@@ -199,7 +199,7 @@ struct EobMonsterInPlay {
 	int8 mode;
 	int8 f_9;
 	int8 curAttackFrame;
-	uint8 f_b;
+	int8 spellStatusLeft;
 	int16 hitPointsMax;
 	int16 hitPointsCur;
 	uint16 dest;
@@ -334,7 +334,7 @@ protected:
 	void setCharEventTimer(int charIndex, uint32 countdown, int evnt, int updateExistingTimer);
 	void deleteCharEventTimer(int charIndex, int evnt);
 	void setupCharacterTimers();
-	void manualAdvanceTimer(int sysTimer, uint32 millis);
+	void advanceTimers(uint32 millis);
 
 	void timerProcessMonsters(int timerNum);
 	void timerSpecialCharacterUpdate(int timerNum);
@@ -511,7 +511,7 @@ protected:
 	bool walkMonsterNextStep(EobMonsterInPlay *m, int destBlock, int direction);
 	void updateMonsterFollowPath(EobMonsterInPlay *m, int turnSteps);
 	void updateMonstersStraying(EobMonsterInPlay *m, int a);
-	void updateMonsters_mode710(EobMonsterInPlay *m);
+	void updateMonstersSpellStatus(EobMonsterInPlay *m);
 	void setBlockMonsterDirection(int block, int dir);
 
 	uint8 *_monsterOvl1;
@@ -829,7 +829,7 @@ protected:
 	int getConstModifierTableValue(int hpModifier, int level, int b);
 	bool calcDamageCheckItemType(int itemType);
 	int recalcDamageModifier(int damageType, int dmgModifier);
-	bool checkMonsterDamageEvasion(EobMonsterInPlay *m);
+	bool tryMonsterAttackEvasion(EobMonsterInPlay *m);
 	int getStrHitChanceModifier(int charIndex);
 	int getStrDamageModifier(int charIndex);
 	int getDexHitChanceModifier(int charIndex);
@@ -856,7 +856,11 @@ protected:
 	void setSpellEventTimer(int spell, int timerBaseFactor, int timerLength, int timerLevelFactor, int updateExistingTimer);
 	void sortCharacterSpellList(int charIndex);
 
-	bool magicObjectHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level);
+	bool magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level);
+	bool magicObjectStatusHit(EobMonsterInPlay *m, int type, bool tryEvade, int mod);
+
+	void printWarning(const char* str);
+	void printNoEffectWarning();
 
 	void spellCallback_start_empty() {}
 	bool spellCallback_end_empty(EobFlyingObject *fo) { return true; }
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 3a71642..c13b4da 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -665,11 +665,13 @@ void EobCoreEngine::gui_drawSpellbook() {
 	int textXs = 71;
 	int textY = 170;
 	int col3 = _bkgColor_1;
+	int col4 = _color6;
 
 	if (_flags.gameID == GI_EOB1) {
 		textCol2 = 11;
 		textXa = textXs = 73;
 		textY = 168;
+		col4 = _bkgColor_1;
 	}
 
 	for (int i = 0; i < 7; i++) {
@@ -686,7 +688,7 @@ void EobCoreEngine::gui_drawSpellbook() {
 			if (d >= 0 && i < 6 && (i + _openBookSpellListOffset) < 9)
 				_screen->printText(_openBookSpellList[d], textXs, 132 + 6 * i, textCol1, col3);
 			else
-				_screen->printText(_magicStrings1[0], textXa, textY, 12, _color6);
+				_screen->printText(_magicStrings1[0], textXa, textY, 12, col4);
 		}
 	}
 
@@ -805,7 +807,7 @@ void EobCoreEngine::gui_initButton(int index, int, int, int) {
 
 	if (_flags.gameID == GI_EOB1) {
 		// EOB1 spellbook modifications
-		if (index > 61 && index < 67)
+		if (index > 60 && index < 66)
 			d = &_buttonDefs[index + 33];
 		if (index == 88)
 			d = &_buttonDefs[index + 12];
@@ -867,7 +869,7 @@ int EobCoreEngine::clickedCamp(Button *button) {
 	_screen->updateScreen();
 
 	enableSysTimer(2);
-	manualAdvanceTimer(2, _restPartyElapsedTime);
+	advanceTimers(_restPartyElapsedTime);
 	_restPartyElapsedTime = 0;
 
 	checkPartyStatus(true);
@@ -1083,7 +1085,7 @@ int EobCoreEngine::clickedSpellbookList(Button *button) {
 
 				int s = _openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellListOffset + _openBookSpellSelectedItem];
 				if (_openBookType == 1)
-					s += _mageSpellListSize;
+					s += _clericSpellOffset;
 
 				castSpell(s, 0);
 
@@ -1100,11 +1102,10 @@ int EobCoreEngine::clickedSpellbookList(Button *button) {
 }
 
 int EobCoreEngine::clickedCastSpellOnCharacter(Button *button) {
-	_activeSpellCaster = button->arg;
+	_activeSpellCaster = button->arg & 0xff;
 
-	if (_activeSpellCaster == 255) {
-		_txt->printMessage(_magicStrings3[1]);
-		snd_playSoundEffect(79);
+	if (_activeSpellCaster == 0xff) {
+		printWarning(_magicStrings3[_flags.gameID == GI_EOB1 ? 2 : 1]);
 		if (_castScrollSlot) {
 			gui_updateSlotAfterScrollUse();
 		} else {
@@ -2774,7 +2775,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
 
 	for (int i = 0; i < 80; i++) {
 		int8 s = charSpellList[i];
-		if (s == 0 || s == _vm->_spellLevelsClericSize)
+		if (s == 0 || (_vm->game() == GI_EOB2 && s == 29))
 			continue;
 
 		if (s < 0)
@@ -2938,8 +2939,8 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
 	_screen->setFont(Screen::FID_8_FNT);
 
 	memset(charSpellList, 0, 80);
-	if (spellType)
-		charSpellList[0] = _vm->_spellLevelsClericSize;
+	if (spellType && _vm->game() == GI_EOB2)
+		charSpellList[0] = 29;
 
 	for (int i = 0; i < 32; i++) {
 		if (_numAssignedSpellsOfType[i * 2] < _numAssignedSpellsOfType[i * 2 + 1])
@@ -3187,7 +3188,7 @@ bool GUI_Eob::restParty() {
 
 					*list *= -1;
 					crs[i] = 48;					
-					_vm->_txt->printMessage(Common::String::format(_vm->_menuStringsRest2[0], _vm->_characters[i].name, _vm->_spells[_vm->_mageSpellListSize + *list].name).c_str());
+					_vm->_txt->printMessage(Common::String::format(_vm->_menuStringsRest2[0], _vm->_characters[i].name, _vm->_spells[_vm->_clericSpellOffset + *list].name).c_str());
 					_vm->delay(80);
 					break;
 				}
@@ -3485,7 +3486,7 @@ void GUI_Eob::messageDialogue(int dim, int id, int buttonTextCol) {
 }
 
 int GUI_Eob::selectCharacterDialogue(int id) {
-	uint8 flags = (id == 26) ? 0x14 : 0x02;
+	uint8 flags = (id == 26) ? (_vm->game() == GI_EOB1 ? 0x04 : 0x14) : 0x02;
 	_vm->removeInputTop();
 
 	_charSelectRedraw = false;	
@@ -3613,10 +3614,13 @@ int GUI_Eob::selectCharacterDialogue(int id) {
 	_screen->setFont(Screen::FID_8_FNT);
 
 	if (result != -1 && id != 53) {
-		if (flags == 0x14) {
-			if (_vm->_classModifierFlags[_vm->_characters[result].cClass] & 0x10 && _vm->_characters[result].level[0] < 9) {
-				displayTextBox(24);
-				result = -1;
+		if (flags & 4) {
+			int lv = _vm->getCharacterLevelIndex(4, _vm->_characters[result].cClass);
+			if (lv != -1) {
+				if (_vm->_characters[result].level[lv] < 9) {
+					displayTextBox(24);
+					result = -1;
+				}
 			}
 		} else {
 			if (_vm->checkInventoryForItem(result, 29, -1) == -1) {
diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
index c6ec81a..6c331e8 100644
--- a/engines/kyra/items_eob.cpp
+++ b/engines/kyra/items_eob.cpp
@@ -445,8 +445,7 @@ void EobCoreEngine::eatItemInHand(int charIndex) {
 	} else if (_itemInHand && _items[_itemInHand].type != 31) {
 		_txt->printMessage(_warningStrings[3]);
 	} else if (_items[_itemInHand].value == -1) {
-		_txt->printMessage(_warningStrings[2]);
-		snd_playSoundEffect(79);
+		printWarning(_warningStrings[2]);
 	} else {
 		c->food += _items[_itemInHand].value;
 		if (c->food > 100)
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index fe770d4..2275bd5 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -156,14 +156,12 @@ void EobCoreEngine::castSpell(int spell, int weaponSlot) {
 
 	if (s->flags & 0x400) {
 		if (c->inventory[0] && c->inventory[1]) {
-			_txt->printMessage(_magicStrings1[2]);
-			snd_playSoundEffect(79);
+			printWarning(_magicStrings1[2]);
 			return;
 		}
 
 		if (isMagicWeapon(c->inventory[0]) || isMagicWeapon(c->inventory[1])) {
-			_txt->printMessage(_magicStrings1[3]);
-			snd_playSoundEffect(79);
+			printWarning(_magicStrings1[3]);
 			return;
 		}
 	}
@@ -205,10 +203,8 @@ void EobCoreEngine::removeCharacterEffect(int spell, int charIndex, int showWarn
 	EobCharacter *c = &_characters[charIndex];
 	EobSpell *s = &_spells[spell];
 
-	if (showWarning) {
-		_txt->printMessage(_magicStrings3[2], -1, c->name, s->name);
-		snd_playSoundEffect(79);
-	}
+	if (showWarning)
+		printWarning(Common::String::format(_magicStrings3[_flags.gameID == GI_EOB1 ? 3 : 2], c->name, s->name).c_str());
 
 	if (s->endCallback)
 		(this->*s->endCallback)(0);
@@ -262,8 +258,7 @@ void EobCoreEngine::removeAllCharacterEffects(int charIndex) {
 }
 
 void EobCoreEngine::castOnWhomDialogue() {
-	_txt->printMessage(_magicStrings3[0]);
-	snd_playSoundEffect(79);
+	printWarning(_magicStrings3[0]);
 	gui_setCastOnWhomButtons();
 }
 
@@ -281,15 +276,13 @@ void EobCoreEngine::startSpell(int spell) {
 
 	if (s->flags & 0x20) {
 		_txt->printMessage(c->name);
-		_txt->printMessage(_magicStrings1[5]);
+		_txt->printMessage(_flags.gameID == GI_EOB1 ? _magicStrings3[1] : _magicStrings1[5]);
 	}
 
 	if ((s->flags & 0x30) && (s->effectFlags & c->effectFlags)) {
-		_txt->printMessage(_magicStrings7[0], -1, c->name, s->name);
-		snd_playSoundEffect(79);
+		printWarning(Common::String::format(_magicStrings7[0], c->name, s->name).c_str());
 	} else if ((s->flags & 0x50) && (s->effectFlags & _partyEffectFlags)) {
-		_txt->printMessage(_magicStrings7[1], -1, s->name);
-		snd_playSoundEffect(79);
+		printWarning(Common::String::format(_magicStrings7[1], s->name).c_str());
 	} else {
 		if (s->flags & 8)
 			setSpellEventTimer(spell, s->timingPara[0], s->timingPara[1], s->timingPara[2], s->timingPara[3]);
@@ -452,7 +445,7 @@ void EobCoreEngine::sortCharacterSpellList(int charIndex) {
 	}
 }
 
-bool EobCoreEngine::magicObjectHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level) {
+bool EobCoreEngine::magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level) {
 	int ignoreAttackerId = fo->flags & 0x10;
 	int singleTargetCheckAdjacent = fo->flags & 1;
 	int blockDamage = fo->flags & 2;
@@ -527,6 +520,70 @@ bool EobCoreEngine::magicObjectHit(EobFlyingObject *fo, int dcTimes, int dcPips,
 	return res;
 }
 
+bool EobCoreEngine::magicObjectStatusHit(EobMonsterInPlay *m, int type, bool tryEvade, int mod) {
+	EobMonsterProperty *p = &_monsterProps[m->type];
+	if (tryEvade) {
+		if (tryMonsterAttackEvasion(m) || (p->capsFlags & 0x10))
+			return true;
+	}
+
+	if (checkUnkConstModifiers(m, 0, p->level, mod, 6))
+		return false;
+	
+	int para = 0;
+		
+	switch (type) {
+	case 0:
+	case 1:
+	case 2:
+		para = (type == 0) ? ((p->typeFlags & 1) ? 1 : 0) : ((type == 1) ? ((p->typeFlags & 2) ? 1 : 0) : 1);
+		if (para && !(p->statusFlags & 2)) {
+			m->mode = 10;
+			m->spellStatusLeft = 15;
+		}
+
+		break;
+
+	case 3:
+		if (!(p->statusFlags & 8))
+			inflictMonsterDamage(m, 1000, true);
+		break;
+
+	case 4:
+		inflictMonsterDamage(m, 1000, true);
+		break;
+
+	case 5:
+		m->flags |= 0x20;
+		_sceneUpdateRequired = true;
+		break;
+
+	case 6:
+		if (!(p->statusFlags & 4) && m->mode != 7 && m->mode != 8 && m->mode != 10) {
+			m->mode = 0;
+			m->spellStatusLeft = 20;
+			para = (getNextMonsterDirection(m->block, _currentBlock) ^ 4) >> 1;
+			m->flags |= 8;
+			walkMonsterNextStep(m, -1, para);
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	return true;
+}
+
+void EobCoreEngine::printWarning(const char* str) {
+	_txt->printMessage(str);
+	snd_playSoundEffect(79);
+}
+
+void EobCoreEngine::printNoEffectWarning() {
+	printWarning(_magicStrings4[0]);
+}
+
 void EobCoreEngine::spellCallback_start_armor() {
 
 }
@@ -548,7 +605,7 @@ void EobCoreEngine::spellCallback_start_magicMissile() {
 }
 
 bool EobCoreEngine::spellCallback_end_magicMissile(EobFlyingObject *fo) {
-	return magicObjectHit(fo, 1, 4, 1, (getCharacterMageLevel(fo->attackerId) - 1) >> 1);
+	return magicObjectDamageHit(fo, 1, 4, 1, (getCharacterMageLevel(fo->attackerId) - 1) >> 1);
 }
 
 void EobCoreEngine::spellCallback_start_shockingGrasp() {
@@ -568,7 +625,7 @@ void EobCoreEngine::spellCallback_start_melfsAcidArrow() {
 }
 
 bool EobCoreEngine::spellCallback_end_melfsAcidArrow(EobFlyingObject *fo) {
-	return magicObjectHit(fo, 2, 4, 0, getCharacterMageLevel(fo->attackerId) / 3);
+	return magicObjectDamageHit(fo, 2, 4, 0, getCharacterMageLevel(fo->attackerId) / 3);
 }
 
 void EobCoreEngine::spellCallback_start_dispelMagic() {
@@ -580,7 +637,7 @@ void EobCoreEngine::spellCallback_start_fireball() {
 }
 
 bool EobCoreEngine::spellCallback_end_fireball(EobFlyingObject *fo) {
-	return magicObjectHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
+	return magicObjectDamageHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
 }
 
 void EobCoreEngine::spellCallback_start_flameArrow() {
@@ -588,7 +645,7 @@ void EobCoreEngine::spellCallback_start_flameArrow() {
 }
 
 bool EobCoreEngine::spellCallback_end_flameArrow(EobFlyingObject *fo) {
-	return magicObjectHit(fo, 5, 6, 0, getCharacterMageLevel(fo->attackerId));
+	return magicObjectDamageHit(fo, 5, 6, 0, getCharacterMageLevel(fo->attackerId));
 }
 
 void EobCoreEngine::spellCallback_start_holdPerson() {
@@ -596,7 +653,28 @@ void EobCoreEngine::spellCallback_start_holdPerson() {
 }
 
 bool EobCoreEngine::spellCallback_end_holdPerson(EobFlyingObject *fo) {
-	return true;
+	bool res = false;
+	
+	if (_flags.gameID == GI_EOB2 && fo->curBlock == _currentBlock) {
+		// party hit
+		int numChar = rollDice(1, 4, 0);
+		int charIndex = rollDice(1, 6, 0);
+		for (int i = 0; i < 6 && numChar; i++) {
+			if (testCharacter(charIndex, 3)) {
+				statusAttack(charIndex, 4, _magicStrings8[1], 4, 5, 9, 1);
+				numChar--;
+			}
+			charIndex = (charIndex + 1) % 6;
+		}
+		res = true;
+
+	} else {
+		// monster hit
+		for (const int16 *m = findBlockMonsters(fo->curBlock, fo->curPos, fo->direction, 1, 1); *m != -1; m++)
+			res |= magicObjectStatusHit(&_monsters[*m], 0, true, 4);
+	}
+
+	return res;
 }
 
 void EobCoreEngine::spellCallback_start_lightningBolt() {
@@ -604,7 +682,7 @@ void EobCoreEngine::spellCallback_start_lightningBolt() {
 }
 
 bool EobCoreEngine::spellCallback_end_lightningBolt(EobFlyingObject *fo) {
-	return magicObjectHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
+	return magicObjectDamageHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
 }
 
 void EobCoreEngine::spellCallback_start_vampiricTouch() {
@@ -616,7 +694,12 @@ bool EobCoreEngine::spellCallback_end_vampiricTouch(EobFlyingObject*) {
 }
 
 void EobCoreEngine::spellCallback_start_fear() {
-
+	sparkEffectOffensive();
+	uint16 bl = calcNewBlockPosition(_currentBlock, _currentDirection);
+	for (int i = 0; i < 30; i++) {
+		if (_monsters[i].block == bl)
+			magicObjectStatusHit(&_monsters[i], 6, true, 4);
+	}
 }
 
 void EobCoreEngine::spellCallback_start_iceStorm() {
@@ -625,12 +708,12 @@ void EobCoreEngine::spellCallback_start_iceStorm() {
 
 bool EobCoreEngine::spellCallback_end_iceStorm(EobFlyingObject *fo) {
 	static int8 blockAdv[] = { -32, 32, 1, -1 };
-	bool res = magicObjectHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
+	bool res = magicObjectDamageHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
 	if (res) {
 		for (int i = 0; i < 4; i++) {
 			uint16 bl = fo->curBlock;
 			fo->curBlock = (fo->curBlock + blockAdv[i]) & 0x3ff;
-			magicObjectHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
+			magicObjectDamageHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
 			fo->curBlock = bl;
 		}
 	}
@@ -650,7 +733,10 @@ void EobCoreEngine::spellCallback_start_holdMonster() {
 }
 
 bool EobCoreEngine::spellCallback_end_holdMonster(EobFlyingObject *fo) {
-	return true;
+	bool res = false;
+	for (const int16 *m = findBlockMonsters(fo->curBlock, fo->curPos, fo->direction, 1, 1); *m != -1; m++)
+		res |= magicObjectStatusHit(&_monsters[*m], 1, true, 4);
+	return res;
 }
 
 void EobCoreEngine::spellCallback_start_wallOfForce() {
@@ -662,18 +748,27 @@ void EobCoreEngine::spellCallback_start_disintegrate() {
 }
 
 void EobCoreEngine::spellCallback_start_fleshToStone() {
-
+	sparkEffectOffensive();
+	int t = getClosestMonsterPos(_openBookChar, calcNewBlockPosition(_currentBlock, _currentDirection));
+	if (t != -1)
+		magicObjectStatusHit(&_monsters[t], 5, true, 4);
+	else
+		printWarning(_magicStrings8[4]);
 }
 
 void EobCoreEngine::spellCallback_start_stoneToFlesh() {
-
+	if (_characters[_activeSpellCaster].flags & 8)
+		_characters[_activeSpellCaster].flags &= ~8;
+	else
+		printNoEffectWarning();
 }
 
 void EobCoreEngine::spellCallback_start_trueSeeing() {
-
+	_wllVmpMap[46] = 0;
 }
 
 bool EobCoreEngine::spellCallback_end_trueSeeing(EobFlyingObject*) {
+	_wllVmpMap[46] = 1;
 	return true;
 }
 
@@ -722,7 +817,13 @@ void EobCoreEngine::spellCallback_start_createFood() {
 }
 
 void EobCoreEngine::spellCallback_start_removeParalysis() {
-
+	int numChar = 4;
+	for (int i = 0; i < 6; i++) {
+		if (!(_characters[i].flags & 4) || !numChar)
+			continue;
+		_characters[i].flags &= ~4;
+		numChar--;
+	}
 }
 
 void EobCoreEngine::spellCallback_start_causeSeriousWounds() {
@@ -750,7 +851,7 @@ void EobCoreEngine::spellCallback_start_flameStrike() {
 }
 
 bool EobCoreEngine::spellCallback_end_flameStrike(EobFlyingObject *fo) {
-	return magicObjectHit(fo, 6, 8, 0, 0);
+	return magicObjectDamageHit(fo, 6, 8, 0, 0);
 }
 
 void EobCoreEngine::spellCallback_start_raiseDead() {
@@ -763,12 +864,10 @@ void EobCoreEngine::spellCallback_start_harm() {
 
 void EobCoreEngine::spellCallback_start_heal() {
 	EobCharacter *c = &_characters[_activeSpellCaster];
-	if (c->hitPointsMax <= c->hitPointsCur) {
-		_txt->printMessage(_magicStrings4[0]);
-		snd_playSoundEffect(79);
-	} else {
+	if (c->hitPointsMax <= c->hitPointsCur)
+		printWarning(_magicStrings4[0]);
+	else
 		modifyCharacterHitpoints(_activeSpellCaster, c->hitPointsMax - c->hitPointsCur);
-	}
 }
 
 void EobCoreEngine::spellCallback_start_layOnHands() {
@@ -782,19 +881,19 @@ void EobCoreEngine::spellCallback_start_turnUndead() {
 bool EobCoreEngine::spellCallback_end_unk1Passive(EobFlyingObject *fo) {
 	bool res = false;
 	if (_partyEffectFlags & 0x20000) {
-		res = magicObjectHit(fo, 4, 10, 6, 0);
+		res = magicObjectDamageHit(fo, 4, 10, 6, 0);
 		if (res) {
 			gui_drawAllCharPortraitsWithStats();
 			_partyEffectFlags &= ~0x20000;
 		}
 	} else {
-		res = magicObjectHit(fo, 12, 10, 6, 0);
+		res = magicObjectDamageHit(fo, 12, 10, 6, 0);
 	}
 	return res;
 }
 
 bool EobCoreEngine::spellCallback_end_unk2Passive(EobFlyingObject *fo) {
-	return magicObjectHit(fo, 0, 0, 18, 0);
+	return magicObjectDamageHit(fo, 0, 0, 18, 0);
 }
 
 bool EobCoreEngine::spellCallback_end_deathSpellPassive(EobFlyingObject *fo) {
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index cde900b..1fa26c2 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -315,7 +315,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 			m->mode = in.readSByte();
 			m->f_9 = in.readSByte();
 			m->curAttackFrame = in.readSByte();
-			m->f_b = in.readByte();
+			m->spellStatusLeft = in.readSByte();
 			m->hitPointsMax = in.readSint16BE();
 			m->hitPointsCur = in.readSint16BE();
 			m->dest = in.readUint16BE();
@@ -523,7 +523,7 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName,
 			out->writeSByte(m->mode);
 			out->writeSByte(m->f_9);
 			out->writeSByte(m->curAttackFrame);
-			out->writeByte(m->f_b);
+			out->writeSByte(m->spellStatusLeft);
 			out->writeSint16BE(m->hitPointsMax);
 			out->writeSint16BE(m->hitPointsCur);
 			out->writeUint16BE(m->dest);
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index e92d813..36584d4 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -583,7 +583,7 @@ void LolEobBaseEngine::openCloseDoor(int block, int openClose) {
 			}
 		}
 
-		enableTimer(_flags.gameID == GI_LOL ? 0 : 12);
+		enableTimer(_flags.gameID == GI_LOL ? 0 : 4);
 
 	} else {
 		while (!(flg & _wllWallFlags[v]))
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index 8c492aa..baa7a0b 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -99,9 +99,9 @@ const uint8 *EobCoreEngine::loadMonsterProperties(const uint8 *data) {
 		d->dmgDc[3].base = (int8)*data++;
 		d->statusFlags = READ_LE_UINT16(data);
 		data += 2;
-		d->flags = READ_LE_UINT16(data);
+		d->capsFlags = READ_LE_UINT16(data);
 		data += 2;
-		d->u22 = (int16)READ_LE_UINT16(data);
+		d->typeFlags = READ_LE_UINT16(data);
 		data += 2;
 		d->experience = READ_LE_UINT16(data);
 		data += 2;
@@ -121,7 +121,7 @@ const uint8 *EobCoreEngine::loadMonsterProperties(const uint8 *data) {
 			}
 		}
 
-		d->u41 = *data++;
+		d->tuResist = *data++;
 		d->dmgModifierEvade = *data++;
 
 		for (int i = 0; i < 3; i++)
@@ -176,7 +176,7 @@ void EobCoreEngine::initMonster(int index, int unit, uint16 block, int pos, int
 	m->pos = pos;
 	m->shpIndex = shpIndex;
 	m->mode = mode;
-	m->f_b = i;
+	m->spellStatusLeft = i;
 	m->dir = dir;
 	m->palette = _flags.gameID == GI_EOB2 ? (index % 3) : 0;
 	m->hitPointsCur = m->hitPointsMax = _flags.gameID == GI_EOB2 ? rollDice(p->hpDcTimes, p->hpDcPips, p->hpDcBase) : (p->hpDcTimes == 255 ? rollDice(1, 4, 0) : rollDice(p->hpDcTimes, 8, 0));
@@ -503,11 +503,11 @@ void EobCoreEngine::drawMonsters(int index) {
 
 		EobMonsterProperty *p = &_monsterProps[d->type];
 
-		if (_flags.gameID == GI_EOB2 && (p->flags & 0x100) && !(_partyEffectFlags & 0x220) && !(d->flags & 2))
+		if (_flags.gameID == GI_EOB2 && (p->capsFlags & 0x100) && !(_partyEffectFlags & 0x220) && !(d->flags & 2))
 			continue;
 
 		int f = (d->animStep << 4) + cDirOffs + d->dir;
-		f = (p->flags & 2) ? _monsterFrmOffsTable1[f] : _monsterFrmOffsTable2[f];
+		f = (p->capsFlags & 2) ? _monsterFrmOffsTable1[f] : _monsterFrmOffsTable2[f];
 
 		if (!blockDistance && d->curAttackFrame < 0)
 			f = d->curAttackFrame + 7;
@@ -719,7 +719,7 @@ void EobCoreEngine::updateMonsters(int unit) {
 				break;
 			case 7:
 			case 10:
-				updateMonsters_mode710(m);
+				updateMonstersSpellStatus(m);
 				break;
 			default:
 				break;
@@ -871,7 +871,7 @@ void EobCoreEngine::updateMoveMonster(EobMonsterInPlay *m) {
 	EobMonsterProperty *p = &_monsterProps[m->type];
 	int d = getNextMonsterDirection(m->block, _currentBlock);
 
-	if ((p->flags & 0x800) && !(d & 1))
+	if ((p->capsFlags & 0x800) && !(d & 1))
 		d >>= 1;
 	else
 		d = m->dir;
@@ -892,13 +892,13 @@ void EobCoreEngine::updateMoveMonster(EobMonsterInPlay *m) {
 	m->curAttackFrame = 0;
 	walkMonster(m, m->dest);
 
-	if (p->flags & 8)
+	if (p->capsFlags & 8)
 		updateMonsterTryCloseAttack(m, -1);
 }
 
 bool EobCoreEngine::updateMonsterTryDistanceAttack(EobMonsterInPlay *m) {
 	EobMonsterProperty *p = &_monsterProps[m->type];
-	if (!m->numRemoteAttacks || ((_flags.gameID == GI_EOB1) && !(p->flags & 0x40)))
+	if (!m->numRemoteAttacks || ((_flags.gameID == GI_EOB1) && !(p->capsFlags & 0x40)))
 		return false;
 
 	if ((_flags.gameID == GI_EOB1 && m->stepsTillRemoteAttack == 5) || (_flags.gameID == GI_EOB2 && rollDice(1, 3) > m->stepsTillRemoteAttack)) {
@@ -1073,8 +1073,8 @@ void EobCoreEngine::walkMonster(EobMonsterInPlay *m, int destBlock) {
 	if (m->flags & 8) {
 		if (_flags.gameID == GI_EOB1 ) {
 			d ^= 4;
-		} else if (--m->f_b <= 0) {
-			m->f_b = 0;
+		} else if (--m->spellStatusLeft <= 0) {
+			m->spellStatusLeft = 0;
 			m->flags &= ~8;
 		} else {
 			d ^= 4;
@@ -1095,7 +1095,7 @@ void EobCoreEngine::walkMonster(EobMonsterInPlay *m, int destBlock) {
 		} else if (_flags.gameID == GI_EOB2) {
 			if (d & 1) {
 				int e = _monsterStepTable1[((d - 1) << 1) + m->dir];
-				if (e && !((_monsterProps[m->type].flags & 0x200) && (rollDice(1, 4) == 4))) {
+				if (e && !((_monsterProps[m->type].capsFlags & 0x200) && (rollDice(1, 4) == 4))) {
 					if (walkMonsterNextStep(m, b + e, -1))
 						return;
 				}
@@ -1144,11 +1144,11 @@ bool EobCoreEngine::walkMonsterNextStep(EobMonsterInPlay *m, int destBlock, int
 		uint8 w = l->walls[direction ^ 2];
 
 		if (!(_wllWallFlags[w] & 4)) {
-			if (_flags.gameID == GI_EOB1 ||!(p->flags & 0x1000) || _wllShapeMap[w] != -1)
+			if (_flags.gameID == GI_EOB1 || !(p->capsFlags & 0x1000) || _wllShapeMap[w] != -1)
 				return false;
 
 			if (_wllWallFlags[w] & 0x20) {
-				if (p->flags & 4 && m->type == 1)
+				if (p->capsFlags & 4 && m->type == 1)
 					l->walls[direction] = l->walls[direction ^ 2] = 72;
 				else
 					openDoor(destBlock);
@@ -1219,9 +1219,9 @@ void EobCoreEngine::updateMonstersStraying(EobMonsterInPlay *m, int a) {
 	}
 }
 
-void EobCoreEngine::updateMonsters_mode710(EobMonsterInPlay *m) {
-	if (m->f_b) {
-		if (!--m->f_b)
+void EobCoreEngine::updateMonstersSpellStatus(EobMonsterInPlay *m) {
+	if (m->spellStatusLeft) {
+		if (!--m->spellStatusLeft)
 			m->mode = 0;
 	}
 }
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 19789bb..f422d69 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -631,7 +631,7 @@ void EobCoreEngine::initButtonData() {
 		{ 4, 0, 0x1100, 113, 122, 20, 8, EOB_CB(clickedSpellbookTab), 2 },
 		{ 5, 0, 0x1100, 134, 122, 20, 8, EOB_CB(clickedSpellbookTab), 3 },
 		{ 6, 0, 0x1100, 155, 122, 20, 8, EOB_CB(clickedSpellbookTab), 4 },
-		{ 110, 0, 0x1100, 75, 168, 97, 6, EOB_CB(clickedSpellbookAbort), 0 },
+		{ 110, 0, 0x1100, 75, 168, 97, 6, EOB_CB(clickedSpellbookAbort), 0 }
 	};
 
 	_buttonDefs = buttonDefs;
@@ -975,11 +975,19 @@ void EobCoreEngine::initSpells() {
 	ec2(fleshToStonePassive);
 
 	_spells = new EobSpell[_numSpells];
-	memset(_spells, 0, _numSpells * sizeof(EobSpell));
+	memset(_spells, 0, _numSpells * sizeof(EobSpell));	
 
-	for (int i = 0; i < _numSpells; i++) {
+	for (int i = 0, n = 0; i < _numSpells; i++, n++) {
 		EobSpell *s = &_spells[i];
-		s->name = _flags.gameID == GI_EOB2 ? ((i == 0 || i == _mageSpellListSize) ? _mageSpellList[0] : ((i < (_mageSpellListSize + 1)) ? _spellNames[i - 1] : _spellNames[i - 2])) : _spellNames[i];
+
+		// Fix Eob 1 spell names
+		bool skip = false;
+		if (i == 5 || i == 9) {
+			n--;
+			skip = true;
+		}
+
+		s->name = _flags.gameID == GI_EOB2 ? ((i == 0 || i == _mageSpellListSize) ? _mageSpellList[0] : ((i < (_mageSpellListSize + 1)) ? _spellNames[i - 1] : _spellNames[i - 2])) : (skip ? _spellNames[0] : _spellNames[n]);
 		s->startCallback = startCallback[i];
 		s->timingPara = magicTimingParaAssign[i];
 		s->endCallback = endCallback[i];
@@ -1031,8 +1039,7 @@ void EobEngine::initStaticResource() {
 	temp /= 27;
 	_monsterProps = new EobMonsterProperty[temp];
 	memset(_monsterProps, 0, temp * sizeof(EobMonsterProperty));
-	// Try to convert EOB1 (hard coded) monster properties to EOB2 type monster properties.
-	// This is still WIP, since most properties are unknown for now.
+	// Convert EOB1 (hard coded) monster properties to EOB2 type monster properties.
 	for (int i = 0; i < temp; i++) {
 		EobMonsterProperty *p = &_monsterProps[i];
 		p->armorClass = (int8)*ps++;
@@ -1049,9 +1056,9 @@ void EobEngine::initStaticResource() {
 		p->dmgDc[2].pips = *ps++;
 		p->dmgDc[2].base = (int8)*ps++;
 		ps++;
-		p->flags = *ps++;
-		ps++;
-		ps++;
+		p->capsFlags = *ps++;
+		p->typeFlags = READ_LE_UINT16(ps);
+		ps += 2;
 		ps++;
 		ps++;
 		p->experience = READ_LE_UINT16(ps);
@@ -1060,7 +1067,7 @@ void EobEngine::initStaticResource() {
 		p->sound1 = *ps++;
 		p->sound2 = *ps++;
 		p->numRemoteAttacks = *ps++;
-		ps++;
+		p->tuResist = *ps++;
 		p->dmgModifierEvade = *ps++;
 	}
 }
@@ -1132,7 +1139,7 @@ void EobEngine::initSpells() {
 
 	int temp;
 	const uint8 *src = _staticres->loadRawData(kEobBaseSpellProperties, temp);
-	_clericSpellOffset -= 3;
+	_clericSpellOffset -= 1;
 
 	for (int i = 0; i < _numSpells; i++) {
 		EobSpell *s = &_spells[i];
diff --git a/engines/kyra/timer.cpp b/engines/kyra/timer.cpp
index 4722966..2ab2b62 100644
--- a/engines/kyra/timer.cpp
+++ b/engines/kyra/timer.cpp
@@ -129,26 +129,6 @@ void TimerManager::update() {
 	}
 }
 
-void TimerManager::manualAdvance(uint32 millis) {
-	uint32 curTime = _system->getMillis();
-	for (Iterator pos = _timers.begin(); pos != _timers.end(); ++pos) {
-		if (pos->enabled == 1 && pos->countdown >= 0) {
-			pos->nextRun -= curTime;
-			while (pos->nextRun <= millis) {
-				if (pos->func && pos->func->isValid())
-					(*pos->func)(pos->id);
-
-				pos->lastUpdate = curTime;
-				pos->nextRun = pos->countdown * _vm->tickLength();
-				millis -= pos->nextRun;
-			}
-			pos->nextRun += curTime;
-			_nextRun = MIN(_nextRun, pos->nextRun);
-		}
-	}
-
-}
-
 void TimerManager::resync() {
 	const uint32 curTime = _isPaused ? _pauseStart : _system->getMillis();
 
diff --git a/engines/kyra/timer.h b/engines/kyra/timer.h
index 5e53d61..205be59 100644
--- a/engines/kyra/timer.h
+++ b/engines/kyra/timer.h
@@ -61,8 +61,6 @@ public:
 
 	void update();
 
-	void manualAdvance(uint32 millis);
-
 	void resetNextRun();
 
 	void setCountdown(uint8 id, int32 countdown);
diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp
index 00dc758..903dec2 100644
--- a/engines/kyra/timer_eob.cpp
+++ b/engines/kyra/timer_eob.cpp
@@ -133,19 +133,21 @@ void EobCoreEngine::setCharEventTimer(int charIndex, uint32 countdown, int evnt,
 		_timer->setNextRun(timerId, ntime);
 
 	if (updateExistingTimer) {
-		bool br = false;
+		bool updated = false;
 		int d = -1;
 
-		for (int i = 0; i < 10 && br == false; i++) {
+		for (int i = 0; i < 10 && updated == false; i++) {
 			if (d == -1 && !c->timers[i])
 				d = i;
 
-			if (!br && c->events[i] == evnt) {
+			if (!updated && c->events[i] == evnt) {
 				d = i;
-				br = true;
+				updated = true;
 			}
 		}
 
+		assert(d != -1);
+
 		c->timers[d] = ntime;
 		c->events[d] = evnt;
 	} else {
@@ -179,7 +181,7 @@ void EobCoreEngine::setupCharacterTimers() {
 		uint32 nextTimer = 0xffffffff;
 
 		for (int ii = 0; ii < 10; ii++) {
-			if (c->timers[ii] < nextTimer)
+			if (c->timers[ii] && c->timers[ii] < nextTimer)
 				nextTimer = c->timers[ii];
 		}
 		uint32 ctime = _system->getMillis();
@@ -193,21 +195,28 @@ void EobCoreEngine::setupCharacterTimers() {
 	}
 }
 
-void EobCoreEngine::manualAdvanceTimer(int sysTimer, uint32 millis) {
-	if (sysTimer != 2)
-		return;
-
+void EobCoreEngine::advanceTimers(uint32 millis) {
 	uint32 ct = _system->getMillis();
 	for (int i = 0; i < 6; i++) {
+		EobCharacter *c = &_characters[i];
 		for (int ii = 0; ii < 10; ii++) {
-			if (_characters[i].timers[ii]) {
-				uint32 chrt = _characters[i].timers[ii] - ct;
-				_characters[i].timers[ii] = chrt > millis ? chrt - millis : 1;
+			if (c->timers[ii] > ct) {
+				uint32 chrt = c->timers[ii] - ct;
+				c->timers[ii] = chrt > millis ? chrt - millis : ct;
 			}
 		}
 	}
 
-	_timer->manualAdvance(millis);
+	setupCharacterTimers();
+
+	if (_scriptTimersMode & 2) {
+		for (int i = 0; i < _scriptTimersCount; i++) {
+			if (_scriptTimers[i].next > ct) {
+				uint32 chrt = _scriptTimers[i].next - ct;
+				_scriptTimers[i].next = chrt > millis ? chrt - millis : ct;
+			}
+		}
+	}
 }
 
 void EobCoreEngine::timerProcessCharacterExchange(int timerNum) {
@@ -314,7 +323,7 @@ void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
 				calcAndInflictCharacterDamage(charIndex, 0, 0, 5, 0x400, 5, 3);
 				setCharEventTimer(charIndex, 546, 8, 1);
 			} else {
-				c->flags &= 0xfd;
+				c->flags &= ~2;
 				gui_drawCharPortraitWithStats(charIndex);
 			}
 			break;
@@ -329,7 +338,7 @@ void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
 
 		case 11:
 			if (c->disabledSlots & 4) {
-				c->disabledSlots &= 0xfb;
+				c->disabledSlots &= ~4;
 				if (_openBookChar == charIndex && _updateFlags)
 					gui_drawSpellbook();
 			}
@@ -345,13 +354,13 @@ void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
 		}
 	}
 
-	uint32 nextTimer = (uint32)(-1);
+	uint32 nextTimer = 0xffffffff;
 	for (int i = 0; i < 10; i++) {
 		if (c->timers[i] && c->timers[i] < nextTimer)
 			nextTimer = c->timers[i];
 	}
 
-	if (nextTimer == (uint32)(-1))
+	if (nextTimer == 0xffffffff)
 		_timer->disable(timerNum);
 	else
 		_timer->setCountdown(timerNum, (nextTimer - ctime) / _tickLength);


Commit: 0e4c184e285c9b20b90536eb485a7f8a50833da3
    https://github.com/scummvm/scummvm/commit/0e4c184e285c9b20b90536eb485a7f8a50833da3
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:13-08:00

Commit Message:
KYRA: (EOB) - implement some gui functionality, some bug fixes, etc.

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    dists/engine-data/kyra.dat
    engines/kyra/eob1.cpp
    engines/kyra/eob1.h
    engines/kyra/eob2.cpp
    engines/kyra/eob2.h
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/items_eob.cpp
    engines/kyra/magic_eob.cpp
    engines/kyra/resource.h
    engines/kyra/staticres.cpp
    engines/kyra/staticres_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index ac94166..9f749f0 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -45,7 +45,7 @@
 #include <map>
 
 enum {
-	kKyraDatVersion = 78
+	kKyraDatVersion = 79
 };
 
 const ExtractFilename extractFilenames[] = {
@@ -238,8 +238,26 @@ const ExtractFilename extractFilenames[] = {
 
 	{ kEobBasePryDoorStrings, kTypeStringList, true },
 	{ kEobBaseWarningStrings, kTypeStringList, true },
-	{ kEobBaseItemSuffixStrings, kTypeStringList, true },
-	{ kEobBaseItemExtraStrings, kTypeStringList, true },
+
+	{ kEobBaseItemSuffixStringsRings, kTypeStringList, true },
+	{ kEobBaseItemSuffixStringsPotions, kTypeStringList, true },
+	{ kEobBaseItemSuffixStringsWands, kTypeStringList, true },
+
+	{ kEobBaseRipItemStrings, kTypeStringList, true },
+	{ kEobBaseCursedString, kTypeStringList, true },
+	{ kEobBaseEnchantedString, kTypeStringList, false },
+	{ kEobBaseMagicObjectStrings, kTypeStringList, true },
+	{ kEobBaseMagicObject5String, kTypeStringList, true },
+	{ kEobBasePatternSuffix, kTypeStringList, true },
+	{ kEobBasePatternGrFix1, kTypeStringList, true },
+	{ kEobBasePatternGrFix2, kTypeStringList, true },
+	{ kEobBaseValidateArmorString, kTypeStringList, true },
+	{ kEobBaseValidateCursedString, kTypeStringList, true },
+	{ kEobBaseValidateNoDropString, kTypeStringList, true },
+	{ kEobBasePotionStrings, kTypeStringList, true },
+	{ kEobBaseWandString, kTypeStringList, true },
+	{ kEobBaseItemMisuseStrings, kTypeStringList, true },
+
 	{ kEobBaseTakenStrings, kTypeStringList, true },
 	{ kEobBasePotionEffectStrings, kTypeStringList, true },
 
@@ -334,6 +352,10 @@ const ExtractFilename extractFilenames[] = {
 	{ kEobBaseInvSlotX, kLolTypeRaw16, false },
 	{ kEobBaseInvSlotY, kTypeRawData, false },
 	{ kEobBaseSlotValidationFlags, kLolTypeRaw16, false },
+
+	{ kEobBaseProjectileWeaponTypes, kTypeRawData, false },
+	{ kEobBaseWandTypes, kTypeRawData, false },
+
 	{ kEobBaseDrawObjPosIndex, kTypeRawData, false },
 	{ kEobBaseFlightObjFlipIndex, kTypeRawData, false },
 	{ kEobBaseFlightObjShpMap, kTypeRawData, false },
@@ -493,6 +515,8 @@ const ExtractFilename extractFilenames[] = {
 	{ kEob2Npc2Strings, kTypeStringList, true },
 	{ kEob2MonsterDustStrings, kTypeStringList, true },
 	{ kEob2DranFoolsStrings, kTypeStringList, true },
+	{ kEob2HornStrings, kTypeStringList, true },
+	{ kEob2HornSounds, kTypeRawData, false },
 	
 	// LANDS OF LORE
 
@@ -1301,10 +1325,40 @@ const char *getIdString(const int id) {
 		return "kEobBasePryDoorStrings";
 	case kEobBaseWarningStrings:
 		return "kEobBaseWarningStrings";
-	case kEobBaseItemSuffixStrings:
-		return "kEobBaseItemSuffixStrings";
-	case kEobBaseItemExtraStrings:
-		return "kEobBaseItemExtraStrings";
+	case kEobBaseItemSuffixStringsRings:
+		return "kEobBaseItemSuffixStringsRings";
+	case kEobBaseItemSuffixStringsPotions:
+		return "kEobBaseItemSuffixStringsPotions";
+	case kEobBaseItemSuffixStringsWands:
+		return "kEobBaseItemSuffixStringsWands";
+	case kEobBaseRipItemStrings:
+		return "kEobBaseRipItemStrings";
+	case kEobBaseCursedString:
+		return "kEobBaseCursedString";
+	case kEobBaseEnchantedString:
+		return "kEobBaseEnchantedString";
+	case kEobBaseMagicObjectStrings:
+		return "kEobBaseMagicObjectStrings";
+	case kEobBaseMagicObject5String:
+		return "kEobBaseMagicObject5String";
+	case kEobBasePatternSuffix:
+		return "kEobBasePatternSuffix";
+	case kEobBasePatternGrFix1:
+		return "kEobBasePatternGrFix1";
+	case kEobBasePatternGrFix2:
+		return "kEobBasePatternGrFix2";
+	case kEobBaseValidateArmorString:
+		return "kEobBaseValidateArmorString";
+	case kEobBaseValidateCursedString:
+		return "kEobBaseValidateCursedString";
+	case kEobBaseValidateNoDropString:
+		return "kEobBaseValidateNoDropString";
+	case kEobBasePotionStrings:
+		return "kEobBasePotionStrings";
+	case kEobBaseWandString:
+		return "kEobBaseWandString";
+	case kEobBaseItemMisuseStrings:
+		return "kEobBaseItemMisuseStrings";
 	case kEobBaseTakenStrings:
 		return "kEobBaseTakenStrings";
 	case kEobBasePotionEffectStrings:
@@ -1471,6 +1525,10 @@ const char *getIdString(const int id) {
 		return "kEobBaseInvSlotY";
 	case kEobBaseSlotValidationFlags:
 		return "kEobBaseSlotValidationFlags";
+	case kEobBaseProjectileWeaponTypes:
+		return "kEobBaseProjectileWeaponTypes";
+	case kEobBaseWandTypes:
+		return "kEobBaseWandTypes";
 	case kEobBaseDrawObjPosIndex:
 		return "kEobBaseDrawObjPosIndex";
 	case kEobBaseFlightObjFlipIndex:
@@ -1770,6 +1828,10 @@ const char *getIdString(const int id) {
 		return "kEob2MonsterDustStrings";
 	case kEob2DranFoolsStrings:
 		return "kEob2DranFoolsStrings";
+	case kEob2HornStrings:
+		return "kEob2HornStrings";
+	case kEob2HornSounds:
+		return "kEob2HornSounds";
 	case kLolIngamePakFiles:
 		return "kLolIngamePakFiles";
 	case kLolCharacterDefs:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index 238a68a..598050d 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -214,8 +214,26 @@ enum kExtractID {
 
 	kEobBasePryDoorStrings,
 	kEobBaseWarningStrings,
-	kEobBaseItemSuffixStrings,
-	kEobBaseItemExtraStrings,
+
+	kEobBaseItemSuffixStringsRings,
+	kEobBaseItemSuffixStringsPotions,
+	kEobBaseItemSuffixStringsWands,
+	
+	kEobBaseRipItemStrings,
+	kEobBaseCursedString,
+	kEobBaseEnchantedString,
+	kEobBaseMagicObjectStrings,
+	kEobBaseMagicObject5String,
+	kEobBasePatternSuffix,
+	kEobBasePatternGrFix1,
+	kEobBasePatternGrFix2,
+	kEobBaseValidateArmorString,
+	kEobBaseValidateCursedString,
+	kEobBaseValidateNoDropString,
+	kEobBasePotionStrings,
+	kEobBaseWandString,
+	kEobBaseItemMisuseStrings,
+	
 	kEobBaseTakenStrings,
 	kEobBasePotionEffectStrings,
 
@@ -333,6 +351,10 @@ enum kExtractID {
 	kEobBaseInvSlotX,
 	kEobBaseInvSlotY,
 	kEobBaseSlotValidationFlags,
+
+	kEobBaseProjectileWeaponTypes,
+	kEobBaseWandTypes,
+
 	kEobBaseDrawObjPosIndex,
 	kEobBaseFlightObjFlipIndex,
 	kEobBaseFlightObjShpMap,
@@ -386,7 +408,6 @@ enum kExtractID {
 	kEob1MonsterDistAttType17,
 	kEob1MonsterDistAttSfx17,
 
-
 	kEob2MainMenuStrings,
 	kEob2IntroStrings,
 	kEob2IntroCPSFiles,
@@ -475,6 +496,8 @@ enum kExtractID {
 	kEob2MonsterDustStrings,
 
 	kEob2DranFoolsStrings,
+	kEob2HornStrings,
+	kEob2HornSounds,
 
 	kLolIngamePakFiles,
 	kLolCharacterDefs,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index ed99d26..0496acc 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1066,8 +1066,23 @@ const int eob1FloppyNeed[] = {
 
 	kEobBasePryDoorStrings,
 	kEobBaseWarningStrings,
-	kEobBaseItemSuffixStrings,
-	kEobBaseItemExtraStrings,
+
+	kEobBaseItemSuffixStringsRings,
+	kEobBaseItemSuffixStringsPotions,
+	kEobBaseItemSuffixStringsWands,
+	
+	kEobBaseRipItemStrings,
+	kEobBaseCursedString,
+	kEobBaseEnchantedString,
+	kEobBaseMagicObjectStrings,
+	kEobBaseMagicObject5String,
+	kEobBasePatternSuffix,
+	kEobBaseValidateArmorString,
+	kEobBaseValidateNoDropString,
+	kEobBasePotionStrings,
+	kEobBaseWandString,
+	kEobBaseItemMisuseStrings,
+
 	kEobBaseTakenStrings,
 	kEobBasePotionEffectStrings,
 
@@ -1186,6 +1201,10 @@ const int eob1FloppyNeed[] = {
 	kEobBaseInvSlotX,
 	kEobBaseInvSlotY,
 	kEobBaseSlotValidationFlags,
+
+	kEobBaseProjectileWeaponTypes,
+	kEobBaseWandTypes,
+
 	kEobBaseDrawObjPosIndex,
 	kEobBaseFlightObjFlipIndex,
 	kEobBaseFlightObjShpMap,
@@ -1249,8 +1268,26 @@ const int eob2FloppyNeed[] = {
 
 	kEobBasePryDoorStrings,
 	kEobBaseWarningStrings,
-	kEobBaseItemSuffixStrings,
-	kEobBaseItemExtraStrings,
+
+	kEobBaseItemSuffixStringsRings,
+	kEobBaseItemSuffixStringsPotions,
+	kEobBaseItemSuffixStringsWands,
+
+	kEobBaseRipItemStrings,
+	kEobBaseCursedString,
+	kEobBaseEnchantedString,
+	kEobBaseMagicObjectStrings,
+	kEobBaseMagicObject5String,
+	kEobBasePatternSuffix,
+	kEobBasePatternGrFix1,
+	kEobBasePatternGrFix2,
+	kEobBaseValidateArmorString,
+	kEobBaseValidateCursedString,
+	kEobBaseValidateNoDropString,
+	kEobBasePotionStrings,
+	kEobBaseWandString,
+	kEobBaseItemMisuseStrings,
+
 	kEobBaseTakenStrings,
 	kEobBasePotionEffectStrings,
 
@@ -1371,6 +1408,10 @@ const int eob2FloppyNeed[] = {
 	kEobBaseInvSlotX,
 	kEobBaseInvSlotY,
 	kEobBaseSlotValidationFlags,
+
+	kEobBaseProjectileWeaponTypes,
+	kEobBaseWandTypes,
+
 	kEobBaseDrawObjPosIndex,
 	kEobBaseFlightObjFlipIndex,
 	kEobBaseFlightObjShpMap,
@@ -1485,6 +1526,8 @@ const int eob2FloppyNeed[] = {
 	kEob2Npc2Strings,
 	kEob2MonsterDustStrings,
 	kEob2DranFoolsStrings,
+	kEob2HornStrings,
+	kEob2HornSounds,
 
 	kLolEobCommonDscShapeIndex,
 	kLolEobCommonDscX,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index 7457f4f..c45b3d4 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -137,7 +137,7 @@ const ExtractEntrySearchData k1OutroReunionSeqProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000547, 0x0000781C, { { 0xCF, 0xD6, 0x1D, 0x3D, 0x14, 0x40, 0x88, 0x35, 0x36, 0x4F, 0x0B, 0x1F, 0x9A, 0x1C, 0x3D, 0xAC } } } }, // floppy
 	{ UNK_LANG, kPlatformPC, { 0x00000547, 0x000077E0, { { 0x80, 0xC4, 0xFC, 0xD5, 0xEB, 0xAA, 0xA5, 0x87, 0x58, 0x5E, 0xAA, 0xE7, 0x01, 0x8F, 0x59, 0x3F } } } }, // floppy
 	{ UNK_LANG, kPlatformPC, { 0x000005E5, 0x00008918, { { 0x6A, 0x33, 0x8C, 0xB0, 0x16, 0x57, 0x2D, 0xEB, 0xB2, 0xE1, 0x64, 0x80, 0x98, 0x99, 0x98, 0x19 } } } }, // CD
-	
+
 	{ UNK_LANG, kPlatformAmiga, { 0x0000054A, 0x0000785F, { { 0x55, 0xEA, 0xB8, 0x7F, 0x3A, 0x86, 0xCD, 0xA6, 0xBC, 0xA7, 0x9A, 0x39, 0xED, 0xF5, 0x30, 0x0A } } } },
 
 	{ UNK_LANG, kPlatformUnknown, { 0x00000547, 0x00007876, { { 0x7A, 0xC7, 0x80, 0x34, 0x7A, 0x1B, 0xAB, 0xF8, 0xA7, 0x2F, 0x63, 0x3C, 0xDA, 0x89, 0x3F, 0x82 } } } }, // some floppy DOS + FM-TOWNS
@@ -1452,19 +1452,124 @@ const ExtractEntrySearchData kEobBaseWarningStringsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseItemSuffixStringsProvider[] = {
-	{ EN_ANY, kPlatformUnknown, { 0x000000BF, 0x00004241, { { 0x5B, 0x5E, 0xD4, 0x55, 0x86, 0x18, 0x9B, 0x99, 0x5D, 0x39, 0x5A, 0x3F, 0xF7, 0xF0, 0x3B, 0x42 } } } },	// EOB 1
-	{ EN_ANY, kPlatformUnknown, { 0x000000CC, 0x00004708, { { 0xF9, 0x04, 0x46, 0x9D, 0xD3, 0xF4, 0xFA, 0xE2, 0x12, 0x79, 0xBB, 0x00, 0x20, 0xE7, 0xB7, 0x35 } } } },	// EOB 2
-	{ DE_DEU, kPlatformUnknown, { 0x000000CA, 0x000047A4, { { 0x89, 0x01, 0x88, 0x85, 0x19, 0x6A, 0xEE, 0xC9, 0x62, 0x65, 0x7E, 0xB7, 0xE6, 0x27, 0xB0, 0x53 } } } },	// EOB 1
-	{ DE_DEU, kPlatformUnknown, { 0x00000109, 0x00005CAF, { { 0xB0, 0x39, 0xF9, 0xAE, 0x04, 0x3A, 0x96, 0xED, 0x55, 0x0E, 0xB4, 0x0F, 0x53, 0x62, 0x6D, 0xD6 } } } },	// EOB 2
+const ExtractEntrySearchData kEobBaseItemSuffixStringsRingsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000002B, 0x00000F7B, { { 0x8A, 0x27, 0x87, 0x81, 0x5F, 0x74, 0x27, 0xA9, 0x5E, 0x1B, 0xEE, 0xC0, 0xF7, 0x22, 0x8F, 0x57 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000022, 0x00000C02, { { 0x7D, 0x5F, 0x40, 0xEA, 0xAD, 0xDD, 0x1B, 0xA0, 0xA6, 0xE0, 0x57, 0x7D, 0x0D, 0x60, 0xF4, 0x2C } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x0000002E, 0x00000FF2, { { 0xE1, 0x50, 0xB7, 0xE2, 0xEF, 0xAD, 0x5B, 0x6D, 0x27, 0x35, 0x9C, 0xE7, 0x2D, 0xB2, 0x2E, 0xD0 } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseItemSuffixStringsPotionsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000054, 0x00001DDB, { { 0xB6, 0x78, 0xD9, 0x09, 0x1D, 0x09, 0x63, 0xF8, 0x96, 0x74, 0xF0, 0x75, 0x23, 0xF5, 0xD4, 0xC4 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000064, 0x000024ED, { { 0x10, 0x5A, 0xB8, 0xCA, 0x0F, 0x0D, 0x44, 0x19, 0x9D, 0x3D, 0x76, 0x54, 0xA1, 0x69, 0x97, 0x8B } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x0000006F, 0x00002792, { { 0x1A, 0x71, 0x2B, 0xCC, 0xCA, 0xDA, 0xF6, 0xED, 0x5E, 0xF0, 0x24, 0x20, 0xD7, 0x2D, 0x18, 0x49 } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseItemSuffixStringsWandsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000003C, 0x000014EB, { { 0xB5, 0x38, 0x35, 0x57, 0xF2, 0xF8, 0x0E, 0xBA, 0x75, 0x03, 0x1C, 0xCD, 0x46, 0x7D, 0x03, 0x83 } } } },	// EOB 1
+	{ EN_ANY, kPlatformUnknown, { 0x0000004A, 0x000019B2, { { 0x44, 0x10, 0xE4, 0xAF, 0xAB, 0x19, 0x25, 0x87, 0x2B, 0x15, 0x1C, 0x4C, 0x03, 0x50, 0x41, 0xC4 } } } },	// EOB 2
+	{ DE_DEU, kPlatformUnknown, { 0x00000040, 0x000016B5, { { 0xEC, 0xF4, 0x71, 0xC1, 0x69, 0x5C, 0xF9, 0xC1, 0xED, 0xC1, 0xED, 0x0C, 0x25, 0x3E, 0x13, 0xB1 } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000069, 0x0000252B, { { 0x12, 0x06, 0xEA, 0x2F, 0xAF, 0x47, 0x55, 0x52, 0xB6, 0xD9, 0x11, 0xA4, 0x4F, 0x30, 0xCE, 0x9D } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseRipItemStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000025, 0x00000AEA, { { 0x7A, 0x2D, 0x03, 0xA5, 0x94, 0xD1, 0xA2, 0x2C, 0x41, 0x1F, 0xEB, 0x5C, 0xFB, 0xB2, 0xC6, 0x9E } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000024, 0x00000B1B, { { 0xD0, 0x26, 0x19, 0x0B, 0xA5, 0x8A, 0x38, 0x73, 0x14, 0x25, 0x40, 0x5D, 0x24, 0xB8, 0x4E, 0xC5 } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x0000002E, 0x00000D38, { { 0xCE, 0xC5, 0x00, 0x63, 0xBB, 0xF0, 0xC4, 0x0D, 0x50, 0x2B, 0x82, 0x1C, 0xC0, 0xCD, 0xF1, 0xAF } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseCursedStringProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000000D, 0x000003C7, { { 0x7F, 0x6B, 0x6A, 0xFE, 0x63, 0xF4, 0x17, 0xAF, 0xFD, 0x00, 0x31, 0x4A, 0x20, 0x9E, 0x8C, 0xEB } } } },	// EOB 1
+	{ EN_ANY, kPlatformUnknown, { 0x0000000D, 0x000003C7, { { 0x59, 0xD8, 0x84, 0x25, 0xE0, 0x06, 0x51, 0xA4, 0x70, 0xC5, 0x78, 0x22, 0xF0, 0x2D, 0xA0, 0x43 } } } },	// EOB 2
+	{ DE_DEU, kPlatformUnknown, { 0x00000010, 0x00000514, { { 0x97, 0x41, 0xA6, 0xAE, 0xF8, 0xA8, 0x3E, 0x85, 0xA8, 0x16, 0x01, 0x15, 0x0E, 0x46, 0x13, 0x45 } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000013, 0x000005A5, { { 0xEC, 0xD3, 0xA5, 0xD2, 0xAD, 0x7C, 0x5E, 0x0F, 0x42, 0xBC, 0x6E, 0xDE, 0x7E, 0x36, 0x0B, 0x43 } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseEnchantedStringProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000007, 0x0000016C, { { 0x98, 0x62, 0xD3, 0xA3, 0x11, 0xAE, 0x0A, 0xBA, 0x8F, 0xE8, 0x30, 0x0B, 0xDC, 0x12, 0x90, 0x3B } } } },	// EOB 1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000007, 0x0000016C, { { 0x01, 0x91, 0xBD, 0x89, 0xAE, 0x0E, 0x71, 0xEE, 0xBE, 0x31, 0xD9, 0x55, 0x21, 0x61, 0x19, 0xAE } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMagicObjectStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000002B, 0x00000E7D, { { 0x7E, 0x8F, 0x17, 0xEB, 0xE5, 0x5D, 0xEB, 0x9A, 0x84, 0xFF, 0x86, 0x6A, 0x01, 0x3E, 0x04, 0x84 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x0000003A, 0x000014E4, { { 0x3D, 0x34, 0x3C, 0xCA, 0xDC, 0xD1, 0xCF, 0x15, 0x69, 0x57, 0xC3, 0xB1, 0x58, 0xDF, 0xE9, 0x9D } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x0000002A, 0x00000EE4, { { 0x9C, 0x38, 0x4B, 0x9B, 0x67, 0x30, 0x4E, 0x88, 0xA9, 0xA2, 0xF8, 0x78, 0x8E, 0xC7, 0xC3, 0x86 } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseMagicObject5StringProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000006, 0x000001FE, { { 0x74, 0x8D, 0xB9, 0x76, 0xD2, 0x2F, 0x60, 0xD2, 0x36, 0x45, 0x98, 0x4C, 0x0A, 0xE5, 0xE5, 0x0D } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000006, 0x00000204, { { 0xE4, 0xC1, 0xAD, 0x71, 0x87, 0x80, 0x9D, 0x97, 0x91, 0x80, 0x3F, 0x71, 0xD3, 0x62, 0x06, 0xD5 } } } }, // EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000007, 0x0000027A, { { 0x44, 0x47, 0x79, 0x46, 0x9B, 0xE5, 0xBD, 0x3C, 0xE8, 0x8D, 0xC6, 0xC5, 0x4E, 0x88, 0x13, 0xC0 } } } }, // EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBasePatternSuffixProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000009, 0x00000245, { { 0x67, 0x3F, 0x33, 0xA5, 0x3B, 0x5D, 0x2C, 0x9E, 0x15, 0x82, 0x04, 0xE2, 0xD7, 0x34, 0x42, 0x24 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000006, 0x0000015D, { { 0x33, 0xD6, 0x91, 0x2D, 0xED, 0xE1, 0x43, 0x42, 0x23, 0xB9, 0xE9, 0x3D, 0x48, 0x82, 0x92, 0x1E } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000008, 0x00000219, { { 0xCD, 0xDC, 0x7F, 0x8B, 0xBE, 0xD6, 0x05, 0x37, 0xDA, 0xDC, 0x11, 0xC3, 0x1E, 0x7A, 0xE7, 0x13 } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBasePatternGrFix1Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000009, 0x00000245, { { 0x67, 0x3F, 0x33, 0xA5, 0x3B, 0x5D, 0x2C, 0x9E, 0x15, 0x82, 0x04, 0xE2, 0xD7, 0x34, 0x42, 0x24 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000006, 0x0000015D, { { 0x33, 0xD6, 0x91, 0x2D, 0xED, 0xE1, 0x43, 0x42, 0x23, 0xB9, 0xE9, 0x3D, 0x48, 0x82, 0x92, 0x1E } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000007, 0x0000018A, { { 0x02, 0x5C, 0x86, 0xD9, 0x62, 0x0C, 0x71, 0xB3, 0x77, 0x9C, 0x7B, 0xBC, 0x4D, 0x5B, 0xDB, 0xE7 } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBasePatternGrFix2Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000009, 0x00000245, { { 0x67, 0x3F, 0x33, 0xA5, 0x3B, 0x5D, 0x2C, 0x9E, 0x15, 0x82, 0x04, 0xE2, 0xD7, 0x34, 0x42, 0x24 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000006, 0x0000015D, { { 0x33, 0xD6, 0x91, 0x2D, 0xED, 0xE1, 0x43, 0x42, 0x23, 0xB9, 0xE9, 0x3D, 0x48, 0x82, 0x92, 0x1E } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000006, 0x00000150, { { 0x48, 0xBE, 0xED, 0xD3, 0xA5, 0x2E, 0xCD, 0xE0, 0x34, 0xBA, 0xA6, 0x8D, 0x7D, 0x00, 0xA2, 0xFF } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseItemExtraStringsProvider[] = {
-	{ EN_ANY, kPlatformUnknown, { 0x00000161, 0x000072D6, { { 0x15, 0xD3, 0x0A, 0x45, 0xCD, 0xD7, 0xC5, 0x93, 0x17, 0x3E, 0x1A, 0x0D, 0xAD, 0x50, 0xC2, 0x5E } } } },	// EOB 1
-	{ EN_ANY, kPlatformUnknown, { 0x00000221, 0x0000B466, { { 0x6E, 0x24, 0x2C, 0xCE, 0x32, 0xC4, 0xF4, 0x4F, 0xC1, 0x79, 0x9A, 0x1C, 0x61, 0xB2, 0x08, 0x4F } } } },	// EOB 2
-	{ DE_DEU, kPlatformUnknown, { 0x00000191, 0x000087C3, { { 0x3B, 0x27, 0x8D, 0xFF, 0x88, 0x2D, 0x0D, 0x92, 0x47, 0xC5, 0x50, 0xB5, 0x36, 0x01, 0xCC, 0x58 } } } },	// EOB 1
-	{ DE_DEU, kPlatformUnknown, { 0x00000281, 0x0000D8BF, { { 0x7D, 0xB7, 0x06, 0x9D, 0x1E, 0x1D, 0x87, 0xAF, 0xD4, 0x40, 0xAF, 0xF9, 0xCD, 0xE3, 0x1E, 0x02 } } } },	// EOB 2
+const ExtractEntrySearchData kEobBaseValidateArmorStringProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000023, 0x00000B78, { { 0xC2, 0x33, 0x6B, 0xB9, 0xE1, 0x5E, 0x88, 0x5E, 0x22, 0xF2, 0x97, 0x83, 0xF8, 0xC8, 0x8C, 0xAB } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000026, 0x00000D19, { { 0xAD, 0x19, 0xE2, 0xDE, 0x04, 0xF9, 0x8F, 0x92, 0xAC, 0x1A, 0x05, 0xEA, 0x7B, 0xB5, 0x9F, 0x09 } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000029, 0x00000E7A, { { 0xEC, 0xA8, 0x2E, 0x8D, 0xB1, 0xC8, 0x0F, 0xCD, 0x24, 0xBD, 0x4B, 0x39, 0x16, 0xC9, 0x53, 0x08 } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseValidateCursedStringProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000002E, 0x00000F35, { { 0xE7, 0x0E, 0xA1, 0xCE, 0xCC, 0x13, 0xBC, 0x4B, 0x2B, 0x19, 0xEB, 0xA4, 0x05, 0xCF, 0xCF, 0x65 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000037, 0x000012D8, { { 0x3C, 0x7F, 0x16, 0xCE, 0x40, 0x58, 0xF1, 0x3A, 0xAB, 0x4C, 0x37, 0x82, 0x32, 0x88, 0xA4, 0x2D } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseValidateNoDropStringProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000001F, 0x00000A8F, { { 0x61, 0x99, 0x3E, 0x36, 0x49, 0x19, 0xB4, 0xE4, 0xBC, 0xFA, 0xB5, 0x71, 0x0E, 0xD6, 0x15, 0x3C } } } },	// EOB 1
+	{ EN_ANY, kPlatformUnknown, { 0x00000020, 0x00000AB6, { { 0xAA, 0x0E, 0x64, 0xD1, 0xA2, 0xA6, 0x62, 0x76, 0x51, 0xDF, 0x9E, 0x76, 0x85, 0x42, 0xE1, 0x4A } } } },	// EOB 2
+	{ DE_DEU, kPlatformUnknown, { 0x00000024, 0x00000C31, { { 0x10, 0xD9, 0x55, 0x69, 0xFE, 0x0A, 0x8C, 0xE5, 0xF7, 0x05, 0x5F, 0x09, 0x3B, 0xC9, 0x93, 0x38 } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000027, 0x00000D9F, { { 0xA5, 0xF0, 0x8E, 0x78, 0x0A, 0x37, 0x31, 0xDC, 0xE0, 0xDF, 0xE5, 0xCB, 0x86, 0xDC, 0x21, 0x73 } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBasePotionStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000017, 0x0000070E, { { 0xD9, 0xCB, 0x26, 0xB6, 0x6F, 0x17, 0x12, 0xB7, 0xB0, 0x95, 0x1B, 0x2A, 0xD8, 0x83, 0x0D, 0x2B } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x0000001E, 0x000009BD, { { 0xCA, 0xD0, 0x29, 0xB0, 0x7A, 0x2B, 0x0B, 0x69, 0xCA, 0xA4, 0xCA, 0x97, 0xCF, 0x8B, 0x03, 0xAD } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x0000001D, 0x00000964, { { 0x5D, 0xE2, 0xA5, 0x0D, 0x72, 0xE9, 0x8F, 0xC9, 0xFA, 0xF3, 0x41, 0x5A, 0x3F, 0x33, 0xAA, 0x15 } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseWandStringProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000035, 0x000011EC, { { 0x7C, 0x3D, 0xF1, 0x28, 0x0C, 0x23, 0xD3, 0x18, 0xEE, 0xAD, 0xA7, 0xF4, 0x58, 0xD7, 0x1C, 0x8E } } } },	// EOB 1
+	{ EN_ANY, kPlatformUnknown, { 0x00000029, 0x00000E47, { { 0xED, 0x2E, 0xD4, 0x4D, 0xDB, 0x90, 0x3F, 0xD0, 0xFB, 0x95, 0xB8, 0xF2, 0xCF, 0x06, 0x08, 0xAF } } } },	// EOB 2
+	{ DE_DEU, kPlatformUnknown, { 0x00000046, 0x0000186E, { { 0x54, 0x8F, 0x53, 0x34, 0xE8, 0x81, 0x76, 0x71, 0x53, 0x3F, 0x99, 0xE7, 0xCF, 0xB7, 0xC9, 0xD9 } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x0000002F, 0x00001070, { { 0x86, 0x18, 0x00, 0x54, 0x05, 0x3D, 0xC2, 0x26, 0xA7, 0xD9, 0x68, 0xE6, 0xC2, 0x0D, 0x26, 0x99 } } } },	// EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseItemMisuseStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000066, 0x000022F6, { { 0xE8, 0xB9, 0x07, 0x61, 0x29, 0x90, 0xB0, 0x22, 0x30, 0xC5, 0x0F, 0xAD, 0xCA, 0x6C, 0x83, 0xC6 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000068, 0x00002472, { { 0xCA, 0xD7, 0xFD, 0x5B, 0x65, 0x72, 0xC7, 0x15, 0xB3, 0xFE, 0xFC, 0xEF, 0x53, 0xFB, 0x57, 0x6C } } } },	// EOB 1
+	{ DE_DEU, kPlatformUnknown, { 0x0000007E, 0x00002C87, { { 0x5E, 0x11, 0xC9, 0x93, 0xF4, 0xAB, 0x1A, 0x9D, 0xA7, 0x62, 0x71, 0x94, 0x37, 0xCA, 0xE2, 0x25 } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
@@ -1983,6 +2088,19 @@ const ExtractEntrySearchData kEobBaseSlotValidationFlagsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEobBaseProjectileWeaponTypesProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000000D, 0x0000063E, { { 0xA6, 0x75, 0x6C, 0x39, 0x96, 0xCB, 0xA7, 0xC2, 0x31, 0xE0, 0x2A, 0x75, 0x30, 0x96, 0x58, 0x05 } } } }, // EOB 1
+	{ UNK_LANG, kPlatformPC, { 0x0000000C, 0x0000063E, { { 0x3E, 0x99, 0x6D, 0xE4, 0x6B, 0xC8, 0x49, 0x1B, 0x17, 0xD2, 0xBE, 0x9B, 0xE0, 0xCD, 0xA1, 0xC2 } } } }, // EOB 1
+	{ UNK_LANG, kPlatformPC, { 0x0000000F, 0x00000829, { { 0x9F, 0x6A, 0x13, 0x8A, 0xA7, 0x40, 0xE8, 0x40, 0x2E, 0x87, 0x49, 0x6B, 0x67, 0xED, 0xE8, 0xCE } } } }, // EOB 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseWandTypesProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000007, 0x00000162, { { 0xDB, 0x5D, 0x34, 0x70, 0x41, 0xAB, 0x8F, 0x75, 0xC8, 0x61, 0x8E, 0x44, 0x82, 0xCF, 0x28, 0x03 } } } }, // EOB 1
+	{ UNK_LANG, kPlatformPC, { 0x00000008, 0x00000175, { { 0x01, 0xC2, 0xF0, 0xC6, 0x1C, 0xD0, 0x14, 0xD9, 0xB8, 0xF5, 0x9C, 0xFC, 0x22, 0xE4, 0xA0, 0xA7 } } } }, // EOB 2
+	EXTRACT_END_ENTRY
+};
+
 const ExtractEntrySearchData kEobBaseDrawObjPosIndexProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000014, 0x00000028, { { 0x44, 0x46, 0x8C, 0x94, 0x76, 0x24, 0x08, 0xC7, 0x1F, 0x1B, 0x10, 0xD7, 0xDF, 0x18, 0x6C, 0x0D } } } },
 	EXTRACT_END_ENTRY
@@ -2778,6 +2896,18 @@ const ExtractEntrySearchData kEob2DranFoolsStringsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEob2HornStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000009A, 0x00003541, { { 0xA5, 0x4D, 0x88, 0xAC, 0x1C, 0xCD, 0x57, 0xD4, 0x1E, 0x9F, 0xAE, 0x13, 0x46, 0xAD, 0xA0, 0x22 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x000000AB, 0x00003B6C, { { 0x36, 0x34, 0xB3, 0xB1, 0x55, 0x66, 0x7A, 0x90, 0x97, 0x01, 0xDC, 0x4A, 0xAF, 0x17, 0x6B, 0x5A } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2HornSoundsProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000106, { { 0x3E, 0x7B, 0x96, 0xFD, 0xCA, 0x4E, 0xA7, 0xA6, 0xB8, 0x82, 0x67, 0xCF, 0x93, 0x86, 0xE4, 0x45 } } } },
+
+	EXTRACT_END_ENTRY
+};
+
 const ExtractEntrySearchData kLolIngamePakFilesProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000088, 0x0000224F, { { 0xDA, 0x24, 0x18, 0xA3, 0xEF, 0x16, 0x70, 0x8F, 0xA8, 0xC2, 0x2E, 0xC2, 0xED, 0x39, 0x03, 0xD1 } } } },
 	{ UNK_LANG, kPlatformPC98, { 0x00000084, 0x00002125, { { 0x7A, 0x89, 0xE2, 0x36, 0xEC, 0x6F, 0x52, 0x2B, 0xEF, 0xBA, 0x3D, 0x28, 0x54, 0xDA, 0xFB, 0x72 } } } },
@@ -3412,8 +3542,26 @@ const ExtractEntry extractProviders[] = {
 	
 	{ kEobBasePryDoorStrings, kEobBasePryDoorStringsProvider },
 	{ kEobBaseWarningStrings, kEobBaseWarningStringsProvider },
-	{ kEobBaseItemSuffixStrings, kEobBaseItemSuffixStringsProvider },
-	{ kEobBaseItemExtraStrings, kEobBaseItemExtraStringsProvider },
+
+	{ kEobBaseItemSuffixStringsRings, kEobBaseItemSuffixStringsRingsProvider },
+	{ kEobBaseItemSuffixStringsPotions, kEobBaseItemSuffixStringsPotionsProvider },
+	{ kEobBaseItemSuffixStringsWands, kEobBaseItemSuffixStringsWandsProvider },
+
+	{ kEobBaseRipItemStrings, kEobBaseRipItemStringsProvider },
+	{ kEobBaseCursedString, kEobBaseCursedStringProvider },
+	{ kEobBaseEnchantedString, kEobBaseEnchantedStringProvider },
+	{ kEobBaseMagicObjectStrings, kEobBaseMagicObjectStringsProvider },
+	{ kEobBaseMagicObject5String, kEobBaseMagicObject5StringProvider },
+	{ kEobBasePatternSuffix, kEobBasePatternSuffixProvider },
+	{ kEobBasePatternGrFix1, kEobBasePatternGrFix1Provider },
+	{ kEobBasePatternGrFix2, kEobBasePatternGrFix2Provider },
+	{ kEobBaseValidateArmorString, kEobBaseValidateArmorStringProvider },
+	{ kEobBaseValidateCursedString, kEobBaseValidateCursedStringProvider },
+	{ kEobBaseValidateNoDropString, kEobBaseValidateNoDropStringProvider },
+	{ kEobBasePotionStrings, kEobBasePotionStringsProvider },
+	{ kEobBaseWandString, kEobBaseWandStringProvider },
+	{ kEobBaseItemMisuseStrings, kEobBaseItemMisuseStringsProvider },
+
 	{ kEobBaseTakenStrings, kEobBaseTakenStringsProvider },
 	{ kEobBasePotionEffectStrings, kEobBasePotionEffectStringsProvider },
 
@@ -3507,6 +3655,10 @@ const ExtractEntry extractProviders[] = {
 	{ kEobBaseInvSlotX, kEobBaseInvSlotXProvider },
 	{ kEobBaseInvSlotY, kEobBaseInvSlotYProvider },
 	{ kEobBaseSlotValidationFlags, kEobBaseSlotValidationFlagsProvider },
+
+	{ kEobBaseProjectileWeaponTypes, kEobBaseProjectileWeaponTypesProvider },
+	{ kEobBaseWandTypes, kEobBaseWandTypesProvider },
+
 	{ kEobBaseDrawObjPosIndex, kEobBaseDrawObjPosIndexProvider },
 	{ kEobBaseFlightObjFlipIndex, kEobBaseFlightObjFlipIndexProvider },
 	{ kEobBaseFlightObjShpMap, kEobBaseFlightObjShpMapProvider },
@@ -3667,6 +3819,8 @@ const ExtractEntry extractProviders[] = {
 	{ kEob2Npc2Strings, kEob2Npc2StringsProvider },
 	{ kEob2MonsterDustStrings, kEob2MonsterDustStringsProvider },
 	{ kEob2DranFoolsStrings, kEob2DranFoolsStringsProvider },
+	{ kEob2HornStrings, kEob2HornStringsProvider },
+	{ kEob2HornSounds, kEob2HornSoundsProvider },
 	
 	{ kLolIngamePakFiles, kLolIngamePakFilesProvider },
 	{ kLolCharacterDefs, kLolCharacterDefsProvider },
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index 902d55c..cd51c0b 100644
Binary files a/dists/engine-data/kyra.dat and b/dists/engine-data/kyra.dat differ
diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
index 70031bf..a9051de 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -210,6 +210,20 @@ void EobEngine::drawDoorIntern(int type, int index, int x, int y, int w, int wal
 	}
 }
 
+bool EobEngine::checkPartyStatusExtra() {
+	_screen->copyPage(0, 10);
+	gui_drawBox(0, 121, 319, 200, _color2_1, _color1_1, _bkgColor_1);
+	_screen->setScreenDim(9);
+	_txt->printMessage(_menuStringsDefeat[0]);
+	while (!shouldQuit()) {
+		removeInputTop();
+		if (checkInput(0, false, 0) & 0xff)
+			break;
+	}
+	_screen->copyPage(10, 0);
+	return true;
+}
+
 uint32 EobEngine::convertSpellFlagToEob2Format(uint32 flag, int ignoreInvisibility) {
 	uint32 res = 0;
 	if (flag & 0x01)
diff --git a/engines/kyra/eob1.h b/engines/kyra/eob1.h
index 8a959e9..3460ac7 100644
--- a/engines/kyra/eob1.h
+++ b/engines/kyra/eob1.h
@@ -85,6 +85,7 @@ private:
 	const uint8 *_doorSwitchCoords;
 
 	// Misc
+	bool checkPartyStatusExtra();
 	uint32 convertSpellFlagToEob2Format(uint32 flag, int ignoreInvisibility);
 	uint32 convertCharacterEffectFlagToEob2Format(uint32 flag);
 };
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index 1931572..c3169b1 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -350,9 +350,16 @@ bool DarkMoonEngine::restParty_extraAbortCondition() {
 	return true;
 }
 
-void DarkMoonEngine::checkPartyStatusExtra() {
+void DarkMoonEngine::useHorn(int charIndex, int weaponSlot) {
+	int v = _items[_characters[charIndex].inventory[weaponSlot]].value - 1;
+	_txt->printMessage(_hornStrings[v]);
+	snd_playSoundEffect(_hornSounds[v]);
+}
+
+bool DarkMoonEngine::checkPartyStatusExtra() {
 	if (checkScriptFlag(0x10))
 		seq_dranFools();
+	return _gui->confirmDialogue2(14, 67, 1);
 }
 
 void DarkMoonEngine::drawLightningColumn() {
diff --git a/engines/kyra/eob2.h b/engines/kyra/eob2.h
index 93a3518..e1c574a 100644
--- a/engines/kyra/eob2.h
+++ b/engines/kyra/eob2.h
@@ -120,11 +120,15 @@ private:
 	bool restParty_extraAbortCondition();
 
 	// misc
-	void checkPartyStatusExtra();
+	void useHorn(int charIndex, int weaponSlot);
+	bool checkPartyStatusExtra();
 	void drawLightningColumn();
 	int resurrectionSelectDialogue();
 	int charSelectDialogue();
 	void characterLevelGain(int charIndex);
+
+	const char *const *_hornStrings;
+	const uint8 *_hornSounds;
 };
 
 }	// End of namespace Kyra
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index bb3848e..07c1f07 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -469,9 +469,8 @@ bool EobCoreEngine::checkPartyStatus(bool handleDeath) {
 		return true;
 
 	gui_drawAllCharPortraitsWithStats();
-	checkPartyStatusExtra();
 
-	if (_gui->confirmDialogue2(14, 67, 1)) {
+	if (checkPartyStatusExtra()) {
 		_screen->setFont(Screen::FID_8_FNT);
 		gui_updateControls();
 		if (_gui->runLoadMenu(0, 0)) {
@@ -1436,7 +1435,7 @@ void EobCoreEngine::displayParchment(int id) {
 	restoreAfterDialogueSequence();
 }
 
-void EobCoreEngine::useSlotWeapon(int charIndex, int slotIndex, int item) {
+void EobCoreEngine::useSlotWeapon(int charIndex, int slotIndex, Item item) {
 	EobCharacter *c = &_characters[charIndex];
 	int tp = item ? _items[item].type : 0;
 
@@ -1454,7 +1453,7 @@ void EobCoreEngine::useSlotWeapon(int charIndex, int slotIndex, int item) {
 	} else if (ep == 2) {
 		inflict = thrownAttack(charIndex, slotIndex, item);
 	} else if (ep == 3) {
-		inflict = bowAttack(charIndex, item);
+		inflict = projectileWeaponAttack(charIndex, item);
 		gui_drawCharPortraitWithStats(charIndex);
 	}
 
@@ -1477,7 +1476,7 @@ void EobCoreEngine::useSlotWeapon(int charIndex, int slotIndex, int item) {
 	setCharEventTimer(charIndex, 18, inflict >= -2 ? slotIndex + 2 : slotIndex, 1);
 }
 
-int EobCoreEngine::closeDistanceAttack(int charIndex, int item) {
+int EobCoreEngine::closeDistanceAttack(int charIndex, Item item) {
 	if (charIndex > 1)
 		return -3;
 
@@ -1527,7 +1526,7 @@ int EobCoreEngine::closeDistanceAttack(int charIndex, int item) {
 	return 0;
 }
 
-int EobCoreEngine::thrownAttack(int charIndex, int slotIndex, int item) {
+int EobCoreEngine::thrownAttack(int charIndex, int slotIndex, Item item) {
 	int d = charIndex > 3 ? charIndex - 2 : charIndex;
 	if (!launchObject(charIndex, item, _currentBlock, _dropItemDirIndex[(_currentDirection << 2) + d], _currentDirection, _items[item].type))
 		return 0;
@@ -1539,7 +1538,42 @@ int EobCoreEngine::thrownAttack(int charIndex, int slotIndex, int item) {
 	return 0;
 }
 
-int EobCoreEngine::bowAttack(int charIndex, int item) {
+int EobCoreEngine::projectileWeaponAttack(int charIndex, Item item) {
+	int tp = _items[item].type;
+	int t = _projectileWeaponAmmoTypes[_flags.gameID == GI_EOB1 ? tp - 2 : tp];
+	Item ammoItem = 0;
+
+	if (t == 16) {
+		if (_characters[charIndex].inventory[0] && _items[_characters[charIndex].inventory[0]].type == 16)
+			SWAP(ammoItem, _characters[charIndex].inventory[0]);
+		else if (_characters[charIndex].inventory[1] && _items[_characters[charIndex].inventory[1]].type == 16)
+			SWAP(ammoItem, _characters[charIndex].inventory[1]);
+		else if (_characters[charIndex].inventory[16])
+			ammoItem = getQueuedItem(&_characters[charIndex].inventory[16], 0, -1);
+		
+	} else {
+		for (int i = 0; i < 27; i++) {
+			if (_items[_characters[charIndex].inventory[i]].type == t) {
+				SWAP(ammoItem, _characters[charIndex].inventory[i] );
+				if (i < 2)
+					gui_drawCharPortraitWithStats(charIndex);
+				break;
+			}
+		}
+	}
+
+	if (!ammoItem)
+		return -4;
+
+	int c = charIndex;
+	if (c > 3)
+		c -= 2;
+
+	if (launchObject(charIndex, ammoItem, _currentBlock, _dropItemDirIndex[(_currentDirection << 2) + c], _currentDirection, tp)) {
+		snd_playSoundEffect(tp == 7 ? 26 : 11);
+		_sceneUpdateRequired = true;
+	}
+
 	return 0;
 }
 
@@ -1773,9 +1807,9 @@ void EobCoreEngine::monsterCloseAttack(EobMonsterInPlay *m) {
 					}
 
 					_characters[c].inventory[slot] = 0;
-					_txt->printMessage(_itemExtraStrings[(_characters[c].raceSex & 1) ^ 1], -1, _characters[c].name);
+					_txt->printMessage(_ripItemStrings[(_characters[c].raceSex & 1) ^ 1], -1, _characters[c].name);
 					printFullItemName(itm);
-					_txt->printMessage(_itemExtraStrings[2]);
+					_txt->printMessage(_ripItemStrings[2]);
 				}
 				gui_drawCharPortraitWithStats(c);
 			}
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index db56951..39919ca 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -446,6 +446,8 @@ protected:
 	Item _lastUsedItem;
 
 	const uint16 *_slotValidationFlags;
+	const int8 *_projectileWeaponAmmoTypes;
+	const uint8 *_wandTypes;
 
 	EobFlyingObject *_flyingObjects;
 	const uint8 *_drawObjPosIndex;
@@ -758,8 +760,26 @@ protected:
 
 	const char *const *_pryDoorStrings;
 	const char *const *_warningStrings;
-	const char *const *_itemExtraStrings;
-	const char *const *_itemSuffixStrings;
+
+	const char *const *_ripItemStrings;
+	const char *const *_cursedString;
+	const char *const *_enchantedString;
+	const char *const *_magicObjectStrings;
+	const char *const *_magicObjectString5;
+	const char *const *_patternSuffix;
+	const char *const *_patternGrFix1;
+	const char *const *_patternGrFix2;
+	const char *const *_validateArmorString;
+	const char *const *_validateCursedString;
+	const char *const *_validateNoDropString;
+	const char *const *_potionStrings;
+	const char *const *_wandStrings;	
+	const char *const *_itemMisuseStrings;	
+	
+	const char *const *_suffixStringsRings;
+	const char *const *_suffixStringsPotions;
+	const char *const *_suffixStringsWands;
+
 	const char *const *_takenStrings;
 	const char *const *_potionEffectStrings;
 
@@ -782,7 +802,8 @@ protected:
 	// misc
 	void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false);
 	void displayParchment(int id);
-	virtual void checkPartyStatusExtra() {}
+	virtual void useHorn(int charIndex, int weaponSlot) {}
+	virtual bool checkPartyStatusExtra() = 0;
 
 	virtual void drawLightningColumn() {}
 	virtual int resurrectionSelectDialogue() { return -1; }
@@ -802,10 +823,10 @@ protected:
 	GUI_Eob *_gui;
 
 	// fight
-	void useSlotWeapon(int charIndex, int slotIndex, int item);
-	int closeDistanceAttack(int charIndex, int item);
-	int thrownAttack(int charIndex, int slotIndex, int item);
-	int bowAttack(int charIndex, int item);
+	void useSlotWeapon(int charIndex, int slotIndex, Item item);
+	int closeDistanceAttack(int charIndex, Item item);
+	int thrownAttack(int charIndex, int slotIndex, Item item);
+	int projectileWeaponAttack(int charIndex, Item item);
 
 	void inflictMonsterDamage(EobMonsterInPlay *m, int damage, bool giveExperience);
 	void calcAndInflictMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int b, int damageType);
@@ -844,6 +865,7 @@ protected:
 	void useMagicBookOrSymbol(int charIndex, int type);
 	void useMagicScroll(int charIndex, int type, int weaponSlot);
 	void usePotion(int charIndex, int weaponSlot);
+	void useWand(int charIndex, int weaponSlot);
 
 	void castSpell(int spell, int weaponSlot);
 	void removeCharacterEffect(int spell, int charIndex, int showWarning);
@@ -1015,6 +1037,7 @@ protected:
 	const char *const *_menuStringsRest4;
 	const char *const *_menuStringsDefeat;
 	const char *_errorSlotEmptyString;
+	const char *_errorSlotNoNameString;
 
 	const char *const *_menuStringsTransfer;
 	const char *const *_menuStringsSpec;
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index c13b4da..c797229 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -924,7 +924,10 @@ int EobCoreEngine::clickedWeaponSlot(Button *button) {
 	if (!testCharacter(button->arg, 1))
 		return 1;
 
-	static const uint8 sY[] = { 24, 24, 80, 80, 136, 136 };
+	// Fix this using the coordinates from gui_drawWeaponSlot().
+	// The coordinates used in the original are slightly wrong
+	// (most noticeable for characters 5 and 6).
+	static const uint8 sY[] = { 27, 27, 79, 79, 131, 131 };
 	int slot = sY[button->arg] > _mouseY ? 0 : 1;
 
 	if ((_gui->_flagsMouseLeft & 0x7f) == 1)
@@ -1298,19 +1301,17 @@ void EobCoreEngine::gui_processWeaponSlotClickLeft(int charIndex, int slotIndex)
 }
 
 void EobCoreEngine::gui_processWeaponSlotClickRight(int charIndex, int slotIndex) {
-	const char * const *strs = &_itemExtraStrings[_flags.gameID == GI_EOB1 ? 17 : (_flags.lang == Common::DE_DEU ? 26 : 22)];
-
 	if (!testCharacter(charIndex, 0x0d))
 		return;
 
-	uint16 itm = _characters[charIndex].inventory[slotIndex];
+	Item itm = _characters[charIndex].inventory[slotIndex];
 	int wslot = slotIndex < 2 ? slotIndex : -1;
 
 	if (slotIndex < 2 && (!validateWeaponSlotItem(charIndex, slotIndex) || (!_currentControlMode && (_characters[charIndex].disabledSlots & (1 << slotIndex)))))
 		return;
 
 	if (!itemUsableByCharacter(charIndex, itm))
-		_txt->printMessage(strs[0], -1, _characters[charIndex].name);
+		_txt->printMessage(_itemMisuseStrings[0], -1, _characters[charIndex].name);
 
 	if (!itm && slotIndex > 1)
 		return;
@@ -1323,7 +1324,7 @@ void EobCoreEngine::gui_processWeaponSlotClickRight(int charIndex, int slotIndex
 		case 0:
 		case 16:
 			// Item automatically used when worn
-			_txt->printMessage(strs[1]);
+			_txt->printMessage(_itemMisuseStrings[1]);
 			break;
 
 		case 1:
@@ -1340,7 +1341,7 @@ void EobCoreEngine::gui_processWeaponSlotClickRight(int charIndex, int slotIndex
 		case 13:
 		case 15:
 			// Item not used that way
-			_txt->printMessage(strs[2]);
+			_txt->printMessage(_itemMisuseStrings[2]);
 			break;
 
 		case 5:
@@ -1377,12 +1378,12 @@ void EobCoreEngine::gui_processWeaponSlotClickRight(int charIndex, int slotIndex
 			break;
 
 		case 18:
-			ep = ep;
+			useWand(charIndex, wslot);
 			break;
 
 		case 19:
 			// eob2 horn
-			ep = ep;
+			useHorn(charIndex, wslot);
 			break;
 
 		case 20:
@@ -1397,7 +1398,7 @@ void EobCoreEngine::gui_processWeaponSlotClickRight(int charIndex, int slotIndex
 			break;
 	}
 
-	if (ep == 1 && charIndex >= 2)
+	if (_flags.gameID == GI_EOB1 || (ep == 1 && charIndex >= 2))
 		return;
 
 	_lastUsedItem = itm;
@@ -3837,8 +3838,12 @@ const char *GUI_Eob::getMenuString(int id) {
 		return _vm->_menuStringsPoison[0];
 	else if (id >= 56)
 		return _vm->_menuStringsHead[id - 56];
-	else if (id >= 53)
-		return _vm->_menuStringsDrop2[id - 53];
+	else if (id == 55)
+		return _vm->_menuStringsDrop2[_vm->game() == GI_EOB1 ? 1 : 2];
+	else if (id == 54)
+		return _vm->_errorSlotNoNameString;
+	else if (id == 53)
+		return _vm->_menuStringsDrop2[0];
 	else if (id >= 48)
 		return _vm->_menuStringsScribe[id - 48];
 	else if (id == 47)
diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
index 6c331e8..de5fe6b 100644
--- a/engines/kyra/items_eob.cpp
+++ b/engines/kyra/items_eob.cpp
@@ -192,10 +192,8 @@ int EobCoreEngine::validateInventorySlotForItem(Item item, int charIndex, int sl
 	if (item < 0)
 		return 0;
 
-	int offset = (_flags.gameID == GI_EOB1) ? 11 : (_flags.lang == Common::DE_DEU ? 16 : 12);
-
 	if (slot == 17 && item && !itemUsableByCharacter(charIndex, item)) {
-		_txt->printMessage(_itemExtraStrings[offset], -1, _characters[charIndex].name);
+		_txt->printMessage(_validateArmorString[0], -1, _characters[charIndex].name);
 		return 0;
 	}
 
@@ -203,7 +201,8 @@ int EobCoreEngine::validateInventorySlotForItem(Item item, int charIndex, int sl
 	int ex = _itemTypes[_items[itm].type].extraProperties & 0x7f;
 
 	if (slot < 2 && _items[itm].flags & 0x20 && ex > 0 && ex < 4) {
-		_txt->printMessage(_itemExtraStrings[offset + 1], -1, _characters[charIndex].name);
+		if (_flags.gameID == GI_EOB2)
+			_txt->printMessage(_validateCursedString[0], -1, _characters[charIndex].name);
 		return 0;
 	}
 
@@ -211,7 +210,7 @@ int EobCoreEngine::validateInventorySlotForItem(Item item, int charIndex, int sl
 	if (v & _slotValidationFlags[slot])
 		return 1;
 
-	_txt->printMessage(_itemExtraStrings[offset + (_flags.gameID == GI_EOB1 ? 1 : 2)]);
+	_txt->printMessage(_validateNoDropString[0]);
 	return 0;
 }
 
@@ -317,7 +316,8 @@ void EobCoreEngine::printFullItemName(Item item) {
 	
 	const char *tstr2 = 0;
 	const char *tstr3 = 0;
-	int e = 0;
+	
+	bool correctSuffixCase = false;
 
 	Common::String tmpString;
 
@@ -330,43 +330,46 @@ void EobCoreEngine::printFullItemName(Item item) {
 				if (v == 0)
 					tmpString = nameUnid;
 				else if (v < 0)
-					tmpString = Common::String::format(_itemExtraStrings[3], v, nameUnid);
+					tmpString = Common::String::format(_cursedString[0], v, nameUnid);
 				else
-					tmpString = Common::String::format(_itemExtraStrings[4], v, nameUnid);
+					tmpString = Common::String::format(_enchantedString[0], v, nameUnid);
 				break;
 
 			case 9:
-				tstr2 = _itemExtraStrings[5];
+				tstr2 = _magicObjectStrings[0];
 				tstr3 = _spells[v].name;
-				e = 1;
+				correctSuffixCase = true;
 				break;
 
 			case 10:
-				tstr2 = _itemExtraStrings[6];
+				tstr2 = _magicObjectStrings[1];
 				tstr3 = _spells[_flags.gameID == GI_EOB1 ? (_clericSpellOffset + v) : v].name;
-				e = 1;
+				correctSuffixCase = true;
 				break;
 
 			case 14:
-				tstr2 = _itemExtraStrings[8];
-				tstr3 = _itemSuffixStrings[8];
+				tstr2 = _magicObjectStrings[3];
+				if (_flags.gameID == GI_EOB1)
+					v--;
+				tstr3 = _suffixStringsPotions[v];
 				break;
 
 			case 16:
-				tstr2 = _itemExtraStrings[7];
-				tstr3 = _itemSuffixStrings[v + 6];
-				e = 0;
+				tstr2 = _magicObjectStrings[2];
+				tstr3 = _suffixStringsRings[v];
 				break;
 
 			case 18:
-				if (v == 5) {
-					tstr2 = _itemExtraStrings[_flags.lang == Common::EN_ANY ? 9 : 10];
-					e = 1;
+				if (_flags.gameID == GI_EOB2 && v == 5) {
+					if (_flags.lang == Common::DE_DEU)
+						tstr2 = _magicObjectString5[0];
+					else
+						tstr3 = _magicObjectString5[0];
+					correctSuffixCase = true;
 				} else {
-					tstr2 = _itemExtraStrings[9];
-					e = 0;
+					tstr2 = _magicObjectStrings[4];
 				}
-				tstr3 = _itemSuffixStrings[v + (_flags.lang == Common::EN_ANY ? 11 : 15)];
+				tstr3 = _suffixStringsWands[v];
 				break;
 
 			default:
@@ -377,15 +380,15 @@ void EobCoreEngine::printFullItemName(Item item) {
 
 		if (tstr3) {
 			if (!tstr2) {
-				tmpString = Common::String::format(_itemExtraStrings[_flags.lang == Common::EN_ANY ? 10 : 11], tstr3);
+				tmpString = tstr3;
 			} else {
-				if (e == 1) {
-					if (tstr2 == _itemExtraStrings[12])
-						tmpString = Common::String::format(_itemExtraStrings[_flags.lang == Common::EN_ANY ? 11 : 14], tstr2, tstr3);
+				if (correctSuffixCase) {
+					if (tstr2 == _magicObjectString5[0])
+						tmpString = Common::String::format(_patternGrFix2[0], tstr2, tstr3);
 					else
-						tmpString = Common::String::format(_itemExtraStrings[_flags.gameID == GI_EOB1 ? 10 : (_flags.lang == Common::EN_ANY ? 11 : 13)], tstr2, tstr3);
+						tmpString = Common::String::format(_patternGrFix1[0], tstr2, tstr3);
 				} else {
-					tmpString = Common::String::format(_itemExtraStrings[_flags.gameID == GI_EOB1 ? 10 : (_flags.lang == Common::EN_ANY ? 11 : 15)], tstr2, tstr3);
+					tmpString = Common::String::format(_patternSuffix[0], tstr2, tstr3);
 				}
 			}
 		}
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 2275bd5..593ef63 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -76,7 +76,6 @@ void EobCoreEngine::useMagicScroll(int charIndex, int type, int weaponSlot) {
 
 void EobCoreEngine::usePotion(int charIndex, int weaponSlot) {
 	EobCharacter *c = &_characters[_openBookChar];
-	int offset = (_flags.gameID == GI_EOB1) ? 13 : (_flags.lang == Common::DE_DEU ? 19 : 15);
 
 	int val = deleteInventoryItem(charIndex, weaponSlot);
 	snd_playSoundEffect(10);
@@ -100,7 +99,7 @@ void EobCoreEngine::usePotion(int charIndex, int weaponSlot) {
 		break;
 
 	case 3:
-		statusAttack(charIndex, 2, _itemExtraStrings[offset], 0, 1, 8, 1);
+		statusAttack(charIndex, 2, _potionStrings[0], 0, 1, 8, 1);
 		c->effectFlags &= ~0x2000;
 		if (c->flags & 2)
 			return;
@@ -136,7 +135,37 @@ void EobCoreEngine::usePotion(int charIndex, int weaponSlot) {
 		break;
 	}
 
-	_txt->printMessage(_itemExtraStrings[offset + 1], -1, c->name, _potionEffectStrings[val]);
+	_txt->printMessage(_potionStrings[1], -1, c->name, _potionEffectStrings[val]);
+}
+
+void EobCoreEngine::useWand(int charIndex, int weaponSlot) {
+	int v = _items[_characters[charIndex].inventory[weaponSlot]].value - 1;
+	if (!v) {
+		_txt->printMessage(_wandStrings[0]);
+		return;
+	}
+
+	if (v != 5)
+		useMagicScroll(charIndex, _wandTypes[v], weaponSlot);
+	else if (_flags.gameID == GI_EOB2)
+		useMagicScroll(charIndex, 64, weaponSlot);
+	else {
+		uint16 bl1 = calcNewBlockPosition(_currentBlock, _currentDirection);
+		uint16 bl2 = calcNewBlockPosition(bl1, _currentDirection);
+		snd_playSoundEffect(98);
+		sparkEffectOffensive();
+		
+		if ((_wllWallFlags[_levelBlockProperties[bl2].walls[_currentDirection ^ 2]] & 4) && !(_levelBlockProperties[bl2].flags & 7) && (_levelBlockProperties[bl1].flags & 7)) {
+			for (int i = 0; i < 30; i++) {
+				if (_monsters[i].block != bl1)
+					continue;
+				placeMonster(&_monsters[i], bl2, -1);
+				_sceneUpdateRequired = true;
+			}
+		} else {
+			_txt->printMessage(_wandStrings[1]);
+		}
+	}
 }
 
 void EobCoreEngine::castSpell(int spell, int weaponSlot) {
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 889865b..02ee384 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -287,8 +287,26 @@ enum KyraResources {
 
 	kEobBasePryDoorStrings,
 	kEobBaseWarningStrings,
-	kEobBaseItemSuffixStrings,
-	kEobBaseItemExtraStrings,
+
+	kEobBaseItemSuffixStringsRings,
+	kEobBaseItemSuffixStringsPotions,
+	kEobBaseItemSuffixStringsWands,
+	
+	kEobBaseRipItemStrings,
+	kEobBaseCursedString,
+	kEobBaseEnchantedString,
+	kEobBaseMagicObjectStrings,
+	kEobBaseMagicObjectString5,
+	kEobBasePatternSuffix,
+	kEobBasePatternGrFix1,
+	kEobBasePatternGrFix2,
+	kEobBaseValidateArmorString,
+	kEobBaseValidateCursedString,
+	kEobBaseValidateNoDropString,
+	kEobBasePotionStrings,
+	kEobBaseWandStrings,
+	kEobBaseItemMisuseStrings,
+
 	kEobBaseTakenStrings,
 	kEobBasePotionEffectStrings,
 
@@ -406,6 +424,10 @@ enum KyraResources {
 	kEobBaseInvSlotX,
 	kEobBaseInvSlotY,
 	kEobBaseSlotValidationFlags,
+
+	kEobBaseProjectileWeaponTypes,
+	kEobBaseWandTypes,
+
 	kEobBaseDrawObjPosIndex,
 	kEobBaseFlightObjFlipIndex,
 	kEobBaseFlightObjShpMap,
@@ -547,6 +569,8 @@ enum KyraResources {
 	kEob2MonsterDustStrings,
 
 	kEob2DranFoolsStrings,
+	kEob2HornStrings,
+	kEob2HornSounds,
 
 	kLolIngamePakFiles,
 	kLolCharacterDefs,
diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp
index acc6135..c169a39 100644
--- a/engines/kyra/staticres.cpp
+++ b/engines/kyra/staticres.cpp
@@ -38,7 +38,7 @@
 
 namespace Kyra {
 
-#define RESFILE_VERSION 78
+#define RESFILE_VERSION 79
 
 namespace {
 bool checkKyraDat(Common::SeekableReadStream *file) {
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index f422d69..19e2512 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -354,8 +354,26 @@ void EobCoreEngine::initStaticResource() {
 
 	_pryDoorStrings = _staticres->loadStrings(kEobBasePryDoorStrings, temp);
 	_warningStrings = _staticres->loadStrings(kEobBaseWarningStrings, temp);
-	_itemSuffixStrings = _staticres->loadStrings(kEobBaseItemSuffixStrings, temp);
-	_itemExtraStrings = _staticres->loadStrings(kEobBaseItemExtraStrings, temp);
+
+	_suffixStringsRings = _staticres->loadStrings(kEobBaseItemSuffixStringsRings, temp);
+	_suffixStringsPotions = _staticres->loadStrings(kEobBaseItemSuffixStringsPotions, temp);
+	_suffixStringsWands = _staticres->loadStrings(kEobBaseItemSuffixStringsWands, temp);
+
+	_ripItemStrings = _staticres->loadStrings(kEobBaseRipItemStrings, temp);
+	_cursedString = _staticres->loadStrings(kEobBaseCursedString, temp);
+	_enchantedString = _staticres->loadStrings(kEobBaseEnchantedString, temp);
+	_magicObjectStrings = _staticres->loadStrings(kEobBaseMagicObjectStrings, temp);
+	_magicObjectString5 = _staticres->loadStrings(kEobBaseMagicObjectString5, temp);
+	_patternSuffix = _staticres->loadStrings(kEobBasePatternSuffix, temp);
+	_patternGrFix1 = _staticres->loadStrings(kEobBasePatternGrFix1, temp);
+	_patternGrFix2 = _staticres->loadStrings(kEobBasePatternGrFix2, temp);
+	_validateArmorString = _staticres->loadStrings(kEobBaseValidateArmorString, temp);
+	_validateCursedString = _staticres->loadStrings(kEobBaseValidateCursedString, temp);
+	_validateNoDropString = _staticres->loadStrings(kEobBaseValidateNoDropString, temp);
+	_potionStrings = _staticres->loadStrings(kEobBasePotionStrings, temp);
+	_wandStrings = _staticres->loadStrings(kEobBaseWandStrings, temp);
+	_itemMisuseStrings = _staticres->loadStrings(kEobBaseItemMisuseStrings, temp);
+	
 	_takenStrings = _staticres->loadStrings(kEobBaseTakenStrings, temp);
 	_potionEffectStrings = _staticres->loadStrings(kEobBasePotionEffectStrings, temp);
 
@@ -455,6 +473,9 @@ void EobCoreEngine::initStaticResource() {
 	_inventorySlotsY = _staticres->loadRawData(kEobBaseInvSlotY, temp);
 	_slotValidationFlags = _staticres->loadRawDataBe16(kEobBaseSlotValidationFlags, temp);
 
+	_projectileWeaponAmmoTypes = (const int8*)_staticres->loadRawData(kEobBaseProjectileWeaponTypes, temp);
+	_wandTypes = _staticres->loadRawData(kEobBaseWandTypes, temp);
+
 	_drawObjPosIndex = _staticres->loadRawData(kEobBaseDrawObjPosIndex, temp);
 	_flightObjFlipIndex = _staticres->loadRawData(kEobBaseFlightObjFlipIndex, temp);
 	_flightObjShpMap = (const int8*)_staticres->loadRawData(kEobBaseFlightObjShpMap, temp);
@@ -508,8 +529,10 @@ void EobCoreEngine::initStaticResource() {
 	_sparkEffectOfY = _staticres->loadRawData(kEobBaseSparkOfY, temp);
 	_magicFlightObjectProperties = _staticres->loadRawData(kEobBaseMagicFlightProps, temp);
 
-	// Hard code these strings, since EOB 1 doesn't have them in the original
-	// (because there is only one single save slot)
+	// Hard code the following strings, since EOB I doesn't have them in the original.
+	// EOB I doesn't have load and save menus, because there is only one single
+	// save slot. Instead of emulating this we provide a menu similiar to EOB II.
+
 	static const char *saveLoadStrings[3][4] = {
 		{	"Cancel",	"Empty Slot",	"Save Game",	"Load Game"		},
 		{	"Abbr.",	"Leerer Slot",	"Speichern",	"  Laden"		},
@@ -521,9 +544,16 @@ void EobCoreEngine::initStaticResource() {
 		"Hier ist noch kein\rSpiel gespeichert!",
 		0
 	};
+
+	static const char *errorSlotNoNameString[3] = {
+		" You must specify\r a name for your\r save game!",
+		" Spielstände müssen\r einen Namen haben!",
+		0
+	};
 	
 	_saveLoadStrings = saveLoadStrings[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
 	_errorSlotEmptyString = errorSlotEmptyString[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
+	_errorSlotNoNameString = errorSlotNoNameString[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
 }
 
 void EobCoreEngine::initButtonData() {
@@ -1192,6 +1222,8 @@ void DarkMoonEngine::initStaticResource() {
 	_npc2Strings = _staticres->loadStrings(kEob2Npc2Strings, temp);
 	_monsterDustStrings = _staticres->loadStrings(kEob2MonsterDustStrings, temp);
 	_dranFoolsStrings = _staticres->loadStrings(kEob2DranFoolsStrings, temp);
+	_hornStrings = _staticres->loadStrings(kEob2HornStrings, temp);
+	_hornSounds = _staticres->loadRawData(kEob2HornSounds, temp);
 }
 
 void DarkMoonEngine::initSpells() {


Commit: 84900e8e50df8490fbdebc3acb25a338949f2de9
    https://github.com/scummvm/scummvm/commit/84900e8e50df8490fbdebc3acb25a338949f2de9
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:13-08:00

Commit Message:
KYRA: (EOB) - add turn undead spell, add some screen fades, fix some bugs

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    dists/engine-data/kyra.dat
    engines/kyra/eob1.cpp
    engines/kyra/eob1.h
    engines/kyra/eob2.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/magic_eob.cpp
    engines/kyra/resource.h
    engines/kyra/saveload_eob.cpp
    engines/kyra/scene_eob.cpp
    engines/kyra/script_eob.cpp
    engines/kyra/sprites_eob.cpp
    engines/kyra/staticres_eob.cpp
    engines/kyra/text_eob.cpp
    engines/kyra/timer_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index 9f749f0..276564b 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -395,6 +395,7 @@ const ExtractFilename extractFilenames[] = {
 	{ kEobBaseSparkOfY, kTypeRawData, false },
 	{ kEobBaseSpellProperties, kTypeRawData, false },
 	{ kEobBaseMagicFlightProps, kTypeRawData, false },
+	{ kEobBaseTurnUndeadEffect, kTypeRawData, false },
 
 	// EYE OF THE BEHOLDER I
 	{ kEob1MainMenuStrings, kTypeStringList, true },
@@ -406,6 +407,7 @@ const ExtractFilename extractFilenames[] = {
 	{ kEob1MonsterDistAttSfx10, kTypeRawData, false },
 	{ kEob1MonsterDistAttType17, kTypeRawData, false },
 	{ kEob1MonsterDistAttSfx17, kTypeRawData, false },
+	{ kEob1TurnUndeadString, kTypeStringList, true },
 
 	// EYE OF THE BEHOLDER II
 	{ kEob2MainMenuStrings, kTypeStringList, true },
@@ -1602,6 +1604,8 @@ const char *getIdString(const int id) {
 		return "kEobBaseSpellProperties";
 	case kEobBaseMagicFlightProps:
 		return "kEobBaseMagicFlightProps";
+	case kEobBaseTurnUndeadEffect:
+		return "kEobBaseTurnUndeadEffect";
 	case kEob1MainMenuStrings:
 		return "kEob1MainMenuStrings";
 	case kEob1DoorShapeDefs:
@@ -1618,6 +1622,8 @@ const char *getIdString(const int id) {
 		return "kEob1MonsterDistAttType17";
 	case kEob1MonsterDistAttSfx17:
 		return "kEob1MonsterDistAttSfx17";
+	case kEob1TurnUndeadString:
+		return "kEob1TurnUndeadString";
 	case kEob2MainMenuStrings:
 		return "kEob2MainMenuStrings";
 	case kEob2IntroStrings:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index 598050d..a587147 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -396,6 +396,7 @@ enum kExtractID {
 
 	kEobBaseSpellProperties,
 	kEobBaseMagicFlightProps,
+	kEobBaseTurnUndeadEffect,
 
 	kEob1MainMenuStrings,
 	kEob1DoorShapeDefs,
@@ -407,6 +408,7 @@ enum kExtractID {
 	kEob1MonsterDistAttSfx10,
 	kEob1MonsterDistAttType17,
 	kEob1MonsterDistAttSfx17,
+	kEob1TurnUndeadString,
 
 	kEob2MainMenuStrings,
 	kEob2IntroStrings,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 0496acc..4ab1202 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1063,6 +1063,7 @@ const int eob1FloppyNeed[] = {
 	kEob1MonsterDistAttSfx10,
 	kEob1MonsterDistAttType17,
 	kEob1MonsterDistAttSfx17,
+	kEob1TurnUndeadString,
 
 	kEobBasePryDoorStrings,
 	kEobBaseWarningStrings,
@@ -1077,6 +1078,8 @@ const int eob1FloppyNeed[] = {
 	kEobBaseMagicObjectStrings,
 	kEobBaseMagicObject5String,
 	kEobBasePatternSuffix,
+	kEobBasePatternGrFix1,
+	kEobBasePatternGrFix2,
 	kEobBaseValidateArmorString,
 	kEobBaseValidateNoDropString,
 	kEobBasePotionStrings,
@@ -1169,6 +1172,7 @@ const int eob1FloppyNeed[] = {
 
 	kEobBaseSpellProperties,
 	kEobBaseMagicFlightProps,
+	kEobBaseTurnUndeadEffect,
 
 	kLolEobCommonDscDoorShapeIndex,
 	kEobBaseWllFlagPreset,
@@ -1382,6 +1386,7 @@ const int eob2FloppyNeed[] = {
 
 	kEobBaseSpellProperties,
 	kEobBaseMagicFlightProps,
+	kEobBaseTurnUndeadEffect,
 
 	kLolEobCommonDscDoorShapeIndex,
 	kEobBaseWllFlagPreset,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index c45b3d4..46239c2 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -2089,8 +2089,7 @@ const ExtractEntrySearchData kEobBaseSlotValidationFlagsProvider[] = {
 };
 
 const ExtractEntrySearchData kEobBaseProjectileWeaponTypesProvider[] = {
-	{ UNK_LANG, kPlatformPC, { 0x0000000D, 0x0000063E, { { 0xA6, 0x75, 0x6C, 0x39, 0x96, 0xCB, 0xA7, 0xC2, 0x31, 0xE0, 0x2A, 0x75, 0x30, 0x96, 0x58, 0x05 } } } }, // EOB 1
-	{ UNK_LANG, kPlatformPC, { 0x0000000C, 0x0000063E, { { 0x3E, 0x99, 0x6D, 0xE4, 0x6B, 0xC8, 0x49, 0x1B, 0x17, 0xD2, 0xBE, 0x9B, 0xE0, 0xCD, 0xA1, 0xC2 } } } }, // EOB 1
+	{ UNK_LANG, kPlatformPC, { 0x00000008, 0x0000061C, { { 0x05, 0x55, 0xA6, 0xD1, 0x3C, 0x12, 0x84, 0xDA, 0xA9, 0x33, 0xCF, 0x07, 0x05, 0x2A, 0xB2, 0x29 } } } }, // EOB 1
 	{ UNK_LANG, kPlatformPC, { 0x0000000F, 0x00000829, { { 0x9F, 0x6A, 0x13, 0x8A, 0xA7, 0x40, 0xE8, 0x40, 0x2E, 0x87, 0x49, 0x6B, 0x67, 0xED, 0xE8, 0xCE } } } }, // EOB 2
 	EXTRACT_END_ENTRY
 };
@@ -2310,6 +2309,12 @@ const ExtractEntrySearchData kEobBaseMagicFlightPropsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEobBaseTurnUndeadEffectProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000008C, 0x00002E8B, { { 0x96, 0x15, 0x61, 0x12, 0x43, 0xCF, 0x3A, 0x84, 0x1A, 0x89, 0xB5, 0x32, 0x0D, 0xB3, 0x20, 0x67 } } } },
+
+	EXTRACT_END_ENTRY
+};
+
 const ExtractEntrySearchData kEob1MainMenuStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000037, 0x00000D79, { { 0x1D, 0x72, 0x7F, 0x8F, 0xEB, 0x4A, 0xBF, 0x82, 0xB7, 0xB5, 0x9D, 0xB0, 0x7B, 0xDA, 0xEC, 0xEE } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000034, 0x00000C6F, { { 0xF2, 0x5F, 0xBE, 0xFB, 0x27, 0x1C, 0x91, 0x33, 0x25, 0x09, 0xC1, 0xA0, 0x27, 0x89, 0xD7, 0xD5 } } } },
@@ -2356,6 +2361,14 @@ const ExtractEntrySearchData kEob1MonsterDistAttSfx17Provider[] = {
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEob1TurnUndeadStringProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000027, 0x00000BF2, { { 0x43, 0x0A, 0x1E, 0xEE, 0x84, 0xD6, 0xD6, 0x87, 0x20, 0x9F, 0x15, 0x22, 0x9B, 0x65, 0x24, 0xDB } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000030, 0x00000F48, { { 0xDA, 0x59, 0xEC, 0xC1, 0x9B, 0xCF, 0x90, 0x4A, 0x93, 0x3E, 0xE5, 0x26, 0x20, 0x8B, 0x74, 0x92 } } } },
+
+	EXTRACT_END_ENTRY
+};
+
+
 const ExtractEntrySearchData kEob2MainMenuStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000005F, 0x000017BE, { { 0x77, 0x8A, 0x50, 0x9F, 0x42, 0xD8, 0x00, 0x05, 0x60, 0x2A, 0x80, 0x25, 0x00, 0xDC, 0x7C, 0x92 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000005E, 0x000017F3, { { 0xD0, 0x93, 0x2E, 0x5F, 0x9D, 0xDB, 0xC4, 0xFB, 0x9E, 0x9F, 0x14, 0xD6, 0xB4, 0xBE, 0x3D, 0x0C } } } },
@@ -3698,6 +3711,7 @@ const ExtractEntry extractProviders[] = {
 
 	{ kEobBaseSpellProperties, kEobBaseSpellPropertiesProvider },
 	{ kEobBaseMagicFlightProps, kEobBaseMagicFlightPropsProvider },
+	{ kEobBaseTurnUndeadEffect, kEobBaseTurnUndeadEffectProvider },
 
 	{ kEob1MainMenuStrings, kEob1MainMenuStringsProvider },
 	{ kEob1DoorShapeDefs, kEob1DoorShapeDefsProvider },
@@ -3709,6 +3723,7 @@ const ExtractEntry extractProviders[] = {
 	{ kEob1MonsterDistAttSfx10, kEob1MonsterDistAttSfx10Provider },
 	{ kEob1MonsterDistAttType17, kEob1MonsterDistAttType17Provider },
 	{ kEob1MonsterDistAttSfx17, kEob1MonsterDistAttSfx17Provider },
+	{ kEob1TurnUndeadString, kEob1TurnUndeadStringProvider },
 
 	{ kEob2MainMenuStrings, kEob2MainMenuStringsProvider },
 	{ kEob2IntroStrings, kEob2IntroStringsProvider },
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index cd51c0b..2128a44 100644
Binary files a/dists/engine-data/kyra.dat and b/dists/engine-data/kyra.dat differ
diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
index a9051de..d12283f 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -83,7 +83,7 @@ void EobEngine::startupLoad() {
 }
 
 void EobEngine::npcSequence(int npcIndex) {
-
+	error("EobEngine::npcSequence(): unimplemented");
 
 }
 
@@ -210,10 +210,54 @@ void EobEngine::drawDoorIntern(int type, int index, int x, int y, int w, int wal
 	}
 }
 
+void EobEngine::turnUndeadAuto() {
+	if (_currentLevel != 2 && _currentLevel != 7)
+		return;
+
+	int oc = _openBookChar;
+
+	for (int i = 0; i < 6; i++) {
+		if (!testCharacter(i, 0x0d))
+			continue;
+		
+		EobCharacter *c = &_characters[i];
+
+		if (_itemTypes[_items[c->inventory[0]].type].extraProperties != 6 && _itemTypes[_items[c->inventory[1]].type].extraProperties != 6)
+			continue;
+
+		int l = getCharacterLevelIndex(2, c->cClass);
+		if (l > -1) {
+			if (c->level[l] > _openBookCasterLevel) {
+				_openBookCasterLevel = c->level[l];
+				_openBookChar = i;
+			}
+		} else {
+			l = getCharacterLevelIndex(4, c->cClass);
+			if (l > -1) {
+				if ((c->level[l] - 2) > _openBookCasterLevel) {
+					_openBookCasterLevel = (c->level[l] - 2);
+					_openBookChar = i;
+				}
+			}
+		}
+	}
+
+	if (_openBookCasterLevel)
+		spellCallback_start_turnUndead();
+
+	_openBookChar = oc;
+	_openBookCasterLevel = 0;
+}
+
+void EobEngine::turnUndeadAutoHit() {
+	_txt->printMessage(_turnUndeadString[0], -1, _characters[_openBookChar].name);
+	sparkEffectOffensive();
+}
+
 bool EobEngine::checkPartyStatusExtra() {
 	_screen->copyPage(0, 10);
-	gui_drawBox(0, 121, 319, 200, _color2_1, _color1_1, _bkgColor_1);
-	_screen->setScreenDim(9);
+	gui_drawBox(0, 121, 320, 80, _color1_1, _color2_1, _bkgColor_1);
+	_txt->setupField(9, false);
 	_txt->printMessage(_menuStringsDefeat[0]);
 	while (!shouldQuit()) {
 		removeInputTop();
@@ -221,6 +265,7 @@ bool EobEngine::checkPartyStatusExtra() {
 			break;
 	}
 	_screen->copyPage(10, 0);
+	_eventList.clear();
 	return true;
 }
 
diff --git a/engines/kyra/eob1.h b/engines/kyra/eob1.h
index 3460ac7..8d41118 100644
--- a/engines/kyra/eob1.h
+++ b/engines/kyra/eob1.h
@@ -84,6 +84,12 @@ private:
 	const uint8 *_doorSwitchShapeEncodeDefs;
 	const uint8 *_doorSwitchCoords;
 
+	// Magic
+	void turnUndeadAuto();
+	void turnUndeadAutoHit();
+
+	const char * const *_turnUndeadString;
+
 	// Misc
 	bool checkPartyStatusExtra();
 	uint32 convertSpellFlagToEob2Format(uint32 flag, int ignoreInvisibility);
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index c3169b1..cd30686 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -338,7 +338,7 @@ void DarkMoonEngine::drawDoorIntern(int type, int, int x, int y, int w, int wall
 }
 
 void DarkMoonEngine::restParty_npc() {
-
+	warning("DarkMoonEngine::restParty_npc(): implement!");
 }
 
 bool DarkMoonEngine::restParty_extraAbortCondition() {
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 07c1f07..22c0519 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -46,6 +46,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_playFinale = false;
 	_runFlag = true;
 	_configMouse = true;
+	_loading = false;
 
 	_largeItemShapes = _smallItemShapes = _thrownItemShapes = _spellShapes = _firebeamShapes = _itemIconShapes =
 		_wallOfForceShapes = _teleporterShapes = _sparkShapes = _compassShapes = 0;
@@ -82,7 +83,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_monsterOvl1 = _monsterOvl2 = 0;
 	_monsters = 0;
 	_dstMonsterIndex = 0;
-	_inflictMonsterDamageUnk = 0;
+	_preventMonsterFlash = false;
 
 	_teleporterPulse = 0;
 
@@ -124,7 +125,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_openBookSpellLevel = 0;
 	_openBookSpellSelectedItem = 0;
 	_openBookSpellListOffset = 0;
-	_openBookChar = _openBookCharBackup = 0;
+	_openBookChar = _openBookCharBackup = _openBookCasterLevel = 0;
 	_openBookType = _openBookTypeBackup = 0;
 	_openBookSpellList = 0;
 	_openBookAvailableSpells = 0;
@@ -415,7 +416,7 @@ void EobCoreEngine::writeSettings() {
 void EobCoreEngine::startupNew() {
 	gui_setPlayFieldButtons();
 	_screen->_curPage = 0;
-	gui_drawPlayField(0);
+	gui_drawPlayField(false);
 	_screen->_curPage = 0;
 	gui_drawAllCharPortraitsWithStats();
 	drawScene(1);
@@ -452,8 +453,7 @@ void EobCoreEngine::runLoop() {
 		_envAudioTimer = _system->getMillis() + (rollDice(1, 10, 3) * 18 * _tickLength);
 		snd_processEnvironmentalSoundEffect(_flags.gameID == GI_EOB1 ? 30 : (rollDice(1, 2, -1) ? 27 : 28), _currentBlock + rollDice(1, 12, -1));
 		updateEnvironmentalSfx(0);
-		//TODO
-		//EOB1__level_2_7__turnUndead();
+		turnUndeadAuto();
 	}
 }
 
@@ -1540,7 +1540,11 @@ int EobCoreEngine::thrownAttack(int charIndex, int slotIndex, Item item) {
 
 int EobCoreEngine::projectileWeaponAttack(int charIndex, Item item) {
 	int tp = _items[item].type;
-	int t = _projectileWeaponAmmoTypes[_flags.gameID == GI_EOB1 ? tp - 2 : tp];
+
+	if (_flags.gameID == GI_EOB1)
+		assert(tp >= 7);
+
+	int t = _projectileWeaponAmmoTypes[_flags.gameID == GI_EOB1 ? tp - 7 : tp];
 	Item ammoItem = 0;
 
 	if (t == 16) {
@@ -1588,7 +1592,7 @@ void EobCoreEngine::inflictMonsterDamage(EobMonsterInPlay *m, int damage, bool g
 	} else {
 		if (checkSceneUpdateNeed(m->block)) {
 			m->flags |= 2;
-			if (_inflictMonsterDamageUnk)
+			if (_preventMonsterFlash)
 				return;
 			flashMonsterShape(m);
 		}
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 39919ca..6463f83 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -406,6 +406,7 @@ protected:
 
 	const EobCharacter *_npcPreset;
 	bool _partyResting;
+	bool _loading;
 
 	// Items
 	void loadItemDefs();
@@ -634,7 +635,7 @@ protected:
 	uint8 _scriptTimersMode;
 
 	// Gui
-	void gui_drawPlayField(int pageNum);
+	void gui_drawPlayField(bool refresh);
 	void gui_restorePlayField();
 	void gui_drawAllCharPortraitsWithStats();
 	void gui_drawCharPortraitWithStats(int index);
@@ -858,7 +859,7 @@ protected:
 	void explodeMonster(EobMonsterInPlay *m);
 	
 	int _dstMonsterIndex;
-	int _inflictMonsterDamageUnk;
+	bool _preventMonsterFlash;
 	int16 _foundMonstersArray[5];
 
 	// magic
@@ -867,6 +868,9 @@ protected:
 	void usePotion(int charIndex, int weaponSlot);
 	void useWand(int charIndex, int weaponSlot);
 
+	virtual void turnUndeadAuto() {};
+	virtual void turnUndeadAutoHit() {};
+
 	void castSpell(int spell, int weaponSlot);
 	void removeCharacterEffect(int spell, int charIndex, int showWarning);
 	void removeAllCharacterEffects(int charIndex);
@@ -880,6 +884,7 @@ protected:
 
 	bool magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level);
 	bool magicObjectStatusHit(EobMonsterInPlay *m, int type, bool tryEvade, int mod);
+	bool turnUndeadHit(EobMonsterInPlay *m, int hitChance, int casterLevel);
 
 	void printWarning(const char* str);
 	void printNoEffectWarning();
@@ -958,6 +963,7 @@ protected:
 	uint8 _openBookType;
 	uint8 _openBookCharBackup;
 	uint8 _openBookTypeBackup;
+	uint8 _openBookCasterLevel;
 	const char *const *_openBookSpellList;
 	int8 *_openBookAvailableSpells;
 	uint8 _activeSpellCaster;
@@ -1011,6 +1017,7 @@ protected:
 	const uint8 *_sparkEffectOfY;
 
 	const uint8 *_magicFlightObjectProperties;
+	const uint8 *_turnUndeadEffect;
 
 	// Menu
 	EobMenuDef *_menuDefs;
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index c797229..ce5f3ea 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -149,17 +149,19 @@ Button *EobCoreEngine::gui_getButton(Button *buttonList, int index) {
 	return 0;
 }
 
-void EobCoreEngine::gui_drawPlayField(int pageNum) {
+void EobCoreEngine::gui_drawPlayField(bool refresh) {
 	_screen->loadEobCpsFileToPage("PLAYFLD", 0, 5, 3, 2);
 	int cp = _screen->setCurPage(2);
 	gui_drawCompass(true);
 
-	if (pageNum && !_sceneDrawPage2)
+	if (refresh && !_sceneDrawPage2)
 		drawScene(0);
 
 	_screen->setCurPage(cp);
 	_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
-	_screen->updateScreen();
+	
+	if (!_loading)
+		_screen->updateScreen();
 
 	_screen->loadEobCpsFileToPage("INVENT", 0, 5, 3, 2);
 }
@@ -167,7 +169,7 @@ void EobCoreEngine::gui_drawPlayField(int pageNum) {
 void EobCoreEngine::gui_restorePlayField() {
 	loadVcnData(0, 0);
 	_screen->_curPage = 0;
-	gui_drawPlayField(1);
+	gui_drawPlayField(true);
 	gui_drawAllCharPortraitsWithStats();
 }
 
@@ -706,7 +708,8 @@ void EobCoreEngine::gui_drawSpellbook() {
 
 	_screen->setCurPage(0);
 	_screen->copyRegion(64, 121, 64, 121, 112, 56, 2, 0, Screen::CR_NO_P_CHECK);
-	_screen->updateScreen();
+	if (!_loading)
+		_screen->updateScreen();
 }
 
 void EobCoreEngine::gui_drawSpellbookScrollArrow(int x, int y, int direction) {
@@ -2245,7 +2248,7 @@ void GUI_Eob::runCampMenu() {
 
 				if (cnt > 4) {
 					_vm->dropCharacter(selectCharacterDialogue(53));
-					_vm->gui_drawPlayField(0);
+					_vm->gui_drawPlayField(false);
 					res = true;
 					_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 14, Screen::CR_NO_P_CHECK);
 					_screen->setFont(Screen::FID_6_FNT);
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 593ef63..f828625 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -80,6 +80,9 @@ void EobCoreEngine::usePotion(int charIndex, int weaponSlot) {
 	int val = deleteInventoryItem(charIndex, weaponSlot);
 	snd_playSoundEffect(10);
 
+	if (_flags.gameID == GI_EOB1)
+		val--;
+
 	switch (val) {
 	case 0:
 		sparkEffectDefensive(charIndex);
@@ -496,7 +499,7 @@ bool EobCoreEngine::magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int d
 		level = 1;
 
 	if ((_levelBlockProperties[fo->curBlock].flags & 7) && (fo->attackerId >= 0 || ignoreAttackerId)) {
-		_inflictMonsterDamageUnk = 1;
+		_preventMonsterFlash = true;
 
 		for (const int16 *m = findBlockMonsters(fo->curBlock, fo->curPos, fo->direction, blockDamage, singleTargetCheckAdjacent); *m != -1; m++) {
 			int dmg = rollDice(dcTimes, dcPips, dcOffs) * level;
@@ -604,6 +607,23 @@ bool EobCoreEngine::magicObjectStatusHit(EobMonsterInPlay *m, int type, bool try
 	return true;
 }
 
+bool EobCoreEngine::turnUndeadHit(EobMonsterInPlay *m, int hitChance, int casterLevel) {
+	uint8 e = _turnUndeadEffect[_monsterProps[m->type].tuResist * 14 + MIN(casterLevel, 14)];
+
+	if (e == 0xff) {
+		calcAndInflictMonsterDamage(m, 0, 0, 500, 0x200, 5, 3);
+	} else if (hitChance < e) {
+		return false;
+	} else {
+		m->mode = 0;
+		m->flags |= 8;
+		m->spellStatusLeft = 40;
+		m->dir = (getNextMonsterDirection(m->block, _currentBlock) ^ 4) >> 1;	
+	}
+
+	return true;
+}
+
 void EobCoreEngine::printWarning(const char* str) {
 	_txt->printMessage(str);
 	snd_playSoundEffect(79);
@@ -900,11 +920,33 @@ void EobCoreEngine::spellCallback_start_heal() {
 }
 
 void EobCoreEngine::spellCallback_start_layOnHands() {
-
+	modifyCharacterHitpoints(_activeSpellCaster, _characters[_openBookChar].level[0] << 1);
 }
 
 void EobCoreEngine::spellCallback_start_turnUndead() {
+	uint16 bl = calcNewBlockPosition(_currentBlock, _currentDirection);
+	if (!(_levelBlockProperties[bl].flags & 7))
+		return;
+	
+	int cl = _openBookCasterLevel ? _openBookCasterLevel : getCharacterClericPaladinLevel(_openBookChar);
+	int r = rollDice(1, 20);
+	bool hit = false;
+
+	for (const int16 *m = findBlockMonsters(bl, 4, 4, 1, 1); *m != -1; m++) {		
+		if ((_monsterProps[_monsters[*m].type].typeFlags & 4) && !(_monsters[*m].flags & 0x10)) {
+			_preventMonsterFlash = true;
+			_monsters[*m].flags |= 0x10;
+			hit |= turnUndeadHit(&_monsters[*m], r, cl);
+		}
+	}
+
+	if (hit) {
+		turnUndeadAutoHit();
+		snd_playSoundEffect(95);
+		updateAllMonsterShapes();
+	}
 
+	_preventMonsterFlash = false;
 }
 
 bool EobCoreEngine::spellCallback_end_unk1Passive(EobFlyingObject *fo) {
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 02ee384..5328aef 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -469,6 +469,7 @@ enum KyraResources {
 
 	kEobBaseSpellProperties,
 	kEobBaseMagicFlightProps,
+	kEobBaseTurnUndeadEffect,
 
 	kEob1MainMenuStrings,
 	kEob1DoorShapeDefs,
@@ -481,6 +482,8 @@ enum KyraResources {
 	kEob1MonsterDistAttType17,
 	kEob1MonsterDistAttSfx17,
 
+	kEob1TurnUndeadString,
+
 	kEob2MainMenuStrings,
 	kEob2IntroStrings,
 	kEob2IntroCPSFiles,
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index 1fa26c2..43a230e 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -149,6 +149,8 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 		return Common::Error(Common::kReadingFailed);
 
 	Common::SeekableSubReadStreamEndian in(saveFile, saveFile->pos(), saveFile->size(), !header.originalSave, DisposeAfterUse::YES);
+	_loading = true;
+	_screen->fadeToBlack(10);
 
 	for (int i = 0; i < 6; i++) {
 		EobCharacter *c = &_characters[i];
@@ -356,7 +358,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 	_screen->setFont(Screen::FID_6_FNT);
 
 	_screen->setCurPage(0);
-	gui_drawPlayField(0);	
+	gui_drawPlayField(false);	
 
 	if (_currentControlMode)
 		_screen->copyRegion(176, 0, 0, 0, 144, 168, 0, 5, Screen::CR_NO_P_CHECK);
@@ -378,6 +380,9 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 	while (!_screen->isMouseVisible())
 		_screen->showMouse();
 
+	_loading = false;
+	_screen->fadeFromBlack(20);
+
 	return Common::kNoError;
 }
 
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index 36584d4..e6b3c26 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -997,7 +997,9 @@ void EobCoreEngine::drawScene(int refresh) {
 		if (refresh)
 			_screen->fillRect(0, 0, 176, 120, 12);
 
-		_screen->setScreenPalette(_screen->getPalette(0));
+		if (!_loading)
+			_screen->setScreenPalette(_screen->getPalette(0));
+
 		_sceneDrawPage2 = 0;
 	}
 
@@ -1025,7 +1027,7 @@ void EobCoreEngine::drawScene(int refresh) {
 	if (!_dialogueField && refresh && !_updateFlags)
 		gui_drawCompass(false);
 
-	if (refresh && !_partyResting)
+	if (refresh && !_partyResting && !_loading)
 		_screen->updateScreen();
 
 	if (_sceneDefaultUpdate) {
diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp
index 9e18a14..833413c 100644
--- a/engines/kyra/script_eob.cpp
+++ b/engines/kyra/script_eob.cpp
@@ -1397,12 +1397,12 @@ int EobInfProcessor::oeob_sequence(int8 *data) {
 
 	case -2:
 		// portal sequence
-		pos=pos;
+		error("EobInfProcessor::oeob_sequence(): unimplemented cmd -2");
 		break;
 
 	case -1:
 		// copy protection
-		pos=pos;
+		error("EobInfProcessor::oeob_sequence(): unimplemented cmd -1");
 		break;
 
 	default:
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index baa7a0b..0874de8 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -140,6 +140,12 @@ const uint8 *EobCoreEngine::loadActiveMonsterData(const uint8 *data, int level)
 		_timer->setCountdown(0x21 + (p << 1), v);
 	}
 
+	uint32 ct = _system->getMillis();
+	for (int i = 0x20; i < 0x24; i++) {
+		int32 del = _timer->getDelay(i);
+		_timer->setNextRun(i, (i & 1) ? ct + (del >> 1) : ct + del);
+	}
+
 	if (_hasTempDataFlags & (1 << (level - 1)))
 		return data + 420;
 
@@ -302,12 +308,12 @@ bool EobCoreEngine::isMonsterOnPos(EobMonsterInPlay *m, uint16 block, int pos, i
 
 const int16 *EobCoreEngine::findBlockMonsters(uint16 block, int pos, int dir, int blockDamage, int singleTargetCheckAdjacent) {
 	static const uint8 cpos4[] = { 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1 };
-	int checkPos4 = (pos <= 4) ? cpos4[(dir << 2) + pos] : 1;
+	int include4 = (pos < 4) ? cpos4[(dir << 2) + pos] : 1;
 	int16 *dst = _foundMonstersArray;
 
 	if (blockDamage) {
 		for (int i = 0; i < 30; i++) {
-			if (_monsters[i].block == block && (_monsters[i].pos != 4 || checkPos4))
+			if (_monsters[i].block == block && (_monsters[i].pos != 4 || include4))
 				*dst++ = i;
 		}
 
@@ -338,7 +344,7 @@ const int16 *EobCoreEngine::findBlockMonsters(uint16 block, int pos, int dir, in
 
 	} else {
 		for (int i = 0; i < 30; i++) {
-			if (isMonsterOnPos(&_monsters[i], block, pos, checkPos4))
+			if (isMonsterOnPos(&_monsters[i], block, pos, include4))
 				*dst++ = i;
 		}
 	}
@@ -395,7 +401,7 @@ void EobCoreEngine::updateAllMonsterShapes() {
 	} else {
 		_sceneUpdateRequired = false;
 	}
-	_inflictMonsterDamageUnk = 0;
+	_preventMonsterFlash = false;
 }
 
 void EobCoreEngine::drawBlockItems(int index) {
@@ -684,7 +690,6 @@ void EobCoreEngine::drawTeleporter(int index) {
 void EobCoreEngine::updateMonsters(int unit) {
 	for (int i = 0; i < 30; i++) {
 		EobMonsterInPlay *m = &_monsters[i];
-
 		if (m->unit == unit) {
 			if (m->hitPointsCur <= 0 || m->flags & 0x20)
 				continue;
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 19e2512..1cf78ee 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -528,6 +528,7 @@ void EobCoreEngine::initStaticResource() {
 	_sparkEffectOfX = _staticres->loadRawData(kEobBaseSparkOfX, temp);
 	_sparkEffectOfY = _staticres->loadRawData(kEobBaseSparkOfY, temp);
 	_magicFlightObjectProperties = _staticres->loadRawData(kEobBaseMagicFlightProps, temp);
+	_turnUndeadEffect = _staticres->loadRawData(kEobBaseTurnUndeadEffect, temp);
 
 	// Hard code the following strings, since EOB I doesn't have them in the original.
 	// EOB I doesn't have load and save menus, because there is only one single
@@ -1065,6 +1066,8 @@ void EobEngine::initStaticResource() {
 	_monsterDistAttType17 = _staticres->loadRawData(kEob1MonsterDistAttType17, temp);
 	_monsterDistAttSfx17 = _staticres->loadRawData(kEob1MonsterDistAttSfx17, temp);
 
+	_turnUndeadString = _staticres->loadStrings(kEob1TurnUndeadString, temp);
+
 	const uint8 *ps = _staticres->loadRawData(kEob1MonsterProperties, temp);
 	temp /= 27;
 	_monsterProps = new EobMonsterProperty[temp];
diff --git a/engines/kyra/text_eob.cpp b/engines/kyra/text_eob.cpp
index c350666..63d893d 100644
--- a/engines/kyra/text_eob.cpp
+++ b/engines/kyra/text_eob.cpp
@@ -70,8 +70,6 @@ void TextDisplayer_Eob::setupField(int dim, bool mode) {
 		clearCurDim();
 	else
 		resetDimTextPositions(dim);
-
-	//_textPageBreakFunc = textPageBreakMore; + 0x25
 }
 
 void TextDisplayer_Eob::resetDimTextPositions(int dim) {
diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp
index 903dec2..9e03bde 100644
--- a/engines/kyra/timer_eob.cpp
+++ b/engines/kyra/timer_eob.cpp
@@ -101,6 +101,7 @@ void EobCoreEngine::setupTimers() {
 	_timer->addTimer(0x21, TimerV2(timerProcessMonsters), 20, true);
 	_timer->addTimer(0x22, TimerV2(timerProcessMonsters), 20, true);
 	_timer->addTimer(0x23, TimerV2(timerProcessMonsters), 20, true);
+	_timer->setNextRun(0x20, _system->getMillis());
 	_timer->setNextRun(0x21, _system->getMillis() + 7 * _tickLength);
 	_timer->setNextRun(0x22, _system->getMillis() + 14 * _tickLength);
 	_timer->setNextRun(0x23, _system->getMillis() + 14 * _tickLength);
@@ -274,7 +275,6 @@ void EobCoreEngine::timerProcessMonsters(int timerNum) {
 	updateMonsters(timerNum & 0x0f);
 }
 
-
 void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
 	int charIndex = timerNum & 0x0f;
 	EobCharacter *c = &_characters[charIndex];
@@ -346,7 +346,8 @@ void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
 
 		case 12:
 			c->effectFlags &= ~0x1000;
-			_txt->printMessage(_characterStatusStrings12[0], -1, c->name);
+			if (_characterStatusStrings12)
+				_txt->printMessage(_characterStatusStrings12[0], -1, c->name);
 			break;
 
 		default:


Commit: 48f83b7bb48a1625f6c195e396f8d40047f50915
    https://github.com/scummvm/scummvm/commit/48f83b7bb48a1625f6c195e396f8d40047f50915
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:13-08:00

Commit Message:
KYRA: (EOB) - implement npc sequences and fix some bugs

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/extract.cpp
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    dists/engine-data/kyra.dat
    engines/kyra/eob1.cpp
    engines/kyra/eob1.h
    engines/kyra/eob2.cpp
    engines/kyra/eob2.h
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/gui_eob.h
    engines/kyra/items_eob.cpp
    engines/kyra/lol.cpp
    engines/kyra/loleobbase.cpp
    engines/kyra/loleobbase.h
    engines/kyra/magic_eob.cpp
    engines/kyra/resource.h
    engines/kyra/script_eob.cpp
    engines/kyra/script_eob.h
    engines/kyra/sprites_eob.cpp
    engines/kyra/staticres_eob.cpp
    engines/kyra/text_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index 276564b..68fc8cc 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -409,6 +409,22 @@ const ExtractFilename extractFilenames[] = {
 	{ kEob1MonsterDistAttSfx17, kTypeRawData, false },
 	{ kEob1TurnUndeadString, kTypeStringList, true },
 
+	{ kEob1NpcShpData, kTypeRawData, false },
+	{ kEob1NpcSubShpIndex1, kTypeRawData, false },
+	{ kEob1NpcSubShpIndex2, kTypeRawData, false },
+	{ kEob1NpcSubShpY, kTypeRawData, false },
+	{ kEob1Npc0Strings, kTypeStringList, true },
+	{ kEob1Npc11Strings, kTypeStringList, true },
+	{ kEob1Npc12Strings, kTypeStringList, true },
+	{ kEob1Npc21Strings, kTypeStringList, true },
+	{ kEob1Npc22Strings, kTypeStringList, true },
+	{ kEob1Npc31Strings, kTypeStringList, true },
+	{ kEob1Npc32Strings, kTypeStringList, true },
+	{ kEob1Npc4Strings, kTypeStringList, true },
+	{ kEob1Npc5Strings, kTypeStringList, true },
+	{ kEob1Npc6Strings, kTypeStringList, true },
+	{ kEob1Npc7Strings, kTypeStringList, true },
+
 	// EYE OF THE BEHOLDER II
 	{ kEob2MainMenuStrings, kTypeStringList, true },
 
@@ -1624,6 +1640,36 @@ const char *getIdString(const int id) {
 		return "kEob1MonsterDistAttSfx17";
 	case kEob1TurnUndeadString:
 		return "kEob1TurnUndeadString";
+	case kEob1NpcShpData:
+		return "kEob1NpcShpData";
+	case kEob1NpcSubShpIndex1:
+		return "kEob1NpcSubShpIndex1";
+	case kEob1NpcSubShpIndex2:
+		return "kEob1NpcSubShpIndex2";
+	case kEob1NpcSubShpY:
+		return "kEob1NpcSubShpY";
+	case kEob1Npc0Strings:
+		return "kEob1Npc0Strings";
+	case kEob1Npc11Strings:
+		return "kEob1Npc11Strings";
+	case kEob1Npc12Strings:
+		return "kEob1Npc12Strings";
+	case kEob1Npc21Strings:
+		return "kEob1Npc21Strings";
+	case kEob1Npc22Strings:
+		return "kEob1Npc22Strings";
+	case kEob1Npc31Strings:
+		return "kEob1Npc31Strings";
+	case kEob1Npc32Strings:
+		return "kEob1Npc32Strings";
+	case kEob1Npc4Strings:
+		return "kEob1Npc4Strings";
+	case kEob1Npc5Strings:
+		return "kEob1Npc5Strings";
+	case kEob1Npc6Strings:
+		return "kEob1Npc6Strings";
+	case kEob1Npc7Strings:
+		return "kEob1Npc7Strings";
 	case kEob2MainMenuStrings:
 		return "kEob2MainMenuStrings";
 	case kEob2IntroStrings:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index a587147..54fd91b 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -410,6 +410,22 @@ enum kExtractID {
 	kEob1MonsterDistAttSfx17,
 	kEob1TurnUndeadString,
 
+	kEob1NpcShpData,
+	kEob1NpcSubShpIndex1,
+	kEob1NpcSubShpIndex2,
+	kEob1NpcSubShpY,
+	kEob1Npc0Strings,
+	kEob1Npc11Strings,
+	kEob1Npc12Strings,
+	kEob1Npc21Strings,
+	kEob1Npc22Strings,
+	kEob1Npc31Strings,
+	kEob1Npc32Strings,
+	kEob1Npc4Strings,
+	kEob1Npc5Strings,
+	kEob1Npc6Strings,
+	kEob1Npc7Strings,
+
 	kEob2MainMenuStrings,
 	kEob2IntroStrings,
 	kEob2IntroCPSFiles,
diff --git a/devtools/create_kyradat/extract.cpp b/devtools/create_kyradat/extract.cpp
index c9ece82..b330c46 100644
--- a/devtools/create_kyradat/extract.cpp
+++ b/devtools/create_kyradat/extract.cpp
@@ -1114,7 +1114,7 @@ bool extractEobNpcData(PAKFile &out, const ExtractInformation *info, const byte
 			WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
 			src += 4; dst += 4;
 			// skipping lots of zero space
-			src += 60;
+			src += 64;
 			WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
 			src += 4; dst += 4;
 			for (int ii = 0; ii < 27; ii++) {
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 4ab1202..5f71050 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1065,6 +1065,22 @@ const int eob1FloppyNeed[] = {
 	kEob1MonsterDistAttSfx17,
 	kEob1TurnUndeadString,
 
+	kEob1NpcShpData,
+	kEob1NpcSubShpIndex1,
+	kEob1NpcSubShpIndex2,
+	kEob1NpcSubShpY,
+	kEob1Npc0Strings,
+	kEob1Npc11Strings,
+	kEob1Npc12Strings,
+	kEob1Npc21Strings,
+	kEob1Npc22Strings,
+	kEob1Npc31Strings,
+	kEob1Npc32Strings,
+	kEob1Npc4Strings,
+	kEob1Npc5Strings,
+	kEob1Npc6Strings,
+	kEob1Npc7Strings,
+
 	kEobBasePryDoorStrings,
 	kEobBaseWarningStrings,
 
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index 46239c2..663652d 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -2368,6 +2368,102 @@ const ExtractEntrySearchData kEob1TurnUndeadStringProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEob1NpcShpDataProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000004C, 0x00000A42, { { 0x70, 0x21, 0x85, 0x8C, 0xD4, 0x04, 0xAA, 0x20, 0x1D, 0x0E, 0x9D, 0xB7, 0x74, 0x58, 0xCC, 0x0C } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1NpcSubShpIndex1Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x00000035, { { 0x9A, 0x83, 0xF9, 0xA4, 0x27, 0xBA, 0xFC, 0xD2, 0xDE, 0x03, 0x65, 0xF2, 0xFA, 0x37, 0xDA, 0xF1 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1NpcSubShpIndex2Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x00000051, { { 0x7E, 0xAC, 0x0E, 0x54, 0x59, 0x5D, 0xF6, 0x53, 0x03, 0x22, 0x1D, 0xC7, 0xFC, 0x16, 0xC8, 0x88 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1NpcSubShpYProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x00000143, { { 0xC1, 0xED, 0x93, 0x5E, 0x84, 0xCE, 0x48, 0xCF, 0x4C, 0xF3, 0x9C, 0x93, 0xBF, 0xFE, 0xB8, 0x6F } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc0StringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000044, 0x000016E2, { { 0x7C, 0x28, 0x72, 0xC9, 0x57, 0xF5, 0xAB, 0x02, 0xD1, 0x42, 0xE8, 0xA3, 0xF9, 0x33, 0x70, 0xEE } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000050, 0x00001B13, { { 0x69, 0x05, 0xEB, 0xB6, 0x86, 0x81, 0xAC, 0x09, 0x53, 0x35, 0x4D, 0x55, 0xF3, 0x13, 0x6F, 0xC0 } } } },
+
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc11StringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000001B, 0x00000928, { { 0x86, 0x08, 0x95, 0x6B, 0xBF, 0x12, 0x2D, 0xF9, 0x62, 0x25, 0xD9, 0xAE, 0x25, 0x10, 0xDF, 0xDC } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x0000001A, 0x000008DB, { { 0xBD, 0xBB, 0x48, 0x8E, 0x04, 0x7D, 0xE4, 0x78, 0xBB, 0x59, 0x6E, 0x86, 0xE1, 0x06, 0x27, 0x50 } } } },
+
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc12StringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000016, 0x0000079C, { { 0x22, 0x57, 0x3A, 0x9C, 0x7C, 0xDB, 0x55, 0xD0, 0x9C, 0x84, 0x28, 0xA6, 0x9D, 0x40, 0x38, 0x6E } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000014, 0x000006ED, { { 0x88, 0x1C, 0x09, 0x61, 0x5D, 0x9D, 0xDE, 0x8A, 0x54, 0x1C, 0x40, 0xCF, 0x28, 0x2B, 0x52, 0x9D } } } },
+
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc21StringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000014, 0x000006FD, { { 0x55, 0x77, 0x2F, 0xB0, 0xB3, 0x2D, 0x81, 0x29, 0xDE, 0x71, 0x83, 0x41, 0x06, 0x5B, 0x72, 0x21 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000015, 0x00000748, { { 0x3E, 0x15, 0x27, 0xFD, 0x76, 0xFB, 0x14, 0x8C, 0xF6, 0x14, 0x3E, 0x20, 0x0A, 0x04, 0xF5, 0x32 } } } },
+
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc22StringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000000F, 0x000004D4, { { 0xE5, 0x97, 0x06, 0x45, 0x6A, 0xAC, 0x96, 0x6D, 0x0A, 0xC9, 0xDF, 0x8F, 0x96, 0x2D, 0x01, 0x5D } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x0000000D, 0x00000439, { { 0x87, 0xCB, 0x17, 0xD2, 0xC8, 0x7F, 0x34, 0xDA, 0x82, 0x30, 0xB2, 0x68, 0xB0, 0x10, 0xD9, 0x52 } } } },
+
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc31StringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000011, 0x00000597, { { 0x5C, 0xEB, 0x0A, 0xE6, 0xB1, 0x37, 0x0E, 0x8F, 0x14, 0xB4, 0x68, 0x86, 0xE5, 0xD2, 0xDE, 0xC7 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000012, 0x00000603, { { 0x8E, 0x68, 0x55, 0xCD, 0x29, 0x1E, 0x3C, 0x06, 0x7B, 0x97, 0xE1, 0x07, 0x49, 0x09, 0xF0, 0x57 } } } },
+
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc32StringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000020, 0x00000AE4, { { 0xED, 0x09, 0x04, 0xEC, 0xE3, 0x43, 0xDA, 0xEE, 0x5D, 0x78, 0x32, 0x63, 0x68, 0xFC, 0x4F, 0x9E } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000020, 0x00000B13, { { 0x87, 0x40, 0x88, 0xA5, 0xE2, 0x6F, 0x83, 0xBC, 0x99, 0x2B, 0xD3, 0xF5, 0x8D, 0x6B, 0x6E, 0x7D } } } },
+
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc4StringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000000D, 0x0000043C, { { 0x2C, 0xE7, 0xE5, 0xAA, 0xF3, 0x50, 0xA8, 0x6D, 0xC2, 0xC6, 0x88, 0xFE, 0x12, 0x96, 0xFE, 0x54 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000014, 0x00000720, { { 0xF8, 0x58, 0x9A, 0xDB, 0xE5, 0x3F, 0x67, 0x53, 0x1F, 0x27, 0x2E, 0x8D, 0x6E, 0xAD, 0x45, 0xF5 } } } },
+
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc5StringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000021, 0x00000ABC, { { 0xF1, 0xB5, 0x9E, 0x51, 0x9E, 0xF8, 0x84, 0x95, 0x55, 0x55, 0xE7, 0xDF, 0x36, 0xE1, 0x78, 0x9A } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x0000001D, 0x00000A8C, { { 0x4A, 0xAE, 0x5B, 0x3B, 0xAD, 0x18, 0x91, 0x3F, 0xC9, 0x5A, 0x82, 0x5D, 0xA7, 0x06, 0x1A, 0xAE } } } },
+
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc6StringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000011, 0x00000612, { { 0x1B, 0xE2, 0x23, 0xD9, 0x00, 0x5C, 0xB9, 0x54, 0xCE, 0xA7, 0x6A, 0x51, 0xF6, 0xBB, 0x8A, 0xC9 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000012, 0x00000647, { { 0x6C, 0x3F, 0xE2, 0xD0, 0xB0, 0x75, 0x2D, 0x73, 0xEE, 0x6F, 0x17, 0x74, 0xAA, 0x7D, 0xA2, 0x21 } } } },
+
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc7StringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000018, 0x00000777, { { 0x60, 0xB4, 0x17, 0x72, 0x89, 0x87, 0x47, 0xE3, 0xD9, 0xC3, 0x59, 0x16, 0xFD, 0x03, 0x31, 0xD4 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000016, 0x000007B6, { { 0xAE, 0xB6, 0x3C, 0x14, 0x2B, 0x34, 0xB8, 0x7C, 0xCF, 0x87, 0xDA, 0x70, 0xBF, 0x0D, 0xAB, 0xE2 } } } },
+
+	EXTRACT_END_ENTRY
+};
 
 const ExtractEntrySearchData kEob2MainMenuStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000005F, 0x000017BE, { { 0x77, 0x8A, 0x50, 0x9F, 0x42, 0xD8, 0x00, 0x05, 0x60, 0x2A, 0x80, 0x25, 0x00, 0xDC, 0x7C, 0x92 } } } },
@@ -3725,6 +3821,22 @@ const ExtractEntry extractProviders[] = {
 	{ kEob1MonsterDistAttSfx17, kEob1MonsterDistAttSfx17Provider },
 	{ kEob1TurnUndeadString, kEob1TurnUndeadStringProvider },
 
+	{ kEob1NpcShpData, kEob1NpcShpDataProvider },
+	{ kEob1NpcSubShpIndex1, kEob1NpcSubShpIndex1Provider },
+	{ kEob1NpcSubShpIndex2, kEob1NpcSubShpIndex2Provider },
+	{ kEob1NpcSubShpY, kEob1NpcSubShpYProvider },
+	{ kEob1Npc0Strings, kEob1Npc0StringsProvider },
+	{ kEob1Npc11Strings, kEob1Npc11StringsProvider },
+	{ kEob1Npc12Strings, kEob1Npc12StringsProvider },
+	{ kEob1Npc21Strings, kEob1Npc21StringsProvider },
+	{ kEob1Npc22Strings, kEob1Npc22StringsProvider },
+	{ kEob1Npc31Strings, kEob1Npc31StringsProvider },
+	{ kEob1Npc32Strings, kEob1Npc32StringsProvider },
+	{ kEob1Npc4Strings, kEob1Npc4StringsProvider },
+	{ kEob1Npc5Strings, kEob1Npc5StringsProvider },
+	{ kEob1Npc6Strings, kEob1Npc6StringsProvider },
+	{ kEob1Npc7Strings, kEob1Npc7StringsProvider },
+
 	{ kEob2MainMenuStrings, kEob2MainMenuStringsProvider },
 	{ kEob2IntroStrings, kEob2IntroStringsProvider },
 	{ kEob2IntroCPSFiles, kEob2IntroCPSFilesProvider },
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index 2128a44..3b79f04 100644
Binary files a/dists/engine-data/kyra.dat and b/dists/engine-data/kyra.dat differ
diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
index d12283f..9505231 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -46,6 +46,19 @@ Common::Error EobEngine::init() {
 
 	_itemsOverlay = _res->fileData("ITEMRMP.VGA", 0);
 
+	static const uint16 wX[] = { 285, 139 };
+	static const uint8 wY[] = { 189, 162 };
+	static const uint16 wW[] = { 31, 31 };
+
+	_dialogueButtonLabelCol1 = 9;
+	_dialogueButtonLabelCol2 = 15;
+	_dialogueButtonW = 95;
+	_dialogueButtonH = 9;
+	_waitButtonPresX = wX;
+	_waitButtonPresY = wY;
+	_waitButtonPresW = wW;
+	_waitButtonReverveW = 7;
+
 	_bkgColor_1 = 132;
 	_color1_1 = 135;
 	_color2_1 = 130;
@@ -82,11 +95,227 @@ void EobEngine::startupLoad() {
 	_sound->loadSoundFile("ADLIB");
 }
 
-void EobEngine::npcSequence(int npcIndex) {
-	error("EobEngine::npcSequence(): unimplemented");
+void EobEngine::drawNpcScene(int npcIndex) {
+	_screen->copyRegion(0, 0, 0, 0, 176, 120, 6, 0, Screen::CR_NO_P_CHECK);
+	switch (npcIndex) {
+	case 0:
+		encodeDrawNpcSeqShape(2, 88, 104);
+		break;
+
+	case 1:
+		if (_npcSequenceSub == -1) {
+			encodeDrawNpcSeqShape(0, 88, 104);
+		} else {
+			encodeDrawNpcSeqShape(0, 60, 104);
+			encodeDrawNpcSeqShape(5, 116, 104);
+		}
+		break;
+
+	case 2:
+		if (_npcSequenceSub == -1) {
+			encodeDrawNpcSeqShape(3, 88, 104);
+		} else {
+			encodeDrawNpcSeqShape(3, 60, 104);
+			encodeDrawNpcSeqShape(_npcSubShpIndex1[_npcSequenceSub], 116, 104);
+			encodeDrawNpcSeqShape(_npcSubShpIndex2[_npcSequenceSub], 116, _npcSubShpY[_npcSequenceSub]);
+		}
+		break;
+
+	case 3:
+		encodeDrawNpcSeqShape(7, 88, 104);
+		break;
+
+	case 4:
+		encodeDrawNpcSeqShape(6, 88, 104);
+		break;
+
+	case 5:
+		encodeDrawNpcSeqShape(18, 88, 88);
+		break;
+
+	case 6:
+		encodeDrawNpcSeqShape(17, 88, 104);
+		break;
+
+	case 7:
+		encodeDrawNpcSeqShape(4, 88, 104);
+		break;
+
+	default:
+		break;
+	}
+}
 
+void EobEngine::encodeDrawNpcSeqShape(int npcIndex, int drawX, int drawY) {
+	const uint8 *shpDef = &_npcShpData[npcIndex << 2];
+	_screen->_curPage = 2;
+	const uint8 *shp = _screen->encodeShape(shpDef[0], shpDef[1], shpDef[2], shpDef[3]);
+	_screen->_curPage = 0;
+	_screen->drawShape(0, shp, drawX - (shp[2] << 2), drawY - shp[1], 5);
+	delete[] shp;
 }
 
+#define DLG2(txt, buttonstr) (runDialogue(txt, 0, _npc##buttonstr##Strings[0], _npc##buttonstr##Strings[1], 0) - 1)
+#define DLG3(txt, buttonstr) (runDialogue(txt, 1, _npc##buttonstr##Strings[0], _npc##buttonstr##Strings[1], _npc##buttonstr##Strings[2], 0) - 1)
+#define DLG2A3(cond, txt, buttonstr1, buttonstr2) ((cond) ? (DLG2(txt, buttonstr1) ? 2 : 0) : DLG3(txt, buttonstr2))
+#define TXT(txt) _txt->printDialogueText(txt, _moreStrings[0])
+
+void EobEngine::runNpcDialogue(int npcIndex) {
+	int r = 0;
+	int a = 0;
+	Item itm = 0;
+	
+	switch (npcIndex) {
+	case 0:
+		for (r = 1; r == 1; ) {
+			gui_drawDialogueBox();
+			r = DLG2A3(checkScriptFlag(0x2000), 8, 12, 11);
+			if (r == 1) {
+				TXT(1);
+				setScriptFlag(0x2000);
+			} else if (r == 0) {
+				npcJoinDialogue(6, 12, 23, 2);
+				setScriptFlag(0x4000);
+			}
+		}
+		break;
+
+	case 1:
+		if (!checkScriptFlag(0x10000)) {
+			if (checkScriptFlag(0x8000)) {
+				a = 1;
+			} else {
+				setScriptFlag(0x8000);
+				r = DLG2(3, 21);
+			}
+			if (!r)
+				r = DLG2(a ? 13 : 4, 22);
+			
+			if (!r) {
+				for (a = 0; a < 6; a++)
+					createItemOnCurrentBlock(55);
+				createItemOnCurrentBlock(62);
+				setScriptFlag(0x10000);
+				TXT(6);
+				npcJoinDialogue(7, 7, 29, 30);
+			} else {
+				TXT(5);
+			}
+			r = 1;
+		}
+
+		if (!checkScriptFlag(0x80000)) {
+			for (a = 0; a < 6; a++) {
+				if (testCharacter(a, 1) && _characters[a].portrait == -9)
+					break;
+			}
+			if (a != 6) {
+				TXT(25);
+				TXT(26);
+				setScriptFlag(0x80000);
+				r = 1;
+			}
+		}
+
+		if (!checkScriptFlag(0x100000)) {
+			if (deletePartyItems(6, -1)) {
+				TXT(28);
+				createItemOnCurrentBlock(32);
+				setScriptFlag(0x100000);
+				r = 1;
+			}
+		}
+
+		if (!r)
+			 _txt->printDialogueText(_npc0Strings[0], true);
+
+		break;
+
+	case 2:
+		if (checkScriptFlag(0x10000)) {
+			if (checkScriptFlag(0x20000)) {
+				TXT(11);
+			} else {
+				r = DLG2A3(!countResurrectionCandidates(), 9, 31, 32);
+				if (r < 2) {
+					if (r == 0)
+						healParty();
+					else
+						resurrectionSelectDialogue();
+					setScriptFlag(0x20000);
+				}				
+			}
+		} else {
+			TXT(24);
+		}
+		break;
+
+	case 3:
+		if (!DLG2(18, 4)) {
+			setScriptFlag(0x8400000);
+			for (a = 0; a < 30; a++) {
+				if (_monsters[a].mode == 8)
+					_monsters[a].mode = 5;
+			}
+		} else if (deletePartyItems(49, -1)) {
+			TXT(20);
+			setScriptFlag(0x400000);
+		} else {
+			TXT(19);
+		}
+		break;
+
+	case 4:
+		r = DLG3(14, 5);
+		if (r == 0)
+			setScriptFlag(0x200000);
+		else if (r == 1)
+			TXT(15);
+		setScriptFlag(0x800000);
+		break;
+
+	case 5:
+		if (!DLG2(16, 6)) {
+			TXT(17);
+			for (a = 0; a < 6; a++) {
+				for (r = 0; r < 2; r++) {
+					itm = _characters[a].inventory[r];
+					if (itm && (_items[itm].type < 51 || _items[itm].type > 56)) {
+						_characters[a].inventory[r] = 0;
+						setItemPosition((Item*)&_levelBlockProperties[_currentBlock].drawObjects, _currentBlock, itm, _dropItemDirIndex[(_currentDirection << 2) + rollDice(1, 2, -1)]);
+					}
+				}
+			}
+		}
+		setScriptFlag(0x2000000);
+		break;
+
+	case 6:
+		TXT(21);
+		setScriptFlag(0x1000000);
+		break;
+
+	case 7:
+		r = DLG3(22, 7);
+		if (r  < 2) {
+			if (r == 0)
+				npcJoinDialogue(8, 27, 44, 45);
+			else
+				TXT(31);
+			setScriptFlag(0x4000000);
+		}
+		break;
+
+	default:
+		break;
+	}
+}
+
+#undef TXT
+#undef DLG2
+#undef DLG3
+#undef DLG2A3
+
 void EobEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
 	EobItem *itm = &_items[_characters[charIndex].inventory[slot]];
 	if (itm->type == 48) {
@@ -269,6 +498,44 @@ bool EobEngine::checkPartyStatusExtra() {
 	return true;
 }
 
+int EobEngine::resurrectionSelectDialogue() {
+	gui_drawDialogueBox();
+	_txt->printDialogueText(_npc0Strings[1]);
+
+	int r = _rrId[runDialogue(-1, 1, _rrNames[0], _rrNames[1], _rrNames[2], _rrNames[3], _rrNames[4], _rrNames[5], _rrNames[6], _rrNames[7], _rrNames[8]) - 1];
+
+	if (r < 0) {
+		r = -r;
+		deletePartyItems(33, r);
+		_npcSequenceSub = r - 1;
+		drawNpcScene(2);
+		npcJoinDialogue(_npcSequenceSub, 32 + (_npcSequenceSub << 1), -1, 33 + (_npcSequenceSub << 1));
+	} else {
+		_characters[r].hitPointsCur = _characters[r].hitPointsMax;
+	}
+
+	return 1;
+}
+
+void EobEngine::healParty() {
+	int cnt = rollDice(1, 3, 2);
+	for (int i = 0; i < 6 && cnt; i++) {
+		if (testCharacter(i, 3))
+			continue;
+		
+		_characters[i].flags &= ~4;
+		neutralizePoison(i);
+		
+		if (_characters[i].hitPointsCur >= _characters[i].hitPointsMax)
+			continue;
+		
+		cnt--;
+		_characters[i].hitPointsCur += rollDice(1, 8, 9);
+		if (_characters[i].hitPointsCur > _characters[i].hitPointsMax)
+			_characters[i].hitPointsCur = _characters[i].hitPointsMax;
+	}
+}
+
 uint32 EobEngine::convertSpellFlagToEob2Format(uint32 flag, int ignoreInvisibility) {
 	uint32 res = 0;
 	if (flag & 0x01)
diff --git a/engines/kyra/eob1.h b/engines/kyra/eob1.h
index 8d41118..8b805c0 100644
--- a/engines/kyra/eob1.h
+++ b/engines/kyra/eob1.h
@@ -56,10 +56,25 @@ private:
 	void seq_playFinale();
 
 	// characters
-	void npcSequence(int npcIndex);
-
-	//const char *const *_npc1Strings;
-	//const char *const *_npc2Strings;
+	void drawNpcScene(int npcIndex);
+	void encodeDrawNpcSeqShape(int npcIndex, int drawX, int drawY);
+	void runNpcDialogue(int npcIndex);
+
+	const uint8 *_npcShpData;
+	const uint8 *_npcSubShpIndex1;
+	const uint8 *_npcSubShpIndex2;
+	const uint8 *_npcSubShpY;
+	const char *const *_npc0Strings;
+	const char *const *_npc11Strings;
+	const char *const *_npc12Strings;
+	const char *const *_npc21Strings;
+	const char *const *_npc22Strings;
+	const char *const *_npc31Strings;
+	const char *const *_npc32Strings;
+	const char *const *_npc4Strings;
+	const char *const *_npc5Strings;
+	const char *const *_npc6Strings;
+	const char *const *_npc7Strings;
 
 	// items
 	void updateUsedCharacterHandItem(int charIndex, int slot);
@@ -92,6 +107,9 @@ private:
 
 	// Misc
 	bool checkPartyStatusExtra();
+	int resurrectionSelectDialogue();
+	void healParty();
+
 	uint32 convertSpellFlagToEob2Format(uint32 flag, int ignoreInvisibility);
 	uint32 convertCharacterEffectFlagToEob2Format(uint32 flag);
 };
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index cd30686..2b4cf46 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -52,6 +52,19 @@ Common::Error DarkMoonEngine::init() {
 
 	_monsterProps = new EobMonsterProperty[10];
 
+	static const uint16 wX[] = { 221, 76 };
+	static const uint8 wY[] = { 189, 162 };
+	static const uint16 wW[] = { 95, 95 };
+
+	_dialogueButtonLabelCol1 = 9;
+	_dialogueButtonLabelCol2 = 15;
+	_dialogueButtonW = 95;
+	_dialogueButtonH = 9;
+	_waitButtonPresX = wX;
+	_waitButtonPresY = wY;
+	_waitButtonPresW = wW;
+	_waitButtonReverveW = 7;
+
 	_bkgColor_1 = 183;
 	_color1_1 = 186;
 	_color2_1 = 181;
@@ -77,11 +90,8 @@ void DarkMoonEngine::startupNew() {
 	EobCoreEngine::startupNew();
 }
 
-void DarkMoonEngine::npcSequence(int npcIndex) {
-	_screen->loadEobBitmap("OUTTAKE", 5, 3);
-	_screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 6, Screen::CR_NO_P_CHECK);
+void DarkMoonEngine::drawNpcScene(int npcIndex) {
 	const uint8 *shpDef = &_npcShpData[npcIndex << 3];
-
 	for (int i = npcIndex; i != 255; i = shpDef[7]) {
 		shpDef = &_npcShpData[i << 3];
 		_screen->_curPage = 2;
@@ -90,15 +100,9 @@ void DarkMoonEngine::npcSequence(int npcIndex) {
 		_screen->drawShape(0, shp, 88 + shpDef[5] - (shp[2] << 2), 104 + shpDef[6] - shp[1], 5);
 		delete[] shp;
 	}
+}
 
-	Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
-	_screen->loadFileDataToPage(s, 5, 32000);
-	delete s;
-
-	gui_drawBox(0, 121, 320, 79, _color1_1, _color2_1, _bkgColor_1);
-	_txt->setupField(9, true);
-	_txt->resetPageBreakString();
-
+void DarkMoonEngine::runNpcDialogue(int npcIndex) {
 	if (npcIndex == 0) {
 		snd_playSoundEffect(57);
 		if (npcJoinDialogue(0, 1, 3, 2))
@@ -108,7 +112,7 @@ void DarkMoonEngine::npcSequence(int npcIndex) {
 		gui_drawDialogueBox();
 
 		_txt->printDialogueText(4, 0);
-		int r = runDialogue(-1, 0, _npc1Strings[0], _npc1Strings[1]) - 1;
+		int r = runDialogue(-1, 0, _npc1Strings[0], _npc1Strings[1], 0) - 1;
 
 		if (r == 0) {
 			_sound->playTrack(0);
@@ -124,7 +128,7 @@ void DarkMoonEngine::npcSequence(int npcIndex) {
 		gui_drawDialogueBox();
 
 		_txt->printDialogueText(8, 0);
-		int r = runDialogue(-1, 0, _npc2Strings[0], _npc2Strings[1]) - 1;
+		int r = runDialogue(-1, 0, _npc2Strings[0], _npc2Strings[1], 0) - 1;
 
 		if (r == 0) {
 			if (rollDice(1, 2, -1))
@@ -136,9 +140,6 @@ void DarkMoonEngine::npcSequence(int npcIndex) {
 			_currentDirection = 0;
 		}
 	}
-
-	_txt->removePageBreakFlag();
-	gui_restorePlayField();
 }
 
 void DarkMoonEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
@@ -338,7 +339,40 @@ void DarkMoonEngine::drawDoorIntern(int type, int, int x, int y, int w, int wall
 }
 
 void DarkMoonEngine::restParty_npc() {
-	warning("DarkMoonEngine::restParty_npc(): implement!");
+	int insalId = -1;
+	int numChar = 0;
+
+	for (int i = 0; i < 6; i++) {
+		if (!testCharacter(i, 1))
+			continue;
+		if (testCharacter(i, 2) && _characters[i].portrait == -1)
+			insalId = i;
+		numChar++;
+	}
+
+	if (insalId == -1 || numChar < 5)
+		return;
+
+	removeCharacterFromParty(insalId);
+	if (insalId < 4)
+		exchangeCharacters(insalId, testCharacter(5, 1) ? 5 : 4);
+
+	clearScriptFlag(6);
+
+	if (!stripPartyItems(1, 1, 1, 1))
+		stripPartyItems(2, 1, 1, 1);
+	stripPartyItems(31, 0, 1, 3);
+	stripPartyItems(39, 1, 0, 3);
+	stripPartyItems(47, 0, 1, 2);
+
+	_items[createItemOnCurrentBlock(28)].value = 26;
+
+	gui_drawPlayField(false);
+	gui_drawAllCharPortraitsWithStats();
+
+	_screen->setClearScreenDim(10);
+	_gui->messageDialogue2(11, 63, 6);
+	_gui->messageDialogue2(11, 64, 6);
 }
 
 bool DarkMoonEngine::restParty_extraAbortCondition() {
@@ -357,7 +391,7 @@ void DarkMoonEngine::useHorn(int charIndex, int weaponSlot) {
 }
 
 bool DarkMoonEngine::checkPartyStatusExtra() {
-	if (checkScriptFlag(0x10))
+	if (checkScriptFlag(0x100000))
 		seq_dranFools();
 	return _gui->confirmDialogue2(14, 67, 1);
 }
@@ -374,49 +408,12 @@ void DarkMoonEngine::drawLightningColumn() {
 }
 
 int DarkMoonEngine::resurrectionSelectDialogue() {
-	int cnt = 0;
-	const char *namesList[10];
-	memset(namesList, 0, 10 * sizeof(const char*));
-	int8 indexList[10];
-
-	for (int i = 0; i < 6; i++) {
-		if (!testCharacter(i, 1))
-			continue;
-		if (_characters[i].hitPointsCur != -10)
-			continue;
-
-		namesList[cnt] = _characters[i].name;
-		indexList[cnt++] = i;
-	}
-
-	for (int i = 0; i < 6; i++) {
-		if (!testCharacter(i, 1))
-			continue;
-
-		for (int ii = 0; ii < 27; ii++) {
-			uint16 inv = _characters[i].inventory[ii];
-			if (!inv)
-				continue;
-
-			if (_items[inv].type != 33)
-				continue;
-
-			namesList[cnt] = _npcPreset[_items[inv].value - 1].name;
-			indexList[cnt++] = -_items[inv].value;
-		}
-	}
-
-	if (_itemInHand) {
-		if (_items[_itemInHand].type == 33) {
-			namesList[cnt] = _npcPreset[_items[_itemInHand].value - 1].name;
-			indexList[cnt++] = -_items[_itemInHand].value;
-		}
-	}
+	countResurrectionCandidates();
 
-	namesList[cnt] = _abortStrings[0];
-	indexList[cnt++] = 99;
+	_rrNames[_rrCount] = _abortStrings[0];
+	_rrId[_rrCount++] = 99;
 
-	int r = indexList[runDialogue(-1, 1, namesList[0], namesList[1], namesList[2], namesList[3], namesList[4], namesList[5], namesList[6], namesList[7], namesList[8]) - 1];
+	int r = _rrId[runDialogue(-1, 1, _rrNames[0], _rrNames[1], _rrNames[2], _rrNames[3], _rrNames[4], _rrNames[5], _rrNames[6], _rrNames[7], _rrNames[8]) - 1];
 	if (r == 99)
 		return 0;
 
diff --git a/engines/kyra/eob2.h b/engines/kyra/eob2.h
index e1c574a..f24db79 100644
--- a/engines/kyra/eob2.h
+++ b/engines/kyra/eob2.h
@@ -94,7 +94,8 @@ private:
 	const char *const *_dranFoolsStrings;
 
 	// characters
-	void npcSequence(int npcIndex);
+	void drawNpcScene(int npcIndex);
+	void runNpcDialogue(int npcIndex);
 
 	const uint8 *_npcShpData;
 	const char *const *_npc1Strings;
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 22c0519..eef3873 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -110,7 +110,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_configHpBarGraphs = true;
 
 	memset(_dialogueLastBitmap, 0, 13);
-	_dlgUnk1 = 0;
+	_npcSequenceSub = 0;
 	_moveCounter = 0;
 	_partyResting = false;
 
@@ -137,6 +137,10 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_spellAnimBuffer = 0;
 	_clericSpellOffset = 0;
 	_restPartyElapsedTime = 0;
+
+	_rrCount = 0;
+	memset(_rrNames, 0, 10 * sizeof(const char*));
+	memset(_rrId, 0, 10 * sizeof(int8));
 }
 
 EobCoreEngine::~EobCoreEngine() {
@@ -975,6 +979,26 @@ void EobCoreEngine::neutralizePoison(int character) {
 	gui_drawCharPortraitWithStats(character);
 }
 
+void EobCoreEngine::npcSequence(int npcIndex) {
+	_screen->loadEobBitmap("OUTTAKE", 5, 3);
+	_screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 6, Screen::CR_NO_P_CHECK);
+
+	drawNpcScene(npcIndex);
+
+	Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
+	_screen->loadFileDataToPage(s, 5, 32000);
+	delete s;
+
+	gui_drawBox(0, 121, 320, 79, _color1_1, _color2_1, _bkgColor_1);
+	_txt->setupField(9, true);
+	_txt->resetPageBreakString();
+
+	runNpcDialogue(npcIndex);
+
+	_txt->removePageBreakFlag();
+	gui_restorePlayField();
+}
+
 void EobCoreEngine::initNpc(int npcIndex) {
 	EobCharacter *c = _characters;
 	int i = 0;
@@ -1005,7 +1029,7 @@ int EobCoreEngine::npcJoinDialogue(int npcIndex, int queryJoinTextId, int confir
 	gui_drawDialogueBox();
 	_txt->printDialogueText(queryJoinTextId, 0);
 
-	int r = runDialogue(-1, 0, _yesNoStrings[0], _yesNoStrings[1]) - 1;
+	int r = runDialogue(-1, 0, _yesNoStrings[0], _yesNoStrings[1], 0) - 1;
 	if (r == 0) {
 		if (confirmJoinTextId == -1) {
 			Common::String tmp = Common::String::format(_npcJoinStrings[0], _npcPreset[npcIndex].name);
@@ -1030,7 +1054,7 @@ int EobCoreEngine::prepareForNewPartyMember(int16 itemType, int16 itemValue) {
 		numChars += (_characters[i].flags & 1);
 
 	if (numChars < 6) {
-		deletePartyItem(itemType, itemValue);
+		deletePartyItems(itemType, itemValue);
 	} else {
 		gui_drawDialogueBox();
 		_txt->printDialogueText(_npcMaxStrings[0]);
@@ -1040,7 +1064,7 @@ int EobCoreEngine::prepareForNewPartyMember(int16 itemType, int16 itemValue) {
 		if (r == 6)
 			return 0;
 
-		deletePartyItem(itemType, itemValue);
+		deletePartyItems(itemType, itemValue);
 		removeCharacterFromParty(r);
 	}
 
@@ -1165,11 +1189,11 @@ void EobCoreEngine::setupDialogueButtons(int presetfirst, int numStr, const char
 
 	va_list args;
 	va_start(args, str1);
-	const char **s5p = va_arg(args, const char**);
+	const char **sp = va_arg(args, const char**);
 	va_end(args);
 	for (int i = 1; i < numStr; i++) {
-		if (s5p[i - 1])
-			_dialogueButtonString[i] = s5p[i - 1];
+		if (sp[i - 1])
+			_dialogueButtonString[i] = sp[i - 1];
 		else
 			_dialogueNumButtons = numStr = i;
 	}
@@ -1191,7 +1215,7 @@ void EobCoreEngine::setupDialogueButtons(int presetfirst, int numStr, const char
 }
 
 void EobCoreEngine::initDialogueSequence() {
-	_dlgUnk1 = -1;
+	_npcSequenceSub = -1;
 	_txt->setWaitButtonMode(0);
 	_dialogueField = true;
 
@@ -1435,6 +1459,47 @@ void EobCoreEngine::displayParchment(int id) {
 	restoreAfterDialogueSequence();
 }
 
+int EobCoreEngine::countResurrectionCandidates() {
+	_rrCount = 0;
+	memset(_rrNames, 0, 10 * sizeof(const char*));	
+
+	for (int i = 0; i < 6; i++) {
+		if (!testCharacter(i, 1))
+			continue;
+		if (_characters[i].hitPointsCur != -10)
+			continue;
+
+		_rrNames[_rrCount] = _characters[i].name;
+		_rrId[_rrCount++] = i;
+	}
+
+	for (int i = 0; i < 6; i++) {
+		if (!testCharacter(i, 1))
+			continue;
+
+		for (int ii = 0; ii < 27; ii++) {
+			uint16 inv = _characters[i].inventory[ii];
+			if (!inv)
+				continue;
+
+			if ((_flags.gameID == GI_EOB1 && ((_itemTypes[_items[inv].type].extraProperties & 0x7f) != 8)) || (_flags.gameID == GI_EOB2 && _items[inv].type != 33))
+				continue;
+
+			_rrNames[_rrCount] = _npcPreset[_items[inv].value - 1].name;
+			_rrId[_rrCount++] = -_items[inv].value;
+		}
+	}
+
+	if (_itemInHand > 0) {
+		if ((_flags.gameID == GI_EOB1 && ((_itemTypes[_items[_itemInHand].type].extraProperties & 0x7f) == 8)) || (_flags.gameID == GI_EOB2 && _items[_itemInHand].type == 33)) {
+			_rrNames[_rrCount] = _npcPreset[_items[_itemInHand].value - 1].name;
+			_rrId[_rrCount++] = -_items[_itemInHand].value;
+		}
+	}
+
+	return _rrCount;
+}
+
 void EobCoreEngine::useSlotWeapon(int charIndex, int slotIndex, Item item) {
 	EobCharacter *c = &_characters[charIndex];
 	int tp = item ? _items[item].type : 0;
@@ -1621,7 +1686,7 @@ int EobCoreEngine::calcCharacterDamage(int charIndex, int times, int itemOrPips,
 	EobCharacter *c = &_characters[charIndex];
 
 	if (a != 5) {
-		if (checkUnkConstModifiers(c, _charClassModUnk[c->cClass], c->level[0], a, c->raceSex))
+		if (checkMonsterLevelConstModifiers(c, _charClassModUnk[c->cClass], c->level[0], a, c->raceSex))
 			s = recalcDamageModifier(damageType, s);
 	}
 
@@ -1699,7 +1764,7 @@ bool EobCoreEngine::characterAttackHitTest(int charIndex, int monsterIndex, int
 
 	if (_flags.gameID == GI_EOB2) {
 		if ((p > 0 && p < 4) || !item ){
-			if (((_monsterProps[t].statusFlags & 0x200) && (d <= 0)) || ((_monsterProps[t].statusFlags & 0x1000) && (d <= 1)))
+			if (((_monsterProps[t].immunityFlags & 0x200) && (d <= 0)) || ((_monsterProps[t].immunityFlags & 0x1000) && (d <= 1)))
 				return false;
 		}
 	}
@@ -1877,7 +1942,7 @@ int EobCoreEngine::calcCloseDistanceMonsterDamage(EobMonsterInPlay *m, int times
 	EobMonsterProperty *p = &_monsterProps[m->type];
 
 	if (b == 5) {
-		if (checkUnkConstModifiers(m, 0, p->level, b, 6))
+		if (checkMonsterLevelConstModifiers(m, 0, p->level, b, 6))
 			s = recalcDamageModifier(damageType, s);
 	}
 
@@ -1886,10 +1951,12 @@ int EobCoreEngine::calcCloseDistanceMonsterDamage(EobMonsterInPlay *m, int times
 			s = 1;
 	}
 
-	if ((flags & 0x100) && ((_flags.gameID == GI_EOB2 && (p->statusFlags & 0x100)) || (_flags.gameID == GI_EOB1 && (p->capsFlags & 4))) && (!(_itemTypes[_items[pips].type].allowedClasses & 4 /* bug in original code ??*/)))
-		s >>= 1;
+	if ((flags & 0x100) && (!(_itemTypes[_items[pips].type].allowedClasses & 4 /* bug in original code ??*/)) &&
+		((_flags.gameID == GI_EOB2 && (p->immunityFlags & 0x100)) ||
+		(_flags.gameID == GI_EOB1 && (p->capsFlags & 4))))
+			s >>= 1;
 
-	if (p->statusFlags & 0x2000) {
+	if (p->immunityFlags & 0x2000) {
 		if (flags & 0x100) {
 			if (_items[pips].value < 3)
 				s >>= 2;
@@ -1913,7 +1980,7 @@ int EobCoreEngine::calcCloseDistanceMonsterDamage(EobMonsterInPlay *m, int times
 
 	static const uint16 damageImmunityFlags[] = { 0x01, 0x10, 0x02, 0x20, 0x80, 0x400, 0x20, 0x800, 0x40, 0x80, 0x400, 0x40 };
 	for (int i = 0; i < 12; i += 2) {
-		if ((flags & damageImmunityFlags[i]) && (p->statusFlags & damageImmunityFlags[i + 1]))
+		if ((flags & damageImmunityFlags[i]) && (p->immunityFlags & damageImmunityFlags[i + 1]))
 			s = 0;
 	}
 
@@ -1935,7 +2002,7 @@ int EobCoreEngine::calcDamageModifers(int charIndex, EobMonsterInPlay *m, int it
 	return (s < 0) ? 0 : s;
 }
 
-bool EobCoreEngine::checkUnkConstModifiers(void *target, int hpModifier, int level, int b, int race) {
+bool EobCoreEngine::checkMonsterLevelConstModifiers(void *target, int hpModifier, int level, int b, int race) {
 	static const int8 constMod[] = { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5 };
 
 	if (b == 5)
@@ -1951,7 +2018,7 @@ bool EobCoreEngine::checkUnkConstModifiers(void *target, int hpModifier, int lev
 }
 
 bool EobCoreEngine::specialAttackConstTest(int charIndex, int b) {
-	return checkUnkConstModifiers(&_characters[charIndex], _charClassModUnk[_characters[charIndex].cClass], _characters[charIndex].level[0], b, _characters[charIndex].raceSex >> 1);
+	return checkMonsterLevelConstModifiers(&_characters[charIndex], _charClassModUnk[_characters[charIndex].cClass], _characters[charIndex].level[0], b, _characters[charIndex].raceSex >> 1);
 }
 
 int EobCoreEngine::getConstModifierTableValue(int hpModifier, int level, int b) {
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 6463f83..1c730f7 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -158,7 +158,7 @@ struct SpriteDecoration {
 struct EobMonsterProperty {
 	int8 armorClass;
 	int8 hitChance;
-	uint8 level;
+	int8 level;
 	uint8 hpDcTimes;
 	uint8 hpDcPips;
 	uint8 hpDcBase;
@@ -168,7 +168,7 @@ struct EobMonsterProperty {
 		uint8 pips;
 		int8 base;
 	} dmgDc[3];
-	uint16 statusFlags;
+	uint16 immunityFlags;
 	uint32 capsFlags;
 	uint32 typeFlags;
 	int32 experience;
@@ -376,7 +376,9 @@ protected:
 	void modifyCharacterHitpoints(int character, int16 points);
 	void neutralizePoison(int character);
 
-	virtual void npcSequence(int npcIndex) = 0;
+	void npcSequence(int npcIndex);
+	virtual void drawNpcScene(int npcIndex) = 0;
+	virtual void runNpcDialogue(int npcIndex) = 0;
 	void initNpc(int npcIndex);
 	int npcJoinDialogue(int npcIndex, int queryJoinTextId, int confirmJoinTextId, int noJoinTextId);
 	int prepareForNewPartyMember(int16 itemType, int16 itemValue);
@@ -405,6 +407,7 @@ protected:
 	const uint8 *_constModExt;
 
 	const EobCharacter *_npcPreset;
+	int _npcSequenceSub;
 	bool _partyResting;
 	bool _loading;
 
@@ -412,11 +415,13 @@ protected:
 	void loadItemDefs();
 	Item duplicateItem(Item itemIndex);
 	void setItemPosition(Item *itemQueue, int block, Item item, int pos);
-	void createInventoryItem(EobCharacter *c, Item itemIndex, int itemValue, int preferedInventorySlot);
+	Item createItemOnCurrentBlock(Item itemIndex);
+	void createInventoryItem(EobCharacter *c, Item itemIndex, int16 itemValue, int preferedInventorySlot);
 	int deleteInventoryItem(int charIndex, int slot);
 	void deleteBlockItem(uint16 block, int type);
 	int validateInventorySlotForItem(Item item, int charIndex, int slot);
-	void deletePartyItem(Item itemType, int16 itemValue);
+	int stripPartyItems(int16 itemType, int16 itemValue, int handleValueMode, int numItems);
+	bool deletePartyItems(int16 itemType, int16 itemValue);
 	virtual void updateUsedCharacterHandItem(int charIndex, int slot) = 0;
 	int itemUsableByCharacter(int charIndex, Item item);
 	int countQueuedItems(Item itemQueue, int16 id, int16 type, int count, int includeFlyingItems);
@@ -622,6 +627,7 @@ protected:
 	// Script
 	void runLevelScript(int block, int flags);
 	void setScriptFlag(int flag);
+	void clearScriptFlag(int flag);
 	bool checkScriptFlag(int flag);
 
 	const uint8 *initScriptTimers(const uint8 *pos);
@@ -739,7 +745,6 @@ protected:
 	int runDialogue(int dialogueTextId, int style, const char *button1, ...);
 
 	char _dialogueLastBitmap[13];
-	int _dlgUnk1;
 	int _moveCounter;
 
 	uint8 _color4;
@@ -803,11 +808,12 @@ protected:
 	// misc
 	void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false);
 	void displayParchment(int id);
+	int countResurrectionCandidates();
+	virtual int resurrectionSelectDialogue() = 0;
 	virtual void useHorn(int charIndex, int weaponSlot) {}
 	virtual bool checkPartyStatusExtra() = 0;
 
 	virtual void drawLightningColumn() {}
-	virtual int resurrectionSelectDialogue() { return -1; }
 	virtual int charSelectDialogue() { return -1; }
 	virtual void characterLevelGain(int charIndex) {}
 
@@ -820,6 +826,10 @@ protected:
 
 	const char * const *_saveLoadStrings;
 
+	int _rrCount;
+	const char *_rrNames[10];
+	int8 _rrId[10];
+
 	Screen_Eob *_screen;
 	GUI_Eob *_gui;
 
@@ -846,7 +856,7 @@ protected:
 
 	int calcCloseDistanceMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int b, int damageType);
 	int calcDamageModifers(int charIndex, EobMonsterInPlay *m, int item, int itemType, int useStrModifier);
-	bool checkUnkConstModifiers(void *target, int hpModifier, int level, int b, int race);
+	bool checkMonsterLevelConstModifiers(void *target, int hpModifier, int level, int b, int race);
 	bool specialAttackConstTest(int charIndex, int b);
 	int getConstModifierTableValue(int hpModifier, int level, int b);
 	bool calcDamageCheckItemType(int itemType);
@@ -1045,6 +1055,7 @@ protected:
 	const char *const *_menuStringsDefeat;
 	const char *_errorSlotEmptyString;
 	const char *_errorSlotNoNameString;
+	const char *_menuOkString;
 
 	const char *const *_menuStringsTransfer;
 	const char *const *_menuStringsSpec;
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index ce5f3ea..c495eb5 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -385,7 +385,7 @@ void EobCoreEngine::gui_drawWeaponSlot(int charIndex, int slot) {
 
 	if (itm)
 		drawItemIconShape(_screen->_curPage, itm, x + 8, y);
-	else if (!slot && checkScriptFlag(0x8000))
+	else if (!slot && _flags.gameID == GI_EOB2 && checkScriptFlag(0x80000000))
 		_screen->drawShape(_screen->_curPage, _itemIconShapes[103], x + 8, y, 0);
 	else
 		_screen->drawShape(_screen->_curPage, _itemIconShapes[85], x + 8, y, 0);
@@ -2410,6 +2410,44 @@ bool GUI_Eob::confirmDialogue2(int dim, int id, int deflt) {
 	return newHighlight ? false : true;
 }
 
+void GUI_Eob::messageDialogue2(int dim, int id, int buttonTextCol) {
+	drawMenuButtonBox(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, false, false);
+
+	_screen->_curPage = 2;
+	_screen->setClearScreenDim(dim);
+	drawMenuButtonBox(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, false, false);
+	_screen->printShadedText(getMenuString(id), (_screen->_curDim->sx << 3) + 5, _screen->_curDim->sy + 5, 15, 0);	
+	_screen->_curPage = 0;
+	_screen->copyRegion(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, 2, 0, Screen::CR_NO_P_CHECK);
+
+	int x = (_screen->_curDim->sx << 3) + (_screen->_curDim->w << 2) - (strlen(_vm->_menuOkString) << 2);
+	int y = _screen->_curDim->sy + _screen->_curDim->h - 21;
+	int w = (strlen(_vm->_menuOkString) << 3) + 8;
+	drawMenuButtonBox(x, y, w, 14, false, false);
+	_screen->printShadedText(_vm->_menuOkString, x + 4, y + 3, buttonTextCol, 0);
+	_screen->updateScreen();
+
+	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
+		int inputFlag = _vm->checkInput(0, false, 0) & 0x8ff;
+		_vm->removeInputTop();
+
+		if (inputFlag == 199 || inputFlag == 201) {
+			if (_vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, x, y, x + w, y + 14))
+				runLoop = false;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_o]) {
+			runLoop = false;
+		}
+	}
+
+	_vm->gui_drawBox(x, y, w, 14, _vm->_color2_1, _vm->_bkgColor_1, -1);
+	_screen->updateScreen();
+	_vm->_system->delayMillis(80);
+	drawMenuButtonBox(x, y, w, 14, false, false);
+	_screen->printShadedText(_vm->_menuOkString, x + 4, y + 3, buttonTextCol, 0);
+	_screen->updateScreen();
+
+}
+
 void GUI_Eob::updateBoxFrameHighLight(int box) {
 	static const uint8 colorTable[] = { 0x0F, 0xB0, 0xB2, 0xB4, 0xB6,
 		0xB8, 0xBA, 0xBC, 0x0C, 0xBC, 0xBA, 0xB8, 0xB6, 0xB4, 0xB2, 0xB0, 0x00
@@ -3375,11 +3413,12 @@ bool GUI_Eob::restParty() {
 	_screen->setScreenDim(4);
 	_screen->setFont(Screen::FID_8_FNT);
 
-	if (!injured && !res)
-		displayTextBox(43);
-
-	if (res && hours > 4)
-		_vm->restParty_npc();
+	if (!res) {
+		if (!injured)
+			displayTextBox(43);
+		if (hours > 4)
+			_vm->restParty_npc();
+	}
 
 	return res;
 }
@@ -3447,8 +3486,6 @@ bool GUI_Eob::confirmDialogue(int id) {
 }
 
 void GUI_Eob::messageDialogue(int dim, int id, int buttonTextCol) {
-	static const char buttonText[] = "OK";
-
 	int od = _screen->curDimIndex();
 	_screen->setScreenDim(dim);
 	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
@@ -3456,12 +3493,12 @@ void GUI_Eob::messageDialogue(int dim, int id, int buttonTextCol) {
 	drawTextBox(dim, id);
 	const ScreenDim *dm = _screen->getScreenDim(dim);
 	
-	int bx = ((dm->sx + dm->w) << 3) - ((strlen(buttonText) << 3) + 16);
+	int bx = ((dm->sx + dm->w) << 3) - ((strlen(_vm->_menuOkString) << 3) + 16);
 	int by = dm->sy + dm->h - 19;
-	int bw = (strlen(buttonText) << 3) + 7;
+	int bw = (strlen(_vm->_menuOkString) << 3) + 7;
 
 	drawMenuButtonBox(bx, by, bw, 14, false, false);
-	_screen->printShadedText(buttonText, bx + 4, by + 3, buttonTextCol, 0);
+	_screen->printShadedText(_vm->_menuOkString, bx + 4, by + 3, buttonTextCol, 0);
 	_screen->updateScreen();
 
 	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
@@ -3469,9 +3506,8 @@ void GUI_Eob::messageDialogue(int dim, int id, int buttonTextCol) {
 		_vm->removeInputTop();
 
 		if (inputFlag == 199 || inputFlag == 201) {
-			Common::Point p = _vm->getMousePos();
-				if (_vm->posWithinRect(p.x, p.y, bx, by, bx + bw, by + 14))
-					runLoop = false;
+			if (_vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, bx, by, bx + bw, by + 14))
+				runLoop = false;
 		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_o]) {
 			runLoop = false;
 		}
diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h
index 709c676..af3d3d2 100644
--- a/engines/kyra/gui_eob.h
+++ b/engines/kyra/gui_eob.h
@@ -63,6 +63,8 @@ public:
 	bool runLoadMenu(int x, int y);
 
 	bool confirmDialogue2(int dim, int id, int deflt);
+	void messageDialogue2(int dim, int id, int buttonTextCol);
+
 	void updateBoxFrameHighLight(int box);
 
 	int getTextInput(char *dest, int x, int y, int destMaxLen, int textColor1, int textColor2, int cursorColor);
diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
index de5fe6b..78d3f8b 100644
--- a/engines/kyra/items_eob.cpp
+++ b/engines/kyra/items_eob.cpp
@@ -103,6 +103,12 @@ Kyra::Item EobCoreEngine::duplicateItem(Item itemIndex) {
 	return i;
 }
 
+Item EobCoreEngine::createItemOnCurrentBlock(Item itemIndex) {
+	Item itm = duplicateItem(itemIndex);
+	setItemPosition((Item*)&_levelBlockProperties[_currentBlock].drawObjects, _currentBlock, itm, _dropItemDirIndex[(_currentDirection << 2) + rollDice(1, 2, -1)]);
+	return itm;
+}
+
 void EobCoreEngine::setItemPosition(Item *itemQueue, int block, Item item, int pos) {
 	if (!item)
 		return;
@@ -123,7 +129,7 @@ void EobCoreEngine::setItemPosition(Item *itemQueue, int block, Item item, int p
 	}
 }
 
-void EobCoreEngine::createInventoryItem(EobCharacter *c, Item itemIndex, int itemValue, int preferedInventorySlot) {
+void EobCoreEngine::createInventoryItem(EobCharacter *c, Item itemIndex, int16 itemValue, int preferedInventorySlot) {
 	if (itemIndex <= 0)
 		return;
 
@@ -214,7 +220,35 @@ int EobCoreEngine::validateInventorySlotForItem(Item item, int charIndex, int sl
 	return 0;
 }
 
-void EobCoreEngine::deletePartyItem(Item itemType, int16 itemValue) {
+int EobCoreEngine::stripPartyItems(int16 itemType, int16 itemValue, int handleValueMode, int numItems) {
+	int itemsLeft = numItems;
+	
+	for (bool runloop = true; runloop && itemsLeft; ) {
+		runloop = false;
+		for (int i = 0; i < 6 && itemsLeft; i++) {
+			if (!testCharacter(i, 1))
+				continue;
+			
+			for (int ii = 0; ii < 27 && itemsLeft; ii++) {
+				if (ii == 16)
+					continue;
+
+				Item itm = _characters[i].inventory[ii];
+				if ((_items[itm].type == itemType) && ((handleValueMode == -1 && _items[itm].value <= itemValue) || (handleValueMode == 0 && _items[itm].value == itemValue) || (handleValueMode == 1 && _items[itm].value >= itemValue))) {
+					_characters[i].inventory[ii] = 0;
+					_items[itm].block = -1;
+					itemsLeft--;
+					runloop = true;
+				}
+			}
+		}
+	}
+
+	return numItems - itemsLeft;
+}
+
+bool EobCoreEngine::deletePartyItems(int16 itemType, int16 itemValue) {
+	bool res = false;
 	for (int i = 0; i < 6; i++) {
 		if (!testCharacter(i, 1))
 			continue;
@@ -228,13 +262,26 @@ void EobCoreEngine::deletePartyItem(Item itemType, int16 itemValue) {
 		int itm = c->inventory[slot];
 		_items[itm].block = -1;
 		c->inventory[slot] = 0;
+		res = true;
 
-		if (_currentControlMode == 0 && slot < 2 && i < 5)
-			gui_drawWeaponSlot(i, slot);
+		if (!_dialogueField) {
+			if (_currentControlMode == 0 && slot < 2 && i < 5)
+				gui_drawWeaponSlot(i, slot);
 
-		if (_currentControlMode == 1 && i == _updateCharNum)
-			gui_drawInventoryItem(slot, 1, 0);
+			if (_currentControlMode == 1 && i == _updateCharNum)
+				gui_drawInventoryItem(slot, 1, 0);
+		}
 	}
+
+	if (_itemInHand > 0) {
+		if ((itemType == -1 || itemType == _items[_itemInHand].type) && (itemValue == -1 || itemValue == _items[_itemInHand].value)) {
+			_items[_itemInHand].block = -1;
+			setHandItem(0);
+			res = true;
+		}
+	}
+
+	return res;
 }
 
 int EobCoreEngine::itemUsableByCharacter(int charIndex, Item item) {
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 7a4a3ec..4fc78c0 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -376,11 +376,14 @@ Common::Error LoLEngine::init() {
 	assert(_gui);
 	_gui->initStaticData();
 
-	_txt = new TextDisplayer_LoL(this, _screen);
 	_dialogueButtonLabelCol1 = 144;
 	_dialogueButtonLabelCol2 = 254;
 	_dialogueButtonW = 74;
 	_dialogueButtonH = 9;
+	_waitButtonReverveW = 80;
+
+	_txt = new TextDisplayer_LoL(this, _screen);
+
 	_bkgColor_1 = -1;
 	_color1_1 = 136;
 	_color2_1 = 251;
diff --git a/engines/kyra/loleobbase.cpp b/engines/kyra/loleobbase.cpp
index 47a261b..2ffae91 100644
--- a/engines/kyra/loleobbase.cpp
+++ b/engines/kyra/loleobbase.cpp
@@ -103,10 +103,14 @@ LolEobBaseEngine::LolEobBaseEngine(OSystem *system, const GameFlags &flags) : Ky
 	_dialogueNumButtons = _dialogueButtonYoffs = _dialogueHighlightedButton = 0;
 	_currentControlMode = 0;
 	_specialSceneFlag = 0;
-	_dialogueButtonLabelCol1 = 9;
-	_dialogueButtonLabelCol2 = 15;
-	_dialogueButtonW = 95;
-	_dialogueButtonH = 9;
+	_dialogueButtonLabelCol1 = 0;
+	_dialogueButtonLabelCol2 = 0;
+	_dialogueButtonW = 0;
+	_dialogueButtonH = 0;
+	_waitButtonPresX = 0;
+	_waitButtonPresY = 0;
+	_waitButtonPresW = 0;
+	_waitButtonReverveW = 0;
 
 	_updateCharNum = -1;
 	_activeVoiceFileTotalTime = 0;
diff --git a/engines/kyra/loleobbase.h b/engines/kyra/loleobbase.h
index a2c1382..ba59fe7 100644
--- a/engines/kyra/loleobbase.h
+++ b/engines/kyra/loleobbase.h
@@ -281,6 +281,10 @@ protected:
 	int16 _dialogueButtonYoffs;
 	uint16 _dialogueButtonW;
 	uint16 _dialogueButtonH;
+	const uint16 *_waitButtonPresX;
+	const uint8 *_waitButtonPresY;
+	const uint16 *_waitButtonPresW;
+	int _waitButtonReverveW;
 	int _dialogueNumButtons;
 	int _dialogueHighlightedButton;
 	int _currentControlMode;
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index f828625..70e4892 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -555,11 +555,11 @@ bool EobCoreEngine::magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int d
 bool EobCoreEngine::magicObjectStatusHit(EobMonsterInPlay *m, int type, bool tryEvade, int mod) {
 	EobMonsterProperty *p = &_monsterProps[m->type];
 	if (tryEvade) {
-		if (tryMonsterAttackEvasion(m) || (p->capsFlags & 0x10))
+		if (tryMonsterAttackEvasion(m) || (p->immunityFlags & 0x10))
 			return true;
 	}
 
-	if (checkUnkConstModifiers(m, 0, p->level, mod, 6))
+	if (checkMonsterLevelConstModifiers(m, 0, p->level, mod, 6))
 		return false;
 	
 	int para = 0;
@@ -569,7 +569,7 @@ bool EobCoreEngine::magicObjectStatusHit(EobMonsterInPlay *m, int type, bool try
 	case 1:
 	case 2:
 		para = (type == 0) ? ((p->typeFlags & 1) ? 1 : 0) : ((type == 1) ? ((p->typeFlags & 2) ? 1 : 0) : 1);
-		if (para && !(p->statusFlags & 2)) {
+		if (para && !(p->immunityFlags & 2)) {
 			m->mode = 10;
 			m->spellStatusLeft = 15;
 		}
@@ -577,7 +577,7 @@ bool EobCoreEngine::magicObjectStatusHit(EobMonsterInPlay *m, int type, bool try
 		break;
 
 	case 3:
-		if (!(p->statusFlags & 8))
+		if (!(p->immunityFlags & 8))
 			inflictMonsterDamage(m, 1000, true);
 		break;
 
@@ -591,12 +591,11 @@ bool EobCoreEngine::magicObjectStatusHit(EobMonsterInPlay *m, int type, bool try
 		break;
 
 	case 6:
-		if (!(p->statusFlags & 4) && m->mode != 7 && m->mode != 8 && m->mode != 10) {
+		if (!(_flags.gameID == GI_EOB1 && !(p->typeFlags & 3)) && !(p->immunityFlags & 4) && m->mode != 7 && m->mode != 8 && m->mode != 10) {
 			m->mode = 0;
 			m->spellStatusLeft = 20;
-			para = (getNextMonsterDirection(m->block, _currentBlock) ^ 4) >> 1;
 			m->flags |= 8;
-			walkMonsterNextStep(m, -1, para);
+			walkMonsterNextStep(m, -1, (getNextMonsterDirection(m->block, _currentBlock) ^ 4) >> 1);
 		}
 		break;
 
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 5328aef..55946e5 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -484,6 +484,22 @@ enum KyraResources {
 
 	kEob1TurnUndeadString,
 
+	kEob1NpcShpData,
+	kEob1NpcSubShpIndex1,
+	kEob1NpcSubShpIndex2,
+	kEob1NpcSubShpY,
+	kEob1Npc0Strings,
+	kEob1Npc11Strings,
+	kEob1Npc12Strings,
+	kEob1Npc21Strings,
+	kEob1Npc22Strings,
+	kEob1Npc31Strings,
+	kEob1Npc32Strings,
+	kEob1Npc4Strings,
+	kEob1Npc5Strings,
+	kEob1Npc6Strings,
+	kEob1Npc7Strings,
+
 	kEob2MainMenuStrings,
 	kEob2IntroStrings,
 	kEob2IntroCPSFiles,
diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp
index 833413c..1e113fb 100644
--- a/engines/kyra/script_eob.cpp
+++ b/engines/kyra/script_eob.cpp
@@ -40,8 +40,12 @@ void EobCoreEngine::setScriptFlag(int flag) {
 	_inf->setFlag(flag);
 }
 
+void EobCoreEngine::clearScriptFlag(int flag) {
+	_inf->clearFlag(flag);
+}
+
 bool EobCoreEngine::checkScriptFlag(int flag) {
-	return _inf->checkFlag(0x8000);
+	return _inf->checkFlag(flag);
 }
 
 const uint8 *EobCoreEngine::initScriptTimers(const uint8 *pos) {
@@ -188,6 +192,22 @@ void EobInfProcessor::run(int func, int sub) {
 	} while (!_abortScript && !_abortAfterSubroutine);
 }
 
+void EobInfProcessor::setFlag(int flag) {
+	_flagTable[17] |= flag;
+}
+
+void EobInfProcessor::clearFlag(int flag) {
+	_flagTable[17] &= ~flag;
+}
+
+bool EobInfProcessor::checkFlag(int flag) const {
+	return (_flagTable[17] & flag) ? true : false;
+}
+
+bool EobInfProcessor::preventRest() const {
+	return _preventRest ? true : false;
+}
+
 void EobInfProcessor::loadState(Common::SeekableSubReadStreamEndian &in) {
 	_preventRest = in.readByte();
 	for (int i = 0; i < 18; i++)
@@ -469,11 +489,11 @@ int EobInfProcessor::oeob_moveInventoryItemToBlock(int8 *data) {
 }
 
 int EobInfProcessor::oeob_printMessage_v1(int8 *data) {
-	static const char ColorConfig[] = { 6, 33, 2, 33, 0 };
+	static const char colorConfig[] = "\x6\x21\x2\x21";
 	char col[5];
 	int8 *pos = data;
 
-	strcpy(col, ColorConfig);
+	strcpy(col, colorConfig);
 	const char *str = (const char*) pos;
 	pos += (strlen(str) + 1);
 
@@ -720,7 +740,7 @@ int EobInfProcessor::oeob_eval_v1(int8 *data) {
 			for (i = 0; i < 6; i++) {
 				if (!(_vm->_characters[i].flags & 1))
 					continue;
-				if ((_vm->_characters[a].raceSex >> 1) == cmd) {
+				if ((_vm->_characters[i].raceSex >> 1) == cmd) {
 					b = 1;
 					break;
 				}
@@ -1371,7 +1391,7 @@ int EobInfProcessor::oeob_identifyItems(int8 *data) {
 
 int EobInfProcessor::oeob_sequence(int8 *data) {
 	int8 *pos = data;
-	_vm->_dlgUnk1 = -1;
+	_vm->_npcSequenceSub = -1;
 	_vm->txt()->setWaitButtonMode(0);
 	_vm->gui_updateControls();
 	_vm->drawScene(1);
@@ -1402,7 +1422,6 @@ int EobInfProcessor::oeob_sequence(int8 *data) {
 
 	case -1:
 		// copy protection
-		error("EobInfProcessor::oeob_sequence(): unimplemented cmd -1");
 		break;
 
 	default:
@@ -1508,8 +1527,8 @@ int EobInfProcessor::oeob_specialEvent(int8 *data) {
 			break;
 
 		case 5:
-			_vm->deletePartyItem(46, 5);
-			_vm->deletePartyItem(46, 6);
+			_vm->deletePartyItems(46, 5);
+			_vm->deletePartyItems(46, 6);
 			break;
 
 		case 6:
diff --git a/engines/kyra/script_eob.h b/engines/kyra/script_eob.h
index 322322a..71e53bc 100644
--- a/engines/kyra/script_eob.h
+++ b/engines/kyra/script_eob.h
@@ -42,9 +42,10 @@ public:
 	void loadData(const uint8 *data, uint32 dataSize);
 	void run(int func, int sub);
 
-	void setFlag(int flag) { _flagTable[17] |= flag; }
-	bool checkFlag(int flag) const { return (_flagTable[17] & flag) ? true : false; }
-	bool preventRest() const { return _preventRest ? true : false; }
+	void setFlag(int flag);
+	void clearFlag(int flag);
+	bool checkFlag(int flag) const;
+	bool preventRest() const;
 
 	void loadState(Common::SeekableSubReadStreamEndian &in);
 	void saveState(Common::OutSaveFile *out);
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index 0874de8..97ee51b 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -83,7 +83,7 @@ const uint8 *EobCoreEngine::loadMonsterProperties(const uint8 *data) {
 		EobMonsterProperty *d = &_monsterProps[cmd];
 		d->armorClass = (int8)*data++;
 		d->hitChance = (int8)*data++;
-		d->level = *data++;
+		d->level = (int8)*data++;
 		d->hpDcTimes = *data++;
 		d->hpDcPips = *data++;
 		d->hpDcBase = *data++;
@@ -97,7 +97,7 @@ const uint8 *EobCoreEngine::loadMonsterProperties(const uint8 *data) {
 		d->dmgDc[2].times = *data++;
 		d->dmgDc[2].pips = *data++;
 		d->dmgDc[3].base = (int8)*data++;
-		d->statusFlags = READ_LE_UINT16(data);
+		d->immunityFlags = READ_LE_UINT16(data);
 		data += 2;
 		d->capsFlags = READ_LE_UINT16(data);
 		data += 2;
@@ -185,7 +185,7 @@ void EobCoreEngine::initMonster(int index, int unit, uint16 block, int pos, int
 	m->spellStatusLeft = i;
 	m->dir = dir;
 	m->palette = _flags.gameID == GI_EOB2 ? (index % 3) : 0;
-	m->hitPointsCur = m->hitPointsMax = _flags.gameID == GI_EOB2 ? rollDice(p->hpDcTimes, p->hpDcPips, p->hpDcBase) : (p->hpDcTimes == 255 ? rollDice(1, 4, 0) : rollDice(p->hpDcTimes, 8, 0));
+	m->hitPointsCur = m->hitPointsMax = _flags.gameID == GI_EOB2 ? rollDice(p->hpDcTimes, p->hpDcPips, p->hpDcBase) : (p->level == -1 ? rollDice(1, 4, 0) : rollDice(p->level, 8, 0));
 	m->randItem = randItem;
 	m->fixedItem = fixedItem;
 	m->sub = _currentSub;
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 1cf78ee..ea943f3 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -151,7 +151,7 @@ bool StaticResource::loadEobNpcData(Common::SeekableReadStream &stream, void *&p
 		s->raceSex = stream.readByte();
 		s->cClass = stream.readByte();
 		s->alignment = stream.readByte();
-		s->portrait = stream.readByte();
+		s->portrait = stream.readSByte();
 		s->food = stream.readByte();
 		stream.read(s->level, 3);
 		s->experience[0] = stream.readUint32BE();
@@ -159,7 +159,7 @@ bool StaticResource::loadEobNpcData(Common::SeekableReadStream &stream, void *&p
 		s->experience[2] = stream.readUint32BE();
 		s->mageSpellsAvailableFlags = stream.readUint32BE();
 		for (int ii = 0; ii < 27; ii++)
-			s->inventory[i] = stream.readUint16BE();
+			s->inventory[ii] = stream.readSint16BE();
 	}
 
 	ptr = e;
@@ -555,6 +555,7 @@ void EobCoreEngine::initStaticResource() {
 	_saveLoadStrings = saveLoadStrings[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
 	_errorSlotEmptyString = errorSlotEmptyString[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
 	_errorSlotNoNameString = errorSlotNoNameString[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
+	_menuOkString = "OK";
 }
 
 void EobCoreEngine::initButtonData() {
@@ -1068,6 +1069,22 @@ void EobEngine::initStaticResource() {
 
 	_turnUndeadString = _staticres->loadStrings(kEob1TurnUndeadString, temp);
 
+	_npcShpData = _staticres->loadRawData(kEob1NpcShpData, temp);
+	_npcSubShpIndex1 = _staticres->loadRawData(kEob1NpcSubShpIndex1, temp);
+	_npcSubShpIndex2 = _staticres->loadRawData(kEob1NpcSubShpIndex2, temp);
+	_npcSubShpY = _staticres->loadRawData(kEob1NpcSubShpY, temp);
+	_npc0Strings = _staticres->loadStrings(kEob1Npc0Strings, temp);
+	_npc11Strings = _staticres->loadStrings(kEob1Npc11Strings, temp);
+	_npc12Strings = _staticres->loadStrings(kEob1Npc12Strings, temp);
+	_npc21Strings = _staticres->loadStrings(kEob1Npc21Strings, temp);
+	_npc22Strings = _staticres->loadStrings(kEob1Npc22Strings, temp);
+	_npc31Strings = _staticres->loadStrings(kEob1Npc31Strings, temp);
+	_npc32Strings = _staticres->loadStrings(kEob1Npc32Strings, temp);
+	_npc4Strings = _staticres->loadStrings(kEob1Npc4Strings, temp);
+	_npc5Strings = _staticres->loadStrings(kEob1Npc5Strings, temp);
+	_npc6Strings = _staticres->loadStrings(kEob1Npc6Strings, temp);
+	_npc7Strings = _staticres->loadStrings(kEob1Npc7Strings, temp);
+
 	const uint8 *ps = _staticres->loadRawData(kEob1MonsterProperties, temp);
 	temp /= 27;
 	_monsterProps = new EobMonsterProperty[temp];
@@ -1077,7 +1094,7 @@ void EobEngine::initStaticResource() {
 		EobMonsterProperty *p = &_monsterProps[i];
 		p->armorClass = (int8)*ps++;
 		p->hitChance = (int8)*ps++;
-		p->hpDcTimes = *ps++;
+		p->level = (int8)*ps++;
 		p->attacksPerRound = *ps++;
 		p->dmgDc[0].times = *ps++;
 		p->dmgDc[0].pips = *ps++;
diff --git a/engines/kyra/text_eob.cpp b/engines/kyra/text_eob.cpp
index 63d893d..80858d1 100644
--- a/engines/kyra/text_eob.cpp
+++ b/engines/kyra/text_eob.cpp
@@ -29,14 +29,16 @@
 
 #include "common/system.h"
 
+#define EOBTEXTBUFFERSIZE 2048
+
 namespace Kyra {
 
 TextDisplayer_Eob::TextDisplayer_Eob(LolEobBaseEngine *engine, Screen *sScreen) : _vm(engine), _screen(sScreen),
 	_lineCount(0), _printFlag(false), _lineWidth(0), _numCharsTotal(0), _allowPageBreak(true),
 	_numCharsLeft(0), _numCharsPrinted(0), _sjisLineBreakFlag(false), _waitButtonMode(1) {
 
-	_dialogueBuffer = new char[1024];
-	memset(_dialogueBuffer, 0, 1024);
+	_dialogueBuffer = new char[EOBTEXTBUFFERSIZE];
+	memset(_dialogueBuffer, 0, EOBTEXTBUFFERSIZE);
 
 	_currentLine = new char[85];
 	memset(_currentLine, 0, 85);
@@ -313,13 +315,13 @@ void TextDisplayer_Eob::printLine(char *str) {
 		if ((lw + _textDimData[sdx].column) > w) {
 			if ((lines - 1 - (_waitButtonSpace << 1)) <= _lineCount)
 				// cut off line to leave space for "MORE" button
-				w -= 80;
+				w -= vm()->_waitButtonReverveW;
 		} else {
 			if (!_sjisLineBreakFlag || (_lineCount + 1 < lines - 1))
 				ct = false;
 			else
 				// cut off line to leave space for "MORE" button
-				w -= 80;
+				w -= vm()->_waitButtonReverveW;
 		}
 
 		if (ct) {
@@ -341,7 +343,7 @@ void TextDisplayer_Eob::printLine(char *str) {
 		if ((lw + _textDimData[sdx].column) > w) {
 			if ((lines - 1) <= _lineCount && _allowPageBreak)
 				// cut off line to leave space for "MORE" button
-				w -= (10 * (_screen->getFontWidth() + _screen->_charWidth));
+				w -= vm()->_waitButtonReverveW;
 
 			w -= _textDimData[sdx].column;
 
@@ -439,7 +441,10 @@ void TextDisplayer_Eob::printLine(char *str) {
 }
 
 void TextDisplayer_Eob::printDialogueText(int stringId, const char *pageBreakString) {
-	strcpy(_dialogueBuffer, (const char *)(screen()->getCPagePtr(5) + READ_LE_UINT16(&screen()->getCPagePtr(5)[(stringId - 1) << 1])));
+	const char * str = (const char *)(screen()->getCPagePtr(5) + READ_LE_UINT16(&screen()->getCPagePtr(5)[(stringId - 1) << 1]));
+	assert (strlen(str) < EOBTEXTBUFFERSIZE);
+	Common::strlcpy(_dialogueBuffer, str, EOBTEXTBUFFERSIZE);
+	
 	displayText(_dialogueBuffer);
 
 	if (pageBreakString) {
@@ -452,6 +457,9 @@ void TextDisplayer_Eob::printDialogueText(int stringId, const char *pageBreakStr
 }
 
 void TextDisplayer_Eob::printDialogueText(const char *str, bool wait) {
+	assert (strlen(str) < EOBTEXTBUFFERSIZE);
+	Common::strlcpy(_dialogueBuffer, str, EOBTEXTBUFFERSIZE);
+
 	strcpy(_dialogueBuffer, str);
 	displayText(_dialogueBuffer);
 	if (wait)
@@ -471,7 +479,8 @@ void TextDisplayer_Eob::printMessage(const char *str, int textColor, ...) {
 
 	displayText(_dialogueBuffer);
 
-	_textDimData[screen()->curDimIndex()].color1 = tc;
+	if (vm()->game() != GI_EOB1)
+		_textDimData[screen()->curDimIndex()].color1 = tc;
 
 	if (!screen()->_curPage)
 		screen()->updateScreen();
@@ -505,7 +514,8 @@ void TextDisplayer_Eob::textPageBreak() {
 	int cp = _screen->setCurPage(0);
 	Screen::FontId cf = screen()->setFont(vm()->gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : Screen::FID_6_FNT);
 
-	vm()->_timer->pauseSingleTimer(11, true);
+	if (vm()->game() == GI_LOL)
+		vm()->_timer->pauseSingleTimer(11, true);
 
 	vm()->_fadeText = false;
 	int resetPortraitAfterSpeechAnim = 0;
@@ -527,27 +537,31 @@ void TextDisplayer_Eob::textPageBreak() {
 
 	int x = ((dim->sx + dim->w) << 3) - (_vm->_dialogueButtonW + 3);
 	int y = 0;
+	int w = vm()->_dialogueButtonW;
 
-	if (vm()->_needSceneRestore && (vm()->_updateFlags & 2)) {
-		if (vm()->_currentControlMode || !(vm()->_updateFlags & 2)) {
-			y = dim->sy + dim->h - 5;
+	if (vm()->game() == GI_LOL) {
+		if (vm()->_needSceneRestore && (vm()->_updateFlags & 2)) {
+			if (vm()->_currentControlMode || !(vm()->_updateFlags & 2)) {
+				y = dim->sy + dim->h - 5;
+			} else {
+				x += 6;
+				y = dim->sy + dim->h - 2;
+			}
 		} else {
-			x += 6;
-			y = dim->sy + dim->h - 2;
+			y = dim->sy + dim->h - 10;
 		}
-	} else if (vm()->game() == GI_LOL) {
-		y = dim->sy + dim->h - 10;
 	} else {
-		y = _waitButtonMode ? 162 : 189;
-		x = _waitButtonMode ? 76 : 221;
+		y = vm()->_waitButtonPresY[_waitButtonMode];
+		x = vm()->_waitButtonPresX[_waitButtonMode];
+		w = vm()->_waitButtonPresW[_waitButtonMode];
 	}
 
 	if (vm()->gameFlags().use16ColorMode) {
 		vm()->gui_drawBox(x + 8, (y & ~7) - 1, 66, 10, 0xee, 0xcc, -1);
 		screen()->printText(_pageBreakString, (x + 37 - (strlen(_pageBreakString) << 1) + 4) & ~3, (y + 2) & ~7, 0xc1, 0);
 	} else {
-		vm()->gui_drawBox(x, y, vm()->_dialogueButtonW, vm()->_dialogueButtonH, vm()->_color1_1, vm()->_color2_1, vm()->_bkgColor_1);
-		screen()->printText(_pageBreakString, x + (vm()->_dialogueButtonW >> 1) - (vm()->screen()->getTextWidth(_pageBreakString) >> 1), y + 2, vm()->_dialogueButtonLabelCol1, 0);
+		vm()->gui_drawBox(x, y, w, vm()->_dialogueButtonH, vm()->_color1_1, vm()->_color2_1, vm()->_bkgColor_1);
+		screen()->printText(_pageBreakString, x + (w >> 1) - (vm()->screen()->getTextWidth(_pageBreakString) >> 1), y + 2, vm()->_dialogueButtonLabelCol1, 0);
 	}
 
 	vm()->removeInputTop();
@@ -579,7 +593,7 @@ void TextDisplayer_Eob::textPageBreak() {
 		if (inputFlag == vm()->_keyMap[Common::KEYCODE_SPACE] || inputFlag == vm()->_keyMap[Common::KEYCODE_RETURN]) {
 			loop = false;
 		} else if (inputFlag == 199 || inputFlag == 201) {
-			if (vm()->posWithinRect(vm()->_mouseX, vm()->_mouseY, x, y, x + _vm->_dialogueButtonW, y + 9)) {
+			if (vm()->posWithinRect(vm()->_mouseX, vm()->_mouseY, x, y, x + w, y + 9)) {
 				if (_vm->game() == GI_LOL)
 					target = true;
 				else
@@ -594,11 +608,12 @@ void TextDisplayer_Eob::textPageBreak() {
 	if (vm()->gameFlags().use16ColorMode)
 		screen()->fillRect(x + 8, y, x + 57, y + 9, _textDimData[screen()->curDimIndex()].color2);
 	else
-		screen()->fillRect(x, y, x + 73, y + 8, _textDimData[screen()->curDimIndex()].color2);
+		screen()->fillRect(x, y, x + w - 1, y + 8, _textDimData[screen()->curDimIndex()].color2);
 
 	clearCurDim();
 
-	vm()->_timer->pauseSingleTimer(11, false);
+	if (vm()->game() == GI_LOL)
+		vm()->_timer->pauseSingleTimer(11, false);
 
 	if (vm()->_updateCharNum != -1) {
 		vm()->_resetPortraitAfterSpeechAnim = resetPortraitAfterSpeechAnim;
@@ -626,11 +641,9 @@ void TextDisplayer_Eob::displayWaitButton() {
 	vm()->_dialogueButtonString[2] = 0;
 	vm()->_dialogueHighlightedButton = 0;
 
-	static const uint16 posX[] = { 221, 76 };
-	static const uint8 posY[] = { 189, 162 };
-
-	vm()->_dialogueButtonPosX = &posX[_waitButtonMode];
-	vm()->_dialogueButtonPosY = &posY[_waitButtonMode];
+	vm()->_dialogueButtonPosX = &vm()->_waitButtonPresX[_waitButtonMode];
+	vm()->_dialogueButtonPosY = &vm()->_waitButtonPresY[_waitButtonMode];
+	vm()->_dialogueButtonW = vm()->_waitButtonPresW[_waitButtonMode];
 	vm()->_dialogueButtonYoffs = 0;
 
 	SWAP(_vm->_dialogueButtonLabelCol1, _vm->_dialogueButtonLabelCol2);
@@ -640,7 +653,10 @@ void TextDisplayer_Eob::displayWaitButton() {
 		vm()->removeInputTop();
 
 	while (!vm()->processDialogue() && !vm()->shouldQuit()) {}
+	
+	vm()->_dialogueButtonW = 95;
 	SWAP(_vm->_dialogueButtonLabelCol1, _vm->_dialogueButtonLabelCol2);
+	clearCurDim();
 }
 
 } // End of namespace Kyra


Commit: aab9e62247af1c22772bb79821675fbab06c047d
    https://github.com/scummvm/scummvm/commit/aab9e62247af1c22772bb79821675fbab06c047d
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:13-08:00

Commit Message:
KYRA: (EOB) - some more sequence code and bug fixes

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    dists/engine-data/kyra.dat
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/items_eob.cpp
    engines/kyra/magic_eob.cpp
    engines/kyra/resource.h
    engines/kyra/script_eob.cpp
    engines/kyra/sprites_eob.cpp
    engines/kyra/staticres_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index 68fc8cc..582516b 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -346,6 +346,11 @@ const ExtractFilename extractFilenames[] = {
 	{ kEobBaseDscItemShapeMap, kTypeRawData, false },
 	{ kEobBaseDscTelptrShpCoords, kTypeRawData, false },
 
+	{ kEobBasePortalSeqData, kTypeRawData, false },
+	{ kEobBaseManDef, kTypeRawData, true },
+	{ kEobBaseManWord, kTypeStringList, true },
+	{ kEobBaseManPrompt, kTypeStringList, true },
+
 	{ kEobBaseDscMonsterFrmOffsTbl1, kTypeRawData, false },
 	{ kEobBaseDscMonsterFrmOffsTbl2, kTypeRawData, false },
 
@@ -1556,7 +1561,15 @@ const char *getIdString(const int id) {
 	case kEobBaseFlightObjSclIndex:
 		return "kEobBaseFlightObjSclIndex";
 	case kEobBaseDscTelptrShpCoords:
-		return "kEobBaseDscTelptrShpCoords";	
+		return "kEobBaseDscTelptrShpCoords";
+	case kEobBasePortalSeqData:
+		return "kEobBasePortalSeqData";
+	case kEobBaseManDef:
+		return "kEobBaseManDef";
+	case kEobBaseManWord:
+		return "kEobBaseManWord";
+	case kEobBaseManPrompt:
+		return "kEobBaseManPrompt";
 	case kEobBaseBookNumbers:
 		return "kEobBaseBookNumbers";
 	case kEobBaseMageSpellsList:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index 54fd91b..ebaff50 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -361,6 +361,11 @@ enum kExtractID {
 	kEobBaseFlightObjSclIndex,
 
 	kEobBaseDscTelptrShpCoords,
+	
+	kEobBasePortalSeqData,
+	kEobBaseManDef,
+	kEobBaseManWord,
+	kEobBaseManPrompt,
 
 	kEobBaseBookNumbers,
 	kEobBaseMageSpellsList,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 5f71050..6e1503b 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1215,6 +1215,11 @@ const int eob1FloppyNeed[] = {
 	kEobBaseDscItemShapeMap,
 	kEobBaseDscTelptrShpCoords,
 
+	kEobBasePortalSeqData,
+	kEobBaseManDef,
+	kEobBaseManWord,
+	kEobBaseManPrompt,
+
 	kEobBaseDscMonsterFrmOffsTbl1,
 	kEobBaseDscMonsterFrmOffsTbl2,
 
@@ -1423,6 +1428,11 @@ const int eob2FloppyNeed[] = {
 	kEobBaseDscItemShapeMap,
 	kEobBaseDscTelptrShpCoords,
 
+	kEobBasePortalSeqData,
+	kEobBaseManDef,
+	kEobBaseManWord,
+	kEobBaseManPrompt,
+
 	kEobBaseDscMonsterFrmOffsTbl1,
 	kEobBaseDscMonsterFrmOffsTbl2,
 
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index 663652d..e27c6ed 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -2063,6 +2063,36 @@ const ExtractEntrySearchData kEobBaseDscTelptrShpCoordsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEobBasePortalSeqDataProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000007E, 0x000002D0, { { 0x18, 0x7E, 0x65, 0x17, 0x4C, 0xD2, 0xB5, 0x2E, 0x81, 0xF8, 0x1C, 0xAC, 0x37, 0x21, 0x62, 0x2A } } } },
+
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseManDefProvider[] = {
+	{ EN_ANY, kPlatformPC, { 0x00000078, 0x000002CD, { { 0x33, 0x9B, 0x0C, 0x6A, 0x2E, 0x4F, 0xE9, 0x02, 0x7B, 0xEE, 0xF1, 0x04, 0xA3, 0xBA, 0xD4, 0xF3 } } } },	// Eob 1
+	{ DE_DEU, kPlatformPC, { 0x00000078, 0x000002C4, { { 0x92, 0x20, 0x58, 0x5F, 0x44, 0x09, 0x0B, 0xF0, 0xDA, 0x09, 0xE2, 0x44, 0x0B, 0xB7, 0x95, 0x96 } } } },	// Eob 1
+	{ EN_ANY, kPlatformPC, { 0x000000C8, 0x00000834, { { 0x18, 0xEA, 0x33, 0xB7, 0x4B, 0x72, 0x23, 0x8D, 0x0E, 0x9F, 0x4E, 0xF5, 0x09, 0xA3, 0x9C, 0xEA } } } },	// Eob 2
+	{ DE_DEU, kPlatformPC, { 0x000000C8, 0x00000622, { { 0xFE, 0x1D, 0x94, 0x3A, 0x0B, 0x17, 0x89, 0xEF, 0x60, 0x18, 0xB2, 0x43, 0x7A, 0x02, 0xDB, 0x61 } } } },	// Eob 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseManWordProvider[] = {
+	{ EN_ANY, kPlatformPC, { 0x000000E0, 0x00005134, { { 0x68, 0x9C, 0x19, 0x2B, 0x5F, 0x38, 0x36, 0x41, 0xA7, 0x7E, 0xB7, 0x51, 0x41, 0x60, 0x1D, 0x67 } } } },	// Eob 1
+	{ DE_DEU, kPlatformPC, { 0x000000EA, 0x00005458, { { 0xEC, 0x14, 0x11, 0xE9, 0x19, 0xFD, 0xF8, 0xFC, 0xA8, 0x46, 0x3D, 0xCD, 0x56, 0x08, 0xC3, 0x4A } } } },	// Eob 1
+	{ EN_ANY, kPlatformPC, { 0x0000017E, 0x00008B64, { { 0x66, 0x38, 0x09, 0x5B, 0x2E, 0x50, 0x54, 0x43, 0x1C, 0xEC, 0x56, 0x3B, 0x72, 0x39, 0xF9, 0xC3 } } } },	// Eob 2
+	{ DE_DEU, kPlatformPC, { 0x0000015B, 0x00007C37, { { 0x44, 0xA3, 0x32, 0x88, 0x9F, 0x63, 0x28, 0xA0, 0xBD, 0x00, 0xF1, 0x08, 0xCA, 0xE5, 0xFE, 0x5F } } } },	// Eob 2
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseManPromptProvider[] = {
+	{ EN_ANY, kPlatformPC, { 0x00000041, 0x000013AC, { { 0x40, 0x2B, 0xB5, 0x99, 0xEF, 0x8F, 0x3C, 0x9F, 0xB1, 0x5A, 0xBE, 0xE4, 0x80, 0x8E, 0xBB, 0x96 } } } },	// Eob 1
+	{ DE_DEU, kPlatformPC, { 0x00000048, 0x000015A5, { { 0x0B, 0xB4, 0x9E, 0xAD, 0xB3, 0x56, 0x75, 0xC1, 0xAE, 0x29, 0xF7, 0xB5, 0x82, 0x14, 0xD1, 0x27 } } } },	// Eob 1
+	{ EN_ANY, kPlatformPC, { 0x00000041, 0x000013AC, { { 0x40, 0x2B, 0xB5, 0x99, 0xEF, 0x8F, 0x3C, 0x9F, 0xB1, 0x5A, 0xBE, 0xE4, 0x80, 0x8E, 0xBB, 0x96 } } } },	// Eob 2
+	{ DE_DEU, kPlatformPC, { 0x0000005C, 0x00001D08, { { 0x10, 0xCE, 0x2D, 0xED, 0xA9, 0xA0, 0x7C, 0xA1, 0x91, 0x3F, 0xD8, 0x43, 0x03, 0x53, 0x97, 0xCA } } } },	// Eob 2
+	EXTRACT_END_ENTRY
+};
+
 const ExtractEntrySearchData kEobBaseDscMonsterFrmOffsTbl1Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000020, 0x00001000, { { 0x98, 0x27, 0x57, 0x25, 0x3B, 0x04, 0x7D, 0x14, 0x3A, 0xD4, 0xA2, 0x5D, 0xBA, 0x04, 0x45, 0xAC } } } },
 	EXTRACT_END_ENTRY
@@ -3758,6 +3788,11 @@ const ExtractEntry extractProviders[] = {
 	{ kEobBaseDscItemShapeMap, kEobBaseDscItemShapeMapProvider },
 	{ kEobBaseDscTelptrShpCoords, kEobBaseDscTelptrShpCoordsProvider },
 
+	{ kEobBasePortalSeqData, kEobBasePortalSeqDataProvider },
+	{ kEobBaseManDef, kEobBaseManDefProvider },	
+	{ kEobBaseManWord, kEobBaseManWordProvider },
+	{ kEobBaseManPrompt, kEobBaseManPromptProvider },
+
 	{ kEobBaseDscMonsterFrmOffsTbl1, kEobBaseDscMonsterFrmOffsTbl1Provider },
 	{ kEobBaseDscMonsterFrmOffsTbl2, kEobBaseDscMonsterFrmOffsTbl2Provider },
 
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index 3b79f04..7cbd3b6 100644
Binary files a/dists/engine-data/kyra.dat and b/dists/engine-data/kyra.dat differ
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index eef3873..f323dd4 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -1500,6 +1500,40 @@ int EobCoreEngine::countResurrectionCandidates() {
 	return _rrCount;
 }
 
+void EobCoreEngine::seq_portal() {
+	//_portalSeq
+}
+
+bool EobCoreEngine::checkPassword() {
+	char answ[20];
+	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+	_screen->copyPage(0, 10);
+	
+	_screen->setScreenDim(13);
+	gui_drawBox(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, _color1_1, _color2_1, -1);
+	gui_drawBox((_screen->_curDim->sx << 3) + 1, _screen->_curDim->sy + 1, (_screen->_curDim->w << 3) - 2, _screen->_curDim->h - 2, _color1_1, _color2_1, _bkgColor_1);
+	_screen->modifyScreenDim(13, _screen->_curDim->sx + 1, _screen->_curDim->sy + 2, _screen->_curDim->w - 2, _screen->_curDim->h - 16);
+	
+	for (int i = 0; i < 3; i++) {
+		_screen->fillRect(_screen->_curDim->sx << 3, _screen->_curDim->sy, ((_screen->_curDim->sx + _screen->_curDim->w) << 3) - 1, (_screen->_curDim->sy + _screen->_curDim->h) - 1, _bkgColor_1);
+		int c = rollDice(1, _mnNumWord - 1, -1);
+		_screen->drawShape(0, _largeItemShapes[_mnDef[c << 2]], 100, 2, 13);
+		_screen->printShadedText(Common::String::format(_mnPrompt[0], _mnDef[(c << 2) + 1], _mnDef[(c << 2) + 2]).c_str(), (_screen->_curDim->sx + 1) << 3, _screen->_curDim->sy, _screen->_curDim->unk8, _bkgColor_1);
+		memset(answ, 0, 20);
+		gui_drawBox(76, 100, 133, 14, _color2_1, _color1_1, -1);
+		gui_drawBox(77, 101, 131, 12, _color2_1, _color1_1, -1);	
+		if (_gui->getTextInput(answ, 10, 103, 15, _screen->_curDim->unk8, _bkgColor_1, 8) < 0)
+			i = 3;
+		if (scumm_stricmp(_mnWord[c], answ) && i == 2)
+			return false;
+	}
+
+	_screen->modifyScreenDim(13, _screen->_curDim->sx - 1, _screen->_curDim->sy - 2, _screen->_curDim->w + 2, _screen->_curDim->h + 16);
+	_screen->setFont(of);
+	_screen->copyPage(10, 0);
+	return true;
+}
+
 void EobCoreEngine::useSlotWeapon(int charIndex, int slotIndex, Item item) {
 	EobCharacter *c = &_characters[charIndex];
 	int tp = item ? _items[item].type : 0;
@@ -2110,7 +2144,7 @@ void EobCoreEngine::explodeMonster(EobMonsterInPlay *m) {
 }
 
 void EobCoreEngine::snd_playSoundEffect(int id, int volume) {
-	if (id < 1 || id > 119 || shouldQuit())
+	if ((id < 1) || (_flags.gameID == GI_EOB2 && id > 119) || shouldQuit())
 		return;
 
 	_sound->playSoundEffect(id, volume);
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 1c730f7..7ebc883 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -174,15 +174,15 @@ struct EobMonsterProperty {
 	int32 experience;
 
 	uint8 u30;
-	uint8 sound1;
-	uint8 sound2;
+	int8 sound1;
+	int8 sound2;
 	uint8 numRemoteAttacks;
 	uint8 remoteWeaponChangeMode;
 	uint8 numRemoteWeapons;
 
 	int8 remoteWeapons[5];
 
-	uint8 tuResist;
+	int8 tuResist;
 	uint8 dmgModifierEvade;
 
 	uint8 decorations[3];
@@ -623,6 +623,7 @@ protected:
 	const uint8 *_wllFlagPreset;
 	int _wllFlagPresetSize;
 	const uint8 *_teleporterShapeCoords;
+	const uint8 *_portalSeq;
 
 	// Script
 	void runLevelScript(int block, int flags);
@@ -807,12 +808,16 @@ protected:
 
 	// misc
 	void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false);
+
 	void displayParchment(int id);
 	int countResurrectionCandidates();
+
+	void seq_portal();
+	bool checkPassword();
+	
 	virtual int resurrectionSelectDialogue() = 0;
 	virtual void useHorn(int charIndex, int weaponSlot) {}
 	virtual bool checkPartyStatusExtra() = 0;
-
 	virtual void drawLightningColumn() {}
 	virtual int charSelectDialogue() { return -1; }
 	virtual void characterLevelGain(int charIndex) {}
@@ -826,6 +831,11 @@ protected:
 
 	const char * const *_saveLoadStrings;
 
+	const uint8 *_mnDef;
+	const char * const *_mnWord;
+	const char * const *_mnPrompt;
+	int _mnNumWord;
+
 	int _rrCount;
 	const char *_rrNames[10];
 	int8 _rrId[10];
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index c495eb5..9dec158 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -2509,7 +2509,7 @@ int GUI_Eob::getTextInput(char *dest, int x, int y, int destMaxLen, int textColo
 		in = 0;
 		_keyPressed.reset();
 
-		while (!in) {
+		while (!in && !_vm->shouldQuit()) {
 			if (next <= _vm->_system->getMillis()) {
 				if (cursorState) {
 					_screen->copyRegion((pos + 1) << 3, 191, (x + pos) << 3, y, 8, 9, 2, 0, Screen::CR_NO_P_CHECK);
@@ -2595,7 +2595,7 @@ int GUI_Eob::getTextInput(char *dest, int x, int y, int destMaxLen, int textColo
 			_screen->printShadedText(sufx, (x + pos) << 3, y, textColor1, textColor2);
 		_screen->updateScreen();
 
-	} while (_keyPressed.keycode != Common::KEYCODE_RETURN && _keyPressed.keycode != Common::KEYCODE_ESCAPE);
+	} while (_keyPressed.keycode != Common::KEYCODE_RETURN && _keyPressed.keycode != Common::KEYCODE_ESCAPE && !_vm->shouldQuit());
 
 	return _keyPressed.keycode == Common::KEYCODE_ESCAPE ? -1 : len;
 }
@@ -3194,8 +3194,10 @@ bool GUI_Eob::restParty() {
 				continue;
 			if (_vm->checkInventoryForItem(i, 30, -1) == -1)
 				continue;
-			if (_vm->restParty_checkHealSpells(i))
+			if (_vm->restParty_checkHealSpells(i)) {
 				useHealers = confirmDialogue(40);
+				break;
+			}
 		} 
 	}
 
diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
index 78d3f8b..b48c393 100644
--- a/engines/kyra/items_eob.cpp
+++ b/engines/kyra/items_eob.cpp
@@ -176,7 +176,9 @@ int EobCoreEngine::deleteInventoryItem(int charIndex, int slot) {
 void EobCoreEngine::deleteBlockItem(uint16 block, int type) {
 	uint16 itm = _levelBlockProperties[block].drawObjects;
 	if (!itm)
-		return;	
+		return;
+
+	_levelBlockProperties[block].drawObjects = 0;
 	
 	for (uint16 i2 = itm, i = 0; itm != i2 || !i; i++ ) {
 		if (type == _items[itm].type || type == -1) {
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 70e4892..3eb7591 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -75,7 +75,7 @@ void EobCoreEngine::useMagicScroll(int charIndex, int type, int weaponSlot) {
 }
 
 void EobCoreEngine::usePotion(int charIndex, int weaponSlot) {
-	EobCharacter *c = &_characters[_openBookChar];
+	EobCharacter *c = &_characters[charIndex];
 
 	int val = deleteInventoryItem(charIndex, weaponSlot);
 	snd_playSoundEffect(10);
@@ -607,6 +607,7 @@ bool EobCoreEngine::magicObjectStatusHit(EobMonsterInPlay *m, int type, bool try
 }
 
 bool EobCoreEngine::turnUndeadHit(EobMonsterInPlay *m, int hitChance, int casterLevel) {
+	assert(_monsterProps[m->type].tuResist > 0);
 	uint8 e = _turnUndeadEffect[_monsterProps[m->type].tuResist * 14 + MIN(casterLevel, 14)];
 
 	if (e == 0xff) {
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 55946e5..0f1539b 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -435,6 +435,11 @@ enum KyraResources {
 
 	kEobBaseDscTelptrShpCoords,
 
+	kEobBasePortalSeqData,
+	kEobBaseManDef,
+	kEobBaseManWord,
+	kEobBaseManPrompt,
+
 	kEobBaseBookNumbers,
 	kEobBaseMageSpellsList,
 	kEobBaseClericSpellsList,
diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp
index 1e113fb..7159700 100644
--- a/engines/kyra/script_eob.cpp
+++ b/engines/kyra/script_eob.cpp
@@ -1416,12 +1416,11 @@ int EobInfProcessor::oeob_sequence(int8 *data) {
 		return 0;
 
 	case -2:
-		// portal sequence
-		error("EobInfProcessor::oeob_sequence(): unimplemented cmd -2");
+		_vm->seq_portal();		
 		break;
 
 	case -1:
-		// copy protection
+		_vm->_runFlag = _vm->checkPassword();
 		break;
 
 	default:
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index 97ee51b..3447b6b 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -107,8 +107,8 @@ const uint8 *EobCoreEngine::loadMonsterProperties(const uint8 *data) {
 		data += 2;
 
 		d->u30 = *data++;
-		d->sound1 = *data++;
-		d->sound2 = *data++;
+		d->sound1 = (int8)*data++;
+		d->sound2 = (int8)*data++;
 		d->numRemoteAttacks = *data++;
 
 		if (*data++ != 0xff) {
@@ -121,7 +121,7 @@ const uint8 *EobCoreEngine::loadMonsterProperties(const uint8 *data) {
 			}
 		}
 
-		d->tuResist = *data++;
+		d->tuResist = (int8)*data++;
 		d->dmgModifierEvade = *data++;
 
 		for (int i = 0; i < 3; i++)
@@ -1181,7 +1181,7 @@ bool EobCoreEngine::walkMonsterNextStep(EobMonsterInPlay *m, int destBlock, int
 		m->dir = direction;
 
 	checkSceneUpdateNeed(obl);
-	if (!_partyResting && p->sound2)
+	if (!_partyResting && p->sound2 > 0)
 		snd_processEnvironmentalSoundEffect(p->sound2, m->block);
 
 	return true;
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index ea943f3..9b15d4a 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -448,6 +448,10 @@ void EobCoreEngine::initStaticResource() {
 	_npcPreset = _staticres->loadEobNpcData(kEobBaseNpcPresets, temp);
 
 	_teleporterShapeCoords = _staticres->loadRawData(kEobBaseDscTelptrShpCoords, temp);
+	_portalSeq = _staticres->loadRawData(kEobBasePortalSeqData, temp);
+	_mnDef = _staticres->loadRawData(kEobBaseManDef, temp);
+	_mnWord = _staticres->loadStrings(kEobBaseManWord, _mnNumWord);
+	_mnPrompt = _staticres->loadStrings(kEobBaseManPrompt, temp);
 
 	_monsterStepTable0 = (int8*) _staticres->loadRawData(_flags.gameID == GI_EOB2 ? kEobBaseMonsterStepTable02 : kEobBaseMonsterStepTable01, temp);
 	_monsterStepTable1 = (int8*)_staticres->loadRawData(kEobBaseMonsterStepTable1, temp);
@@ -1114,10 +1118,10 @@ void EobEngine::initStaticResource() {
 		p->experience = READ_LE_UINT16(ps);
 		ps += 2;
 		p->u30 = *ps++;
-		p->sound1 = *ps++;
-		p->sound2 = *ps++;
+		p->sound1 = (int8)*ps++;
+		p->sound2 = (int8)*ps++;
 		p->numRemoteAttacks = *ps++;
-		p->tuResist = *ps++;
+		p->tuResist = (int8)*ps++;
 		p->dmgModifierEvade = *ps++;
 	}
 }


Commit: bac0caeb0ff712fe9002985c44c1ea651b86e018
    https://github.com/scummvm/scummvm/commit/bac0caeb0ff712fe9002985c44c1ea651b86e018
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:13-08:00

Commit Message:
KYRA: (EOB) - lots of fixes towards EOB1 playability

also implement some new code (EOB1 portals, burning hands spell, etc.)

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    dists/engine-data/kyra.dat
    engines/kyra/chargen.cpp
    engines/kyra/eob1.cpp
    engines/kyra/eob1.h
    engines/kyra/eob2.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/magic_eob.cpp
    engines/kyra/resource.h
    engines/kyra/saveload_eob.cpp
    engines/kyra/scene_eob.cpp
    engines/kyra/screen.cpp
    engines/kyra/screen.h
    engines/kyra/screen_eob.cpp
    engines/kyra/screen_eob.h
    engines/kyra/script_eob.cpp
    engines/kyra/sequences_eob1.cpp
    engines/kyra/sequences_eob2.cpp
    engines/kyra/sprites_eob.cpp
    engines/kyra/staticres_eob.cpp
    engines/kyra/timer_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index 582516b..a646bee 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -332,11 +332,13 @@ const ExtractFilename extractFilenames[] = {
 	{ kEobBaseDscDoorScaleMult5, kTypeRawData, false },
 	{ kEobBaseDscDoorScaleMult6, kTypeRawData, false },
 	{ kEobBaseDscDoorType5Offs, kTypeRawData, false },
+	{ kEobBaseDscDoorXE, kTypeRawData, false },
 	{ kEobBaseDscDoorY1, kTypeRawData, false },
 	{ kEobBaseDscDoorY3, kTypeRawData, false },
 	{ kEobBaseDscDoorY4, kTypeRawData, false },
 	{ kEobBaseDscDoorY5, kTypeRawData, false },
 	{ kEobBaseDscDoorY6, kTypeRawData, false },
+	{ kEobBaseDscDoorY7, kTypeRawData, false },
 	{ kEobBaseDscDoorCoordsExt, kLolTypeRaw16, false },
 
 	{ kEobBaseDscItemPosIndex, kTypeRawData, false },
@@ -401,6 +403,7 @@ const ExtractFilename extractFilenames[] = {
 	{ kEobBaseSpellProperties, kTypeRawData, false },
 	{ kEobBaseMagicFlightProps, kTypeRawData, false },
 	{ kEobBaseTurnUndeadEffect, kTypeRawData, false },
+	{ kEobBaseBurningHandsDest, kTypeRawData, false },
 
 	// EYE OF THE BEHOLDER I
 	{ kEob1MainMenuStrings, kTypeStringList, true },
@@ -1516,6 +1519,8 @@ const char *getIdString(const int id) {
 		return "kEobBaseDscDoorScaleMult6";
 	case kEobBaseDscDoorType5Offs:
 		return "kEobBaseDscDoorType5Offs";
+	case kEobBaseDscDoorXE:
+		return "kEobBaseDscDoorXE";
 	case kEobBaseDscDoorY1:
 		return "kEobBaseDscDoorY1";
 	case kEobBaseDscDoorY3:
@@ -1526,6 +1531,8 @@ const char *getIdString(const int id) {
 		return "kEobBaseDscDoorY5";
 	case kEobBaseDscDoorY6:
 		return "kEobBaseDscDoorY6";
+	case kEobBaseDscDoorY7:
+		return "kEobBaseDscDoorY7";
 	case kEobBaseDscDoorCoordsExt:
 		return "kEobBaseDscDoorCoordsExt";
 	case kEobBaseDscItemPosIndex:
@@ -1635,6 +1642,8 @@ const char *getIdString(const int id) {
 		return "kEobBaseMagicFlightProps";
 	case kEobBaseTurnUndeadEffect:
 		return "kEobBaseTurnUndeadEffect";
+	case kEobBaseBurningHandsDest:
+		return "kEobBaseBurningHandsDest";
 	case kEob1MainMenuStrings:
 		return "kEob1MainMenuStrings";
 	case kEob1DoorShapeDefs:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index ebaff50..a7b53b4 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -332,11 +332,13 @@ enum kExtractID {
 	kEobBaseDscDoorScaleMult5,
 	kEobBaseDscDoorScaleMult6,
 	kEobBaseDscDoorType5Offs,
+	kEobBaseDscDoorXE,
 	kEobBaseDscDoorY1,
 	kEobBaseDscDoorY3,
 	kEobBaseDscDoorY4,
 	kEobBaseDscDoorY5,
 	kEobBaseDscDoorY6,
+	kEobBaseDscDoorY7,
 	kEobBaseDscDoorCoordsExt,
 
 	kEobBaseDscItemPosIndex,
@@ -402,6 +404,7 @@ enum kExtractID {
 	kEobBaseSpellProperties,
 	kEobBaseMagicFlightProps,
 	kEobBaseTurnUndeadEffect,
+	kEobBaseBurningHandsDest,
 
 	kEob1MainMenuStrings,
 	kEob1DoorShapeDefs,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 6e1503b..000c350 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1189,6 +1189,7 @@ const int eob1FloppyNeed[] = {
 	kEobBaseSpellProperties,
 	kEobBaseMagicFlightProps,
 	kEobBaseTurnUndeadEffect,
+	kEobBaseBurningHandsDest,
 
 	kLolEobCommonDscDoorShapeIndex,
 	kEobBaseWllFlagPreset,
@@ -1200,12 +1201,13 @@ const int eob1FloppyNeed[] = {
 	kEobBaseDscDoorScaleMult4,
 	kEobBaseDscDoorScaleMult5,
 	kEobBaseDscDoorScaleMult6,
+	kEobBaseDscDoorXE,
 	kEobBaseDscDoorY1,
-	kLolEobCommonDscDoorY2,
 	kEobBaseDscDoorY3,
 	kEobBaseDscDoorY4,
 	kEobBaseDscDoorY5,
 	kEobBaseDscDoorY6,
+	kEobBaseDscDoorY7,
 	kEobBaseDscDoorCoordsExt,
 
 	kEobBaseDscItemPosIndex,
@@ -1408,6 +1410,7 @@ const int eob2FloppyNeed[] = {
 	kEobBaseSpellProperties,
 	kEobBaseMagicFlightProps,
 	kEobBaseTurnUndeadEffect,
+	kEobBaseBurningHandsDest,
 
 	kLolEobCommonDscDoorShapeIndex,
 	kEobBaseWllFlagPreset,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index e27c6ed..a92c097 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -2001,6 +2001,11 @@ const ExtractEntrySearchData kEobBaseDscDoorType5OffsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEobBaseDscDoorXEProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000020, 0x0000010F, { { 0x7B, 0x7D, 0x03, 0xDE, 0x33, 0x95, 0xB8, 0xFD, 0xAD, 0x72, 0x44, 0x7D, 0x47, 0xFE, 0x04, 0x3D } } } },
+	EXTRACT_END_ENTRY
+};
+
 const ExtractEntrySearchData kEobBaseDscDoorY1Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x000000D7, { { 0x25, 0xAE, 0xF4, 0x99, 0xE8, 0x97, 0x47, 0xAE, 0x75, 0xF3, 0xA9, 0x70, 0x4C, 0x70, 0xF3, 0x11 } } } },	// EOB 1
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x000000D8, { { 0xB4, 0xAA, 0x0D, 0x91, 0x58, 0x22, 0x16, 0xCF, 0xC5, 0x9D, 0x8D, 0xA1, 0xB4, 0x40, 0x83, 0x0E } } } },	// EOB 2
@@ -2027,6 +2032,11 @@ const ExtractEntrySearchData kEobBaseDscDoorY6Provider[] = {
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEobBaseDscDoorY7Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x000000DA, { { 0xA9, 0x24, 0x71, 0x8A, 0x18, 0x24, 0x6D, 0x0A, 0x65, 0x12, 0xBB, 0x1F, 0xE7, 0x95, 0xC5, 0xA4 } } } },
+	EXTRACT_END_ENTRY
+};
+
 const ExtractEntrySearchData kEobBaseDscDoorCoordsExtProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000048, 0x00000C8E, { { 0x2E, 0x0E, 0xB2, 0xAC, 0xE7, 0x0F, 0xDF, 0x38, 0xDF, 0x92, 0xB7, 0xB5, 0xA2, 0xFD, 0x40, 0x2D } } } },
 	EXTRACT_END_ENTRY
@@ -2340,7 +2350,14 @@ const ExtractEntrySearchData kEobBaseMagicFlightPropsProvider[] = {
 };
 
 const ExtractEntrySearchData kEobBaseTurnUndeadEffectProvider[] = {
-	{ UNK_LANG, kPlatformUnknown, { 0x0000008C, 0x00002E8B, { { 0x96, 0x15, 0x61, 0x12, 0x43, 0xCF, 0x3A, 0x84, 0x1A, 0x89, 0xB5, 0x32, 0x0D, 0xB3, 0x20, 0x67 } } } },
+	{ UNK_LANG, kPlatformPC, { 0x0000008C, 0x00002E8B, { { 0x96, 0x15, 0x61, 0x12, 0x43, 0xCF, 0x3A, 0x84, 0x1A, 0x89, 0xB5, 0x32, 0x0D, 0xB3, 0x20, 0x67 } } } },
+
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseBurningHandsDestProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000008, 0x0000000C, { { 0x61, 0xD7, 0xAB, 0xE1, 0x56, 0x54, 0x51, 0x5B, 0xD9, 0x59, 0x2D, 0x3D, 0xAE, 0xA4, 0x49, 0x31 } } } },	// EOB1
+	{ UNK_LANG, kPlatformPC, { 0x00000020, 0x0000003E, { { 0xA5, 0x8C, 0xCA, 0x13, 0xED, 0x0F, 0xB7, 0xA2, 0xD7, 0x9C, 0xCD, 0x11, 0x65, 0x11, 0x4B, 0xD8 } } } },	// EOB2
 
 	EXTRACT_END_ENTRY
 };
@@ -3775,11 +3792,13 @@ const ExtractEntry extractProviders[] = {
 	{ kEobBaseDscDoorScaleMult5, kEobBaseDscDoorScaleMult5Provider },
 	{ kEobBaseDscDoorScaleMult6, kEobBaseDscDoorScaleMult6Provider },
 	{ kEobBaseDscDoorType5Offs, kEobBaseDscDoorType5OffsProvider },
+	{ kEobBaseDscDoorXE, kEobBaseDscDoorXEProvider },
 	{ kEobBaseDscDoorY1, kEobBaseDscDoorY1Provider },
 	{ kEobBaseDscDoorY3, kEobBaseDscDoorY3Provider },
 	{ kEobBaseDscDoorY4, kEobBaseDscDoorY4Provider },
 	{ kEobBaseDscDoorY5, kEobBaseDscDoorY5Provider },
 	{ kEobBaseDscDoorY6, kEobBaseDscDoorY6Provider },
+	{ kEobBaseDscDoorY7, kEobBaseDscDoorY7Provider },
 	{ kEobBaseDscDoorCoordsExt, kEobBaseDscDoorCoordsExtProvider },
 	{ kEobBaseDscItemPosIndex, kEobBaseDscItemPosIndexProvider },
 	{ kEobBaseDscItemShpX, kEobBaseDscItemShpXProvider },
@@ -3843,6 +3862,7 @@ const ExtractEntry extractProviders[] = {
 	{ kEobBaseSpellProperties, kEobBaseSpellPropertiesProvider },
 	{ kEobBaseMagicFlightProps, kEobBaseMagicFlightPropsProvider },
 	{ kEobBaseTurnUndeadEffect, kEobBaseTurnUndeadEffectProvider },
+	{ kEobBaseBurningHandsDest, kEobBaseBurningHandsDestProvider },
 
 	{ kEob1MainMenuStrings, kEob1MainMenuStringsProvider },
 	{ kEob1DoorShapeDefs, kEob1DoorShapeDefsProvider },
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index 7cbd3b6..494a395 100644
Binary files a/dists/engine-data/kyra.dat and b/dists/engine-data/kyra.dat differ
diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index c8040ed..6814129 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -236,7 +236,7 @@ bool CharacterGenerator::start(EobCharacter *characters, uint8 ***faceShapes) {
 }
 
 void CharacterGenerator::init() {
-	_screen->loadEobBitmap("CHARGENA", 3, 3);
+	_screen->loadShapeSetBitmap("CHARGENA", 3, 3);
 	if (_faceShapes) {
 		for (int i = 0; i < 44; i++)
 			delete[] _faceShapes[i];
@@ -248,8 +248,8 @@ void CharacterGenerator::init() {
 		_faceShapes[i] = _screen->encodeShape((i % 10) << 2, (i / 10) << 5, 4, 32, true);
 	_screen->_curPage = 0;
 
-	_screen->loadEobCpsFileToPage("CHARGEN", 0, 3, 3, 0);
-	_screen->loadEobBitmap("CHARGENB", 3, 3);
+	_screen->loadEobBitmap("CHARGEN", 0, 3, 3, 0);
+	_screen->loadShapeSetBitmap("CHARGENB", 3, 3);
 	if (_chargenMagicShapes) {
 		for (int i = 0; i < 10; i++)
 			delete[] _chargenMagicShapes[i];
diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
index 9505231..762b2d1 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -78,6 +78,9 @@ Common::Error EobEngine::init() {
 
 	_scriptTimersCount = 1;
 
+	//_wllWallFlags[132] = 0x1f;
+	_wllWallFlags[133] = 1;
+
 	return Common::kNoError;
 }
 
@@ -341,8 +344,25 @@ void EobEngine::replaceMonster(int unit, uint16 block, int pos, int dir, int typ
 	}
 }
 
+void EobEngine::updateScriptTimersExtra() {
+	int cnt = 0;
+	for (int i = 1; i < 30; i++) {
+		if (_monsters[i].hitPointsCur <= 0)
+			cnt++;
+	}
+
+	if (!cnt) {
+		for (int i = 1; i < 30; i++) {
+			if (getBlockDistance(_monsters[i].block, _currentBlock) > 3) {
+				killMonster(&_monsters[i], true);
+				break;
+			}
+		}
+	}
+}
+
 void EobEngine::loadDoorShapes(int doorType1, int shapeId1, int doorType2, int shapeId2) {
-	_screen->loadEobBitmap("DOOR", 5, 3);
+	_screen->loadShapeSetBitmap("DOOR", 5, 3);
 	_screen->_curPage = 2;
 
 	if (doorType1 != 0xff) {
@@ -351,8 +371,8 @@ void EobEngine::loadDoorShapes(int doorType1, int shapeId1, int doorType2, int s
 			_doorShapes[shapeId1 + i] = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
 			enc = &_doorSwitchShapeEncodeDefs[(doorType1 * 3 + i) << 2];
 			_doorSwitches[shapeId1 + i].shp = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
-			_doorSwitches[shapeId1 + i].x = _doorSwitchCoords[doorType1 << 1];
-			_doorSwitches[shapeId1 + i].y = _doorSwitchCoords[(doorType1 << 1) + 1];
+			_doorSwitches[shapeId1 + i].x = _doorSwitchCoords[doorType1 * 6 + i * 2];
+			_doorSwitches[shapeId1 + i].y = _doorSwitchCoords[doorType1 * 6 + i * 2 + 1];
 		}
 	}
 
@@ -362,8 +382,8 @@ void EobEngine::loadDoorShapes(int doorType1, int shapeId1, int doorType2, int s
 			_doorShapes[shapeId2 + i] = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
 			enc = &_doorSwitchShapeEncodeDefs[(doorType2 * 3 + i) << 2];
 			_doorSwitches[shapeId2 + i].shp = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
-			_doorSwitches[shapeId2 + i].x = _doorSwitchCoords[doorType2 << 1];
-			_doorSwitches[shapeId2 + i].y = _doorSwitchCoords[(doorType2 << 1) + 1];
+			_doorSwitches[shapeId2 + i].x = _doorSwitchCoords[doorType2 * 6 + i * 2];
+			_doorSwitches[shapeId2 + i].y = _doorSwitchCoords[doorType2 * 6 + i * 2+ 1];
 		}
 	}
 
@@ -383,7 +403,7 @@ void EobEngine::drawDoorIntern(int type, int index, int x, int y, int w, int wal
 		case 4:
 		case 5:
 		case 6:
-			y = _dscDoorY2[mDim] - shp[1];
+			y = _dscDoorY6[mDim] - shp[1];
 			d1 = _dscDoorCoordsExt[index << 1] >> 3;
 			d2 = _dscDoorCoordsExt[(index << 1) + 1] >> 3;
 			if (_shpDmX1 > d1)
@@ -403,7 +423,7 @@ void EobEngine::drawDoorIntern(int type, int index, int x, int y, int w, int wal
 		case 7:
 		case 8:
 		case 9:
-			y = _dscDoorY3[mDim] - _doorShapes[shapeIndex + 3][1];
+			y = _dscDoorY7[mDim] - _doorShapes[shapeIndex + 3][1];
 			d1 = x - (_doorShapes[shapeIndex + 3][2] << 2);
 			x -= (shp[2] << 2);
 			drawBlockObject(0, 2, _doorShapes[shapeIndex + 3], d1, y, 5);
diff --git a/engines/kyra/eob1.h b/engines/kyra/eob1.h
index 8b805c0..21543dd 100644
--- a/engines/kyra/eob1.h
+++ b/engines/kyra/eob1.h
@@ -81,6 +81,7 @@ private:
 
 	// Monsters
 	void replaceMonster(int unit, uint16 block, int d, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem);
+	void updateScriptTimersExtra();
 
 	// Level
 	void loadDoorShapes(int doorType1, int shapeId1, int doorType2, int shapeId2);
@@ -94,6 +95,7 @@ private:
 	const uint8 *_dscDoorY4;
 	const uint8 *_dscDoorY5;
 	const uint8 *_dscDoorY6;
+	const uint8 *_dscDoorY7;
 
 	const uint8 *_doorShapeEncodeDefs;
 	const uint8 *_doorSwitchShapeEncodeDefs;
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index 2b4cf46..9efc558 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -159,7 +159,7 @@ void DarkMoonEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
 
 void DarkMoonEngine::generateMonsterPalettes(const char *file, int16 monsterIndex) {
 	int cp = _screen->setCurPage(2);
-	_screen->loadEobBitmap(file, 3, 3);
+	_screen->loadShapeSetBitmap(file, 3, 3);
 	uint8 tmpPal[16];
 	uint8 newPal[16];
 
@@ -291,7 +291,7 @@ bool DarkMoonEngine::killMonsterExtra(EobMonsterInPlay *m) {
 }
 
 const uint8 *DarkMoonEngine::loadDoorShapes(const char *filename, int doorIndex, const uint8 *shapeDefs) {
-	_screen->loadEobBitmap(filename, 3, 3);
+	_screen->loadShapeSetBitmap(filename, 3, 3);
 	for (int i = 0; i < 3; i++) {
 		_doorShapes[doorIndex * 3 + i] = _screen->encodeShape(READ_LE_UINT16(shapeDefs), READ_LE_UINT16(shapeDefs + 2), READ_LE_UINT16(shapeDefs + 4), READ_LE_UINT16(shapeDefs + 6));
 		shapeDefs += 8;
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index f323dd4..3e1001d 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -98,6 +98,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_dscDoorScaleMult2 = 0;
 	_dscDoorScaleMult3 = 0;
 	_dscDoorY1 = 0;
+	_dscDoorXE = 0;
 
 	_color9 = 17;
 	_color10 = 23;
@@ -137,6 +138,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_spellAnimBuffer = 0;
 	_clericSpellOffset = 0;
 	_restPartyElapsedTime = 0;
+	_allowSkip = false;
 
 	_rrCount = 0;
 	memset(_rrNames, 0, 10 * sizeof(const char*));
@@ -980,7 +982,7 @@ void EobCoreEngine::neutralizePoison(int character) {
 }
 
 void EobCoreEngine::npcSequence(int npcIndex) {
-	_screen->loadEobBitmap("OUTTAKE", 5, 3);
+	_screen->loadShapeSetBitmap("OUTTAKE", 5, 3);
 	_screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 6, Screen::CR_NO_P_CHECK);
 
 	drawNpcScene(npcIndex);
@@ -1019,7 +1021,7 @@ void EobCoreEngine::initNpc(int npcIndex) {
 		c->inventory[i] = duplicateItem(c->inventory[i]);
 	}
 
-	_screen->loadEobBitmap(_flags.gameID == GI_EOB2 ? "OUTPORTS" : "OUTTAKE", 3, 3);
+	_screen->loadShapeSetBitmap(_flags.gameID == GI_EOB2 ? "OUTPORTS" : "OUTTAKE", 3, 3);
 	_screen->_curPage = 2;
 	c->faceShape = _screen->encodeShape(npcIndex << 2, _flags.gameID == GI_EOB2 ? 0 : 160, 4, 32, true);
 	_screen->_curPage = 0;
@@ -1257,7 +1259,7 @@ void EobCoreEngine::drawSequenceBitmap(const char *file, int destRect, int x1, i
 	if (scumm_stricmp(_dialogueLastBitmap, file)) {
 		if (!destRect) {
 			if (!(flags & 1)) {
-				_screen->loadEobCpsFileToPage("BORDER", 0, 3, 3, 2);
+				_screen->loadEobBitmap("BORDER", 0, 3, 3, 2);
 				_screen->copyRegion(0, 0, 0, 0, 184, 121, 2, page, Screen::CR_NO_P_CHECK);
 			} else {
 				_screen->copyRegion(0, 0, 0, 0, 184, 121, 0, page, Screen::CR_NO_P_CHECK);
@@ -1267,7 +1269,7 @@ void EobCoreEngine::drawSequenceBitmap(const char *file, int destRect, int x1, i
 				_screen->copyRegion(0, 0, 0, 0, 184, 121, 2, 6, Screen::CR_NO_P_CHECK);
 		}
 
-		_screen->loadEobCpsFileToPage(file, 0, 3, 3, 2);
+		_screen->loadEobBitmap(file, 0, 3, 3, 2);
 		strcpy(_dialogueLastBitmap, file);
 	}
 
@@ -1407,16 +1409,12 @@ bool EobCoreEngine::restParty_checkSpellsToLearn() {
 	return false;
 }
 
-void EobCoreEngine::restParty_npc() {
-
-}
-
 bool EobCoreEngine::restParty_extraAbortCondition() {
 	return false;
 }
 
 void EobCoreEngine::delay(uint32 millis, bool, bool) {
-	while (millis && !shouldQuit() && !skipFlag()) {
+	while (millis && !shouldQuit() && !(_allowSkip && skipFlag())) {
 		updateInput();
 		uint32 step = MIN<uint32>(millis, (_tickLength / 5));
 		_system->delayMillis(step);
@@ -1501,7 +1499,75 @@ int EobCoreEngine::countResurrectionCandidates() {
 }
 
 void EobCoreEngine::seq_portal() {
-	//_portalSeq
+	releaseDoorShapes();
+	releaseMonsterShapes(0, 36);
+	releaseDecorations();
+
+	uint8 *shapes1[5];
+	uint8 *shapes2[5];
+	uint8 *shapes3[5];
+	uint8 *shape0;
+
+	_screen->loadShapeSetBitmap("PORTALA", 5, 3);
+
+	for (int i = 0; i < 5; i++) {
+		shapes1[i] = _screen->encodeShape(i * 3, 0, 3, 75);
+		shapes2[i] = _screen->encodeShape(i * 3, 80, 3, 75);
+		shapes3[i] = _screen->encodeShape(15, i * 18, 15, 18);
+	}
+
+	shape0 = _screen->encodeShape(30, 0, 8, 77);
+	_screen->loadEobBitmap("PORTALB", 0, 5, 3, 2);
+
+	snd_playSoundEffect(33);
+	snd_playSoundEffect(19);
+	_screen->copyRegion(24, 0, 24, 0, 144, 104, 2, 5, Screen::CR_NO_P_CHECK);
+	_screen->copyRegion(24, 0, 24, 0, 144, 104, 0, 2, Screen::CR_NO_P_CHECK);
+	_screen->drawShape(2, shapes3[0], 28, 9, 0);
+	_screen->drawShape(2, shapes1[0], 34, 28, 0);
+	_screen->drawShape(2, shapes2[0], 120, 28, 0);
+	_screen->drawShape(2, shape0, 56, 27, 0);
+	_screen->crossFadeRegion(24, 0, 24, 0, 144, 104, 2, 0);
+	_screen->copyRegion(24, 0, 24, 0, 144, 104, 5, 2, Screen::CR_NO_P_CHECK);
+	delay(30 * _tickLength);
+
+	for (const int8 *pos = _portalSeq; *pos > -1 && !shouldQuit(); ) {
+		int s = *pos++;
+		_screen->drawShape(0, shapes3[s], 28, 9, 0);
+		_screen->drawShape(0, shapes1[s], 34, 28, 0);
+		_screen->drawShape(0, shapes2[s], 120, 28, 0);
+
+		if ((s == 1) && (pos >= _portalSeq + 3)) {
+			if (*(pos - 3) == 0) {
+				snd_playSoundEffect(24);
+				snd_playSoundEffect(86);
+			}
+		}
+
+		s = *pos++;
+		if (s == 0) {
+			_screen->drawShape(0, shape0, 56, 27, 0);
+		} else {
+			s--;
+			_screen->copyRegion((s % 5) << 6, s / 5 * 77, 56, 27, 64, 77, 2, 0, Screen::CR_NO_P_CHECK);
+			if (s == 0)
+				snd_playSoundEffect(31);
+			else if (s == 3) {
+				if (*(pos - 2) == 3)
+					snd_playSoundEffect(90);
+			}
+		}		
+		
+		_screen->updateScreen();
+		delay(2 * _tickLength);
+	}
+	
+	delete[] shape0;
+	for (int i = 0; i < 5; i++) {
+		delete[] shapes1[i];
+		delete[] shapes2[i];
+		delete[] shapes3[i];
+	}
 }
 
 bool EobCoreEngine::checkPassword() {
@@ -1830,10 +1896,13 @@ bool EobCoreEngine::monsterAttackHitTest(EobMonsterInPlay *m, int charIndex) {
 
 	int r = rollDice(1, 20);
 	if (r != 20) {
+		// Prot from evil
 		if (_characters[charIndex].effectFlags & 0x800)
 			r -= 2;
+		// blur
 		if (_characters[charIndex].effectFlags & 0x10)
 			r -= 2;
+		// prayer
 		if (_partyEffectFlags & 0x8000)
 			r--;
 	}
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 7ebc883..33b4a2f 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -508,6 +508,7 @@ protected:
 	void updateMonsters(int unit);
 	void updateMonsterDest(EobMonsterInPlay *m);
 	void updateMonsterDest2(EobMonsterInPlay *m);
+	void updateAllMonsterDests();
 	void turnFriendlyMonstersHostile();
 	int getNextMonsterDirection(int curBlock, int destBlock);
 	int getNextMonsterPos(EobMonsterInPlay *m, int block);
@@ -619,11 +620,12 @@ protected:
 	const uint8 *_dscDoorScaleMult2;
 	const uint8 *_dscDoorScaleMult3;
 	const uint8 *_dscDoorY1;
+	const uint8 *_dscDoorXE;
 
 	const uint8 *_wllFlagPreset;
 	int _wllFlagPresetSize;
 	const uint8 *_teleporterShapeCoords;
-	const uint8 *_portalSeq;
+	const int8 *_portalSeq;
 
 	// Script
 	void runLevelScript(int block, int flags);
@@ -633,6 +635,7 @@ protected:
 
 	const uint8 *initScriptTimers(const uint8 *pos);
 	void updateScriptTimers();
+	virtual void updateScriptTimersExtra() {}
 
 	EobInfProcessor *_inf;
 	int _stepCounter;
@@ -803,7 +806,7 @@ protected:
 	int restParty_getCharacterWithLowestHp();
 	bool restParty_checkHealSpells(int charIndex);
 	bool restParty_checkSpellsToLearn();
-	virtual void restParty_npc();
+	virtual void restParty_npc() {}
 	virtual bool restParty_extraAbortCondition();
 
 	// misc
@@ -840,6 +843,8 @@ protected:
 	const char *_rrNames[10];
 	int8 _rrId[10];
 
+	bool _allowSkip;
+
 	Screen_Eob *_screen;
 	GUI_Eob *_gui;
 
@@ -881,6 +886,7 @@ protected:
 	int _dstMonsterIndex;
 	bool _preventMonsterFlash;
 	int16 _foundMonstersArray[5];
+	int8 _monsterBlockPosArray[6];
 
 	// magic
 	void useMagicBookOrSymbol(int charIndex, int type);
@@ -969,6 +975,7 @@ protected:
 	void spellCallback_start_heal();
 	void spellCallback_start_layOnHands();
 	void spellCallback_start_turnUndead();
+	bool spellCallback_end_kuotoaAttack(EobFlyingObject *fo);
 	bool spellCallback_end_unk1Passive(EobFlyingObject *fo);
 	bool spellCallback_end_unk2Passive(EobFlyingObject *fo);
 	bool spellCallback_end_deathSpellPassive(EobFlyingObject *fo);
@@ -1038,6 +1045,7 @@ protected:
 
 	const uint8 *_magicFlightObjectProperties;
 	const uint8 *_turnUndeadEffect;
+	const uint8 *_burningHandsDest;
 
 	// Menu
 	EobMenuDef *_menuDefs;
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 9dec158..04b863c 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -150,7 +150,7 @@ Button *EobCoreEngine::gui_getButton(Button *buttonList, int index) {
 }
 
 void EobCoreEngine::gui_drawPlayField(bool refresh) {
-	_screen->loadEobCpsFileToPage("PLAYFLD", 0, 5, 3, 2);
+	_screen->loadEobBitmap("PLAYFLD", 0, 5, 3, 2);
 	int cp = _screen->setCurPage(2);
 	gui_drawCompass(true);
 
@@ -163,7 +163,7 @@ void EobCoreEngine::gui_drawPlayField(bool refresh) {
 	if (!_loading)
 		_screen->updateScreen();
 
-	_screen->loadEobCpsFileToPage("INVENT", 0, 5, 3, 2);
+	_screen->loadEobBitmap("INVENT", 0, 5, 3, 2);
 }
 
 void EobCoreEngine::gui_restorePlayField() {
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 3eb7591..12d2524 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -142,7 +142,7 @@ void EobCoreEngine::usePotion(int charIndex, int weaponSlot) {
 }
 
 void EobCoreEngine::useWand(int charIndex, int weaponSlot) {
-	int v = _items[_characters[charIndex].inventory[weaponSlot]].value - 1;
+	int v = _items[_characters[charIndex].inventory[weaponSlot]].value;
 	if (!v) {
 		_txt->printMessage(_wandStrings[0]);
 		return;
@@ -535,7 +535,7 @@ bool EobCoreEngine::magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int d
 			if (!fo->item && (_characters[c].effectFlags & 8)) {
 				res = true;
 			} else {
-				if ((_characters[c].flags & 1) && hitTest && !monsterAttackHitTest(&_monsters[0], c)) {
+				if ((_characters[c].flags & 1) && (!hitTest || monsterAttackHitTest(&_monsters[0], c))) {
 					int dmg = rollDice(dcTimes, dcPips, dcOffs) * level;
 					res = true;
 					calcAndInflictCharacterDamage(c, 0, 0, dmg, dmgFlag, s, dmgType);
@@ -638,7 +638,31 @@ void EobCoreEngine::spellCallback_start_armor() {
 }
 
 void EobCoreEngine::spellCallback_start_burningHands() {
+	static const int16 bX[] = { 0, 152, 24, 120, 56, 88 };
+	static const int8 bY[] = { 64, 64, 56, 56, 56, 56 };
 
+	for (int i = 0; i < 6; i++)
+		drawBlockObject(i & 1, 0, _firebeamShapes[(5 - i) >> 1], bX[i], bY[i], 0);
+	_screen->updateScreen();
+	delay(2 * _tickLength);
+	
+	int cl = getCharacterMageLevel(_openBookChar);
+	int bl = calcNewBlockPosition(_currentBlock, _currentDirection);
+
+	const int8 *pos = getMonsterBlockPositions(bl);
+	_preventMonsterFlash = true;
+
+	int numDest = (_flags.gameID == GI_EOB1) ? 2 : 6;
+	const uint8 *d = &_burningHandsDest[_currentDirection * (_flags.gameID == GI_EOB1 ? 2 : 8)];
+
+	for (int i = 0; i < numDest; i++, d++) {
+		if (pos[*d] == -1)
+			continue;
+		calcAndInflictMonsterDamage(&_monsters[pos[*d]], 1, 3, cl << 1, 0x21, 4, 0);
+	}
+
+	updateAllMonsterShapes();
+	_sceneUpdateRequired = true;
 }
 
 void EobCoreEngine::spellCallback_start_detectMagic() {
@@ -949,6 +973,10 @@ void EobCoreEngine::spellCallback_start_turnUndead() {
 	_preventMonsterFlash = false;
 }
 
+bool EobCoreEngine::spellCallback_end_kuotoaAttack(EobFlyingObject *fo) {
+	return magicObjectDamageHit(fo, 0, 0, 12, 1);
+}
+
 bool EobCoreEngine::spellCallback_end_unk1Passive(EobFlyingObject *fo) {
 	bool res = false;
 	if (_partyEffectFlags & 0x20000) {
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 0f1539b..f80fdd9 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -405,11 +405,13 @@ enum KyraResources {
 	kEobBaseDscDoorScaleMult5,
 	kEobBaseDscDoorScaleMult6,
 	kEobBaseDscDoorType5Offs,
+	kEobBaseDscDoorXE,
 	kEobBaseDscDoorY1,
 	kEobBaseDscDoorY3,
 	kEobBaseDscDoorY4,
 	kEobBaseDscDoorY5,
 	kEobBaseDscDoorY6,
+	kEobBaseDscDoorY7,
 	kEobBaseDscDoorCoordsExt,
 
 	kEobBaseDscItemPosIndex,
@@ -475,6 +477,7 @@ enum KyraResources {
 	kEobBaseSpellProperties,
 	kEobBaseMagicFlightProps,
 	kEobBaseTurnUndeadEffect,
+	kEobBaseBurningHandsDest,
 
 	kEob1MainMenuStrings,
 	kEob1DoorShapeDefs,
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index 43a230e..88f0c1c 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -205,7 +205,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 
 	setupCharacterTimers();
 
-	_screen->loadEobBitmap("CHARGENA", 3, 3);
+	_screen->loadShapeSetBitmap("CHARGENA", 3, 3);
 	for (int i = 0; i < 6; i++) {
 		EobCharacter *c = &_characters[i];
 		if (!c->flags || c->portrait < 0)
@@ -213,12 +213,12 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 		c->faceShape = _screen->encodeShape((c->portrait % 10) << 2, (c->portrait / 10) << 5, 4, 32, true);
 	}
 
-	_screen->loadEobBitmap(_flags.gameID == GI_EOB2 ? "OUTPORTS" : "OUTTAKE", 3, 3);
+	_screen->loadShapeSetBitmap(_flags.gameID == GI_EOB2 ? "OUTPORTS" : "OUTTAKE", 3, 3);
 	for (int i = 0; i < 6; i++) {
 		EobCharacter *c = &_characters[i];
 		if (!c->flags || c->portrait >= 0)
 			continue;
-		c->faceShape = _screen->encodeShape(-(c->portrait + 1), _flags.gameID == GI_EOB2 ? 0 : 160, 4, 32, true);
+		c->faceShape = _screen->encodeShape((-(c->portrait + 1)) << 2, _flags.gameID == GI_EOB2 ? 0 : 160, 4, 32, true);
 	}
 	_screen->_curPage = 0;
 
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index e6b3c26..4c1bb16 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -690,7 +690,7 @@ void EobCoreEngine::loadLevel(int level, int sub) {
 	}
 
 	loadVcnData(gfxFile.c_str(), 0);
-	_screen->loadEobCpsFileToPage("INVENT", 0, 5, 3, 2);
+	_screen->loadEobBitmap("INVENT", 0, 5, 3, 2);
 
 	enableSysTimer(2);
 	_sceneDrawPage1 = 2;
@@ -734,15 +734,13 @@ Common::String EobCoreEngine::initLevelData(int sub){
 			pos += 13;
 		}
 
-	////////	_screen->loadPalette(tmpStr, _screen->getPalette(0));
-
 		if (_flags.gameID == GI_EOB1) {
 			pos += 11;
 			_screen->setShapeFadeMode(0, false);
 			_screen->setShapeFadeMode(1, false);
 		}
-		else
-			_screen->loadPalette(tmpStr.c_str(), _screen->getPalette(0));
+		
+		_screen->loadPalette(tmpStr.c_str(), _screen->getPalette(0));
 
 		Palette backupPal(256);
 		backupPal.copy(_screen->getPalette(0), 224, 32, 224);
@@ -796,9 +794,8 @@ Common::String EobCoreEngine::initLevelData(int sub){
 
 	for (int i = 0; i < 2; i++) {
 		if (_flags.gameID == GI_EOB1) {
-			if (*pos == 0xFF)
-				continue;
-			loadMonsterShapes((const char *)(pos + 1), i * 18, false, *pos * 18);
+			if (*pos != 0xFF)
+				loadMonsterShapes((const char *)(pos + 1), i * 18, false, *pos * 18);
 			pos += 13;
 		} else {
 			if (*pos++ != 0xEC)
@@ -880,7 +877,7 @@ void EobCoreEngine::loadBlockProperties(const char *mazFile) {
 }
 
 void EobCoreEngine::loadDecorations(const char *cpsFile, const char *decFile) {
-	_screen->loadEobBitmap(cpsFile, 3, 3);
+	_screen->loadShapeSetBitmap(cpsFile, 3, 3);
 	Common::SeekableReadStream *s = _res->createReadStream(decFile);
 
 	_levelDecorationDataSize = s->readUint16LE();
@@ -1142,7 +1139,10 @@ void EobCoreEngine::drawDecorations(int index) {
 int EobCoreEngine::calcNewBlockPositionAndTestPassability(uint16 curBlock, uint16 direction) {
 	uint16 b = calcNewBlockPosition(curBlock, direction);
 	int w = _levelBlockProperties[b].walls[direction ^ 2];
+	
 	int f = _wllWallFlags[w];
+	if (!f)
+		assert (w < (_flags.gameID == GI_EOB1 ? 70 : 80));
 
 	if (w == 74 && _currentBlock == curBlock) {
 		for (int i = 0; i < 5; i++) {
@@ -1163,7 +1163,7 @@ void EobCoreEngine::notifyBlockNotPassable() {
 }
 
 void EobCoreEngine::moveParty(uint16 block) {
-	//processMonstersUnk1();
+	updateAllMonsterDests();
 	uint16 old = _currentBlock;
 	_currentBlock = block;
 
@@ -1176,10 +1176,10 @@ void EobCoreEngine::moveParty(uint16 block) {
 
 	runLevelScript(block, 1);
 
-	if (_levelBlockProperties[block].walls[0] == 26)
+	if (_flags.gameID == GI_EOB2 && _levelBlockProperties[block].walls[0] == 26)
 		memset(_levelBlockProperties[block].walls, 0, 4);
 
-	//processMonstersUnk1();
+	updateAllMonsterDests();
 	_stepCounter++;
 	//_keybControlUnk = -1;
 	_sceneUpdateRequired = true;
@@ -1192,6 +1192,14 @@ int EobCoreEngine::clickedDoorSwitch(uint16 block, uint16 direction) {
 	SpriteDecoration *d = &_doorSwitches[((v > 12 && v < 23) || v == 31) ? 3 : 0];
 	int x1 = d->x + _dscShapeCoords[138] - 4;
 	int y1 = d->y - 4;
+
+	if (_flags.gameID == GI_EOB1 && _currentLevel >= 4 && _currentLevel <= 6) {
+		if (v >= 30)
+			x1 += 4;
+		else
+			x1 += ((v - _dscDoorXE[v]) * 9);
+	}
+	
 	if (!posWithinRect(_mouseX, _mouseY, x1, y1, x1 + (d->shp[2] << 3) + 8, y1 + d->shp[1] + 8) && (_clickedSpecialFlag == 0x40))
 		return clickedDoorNoPry(block, direction);
 
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index 5e424b4..79edfe9 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -2971,6 +2971,9 @@ bool Screen::loadPalette(const char *filename, Palette &pal) {
 	} else if (_vm->gameFlags().platform == Common::kPlatformPC98 && _use16ColorMode) {
 		numCols = stream->size() / Palette::kPC98BytesPerColor;
 		pal.loadPC98Palette(*stream, 0, MIN(maxCols, numCols));
+	} else if (_vm->gameFlags().gameID == GI_EOB1) {		
+		numCols = stream->size() / Palette::kVGABytesPerColor;
+		pal.loadVGAPalette7bit(*stream, 0, MIN(maxCols, numCols));
 	} else {
 		numCols = stream->size() / Palette::kVGABytesPerColor;
 		pal.loadVGAPalette(*stream, 0, MIN(maxCols, numCols));
@@ -3438,6 +3441,18 @@ void Palette::loadVGAPalette(Common::ReadStream &stream, int startIndex, int col
 	stream.read(_palData + startIndex * 3, colors * 3);
 }
 
+void Palette::loadVGAPalette7bit(Common::ReadStream &stream, int startIndex, int colors) {
+	assert(startIndex + colors <= _numColors);
+
+	stream.read(_palData + startIndex * 3, colors * 3);
+	uint8 *pos = _palData + startIndex * 3;
+	for (int i = 0 ; i < colors; i++) {
+		*pos++ &= 0x3f;
+		*pos++ &= 0x3f;
+		*pos++ &= 0x3f;
+	}
+}
+
 void Palette::loadAmigaPalette(Common::ReadStream &stream, int startIndex, int colors) {
 	assert(startIndex + colors <= _numColors);
 
diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h
index cb7d73d..d4f0dc9 100644
--- a/engines/kyra/screen.h
+++ b/engines/kyra/screen.h
@@ -252,6 +252,11 @@ public:
 	void loadVGAPalette(Common::ReadStream &stream, int startIndex, int colors);
 
 	/**
+	 * Load a VGA palette from the given stream masking out the upper bit.
+	 */
+	void loadVGAPalette7bit(Common::ReadStream &stream, int startIndex, int colors);
+
+	/**
 	 * Load a AMIGA palette from the given stream.
 	 */
 	void loadAmigaPalette(Common::ReadStream &stream, int startIndex, int colors);
diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp
index d3c2187..ccbc2a1 100644
--- a/engines/kyra/screen_eob.cpp
+++ b/engines/kyra/screen_eob.cpp
@@ -145,12 +145,15 @@ void Screen_Eob::printShadedText(const char *string, int x, int y, int col1, int
 	printText(string, x, y, col1, 0);
 }
 
-void Screen_Eob::loadEobBitmap(const char *file, int tempPage, int destPage) {
-	loadEobCpsFileToPage(file, 0, tempPage, destPage, -1);
+void Screen_Eob::loadShapeSetBitmap(const char *file, int tempPage, int destPage) {
+	loadEobBitmap(file, 0, tempPage, destPage, -1);
 	_curPage = 2;
 }
 
-void Screen_Eob::loadEobCpsFileToPage(const char *file, const uint8 *ditheringData, int tempPage, int destPage, int copyToPage) {
+void Screen_Eob::loadEobBitmap(const char *file, const uint8 *ditheringData, int tempPage, int destPage, int copyToPage) {
+	//Common::String tmp = file;
+	//if (_vm->game() == GI_EOB1 && tmp.equalsIgnoreCase("spider"))
+	//	tmp += "1";
 	Common::String tmp = Common::String::format("%s.CPS", file);
 	Common::SeekableReadStream *s = _vm->resource()->createReadStream(tmp);
 	bool loadAlternative = false;
@@ -170,7 +173,7 @@ void Screen_Eob::loadEobCpsFileToPage(const char *file, const uint8 *ditheringDa
 		tmp.setChar('X', 0);
 		s = _vm->resource()->createReadStream(tmp);
 		if (!s)
-			error("Screen_Eob::loadEobCpsFileToPage(): CPS file loading failed.");
+			error("Screen_Eob::loadEobBitmap(): CPS file loading failed.");
 		s->seek(768);
 		loadFileDataToPage(s, destPage, 64000);
 		delete s;
diff --git a/engines/kyra/screen_eob.h b/engines/kyra/screen_eob.h
index 19cbdb5..909a561 100644
--- a/engines/kyra/screen_eob.h
+++ b/engines/kyra/screen_eob.h
@@ -51,8 +51,8 @@ public:
 	void loadFileDataToPage(Common::SeekableReadStream *s, int pageNum, uint32 size);
 
 	void printShadedText(const char *string, int x, int y, int col1, int col2);
-	void loadEobCpsFileToPage(const char *file, const uint8 *ditheringData, int tempPage, int destPage, int copyToPage);
-	void loadEobBitmap(const char *file, int tempPage, int destPage);
+	void loadEobBitmap(const char *file, const uint8 *ditheringData, int tempPage, int destPage, int copyToPage);
+	void loadShapeSetBitmap(const char *file, int tempPage, int destPage);
 
 	uint8 *encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool flag = false);
 	void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd = -1, int flags = 0, ...);
diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp
index 7159700..2b86aa8 100644
--- a/engines/kyra/script_eob.cpp
+++ b/engines/kyra/script_eob.cpp
@@ -54,7 +54,7 @@ const uint8 *EobCoreEngine::initScriptTimers(const uint8 *pos) {
 	while (((int16)READ_LE_UINT16(pos)) != -1) {
 		_scriptTimers[_scriptTimersCount].func = READ_LE_UINT16(pos);
 		pos += 2;
-		uint16 ticks = (int16)READ_LE_UINT16(pos) * 18;
+		uint16 ticks = READ_LE_UINT16(pos) * 18;
 		_scriptTimers[_scriptTimersCount].ticks = ticks;
 		pos += 2;
 		_scriptTimers[_scriptTimersCount++].next = _system->getMillis() + ticks * _tickLength;
@@ -64,20 +64,26 @@ const uint8 *EobCoreEngine::initScriptTimers(const uint8 *pos) {
 }
 
 void EobCoreEngine::updateScriptTimers() {
-	if ((_scriptTimersMode & 1) && _stepsUntilScriptCall && _stepCounter > _stepsUntilScriptCall) {
+	bool timerUpdate = false;
+	if ((_scriptTimersMode & 2) && _stepsUntilScriptCall && _stepCounter > _stepsUntilScriptCall) {
 		_inf->run(0, 0x20);
 		_stepCounter = 0;
+		timerUpdate = true;
 	}
 
-	if (_scriptTimersMode & 2) {
+	if (_scriptTimersMode & 1) {
 		for (int i = 0; i < _scriptTimersCount; i++) {
 			if (_scriptTimers[i].next < _system->getMillis()) {
 				_inf->run(_scriptTimers[i].func, _flags.gameID == GI_EOB1 ? 0x20 : 0x80);
 				_scriptTimers[i].next = _system->getMillis() + _scriptTimers[i].ticks * _tickLength;
 				_sceneUpdateRequired = true;
+				timerUpdate = true;
 			}
 		}
 	}
+
+	if (timerUpdate)
+		updateScriptTimersExtra();
 }
 
 EobInfProcessor::EobInfProcessor(EobCoreEngine *engine, Screen_Eob *screen) : _vm(engine), _screen(screen),
@@ -211,13 +217,13 @@ bool EobInfProcessor::preventRest() const {
 void EobInfProcessor::loadState(Common::SeekableSubReadStreamEndian &in) {
 	_preventRest = in.readByte();
 	for (int i = 0; i < 18; i++)
-		_flagTable[i] = in.readUint16BE();
+		_flagTable[i] = in.readUint32BE();
 }
 
 void EobInfProcessor::saveState(Common::OutSaveFile *out) {
 	out->writeByte(_preventRest);
 	for (int i = 0; i < 18; i++)
-		out->writeUint16BE(_flagTable[i]);
+		out->writeUint32BE(_flagTable[i]);
 }
 
 const char *EobInfProcessor::getString(uint16 index) {
diff --git a/engines/kyra/sequences_eob1.cpp b/engines/kyra/sequences_eob1.cpp
index dcfabfe..8f360c0 100644
--- a/engines/kyra/sequences_eob1.cpp
+++ b/engines/kyra/sequences_eob1.cpp
@@ -43,7 +43,7 @@ int EobEngine::mainMenu() {
 		switch (menuChoice) {
 			case 0:
 				_screen->loadPalette("EOBPAL.COL", _screen->getPalette(0));
-				_screen->loadEobCpsFileToPage("INTRO", 0, 5, 3, 2);
+				_screen->loadEobBitmap("INTRO", 0, 5, 3, 2);
 				_screen->setScreenPalette(_screen->getPalette(0));
 				_screen->_curPage = 2;
 				of = _screen->setFont(Screen::FID_6_FNT);
@@ -107,6 +107,7 @@ void EobEngine::seq_playOpeningCredits() {
 	static const char *cmpList[] = { "WESTWOOD.CMP", "AND.CMP", "SSI.CMP", "PRESENT.CMP", "DAND.CMP" };
 	static const uint8 frameDelay[] = { 140, 50, 100, 50, 140 };
 
+	_allowSkip = true;
 	_screen->loadPalette("WESTWOOD.COL", _screen->getPalette(0));
 	_screen->setScreenPalette(_screen->getPalette(0));
 
@@ -125,14 +126,21 @@ void EobEngine::seq_playOpeningCredits() {
 	}
 
 	delay(50 * _tickLength);
+	_allowSkip = false;
 }
 
 void EobEngine::seq_playIntro() {
+	_allowSkip = true;
 	//_sound->playTrack(2);
+
+	_allowSkip = false;
 }
 
 void EobEngine::seq_playFinale() {
+	_allowSkip = true;
+
 
+	_allowSkip = false;
 }
 
 }	// End of namespace Kyra
diff --git a/engines/kyra/sequences_eob2.cpp b/engines/kyra/sequences_eob2.cpp
index 8ff5581..bba5a7a 100644
--- a/engines/kyra/sequences_eob2.cpp
+++ b/engines/kyra/sequences_eob2.cpp
@@ -941,6 +941,7 @@ DarkmoonSequenceHelper::DarkmoonSequenceHelper(OSystem *system, DarkMoonEngine *
 
 	_system->delayMillis(150);
 	_vm->resetSkipFlag(true);
+	_vm->_allowSkip = true;
 }
 
 DarkmoonSequenceHelper::~DarkmoonSequenceHelper() {
@@ -960,6 +961,7 @@ DarkmoonSequenceHelper::~DarkmoonSequenceHelper() {
 
 	_system->delayMillis(150);
 	_vm->resetSkipFlag(true);
+	_vm->_allowSkip = false;
 }
 
 void DarkmoonSequenceHelper::loadScene(int index, int pageNum) {
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index 3447b6b..802ba4e 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -54,7 +54,11 @@ int LolEobBaseEngine::getBlockDistance(uint16 block1, uint16 block2) {
 namespace Kyra {
 
 void EobCoreEngine::loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex) {
-	_screen->loadEobBitmap(filename, 3, 3);
+	Common::String s = _flags.gameID == GI_EOB1 && !scumm_stricmp(filename, "spider") ? "spider1" : filename;
+	if (GI_EOB1 && !scumm_stricmp(filename, "rust"))
+		s += "1";
+
+	_screen->loadShapeSetBitmap(s.c_str(), 3, 3);
 	const uint16 *enc = &_encodeMonsterShpTable[encodeTableIndex << 2];
 
 	for (int i = 0; i < 6; i++, enc += 4)
@@ -275,14 +279,14 @@ void EobCoreEngine::updateAttackingMonsterFlags() {
 }
 
 const int8 *EobCoreEngine::getMonsterBlockPositions(uint16 block) {
-	static int8 pos[6];
-	memset(pos, -1, sizeof(pos));
+	memset(_monsterBlockPosArray, -1, sizeof(_monsterBlockPosArray));
 	for (int8 i = 0; i < 30; i++) {
 		if (_monsters[i].block != block)
 			continue;
-		pos[_monsters[i].pos] = i;
+		assert(_monsters[i].pos < sizeof(_monsterBlockPosArray));
+		_monsterBlockPosArray[_monsters[i].pos] = i;
 	}
-	return pos;
+	return _monsterBlockPosArray;
 }
 
 int EobCoreEngine::getClosestMonsterPos(int charIndex, int block) {
@@ -770,6 +774,11 @@ void EobCoreEngine::updateMonsterDest2(EobMonsterInPlay *m) {
 	m->dest = _currentBlock;
 }
 
+void EobCoreEngine::updateAllMonsterDests() {
+	for (int i = 0; i < 30; i++)
+		updateMonsterDest(&_monsters[i]);
+}
+
 void EobCoreEngine::turnFriendlyMonstersHostile() {
 	EobMonsterInPlay *m = 0;
 	for (int i = 0; i < 30; i++) {
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 9b15d4a..f07cd11 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -448,7 +448,7 @@ void EobCoreEngine::initStaticResource() {
 	_npcPreset = _staticres->loadEobNpcData(kEobBaseNpcPresets, temp);
 
 	_teleporterShapeCoords = _staticres->loadRawData(kEobBaseDscTelptrShpCoords, temp);
-	_portalSeq = _staticres->loadRawData(kEobBasePortalSeqData, temp);
+	_portalSeq = (const int8*)_staticres->loadRawData(kEobBasePortalSeqData, temp);
 	_mnDef = _staticres->loadRawData(kEobBaseManDef, temp);
 	_mnWord = _staticres->loadStrings(kEobBaseManWord, _mnNumWord);
 	_mnPrompt = _staticres->loadStrings(kEobBaseManPrompt, temp);
@@ -493,6 +493,7 @@ void EobCoreEngine::initStaticResource() {
 	_dscDoorScaleMult2 = _staticres->loadRawData(kEobBaseDscDoorScaleMult2, temp);
 	_dscDoorScaleMult3 = _staticres->loadRawData(kEobBaseDscDoorScaleMult3, temp);
 	_dscDoorY1 = _staticres->loadRawData(kEobBaseDscDoorY1, temp);
+	_dscDoorXE = _staticres->loadRawData(kEobBaseDscDoorXE, temp);
 
 	_dscItemPosIndex= _staticres->loadRawData(kEobBaseDscItemPosIndex, temp);
 	_dscItemShpX = (const int16*)_staticres->loadRawDataBe16(kEobBaseDscItemShpX, temp);
@@ -533,6 +534,7 @@ void EobCoreEngine::initStaticResource() {
 	_sparkEffectOfY = _staticres->loadRawData(kEobBaseSparkOfY, temp);
 	_magicFlightObjectProperties = _staticres->loadRawData(kEobBaseMagicFlightProps, temp);
 	_turnUndeadEffect = _staticres->loadRawData(kEobBaseTurnUndeadEffect, temp);
+	_burningHandsDest = _staticres->loadRawData(kEobBaseBurningHandsDest, temp);
 
 	// Hard code the following strings, since EOB I doesn't have them in the original.
 	// EOB I doesn't have load and save menus, because there is only one single
@@ -1002,7 +1004,8 @@ void EobCoreEngine::initSpells() {
 	ec2(empty);
 	ec(empty);
 	ec2(empty);
-	ec(unk1Passive);
+	ec1(kuotoaAttack);
+	ec2(unk1Passive);
 	ec2(empty);
 	ec2(unk2Passive);
 	ec(deathSpellPassive);
@@ -1064,6 +1067,7 @@ void EobEngine::initStaticResource() {
 	_dscDoorY4 = _staticres->loadRawData(kEobBaseDscDoorY4, temp);
 	_dscDoorY5 = _staticres->loadRawData(kEobBaseDscDoorY5, temp);
 	_dscDoorY6 = _staticres->loadRawData(kEobBaseDscDoorY6, temp);
+	_dscDoorY7 = _staticres->loadRawData(kEobBaseDscDoorY7, temp);
 	_dscDoorCoordsExt = (const int16*)_staticres->loadRawDataBe16(kEobBaseDscDoorCoordsExt, temp);
 
 	_monsterDistAttType10 = _staticres->loadRawData(kEob1MonsterDistAttType10, temp);
diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp
index 9e03bde..ba4d6a2 100644
--- a/engines/kyra/timer_eob.cpp
+++ b/engines/kyra/timer_eob.cpp
@@ -210,7 +210,7 @@ void EobCoreEngine::advanceTimers(uint32 millis) {
 
 	setupCharacterTimers();
 
-	if (_scriptTimersMode & 2) {
+	if (_scriptTimersMode & 1) {
 		for (int i = 0; i < _scriptTimersCount; i++) {
 			if (_scriptTimers[i].next > ct) {
 				uint32 chrt = _scriptTimers[i].next - ct;
@@ -371,7 +371,7 @@ void EobCoreEngine::timerUpdateTeleporters(int timerNum) {
 	_teleporterPulse ^= 1;
 	for (int i = 0; i < 18; i++) {
 		uint8 w = _visibleBlocks[i]->walls[_sceneDrawVarDown];
-		if (w == 44 || w == 74) {
+		if ((_flags.gameID == GI_EOB1 && w == 52) || (_flags.gameID == GI_EOB2 && (w == 44 || w == 74))) {
 			_sceneUpdateRequired = true;
 			return;
 		}


Commit: fc5b29fdbcf4170436a32da2c1f4b078b1f1f90f
    https://github.com/scummvm/scummvm/commit/fc5b29fdbcf4170436a32da2c1f4b078b1f1f90f
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:13-08:00

Commit Message:
KYRA: (EOB) - implemented some spells and fixed more bugs

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    engines/kyra/eob1.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/items_eob.cpp
    engines/kyra/magic_eob.cpp
    engines/kyra/resource.h
    engines/kyra/saveload_eob.cpp
    engines/kyra/sprites_eob.cpp
    engines/kyra/staticres_eob.cpp
    engines/kyra/timer_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index a646bee..d5fc803 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -411,8 +411,8 @@ const ExtractFilename extractFilenames[] = {
 	{ kEob1DoorSwitchShapeDefs, kTypeRawData, false },
 	{ kEob1DoorSwitchCoords, kTypeRawData, false },
 	{ kEob1MonsterProperties, kTypeRawData, false },
-	{ kEob1MonsterDistAttType10, kTypeRawData, false },
-	{ kEob1MonsterDistAttSfx10, kTypeRawData, false },
+	{ kEob1EnemyMageSpellList, kTypeRawData, false },
+	{ kEob1EnemyMageSfx, kTypeRawData, false },
 	{ kEob1MonsterDistAttType17, kTypeRawData, false },
 	{ kEob1MonsterDistAttSfx17, kTypeRawData, false },
 	{ kEob1TurnUndeadString, kTypeStringList, true },
@@ -1652,10 +1652,10 @@ const char *getIdString(const int id) {
 		return "kEob1DoorSwitchCoords";
 	case kEob1MonsterProperties:
 		return "kEob1MonsterProperties";
-	case kEob1MonsterDistAttType10:
-		return "kEob1MonsterDistAttType10";
-	case kEob1MonsterDistAttSfx10:
-		return "kEob1MonsterDistAttSfx10";
+	case kEob1EnemyMageSpellList:
+		return "kEob1EnemyMageSpellList";
+	case kEob1EnemyMageSfx:
+		return "kEob1EnemyMageSfx";
 	case kEob1MonsterDistAttType17:
 		return "kEob1MonsterDistAttType17";
 	case kEob1MonsterDistAttSfx17:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index a7b53b4..75511b6 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -412,8 +412,8 @@ enum kExtractID {
 	kEob1DoorSwitchCoords,
 	kEob1MonsterProperties,
 
-	kEob1MonsterDistAttType10,
-	kEob1MonsterDistAttSfx10,
+	kEob1EnemyMageSpellList,
+	kEob1EnemyMageSfx,
 	kEob1MonsterDistAttType17,
 	kEob1MonsterDistAttSfx17,
 	kEob1TurnUndeadString,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 000c350..bfbab79 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1059,8 +1059,8 @@ const int eob1FloppyNeed[] = {
 	kEob1DoorSwitchShapeDefs,
 	kEob1DoorSwitchCoords,
 	kEob1MonsterProperties,
-	kEob1MonsterDistAttType10,
-	kEob1MonsterDistAttSfx10,
+	kEob1EnemyMageSpellList,
+	kEob1EnemyMageSfx,
 	kEob1MonsterDistAttType17,
 	kEob1MonsterDistAttSfx17,
 	kEob1TurnUndeadString,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index a92c097..a30d248 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -2388,12 +2388,12 @@ const ExtractEntrySearchData kEob1MonsterPropertiesProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1MonsterDistAttType10Provider[] = {
+const ExtractEntrySearchData kEob1EnemyMageSpellListProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000000F, { { 0x01, 0x1B, 0x9C, 0x51, 0xC9, 0xA2, 0x10, 0xBB, 0xA7, 0x82, 0xD4, 0x91, 0x7E, 0x84, 0x54, 0x93 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1MonsterDistAttSfx10Provider[] = {
+const ExtractEntrySearchData kEob1EnemyMageSfxProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000029B, { { 0xA2, 0x9F, 0x2E, 0xDE, 0x15, 0x23, 0x78, 0xDD, 0x26, 0x98, 0x6E, 0xA3, 0x77, 0xEA, 0xB5, 0x80 } } } },
 	EXTRACT_END_ENTRY
 };
@@ -3870,8 +3870,8 @@ const ExtractEntry extractProviders[] = {
 	{ kEob1DoorSwitchCoords, kEob1DoorSwitchCoordsProvider },
 	{ kEob1MonsterProperties, kEob1MonsterPropertiesProvider },
 
-	{ kEob1MonsterDistAttType10, kEob1MonsterDistAttType10Provider },
-	{ kEob1MonsterDistAttSfx10, kEob1MonsterDistAttSfx10Provider },
+	{ kEob1EnemyMageSpellList, kEob1EnemyMageSpellListProvider },
+	{ kEob1EnemyMageSfx, kEob1EnemyMageSfxProvider },
 	{ kEob1MonsterDistAttType17, kEob1MonsterDistAttType17Provider },
 	{ kEob1MonsterDistAttSfx17, kEob1MonsterDistAttSfx17Provider },
 	{ kEob1TurnUndeadString, kEob1TurnUndeadStringProvider },
diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
index 762b2d1..f48e850 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -438,9 +438,9 @@ void EobEngine::drawDoorIntern(int type, int index, int x, int y, int w, int wal
 		case 11:
 			v = ((wall < 30) ? (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult5[mDim] : _dscDoorScaleMult6[mDim]) * -1;
 			x -= (shp[2] << 2);
-			y = _dscDoorY3[mDim] + v;
+			y = _dscDoorY4[mDim] + v;
 			drawBlockObject(0, 2, shp, x, y + v, 5);
-			v >>= 4;
+			v = (v >> 3) + (v >> 2);
 			y = _dscDoorY5[mDim];
 			drawBlockObject(0, 2, _doorShapes[shapeIndex + 3], x, y - v, 5);
 			if (_wllShapeMap[wall] == -1)
@@ -505,6 +505,7 @@ void EobEngine::turnUndeadAutoHit() {
 
 bool EobEngine::checkPartyStatusExtra() {
 	_screen->copyPage(0, 10);
+	int cd = _screen->curDimIndex();
 	gui_drawBox(0, 121, 320, 80, _color1_1, _color2_1, _bkgColor_1);
 	_txt->setupField(9, false);
 	_txt->printMessage(_menuStringsDefeat[0]);
@@ -515,6 +516,8 @@ bool EobEngine::checkPartyStatusExtra() {
 	}
 	_screen->copyPage(10, 0);
 	_eventList.clear();
+	_screen->setScreenDim(cd);
+	_txt->removePageBreakFlag();
 	return true;
 }
 
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 3e1001d..5fc50f6 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -55,8 +55,8 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_tempIconShape = 0;
 
 	_monsterDustStrings = 0;
-	_monsterDistAttType10 = 0;
-	_monsterDistAttSfx10 = 0;
+	_enemyMageSpellList = 0;
+	_enemyMageSfx = 0;
 	_monsterDistAttType17 = 0;
 	_monsterDistAttSfx17 = 0;
 
@@ -130,8 +130,8 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_openBookType = _openBookTypeBackup = 0;
 	_openBookSpellList = 0;
 	_openBookAvailableSpells = 0;
-	_activeSpellCaster = 0;
-	_activeSpellCasterPos = 0;
+	_activeSpellCharId = 0;
+	_activeSpellCharacterPos = 0;
 	_activeSpell = 0;
 	_returnAfterSpellCallback = false;
 	_spells = 0;
@@ -473,7 +473,7 @@ bool EobCoreEngine::checkPartyStatus(bool handleDeath) {
 
 	if (!handleDeath)
 		return true;
-
+	
 	gui_drawAllCharPortraitsWithStats();
 
 	if (checkPartyStatusExtra()) {
@@ -1550,13 +1550,14 @@ void EobCoreEngine::seq_portal() {
 		} else {
 			s--;
 			_screen->copyRegion((s % 5) << 6, s / 5 * 77, 56, 27, 64, 77, 2, 0, Screen::CR_NO_P_CHECK);
-			if (s == 0)
-				snd_playSoundEffect(31);
-			else if (s == 3) {
-				if (*(pos - 2) == 3)
-					snd_playSoundEffect(90);
-			}
-		}		
+		}
+
+		if (s == 1)
+			snd_playSoundEffect(31);
+		else if (s == 3) {
+			if (*(pos - 2) == 3)
+				snd_playSoundEffect(90);
+		}
 		
 		_screen->updateScreen();
 		delay(2 * _tickLength);
@@ -1646,7 +1647,7 @@ int EobCoreEngine::closeDistanceAttack(int charIndex, Item item) {
 		return -3;
 
 	uint16 d = calcNewBlockPosition(_currentBlock, _currentDirection);
-	int r = getClosestMonsterPos(charIndex, d);
+	int r = getClosestMonster(charIndex, d);
 
 	if (r == -1) {
 		uint8 w = _specialWallTypes[_levelBlockProperties[d].walls[_sceneDrawVarDown]];
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 33b4a2f..1b701cf 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -486,8 +486,8 @@ protected:
 	int countSpecificMonsters(int type);
 	void updateAttackingMonsterFlags();
 
-	const int8 *getMonsterBlockPositions(uint16 block);
-	int getClosestMonsterPos(int charIndex, int block);
+	const int8 *getMonstersOnBlockPositions(uint16 block);
+	int getClosestMonster(int charIndex, int block);
 
 	bool blockHasMonsters(uint16 block);
 	bool isMonsterOnPos(EobMonsterInPlay *m, uint16 block, int pos, int checkPos4);
@@ -547,8 +547,8 @@ protected:
 	const uint8 *_findBlockMonstersTable;
 	const char *const *_monsterDustStrings;
 	
-	const uint8 *_monsterDistAttType10;
-	const uint8 *_monsterDistAttSfx10;
+	const uint8 *_enemyMageSpellList;
+	const uint8 *_enemyMageSfx;
 	const uint8 *_monsterDistAttType17;
 	const uint8 *_monsterDistAttSfx17;
 	const char *const *_monsterSpecAttStrings;
@@ -912,7 +912,9 @@ protected:
 	bool magicObjectStatusHit(EobMonsterInPlay *m, int type, bool tryEvade, int mod);
 	bool turnUndeadHit(EobMonsterInPlay *m, int hitChance, int casterLevel);
 
-	void printWarning(const char* str);
+	int findSingleSpellTarget(int dist);
+
+	void printWarning(const char *str);
 	void printNoEffectWarning();
 
 	void spellCallback_start_empty() {}
@@ -993,8 +995,8 @@ protected:
 	uint8 _openBookCasterLevel;
 	const char *const *_openBookSpellList;
 	int8 *_openBookAvailableSpells;
-	uint8 _activeSpellCaster;
-	uint8 _activeSpellCasterPos;
+	uint8 _activeSpellCharId;
+	uint8 _activeSpellCharacterPos;
 	uint8 _activeSpell;
 	bool _returnAfterSpellCallback;
 
@@ -1046,6 +1048,11 @@ protected:
 	const uint8 *_magicFlightObjectProperties;
 	const uint8 *_turnUndeadEffect;
 	const uint8 *_burningHandsDest;
+	const int8 *_coneOfColdDest1;
+	const int8 *_coneOfColdDest2;
+	const int8 *_coneOfColdDest3;
+	const int8 *_coneOfColdDest4;
+	const int8 *_coneOfColdGfxTbl;
 
 	// Menu
 	EobMenuDef *_menuDefs;
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 04b863c..393bbab 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -524,7 +524,7 @@ void EobCoreEngine::gui_drawCharPortraitStatusFrame(int index) {
 	EobCharacter *c = &_characters[index];
 
 	bool redGreen = ((c->effectFlags & 0x4818) || (_partyEffectFlags & 0x20000) || c->effectsRemainder[0] || c->effectsRemainder[1]) ? true : false;
-	bool yellow = ((c->effectFlags & 0x13000) || (_partyEffectFlags & 0x8420) || c->effectsRemainder[0] || c->effectsRemainder[1]) ? true : false;
+	bool yellow = ((c->effectFlags & 0x13000) || (_partyEffectFlags & 0x8420)) ? true : false;
 
 	if (redGreen || yellow) {
 		if (redGreen && !yellow) {
@@ -1108,9 +1108,9 @@ int EobCoreEngine::clickedSpellbookList(Button *button) {
 }
 
 int EobCoreEngine::clickedCastSpellOnCharacter(Button *button) {
-	_activeSpellCaster = button->arg & 0xff;
+	_activeSpellCharId = button->arg & 0xff;
 
-	if (_activeSpellCaster == 0xff) {
+	if (_activeSpellCharId == 0xff) {
 		printWarning(_magicStrings3[_flags.gameID == GI_EOB1 ? 2 : 1]);
 		if (_castScrollSlot) {
 			gui_updateSlotAfterScrollUse();
@@ -1119,7 +1119,7 @@ int EobCoreEngine::clickedCastSpellOnCharacter(Button *button) {
 			gui_drawSpellbook();
 		}
 	} else {
-		if (_characters[_activeSpellCaster].flags & 1)
+		if (_characters[_activeSpellCharId].flags & 1)
 			startSpell(_activeSpell);
 	}
 
diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
index b48c393..e2d2870 100644
--- a/engines/kyra/items_eob.cpp
+++ b/engines/kyra/items_eob.cpp
@@ -256,22 +256,19 @@ bool EobCoreEngine::deletePartyItems(int16 itemType, int16 itemValue) {
 			continue;
 
 		EobCharacter *c = &_characters[i];
-		int slot = checkInventoryForItem(i, itemType, itemValue);
-
-		if (slot == -1)
-			continue;
-
-		int itm = c->inventory[slot];
-		_items[itm].block = -1;
-		c->inventory[slot] = 0;
-		res = true;
+		for (int slot = checkInventoryForItem(i, itemType, itemValue); slot != -1; slot = checkInventoryForItem(i, itemType, itemValue)) {
+			int itm = c->inventory[slot];
+			_items[itm].block = -1;
+			c->inventory[slot] = 0;
+			res = true;
 
-		if (!_dialogueField) {
-			if (_currentControlMode == 0 && slot < 2 && i < 5)
-				gui_drawWeaponSlot(i, slot);
+			if (!_dialogueField) {
+				if (_currentControlMode == 0 && slot < 2 && i < 5)
+					gui_drawWeaponSlot(i, slot);
 
-			if (_currentControlMode == 1 && i == _updateCharNum)
-				gui_drawInventoryItem(slot, 1, 0);
+				if (_currentControlMode == 1 && i == _updateCharNum)
+					gui_drawInventoryItem(slot, 1, 0);
+			}
 		}
 	}
 
@@ -379,9 +376,9 @@ void EobCoreEngine::printFullItemName(Item item) {
 				if (v == 0)
 					tmpString = nameUnid;
 				else if (v < 0)
-					tmpString = Common::String::format(_cursedString[0], v, nameUnid);
+					tmpString = _flags.gameID == GI_EOB1 ? Common::String::format(_cursedString[0], nameUnid, v) : Common::String::format(_cursedString[0], v, nameUnid);
 				else
-					tmpString = Common::String::format(_enchantedString[0], v, nameUnid);
+					tmpString = _flags.gameID == GI_EOB1 ? Common::String::format(_enchantedString[0], nameUnid, v) : Common::String::format(_enchantedString[0], v, nameUnid);
 				break;
 
 			case 9:
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 12d2524..d06e15b 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -184,7 +184,7 @@ void EobCoreEngine::castSpell(int spell, int weaponSlot) {
 	if (ci > 3)
 		ci -= 2;
 
-	_activeSpellCasterPos = _dropItemDirIndex[(_currentDirection << 2) + ci];
+	_activeSpellCharacterPos = _dropItemDirIndex[(_currentDirection << 2) + ci];
 
 	if (s->flags & 0x400) {
 		if (c->inventory[0] && c->inventory[1]) {
@@ -226,7 +226,7 @@ void EobCoreEngine::castSpell(int spell, int weaponSlot) {
 		return;
 	}
 
-	_activeSpellCaster = _openBookChar;
+	_activeSpellCharId = _openBookChar;
 	startSpell(spell);
 }
 
@@ -258,7 +258,7 @@ void EobCoreEngine::removeCharacterEffect(int spell, int charIndex, int showWarn
 	}
 
 	if (s->flags & 0x2)
-		recalcArmorClass(_activeSpellCaster);
+		recalcArmorClass(_activeSpellCharId);
 
 	if (showWarning) {
 		if (s->flags & 0x20A0)
@@ -296,11 +296,11 @@ void EobCoreEngine::castOnWhomDialogue() {
 
 void EobCoreEngine::startSpell(int spell) {
 	EobSpell *s = &_spells[spell];
-	EobCharacter *c = &_characters[_activeSpellCaster];
+	EobCharacter *c = &_characters[_activeSpellCharId];
 	snd_playSoundEffect(s->sound);
 
 	if (s->flags & 0xa0)
-		sparkEffectDefensive(_activeSpellCaster);
+		sparkEffectDefensive(_activeSpellCharId);
 	else if (s->flags & 0x40)
 		sparkEffectDefensive(-1);
 	else if (s->flags & 0x1000)
@@ -312,9 +312,17 @@ void EobCoreEngine::startSpell(int spell) {
 	}
 
 	if ((s->flags & 0x30) && (s->effectFlags & c->effectFlags)) {
-		printWarning(Common::String::format(_magicStrings7[0], c->name, s->name).c_str());
+		if (_flags.gameID == GI_EOB1) {
+			// TODO: warnings seem to exist at least for bless and aid
+		} else {
+			printWarning(Common::String::format(_magicStrings7[0], c->name, s->name).c_str());
+		}
 	} else if ((s->flags & 0x50) && (s->effectFlags & _partyEffectFlags)) {
-		printWarning(Common::String::format(_magicStrings7[1], s->name).c_str());
+		if (_flags.gameID == GI_EOB1) {
+			// TODO: warnings seem to exist at least for bless and aid
+		} else {
+			printWarning(Common::String::format(_magicStrings7[1], s->name).c_str());
+		}
 	} else {
 		if (s->flags & 8)
 			setSpellEventTimer(spell, s->timingPara[0], s->timingPara[1], s->timingPara[2], s->timingPara[3]);
@@ -341,10 +349,10 @@ void EobCoreEngine::startSpell(int spell) {
 		}
 
 		if (s->flags & 2)
-			recalcArmorClass(_activeSpellCaster);
+			recalcArmorClass(_activeSpellCharId);
 
 		if (s->flags & 0x20A0)
-			gui_drawCharPortraitWithStats(_activeSpellCaster);
+			gui_drawCharPortraitWithStats(_activeSpellCharId);
 		if (s->flags & 0x40)
 			gui_drawAllCharPortraitsWithStats();
 	}
@@ -438,7 +446,7 @@ void EobCoreEngine::sparkEffectOffensive() {
 void EobCoreEngine::setSpellEventTimer(int spell, int timerBaseFactor, int timerLength, int timerLevelFactor, int updateExistingTimer) {
 	int l = _openBookType == 1 ? getCharacterClericPaladinLevel(_openBookChar) : getCharacterMageLevel(_openBookChar);
 	uint32 countdown = timerLength * timerBaseFactor + timerLength * l * timerLevelFactor;
-	setCharEventTimer(_activeSpellCaster, countdown, -spell, updateExistingTimer);
+	setCharEventTimer(_activeSpellCharId, countdown, -spell, updateExistingTimer);
 }
 
 void EobCoreEngine::sortCharacterSpellList(int charIndex) {
@@ -624,7 +632,23 @@ bool EobCoreEngine::turnUndeadHit(EobMonsterInPlay *m, int hitChance, int caster
 	return true;
 }
 
-void EobCoreEngine::printWarning(const char* str) {
+int EobCoreEngine::findSingleSpellTarget(int dist) {
+	uint16 bl = _currentBlock;
+	int res = -1;
+
+	for (int i = 0; i < dist && res == -1; i++) {
+		bl = calcNewBlockPosition(bl, _currentDirection);
+		res = getClosestMonster(_openBookChar, bl);
+		if (!(_wllWallFlags[_levelBlockProperties[bl].walls[_sceneDrawVarDown]] & 1)) {
+			i = dist;
+			res = -1;
+		}
+	}
+
+	return res;
+}
+
+void EobCoreEngine::printWarning(const char *str) {
 	_txt->printMessage(str);
 	snd_playSoundEffect(79);
 }
@@ -634,7 +658,9 @@ void EobCoreEngine::printNoEffectWarning() {
 }
 
 void EobCoreEngine::spellCallback_start_armor() {
-
+	_characters[_activeSpellCharId].effectsRemainder[0] = getCharacterMageLevel(_openBookChar) + 8;
+	if ((getDexterityArmorClassModifier(_characters[_activeSpellCharId].dexterityCur) + 6) >= _characters[_activeSpellCharId].armorClass)
+		printWarning(Common::String::format(_magicStrings6[0], _characters[_activeSpellCharId].name).c_str());
 }
 
 void EobCoreEngine::spellCallback_start_burningHands() {
@@ -649,7 +675,7 @@ void EobCoreEngine::spellCallback_start_burningHands() {
 	int cl = getCharacterMageLevel(_openBookChar);
 	int bl = calcNewBlockPosition(_currentBlock, _currentDirection);
 
-	const int8 *pos = getMonsterBlockPositions(bl);
+	const int8 *pos = getMonstersOnBlockPositions(bl);
 	_preventMonsterFlash = true;
 
 	int numDest = (_flags.gameID == GI_EOB1) ? 2 : 6;
@@ -674,7 +700,7 @@ bool EobCoreEngine::spellCallback_end_detectMagic(EobFlyingObject*) {
 }
 
 void EobCoreEngine::spellCallback_start_magicMissile() {
-	launchMagicObject(_openBookChar, 0, _currentBlock, _activeSpellCasterPos, _currentDirection);
+	launchMagicObject(_openBookChar, 0, _currentBlock, _activeSpellCharacterPos, _currentDirection);
 }
 
 bool EobCoreEngine::spellCallback_end_magicMissile(EobFlyingObject *fo) {
@@ -694,10 +720,11 @@ void EobCoreEngine::spellCallback_start_improvedIdentify() {
 }
 
 void EobCoreEngine::spellCallback_start_melfsAcidArrow() {
-	launchMagicObject(_openBookChar, 1, _currentBlock, _activeSpellCasterPos, _currentDirection);
+	launchMagicObject(_openBookChar, 1, _currentBlock, _activeSpellCharacterPos, _currentDirection);
 }
 
 bool EobCoreEngine::spellCallback_end_melfsAcidArrow(EobFlyingObject *fo) {
+	assert(fo);
 	return magicObjectDamageHit(fo, 2, 4, 0, getCharacterMageLevel(fo->attackerId) / 3);
 }
 
@@ -706,7 +733,7 @@ void EobCoreEngine::spellCallback_start_dispelMagic() {
 }
 
 void EobCoreEngine::spellCallback_start_fireball() {
-	launchMagicObject(_openBookChar, 2, _currentBlock, _activeSpellCasterPos, _currentDirection);
+	launchMagicObject(_openBookChar, 2, _currentBlock, _activeSpellCharacterPos, _currentDirection);
 }
 
 bool EobCoreEngine::spellCallback_end_fireball(EobFlyingObject *fo) {
@@ -714,7 +741,7 @@ bool EobCoreEngine::spellCallback_end_fireball(EobFlyingObject *fo) {
 }
 
 void EobCoreEngine::spellCallback_start_flameArrow() {
-	launchMagicObject(_openBookChar, 3, _currentBlock, _activeSpellCasterPos, _currentDirection);
+	launchMagicObject(_openBookChar, 3, _currentBlock, _activeSpellCharacterPos, _currentDirection);
 }
 
 bool EobCoreEngine::spellCallback_end_flameArrow(EobFlyingObject *fo) {
@@ -722,7 +749,7 @@ bool EobCoreEngine::spellCallback_end_flameArrow(EobFlyingObject *fo) {
 }
 
 void EobCoreEngine::spellCallback_start_holdPerson() {
-	launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 4 : 3, _currentBlock, _activeSpellCasterPos, _currentDirection);
+	launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 4 : 3, _currentBlock, _activeSpellCharacterPos, _currentDirection);
 }
 
 bool EobCoreEngine::spellCallback_end_holdPerson(EobFlyingObject *fo) {
@@ -751,7 +778,7 @@ bool EobCoreEngine::spellCallback_end_holdPerson(EobFlyingObject *fo) {
 }
 
 void EobCoreEngine::spellCallback_start_lightningBolt() {
-	launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 5 : 4, _currentBlock, _activeSpellCasterPos, _currentDirection);
+	launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 5 : 4, _currentBlock, _activeSpellCharacterPos, _currentDirection);
 }
 
 bool EobCoreEngine::spellCallback_end_lightningBolt(EobFlyingObject *fo) {
@@ -776,7 +803,7 @@ void EobCoreEngine::spellCallback_start_fear() {
 }
 
 void EobCoreEngine::spellCallback_start_iceStorm() {
-	launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 6 : 5, _currentBlock, _activeSpellCasterPos, _currentDirection);
+	launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 6 : 5, _currentBlock, _activeSpellCharacterPos, _currentDirection);
 }
 
 bool EobCoreEngine::spellCallback_end_iceStorm(EobFlyingObject *fo) {
@@ -794,15 +821,32 @@ bool EobCoreEngine::spellCallback_end_iceStorm(EobFlyingObject *fo) {
 }
 
 void EobCoreEngine::spellCallback_start_removeCurse() {
-
+	for (int i = 0; i < 27; i++) {
+		Item itm = _characters[_activeSpellCharId].inventory[i];
+		if (itm && (_items[itm].flags & 0x20) && !isMagicWeapon(itm))
+			_items[itm].flags = (_items[itm].flags & ~0x20) | 0x40;
+	}
 }
 
 void EobCoreEngine::spellCallback_start_coneOfCold() {
+	static const int8 *dirTables[] = { _coneOfColdDest1, _coneOfColdDest2, _coneOfColdDest3, _coneOfColdDest4 };
+	
+	int cl = getCharacterMageLevel(_openBookChar);
+	//drawConeOfColdEffect(150, 50, 10, 1, 100, _coneOfColdGfxTbl);
+	
+	const int8 *tbl = dirTables[_currentDirection];
+	_preventMonsterFlash = true;
+
+	for (int i = 0; i < 7; i++) {		
+		for (const int16 *m = findBlockMonsters((_currentBlock + tbl[i]) & 0x3ff, 4, _currentDirection, 1, 1); *m != -1; m++)
+			calcAndInflictMonsterDamage(&_monsters[*m], cl, 4, cl, 0x41, 5, 0);
+	}
 
+	updateAllMonsterShapes();
 }
 
 void EobCoreEngine::spellCallback_start_holdMonster() {
-
+	launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 7 : 6, _currentBlock, _activeSpellCharacterPos, _currentDirection);
 }
 
 bool EobCoreEngine::spellCallback_end_holdMonster(EobFlyingObject *fo) {
@@ -817,12 +861,16 @@ void EobCoreEngine::spellCallback_start_wallOfForce() {
 }
 
 void EobCoreEngine::spellCallback_start_disintegrate() {
-
+	int d = findSingleSpellTarget(1);
+	if (d != -1)
+		magicObjectStatusHit(&_monsters[d], 4, true, 4);
+	memset(_visibleBlocks[13]->walls, 0, 4);
+	_sceneUpdateRequired = true;
 }
 
 void EobCoreEngine::spellCallback_start_fleshToStone() {
 	sparkEffectOffensive();
-	int t = getClosestMonsterPos(_openBookChar, calcNewBlockPosition(_currentBlock, _currentDirection));
+	int t = getClosestMonster(_openBookChar, calcNewBlockPosition(_currentBlock, _currentDirection));
 	if (t != -1)
 		magicObjectStatusHit(&_monsters[t], 5, true, 4);
 	else
@@ -830,8 +878,8 @@ void EobCoreEngine::spellCallback_start_fleshToStone() {
 }
 
 void EobCoreEngine::spellCallback_start_stoneToFlesh() {
-	if (_characters[_activeSpellCaster].flags & 8)
-		_characters[_activeSpellCaster].flags &= ~8;
+	if (_characters[_activeSpellCharId].flags & 8)
+		_characters[_activeSpellCharId].flags &= ~8;
 	else
 		printNoEffectWarning();
 }
@@ -846,11 +894,18 @@ bool EobCoreEngine::spellCallback_end_trueSeeing(EobFlyingObject*) {
 }
 
 void EobCoreEngine::spellCallback_start_slayLiving() {
-
+	int d = findSingleSpellTarget(2);
+	if (d != -1)
+		if (!magicObjectStatusHit(&_monsters[d], 3, true, 4))
+			inflictMonsterDamage(&_monsters[d], rollDice(2, 8, 1), true);
 }
 
 void EobCoreEngine::spellCallback_start_powerWordStun() {
-
+	int d = findSingleSpellTarget(2);
+	if (d != -1) {
+		if (_monsters[d].hitPointsCur < 90)
+			magicObjectStatusHit(&_monsters[d], 5, true, 4);
+	}
 }
 
 void EobCoreEngine::spellCallback_start_causeLightWounds() {
@@ -858,7 +913,7 @@ void EobCoreEngine::spellCallback_start_causeLightWounds() {
 }
 
 void EobCoreEngine::spellCallback_start_cureLightWounds() {
-	modifyCharacterHitpoints(_activeSpellCaster, rollDice(1, 8));
+	modifyCharacterHitpoints(_activeSpellCharId, rollDice(1, 8));
 }
 
 void EobCoreEngine::spellCallback_start_aid() {
@@ -904,7 +959,7 @@ void EobCoreEngine::spellCallback_start_causeSeriousWounds() {
 }
 
 void EobCoreEngine::spellCallback_start_cureSeriousWounds() {
-	modifyCharacterHitpoints(_activeSpellCaster, rollDice(2, 8, 1));
+	modifyCharacterHitpoints(_activeSpellCharId, rollDice(2, 8, 1));
 }
 
 void EobCoreEngine::spellCallback_start_neutralizePoison() {
@@ -916,11 +971,11 @@ void EobCoreEngine::spellCallback_start_causeCriticalWounds() {
 }
 
 void EobCoreEngine::spellCallback_start_cureCriticalWounds() {
-	modifyCharacterHitpoints(_activeSpellCaster, rollDice(3, 8, 3));
+	modifyCharacterHitpoints(_activeSpellCharId, rollDice(3, 8, 3));
 }
 
 void EobCoreEngine::spellCallback_start_flameStrike() {
-	launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 8 : 7, _currentBlock, _activeSpellCasterPos, _currentDirection);
+	launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 8 : 7, _currentBlock, _activeSpellCharacterPos, _currentDirection);
 }
 
 bool EobCoreEngine::spellCallback_end_flameStrike(EobFlyingObject *fo) {
@@ -928,7 +983,12 @@ bool EobCoreEngine::spellCallback_end_flameStrike(EobFlyingObject *fo) {
 }
 
 void EobCoreEngine::spellCallback_start_raiseDead() {
-
+	if (_characters[_activeSpellCharId].hitPointsCur == -10 || ((_characters[_activeSpellCharId].raceSex >> 1) == 1)) {
+		_characters[_activeSpellCharId].hitPointsCur = 1;
+		gui_drawCharPortraitWithStats(_activeSpellCharId);
+	} else {
+		printNoEffectWarning();
+	}
 }
 
 void EobCoreEngine::spellCallback_start_harm() {
@@ -936,15 +996,15 @@ void EobCoreEngine::spellCallback_start_harm() {
 }
 
 void EobCoreEngine::spellCallback_start_heal() {
-	EobCharacter *c = &_characters[_activeSpellCaster];
+	EobCharacter *c = &_characters[_activeSpellCharId];
 	if (c->hitPointsMax <= c->hitPointsCur)
 		printWarning(_magicStrings4[0]);
 	else
-		modifyCharacterHitpoints(_activeSpellCaster, c->hitPointsMax - c->hitPointsCur);
+		modifyCharacterHitpoints(_activeSpellCharId, c->hitPointsMax - c->hitPointsCur);
 }
 
 void EobCoreEngine::spellCallback_start_layOnHands() {
-	modifyCharacterHitpoints(_activeSpellCaster, _characters[_openBookChar].level[0] << 1);
+	modifyCharacterHitpoints(_activeSpellCharId, _characters[_openBookChar].level[0] << 1);
 }
 
 void EobCoreEngine::spellCallback_start_turnUndead() {
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index f80fdd9..a54ae6c 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -485,8 +485,8 @@ enum KyraResources {
 	kEob1DoorSwitchCoords,
 	kEob1MonsterProperties,
 
-	kEob1MonsterDistAttType10,
-	kEob1MonsterDistAttSfx10,
+	kEob1EnemyMageSpellList,
+	kEob1EnemyMageSfx,
 	kEob1MonsterDistAttType17,
 	kEob1MonsterDistAttSfx17,
 
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index 88f0c1c..05eea82 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -241,8 +241,8 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 	_openBookType = in.readByte();
 	_openBookCharBackup = in.readByte();
 	_openBookTypeBackup = in.readByte();
-	_activeSpellCaster = in.readByte();
-	_activeSpellCasterPos = in.readByte();
+	_activeSpellCharId = in.readByte();
+	_activeSpellCharacterPos = in.readByte();
 	_activeSpell = in.readByte();
 	_returnAfterSpellCallback = in.readByte() ? true : false;
 
@@ -465,8 +465,8 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName,
 	out->writeByte(_openBookType);
 	out->writeByte(_openBookCharBackup);
 	out->writeByte(_openBookTypeBackup);
-	out->writeByte(_activeSpellCaster);
-	out->writeByte(_activeSpellCasterPos);
+	out->writeByte(_activeSpellCharId);
+	out->writeByte(_activeSpellCharacterPos);
 	out->writeByte(_activeSpell);
 	out->writeByte(_returnAfterSpellCallback ? 1 : 0);
 
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index 802ba4e..945ccac 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -54,8 +54,8 @@ int LolEobBaseEngine::getBlockDistance(uint16 block1, uint16 block2) {
 namespace Kyra {
 
 void EobCoreEngine::loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex) {
-	Common::String s = _flags.gameID == GI_EOB1 && !scumm_stricmp(filename, "spider") ? "spider1" : filename;
-	if (GI_EOB1 && !scumm_stricmp(filename, "rust"))
+	Common::String s = filename;
+	if (GI_EOB1 && !scumm_stricmp(filename, "rust") || !scumm_stricmp(filename, "drider") || !scumm_stricmp(filename, "spider") || !scumm_stricmp(filename, "mantis") || !scumm_stricmp(filename, "xorn"))
 		s += "1";
 
 	_screen->loadShapeSetBitmap(s.c_str(), 3, 3);
@@ -147,7 +147,7 @@ const uint8 *EobCoreEngine::loadActiveMonsterData(const uint8 *data, int level)
 	uint32 ct = _system->getMillis();
 	for (int i = 0x20; i < 0x24; i++) {
 		int32 del = _timer->getDelay(i);
-		_timer->setNextRun(i, (i & 1) ? ct + (del >> 1) : ct + del);
+		_timer->setNextRun(i, (i & 1) ? ct + (del >> 1) * _tickLength : ct + del * _tickLength);
 	}
 
 	if (_hasTempDataFlags & (1 << (level - 1)))
@@ -178,7 +178,7 @@ void EobCoreEngine::initMonster(int index, int unit, uint16 block, int pos, int
 	if (index & 1)
 		unit++;
 
-	m->stepsTillRemoteAttack = _flags.gameID == GI_EOB2 ? rollDice(1, 3, 0) : 0;
+	m->stepsTillRemoteAttack = _flags.gameID == GI_EOB2 ? rollDice(1, 3, 0) : 5;
 	m->type = type;
 	m->numRemoteAttacks = p->numRemoteAttacks;
 	m->curRemoteWeapon = 0;
@@ -278,7 +278,7 @@ void EobCoreEngine::updateAttackingMonsterFlags() {
 		_inf->setFlag(0x800);
 }
 
-const int8 *EobCoreEngine::getMonsterBlockPositions(uint16 block) {
+const int8 *EobCoreEngine::getMonstersOnBlockPositions(uint16 block) {
 	memset(_monsterBlockPosArray, -1, sizeof(_monsterBlockPosArray));
 	for (int8 i = 0; i < 30; i++) {
 		if (_monsters[i].block != block)
@@ -289,8 +289,8 @@ const int8 *EobCoreEngine::getMonsterBlockPositions(uint16 block) {
 	return _monsterBlockPosArray;
 }
 
-int EobCoreEngine::getClosestMonsterPos(int charIndex, int block) {
-	const int8 *pos = getMonsterBlockPositions(block);
+int EobCoreEngine::getClosestMonster(int charIndex, int block) {
+	const int8 *pos = getMonstersOnBlockPositions(block);
 	if (pos[4] != -1)
 		return pos[4];
 
@@ -915,7 +915,7 @@ bool EobCoreEngine::updateMonsterTryDistanceAttack(EobMonsterInPlay *m) {
 	if (!m->numRemoteAttacks || ((_flags.gameID == GI_EOB1) && !(p->capsFlags & 0x40)))
 		return false;
 
-	if ((_flags.gameID == GI_EOB1 && m->stepsTillRemoteAttack == 5) || (_flags.gameID == GI_EOB2 && rollDice(1, 3) > m->stepsTillRemoteAttack)) {
+	if ((_flags.gameID == GI_EOB1 && m->stepsTillRemoteAttack < 5) || (_flags.gameID == GI_EOB2 && (rollDice(1, 3) > m->stepsTillRemoteAttack))) {
 		m->stepsTillRemoteAttack++;
 		return false;
 	}
@@ -940,8 +940,8 @@ bool EobCoreEngine::updateMonsterTryDistanceAttack(EobMonsterInPlay *m) {
 			snd_processEnvironmentalSoundEffect(31, m->block);
 			break;
 		case 10:
-			launchMagicObject(-1, _monsterDistAttType10[m->numRemoteAttacks], m->block, m->pos, m->dir);
-			snd_processEnvironmentalSoundEffect(_monsterDistAttSfx10[m->numRemoteAttacks], m->block);
+			launchMagicObject(-1, _enemyMageSpellList[m->numRemoteAttacks], m->block, m->pos, m->dir);
+			snd_processEnvironmentalSoundEffect(_enemyMageSfx[m->numRemoteAttacks], m->block);
 			break;
 		case 11:
 			itm = duplicateItem(60);
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index f07cd11..f30833c 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -1070,8 +1070,8 @@ void EobEngine::initStaticResource() {
 	_dscDoorY7 = _staticres->loadRawData(kEobBaseDscDoorY7, temp);
 	_dscDoorCoordsExt = (const int16*)_staticres->loadRawDataBe16(kEobBaseDscDoorCoordsExt, temp);
 
-	_monsterDistAttType10 = _staticres->loadRawData(kEob1MonsterDistAttType10, temp);
-	_monsterDistAttSfx10 = _staticres->loadRawData(kEob1MonsterDistAttSfx10, temp);
+	_enemyMageSpellList = _staticres->loadRawData(kEob1EnemyMageSpellList, temp);
+	_enemyMageSfx = _staticres->loadRawData(kEob1EnemyMageSfx, temp);
 	_monsterDistAttType17 = _staticres->loadRawData(kEob1MonsterDistAttType17, temp);
 	_monsterDistAttSfx17 = _staticres->loadRawData(kEob1MonsterDistAttSfx17, temp);
 
diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp
index ba4d6a2..20a05f9 100644
--- a/engines/kyra/timer_eob.cpp
+++ b/engines/kyra/timer_eob.cpp
@@ -203,7 +203,7 @@ void EobCoreEngine::advanceTimers(uint32 millis) {
 		for (int ii = 0; ii < 10; ii++) {
 			if (c->timers[ii] > ct) {
 				uint32 chrt = c->timers[ii] - ct;
-				c->timers[ii] = chrt > millis ? chrt - millis : ct;
+				c->timers[ii] = chrt > millis ? ct + chrt - millis : ct;
 			}
 		}
 	}
@@ -214,7 +214,7 @@ void EobCoreEngine::advanceTimers(uint32 millis) {
 		for (int i = 0; i < _scriptTimersCount; i++) {
 			if (_scriptTimers[i].next > ct) {
 				uint32 chrt = _scriptTimers[i].next - ct;
-				_scriptTimers[i].next = chrt > millis ? chrt - millis : ct;
+				_scriptTimers[i].next = chrt > millis ? ct + chrt - millis : ct;
 			}
 		}
 	}
@@ -331,7 +331,7 @@ void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
 		case 9:
 			if (c->flags & 4) {
 				_txt->printMessage(_characterStatusStrings9[0], -1, c->name);
-				c->flags &= 0xfb;
+				c->flags &= ~4;
 				gui_drawCharPortraitWithStats(charIndex);
 			}
 			break;


Commit: 359f3efd03704965d258c90381412a5ef2cf9239
    https://github.com/scummvm/scummvm/commit/359f3efd03704965d258c90381412a5ef2cf9239
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:14-08:00

Commit Message:
KYRA: (EOB) - add some spells

(shocking grasp, flame blade, vampiric touch etc.)

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    engines/kyra/eob1.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/items_eob.cpp
    engines/kyra/magic_eob.cpp
    engines/kyra/resource.h
    engines/kyra/sprites_eob.cpp
    engines/kyra/staticres_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index d5fc803..8bd5bae 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -413,8 +413,8 @@ const ExtractFilename extractFilenames[] = {
 	{ kEob1MonsterProperties, kTypeRawData, false },
 	{ kEob1EnemyMageSpellList, kTypeRawData, false },
 	{ kEob1EnemyMageSfx, kTypeRawData, false },
-	{ kEob1MonsterDistAttType17, kTypeRawData, false },
-	{ kEob1MonsterDistAttSfx17, kTypeRawData, false },
+	{ kEob1BeholderSpellList, kTypeRawData, false },
+	{ kEob1BeholderSfx, kTypeRawData, false },
 	{ kEob1TurnUndeadString, kTypeStringList, true },
 
 	{ kEob1NpcShpData, kTypeRawData, false },
@@ -1656,10 +1656,10 @@ const char *getIdString(const int id) {
 		return "kEob1EnemyMageSpellList";
 	case kEob1EnemyMageSfx:
 		return "kEob1EnemyMageSfx";
-	case kEob1MonsterDistAttType17:
-		return "kEob1MonsterDistAttType17";
-	case kEob1MonsterDistAttSfx17:
-		return "kEob1MonsterDistAttSfx17";
+	case kEob1BeholderSpellList:
+		return "kEob1BeholderSpellList";
+	case kEob1BeholderSfx:
+		return "kEob1BeholderSfx";
 	case kEob1TurnUndeadString:
 		return "kEob1TurnUndeadString";
 	case kEob1NpcShpData:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index 75511b6..7cacbb5 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -414,8 +414,8 @@ enum kExtractID {
 
 	kEob1EnemyMageSpellList,
 	kEob1EnemyMageSfx,
-	kEob1MonsterDistAttType17,
-	kEob1MonsterDistAttSfx17,
+	kEob1BeholderSpellList,
+	kEob1BeholderSfx,
 	kEob1TurnUndeadString,
 
 	kEob1NpcShpData,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index bfbab79..31f6dd6 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1061,8 +1061,8 @@ const int eob1FloppyNeed[] = {
 	kEob1MonsterProperties,
 	kEob1EnemyMageSpellList,
 	kEob1EnemyMageSfx,
-	kEob1MonsterDistAttType17,
-	kEob1MonsterDistAttSfx17,
+	kEob1BeholderSpellList,
+	kEob1BeholderSfx,
 	kEob1TurnUndeadString,
 
 	kEob1NpcShpData,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index a30d248..d846372 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -2398,12 +2398,12 @@ const ExtractEntrySearchData kEob1EnemyMageSfxProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1MonsterDistAttType17Provider[] = {
+const ExtractEntrySearchData kEob1BeholderSpellListProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000079, { { 0x8E, 0x13, 0x54, 0x9D, 0x54, 0xF6, 0xC9, 0x6E, 0x10, 0xF1, 0xC0, 0xE9, 0x66, 0xDD, 0x95, 0xED } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1MonsterDistAttSfx17Provider[] = {
+const ExtractEntrySearchData kEob1BeholderSfxProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x000000F5, { { 0xA9, 0x90, 0x41, 0x0D, 0xB5, 0xE0, 0x28, 0xFD, 0x0A, 0xC3, 0xF9, 0xEC, 0xC8, 0x47, 0xC1, 0x57 } } } },
 	EXTRACT_END_ENTRY
 };
@@ -3872,8 +3872,8 @@ const ExtractEntry extractProviders[] = {
 
 	{ kEob1EnemyMageSpellList, kEob1EnemyMageSpellListProvider },
 	{ kEob1EnemyMageSfx, kEob1EnemyMageSfxProvider },
-	{ kEob1MonsterDistAttType17, kEob1MonsterDistAttType17Provider },
-	{ kEob1MonsterDistAttSfx17, kEob1MonsterDistAttSfx17Provider },
+	{ kEob1BeholderSpellList, kEob1BeholderSpellListProvider },
+	{ kEob1BeholderSfx, kEob1BeholderSfxProvider },
 	{ kEob1TurnUndeadString, kEob1TurnUndeadStringProvider },
 
 	{ kEob1NpcShpData, kEob1NpcShpDataProvider },
diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
index f48e850..6491dfa 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -78,7 +78,7 @@ Common::Error EobEngine::init() {
 
 	_scriptTimersCount = 1;
 
-	//_wllWallFlags[132] = 0x1f;
+	_wllWallFlags[132] = 1;
 	_wllWallFlags[133] = 1;
 
 	return Common::kNoError;
@@ -222,7 +222,9 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 
 		if (!checkScriptFlag(0x100000)) {
 			if (deletePartyItems(6, -1)) {
-				TXT(28);
+				//_npcSequenceSub = 0;
+				//drawNpcScene(npcIndex);
+				TXT(28);				
 				createItemOnCurrentBlock(32);
 				setScriptFlag(0x100000);
 				r = 1;
@@ -423,7 +425,7 @@ void EobEngine::drawDoorIntern(int type, int index, int x, int y, int w, int wal
 		case 7:
 		case 8:
 		case 9:
-			y = _dscDoorY7[mDim] - _doorShapes[shapeIndex + 3][1];
+			y = _dscDoorY3[mDim] - _doorShapes[shapeIndex + 3][1];
 			d1 = x - (_doorShapes[shapeIndex + 3][2] << 2);
 			x -= (shp[2] << 2);
 			drawBlockObject(0, 2, _doorShapes[shapeIndex + 3], d1, y, 5);
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 5fc50f6..b9406ff 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -57,8 +57,8 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_monsterDustStrings = 0;
 	_enemyMageSpellList = 0;
 	_enemyMageSfx = 0;
-	_monsterDistAttType17 = 0;
-	_monsterDistAttSfx17 = 0;
+	_beholderSpellList = 0;
+	_beholderSfx = 0;
 
 	_faceShapes = 0;
 	_characters = 0;
@@ -853,8 +853,8 @@ void EobCoreEngine::recalcArmorClass(int index) {
 	if (c->effectFlags & 0x4000) {
 		int8 m1 = 5;
 
-		if (getCharacterClericPaladinLevel(index) > 5)
-			m1 += ((getCharacterClericPaladinLevel(index) - 5) / 3);
+		if (getClericPaladinLevel(index) > 5)
+			m1 += ((getClericPaladinLevel(index) - 5) / 3);
 
 		if (c->armorClass > m1)
 			c->armorClass = m1;
@@ -893,7 +893,7 @@ int EobCoreEngine::validateWeaponSlotItem(int index, int slot) {
 	return r;
 }
 
-int EobCoreEngine::getCharacterClericPaladinLevel(int index) {
+int EobCoreEngine::getClericPaladinLevel(int index) {
 	if (_castScrollSlot)
 		return 9;
 
@@ -913,7 +913,7 @@ int EobCoreEngine::getCharacterClericPaladinLevel(int index) {
 	return 1;
 }
 
-int EobCoreEngine::getCharacterMageLevel(int index) {
+int EobCoreEngine::getMageLevel(int index) {
 	if (_castScrollSlot)
 		return 9;
 
@@ -1682,7 +1682,7 @@ int EobCoreEngine::closeDistanceAttack(int charIndex, Item item) {
 
 		uint16 flg = 0x100;
 
-		if ((_flags.gameID == GI_EOB1 && _items[item].type > 51 && _items[item].type < 57) || (_flags.gameID == GI_EOB2 && isMagicWeapon(item)))
+		if (isMagicEffectItem(item))
 			flg |= 1;
 
 		_dstMonsterIndex = r;
@@ -1966,6 +1966,10 @@ void EobCoreEngine::monsterCloseAttack(EobMonsterInPlay *m) {
 			if (!monsterAttackHitTest(m, c))
 				continue;
 			dmg += rollDice(_monsterProps[m->type].dmgDc[ii].times, _monsterProps[m->type].dmgDc[ii].pips, _monsterProps[m->type].dmgDc[ii].base);
+			if (_characters[c].effectsRemainder[1]) {
+				if (--_characters[c].effectsRemainder[1])
+					dmg = 0;
+			}
 		}
 
 		if (dmg > 0) {
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 1b701cf..8675828 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -367,8 +367,9 @@ protected:
 
 	void recalcArmorClass(int index);
 	int validateWeaponSlotItem(int index, int slot);
-	int getCharacterClericPaladinLevel(int index);
-	int getCharacterMageLevel(int index);
+
+	int getClericPaladinLevel(int index);
+	int getMageLevel(int index);
 	int getCharacterLevelIndex(int type, int cClass);
 
 	int countCharactersWithSpecificItems(int16 itemType, int16 itemValue);
@@ -429,7 +430,7 @@ protected:
 	void printFullItemName(Item item);
 	void identifyQueuedItems(Item itemQueue);
 	void drawItemIconShape(int pageNum, Item itemId, int x, int y);
-	bool isMagicWeapon(Item itemIndex);
+	bool isMagicEffectItem(Item itemIndex);
 	bool checkInventoryForRings(int charIndex, int itemValue);
 	void eatItemInHand(int charIndex);
 
@@ -549,8 +550,8 @@ protected:
 	
 	const uint8 *_enemyMageSpellList;
 	const uint8 *_enemyMageSfx;
-	const uint8 *_monsterDistAttType17;
-	const uint8 *_monsterDistAttSfx17;
+	const uint8 *_beholderSpellList;
+	const uint8 *_beholderSfx;
 	const char *const *_monsterSpecAttStrings;
 
 	const int8 *_monsterFrmOffsTable1;
@@ -912,57 +913,63 @@ protected:
 	bool magicObjectStatusHit(EobMonsterInPlay *m, int type, bool tryEvade, int mod);
 	bool turnUndeadHit(EobMonsterInPlay *m, int hitChance, int casterLevel);
 
+	int getMagicWeaponSlot(int charIndex);
+	int createMagicWeaponType(int invFlags, int handFlags, int armorClass, int allowedClasses, int dmgNum, int dmgPips, int dmgInc, int extraProps);
+	Item createMagicWeaponItem(int flags, int icon, int value, int type);
+	void removeMagicWeaponItem(Item item);
+
 	int findSingleSpellTarget(int dist);
 
 	void printWarning(const char *str);
 	void printNoEffectWarning();
 
 	void spellCallback_start_empty() {}
-	bool spellCallback_end_empty(EobFlyingObject *fo) { return true; }
+	bool spellCallback_end_empty(void*) { return true; }
 	void spellCallback_start_armor();
 	void spellCallback_start_burningHands();
 	void spellCallback_start_detectMagic();
-	bool spellCallback_end_detectMagic(EobFlyingObject *fo);
+	bool spellCallback_end_detectMagic(void*);
 	void spellCallback_start_magicMissile();
-	bool spellCallback_end_magicMissile(EobFlyingObject *fo);
+	bool spellCallback_end_magicMissile(void *obj);
 	void spellCallback_start_shockingGrasp();
-	bool spellCallback_end_shockingGraspFlameBlade(EobFlyingObject *fo);
+	bool spellCallback_end_shockingGraspFlameBlade(void *obj);
 	void spellCallback_start_improvedIdentify();
 	void spellCallback_start_melfsAcidArrow();
-	bool spellCallback_end_melfsAcidArrow(EobFlyingObject *fo);
+	bool spellCallback_end_melfsAcidArrow(void *obj);
 	void spellCallback_start_dispelMagic();
 	void spellCallback_start_fireball();
-	bool spellCallback_end_fireball(EobFlyingObject *fo);
+	bool spellCallback_end_fireball(void *obj);
 	void spellCallback_start_flameArrow();
-	bool spellCallback_end_flameArrow(EobFlyingObject *fo);
+	bool spellCallback_end_flameArrow(void *obj);
 	void spellCallback_start_holdPerson();
-	bool spellCallback_end_holdPerson(EobFlyingObject *fo);
+	bool spellCallback_end_holdPerson(void *obj);
 	void spellCallback_start_lightningBolt();
-	bool spellCallback_end_lightningBolt(EobFlyingObject *fo);
+	bool spellCallback_end_lightningBolt(void *obj);
 	void spellCallback_start_vampiricTouch();
-	bool spellCallback_end_vampiricTouch(EobFlyingObject *fo);
+	bool spellCallback_end_vampiricTouch(void *obj);
 	void spellCallback_start_fear();
 	void spellCallback_start_iceStorm();
-	bool spellCallback_end_iceStorm(EobFlyingObject *fo);
+	bool spellCallback_end_iceStorm(void *obj);
+	void spellCallback_start_stoneSkin();
 	void spellCallback_start_removeCurse();
 	void spellCallback_start_coneOfCold();
 	void spellCallback_start_holdMonster();
-	bool spellCallback_end_holdMonster(EobFlyingObject *fo);
+	bool spellCallback_end_holdMonster(void *obj);
 	void spellCallback_start_wallOfForce();
 	void spellCallback_start_disintegrate();
 	void spellCallback_start_fleshToStone();
 	void spellCallback_start_stoneToFlesh();
 	void spellCallback_start_trueSeeing();
-	bool spellCallback_end_trueSeeing(EobFlyingObject *fo);
+	bool spellCallback_end_trueSeeing(void*);
 	void spellCallback_start_slayLiving();
 	void spellCallback_start_powerWordStun();
 	void spellCallback_start_causeLightWounds();
 	void spellCallback_start_cureLightWounds();
 	void spellCallback_start_aid();
-	bool spellCallback_end_aid(EobFlyingObject *fo);
+	bool spellCallback_end_aid(void *obj);
 	void spellCallback_start_flameBlade();
 	void spellCallback_start_slowPoison();
-	bool spellCallback_end_slowPoison(EobFlyingObject *fo);
+	bool spellCallback_end_slowPoison(void *obj);
 	void spellCallback_start_createFood();
 	void spellCallback_start_removeParalysis();
 	void spellCallback_start_causeSeriousWounds();
@@ -971,19 +978,19 @@ protected:
 	void spellCallback_start_causeCriticalWounds();
 	void spellCallback_start_cureCriticalWounds();
 	void spellCallback_start_flameStrike();
-	bool spellCallback_end_flameStrike(EobFlyingObject *fo);
+	bool spellCallback_end_flameStrike(void *obj);
 	void spellCallback_start_raiseDead();
 	void spellCallback_start_harm();
 	void spellCallback_start_heal();
 	void spellCallback_start_layOnHands();
 	void spellCallback_start_turnUndead();
-	bool spellCallback_end_kuotoaAttack(EobFlyingObject *fo);
-	bool spellCallback_end_unk1Passive(EobFlyingObject *fo);
-	bool spellCallback_end_unk2Passive(EobFlyingObject *fo);
-	bool spellCallback_end_deathSpellPassive(EobFlyingObject *fo);
-	bool spellCallback_end_disintegratePassive(EobFlyingObject *fo);
-	bool spellCallback_end_causeCriticalWoundsPassive(EobFlyingObject *fo);
-	bool spellCallback_end_fleshToStonePassive(EobFlyingObject *fo);
+	bool spellCallback_end_lightningBoltPassive(void *obj);
+	bool spellCallback_end_unk1Passive(void *obj);
+	bool spellCallback_end_unk2Passive(void *obj);
+	bool spellCallback_end_deathSpellPassive(void*);
+	bool spellCallback_end_disintegratePassive(void*);
+	bool spellCallback_end_causeCriticalWoundsPassive(void*);
+	bool spellCallback_end_fleshToStonePassive(void*);
 
 	int8 _openBookSpellLevel;
 	int8 _openBookSpellSelectedItem;
@@ -997,11 +1004,11 @@ protected:
 	int8 *_openBookAvailableSpells;
 	uint8 _activeSpellCharId;
 	uint8 _activeSpellCharacterPos;
-	uint8 _activeSpell;
+	int _activeSpell;
 	bool _returnAfterSpellCallback;
 
 	typedef void (EobCoreEngine::*SpellStartCallback)();
-	typedef bool (EobCoreEngine::*SpellEndCallback)(EobFlyingObject *fo);
+	typedef bool (EobCoreEngine::*SpellEndCallback)(void *obj);
 
 	struct EobSpell {
 		const char *name;
diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
index e2d2870..a83207b 100644
--- a/engines/kyra/items_eob.cpp
+++ b/engines/kyra/items_eob.cpp
@@ -208,7 +208,7 @@ int EobCoreEngine::validateInventorySlotForItem(Item item, int charIndex, int sl
 	int itm = _characters[charIndex].inventory[slot];
 	int ex = _itemTypes[_items[itm].type].extraProperties & 0x7f;
 
-	if (slot < 2 && _items[itm].flags & 0x20 && ex > 0 && ex < 4) {
+	if (slot < 2 && (_items[itm].flags & 0x20) && ex > 0 && ex < 4) {
 		if (_flags.gameID == GI_EOB2)
 			_txt->printMessage(_validateCursedString[0], -1, _characters[charIndex].name);
 		return 0;
@@ -474,8 +474,8 @@ void EobCoreEngine::drawItemIconShape(int pageNum, Item itemId, int x, int y) {
 	}
 }
 
-bool EobCoreEngine::isMagicWeapon(Item itemIndex) {
-	return (_items[itemIndex].type > 10 && _items[itemIndex].type < 18);
+bool EobCoreEngine::isMagicEffectItem(Item itemIndex) {
+	return (itemIndex > 10 && itemIndex < 18);
 }
 
 bool EobCoreEngine::checkInventoryForRings(int charIndex, int itemValue) {
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index d06e15b..88046fd 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -192,7 +192,7 @@ void EobCoreEngine::castSpell(int spell, int weaponSlot) {
 			return;
 		}
 
-		if (isMagicWeapon(c->inventory[0]) || isMagicWeapon(c->inventory[1])) {
+		if (isMagicEffectItem(c->inventory[0]) || isMagicEffectItem(c->inventory[1])) {
 			printWarning(_magicStrings1[3]);
 			return;
 		}
@@ -239,7 +239,7 @@ void EobCoreEngine::removeCharacterEffect(int spell, int charIndex, int showWarn
 		printWarning(Common::String::format(_magicStrings3[_flags.gameID == GI_EOB1 ? 3 : 2], c->name, s->name).c_str());
 
 	if (s->endCallback)
-		(this->*s->endCallback)(0);
+		(this->*s->endCallback)(c);
 
 	if (s->flags & 1)
 		c->effectFlags &= ~s->effectFlags;
@@ -270,13 +270,15 @@ void EobCoreEngine::removeCharacterEffect(int spell, int charIndex, int showWarn
 
 void EobCoreEngine::removeAllCharacterEffects(int charIndex) {
 	EobCharacter *c = &_characters[charIndex];
+	c->effectFlags = 0;
 	memset(c->effectsRemainder, 0, 4);
 
 	for (int i = 0; i < 10; i++) {
-		if (c->events[i] < 0)
+		if (c->events[i] < 0) {
 			removeCharacterEffect(-c->events[i], charIndex, 0);
-		c->timers[i] = 0;
-		c->events[i] = 0;
+			c->timers[i] = 0;
+			c->events[i] = 0;
+		}
 	}
 
 	setupCharacterTimers();
@@ -444,7 +446,7 @@ void EobCoreEngine::sparkEffectOffensive() {
 }
 
 void EobCoreEngine::setSpellEventTimer(int spell, int timerBaseFactor, int timerLength, int timerLevelFactor, int updateExistingTimer) {
-	int l = _openBookType == 1 ? getCharacterClericPaladinLevel(_openBookChar) : getCharacterMageLevel(_openBookChar);
+	int l = _openBookType == 1 ? getClericPaladinLevel(_openBookChar) : getMageLevel(_openBookChar);
 	uint32 countdown = timerLength * timerBaseFactor + timerLength * l * timerLevelFactor;
 	setCharEventTimer(_activeSpellCharId, countdown, -spell, updateExistingTimer);
 }
@@ -632,6 +634,63 @@ bool EobCoreEngine::turnUndeadHit(EobMonsterInPlay *m, int hitChance, int caster
 	return true;
 }
 
+int EobCoreEngine::getMagicWeaponSlot(int charIndex) {
+	return _characters[charIndex].inventory[1] ? 0 : 1;
+}
+
+int EobCoreEngine::createMagicWeaponType(int invFlags, int handFlags, int armorClass, int allowedClasses, int dmgNumDice, int dmgPips, int dmgInc, int extraProps) {
+	int i = 51;
+	for (; i < 57; i++) {
+		if (_itemTypes[i].armorClass == -30)
+			break;
+	}
+
+	if (i == 57)
+		return -1;
+
+	EobItemType *tp = &_itemTypes[i];
+	tp->invFlags = invFlags;
+	tp->requiredHands = 0;
+	tp->handFlags = handFlags;
+	tp->armorClass = armorClass;
+	tp->allowedClasses = allowedClasses;
+	tp->dmgNumDiceL = tp->dmgNumDiceS = dmgNumDice;
+	tp->dmgNumPipsL = tp->dmgNumPipsL = dmgPips;
+	tp->dmgIncL = tp->dmgIncS = dmgInc;
+	tp->extraProperties = extraProps;
+
+	return i;
+}
+
+Item EobCoreEngine::createMagicWeaponItem(int flags, int icon, int value, int type) {
+	Item i = 11;
+	for (; i < 17; i++) {
+		if (_items[i].block == -2)
+			break;
+	}
+
+	if (i == 17)
+		return -1;
+
+	EobItem *itm = &_items[i];
+	itm->flags = 0x20 | flags;
+	itm->icon = icon;
+	itm->value = value;
+	itm->type = type;
+	itm->pos = 0;
+	itm->block = 0;
+	itm->nameId = itm->nameUnid = 0;
+	itm->prev = itm->next = 0;
+
+	return i;
+}
+
+void EobCoreEngine::removeMagicWeaponItem(Item item) {
+	_itemTypes[_items[item].type].armorClass = -30;
+	_items[item].block = -2;
+	_items[item].level = -1;
+}
+
 int EobCoreEngine::findSingleSpellTarget(int dist) {
 	uint16 bl = _currentBlock;
 	int res = -1;
@@ -658,7 +717,7 @@ void EobCoreEngine::printNoEffectWarning() {
 }
 
 void EobCoreEngine::spellCallback_start_armor() {
-	_characters[_activeSpellCharId].effectsRemainder[0] = getCharacterMageLevel(_openBookChar) + 8;
+	_characters[_activeSpellCharId].effectsRemainder[0] = getMageLevel(_openBookChar) + 8;
 	if ((getDexterityArmorClassModifier(_characters[_activeSpellCharId].dexterityCur) + 6) >= _characters[_activeSpellCharId].armorClass)
 		printWarning(Common::String::format(_magicStrings6[0], _characters[_activeSpellCharId].name).c_str());
 }
@@ -672,7 +731,7 @@ void EobCoreEngine::spellCallback_start_burningHands() {
 	_screen->updateScreen();
 	delay(2 * _tickLength);
 	
-	int cl = getCharacterMageLevel(_openBookChar);
+	int cl = getMageLevel(_openBookChar);
 	int bl = calcNewBlockPosition(_currentBlock, _currentDirection);
 
 	const int8 *pos = getMonstersOnBlockPositions(bl);
@@ -692,10 +751,11 @@ void EobCoreEngine::spellCallback_start_burningHands() {
 }
 
 void EobCoreEngine::spellCallback_start_detectMagic() {
-
+	setHandItem(_itemInHand);
 }
 
-bool EobCoreEngine::spellCallback_end_detectMagic(EobFlyingObject*) {
+bool EobCoreEngine::spellCallback_end_detectMagic(void*) {
+	setHandItem(_itemInHand);
 	return true;
 }
 
@@ -703,15 +763,33 @@ void EobCoreEngine::spellCallback_start_magicMissile() {
 	launchMagicObject(_openBookChar, 0, _currentBlock, _activeSpellCharacterPos, _currentDirection);
 }
 
-bool EobCoreEngine::spellCallback_end_magicMissile(EobFlyingObject *fo) {
-	return magicObjectDamageHit(fo, 1, 4, 1, (getCharacterMageLevel(fo->attackerId) - 1) >> 1);
+bool EobCoreEngine::spellCallback_end_magicMissile(void *obj) {
+	EobFlyingObject *fo = (EobFlyingObject*)obj;
+	return magicObjectDamageHit(fo, 1, 4, 1, (getMageLevel(fo->attackerId) - 1) >> 1);
 }
 
 void EobCoreEngine::spellCallback_start_shockingGrasp() {
-
+	int t = createMagicWeaponType(0, 0, 0, 0x0f, 1, 8, getMageLevel(_openBookChar), 1);
+	Item i = (t != -1) ? createMagicWeaponItem(0x10, 82, 0, t) : -1;
+	if (t == -1 || i == -1) {
+		if (_flags.gameID == GI_EOB2)
+			printWarning(_magicStrings8[0]);
+		removeCharacterEffect(_activeSpell, _activeSpellCharId, 0);
+		deleteCharEventTimer(_activeSpellCharId, -_activeSpell);
+		_returnAfterSpellCallback = true;
+	} else {
+		_characters[_activeSpellCharId].inventory[getMagicWeaponSlot(_activeSpellCharId)] = i;
+	}
 }
 
-bool EobCoreEngine::spellCallback_end_shockingGraspFlameBlade(EobFlyingObject*) {
+bool EobCoreEngine::spellCallback_end_shockingGraspFlameBlade(void *obj) {
+	EobCharacter *c = (EobCharacter*)obj;
+	for (int i = 0; i < 2; i++) {
+		if (isMagicEffectItem(c->inventory[i])) {
+			removeMagicWeaponItem(c->inventory[i]);
+			c->inventory[i] = 0;
+		}
+	}
 	return true;
 }
 
@@ -723,36 +801,43 @@ void EobCoreEngine::spellCallback_start_melfsAcidArrow() {
 	launchMagicObject(_openBookChar, 1, _currentBlock, _activeSpellCharacterPos, _currentDirection);
 }
 
-bool EobCoreEngine::spellCallback_end_melfsAcidArrow(EobFlyingObject *fo) {
+bool EobCoreEngine::spellCallback_end_melfsAcidArrow(void *obj) {
+	EobFlyingObject *fo = (EobFlyingObject*)obj;
 	assert(fo);
-	return magicObjectDamageHit(fo, 2, 4, 0, getCharacterMageLevel(fo->attackerId) / 3);
+	return magicObjectDamageHit(fo, 2, 4, 0, getMageLevel(fo->attackerId) / 3);
 }
 
 void EobCoreEngine::spellCallback_start_dispelMagic() {
-
+	for (int i = 0; i < 6; i++) {
+		if (testCharacter(i, 1))
+			removeAllCharacterEffects(i);
+	}
 }
 
 void EobCoreEngine::spellCallback_start_fireball() {
 	launchMagicObject(_openBookChar, 2, _currentBlock, _activeSpellCharacterPos, _currentDirection);
 }
 
-bool EobCoreEngine::spellCallback_end_fireball(EobFlyingObject *fo) {
-	return magicObjectDamageHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
+bool EobCoreEngine::spellCallback_end_fireball(void *obj) {
+	EobFlyingObject *fo = (EobFlyingObject*)obj;
+	return magicObjectDamageHit(fo, 1, 6, 0, getMageLevel(fo->attackerId));
 }
 
 void EobCoreEngine::spellCallback_start_flameArrow() {
 	launchMagicObject(_openBookChar, 3, _currentBlock, _activeSpellCharacterPos, _currentDirection);
 }
 
-bool EobCoreEngine::spellCallback_end_flameArrow(EobFlyingObject *fo) {
-	return magicObjectDamageHit(fo, 5, 6, 0, getCharacterMageLevel(fo->attackerId));
+bool EobCoreEngine::spellCallback_end_flameArrow(void *obj) {
+	EobFlyingObject *fo = (EobFlyingObject*)obj;
+	return magicObjectDamageHit(fo, 5, 6, 0, getMageLevel(fo->attackerId));
 }
 
 void EobCoreEngine::spellCallback_start_holdPerson() {
 	launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 4 : 3, _currentBlock, _activeSpellCharacterPos, _currentDirection);
 }
 
-bool EobCoreEngine::spellCallback_end_holdPerson(EobFlyingObject *fo) {
+bool EobCoreEngine::spellCallback_end_holdPerson(void *obj) {
+	EobFlyingObject *fo = (EobFlyingObject*)obj;
 	bool res = false;
 	
 	if (_flags.gameID == GI_EOB2 && fo->curBlock == _currentBlock) {
@@ -781,15 +866,30 @@ void EobCoreEngine::spellCallback_start_lightningBolt() {
 	launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 5 : 4, _currentBlock, _activeSpellCharacterPos, _currentDirection);
 }
 
-bool EobCoreEngine::spellCallback_end_lightningBolt(EobFlyingObject *fo) {
-	return magicObjectDamageHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
+bool EobCoreEngine::spellCallback_end_lightningBolt(void *obj) {
+	EobFlyingObject *fo = (EobFlyingObject*)obj;
+	return magicObjectDamageHit(fo, 1, 6, 0, getMageLevel(fo->attackerId));
 }
 
 void EobCoreEngine::spellCallback_start_vampiricTouch() {
-
+	int t = createMagicWeaponType(0, 0, 0, 0x0f, getMageLevel(_openBookChar) >> 1, 6, 0, 1);
+	Item i = (t != -1) ? createMagicWeaponItem(0x18, 83, 0, t) : -1;
+	if (t == -1 || i == -1) {
+		if (_flags.gameID == GI_EOB2)
+			printWarning(_magicStrings8[0]);
+		removeCharacterEffect(_activeSpell, _activeSpellCharId, 0);
+		deleteCharEventTimer(_activeSpellCharId, -_activeSpell);
+		_returnAfterSpellCallback = true;
+	} else {
+		_characters[_activeSpellCharId].inventory[getMagicWeaponSlot(_activeSpellCharId)] = i;
+	}
 }
 
-bool EobCoreEngine::spellCallback_end_vampiricTouch(EobFlyingObject*) {
+bool EobCoreEngine::spellCallback_end_vampiricTouch(void *obj) {
+	EobCharacter *c = (EobCharacter*)obj;
+	if (c->hitPointsCur > c->hitPointsMax)
+		c->hitPointsCur = c->hitPointsMax;
+	spellCallback_end_shockingGraspFlameBlade(obj);
 	return true;
 }
 
@@ -806,24 +906,29 @@ void EobCoreEngine::spellCallback_start_iceStorm() {
 	launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 6 : 5, _currentBlock, _activeSpellCharacterPos, _currentDirection);
 }
 
-bool EobCoreEngine::spellCallback_end_iceStorm(EobFlyingObject *fo) {
+bool EobCoreEngine::spellCallback_end_iceStorm(void *obj) {
+	EobFlyingObject *fo = (EobFlyingObject*)obj;
 	static int8 blockAdv[] = { -32, 32, 1, -1 };
-	bool res = magicObjectDamageHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
+	bool res = magicObjectDamageHit(fo, 1, 6, 0, getMageLevel(fo->attackerId));
 	if (res) {
 		for (int i = 0; i < 4; i++) {
 			uint16 bl = fo->curBlock;
 			fo->curBlock = (fo->curBlock + blockAdv[i]) & 0x3ff;
-			magicObjectDamageHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
+			magicObjectDamageHit(fo, 1, 6, 0, getMageLevel(fo->attackerId));
 			fo->curBlock = bl;
 		}
 	}
 	return res;
 }
 
+void EobCoreEngine::spellCallback_start_stoneSkin() {
+	_characters[_activeSpellCharId].effectsRemainder[1] = (getMageLevel(_openBookChar) >> 1) + rollDice(1, 4);
+}
+
 void EobCoreEngine::spellCallback_start_removeCurse() {
 	for (int i = 0; i < 27; i++) {
 		Item itm = _characters[_activeSpellCharId].inventory[i];
-		if (itm && (_items[itm].flags & 0x20) && !isMagicWeapon(itm))
+		if (itm && (_items[itm].flags & 0x20) && !isMagicEffectItem(itm))
 			_items[itm].flags = (_items[itm].flags & ~0x20) | 0x40;
 	}
 }
@@ -831,7 +936,7 @@ void EobCoreEngine::spellCallback_start_removeCurse() {
 void EobCoreEngine::spellCallback_start_coneOfCold() {
 	static const int8 *dirTables[] = { _coneOfColdDest1, _coneOfColdDest2, _coneOfColdDest3, _coneOfColdDest4 };
 	
-	int cl = getCharacterMageLevel(_openBookChar);
+	int cl = getMageLevel(_openBookChar);
 	//drawConeOfColdEffect(150, 50, 10, 1, 100, _coneOfColdGfxTbl);
 	
 	const int8 *tbl = dirTables[_currentDirection];
@@ -849,7 +954,8 @@ void EobCoreEngine::spellCallback_start_holdMonster() {
 	launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 7 : 6, _currentBlock, _activeSpellCharacterPos, _currentDirection);
 }
 
-bool EobCoreEngine::spellCallback_end_holdMonster(EobFlyingObject *fo) {
+bool EobCoreEngine::spellCallback_end_holdMonster(void *obj) {
+	EobFlyingObject *fo = (EobFlyingObject*)obj;
 	bool res = false;
 	for (const int16 *m = findBlockMonsters(fo->curBlock, fo->curPos, fo->direction, 1, 1); *m != -1; m++)
 		res |= magicObjectStatusHit(&_monsters[*m], 1, true, 4);
@@ -888,16 +994,17 @@ void EobCoreEngine::spellCallback_start_trueSeeing() {
 	_wllVmpMap[46] = 0;
 }
 
-bool EobCoreEngine::spellCallback_end_trueSeeing(EobFlyingObject*) {
+bool EobCoreEngine::spellCallback_end_trueSeeing(void*) {
 	_wllVmpMap[46] = 1;
 	return true;
 }
 
 void EobCoreEngine::spellCallback_start_slayLiving() {
 	int d = findSingleSpellTarget(2);
-	if (d != -1)
+	if (d != -1) {
 		if (!magicObjectStatusHit(&_monsters[d], 3, true, 4))
 			inflictMonsterDamage(&_monsters[d], rollDice(2, 8, 1), true);
+	}
 }
 
 void EobCoreEngine::spellCallback_start_powerWordStun() {
@@ -917,22 +1024,55 @@ void EobCoreEngine::spellCallback_start_cureLightWounds() {
 }
 
 void EobCoreEngine::spellCallback_start_aid() {
+	if (!testCharacter(_activeSpellCharId, 3)) {
+		printNoEffectWarning();
+	} else if (_characters[_activeSpellCharId].effectsRemainder[3]) {
+		printWarning(Common::String::format(_magicStrings8[(_flags.gameID == GI_EOB1) ? 2 : 5], _characters[_activeSpellCharId].name).c_str());
+	} else {
+		_characters[_activeSpellCharId].effectsRemainder[3] = rollDice(1, 8);
+		_characters[_activeSpellCharId].hitPointsCur += _characters[_activeSpellCharId].effectsRemainder[3];
+		_characters[_activeSpellCharId].effectFlags |= 0x1000;
+		return;
+	}
 
+	removeCharacterEffect(_activeSpell, _activeSpellCharId, 0);
+	deleteCharEventTimer(_activeSpellCharId, -_activeSpell);
 }
 
-bool EobCoreEngine::spellCallback_end_aid(EobFlyingObject*) {
+bool EobCoreEngine::spellCallback_end_aid(void *obj) {
+	EobCharacter *c = (EobCharacter*)obj;
+	c->hitPointsCur -= c->effectsRemainder[3];
+	c->effectsRemainder[3] = 0;
+	c->effectFlags &= ~0x1000;
 	return true;
 }
 
 void EobCoreEngine::spellCallback_start_flameBlade() {
-
+	int t = createMagicWeaponType(0, 0, 0, 0x0f, 1, 4, 4, 1);
+	Item i = (t != -1) ? createMagicWeaponItem(0, 84, 0, t) : -1;
+	if (t == -1 || i == -1) {
+		if (_flags.gameID == GI_EOB2)
+			printWarning(_magicStrings8[0]);
+		removeCharacterEffect(_activeSpell, _activeSpellCharId, 0);
+		deleteCharEventTimer(_activeSpellCharId, -_activeSpell);
+		_returnAfterSpellCallback = true;
+	} else {
+		_characters[_activeSpellCharId].inventory[getMagicWeaponSlot(_activeSpellCharId)] = i;
+	}
 }
 
 void EobCoreEngine::spellCallback_start_slowPoison() {
-
+	if (_characters[_activeSpellCharId].flags & 2) {
+		_characters[_activeSpellCharId].effectFlags |= 0x2000;
+		setSpellEventTimer(_activeSpell, 1, 32760, 1, 1);
+	} else {
+		printNoEffectWarning();
+	}
 }
 
-bool EobCoreEngine::spellCallback_end_slowPoison(EobFlyingObject*) {
+bool EobCoreEngine::spellCallback_end_slowPoison(void *obj) {
+	EobCharacter *c = (EobCharacter*)obj;
+	c->effectFlags &= ~0x2000;
 	return true;
 }
 
@@ -963,7 +1103,10 @@ void EobCoreEngine::spellCallback_start_cureSeriousWounds() {
 }
 
 void EobCoreEngine::spellCallback_start_neutralizePoison() {
-
+	if (_characters[_activeSpellCharId].flags & 2)
+		neutralizePoison(_activeSpellCharId);
+	else
+		printNoEffectWarning();
 }
 
 void EobCoreEngine::spellCallback_start_causeCriticalWounds() {
@@ -978,7 +1121,8 @@ void EobCoreEngine::spellCallback_start_flameStrike() {
 	launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 8 : 7, _currentBlock, _activeSpellCharacterPos, _currentDirection);
 }
 
-bool EobCoreEngine::spellCallback_end_flameStrike(EobFlyingObject *fo) {
+bool EobCoreEngine::spellCallback_end_flameStrike(void *obj) {
+	EobFlyingObject *fo = (EobFlyingObject*)obj;
 	return magicObjectDamageHit(fo, 6, 8, 0, 0);
 }
 
@@ -1012,7 +1156,7 @@ void EobCoreEngine::spellCallback_start_turnUndead() {
 	if (!(_levelBlockProperties[bl].flags & 7))
 		return;
 	
-	int cl = _openBookCasterLevel ? _openBookCasterLevel : getCharacterClericPaladinLevel(_openBookChar);
+	int cl = _openBookCasterLevel ? _openBookCasterLevel : getClericPaladinLevel(_openBookChar);
 	int r = rollDice(1, 20);
 	bool hit = false;
 
@@ -1033,11 +1177,13 @@ void EobCoreEngine::spellCallback_start_turnUndead() {
 	_preventMonsterFlash = false;
 }
 
-bool EobCoreEngine::spellCallback_end_kuotoaAttack(EobFlyingObject *fo) {
+bool EobCoreEngine::spellCallback_end_lightningBoltPassive(void *obj) {
+	EobFlyingObject *fo = (EobFlyingObject*)obj;
 	return magicObjectDamageHit(fo, 0, 0, 12, 1);
 }
 
-bool EobCoreEngine::spellCallback_end_unk1Passive(EobFlyingObject *fo) {
+bool EobCoreEngine::spellCallback_end_unk1Passive(void *obj) {
+	EobFlyingObject *fo = (EobFlyingObject*)obj;
 	bool res = false;
 	if (_partyEffectFlags & 0x20000) {
 		res = magicObjectDamageHit(fo, 4, 10, 6, 0);
@@ -1051,23 +1197,24 @@ bool EobCoreEngine::spellCallback_end_unk1Passive(EobFlyingObject *fo) {
 	return res;
 }
 
-bool EobCoreEngine::spellCallback_end_unk2Passive(EobFlyingObject *fo) {
+bool EobCoreEngine::spellCallback_end_unk2Passive(void *obj) {
+	EobFlyingObject *fo = (EobFlyingObject*)obj;
 	return magicObjectDamageHit(fo, 0, 0, 18, 0);
 }
 
-bool EobCoreEngine::spellCallback_end_deathSpellPassive(EobFlyingObject *fo) {
+bool EobCoreEngine::spellCallback_end_deathSpellPassive(void*) {
 	return true;
 }
 
-bool EobCoreEngine::spellCallback_end_disintegratePassive(EobFlyingObject *fo) {
+bool EobCoreEngine::spellCallback_end_disintegratePassive(void*) {
 	return true;
 }
 
-bool EobCoreEngine::spellCallback_end_causeCriticalWoundsPassive(EobFlyingObject *fo) {
+bool EobCoreEngine::spellCallback_end_causeCriticalWoundsPassive(void*) {
 	return true;
 }
 
-bool EobCoreEngine::spellCallback_end_fleshToStonePassive(EobFlyingObject *fo) {
+bool EobCoreEngine::spellCallback_end_fleshToStonePassive(void*) {
 	return true;
 }
 
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index a54ae6c..b3a5aa3 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -487,8 +487,8 @@ enum KyraResources {
 
 	kEob1EnemyMageSpellList,
 	kEob1EnemyMageSfx,
-	kEob1MonsterDistAttType17,
-	kEob1MonsterDistAttSfx17,
+	kEob1BeholderSpellList,
+	kEob1BeholderSfx,
 
 	kEob1TurnUndeadString,
 
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index 945ccac..cb8ae51 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -55,7 +55,7 @@ namespace Kyra {
 
 void EobCoreEngine::loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex) {
 	Common::String s = filename;
-	if (GI_EOB1 && !scumm_stricmp(filename, "rust") || !scumm_stricmp(filename, "drider") || !scumm_stricmp(filename, "spider") || !scumm_stricmp(filename, "mantis") || !scumm_stricmp(filename, "xorn"))
+	if (GI_EOB1 && !scumm_stricmp(filename, "rust") || !scumm_stricmp(filename, "drider") || !scumm_stricmp(filename, "spider") || !scumm_stricmp(filename, "mantis") || !scumm_stricmp(filename, "xorn") || !scumm_stricmp(filename, "xanath"))
 		s += "1";
 
 	_screen->loadShapeSetBitmap(s.c_str(), 3, 3);
@@ -971,8 +971,8 @@ bool EobCoreEngine::updateMonsterTryDistanceAttack(EobMonsterInPlay *m) {
 				}
 				snd_processEnvironmentalSoundEffect(108, m->block);
 			} else {
-				launchMagicObject(-1, _monsterDistAttType17[m->numRemoteAttacks], m->block, m->pos, m->dir);
-				snd_processEnvironmentalSoundEffect(_monsterDistAttSfx17[m->numRemoteAttacks], m->block);
+				launchMagicObject(-1, _beholderSpellList[d], m->block, m->pos, m->dir);
+				snd_processEnvironmentalSoundEffect(_beholderSfx[d], m->block);
 			}
 			break;
 		default:
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index f30833c..b1ab606 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -803,7 +803,7 @@ void EobCoreEngine::initSpells() {
 	mp(2);	// Vampiric Touch
 	mpn;	// Fear
 	mpn;	// Ice Storm
-	mp1n;	// Stone Skin		/// --- para required?
+	mp1n;	// Stone Skin
 	mp1n;	// Cloud Kill		///
 	mp2(4);	// Improved Invisibility	///
 	mp2n;	// remove Curse		///
@@ -881,7 +881,8 @@ void EobCoreEngine::initSpells() {
 	sc(vampiricTouch);
 	sc(fear);
 	sc(iceStorm);
-	sc(empty);	// EOB1: stone skin, EOB2: imp invisibility
+	sc1(stoneSkin);	// stone skin
+	sc2(empty); // imp invisibility
 	sc1(empty); // Cloudkill
 	sc2(removeCurse);
 	sc(coneOfCold);
@@ -1004,7 +1005,7 @@ void EobCoreEngine::initSpells() {
 	ec2(empty);
 	ec(empty);
 	ec2(empty);
-	ec1(kuotoaAttack);
+	ec1(lightningBoltPassive);
 	ec2(unk1Passive);
 	ec2(empty);
 	ec2(unk2Passive);
@@ -1072,8 +1073,8 @@ void EobEngine::initStaticResource() {
 
 	_enemyMageSpellList = _staticres->loadRawData(kEob1EnemyMageSpellList, temp);
 	_enemyMageSfx = _staticres->loadRawData(kEob1EnemyMageSfx, temp);
-	_monsterDistAttType17 = _staticres->loadRawData(kEob1MonsterDistAttType17, temp);
-	_monsterDistAttSfx17 = _staticres->loadRawData(kEob1MonsterDistAttSfx17, temp);
+	_beholderSpellList = _staticres->loadRawData(kEob1BeholderSpellList, temp);
+	_beholderSfx = _staticres->loadRawData(kEob1BeholderSfx, temp);
 
 	_turnUndeadString = _staticres->loadStrings(kEob1TurnUndeadString, temp);
 
@@ -1162,7 +1163,7 @@ void EobEngine::initSpells() {
 		{ 0x0488, 0x000000, 0x01 },	// vampiric touch
 		{ 0x0100, 0x000000, 0x00 },	// fear
 		{ 0x0100, 0x000000, 0x41 },	// ice storm
-		{ 0x0000, 0x000000, 0x00 },	// STONE SKIN
+		{ 0x0033, 0x000001, 0x00 },	// STONE SKIN
 		{ 0x0000, 0x000000, 0x00 },	// CLOUD KILL
 		{ 0x0100, 0x000000, 0x41 },	// cone of cold
 		{ 0x0100, 0x000000, 0x00 },	// hold monster


Commit: 0d54aff6324b1f6c739df89ab072328cc5402873
    https://github.com/scummvm/scummvm/commit/0d54aff6324b1f6c739df89ab072328cc5402873
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:14-08:00

Commit Message:
KYRA: (EOB) - add EOB 1 intro

(also add and fix several other things, like cone of cold vortex, drawShape issues, etc.)

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    dists/engine-data/kyra.dat
    engines/kyra/chargen.cpp
    engines/kyra/eob1.cpp
    engines/kyra/eob1.h
    engines/kyra/eob2.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/magic_eob.cpp
    engines/kyra/resource.h
    engines/kyra/scene_eob.cpp
    engines/kyra/screen_eob.cpp
    engines/kyra/screen_eob.h
    engines/kyra/script_eob.cpp
    engines/kyra/script_eob.h
    engines/kyra/sequences_eob1.cpp
    engines/kyra/sequences_eob2.cpp
    engines/kyra/sprites_eob.cpp
    engines/kyra/staticres_eob.cpp
    engines/kyra/text_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index 8bd5bae..a8531dd 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -404,9 +404,37 @@ const ExtractFilename extractFilenames[] = {
 	{ kEobBaseMagicFlightProps, kTypeRawData, false },
 	{ kEobBaseTurnUndeadEffect, kTypeRawData, false },
 	{ kEobBaseBurningHandsDest, kTypeRawData, false },
+	{ kEobBaseConeOfColdDest1, kTypeRawData, false },
+	{ kEobBaseConeOfColdDest2, kTypeRawData, false },
+	{ kEobBaseConeOfColdDest3, kTypeRawData, false },
+	{ kEobBaseConeOfColdDest4, kTypeRawData, false },
+	{ kEobBaseConeOfColdGfxTbl, k3TypeRaw16to8, false },
 
 	// EYE OF THE BEHOLDER I
 	{ kEob1MainMenuStrings, kTypeStringList, true },
+	{ kEob1BonusStrings, kTypeStringList, true },
+
+	{ kEob1IntroFilesOpening, kTypeStringList, false },
+	{ kEob1IntroFilesTower, kTypeStringList, false },
+	{ kEob1IntroFilesOrb, kTypeStringList, false },
+	{ kEob1IntroFilesWdEntry, kTypeStringList, false },
+	{ kEob1IntroFilesKing, kTypeStringList, false },
+	{ kEob1IntroFilesHands, kTypeStringList, false },
+	{ kEob1IntroFilesWdExit, kTypeStringList, false },
+	{ kEob1IntroFilesTunnel, kTypeStringList, false },
+	{ kEob1IntroOpeningFrmDelay, k3TypeRaw16to8, false },
+	{ kEob1IntroWdEncodeX, kTypeRawData, false },
+	{ kEob1IntroWdEncodeY, kTypeRawData, false },
+	{ kEob1IntroWdEncodeWH, kTypeRawData, false },
+	{ kEob1IntroWdDsX, kLolTypeRaw16, false },
+	{ kEob1IntroWdDsY, kTypeRawData, false },
+	{ kEob1IntroTvlX1, kTypeRawData, false },
+	{ kEob1IntroTvlY1, kTypeRawData, false },
+	{ kEob1IntroTvlX2, kTypeRawData, false },
+	{ kEob1IntroTvlY2, kTypeRawData, false },
+	{ kEob1IntroTvlW, kTypeRawData, false },
+	{ kEob1IntroTvlH, kTypeRawData, false },
+
 	{ kEob1DoorShapeDefs, kTypeRawData, false },
 	{ kEob1DoorSwitchShapeDefs, kTypeRawData, false },
 	{ kEob1DoorSwitchCoords, kTypeRawData, false },
@@ -1644,8 +1672,60 @@ const char *getIdString(const int id) {
 		return "kEobBaseTurnUndeadEffect";
 	case kEobBaseBurningHandsDest:
 		return "kEobBaseBurningHandsDest";
+	case kEobBaseConeOfColdDest1:
+		return "kEobBaseConeOfColdDest1";
+	case kEobBaseConeOfColdDest2:
+		return "kEobBaseConeOfColdDest2";
+	case kEobBaseConeOfColdDest3:
+		return "kEobBaseConeOfColdDest3";
+	case kEobBaseConeOfColdDest4:
+		return "kEobBaseConeOfColdDest4";
+	case kEobBaseConeOfColdGfxTbl:
+		return "kEobBaseConeOfColdGfxTbl";
 	case kEob1MainMenuStrings:
 		return "kEob1MainMenuStrings";
+	case kEob1BonusStrings:
+		return "kEob1BonusStrings";
+	case kEob1IntroFilesOpening:
+		return "kEob1IntroFilesOpening";
+	case kEob1IntroFilesTower:
+		return "kEob1IntroFilesTower";
+	case kEob1IntroFilesOrb:
+		return "kEob1IntroFilesOrb";
+	case kEob1IntroFilesWdEntry:
+		return "kEob1IntroFilesWdEntry";
+	case kEob1IntroFilesKing:
+		return "kEob1IntroFilesKing";
+	case kEob1IntroFilesHands:
+		return "kEob1IntroFilesHands";
+	case kEob1IntroFilesWdExit:
+		return "kEob1IntroFilesWdExit";
+	case kEob1IntroFilesTunnel:
+		return "kEob1IntroFilesTunnel";
+	case kEob1IntroOpeningFrmDelay:
+		return "kEob1IntroOpeningFrmDelay";
+	case kEob1IntroWdEncodeX:
+		return "kEob1IntroWdEncodeX";
+	case kEob1IntroWdEncodeY:
+		return "kEob1IntroWdEncodeY";
+	case kEob1IntroWdEncodeWH:
+		return "kEob1IntroWdEncodeWH";
+	case kEob1IntroWdDsX:
+		return "kEob1IntroWdDsX";
+	case kEob1IntroWdDsY:
+		return "kEob1IntroWdDsY";
+	case kEob1IntroTvlX1:
+		return "kEob1IntroTvlX1";
+	case kEob1IntroTvlY1:
+		return "kEob1IntroTvlY1";
+	case kEob1IntroTvlX2:
+		return "kEob1IntroTvlX2";
+	case kEob1IntroTvlY2:
+		return "kEob1IntroTvlY2";
+	case kEob1IntroTvlW:
+		return "kEob1IntroTvlW";
+	case kEob1IntroTvlH:
+		return "kEob1IntroTvlH";
 	case kEob1DoorShapeDefs:
 		return "kEob1DoorShapeDefs";
 	case kEob1DoorSwitchCoords:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index 7cacbb5..44fa93a 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -405,8 +405,36 @@ enum kExtractID {
 	kEobBaseMagicFlightProps,
 	kEobBaseTurnUndeadEffect,
 	kEobBaseBurningHandsDest,
+	kEobBaseConeOfColdDest1,
+	kEobBaseConeOfColdDest2,
+	kEobBaseConeOfColdDest3,
+	kEobBaseConeOfColdDest4,
+	kEobBaseConeOfColdGfxTbl,
 
 	kEob1MainMenuStrings,
+	kEob1BonusStrings,
+
+	kEob1IntroFilesOpening,
+	kEob1IntroFilesTower,
+	kEob1IntroFilesOrb,
+	kEob1IntroFilesWdEntry,
+	kEob1IntroFilesKing,
+	kEob1IntroFilesHands,
+	kEob1IntroFilesWdExit,
+	kEob1IntroFilesTunnel,
+	kEob1IntroOpeningFrmDelay,
+	kEob1IntroWdEncodeX,
+	kEob1IntroWdEncodeY,
+	kEob1IntroWdEncodeWH,
+	kEob1IntroWdDsX,
+	kEob1IntroWdDsY,
+	kEob1IntroTvlX1,
+	kEob1IntroTvlY1,
+	kEob1IntroTvlX2,
+	kEob1IntroTvlY2,
+	kEob1IntroTvlW,
+	kEob1IntroTvlH,
+
 	kEob1DoorShapeDefs,
 	kEob1DoorSwitchShapeDefs,
 	kEob1DoorSwitchCoords,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 31f6dd6..9ecbf01 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -97,8 +97,8 @@ const Game kyra3Games[] = {
 };
 
 const Game eob1Games[] = {
-	{ kEob1, { EN_ANY, -1, -1 }, kPlatformPC, kNoSpecial, { "1bde1dd37b40ab6de8ad11be33a44c5a", 0 } },
-	{ kEob1, { DE_DEU, -1, -1 }, kPlatformPC, kNoSpecial, { "0fa3c6e00a81171b9f2adb3fdeb8eea3", 0 } },
+	{ kEob1, { EN_ANY, -1, -1 }, kPlatformPC, kNoSpecial, { "1bde1dd37b40ab6de8ad11be33a44c5a", "d760a605d1a1302d06975a1f209fdd72" } },
+	{ kEob1, { DE_DEU, -1, -1 }, kPlatformPC, kNoSpecial, { "0fa3c6e00a81171b9f2adb3fdeb8eea3", "756f300c62aabf1dbd3c26b3b04f8c00" } },
 	GAME_DUMMY_ENTRY
 };
 
@@ -1055,6 +1055,29 @@ const int eob1FloppyNeed[] = {
 	kEobBaseConstModExt,
 
 	kEob1MainMenuStrings,
+	kEob1BonusStrings,
+
+	kEob1IntroFilesOpening,
+	kEob1IntroFilesTower,
+	kEob1IntroFilesOrb,
+	kEob1IntroFilesWdEntry,
+	kEob1IntroFilesKing,
+	kEob1IntroFilesHands,
+	kEob1IntroFilesWdExit,
+	kEob1IntroFilesTunnel,
+	kEob1IntroOpeningFrmDelay,
+	kEob1IntroWdEncodeX,
+	kEob1IntroWdEncodeY,
+	kEob1IntroWdEncodeWH,
+	kEob1IntroWdDsX,
+	kEob1IntroWdDsY,
+	kEob1IntroTvlX1,
+	kEob1IntroTvlY1,
+	kEob1IntroTvlX2,
+	kEob1IntroTvlY2,
+	kEob1IntroTvlW,
+	kEob1IntroTvlH,
+
 	kEob1DoorShapeDefs,
 	kEob1DoorSwitchShapeDefs,
 	kEob1DoorSwitchCoords,
@@ -1190,6 +1213,11 @@ const int eob1FloppyNeed[] = {
 	kEobBaseMagicFlightProps,
 	kEobBaseTurnUndeadEffect,
 	kEobBaseBurningHandsDest,
+	kEobBaseConeOfColdDest1,
+	kEobBaseConeOfColdDest2,
+	kEobBaseConeOfColdDest3,
+	kEobBaseConeOfColdDest4,
+	kEobBaseConeOfColdGfxTbl,
 
 	kLolEobCommonDscDoorShapeIndex,
 	kEobBaseWllFlagPreset,
@@ -1411,6 +1439,11 @@ const int eob2FloppyNeed[] = {
 	kEobBaseMagicFlightProps,
 	kEobBaseTurnUndeadEffect,
 	kEobBaseBurningHandsDest,
+	kEobBaseConeOfColdDest1,
+	kEobBaseConeOfColdDest2,
+	kEobBaseConeOfColdDest3,
+	kEobBaseConeOfColdDest4,
+	kEobBaseConeOfColdGfxTbl,
 
 	kLolEobCommonDscDoorShapeIndex,
 	kEobBaseWllFlagPreset,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index d846372..ab75baf 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -2362,12 +2362,143 @@ const ExtractEntrySearchData kEobBaseBurningHandsDestProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEobBaseConeOfColdDest1Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000007, 0x00000500, { { 0x48, 0xF1, 0xFE, 0x48, 0xEC, 0x64, 0x17, 0x51, 0x5C, 0x9A, 0x91, 0x35, 0x95, 0xC3, 0x73, 0x8E } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseConeOfColdDest2Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000007, 0x00000210, { { 0xBA, 0x62, 0xA0, 0x4F, 0x50, 0x0C, 0x02, 0xC3, 0xAD, 0x7C, 0x39, 0x63, 0x5F, 0x41, 0xB4, 0xFB } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseConeOfColdDest3Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000007, 0x00000200, { { 0xA0, 0x1F, 0xAC, 0x3A, 0x2D, 0x25, 0x1F, 0x5C, 0xD2, 0x04, 0xAC, 0xAB, 0x97, 0x8B, 0x61, 0xD7 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseConeOfColdDest4Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000007, 0x000004F0, { { 0xB3, 0x9A, 0x2B, 0x3A, 0x51, 0x24, 0x95, 0xBE, 0xDE, 0x0F, 0xD5, 0xE9, 0xE9, 0x21, 0x96, 0x04 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseConeOfColdGfxTblProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000010, 0x0000003E, { { 0x0A, 0xBA, 0xFD, 0x3F, 0xD8, 0x49, 0x3F, 0xD2, 0x26, 0x1B, 0x19, 0x53, 0x4F, 0x84, 0xB9, 0x4F } } } },
+	EXTRACT_END_ENTRY
+};
+
 const ExtractEntrySearchData kEob1MainMenuStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000037, 0x00000D79, { { 0x1D, 0x72, 0x7F, 0x8F, 0xEB, 0x4A, 0xBF, 0x82, 0xB7, 0xB5, 0x9D, 0xB0, 0x7B, 0xDA, 0xEC, 0xEE } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000034, 0x00000C6F, { { 0xF2, 0x5F, 0xBE, 0xFB, 0x27, 0x1C, 0x91, 0x33, 0x25, 0x09, 0xC1, 0xA0, 0x27, 0x89, 0xD7, 0xD5 } } } },
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEob1BonusStringsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000093, 0x000031B6, { { 0xC1, 0x54, 0x1D, 0x02, 0x4A, 0x35, 0x7F, 0x5D, 0x84, 0x2D, 0x2C, 0x9C, 0x06, 0x97, 0x29, 0x8D } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000093, 0x000031CD, { { 0x3E, 0x0F, 0x52, 0x02, 0xC7, 0x9E, 0x83, 0xB3, 0xB1, 0xAB, 0x03, 0x3A, 0x18, 0xE2, 0x87, 0x2E } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroFilesOpeningProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000003F, 0x00001044, { { 0xF5, 0x8C, 0xC8, 0x39, 0x38, 0xBB, 0x0B, 0xCA, 0x34, 0x38, 0x1D, 0x11, 0x46, 0x91, 0xEF, 0x7E } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroFilesTowerProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000001A, 0x000006E6, { { 0xBD, 0x06, 0x3B, 0x7D, 0x24, 0x79, 0xD6, 0xC2, 0xFA, 0xDA, 0x31, 0x15, 0x3E, 0xE2, 0x75, 0xF8 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroFilesOrbProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000015, 0x00000565, { { 0xA7, 0x91, 0x97, 0x5B, 0x29, 0xE8, 0x27, 0x90, 0xB3, 0x8F, 0xD5, 0x13, 0x77, 0x4A, 0x93, 0x37 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroFilesWdEntryProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000002C, 0x00000B42, { { 0x5C, 0xDF, 0xB1, 0x2A, 0x83, 0x03, 0x73, 0x47, 0x1E, 0x29, 0x7C, 0x16, 0x2E, 0x5D, 0x0F, 0xA4 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroFilesKingProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000016, 0x000005AE, { { 0xB5, 0xB5, 0x80, 0xD3, 0xC0, 0xF4, 0x9F, 0xE1, 0x12, 0x3C, 0xCB, 0xD6, 0xF2, 0x7F, 0x15, 0x5B } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroFilesHandsProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000027C, { { 0x90, 0xC7, 0x36, 0xE6, 0x7D, 0x6D, 0xCB, 0x77, 0xA0, 0x03, 0x45, 0x48, 0x46, 0xF3, 0x80, 0xC8 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroFilesWdExitProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000033, 0x00000D2A, { { 0xA8, 0xF0, 0x36, 0x0E, 0x37, 0xC6, 0xCC, 0xDB, 0x9B, 0xB8, 0x52, 0x64, 0x02, 0x1E, 0x9D, 0x1C } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroFilesTunnelProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000001A, 0x000006E2, { { 0xA1, 0xDD, 0x20, 0x50, 0x7A, 0xB6, 0x89, 0x67, 0x13, 0xAA, 0x47, 0x6B, 0xC0, 0xA0, 0x8A, 0xFD } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroOpeningFrmDelayProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000000A, 0x000001E0, { { 0xDA, 0xE3, 0x06, 0xA2, 0x41, 0xF6, 0x5A, 0x6A, 0xBD, 0x0B, 0xA6, 0x09, 0x69, 0x03, 0x1D, 0x2C } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroWdEncodeXProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000001F, 0x000001BB, { { 0x00, 0x50, 0x8E, 0xF5, 0x51, 0xA6, 0xF5, 0x57, 0x0D, 0x55, 0x6C, 0x14, 0x62, 0xCD, 0xD0, 0x7E } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroWdEncodeYProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000001F, 0x0000000B, { { 0x39, 0x38, 0x02, 0xCE, 0x9D, 0x89, 0x1E, 0xBF, 0x32, 0x86, 0xA0, 0x79, 0xA4, 0xBE, 0xC5, 0x81 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroWdEncodeWHProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000001F, 0x00000027, { { 0xA8, 0x6C, 0x13, 0x2B, 0x4C, 0x26, 0x38, 0x3D, 0xDA, 0xC2, 0x90, 0xB3, 0x97, 0xA9, 0x45, 0x84 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroWdDsXProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000003E, 0x0000104A, { { 0xAC, 0x1F, 0xA6, 0x20, 0xD0, 0x02, 0xF0, 0x9D, 0x75, 0x93, 0x6C, 0x12, 0x0A, 0x76, 0x1B, 0x3F } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroWdDsYProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000001F, 0x00000655, { { 0xF3, 0xF7, 0x65, 0xEC, 0xEA, 0x5C, 0x08, 0xCF, 0xAD, 0x48, 0x35, 0xA2, 0x5B, 0x82, 0xB0, 0xC5 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroTvlX1Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x00000027, { { 0x7F, 0x14, 0x7D, 0x8C, 0x20, 0x49, 0xDB, 0xC3, 0x31, 0x1A, 0xC3, 0x95, 0xA4, 0x8C, 0x96, 0xDC } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroTvlY1Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x000000EC, { { 0x29, 0xB4, 0x8D, 0xE1, 0xDF, 0x36, 0x39, 0x27, 0xC8, 0xF6, 0x32, 0x1A, 0x3B, 0x74, 0xA1, 0x4F } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroTvlX2Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x00000051, { { 0x51, 0x33, 0x0A, 0x55, 0x76, 0xA2, 0x91, 0xDA, 0x59, 0xD6, 0x09, 0xD9, 0x3D, 0xD4, 0xB8, 0xFE } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroTvlY2Provider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x0000016A, { { 0xD5, 0xA3, 0xF6, 0x12, 0x90, 0x87, 0xF2, 0xC7, 0x6A, 0x22, 0x77, 0xB5, 0x48, 0xB2, 0xCB, 0xCA } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroTvlWProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x0000004E, { { 0xCF, 0xC7, 0xA8, 0x59, 0x6A, 0x5B, 0x35, 0x7F, 0xC9, 0xEC, 0x59, 0x7E, 0x88, 0x31, 0x32, 0xA6 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroTvlHProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x0000013D, { { 0x26, 0x7B, 0x3D, 0x5F, 0x64, 0x97, 0xF9, 0x1B, 0xB6, 0x65, 0x99, 0x95, 0x0A, 0x98, 0x38, 0x92 } } } },
+	EXTRACT_END_ENTRY
+};
+
 const ExtractEntrySearchData kEob1DoorShapeDefsProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000060, 0x00000F8A, { { 0x95, 0x53, 0x1B, 0x07, 0x64, 0x81, 0x0E, 0x04, 0xC0, 0xDA, 0xB5, 0x74, 0x57, 0x04, 0x10, 0xE2 } } } },
 	EXTRACT_END_ENTRY
@@ -3863,8 +3994,36 @@ const ExtractEntry extractProviders[] = {
 	{ kEobBaseMagicFlightProps, kEobBaseMagicFlightPropsProvider },
 	{ kEobBaseTurnUndeadEffect, kEobBaseTurnUndeadEffectProvider },
 	{ kEobBaseBurningHandsDest, kEobBaseBurningHandsDestProvider },
+	{ kEobBaseConeOfColdDest1, kEobBaseConeOfColdDest1Provider },
+	{ kEobBaseConeOfColdDest2, kEobBaseConeOfColdDest2Provider },
+	{ kEobBaseConeOfColdDest3, kEobBaseConeOfColdDest3Provider },
+	{ kEobBaseConeOfColdDest4, kEobBaseConeOfColdDest4Provider },
+	{ kEobBaseConeOfColdGfxTbl, kEobBaseConeOfColdGfxTblProvider },	
 
 	{ kEob1MainMenuStrings, kEob1MainMenuStringsProvider },
+	{ kEob1BonusStrings, kEob1BonusStringsProvider },
+
+	{ kEob1IntroFilesOpening, kEob1IntroFilesOpeningProvider },
+	{ kEob1IntroFilesTower, kEob1IntroFilesTowerProvider },
+	{ kEob1IntroFilesOrb, kEob1IntroFilesOrbProvider },
+	{ kEob1IntroFilesWdEntry, kEob1IntroFilesWdEntryProvider },
+	{ kEob1IntroFilesKing, kEob1IntroFilesKingProvider },
+	{ kEob1IntroFilesHands, kEob1IntroFilesHandsProvider },
+	{ kEob1IntroFilesWdExit, kEob1IntroFilesWdExitProvider },
+	{ kEob1IntroFilesTunnel, kEob1IntroFilesTunnelProvider },
+	{ kEob1IntroOpeningFrmDelay, kEob1IntroOpeningFrmDelayProvider },
+	{ kEob1IntroWdEncodeX, kEob1IntroWdEncodeXProvider },
+	{ kEob1IntroWdEncodeY, kEob1IntroWdEncodeYProvider },
+	{ kEob1IntroWdEncodeWH, kEob1IntroWdEncodeWHProvider },
+	{ kEob1IntroWdDsX, kEob1IntroWdDsXProvider },
+	{ kEob1IntroWdDsY, kEob1IntroWdDsYProvider },
+	{ kEob1IntroTvlX1, kEob1IntroTvlX1Provider },
+	{ kEob1IntroTvlY1, kEob1IntroTvlY1Provider },
+	{ kEob1IntroTvlX2, kEob1IntroTvlX2Provider },
+	{ kEob1IntroTvlY2, kEob1IntroTvlY2Provider },
+	{ kEob1IntroTvlW, kEob1IntroTvlWProvider },
+	{ kEob1IntroTvlH, kEob1IntroTvlHProvider },
+
 	{ kEob1DoorShapeDefs, kEob1DoorShapeDefsProvider },
 	{ kEob1DoorSwitchShapeDefs, kEob1DoorSwitchShapeDefsProvider },
 	{ kEob1DoorSwitchCoords, kEob1DoorSwitchCoordsProvider },
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index 494a395..aa3d62b 100644
Binary files a/dists/engine-data/kyra.dat and b/dists/engine-data/kyra.dat differ
diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index 6814129..e97b7a1 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -144,7 +144,7 @@ CharacterGenerator::~CharacterGenerator() {
 	}
 
 	if (_chargenButtonLabels) {
-		for (int i = 0; i < 10; i++)
+		for (int i = 0; i < 17; i++)
 			delete[] _chargenButtonLabels[i];
 		delete[] _chargenButtonLabels;
 	}
@@ -516,7 +516,7 @@ int CharacterGenerator::classMenu(int raceSex) {
 
 	toggleSpecialButton(5, 0, 0);
 
-	itemsMask &=_classMenuMasks[raceSex / 2];
+	itemsMask &= _classMenuMasks[raceSex / 2];
 	_vm->_gui->simpleMenu_setup(2, 15, _chargenClassStrings, itemsMask, 0, 0);
 
 	_vm->_mouseX = _vm->_mouseY = 0;
@@ -565,7 +565,7 @@ int CharacterGenerator::alignmentMenu(int cClass) {
 
 	toggleSpecialButton(5, 0, 0);
 
-	itemsMask &=_alignmentMenuMasks[cClass];
+	itemsMask &= _alignmentMenuMasks[cClass];
 	_vm->_gui->simpleMenu_setup(3, 9, _chargenAlignmentStrings, itemsMask, 0, 0);
 
 	_vm->_mouseX = _vm->_mouseY = 0;
diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
index 6491dfa..71644c5 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -172,23 +172,23 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 	case 0:
 		for (r = 1; r == 1; ) {
 			gui_drawDialogueBox();
-			r = DLG2A3(checkScriptFlag(0x2000), 8, 12, 11);
+			r = DLG2A3(checkScriptFlags(0x2000), 8, 12, 11);
 			if (r == 1) {
 				TXT(1);
-				setScriptFlag(0x2000);
+				setScriptFlags(0x2000);
 			} else if (r == 0) {
 				npcJoinDialogue(6, 12, 23, 2);
-				setScriptFlag(0x4000);
+				setScriptFlags(0x4000);
 			}
 		}
 		break;
 
 	case 1:
-		if (!checkScriptFlag(0x10000)) {
-			if (checkScriptFlag(0x8000)) {
+		if (!checkScriptFlags(0x10000)) {
+			if (checkScriptFlags(0x8000)) {
 				a = 1;
 			} else {
-				setScriptFlag(0x8000);
+				setScriptFlags(0x8000);
 				r = DLG2(3, 21);
 			}
 			if (!r)
@@ -198,7 +198,7 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 				for (a = 0; a < 6; a++)
 					createItemOnCurrentBlock(55);
 				createItemOnCurrentBlock(62);
-				setScriptFlag(0x10000);
+				setScriptFlags(0x10000);
 				TXT(6);
 				npcJoinDialogue(7, 7, 29, 30);
 			} else {
@@ -207,7 +207,7 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 			r = 1;
 		}
 
-		if (!checkScriptFlag(0x80000)) {
+		if (!checkScriptFlags(0x80000)) {
 			for (a = 0; a < 6; a++) {
 				if (testCharacter(a, 1) && _characters[a].portrait == -9)
 					break;
@@ -215,18 +215,18 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 			if (a != 6) {
 				TXT(25);
 				TXT(26);
-				setScriptFlag(0x80000);
+				setScriptFlags(0x80000);
 				r = 1;
 			}
 		}
 
-		if (!checkScriptFlag(0x100000)) {
+		if (!checkScriptFlags(0x100000)) {
 			if (deletePartyItems(6, -1)) {
 				//_npcSequenceSub = 0;
 				//drawNpcScene(npcIndex);
 				TXT(28);				
 				createItemOnCurrentBlock(32);
-				setScriptFlag(0x100000);
+				setScriptFlags(0x100000);
 				r = 1;
 			}
 		}
@@ -237,8 +237,8 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 		break;
 
 	case 2:
-		if (checkScriptFlag(0x10000)) {
-			if (checkScriptFlag(0x20000)) {
+		if (checkScriptFlags(0x10000)) {
+			if (checkScriptFlags(0x20000)) {
 				TXT(11);
 			} else {
 				r = DLG2A3(!countResurrectionCandidates(), 9, 31, 32);
@@ -247,7 +247,7 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 						healParty();
 					else
 						resurrectionSelectDialogue();
-					setScriptFlag(0x20000);
+					setScriptFlags(0x20000);
 				}				
 			}
 		} else {
@@ -257,14 +257,14 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 
 	case 3:
 		if (!DLG2(18, 4)) {
-			setScriptFlag(0x8400000);
+			setScriptFlags(0x8400000);
 			for (a = 0; a < 30; a++) {
 				if (_monsters[a].mode == 8)
 					_monsters[a].mode = 5;
 			}
 		} else if (deletePartyItems(49, -1)) {
 			TXT(20);
-			setScriptFlag(0x400000);
+			setScriptFlags(0x400000);
 		} else {
 			TXT(19);
 		}
@@ -273,10 +273,10 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 	case 4:
 		r = DLG3(14, 5);
 		if (r == 0)
-			setScriptFlag(0x200000);
+			setScriptFlags(0x200000);
 		else if (r == 1)
 			TXT(15);
-		setScriptFlag(0x800000);
+		setScriptFlags(0x800000);
 		break;
 
 	case 5:
@@ -292,12 +292,12 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 				}
 			}
 		}
-		setScriptFlag(0x2000000);
+		setScriptFlags(0x2000000);
 		break;
 
 	case 6:
 		TXT(21);
-		setScriptFlag(0x1000000);
+		setScriptFlags(0x1000000);
 		break;
 
 	case 7:
@@ -307,7 +307,7 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 				npcJoinDialogue(8, 27, 44, 45);
 			else
 				TXT(31);
-			setScriptFlag(0x4000000);
+			setScriptFlags(0x4000000);
 		}
 		break;
 
diff --git a/engines/kyra/eob1.h b/engines/kyra/eob1.h
index 21543dd..227db4f 100644
--- a/engines/kyra/eob1.h
+++ b/engines/kyra/eob1.h
@@ -55,6 +55,44 @@ private:
 	void seq_playIntro();
 	void seq_playFinale();
 
+	void seq_tower();
+	void seq_orb();
+	void seq_waterdeepEntry();
+	void seq_king();
+	void seq_hands();
+	void seq_waterdeepExit();
+	void seq_tunnel();	
+
+	void seq_xdeath();
+
+	void copyBlurRegion(int x1, int y1, int x2, int y2, int w, int h, int step);
+
+	void boxMorphTransition(int targetDestX, int targetDestY, int targetFinalX, int targetFinalY, int targetSrcX, int targetSrcY, int targetFinalW, int targetFinalH, int originX1, int originY1, int originW, int originH);
+	void whirlTransition();
+	
+	const char *const *_introFilesOpening;
+	const char *const *_introFilesTower;
+	const char *const *_introFilesOrb;
+	const char *const *_introFilesWdEntry;
+	const char *const *_introFilesKing;
+	const char *const *_introFilesHands;
+	const char *const *_introFilesWdExit;
+	const char *const *_introFilesTunnel;
+	const uint8 *_introOpeningFrmDelay;
+	const uint8 *_introWdEncodeX;
+	const uint8 *_introWdEncodeY;
+	const uint8 *_introWdEncodeWH;
+	const uint16 *_introWdDsX;
+	const uint8 *_introWdDsY;
+	const uint8 *_introTvlX1;
+	const uint8 *_introTvlY1;
+	const uint8 *_introTvlX2;
+	const uint8 *_introTvlY2;
+	const uint8 *_introTvlW;
+	const uint8 *_introTvlH;
+	
+	const char *const *_finBonusStrings;
+
 	// characters
 	void drawNpcScene(int npcIndex);
 	void encodeDrawNpcSeqShape(int npcIndex, int drawX, int drawY);
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index 9efc558..0ecdba0 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -106,7 +106,7 @@ void DarkMoonEngine::runNpcDialogue(int npcIndex) {
 	if (npcIndex == 0) {
 		snd_playSoundEffect(57);
 		if (npcJoinDialogue(0, 1, 3, 2))
-			setScriptFlag(0x40);
+			setScriptFlags(0x40);
 	} else if (npcIndex == 1) {
 		snd_playSoundEffect(53);
 		gui_drawDialogueBox();
@@ -120,7 +120,7 @@ void DarkMoonEngine::runNpcDialogue(int npcIndex) {
 			snd_playSoundEffect(91);
 			npcJoinDialogue(1, 5, 6, 7);
 		} else if (r == 1) {
-			setScriptFlag(0x20);
+			setScriptFlags(0x20);
 		}
 
 	} else if (npcIndex == 2) {
@@ -135,7 +135,7 @@ void DarkMoonEngine::runNpcDialogue(int npcIndex) {
 				_txt->printDialogueText(9, _okStrings[0]);
 			else
 				npcJoinDialogue(2, 102, 103, 104);
-			setScriptFlag(8);
+			setScriptFlags(8);
 		} else if (r == 1) {
 			_currentDirection = 0;
 		}
@@ -357,7 +357,7 @@ void DarkMoonEngine::restParty_npc() {
 	if (insalId < 4)
 		exchangeCharacters(insalId, testCharacter(5, 1) ? 5 : 4);
 
-	clearScriptFlag(6);
+	clearScriptFlags(6);
 
 	if (!stripPartyItems(1, 1, 1, 1))
 		stripPartyItems(2, 1, 1, 1);
@@ -391,7 +391,7 @@ void DarkMoonEngine::useHorn(int charIndex, int weaponSlot) {
 }
 
 bool DarkMoonEngine::checkPartyStatusExtra() {
-	if (checkScriptFlag(0x100000))
+	if (checkScriptFlags(0x100000))
 		seq_dranFools();
 	return _gui->confirmDialogue2(14, 67, 1);
 }
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index b9406ff..dc987c1 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -133,6 +133,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_activeSpellCharId = 0;
 	_activeSpellCharacterPos = 0;
 	_activeSpell = 0;
+	_characterSpellTarget = 0;
 	_returnAfterSpellCallback = false;
 	_spells = 0;
 	_spellAnimBuffer = 0;
@@ -447,6 +448,9 @@ void EobCoreEngine::runLoop() {
 		checkInput(_activeButtons, true, 0);
 		removeInputTop();
 
+		if (!_runFlag)
+			break;
+
 		_timer->update();
 		updateScriptTimers();
 
@@ -1499,10 +1503,6 @@ int EobCoreEngine::countResurrectionCandidates() {
 }
 
 void EobCoreEngine::seq_portal() {
-	releaseDoorShapes();
-	releaseMonsterShapes(0, 36);
-	releaseDecorations();
-
 	uint8 *shapes1[5];
 	uint8 *shapes2[5];
 	uint8 *shapes3[5];
@@ -1686,7 +1686,7 @@ int EobCoreEngine::closeDistanceAttack(int charIndex, Item item) {
 			flg |= 1;
 
 		_dstMonsterIndex = r;
-		return calcCloseDistanceMonsterDamage(&_monsters[r], charIndex, item, 1, flg, 5, 3);
+		return calcMonsterDamage(&_monsters[r], charIndex, item, 1, flg, 5, 3);
 	}
 
 	return 0;
@@ -1770,38 +1770,38 @@ void EobCoreEngine::inflictMonsterDamage(EobMonsterInPlay *m, int damage, bool g
 		m->dest = _currentBlock;
 }
 
-void EobCoreEngine::calcAndInflictMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int b, int damageType) {
-	int dmg = calcCloseDistanceMonsterDamage(m, times, pips, offs, flags, b, damageType);
+void EobCoreEngine::calcAndInflictMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int savingThrowType, int savingThrowEffect) {
+	int dmg = calcMonsterDamage(m, times, pips, offs, flags, savingThrowType, savingThrowEffect);
 	if (dmg > 0)
 		inflictMonsterDamage(m, dmg, flags & 0x800 ? true : false);
 }
 
-void EobCoreEngine::calcAndInflictCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flg, int a, int damageType) {
-	int dmg = calcCharacterDamage(charIndex, times, itemOrPips, useStrModifierOrBase, flg, a, damageType);
+void EobCoreEngine::calcAndInflictCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flags, int savingThrowType, int savingThrowEffect) {
+	int dmg = calcCharacterDamage(charIndex, times, itemOrPips, useStrModifierOrBase, flags, savingThrowType, savingThrowEffect);
 	if (dmg)
 		inflictCharacterDamage(charIndex, dmg);
 }
 
-int EobCoreEngine::calcCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flg, int a, int damageType) {
-	int s = (flg & 0x100) ? calcDamageModifers(times, 0, itemOrPips, _items[itemOrPips].type, useStrModifierOrBase) : rollDice(times, itemOrPips, useStrModifierOrBase);
+int EobCoreEngine::calcCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flags, int savingThrowType, int savingThrowEffect) {
+	int s = (flags & 0x100) ? calcDamageModifers(times, 0, itemOrPips, _items[itemOrPips].type, useStrModifierOrBase) : rollDice(times, itemOrPips, useStrModifierOrBase);
 	EobCharacter *c = &_characters[charIndex];
 
-	if (a != 5) {
-		if (checkMonsterLevelConstModifiers(c, _charClassModUnk[c->cClass], c->level[0], a, c->raceSex))
-			s = recalcDamageModifier(damageType, s);
+	if (savingThrowType != 5) {
+		if (trySavingThrow(c, _charClassModUnk[c->cClass], c->level[0], savingThrowType, c->raceSex))
+			s = savingThrowReduceDamage(savingThrowEffect, s);
 	}
 
-	if ((flg & 0x110) == 0x110) {
+	if ((flags & 0x110) == 0x110) {
 		if (!calcDamageCheckItemType(_items[itemOrPips].type))
 			s = 1;
 	}
 
-	if (flg & 4) {
+	if (flags & 4) {
 		if (checkInventoryForRings(charIndex, 3))
 			s = 0;
 	}
 
-	if (flg & 0x400) {
+	if (flags & 0x400) {
 		if (c->effectFlags & 0x2000)
 			s = 0;
 		else
@@ -2016,14 +2016,14 @@ void EobCoreEngine::monsterSpellCast(EobMonsterInPlay *m, int type) {
 	snd_processEnvironmentalSoundEffect(_spells[_magicFlightObjectProperties[type << 2]].sound, m->block);
 }
 
-void EobCoreEngine::statusAttack(int charIndex, int attackStatusFlags, const char *attackStatusString, int a, uint32 effectDuration, int restoreEvent, int noRefresh) {
+void EobCoreEngine::statusAttack(int charIndex, int attackStatusFlags, const char *attackStatusString, int savingThrowType, uint32 effectDuration, int restoreEvent, int noRefresh) {
 	EobCharacter *c = &_characters[charIndex];
 	if ((c->flags & attackStatusFlags) && noRefresh)
 		return;
 	if (!testCharacter(charIndex, 3))
 		return;
 
-	if (a != 5 && specialAttackConstTest(charIndex, a))
+	if (savingThrowType != 5 && specialAttackSavingThrow(charIndex, savingThrowType))
 		return;
 
 	if (attackStatusFlags & 8) {
@@ -2045,13 +2045,13 @@ void EobCoreEngine::statusAttack(int charIndex, int attackStatusFlags, const cha
 	_txt->printMessage(_characterStatusStrings13[0], -1, c->name, attackStatusString);
 }
 
-int EobCoreEngine::calcCloseDistanceMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int b, int damageType) {
+int EobCoreEngine::calcMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int savingThrowType, int savingThrowEffect) {
 	int s = flags & 0x100 ? calcDamageModifers(times, m, pips, _items[pips].type, offs) : rollDice(times, pips, offs);
 	EobMonsterProperty *p = &_monsterProps[m->type];
 
-	if (b == 5) {
-		if (checkMonsterLevelConstModifiers(m, 0, p->level, b, 6))
-			s = recalcDamageModifier(damageType, s);
+	if (savingThrowType != 5) {
+		if (trySavingThrow(m, 0, p->level, savingThrowType, 6))
+			s = savingThrowReduceDamage(savingThrowEffect, s);
 	}
 
 	if ((flags & 0x110) == 0x110) {
@@ -2110,14 +2110,14 @@ int EobCoreEngine::calcDamageModifers(int charIndex, EobMonsterInPlay *m, int it
 	return (s < 0) ? 0 : s;
 }
 
-bool EobCoreEngine::checkMonsterLevelConstModifiers(void *target, int hpModifier, int level, int b, int race) {
+bool EobCoreEngine::trySavingThrow(void *target, int hpModifier, int level, int type, int race) {
 	static const int8 constMod[] = { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5 };
 
-	if (b == 5)
+	if (type == 5)
 		return false;
 
-	int s = getConstModifierTableValue(hpModifier, level, b);
-	if (((race == 3 || race == 5) && (b == 4 || b == 1 || b == 0)) || (race == 4 && (b == 4 || b == 1))) {
+	int s = getConstModifierTableValue(hpModifier, level, type);
+	if (((race == 3 || race == 5) && (type == 4 || type == 1 || type == 0)) || (race == 4 && (type == 4 || type == 1))) {
 		EobCharacter *c = (EobCharacter*)target;
 		s -= constMod[c->constitutionCur];
 	}
@@ -2125,8 +2125,8 @@ bool EobCoreEngine::checkMonsterLevelConstModifiers(void *target, int hpModifier
 	return rollDice(1, 20) < s ? false : true;
 }
 
-bool EobCoreEngine::specialAttackConstTest(int charIndex, int b) {
-	return checkMonsterLevelConstModifiers(&_characters[charIndex], _charClassModUnk[_characters[charIndex].cClass], _characters[charIndex].level[0], b, _characters[charIndex].raceSex >> 1);
+bool EobCoreEngine::specialAttackSavingThrow(int charIndex, int type) {
+	return trySavingThrow(&_characters[charIndex], _charClassModUnk[_characters[charIndex].cClass], _characters[charIndex].level[0], type, _characters[charIndex].raceSex >> 1);
 }
 
 int EobCoreEngine::getConstModifierTableValue(int hpModifier, int level, int b) {
@@ -2144,14 +2144,14 @@ bool EobCoreEngine::calcDamageCheckItemType(int itemType) {
 	return (itemType == 2 || itemType == 3) ? true : false;
 }
 
-int EobCoreEngine::recalcDamageModifier(int damageType, int dmgModifier) {
-	if (damageType == 3)
+int EobCoreEngine::savingThrowReduceDamage(int savingThrowEffect, int damage) {
+	if (savingThrowEffect == 3)
 		return 0;
 
-	if (damageType == 0 || damageType == 1)
-		return dmgModifier >> 1;
+	if (savingThrowEffect == 0 || savingThrowEffect == 1)
+		return damage >> 1;
 
-	return dmgModifier;
+	return damage;
 }
 
 bool EobCoreEngine::tryMonsterAttackEvasion(EobMonsterInPlay *m) {
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 8675828..51dfb8b 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -260,6 +260,7 @@ protected:
 
 	// Main Menu, Intro, Finale
 	virtual int mainMenu() = 0;
+	virtual void seq_xdeath() {};
 	virtual void seq_playFinale() = 0;
 	bool _playFinale;
 
@@ -630,9 +631,9 @@ protected:
 
 	// Script
 	void runLevelScript(int block, int flags);
-	void setScriptFlag(int flag);
-	void clearScriptFlag(int flag);
-	bool checkScriptFlag(int flag);
+	void setScriptFlags(uint32 flags);
+	void clearScriptFlags(uint32 flags);
+	bool checkScriptFlags(uint32 flags);
 
 	const uint8 *initScriptTimers(const uint8 *pos);
 	void updateScriptTimers();
@@ -856,9 +857,9 @@ protected:
 	int projectileWeaponAttack(int charIndex, Item item);
 
 	void inflictMonsterDamage(EobMonsterInPlay *m, int damage, bool giveExperience);
-	void calcAndInflictMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int b, int damageType);
-	void calcAndInflictCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flg, int a, int damageType);
-	int calcCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flg, int a, int damageType) ;
+	void calcAndInflictMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int savingThrowType, int savingThrowEffect);
+	void calcAndInflictCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flags, int savingThrowType, int savingThrowEffect);
+	int calcCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flags, int savingThrowType, int damageType) ;
 	void inflictCharacterDamage(int charIndex, int damage);
 
 	bool characterAttackHitTest(int charIndex, int monsterIndex, int item, int attackType);
@@ -868,15 +869,15 @@ protected:
 
 	void monsterCloseAttack(EobMonsterInPlay *m);
 	void monsterSpellCast(EobMonsterInPlay *m, int type);
-	void statusAttack(int charIndex, int attackStatusFlags, const char *attackStatusString, int a, uint32 effectDuration, int restoreEvent, int noRefresh);
+	void statusAttack(int charIndex, int attackStatusFlags, const char *attackStatusString, int savingThrowType, uint32 effectDuration, int restoreEvent, int noRefresh);
 
-	int calcCloseDistanceMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int b, int damageType);
+	int calcMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int savingThrowType, int savingThrowEffect);
 	int calcDamageModifers(int charIndex, EobMonsterInPlay *m, int item, int itemType, int useStrModifier);
-	bool checkMonsterLevelConstModifiers(void *target, int hpModifier, int level, int b, int race);
-	bool specialAttackConstTest(int charIndex, int b);
+	bool trySavingThrow(void *target, int hpModifier, int level, int type, int race);
+	bool specialAttackSavingThrow(int charIndex, int type);
 	int getConstModifierTableValue(int hpModifier, int level, int b);
 	bool calcDamageCheckItemType(int itemType);
-	int recalcDamageModifier(int damageType, int dmgModifier);
+	int savingThrowReduceDamage(int savingThrowEffect, int damage);
 	bool tryMonsterAttackEvasion(EobMonsterInPlay *m);
 	int getStrHitChanceModifier(int charIndex);
 	int getStrDamageModifier(int charIndex);
@@ -912,6 +913,7 @@ protected:
 	bool magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level);
 	bool magicObjectStatusHit(EobMonsterInPlay *m, int type, bool tryEvade, int mod);
 	bool turnUndeadHit(EobMonsterInPlay *m, int hitChance, int casterLevel);
+	void causeWounds(int dcTimes, int dcPips, int dcOffs);
 
 	int getMagicWeaponSlot(int charIndex);
 	int createMagicWeaponType(int invFlags, int handFlags, int armorClass, int allowedClasses, int dmgNum, int dmgPips, int dmgInc, int extraProps);
@@ -919,6 +921,10 @@ protected:
 	void removeMagicWeaponItem(Item item);
 
 	int findSingleSpellTarget(int dist);
+	
+	int findFirstCharacterSpellTarget();
+	int findNextCharacterSpellTarget(int curCharIndex);
+	int charDeathSavingThrow(int charIndex, int div);
 
 	void printWarning(const char *str);
 	void printNoEffectWarning();
@@ -987,10 +993,10 @@ protected:
 	bool spellCallback_end_lightningBoltPassive(void *obj);
 	bool spellCallback_end_unk1Passive(void *obj);
 	bool spellCallback_end_unk2Passive(void *obj);
-	bool spellCallback_end_deathSpellPassive(void*);
-	bool spellCallback_end_disintegratePassive(void*);
-	bool spellCallback_end_causeCriticalWoundsPassive(void*);
-	bool spellCallback_end_fleshToStonePassive(void*);
+	bool spellCallback_end_deathSpellPassive(void *obj);
+	bool spellCallback_end_disintegratePassive(void *obj);
+	bool spellCallback_end_causeCriticalWoundsPassive(void *obj);
+	bool spellCallback_end_fleshToStonePassive(void *obj);
 
 	int8 _openBookSpellLevel;
 	int8 _openBookSpellSelectedItem;
@@ -1005,6 +1011,7 @@ protected:
 	uint8 _activeSpellCharId;
 	uint8 _activeSpellCharacterPos;
 	int _activeSpell;
+	int _characterSpellTarget;
 	bool _returnAfterSpellCallback;
 
 	typedef void (EobCoreEngine::*SpellStartCallback)();
@@ -1059,7 +1066,8 @@ protected:
 	const int8 *_coneOfColdDest2;
 	const int8 *_coneOfColdDest3;
 	const int8 *_coneOfColdDest4;
-	const int8 *_coneOfColdGfxTbl;
+	const uint8 *_coneOfColdGfxTbl;
+	int _coneOfColdGfxTblSize;
 
 	// Menu
 	EobMenuDef *_menuDefs;
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 393bbab..fcd66c9 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -385,7 +385,7 @@ void EobCoreEngine::gui_drawWeaponSlot(int charIndex, int slot) {
 
 	if (itm)
 		drawItemIconShape(_screen->_curPage, itm, x + 8, y);
-	else if (!slot && _flags.gameID == GI_EOB2 && checkScriptFlag(0x80000000))
+	else if (!slot && _flags.gameID == GI_EOB2 && checkScriptFlags(0x80000000))
 		_screen->drawShape(_screen->_curPage, _itemIconShapes[103], x + 8, y, 0);
 	else
 		_screen->drawShape(_screen->_curPage, _itemIconShapes[85], x + 8, y, 0);
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 88046fd..2ad0da7 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -314,17 +314,14 @@ void EobCoreEngine::startSpell(int spell) {
 	}
 
 	if ((s->flags & 0x30) && (s->effectFlags & c->effectFlags)) {
-		if (_flags.gameID == GI_EOB1) {
-			// TODO: warnings seem to exist at least for bless and aid
-		} else {
+		if (_flags.gameID == GI_EOB2)
 			printWarning(Common::String::format(_magicStrings7[0], c->name, s->name).c_str());
-		}
 	} else if ((s->flags & 0x50) && (s->effectFlags & _partyEffectFlags)) {
-		if (_flags.gameID == GI_EOB1) {
-			// TODO: warnings seem to exist at least for bless and aid
-		} else {
+		if (_flags.gameID == GI_EOB1 && s->effectFlags == 0x400)
+			// EOB 1 only warns in case of a bless spell
+			printWarning(_magicStrings8[1]);
+		else
 			printWarning(Common::String::format(_magicStrings7[1], s->name).c_str());
-		}
 	} else {
 		if (s->flags & 8)
 			setSpellEventTimer(spell, s->timingPara[0], s->timingPara[1], s->timingPara[2], s->timingPara[3]);
@@ -569,7 +566,7 @@ bool EobCoreEngine::magicObjectStatusHit(EobMonsterInPlay *m, int type, bool try
 			return true;
 	}
 
-	if (checkMonsterLevelConstModifiers(m, 0, p->level, mod, 6))
+	if (trySavingThrow(m, 0, p->level, mod, 6))
 		return false;
 	
 	int para = 0;
@@ -638,6 +635,26 @@ int EobCoreEngine::getMagicWeaponSlot(int charIndex) {
 	return _characters[charIndex].inventory[1] ? 0 : 1;
 }
 
+void EobCoreEngine::causeWounds(int dcTimes, int dcPips, int dcOffs) {
+	if (_openBookChar == 0 || _openBookChar == 1) {
+		int d = getClosestMonster(_openBookChar, calcNewBlockPosition(_currentBlock, _currentDirection));
+		if (d != -1) {
+			if (!characterAttackHitTest(_openBookChar, d, 0, 1))
+				return;
+			
+			if (dcTimes == -1) {
+				dcOffs = _monsters[d].hitPointsMax - rollDice(1, 4);
+				dcTimes = dcPips = 0;
+			}
+			calcAndInflictMonsterDamage(&_monsters[d], dcTimes, dcPips, dcOffs, 0x801, 4, 2);
+		} else {
+			printWarning(Common::String::format(_magicStrings3[_flags.gameID == GI_EOB1 ? 4 : 3], _characters[_openBookChar].name).c_str());
+		}
+	} else {
+		printWarning(Common::String::format(_magicStrings3[_flags.gameID == GI_EOB1 ? 5 : 4], _characters[_openBookChar].name).c_str());
+	}
+}
+
 int EobCoreEngine::createMagicWeaponType(int invFlags, int handFlags, int armorClass, int allowedClasses, int dmgNumDice, int dmgPips, int dmgInc, int extraProps) {
 	int i = 51;
 	for (; i < 57; i++) {
@@ -655,7 +672,7 @@ int EobCoreEngine::createMagicWeaponType(int invFlags, int handFlags, int armorC
 	tp->armorClass = armorClass;
 	tp->allowedClasses = allowedClasses;
 	tp->dmgNumDiceL = tp->dmgNumDiceS = dmgNumDice;
-	tp->dmgNumPipsL = tp->dmgNumPipsL = dmgPips;
+	tp->dmgNumPipsL = tp->dmgNumPipsS = dmgPips;
 	tp->dmgIncL = tp->dmgIncS = dmgInc;
 	tp->extraProperties = extraProps;
 
@@ -707,6 +724,33 @@ int EobCoreEngine::findSingleSpellTarget(int dist) {
 	return res;
 }
 
+int EobCoreEngine::findFirstCharacterSpellTarget() {
+	int curCharIndex = rollDice(1, 6, -1);
+	for (_characterSpellTarget = 0; _characterSpellTarget < 6; _characterSpellTarget++) {
+		if (testCharacter(curCharIndex, 3))
+			return curCharIndex;
+		if (++curCharIndex == 6)
+			curCharIndex = 0;
+	}
+	return -1;
+}
+
+int EobCoreEngine::findNextCharacterSpellTarget(int curCharIndex) {
+	for (; _characterSpellTarget < 6; _characterSpellTarget++) {
+		if (++curCharIndex == 6)
+			curCharIndex = 0;
+		if (testCharacter(curCharIndex, 3))
+			return curCharIndex;
+	}
+	return -1;
+}
+
+int EobCoreEngine::charDeathSavingThrow(int charIndex, int div) {
+	if (specialAttackSavingThrow(charIndex, 4))
+		div >>= 1;
+	return div;
+}
+
 void EobCoreEngine::printWarning(const char *str) {
 	_txt->printMessage(str);
 	snd_playSoundEffect(79);
@@ -794,7 +838,11 @@ bool EobCoreEngine::spellCallback_end_shockingGraspFlameBlade(void *obj) {
 }
 
 void EobCoreEngine::spellCallback_start_improvedIdentify() {
-
+	for (int i = 0; i < 2; i++) {
+		Item itm = _characters[_activeSpellCharId].inventory[i];
+		if (itm)
+			_items[itm].flags |= 0x40;
+	}
 }
 
 void EobCoreEngine::spellCallback_start_melfsAcidArrow() {
@@ -937,7 +985,15 @@ void EobCoreEngine::spellCallback_start_coneOfCold() {
 	static const int8 *dirTables[] = { _coneOfColdDest1, _coneOfColdDest2, _coneOfColdDest3, _coneOfColdDest4 };
 	
 	int cl = getMageLevel(_openBookChar);
-	//drawConeOfColdEffect(150, 50, 10, 1, 100, _coneOfColdGfxTbl);
+
+	_screen->setCurPage(2);
+	_screen->fillRect(0, 0, 176, 120, 0);
+	_screen->setGfxParameters(0, 0, _screen->getPagePixel(2, 0, 0));
+	drawSceneShapes(7);
+	_screen->setCurPage(0);
+	disableSysTimer(2);
+	_screen->drawVortex(150, 50, 10, 1, 100, _coneOfColdGfxTbl, _coneOfColdGfxTblSize);
+	enableSysTimer(2);
 	
 	const int8 *tbl = dirTables[_currentDirection];
 	_preventMonsterFlash = true;
@@ -1016,7 +1072,7 @@ void EobCoreEngine::spellCallback_start_powerWordStun() {
 }
 
 void EobCoreEngine::spellCallback_start_causeLightWounds() {
-
+	causeWounds(1, 8, 0);
 }
 
 void EobCoreEngine::spellCallback_start_cureLightWounds() {
@@ -1095,7 +1151,7 @@ void EobCoreEngine::spellCallback_start_removeParalysis() {
 }
 
 void EobCoreEngine::spellCallback_start_causeSeriousWounds() {
-	
+	causeWounds(2, 8, 1);
 }
 
 void EobCoreEngine::spellCallback_start_cureSeriousWounds() {
@@ -1110,7 +1166,7 @@ void EobCoreEngine::spellCallback_start_neutralizePoison() {
 }
 
 void EobCoreEngine::spellCallback_start_causeCriticalWounds() {
-
+	causeWounds(3, 8, 3);
 }
 
 void EobCoreEngine::spellCallback_start_cureCriticalWounds() {
@@ -1136,7 +1192,7 @@ void EobCoreEngine::spellCallback_start_raiseDead() {
 }
 
 void EobCoreEngine::spellCallback_start_harm() {
-
+	causeWounds(-1, -1, -1);
 }
 
 void EobCoreEngine::spellCallback_start_heal() {
@@ -1202,19 +1258,68 @@ bool EobCoreEngine::spellCallback_end_unk2Passive(void *obj) {
 	return magicObjectDamageHit(fo, 0, 0, 18, 0);
 }
 
-bool EobCoreEngine::spellCallback_end_deathSpellPassive(void*) {
+bool EobCoreEngine::spellCallback_end_deathSpellPassive(void *obj) {
+	EobFlyingObject *fo = (EobFlyingObject*)obj;
+	if (fo->curBlock != _currentBlock)
+		return false;
+
+	int numDest = rollDice(1, 4);
+	_txt->printMessage(_magicStrings2[2]);
+	for (int d = findFirstCharacterSpellTarget(); d != -1 && numDest; d = findNextCharacterSpellTarget(d)) {
+		if (_characters[d].level[0] < 8) {
+			inflictCharacterDamage(d, 300);
+			numDest--;
+		}
+	}
+
 	return true;
 }
 
-bool EobCoreEngine::spellCallback_end_disintegratePassive(void*) {
+bool EobCoreEngine::spellCallback_end_disintegratePassive(void *obj) {
+	EobFlyingObject *fo = (EobFlyingObject*)obj;
+	if (fo->curBlock != _currentBlock)
+		return false;
+	
+	int d = findFirstCharacterSpellTarget();
+	if (d != -1) {
+		if (!charDeathSavingThrow(d, 1)) {
+			inflictCharacterDamage(d, 300);
+			_txt->printMessage(_magicStrings2[1], -1, _characters[d].name);
+		}
+	}
+
 	return true;
 }
 
-bool EobCoreEngine::spellCallback_end_causeCriticalWoundsPassive(void*) {
+bool EobCoreEngine::spellCallback_end_causeCriticalWoundsPassive(void *obj) {
+	EobFlyingObject *fo = (EobFlyingObject*)obj;
+	if (fo->curBlock != _currentBlock)
+		return false;
+
+	int d = findFirstCharacterSpellTarget();
+	if (d != -1) {
+		_txt->printMessage(_magicStrings2[3], -1, _characters[d].name);
+		inflictCharacterDamage(d, rollDice(3, 8, 3));
+	}
+
 	return true;
 }
 
-bool EobCoreEngine::spellCallback_end_fleshToStonePassive(void*) {
+bool EobCoreEngine::spellCallback_end_fleshToStonePassive(void *obj) {
+	EobFlyingObject *fo = (EobFlyingObject*)obj;
+	if (fo->curBlock != _currentBlock)
+		return false;
+	
+	int d = findFirstCharacterSpellTarget();
+	while (d != -1) {
+		if (!charDeathSavingThrow(d, 2)) {
+			statusAttack(d, 8, _magicStrings2[4], 5, 0, 0, 1);
+			d = -1;
+		} else {
+			d = findNextCharacterSpellTarget(d);
+		}
+	}
+	
 	return true;
 }
 
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index b3a5aa3..5ed658c 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -478,8 +478,36 @@ enum KyraResources {
 	kEobBaseMagicFlightProps,
 	kEobBaseTurnUndeadEffect,
 	kEobBaseBurningHandsDest,
+	kEobBaseConeOfColdDest1,
+	kEobBaseConeOfColdDest2,
+	kEobBaseConeOfColdDest3,
+	kEobBaseConeOfColdDest4,
+	kEobBaseConeOfColdGfxTbl,
 
 	kEob1MainMenuStrings,
+	kEob1BonusStrings,
+
+	kEob1IntroFilesOpening,
+	kEob1IntroFilesTower,
+	kEob1IntroFilesOrb,
+	kEob1IntroFilesWdEntry,
+	kEob1IntroFilesKing,
+	kEob1IntroFilesHands,
+	kEob1IntroFilesWdExit,
+	kEob1IntroFilesTunnel,
+	kEob1IntroOpeningFrmDelay,
+	kEob1IntroWdEncodeX,
+	kEob1IntroWdEncodeY,
+	kEob1IntroWdEncodeWH,
+	kEob1IntroWdDsX,
+	kEob1IntroWdDsY,
+	kEob1IntroTvlX1,
+	kEob1IntroTvlY1,
+	kEob1IntroTvlX2,
+	kEob1IntroTvlY2,
+	kEob1IntroTvlW,
+	kEob1IntroTvlH,
+
 	kEob1DoorShapeDefs,
 	kEob1DoorSwitchShapeDefs,
 	kEob1DoorSwitchCoords,
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index 4c1bb16..aef131f 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -1139,10 +1139,10 @@ void EobCoreEngine::drawDecorations(int index) {
 int EobCoreEngine::calcNewBlockPositionAndTestPassability(uint16 curBlock, uint16 direction) {
 	uint16 b = calcNewBlockPosition(curBlock, direction);
 	int w = _levelBlockProperties[b].walls[direction ^ 2];
-	
 	int f = _wllWallFlags[w];
+
 	if (!f)
-		assert (w < (_flags.gameID == GI_EOB1 ? 70 : 80));
+		assert((_flags.gameID == GI_EOB1 && w < 70) || (_flags.gameID == GI_EOB2 && w < 80));
 
 	if (w == 74 && _currentBlock == curBlock) {
 		for (int i = 0; i < 5; i++) {
diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp
index ccbc2a1..c9ee911 100644
--- a/engines/kyra/screen_eob.cpp
+++ b/engines/kyra/screen_eob.cpp
@@ -189,14 +189,14 @@ void Screen_Eob::loadEobBitmap(const char *file, const uint8 *ditheringData, int
 	}
 }
 
-uint8 *Screen_Eob::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool flag) {
+uint8 *Screen_Eob::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4bitEncoding) {
 	uint8 *shp = 0;
 	uint16 shapesize = 0;
 
 	uint8 *srcPage = getPagePtr(_curPage) + y * 320 + (x << 3);
 	uint8 *src = srcPage;
 
-	if (flag) {
+	if (no4bitEncoding) {
 		uint16 h1 = h;
 		while (h1--) {
 			uint8 *lineEnd = src + (w << 3);
@@ -237,19 +237,20 @@ uint8 *Screen_Eob::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool flag
 			uint8 *lineEnd = src + (w << 3);
 			do {
 				uint8 val = *src++;
-				if (!val) {
-					*dst++ = val;
+				if (!val) {				
+					*dst++ = 0;
 					uint8 *startZeroPos = src;
+
 					while (src != lineEnd && *src == 0)
 						src++;
 
 					uint16 numZero = src - startZeroPos + 1;
 					if (numZero >> 8) {
-						numZero -= 0xff;
-						*dst++ = 0xff;
+						*dst++ = 255;
 						*dst++ = 0;
+						numZero -= 255;
 					}
-					val = (numZero & 0xff);
+					val = numZero & 0xff;
 				}
 				*dst++ = val;
 			} while (src != lineEnd);
@@ -384,7 +385,7 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
 		if (dX < 0) {
 			width += dX;
 			d = -dX;
-			if ((flags & 1))
+			if (flags & 1)
 				src -= (d >> 1);
 			else
 				src += (d >> 1);
@@ -415,7 +416,7 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
 		dY = 320 - width;
 		width >>= 1;
 		w2 >>= 1;
-		if ((flags & 1))
+		if (flags & 1)
 			src += (w2 - 1);
 
 		int16 w1shr = width;
@@ -431,7 +432,7 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
 			w1shr++;
 
 		int lineSrcStep = (w2 - w1shr);
-		if ((flags & 1))
+		if (flags & 1)
 			lineSrcStep = w3 - lineSrcStep;
 
 		while (dH--) {
@@ -503,20 +504,12 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
 				return;
 			d = -d;
 
-			for (int ii = 0; ii < d; ii++) {
+			for (int i = 0; i < d; i++) {
 				marginLeft = width;
-				int i = 0;
-				do {
-					for (i = 0; i < marginLeft; i++)
-						if (!*src++)
-							break;
-
-					if (!*(src-1) || i < marginLeft)
+				for (int ii = 0; ii < marginLeft; ii++) {
+					if (!*src++)
 						marginLeft = marginLeft + 1 - *src++;
-					else
-						marginLeft = 0;
-
-				} while (marginLeft);
+				}
 			}
             dY = _dsY1;
 		}
@@ -552,25 +545,40 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
 			marginRight = w2 - marginLeft - width;
 		}
 
-		dst += (y * 320 + dX);
+		dst += (dY * 320 + dX);
 		uint8 * dstL = dst;
 
 		if (pageNum == 0 || pageNum == 1)
 			addDirtyRect(rX, rY, rW, rH);
 
 		while (dH--) {
-			int16 xpos = (int16) marginLeft;
+			int16 xpos = (int16) marginLeft;			
+
+			if (flags & 1) {				
+				for (int i = 0; i < w2; i++) {
+					if (*src++ == 0) {
+						i += (*src - 1);
+						src += (*src - 1);
+					}
+				}
+				src--;
+			}
+			const uint8 *src2 = src;
 
 			if (xpos) {
 				do {
-					while (*src && xpos) {
-						src++;
+					uint8 val = (flags & 1) ? *(src - 1) : *src;
+					while (val && xpos) {
+						src += pixelStep;
 						xpos--;
+						val = (flags & 1) ? *(src - 1) : *src;
 					}
 
-					if (!*src) {
-						uint8 bt = *++src;
-						src++;
+					val = (flags & 1) ? *(src - 1) : *src;
+					if (!val) {
+						src += pixelStep;
+						uint8 bt = (flags & 1) ? src[1] : src[0];
+						src += pixelStep;
 						xpos = xpos - bt;
 					}
 				} while (xpos > 0);
@@ -580,28 +588,36 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
 			xpos += width;
 
 			while (xpos > 0) {
-				uint8 c = *src++;
+				uint8 c = *src;
+				uint8 m = (flags & 1) ? *(src - 1) : c;
+				src += pixelStep;
 
-				if (c) {
+				if (m) {
 					drawShapeSetPixel(dst++, c);
 					xpos--;
 				} else {
-					dst += *src;
-					xpos -= *src++;
+					uint8 len = (flags & 1) ? src[1] : src[0];
+					dst += len;
+					xpos -= len;
+					src += pixelStep;
 				}
 			}
 			xpos += marginRight;
 
 			if (xpos) {
 				do {
-					while (*src && xpos) {
-						src++;
+					uint8 val = (flags & 1) ? *(src - 1) : *src;
+					while (val && xpos) {
+						src += pixelStep;
 						xpos--;
+						val = (flags & 1) ? *(src - 1) : *src;
 					}
 
-					if (!*src) {
-						uint8 bt = *++src;
-						src++;
+					val = (flags & 1) ? *(src - 1) : *src;
+					if (!val) {
+						src += pixelStep;
+						uint8 bt = (flags & 1) ? src[1] : src[0];
+						src += pixelStep;
 						xpos = xpos - bt;
 					}
 				} while (xpos > 0);
@@ -609,6 +625,8 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
 
 			dstL += 320;
 			dst = dstL;
+			if (flags & 1)			
+				src = src2 + 1;
 		}
 	}
 }
@@ -707,7 +725,7 @@ void Screen_Eob::setGfxParameters(int x, int y, int col) {
 	_gfxCol = col;
 }
 
-void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize, int aspectRatio, const uint8 *colorTable, int colorTableSize) {
+void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepSize, int aspectRatio, const uint8 *colorTable, int colorTableSize) {
 	int ymin = 0;
 	int ymax = _gfxMaxY[scale];
 	int xmin = -100;
@@ -735,20 +753,20 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize
 	int16 *ptr7 = (int16*)&_dsTempPage[1500];
 	int16 *ptr8 = (int16*)&_dsTempPage[1800];
 
-	if (numSteps > 150)
-		numSteps = 150;
+	if (numElements > 150)
+		numElements = 150;
 
-	for (int i = 0; i < numSteps; i++) {
+	for (int i = 0; i < numElements; i++) {
 		ptr2[i] = ptr3[i] = 0;
 		ptr4[i] = _vm->_rnd.getRandomNumberRng(0, radius) - (radius >> 1);
 		ptr5[i] = _vm->_rnd.getRandomNumberRng(0, radius) - (radius >> 1) - (radius >> (8 - aspectRatio));
-		ptr7[i] = _vm->_rnd.getRandomNumberRng(1024/stepSize, 2048/stepSize);
+		ptr7[i] = _vm->_rnd.getRandomNumberRng(1024 / stepSize, 2048 / stepSize);
 		ptr8[i] = scale << 8;
 	}
 
 	for (int l = 2; l;) {
 		if (l != 2) {
-			for (int i = numSteps - 1; i >= 0; i--) {
+			for (int i = numElements - 1; i >= 0; i--) {
 				uint32 end = _system->getMillis() + 1;
 				int16 px = ((ptr2[i] >> 6) >> scale) + gx2;
 				int16 py = ((ptr3[i] >> 6) >> scale) + gy2;
@@ -760,7 +778,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize
 						updateScreen();
 						uint32 cur = _system->getMillis();
 						if (end > cur)
-						_system->delayMillis(end - cur);
+							_system->delayMillis(end - cur);
 					}
 				}
 			}			
@@ -768,7 +786,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize
 
 		l = 0;
 
-		for (int i = 0; i < numSteps; i++) {
+		for (int i = 0; i < numElements; i++) {
 			uint32 end = _system->getMillis() + 1;
 			if (ptr4[i] <= 0)
 				ptr4[i]++;
@@ -805,7 +823,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize
 						updateScreen();
 						uint32 cur = _system->getMillis();
 						if (end > cur)
-						_system->delayMillis(end - cur);
+							_system->delayMillis(end - cur);
 					}
 				}
 			} else {
@@ -817,12 +835,157 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize
 	showMouse();
 }
 
+void Screen_Eob::drawVortex(int numElements, int radius, int stepSize, int, int disorder, const uint8 *colorTable, int colorTableSize) {
+	int16 *xCoords = (int16*)_dsTempPage;
+	int16 *yCoords = (int16*)&_dsTempPage[300];
+	int16 *xMod = (int16*)&_dsTempPage[600];
+	int16 *yMod = (int16*)&_dsTempPage[900];
+	int16 *pixBackup = (int16*)&_dsTempPage[1200];
+	int16 *colTableStep = (int16*)&_dsTempPage[1500];
+	int16 *colTableIndex = (int16*)&_dsTempPage[1800];
+	int16 *pixDelay = (int16*)&_dsTempPage[2100];
+
+	hideMouse();
+	int cp = _curPage;
+
+	if (numElements > 150)
+		numElements = 150;
+
+	int cx = 88;
+	int cy = 48;
+	radius <<= 6;
+
+	for (int i = 0; i < numElements; i++) {
+		int16 v38 = _vm->_rnd.getRandomNumberRng(radius >> 2, radius);
+		int16 stepSum = 0;
+		int16 sqsum = 0;
+		while (sqsum < v38) {
+			stepSum += stepSize;
+			sqsum += stepSum;
+		}
+
+		switch (_vm->_rnd.getRandomNumber(255) & 3) {
+		case 0:
+			xCoords[i] = 32;
+			yCoords[i] = sqsum;
+			xMod[i] = stepSum;
+			yMod[i] = 0;
+			break;
+
+		case 1:
+			xCoords[i] = sqsum;
+			yCoords[i] = 32;
+			xMod[i] = 0;
+			yMod[i] = stepSum;
+			break;
+
+		case 2:
+			xCoords[i] = 32;
+			yCoords[i] = -sqsum;
+			xMod[i] = stepSum;
+			yMod[i] = 0;
+			break;
+
+		default:
+			xCoords[i] = -sqsum;
+			yCoords[i] = 32;
+			xMod[i] = 0;
+			yMod[i] = stepSum;
+			break;
+		}
+
+		if (_vm->_rnd.getRandomBit()) {
+			xMod[i] *= -1;
+			yMod[i] *= -1;
+		}
+
+		colTableStep[i] = _vm->_rnd.getRandomNumberRng(1024 / disorder, 2048 / disorder);
+		colTableIndex[i] = 0;
+		pixDelay[i] = _vm->_rnd.getRandomNumberRng(0, disorder >> 2);
+	}
+
+	int d = 0;
+	for (int i = 2; i; ) {
+		if (i != 2) {
+			uint32 nextDelay = _system->getMillis() + 1;
+			for (int ii = numElements - 1; ii >= 0; ii--) {
+				int16 px = CLIP((xCoords[ii] >> 6) + cx, 0, SCREEN_W - 1);
+				int16 py = CLIP((yCoords[ii] >> 6) + cy, 0, SCREEN_H - 1);
+				setPagePixel(0, px, py, pixBackup[ii]);
+		
+				if (ii % 15 == 0)  {
+					updateScreen();
+					uint32 cur = _system->getMillis();
+					if (nextDelay > cur)
+						_system->delayMillis(nextDelay - cur);
+					nextDelay += 1;
+				}
+			}
+		}
+
+		i = 0;
+		int r = (stepSize >> 1) + (stepSize >> 2) + (stepSize >> 3);
+		uint32 nextDelay2 = _system->getMillis() + 1;
+
+		for (int ii = 0; ii < numElements; ii++) {
+			if (pixDelay[ii] == 0) {
+				if (xCoords[ii] > 0) {
+					xMod[ii] -= ((xMod[ii] > 0) ? stepSize : r);
+				} else {
+					xMod[ii] += ((xMod[ii] < 0) ? stepSize : r);
+				}
+
+				if (yCoords[ii] > 0) {
+					yMod[ii] -= ((yMod[ii] > 0) ? stepSize : r);
+				} else {
+					yMod[ii] += ((yMod[ii] < 0) ? stepSize : r);
+				}
+
+				xCoords[ii] += xMod[ii];
+				yCoords[ii] += yMod[ii];
+				colTableIndex[ii] += colTableStep[ii];
+
+			} else {
+				pixDelay[ii]--;
+			}
+
+			int16 px = CLIP((xCoords[ii] >> 6) + cx, 0, SCREEN_W - 1);
+			int16 py = CLIP((yCoords[ii] >> 6) + cy, 0, SCREEN_H - 1);
+
+			uint8 tc1 =  ((disorder >> 2) <= d) ? getPagePixel(2, px, py) : 0;
+			pixBackup[ii] = getPagePixel(0, px, py);
+			uint8 tblIndex = CLIP(colTableIndex[ii] >> 8, 0, colorTableSize - 1);
+			uint8 tc2 = colorTable[tblIndex];
+
+			if (tc2) {
+				i = 1;
+				if (tc1 == _gfxCol && !pixDelay[ii]) {
+					setPagePixel(0, px, py, tc2);
+					if (ii % 15 == 0)  {
+						updateScreen();
+						uint32 cur = _system->getMillis();
+						if (nextDelay2 > cur)
+							_system->delayMillis(nextDelay2 - cur);
+						nextDelay2 += 1;
+					}
+				}
+			} else {
+				colTableStep[ii] = 0;
+			}
+		}
+		d++;
+	}
+
+	_curPage = cp;
+	showMouse();
+}
+
 void Screen_Eob::fadeTextColor(Palette *pal, int color1, int rate) {
 	uint8 *col = pal->getData();
 
 	for (bool loop = true; loop; ) {
 		loop = true;
-		uint32 end = _system->getMillis() + 16;
+		uint32 end = _system->getMillis() + 1;
 
 		loop = false;
 		for (int ii = 0; ii < 3; ii++) {
diff --git a/engines/kyra/screen_eob.h b/engines/kyra/screen_eob.h
index 909a561..d2d8881 100644
--- a/engines/kyra/screen_eob.h
+++ b/engines/kyra/screen_eob.h
@@ -54,7 +54,7 @@ public:
 	void loadEobBitmap(const char *file, const uint8 *ditheringData, int tempPage, int destPage, int copyToPage);
 	void loadShapeSetBitmap(const char *file, int tempPage, int destPage);
 
-	uint8 *encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool flag = false);
+	uint8 *encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4bitEncoding = false);
 	void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd = -1, int flags = 0, ...);
 	const uint8 *scaleShape(const uint8 *shapeData, int blockDistance);
 	const uint8 *scaleShapeStep(const uint8 *shp);
@@ -65,7 +65,8 @@ public:
 	void setShapeFadeMode (uint8 i, bool b);
 
 	void setGfxParameters(int x, int y, int col);
-	void drawExplosion(int scale, int radius, int numSteps, int stepSize, int aspectRatio, const uint8 *colorTable, int colorTableSize);
+	void drawExplosion(int scale, int radius, int numElements, int stepSize, int aspectRatio, const uint8 *colorTable, int colorTableSize);
+	void drawVortex(int numElements, int radius, int stepSize, int, int disorder, const uint8 *colorTable, int colorTableSize);
 
 	void fadeTextColor(Palette *pal, int color1, int fadeTextColor);
 	bool delayedFadePalStep(Palette *fadePal, Palette *destPal, int rate);
diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp
index 2b86aa8..15f3c80 100644
--- a/engines/kyra/script_eob.cpp
+++ b/engines/kyra/script_eob.cpp
@@ -36,16 +36,16 @@ void EobCoreEngine::runLevelScript(int block, int flags) {
 	_inf->run(block, flags);
 }
 
-void EobCoreEngine::setScriptFlag(int flag) {
-	_inf->setFlag(flag);
+void EobCoreEngine::setScriptFlags(uint32 flags) {
+	_inf->setFlags(flags);
 }
 
-void EobCoreEngine::clearScriptFlag(int flag) {
-	_inf->clearFlag(flag);
+void EobCoreEngine::clearScriptFlags(uint32 flags) {
+	_inf->clearFlags(flags);
 }
 
-bool EobCoreEngine::checkScriptFlag(int flag) {
-	return _inf->checkFlag(flag);
+bool EobCoreEngine::checkScriptFlags(uint32 flags) {
+	return _inf->checkFlags(flags);
 }
 
 const uint8 *EobCoreEngine::initScriptTimers(const uint8 *pos) {
@@ -198,16 +198,16 @@ void EobInfProcessor::run(int func, int sub) {
 	} while (!_abortScript && !_abortAfterSubroutine);
 }
 
-void EobInfProcessor::setFlag(int flag) {
-	_flagTable[17] |= flag;
+void EobInfProcessor::setFlags(uint32 flags) {
+	_flagTable[17] |= flags;
 }
 
-void EobInfProcessor::clearFlag(int flag) {
-	_flagTable[17] &= ~flag;
+void EobInfProcessor::clearFlags(uint32 flags) {
+	_flagTable[17] &= ~flags;
 }
 
-bool EobInfProcessor::checkFlag(int flag) const {
-	return (_flagTable[17] & flag) ? true : false;
+bool EobInfProcessor::checkFlags(uint32 flags) const {
+	return ((_flagTable[17] & flags) == flags) ? true : false;
 }
 
 bool EobInfProcessor::preventRest() const {
@@ -709,13 +709,13 @@ int EobInfProcessor::oeob_eval_v1(int8 *data) {
 	while (cmd != -18) {
 		switch (cmd + 38) {
 		case 0:
-			a = 0;
+			a = 1;
 			for (i = 0; i < 6; i++) {
 				if (!(_vm->_characters[i].flags & 1))
 					continue;
-				if (_vm->_characters[i].effectFlags & 4)
+				if (_vm->_characters[i].effectFlags & 0x40)
 					continue;
-				a = 1;
+				a = 0;
 				break;
 			}
 			_stack[_stackIndex++] = a;
@@ -806,7 +806,7 @@ int EobInfProcessor::oeob_eval_v1(int8 *data) {
 			break;
 
 		case 25:
-			_stack[_stackIndex++] = _vm->_levelBlockProperties[READ_LE_UINT16(pos)].flags ? 1 : 0;
+			_stack[_stackIndex++] = (_vm->_levelBlockProperties[READ_LE_UINT16(pos)].flags & 1) ? 1 : 0;
 			pos += 2;
 			break;
 
@@ -944,13 +944,13 @@ int EobInfProcessor::oeob_eval_v2(int8 *data) {
 			break;
 
 		case 12:
-			a = 0;
+			a = 1;
 			for (i = 0; i < 6; i++) {
 				if (!(_vm->_characters[i].flags & 1))
 					continue;
 				if (_vm->_characters[i].effectFlags & 0x40)
 					continue;
-				a = 1;
+				a = 0;
 				break;
 			}
 			_stack[_stackIndex++] = a;
@@ -1415,7 +1415,7 @@ int EobInfProcessor::oeob_sequence(int8 *data) {
 
 	switch (cmd) {
 	case -3:
-		// eob1 outro
+		_vm->seq_xdeath();
 		_vm->_runFlag = false;
 		_vm->_playFinale = true;
 		_abortScript = 1;
diff --git a/engines/kyra/script_eob.h b/engines/kyra/script_eob.h
index 71e53bc..648d214 100644
--- a/engines/kyra/script_eob.h
+++ b/engines/kyra/script_eob.h
@@ -42,9 +42,9 @@ public:
 	void loadData(const uint8 *data, uint32 dataSize);
 	void run(int func, int sub);
 
-	void setFlag(int flag);
-	void clearFlag(int flag);
-	bool checkFlag(int flag) const;
+	void setFlags(uint32 flags);
+	void clearFlags(uint32 flags);
+	bool checkFlags(uint32 flags) const;
 	bool preventRest() const;
 
 	void loadState(Common::SeekableSubReadStreamEndian &in);
diff --git a/engines/kyra/sequences_eob1.cpp b/engines/kyra/sequences_eob1.cpp
index 8f360c0..4c5bd17 100644
--- a/engines/kyra/sequences_eob1.cpp
+++ b/engines/kyra/sequences_eob1.cpp
@@ -104,43 +104,954 @@ int EobEngine::mainMenuLoop() {
 }
 
 void EobEngine::seq_playOpeningCredits() {
-	static const char *cmpList[] = { "WESTWOOD.CMP", "AND.CMP", "SSI.CMP", "PRESENT.CMP", "DAND.CMP" };
-	static const uint8 frameDelay[] = { 140, 50, 100, 50, 140 };
-
 	_allowSkip = true;
-	_screen->loadPalette("WESTWOOD.COL", _screen->getPalette(0));
+	_screen->loadPalette(_introFilesOpening[5], _screen->getPalette(0));
 	_screen->setScreenPalette(_screen->getPalette(0));
 
-	_screen->loadBitmap(cmpList[0], 5, 3, 0);
+	_screen->loadBitmap(_introFilesOpening[4], 5, 3, 0);
 	_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
 	_screen->updateScreen();
 
 	_sound->playTrack(1);
-	delay(frameDelay[0] * _tickLength);
+	delay(_introOpeningFrmDelay[0] * _tickLength);
 
-	for (int i = 1; i < 5 && !shouldQuit() && !skipFlag(); i++) {
-		_screen->loadBitmap(cmpList[i], 5, 3, 0);
-		uint32 nextFrameTimer = _system->getMillis() + frameDelay[i] * _tickLength;
+	for (int i = 0; i < 4 && !shouldQuit() && !skipFlag(); i++) {
+		_screen->loadBitmap(_introFilesOpening[i], 5, 3, 0);
+		uint32 nextFrameTimer = _system->getMillis() + _introOpeningFrmDelay[i + 1] * _tickLength;
 		_screen->crossFadeRegion(0, 50, 0, 50, 320, 102, 2, 0);
 		delayUntil(nextFrameTimer);
 	}
 
-	delay(50 * _tickLength);
 	_allowSkip = false;
 }
 
 void EobEngine::seq_playIntro() {
 	_allowSkip = true;
-	//_sound->playTrack(2);
 
+	if (!shouldQuit() && !skipFlag()) {
+		_sound->playTrack(2);
+		_screen->loadBitmap("TITLE-V.CMP", 5, 3, 0);
+		_screen->crossFadeRegion(0, 0, 0, 0, 320, 200, 2, 0);
+		delay(120 * _tickLength);
+	}
+
+	_screen->loadBitmap("TEXT.CMP", 3, 6, 0);
+
+	seq_tower();
+	seq_orb();
+	seq_waterdeepEntry();
+	seq_king();
+	seq_hands();
+	seq_waterdeepExit();
+	seq_tunnel();
+
+	whirlTransition();
+	_sound->haltTrack();
 	_allowSkip = false;
 }
 
 void EobEngine::seq_playFinale() {
-	_allowSkip = true;
+	Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
+	_screen->loadFileDataToPage(s, 5, 32000);
+	delete s;
 
+	snd_playSoundEffect(20);
+	
+	_txt->resetPageBreakString();
+	_txt->setWaitButtonMode(1);
+	_txt->setupField(12, true);
+	gui_drawBox(0, 0, 176, 175, _color1_1, _color2_1, _bkgColor_1);
+	_txt->printDialogueText(51, _moreStrings[0]);
+	
+	if (!checkScriptFlags(0x1ffe)) {
+		_screen->fadeToBlack();
+		return;
+	}
+	
+	_txt->printDialogueText(_finBonusStrings[0]);
+	for (int i = 0; i < 6; i++) {
+		_txt->printDialogueText(_finBonusStrings[1]);
+		if (_characters[i].flags & 1)
+			_txt->printDialogueText(_characters[i].name);
+	}
+	
+	uint32 password = 0;
+	for (int i = 0; i < 4; i++) {
+		if (!(_characters[i].flags & 1))
+			continue;
 
-	_allowSkip = false;
+		int len = strlen(_characters[i].name);
+		for (int ii = 0; ii < len; ii++) {
+			uint32 c = _characters[i].name[ii];
+			password += (c * c);
+		}
+	}
+
+	_txt->printDialogueText(Common::String::format(_finBonusStrings[2], password).c_str(), true);
+	_screen->fadeToBlack();
+}
+
+void EobEngine::seq_tower() {
+	if (shouldQuit() || skipFlag())
+		return;
+
+	_screen->loadPalette(_introFilesTower[0], _screen->getPalette(0));
+	_screen->loadBitmap(_introFilesTower[1], 5, 3, 0);
+	_screen->setCurPage(2);
+	uint8 *shp = _screen->encodeShape(0, 0, 16, 56, true);
+	_screen->copyPage(3, 4);
+	_screen->clearCurPage();
+
+	for (int i = 0; i < 200; i += 64)
+		_screen->copyRegion(128, 104, 96, i, 128, 64, 4, 2, Screen::CR_NO_P_CHECK);
+
+	_screen->fillRect(0, 184, 319, 199, 12);
+	int cp = _screen->setCurPage(0);
+	whirlTransition();
+	_screen->setScreenPalette(_screen->getPalette(0));
+	_screen->setCurPage(cp);
+	_screen->clearCurPage();
+
+	for (int i = 0; i < 200; i += 64)
+		_screen->copyRegion(128, 104, 0, i, 128, 64, 4, 2, Screen::CR_NO_P_CHECK);
+
+	_screen->setCurPage(0);
+
+	for (int i = 0; i < 64 && !shouldQuit() && !skipFlag(); i += 2) {
+		uint32 end = _system->getMillis() + 2 * _tickLength;
+		_screen->copyRegion(0, 142 - i, 96, 0, 128, i + 1, 4, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(0, 0, 96, i + 1, 128, 167 - i, 2, 0, Screen::CR_NO_P_CHECK);
+		if (!i)
+			_screen->copyRegion(0, 0, 0, 168, 320, 32, 6, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	for (int i = 0; i < 24 && !shouldQuit() && !skipFlag(); i += 2) {
+		uint32 end = _system->getMillis() + 2 * _tickLength;
+		_screen->copyRegion(0, 79 - i, 96, 0, 24, 65 + i, 4, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(104, 79 - i, 200, 0, 24, 65 + i, 4, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(24, 110, 120, i + 31, 80, 34, 4, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(152, 0, 120, 32, 80, i + 1, 4, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(0, 0, 96, 65 + i, 128, 103 - i, 2, 0, Screen::CR_NO_P_CHECK);	
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	for (int i = 0; i < 56 && !shouldQuit() && !skipFlag(); i += 2) {
+		uint32 end = _system->getMillis() + 2 * _tickLength;
+		_screen->copyRegion(0, 56, 96, i, 24, 54, 4, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(104, 56, 200, i, 24, 54, 4, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(0, 110, 96, 54 + i, 128, 34, 4, 0, Screen::CR_NO_P_CHECK);
+
+		if (i < 32) {
+			_screen->fillRect(128, 0, 255, i + 1, 12, 2);
+			_screen->copyRegion(152, 0, 120, 32, 80, i + 25, 4, 0, Screen::CR_NO_P_CHECK);
+		} else {
+			_screen->fillRect(128, 0, 255, i + 1, 12, 2);
+			_screen->copyRegion(152, i + 1, 120, 32 + i + 1, 80, 23, 4, 0, Screen::CR_NO_P_CHECK);
+			_screen->copyRegion(152, 0, 152, 32, 80, i + 1, 4, 2, Screen::CR_NO_P_CHECK);
+		}
+
+		_screen->drawShape(2, shp, 128, i - 55, 0);
+		_screen->copyRegion(128, 0, 96, 0, 128, i + 1, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(0, 0, 96, i + 89, 128, 79 - i, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_screen->copyRegion(0, 32, 0, 168, 320, 32, 6, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(65 * _tickLength);
+	delete[] shp;
+}
+
+void EobEngine::seq_orb() {
+	if (shouldQuit() || skipFlag())
+		return;
+
+	uint8 *shp[5];
+	_screen->loadBitmap(_introFilesOrb[0], 5, 3, 0);
+	_screen->setCurPage(2);
+	shp[4] = _screen->encodeShape(0, 0, 20, 136, true);
+	_screen->loadBitmap(_introFilesOrb[1], 5, 3, 0);
+	shp[3] = _screen->encodeShape(16, 0, 16, 104, true);
+	
+	_screen->fillRect(0, 0, 127, 103, 12);
+	for (int i = 1; i < 4; i++) {
+		copyBlurRegion(128, 0, 0, 0, 128, 104, i);
+		shp[3 - i] = _screen->encodeShape(0, 0, 16, 104, true);
+	}
+	
+	_screen->fillRect(0, 0, 159, 135, 12);
+	_screen->setCurPage(0);
+	_screen->copyPage(3, 4);
+	_screen->clearCurPage();
+	
+	_sound->playTrack(6);
+
+	for (int i = -1; i < 4 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + 3 * _tickLength;
+		if (i >= 0)
+			_screen->drawShape(2, shp[i], 16, 16, 0);
+		_screen->drawShape(2, shp[4], 0, 0, 0);
+		_screen->copyRegion(0, 0, 80, 24, 160, 136, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_screen->copyRegion(0, 64, 0, 168, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(40 * _tickLength);
+
+	_sound->playTrack(6);
+
+	for (int i = 3; i > -2 && !shouldQuit() && !skipFlag(); i--) {
+		uint32 end = _system->getMillis() + 3 * _tickLength;
+		_screen->fillRect(16, 16, 143, 119, 12, 2);
+		if (i >= 0)
+			_screen->drawShape(2, shp[i], 16, 16, 0);
+		_screen->drawShape(2, shp[4], 0, 0, 0);
+		_screen->copyRegion(0, 0, 80, 24, 160, 136, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	delay(40 * _tickLength);
+
+	for (int i = 0; i < 5; i++)
+		delete[] shp[i];
+}
+
+void EobEngine::seq_waterdeepEntry() {
+	if (shouldQuit() || skipFlag())
+		return;
+
+	uint8 *shp[4];
+	uint8 *shp2[31];
+	uint8 *shp3[3];
+
+	_screen->loadPalette(_introFilesWdEntry[0], _screen->getPalette(0));
+	_screen->setScreenPalette(_screen->getPalette(0));
+	_screen->loadBitmap(_introFilesWdEntry[1], 5, 3, 0);
+	_screen->setCurPage(2);
+	shp[3] = _screen->encodeShape(0, 0, 20, 136, true);
+	for (int i = 1; i < 4; i++) {
+		copyBlurRegion(0, 0, 0, 0, 160, 136, i);
+		shp[3 - i] = _screen->encodeShape(0, 0, 20, 136, true);
+	}
+	_screen->setCurPage(0);
+
+	_screen->copyPage(3, 4);
+	_screen->fillRect(0, 168, 319, 199, 12, 0);
+	_sound->playTrack(6);
+
+	for (int i = 0; i < 4 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + 3 * _tickLength;
+		_screen->drawShape(0, shp[i], 80, 24, 0);
+		delete[] shp[i];
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_screen->copyRegion(0, 80, 0, 168, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(50 * _tickLength);
+
+	_screen->setCurPage(2);
+	shp[0] = _screen->encodeShape(20, 0, 20, 136, true);
+	_screen->loadBitmap(_introFilesWdEntry[2], 5, 3, 0);
+	shp[1] = _screen->encodeShape(0, 0, 20, 136, true);
+	shp[2] = _screen->encodeShape(20, 0, 20, 136, true);
+	_screen->loadBitmap(_introFilesWdEntry[3], 5, 3, 0);
+
+	for (int i = 0; i < 31; i++)
+		shp2[i] = _screen->encodeShape(_introWdEncodeX[i], 136 + (_introWdEncodeY[i] << 3), _introWdEncodeWH[i], _introWdEncodeWH[i] << 3, true);
+	for (int i = 0; i < 3; i++)
+		shp3[i] = _screen->encodeShape(5 * i, 152, 5, 32, true);
+
+	_screen->copyPage(3, 4);
+
+	for (int i = 0; i < 3 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + 3 * _tickLength;
+		_screen->fillRect(0, 0, 159, 135, 12, 2);
+		_screen->drawShape(2, shp[i], 0, 0, 0);
+		_screen->copyRegion(0, 0, 80, 24, 160, 136, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_screen->copyRegion(0, 0, 80, 24, 160, 136, 4, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(4 * _tickLength);
+	_screen->copyRegion(160, 0, 80, 24, 160, 136, 4, 0, Screen::CR_NO_P_CHECK);
+	_screen->fillRect(0, 168, 319, 199, 12, 0);
+	_screen->updateScreen();
+	delay(4 * _tickLength);
+	_screen->copyRegion(0, 184, 40, 184, 232, 16, 4, 0, Screen::CR_NO_P_CHECK);
+
+	int cx = 264;
+	int cy = 11;
+
+	for (int i = 0; i < 70 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + 3 * _tickLength;
+
+		_screen->copyRegion(cx - 2, cy - 2, 0, 0, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+		_screen->drawShape(4, shp3[((i & 3) == 3) ? 1 : (i & 3)], cx, cy, 0);
+		_screen->copyRegion(cx - 2, cy - 2, cx - 82, cy + 22, 48, 36, 4, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(0, 0, cx - 2, cy - 2, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+		cx--;
+		cy++;
+
+		for (int ii = 0; ii < 5; ii++) {
+			int s = _rnd.getRandomNumber(255) % 31;
+			_screen->drawShape(0, shp2[s], _introWdDsX[s] - 80, _introWdDsY[s] + 24, 0);
+		}
+
+		if (!(_rnd.getRandomNumber(255) & 7))
+			_sound->playTrack(_rnd.getRandomBit() ? 5 : 14);
+
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	for (int i = 0; i < 3; i++) {
+		delete[] shp[i];
+		delete[] shp3[i];
+	}
+
+	for (int i = 0; i < 31; i++)
+		delete[] shp2[i];
+}
+
+void EobEngine::seq_king() {
+	if (shouldQuit() || skipFlag())
+		return;
+
+	_screen->loadBitmap(_introFilesKing[0], 5, 3, 0);
+	_screen->copyPage(3, 4);
+
+	int x = 15;
+	int y = 14;
+	int w = 1;
+	int h = 1;
+
+	for (int i = 0; i < 10 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->copyRegion(x << 3, y << 3, x << 3, y << 3, w << 3, h << 3, 4, 0, Screen::CR_NO_P_CHECK);
+		if (x > 6)
+			x --;
+		if (y > 0)
+			y -= 2;
+		w += 3;
+		if (x + w > 34)
+			w = 34 - x;
+		h += 3;
+		if (y + h > 23)
+			h = 23 - y;
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	delay(25 * _tickLength);
+
+	uint8 *shp[4];
+	int16 dy[4];
+	int16 stepY[4];
+
+	static const uint8 advEncX[] = { 0, 6, 12, 19 };
+	static const uint8 advEncW[] = { 6, 6, 7, 6 };
+	static const int8 modY[] = { -4, -8, -2, -2, 1, 0, 0, 0 };
+	
+	_screen->loadBitmap(_introFilesKing[1], 5, 3, 0);
+	_screen->setCurPage(2);
+	for (int i = 0; i < 4; i++) {
+		shp[i] = _screen->encodeShape(advEncX[i], 0, advEncW[i], 98, true);
+		dy[i] = 180 + ((_rnd.getRandomNumber(255) & 3) << 3);
+		stepY[i] = (i * 5) & 3;
+	}
+
+	_screen->copyPage(0, 4);
+
+	for (bool runloop = true; runloop && !shouldQuit() && !skipFlag(); ) {
+		runloop = false;
+		uint32 end = _system->getMillis() + 2 * _tickLength;
+		
+		for (int i = 0; i < 4; i++) {
+			if (dy[i] <= 82)
+				continue;
+			stepY[i] = (stepY[i] + 1) & 7;
+			dy[i] += modY[stepY[i]];
+
+			if (dy[i] < 82)
+				dy[i] = 82;
+
+			if (dy[i] < 180) {
+				_screen->copyRegion((advEncX[i] + 8) << 3, dy[i] - 2, 0, dy[i] - 2, advEncW[i] << 3, 182 - dy[i], 4, 4, Screen::CR_NO_P_CHECK);
+				_screen->drawShape(4, shp[i], 0, dy[i], 0);
+				_screen->copyRegion(0, dy[i] - 2, (advEncX[i] + 8) << 3, dy[i] - 2, advEncW[i] << 3, 182 - dy[i], 4, 0, Screen::CR_NO_P_CHECK);
+			}
+
+			if (_rnd.getRandomNumber(255) & 3)
+				_sound->playTrack(7);
+
+			runloop = true;
+		}
+
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_screen->copyRegion(0, 96, 0, 160, 320, 32, 6, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(70 * _tickLength);
+
+	for (int i = 0; i < 4; i++)
+		delete[] shp[i];
+}
+
+void EobEngine::seq_hands() {
+	if (shouldQuit() || skipFlag())
+		return;
+
+	_screen->setCurPage(2);
+	uint8 *shp1 = _screen->encodeShape(0, 140, 21, 60, true);
+	uint8 *shp2 = _screen->encodeShape(21, 140, 12, 60, true);
+	_screen->loadBitmap(_introFilesHands[0], 3, 5, 0);
+
+	_screen->fillRect(0, 160, 319, 199, 12, 0);
+	_screen->fillRect(0, 0, 191, 63, 157, 2);
+	_screen->drawShape(2, shp1, 0, 4, 0);
+	_screen->drawShape(2, shp2, 151, 4, 0);	
+	boxMorphTransition(25, 8, 18, 4, 3, 0, 21, 8, 6, 0, 28, 23);
+	_screen->copyRegion(0, 128, 0, 176, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+
+	_screen->updateScreen();
+	delay(15 * _tickLength);
+	_sound->playTrack(11);
+
+	for (int i = -22; i <= 20 && !shouldQuit() && !skipFlag(); i += 4) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->fillRect(0, 0, 167, 63, 157);
+		_screen->drawShape(2, shp1, i, 4, 0);
+		_screen->drawShape(2, shp1, 105 - i, 4, 0);
+		_screen->copyRegion(0, 0, 144, 32, 168, 64, 2, 0, Screen::CR_NO_P_CHECK);		
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_sound->playTrack(10);
+
+	delete[] shp1;
+	delete[] shp2;
+	delay(15 * _tickLength);
+
+	_screen->setCurPage(4);
+	shp1 = _screen->encodeShape(17, 0, 11, 120, true);
+	shp2 = _screen->encodeShape(28, 112, 1, 31, true);
+	uint8 *shp3 = _screen->encodeShape(9, 138, 14, 54, true);
+	
+	_screen->setCurPage(2);
+	_screen->fillRect(0, 0, 135, 63, 157);
+	_screen->drawShape(2, shp1, 32, -80, 0);
+	_screen->drawShape(2, shp2, 40, -16, 0);
+	boxMorphTransition(18, 16, 10, 12, 0, 0, 17, 8, 17, 3, 25, 10);
+	delay(15 * _tickLength);
+
+	for (int i = -80; i <= 0 && !shouldQuit() && !skipFlag(); i += 4) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->fillRect(0, 0, 135, 63, 157);
+		_screen->drawShape(2, shp1, 32, i, 0);
+		_screen->drawShape(2, shp2, 40, i + 64, 0);
+		_screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK);		
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_sound->playTrack(12);
+	delay(5 * _tickLength);
+
+	for (int i = 0; i > -54 && !shouldQuit() && !skipFlag(); i -= 4) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->fillRect(0, 0, 135, 63, 157);
+		_screen->drawShape(2, shp3, 12, 64 + i, 0);
+		_screen->drawShape(2, shp1, 32, i, 0);
+		_screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK);		
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	delete[] shp1;
+	delete[] shp2;
+	delete[] shp3;
+	delay(15 * _tickLength);
+
+	_screen->setCurPage(4);
+	shp1 = _screen->encodeShape(0, 0, 17, 136, true);
+	shp2 = _screen->encodeShape(0, 136, 9, 48, true);
+
+	_screen->setCurPage(2);
+	_screen->fillRect(0, 0, 143, 95, 157);
+	_screen->drawShape(2, shp1, -56, -56, 0);
+	_screen->drawShape(2, shp2, 52, 49, 0);
+	boxMorphTransition(9, 6, 0, 0, 0, 0, 18, 12, 8, 11, 21, 10);
+	delay(15 * _tickLength);
+	_sound->playTrack(11);
+
+	for (int i = -56; i <= -8 && !shouldQuit() && !skipFlag(); i += 4) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->fillRect(0, 0, 143, 95, 157);
+		_screen->drawShape(2, shp1, i, i, 0);
+		_screen->drawShape(2, shp2, (i == -8) ? 55 : 52, (i == -8) ? 52 : 49, 0);
+		_screen->copyRegion(0, 0, 0, 0, 144, 96, 2, 0, Screen::CR_NO_P_CHECK);		
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_sound->playTrack(10);
+	delete[] shp1;
+	delete[] shp2;
+	delay(30 * _tickLength);
+
+	_screen->setCurPage(4);
+	shp1 = _screen->encodeShape(28, 0, 11, 40, true);
+	shp2 = _screen->encodeShape(28, 40, 10, 72, true);
+
+	_screen->setCurPage(2);
+	_screen->fillRect(0, 0, 87, 112, 157);
+	_screen->drawShape(2, shp2, 0, 90, 0);
+	boxMorphTransition(20, 13, 15, 6, 0, 0, 11, 14, 0, 0, 24, 16);
+	delay(15 * _tickLength);
+
+	int dy = 90;
+	for (int i = -40; i <= 0 && !shouldQuit() && !skipFlag(); i += 4) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->fillRect(0, 0, 87, 112, 157);
+		_screen->drawShape(2, shp2, 0, dy, 0);
+		_screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK);		
+		_screen->updateScreen();
+		delayUntil(end);
+		dy -= 5;
+	}
+
+	_sound->playTrack(13);
+
+	for (int i = -40; i <= 0 && !shouldQuit() && !skipFlag(); i += 4) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->fillRect(0, 0, 87, 39, 157);
+		_screen->drawShape(2, shp1, 0, i, 0);
+		_screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK);		
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	delete[] shp1;
+	delete[] shp2;
+	delay(48 * _tickLength);
+}
+
+void EobEngine::seq_waterdeepExit() {
+	if (shouldQuit() || skipFlag())
+		return;
+
+	uint8 *shp2[31];
+	uint8 *shp3[3];
+
+	_screen->loadBitmap(_introFilesWdExit[0], 5, 3, 0);
+	_screen->setCurPage(2);
+	for (int i = 0; i < 31; i++)
+		shp2[i] = _screen->encodeShape(_introWdEncodeX[i], 136 + (_introWdEncodeY[i] << 3), _introWdEncodeWH[i], _introWdEncodeWH[i] << 3, true);
+	for (int i = 0; i < 3; i++)
+		shp3[i] = _screen->encodeShape(5 * i + 15, 152, 5, 32, true);
+	uint8 *shp1 = _screen->encodeShape(31, 136, 5, 32, true);
+	_screen->copyPage(3, 4);
+	_screen->copyRegion(0, 0, 0, 136, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+	_screen->fillRect(0, 168, 319, 199, 12, 0);
+	_screen->copyRegion(160, 0, 80, 24, 160, 136, 4, 0, Screen::CR_NO_P_CHECK);
+
+	int cx = 140;
+	int cy = 128;
+
+	for (int i = 0; i < 70 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + 3 * _tickLength;
+		int fx = cx - 2;
+		if (fx < 160)
+			fx = 160;
+		int fy = cy - 2;
+		if (fy > 98)
+			fy = 98;
+
+		_screen->copyRegion(fx, fy, 0, 0, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+		_screen->drawShape(4, shp3[((i & 3) == 3) ? 1 : (i & 3)], cx, cy, 0);
+		_screen->drawShape(4, shp1, 160, 104, 0);
+		_screen->copyRegion(fx, fy, fx - 80, fy + 24, 48, 36, 4, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(0, 0, fx, fy, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+		cx++;
+		cy--;
+
+		for (int ii = 0; ii < 5; ii++) {
+			int s = _rnd.getRandomNumber(255) % 31;
+			_screen->drawShape(0, shp2[s], _introWdDsX[s] - 80, _introWdDsY[s] + 24, 0);
+		}
+
+		if (!(_rnd.getRandomNumber(255) & 7))
+			_sound->playTrack(_rnd.getRandomBit() ? 5 : 14);
+
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	for (int i = 0; i < 3; i++)
+		delete[] shp3[i];
+
+	for (int i = 0; i < 31; i++)
+		delete[] shp2[i];
+	delete[] shp1;
+
+	_screen->setCurPage(0);
+	_screen->fillRect(0, 168, 319, 199, 12, 0);
+	_screen->copyRegion(0, 136, 0, 0, 48, 36, 0, 4, Screen::CR_NO_P_CHECK);
+
+	_screen->loadPalette(_introFilesWdExit[1], _screen->getPalette(0));
+	_screen->setScreenPalette(_screen->getPalette(0));
+	_screen->loadBitmap(_introFilesWdExit[2], 3, 5, 0);
+	_screen->copyPage(5, 2);
+	whirlTransition();
+	delay(6 * _tickLength);
+
+	_screen->copyRegion(0, 144, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+
+	cx = 0;
+	cy = 136;
+	int dy = 0;
+	for (int i = 0; i < 19 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->copyRegion(cx, cy, 80, dy + 16, 160, 8, 2, 0, Screen::CR_NO_P_CHECK);
+		cy += 8;
+		dy += 8;
+		if (i == 6) {
+			cx = 160;
+			cy = 0;
+		}
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_sound->playTrack(3);
+	delay(60 * _tickLength);
+
+	for (int i = 0; i < 56 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->copyRegion(0, 136 + i, 80, 16, 160, 56 - i, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(160, 0, 80, 72 - i, 160, 96 + i, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	for (int i = 1; i < 48 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->copyRegion(160, i, 80, 16, 160, 152, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_screen->loadBitmap(_introFilesWdExit[3], 3, 5, 0);
+	_screen->copyPage(5, 2);
+	delay(30 * _tickLength);
+	_screen->setCurPage(0);
+	_screen->fillRect(0, 16, 319, 31, 12);
+	_screen->fillRect(0, 136, 319, 199, 12);
+	_screen->copyRegion(0, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->loadPalette(_introFilesWdExit[4], _screen->getPalette(0));
+	_screen->setScreenPalette(_screen->getPalette(0));
+	_screen->updateScreen();
+	delay(50 * _tickLength);
+}
+
+void EobEngine::seq_tunnel() {
+	if (shouldQuit() || skipFlag())
+		return;
+
+	_screen->setCurPage(4);
+	uint8 *shp2 = _screen->encodeShape(20, 0, 20, 120, true);
+	uint8 *shp1 = _screen->encodeShape(0, 0, 20, 120, true);
+	drawBlockObject(1, 4, shp2, 160, 0, 0);
+	drawBlockObject(1, 4, shp1, 0, 0, 0);
+	delete[] shp1;
+	delete[] shp2;
+
+	for (int i = 0; i < 3 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + 8 * _tickLength;
+		_screen->copyRegion(0, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
+		_sound->playTrack(7);
+		_screen->updateScreen();
+		delayUntil(end);
+		_screen->copyRegion(0, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
+		_sound->playTrack(7);
+		end = _system->getMillis() + 8 * _tickLength;
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_screen->copyRegion(0, 160, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(18 * _tickLength);
+	_screen->copyRegion(160, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(5 * _tickLength);
+	_screen->copyRegion(0, 122, 80, 32, 160, 60, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->copyRegion(160, 122, 80, 92, 160, 60, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(5 * _tickLength);
+	_screen->copyRegion(160, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
+	for (int i = 0; i < 6; i++)
+		_screen->copyRegion(i * 48, 185, 56, (i << 3) + 24, 48, 8, 2, 2, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(5 * _tickLength);
+	_screen->copyRegion(0, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
+
+	_screen->loadBitmap(_introFilesTunnel[0], 5, 3, 0);
+	_screen->copyPage(3, 4);
+	_screen->updateScreen();
+	delay(40 * _tickLength);
+
+	_screen->copyRegion(264, 0, 136, 56, 48, 48, 4, 0, Screen::CR_NO_P_CHECK);
+	_sound->playTrack(8);
+	_screen->copyRegion(0, 0, 0, 0, 320, 184, 0, 2, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(16 * _tickLength);
+	_sound->playTrack(4);
+
+	for (int i = 0; i < 30 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + _tickLength;
+		if (i == 0)
+			_screen->fillRect(0, 168, 319, 199, 12, 0);
+		_screen->copyRegion(80, 25 + (_rnd.getRandomNumber(255) & 7), 80, 24, 160, 144, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_sound->playTrack(9);
+
+	for (int i = 0; i < 6 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + _tickLength;		
+		_screen->copyRegion(_introTvlX1[i] << 3, _introTvlY1[i], _introTvlX2[i] << 3, _introTvlY2[i], _introTvlW[i] << 3, _introTvlH[i], 4, 2, Screen::CR_NO_P_CHECK);
+		for (int ii = 0; ii < 4 && !shouldQuit() && !skipFlag(); ii++) {
+			_screen->updateScreen();
+			delayUntil(end);
+			end = _system->getMillis() + _tickLength;
+			_screen->copyRegion(80, 25 + (_rnd.getRandomNumber(255) & 7), 80, 24, 160, 144, 2, 0, Screen::CR_NO_P_CHECK);
+		}
+	}
+	_screen->copyRegion(0, 0, 0, 0, 320, 168, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(40 * _tickLength);
+
+	_screen->loadBitmap(_introFilesTunnel[1], 5, 3, 0);
+	_screen->copyPage(3, 4);
+	_sound->playTrack(6);
+	_screen->copyRegion(0, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(2 * _tickLength);
+	_screen->copyRegion(160, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(2 * _tickLength);
+	_screen->copyRegion(0, 120, 80, 30, 160, 64, 4, 0, Screen::CR_NO_P_CHECK);
+	_screen->copyRegion(160, 120, 80, 94, 160, 64, 4, 0, Screen::CR_NO_P_CHECK);
+	_screen->copyRegion(0, 176, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+	_screen->setCurPage(0);
+	_screen->updateScreen();
+	delay(50 * _tickLength);	
+}
+
+void EobEngine::seq_xdeath() {
+	uint8 *shapes1[5];
+	uint8 *shapes2;
+	
+	_screen->loadShapeSetBitmap("XDEATH2", 5, 3);
+	for (int i = 0; i < 4; i++)
+		shapes1[i] = _screen->encodeShape(i / 2 * 14, i / 2 * 88, 14, 88, true);
+	_screen->loadShapeSetBitmap("XDEATH3", 5, 3);
+	shapes2 = _screen->encodeShape(22, 0, 16, 95, true);
+	_screen->loadEobBitmap("XDEATH1", 0, 5, 3, -1);
+	_screen->setCurPage(0);
+
+	for (int i = 0; i < 10; i++) {
+		if (i == 2)
+			snd_playSoundEffect(72);
+		else if (i == 4 || i == 6)
+			snd_playSoundEffect(54);
+		else
+			snd_playSoundEffect(34);
+
+		if (i < 6) {
+			_screen->copyRegion((i % 3) * 104, i / 3 * 88, 32, 10, 104, 88, 2, 0, Screen::CR_NO_P_CHECK);
+		} else {
+			snd_playSoundEffect(42);
+			_screen->drawShape(0, shapes1[i - 6], 32, 10, 0);
+		}
+
+		_screen->updateScreen();
+		delay(4 * _tickLength);
+	}
+
+	const ScreenDim *dm = _screen->getScreenDim(5);
+	_screen->modifyScreenDim(5, dm->sx, 8, dm->w, dm->h);
+	_screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 5, Screen::CR_NO_P_CHECK);
+
+	for (int i = 0; i < 19; i++) {
+		snd_playSoundEffect(119);
+		_screen->copyRegion(0, 0, 0, 0, 176, 120, 5, 2, Screen::CR_NO_P_CHECK);
+		_screen->drawShape(2, shapes2, 24, i * 5 - 90, 5);
+		_screen->copyRegion(0, 0, 0, 0, 176, 120, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delay(2 * _tickLength);
+	}
+	
+	_screen->modifyScreenDim(5, dm->sx, 0, dm->w, dm->h);
+
+	snd_playSoundEffect(5);
+	delay(60 * _tickLength);
+
+	for (int i = 0; i < 4; i++)
+		delete[] shapes1[i];
+	delete[] shapes2;
+}
+
+void EobEngine::copyBlurRegion(int x1, int y1, int x2, int y2, int w, int h, int step) {
+	const uint8 *ptr2 = _screen->getCPagePtr(3) + y1 * 320 + x1;
+
+	if (step == 1) {
+		while (h > 0) {
+			int dx = x2;
+			for (int i = 0; i < w; i += 2) {
+				_screen->setPagePixel(3, dx++, y2, ptr2[i]);
+				_screen->setPagePixel(3, dx++, y2, 0);
+			}
+			dx = x2;
+			y2++;
+			ptr2 += 320;
+			for (int i = 0; i < w; i += 2) {
+				_screen->setPagePixel(3, dx++, y2, 0);
+				_screen->setPagePixel(3, dx++, y2, ptr2[i + 1]);
+			}
+			y2++;
+			ptr2 += 320;
+			h -= 2;
+		}
+	} else if (step == 2) {
+		while (h > 0) {
+			int dx = x2;
+			for (int i = 0; i < w; i += 2) {
+				_screen->setPagePixel(3, dx++, y2, ptr2[i]);
+				_screen->setPagePixel(3, dx++, y2, 0);
+			}
+			dx = x2;
+			y2++;
+			ptr2 += 320;
+			for (int i = 0; i < w; i++)
+				_screen->setPagePixel(3, dx++, y2, 0);
+
+			y2++;
+			ptr2 += 320;
+			h -= 2;
+		}
+	} else if (step == 3) {
+		for (int i = 0; i < h; i++) {
+			int dx = x2;
+			if ((i % 3) == 0) {
+				int ii = 0;
+				for (; ii < w - 3; ii += 3) {
+					_screen->setPagePixel(3, dx++, y2, ptr2[ii]);
+					_screen->setPagePixel(3, dx++, y2, 0);
+					_screen->setPagePixel(3, dx++, y2, 0);
+				}
+				for (; ii < w; ii++)
+					_screen->setPagePixel(3, dx++, y2, 0);
+			} else {
+				for (int ii = 0; ii < w; ii++)
+					_screen->setPagePixel(3, dx++, y2, 0);
+			}
+			y2++;
+			ptr2 += 320;
+		}
+	}
+}
+
+void EobEngine::boxMorphTransition(int targetDestX, int targetDestY, int targetFinalX, int targetFinalY, int targetSrcX, int targetSrcY, int targetFinalW, int targetFinalH, int originX1, int originY1, int originW, int originH) {
+	int originX2 = originX1 + originW;
+	int originY2 = originY1 + originH;
+	if (originY2 > 21)
+		originY2 = 21;
+
+	int w = 1;
+	int h = 1;
+	for (bool runloop = true; runloop && !shouldQuit() && !skipFlag(); ) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->copyRegion(targetSrcX << 3, targetSrcY << 3, targetDestX << 3, targetDestY << 3, w << 3, h << 3, 2, 0, Screen::CR_NO_P_CHECK);
+		if (originX1 < targetDestX)
+			_screen->copyRegion(312, 0, originX1 << 3, 0, 8, 176, 0, 0, Screen::CR_NO_P_CHECK);
+		if (originY1 < targetDestY)
+			_screen->copyRegion(0, 192, 0, originY1 << 3, 320, 8, 0, 0, Screen::CR_NO_P_CHECK);
+		if ((targetFinalX + targetFinalW) <= originX2)
+			_screen->copyRegion(312, 0, originX2 << 3, 0, 8, 176, 0, 0, Screen::CR_NO_P_CHECK);
+		if ((targetFinalY + targetFinalH) <= originY2)
+			_screen->copyRegion(0, 192, 0, originY2 << 3, 320, 8, 0, 0, Screen::CR_NO_P_CHECK);
+
+		if (!(targetDestX != targetFinalX || targetDestY != targetFinalY || w != targetFinalW || h != targetFinalH || originX1 < targetFinalX || originY1 < targetFinalY || (targetFinalX + targetFinalW) < originX2 || (targetFinalY + targetFinalH) < originY2))
+			runloop = false;
+
+		int v = targetFinalX - targetDestX;
+		v = (v < 0) ? -1 : ((v > 0) ? 1 : 0);
+		targetDestX += v;
+		v = targetFinalY - targetDestY;
+		v = (v < 0) ? -1 : ((v > 0) ? 1 : 0);
+		targetDestY += v;
+
+		if (w != targetFinalW)
+			w += 2;
+		if (w > targetFinalW)
+			w = targetFinalW;
+
+		if (h != targetFinalH)
+			h += 2;
+		if (h > targetFinalH)
+			h = targetFinalH;
+
+		if (++originX1 > targetFinalX)
+			originX1 = targetFinalX;
+
+		if (++originY1 > targetFinalY)
+			originY1 = targetFinalY;
+
+		if ((targetFinalX + targetFinalW) < originX2)
+			originX2--;
+
+		if ((targetFinalY + targetFinalH) < originY2)
+			originY2--;
+
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+}
+
+void EobEngine::whirlTransition() {
+	for (int i = 0; i < 2; i++) {
+		for (int ii = 0; ii < 8; ii++) {
+			uint32 e = _system->getMillis() + 3;
+			if (ii & 1) {
+				for (int iii = i + ii; iii < 320; iii += 8)
+					_screen->drawClippedLine(iii, 0, iii, 199, 12);
+			} else {
+				for (int iii = i + ii; iii < 200; iii += 8)
+					_screen->drawClippedLine(0, iii, 319, iii, 12);
+			}
+			_screen->updateScreen();
+			uint32 c = _system->getMillis();
+			if (e > c)
+				_system->delayMillis(e - c);
+		}
+	}
 }
 
 }	// End of namespace Kyra
diff --git a/engines/kyra/sequences_eob2.cpp b/engines/kyra/sequences_eob2.cpp
index bba5a7a..395e947 100644
--- a/engines/kyra/sequences_eob2.cpp
+++ b/engines/kyra/sequences_eob2.cpp
@@ -120,7 +120,6 @@ int DarkMoonEngine::mainMenu() {
 
 			case 1:
 				// load game in progress
-				//
 				menuChoice = -1;
 				break;
 
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index cb8ae51..e4001b2 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -55,7 +55,7 @@ namespace Kyra {
 
 void EobCoreEngine::loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex) {
 	Common::String s = filename;
-	if (GI_EOB1 && !scumm_stricmp(filename, "rust") || !scumm_stricmp(filename, "drider") || !scumm_stricmp(filename, "spider") || !scumm_stricmp(filename, "mantis") || !scumm_stricmp(filename, "xorn") || !scumm_stricmp(filename, "xanath"))
+	if ((_flags.gameID == GI_EOB1) && (!scumm_stricmp(filename, "rust") || !scumm_stricmp(filename, "drider") || !scumm_stricmp(filename, "spider") || !scumm_stricmp(filename, "mantis") || !scumm_stricmp(filename, "xorn") || !scumm_stricmp(filename, "xanath")))
 		s += "1";
 
 	_screen->loadShapeSetBitmap(s.c_str(), 3, 3);
@@ -272,10 +272,10 @@ void EobCoreEngine::updateAttackingMonsterFlags() {
 	}
 
 	if (m2->type == 7)
-		_inf->setFlag(4);
+		setScriptFlags(4);
 
 	if (m2->type == 12)
-		_inf->setFlag(0x800);
+		setScriptFlags(0x800);
 }
 
 const int8 *EobCoreEngine::getMonstersOnBlockPositions(uint16 block) {
@@ -791,9 +791,9 @@ void EobCoreEngine::turnFriendlyMonstersHostile() {
 
 	if (m) {
 		if (m->type == 7)
-			_inf->setFlag(0x40000);
+			setScriptFlags(0x40000);
 		else if (m->type == 12)
-			_inf->setFlag(0x8000000);
+			setScriptFlags(0x8000000);
 	}
 }
 
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index b1ab606..5995f8a 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -535,6 +535,11 @@ void EobCoreEngine::initStaticResource() {
 	_magicFlightObjectProperties = _staticres->loadRawData(kEobBaseMagicFlightProps, temp);
 	_turnUndeadEffect = _staticres->loadRawData(kEobBaseTurnUndeadEffect, temp);
 	_burningHandsDest = _staticres->loadRawData(kEobBaseBurningHandsDest, temp);
+	_coneOfColdDest1 = (const int8*)_staticres->loadRawData(kEobBaseConeOfColdDest1, temp);
+	_coneOfColdDest2 = (const int8*)_staticres->loadRawData(kEobBaseConeOfColdDest2, temp);
+	_coneOfColdDest3 = (const int8*)_staticres->loadRawData(kEobBaseConeOfColdDest3, temp);
+	_coneOfColdDest4 = (const int8*)_staticres->loadRawData(kEobBaseConeOfColdDest4, temp);
+	_coneOfColdGfxTbl = _staticres->loadRawData(kEobBaseConeOfColdGfxTbl, _coneOfColdGfxTblSize);
 
 	// Hard code the following strings, since EOB I doesn't have them in the original.
 	// EOB I doesn't have load and save menus, because there is only one single
@@ -1056,6 +1061,28 @@ void EobCoreEngine::initSpells() {
 void EobEngine::initStaticResource() {
 	int temp;
 	_mainMenuStrings = _staticres->loadStrings(kEob1MainMenuStrings, temp);
+	_finBonusStrings = _staticres->loadStrings(kEob1BonusStrings, temp);
+		
+	_introFilesOpening = _staticres->loadStrings(kEob1IntroFilesOpening, temp);
+	_introFilesTower = _staticres->loadStrings(kEob1IntroFilesTower, temp);
+	_introFilesOrb = _staticres->loadStrings(kEob1IntroFilesOrb, temp);
+	_introFilesWdEntry = _staticres->loadStrings(kEob1IntroFilesWdEntry, temp);
+	_introFilesKing = _staticres->loadStrings(kEob1IntroFilesKing, temp);
+	_introFilesHands = _staticres->loadStrings(kEob1IntroFilesHands, temp);
+	_introFilesWdExit = _staticres->loadStrings(kEob1IntroFilesWdExit, temp);
+	_introFilesTunnel = _staticres->loadStrings(kEob1IntroFilesTunnel, temp);
+	_introOpeningFrmDelay = _staticres->loadRawData(kEob1IntroOpeningFrmDelay, temp);
+	_introWdEncodeX = _staticres->loadRawData(kEob1IntroWdEncodeX, temp);
+	_introWdEncodeY = _staticres->loadRawData(kEob1IntroWdEncodeY, temp);
+	_introWdEncodeWH = _staticres->loadRawData(kEob1IntroWdEncodeWH, temp);
+	_introWdDsX = _staticres->loadRawDataBe16(kEob1IntroWdDsX, temp);
+	_introWdDsY = _staticres->loadRawData(kEob1IntroWdDsY, temp);
+	_introTvlX1 = _staticres->loadRawData(kEob1IntroTvlX1, temp);
+	_introTvlY1 = _staticres->loadRawData(kEob1IntroTvlY1, temp);
+	_introTvlX2 = _staticres->loadRawData(kEob1IntroTvlX2, temp);
+	_introTvlY2 = _staticres->loadRawData(kEob1IntroTvlY2, temp);
+	_introTvlW = _staticres->loadRawData(kEob1IntroTvlW, temp);
+	_introTvlH = _staticres->loadRawData(kEob1IntroTvlH, temp);
 
 	_doorShapeEncodeDefs = _staticres->loadRawData(kEob1DoorShapeDefs, temp);
 	_doorSwitchShapeEncodeDefs = _staticres->loadRawData(kEob1DoorSwitchShapeDefs, temp);
diff --git a/engines/kyra/text_eob.cpp b/engines/kyra/text_eob.cpp
index 80858d1..3641681 100644
--- a/engines/kyra/text_eob.cpp
+++ b/engines/kyra/text_eob.cpp
@@ -646,7 +646,7 @@ void TextDisplayer_Eob::displayWaitButton() {
 	vm()->_dialogueButtonW = vm()->_waitButtonPresW[_waitButtonMode];
 	vm()->_dialogueButtonYoffs = 0;
 
-	SWAP(_vm->_dialogueButtonLabelCol1, _vm->_dialogueButtonLabelCol2);
+	SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2);
 	vm()->drawDialogueButtons();
 
 	if (!vm()->shouldQuit())
@@ -654,8 +654,9 @@ void TextDisplayer_Eob::displayWaitButton() {
 
 	while (!vm()->processDialogue() && !vm()->shouldQuit()) {}
 	
+	_screen->fillRect(vm()->_dialogueButtonPosX[0], vm()->_dialogueButtonPosY[0], vm()->_dialogueButtonPosX[0] + vm()->_dialogueButtonW - 1, vm()->_dialogueButtonPosY[0] + vm()->_dialogueButtonH - 1, vm()->_bkgColor_1);
 	vm()->_dialogueButtonW = 95;
-	SWAP(_vm->_dialogueButtonLabelCol1, _vm->_dialogueButtonLabelCol2);
+	SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2);
 	clearCurDim();
 }
 


Commit: b288889c978990423b08dad8f838d891610f36b5
    https://github.com/scummvm/scummvm/commit/b288889c978990423b08dad8f838d891610f36b5
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:14-08:00

Commit Message:
KYRA: (EOB) - implement wall of force spell

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    dists/engine-data/kyra.dat
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/loleobbase.h
    engines/kyra/magic_eob.cpp
    engines/kyra/resource.h
    engines/kyra/saveload_eob.cpp
    engines/kyra/scene_eob.cpp
    engines/kyra/script_eob.cpp
    engines/kyra/sequences_eob2.cpp
    engines/kyra/sprites_eob.cpp
    engines/kyra/staticres_eob.cpp
    engines/kyra/timer_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index a8531dd..069118b 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -571,6 +571,11 @@ const ExtractFilename extractFilenames[] = {
 	{ kEob2DranFoolsStrings, kTypeStringList, true },
 	{ kEob2HornStrings, kTypeStringList, true },
 	{ kEob2HornSounds, kTypeRawData, false },
+	{ kEob2WallOfForceDsX, kLolTypeRaw16, false },
+	{ kEob2WallOfForceDsY, kTypeRawData, false },
+	{ kEob2WallOfForceNumW, kTypeRawData, false },
+	{ kEob2WallOfForceNumH, kTypeRawData, false },
+	{ kEob2WallOfForceShpId, kTypeRawData, false },
 	
 	// LANDS OF LORE
 
@@ -1986,6 +1991,16 @@ const char *getIdString(const int id) {
 		return "kEob2HornStrings";
 	case kEob2HornSounds:
 		return "kEob2HornSounds";
+	case kEob2WallOfForceDsX:
+		return "kEob2WallOfForceDsX";
+	case kEob2WallOfForceDsY:
+		return "kEob2WallOfForceDsY";
+	case kEob2WallOfForceNumW:
+		return "kEob2WallOfForceNumW";
+	case kEob2WallOfForceNumH:
+		return "kEob2WallOfForceNumH";
+	case kEob2WallOfForceShpId:
+		return "kEob2WallOfForceShpId";
 	case kLolIngamePakFiles:
 		return "kLolIngamePakFiles";
 	case kLolCharacterDefs:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index 44fa93a..c7a29fb 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -553,6 +553,12 @@ enum kExtractID {
 	kEob2HornStrings,
 	kEob2HornSounds,
 
+	kEob2WallOfForceDsX,
+	kEob2WallOfForceDsY,
+	kEob2WallOfForceNumW,
+	kEob2WallOfForceNumH,
+	kEob2WallOfForceShpId,
+
 	kLolIngamePakFiles,
 	kLolCharacterDefs,
 	kLolIngameSfxFiles,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 9ecbf01..d5b5c29 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1595,6 +1595,11 @@ const int eob2FloppyNeed[] = {
 	kEob2DranFoolsStrings,
 	kEob2HornStrings,
 	kEob2HornSounds,
+	kEob2WallOfForceDsX,
+	kEob2WallOfForceDsY,
+	kEob2WallOfForceNumW,
+	kEob2WallOfForceNumH,
+	kEob2WallOfForceShpId,
 
 	kLolEobCommonDscShapeIndex,
 	kLolEobCommonDscX,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index ab75baf..0b24924 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -3195,6 +3195,32 @@ const ExtractEntrySearchData kEob2HornSoundsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEob2WallOfForceDsXProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000024, 0x00000D67, { { 0x51, 0xCF, 0xAB, 0x1E, 0xB4, 0xE0, 0xE3, 0x44, 0x29, 0xD1, 0xDC, 0x82, 0xCD, 0x08, 0x50, 0xF5 } } } },
+
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2WallOfForceDsYProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000003, 0x00000048, { { 0x45, 0xFC, 0xEA, 0x8C, 0x34, 0xD7, 0xBE, 0x74, 0x05, 0x03, 0xE6, 0x94, 0x34, 0xB5, 0x45, 0x4D } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2WallOfForceNumWProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000003, 0x00000006, { { 0x52, 0x89, 0xDF, 0x73, 0x7D, 0xF5, 0x73, 0x26, 0xFC, 0xDD, 0x22, 0x59, 0x7A, 0xFB, 0x1F, 0xAC } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2WallOfForceNumHProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000003, 0x00000011, { { 0x33, 0x86, 0x06, 0xBE, 0x8D, 0xC8, 0x37, 0x2D, 0x0F, 0x61, 0x97, 0xA4, 0x26, 0xA9, 0xBC, 0x60 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2WallOfForceShpIdProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000003, 0x00000006, { { 0x77, 0xAE, 0x9B, 0x52, 0x9E, 0xF7, 0xEB, 0x48, 0xA8, 0x5E, 0xED, 0xC2, 0x08, 0x53, 0xCE, 0x3C } } } },
+	EXTRACT_END_ENTRY
+};
+
 const ExtractEntrySearchData kLolIngamePakFilesProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000088, 0x0000224F, { { 0xDA, 0x24, 0x18, 0xA3, 0xEF, 0x16, 0x70, 0x8F, 0xA8, 0xC2, 0x2E, 0xC2, 0xED, 0x39, 0x03, 0xD1 } } } },
 	{ UNK_LANG, kPlatformPC98, { 0x00000084, 0x00002125, { { 0x7A, 0x89, 0xE2, 0x36, 0xEC, 0x6F, 0x52, 0x2B, 0xEF, 0xBA, 0x3D, 0x28, 0x54, 0xDA, 0xFB, 0x72 } } } },
@@ -4162,6 +4188,11 @@ const ExtractEntry extractProviders[] = {
 	{ kEob2DranFoolsStrings, kEob2DranFoolsStringsProvider },
 	{ kEob2HornStrings, kEob2HornStringsProvider },
 	{ kEob2HornSounds, kEob2HornSoundsProvider },
+	{ kEob2WallOfForceDsX, kEob2WallOfForceDsXProvider },
+	{ kEob2WallOfForceDsY, kEob2WallOfForceDsYProvider },
+	{ kEob2WallOfForceNumW, kEob2WallOfForceNumWProvider },
+	{ kEob2WallOfForceNumH, kEob2WallOfForceNumHProvider },
+	{ kEob2WallOfForceShpId, kEob2WallOfForceShpIdProvider },
 	
 	{ kLolIngamePakFiles, kLolIngamePakFilesProvider },
 	{ kLolCharacterDefs, kLolCharacterDefsProvider },
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index aa3d62b..35aff97 100644
Binary files a/dists/engine-data/kyra.dat and b/dists/engine-data/kyra.dat differ
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index dc987c1..c94cb16 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -141,6 +141,8 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_restPartyElapsedTime = 0;
 	_allowSkip = false;
 
+	_wallsOfForce = 0;
+
 	_rrCount = 0;
 	memset(_rrNames, 0, 10 * sizeof(const char*));
 	memset(_rrId, 0, 10 * sizeof(int8));
@@ -205,6 +207,7 @@ EobCoreEngine::~EobCoreEngine() {
 
 	delete[] _spells;
 	delete[] _spellAnimBuffer;
+	delete[] _wallsOfForce;
 
 	delete _gui;
 	_gui = 0;
@@ -318,6 +321,9 @@ Common::Error EobCoreEngine::init() {
 	_spellAnimBuffer = new uint8[4096];
 	memset(_spellAnimBuffer, 0, 4096);
 
+	_wallsOfForce = new WallOfForce[5];
+	memset(_wallsOfForce, 0, 5 * sizeof(WallOfForce));
+
 	memset(_doorType, 0, sizeof(_doorType));
 	memset(_noDoorSwitch, 0, sizeof(_noDoorSwitch));
 
@@ -349,7 +355,6 @@ Common::Error EobCoreEngine::go() {
 
 	loadItemsAndDecorationsShapes();
 	_screen->setMouseCursor(0, 0, _itemIconShapes[0]);
-	_screen->showMouse();
 
 	loadItemDefs();
 	int action = 0;
@@ -363,6 +368,7 @@ Common::Error EobCoreEngine::go() {
 			startupLoad();
 			_gameToLoad = -1;
 		} else {
+			_screen->showMouse();
 			action = mainMenu();
 		}
 
@@ -453,6 +459,7 @@ void EobCoreEngine::runLoop() {
 
 		_timer->update();
 		updateScriptTimers();
+		updateWallOfForceTimers();
 
 		if (_sceneUpdateRequired)
 			drawScene(1);
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 51dfb8b..ffc951e 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -561,6 +561,12 @@ protected:
 	const uint16 *_encodeMonsterShpTable;
 	const uint8 _teleporterWallId;
 
+	const int16 *_wallOfForceDsX;
+	const uint8 *_wallOfForceDsY;
+	const uint8 *_wallOfForceDsNumW;
+	const uint8 *_wallOfForceDsNumH;
+	const uint8 *_wallOfForceShpId;
+
 	const int8 *_monsterDirChangeTable;
 
 	// Level
@@ -833,6 +839,9 @@ protected:
 	void *generateMonsterTempData(LevelTempData *tmp);
 	void restoreMonsterTempData(LevelTempData *tmp);
 	void releaseMonsterTempData(LevelTempData *tmp);
+	void *generateWallOfForceTempData(LevelTempData *tmp);
+	void restoreWallOfForceTempData(LevelTempData *tmp);
+	void releaseWallOfForceTempData(LevelTempData *tmp);
 
 	const char * const *_saveLoadStrings;
 
@@ -920,6 +929,9 @@ protected:
 	Item createMagicWeaponItem(int flags, int icon, int value, int type);
 	void removeMagicWeaponItem(Item item);
 
+	void updateWallOfForceTimers();
+	void destroyWallOfForce(int index);
+
 	int findSingleSpellTarget(int dist);
 	
 	int findFirstCharacterSpellTarget();
@@ -1031,6 +1043,13 @@ protected:
 	EobSpell *_spells;
 	int _numSpells;
 
+	struct WallOfForce {
+		uint16 block;
+		uint32 duration;
+	};
+
+	WallOfForce *_wallsOfForce;
+
 	const char *const *_bookNumbers;
 	const char *const *_mageSpellList;
 	int _mageSpellListSize;
diff --git a/engines/kyra/loleobbase.h b/engines/kyra/loleobbase.h
index ba59fe7..02b236d 100644
--- a/engines/kyra/loleobbase.h
+++ b/engines/kyra/loleobbase.h
@@ -60,6 +60,7 @@ struct LevelTempData {
 	uint16 *flags;
 	void *monsters;
 	void *flyingObjects;
+	void *wallsOfForce;
 	uint8 monsterDifficulty;
 };
 
@@ -315,6 +316,9 @@ protected:
 	void restoreFlyingObjectTempData(LevelTempData *tmp);
 	void *generateFlyingObjectTempData(LevelTempData *tmp);
 	void releaseFlyingObjectTempData(LevelTempData *tmp);
+	virtual void *generateWallOfForceTempData(LevelTempData *tmp) { return 0; }
+	virtual void restoreWallOfForceTempData(LevelTempData *tmp) {}
+	virtual void releaseWallOfForceTempData(LevelTempData *tmp) {}
 
 	LevelTempData *_lvlTempData[29];
 	const int _numFlyingObjects;
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 2ad0da7..646d389 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -24,6 +24,7 @@
 
 #include "kyra/eobcommon.h"
 #include "kyra/resource.h"
+#include "common/system.h"
 
 namespace Kyra {
 
@@ -490,11 +491,11 @@ bool EobCoreEngine::magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int d
 	int blockDamage = fo->flags & 2;
 	int hitTest = fo->flags & 4;
 
-	int s = 5;
-	int dmgType = 3;
+	int savingThrowType = 5;
+	int savingThrowEffect = 3;
 	if (fo->flags & 8) {
-		s = 4;
-		dmgType = 0;
+		savingThrowType = 4;
+		savingThrowEffect = 0;
 	}
 
 	int dmgFlag = _spells[fo->callBackIndex].damageFlags;
@@ -516,7 +517,7 @@ bool EobCoreEngine::magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int d
 					continue;
 			}
 
-			calcAndInflictMonsterDamage(&_monsters[*m], 0, 0, dmg, dmgFlag, s, dmgType);
+			calcAndInflictMonsterDamage(&_monsters[*m], 0, 0, dmg, dmgFlag, savingThrowType, savingThrowEffect);
 			res = true;
 		}
 		updateAllMonsterShapes();
@@ -532,7 +533,7 @@ bool EobCoreEngine::magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int d
 				int dmg = rollDice(dcTimes, dcPips, dcOffs) * level;
 				res = true;
 
-				calcAndInflictCharacterDamage(i, 0, 0, dmg, dmgFlag, s, dmgType);
+				calcAndInflictCharacterDamage(i, 0, 0, dmg, dmgFlag, savingThrowType, savingThrowEffect);
 			}
 		} else {
 			int c = _dscItemPosIndex[(_currentDirection << 2) + (fo->curPos & 3)];
@@ -545,7 +546,7 @@ bool EobCoreEngine::magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int d
 				if ((_characters[c].flags & 1) && (!hitTest || monsterAttackHitTest(&_monsters[0], c))) {
 					int dmg = rollDice(dcTimes, dcPips, dcOffs) * level;
 					res = true;
-					calcAndInflictCharacterDamage(c, 0, 0, dmg, dmgFlag, s, dmgType);
+					calcAndInflictCharacterDamage(c, 0, 0, dmg, dmgFlag, savingThrowType, savingThrowEffect);
 				}
 			}
 		}
@@ -708,6 +709,22 @@ void EobCoreEngine::removeMagicWeaponItem(Item item) {
 	_items[item].level = -1;
 }
 
+void EobCoreEngine::updateWallOfForceTimers() {
+	uint32 ct = _system->getMillis();
+	for (int i = 0; i < 5; i++) {
+		if (!_wallsOfForce[i].block)
+			continue;
+		if (_wallsOfForce[i].duration < ct)
+			destroyWallOfForce(i);
+	}
+}
+
+void EobCoreEngine::destroyWallOfForce(int index) {
+	memset(_levelBlockProperties[_wallsOfForce[index].block].walls, 0, 4);
+	_wallsOfForce[index].block = 0;
+	_sceneUpdateRequired = true;
+}
+
 int EobCoreEngine::findSingleSpellTarget(int dist) {
 	uint16 bl = _currentBlock;
 	int res = -1;
@@ -924,7 +941,7 @@ void EobCoreEngine::spellCallback_start_vampiricTouch() {
 	Item i = (t != -1) ? createMagicWeaponItem(0x18, 83, 0, t) : -1;
 	if (t == -1 || i == -1) {
 		if (_flags.gameID == GI_EOB2)
-			printWarning(_magicStrings8[0]);
+			printWarning(_magicStrings8[2]);
 		removeCharacterEffect(_activeSpell, _activeSpellCharId, 0);
 		deleteCharEventTimer(_activeSpellCharId, -_activeSpell);
 		_returnAfterSpellCallback = true;
@@ -1019,7 +1036,33 @@ bool EobCoreEngine::spellCallback_end_holdMonster(void *obj) {
 }
 
 void EobCoreEngine::spellCallback_start_wallOfForce() {
+	uint16 bl = calcNewBlockPosition(_currentBlock, _currentDirection);
+	LevelBlockProperty *l = &_levelBlockProperties[bl];
+	if (l->walls[0] || l->walls[1] || l->walls[2] || l->walls[3] || (l->flags & 7)) {
+		printWarning(_magicStrings8[3]);
+		return;
+	}
+
+	uint32 dur = 0xffffffff;
+	int s = 0;
+	int i = 0;
 
+	for (; i < 5; i++) {
+		if (!_wallsOfForce[i].block)
+			break;
+		if (_wallsOfForce[i].duration < dur) {
+			dur = _wallsOfForce[i].duration;
+			s = i;
+		}
+	}
+
+	if (i == 5)
+		destroyWallOfForce(s);
+
+	memset(_levelBlockProperties[bl].walls, 74, 4);
+	_wallsOfForce[s].block = bl;
+	_wallsOfForce[s].duration = _system->getMillis() + (((getMageLevel(_openBookChar) * 546) >> 1) + 546) * _tickLength;
+	_sceneUpdateRequired = true;
 }
 
 void EobCoreEngine::spellCallback_start_disintegrate() {
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 5ed658c..f330d42 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -627,6 +627,12 @@ enum KyraResources {
 	kEob2HornStrings,
 	kEob2HornSounds,
 
+	kEob2WallOfForceDsX,
+	kEob2WallOfForceDsY,
+	kEob2WallOfForceNumW,
+	kEob2WallOfForceNumH,
+	kEob2WallOfForceShpId,
+
 	kLolIngamePakFiles,
 	kLolCharacterDefs,
 	kLolIngameSfxFiles,
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index 05eea82..24a1013 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -72,6 +72,7 @@ void LolEobBaseEngine::generateTempData() {
 
 	_lvlTempData[l]->monsters = generateMonsterTempData(_lvlTempData[l]);
 	_lvlTempData[l]->flyingObjects = generateFlyingObjectTempData(_lvlTempData[l]);
+	_lvlTempData[l]->wallsOfForce = generateWallOfForceTempData(_lvlTempData[l]);
 
 	_hasTempDataFlags |= (1 << l);
 	delete[] p2;
@@ -104,6 +105,7 @@ void LolEobBaseEngine::restoreBlockTempData(int levelIndex) {
 
 	restoreMonsterTempData(_lvlTempData[l]);
 	restoreFlyingObjectTempData(_lvlTempData[l]);
+	restoreWallOfForceTempData(_lvlTempData[l]);
 
 	delete[] p2;
 }
@@ -115,6 +117,7 @@ void LolEobBaseEngine::releaseTempData() {
 			delete[] _lvlTempData[i]->flags;
 			releaseMonsterTempData(_lvlTempData[i]);
 			releaseFlyingObjectTempData(_lvlTempData[i]);
+			releaseWallOfForceTempData(_lvlTempData[i]);
 			delete _lvlTempData[i];
 			_lvlTempData[i] = 0;
 		}
@@ -293,13 +296,15 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 		}
 
 		_lvlTempData[i] = new LevelTempData;
-		_lvlTempData[i]->wallsXorData = new uint8[4096];
-		_lvlTempData[i]->flags = new uint16[1024];
+		LevelTempData *l = _lvlTempData[i];
+		l->wallsXorData = new uint8[4096];
+		l->flags = new uint16[1024];
 		EobMonsterInPlay *lm = new EobMonsterInPlay[30];
-		 _lvlTempData[i]->monsters = lm;
+		l->monsters = lm;
 		EobFlyingObject *lf = new EobFlyingObject[_numFlyingObjects];
-		_lvlTempData[i]->flyingObjects = lf;
-		LevelTempData *l = _lvlTempData[i];
+		l->flyingObjects = lf;
+		WallOfForce *lw = new WallOfForce[5];
+		l->wallsOfForce = lw;		
 
 		in.read(l->wallsXorData, 4096);
 		for (int ii = 0; ii < 1024; ii++)
@@ -349,10 +354,14 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 			m->flags = in.readByte();
 			m->unused = in.readByte();
 		}
+
+		for (int ii = 0; ii < 5; ii++) {
+			WallOfForce *w = &lw[ii];
+			w->block = in.readUint16BE();
+			w->duration = in.readUint32BE();
+		}
 	}
 
-	if (_flags.gameID == GI_EOB1)
-		_screen->loadPalette("EOBPAL.COL", _screen->getPalette(0));
 	loadLevel(_currentLevel, _currentSub);
 	_sceneUpdateRequired = true;
 	_screen->setFont(Screen::FID_6_FNT);
@@ -515,6 +524,7 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName,
 
 		EobMonsterInPlay *lm = (EobMonsterInPlay*)_lvlTempData[i]->monsters;
 		EobFlyingObject *lf = (EobFlyingObject*)_lvlTempData[i]->flyingObjects;
+		WallOfForce *lw = (WallOfForce*)_lvlTempData[i]->wallsOfForce;
 
 		for (int ii = 0; ii < 30; ii++) {
 			EobMonsterInPlay *m = &lm[ii];
@@ -560,6 +570,12 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName,
 			out->writeByte(m->flags);
 			out->writeByte(m->unused);
 		}
+
+		for (int ii = 0; ii < 5; ii++) {
+			WallOfForce *w = &lw[ii];
+			out->writeUint16BE(w->block);
+			out->writeUint32BE(w->duration);
+		}
 	}
 
 	out->finalize();
@@ -591,6 +607,27 @@ void EobCoreEngine::releaseMonsterTempData(LevelTempData *tmp) {
 	delete[] p;
 }
 
+void *EobCoreEngine::generateWallOfForceTempData(LevelTempData *tmp) {
+	WallOfForce *w = new WallOfForce[5];
+	memcpy(w, _wallsOfForce,  sizeof(WallOfForce) * 5);
+	uint32 ct = _system->getMillis();
+	for (int i = 0; i < 5; i++)
+		w[i].duration = (w[i].duration > ct) ? w[i].duration - ct : _tickLength;
+	return w;
+}
+
+void EobCoreEngine::restoreWallOfForceTempData(LevelTempData *tmp) {
+	memcpy(_wallsOfForce, tmp->wallsOfForce,  sizeof(WallOfForce) * 5);
+	uint32 ct = _system->getMillis();
+	for (int i = 0; i < 5; i++)
+		_wallsOfForce[i].duration += ct;
+}
+
+void EobCoreEngine::releaseWallOfForceTempData(LevelTempData *tmp) {
+	WallOfForce *p = (WallOfForce*)tmp->wallsOfForce;
+	delete[] p;
+}
+
 #endif // ENABLE_EOB
 
 }	// End of namespace Kyra
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index aef131f..afce9ef 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -1144,9 +1144,12 @@ int EobCoreEngine::calcNewBlockPositionAndTestPassability(uint16 curBlock, uint1
 	if (!f)
 		assert((_flags.gameID == GI_EOB1 && w < 70) || (_flags.gameID == GI_EOB2 && w < 80));
 
-	if (w == 74 && _currentBlock == curBlock) {
+	if (_flags.gameID == GI_EOB2 && w == 74 && _currentBlock == curBlock) {
 		for (int i = 0; i < 5; i++) {
-
+			if (_wallsOfForce[i].block == b) {
+				destroyWallOfForce(i);
+				f = _wllWallFlags[0];
+			}
 		}
 	}
 
diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp
index 15f3c80..6feac6b 100644
--- a/engines/kyra/script_eob.cpp
+++ b/engines/kyra/script_eob.cpp
@@ -638,13 +638,13 @@ int EobInfProcessor::oeob_calcAndInflictCharacterDamage(int8 *data) {
 	int useStrModifierOrBase = *pos++;
 
 	int flg = (charIndex == -1) ? 4 : 0;
-	int a = 5;
-	int damageType = 1;
+	int savingThrowType = 5;
+	int savingThrowEffect = 1;
 
 	if (_vm->game() == GI_EOB2) {
 		flg = *pos++;
-		a = *pos++;
-		damageType = *pos++;
+		savingThrowType = *pos++;
+		savingThrowEffect = *pos++;
 	} else if (!itemOrPips) {
 		useStrModifierOrBase = times;
 		times = 0;
@@ -652,9 +652,9 @@ int EobInfProcessor::oeob_calcAndInflictCharacterDamage(int8 *data) {
 
 	if (charIndex == -1) {
 		for (int i = 0; i < 6; i++)
-			_vm->calcAndInflictCharacterDamage(i, times, itemOrPips, useStrModifierOrBase, flg, a, damageType);
+			_vm->calcAndInflictCharacterDamage(i, times, itemOrPips, useStrModifierOrBase, flg, savingThrowType, savingThrowEffect);
 	} else {
-		_vm->calcAndInflictCharacterDamage(charIndex, times, itemOrPips, useStrModifierOrBase, flg, a, damageType);
+		_vm->calcAndInflictCharacterDamage(charIndex, times, itemOrPips, useStrModifierOrBase, flg, savingThrowType, savingThrowEffect);
 	}
 	return pos - data;
 }
diff --git a/engines/kyra/sequences_eob2.cpp b/engines/kyra/sequences_eob2.cpp
index 395e947..ea96779 100644
--- a/engines/kyra/sequences_eob2.cpp
+++ b/engines/kyra/sequences_eob2.cpp
@@ -239,7 +239,7 @@ void DarkMoonEngine::seq_playIntro() {
 	sq.loadScene(1, 2);
 	sq.waitForSongNotifier(4);
 
-	//intro scroll
+	// intro scroll
 	if (!skipFlag() && !shouldQuit()) {
 		for (int i = 0; i < 280; i += 3) {
 			uint32 endtime = _system->getMillis() + _tickLength;
@@ -978,7 +978,7 @@ void DarkmoonSequenceHelper::loadScene(int index, int pageNum) {
 		}
 
 		if (!s)
-			error("DarkmoonSequenceHelper::loadScene(): Sequence CPS file loading failed.");
+			error("DarkmoonSequenceHelper::loadScene(): CPS file loading failure in scene %d", index);
 
 		if (_mode == kFinale)
 			s->read(_palettes[0]->getData(), 768);
@@ -1026,7 +1026,7 @@ void DarkmoonSequenceHelper::runSequence(int index, int del) {
 			if (s->pal)
 				setPaletteWithoutTextColor(palIndex);
 			delay(s->delay);
-			if (_mode == DarkmoonSequenceHelper::kIntro && s->pal)
+			if (_mode == kIntro && s->pal)
 				setPaletteWithoutTextColor(0);
 			break;
 
@@ -1035,7 +1035,7 @@ void DarkmoonSequenceHelper::runSequence(int index, int del) {
 			shapeW = _shapes[s->obj][2];
 			shapeH = _shapes[s->obj][3];
 
-			if (_mode == DarkmoonSequenceHelper::kFinale) {
+			if (_mode == kFinale) {
 				_screen->setScreenDim(18);
 				x -= (_screen->_curDim->sx << 3);
 				y -= _screen->_curDim->sy;
@@ -1045,7 +1045,7 @@ void DarkmoonSequenceHelper::runSequence(int index, int del) {
 					x2 = x;
 			}
 
-			_screen->drawShape(0, _shapes[s->obj], x, y, _mode == DarkmoonSequenceHelper::kIntro ? 0 : 18);
+			_screen->drawShape(0, _shapes[s->obj], x, y, _mode == kIntro ? 0 : 18);
 
 			if (s->pal)
 				setPaletteWithoutTextColor(palIndex);
@@ -1054,7 +1054,7 @@ void DarkmoonSequenceHelper::runSequence(int index, int del) {
 
 			delay(s->delay);
 
-			if (_mode == DarkmoonSequenceHelper::kIntro) {
+			if (_mode == kIntro) {
 				if (s->pal)
 					setPaletteWithoutTextColor(0);
 				_screen->copyRegion(x - 8, y - 8, x, y, (shapeW + 1) << 3, shapeH, 2, 0, Screen::CR_NO_P_CHECK);
@@ -1076,14 +1076,14 @@ void DarkmoonSequenceHelper::runSequence(int index, int del) {
 
 			delay(s->delay);
 
-			if (_mode == DarkmoonSequenceHelper::kIntro && s->pal)
+			if (_mode == kIntro && s->pal)
 				setPaletteWithoutTextColor(0);
 			break;
 
 		case 3:
 		case 4:
 			// fade shape in or out or restore background
-			if (_mode == DarkmoonSequenceHelper::kFinale)
+			if (_mode == kFinale)
 				break;
 
 			_screen->setShapeFadeMode(0, true);
@@ -1109,10 +1109,10 @@ void DarkmoonSequenceHelper::runSequence(int index, int del) {
 
 		case 5:
 			// copy region
-			if (_mode == DarkmoonSequenceHelper::kFinale && s->pal)
+			if (_mode == kFinale && s->pal)
 				setPaletteWithoutTextColor(palIndex);
 
-			_screen->copyRegion(s->x2 << 3, s->y2, s->x1, s->y1, s->w << 3, s->h, (s->obj && _mode == DarkmoonSequenceHelper::kFinale) ? 6 : 2, 0, Screen::CR_NO_P_CHECK);
+			_screen->copyRegion(s->x2 << 3, s->y2, s->x1, s->y1, s->w << 3, s->h, (s->obj && _mode == kFinale) ? 6 : 2, 0, Screen::CR_NO_P_CHECK);
 			_screen->updateScreen();
 			delay(s->delay);
 			break;
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index e4001b2..caf4a74 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -587,7 +587,24 @@ void EobCoreEngine::drawMonsters(int index) {
 }
 
 void EobCoreEngine::drawWallOfForce(int index) {
-
+	int d = _dscDimMap[index];
+	assert(d < 3);
+	int dH = _wallOfForceDsNumH[d];
+	int dW = _wallOfForceDsNumW[d];
+	int y = _wallOfForceDsY[d];
+	int shpId = _wallOfForceShpId[d] + _teleporterPulse;
+	int h = _wallOfForceShapes[shpId][1];
+	int w = _wallOfForceShapes[shpId][2] << 3;
+
+	for (int i = 0; i < dH; i++) {
+		int x = _wallOfForceDsX[index];
+		for (int ii = 0; ii < dW; ii++) {
+			drawBlockObject(0, 2, _wallOfForceShapes[shpId], x, y, 5);
+			x += w;
+		}
+		y += h;
+		shpId ^= 1;
+	}
 }
 
 void EobCoreEngine::drawFlyingObjects(int index) {
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 5995f8a..069bf13 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -1280,6 +1280,12 @@ void DarkMoonEngine::initStaticResource() {
 	_dranFoolsStrings = _staticres->loadStrings(kEob2DranFoolsStrings, temp);
 	_hornStrings = _staticres->loadStrings(kEob2HornStrings, temp);
 	_hornSounds = _staticres->loadRawData(kEob2HornSounds, temp);
+
+	_wallOfForceDsX = (const int16*)_staticres->loadRawDataBe16(kEob2WallOfForceDsX, temp);
+	_wallOfForceDsY = _staticres->loadRawData(kEob2WallOfForceDsY, temp);
+	_wallOfForceDsNumW = _staticres->loadRawData(kEob2WallOfForceNumW, temp);
+	_wallOfForceDsNumH = _staticres->loadRawData(kEob2WallOfForceNumH, temp);
+	_wallOfForceShpId = _staticres->loadRawData(kEob2WallOfForceShpId, temp);
 }
 
 void DarkMoonEngine::initSpells() {
diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp
index 20a05f9..61fa554 100644
--- a/engines/kyra/timer_eob.cpp
+++ b/engines/kyra/timer_eob.cpp
@@ -371,7 +371,7 @@ void EobCoreEngine::timerUpdateTeleporters(int timerNum) {
 	_teleporterPulse ^= 1;
 	for (int i = 0; i < 18; i++) {
 		uint8 w = _visibleBlocks[i]->walls[_sceneDrawVarDown];
-		if ((_flags.gameID == GI_EOB1 && w == 52) || (_flags.gameID == GI_EOB2 && (w == 44 || w == 74))) {
+		if ((w == _teleporterWallId) || (_flags.gameID == GI_EOB2 && w == 74)) {
 			_sceneUpdateRequired = true;
 			return;
 		}


Commit: b3c8173bd46ddc831344848723598846bd5c41e8
    https://github.com/scummvm/scummvm/commit/b3c8173bd46ddc831344848723598846bd5c41e8
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:14-08:00

Commit Message:
KYRA: (EOB) - extend save/load dialogue to support 990 slots

Changed paths:
    engines/kyra/gui.cpp
    engines/kyra/gui.h
    engines/kyra/gui_eob.cpp
    engines/kyra/gui_eob.h
    engines/kyra/gui_hof.cpp
    engines/kyra/gui_lok.cpp
    engines/kyra/gui_lol.cpp
    engines/kyra/gui_mr.cpp
    engines/kyra/gui_v2.cpp
    engines/kyra/saveload_eob.cpp
    engines/kyra/text_eob.cpp



diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp
index d03fa23..9c0adf1 100644
--- a/engines/kyra/gui.cpp
+++ b/engines/kyra/gui.cpp
@@ -32,7 +32,7 @@
 namespace Kyra {
 
 GUI::GUI(KyraEngine_v1 *kyra) : _vm(kyra), _screen(kyra->screen()) {
-	_savegameListUpdateNeeded = false;
+	_saveSlotsListUpdateNeeded = true;
 	_savegameListSize = 0;
 	_savegameList = 0;
 }
@@ -46,7 +46,7 @@ GUI::~GUI() {
 	}
 }
 
-void GUI::updateSaveList(bool excludeQuickSaves) {
+void GUI::updateSaveFileList(bool excludeQuickSaves) {
 	Common::String pattern = _vm->_targetName + ".???";
 	Common::StringArray saveFileList = _vm->_saveFileMan->listSavefiles(pattern);
 	_saveSlots.clear();
@@ -93,11 +93,11 @@ int GUI::getNextSavegameSlot() {
 	return 0;
 }
 
-void GUI::updateSavegameList() {
-	if (!_savegameListUpdateNeeded)
+void GUI::updateSaveSlotsList() {
+	if (!_saveSlotsListUpdateNeeded)
 		return;
 
-	_savegameListUpdateNeeded = false;
+	_saveSlotsListUpdateNeeded = false;
 
 	if (_savegameList) {
 		for (int i = 0; i < _savegameListSize; i++)
@@ -105,31 +105,31 @@ void GUI::updateSavegameList() {
 		delete[] _savegameList;
 	}
 
-	updateSaveList(true);
-	_savegameListSize = _saveSlots.size();
+	updateSaveFileList(true);
+	int numSaves = _savegameListSize = _saveSlots.size();
+	bool allowEmptySlots = (_vm->game() == GI_EOB1 || _vm->game() == GI_EOB2);
 
 	if (_savegameListSize) {
-		if (_vm->game() == GI_EOB1 || _vm->game() == GI_EOB2) {
-			Common::sort(_saveSlots.begin(), _saveSlots.end(),  Common::Less<int>());
-			_savegameListSize = _saveSlots.back() + 1;
-		} else {
-			Common::sort(_saveSlots.begin(), _saveSlots.end(),  Common::Greater<int>());
-		}
+		if (allowEmptySlots)
+			_savegameListSize = 990;
 
 		KyraEngine_v1::SaveHeader header;
 		Common::InSaveFile *in;
 
-		_savegameList = new char *[_savegameListSize];
+		_savegameList = new char*[_savegameListSize];
+		memset(_savegameList, 0, _savegameListSize * sizeof(char*));
 
-		for (int i = 0; i < _savegameListSize; i++) {
-			in = _vm->openSaveForReading(_vm->getSavegameFilename(i), header);
+		for (int i = 0; i < numSaves; i++) {
+			in = _vm->openSaveForReading(_vm->getSavegameFilename(_saveSlots[i]), header);
+			char **listEntry = &_savegameList[allowEmptySlots? _saveSlots[i] : i];
 			if (in) {
-				_savegameList[i] = new char[header.description.size() + 1];
-				Common::strlcpy(_savegameList[i], header.description.c_str(), header.description.size() + 1);
-				Util::convertISOToDOS(_savegameList[i]);
+				*listEntry = new char[header.description.size() + 1];
+				Common::strlcpy(*listEntry, header.description.c_str(), header.description.size() + 1);
+				Util::convertISOToDOS(*listEntry);
 				delete in;
 			} else {
-				_savegameList[i] = 0;
+				*listEntry = 0;
+				error("GUI::updateSavegameList(): Unexpected missing save file for slot: %d.", _saveSlots[i]);
 			}
 		}
 
diff --git a/engines/kyra/gui.h b/engines/kyra/gui.h
index efca845..4991707 100644
--- a/engines/kyra/gui.h
+++ b/engines/kyra/gui.h
@@ -108,6 +108,8 @@ public:
 	// utilities for thumbnail creation
 	virtual void createScreenThumbnail(Graphics::Surface &dst) = 0;
 
+	void notifyUpdateSaveSlotsList() { _saveSlotsListUpdateNeeded = true; }
+
 protected:
 	KyraEngine_v1 *_vm;
 	Screen *_screen;
@@ -116,16 +118,16 @@ protected:
 	// Since ScummVM's savegame indices aren't, we re-index them.
 	// The integers stored in _saveSlots are ScummVM savegame indices.
 	Common::Array<int> _saveSlots;
-	void updateSaveList(bool excludeQuickSaves = false);
+	void updateSaveFileList(bool excludeQuickSaves = false);
 	int getNextSavegameSlot();
-	void updateSavegameList();
+	void updateSaveSlotsList();
 
 	virtual void sortSaveSlots();
 
 	uint32 _lastScreenUpdate;
 	char **_savegameList;
 	int _savegameListSize;
-	bool _savegameListUpdateNeeded;
+	bool _saveSlotsListUpdateNeeded;
 
 	Common::KeyState _keyPressed;
 };
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index fcd66c9..7778feb 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -1609,7 +1609,9 @@ int GUI_Eob::processButtonList(Kyra::Button *buttonList, uint16 inputFlags, int8
 	_flagsMouseRight = (_vm->_mouseClick == 2) ? 2 : 4;
 	_vm->_mouseClick = 0;
 
-	if (in >= 199 && in <= 202) {
+	if (mouseWheel) {
+		return 204 + mouseWheel;
+	} else if (in >= 199 && in <= 202) {
 		buttonReleaseFlag = (inputFlags & 0x800) ? 3 : 1;
 		if (in < 201)
 			_flagsMouseLeft = buttonReleaseFlag;
@@ -2318,7 +2320,6 @@ bool GUI_Eob::runLoadMenu(int x, int y) {
 	int xo = dm->sx;
 	int yo = dm->sy;
 	bool result = false;
-	_savegameListUpdateNeeded = true;
 	
 	_screen->modifyScreenDim(11, dm->sx + (x >> 3), dm->sy + y, dm->w, dm->h);
 	
@@ -2629,7 +2630,6 @@ bool GUI_Eob::runSaveMenu(int x, int y) {
 	int xo = dm->sx;
 	int yo = dm->sy;
 	bool result = false;
-	_savegameListUpdateNeeded = true;
 	
 	_screen->modifyScreenDim(11, dm->sx + (x >> 3), dm->sy + y, dm->w, dm->h);
 	
@@ -2667,12 +2667,11 @@ bool GUI_Eob::runSaveMenu(int x, int y) {
 			Common::Error err = _vm->saveGameStateIntern(_savegameOffset + slot, _saveSlotStringsTemp[slot], &thumb);
 			thumb.free();
 
-			if (err.getCode() == Common::kNoError) {
-				_savegameListUpdateNeeded = true;			
+			if (err.getCode() == Common::kNoError)			
 				result = true;
-			} else {
+			else
 				messageDialogue(11, 15, 6);
-			}
+
 			runLoop = false;			
 		}
 	}
@@ -2687,14 +2686,11 @@ int GUI_Eob::selectSaveSlotDialogue(int x, int y, int id) {
 	_saveSlotX = _saveSlotY = 0;
 	_screen->setCurPage(2);
 	
-	updateSavegameList();
-	setupSaveMenuSlots();
+	updateSaveSlotsList();
+	_savegameOffset = 0;
 
 	drawMenuButtonBox(0, 0, 176, 144, false, false);
 	_screen->printShadedText(_vm->_saveLoadStrings[2 + id], 52, 5, 15, 0);
-	
-	for (int i = 0; i < 7; i++)
-		drawSaveSlotButton(i, 1, 15);
 
 	_screen->copyRegion(0, 0, x, y, 176, 144, 2, 0, Screen::CR_NO_P_CHECK);
 	_screen->setCurPage(0);
@@ -2703,6 +2699,7 @@ int GUI_Eob::selectSaveSlotDialogue(int x, int y, int id) {
 	_saveSlotX = x;
 	_saveSlotY = y;
 	int lastHighlight = -1;
+	int lastOffset = -1;
 	int newHighlight = 0;
 	int slot = -1;
 
@@ -2712,12 +2709,47 @@ int GUI_Eob::selectSaveSlotDialogue(int x, int y, int id) {
 
 		if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
 			runLoop = false;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE]) {
+			newHighlight = 6;
+			runLoop = false;
 		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP2]) {
-			if (++newHighlight > 6)
-				newHighlight = 0;
+			if (++newHighlight > 5) {
+				newHighlight = 5;
+				if (++_savegameOffset > 984)
+					_savegameOffset = 984;
+				else
+					lastOffset = -1;
+			}
 		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP8]) {
-			if (--newHighlight < 0)
-				newHighlight = 6;
+			if (--newHighlight < 0) {
+				newHighlight = 0;
+				if (--_savegameOffset < 0)
+					_savegameOffset = 0;
+				else
+					lastOffset = -1;
+			}
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_PAGEDOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP1]) {
+			_savegameOffset += 6;
+			if (_savegameOffset > 984)
+				_savegameOffset = 984;
+			else
+				lastOffset = -1;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_PAGEUP] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP7]) {
+			_savegameOffset -= 6;
+			if (_savegameOffset < 0)
+				_savegameOffset = 0;
+			else
+				lastOffset = -1;
+		} else if (inputFlag == 205) {
+			if (++_savegameOffset > 984)
+				_savegameOffset = 984;
+			else
+				lastOffset = -1;
+		} else if (inputFlag == 203) {
+			if (--_savegameOffset < 0)
+				_savegameOffset = 0;
+			else
+				lastOffset = -1;
 		} else {
 			slot = getHighlightSlot();
 			if (slot != -1) {
@@ -2727,9 +2759,25 @@ int GUI_Eob::selectSaveSlotDialogue(int x, int y, int id) {
 			}
 		}
 
+		if (lastOffset != _savegameOffset) {
+			lastHighlight = -1;
+			setupSaveMenuSlots();
+			for (int i = 0; i < 7; i++)
+				drawSaveSlotButton(i, 1, 15);
+			lastOffset = _savegameOffset;
+		}
+
 		if (lastHighlight != newHighlight) {
 			drawSaveSlotButton(lastHighlight, 0, 15);
 			drawSaveSlotButton(newHighlight, 0, 6);
+			
+			// Display highlighted slot index in the bottom left corner to avoid people getting lost with the 990 save slots
+			_screen->setFont(Screen::FID_6_FNT);
+			_screen->fillRect(_saveSlotX + 5, _saveSlotY + 135, _saveSlotX + 46, _saveSlotY + 140, _vm->_bkgColor_1);
+			int sli = (newHighlight == 6) ?  _savegameOffset : (_savegameOffset + newHighlight);
+			_screen->printText(Common::String::format("%03d/989", sli).c_str(), _saveSlotX + 5, _saveSlotY + 135, _vm->_color2_1, _vm->_bkgColor_1);
+			_screen->setFont(Screen::FID_8_FNT);
+
 			_screen->updateScreen();
 			lastHighlight = newHighlight;
 		}
@@ -3966,6 +4014,10 @@ int GUI_Eob::getHighlightSlot() {
 	return res;
 }
 
+void GUI_Eob::sortSaveSlots() {
+	Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Less<int>());
+}
+
 void GUI_Eob::restParty_updateRestTime(int hours, bool init) {
 	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
 	int od = _screen->curDimIndex();
diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h
index af3d3d2..30fd4cc 100644
--- a/engines/kyra/gui_eob.h
+++ b/engines/kyra/gui_eob.h
@@ -102,6 +102,7 @@ private:
 
 	void setupSaveMenuSlots();
 	int getHighlightSlot();
+	void sortSaveSlots();
 
 	void restParty_updateRestTime(int hours, bool init);
 
diff --git a/engines/kyra/gui_hof.cpp b/engines/kyra/gui_hof.cpp
index a1e0ce6..8d968ec 100644
--- a/engines/kyra/gui_hof.cpp
+++ b/engines/kyra/gui_hof.cpp
@@ -1148,7 +1148,7 @@ int GUI_HoF::sliderHandler(Button *caller) {
 }
 
 int GUI_HoF::loadMenu(Button *caller) {
-	updateSaveList();
+	updateSaveFileList();
 
 	if (!_vm->_menuDirectlyToLoad) {
 		updateMenuButton(caller);
diff --git a/engines/kyra/gui_lok.cpp b/engines/kyra/gui_lok.cpp
index 6e0d108..e66b3ce 100644
--- a/engines/kyra/gui_lok.cpp
+++ b/engines/kyra/gui_lok.cpp
@@ -596,7 +596,7 @@ void GUI_LoK::setupSavegames(Menu &menu, int num) {
 }
 
 int GUI_LoK::saveGameMenu(Button *button) {
-	updateSaveList();
+	updateSaveFileList();
 
 	updateMenuButton(button);
 	_menu[2].item[5].enabled = true;
@@ -636,7 +636,7 @@ int GUI_LoK::saveGameMenu(Button *button) {
 }
 
 int GUI_LoK::loadGameMenu(Button *button) {
-	updateSaveList();
+	updateSaveFileList();
 
 	if (_vm->_menuDirectlyToLoad) {
 		_menu[2].item[5].enabled = false;
diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp
index ac3d16b..6a8e6e1 100644
--- a/engines/kyra/gui_lol.cpp
+++ b/engines/kyra/gui_lol.cpp
@@ -2222,13 +2222,13 @@ int GUI_LoL::runMenu(Menu &menu) {
 	// Instead, the respevtive struct entry is used to determine whether
 	// a menu has scroll buttons or slider bars.
 	uint8 hasSpecialButtons = 0;
-	_savegameListUpdateNeeded = true;
+	_saveSlotsListUpdateNeeded = true;
 
 	while (_displayMenu) {
 		_vm->_mouseX = _vm->_mouseY = 0;
 
 		if (_currentMenu == &_loadMenu || _currentMenu == &_saveMenu || _currentMenu == &_deleteMenu) {
-			updateSavegameList();
+			updateSaveSlotsList();
 			setupSaveMenuSlots(*_currentMenu, 4);
 		}
 
@@ -2837,7 +2837,7 @@ int GUI_LoL::clickedChoiceMenu(Button *button) {
 				_vm->_saveFileMan->renameSavefile(oldName, newName);
 			}
 			_newMenu = &_mainMenu;
-			_savegameListUpdateNeeded = true;
+			_saveSlotsListUpdateNeeded = true;
 		}
 	} else if (button->arg == _choiceMenu.item[1].itemId) {
 		_newMenu = &_mainMenu;
diff --git a/engines/kyra/gui_mr.cpp b/engines/kyra/gui_mr.cpp
index 8208296..b8bf8f4 100644
--- a/engines/kyra/gui_mr.cpp
+++ b/engines/kyra/gui_mr.cpp
@@ -1277,7 +1277,7 @@ int GUI_MR::optionsButton(Button *button) {
 }
 
 int GUI_MR::loadMenu(Button *caller) {
-	updateSaveList();
+	updateSaveFileList();
 
 	if (!_vm->_menuDirectlyToLoad) {
 		updateMenuButton(caller);
diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp
index a1d74fd..27b329c 100644
--- a/engines/kyra/gui_v2.cpp
+++ b/engines/kyra/gui_v2.cpp
@@ -594,7 +594,7 @@ int GUI_v2::cancelLoadMenu(Button *caller) {
 }
 
 int GUI_v2::saveMenu(Button *caller) {
-	updateSaveList();
+	updateSaveFileList();
 
 	updateMenuButton(caller);
 
@@ -690,7 +690,7 @@ int GUI_v2::cancelSaveMenu(Button *caller) {
 }
 
 int GUI_v2::deleteMenu(Button *caller) {
-	updateSaveList();
+	updateSaveFileList();
 
 	updateMenuButton(caller);
 	if (_saveSlots.size() < 2) {
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index 24a1013..847f304 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -391,6 +391,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 
 	_loading = false;
 	_screen->fadeFromBlack(20);
+	removeInputTop();
 
 	return Common::kNoError;
 }
@@ -589,6 +590,9 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName,
 	}
 
 	delete out;
+
+	_gui->notifyUpdateSaveSlotsList();
+
 	return Common::kNoError;
 }
 
diff --git a/engines/kyra/text_eob.cpp b/engines/kyra/text_eob.cpp
index 3641681..318147c 100644
--- a/engines/kyra/text_eob.cpp
+++ b/engines/kyra/text_eob.cpp
@@ -573,7 +573,7 @@ void TextDisplayer_Eob::textPageBreak() {
 		int inputFlag = vm()->checkInput(0, false) & 0xFF;
 		vm()->removeInputTop();
 
-		while (!inputFlag) {
+		while (!inputFlag && !_vm->shouldQuit()) {
 			vm()->update();
 
 			if (vm()->speechEnabled()) {
@@ -603,7 +603,7 @@ void TextDisplayer_Eob::textPageBreak() {
 			if (target)
 				loop = false;
 		}
-	} while (loop);
+	} while (loop && !_vm->shouldQuit());
 
 	if (vm()->gameFlags().use16ColorMode)
 		screen()->fillRect(x + 8, y, x + 57, y + 9, _textDimData[screen()->curDimIndex()].color2);


Commit: f7032c126dd097e8083e0fc740c7c856e0f2dd58
    https://github.com/scummvm/scummvm/commit/f7032c126dd097e8083e0fc740c7c856e0f2dd58
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:14-08:00

Commit Message:
KYRA: (EOB) - fix some bugs

- fix monster movement
- fix character level gain
- add some static res for party transfer

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    dists/engine-data/kyra.dat
    engines/kyra/chargen.cpp
    engines/kyra/eob1.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/lol.cpp
    engines/kyra/loleobbase.cpp
    engines/kyra/resource.h
    engines/kyra/scene_eob.cpp
    engines/kyra/screen_eob.cpp
    engines/kyra/sprites_eob.cpp
    engines/kyra/staticres_eob.cpp
    engines/kyra/timer.cpp
    engines/kyra/timer_eob.cpp
    engines/kyra/timer_lol.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index 069118b..ad56fb4 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -463,6 +463,8 @@ const ExtractFilename extractFilenames[] = {
 
 	// EYE OF THE BEHOLDER II
 	{ kEob2MainMenuStrings, kTypeStringList, true },
+	{ kEob2TransferConvertTable, kTypeRawData, false },
+	{ kEob2TransferExpTable, kLolTypeRaw32, false },
 
 	{ kEob2IntroStrings, k2TypeSfxList, true },
 	{ kEob2IntroCPSFiles, kTypeStringList, true },
@@ -1779,6 +1781,10 @@ const char *getIdString(const int id) {
 		return "kEob1Npc7Strings";
 	case kEob2MainMenuStrings:
 		return "kEob2MainMenuStrings";
+	case kEob2TransferConvertTable:
+		return "kEob2TransferConvertTable";
+	case kEob2TransferExpTable:
+		return "kEob2TransferExpTable";
 	case kEob2IntroStrings:
 		return "kEob2IntroStrings";
 	case kEob2IntroCPSFiles:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index c7a29fb..d7bcc4d 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -463,6 +463,9 @@ enum kExtractID {
 	kEob1Npc7Strings,
 
 	kEob2MainMenuStrings,
+	kEob2TransferConvertTable,
+	kEob2TransferExpTable,
+
 	kEob2IntroStrings,
 	kEob2IntroCPSFiles,
 	kEob2IntroSeqData00,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index d5b5c29..78baeb6 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1485,6 +1485,8 @@ const int eob2FloppyNeed[] = {
 	kEobBaseFlightObjSclIndex,
 
 	kEob2MainMenuStrings,
+	kEob2TransferConvertTable,
+	kEob2TransferExpTable,
 
 	kEob2IntroStrings,
 	kEob2IntroCPSFiles,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index 0b24924..239ee6e 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -2649,6 +2649,16 @@ const ExtractEntrySearchData kEob2MainMenuStringsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEob2TransferConvertTableProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000031, 0x000004BC, { { 0x96, 0x53, 0xA2, 0xF1, 0x26, 0xFE, 0x1B, 0x5E, 0xDF, 0x62, 0x2C, 0x8C, 0xBD, 0x62, 0x5A, 0xF9 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2TransferExpTableProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000018, 0x0000076B, { { 0x91, 0x65, 0x5B, 0x8D, 0xE8, 0x5B, 0x28, 0x32, 0x4D, 0x7A, 0x57, 0x8E, 0x18, 0x5B, 0x1A, 0xE9 } } } },
+	EXTRACT_END_ENTRY
+};
+
 const ExtractEntrySearchData kEob2IntroStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000321, 0x0000DBC3, { { 0x11, 0x9B, 0x54, 0xB3, 0x34, 0xF0, 0xB5, 0xE1, 0xFA, 0x6A, 0x31, 0x02, 0x59, 0x29, 0xCA, 0x94 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000038E, 0x0001119C, { { 0x92, 0x63, 0x18, 0xDD, 0x9F, 0x62, 0xF5, 0xBC, 0x3D, 0x93, 0xDC, 0x6E, 0xE5, 0xBE, 0x8C, 0x0B } } } },
@@ -4078,6 +4088,9 @@ const ExtractEntry extractProviders[] = {
 	{ kEob1Npc7Strings, kEob1Npc7StringsProvider },
 
 	{ kEob2MainMenuStrings, kEob2MainMenuStringsProvider },
+	{ kEob2TransferConvertTable, kEob2TransferConvertTableProvider },
+	{ kEob2TransferExpTable, kEob2TransferExpTableProvider },
+
 	{ kEob2IntroStrings, kEob2IntroStringsProvider },
 	{ kEob2IntroCPSFiles, kEob2IntroCPSFilesProvider },
 	{ kEob2IntroSeqData00, kEob2IntroSeqData00Provider },
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index 35aff97..8d45a5f 100644
Binary files a/dists/engine-data/kyra.dat and b/dists/engine-data/kyra.dat differ
diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index e97b7a1..7516916 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -108,10 +108,6 @@ private:
 	Screen_Eob *_screen;
 };
 
-bool EobCoreEngine::startCharacterGeneration() {
-	return CharacterGenerator(this, _screen).start(_characters, &_faceShapes);
-}
-
 CharacterGenerator::CharacterGenerator(EobCoreEngine *vm, Screen_Eob *screen) : _vm(vm), _screen(screen),
 	_characters(0), _faceShapes(0), _chargenMagicShapes(0), _chargenButtonLabels(0), _chargenMagicShapeTimer(0),
 	_updateBoxShapesIndex(0), _lastUpdateBoxShapesIndex(0), _magicShapesBox(6), _activeBox(0) {
@@ -1445,6 +1441,15 @@ const int16 CharacterGenerator::_raceModifiers[] = {
 	0, 0, 0, 0,	1, -1, 0, 1, -1, 0, 0, 0, -1, 0, 0, 1, 0, 0
 };
 
+bool EobCoreEngine::startCharacterGeneration() {
+	return CharacterGenerator(this, _screen).start(_characters, &_faceShapes);
+}
+
+bool EobCoreEngine::transferParty() {
+
+	return false;
+}
+
 }	// End of namespace Kyra
 
 #endif // ENABLE_EOB
diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
index 71644c5..8ce41d6 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -78,8 +78,8 @@ Common::Error EobEngine::init() {
 
 	_scriptTimersCount = 1;
 
-	_wllWallFlags[132] = 1;
-	_wllWallFlags[133] = 1;
+	//_wllWallFlags[132] = 1;
+	//_wllWallFlags[133] = 1;
 
 	return Common::kNoError;
 }
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index c94cb16..3a298d8 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -40,14 +40,16 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_teleporterWallId(flags.gameID == GI_EOB1 ? 52 : 44) {
 	_screen = 0;
 	_gui = 0;
-	//_processingButtons=false;
-	//_runLoopUnk2 = 0;
-	//_runLoopTimerUnk = 0;
+
 	_playFinale = false;
 	_runFlag = true;
 	_configMouse = true;
 	_loading = false;
 
+	_envAudioTimer = 0;
+	_flashShapeTimer = 0;
+	_drawSceneTimer = 0;
+
 	_largeItemShapes = _smallItemShapes = _thrownItemShapes = _spellShapes = _firebeamShapes = _itemIconShapes =
 		_wallOfForceShapes = _teleporterShapes = _sparkShapes = _compassShapes = 0;
 	_redSplatShape = _greenSplatShape = _deadCharShape = _disabledCharGrid = _blackBoxSmallGrid =
@@ -60,6 +62,9 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_beholderSpellList = 0;
 	_beholderSfx = 0;
 
+	_transferConvertTable = 0;
+	_transferExpTable = 0;
+
 	_faceShapes = 0;
 	_characters = 0;
 	_items = 0;
@@ -297,6 +302,13 @@ Common::Error EobCoreEngine::init() {
 	memset(&_wllShapeMap[3], -1, 5);
 	memset(&_wllShapeMap[13], -1, 5);
 
+	/*int clen = _flags.gameID == GI_EOB2 ? 80 : 70;
+	memcpy(&_wllShapeMap[256 - clen], _wllVmpMap, clen);
+	memcpy(&_specialWallTypes[256 - 2 * clen], _wllVmpMap, clen);
+	memcpy(&_specialWallTypes[256 - clen], _wllShapeMap, clen);
+	memcpy(&_wllWallFlags[256 - 2 * clen], _wllShapeMap, clen);
+	memcpy(&_wllWallFlags[256 - clen], _specialWallTypes, clen);*/
+
 	_wllVcnOffset = 16;
 
 	_monsters = new EobMonsterInPlay[30];
@@ -384,7 +396,9 @@ Common::Error EobCoreEngine::go() {
 				startupNew();
 		} else if (action == -3) {
 			// transfer party
-			repeatLoop = false;
+			repeatLoop = transferParty();
+			if (repeatLoop && !shouldQuit())
+				startupNew();
 		}
 	}
 
@@ -441,15 +455,13 @@ void EobCoreEngine::runLoop() {
 	_envAudioTimer = _system->getMillis() + (rollDice(1, 10, 3) * 18 * _tickLength);	
 	_flashShapeTimer = 0;
 	_drawSceneTimer = _system->getMillis();
-	//__unkB__ = 1;
+
 	_screen->setFont(Screen::FID_6_FNT);
 	_screen->setScreenDim(7);
 
-	//_runLoopUnk2 = _currentBlock;
 	_runFlag = true;
 
 	while (!shouldQuit() && _runFlag) {
-		//_runLoopUnk2 = _currentBlock;
 		checkPartyStatus(true);
 		checkInput(_activeButtons, true, 0);
 		removeInputTop();
@@ -723,7 +735,7 @@ int EobCoreEngine::generateCharacterHitpointsByLevel(int charIndex, int levelInd
 
 int EobCoreEngine::getClassAndConstHitpointsModifier(int cclass, int constitution) {
 	int res = _hpConstModifiers[constitution];
-
+	// This also applies to EOB1 despite being coded differently there
 	if (res <= 2 || (_classModifierFlags[cclass] & 0x31))
 		return res;
 
@@ -1176,7 +1188,7 @@ uint32 EobCoreEngine::getRequiredExperience(int cClass, int levelIndex, int leve
 
 void EobCoreEngine::increaseCharacterLevel(int charIndex, int levelIndex) {
 	_characters[charIndex].level[levelIndex]++;
-	int hpInc = generateCharacterHitpointsByLevel(charIndex, levelIndex);
+	int hpInc = generateCharacterHitpointsByLevel(charIndex, 1 << levelIndex);
 	_characters[charIndex].hitPointsCur += hpInc;
 	_characters[charIndex].hitPointsMax += hpInc;
 
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index ffc951e..5f1bf8b 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -317,8 +317,9 @@ protected:
 	bool _runFlag;
 	//int _runLoopUnk2;
 
-	// Create Party
+	// Character generation / party transfer
 	bool startCharacterGeneration();
+	bool transferParty();
 
 	uint8 **_faceShapes;
 
@@ -329,6 +330,9 @@ protected:
 	static const uint8 _charClassModUnk[];
 
 	const uint8 *_classModifierFlags;
+	
+	const uint8 *_transferConvertTable;
+	const uint32 *_transferExpTable;
 
 	// timers
 	void setupTimers();
@@ -509,7 +513,7 @@ protected:
 
 	void updateMonsters(int unit);
 	void updateMonsterDest(EobMonsterInPlay *m);
-	void updateMonsterDest2(EobMonsterInPlay *m);
+	void updateMonsterAttackMode(EobMonsterInPlay *m);
 	void updateAllMonsterDests();
 	void turnFriendlyMonstersHostile();
 	int getNextMonsterDirection(int curBlock, int destBlock);
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 7778feb..a5f06c5 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -1978,8 +1978,6 @@ int GUI_Eob::processButtonList(Kyra::Button *buttonList, uint16 inputFlags, int8
 	if (!result)
 		result = inputFlags;
 	
-	//_vm->_processingButtons=false;
-
 	return result;
 }
 
@@ -2773,7 +2771,6 @@ int GUI_Eob::selectSaveSlotDialogue(int x, int y, int id) {
 			
 			// Display highlighted slot index in the bottom left corner to avoid people getting lost with the 990 save slots
 			_screen->setFont(Screen::FID_6_FNT);
-			_screen->fillRect(_saveSlotX + 5, _saveSlotY + 135, _saveSlotX + 46, _saveSlotY + 140, _vm->_bkgColor_1);
 			int sli = (newHighlight == 6) ?  _savegameOffset : (_savegameOffset + newHighlight);
 			_screen->printText(Common::String::format("%03d/989", sli).c_str(), _saveSlotX + 5, _saveSlotY + 135, _vm->_color2_1, _vm->_bkgColor_1);
 			_screen->setFont(Screen::FID_8_FNT);
@@ -3980,6 +3977,7 @@ void GUI_Eob::releaseButtons(Button *list) {
 		delete list;
 		list = n;
 	}
+	_vm->gui_notifyButtonListChanged();
 }
 
 void GUI_Eob::setupSaveMenuSlots() {
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 4fc78c0..030b1de 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -1163,6 +1163,7 @@ void LoLEngine::setCharacterUpdateEvent(int charNum, int updateType, int updateD
 		l->characterUpdateEvents[i] = updateType;
 		l->characterUpdateDelay[i] = updateDelay;
 		_timer->setNextRun(3, _system->getMillis());
+		_timer->resetNextRun();
 		_timer->enable(3);
 		break;
 	}
diff --git a/engines/kyra/loleobbase.cpp b/engines/kyra/loleobbase.cpp
index 2ffae91..c2ec8da 100644
--- a/engines/kyra/loleobbase.cpp
+++ b/engines/kyra/loleobbase.cpp
@@ -164,14 +164,14 @@ Common::Error LolEobBaseEngine::init() {
 	_levelBlockProperties = new LevelBlockProperty[1025];
 	memset(_levelBlockProperties, 0, 1025 * sizeof(LevelBlockProperty));
 
-	_wllVmpMap = new uint8[255];
-	memset(_wllVmpMap, 0, 255);
-	_wllShapeMap = new int8[255];
-	memset(_wllShapeMap, 0, 255);
-	_specialWallTypes = new uint8[255];
-	memset(_specialWallTypes, 0, 255);
-	_wllWallFlags = new uint8[255];
-	memset(_wllWallFlags, 0, 255);
+	_wllVmpMap = new uint8[256];
+	memset(_wllVmpMap, 0, 256);
+	_wllShapeMap = new int8[256];
+	memset(_wllShapeMap, 0, 256);
+	_specialWallTypes = new uint8[256];
+	memset(_specialWallTypes, 0, 256);
+	_wllWallFlags = new uint8[256];
+	memset(_wllWallFlags, 0, 256);
 
 	_blockDrawingBuffer = new uint16[1320];
 	memset(_blockDrawingBuffer, 0, 1320 * sizeof(uint16));
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index f330d42..cd38657 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -537,6 +537,9 @@ enum KyraResources {
 	kEob1Npc7Strings,
 
 	kEob2MainMenuStrings,
+	kEob2TransferConvertTable,
+	kEob2TransferExpTable,
+
 	kEob2IntroStrings,
 	kEob2IntroCPSFiles,
 	kEob2IntroSeqData00,
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index afce9ef..1bd7fca 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -1012,8 +1012,8 @@ void EobCoreEngine::drawScene(int refresh) {
 	}
 
 	if (_sceneDefaultUpdate) {
-		resetSkipFlag();
 		delayUntil(_drawSceneTimer);
+		removeInputTop();
 	}
 
 	if (refresh && !_partyResting)
@@ -1029,7 +1029,7 @@ void EobCoreEngine::drawScene(int refresh) {
 
 	if (_sceneDefaultUpdate) {
 		_sceneDefaultUpdate = false;
-		_drawSceneTimer = _system->getMillis() /*+ 4 * _tickLength*/;
+		_drawSceneTimer = _system->getMillis() + 4 * _tickLength;
 	}
 
 	_sceneUpdateRequired = false;
@@ -1141,8 +1141,8 @@ int EobCoreEngine::calcNewBlockPositionAndTestPassability(uint16 curBlock, uint1
 	int w = _levelBlockProperties[b].walls[direction ^ 2];
 	int f = _wllWallFlags[w];
 
-	if (!f)
-		assert((_flags.gameID == GI_EOB1 && w < 70) || (_flags.gameID == GI_EOB2 && w < 80));
+	//if (!f)
+	assert((_flags.gameID == GI_EOB1 && w < 70) || (_flags.gameID == GI_EOB2 && w < 80));
 
 	if (_flags.gameID == GI_EOB2 && w == 74 && _currentBlock == curBlock) {
 		for (int i = 0; i < 5; i++) {
diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp
index c9ee911..d29af69 100644
--- a/engines/kyra/screen_eob.cpp
+++ b/engines/kyra/screen_eob.cpp
@@ -151,9 +151,6 @@ void Screen_Eob::loadShapeSetBitmap(const char *file, int tempPage, int destPage
 }
 
 void Screen_Eob::loadEobBitmap(const char *file, const uint8 *ditheringData, int tempPage, int destPage, int copyToPage) {
-	//Common::String tmp = file;
-	//if (_vm->game() == GI_EOB1 && tmp.equalsIgnoreCase("spider"))
-	//	tmp += "1";
 	Common::String tmp = Common::String::format("%s.CPS", file);
 	Common::SeekableReadStream *s = _vm->resource()->createReadStream(tmp);
 	bool loadAlternative = false;
@@ -170,15 +167,20 @@ void Screen_Eob::loadEobBitmap(const char *file, const uint8 *ditheringData, int
 	}
 
 	if (loadAlternative) {
-		tmp.setChar('X', 0);
-		s = _vm->resource()->createReadStream(tmp);
-		if (!s)
-			error("Screen_Eob::loadEobBitmap(): CPS file loading failed.");
-		s->seek(768);
-		loadFileDataToPage(s, destPage, 64000);
-		delete s;
+		if (_vm->game() == GI_EOB1) {
+			tmp.insertChar('1', tmp.size() - 4);
+			loadBitmap(tmp.c_str(), tempPage, destPage, 0);
+		} else {
+			tmp.setChar('X', 0);
+			s = _vm->resource()->createReadStream(tmp);
+			if (!s)
+				error("Screen_Eob::loadEobBitmap(): CPS file loading failed.");
+			s->seek(768);
+			loadFileDataToPage(s, destPage, 64000);
+			delete s;
+		}
 	}
-
+	
 	if (copyToPage == -1) {
 		return;
 	} else if (copyToPage == 0) {
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index caf4a74..bd5ab27 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -53,12 +53,8 @@ int LolEobBaseEngine::getBlockDistance(uint16 block1, uint16 block2) {
 
 namespace Kyra {
 
-void EobCoreEngine::loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex) {
-	Common::String s = filename;
-	if ((_flags.gameID == GI_EOB1) && (!scumm_stricmp(filename, "rust") || !scumm_stricmp(filename, "drider") || !scumm_stricmp(filename, "spider") || !scumm_stricmp(filename, "mantis") || !scumm_stricmp(filename, "xorn") || !scumm_stricmp(filename, "xanath")))
-		s += "1";
-
-	_screen->loadShapeSetBitmap(s.c_str(), 3, 3);
+void EobCoreEngine::loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex) {	
+	_screen->loadShapeSetBitmap(filename, 3, 3);
 	const uint16 *enc = &_encodeMonsterShpTable[encodeTableIndex << 2];
 
 	for (int i = 0; i < 6; i++, enc += 4)
@@ -149,6 +145,7 @@ const uint8 *EobCoreEngine::loadActiveMonsterData(const uint8 *data, int level)
 		int32 del = _timer->getDelay(i);
 		_timer->setNextRun(i, (i & 1) ? ct + (del >> 1) * _tickLength : ct + del * _tickLength);
 	}
+	_timer->resetNextRun();
 
 	if (_hasTempDataFlags & (1 << (level - 1)))
 		return data + 420;
@@ -470,6 +467,12 @@ void EobCoreEngine::drawBlockItems(int index) {
 
 void EobCoreEngine::drawDoor(int index) {
 	int s = _visibleBlocks[index]->walls[_sceneDrawVarDown];
+
+	if (_flags.gameID == GI_EOB1 && s == 0x85)
+		s = 0;
+
+	assert((_flags.gameID == GI_EOB1 && s < 32) || (_flags.gameID == GI_EOB2 && s < 53));
+
 	int type = _dscDoorShpIndex[s];
 	int d = _dscDimMap[index];
 	int w = _dscShapeCoords[(index * 5 + 4) << 1];
@@ -722,7 +725,7 @@ void EobCoreEngine::updateMonsters(int unit) {
 			updateMonsterDest(m);
 
 			if (m->mode > 0)
-				updateMonsterDest2(m);
+				updateMonsterAttackMode(m);
 
 			switch (m->mode) {
 			case 0:
@@ -780,7 +783,7 @@ void EobCoreEngine::updateMonsterDest(EobMonsterInPlay *m) {
 	m->dest = _currentBlock;
 }
 
-void EobCoreEngine::updateMonsterDest2(EobMonsterInPlay *m) {
+void EobCoreEngine::updateMonsterAttackMode(EobMonsterInPlay *m) {
 	if (!(m->flags & 1) || m->mode == 10)
 		return;
 	if (m->mode == 8) {
@@ -902,7 +905,7 @@ void EobCoreEngine::updateMoveMonster(EobMonsterInPlay *m) {
 	EobMonsterProperty *p = &_monsterProps[m->type];
 	int d = getNextMonsterDirection(m->block, _currentBlock);
 
-	if ((p->capsFlags & 0x800) && !(d & 1))
+	if ((_flags.gameID == GI_EOB2) && (p->capsFlags & 0x800) && !(d & 1))
 		d >>= 1;
 	else
 		d = m->dir;
@@ -1102,31 +1105,34 @@ void EobCoreEngine::walkMonster(EobMonsterInPlay *m, int destBlock) {
 		return;
 
 	if (m->flags & 8) {
+		// Interestingly, the fear spell in EOB 1 does not expire.
+		// I don't know whether this is intended or not.
 		if (_flags.gameID == GI_EOB1 ) {
 			d ^= 4;
-		} else if (--m->spellStatusLeft <= 0) {
-			m->spellStatusLeft = 0;
-			m->flags &= ~8;
-		} else {
-			d ^= 4;
+		} else if (m->spellStatusLeft > 0) {
+			if (--m->spellStatusLeft == 0)
+				m->flags &= ~8;
+			else
+				d ^= 4;
 		}
 	}
 
 	int d2 = (d - s) & 7;
 
-	if (b + _monsterStepTable0[_flags.gameID == GI_EOB1 ? (d >> 1) : d] == destBlock) {
-		if (_flags.gameID == GI_EOB1 && !(d & 1)) {
-			if (d2 >= 5) {
+	if (_flags.gameID == GI_EOB1) {
+		if ((b + _monsterStepTable0[d >> 1] == _currentBlock) && !(d & 1)) {
+			if (d2 >= 5)
 				s = m->dir - 1;
-			} else if (d2 != 0) {
+			else if (d2 != 0)
 				s = m->dir + 1;
-			}
 			walkMonsterNextStep(m, -1, s & 3);
 			return;
-		} else if (_flags.gameID == GI_EOB2) {
+		}
+	} else if (_flags.gameID == GI_EOB2) {
+		if (b + _monsterStepTable0[d] == destBlock) {
 			if (d & 1) {
 				int e = _monsterStepTable1[((d - 1) << 1) + m->dir];
-				if (e && !((_monsterProps[m->type].capsFlags & 0x200) && (rollDice(1, 4) == 4))) {
+				if (e && (!(_monsterProps[m->type].capsFlags & 0x200) || (rollDice(1, 4) < 4))) {
 					if (walkMonsterNextStep(m, b + e, -1))
 						return;
 				}
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 069bf13..57ee737 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -1241,6 +1241,9 @@ void EobEngine::initSpells() {
 void DarkMoonEngine::initStaticResource() {
 	int temp;
 	_mainMenuStrings = _staticres->loadStrings(kEob2MainMenuStrings, temp);
+	_transferConvertTable = _staticres->loadRawData(kEob2TransferConvertTable, temp);
+	_transferExpTable = _staticres->loadRawDataBe32(kEob2TransferExpTable, temp);
+
 	_introStrings = _staticres->loadStrings(kEob2IntroStrings, temp);
 	_cpsFilesIntro = _staticres->loadStrings(kEob2IntroCPSFiles, temp);
 
diff --git a/engines/kyra/timer.cpp b/engines/kyra/timer.cpp
index 2ab2b62..95c283f 100644
--- a/engines/kyra/timer.cpp
+++ b/engines/kyra/timer.cpp
@@ -149,6 +149,8 @@ void TimerManager::setCountdown(uint8 id, int32 countdown) {
 			uint32 curTime = _system->getMillis();
 			timer->lastUpdate = curTime;
 			timer->nextRun = curTime + countdown * _vm->tickLength();
+			if (timer->enabled & 2)
+				timer->pauseStartTime = curTime;
 
 			_nextRun = MIN(_nextRun, timer->nextRun);
 		}
@@ -177,6 +179,8 @@ int32 TimerManager::getDelay(uint8 id) const {
 void TimerManager::setNextRun(uint8 id, uint32 nextRun) {
 	Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
 	if (timer != _timers.end()) {
+		if (timer->enabled & 2)
+			timer->pauseStartTime = _system->getMillis();
 		timer->nextRun = nextRun;
 		return;
 	}
diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp
index 61fa554..caeae8c 100644
--- a/engines/kyra/timer_eob.cpp
+++ b/engines/kyra/timer_eob.cpp
@@ -115,6 +115,7 @@ void EobCoreEngine::setupTimers() {
 	_timer->addTimer(5, TimerV2(timerUpdateTeleporters), 10, true);
 	_timer->addTimer(6, TimerV2(timerUpdateFoodStatus), 1080, true);
 	_timer->addTimer(7, TimerV2(timerUpdateMonsterIdleAnim), 25, true);
+	_timer->resetNextRun();
 }
 
 void EobCoreEngine::setCharEventTimer(int charIndex, uint32 countdown, int evnt, int updateExistingTimer) {
@@ -132,6 +133,7 @@ void EobCoreEngine::setCharEventTimer(int charIndex, uint32 countdown, int evnt,
 
 	if (ntime < _timer->getNextRun(timerId))
 		_timer->setNextRun(timerId, ntime);
+	_timer->resetNextRun();
 
 	if (updateExistingTimer) {
 		bool updated = false;
@@ -194,6 +196,7 @@ void EobCoreEngine::setupCharacterTimers() {
 			_timer->setCountdown(0x30 | i, (nextTimer - ctime) / _tickLength);
 		}
 	}
+	_timer->resetNextRun();
 }
 
 void EobCoreEngine::advanceTimers(uint32 millis) {
diff --git a/engines/kyra/timer_lol.cpp b/engines/kyra/timer_lol.cpp
index 5a6677a..d0b4062 100644
--- a/engines/kyra/timer_lol.cpp
+++ b/engines/kyra/timer_lol.cpp
@@ -45,6 +45,7 @@ void LoLEngine::setupTimers() {
 	_timer->addTimer(9, TimerV2(timerUpdatePortraitAnimations), 10, true);
 	_timer->addTimer(10, TimerV2(timerUpdateLampState), 360, true);
 	_timer->addTimer(11, TimerV2(timerFadeMessageText), 360, false);
+	_timer->resetNextRun();
 }
 
 void LoLEngine::timerProcessMonsters(int timerNum) {


Commit: c35de374dfe545ffc5044a00a247c5814e3b250e
    https://github.com/scummvm/scummvm/commit/c35de374dfe545ffc5044a00a247c5814e3b250e
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:14-08:00

Commit Message:
KYRA: (EOB) - lots of bug fixes, mostly for EOB II

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    dists/engine-data/kyra.dat
    engines/kyra/detection.cpp
    engines/kyra/eob2.cpp
    engines/kyra/eob2.h
    engines/kyra/eobcommon.cpp
    engines/kyra/magic_eob.cpp
    engines/kyra/resource.h
    engines/kyra/saveload_eob.cpp
    engines/kyra/scene_eob.cpp
    engines/kyra/screen_eob.cpp
    engines/kyra/script_eob.cpp
    engines/kyra/script_eob.h
    engines/kyra/sequences_eob2.cpp
    engines/kyra/staticres_eob.cpp
    engines/kyra/text_eob.cpp
    engines/kyra/timer_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index ad56fb4..11e868f 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -570,7 +570,8 @@ const ExtractFilename extractFilenames[] = {
 	{ kEob2Npc1Strings, kTypeStringList, true },
 	{ kEob2Npc2Strings, kTypeStringList, true },
 	{ kEob2MonsterDustStrings, kTypeStringList, true },
-	{ kEob2DranFoolsStrings, kTypeStringList, true },
+	{ kEob2DreamSteps, kTypeRawData, false },
+	{ kEob2KheldranStrings, kTypeStringList, true },
 	{ kEob2HornStrings, kTypeStringList, true },
 	{ kEob2HornSounds, kTypeRawData, false },
 	{ kEob2WallOfForceDsX, kLolTypeRaw16, false },
@@ -1991,8 +1992,10 @@ const char *getIdString(const int id) {
 		return "kEob2Npc2Strings";
 	case kEob2MonsterDustStrings:
 		return "kEob2MonsterDustStrings";
-	case kEob2DranFoolsStrings:
-		return "kEob2DranFoolsStrings";
+	case kEob2DreamSteps:
+		return "kEob2DreamSteps";
+	case kEob2KheldranStrings:
+		return "kEob2KheldranStrings";
 	case kEob2HornStrings:
 		return "kEob2HornStrings";
 	case kEob2HornSounds:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index d7bcc4d..4ac9475 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -552,7 +552,8 @@ enum kExtractID {
 	kEob2Npc2Strings,
 	kEob2MonsterDustStrings,
 
-	kEob2DranFoolsStrings,
+	kEob2DreamSteps,
+	kEob2KheldranStrings,
 	kEob2HornStrings,
 	kEob2HornSounds,
 
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 78baeb6..cc81aba 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1594,7 +1594,8 @@ const int eob2FloppyNeed[] = {
 	kEob2Npc1Strings,
 	kEob2Npc2Strings,
 	kEob2MonsterDustStrings,
-	kEob2DranFoolsStrings,
+	kEob2DreamSteps,
+	kEob2KheldranStrings,
 	kEob2HornStrings,
 	kEob2HornSounds,
 	kEob2WallOfForceDsX,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index 239ee6e..064b3c8 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -3187,7 +3187,12 @@ const ExtractEntrySearchData kEob2MonsterDustStringsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2DranFoolsStringsProvider[] = {
+const ExtractEntrySearchData kEob2DreamStepsProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000000E, 0x00000114, { { 0x27, 0x32, 0xCB, 0x89, 0x27, 0xC5, 0xDD, 0x91, 0xBE, 0x97, 0x62, 0xF5, 0x76, 0xF7, 0xCD, 0x25 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2KheldranStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000001A, 0x00000887, { { 0xA6, 0xB4, 0x45, 0x1B, 0x33, 0x54, 0x36, 0xAD, 0x1D, 0xB1, 0xDA, 0xC3, 0x12, 0x85, 0x3C, 0x58 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000012, 0x00000511, { { 0xEE, 0x21, 0xA8, 0x6E, 0xF7, 0xEC, 0x9A, 0x8D, 0xBA, 0x8D, 0xE3, 0x4A, 0x17, 0x15, 0xCA, 0x8C } } } },
 	EXTRACT_END_ENTRY
@@ -4198,7 +4203,8 @@ const ExtractEntry extractProviders[] = {
 	{ kEob2Npc1Strings, kEob2Npc1StringsProvider },
 	{ kEob2Npc2Strings, kEob2Npc2StringsProvider },
 	{ kEob2MonsterDustStrings, kEob2MonsterDustStringsProvider },
-	{ kEob2DranFoolsStrings, kEob2DranFoolsStringsProvider },
+	{ kEob2DreamSteps, kEob2DreamStepsProvider },
+	{ kEob2KheldranStrings, kEob2KheldranStringsProvider },
 	{ kEob2HornStrings, kEob2HornStringsProvider },
 	{ kEob2HornSounds, kEob2HornSoundsProvider },
 	{ kEob2WallOfForceDsX, kEob2WallOfForceDsXProvider },
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index 8d45a5f..704c8ad 100644
Binary files a/dists/engine-data/kyra.dat and b/dists/engine-data/kyra.dat differ
diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp
index 44fbc0f..adfb1c6 100644
--- a/engines/kyra/detection.cpp
+++ b/engines/kyra/detection.cpp
@@ -188,7 +188,7 @@ void KyraMetaEngine::removeSaveState(const char *target, int slot) const {
 	// In Kyra games slot 0 can't be deleted, it's for restarting the game(s).
 	// An exception makes Lands of Lore here, it does not have any way to restart the
 	// game except via its main menu.
-	if (slot == 0 && !ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("lol"))
+	if (slot == 0 && !ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("lol") && !ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob") && !ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob2"))
 		return;
 
 	Common::String filename = Kyra::KyraEngine_v1::getSavegameFilename(target, slot);
@@ -198,7 +198,7 @@ void KyraMetaEngine::removeSaveState(const char *target, int slot) const {
 SaveStateDescriptor KyraMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
 	Common::String filename = Kyra::KyraEngine_v1::getSavegameFilename(target, slot);
 	Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename);
-	const bool lolGame = ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("lol");
+	bool nonKyraGame = ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("lol") || ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob") || ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob2");
 
 	if (in) {
 		Kyra::KyraEngine_v1::SaveHeader header;
@@ -212,12 +212,12 @@ SaveStateDescriptor KyraMetaEngine::querySaveMetaInfos(const char *target, int s
 
 			// Slot 0 is used for the 'restart game' save in all three Kyrandia games, thus
 			// we prevent it from being deleted.
-			desc.setDeletableFlag(slot != 0 || lolGame);
+			desc.setDeletableFlag(slot != 0 || nonKyraGame);
 
 			// We don't allow quick saves (slot 990 till 998) to be overwritten.
 			// The same goes for the 'Autosave', which is slot 999. Slot 0 will also
 			// be protected in Kyra 1-3, since it's the 'restart game' save.
-			desc.setWriteProtectedFlag((slot == 0 && !lolGame) || slot >= 990);
+			desc.setWriteProtectedFlag((slot == 0 && !nonKyraGame) || slot >= 990);
 			desc.setThumbnail(header.thumbnail);
 
 			return desc;
@@ -229,7 +229,7 @@ SaveStateDescriptor KyraMetaEngine::querySaveMetaInfos(const char *target, int s
 	// We don't allow quick saves (slot 990 till 998) to be overwritten.
 	// The same goes for the 'Autosave', which is slot 999. Slot 0 will also
 	// be protected in Kyra 1-3, since it's the 'restart game' save.
-	desc.setWriteProtectedFlag((slot == 0 && !lolGame) || slot >= 990);
+	desc.setWriteProtectedFlag((slot == 0 && !nonKyraGame) || slot >= 990);
 
 	return desc;
 }
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index 0ecdba0..0ffca10 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -77,6 +77,10 @@ Common::Error DarkMoonEngine::init() {
 	_color13 = 177;
 	_color14 = 182;
 
+	// Necessary wall hacks (where the original code makes out of bounds accesses)
+	_wllWallFlags[183] = 0x50;
+	_wllVmpMap[183] = 1;
+
 	return Common::kNoError;
 }
 
@@ -312,6 +316,8 @@ const uint8 *DarkMoonEngine::loadDoorShapes(const char *filename, int doorIndex,
 void DarkMoonEngine::drawDoorIntern(int type, int, int x, int y, int w, int wall, int mDim, int16, int16) {
 	int shapeIndex = type * 3 + 2 - mDim;
 	uint8 *shp = _doorShapes[shapeIndex];
+	if (!shp)
+		return;
 
 	if ((_doorType[type] == 0) || (_doorType[type] == 1)) {
 		y = _dscDoorY1[mDim] - shp[1];
@@ -392,7 +398,7 @@ void DarkMoonEngine::useHorn(int charIndex, int weaponSlot) {
 
 bool DarkMoonEngine::checkPartyStatusExtra() {
 	if (checkScriptFlags(0x100000))
-		seq_dranFools();
+		seq_kheldran();
 	return _gui->confirmDialogue2(14, 67, 1);
 }
 
@@ -462,7 +468,7 @@ void DarkMoonEngine::characterLevelGain(int charIndex) {
 		if (er == 0xffffffff)
 			continue;
 
-		increaseCharacterExperience(charIndex, er - c->experience[i]);
+		increaseCharacterExperience(charIndex, er - c->experience[i] + 1);
 	}
 }
 
diff --git a/engines/kyra/eob2.h b/engines/kyra/eob2.h
index f24db79..6da0901 100644
--- a/engines/kyra/eob2.h
+++ b/engines/kyra/eob2.h
@@ -88,10 +88,11 @@ private:
 
 	// Ingame sequence
 	void seq_nightmare();
-	void seq_dranFools();
+	void seq_kheldran();
 	void seq_dranDragonTransformation();
 
-	const char *const *_dranFoolsStrings;
+	const int8 *_dreamSteps;
+	const char *const *_kheldranStrings;
 
 	// characters
 	void drawNpcScene(int npcIndex);
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 3a298d8..6760952 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -302,13 +302,6 @@ Common::Error EobCoreEngine::init() {
 	memset(&_wllShapeMap[3], -1, 5);
 	memset(&_wllShapeMap[13], -1, 5);
 
-	/*int clen = _flags.gameID == GI_EOB2 ? 80 : 70;
-	memcpy(&_wllShapeMap[256 - clen], _wllVmpMap, clen);
-	memcpy(&_specialWallTypes[256 - 2 * clen], _wllVmpMap, clen);
-	memcpy(&_specialWallTypes[256 - clen], _wllShapeMap, clen);
-	memcpy(&_wllWallFlags[256 - 2 * clen], _wllShapeMap, clen);
-	memcpy(&_wllWallFlags[256 - clen], _specialWallTypes, clen);*/
-
 	_wllVcnOffset = 16;
 
 	_monsters = new EobMonsterInPlay[30];
@@ -1248,6 +1241,7 @@ void EobCoreEngine::initDialogueSequence() {
 
 	_txt->resetPageBreakString();
 	gui_updateControls();
+	//_allowSkip = true;
 
 	_sound->playTrack(0);
 	Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
@@ -1263,6 +1257,7 @@ void EobCoreEngine::restoreAfterDialogueSequence() {
 	_dialogueLastBitmap[0] = 0;
 
 	gui_restorePlayField();
+	//_allowSkip = false;
 	_screen->setScreenDim(7);
 
 	if (_flags.gameID == GI_EOB2)
@@ -1603,14 +1598,18 @@ bool EobCoreEngine::checkPassword() {
 	for (int i = 0; i < 3; i++) {
 		_screen->fillRect(_screen->_curDim->sx << 3, _screen->_curDim->sy, ((_screen->_curDim->sx + _screen->_curDim->w) << 3) - 1, (_screen->_curDim->sy + _screen->_curDim->h) - 1, _bkgColor_1);
 		int c = rollDice(1, _mnNumWord - 1, -1);
-		_screen->drawShape(0, _largeItemShapes[_mnDef[c << 2]], 100, 2, 13);
+		const uint8 *shp = (_mnDef[c << 2] < _numLargeItemShapes) ? _largeItemShapes[_mnDef[c << 2]] : (_mnDef[c << 2] < 15 ? 0 : _smallItemShapes[_mnDef[c << 2] - 15]);
+		assert(shp);
+		_screen->drawShape(0, shp, 100, 2, 13);
 		_screen->printShadedText(Common::String::format(_mnPrompt[0], _mnDef[(c << 2) + 1], _mnDef[(c << 2) + 2]).c_str(), (_screen->_curDim->sx + 1) << 3, _screen->_curDim->sy, _screen->_curDim->unk8, _bkgColor_1);
 		memset(answ, 0, 20);
 		gui_drawBox(76, 100, 133, 14, _color2_1, _color1_1, -1);
 		gui_drawBox(77, 101, 131, 12, _color2_1, _color1_1, -1);	
 		if (_gui->getTextInput(answ, 10, 103, 15, _screen->_curDim->unk8, _bkgColor_1, 8) < 0)
 			i = 3;
-		if (scumm_stricmp(_mnWord[c], answ) && i == 2)
+		if (!scumm_stricmp(_mnWord[c], answ))
+			break;
+		else if (i == 2)
 			return false;
 	}
 
@@ -1806,7 +1805,7 @@ int EobCoreEngine::calcCharacterDamage(int charIndex, int times, int itemOrPips,
 	EobCharacter *c = &_characters[charIndex];
 
 	if (savingThrowType != 5) {
-		if (trySavingThrow(c, _charClassModUnk[c->cClass], c->level[0], savingThrowType, c->raceSex))
+		if (trySavingThrow(c, _charClassModUnk[c->cClass], c->level[0], savingThrowType, c->raceSex >> 1 /*fix bug in original code by adding a right shift*/))
 			s = savingThrowReduceDamage(savingThrowEffect, s);
 	}
 
@@ -2006,6 +2005,7 @@ void EobCoreEngine::monsterCloseAttack(EobMonsterInPlay *m) {
 					_txt->printMessage(_ripItemStrings[(_characters[c].raceSex & 1) ^ 1], -1, _characters[c].name);
 					printFullItemName(itm);
 					_txt->printMessage(_ripItemStrings[2]);
+					break;
 				}
 				gui_drawCharPortraitWithStats(c);
 			}
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 646d389..0424558 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -360,7 +360,7 @@ void EobCoreEngine::startSpell(int spell) {
 	if (_castScrollSlot) {
 		gui_updateSlotAfterScrollUse();
 	} else {
-		c->disabledSlots |= 4;
+		_characters[_openBookChar].disabledSlots |= 4;
 		setCharEventTimer(_openBookChar, 72, 11, 1);
 		gui_toggleButtons();
 		gui_drawSpellbook();
@@ -405,7 +405,6 @@ void EobCoreEngine::sparkEffectDefensive(int charIndex) {
 				_screen->updateScreen();
 			}
 		}
-		resetSkipFlag();
 		delay(2 * _tickLength);
 	}
 
@@ -430,7 +429,6 @@ void EobCoreEngine::sparkEffectOffensive() {
 			if (shpIndex)
 				_screen->drawShape(2, _sparkShapes[shpIndex - 1], _sparkEffectOfX[ii], _sparkEffectOfY[ii], 0);
 		}
-		resetSkipFlag();
 		delay(2 * _tickLength);
 		_screen->copyRegion(0, 0, 0, 0, 176, 120, 2, 0, Screen::CR_NO_P_CHECK);
 		_screen->updateScreen();
@@ -444,6 +442,7 @@ void EobCoreEngine::sparkEffectOffensive() {
 }
 
 void EobCoreEngine::setSpellEventTimer(int spell, int timerBaseFactor, int timerLength, int timerLevelFactor, int updateExistingTimer) {
+	assert (spell >= 0);
 	int l = _openBookType == 1 ? getClericPaladinLevel(_openBookChar) : getMageLevel(_openBookChar);
 	uint32 countdown = timerLength * timerBaseFactor + timerLength * l * timerLevelFactor;
 	setCharEventTimer(_activeSpellCharId, countdown, -spell, updateExistingTimer);
@@ -753,7 +752,7 @@ int EobCoreEngine::findFirstCharacterSpellTarget() {
 }
 
 int EobCoreEngine::findNextCharacterSpellTarget(int curCharIndex) {
-	for (; _characterSpellTarget < 6; _characterSpellTarget++) {
+	for (_characterSpellTarget++; _characterSpellTarget < 6; ) {
 		if (++curCharIndex == 6)
 			curCharIndex = 0;
 		if (testCharacter(curCharIndex, 3))
@@ -763,8 +762,14 @@ int EobCoreEngine::findNextCharacterSpellTarget(int curCharIndex) {
 }
 
 int EobCoreEngine::charDeathSavingThrow(int charIndex, int div) {
-	if (specialAttackSavingThrow(charIndex, 4))
+	bool _beholderOrgBhv = true;
+	// Due to a bug in the original code the saving throw result is completely ignored
+	// here. The Beholders' disintegrate spell will alway succeed while their flesh to
+	// stone spell will always fail.
+	if (_beholderOrgBhv)
 		div >>= 1;
+	else
+		div = specialAttackSavingThrow(charIndex, 4) ? 1 : 0;
 	return div;
 }
 
@@ -1226,7 +1231,7 @@ bool EobCoreEngine::spellCallback_end_flameStrike(void *obj) {
 }
 
 void EobCoreEngine::spellCallback_start_raiseDead() {
-	if (_characters[_activeSpellCharId].hitPointsCur == -10 || ((_characters[_activeSpellCharId].raceSex >> 1) == 1)) {
+	if (_characters[_activeSpellCharId].hitPointsCur == -10 && ((_characters[_activeSpellCharId].raceSex >> 1) != 1)) {
 		_characters[_activeSpellCharId].hitPointsCur = 1;
 		gui_drawCharPortraitWithStats(_activeSpellCharId);
 	} else {
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index cd38657..a7060cd 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -626,7 +626,8 @@ enum KyraResources {
 	kEob2Npc2Strings,
 	kEob2MonsterDustStrings,
 
-	kEob2DranFoolsStrings,
+	kEob2DreamSteps,
+	kEob2KheldranStrings,
 	kEob2HornStrings,
 	kEob2HornSounds,
 
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index 847f304..01fbd75 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -366,6 +366,13 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 	_sceneUpdateRequired = true;
 	_screen->setFont(Screen::FID_6_FNT);
 
+	for (int i = 0; i < 6; i++) {
+		for (int ii = 0; ii < 10; ii++) {
+			if (_characters[i].events[ii] == -57)
+				spellCallback_start_trueSeeing();
+		}
+	}
+
 	_screen->setCurPage(0);
 	gui_drawPlayField(false);	
 
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index 1bd7fca..98cd60d 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -647,8 +647,12 @@ void EobCoreEngine::loadLevel(int level, int sub) {
 		delete s;
 	}
 
-	Common::String gfxFile = initLevelData(sub);
-
+	Common::String gfxFile;
+	// Work around for issue with corrupt (incomplete) monster property data 
+	// when loading a savegame saved in a sub level
+	for (int i = 0; i <= sub; i++)
+		gfxFile = initLevelData(i);
+	
 	const uint8 *data = _screen->getCPagePtr(5);
 	const uint8 *pos = data + READ_LE_UINT16(data);
 	uint16 len = READ_LE_UINT16(pos);
@@ -1142,7 +1146,7 @@ int EobCoreEngine::calcNewBlockPositionAndTestPassability(uint16 curBlock, uint1
 	int f = _wllWallFlags[w];
 
 	//if (!f)
-	assert((_flags.gameID == GI_EOB1 && w < 70) || (_flags.gameID == GI_EOB2 && w < 80));
+		assert((_flags.gameID == GI_EOB1 && w < 70) || (_flags.gameID == GI_EOB2 && w < 80));
 
 	if (_flags.gameID == GI_EOB2 && w == 74 && _currentBlock == curBlock) {
 		for (int i = 0; i < 5; i++) {
diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp
index d29af69..9c67750 100644
--- a/engines/kyra/screen_eob.cpp
+++ b/engines/kyra/screen_eob.cpp
@@ -774,15 +774,8 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS
 				int16 py = ((ptr3[i] >> 6) >> scale) + gy2;
 				if (py > ymax)
 					py = ymax;
-				if (posWithinRect(px, py, rX1, rY1, rX2, rY2)) {
+				if (posWithinRect(px, py, rX1, rY1, rX2, rY2))
 					setPagePixel(0, px, py, ptr6[i]);
-					if (i % 5 == 0)  {
-						updateScreen();
-						uint32 cur = _system->getMillis();
-						if (end > cur)
-							_system->delayMillis(end - cur);
-					}
-				}
 			}			
 		}
 
@@ -914,14 +907,6 @@ void Screen_Eob::drawVortex(int numElements, int radius, int stepSize, int, int
 				int16 px = CLIP((xCoords[ii] >> 6) + cx, 0, SCREEN_W - 1);
 				int16 py = CLIP((yCoords[ii] >> 6) + cy, 0, SCREEN_H - 1);
 				setPagePixel(0, px, py, pixBackup[ii]);
-		
-				if (ii % 15 == 0)  {
-					updateScreen();
-					uint32 cur = _system->getMillis();
-					if (nextDelay > cur)
-						_system->delayMillis(nextDelay - cur);
-					nextDelay += 1;
-				}
 			}
 		}
 
diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp
index 6feac6b..1dbb024 100644
--- a/engines/kyra/script_eob.cpp
+++ b/engines/kyra/script_eob.cpp
@@ -106,8 +106,8 @@ EobInfProcessor::EobInfProcessor(EobCoreEngine *engine, Screen_Eob *screen) : _v
 	Opcode(oeob_calcAndInflictCharacterDamage);
 	Opcode(oeob_jump);
 	Opcode(oeob_end);
-	Opcode(oeob_popPosAndReturn);
-	Opcode(oeob_pushPosAndJump);
+	Opcode(oeob_returnFromSubroutine);
+	Opcode(oeob_callSubroutine);
 	OpcodeAlt(oeob_eval);
 	Opcode(oeob_deleteItem);
 	Opcode(oeob_loadNewLevelOrMonsters);
@@ -125,6 +125,7 @@ EobInfProcessor::EobInfProcessor(EobCoreEngine *engine, Screen_Eob *screen) : _v
 #undef OpcodeAlt
 
 	_scriptData = 0;
+	_scriptSize = 0;
 
 	_abortScript = 0;
 	_abortAfterSubroutine = 0;
@@ -134,9 +135,9 @@ EobInfProcessor::EobInfProcessor(EobCoreEngine *engine, Screen_Eob *screen) : _v
 	_lastScriptFunc = 0;
 	_lastScriptSub = 0;
 
-	_scriptPosStack = new int8*[10];
-	memset(_scriptPosStack, 0, 10 * sizeof(int8*));
-	_scriptPosStackIndex = 0;
+	_subroutineStack = new int8*[10];
+	memset(_subroutineStack, 0, 10 * sizeof(int8*));
+	_subroutineStackPos = 0;
 
 	_flagTable = new uint32[18];
 	memset(_flagTable, 0, 18 * sizeof(uint32));
@@ -145,14 +146,14 @@ EobInfProcessor::EobInfProcessor(EobCoreEngine *engine, Screen_Eob *screen) : _v
 	memset(_stack, 0, 30 * sizeof(int16));
 	_stackIndex = 0;
 
-	memset(_scriptPosStack, 0, sizeof(_scriptPosStack));
-	_scriptPosStackIndex = 0;
+	memset(_subroutineStack, 0, sizeof(_subroutineStack));
+	_subroutineStackPos = 0;
 
 	_activeCharacter = -1;
 }
 
 EobInfProcessor::~EobInfProcessor() {
-	delete[] _scriptPosStack;
+	delete[] _subroutineStack;
 	delete[] _flagTable;
 	delete[] _stack;
 	delete[] _scriptData;
@@ -163,8 +164,9 @@ EobInfProcessor::~EobInfProcessor() {
 
 void EobInfProcessor::loadData(const uint8 *data, uint32 dataSize) {
 	delete[] _scriptData;
-	_scriptData = new int8[dataSize];
-	memcpy(_scriptData, data, dataSize);
+	_scriptSize = dataSize;
+	_scriptData = new int8[_scriptSize];
+	memcpy(_scriptData, data, _scriptSize);
 }
 
 void EobInfProcessor::run(int func, int sub) {
@@ -382,7 +384,7 @@ int EobInfProcessor::oeob_movePartyOrObject(int8 *data) {
 		int bc = _lastScriptSub;
 		int bd = _abortScript;
 		int be = _activeCharacter;
-		int bf = _scriptPosStackIndex;
+		int bf = _subroutineStackPos;
 
 		_vm->moveParty(d);
 
@@ -392,7 +394,7 @@ int EobInfProcessor::oeob_movePartyOrObject(int8 *data) {
 		_abortScript = bd;
 		_activeCharacter = be;
 		if (!_abortAfterSubroutine)
-			_scriptPosStackIndex = bf;
+			_subroutineStackPos = bf;
 		_vm->_sceneDefaultUpdate = 0;
 
 	} else if ((a == -31 && _vm->game() == GI_EOB2) || a == -11) {
@@ -589,7 +591,6 @@ int EobInfProcessor::oeob_playSoundEffect(int8 *data) {
 int EobInfProcessor::oeob_removeFlags(int8 *data) {
 	int8 *pos = data;
 	int8 a = *pos++;
-	int8 b = *pos++;
 
 	switch (a) {
 	case -47:
@@ -601,11 +602,11 @@ int EobInfProcessor::oeob_removeFlags(int8 *data) {
 		break;
 
 	case -17:
-		_flagTable[_vm->_currentLevel] &= ~(1 << b);
+		_flagTable[_vm->_currentLevel] &= ~(1 << (*pos++));
 		break;
 
 	case -16:
-		_flagTable[17] &= ~(1 << b);
+		_flagTable[17] &= ~(1 << (*pos++));
 		break;
 
 	default:
@@ -667,28 +668,29 @@ int EobInfProcessor::oeob_jump(int8 *data) {
 
 int EobInfProcessor::oeob_end(int8 *data) {
 	_abortScript = 1;
-	_scriptPosStackIndex = 0;
+	_subroutineStackPos = 0;
 	return 0;
 }
 
-int EobInfProcessor::oeob_popPosAndReturn(int8 *data) {
+int EobInfProcessor::oeob_returnFromSubroutine(int8 *data) {
 	int8 *pos = data;
 
-	if (_scriptPosStackIndex)
-		pos = _scriptPosStack[--_scriptPosStackIndex];
+	if (_subroutineStackPos)
+		pos = _subroutineStack[--_subroutineStackPos];
 	else
 		_abortScript = 1;
 
 	return pos - data;
 }
 
-int EobInfProcessor::oeob_pushPosAndJump(int8 *data) {
+int EobInfProcessor::oeob_callSubroutine(int8 *data) {
 	int8 *pos = data;
 	uint16 offs = READ_LE_UINT16(pos);
+	assert(offs < _scriptSize);
 	pos += 2;
 
-	if (_scriptPosStackIndex < 10) {
-		_scriptPosStack[_scriptPosStackIndex++] = pos;
+	if (_subroutineStackPos < 10) {
+		_subroutineStack[_subroutineStackPos++] = pos;
 		pos = _scriptData + offs;
 	}
 
@@ -1245,7 +1247,7 @@ int EobInfProcessor::oeob_loadNewLevelOrMonsters(int8 *data) {
 		_vm->_sceneUpdateRequired = true;
 
 		_vm->gui_drawAllCharPortraitsWithStats();
-		_scriptPosStackIndex = 0;
+		_subroutineStackPos = 0;
 
 	} else {
 		cmd = *pos++;
diff --git a/engines/kyra/script_eob.h b/engines/kyra/script_eob.h
index 648d214..8f44c7f 100644
--- a/engines/kyra/script_eob.h
+++ b/engines/kyra/script_eob.h
@@ -69,8 +69,8 @@ private:
 	int oeob_calcAndInflictCharacterDamage(int8 *data);
 	int oeob_jump(int8 *data);
 	int oeob_end(int8 *data);
-	int oeob_popPosAndReturn(int8 *data);
-	int oeob_pushPosAndJump(int8 *data);
+	int oeob_returnFromSubroutine(int8 *data);
+	int oeob_callSubroutine(int8 *data);
 	int oeob_eval_v1(int8 *data);
 	int oeob_eval_v2(int8 *data);
 	int oeob_deleteItem(int8 *data);
@@ -94,6 +94,7 @@ private:
 	Common::Array<const InfProc*> _opcodes;
 
 	int8 *_scriptData;
+	uint16 _scriptSize;
 
 	uint8 _abortScript;
 	uint16 _abortAfterSubroutine;
@@ -103,8 +104,8 @@ private:
 	uint16 _lastScriptFunc;
 	uint16 _lastScriptSub;
 
-	int8 **_scriptPosStack;
-	int _scriptPosStackIndex;
+	int8 **_subroutineStack;
+	int _subroutineStackPos;
 
 	uint32 *_flagTable;
 
diff --git a/engines/kyra/sequences_eob2.cpp b/engines/kyra/sequences_eob2.cpp
index ea96779..dcf293b 100644
--- a/engines/kyra/sequences_eob2.cpp
+++ b/engines/kyra/sequences_eob2.cpp
@@ -1282,12 +1282,11 @@ void DarkMoonEngine::seq_nightmare() {
 	_txt->printDialogueText(99, 0);
 	snd_playSoundEffect(54);
 
-	static const int8 dreamSteps[] = { 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 3, 2, 1, 0, -1 };
 	static const uint8 seqX[] = { 0, 20, 0, 20 };
 	static const uint8 seqY[] = { 0, 0, 96, 96 };
 	static const uint8 seqDelay[] = { 12, 7, 7, 12 };
 
-	for (const int8 *i = dreamSteps; *i != -1; ++i) {
+	for (const int8 *i = _dreamSteps; *i != -1; ++i) {
 		drawSequenceBitmap("DREAM", 0, seqX[*i], seqY[*i], 0);
 		delay(seqDelay[*i] * _tickLength);
 	}
@@ -1299,14 +1298,14 @@ void DarkMoonEngine::seq_nightmare() {
 	_screen->setFont(of);
 }
 
-void DarkMoonEngine::seq_dranFools() {
+void DarkMoonEngine::seq_kheldran() {
 	Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
 
 	initDialogueSequence();
 	gui_drawDialogueBox();
 	
 	static const char file[] = "KHELDRAN";
-	_txt->printDialogueText(_dranFoolsStrings[0]);
+	_txt->printDialogueText(_kheldranStrings[0]);
 	drawSequenceBitmap(file, 0, 0, 0, 0);
 	_txt->printDialogueText(20, _moreStrings[0]);
 	snd_playSoundEffect(56);
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 57ee737..274feba 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -1280,7 +1280,8 @@ void DarkMoonEngine::initStaticResource() {
 	_npc1Strings = _staticres->loadStrings(kEob2Npc1Strings, temp);
 	_npc2Strings = _staticres->loadStrings(kEob2Npc2Strings, temp);
 	_monsterDustStrings = _staticres->loadStrings(kEob2MonsterDustStrings, temp);
-	_dranFoolsStrings = _staticres->loadStrings(kEob2DranFoolsStrings, temp);
+	_dreamSteps = (const int8*)_staticres->loadRawData(kEob2DreamSteps, temp);
+	_kheldranStrings = _staticres->loadStrings(kEob2KheldranStrings, temp);
 	_hornStrings = _staticres->loadStrings(kEob2HornStrings, temp);
 	_hornSounds = _staticres->loadRawData(kEob2HornSounds, temp);
 
diff --git a/engines/kyra/text_eob.cpp b/engines/kyra/text_eob.cpp
index 318147c..a2cc5c6 100644
--- a/engines/kyra/text_eob.cpp
+++ b/engines/kyra/text_eob.cpp
@@ -29,16 +29,18 @@
 
 #include "common/system.h"
 
-#define EOBTEXTBUFFERSIZE 2048
-
 namespace Kyra {
 
+enum {
+	kEobTextBufferSize = 2048
+};
+
 TextDisplayer_Eob::TextDisplayer_Eob(LolEobBaseEngine *engine, Screen *sScreen) : _vm(engine), _screen(sScreen),
 	_lineCount(0), _printFlag(false), _lineWidth(0), _numCharsTotal(0), _allowPageBreak(true),
 	_numCharsLeft(0), _numCharsPrinted(0), _sjisLineBreakFlag(false), _waitButtonMode(1) {
 
-	_dialogueBuffer = new char[EOBTEXTBUFFERSIZE];
-	memset(_dialogueBuffer, 0, EOBTEXTBUFFERSIZE);
+	_dialogueBuffer = new char[kEobTextBufferSize];
+	memset(_dialogueBuffer, 0, kEobTextBufferSize);
 
 	_currentLine = new char[85];
 	memset(_currentLine, 0, 85);
@@ -221,12 +223,14 @@ void TextDisplayer_Eob::displayText(char *str, ...) {
 			break;
 
 		default:
-			_lineWidth += (pc98PrintFlag ? 4 : _screen->getCharWidth((uint8)c));
-			_currentLine[_numCharsLeft++] = c;
-			_currentLine[_numCharsLeft] = 0;
+			if (_vm->game() == GI_LOL || c > 30) {
+				_lineWidth += (pc98PrintFlag ? 4 : _screen->getCharWidth((uint8)c));
+				_currentLine[_numCharsLeft++] = c;
+				_currentLine[_numCharsLeft] = 0;
 
-			if ((_textDimData[sdx].column + _lineWidth) > (sd->w << 3))
-				printLine(_currentLine);
+				if ((_textDimData[sdx].column + _lineWidth) > (sd->w << 3))
+					printLine(_currentLine);
+			}
 		}
 
 		c = parseCommand();
@@ -271,6 +275,10 @@ void TextDisplayer_Eob::readNextPara() {
 			_tempString1 = 0;
 	}
 
+	if (d & 0x80) {
+		warning("TextDisplayer_Eob::readNextPara():");
+	}
+
 	_ctrl[1] = d;
 	_ctrl[2] = 0;
 }
@@ -442,8 +450,8 @@ void TextDisplayer_Eob::printLine(char *str) {
 
 void TextDisplayer_Eob::printDialogueText(int stringId, const char *pageBreakString) {
 	const char * str = (const char *)(screen()->getCPagePtr(5) + READ_LE_UINT16(&screen()->getCPagePtr(5)[(stringId - 1) << 1]));
-	assert (strlen(str) < EOBTEXTBUFFERSIZE);
-	Common::strlcpy(_dialogueBuffer, str, EOBTEXTBUFFERSIZE);
+	assert (strlen(str) < kEobTextBufferSize);
+	Common::strlcpy(_dialogueBuffer, str, kEobTextBufferSize);
 	
 	displayText(_dialogueBuffer);
 
@@ -457,8 +465,8 @@ void TextDisplayer_Eob::printDialogueText(int stringId, const char *pageBreakStr
 }
 
 void TextDisplayer_Eob::printDialogueText(const char *str, bool wait) {
-	assert (strlen(str) < EOBTEXTBUFFERSIZE);
-	Common::strlcpy(_dialogueBuffer, str, EOBTEXTBUFFERSIZE);
+	assert (strlen(str) < kEobTextBufferSize);
+	Common::strlcpy(_dialogueBuffer, str, kEobTextBufferSize);
 
 	strcpy(_dialogueBuffer, str);
 	displayText(_dialogueBuffer);
@@ -474,7 +482,7 @@ void TextDisplayer_Eob::printMessage(const char *str, int textColor, ...) {
 
 	va_list args;
 	va_start(args, textColor);
-	vsnprintf(_dialogueBuffer, 240, str, args);
+	vsnprintf(_dialogueBuffer, kEobTextBufferSize - 1, str, args);
 	va_end(args);
 
 	displayText(_dialogueBuffer);
@@ -655,6 +663,7 @@ void TextDisplayer_Eob::displayWaitButton() {
 	while (!vm()->processDialogue() && !vm()->shouldQuit()) {}
 	
 	_screen->fillRect(vm()->_dialogueButtonPosX[0], vm()->_dialogueButtonPosY[0], vm()->_dialogueButtonPosX[0] + vm()->_dialogueButtonW - 1, vm()->_dialogueButtonPosY[0] + vm()->_dialogueButtonH - 1, vm()->_bkgColor_1);
+	_screen->updateScreen();
 	vm()->_dialogueButtonW = 95;
 	SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2);
 	clearCurDim();
diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp
index caeae8c..f36688d 100644
--- a/engines/kyra/timer_eob.cpp
+++ b/engines/kyra/timer_eob.cpp
@@ -221,6 +221,13 @@ void EobCoreEngine::advanceTimers(uint32 millis) {
 			}
 		}
 	}
+
+	for (int i = 0; i < 5; i++) {
+		if (_wallsOfForce[i].duration > ct) {
+			uint32 chrt = _wallsOfForce[i].duration - ct;
+			_wallsOfForce[i].duration = chrt > millis ? ct + chrt - millis : ct;
+		}
+	}
 }
 
 void EobCoreEngine::timerProcessCharacterExchange(int timerNum) {


Commit: 2448d885e4e331a22e1e468277142155a5ddda87
    https://github.com/scummvm/scummvm/commit/2448d885e4e331a22e1e468277142155a5ddda87
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:14-08:00

Commit Message:
KYRA: (EOB) - complete EOBII playability

- fixed temp data generation, block data loading, some spell issues, etc.
- both EOB I and II should now be completable
- one big issue remaining (AdLib driver gets swamped with monster sounds which causes heavy lags in some levels)

Changed paths:
    engines/kyra/detection.cpp
    engines/kyra/eob1.cpp
    engines/kyra/eob2.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/items_eob.cpp
    engines/kyra/lol.h
    engines/kyra/loleobbase.h
    engines/kyra/magic_eob.cpp
    engines/kyra/saveload_eob.cpp
    engines/kyra/scene_eob.cpp
    engines/kyra/scene_lol.cpp
    engines/kyra/screen_eob.cpp
    engines/kyra/script_eob.cpp
    engines/kyra/script_eob.h
    engines/kyra/sequences_eob2.cpp
    engines/kyra/sprites_eob.cpp
    engines/kyra/staticres_eob.cpp
    engines/kyra/text_eob.cpp
    engines/kyra/timer_eob.cpp



diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp
index adfb1c6..dd67c3e 100644
--- a/engines/kyra/detection.cpp
+++ b/engines/kyra/detection.cpp
@@ -160,6 +160,10 @@ SaveStateList KyraMetaEngine::listSaves(const char *target) const {
 
 	SaveStateList saveList;
 	for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+		// Skip automatic final saves made by EOB for the purpose of party transfer
+		if (!scumm_stricmp(file->c_str() + file->size() - 3, "fin"))
+			continue;
+		
 		// Obtain the last 3 digits of the filename, since they correspond to the save slot
 		int slotNum = atoi(file->c_str() + file->size() - 3);
 
diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
index 8ce41d6..d67cda5 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -78,9 +78,6 @@ Common::Error EobEngine::init() {
 
 	_scriptTimersCount = 1;
 
-	//_wllWallFlags[132] = 1;
-	//_wllWallFlags[133] = 1;
-
 	return Common::kNoError;
 }
 
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index 0ffca10..d9aad0c 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -77,10 +77,6 @@ Common::Error DarkMoonEngine::init() {
 	_color13 = 177;
 	_color14 = 182;
 
-	// Necessary wall hacks (where the original code makes out of bounds accesses)
-	_wllWallFlags[183] = 0x50;
-	_wllVmpMap[183] = 1;
-
 	return Common::kNoError;
 }
 
@@ -226,8 +222,8 @@ void DarkMoonEngine::loadMonsterDecoration(const char *file, int16 monsterIndex)
 			SpriteDecoration *m = &_monsterDecorations[i * 6 + ii + monsterIndex];
 
 			m->shp = _screen->encodeShape(dc[0], dc[1], dc[2], dc[3]);
-			m->x = dc[4];
-			m->y = dc[5];
+			m->x = (int8)dc[4];
+			m->y = (int8)dc[5];
 		}
 	}
 
@@ -281,6 +277,7 @@ bool DarkMoonEngine::killMonsterExtra(EobMonsterInPlay *m) {
 		if (m->type) {
 			_playFinale = true;
 			_runFlag = false;
+			delay(850);
 		} else {
 			m->hitPointsCur = 150;
 			m->curRemoteWeapon = 0;
@@ -306,7 +303,7 @@ const uint8 *DarkMoonEngine::loadDoorShapes(const char *filename, int doorIndex,
 		shapeDefs += 8;
 		_doorSwitches[doorIndex * 3 + i].x = *shapeDefs;
 		shapeDefs += 2;
-		_doorSwitches[doorIndex * 3 + i]. y= *shapeDefs;
+		_doorSwitches[doorIndex * 3 + i].y= *shapeDefs;
 		shapeDefs += 2;
 	}
 	_screen->_curPage = 0;
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 6760952..fbd8ef6 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -398,8 +398,11 @@ Common::Error EobCoreEngine::go() {
 	if (!shouldQuit() && action > -3) {
 		runLoop();
 
-		if (_playFinale)
+		if (_playFinale) {
+			// make final save for party transfer
+			saveGameStateIntern(-1, 0, 0);
 			seq_playFinale();
+		}
 	}
 
 	return Common::kNoError;
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 5f1bf8b..7ab9333 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -151,8 +151,8 @@ struct EobItemType {
 
 struct SpriteDecoration {
 	uint8 *shp;
-	uint8 x;
-	uint8 y;
+	int16 x;
+	int16 y;
 };
 
 struct EobMonsterProperty {
@@ -574,11 +574,13 @@ protected:
 	const int8 *_monsterDirChangeTable;
 
 	// Level
-	void loadLevel(int level, int func);
-	Common::String initLevelData(int func);
+	void loadLevel(int level, int sub);
+	Common::String initLevelData(int sub);
 	void addLevelItems();
 	void loadVcnData(const char *file, const char */*nextFile*/);
 	void loadBlockProperties(const char *mazFile);
+	const uint8 *getBlockFileData(int levelIndex);
+	const uint8 *getBlockFileData(const char *mazFile);
 	void loadDecorations(const char *cpsFile, const char *decFile);
 	void assignWallsAndDecorations(int wallIndex, int vmpIndex, int decDataIndex, int specialType, int flags);
 	void releaseDecorations();
@@ -613,6 +615,7 @@ protected:
 
 	int8 _currentSub;
 	Common::String _curGfxFile;
+	Common::String _curBlockFile;
 
 	uint32 _drawSceneTimer;
 	uint32 _flashShapeTimer;
@@ -1006,13 +1009,13 @@ protected:
 	void spellCallback_start_heal();
 	void spellCallback_start_layOnHands();
 	void spellCallback_start_turnUndead();
-	bool spellCallback_end_lightningBoltPassive(void *obj);
-	bool spellCallback_end_unk1Passive(void *obj);
-	bool spellCallback_end_unk2Passive(void *obj);
-	bool spellCallback_end_deathSpellPassive(void *obj);
-	bool spellCallback_end_disintegratePassive(void *obj);
-	bool spellCallback_end_causeCriticalWoundsPassive(void *obj);
-	bool spellCallback_end_fleshToStonePassive(void *obj);
+	bool spellCallback_end_monster_lightningBolt(void *obj);
+	bool spellCallback_end_monster_fireball1(void *obj);
+	bool spellCallback_end_monster_fireball2(void *obj);
+	bool spellCallback_end_monster_deathSpell(void *obj);
+	bool spellCallback_end_monster_disintegrate(void *obj);
+	bool spellCallback_end_monster_causeCriticalWounds(void *obj);
+	bool spellCallback_end_monster_fleshToStone(void *obj);
 
 	int8 _openBookSpellLevel;
 	int8 _openBookSpellSelectedItem;
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index a5f06c5..d333528 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -853,12 +853,12 @@ int EobCoreEngine::clickedCamp(Button *button) {
 		gui_drawCharPortraitWithStats(i);
 	}
 
-	_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 14, Screen::CR_NO_P_CHECK);
 	_screen->copyPage(0, 7);
+	_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 12, Screen::CR_NO_P_CHECK);
 	
 	_gui->runCampMenu();
 
-	_screen->copyRegion(0, 0, 0, 120, 176, 24, 14, 2, Screen::CR_NO_P_CHECK);
+	_screen->copyRegion(0, 0, 0, 120, 176, 24, 12, 2, Screen::CR_NO_P_CHECK);
 	_screen->setScreenDim(cd);
 	drawScene(0);
 
@@ -2250,7 +2250,7 @@ void GUI_Eob::runCampMenu() {
 					_vm->dropCharacter(selectCharacterDialogue(53));
 					_vm->gui_drawPlayField(false);
 					res = true;
-					_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 14, Screen::CR_NO_P_CHECK);
+					_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 12, Screen::CR_NO_P_CHECK);
 					_screen->setFont(Screen::FID_6_FNT);
 					_vm->gui_drawAllCharPortraitsWithStats();
 					_screen->setFont(Screen::FID_8_FNT);
@@ -2282,6 +2282,8 @@ void GUI_Eob::runCampMenu() {
 			default:
 				break;
 			}
+
+			lastMenu = -1;
 			
 		} else {
 			Common::Point p = _vm->getMousePos();
diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
index a83207b..e3309f8 100644
--- a/engines/kyra/items_eob.cpp
+++ b/engines/kyra/items_eob.cpp
@@ -208,8 +208,8 @@ int EobCoreEngine::validateInventorySlotForItem(Item item, int charIndex, int sl
 	int itm = _characters[charIndex].inventory[slot];
 	int ex = _itemTypes[_items[itm].type].extraProperties & 0x7f;
 
-	if (slot < 2 && (_items[itm].flags & 0x20) && ex > 0 && ex < 4) {
-		if (_flags.gameID == GI_EOB2)
+	if (_items[itm].flags & 0x20 && (_flags.gameID == GI_EOB1 || slot < 2)) {
+		if (_flags.gameID == GI_EOB2 && ex > 0 && ex < 4)
 			_txt->printMessage(_validateCursedString[0], -1, _characters[charIndex].name);
 		return 0;
 	}
@@ -692,6 +692,9 @@ void EobCoreEngine::endObjectFlight(EobFlyingObject *fo) {
 }
 
 void EobCoreEngine::checkFlyingObjects() {
+	if (!_runFlag)
+		return;
+
 	for (int i = 0; i < 10; i++) {
 		EobFlyingObject *fo = &_flyingObjects[i];
 		if (!fo->enable)
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index 8ddba86..e75d621 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -917,6 +917,7 @@ private:
 	uint8 *getLevelDecorationShapes(int index);
 	void restoreTempDataAdjustMonsterStrength(int index);
 	void loadBlockProperties(const char *cmzFile);
+	const uint8 *getBlockFileData(int levelIndex);
 	void loadLevelShpDat(const char *shpFile, const char *datFile, bool flag);
 	void loadLevelGraphics(const char *file, int specialColor, int weight, int vcnLen, int vmpLen, const char *palFile);
 
diff --git a/engines/kyra/loleobbase.h b/engines/kyra/loleobbase.h
index 02b236d..cb7f920 100644
--- a/engines/kyra/loleobbase.h
+++ b/engines/kyra/loleobbase.h
@@ -147,6 +147,7 @@ protected:
 	virtual void drawSceneShapes(int start) = 0;
 	virtual void drawDecorations(int index) = 0;
 
+	virtual const uint8 *getBlockFileData(int levelIndex) = 0;
 	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);
@@ -233,6 +234,7 @@ protected:
 	const uint8 *_dscTileIndex;
 
 	const uint8 *_dscDoorShpIndex;
+	int _dscDoorShpIndexSize;
 	const uint8 *_dscDoorY2;
 
 	// Script
@@ -308,7 +310,7 @@ protected:
 	virtual Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) = 0;
 
 	void generateTempData();
-	void restoreBlockTempData(int levelIndex);
+	virtual void restoreBlockTempData(int levelIndex);
 	void releaseTempData();
 	virtual void *generateMonsterTempData(LevelTempData *tmp) = 0;
 	virtual void restoreMonsterTempData(LevelTempData *tmp) = 0;
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 0424558..9063d51 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -236,8 +236,14 @@ void EobCoreEngine::removeCharacterEffect(int spell, int charIndex, int showWarn
 	EobCharacter *c = &_characters[charIndex];
 	EobSpell *s = &_spells[spell];
 
-	if (showWarning)
+	if (showWarning) {
+		int od = _screen->curDimIndex();
+		Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+		_screen->setScreenDim(7);
 		printWarning(Common::String::format(_magicStrings3[_flags.gameID == GI_EOB1 ? 3 : 2], c->name, s->name).c_str());
+		_screen->setScreenDim(od);
+		_screen->setFont(of);
+	}
 
 	if (s->endCallback)
 		(this->*s->endCallback)(c);
@@ -1281,12 +1287,12 @@ void EobCoreEngine::spellCallback_start_turnUndead() {
 	_preventMonsterFlash = false;
 }
 
-bool EobCoreEngine::spellCallback_end_lightningBoltPassive(void *obj) {
+bool EobCoreEngine::spellCallback_end_monster_lightningBolt(void *obj) {
 	EobFlyingObject *fo = (EobFlyingObject*)obj;
 	return magicObjectDamageHit(fo, 0, 0, 12, 1);
 }
 
-bool EobCoreEngine::spellCallback_end_unk1Passive(void *obj) {
+bool EobCoreEngine::spellCallback_end_monster_fireball1(void *obj) {
 	EobFlyingObject *fo = (EobFlyingObject*)obj;
 	bool res = false;
 	if (_partyEffectFlags & 0x20000) {
@@ -1301,12 +1307,12 @@ bool EobCoreEngine::spellCallback_end_unk1Passive(void *obj) {
 	return res;
 }
 
-bool EobCoreEngine::spellCallback_end_unk2Passive(void *obj) {
+bool EobCoreEngine::spellCallback_end_monster_fireball2(void *obj) {
 	EobFlyingObject *fo = (EobFlyingObject*)obj;
 	return magicObjectDamageHit(fo, 0, 0, 18, 0);
 }
 
-bool EobCoreEngine::spellCallback_end_deathSpellPassive(void *obj) {
+bool EobCoreEngine::spellCallback_end_monster_deathSpell(void *obj) {
 	EobFlyingObject *fo = (EobFlyingObject*)obj;
 	if (fo->curBlock != _currentBlock)
 		return false;
@@ -1323,7 +1329,7 @@ bool EobCoreEngine::spellCallback_end_deathSpellPassive(void *obj) {
 	return true;
 }
 
-bool EobCoreEngine::spellCallback_end_disintegratePassive(void *obj) {
+bool EobCoreEngine::spellCallback_end_monster_disintegrate(void *obj) {
 	EobFlyingObject *fo = (EobFlyingObject*)obj;
 	if (fo->curBlock != _currentBlock)
 		return false;
@@ -1339,7 +1345,7 @@ bool EobCoreEngine::spellCallback_end_disintegratePassive(void *obj) {
 	return true;
 }
 
-bool EobCoreEngine::spellCallback_end_causeCriticalWoundsPassive(void *obj) {
+bool EobCoreEngine::spellCallback_end_monster_causeCriticalWounds(void *obj) {
 	EobFlyingObject *fo = (EobFlyingObject*)obj;
 	if (fo->curBlock != _currentBlock)
 		return false;
@@ -1353,7 +1359,7 @@ bool EobCoreEngine::spellCallback_end_causeCriticalWoundsPassive(void *obj) {
 	return true;
 }
 
-bool EobCoreEngine::spellCallback_end_fleshToStonePassive(void *obj) {
+bool EobCoreEngine::spellCallback_end_monster_fleshToStone(void *obj) {
 	EobFlyingObject *fo = (EobFlyingObject*)obj;
 	if (fo->curBlock != _currentBlock)
 		return false;
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index 01fbd75..49c6668 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -47,15 +47,7 @@ void LolEobBaseEngine::generateTempData() {
 	_lvlTempData[l]->wallsXorData = new uint8[4096];
 	_lvlTempData[l]->flags = new uint16[1024];
 
-	const uint8 *p = 0;
-	const uint8 *p2 = 0;
-	if (_flags.gameID == GI_LOL) {
-		screen()->loadBitmap(Common::String::format("LEVEL%d.CMZ", _currentLevel).c_str(), 15, 15, 0);
-		p = screen()->getCPagePtr(14);
-	} else {
-		p2 = p = _res->fileData(Common::String::format("LEVEL%d.MAZ", _currentLevel).c_str(), 0);
-	}
-
+	const uint8 *p = getBlockFileData(_currentLevel);
 	uint16 len = READ_LE_UINT16(p + 4);
 	p += 6;
 
@@ -75,20 +67,11 @@ void LolEobBaseEngine::generateTempData() {
 	_lvlTempData[l]->wallsOfForce = generateWallOfForceTempData(_lvlTempData[l]);
 
 	_hasTempDataFlags |= (1 << l);
-	delete[] p2;
 }
 
 void LolEobBaseEngine::restoreBlockTempData(int levelIndex) {
 	int l = levelIndex - 1;
-	const uint8 *p = 0;
-	const uint8 *p2 = 0;
-	if (_flags.gameID == GI_LOL) {
-		screen()->loadBitmap(Common::String::format("LEVEL%d.CMZ", levelIndex).c_str(), 3, 3, 0);
-		p = screen()->getCPagePtr(2);
-	} else {
-		p2 = p = _res->fileData(Common::String::format("LEVEL%d.MAZ", levelIndex).c_str(), 0);
-	}
-
+	const uint8 *p = getBlockFileData(levelIndex);
 	uint16 len = READ_LE_UINT16(p + 4);
 	p += 6;
 
@@ -106,8 +89,6 @@ void LolEobBaseEngine::restoreBlockTempData(int levelIndex) {
 	restoreMonsterTempData(_lvlTempData[l]);
 	restoreFlyingObjectTempData(_lvlTempData[l]);
 	restoreWallOfForceTempData(_lvlTempData[l]);
-
-	delete[] p2;
 }
 
 void LolEobBaseEngine::releaseTempData() {
@@ -144,7 +125,14 @@ void LolEobBaseEngine::releaseFlyingObjectTempData(LevelTempData *tmp) {
 #ifdef ENABLE_EOB
 
 Common::Error EobCoreEngine::loadGameState(int slot) {
-	const char *fileName = getSavegameFilename(slot);
+	const char *fileName = 0;
+
+	if (slot == -1) {
+		_savegameFilename = /*_targetName + */Common::String("eob.fin");
+		fileName = _savegameFilename.c_str();
+	} else {
+		fileName = getSavegameFilename(slot);
+	}
 
 	SaveHeader header;
 	Common::InSaveFile *saveFile = openSaveForReading(fileName, header);
@@ -388,7 +376,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 		useMagicBookOrSymbol(_openBookChar, _openBookType);
 	}
 
-	_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 14, Screen::CR_NO_P_CHECK);
+	_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 12, Screen::CR_NO_P_CHECK);
 
 	gui_toggleButtons();
 	setHandItem(_itemInHand);
@@ -404,8 +392,18 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 }
 
 Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) {
-	const Common::String finSuffix(".FIN");
-	const char *fileName = (slot != -1) ? getSavegameFilename(slot) : (_targetName + finSuffix).c_str();
+	Common::String saveNameTmp;
+	const char *fileName = 0;
+
+	if (slot == -1) {
+		_savegameFilename = _targetName + Common::String(".fin");
+		fileName = _savegameFilename.c_str();
+		saveNameTmp = _targetName + Common::String(" final");
+		saveNameTmp.toUppercase();
+		saveName = saveNameTmp.c_str();
+	} else {
+		fileName = getSavegameFilename(slot);
+	}
 
 	Common::OutSaveFile *out = openSaveForWriting(fileName, saveName, thumbnail);
 	if (!out)
@@ -525,7 +523,7 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName,
 		LevelTempData *l = _lvlTempData[i];
 		if (!l || !(_hasTempDataFlags & (1 << i)))
 			continue;
-
+	
 		out->write(l->wallsXorData, 4096);
 		for (int ii = 0; ii < 1024; ii++)
 			out->writeByte(l->flags[ii] & 0xff);
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index 98cd60d..5f06139 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -863,23 +863,31 @@ void EobCoreEngine::loadVcnData(const char *file, const char*/*nextFile*/) {
 
 void EobCoreEngine::loadBlockProperties(const char *mazFile) {
 	memset(_levelBlockProperties, 0, 1024 * sizeof(LevelBlockProperty));
-	Common::SeekableReadStream *s = _res->createReadStream(mazFile);
-	_screen->loadFileDataToPage(s, 2, 4096);
-	delete s;
+	const uint8 *p = getBlockFileData(mazFile) + 6;
 
 	if (_hasTempDataFlags & (1 << (_currentLevel - 1))) {
 		restoreBlockTempData(_currentLevel);
 		return;
 	}
 
-	const uint8 *p = _screen->getCPagePtr(2) + 6;
-
 	for (int i = 0; i < 1024; i++) {
 		for (int ii = 0; ii < 4; ii++)
 			_levelBlockProperties[i].walls[ii] = *p++;
 	}
 }
 
+const uint8 *EobCoreEngine::getBlockFileData(int) {
+	Common::SeekableReadStream *s = _res->createReadStream(_curBlockFile);
+	_screen->loadFileDataToPage(s, 15, s->size());
+	delete s;
+	return _screen->getCPagePtr(14);
+}
+
+const uint8 *EobCoreEngine::getBlockFileData(const char *mazFile) {
+	_curBlockFile = mazFile;
+	return getBlockFileData(0);
+}
+
 void EobCoreEngine::loadDecorations(const char *cpsFile, const char *decFile) {
 	_screen->loadShapeSetBitmap(cpsFile, 3, 3);
 	Common::SeekableReadStream *s = _res->createReadStream(decFile);
@@ -919,6 +927,12 @@ void EobCoreEngine::loadDecorations(const char *cpsFile, const char *decFile) {
 
 void EobCoreEngine::assignWallsAndDecorations(int wallIndex, int vmpIndex, int decIndex, int specialType, int flags) {
 	_wllVmpMap[wallIndex] = vmpIndex;
+	for (int i = 0; i < 6; i++) {
+		for (int ii = 0; ii < 10; ii++) {
+			if (_characters[i].events[ii] == -57)
+				spellCallback_start_trueSeeing();
+		}
+	}
 	_wllShapeMap[wallIndex] = _mappedDecorationsCount + 1;
 	_specialWallTypes[wallIndex] = specialType;
 	_wllWallFlags[wallIndex] = flags ^ 4;
@@ -1145,8 +1159,7 @@ int EobCoreEngine::calcNewBlockPositionAndTestPassability(uint16 curBlock, uint1
 	int w = _levelBlockProperties[b].walls[direction ^ 2];
 	int f = _wllWallFlags[w];
 
-	//if (!f)
-		assert((_flags.gameID == GI_EOB1 && w < 70) || (_flags.gameID == GI_EOB2 && w < 80));
+	assert((_flags.gameID == GI_EOB1 && w < 70) || (_flags.gameID == GI_EOB2 && w < 80));
 
 	if (_flags.gameID == GI_EOB2 && w == 74 && _currentBlock == curBlock) {
 		for (int i = 0; i < 5; i++) {
diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp
index 998fb73..d28477b 100644
--- a/engines/kyra/scene_lol.cpp
+++ b/engines/kyra/scene_lol.cpp
@@ -252,6 +252,11 @@ void LoLEngine::loadBlockProperties(const char *cmzFile) {
 	}
 }
 
+const uint8 *LoLEngine::getBlockFileData(int levelIndex) {
+	_screen->loadBitmap(Common::String::format("LEVEL%d.CMZ", levelIndex).c_str(), 15, 15, 0);
+	return screen()->getCPagePtr(14);
+}
+
 void LoLEngine::loadLevelShpDat(const char *shpFile, const char *datFile, bool flag) {
 	memset(_tempBuffer5120, 0, 5120);
 
diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp
index 9c67750..4161c75 100644
--- a/engines/kyra/screen_eob.cpp
+++ b/engines/kyra/screen_eob.cpp
@@ -769,7 +769,6 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS
 	for (int l = 2; l;) {
 		if (l != 2) {
 			for (int i = numElements - 1; i >= 0; i--) {
-				uint32 end = _system->getMillis() + 1;
 				int16 px = ((ptr2[i] >> 6) >> scale) + gx2;
 				int16 py = ((ptr3[i] >> 6) >> scale) + gy2;
 				if (py > ymax)
@@ -902,7 +901,6 @@ void Screen_Eob::drawVortex(int numElements, int radius, int stepSize, int, int
 	int d = 0;
 	for (int i = 2; i; ) {
 		if (i != 2) {
-			uint32 nextDelay = _system->getMillis() + 1;
 			for (int ii = numElements - 1; ii >= 0; ii--) {
 				int16 px = CLIP((xCoords[ii] >> 6) + cx, 0, SCREEN_W - 1);
 				int16 py = CLIP((yCoords[ii] >> 6) + cy, 0, SCREEN_H - 1);
@@ -912,7 +910,7 @@ void Screen_Eob::drawVortex(int numElements, int radius, int stepSize, int, int
 
 		i = 0;
 		int r = (stepSize >> 1) + (stepSize >> 2) + (stepSize >> 3);
-		uint32 nextDelay2 = _system->getMillis() + 1;
+		uint32 nextDelay = _system->getMillis() + 1;
 
 		for (int ii = 0; ii < numElements; ii++) {
 			if (pixDelay[ii] == 0) {
@@ -951,9 +949,9 @@ void Screen_Eob::drawVortex(int numElements, int radius, int stepSize, int, int
 					if (ii % 15 == 0)  {
 						updateScreen();
 						uint32 cur = _system->getMillis();
-						if (nextDelay2 > cur)
-							_system->delayMillis(nextDelay2 - cur);
-						nextDelay2 += 1;
+						if (nextDelay > cur)
+							_system->delayMillis(nextDelay - cur);
+						nextDelay += 1;
 					}
 				}
 			} else {
diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp
index 1dbb024..6522731 100644
--- a/engines/kyra/script_eob.cpp
+++ b/engines/kyra/script_eob.cpp
@@ -89,8 +89,8 @@ void EobCoreEngine::updateScriptTimers() {
 EobInfProcessor::EobInfProcessor(EobCoreEngine *engine, Screen_Eob *screen) : _vm(engine), _screen(screen),
 	_commandMin(engine->game() == GI_EOB1 ? -27 : -31) {
 
-#define Opcode(x) _opcodes.push_back(new InfProc(this, &EobInfProcessor::x))
-#define OpcodeAlt(x) if (_vm->game() == GI_EOB1) Opcode(x##_v1); else Opcode(x##_v2);
+#define Opcode(x) _opcodes.push_back(new InfOpcode(new InfProc(this, &EobInfProcessor::x), #x))
+#define OpcodeAlt(x) if (_vm->game() == GI_EOB1) { Opcode(x##_v1); } else { Opcode(x##_v2); }
 	Opcode(oeob_setWallType);
 	Opcode(oeob_toggleWallState);
 	Opcode(oeob_openDoor);
@@ -157,8 +157,10 @@ EobInfProcessor::~EobInfProcessor() {
 	delete[] _flagTable;
 	delete[] _stack;
 	delete[] _scriptData;
-	for (Common::Array<const InfProc*>::const_iterator a = _opcodes.begin(); a != _opcodes.end(); ++a)
+	for (Common::Array<const InfOpcode*>::const_iterator a = _opcodes.begin(); a != _opcodes.end(); ++a) {
+		delete (*a)->proc;
 		delete *a;
+	}
 	_opcodes.clear();
 }
 
@@ -196,7 +198,8 @@ void EobInfProcessor::run(int func, int sub) {
 		int8 cmd = *pos++;
 		if (cmd <= _commandMin || cmd >= 0)
 			continue;
-		pos += (*_opcodes[-(cmd + 1)])(pos);
+		debugC(5, kDebugLevelScript, "[0x%.08X] EobInfProcessor::%s()", (uint32)(pos - _scriptData), _opcodes[-(cmd + 1)]->desc.c_str());
+		pos += (*_opcodes[-(cmd + 1)]->proc)(pos);
 	} while (!_abortScript && !_abortAfterSubroutine);
 }
 
diff --git a/engines/kyra/script_eob.h b/engines/kyra/script_eob.h
index 8f44c7f..f7e5f09 100644
--- a/engines/kyra/script_eob.h
+++ b/engines/kyra/script_eob.h
@@ -91,7 +91,12 @@ private:
 	Screen_Eob *_screen;
 
 	typedef Common::Functor1Mem<int8*, int, EobInfProcessor> InfProc;
-	Common::Array<const InfProc*> _opcodes;
+	struct InfOpcode {
+		InfOpcode(InfProc *p, const char *d) : proc(p), desc(d) {}
+		InfProc *proc;
+		Common::String desc;
+	};
+	Common::Array<const InfOpcode*> _opcodes;
 
 	int8 *_scriptData;
 	uint16 _scriptSize;
diff --git a/engines/kyra/sequences_eob2.cpp b/engines/kyra/sequences_eob2.cpp
index dcf293b..37aca45 100644
--- a/engines/kyra/sequences_eob2.cpp
+++ b/engines/kyra/sequences_eob2.cpp
@@ -466,6 +466,7 @@ void DarkMoonEngine::seq_playFinale() {
 	DarkmoonSequenceHelper sq(_system, this, _screen, DarkmoonSequenceHelper::kFinale, _finaleStrings, _cpsFilesFinale, _palFilesFinale, _shapesFinale, _seqFinale);
 
 	_screen->setCurPage(0);
+	_screen->setFont(Screen::FID_8_FNT);
 
 	_sound->loadSoundFile("FINALE1");
 	_sound->playTrack(0);
@@ -936,10 +937,11 @@ DarkmoonSequenceHelper::DarkmoonSequenceHelper(OSystem *system, DarkMoonEngine *
 	_fadePalRate = 0;
 
 	_screen->setScreenPalette(*_palettes[0]);
+	_screen->setFont(Screen::FID_8_FNT);
 	_screen->hideMouse();
 
-	_system->delayMillis(150);
-	_vm->resetSkipFlag(true);
+	_vm->delay(150);
+	_vm->_eventList.clear();
 	_vm->_allowSkip = true;
 }
 
@@ -1274,7 +1276,7 @@ void DarkmoonSequenceHelper::waitForSongNotifier(int index, bool introUpdateAnim
 
 void DarkMoonEngine::seq_nightmare() {
 	Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
-	_screen->copyRegion(0, 0, 0, 120, 176, 24, 14, 2, Screen::CR_NO_P_CHECK);
+	_screen->copyRegion(0, 0, 0, 120, 176, 24, 12, 2, Screen::CR_NO_P_CHECK);
 
 	initDialogueSequence();
 	gui_drawDialogueBox();
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index bd5ab27..eca0530 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -471,7 +471,8 @@ void EobCoreEngine::drawDoor(int index) {
 	if (_flags.gameID == GI_EOB1 && s == 0x85)
 		s = 0;
 
-	assert((_flags.gameID == GI_EOB1 && s < 32) || (_flags.gameID == GI_EOB2 && s < 53));
+	if (s >= _dscDoorShpIndexSize)
+		return;
 
 	int type = _dscDoorShpIndex[s];
 	int d = _dscDimMap[index];
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 274feba..4ff879c 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -254,7 +254,7 @@ void LolEobBaseEngine::initStaticResource() {
 	_dscBlockMap = _staticres->loadRawData(kLolEobCommonDscBlockMap, temp);
 	_dscBlockIndex = (const int8 *)_staticres->loadRawData(kLolEobCommonDscBlockIndex, temp);
 	_dscDimMap = _staticres->loadRawData(kLolEobCommonDscDimMap, temp);
-	_dscDoorShpIndex = _staticres->loadRawData(kLolEobCommonDscDoorShapeIndex, temp);
+	_dscDoorShpIndex = _staticres->loadRawData(kLolEobCommonDscDoorShapeIndex, _dscDoorShpIndexSize);
 	_dscDoorY2 = _staticres->loadRawData(kLolEobCommonDscDoorY2, temp);
 	_moreStrings = _staticres->loadStrings(kLolEobCommonMoreStrings, temp);
 }
@@ -1010,14 +1010,14 @@ void EobCoreEngine::initSpells() {
 	ec2(empty);
 	ec(empty);
 	ec2(empty);
-	ec1(lightningBoltPassive);
-	ec2(unk1Passive);
+	ec1(monster_lightningBolt);
+	ec2(monster_fireball1);
 	ec2(empty);
-	ec2(unk2Passive);
-	ec(deathSpellPassive);
-	ec(disintegratePassive);
-	ec2(causeCriticalWoundsPassive);
-	ec2(fleshToStonePassive);
+	ec2(monster_fireball2);
+	ec(monster_deathSpell);
+	ec(monster_disintegrate);
+	ec2(monster_causeCriticalWounds);
+	ec2(monster_fleshToStone);
 
 	_spells = new EobSpell[_numSpells];
 	memset(_spells, 0, _numSpells * sizeof(EobSpell));	
diff --git a/engines/kyra/text_eob.cpp b/engines/kyra/text_eob.cpp
index a2cc5c6..0fe01df 100644
--- a/engines/kyra/text_eob.cpp
+++ b/engines/kyra/text_eob.cpp
@@ -619,6 +619,7 @@ void TextDisplayer_Eob::textPageBreak() {
 		screen()->fillRect(x, y, x + w - 1, y + 8, _textDimData[screen()->curDimIndex()].color2);
 
 	clearCurDim();
+	_screen->updateScreen();
 
 	if (vm()->game() == GI_LOL)
 		vm()->_timer->pauseSingleTimer(11, false);
diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp
index f36688d..277e04e 100644
--- a/engines/kyra/timer_eob.cpp
+++ b/engines/kyra/timer_eob.cpp
@@ -390,6 +390,7 @@ void EobCoreEngine::timerUpdateTeleporters(int timerNum) {
 
 void EobCoreEngine::timerUpdateFoodStatus(int timerNum) {
 	for (int i = 0; i < 6; i++) {
+		// Ring of Sustenance check
 		if (checkInventoryForRings(i, 2))
 			continue;
 		EobCharacter *c = &_characters[i];


Commit: 816b40ebf8c653f4c3f898ae4697ea85f5fe015f
    https://github.com/scummvm/scummvm/commit/816b40ebf8c653f4c3f898ae4697ea85f5fe015f
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:15-08:00

Commit Message:
KYRA: (EOB) - add debugger, etc.

- add basic debugger support
- fix several minor bugs

Changed paths:
    engines/kyra/chargen.cpp
    engines/kyra/debugger.cpp
    engines/kyra/debugger.h
    engines/kyra/eob1.h
    engines/kyra/eob2.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/items_eob.cpp
    engines/kyra/saveload_eob.cpp
    engines/kyra/scene_eob.cpp
    engines/kyra/script_eob.cpp
    engines/kyra/script_eob.h
    engines/kyra/sequences_eob1.cpp
    engines/kyra/sequences_eob2.cpp
    engines/kyra/sound_lol.cpp
    engines/kyra/sprites_eob.cpp
    engines/kyra/timer_eob.cpp



diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index 7516916..0e38ffe 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -47,6 +47,7 @@ private:
 	int raceSexMenu();
 	int classMenu(int raceSex);
 	int alignmentMenu(int cClass);
+	int getInput(Button *buttonList);
 	void updateMagicShapes();
 	void generateStats(int index);
 	void modifyMenu();
@@ -153,8 +154,7 @@ bool CharacterGenerator::start(EobCharacter *characters, uint8 ***faceShapes) {
 	_characters = characters;
 	_faceShapes = *faceShapes;
 
-	_vm->sound()->playTrack(0);
-
+	_vm->snd_stopSound();
 	_vm->delay(_vm->_tickLength);
 
 	init();
@@ -169,8 +169,7 @@ bool CharacterGenerator::start(EobCharacter *characters, uint8 ***faceShapes) {
 
 	for (bool loop = true; loop && (!_vm->shouldQuit()); ) {
 		_vm->_gui->updateBoxFrameHighLight(_activeBox + 6);
-		_vm->sound()->process();
-		int inputFlag = _vm->checkInput(_vm->_activeButtons, false, 0);
+		int inputFlag = getInput(_vm->_activeButtons);		
 		_vm->removeInputTop();
 
 		if (inputFlag) {
@@ -381,9 +380,7 @@ int CharacterGenerator::viewDeleteCharacter() {
 	int res = 0;
 	for (bool loop = true; loop && _characters[_activeBox].name[0] && !_vm->shouldQuit(); ) {
 		_vm->_gui->updateBoxFrameHighLight(_activeBox + 6);
-		_vm->sound()->process();
-
-		int inputFlag = _vm->checkInput(_vm->_activeButtons, false, 0);
+		int inputFlag =getInput(_vm->_activeButtons);
 		int cbx = _activeBox;
 		_vm->removeInputTop();
 
@@ -520,8 +517,7 @@ int CharacterGenerator::classMenu(int raceSex) {
 
 	while (res == -1 && !_vm->shouldQuit()) {
 		updateMagicShapes();
-
-		int in = _vm->checkInput(0, false, 0) & 0xff;
+		int in = getInput(_vm->_activeButtons) & 0xff;
 		Common::Point mp = _vm->getMousePos();
 
 		if (in == _vm->_keyMap[Common::KEYCODE_ESCAPE] || _vm->_gui->_menuLastInFlags == _vm->_keyMap[Common::KEYCODE_ESCAPE] || _vm->_gui->_menuLastInFlags == _vm->_keyMap[Common::KEYCODE_b]) {
@@ -569,8 +565,7 @@ int CharacterGenerator::alignmentMenu(int cClass) {
 
 	while (res == -1 && !_vm->shouldQuit()) {
 		updateMagicShapes();
-
-		int in = _vm->checkInput(0, false, 0) & 0xff;
+		int in = getInput(_vm->_activeButtons) & 0xff;
 		Common::Point mp = _vm->getMousePos();
 
 		if (in == _vm->_keyMap[Common::KEYCODE_ESCAPE] || _vm->_gui->_menuLastInFlags == _vm->_keyMap[Common::KEYCODE_ESCAPE] || _vm->_gui->_menuLastInFlags == _vm->_keyMap[Common::KEYCODE_b]) {
@@ -593,9 +588,21 @@ int CharacterGenerator::alignmentMenu(int cClass) {
 	return res;
 }
 
-void CharacterGenerator::updateMagicShapes() {
-	_vm->sound()->process();
+int CharacterGenerator::getInput(Button *buttonList) {
+	if (_vm->game() == GI_EOB1 && _vm->sound()->checkTrigger()) {
+		_vm->sound()->resetTrigger();
+		_vm->sound()->playTrack(20);
+	// WORKAROUND for EOB II: The original implements the same sound trigger check as in EOB I.
+	// However, Westwood seems to have forgotten to set the trigger at the end of the AdLib song,
+	// so that the music will not loop. We simply check whether the sound driver is still playing.
+	} else if (_vm->game() == GI_EOB2 && !_vm->sound()->isPlaying()) {
+		_vm->delay(3 * _vm->_tickLength);
+		_vm->sound()->playTrack(13);
+	}
+	return _vm->checkInput(buttonList, false, 0);
+}
 
+void CharacterGenerator::updateMagicShapes() {
 	if (_magicShapesBox != _activeBox) {
 		_chargenMagicShapeTimer = 0;
 		_magicShapesBox = _activeBox;
@@ -719,7 +726,7 @@ void CharacterGenerator::statsAndFacesMenu() {
 
 	while (!in && !_vm->shouldQuit()) {
 		updateMagicShapes();
-		in = _vm->checkInput(_vm->_activeButtons, false, 0);
+		in = getInput(_vm->_activeButtons);
 		_vm->removeInputTop();
 
 		if (in == 0x8001) {
@@ -786,7 +793,7 @@ void CharacterGenerator::faceSelectMenu() {
 
 		while (!in && !_vm->shouldQuit()) {
 			updateMagicShapes();
-			in = _vm->checkInput(_vm->_activeButtons, false, 0);
+			in = getInput(_vm->_activeButtons);
 			_vm->removeInputTop();
 
 			_vm->_gui->updateBoxFrameHighLight(box + 10);
@@ -978,7 +985,7 @@ int CharacterGenerator::modifyStat(int index, int8 *stat1, int8 *stat2) {
 	for (bool loop = true; loop && !_vm->shouldQuit(); ) {
 		uint8 v1 = *s1;
 		updateMagicShapes();
-		int	inputFlag = _vm->checkInput(_vm->_activeButtons, false, 0);
+		int	inputFlag = getInput(_vm->_activeButtons);
 		_vm->removeInputTop();
 
 		if (inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_MINUS] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP_MINUS] || inputFlag == 0x8009) {
diff --git a/engines/kyra/debugger.cpp b/engines/kyra/debugger.cpp
index 35b4d8b..6a4b88c 100644
--- a/engines/kyra/debugger.cpp
+++ b/engines/kyra/debugger.cpp
@@ -26,6 +26,7 @@
 #include "kyra/timer.h"
 #include "kyra/resource.h"
 #include "kyra/lol.h"
+#include "kyra/eobcommon.h"
 
 #include "common/system.h"
 
@@ -470,4 +471,9 @@ Debugger_LoL::Debugger_LoL(LoLEngine *vm) : Debugger(vm), _vm(vm) {
 }
 #endif // ENABLE_LOL
 
+#ifdef ENABLE_EOB
+Debugger_Eob::Debugger_Eob(EobCoreEngine *vm) : Debugger(vm), _vm(vm) {
+}
+#endif // ENABLE_EOB
+
 } // End of namespace Kyra
diff --git a/engines/kyra/debugger.h b/engines/kyra/debugger.h
index e9c0a6a..1bd8363 100644
--- a/engines/kyra/debugger.h
+++ b/engines/kyra/debugger.h
@@ -108,6 +108,18 @@ protected:
 };
 #endif // ENABLE_LOL
 
+#ifdef ENABLE_EOB
+class EobCoreEngine;
+
+class Debugger_Eob : public Debugger {
+public:
+	Debugger_Eob(EobCoreEngine *vm);
+
+protected:
+	EobCoreEngine *_vm;
+};
+#endif // ENABLE_EOB
+
 } // End of namespace Kyra
 
 #endif
diff --git a/engines/kyra/eob1.h b/engines/kyra/eob1.h
index 227db4f..8811d7d 100644
--- a/engines/kyra/eob1.h
+++ b/engines/kyra/eob1.h
@@ -65,8 +65,8 @@ private:
 
 	void seq_xdeath();
 
+	void loadSetIntroPalette(const char *filename);
 	void copyBlurRegion(int x1, int y1, int x2, int y2, int w, int h, int step);
-
 	void boxMorphTransition(int targetDestX, int targetDestY, int targetFinalX, int targetFinalY, int targetSrcX, int targetSrcY, int targetFinalW, int targetFinalH, int originX1, int originY1, int originW, int originH);
 	void whirlTransition();
 	
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index d9aad0c..f309fae 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -115,7 +115,7 @@ void DarkMoonEngine::runNpcDialogue(int npcIndex) {
 		int r = runDialogue(-1, 0, _npc1Strings[0], _npc1Strings[1], 0) - 1;
 
 		if (r == 0) {
-			_sound->playTrack(0);
+			snd_stopSound();
 			delay(3 * _tickLength);
 			snd_playSoundEffect(91);
 			npcJoinDialogue(1, 5, 6, 7);
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index fbd8ef6..802907e 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -27,6 +27,7 @@
 #include "kyra/sound_intern.h"
 #include "kyra/script_eob.h"
 #include "kyra/timer.h"
+#include "kyra/debugger.h"
 
 #include "common/config-manager.h"
 
@@ -40,6 +41,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_teleporterWallId(flags.gameID == GI_EOB1 ? 52 : 44) {
 	_screen = 0;
 	_gui = 0;
+	_debugger = 0;
 
 	_playFinale = false;
 	_runFlag = true;
@@ -220,8 +222,11 @@ EobCoreEngine::~EobCoreEngine() {
 	_menuDefs = 0;
 
 	delete _inf;
+	_inf = 0;
 	delete _timer;
 	_timer = 0;
+	delete _debugger;
+	_debugger = 0;
 }
 
 Common::Error EobCoreEngine::init() {
@@ -241,6 +246,7 @@ Common::Error EobCoreEngine::init() {
 
 	//MidiDriverType midiDriver = MidiDriver::detectDevice(MDT_PCSPK | MDT_ADLIB);
 	_sound = new SoundAdLibPC(this, _mixer);
+	_sound->init();
 	assert(_sound);
 
 	if (_sound)
@@ -266,8 +272,13 @@ Common::Error EobCoreEngine::init() {
 
 	setupKeyMap();
 	_gui = new GUI_Eob(this);
+	assert(_gui);
 	_txt = new TextDisplayer_Eob(this, _screen);
+	assert(_txt);
 	_inf = new EobInfProcessor(this, _screen);
+	assert(_inf);
+	_debugger = new Debugger_Eob(this);
+	assert(_debugger);
 
 	_screen->loadFont(Screen::FID_6_FNT, "FONT6.FNT");
 	_screen->loadFont(Screen::FID_8_FNT, "FONT8.FNT");
@@ -682,7 +693,7 @@ void EobCoreEngine::setHandItem(Item itemIndex) {
 	int icon = _items[_itemInHand].icon;
 	const uint8 *shp = _itemIconShapes[icon];
 
-	if (icon && (_items[_itemInHand].flags & 0x80) && ((_flags.gameID == GI_EOB2 && (_partyEffectFlags & 2)) || (_flags.gameID == GI_EOB1 && (_partyEffectFlags & 0x10000)))) {
+	if (icon && (_items[_itemInHand].flags & 0x80) && (_partyEffectFlags & 2)) {
 		memcpy(_tempIconShape, shp, 300);
 		if (_flags.gameID == GI_EOB1)
 			_screen->replaceShapePalette(_tempIconShape, &_itemsOverlay[icon << 4]);
@@ -1246,7 +1257,7 @@ void EobCoreEngine::initDialogueSequence() {
 	gui_updateControls();
 	//_allowSkip = true;
 
-	_sound->playTrack(0);
+	snd_stopSound();
 	Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
 	_screen->loadFileDataToPage(s, 5, 32000);
 	_txt->setupField(9, 0);
@@ -2246,6 +2257,10 @@ void EobCoreEngine::snd_playSoundEffect(int id, int volume) {
 	_sound->playSoundEffect(id, volume);
 }
 
+void EobCoreEngine::snd_stopSound() {
+	_sound->playSoundEffect(0);
+}
+
 }	// End of namespace Kyra
 
 #endif // ENABLE_EOB
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 7ab9333..fcfc29f 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -1139,6 +1139,7 @@ protected:
 
 	// sound
 	void snd_playSoundEffect(int id, int volume=0xFF);
+	void snd_stopSound();
 };
 
 }	// End of namespace Kyra
diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
index e3309f8..96b19a9 100644
--- a/engines/kyra/items_eob.cpp
+++ b/engines/kyra/items_eob.cpp
@@ -303,7 +303,7 @@ int EobCoreEngine::countQueuedItems(Item itemQueue, int16 id, int16 type, int co
 		EobItem *itm = &_items[o1];
 		forceLoop = false;
 		if (id != -1 || type != -1) {
-			if (((id != -1 ) || (id == -1 && type != itm->type)) && ((type != -1) || (type == -1 && id != o1)))
+			if (((id != -1) || (id == -1 && type != itm->type)) && ((type != -1) || (type == -1 && id != o1)))
 				continue;			
 		}
 
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index 49c6668..07841be 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -411,9 +411,13 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName,
 
 	completeDoorOperations();
 	generateTempData();
+	advanceTimers(_restPartyElapsedTime);
+	_restPartyElapsedTime = 0;
 
-	for (int i = 0; i < 6; i++) {
+	for (int i = 0; i < 6; i++)
 		timerSpecialCharacterUpdate(0x30 + i);
+
+	for (int i = 0; i < 6; i++) {
 		EobCharacter *c = &_characters[i];
 
 		out->writeByte(c->id);
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index 5f06139..cf20429 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -708,8 +708,6 @@ Common::String EobCoreEngine::initLevelData(int sub){
 
 	int slen = (_flags.gameID == GI_EOB1) ? 12 : 13;
 
-	_sound->playTrack(0);
-
 	for (int i = 0; i < sub; i++)
 		pos = data + READ_LE_UINT16(pos);
 
@@ -762,7 +760,7 @@ Common::String EobCoreEngine::initLevelData(int sub){
 	}
 
 	if (_flags.gameID == GI_EOB2) {
-		delay(_tickLength);
+		delay(3 * _tickLength);
 		_sound->loadSoundFile((const char*) pos);
 		pos += 13;
 	}
@@ -1029,10 +1027,8 @@ void EobCoreEngine::drawScene(int refresh) {
 		}
 	}
 
-	if (_sceneDefaultUpdate) {
+	if (_sceneDefaultUpdate)
 		delayUntil(_drawSceneTimer);
-		removeInputTop();
-	}
 
 	if (refresh && !_partyResting)
 		_screen->copyRegion(0, 0, 0, 0, 176, 120, 2, 0, Screen::CR_NO_P_CHECK);
diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp
index 6522731..e85b1dc 100644
--- a/engines/kyra/script_eob.cpp
+++ b/engines/kyra/script_eob.cpp
@@ -133,7 +133,7 @@ EobInfProcessor::EobInfProcessor(EobCoreEngine *engine, Screen_Eob *screen) : _v
 	_preventRest = 0;
 
 	_lastScriptFunc = 0;
-	_lastScriptSub = 0;
+	_lastScriptFlags = 0;
 
 	_subroutineStack = new int8*[10];
 	memset(_subroutineStack, 0, 10 * sizeof(int8*));
@@ -171,7 +171,7 @@ void EobInfProcessor::loadData(const uint8 *data, uint32 dataSize) {
 	memcpy(_scriptData, data, _scriptSize);
 }
 
-void EobInfProcessor::run(int func, int sub) {
+void EobInfProcessor::run(int func, int flags) {
 	int o = _vm->_levelBlockProperties[func].assignedObjects;
 	if (!o)
 		return;
@@ -179,7 +179,7 @@ void EobInfProcessor::run(int func, int sub) {
 	uint16 f = _vm->_levelBlockProperties[func].flags;
 
 	uint16 subFlags = ((f & 0xfff8) >> 3) | 0xe0;
-	if (!(sub & subFlags))
+	if (!(flags & subFlags))
 		return;
 
 	_abortScript = 0;
@@ -188,9 +188,7 @@ void EobInfProcessor::run(int func, int sub) {
 	_activeCharacter = -1;
 
 	_lastScriptFunc = func;
-	_lastScriptSub = sub;
-
-	_vm->resetSkipFlag(true);
+	_lastScriptFlags = flags;
 
 	int8 *pos = (int8*)(_scriptData + o);
 
@@ -198,7 +196,7 @@ void EobInfProcessor::run(int func, int sub) {
 		int8 cmd = *pos++;
 		if (cmd <= _commandMin || cmd >= 0)
 			continue;
-		debugC(5, kDebugLevelScript, "[0x%.08X] EobInfProcessor::%s()", (uint32)(pos - _scriptData), _opcodes[-(cmd + 1)]->desc.c_str());
+		debugC(3, kDebugLevelScript, "[0x%.04X] EobInfProcessor::%s()", (uint32)(pos - _scriptData), _opcodes[-(cmd + 1)]->desc.c_str());
 		pos += (*_opcodes[-(cmd + 1)]->proc)(pos);
 	} while (!_abortScript && !_abortAfterSubroutine);
 }
@@ -379,21 +377,23 @@ int EobInfProcessor::oeob_movePartyOrObject(int8 *data) {
 				continue;
 			_vm->placeMonster(&_vm->_monsters[i], d, _vm->_monsters[i].pos);
 		}
+		debugC(5, kDebugLevelScript, "         - move monsters on block '0x%.04X' to block '0x%.04X'", c, d);
 
 	} else if (a == -24) {
 		// move party to block d
 		int ba = _dlgResult;
 		int bb = _lastScriptFunc;
-		int bc = _lastScriptSub;
+		int bc = _lastScriptFlags;
 		int bd = _abortScript;
 		int be = _activeCharacter;
 		int bf = _subroutineStackPos;
 
 		_vm->moveParty(d);
+		debugC(5, kDebugLevelScript, "         - move party to block '0x%.04X'", d);
 
 		_dlgResult = ba;
 		_lastScriptFunc = bb;
-		_lastScriptSub = bc;
+		_lastScriptFlags = bc;
 		_abortScript = bd;
 		_activeCharacter = be;
 		if (!_abortAfterSubroutine)
@@ -447,6 +447,7 @@ int EobInfProcessor::oeob_movePartyOrObject(int8 *data) {
 				_vm->_items[i].block = d;
 			}
 		}
+		debugC(5, kDebugLevelScript, "         - move items from level '%d', block '0x%.04X' to level '%d', block '0x%.04X'", c, e, d, f);
 	}
 
 	_vm->_sceneUpdateRequired = true;
@@ -550,24 +551,29 @@ int EobInfProcessor::oeob_setFlags(int8 *data) {
 	switch (*pos++) {
 	case -47:
 		_preventRest = 0;
+		debugC(5, kDebugLevelScript, "         - set preventRest to 0");
 		break;
 
 	case -28:
 		_dlgResult = 1;
+		debugC(5, kDebugLevelScript, "         - set dlgResult to 1");
 		break;
 
 	case -17:
 		_flagTable[_vm->_currentLevel] |= (1 << (*pos++));
+		debugC(5, kDebugLevelScript, "         - set level flag '%d' for current level (current level = '%d')", *(pos - 1), _vm->_currentLevel);
 		break;
 
 	case -16:
 		_flagTable[17] |= (1 << (*pos++));
+		debugC(5, kDebugLevelScript, "         - set global flag '%d'", *(pos - 1));
 		break;
 
 	case -13:
 		b = *pos++;
 		_vm->_monsters[b].flags |= (1 << (*pos++));
 		_vm->_monsters[b].mode = 0;
+		debugC(5, kDebugLevelScript, "         - set monster flag '%d' for monster '%d'", *(pos - 1), b);
 		break;
 
 	default:
@@ -598,18 +604,22 @@ int EobInfProcessor::oeob_removeFlags(int8 *data) {
 	switch (a) {
 	case -47:
 		_preventRest = 1;
+		debugC(5, kDebugLevelScript, "         - set preventRest to 1");
 		break;
 
 	case -28:
 		_dlgResult = 0;
+		debugC(5, kDebugLevelScript, "         - set dlgResult to 0");
 		break;
 
 	case -17:
 		_flagTable[_vm->_currentLevel] &= ~(1 << (*pos++));
+		debugC(5, kDebugLevelScript, "         - clear level flag '%d' for current level (current level = '%d')", *(pos - 1), _vm->_currentLevel);
 		break;
 
 	case -16:
 		_flagTable[17] &= ~(1 << (*pos++));
+		debugC(5, kDebugLevelScript, "         - clear global flag '%d'", *(pos - 1));
 		break;
 
 	default:
@@ -724,10 +734,12 @@ int EobInfProcessor::oeob_eval_v1(int8 *data) {
 				break;
 			}
 			_stack[_stackIndex++] = a;
+			debugC(5, kDebugLevelScript, "         - check if whole party is invisible - PUSH result: '%d'", a);
 			break;
 
-		case 1:
+		case 1:			
 			_stack[_stackIndex++] = _vm->rollDice(pos[0], pos[1], pos[2]);
+			debugC(9, kDebugLevelScript, "         - throw dice(s): num = '%d', pips = '%d', offset = '%d' - PUSH result: '%d'", pos[0], pos[1], pos[2], _stack[_stackIndex - 1]);
 			pos += 3;
 			break;
 
@@ -743,6 +755,7 @@ int EobInfProcessor::oeob_eval_v1(int8 *data) {
 				}
 			}
 			_stack[_stackIndex++] = b;
+			debugC(5, kDebugLevelScript, "         - check if character with class flags '0x%.02X' is present - PUSH result: '%d'", cmd, b);
 			break;
 
 		case 3:
@@ -757,10 +770,12 @@ int EobInfProcessor::oeob_eval_v1(int8 *data) {
 				}
 			}
 			_stack[_stackIndex++] = b;
+			debugC(5, kDebugLevelScript, "         - check if character with race '%d' is present - PUSH result: '%d'", cmd, b);
 			break;
 
 		case 6:
-			_stack[_stackIndex++] = _lastScriptSub;
+			_stack[_stackIndex++] = _lastScriptFlags;
+			debugC(5, kDebugLevelScript, "         - get script execution flags - PUSH result: '%d'", _lastScriptFlags);
 			break;
 
 		case 13:
@@ -768,37 +783,45 @@ int EobInfProcessor::oeob_eval_v1(int8 *data) {
 			switch (*pos++) {
 			case -31:
 				_stack[_stackIndex++] = itm->type;
+				debugC(5, kDebugLevelScript, "         - get hand item type (hand item number = '%d') - PUSH result: '%d'", _vm->_itemInHand, itm->type);
 				break;
 
 			case -11:
 				_stack[_stackIndex++] = _vm->_itemInHand;
+				debugC(5, kDebugLevelScript, "         - get hand item number - PUSH result: '%d'", _vm->_itemInHand);
 				break;
 
 			default:
 				_stack[_stackIndex++] = itm->value;
+				debugC(5, kDebugLevelScript, "         - get hand item value (hand item number = '%d') - PUSH result: '%d'", _vm->_itemInHand, itm->value);
 				break;
 			}
 			break;
 
 		case 15:
 			_stack[_stackIndex++] = _vm->_levelBlockProperties[READ_LE_UINT16(pos + 1)].walls[pos[0]];
+			debugC(5, kDebugLevelScript, "         - get wall index for block '0x%.04X', direction '%d' - PUSH result: '%d'", READ_LE_UINT16(pos + 1), pos[0], _stack[_stackIndex - 1]);
 			pos += 3;
 			break;
 
 		case 19:
 			_stack[_stackIndex++] = _vm->_currentDirection;
+			debugC(5, kDebugLevelScript, "         - get current direction - PUSH result: '%d'", _vm->_currentDirection);
 			break;
 
 		case 21:
 			_stack[_stackIndex++] = (_flagTable[_vm->_currentLevel] & (1 << (*pos++))) ? 1 : 0;
+			debugC(5, kDebugLevelScript, "         - test level flag '%d' (current level = '%d') - PUSH result: '%d'", *(pos - 1), _vm->_currentLevel, _stack[_stackIndex - 1]);
 			break;
 
 		case 22:
 			_stack[_stackIndex++] = (_flagTable[17] & (1 << (*pos++))) ? 1 : 0;
+			debugC(5, kDebugLevelScript, "         - test global flag '%d' - PUSH result: '%d'", *(pos - 1), _stack[_stackIndex - 1]);
 			break;
 
 		case 23:
 			_stack[_stackIndex++] = (_vm->_currentBlock == READ_LE_UINT16(pos)) ? 1 : 0;
+			debugC(5, kDebugLevelScript, "         - compare current block with block '0x%.04X' (current block = '0x%.04X') - PUSH result: '%d'", _vm->_currentBlock, READ_LE_UINT16(pos), _stack[_stackIndex - 1]);
 			pos += 2;
 			break;
 
@@ -808,10 +831,12 @@ int EobInfProcessor::oeob_eval_v1(int8 *data) {
 			b = READ_LE_UINT16(pos);
 			pos += 2;
 			_stack[_stackIndex++] = _vm->countQueuedItems(_vm->_levelBlockProperties[b].drawObjects, a, -1, 0, 1);
+			debugC(5, kDebugLevelScript, "         - find item number '%d' on block '0x%.04X' - PUSH result: '%d'", a, b, _stack[_stackIndex - 1]);
 			break;
 
 		case 25:
 			_stack[_stackIndex++] = (_vm->_levelBlockProperties[READ_LE_UINT16(pos)].flags & 1) ? 1 : 0;
+			debugC(5, kDebugLevelScript, "         - test block flag '1' for block '0x%.04X' - PUSH result: '%d'", READ_LE_UINT16(pos), _stack[_stackIndex - 1]);
 			pos += 2;
 			break;
 
@@ -820,10 +845,12 @@ int EobInfProcessor::oeob_eval_v1(int8 *data) {
 			i = READ_LE_UINT16(pos);
 			pos += 2;
 			_stack[_stackIndex++] = _vm->countQueuedItems(_vm->_levelBlockProperties[i].drawObjects, -1, b, 1, 1);
+			debugC(5, kDebugLevelScript, "         - count items of type '%d' on block '0x%.04X' - PUSH result: '%d'", b, i, _stack[_stackIndex - 1]);
 			break;
 
 		case 29:
 			_stack[_stackIndex++] = _vm->_levelBlockProperties[READ_LE_UINT16(pos)].walls[0];
+			debugC(5, kDebugLevelScript, "         - get wall index 0 for block '0x%.04X' - PUSH result: '%d'", READ_LE_UINT16(pos), _stack[_stackIndex - 1]);
 			pos += 2;
 			break;
 
@@ -831,54 +858,63 @@ int EobInfProcessor::oeob_eval_v1(int8 *data) {
 			a = _stack[--_stackIndex];
 			b = _stack[--_stackIndex];
 			_stack[_stackIndex++] = (a || b) ? 1 : 0;
+			debugC(5, kDebugLevelScript, "         - evaluate: POP('%d') || POP('%d') - PUSH result: '%d'", a, b, _stack[_stackIndex - 1]);
 			break;
 
 		case 31:
 			a = _stack[--_stackIndex];
 			b = _stack[--_stackIndex];
 			_stack[_stackIndex++] = (a && b) ? 1 : 0;
+			debugC(5, kDebugLevelScript, "         - evaluate: POP('%d') && POP('%d') - PUSH result: '%d'", a, b, _stack[_stackIndex - 1]);
 			break;
 
 		case 32:
 			a = _stack[--_stackIndex];
 			b = _stack[--_stackIndex];
 			_stack[_stackIndex++] = (a <= b) ? 1 : 0;
+			debugC(5, kDebugLevelScript, "         - evaluate: POP('%d') <= POP('%d') - PUSH result: '%d'", a, b, _stack[_stackIndex - 1]);
 			break;
 
 		case 33:
 			a = _stack[--_stackIndex];
 			b = _stack[--_stackIndex];
 			_stack[_stackIndex++] = (a < b) ? 1 : 0;
+			debugC(5, kDebugLevelScript, "         - evaluate: POP('%d') < POP('%d') - PUSH result: '%d'", a, b, _stack[_stackIndex - 1]);
 			break;
 
 		case 34:
 			a = _stack[--_stackIndex];
 			b = _stack[--_stackIndex];
 			_stack[_stackIndex++] = (a >= b) ? 1 : 0;
+			debugC(5, kDebugLevelScript, "         - evaluate: POP('%d') >= POP('%d') - PUSH result: '%d'", a, b, _stack[_stackIndex - 1]);
 			break;
 
 		case 35:
 			a = _stack[--_stackIndex];
 			b = _stack[--_stackIndex];
 			_stack[_stackIndex++] = (a > b) ? 1 : 0;
+			debugC(5, kDebugLevelScript, "         - evaluate: POP('%d') > POP('%d') - PUSH result: '%d'", a, b, _stack[_stackIndex - 1]);
 			break;
 
 		case 36:
 			a = _stack[--_stackIndex];
 			b = _stack[--_stackIndex];
 			_stack[_stackIndex++] = (a != b) ? 1 : 0;
+			debugC(5, kDebugLevelScript, "         - evaluate: POP('%d') != POP('%d') - PUSH result: '%d'", a, b, _stack[_stackIndex - 1]);
 			break;
 
 		case 37:
 			a = _stack[--_stackIndex];
 			b = _stack[--_stackIndex];
 			_stack[_stackIndex++] = (a == b) ? 1 : 0;
+			debugC(5, kDebugLevelScript, "         - evaluate: POP('%d') == POP('%d') - PUSH result: '%d'", a, b, _stack[_stackIndex - 1]);
 			break;
 
 		default:
 			a = cmd;
 			if (a >= 0 && a < 128)
 				_stack[_stackIndex++] = a;
+			debugC(5, kDebugLevelScript, "         - PUSH value: '%d'", a);
 			break;
 		}
 		cmd = *pos++;
@@ -889,6 +925,7 @@ int EobInfProcessor::oeob_eval_v1(int8 *data) {
 		pos += 2;
 	else
 		pos = _scriptData + READ_LE_UINT16(pos);
+	debugC(5, kDebugLevelScript, "         - conditional jump depending on POP('%d')", cmd);
 
 	return pos - data;
 }
@@ -1005,7 +1042,7 @@ int EobInfProcessor::oeob_eval_v2(int8 *data) {
 			break;
 
 		case 18:
-			_stack[_stackIndex++] = _lastScriptSub;
+			_stack[_stackIndex++] = _lastScriptFlags;
 			break;
 
 		case 22:
@@ -1193,10 +1230,13 @@ int EobInfProcessor::oeob_eval_v2(int8 *data) {
 int EobInfProcessor::oeob_deleteItem(int8 *data) {
 	int8 *pos = data;
 	int8 c = *pos++;
+
 	if (c == -1) {
 		_vm->deleteInventoryItem(0, -1);
+		debugC(5, kDebugLevelScript, "         - delete hand item");
 	} else {
 		_vm->deleteBlockItem(READ_LE_UINT16(pos), (c == -2) ? -1 : c);
+		debugC(5, kDebugLevelScript, "         - delete item(s) of type '%d' on block '0x%.04X'", (c == -2) ? -1 : c, READ_LE_UINT16(pos));
 		pos += 2;
 	}
 
@@ -1239,6 +1279,7 @@ int EobInfProcessor::oeob_loadNewLevelOrMonsters(int8 *data) {
 		_screen->setScreenDim(7);
 
 		_vm->loadLevel(index, cmd);
+		debugC(5, kDebugLevelScript, "         - entering level '%d', sub level '%d', start block '0x%.04X', start direction '%d'", index, cmd, _vm->_currentBlock, _vm->_currentDirection);
 
 		if (_vm->_dialogueField)
 			_vm->restoreAfterDialogueSequence();
@@ -1256,6 +1297,7 @@ int EobInfProcessor::oeob_loadNewLevelOrMonsters(int8 *data) {
 		cmd = *pos++;
 		_vm->releaseMonsterShapes(cmd * 18, 18);
 		_vm->loadMonsterShapes((const char*)pos, cmd * 18, true, index * 18);
+		debugC(5, kDebugLevelScript, "         - loading monster shapes '%s', monster number '%d', encode type '%d'", (const char*)pos, cmd, index);
 		pos += 13;
 		_vm->gui_restorePlayField();
 		res = pos - data;
@@ -1268,6 +1310,7 @@ int EobInfProcessor::oeob_increasePartyExperience(int8 *data) {
 	int8 *pos = data;
 	if (*pos++ == -30) {
 		_vm->increasePartyExperience((int16)READ_LE_UINT16(pos));
+		debugC(5, kDebugLevelScript, "         - award '%d' experience points", READ_LE_UINT16(pos));
 		pos += 2;
 	}
 	return pos - data;
@@ -1282,10 +1325,13 @@ int EobInfProcessor::oeob_createItem_v1(int8 *data) {
 	uint8 itmPos = *pos++;
 
 	if (itm) {
-		if (block == 0xffff && !_vm->_itemInHand)
+		if (block == 0xffff && !_vm->_itemInHand) {
 			_vm->setHandItem(itm);
-		else if (block != 0xffff )
+			debugC(5, kDebugLevelScript, "         - create hand item '%d'", itm);
+		} else if (block != 0xffff) {
 			_vm->setItemPosition((Item*)&_vm->_levelBlockProperties[block & 0x3ff].drawObjects, block, itm, itmPos);
+			debugC(5, kDebugLevelScript, "         - create item '%d' on block '0x%.04X', position '%d'", itm, block, itmPos);
+		}
 	}
 
 	return pos - data;
@@ -1315,14 +1361,19 @@ int EobInfProcessor::oeob_createItem_v2(int8 *data) {
 		return pos - data;
 
 	if (block == 0xffff) {
-		if (!_vm->_itemInHand)
+		if (!_vm->_itemInHand) {
 			_vm->setHandItem(itm);
-		else
+			debugC(5, kDebugLevelScript, "         - create hand item '%d' (value '%d', flags '0x%X', icon number '%d')", itm, _vm->_items[itm].value, _vm->_items[itm].flags, _vm->_items[itm].icon);
+		} else {
 			_vm->setItemPosition((Item*)&_vm->_levelBlockProperties[_vm->_currentBlock & 0x3ff].drawObjects, _vm->_currentBlock, itm, _itemPos[_vm->rollDice(1, 2, -1)]);
+			debugC(5, kDebugLevelScript, "         - create item '%d' (value '%d', flags '0x%X', icon number '%d') on current block", itm, _vm->_items[itm].value, _vm->_items[itm].flags, _vm->_items[itm].icon);
+		}
 	} else if (block == 0xfffe) {
 		_vm->setItemPosition((Item*)&_vm->_levelBlockProperties[_vm->_currentBlock & 0x3ff].drawObjects, _vm->_currentBlock, itm, _itemPos[(_vm->_currentDirection << 2) + _vm->rollDice(1, 2, -1)]);
+		debugC(5, kDebugLevelScript, "         - create item '%d' (value '%d', flags '0x%X', icon number '%d') on current block", itm, _vm->_items[itm].value, _vm->_items[itm].flags, _vm->_items[itm].icon);
 	} else {
 		_vm->setItemPosition((Item*)&_vm->_levelBlockProperties[block & 0x3ff].drawObjects, block, itm, itmPos);
+		debugC(5, kDebugLevelScript, "         - create item '%d' (value '%d', flags '0x%X', icon number '%d') on block '0x%.04X', position '%d'", itm, _vm->_items[itm].value, _vm->_items[itm].flags, _vm->_items[itm].icon, block, itmPos);
 	}
 
 	return pos - data;
diff --git a/engines/kyra/script_eob.h b/engines/kyra/script_eob.h
index f7e5f09..8f883fd 100644
--- a/engines/kyra/script_eob.h
+++ b/engines/kyra/script_eob.h
@@ -40,7 +40,7 @@ public:
 	~EobInfProcessor();
 
 	void loadData(const uint8 *data, uint32 dataSize);
-	void run(int func, int sub);
+	void run(int func, int flags);
 
 	void setFlags(uint32 flags);
 	void clearFlags(uint32 flags);
@@ -107,7 +107,7 @@ private:
 	uint8 _preventRest;
 
 	uint16 _lastScriptFunc;
-	uint16 _lastScriptSub;
+	uint16 _lastScriptFlags;
 
 	int8 **_subroutineStack;
 	int _subroutineStackPos;
diff --git a/engines/kyra/sequences_eob1.cpp b/engines/kyra/sequences_eob1.cpp
index 4c5bd17..2ff4a3a 100644
--- a/engines/kyra/sequences_eob1.cpp
+++ b/engines/kyra/sequences_eob1.cpp
@@ -105,9 +105,8 @@ int EobEngine::mainMenuLoop() {
 
 void EobEngine::seq_playOpeningCredits() {
 	_allowSkip = true;
-	_screen->loadPalette(_introFilesOpening[5], _screen->getPalette(0));
-	_screen->setScreenPalette(_screen->getPalette(0));
 
+	loadSetIntroPalette(_introFilesOpening[5]);
 	_screen->loadBitmap(_introFilesOpening[4], 5, 3, 0);
 	_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
 	_screen->updateScreen();
@@ -135,7 +134,14 @@ void EobEngine::seq_playIntro() {
 		delay(120 * _tickLength);
 	}
 
-	_screen->loadBitmap("TEXT.CMP", 3, 6, 0);
+	Common::SeekableReadStream *s = _res->createReadStream("TEXT.RAW");
+	if (s) {
+		s->seek(768);
+		_screen->loadFileDataToPage(s, 6, s->size() - 768);
+		delete s;
+	} else {
+		_screen->loadBitmap("TEXT.CMP", 3, 6, 0);
+	}
 
 	seq_tower();
 	seq_orb();
@@ -194,8 +200,7 @@ void EobEngine::seq_playFinale() {
 void EobEngine::seq_tower() {
 	if (shouldQuit() || skipFlag())
 		return;
-
-	_screen->loadPalette(_introFilesTower[0], _screen->getPalette(0));
+	
 	_screen->loadBitmap(_introFilesTower[1], 5, 3, 0);
 	_screen->setCurPage(2);
 	uint8 *shp = _screen->encodeShape(0, 0, 16, 56, true);
@@ -208,7 +213,8 @@ void EobEngine::seq_tower() {
 	_screen->fillRect(0, 184, 319, 199, 12);
 	int cp = _screen->setCurPage(0);
 	whirlTransition();
-	_screen->setScreenPalette(_screen->getPalette(0));
+	loadSetIntroPalette(_introFilesTower[0]);
+
 	_screen->setCurPage(cp);
 	_screen->clearCurPage();
 
@@ -331,8 +337,7 @@ void EobEngine::seq_waterdeepEntry() {
 	uint8 *shp2[31];
 	uint8 *shp3[3];
 
-	_screen->loadPalette(_introFilesWdEntry[0], _screen->getPalette(0));
-	_screen->setScreenPalette(_screen->getPalette(0));
+	loadSetIntroPalette(_introFilesWdEntry[0]);
 	_screen->loadBitmap(_introFilesWdEntry[1], 5, 3, 0);
 	_screen->setCurPage(2);
 	shp[3] = _screen->encodeShape(0, 0, 20, 136, true);
@@ -712,8 +717,7 @@ void EobEngine::seq_waterdeepExit() {
 	_screen->fillRect(0, 168, 319, 199, 12, 0);
 	_screen->copyRegion(0, 136, 0, 0, 48, 36, 0, 4, Screen::CR_NO_P_CHECK);
 
-	_screen->loadPalette(_introFilesWdExit[1], _screen->getPalette(0));
-	_screen->setScreenPalette(_screen->getPalette(0));
+	loadSetIntroPalette(_introFilesWdExit[1]);
 	_screen->loadBitmap(_introFilesWdExit[2], 3, 5, 0);
 	_screen->copyPage(5, 2);
 	whirlTransition();
@@ -762,8 +766,7 @@ void EobEngine::seq_waterdeepExit() {
 	_screen->fillRect(0, 16, 319, 31, 12);
 	_screen->fillRect(0, 136, 319, 199, 12);
 	_screen->copyRegion(0, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
-	_screen->loadPalette(_introFilesWdExit[4], _screen->getPalette(0));
-	_screen->setScreenPalette(_screen->getPalette(0));
+	loadSetIntroPalette(_introFilesWdExit[4]);
 	_screen->updateScreen();
 	delay(50 * _tickLength);
 }
@@ -916,6 +919,15 @@ void EobEngine::seq_xdeath() {
 	for (int i = 0; i < 4; i++)
 		delete[] shapes1[i];
 	delete[] shapes2;
+
+	gui_drawPlayField(false);
+	gui_drawAllCharPortraitsWithStats();
+}
+
+void EobEngine::loadSetIntroPalette(const char *filename) {
+	_screen->loadPalette(filename, _screen->getPalette(0));
+	_screen->getPalette(0).fill(0, 1, 0);
+	_screen->setScreenPalette(_screen->getPalette(0));
 }
 
 void EobEngine::copyBlurRegion(int x1, int y1, int x2, int y2, int w, int h, int step) {
diff --git a/engines/kyra/sequences_eob2.cpp b/engines/kyra/sequences_eob2.cpp
index 37aca45..58540fd 100644
--- a/engines/kyra/sequences_eob2.cpp
+++ b/engines/kyra/sequences_eob2.cpp
@@ -169,11 +169,10 @@ void DarkMoonEngine::seq_playIntro() {
 	_screen->setCurPage(0);
 	_screen->clearCurPage();
 
-	_sound->playTrack(0);
+	snd_stopSound();
 
 	sq.loadScene(4, 2);
 	sq.loadScene(0, 2);
-
 	sq.delay(1);
 
 	if (!skipFlag() && !shouldQuit())
@@ -469,8 +468,7 @@ void DarkMoonEngine::seq_playFinale() {
 	_screen->setFont(Screen::FID_8_FNT);
 
 	_sound->loadSoundFile("FINALE1");
-	_sound->playTrack(0);
-
+	snd_stopSound();
 	sq.delay(3);
 
 	_screen->clearCurPage();
@@ -741,7 +739,7 @@ void DarkMoonEngine::seq_playFinale() {
 
 	sq.loadScene(10, 2);
 	sq.loadScene(9, 2);
-	_sound->playTrack(0);
+	snd_stopSound();
 	sq.delay(3);
 
 	_sound->loadSoundFile("FINALE2");
@@ -780,7 +778,7 @@ void DarkMoonEngine::seq_playFinale() {
 	while (!skipFlag() && !shouldQuit())
 		delay(_tickLength);
 
-	_sound->playTrack(0);
+	snd_stopSound();
 	sq.fadePalette(9, 10);
 }
 
diff --git a/engines/kyra/sound_lol.cpp b/engines/kyra/sound_lol.cpp
index 6bf047f..a37ec9f 100644
--- a/engines/kyra/sound_lol.cpp
+++ b/engines/kyra/sound_lol.cpp
@@ -167,8 +167,8 @@ void LoLEngine::snd_playSoundEffect(int track, int volume) {
 	volume &= 0xff;
 	int16 volIndex = (int16)READ_LE_UINT16(&_ingameSoundIndex[track * 2 + 1]);
 
-	volume = (volIndex > 0) ? (volIndex * volume) >> 8 : -volIndex;
-	volume = CLIP(volume >> 4, 2, 13) * 7 + 164;
+	uint16 vocLevel = (volIndex > 0) ? (volIndex * volume) >> 8 : -volIndex;
+	vocLevel = CLIP(volume >> 4, 2, 13) * 7 + 164;
 
 	int16 vocIndex = (int16)READ_LE_UINT16(&_ingameSoundIndex[track * 2]);
 
@@ -180,7 +180,7 @@ void LoLEngine::snd_playSoundEffect(int track, int volume) {
 
 	if (hasVocFile) {
 		if (_sound->isVoicePresent(_ingameSoundList[vocIndex]))
-			_sound->voicePlay(_ingameSoundList[vocIndex], 0, volume & 0xff, true);
+			_sound->voicePlay(_ingameSoundList[vocIndex], 0, vocLevel & 0xff, true);
 	} else if (_flags.platform == Common::kPlatformPC) {
 		if (_sound->getSfxType() == Sound::kMidiMT32)
 			track = (track < _ingameMT32SoundIndexSize) ? (_ingameMT32SoundIndex[track] - 1) : -1;
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index eca0530..2dc9405 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -438,7 +438,7 @@ void EobCoreEngine::drawBlockItems(int index) {
 			}
 
 			int8 scaleSteps = (int8)_dscItemScaleIndex[(_dscDimMap[index] << 2) + ps];
-			if (flg & 8 && ps < 2 && scaleSteps) {
+			if ((flg & 8) && ps < 2 && scaleSteps) {
 				tile2 = _dscItemTileIndex[index];
 				if (tile2 != -1)
 					setLevelShapesDim(tile2, _shpDmX1, _shpDmX2, 5);
@@ -447,7 +447,7 @@ void EobCoreEngine::drawBlockItems(int index) {
 
 			if (scaleSteps >= 0) {
 				const uint8 *shp = _screen->scaleShape(_dscItemShapeMap[itm->icon] < _numLargeItemShapes ? _largeItemShapes[_dscItemShapeMap[itm->icon]] : (_dscItemShapeMap[itm->icon] < 15 ? 0 : _smallItemShapes[_dscItemShapeMap[itm->icon] - 15]), scaleSteps);
-				x = x + itemPosFin[o & 7] - (shp[2] << 2);
+				x = x + (itemPosFin[o & 7] << 1) - ((shp[2] << 3) >> 1);
 				y -= shp[1];
 
 				if (itm->pos != 8)
diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp
index 277e04e..3b56b79 100644
--- a/engines/kyra/timer_eob.cpp
+++ b/engines/kyra/timer_eob.cpp
@@ -304,6 +304,10 @@ void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
 			continue;
 		}
 
+		int od = _screen->curDimIndex();
+		Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+		_screen->setScreenDim(7);
+
 		switch (evt) {
 		case 2:
 		case 3:
@@ -363,7 +367,10 @@ void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
 		default:
 			break;
 		}
-	}
+
+		_screen->setScreenDim(od);
+		_screen->setFont(of);
+	}	
 
 	uint32 nextTimer = 0xffffffff;
 	for (int i = 0; i < 10; i++) {


Commit: 68ed8b95989d784fe42f4e6e400224ffb63ba80b
    https://github.com/scummvm/scummvm/commit/68ed8b95989d784fe42f4e6e400224ffb63ba80b
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:15-08:00

Commit Message:
KYRA: (EOB) - fix some valgrind warnings

Changed paths:
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/lol.cpp
    engines/kyra/lol.h
    engines/kyra/loleobbase.cpp
    engines/kyra/scene_eob.cpp
    engines/kyra/scene_lol.cpp
    engines/kyra/screen.cpp
    engines/kyra/screen_eob.cpp
    engines/kyra/script_tim.cpp
    engines/kyra/sequences_eob2.cpp



diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 802907e..3bc145a 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -183,7 +183,7 @@ EobCoreEngine::~EobCoreEngine() {
 	delete[] _itemTypes;
 	if (_itemNames) {
 		for (int i = 0; i < 130; i++)
-			delete _itemNames[i];
+			delete[] _itemNames[i];
 	}
 	delete[] _itemNames;
 	delete[] _flyingObjects;
@@ -218,6 +218,9 @@ EobCoreEngine::~EobCoreEngine() {
 
 	delete _gui;
 	_gui = 0;
+	delete _screen;
+	_screen = 0;
+
 	delete[] _menuDefs;
 	_menuDefs = 0;
 
@@ -227,6 +230,8 @@ EobCoreEngine::~EobCoreEngine() {
 	_timer = 0;
 	delete _debugger;
 	_debugger = 0;
+	delete _txt;
+	_txt = 0;
 }
 
 Common::Error EobCoreEngine::init() {
@@ -672,6 +677,8 @@ void EobCoreEngine::releaseItemsAndDecorationsShapes() {
 		delete []_firebeamShapes;
 	}
 
+	delete[] _redSplatShape;
+	delete[] _greenSplatShape;
 	delete[] _deadCharShape;
 	delete[] _disabledCharGrid;
 	delete[] _blackBoxSmallGrid;
@@ -1214,18 +1221,15 @@ void EobCoreEngine::setWeaponSlotStatus(int charIndex, int mode, int slot) {
 	gui_drawCharPortraitWithStats(charIndex);
 }
 
-void EobCoreEngine::setupDialogueButtons(int presetfirst, int numStr, const char *str1, ...) {
+void EobCoreEngine::setupDialogueButtons(int presetfirst, int numStr, const char *str1, va_list &args) {
 	_dialogueNumButtons = numStr;
 	_dialogueButtonString[0] = str1;
 	_dialogueHighlightedButton = 0;
 
-	va_list args;
-	va_start(args, str1);
-	const char **sp = va_arg(args, const char**);
-	va_end(args);
 	for (int i = 1; i < numStr; i++) {
-		if (sp[i - 1])
-			_dialogueButtonString[i] = sp[i - 1];
+		const char *tmp = va_arg(args, const char*);
+		if (tmp)
+			_dialogueButtonString[i] = tmp;
 		else
 			_dialogueNumButtons = numStr = i;
 	}
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index fcfc29f..800716c 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -757,7 +757,7 @@ protected:
 	bool _configHpBarGraphs;
 
 	// text
-	void setupDialogueButtons(int presetfirst, int numStr, const char *str1, ...);
+	void setupDialogueButtons(int presetfirst, int numStr, const char *str1, va_list &args);
 	void initDialogueSequence();
 	void restoreAfterDialogueSequence();
 	void drawSequenceBitmap(const char *file, int destRect, int x1, int y1, int flags);
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 030b1de..a8dfeb5 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -225,6 +225,8 @@ LoLEngine::~LoLEngine() {
 	_gui = 0;
 	delete _tim;
 	_tim = 0;
+	delete _txt;
+	_txt = 0;
 
 	delete[] _itemsInPlay;
 	delete[] _itemProperties;
@@ -298,6 +300,8 @@ LoLEngine::~LoLEngine() {
 		_doorShapes[i] = 0;
 	}
 
+	releaseDecorations();
+
 	delete[] _automapShapes;
 
 	for (Common::Array<const TIMOpcode*>::iterator i = _timIntroOpcodes.begin(); i != _timIntroOpcodes.end(); ++i)
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index e75d621..ae3408e 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -915,6 +915,7 @@ private:
 	void assignBlockObject(LevelBlockProperty *l, uint16 item);
 	int assignLevelDecorationShapes(int index);
 	uint8 *getLevelDecorationShapes(int index);
+	void releaseDecorations(int first = 0, int num = 400);
 	void restoreTempDataAdjustMonsterStrength(int index);
 	void loadBlockProperties(const char *cmzFile);
 	const uint8 *getBlockFileData(int levelIndex);
diff --git a/engines/kyra/loleobbase.cpp b/engines/kyra/loleobbase.cpp
index c2ec8da..bcab278 100644
--- a/engines/kyra/loleobbase.cpp
+++ b/engines/kyra/loleobbase.cpp
@@ -149,9 +149,6 @@ LolEobBaseEngine::~LolEobBaseEngine() {
 	delete[] _levelDecorationData;
 	delete[] _levelDecorationProperties;
 	delete[] _levelBlockProperties;
-
-	delete _txt;
-	_txt = 0;
 }
 
 Common::Error LolEobBaseEngine::init() {
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index cf20429..ce0cdf8 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -1092,18 +1092,22 @@ void EobCoreEngine::drawSceneShapes(int start) {
 }
 
 void EobCoreEngine::drawDecorations(int index) {
-	static const int16 *dscWalls[] =  { 0, 0, &_sceneDrawVarDown, &_sceneDrawVarRight, &_sceneDrawVarDown,
-		&_sceneDrawVarRight, &_sceneDrawVarDown, 0, &_sceneDrawVarDown, &_sceneDrawVarLeft, &_sceneDrawVarDown,
-		&_sceneDrawVarLeft,	0, 0, &_sceneDrawVarDown, &_sceneDrawVarRight, &_sceneDrawVarDown, &_sceneDrawVarRight,
-		&_sceneDrawVarDown,	0, &_sceneDrawVarDown, &_sceneDrawVarLeft, &_sceneDrawVarDown, &_sceneDrawVarLeft,
-		&_sceneDrawVarDown,	&_sceneDrawVarRight, &_sceneDrawVarDown, 0, &_sceneDrawVarDown, &_sceneDrawVarLeft,
-		0, &_sceneDrawVarRight,	&_sceneDrawVarDown, 0, 0, &_sceneDrawVarLeft
+	static const int16 *dscWalls[] =  { 
+		0,					0,						&_sceneDrawVarDown, &_sceneDrawVarRight,
+		&_sceneDrawVarDown,	&_sceneDrawVarRight,	&_sceneDrawVarDown, 0,
+		&_sceneDrawVarDown, &_sceneDrawVarLeft,		&_sceneDrawVarDown,	&_sceneDrawVarLeft,
+		0,					0,						&_sceneDrawVarDown, &_sceneDrawVarRight,
+		&_sceneDrawVarDown, &_sceneDrawVarRight,	&_sceneDrawVarDown,	0,
+		&_sceneDrawVarDown, &_sceneDrawVarLeft,		&_sceneDrawVarDown, &_sceneDrawVarLeft,
+		&_sceneDrawVarDown,	&_sceneDrawVarRight,	&_sceneDrawVarDown, 0,
+		&_sceneDrawVarDown, &_sceneDrawVarLeft,		0,					&_sceneDrawVarRight,
+		&_sceneDrawVarDown, 0,						0,					&_sceneDrawVarLeft
 	};
 
 	for (int i = 1; i >= 0; i--) {
 		int s = index * 2 + i;
 		if (dscWalls[s]) {
-			int d = *dscWalls[s];
+			int16 d = *dscWalls[s];
 			int8 l = _wllShapeMap[_visibleBlocks[index]->walls[d]];
 
 			uint8 *shapeData = 0;
diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp
index d28477b..e38e5eb 100644
--- a/engines/kyra/scene_lol.cpp
+++ b/engines/kyra/scene_lol.cpp
@@ -200,6 +200,7 @@ int LoLEngine::assignLevelDecorationShapes(int index) {
 		if (pv) {
 			_levelDecorationProperties[o].shapeIndex[i] = pv;
 		} else {
+			releaseDecorations(_lvlShapeIndex, 1);
 			_levelDecorationShapes[_lvlShapeIndex] = getLevelDecorationShapes(t);
 			p1[t] = _lvlShapeIndex;
 			_levelDecorationProperties[o].shapeIndex[i] = _lvlShapeIndex++;
@@ -232,6 +233,13 @@ uint8 *LoLEngine::getLevelDecorationShapes(int shapeIndex) {
 	return res;
 }
 
+void LoLEngine::releaseDecorations(int first, int num) {
+	for (int i = first; i < (first + num); i++) {
+		delete[] _levelDecorationShapes[i];
+		_levelDecorationShapes[i] = 0;
+	}
+}
+
 void LoLEngine::loadBlockProperties(const char *cmzFile) {
 	memset(_levelBlockProperties, 0, 1024 * sizeof(LevelBlockProperty));
 	_screen->loadBitmap(cmzFile, 2, 2, 0);
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index 79edfe9..f9a49e7 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -848,7 +848,8 @@ void Screen::copyRegionToBuffer(int pageNum, int x, int y, int w, int h, uint8 *
 void Screen::copyPage(uint8 srcPage, uint8 dstPage) {
 	uint8 *src = getPagePtr(srcPage);
 	uint8 *dst = getPagePtr(dstPage);
-	memcpy(dst, src, SCREEN_W * SCREEN_H);
+	if (src != dst)
+		memcpy(dst, src, SCREEN_W * SCREEN_H);
 	copyOverlayRegion(0, 0, 0, 0, SCREEN_W, SCREEN_H, srcPage, dstPage);
 
 	if (dstPage == 0 || dstPage == 1)
diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp
index 4161c75..8562e25 100644
--- a/engines/kyra/screen_eob.cpp
+++ b/engines/kyra/screen_eob.cpp
@@ -46,6 +46,7 @@ Screen_Eob::Screen_Eob(EobCoreEngine *vm, OSystem *system) : Screen(vm, system)
 	_gfxCol = 0;
 	_customDimTable = 0;
 	_dsTempPage = 0;
+	_curDimIndex = 0;
 }
 
 Screen_Eob::~Screen_Eob() {
@@ -266,7 +267,7 @@ uint8 *Screen_Eob::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4b
 		uint8 *colorMap = new uint8[0x100];
 		memset (colorMap, 0xff, 0x100);
 
-		shapesize = h * (w << 2) + 0x14;
+		shapesize = h * (w << 2) + 20;
 		shp = new uint8[shapesize];
 		memset (shp, 0, shapesize);
 		uint8 *dst = shp;
@@ -673,14 +674,13 @@ const uint8 *Screen_Eob::scaleShapeStep(const uint8 *shp) {
 		i = -i;
 
 	_dsScaleTmp = (i << 4) | (i & 0x0f);
-	memcpy(d, shp, 16);
-	d += 16;
-	shp += 16;
+	for (int ii = 0; ii < 16; ii++)
+		*d++ = *shp++;
 
 	_dsDiv = w2 / 3;
 	_dsRem = w2 % 3;
 
-	do {
+	while (--h) {
 		scaleShapeProcessLine(d, shp);
 		if (!--h)
 			break;
@@ -688,7 +688,7 @@ const uint8 *Screen_Eob::scaleShapeStep(const uint8 *shp) {
 		if (!--h)
 			break;
 		shp += w2;
-	} while (--h);
+	}
 
 	return (const uint8 *) _dsTempPage;
 }
@@ -1100,15 +1100,14 @@ void Screen_Eob::drawShapeSetPixel(uint8 * dst, uint8 c) {
 void Screen_Eob::scaleShapeProcessLine(uint8 *&dst, const uint8 *&src) {
 	for (int i = 0; i < _dsDiv; i++) {
 		*dst++ = *src++;
-		*dst++ = READ_BE_UINT16(src) >> 4;
+		*dst++ = (READ_BE_UINT16(src) >> 4) & 0xff;
 		src += 2;
 	}
 
 	if (_dsRem == 1) {
 		*dst++ = *src++;
 		*dst++ = _dsScaleTmp;
-
-	} if (_dsRem == 2) {
+	} else if (_dsRem == 2) {
 		*dst++ = (src[0] & 0xf0) | (src[1] >> 4);
 		src += 2;
 		*dst++ = _dsScaleTmp;
diff --git a/engines/kyra/script_tim.cpp b/engines/kyra/script_tim.cpp
index 75977fc..7995ad2 100644
--- a/engines/kyra/script_tim.cpp
+++ b/engines/kyra/script_tim.cpp
@@ -893,6 +893,7 @@ TIMInterpreter_LoL::TIMInterpreter_LoL(LoLEngine *engine, Screen_v2 *screen_v2,
 
 	_screen = engine->_screen;
 
+	delete _animator;
 	_animator = new TimAnimator(engine, screen_v2, system, true);
 
 	_drawPage2 = 0;
diff --git a/engines/kyra/sequences_eob2.cpp b/engines/kyra/sequences_eob2.cpp
index 58540fd..597d84d 100644
--- a/engines/kyra/sequences_eob2.cpp
+++ b/engines/kyra/sequences_eob2.cpp
@@ -951,7 +951,7 @@ DarkmoonSequenceHelper::~DarkmoonSequenceHelper() {
 	delete _palettes[11];
 
 	for (int i = 0; i < 30; i++)
-		delete _shapes[i];
+		delete[] _shapes[i];
 	delete[] _shapes;
 
 	_screen->clearCurPage();


Commit: ac1aa43ca8b2ad9f2743006a5e40a7967a40fec5
    https://github.com/scummvm/scummvm/commit/ac1aa43ca8b2ad9f2743006a5e40a7967a40fec5
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:15-08:00

Commit Message:
KYRA: (EOB) - fix char generator regression + cleanup

Changed paths:
    engines/kyra/chargen.cpp
    engines/kyra/text_eob.cpp
    engines/kyra/text_eob.h



diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index 0e38ffe..92d1b15 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -380,7 +380,7 @@ int CharacterGenerator::viewDeleteCharacter() {
 	int res = 0;
 	for (bool loop = true; loop && _characters[_activeBox].name[0] && !_vm->shouldQuit(); ) {
 		_vm->_gui->updateBoxFrameHighLight(_activeBox + 6);
-		int inputFlag =getInput(_vm->_activeButtons);
+		int inputFlag = getInput(_vm->_activeButtons);
 		int cbx = _activeBox;
 		_vm->removeInputTop();
 
@@ -517,7 +517,7 @@ int CharacterGenerator::classMenu(int raceSex) {
 
 	while (res == -1 && !_vm->shouldQuit()) {
 		updateMagicShapes();
-		int in = getInput(_vm->_activeButtons) & 0xff;
+		int in = getInput(0) & 0xff;
 		Common::Point mp = _vm->getMousePos();
 
 		if (in == _vm->_keyMap[Common::KEYCODE_ESCAPE] || _vm->_gui->_menuLastInFlags == _vm->_keyMap[Common::KEYCODE_ESCAPE] || _vm->_gui->_menuLastInFlags == _vm->_keyMap[Common::KEYCODE_b]) {
@@ -565,7 +565,7 @@ int CharacterGenerator::alignmentMenu(int cClass) {
 
 	while (res == -1 && !_vm->shouldQuit()) {
 		updateMagicShapes();
-		int in = getInput(_vm->_activeButtons) & 0xff;
+		int in = getInput(0) & 0xff;
 		Common::Point mp = _vm->getMousePos();
 
 		if (in == _vm->_keyMap[Common::KEYCODE_ESCAPE] || _vm->_gui->_menuLastInFlags == _vm->_keyMap[Common::KEYCODE_ESCAPE] || _vm->_gui->_menuLastInFlags == _vm->_keyMap[Common::KEYCODE_b]) {
diff --git a/engines/kyra/text_eob.cpp b/engines/kyra/text_eob.cpp
index 0fe01df..e4e9b37 100644
--- a/engines/kyra/text_eob.cpp
+++ b/engines/kyra/text_eob.cpp
@@ -55,6 +55,11 @@ TextDisplayer_Eob::TextDisplayer_Eob(LolEobBaseEngine *engine, Screen *sScreen)
 		_textDimData[i].column = d->unkE;
 	}
 
+	_table1 = new char[128];
+	memset(_table1, 0, 128);
+	_table2 = new char[16];
+	memset(_table2, 0, 16);
+
 	_waitButtonSpace = 0;
 }
 
@@ -62,6 +67,8 @@ TextDisplayer_Eob::~TextDisplayer_Eob() {
 	delete[] _dialogueBuffer;
 	delete[] _currentLine;
 	delete[] _textDimData;
+	delete[] _table1;
+	delete[] _table2;
 }
 
 void TextDisplayer_Eob::setupField(int dim, bool mode) {
@@ -257,6 +264,7 @@ char TextDisplayer_Eob::parseCommand() {
 }
 
 void TextDisplayer_Eob::readNextPara() {
+	char c = 0;
 	char d = 0;
 
 	if (_tempString2) {
@@ -275,12 +283,16 @@ void TextDisplayer_Eob::readNextPara() {
 			_tempString1 = 0;
 	}
 
-	if (d & 0x80) {
-		warning("TextDisplayer_Eob::readNextPara():");
+	if ((_vm->game() != GI_LOL) && (d & 0x80)) {		
+		d &= 0x7f;
+		c = d & 7;
+		d = (d & 0x78) >> 3;
+		c = _table1[(d << 3) + c];
+		d = _table2[d];
 	}
 
 	_ctrl[1] = d;
-	_ctrl[2] = 0;
+	_ctrl[2] = c;
 }
 
 void TextDisplayer_Eob::printLine(char *str) {
diff --git a/engines/kyra/text_eob.h b/engines/kyra/text_eob.h
index eb49574..9409ac4 100644
--- a/engines/kyra/text_eob.h
+++ b/engines/kyra/text_eob.h
@@ -103,6 +103,9 @@ protected:
 private:
 	LolEobBaseEngine *_vm;
 	Screen *_screen;
+
+	char *_table1;
+	char *_table2;
 };
 
 } // End of namespace Kyra


Commit: 1cbd56693086afa8ce93092c3638e1052e31a5d9
    https://github.com/scummvm/scummvm/commit/1cbd56693086afa8ce93092c3638e1052e31a5d9
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:15-08:00

Commit Message:
KYRA: (EOB) - fix invalid string access

(also fix several cpp-check warnings)

Changed paths:
    engines/kyra/chargen.cpp
    engines/kyra/eob1.cpp
    engines/kyra/eob1.h
    engines/kyra/eob2.cpp
    engines/kyra/eob2.h
    engines/kyra/eobcommon.cpp
    engines/kyra/gui.h
    engines/kyra/gui_eob.cpp
    engines/kyra/items_eob.cpp
    engines/kyra/magic_eob.cpp
    engines/kyra/saveload_eob.cpp
    engines/kyra/saveload_lol.cpp
    engines/kyra/screen.cpp
    engines/kyra/screen_eob.cpp
    engines/kyra/screen_lol.cpp
    engines/kyra/sprites_eob.cpp
    engines/kyra/staticres_eob.cpp
    engines/kyra/text_eob.cpp



diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index 92d1b15..5231093 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -1317,7 +1317,7 @@ void CharacterGenerator::finish() {
 	}
 
 	if (_chargenButtonLabels) {
-		for (int i = 0; i < 10; i++)
+		for (int i = 0; i < 17; i++)
 			delete[] _chargenButtonLabels[i];
 		delete[] _chargenButtonLabels;
 		_chargenButtonLabels = 0;
diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
index d67cda5..c345b47 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -31,6 +31,15 @@ namespace Kyra {
 EobEngine::EobEngine(OSystem *system, const GameFlags &flags) : EobCoreEngine(system, flags) {
 	_numSpells = 53;
 	_menuChoiceInit = 4;
+
+	_turnUndeadString = _introFilesOpening = _introFilesTower = _introFilesOrb = _introFilesWdEntry	= _introFilesKing = _introFilesHands = _introFilesWdExit =
+		_introFilesTunnel = _finBonusStrings = _npc11Strings = _npc12Strings = _npc21Strings = _npc22Strings = _npc31Strings = _npc32Strings = _npc4Strings	=
+		_npc5Strings = _npc6Strings	= _npc7Strings = 0;
+	_introOpeningFrmDelay = _introWdEncodeX	= _introWdEncodeY = _introWdEncodeWH = _npcShpData = _npcSubShpIndex1 = _npcSubShpIndex2 = _npcSubShpY = _introWdDsY =
+		_introTvlX1 = _introTvlY1 = _introTvlX2	= _introTvlY2 = _introTvlW = _introTvlH = _dscDoorScaleMult4 = _dscDoorScaleMult5 = _dscDoorScaleMult6 =
+		_dscDoorY3 = _dscDoorY4 = _dscDoorY5 = _dscDoorY6 = _dscDoorY7 = _doorShapeEncodeDefs = _doorSwitchShapeEncodeDefs = _doorSwitchCoords = 0;
+	_introWdDsX = 0;
+	_dscDoorCoordsExt = 0;
 }
 
 EobEngine::~EobEngine() {
@@ -558,34 +567,6 @@ void EobEngine::healParty() {
 	}
 }
 
-uint32 EobEngine::convertSpellFlagToEob2Format(uint32 flag, int ignoreInvisibility) {
-	uint32 res = 0;
-	if (flag & 0x01)
-		res |= 0x20;
-	if (flag & 0x02)
-		res |= 0x400;
-	if (flag & 0x04)
-		res |= 0x80;
-	if (flag & 0x08)
-		res |= 0x40;
-	if (ignoreInvisibility)
-		res |= 0x100;
-	return res;
-}
-
-uint32 EobEngine::convertCharacterEffectFlagToEob2Format(uint32 flag) {
-	uint32 res = 0;
-	if (flag & 0x02)
-		res |= 0x08;
-	if (flag & 0x04)
-		res |= 0x40;
-	if (flag & 0x80)
-		res |= 0x2000;
-	if (flag & 0x100)
-		res |= 0x4000;
-	return res;
-}
-
 }	// End of namespace Kyra
 
 #endif // ENABLE_EOB
diff --git a/engines/kyra/eob1.h b/engines/kyra/eob1.h
index 8811d7d..3eade85 100644
--- a/engines/kyra/eob1.h
+++ b/engines/kyra/eob1.h
@@ -149,9 +149,6 @@ private:
 	bool checkPartyStatusExtra();
 	int resurrectionSelectDialogue();
 	void healParty();
-
-	uint32 convertSpellFlagToEob2Format(uint32 flag, int ignoreInvisibility);
-	uint32 convertCharacterEffectFlagToEob2Format(uint32 flag);
 };
 
 
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index f309fae..afaef0b 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -34,6 +34,12 @@ DarkMoonEngine::DarkMoonEngine(OSystem *system, const GameFlags &flags) : EobCor
 	_dscDoorType5Offs = 0;
 	_numSpells = 70;
 	_menuChoiceInit = 4;
+
+	_introStrings = _cpsFilesIntro = _cpsFilesFinale = _finaleStrings = _kheldranStrings = _npc1Strings = _npc2Strings = _hornStrings = 0;
+	_seqIntro = _seqFinale = 0;
+	_shapesIntro = _shapesFinale = 0;
+	_creditsData = _npcShpData = _dscDoorType5Offs = _hornSounds = 0;
+	_dreamSteps = 0;
 }
 
 DarkMoonEngine::~DarkMoonEngine() {
diff --git a/engines/kyra/eob2.h b/engines/kyra/eob2.h
index 6da0901..8c9b6dd 100644
--- a/engines/kyra/eob2.h
+++ b/engines/kyra/eob2.h
@@ -72,12 +72,12 @@ private:
 	void seq_playFinale();
 	void seq_playCredits(DarkmoonSequenceHelper *sq, const uint8 *data, int sd, int backupPage, int tempPage, int speed);
 
-	const char * const*_introStrings;
+	const char * const *_introStrings;
 	const char * const *_cpsFilesIntro;
 	const EobSequenceStep **_seqIntro;
 	const EobShapeDef **_shapesIntro;
 
-	const char * const*_finaleStrings;
+	const char * const *_finaleStrings;
 	const uint8 *_creditsData;
 	const char * const *_cpsFilesFinale;
 	const EobSequenceStep **_seqFinale;
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 3bc145a..9e75be0 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -110,6 +110,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_color9 = 17;
 	_color10 = 23;
 	_color11 = 20;
+	_color4 = _color5 = _color6 = _color7 = _color8 = _color12 = _color13 = _color14 = 0;
 
 	_menuDefs = 0;
 
@@ -153,6 +154,48 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_rrCount = 0;
 	memset(_rrNames, 0, 10 * sizeof(const char*));
 	memset(_rrId, 0, 10 * sizeof(int8));
+
+	_mainMenuStrings = _levelGainStrings = _monsterSpecAttStrings = _characterGuiStringsHp = _characterGuiStringsWp = _characterGuiStringsWr = _characterGuiStringsSt =
+		_characterGuiStringsIn = _characterStatusStrings7 = _characterStatusStrings8 = _characterStatusStrings9 = _characterStatusStrings12 = _characterStatusStrings13 = 0;
+	_classModifierFlags = _constModLevelIndex = _constModDiv = _constModExt = _wandTypes = _drawObjPosIndex = _flightObjFlipIndex = _expObjectTblIndex =
+		_expObjectShpStart = _expObjectTlMode = _expObjectAnimTbl1 = _expObjectAnimTbl2 = _expObjectAnimTbl3 = 0;
+	_monsterStepTable0 = _monsterStepTable1 = _monsterStepTable2 = _monsterStepTable3 = _projectileWeaponAmmoTypes = _flightObjShpMap = _flightObjSclIndex = 0;
+	_monsterCloseAttPosTable1 = _monsterCloseAttPosTable2 = _monsterCloseAttChkTable1 = _monsterCloseAttChkTable2 = _monsterCloseAttDstTable1 = _monsterCloseAttDstTable2 = 0;
+	_monsterProximityTable = _findBlockMonstersTable = _wallOfForceDsY = _wallOfForceDsNumW = _wallOfForceDsNumH = _wallOfForceShpId = _wllFlagPreset = _teleporterShapeCoords = 0;
+		_monsterCloseAttUnkTable = _monsterFrmOffsTable1 = _monsterFrmOffsTable2 = _monsterDirChangeTable = _portalSeq = 0;
+	_wallOfForceDsX = 0;
+	_expObjectAnimTbl1Size = _expObjectAnimTbl2Size = _expObjectAnimTbl3Size = _wllFlagPresetSize = _scriptTimersCount = _buttonList1Size = _buttonList2Size = 
+		_buttonList3Size = _buttonList4Size = _buttonList5Size = _buttonList6Size = _buttonList7Size = _buttonList8Size = 0;
+	_inventorySlotsY = _mnDef = 0;
+	_buttonDefs = 0;
+	_npcPreset = 0;
+	_chargenStatStrings	= _chargenRaceSexStrings = _chargenClassStrings = _chargenAlignmentStrings = _pryDoorStrings = _warningStrings = _ripItemStrings =
+		_cursedString = _enchantedString = _magicObjectStrings = _magicObjectString5 = _patternSuffix = _patternGrFix1 = _patternGrFix2 = _validateArmorString =
+		_validateCursedString = _validateNoDropString = _potionStrings = _wandStrings = _itemMisuseStrings = _suffixStringsRings = _suffixStringsPotions =
+		_suffixStringsWands	= _takenStrings	= _potionEffectStrings = _yesNoStrings = _npcMaxStrings = _okStrings = _npcJoinStrings = _cancelStrings	=
+		_abortStrings = _saveLoadStrings = _mnWord = _mnPrompt = _bookNumbers = _mageSpellList = _clericSpellList = _spellNames = _magicStrings1 = _magicStrings2 =
+		_magicStrings3 = _magicStrings4 = _magicStrings6 = _magicStrings7 = _magicStrings8 = 0;
+	_spellAnimBuffer = 0;
+	_sparkEffectDefSteps = _sparkEffectDefSubSteps = _sparkEffectDefShift = _sparkEffectDefAdd = _sparkEffectDefX = _sparkEffectDefY = _sparkEffectOfShift =
+		_sparkEffectOfX	= _sparkEffectOfY = _magicFlightObjectProperties = _turnUndeadEffect = _burningHandsDest = _coneOfColdGfxTbl = 0;
+	_sparkEffectOfFlags1 = _sparkEffectOfFlags2 = 0;
+	_coneOfColdDest1 = _coneOfColdDest2 = _coneOfColdDest3 = _coneOfColdDest4 = 0;
+	_coneOfColdGfxTblSize = 0;
+	_menuButtonDefs = 0;
+	_menuStringsMain = _menuStringsSaveLoad	= _menuStringsOnOff	= _menuStringsSpells = _menuStringsRest	= _menuStringsDrop = _menuStringsExit = _menuStringsStarve =
+		_menuStringsScribe = _menuStringsDrop2 = _menuStringsHead = _menuStringsPoison = _menuStringsMgc = _menuStringsPrefs = _menuStringsRest2 = _menuStringsRest3 =
+		_menuStringsRest4 = _menuStringsDefeat = _menuStringsTransfer = _menuStringsSpec = _menuStringsSpellNo = _menuYesNoStrings = 0;
+	_errorSlotEmptyString = _errorSlotNoNameString = _menuOkString = 0;
+	_spellLevelsMage = _spellLevelsCleric = _numSpellsCleric = _numSpellsWisAdj	= _numSpellsPal	= _numSpellsMage = 0;
+	_mnNumWord = _numSpells = _mageSpellListSize = _spellLevelsMageSize = _spellLevelsClericSize = 0;
+	_inventorySlotsX = _slotValidationFlags = _encodeMonsterShpTable = 0;
+	memset(_expRequirementTables, 0, sizeof(_expRequirementTables));
+	memset(_constModTables, 0, sizeof(_constModTables));
+	memset(_doorType, 0, sizeof(_doorType));
+	memset(_noDoorSwitch, 0, sizeof(_noDoorSwitch));
+	memset(_scriptTimers, 0, sizeof(_scriptTimers));
+	memset(_monsterBlockPosArray, 0, sizeof(_monsterBlockPosArray));
+	memset(_foundMonstersArray, 0, sizeof(_foundMonstersArray));
 }
 
 EobCoreEngine::~EobCoreEngine() {
@@ -251,11 +294,10 @@ Common::Error EobCoreEngine::init() {
 
 	//MidiDriverType midiDriver = MidiDriver::detectDevice(MDT_PCSPK | MDT_ADLIB);
 	_sound = new SoundAdLibPC(this, _mixer);
-	_sound->init();
 	assert(_sound);
+	_sound->init();	
 
-	if (_sound)
-		_sound->updateVolumeSettings();
+	syncSoundSettings();
 
 	_res = new Resource(this);
 	assert(_res);
@@ -288,8 +330,6 @@ Common::Error EobCoreEngine::init() {
 	_screen->loadFont(Screen::FID_6_FNT, "FONT6.FNT");
 	_screen->loadFont(Screen::FID_8_FNT, "FONT8.FNT");
 
-	readSettings();
-
 	Common::Error err = LolEobBaseEngine::init();
 	if (err.getCode() != Common::kNoError)
 		return err;
@@ -365,6 +405,9 @@ Common::Error EobCoreEngine::init() {
 	memset(_monsterOvl2, 13, 16 * sizeof(uint8));
 	_monsterOvl1[0] = _monsterOvl2[0] = 0;
 
+	// Prevent autosave on game startup
+	_lastAutosave = _system->getMillis();
+
 	return Common::kNoError;
 }
 
@@ -701,7 +744,7 @@ void EobCoreEngine::setHandItem(Item itemIndex) {
 	const uint8 *shp = _itemIconShapes[icon];
 
 	if (icon && (_items[_itemInHand].flags & 0x80) && (_partyEffectFlags & 2)) {
-		memcpy(_tempIconShape, shp, 300);
+		memcpy(_tempIconShape, shp, shp[1] * shp[2] * 4 + 20);
 		if (_flags.gameID == GI_EOB1)
 			_screen->replaceShapePalette(_tempIconShape, &_itemsOverlay[icon << 4]);
 		else
@@ -1225,9 +1268,10 @@ void EobCoreEngine::setupDialogueButtons(int presetfirst, int numStr, const char
 	_dialogueNumButtons = numStr;
 	_dialogueButtonString[0] = str1;
 	_dialogueHighlightedButton = 0;
+	const char *tmp = 0;
 
 	for (int i = 1; i < numStr; i++) {
-		const char *tmp = va_arg(args, const char*);
+		tmp = va_arg(args, const char*);
 		if (tmp)
 			_dialogueButtonString[i] = tmp;
 		else
diff --git a/engines/kyra/gui.h b/engines/kyra/gui.h
index 4991707..2b32bf3 100644
--- a/engines/kyra/gui.h
+++ b/engines/kyra/gui.h
@@ -43,7 +43,7 @@ struct Button {
 	Button() : nextButton(0), index(0), keyCode(0), keyCode2(0), data0Val1(0), data1Val1(0), data2Val1(0), data3Val1(0), flags(0),
 	    data0ShapePtr(0), data1ShapePtr(0), data2ShapePtr(0), data0Callback(), data1Callback(), data2Callback(),
 	    dimTableIndex(0), x(0), y(0), width(0), height(0), data0Val2(0), data0Val3(0), data1Val2(0), data1Val3(0),
-	    data2Val2(0), data2Val3(0), data3Val2(0), data3Val3(0), flags2(0), mouseWheel(0), buttonCallback(), arg(0) {}
+	    data2Val2(0), data2Val3(0), data3Val2(0), data3Val3(0), flags2(0), mouseWheel(0), buttonCallback(), extButtonDef(0), arg(0) {}
 
 	Button *nextButton;
 	uint16 index;
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index d333528..af97d48 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -85,6 +85,7 @@ void LolEobBaseEngine::gui_drawHorizontalBarGraph(int x, int y, int w, int h, in
 }
 
 void LolEobBaseEngine::gui_initButtonsFromList(const int16 *list) {
+	return;
 	while (*list != -1)
 		gui_initButton(*list++);
 }
@@ -1480,7 +1481,7 @@ GUI_Eob::GUI_Eob(EobCoreEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) {
 GUI_Eob::~GUI_Eob() {
 	if (_menuStringsPrefsTemp) {
 		for (int i = 0; i < 4; i++)
-			delete _menuStringsPrefsTemp[i];
+			delete[] _menuStringsPrefsTemp[i];
 		delete[] _menuStringsPrefsTemp;
 	}
 
@@ -1600,6 +1601,7 @@ void GUI_Eob::processButton(Button *button) {
 }
 
 int GUI_Eob::processButtonList(Kyra::Button *buttonList, uint16 inputFlags, int8 mouseWheel) {
+	return 0;
 	_progress = 0;
 	uint16 in = inputFlags & 0xff;
 	uint16 buttonReleaseFlag = 0;
@@ -3897,7 +3899,7 @@ void GUI_Eob::memorizePrayMenuPrintString(int spellId, int bookPageIndex, int sp
 
 void GUI_Eob::updateOptionsStrings() {
 	for (int i = 0; i < 4; i++) {
-		delete _menuStringsPrefsTemp[i];
+		delete[] _menuStringsPrefsTemp[i];
 		_menuStringsPrefsTemp[i] = new char[strlen(_vm->_menuStringsPrefs[i]) + 8];
 	}
 
diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
index 96b19a9..44f3a7e 100644
--- a/engines/kyra/items_eob.cpp
+++ b/engines/kyra/items_eob.cpp
@@ -461,12 +461,18 @@ void EobCoreEngine::drawItemIconShape(int pageNum, Item itemId, int x, int y) {
 	int icn = _items[itemId].icon;
 	bool applyBluePal = ((_partyEffectFlags & 2) && (_items[itemId].flags & 0x80)) ? true : false;
 
+	memcpy(_tempIconShape, _itemIconShapes[icn], _itemIconShapes[icn][1] * _itemIconShapes[icn][2] * 4 + 20);
+
 	if (applyBluePal) {
-		_screen->setFadeTableIndex(3);
-		_screen->setShapeFadeMode(1, true);
+		if (_flags.gameID == GI_EOB1) {
+			_screen->replaceShapePalette(_tempIconShape, &_itemsOverlay[icn << 4]);
+		} else {
+			_screen->setFadeTableIndex(3);
+			_screen->setShapeFadeMode(1, true);
+		}
 	}
 
-	_screen->drawShape(pageNum, _itemIconShapes[icn], x, y, 0);
+	_screen->drawShape(pageNum, _tempIconShape, x, y, 0);
 
 	if (applyBluePal) {
 		_screen->setFadeTableIndex(4);
@@ -491,8 +497,8 @@ void EobCoreEngine::eatItemInHand(int charIndex) {
 	EobCharacter *c = &_characters[charIndex];
 	if (!testCharacter(charIndex, 5)) {
 		_txt->printMessage(_warningStrings[1], -1, c->name);
-	} else if (_itemInHand && _items[_itemInHand].type != 31) {
-		_txt->printMessage(_warningStrings[3]);
+	} else if (_itemInHand && _items[_itemInHand].type != 31 && !(_flags.gameID == GI_EOB1 && _items[_itemInHand].type == 49)) {
+		_txt->printMessage(_warningStrings[_flags.gameID == GI_EOB1 ? 2 : 3]);
 	} else if (_items[_itemInHand].value == -1) {
 		printWarning(_warningStrings[2]);
 	} else {
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 9063d51..b70058d 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -542,7 +542,7 @@ bool EobCoreEngine::magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int d
 			}
 		} else {
 			int c = _dscItemPosIndex[(_currentDirection << 2) + (fo->curPos & 3)];
-			if ((c > 2) && (testCharacter(5, 1) || testCharacter(6, 1)) && rollDice(1, 2, -1))
+			if ((c > 2) && (testCharacter(4, 1) || testCharacter(5, 1)) && rollDice(1, 2, -1))
 				c += 2;
 
 			if (!fo->item && (_characters[c].effectFlags & 8)) {
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index 07841be..ec89fca 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -39,6 +39,7 @@ void LolEobBaseEngine::generateTempData() {
 		delete[] _lvlTempData[l]->flags;
 		releaseMonsterTempData(_lvlTempData[l]);
 		releaseFlyingObjectTempData(_lvlTempData[l]);
+		releaseWallOfForceTempData(_lvlTempData[l]);
 		delete _lvlTempData[l];
 	}
 
@@ -280,6 +281,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 			delete[] _lvlTempData[i]->flags;
 			releaseMonsterTempData(_lvlTempData[i]);
 			releaseFlyingObjectTempData(_lvlTempData[i]);
+			releaseWallOfForceTempData(_lvlTempData[i]);
 			delete _lvlTempData[i];
 		}
 
diff --git a/engines/kyra/saveload_lol.cpp b/engines/kyra/saveload_lol.cpp
index 33097a8..e5977dd 100644
--- a/engines/kyra/saveload_lol.cpp
+++ b/engines/kyra/saveload_lol.cpp
@@ -187,6 +187,7 @@ Common::Error LoLEngine::loadGameState(int slot) {
 			delete[] _lvlTempData[i]->flags;
 			releaseMonsterTempData(_lvlTempData[i]);
 			releaseFlyingObjectTempData(_lvlTempData[i]);
+			releaseWallOfForceTempData(_lvlTempData[i]);
 			delete _lvlTempData[i];
 		}
 
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index f9a49e7..c0d05dc 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -51,6 +51,7 @@ Screen::Screen(KyraEngine_v1 *vm, OSystem *system)
 
 	_currentFont = FID_8_FNT;
 	_paletteChanged = true;
+	_curDim = 0;
 }
 
 Screen::~Screen() {
diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp
index 8562e25..0b877b7 100644
--- a/engines/kyra/screen_eob.cpp
+++ b/engines/kyra/screen_eob.cpp
@@ -47,10 +47,18 @@ Screen_Eob::Screen_Eob(EobCoreEngine *vm, OSystem *system) : Screen(vm, system)
 	_customDimTable = 0;
 	_dsTempPage = 0;
 	_curDimIndex = 0;
+	_dsDiv = 0;
+	_dsRem = 0;
+	_dsScaleTmp = 0;
+	_gfxMaxY = 0;
 }
 
 Screen_Eob::~Screen_Eob() {
 	delete[] _fadeData;
+	if (_customDimTable) {
+		for (int i = 0; i < _screenDimTableCount; i++)
+			delete _customDimTable[i];
+	}
 	delete[] _customDimTable;
 	delete[] _dsTempPage;
 }
@@ -58,7 +66,7 @@ Screen_Eob::~Screen_Eob() {
 bool Screen_Eob::init() {
 	if (Screen::init()) {
 		_customDimTable = new ScreenDim*[_screenDimTableCount];
-		memset(_customDimTable, 0, sizeof(ScreenDim *)* _screenDimTableCount);
+		memset(_customDimTable, 0, sizeof(ScreenDim*) * _screenDimTableCount);
 
 		int temp;
 		_gfxMaxY = _vm->staticres()->loadRawData(kEobBaseExpObjectY, temp);
diff --git a/engines/kyra/screen_lol.cpp b/engines/kyra/screen_lol.cpp
index 6d0460e..0f02165 100644
--- a/engines/kyra/screen_lol.cpp
+++ b/engines/kyra/screen_lol.cpp
@@ -42,8 +42,10 @@ Screen_LoL::Screen_LoL(LoLEngine *vm, OSystem *system) : Screen_v2(vm, system),
 	for (int i = 0; i < 8; i++)
 		_levelOverlays[i] = new uint8[256];
 
-	_fadeFlag = 2;
+	_screenDimTable = 0;
+	_customDimTable = 0;
 	_curDimIndex = 0;
+	_fadeFlag = 2;
 }
 
 Screen_LoL::~Screen_LoL() {
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index 2dc9405..6d8776f 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -657,13 +657,13 @@ void EobCoreEngine::drawFlyingObjects(int index) {
 				flipped = fo->direction == ((_currentDirection + 1) & 3) ? 1 : 0;
 			} else {
 				shp = (_flightObjShpMap[shpIx] + dirOffs) < _numThrownItemShapes ? _thrownItemShapes[_flightObjShpMap[shpIx] + dirOffs] : _spellShapes[_flightObjShpMap[shpIx - _numThrownItemShapes] + dirOffs];
-				flipped = _flightObjFlipIndex[(fo->direction << 2) + fo->curPos];
+				flipped = _flightObjFlipIndex[(fo->direction << 2) + (fo->curPos & 3)];
 			}
 
 		} else {
 			rstFade = true;
 			shp = (fo->objectType < _numThrownItemShapes) ? _thrownItemShapes[fo->objectType] : _spellShapes[fo->objectType - _numThrownItemShapes];
-			flipped = _flightObjFlipIndex[(fo->direction << 2) + fo->curPos];
+			flipped = _flightObjFlipIndex[(fo->direction << 2) + (fo->curPos & 3)];
 
 			if (fo->flags & 0x40) {
 				x = _dscShapeCoords[(index * 5 + 4) << 1] + 88;
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 4ff879c..6f7dfc1 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -1230,7 +1230,7 @@ void EobEngine::initSpells() {
 	for (int i = 0; i < _numSpells; i++) {
 		EobSpell *s = &_spells[i];
 		src += 4;
-		s->flags = flagTable[i].typeFlag;/*convertSpellFlagToEob2Format(src[0], src[14]);*/
+		s->flags = flagTable[i].typeFlag;
 		s->damageFlags = flagTable[i].damageFlag;
 		s->effectFlags = flagTable[i].effectFlag;
 		s->sound = src[13];
diff --git a/engines/kyra/text_eob.cpp b/engines/kyra/text_eob.cpp
index e4e9b37..1c0c7e5 100644
--- a/engines/kyra/text_eob.cpp
+++ b/engines/kyra/text_eob.cpp
@@ -287,8 +287,9 @@ void TextDisplayer_Eob::readNextPara() {
 		d &= 0x7f;
 		c = d & 7;
 		d = (d & 0x78) >> 3;
-		c = _table1[(d << 3) + c];
-		d = _table2[d];
+		uint8 l = d;
+		c = _table1[(l << 3) + c];
+		d = _table2[l];
 	}
 
 	_ctrl[1] = d;


Commit: 532f8f33f2dad8c0292c41301926becc5198a83e
    https://github.com/scummvm/scummvm/commit/532f8f33f2dad8c0292c41301926becc5198a83e
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:15-08:00

Commit Message:
KYRA: (EOB) - fix mem leak

Changed paths:
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/lol.h
    engines/kyra/loleobbase.cpp
    engines/kyra/loleobbase.h
    engines/kyra/staticres_eob.cpp



diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 800716c..795b017 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -71,7 +71,6 @@ struct EobGuiButtonDef {
 	uint8 y;
 	uint16 w;
 	uint8 h;
-	Button::Callback buttonCallback;
 	uint16 arg;
 };
 
@@ -738,6 +737,7 @@ protected:
 	int _buttonList8Size;
 
 	const EobGuiButtonDef *_buttonDefs;
+
 	const char *const *_characterGuiStringsHp;
 	const char *const *_characterGuiStringsWp;
 	const char *const *_characterGuiStringsWr;
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index af97d48..4ced205 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -85,7 +85,6 @@ void LolEobBaseEngine::gui_drawHorizontalBarGraph(int x, int y, int w, int h, in
 }
 
 void LolEobBaseEngine::gui_initButtonsFromList(const int16 *list) {
-	return;
 	while (*list != -1)
 		gui_initButton(*list++);
 }
@@ -808,13 +807,17 @@ void EobCoreEngine::gui_initButton(int index, int, int, int) {
 	b->index = index + 1;
 
 	const EobGuiButtonDef *d = &_buttonDefs[index];
+	b->buttonCallback = _buttonCallbacks[index];
 
 	if (_flags.gameID == GI_EOB1) {
 		// EOB1 spellbook modifications
-		if (index > 60 && index < 66)
+		if (index > 60 && index < 66) {
 			d = &_buttonDefs[index + 33];
-		if (index == 88)
+			b->buttonCallback = _buttonCallbacks[index + 33];
+		} else if (index == 88) {
 			d = &_buttonDefs[index + 12];
+			b->buttonCallback = _buttonCallbacks[index + 12];
+		}
 	}
 
 	b->x = d->x;
@@ -830,7 +833,6 @@ void EobCoreEngine::gui_initButton(int index, int, int, int) {
 	b->keyCode = d->keyCode;
 	b->keyCode2 = d->keyCode2;
 	b->arg = d->arg;
-	b->buttonCallback = d->buttonCallback;
 }
 
 int EobCoreEngine::clickedCharPortraitDefault(Button *button) {
@@ -1437,8 +1439,6 @@ void EobCoreEngine::gui_processInventorySlotClick(int slot) {
 }
 
 GUI_Eob::GUI_Eob(EobCoreEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) {
-	//_scrollUpFunctor = _scrollDownFunctor = BUTTON_FUNCTOR(GUI_Eob, this, 0);
-
 	_menuStringsPrefsTemp = new char*[4];
 	memset(_menuStringsPrefsTemp, 0, 4 * sizeof(char*));
 
@@ -1601,7 +1601,6 @@ void GUI_Eob::processButton(Button *button) {
 }
 
 int GUI_Eob::processButtonList(Kyra::Button *buttonList, uint16 inputFlags, int8 mouseWheel) {
-	return 0;
 	_progress = 0;
 	uint16 in = inputFlags & 0xff;
 	uint16 buttonReleaseFlag = 0;
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index ae3408e..7bd6768 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -561,7 +561,6 @@ private:
 	int clickedLamp(Button *button);
 	int clickedStatusIcon(Button *button);
 
-	Common::Array<Button::Callback> _buttonCallbacks;
 	const LoLButtonDef *_buttonData;
 	const int16 *_buttonList1;
 	const int16 *_buttonList2;
diff --git a/engines/kyra/loleobbase.cpp b/engines/kyra/loleobbase.cpp
index bcab278..3db7537 100644
--- a/engines/kyra/loleobbase.cpp
+++ b/engines/kyra/loleobbase.cpp
@@ -149,6 +149,10 @@ LolEobBaseEngine::~LolEobBaseEngine() {
 	delete[] _levelDecorationData;
 	delete[] _levelDecorationProperties;
 	delete[] _levelBlockProperties;
+
+	for (Common::Array<Button::Callback>::iterator i = _buttonCallbacks.begin(); i != _buttonCallbacks.end(); ++i)
+		i->reset();
+	_buttonCallbacks.clear();
 }
 
 Common::Error LolEobBaseEngine::init() {
diff --git a/engines/kyra/loleobbase.h b/engines/kyra/loleobbase.h
index cb7f920..06d0688 100644
--- a/engines/kyra/loleobbase.h
+++ b/engines/kyra/loleobbase.h
@@ -256,6 +256,7 @@ protected:
 
 	Button *_activeButtons;
 	Button _activeButtonData[70];
+	Common::Array<Button::Callback> _buttonCallbacks;
 	//bool _processingButtons;
 
 	uint8 _mouseClick;
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 6f7dfc1..e90fea5 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -570,114 +570,170 @@ void EobCoreEngine::initStaticResource() {
 }
 
 void EobCoreEngine::initButtonData() {
-	#define EOB_CB(x)	BUTTON_FUNCTOR(EobCoreEngine, this, &EobCoreEngine::x)
 	static const EobGuiButtonDef buttonDefs[] = {
-		{ 112, 0, 0x1100, 184, 2, 63, 50, EOB_CB(clickedCharPortraitDefault), 0 },
-		{ 113, 0, 0x1100, 256, 2, 63, 50, EOB_CB(clickedCharPortraitDefault), 1 },
-		{ 114, 0, 0x1100, 184, 54, 63, 50, EOB_CB(clickedCharPortraitDefault), 2 },
-		{ 115, 0, 0x1100, 256, 54, 63, 50, EOB_CB(clickedCharPortraitDefault), 3 },
-		{ 48, 110, 0x1100, 289, 177, 31, 21, EOB_CB(clickedCamp), 0 },
-		{ 0, 0, 0x1100, 0, 102, 88, 18, EOB_CB(clickedSceneDropPickupItem), 0 },
-		{ 0, 0, 0x1100, 89, 102, 88, 18, EOB_CB(clickedSceneDropPickupItem), 1 },
-		{ 0, 0, 0x1100, 0, 72, 88, 29, EOB_CB(clickedSceneDropPickupItem), 2 },
-		{ 0, 0, 0x1100, 89, 72, 88, 29, EOB_CB(clickedSceneDropPickupItem), 3 },
-		{ 24, 0, 0x1100, 184, 10, 33, 33, EOB_CB(clickedCharPortrait2), 0 },
-		{ 0, 0, 0x1100, 256, 10, 33, 33, EOB_CB(clickedCharPortrait2), 1 },
-		{ 0, 0, 0x1100, 184, 62, 33, 33, EOB_CB(clickedCharPortrait2), 2 },
-		{ 0, 0, 0x1100, 256, 62, 33, 33, EOB_CB(clickedCharPortrait2), 3 },
-		{ 0, 0, 0x1100, 216, 10, 31, 33, EOB_CB(clickedWeaponSlot), 0 },
-		{ 0, 0, 0x1100, 288, 10, 31, 33, EOB_CB(clickedWeaponSlot), 1 },
-		{ 0, 0, 0x1100, 216, 62, 31, 33, EOB_CB(clickedWeaponSlot), 2 },
-		{ 0, 0, 0x1100, 288, 62, 31, 33, EOB_CB(clickedWeaponSlot), 3 },
-		{ 368, 0, 0x1000, 184, 2, 63, 8, EOB_CB(clickedCharNameLabelRight), 0 },
-		{ 369, 0, 0x1000, 256, 2, 63, 8, EOB_CB(clickedCharNameLabelRight), 1 },
-		{ 370, 0, 0x1000, 184, 54, 63, 8, EOB_CB(clickedCharNameLabelRight), 2 },
-		{ 371, 0, 0x1000, 256, 54, 63, 8, EOB_CB(clickedCharNameLabelRight), 3 },
-		{ 0, 0, 0x1100, 230, 116, 16, 16, EOB_CB(clickedInventorySlot), 0 },
-		{ 0, 0, 0x1100, 278, 116, 16, 16, EOB_CB(clickedInventorySlot), 1 },
-		{ 0, 0, 0x1100, 181, 40, 16, 16, EOB_CB(clickedInventorySlot), 2 },
-		{ 0, 0, 0x1100, 199, 40, 16, 16, EOB_CB(clickedInventorySlot), 3 },
-		{ 0, 0, 0x1100, 181, 58, 16, 16, EOB_CB(clickedInventorySlot), 4 },
-		{ 0, 0, 0x1100, 199, 58, 16, 16, EOB_CB(clickedInventorySlot), 5 },
-		{ 0, 0, 0x1100, 181, 76, 16, 16, EOB_CB(clickedInventorySlot), 6 },
-		{ 0, 0, 0x1100, 199, 76, 16, 16, EOB_CB(clickedInventorySlot), 7 },
-		{ 0, 0, 0x1100, 181, 94, 16, 16, EOB_CB(clickedInventorySlot), 8 },
-		{ 0, 0, 0x1100, 199, 94, 16, 16, EOB_CB(clickedInventorySlot), 9 },
-		{ 0, 0, 0x1100, 181, 112, 16, 16, EOB_CB(clickedInventorySlot), 10 },
-		{ 0, 0, 0x1100, 199, 112, 16, 16, EOB_CB(clickedInventorySlot), 11 },
-		{ 0, 0, 0x1100, 181, 130, 16, 16, EOB_CB(clickedInventorySlot), 12 },
-		{ 0, 0, 0x1100, 199, 130, 16, 16, EOB_CB(clickedInventorySlot), 13 },
-		{ 0, 0, 0x1100, 181, 148, 16, 16, EOB_CB(clickedInventorySlot), 14 },
-		{ 0, 0, 0x1100, 199, 148, 16, 16, EOB_CB(clickedInventorySlot), 15 },
-		{ 0, 0, 0x1100, 225, 55, 16, 16, EOB_CB(clickedInventorySlot), 16 },
-		{ 0, 0, 0x1100, 224, 76, 16, 16, EOB_CB(clickedInventorySlot), 17 },
-		{ 0, 0, 0x1100, 225, 96, 16, 16, EOB_CB(clickedInventorySlot), 18 },
-		{ 0, 0, 0x1100, 298, 55, 16, 16, EOB_CB(clickedInventorySlot), 19 },
-		{ 0, 0, 0x1100, 287, 75, 16, 16, EOB_CB(clickedInventorySlot), 20 },
-		{ 0, 0, 0x1100, 277, 137, 16, 16, EOB_CB(clickedInventorySlot), 21 },
-		{ 0, 0, 0x1100, 300, 94, 16, 16, EOB_CB(clickedInventorySlot), 22 },
-		{ 0, 0, 0x1100, 300, 112, 16, 16, EOB_CB(clickedInventorySlot), 23 },
-		{ 0, 0, 0x1100, 300, 130, 16, 16, EOB_CB(clickedInventorySlot), 24 },
-		{ 0, 0, 0x1100, 236, 37, 31, 16, EOB_CB(clickedEatItem), 25 },
-		{ 26, 0, 0x1100, 291, 149, 25, 17, EOB_CB(clickedInventoryNextPage), 25 },
-		{ 110, 24, 0x1100, 181, 3, 32, 32, EOB_CB(clickedPortraitRestore), 25 },
-		{ 96, 352, 0x1100, 24, 128, 21, 16, EOB_CB(clickedUpArrow), 25 },
-		{ 98, 97, 0x1100, 24, 144, 21, 16, EOB_CB(clickedDownArrow), 25 },
-		{ 92, 348, 0x1100, 3, 144, 21, 16, EOB_CB(clickedLeftArrow), 25 },
-		{ 102, 358, 0x1100, 45, 144, 21, 16, EOB_CB(clickedRightArrow), 25 },
-		{ 91, 0, 0x1100, 3, 128, 21, 16, EOB_CB(clickedTurnLeftArrow), 25 },
-		{ 101, 0, 0x1100, 45, 128, 21, 16, EOB_CB(clickedTurnRightArrow), 25 },
-		{ 110, 0, 0x1100, 184, 0, 136, 120, EOB_CB(clickedAbortCharSwitch), 0 },
-		{ 0, 0, 0x1100, 0, 8, 88, 48, EOB_CB(clickedSceneThrowItem), 0 },
-		{ 0, 0, 0x1100, 88, 8, 88, 48, EOB_CB(clickedSceneThrowItem), 1 },
-		{ 0, 0, 0x1100, 24, 8, 128, 96, EOB_CB(clickedSceneSpecial), 1 },
-		{ 112, 113, 0x1100, 274, 35, 20, 15, EOB_CB(clickedInventoryPrevChar), 1 },
-		{ 114, 115, 0x1100, 297, 35, 20, 15, EOB_CB(clickedInventoryNextChar), 1 },
-		{ 2, 0, 0x1100, 68, 121, 18, 10, EOB_CB(clickedSpellbookTab), 0 },
-		{ 3, 0, 0x1100, 86, 121, 18, 10, EOB_CB(clickedSpellbookTab), 1 },
-		{ 4, 0, 0x1100, 104, 121, 15, 10, EOB_CB(clickedSpellbookTab), 2 },
-		{ 5, 0, 0x1100, 122, 121, 15, 10, EOB_CB(clickedSpellbookTab), 3 },
-		{ 6, 0, 0x1100, 140, 121, 15, 10, EOB_CB(clickedSpellbookTab), 4 },
-		{ 0, 0, 0x1100, 75, 131, 97, 6, EOB_CB(clickedSpellbookList), 0 },
-		{ 0, 0, 0x1100, 75, 137, 97, 6, EOB_CB(clickedSpellbookList), 1 },
-		{ 0, 0, 0x1100, 75, 143, 97, 6, EOB_CB(clickedSpellbookList), 2 },
-		{ 0, 0, 0x1100, 75, 149, 97, 6, EOB_CB(clickedSpellbookList), 3 },
-		{ 0, 0, 0x1100, 75, 155, 97, 6, EOB_CB(clickedSpellbookList), 4 },
-		{ 0, 0, 0x1100, 75, 161, 97, 6, EOB_CB(clickedSpellbookList), 5 },
-		{ 112, 0, 0x1100, 184, 2, 63, 50, EOB_CB(clickedCastSpellOnCharacter), 0 },
-		{ 113, 0, 0x1100, 256, 2, 63, 50, EOB_CB(clickedCastSpellOnCharacter), 1 },
-		{ 114, 0, 0x1100, 184, 54, 63, 50, EOB_CB(clickedCastSpellOnCharacter), 2 },
-		{ 115, 0, 0x1100, 256, 54, 63, 50, EOB_CB(clickedCastSpellOnCharacter), 3 },
-		{ 53, 54, 0x1100, 320, 200, 0, 0, EOB_CB(clickedSpellbookList), 6 },
-		{ 61, 0, 0x1100, 320, 200, 0, 0, EOB_CB(clickedSpellbookList), 7 },
-		{ 0, 0, 0x1100, 184, 114, 33, 33, EOB_CB(clickedCharPortrait2), 4 },
-		{ 0, 0, 0x1100, 256, 114, 33, 33, EOB_CB(clickedCharPortrait2), 5 },
-		{ 0, 0, 0x1100, 216, 114, 31, 33, EOB_CB(clickedWeaponSlot), 4 },
-		{ 0, 0, 0x1100, 288, 114, 31, 33, EOB_CB(clickedWeaponSlot), 5 },
-		{ 372, 0, 0x1000, 184, 106, 63, 8, EOB_CB(clickedCharNameLabelRight), 4 },
-		{ 373, 0, 0x1000, 256, 106, 63, 8, EOB_CB(clickedCharNameLabelRight), 5 },
-		{ 0, 0, 0x1100, 227, 135, 10, 10, EOB_CB(clickedInventorySlot), 25 },
-		{ 0, 0, 0x1100, 239, 135, 10, 10, EOB_CB(clickedInventorySlot), 26 },
-		{ 116, 0, 0x1100, 184, 106, 63, 50, EOB_CB(clickedCastSpellOnCharacter), 4 },
-		{ 117, 0, 0x1100, 256, 106, 63, 50, EOB_CB(clickedCastSpellOnCharacter), 5 },
-		{ 110, 0, 0x1100, 68, 168, 78, 10, EOB_CB(clickedSpellbookAbort), 0 },
-		{ 110, 0, 0x1100, 68, 168, 78, 10, EOB_CB(clickedCastSpellOnCharacter), 65535 },
-		{ 116, 0, 0x1100, 184, 106, 63, 50, EOB_CB(clickedCharPortraitDefault), 4 },
-		{ 117, 0, 0x1100, 256, 106, 63, 50, EOB_CB(clickedCharPortraitDefault), 5 },
-		{ 116, 117, 0x1100, 320, 200, 1, 1, EOB_CB(clickedInventoryNextChar), 2 },
-		{ 7, 0, 0x1100, 158, 121, 15, 10, EOB_CB(clickedSpellbookTab), 5 },
-		{ 0, 0, 0x1100, 146, 168, 32, 10, EOB_CB(clickedSpellbookScroll), 0 },
+		{ 112, 0, 0x1100, 184, 2, 63, 50, 0 },
+		{ 113, 0, 0x1100, 256, 2, 63, 50, 1 },
+		{ 114, 0, 0x1100, 184, 54, 63, 50, 2 },
+		{ 115, 0, 0x1100, 256, 54, 63, 50, 3 },
+		{ 48, 110, 0x1100, 289, 177, 31, 21, 0 },
+		{ 0, 0, 0x1100, 0, 102, 88, 18, 0 },
+		{ 0, 0, 0x1100, 89, 102, 88, 18, 1 },
+		{ 0, 0, 0x1100, 0, 72, 88, 29, 2 },
+		{ 0, 0, 0x1100, 89, 72, 88, 29, 3 },
+		{ 24, 0, 0x1100, 184, 10, 33, 33, 0 },
+		{ 0, 0, 0x1100, 256, 10, 33, 33, 1 },
+		{ 0, 0, 0x1100, 184, 62, 33, 33, 2 },
+		{ 0, 0, 0x1100, 256, 62, 33, 33, 3 },
+		{ 0, 0, 0x1100, 216, 10, 31, 33, 0 },
+		{ 0, 0, 0x1100, 288, 10, 31, 33, 1 },
+		{ 0, 0, 0x1100, 216, 62, 31, 33, 2 },
+		{ 0, 0, 0x1100, 288, 62, 31, 33, 3 },
+		{ 368, 0, 0x1000, 184, 2, 63, 8, 0 },
+		{ 369, 0, 0x1000, 256, 2, 63, 8, 1 },
+		{ 370, 0, 0x1000, 184, 54, 63, 8, 2 },		
+		{ 371, 0, 0x1000, 256, 54, 63, 8, 3 },
+		{ 0, 0, 0x1100, 230, 116, 16, 16, 0 },
+		{ 0, 0, 0x1100, 278, 116, 16, 16, 1 },
+		{ 0, 0, 0x1100, 181, 40, 16, 16, 2 },
+		{ 0, 0, 0x1100, 199, 40, 16, 16, 3 },
+		{ 0, 0, 0x1100, 181, 58, 16, 16, 4 },
+		{ 0, 0, 0x1100, 199, 58, 16, 16, 5 },
+		{ 0, 0, 0x1100, 181, 76, 16, 16, 6 },
+		{ 0, 0, 0x1100, 199, 76, 16, 16, 7 },
+		{ 0, 0, 0x1100, 181, 94, 16, 16, 8 },		
+		{ 0, 0, 0x1100, 199, 94, 16, 16, 9 },
+		{ 0, 0, 0x1100, 181, 112, 16, 16, 10 },
+		{ 0, 0, 0x1100, 199, 112, 16, 16, 11 },
+		{ 0, 0, 0x1100, 181, 130, 16, 16, 12 },
+		{ 0, 0, 0x1100, 199, 130, 16, 16, 13 },
+		{ 0, 0, 0x1100, 181, 148, 16, 16, 14 },
+		{ 0, 0, 0x1100, 199, 148, 16, 16, 15 },
+		{ 0, 0, 0x1100, 225, 55, 16, 16, 16 },
+		{ 0, 0, 0x1100, 224, 76, 16, 16, 17 },
+		{ 0, 0, 0x1100, 225, 96, 16, 16, 18 },
+		{ 0, 0, 0x1100, 298, 55, 16, 16, 19 },
+		{ 0, 0, 0x1100, 287, 75, 16, 16, 20 },
+		{ 0, 0, 0x1100, 277, 137, 16, 16, 21 },
+		{ 0, 0, 0x1100, 300, 94, 16, 16, 22 },
+		{ 0, 0, 0x1100, 300, 112, 16, 16, 23 },
+		{ 0, 0, 0x1100, 300, 130, 16, 16, 24 },
+		{ 0, 0, 0x1100, 236, 37, 31, 16, 25 },
+		{ 26, 0, 0x1100, 291, 149, 25, 17, 25 },
+		{ 110, 24, 0x1100, 181, 3, 32, 32, 25 },
+		{ 96, 352, 0x1100, 24, 128, 21, 16, 25 },
+		{ 98, 97, 0x1100, 24, 144, 21, 16, 25 },
+		{ 92, 348, 0x1100, 3, 144, 21, 16, 25 },
+		{ 102, 358, 0x1100, 45, 144, 21, 16, 25 },
+		{ 91, 0, 0x1100, 3, 128, 21, 16, 25 },
+		{ 101, 0, 0x1100, 45, 128, 21, 16, 25 },
+		{ 110, 0, 0x1100, 184, 0, 136, 120, 0 },
+		{ 0, 0, 0x1100, 0, 8, 88, 48, 0 },
+		{ 0, 0, 0x1100, 88, 8, 88, 48, 1 },
+		{ 0, 0, 0x1100, 24, 8, 128, 96, 1 },
+		{ 112, 113, 0x1100, 274, 35, 20, 15, 1 },
+		{ 114, 115, 0x1100, 297, 35, 20, 15, 1 },
+		{ 2, 0, 0x1100, 68, 121, 18, 10, 0 },
+		{ 3, 0, 0x1100, 86, 121, 18, 10, 1 },
+		{ 4, 0, 0x1100, 104, 121, 15, 10, 2 },
+		{ 5, 0, 0x1100, 122, 121, 15, 10, 3 },
+		{ 6, 0, 0x1100, 140, 121, 15, 10, 4 },
+		{ 0, 0, 0x1100, 75, 131, 97, 6, 0 },
+		{ 0, 0, 0x1100, 75, 137, 97, 6, 1 },
+		{ 0, 0, 0x1100, 75, 143, 97, 6, 2 },
+		{ 0, 0, 0x1100, 75, 149, 97, 6, 3 },
+		{ 0, 0, 0x1100, 75, 155, 97, 6, 4 },
+		{ 0, 0, 0x1100, 75, 161, 97, 6, 5 },
+		{ 112, 0, 0x1100, 184, 2, 63, 50, 0 },
+		{ 113, 0, 0x1100, 256, 2, 63, 50, 1 },
+		{ 114, 0, 0x1100, 184, 54, 63, 50, 2 },
+		{ 115, 0, 0x1100, 256, 54, 63, 50, 3 },
+		{ 53, 54, 0x1100, 320, 200, 0, 0, 6 },
+		{ 61, 0, 0x1100, 320, 200, 0, 0, 7 },
+		{ 0, 0, 0x1100, 184, 114, 33, 33, 4 },
+		{ 0, 0, 0x1100, 256, 114, 33, 33, 5 },
+		{ 0, 0, 0x1100, 216, 114, 31, 33, 4 },
+		{ 0, 0, 0x1100, 288, 114, 31, 33, 5 },
+		{ 372, 0, 0x1000, 184, 106, 63, 8, 4 },
+		{ 373, 0, 0x1000, 256, 106, 63, 8, 5 },
+		{ 0, 0, 0x1100, 227, 135, 10, 10, 25 },
+		{ 0, 0, 0x1100, 239, 135, 10, 10, 26 },
+		{ 116, 0, 0x1100, 184, 106, 63, 50, 4 },
+		{ 117, 0, 0x1100, 256, 106, 63, 50, 5 },
+		{ 110, 0, 0x1100, 68, 168, 78, 10, 0 },
+		{ 110, 0, 0x1100, 68, 168, 78, 10, 65535 },
+		{ 116, 0, 0x1100, 184, 106, 63, 50, 4 },
+		{ 117, 0, 0x1100, 256, 106, 63, 50, 5 },
+		{ 116, 117, 0x1100, 320, 200, 1, 1, 2 },
+		{ 7, 0, 0x1100, 158, 121, 15, 10, 5 },
+		{ 0, 0, 0x1100, 146, 168, 32, 10, 0 },
 
 		// EOB1 spellbook modifications
-		{ 2, 0, 0x1100, 71, 122, 20, 8, EOB_CB(clickedSpellbookTab), 0 },
-		{ 3, 0, 0x1100, 92, 122, 20, 8, EOB_CB(clickedSpellbookTab), 1 },
-		{ 4, 0, 0x1100, 113, 122, 20, 8, EOB_CB(clickedSpellbookTab), 2 },
-		{ 5, 0, 0x1100, 134, 122, 20, 8, EOB_CB(clickedSpellbookTab), 3 },
-		{ 6, 0, 0x1100, 155, 122, 20, 8, EOB_CB(clickedSpellbookTab), 4 },
-		{ 110, 0, 0x1100, 75, 168, 97, 6, EOB_CB(clickedSpellbookAbort), 0 }
+		{ 2, 0, 0x1100, 71, 122, 20, 8, 0 },
+		{ 3, 0, 0x1100, 92, 122, 20, 8, 1 },
+		{ 4, 0, 0x1100, 113, 122, 20, 8, 2 },
+		{ 5, 0, 0x1100, 134, 122, 20, 8, 3 },
+		{ 6, 0, 0x1100, 155, 122, 20, 8, 4 },
+		{ 110, 0, 0x1100, 75, 168, 97, 6, 0 }
 	};
 
 	_buttonDefs = buttonDefs;
+	_buttonCallbacks.clear();
+	_buttonCallbacks.reserve(ARRAYSIZE(buttonDefs));
+
+#define EOB_CBN(x) _buttonCallbacks.push_back(BUTTON_FUNCTOR(EobCoreEngine, this, &EobCoreEngine::x))
+#define EOB_CBR(x) for (int l = x; l; l--) { _buttonCallbacks.push_back(_buttonCallbacks[_buttonCallbacks.size() - 1]); }
+#define EOB_CBI(x, y) for (int l = x; l; l--) { _buttonCallbacks.push_back(_buttonCallbacks[y]); }
+	EOB_CBN(clickedCharPortraitDefault);
+	EOB_CBR(3);
+	EOB_CBN(clickedCamp);
+	EOB_CBN(clickedSceneDropPickupItem);
+	EOB_CBR(3);
+	EOB_CBN(clickedCharPortrait2);
+	EOB_CBR(3);
+	EOB_CBN(clickedWeaponSlot);
+	EOB_CBR(3);
+	EOB_CBN(clickedCharNameLabelRight);
+	EOB_CBR(3);
+	EOB_CBN(clickedInventorySlot);
+	EOB_CBR(24);
+	EOB_CBN(clickedEatItem);
+	EOB_CBN(clickedInventoryNextPage);
+	EOB_CBN(clickedPortraitRestore);
+	EOB_CBN(clickedUpArrow);
+	EOB_CBN(clickedDownArrow);
+	EOB_CBN(clickedLeftArrow);
+	EOB_CBN(clickedRightArrow);
+	EOB_CBN(clickedTurnLeftArrow);
+	EOB_CBN(clickedTurnRightArrow);
+	EOB_CBN(clickedAbortCharSwitch);
+	EOB_CBN(clickedSceneThrowItem);
+	EOB_CBR(1);
+	EOB_CBN(clickedSceneSpecial);
+	EOB_CBN(clickedInventoryPrevChar);
+	EOB_CBN(clickedInventoryNextChar);
+	EOB_CBN(clickedSpellbookTab);
+	EOB_CBR(4);
+	EOB_CBN(clickedSpellbookList);
+	EOB_CBR(5);
+	EOB_CBN(clickedCastSpellOnCharacter);
+	EOB_CBR(3);
+	EOB_CBI(2, 66);
+	EOB_CBI(2, 9);
+	EOB_CBI(2, 13);
+	EOB_CBI(2, 17);
+	EOB_CBI(2, 21);
+	EOB_CBI(2, 72);
+	EOB_CBN(clickedSpellbookAbort);
+	EOB_CBI(1, 72);
+	EOB_CBI(2, 0);
+	EOB_CBI(1, 60);
+	EOB_CBI(1, 61);
+	EOB_CBN(clickedSpellbookScroll);
+	EOB_CBI(5, 61);
+	EOB_CBI(1, 88);
+#undef EOB_CBI
+#undef EOB_CBR
+#undef EOB_CBN
 }
 
 void EobCoreEngine::initMenus() {
@@ -788,19 +844,19 @@ void EobCoreEngine::initSpells() {
 	mpn;
 	mp(0);	// Detect Magic
 	mpn;	// Magic Missile
-	mp1n;						///
+	mp1n;
 	mp(1);	// Shield
 	mp(2);	// Shocking Grasp
-	mp2(3);	// Blur				///
-	mp2(1);	// Detect Invis		///
-	mp2n;	// Imp Identify		///
+	mp2(3);	// Blur
+	mp2(1);	// Detect Invis
+	mp2n;	// Imp Identify
 	mpn;	// Invis
-	mp1n;						///
+	mp1n;
 	mpn;	// Melf
-	mp1n;	// Stinking Cloud	///
+	mp1n;	// Stinking Cloud
 	mpn;	// Dispel Magic
 	mpn;	// Fireball
-	mp1n;	// Flame Arrow		///
+	mp1n;	// Flame Arrow
 	mp(3);	// Haste
 	mpn;	// Hold Person
 	mpn;	// Invisibility
@@ -809,23 +865,23 @@ void EobCoreEngine::initSpells() {
 	mpn;	// Fear
 	mpn;	// Ice Storm
 	mp1n;	// Stone Skin
-	mp1n;	// Cloud Kill		///
-	mp2(4);	// Improved Invisibility	///
-	mp2n;	// remove Curse		///
+	mp1n;	// Cloud Kill
+	mp2(4);	// Improved Invisibility
+	mp2n;	// remove Curse
 	mpn;	// Cone of Cold
 	mpn;	// Hold Monster
-	mp2n;	// Wall of Force	///
-	mp2n;	// Disintegrate		///
-	mp2n;	// Flesh To Stone	///
-	mp2n;	// Stone To Flesh	///
-	mp2(2);	// True Seeing		///
-	mp2n;	// Finger of Death	///
-	mp2n;	// Power Word Stun	///
-	mp2n;	// Bigby's Fist		///
-	mp2n;	// empty			///
+	mp2n;	// Wall of Force
+	mp2n;	// Disintegrate
+	mp2n;	// Flesh To Stone
+	mp2n;	// Stone To Flesh
+	mp2(2);	// True Seeing
+	mp2n;	// Finger of Death
+	mp2n;	// Power Word Stun
+	mp2n;	// Bigby's Fist
+	mp2n;	// empty
 	mp(5);	// Bless
-	mpn;						/// EOB1: cure, EOB2: cause
-	mpn;						/// EOB1: cause, EOB2: cure
+	mpn;						// EOB1: cure, EOB2: cause
+	mpn;						// EOB1: cause, EOB2: cure
 	mp(0);	// Detect Magic
 	mp(6);	// Prot from Evil
 	mp(7);	// Aid
@@ -837,25 +893,25 @@ void EobCoreEngine::initSpells() {
 	mp(1);	// Magical Vestment
 	mp(2);	// Prayer
 	mpn;	// Remove Paralysis
-	mpn;						/// EOB1: cure, EOB2: cause
-	mpn;						/// EOB1: cause, EOB2: cure
+	mpn;						// EOB1: cure, EOB2: cause
+	mpn;						// EOB1: cause, EOB2: cure
 	mpn;	// Neutral Poison
 	mp(6);	// Prot From Evil 10'
-	mp1n;	// Prot From Lightning			/// --- para required?
-	mpn;						/// EOB1: cure, EOB2: cause
-	mpn;						/// EOB1: cause, EOB2: cure
+	mp1n;	// Prot From Lightning
+	mpn;						// EOB1: cure, EOB2: cause
+	mpn;						// EOB1: cause, EOB2: cure
 	mpn;	// Flame Strike
 	mpn;	// Raise Dead
-	mp2n;	// Slay Living		///
-	mp2(2);	// True Seeing		///
-	mp2n;	// Harm				///
-	mp2n;	// Heal				///
-	mp2n;	// Resurrect		///
+	mp2n;	// Slay Living
+	mp2(2);	// True Seeing
+	mp2n;	// Harm
+	mp2n;	// Heal
+	mp2n;	// Resurrect
 	mpn;	// Lay on Hands
-	mp2n;	// Turn Undead		///
-	mpn;	// UNK 1 passive
-	mp2(10);// Mystic Defense	///
-	mp2n;	// UNK 2 passive	///
+	mp2n;	// Turn Undead
+	mpn;	// Lightning Bolt (EOB1) / Fireball 1(EOB2) passive
+	mp2(10);// Mystic Defense
+	mp2n;	// Fireball 2 passive
 	mpn;	// death spell passive
 	mpn;	// disintegrate passive
 	mp2n;	// cause critical passive
@@ -921,7 +977,7 @@ void EobCoreEngine::initSpells() {
 	sc1(causeSeriousWounds);
 	sc(neutralizePoison);
 	sc(empty);
-	sc1(empty);	// Prot from Lightning
+	sc1(empty);
 	sc2(causeCriticalWounds);
 	sc(cureCriticalWounds);
 	sc1(causeCriticalWounds);


Commit: 812ea181b86aab153592c16bceea6a32b39b3cf4
    https://github.com/scummvm/scummvm/commit/812ea181b86aab153592c16bceea6a32b39b3cf4
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:15-08:00

Commit Message:
KYRA: (EOB) - cleanup

Changed paths:
    engines/kyra/loleobbase.cpp
    engines/kyra/staticres_eob.cpp



diff --git a/engines/kyra/loleobbase.cpp b/engines/kyra/loleobbase.cpp
index 3db7537..bcab278 100644
--- a/engines/kyra/loleobbase.cpp
+++ b/engines/kyra/loleobbase.cpp
@@ -149,10 +149,6 @@ LolEobBaseEngine::~LolEobBaseEngine() {
 	delete[] _levelDecorationData;
 	delete[] _levelDecorationProperties;
 	delete[] _levelBlockProperties;
-
-	for (Common::Array<Button::Callback>::iterator i = _buttonCallbacks.begin(); i != _buttonCallbacks.end(); ++i)
-		i->reset();
-	_buttonCallbacks.clear();
 }
 
 Common::Error LolEobBaseEngine::init() {
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index e90fea5..72b09e4 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -680,59 +680,47 @@ void EobCoreEngine::initButtonData() {
 	_buttonCallbacks.clear();
 	_buttonCallbacks.reserve(ARRAYSIZE(buttonDefs));
 
-#define EOB_CBN(x) _buttonCallbacks.push_back(BUTTON_FUNCTOR(EobCoreEngine, this, &EobCoreEngine::x))
-#define EOB_CBR(x) for (int l = x; l; l--) { _buttonCallbacks.push_back(_buttonCallbacks[_buttonCallbacks.size() - 1]); }
+#define EOB_CBN(x, y) _buttonCallbacks.push_back(BUTTON_FUNCTOR(EobCoreEngine, this, &EobCoreEngine::y)); for (int l = 0; l < (x - 1); l++) { _buttonCallbacks.push_back(_buttonCallbacks[_buttonCallbacks.size() - 1 - l]); }
 #define EOB_CBI(x, y) for (int l = x; l; l--) { _buttonCallbacks.push_back(_buttonCallbacks[y]); }
-	EOB_CBN(clickedCharPortraitDefault);
-	EOB_CBR(3);
-	EOB_CBN(clickedCamp);
-	EOB_CBN(clickedSceneDropPickupItem);
-	EOB_CBR(3);
-	EOB_CBN(clickedCharPortrait2);
-	EOB_CBR(3);
-	EOB_CBN(clickedWeaponSlot);
-	EOB_CBR(3);
-	EOB_CBN(clickedCharNameLabelRight);
-	EOB_CBR(3);
-	EOB_CBN(clickedInventorySlot);
-	EOB_CBR(24);
-	EOB_CBN(clickedEatItem);
-	EOB_CBN(clickedInventoryNextPage);
-	EOB_CBN(clickedPortraitRestore);
-	EOB_CBN(clickedUpArrow);
-	EOB_CBN(clickedDownArrow);
-	EOB_CBN(clickedLeftArrow);
-	EOB_CBN(clickedRightArrow);
-	EOB_CBN(clickedTurnLeftArrow);
-	EOB_CBN(clickedTurnRightArrow);
-	EOB_CBN(clickedAbortCharSwitch);
-	EOB_CBN(clickedSceneThrowItem);
-	EOB_CBR(1);
-	EOB_CBN(clickedSceneSpecial);
-	EOB_CBN(clickedInventoryPrevChar);
-	EOB_CBN(clickedInventoryNextChar);
-	EOB_CBN(clickedSpellbookTab);
-	EOB_CBR(4);
-	EOB_CBN(clickedSpellbookList);
-	EOB_CBR(5);
-	EOB_CBN(clickedCastSpellOnCharacter);
-	EOB_CBR(3);
+	EOB_CBN(4, clickedCharPortraitDefault);
+	EOB_CBN(1, clickedCamp);
+	EOB_CBN(4, clickedSceneDropPickupItem);
+	EOB_CBN(4, clickedCharPortrait2);
+	EOB_CBN(4, clickedWeaponSlot);
+	EOB_CBN(4, clickedCharNameLabelRight);
+	EOB_CBN(25, clickedInventorySlot);
+	EOB_CBN(1, clickedEatItem);
+	EOB_CBN(1, clickedInventoryNextPage);
+	EOB_CBN(1, clickedPortraitRestore);
+	EOB_CBN(1, clickedUpArrow);
+	EOB_CBN(1, clickedDownArrow);
+	EOB_CBN(1, clickedLeftArrow);
+	EOB_CBN(1, clickedRightArrow);
+	EOB_CBN(1, clickedTurnLeftArrow);
+	EOB_CBN(1, clickedTurnRightArrow);
+	EOB_CBN(1, clickedAbortCharSwitch);
+	EOB_CBN(2, clickedSceneThrowItem);
+	EOB_CBN(1, clickedSceneSpecial);
+	EOB_CBN(1, clickedInventoryPrevChar);
+	EOB_CBN(1, clickedInventoryNextChar);
+	EOB_CBN(5, clickedSpellbookTab);
+	EOB_CBN(6, clickedSpellbookList);
+	EOB_CBN(4, clickedCastSpellOnCharacter);
 	EOB_CBI(2, 66);
 	EOB_CBI(2, 9);
 	EOB_CBI(2, 13);
 	EOB_CBI(2, 17);
 	EOB_CBI(2, 21);
 	EOB_CBI(2, 72);
-	EOB_CBN(clickedSpellbookAbort);
+	EOB_CBN(1, clickedSpellbookAbort);
 	EOB_CBI(1, 72);
 	EOB_CBI(2, 0);
 	EOB_CBI(1, 60);
 	EOB_CBI(1, 61);
-	EOB_CBN(clickedSpellbookScroll);
+	EOB_CBN(1, clickedSpellbookScroll);
 	EOB_CBI(5, 61);
 	EOB_CBI(1, 88);
 #undef EOB_CBI
-#undef EOB_CBR
 #undef EOB_CBN
 }
 


Commit: a944990a6896e9e667e987a3cb3d3d8affc0e5b3
    https://github.com/scummvm/scummvm/commit/a944990a6896e9e667e987a3cb3d3d8affc0e5b3
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:15-08:00

Commit Message:
KYRA: (EOB) - rename some saving throw related data

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    engines/kyra/chargen.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/resource.h
    engines/kyra/staticres_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index 11e868f..d500cbd 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -228,13 +228,13 @@ const ExtractFilename extractFilenames[] = {
 	{ kEobBaseChargenRaceMinStats, k3TypeRaw16to8, false },
 	{ kEobBaseChargenRaceMaxStats, kLolTypeRaw16, false },
 
-	{ kEobBaseConstModTable1, kTypeRawData, false },
-	{ kEobBaseConstModTable2, kTypeRawData, false },
-	{ kEobBaseConstModTable3, kTypeRawData, false },
-	{ kEobBaseConstModTable4, kTypeRawData, false },
-	{ kEobBaseConstModLvlIndex, kTypeRawData, false },
-	{ kEobBaseConstModDiv, kTypeRawData, false },
-	{ kEobBaseConstModExt, kTypeRawData, false },
+	{ kEobBaseSaveThrowTable1, kTypeRawData, false },
+	{ kEobBaseSaveThrowTable2, kTypeRawData, false },
+	{ kEobBaseSaveThrowTable3, kTypeRawData, false },
+	{ kEobBaseSaveThrowTable4, kTypeRawData, false },
+	{ kEobBaseSaveThrwLvlIndex, kTypeRawData, false },
+	{ kEobBaseSaveThrwModDiv, kTypeRawData, false },
+	{ kEobBaseSaveThrwModExt, kTypeRawData, false },
 
 	{ kEobBasePryDoorStrings, kTypeStringList, true },
 	{ kEobBaseWarningStrings, kTypeStringList, true },
@@ -1369,20 +1369,20 @@ const char *getIdString(const int id) {
 		return "kEobBaseChargenRaceMinStats";
 	case kEobBaseChargenRaceMaxStats:
 		return "kEobBaseChargenRaceMaxStats";
-	case kEobBaseConstModTable1:
-		return "kEobBaseConstModTable1";
-	case kEobBaseConstModTable2:
-		return "kEobBaseConstModTable2";
-	case kEobBaseConstModTable3:
-		return "kEobBaseConstModTable3";
-	case kEobBaseConstModTable4:
-		return "kEobBaseConstModTable4";
-	case kEobBaseConstModLvlIndex:
-		return "kEobBaseConstModLvlIndex";
-	case kEobBaseConstModDiv:
-		return "kEobBaseConstModDiv";
-	case kEobBaseConstModExt:
-		return "kEobBaseConstModExt";
+	case kEobBaseSaveThrowTable1:
+		return "kEobBaseSaveThrowTable1";
+	case kEobBaseSaveThrowTable2:
+		return "kEobBaseSaveThrowTable2";
+	case kEobBaseSaveThrowTable3:
+		return "kEobBaseSaveThrowTable3";
+	case kEobBaseSaveThrowTable4:
+		return "kEobBaseSaveThrowTable4";
+	case kEobBaseSaveThrwLvlIndex:
+		return "kEobBaseSaveThrwLvlIndex";
+	case kEobBaseSaveThrwModDiv:
+		return "kEobBaseSaveThrwModDiv";
+	case kEobBaseSaveThrwModExt:
+		return "kEobBaseSaveThrwModExt";
 	case kEobBasePryDoorStrings:
 		return "kEobBasePryDoorStrings";
 	case kEobBaseWarningStrings:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index 4ac9475..08b71ee 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -204,13 +204,13 @@ enum kExtractID {
 	kEobBaseChargenRaceMinStats,
 	kEobBaseChargenRaceMaxStats,
 
-	kEobBaseConstModTable1,
-	kEobBaseConstModTable2,
-	kEobBaseConstModTable3,
-	kEobBaseConstModTable4,
-	kEobBaseConstModLvlIndex,
-	kEobBaseConstModDiv,
-	kEobBaseConstModExt,
+	kEobBaseSaveThrowTable1,
+	kEobBaseSaveThrowTable2,
+	kEobBaseSaveThrowTable3,
+	kEobBaseSaveThrowTable4,
+	kEobBaseSaveThrwLvlIndex,
+	kEobBaseSaveThrwModDiv,
+	kEobBaseSaveThrwModExt,
 
 	kEobBasePryDoorStrings,
 	kEobBaseWarningStrings,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index cc81aba..65c1a23 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1046,13 +1046,13 @@ const int eob1FloppyNeed[] = {
 	kEobBaseChargenRaceMinStats,
 	kEobBaseChargenRaceMaxStats,
 
-	kEobBaseConstModTable1,
-	kEobBaseConstModTable2,
-	kEobBaseConstModTable3,
-	kEobBaseConstModTable4,
-	kEobBaseConstModLvlIndex,
-	kEobBaseConstModDiv,
-	kEobBaseConstModExt,
+	kEobBaseSaveThrowTable1,
+	kEobBaseSaveThrowTable2,
+	kEobBaseSaveThrowTable3,
+	kEobBaseSaveThrowTable4,
+	kEobBaseSaveThrwLvlIndex,
+	kEobBaseSaveThrwModDiv,
+	kEobBaseSaveThrwModExt,
 
 	kEob1MainMenuStrings,
 	kEob1BonusStrings,
@@ -1313,13 +1313,13 @@ const int eob2FloppyNeed[] = {
 	kEobBaseChargenRaceMinStats,
 	kEobBaseChargenRaceMaxStats,
 
-	kEobBaseConstModTable1,
-	kEobBaseConstModTable2,
-	kEobBaseConstModTable3,
-	kEobBaseConstModTable4,
-	kEobBaseConstModLvlIndex,
-	kEobBaseConstModDiv,
-	kEobBaseConstModExt,
+	kEobBaseSaveThrowTable1,
+	kEobBaseSaveThrowTable2,
+	kEobBaseSaveThrowTable3,
+	kEobBaseSaveThrowTable4,
+	kEobBaseSaveThrwLvlIndex,
+	kEobBaseSaveThrwModDiv,
+	kEobBaseSaveThrwModExt,
 
 	kEobBasePryDoorStrings,
 	kEobBaseWarningStrings,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index 064b3c8..c854780 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -1401,37 +1401,37 @@ const ExtractEntrySearchData kEobBaseChargenRaceMaxStatsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseConstModTable1Provider[] = {
+const ExtractEntrySearchData kEobBaseSaveThrowTable1Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000032, 0x00000214, { { 0x3D, 0x89, 0x30, 0x0A, 0x5C, 0x4A, 0x0F, 0xC3, 0xC7, 0x6B, 0x72, 0x7C, 0x12, 0x51, 0x8D, 0x8E } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseConstModTable2Provider[] = {
+const ExtractEntrySearchData kEobBaseSaveThrowTable2Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000019, 0x000000E7, { { 0xF4, 0x0D, 0xDF, 0xA3, 0x23, 0x71, 0x76, 0x2A, 0xC5, 0x6F, 0xF1, 0x59, 0x5F, 0x45, 0x73, 0x05 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseConstModTable3Provider[] = {
+const ExtractEntrySearchData kEobBaseSaveThrowTable3Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000023, 0x00000155, { { 0x42, 0x98, 0x84, 0x00, 0x70, 0x8A, 0x7B, 0x26, 0xC0, 0x96, 0xA3, 0x28, 0x41, 0x36, 0x4B, 0x21 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseConstModTable4Provider[] = {
+const ExtractEntrySearchData kEobBaseSaveThrowTable4Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000001E, 0x0000013B, { { 0xAB, 0x84, 0x2B, 0x0A, 0xC2, 0x46, 0xFF, 0x83, 0x03, 0xF8, 0x3F, 0x32, 0x53, 0xA2, 0x95, 0x65 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseConstModLvlIndexProvider[] = {
+const ExtractEntrySearchData kEobBaseSaveThrwLvlIndexProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000006, 0x00000070, { { 0x57, 0x48, 0x5F, 0x75, 0x79, 0xD4, 0xAA, 0x7D, 0xB7, 0xEB, 0x19, 0x9F, 0xCF, 0x99, 0x29, 0x29 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseConstModDivProvider[] = {
+const ExtractEntrySearchData kEobBaseSaveThrwModDivProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000006, 0x00000012, { { 0x50, 0x29, 0x51, 0x65, 0x0B, 0xF1, 0xCC, 0xDA, 0x2C, 0xA4, 0x7E, 0xEE, 0x20, 0xB0, 0x29, 0xB1 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseConstModExtProvider[] = {
+const ExtractEntrySearchData kEobBaseSaveThrwModExtProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000006, 0x00000030, { { 0x07, 0x7D, 0x61, 0x1C, 0x95, 0xEC, 0x9A, 0xCE, 0xA1, 0x29, 0x83, 0x2F, 0xCA, 0x95, 0x95, 0xF5 } } } },
 	EXTRACT_END_ENTRY
 };
@@ -3860,13 +3860,13 @@ const ExtractEntry extractProviders[] = {
 	{ kEobBaseChargenRaceMinStats, kEobBaseChargenRaceMinStatsProvider },
 	{ kEobBaseChargenRaceMaxStats, kEobBaseChargenRaceMaxStatsProvider },
 
-	{ kEobBaseConstModTable1, kEobBaseConstModTable1Provider },
-	{ kEobBaseConstModTable2, kEobBaseConstModTable2Provider },
-	{ kEobBaseConstModTable3, kEobBaseConstModTable3Provider },
-	{ kEobBaseConstModTable4, kEobBaseConstModTable4Provider },
-	{ kEobBaseConstModLvlIndex, kEobBaseConstModLvlIndexProvider },
-	{ kEobBaseConstModDiv, kEobBaseConstModDivProvider },
-	{ kEobBaseConstModExt, kEobBaseConstModExtProvider },
+	{ kEobBaseSaveThrowTable1, kEobBaseSaveThrowTable1Provider },
+	{ kEobBaseSaveThrowTable2, kEobBaseSaveThrowTable2Provider },
+	{ kEobBaseSaveThrowTable3, kEobBaseSaveThrowTable3Provider },
+	{ kEobBaseSaveThrowTable4, kEobBaseSaveThrowTable4Provider },
+	{ kEobBaseSaveThrwLvlIndex, kEobBaseSaveThrwLvlIndexProvider },
+	{ kEobBaseSaveThrwModDiv, kEobBaseSaveThrwModDivProvider },
+	{ kEobBaseSaveThrwModExt, kEobBaseSaveThrwModExtProvider },
 	
 	{ kEobBasePryDoorStrings, kEobBasePryDoorStringsProvider },
 	{ kEobBaseWarningStrings, kEobBaseWarningStringsProvider },
diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index 5231093..a288359 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -639,7 +639,7 @@ void CharacterGenerator::generateStats(int index) {
 		_chargenMaxStats[i] = _chargenRaceMaxStats[rc * 6 + i];
 	}
 
-	if (_vm->_charClassModUnk[c->cClass])
+	if (_vm->_charClassModifier[c->cClass])
 		_chargenMaxStats[0] = 18;
 
 	uint16 sv[6];
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 9e75be0..6f58d3a 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -157,7 +157,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 
 	_mainMenuStrings = _levelGainStrings = _monsterSpecAttStrings = _characterGuiStringsHp = _characterGuiStringsWp = _characterGuiStringsWr = _characterGuiStringsSt =
 		_characterGuiStringsIn = _characterStatusStrings7 = _characterStatusStrings8 = _characterStatusStrings9 = _characterStatusStrings12 = _characterStatusStrings13 = 0;
-	_classModifierFlags = _constModLevelIndex = _constModDiv = _constModExt = _wandTypes = _drawObjPosIndex = _flightObjFlipIndex = _expObjectTblIndex =
+	_classModifierFlags = _saveThrowLevelIndex = _saveThrowModDiv = _saveThrowModExt = _wandTypes = _drawObjPosIndex = _flightObjFlipIndex = _expObjectTblIndex =
 		_expObjectShpStart = _expObjectTlMode = _expObjectAnimTbl1 = _expObjectAnimTbl2 = _expObjectAnimTbl3 = 0;
 	_monsterStepTable0 = _monsterStepTable1 = _monsterStepTable2 = _monsterStepTable3 = _projectileWeaponAmmoTypes = _flightObjShpMap = _flightObjSclIndex = 0;
 	_monsterCloseAttPosTable1 = _monsterCloseAttPosTable2 = _monsterCloseAttChkTable1 = _monsterCloseAttChkTable2 = _monsterCloseAttDstTable1 = _monsterCloseAttDstTable2 = 0;
@@ -190,7 +190,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_mnNumWord = _numSpells = _mageSpellListSize = _spellLevelsMageSize = _spellLevelsClericSize = 0;
 	_inventorySlotsX = _slotValidationFlags = _encodeMonsterShpTable = 0;
 	memset(_expRequirementTables, 0, sizeof(_expRequirementTables));
-	memset(_constModTables, 0, sizeof(_constModTables));
+	memset(_saveThrowTables, 0, sizeof(_saveThrowTables));
 	memset(_doorType, 0, sizeof(_doorType));
 	memset(_noDoorSwitch, 0, sizeof(_noDoorSwitch));
 	memset(_scriptTimers, 0, sizeof(_scriptTimers));
@@ -1867,7 +1867,7 @@ int EobCoreEngine::calcCharacterDamage(int charIndex, int times, int itemOrPips,
 	EobCharacter *c = &_characters[charIndex];
 
 	if (savingThrowType != 5) {
-		if (trySavingThrow(c, _charClassModUnk[c->cClass], c->level[0], savingThrowType, c->raceSex >> 1 /*fix bug in original code by adding a right shift*/))
+		if (trySavingThrow(c, _charClassModifier[c->cClass], c->level[0], savingThrowType, c->raceSex >> 1 /*fix bug in original code by adding a right shift*/))
 			s = savingThrowReduceDamage(savingThrowEffect, s);
 	}
 
@@ -2197,7 +2197,7 @@ bool EobCoreEngine::trySavingThrow(void *target, int hpModifier, int level, int
 	if (type == 5)
 		return false;
 
-	int s = getConstModifierTableValue(hpModifier, level, type);
+	int s = getSaveThrowModifier(hpModifier, level, type);
 	if (((race == 3 || race == 5) && (type == 4 || type == 1 || type == 0)) || (race == 4 && (type == 4 || type == 1))) {
 		EobCharacter *c = (EobCharacter*)target;
 		s -= constMod[c->constitutionCur];
@@ -2207,15 +2207,15 @@ bool EobCoreEngine::trySavingThrow(void *target, int hpModifier, int level, int
 }
 
 bool EobCoreEngine::specialAttackSavingThrow(int charIndex, int type) {
-	return trySavingThrow(&_characters[charIndex], _charClassModUnk[_characters[charIndex].cClass], _characters[charIndex].level[0], type, _characters[charIndex].raceSex >> 1);
+	return trySavingThrow(&_characters[charIndex], _charClassModifier[_characters[charIndex].cClass], _characters[charIndex].level[0], type, _characters[charIndex].raceSex >> 1);
 }
 
-int EobCoreEngine::getConstModifierTableValue(int hpModifier, int level, int b) {
-	const uint8 *tbl = _constModTables[hpModifier];
-	if (_constModLevelIndex[hpModifier] < level)
-		level = _constModLevelIndex[hpModifier];
-	level /= _constModDiv[hpModifier];
-	level += (_constModExt[hpModifier] * b);
+int EobCoreEngine::getSaveThrowModifier(int hpModifier, int level, int type) {
+	const uint8 *tbl = _saveThrowTables[hpModifier];
+	if (_saveThrowLevelIndex[hpModifier] < level)
+		level = _saveThrowLevelIndex[hpModifier];
+	level /= _saveThrowModDiv[hpModifier];
+	level += (_saveThrowModExt[hpModifier] * type);
 
 	return tbl[level];
 }
@@ -2281,7 +2281,7 @@ int EobCoreEngine::getMonsterAcHitChanceModifier(int charIndex, int monsterAc) {
 	static const uint8 mod2[] = { 1, 1, 2, 1 };
 
 	int l = _characters[charIndex].level[0] - 1;
-	int cm = _charClassModUnk[_characters[charIndex].cClass];
+	int cm = _charClassModifier[_characters[charIndex].cClass];
 
 	return (20 - ((l / mod1[cm]) * mod2[cm])) - monsterAc;
 }
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 795b017..e4c06fe 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -326,7 +326,7 @@ protected:
 	static const uint8 _hpIncrPerLevel[];
 	static const uint8 _numLevelsPerClass[];
 	static const int16 _hpConstModifiers[];
-	static const uint8 _charClassModUnk[];
+	static const uint8 _charClassModifier[];
 
 	const uint8 *_classModifierFlags;
 	
@@ -406,10 +406,10 @@ protected:
 	const char *const *_levelGainStrings;
 	const uint32 *_expRequirementTables[6];
 
-	const uint8 *_constModTables[6];
-	const uint8 *_constModLevelIndex;
-	const uint8 *_constModDiv;
-	const uint8 *_constModExt;
+	const uint8 *_saveThrowTables[6];
+	const uint8 *_saveThrowLevelIndex;
+	const uint8 *_saveThrowModDiv;
+	const uint8 *_saveThrowModExt;
 
 	const EobCharacter *_npcPreset;
 	int _npcSequenceSub;
@@ -891,7 +891,7 @@ protected:
 	int calcDamageModifers(int charIndex, EobMonsterInPlay *m, int item, int itemType, int useStrModifier);
 	bool trySavingThrow(void *target, int hpModifier, int level, int type, int race);
 	bool specialAttackSavingThrow(int charIndex, int type);
-	int getConstModifierTableValue(int hpModifier, int level, int b);
+	int getSaveThrowModifier(int hpModifier, int level, int type);
 	bool calcDamageCheckItemType(int itemType);
 	int savingThrowReduceDamage(int savingThrowEffect, int damage);
 	bool tryMonsterAttackEvasion(EobMonsterInPlay *m);
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index a7060cd..8edfd0a 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -277,13 +277,13 @@ enum KyraResources {
 	kEobBaseChargenRaceMinStats,
 	kEobBaseChargenRaceMaxStats,
 
-	kEobBaseConstModTable1,
-	kEobBaseConstModTable2,
-	kEobBaseConstModTable3,
-	kEobBaseConstModTable4,
-	kEobBaseConstModLvlIndex,
-	kEobBaseConstModDiv,
-	kEobBaseConstModExt,
+	kEobBaseSaveThrowTable1,
+	kEobBaseSaveThrowTable2,
+	kEobBaseSaveThrowTable3,
+	kEobBaseSaveThrowTable4,
+	kEobBaseSaveThrwLvlIndex,
+	kEobBaseSaveThrwModDiv,
+	kEobBaseSaveThrwModExt,
 
 	kEobBasePryDoorStrings,
 	kEobBaseWarningStrings,
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 72b09e4..ec5d184 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -274,7 +274,7 @@ const int8 EobCoreEngine::_characterClassType[] = {
 
 const int16 EobCoreEngine::_hpConstModifiers[] = { -1, -3, -2, -2, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 6, 6, 7, 7 };
 
-const uint8 EobCoreEngine::_charClassModUnk[] = {
+const uint8 EobCoreEngine::_charClassModifier[] = {
 	0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02,
 	0x00, 0x00, 0x02
 };
@@ -436,13 +436,13 @@ void EobCoreEngine::initStaticResource() {
 
 	_classModifierFlags = _staticres->loadRawData(kEobBaseClassModifierFlags, temp);
 
-	_constModTables[0] = _constModTables[4] = _constModTables[5] = _staticres->loadRawData(kEobBaseConstModTable1, temp);
-	_constModTables[1] = _staticres->loadRawData(kEobBaseConstModTable2, temp);
-	_constModTables[2] = _staticres->loadRawData(kEobBaseConstModTable3, temp);
-	_constModTables[3] = _staticres->loadRawData(kEobBaseConstModTable4, temp);
-	_constModLevelIndex = _staticres->loadRawData(kEobBaseConstModLvlIndex, temp);
-	_constModDiv = _staticres->loadRawData(kEobBaseConstModDiv, temp);
-	_constModExt = _staticres->loadRawData(kEobBaseConstModExt, temp);
+	_saveThrowTables[0] = _saveThrowTables[4] = _saveThrowTables[5] = _staticres->loadRawData(kEobBaseSaveThrowTable1, temp);
+	_saveThrowTables[1] = _staticres->loadRawData(kEobBaseSaveThrowTable2, temp);
+	_saveThrowTables[2] = _staticres->loadRawData(kEobBaseSaveThrowTable3, temp);
+	_saveThrowTables[3] = _staticres->loadRawData(kEobBaseSaveThrowTable4, temp);
+	_saveThrowLevelIndex = _staticres->loadRawData(kEobBaseSaveThrwLvlIndex, temp);
+	_saveThrowModDiv = _staticres->loadRawData(kEobBaseSaveThrwModDiv, temp);
+	_saveThrowModExt = _staticres->loadRawData(kEobBaseSaveThrwModExt, temp);
 
 	_encodeMonsterShpTable = _staticres->loadRawDataBe16(kEobBaseEncodeMonsterDefs, temp);
 	_npcPreset = _staticres->loadEobNpcData(kEobBaseNpcPresets, temp);


Commit: 5837e0f94ea7abf67ecd618fb641eec98231ebcb
    https://github.com/scummvm/scummvm/commit/5837e0f94ea7abf67ecd618fb641eec98231ebcb
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:15-08:00

Commit Message:
KYRA: (EOB) - make sure that the music stops after character generation in Eob 1

(also more cleanup)

Changed paths:
    engines/kyra/chargen.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/gui_eob.h
    engines/kyra/scene_eob.cpp



diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index a288359..f7a5460 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -224,7 +224,8 @@ bool CharacterGenerator::start(EobCharacter *characters, uint8 ***faceShapes) {
 		finish();
 	}
 
-	_vm->sound()->playTrack(15);
+	if (_vm->game() == GI_EOB2)
+		_vm->sound()->playTrack(15);
 
 	*faceShapes = _faceShapes;
 	return true;
@@ -1406,29 +1407,6 @@ const EobRect8 CharacterGenerator::_chargenButtonBodyCoords[] = {
 	{ 0x14, 0x90, 0x0B, 0x10 }
 };
 
-const EobRect16 GUI_Eob::_updateBoxFrameHighLights[] = {
-	{ 0x00B7, 0x0001, 0x00F7, 0x0034 },
-	{ 0x00FF, 0x0001, 0x013F, 0x0034 },
-	{ 0x00B7, 0x0035, 0x00F7, 0x0068 },
-	{ 0x00FF, 0x0035, 0x013F, 0x0068 },
-	{ 0x00B7, 0x0069, 0x00F7, 0x009C },
-	{ 0x00FF, 0x0069, 0x013F, 0x009C },
-	{ 0x0010, 0x003F, 0x0030, 0x0060 },
-	{ 0x0050, 0x003F, 0x0070, 0x0060 },
-	{ 0x0010, 0x007F, 0x0030, 0x00A0 },
-	{ 0x0050, 0x007F, 0x0070, 0x00A0 },
-	{ 0x00B0, 0x0042, 0x00D0, 0x0061 },
-	{ 0x00D0, 0x0042, 0x00F0, 0x0061 },
-	{ 0x00F0, 0x0042, 0x0110, 0x0061 },
-	{ 0x0110, 0x0042, 0x0130, 0x0061 },
-	{ 0x0004, 0x0018, 0x0024, 0x0039 },
-	{ 0x00A3, 0x0018, 0x00C3, 0x0039 },
-	{ 0x0004, 0x0040, 0x0024, 0x0061 },
-	{ 0x00A3, 0x0040, 0x00C3, 0x0061 },
-	{ 0x0004, 0x0068, 0x0024, 0x0089 },
-	{ 0x00A3, 0x0068, 0x00C3, 0x0089 }
-};
-
 const int16 CharacterGenerator::_chargenBoxX[] = { 0x10, 0x50, 0x10, 0x50 };
 const int16 CharacterGenerator::_chargenBoxY[] = { 0x3F, 0x3F, 0x7F, 0x7F };
 const int16 CharacterGenerator::_chargenNameFieldX[] = { 0x02, 0x42, 0x02, 0x42 };
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index e4c06fe..06d4327 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -314,7 +314,6 @@ protected:
 	bool checkPartyStatus(bool handleDeath);
 
 	bool _runFlag;
-	//int _runLoopUnk2;
 
 	// Character generation / party transfer
 	bool startCharacterGeneration();
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 4ced205..f084bc9 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -2451,9 +2451,7 @@ void GUI_Eob::messageDialogue2(int dim, int id, int buttonTextCol) {
 }
 
 void GUI_Eob::updateBoxFrameHighLight(int box) {
-	static const uint8 colorTable[] = { 0x0F, 0xB0, 0xB2, 0xB4, 0xB6,
-		0xB8, 0xBA, 0xBC, 0x0C, 0xBC, 0xBA, 0xB8, 0xB6, 0xB4, 0xB2, 0xB0, 0x00
-	};
+	static const uint8 colorTable[] = { 0x0F, 0xB0, 0xB2, 0xB4, 0xB6, 0xB8, 0xBA, 0xBC, 0x0C, 0xBC, 0xBA, 0xB8, 0xB6, 0xB4, 0xB2, 0xB0, 0x00 };
 
 	if (_updateBoxIndex == box) {
 		if (_updateBoxIndex == -1)
@@ -4044,6 +4042,29 @@ void GUI_Eob::restParty_updateRestTime(int hours, bool init) {
 	_screen->setFont(of);
 }
 
+const EobRect16 GUI_Eob::_updateBoxFrameHighLights[] = {
+	{ 0x00B7, 0x0001, 0x00F7, 0x0034 },
+	{ 0x00FF, 0x0001, 0x013F, 0x0034 },
+	{ 0x00B7, 0x0035, 0x00F7, 0x0068 },
+	{ 0x00FF, 0x0035, 0x013F, 0x0068 },
+	{ 0x00B7, 0x0069, 0x00F7, 0x009C },
+	{ 0x00FF, 0x0069, 0x013F, 0x009C },
+	{ 0x0010, 0x003F, 0x0030, 0x0060 },
+	{ 0x0050, 0x003F, 0x0070, 0x0060 },
+	{ 0x0010, 0x007F, 0x0030, 0x00A0 },
+	{ 0x0050, 0x007F, 0x0070, 0x00A0 },
+	{ 0x00B0, 0x0042, 0x00D0, 0x0061 },
+	{ 0x00D0, 0x0042, 0x00F0, 0x0061 },
+	{ 0x00F0, 0x0042, 0x0110, 0x0061 },
+	{ 0x0110, 0x0042, 0x0130, 0x0061 },
+	{ 0x0004, 0x0018, 0x0024, 0x0039 },
+	{ 0x00A3, 0x0018, 0x00C3, 0x0039 },
+	{ 0x0004, 0x0040, 0x0024, 0x0061 },
+	{ 0x00A3, 0x0040, 0x00C3, 0x0061 },
+	{ 0x0004, 0x0068, 0x0024, 0x0089 },
+	{ 0x00A3, 0x0068, 0x00C3, 0x0089 }
+};
+
 #endif // ENABLE_EOB
 
 }	// End of namespace Kyra
diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h
index 30fd4cc..a0ac509 100644
--- a/engines/kyra/gui_eob.h
+++ b/engines/kyra/gui_eob.h
@@ -106,9 +106,6 @@ private:
 
 	void restParty_updateRestTime(int hours, bool init);
 
-	Button _scrollUpButton;//////////////////77
-	Button _scrollDownButton;
-
 	char **_menuStringsPrefsTemp;
 	char **_saveSlotStringsTemp;
 	int16 *_saveSlotIdTemp;
@@ -130,9 +127,6 @@ private:
 	uint16 _prcButtonUnk3;
 	uint16 _cflag;
 
-	//Button::Callback _scrollUpFunctor;
-	//Button::Callback _scrollDownFunctor;
-
 	int _menuLineSpacing;
 	int _menuLastInFlags;
 
@@ -150,6 +144,7 @@ private:
 	int _updateBoxIndex;
 	int _updateBoxColorIndex;
 	uint32 _highLightBoxTimer;
+
 	static const EobRect16 _updateBoxFrameHighLights[];
 };
 
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index ce0cdf8..0aaad6d 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -620,6 +620,7 @@ namespace Kyra {
 void EobCoreEngine::loadLevel(int level, int sub) {
 	_currentLevel = level;
 	_currentSub = sub;
+	uint32 end = _system->getMillis() + 500;
 
 	Common::String file;
 	Common::SeekableReadStream *s = 0;
@@ -695,6 +696,8 @@ void EobCoreEngine::loadLevel(int level, int sub) {
 
 	loadVcnData(gfxFile.c_str(), 0);
 	_screen->loadEobBitmap("INVENT", 0, 5, 3, 2);
+	delayUntil(end);
+	snd_stopSound();
 
 	enableSysTimer(2);
 	_sceneDrawPage1 = 2;


Commit: 49c111f8ca4a822ce98c81a9162899d3d1e4e6b2
    https://github.com/scummvm/scummvm/commit/49c111f8ca4a822ce98c81a9162899d3d1e4e6b2
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:15-08:00

Commit Message:
KYRA: (EOB) - ignore 'EYE.PAK' file in resource loader

(This seems to be some sort of installer archive which is not supported atm)

Changed paths:
    engines/kyra/resource.cpp



diff --git a/engines/kyra/resource.cpp b/engines/kyra/resource.cpp
index 3aaab07..e1b7227 100644
--- a/engines/kyra/resource.cpp
+++ b/engines/kyra/resource.cpp
@@ -84,7 +84,7 @@ bool Resource::reset() {
 				name.toUppercase();
 
 				// No PAK file
-				if (name == "TWMUSIC.PAK")
+				if (name == "TWMUSIC.PAK" || name == "EYE.PAK")
 					continue;
 
 				// We need to only load the script archive for the language the user specified


Commit: aac7e16afa8546232a27754c6928cd43cd6ba876
    https://github.com/scummvm/scummvm/commit/aac7e16afa8546232a27754c6928cd43cd6ba876
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:15-08:00

Commit Message:
KYRA: (EOB) - fix some more bugs

- wrong usage of static array which caused issues when restarting after RTL
- portability issue with dialog labels
- (original code) bug in hold person spell

Changed paths:
    engines/kyra/eob1.cpp
    engines/kyra/eob1.h
    engines/kyra/eob2.cpp
    engines/kyra/eob2.h
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/magic_eob.cpp
    engines/kyra/scene_eob.cpp
    engines/kyra/script_eob.cpp
    engines/kyra/staticres_eob.cpp



diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
index c345b47..ae24b14 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -33,8 +33,8 @@ EobEngine::EobEngine(OSystem *system, const GameFlags &flags) : EobCoreEngine(sy
 	_menuChoiceInit = 4;
 
 	_turnUndeadString = _introFilesOpening = _introFilesTower = _introFilesOrb = _introFilesWdEntry	= _introFilesKing = _introFilesHands = _introFilesWdExit =
-		_introFilesTunnel = _finBonusStrings = _npc11Strings = _npc12Strings = _npc21Strings = _npc22Strings = _npc31Strings = _npc32Strings = _npc4Strings	=
-		_npc5Strings = _npc6Strings	= _npc7Strings = 0;
+		_introFilesTunnel = _finBonusStrings = _npcStrings[1] = _npcStrings[2] = _npcStrings[3] = _npcStrings[4] = _npcStrings[5] = _npcStrings[6] = _npcStrings[7]	=
+		_npcStrings[8] = _npcStrings[9]	= _npcStrings[10] = 0;
 	_introOpeningFrmDelay = _introWdEncodeX	= _introWdEncodeY = _introWdEncodeWH = _npcShpData = _npcSubShpIndex1 = _npcSubShpIndex2 = _npcSubShpY = _introWdDsY =
 		_introTvlX1 = _introTvlY1 = _introTvlX2	= _introTvlY2 = _introTvlW = _introTvlH = _dscDoorScaleMult4 = _dscDoorScaleMult5 = _dscDoorScaleMult6 =
 		_dscDoorY3 = _dscDoorY4 = _dscDoorY5 = _dscDoorY6 = _dscDoorY7 = _doorShapeEncodeDefs = _doorSwitchShapeEncodeDefs = _doorSwitchCoords = 0;
@@ -164,8 +164,8 @@ void EobEngine::encodeDrawNpcSeqShape(int npcIndex, int drawX, int drawY) {
 	delete[] shp;
 }
 
-#define DLG2(txt, buttonstr) (runDialogue(txt, 0, _npc##buttonstr##Strings[0], _npc##buttonstr##Strings[1], 0) - 1)
-#define DLG3(txt, buttonstr) (runDialogue(txt, 1, _npc##buttonstr##Strings[0], _npc##buttonstr##Strings[1], _npc##buttonstr##Strings[2], 0) - 1)
+#define DLG2(txt, buttonstr) (runDialogue(txt, 2, _npcStrings[buttonstr][0], _npcStrings[buttonstr][1]) - 1)
+#define DLG3(txt, buttonstr) (runDialogue(txt, 3, _npcStrings[buttonstr][0], _npcStrings[buttonstr][1], _npcStrings[buttonstr][2]) - 1)
 #define DLG2A3(cond, txt, buttonstr1, buttonstr2) ((cond) ? (DLG2(txt, buttonstr1) ? 2 : 0) : DLG3(txt, buttonstr2))
 #define TXT(txt) _txt->printDialogueText(txt, _moreStrings[0])
 
@@ -178,7 +178,7 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 	case 0:
 		for (r = 1; r == 1; ) {
 			gui_drawDialogueBox();
-			r = DLG2A3(checkScriptFlags(0x2000), 8, 12, 11);
+			r = DLG2A3(checkScriptFlags(0x2000), 8, 2, 1);
 			if (r == 1) {
 				TXT(1);
 				setScriptFlags(0x2000);
@@ -195,10 +195,10 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 				a = 1;
 			} else {
 				setScriptFlags(0x8000);
-				r = DLG2(3, 21);
+				r = DLG2(3, 3);
 			}
 			if (!r)
-				r = DLG2(a ? 13 : 4, 22);
+				r = DLG2(a ? 13 : 4, 4);
 			
 			if (!r) {
 				for (a = 0; a < 6; a++)
@@ -238,7 +238,7 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 		}
 
 		if (!r)
-			 _txt->printDialogueText(_npc0Strings[0], true);
+			 _txt->printDialogueText(_npcStrings[0][0], true);
 
 		break;
 
@@ -247,7 +247,7 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 			if (checkScriptFlags(0x20000)) {
 				TXT(11);
 			} else {
-				r = DLG2A3(!countResurrectionCandidates(), 9, 31, 32);
+				r = DLG2A3(!countResurrectionCandidates(), 9, 5, 6);
 				if (r < 2) {
 					if (r == 0)
 						healParty();
@@ -262,7 +262,7 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 		break;
 
 	case 3:
-		if (!DLG2(18, 4)) {
+		if (!DLG2(18, 7)) {
 			setScriptFlags(0x8400000);
 			for (a = 0; a < 30; a++) {
 				if (_monsters[a].mode == 8)
@@ -277,7 +277,7 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 		break;
 
 	case 4:
-		r = DLG3(14, 5);
+		r = DLG3(14, 8);
 		if (r == 0)
 			setScriptFlags(0x200000);
 		else if (r == 1)
@@ -286,7 +286,7 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 		break;
 
 	case 5:
-		if (!DLG2(16, 6)) {
+		if (!DLG2(16, 9)) {
 			TXT(17);
 			for (a = 0; a < 6; a++) {
 				for (r = 0; r < 2; r++) {
@@ -307,7 +307,7 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 		break;
 
 	case 7:
-		r = DLG3(22, 7);
+		r = DLG3(22, 10);
 		if (r  < 2) {
 			if (r == 0)
 				npcJoinDialogue(8, 27, 44, 45);
@@ -531,9 +531,9 @@ bool EobEngine::checkPartyStatusExtra() {
 
 int EobEngine::resurrectionSelectDialogue() {
 	gui_drawDialogueBox();
-	_txt->printDialogueText(_npc0Strings[1]);
+	_txt->printDialogueText(_npcStrings[0][1]);
 
-	int r = _rrId[runDialogue(-1, 1, _rrNames[0], _rrNames[1], _rrNames[2], _rrNames[3], _rrNames[4], _rrNames[5], _rrNames[6], _rrNames[7], _rrNames[8]) - 1];
+	int r = _rrId[runDialogue(-1, 9, _rrNames[0], _rrNames[1], _rrNames[2], _rrNames[3], _rrNames[4], _rrNames[5], _rrNames[6], _rrNames[7], _rrNames[8]) - 1];
 
 	if (r < 0) {
 		r = -r;
diff --git a/engines/kyra/eob1.h b/engines/kyra/eob1.h
index 3eade85..00583e9 100644
--- a/engines/kyra/eob1.h
+++ b/engines/kyra/eob1.h
@@ -102,17 +102,7 @@ private:
 	const uint8 *_npcSubShpIndex1;
 	const uint8 *_npcSubShpIndex2;
 	const uint8 *_npcSubShpY;
-	const char *const *_npc0Strings;
-	const char *const *_npc11Strings;
-	const char *const *_npc12Strings;
-	const char *const *_npc21Strings;
-	const char *const *_npc22Strings;
-	const char *const *_npc31Strings;
-	const char *const *_npc32Strings;
-	const char *const *_npc4Strings;
-	const char *const *_npc5Strings;
-	const char *const *_npc6Strings;
-	const char *const *_npc7Strings;
+	const char *const *_npcStrings[11];
 
 	// items
 	void updateUsedCharacterHandItem(int charIndex, int slot);
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index afaef0b..60df8f8 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -35,7 +35,7 @@ DarkMoonEngine::DarkMoonEngine(OSystem *system, const GameFlags &flags) : EobCor
 	_numSpells = 70;
 	_menuChoiceInit = 4;
 
-	_introStrings = _cpsFilesIntro = _cpsFilesFinale = _finaleStrings = _kheldranStrings = _npc1Strings = _npc2Strings = _hornStrings = 0;
+	_introStrings = _cpsFilesIntro = _cpsFilesFinale = _finaleStrings = _kheldranStrings = _npcStrings[0] = _npcStrings[1] = _hornStrings = 0;
 	_seqIntro = _seqFinale = 0;
 	_shapesIntro = _shapesFinale = 0;
 	_creditsData = _npcShpData = _dscDoorType5Offs = _hornSounds = 0;
@@ -118,7 +118,7 @@ void DarkMoonEngine::runNpcDialogue(int npcIndex) {
 		gui_drawDialogueBox();
 
 		_txt->printDialogueText(4, 0);
-		int r = runDialogue(-1, 0, _npc1Strings[0], _npc1Strings[1], 0) - 1;
+		int r = runDialogue(-1, 2, _npcStrings[0][0], _npcStrings[0][1]) - 1;
 
 		if (r == 0) {
 			snd_stopSound();
@@ -134,7 +134,7 @@ void DarkMoonEngine::runNpcDialogue(int npcIndex) {
 		gui_drawDialogueBox();
 
 		_txt->printDialogueText(8, 0);
-		int r = runDialogue(-1, 0, _npc2Strings[0], _npc2Strings[1], 0) - 1;
+		int r = runDialogue(-1, 2, _npcStrings[1][0], _npcStrings[1][1]) - 1;
 
 		if (r == 0) {
 			if (rollDice(1, 2, -1))
@@ -422,7 +422,7 @@ int DarkMoonEngine::resurrectionSelectDialogue() {
 	_rrNames[_rrCount] = _abortStrings[0];
 	_rrId[_rrCount++] = 99;
 
-	int r = _rrId[runDialogue(-1, 1, _rrNames[0], _rrNames[1], _rrNames[2], _rrNames[3], _rrNames[4], _rrNames[5], _rrNames[6], _rrNames[7], _rrNames[8]) - 1];
+	int r = _rrId[runDialogue(-1, 9, _rrNames[0], _rrNames[1], _rrNames[2], _rrNames[3], _rrNames[4], _rrNames[5], _rrNames[6], _rrNames[7], _rrNames[8]) - 1];
 	if (r == 99)
 		return 0;
 
@@ -450,7 +450,7 @@ int DarkMoonEngine::charSelectDialogue() {
 
 	namesList[cnt++] = _abortStrings[0];
 
-	int r = runDialogue(-1, 1, namesList[0], namesList[1], namesList[2], namesList[3], namesList[4], namesList[5], namesList[6], 0) - 1;
+	int r = runDialogue(-1, 7, namesList[0], namesList[1], namesList[2], namesList[3], namesList[4], namesList[5], namesList[6]) - 1;
 	if (r == cnt - 1)
 		return 99;
 
diff --git a/engines/kyra/eob2.h b/engines/kyra/eob2.h
index 8c9b6dd..35eb90a 100644
--- a/engines/kyra/eob2.h
+++ b/engines/kyra/eob2.h
@@ -99,8 +99,7 @@ private:
 	void runNpcDialogue(int npcIndex);
 
 	const uint8 *_npcShpData;
-	const char *const *_npc1Strings;
-	const char *const *_npc2Strings;
+	const char *const *_npcStrings[2];
 
 	// items
 	void updateUsedCharacterHandItem(int charIndex, int slot);
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 6f58d3a..389a0e9 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -196,6 +196,20 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	memset(_scriptTimers, 0, sizeof(_scriptTimers));
 	memset(_monsterBlockPosArray, 0, sizeof(_monsterBlockPosArray));
 	memset(_foundMonstersArray, 0, sizeof(_foundMonstersArray));
+
+#define DWM0 _dscWallMapping.push_back(0)
+#define DWM(x) _dscWallMapping.push_back(&_sceneDrawVar##x)
+	DWM0;		DWM0;		DWM(Down);	DWM(Right);
+	DWM(Down);	DWM(Right);	DWM(Down);	DWM0;
+	DWM(Down);	DWM(Left);	DWM(Down);	DWM(Left);
+	DWM0;		DWM0;		DWM(Down);	DWM(Right);
+	DWM(Down);	DWM(Right);	DWM(Down);	DWM0;
+	DWM(Down);	DWM(Left);	DWM(Down);	DWM(Left);
+	DWM(Down);	DWM(Right);	DWM(Down);	DWM0;
+	DWM(Down);	DWM(Left);	DWM0;		DWM(Right);
+	DWM(Down);	DWM0;		DWM0;		DWM(Left);
+#undef DWM
+#undef DWM0
 }
 
 EobCoreEngine::~EobCoreEngine() {
@@ -254,6 +268,7 @@ EobCoreEngine::~EobCoreEngine() {
 
 	releaseDecorations();
 	delete[] _levelDecorationRects;
+	_dscWallMapping.clear();
 
 	delete[] _spells;
 	delete[] _spellAnimBuffer;
@@ -757,8 +772,7 @@ void EobCoreEngine::setHandItem(Item itemIndex) {
 }
 
 int EobCoreEngine::getDexterityArmorClassModifier(int dexterity) {
-	static const int mod[] = { 5, 5, 5, 4, 3, 2, 1, 0, 0,
-		0, 0, 0, 0, 0, 0, -1, -2, -3, -4, -4, -5, -5, -5, -6, -6 };
+	static const int8 mod[] = { 5, 5, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, -2, -3, -4, -4, -5, -5, -5, -6, -6 };
 	return mod[dexterity];
 }
 
@@ -1111,7 +1125,7 @@ int EobCoreEngine::npcJoinDialogue(int npcIndex, int queryJoinTextId, int confir
 	gui_drawDialogueBox();
 	_txt->printDialogueText(queryJoinTextId, 0);
 
-	int r = runDialogue(-1, 0, _yesNoStrings[0], _yesNoStrings[1], 0) - 1;
+	int r = runDialogue(-1, 2, _yesNoStrings[0], _yesNoStrings[1]) - 1;
 	if (r == 0) {
 		if (confirmJoinTextId == -1) {
 			Common::String tmp = Common::String::format(_npcJoinStrings[0], _npcPreset[npcIndex].name);
@@ -1140,8 +1154,8 @@ int EobCoreEngine::prepareForNewPartyMember(int16 itemType, int16 itemValue) {
 	} else {
 		gui_drawDialogueBox();
 		_txt->printDialogueText(_npcMaxStrings[0]);
-		int r = runDialogue(-1, 1, _characters[0].name, _characters[1].name, _characters[2].name, _characters[3].name,
-			_characters[4].name, _characters[5].name, _abortStrings[0], 0, 0) - 1;
+		int r = runDialogue(-1, 7, _characters[0].name, _characters[1].name, _characters[2].name, _characters[3].name,
+			_characters[4].name, _characters[5].name, _abortStrings[0]) - 1;
 
 		if (r == 6)
 			return 0;
@@ -1264,16 +1278,14 @@ void EobCoreEngine::setWeaponSlotStatus(int charIndex, int mode, int slot) {
 	gui_drawCharPortraitWithStats(charIndex);
 }
 
-void EobCoreEngine::setupDialogueButtons(int presetfirst, int numStr, const char *str1, va_list &args) {
+void EobCoreEngine::setupDialogueButtons(int presetfirst, int numStr, va_list &args) {
 	_dialogueNumButtons = numStr;
-	_dialogueButtonString[0] = str1;
 	_dialogueHighlightedButton = 0;
-	const char *tmp = 0;
 
-	for (int i = 1; i < numStr; i++) {
-		tmp = va_arg(args, const char*);
-		if (tmp)
-			_dialogueButtonString[i] = tmp;
+	for (int i = 0; i < numStr; i++) {
+		const char *s = va_arg(args, const char*);
+		if (s)
+			_dialogueButtonString[i] = s;
 		else
 			_dialogueNumButtons = numStr = i;
 	}
@@ -1364,16 +1376,16 @@ void EobCoreEngine::drawSequenceBitmap(const char *file, int destRect, int x1, i
 	_screen->updateScreen();
 }
 
-int EobCoreEngine::runDialogue(int dialogueTextId, int style, const char *button1, ...) {
+int EobCoreEngine::runDialogue(int dialogueTextId, int numStr, ...) {
 	if (dialogueTextId != -1)
 		txt()->printDialogueText(dialogueTextId, 0);
 
 	va_list args;
-	va_start(args, button1);
-	if (style)
-		setupDialogueButtons(2, 9, button1, args);
+	va_start(args, numStr);
+	if (numStr > 2)
+		setupDialogueButtons(2, numStr, args);
 	else
-		setupDialogueButtons(0, 2, button1, args);
+		setupDialogueButtons(0, numStr, args);
 	va_end(args);
 
 	int res = 0;
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 06d4327..93db0b3 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -620,6 +620,7 @@ protected:
 	uint32 _envAudioTimer;
 	uint16 _teleporterPulse;
 
+	Common::Array<const int16*> _dscWallMapping;
 	const int16 *_dscShapeCoords;
 
 	const uint8 *_dscItemPosIndex;
@@ -756,11 +757,11 @@ protected:
 	bool _configHpBarGraphs;
 
 	// text
-	void setupDialogueButtons(int presetfirst, int numStr, const char *str1, va_list &args);
+	void setupDialogueButtons(int presetfirst, int numStr, va_list &args);
 	void initDialogueSequence();
 	void restoreAfterDialogueSequence();
 	void drawSequenceBitmap(const char *file, int destRect, int x1, int y1, int flags);
-	int runDialogue(int dialogueTextId, int style, const char *button1, ...);
+	int runDialogue(int dialogueTextId, int numStr, ...);
 
 	char _dialogueLastBitmap[13];
 	int _moveCounter;
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index f084bc9..7d8e925 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -2100,7 +2100,7 @@ void GUI_Eob::runCampMenu() {
 	int newMenu = 0;
 	int lastMenu = -1;
 	bool redrawPortraits = false;
-	bool res = false;
+
 	_charSelectRedraw = false;
 	_needRest = false;
 	Button *buttonList = 0;
@@ -2250,7 +2250,6 @@ void GUI_Eob::runCampMenu() {
 				if (cnt > 4) {
 					_vm->dropCharacter(selectCharacterDialogue(53));
 					_vm->gui_drawPlayField(false);
-					res = true;
 					_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 12, Screen::CR_NO_P_CHECK);
 					_screen->setFont(Screen::FID_6_FNT);
 					_vm->gui_drawAllCharPortraitsWithStats();
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index b70058d..21bb10a 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -919,7 +919,7 @@ bool EobCoreEngine::spellCallback_end_holdPerson(void *obj) {
 	if (_flags.gameID == GI_EOB2 && fo->curBlock == _currentBlock) {
 		// party hit
 		int numChar = rollDice(1, 4, 0);
-		int charIndex = rollDice(1, 6, 0);
+		int charIndex = rollDice(1, 6, -1);
 		for (int i = 0; i < 6 && numChar; i++) {
 			if (testCharacter(charIndex, 3)) {
 				statusAttack(charIndex, 4, _magicStrings8[1], 4, 5, 9, 1);
@@ -1010,7 +1010,7 @@ void EobCoreEngine::spellCallback_start_removeCurse() {
 }
 
 void EobCoreEngine::spellCallback_start_coneOfCold() {
-	static const int8 *dirTables[] = { _coneOfColdDest1, _coneOfColdDest2, _coneOfColdDest3, _coneOfColdDest4 };
+	const int8 *dirTables[] = { _coneOfColdDest1, _coneOfColdDest2, _coneOfColdDest3, _coneOfColdDest4 };
 	
 	int cl = getMageLevel(_openBookChar);
 
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index 0aaad6d..e2a2e79 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -896,6 +896,7 @@ void EobCoreEngine::loadDecorations(const char *cpsFile, const char *decFile) {
 	_levelDecorationDataSize = s->readUint16LE();
 	delete[] _levelDecorationData;
 	_levelDecorationData = new LevelDecorationProperty[_levelDecorationDataSize];
+	memset(_levelDecorationData, 0, _levelDecorationDataSize * sizeof(LevelDecorationProperty));
 
 	for (int i = 0; i < _levelDecorationDataSize; i++) {
 		LevelDecorationProperty *l = &_levelDecorationData[i];
@@ -944,6 +945,7 @@ void EobCoreEngine::assignWallsAndDecorations(int wallIndex, int vmpIndex, int d
 	}
 
 	do {
+		assert(decIndex < _levelDecorationDataSize);
 		memcpy(&_levelDecorationProperties[_mappedDecorationsCount], &_levelDecorationData[decIndex], sizeof(LevelDecorationProperty));
 
 		for (int i = 0; i < 10; i++) {
@@ -956,7 +958,7 @@ void EobCoreEngine::assignWallsAndDecorations(int wallIndex, int vmpIndex, int d
 
 			EobRect8 *r = &_levelDecorationRects[t];
 			if (r->w == 0 || r->h == 0)
-				error("Error trying to make decoration %d	x: %d y:%d w:%d h:%d", decIndex, r->x, r->y, r->w, r->h);
+				error("Error trying to make decoration %d (x: %d, y: %d, w: %d, h: %d)", decIndex, r->x, r->y, r->w, r->h);
 
 			_levelDecorationShapes[t] = _screen->encodeShape(r->x, r->y, r->w, r->h);
 		}
@@ -1095,22 +1097,10 @@ void EobCoreEngine::drawSceneShapes(int start) {
 }
 
 void EobCoreEngine::drawDecorations(int index) {
-	static const int16 *dscWalls[] =  { 
-		0,					0,						&_sceneDrawVarDown, &_sceneDrawVarRight,
-		&_sceneDrawVarDown,	&_sceneDrawVarRight,	&_sceneDrawVarDown, 0,
-		&_sceneDrawVarDown, &_sceneDrawVarLeft,		&_sceneDrawVarDown,	&_sceneDrawVarLeft,
-		0,					0,						&_sceneDrawVarDown, &_sceneDrawVarRight,
-		&_sceneDrawVarDown, &_sceneDrawVarRight,	&_sceneDrawVarDown,	0,
-		&_sceneDrawVarDown, &_sceneDrawVarLeft,		&_sceneDrawVarDown, &_sceneDrawVarLeft,
-		&_sceneDrawVarDown,	&_sceneDrawVarRight,	&_sceneDrawVarDown, 0,
-		&_sceneDrawVarDown, &_sceneDrawVarLeft,		0,					&_sceneDrawVarRight,
-		&_sceneDrawVarDown, 0,						0,					&_sceneDrawVarLeft
-	};
-
 	for (int i = 1; i >= 0; i--) {
 		int s = index * 2 + i;
-		if (dscWalls[s]) {
-			int16 d = *dscWalls[s];
+		if (_dscWallMapping[s]) {
+			int16 d = *_dscWallMapping[s];
 			int8 l = _wllShapeMap[_visibleBlocks[index]->walls[d]];
 
 			uint8 *shapeData = 0;
diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp
index e85b1dc..4123e89 100644
--- a/engines/kyra/script_eob.cpp
+++ b/engines/kyra/script_eob.cpp
@@ -1527,7 +1527,7 @@ int EobInfProcessor::oeob_dialogue(int8 *data) {
 			break;
 
 		case -40:
-			_dlgResult = _vm->runDialogue(READ_LE_UINT16(pos), READ_LE_UINT16(pos + 6) == 0xffff ? 0 : 1, getString(READ_LE_UINT16(pos + 2)), getString(READ_LE_UINT16(pos + 4)), getString(READ_LE_UINT16(pos + 6)), 0);
+			_dlgResult = _vm->runDialogue(READ_LE_UINT16(pos), READ_LE_UINT16(pos + 6) == 0xffff ? 2 : 3, getString(READ_LE_UINT16(pos + 2)), getString(READ_LE_UINT16(pos + 4)), getString(READ_LE_UINT16(pos + 6)));
 			pos += 8;
 			break;
 
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index ec5d184..7433fbf 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -427,11 +427,8 @@ void EobCoreEngine::initStaticResource() {
 	_characterStatusStrings13 = _staticres->loadStrings(_flags.gameID == GI_EOB2 ? kEobBaseCharStatusStrings132 : kEobBaseCharStatusStrings131, temp);
 
 	_levelGainStrings = _staticres->loadStrings(kEobBaseLevelGainStrings, temp);
-	_expRequirementTables[0] = _staticres->loadRawDataBe32(kEobBaseExperienceTable0, temp);
-	_expRequirementTables[1] = _staticres->loadRawDataBe32(kEobBaseExperienceTable1, temp);
-	_expRequirementTables[2] = _staticres->loadRawDataBe32(kEobBaseExperienceTable2, temp);
-	_expRequirementTables[3] = _staticres->loadRawDataBe32(kEobBaseExperienceTable3, temp);
-	_expRequirementTables[4] = _staticres->loadRawDataBe32(kEobBaseExperienceTable4, temp);
+	for (int i = 0; i < 5; i++)
+		_expRequirementTables[i] = _staticres->loadRawDataBe32(kEobBaseExperienceTable0 + i, temp);
 	_expRequirementTables[5] = _staticres->loadRawDataBe32(kEobBaseExperienceTable4, temp);
 
 	_classModifierFlags = _staticres->loadRawData(kEobBaseClassModifierFlags, temp);
@@ -1153,17 +1150,8 @@ void EobEngine::initStaticResource() {
 	_npcSubShpIndex1 = _staticres->loadRawData(kEob1NpcSubShpIndex1, temp);
 	_npcSubShpIndex2 = _staticres->loadRawData(kEob1NpcSubShpIndex2, temp);
 	_npcSubShpY = _staticres->loadRawData(kEob1NpcSubShpY, temp);
-	_npc0Strings = _staticres->loadStrings(kEob1Npc0Strings, temp);
-	_npc11Strings = _staticres->loadStrings(kEob1Npc11Strings, temp);
-	_npc12Strings = _staticres->loadStrings(kEob1Npc12Strings, temp);
-	_npc21Strings = _staticres->loadStrings(kEob1Npc21Strings, temp);
-	_npc22Strings = _staticres->loadStrings(kEob1Npc22Strings, temp);
-	_npc31Strings = _staticres->loadStrings(kEob1Npc31Strings, temp);
-	_npc32Strings = _staticres->loadStrings(kEob1Npc32Strings, temp);
-	_npc4Strings = _staticres->loadStrings(kEob1Npc4Strings, temp);
-	_npc5Strings = _staticres->loadStrings(kEob1Npc5Strings, temp);
-	_npc6Strings = _staticres->loadStrings(kEob1Npc6Strings, temp);
-	_npc7Strings = _staticres->loadStrings(kEob1Npc7Strings, temp);
+	for (int i = 0; i < 11; i++)
+		_npcStrings[i] = _staticres->loadStrings(kEob1Npc0Strings + i, temp);
 
 	const uint8 *ps = _staticres->loadRawData(kEob1MonsterProperties, temp);
 	temp /= 27;
@@ -1321,8 +1309,8 @@ void DarkMoonEngine::initStaticResource() {
 	_dscDoorType5Offs = _staticres->loadRawData(kEobBaseDscDoorType5Offs, temp);
 
 	_npcShpData = _staticres->loadRawData(kEob2NpcShapeData, temp);
-	_npc1Strings = _staticres->loadStrings(kEob2Npc1Strings, temp);
-	_npc2Strings = _staticres->loadStrings(kEob2Npc2Strings, temp);
+	_npcStrings[0] = _staticres->loadStrings(kEob2Npc1Strings, temp);
+	_npcStrings[1] = _staticres->loadStrings(kEob2Npc2Strings, temp);
 	_monsterDustStrings = _staticres->loadStrings(kEob2MonsterDustStrings, temp);
 	_dreamSteps = (const int8*)_staticres->loadRawData(kEob2DreamSteps, temp);
 	_kheldranStrings = _staticres->loadStrings(kEob2KheldranStrings, temp);


Commit: 8b618e46df21d90a1a5ad62633a2b9d3c1da0317
    https://github.com/scummvm/scummvm/commit/8b618e46df21d90a1a5ad62633a2b9d3c1da0317
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:16-08:00

Commit Message:
KYRA: (EOB/LOL) - cleanup common code

(rename some stuff and move EOB/LOL common code to separate files)

Changed paths:
  A engines/kyra/gui_rpg.cpp
  A engines/kyra/kyra_rpg.cpp
  A engines/kyra/kyra_rpg.h
  A engines/kyra/saveload_rpg.cpp
  A engines/kyra/scene_rpg.cpp
  A engines/kyra/sprites_rpg.cpp
  A engines/kyra/staticres_rpg.cpp
  A engines/kyra/text_rpg.cpp
  A engines/kyra/text_rpg.h
  A engines/kyra/timer_rpg.cpp
  R engines/kyra/loleobbase.cpp
  R engines/kyra/loleobbase.h
  R engines/kyra/text_eob.cpp
  R engines/kyra/text_eob.h
    engines/kyra/chargen.cpp
    engines/kyra/detection.cpp
    engines/kyra/eob1.cpp
    engines/kyra/eob1.h
    engines/kyra/eob2.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/gui_eob.h
    engines/kyra/items_eob.cpp
    engines/kyra/lol.cpp
    engines/kyra/lol.h
    engines/kyra/magic_eob.cpp
    engines/kyra/module.mk
    engines/kyra/saveload_eob.cpp
    engines/kyra/saveload_lol.cpp
    engines/kyra/scene_eob.cpp
    engines/kyra/screen_eob.cpp
    engines/kyra/screen_eob.h
    engines/kyra/script_eob.cpp
    engines/kyra/script_eob.h
    engines/kyra/sequences_eob1.cpp
    engines/kyra/sequences_eob2.cpp
    engines/kyra/sound_lol.cpp
    engines/kyra/sprites_eob.cpp
    engines/kyra/staticres_eob.cpp
    engines/kyra/text_lol.cpp
    engines/kyra/text_lol.h
    engines/kyra/timer_eob.cpp



diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index f7a5460..b190e11 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -169,7 +169,7 @@ bool CharacterGenerator::start(EobCharacter *characters, uint8 ***faceShapes) {
 
 	for (bool loop = true; loop && (!_vm->shouldQuit()); ) {
 		_vm->_gui->updateBoxFrameHighLight(_activeBox + 6);
-		int inputFlag = getInput(_vm->_activeButtons);		
+		int inputFlag = getInput(_vm->_activeButtons);
 		_vm->removeInputTop();
 
 		if (inputFlag) {
@@ -434,7 +434,7 @@ int CharacterGenerator::viewDeleteCharacter() {
 }
 
 void CharacterGenerator::createPartyMember() {
-	_screen->setScreenDim(2);	
+	_screen->setScreenDim(2);
 	assert(_vm->_gui);
 
 	for (int i = 0; i != 3 && !_vm->shouldQuit(); i++) {
diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp
index dd67c3e..abb6a70 100644
--- a/engines/kyra/detection.cpp
+++ b/engines/kyra/detection.cpp
@@ -163,7 +163,7 @@ SaveStateList KyraMetaEngine::listSaves(const char *target) const {
 		// Skip automatic final saves made by EOB for the purpose of party transfer
 		if (!scumm_stricmp(file->c_str() + file->size() - 3, "fin"))
 			continue;
-		
+
 		// Obtain the last 3 digits of the filename, since they correspond to the save slot
 		int slotNum = atoi(file->c_str() + file->size() - 3);
 
diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
index ae24b14..c871189 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -173,7 +173,7 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 	int r = 0;
 	int a = 0;
 	Item itm = 0;
-	
+
 	switch (npcIndex) {
 	case 0:
 		for (r = 1; r == 1; ) {
@@ -199,7 +199,7 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 			}
 			if (!r)
 				r = DLG2(a ? 13 : 4, 4);
-			
+
 			if (!r) {
 				for (a = 0; a < 6; a++)
 					createItemOnCurrentBlock(55);
@@ -230,7 +230,7 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 			if (deletePartyItems(6, -1)) {
 				//_npcSequenceSub = 0;
 				//drawNpcScene(npcIndex);
-				TXT(28);				
+				TXT(28);
 				createItemOnCurrentBlock(32);
 				setScriptFlags(0x100000);
 				r = 1;
@@ -254,7 +254,7 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 					else
 						resurrectionSelectDialogue();
 					setScriptFlags(0x20000);
-				}				
+				}
 			}
 		} else {
 			TXT(24);
@@ -476,7 +476,7 @@ void EobEngine::turnUndeadAuto() {
 	for (int i = 0; i < 6; i++) {
 		if (!testCharacter(i, 0x0d))
 			continue;
-		
+
 		EobCharacter *c = &_characters[i];
 
 		if (_itemTypes[_items[c->inventory[0]].type].extraProperties != 6 && _itemTypes[_items[c->inventory[1]].type].extraProperties != 6)
@@ -553,13 +553,13 @@ void EobEngine::healParty() {
 	for (int i = 0; i < 6 && cnt; i++) {
 		if (testCharacter(i, 3))
 			continue;
-		
+
 		_characters[i].flags &= ~4;
 		neutralizePoison(i);
-		
+
 		if (_characters[i].hitPointsCur >= _characters[i].hitPointsMax)
 			continue;
-		
+
 		cnt--;
 		_characters[i].hitPointsCur += rollDice(1, 8, 9);
 		if (_characters[i].hitPointsCur > _characters[i].hitPointsMax)
diff --git a/engines/kyra/eob1.h b/engines/kyra/eob1.h
index 00583e9..2dfccca 100644
--- a/engines/kyra/eob1.h
+++ b/engines/kyra/eob1.h
@@ -61,7 +61,7 @@ private:
 	void seq_king();
 	void seq_hands();
 	void seq_waterdeepExit();
-	void seq_tunnel();	
+	void seq_tunnel();
 
 	void seq_xdeath();
 
@@ -69,7 +69,7 @@ private:
 	void copyBlurRegion(int x1, int y1, int x2, int y2, int w, int h, int step);
 	void boxMorphTransition(int targetDestX, int targetDestY, int targetFinalX, int targetFinalY, int targetSrcX, int targetSrcY, int targetFinalW, int targetFinalH, int originX1, int originY1, int originW, int originH);
 	void whirlTransition();
-	
+
 	const char *const *_introFilesOpening;
 	const char *const *_introFilesTower;
 	const char *const *_introFilesOrb;
@@ -90,7 +90,7 @@ private:
 	const uint8 *_introTvlY2;
 	const uint8 *_introTvlW;
 	const uint8 *_introTvlH;
-	
+
 	const char *const *_finBonusStrings;
 
 	// characters
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index 60df8f8..64e394a 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -387,7 +387,7 @@ void DarkMoonEngine::restParty_npc() {
 bool DarkMoonEngine::restParty_extraAbortCondition() {
 	if (_currentLevel != 3)
 		return false;
-	
+
 	seq_nightmare();
 
 	return true;
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 389a0e9..dfa465c 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -22,7 +22,7 @@
 
 #ifdef ENABLE_EOB
 
-#include "kyra/loleobbase.h"
+#include "kyra/kyra_rpg.h"
 #include "kyra/resource.h"
 #include "kyra/sound_intern.h"
 #include "kyra/script_eob.h"
@@ -36,7 +36,7 @@
 
 namespace Kyra {
 
-EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBaseEngine(system, flags), _numLargeItemShapes(flags.gameID == GI_EOB1 ? 14 : 11),
+EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : KyraRpgEngine(system, flags), _numLargeItemShapes(flags.gameID == GI_EOB1 ? 14 : 11),
 	_numSmallItemShapes(flags.gameID == GI_EOB1 ? 23 : 26), _numThrownItemShapes(flags.gameID == GI_EOB1 ? 12 : 9), _numItemIconShapes(flags.gameID == GI_EOB1 ? 89 : 112),
 	_teleporterWallId(flags.gameID == GI_EOB1 ? 52 : 44) {
 	_screen = 0;
@@ -164,7 +164,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
 	_monsterProximityTable = _findBlockMonstersTable = _wallOfForceDsY = _wallOfForceDsNumW = _wallOfForceDsNumH = _wallOfForceShpId = _wllFlagPreset = _teleporterShapeCoords = 0;
 		_monsterCloseAttUnkTable = _monsterFrmOffsTable1 = _monsterFrmOffsTable2 = _monsterDirChangeTable = _portalSeq = 0;
 	_wallOfForceDsX = 0;
-	_expObjectAnimTbl1Size = _expObjectAnimTbl2Size = _expObjectAnimTbl3Size = _wllFlagPresetSize = _scriptTimersCount = _buttonList1Size = _buttonList2Size = 
+	_expObjectAnimTbl1Size = _expObjectAnimTbl2Size = _expObjectAnimTbl3Size = _wllFlagPresetSize = _scriptTimersCount = _buttonList1Size = _buttonList2Size =
 		_buttonList3Size = _buttonList4Size = _buttonList5Size = _buttonList6Size = _buttonList7Size = _buttonList8Size = 0;
 	_inventorySlotsY = _mnDef = 0;
 	_buttonDefs = 0;
@@ -310,7 +310,7 @@ Common::Error EobCoreEngine::init() {
 	//MidiDriverType midiDriver = MidiDriver::detectDevice(MDT_PCSPK | MDT_ADLIB);
 	_sound = new SoundAdLibPC(this, _mixer);
 	assert(_sound);
-	_sound->init();	
+	_sound->init();
 
 	syncSoundSettings();
 
@@ -335,7 +335,7 @@ Common::Error EobCoreEngine::init() {
 	setupKeyMap();
 	_gui = new GUI_Eob(this);
 	assert(_gui);
-	_txt = new TextDisplayer_Eob(this, _screen);
+	_txt = new TextDisplayer_rpg(this, _screen);
 	assert(_txt);
 	_inf = new EobInfProcessor(this, _screen);
 	assert(_inf);
@@ -345,7 +345,7 @@ Common::Error EobCoreEngine::init() {
 	_screen->loadFont(Screen::FID_6_FNT, "FONT6.FNT");
 	_screen->loadFont(Screen::FID_8_FNT, "FONT8.FNT");
 
-	Common::Error err = LolEobBaseEngine::init();
+	Common::Error err = KyraRpgEngine::init();
 	if (err.getCode() != Common::kNoError)
 		return err;
 
@@ -522,7 +522,7 @@ void EobCoreEngine::startupNew() {
 }
 
 void EobCoreEngine::runLoop() {
-	_envAudioTimer = _system->getMillis() + (rollDice(1, 10, 3) * 18 * _tickLength);	
+	_envAudioTimer = _system->getMillis() + (rollDice(1, 10, 3) * 18 * _tickLength);
 	_flashShapeTimer = 0;
 	_drawSceneTimer = _system->getMillis();
 
@@ -566,7 +566,7 @@ bool EobCoreEngine::checkPartyStatus(bool handleDeath) {
 
 	if (!handleDeath)
 		return true;
-	
+
 	gui_drawAllCharPortraitsWithStats();
 
 	if (checkPartyStatusExtra()) {
@@ -1172,7 +1172,7 @@ void EobCoreEngine::dropCharacter(int charIndex) {
 		return;
 
 	removeCharacterFromParty(charIndex);
-	
+
 	if (charIndex < 5)
 		exchangeCharacters(charIndex, testCharacter(5, 1) ? 5 : 4);
 
@@ -1439,7 +1439,7 @@ bool EobCoreEngine::restParty_updateMonsters() {
 			return true;
 		}
 	}
-	
+
 	_sound->enableSFX(sfxEnabled);
 	_sound->enableMusic(musicEnabled);
 	return false;
@@ -1468,7 +1468,7 @@ bool EobCoreEngine::restParty_checkHealSpells(int charIndex) {
 	static const uint8 eob2healSpells[] = { 3, 16, 20 };
 	const uint8 *spells = _flags.gameID == GI_EOB1 ? eob1healSpells : eob2healSpells;
 	const int8 *list = _characters[charIndex].clericSpells;
-	
+
 	for (int i = 0; i < 80; i++) {
 		int s = list[i] < 0 ? -list[i] : list[i];
 		if (s == spells[0] || s == spells[1] || s == spells[2])
@@ -1551,7 +1551,7 @@ void EobCoreEngine::displayParchment(int id) {
 
 int EobCoreEngine::countResurrectionCandidates() {
 	_rrCount = 0;
-	memset(_rrNames, 0, 10 * sizeof(const char*));	
+	memset(_rrNames, 0, 10 * sizeof(const char*));
 
 	for (int i = 0; i < 6; i++) {
 		if (!testCharacter(i, 1))
@@ -1646,11 +1646,11 @@ void EobCoreEngine::seq_portal() {
 			if (*(pos - 2) == 3)
 				snd_playSoundEffect(90);
 		}
-		
+
 		_screen->updateScreen();
 		delay(2 * _tickLength);
 	}
-	
+
 	delete[] shape0;
 	for (int i = 0; i < 5; i++) {
 		delete[] shapes1[i];
@@ -1663,12 +1663,12 @@ bool EobCoreEngine::checkPassword() {
 	char answ[20];
 	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
 	_screen->copyPage(0, 10);
-	
+
 	_screen->setScreenDim(13);
 	gui_drawBox(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, _color1_1, _color2_1, -1);
 	gui_drawBox((_screen->_curDim->sx << 3) + 1, _screen->_curDim->sy + 1, (_screen->_curDim->w << 3) - 2, _screen->_curDim->h - 2, _color1_1, _color2_1, _bkgColor_1);
 	_screen->modifyScreenDim(13, _screen->_curDim->sx + 1, _screen->_curDim->sy + 2, _screen->_curDim->w - 2, _screen->_curDim->h - 16);
-	
+
 	for (int i = 0; i < 3; i++) {
 		_screen->fillRect(_screen->_curDim->sx << 3, _screen->_curDim->sy, ((_screen->_curDim->sx + _screen->_curDim->w) << 3) - 1, (_screen->_curDim->sy + _screen->_curDim->h) - 1, _bkgColor_1);
 		int c = rollDice(1, _mnNumWord - 1, -1);
@@ -1678,7 +1678,7 @@ bool EobCoreEngine::checkPassword() {
 		_screen->printShadedText(Common::String::format(_mnPrompt[0], _mnDef[(c << 2) + 1], _mnDef[(c << 2) + 2]).c_str(), (_screen->_curDim->sx + 1) << 3, _screen->_curDim->sy, _screen->_curDim->unk8, _bkgColor_1);
 		memset(answ, 0, 20);
 		gui_drawBox(76, 100, 133, 14, _color2_1, _color1_1, -1);
-		gui_drawBox(77, 101, 131, 12, _color2_1, _color1_1, -1);	
+		gui_drawBox(77, 101, 131, 12, _color2_1, _color1_1, -1);
 		if (_gui->getTextInput(answ, 10, 103, 15, _screen->_curDim->unk8, _bkgColor_1, 8) < 0)
 			i = 3;
 		if (!scumm_stricmp(_mnWord[c], answ))
@@ -1812,7 +1812,7 @@ int EobCoreEngine::projectileWeaponAttack(int charIndex, Item item) {
 			SWAP(ammoItem, _characters[charIndex].inventory[1]);
 		else if (_characters[charIndex].inventory[16])
 			ammoItem = getQueuedItem(&_characters[charIndex].inventory[16], 0, -1);
-		
+
 	} else {
 		for (int i = 0; i < 27; i++) {
 			if (_items[_characters[charIndex].inventory[i]].type == t) {
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 93db0b3..3b12308 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -24,7 +24,7 @@
 #define KYRA_EOBCOMMON_H
 
 #if defined(ENABLE_EOB) || defined(ENABLE_LOL)
-#include "kyra/loleobbase.h"
+#include "kyra/kyra_rpg.h"
 #endif // (ENABLE_EOB || ENABLE_LOL)
 
 #ifdef ENABLE_EOB
@@ -239,8 +239,8 @@ struct EobMenuButtonDef {
 
 class EobInfProcessor;
 
-class EobCoreEngine : public LolEobBaseEngine {
-friend class TextDisplayer_Eob;
+class EobCoreEngine : public KyraRpgEngine {
+friend class TextDisplayer_rpg;
 friend class GUI_Eob;
 friend class EobInfProcessor;
 friend class DarkmoonSequenceHelper;
@@ -328,7 +328,7 @@ protected:
 	static const uint8 _charClassModifier[];
 
 	const uint8 *_classModifierFlags;
-	
+
 	const uint8 *_transferConvertTable;
 	const uint32 *_transferExpTable;
 
@@ -550,7 +550,7 @@ protected:
 	const uint8 *_monsterProximityTable;
 	const uint8 *_findBlockMonstersTable;
 	const char *const *_monsterDustStrings;
-	
+
 	const uint8 *_enemyMageSpellList;
 	const uint8 *_enemyMageSfx;
 	const uint8 *_beholderSpellList;
@@ -798,9 +798,9 @@ protected:
 	const char *const *_validateCursedString;
 	const char *const *_validateNoDropString;
 	const char *const *_potionStrings;
-	const char *const *_wandStrings;	
-	const char *const *_itemMisuseStrings;	
-	
+	const char *const *_wandStrings;
+	const char *const *_itemMisuseStrings;
+
 	const char *const *_suffixStringsRings;
 	const char *const *_suffixStringsPotions;
 	const char *const *_suffixStringsWands;
@@ -832,7 +832,7 @@ protected:
 
 	void seq_portal();
 	bool checkPassword();
-	
+
 	virtual int resurrectionSelectDialogue() = 0;
 	virtual void useHorn(int charIndex, int weaponSlot) {}
 	virtual bool checkPartyStatusExtra() = 0;
@@ -900,7 +900,7 @@ protected:
 	int getDexHitChanceModifier(int charIndex);
 	int getMonsterAcHitChanceModifier(int charIndex, int monsterAc);
 	void explodeMonster(EobMonsterInPlay *m);
-	
+
 	int _dstMonsterIndex;
 	bool _preventMonsterFlash;
 	int16 _foundMonstersArray[5];
@@ -940,7 +940,7 @@ protected:
 	void destroyWallOfForce(int index);
 
 	int findSingleSpellTarget(int dist);
-	
+
 	int findFirstCharacterSpellTarget();
 	int findNextCharacterSpellTarget(int curCharIndex);
 	int charDeathSavingThrow(int charIndex, int div);
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 7d8e925..6d13b17 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -20,12 +20,12 @@
  *
  */
 
-#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+#ifdef ENABLE_EOB
 
 #include "kyra/eobcommon.h"
 #include "kyra/gui_eob.h"
 #include "kyra/script_eob.h"
-#include "kyra/text_eob.h"
+#include "kyra/text_rpg.h"
 #include "kyra/timer.h"
 #include "kyra/util.h"
 
@@ -35,110 +35,6 @@
 
 namespace Kyra {
 
-void LolEobBaseEngine::removeInputTop() {
-	if (!_eventList.empty()) {
-		if (_eventList.begin()->event.type == Common::EVENT_LBUTTONDOWN)
-			_mouseClick = 1;
-		else if (_eventList.begin()->event.type == Common::EVENT_RBUTTONDOWN)
-			_mouseClick = 2;
-		else
-			_mouseClick = 0;
-
-		_eventList.erase(_eventList.begin());
-	}
-}
-
-void LolEobBaseEngine::gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor) {
-	w--; h--;
-	if (fillColor != -1)
-		screen()->fillRect(x + 1, y + 1, x + w - 1, y + h - 1, fillColor);
-
-	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 LolEobBaseEngine::gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32 cur, int32 max, int col1, int col2) {
-	if (max < 1)
-		return;
-	if (cur < 0)
-		cur = 0;
-
-	int32 e = MIN(cur, max);
-
-	if (!--w)
-		return;
-	if (!--h)
-		return;
-
-	int32 t = (e * w) / max;
-
-	if (!t && e)
-		t++;
-
-	if (t)
-		screen()->fillRect(x, y, x + t - 1, y + h, col1);
-
-	if (t < w && col2)
-		screen()->fillRect(x + t, y, x + w, y + h, col2);
-}
-
-void LolEobBaseEngine::gui_initButtonsFromList(const int16 *list) {
-	while (*list != -1)
-		gui_initButton(*list++);
-}
-
-void LolEobBaseEngine::gui_resetButtonList() {
-	for (uint i = 0; i < ARRAYSIZE(_activeButtonData); ++i)
-		_activeButtonData[i].nextButton = 0;
-
-	gui_notifyButtonListChanged();
-	_activeButtons = 0;
-}
-
-void LolEobBaseEngine::gui_notifyButtonListChanged() {
-	if (gui()) {
-		if (!_buttonListChanged && !_preserveEvents)
-			removeInputTop();
-		_buttonListChanged = true;
-	}
-}
-
-bool LolEobBaseEngine::clickedShape(int shapeIndex) {
-	if (_clickedSpecialFlag != 0x40)
-		return true;
-
-	for (; shapeIndex; shapeIndex = _levelDecorationProperties[shapeIndex].next) {
-		if (_flags.gameID != GI_LOL)
-			shapeIndex--;
-
-		uint16 s = _levelDecorationProperties[shapeIndex].shapeIndex[1];
-
-		if (s == 0xffff)
-			continue;
-
-		int w = _flags.gameID == GI_LOL ? _levelDecorationShapes[s][3] : (_levelDecorationShapes[s][2] << 3);
-		int h = _levelDecorationShapes[s][_flags.gameID == GI_LOL ? 2 : 1];
-		int x = _levelDecorationProperties[shapeIndex].shapeX[1] + _clickedShapeXOffs;
-		int y = _levelDecorationProperties[shapeIndex].shapeY[1] + _clickedShapeYOffs;
-
-		if (_levelDecorationProperties[shapeIndex].flags & 1) {
-			if (_flags.gameID == GI_LOL)
-				w <<= 1;
-			else
-				x = 176 - x - w;
-		}
-
-		if (posWithinRect(_mouseX, _mouseY, x - 4, y - 4, x + w + 8, y + h + 8))
-			return true;
-	}
-
-	return false;
-}
-
-#ifdef ENABLE_EOB
-
 Button *EobCoreEngine::gui_getButton(Button *buttonList, int index) {
 	while (buttonList) {
 		if (buttonList->index == index)
@@ -159,7 +55,7 @@ void EobCoreEngine::gui_drawPlayField(bool refresh) {
 
 	_screen->setCurPage(cp);
 	_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
-	
+
 	if (!_loading)
 		_screen->updateScreen();
 
@@ -397,7 +293,7 @@ void EobCoreEngine::gui_drawWeaponSlot(int charIndex, int slot) {
 void EobCoreEngine::gui_drawWeaponSlotStatus(int x, int y, int status) {
 	Common::String tmpStr;
 	Common::String tmpStr2;
-	
+
 	if (status > -3 || status == -5)
 		_screen->drawShape(_screen->_curPage, _greenSplatShape, x - 1, y, 0);
 	else
@@ -507,7 +403,7 @@ void EobCoreEngine::gui_drawFoodStatusGraph(int index) {
 
 void EobCoreEngine::gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32 curVal, int32 maxVal, int col1, int col2) {
 	gui_drawBox(x - 1, y - 1, w + 3, h + 2, _color2_1, _color1_1, -1);
-	LolEobBaseEngine::gui_drawHorizontalBarGraph(x, y, w + 2, h, curVal, maxVal, col1, col2);
+	KyraRpgEngine::gui_drawHorizontalBarGraph(x, y, w + 2, h, curVal, maxVal, col1, col2);
 }
 
 void EobCoreEngine::gui_drawCharPortraitStatusFrame(int index) {
@@ -858,7 +754,7 @@ int EobCoreEngine::clickedCamp(Button *button) {
 
 	_screen->copyPage(0, 7);
 	_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 12, Screen::CR_NO_P_CHECK);
-	
+
 	_gui->runCampMenu();
 
 	_screen->copyRegion(0, 0, 0, 120, 176, 24, 12, 2, Screen::CR_NO_P_CHECK);
@@ -870,7 +766,7 @@ int EobCoreEngine::clickedCamp(Button *button) {
 
 	_screen->setCurPage(0);
 	const ScreenDim *dm = _screen->getScreenDim(10);
-	_screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK);	
+	_screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK);
 
 	_screen->updateScreen();
 
@@ -1457,7 +1353,7 @@ GUI_Eob::GUI_Eob(EobCoreEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) {
 	_progress = 0;
 	_prcButtonUnk3 = 1;
 	_cflag = 0xffff;
-	
+
 	_menuLineSpacing = 0;
 	_menuLastInFlags = 0;
 	_menuCur = 0;
@@ -1471,7 +1367,7 @@ GUI_Eob::GUI_Eob(EobCoreEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) {
 	memset(_numAssignedSpellsOfType, 0, 72);
 
 	_charSelectRedraw = false;
-	
+
 	_updateBoxIndex = -1;
 	_highLightBoxTimer = 0;
 	_updateBoxColorIndex = 0;
@@ -1978,7 +1874,7 @@ int GUI_Eob::processButtonList(Kyra::Button *buttonList, uint16 inputFlags, int8
 
 	if (!result)
 		result = inputFlags;
-	
+
 	return result;
 }
 
@@ -2093,10 +1989,10 @@ void GUI_Eob::simpleMenu_flashSelection(const char *str, int x, int y, int color
 
 void GUI_Eob::runCampMenu() {
 	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
-	
+
 	Button *highlightButton = 0;
 	Button *prevHighlightButton = 0;
-	
+
 	int newMenu = 0;
 	int lastMenu = -1;
 	bool redrawPortraits = false;
@@ -2108,7 +2004,7 @@ void GUI_Eob::runCampMenu() {
 	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
 		if (newMenu == 2)
 			updateOptionsStrings();
-		
+
 		if (newMenu != -1) {
 			releaseButtons(buttonList);
 
@@ -2117,7 +2013,7 @@ void GUI_Eob::runCampMenu() {
 				_vm->_menuDefs[2].titleStrId = 57;
 			else if (newMenu == 1)
 				_vm->_menuDefs[1].titleStrId = 58;
-			
+
 			buttonList = initMenu(newMenu);
 
 			if (newMenu != lastMenu) {
@@ -2128,10 +2024,10 @@ void GUI_Eob::runCampMenu() {
 			lastMenu = newMenu;
 			newMenu = -1;
 		}
-		
+
 		int inputFlag = _vm->checkInput(buttonList, false, 0) & 0x80ff;
 		_vm->removeInputTop();
-		
+
 		if (inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE])
 			inputFlag = 0x8007;
 		else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP5] || inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
@@ -2175,7 +2071,7 @@ void GUI_Eob::runCampMenu() {
 
 				highlightButton = _vm->gui_getButton(buttonList, s);
 			}
-			
+
 		} else if (inputFlag > 0x8000 && inputFlag < 0x8010) {
 			int i = 0;
 			int cnt = 0;
@@ -2284,7 +2180,7 @@ void GUI_Eob::runCampMenu() {
 			}
 
 			lastMenu = -1;
-			
+
 		} else {
 			Common::Point p = _vm->getMousePos();
 			for (Button *b = buttonList; b; b = b->nextButton) {
@@ -2292,7 +2188,7 @@ void GUI_Eob::runCampMenu() {
 					highlightButton = b;
 			}
 		}
-		
+
 		if (_charSelectRedraw || redrawPortraits) {
 			for (int i = 0; i < 6; i++) {
 				_vm->gui_drawCharPortraitWithStats(i);
@@ -2320,10 +2216,10 @@ bool GUI_Eob::runLoadMenu(int x, int y) {
 	int xo = dm->sx;
 	int yo = dm->sy;
 	bool result = false;
-	
+
 	_screen->modifyScreenDim(11, dm->sx + (x >> 3), dm->sy + y, dm->w, dm->h);
-	
-	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {	
+
+	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
 		int slot = selectSaveSlotDialogue(x, y, 1);
 		if (slot > 5) {
 			runLoop = result = false;
@@ -2356,7 +2252,7 @@ bool GUI_Eob::confirmDialogue2(int dim, int id, int deflt) {
 	int16 y = _screen->_curDim->sy + _screen->_curDim->h - 21;
 	int newHighlight = deflt ^ 1;
 	int lastHighlight = -1;
-	
+
 	for (int i = 0; i < 2; i++)
 		drawMenuButtonBox(x[i], y, 32, 14, false, false);
 
@@ -2391,7 +2287,7 @@ bool GUI_Eob::confirmDialogue2(int dim, int id, int deflt) {
 		}
 
 		if (newHighlight != lastHighlight) {
-			for (int i = 0; i < 2; i++)				
+			for (int i = 0; i < 2; i++)
 				_screen->printShadedText(_vm->_menuYesNoStrings[i], x[i] + 16 - (strlen(_vm->_menuYesNoStrings[i]) << 2) + 1, y + 3, i == newHighlight ? 6 : 15, 0);
 			_screen->updateScreen();
 			lastHighlight = newHighlight;
@@ -2407,7 +2303,7 @@ bool GUI_Eob::confirmDialogue2(int dim, int id, int deflt) {
 	_screen->copyRegion(0, _screen->_curDim->h, _screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, 2, 0, Screen::CR_NO_P_CHECK);
 	_screen->setFont(of);
 	_screen->setScreenDim(od);
-	
+
 	return newHighlight ? false : true;
 }
 
@@ -2417,7 +2313,7 @@ void GUI_Eob::messageDialogue2(int dim, int id, int buttonTextCol) {
 	_screen->_curPage = 2;
 	_screen->setClearScreenDim(dim);
 	drawMenuButtonBox(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, false, false);
-	_screen->printShadedText(getMenuString(id), (_screen->_curDim->sx << 3) + 5, _screen->_curDim->sy + 5, 15, 0);	
+	_screen->printShadedText(getMenuString(id), (_screen->_curDim->sx << 3) + 5, _screen->_curDim->sy + 5, 15, 0);
 	_screen->_curPage = 0;
 	_screen->copyRegion(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, 2, 0, Screen::CR_NO_P_CHECK);
 
@@ -2628,10 +2524,10 @@ bool GUI_Eob::runSaveMenu(int x, int y) {
 	int xo = dm->sx;
 	int yo = dm->sy;
 	bool result = false;
-	
+
 	_screen->modifyScreenDim(11, dm->sx + (x >> 3), dm->sy + y, dm->w, dm->h);
-	
-	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {	
+
+	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
 		int slot = selectSaveSlotDialogue(x, y, 0);
 		if (slot > 5) {
 			runLoop = result = false;
@@ -2641,13 +2537,13 @@ bool GUI_Eob::runSaveMenu(int x, int y) {
 				_saveSlotStringsTemp[slot][0] = 0;
 			else
 				useSlot = confirmDialogue2(11, 55, 1);
-			
+
 			if (!useSlot)
 				continue;
 
 			int fx = (x + 1) << 3;
 			int fy = y + slot * 17 + 23;
-			
+
 			for (int in = -1; in == -1 && !_vm->shouldQuit(); ) {
 				_screen->fillRect(fx - 2, fy, fx + 160, fy + 8, _vm->_bkgColor_1);
 				in = getTextInput(_saveSlotStringsTemp[slot], x + 1, fy, 19, 2, 0, 8);
@@ -2665,12 +2561,12 @@ bool GUI_Eob::runSaveMenu(int x, int y) {
 			Common::Error err = _vm->saveGameStateIntern(_savegameOffset + slot, _saveSlotStringsTemp[slot], &thumb);
 			thumb.free();
 
-			if (err.getCode() == Common::kNoError)			
+			if (err.getCode() == Common::kNoError)
 				result = true;
 			else
 				messageDialogue(11, 15, 6);
 
-			runLoop = false;			
+			runLoop = false;
 		}
 	}
 
@@ -2683,7 +2579,7 @@ int GUI_Eob::selectSaveSlotDialogue(int x, int y, int id) {
 
 	_saveSlotX = _saveSlotY = 0;
 	_screen->setCurPage(2);
-	
+
 	updateSaveSlotsList();
 	_savegameOffset = 0;
 
@@ -2701,7 +2597,7 @@ int GUI_Eob::selectSaveSlotDialogue(int x, int y, int id) {
 	int newHighlight = 0;
 	int slot = -1;
 
-	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {		
+	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
 		int inputFlag = _vm->checkInput(0, false, 0) & 0x8ff;
 		_vm->removeInputTop();
 
@@ -2768,7 +2664,7 @@ int GUI_Eob::selectSaveSlotDialogue(int x, int y, int id) {
 		if (lastHighlight != newHighlight) {
 			drawSaveSlotButton(lastHighlight, 0, 15);
 			drawSaveSlotButton(newHighlight, 0, 6);
-			
+
 			// Display highlighted slot index in the bottom left corner to avoid people getting lost with the 990 save slots
 			_screen->setFont(Screen::FID_6_FNT);
 			int sli = (newHighlight == 6) ?  _savegameOffset : (_savegameOffset + newHighlight);
@@ -2798,7 +2694,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
 	uint32 avltyFlags = 0;
 	int li = 0;
 	int lv = 0;
-	
+
 	EobCharacter *c = &_vm->_characters[charIndex];
 	int8 wm = c->wisdomCur - 12;
 	if (wm < 0)
@@ -2806,10 +2702,10 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
 
 	if (spellType) {
 		li = _vm->getCharacterLevelIndex(2, c->cClass);
-		
+
 		if (li == -1) {
 			li = _vm->getCharacterLevelIndex(4, c->cClass);
-			
+
 			if (li != -1) {
 				lv = c->level[li] - 1;
 				if (lv < 0)
@@ -2817,7 +2713,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
 
 				for (int i = 0; i < _numPages; i++)
 					np[i] = _vm->_numSpellsPal[lv * _numPages + i];
-				
+
 				avltyFlags = _paladinSpellAvltyFlags;
 			}
 
@@ -2878,7 +2774,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
 	for (int i = 0; i < 32; i++) {
 		if (!(avltyFlags & (1 << i)))
 			continue;
-		
+
 		int d = lh[i] - 1;
 		if (d < 0)
 			continue;
@@ -2931,7 +2827,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
 
 		if (updateDesc) {
 			updateDesc = false;
-			_screen->printShadedText(Common::String::format(_vm->_menuStringsMgc[1], np[lastHighLightButton] - numAssignedSpellsPerBookPage[lastHighLightButton], np[lastHighLightButton]).c_str(), 8, 38, 9, _vm->_bkgColor_1);		
+			_screen->printShadedText(Common::String::format(_vm->_menuStringsMgc[1], np[lastHighLightButton] - numAssignedSpellsPerBookPage[lastHighLightButton], np[lastHighLightButton]).c_str(), 8, 38, 9, _vm->_bkgColor_1);
 		}
 
 		if (newHighLightText < 0)
@@ -2939,13 +2835,13 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
 
 		if (menuSpellMap[lastHighLightButton * 11] <= newHighLightText)
 			newHighLightText = 0;
-		
+
 		if (newHighLightText != lastHighLightText) {
 			memorizePrayMenuPrintString(menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1], lastHighLightText, spellType, true, false);
 			memorizePrayMenuPrintString(menuSpellMap[lastHighLightButton * 11 + newHighLightText + 1], newHighLightText, spellType, true, true);
 			lastHighLightText = newHighLightText;
 		}
-		
+
 		int inputFlag = _vm->checkInput(buttonList, false, 0) & 0x80ff;
 		_vm->removeInputTop();
 
@@ -2961,7 +2857,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
 				newHighLightText = (p.y - 50 ) / 9;
 				if (menuSpellMap[lastHighLightButton * 11] - 1 < newHighLightText)
 					newHighLightText = menuSpellMap[lastHighLightButton * 11] - 1;
-			}			
+			}
 		}
 
 		if (inputFlag & 0x8000) {
@@ -2999,7 +2895,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
 			newHighLightText = 0;
 		} else if (inputFlag == 0x8017) {
 			if (numAssignedSpellsPerBookPage[lastHighLightButton]) {
-				for (int i = 1; i <= menuSpellMap[lastHighLightButton * 11]; i++) {				
+				for (int i = 1; i <= menuSpellMap[lastHighLightButton * 11]; i++) {
 					numAssignedSpellsPerBookPage[lastHighLightButton] -= _numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + i] * 2 - 2];
 					_numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + i] * 2 - 2] = 0;
 				}
@@ -3087,7 +2983,7 @@ void GUI_Eob::scribeScrollDialogue() {
 	if (numScrolls) {
 		int csel = selectCharacterDialogue(49);
 		if (csel != -1) {
-			
+
 			EobCharacter *c = &_vm->_characters[csel];
 			int s = 0;
 
@@ -3128,7 +3024,7 @@ void GUI_Eob::scribeScrollDialogue() {
 						redraw = false;
 						lastHighLight = -1;
 						newHighLight = 0;
-					}					
+					}
 
 					if (lastHighLight != newHighLight) {
 						if (lastHighLight >= 0)
@@ -3152,7 +3048,7 @@ void GUI_Eob::scribeScrollDialogue() {
 					} else if (inputFlag == 0x8023 || inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE]) {
 						s = 0;
 					} else if (inputFlag == 0x8024) {
-						newHighLight = (_vm->_mouseY - 50) / 9;						
+						newHighLight = (_vm->_mouseY - 50) / 9;
 						if (newHighLight >= 0 && newHighLight < s) {
 							inputFlag = _vm->_keyMap[Common::KEYCODE_SPACE];
 						} else {
@@ -3193,7 +3089,7 @@ bool GUI_Eob::restParty() {
 	static const int8 eob1healSpells[] = { 2, 15, 20, 24 };
 	static const int8 eob2healSpells[] = { 3, 16, 20, 28 };
 	const int8 *spells = _vm->game() == GI_EOB1 ? eob1healSpells : eob2healSpells;
-	
+
 	uint8 crs[6];
 	memset(crs, 0, 6);
 	int hours = 0;
@@ -3243,7 +3139,7 @@ bool GUI_Eob::restParty() {
 				useHealers = confirmDialogue(40);
 				break;
 			}
-		} 
+		}
 	}
 
 	_screen->setClearScreenDim(7);
@@ -3269,14 +3165,14 @@ bool GUI_Eob::restParty() {
 				for (int ii = 0; ii < 80; ii++) {
 					if ((ii / 10 + 48) >= crs[i])
 						break;
-					
+
 					if (*list >= 0) {
 						list++;
 						continue;
 					}
 
 					*list *= -1;
-					crs[i] = 48;					
+					crs[i] = 48;
 					_vm->_txt->printMessage(Common::String::format(_vm->_menuStringsRest2[0], _vm->_characters[i].name, _vm->_spells[_vm->_clericSpellOffset + *list].name).c_str());
 					_vm->delay(80);
 					break;
@@ -3289,14 +3185,14 @@ bool GUI_Eob::restParty() {
 				for (int ii = 0; ii < 80; ii++) {
 					if ((ii / 6 + 48) >= crs[i])
 						break;
-					
+
 					if (*list >= 0) {
 						list++;
 						continue;
 					}
 
 					*list *= -1;
-					crs[i] = 48;					
+					crs[i] = 48;
 					_vm->_txt->printMessage(Common::String::format(_vm->_menuStringsRest2[1], _vm->_characters[i].name, _vm->_spells[*list].name).c_str());
 					_vm->delay(80);
 					break;
@@ -3311,7 +3207,7 @@ bool GUI_Eob::restParty() {
 					continue;
 				if (_vm->checkInventoryForItem(i, 30, -1) == -1)
 					continue;
-				
+
 				list = 0;
 				if (crs[i] >= 48) {
 					for (int ii = 0; !list && ii < 3; ii++)
@@ -3416,7 +3312,7 @@ bool GUI_Eob::restParty() {
 						_vm->gui_drawCharPortraitWithStats(i);
 					}
 				}
-				
+
 				if (starving) {
 					if (!confirmDialogue(47)) {
 						restContinue = false;
@@ -3475,7 +3371,7 @@ bool GUI_Eob::confirmDialogue(int id) {
 	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
 
 	Button *buttonList = initMenu(5);
-	
+
 	_screen->printShadedText(getMenuString(id), (_screen->_curDim->sx + 1) << 3, _screen->_curDim->sy + 4, 15, 0);
 
 	int newHighlight = 0;
@@ -3490,7 +3386,7 @@ bool GUI_Eob::confirmDialogue(int id) {
 			_screen->updateScreen();
 			lastHighlight = newHighlight;
 		}
-		
+
 		int inputFlag = _vm->checkInput(buttonList, false, 0) & 0x80ff;
 		_vm->removeInputTop();
 
@@ -3539,7 +3435,7 @@ void GUI_Eob::messageDialogue(int dim, int id, int buttonTextCol) {
 
 	drawTextBox(dim, id);
 	const ScreenDim *dm = _screen->getScreenDim(dim);
-	
+
 	int bx = ((dm->sx + dm->w) << 3) - ((strlen(_vm->_menuOkString) << 3) + 16);
 	int by = dm->sy + dm->h - 19;
 	int bw = (strlen(_vm->_menuOkString) << 3) + 7;
@@ -3565,7 +3461,7 @@ void GUI_Eob::messageDialogue(int dim, int id, int buttonTextCol) {
 	_vm->_system->delayMillis(80);
 	drawMenuButtonBox(bx, by, bw, 14, false, true);
 	_screen->updateScreen();
-	
+
 	_screen->copyRegion(0, dm->h, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK);
 	_screen->setScreenDim(od);
 	_screen->setFont(of);
@@ -3576,7 +3472,7 @@ int GUI_Eob::selectCharacterDialogue(int id) {
 	uint8 flags = (id == 26) ? (_vm->game() == GI_EOB1 ? 0x04 : 0x14) : 0x02;
 	_vm->removeInputTop();
 
-	_charSelectRedraw = false;	
+	_charSelectRedraw = false;
 	bool abort = false;
 	int count = 0;
 	int result = -1;
@@ -3584,20 +3480,20 @@ int GUI_Eob::selectCharacterDialogue(int id) {
 
 	for (int i = 0; i < 6; i++) {
 		found[i] = -1;
-		
+
 		if (!_vm->testCharacter(i, 1))
 			continue;
-		
+
 		if (!(_vm->_classModifierFlags[_vm->_characters[i].cClass] & flags) && (id != 53))
 			continue;
-		
+
 		if (id != 53 && (!_vm->_characters[i].food || !_vm->testCharacter(i, 4))) {
 			abort = true;
 		} else {
 			found[i] = 0;
 			result = i;
 			count++;
-		} 
+		}
 	}
 
 	if (!count) {
@@ -3627,7 +3523,7 @@ int GUI_Eob::selectCharacterDialogue(int id) {
 		_charSelectRedraw = true;
 	}
 
-	if (count == 1) {		
+	if (count == 1) {
 		int l = _vm->getCharacterLevelIndex(4, _vm->_characters[result].cClass);
 
 		if (l == -1)
@@ -3650,7 +3546,7 @@ int GUI_Eob::selectCharacterDialogue(int id) {
 	while (result == -2 && !_vm->shouldQuit()) {
 		int inputFlag = _vm->checkInput(buttonList, false, 0);
 		_vm->removeInputTop();
-		
+
 		updateBoxFrameHighLight(hlCur);
 
 		if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP8] || inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_a] || inputFlag == _vm->_keyMap[Common::KEYCODE_w]) {
@@ -3757,7 +3653,7 @@ Button *GUI_Eob::initMenu(int id) {
 		const ScreenDim *dm = _screen->getScreenDim(m->dim);
 		_screen->fillRect(dm->sx << 3, dm->sy, ((dm->sx + dm->w) << 3) - 1, (dm->sy + dm->h) - 1, _vm->_bkgColor_1);
 		_screen->setScreenDim(m->dim);
-		drawMenuButtonBox(dm->sx << 3, dm->sy, dm->w << 3, dm->h, false, false);		
+		drawMenuButtonBox(dm->sx << 3, dm->sy, dm->w << 3, dm->h, false, false);
 	}
 
 	_screen->printShadedText(getMenuString(m->titleStrId), 5, 5, m->titleCol, 0);
@@ -3798,7 +3694,7 @@ Button *GUI_Eob::initMenu(int id) {
 void GUI_Eob::drawMenuButton(Button *b, bool clicked, bool highlight, bool noFill) {
 	if (!b)
 		return;
-	
+
 	EobMenuButtonDef *d = (EobMenuButtonDef*)b->extButtonDef;
 
 	if (d->flags & 1)
@@ -3806,7 +3702,7 @@ void GUI_Eob::drawMenuButton(Button *b, bool clicked, bool highlight, bool noFil
 
 	if (d->labelId) {
 		const char *s = getMenuString(d->labelId);
-		
+
 		int xOffs = 4;
 		int yOffs = 3;
 
@@ -3825,7 +3721,7 @@ void GUI_Eob::drawMenuButton(Button *b, bool clicked, bool highlight, bool noFil
 void GUI_Eob::drawMenuButtonBox(int x, int y, int w, int h, bool clicked, bool noFill) {
 	uint8 col1 = _vm->_color1_1;
 	uint8 col2 = _vm->_color2_1;
-	
+
 	if (clicked)
 		col1 = col2 = _vm->_bkgColor_1;
 
@@ -3859,7 +3755,7 @@ void GUI_Eob::drawSaveSlotButton(int slot, int redrawBox, int textCol) {
 		return;
 
 	int x = _saveSlotX + 4;
-	int y = _saveSlotY + slot * 17 + 20;	
+	int y = _saveSlotY + slot * 17 + 20;
 	int w = 167;
 	const char *s = (slot < 6) ?_saveSlotStringsTemp[slot] : _vm->_saveLoadStrings[0];
 
@@ -3867,8 +3763,8 @@ void GUI_Eob::drawSaveSlotButton(int slot, int redrawBox, int textCol) {
 		x = _saveSlotX + 118;
 		y = _saveSlotY + 126;
 		w = 53;
-	} 
-	
+	}
+
 	if (redrawBox)
 		drawMenuButtonBox(x, y, w, 14, (redrawBox - 1) ? true : false, false);
 
@@ -3997,7 +3893,7 @@ void GUI_Eob::setupSaveMenuSlots() {
 int GUI_Eob::getHighlightSlot() {
 	int res = -1;
 	Common::Point p = _vm->getMousePos();
-	
+
 	for (int i = 0; i < 6; i++) {
 		int y = _saveSlotY + i * 17 + 20;
 		if (_vm->posWithinRect(p.x, p.y, _saveSlotX + 4, y, _saveSlotX + 167, y + 14)) {
@@ -4034,7 +3930,7 @@ void GUI_Eob::restParty_updateRestTime(int hours, bool init) {
 	_screen->setCurPage(0);
 	_screen->copyRegion(((_screen->_curDim->sx + 1) << 3) - 1, _screen->_curDim->sy + 20, ((_screen->_curDim->sx + 1) << 3) - 1, _screen->_curDim->sy + 20, 144, 8, 2, 0, Screen::CR_NO_P_CHECK);
 	_screen->updateScreen();
-	
+
 	_vm->delay(160);
 
 	_screen->setScreenDim(od);
@@ -4064,9 +3960,7 @@ const EobRect16 GUI_Eob::_updateBoxFrameHighLights[] = {
 	{ 0x00A3, 0x0068, 0x00C3, 0x0089 }
 };
 
-#endif // ENABLE_EOB
-
 }	// End of namespace Kyra
 
-#endif // defined(ENABLE_EOB) || defined(ENABLE_LOL)
+#endif // ENABLE_EOB
 
diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h
index a0ac509..46d36b9 100644
--- a/engines/kyra/gui_eob.h
+++ b/engines/kyra/gui_eob.h
@@ -56,7 +56,7 @@ public:
 
 	// Non button based menu handling (main menu, character generation)
 	void simpleMenu_setup(int sd, int maxItem, const char *const *strings, int32 menuItemsMask, int unk, int lineSpacing);
-	int simpleMenu_process(int sd, const char *const *strings, void *b, int32 menuItemsMask, int unk);	
+	int simpleMenu_process(int sd, const char *const *strings, void *b, int32 menuItemsMask, int unk);
 
 	// Button based menus (camp menu, load menu)
 	void runCampMenu();
@@ -87,8 +87,8 @@ private:
 	void messageDialogue(int dim, int id, int buttonTextCol);
 	int selectCharacterDialogue(int id);
 	void displayTextBox(int id);
-	
-	Button *initMenu(int id);	
+
+	Button *initMenu(int id);
 	void drawMenuButton(Button *b, bool clicked, bool highlight, bool noFill);
 	void drawMenuButtonBox(int x, int y, int w, int h, bool clicked, bool noFill);
 	void drawTextBox(int dim, int id);
diff --git a/engines/kyra/gui_rpg.cpp b/engines/kyra/gui_rpg.cpp
new file mode 100644
index 0000000..8b2a593
--- /dev/null
+++ b/engines/kyra/gui_rpg.cpp
@@ -0,0 +1,134 @@
+/* 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.
+ *
+ */
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#include "kyra/kyra_rpg.h"
+
+namespace Kyra {
+
+void KyraRpgEngine::removeInputTop() {
+	if (!_eventList.empty()) {
+		if (_eventList.begin()->event.type == Common::EVENT_LBUTTONDOWN)
+			_mouseClick = 1;
+		else if (_eventList.begin()->event.type == Common::EVENT_RBUTTONDOWN)
+			_mouseClick = 2;
+		else
+			_mouseClick = 0;
+
+		_eventList.erase(_eventList.begin());
+	}
+}
+
+void KyraRpgEngine::gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor) {
+	w--; h--;
+	if (fillColor != -1)
+		screen()->fillRect(x + 1, y + 1, x + w - 1, y + h - 1, fillColor);
+
+	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 KyraRpgEngine::gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32 cur, int32 max, int col1, int col2) {
+	if (max < 1)
+		return;
+	if (cur < 0)
+		cur = 0;
+
+	int32 e = MIN(cur, max);
+
+	if (!--w)
+		return;
+	if (!--h)
+		return;
+
+	int32 t = (e * w) / max;
+
+	if (!t && e)
+		t++;
+
+	if (t)
+		screen()->fillRect(x, y, x + t - 1, y + h, col1);
+
+	if (t < w && col2)
+		screen()->fillRect(x + t, y, x + w, y + h, col2);
+}
+
+void KyraRpgEngine::gui_initButtonsFromList(const int16 *list) {
+	while (*list != -1)
+		gui_initButton(*list++);
+}
+
+void KyraRpgEngine::gui_resetButtonList() {
+	for (uint i = 0; i < ARRAYSIZE(_activeButtonData); ++i)
+		_activeButtonData[i].nextButton = 0;
+
+	gui_notifyButtonListChanged();
+	_activeButtons = 0;
+}
+
+void KyraRpgEngine::gui_notifyButtonListChanged() {
+	if (gui()) {
+		if (!_buttonListChanged && !_preserveEvents)
+			removeInputTop();
+		_buttonListChanged = true;
+	}
+}
+
+bool KyraRpgEngine::clickedShape(int shapeIndex) {
+	if (_clickedSpecialFlag != 0x40)
+		return true;
+
+	for (; shapeIndex; shapeIndex = _levelDecorationProperties[shapeIndex].next) {
+		if (_flags.gameID != GI_LOL)
+			shapeIndex--;
+
+		uint16 s = _levelDecorationProperties[shapeIndex].shapeIndex[1];
+
+		if (s == 0xffff)
+			continue;
+
+		int w = _flags.gameID == GI_LOL ? _levelDecorationShapes[s][3] : (_levelDecorationShapes[s][2] << 3);
+		int h = _levelDecorationShapes[s][_flags.gameID == GI_LOL ? 2 : 1];
+		int x = _levelDecorationProperties[shapeIndex].shapeX[1] + _clickedShapeXOffs;
+		int y = _levelDecorationProperties[shapeIndex].shapeY[1] + _clickedShapeYOffs;
+
+		if (_levelDecorationProperties[shapeIndex].flags & 1) {
+			if (_flags.gameID == GI_LOL)
+				w <<= 1;
+			else
+				x = 176 - x - w;
+		}
+
+		if (posWithinRect(_mouseX, _mouseY, x - 4, y - 4, x + w + 8, y + h + 8))
+			return true;
+	}
+
+	return false;
+}
+
+}	// End of namespace Kyra
+
+#endif // defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
index 44f3a7e..454e56a 100644
--- a/engines/kyra/items_eob.cpp
+++ b/engines/kyra/items_eob.cpp
@@ -179,7 +179,7 @@ void EobCoreEngine::deleteBlockItem(uint16 block, int type) {
 		return;
 
 	_levelBlockProperties[block].drawObjects = 0;
-	
+
 	for (uint16 i2 = itm, i = 0; itm != i2 || !i; i++ ) {
 		if (type == _items[itm].type || type == -1) {
 			_items[itm].block = -1;
@@ -224,13 +224,13 @@ int EobCoreEngine::validateInventorySlotForItem(Item item, int charIndex, int sl
 
 int EobCoreEngine::stripPartyItems(int16 itemType, int16 itemValue, int handleValueMode, int numItems) {
 	int itemsLeft = numItems;
-	
+
 	for (bool runloop = true; runloop && itemsLeft; ) {
 		runloop = false;
 		for (int i = 0; i < 6 && itemsLeft; i++) {
 			if (!testCharacter(i, 1))
 				continue;
-			
+
 			for (int ii = 0; ii < 27 && itemsLeft; ii++) {
 				if (ii == 16)
 					continue;
@@ -293,18 +293,18 @@ int EobCoreEngine::itemUsableByCharacter(int charIndex, Item item) {
 int EobCoreEngine::countQueuedItems(Item itemQueue, int16 id, int16 type, int count, int includeFlyingItems) {
 	uint16 o1 = itemQueue;
 	uint16 o2 = o1;
-	
+
 	if (!o1)
 		return 0;
 
 	int res = 0;
-		
+
 	for (bool forceLoop = true; o1 != o2 || forceLoop; o1 = _items[o1].prev) {
 		EobItem *itm = &_items[o1];
 		forceLoop = false;
 		if (id != -1 || type != -1) {
 			if (((id != -1) || (id == -1 && type != itm->type)) && ((type != -1) || (type == -1 && id != o1)))
-				continue;			
+				continue;
 		}
 
 		if (!includeFlyingItems) {
@@ -314,8 +314,8 @@ int EobCoreEngine::countQueuedItems(Item itemQueue, int16 id, int16 type, int co
 
 		if (!count)
 			return o1;
-		
-		res++;		
+
+		res++;
 	}
 
 	return res;
@@ -329,13 +329,13 @@ int EobCoreEngine::getQueuedItem(Item *items, int pos, int id) {
 		return 0;
 
 	EobItem *itm = &_items[o1];
-	
+
 	for (bool forceLoop = true; o1 != o2 || forceLoop; o1 = itm->prev) {
 		itm = &_items[o1];
 		forceLoop = false;
 		if ((id != -1 || (id == -1 && itm->pos != pos)) && id != o1)
 			continue;
-		
+
 		Item n = itm->next;
 		Item p = itm->prev;
 		_items[n].prev = p;
@@ -359,10 +359,10 @@ void EobCoreEngine::printFullItemName(Item item) {
 	const char *nameId = _itemNames[itm->nameId];
 	uint8 f = _itemTypes[itm->type].extraProperties & 0x7f;
 	int8 v = itm->value;
-	
+
 	const char *tstr2 = 0;
 	const char *tstr3 = 0;
-	
+
 	bool correctSuffixCase = false;
 
 	Common::String tmpString;
@@ -422,7 +422,7 @@ void EobCoreEngine::printFullItemName(Item item) {
 				tmpString = nameUnid;
 				break;
 		}
-	
+
 
 		if (tstr3) {
 			if (!tstr2) {
@@ -511,7 +511,7 @@ void EobCoreEngine::eatItemInHand(int charIndex) {
 		gui_drawFoodStatusGraph(charIndex);
 		_screen->updateScreen();
 		snd_playSoundEffect(9);
-	}	
+	}
 }
 
 bool EobCoreEngine::launchObject(int charIndex, Item item, uint16 startBlock, int startPos, int dir, int type) {
@@ -540,7 +540,7 @@ bool EobCoreEngine::launchObject(int charIndex, Item item, uint16 startBlock, in
 	t->attackerId = charIndex;
 	t->callBackIndex = 0;
 
-	snd_playSoundEffect(type == 7 ? 26 : 11);	
+	snd_playSoundEffect(type == 7 ? 26 : 11);
 	return true;
 }
 
@@ -579,7 +579,7 @@ bool EobCoreEngine::updateObjectFlight(EobFlyingObject *fo, int block, int pos)
 			setItemPosition((Item*)&_levelBlockProperties[block].drawObjects, block, fo->item, pos | 4);
 			fo->curBlock = block;
 			fo->curPos = pos;
-			fo->distance--;	
+			fo->distance--;
 			return true;
 
 		} else {
@@ -594,7 +594,7 @@ bool EobCoreEngine::updateObjectFlight(EobFlyingObject *fo, int block, int pos)
 		fo->curBlock = block;
 		fo->curPos = pos;
 		if (fo->distance != 255)
-			fo->distance--;		
+			fo->distance--;
 	}
 	return true;
 }
@@ -653,7 +653,7 @@ void EobCoreEngine::explodeObject(EobFlyingObject *fo, int block, Item item) {
 	int16 x2 = 0;
 
 	setLevelShapesDim(tl, x1, x2, 5);
-	
+
 	if (x2 < x1)
 		return;
 
diff --git a/engines/kyra/kyra_rpg.cpp b/engines/kyra/kyra_rpg.cpp
new file mode 100644
index 0000000..4a0db7b
--- /dev/null
+++ b/engines/kyra/kyra_rpg.cpp
@@ -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.
+ *
+ */
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#include "kyra/kyra_rpg.h"
+#include "kyra/sound.h"
+
+#include "common/system.h"
+
+namespace Kyra {
+
+KyraRpgEngine::KyraRpgEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(system, flags), _numFlyingObjects(_flags.gameID == GI_LOL ? 8 : 10) {
+	_txt = 0;
+	_mouseClick = 0;
+	_preserveEvents = _buttonListChanged = false;
+
+	_sceneXoffset = 0;
+	_sceneShpDim = 5;
+
+	_activeButtons = 0;
+
+	_currentLevel = 0;
+
+	_vmpPtr = 0;
+	_vcnBlocks = 0;
+	_vcfBlocks = 0;
+	_vcnShift = 0;
+	_vcnExpTable = 0;
+	_vmpPtr = 0;
+	_blockBrightness = _wllVcnOffset = 0;
+	_blockDrawingBuffer = 0;
+	_sceneWindowBuffer = 0;
+	_monsterShapes = _monsterPalettes = 0;
+
+	_doorShapes = 0;
+
+	_levelDecorationProperties = 0;
+	_levelDecorationData = 0;
+	_levelDecorationShapes = 0;
+	_decorationCount = 0;
+	_mappedDecorationsCount = 0;
+	memset(_visibleBlockIndex, 0, sizeof(_visibleBlockIndex));
+
+	_lvlShapeTop = _lvlShapeBottom = _lvlShapeLeftRight = 0;
+	_levelBlockProperties = 0;
+	_hasTempDataFlags = 0;
+
+	_wllVmpMap = _specialWallTypes = _wllWallFlags = 0;
+	_wllShapeMap = 0;
+
+	_sceneDrawVarDown = _sceneDrawVarRight = _sceneDrawVarLeft = _wllProcessFlag = 0;
+
+	_currentBlock = 0;
+	_currentDirection = 0;
+	_compassDirection = -1;
+	_updateFlags = _clickedSpecialFlag = 0;
+	_sceneDefaultUpdate = 0;
+	_sceneUpdateRequired = false;
+
+	_flyingObjectsPtr = 0;
+	_flyingObjectStructSize = sizeof(EobFlyingObject);
+
+	_clickedShapeXOffs = _clickedShapeYOffs = 0;
+
+	_dscShapeX = 0;
+	_dscTileIndex = 0;
+	_dscUnk2 = 0;
+	_dscDim1 = 0;
+	_dscDim2 = 0;
+	_dscBlockMap = 0;
+	_dscBlockIndex = 0;
+	_dscShapeIndex = 0;
+	_dscDimMap = 0;
+	_dscDoorShpIndex = 0;
+	_dscDoorY2 = 0;
+
+	_shpDmX1 = _shpDmX2 = 0;
+
+	memset(_openDoorState, 0, sizeof(_openDoorState));
+	memset(_dialogueButtonString, 0, 3 * sizeof(const char *));
+	_dialogueButtonPosX = 0;
+	_dialogueButtonPosY = 0;
+	_dialogueNumButtons = _dialogueButtonYoffs = _dialogueHighlightedButton = 0;
+	_currentControlMode = 0;
+	_specialSceneFlag = 0;
+	_dialogueButtonLabelCol1 = 0;
+	_dialogueButtonLabelCol2 = 0;
+	_dialogueButtonW = 0;
+	_dialogueButtonH = 0;
+	_waitButtonPresX = 0;
+	_waitButtonPresY = 0;
+	_waitButtonPresW = 0;
+	_waitButtonReverveW = 0;
+
+	_updateCharNum = -1;
+	_activeVoiceFileTotalTime = 0;
+	_updatePortraitSpeechAnimDuration = _resetPortraitAfterSpeechAnim = _needSceneRestore = 0;
+	_fadeText = false;
+
+	memset(_lvlTempData, 0, sizeof(_lvlTempData));
+
+	_dialogueField = false;
+
+	_environmentSfx = _environmentSfxVol = _envSfxDistThreshold = 0;
+	_monsterStepCounter = _monsterStepMode = 0;
+}
+
+KyraRpgEngine::~KyraRpgEngine() {
+	delete[] _wllVmpMap;
+	delete[] _wllShapeMap;
+	delete[] _specialWallTypes;
+	delete[] _wllWallFlags;
+
+	delete[] _vmpPtr;
+	delete[] _vcnExpTable;
+	delete[] _vcnBlocks;
+	delete[] _vcfBlocks;
+	delete[] _vcnShift;
+	delete[] _blockDrawingBuffer;
+	delete[] _sceneWindowBuffer;
+
+	delete[] _lvlShapeTop;
+	delete[] _lvlShapeBottom;
+	delete[] _lvlShapeLeftRight;
+
+	delete[] _doorShapes;
+
+	delete[] _levelDecorationShapes;
+	delete[] _levelDecorationData;
+	delete[] _levelDecorationProperties;
+	delete[] _levelBlockProperties;
+}
+
+Common::Error KyraRpgEngine::init() {
+	gui_resetButtonList();
+
+	_levelDecorationProperties = new LevelDecorationProperty[100];
+	memset(_levelDecorationProperties, 0, 100 * sizeof(LevelDecorationProperty));
+	_levelDecorationShapes = new uint8*[400];
+	memset(_levelDecorationShapes, 0, 400 * sizeof(uint8*));
+	_levelBlockProperties = new LevelBlockProperty[1025];
+	memset(_levelBlockProperties, 0, 1025 * sizeof(LevelBlockProperty));
+
+	_wllVmpMap = new uint8[256];
+	memset(_wllVmpMap, 0, 256);
+	_wllShapeMap = new int8[256];
+	memset(_wllShapeMap, 0, 256);
+	_specialWallTypes = new uint8[256];
+	memset(_specialWallTypes, 0, 256);
+	_wllWallFlags = new uint8[256];
+	memset(_wllWallFlags, 0, 256);
+
+	_blockDrawingBuffer = new uint16[1320];
+	memset(_blockDrawingBuffer, 0, 1320 * sizeof(uint16));
+	_sceneWindowBuffer = new uint8[21120];
+	memset(_sceneWindowBuffer, 0, 21120);
+
+	_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));
+
+	_vcnExpTable = new uint8[128];
+	for (int i = 0; i < 128; i++)
+		_vcnExpTable[i] = i & 0x0f;
+
+	_doorShapes = new uint8*[6];
+	memset(_doorShapes, 0, 6 * sizeof(uint8*));
+
+	initStaticResource();
+
+	_envSfxDistThreshold = (_sound->getSfxType() == Sound::kAdLib || _sound->getSfxType() == Sound::kPCSpkr) ? 15 : 3;
+
+	return Common::kNoError;
+}
+
+bool KyraRpgEngine::posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2) {
+	if (posX < x1 || posX > x2 || posY < y1 || posY > y2)
+		return false;
+	return true;
+}
+
+void KyraRpgEngine::drawDialogueButtons() {
+	int cp = screen()->setCurPage(0);
+	Screen::FontId of = screen()->setFont(gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : Screen::FID_6_FNT);
+
+	for (int i = 0; i < _dialogueNumButtons; i++) {
+		int x = _dialogueButtonPosX[i];
+		if (gameFlags().use16ColorMode) {
+			gui_drawBox(x, ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) & ~7) - 1, 74, 10, 0xee, 0xcc, -1);
+			screen()->printText(_dialogueButtonString[i], (x + 37 - (screen()->getTextWidth(_dialogueButtonString[i])) / 2) & ~3,
+				((_dialogueButtonYoffs + _dialogueButtonPosY[i]) + 2) & ~7, _dialogueHighlightedButton == i ? 0xc1 : 0xe1, 0);
+		} else {
+			gui_drawBox(x, (_dialogueButtonYoffs + _dialogueButtonPosY[i]), _dialogueButtonW, _dialogueButtonH, _color1_1, _color2_1, _bkgColor_1);
+			screen()->printText(_dialogueButtonString[i], x + (_dialogueButtonW >> 1) - (screen()->getTextWidth(_dialogueButtonString[i])) / 2,
+				(_dialogueButtonYoffs + _dialogueButtonPosY[i]) + 2, _dialogueHighlightedButton == i ? _dialogueButtonLabelCol1 : _dialogueButtonLabelCol2, 0);
+		}
+	}
+	screen()->setFont(of);
+	screen()->setCurPage(cp);
+}
+
+uint16 KyraRpgEngine::processDialogue() {
+	int df = _dialogueHighlightedButton;
+	int res = 0;
+
+	for (int i = 0; i < _dialogueNumButtons; i++) {
+		int x = _dialogueButtonPosX[i];
+		int y = (gameFlags().use16ColorMode ? ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) & ~7) - 1 : (_dialogueButtonYoffs + _dialogueButtonPosY[i]));
+		Common::Point p = getMousePos();
+		if (posWithinRect(p.x, p.y, x, y, x + _dialogueButtonW, y + _dialogueButtonH)) {
+			_dialogueHighlightedButton = i;
+			break;
+		}
+	}
+
+	if (_dialogueNumButtons == 0) {
+		int e = checkInput(0, false) & 0xFF;
+		removeInputTop();
+
+		if (e) {
+			gui_notifyButtonListChanged();
+
+			if (e == _keyMap[Common::KEYCODE_SPACE] || e == _keyMap[Common::KEYCODE_RETURN]) {
+				snd_stopSpeech(true);
+			}
+		}
+
+		if (snd_updateCharacterSpeech() != 2) {
+				res = 1;
+				if (!shouldQuit()) {
+					removeInputTop();
+					gui_notifyButtonListChanged();
+				}
+		}
+	} else {
+		int e = checkInput(0, false, 0) & 0xFF;
+		removeInputTop();
+		if (e)
+			gui_notifyButtonListChanged();
+
+		if ((_flags.gameID == GI_LOL && (e == 200 || e == 202)) || (_flags.gameID != GI_LOL && (e == 199 || e == 201))) {
+			for (int i = 0; i < _dialogueNumButtons; i++) {
+				int x = _dialogueButtonPosX[i];
+				int y = (gameFlags().use16ColorMode ? ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) & ~7) - 1 : (_dialogueButtonYoffs + _dialogueButtonPosY[i]));
+				Common::Point p = getMousePos();
+				if (posWithinRect(p.x, p.y, x, y, x + _dialogueButtonW, y + _dialogueButtonH)) {
+					_dialogueHighlightedButton = i;
+					res = _dialogueHighlightedButton + 1;
+					break;
+				}
+			}
+		} else if (e == _keyMap[Common::KEYCODE_SPACE] || e == _keyMap[Common::KEYCODE_RETURN]) {
+			snd_stopSpeech(true);
+			res = _dialogueHighlightedButton + 1;
+		} else if (e == _keyMap[Common::KEYCODE_LEFT] || e == _keyMap[Common::KEYCODE_DOWN]) {
+			if (_dialogueNumButtons > 1 && _dialogueHighlightedButton > 0)
+				_dialogueHighlightedButton--;
+		} else if (e == _keyMap[Common::KEYCODE_RIGHT] || e == _keyMap[Common::KEYCODE_UP]) {
+			if (_dialogueNumButtons > 1 && _dialogueHighlightedButton < (_dialogueNumButtons - 1))
+				_dialogueHighlightedButton++;
+		}
+	}
+
+	if (df != _dialogueHighlightedButton)
+		drawDialogueButtons();
+
+	screen()->updateScreen();
+
+	if (res == 0)
+		return 0;
+
+	stopPortraitSpeechAnim();
+
+	if (game() == GI_LOL) {
+		if (!textEnabled() && _currentControlMode) {
+			screen()->setScreenDim(5);
+			const ScreenDim *d = screen()->getScreenDim(5);
+			screen()->fillRect(d->sx, d->sy + d->h - 9, d->sx + d->w - 1, d->sy + d->h - 1, d->unkA);
+		} else {
+			const ScreenDim *d = screen()->_curDim;
+			if (gameFlags().use16ColorMode)
+				screen()->fillRect(d->sx, d->sy, d->sx + d->w - 3, d->sy + d->h - 2, d->unkA);
+			else
+				screen()->fillRect(d->sx, d->sy, d->sx + d->w - 2, d->sy + d->h - 1, d->unkA);
+			txt()->clearDim(4);
+			txt()->resetDimTextPositions(4);
+		}
+	}
+
+	return res;
+}
+
+void KyraRpgEngine::delayUntil(uint32 time, bool doUpdate, bool isMainLoop) {
+	uint32 curTime = _system->getMillis();
+	if (time > curTime)
+		delay(time - curTime, doUpdate, isMainLoop);
+}
+
+int KyraRpgEngine::rollDice(int times, int pips, int inc) {
+	if (times <= 0 || pips <= 0)
+		return inc;
+
+	int res = 0;
+	while (times--)
+		res += _rnd.getRandomNumberRng(1, pips);
+
+	return res + inc;
+}
+
+bool KyraRpgEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) {
+	if (!_sound->sfxEnabled() || shouldQuit())
+		return false;
+
+	if (_environmentSfx)
+		snd_playSoundEffect(_environmentSfx, _environmentSfxVol);
+
+	int dist = 0;
+	if (block) {
+		dist = getBlockDistance(_currentBlock, block);
+		if (dist > _envSfxDistThreshold) {
+			_environmentSfx = 0;
+			return false;
+		}
+	}
+
+	_environmentSfx = soundId;
+	_environmentSfxVol = (15 - ((block || (_flags.gameID == GI_LOL && dist < 2)) ? dist : 0)) << 4;
+
+	return true;
+}
+
+void KyraRpgEngine::updateEnvironmentalSfx(int soundId) {
+	snd_processEnvironmentalSoundEffect(soundId, _currentBlock);
+}
+
+}	// End of namespace Kyra
+
+#endif // ENABLE_EOB || ENABLE_LOL
diff --git a/engines/kyra/kyra_rpg.h b/engines/kyra/kyra_rpg.h
new file mode 100644
index 0000000..9acc6ff
--- /dev/null
+++ b/engines/kyra/kyra_rpg.h
@@ -0,0 +1,355 @@
+/* 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.
+ *
+ */
+
+#ifndef KYRA_RPG_H
+#define KYRA_RPG_H
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#include "kyra/kyra_v1.h"
+#include "kyra/screen_eob.h"
+#include "kyra/gui_eob.h"
+#include "kyra/text_lol.h"
+
+namespace Kyra {
+
+struct LevelDecorationProperty {
+	uint16 shapeIndex[10];
+	uint8 scaleFlag[10];
+	int16 shapeX[10];
+	int16 shapeY[10];
+	int8 next;
+	uint8 flags;
+};
+
+struct LevelBlockProperty {
+	uint8 walls[4];
+	uint16 assignedObjects;
+	uint16 drawObjects;
+	uint8 direction;
+	uint16 flags;
+};
+
+struct OpenDoorState {
+	uint16 block;
+	int8 wall;
+	int8 state;
+};
+
+struct LevelTempData {
+	uint8 *wallsXorData;
+	uint16 *flags;
+	void *monsters;
+	void *flyingObjects;
+	void *wallsOfForce;
+	uint8 monsterDifficulty;
+};
+
+struct EobFlyingObject {
+	uint8 enable;
+	uint8 objectType;
+	int16 attackerId;
+	Item item;
+	uint16 curBlock;
+	uint16 u2;
+	uint8 u1;
+	uint8 direction;
+	uint8 distance;
+	int8 callBackIndex;
+	uint8 curPos;
+	uint8 flags;
+	uint8 unused;
+};
+
+class KyraRpgEngine : public KyraEngine_v1 {
+friend class TextDisplayer_rpg;
+public:
+	KyraRpgEngine(OSystem *system, const GameFlags &flags);
+	virtual ~KyraRpgEngine();
+
+	virtual Screen *screen() = 0;
+	virtual GUI *gui() const = 0;
+
+protected:
+	// Startup
+	virtual Common::Error init();
+	virtual Common::Error go() = 0;
+
+	// Init
+	void initStaticResource();
+
+	const uint8 **_itemIconShapes;
+
+	// Main loop
+	virtual void update() = 0;
+	void updateEnvironmentalSfx(int soundId);
+
+	// timers
+	virtual void setupTimers() = 0;
+	void enableSysTimer(int sysTimer);
+	void disableSysTimer(int sysTimer);
+	void enableTimer(int id);
+	virtual uint8 getClock2Timer(int index) = 0;
+	virtual uint8 getNumClock2Timers() = 0;
+
+	void timerProcessDoors(int timerNum);
+
+	// mouse
+	bool posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2);
+	virtual void setHandItem(Item itemIndex) = 0;
+
+	// Characters
+	int _updateCharNum;
+	int _updatePortraitSpeechAnimDuration;
+	bool _fadeText;
+	int _resetPortraitAfterSpeechAnim;
+	int _needSceneRestore;
+
+	// Items
+	int _itemInHand;
+
+	// Monsters
+	int getBlockDistance(uint16 block1, uint16 block2);
+
+	uint8 **_monsterPalettes;
+	uint8 **_monsterShapes;
+
+	int16 _shpDmX1;
+	int16 _shpDmX2;
+
+	int _monsterStepCounter;
+	int _monsterStepMode;
+
+	// Level
+	virtual void addLevelItems() = 0;
+	virtual void loadBlockProperties(const char *file) = 0;
+
+	virtual void drawScene(int pageNum) = 0;
+	virtual void drawSceneShapes(int start) = 0;
+	virtual void drawDecorations(int index) = 0;
+
+	virtual const uint8 *getBlockFileData(int levelIndex) = 0;
+	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 generateBlockDrawingBuffer();
+	void generateVmpTileData(int16 startBlockX, uint8 startBlockY, uint8 wllVmpIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY);
+	void generateVmpTileDataFlipped(int16 startBlockX, uint8 startBlockY, uint8 wllVmpIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY);
+	bool hasWall(int index);
+	void assignVisibleBlocks(int block, int direction);
+	bool checkSceneUpdateNeed(int block);
+	void drawVcnBlocks();
+	uint16 calcNewBlockPosition(uint16 curBlock, uint16 direction);
+
+	virtual int clickedDoorSwitch(uint16 block, uint16 direction) = 0;
+	int clickedWallShape(uint16 block, uint16 direction);
+	int clickedLeverOn(uint16 block, uint16 direction);
+	int clickedLeverOff(uint16 block, uint16 direction);
+	int clickedWallOnlyScript(uint16 block);
+	virtual int clickedNiche(uint16 block, uint16 direction) = 0;
+
+	void processDoorSwitch(uint16 block, int openClose);
+	void openCloseDoor(int block, int openClose);
+	void completeDoorOperations();
+
+	uint8 *_wllVmpMap;
+	int8 *_wllShapeMap;
+	uint8 *_specialWallTypes;
+	uint8 *_wllWallFlags;
+
+	int _sceneXoffset;
+	int _sceneShpDim;
+
+	LevelBlockProperty *_levelBlockProperties;
+	LevelBlockProperty *_visibleBlocks[18];
+	LevelDecorationProperty *_levelDecorationData;
+	uint16 _levelDecorationDataSize;
+	LevelDecorationProperty *_levelDecorationProperties;
+	uint8 **_levelDecorationShapes;
+	uint16 _decorationCount;
+	int16 _mappedDecorationsCount;
+	uint16 *_vmpPtr;
+	uint8 *_vcnBlocks;
+	uint8 *_vcfBlocks;
+	uint8 *_vcnShift;
+	uint8 *_vcnExpTable;
+	uint16 *_blockDrawingBuffer;
+	uint8 *_sceneWindowBuffer;
+	uint8 _blockBrightness;
+	uint8 _wllVcnOffset;
+
+	uint8 **_doorShapes;
+
+	uint8 _currentLevel;
+	uint16 _currentBlock;
+	uint16 _currentDirection;
+	int _sceneDefaultUpdate;
+	bool _sceneUpdateRequired;
+
+	int16 _visibleBlockIndex[18];
+	int16 *_lvlShapeLeftRight;
+	int16 *_lvlShapeTop;
+	int16 *_lvlShapeBottom;
+
+	char _lastBlockDataFile[13];
+	uint32 _hasTempDataFlags;
+
+	int16 _sceneDrawVarDown;
+	int16 _sceneDrawVarRight;
+	int16 _sceneDrawVarLeft;
+	int _wllProcessFlag;
+
+	OpenDoorState _openDoorState[3];
+
+	int _sceneDrawPage1;
+	int _sceneDrawPage2;
+
+	const int8 *_dscShapeIndex;
+	const uint8 *_dscDimMap;
+	const int8 *_dscDim1;
+	const int8 *_dscDim2;
+	const int16 *_dscShapeX;
+	const uint8 *_dscUnk2;
+	const uint8 *_dscBlockMap;
+	const int8 *_dscBlockIndex;
+	const uint8 *_dscTileIndex;
+
+	const uint8 *_dscDoorShpIndex;
+	int _dscDoorShpIndexSize;
+	const uint8 *_dscDoorY2;
+
+	// Script
+	virtual void runLevelScript(int block, int flags) = 0;
+
+	// Gui
+	void removeInputTop();
+	void gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor);
+	virtual void gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32 curVal, int32 maxVal, int col1, int col2);
+	void gui_initButtonsFromList(const int16 *list);
+	virtual void gui_initButton(int index, int x = -1, int y = -1, int val = -1) = 0;
+	void gui_resetButtonList();
+	void gui_notifyButtonListChanged();
+
+	bool clickedShape(int shapeIndex);
+
+	int _clickedShapeXOffs;
+	int _clickedShapeYOffs;
+
+	Button *_activeButtons;
+	Button _activeButtonData[70];
+	Common::Array<Button::Callback> _buttonCallbacks;
+	//bool _processingButtons;
+
+	uint8 _mouseClick;
+	bool _preserveEvents;
+	bool _buttonListChanged;
+
+	int _updateFlags;
+	int _clickedSpecialFlag;
+
+	int _compassDirection;
+
+	static const uint8 _dropItemDirIndex[];
+
+	// text
+	void drawDialogueButtons();
+	uint16 processDialogue();
+
+	TextDisplayer_rpg *_txt;
+	virtual TextDisplayer_rpg *txt() { return _txt; }
+
+	bool _dialogueField;
+
+	const char *_dialogueButtonString[9];
+	const uint16 *_dialogueButtonPosX;
+	const uint8 *_dialogueButtonPosY;
+	int16 _dialogueButtonYoffs;
+	uint16 _dialogueButtonW;
+	uint16 _dialogueButtonH;
+	const uint16 *_waitButtonPresX;
+	const uint8 *_waitButtonPresY;
+	const uint16 *_waitButtonPresW;
+	int _waitButtonReverveW;
+	int _dialogueNumButtons;
+	int _dialogueHighlightedButton;
+	int _currentControlMode;
+	int _specialSceneFlag;
+	uint8 _dialogueButtonLabelCol1;
+	uint8 _dialogueButtonLabelCol2;
+
+	int _bkgColor_1;
+	uint8 _color1_1;
+	uint8 _color2_1;
+
+	const char *const *_moreStrings;
+
+	// misc
+	virtual void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false) = 0;
+	void delayUntil(uint32 time, bool doUpdate = false, bool isMainLoop = false);
+	int rollDice(int times, int pips, int inc = 0);
+
+	virtual Common::Error loadGameState(int slot) = 0;
+	virtual Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) = 0;
+
+	void generateTempData();
+	virtual void restoreBlockTempData(int levelIndex);
+	void releaseTempData();
+	virtual void *generateMonsterTempData(LevelTempData *tmp) = 0;
+	virtual void restoreMonsterTempData(LevelTempData *tmp) = 0;
+	virtual void releaseMonsterTempData(LevelTempData *tmp) = 0;
+	void restoreFlyingObjectTempData(LevelTempData *tmp);
+	void *generateFlyingObjectTempData(LevelTempData *tmp);
+	void releaseFlyingObjectTempData(LevelTempData *tmp);
+	virtual void *generateWallOfForceTempData(LevelTempData *tmp) { return 0; }
+	virtual void restoreWallOfForceTempData(LevelTempData *tmp) {}
+	virtual void releaseWallOfForceTempData(LevelTempData *tmp) {}
+
+	LevelTempData *_lvlTempData[29];
+	const int _numFlyingObjects;
+	uint32 _flyingObjectStructSize;
+	void *_flyingObjectsPtr;
+
+	// sound
+	virtual bool snd_processEnvironmentalSoundEffect(int soundId, int block);
+	virtual void snd_stopSpeech(bool) {}
+	virtual int snd_updateCharacterSpeech() { return 0; }
+	virtual void stopPortraitSpeechAnim() {}
+	virtual void setupOpcodeTable() {}
+	virtual void snd_playVoiceFile(int) {}
+
+	int _environmentSfx;
+	int _environmentSfxVol;
+	int _envSfxDistThreshold;
+
+	uint32 _activeVoiceFileTotalTime;
+
+	// unused
+	void setWalkspeed(uint8) {}
+	void removeHandItem() {}
+	bool lineIsPassable(int, int) { return false; }
+};
+
+}	// End of namespace Kyra
+
+#endif // ENABLE_EOB || ENABLE_LOL
+
+#endif
\ No newline at end of file
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index a8dfeb5..8561b5e 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -42,7 +42,7 @@ namespace Kyra {
 
 const char *const LoLEngine::kKeymapName = "lol";
 
-LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : LolEobBaseEngine(system, flags) {
+LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraRpgEngine(system, flags) {
 	_screen = 0;
 	_gui = 0;
 	_tim = 0;
@@ -154,9 +154,9 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : LolEobBaseEngine
 	_dscWalls = 0;
 	_dscOvlMap = 0;
 	_dscShapeScaleW = 0;
-	_dscShapeScaleH = 0;	
+	_dscShapeScaleH = 0;
 	_dscShapeY = 0;
-	_dscShapeOvlIndex = 0;	
+	_dscShapeOvlIndex = 0;
 	_dscDoorMonsterX = _dscDoorMonsterY = 0;
 	_dscDoor4 = 0;
 
@@ -409,8 +409,8 @@ Common::Error LoLEngine::init() {
 	if (!_sound->init())
 		error("Couldn't init sound");
 
-	LolEobBaseEngine::init();
-	
+	KyraRpgEngine::init();
+
 	_wllAutomapData = new uint8[80];
 	memset(_wllAutomapData, 0, 80);
 
@@ -1091,7 +1091,7 @@ int LoLEngine::decodeCyrillic(const char *src, char *dst) {
 			assert(cChar < sizeof(decodeTable2));
 			cChar = decodeTable2[cChar];
 		} else if (cChar >= 0x70) {
-			cChar = *src++;			
+			cChar = *src++;
 		} else if (cChar >= 0x30) {
 			if (cChar < 0x60)
 				cChar -= 0x30;
@@ -1929,7 +1929,7 @@ void LoLEngine::setupDialogueButtons(int numStr, const char *s1, const char *s2,
 		_dialogueButtonString[1] = s2;
 		_dialogueButtonString[2] = s3;
 		_dialogueHighlightedButton = 0;
-		
+
 		const ScreenDim *d = screen()->getScreenDim(5);
 
 		static uint16 posX[3];
@@ -1945,8 +1945,8 @@ void LoLEngine::setupDialogueButtons(int numStr, const char *s1, const char *s2,
 		} else {
 			int xOffs = d->w / numStr;
 			posX[0] = d->sx + (xOffs >> 1) - 37;
-			posX[1] = posX[0] + xOffs; 
-			posX[2] = posX[1] + xOffs;		
+			posX[1] = posX[0] + xOffs;
+			posX[2] = posX[1] + xOffs;
 		}
 
 		drawDialogueButtons();
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index 7bd6768..dabc141 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -25,7 +25,7 @@
 #ifndef KYRA_LOL_H
 #define KYRA_LOL_H
 
-#include "kyra/loleobbase.h"
+#include "kyra/kyra_rpg.h"
 #include "kyra/script_tim.h"
 #include "kyra/script.h"
 #include "kyra/gui_lol.h"
@@ -265,7 +265,7 @@ struct MistOfDoomAnimData {
 	uint8 sound;
 };
 
-class LoLEngine : public LolEobBaseEngine {
+class LoLEngine : public KyraRpgEngine {
 friend class GUI_LoL;
 friend class TextDisplayer_LoL;
 friend class TIMInterpreter_LoL;
@@ -577,7 +577,7 @@ private:
 	void setupDialogueButtons(int numStr, const char *s1, const char *s2, const char *s3);
 
 	TextDisplayer_LoL *_txt;
-	TextDisplayer_Eob *txt() { return _txt; }
+	TextDisplayer_rpg *txt() { return _txt; }
 
 	// emc scripts
 	void runInitScript(const char *filename, int optionalFunc);
diff --git a/engines/kyra/loleobbase.cpp b/engines/kyra/loleobbase.cpp
deleted file mode 100644
index bcab278..0000000
--- a/engines/kyra/loleobbase.cpp
+++ /dev/null
@@ -1,361 +0,0 @@
-/* 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.
- *
- */
-
-#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
-
-#include "kyra/loleobbase.h"
-#include "kyra/sound.h"
-
-#include "common/system.h"
-
-namespace Kyra {
-
-LolEobBaseEngine::LolEobBaseEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(system, flags), _numFlyingObjects(_flags.gameID == GI_LOL ? 8 : 10) {
-	_txt = 0;
-	_mouseClick = 0;
-	_preserveEvents = _buttonListChanged = false;
-
-	_sceneXoffset = 0;
-	_sceneShpDim = 5;
-	
-	_activeButtons = 0;
-
-	_currentLevel = 0;
-
-	_vmpPtr = 0;
-	_vcnBlocks = 0;
-	_vcfBlocks = 0;
-	_vcnShift = 0;
-	_vcnExpTable = 0;
-	_vmpPtr = 0;
-	_blockBrightness = _wllVcnOffset = 0;
-	_blockDrawingBuffer = 0;
-	_sceneWindowBuffer = 0;
-	_monsterShapes = _monsterPalettes = 0;
-
-	_doorShapes = 0;
-
-	_levelDecorationProperties = 0;
-	_levelDecorationData = 0;
-	_levelDecorationShapes = 0;
-	_decorationCount = 0;
-	_mappedDecorationsCount = 0;
-	memset(_visibleBlockIndex, 0, sizeof(_visibleBlockIndex));
-
-	_lvlShapeTop = _lvlShapeBottom = _lvlShapeLeftRight = 0;
-	_levelBlockProperties = 0;
-	_hasTempDataFlags = 0;
-
-	_wllVmpMap = _specialWallTypes = _wllWallFlags = 0;
-	_wllShapeMap = 0;
-
-	_sceneDrawVarDown = _sceneDrawVarRight = _sceneDrawVarLeft = _wllProcessFlag = 0;
-
-	_currentBlock = 0;
-	_currentDirection = 0;
-	_compassDirection = -1;
-	_updateFlags = _clickedSpecialFlag = 0;
-	_sceneDefaultUpdate = 0;
-	_sceneUpdateRequired = false;
-	
-	_flyingObjectsPtr = 0;
-	_flyingObjectStructSize = sizeof(EobFlyingObject);
-
-	_clickedShapeXOffs = _clickedShapeYOffs = 0;
-
-	_dscShapeX = 0;
-	_dscTileIndex = 0;
-	_dscUnk2 = 0;
-	_dscDim1 = 0;
-	_dscDim2 = 0;
-	_dscBlockMap = 0;
-	_dscBlockIndex = 0;
-	_dscShapeIndex = 0;
-	_dscDimMap = 0;
-	_dscDoorShpIndex = 0;
-	_dscDoorY2 = 0;
-
-	_shpDmX1 = _shpDmX2 = 0;
-
-	memset(_openDoorState, 0, sizeof(_openDoorState));
-	memset(_dialogueButtonString, 0, 3 * sizeof(const char *));
-	_dialogueButtonPosX = 0;
-	_dialogueButtonPosY = 0;
-	_dialogueNumButtons = _dialogueButtonYoffs = _dialogueHighlightedButton = 0;
-	_currentControlMode = 0;
-	_specialSceneFlag = 0;
-	_dialogueButtonLabelCol1 = 0;
-	_dialogueButtonLabelCol2 = 0;
-	_dialogueButtonW = 0;
-	_dialogueButtonH = 0;
-	_waitButtonPresX = 0;
-	_waitButtonPresY = 0;
-	_waitButtonPresW = 0;
-	_waitButtonReverveW = 0;
-
-	_updateCharNum = -1;
-	_activeVoiceFileTotalTime = 0;
-	_updatePortraitSpeechAnimDuration = _resetPortraitAfterSpeechAnim = _needSceneRestore = 0;
-	_fadeText = false;
-
-	memset(_lvlTempData, 0, sizeof(_lvlTempData));
-
-	_dialogueField = false;
-
-	_environmentSfx = _environmentSfxVol = _envSfxDistThreshold = 0;
-	_monsterStepCounter = _monsterStepMode = 0;
-}
-
-LolEobBaseEngine::~LolEobBaseEngine() {
-	delete[] _wllVmpMap;
-	delete[] _wllShapeMap;
-	delete[] _specialWallTypes;
-	delete[] _wllWallFlags;
-
-	delete[] _vmpPtr;
-	delete[] _vcnExpTable;
-	delete[] _vcnBlocks;
-	delete[] _vcfBlocks;
-	delete[] _vcnShift;
-	delete[] _blockDrawingBuffer;
-	delete[] _sceneWindowBuffer;
-
-	delete[] _lvlShapeTop;
-	delete[] _lvlShapeBottom;
-	delete[] _lvlShapeLeftRight;
-
-	delete[] _doorShapes;
-
-	delete[] _levelDecorationShapes;
-	delete[] _levelDecorationData;
-	delete[] _levelDecorationProperties;
-	delete[] _levelBlockProperties;
-}
-
-Common::Error LolEobBaseEngine::init() {
-	gui_resetButtonList();
-
-	_levelDecorationProperties = new LevelDecorationProperty[100];
-	memset(_levelDecorationProperties, 0, 100 * sizeof(LevelDecorationProperty));
-	_levelDecorationShapes = new uint8*[400];
-	memset(_levelDecorationShapes, 0, 400 * sizeof(uint8*));
-	_levelBlockProperties = new LevelBlockProperty[1025];
-	memset(_levelBlockProperties, 0, 1025 * sizeof(LevelBlockProperty));
-
-	_wllVmpMap = new uint8[256];
-	memset(_wllVmpMap, 0, 256);
-	_wllShapeMap = new int8[256];
-	memset(_wllShapeMap, 0, 256);
-	_specialWallTypes = new uint8[256];
-	memset(_specialWallTypes, 0, 256);
-	_wllWallFlags = new uint8[256];
-	memset(_wllWallFlags, 0, 256);
-
-	_blockDrawingBuffer = new uint16[1320];
-	memset(_blockDrawingBuffer, 0, 1320 * sizeof(uint16));
-	_sceneWindowBuffer = new uint8[21120];
-	memset(_sceneWindowBuffer, 0, 21120);
-
-	_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));
-
-	_vcnExpTable = new uint8[128];
-	for (int i = 0; i < 128; i++)
-		_vcnExpTable[i] = i & 0x0f;
-
-	_doorShapes = new uint8*[6];
-	memset(_doorShapes, 0, 6 * sizeof(uint8*));
-
-	initStaticResource();
-
-	_envSfxDistThreshold = (_sound->getSfxType() == Sound::kAdLib || _sound->getSfxType() == Sound::kPCSpkr) ? 15 : 3;
-
-	return Common::kNoError;
-}
-
-bool LolEobBaseEngine::posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2) {
-	if (posX < x1 || posX > x2 || posY < y1 || posY > y2)
-		return false;
-	return true;
-}
-
-void LolEobBaseEngine::drawDialogueButtons() {
-	int cp = screen()->setCurPage(0);
-	Screen::FontId of = screen()->setFont(gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : Screen::FID_6_FNT);
-
-	for (int i = 0; i < _dialogueNumButtons; i++) {
-		int x = _dialogueButtonPosX[i];
-		if (gameFlags().use16ColorMode) {
-			gui_drawBox(x, ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) & ~7) - 1, 74, 10, 0xee, 0xcc, -1);
-			screen()->printText(_dialogueButtonString[i], (x + 37 - (screen()->getTextWidth(_dialogueButtonString[i])) / 2) & ~3,
-				((_dialogueButtonYoffs + _dialogueButtonPosY[i]) + 2) & ~7, _dialogueHighlightedButton == i ? 0xc1 : 0xe1, 0);
-		} else {
-			gui_drawBox(x, (_dialogueButtonYoffs + _dialogueButtonPosY[i]), _dialogueButtonW, _dialogueButtonH, _color1_1, _color2_1, _bkgColor_1);
-			screen()->printText(_dialogueButtonString[i], x + (_dialogueButtonW >> 1) - (screen()->getTextWidth(_dialogueButtonString[i])) / 2,
-				(_dialogueButtonYoffs + _dialogueButtonPosY[i]) + 2, _dialogueHighlightedButton == i ? _dialogueButtonLabelCol1 : _dialogueButtonLabelCol2, 0);
-		}
-	}
-	screen()->setFont(of);
-	screen()->setCurPage(cp);
-}
-
-uint16 LolEobBaseEngine::processDialogue() {
-	int df = _dialogueHighlightedButton;
-	int res = 0;
-
-	for (int i = 0; i < _dialogueNumButtons; i++) {
-		int x = _dialogueButtonPosX[i];
-		int y = (gameFlags().use16ColorMode ? ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) & ~7) - 1 : (_dialogueButtonYoffs + _dialogueButtonPosY[i]));
-		Common::Point p = getMousePos();
-		if (posWithinRect(p.x, p.y, x, y, x + _dialogueButtonW, y + _dialogueButtonH)) {
-			_dialogueHighlightedButton = i;
-			break;
-		}
-	}
-
-	if (_dialogueNumButtons == 0) {
-		int e = checkInput(0, false) & 0xFF;
-		removeInputTop();
-
-		if (e) {
-			gui_notifyButtonListChanged();
-
-			if (e == _keyMap[Common::KEYCODE_SPACE] || e == _keyMap[Common::KEYCODE_RETURN]) {
-				snd_stopSpeech(true);
-			}
-		}
-
-		if (snd_updateCharacterSpeech() != 2) {
-				res = 1;
-				if (!shouldQuit()) {
-					removeInputTop();
-					gui_notifyButtonListChanged();
-				}
-		}
-	} else {
-		int e = checkInput(0, false, 0) & 0xFF;
-		removeInputTop();
-		if (e)
-			gui_notifyButtonListChanged();
-
-		if ((_flags.gameID == GI_LOL && (e == 200 || e == 202)) || (_flags.gameID != GI_LOL && (e == 199 || e == 201))) {
-			for (int i = 0; i < _dialogueNumButtons; i++) {
-				int x = _dialogueButtonPosX[i];
-				int y = (gameFlags().use16ColorMode ? ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) & ~7) - 1 : (_dialogueButtonYoffs + _dialogueButtonPosY[i]));
-				Common::Point p = getMousePos();
-				if (posWithinRect(p.x, p.y, x, y, x + _dialogueButtonW, y + _dialogueButtonH)) {
-					_dialogueHighlightedButton = i;
-					res = _dialogueHighlightedButton + 1;
-					break;
-				}
-			}
-		} else if (e == _keyMap[Common::KEYCODE_SPACE] || e == _keyMap[Common::KEYCODE_RETURN]) {
-			snd_stopSpeech(true);
-			res = _dialogueHighlightedButton + 1;
-		} else if (e == _keyMap[Common::KEYCODE_LEFT] || e == _keyMap[Common::KEYCODE_DOWN]) {
-			if (_dialogueNumButtons > 1 && _dialogueHighlightedButton > 0)
-				_dialogueHighlightedButton--;
-		} else if (e == _keyMap[Common::KEYCODE_RIGHT] || e == _keyMap[Common::KEYCODE_UP]) {
-			if (_dialogueNumButtons > 1 && _dialogueHighlightedButton < (_dialogueNumButtons - 1))
-				_dialogueHighlightedButton++;
-		}
-	}
-
-	if (df != _dialogueHighlightedButton)
-		drawDialogueButtons();
-
-	screen()->updateScreen();
-
-	if (res == 0)
-		return 0;
-
-	stopPortraitSpeechAnim();
-
-	if (game() == GI_LOL) {
-		if (!textEnabled() && _currentControlMode) {
-			screen()->setScreenDim(5);
-			const ScreenDim *d = screen()->getScreenDim(5);
-			screen()->fillRect(d->sx, d->sy + d->h - 9, d->sx + d->w - 1, d->sy + d->h - 1, d->unkA);
-		} else {
-			const ScreenDim *d = screen()->_curDim;
-			if (gameFlags().use16ColorMode)
-				screen()->fillRect(d->sx, d->sy, d->sx + d->w - 3, d->sy + d->h - 2, d->unkA);
-			else
-				screen()->fillRect(d->sx, d->sy, d->sx + d->w - 2, d->sy + d->h - 1, d->unkA);
-			txt()->clearDim(4);
-			txt()->resetDimTextPositions(4);
-		}
-	}
-
-	return res;
-}
-
-void LolEobBaseEngine::delayUntil(uint32 time, bool doUpdate, bool isMainLoop) {
-	uint32 curTime = _system->getMillis();
-	if (time > curTime)
-		delay(time - curTime, doUpdate, isMainLoop);
-}
-
-int LolEobBaseEngine::rollDice(int times, int pips, int inc) {
-	if (times <= 0 || pips <= 0)
-		return inc;
-
-	int res = 0;
-	while (times--)
-		res += _rnd.getRandomNumberRng(1, pips);
-
-	return res + inc;
-}
-
-bool LolEobBaseEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) {
-	if (!_sound->sfxEnabled() || shouldQuit())
-		return false;
-
-	if (_environmentSfx)
-		snd_playSoundEffect(_environmentSfx, _environmentSfxVol);
-
-	int dist = 0;
-	if (block) {
-		dist = getBlockDistance(_currentBlock, block);
-		if (dist > _envSfxDistThreshold) {
-			_environmentSfx = 0;
-			return false;
-		}
-	}
-
-	_environmentSfx = soundId;
-	_environmentSfxVol = (15 - ((block || (_flags.gameID == GI_LOL && dist < 2)) ? dist : 0)) << 4;
-
-	return true;
-}
-
-void LolEobBaseEngine::updateEnvironmentalSfx(int soundId) {
-	snd_processEnvironmentalSoundEffect(soundId, _currentBlock);
-}
-
-}	// End of namespace Kyra
-
-#endif // ENABLE_EOB || ENABLE_LOL
diff --git a/engines/kyra/loleobbase.h b/engines/kyra/loleobbase.h
deleted file mode 100644
index 06d0688..0000000
--- a/engines/kyra/loleobbase.h
+++ /dev/null
@@ -1,355 +0,0 @@
-/* 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.
- *
- */
-
-#ifndef KYRA_LOLEOBBASE_H
-#define KYRA_LOLEOBBASE_H
-
-#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
-
-#include "kyra/kyra_v1.h"
-#include "kyra/screen_eob.h"
-#include "kyra/gui_eob.h"
-#include "kyra/text_lol.h"
-
-namespace Kyra {
-
-struct LevelDecorationProperty {
-	uint16 shapeIndex[10];
-	uint8 scaleFlag[10];
-	int16 shapeX[10];
-	int16 shapeY[10];
-	int8 next;
-	uint8 flags;
-};
-
-struct LevelBlockProperty {
-	uint8 walls[4];
-	uint16 assignedObjects;
-	uint16 drawObjects;
-	uint8 direction;
-	uint16 flags;
-};
-
-struct OpenDoorState {
-	uint16 block;
-	int8 wall;
-	int8 state;
-};
-
-struct LevelTempData {
-	uint8 *wallsXorData;
-	uint16 *flags;
-	void *monsters;
-	void *flyingObjects;
-	void *wallsOfForce;
-	uint8 monsterDifficulty;
-};
-
-struct EobFlyingObject {
-	uint8 enable;
-	uint8 objectType;
-	int16 attackerId;
-	Item item;	
-	uint16 curBlock;
-	uint16 u2;
-	uint8 u1;
-	uint8 direction;
-	uint8 distance;
-	int8 callBackIndex;
-	uint8 curPos;
-	uint8 flags;
-	uint8 unused;
-};
-
-class LolEobBaseEngine : public KyraEngine_v1 {
-friend class TextDisplayer_Eob;
-public:
-	LolEobBaseEngine(OSystem *system, const GameFlags &flags);
-	virtual ~LolEobBaseEngine();
-
-	virtual Screen *screen() = 0;
-	virtual GUI *gui() const = 0;
-
-protected:
-	// Startup
-	virtual Common::Error init();
-	virtual Common::Error go() = 0;
-
-	// Init
-	void initStaticResource();
-
-	const uint8 **_itemIconShapes;
-
-	// Main loop
-	virtual void update() = 0;
-	void updateEnvironmentalSfx(int soundId);
-
-	// timers
-	virtual void setupTimers() = 0;
-	void enableSysTimer(int sysTimer);
-	void disableSysTimer(int sysTimer);
-	void enableTimer(int id);
-	virtual uint8 getClock2Timer(int index) = 0;
-	virtual uint8 getNumClock2Timers() = 0;
-
-	void timerProcessDoors(int timerNum);
-
-	// mouse
-	bool posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2);
-	virtual void setHandItem(Item itemIndex) = 0;
-
-	// Characters
-	int _updateCharNum;
-	int _updatePortraitSpeechAnimDuration;
-	bool _fadeText;
-	int _resetPortraitAfterSpeechAnim;
-	int _needSceneRestore;
-
-	// Items
-	int _itemInHand;
-
-	// Monsters
-	int getBlockDistance(uint16 block1, uint16 block2);
-
-	uint8 **_monsterPalettes;
-	uint8 **_monsterShapes;
-
-	int16 _shpDmX1;
-	int16 _shpDmX2;
-
-	int _monsterStepCounter;
-	int _monsterStepMode;
-
-	// Level
-	virtual void addLevelItems() = 0;
-	virtual void loadBlockProperties(const char *file) = 0;
-
-	virtual void drawScene(int pageNum) = 0;
-	virtual void drawSceneShapes(int start) = 0;
-	virtual void drawDecorations(int index) = 0;
-
-	virtual const uint8 *getBlockFileData(int levelIndex) = 0;
-	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 generateBlockDrawingBuffer();
-	void generateVmpTileData(int16 startBlockX, uint8 startBlockY, uint8 wllVmpIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY);
-	void generateVmpTileDataFlipped(int16 startBlockX, uint8 startBlockY, uint8 wllVmpIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY);
-	bool hasWall(int index);
-	void assignVisibleBlocks(int block, int direction);
-	bool checkSceneUpdateNeed(int block);
-	void drawVcnBlocks();
-	uint16 calcNewBlockPosition(uint16 curBlock, uint16 direction);
-
-	virtual int clickedDoorSwitch(uint16 block, uint16 direction) = 0;
-	int clickedWallShape(uint16 block, uint16 direction);
-	int clickedLeverOn(uint16 block, uint16 direction);
-	int clickedLeverOff(uint16 block, uint16 direction);
-	int clickedWallOnlyScript(uint16 block);
-	virtual int clickedNiche(uint16 block, uint16 direction) = 0;
-
-	void processDoorSwitch(uint16 block, int openClose);
-	void openCloseDoor(int block, int openClose);
-	void completeDoorOperations();
-
-	uint8 *_wllVmpMap;
-	int8 *_wllShapeMap;
-	uint8 *_specialWallTypes;
-	uint8 *_wllWallFlags;
-
-	int _sceneXoffset;
-	int _sceneShpDim;
-
-	LevelBlockProperty *_levelBlockProperties;
-	LevelBlockProperty *_visibleBlocks[18];
-	LevelDecorationProperty *_levelDecorationData;
-	uint16 _levelDecorationDataSize;
-	LevelDecorationProperty *_levelDecorationProperties;
-	uint8 **_levelDecorationShapes;
-	uint16 _decorationCount;
-	int16 _mappedDecorationsCount;
-	uint16 *_vmpPtr;
-	uint8 *_vcnBlocks;
-	uint8 *_vcfBlocks;
-	uint8 *_vcnShift;
-	uint8 *_vcnExpTable;
-	uint16 *_blockDrawingBuffer;
-	uint8 *_sceneWindowBuffer;
-	uint8 _blockBrightness;
-	uint8 _wllVcnOffset;
-
-	uint8 **_doorShapes;
-
-	uint8 _currentLevel;
-	uint16 _currentBlock;
-	uint16 _currentDirection;
-	int _sceneDefaultUpdate;
-	bool _sceneUpdateRequired;
-
-	int16 _visibleBlockIndex[18];
-	int16 *_lvlShapeLeftRight;
-	int16 *_lvlShapeTop;
-	int16 *_lvlShapeBottom;
-
-	char _lastBlockDataFile[13];
-	uint32 _hasTempDataFlags;
-
-	int16 _sceneDrawVarDown;
-	int16 _sceneDrawVarRight;
-	int16 _sceneDrawVarLeft;
-	int _wllProcessFlag;
-
-	OpenDoorState _openDoorState[3];
-
-	int _sceneDrawPage1;
-	int _sceneDrawPage2;
-
-	const int8 *_dscShapeIndex;
-	const uint8 *_dscDimMap;
-	const int8 *_dscDim1;
-	const int8 *_dscDim2;
-	const int16 *_dscShapeX;
-	const uint8 *_dscUnk2;
-	const uint8 *_dscBlockMap;
-	const int8 *_dscBlockIndex;
-	const uint8 *_dscTileIndex;
-
-	const uint8 *_dscDoorShpIndex;
-	int _dscDoorShpIndexSize;
-	const uint8 *_dscDoorY2;
-
-	// Script
-	virtual void runLevelScript(int block, int flags) = 0;
-
-	// Gui
-	void removeInputTop();
-	void gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor);
-	virtual void gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32 curVal, int32 maxVal, int col1, int col2);
-	void gui_initButtonsFromList(const int16 *list);
-	virtual void gui_initButton(int index, int x = -1, int y = -1, int val = -1) = 0;
-	void gui_resetButtonList();
-	void gui_notifyButtonListChanged();
-
-	bool clickedShape(int shapeIndex);
-
-	int _clickedShapeXOffs;
-	int _clickedShapeYOffs;
-
-	Button *_activeButtons;
-	Button _activeButtonData[70];
-	Common::Array<Button::Callback> _buttonCallbacks;
-	//bool _processingButtons;
-
-	uint8 _mouseClick;
-	bool _preserveEvents;
-	bool _buttonListChanged;
-
-	int _updateFlags;
-	int _clickedSpecialFlag;
-
-	int _compassDirection;
-
-	static const uint8 _dropItemDirIndex[];
-
-	// text
-	void drawDialogueButtons();
-	uint16 processDialogue();
-
-	TextDisplayer_Eob *_txt;
-	virtual TextDisplayer_Eob *txt() { return _txt; }
-
-	bool _dialogueField;
-
-	const char *_dialogueButtonString[9];
-	const uint16 *_dialogueButtonPosX;
-	const uint8 *_dialogueButtonPosY;
-	int16 _dialogueButtonYoffs;
-	uint16 _dialogueButtonW;
-	uint16 _dialogueButtonH;
-	const uint16 *_waitButtonPresX;
-	const uint8 *_waitButtonPresY;
-	const uint16 *_waitButtonPresW;
-	int _waitButtonReverveW;
-	int _dialogueNumButtons;
-	int _dialogueHighlightedButton;
-	int _currentControlMode;
-	int _specialSceneFlag;
-	uint8 _dialogueButtonLabelCol1;
-	uint8 _dialogueButtonLabelCol2;
-
-	int _bkgColor_1;
-	uint8 _color1_1;
-	uint8 _color2_1;
-
-	const char *const *_moreStrings;
-
-	// misc
-	virtual void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false) = 0;
-	void delayUntil(uint32 time, bool doUpdate = false, bool isMainLoop = false);
-	int rollDice(int times, int pips, int inc = 0);
-
-	virtual Common::Error loadGameState(int slot) = 0;
-	virtual Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) = 0;
-
-	void generateTempData();
-	virtual void restoreBlockTempData(int levelIndex);
-	void releaseTempData();
-	virtual void *generateMonsterTempData(LevelTempData *tmp) = 0;
-	virtual void restoreMonsterTempData(LevelTempData *tmp) = 0;
-	virtual void releaseMonsterTempData(LevelTempData *tmp) = 0;
-	void restoreFlyingObjectTempData(LevelTempData *tmp);
-	void *generateFlyingObjectTempData(LevelTempData *tmp);
-	void releaseFlyingObjectTempData(LevelTempData *tmp);
-	virtual void *generateWallOfForceTempData(LevelTempData *tmp) { return 0; }
-	virtual void restoreWallOfForceTempData(LevelTempData *tmp) {}
-	virtual void releaseWallOfForceTempData(LevelTempData *tmp) {}
-
-	LevelTempData *_lvlTempData[29];
-	const int _numFlyingObjects;
-	uint32 _flyingObjectStructSize;
-	void *_flyingObjectsPtr;
-
-	// sound
-	virtual bool snd_processEnvironmentalSoundEffect(int soundId, int block);
-	virtual void snd_stopSpeech(bool) {}
-	virtual int snd_updateCharacterSpeech() { return 0; }
-	virtual void stopPortraitSpeechAnim() {}
-	virtual void setupOpcodeTable() {}
-	virtual void snd_playVoiceFile(int) {}
-
-	int _environmentSfx;
-	int _environmentSfxVol;
-	int _envSfxDistThreshold;
-
-	uint32 _activeVoiceFileTotalTime;
-
-	// unused
-	void setWalkspeed(uint8) {}
-	void removeHandItem() {}
-	bool lineIsPassable(int, int) { return false; }
-};
-
-}	// End of namespace Kyra
-
-#endif // ENABLE_EOB || ENABLE_LOL
-
-#endif
\ No newline at end of file
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 21bb10a..e3428fb 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -158,7 +158,7 @@ void EobCoreEngine::useWand(int charIndex, int weaponSlot) {
 		uint16 bl2 = calcNewBlockPosition(bl1, _currentDirection);
 		snd_playSoundEffect(98);
 		sparkEffectOffensive();
-		
+
 		if ((_wllWallFlags[_levelBlockProperties[bl2].walls[_currentDirection ^ 2]] & 4) && !(_levelBlockProperties[bl2].flags & 7) && (_levelBlockProperties[bl1].flags & 7)) {
 			for (int i = 0; i < 30; i++) {
 				if (_monsters[i].block != bl1)
@@ -574,9 +574,9 @@ bool EobCoreEngine::magicObjectStatusHit(EobMonsterInPlay *m, int type, bool try
 
 	if (trySavingThrow(m, 0, p->level, mod, 6))
 		return false;
-	
+
 	int para = 0;
-		
+
 	switch (type) {
 	case 0:
 	case 1:
@@ -631,7 +631,7 @@ bool EobCoreEngine::turnUndeadHit(EobMonsterInPlay *m, int hitChance, int caster
 		m->mode = 0;
 		m->flags |= 8;
 		m->spellStatusLeft = 40;
-		m->dir = (getNextMonsterDirection(m->block, _currentBlock) ^ 4) >> 1;	
+		m->dir = (getNextMonsterDirection(m->block, _currentBlock) ^ 4) >> 1;
 	}
 
 	return true;
@@ -647,7 +647,7 @@ void EobCoreEngine::causeWounds(int dcTimes, int dcPips, int dcOffs) {
 		if (d != -1) {
 			if (!characterAttackHitTest(_openBookChar, d, 0, 1))
 				return;
-			
+
 			if (dcTimes == -1) {
 				dcOffs = _monsters[d].hitPointsMax - rollDice(1, 4);
 				dcTimes = dcPips = 0;
@@ -802,7 +802,7 @@ void EobCoreEngine::spellCallback_start_burningHands() {
 		drawBlockObject(i & 1, 0, _firebeamShapes[(5 - i) >> 1], bX[i], bY[i], 0);
 	_screen->updateScreen();
 	delay(2 * _tickLength);
-	
+
 	int cl = getMageLevel(_openBookChar);
 	int bl = calcNewBlockPosition(_currentBlock, _currentDirection);
 
@@ -915,7 +915,7 @@ void EobCoreEngine::spellCallback_start_holdPerson() {
 bool EobCoreEngine::spellCallback_end_holdPerson(void *obj) {
 	EobFlyingObject *fo = (EobFlyingObject*)obj;
 	bool res = false;
-	
+
 	if (_flags.gameID == GI_EOB2 && fo->curBlock == _currentBlock) {
 		// party hit
 		int numChar = rollDice(1, 4, 0);
@@ -1011,7 +1011,7 @@ void EobCoreEngine::spellCallback_start_removeCurse() {
 
 void EobCoreEngine::spellCallback_start_coneOfCold() {
 	const int8 *dirTables[] = { _coneOfColdDest1, _coneOfColdDest2, _coneOfColdDest3, _coneOfColdDest4 };
-	
+
 	int cl = getMageLevel(_openBookChar);
 
 	_screen->setCurPage(2);
@@ -1022,11 +1022,11 @@ void EobCoreEngine::spellCallback_start_coneOfCold() {
 	disableSysTimer(2);
 	_screen->drawVortex(150, 50, 10, 1, 100, _coneOfColdGfxTbl, _coneOfColdGfxTblSize);
 	enableSysTimer(2);
-	
+
 	const int8 *tbl = dirTables[_currentDirection];
 	_preventMonsterFlash = true;
 
-	for (int i = 0; i < 7; i++) {		
+	for (int i = 0; i < 7; i++) {
 		for (const int16 *m = findBlockMonsters((_currentBlock + tbl[i]) & 0x3ff, 4, _currentDirection, 1, 1); *m != -1; m++)
 			calcAndInflictMonsterDamage(&_monsters[*m], cl, 4, cl, 0x41, 5, 0);
 	}
@@ -1265,12 +1265,12 @@ void EobCoreEngine::spellCallback_start_turnUndead() {
 	uint16 bl = calcNewBlockPosition(_currentBlock, _currentDirection);
 	if (!(_levelBlockProperties[bl].flags & 7))
 		return;
-	
+
 	int cl = _openBookCasterLevel ? _openBookCasterLevel : getClericPaladinLevel(_openBookChar);
 	int r = rollDice(1, 20);
 	bool hit = false;
 
-	for (const int16 *m = findBlockMonsters(bl, 4, 4, 1, 1); *m != -1; m++) {		
+	for (const int16 *m = findBlockMonsters(bl, 4, 4, 1, 1); *m != -1; m++) {
 		if ((_monsterProps[_monsters[*m].type].typeFlags & 4) && !(_monsters[*m].flags & 0x10)) {
 			_preventMonsterFlash = true;
 			_monsters[*m].flags |= 0x10;
@@ -1333,7 +1333,7 @@ bool EobCoreEngine::spellCallback_end_monster_disintegrate(void *obj) {
 	EobFlyingObject *fo = (EobFlyingObject*)obj;
 	if (fo->curBlock != _currentBlock)
 		return false;
-	
+
 	int d = findFirstCharacterSpellTarget();
 	if (d != -1) {
 		if (!charDeathSavingThrow(d, 1)) {
@@ -1363,7 +1363,7 @@ bool EobCoreEngine::spellCallback_end_monster_fleshToStone(void *obj) {
 	EobFlyingObject *fo = (EobFlyingObject*)obj;
 	if (fo->curBlock != _currentBlock)
 		return false;
-	
+
 	int d = findFirstCharacterSpellTarget();
 	while (d != -1) {
 		if (!charDeathSavingThrow(d, 2)) {
@@ -1373,7 +1373,7 @@ bool EobCoreEngine::spellCallback_end_monster_fleshToStone(void *obj) {
 			d = findNextCharacterSpellTarget(d);
 		}
 	}
-	
+
 	return true;
 }
 
diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk
index 6eed6da..23aee52 100644
--- a/engines/kyra/module.mk
+++ b/engines/kyra/module.mk
@@ -74,14 +74,14 @@ MODULE_OBJS := \
 	wsamovie.o
 
 KYRARPG_COMMON_OBJ = \
-	gui_eob.o \
-	loleobbase.o \
-	saveload_eob.o \
-	scene_eob.o \
-	sprites_eob.o \
-	staticres_eob.o \
-	text_eob.o \
-	timer_eob.o
+	gui_rpg.o \
+	kyra_rpg.o \
+	saveload_rpg.o \
+	scene_rpg.o \
+	sprites_rpg.o \
+	staticres_rpg.o \
+	text_rpg.o \
+	timer_rpg.o
 
 ifdef ENABLE_LOL
 MODULE_OBJS += \
@@ -111,12 +111,18 @@ MODULE_OBJS += \
 	eobcommon.o \
 	eob1.o \
 	eob2.o \
+	gui_eob.o \
 	items_eob.o \
 	magic_eob.o \
+	saveload_eob.o \
+	scene_eob.o \
 	screen_eob.o \
 	script_eob.o \
 	sequences_eob1.o \
-	sequences_eob2.o
+	sequences_eob2.o \
+	sprites_eob.o \
+	staticres_eob.o \
+	timer_eob.o
 endif
 
 # This module can be built as a plugin
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index ec89fca..091b320 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -20,9 +20,8 @@
  *
  */
 
-#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+#ifdef ENABLE_EOB
 
-#include "kyra/eobcommon.h"
 #include "kyra/resource.h"
 #include "kyra/script_eob.h"
 
@@ -32,99 +31,6 @@
 
 namespace Kyra {
 
-void LolEobBaseEngine::generateTempData() {
-	int l = _currentLevel - 1;
-	if (_lvlTempData[l]) {
-		delete[] _lvlTempData[l]->wallsXorData;
-		delete[] _lvlTempData[l]->flags;
-		releaseMonsterTempData(_lvlTempData[l]);
-		releaseFlyingObjectTempData(_lvlTempData[l]);
-		releaseWallOfForceTempData(_lvlTempData[l]);
-		delete _lvlTempData[l];
-	}
-
-	_lvlTempData[l] = new LevelTempData;
-
-	_lvlTempData[l]->wallsXorData = new uint8[4096];
-	_lvlTempData[l]->flags = new uint16[1024];
-
-	const uint8 *p = getBlockFileData(_currentLevel);
-	uint16 len = READ_LE_UINT16(p + 4);
-	p += 6;
-
-	memset(_lvlTempData[l]->wallsXorData, 0, 4096);
-	memset(_lvlTempData[l]->flags, 0, 1024 * sizeof(uint16));
-	uint8 *d = _lvlTempData[l]->wallsXorData;
-	uint16 *df = _lvlTempData[l]->flags;
-
-	for (int i = 0; i < 1024; i++) {
-		for (int ii = 0; ii < 4; ii++)
-			*d++ = p[i * len + ii] ^ _levelBlockProperties[i].walls[ii];
-		*df++ = _levelBlockProperties[i].flags;
-	}
-
-	_lvlTempData[l]->monsters = generateMonsterTempData(_lvlTempData[l]);
-	_lvlTempData[l]->flyingObjects = generateFlyingObjectTempData(_lvlTempData[l]);
-	_lvlTempData[l]->wallsOfForce = generateWallOfForceTempData(_lvlTempData[l]);
-
-	_hasTempDataFlags |= (1 << l);
-}
-
-void LolEobBaseEngine::restoreBlockTempData(int levelIndex) {
-	int l = levelIndex - 1;
-	const uint8 *p = getBlockFileData(levelIndex);
-	uint16 len = READ_LE_UINT16(p + 4);
-	p += 6;
-
-	memset(_levelBlockProperties, 0, 1024 * sizeof(LevelBlockProperty));
-
-	uint8 *t = _lvlTempData[l]->wallsXorData;
-	uint16 *t2 = _lvlTempData[l]->flags;
-
-	for (int i = 0; i < 1024; i++) {
-		for (int ii = 0; ii < 4; ii++)
-			_levelBlockProperties[i].walls[ii] = p[i * len + ii] ^ *t++;
-		_levelBlockProperties[i].flags = *t2++;
-	}
-
-	restoreMonsterTempData(_lvlTempData[l]);
-	restoreFlyingObjectTempData(_lvlTempData[l]);
-	restoreWallOfForceTempData(_lvlTempData[l]);
-}
-
-void LolEobBaseEngine::releaseTempData() {
-	for (int i = 0; i < 29; i++) {
-		if (_lvlTempData[i]) {
-			delete[] _lvlTempData[i]->wallsXorData;
-			delete[] _lvlTempData[i]->flags;
-			releaseMonsterTempData(_lvlTempData[i]);
-			releaseFlyingObjectTempData(_lvlTempData[i]);
-			releaseWallOfForceTempData(_lvlTempData[i]);
-			delete _lvlTempData[i];
-			_lvlTempData[i] = 0;
-		}
-	}
-}
-
-void *LolEobBaseEngine::generateFlyingObjectTempData(LevelTempData *tmp) {
-	assert(_flyingObjectStructSize == sizeof(EobFlyingObject));
-	EobFlyingObject *f = new EobFlyingObject[_numFlyingObjects];
-	memcpy(f, _flyingObjectsPtr,  sizeof(EobFlyingObject) * _numFlyingObjects);
-	return f;
-}
-
-void LolEobBaseEngine::restoreFlyingObjectTempData(LevelTempData *tmp) {
-	assert(_flyingObjectStructSize == sizeof(EobFlyingObject));
-	memcpy(_flyingObjectsPtr, tmp->flyingObjects, sizeof(EobFlyingObject) * _numFlyingObjects);
-}
-
-void LolEobBaseEngine::releaseFlyingObjectTempData(LevelTempData *tmp) {
-	EobFlyingObject *p = (EobFlyingObject*)tmp->flyingObjects;
-	delete[] p;
-}
-
-#ifdef ENABLE_EOB
-
 Common::Error EobCoreEngine::loadGameState(int slot) {
 	const char *fileName = 0;
 
@@ -221,7 +127,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 	_itemInHand = in.readSint16BE();
 	_hasTempDataFlags = in.readUint32BE();
 	_partyEffectFlags = in.readUint32BE();
-	
+
 	_updateFlags = in.readUint16BE();
 	_compassDirection = in.readUint16BE();
 	_currentControlMode = in.readUint16BE();
@@ -294,7 +200,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 		EobFlyingObject *lf = new EobFlyingObject[_numFlyingObjects];
 		l->flyingObjects = lf;
 		WallOfForce *lw = new WallOfForce[5];
-		l->wallsOfForce = lw;		
+		l->wallsOfForce = lw;
 
 		in.read(l->wallsXorData, 4096);
 		for (int ii = 0; ii < 1024; ii++)
@@ -364,7 +270,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
 	}
 
 	_screen->setCurPage(0);
-	gui_drawPlayField(false);	
+	gui_drawPlayField(false);
 
 	if (_currentControlMode)
 		_screen->copyRegion(176, 0, 0, 0, 144, 168, 0, 5, Screen::CR_NO_P_CHECK);
@@ -474,7 +380,7 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName,
 	out->writeSint16BE(_itemInHand);
 	out->writeUint32BE(_hasTempDataFlags);
 	out->writeUint32BE(_partyEffectFlags);
-	
+
 	out->writeUint16BE(_updateFlags);
 	out->writeUint16BE(_compassDirection);
 	out->writeUint16BE(_currentControlMode);
@@ -529,7 +435,7 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName,
 		LevelTempData *l = _lvlTempData[i];
 		if (!l || !(_hasTempDataFlags & (1 << i)))
 			continue;
-	
+
 		out->write(l->wallsXorData, 4096);
 		for (int ii = 0; ii < 1024; ii++)
 			out->writeByte(l->flags[ii] & 0xff);
@@ -643,8 +549,6 @@ void EobCoreEngine::releaseWallOfForceTempData(LevelTempData *tmp) {
 	delete[] p;
 }
 
-#endif // ENABLE_EOB
-
 }	// End of namespace Kyra
 
-#endif // ENABLE_EOB || ENABLE_LOL
+#endif // ENABLE_EOB
diff --git a/engines/kyra/saveload_lol.cpp b/engines/kyra/saveload_lol.cpp
index e5977dd..c7fb107 100644
--- a/engines/kyra/saveload_lol.cpp
+++ b/engines/kyra/saveload_lol.cpp
@@ -479,7 +479,7 @@ Graphics::Surface *LoLEngine::generateSaveThumbnail() const {
 
 void LoLEngine::restoreBlockTempData(int levelIndex) {
 	memset(_tempBuffer5120, 0, 5120);
-	LolEobBaseEngine::restoreBlockTempData(levelIndex);
+	KyraRpgEngine::restoreBlockTempData(levelIndex);
 	restoreTempDataAdjustMonsterStrength(levelIndex - 1);
 }
 
diff --git a/engines/kyra/saveload_rpg.cpp b/engines/kyra/saveload_rpg.cpp
new file mode 100644
index 0000000..4553570
--- /dev/null
+++ b/engines/kyra/saveload_rpg.cpp
@@ -0,0 +1,127 @@
+/* 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.
+ *
+ */
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#include "kyra/resource.h"
+#include "kyra/script_eob.h"
+
+#include "common/system.h"
+#include "common/savefile.h"
+#include "common/substream.h"
+
+namespace Kyra {
+
+void KyraRpgEngine::generateTempData() {
+	int l = _currentLevel - 1;
+	if (_lvlTempData[l]) {
+		delete[] _lvlTempData[l]->wallsXorData;
+		delete[] _lvlTempData[l]->flags;
+		releaseMonsterTempData(_lvlTempData[l]);
+		releaseFlyingObjectTempData(_lvlTempData[l]);
+		releaseWallOfForceTempData(_lvlTempData[l]);
+		delete _lvlTempData[l];
+	}
+
+	_lvlTempData[l] = new LevelTempData;
+
+	_lvlTempData[l]->wallsXorData = new uint8[4096];
+	_lvlTempData[l]->flags = new uint16[1024];
+
+	const uint8 *p = getBlockFileData(_currentLevel);
+	uint16 len = READ_LE_UINT16(p + 4);
+	p += 6;
+
+	memset(_lvlTempData[l]->wallsXorData, 0, 4096);
+	memset(_lvlTempData[l]->flags, 0, 1024 * sizeof(uint16));
+	uint8 *d = _lvlTempData[l]->wallsXorData;
+	uint16 *df = _lvlTempData[l]->flags;
+
+	for (int i = 0; i < 1024; i++) {
+		for (int ii = 0; ii < 4; ii++)
+			*d++ = p[i * len + ii] ^ _levelBlockProperties[i].walls[ii];
+		*df++ = _levelBlockProperties[i].flags;
+	}
+
+	_lvlTempData[l]->monsters = generateMonsterTempData(_lvlTempData[l]);
+	_lvlTempData[l]->flyingObjects = generateFlyingObjectTempData(_lvlTempData[l]);
+	_lvlTempData[l]->wallsOfForce = generateWallOfForceTempData(_lvlTempData[l]);
+
+	_hasTempDataFlags |= (1 << l);
+}
+
+void KyraRpgEngine::restoreBlockTempData(int levelIndex) {
+	int l = levelIndex - 1;
+	const uint8 *p = getBlockFileData(levelIndex);
+	uint16 len = READ_LE_UINT16(p + 4);
+	p += 6;
+
+	memset(_levelBlockProperties, 0, 1024 * sizeof(LevelBlockProperty));
+
+	uint8 *t = _lvlTempData[l]->wallsXorData;
+	uint16 *t2 = _lvlTempData[l]->flags;
+
+	for (int i = 0; i < 1024; i++) {
+		for (int ii = 0; ii < 4; ii++)
+			_levelBlockProperties[i].walls[ii] = p[i * len + ii] ^ *t++;
+		_levelBlockProperties[i].flags = *t2++;
+	}
+
+	restoreMonsterTempData(_lvlTempData[l]);
+	restoreFlyingObjectTempData(_lvlTempData[l]);
+	restoreWallOfForceTempData(_lvlTempData[l]);
+}
+
+void KyraRpgEngine::releaseTempData() {
+	for (int i = 0; i < 29; i++) {
+		if (_lvlTempData[i]) {
+			delete[] _lvlTempData[i]->wallsXorData;
+			delete[] _lvlTempData[i]->flags;
+			releaseMonsterTempData(_lvlTempData[i]);
+			releaseFlyingObjectTempData(_lvlTempData[i]);
+			releaseWallOfForceTempData(_lvlTempData[i]);
+			delete _lvlTempData[i];
+			_lvlTempData[i] = 0;
+		}
+	}
+}
+
+void *KyraRpgEngine::generateFlyingObjectTempData(LevelTempData *tmp) {
+	assert(_flyingObjectStructSize == sizeof(EobFlyingObject));
+	EobFlyingObject *f = new EobFlyingObject[_numFlyingObjects];
+	memcpy(f, _flyingObjectsPtr,  sizeof(EobFlyingObject) * _numFlyingObjects);
+	return f;
+}
+
+void KyraRpgEngine::restoreFlyingObjectTempData(LevelTempData *tmp) {
+	assert(_flyingObjectStructSize == sizeof(EobFlyingObject));
+	memcpy(_flyingObjectsPtr, tmp->flyingObjects, sizeof(EobFlyingObject) * _numFlyingObjects);
+}
+
+void KyraRpgEngine::releaseFlyingObjectTempData(LevelTempData *tmp) {
+	EobFlyingObject *p = (EobFlyingObject*)tmp->flyingObjects;
+	delete[] p;
+}
+
+}	// End of namespace Kyra
+
+#endif // ENABLE_EOB || ENABLE_LOL
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index e2a2e79..1927df7 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -20,7 +20,7 @@
  *
  */
 
-#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+#ifdef ENABLE_EOB
 
 #include "kyra/eobcommon.h"
 #include "kyra/resource.h"
@@ -30,590 +30,6 @@
 
 #include "common/system.h"
 
-namespace Kyra {
-
-void LolEobBaseEngine::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 = _visibleBlocks[i]->walls[_sceneDrawVarDown];
-			uint8 a = _wllWallFlags[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 += (_sceneXoffset >> 3);
-		x2 += (_sceneXoffset >> 3);
-
-
-		_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 LolEobBaseEngine::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 LolEobBaseEngine::drawLevelModifyScreenDim(int dim, int16 x1, int16 y1, int16 x2, int16 y2) {
-	screen()->modifyScreenDim(dim, x1, y1 << 3, x2 - x1, (y2 - y1) << 3);
-}
-
-void LolEobBaseEngine::generateBlockDrawingBuffer() {
-	_sceneDrawVarDown = _dscBlockMap[_currentDirection];
-	_sceneDrawVarRight = _dscBlockMap[_currentDirection + 4];
-	_sceneDrawVarLeft = _dscBlockMap[_currentDirection + 8];
-
-	/*******************************************
-    *             _visibleBlocks map           *
-	*                                          *
-	*     |     |     |     |     |     |      *
-	*  00 |  01 |  02 |  03 |  04 |  05 |  06  *
-	* ____|_____|_____|_____|_____|_____|_____ *
-	*     |     |     |     |     |     |      *
-	*     |  07 |  08 |  09 |  10 |  11 |      *
-	*     |_____|_____|_____|_____|_____|      *
-	*           |     |     |     |            *
-	*           |  12 |  13 |  14 |            *
-	*           |_____|_____|_____|            *
-	*                 |     |                  *
-	*              15 |  16 |  17              *
-	*                 | (P) |                  *
-	********************************************/
-
-	memset(_blockDrawingBuffer, 0, 660 * sizeof(uint16));
-
-	_wllProcessFlag = ((_currentBlock >> 5) + (_currentBlock & 0x1f) + _currentDirection) & 1;
-
-	if (_wllProcessFlag) // floor and ceiling
-		generateVmpTileDataFlipped(0, 15, 1, -330, 22, 15);
-	else
-		generateVmpTileData(0, 15, 1, -330, 22, 15);
-
-	assignVisibleBlocks(_currentBlock, _currentDirection);
-
-	uint8 t = _visibleBlocks[0]->walls[_sceneDrawVarRight];
-	if (t)
-		generateVmpTileData(-2, 3, t, 102, 3, 5);
-
-	t = _visibleBlocks[6]->walls[_sceneDrawVarLeft];
-	if (t)
-		generateVmpTileDataFlipped(21, 3, t, 102, 3, 5);
-
-	t = _visibleBlocks[1]->walls[_sceneDrawVarRight];
-	uint8 t2 = _visibleBlocks[2]->walls[_sceneDrawVarDown];
-
-	if (hasWall(t) && !(_wllWallFlags[t2] & 8))
-		generateVmpTileData(2, 3, t, 102, 3, 5);
-	else if (t && (_wllWallFlags[t2] & 8))
-		generateVmpTileData(2, 3, t2, 102, 3, 5);
-
-	t = _visibleBlocks[5]->walls[_sceneDrawVarLeft];
-	t2 = _visibleBlocks[4]->walls[_sceneDrawVarDown];
-
-	if (hasWall(t) && !(_wllWallFlags[t2] & 8))
-		generateVmpTileDataFlipped(17, 3, t, 102, 3, 5);
-	else if (t && (_wllWallFlags[t2] & 8))
-		generateVmpTileDataFlipped(17, 3, t2, 102, 3, 5);
-
-	t = _visibleBlocks[2]->walls[_sceneDrawVarRight];
-	if (t)
-		generateVmpTileData(8, 3, t, 97, 1, 5);
-
-	t = _visibleBlocks[4]->walls[_sceneDrawVarLeft];
-	if (t)
-		generateVmpTileDataFlipped(13, 3, t, 97, 1, 5);
-
-	t = _visibleBlocks[1]->walls[_sceneDrawVarDown];
-	if (hasWall(t))
-		generateVmpTileData(-4, 3, t, 129, 6, 5);
-
-	t = _visibleBlocks[5]->walls[_sceneDrawVarDown];
-	if (hasWall(t))
-		generateVmpTileData(20, 3, t, 129, 6, 5);
-
-	t = _visibleBlocks[2]->walls[_sceneDrawVarDown];
-	if (hasWall(t))
-		generateVmpTileData(2, 3, t, 129, 6, 5);
-
-	t = _visibleBlocks[4]->walls[_sceneDrawVarDown];
-	if (hasWall(t))
-		generateVmpTileData(14, 3, t, 129, 6, 5);
-
-	t = _visibleBlocks[3]->walls[_sceneDrawVarDown];
-	if (t)
-		generateVmpTileData(8, 3, t, 129, 6, 5);
-
-	t = _visibleBlocks[7]->walls[_sceneDrawVarRight];
-	if (t)
-		generateVmpTileData(0, 3, t, 117, 2, 6);
-
-	t = _visibleBlocks[11]->walls[_sceneDrawVarLeft];
-	if (t)
-		generateVmpTileDataFlipped(20, 3, t, 117, 2, 6);
-
-	t = _visibleBlocks[8]->walls[_sceneDrawVarRight];
-	if (t)
-		generateVmpTileData(6, 2, t, 81, 2, 8);
-
-	t = _visibleBlocks[10]->walls[_sceneDrawVarLeft];
-	if (t)
-		generateVmpTileDataFlipped(14, 2, t, 81, 2, 8);
-
-	t = _visibleBlocks[8]->walls[_sceneDrawVarDown];
-	if (hasWall(t))
-		generateVmpTileData(-4, 2, t, 159, 10, 8);
-
-	t = _visibleBlocks[10]->walls[_sceneDrawVarDown];
-	if (hasWall(t))
-		generateVmpTileData(16, 2, t, 159, 10, 8);
-
-	t = _visibleBlocks[9]->walls[_sceneDrawVarDown];
-	if (t)
-		generateVmpTileData(6, 2, t, 159, 10, 8);
-
-	t = _visibleBlocks[12]->walls[_sceneDrawVarRight];
-	if (t)
-		generateVmpTileData(3, 1, t, 45, 3, 12);
-
-	t = _visibleBlocks[14]->walls[_sceneDrawVarLeft];
-	if (t)
-		generateVmpTileDataFlipped(16, 1, t, 45, 3, 12);
-
-	t = _visibleBlocks[12]->walls[_sceneDrawVarDown];
-	if (!(_wllWallFlags[t] & 8))
-		generateVmpTileData(-13, 1, t, 239, 16, 12);
-
-	t = _visibleBlocks[14]->walls[_sceneDrawVarDown];
-	if (!(_wllWallFlags[t] & 8))
-		generateVmpTileData(19, 1, t, 239, 16, 12);
-
-	t = _visibleBlocks[13]->walls[_sceneDrawVarDown];
-	if (t)
-		generateVmpTileData(3, 1, t, 239, 16, 12);
-
-	t = _visibleBlocks[15]->walls[_sceneDrawVarRight];
-	t2 = _visibleBlocks[17]->walls[_sceneDrawVarLeft];
-	if (t)
-		generateVmpTileData(0, 0, t, 0, 3, 15);
-	if (t2)
-		generateVmpTileDataFlipped(19, 0, t2, 0, 3, 15);
-}
-
-void LolEobBaseEngine::generateVmpTileData(int16 startBlockX, uint8 startBlockY, uint8 vmpMapIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY) {
-	if (!_wllVmpMap[vmpMapIndex])
-		return;
-
-	uint16 *vmp = &_vmpPtr[(_wllVmpMap[vmpMapIndex] - 1) * 431 + vmpOffset + 330];
-
-	for (int i = 0; i < numBlocksY; i++) {
-		uint16 *bl = &_blockDrawingBuffer[(startBlockY + i) * 22 + startBlockX];
-		for (int ii = 0; ii < numBlocksX; ii++) {
-			if ((startBlockX + ii >= 0) && (startBlockX + ii < 22) && *vmp)
-				*bl = *vmp;
-			bl++;
-			vmp++;
-		}
-	}
-}
-
-void LolEobBaseEngine::generateVmpTileDataFlipped(int16 startBlockX, uint8 startBlockY, uint8 vmpMapIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY) {
-	if (!_wllVmpMap[vmpMapIndex])
-		return;
-
-	uint16 *vmp = &_vmpPtr[(_wllVmpMap[vmpMapIndex] - 1) * 431 + vmpOffset + 330];
-
-	for (int i = 0; i < numBlocksY; i++) {
-		for (int ii = 0; ii < numBlocksX; ii++) {
-			if ((startBlockX + ii) < 0 || (startBlockX + ii) > 21)
-				continue;
-
-			uint16 v = vmp[i * numBlocksX + (numBlocksX - 1 - ii)];
-			if (!v)
-				continue;
-
-			if (v & 0x4000)
-				v -= 0x4000;
-			else
-				v |= 0x4000;
-
-			_blockDrawingBuffer[(startBlockY + i) * 22 + startBlockX + ii] = v;
-		}
-	}
-}
-
-bool LolEobBaseEngine::hasWall(int index) {
-	if (!index || (_wllWallFlags[index] & 8))
-		return false;
-	return true;
-}
-
-void LolEobBaseEngine::assignVisibleBlocks(int block, int direction) {
-	for (int i = 0; i < 18; i++) {
-		uint16 t = (block + _dscBlockIndex[direction * 18 + i]) & 0x3ff;
-		_visibleBlockIndex[i] = t;
-
-		_visibleBlocks[i] = &_levelBlockProperties[t];
-		_lvlShapeLeftRight[i] = _lvlShapeLeftRight[18 + i] = -1;
-	}
-}
-
-bool LolEobBaseEngine::checkSceneUpdateNeed(int block) {
-	if (_sceneUpdateRequired)
-		return true;
-
-	for (int i = 0; i < 15; i++) {
-		if (_visibleBlockIndex[i] == block) {
-			_sceneUpdateRequired = true;
-			return true;
-		}
-	}
-
-	if (_currentBlock == block){
-		_sceneUpdateRequired = true;
-		return true;
-	}
-
-	return false;
-}
-
-void LolEobBaseEngine::drawVcnBlocks() {
-	uint8 *d = _sceneWindowBuffer;
-	uint16 *bdb = _blockDrawingBuffer;
-
-	for (int y = 0; y < 15; y++) {
-		for (int x = 0; x < 22; x++) {
-			bool horizontalFlip = false;
-			int remainder = 0;
-
-			uint16 vcnOffset = *bdb++;
-			int wllVcnOffset = 0;
-			int wllVcnRmdOffset = 0;
-
-			if (vcnOffset & 0x8000) {
-				// this renders a wall block over the transparent pixels of a floor/ceiling block
-				remainder = vcnOffset - 0x8000;
-				vcnOffset = 0;
-				wllVcnRmdOffset = _wllVcnOffset;
-			}
-
-			if (vcnOffset & 0x4000) {
-				horizontalFlip = true;
-				vcnOffset &= 0x3fff;
-			}
-
-			uint8 *src = 0;
-			if (vcnOffset) {
-				src = &_vcnBlocks[vcnOffset << 5];
-				wllVcnOffset = _wllVcnOffset;
-			} else {
-				// floor/ceiling blocks
-				vcnOffset = bdb[329];
-				if (vcnOffset & 0x4000) {
-					horizontalFlip = true;
-					vcnOffset &= 0x3fff;
-				}
-
-				src = (_vcfBlocks ? _vcfBlocks : _vcnBlocks) + (vcnOffset << 5);
-			}
-
-			uint8 shift = _vcnShift ? _vcnShift[vcnOffset] : _blockBrightness;
-
-			if (horizontalFlip) {
-				for (int blockY = 0; blockY < 8; blockY++) {
-					src += 3;
-					for (int blockX = 0; blockX < 4; blockX++) {
-						uint8 t = *src--;
-						*d++ = _vcnExpTable[((t & 0x0f) + wllVcnOffset) | shift];
-						*d++ = _vcnExpTable[((t >> 4) + wllVcnOffset) | 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) + wllVcnOffset) | shift];
-						*d++ = _vcnExpTable[((t & 0x0f) + wllVcnOffset) | shift];
-					}
-					d += 168;
-				}
-			}
-			d -= 1400;
-
-			if (remainder) {
-				d -= 8;
-				horizontalFlip = false;
-
-				if (remainder & 0x4000) {
-					remainder &= 0x3fff;
-					horizontalFlip = true;
-				}
-
-				shift = _vcnShift ? _vcnShift[remainder] : _blockBrightness;
-				src = &_vcnBlocks[remainder << 5];
-
-				if (horizontalFlip) {
-					for (int blockY = 0; blockY < 8; blockY++) {
-						src += 3;
-						for (int blockX = 0; blockX < 4; blockX++) {
-							uint8 t = *src--;
-							uint8 h = _vcnExpTable[((t & 0x0f) + wllVcnRmdOffset) | shift];
-							uint8 l = _vcnExpTable[((t >> 4) + wllVcnRmdOffset) | 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) + wllVcnRmdOffset) | shift];
-							uint8 l = _vcnExpTable[((t & 0x0f) + wllVcnRmdOffset) | shift];
-							if (h)
-								*d = h;
-							d++;
-							if (l)
-								*d = l;
-							d++;
-						}
-						d += 168;
-					}
-				}
-				d -= 1400;
-			}
-		}
-		d += 1232;
-	}
-
-	screen()->copyBlockToPage(_sceneDrawPage1, _sceneXoffset, 0, 176, 120, _sceneWindowBuffer);
-}
-
-uint16 LolEobBaseEngine::calcNewBlockPosition(uint16 curBlock, uint16 direction) {
-	static const int16 blockPosTable[] = { -32, 1, 32, -1 };
-	return (curBlock + blockPosTable[direction]) & 0x3ff;
-}
-
-int LolEobBaseEngine::clickedWallShape(uint16 block, uint16 direction) {
-	uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]];
-	if (!clickedShape(v))
-		return 0;
-
-	snd_stopSpeech(true);
-	runLevelScript(block, 0x40);
-
-	return 1;
-}
-
-int LolEobBaseEngine::clickedLeverOn(uint16 block, uint16 direction) {
-	uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]];
-	if (!clickedShape(v))
-		return 0;
-
-	_levelBlockProperties[block].walls[direction]++;
-	_sceneUpdateRequired = true;
-
-	if (_flags.gameID == GI_LOL)
-		snd_playSoundEffect(30, -1);
-
-	runLevelScript(block, _clickedSpecialFlag);
-
-	return 1;
-}
-
-int LolEobBaseEngine::clickedLeverOff(uint16 block, uint16 direction) {
-	uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]];
-	if (!clickedShape(v))
-		return 0;
-
-	_levelBlockProperties[block].walls[direction]--;
-	_sceneUpdateRequired = true;
-
-	if (_flags.gameID == GI_LOL)
-		snd_playSoundEffect(29, -1);
-
-	runLevelScript(block, _clickedSpecialFlag);
-	return 1;
-}
-
-int LolEobBaseEngine::clickedWallOnlyScript(uint16 block) {
-	runLevelScript(block, _clickedSpecialFlag);
-	return 1;
-}
-
-void LolEobBaseEngine::processDoorSwitch(uint16 block, int openClose) {
-	if (block == _currentBlock)
-		return;
-
-	if ((_flags.gameID == GI_LOL && (_levelBlockProperties[block].assignedObjects & 0x8000)) || (_flags.gameID != GI_LOL  && (_levelBlockProperties[block].flags & 7)))
-		return;
-
-	if (openClose == 0) {
-		for (int i = 0; i < 3; i++) {
-			if (_openDoorState[i].block != block)
-				continue;
-			openClose = -_openDoorState[i].state;
-			break;
-		}
-	}
-
-	if (openClose == 0) {
-		openClose = (_wllWallFlags[_levelBlockProperties[block].walls[_wllWallFlags[_levelBlockProperties[block].walls[0]] & 8 ? 0 : 1]] & 1) ? 1 : -1;
-		if (_flags.gameID != GI_LOL)
-			openClose *= -1;
-	}
-
-	openCloseDoor(block, openClose);
-}
-
-void LolEobBaseEngine::openCloseDoor(int block, int openClose) {
-	int s1 = -1;
-	int s2 = -1;
-
-	int c = (_wllWallFlags[_levelBlockProperties[block].walls[0]] & 8) ? 0 : 1;
-	int v = _levelBlockProperties[block].walls[c];
-	int flg = (openClose == 1) ? 0x10 : (openClose == -1 ? 0x20 : 0);
-
-	if (_wllWallFlags[v] & flg)
-		return;
-
-	for (int i = 0; i < 3; i++) {
-		if (_openDoorState[i].block == block) {
-			s1 = i;
-			break;
-		} else if (_openDoorState[i].block == 0 && s2 == -1) {
-			s2 = i;
-		}
-	}
-
-	if (s1 != -1 || s2 != -1) {
-		if (s1 == -1)
-			s1 = s2;
-
-		_openDoorState[s1].block = block;
-		_openDoorState[s1].state = openClose;
-		_openDoorState[s1].wall = c;
-
-		flg = (-openClose == 1) ? 0x10 : (-openClose == -1 ? 0x20 : 0);
-
-		if (_wllWallFlags[v] & flg) {
-			_levelBlockProperties[block].walls[c] += openClose;
-			_levelBlockProperties[block].walls[c ^ 2] += openClose;
-
-			int snd = (openClose == -1) ? 4 : 3;
-			if (_flags.gameID == GI_LOL) {
-				snd_processEnvironmentalSoundEffect(snd + 28, _currentBlock);
-				if (!checkSceneUpdateNeed(block))
-					updateEnvironmentalSfx(0);
-			} else {
-				updateEnvironmentalSfx(snd);
-			}
-		}
-
-		enableTimer(_flags.gameID == GI_LOL ? 0 : 4);
-
-	} else {
-		while (!(flg & _wllWallFlags[v]))
-			v += openClose;
-
-		_levelBlockProperties[block].walls[c] = _levelBlockProperties[block].walls[c ^ 2] = v;
-		checkSceneUpdateNeed(block);
-	}
-}
-
-void LolEobBaseEngine::completeDoorOperations() {
-	for (int i = 0; i < 3; i++) {
-		if (!_openDoorState[i].block)
-			continue;
-
-		uint16 b = _openDoorState[i].block;
-
-		do {
-			_levelBlockProperties[b].walls[_openDoorState[i].wall] += _openDoorState[i].state;
-			_levelBlockProperties[b].walls[_openDoorState[i].wall ^ 2] += _openDoorState[i].state;
-		} while	(!(_wllWallFlags[_levelBlockProperties[b].walls[_openDoorState[i].wall]] & 0x30));
-
-		_openDoorState[i].block = 0;
-	}
-}
-
-} // End of namespace Kyra
-
-#endif // ENABLE_EOB || ENABLE_LOL
-#ifdef ENABLE_EOB
 
 namespace Kyra {
 
@@ -625,7 +41,7 @@ void EobCoreEngine::loadLevel(int level, int sub) {
 	Common::String file;
 	Common::SeekableReadStream *s = 0;
 	static const char *suffix[] = { "INF", "DRO", "ELO", 0 };
-	
+
 	for (const char *const *sf = suffix; *sf && !s; sf++) {
 		file = Common::String::format("LEVEL%d.%s", level, *sf);
 		s = _res->createReadStream(file);
@@ -649,11 +65,11 @@ void EobCoreEngine::loadLevel(int level, int sub) {
 	}
 
 	Common::String gfxFile;
-	// Work around for issue with corrupt (incomplete) monster property data 
+	// Work around for issue with corrupt (incomplete) monster property data
 	// when loading a savegame saved in a sub level
 	for (int i = 0; i <= sub; i++)
 		gfxFile = initLevelData(i);
-	
+
 	const uint8 *data = _screen->getCPagePtr(5);
 	const uint8 *pos = data + READ_LE_UINT16(data);
 	uint16 len = READ_LE_UINT16(pos);
@@ -744,7 +160,7 @@ Common::String EobCoreEngine::initLevelData(int sub){
 			_screen->setShapeFadeMode(0, false);
 			_screen->setShapeFadeMode(1, false);
 		}
-		
+
 		_screen->loadPalette(tmpStr.c_str(), _screen->getPalette(0));
 
 		Palette backupPal(256);
@@ -850,7 +266,7 @@ void EobCoreEngine::addLevelItems() {
 void EobCoreEngine::loadVcnData(const char *file, const char*/*nextFile*/) {
 	if (file)
 		strcpy(_lastBlockDataFile, file);
-	
+
 	_screen->loadBitmap(Common::String::format("%s.VCN", _lastBlockDataFile).c_str(), 3, 3, 0);
 	const uint8 *v = _screen->getCPagePtr(2);
 	uint32 tlen = READ_LE_UINT16(v) << 5;
@@ -1212,7 +628,7 @@ int EobCoreEngine::clickedDoorSwitch(uint16 block, uint16 direction) {
 		else
 			x1 += ((v - _dscDoorXE[v]) * 9);
 	}
-	
+
 	if (!posWithinRect(_mouseX, _mouseY, x1, y1, x1 + (d->shp[2] << 3) + 8, y1 + d->shp[1] + 8) && (_clickedSpecialFlag == 0x40))
 		return clickedDoorNoPry(block, direction);
 
diff --git a/engines/kyra/scene_rpg.cpp b/engines/kyra/scene_rpg.cpp
new file mode 100644
index 0000000..07a7a87
--- /dev/null
+++ b/engines/kyra/scene_rpg.cpp
@@ -0,0 +1,614 @@
+/* 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.
+ *
+ */
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#include "kyra/kyra_rpg.h"
+#include "kyra/resource.h"
+#include "kyra/timer.h"
+#include "kyra/sound.h"
+
+#include "common/system.h"
+
+namespace Kyra {
+
+void KyraRpgEngine::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 = _visibleBlocks[i]->walls[_sceneDrawVarDown];
+			uint8 a = _wllWallFlags[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 += (_sceneXoffset >> 3);
+		x2 += (_sceneXoffset >> 3);
+
+
+		_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 KyraRpgEngine::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 KyraRpgEngine::drawLevelModifyScreenDim(int dim, int16 x1, int16 y1, int16 x2, int16 y2) {
+	screen()->modifyScreenDim(dim, x1, y1 << 3, x2 - x1, (y2 - y1) << 3);
+}
+
+void KyraRpgEngine::generateBlockDrawingBuffer() {
+	_sceneDrawVarDown = _dscBlockMap[_currentDirection];
+	_sceneDrawVarRight = _dscBlockMap[_currentDirection + 4];
+	_sceneDrawVarLeft = _dscBlockMap[_currentDirection + 8];
+
+	/*******************************************
+    *             _visibleBlocks map           *
+	*                                          *
+	*     |     |     |     |     |     |      *
+	*  00 |  01 |  02 |  03 |  04 |  05 |  06  *
+	* ____|_____|_____|_____|_____|_____|_____ *
+	*     |     |     |     |     |     |      *
+	*     |  07 |  08 |  09 |  10 |  11 |      *
+	*     |_____|_____|_____|_____|_____|      *
+	*           |     |     |     |            *
+	*           |  12 |  13 |  14 |            *
+	*           |_____|_____|_____|            *
+	*                 |     |                  *
+	*              15 |  16 |  17              *
+	*                 | (P) |                  *
+	********************************************/
+
+	memset(_blockDrawingBuffer, 0, 660 * sizeof(uint16));
+
+	_wllProcessFlag = ((_currentBlock >> 5) + (_currentBlock & 0x1f) + _currentDirection) & 1;
+
+	if (_wllProcessFlag) // floor and ceiling
+		generateVmpTileDataFlipped(0, 15, 1, -330, 22, 15);
+	else
+		generateVmpTileData(0, 15, 1, -330, 22, 15);
+
+	assignVisibleBlocks(_currentBlock, _currentDirection);
+
+	uint8 t = _visibleBlocks[0]->walls[_sceneDrawVarRight];
+	if (t)
+		generateVmpTileData(-2, 3, t, 102, 3, 5);
+
+	t = _visibleBlocks[6]->walls[_sceneDrawVarLeft];
+	if (t)
+		generateVmpTileDataFlipped(21, 3, t, 102, 3, 5);
+
+	t = _visibleBlocks[1]->walls[_sceneDrawVarRight];
+	uint8 t2 = _visibleBlocks[2]->walls[_sceneDrawVarDown];
+
+	if (hasWall(t) && !(_wllWallFlags[t2] & 8))
+		generateVmpTileData(2, 3, t, 102, 3, 5);
+	else if (t && (_wllWallFlags[t2] & 8))
+		generateVmpTileData(2, 3, t2, 102, 3, 5);
+
+	t = _visibleBlocks[5]->walls[_sceneDrawVarLeft];
+	t2 = _visibleBlocks[4]->walls[_sceneDrawVarDown];
+
+	if (hasWall(t) && !(_wllWallFlags[t2] & 8))
+		generateVmpTileDataFlipped(17, 3, t, 102, 3, 5);
+	else if (t && (_wllWallFlags[t2] & 8))
+		generateVmpTileDataFlipped(17, 3, t2, 102, 3, 5);
+
+	t = _visibleBlocks[2]->walls[_sceneDrawVarRight];
+	if (t)
+		generateVmpTileData(8, 3, t, 97, 1, 5);
+
+	t = _visibleBlocks[4]->walls[_sceneDrawVarLeft];
+	if (t)
+		generateVmpTileDataFlipped(13, 3, t, 97, 1, 5);
+
+	t = _visibleBlocks[1]->walls[_sceneDrawVarDown];
+	if (hasWall(t))
+		generateVmpTileData(-4, 3, t, 129, 6, 5);
+
+	t = _visibleBlocks[5]->walls[_sceneDrawVarDown];
+	if (hasWall(t))
+		generateVmpTileData(20, 3, t, 129, 6, 5);
+
+	t = _visibleBlocks[2]->walls[_sceneDrawVarDown];
+	if (hasWall(t))
+		generateVmpTileData(2, 3, t, 129, 6, 5);
+
+	t = _visibleBlocks[4]->walls[_sceneDrawVarDown];
+	if (hasWall(t))
+		generateVmpTileData(14, 3, t, 129, 6, 5);
+
+	t = _visibleBlocks[3]->walls[_sceneDrawVarDown];
+	if (t)
+		generateVmpTileData(8, 3, t, 129, 6, 5);
+
+	t = _visibleBlocks[7]->walls[_sceneDrawVarRight];
+	if (t)
+		generateVmpTileData(0, 3, t, 117, 2, 6);
+
+	t = _visibleBlocks[11]->walls[_sceneDrawVarLeft];
+	if (t)
+		generateVmpTileDataFlipped(20, 3, t, 117, 2, 6);
+
+	t = _visibleBlocks[8]->walls[_sceneDrawVarRight];
+	if (t)
+		generateVmpTileData(6, 2, t, 81, 2, 8);
+
+	t = _visibleBlocks[10]->walls[_sceneDrawVarLeft];
+	if (t)
+		generateVmpTileDataFlipped(14, 2, t, 81, 2, 8);
+
+	t = _visibleBlocks[8]->walls[_sceneDrawVarDown];
+	if (hasWall(t))
+		generateVmpTileData(-4, 2, t, 159, 10, 8);
+
+	t = _visibleBlocks[10]->walls[_sceneDrawVarDown];
+	if (hasWall(t))
+		generateVmpTileData(16, 2, t, 159, 10, 8);
+
+	t = _visibleBlocks[9]->walls[_sceneDrawVarDown];
+	if (t)
+		generateVmpTileData(6, 2, t, 159, 10, 8);
+
+	t = _visibleBlocks[12]->walls[_sceneDrawVarRight];
+	if (t)
+		generateVmpTileData(3, 1, t, 45, 3, 12);
+
+	t = _visibleBlocks[14]->walls[_sceneDrawVarLeft];
+	if (t)
+		generateVmpTileDataFlipped(16, 1, t, 45, 3, 12);
+
+	t = _visibleBlocks[12]->walls[_sceneDrawVarDown];
+	if (!(_wllWallFlags[t] & 8))
+		generateVmpTileData(-13, 1, t, 239, 16, 12);
+
+	t = _visibleBlocks[14]->walls[_sceneDrawVarDown];
+	if (!(_wllWallFlags[t] & 8))
+		generateVmpTileData(19, 1, t, 239, 16, 12);
+
+	t = _visibleBlocks[13]->walls[_sceneDrawVarDown];
+	if (t)
+		generateVmpTileData(3, 1, t, 239, 16, 12);
+
+	t = _visibleBlocks[15]->walls[_sceneDrawVarRight];
+	t2 = _visibleBlocks[17]->walls[_sceneDrawVarLeft];
+	if (t)
+		generateVmpTileData(0, 0, t, 0, 3, 15);
+	if (t2)
+		generateVmpTileDataFlipped(19, 0, t2, 0, 3, 15);
+}
+
+void KyraRpgEngine::generateVmpTileData(int16 startBlockX, uint8 startBlockY, uint8 vmpMapIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY) {
+	if (!_wllVmpMap[vmpMapIndex])
+		return;
+
+	uint16 *vmp = &_vmpPtr[(_wllVmpMap[vmpMapIndex] - 1) * 431 + vmpOffset + 330];
+
+	for (int i = 0; i < numBlocksY; i++) {
+		uint16 *bl = &_blockDrawingBuffer[(startBlockY + i) * 22 + startBlockX];
+		for (int ii = 0; ii < numBlocksX; ii++) {
+			if ((startBlockX + ii >= 0) && (startBlockX + ii < 22) && *vmp)
+				*bl = *vmp;
+			bl++;
+			vmp++;
+		}
+	}
+}
+
+void KyraRpgEngine::generateVmpTileDataFlipped(int16 startBlockX, uint8 startBlockY, uint8 vmpMapIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY) {
+	if (!_wllVmpMap[vmpMapIndex])
+		return;
+
+	uint16 *vmp = &_vmpPtr[(_wllVmpMap[vmpMapIndex] - 1) * 431 + vmpOffset + 330];
+
+	for (int i = 0; i < numBlocksY; i++) {
+		for (int ii = 0; ii < numBlocksX; ii++) {
+			if ((startBlockX + ii) < 0 || (startBlockX + ii) > 21)
+				continue;
+
+			uint16 v = vmp[i * numBlocksX + (numBlocksX - 1 - ii)];
+			if (!v)
+				continue;
+
+			if (v & 0x4000)
+				v -= 0x4000;
+			else
+				v |= 0x4000;
+
+			_blockDrawingBuffer[(startBlockY + i) * 22 + startBlockX + ii] = v;
+		}
+	}
+}
+
+bool KyraRpgEngine::hasWall(int index) {
+	if (!index || (_wllWallFlags[index] & 8))
+		return false;
+	return true;
+}
+
+void KyraRpgEngine::assignVisibleBlocks(int block, int direction) {
+	for (int i = 0; i < 18; i++) {
+		uint16 t = (block + _dscBlockIndex[direction * 18 + i]) & 0x3ff;
+		_visibleBlockIndex[i] = t;
+
+		_visibleBlocks[i] = &_levelBlockProperties[t];
+		_lvlShapeLeftRight[i] = _lvlShapeLeftRight[18 + i] = -1;
+	}
+}
+
+bool KyraRpgEngine::checkSceneUpdateNeed(int block) {
+	if (_sceneUpdateRequired)
+		return true;
+
+	for (int i = 0; i < 15; i++) {
+		if (_visibleBlockIndex[i] == block) {
+			_sceneUpdateRequired = true;
+			return true;
+		}
+	}
+
+	if (_currentBlock == block){
+		_sceneUpdateRequired = true;
+		return true;
+	}
+
+	return false;
+}
+
+void KyraRpgEngine::drawVcnBlocks() {
+	uint8 *d = _sceneWindowBuffer;
+	uint16 *bdb = _blockDrawingBuffer;
+
+	for (int y = 0; y < 15; y++) {
+		for (int x = 0; x < 22; x++) {
+			bool horizontalFlip = false;
+			int remainder = 0;
+
+			uint16 vcnOffset = *bdb++;
+			int wllVcnOffset = 0;
+			int wllVcnRmdOffset = 0;
+
+			if (vcnOffset & 0x8000) {
+				// this renders a wall block over the transparent pixels of a floor/ceiling block
+				remainder = vcnOffset - 0x8000;
+				vcnOffset = 0;
+				wllVcnRmdOffset = _wllVcnOffset;
+			}
+
+			if (vcnOffset & 0x4000) {
+				horizontalFlip = true;
+				vcnOffset &= 0x3fff;
+			}
+
+			uint8 *src = 0;
+			if (vcnOffset) {
+				src = &_vcnBlocks[vcnOffset << 5];
+				wllVcnOffset = _wllVcnOffset;
+			} else {
+				// floor/ceiling blocks
+				vcnOffset = bdb[329];
+				if (vcnOffset & 0x4000) {
+					horizontalFlip = true;
+					vcnOffset &= 0x3fff;
+				}
+
+				src = (_vcfBlocks ? _vcfBlocks : _vcnBlocks) + (vcnOffset << 5);
+			}
+
+			uint8 shift = _vcnShift ? _vcnShift[vcnOffset] : _blockBrightness;
+
+			if (horizontalFlip) {
+				for (int blockY = 0; blockY < 8; blockY++) {
+					src += 3;
+					for (int blockX = 0; blockX < 4; blockX++) {
+						uint8 t = *src--;
+						*d++ = _vcnExpTable[((t & 0x0f) + wllVcnOffset) | shift];
+						*d++ = _vcnExpTable[((t >> 4) + wllVcnOffset) | 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) + wllVcnOffset) | shift];
+						*d++ = _vcnExpTable[((t & 0x0f) + wllVcnOffset) | shift];
+					}
+					d += 168;
+				}
+			}
+			d -= 1400;
+
+			if (remainder) {
+				d -= 8;
+				horizontalFlip = false;
+
+				if (remainder & 0x4000) {
+					remainder &= 0x3fff;
+					horizontalFlip = true;
+				}
+
+				shift = _vcnShift ? _vcnShift[remainder] : _blockBrightness;
+				src = &_vcnBlocks[remainder << 5];
+
+				if (horizontalFlip) {
+					for (int blockY = 0; blockY < 8; blockY++) {
+						src += 3;
+						for (int blockX = 0; blockX < 4; blockX++) {
+							uint8 t = *src--;
+							uint8 h = _vcnExpTable[((t & 0x0f) + wllVcnRmdOffset) | shift];
+							uint8 l = _vcnExpTable[((t >> 4) + wllVcnRmdOffset) | 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) + wllVcnRmdOffset) | shift];
+							uint8 l = _vcnExpTable[((t & 0x0f) + wllVcnRmdOffset) | shift];
+							if (h)
+								*d = h;
+							d++;
+							if (l)
+								*d = l;
+							d++;
+						}
+						d += 168;
+					}
+				}
+				d -= 1400;
+			}
+		}
+		d += 1232;
+	}
+
+	screen()->copyBlockToPage(_sceneDrawPage1, _sceneXoffset, 0, 176, 120, _sceneWindowBuffer);
+}
+
+uint16 KyraRpgEngine::calcNewBlockPosition(uint16 curBlock, uint16 direction) {
+	static const int16 blockPosTable[] = { -32, 1, 32, -1 };
+	return (curBlock + blockPosTable[direction]) & 0x3ff;
+}
+
+int KyraRpgEngine::clickedWallShape(uint16 block, uint16 direction) {
+	uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]];
+	if (!clickedShape(v))
+		return 0;
+
+	snd_stopSpeech(true);
+	runLevelScript(block, 0x40);
+
+	return 1;
+}
+
+int KyraRpgEngine::clickedLeverOn(uint16 block, uint16 direction) {
+	uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]];
+	if (!clickedShape(v))
+		return 0;
+
+	_levelBlockProperties[block].walls[direction]++;
+	_sceneUpdateRequired = true;
+
+	if (_flags.gameID == GI_LOL)
+		snd_playSoundEffect(30, -1);
+
+	runLevelScript(block, _clickedSpecialFlag);
+
+	return 1;
+}
+
+int KyraRpgEngine::clickedLeverOff(uint16 block, uint16 direction) {
+	uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]];
+	if (!clickedShape(v))
+		return 0;
+
+	_levelBlockProperties[block].walls[direction]--;
+	_sceneUpdateRequired = true;
+
+	if (_flags.gameID == GI_LOL)
+		snd_playSoundEffect(29, -1);
+
+	runLevelScript(block, _clickedSpecialFlag);
+	return 1;
+}
+
+int KyraRpgEngine::clickedWallOnlyScript(uint16 block) {
+	runLevelScript(block, _clickedSpecialFlag);
+	return 1;
+}
+
+void KyraRpgEngine::processDoorSwitch(uint16 block, int openClose) {
+	if (block == _currentBlock)
+		return;
+
+	if ((_flags.gameID == GI_LOL && (_levelBlockProperties[block].assignedObjects & 0x8000)) || (_flags.gameID != GI_LOL  && (_levelBlockProperties[block].flags & 7)))
+		return;
+
+	if (openClose == 0) {
+		for (int i = 0; i < 3; i++) {
+			if (_openDoorState[i].block != block)
+				continue;
+			openClose = -_openDoorState[i].state;
+			break;
+		}
+	}
+
+	if (openClose == 0) {
+		openClose = (_wllWallFlags[_levelBlockProperties[block].walls[_wllWallFlags[_levelBlockProperties[block].walls[0]] & 8 ? 0 : 1]] & 1) ? 1 : -1;
+		if (_flags.gameID != GI_LOL)
+			openClose *= -1;
+	}
+
+	openCloseDoor(block, openClose);
+}
+
+void KyraRpgEngine::openCloseDoor(int block, int openClose) {
+	int s1 = -1;
+	int s2 = -1;
+
+	int c = (_wllWallFlags[_levelBlockProperties[block].walls[0]] & 8) ? 0 : 1;
+	int v = _levelBlockProperties[block].walls[c];
+	int flg = (openClose == 1) ? 0x10 : (openClose == -1 ? 0x20 : 0);
+
+	if (_wllWallFlags[v] & flg)
+		return;
+
+	for (int i = 0; i < 3; i++) {
+		if (_openDoorState[i].block == block) {
+			s1 = i;
+			break;
+		} else if (_openDoorState[i].block == 0 && s2 == -1) {
+			s2 = i;
+		}
+	}
+
+	if (s1 != -1 || s2 != -1) {
+		if (s1 == -1)
+			s1 = s2;
+
+		_openDoorState[s1].block = block;
+		_openDoorState[s1].state = openClose;
+		_openDoorState[s1].wall = c;
+
+		flg = (-openClose == 1) ? 0x10 : (-openClose == -1 ? 0x20 : 0);
+
+		if (_wllWallFlags[v] & flg) {
+			_levelBlockProperties[block].walls[c] += openClose;
+			_levelBlockProperties[block].walls[c ^ 2] += openClose;
+
+			int snd = (openClose == -1) ? 4 : 3;
+			if (_flags.gameID == GI_LOL) {
+				snd_processEnvironmentalSoundEffect(snd + 28, _currentBlock);
+				if (!checkSceneUpdateNeed(block))
+					updateEnvironmentalSfx(0);
+			} else {
+				updateEnvironmentalSfx(snd);
+			}
+		}
+
+		enableTimer(_flags.gameID == GI_LOL ? 0 : 4);
+
+	} else {
+		while (!(flg & _wllWallFlags[v]))
+			v += openClose;
+
+		_levelBlockProperties[block].walls[c] = _levelBlockProperties[block].walls[c ^ 2] = v;
+		checkSceneUpdateNeed(block);
+	}
+}
+
+void KyraRpgEngine::completeDoorOperations() {
+	for (int i = 0; i < 3; i++) {
+		if (!_openDoorState[i].block)
+			continue;
+
+		uint16 b = _openDoorState[i].block;
+
+		do {
+			_levelBlockProperties[b].walls[_openDoorState[i].wall] += _openDoorState[i].state;
+			_levelBlockProperties[b].walls[_openDoorState[i].wall ^ 2] += _openDoorState[i].state;
+		} while	(!(_wllWallFlags[_levelBlockProperties[b].walls[_openDoorState[i].wall]] & 0x30));
+
+		_openDoorState[i].block = 0;
+	}
+}
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB || ENABLE_LOL
diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp
index 0b877b7..ca44a8a 100644
--- a/engines/kyra/screen_eob.cpp
+++ b/engines/kyra/screen_eob.cpp
@@ -189,7 +189,7 @@ void Screen_Eob::loadEobBitmap(const char *file, const uint8 *ditheringData, int
 			delete s;
 		}
 	}
-	
+
 	if (copyToPage == -1) {
 		return;
 	} else if (copyToPage == 0) {
@@ -248,7 +248,7 @@ uint8 *Screen_Eob::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4b
 			uint8 *lineEnd = src + (w << 3);
 			do {
 				uint8 val = *src++;
-				if (!val) {				
+				if (!val) {
 					*dst++ = 0;
 					uint8 *startZeroPos = src;
 
@@ -563,9 +563,9 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
 			addDirtyRect(rX, rY, rW, rH);
 
 		while (dH--) {
-			int16 xpos = (int16) marginLeft;			
+			int16 xpos = (int16) marginLeft;
 
-			if (flags & 1) {				
+			if (flags & 1) {
 				for (int i = 0; i < w2; i++) {
 					if (*src++ == 0) {
 						i += (*src - 1);
@@ -636,7 +636,7 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
 
 			dstL += 320;
 			dst = dstL;
-			if (flags & 1)			
+			if (flags & 1)
 				src = src2 + 1;
 		}
 	}
@@ -751,7 +751,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS
 	int rY1 = dm->sy;
 	int rX2 = rX1 + (dm->w << 3);
 	int rY2 = rY1 + dm->h - 1;
-	
+
 	int16 gx2 = _gfxX;
 	int16 gy2 = _gfxY;
 
@@ -783,7 +783,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS
 					py = ymax;
 				if (posWithinRect(px, py, rX1, rY1, rX2, rY2))
 					setPagePixel(0, px, py, ptr6[i]);
-			}			
+			}
 		}
 
 		l = 0;
@@ -798,7 +798,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS
 			ptr5[i] += 5;
 			ptr3[i] += ptr5[i];
 			ptr8[i] += ptr7[i];
-				
+
 			int16 px = ((ptr2[i] >> 6) >> scale) + gx2;
 			int16 py = ((ptr3[i] >> 6) >> scale) + gy2;
 			if (py >= ymax || py < ymin)
@@ -808,7 +808,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS
 
 			if (py > ymax)
 				py = ymax;
-			
+
 			int pxVal1 = 0;
 			if (posWithinRect(px, py, 0, 0, 319, 199)) {
 				pxVal1 = getPagePixel(2, px, py);
@@ -833,7 +833,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS
 			}
 		}
 	}
-	
+
 	showMouse();
 }
 
diff --git a/engines/kyra/screen_eob.h b/engines/kyra/screen_eob.h
index d2d8881..78361eb 100644
--- a/engines/kyra/screen_eob.h
+++ b/engines/kyra/screen_eob.h
@@ -100,7 +100,7 @@ private:
 	static const int _screenDimTableCount;
 
 	ScreenDim **_customDimTable;
-	int _curDimIndex;	
+	int _curDimIndex;
 };
 
 }	// End of namespace Kyra
diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp
index 4123e89..c59c66b 100644
--- a/engines/kyra/script_eob.cpp
+++ b/engines/kyra/script_eob.cpp
@@ -737,7 +737,7 @@ int EobInfProcessor::oeob_eval_v1(int8 *data) {
 			debugC(5, kDebugLevelScript, "         - check if whole party is invisible - PUSH result: '%d'", a);
 			break;
 
-		case 1:			
+		case 1:
 			_stack[_stackIndex++] = _vm->rollDice(pos[0], pos[1], pos[2]);
 			debugC(9, kDebugLevelScript, "         - throw dice(s): num = '%d', pips = '%d', offset = '%d' - PUSH result: '%d'", pos[0], pos[1], pos[2], _stack[_stackIndex - 1]);
 			pos += 3;
@@ -1478,7 +1478,7 @@ int EobInfProcessor::oeob_sequence(int8 *data) {
 		return 0;
 
 	case -2:
-		_vm->seq_portal();		
+		_vm->seq_portal();
 		break;
 
 	case -1:
diff --git a/engines/kyra/script_eob.h b/engines/kyra/script_eob.h
index 8f883fd..a561568 100644
--- a/engines/kyra/script_eob.h
+++ b/engines/kyra/script_eob.h
@@ -32,7 +32,7 @@
 
 namespace Kyra {
 
-class LolEobBaseEngine;
+class KyraRpgEngine;
 
 class EobInfProcessor {
 public:
diff --git a/engines/kyra/sequences_eob1.cpp b/engines/kyra/sequences_eob1.cpp
index 2ff4a3a..b25de5c 100644
--- a/engines/kyra/sequences_eob1.cpp
+++ b/engines/kyra/sequences_eob1.cpp
@@ -38,7 +38,7 @@ int EobEngine::mainMenu() {
 	_menuChoiceInit = 0;
 
 	Screen::FontId of = _screen->_currentFont;
-	
+
 	while (menuChoice >= 0 && !shouldQuit()) {
 		switch (menuChoice) {
 			case 0:
@@ -162,25 +162,25 @@ void EobEngine::seq_playFinale() {
 	delete s;
 
 	snd_playSoundEffect(20);
-	
+
 	_txt->resetPageBreakString();
 	_txt->setWaitButtonMode(1);
 	_txt->setupField(12, true);
 	gui_drawBox(0, 0, 176, 175, _color1_1, _color2_1, _bkgColor_1);
 	_txt->printDialogueText(51, _moreStrings[0]);
-	
+
 	if (!checkScriptFlags(0x1ffe)) {
 		_screen->fadeToBlack();
 		return;
 	}
-	
+
 	_txt->printDialogueText(_finBonusStrings[0]);
 	for (int i = 0; i < 6; i++) {
 		_txt->printDialogueText(_finBonusStrings[1]);
 		if (_characters[i].flags & 1)
 			_txt->printDialogueText(_characters[i].name);
 	}
-	
+
 	uint32 password = 0;
 	for (int i = 0; i < 4; i++) {
 		if (!(_characters[i].flags & 1))
@@ -200,7 +200,7 @@ void EobEngine::seq_playFinale() {
 void EobEngine::seq_tower() {
 	if (shouldQuit() || skipFlag())
 		return;
-	
+
 	_screen->loadBitmap(_introFilesTower[1], 5, 3, 0);
 	_screen->setCurPage(2);
 	uint8 *shp = _screen->encodeShape(0, 0, 16, 56, true);
@@ -239,7 +239,7 @@ void EobEngine::seq_tower() {
 		_screen->copyRegion(104, 79 - i, 200, 0, 24, 65 + i, 4, 0, Screen::CR_NO_P_CHECK);
 		_screen->copyRegion(24, 110, 120, i + 31, 80, 34, 4, 0, Screen::CR_NO_P_CHECK);
 		_screen->copyRegion(152, 0, 120, 32, 80, i + 1, 4, 0, Screen::CR_NO_P_CHECK);
-		_screen->copyRegion(0, 0, 96, 65 + i, 128, 103 - i, 2, 0, Screen::CR_NO_P_CHECK);	
+		_screen->copyRegion(0, 0, 96, 65 + i, 128, 103 - i, 2, 0, Screen::CR_NO_P_CHECK);
 		_screen->updateScreen();
 		delayUntil(end);
 	}
@@ -282,18 +282,18 @@ void EobEngine::seq_orb() {
 	shp[4] = _screen->encodeShape(0, 0, 20, 136, true);
 	_screen->loadBitmap(_introFilesOrb[1], 5, 3, 0);
 	shp[3] = _screen->encodeShape(16, 0, 16, 104, true);
-	
+
 	_screen->fillRect(0, 0, 127, 103, 12);
 	for (int i = 1; i < 4; i++) {
 		copyBlurRegion(128, 0, 0, 0, 128, 104, i);
 		shp[3 - i] = _screen->encodeShape(0, 0, 16, 104, true);
 	}
-	
+
 	_screen->fillRect(0, 0, 159, 135, 12);
 	_screen->setCurPage(0);
 	_screen->copyPage(3, 4);
 	_screen->clearCurPage();
-	
+
 	_sound->playTrack(6);
 
 	for (int i = -1; i < 4 && !shouldQuit() && !skipFlag(); i++) {
@@ -467,7 +467,7 @@ void EobEngine::seq_king() {
 	static const uint8 advEncX[] = { 0, 6, 12, 19 };
 	static const uint8 advEncW[] = { 6, 6, 7, 6 };
 	static const int8 modY[] = { -4, -8, -2, -2, 1, 0, 0, 0 };
-	
+
 	_screen->loadBitmap(_introFilesKing[1], 5, 3, 0);
 	_screen->setCurPage(2);
 	for (int i = 0; i < 4; i++) {
@@ -481,7 +481,7 @@ void EobEngine::seq_king() {
 	for (bool runloop = true; runloop && !shouldQuit() && !skipFlag(); ) {
 		runloop = false;
 		uint32 end = _system->getMillis() + 2 * _tickLength;
-		
+
 		for (int i = 0; i < 4; i++) {
 			if (dy[i] <= 82)
 				continue;
@@ -527,7 +527,7 @@ void EobEngine::seq_hands() {
 	_screen->fillRect(0, 160, 319, 199, 12, 0);
 	_screen->fillRect(0, 0, 191, 63, 157, 2);
 	_screen->drawShape(2, shp1, 0, 4, 0);
-	_screen->drawShape(2, shp2, 151, 4, 0);	
+	_screen->drawShape(2, shp2, 151, 4, 0);
 	boxMorphTransition(25, 8, 18, 4, 3, 0, 21, 8, 6, 0, 28, 23);
 	_screen->copyRegion(0, 128, 0, 176, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
 
@@ -540,7 +540,7 @@ void EobEngine::seq_hands() {
 		_screen->fillRect(0, 0, 167, 63, 157);
 		_screen->drawShape(2, shp1, i, 4, 0);
 		_screen->drawShape(2, shp1, 105 - i, 4, 0);
-		_screen->copyRegion(0, 0, 144, 32, 168, 64, 2, 0, Screen::CR_NO_P_CHECK);		
+		_screen->copyRegion(0, 0, 144, 32, 168, 64, 2, 0, Screen::CR_NO_P_CHECK);
 		_screen->updateScreen();
 		delayUntil(end);
 	}
@@ -555,7 +555,7 @@ void EobEngine::seq_hands() {
 	shp1 = _screen->encodeShape(17, 0, 11, 120, true);
 	shp2 = _screen->encodeShape(28, 112, 1, 31, true);
 	uint8 *shp3 = _screen->encodeShape(9, 138, 14, 54, true);
-	
+
 	_screen->setCurPage(2);
 	_screen->fillRect(0, 0, 135, 63, 157);
 	_screen->drawShape(2, shp1, 32, -80, 0);
@@ -568,7 +568,7 @@ void EobEngine::seq_hands() {
 		_screen->fillRect(0, 0, 135, 63, 157);
 		_screen->drawShape(2, shp1, 32, i, 0);
 		_screen->drawShape(2, shp2, 40, i + 64, 0);
-		_screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK);		
+		_screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK);
 		_screen->updateScreen();
 		delayUntil(end);
 	}
@@ -581,7 +581,7 @@ void EobEngine::seq_hands() {
 		_screen->fillRect(0, 0, 135, 63, 157);
 		_screen->drawShape(2, shp3, 12, 64 + i, 0);
 		_screen->drawShape(2, shp1, 32, i, 0);
-		_screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK);		
+		_screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK);
 		_screen->updateScreen();
 		delayUntil(end);
 	}
@@ -608,7 +608,7 @@ void EobEngine::seq_hands() {
 		_screen->fillRect(0, 0, 143, 95, 157);
 		_screen->drawShape(2, shp1, i, i, 0);
 		_screen->drawShape(2, shp2, (i == -8) ? 55 : 52, (i == -8) ? 52 : 49, 0);
-		_screen->copyRegion(0, 0, 0, 0, 144, 96, 2, 0, Screen::CR_NO_P_CHECK);		
+		_screen->copyRegion(0, 0, 0, 0, 144, 96, 2, 0, Screen::CR_NO_P_CHECK);
 		_screen->updateScreen();
 		delayUntil(end);
 	}
@@ -633,7 +633,7 @@ void EobEngine::seq_hands() {
 		uint32 end = _system->getMillis() + _tickLength;
 		_screen->fillRect(0, 0, 87, 112, 157);
 		_screen->drawShape(2, shp2, 0, dy, 0);
-		_screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK);		
+		_screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK);
 		_screen->updateScreen();
 		delayUntil(end);
 		dy -= 5;
@@ -645,7 +645,7 @@ void EobEngine::seq_hands() {
 		uint32 end = _system->getMillis() + _tickLength;
 		_screen->fillRect(0, 0, 87, 39, 157);
 		_screen->drawShape(2, shp1, 0, i, 0);
-		_screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK);		
+		_screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK);
 		_screen->updateScreen();
 		delayUntil(end);
 	}
@@ -837,7 +837,7 @@ void EobEngine::seq_tunnel() {
 	_sound->playTrack(9);
 
 	for (int i = 0; i < 6 && !shouldQuit() && !skipFlag(); i++) {
-		uint32 end = _system->getMillis() + _tickLength;		
+		uint32 end = _system->getMillis() + _tickLength;
 		_screen->copyRegion(_introTvlX1[i] << 3, _introTvlY1[i], _introTvlX2[i] << 3, _introTvlY2[i], _introTvlW[i] << 3, _introTvlH[i], 4, 2, Screen::CR_NO_P_CHECK);
 		for (int ii = 0; ii < 4 && !shouldQuit() && !skipFlag(); ii++) {
 			_screen->updateScreen();
@@ -864,13 +864,13 @@ void EobEngine::seq_tunnel() {
 	_screen->copyRegion(0, 176, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
 	_screen->setCurPage(0);
 	_screen->updateScreen();
-	delay(50 * _tickLength);	
+	delay(50 * _tickLength);
 }
 
 void EobEngine::seq_xdeath() {
 	uint8 *shapes1[5];
 	uint8 *shapes2;
-	
+
 	_screen->loadShapeSetBitmap("XDEATH2", 5, 3);
 	for (int i = 0; i < 4; i++)
 		shapes1[i] = _screen->encodeShape(i / 2 * 14, i / 2 * 88, 14, 88, true);
@@ -910,7 +910,7 @@ void EobEngine::seq_xdeath() {
 		_screen->updateScreen();
 		delay(2 * _tickLength);
 	}
-	
+
 	_screen->modifyScreenDim(5, dm->sx, 0, dm->w, dm->h);
 
 	snd_playSoundEffect(5);
diff --git a/engines/kyra/sequences_eob2.cpp b/engines/kyra/sequences_eob2.cpp
index 597d84d..433ee4a 100644
--- a/engines/kyra/sequences_eob2.cpp
+++ b/engines/kyra/sequences_eob2.cpp
@@ -1278,7 +1278,7 @@ void DarkMoonEngine::seq_nightmare() {
 
 	initDialogueSequence();
 	gui_drawDialogueBox();
-	
+
 	_txt->printDialogueText(99, 0);
 	snd_playSoundEffect(54);
 
@@ -1292,7 +1292,7 @@ void DarkMoonEngine::seq_nightmare() {
 	}
 
 	_txt->printDialogueText(20, _okStrings[0]);
-	
+
 	restoreAfterDialogueSequence();
 
 	_screen->setFont(of);
@@ -1303,7 +1303,7 @@ void DarkMoonEngine::seq_kheldran() {
 
 	initDialogueSequence();
 	gui_drawDialogueBox();
-	
+
 	static const char file[] = "KHELDRAN";
 	_txt->printDialogueText(_kheldranStrings[0]);
 	drawSequenceBitmap(file, 0, 0, 0, 0);
@@ -1316,7 +1316,7 @@ void DarkMoonEngine::seq_kheldran() {
 	drawSequenceBitmap(file, 0, 20, 96, 0);
 	delay(7 * _tickLength);
 	_txt->printDialogueText(76, _okStrings[0]);
-	
+
 	restoreAfterDialogueSequence();
 
 	_screen->setFont(of);
@@ -1327,7 +1327,7 @@ void DarkMoonEngine::seq_dranDragonTransformation() {
 
 	initDialogueSequence();
 	gui_drawDialogueBox();
-	
+
 	static const char file[] = "DRANX";
 	drawSequenceBitmap(file, 0, 0, 0, 0);
 	_txt->printDialogueText(120, _moreStrings[0]);
@@ -1338,7 +1338,7 @@ void DarkMoonEngine::seq_dranDragonTransformation() {
 	delay(7 * _tickLength);
 	drawSequenceBitmap(file, 0, 20, 96, 0);
 	delay(18 * _tickLength);
-	
+
 	restoreAfterDialogueSequence();
 
 	_screen->setFont(of);
diff --git a/engines/kyra/sound_lol.cpp b/engines/kyra/sound_lol.cpp
index a37ec9f..cb9be43 100644
--- a/engines/kyra/sound_lol.cpp
+++ b/engines/kyra/sound_lol.cpp
@@ -198,7 +198,7 @@ void LoLEngine::snd_playSoundEffect(int track, int volume) {
 }
 
 bool LoLEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) {
-	if (!LolEobBaseEngine::snd_processEnvironmentalSoundEffect(soundId, block))
+	if (!KyraRpgEngine::snd_processEnvironmentalSoundEffect(soundId, block))
 		return false;
 
 	if (block != _currentBlock) {
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index 6d8776f..9adf84d 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -20,7 +20,7 @@
  *
  */
 
-#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+#ifdef ENABLE_EOB
 
 #include "kyra/eobcommon.h"
 #include "kyra/script_eob.h"
@@ -29,31 +29,10 @@
 
 #include "common/system.h"
 
-namespace Kyra {
-
-int LolEobBaseEngine::getBlockDistance(uint16 block1, uint16 block2) {
-	int b1x = block1 & 0x1f;
-	int b1y = block1 >> 5;
-	int b2x = block2 & 0x1f;
-	int b2y = block2 >> 5;
-
-	uint8 dy = ABS(b2y - b1y);
-	uint8 dx = ABS(b2x - b1x);
-
-	if (dx > dy)
-		SWAP(dx, dy);
-
-	return (dx >> 1) + dy;
-}
-
-} // namespace Kyra
-
-#endif
-#ifdef ENABLE_EOB
 
 namespace Kyra {
 
-void EobCoreEngine::loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex) {	
+void EobCoreEngine::loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex) {
 	_screen->loadShapeSetBitmap(filename, 3, 3);
 	const uint16 *enc = &_encodeMonsterShpTable[encodeTableIndex << 2];
 
diff --git a/engines/kyra/sprites_rpg.cpp b/engines/kyra/sprites_rpg.cpp
new file mode 100644
index 0000000..0c4fcb0
--- /dev/null
+++ b/engines/kyra/sprites_rpg.cpp
@@ -0,0 +1,46 @@
+/* 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.
+ *
+ */
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#include "kyra/kyra_rpg.h"
+
+namespace Kyra {
+
+int KyraRpgEngine::getBlockDistance(uint16 block1, uint16 block2) {
+	int b1x = block1 & 0x1f;
+	int b1y = block1 >> 5;
+	int b2x = block2 & 0x1f;
+	int b2y = block2 >> 5;
+
+	uint8 dy = ABS(b2y - b1y);
+	uint8 dx = ABS(b2x - b1x);
+
+	if (dx > dy)
+		SWAP(dx, dy);
+
+	return (dx >> 1) + dy;
+}
+
+} // namespace Kyra
+
+#endif
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 7433fbf..faa2591 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -22,23 +22,11 @@
  */
 
 #include "kyra/eob1.h"
-#include "kyra/eob2.h"
 #include "kyra/resource.h"
 
 
 namespace Kyra {
 
-
-#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
-const uint16 *StaticResource::loadRawDataBe16(int id, int &entries) {
-	return (const uint16 *)getData(id, kLolRawDataBe16, entries);
-}
-
-const uint32 *StaticResource::loadRawDataBe32(int id, int &entries) {
-	return (const uint32 *)getData(id, kLolRawDataBe32, entries);
-}
-#endif // defined(ENABLE_EOB) || defined(ENABLE_LOL)
-
 #ifdef ENABLE_EOB
 const EobSequenceStep *StaticResource::loadEob2SeqData(int id, int &entries) {
 	return (const EobSequenceStep *)getData(id, kEob2SequenceData, entries);
@@ -51,35 +39,7 @@ const EobShapeDef *StaticResource::loadEob2ShapeData(int id, int &entries) {
 const EobCharacter *StaticResource::loadEobNpcData(int id, int &entries) {
 	return (const EobCharacter *)getData(id, kEobNpcData, entries);
 }
-#endif // ENABLE_EOB
-
-#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
-bool StaticResource::loadRawDataBe16(Common::SeekableReadStream &stream, void *&ptr, int &size) {
-	size = stream.size() >> 1;
-
-	uint16 *r = new uint16[size];
-
-	for (int i = 0; i < size; i++)
-		r[i] = stream.readUint16BE();
-
-	ptr = r;
-	return true;
-}
-
-bool StaticResource::loadRawDataBe32(Common::SeekableReadStream &stream, void *&ptr, int &size) {
-	size = stream.size() >> 2;
-
-	uint32 *r = new uint32[size];
-
-	for (int i = 0; i < size; i++)
-		r[i] = stream.readUint32BE();
-
-	ptr = r;
-	return true;
-}
-#endif // defined(ENABLE_EOB) || defined(ENABLE_LOL)
 
-#ifdef ENABLE_EOB
 bool StaticResource::loadEob2SeqData(Common::SeekableReadStream &stream, void *&ptr, int &size) {
 	size = stream.size() / 11;
 
@@ -165,25 +125,7 @@ bool StaticResource::loadEobNpcData(Common::SeekableReadStream &stream, void *&p
 	ptr = e;
 	return true;
 }
-#endif // ENABLE_EOB
 
-#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
-void StaticResource::freeRawDataBe16(void *&ptr, int &size) {
-	uint16 *data = (uint16 *)ptr;
-	delete[] data;
-	ptr = 0;
-	size = 0;
-}
-
-void StaticResource::freeRawDataBe32(void *&ptr, int &size) {
-	uint32 *data = (uint32 *)ptr;
-	delete[] data;
-	ptr = 0;
-	size = 0;
-}
-#endif // defined(ENABLE_EOB) || defined(ENABLE_LOL)
-
-#ifdef ENABLE_EOB
 void StaticResource::freeEob2SeqData(void *&ptr, int &size) {
 	EobSequenceStep *d = (EobSequenceStep *)ptr;
 	delete[] d;
@@ -238,29 +180,6 @@ const ScreenDim Screen_Eob::_screenDimTable[] = {
 };
 
 const int Screen_Eob::_screenDimTableCount = ARRAYSIZE(Screen_Eob::_screenDimTable);
-#endif
-
-#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
-const uint8 LolEobBaseEngine::_dropItemDirIndex[] = { 0, 1, 2, 3, 1, 3, 0, 2, 3, 2, 1, 0, 2, 0, 3, 1 };
-
-void LolEobBaseEngine::initStaticResource() {
-	int temp;
-	_dscShapeX = (const int16 *)_staticres->loadRawDataBe16(kLolEobCommonDscX, temp);
-	_dscShapeIndex = (const int8 *)_staticres->loadRawData(kLolEobCommonDscShapeIndex, temp);
-	_dscTileIndex = _staticres->loadRawData(kLolEobCommonDscTileIndex, temp);
-	_dscDim1 = (const int8 *)_staticres->loadRawData(kLolEobCommonDscDimData1, temp);
-	_dscDim2 = (const int8 *)_staticres->loadRawData(kLolEobCommonDscDimData2, temp);
-	_dscUnk2 = _staticres->loadRawData(kLolEobCommonDscUnk2, temp);
-	_dscBlockMap = _staticres->loadRawData(kLolEobCommonDscBlockMap, temp);
-	_dscBlockIndex = (const int8 *)_staticres->loadRawData(kLolEobCommonDscBlockIndex, temp);
-	_dscDimMap = _staticres->loadRawData(kLolEobCommonDscDimMap, temp);
-	_dscDoorShpIndex = _staticres->loadRawData(kLolEobCommonDscDoorShapeIndex, _dscDoorShpIndexSize);
-	_dscDoorY2 = _staticres->loadRawData(kLolEobCommonDscDoorY2, temp);
-	_moreStrings = _staticres->loadStrings(kLolEobCommonMoreStrings, temp);
-}
-
-#endif // (ENABLE_EOB || ENABLE_LOL)
-#ifdef ENABLE_EOB
 
 const uint8 EobCoreEngine::_hpIncrPerLevel[] = { 10, 4, 8, 6, 10, 10, 9, 10, 9, 10, 9, 9, 3, 1, 2, 2, 3, 3 };
 
@@ -373,7 +292,7 @@ void EobCoreEngine::initStaticResource() {
 	_potionStrings = _staticres->loadStrings(kEobBasePotionStrings, temp);
 	_wandStrings = _staticres->loadStrings(kEobBaseWandStrings, temp);
 	_itemMisuseStrings = _staticres->loadStrings(kEobBaseItemMisuseStrings, temp);
-	
+
 	_takenStrings = _staticres->loadStrings(kEobBaseTakenStrings, temp);
 	_potionEffectStrings = _staticres->loadStrings(kEobBasePotionEffectStrings, temp);
 
@@ -559,7 +478,7 @@ void EobCoreEngine::initStaticResource() {
 		" Spielstände müssen\r einen Namen haben!",
 		0
 	};
-	
+
 	_saveLoadStrings = saveLoadStrings[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
 	_errorSlotEmptyString = errorSlotEmptyString[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
 	_errorSlotNoNameString = errorSlotNoNameString[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
@@ -587,7 +506,7 @@ void EobCoreEngine::initButtonData() {
 		{ 0, 0, 0x1100, 288, 62, 31, 33, 3 },
 		{ 368, 0, 0x1000, 184, 2, 63, 8, 0 },
 		{ 369, 0, 0x1000, 256, 2, 63, 8, 1 },
-		{ 370, 0, 0x1000, 184, 54, 63, 8, 2 },		
+		{ 370, 0, 0x1000, 184, 54, 63, 8, 2 },
 		{ 371, 0, 0x1000, 256, 54, 63, 8, 3 },
 		{ 0, 0, 0x1100, 230, 116, 16, 16, 0 },
 		{ 0, 0, 0x1100, 278, 116, 16, 16, 1 },
@@ -597,7 +516,7 @@ void EobCoreEngine::initButtonData() {
 		{ 0, 0, 0x1100, 199, 58, 16, 16, 5 },
 		{ 0, 0, 0x1100, 181, 76, 16, 16, 6 },
 		{ 0, 0, 0x1100, 199, 76, 16, 16, 7 },
-		{ 0, 0, 0x1100, 181, 94, 16, 16, 8 },		
+		{ 0, 0, 0x1100, 181, 94, 16, 16, 8 },
 		{ 0, 0, 0x1100, 199, 94, 16, 16, 9 },
 		{ 0, 0, 0x1100, 181, 112, 16, 16, 10 },
 		{ 0, 0, 0x1100, 199, 112, 16, 16, 11 },
@@ -785,7 +704,7 @@ void EobCoreEngine::initMenus() {
 	delete[] _menuDefs;
 	_menuDefs = new EobMenuDef[ARRAYSIZE(menuDefs)];
 	memcpy(_menuDefs, menuDefs, sizeof(menuDefs));
-	
+
 	if (_flags.gameID == GI_EOB1) {
 		// assign EOB 1 style memorize/pray menu
 		_menuDefs[4].numButtons = 8;
@@ -1061,7 +980,7 @@ void EobCoreEngine::initSpells() {
 	ec2(monster_fleshToStone);
 
 	_spells = new EobSpell[_numSpells];
-	memset(_spells, 0, _numSpells * sizeof(EobSpell));	
+	memset(_spells, 0, _numSpells * sizeof(EobSpell));
 
 	for (int i = 0, n = 0; i < _numSpells; i++, n++) {
 		EobSpell *s = &_spells[i];
@@ -1103,7 +1022,7 @@ void EobEngine::initStaticResource() {
 	int temp;
 	_mainMenuStrings = _staticres->loadStrings(kEob1MainMenuStrings, temp);
 	_finBonusStrings = _staticres->loadStrings(kEob1BonusStrings, temp);
-		
+
 	_introFilesOpening = _staticres->loadStrings(kEob1IntroFilesOpening, temp);
 	_introFilesTower = _staticres->loadStrings(kEob1IntroFilesTower, temp);
 	_introFilesOrb = _staticres->loadStrings(kEob1IntroFilesOrb, temp);
diff --git a/engines/kyra/staticres_rpg.cpp b/engines/kyra/staticres_rpg.cpp
new file mode 100644
index 0000000..49a55fc
--- /dev/null
+++ b/engines/kyra/staticres_rpg.cpp
@@ -0,0 +1,97 @@
+/* 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.
+ *
+ *
+ */
+
+#include "kyra/resource.h"
+
+
+namespace Kyra {
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+const uint16 *StaticResource::loadRawDataBe16(int id, int &entries) {
+	return (const uint16 *)getData(id, kLolRawDataBe16, entries);
+}
+
+const uint32 *StaticResource::loadRawDataBe32(int id, int &entries) {
+	return (const uint32 *)getData(id, kLolRawDataBe32, entries);
+}
+
+bool StaticResource::loadRawDataBe16(Common::SeekableReadStream &stream, void *&ptr, int &size) {
+	size = stream.size() >> 1;
+
+	uint16 *r = new uint16[size];
+
+	for (int i = 0; i < size; i++)
+		r[i] = stream.readUint16BE();
+
+	ptr = r;
+	return true;
+}
+
+bool StaticResource::loadRawDataBe32(Common::SeekableReadStream &stream, void *&ptr, int &size) {
+	size = stream.size() >> 2;
+
+	uint32 *r = new uint32[size];
+
+	for (int i = 0; i < size; i++)
+		r[i] = stream.readUint32BE();
+
+	ptr = r;
+	return true;
+}
+
+void StaticResource::freeRawDataBe16(void *&ptr, int &size) {
+	uint16 *data = (uint16 *)ptr;
+	delete[] data;
+	ptr = 0;
+	size = 0;
+}
+
+void StaticResource::freeRawDataBe32(void *&ptr, int &size) {
+	uint32 *data = (uint32 *)ptr;
+	delete[] data;
+	ptr = 0;
+	size = 0;
+}
+
+const uint8 KyraRpgEngine::_dropItemDirIndex[] = { 0, 1, 2, 3, 1, 3, 0, 2, 3, 2, 1, 0, 2, 0, 3, 1 };
+
+void KyraRpgEngine::initStaticResource() {
+	int temp;
+	_dscShapeX = (const int16 *)_staticres->loadRawDataBe16(kLolEobCommonDscX, temp);
+	_dscShapeIndex = (const int8 *)_staticres->loadRawData(kLolEobCommonDscShapeIndex, temp);
+	_dscTileIndex = _staticres->loadRawData(kLolEobCommonDscTileIndex, temp);
+	_dscDim1 = (const int8 *)_staticres->loadRawData(kLolEobCommonDscDimData1, temp);
+	_dscDim2 = (const int8 *)_staticres->loadRawData(kLolEobCommonDscDimData2, temp);
+	_dscUnk2 = _staticres->loadRawData(kLolEobCommonDscUnk2, temp);
+	_dscBlockMap = _staticres->loadRawData(kLolEobCommonDscBlockMap, temp);
+	_dscBlockIndex = (const int8 *)_staticres->loadRawData(kLolEobCommonDscBlockIndex, temp);
+	_dscDimMap = _staticres->loadRawData(kLolEobCommonDscDimMap, temp);
+	_dscDoorShpIndex = _staticres->loadRawData(kLolEobCommonDscDoorShapeIndex, _dscDoorShpIndexSize);
+	_dscDoorY2 = _staticres->loadRawData(kLolEobCommonDscDoorY2, temp);
+	_moreStrings = _staticres->loadStrings(kLolEobCommonMoreStrings, temp);
+}
+
+#endif // (ENABLE_EOB || ENABLE_LOL)
+
+} // End of namespace Kyra
+
diff --git a/engines/kyra/text_eob.cpp b/engines/kyra/text_eob.cpp
deleted file mode 100644
index 1c0c7e5..0000000
--- a/engines/kyra/text_eob.cpp
+++ /dev/null
@@ -1,688 +0,0 @@
-/* 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.
- *
- *
- */
-
-#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
-
-#include "kyra/loleobbase.h"
-#include "kyra/screen.h"
-#include "kyra/timer.h"
-
-#include "common/system.h"
-
-namespace Kyra {
-
-enum {
-	kEobTextBufferSize = 2048
-};
-
-TextDisplayer_Eob::TextDisplayer_Eob(LolEobBaseEngine *engine, Screen *sScreen) : _vm(engine), _screen(sScreen),
-	_lineCount(0), _printFlag(false), _lineWidth(0), _numCharsTotal(0), _allowPageBreak(true),
-	_numCharsLeft(0), _numCharsPrinted(0), _sjisLineBreakFlag(false), _waitButtonMode(1) {
-
-	_dialogueBuffer = new char[kEobTextBufferSize];
-	memset(_dialogueBuffer, 0, kEobTextBufferSize);
-
-	_currentLine = new char[85];
-	memset(_currentLine, 0, 85);
-
-	_textDimData = new TextDimData[_screen->screenDimTableCount()];
-
-	for (int i = 0; i < _screen->screenDimTableCount(); i++){
-		const ScreenDim *d = _screen->getScreenDim(i);
-		_textDimData[i].color1 = d->unk8;
-		_textDimData[i].color2 = d->unkA;
-		_textDimData[i].line = d->unkC;
-		_textDimData[i].column = d->unkE;
-	}
-
-	_table1 = new char[128];
-	memset(_table1, 0, 128);
-	_table2 = new char[16];
-	memset(_table2, 0, 16);
-
-	_waitButtonSpace = 0;
-}
-
-TextDisplayer_Eob::~TextDisplayer_Eob() {
-	delete[] _dialogueBuffer;
-	delete[] _currentLine;
-	delete[] _textDimData;
-	delete[] _table1;
-	delete[] _table2;
-}
-
-void TextDisplayer_Eob::setupField(int dim, bool mode) {
-	setPageBreakFlag();
-
-	_textDimData[dim].color2 = _vm->_bkgColor_1;
-	_screen->setScreenDim(dim);
-
-	if (mode)
-		clearCurDim();
-	else
-		resetDimTextPositions(dim);
-}
-
-void TextDisplayer_Eob::resetDimTextPositions(int dim) {
-	_textDimData[dim].column = 0;
-	_textDimData[dim].line = 0;
-}
-
-void TextDisplayer_Eob::resetPageBreakString() {
-	if (vm()->_moreStrings)
-		strcpy(_pageBreakString, vm()->_moreStrings[0]);
-}
-
-void TextDisplayer_Eob::setPageBreakFlag() {
-	_allowPageBreak = true;
-	_lineCount = 0;
-}
-
-void TextDisplayer_Eob::removePageBreakFlag() {
-	_allowPageBreak = false;
-}
-
-void TextDisplayer_Eob::displayText(char *str, ...) {
-	const bool isPc98 = (_vm->gameFlags().platform == Common::kPlatformPC98);
-
-	_printFlag = false;
-
-	_lineWidth = 0;
-	_numCharsLeft = 0;
-	_numCharsPrinted = 0;
-
-	_tempString1 = str;
-	_tempString2 = 0;
-
-	_currentLine[0] = 0;
-
-	memset(_ctrl, 0, 3);
-
-	char c = parseCommand();
-
-	va_list args;
-	va_start(args, str);
-
-	const ScreenDim *sd = _screen->_curDim;
-	int sdx = _screen->curDimIndex();
-
-	bool pc98PrintFlag = (isPc98 && (sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) ? true : false;
-	uint16 charsPerLine = (sd->w << 3) / (_screen->getFontWidth() + _screen->_charWidth);
-
-	while (c) {
-		char a = tolower(_ctrl[1]);
-
-		if (!_tempString2 && c == '%') {
-			if (a == 'd') {
-				strcpy(_scriptParaString, Common::String::format("%d", va_arg(args, int)).c_str());
-				_tempString2 = _scriptParaString;
-			} else if (a == 's') {
-				_tempString2 = va_arg(args, char *);
-			} else {
-				break;
-			}
-
-			_ctrl[0] = _ctrl[2];
-			_ctrl[2] = _ctrl[1] = 0;
-			c = parseCommand();
-		}
-
-		if (isPc98) {
-			uint8 cu = (uint8) c;
-			if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0)) {
-				_currentLine[_numCharsLeft++] = c;
-				_currentLine[_numCharsLeft++] = parseCommand();
-				_currentLine[_numCharsLeft] = '\0';
-				_lineWidth += 8;
-				if ((_textDimData[sdx].column + _lineWidth) > (sd->w << 3))
-					printLine(_currentLine);
-				c = parseCommand();
-				continue;
-			}
-		}
-
-		uint16 dv = _textDimData[sdx].column / (_screen->getFontWidth() + _screen->_charWidth);
-
-		switch (c - 1) {
-		case 0:
-			printLine(_currentLine);
-			textPageBreak();
-			_numCharsPrinted = 0;
-			break;
-
-		case 1:
-			printLine(_currentLine);
-			_textDimData[sdx].color2 = parseCommand();
-			break;
-
-		case 5:
-			printLine(_currentLine);
-			_textDimData[sdx].color1 = parseCommand();
-			break;
-
-		case 8:
-			printLine(_currentLine);
-			dv = _textDimData[sdx].column / (_screen->getFontWidth() + _screen->_charWidth);
-			dv = ((dv + 8) & 0xfff8) - 1;
-			if (dv >= charsPerLine)
-				dv = 0;
-			_textDimData[sdx].column = (_screen->getFontWidth() + _screen->_charWidth) * dv;
-			break;
-
-		case 11:
-			_sjisLineBreakFlag=_sjisLineBreakFlag;
-			// TODO (UNUSED)
-			break;
-
-		case 12:
-			if (isPc98)
-				_sjisLineBreakFlag = true;
-			printLine(_currentLine);
-			_sjisLineBreakFlag = false;
-			_lineCount++;
-			_textDimData[sdx].column = 0;
-			_textDimData[sdx].line++;
-			break;
-
-		case 18:
-			_sjisLineBreakFlag=_sjisLineBreakFlag;
-			// TODO (UNUSED)
-			break;
-
-		case 23:
-			_sjisLineBreakFlag=_sjisLineBreakFlag;
-			// TODO (UNUSED)
-			break;
-
-		case 24:
-			_sjisLineBreakFlag=_sjisLineBreakFlag;
-			// TODO (UNUSED)
-			break;
-
-		case 26:
-			_sjisLineBreakFlag=_sjisLineBreakFlag;
-			// TODO (UNUSED)
-			break;
-
-		case 28:
-			_sjisLineBreakFlag=_sjisLineBreakFlag;
-			// TODO (UNUSED)
-			break;
-
-		default:
-			if (_vm->game() == GI_LOL || c > 30) {
-				_lineWidth += (pc98PrintFlag ? 4 : _screen->getCharWidth((uint8)c));
-				_currentLine[_numCharsLeft++] = c;
-				_currentLine[_numCharsLeft] = 0;
-
-				if ((_textDimData[sdx].column + _lineWidth) > (sd->w << 3))
-					printLine(_currentLine);
-			}
-		}
-
-		c = parseCommand();
-	}
-
-	va_end(args);
-
-	if (_numCharsLeft)
-		printLine(_currentLine);
-}
-
-char TextDisplayer_Eob::parseCommand() {
-	if (!_ctrl[1])
-		readNextPara();
-
-	char res = _ctrl[1];
-	_ctrl[1] = _ctrl[2];
-	_ctrl[2] = 0;
-
-	if (!_ctrl[1])
-		readNextPara();
-
-	return res;
-}
-
-void TextDisplayer_Eob::readNextPara() {
-	char c = 0;
-	char d = 0;
-
-	if (_tempString2) {
-		if (*_tempString2) {
-			d = *_tempString2++;
-		} else {
-			_tempString2 = 0;
-			d = _ctrl[0];
-		}
-	}
-
-	if (!d && _tempString1) {
-		if (*_tempString1)
-			d = *_tempString1++;
-		else
-			_tempString1 = 0;
-	}
-
-	if ((_vm->game() != GI_LOL) && (d & 0x80)) {		
-		d &= 0x7f;
-		c = d & 7;
-		d = (d & 0x78) >> 3;
-		uint8 l = d;
-		c = _table1[(l << 3) + c];
-		d = _table2[l];
-	}
-
-	_ctrl[1] = d;
-	_ctrl[2] = c;
-}
-
-void TextDisplayer_Eob::printLine(char *str) {
-	const bool isPc98 = (_vm->gameFlags().platform == Common::kPlatformPC98);
-	const ScreenDim *sd = _screen->_curDim;
-	int sdx = _screen->curDimIndex();
-	bool pc98PrintFlag = (isPc98 && (sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) ? true : false;
-
-	int fh = (_screen->_currentFont == Screen::FID_SJIS_FNT) ? 9 : (_screen->getFontHeight() + _screen->_charOffset);
-	int lines = (sd->h - _screen->_charOffset) / fh;
-
-	while (_textDimData[sdx].line >= lines) {
-		if ((lines - _waitButtonSpace) <= _lineCount && _allowPageBreak) {
-			_lineCount = 0;
-			textPageBreak();
-			_numCharsPrinted = 0;
-		}
-
-		int h1 = ((sd->h / fh) - 1) * fh;
-		int h2 = sd->h - fh;
-
-		if (h2)
-			_screen->copyRegion(sd->sx << 3, sd->sy + fh, sd->sx << 3, sd->sy, sd->w << 3, h2, _screen->_curPage, _screen->_curPage, Screen::CR_NO_P_CHECK);
-
-		_screen->fillRect(sd->sx << 3, sd->sy + h1, ((sd->sx + sd->w) << 3) - 1, sd->sy + sd->h - 1, _textDimData[sdx].color2);
-		if (_textDimData[sdx].line)
-			_textDimData[sdx].line--;
-	}
-
-	int x1 = (sd->sx << 3) + _textDimData[sdx].column;
-	int y = sd->sy + (pc98PrintFlag ? (_textDimData[sdx].line << 3) : (fh * _textDimData[sdx].line));
-	int w = sd->w << 3;
-	int lw = _lineWidth;
-	int s = _numCharsLeft;
-	char c = 0;
-
-	if (pc98PrintFlag) {
-		bool ct = true;
-
-		if ((lw + _textDimData[sdx].column) > w) {
-			if ((lines - 1 - (_waitButtonSpace << 1)) <= _lineCount)
-				// cut off line to leave space for "MORE" button
-				w -= vm()->_waitButtonReverveW;
-		} else {
-			if (!_sjisLineBreakFlag || (_lineCount + 1 < lines - 1))
-				ct = false;
-			else
-				// cut off line to leave space for "MORE" button
-				w -= vm()->_waitButtonReverveW;
-		}
-
-		if (ct) {
-			w -= _textDimData[sdx].column;
-
-			int n2 = 0;
-			int n1 = (w / 4) - 1;
-
-			while (n2 < n1 && n2 < s) {
-				c = str[n2];
-				uint8 cu = (uint8) c;
-				if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0))
-					n2++;
-				n2++;
-			}
-			s = n2;
-		}
-	} else {
-		if ((lw + _textDimData[sdx].column) > w) {
-			if ((lines - 1) <= _lineCount && _allowPageBreak)
-				// cut off line to leave space for "MORE" button
-				w -= vm()->_waitButtonReverveW;
-
-			w -= _textDimData[sdx].column;
-
-			int n2 = 0;
-			int n1 = s - 1;
-
-			while (n1 > 0) {
-				//cut off line after last space
-				c = str[n1];
-
-				lw -= _screen->getCharWidth((uint8)c);
-
-				if (!n2 && lw <= w)
-					n2 = n1;
-
-				if (n2 && c == ' ') {
-					s = n1;
-					_printFlag = false;
-					break;
-				}
-				n1--;
-			}
-
-			if (!n1) {
-				if (_textDimData[sdx].column && !_printFlag) {
-					s = lw = 0;
-					_printFlag = true;
-				} else {
-					s = n2;
-				}
-			}
-		}
-	}
-
-	c = str[s];
-	str[s] = 0;
-
-	uint8 col = _textDimData[sdx].color1;
-	if (isPc98 && (sdx == 2 || sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) {
-		switch (_textDimData[sdx].color1) {
-		case 0x88:
-			col = 0x41;
-			break;
-		case 0x55:
-			col = 0x81;
-			break;
-		case 0xaa:
-			col = 0x21;
-			break;
-		case 0x99:
-			col = 0xa1;
-			break;
-		case 0x33:
-			col = 0xe1;
-			break;
-		case 0x18:
-			col = 0x61;
-			break;
-		default:
-			col = 1;
-			break;
-		}
-		_screen->printText(str, x1 & ~3, (y + 8) & ~7, col, 0);
-	} else {
-		_screen->printText(str, x1, y, col, _textDimData[sdx].color2);
-	}
-
-	_textDimData[sdx].column += lw;
-	_numCharsPrinted += strlen(str);
-
-	str[s] = c;
-
-	if (c == ' ')
-		s++;
-
-	if (str[s] == ' ')
-		s++;
-
-	uint32 len = strlen(&str[s]);
-	for (uint32 i = 0; i < len; i++)
-		str[i] = str[s + i];
-	str[len] = 0;
-
-	_numCharsLeft = strlen(str);
-	_lineWidth = pc98PrintFlag ? (_numCharsLeft << 2) : _screen->getTextWidth(str);
-
-	if (!_numCharsLeft && _textDimData[sdx].column < (sd->w << 3))
-		return;
-
-	_textDimData[sdx].column = 0;
-	_textDimData[sdx].line++;
-	_lineCount++;
-
-	printLine(str);
-}
-
-void TextDisplayer_Eob::printDialogueText(int stringId, const char *pageBreakString) {
-	const char * str = (const char *)(screen()->getCPagePtr(5) + READ_LE_UINT16(&screen()->getCPagePtr(5)[(stringId - 1) << 1]));
-	assert (strlen(str) < kEobTextBufferSize);
-	Common::strlcpy(_dialogueBuffer, str, kEobTextBufferSize);
-	
-	displayText(_dialogueBuffer);
-
-	if (pageBreakString) {
-		if (pageBreakString[0]) {
-			strcpy(_pageBreakString, pageBreakString);
-			displayWaitButton();
-			resetPageBreakString();
-		}
-	}
-}
-
-void TextDisplayer_Eob::printDialogueText(const char *str, bool wait) {
-	assert (strlen(str) < kEobTextBufferSize);
-	Common::strlcpy(_dialogueBuffer, str, kEobTextBufferSize);
-
-	strcpy(_dialogueBuffer, str);
-	displayText(_dialogueBuffer);
-	if (wait)
-		displayWaitButton();
-}
-
-void TextDisplayer_Eob::printMessage(const char *str, int textColor, ...) {
-	int tc = _textDimData[screen()->curDimIndex()].color1;
-
-	if (textColor != -1)
-		_textDimData[screen()->curDimIndex()].color1 = textColor;
-
-	va_list args;
-	va_start(args, textColor);
-	vsnprintf(_dialogueBuffer, kEobTextBufferSize - 1, str, args);
-	va_end(args);
-
-	displayText(_dialogueBuffer);
-
-	if (vm()->game() != GI_EOB1)
-		_textDimData[screen()->curDimIndex()].color1 = tc;
-
-	if (!screen()->_curPage)
-		screen()->updateScreen();
-}
-
-int TextDisplayer_Eob::clearDim(int dim) {
-	int res = screen()->curDimIndex();
-	screen()->setScreenDim(dim);
-	_textDimData[dim].color1 = screen()->_curDim->unk8;
-	_textDimData[dim].color2 = vm()->game() == GI_LOL ? screen()->_curDim->unkA : vm()->_bkgColor_1;
-	clearCurDim();
-	return res;
-}
-
-void TextDisplayer_Eob::clearCurDim() {
-	int d = screen()->curDimIndex();
-	const ScreenDim *tmp = screen()->getScreenDim(d);
-	if (vm()->gameFlags().use16ColorMode) {
-		screen()->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 2, (tmp->sy + tmp->h) - 2, _textDimData[d].color2);
-	} else
-		screen()->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 1, (tmp->sy + tmp->h) - 1, _textDimData[d].color2);
-
-	_lineCount = 0;
-	_textDimData[d].column = _textDimData[d].line = 0;
-}
-
-void TextDisplayer_Eob::textPageBreak() {
-	if (vm()->game() != GI_LOL)
-		SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2);
-
-	int cp = _screen->setCurPage(0);
-	Screen::FontId cf = screen()->setFont(vm()->gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : Screen::FID_6_FNT);
-
-	if (vm()->game() == GI_LOL)
-		vm()->_timer->pauseSingleTimer(11, true);
-
-	vm()->_fadeText = false;
-	int resetPortraitAfterSpeechAnim = 0;
-	int updatePortraitSpeechAnimDuration = 0;
-
-	if (vm()->_updateCharNum != -1)  {
-		resetPortraitAfterSpeechAnim = vm()->_resetPortraitAfterSpeechAnim;
-		vm()->_resetPortraitAfterSpeechAnim = 0;
-		updatePortraitSpeechAnimDuration = vm()->_updatePortraitSpeechAnimDuration;
-		if (vm()->_updatePortraitSpeechAnimDuration > 36)
-			vm()->_updatePortraitSpeechAnimDuration = 36;
-	}
-
-	uint32 speechPartTime = 0;
-	if (vm()->speechEnabled() && vm()->_activeVoiceFileTotalTime && _numCharsTotal)
-		speechPartTime = vm()->_system->getMillis() + ((_numCharsPrinted * vm()->_activeVoiceFileTotalTime) / _numCharsTotal);
-
-	const ScreenDim *dim = screen()->getScreenDim(screen()->curDimIndex());
-
-	int x = ((dim->sx + dim->w) << 3) - (_vm->_dialogueButtonW + 3);
-	int y = 0;
-	int w = vm()->_dialogueButtonW;
-
-	if (vm()->game() == GI_LOL) {
-		if (vm()->_needSceneRestore && (vm()->_updateFlags & 2)) {
-			if (vm()->_currentControlMode || !(vm()->_updateFlags & 2)) {
-				y = dim->sy + dim->h - 5;
-			} else {
-				x += 6;
-				y = dim->sy + dim->h - 2;
-			}
-		} else {
-			y = dim->sy + dim->h - 10;
-		}
-	} else {
-		y = vm()->_waitButtonPresY[_waitButtonMode];
-		x = vm()->_waitButtonPresX[_waitButtonMode];
-		w = vm()->_waitButtonPresW[_waitButtonMode];
-	}
-
-	if (vm()->gameFlags().use16ColorMode) {
-		vm()->gui_drawBox(x + 8, (y & ~7) - 1, 66, 10, 0xee, 0xcc, -1);
-		screen()->printText(_pageBreakString, (x + 37 - (strlen(_pageBreakString) << 1) + 4) & ~3, (y + 2) & ~7, 0xc1, 0);
-	} else {
-		vm()->gui_drawBox(x, y, w, vm()->_dialogueButtonH, vm()->_color1_1, vm()->_color2_1, vm()->_bkgColor_1);
-		screen()->printText(_pageBreakString, x + (w >> 1) - (vm()->screen()->getTextWidth(_pageBreakString) >> 1), y + 2, vm()->_dialogueButtonLabelCol1, 0);
-	}
-
-	vm()->removeInputTop();
-
-	bool loop = true;
-	bool target = false;
-
-	do {
-		int inputFlag = vm()->checkInput(0, false) & 0xFF;
-		vm()->removeInputTop();
-
-		while (!inputFlag && !_vm->shouldQuit()) {
-			vm()->update();
-
-			if (vm()->speechEnabled()) {
-				if (((vm()->_system->getMillis() > speechPartTime) || (vm()->snd_updateCharacterSpeech() != 2)) && speechPartTime) {
-					loop = false;
-					inputFlag = vm()->_keyMap[Common::KEYCODE_RETURN];
-					break;
-				}
-			}
-
-			inputFlag = vm()->checkInput(0, false) & 0xFF;
-			vm()->removeInputTop();
-		}
-
-		vm()->gui_notifyButtonListChanged();
-
-		if (inputFlag == vm()->_keyMap[Common::KEYCODE_SPACE] || inputFlag == vm()->_keyMap[Common::KEYCODE_RETURN]) {
-			loop = false;
-		} else if (inputFlag == 199 || inputFlag == 201) {
-			if (vm()->posWithinRect(vm()->_mouseX, vm()->_mouseY, x, y, x + w, y + 9)) {
-				if (_vm->game() == GI_LOL)
-					target = true;
-				else
-					loop = false;
-			}
-		} else if (inputFlag == 200 || inputFlag == 202) {
-			if (target)
-				loop = false;
-		}
-	} while (loop && !_vm->shouldQuit());
-
-	if (vm()->gameFlags().use16ColorMode)
-		screen()->fillRect(x + 8, y, x + 57, y + 9, _textDimData[screen()->curDimIndex()].color2);
-	else
-		screen()->fillRect(x, y, x + w - 1, y + 8, _textDimData[screen()->curDimIndex()].color2);
-
-	clearCurDim();
-	_screen->updateScreen();
-
-	if (vm()->game() == GI_LOL)
-		vm()->_timer->pauseSingleTimer(11, false);
-
-	if (vm()->_updateCharNum != -1) {
-		vm()->_resetPortraitAfterSpeechAnim = resetPortraitAfterSpeechAnim;
-		if (updatePortraitSpeechAnimDuration > 36)
-			updatePortraitSpeechAnimDuration -= 36;
-		else
-			updatePortraitSpeechAnimDuration >>= 1;
-
-		vm()->_updatePortraitSpeechAnimDuration = updatePortraitSpeechAnimDuration;
-	}
-
-	screen()->setFont(cf);
-	screen()->setCurPage(cp);
-
-	if (vm()->game() != GI_LOL)
-		SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2);
-
-	vm()->removeInputTop();
-}
-
-void TextDisplayer_Eob::displayWaitButton() {
-	vm()->_dialogueNumButtons = 1;
-	vm()->_dialogueButtonString[0] = _pageBreakString;
-	vm()->_dialogueButtonString[1] = 0;
-	vm()->_dialogueButtonString[2] = 0;
-	vm()->_dialogueHighlightedButton = 0;
-
-	vm()->_dialogueButtonPosX = &vm()->_waitButtonPresX[_waitButtonMode];
-	vm()->_dialogueButtonPosY = &vm()->_waitButtonPresY[_waitButtonMode];
-	vm()->_dialogueButtonW = vm()->_waitButtonPresW[_waitButtonMode];
-	vm()->_dialogueButtonYoffs = 0;
-
-	SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2);
-	vm()->drawDialogueButtons();
-
-	if (!vm()->shouldQuit())
-		vm()->removeInputTop();
-
-	while (!vm()->processDialogue() && !vm()->shouldQuit()) {}
-	
-	_screen->fillRect(vm()->_dialogueButtonPosX[0], vm()->_dialogueButtonPosY[0], vm()->_dialogueButtonPosX[0] + vm()->_dialogueButtonW - 1, vm()->_dialogueButtonPosY[0] + vm()->_dialogueButtonH - 1, vm()->_bkgColor_1);
-	_screen->updateScreen();
-	vm()->_dialogueButtonW = 95;
-	SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2);
-	clearCurDim();
-}
-
-} // End of namespace Kyra
-
-#endif // (ENABLE_EOB || ENABLE_LOL)
diff --git a/engines/kyra/text_eob.h b/engines/kyra/text_eob.h
deleted file mode 100644
index 9409ac4..0000000
--- a/engines/kyra/text_eob.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are to 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.
- *
- */
-
-#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
-
-#ifndef KYRA_TEXT_EOB_H
-#define KYRA_TEXT_EOB_H
-
-#include "common/scummsys.h"
-
-namespace Kyra {
-
-class Screen;
-class LolEobBaseEngine;
-
-class TextDisplayer_Eob {
-public:
-	TextDisplayer_Eob(LolEobBaseEngine *engine, Screen *sScreen);
-	virtual ~TextDisplayer_Eob();
-
-	virtual void setupField(int dim, bool mode);
-
-	void printDialogueText(int stringId, const char *pageBreakString);
-	void printDialogueText(const char *str, bool wait = false);
-	void printMessage(const char *str, int textColor = -1, ...);
-
-	int clearDim(int dim);
-	void clearCurDim();
-
-	void resetDimTextPositions(int dim);
-	void resetPageBreakString();
-	void setPageBreakFlag();
-	void removePageBreakFlag();
-
-	void allowPageBreak(bool mode) { _allowPageBreak = mode; }
-	void setWaitButtonMode(int mode) { _waitButtonMode = mode; }
-	int lineCount() { return _lineCount; }
-
-protected:
-	virtual LolEobBaseEngine *vm() { return _vm; }
-	virtual Screen *screen() { return _screen; }
-
-	void displayText(char *str, ...);
-	char parseCommand();
-	void readNextPara();
-	void printLine(char *str);
-	virtual void textPageBreak();
-	void displayWaitButton();
-
-	char *_dialogueBuffer;
-
-	char *_tempString1;
-	char *_tempString2;
-	char *_currentLine;
-	char _ctrl[3];
-
-	uint16 _lineWidth;
-	uint32 _numCharsTotal;
-	uint32 _numCharsLeft;
-	uint32 _numCharsPrinted;
-
-	bool _printFlag;
-	bool _sjisLineBreakFlag;
-
-	char _pageBreakString[20];
-	char _scriptParaString[11];
-	int _lineCount;
-
-	bool _allowPageBreak;
-	int _waitButtonSpace;
-	int _waitButtonMode;
-
-	static const char _pageBreakDefault[3][5];
-
-	struct TextDimData {
-		uint8 color1;
-		uint8 color2;
-		uint16 column;
-		uint8 line;
-	};
-
-	TextDimData *_textDimData;
-
-private:
-	LolEobBaseEngine *_vm;
-	Screen *_screen;
-
-	char *_table1;
-	char *_table2;
-};
-
-} // End of namespace Kyra
-
-#endif
-
-#endif // ENABLE_EOB || ENABLE_LOL
diff --git a/engines/kyra/text_lol.cpp b/engines/kyra/text_lol.cpp
index da1efa3..d07956b 100644
--- a/engines/kyra/text_lol.cpp
+++ b/engines/kyra/text_lol.cpp
@@ -32,7 +32,7 @@
 
 namespace Kyra {
 
-TextDisplayer_LoL::TextDisplayer_LoL(LoLEngine *engine, Screen_LoL *screenLoL) : TextDisplayer_Eob(engine, engine->screen()),
+TextDisplayer_LoL::TextDisplayer_LoL(LoLEngine *engine, Screen_LoL *screenLoL) : TextDisplayer_rpg(engine, engine->screen()),
 	_vm(engine), _screen(screenLoL), _scriptTextParameter(0) {
 
 	memset(_stringParameters, 0, 15 * sizeof(char *));
@@ -333,7 +333,7 @@ void TextDisplayer_LoL::preprocessString(char *str, EMCState *script, const uint
 	*dst = 0;
 }
 
-LolEobBaseEngine *TextDisplayer_LoL::vm() {
+KyraRpgEngine *TextDisplayer_LoL::vm() {
 	return _vm;
 }
 
@@ -343,7 +343,7 @@ Screen *TextDisplayer_LoL::screen() {
 
 void TextDisplayer_LoL::textPageBreak() {
 	strcpy(_pageBreakString, _vm->getLangString(0x4073));
-	TextDisplayer_Eob::textPageBreak();
+	TextDisplayer_rpg::textPageBreak();
 }
 
 } // End of namespace Kyra
diff --git a/engines/kyra/text_lol.h b/engines/kyra/text_lol.h
index 0dcc4b7..6da217e 100644
--- a/engines/kyra/text_lol.h
+++ b/engines/kyra/text_lol.h
@@ -24,7 +24,7 @@
 #define KYRA_TEXT_LOL_H
 
 #if defined(ENABLE_EOB) || defined(ENABLE_LOL)
-#include "kyra/text_eob.h"
+#include "kyra/text_rpg.h"
 #endif
 #include "common/scummsys.h"
 
@@ -36,7 +36,7 @@ class Screen_LoL;
 class LoLEngine;
 struct EMCState;
 
-class TextDisplayer_LoL : public TextDisplayer_Eob {
+class TextDisplayer_LoL : public TextDisplayer_rpg {
 public:
 	TextDisplayer_LoL(LoLEngine *engine, Screen_LoL *screenLoL);
 	~TextDisplayer_LoL();
@@ -50,7 +50,7 @@ public:
 	int16 _scriptTextParameter;
 
 private:
-	LolEobBaseEngine *vm();
+	KyraRpgEngine *vm();
 	Screen *screen();
 
 	void preprocessString(char *str, EMCState *script, const uint16 *paramList, int16 paramIndex);
diff --git a/engines/kyra/text_rpg.cpp b/engines/kyra/text_rpg.cpp
new file mode 100644
index 0000000..bbc3cdb
--- /dev/null
+++ b/engines/kyra/text_rpg.cpp
@@ -0,0 +1,688 @@
+/* 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.
+ *
+ *
+ */
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#include "kyra/kyra_rpg.h"
+#include "kyra/screen.h"
+#include "kyra/timer.h"
+
+#include "common/system.h"
+
+namespace Kyra {
+
+enum {
+	kEobTextBufferSize = 2048
+};
+
+TextDisplayer_rpg::TextDisplayer_rpg(KyraRpgEngine *engine, Screen *sScreen) : _vm(engine), _screen(sScreen),
+	_lineCount(0), _printFlag(false), _lineWidth(0), _numCharsTotal(0), _allowPageBreak(true),
+	_numCharsLeft(0), _numCharsPrinted(0), _sjisLineBreakFlag(false), _waitButtonMode(1) {
+
+	_dialogueBuffer = new char[kEobTextBufferSize];
+	memset(_dialogueBuffer, 0, kEobTextBufferSize);
+
+	_currentLine = new char[85];
+	memset(_currentLine, 0, 85);
+
+	_textDimData = new TextDimData[_screen->screenDimTableCount()];
+
+	for (int i = 0; i < _screen->screenDimTableCount(); i++){
+		const ScreenDim *d = _screen->getScreenDim(i);
+		_textDimData[i].color1 = d->unk8;
+		_textDimData[i].color2 = d->unkA;
+		_textDimData[i].line = d->unkC;
+		_textDimData[i].column = d->unkE;
+	}
+
+	_table1 = new char[128];
+	memset(_table1, 0, 128);
+	_table2 = new char[16];
+	memset(_table2, 0, 16);
+
+	_waitButtonSpace = 0;
+}
+
+TextDisplayer_rpg::~TextDisplayer_rpg() {
+	delete[] _dialogueBuffer;
+	delete[] _currentLine;
+	delete[] _textDimData;
+	delete[] _table1;
+	delete[] _table2;
+}
+
+void TextDisplayer_rpg::setupField(int dim, bool mode) {
+	setPageBreakFlag();
+
+	_textDimData[dim].color2 = _vm->_bkgColor_1;
+	_screen->setScreenDim(dim);
+
+	if (mode)
+		clearCurDim();
+	else
+		resetDimTextPositions(dim);
+}
+
+void TextDisplayer_rpg::resetDimTextPositions(int dim) {
+	_textDimData[dim].column = 0;
+	_textDimData[dim].line = 0;
+}
+
+void TextDisplayer_rpg::resetPageBreakString() {
+	if (vm()->_moreStrings)
+		strcpy(_pageBreakString, vm()->_moreStrings[0]);
+}
+
+void TextDisplayer_rpg::setPageBreakFlag() {
+	_allowPageBreak = true;
+	_lineCount = 0;
+}
+
+void TextDisplayer_rpg::removePageBreakFlag() {
+	_allowPageBreak = false;
+}
+
+void TextDisplayer_rpg::displayText(char *str, ...) {
+	const bool isPc98 = (_vm->gameFlags().platform == Common::kPlatformPC98);
+
+	_printFlag = false;
+
+	_lineWidth = 0;
+	_numCharsLeft = 0;
+	_numCharsPrinted = 0;
+
+	_tempString1 = str;
+	_tempString2 = 0;
+
+	_currentLine[0] = 0;
+
+	memset(_ctrl, 0, 3);
+
+	char c = parseCommand();
+
+	va_list args;
+	va_start(args, str);
+
+	const ScreenDim *sd = _screen->_curDim;
+	int sdx = _screen->curDimIndex();
+
+	bool pc98PrintFlag = (isPc98 && (sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) ? true : false;
+	uint16 charsPerLine = (sd->w << 3) / (_screen->getFontWidth() + _screen->_charWidth);
+
+	while (c) {
+		char a = tolower(_ctrl[1]);
+
+		if (!_tempString2 && c == '%') {
+			if (a == 'd') {
+				strcpy(_scriptParaString, Common::String::format("%d", va_arg(args, int)).c_str());
+				_tempString2 = _scriptParaString;
+			} else if (a == 's') {
+				_tempString2 = va_arg(args, char *);
+			} else {
+				break;
+			}
+
+			_ctrl[0] = _ctrl[2];
+			_ctrl[2] = _ctrl[1] = 0;
+			c = parseCommand();
+		}
+
+		if (isPc98) {
+			uint8 cu = (uint8) c;
+			if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0)) {
+				_currentLine[_numCharsLeft++] = c;
+				_currentLine[_numCharsLeft++] = parseCommand();
+				_currentLine[_numCharsLeft] = '\0';
+				_lineWidth += 8;
+				if ((_textDimData[sdx].column + _lineWidth) > (sd->w << 3))
+					printLine(_currentLine);
+				c = parseCommand();
+				continue;
+			}
+		}
+
+		uint16 dv = _textDimData[sdx].column / (_screen->getFontWidth() + _screen->_charWidth);
+
+		switch (c - 1) {
+		case 0:
+			printLine(_currentLine);
+			textPageBreak();
+			_numCharsPrinted = 0;
+			break;
+
+		case 1:
+			printLine(_currentLine);
+			_textDimData[sdx].color2 = parseCommand();
+			break;
+
+		case 5:
+			printLine(_currentLine);
+			_textDimData[sdx].color1 = parseCommand();
+			break;
+
+		case 8:
+			printLine(_currentLine);
+			dv = _textDimData[sdx].column / (_screen->getFontWidth() + _screen->_charWidth);
+			dv = ((dv + 8) & 0xfff8) - 1;
+			if (dv >= charsPerLine)
+				dv = 0;
+			_textDimData[sdx].column = (_screen->getFontWidth() + _screen->_charWidth) * dv;
+			break;
+
+		case 11:
+			_sjisLineBreakFlag=_sjisLineBreakFlag;
+			// TODO (UNUSED)
+			break;
+
+		case 12:
+			if (isPc98)
+				_sjisLineBreakFlag = true;
+			printLine(_currentLine);
+			_sjisLineBreakFlag = false;
+			_lineCount++;
+			_textDimData[sdx].column = 0;
+			_textDimData[sdx].line++;
+			break;
+
+		case 18:
+			_sjisLineBreakFlag=_sjisLineBreakFlag;
+			// TODO (UNUSED)
+			break;
+
+		case 23:
+			_sjisLineBreakFlag=_sjisLineBreakFlag;
+			// TODO (UNUSED)
+			break;
+
+		case 24:
+			_sjisLineBreakFlag=_sjisLineBreakFlag;
+			// TODO (UNUSED)
+			break;
+
+		case 26:
+			_sjisLineBreakFlag=_sjisLineBreakFlag;
+			// TODO (UNUSED)
+			break;
+
+		case 28:
+			_sjisLineBreakFlag=_sjisLineBreakFlag;
+			// TODO (UNUSED)
+			break;
+
+		default:
+			if (_vm->game() == GI_LOL || c > 30) {
+				_lineWidth += (pc98PrintFlag ? 4 : _screen->getCharWidth((uint8)c));
+				_currentLine[_numCharsLeft++] = c;
+				_currentLine[_numCharsLeft] = 0;
+
+				if ((_textDimData[sdx].column + _lineWidth) > (sd->w << 3))
+					printLine(_currentLine);
+			}
+		}
+
+		c = parseCommand();
+	}
+
+	va_end(args);
+
+	if (_numCharsLeft)
+		printLine(_currentLine);
+}
+
+char TextDisplayer_rpg::parseCommand() {
+	if (!_ctrl[1])
+		readNextPara();
+
+	char res = _ctrl[1];
+	_ctrl[1] = _ctrl[2];
+	_ctrl[2] = 0;
+
+	if (!_ctrl[1])
+		readNextPara();
+
+	return res;
+}
+
+void TextDisplayer_rpg::readNextPara() {
+	char c = 0;
+	char d = 0;
+
+	if (_tempString2) {
+		if (*_tempString2) {
+			d = *_tempString2++;
+		} else {
+			_tempString2 = 0;
+			d = _ctrl[0];
+		}
+	}
+
+	if (!d && _tempString1) {
+		if (*_tempString1)
+			d = *_tempString1++;
+		else
+			_tempString1 = 0;
+	}
+
+	if ((_vm->game() != GI_LOL) && (d & 0x80)) {
+		d &= 0x7f;
+		c = d & 7;
+		d = (d & 0x78) >> 3;
+		uint8 l = d;
+		c = _table1[(l << 3) + c];
+		d = _table2[l];
+	}
+
+	_ctrl[1] = d;
+	_ctrl[2] = c;
+}
+
+void TextDisplayer_rpg::printLine(char *str) {
+	const bool isPc98 = (_vm->gameFlags().platform == Common::kPlatformPC98);
+	const ScreenDim *sd = _screen->_curDim;
+	int sdx = _screen->curDimIndex();
+	bool pc98PrintFlag = (isPc98 && (sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) ? true : false;
+
+	int fh = (_screen->_currentFont == Screen::FID_SJIS_FNT) ? 9 : (_screen->getFontHeight() + _screen->_charOffset);
+	int lines = (sd->h - _screen->_charOffset) / fh;
+
+	while (_textDimData[sdx].line >= lines) {
+		if ((lines - _waitButtonSpace) <= _lineCount && _allowPageBreak) {
+			_lineCount = 0;
+			textPageBreak();
+			_numCharsPrinted = 0;
+		}
+
+		int h1 = ((sd->h / fh) - 1) * fh;
+		int h2 = sd->h - fh;
+
+		if (h2)
+			_screen->copyRegion(sd->sx << 3, sd->sy + fh, sd->sx << 3, sd->sy, sd->w << 3, h2, _screen->_curPage, _screen->_curPage, Screen::CR_NO_P_CHECK);
+
+		_screen->fillRect(sd->sx << 3, sd->sy + h1, ((sd->sx + sd->w) << 3) - 1, sd->sy + sd->h - 1, _textDimData[sdx].color2);
+		if (_textDimData[sdx].line)
+			_textDimData[sdx].line--;
+	}
+
+	int x1 = (sd->sx << 3) + _textDimData[sdx].column;
+	int y = sd->sy + (pc98PrintFlag ? (_textDimData[sdx].line << 3) : (fh * _textDimData[sdx].line));
+	int w = sd->w << 3;
+	int lw = _lineWidth;
+	int s = _numCharsLeft;
+	char c = 0;
+
+	if (pc98PrintFlag) {
+		bool ct = true;
+
+		if ((lw + _textDimData[sdx].column) > w) {
+			if ((lines - 1 - (_waitButtonSpace << 1)) <= _lineCount)
+				// cut off line to leave space for "MORE" button
+				w -= vm()->_waitButtonReverveW;
+		} else {
+			if (!_sjisLineBreakFlag || (_lineCount + 1 < lines - 1))
+				ct = false;
+			else
+				// cut off line to leave space for "MORE" button
+				w -= vm()->_waitButtonReverveW;
+		}
+
+		if (ct) {
+			w -= _textDimData[sdx].column;
+
+			int n2 = 0;
+			int n1 = (w / 4) - 1;
+
+			while (n2 < n1 && n2 < s) {
+				c = str[n2];
+				uint8 cu = (uint8) c;
+				if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0))
+					n2++;
+				n2++;
+			}
+			s = n2;
+		}
+	} else {
+		if ((lw + _textDimData[sdx].column) > w) {
+			if ((lines - 1) <= _lineCount && _allowPageBreak)
+				// cut off line to leave space for "MORE" button
+				w -= vm()->_waitButtonReverveW;
+
+			w -= _textDimData[sdx].column;
+
+			int n2 = 0;
+			int n1 = s - 1;
+
+			while (n1 > 0) {
+				//cut off line after last space
+				c = str[n1];
+
+				lw -= _screen->getCharWidth((uint8)c);
+
+				if (!n2 && lw <= w)
+					n2 = n1;
+
+				if (n2 && c == ' ') {
+					s = n1;
+					_printFlag = false;
+					break;
+				}
+				n1--;
+			}
+
+			if (!n1) {
+				if (_textDimData[sdx].column && !_printFlag) {
+					s = lw = 0;
+					_printFlag = true;
+				} else {
+					s = n2;
+				}
+			}
+		}
+	}
+
+	c = str[s];
+	str[s] = 0;
+
+	uint8 col = _textDimData[sdx].color1;
+	if (isPc98 && (sdx == 2 || sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) {
+		switch (_textDimData[sdx].color1) {
+		case 0x88:
+			col = 0x41;
+			break;
+		case 0x55:
+			col = 0x81;
+			break;
+		case 0xaa:
+			col = 0x21;
+			break;
+		case 0x99:
+			col = 0xa1;
+			break;
+		case 0x33:
+			col = 0xe1;
+			break;
+		case 0x18:
+			col = 0x61;
+			break;
+		default:
+			col = 1;
+			break;
+		}
+		_screen->printText(str, x1 & ~3, (y + 8) & ~7, col, 0);
+	} else {
+		_screen->printText(str, x1, y, col, _textDimData[sdx].color2);
+	}
+
+	_textDimData[sdx].column += lw;
+	_numCharsPrinted += strlen(str);
+
+	str[s] = c;
+
+	if (c == ' ')
+		s++;
+
+	if (str[s] == ' ')
+		s++;
+
+	uint32 len = strlen(&str[s]);
+	for (uint32 i = 0; i < len; i++)
+		str[i] = str[s + i];
+	str[len] = 0;
+
+	_numCharsLeft = strlen(str);
+	_lineWidth = pc98PrintFlag ? (_numCharsLeft << 2) : _screen->getTextWidth(str);
+
+	if (!_numCharsLeft && _textDimData[sdx].column < (sd->w << 3))
+		return;
+
+	_textDimData[sdx].column = 0;
+	_textDimData[sdx].line++;
+	_lineCount++;
+
+	printLine(str);
+}
+
+void TextDisplayer_rpg::printDialogueText(int stringId, const char *pageBreakString) {
+	const char * str = (const char *)(screen()->getCPagePtr(5) + READ_LE_UINT16(&screen()->getCPagePtr(5)[(stringId - 1) << 1]));
+	assert (strlen(str) < kEobTextBufferSize);
+	Common::strlcpy(_dialogueBuffer, str, kEobTextBufferSize);
+
+	displayText(_dialogueBuffer);
+
+	if (pageBreakString) {
+		if (pageBreakString[0]) {
+			strcpy(_pageBreakString, pageBreakString);
+			displayWaitButton();
+			resetPageBreakString();
+		}
+	}
+}
+
+void TextDisplayer_rpg::printDialogueText(const char *str, bool wait) {
+	assert (strlen(str) < kEobTextBufferSize);
+	Common::strlcpy(_dialogueBuffer, str, kEobTextBufferSize);
+
+	strcpy(_dialogueBuffer, str);
+	displayText(_dialogueBuffer);
+	if (wait)
+		displayWaitButton();
+}
+
+void TextDisplayer_rpg::printMessage(const char *str, int textColor, ...) {
+	int tc = _textDimData[screen()->curDimIndex()].color1;
+
+	if (textColor != -1)
+		_textDimData[screen()->curDimIndex()].color1 = textColor;
+
+	va_list args;
+	va_start(args, textColor);
+	vsnprintf(_dialogueBuffer, kEobTextBufferSize - 1, str, args);
+	va_end(args);
+
+	displayText(_dialogueBuffer);
+
+	if (vm()->game() != GI_EOB1)
+		_textDimData[screen()->curDimIndex()].color1 = tc;
+
+	if (!screen()->_curPage)
+		screen()->updateScreen();
+}
+
+int TextDisplayer_rpg::clearDim(int dim) {
+	int res = screen()->curDimIndex();
+	screen()->setScreenDim(dim);
+	_textDimData[dim].color1 = screen()->_curDim->unk8;
+	_textDimData[dim].color2 = vm()->game() == GI_LOL ? screen()->_curDim->unkA : vm()->_bkgColor_1;
+	clearCurDim();
+	return res;
+}
+
+void TextDisplayer_rpg::clearCurDim() {
+	int d = screen()->curDimIndex();
+	const ScreenDim *tmp = screen()->getScreenDim(d);
+	if (vm()->gameFlags().use16ColorMode) {
+		screen()->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 2, (tmp->sy + tmp->h) - 2, _textDimData[d].color2);
+	} else
+		screen()->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 1, (tmp->sy + tmp->h) - 1, _textDimData[d].color2);
+
+	_lineCount = 0;
+	_textDimData[d].column = _textDimData[d].line = 0;
+}
+
+void TextDisplayer_rpg::textPageBreak() {
+	if (vm()->game() != GI_LOL)
+		SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2);
+
+	int cp = _screen->setCurPage(0);
+	Screen::FontId cf = screen()->setFont(vm()->gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : Screen::FID_6_FNT);
+
+	if (vm()->game() == GI_LOL)
+		vm()->_timer->pauseSingleTimer(11, true);
+
+	vm()->_fadeText = false;
+	int resetPortraitAfterSpeechAnim = 0;
+	int updatePortraitSpeechAnimDuration = 0;
+
+	if (vm()->_updateCharNum != -1)  {
+		resetPortraitAfterSpeechAnim = vm()->_resetPortraitAfterSpeechAnim;
+		vm()->_resetPortraitAfterSpeechAnim = 0;
+		updatePortraitSpeechAnimDuration = vm()->_updatePortraitSpeechAnimDuration;
+		if (vm()->_updatePortraitSpeechAnimDuration > 36)
+			vm()->_updatePortraitSpeechAnimDuration = 36;
+	}
+
+	uint32 speechPartTime = 0;
+	if (vm()->speechEnabled() && vm()->_activeVoiceFileTotalTime && _numCharsTotal)
+		speechPartTime = vm()->_system->getMillis() + ((_numCharsPrinted * vm()->_activeVoiceFileTotalTime) / _numCharsTotal);
+
+	const ScreenDim *dim = screen()->getScreenDim(screen()->curDimIndex());
+
+	int x = ((dim->sx + dim->w) << 3) - (_vm->_dialogueButtonW + 3);
+	int y = 0;
+	int w = vm()->_dialogueButtonW;
+
+	if (vm()->game() == GI_LOL) {
+		if (vm()->_needSceneRestore && (vm()->_updateFlags & 2)) {
+			if (vm()->_currentControlMode || !(vm()->_updateFlags & 2)) {
+				y = dim->sy + dim->h - 5;
+			} else {
+				x += 6;
+				y = dim->sy + dim->h - 2;
+			}
+		} else {
+			y = dim->sy + dim->h - 10;
+		}
+	} else {
+		y = vm()->_waitButtonPresY[_waitButtonMode];
+		x = vm()->_waitButtonPresX[_waitButtonMode];
+		w = vm()->_waitButtonPresW[_waitButtonMode];
+	}
+
+	if (vm()->gameFlags().use16ColorMode) {
+		vm()->gui_drawBox(x + 8, (y & ~7) - 1, 66, 10, 0xee, 0xcc, -1);
+		screen()->printText(_pageBreakString, (x + 37 - (strlen(_pageBreakString) << 1) + 4) & ~3, (y + 2) & ~7, 0xc1, 0);
+	} else {
+		vm()->gui_drawBox(x, y, w, vm()->_dialogueButtonH, vm()->_color1_1, vm()->_color2_1, vm()->_bkgColor_1);
+		screen()->printText(_pageBreakString, x + (w >> 1) - (vm()->screen()->getTextWidth(_pageBreakString) >> 1), y + 2, vm()->_dialogueButtonLabelCol1, 0);
+	}
+
+	vm()->removeInputTop();
+
+	bool loop = true;
+	bool target = false;
+
+	do {
+		int inputFlag = vm()->checkInput(0, false) & 0xFF;
+		vm()->removeInputTop();
+
+		while (!inputFlag && !_vm->shouldQuit()) {
+			vm()->update();
+
+			if (vm()->speechEnabled()) {
+				if (((vm()->_system->getMillis() > speechPartTime) || (vm()->snd_updateCharacterSpeech() != 2)) && speechPartTime) {
+					loop = false;
+					inputFlag = vm()->_keyMap[Common::KEYCODE_RETURN];
+					break;
+				}
+			}
+
+			inputFlag = vm()->checkInput(0, false) & 0xFF;
+			vm()->removeInputTop();
+		}
+
+		vm()->gui_notifyButtonListChanged();
+
+		if (inputFlag == vm()->_keyMap[Common::KEYCODE_SPACE] || inputFlag == vm()->_keyMap[Common::KEYCODE_RETURN]) {
+			loop = false;
+		} else if (inputFlag == 199 || inputFlag == 201) {
+			if (vm()->posWithinRect(vm()->_mouseX, vm()->_mouseY, x, y, x + w, y + 9)) {
+				if (_vm->game() == GI_LOL)
+					target = true;
+				else
+					loop = false;
+			}
+		} else if (inputFlag == 200 || inputFlag == 202) {
+			if (target)
+				loop = false;
+		}
+	} while (loop && !_vm->shouldQuit());
+
+	if (vm()->gameFlags().use16ColorMode)
+		screen()->fillRect(x + 8, y, x + 57, y + 9, _textDimData[screen()->curDimIndex()].color2);
+	else
+		screen()->fillRect(x, y, x + w - 1, y + 8, _textDimData[screen()->curDimIndex()].color2);
+
+	clearCurDim();
+	_screen->updateScreen();
+
+	if (vm()->game() == GI_LOL)
+		vm()->_timer->pauseSingleTimer(11, false);
+
+	if (vm()->_updateCharNum != -1) {
+		vm()->_resetPortraitAfterSpeechAnim = resetPortraitAfterSpeechAnim;
+		if (updatePortraitSpeechAnimDuration > 36)
+			updatePortraitSpeechAnimDuration -= 36;
+		else
+			updatePortraitSpeechAnimDuration >>= 1;
+
+		vm()->_updatePortraitSpeechAnimDuration = updatePortraitSpeechAnimDuration;
+	}
+
+	screen()->setFont(cf);
+	screen()->setCurPage(cp);
+
+	if (vm()->game() != GI_LOL)
+		SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2);
+
+	vm()->removeInputTop();
+}
+
+void TextDisplayer_rpg::displayWaitButton() {
+	vm()->_dialogueNumButtons = 1;
+	vm()->_dialogueButtonString[0] = _pageBreakString;
+	vm()->_dialogueButtonString[1] = 0;
+	vm()->_dialogueButtonString[2] = 0;
+	vm()->_dialogueHighlightedButton = 0;
+
+	vm()->_dialogueButtonPosX = &vm()->_waitButtonPresX[_waitButtonMode];
+	vm()->_dialogueButtonPosY = &vm()->_waitButtonPresY[_waitButtonMode];
+	vm()->_dialogueButtonW = vm()->_waitButtonPresW[_waitButtonMode];
+	vm()->_dialogueButtonYoffs = 0;
+
+	SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2);
+	vm()->drawDialogueButtons();
+
+	if (!vm()->shouldQuit())
+		vm()->removeInputTop();
+
+	while (!vm()->processDialogue() && !vm()->shouldQuit()) {}
+
+	_screen->fillRect(vm()->_dialogueButtonPosX[0], vm()->_dialogueButtonPosY[0], vm()->_dialogueButtonPosX[0] + vm()->_dialogueButtonW - 1, vm()->_dialogueButtonPosY[0] + vm()->_dialogueButtonH - 1, vm()->_bkgColor_1);
+	_screen->updateScreen();
+	vm()->_dialogueButtonW = 95;
+	SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2);
+	clearCurDim();
+}
+
+} // End of namespace Kyra
+
+#endif // (ENABLE_EOB || ENABLE_LOL)
diff --git a/engines/kyra/text_rpg.h b/engines/kyra/text_rpg.h
new file mode 100644
index 0000000..fcafcc0
--- /dev/null
+++ b/engines/kyra/text_rpg.h
@@ -0,0 +1,115 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are to 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.
+ *
+ */
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#ifndef KYRA_TEXT_EOB_H
+#define KYRA_TEXT_EOB_H
+
+#include "common/scummsys.h"
+
+namespace Kyra {
+
+class Screen;
+class KyraRpgEngine;
+
+class TextDisplayer_rpg {
+public:
+	TextDisplayer_rpg(KyraRpgEngine *engine, Screen *sScreen);
+	virtual ~TextDisplayer_rpg();
+
+	virtual void setupField(int dim, bool mode);
+
+	void printDialogueText(int stringId, const char *pageBreakString);
+	void printDialogueText(const char *str, bool wait = false);
+	void printMessage(const char *str, int textColor = -1, ...);
+
+	int clearDim(int dim);
+	void clearCurDim();
+
+	void resetDimTextPositions(int dim);
+	void resetPageBreakString();
+	void setPageBreakFlag();
+	void removePageBreakFlag();
+
+	void allowPageBreak(bool mode) { _allowPageBreak = mode; }
+	void setWaitButtonMode(int mode) { _waitButtonMode = mode; }
+	int lineCount() { return _lineCount; }
+
+protected:
+	virtual KyraRpgEngine *vm() { return _vm; }
+	virtual Screen *screen() { return _screen; }
+
+	void displayText(char *str, ...);
+	char parseCommand();
+	void readNextPara();
+	void printLine(char *str);
+	virtual void textPageBreak();
+	void displayWaitButton();
+
+	char *_dialogueBuffer;
+
+	char *_tempString1;
+	char *_tempString2;
+	char *_currentLine;
+	char _ctrl[3];
+
+	uint16 _lineWidth;
+	uint32 _numCharsTotal;
+	uint32 _numCharsLeft;
+	uint32 _numCharsPrinted;
+
+	bool _printFlag;
+	bool _sjisLineBreakFlag;
+
+	char _pageBreakString[20];
+	char _scriptParaString[11];
+	int _lineCount;
+
+	bool _allowPageBreak;
+	int _waitButtonSpace;
+	int _waitButtonMode;
+
+	static const char _pageBreakDefault[3][5];
+
+	struct TextDimData {
+		uint8 color1;
+		uint8 color2;
+		uint16 column;
+		uint8 line;
+	};
+
+	TextDimData *_textDimData;
+
+private:
+	KyraRpgEngine *_vm;
+	Screen *_screen;
+
+	char *_table1;
+	char *_table2;
+};
+
+} // End of namespace Kyra
+
+#endif
+
+#endif // ENABLE_EOB || ENABLE_LOL
diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp
index 3b56b79..b80563b 100644
--- a/engines/kyra/timer_eob.cpp
+++ b/engines/kyra/timer_eob.cpp
@@ -20,74 +20,11 @@
  *
  */
 
-#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
-
 #include "kyra/eobcommon.h"
 #include "kyra/timer.h"
 
 #include "common/system.h"
 
-namespace Kyra {
-
-void LolEobBaseEngine::enableSysTimer(int sysTimer) {
-	if (sysTimer != 2)
-		return;
-
-	for (int i = 0; i < getNumClock2Timers(); i++)
-		_timer->pauseSingleTimer(getClock2Timer(i), false);
-}
-
-void LolEobBaseEngine::disableSysTimer(int sysTimer) {
-	if (sysTimer != 2)
-		return;
-
-	for (int i = 0; i < getNumClock2Timers(); i++)
-		_timer->pauseSingleTimer(getClock2Timer(i), true);
-}
-
-void LolEobBaseEngine::enableTimer(int id) {
-	_timer->enable(id);
-	_timer->setCountdown(id, _timer->getDelay(id));
-}
-
-void LolEobBaseEngine::timerProcessDoors(int timerNum) {
-	for (int i = 0; i < 3; i++) {
-		uint16 b = _openDoorState[i].block;
-		if (!b)
-			continue;
-
-		int v = _openDoorState[i].state;
-		int c = _openDoorState[i].wall;
-
-		_levelBlockProperties[b].walls[c] += v;
-		_levelBlockProperties[b].walls[c ^ 2] += v;
-
-		int snd = 3;
-		int flg = _wllWallFlags[_levelBlockProperties[b].walls[c]];
-		if (flg & 0x20)
-			snd = 5;
-		else if (v == -1)
-			snd = 4;
-
-		if (_flags.gameID == GI_LOL) {
-			if (!(_updateFlags & 1)) {
-				snd_processEnvironmentalSoundEffect(snd + 28, b);
-				if (!checkSceneUpdateNeed(b))
-					updateEnvironmentalSfx(0);
-			}
-		} else {
-			checkSceneUpdateNeed(b);
-			updateEnvironmentalSfx(snd);
-		}
-
-		if (flg & 0x30)
-			_openDoorState[i].block = 0;
-	}
-}
-
-} // namespace Kyra
-
-#endif
 #ifdef ENABLE_EOB
 
 namespace Kyra {
@@ -370,7 +307,7 @@ void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
 
 		_screen->setScreenDim(od);
 		_screen->setFont(of);
-	}	
+	}
 
 	uint32 nextTimer = 0xffffffff;
 	for (int i = 0; i < 10; i++) {
diff --git a/engines/kyra/timer_rpg.cpp b/engines/kyra/timer_rpg.cpp
new file mode 100644
index 0000000..02c2669
--- /dev/null
+++ b/engines/kyra/timer_rpg.cpp
@@ -0,0 +1,90 @@
+/* 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.
+ *
+ */
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#include "kyra/kyra_rpg.h"
+#include "kyra/timer.h"
+
+#include "common/system.h"
+
+namespace Kyra {
+
+void KyraRpgEngine::enableSysTimer(int sysTimer) {
+	if (sysTimer != 2)
+		return;
+
+	for (int i = 0; i < getNumClock2Timers(); i++)
+		_timer->pauseSingleTimer(getClock2Timer(i), false);
+}
+
+void KyraRpgEngine::disableSysTimer(int sysTimer) {
+	if (sysTimer != 2)
+		return;
+
+	for (int i = 0; i < getNumClock2Timers(); i++)
+		_timer->pauseSingleTimer(getClock2Timer(i), true);
+}
+
+void KyraRpgEngine::enableTimer(int id) {
+	_timer->enable(id);
+	_timer->setCountdown(id, _timer->getDelay(id));
+}
+
+void KyraRpgEngine::timerProcessDoors(int timerNum) {
+	for (int i = 0; i < 3; i++) {
+		uint16 b = _openDoorState[i].block;
+		if (!b)
+			continue;
+
+		int v = _openDoorState[i].state;
+		int c = _openDoorState[i].wall;
+
+		_levelBlockProperties[b].walls[c] += v;
+		_levelBlockProperties[b].walls[c ^ 2] += v;
+
+		int snd = 3;
+		int flg = _wllWallFlags[_levelBlockProperties[b].walls[c]];
+		if (flg & 0x20)
+			snd = 5;
+		else if (v == -1)
+			snd = 4;
+
+		if (_flags.gameID == GI_LOL) {
+			if (!(_updateFlags & 1)) {
+				snd_processEnvironmentalSoundEffect(snd + 28, b);
+				if (!checkSceneUpdateNeed(b))
+					updateEnvironmentalSfx(0);
+			}
+		} else {
+			checkSceneUpdateNeed(b);
+			updateEnvironmentalSfx(snd);
+		}
+
+		if (flg & 0x30)
+			_openDoorState[i].block = 0;
+	}
+}
+
+} // namespace Kyra
+
+#endif


Commit: 6c8fb30cbd80660bc3882ca0c0895dec8cbc4108
    https://github.com/scummvm/scummvm/commit/6c8fb30cbd80660bc3882ca0c0895dec8cbc4108
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:16-08:00

Commit Message:
KYRA: (EOB) - fix static resource loading for EOB when LOL is disabled

Changed paths:
    engines/kyra/resource.h
    engines/kyra/staticres.cpp



diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 8edfd0a..413bc45 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -773,6 +773,7 @@ private:
 	const FileType *getFiletype(int type);
 	const void *getData(int id, int requesttype, int &size);
 
+	bool loadDummy(Common::SeekableReadStream &stream, void *&ptr, int &size);
 	bool loadStringTable(Common::SeekableReadStream &stream, void *&ptr, int &size);
 	bool loadRawData(Common::SeekableReadStream &stream, void *&ptr, int &size);
 	bool loadShapeTable(Common::SeekableReadStream &stream, void *&ptr, int &size);
@@ -798,6 +799,7 @@ private:
 	bool loadEobNpcData(Common::SeekableReadStream &stream, void *&ptr, int &size);
 #endif // ENABLE_EOB
 
+	void freeDummy(void *&ptr, int &size);
 	void freeRawData(void *&ptr, int &size);
 	void freeStringTable(void *&ptr, int &size);
 	void freeShapeTable(void *&ptr, int &size);
diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp
index c169a39..092a4cc 100644
--- a/engines/kyra/staticres.cpp
+++ b/engines/kyra/staticres.cpp
@@ -257,6 +257,14 @@ bool StaticResource::init() {
 		{ kLolRawDataBe16, proc(loadRawDataBe16), proc(freeRawDataBe16) },
 		{ kLolRawDataBe32, proc(loadRawDataBe32), proc(freeRawDataBe32) },
 		{ kLolButtonData, proc(loadButtonDefs), proc(freeButtonDefs) },
+#else
+		{ kLolCharData, proc(loadDummy), proc(freeDummy) },
+		{ kLolSpellData, proc(loadDummy), proc(freeDummy) },
+		{ kLolCompassData, proc(loadDummy), proc(freeDummy) },
+		{ kLolFlightShpData, proc(loadDummy), proc(freeDummy) },
+		{ kLolRawDataBe16, proc(loadDummy), proc(freeDummy) },
+		{ kLolRawDataBe32, proc(loadDummy), proc(freeDummy) },
+		{ kLolButtonData, proc(loadDummy), proc(freeDummy) },
 #endif // ENABLE_LOL
 
 #ifdef ENABLE_EOB
@@ -411,6 +419,10 @@ const void *StaticResource::getData(int id, int requesttype, int &size) {
 	return 0;
 }
 
+bool StaticResource::loadDummy(Common::SeekableReadStream &stream, void *&ptr, int &size) {
+	return true;
+}
+
 bool StaticResource::loadStringTable(Common::SeekableReadStream &stream, void *&ptr, int &size) {
 	uint32 count = stream.readUint32BE();
 	size = count;
@@ -615,6 +627,9 @@ bool StaticResource::loadShapeAnimData_v2(Common::SeekableReadStream &stream, vo
 	return true;
 }
 
+void StaticResource::freeDummy(void *&ptr, int &size) {
+}
+
 void StaticResource::freeRawData(void *&ptr, int &size) {
 	uint8 *data = (uint8 *)ptr;
 	delete[] data;


Commit: 4c6302943b1122703241686a66c1f90b2ee4a209
    https://github.com/scummvm/scummvm/commit/4c6302943b1122703241686a66c1f90b2ee4a209
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:16-08:00

Commit Message:
KYRA: implement Screen::decodeFrame1()

(required for decoding some EGA bitmaps in EOB1)

Changed paths:
    engines/kyra/screen.cpp
    engines/kyra/screen.h



diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index c0d05dc..e4613e2 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -2052,6 +2052,87 @@ void Screen::drawShapePlotType52(uint8 *dst, uint8 cmd) {
 	*dst = cmd;
 }
 
+void Screen::decodeFrame1(const uint8 *src, uint8 *dst, uint32 size) {
+	const uint8 *dstEnd = dst + size;
+
+	struct Pattern {
+		const uint8 *pos;
+		uint16 len;
+	};
+
+	Pattern *patterns = new Pattern[3840];
+	uint16 numPatterns = 0;
+	uint8 nib = 0;	
+
+	uint16 code = decodeEGAGetCode(src, nib);
+	uint8 last = code & 0xff;
+
+	uint8 *dstPrev = dst;
+	uint16 count = 1;
+	uint16 countPrev = 1;
+
+	*dst++ = last;
+
+	while (dst < dstEnd) {
+		code = decodeEGAGetCode(src, nib);
+		last = code & 0xff;
+		uint8 cmd = code >> 8;
+
+		if (cmd--) {
+			code = (cmd << 8) | last;
+			uint8 *tmpDst = dst;
+			last = *dst;
+
+			if (code < numPatterns) {
+				const uint8 *tmpSrc = patterns[code].pos;
+				countPrev = patterns[code].len;
+				for (int i = 0; i < countPrev; i++)
+					*dst++ = *tmpSrc++;
+
+			} else {
+				const uint8 *tmpSrc = dstPrev;
+				count = countPrev;
+				for (int i = 0; i < countPrev; i++)
+					*dst++ = *tmpSrc++;
+				*dst++ = last;
+				countPrev++;
+			}
+
+			if (numPatterns < 3840) {
+				patterns[numPatterns].pos = dstPrev;
+				patterns[numPatterns++].len = ++count;
+			}
+
+			dstPrev = tmpDst;
+			count = countPrev;
+
+		} else {
+			*dst++ = last;
+
+			if (numPatterns < 3840) {
+				patterns[numPatterns].pos = dstPrev;
+				patterns[numPatterns++].len = ++count;
+			}
+
+			dstPrev = dst - 1;
+			count = 1;
+			countPrev = 1;
+		}
+	}
+	delete[] patterns;
+}
+
+uint16 Screen::decodeEGAGetCode(const uint8 *&pos, uint8 &nib) {
+	uint16 res = READ_BE_UINT16(pos++);
+	if ((++nib) & 1) {
+		res >>= 4;		
+	} else {
+		pos++;
+		res &= 0xfff;
+	}
+	return res;
+}
+
 void Screen::decodeFrame3(const uint8 *src, uint8 *dst, uint32 size) {
 	const uint8 *dstEnd = dst + size;
 	while (dst < dstEnd) {
@@ -2933,6 +3014,9 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, Palette
 	case 0:
 		memcpy(dstData, srcPtr, imgSize);
 		break;
+	case 1:
+		Screen::decodeFrame1(srcPtr, dstData, imgSize);
+		break;
 	case 3:
 		Screen::decodeFrame3(srcPtr, dstData, imgSize);
 		break;
diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h
index d4f0dc9..192e267 100644
--- a/engines/kyra/screen.h
+++ b/engines/kyra/screen.h
@@ -515,6 +515,9 @@ public:
 	FontId _currentFont;
 
 	// decoding functions
+	static void decodeFrame1(const uint8 *src, uint8 *dst, uint32 size);
+	static uint16 decodeEGAGetCode(const uint8 *&pos, uint8 &nib);
+
 	static void decodeFrame3(const uint8 *src, uint8 *dst, uint32 size);
 	static uint decodeFrame4(const uint8 *src, uint8 *dst, uint32 dstSize);
 	static void decodeFrameDelta(uint8 *dst, const uint8 *src, bool noXor = false);


Commit: 36d85a315fe2d6927f6609ec312f8fea8b9a3c3c
    https://github.com/scummvm/scummvm/commit/36d85a315fe2d6927f6609ec312f8fea8b9a3c3c
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:16-08:00

Commit Message:
KYRA: (EOB) - rename some files for a better match with the contained code

Changed paths:
  A engines/kyra/darkmoon.cpp
  A engines/kyra/darkmoon.h
  A engines/kyra/eob.cpp
  A engines/kyra/eob.h
  A engines/kyra/sequences_darkmoon.cpp
  A engines/kyra/sequences_eob.cpp
  R engines/kyra/eob2.cpp
  R engines/kyra/eob2.h
  R engines/kyra/eob1.cpp
  R engines/kyra/eob1.h
  R engines/kyra/sequences_eob2.cpp
  R engines/kyra/sequences_eob1.cpp
    engines/kyra/detection.cpp
    engines/kyra/module.mk
    engines/kyra/resource.h
    engines/kyra/staticres_eob.cpp



diff --git a/engines/kyra/darkmoon.cpp b/engines/kyra/darkmoon.cpp
new file mode 100644
index 0000000..e44040b
--- /dev/null
+++ b/engines/kyra/darkmoon.cpp
@@ -0,0 +1,480 @@
+/* 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.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/darkmoon.h"
+#include "kyra/resource.h"
+#include "kyra/sound.h"
+
+namespace Kyra {
+
+DarkMoonEngine::DarkMoonEngine(OSystem *system, const GameFlags &flags) : EobCoreEngine(system, flags) {
+	_seqIntro = _seqFinale = 0;
+	_shapesIntro = _shapesFinale = 0;
+	_dscDoorType5Offs = 0;
+	_numSpells = 70;
+	_menuChoiceInit = 4;
+
+	_introStrings = _cpsFilesIntro = _cpsFilesFinale = _finaleStrings = _kheldranStrings = _npcStrings[0] = _npcStrings[1] = _hornStrings = 0;
+	_seqIntro = _seqFinale = 0;
+	_shapesIntro = _shapesFinale = 0;
+	_creditsData = _npcShpData = _dscDoorType5Offs = _hornSounds = 0;
+	_dreamSteps = 0;
+}
+
+DarkMoonEngine::~DarkMoonEngine() {
+	delete[] _seqIntro;
+	delete[] _seqFinale;
+	delete[] _shapesIntro;
+	delete[] _shapesFinale;
+}
+
+Common::Error DarkMoonEngine::init() {
+	Common::Error err = EobCoreEngine::init();
+	if (err.getCode() != Common::kNoError)
+		return err;
+
+	initStaticResource();
+
+	_monsterProps = new EobMonsterProperty[10];
+
+	static const uint16 wX[] = { 221, 76 };
+	static const uint8 wY[] = { 189, 162 };
+	static const uint16 wW[] = { 95, 95 };
+
+	_dialogueButtonLabelCol1 = 9;
+	_dialogueButtonLabelCol2 = 15;
+	_dialogueButtonW = 95;
+	_dialogueButtonH = 9;
+	_waitButtonPresX = wX;
+	_waitButtonPresY = wY;
+	_waitButtonPresW = wW;
+	_waitButtonReverveW = 7;
+
+	_bkgColor_1 = 183;
+	_color1_1 = 186;
+	_color2_1 = 181;
+	_color4 = 133;
+	_color5 = 184;
+	_color6 = 183;
+	_color7 = 181;
+	_color8 = 186;
+	_color12 = 180;
+	_color13 = 177;
+	_color14 = 182;
+
+	return Common::kNoError;
+}
+
+void DarkMoonEngine::startupNew() {
+	_currentLevel = 4;
+	_currentSub = 0;
+	loadLevel(4, 0);
+	_currentBlock = 171;
+	_currentDirection = 2;
+	setHandItem(0);
+	EobCoreEngine::startupNew();
+}
+
+void DarkMoonEngine::drawNpcScene(int npcIndex) {
+	const uint8 *shpDef = &_npcShpData[npcIndex << 3];
+	for (int i = npcIndex; i != 255; i = shpDef[7]) {
+		shpDef = &_npcShpData[i << 3];
+		_screen->_curPage = 2;
+		const uint8 *shp = _screen->encodeShape(READ_LE_UINT16(shpDef), shpDef[2], shpDef[3], shpDef[4]);
+		_screen->_curPage = 0;
+		_screen->drawShape(0, shp, 88 + shpDef[5] - (shp[2] << 2), 104 + shpDef[6] - shp[1], 5);
+		delete[] shp;
+	}
+}
+
+void DarkMoonEngine::runNpcDialogue(int npcIndex) {
+	if (npcIndex == 0) {
+		snd_playSoundEffect(57);
+		if (npcJoinDialogue(0, 1, 3, 2))
+			setScriptFlags(0x40);
+	} else if (npcIndex == 1) {
+		snd_playSoundEffect(53);
+		gui_drawDialogueBox();
+
+		_txt->printDialogueText(4, 0);
+		int r = runDialogue(-1, 2, _npcStrings[0][0], _npcStrings[0][1]) - 1;
+
+		if (r == 0) {
+			snd_stopSound();
+			delay(3 * _tickLength);
+			snd_playSoundEffect(91);
+			npcJoinDialogue(1, 5, 6, 7);
+		} else if (r == 1) {
+			setScriptFlags(0x20);
+		}
+
+	} else if (npcIndex == 2) {
+		snd_playSoundEffect(55);
+		gui_drawDialogueBox();
+
+		_txt->printDialogueText(8, 0);
+		int r = runDialogue(-1, 2, _npcStrings[1][0], _npcStrings[1][1]) - 1;
+
+		if (r == 0) {
+			if (rollDice(1, 2, -1))
+				_txt->printDialogueText(9, _okStrings[0]);
+			else
+				npcJoinDialogue(2, 102, 103, 104);
+			setScriptFlags(8);
+		} else if (r == 1) {
+			_currentDirection = 0;
+		}
+	}
+}
+
+void DarkMoonEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
+	EobItem *itm = &_items[_characters[charIndex].inventory[slot]];
+	if (itm->type == 48 || itm->type == 62) {
+		if (itm->value == 5)
+			return;
+		int charges = itm->flags & 0x3f;
+		if (--charges)
+			--itm->flags;
+		else
+			deleteInventoryItem(charIndex, slot);
+	} else if (itm->type == 26 || itm->type == 34 || itm->type == 35) {
+		deleteInventoryItem(charIndex, slot);
+	}
+}
+
+void DarkMoonEngine::generateMonsterPalettes(const char *file, int16 monsterIndex) {
+	int cp = _screen->setCurPage(2);
+	_screen->loadShapeSetBitmap(file, 3, 3);
+	uint8 tmpPal[16];
+	uint8 newPal[16];
+
+	for (int i = 0; i < 6; i++) {
+		int dci = monsterIndex + i;
+		memcpy(tmpPal, _monsterShapes[dci] + 4, 16);
+		int colx = 302 + 3 * i;
+
+		for (int ii = 0; ii < 16; ii++) {
+			uint8 col = _screen->getPagePixel(_screen->_curPage, colx, 184 + ii);
+
+			int iii = 0;
+			for (; iii < 16; iii++) {
+				if (tmpPal[iii] == col) {
+					newPal[ii] = iii;
+					break;
+				}
+			}
+
+			if (iii == 16)
+				newPal[ii] = 0;
+		}
+
+		for (int ii = 1; ii < 3; ii++) {
+			memcpy(tmpPal, _monsterShapes[dci] + 4, 16);
+
+			for (int iii = 0; iii < 16; iii++) {
+				uint8 col = _screen->getPagePixel(_screen->_curPage, colx + ii, 184 + iii);
+				if (newPal[iii])
+					tmpPal[newPal[iii]] = col;
+			}
+
+			int c = i;
+			if (monsterIndex >= 18)
+				c += 6;
+
+			c = (c << 1) + (ii - 1);
+			assert(c < 24);
+			memcpy(_monsterPalettes[c], tmpPal, 16);
+		}
+	}
+
+	_screen->setCurPage(cp);
+}
+
+void DarkMoonEngine::loadMonsterDecoration(const char *file, int16 monsterIndex) {
+	Common::SeekableReadStream *s = _res->createReadStream(Common::String::format("%s.dcr", file));
+	if (!s)
+		return;
+
+	int len = s->readUint16LE();
+
+	for (int i = 0; i < len; i++) {
+		for (int ii = 0; ii < 6; ii++) {
+			uint8 dc[6];
+			s->read(dc, 6);
+			if (!dc[2] || !dc[3])
+				continue;
+
+			SpriteDecoration *m = &_monsterDecorations[i * 6 + ii + monsterIndex];
+
+			m->shp = _screen->encodeShape(dc[0], dc[1], dc[2], dc[3]);
+			m->x = (int8)dc[4];
+			m->y = (int8)dc[5];
+		}
+	}
+
+	delete s;
+}
+
+void DarkMoonEngine::replaceMonster(int unit, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem) {
+	uint8 flg = _levelBlockProperties[block].flags & 7;
+
+	if (flg == 7 || _currentBlock == block || (flg && (_monsterProps[type].u30 || pos == 4)))
+		return;
+
+	for (int i = 0; i < 30; i++) {
+		if (_monsters[i].block != block)
+			continue;
+		if (_monsters[i].pos == 4 || _monsterProps[_monsters[i].type].u30)
+			return;
+	}
+
+	int index = -1;
+	int maxDist = 0;
+
+	for (int i = 0; i < 30; i++) {
+		if (_monsters[i].hitPointsCur <= 0) {
+			index = i;
+			break;
+		}
+
+		if (_monsters[i].flags & 0x40)
+			continue;
+
+		int dist = getBlockDistance(_monsters[i].block, _currentBlock);
+
+		if (dist > maxDist) {
+			maxDist = dist;
+			index = i;
+		}
+	}
+
+	if (index == -1)
+		return;
+
+	if (_monsters[index].hitPointsCur > 0)
+		killMonster(&_monsters[index], false);
+
+	initMonster(index, unit, block, pos, dir, type, shpIndex, mode, h2, randItem, fixedItem);
+}
+
+bool DarkMoonEngine::killMonsterExtra(EobMonsterInPlay *m) {
+	if (_currentLevel == 16 && _currentSub == 1 && (_monsterProps[m->type].capsFlags & 4)) {
+		if (m->type) {
+			_playFinale = true;
+			_runFlag = false;
+			delay(850);
+		} else {
+			m->hitPointsCur = 150;
+			m->curRemoteWeapon = 0;
+			m->numRemoteAttacks = 255;
+			m->shpIndex++;
+			m->type++;
+			seq_dranDragonTransformation();
+		}
+		return false;
+	}
+	return true;
+}
+
+const uint8 *DarkMoonEngine::loadDoorShapes(const char *filename, int doorIndex, const uint8 *shapeDefs) {
+	_screen->loadShapeSetBitmap(filename, 3, 3);
+	for (int i = 0; i < 3; i++) {
+		_doorShapes[doorIndex * 3 + i] = _screen->encodeShape(READ_LE_UINT16(shapeDefs), READ_LE_UINT16(shapeDefs + 2), READ_LE_UINT16(shapeDefs + 4), READ_LE_UINT16(shapeDefs + 6));
+		shapeDefs += 8;
+	}
+
+	for (int i = 0; i < 2; i++) {
+		_doorSwitches[doorIndex * 3 + i].shp = _screen->encodeShape(READ_LE_UINT16(shapeDefs), READ_LE_UINT16(shapeDefs + 2), READ_LE_UINT16(shapeDefs + 4), READ_LE_UINT16(shapeDefs + 6));
+		shapeDefs += 8;
+		_doorSwitches[doorIndex * 3 + i].x = *shapeDefs;
+		shapeDefs += 2;
+		_doorSwitches[doorIndex * 3 + i].y= *shapeDefs;
+		shapeDefs += 2;
+	}
+	_screen->_curPage = 0;
+	return shapeDefs;
+}
+
+void DarkMoonEngine::drawDoorIntern(int type, int, int x, int y, int w, int wall, int mDim, int16, int16) {
+	int shapeIndex = type * 3 + 2 - mDim;
+	uint8 *shp = _doorShapes[shapeIndex];
+	if (!shp)
+		return;
+
+	if ((_doorType[type] == 0) || (_doorType[type] == 1)) {
+		y = _dscDoorY1[mDim] - shp[1];
+		x -= (shp[2] << 2);
+
+		if (_doorType[type] == 1) {
+			drawBlockObject(0, 2, shp, x, y, 5);
+			shp = _doorShapes[3 + shapeIndex];
+		}
+
+		y -= ((wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult1[mDim]);
+
+		if (_specialWallTypes[wall] == 5)
+			y -= _dscDoorType5Offs[shapeIndex];
+
+	} else if (_doorType[type] == 2) {
+		x -= (shp[2] << 2);
+		y = _dscDoorY2[mDim] - ((wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult3[mDim]);
+	}
+
+	drawBlockObject(0, 2, shp, x, y, 5);
+
+	if (_wllShapeMap[wall] == -1 && !_noDoorSwitch[type])
+		drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
+}
+
+void DarkMoonEngine::restParty_npc() {
+	int insalId = -1;
+	int numChar = 0;
+
+	for (int i = 0; i < 6; i++) {
+		if (!testCharacter(i, 1))
+			continue;
+		if (testCharacter(i, 2) && _characters[i].portrait == -1)
+			insalId = i;
+		numChar++;
+	}
+
+	if (insalId == -1 || numChar < 5)
+		return;
+
+	removeCharacterFromParty(insalId);
+	if (insalId < 4)
+		exchangeCharacters(insalId, testCharacter(5, 1) ? 5 : 4);
+
+	clearScriptFlags(6);
+
+	if (!stripPartyItems(1, 1, 1, 1))
+		stripPartyItems(2, 1, 1, 1);
+	stripPartyItems(31, 0, 1, 3);
+	stripPartyItems(39, 1, 0, 3);
+	stripPartyItems(47, 0, 1, 2);
+
+	_items[createItemOnCurrentBlock(28)].value = 26;
+
+	gui_drawPlayField(false);
+	gui_drawAllCharPortraitsWithStats();
+
+	_screen->setClearScreenDim(10);
+	_gui->messageDialogue2(11, 63, 6);
+	_gui->messageDialogue2(11, 64, 6);
+}
+
+bool DarkMoonEngine::restParty_extraAbortCondition() {
+	if (_currentLevel != 3)
+		return false;
+
+	seq_nightmare();
+
+	return true;
+}
+
+void DarkMoonEngine::useHorn(int charIndex, int weaponSlot) {
+	int v = _items[_characters[charIndex].inventory[weaponSlot]].value - 1;
+	_txt->printMessage(_hornStrings[v]);
+	snd_playSoundEffect(_hornSounds[v]);
+}
+
+bool DarkMoonEngine::checkPartyStatusExtra() {
+	if (checkScriptFlags(0x100000))
+		seq_kheldran();
+	return _gui->confirmDialogue2(14, 67, 1);
+}
+
+void DarkMoonEngine::drawLightningColumn() {
+	int f = rollDice(1, 2, -1);
+	int y = 0;
+
+	for (int i = 0; i < 6; i++) {
+		f ^= 1;
+		drawBlockObject(f, 2, _lightningColumnShape, 72, y, 5);
+		y += 64;
+	}
+}
+
+int DarkMoonEngine::resurrectionSelectDialogue() {
+	countResurrectionCandidates();
+
+	_rrNames[_rrCount] = _abortStrings[0];
+	_rrId[_rrCount++] = 99;
+
+	int r = _rrId[runDialogue(-1, 9, _rrNames[0], _rrNames[1], _rrNames[2], _rrNames[3], _rrNames[4], _rrNames[5], _rrNames[6], _rrNames[7], _rrNames[8]) - 1];
+	if (r == 99)
+		return 0;
+
+	if (r < 0) {
+		r = -r;
+		if (prepareForNewPartyMember(33, r))
+			initNpc(r - 1);
+	} else {
+		_characters[r].hitPointsCur = 1;
+	}
+
+	return 1;
+}
+
+int DarkMoonEngine::charSelectDialogue() {
+	int cnt = 0;
+	const char *namesList[7];
+	memset(namesList, 0, 7 * sizeof(const char*));
+
+	for (int i = 0; i < 6; i++) {
+		if (!testCharacter(i, 3))
+			continue;
+		namesList[cnt++] = _characters[i].name;
+	}
+
+	namesList[cnt++] = _abortStrings[0];
+
+	int r = runDialogue(-1, 7, namesList[0], namesList[1], namesList[2], namesList[3], namesList[4], namesList[5], namesList[6]) - 1;
+	if (r == cnt - 1)
+		return 99;
+
+	for (cnt = 0; cnt < 6; cnt++) {
+		if (!testCharacter(cnt, 3))
+			continue;
+		if (--r < 0)
+			break;
+	}
+	return cnt;
+}
+
+void DarkMoonEngine::characterLevelGain(int charIndex) {
+	EobCharacter *c = &_characters[charIndex];
+	int s = _numLevelsPerClass[c->cClass];
+	for (int i = 0; i < s; i++) {
+		uint32 er = getRequiredExperience(c->cClass, i, c->level[i] + 1);
+		if (er == 0xffffffff)
+			continue;
+
+		increaseCharacterExperience(charIndex, er - c->experience[i] + 1);
+	}
+}
+
+}	// End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/darkmoon.h b/engines/kyra/darkmoon.h
new file mode 100644
index 0000000..35eb90a
--- /dev/null
+++ b/engines/kyra/darkmoon.h
@@ -0,0 +1,139 @@
+/* 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.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#ifndef KYRA_EOB2_H
+#define KYRA_EOB2_H
+
+#include "kyra/eobcommon.h"
+
+namespace Kyra {
+
+class DarkmoonSequenceHelper;
+
+struct EobSequenceStep {
+	uint8 command;
+	uint8 obj;
+	int16 x1;
+	uint8 y1;
+	uint8 delay;
+	uint8 pal;
+	uint8 x2;
+	uint8 y2;
+	uint8 w;
+	uint8 h;
+};
+
+class DarkMoonEngine : public EobCoreEngine {
+friend class GUI_Eob;
+friend class DarkmoonSequenceHelper;
+public:
+	DarkMoonEngine(OSystem *system, const GameFlags &flags);
+	~DarkMoonEngine();
+
+private:
+	// Init / Release
+	Common::Error init();
+	void initStaticResource();
+	void initSpells();
+
+	// Main Menu
+	int mainMenu();
+	int mainMenuLoop();
+
+	int _menuChoiceInit;
+
+	// Main loop
+	void startupNew();
+	void startupLoad() {}
+
+	// Intro/Outro
+	void seq_playIntro();
+	void seq_playFinale();
+	void seq_playCredits(DarkmoonSequenceHelper *sq, const uint8 *data, int sd, int backupPage, int tempPage, int speed);
+
+	const char * const *_introStrings;
+	const char * const *_cpsFilesIntro;
+	const EobSequenceStep **_seqIntro;
+	const EobShapeDef **_shapesIntro;
+
+	const char * const *_finaleStrings;
+	const uint8 *_creditsData;
+	const char * const *_cpsFilesFinale;
+	const EobSequenceStep **_seqFinale;
+	const EobShapeDef **_shapesFinale;
+
+	static const char *_palFilesIntro[];
+	static const char *_palFilesFinale[];
+
+	// Ingame sequence
+	void seq_nightmare();
+	void seq_kheldran();
+	void seq_dranDragonTransformation();
+
+	const int8 *_dreamSteps;
+	const char *const *_kheldranStrings;
+
+	// characters
+	void drawNpcScene(int npcIndex);
+	void runNpcDialogue(int npcIndex);
+
+	const uint8 *_npcShpData;
+	const char *const *_npcStrings[2];
+
+	// items
+	void updateUsedCharacterHandItem(int charIndex, int slot);
+
+	// Monsters
+	void generateMonsterPalettes(const char *file, int16 monsterIndex);
+	void loadMonsterDecoration(const char *file, int16 monsterIndex);
+	void replaceMonster(int unit, uint16 block, int d, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem);
+	bool killMonsterExtra(EobMonsterInPlay *m);
+
+	// Level
+	const uint8 *loadDoorShapes(const char *filename, int doorIndex, const uint8 *shapeDefs);
+	void drawDoorIntern(int type, int, int x, int y, int w, int wall, int mDim, int16, int16);
+
+	const uint8 *_dscDoorType5Offs;
+
+	// Rest party
+	void restParty_npc();
+	bool restParty_extraAbortCondition();
+
+	// misc
+	void useHorn(int charIndex, int weaponSlot);
+	bool checkPartyStatusExtra();
+	void drawLightningColumn();
+	int resurrectionSelectDialogue();
+	int charSelectDialogue();
+	void characterLevelGain(int charIndex);
+
+	const char *const *_hornStrings;
+	const uint8 *_hornSounds;
+};
+
+}	// End of namespace Kyra
+
+#endif
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp
index abb6a70..e021a3a 100644
--- a/engines/kyra/detection.cpp
+++ b/engines/kyra/detection.cpp
@@ -24,8 +24,8 @@
 #include "kyra/lol.h"
 #include "kyra/kyra_hof.h"
 #include "kyra/kyra_mr.h"
-#include "kyra/eob1.h"
-#include "kyra/eob2.h"
+#include "kyra/eob.h"
+#include "kyra/darkmoon.h"
 
 #include "common/config-manager.h"
 #include "common/system.h"
diff --git a/engines/kyra/eob.cpp b/engines/kyra/eob.cpp
new file mode 100644
index 0000000..d90a3ca
--- /dev/null
+++ b/engines/kyra/eob.cpp
@@ -0,0 +1,572 @@
+/* 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.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/eob.h"
+#include "kyra/resource.h"
+#include "kyra/sound.h"
+
+namespace Kyra {
+
+EobEngine::EobEngine(OSystem *system, const GameFlags &flags) : EobCoreEngine(system, flags) {
+	_numSpells = 53;
+	_menuChoiceInit = 4;
+
+	_turnUndeadString = _introFilesOpening = _introFilesTower = _introFilesOrb = _introFilesWdEntry	= _introFilesKing = _introFilesHands = _introFilesWdExit =
+		_introFilesTunnel = _finBonusStrings = _npcStrings[1] = _npcStrings[2] = _npcStrings[3] = _npcStrings[4] = _npcStrings[5] = _npcStrings[6] = _npcStrings[7]	=
+		_npcStrings[8] = _npcStrings[9]	= _npcStrings[10] = 0;
+	_introOpeningFrmDelay = _introWdEncodeX	= _introWdEncodeY = _introWdEncodeWH = _npcShpData = _npcSubShpIndex1 = _npcSubShpIndex2 = _npcSubShpY = _introWdDsY =
+		_introTvlX1 = _introTvlY1 = _introTvlX2	= _introTvlY2 = _introTvlW = _introTvlH = _dscDoorScaleMult4 = _dscDoorScaleMult5 = _dscDoorScaleMult6 =
+		_dscDoorY3 = _dscDoorY4 = _dscDoorY5 = _dscDoorY6 = _dscDoorY7 = _doorShapeEncodeDefs = _doorSwitchShapeEncodeDefs = _doorSwitchCoords = 0;
+	_introWdDsX = 0;
+	_dscDoorCoordsExt = 0;
+}
+
+EobEngine::~EobEngine() {
+	delete[] _itemsOverlay;
+}
+
+Common::Error EobEngine::init() {
+	Common::Error err = EobCoreEngine::init();
+	if (err.getCode() != Common::kNoError)
+		return err;
+
+	initStaticResource();
+
+	_itemsOverlay = _res->fileData("ITEMRMP.VGA", 0);
+
+	static const uint16 wX[] = { 285, 139 };
+	static const uint8 wY[] = { 189, 162 };
+	static const uint16 wW[] = { 31, 31 };
+
+	_dialogueButtonLabelCol1 = 9;
+	_dialogueButtonLabelCol2 = 15;
+	_dialogueButtonW = 95;
+	_dialogueButtonH = 9;
+	_waitButtonPresX = wX;
+	_waitButtonPresY = wY;
+	_waitButtonPresW = wW;
+	_waitButtonReverveW = 7;
+
+	_bkgColor_1 = 132;
+	_color1_1 = 135;
+	_color2_1 = 130;
+	_color4 = 133;
+	_color5 = 133;
+	_color6 = 180;
+	_color7 = 177;
+	_color8 = 184;
+
+	_color14 = _color8;
+	_color13 = _color7;
+	_color12 = _color6;
+
+	_screen->modifyScreenDim(7, 0x01, 0xB3, 0x22, 0x12);
+	_screen->modifyScreenDim(9, 0x01, 0x7D, 0x26, 0x3F);
+	_screen->modifyScreenDim(12, 0x01, 0x04, 0x14, 0xA0);
+
+	_scriptTimersCount = 1;
+
+	return Common::kNoError;
+}
+
+void EobEngine::startupNew() {
+	_currentLevel = 1;
+	_currentSub = 0;
+	loadLevel(1, 0);
+	_currentBlock = 490;
+	_currentDirection = 0;
+	setHandItem(0);
+	EobCoreEngine::startupNew();
+}
+
+void EobEngine::startupLoad() {
+	_sound->loadSoundFile("ADLIB");
+}
+
+void EobEngine::drawNpcScene(int npcIndex) {
+	_screen->copyRegion(0, 0, 0, 0, 176, 120, 6, 0, Screen::CR_NO_P_CHECK);
+	switch (npcIndex) {
+	case 0:
+		encodeDrawNpcSeqShape(2, 88, 104);
+		break;
+
+	case 1:
+		if (_npcSequenceSub == -1) {
+			encodeDrawNpcSeqShape(0, 88, 104);
+		} else {
+			encodeDrawNpcSeqShape(0, 60, 104);
+			encodeDrawNpcSeqShape(5, 116, 104);
+		}
+		break;
+
+	case 2:
+		if (_npcSequenceSub == -1) {
+			encodeDrawNpcSeqShape(3, 88, 104);
+		} else {
+			encodeDrawNpcSeqShape(3, 60, 104);
+			encodeDrawNpcSeqShape(_npcSubShpIndex1[_npcSequenceSub], 116, 104);
+			encodeDrawNpcSeqShape(_npcSubShpIndex2[_npcSequenceSub], 116, _npcSubShpY[_npcSequenceSub]);
+		}
+		break;
+
+	case 3:
+		encodeDrawNpcSeqShape(7, 88, 104);
+		break;
+
+	case 4:
+		encodeDrawNpcSeqShape(6, 88, 104);
+		break;
+
+	case 5:
+		encodeDrawNpcSeqShape(18, 88, 88);
+		break;
+
+	case 6:
+		encodeDrawNpcSeqShape(17, 88, 104);
+		break;
+
+	case 7:
+		encodeDrawNpcSeqShape(4, 88, 104);
+		break;
+
+	default:
+		break;
+	}
+}
+
+void EobEngine::encodeDrawNpcSeqShape(int npcIndex, int drawX, int drawY) {
+	const uint8 *shpDef = &_npcShpData[npcIndex << 2];
+	_screen->_curPage = 2;
+	const uint8 *shp = _screen->encodeShape(shpDef[0], shpDef[1], shpDef[2], shpDef[3]);
+	_screen->_curPage = 0;
+	_screen->drawShape(0, shp, drawX - (shp[2] << 2), drawY - shp[1], 5);
+	delete[] shp;
+}
+
+#define DLG2(txt, buttonstr) (runDialogue(txt, 2, _npcStrings[buttonstr][0], _npcStrings[buttonstr][1]) - 1)
+#define DLG3(txt, buttonstr) (runDialogue(txt, 3, _npcStrings[buttonstr][0], _npcStrings[buttonstr][1], _npcStrings[buttonstr][2]) - 1)
+#define DLG2A3(cond, txt, buttonstr1, buttonstr2) ((cond) ? (DLG2(txt, buttonstr1) ? 2 : 0) : DLG3(txt, buttonstr2))
+#define TXT(txt) _txt->printDialogueText(txt, _moreStrings[0])
+
+void EobEngine::runNpcDialogue(int npcIndex) {
+	int r = 0;
+	int a = 0;
+	Item itm = 0;
+
+	switch (npcIndex) {
+	case 0:
+		for (r = 1; r == 1; ) {
+			gui_drawDialogueBox();
+			r = DLG2A3(checkScriptFlags(0x2000), 8, 2, 1);
+			if (r == 1) {
+				TXT(1);
+				setScriptFlags(0x2000);
+			} else if (r == 0) {
+				npcJoinDialogue(6, 12, 23, 2);
+				setScriptFlags(0x4000);
+			}
+		}
+		break;
+
+	case 1:
+		if (!checkScriptFlags(0x10000)) {
+			if (checkScriptFlags(0x8000)) {
+				a = 1;
+			} else {
+				setScriptFlags(0x8000);
+				r = DLG2(3, 3);
+			}
+			if (!r)
+				r = DLG2(a ? 13 : 4, 4);
+
+			if (!r) {
+				for (a = 0; a < 6; a++)
+					createItemOnCurrentBlock(55);
+				createItemOnCurrentBlock(62);
+				setScriptFlags(0x10000);
+				TXT(6);
+				npcJoinDialogue(7, 7, 29, 30);
+			} else {
+				TXT(5);
+			}
+			r = 1;
+		}
+
+		if (!checkScriptFlags(0x80000)) {
+			for (a = 0; a < 6; a++) {
+				if (testCharacter(a, 1) && _characters[a].portrait == -9)
+					break;
+			}
+			if (a != 6) {
+				TXT(25);
+				TXT(26);
+				setScriptFlags(0x80000);
+				r = 1;
+			}
+		}
+
+		if (!checkScriptFlags(0x100000)) {
+			if (deletePartyItems(6, -1)) {
+				//_npcSequenceSub = 0;
+				//drawNpcScene(npcIndex);
+				TXT(28);
+				createItemOnCurrentBlock(32);
+				setScriptFlags(0x100000);
+				r = 1;
+			}
+		}
+
+		if (!r)
+			 _txt->printDialogueText(_npcStrings[0][0], true);
+
+		break;
+
+	case 2:
+		if (checkScriptFlags(0x10000)) {
+			if (checkScriptFlags(0x20000)) {
+				TXT(11);
+			} else {
+				r = DLG2A3(!countResurrectionCandidates(), 9, 5, 6);
+				if (r < 2) {
+					if (r == 0)
+						healParty();
+					else
+						resurrectionSelectDialogue();
+					setScriptFlags(0x20000);
+				}
+			}
+		} else {
+			TXT(24);
+		}
+		break;
+
+	case 3:
+		if (!DLG2(18, 7)) {
+			setScriptFlags(0x8400000);
+			for (a = 0; a < 30; a++) {
+				if (_monsters[a].mode == 8)
+					_monsters[a].mode = 5;
+			}
+		} else if (deletePartyItems(49, -1)) {
+			TXT(20);
+			setScriptFlags(0x400000);
+		} else {
+			TXT(19);
+		}
+		break;
+
+	case 4:
+		r = DLG3(14, 8);
+		if (r == 0)
+			setScriptFlags(0x200000);
+		else if (r == 1)
+			TXT(15);
+		setScriptFlags(0x800000);
+		break;
+
+	case 5:
+		if (!DLG2(16, 9)) {
+			TXT(17);
+			for (a = 0; a < 6; a++) {
+				for (r = 0; r < 2; r++) {
+					itm = _characters[a].inventory[r];
+					if (itm && (_items[itm].type < 51 || _items[itm].type > 56)) {
+						_characters[a].inventory[r] = 0;
+						setItemPosition((Item*)&_levelBlockProperties[_currentBlock].drawObjects, _currentBlock, itm, _dropItemDirIndex[(_currentDirection << 2) + rollDice(1, 2, -1)]);
+					}
+				}
+			}
+		}
+		setScriptFlags(0x2000000);
+		break;
+
+	case 6:
+		TXT(21);
+		setScriptFlags(0x1000000);
+		break;
+
+	case 7:
+		r = DLG3(22, 10);
+		if (r  < 2) {
+			if (r == 0)
+				npcJoinDialogue(8, 27, 44, 45);
+			else
+				TXT(31);
+			setScriptFlags(0x4000000);
+		}
+		break;
+
+	default:
+		break;
+	}
+}
+
+#undef TXT
+#undef DLG2
+#undef DLG3
+#undef DLG2A3
+
+void EobEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
+	EobItem *itm = &_items[_characters[charIndex].inventory[slot]];
+	if (itm->type == 48) {
+		int charges = itm->flags & 0x3f;
+		if (--charges)
+			--itm->flags;
+		else
+			deleteInventoryItem(charIndex, slot);
+	} else if (itm->type == 34 || itm->type == 35) {
+		deleteInventoryItem(charIndex, slot);
+	}
+}
+
+void EobEngine::replaceMonster(int unit, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem) {
+	if (_levelBlockProperties[block].flags & 7)
+		return;
+
+	for (int i = 0; i < 30; i++) {
+		if (_monsters[i].hitPointsCur <= 0) {
+			initMonster(i, unit, block, pos, dir, type, shpIndex, mode, h2, randItem, fixedItem);;
+			break;
+		}
+	}
+}
+
+void EobEngine::updateScriptTimersExtra() {
+	int cnt = 0;
+	for (int i = 1; i < 30; i++) {
+		if (_monsters[i].hitPointsCur <= 0)
+			cnt++;
+	}
+
+	if (!cnt) {
+		for (int i = 1; i < 30; i++) {
+			if (getBlockDistance(_monsters[i].block, _currentBlock) > 3) {
+				killMonster(&_monsters[i], true);
+				break;
+			}
+		}
+	}
+}
+
+void EobEngine::loadDoorShapes(int doorType1, int shapeId1, int doorType2, int shapeId2) {
+	_screen->loadShapeSetBitmap("DOOR", 5, 3);
+	_screen->_curPage = 2;
+
+	if (doorType1 != 0xff) {
+		for (int i = 0; i < 3; i++) {
+			const uint8 *enc = &_doorShapeEncodeDefs[(doorType1 * 3 + i) << 2];
+			_doorShapes[shapeId1 + i] = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
+			enc = &_doorSwitchShapeEncodeDefs[(doorType1 * 3 + i) << 2];
+			_doorSwitches[shapeId1 + i].shp = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
+			_doorSwitches[shapeId1 + i].x = _doorSwitchCoords[doorType1 * 6 + i * 2];
+			_doorSwitches[shapeId1 + i].y = _doorSwitchCoords[doorType1 * 6 + i * 2 + 1];
+		}
+	}
+
+	if (doorType2 != 0xff) {
+		for (int i = 0; i < 3; i++) {
+			const uint8 *enc = &_doorShapeEncodeDefs[(doorType2 * 3 + i) << 2];
+			_doorShapes[shapeId2 + i] = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
+			enc = &_doorSwitchShapeEncodeDefs[(doorType2 * 3 + i) << 2];
+			_doorSwitches[shapeId2 + i].shp = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
+			_doorSwitches[shapeId2 + i].x = _doorSwitchCoords[doorType2 * 6 + i * 2];
+			_doorSwitches[shapeId2 + i].y = _doorSwitchCoords[doorType2 * 6 + i * 2+ 1];
+		}
+	}
+
+	_screen->_curPage = 0;
+}
+
+void EobEngine::drawDoorIntern(int type, int index, int x, int y, int w, int wall, int mDim, int16 y1, int16 y2) {
+	int shapeIndex = type + 2 - mDim;
+	uint8 *shp = _doorShapes[shapeIndex];
+
+	int d1 = 0;
+	int d2 = 0;
+	int v = 0;
+	const ScreenDim *td = _screen->getScreenDim(5);
+
+	switch (_currentLevel) {
+		case 4:
+		case 5:
+		case 6:
+			y = _dscDoorY6[mDim] - shp[1];
+			d1 = _dscDoorCoordsExt[index << 1] >> 3;
+			d2 = _dscDoorCoordsExt[(index << 1) + 1] >> 3;
+			if (_shpDmX1 > d1)
+				d1 = _shpDmX1;
+			if (_shpDmX2 < d2)
+				d2 = _shpDmX2;
+			_screen->modifyScreenDim(5, d1, td->sy, d2 - d1, td->h);
+			v = ((wall < 30) ? (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult3[mDim] : _dscDoorScaleMult4[mDim]) * -1;
+			v -= (shp[2] << 3);
+			drawBlockObject(0, 2, shp, x + v, y, 5);
+			v += (shp[2] << 3);
+			drawBlockObject(1, 2, shp, x - v, y, 5);
+			if (_wllShapeMap[wall] == -1)
+				drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w - v, _doorSwitches[shapeIndex].y, 5);
+			break;
+
+		case 7:
+		case 8:
+		case 9:
+			y = _dscDoorY3[mDim] - _doorShapes[shapeIndex + 3][1];
+			d1 = x - (_doorShapes[shapeIndex + 3][2] << 2);
+			x -= (shp[2] << 2);
+			drawBlockObject(0, 2, _doorShapes[shapeIndex + 3], d1, y, 5);
+			scaleLevelShapesDim(index, y1, y2, 5);
+			y = _dscDoorY3[mDim] - ((wall < 30) ? (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult1[mDim] : _dscDoorScaleMult2[mDim]);
+			drawBlockObject(0, 2, shp, x, y, 5);
+			if (_wllShapeMap[wall] == -1)
+				drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
+			break;
+
+		case 10:
+		case 11:
+			v = ((wall < 30) ? (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult5[mDim] : _dscDoorScaleMult6[mDim]) * -1;
+			x -= (shp[2] << 2);
+			y = _dscDoorY4[mDim] + v;
+			drawBlockObject(0, 2, shp, x, y + v, 5);
+			v = (v >> 3) + (v >> 2);
+			y = _dscDoorY5[mDim];
+			drawBlockObject(0, 2, _doorShapes[shapeIndex + 3], x, y - v, 5);
+			if (_wllShapeMap[wall] == -1)
+				drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
+			break;
+
+		default:
+			y = (_currentLevel == 12 ? _dscDoorY6[mDim] : _dscDoorY1[mDim]) - shp[1];
+			x -= (shp[2] << 2);
+			y -= (wall >= 30 ? _dscDoorScaleMult2[mDim] : (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult1[mDim]);
+			drawBlockObject(0, 2, shp, x, y, 5);
+
+			if (_wllShapeMap[wall] == -1)
+				drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
+			break;
+	}
+}
+
+void EobEngine::turnUndeadAuto() {
+	if (_currentLevel != 2 && _currentLevel != 7)
+		return;
+
+	int oc = _openBookChar;
+
+	for (int i = 0; i < 6; i++) {
+		if (!testCharacter(i, 0x0d))
+			continue;
+
+		EobCharacter *c = &_characters[i];
+
+		if (_itemTypes[_items[c->inventory[0]].type].extraProperties != 6 && _itemTypes[_items[c->inventory[1]].type].extraProperties != 6)
+			continue;
+
+		int l = getCharacterLevelIndex(2, c->cClass);
+		if (l > -1) {
+			if (c->level[l] > _openBookCasterLevel) {
+				_openBookCasterLevel = c->level[l];
+				_openBookChar = i;
+			}
+		} else {
+			l = getCharacterLevelIndex(4, c->cClass);
+			if (l > -1) {
+				if ((c->level[l] - 2) > _openBookCasterLevel) {
+					_openBookCasterLevel = (c->level[l] - 2);
+					_openBookChar = i;
+				}
+			}
+		}
+	}
+
+	if (_openBookCasterLevel)
+		spellCallback_start_turnUndead();
+
+	_openBookChar = oc;
+	_openBookCasterLevel = 0;
+}
+
+void EobEngine::turnUndeadAutoHit() {
+	_txt->printMessage(_turnUndeadString[0], -1, _characters[_openBookChar].name);
+	sparkEffectOffensive();
+}
+
+bool EobEngine::checkPartyStatusExtra() {
+	_screen->copyPage(0, 10);
+	int cd = _screen->curDimIndex();
+	gui_drawBox(0, 121, 320, 80, _color1_1, _color2_1, _bkgColor_1);
+	_txt->setupField(9, false);
+	_txt->printMessage(_menuStringsDefeat[0]);
+	while (!shouldQuit()) {
+		removeInputTop();
+		if (checkInput(0, false, 0) & 0xff)
+			break;
+	}
+	_screen->copyPage(10, 0);
+	_eventList.clear();
+	_screen->setScreenDim(cd);
+	_txt->removePageBreakFlag();
+	return true;
+}
+
+int EobEngine::resurrectionSelectDialogue() {
+	gui_drawDialogueBox();
+	_txt->printDialogueText(_npcStrings[0][1]);
+
+	int r = _rrId[runDialogue(-1, 9, _rrNames[0], _rrNames[1], _rrNames[2], _rrNames[3], _rrNames[4], _rrNames[5], _rrNames[6], _rrNames[7], _rrNames[8]) - 1];
+
+	if (r < 0) {
+		r = -r;
+		deletePartyItems(33, r);
+		_npcSequenceSub = r - 1;
+		drawNpcScene(2);
+		npcJoinDialogue(_npcSequenceSub, 32 + (_npcSequenceSub << 1), -1, 33 + (_npcSequenceSub << 1));
+	} else {
+		_characters[r].hitPointsCur = _characters[r].hitPointsMax;
+	}
+
+	return 1;
+}
+
+void EobEngine::healParty() {
+	int cnt = rollDice(1, 3, 2);
+	for (int i = 0; i < 6 && cnt; i++) {
+		if (testCharacter(i, 3))
+			continue;
+
+		_characters[i].flags &= ~4;
+		neutralizePoison(i);
+
+		if (_characters[i].hitPointsCur >= _characters[i].hitPointsMax)
+			continue;
+
+		cnt--;
+		_characters[i].hitPointsCur += rollDice(1, 8, 9);
+		if (_characters[i].hitPointsCur > _characters[i].hitPointsMax)
+			_characters[i].hitPointsCur = _characters[i].hitPointsMax;
+	}
+}
+
+}	// End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/eob.h b/engines/kyra/eob.h
new file mode 100644
index 0000000..2dfccca
--- /dev/null
+++ b/engines/kyra/eob.h
@@ -0,0 +1,149 @@
+/* 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.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#ifndef KYRA_EOB1_H
+#define KYRA_EOB1_H
+
+#include "kyra/eobcommon.h"
+
+namespace Kyra {
+
+class EobEngine : public EobCoreEngine {
+friend class GUI_Eob;
+public:
+	EobEngine(OSystem *system, const GameFlags &flags);
+	~EobEngine();
+
+private:
+	// Init / Release
+	Common::Error init();
+	void initStaticResource();
+	void initSpells();
+
+	// Main Menu
+	int mainMenu();
+	int mainMenuLoop();
+	int _menuChoiceInit;
+
+	// Main loop
+	void startupNew();
+	void startupLoad();
+
+	// Intro/Outro
+	void seq_playOpeningCredits();
+	void seq_playIntro();
+	void seq_playFinale();
+
+	void seq_tower();
+	void seq_orb();
+	void seq_waterdeepEntry();
+	void seq_king();
+	void seq_hands();
+	void seq_waterdeepExit();
+	void seq_tunnel();
+
+	void seq_xdeath();
+
+	void loadSetIntroPalette(const char *filename);
+	void copyBlurRegion(int x1, int y1, int x2, int y2, int w, int h, int step);
+	void boxMorphTransition(int targetDestX, int targetDestY, int targetFinalX, int targetFinalY, int targetSrcX, int targetSrcY, int targetFinalW, int targetFinalH, int originX1, int originY1, int originW, int originH);
+	void whirlTransition();
+
+	const char *const *_introFilesOpening;
+	const char *const *_introFilesTower;
+	const char *const *_introFilesOrb;
+	const char *const *_introFilesWdEntry;
+	const char *const *_introFilesKing;
+	const char *const *_introFilesHands;
+	const char *const *_introFilesWdExit;
+	const char *const *_introFilesTunnel;
+	const uint8 *_introOpeningFrmDelay;
+	const uint8 *_introWdEncodeX;
+	const uint8 *_introWdEncodeY;
+	const uint8 *_introWdEncodeWH;
+	const uint16 *_introWdDsX;
+	const uint8 *_introWdDsY;
+	const uint8 *_introTvlX1;
+	const uint8 *_introTvlY1;
+	const uint8 *_introTvlX2;
+	const uint8 *_introTvlY2;
+	const uint8 *_introTvlW;
+	const uint8 *_introTvlH;
+
+	const char *const *_finBonusStrings;
+
+	// characters
+	void drawNpcScene(int npcIndex);
+	void encodeDrawNpcSeqShape(int npcIndex, int drawX, int drawY);
+	void runNpcDialogue(int npcIndex);
+
+	const uint8 *_npcShpData;
+	const uint8 *_npcSubShpIndex1;
+	const uint8 *_npcSubShpIndex2;
+	const uint8 *_npcSubShpY;
+	const char *const *_npcStrings[11];
+
+	// items
+	void updateUsedCharacterHandItem(int charIndex, int slot);
+
+	// Monsters
+	void replaceMonster(int unit, uint16 block, int d, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem);
+	void updateScriptTimersExtra();
+
+	// Level
+	void loadDoorShapes(int doorType1, int shapeId1, int doorType2, int shapeId2);
+	void drawDoorIntern(int type, int index, int x, int y, int w, int wall, int mDim, int16 y1, int16 y2);
+
+	const int16 *_dscDoorCoordsExt;
+	const uint8 *_dscDoorScaleMult4;
+	const uint8 *_dscDoorScaleMult5;
+	const uint8 *_dscDoorScaleMult6;
+	const uint8 *_dscDoorY3;
+	const uint8 *_dscDoorY4;
+	const uint8 *_dscDoorY5;
+	const uint8 *_dscDoorY6;
+	const uint8 *_dscDoorY7;
+
+	const uint8 *_doorShapeEncodeDefs;
+	const uint8 *_doorSwitchShapeEncodeDefs;
+	const uint8 *_doorSwitchCoords;
+
+	// Magic
+	void turnUndeadAuto();
+	void turnUndeadAutoHit();
+
+	const char * const *_turnUndeadString;
+
+	// Misc
+	bool checkPartyStatusExtra();
+	int resurrectionSelectDialogue();
+	void healParty();
+};
+
+
+}	// End of namespace Kyra
+
+#endif
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
deleted file mode 100644
index c871189..0000000
--- a/engines/kyra/eob1.cpp
+++ /dev/null
@@ -1,572 +0,0 @@
-/* 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.
- *
- */
-
-#ifdef ENABLE_EOB
-
-#include "kyra/eob1.h"
-#include "kyra/resource.h"
-#include "kyra/sound.h"
-
-namespace Kyra {
-
-EobEngine::EobEngine(OSystem *system, const GameFlags &flags) : EobCoreEngine(system, flags) {
-	_numSpells = 53;
-	_menuChoiceInit = 4;
-
-	_turnUndeadString = _introFilesOpening = _introFilesTower = _introFilesOrb = _introFilesWdEntry	= _introFilesKing = _introFilesHands = _introFilesWdExit =
-		_introFilesTunnel = _finBonusStrings = _npcStrings[1] = _npcStrings[2] = _npcStrings[3] = _npcStrings[4] = _npcStrings[5] = _npcStrings[6] = _npcStrings[7]	=
-		_npcStrings[8] = _npcStrings[9]	= _npcStrings[10] = 0;
-	_introOpeningFrmDelay = _introWdEncodeX	= _introWdEncodeY = _introWdEncodeWH = _npcShpData = _npcSubShpIndex1 = _npcSubShpIndex2 = _npcSubShpY = _introWdDsY =
-		_introTvlX1 = _introTvlY1 = _introTvlX2	= _introTvlY2 = _introTvlW = _introTvlH = _dscDoorScaleMult4 = _dscDoorScaleMult5 = _dscDoorScaleMult6 =
-		_dscDoorY3 = _dscDoorY4 = _dscDoorY5 = _dscDoorY6 = _dscDoorY7 = _doorShapeEncodeDefs = _doorSwitchShapeEncodeDefs = _doorSwitchCoords = 0;
-	_introWdDsX = 0;
-	_dscDoorCoordsExt = 0;
-}
-
-EobEngine::~EobEngine() {
-	delete[] _itemsOverlay;
-}
-
-Common::Error EobEngine::init() {
-	Common::Error err = EobCoreEngine::init();
-	if (err.getCode() != Common::kNoError)
-		return err;
-
-	initStaticResource();
-
-	_itemsOverlay = _res->fileData("ITEMRMP.VGA", 0);
-
-	static const uint16 wX[] = { 285, 139 };
-	static const uint8 wY[] = { 189, 162 };
-	static const uint16 wW[] = { 31, 31 };
-
-	_dialogueButtonLabelCol1 = 9;
-	_dialogueButtonLabelCol2 = 15;
-	_dialogueButtonW = 95;
-	_dialogueButtonH = 9;
-	_waitButtonPresX = wX;
-	_waitButtonPresY = wY;
-	_waitButtonPresW = wW;
-	_waitButtonReverveW = 7;
-
-	_bkgColor_1 = 132;
-	_color1_1 = 135;
-	_color2_1 = 130;
-	_color4 = 133;
-	_color5 = 133;
-	_color6 = 180;
-	_color7 = 177;
-	_color8 = 184;
-
-	_color14 = _color8;
-	_color13 = _color7;
-	_color12 = _color6;
-
-	_screen->modifyScreenDim(7, 0x01, 0xB3, 0x22, 0x12);
-	_screen->modifyScreenDim(9, 0x01, 0x7D, 0x26, 0x3F);
-	_screen->modifyScreenDim(12, 0x01, 0x04, 0x14, 0xA0);
-
-	_scriptTimersCount = 1;
-
-	return Common::kNoError;
-}
-
-void EobEngine::startupNew() {
-	_currentLevel = 1;
-	_currentSub = 0;
-	loadLevel(1, 0);
-	_currentBlock = 490;
-	_currentDirection = 0;
-	setHandItem(0);
-	EobCoreEngine::startupNew();
-}
-
-void EobEngine::startupLoad() {
-	_sound->loadSoundFile("ADLIB");
-}
-
-void EobEngine::drawNpcScene(int npcIndex) {
-	_screen->copyRegion(0, 0, 0, 0, 176, 120, 6, 0, Screen::CR_NO_P_CHECK);
-	switch (npcIndex) {
-	case 0:
-		encodeDrawNpcSeqShape(2, 88, 104);
-		break;
-
-	case 1:
-		if (_npcSequenceSub == -1) {
-			encodeDrawNpcSeqShape(0, 88, 104);
-		} else {
-			encodeDrawNpcSeqShape(0, 60, 104);
-			encodeDrawNpcSeqShape(5, 116, 104);
-		}
-		break;
-
-	case 2:
-		if (_npcSequenceSub == -1) {
-			encodeDrawNpcSeqShape(3, 88, 104);
-		} else {
-			encodeDrawNpcSeqShape(3, 60, 104);
-			encodeDrawNpcSeqShape(_npcSubShpIndex1[_npcSequenceSub], 116, 104);
-			encodeDrawNpcSeqShape(_npcSubShpIndex2[_npcSequenceSub], 116, _npcSubShpY[_npcSequenceSub]);
-		}
-		break;
-
-	case 3:
-		encodeDrawNpcSeqShape(7, 88, 104);
-		break;
-
-	case 4:
-		encodeDrawNpcSeqShape(6, 88, 104);
-		break;
-
-	case 5:
-		encodeDrawNpcSeqShape(18, 88, 88);
-		break;
-
-	case 6:
-		encodeDrawNpcSeqShape(17, 88, 104);
-		break;
-
-	case 7:
-		encodeDrawNpcSeqShape(4, 88, 104);
-		break;
-
-	default:
-		break;
-	}
-}
-
-void EobEngine::encodeDrawNpcSeqShape(int npcIndex, int drawX, int drawY) {
-	const uint8 *shpDef = &_npcShpData[npcIndex << 2];
-	_screen->_curPage = 2;
-	const uint8 *shp = _screen->encodeShape(shpDef[0], shpDef[1], shpDef[2], shpDef[3]);
-	_screen->_curPage = 0;
-	_screen->drawShape(0, shp, drawX - (shp[2] << 2), drawY - shp[1], 5);
-	delete[] shp;
-}
-
-#define DLG2(txt, buttonstr) (runDialogue(txt, 2, _npcStrings[buttonstr][0], _npcStrings[buttonstr][1]) - 1)
-#define DLG3(txt, buttonstr) (runDialogue(txt, 3, _npcStrings[buttonstr][0], _npcStrings[buttonstr][1], _npcStrings[buttonstr][2]) - 1)
-#define DLG2A3(cond, txt, buttonstr1, buttonstr2) ((cond) ? (DLG2(txt, buttonstr1) ? 2 : 0) : DLG3(txt, buttonstr2))
-#define TXT(txt) _txt->printDialogueText(txt, _moreStrings[0])
-
-void EobEngine::runNpcDialogue(int npcIndex) {
-	int r = 0;
-	int a = 0;
-	Item itm = 0;
-
-	switch (npcIndex) {
-	case 0:
-		for (r = 1; r == 1; ) {
-			gui_drawDialogueBox();
-			r = DLG2A3(checkScriptFlags(0x2000), 8, 2, 1);
-			if (r == 1) {
-				TXT(1);
-				setScriptFlags(0x2000);
-			} else if (r == 0) {
-				npcJoinDialogue(6, 12, 23, 2);
-				setScriptFlags(0x4000);
-			}
-		}
-		break;
-
-	case 1:
-		if (!checkScriptFlags(0x10000)) {
-			if (checkScriptFlags(0x8000)) {
-				a = 1;
-			} else {
-				setScriptFlags(0x8000);
-				r = DLG2(3, 3);
-			}
-			if (!r)
-				r = DLG2(a ? 13 : 4, 4);
-
-			if (!r) {
-				for (a = 0; a < 6; a++)
-					createItemOnCurrentBlock(55);
-				createItemOnCurrentBlock(62);
-				setScriptFlags(0x10000);
-				TXT(6);
-				npcJoinDialogue(7, 7, 29, 30);
-			} else {
-				TXT(5);
-			}
-			r = 1;
-		}
-
-		if (!checkScriptFlags(0x80000)) {
-			for (a = 0; a < 6; a++) {
-				if (testCharacter(a, 1) && _characters[a].portrait == -9)
-					break;
-			}
-			if (a != 6) {
-				TXT(25);
-				TXT(26);
-				setScriptFlags(0x80000);
-				r = 1;
-			}
-		}
-
-		if (!checkScriptFlags(0x100000)) {
-			if (deletePartyItems(6, -1)) {
-				//_npcSequenceSub = 0;
-				//drawNpcScene(npcIndex);
-				TXT(28);
-				createItemOnCurrentBlock(32);
-				setScriptFlags(0x100000);
-				r = 1;
-			}
-		}
-
-		if (!r)
-			 _txt->printDialogueText(_npcStrings[0][0], true);
-
-		break;
-
-	case 2:
-		if (checkScriptFlags(0x10000)) {
-			if (checkScriptFlags(0x20000)) {
-				TXT(11);
-			} else {
-				r = DLG2A3(!countResurrectionCandidates(), 9, 5, 6);
-				if (r < 2) {
-					if (r == 0)
-						healParty();
-					else
-						resurrectionSelectDialogue();
-					setScriptFlags(0x20000);
-				}
-			}
-		} else {
-			TXT(24);
-		}
-		break;
-
-	case 3:
-		if (!DLG2(18, 7)) {
-			setScriptFlags(0x8400000);
-			for (a = 0; a < 30; a++) {
-				if (_monsters[a].mode == 8)
-					_monsters[a].mode = 5;
-			}
-		} else if (deletePartyItems(49, -1)) {
-			TXT(20);
-			setScriptFlags(0x400000);
-		} else {
-			TXT(19);
-		}
-		break;
-
-	case 4:
-		r = DLG3(14, 8);
-		if (r == 0)
-			setScriptFlags(0x200000);
-		else if (r == 1)
-			TXT(15);
-		setScriptFlags(0x800000);
-		break;
-
-	case 5:
-		if (!DLG2(16, 9)) {
-			TXT(17);
-			for (a = 0; a < 6; a++) {
-				for (r = 0; r < 2; r++) {
-					itm = _characters[a].inventory[r];
-					if (itm && (_items[itm].type < 51 || _items[itm].type > 56)) {
-						_characters[a].inventory[r] = 0;
-						setItemPosition((Item*)&_levelBlockProperties[_currentBlock].drawObjects, _currentBlock, itm, _dropItemDirIndex[(_currentDirection << 2) + rollDice(1, 2, -1)]);
-					}
-				}
-			}
-		}
-		setScriptFlags(0x2000000);
-		break;
-
-	case 6:
-		TXT(21);
-		setScriptFlags(0x1000000);
-		break;
-
-	case 7:
-		r = DLG3(22, 10);
-		if (r  < 2) {
-			if (r == 0)
-				npcJoinDialogue(8, 27, 44, 45);
-			else
-				TXT(31);
-			setScriptFlags(0x4000000);
-		}
-		break;
-
-	default:
-		break;
-	}
-}
-
-#undef TXT
-#undef DLG2
-#undef DLG3
-#undef DLG2A3
-
-void EobEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
-	EobItem *itm = &_items[_characters[charIndex].inventory[slot]];
-	if (itm->type == 48) {
-		int charges = itm->flags & 0x3f;
-		if (--charges)
-			--itm->flags;
-		else
-			deleteInventoryItem(charIndex, slot);
-	} else if (itm->type == 34 || itm->type == 35) {
-		deleteInventoryItem(charIndex, slot);
-	}
-}
-
-void EobEngine::replaceMonster(int unit, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem) {
-	if (_levelBlockProperties[block].flags & 7)
-		return;
-
-	for (int i = 0; i < 30; i++) {
-		if (_monsters[i].hitPointsCur <= 0) {
-			initMonster(i, unit, block, pos, dir, type, shpIndex, mode, h2, randItem, fixedItem);;
-			break;
-		}
-	}
-}
-
-void EobEngine::updateScriptTimersExtra() {
-	int cnt = 0;
-	for (int i = 1; i < 30; i++) {
-		if (_monsters[i].hitPointsCur <= 0)
-			cnt++;
-	}
-
-	if (!cnt) {
-		for (int i = 1; i < 30; i++) {
-			if (getBlockDistance(_monsters[i].block, _currentBlock) > 3) {
-				killMonster(&_monsters[i], true);
-				break;
-			}
-		}
-	}
-}
-
-void EobEngine::loadDoorShapes(int doorType1, int shapeId1, int doorType2, int shapeId2) {
-	_screen->loadShapeSetBitmap("DOOR", 5, 3);
-	_screen->_curPage = 2;
-
-	if (doorType1 != 0xff) {
-		for (int i = 0; i < 3; i++) {
-			const uint8 *enc = &_doorShapeEncodeDefs[(doorType1 * 3 + i) << 2];
-			_doorShapes[shapeId1 + i] = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
-			enc = &_doorSwitchShapeEncodeDefs[(doorType1 * 3 + i) << 2];
-			_doorSwitches[shapeId1 + i].shp = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
-			_doorSwitches[shapeId1 + i].x = _doorSwitchCoords[doorType1 * 6 + i * 2];
-			_doorSwitches[shapeId1 + i].y = _doorSwitchCoords[doorType1 * 6 + i * 2 + 1];
-		}
-	}
-
-	if (doorType2 != 0xff) {
-		for (int i = 0; i < 3; i++) {
-			const uint8 *enc = &_doorShapeEncodeDefs[(doorType2 * 3 + i) << 2];
-			_doorShapes[shapeId2 + i] = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
-			enc = &_doorSwitchShapeEncodeDefs[(doorType2 * 3 + i) << 2];
-			_doorSwitches[shapeId2 + i].shp = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3]);
-			_doorSwitches[shapeId2 + i].x = _doorSwitchCoords[doorType2 * 6 + i * 2];
-			_doorSwitches[shapeId2 + i].y = _doorSwitchCoords[doorType2 * 6 + i * 2+ 1];
-		}
-	}
-
-	_screen->_curPage = 0;
-}
-
-void EobEngine::drawDoorIntern(int type, int index, int x, int y, int w, int wall, int mDim, int16 y1, int16 y2) {
-	int shapeIndex = type + 2 - mDim;
-	uint8 *shp = _doorShapes[shapeIndex];
-
-	int d1 = 0;
-	int d2 = 0;
-	int v = 0;
-	const ScreenDim *td = _screen->getScreenDim(5);
-
-	switch (_currentLevel) {
-		case 4:
-		case 5:
-		case 6:
-			y = _dscDoorY6[mDim] - shp[1];
-			d1 = _dscDoorCoordsExt[index << 1] >> 3;
-			d2 = _dscDoorCoordsExt[(index << 1) + 1] >> 3;
-			if (_shpDmX1 > d1)
-				d1 = _shpDmX1;
-			if (_shpDmX2 < d2)
-				d2 = _shpDmX2;
-			_screen->modifyScreenDim(5, d1, td->sy, d2 - d1, td->h);
-			v = ((wall < 30) ? (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult3[mDim] : _dscDoorScaleMult4[mDim]) * -1;
-			v -= (shp[2] << 3);
-			drawBlockObject(0, 2, shp, x + v, y, 5);
-			v += (shp[2] << 3);
-			drawBlockObject(1, 2, shp, x - v, y, 5);
-			if (_wllShapeMap[wall] == -1)
-				drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w - v, _doorSwitches[shapeIndex].y, 5);
-			break;
-
-		case 7:
-		case 8:
-		case 9:
-			y = _dscDoorY3[mDim] - _doorShapes[shapeIndex + 3][1];
-			d1 = x - (_doorShapes[shapeIndex + 3][2] << 2);
-			x -= (shp[2] << 2);
-			drawBlockObject(0, 2, _doorShapes[shapeIndex + 3], d1, y, 5);
-			scaleLevelShapesDim(index, y1, y2, 5);
-			y = _dscDoorY3[mDim] - ((wall < 30) ? (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult1[mDim] : _dscDoorScaleMult2[mDim]);
-			drawBlockObject(0, 2, shp, x, y, 5);
-			if (_wllShapeMap[wall] == -1)
-				drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
-			break;
-
-		case 10:
-		case 11:
-			v = ((wall < 30) ? (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult5[mDim] : _dscDoorScaleMult6[mDim]) * -1;
-			x -= (shp[2] << 2);
-			y = _dscDoorY4[mDim] + v;
-			drawBlockObject(0, 2, shp, x, y + v, 5);
-			v = (v >> 3) + (v >> 2);
-			y = _dscDoorY5[mDim];
-			drawBlockObject(0, 2, _doorShapes[shapeIndex + 3], x, y - v, 5);
-			if (_wllShapeMap[wall] == -1)
-				drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
-			break;
-
-		default:
-			y = (_currentLevel == 12 ? _dscDoorY6[mDim] : _dscDoorY1[mDim]) - shp[1];
-			x -= (shp[2] << 2);
-			y -= (wall >= 30 ? _dscDoorScaleMult2[mDim] : (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult1[mDim]);
-			drawBlockObject(0, 2, shp, x, y, 5);
-
-			if (_wllShapeMap[wall] == -1)
-				drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
-			break;
-	}
-}
-
-void EobEngine::turnUndeadAuto() {
-	if (_currentLevel != 2 && _currentLevel != 7)
-		return;
-
-	int oc = _openBookChar;
-
-	for (int i = 0; i < 6; i++) {
-		if (!testCharacter(i, 0x0d))
-			continue;
-
-		EobCharacter *c = &_characters[i];
-
-		if (_itemTypes[_items[c->inventory[0]].type].extraProperties != 6 && _itemTypes[_items[c->inventory[1]].type].extraProperties != 6)
-			continue;
-
-		int l = getCharacterLevelIndex(2, c->cClass);
-		if (l > -1) {
-			if (c->level[l] > _openBookCasterLevel) {
-				_openBookCasterLevel = c->level[l];
-				_openBookChar = i;
-			}
-		} else {
-			l = getCharacterLevelIndex(4, c->cClass);
-			if (l > -1) {
-				if ((c->level[l] - 2) > _openBookCasterLevel) {
-					_openBookCasterLevel = (c->level[l] - 2);
-					_openBookChar = i;
-				}
-			}
-		}
-	}
-
-	if (_openBookCasterLevel)
-		spellCallback_start_turnUndead();
-
-	_openBookChar = oc;
-	_openBookCasterLevel = 0;
-}
-
-void EobEngine::turnUndeadAutoHit() {
-	_txt->printMessage(_turnUndeadString[0], -1, _characters[_openBookChar].name);
-	sparkEffectOffensive();
-}
-
-bool EobEngine::checkPartyStatusExtra() {
-	_screen->copyPage(0, 10);
-	int cd = _screen->curDimIndex();
-	gui_drawBox(0, 121, 320, 80, _color1_1, _color2_1, _bkgColor_1);
-	_txt->setupField(9, false);
-	_txt->printMessage(_menuStringsDefeat[0]);
-	while (!shouldQuit()) {
-		removeInputTop();
-		if (checkInput(0, false, 0) & 0xff)
-			break;
-	}
-	_screen->copyPage(10, 0);
-	_eventList.clear();
-	_screen->setScreenDim(cd);
-	_txt->removePageBreakFlag();
-	return true;
-}
-
-int EobEngine::resurrectionSelectDialogue() {
-	gui_drawDialogueBox();
-	_txt->printDialogueText(_npcStrings[0][1]);
-
-	int r = _rrId[runDialogue(-1, 9, _rrNames[0], _rrNames[1], _rrNames[2], _rrNames[3], _rrNames[4], _rrNames[5], _rrNames[6], _rrNames[7], _rrNames[8]) - 1];
-
-	if (r < 0) {
-		r = -r;
-		deletePartyItems(33, r);
-		_npcSequenceSub = r - 1;
-		drawNpcScene(2);
-		npcJoinDialogue(_npcSequenceSub, 32 + (_npcSequenceSub << 1), -1, 33 + (_npcSequenceSub << 1));
-	} else {
-		_characters[r].hitPointsCur = _characters[r].hitPointsMax;
-	}
-
-	return 1;
-}
-
-void EobEngine::healParty() {
-	int cnt = rollDice(1, 3, 2);
-	for (int i = 0; i < 6 && cnt; i++) {
-		if (testCharacter(i, 3))
-			continue;
-
-		_characters[i].flags &= ~4;
-		neutralizePoison(i);
-
-		if (_characters[i].hitPointsCur >= _characters[i].hitPointsMax)
-			continue;
-
-		cnt--;
-		_characters[i].hitPointsCur += rollDice(1, 8, 9);
-		if (_characters[i].hitPointsCur > _characters[i].hitPointsMax)
-			_characters[i].hitPointsCur = _characters[i].hitPointsMax;
-	}
-}
-
-}	// End of namespace Kyra
-
-#endif // ENABLE_EOB
diff --git a/engines/kyra/eob1.h b/engines/kyra/eob1.h
deleted file mode 100644
index 2dfccca..0000000
--- a/engines/kyra/eob1.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/* 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.
- *
- */
-
-#ifdef ENABLE_EOB
-
-#ifndef KYRA_EOB1_H
-#define KYRA_EOB1_H
-
-#include "kyra/eobcommon.h"
-
-namespace Kyra {
-
-class EobEngine : public EobCoreEngine {
-friend class GUI_Eob;
-public:
-	EobEngine(OSystem *system, const GameFlags &flags);
-	~EobEngine();
-
-private:
-	// Init / Release
-	Common::Error init();
-	void initStaticResource();
-	void initSpells();
-
-	// Main Menu
-	int mainMenu();
-	int mainMenuLoop();
-	int _menuChoiceInit;
-
-	// Main loop
-	void startupNew();
-	void startupLoad();
-
-	// Intro/Outro
-	void seq_playOpeningCredits();
-	void seq_playIntro();
-	void seq_playFinale();
-
-	void seq_tower();
-	void seq_orb();
-	void seq_waterdeepEntry();
-	void seq_king();
-	void seq_hands();
-	void seq_waterdeepExit();
-	void seq_tunnel();
-
-	void seq_xdeath();
-
-	void loadSetIntroPalette(const char *filename);
-	void copyBlurRegion(int x1, int y1, int x2, int y2, int w, int h, int step);
-	void boxMorphTransition(int targetDestX, int targetDestY, int targetFinalX, int targetFinalY, int targetSrcX, int targetSrcY, int targetFinalW, int targetFinalH, int originX1, int originY1, int originW, int originH);
-	void whirlTransition();
-
-	const char *const *_introFilesOpening;
-	const char *const *_introFilesTower;
-	const char *const *_introFilesOrb;
-	const char *const *_introFilesWdEntry;
-	const char *const *_introFilesKing;
-	const char *const *_introFilesHands;
-	const char *const *_introFilesWdExit;
-	const char *const *_introFilesTunnel;
-	const uint8 *_introOpeningFrmDelay;
-	const uint8 *_introWdEncodeX;
-	const uint8 *_introWdEncodeY;
-	const uint8 *_introWdEncodeWH;
-	const uint16 *_introWdDsX;
-	const uint8 *_introWdDsY;
-	const uint8 *_introTvlX1;
-	const uint8 *_introTvlY1;
-	const uint8 *_introTvlX2;
-	const uint8 *_introTvlY2;
-	const uint8 *_introTvlW;
-	const uint8 *_introTvlH;
-
-	const char *const *_finBonusStrings;
-
-	// characters
-	void drawNpcScene(int npcIndex);
-	void encodeDrawNpcSeqShape(int npcIndex, int drawX, int drawY);
-	void runNpcDialogue(int npcIndex);
-
-	const uint8 *_npcShpData;
-	const uint8 *_npcSubShpIndex1;
-	const uint8 *_npcSubShpIndex2;
-	const uint8 *_npcSubShpY;
-	const char *const *_npcStrings[11];
-
-	// items
-	void updateUsedCharacterHandItem(int charIndex, int slot);
-
-	// Monsters
-	void replaceMonster(int unit, uint16 block, int d, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem);
-	void updateScriptTimersExtra();
-
-	// Level
-	void loadDoorShapes(int doorType1, int shapeId1, int doorType2, int shapeId2);
-	void drawDoorIntern(int type, int index, int x, int y, int w, int wall, int mDim, int16 y1, int16 y2);
-
-	const int16 *_dscDoorCoordsExt;
-	const uint8 *_dscDoorScaleMult4;
-	const uint8 *_dscDoorScaleMult5;
-	const uint8 *_dscDoorScaleMult6;
-	const uint8 *_dscDoorY3;
-	const uint8 *_dscDoorY4;
-	const uint8 *_dscDoorY5;
-	const uint8 *_dscDoorY6;
-	const uint8 *_dscDoorY7;
-
-	const uint8 *_doorShapeEncodeDefs;
-	const uint8 *_doorSwitchShapeEncodeDefs;
-	const uint8 *_doorSwitchCoords;
-
-	// Magic
-	void turnUndeadAuto();
-	void turnUndeadAutoHit();
-
-	const char * const *_turnUndeadString;
-
-	// Misc
-	bool checkPartyStatusExtra();
-	int resurrectionSelectDialogue();
-	void healParty();
-};
-
-
-}	// End of namespace Kyra
-
-#endif
-
-#endif // ENABLE_EOB
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
deleted file mode 100644
index 64e394a..0000000
--- a/engines/kyra/eob2.cpp
+++ /dev/null
@@ -1,480 +0,0 @@
-/* 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.
- *
- */
-
-#ifdef ENABLE_EOB
-
-#include "kyra/eob2.h"
-#include "kyra/resource.h"
-#include "kyra/sound.h"
-
-namespace Kyra {
-
-DarkMoonEngine::DarkMoonEngine(OSystem *system, const GameFlags &flags) : EobCoreEngine(system, flags) {
-	_seqIntro = _seqFinale = 0;
-	_shapesIntro = _shapesFinale = 0;
-	_dscDoorType5Offs = 0;
-	_numSpells = 70;
-	_menuChoiceInit = 4;
-
-	_introStrings = _cpsFilesIntro = _cpsFilesFinale = _finaleStrings = _kheldranStrings = _npcStrings[0] = _npcStrings[1] = _hornStrings = 0;
-	_seqIntro = _seqFinale = 0;
-	_shapesIntro = _shapesFinale = 0;
-	_creditsData = _npcShpData = _dscDoorType5Offs = _hornSounds = 0;
-	_dreamSteps = 0;
-}
-
-DarkMoonEngine::~DarkMoonEngine() {
-	delete[] _seqIntro;
-	delete[] _seqFinale;
-	delete[] _shapesIntro;
-	delete[] _shapesFinale;
-}
-
-Common::Error DarkMoonEngine::init() {
-	Common::Error err = EobCoreEngine::init();
-	if (err.getCode() != Common::kNoError)
-		return err;
-
-	initStaticResource();
-
-	_monsterProps = new EobMonsterProperty[10];
-
-	static const uint16 wX[] = { 221, 76 };
-	static const uint8 wY[] = { 189, 162 };
-	static const uint16 wW[] = { 95, 95 };
-
-	_dialogueButtonLabelCol1 = 9;
-	_dialogueButtonLabelCol2 = 15;
-	_dialogueButtonW = 95;
-	_dialogueButtonH = 9;
-	_waitButtonPresX = wX;
-	_waitButtonPresY = wY;
-	_waitButtonPresW = wW;
-	_waitButtonReverveW = 7;
-
-	_bkgColor_1 = 183;
-	_color1_1 = 186;
-	_color2_1 = 181;
-	_color4 = 133;
-	_color5 = 184;
-	_color6 = 183;
-	_color7 = 181;
-	_color8 = 186;
-	_color12 = 180;
-	_color13 = 177;
-	_color14 = 182;
-
-	return Common::kNoError;
-}
-
-void DarkMoonEngine::startupNew() {
-	_currentLevel = 4;
-	_currentSub = 0;
-	loadLevel(4, 0);
-	_currentBlock = 171;
-	_currentDirection = 2;
-	setHandItem(0);
-	EobCoreEngine::startupNew();
-}
-
-void DarkMoonEngine::drawNpcScene(int npcIndex) {
-	const uint8 *shpDef = &_npcShpData[npcIndex << 3];
-	for (int i = npcIndex; i != 255; i = shpDef[7]) {
-		shpDef = &_npcShpData[i << 3];
-		_screen->_curPage = 2;
-		const uint8 *shp = _screen->encodeShape(READ_LE_UINT16(shpDef), shpDef[2], shpDef[3], shpDef[4]);
-		_screen->_curPage = 0;
-		_screen->drawShape(0, shp, 88 + shpDef[5] - (shp[2] << 2), 104 + shpDef[6] - shp[1], 5);
-		delete[] shp;
-	}
-}
-
-void DarkMoonEngine::runNpcDialogue(int npcIndex) {
-	if (npcIndex == 0) {
-		snd_playSoundEffect(57);
-		if (npcJoinDialogue(0, 1, 3, 2))
-			setScriptFlags(0x40);
-	} else if (npcIndex == 1) {
-		snd_playSoundEffect(53);
-		gui_drawDialogueBox();
-
-		_txt->printDialogueText(4, 0);
-		int r = runDialogue(-1, 2, _npcStrings[0][0], _npcStrings[0][1]) - 1;
-
-		if (r == 0) {
-			snd_stopSound();
-			delay(3 * _tickLength);
-			snd_playSoundEffect(91);
-			npcJoinDialogue(1, 5, 6, 7);
-		} else if (r == 1) {
-			setScriptFlags(0x20);
-		}
-
-	} else if (npcIndex == 2) {
-		snd_playSoundEffect(55);
-		gui_drawDialogueBox();
-
-		_txt->printDialogueText(8, 0);
-		int r = runDialogue(-1, 2, _npcStrings[1][0], _npcStrings[1][1]) - 1;
-
-		if (r == 0) {
-			if (rollDice(1, 2, -1))
-				_txt->printDialogueText(9, _okStrings[0]);
-			else
-				npcJoinDialogue(2, 102, 103, 104);
-			setScriptFlags(8);
-		} else if (r == 1) {
-			_currentDirection = 0;
-		}
-	}
-}
-
-void DarkMoonEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
-	EobItem *itm = &_items[_characters[charIndex].inventory[slot]];
-	if (itm->type == 48 || itm->type == 62) {
-		if (itm->value == 5)
-			return;
-		int charges = itm->flags & 0x3f;
-		if (--charges)
-			--itm->flags;
-		else
-			deleteInventoryItem(charIndex, slot);
-	} else if (itm->type == 26 || itm->type == 34 || itm->type == 35) {
-		deleteInventoryItem(charIndex, slot);
-	}
-}
-
-void DarkMoonEngine::generateMonsterPalettes(const char *file, int16 monsterIndex) {
-	int cp = _screen->setCurPage(2);
-	_screen->loadShapeSetBitmap(file, 3, 3);
-	uint8 tmpPal[16];
-	uint8 newPal[16];
-
-	for (int i = 0; i < 6; i++) {
-		int dci = monsterIndex + i;
-		memcpy(tmpPal, _monsterShapes[dci] + 4, 16);
-		int colx = 302 + 3 * i;
-
-		for (int ii = 0; ii < 16; ii++) {
-			uint8 col = _screen->getPagePixel(_screen->_curPage, colx, 184 + ii);
-
-			int iii = 0;
-			for (; iii < 16; iii++) {
-				if (tmpPal[iii] == col) {
-					newPal[ii] = iii;
-					break;
-				}
-			}
-
-			if (iii == 16)
-				newPal[ii] = 0;
-		}
-
-		for (int ii = 1; ii < 3; ii++) {
-			memcpy(tmpPal, _monsterShapes[dci] + 4, 16);
-
-			for (int iii = 0; iii < 16; iii++) {
-				uint8 col = _screen->getPagePixel(_screen->_curPage, colx + ii, 184 + iii);
-				if (newPal[iii])
-					tmpPal[newPal[iii]] = col;
-			}
-
-			int c = i;
-			if (monsterIndex >= 18)
-				c += 6;
-
-			c = (c << 1) + (ii - 1);
-			assert(c < 24);
-			memcpy(_monsterPalettes[c], tmpPal, 16);
-		}
-	}
-
-	_screen->setCurPage(cp);
-}
-
-void DarkMoonEngine::loadMonsterDecoration(const char *file, int16 monsterIndex) {
-	Common::SeekableReadStream *s = _res->createReadStream(Common::String::format("%s.dcr", file));
-	if (!s)
-		return;
-
-	int len = s->readUint16LE();
-
-	for (int i = 0; i < len; i++) {
-		for (int ii = 0; ii < 6; ii++) {
-			uint8 dc[6];
-			s->read(dc, 6);
-			if (!dc[2] || !dc[3])
-				continue;
-
-			SpriteDecoration *m = &_monsterDecorations[i * 6 + ii + monsterIndex];
-
-			m->shp = _screen->encodeShape(dc[0], dc[1], dc[2], dc[3]);
-			m->x = (int8)dc[4];
-			m->y = (int8)dc[5];
-		}
-	}
-
-	delete s;
-}
-
-void DarkMoonEngine::replaceMonster(int unit, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem) {
-	uint8 flg = _levelBlockProperties[block].flags & 7;
-
-	if (flg == 7 || _currentBlock == block || (flg && (_monsterProps[type].u30 || pos == 4)))
-		return;
-
-	for (int i = 0; i < 30; i++) {
-		if (_monsters[i].block != block)
-			continue;
-		if (_monsters[i].pos == 4 || _monsterProps[_monsters[i].type].u30)
-			return;
-	}
-
-	int index = -1;
-	int maxDist = 0;
-
-	for (int i = 0; i < 30; i++) {
-		if (_monsters[i].hitPointsCur <= 0) {
-			index = i;
-			break;
-		}
-
-		if (_monsters[i].flags & 0x40)
-			continue;
-
-		int dist = getBlockDistance(_monsters[i].block, _currentBlock);
-
-		if (dist > maxDist) {
-			maxDist = dist;
-			index = i;
-		}
-	}
-
-	if (index == -1)
-		return;
-
-	if (_monsters[index].hitPointsCur > 0)
-		killMonster(&_monsters[index], false);
-
-	initMonster(index, unit, block, pos, dir, type, shpIndex, mode, h2, randItem, fixedItem);
-}
-
-bool DarkMoonEngine::killMonsterExtra(EobMonsterInPlay *m) {
-	if (_currentLevel == 16 && _currentSub == 1 && (_monsterProps[m->type].capsFlags & 4)) {
-		if (m->type) {
-			_playFinale = true;
-			_runFlag = false;
-			delay(850);
-		} else {
-			m->hitPointsCur = 150;
-			m->curRemoteWeapon = 0;
-			m->numRemoteAttacks = 255;
-			m->shpIndex++;
-			m->type++;
-			seq_dranDragonTransformation();
-		}
-		return false;
-	}
-	return true;
-}
-
-const uint8 *DarkMoonEngine::loadDoorShapes(const char *filename, int doorIndex, const uint8 *shapeDefs) {
-	_screen->loadShapeSetBitmap(filename, 3, 3);
-	for (int i = 0; i < 3; i++) {
-		_doorShapes[doorIndex * 3 + i] = _screen->encodeShape(READ_LE_UINT16(shapeDefs), READ_LE_UINT16(shapeDefs + 2), READ_LE_UINT16(shapeDefs + 4), READ_LE_UINT16(shapeDefs + 6));
-		shapeDefs += 8;
-	}
-
-	for (int i = 0; i < 2; i++) {
-		_doorSwitches[doorIndex * 3 + i].shp = _screen->encodeShape(READ_LE_UINT16(shapeDefs), READ_LE_UINT16(shapeDefs + 2), READ_LE_UINT16(shapeDefs + 4), READ_LE_UINT16(shapeDefs + 6));
-		shapeDefs += 8;
-		_doorSwitches[doorIndex * 3 + i].x = *shapeDefs;
-		shapeDefs += 2;
-		_doorSwitches[doorIndex * 3 + i].y= *shapeDefs;
-		shapeDefs += 2;
-	}
-	_screen->_curPage = 0;
-	return shapeDefs;
-}
-
-void DarkMoonEngine::drawDoorIntern(int type, int, int x, int y, int w, int wall, int mDim, int16, int16) {
-	int shapeIndex = type * 3 + 2 - mDim;
-	uint8 *shp = _doorShapes[shapeIndex];
-	if (!shp)
-		return;
-
-	if ((_doorType[type] == 0) || (_doorType[type] == 1)) {
-		y = _dscDoorY1[mDim] - shp[1];
-		x -= (shp[2] << 2);
-
-		if (_doorType[type] == 1) {
-			drawBlockObject(0, 2, shp, x, y, 5);
-			shp = _doorShapes[3 + shapeIndex];
-		}
-
-		y -= ((wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult1[mDim]);
-
-		if (_specialWallTypes[wall] == 5)
-			y -= _dscDoorType5Offs[shapeIndex];
-
-	} else if (_doorType[type] == 2) {
-		x -= (shp[2] << 2);
-		y = _dscDoorY2[mDim] - ((wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult3[mDim]);
-	}
-
-	drawBlockObject(0, 2, shp, x, y, 5);
-
-	if (_wllShapeMap[wall] == -1 && !_noDoorSwitch[type])
-		drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
-}
-
-void DarkMoonEngine::restParty_npc() {
-	int insalId = -1;
-	int numChar = 0;
-
-	for (int i = 0; i < 6; i++) {
-		if (!testCharacter(i, 1))
-			continue;
-		if (testCharacter(i, 2) && _characters[i].portrait == -1)
-			insalId = i;
-		numChar++;
-	}
-
-	if (insalId == -1 || numChar < 5)
-		return;
-
-	removeCharacterFromParty(insalId);
-	if (insalId < 4)
-		exchangeCharacters(insalId, testCharacter(5, 1) ? 5 : 4);
-
-	clearScriptFlags(6);
-
-	if (!stripPartyItems(1, 1, 1, 1))
-		stripPartyItems(2, 1, 1, 1);
-	stripPartyItems(31, 0, 1, 3);
-	stripPartyItems(39, 1, 0, 3);
-	stripPartyItems(47, 0, 1, 2);
-
-	_items[createItemOnCurrentBlock(28)].value = 26;
-
-	gui_drawPlayField(false);
-	gui_drawAllCharPortraitsWithStats();
-
-	_screen->setClearScreenDim(10);
-	_gui->messageDialogue2(11, 63, 6);
-	_gui->messageDialogue2(11, 64, 6);
-}
-
-bool DarkMoonEngine::restParty_extraAbortCondition() {
-	if (_currentLevel != 3)
-		return false;
-
-	seq_nightmare();
-
-	return true;
-}
-
-void DarkMoonEngine::useHorn(int charIndex, int weaponSlot) {
-	int v = _items[_characters[charIndex].inventory[weaponSlot]].value - 1;
-	_txt->printMessage(_hornStrings[v]);
-	snd_playSoundEffect(_hornSounds[v]);
-}
-
-bool DarkMoonEngine::checkPartyStatusExtra() {
-	if (checkScriptFlags(0x100000))
-		seq_kheldran();
-	return _gui->confirmDialogue2(14, 67, 1);
-}
-
-void DarkMoonEngine::drawLightningColumn() {
-	int f = rollDice(1, 2, -1);
-	int y = 0;
-
-	for (int i = 0; i < 6; i++) {
-		f ^= 1;
-		drawBlockObject(f, 2, _lightningColumnShape, 72, y, 5);
-		y += 64;
-	}
-}
-
-int DarkMoonEngine::resurrectionSelectDialogue() {
-	countResurrectionCandidates();
-
-	_rrNames[_rrCount] = _abortStrings[0];
-	_rrId[_rrCount++] = 99;
-
-	int r = _rrId[runDialogue(-1, 9, _rrNames[0], _rrNames[1], _rrNames[2], _rrNames[3], _rrNames[4], _rrNames[5], _rrNames[6], _rrNames[7], _rrNames[8]) - 1];
-	if (r == 99)
-		return 0;
-
-	if (r < 0) {
-		r = -r;
-		if (prepareForNewPartyMember(33, r))
-			initNpc(r - 1);
-	} else {
-		_characters[r].hitPointsCur = 1;
-	}
-
-	return 1;
-}
-
-int DarkMoonEngine::charSelectDialogue() {
-	int cnt = 0;
-	const char *namesList[7];
-	memset(namesList, 0, 7 * sizeof(const char*));
-
-	for (int i = 0; i < 6; i++) {
-		if (!testCharacter(i, 3))
-			continue;
-		namesList[cnt++] = _characters[i].name;
-	}
-
-	namesList[cnt++] = _abortStrings[0];
-
-	int r = runDialogue(-1, 7, namesList[0], namesList[1], namesList[2], namesList[3], namesList[4], namesList[5], namesList[6]) - 1;
-	if (r == cnt - 1)
-		return 99;
-
-	for (cnt = 0; cnt < 6; cnt++) {
-		if (!testCharacter(cnt, 3))
-			continue;
-		if (--r < 0)
-			break;
-	}
-	return cnt;
-}
-
-void DarkMoonEngine::characterLevelGain(int charIndex) {
-	EobCharacter *c = &_characters[charIndex];
-	int s = _numLevelsPerClass[c->cClass];
-	for (int i = 0; i < s; i++) {
-		uint32 er = getRequiredExperience(c->cClass, i, c->level[i] + 1);
-		if (er == 0xffffffff)
-			continue;
-
-		increaseCharacterExperience(charIndex, er - c->experience[i] + 1);
-	}
-}
-
-}	// End of namespace Kyra
-
-#endif // ENABLE_EOB
diff --git a/engines/kyra/eob2.h b/engines/kyra/eob2.h
deleted file mode 100644
index 35eb90a..0000000
--- a/engines/kyra/eob2.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/* 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.
- *
- */
-
-#ifdef ENABLE_EOB
-
-#ifndef KYRA_EOB2_H
-#define KYRA_EOB2_H
-
-#include "kyra/eobcommon.h"
-
-namespace Kyra {
-
-class DarkmoonSequenceHelper;
-
-struct EobSequenceStep {
-	uint8 command;
-	uint8 obj;
-	int16 x1;
-	uint8 y1;
-	uint8 delay;
-	uint8 pal;
-	uint8 x2;
-	uint8 y2;
-	uint8 w;
-	uint8 h;
-};
-
-class DarkMoonEngine : public EobCoreEngine {
-friend class GUI_Eob;
-friend class DarkmoonSequenceHelper;
-public:
-	DarkMoonEngine(OSystem *system, const GameFlags &flags);
-	~DarkMoonEngine();
-
-private:
-	// Init / Release
-	Common::Error init();
-	void initStaticResource();
-	void initSpells();
-
-	// Main Menu
-	int mainMenu();
-	int mainMenuLoop();
-
-	int _menuChoiceInit;
-
-	// Main loop
-	void startupNew();
-	void startupLoad() {}
-
-	// Intro/Outro
-	void seq_playIntro();
-	void seq_playFinale();
-	void seq_playCredits(DarkmoonSequenceHelper *sq, const uint8 *data, int sd, int backupPage, int tempPage, int speed);
-
-	const char * const *_introStrings;
-	const char * const *_cpsFilesIntro;
-	const EobSequenceStep **_seqIntro;
-	const EobShapeDef **_shapesIntro;
-
-	const char * const *_finaleStrings;
-	const uint8 *_creditsData;
-	const char * const *_cpsFilesFinale;
-	const EobSequenceStep **_seqFinale;
-	const EobShapeDef **_shapesFinale;
-
-	static const char *_palFilesIntro[];
-	static const char *_palFilesFinale[];
-
-	// Ingame sequence
-	void seq_nightmare();
-	void seq_kheldran();
-	void seq_dranDragonTransformation();
-
-	const int8 *_dreamSteps;
-	const char *const *_kheldranStrings;
-
-	// characters
-	void drawNpcScene(int npcIndex);
-	void runNpcDialogue(int npcIndex);
-
-	const uint8 *_npcShpData;
-	const char *const *_npcStrings[2];
-
-	// items
-	void updateUsedCharacterHandItem(int charIndex, int slot);
-
-	// Monsters
-	void generateMonsterPalettes(const char *file, int16 monsterIndex);
-	void loadMonsterDecoration(const char *file, int16 monsterIndex);
-	void replaceMonster(int unit, uint16 block, int d, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem);
-	bool killMonsterExtra(EobMonsterInPlay *m);
-
-	// Level
-	const uint8 *loadDoorShapes(const char *filename, int doorIndex, const uint8 *shapeDefs);
-	void drawDoorIntern(int type, int, int x, int y, int w, int wall, int mDim, int16, int16);
-
-	const uint8 *_dscDoorType5Offs;
-
-	// Rest party
-	void restParty_npc();
-	bool restParty_extraAbortCondition();
-
-	// misc
-	void useHorn(int charIndex, int weaponSlot);
-	bool checkPartyStatusExtra();
-	void drawLightningColumn();
-	int resurrectionSelectDialogue();
-	int charSelectDialogue();
-	void characterLevelGain(int charIndex);
-
-	const char *const *_hornStrings;
-	const uint8 *_hornSounds;
-};
-
-}	// End of namespace Kyra
-
-#endif
-
-#endif // ENABLE_EOB
diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk
index 23aee52..21e3ba3 100644
--- a/engines/kyra/module.mk
+++ b/engines/kyra/module.mk
@@ -109,8 +109,8 @@ endif
 MODULE_OBJS += \
 	chargen.o \
 	eobcommon.o \
-	eob1.o \
-	eob2.o \
+	eob.o \
+	darkmoon.o \
 	gui_eob.o \
 	items_eob.o \
 	magic_eob.o \
@@ -118,8 +118,8 @@ MODULE_OBJS += \
 	scene_eob.o \
 	screen_eob.o \
 	script_eob.o \
-	sequences_eob1.o \
-	sequences_eob2.o \
+	sequences_eob.o \
+	sequences_darkmoon.o \
 	sprites_eob.o \
 	staticres_eob.o \
 	timer_eob.o
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 413bc45..072b418 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -35,7 +35,7 @@
 #include "common/archive.h"
 
 #include "kyra/kyra_v1.h"
-#include "kyra/eob2.h"
+#include "kyra/darkmoon.h"
 #include "kyra/lol.h"
 #include "kyra/kyra_hof.h"
 
diff --git a/engines/kyra/sequences_darkmoon.cpp b/engines/kyra/sequences_darkmoon.cpp
new file mode 100644
index 0000000..6b342ad
--- /dev/null
+++ b/engines/kyra/sequences_darkmoon.cpp
@@ -0,0 +1,1349 @@
+/* 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.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/darkmoon.h"
+#include "kyra/screen_eob.h"
+#include "kyra/resource.h"
+#include "kyra/sound.h"
+
+#include "common/system.h"
+
+#include "base/version.h"
+
+namespace Kyra {
+
+class DarkmoonSequenceHelper {
+friend class DarkMoonEngine;
+public:
+	enum Mode {
+		kIntro,
+		kFinale
+	};
+
+	DarkmoonSequenceHelper(OSystem *system, DarkMoonEngine *vm, Screen_Eob *screen, Mode mode, const char *const *strings, const char *const *cpsFiles, const char *const *palFiles, const EobShapeDef **shapeDefList, const EobSequenceStep **seqList);
+	~DarkmoonSequenceHelper();
+
+	void loadScene(int index, int pageNum);
+	void runSequence(int index, int del = -1);
+
+	void printText(int index, int color);
+	void fadeText();
+
+	void update(int srcPage);
+
+	void setPalette(int index);
+	void fadePalette(int index, int del);
+	void copyPalette(int srcIndex, int destIndex);
+
+	void initDelayedPaletteFade(int palIndex, int rate);
+	bool processDelayedPaletteFade();
+
+	void delay(uint32 ticks);
+	void waitForSongNotifier(int index, bool introUpdateAnim = false);
+
+private:
+	void setPaletteWithoutTextColor(int index);
+
+	OSystem *_system;
+	DarkMoonEngine *_vm;
+	Screen_Eob *_screen;
+	Mode _mode;
+
+	const char *const *_strings;
+	const char *const *_cpsFiles;
+	const char *const *_palFiles;
+	const EobShapeDef **_shapeDefs;
+	const EobSequenceStep **_seqData;
+
+	Palette *_palettes[12];
+
+	const uint8 **_shapes;
+
+	uint32 _fadePalTimer;
+	int _fadePalRate;
+	int _fadePalIndex;
+};
+
+int DarkMoonEngine::mainMenu() {
+	int menuChoice = _menuChoiceInit;
+	_menuChoiceInit = 0;
+
+	_sound->loadSoundFile("INTRO");
+	Screen::FontId of = _screen->_currentFont;
+	int op = 0;
+	Common::SeekableReadStream *s = 0;
+
+	while (menuChoice >= 0 && !shouldQuit()) {
+		switch (menuChoice) {
+			case 0:
+				s = _res->createReadStream("XENU.CPS");
+				if (s) {
+					s->read(_screen->getPalette(0).getData(), 768);
+					_screen->loadFileDataToPage(s, 3, 64000);
+					delete s;
+				} else {
+					_screen->loadBitmap("MENU.CPS", 3, 2, &_screen->getPalette(0));
+				}
+
+				_screen->setScreenPalette(_screen->getPalette(0));
+
+				of = _screen->setFont(Screen::FID_6_FNT);
+				op = _screen->setCurPage(2);
+				_screen->printText(gScummVMVersion, 267 - strlen(gScummVMVersion) * 6, 160, 13, 0);
+				_screen->setFont(of);
+				_screen->_curPage = op;
+				_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
+				_screen->updateScreen();
+				menuChoice = mainMenuLoop();
+				break;
+
+			case 1:
+				// load game in progress
+				menuChoice = -1;
+				break;
+
+			case 2:
+				// create new party
+				menuChoice = -2;
+				break;
+
+			case 3:
+				// transfer party
+				//seq_playFinale();
+				menuChoice = -3;
+				break;
+
+			case 4:
+				// play intro
+				seq_playIntro();
+				menuChoice = 0;
+				break;
+
+			case 5:
+				// quit
+				menuChoice = -5;
+				break;
+		}
+	}
+
+	return shouldQuit() ? -5 : menuChoice;
+}
+
+int DarkMoonEngine::mainMenuLoop() {
+	int sel = -1;
+	do {
+		_screen->setScreenDim(6);
+		_gui->simpleMenu_setup(6, 0, _mainMenuStrings, -1, 0, 0);
+
+		while (sel == -1 && !shouldQuit())
+			sel = _gui->simpleMenu_process(6, _mainMenuStrings, 0, -1, 0);
+	} while ((sel < 0 || sel > 5) && !shouldQuit());
+
+	return sel + 1;
+}
+
+void DarkMoonEngine::seq_playIntro() {
+	DarkmoonSequenceHelper sq(_system, this, _screen, DarkmoonSequenceHelper::kIntro, _introStrings, _cpsFilesIntro, _palFilesIntro, _shapesIntro, _seqIntro);
+
+	_screen->setCurPage(0);
+	_screen->clearCurPage();
+
+	snd_stopSound();
+
+	sq.loadScene(4, 2);
+	sq.loadScene(0, 2);
+	sq.delay(1);
+
+	if (!skipFlag() && !shouldQuit())
+		_sound->playTrack(12);
+
+	_screen->copyRegion(0, 0, 8, 8, 304, 128, 2, 0, Screen::CR_NO_P_CHECK);
+	sq.setPalette(9);
+	sq.fadePalette(0, 3);
+
+	_screen->setCurPage(2);
+	_screen->setClearScreenDim(17);
+	_screen->setCurPage(0);
+
+	removeInputTop();
+	sq.delay(18);
+
+	sq.runSequence(3, 18);
+	sq.runSequence(6, 18);
+	sq.runSequence(0);
+
+	sq.waitForSongNotifier(1);
+
+	sq.runSequence(11);
+	sq.runSequence(7, 6);
+	sq.runSequence(2, 6);
+
+	sq.waitForSongNotifier(2);
+
+	sq.runSequence(38);
+	sq.runSequence(3);
+	sq.runSequence(8);
+	sq.runSequence(1, 10);
+	sq.runSequence(0, 6);
+	sq.runSequence(2);
+
+	sq.waitForSongNotifier(3);
+
+	_screen->setClearScreenDim(17);
+	_screen->setCurPage(2);
+	_screen->setClearScreenDim(17);
+	_screen->setCurPage(0);
+
+	sq.runSequence(40);
+	sq.runSequence(7, 18);
+
+	sq.printText(0, 16);	// You were settling...
+	sq.runSequence(7, 90);
+	sq.fadeText();
+
+	sq.printText(1, 16);	// Then a note was slipped to you
+	sq.runSequence(8);
+	sq.runSequence(2, 72);
+	sq.fadeText();
+
+	sq.printText(2, 16);	// It was from your friend Khelben Blackstaff...
+	sq.runSequence(2);
+	sq.runSequence(6, 36);
+	sq.runSequence(3);
+	sq.fadeText();
+
+	sq.printText(3, 16);	// The message was urgent.
+
+	sq.loadScene(1, 2);
+	sq.waitForSongNotifier(4);
+
+	// intro scroll
+	if (!skipFlag() && !shouldQuit()) {
+		for (int i = 0; i < 280; i += 3) {
+			uint32 endtime = _system->getMillis() + _tickLength;
+			_screen->copyRegion(11, 8, 8, 8, 301, 128, 0, 0, Screen::CR_NO_P_CHECK);
+			_screen->copyRegion(i, 0, 309, 8, 3, 128, 2, 0, Screen::CR_NO_P_CHECK);
+			_screen->updateScreen();
+			if (i == 96)
+				sq.runSequence(42);
+			delayUntil(endtime);
+		}
+	}
+
+	_screen->copyRegion(8, 8, 0, 0, 304, 128, 0, 2, Screen::CR_NO_P_CHECK);
+	sq.runSequence(4);
+	sq.fadeText();
+	sq.delay(10);
+
+	sq.loadScene(2, 2);
+	sq.update(2);
+	sq.delay(10);
+
+	sq.printText(4, 16);	// What could Khelben want?
+	sq.delay(25);
+
+	sq.loadScene(3, 2);
+	sq.delay(54);
+	sq.runSequence(13);
+	_screen->copyRegion(104, 16, 96, 8, 120, 100, 0, 2, Screen::CR_NO_P_CHECK);
+	sq.fadeText();
+
+	sq.printText(5, 15);	// Welcome, please come in
+	sq.runSequence(10);
+	sq.runSequence(10);
+	sq.runSequence(9);
+	sq.runSequence(9);
+	sq.fadeText();
+
+	sq.printText(6, 15);	// Khelben awaits you in his study
+	for (int i = 0; i < 3; i++)
+		sq.runSequence(10);
+	sq.runSequence(9);
+	sq.runSequence(14);
+	sq.loadScene(5, 2);
+
+	sq.waitForSongNotifier(5);
+
+	sq.fadeText();
+	_screen->clearCurPage();
+	_screen->updateScreen();
+
+	for (int i = 0; i < 6; i++)
+		sq.runSequence(15);
+
+	sq.loadScene(6, 2);
+	sq.loadScene(7, 2);
+	_screen->clearCurPage();
+	sq.update(2);
+
+	sq.runSequence(16);
+	sq.printText(7, 15);	// Thank you for coming so quickly
+	sq.runSequence(16);
+	sq.runSequence(17);
+	for (int i = 0; i < 3; i++)
+		sq.runSequence(16);
+	sq.fadeText();
+	sq.runSequence(16);
+
+	sq.loadScene(8, 2);
+	sq.update(2);
+	sq.runSequence(32);
+	sq.printText(8, 15);	// I am troubled my friend
+	sq.runSequence(33);
+	sq.runSequence(33);
+	for (int i = 0; i < 4; i++)
+		sq.runSequence(32);
+	sq.fadeText();
+
+	sq.printText(9, 15);	// Ancient evil stirs in the Temple Darkmoon
+	sq.runSequence(33);
+	sq.runSequence(43);
+	sq.runSequence(33);
+	for (int i = 0; i < 3; i++)
+		sq.runSequence(32);
+	sq.fadeText();
+
+	sq.printText(10, 15);	// I fear for the safety of our city
+	for (int i = 0; i < 4; i++)
+		sq.runSequence(33);
+	sq.runSequence(32);
+	sq.runSequence(32);
+
+	sq.loadScene(9, 2);
+	sq.fadeText();
+
+	sq.waitForSongNotifier(6);
+
+	sq.update(2);
+	sq.runSequence(34);
+
+	sq.printText(11, 15);	// I need your help
+	for (int i = 0; i < 3; i++)
+		sq.runSequence(34);
+	sq.runSequence(35);
+	for (int i = 0; i < 4; i++)
+		sq.runSequence(34);
+	sq.fadeText();
+
+	sq.loadScene(12, 2);
+	sq.update(2);
+	sq.loadScene(6, 2);
+	sq.runSequence(18);
+
+	sq.printText(12, 15);	// Three nights ago I sent forth a scout
+	sq.runSequence(19);
+	sq.runSequence(20);
+	sq.runSequence(22);
+	sq.runSequence(19);
+	sq.runSequence(20);
+	sq.runSequence(18);
+	sq.fadeText();
+
+	sq.printText(13, 15);	// She has not yet returned
+	sq.runSequence(20);
+	sq.runSequence(19);
+	sq.runSequence(23);
+	sq.runSequence(24);
+	sq.runSequence(20);
+	sq.runSequence(19);
+	sq.runSequence(17);
+	sq.runSequence(18);
+	sq.fadeText();
+
+	sq.printText(14, 15);	// I fear for her safety
+	sq.runSequence(19);
+	sq.runSequence(20);
+	sq.runSequence(20);
+	sq.runSequence(18);
+	sq.runSequence(25);
+	sq.runSequence(18);
+	sq.runSequence(18);
+	sq.fadeText();
+	sq.runSequence(18);
+	sq.runSequence(18);
+
+	sq.printText(15, 15);	// Take this coin
+	sq.runSequence(28);
+	sq.runSequence(19);
+	sq.runSequence(20);
+	sq.runSequence(18);
+	sq.runSequence(18);
+	sq.fadeText();
+
+	sq.loadScene(10, 2);
+	_screen->clearCurPage();
+	_screen->updateScreen();
+
+	sq.runSequence(37, 18);
+	sq.runSequence(36, 36);
+
+	sq.loadScene(12, 2);
+	_screen->clearCurPage();
+	sq.update(2);
+
+	sq.loadScene(11, 2);
+	sq.printText(16, 15);	// I will use it to contact you
+	sq.runSequence(19);
+	sq.runSequence(20);
+	sq.runSequence(20);
+	sq.runSequence(18);
+	sq.runSequence(18);
+	sq.fadeText();
+
+	sq.printText(17, 15);	// You must act quickly
+	sq.runSequence(19);
+	sq.runSequence(20);
+	sq.runSequence(19);
+	sq.runSequence(18);
+	sq.runSequence(18);
+	sq.fadeText();
+	sq.runSequence(18);
+
+	sq.printText(18, 15);	// I will teleport you near Darkmoon
+	sq.runSequence(20);
+	sq.runSequence(27);
+	sq.runSequence(20);
+	sq.runSequence(19);
+	sq.runSequence(18);
+	sq.runSequence(18);
+	sq.fadeText();
+	sq.runSequence(18);
+
+	sq.printText(19, 15);	// May luck be with you my friend
+	sq.runSequence(19);
+	sq.runSequence(19);
+	sq.runSequence(20);
+	sq.runSequence(18);
+	sq.fadeText();
+	sq.runSequence(29);
+
+	sq.waitForSongNotifier(7);
+
+	sq.runSequence(30);
+	sq.runSequence(31);
+
+	sq.waitForSongNotifier(8, true);
+
+	if (skipFlag() || shouldQuit()) {
+		_sound->playTrack(15);
+	} else {
+		_screen->setScreenDim(17);
+		_screen->clearCurDim();
+		_sound->playTrack(14);
+		sq.fadePalette(10, 1);
+		_screen->setClearScreenDim(18);
+		sq.delay(6);
+		sq.fadePalette(9, 1);
+		_screen->clearCurPage();
+	}
+
+	sq.fadePalette(9, 10);
+}
+
+void DarkMoonEngine::seq_playFinale() {
+	DarkmoonSequenceHelper sq(_system, this, _screen, DarkmoonSequenceHelper::kFinale, _finaleStrings, _cpsFilesFinale, _palFilesFinale, _shapesFinale, _seqFinale);
+
+	_screen->setCurPage(0);
+	_screen->setFont(Screen::FID_8_FNT);
+
+	_sound->loadSoundFile("FINALE1");
+	snd_stopSound();
+	sq.delay(3);
+
+	_screen->clearCurPage();
+	_screen->updateScreen();
+
+	sq.loadScene(0, 2);
+	sq.delay(18);
+
+	if (!skipFlag() && !shouldQuit())
+		_sound->playTrack(1);
+	sq.update(2);
+
+	sq.loadScene(1, 2);
+
+	sq.runSequence(0);
+	sq.runSequence(0);
+	for (int i = 0; i < 3; i++)
+		sq.runSequence(2);
+	sq.runSequence(1);
+	sq.runSequence(2);
+	sq.runSequence(2);
+
+	sq.printText(0, 10);			// Finally, Dran has been defeated
+	for (int i = 0; i < 7; i++)
+		sq.runSequence(2);
+	sq.fadeText();
+	sq.runSequence(2);
+
+	sq.waitForSongNotifier(1);
+
+	sq.printText(1, 10);			// Suddenly, your friend Khelben appears
+	sq.runSequence(4);
+	for (int i = 0; i < 3; i++)
+		sq.runSequence(2);
+	sq.fadeText();
+
+	sq.printText(2, 15);			// Greetings, my victorious friends
+	for (int i = 0; i < 4; i++)
+		sq.runSequence(5);
+	sq.runSequence(2);
+	sq.runSequence(2);
+	sq.fadeText();
+	sq.runSequence(6);
+
+	sq.printText(3, 15);			// You have defeated Dran
+	for (int i = 0; i < 5; i++)
+		sq.runSequence(5);
+	sq.runSequence(2);
+	sq.runSequence(2);
+	sq.fadeText();
+
+	sq.printText(4, 15);			// I did not know Dran was a dragon
+	for (int i = 0; i < 4; i++)
+		sq.runSequence(5);
+	sq.runSequence(2);
+	sq.runSequence(2);
+	sq.fadeText();
+
+	sq.printText(5, 15);			// He must have been over 300 years old
+	for (int i = 0; i < 4; i++)
+		sq.runSequence(5);
+	sq.runSequence(2);
+	sq.runSequence(2);
+	sq.fadeText();
+
+	sq.printText(6, 15);			// His power is gone
+	for (int i = 0; i < 3; i++)
+		sq.runSequence(5);
+	sq.runSequence(2);
+	sq.runSequence(2);
+	sq.fadeText();
+
+	sq.printText(7, 15);			// But Darkmoon is still a source of great evil
+	for (int i = 0; i < 4; i++)
+		sq.runSequence(5);
+	sq.runSequence(2);
+	sq.runSequence(2);
+	sq.fadeText();
+
+	sq.printText(8, 15);			// And many of his minions remain
+	for (int i = 0; i < 4; i++)
+		sq.runSequence(5);
+	sq.runSequence(2);
+	sq.runSequence(2);
+	sq.fadeText();
+
+	sq.loadScene(2, 2);
+	sq.update(2);
+	sq.loadScene(3, 2);
+	_screen->copyRegion(8, 8, 0, 0, 304, 128, 0, 2, Screen::CR_NO_P_CHECK);
+
+	sq.printText(9, 15);			// Now we must leave this place
+	sq.runSequence(7);
+	sq.runSequence(8);
+	sq.runSequence(7);
+	sq.runSequence(7, 36);
+	sq.fadeText();
+
+	sq.printText(10, 15);			// So my forces can destroy it..
+	for (int i = 0; i < 3; i++)
+		sq.runSequence(7);
+	sq.runSequence(8);
+	sq.runSequence(7);
+	sq.runSequence(7, 36);
+	sq.runSequence(8, 18);
+	sq.fadeText();
+
+	sq.printText(11, 15);			// Follow me
+	sq.runSequence(7, 18);
+	sq.runSequence(9, 18);
+	sq.runSequence(8, 18);
+	sq.fadeText();
+
+	sq.loadScene(7, 2);
+	sq.copyPalette(3, 0);
+	sq.loadScene(4, 2);
+
+	sq.waitForSongNotifier(2);
+
+	_screen->clearCurPage();
+	sq.update(2);
+
+	sq.loadScene(8, 2);
+	sq.loadScene(6, 6);
+	sq.delay(10);
+
+	sq.printText(12, 10);			// Powerful mages stand ready for the final assault...
+	sq.delay(90);
+	sq.fadeText();
+
+	sq.waitForSongNotifier(3);
+
+	if (!skipFlag() && !shouldQuit())
+		_sound->playTrack(7);
+	sq.delay(8);
+
+	sq.runSequence(10);
+	sq.runSequence(13);
+	sq.initDelayedPaletteFade(4, 1);
+
+	sq.runSequence(14);
+	sq.runSequence(13);
+	sq.runSequence(14);
+	sq.runSequence(14);
+	sq.runSequence(13);
+	sq.initDelayedPaletteFade(2, 1);
+
+	sq.runSequence(15);
+	sq.runSequence(14);
+	sq.runSequence(13);
+	sq.runSequence(15);
+	sq.runSequence(15);
+	sq.runSequence(11);
+
+	sq.printText(13, 10);			// The temple's evil is very strong
+	sq.delay(72);
+	sq.fadeText();
+
+	sq.printText(14, 10);			// It must not be allowed...
+	sq.delay(72);
+	sq.fadeText();
+
+	sq.waitForSongNotifier(4);
+
+	if (!skipFlag() && !shouldQuit())
+		_sound->playTrack(7);
+	sq.delay(8);
+
+	sq.runSequence(10);
+	sq.initDelayedPaletteFade(5, 1);
+	sq.runSequence(13);
+	sq.runSequence(14);
+	sq.runSequence(13);
+	sq.runSequence(14);
+	sq.runSequence(13);
+	sq.runSequence(13);
+	sq.runSequence(14);
+	sq.runSequence(14);
+	sq.runSequence(13);
+	sq.runSequence(12);
+	for (int i = 0; i < 4; i++)
+		sq.runSequence(16);
+	sq.runSequence(17);
+	sq.runSequence(18);
+
+	sq.printText(15, 10);			// The temple ceases to exist
+	sq.initDelayedPaletteFade(6, 1);
+	sq.delay(36);
+
+	if (!skipFlag() && !shouldQuit())
+		_sound->playTrack(11);
+
+	sq.delay(54);
+	sq.fadeText();
+	sq.loadScene(12, 2);
+
+	sq.waitForSongNotifier(5);
+
+	if (!skipFlag() && !shouldQuit())
+		_sound->playTrack(6);
+
+	if (!skipFlag() && !shouldQuit())
+		_screen->crossFadeRegion(0, 0, 8, 8, 304, 128, 2, 0);
+	sq.delay(18);
+
+	sq.printText(16, 15);			// My friends, our work is done
+	sq.runSequence(20);
+	sq.runSequence(19);
+	sq.runSequence(19, 36);
+	if (!skipFlag() && !shouldQuit())
+		_sound->playTrack(12);
+	sq.fadeText();
+
+	sq.printText(17, 15);			// Thank you
+	sq.runSequence(19);
+	sq.runSequence(20, 36);
+	sq.fadeText();
+
+	sq.printText(18, 15);			// You have earned my deepest respect
+	if (!skipFlag() && !shouldQuit())
+		_sound->playTrack(11);
+	sq.runSequence(20);
+	sq.runSequence(19);
+	sq.runSequence(19);
+	if (!skipFlag() && !shouldQuit())
+		_sound->playTrack(11);
+	sq.delay(36);
+	sq.fadeText();
+
+	sq.printText(19, 15);			// We will remember you always
+	sq.runSequence(19);
+	sq.runSequence(19, 18);
+	if (!skipFlag() && !shouldQuit())
+		_sound->playTrack(11);
+	sq.runSequence(20, 18);
+	sq.fadeText();
+
+	sq.delay(28);
+	if (!skipFlag() && !shouldQuit())
+		_sound->playTrack(12);
+	sq.delay(3);
+
+	sq.loadScene(5, 2);
+	if (skipFlag() || shouldQuit()) {
+		_screen->copyRegion(0, 0, 8, 8, 304, 128, 2, 0, Screen::CR_NO_P_CHECK);
+	} else {
+		_sound->playTrack(6);
+		_screen->crossFadeRegion(0, 0, 8, 8, 304, 128, 2, 0);
+	}
+
+	if (!skipFlag() && !shouldQuit())
+		_sound->playTrack(12);
+	sq.delay(5);
+	if (!skipFlag() && !shouldQuit())
+		_sound->playTrack(11);
+	sq.delay(11);
+	if (!skipFlag() && !shouldQuit())
+		_sound->playTrack(12);
+	sq.delay(7);
+	if (!skipFlag() && !shouldQuit())
+		_sound->playTrack(11);
+	sq.delay(12);
+	if (!skipFlag() && !shouldQuit())
+		_sound->playTrack(12);
+
+	removeInputTop();
+	resetSkipFlag(true);
+
+	sq.loadScene(10, 2);
+	sq.loadScene(9, 2);
+	snd_stopSound();
+	sq.delay(3);
+
+	_sound->loadSoundFile("FINALE2");
+
+	sq.delay(18);
+	if (!skipFlag() && !shouldQuit())
+		_sound->playTrack(1);
+
+	seq_playCredits(&sq, _creditsData, 18, 2, 6, 2);
+
+	sq.delay(90);
+
+	resetSkipFlag(true);
+
+	sq.setPalette(11);
+	sq.fadePalette(9, 10);
+
+	_screen->clearCurPage();
+	sq.loadScene(11, 2);
+
+	static const uint8 finPortraitPos[] = { 0x50, 0x50, 0xD0, 0x50, 0x50, 0x90, 0xD0, 0x90, 0x90, 0x50, 0x90, 0x90 };
+
+	for (int i = 0; i < 6; i++) {
+		if (!testCharacter(i, 1))
+			continue;
+		if (i > 3)
+			_screen->drawShape(2, sq._shapes[6 + i], finPortraitPos[i << 1] - 16, finPortraitPos[(i << 1) + 1] - 16, 0);
+		_screen->drawShape(2, _characters[i].faceShape, finPortraitPos[i << 1], finPortraitPos[(i << 1) + 1], 0);
+	}
+
+	_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
+
+	sq.setPalette(9);
+	sq.fadePalette(0, 18);
+
+	while (!skipFlag() && !shouldQuit())
+		delay(_tickLength);
+
+	snd_stopSound();
+	sq.fadePalette(9, 10);
+}
+
+void DarkMoonEngine::seq_playCredits(DarkmoonSequenceHelper *sq, const uint8 *data, int sd, int backupPage, int tempPage, int speed) {
+	if (!data)
+		return;
+
+	_screen->setScreenDim(sd);
+	const ScreenDim *dm = _screen->_curDim;
+
+	_screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 0, backupPage, Screen::CR_NO_P_CHECK);
+
+	struct CreditsDataItem {
+		int16 x;
+		int16 y;
+		const void *data;
+		char *str;
+		uint8 crlf;
+		uint8 size;
+		uint8 dataType;
+	} items[36];
+	memset(items, 0, sizeof(items));
+
+	const char *pos = (const char *)data;
+	uint32 end = _system->getMillis();
+	uint32 cur = 0;
+	int i = 0;
+
+	do {
+		for (bool loop = true; loop; ) {
+			sq->processDelayedPaletteFade();
+			cur = _system->getMillis();
+			if (end <= cur)
+				break;
+			delay(MIN<uint32>(_tickLength, end - cur));
+		}
+
+		end = _system->getMillis() + speed * _tickLength;
+
+		for (; i < 35 && *pos; i++) {
+			int16 nextY = i ? items[i].y + items[i].size + (items[i].size >> 2) : dm->h;
+
+			const char *posOld = pos;
+			pos = strchr(pos, 0x0d);
+			if (!pos)
+				pos = strchr(posOld, 0x00);
+
+			items[i + 1].crlf = *pos++;
+
+			if (*posOld == 2) {
+				const uint8 *shp = sq->_shapes[(*++posOld) - 1];
+				items[i + 1].data = shp;
+				items[i + 1].size = shp[1];
+				items[i + 1].x = (dm->w - shp[2]) << 2 ;
+				items[i + 1].dataType = 1;
+				delete[] items[i + 1].str;
+				items[i + 1].str = 0;
+
+			} else {
+				if (*posOld == 1) {
+					posOld++;
+					items[i + 1].size = 6;
+				} else {
+					items[i + 1].size = _screen->getFontWidth();
+				}
+
+				items[i + 1].dataType = 0;
+
+				int l = pos - posOld;
+				if (items[i + 1].crlf != 0x0d)
+					l++;
+
+				delete[] items[i + 1].str;
+				items[i + 1].str = new char[l];
+				memcpy(items[i + 1].str, posOld, l);
+				items[i + 1].str[l - 1] = 0;
+				items[i + 1].data = 0;
+				items[i + 1].x = (((dm->w << 3) - (strlen(items[i + 1].str) * items[i + 1].size)) >> 1) + 1;
+			}
+
+			items[i + 1].y = nextY;
+		}
+
+		_screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, backupPage, tempPage, Screen::CR_NO_P_CHECK);
+
+		for (int h = 0; h < i; h++) {
+			if (items[h + 1].y < dm->h) {
+				if (items[h + 1].dataType == 1) {
+					_screen->drawShape(tempPage, (const uint8*)items[h + 1].data, items[h + 1].x, items[h + 1].y, sd);
+				} else {
+					_screen->setCurPage(tempPage);
+
+					if (items[h + 1].size == 6)
+						_screen->setFont(Screen::FID_6_FNT);
+
+					_screen->printText(items[h + 1].str, (dm->sx << 3) + items[h + 1].x - 1, dm->sy + items[h + 1].y + 1, 12, 0);
+					_screen->printText(items[h + 1].str, (dm->sx << 3) + items[h + 1].x, dm->sy + items[h + 1].y, 240, 0);
+
+					if (items[h + 1].size == 6)
+						_screen->setFont(Screen::FID_8_FNT);
+
+					_screen->setCurPage(0);
+				}
+			}
+
+			items[h + 1].y -= 2;
+		}
+
+		_screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, tempPage, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+
+		if (-items[1].size > items[1].y) {
+			delete[] items[1].str;
+			--i;
+			for (int t = 1; t <= i; t++)
+				memcpy(&items[t], &items[t + 1], sizeof(CreditsDataItem));
+			items[i + 1].str = 0;
+		}
+
+		if (i < 35 && ((items[i].y + items[i].size) < (dm->sy + dm->h))) {
+			resetSkipFlag(true);
+			break;
+		}
+
+		sq->processDelayedPaletteFade();
+	} while (!skipFlag() && i && !shouldQuit());
+
+	for (i = 0; i < 35; i++)
+		delete[] items[i].str;
+}
+
+DarkmoonSequenceHelper::DarkmoonSequenceHelper(OSystem *system, DarkMoonEngine *vm, Screen_Eob *screen, Mode mode, const char *const *strings, const char *const *cpsFiles, const char *const *palFiles, const EobShapeDef **shapeDefList, const EobSequenceStep **seqList) :
+	_system(system), _vm(vm), _screen(screen), _mode(mode), _strings(strings), _cpsFiles(cpsFiles), _palFiles(palFiles), _shapeDefs(shapeDefList), _seqData(seqList) {
+
+	for (int i = 0; _palFiles[i]; i++) {
+		if (i < 4)
+			_palettes[i] = &_screen->getPalette(i);
+		else
+			_palettes[i] = new Palette(256);
+		_screen->loadPalette(_palFiles[i], *_palettes[i]);
+	}
+
+	_palettes[9] = new Palette(256);
+	_palettes[9]->fill(0, 256, 0);
+	_palettes[10] = new Palette(256);
+	_palettes[10]->fill(0, 256, 63);
+	_palettes[11] = new Palette(256);
+	_palettes[11]->fill(0, 256, 0);
+
+	_shapes = new const uint8*[30];
+	memset(_shapes, 0, 30 * sizeof(uint8*));
+
+	_fadePalTimer = 0;
+	_fadePalRate = 0;
+
+	_screen->setScreenPalette(*_palettes[0]);
+	_screen->setFont(Screen::FID_8_FNT);
+	_screen->hideMouse();
+
+	_vm->delay(150);
+	_vm->_eventList.clear();
+	_vm->_allowSkip = true;
+}
+
+DarkmoonSequenceHelper::~DarkmoonSequenceHelper() {
+	for (int i = 4; _palFiles[i]; i++)
+		delete _palettes[i];
+	delete _palettes[9];
+	delete _palettes[10];
+	delete _palettes[11];
+
+	for (int i = 0; i < 30; i++)
+		delete[] _shapes[i];
+	delete[] _shapes;
+
+	_screen->clearCurPage();
+	_screen->showMouse();
+	_screen->updateScreen();
+
+	_system->delayMillis(150);
+	_vm->resetSkipFlag(true);
+	_vm->_allowSkip = false;
+}
+
+void DarkmoonSequenceHelper::loadScene(int index, int pageNum) {
+	char file[13];
+	strcpy(file, _cpsFiles[index]);
+
+	Common::SeekableReadStream *s = _vm->resource()->createReadStream(file);
+	if (s && file[0] != 'X') {
+		delete s;
+		_screen->loadBitmap(_cpsFiles[index], pageNum | 1, pageNum | 1, _palettes[0]);
+	} else {
+		if (!s) {
+			file[0] = 'X';
+			s = _vm->resource()->createReadStream(file);
+		}
+
+		if (!s)
+			error("DarkmoonSequenceHelper::loadScene(): CPS file loading failure in scene %d", index);
+
+		if (_mode == kFinale)
+			s->read(_palettes[0]->getData(), 768);
+		else
+			s->seek(768);
+		_screen->loadFileDataToPage(s, 3, 64000);
+		delete s;
+	}
+
+	int cp = _screen->setCurPage(pageNum);
+
+	if (_shapeDefs[index]) {
+		for (const EobShapeDef *df = _shapeDefs[index]; df->w; df++ ) {
+			uint16 shapeIndex = (df->index < 0) ? df->index * -1 : df->index;
+			if (_shapes[shapeIndex])
+				delete[] _shapes[shapeIndex];
+			_shapes[shapeIndex] = _screen->encodeShape(df->x, df->y, df->w, df->h, (df->index >> 8) != 0);
+		}
+	}
+
+	_screen->setCurPage(cp);
+	_screen->copyPage(pageNum | 1, pageNum);
+
+	if ((pageNum == 0 || pageNum == 1) && !_vm->skipFlag() && !_vm->shouldQuit())
+		_screen->updateScreen();
+}
+
+void DarkmoonSequenceHelper::runSequence(int index, int del) {
+	if (_vm->skipFlag() || _vm->shouldQuit())
+		return;
+
+	uint32 end = 0;
+
+	for (const EobSequenceStep *s = _seqData[index]; s->command != 0xff && !_vm->skipFlag() && !_vm->shouldQuit(); s++) {
+		int palIndex = _mode == kFinale ? (s->pal + 1) : s->pal;
+		int x = s->x1;
+		int y = s->y1;
+		int x2 = 0;
+		uint16 shapeW = 0;
+		uint16 shapeH = 0;
+
+		switch(s->command) {
+		case 0:
+			// flash palette
+			if (s->pal)
+				setPaletteWithoutTextColor(palIndex);
+			delay(s->delay);
+			if (_mode == kIntro && s->pal)
+				setPaletteWithoutTextColor(0);
+			break;
+
+		case 1:
+			// draw shape, then restore background
+			shapeW = _shapes[s->obj][2];
+			shapeH = _shapes[s->obj][3];
+
+			if (_mode == kFinale) {
+				_screen->setScreenDim(18);
+				x -= (_screen->_curDim->sx << 3);
+				y -= _screen->_curDim->sy;
+				if (x < 0)
+					shapeW -= ((-x >> 3) + 1);
+				else
+					x2 = x;
+			}
+
+			_screen->drawShape(0, _shapes[s->obj], x, y, _mode == kIntro ? 0 : 18);
+
+			if (s->pal)
+				setPaletteWithoutTextColor(palIndex);
+			else
+				_screen->updateScreen();
+
+			delay(s->delay);
+
+			if (_mode == kIntro) {
+				if (s->pal)
+					setPaletteWithoutTextColor(0);
+				_screen->copyRegion(x - 8, y - 8, x, y, (shapeW + 1) << 3, shapeH, 2, 0, Screen::CR_NO_P_CHECK);
+			} else {
+				_screen->copyRegion(x2, y, x2 + (_screen->_curDim->sx << 3), y + _screen->_curDim->sy, (shapeW + 1) << 3, shapeH, 2, 0, Screen::CR_NO_P_CHECK);
+			}
+
+			_screen->updateScreen();
+			break;
+
+		case 2:
+			// draw shape
+			_screen->drawShape(_screen->_curPage, _shapes[s->obj], x, y, 0);
+
+			if (s->pal)
+				setPaletteWithoutTextColor(palIndex);
+			else if(!_screen->_curPage)
+				_screen->updateScreen();
+
+			delay(s->delay);
+
+			if (_mode == kIntro && s->pal)
+				setPaletteWithoutTextColor(0);
+			break;
+
+		case 3:
+		case 4:
+			// fade shape in or out or restore background
+			if (_mode == kFinale)
+				break;
+
+			_screen->setShapeFadeMode(0, true);
+			_screen->setShapeFadeMode(1, true);
+
+			end = _system->getMillis() + s->delay * _vm->tickLength();
+
+			if (palIndex) {
+				_screen->setFadeTableIndex(palIndex - 1);
+
+				_screen->copyRegion(s->x1 - 8, s->y1 - 8, 0, 0, (_shapes[s->obj][2] + 1) << 3, _shapes[s->obj][3], 2, 4, Screen::CR_NO_P_CHECK);
+				_screen->drawShape(4, _shapes[s->obj], s->x1 & 7, 0, 0);
+				_screen->copyRegion(0, 0, s->x1, s->y1, (_shapes[s->obj][2] + 1) << 3, _shapes[s->obj][3], 4, 0, Screen::CR_NO_P_CHECK);
+			} else {
+				_screen->copyRegion(s->x1 - 8, s->y1 - 8, s->x1, s->y1, (_shapes[s->obj][2] + 1) << 3, _shapes[s->obj][3], 2, 0, Screen::CR_NO_P_CHECK);
+			}
+			_screen->updateScreen();
+
+			_vm->delayUntil(end);
+			_screen->setShapeFadeMode(0, false);
+			_screen->setShapeFadeMode(1, false);
+			break;
+
+		case 5:
+			// copy region
+			if (_mode == kFinale && s->pal)
+				setPaletteWithoutTextColor(palIndex);
+
+			_screen->copyRegion(s->x2 << 3, s->y2, s->x1, s->y1, s->w << 3, s->h, (s->obj && _mode == kFinale) ? 6 : 2, 0, Screen::CR_NO_P_CHECK);
+			_screen->updateScreen();
+			delay(s->delay);
+			break;
+
+		case 6:
+			// play sound effect
+			if (s->obj != 0xff)
+				_vm->sound()->playSoundEffect(s->obj);
+			break;
+
+		default:
+			error("DarkmoonSequenceHelper::runSequence(): Unknown animation opcode encountered.");
+			break;
+		}
+	}
+
+	if (del > 0)
+		delay(del);
+}
+
+void DarkmoonSequenceHelper::printText(int index, int color) {
+	if (_vm->skipFlag() || _vm->shouldQuit())
+		return;
+
+	_screen->setClearScreenDim(17);
+	_palettes[0]->copy(*_palettes[0], color, 1, 255);
+	setPalette(0);
+
+	char *temp = new char[strlen(_strings[index]) + 1];
+	char *str = temp;
+	strcpy(str, _strings[index]);
+
+	const ScreenDim *dm = _screen->_curDim;
+
+	for (int yOffs = 0; *str; yOffs += 9) {
+		char *cr = strchr(str, 13);
+
+		if (cr)
+			*cr = 0;
+
+		uint32 len = strlen(str);
+		_screen->printText(str, (dm->sx + ((dm->w - len) >> 1)) << 3, dm->sy + yOffs, 255, dm->unkA);
+
+		if (cr) {
+			*cr = 13;
+			str = cr + 1;
+		} else {
+			str += len;
+		}
+	}
+
+	delete[] temp;
+	_screen->updateScreen();
+}
+
+void DarkmoonSequenceHelper::fadeText() {
+	if (_vm->skipFlag() || _vm->shouldQuit())
+		return;
+
+	_screen->fadeTextColor(_palettes[0], 255, 2);
+	_screen->clearCurDim();
+}
+
+void DarkmoonSequenceHelper::update(int srcPage) {
+	if (_vm->skipFlag() || _vm->shouldQuit())
+		return;
+
+	_screen->copyRegion(0, 0, 8, 8, 304, 128, srcPage, 0, Screen::CR_NO_P_CHECK);
+	setPaletteWithoutTextColor(0);
+}
+
+void DarkmoonSequenceHelper::setPaletteWithoutTextColor(int index) {
+	if (_vm->skipFlag() || _vm->shouldQuit())
+		return;
+
+	if (!memcmp(_palettes[11]->getData(), _palettes[index]->getData(), 765))
+		return;
+
+	_palettes[11]->copy(*_palettes[index], 0, 255);
+	_palettes[11]->copy(*_palettes[0], 255, 1, 255);
+	setPalette(11);
+
+	_screen->updateScreen();
+}
+
+void DarkmoonSequenceHelper::setPalette(int index) {
+	_screen->setScreenPalette(*_palettes[index]);
+}
+
+void DarkmoonSequenceHelper::fadePalette(int index, int del) {
+	if (_vm->skipFlag() || _vm->shouldQuit())
+		return;
+
+	_screen->fadePalette(*_palettes[index], del * _vm->tickLength());
+}
+
+void DarkmoonSequenceHelper::copyPalette(int srcIndex, int destIndex) {
+	_palettes[destIndex]->copy(*_palettes[srcIndex]);
+}
+
+void DarkmoonSequenceHelper::initDelayedPaletteFade(int palIndex, int rate) {
+	_palettes[11]->copy(*_palettes[0]);
+
+	_fadePalIndex = palIndex;
+	_fadePalRate = rate;
+	_fadePalTimer = _system->getMillis() + 2 * _vm->_tickLength;
+}
+
+bool DarkmoonSequenceHelper::processDelayedPaletteFade() {
+	if (_vm->skipFlag() || _vm->shouldQuit())
+		return true;
+
+	if (!_fadePalRate || (_system->getMillis() <= _fadePalTimer))
+		return false;
+
+	if (_screen->delayedFadePalStep(_palettes[_fadePalIndex], _palettes[0], _fadePalRate)) {
+		setPaletteWithoutTextColor(0);
+		_fadePalTimer = _system->getMillis() + 3 * _vm->_tickLength;
+	} else {
+		_fadePalRate = 0;
+	}
+
+	return false;
+}
+
+void DarkmoonSequenceHelper::delay(uint32 ticks) {
+	if (_vm->skipFlag() || _vm->shouldQuit())
+		return;
+
+	uint32 end = _system->getMillis() + ticks * _vm->_tickLength;
+
+	if (_mode == kFinale) {
+		do {
+			if (processDelayedPaletteFade())
+				break;
+			_vm->updateInput();
+		} while (end > _system->getMillis());
+		processDelayedPaletteFade();
+
+	} else {
+		_vm->delayUntil(end);
+	}
+}
+
+void DarkmoonSequenceHelper::waitForSongNotifier(int index, bool introUpdateAnim) {
+	int seq = 0;
+	while (_vm->sound()->checkTrigger() < index && !(_vm->skipFlag() || _vm->shouldQuit())) {
+		if (introUpdateAnim) {
+			runSequence(30 | seq);
+			seq ^= 1;
+		}
+
+		if (_mode == kFinale)
+			processDelayedPaletteFade();
+
+		_vm->updateInput();
+	}
+}
+
+void DarkMoonEngine::seq_nightmare() {
+	Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+	_screen->copyRegion(0, 0, 0, 120, 176, 24, 12, 2, Screen::CR_NO_P_CHECK);
+
+	initDialogueSequence();
+	gui_drawDialogueBox();
+
+	_txt->printDialogueText(99, 0);
+	snd_playSoundEffect(54);
+
+	static const uint8 seqX[] = { 0, 20, 0, 20 };
+	static const uint8 seqY[] = { 0, 0, 96, 96 };
+	static const uint8 seqDelay[] = { 12, 7, 7, 12 };
+
+	for (const int8 *i = _dreamSteps; *i != -1; ++i) {
+		drawSequenceBitmap("DREAM", 0, seqX[*i], seqY[*i], 0);
+		delay(seqDelay[*i] * _tickLength);
+	}
+
+	_txt->printDialogueText(20, _okStrings[0]);
+
+	restoreAfterDialogueSequence();
+
+	_screen->setFont(of);
+}
+
+void DarkMoonEngine::seq_kheldran() {
+	Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+
+	initDialogueSequence();
+	gui_drawDialogueBox();
+
+	static const char file[] = "KHELDRAN";
+	_txt->printDialogueText(_kheldranStrings[0]);
+	drawSequenceBitmap(file, 0, 0, 0, 0);
+	_txt->printDialogueText(20, _moreStrings[0]);
+	snd_playSoundEffect(56);
+	drawSequenceBitmap(file, 0, 20, 0, 0);
+	delay(10 * _tickLength);
+	drawSequenceBitmap(file, 0, 0, 96, 0);
+	delay(10 * _tickLength);
+	drawSequenceBitmap(file, 0, 20, 96, 0);
+	delay(7 * _tickLength);
+	_txt->printDialogueText(76, _okStrings[0]);
+
+	restoreAfterDialogueSequence();
+
+	_screen->setFont(of);
+}
+
+void DarkMoonEngine::seq_dranDragonTransformation() {
+	Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+
+	initDialogueSequence();
+	gui_drawDialogueBox();
+
+	static const char file[] = "DRANX";
+	drawSequenceBitmap(file, 0, 0, 0, 0);
+	_txt->printDialogueText(120, _moreStrings[0]);
+	snd_playSoundEffect(56);
+	drawSequenceBitmap(file, 0, 20, 0, 0);
+	delay(7 * _tickLength);
+	drawSequenceBitmap(file, 0, 0, 96, 0);
+	delay(7 * _tickLength);
+	drawSequenceBitmap(file, 0, 20, 96, 0);
+	delay(18 * _tickLength);
+
+	restoreAfterDialogueSequence();
+
+	_screen->setFont(of);
+}
+
+}	// End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/sequences_eob.cpp b/engines/kyra/sequences_eob.cpp
new file mode 100644
index 0000000..e8526f2
--- /dev/null
+++ b/engines/kyra/sequences_eob.cpp
@@ -0,0 +1,1071 @@
+/* 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.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/eob.h"
+#include "kyra/screen_eob.h"
+#include "kyra/resource.h"
+#include "kyra/sound.h"
+
+#include "common/system.h"
+
+#include "base/version.h"
+
+namespace Kyra {
+
+int EobEngine::mainMenu() {
+	int menuChoice = _menuChoiceInit;
+	_menuChoiceInit = 0;
+
+	Screen::FontId of = _screen->_currentFont;
+
+	while (menuChoice >= 0 && !shouldQuit()) {
+		switch (menuChoice) {
+			case 0:
+				_screen->loadPalette("EOBPAL.COL", _screen->getPalette(0));
+				_screen->loadEobBitmap("INTRO", 0, 5, 3, 2);
+				_screen->setScreenPalette(_screen->getPalette(0));
+				_screen->_curPage = 2;
+				of = _screen->setFont(Screen::FID_6_FNT);
+				_screen->printText(gScummVMVersion, 280 - strlen(gScummVMVersion) * 6, 153, _screen->getPagePixel(2, 0, 0), 0);
+				_screen->setFont(of);
+				_screen->fillRect(0, 159, 319, 199, _screen->getPagePixel(2, 0, 0));
+				gui_drawBox(77, 165, 173, 29, 13, 14, 12);
+				gui_drawBox(76, 164, 175, 31, 13, 14, -1);
+				_screen->_curPage = 0;
+				_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
+				_screen->updateScreen();
+				menuChoice = mainMenuLoop();
+				break;
+
+			case 1:
+				// load game in progress
+				//
+				menuChoice = -1;
+				break;
+
+			case 2:
+				// create new party
+				menuChoice = -2;
+				break;
+
+			case 3:
+				// quit
+				menuChoice = -5;
+				break;
+
+			case 4:
+				// intro
+				_sound->loadSoundFile("SOUND");
+				_screen->hideMouse();
+				seq_playOpeningCredits();
+				seq_playIntro();
+				_screen->showMouse();
+				_sound->loadSoundFile("ADLIB");
+				menuChoice = 0;
+				break;
+		}
+	}
+
+	return shouldQuit() ? -5 : menuChoice;
+}
+
+int EobEngine::mainMenuLoop() {
+	int sel = -1;
+	do {
+		_screen->setScreenDim(28);
+		_gui->simpleMenu_setup(8, 0, _mainMenuStrings, -1, 0, 0);
+
+		while (sel == -1 && !shouldQuit())
+			sel = _gui->simpleMenu_process(8, _mainMenuStrings, 0, -1, 0);
+	} while ((sel < 0 || sel > 5) && !shouldQuit());
+
+	return sel + 1;
+}
+
+void EobEngine::seq_playOpeningCredits() {
+	_allowSkip = true;
+
+	loadSetIntroPalette(_introFilesOpening[5]);
+	_screen->loadBitmap(_introFilesOpening[4], 5, 3, 0);
+	_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+
+	_sound->playTrack(1);
+	delay(_introOpeningFrmDelay[0] * _tickLength);
+
+	for (int i = 0; i < 4 && !shouldQuit() && !skipFlag(); i++) {
+		_screen->loadBitmap(_introFilesOpening[i], 5, 3, 0);
+		uint32 nextFrameTimer = _system->getMillis() + _introOpeningFrmDelay[i + 1] * _tickLength;
+		_screen->crossFadeRegion(0, 50, 0, 50, 320, 102, 2, 0);
+		delayUntil(nextFrameTimer);
+	}
+
+	_allowSkip = false;
+}
+
+void EobEngine::seq_playIntro() {
+	_allowSkip = true;
+
+	if (!shouldQuit() && !skipFlag()) {
+		_sound->playTrack(2);
+		_screen->loadBitmap("TITLE-V.CMP", 5, 3, 0);
+		_screen->crossFadeRegion(0, 0, 0, 0, 320, 200, 2, 0);
+		delay(120 * _tickLength);
+	}
+
+	Common::SeekableReadStream *s = _res->createReadStream("TEXT.RAW");
+	if (s) {
+		s->seek(768);
+		_screen->loadFileDataToPage(s, 6, s->size() - 768);
+		delete s;
+	} else {
+		_screen->loadBitmap("TEXT.CMP", 3, 6, 0);
+	}
+
+	seq_tower();
+	seq_orb();
+	seq_waterdeepEntry();
+	seq_king();
+	seq_hands();
+	seq_waterdeepExit();
+	seq_tunnel();
+
+	whirlTransition();
+	_sound->haltTrack();
+	_allowSkip = false;
+}
+
+void EobEngine::seq_playFinale() {
+	Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
+	_screen->loadFileDataToPage(s, 5, 32000);
+	delete s;
+
+	snd_playSoundEffect(20);
+
+	_txt->resetPageBreakString();
+	_txt->setWaitButtonMode(1);
+	_txt->setupField(12, true);
+	gui_drawBox(0, 0, 176, 175, _color1_1, _color2_1, _bkgColor_1);
+	_txt->printDialogueText(51, _moreStrings[0]);
+
+	if (!checkScriptFlags(0x1ffe)) {
+		_screen->fadeToBlack();
+		return;
+	}
+
+	_txt->printDialogueText(_finBonusStrings[0]);
+	for (int i = 0; i < 6; i++) {
+		_txt->printDialogueText(_finBonusStrings[1]);
+		if (_characters[i].flags & 1)
+			_txt->printDialogueText(_characters[i].name);
+	}
+
+	uint32 password = 0;
+	for (int i = 0; i < 4; i++) {
+		if (!(_characters[i].flags & 1))
+			continue;
+
+		int len = strlen(_characters[i].name);
+		for (int ii = 0; ii < len; ii++) {
+			uint32 c = _characters[i].name[ii];
+			password += (c * c);
+		}
+	}
+
+	_txt->printDialogueText(Common::String::format(_finBonusStrings[2], password).c_str(), true);
+	_screen->fadeToBlack();
+}
+
+void EobEngine::seq_tower() {
+	if (shouldQuit() || skipFlag())
+		return;
+
+	_screen->loadBitmap(_introFilesTower[1], 5, 3, 0);
+	_screen->setCurPage(2);
+	uint8 *shp = _screen->encodeShape(0, 0, 16, 56, true);
+	_screen->copyPage(3, 4);
+	_screen->clearCurPage();
+
+	for (int i = 0; i < 200; i += 64)
+		_screen->copyRegion(128, 104, 96, i, 128, 64, 4, 2, Screen::CR_NO_P_CHECK);
+
+	_screen->fillRect(0, 184, 319, 199, 12);
+	int cp = _screen->setCurPage(0);
+	whirlTransition();
+	loadSetIntroPalette(_introFilesTower[0]);
+
+	_screen->setCurPage(cp);
+	_screen->clearCurPage();
+
+	for (int i = 0; i < 200; i += 64)
+		_screen->copyRegion(128, 104, 0, i, 128, 64, 4, 2, Screen::CR_NO_P_CHECK);
+
+	_screen->setCurPage(0);
+
+	for (int i = 0; i < 64 && !shouldQuit() && !skipFlag(); i += 2) {
+		uint32 end = _system->getMillis() + 2 * _tickLength;
+		_screen->copyRegion(0, 142 - i, 96, 0, 128, i + 1, 4, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(0, 0, 96, i + 1, 128, 167 - i, 2, 0, Screen::CR_NO_P_CHECK);
+		if (!i)
+			_screen->copyRegion(0, 0, 0, 168, 320, 32, 6, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	for (int i = 0; i < 24 && !shouldQuit() && !skipFlag(); i += 2) {
+		uint32 end = _system->getMillis() + 2 * _tickLength;
+		_screen->copyRegion(0, 79 - i, 96, 0, 24, 65 + i, 4, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(104, 79 - i, 200, 0, 24, 65 + i, 4, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(24, 110, 120, i + 31, 80, 34, 4, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(152, 0, 120, 32, 80, i + 1, 4, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(0, 0, 96, 65 + i, 128, 103 - i, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	for (int i = 0; i < 56 && !shouldQuit() && !skipFlag(); i += 2) {
+		uint32 end = _system->getMillis() + 2 * _tickLength;
+		_screen->copyRegion(0, 56, 96, i, 24, 54, 4, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(104, 56, 200, i, 24, 54, 4, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(0, 110, 96, 54 + i, 128, 34, 4, 0, Screen::CR_NO_P_CHECK);
+
+		if (i < 32) {
+			_screen->fillRect(128, 0, 255, i + 1, 12, 2);
+			_screen->copyRegion(152, 0, 120, 32, 80, i + 25, 4, 0, Screen::CR_NO_P_CHECK);
+		} else {
+			_screen->fillRect(128, 0, 255, i + 1, 12, 2);
+			_screen->copyRegion(152, i + 1, 120, 32 + i + 1, 80, 23, 4, 0, Screen::CR_NO_P_CHECK);
+			_screen->copyRegion(152, 0, 152, 32, 80, i + 1, 4, 2, Screen::CR_NO_P_CHECK);
+		}
+
+		_screen->drawShape(2, shp, 128, i - 55, 0);
+		_screen->copyRegion(128, 0, 96, 0, 128, i + 1, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(0, 0, 96, i + 89, 128, 79 - i, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_screen->copyRegion(0, 32, 0, 168, 320, 32, 6, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(65 * _tickLength);
+	delete[] shp;
+}
+
+void EobEngine::seq_orb() {
+	if (shouldQuit() || skipFlag())
+		return;
+
+	uint8 *shp[5];
+	_screen->loadBitmap(_introFilesOrb[0], 5, 3, 0);
+	_screen->setCurPage(2);
+	shp[4] = _screen->encodeShape(0, 0, 20, 136, true);
+	_screen->loadBitmap(_introFilesOrb[1], 5, 3, 0);
+	shp[3] = _screen->encodeShape(16, 0, 16, 104, true);
+
+	_screen->fillRect(0, 0, 127, 103, 12);
+	for (int i = 1; i < 4; i++) {
+		copyBlurRegion(128, 0, 0, 0, 128, 104, i);
+		shp[3 - i] = _screen->encodeShape(0, 0, 16, 104, true);
+	}
+
+	_screen->fillRect(0, 0, 159, 135, 12);
+	_screen->setCurPage(0);
+	_screen->copyPage(3, 4);
+	_screen->clearCurPage();
+
+	_sound->playTrack(6);
+
+	for (int i = -1; i < 4 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + 3 * _tickLength;
+		if (i >= 0)
+			_screen->drawShape(2, shp[i], 16, 16, 0);
+		_screen->drawShape(2, shp[4], 0, 0, 0);
+		_screen->copyRegion(0, 0, 80, 24, 160, 136, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_screen->copyRegion(0, 64, 0, 168, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(40 * _tickLength);
+
+	_sound->playTrack(6);
+
+	for (int i = 3; i > -2 && !shouldQuit() && !skipFlag(); i--) {
+		uint32 end = _system->getMillis() + 3 * _tickLength;
+		_screen->fillRect(16, 16, 143, 119, 12, 2);
+		if (i >= 0)
+			_screen->drawShape(2, shp[i], 16, 16, 0);
+		_screen->drawShape(2, shp[4], 0, 0, 0);
+		_screen->copyRegion(0, 0, 80, 24, 160, 136, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	delay(40 * _tickLength);
+
+	for (int i = 0; i < 5; i++)
+		delete[] shp[i];
+}
+
+void EobEngine::seq_waterdeepEntry() {
+	if (shouldQuit() || skipFlag())
+		return;
+
+	uint8 *shp[4];
+	uint8 *shp2[31];
+	uint8 *shp3[3];
+
+	loadSetIntroPalette(_introFilesWdEntry[0]);
+	_screen->loadBitmap(_introFilesWdEntry[1], 5, 3, 0);
+	_screen->setCurPage(2);
+	shp[3] = _screen->encodeShape(0, 0, 20, 136, true);
+	for (int i = 1; i < 4; i++) {
+		copyBlurRegion(0, 0, 0, 0, 160, 136, i);
+		shp[3 - i] = _screen->encodeShape(0, 0, 20, 136, true);
+	}
+	_screen->setCurPage(0);
+
+	_screen->copyPage(3, 4);
+	_screen->fillRect(0, 168, 319, 199, 12, 0);
+	_sound->playTrack(6);
+
+	for (int i = 0; i < 4 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + 3 * _tickLength;
+		_screen->drawShape(0, shp[i], 80, 24, 0);
+		delete[] shp[i];
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_screen->copyRegion(0, 80, 0, 168, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(50 * _tickLength);
+
+	_screen->setCurPage(2);
+	shp[0] = _screen->encodeShape(20, 0, 20, 136, true);
+	_screen->loadBitmap(_introFilesWdEntry[2], 5, 3, 0);
+	shp[1] = _screen->encodeShape(0, 0, 20, 136, true);
+	shp[2] = _screen->encodeShape(20, 0, 20, 136, true);
+	_screen->loadBitmap(_introFilesWdEntry[3], 5, 3, 0);
+
+	for (int i = 0; i < 31; i++)
+		shp2[i] = _screen->encodeShape(_introWdEncodeX[i], 136 + (_introWdEncodeY[i] << 3), _introWdEncodeWH[i], _introWdEncodeWH[i] << 3, true);
+	for (int i = 0; i < 3; i++)
+		shp3[i] = _screen->encodeShape(5 * i, 152, 5, 32, true);
+
+	_screen->copyPage(3, 4);
+
+	for (int i = 0; i < 3 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + 3 * _tickLength;
+		_screen->fillRect(0, 0, 159, 135, 12, 2);
+		_screen->drawShape(2, shp[i], 0, 0, 0);
+		_screen->copyRegion(0, 0, 80, 24, 160, 136, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_screen->copyRegion(0, 0, 80, 24, 160, 136, 4, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(4 * _tickLength);
+	_screen->copyRegion(160, 0, 80, 24, 160, 136, 4, 0, Screen::CR_NO_P_CHECK);
+	_screen->fillRect(0, 168, 319, 199, 12, 0);
+	_screen->updateScreen();
+	delay(4 * _tickLength);
+	_screen->copyRegion(0, 184, 40, 184, 232, 16, 4, 0, Screen::CR_NO_P_CHECK);
+
+	int cx = 264;
+	int cy = 11;
+
+	for (int i = 0; i < 70 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + 3 * _tickLength;
+
+		_screen->copyRegion(cx - 2, cy - 2, 0, 0, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+		_screen->drawShape(4, shp3[((i & 3) == 3) ? 1 : (i & 3)], cx, cy, 0);
+		_screen->copyRegion(cx - 2, cy - 2, cx - 82, cy + 22, 48, 36, 4, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(0, 0, cx - 2, cy - 2, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+		cx--;
+		cy++;
+
+		for (int ii = 0; ii < 5; ii++) {
+			int s = _rnd.getRandomNumber(255) % 31;
+			_screen->drawShape(0, shp2[s], _introWdDsX[s] - 80, _introWdDsY[s] + 24, 0);
+		}
+
+		if (!(_rnd.getRandomNumber(255) & 7))
+			_sound->playTrack(_rnd.getRandomBit() ? 5 : 14);
+
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	for (int i = 0; i < 3; i++) {
+		delete[] shp[i];
+		delete[] shp3[i];
+	}
+
+	for (int i = 0; i < 31; i++)
+		delete[] shp2[i];
+}
+
+void EobEngine::seq_king() {
+	if (shouldQuit() || skipFlag())
+		return;
+
+	_screen->loadBitmap(_introFilesKing[0], 5, 3, 0);
+	_screen->copyPage(3, 4);
+
+	int x = 15;
+	int y = 14;
+	int w = 1;
+	int h = 1;
+
+	for (int i = 0; i < 10 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->copyRegion(x << 3, y << 3, x << 3, y << 3, w << 3, h << 3, 4, 0, Screen::CR_NO_P_CHECK);
+		if (x > 6)
+			x --;
+		if (y > 0)
+			y -= 2;
+		w += 3;
+		if (x + w > 34)
+			w = 34 - x;
+		h += 3;
+		if (y + h > 23)
+			h = 23 - y;
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	delay(25 * _tickLength);
+
+	uint8 *shp[4];
+	int16 dy[4];
+	int16 stepY[4];
+
+	static const uint8 advEncX[] = { 0, 6, 12, 19 };
+	static const uint8 advEncW[] = { 6, 6, 7, 6 };
+	static const int8 modY[] = { -4, -8, -2, -2, 1, 0, 0, 0 };
+
+	_screen->loadBitmap(_introFilesKing[1], 5, 3, 0);
+	_screen->setCurPage(2);
+	for (int i = 0; i < 4; i++) {
+		shp[i] = _screen->encodeShape(advEncX[i], 0, advEncW[i], 98, true);
+		dy[i] = 180 + ((_rnd.getRandomNumber(255) & 3) << 3);
+		stepY[i] = (i * 5) & 3;
+	}
+
+	_screen->copyPage(0, 4);
+
+	for (bool runloop = true; runloop && !shouldQuit() && !skipFlag(); ) {
+		runloop = false;
+		uint32 end = _system->getMillis() + 2 * _tickLength;
+
+		for (int i = 0; i < 4; i++) {
+			if (dy[i] <= 82)
+				continue;
+			stepY[i] = (stepY[i] + 1) & 7;
+			dy[i] += modY[stepY[i]];
+
+			if (dy[i] < 82)
+				dy[i] = 82;
+
+			if (dy[i] < 180) {
+				_screen->copyRegion((advEncX[i] + 8) << 3, dy[i] - 2, 0, dy[i] - 2, advEncW[i] << 3, 182 - dy[i], 4, 4, Screen::CR_NO_P_CHECK);
+				_screen->drawShape(4, shp[i], 0, dy[i], 0);
+				_screen->copyRegion(0, dy[i] - 2, (advEncX[i] + 8) << 3, dy[i] - 2, advEncW[i] << 3, 182 - dy[i], 4, 0, Screen::CR_NO_P_CHECK);
+			}
+
+			if (_rnd.getRandomNumber(255) & 3)
+				_sound->playTrack(7);
+
+			runloop = true;
+		}
+
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_screen->copyRegion(0, 96, 0, 160, 320, 32, 6, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(70 * _tickLength);
+
+	for (int i = 0; i < 4; i++)
+		delete[] shp[i];
+}
+
+void EobEngine::seq_hands() {
+	if (shouldQuit() || skipFlag())
+		return;
+
+	_screen->setCurPage(2);
+	uint8 *shp1 = _screen->encodeShape(0, 140, 21, 60, true);
+	uint8 *shp2 = _screen->encodeShape(21, 140, 12, 60, true);
+	_screen->loadBitmap(_introFilesHands[0], 3, 5, 0);
+
+	_screen->fillRect(0, 160, 319, 199, 12, 0);
+	_screen->fillRect(0, 0, 191, 63, 157, 2);
+	_screen->drawShape(2, shp1, 0, 4, 0);
+	_screen->drawShape(2, shp2, 151, 4, 0);
+	boxMorphTransition(25, 8, 18, 4, 3, 0, 21, 8, 6, 0, 28, 23);
+	_screen->copyRegion(0, 128, 0, 176, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+
+	_screen->updateScreen();
+	delay(15 * _tickLength);
+	_sound->playTrack(11);
+
+	for (int i = -22; i <= 20 && !shouldQuit() && !skipFlag(); i += 4) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->fillRect(0, 0, 167, 63, 157);
+		_screen->drawShape(2, shp1, i, 4, 0);
+		_screen->drawShape(2, shp1, 105 - i, 4, 0);
+		_screen->copyRegion(0, 0, 144, 32, 168, 64, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_sound->playTrack(10);
+
+	delete[] shp1;
+	delete[] shp2;
+	delay(15 * _tickLength);
+
+	_screen->setCurPage(4);
+	shp1 = _screen->encodeShape(17, 0, 11, 120, true);
+	shp2 = _screen->encodeShape(28, 112, 1, 31, true);
+	uint8 *shp3 = _screen->encodeShape(9, 138, 14, 54, true);
+
+	_screen->setCurPage(2);
+	_screen->fillRect(0, 0, 135, 63, 157);
+	_screen->drawShape(2, shp1, 32, -80, 0);
+	_screen->drawShape(2, shp2, 40, -16, 0);
+	boxMorphTransition(18, 16, 10, 12, 0, 0, 17, 8, 17, 3, 25, 10);
+	delay(15 * _tickLength);
+
+	for (int i = -80; i <= 0 && !shouldQuit() && !skipFlag(); i += 4) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->fillRect(0, 0, 135, 63, 157);
+		_screen->drawShape(2, shp1, 32, i, 0);
+		_screen->drawShape(2, shp2, 40, i + 64, 0);
+		_screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_sound->playTrack(12);
+	delay(5 * _tickLength);
+
+	for (int i = 0; i > -54 && !shouldQuit() && !skipFlag(); i -= 4) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->fillRect(0, 0, 135, 63, 157);
+		_screen->drawShape(2, shp3, 12, 64 + i, 0);
+		_screen->drawShape(2, shp1, 32, i, 0);
+		_screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	delete[] shp1;
+	delete[] shp2;
+	delete[] shp3;
+	delay(15 * _tickLength);
+
+	_screen->setCurPage(4);
+	shp1 = _screen->encodeShape(0, 0, 17, 136, true);
+	shp2 = _screen->encodeShape(0, 136, 9, 48, true);
+
+	_screen->setCurPage(2);
+	_screen->fillRect(0, 0, 143, 95, 157);
+	_screen->drawShape(2, shp1, -56, -56, 0);
+	_screen->drawShape(2, shp2, 52, 49, 0);
+	boxMorphTransition(9, 6, 0, 0, 0, 0, 18, 12, 8, 11, 21, 10);
+	delay(15 * _tickLength);
+	_sound->playTrack(11);
+
+	for (int i = -56; i <= -8 && !shouldQuit() && !skipFlag(); i += 4) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->fillRect(0, 0, 143, 95, 157);
+		_screen->drawShape(2, shp1, i, i, 0);
+		_screen->drawShape(2, shp2, (i == -8) ? 55 : 52, (i == -8) ? 52 : 49, 0);
+		_screen->copyRegion(0, 0, 0, 0, 144, 96, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_sound->playTrack(10);
+	delete[] shp1;
+	delete[] shp2;
+	delay(30 * _tickLength);
+
+	_screen->setCurPage(4);
+	shp1 = _screen->encodeShape(28, 0, 11, 40, true);
+	shp2 = _screen->encodeShape(28, 40, 10, 72, true);
+
+	_screen->setCurPage(2);
+	_screen->fillRect(0, 0, 87, 112, 157);
+	_screen->drawShape(2, shp2, 0, 90, 0);
+	boxMorphTransition(20, 13, 15, 6, 0, 0, 11, 14, 0, 0, 24, 16);
+	delay(15 * _tickLength);
+
+	int dy = 90;
+	for (int i = -40; i <= 0 && !shouldQuit() && !skipFlag(); i += 4) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->fillRect(0, 0, 87, 112, 157);
+		_screen->drawShape(2, shp2, 0, dy, 0);
+		_screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+		dy -= 5;
+	}
+
+	_sound->playTrack(13);
+
+	for (int i = -40; i <= 0 && !shouldQuit() && !skipFlag(); i += 4) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->fillRect(0, 0, 87, 39, 157);
+		_screen->drawShape(2, shp1, 0, i, 0);
+		_screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	delete[] shp1;
+	delete[] shp2;
+	delay(48 * _tickLength);
+}
+
+void EobEngine::seq_waterdeepExit() {
+	if (shouldQuit() || skipFlag())
+		return;
+
+	uint8 *shp2[31];
+	uint8 *shp3[3];
+
+	_screen->loadBitmap(_introFilesWdExit[0], 5, 3, 0);
+	_screen->setCurPage(2);
+	for (int i = 0; i < 31; i++)
+		shp2[i] = _screen->encodeShape(_introWdEncodeX[i], 136 + (_introWdEncodeY[i] << 3), _introWdEncodeWH[i], _introWdEncodeWH[i] << 3, true);
+	for (int i = 0; i < 3; i++)
+		shp3[i] = _screen->encodeShape(5 * i + 15, 152, 5, 32, true);
+	uint8 *shp1 = _screen->encodeShape(31, 136, 5, 32, true);
+	_screen->copyPage(3, 4);
+	_screen->copyRegion(0, 0, 0, 136, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+	_screen->fillRect(0, 168, 319, 199, 12, 0);
+	_screen->copyRegion(160, 0, 80, 24, 160, 136, 4, 0, Screen::CR_NO_P_CHECK);
+
+	int cx = 140;
+	int cy = 128;
+
+	for (int i = 0; i < 70 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + 3 * _tickLength;
+		int fx = cx - 2;
+		if (fx < 160)
+			fx = 160;
+		int fy = cy - 2;
+		if (fy > 98)
+			fy = 98;
+
+		_screen->copyRegion(fx, fy, 0, 0, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+		_screen->drawShape(4, shp3[((i & 3) == 3) ? 1 : (i & 3)], cx, cy, 0);
+		_screen->drawShape(4, shp1, 160, 104, 0);
+		_screen->copyRegion(fx, fy, fx - 80, fy + 24, 48, 36, 4, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(0, 0, fx, fy, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+		cx++;
+		cy--;
+
+		for (int ii = 0; ii < 5; ii++) {
+			int s = _rnd.getRandomNumber(255) % 31;
+			_screen->drawShape(0, shp2[s], _introWdDsX[s] - 80, _introWdDsY[s] + 24, 0);
+		}
+
+		if (!(_rnd.getRandomNumber(255) & 7))
+			_sound->playTrack(_rnd.getRandomBit() ? 5 : 14);
+
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	for (int i = 0; i < 3; i++)
+		delete[] shp3[i];
+
+	for (int i = 0; i < 31; i++)
+		delete[] shp2[i];
+	delete[] shp1;
+
+	_screen->setCurPage(0);
+	_screen->fillRect(0, 168, 319, 199, 12, 0);
+	_screen->copyRegion(0, 136, 0, 0, 48, 36, 0, 4, Screen::CR_NO_P_CHECK);
+
+	loadSetIntroPalette(_introFilesWdExit[1]);
+	_screen->loadBitmap(_introFilesWdExit[2], 3, 5, 0);
+	_screen->copyPage(5, 2);
+	whirlTransition();
+	delay(6 * _tickLength);
+
+	_screen->copyRegion(0, 144, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+
+	cx = 0;
+	cy = 136;
+	int dy = 0;
+	for (int i = 0; i < 19 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->copyRegion(cx, cy, 80, dy + 16, 160, 8, 2, 0, Screen::CR_NO_P_CHECK);
+		cy += 8;
+		dy += 8;
+		if (i == 6) {
+			cx = 160;
+			cy = 0;
+		}
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_sound->playTrack(3);
+	delay(60 * _tickLength);
+
+	for (int i = 0; i < 56 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->copyRegion(0, 136 + i, 80, 16, 160, 56 - i, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->copyRegion(160, 0, 80, 72 - i, 160, 96 + i, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	for (int i = 1; i < 48 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->copyRegion(160, i, 80, 16, 160, 152, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_screen->loadBitmap(_introFilesWdExit[3], 3, 5, 0);
+	_screen->copyPage(5, 2);
+	delay(30 * _tickLength);
+	_screen->setCurPage(0);
+	_screen->fillRect(0, 16, 319, 31, 12);
+	_screen->fillRect(0, 136, 319, 199, 12);
+	_screen->copyRegion(0, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
+	loadSetIntroPalette(_introFilesWdExit[4]);
+	_screen->updateScreen();
+	delay(50 * _tickLength);
+}
+
+void EobEngine::seq_tunnel() {
+	if (shouldQuit() || skipFlag())
+		return;
+
+	_screen->setCurPage(4);
+	uint8 *shp2 = _screen->encodeShape(20, 0, 20, 120, true);
+	uint8 *shp1 = _screen->encodeShape(0, 0, 20, 120, true);
+	drawBlockObject(1, 4, shp2, 160, 0, 0);
+	drawBlockObject(1, 4, shp1, 0, 0, 0);
+	delete[] shp1;
+	delete[] shp2;
+
+	for (int i = 0; i < 3 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + 8 * _tickLength;
+		_screen->copyRegion(0, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
+		_sound->playTrack(7);
+		_screen->updateScreen();
+		delayUntil(end);
+		_screen->copyRegion(0, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
+		_sound->playTrack(7);
+		end = _system->getMillis() + 8 * _tickLength;
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_screen->copyRegion(0, 160, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(18 * _tickLength);
+	_screen->copyRegion(160, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(5 * _tickLength);
+	_screen->copyRegion(0, 122, 80, 32, 160, 60, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->copyRegion(160, 122, 80, 92, 160, 60, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(5 * _tickLength);
+	_screen->copyRegion(160, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
+	for (int i = 0; i < 6; i++)
+		_screen->copyRegion(i * 48, 185, 56, (i << 3) + 24, 48, 8, 2, 2, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(5 * _tickLength);
+	_screen->copyRegion(0, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
+
+	_screen->loadBitmap(_introFilesTunnel[0], 5, 3, 0);
+	_screen->copyPage(3, 4);
+	_screen->updateScreen();
+	delay(40 * _tickLength);
+
+	_screen->copyRegion(264, 0, 136, 56, 48, 48, 4, 0, Screen::CR_NO_P_CHECK);
+	_sound->playTrack(8);
+	_screen->copyRegion(0, 0, 0, 0, 320, 184, 0, 2, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(16 * _tickLength);
+	_sound->playTrack(4);
+
+	for (int i = 0; i < 30 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + _tickLength;
+		if (i == 0)
+			_screen->fillRect(0, 168, 319, 199, 12, 0);
+		_screen->copyRegion(80, 25 + (_rnd.getRandomNumber(255) & 7), 80, 24, 160, 144, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+
+	_sound->playTrack(9);
+
+	for (int i = 0; i < 6 && !shouldQuit() && !skipFlag(); i++) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->copyRegion(_introTvlX1[i] << 3, _introTvlY1[i], _introTvlX2[i] << 3, _introTvlY2[i], _introTvlW[i] << 3, _introTvlH[i], 4, 2, Screen::CR_NO_P_CHECK);
+		for (int ii = 0; ii < 4 && !shouldQuit() && !skipFlag(); ii++) {
+			_screen->updateScreen();
+			delayUntil(end);
+			end = _system->getMillis() + _tickLength;
+			_screen->copyRegion(80, 25 + (_rnd.getRandomNumber(255) & 7), 80, 24, 160, 144, 2, 0, Screen::CR_NO_P_CHECK);
+		}
+	}
+	_screen->copyRegion(0, 0, 0, 0, 320, 168, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(40 * _tickLength);
+
+	_screen->loadBitmap(_introFilesTunnel[1], 5, 3, 0);
+	_screen->copyPage(3, 4);
+	_sound->playTrack(6);
+	_screen->copyRegion(0, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(2 * _tickLength);
+	_screen->copyRegion(160, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+	delay(2 * _tickLength);
+	_screen->copyRegion(0, 120, 80, 30, 160, 64, 4, 0, Screen::CR_NO_P_CHECK);
+	_screen->copyRegion(160, 120, 80, 94, 160, 64, 4, 0, Screen::CR_NO_P_CHECK);
+	_screen->copyRegion(0, 176, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+	_screen->setCurPage(0);
+	_screen->updateScreen();
+	delay(50 * _tickLength);
+}
+
+void EobEngine::seq_xdeath() {
+	uint8 *shapes1[5];
+	uint8 *shapes2;
+
+	_screen->loadShapeSetBitmap("XDEATH2", 5, 3);
+	for (int i = 0; i < 4; i++)
+		shapes1[i] = _screen->encodeShape(i / 2 * 14, i / 2 * 88, 14, 88, true);
+	_screen->loadShapeSetBitmap("XDEATH3", 5, 3);
+	shapes2 = _screen->encodeShape(22, 0, 16, 95, true);
+	_screen->loadEobBitmap("XDEATH1", 0, 5, 3, -1);
+	_screen->setCurPage(0);
+
+	for (int i = 0; i < 10; i++) {
+		if (i == 2)
+			snd_playSoundEffect(72);
+		else if (i == 4 || i == 6)
+			snd_playSoundEffect(54);
+		else
+			snd_playSoundEffect(34);
+
+		if (i < 6) {
+			_screen->copyRegion((i % 3) * 104, i / 3 * 88, 32, 10, 104, 88, 2, 0, Screen::CR_NO_P_CHECK);
+		} else {
+			snd_playSoundEffect(42);
+			_screen->drawShape(0, shapes1[i - 6], 32, 10, 0);
+		}
+
+		_screen->updateScreen();
+		delay(4 * _tickLength);
+	}
+
+	const ScreenDim *dm = _screen->getScreenDim(5);
+	_screen->modifyScreenDim(5, dm->sx, 8, dm->w, dm->h);
+	_screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 5, Screen::CR_NO_P_CHECK);
+
+	for (int i = 0; i < 19; i++) {
+		snd_playSoundEffect(119);
+		_screen->copyRegion(0, 0, 0, 0, 176, 120, 5, 2, Screen::CR_NO_P_CHECK);
+		_screen->drawShape(2, shapes2, 24, i * 5 - 90, 5);
+		_screen->copyRegion(0, 0, 0, 0, 176, 120, 2, 0, Screen::CR_NO_P_CHECK);
+		_screen->updateScreen();
+		delay(2 * _tickLength);
+	}
+
+	_screen->modifyScreenDim(5, dm->sx, 0, dm->w, dm->h);
+
+	snd_playSoundEffect(5);
+	delay(60 * _tickLength);
+
+	for (int i = 0; i < 4; i++)
+		delete[] shapes1[i];
+	delete[] shapes2;
+
+	gui_drawPlayField(false);
+	gui_drawAllCharPortraitsWithStats();
+}
+
+void EobEngine::loadSetIntroPalette(const char *filename) {
+	_screen->loadPalette(filename, _screen->getPalette(0));
+	_screen->getPalette(0).fill(0, 1, 0);
+	_screen->setScreenPalette(_screen->getPalette(0));
+}
+
+void EobEngine::copyBlurRegion(int x1, int y1, int x2, int y2, int w, int h, int step) {
+	const uint8 *ptr2 = _screen->getCPagePtr(3) + y1 * 320 + x1;
+
+	if (step == 1) {
+		while (h > 0) {
+			int dx = x2;
+			for (int i = 0; i < w; i += 2) {
+				_screen->setPagePixel(3, dx++, y2, ptr2[i]);
+				_screen->setPagePixel(3, dx++, y2, 0);
+			}
+			dx = x2;
+			y2++;
+			ptr2 += 320;
+			for (int i = 0; i < w; i += 2) {
+				_screen->setPagePixel(3, dx++, y2, 0);
+				_screen->setPagePixel(3, dx++, y2, ptr2[i + 1]);
+			}
+			y2++;
+			ptr2 += 320;
+			h -= 2;
+		}
+	} else if (step == 2) {
+		while (h > 0) {
+			int dx = x2;
+			for (int i = 0; i < w; i += 2) {
+				_screen->setPagePixel(3, dx++, y2, ptr2[i]);
+				_screen->setPagePixel(3, dx++, y2, 0);
+			}
+			dx = x2;
+			y2++;
+			ptr2 += 320;
+			for (int i = 0; i < w; i++)
+				_screen->setPagePixel(3, dx++, y2, 0);
+
+			y2++;
+			ptr2 += 320;
+			h -= 2;
+		}
+	} else if (step == 3) {
+		for (int i = 0; i < h; i++) {
+			int dx = x2;
+			if ((i % 3) == 0) {
+				int ii = 0;
+				for (; ii < w - 3; ii += 3) {
+					_screen->setPagePixel(3, dx++, y2, ptr2[ii]);
+					_screen->setPagePixel(3, dx++, y2, 0);
+					_screen->setPagePixel(3, dx++, y2, 0);
+				}
+				for (; ii < w; ii++)
+					_screen->setPagePixel(3, dx++, y2, 0);
+			} else {
+				for (int ii = 0; ii < w; ii++)
+					_screen->setPagePixel(3, dx++, y2, 0);
+			}
+			y2++;
+			ptr2 += 320;
+		}
+	}
+}
+
+void EobEngine::boxMorphTransition(int targetDestX, int targetDestY, int targetFinalX, int targetFinalY, int targetSrcX, int targetSrcY, int targetFinalW, int targetFinalH, int originX1, int originY1, int originW, int originH) {
+	int originX2 = originX1 + originW;
+	int originY2 = originY1 + originH;
+	if (originY2 > 21)
+		originY2 = 21;
+
+	int w = 1;
+	int h = 1;
+	for (bool runloop = true; runloop && !shouldQuit() && !skipFlag(); ) {
+		uint32 end = _system->getMillis() + _tickLength;
+		_screen->copyRegion(targetSrcX << 3, targetSrcY << 3, targetDestX << 3, targetDestY << 3, w << 3, h << 3, 2, 0, Screen::CR_NO_P_CHECK);
+		if (originX1 < targetDestX)
+			_screen->copyRegion(312, 0, originX1 << 3, 0, 8, 176, 0, 0, Screen::CR_NO_P_CHECK);
+		if (originY1 < targetDestY)
+			_screen->copyRegion(0, 192, 0, originY1 << 3, 320, 8, 0, 0, Screen::CR_NO_P_CHECK);
+		if ((targetFinalX + targetFinalW) <= originX2)
+			_screen->copyRegion(312, 0, originX2 << 3, 0, 8, 176, 0, 0, Screen::CR_NO_P_CHECK);
+		if ((targetFinalY + targetFinalH) <= originY2)
+			_screen->copyRegion(0, 192, 0, originY2 << 3, 320, 8, 0, 0, Screen::CR_NO_P_CHECK);
+
+		if (!(targetDestX != targetFinalX || targetDestY != targetFinalY || w != targetFinalW || h != targetFinalH || originX1 < targetFinalX || originY1 < targetFinalY || (targetFinalX + targetFinalW) < originX2 || (targetFinalY + targetFinalH) < originY2))
+			runloop = false;
+
+		int v = targetFinalX - targetDestX;
+		v = (v < 0) ? -1 : ((v > 0) ? 1 : 0);
+		targetDestX += v;
+		v = targetFinalY - targetDestY;
+		v = (v < 0) ? -1 : ((v > 0) ? 1 : 0);
+		targetDestY += v;
+
+		if (w != targetFinalW)
+			w += 2;
+		if (w > targetFinalW)
+			w = targetFinalW;
+
+		if (h != targetFinalH)
+			h += 2;
+		if (h > targetFinalH)
+			h = targetFinalH;
+
+		if (++originX1 > targetFinalX)
+			originX1 = targetFinalX;
+
+		if (++originY1 > targetFinalY)
+			originY1 = targetFinalY;
+
+		if ((targetFinalX + targetFinalW) < originX2)
+			originX2--;
+
+		if ((targetFinalY + targetFinalH) < originY2)
+			originY2--;
+
+		_screen->updateScreen();
+		delayUntil(end);
+	}
+}
+
+void EobEngine::whirlTransition() {
+	for (int i = 0; i < 2; i++) {
+		for (int ii = 0; ii < 8; ii++) {
+			uint32 e = _system->getMillis() + 3;
+			if (ii & 1) {
+				for (int iii = i + ii; iii < 320; iii += 8)
+					_screen->drawClippedLine(iii, 0, iii, 199, 12);
+			} else {
+				for (int iii = i + ii; iii < 200; iii += 8)
+					_screen->drawClippedLine(0, iii, 319, iii, 12);
+			}
+			_screen->updateScreen();
+			uint32 c = _system->getMillis();
+			if (e > c)
+				_system->delayMillis(e - c);
+		}
+	}
+}
+
+}	// End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/sequences_eob1.cpp b/engines/kyra/sequences_eob1.cpp
deleted file mode 100644
index b25de5c..0000000
--- a/engines/kyra/sequences_eob1.cpp
+++ /dev/null
@@ -1,1071 +0,0 @@
-/* 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.
- *
- */
-
-#ifdef ENABLE_EOB
-
-#include "kyra/eob1.h"
-#include "kyra/screen_eob.h"
-#include "kyra/resource.h"
-#include "kyra/sound.h"
-
-#include "common/system.h"
-
-#include "base/version.h"
-
-namespace Kyra {
-
-int EobEngine::mainMenu() {
-	int menuChoice = _menuChoiceInit;
-	_menuChoiceInit = 0;
-
-	Screen::FontId of = _screen->_currentFont;
-
-	while (menuChoice >= 0 && !shouldQuit()) {
-		switch (menuChoice) {
-			case 0:
-				_screen->loadPalette("EOBPAL.COL", _screen->getPalette(0));
-				_screen->loadEobBitmap("INTRO", 0, 5, 3, 2);
-				_screen->setScreenPalette(_screen->getPalette(0));
-				_screen->_curPage = 2;
-				of = _screen->setFont(Screen::FID_6_FNT);
-				_screen->printText(gScummVMVersion, 280 - strlen(gScummVMVersion) * 6, 153, _screen->getPagePixel(2, 0, 0), 0);
-				_screen->setFont(of);
-				_screen->fillRect(0, 159, 319, 199, _screen->getPagePixel(2, 0, 0));
-				gui_drawBox(77, 165, 173, 29, 13, 14, 12);
-				gui_drawBox(76, 164, 175, 31, 13, 14, -1);
-				_screen->_curPage = 0;
-				_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
-				_screen->updateScreen();
-				menuChoice = mainMenuLoop();
-				break;
-
-			case 1:
-				// load game in progress
-				//
-				menuChoice = -1;
-				break;
-
-			case 2:
-				// create new party
-				menuChoice = -2;
-				break;
-
-			case 3:
-				// quit
-				menuChoice = -5;
-				break;
-
-			case 4:
-				// intro
-				_sound->loadSoundFile("SOUND");
-				_screen->hideMouse();
-				seq_playOpeningCredits();
-				seq_playIntro();
-				_screen->showMouse();
-				_sound->loadSoundFile("ADLIB");
-				menuChoice = 0;
-				break;
-		}
-	}
-
-	return shouldQuit() ? -5 : menuChoice;
-}
-
-int EobEngine::mainMenuLoop() {
-	int sel = -1;
-	do {
-		_screen->setScreenDim(28);
-		_gui->simpleMenu_setup(8, 0, _mainMenuStrings, -1, 0, 0);
-
-		while (sel == -1 && !shouldQuit())
-			sel = _gui->simpleMenu_process(8, _mainMenuStrings, 0, -1, 0);
-	} while ((sel < 0 || sel > 5) && !shouldQuit());
-
-	return sel + 1;
-}
-
-void EobEngine::seq_playOpeningCredits() {
-	_allowSkip = true;
-
-	loadSetIntroPalette(_introFilesOpening[5]);
-	_screen->loadBitmap(_introFilesOpening[4], 5, 3, 0);
-	_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
-	_screen->updateScreen();
-
-	_sound->playTrack(1);
-	delay(_introOpeningFrmDelay[0] * _tickLength);
-
-	for (int i = 0; i < 4 && !shouldQuit() && !skipFlag(); i++) {
-		_screen->loadBitmap(_introFilesOpening[i], 5, 3, 0);
-		uint32 nextFrameTimer = _system->getMillis() + _introOpeningFrmDelay[i + 1] * _tickLength;
-		_screen->crossFadeRegion(0, 50, 0, 50, 320, 102, 2, 0);
-		delayUntil(nextFrameTimer);
-	}
-
-	_allowSkip = false;
-}
-
-void EobEngine::seq_playIntro() {
-	_allowSkip = true;
-
-	if (!shouldQuit() && !skipFlag()) {
-		_sound->playTrack(2);
-		_screen->loadBitmap("TITLE-V.CMP", 5, 3, 0);
-		_screen->crossFadeRegion(0, 0, 0, 0, 320, 200, 2, 0);
-		delay(120 * _tickLength);
-	}
-
-	Common::SeekableReadStream *s = _res->createReadStream("TEXT.RAW");
-	if (s) {
-		s->seek(768);
-		_screen->loadFileDataToPage(s, 6, s->size() - 768);
-		delete s;
-	} else {
-		_screen->loadBitmap("TEXT.CMP", 3, 6, 0);
-	}
-
-	seq_tower();
-	seq_orb();
-	seq_waterdeepEntry();
-	seq_king();
-	seq_hands();
-	seq_waterdeepExit();
-	seq_tunnel();
-
-	whirlTransition();
-	_sound->haltTrack();
-	_allowSkip = false;
-}
-
-void EobEngine::seq_playFinale() {
-	Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
-	_screen->loadFileDataToPage(s, 5, 32000);
-	delete s;
-
-	snd_playSoundEffect(20);
-
-	_txt->resetPageBreakString();
-	_txt->setWaitButtonMode(1);
-	_txt->setupField(12, true);
-	gui_drawBox(0, 0, 176, 175, _color1_1, _color2_1, _bkgColor_1);
-	_txt->printDialogueText(51, _moreStrings[0]);
-
-	if (!checkScriptFlags(0x1ffe)) {
-		_screen->fadeToBlack();
-		return;
-	}
-
-	_txt->printDialogueText(_finBonusStrings[0]);
-	for (int i = 0; i < 6; i++) {
-		_txt->printDialogueText(_finBonusStrings[1]);
-		if (_characters[i].flags & 1)
-			_txt->printDialogueText(_characters[i].name);
-	}
-
-	uint32 password = 0;
-	for (int i = 0; i < 4; i++) {
-		if (!(_characters[i].flags & 1))
-			continue;
-
-		int len = strlen(_characters[i].name);
-		for (int ii = 0; ii < len; ii++) {
-			uint32 c = _characters[i].name[ii];
-			password += (c * c);
-		}
-	}
-
-	_txt->printDialogueText(Common::String::format(_finBonusStrings[2], password).c_str(), true);
-	_screen->fadeToBlack();
-}
-
-void EobEngine::seq_tower() {
-	if (shouldQuit() || skipFlag())
-		return;
-
-	_screen->loadBitmap(_introFilesTower[1], 5, 3, 0);
-	_screen->setCurPage(2);
-	uint8 *shp = _screen->encodeShape(0, 0, 16, 56, true);
-	_screen->copyPage(3, 4);
-	_screen->clearCurPage();
-
-	for (int i = 0; i < 200; i += 64)
-		_screen->copyRegion(128, 104, 96, i, 128, 64, 4, 2, Screen::CR_NO_P_CHECK);
-
-	_screen->fillRect(0, 184, 319, 199, 12);
-	int cp = _screen->setCurPage(0);
-	whirlTransition();
-	loadSetIntroPalette(_introFilesTower[0]);
-
-	_screen->setCurPage(cp);
-	_screen->clearCurPage();
-
-	for (int i = 0; i < 200; i += 64)
-		_screen->copyRegion(128, 104, 0, i, 128, 64, 4, 2, Screen::CR_NO_P_CHECK);
-
-	_screen->setCurPage(0);
-
-	for (int i = 0; i < 64 && !shouldQuit() && !skipFlag(); i += 2) {
-		uint32 end = _system->getMillis() + 2 * _tickLength;
-		_screen->copyRegion(0, 142 - i, 96, 0, 128, i + 1, 4, 0, Screen::CR_NO_P_CHECK);
-		_screen->copyRegion(0, 0, 96, i + 1, 128, 167 - i, 2, 0, Screen::CR_NO_P_CHECK);
-		if (!i)
-			_screen->copyRegion(0, 0, 0, 168, 320, 32, 6, 0, Screen::CR_NO_P_CHECK);
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	for (int i = 0; i < 24 && !shouldQuit() && !skipFlag(); i += 2) {
-		uint32 end = _system->getMillis() + 2 * _tickLength;
-		_screen->copyRegion(0, 79 - i, 96, 0, 24, 65 + i, 4, 0, Screen::CR_NO_P_CHECK);
-		_screen->copyRegion(104, 79 - i, 200, 0, 24, 65 + i, 4, 0, Screen::CR_NO_P_CHECK);
-		_screen->copyRegion(24, 110, 120, i + 31, 80, 34, 4, 0, Screen::CR_NO_P_CHECK);
-		_screen->copyRegion(152, 0, 120, 32, 80, i + 1, 4, 0, Screen::CR_NO_P_CHECK);
-		_screen->copyRegion(0, 0, 96, 65 + i, 128, 103 - i, 2, 0, Screen::CR_NO_P_CHECK);
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	for (int i = 0; i < 56 && !shouldQuit() && !skipFlag(); i += 2) {
-		uint32 end = _system->getMillis() + 2 * _tickLength;
-		_screen->copyRegion(0, 56, 96, i, 24, 54, 4, 0, Screen::CR_NO_P_CHECK);
-		_screen->copyRegion(104, 56, 200, i, 24, 54, 4, 0, Screen::CR_NO_P_CHECK);
-		_screen->copyRegion(0, 110, 96, 54 + i, 128, 34, 4, 0, Screen::CR_NO_P_CHECK);
-
-		if (i < 32) {
-			_screen->fillRect(128, 0, 255, i + 1, 12, 2);
-			_screen->copyRegion(152, 0, 120, 32, 80, i + 25, 4, 0, Screen::CR_NO_P_CHECK);
-		} else {
-			_screen->fillRect(128, 0, 255, i + 1, 12, 2);
-			_screen->copyRegion(152, i + 1, 120, 32 + i + 1, 80, 23, 4, 0, Screen::CR_NO_P_CHECK);
-			_screen->copyRegion(152, 0, 152, 32, 80, i + 1, 4, 2, Screen::CR_NO_P_CHECK);
-		}
-
-		_screen->drawShape(2, shp, 128, i - 55, 0);
-		_screen->copyRegion(128, 0, 96, 0, 128, i + 1, 2, 0, Screen::CR_NO_P_CHECK);
-		_screen->copyRegion(0, 0, 96, i + 89, 128, 79 - i, 2, 0, Screen::CR_NO_P_CHECK);
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	_screen->copyRegion(0, 32, 0, 168, 320, 32, 6, 0, Screen::CR_NO_P_CHECK);
-	_screen->updateScreen();
-	delay(65 * _tickLength);
-	delete[] shp;
-}
-
-void EobEngine::seq_orb() {
-	if (shouldQuit() || skipFlag())
-		return;
-
-	uint8 *shp[5];
-	_screen->loadBitmap(_introFilesOrb[0], 5, 3, 0);
-	_screen->setCurPage(2);
-	shp[4] = _screen->encodeShape(0, 0, 20, 136, true);
-	_screen->loadBitmap(_introFilesOrb[1], 5, 3, 0);
-	shp[3] = _screen->encodeShape(16, 0, 16, 104, true);
-
-	_screen->fillRect(0, 0, 127, 103, 12);
-	for (int i = 1; i < 4; i++) {
-		copyBlurRegion(128, 0, 0, 0, 128, 104, i);
-		shp[3 - i] = _screen->encodeShape(0, 0, 16, 104, true);
-	}
-
-	_screen->fillRect(0, 0, 159, 135, 12);
-	_screen->setCurPage(0);
-	_screen->copyPage(3, 4);
-	_screen->clearCurPage();
-
-	_sound->playTrack(6);
-
-	for (int i = -1; i < 4 && !shouldQuit() && !skipFlag(); i++) {
-		uint32 end = _system->getMillis() + 3 * _tickLength;
-		if (i >= 0)
-			_screen->drawShape(2, shp[i], 16, 16, 0);
-		_screen->drawShape(2, shp[4], 0, 0, 0);
-		_screen->copyRegion(0, 0, 80, 24, 160, 136, 2, 0, Screen::CR_NO_P_CHECK);
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	_screen->copyRegion(0, 64, 0, 168, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
-	_screen->updateScreen();
-	delay(40 * _tickLength);
-
-	_sound->playTrack(6);
-
-	for (int i = 3; i > -2 && !shouldQuit() && !skipFlag(); i--) {
-		uint32 end = _system->getMillis() + 3 * _tickLength;
-		_screen->fillRect(16, 16, 143, 119, 12, 2);
-		if (i >= 0)
-			_screen->drawShape(2, shp[i], 16, 16, 0);
-		_screen->drawShape(2, shp[4], 0, 0, 0);
-		_screen->copyRegion(0, 0, 80, 24, 160, 136, 2, 0, Screen::CR_NO_P_CHECK);
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	delay(40 * _tickLength);
-
-	for (int i = 0; i < 5; i++)
-		delete[] shp[i];
-}
-
-void EobEngine::seq_waterdeepEntry() {
-	if (shouldQuit() || skipFlag())
-		return;
-
-	uint8 *shp[4];
-	uint8 *shp2[31];
-	uint8 *shp3[3];
-
-	loadSetIntroPalette(_introFilesWdEntry[0]);
-	_screen->loadBitmap(_introFilesWdEntry[1], 5, 3, 0);
-	_screen->setCurPage(2);
-	shp[3] = _screen->encodeShape(0, 0, 20, 136, true);
-	for (int i = 1; i < 4; i++) {
-		copyBlurRegion(0, 0, 0, 0, 160, 136, i);
-		shp[3 - i] = _screen->encodeShape(0, 0, 20, 136, true);
-	}
-	_screen->setCurPage(0);
-
-	_screen->copyPage(3, 4);
-	_screen->fillRect(0, 168, 319, 199, 12, 0);
-	_sound->playTrack(6);
-
-	for (int i = 0; i < 4 && !shouldQuit() && !skipFlag(); i++) {
-		uint32 end = _system->getMillis() + 3 * _tickLength;
-		_screen->drawShape(0, shp[i], 80, 24, 0);
-		delete[] shp[i];
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	_screen->copyRegion(0, 80, 0, 168, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
-	_screen->updateScreen();
-	delay(50 * _tickLength);
-
-	_screen->setCurPage(2);
-	shp[0] = _screen->encodeShape(20, 0, 20, 136, true);
-	_screen->loadBitmap(_introFilesWdEntry[2], 5, 3, 0);
-	shp[1] = _screen->encodeShape(0, 0, 20, 136, true);
-	shp[2] = _screen->encodeShape(20, 0, 20, 136, true);
-	_screen->loadBitmap(_introFilesWdEntry[3], 5, 3, 0);
-
-	for (int i = 0; i < 31; i++)
-		shp2[i] = _screen->encodeShape(_introWdEncodeX[i], 136 + (_introWdEncodeY[i] << 3), _introWdEncodeWH[i], _introWdEncodeWH[i] << 3, true);
-	for (int i = 0; i < 3; i++)
-		shp3[i] = _screen->encodeShape(5 * i, 152, 5, 32, true);
-
-	_screen->copyPage(3, 4);
-
-	for (int i = 0; i < 3 && !shouldQuit() && !skipFlag(); i++) {
-		uint32 end = _system->getMillis() + 3 * _tickLength;
-		_screen->fillRect(0, 0, 159, 135, 12, 2);
-		_screen->drawShape(2, shp[i], 0, 0, 0);
-		_screen->copyRegion(0, 0, 80, 24, 160, 136, 2, 0, Screen::CR_NO_P_CHECK);
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	_screen->copyRegion(0, 0, 80, 24, 160, 136, 4, 0, Screen::CR_NO_P_CHECK);
-	_screen->updateScreen();
-	delay(4 * _tickLength);
-	_screen->copyRegion(160, 0, 80, 24, 160, 136, 4, 0, Screen::CR_NO_P_CHECK);
-	_screen->fillRect(0, 168, 319, 199, 12, 0);
-	_screen->updateScreen();
-	delay(4 * _tickLength);
-	_screen->copyRegion(0, 184, 40, 184, 232, 16, 4, 0, Screen::CR_NO_P_CHECK);
-
-	int cx = 264;
-	int cy = 11;
-
-	for (int i = 0; i < 70 && !shouldQuit() && !skipFlag(); i++) {
-		uint32 end = _system->getMillis() + 3 * _tickLength;
-
-		_screen->copyRegion(cx - 2, cy - 2, 0, 0, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
-		_screen->drawShape(4, shp3[((i & 3) == 3) ? 1 : (i & 3)], cx, cy, 0);
-		_screen->copyRegion(cx - 2, cy - 2, cx - 82, cy + 22, 48, 36, 4, 0, Screen::CR_NO_P_CHECK);
-		_screen->copyRegion(0, 0, cx - 2, cy - 2, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
-		cx--;
-		cy++;
-
-		for (int ii = 0; ii < 5; ii++) {
-			int s = _rnd.getRandomNumber(255) % 31;
-			_screen->drawShape(0, shp2[s], _introWdDsX[s] - 80, _introWdDsY[s] + 24, 0);
-		}
-
-		if (!(_rnd.getRandomNumber(255) & 7))
-			_sound->playTrack(_rnd.getRandomBit() ? 5 : 14);
-
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	for (int i = 0; i < 3; i++) {
-		delete[] shp[i];
-		delete[] shp3[i];
-	}
-
-	for (int i = 0; i < 31; i++)
-		delete[] shp2[i];
-}
-
-void EobEngine::seq_king() {
-	if (shouldQuit() || skipFlag())
-		return;
-
-	_screen->loadBitmap(_introFilesKing[0], 5, 3, 0);
-	_screen->copyPage(3, 4);
-
-	int x = 15;
-	int y = 14;
-	int w = 1;
-	int h = 1;
-
-	for (int i = 0; i < 10 && !shouldQuit() && !skipFlag(); i++) {
-		uint32 end = _system->getMillis() + _tickLength;
-		_screen->copyRegion(x << 3, y << 3, x << 3, y << 3, w << 3, h << 3, 4, 0, Screen::CR_NO_P_CHECK);
-		if (x > 6)
-			x --;
-		if (y > 0)
-			y -= 2;
-		w += 3;
-		if (x + w > 34)
-			w = 34 - x;
-		h += 3;
-		if (y + h > 23)
-			h = 23 - y;
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	delay(25 * _tickLength);
-
-	uint8 *shp[4];
-	int16 dy[4];
-	int16 stepY[4];
-
-	static const uint8 advEncX[] = { 0, 6, 12, 19 };
-	static const uint8 advEncW[] = { 6, 6, 7, 6 };
-	static const int8 modY[] = { -4, -8, -2, -2, 1, 0, 0, 0 };
-
-	_screen->loadBitmap(_introFilesKing[1], 5, 3, 0);
-	_screen->setCurPage(2);
-	for (int i = 0; i < 4; i++) {
-		shp[i] = _screen->encodeShape(advEncX[i], 0, advEncW[i], 98, true);
-		dy[i] = 180 + ((_rnd.getRandomNumber(255) & 3) << 3);
-		stepY[i] = (i * 5) & 3;
-	}
-
-	_screen->copyPage(0, 4);
-
-	for (bool runloop = true; runloop && !shouldQuit() && !skipFlag(); ) {
-		runloop = false;
-		uint32 end = _system->getMillis() + 2 * _tickLength;
-
-		for (int i = 0; i < 4; i++) {
-			if (dy[i] <= 82)
-				continue;
-			stepY[i] = (stepY[i] + 1) & 7;
-			dy[i] += modY[stepY[i]];
-
-			if (dy[i] < 82)
-				dy[i] = 82;
-
-			if (dy[i] < 180) {
-				_screen->copyRegion((advEncX[i] + 8) << 3, dy[i] - 2, 0, dy[i] - 2, advEncW[i] << 3, 182 - dy[i], 4, 4, Screen::CR_NO_P_CHECK);
-				_screen->drawShape(4, shp[i], 0, dy[i], 0);
-				_screen->copyRegion(0, dy[i] - 2, (advEncX[i] + 8) << 3, dy[i] - 2, advEncW[i] << 3, 182 - dy[i], 4, 0, Screen::CR_NO_P_CHECK);
-			}
-
-			if (_rnd.getRandomNumber(255) & 3)
-				_sound->playTrack(7);
-
-			runloop = true;
-		}
-
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	_screen->copyRegion(0, 96, 0, 160, 320, 32, 6, 0, Screen::CR_NO_P_CHECK);
-	_screen->updateScreen();
-	delay(70 * _tickLength);
-
-	for (int i = 0; i < 4; i++)
-		delete[] shp[i];
-}
-
-void EobEngine::seq_hands() {
-	if (shouldQuit() || skipFlag())
-		return;
-
-	_screen->setCurPage(2);
-	uint8 *shp1 = _screen->encodeShape(0, 140, 21, 60, true);
-	uint8 *shp2 = _screen->encodeShape(21, 140, 12, 60, true);
-	_screen->loadBitmap(_introFilesHands[0], 3, 5, 0);
-
-	_screen->fillRect(0, 160, 319, 199, 12, 0);
-	_screen->fillRect(0, 0, 191, 63, 157, 2);
-	_screen->drawShape(2, shp1, 0, 4, 0);
-	_screen->drawShape(2, shp2, 151, 4, 0);
-	boxMorphTransition(25, 8, 18, 4, 3, 0, 21, 8, 6, 0, 28, 23);
-	_screen->copyRegion(0, 128, 0, 176, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
-
-	_screen->updateScreen();
-	delay(15 * _tickLength);
-	_sound->playTrack(11);
-
-	for (int i = -22; i <= 20 && !shouldQuit() && !skipFlag(); i += 4) {
-		uint32 end = _system->getMillis() + _tickLength;
-		_screen->fillRect(0, 0, 167, 63, 157);
-		_screen->drawShape(2, shp1, i, 4, 0);
-		_screen->drawShape(2, shp1, 105 - i, 4, 0);
-		_screen->copyRegion(0, 0, 144, 32, 168, 64, 2, 0, Screen::CR_NO_P_CHECK);
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	_sound->playTrack(10);
-
-	delete[] shp1;
-	delete[] shp2;
-	delay(15 * _tickLength);
-
-	_screen->setCurPage(4);
-	shp1 = _screen->encodeShape(17, 0, 11, 120, true);
-	shp2 = _screen->encodeShape(28, 112, 1, 31, true);
-	uint8 *shp3 = _screen->encodeShape(9, 138, 14, 54, true);
-
-	_screen->setCurPage(2);
-	_screen->fillRect(0, 0, 135, 63, 157);
-	_screen->drawShape(2, shp1, 32, -80, 0);
-	_screen->drawShape(2, shp2, 40, -16, 0);
-	boxMorphTransition(18, 16, 10, 12, 0, 0, 17, 8, 17, 3, 25, 10);
-	delay(15 * _tickLength);
-
-	for (int i = -80; i <= 0 && !shouldQuit() && !skipFlag(); i += 4) {
-		uint32 end = _system->getMillis() + _tickLength;
-		_screen->fillRect(0, 0, 135, 63, 157);
-		_screen->drawShape(2, shp1, 32, i, 0);
-		_screen->drawShape(2, shp2, 40, i + 64, 0);
-		_screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK);
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	_sound->playTrack(12);
-	delay(5 * _tickLength);
-
-	for (int i = 0; i > -54 && !shouldQuit() && !skipFlag(); i -= 4) {
-		uint32 end = _system->getMillis() + _tickLength;
-		_screen->fillRect(0, 0, 135, 63, 157);
-		_screen->drawShape(2, shp3, 12, 64 + i, 0);
-		_screen->drawShape(2, shp1, 32, i, 0);
-		_screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK);
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	delete[] shp1;
-	delete[] shp2;
-	delete[] shp3;
-	delay(15 * _tickLength);
-
-	_screen->setCurPage(4);
-	shp1 = _screen->encodeShape(0, 0, 17, 136, true);
-	shp2 = _screen->encodeShape(0, 136, 9, 48, true);
-
-	_screen->setCurPage(2);
-	_screen->fillRect(0, 0, 143, 95, 157);
-	_screen->drawShape(2, shp1, -56, -56, 0);
-	_screen->drawShape(2, shp2, 52, 49, 0);
-	boxMorphTransition(9, 6, 0, 0, 0, 0, 18, 12, 8, 11, 21, 10);
-	delay(15 * _tickLength);
-	_sound->playTrack(11);
-
-	for (int i = -56; i <= -8 && !shouldQuit() && !skipFlag(); i += 4) {
-		uint32 end = _system->getMillis() + _tickLength;
-		_screen->fillRect(0, 0, 143, 95, 157);
-		_screen->drawShape(2, shp1, i, i, 0);
-		_screen->drawShape(2, shp2, (i == -8) ? 55 : 52, (i == -8) ? 52 : 49, 0);
-		_screen->copyRegion(0, 0, 0, 0, 144, 96, 2, 0, Screen::CR_NO_P_CHECK);
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	_sound->playTrack(10);
-	delete[] shp1;
-	delete[] shp2;
-	delay(30 * _tickLength);
-
-	_screen->setCurPage(4);
-	shp1 = _screen->encodeShape(28, 0, 11, 40, true);
-	shp2 = _screen->encodeShape(28, 40, 10, 72, true);
-
-	_screen->setCurPage(2);
-	_screen->fillRect(0, 0, 87, 112, 157);
-	_screen->drawShape(2, shp2, 0, 90, 0);
-	boxMorphTransition(20, 13, 15, 6, 0, 0, 11, 14, 0, 0, 24, 16);
-	delay(15 * _tickLength);
-
-	int dy = 90;
-	for (int i = -40; i <= 0 && !shouldQuit() && !skipFlag(); i += 4) {
-		uint32 end = _system->getMillis() + _tickLength;
-		_screen->fillRect(0, 0, 87, 112, 157);
-		_screen->drawShape(2, shp2, 0, dy, 0);
-		_screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK);
-		_screen->updateScreen();
-		delayUntil(end);
-		dy -= 5;
-	}
-
-	_sound->playTrack(13);
-
-	for (int i = -40; i <= 0 && !shouldQuit() && !skipFlag(); i += 4) {
-		uint32 end = _system->getMillis() + _tickLength;
-		_screen->fillRect(0, 0, 87, 39, 157);
-		_screen->drawShape(2, shp1, 0, i, 0);
-		_screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK);
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	delete[] shp1;
-	delete[] shp2;
-	delay(48 * _tickLength);
-}
-
-void EobEngine::seq_waterdeepExit() {
-	if (shouldQuit() || skipFlag())
-		return;
-
-	uint8 *shp2[31];
-	uint8 *shp3[3];
-
-	_screen->loadBitmap(_introFilesWdExit[0], 5, 3, 0);
-	_screen->setCurPage(2);
-	for (int i = 0; i < 31; i++)
-		shp2[i] = _screen->encodeShape(_introWdEncodeX[i], 136 + (_introWdEncodeY[i] << 3), _introWdEncodeWH[i], _introWdEncodeWH[i] << 3, true);
-	for (int i = 0; i < 3; i++)
-		shp3[i] = _screen->encodeShape(5 * i + 15, 152, 5, 32, true);
-	uint8 *shp1 = _screen->encodeShape(31, 136, 5, 32, true);
-	_screen->copyPage(3, 4);
-	_screen->copyRegion(0, 0, 0, 136, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
-	_screen->fillRect(0, 168, 319, 199, 12, 0);
-	_screen->copyRegion(160, 0, 80, 24, 160, 136, 4, 0, Screen::CR_NO_P_CHECK);
-
-	int cx = 140;
-	int cy = 128;
-
-	for (int i = 0; i < 70 && !shouldQuit() && !skipFlag(); i++) {
-		uint32 end = _system->getMillis() + 3 * _tickLength;
-		int fx = cx - 2;
-		if (fx < 160)
-			fx = 160;
-		int fy = cy - 2;
-		if (fy > 98)
-			fy = 98;
-
-		_screen->copyRegion(fx, fy, 0, 0, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
-		_screen->drawShape(4, shp3[((i & 3) == 3) ? 1 : (i & 3)], cx, cy, 0);
-		_screen->drawShape(4, shp1, 160, 104, 0);
-		_screen->copyRegion(fx, fy, fx - 80, fy + 24, 48, 36, 4, 0, Screen::CR_NO_P_CHECK);
-		_screen->copyRegion(0, 0, fx, fy, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
-		cx++;
-		cy--;
-
-		for (int ii = 0; ii < 5; ii++) {
-			int s = _rnd.getRandomNumber(255) % 31;
-			_screen->drawShape(0, shp2[s], _introWdDsX[s] - 80, _introWdDsY[s] + 24, 0);
-		}
-
-		if (!(_rnd.getRandomNumber(255) & 7))
-			_sound->playTrack(_rnd.getRandomBit() ? 5 : 14);
-
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	for (int i = 0; i < 3; i++)
-		delete[] shp3[i];
-
-	for (int i = 0; i < 31; i++)
-		delete[] shp2[i];
-	delete[] shp1;
-
-	_screen->setCurPage(0);
-	_screen->fillRect(0, 168, 319, 199, 12, 0);
-	_screen->copyRegion(0, 136, 0, 0, 48, 36, 0, 4, Screen::CR_NO_P_CHECK);
-
-	loadSetIntroPalette(_introFilesWdExit[1]);
-	_screen->loadBitmap(_introFilesWdExit[2], 3, 5, 0);
-	_screen->copyPage(5, 2);
-	whirlTransition();
-	delay(6 * _tickLength);
-
-	_screen->copyRegion(0, 144, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
-
-	cx = 0;
-	cy = 136;
-	int dy = 0;
-	for (int i = 0; i < 19 && !shouldQuit() && !skipFlag(); i++) {
-		uint32 end = _system->getMillis() + _tickLength;
-		_screen->copyRegion(cx, cy, 80, dy + 16, 160, 8, 2, 0, Screen::CR_NO_P_CHECK);
-		cy += 8;
-		dy += 8;
-		if (i == 6) {
-			cx = 160;
-			cy = 0;
-		}
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	_sound->playTrack(3);
-	delay(60 * _tickLength);
-
-	for (int i = 0; i < 56 && !shouldQuit() && !skipFlag(); i++) {
-		uint32 end = _system->getMillis() + _tickLength;
-		_screen->copyRegion(0, 136 + i, 80, 16, 160, 56 - i, 2, 0, Screen::CR_NO_P_CHECK);
-		_screen->copyRegion(160, 0, 80, 72 - i, 160, 96 + i, 2, 0, Screen::CR_NO_P_CHECK);
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	for (int i = 1; i < 48 && !shouldQuit() && !skipFlag(); i++) {
-		uint32 end = _system->getMillis() + _tickLength;
-		_screen->copyRegion(160, i, 80, 16, 160, 152, 2, 0, Screen::CR_NO_P_CHECK);
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	_screen->loadBitmap(_introFilesWdExit[3], 3, 5, 0);
-	_screen->copyPage(5, 2);
-	delay(30 * _tickLength);
-	_screen->setCurPage(0);
-	_screen->fillRect(0, 16, 319, 31, 12);
-	_screen->fillRect(0, 136, 319, 199, 12);
-	_screen->copyRegion(0, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
-	loadSetIntroPalette(_introFilesWdExit[4]);
-	_screen->updateScreen();
-	delay(50 * _tickLength);
-}
-
-void EobEngine::seq_tunnel() {
-	if (shouldQuit() || skipFlag())
-		return;
-
-	_screen->setCurPage(4);
-	uint8 *shp2 = _screen->encodeShape(20, 0, 20, 120, true);
-	uint8 *shp1 = _screen->encodeShape(0, 0, 20, 120, true);
-	drawBlockObject(1, 4, shp2, 160, 0, 0);
-	drawBlockObject(1, 4, shp1, 0, 0, 0);
-	delete[] shp1;
-	delete[] shp2;
-
-	for (int i = 0; i < 3 && !shouldQuit() && !skipFlag(); i++) {
-		uint32 end = _system->getMillis() + 8 * _tickLength;
-		_screen->copyRegion(0, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
-		_sound->playTrack(7);
-		_screen->updateScreen();
-		delayUntil(end);
-		_screen->copyRegion(0, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
-		_sound->playTrack(7);
-		end = _system->getMillis() + 8 * _tickLength;
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	_screen->copyRegion(0, 160, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
-	_screen->updateScreen();
-	delay(18 * _tickLength);
-	_screen->copyRegion(160, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
-	_screen->updateScreen();
-	delay(5 * _tickLength);
-	_screen->copyRegion(0, 122, 80, 32, 160, 60, 2, 0, Screen::CR_NO_P_CHECK);
-	_screen->copyRegion(160, 122, 80, 92, 160, 60, 2, 0, Screen::CR_NO_P_CHECK);
-	_screen->updateScreen();
-	delay(5 * _tickLength);
-	_screen->copyRegion(160, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
-	for (int i = 0; i < 6; i++)
-		_screen->copyRegion(i * 48, 185, 56, (i << 3) + 24, 48, 8, 2, 2, Screen::CR_NO_P_CHECK);
-	_screen->updateScreen();
-	delay(5 * _tickLength);
-	_screen->copyRegion(0, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
-
-	_screen->loadBitmap(_introFilesTunnel[0], 5, 3, 0);
-	_screen->copyPage(3, 4);
-	_screen->updateScreen();
-	delay(40 * _tickLength);
-
-	_screen->copyRegion(264, 0, 136, 56, 48, 48, 4, 0, Screen::CR_NO_P_CHECK);
-	_sound->playTrack(8);
-	_screen->copyRegion(0, 0, 0, 0, 320, 184, 0, 2, Screen::CR_NO_P_CHECK);
-	_screen->updateScreen();
-	delay(16 * _tickLength);
-	_sound->playTrack(4);
-
-	for (int i = 0; i < 30 && !shouldQuit() && !skipFlag(); i++) {
-		uint32 end = _system->getMillis() + _tickLength;
-		if (i == 0)
-			_screen->fillRect(0, 168, 319, 199, 12, 0);
-		_screen->copyRegion(80, 25 + (_rnd.getRandomNumber(255) & 7), 80, 24, 160, 144, 2, 0, Screen::CR_NO_P_CHECK);
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-
-	_sound->playTrack(9);
-
-	for (int i = 0; i < 6 && !shouldQuit() && !skipFlag(); i++) {
-		uint32 end = _system->getMillis() + _tickLength;
-		_screen->copyRegion(_introTvlX1[i] << 3, _introTvlY1[i], _introTvlX2[i] << 3, _introTvlY2[i], _introTvlW[i] << 3, _introTvlH[i], 4, 2, Screen::CR_NO_P_CHECK);
-		for (int ii = 0; ii < 4 && !shouldQuit() && !skipFlag(); ii++) {
-			_screen->updateScreen();
-			delayUntil(end);
-			end = _system->getMillis() + _tickLength;
-			_screen->copyRegion(80, 25 + (_rnd.getRandomNumber(255) & 7), 80, 24, 160, 144, 2, 0, Screen::CR_NO_P_CHECK);
-		}
-	}
-	_screen->copyRegion(0, 0, 0, 0, 320, 168, 2, 0, Screen::CR_NO_P_CHECK);
-	_screen->updateScreen();
-	delay(40 * _tickLength);
-
-	_screen->loadBitmap(_introFilesTunnel[1], 5, 3, 0);
-	_screen->copyPage(3, 4);
-	_sound->playTrack(6);
-	_screen->copyRegion(0, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
-	_screen->updateScreen();
-	delay(2 * _tickLength);
-	_screen->copyRegion(160, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
-	_screen->updateScreen();
-	delay(2 * _tickLength);
-	_screen->copyRegion(0, 120, 80, 30, 160, 64, 4, 0, Screen::CR_NO_P_CHECK);
-	_screen->copyRegion(160, 120, 80, 94, 160, 64, 4, 0, Screen::CR_NO_P_CHECK);
-	_screen->copyRegion(0, 176, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
-	_screen->setCurPage(0);
-	_screen->updateScreen();
-	delay(50 * _tickLength);
-}
-
-void EobEngine::seq_xdeath() {
-	uint8 *shapes1[5];
-	uint8 *shapes2;
-
-	_screen->loadShapeSetBitmap("XDEATH2", 5, 3);
-	for (int i = 0; i < 4; i++)
-		shapes1[i] = _screen->encodeShape(i / 2 * 14, i / 2 * 88, 14, 88, true);
-	_screen->loadShapeSetBitmap("XDEATH3", 5, 3);
-	shapes2 = _screen->encodeShape(22, 0, 16, 95, true);
-	_screen->loadEobBitmap("XDEATH1", 0, 5, 3, -1);
-	_screen->setCurPage(0);
-
-	for (int i = 0; i < 10; i++) {
-		if (i == 2)
-			snd_playSoundEffect(72);
-		else if (i == 4 || i == 6)
-			snd_playSoundEffect(54);
-		else
-			snd_playSoundEffect(34);
-
-		if (i < 6) {
-			_screen->copyRegion((i % 3) * 104, i / 3 * 88, 32, 10, 104, 88, 2, 0, Screen::CR_NO_P_CHECK);
-		} else {
-			snd_playSoundEffect(42);
-			_screen->drawShape(0, shapes1[i - 6], 32, 10, 0);
-		}
-
-		_screen->updateScreen();
-		delay(4 * _tickLength);
-	}
-
-	const ScreenDim *dm = _screen->getScreenDim(5);
-	_screen->modifyScreenDim(5, dm->sx, 8, dm->w, dm->h);
-	_screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 5, Screen::CR_NO_P_CHECK);
-
-	for (int i = 0; i < 19; i++) {
-		snd_playSoundEffect(119);
-		_screen->copyRegion(0, 0, 0, 0, 176, 120, 5, 2, Screen::CR_NO_P_CHECK);
-		_screen->drawShape(2, shapes2, 24, i * 5 - 90, 5);
-		_screen->copyRegion(0, 0, 0, 0, 176, 120, 2, 0, Screen::CR_NO_P_CHECK);
-		_screen->updateScreen();
-		delay(2 * _tickLength);
-	}
-
-	_screen->modifyScreenDim(5, dm->sx, 0, dm->w, dm->h);
-
-	snd_playSoundEffect(5);
-	delay(60 * _tickLength);
-
-	for (int i = 0; i < 4; i++)
-		delete[] shapes1[i];
-	delete[] shapes2;
-
-	gui_drawPlayField(false);
-	gui_drawAllCharPortraitsWithStats();
-}
-
-void EobEngine::loadSetIntroPalette(const char *filename) {
-	_screen->loadPalette(filename, _screen->getPalette(0));
-	_screen->getPalette(0).fill(0, 1, 0);
-	_screen->setScreenPalette(_screen->getPalette(0));
-}
-
-void EobEngine::copyBlurRegion(int x1, int y1, int x2, int y2, int w, int h, int step) {
-	const uint8 *ptr2 = _screen->getCPagePtr(3) + y1 * 320 + x1;
-
-	if (step == 1) {
-		while (h > 0) {
-			int dx = x2;
-			for (int i = 0; i < w; i += 2) {
-				_screen->setPagePixel(3, dx++, y2, ptr2[i]);
-				_screen->setPagePixel(3, dx++, y2, 0);
-			}
-			dx = x2;
-			y2++;
-			ptr2 += 320;
-			for (int i = 0; i < w; i += 2) {
-				_screen->setPagePixel(3, dx++, y2, 0);
-				_screen->setPagePixel(3, dx++, y2, ptr2[i + 1]);
-			}
-			y2++;
-			ptr2 += 320;
-			h -= 2;
-		}
-	} else if (step == 2) {
-		while (h > 0) {
-			int dx = x2;
-			for (int i = 0; i < w; i += 2) {
-				_screen->setPagePixel(3, dx++, y2, ptr2[i]);
-				_screen->setPagePixel(3, dx++, y2, 0);
-			}
-			dx = x2;
-			y2++;
-			ptr2 += 320;
-			for (int i = 0; i < w; i++)
-				_screen->setPagePixel(3, dx++, y2, 0);
-
-			y2++;
-			ptr2 += 320;
-			h -= 2;
-		}
-	} else if (step == 3) {
-		for (int i = 0; i < h; i++) {
-			int dx = x2;
-			if ((i % 3) == 0) {
-				int ii = 0;
-				for (; ii < w - 3; ii += 3) {
-					_screen->setPagePixel(3, dx++, y2, ptr2[ii]);
-					_screen->setPagePixel(3, dx++, y2, 0);
-					_screen->setPagePixel(3, dx++, y2, 0);
-				}
-				for (; ii < w; ii++)
-					_screen->setPagePixel(3, dx++, y2, 0);
-			} else {
-				for (int ii = 0; ii < w; ii++)
-					_screen->setPagePixel(3, dx++, y2, 0);
-			}
-			y2++;
-			ptr2 += 320;
-		}
-	}
-}
-
-void EobEngine::boxMorphTransition(int targetDestX, int targetDestY, int targetFinalX, int targetFinalY, int targetSrcX, int targetSrcY, int targetFinalW, int targetFinalH, int originX1, int originY1, int originW, int originH) {
-	int originX2 = originX1 + originW;
-	int originY2 = originY1 + originH;
-	if (originY2 > 21)
-		originY2 = 21;
-
-	int w = 1;
-	int h = 1;
-	for (bool runloop = true; runloop && !shouldQuit() && !skipFlag(); ) {
-		uint32 end = _system->getMillis() + _tickLength;
-		_screen->copyRegion(targetSrcX << 3, targetSrcY << 3, targetDestX << 3, targetDestY << 3, w << 3, h << 3, 2, 0, Screen::CR_NO_P_CHECK);
-		if (originX1 < targetDestX)
-			_screen->copyRegion(312, 0, originX1 << 3, 0, 8, 176, 0, 0, Screen::CR_NO_P_CHECK);
-		if (originY1 < targetDestY)
-			_screen->copyRegion(0, 192, 0, originY1 << 3, 320, 8, 0, 0, Screen::CR_NO_P_CHECK);
-		if ((targetFinalX + targetFinalW) <= originX2)
-			_screen->copyRegion(312, 0, originX2 << 3, 0, 8, 176, 0, 0, Screen::CR_NO_P_CHECK);
-		if ((targetFinalY + targetFinalH) <= originY2)
-			_screen->copyRegion(0, 192, 0, originY2 << 3, 320, 8, 0, 0, Screen::CR_NO_P_CHECK);
-
-		if (!(targetDestX != targetFinalX || targetDestY != targetFinalY || w != targetFinalW || h != targetFinalH || originX1 < targetFinalX || originY1 < targetFinalY || (targetFinalX + targetFinalW) < originX2 || (targetFinalY + targetFinalH) < originY2))
-			runloop = false;
-
-		int v = targetFinalX - targetDestX;
-		v = (v < 0) ? -1 : ((v > 0) ? 1 : 0);
-		targetDestX += v;
-		v = targetFinalY - targetDestY;
-		v = (v < 0) ? -1 : ((v > 0) ? 1 : 0);
-		targetDestY += v;
-
-		if (w != targetFinalW)
-			w += 2;
-		if (w > targetFinalW)
-			w = targetFinalW;
-
-		if (h != targetFinalH)
-			h += 2;
-		if (h > targetFinalH)
-			h = targetFinalH;
-
-		if (++originX1 > targetFinalX)
-			originX1 = targetFinalX;
-
-		if (++originY1 > targetFinalY)
-			originY1 = targetFinalY;
-
-		if ((targetFinalX + targetFinalW) < originX2)
-			originX2--;
-
-		if ((targetFinalY + targetFinalH) < originY2)
-			originY2--;
-
-		_screen->updateScreen();
-		delayUntil(end);
-	}
-}
-
-void EobEngine::whirlTransition() {
-	for (int i = 0; i < 2; i++) {
-		for (int ii = 0; ii < 8; ii++) {
-			uint32 e = _system->getMillis() + 3;
-			if (ii & 1) {
-				for (int iii = i + ii; iii < 320; iii += 8)
-					_screen->drawClippedLine(iii, 0, iii, 199, 12);
-			} else {
-				for (int iii = i + ii; iii < 200; iii += 8)
-					_screen->drawClippedLine(0, iii, 319, iii, 12);
-			}
-			_screen->updateScreen();
-			uint32 c = _system->getMillis();
-			if (e > c)
-				_system->delayMillis(e - c);
-		}
-	}
-}
-
-}	// End of namespace Kyra
-
-#endif // ENABLE_EOB
diff --git a/engines/kyra/sequences_eob2.cpp b/engines/kyra/sequences_eob2.cpp
deleted file mode 100644
index 433ee4a..0000000
--- a/engines/kyra/sequences_eob2.cpp
+++ /dev/null
@@ -1,1349 +0,0 @@
-/* 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.
- *
- */
-
-#ifdef ENABLE_EOB
-
-#include "kyra/eob2.h"
-#include "kyra/screen_eob.h"
-#include "kyra/resource.h"
-#include "kyra/sound.h"
-
-#include "common/system.h"
-
-#include "base/version.h"
-
-namespace Kyra {
-
-class DarkmoonSequenceHelper {
-friend class DarkMoonEngine;
-public:
-	enum Mode {
-		kIntro,
-		kFinale
-	};
-
-	DarkmoonSequenceHelper(OSystem *system, DarkMoonEngine *vm, Screen_Eob *screen, Mode mode, const char *const *strings, const char *const *cpsFiles, const char *const *palFiles, const EobShapeDef **shapeDefList, const EobSequenceStep **seqList);
-	~DarkmoonSequenceHelper();
-
-	void loadScene(int index, int pageNum);
-	void runSequence(int index, int del = -1);
-
-	void printText(int index, int color);
-	void fadeText();
-
-	void update(int srcPage);
-
-	void setPalette(int index);
-	void fadePalette(int index, int del);
-	void copyPalette(int srcIndex, int destIndex);
-
-	void initDelayedPaletteFade(int palIndex, int rate);
-	bool processDelayedPaletteFade();
-
-	void delay(uint32 ticks);
-	void waitForSongNotifier(int index, bool introUpdateAnim = false);
-
-private:
-	void setPaletteWithoutTextColor(int index);
-
-	OSystem *_system;
-	DarkMoonEngine *_vm;
-	Screen_Eob *_screen;
-	Mode _mode;
-
-	const char *const *_strings;
-	const char *const *_cpsFiles;
-	const char *const *_palFiles;
-	const EobShapeDef **_shapeDefs;
-	const EobSequenceStep **_seqData;
-
-	Palette *_palettes[12];
-
-	const uint8 **_shapes;
-
-	uint32 _fadePalTimer;
-	int _fadePalRate;
-	int _fadePalIndex;
-};
-
-int DarkMoonEngine::mainMenu() {
-	int menuChoice = _menuChoiceInit;
-	_menuChoiceInit = 0;
-
-	_sound->loadSoundFile("INTRO");
-	Screen::FontId of = _screen->_currentFont;
-	int op = 0;
-	Common::SeekableReadStream *s = 0;
-
-	while (menuChoice >= 0 && !shouldQuit()) {
-		switch (menuChoice) {
-			case 0:
-				s = _res->createReadStream("XENU.CPS");
-				if (s) {
-					s->read(_screen->getPalette(0).getData(), 768);
-					_screen->loadFileDataToPage(s, 3, 64000);
-					delete s;
-				} else {
-					_screen->loadBitmap("MENU.CPS", 3, 2, &_screen->getPalette(0));
-				}
-
-				_screen->setScreenPalette(_screen->getPalette(0));
-
-				of = _screen->setFont(Screen::FID_6_FNT);
-				op = _screen->setCurPage(2);
-				_screen->printText(gScummVMVersion, 267 - strlen(gScummVMVersion) * 6, 160, 13, 0);
-				_screen->setFont(of);
-				_screen->_curPage = op;
-				_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
-				_screen->updateScreen();
-				menuChoice = mainMenuLoop();
-				break;
-
-			case 1:
-				// load game in progress
-				menuChoice = -1;
-				break;
-
-			case 2:
-				// create new party
-				menuChoice = -2;
-				break;
-
-			case 3:
-				// transfer party
-				//seq_playFinale();
-				menuChoice = -3;
-				break;
-
-			case 4:
-				// play intro
-				seq_playIntro();
-				menuChoice = 0;
-				break;
-
-			case 5:
-				// quit
-				menuChoice = -5;
-				break;
-		}
-	}
-
-	return shouldQuit() ? -5 : menuChoice;
-}
-
-int DarkMoonEngine::mainMenuLoop() {
-	int sel = -1;
-	do {
-		_screen->setScreenDim(6);
-		_gui->simpleMenu_setup(6, 0, _mainMenuStrings, -1, 0, 0);
-
-		while (sel == -1 && !shouldQuit())
-			sel = _gui->simpleMenu_process(6, _mainMenuStrings, 0, -1, 0);
-	} while ((sel < 0 || sel > 5) && !shouldQuit());
-
-	return sel + 1;
-}
-
-void DarkMoonEngine::seq_playIntro() {
-	DarkmoonSequenceHelper sq(_system, this, _screen, DarkmoonSequenceHelper::kIntro, _introStrings, _cpsFilesIntro, _palFilesIntro, _shapesIntro, _seqIntro);
-
-	_screen->setCurPage(0);
-	_screen->clearCurPage();
-
-	snd_stopSound();
-
-	sq.loadScene(4, 2);
-	sq.loadScene(0, 2);
-	sq.delay(1);
-
-	if (!skipFlag() && !shouldQuit())
-		_sound->playTrack(12);
-
-	_screen->copyRegion(0, 0, 8, 8, 304, 128, 2, 0, Screen::CR_NO_P_CHECK);
-	sq.setPalette(9);
-	sq.fadePalette(0, 3);
-
-	_screen->setCurPage(2);
-	_screen->setClearScreenDim(17);
-	_screen->setCurPage(0);
-
-	removeInputTop();
-	sq.delay(18);
-
-	sq.runSequence(3, 18);
-	sq.runSequence(6, 18);
-	sq.runSequence(0);
-
-	sq.waitForSongNotifier(1);
-
-	sq.runSequence(11);
-	sq.runSequence(7, 6);
-	sq.runSequence(2, 6);
-
-	sq.waitForSongNotifier(2);
-
-	sq.runSequence(38);
-	sq.runSequence(3);
-	sq.runSequence(8);
-	sq.runSequence(1, 10);
-	sq.runSequence(0, 6);
-	sq.runSequence(2);
-
-	sq.waitForSongNotifier(3);
-
-	_screen->setClearScreenDim(17);
-	_screen->setCurPage(2);
-	_screen->setClearScreenDim(17);
-	_screen->setCurPage(0);
-
-	sq.runSequence(40);
-	sq.runSequence(7, 18);
-
-	sq.printText(0, 16);	// You were settling...
-	sq.runSequence(7, 90);
-	sq.fadeText();
-
-	sq.printText(1, 16);	// Then a note was slipped to you
-	sq.runSequence(8);
-	sq.runSequence(2, 72);
-	sq.fadeText();
-
-	sq.printText(2, 16);	// It was from your friend Khelben Blackstaff...
-	sq.runSequence(2);
-	sq.runSequence(6, 36);
-	sq.runSequence(3);
-	sq.fadeText();
-
-	sq.printText(3, 16);	// The message was urgent.
-
-	sq.loadScene(1, 2);
-	sq.waitForSongNotifier(4);
-
-	// intro scroll
-	if (!skipFlag() && !shouldQuit()) {
-		for (int i = 0; i < 280; i += 3) {
-			uint32 endtime = _system->getMillis() + _tickLength;
-			_screen->copyRegion(11, 8, 8, 8, 301, 128, 0, 0, Screen::CR_NO_P_CHECK);
-			_screen->copyRegion(i, 0, 309, 8, 3, 128, 2, 0, Screen::CR_NO_P_CHECK);
-			_screen->updateScreen();
-			if (i == 96)
-				sq.runSequence(42);
-			delayUntil(endtime);
-		}
-	}
-
-	_screen->copyRegion(8, 8, 0, 0, 304, 128, 0, 2, Screen::CR_NO_P_CHECK);
-	sq.runSequence(4);
-	sq.fadeText();
-	sq.delay(10);
-
-	sq.loadScene(2, 2);
-	sq.update(2);
-	sq.delay(10);
-
-	sq.printText(4, 16);	// What could Khelben want?
-	sq.delay(25);
-
-	sq.loadScene(3, 2);
-	sq.delay(54);
-	sq.runSequence(13);
-	_screen->copyRegion(104, 16, 96, 8, 120, 100, 0, 2, Screen::CR_NO_P_CHECK);
-	sq.fadeText();
-
-	sq.printText(5, 15);	// Welcome, please come in
-	sq.runSequence(10);
-	sq.runSequence(10);
-	sq.runSequence(9);
-	sq.runSequence(9);
-	sq.fadeText();
-
-	sq.printText(6, 15);	// Khelben awaits you in his study
-	for (int i = 0; i < 3; i++)
-		sq.runSequence(10);
-	sq.runSequence(9);
-	sq.runSequence(14);
-	sq.loadScene(5, 2);
-
-	sq.waitForSongNotifier(5);
-
-	sq.fadeText();
-	_screen->clearCurPage();
-	_screen->updateScreen();
-
-	for (int i = 0; i < 6; i++)
-		sq.runSequence(15);
-
-	sq.loadScene(6, 2);
-	sq.loadScene(7, 2);
-	_screen->clearCurPage();
-	sq.update(2);
-
-	sq.runSequence(16);
-	sq.printText(7, 15);	// Thank you for coming so quickly
-	sq.runSequence(16);
-	sq.runSequence(17);
-	for (int i = 0; i < 3; i++)
-		sq.runSequence(16);
-	sq.fadeText();
-	sq.runSequence(16);
-
-	sq.loadScene(8, 2);
-	sq.update(2);
-	sq.runSequence(32);
-	sq.printText(8, 15);	// I am troubled my friend
-	sq.runSequence(33);
-	sq.runSequence(33);
-	for (int i = 0; i < 4; i++)
-		sq.runSequence(32);
-	sq.fadeText();
-
-	sq.printText(9, 15);	// Ancient evil stirs in the Temple Darkmoon
-	sq.runSequence(33);
-	sq.runSequence(43);
-	sq.runSequence(33);
-	for (int i = 0; i < 3; i++)
-		sq.runSequence(32);
-	sq.fadeText();
-
-	sq.printText(10, 15);	// I fear for the safety of our city
-	for (int i = 0; i < 4; i++)
-		sq.runSequence(33);
-	sq.runSequence(32);
-	sq.runSequence(32);
-
-	sq.loadScene(9, 2);
-	sq.fadeText();
-
-	sq.waitForSongNotifier(6);
-
-	sq.update(2);
-	sq.runSequence(34);
-
-	sq.printText(11, 15);	// I need your help
-	for (int i = 0; i < 3; i++)
-		sq.runSequence(34);
-	sq.runSequence(35);
-	for (int i = 0; i < 4; i++)
-		sq.runSequence(34);
-	sq.fadeText();
-
-	sq.loadScene(12, 2);
-	sq.update(2);
-	sq.loadScene(6, 2);
-	sq.runSequence(18);
-
-	sq.printText(12, 15);	// Three nights ago I sent forth a scout
-	sq.runSequence(19);
-	sq.runSequence(20);
-	sq.runSequence(22);
-	sq.runSequence(19);
-	sq.runSequence(20);
-	sq.runSequence(18);
-	sq.fadeText();
-
-	sq.printText(13, 15);	// She has not yet returned
-	sq.runSequence(20);
-	sq.runSequence(19);
-	sq.runSequence(23);
-	sq.runSequence(24);
-	sq.runSequence(20);
-	sq.runSequence(19);
-	sq.runSequence(17);
-	sq.runSequence(18);
-	sq.fadeText();
-
-	sq.printText(14, 15);	// I fear for her safety
-	sq.runSequence(19);
-	sq.runSequence(20);
-	sq.runSequence(20);
-	sq.runSequence(18);
-	sq.runSequence(25);
-	sq.runSequence(18);
-	sq.runSequence(18);
-	sq.fadeText();
-	sq.runSequence(18);
-	sq.runSequence(18);
-
-	sq.printText(15, 15);	// Take this coin
-	sq.runSequence(28);
-	sq.runSequence(19);
-	sq.runSequence(20);
-	sq.runSequence(18);
-	sq.runSequence(18);
-	sq.fadeText();
-
-	sq.loadScene(10, 2);
-	_screen->clearCurPage();
-	_screen->updateScreen();
-
-	sq.runSequence(37, 18);
-	sq.runSequence(36, 36);
-
-	sq.loadScene(12, 2);
-	_screen->clearCurPage();
-	sq.update(2);
-
-	sq.loadScene(11, 2);
-	sq.printText(16, 15);	// I will use it to contact you
-	sq.runSequence(19);
-	sq.runSequence(20);
-	sq.runSequence(20);
-	sq.runSequence(18);
-	sq.runSequence(18);
-	sq.fadeText();
-
-	sq.printText(17, 15);	// You must act quickly
-	sq.runSequence(19);
-	sq.runSequence(20);
-	sq.runSequence(19);
-	sq.runSequence(18);
-	sq.runSequence(18);
-	sq.fadeText();
-	sq.runSequence(18);
-
-	sq.printText(18, 15);	// I will teleport you near Darkmoon
-	sq.runSequence(20);
-	sq.runSequence(27);
-	sq.runSequence(20);
-	sq.runSequence(19);
-	sq.runSequence(18);
-	sq.runSequence(18);
-	sq.fadeText();
-	sq.runSequence(18);
-
-	sq.printText(19, 15);	// May luck be with you my friend
-	sq.runSequence(19);
-	sq.runSequence(19);
-	sq.runSequence(20);
-	sq.runSequence(18);
-	sq.fadeText();
-	sq.runSequence(29);
-
-	sq.waitForSongNotifier(7);
-
-	sq.runSequence(30);
-	sq.runSequence(31);
-
-	sq.waitForSongNotifier(8, true);
-
-	if (skipFlag() || shouldQuit()) {
-		_sound->playTrack(15);
-	} else {
-		_screen->setScreenDim(17);
-		_screen->clearCurDim();
-		_sound->playTrack(14);
-		sq.fadePalette(10, 1);
-		_screen->setClearScreenDim(18);
-		sq.delay(6);
-		sq.fadePalette(9, 1);
-		_screen->clearCurPage();
-	}
-
-	sq.fadePalette(9, 10);
-}
-
-void DarkMoonEngine::seq_playFinale() {
-	DarkmoonSequenceHelper sq(_system, this, _screen, DarkmoonSequenceHelper::kFinale, _finaleStrings, _cpsFilesFinale, _palFilesFinale, _shapesFinale, _seqFinale);
-
-	_screen->setCurPage(0);
-	_screen->setFont(Screen::FID_8_FNT);
-
-	_sound->loadSoundFile("FINALE1");
-	snd_stopSound();
-	sq.delay(3);
-
-	_screen->clearCurPage();
-	_screen->updateScreen();
-
-	sq.loadScene(0, 2);
-	sq.delay(18);
-
-	if (!skipFlag() && !shouldQuit())
-		_sound->playTrack(1);
-	sq.update(2);
-
-	sq.loadScene(1, 2);
-
-	sq.runSequence(0);
-	sq.runSequence(0);
-	for (int i = 0; i < 3; i++)
-		sq.runSequence(2);
-	sq.runSequence(1);
-	sq.runSequence(2);
-	sq.runSequence(2);
-
-	sq.printText(0, 10);			// Finally, Dran has been defeated
-	for (int i = 0; i < 7; i++)
-		sq.runSequence(2);
-	sq.fadeText();
-	sq.runSequence(2);
-
-	sq.waitForSongNotifier(1);
-
-	sq.printText(1, 10);			// Suddenly, your friend Khelben appears
-	sq.runSequence(4);
-	for (int i = 0; i < 3; i++)
-		sq.runSequence(2);
-	sq.fadeText();
-
-	sq.printText(2, 15);			// Greetings, my victorious friends
-	for (int i = 0; i < 4; i++)
-		sq.runSequence(5);
-	sq.runSequence(2);
-	sq.runSequence(2);
-	sq.fadeText();
-	sq.runSequence(6);
-
-	sq.printText(3, 15);			// You have defeated Dran
-	for (int i = 0; i < 5; i++)
-		sq.runSequence(5);
-	sq.runSequence(2);
-	sq.runSequence(2);
-	sq.fadeText();
-
-	sq.printText(4, 15);			// I did not know Dran was a dragon
-	for (int i = 0; i < 4; i++)
-		sq.runSequence(5);
-	sq.runSequence(2);
-	sq.runSequence(2);
-	sq.fadeText();
-
-	sq.printText(5, 15);			// He must have been over 300 years old
-	for (int i = 0; i < 4; i++)
-		sq.runSequence(5);
-	sq.runSequence(2);
-	sq.runSequence(2);
-	sq.fadeText();
-
-	sq.printText(6, 15);			// His power is gone
-	for (int i = 0; i < 3; i++)
-		sq.runSequence(5);
-	sq.runSequence(2);
-	sq.runSequence(2);
-	sq.fadeText();
-
-	sq.printText(7, 15);			// But Darkmoon is still a source of great evil
-	for (int i = 0; i < 4; i++)
-		sq.runSequence(5);
-	sq.runSequence(2);
-	sq.runSequence(2);
-	sq.fadeText();
-
-	sq.printText(8, 15);			// And many of his minions remain
-	for (int i = 0; i < 4; i++)
-		sq.runSequence(5);
-	sq.runSequence(2);
-	sq.runSequence(2);
-	sq.fadeText();
-
-	sq.loadScene(2, 2);
-	sq.update(2);
-	sq.loadScene(3, 2);
-	_screen->copyRegion(8, 8, 0, 0, 304, 128, 0, 2, Screen::CR_NO_P_CHECK);
-
-	sq.printText(9, 15);			// Now we must leave this place
-	sq.runSequence(7);
-	sq.runSequence(8);
-	sq.runSequence(7);
-	sq.runSequence(7, 36);
-	sq.fadeText();
-
-	sq.printText(10, 15);			// So my forces can destroy it..
-	for (int i = 0; i < 3; i++)
-		sq.runSequence(7);
-	sq.runSequence(8);
-	sq.runSequence(7);
-	sq.runSequence(7, 36);
-	sq.runSequence(8, 18);
-	sq.fadeText();
-
-	sq.printText(11, 15);			// Follow me
-	sq.runSequence(7, 18);
-	sq.runSequence(9, 18);
-	sq.runSequence(8, 18);
-	sq.fadeText();
-
-	sq.loadScene(7, 2);
-	sq.copyPalette(3, 0);
-	sq.loadScene(4, 2);
-
-	sq.waitForSongNotifier(2);
-
-	_screen->clearCurPage();
-	sq.update(2);
-
-	sq.loadScene(8, 2);
-	sq.loadScene(6, 6);
-	sq.delay(10);
-
-	sq.printText(12, 10);			// Powerful mages stand ready for the final assault...
-	sq.delay(90);
-	sq.fadeText();
-
-	sq.waitForSongNotifier(3);
-
-	if (!skipFlag() && !shouldQuit())
-		_sound->playTrack(7);
-	sq.delay(8);
-
-	sq.runSequence(10);
-	sq.runSequence(13);
-	sq.initDelayedPaletteFade(4, 1);
-
-	sq.runSequence(14);
-	sq.runSequence(13);
-	sq.runSequence(14);
-	sq.runSequence(14);
-	sq.runSequence(13);
-	sq.initDelayedPaletteFade(2, 1);
-
-	sq.runSequence(15);
-	sq.runSequence(14);
-	sq.runSequence(13);
-	sq.runSequence(15);
-	sq.runSequence(15);
-	sq.runSequence(11);
-
-	sq.printText(13, 10);			// The temple's evil is very strong
-	sq.delay(72);
-	sq.fadeText();
-
-	sq.printText(14, 10);			// It must not be allowed...
-	sq.delay(72);
-	sq.fadeText();
-
-	sq.waitForSongNotifier(4);
-
-	if (!skipFlag() && !shouldQuit())
-		_sound->playTrack(7);
-	sq.delay(8);
-
-	sq.runSequence(10);
-	sq.initDelayedPaletteFade(5, 1);
-	sq.runSequence(13);
-	sq.runSequence(14);
-	sq.runSequence(13);
-	sq.runSequence(14);
-	sq.runSequence(13);
-	sq.runSequence(13);
-	sq.runSequence(14);
-	sq.runSequence(14);
-	sq.runSequence(13);
-	sq.runSequence(12);
-	for (int i = 0; i < 4; i++)
-		sq.runSequence(16);
-	sq.runSequence(17);
-	sq.runSequence(18);
-
-	sq.printText(15, 10);			// The temple ceases to exist
-	sq.initDelayedPaletteFade(6, 1);
-	sq.delay(36);
-
-	if (!skipFlag() && !shouldQuit())
-		_sound->playTrack(11);
-
-	sq.delay(54);
-	sq.fadeText();
-	sq.loadScene(12, 2);
-
-	sq.waitForSongNotifier(5);
-
-	if (!skipFlag() && !shouldQuit())
-		_sound->playTrack(6);
-
-	if (!skipFlag() && !shouldQuit())
-		_screen->crossFadeRegion(0, 0, 8, 8, 304, 128, 2, 0);
-	sq.delay(18);
-
-	sq.printText(16, 15);			// My friends, our work is done
-	sq.runSequence(20);
-	sq.runSequence(19);
-	sq.runSequence(19, 36);
-	if (!skipFlag() && !shouldQuit())
-		_sound->playTrack(12);
-	sq.fadeText();
-
-	sq.printText(17, 15);			// Thank you
-	sq.runSequence(19);
-	sq.runSequence(20, 36);
-	sq.fadeText();
-
-	sq.printText(18, 15);			// You have earned my deepest respect
-	if (!skipFlag() && !shouldQuit())
-		_sound->playTrack(11);
-	sq.runSequence(20);
-	sq.runSequence(19);
-	sq.runSequence(19);
-	if (!skipFlag() && !shouldQuit())
-		_sound->playTrack(11);
-	sq.delay(36);
-	sq.fadeText();
-
-	sq.printText(19, 15);			// We will remember you always
-	sq.runSequence(19);
-	sq.runSequence(19, 18);
-	if (!skipFlag() && !shouldQuit())
-		_sound->playTrack(11);
-	sq.runSequence(20, 18);
-	sq.fadeText();
-
-	sq.delay(28);
-	if (!skipFlag() && !shouldQuit())
-		_sound->playTrack(12);
-	sq.delay(3);
-
-	sq.loadScene(5, 2);
-	if (skipFlag() || shouldQuit()) {
-		_screen->copyRegion(0, 0, 8, 8, 304, 128, 2, 0, Screen::CR_NO_P_CHECK);
-	} else {
-		_sound->playTrack(6);
-		_screen->crossFadeRegion(0, 0, 8, 8, 304, 128, 2, 0);
-	}
-
-	if (!skipFlag() && !shouldQuit())
-		_sound->playTrack(12);
-	sq.delay(5);
-	if (!skipFlag() && !shouldQuit())
-		_sound->playTrack(11);
-	sq.delay(11);
-	if (!skipFlag() && !shouldQuit())
-		_sound->playTrack(12);
-	sq.delay(7);
-	if (!skipFlag() && !shouldQuit())
-		_sound->playTrack(11);
-	sq.delay(12);
-	if (!skipFlag() && !shouldQuit())
-		_sound->playTrack(12);
-
-	removeInputTop();
-	resetSkipFlag(true);
-
-	sq.loadScene(10, 2);
-	sq.loadScene(9, 2);
-	snd_stopSound();
-	sq.delay(3);
-
-	_sound->loadSoundFile("FINALE2");
-
-	sq.delay(18);
-	if (!skipFlag() && !shouldQuit())
-		_sound->playTrack(1);
-
-	seq_playCredits(&sq, _creditsData, 18, 2, 6, 2);
-
-	sq.delay(90);
-
-	resetSkipFlag(true);
-
-	sq.setPalette(11);
-	sq.fadePalette(9, 10);
-
-	_screen->clearCurPage();
-	sq.loadScene(11, 2);
-
-	static const uint8 finPortraitPos[] = { 0x50, 0x50, 0xD0, 0x50, 0x50, 0x90, 0xD0, 0x90, 0x90, 0x50, 0x90, 0x90 };
-
-	for (int i = 0; i < 6; i++) {
-		if (!testCharacter(i, 1))
-			continue;
-		if (i > 3)
-			_screen->drawShape(2, sq._shapes[6 + i], finPortraitPos[i << 1] - 16, finPortraitPos[(i << 1) + 1] - 16, 0);
-		_screen->drawShape(2, _characters[i].faceShape, finPortraitPos[i << 1], finPortraitPos[(i << 1) + 1], 0);
-	}
-
-	_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
-
-	sq.setPalette(9);
-	sq.fadePalette(0, 18);
-
-	while (!skipFlag() && !shouldQuit())
-		delay(_tickLength);
-
-	snd_stopSound();
-	sq.fadePalette(9, 10);
-}
-
-void DarkMoonEngine::seq_playCredits(DarkmoonSequenceHelper *sq, const uint8 *data, int sd, int backupPage, int tempPage, int speed) {
-	if (!data)
-		return;
-
-	_screen->setScreenDim(sd);
-	const ScreenDim *dm = _screen->_curDim;
-
-	_screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 0, backupPage, Screen::CR_NO_P_CHECK);
-
-	struct CreditsDataItem {
-		int16 x;
-		int16 y;
-		const void *data;
-		char *str;
-		uint8 crlf;
-		uint8 size;
-		uint8 dataType;
-	} items[36];
-	memset(items, 0, sizeof(items));
-
-	const char *pos = (const char *)data;
-	uint32 end = _system->getMillis();
-	uint32 cur = 0;
-	int i = 0;
-
-	do {
-		for (bool loop = true; loop; ) {
-			sq->processDelayedPaletteFade();
-			cur = _system->getMillis();
-			if (end <= cur)
-				break;
-			delay(MIN<uint32>(_tickLength, end - cur));
-		}
-
-		end = _system->getMillis() + speed * _tickLength;
-
-		for (; i < 35 && *pos; i++) {
-			int16 nextY = i ? items[i].y + items[i].size + (items[i].size >> 2) : dm->h;
-
-			const char *posOld = pos;
-			pos = strchr(pos, 0x0d);
-			if (!pos)
-				pos = strchr(posOld, 0x00);
-
-			items[i + 1].crlf = *pos++;
-
-			if (*posOld == 2) {
-				const uint8 *shp = sq->_shapes[(*++posOld) - 1];
-				items[i + 1].data = shp;
-				items[i + 1].size = shp[1];
-				items[i + 1].x = (dm->w - shp[2]) << 2 ;
-				items[i + 1].dataType = 1;
-				delete[] items[i + 1].str;
-				items[i + 1].str = 0;
-
-			} else {
-				if (*posOld == 1) {
-					posOld++;
-					items[i + 1].size = 6;
-				} else {
-					items[i + 1].size = _screen->getFontWidth();
-				}
-
-				items[i + 1].dataType = 0;
-
-				int l = pos - posOld;
-				if (items[i + 1].crlf != 0x0d)
-					l++;
-
-				delete[] items[i + 1].str;
-				items[i + 1].str = new char[l];
-				memcpy(items[i + 1].str, posOld, l);
-				items[i + 1].str[l - 1] = 0;
-				items[i + 1].data = 0;
-				items[i + 1].x = (((dm->w << 3) - (strlen(items[i + 1].str) * items[i + 1].size)) >> 1) + 1;
-			}
-
-			items[i + 1].y = nextY;
-		}
-
-		_screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, backupPage, tempPage, Screen::CR_NO_P_CHECK);
-
-		for (int h = 0; h < i; h++) {
-			if (items[h + 1].y < dm->h) {
-				if (items[h + 1].dataType == 1) {
-					_screen->drawShape(tempPage, (const uint8*)items[h + 1].data, items[h + 1].x, items[h + 1].y, sd);
-				} else {
-					_screen->setCurPage(tempPage);
-
-					if (items[h + 1].size == 6)
-						_screen->setFont(Screen::FID_6_FNT);
-
-					_screen->printText(items[h + 1].str, (dm->sx << 3) + items[h + 1].x - 1, dm->sy + items[h + 1].y + 1, 12, 0);
-					_screen->printText(items[h + 1].str, (dm->sx << 3) + items[h + 1].x, dm->sy + items[h + 1].y, 240, 0);
-
-					if (items[h + 1].size == 6)
-						_screen->setFont(Screen::FID_8_FNT);
-
-					_screen->setCurPage(0);
-				}
-			}
-
-			items[h + 1].y -= 2;
-		}
-
-		_screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, tempPage, 0, Screen::CR_NO_P_CHECK);
-		_screen->updateScreen();
-
-		if (-items[1].size > items[1].y) {
-			delete[] items[1].str;
-			--i;
-			for (int t = 1; t <= i; t++)
-				memcpy(&items[t], &items[t + 1], sizeof(CreditsDataItem));
-			items[i + 1].str = 0;
-		}
-
-		if (i < 35 && ((items[i].y + items[i].size) < (dm->sy + dm->h))) {
-			resetSkipFlag(true);
-			break;
-		}
-
-		sq->processDelayedPaletteFade();
-	} while (!skipFlag() && i && !shouldQuit());
-
-	for (i = 0; i < 35; i++)
-		delete[] items[i].str;
-}
-
-DarkmoonSequenceHelper::DarkmoonSequenceHelper(OSystem *system, DarkMoonEngine *vm, Screen_Eob *screen, Mode mode, const char *const *strings, const char *const *cpsFiles, const char *const *palFiles, const EobShapeDef **shapeDefList, const EobSequenceStep **seqList) :
-	_system(system), _vm(vm), _screen(screen), _mode(mode), _strings(strings), _cpsFiles(cpsFiles), _palFiles(palFiles), _shapeDefs(shapeDefList), _seqData(seqList) {
-
-	for (int i = 0; _palFiles[i]; i++) {
-		if (i < 4)
-			_palettes[i] = &_screen->getPalette(i);
-		else
-			_palettes[i] = new Palette(256);
-		_screen->loadPalette(_palFiles[i], *_palettes[i]);
-	}
-
-	_palettes[9] = new Palette(256);
-	_palettes[9]->fill(0, 256, 0);
-	_palettes[10] = new Palette(256);
-	_palettes[10]->fill(0, 256, 63);
-	_palettes[11] = new Palette(256);
-	_palettes[11]->fill(0, 256, 0);
-
-	_shapes = new const uint8*[30];
-	memset(_shapes, 0, 30 * sizeof(uint8*));
-
-	_fadePalTimer = 0;
-	_fadePalRate = 0;
-
-	_screen->setScreenPalette(*_palettes[0]);
-	_screen->setFont(Screen::FID_8_FNT);
-	_screen->hideMouse();
-
-	_vm->delay(150);
-	_vm->_eventList.clear();
-	_vm->_allowSkip = true;
-}
-
-DarkmoonSequenceHelper::~DarkmoonSequenceHelper() {
-	for (int i = 4; _palFiles[i]; i++)
-		delete _palettes[i];
-	delete _palettes[9];
-	delete _palettes[10];
-	delete _palettes[11];
-
-	for (int i = 0; i < 30; i++)
-		delete[] _shapes[i];
-	delete[] _shapes;
-
-	_screen->clearCurPage();
-	_screen->showMouse();
-	_screen->updateScreen();
-
-	_system->delayMillis(150);
-	_vm->resetSkipFlag(true);
-	_vm->_allowSkip = false;
-}
-
-void DarkmoonSequenceHelper::loadScene(int index, int pageNum) {
-	char file[13];
-	strcpy(file, _cpsFiles[index]);
-
-	Common::SeekableReadStream *s = _vm->resource()->createReadStream(file);
-	if (s && file[0] != 'X') {
-		delete s;
-		_screen->loadBitmap(_cpsFiles[index], pageNum | 1, pageNum | 1, _palettes[0]);
-	} else {
-		if (!s) {
-			file[0] = 'X';
-			s = _vm->resource()->createReadStream(file);
-		}
-
-		if (!s)
-			error("DarkmoonSequenceHelper::loadScene(): CPS file loading failure in scene %d", index);
-
-		if (_mode == kFinale)
-			s->read(_palettes[0]->getData(), 768);
-		else
-			s->seek(768);
-		_screen->loadFileDataToPage(s, 3, 64000);
-		delete s;
-	}
-
-	int cp = _screen->setCurPage(pageNum);
-
-	if (_shapeDefs[index]) {
-		for (const EobShapeDef *df = _shapeDefs[index]; df->w; df++ ) {
-			uint16 shapeIndex = (df->index < 0) ? df->index * -1 : df->index;
-			if (_shapes[shapeIndex])
-				delete[] _shapes[shapeIndex];
-			_shapes[shapeIndex] = _screen->encodeShape(df->x, df->y, df->w, df->h, (df->index >> 8) != 0);
-		}
-	}
-
-	_screen->setCurPage(cp);
-	_screen->copyPage(pageNum | 1, pageNum);
-
-	if ((pageNum == 0 || pageNum == 1) && !_vm->skipFlag() && !_vm->shouldQuit())
-		_screen->updateScreen();
-}
-
-void DarkmoonSequenceHelper::runSequence(int index, int del) {
-	if (_vm->skipFlag() || _vm->shouldQuit())
-		return;
-
-	uint32 end = 0;
-
-	for (const EobSequenceStep *s = _seqData[index]; s->command != 0xff && !_vm->skipFlag() && !_vm->shouldQuit(); s++) {
-		int palIndex = _mode == kFinale ? (s->pal + 1) : s->pal;
-		int x = s->x1;
-		int y = s->y1;
-		int x2 = 0;
-		uint16 shapeW = 0;
-		uint16 shapeH = 0;
-
-		switch(s->command) {
-		case 0:
-			// flash palette
-			if (s->pal)
-				setPaletteWithoutTextColor(palIndex);
-			delay(s->delay);
-			if (_mode == kIntro && s->pal)
-				setPaletteWithoutTextColor(0);
-			break;
-
-		case 1:
-			// draw shape, then restore background
-			shapeW = _shapes[s->obj][2];
-			shapeH = _shapes[s->obj][3];
-
-			if (_mode == kFinale) {
-				_screen->setScreenDim(18);
-				x -= (_screen->_curDim->sx << 3);
-				y -= _screen->_curDim->sy;
-				if (x < 0)
-					shapeW -= ((-x >> 3) + 1);
-				else
-					x2 = x;
-			}
-
-			_screen->drawShape(0, _shapes[s->obj], x, y, _mode == kIntro ? 0 : 18);
-
-			if (s->pal)
-				setPaletteWithoutTextColor(palIndex);
-			else
-				_screen->updateScreen();
-
-			delay(s->delay);
-
-			if (_mode == kIntro) {
-				if (s->pal)
-					setPaletteWithoutTextColor(0);
-				_screen->copyRegion(x - 8, y - 8, x, y, (shapeW + 1) << 3, shapeH, 2, 0, Screen::CR_NO_P_CHECK);
-			} else {
-				_screen->copyRegion(x2, y, x2 + (_screen->_curDim->sx << 3), y + _screen->_curDim->sy, (shapeW + 1) << 3, shapeH, 2, 0, Screen::CR_NO_P_CHECK);
-			}
-
-			_screen->updateScreen();
-			break;
-
-		case 2:
-			// draw shape
-			_screen->drawShape(_screen->_curPage, _shapes[s->obj], x, y, 0);
-
-			if (s->pal)
-				setPaletteWithoutTextColor(palIndex);
-			else if(!_screen->_curPage)
-				_screen->updateScreen();
-
-			delay(s->delay);
-
-			if (_mode == kIntro && s->pal)
-				setPaletteWithoutTextColor(0);
-			break;
-
-		case 3:
-		case 4:
-			// fade shape in or out or restore background
-			if (_mode == kFinale)
-				break;
-
-			_screen->setShapeFadeMode(0, true);
-			_screen->setShapeFadeMode(1, true);
-
-			end = _system->getMillis() + s->delay * _vm->tickLength();
-
-			if (palIndex) {
-				_screen->setFadeTableIndex(palIndex - 1);
-
-				_screen->copyRegion(s->x1 - 8, s->y1 - 8, 0, 0, (_shapes[s->obj][2] + 1) << 3, _shapes[s->obj][3], 2, 4, Screen::CR_NO_P_CHECK);
-				_screen->drawShape(4, _shapes[s->obj], s->x1 & 7, 0, 0);
-				_screen->copyRegion(0, 0, s->x1, s->y1, (_shapes[s->obj][2] + 1) << 3, _shapes[s->obj][3], 4, 0, Screen::CR_NO_P_CHECK);
-			} else {
-				_screen->copyRegion(s->x1 - 8, s->y1 - 8, s->x1, s->y1, (_shapes[s->obj][2] + 1) << 3, _shapes[s->obj][3], 2, 0, Screen::CR_NO_P_CHECK);
-			}
-			_screen->updateScreen();
-
-			_vm->delayUntil(end);
-			_screen->setShapeFadeMode(0, false);
-			_screen->setShapeFadeMode(1, false);
-			break;
-
-		case 5:
-			// copy region
-			if (_mode == kFinale && s->pal)
-				setPaletteWithoutTextColor(palIndex);
-
-			_screen->copyRegion(s->x2 << 3, s->y2, s->x1, s->y1, s->w << 3, s->h, (s->obj && _mode == kFinale) ? 6 : 2, 0, Screen::CR_NO_P_CHECK);
-			_screen->updateScreen();
-			delay(s->delay);
-			break;
-
-		case 6:
-			// play sound effect
-			if (s->obj != 0xff)
-				_vm->sound()->playSoundEffect(s->obj);
-			break;
-
-		default:
-			error("DarkmoonSequenceHelper::runSequence(): Unknown animation opcode encountered.");
-			break;
-		}
-	}
-
-	if (del > 0)
-		delay(del);
-}
-
-void DarkmoonSequenceHelper::printText(int index, int color) {
-	if (_vm->skipFlag() || _vm->shouldQuit())
-		return;
-
-	_screen->setClearScreenDim(17);
-	_palettes[0]->copy(*_palettes[0], color, 1, 255);
-	setPalette(0);
-
-	char *temp = new char[strlen(_strings[index]) + 1];
-	char *str = temp;
-	strcpy(str, _strings[index]);
-
-	const ScreenDim *dm = _screen->_curDim;
-
-	for (int yOffs = 0; *str; yOffs += 9) {
-		char *cr = strchr(str, 13);
-
-		if (cr)
-			*cr = 0;
-
-		uint32 len = strlen(str);
-		_screen->printText(str, (dm->sx + ((dm->w - len) >> 1)) << 3, dm->sy + yOffs, 255, dm->unkA);
-
-		if (cr) {
-			*cr = 13;
-			str = cr + 1;
-		} else {
-			str += len;
-		}
-	}
-
-	delete[] temp;
-	_screen->updateScreen();
-}
-
-void DarkmoonSequenceHelper::fadeText() {
-	if (_vm->skipFlag() || _vm->shouldQuit())
-		return;
-
-	_screen->fadeTextColor(_palettes[0], 255, 2);
-	_screen->clearCurDim();
-}
-
-void DarkmoonSequenceHelper::update(int srcPage) {
-	if (_vm->skipFlag() || _vm->shouldQuit())
-		return;
-
-	_screen->copyRegion(0, 0, 8, 8, 304, 128, srcPage, 0, Screen::CR_NO_P_CHECK);
-	setPaletteWithoutTextColor(0);
-}
-
-void DarkmoonSequenceHelper::setPaletteWithoutTextColor(int index) {
-	if (_vm->skipFlag() || _vm->shouldQuit())
-		return;
-
-	if (!memcmp(_palettes[11]->getData(), _palettes[index]->getData(), 765))
-		return;
-
-	_palettes[11]->copy(*_palettes[index], 0, 255);
-	_palettes[11]->copy(*_palettes[0], 255, 1, 255);
-	setPalette(11);
-
-	_screen->updateScreen();
-}
-
-void DarkmoonSequenceHelper::setPalette(int index) {
-	_screen->setScreenPalette(*_palettes[index]);
-}
-
-void DarkmoonSequenceHelper::fadePalette(int index, int del) {
-	if (_vm->skipFlag() || _vm->shouldQuit())
-		return;
-
-	_screen->fadePalette(*_palettes[index], del * _vm->tickLength());
-}
-
-void DarkmoonSequenceHelper::copyPalette(int srcIndex, int destIndex) {
-	_palettes[destIndex]->copy(*_palettes[srcIndex]);
-}
-
-void DarkmoonSequenceHelper::initDelayedPaletteFade(int palIndex, int rate) {
-	_palettes[11]->copy(*_palettes[0]);
-
-	_fadePalIndex = palIndex;
-	_fadePalRate = rate;
-	_fadePalTimer = _system->getMillis() + 2 * _vm->_tickLength;
-}
-
-bool DarkmoonSequenceHelper::processDelayedPaletteFade() {
-	if (_vm->skipFlag() || _vm->shouldQuit())
-		return true;
-
-	if (!_fadePalRate || (_system->getMillis() <= _fadePalTimer))
-		return false;
-
-	if (_screen->delayedFadePalStep(_palettes[_fadePalIndex], _palettes[0], _fadePalRate)) {
-		setPaletteWithoutTextColor(0);
-		_fadePalTimer = _system->getMillis() + 3 * _vm->_tickLength;
-	} else {
-		_fadePalRate = 0;
-	}
-
-	return false;
-}
-
-void DarkmoonSequenceHelper::delay(uint32 ticks) {
-	if (_vm->skipFlag() || _vm->shouldQuit())
-		return;
-
-	uint32 end = _system->getMillis() + ticks * _vm->_tickLength;
-
-	if (_mode == kFinale) {
-		do {
-			if (processDelayedPaletteFade())
-				break;
-			_vm->updateInput();
-		} while (end > _system->getMillis());
-		processDelayedPaletteFade();
-
-	} else {
-		_vm->delayUntil(end);
-	}
-}
-
-void DarkmoonSequenceHelper::waitForSongNotifier(int index, bool introUpdateAnim) {
-	int seq = 0;
-	while (_vm->sound()->checkTrigger() < index && !(_vm->skipFlag() || _vm->shouldQuit())) {
-		if (introUpdateAnim) {
-			runSequence(30 | seq);
-			seq ^= 1;
-		}
-
-		if (_mode == kFinale)
-			processDelayedPaletteFade();
-
-		_vm->updateInput();
-	}
-}
-
-void DarkMoonEngine::seq_nightmare() {
-	Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
-	_screen->copyRegion(0, 0, 0, 120, 176, 24, 12, 2, Screen::CR_NO_P_CHECK);
-
-	initDialogueSequence();
-	gui_drawDialogueBox();
-
-	_txt->printDialogueText(99, 0);
-	snd_playSoundEffect(54);
-
-	static const uint8 seqX[] = { 0, 20, 0, 20 };
-	static const uint8 seqY[] = { 0, 0, 96, 96 };
-	static const uint8 seqDelay[] = { 12, 7, 7, 12 };
-
-	for (const int8 *i = _dreamSteps; *i != -1; ++i) {
-		drawSequenceBitmap("DREAM", 0, seqX[*i], seqY[*i], 0);
-		delay(seqDelay[*i] * _tickLength);
-	}
-
-	_txt->printDialogueText(20, _okStrings[0]);
-
-	restoreAfterDialogueSequence();
-
-	_screen->setFont(of);
-}
-
-void DarkMoonEngine::seq_kheldran() {
-	Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
-
-	initDialogueSequence();
-	gui_drawDialogueBox();
-
-	static const char file[] = "KHELDRAN";
-	_txt->printDialogueText(_kheldranStrings[0]);
-	drawSequenceBitmap(file, 0, 0, 0, 0);
-	_txt->printDialogueText(20, _moreStrings[0]);
-	snd_playSoundEffect(56);
-	drawSequenceBitmap(file, 0, 20, 0, 0);
-	delay(10 * _tickLength);
-	drawSequenceBitmap(file, 0, 0, 96, 0);
-	delay(10 * _tickLength);
-	drawSequenceBitmap(file, 0, 20, 96, 0);
-	delay(7 * _tickLength);
-	_txt->printDialogueText(76, _okStrings[0]);
-
-	restoreAfterDialogueSequence();
-
-	_screen->setFont(of);
-}
-
-void DarkMoonEngine::seq_dranDragonTransformation() {
-	Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
-
-	initDialogueSequence();
-	gui_drawDialogueBox();
-
-	static const char file[] = "DRANX";
-	drawSequenceBitmap(file, 0, 0, 0, 0);
-	_txt->printDialogueText(120, _moreStrings[0]);
-	snd_playSoundEffect(56);
-	drawSequenceBitmap(file, 0, 20, 0, 0);
-	delay(7 * _tickLength);
-	drawSequenceBitmap(file, 0, 0, 96, 0);
-	delay(7 * _tickLength);
-	drawSequenceBitmap(file, 0, 20, 96, 0);
-	delay(18 * _tickLength);
-
-	restoreAfterDialogueSequence();
-
-	_screen->setFont(of);
-}
-
-}	// End of namespace Kyra
-
-#endif // ENABLE_EOB
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index faa2591..2594828 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -21,7 +21,7 @@
  *
  */
 
-#include "kyra/eob1.h"
+#include "kyra/eob.h"
 #include "kyra/resource.h"
 
 


Commit: 4e4f4164be57d66610eac570e048c9ade07f42ea
    https://github.com/scummvm/scummvm/commit/4e4f4164be57d66610eac570e048c9ade07f42ea
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:16-08:00

Commit Message:
KYRA: (EOB) - fix eob2 sequence text fading

Changed paths:
    engines/kyra/screen_eob.cpp
    engines/kyra/sequences_darkmoon.cpp



diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp
index ca44a8a..36af074 100644
--- a/engines/kyra/screen_eob.cpp
+++ b/engines/kyra/screen_eob.cpp
@@ -978,7 +978,7 @@ void Screen_Eob::fadeTextColor(Palette *pal, int color1, int rate) {
 
 	for (bool loop = true; loop; ) {
 		loop = true;
-		uint32 end = _system->getMillis() + 1;
+		uint32 end = _system->getMillis() + _vm->tickLength();
 
 		loop = false;
 		for (int ii = 0; ii < 3; ii++) {
diff --git a/engines/kyra/sequences_darkmoon.cpp b/engines/kyra/sequences_darkmoon.cpp
index 6b342ad..66d5329 100644
--- a/engines/kyra/sequences_darkmoon.cpp
+++ b/engines/kyra/sequences_darkmoon.cpp
@@ -1172,7 +1172,7 @@ void DarkmoonSequenceHelper::fadeText() {
 	if (_vm->skipFlag() || _vm->shouldQuit())
 		return;
 
-	_screen->fadeTextColor(_palettes[0], 255, 2);
+	_screen->fadeTextColor(_palettes[0], 255, 8);
 	_screen->clearCurDim();
 }
 


Commit: 0aa32385230dbe1ab62bb2d02d04ca5cc46d928c
    https://github.com/scummvm/scummvm/commit/0aa32385230dbe1ab62bb2d02d04ca5cc46d928c
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:16-08:00

Commit Message:
KYRA: (EOB/LOL) - rename some vars

(all cases of Eob to EoB, all cases of Lol to LoL, all cases of LolEobCommon to RpgCommon)

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/extract.cpp
    devtools/create_kyradat/extract.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    engines/kyra/chargen.cpp
    engines/kyra/darkmoon.cpp
    engines/kyra/darkmoon.h
    engines/kyra/debugger.cpp
    engines/kyra/debugger.h
    engines/kyra/detection.cpp
    engines/kyra/eob.cpp
    engines/kyra/eob.h
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/gui_eob.h
    engines/kyra/items_eob.cpp
    engines/kyra/kyra_hof.cpp
    engines/kyra/kyra_hof.h
    engines/kyra/kyra_rpg.cpp
    engines/kyra/kyra_rpg.h
    engines/kyra/lol.cpp
    engines/kyra/lol.h
    engines/kyra/magic_eob.cpp
    engines/kyra/resource.h
    engines/kyra/saveload_eob.cpp
    engines/kyra/saveload_lol.cpp
    engines/kyra/saveload_rpg.cpp
    engines/kyra/scene_eob.cpp
    engines/kyra/scene_lol.cpp
    engines/kyra/screen_eob.cpp
    engines/kyra/screen_eob.h
    engines/kyra/script_eob.cpp
    engines/kyra/script_eob.h
    engines/kyra/script_lol.cpp
    engines/kyra/sequences_darkmoon.cpp
    engines/kyra/sequences_eob.cpp
    engines/kyra/sequences_lol.cpp
    engines/kyra/sound_adlib.cpp
    engines/kyra/sprites_eob.cpp
    engines/kyra/sprites_lol.cpp
    engines/kyra/staticres.cpp
    engines/kyra/staticres_eob.cpp
    engines/kyra/staticres_lol.cpp
    engines/kyra/staticres_rpg.cpp
    engines/kyra/text_rpg.cpp
    engines/kyra/timer_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index d500cbd..207385e 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -216,456 +216,456 @@ const ExtractFilename extractFilenames[] = {
 	{ k3ItemStringMap, kTypeRawData, false },
 
 	// EYE OF THE BEHOLDER COMMON
-	{ kEobBaseChargenStrings1, kTypeStringList, true },
-	{ kEobBaseChargenStrings2, kTypeStringList, true },
-	{ kEobBaseChargenStartLevels, kTypeRawData, false },
-	{ kEobBaseChargenStatStrings, kTypeStringList, true},
-	{ kEobBaseChargenRaceSexStrings, kTypeStringList, true },
-	{ kEobBaseChargenClassStrings, kTypeStringList, true },
-	{ kEobBaseChargenAlignmentStrings, kTypeStringList, true },
-	{ kEobBaseChargenEnterGameStrings, kTypeStringList, true },
-	{ kEobBaseChargenClassMinStats, k3TypeRaw16to8, false },
-	{ kEobBaseChargenRaceMinStats, k3TypeRaw16to8, false },
-	{ kEobBaseChargenRaceMaxStats, kLolTypeRaw16, false },
-
-	{ kEobBaseSaveThrowTable1, kTypeRawData, false },
-	{ kEobBaseSaveThrowTable2, kTypeRawData, false },
-	{ kEobBaseSaveThrowTable3, kTypeRawData, false },
-	{ kEobBaseSaveThrowTable4, kTypeRawData, false },
-	{ kEobBaseSaveThrwLvlIndex, kTypeRawData, false },
-	{ kEobBaseSaveThrwModDiv, kTypeRawData, false },
-	{ kEobBaseSaveThrwModExt, kTypeRawData, false },
-
-	{ kEobBasePryDoorStrings, kTypeStringList, true },
-	{ kEobBaseWarningStrings, kTypeStringList, true },
-
-	{ kEobBaseItemSuffixStringsRings, kTypeStringList, true },
-	{ kEobBaseItemSuffixStringsPotions, kTypeStringList, true },
-	{ kEobBaseItemSuffixStringsWands, kTypeStringList, true },
-
-	{ kEobBaseRipItemStrings, kTypeStringList, true },
-	{ kEobBaseCursedString, kTypeStringList, true },
-	{ kEobBaseEnchantedString, kTypeStringList, false },
-	{ kEobBaseMagicObjectStrings, kTypeStringList, true },
-	{ kEobBaseMagicObject5String, kTypeStringList, true },
-	{ kEobBasePatternSuffix, kTypeStringList, true },
-	{ kEobBasePatternGrFix1, kTypeStringList, true },
-	{ kEobBasePatternGrFix2, kTypeStringList, true },
-	{ kEobBaseValidateArmorString, kTypeStringList, true },
-	{ kEobBaseValidateCursedString, kTypeStringList, true },
-	{ kEobBaseValidateNoDropString, kTypeStringList, true },
-	{ kEobBasePotionStrings, kTypeStringList, true },
-	{ kEobBaseWandString, kTypeStringList, true },
-	{ kEobBaseItemMisuseStrings, kTypeStringList, true },
-
-	{ kEobBaseTakenStrings, kTypeStringList, true },
-	{ kEobBasePotionEffectStrings, kTypeStringList, true },
-
-	{ kEobBaseYesNoStrings, kTypeStringList, true },
-	{ kLolEobCommonMoreStrings, kTypeStringList, true },
-	{ kEobBaseNpcMaxStrings, kTypeStringList, true },
-	{ kEobBaseOkStrings, kTypeStringList, true },
-	{ kEobBaseNpcJoinStrings, kTypeStringList, true },
-	{ kEobBaseCancelStrings, kTypeStringList, true },
-	{ kEobBaseAbortStrings, kTypeStringList, true },
-
-	{ kEobBaseMenuStringsMain, kTypeStringList, true },
-	{ kEobBaseMenuStringsSaveLoad, kTypeStringList, true },
-	{ kEobBaseMenuStringsOnOff, kTypeStringList, true },
-	{ kEobBaseMenuStringsSpells, kTypeStringList, true },
-	{ kEobBaseMenuStringsRest, kTypeStringList, true },
-	{ kEobBaseMenuStringsDrop, kTypeStringList, true },
-	{ kEobBaseMenuStringsExit, kTypeStringList, true },
-	{ kEobBaseMenuStringsStarve, kTypeStringList, true },
-	{ kEobBaseMenuStringsScribe, kTypeStringList, true },
-	{ kEobBaseMenuStringsDrop2, kTypeStringList, true },
-	{ kEobBaseMenuStringsHead, kTypeStringList, true },
-	{ kEobBaseMenuStringsPoison, kTypeStringList, true },
-	{ kEobBaseMenuStringsMgc, kTypeStringList, true },
-	{ kEobBaseMenuStringsPrefs, kTypeStringList, true },
-	{ kEobBaseMenuStringsRest2, kTypeStringList, true },
-	{ kEobBaseMenuStringsRest3, kTypeStringList, true },
-	{ kEobBaseMenuStringsRest4, kTypeStringList, true },
-	{ kEobBaseMenuStringsDefeat, kTypeStringList, true },
-	{ kEobBaseMenuStringsTransfer, kTypeStringList, true },
-	{ kEobBaseMenuStringsSpec, kTypeStringList, true },
-	{ kEobBaseMenuStringsSpellNo, kTypeStringList, false },
-	{ kEobBaseMenuYesNoStrings, kTypeStringList, true },
-
-	{ kEobBaseSpellLevelsMage, kTypeRawData, false },
-	{ kEobBaseSpellLevelsCleric, kTypeRawData, false },
-	{ kEobBaseNumSpellsCleric, kTypeRawData, false },
-	{ kEobBaseNumSpellsWisAdj, kTypeRawData, false },
-	{ kEobBaseNumSpellsPal, kTypeRawData, false },
-	{ kEobBaseNumSpellsMage, kTypeRawData, false },
+	{ kEoBBaseChargenStrings1, kTypeStringList, true },
+	{ kEoBBaseChargenStrings2, kTypeStringList, true },
+	{ kEoBBaseChargenStartLevels, kTypeRawData, false },
+	{ kEoBBaseChargenStatStrings, kTypeStringList, true},
+	{ kEoBBaseChargenRaceSexStrings, kTypeStringList, true },
+	{ kEoBBaseChargenClassStrings, kTypeStringList, true },
+	{ kEoBBaseChargenAlignmentStrings, kTypeStringList, true },
+	{ kEoBBaseChargenEnterGameStrings, kTypeStringList, true },
+	{ kEoBBaseChargenClassMinStats, k3TypeRaw16to8, false },
+	{ kEoBBaseChargenRaceMinStats, k3TypeRaw16to8, false },
+	{ kEoBBaseChargenRaceMaxStats, kLoLTypeRaw16, false },
+
+	{ kEoBBaseSaveThrowTable1, kTypeRawData, false },
+	{ kEoBBaseSaveThrowTable2, kTypeRawData, false },
+	{ kEoBBaseSaveThrowTable3, kTypeRawData, false },
+	{ kEoBBaseSaveThrowTable4, kTypeRawData, false },
+	{ kEoBBaseSaveThrwLvlIndex, kTypeRawData, false },
+	{ kEoBBaseSaveThrwModDiv, kTypeRawData, false },
+	{ kEoBBaseSaveThrwModExt, kTypeRawData, false },
+
+	{ kEoBBasePryDoorStrings, kTypeStringList, true },
+	{ kEoBBaseWarningStrings, kTypeStringList, true },
+
+	{ kEoBBaseItemSuffixStringsRings, kTypeStringList, true },
+	{ kEoBBaseItemSuffixStringsPotions, kTypeStringList, true },
+	{ kEoBBaseItemSuffixStringsWands, kTypeStringList, true },
+
+	{ kEoBBaseRipItemStrings, kTypeStringList, true },
+	{ kEoBBaseCursedString, kTypeStringList, true },
+	{ kEoBBaseEnchantedString, kTypeStringList, false },
+	{ kEoBBaseMagicObjectStrings, kTypeStringList, true },
+	{ kEoBBaseMagicObject5String, kTypeStringList, true },
+	{ kEoBBasePatternSuffix, kTypeStringList, true },
+	{ kEoBBasePatternGrFix1, kTypeStringList, true },
+	{ kEoBBasePatternGrFix2, kTypeStringList, true },
+	{ kEoBBaseValidateArmorString, kTypeStringList, true },
+	{ kEoBBaseValidateCursedString, kTypeStringList, true },
+	{ kEoBBaseValidateNoDropString, kTypeStringList, true },
+	{ kEoBBasePotionStrings, kTypeStringList, true },
+	{ kEoBBaseWandString, kTypeStringList, true },
+	{ kEoBBaseItemMisuseStrings, kTypeStringList, true },
+
+	{ kEoBBaseTakenStrings, kTypeStringList, true },
+	{ kEoBBasePotionEffectStrings, kTypeStringList, true },
+
+	{ kEoBBaseYesNoStrings, kTypeStringList, true },
+	{ kRpgCommonMoreStrings, kTypeStringList, true },
+	{ kEoBBaseNpcMaxStrings, kTypeStringList, true },
+	{ kEoBBaseOkStrings, kTypeStringList, true },
+	{ kEoBBaseNpcJoinStrings, kTypeStringList, true },
+	{ kEoBBaseCancelStrings, kTypeStringList, true },
+	{ kEoBBaseAbortStrings, kTypeStringList, true },
+
+	{ kEoBBaseMenuStringsMain, kTypeStringList, true },
+	{ kEoBBaseMenuStringsSaveLoad, kTypeStringList, true },
+	{ kEoBBaseMenuStringsOnOff, kTypeStringList, true },
+	{ kEoBBaseMenuStringsSpells, kTypeStringList, true },
+	{ kEoBBaseMenuStringsRest, kTypeStringList, true },
+	{ kEoBBaseMenuStringsDrop, kTypeStringList, true },
+	{ kEoBBaseMenuStringsExit, kTypeStringList, true },
+	{ kEoBBaseMenuStringsStarve, kTypeStringList, true },
+	{ kEoBBaseMenuStringsScribe, kTypeStringList, true },
+	{ kEoBBaseMenuStringsDrop2, kTypeStringList, true },
+	{ kEoBBaseMenuStringsHead, kTypeStringList, true },
+	{ kEoBBaseMenuStringsPoison, kTypeStringList, true },
+	{ kEoBBaseMenuStringsMgc, kTypeStringList, true },
+	{ kEoBBaseMenuStringsPrefs, kTypeStringList, true },
+	{ kEoBBaseMenuStringsRest2, kTypeStringList, true },
+	{ kEoBBaseMenuStringsRest3, kTypeStringList, true },
+	{ kEoBBaseMenuStringsRest4, kTypeStringList, true },
+	{ kEoBBaseMenuStringsDefeat, kTypeStringList, true },
+	{ kEoBBaseMenuStringsTransfer, kTypeStringList, true },
+	{ kEoBBaseMenuStringsSpec, kTypeStringList, true },
+	{ kEoBBaseMenuStringsSpellNo, kTypeStringList, false },
+	{ kEoBBaseMenuYesNoStrings, kTypeStringList, true },
+
+	{ kEoBBaseSpellLevelsMage, kTypeRawData, false },
+	{ kEoBBaseSpellLevelsCleric, kTypeRawData, false },
+	{ kEoBBaseNumSpellsCleric, kTypeRawData, false },
+	{ kEoBBaseNumSpellsWisAdj, kTypeRawData, false },
+	{ kEoBBaseNumSpellsPal, kTypeRawData, false },
+	{ kEoBBaseNumSpellsMage, kTypeRawData, false },
 	
-	{ kEobBaseCharGuiStringsHp, kTypeStringList, true },
-	{ kEobBaseCharGuiStringsWp1, kTypeStringList, true },
-	{ kEobBaseCharGuiStringsWp2, kTypeStringList, true },
-	{ kEobBaseCharGuiStringsWr, kTypeStringList, true },
-	{ kEobBaseCharGuiStringsSt1, kTypeStringList, true },
-	{ kEobBaseCharGuiStringsSt2, kTypeStringList, true },
-	{ kEobBaseCharGuiStringsIn, kTypeStringList, true },
-
-	{ kEobBaseCharStatusStrings7, kTypeStringList, true },
-	{ kEobBaseCharStatusStrings81, kTypeStringList, true },
-	{ kEobBaseCharStatusStrings82, kTypeStringList, true },
-	{ kEobBaseCharStatusStrings9, kTypeStringList, true },
-	{ kEobBaseCharStatusStrings12, kTypeStringList, true },
-	{ kEobBaseCharStatusStrings131, kTypeStringList, true },
-	{ kEobBaseCharStatusStrings132, kTypeStringList, true },
-
-	{ kEobBaseLevelGainStrings, kTypeStringList, true },
-	{ kEobBaseExperienceTable0, kLolTypeRaw32, false },
-	{ kEobBaseExperienceTable1, kLolTypeRaw32, false },
-	{ kEobBaseExperienceTable2, kLolTypeRaw32, false },
-	{ kEobBaseExperienceTable3, kLolTypeRaw32, false },
-	{ kEobBaseExperienceTable4, kLolTypeRaw32, false },
-
-	{ kEobBaseWllFlagPreset, kTypeRawData, false },
-	{ kEobBaseDscShapeCoords, kLolTypeRaw16, false },
-	{ kEobBaseDscDoorScaleOffs, kTypeRawData, false },
-	{ kEobBaseDscDoorScaleMult1, kTypeRawData, false },
-	{ kEobBaseDscDoorScaleMult2, kTypeRawData, false },
-	{ kEobBaseDscDoorScaleMult3, kTypeRawData, false },
-	{ kEobBaseDscDoorScaleMult4, kTypeRawData, false },
-	{ kEobBaseDscDoorScaleMult5, kTypeRawData, false },
-	{ kEobBaseDscDoorScaleMult6, kTypeRawData, false },
-	{ kEobBaseDscDoorType5Offs, kTypeRawData, false },
-	{ kEobBaseDscDoorXE, kTypeRawData, false },
-	{ kEobBaseDscDoorY1, kTypeRawData, false },
-	{ kEobBaseDscDoorY3, kTypeRawData, false },
-	{ kEobBaseDscDoorY4, kTypeRawData, false },
-	{ kEobBaseDscDoorY5, kTypeRawData, false },
-	{ kEobBaseDscDoorY6, kTypeRawData, false },
-	{ kEobBaseDscDoorY7, kTypeRawData, false },
-	{ kEobBaseDscDoorCoordsExt, kLolTypeRaw16, false },
-
-	{ kEobBaseDscItemPosIndex, kTypeRawData, false },
-	{ kEobBaseDscItemShpX, kLolTypeRaw16, false },
-	{ kEobBaseDscItemPosUnk, kTypeRawData, false },
-	{ kEobBaseDscItemTileIndex, kTypeRawData, false },
-	{ kEobBaseDscItemShapeMap, kTypeRawData, false },
-	{ kEobBaseDscTelptrShpCoords, kTypeRawData, false },
-
-	{ kEobBasePortalSeqData, kTypeRawData, false },
-	{ kEobBaseManDef, kTypeRawData, true },
-	{ kEobBaseManWord, kTypeStringList, true },
-	{ kEobBaseManPrompt, kTypeStringList, true },
-
-	{ kEobBaseDscMonsterFrmOffsTbl1, kTypeRawData, false },
-	{ kEobBaseDscMonsterFrmOffsTbl2, kTypeRawData, false },
-
-	{ kEobBaseInvSlotX, kLolTypeRaw16, false },
-	{ kEobBaseInvSlotY, kTypeRawData, false },
-	{ kEobBaseSlotValidationFlags, kLolTypeRaw16, false },
-
-	{ kEobBaseProjectileWeaponTypes, kTypeRawData, false },
-	{ kEobBaseWandTypes, kTypeRawData, false },
-
-	{ kEobBaseDrawObjPosIndex, kTypeRawData, false },
-	{ kEobBaseFlightObjFlipIndex, kTypeRawData, false },
-	{ kEobBaseFlightObjShpMap, kTypeRawData, false },
-	{ kEobBaseFlightObjSclIndex, kTypeRawData, false },
-
-	{ kEobBaseBookNumbers, kTypeStringList, true },
-	{ kEobBaseMageSpellsList, kTypeStringList, true },
-	{ kEobBaseClericSpellsList, kTypeStringList, true },
-	{ kEobBaseSpellNames, kTypeStringList, true },
-
-	{ kEobBaseMagicStrings1, kTypeStringList, true },
-	{ kEobBaseMagicStrings2, kTypeStringList, true },
-	{ kEobBaseMagicStrings3, kTypeStringList, true },
-	{ kEobBaseMagicStrings4, kTypeStringList, true },
-	{ kEobBaseMagicStrings6, kTypeStringList, true },
-	{ kEobBaseMagicStrings7, kTypeStringList, true },
-	{ kEobBaseMagicStrings8, kTypeStringList, true },
+	{ kEoBBaseCharGuiStringsHp, kTypeStringList, true },
+	{ kEoBBaseCharGuiStringsWp1, kTypeStringList, true },
+	{ kEoBBaseCharGuiStringsWp2, kTypeStringList, true },
+	{ kEoBBaseCharGuiStringsWr, kTypeStringList, true },
+	{ kEoBBaseCharGuiStringsSt1, kTypeStringList, true },
+	{ kEoBBaseCharGuiStringsSt2, kTypeStringList, true },
+	{ kEoBBaseCharGuiStringsIn, kTypeStringList, true },
+
+	{ kEoBBaseCharStatusStrings7, kTypeStringList, true },
+	{ kEoBBaseCharStatusStrings81, kTypeStringList, true },
+	{ kEoBBaseCharStatusStrings82, kTypeStringList, true },
+	{ kEoBBaseCharStatusStrings9, kTypeStringList, true },
+	{ kEoBBaseCharStatusStrings12, kTypeStringList, true },
+	{ kEoBBaseCharStatusStrings131, kTypeStringList, true },
+	{ kEoBBaseCharStatusStrings132, kTypeStringList, true },
+
+	{ kEoBBaseLevelGainStrings, kTypeStringList, true },
+	{ kEoBBaseExperienceTable0, kLoLTypeRaw32, false },
+	{ kEoBBaseExperienceTable1, kLoLTypeRaw32, false },
+	{ kEoBBaseExperienceTable2, kLoLTypeRaw32, false },
+	{ kEoBBaseExperienceTable3, kLoLTypeRaw32, false },
+	{ kEoBBaseExperienceTable4, kLoLTypeRaw32, false },
+
+	{ kEoBBaseWllFlagPreset, kTypeRawData, false },
+	{ kEoBBaseDscShapeCoords, kLoLTypeRaw16, false },
+	{ kEoBBaseDscDoorScaleOffs, kTypeRawData, false },
+	{ kEoBBaseDscDoorScaleMult1, kTypeRawData, false },
+	{ kEoBBaseDscDoorScaleMult2, kTypeRawData, false },
+	{ kEoBBaseDscDoorScaleMult3, kTypeRawData, false },
+	{ kEoBBaseDscDoorScaleMult4, kTypeRawData, false },
+	{ kEoBBaseDscDoorScaleMult5, kTypeRawData, false },
+	{ kEoBBaseDscDoorScaleMult6, kTypeRawData, false },
+	{ kEoBBaseDscDoorType5Offs, kTypeRawData, false },
+	{ kEoBBaseDscDoorXE, kTypeRawData, false },
+	{ kEoBBaseDscDoorY1, kTypeRawData, false },
+	{ kEoBBaseDscDoorY3, kTypeRawData, false },
+	{ kEoBBaseDscDoorY4, kTypeRawData, false },
+	{ kEoBBaseDscDoorY5, kTypeRawData, false },
+	{ kEoBBaseDscDoorY6, kTypeRawData, false },
+	{ kEoBBaseDscDoorY7, kTypeRawData, false },
+	{ kEoBBaseDscDoorCoordsExt, kLoLTypeRaw16, false },
+
+	{ kEoBBaseDscItemPosIndex, kTypeRawData, false },
+	{ kEoBBaseDscItemShpX, kLoLTypeRaw16, false },
+	{ kEoBBaseDscItemPosUnk, kTypeRawData, false },
+	{ kEoBBaseDscItemTileIndex, kTypeRawData, false },
+	{ kEoBBaseDscItemShapeMap, kTypeRawData, false },
+	{ kEoBBaseDscTelptrShpCoords, kTypeRawData, false },
+
+	{ kEoBBasePortalSeqData, kTypeRawData, false },
+	{ kEoBBaseManDef, kTypeRawData, true },
+	{ kEoBBaseManWord, kTypeStringList, true },
+	{ kEoBBaseManPrompt, kTypeStringList, true },
+
+	{ kEoBBaseDscMonsterFrmOffsTbl1, kTypeRawData, false },
+	{ kEoBBaseDscMonsterFrmOffsTbl2, kTypeRawData, false },
+
+	{ kEoBBaseInvSlotX, kLoLTypeRaw16, false },
+	{ kEoBBaseInvSlotY, kTypeRawData, false },
+	{ kEoBBaseSlotValidationFlags, kLoLTypeRaw16, false },
+
+	{ kEoBBaseProjectileWeaponTypes, kTypeRawData, false },
+	{ kEoBBaseWandTypes, kTypeRawData, false },
+
+	{ kEoBBaseDrawObjPosIndex, kTypeRawData, false },
+	{ kEoBBaseFlightObjFlipIndex, kTypeRawData, false },
+	{ kEoBBaseFlightObjShpMap, kTypeRawData, false },
+	{ kEoBBaseFlightObjSclIndex, kTypeRawData, false },
+
+	{ kEoBBaseBookNumbers, kTypeStringList, true },
+	{ kEoBBaseMageSpellsList, kTypeStringList, true },
+	{ kEoBBaseClericSpellsList, kTypeStringList, true },
+	{ kEoBBaseSpellNames, kTypeStringList, true },
+
+	{ kEoBBaseMagicStrings1, kTypeStringList, true },
+	{ kEoBBaseMagicStrings2, kTypeStringList, true },
+	{ kEoBBaseMagicStrings3, kTypeStringList, true },
+	{ kEoBBaseMagicStrings4, kTypeStringList, true },
+	{ kEoBBaseMagicStrings6, kTypeStringList, true },
+	{ kEoBBaseMagicStrings7, kTypeStringList, true },
+	{ kEoBBaseMagicStrings8, kTypeStringList, true },
 	
-	{ kEobBaseExpObjectTlMode, kTypeRawData, false },
-	{ kEobBaseExpObjectTblIndex, kTypeRawData, false },
-	{ kEobBaseExpObjectShpStart, kTypeRawData, false },
-	{ kEobBaseExpObjectTbl1, kTypeRawData, false },
-	{ kEobBaseExpObjectTbl2, kTypeRawData, false },
-	{ kEobBaseExpObjectTbl3, kTypeRawData, false },
-	{ kEobBaseExpObjectY, k3TypeRaw16to8, false },
-
-	{ kEobBaseSparkDefSteps, kTypeRawData, false },
-	{ kEobBaseSparkDefSubSteps, kTypeRawData, false },
-	{ kEobBaseSparkDefShift, kTypeRawData, false },
-	{ kEobBaseSparkDefAdd, kTypeRawData, false },
-	{ kEobBaseSparkDefX, k3TypeRaw16to8, false },
-	{ kEobBaseSparkDefY, kTypeRawData, false },
-	{ kEobBaseSparkOfFlags1, kLolTypeRaw32, false },
-	{ kEobBaseSparkOfFlags2, kLolTypeRaw32, false },
-	{ kEobBaseSparkOfShift, kTypeRawData, false },
-	{ kEobBaseSparkOfX, kTypeRawData, false },
-	{ kEobBaseSparkOfY, kTypeRawData, false },
-	{ kEobBaseSpellProperties, kTypeRawData, false },
-	{ kEobBaseMagicFlightProps, kTypeRawData, false },
-	{ kEobBaseTurnUndeadEffect, kTypeRawData, false },
-	{ kEobBaseBurningHandsDest, kTypeRawData, false },
-	{ kEobBaseConeOfColdDest1, kTypeRawData, false },
-	{ kEobBaseConeOfColdDest2, kTypeRawData, false },
-	{ kEobBaseConeOfColdDest3, kTypeRawData, false },
-	{ kEobBaseConeOfColdDest4, kTypeRawData, false },
-	{ kEobBaseConeOfColdGfxTbl, k3TypeRaw16to8, false },
+	{ kEoBBaseExpObjectTlMode, kTypeRawData, false },
+	{ kEoBBaseExpObjectTblIndex, kTypeRawData, false },
+	{ kEoBBaseExpObjectShpStart, kTypeRawData, false },
+	{ kEoBBaseExpObjectTbl1, kTypeRawData, false },
+	{ kEoBBaseExpObjectTbl2, kTypeRawData, false },
+	{ kEoBBaseExpObjectTbl3, kTypeRawData, false },
+	{ kEoBBaseExpObjectY, k3TypeRaw16to8, false },
+
+	{ kEoBBaseSparkDefSteps, kTypeRawData, false },
+	{ kEoBBaseSparkDefSubSteps, kTypeRawData, false },
+	{ kEoBBaseSparkDefShift, kTypeRawData, false },
+	{ kEoBBaseSparkDefAdd, kTypeRawData, false },
+	{ kEoBBaseSparkDefX, k3TypeRaw16to8, false },
+	{ kEoBBaseSparkDefY, kTypeRawData, false },
+	{ kEoBBaseSparkOfFlags1, kLoLTypeRaw32, false },
+	{ kEoBBaseSparkOfFlags2, kLoLTypeRaw32, false },
+	{ kEoBBaseSparkOfShift, kTypeRawData, false },
+	{ kEoBBaseSparkOfX, kTypeRawData, false },
+	{ kEoBBaseSparkOfY, kTypeRawData, false },
+	{ kEoBBaseSpellProperties, kTypeRawData, false },
+	{ kEoBBaseMagicFlightProps, kTypeRawData, false },
+	{ kEoBBaseTurnUndeadEffect, kTypeRawData, false },
+	{ kEoBBaseBurningHandsDest, kTypeRawData, false },
+	{ kEoBBaseConeOfColdDest1, kTypeRawData, false },
+	{ kEoBBaseConeOfColdDest2, kTypeRawData, false },
+	{ kEoBBaseConeOfColdDest3, kTypeRawData, false },
+	{ kEoBBaseConeOfColdDest4, kTypeRawData, false },
+	{ kEoBBaseConeOfColdGfxTbl, k3TypeRaw16to8, false },
 
 	// EYE OF THE BEHOLDER I
-	{ kEob1MainMenuStrings, kTypeStringList, true },
-	{ kEob1BonusStrings, kTypeStringList, true },
-
-	{ kEob1IntroFilesOpening, kTypeStringList, false },
-	{ kEob1IntroFilesTower, kTypeStringList, false },
-	{ kEob1IntroFilesOrb, kTypeStringList, false },
-	{ kEob1IntroFilesWdEntry, kTypeStringList, false },
-	{ kEob1IntroFilesKing, kTypeStringList, false },
-	{ kEob1IntroFilesHands, kTypeStringList, false },
-	{ kEob1IntroFilesWdExit, kTypeStringList, false },
-	{ kEob1IntroFilesTunnel, kTypeStringList, false },
-	{ kEob1IntroOpeningFrmDelay, k3TypeRaw16to8, false },
-	{ kEob1IntroWdEncodeX, kTypeRawData, false },
-	{ kEob1IntroWdEncodeY, kTypeRawData, false },
-	{ kEob1IntroWdEncodeWH, kTypeRawData, false },
-	{ kEob1IntroWdDsX, kLolTypeRaw16, false },
-	{ kEob1IntroWdDsY, kTypeRawData, false },
-	{ kEob1IntroTvlX1, kTypeRawData, false },
-	{ kEob1IntroTvlY1, kTypeRawData, false },
-	{ kEob1IntroTvlX2, kTypeRawData, false },
-	{ kEob1IntroTvlY2, kTypeRawData, false },
-	{ kEob1IntroTvlW, kTypeRawData, false },
-	{ kEob1IntroTvlH, kTypeRawData, false },
-
-	{ kEob1DoorShapeDefs, kTypeRawData, false },
-	{ kEob1DoorSwitchShapeDefs, kTypeRawData, false },
-	{ kEob1DoorSwitchCoords, kTypeRawData, false },
-	{ kEob1MonsterProperties, kTypeRawData, false },
-	{ kEob1EnemyMageSpellList, kTypeRawData, false },
-	{ kEob1EnemyMageSfx, kTypeRawData, false },
-	{ kEob1BeholderSpellList, kTypeRawData, false },
-	{ kEob1BeholderSfx, kTypeRawData, false },
-	{ kEob1TurnUndeadString, kTypeStringList, true },
-
-	{ kEob1NpcShpData, kTypeRawData, false },
-	{ kEob1NpcSubShpIndex1, kTypeRawData, false },
-	{ kEob1NpcSubShpIndex2, kTypeRawData, false },
-	{ kEob1NpcSubShpY, kTypeRawData, false },
-	{ kEob1Npc0Strings, kTypeStringList, true },
-	{ kEob1Npc11Strings, kTypeStringList, true },
-	{ kEob1Npc12Strings, kTypeStringList, true },
-	{ kEob1Npc21Strings, kTypeStringList, true },
-	{ kEob1Npc22Strings, kTypeStringList, true },
-	{ kEob1Npc31Strings, kTypeStringList, true },
-	{ kEob1Npc32Strings, kTypeStringList, true },
-	{ kEob1Npc4Strings, kTypeStringList, true },
-	{ kEob1Npc5Strings, kTypeStringList, true },
-	{ kEob1Npc6Strings, kTypeStringList, true },
-	{ kEob1Npc7Strings, kTypeStringList, true },
+	{ kEoB1MainMenuStrings, kTypeStringList, true },
+	{ kEoB1BonusStrings, kTypeStringList, true },
+
+	{ kEoB1IntroFilesOpening, kTypeStringList, false },
+	{ kEoB1IntroFilesTower, kTypeStringList, false },
+	{ kEoB1IntroFilesOrb, kTypeStringList, false },
+	{ kEoB1IntroFilesWdEntry, kTypeStringList, false },
+	{ kEoB1IntroFilesKing, kTypeStringList, false },
+	{ kEoB1IntroFilesHands, kTypeStringList, false },
+	{ kEoB1IntroFilesWdExit, kTypeStringList, false },
+	{ kEoB1IntroFilesTunnel, kTypeStringList, false },
+	{ kEoB1IntroOpeningFrmDelay, k3TypeRaw16to8, false },
+	{ kEoB1IntroWdEncodeX, kTypeRawData, false },
+	{ kEoB1IntroWdEncodeY, kTypeRawData, false },
+	{ kEoB1IntroWdEncodeWH, kTypeRawData, false },
+	{ kEoB1IntroWdDsX, kLoLTypeRaw16, false },
+	{ kEoB1IntroWdDsY, kTypeRawData, false },
+	{ kEoB1IntroTvlX1, kTypeRawData, false },
+	{ kEoB1IntroTvlY1, kTypeRawData, false },
+	{ kEoB1IntroTvlX2, kTypeRawData, false },
+	{ kEoB1IntroTvlY2, kTypeRawData, false },
+	{ kEoB1IntroTvlW, kTypeRawData, false },
+	{ kEoB1IntroTvlH, kTypeRawData, false },
+
+	{ kEoB1DoorShapeDefs, kTypeRawData, false },
+	{ kEoB1DoorSwitchShapeDefs, kTypeRawData, false },
+	{ kEoB1DoorSwitchCoords, kTypeRawData, false },
+	{ kEoB1MonsterProperties, kTypeRawData, false },
+	{ kEoB1EnemyMageSpellList, kTypeRawData, false },
+	{ kEoB1EnemyMageSfx, kTypeRawData, false },
+	{ kEoB1BeholderSpellList, kTypeRawData, false },
+	{ kEoB1BeholderSfx, kTypeRawData, false },
+	{ kEoB1TurnUndeadString, kTypeStringList, true },
+
+	{ kEoB1NpcShpData, kTypeRawData, false },
+	{ kEoB1NpcSubShpIndex1, kTypeRawData, false },
+	{ kEoB1NpcSubShpIndex2, kTypeRawData, false },
+	{ kEoB1NpcSubShpY, kTypeRawData, false },
+	{ kEoB1Npc0Strings, kTypeStringList, true },
+	{ kEoB1Npc11Strings, kTypeStringList, true },
+	{ kEoB1Npc12Strings, kTypeStringList, true },
+	{ kEoB1Npc21Strings, kTypeStringList, true },
+	{ kEoB1Npc22Strings, kTypeStringList, true },
+	{ kEoB1Npc31Strings, kTypeStringList, true },
+	{ kEoB1Npc32Strings, kTypeStringList, true },
+	{ kEoB1Npc4Strings, kTypeStringList, true },
+	{ kEoB1Npc5Strings, kTypeStringList, true },
+	{ kEoB1Npc6Strings, kTypeStringList, true },
+	{ kEoB1Npc7Strings, kTypeStringList, true },
 
 	// EYE OF THE BEHOLDER II
-	{ kEob2MainMenuStrings, kTypeStringList, true },
-	{ kEob2TransferConvertTable, kTypeRawData, false },
-	{ kEob2TransferExpTable, kLolTypeRaw32, false },
-
-	{ kEob2IntroStrings, k2TypeSfxList, true },
-	{ kEob2IntroCPSFiles, kTypeStringList, true },
-	{ kEob2IntroSeqData00, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData01, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData02, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData03, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData04, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData05, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData06, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData07, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData08, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData09, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData10, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData11, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData12, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData13, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData14, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData15, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData16, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData17, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData18, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData19, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData20, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData21, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData22, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData23, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData24, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData25, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData26, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData27, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData28, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData29, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData30, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData31, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData32, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData33, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData34, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData35, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData36, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData37, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData38, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData39, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData40, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData41, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData42, kEob2TypeSeqData, false },
- 	{ kEob2IntroSeqData43, kEob2TypeSeqData, false },
-	{ kEob2IntroShapes00, kEob2TypeShapeData, false },
- 	{ kEob2IntroShapes01, kEob2TypeShapeData, false },
- 	{ kEob2IntroShapes04, kEob2TypeShapeData, false },
- 	{ kEob2IntroShapes07, kEob2TypeShapeData, false },
-
-	{ kEob2FinaleStrings, k2TypeSfxList, true },
-	{ kEob2CreditsData, kTypeRawData, true },
-	{ kEob2FinaleCPSFiles, kTypeStringList, true },
-	{ kEob2FinaleSeqData00, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData01, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData02, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData03, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData04, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData05, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData06, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData07, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData08, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData09, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData10, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData11, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData12, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData13, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData14, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData15, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData16, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData17, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData18, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData19, kEob2TypeSeqData, false },
- 	{ kEob2FinaleSeqData20, kEob2TypeSeqData, false },
-	{ kEob2FinaleShapes00, kEob2TypeShapeData, false },
- 	{ kEob2FinaleShapes03, kEob2TypeShapeData, false },
- 	{ kEob2FinaleShapes07, kEob2TypeShapeData, false },
- 	{ kEob2FinaleShapes09, kEob2TypeShapeData, false },
- 	{ kEob2FinaleShapes10, kEob2TypeShapeData, false },
-	{ kEob2NpcShapeData, kTypeRawData, false },
-	{ kEobBaseClassModifierFlags, kTypeRawData, false },
-	{ kEobBaseMonsterStepTable01, kTypeRawData, false },
-	{ kEobBaseMonsterStepTable02, kTypeRawData, false },
-	{ kEobBaseMonsterStepTable1, kTypeRawData, false },
-	{ kEobBaseMonsterStepTable2, k3TypeRaw16to8, false },
-	{ kEobBaseMonsterStepTable3, k3TypeRaw16to8, false },
-	{ kEobBaseMonsterCloseAttPosTable1, kTypeRawData, false },
-	{ kEobBaseMonsterCloseAttPosTable21, kTypeRawData, false },
-	{ kEobBaseMonsterCloseAttPosTable22, kTypeRawData, false },
-	{ kEobBaseMonsterCloseAttUnkTable, kTypeRawData, false },
-	{ kEobBaseMonsterCloseAttChkTable1, kTypeRawData, false },
-	{ kEobBaseMonsterCloseAttChkTable2, kTypeRawData, false },
-	{ kEobBaseMonsterCloseAttDstTable1, kTypeRawData, false },
-	{ kEobBaseMonsterCloseAttDstTable2, kTypeRawData, false },
-	{ kEobBaseMonsterProximityTable, kTypeRawData, false },
-	{ kEobBaseFindBlockMonstersTable, kTypeRawData, false },
-	{ kEobBaseMonsterDirChangeTable, kTypeRawData, false },
-	{ kEobBaseMonsterDistAttStrings, kTypeStringList, true },
-	{ kEobBaseEncodeMonsterDefs, kLolTypeRaw16, false },
-	{ kEobBaseNpcPresets, kEobTypeNpcData, false },
-	{ kEob2Npc1Strings, kTypeStringList, true },
-	{ kEob2Npc2Strings, kTypeStringList, true },
-	{ kEob2MonsterDustStrings, kTypeStringList, true },
-	{ kEob2DreamSteps, kTypeRawData, false },
-	{ kEob2KheldranStrings, kTypeStringList, true },
-	{ kEob2HornStrings, kTypeStringList, true },
-	{ kEob2HornSounds, kTypeRawData, false },
-	{ kEob2WallOfForceDsX, kLolTypeRaw16, false },
-	{ kEob2WallOfForceDsY, kTypeRawData, false },
-	{ kEob2WallOfForceNumW, kTypeRawData, false },
-	{ kEob2WallOfForceNumH, kTypeRawData, false },
-	{ kEob2WallOfForceShpId, kTypeRawData, false },
+	{ kEoB2MainMenuStrings, kTypeStringList, true },
+	{ kEoB2TransferConvertTable, kTypeRawData, false },
+	{ kEoB2TransferExpTable, kLoLTypeRaw32, false },
+
+	{ kEoB2IntroStrings, k2TypeSfxList, true },
+	{ kEoB2IntroCPSFiles, kTypeStringList, true },
+	{ kEoB2IntroSeqData00, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData01, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData02, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData03, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData04, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData05, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData06, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData07, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData08, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData09, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData10, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData11, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData12, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData13, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData14, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData15, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData16, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData17, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData18, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData19, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData20, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData21, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData22, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData23, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData24, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData25, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData26, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData27, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData28, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData29, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData30, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData31, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData32, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData33, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData34, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData35, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData36, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData37, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData38, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData39, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData40, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData41, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData42, kEoB2TypeSeqData, false },
+ 	{ kEoB2IntroSeqData43, kEoB2TypeSeqData, false },
+	{ kEoB2IntroShapes00, kEoB2TypeShapeData, false },
+ 	{ kEoB2IntroShapes01, kEoB2TypeShapeData, false },
+ 	{ kEoB2IntroShapes04, kEoB2TypeShapeData, false },
+ 	{ kEoB2IntroShapes07, kEoB2TypeShapeData, false },
+
+	{ kEoB2FinaleStrings, k2TypeSfxList, true },
+	{ kEoB2CreditsData, kTypeRawData, true },
+	{ kEoB2FinaleCPSFiles, kTypeStringList, true },
+	{ kEoB2FinaleSeqData00, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData01, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData02, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData03, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData04, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData05, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData06, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData07, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData08, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData09, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData10, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData11, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData12, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData13, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData14, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData15, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData16, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData17, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData18, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData19, kEoB2TypeSeqData, false },
+ 	{ kEoB2FinaleSeqData20, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleShapes00, kEoB2TypeShapeData, false },
+ 	{ kEoB2FinaleShapes03, kEoB2TypeShapeData, false },
+ 	{ kEoB2FinaleShapes07, kEoB2TypeShapeData, false },
+ 	{ kEoB2FinaleShapes09, kEoB2TypeShapeData, false },
+ 	{ kEoB2FinaleShapes10, kEoB2TypeShapeData, false },
+	{ kEoB2NpcShapeData, kTypeRawData, false },
+	{ kEoBBaseClassModifierFlags, kTypeRawData, false },
+	{ kEoBBaseMonsterStepTable01, kTypeRawData, false },
+	{ kEoBBaseMonsterStepTable02, kTypeRawData, false },
+	{ kEoBBaseMonsterStepTable1, kTypeRawData, false },
+	{ kEoBBaseMonsterStepTable2, k3TypeRaw16to8, false },
+	{ kEoBBaseMonsterStepTable3, k3TypeRaw16to8, false },
+	{ kEoBBaseMonsterCloseAttPosTable1, kTypeRawData, false },
+	{ kEoBBaseMonsterCloseAttPosTable21, kTypeRawData, false },
+	{ kEoBBaseMonsterCloseAttPosTable22, kTypeRawData, false },
+	{ kEoBBaseMonsterCloseAttUnkTable, kTypeRawData, false },
+	{ kEoBBaseMonsterCloseAttChkTable1, kTypeRawData, false },
+	{ kEoBBaseMonsterCloseAttChkTable2, kTypeRawData, false },
+	{ kEoBBaseMonsterCloseAttDstTable1, kTypeRawData, false },
+	{ kEoBBaseMonsterCloseAttDstTable2, kTypeRawData, false },
+	{ kEoBBaseMonsterProximityTable, kTypeRawData, false },
+	{ kEoBBaseFindBlockMonstersTable, kTypeRawData, false },
+	{ kEoBBaseMonsterDirChangeTable, kTypeRawData, false },
+	{ kEoBBaseMonsterDistAttStrings, kTypeStringList, true },
+	{ kEoBBaseEncodeMonsterDefs, kLoLTypeRaw16, false },
+	{ kEoBBaseNpcPresets, kEoBTypeNpcData, false },
+	{ kEoB2Npc1Strings, kTypeStringList, true },
+	{ kEoB2Npc2Strings, kTypeStringList, true },
+	{ kEoB2MonsterDustStrings, kTypeStringList, true },
+	{ kEoB2DreamSteps, kTypeRawData, false },
+	{ kEoB2KheldranStrings, kTypeStringList, true },
+	{ kEoB2HornStrings, kTypeStringList, true },
+	{ kEoB2HornSounds, kTypeRawData, false },
+	{ kEoB2WallOfForceDsX, kLoLTypeRaw16, false },
+	{ kEoB2WallOfForceDsY, kTypeRawData, false },
+	{ kEoB2WallOfForceNumW, kTypeRawData, false },
+	{ kEoB2WallOfForceNumH, kTypeRawData, false },
+	{ kEoB2WallOfForceShpId, kTypeRawData, false },
 	
 	// LANDS OF LORE
 
 	// Ingame
-	{ kLolIngamePakFiles, kTypeStringList, false },
-
-	{ kLolCharacterDefs, kLolTypeCharData, true },
-	{ kLolIngameSfxFiles, k2TypeSfxList, false },
-	{ kLolIngameSfxIndex, kTypeRawData, false },
-	{ kLolMusicTrackMap, kTypeRawData, false },
-	{ kLolIngameGMSfxIndex, kTypeRawData, false },
-	{ kLolIngameMT32SfxIndex, kTypeRawData, false },
-	{ kLolIngamePcSpkSfxIndex, kTypeRawData, false },
-	{ kLolSpellProperties, kLolTypeSpellData, false },
-	{ kLolGameShapeMap, kTypeRawData, false },
-	{ kLolSceneItemOffs, kTypeRawData, false },
-	{ kLolCharInvIndex, k3TypeRaw16to8, false },
-	{ kLolCharInvDefs, kTypeRawData, false },
-	{ kLolCharDefsMan, kLolTypeRaw16, false },
-	{ kLolCharDefsWoman, kLolTypeRaw16, false },
-	{ kLolCharDefsKieran, kLolTypeRaw16, false },
-	{ kLolCharDefsAkshel, kLolTypeRaw16, false },
-	{ kLolExpRequirements, kLolTypeRaw32, false },
-	{ kLolMonsterModifiers, kLolTypeRaw16, false },
-	{ kLolMonsterShiftOffsets, kTypeRawData, false },
-	{ kLolMonsterDirFlags, kTypeRawData, false },
-	{ kLolMonsterScaleY, kTypeRawData, false },
-	{ kLolMonsterScaleX, kTypeRawData, false },
-	{ kLolMonsterScaleWH, kLolTypeRaw16, false },
-	{ kLolFlyingObjectShp, kLolTypeFlightShpData, false },
-	{ kLolInventoryDesc, kLolTypeRaw16, false },
-	{ kLolLevelShpList, kTypeStringList, false },
-	{ kLolLevelDatList, kTypeStringList, false },
-	{ kLolCompassDefs, kLolTypeCompassData, false },
-	{ kLolItemPrices, kLolTypeRaw16, false },
-	{ kLolStashSetup, kTypeRawData, false },
-
-	{ kLolDscWalls, kTypeRawData, false },
-	{ kLolEobCommonDscShapeIndex, kTypeRawData, false },
-	{ kLolDscOvlMap, kTypeRawData, false },
-	{ kLolDscScaleWidthData, kLolTypeRaw16, false },
-	{ kLolDscScaleHeightData, kLolTypeRaw16, false },
-	{ kLolEobCommonDscX, kLolTypeRaw16, false },
-	{ kLolDscY, kTypeRawData, false },
-	{ kLolEobCommonDscTileIndex, kTypeRawData, false },
-	{ kLolEobCommonDscUnk2, kTypeRawData, false },
-	{ kLolEobCommonDscDoorShapeIndex, kTypeRawData, false },
-	{ kLolEobCommonDscDimData1, kTypeRawData, false },
-	{ kLolEobCommonDscDimData2, kTypeRawData, false },
-	{ kLolEobCommonDscBlockMap, kTypeRawData, false },
-	{ kLolEobCommonDscDimMap, kTypeRawData, false },
-	{ kLolDscDoorScale, kLolTypeRaw16, false },
-	{ kLolDscOvlIndex, k3TypeRaw16to8, false },
-	{ kLolEobCommonDscBlockIndex, kTypeRawData, false },
-	{ kLolDscDoor4, kLolTypeRaw16, false },
-	{ kLolEobCommonDscDoorY2, kTypeRawData, false },
-	{ kLolDscDoorX, kLolTypeRaw16, false },
-	{ kLolDscDoorY, kLolTypeRaw16, false },
-
-	{ kLolScrollXTop, k3TypeRaw16to8, false },
-	{ kLolScrollYTop, k3TypeRaw16to8, false },
-	{ kLolScrollXBottom, k3TypeRaw16to8, false },
-	{ kLolScrollYBottom, k3TypeRaw16to8, false },
-
-	{ kLolButtonDefs, kLolTypeButtonDef, false },
-	{ kLolButtonList1, kLolTypeRaw16, false },
-	{ kLolButtonList2, kLolTypeRaw16, false },
-	{ kLolButtonList3, kLolTypeRaw16, false },
-	{ kLolButtonList4, kLolTypeRaw16, false },
-	{ kLolButtonList5, kLolTypeRaw16, false },
-	{ kLolButtonList6, kLolTypeRaw16, false },
-	{ kLolButtonList7, kLolTypeRaw16, false },
-	{ kLolButtonList8, kLolTypeRaw16, false },
-
-	{ kLolLegendData, kTypeRawData, false },
-	{ kLolMapCursorOvl, kTypeRawData, false },
-	{ kLolMapStringId, kLolTypeRaw16, false },
-
-	{ kLolSpellbookAnim, k3TypeRaw16to8, false },
-	{ kLolSpellbookCoords, k3TypeRaw16to8, false },
-	{ kLolHealShapeFrames, kTypeRawData, false },
-	{ kLolLightningDefs, kTypeRawData, false },
-	{ kLolFireballCoords, kLolTypeRaw16, false },
-
-	{ kLolCredits, kTypeRawData, false },
-
-	{ kLolHistory, kTypeRawData, false },
+	{ kLoLIngamePakFiles, kTypeStringList, false },
+
+	{ kLoLCharacterDefs, kLoLTypeCharData, true },
+	{ kLoLIngameSfxFiles, k2TypeSfxList, false },
+	{ kLoLIngameSfxIndex, kTypeRawData, false },
+	{ kLoLMusicTrackMap, kTypeRawData, false },
+	{ kLoLIngameGMSfxIndex, kTypeRawData, false },
+	{ kLoLIngameMT32SfxIndex, kTypeRawData, false },
+	{ kLoLIngamePcSpkSfxIndex, kTypeRawData, false },
+	{ kLoLSpellProperties, kLoLTypeSpellData, false },
+	{ kLoLGameShapeMap, kTypeRawData, false },
+	{ kLoLSceneItemOffs, kTypeRawData, false },
+	{ kLoLCharInvIndex, k3TypeRaw16to8, false },
+	{ kLoLCharInvDefs, kTypeRawData, false },
+	{ kLoLCharDefsMan, kLoLTypeRaw16, false },
+	{ kLoLCharDefsWoman, kLoLTypeRaw16, false },
+	{ kLoLCharDefsKieran, kLoLTypeRaw16, false },
+	{ kLoLCharDefsAkshel, kLoLTypeRaw16, false },
+	{ kLoLExpRequirements, kLoLTypeRaw32, false },
+	{ kLoLMonsterModifiers, kLoLTypeRaw16, false },
+	{ kLoLMonsterShiftOffsets, kTypeRawData, false },
+	{ kLoLMonsterDirFlags, kTypeRawData, false },
+	{ kLoLMonsterScaleY, kTypeRawData, false },
+	{ kLoLMonsterScaleX, kTypeRawData, false },
+	{ kLoLMonsterScaleWH, kLoLTypeRaw16, false },
+	{ kLoLFlyingObjectShp, kLoLTypeFlightShpData, false },
+	{ kLoLInventoryDesc, kLoLTypeRaw16, false },
+	{ kLoLLevelShpList, kTypeStringList, false },
+	{ kLoLLevelDatList, kTypeStringList, false },
+	{ kLoLCompassDefs, kLoLTypeCompassData, false },
+	{ kLoLItemPrices, kLoLTypeRaw16, false },
+	{ kLoLStashSetup, kTypeRawData, false },
+
+	{ kLoLDscWalls, kTypeRawData, false },
+	{ kRpgCommonDscShapeIndex, kTypeRawData, false },
+	{ kLoLDscOvlMap, kTypeRawData, false },
+	{ kLoLDscScaleWidthData, kLoLTypeRaw16, false },
+	{ kLoLDscScaleHeightData, kLoLTypeRaw16, false },
+	{ kRpgCommonDscX, kLoLTypeRaw16, false },
+	{ kLoLDscY, kTypeRawData, false },
+	{ kRpgCommonDscTileIndex, kTypeRawData, false },
+	{ kRpgCommonDscUnk2, kTypeRawData, false },
+	{ kRpgCommonDscDoorShapeIndex, kTypeRawData, false },
+	{ kRpgCommonDscDimData1, kTypeRawData, false },
+	{ kRpgCommonDscDimData2, kTypeRawData, false },
+	{ kRpgCommonDscBlockMap, kTypeRawData, false },
+	{ kRpgCommonDscDimMap, kTypeRawData, false },
+	{ kLoLDscDoorScale, kLoLTypeRaw16, false },
+	{ kLoLDscOvlIndex, k3TypeRaw16to8, false },
+	{ kRpgCommonDscBlockIndex, kTypeRawData, false },
+	{ kLoLDscDoor4, kLoLTypeRaw16, false },
+	{ kRpgCommonDscDoorY2, kTypeRawData, false },
+	{ kLoLDscDoorX, kLoLTypeRaw16, false },
+	{ kLoLDscDoorY, kLoLTypeRaw16, false },
+
+	{ kLoLScrollXTop, k3TypeRaw16to8, false },
+	{ kLoLScrollYTop, k3TypeRaw16to8, false },
+	{ kLoLScrollXBottom, k3TypeRaw16to8, false },
+	{ kLoLScrollYBottom, k3TypeRaw16to8, false },
+
+	{ kLoLButtonDefs, kLoLTypeButtonDef, false },
+	{ kLoLButtonList1, kLoLTypeRaw16, false },
+	{ kLoLButtonList2, kLoLTypeRaw16, false },
+	{ kLoLButtonList3, kLoLTypeRaw16, false },
+	{ kLoLButtonList4, kLoLTypeRaw16, false },
+	{ kLoLButtonList5, kLoLTypeRaw16, false },
+	{ kLoLButtonList6, kLoLTypeRaw16, false },
+	{ kLoLButtonList7, kLoLTypeRaw16, false },
+	{ kLoLButtonList8, kLoLTypeRaw16, false },
+
+	{ kLoLLegendData, kTypeRawData, false },
+	{ kLoLMapCursorOvl, kTypeRawData, false },
+	{ kLoLMapStringId, kLoLTypeRaw16, false },
+
+	{ kLoLSpellbookAnim, k3TypeRaw16to8, false },
+	{ kLoLSpellbookCoords, k3TypeRaw16to8, false },
+	{ kLoLHealShapeFrames, kTypeRawData, false },
+	{ kLoLLightningDefs, kTypeRawData, false },
+	{ kLoLFireballCoords, kLoLTypeRaw16, false },
+
+	{ kLoLCredits, kTypeRawData, false },
+
+	{ kLoLHistory, kTypeRawData, false },
 
 	{ -1, 0, 0 }
 };
@@ -691,9 +691,9 @@ const TypeTable gameTable[] = {
 	{ kKyra1, 0 },
 	{ kKyra2, 1 },
 	{ kKyra3, 2 },
-	{ kEob1, 3 },
-	{ kEob2, 4 },
-	{ kLol, 5 },
+	{ kEoB1, 3 },
+	{ kEoB2, 4 },
+	{ kLoL, 5 },
 	{ -1, -1 }
 };
 
@@ -1347,817 +1347,817 @@ const char *getIdString(const int id) {
 		return "k3ItemMagicTable";
 	case k3ItemStringMap:
 		return "k3ItemStringMap";
-	case kEobBaseChargenStrings1:
-		return "kEobBaseChargenStrings1";
-	case kEobBaseChargenStrings2:
-		return "kEobBaseChargenStrings2";
-	case kEobBaseChargenStartLevels:
-		return "kEobBaseChargenStartLevels";
-	case kEobBaseChargenStatStrings:
-		return "kEobBaseChargenStatStrings";
-	case kEobBaseChargenRaceSexStrings:
-		return "kEobBaseChargenRaceSexStrings";
-	case kEobBaseChargenClassStrings:
-		return "kEobBaseChargenClassStrings";
-	case kEobBaseChargenAlignmentStrings:
-		return "kEobBaseChargenAlignmentStrings";
-	case kEobBaseChargenEnterGameStrings:
-		return "kEobBaseChargenEnterGameStrings";
-	case kEobBaseChargenClassMinStats:
-		return "kEobBaseChargenClassMinStats";
-	case kEobBaseChargenRaceMinStats:
-		return "kEobBaseChargenRaceMinStats";
-	case kEobBaseChargenRaceMaxStats:
-		return "kEobBaseChargenRaceMaxStats";
-	case kEobBaseSaveThrowTable1:
-		return "kEobBaseSaveThrowTable1";
-	case kEobBaseSaveThrowTable2:
-		return "kEobBaseSaveThrowTable2";
-	case kEobBaseSaveThrowTable3:
-		return "kEobBaseSaveThrowTable3";
-	case kEobBaseSaveThrowTable4:
-		return "kEobBaseSaveThrowTable4";
-	case kEobBaseSaveThrwLvlIndex:
-		return "kEobBaseSaveThrwLvlIndex";
-	case kEobBaseSaveThrwModDiv:
-		return "kEobBaseSaveThrwModDiv";
-	case kEobBaseSaveThrwModExt:
-		return "kEobBaseSaveThrwModExt";
-	case kEobBasePryDoorStrings:
-		return "kEobBasePryDoorStrings";
-	case kEobBaseWarningStrings:
-		return "kEobBaseWarningStrings";
-	case kEobBaseItemSuffixStringsRings:
-		return "kEobBaseItemSuffixStringsRings";
-	case kEobBaseItemSuffixStringsPotions:
-		return "kEobBaseItemSuffixStringsPotions";
-	case kEobBaseItemSuffixStringsWands:
-		return "kEobBaseItemSuffixStringsWands";
-	case kEobBaseRipItemStrings:
-		return "kEobBaseRipItemStrings";
-	case kEobBaseCursedString:
-		return "kEobBaseCursedString";
-	case kEobBaseEnchantedString:
-		return "kEobBaseEnchantedString";
-	case kEobBaseMagicObjectStrings:
-		return "kEobBaseMagicObjectStrings";
-	case kEobBaseMagicObject5String:
-		return "kEobBaseMagicObject5String";
-	case kEobBasePatternSuffix:
-		return "kEobBasePatternSuffix";
-	case kEobBasePatternGrFix1:
-		return "kEobBasePatternGrFix1";
-	case kEobBasePatternGrFix2:
-		return "kEobBasePatternGrFix2";
-	case kEobBaseValidateArmorString:
-		return "kEobBaseValidateArmorString";
-	case kEobBaseValidateCursedString:
-		return "kEobBaseValidateCursedString";
-	case kEobBaseValidateNoDropString:
-		return "kEobBaseValidateNoDropString";
-	case kEobBasePotionStrings:
-		return "kEobBasePotionStrings";
-	case kEobBaseWandString:
-		return "kEobBaseWandString";
-	case kEobBaseItemMisuseStrings:
-		return "kEobBaseItemMisuseStrings";
-	case kEobBaseTakenStrings:
-		return "kEobBaseTakenStrings";
-	case kEobBasePotionEffectStrings:
-		return "kEobBasePotionEffectStrings";
-	case kEobBaseYesNoStrings:
-		return "kEobBaseYesNoStrings";
-	case kLolEobCommonMoreStrings:
-		return "kLolEobCommonMoreStrings";
-	case kEobBaseNpcMaxStrings:
-		return "kEobBaseNpcMaxStrings";
-	case kEobBaseOkStrings:
-		return "kEobBaseOkStrings";
-	case kEobBaseNpcJoinStrings:
-		return "kEobBaseNpcJoinStrings";		
-	case kEobBaseCancelStrings:
-		return "kEobBaseCancelStrings";
-	case kEobBaseAbortStrings:
-		return "kEobBaseAbortStrings";
-	case kEobBaseMenuStringsMain:
-		return "kEobBaseMenuStringsMain";
-	case kEobBaseMenuStringsSaveLoad:
-		return "kEobBaseMenuStringsSaveLoad";
-	case kEobBaseMenuStringsOnOff:
-		return "kEobBaseMenuStringsOnOff";
-	case kEobBaseMenuStringsSpells:
-		return "kEobBaseMenuStringsSpells";
-	case kEobBaseMenuStringsRest:
-		return "kEobBaseMenuStringsRest";
-	case kEobBaseMenuStringsDrop:
-		return "kEobBaseMenuStringsDrop";
-	case kEobBaseMenuStringsExit:
-		return "kEobBaseMenuStringsExit";
-	case kEobBaseMenuStringsStarve:
-		return "kEobBaseMenuStringsStarve";
-	case kEobBaseMenuStringsScribe:
-		return "kEobBaseMenuStringsScribe";
-	case kEobBaseMenuStringsDrop2:
-		return "kEobBaseMenuStringsDrop2";
-	case kEobBaseMenuStringsHead:
-		return "kEobBaseMenuStringsHead";
-	case kEobBaseMenuStringsPoison:
-		return "kEobBaseMenuStringsPoison";
-	case kEobBaseMenuStringsMgc:
-		return "kEobBaseMenuStringsMgc";
-	case kEobBaseMenuStringsPrefs:
-		return "kEobBaseMenuStringsPrefs";
-	case kEobBaseMenuStringsRest2:
-		return "kEobBaseMenuStringsRest2";
-	case kEobBaseMenuStringsRest3:
-		return "kEobBaseMenuStringsRest3";
-	case kEobBaseMenuStringsRest4:
-		return "kEobBaseMenuStringsRest4";
-	case kEobBaseMenuStringsDefeat:
-		return "kEobBaseMenuStringsDefeat";
-	case kEobBaseMenuStringsTransfer:
-		return "kEobBaseMenuStringsTransfer";
-	case kEobBaseMenuStringsSpec:
-		return "kEobBaseMenuStringsSpec";
-	case kEobBaseMenuStringsSpellNo:
-		return "kEobBaseMenuStringsSpellNo";
-	case kEobBaseMenuYesNoStrings:
-		return "kEobBaseMenuYesNoStrings";
-	case kEobBaseSpellLevelsMage:
-		return "kEobBaseSpellLevelsMage";
-	case kEobBaseSpellLevelsCleric:
-		return "kEobBaseSpellLevelsCleric";
-	case kEobBaseNumSpellsCleric:
-		return "kEobBaseNumSpellsCleric";
-	case kEobBaseNumSpellsWisAdj:
-		return "kEobBaseNumSpellsWisAdj";
-	case kEobBaseNumSpellsPal:
-		return "kEobBaseNumSpellsPal";
-	case kEobBaseNumSpellsMage:
-		return "kEobBaseNumSpellsMage";
-	case kEobBaseCharGuiStringsHp:
-		return "kEobBaseCharGuiStringsHp";
-	case kEobBaseCharGuiStringsWp1:
-		return "kEobBaseCharGuiStringsWp1";
-	case kEobBaseCharGuiStringsWp2:
-		return "kEobBaseCharGuiStringsWp2";
-	case kEobBaseCharGuiStringsWr:
-		return "kEobBaseCharGuiStringsWr";
-	case kEobBaseCharGuiStringsSt1:
-		return "kEobBaseCharGuiStringsSt1";
-	case kEobBaseCharGuiStringsSt2:
-		return "kEobBaseCharGuiStringsSt2";
-	case kEobBaseCharGuiStringsIn:
-		return "kEobBaseCharGuiStringsIn";
-	case kEobBaseCharStatusStrings7:
-		return "kEobBaseCharStatusStrings7";
-	case kEobBaseCharStatusStrings81:
-		return "kEobBaseCharStatusStrings81";
-	case kEobBaseCharStatusStrings82:
-		return "kEobBaseCharStatusStrings82";
-	case kEobBaseCharStatusStrings9:
-		return "kEobBaseCharStatusStrings9";
-	case kEobBaseCharStatusStrings12:
-		return "kEobBaseCharStatusStrings12";
-	case kEobBaseCharStatusStrings131:
-		return "kEobBaseCharStatusStrings131";
-	case kEobBaseCharStatusStrings132:
-		return "kEobBaseCharStatusStrings132";
-	case kEobBaseLevelGainStrings:
-		return "kEobBaseLevelGainStrings";
-	case kEobBaseExperienceTable0:
-		return "kEobBaseExperienceTable0";
-	case kEobBaseExperienceTable1:
-		return "kEobBaseExperienceTable1";
-	case kEobBaseExperienceTable2:
-		return "kEobBaseExperienceTable2";
-	case kEobBaseExperienceTable3:
-		return "kEobBaseExperienceTable3";
-	case kEobBaseExperienceTable4:
-		return "kEobBaseExperienceTable4";
-	case kEobBaseWllFlagPreset:
-		return "kEobBaseWllFlagPreset";
-	case kEobBaseDscShapeCoords:
-		return "kEobBaseDscShapeCoords";
-	case kEobBaseDscDoorScaleOffs:
-		return "kEobBaseDscDoorScaleOffs";
-	case kEobBaseDscDoorScaleMult1:
-		return "kEobBaseDscDoorScaleMult1";
-	case kEobBaseDscDoorScaleMult2:
-		return "kEobBaseDscDoorScaleMult2";
-	case kEobBaseDscDoorScaleMult3:
-		return "kEobBaseDscDoorScaleMult3";
-	case kEobBaseDscDoorScaleMult4:
-		return "kEobBaseDscDoorScaleMult4";
-	case kEobBaseDscDoorScaleMult5:
-		return "kEobBaseDscDoorScaleMult5";
-	case kEobBaseDscDoorScaleMult6:
-		return "kEobBaseDscDoorScaleMult6";
-	case kEobBaseDscDoorType5Offs:
-		return "kEobBaseDscDoorType5Offs";
-	case kEobBaseDscDoorXE:
-		return "kEobBaseDscDoorXE";
-	case kEobBaseDscDoorY1:
-		return "kEobBaseDscDoorY1";
-	case kEobBaseDscDoorY3:
-		return "kEobBaseDscDoorY3";
-	case kEobBaseDscDoorY4:
-		return "kEobBaseDscDoorY4";
-	case kEobBaseDscDoorY5:
-		return "kEobBaseDscDoorY5";
-	case kEobBaseDscDoorY6:
-		return "kEobBaseDscDoorY6";
-	case kEobBaseDscDoorY7:
-		return "kEobBaseDscDoorY7";
-	case kEobBaseDscDoorCoordsExt:
-		return "kEobBaseDscDoorCoordsExt";
-	case kEobBaseDscItemPosIndex:
-		return "kEobBaseDscItemPosIndex";
-	case kEobBaseDscItemShpX:
-		return "kEobBaseDscItemShpX";
-	case kEobBaseDscItemPosUnk:
-		return "kEobBaseDscItemPosUnk";
-	case kEobBaseDscItemTileIndex:
-		return "kEobBaseDscItemTileIndex";
-	case kEobBaseDscItemShapeMap:
-		return "kEobBaseDscItemShapeMap";
-	case kEobBaseDscMonsterFrmOffsTbl1:
-		return "kEobBaseDscMonsterFrmOffsTbl1";
-	case kEobBaseDscMonsterFrmOffsTbl2:
-		return "kEobBaseDscMonsterFrmOffsTbl2";
-	case kEobBaseInvSlotX:
-		return "kEobBaseInvSlotX";
-	case kEobBaseInvSlotY:
-		return "kEobBaseInvSlotY";
-	case kEobBaseSlotValidationFlags:
-		return "kEobBaseSlotValidationFlags";
-	case kEobBaseProjectileWeaponTypes:
-		return "kEobBaseProjectileWeaponTypes";
-	case kEobBaseWandTypes:
-		return "kEobBaseWandTypes";
-	case kEobBaseDrawObjPosIndex:
-		return "kEobBaseDrawObjPosIndex";
-	case kEobBaseFlightObjFlipIndex:
-		return "kEobBaseFlightObjFlipIndex";
-	case kEobBaseFlightObjShpMap:
-		return "kEobBaseFlightObjShpMap";
-	case kEobBaseFlightObjSclIndex:
-		return "kEobBaseFlightObjSclIndex";
-	case kEobBaseDscTelptrShpCoords:
-		return "kEobBaseDscTelptrShpCoords";
-	case kEobBasePortalSeqData:
-		return "kEobBasePortalSeqData";
-	case kEobBaseManDef:
-		return "kEobBaseManDef";
-	case kEobBaseManWord:
-		return "kEobBaseManWord";
-	case kEobBaseManPrompt:
-		return "kEobBaseManPrompt";
-	case kEobBaseBookNumbers:
-		return "kEobBaseBookNumbers";
-	case kEobBaseMageSpellsList:
-		return "kEobBaseMageSpellsList";
-	case kEobBaseClericSpellsList:
-		return "kEobBaseClericSpellsList";
-	case kEobBaseSpellNames:
-		return "kEobBaseSpellNames";
-
-	case kEobBaseMagicStrings1:
-		return "kEobBaseMagicStrings1";
-	case kEobBaseMagicStrings2:
-		return "kEobBaseMagicStrings2";
-	case kEobBaseMagicStrings3:
-		return "kEobBaseMagicStrings3";
-	case kEobBaseMagicStrings4:
-		return "kEobBaseMagicStrings4";
-	case kEobBaseMagicStrings6:
-		return "kEobBaseMagicStrings6";
-	case kEobBaseMagicStrings7:
-		return "kEobBaseMagicStrings7";
-	case kEobBaseMagicStrings8:
-		return "kEobBaseMagicStrings8";
-	case kEobBaseExpObjectTlMode:
-		return "kEobBaseExpObjectTlMode";
-	case kEobBaseExpObjectTblIndex:
-		return "kEobBaseExpObjectTblIndex";
-	case kEobBaseExpObjectShpStart:
-		return "kEobBaseExpObjectShpStart";
-	case kEobBaseExpObjectTbl1:
-		return "kEobBaseExpObjectTbl1";
-	case kEobBaseExpObjectTbl2:
-		return "kEobBaseExpObjectTbl2";
-	case kEobBaseExpObjectTbl3:
-		return "kEobBaseExpObjectTbl3";
-	case kEobBaseExpObjectY:
-		return "kEobBaseExpObjectY";
-	case kEobBaseSparkDefSteps:
-		return "kEobBaseSparkDefSteps";
-	case kEobBaseSparkDefSubSteps:
-		return "kEobBaseSparkDefSubSteps";
-	case kEobBaseSparkDefShift:
-		return "kEobBaseSparkDefShift";
-	case kEobBaseSparkDefAdd:
-		return "kEobBaseSparkDefAdd";
-	case kEobBaseSparkDefX:
-		return "kEobBaseSparkDefX";
-	case kEobBaseSparkDefY:
-		return "kEobBaseSparkDefY";
-	case kEobBaseSparkOfFlags1:
-		return "kEobBaseSparkOfFlags1";
-	case kEobBaseSparkOfFlags2:
-		return "kEobBaseSparkOfFlags2";
-	case kEobBaseSparkOfShift:
-		return "kEobBaseSparkOfShift";
-	case kEobBaseSparkOfX:
-		return "kEobBaseSparkOfX";
-	case kEobBaseSparkOfY:
-		return "kEobBaseSparkOfY";
-	case kEobBaseSpellProperties:
-		return "kEobBaseSpellProperties";
-	case kEobBaseMagicFlightProps:
-		return "kEobBaseMagicFlightProps";
-	case kEobBaseTurnUndeadEffect:
-		return "kEobBaseTurnUndeadEffect";
-	case kEobBaseBurningHandsDest:
-		return "kEobBaseBurningHandsDest";
-	case kEobBaseConeOfColdDest1:
-		return "kEobBaseConeOfColdDest1";
-	case kEobBaseConeOfColdDest2:
-		return "kEobBaseConeOfColdDest2";
-	case kEobBaseConeOfColdDest3:
-		return "kEobBaseConeOfColdDest3";
-	case kEobBaseConeOfColdDest4:
-		return "kEobBaseConeOfColdDest4";
-	case kEobBaseConeOfColdGfxTbl:
-		return "kEobBaseConeOfColdGfxTbl";
-	case kEob1MainMenuStrings:
-		return "kEob1MainMenuStrings";
-	case kEob1BonusStrings:
-		return "kEob1BonusStrings";
-	case kEob1IntroFilesOpening:
-		return "kEob1IntroFilesOpening";
-	case kEob1IntroFilesTower:
-		return "kEob1IntroFilesTower";
-	case kEob1IntroFilesOrb:
-		return "kEob1IntroFilesOrb";
-	case kEob1IntroFilesWdEntry:
-		return "kEob1IntroFilesWdEntry";
-	case kEob1IntroFilesKing:
-		return "kEob1IntroFilesKing";
-	case kEob1IntroFilesHands:
-		return "kEob1IntroFilesHands";
-	case kEob1IntroFilesWdExit:
-		return "kEob1IntroFilesWdExit";
-	case kEob1IntroFilesTunnel:
-		return "kEob1IntroFilesTunnel";
-	case kEob1IntroOpeningFrmDelay:
-		return "kEob1IntroOpeningFrmDelay";
-	case kEob1IntroWdEncodeX:
-		return "kEob1IntroWdEncodeX";
-	case kEob1IntroWdEncodeY:
-		return "kEob1IntroWdEncodeY";
-	case kEob1IntroWdEncodeWH:
-		return "kEob1IntroWdEncodeWH";
-	case kEob1IntroWdDsX:
-		return "kEob1IntroWdDsX";
-	case kEob1IntroWdDsY:
-		return "kEob1IntroWdDsY";
-	case kEob1IntroTvlX1:
-		return "kEob1IntroTvlX1";
-	case kEob1IntroTvlY1:
-		return "kEob1IntroTvlY1";
-	case kEob1IntroTvlX2:
-		return "kEob1IntroTvlX2";
-	case kEob1IntroTvlY2:
-		return "kEob1IntroTvlY2";
-	case kEob1IntroTvlW:
-		return "kEob1IntroTvlW";
-	case kEob1IntroTvlH:
-		return "kEob1IntroTvlH";
-	case kEob1DoorShapeDefs:
-		return "kEob1DoorShapeDefs";
-	case kEob1DoorSwitchCoords:
-		return "kEob1DoorSwitchCoords";
-	case kEob1MonsterProperties:
-		return "kEob1MonsterProperties";
-	case kEob1EnemyMageSpellList:
-		return "kEob1EnemyMageSpellList";
-	case kEob1EnemyMageSfx:
-		return "kEob1EnemyMageSfx";
-	case kEob1BeholderSpellList:
-		return "kEob1BeholderSpellList";
-	case kEob1BeholderSfx:
-		return "kEob1BeholderSfx";
-	case kEob1TurnUndeadString:
-		return "kEob1TurnUndeadString";
-	case kEob1NpcShpData:
-		return "kEob1NpcShpData";
-	case kEob1NpcSubShpIndex1:
-		return "kEob1NpcSubShpIndex1";
-	case kEob1NpcSubShpIndex2:
-		return "kEob1NpcSubShpIndex2";
-	case kEob1NpcSubShpY:
-		return "kEob1NpcSubShpY";
-	case kEob1Npc0Strings:
-		return "kEob1Npc0Strings";
-	case kEob1Npc11Strings:
-		return "kEob1Npc11Strings";
-	case kEob1Npc12Strings:
-		return "kEob1Npc12Strings";
-	case kEob1Npc21Strings:
-		return "kEob1Npc21Strings";
-	case kEob1Npc22Strings:
-		return "kEob1Npc22Strings";
-	case kEob1Npc31Strings:
-		return "kEob1Npc31Strings";
-	case kEob1Npc32Strings:
-		return "kEob1Npc32Strings";
-	case kEob1Npc4Strings:
-		return "kEob1Npc4Strings";
-	case kEob1Npc5Strings:
-		return "kEob1Npc5Strings";
-	case kEob1Npc6Strings:
-		return "kEob1Npc6Strings";
-	case kEob1Npc7Strings:
-		return "kEob1Npc7Strings";
-	case kEob2MainMenuStrings:
-		return "kEob2MainMenuStrings";
-	case kEob2TransferConvertTable:
-		return "kEob2TransferConvertTable";
-	case kEob2TransferExpTable:
-		return "kEob2TransferExpTable";
-	case kEob2IntroStrings:
-		return "kEob2IntroStrings";
-	case kEob2IntroCPSFiles:
-		return "kEob2IntroCPSFiles";
-	case kEob2IntroSeqData00:
-		return "kEob2IntroSeqData00";
- 	case kEob2IntroSeqData01:
-		return "kEob2IntroSeqData01";
- 	case kEob2IntroSeqData02:
-		return "kEob2IntroSeqData02";
- 	case kEob2IntroSeqData03:
-		return "kEob2IntroSeqData03";
- 	case kEob2IntroSeqData04:
-		return "kEob2IntroSeqData04";
- 	case kEob2IntroSeqData05:
-		return "kEob2IntroSeqData05";
- 	case kEob2IntroSeqData06:
-		return "kEob2IntroSeqData06";
- 	case kEob2IntroSeqData07:
-		return "kEob2IntroSeqData07";
- 	case kEob2IntroSeqData08:
-		return "kEob2IntroSeqData08";
- 	case kEob2IntroSeqData09:
-		return "kEob2IntroSeqData09";
- 	case kEob2IntroSeqData10:
-		return "kEob2IntroSeqData10";
- 	case kEob2IntroSeqData11:
-		return "kEob2IntroSeqData11";
- 	case kEob2IntroSeqData12:
-		return "kEob2IntroSeqData12";
- 	case kEob2IntroSeqData13:
-		return "kEob2IntroSeqData13";
- 	case kEob2IntroSeqData14:
-		return "kEob2IntroSeqData14";
- 	case kEob2IntroSeqData15:
-		return "kEob2IntroSeqData15";
- 	case kEob2IntroSeqData16:
-		return "kEob2IntroSeqData16";
- 	case kEob2IntroSeqData17:
-		return "kEob2IntroSeqData17";
- 	case kEob2IntroSeqData18:
-		return "kEob2IntroSeqData18";
- 	case kEob2IntroSeqData19:
-		return "kEob2IntroSeqData19";
- 	case kEob2IntroSeqData20:
-		return "kEob2IntroSeqData20";
- 	case kEob2IntroSeqData21:
-		return "kEob2IntroSeqData21";
- 	case kEob2IntroSeqData22:
-		return "kEob2IntroSeqData22";
- 	case kEob2IntroSeqData23:
-		return "kEob2IntroSeqData23";
- 	case kEob2IntroSeqData24:
-		return "kEob2IntroSeqData24";
- 	case kEob2IntroSeqData25:
-		return "kEob2IntroSeqData25";
- 	case kEob2IntroSeqData26:
-		return "kEob2IntroSeqData26";
- 	case kEob2IntroSeqData27:
-		return "kEob2IntroSeqData27";
- 	case kEob2IntroSeqData28:
-		return "kEob2IntroSeqData28";
- 	case kEob2IntroSeqData29:
-		return "kEob2IntroSeqData29";
- 	case kEob2IntroSeqData30:
-		return "kEob2IntroSeqData30";
- 	case kEob2IntroSeqData31:
-		return "kEob2IntroSeqData31";
- 	case kEob2IntroSeqData32:
-		return "kEob2IntroSeqData32";
- 	case kEob2IntroSeqData33:
-		return "kEob2IntroSeqData33";
- 	case kEob2IntroSeqData34:
-		return "kEob2IntroSeqData34";
- 	case kEob2IntroSeqData35:
-		return "kEob2IntroSeqData35";
- 	case kEob2IntroSeqData36:
-		return "kEob2IntroSeqData36";
- 	case kEob2IntroSeqData37:
-		return "kEob2IntroSeqData37";
- 	case kEob2IntroSeqData38:
-		return "kEob2IntroSeqData38";
- 	case kEob2IntroSeqData39:
-		return "kEob2IntroSeqData39";
- 	case kEob2IntroSeqData40:
-		return "kEob2IntroSeqData40";
- 	case kEob2IntroSeqData41:
-		return "kEob2IntroSeqData41";
- 	case kEob2IntroSeqData42:
-		return "kEob2IntroSeqData42";
- 	case kEob2IntroSeqData43:
-		return "kEob2IntroSeqData43";
- 	case kEob2IntroShapes00:
-		return "kEob2IntroShapes00";
- 	case kEob2IntroShapes01:
-		return "kEob2IntroShapes01";
- 	case kEob2IntroShapes04:
-		return "kEob2IntroShapes04";
- 	case kEob2IntroShapes07:
-		return "kEob2IntroShapes07";
-	case kEob2FinaleStrings:
-		return "kEob2FinaleStrings";
-	case kEob2CreditsData:
-		return "kEob2CreditsData";
-	case kEob2FinaleCPSFiles:
-		return "kEob2FinaleCPSFiles";		
- 	case kEob2FinaleSeqData00:
-		return "kEob2FinaleSeqData00";
- 	case kEob2FinaleSeqData01:
-		return "kEob2FinaleSeqData01";
- 	case kEob2FinaleSeqData02:
-		return "kEob2FinaleSeqData02";
- 	case kEob2FinaleSeqData03:
-		return "kEob2FinaleSeqData03";
- 	case kEob2FinaleSeqData04:
-		return "kEob2FinaleSeqData04";
- 	case kEob2FinaleSeqData05:
-		return "kEob2FinaleSeqData05";
- 	case kEob2FinaleSeqData06:
-		return "kEob2FinaleSeqData06";
- 	case kEob2FinaleSeqData07:
-		return "kEob2FinaleSeqData07";
- 	case kEob2FinaleSeqData08:
-		return "kEob2FinaleSeqData08";
- 	case kEob2FinaleSeqData09:
-		return "kEob2FinaleSeqData09";
- 	case kEob2FinaleSeqData10:
-		return "kEob2FinaleSeqData10";
- 	case kEob2FinaleSeqData11:
-		return "kEob2FinaleSeqData11";
- 	case kEob2FinaleSeqData12:
-		return "kEob2FinaleSeqData12";
- 	case kEob2FinaleSeqData13:
-		return "kEob2FinaleSeqData13";
- 	case kEob2FinaleSeqData14:
-		return "kEob2FinaleSeqData14";
- 	case kEob2FinaleSeqData15:
-		return "kEob2FinaleSeqData15";
- 	case kEob2FinaleSeqData16:
-		return "kEob2FinaleSeqData16";
- 	case kEob2FinaleSeqData17:
-		return "kEob2FinaleSeqData17";
- 	case kEob2FinaleSeqData18:
-		return "kEob2FinaleSeqData18";
- 	case kEob2FinaleSeqData19:
-		return "kEob2FinaleSeqData19";
- 	case kEob2FinaleSeqData20:
-		return "kEob2FinaleSeqData20";	
- 	case kEob2FinaleShapes00:
-		return "kEob2FinaleShapes00";
- 	case kEob2FinaleShapes03:
-		return "kEob2FinaleShapes03";
- 	case kEob2FinaleShapes07:
-		return "kEob2FinaleShapes07";
- 	case kEob2FinaleShapes09:
-		return "kEob2FinaleShapes09";
- 	case kEob2FinaleShapes10:
-		return "kEob2FinaleShapes10";
-	case kEob2NpcShapeData:
-		return "kEob2NpcShapeData";
-	case kEobBaseClassModifierFlags:
-		return "kEobBaseClassModifierFlags";
-	case kEobBaseMonsterStepTable01:
-		return "kEobBaseMonsterStepTable01";
-	case kEobBaseMonsterStepTable02:
-		return "kEobBaseMonsterStepTable02";
-	case kEobBaseMonsterStepTable1:
-		return "kEobBaseMonsterStepTable1";
-	case kEobBaseMonsterStepTable2:
-		return "kEobBaseMonsterStepTable2";
-	case kEobBaseMonsterStepTable3:
-		return "kEobBaseMonsterStepTable3";
-	case kEobBaseMonsterCloseAttPosTable1:
-		return "kEobBaseMonsterCloseAttPosTable1";
-	case kEobBaseMonsterCloseAttPosTable21:
-		return "kEobBaseMonsterCloseAttPosTable21";
-	case kEobBaseMonsterCloseAttPosTable22:
-		return "kEobBaseMonsterCloseAttPosTable22";
-	case kEobBaseMonsterCloseAttUnkTable:
-		return "kEobBaseMonsterCloseAttUnkTable";
-	case kEobBaseMonsterCloseAttChkTable1:
-		return "kEobBaseMonsterCloseAttChkTable1";
-	case kEobBaseMonsterCloseAttChkTable2:
-		return "kEobBaseMonsterCloseAttChkTable2";
-	case kEobBaseMonsterCloseAttDstTable1:
-		return "kEobBaseMonsterCloseAttDstTable1";
-	case kEobBaseMonsterCloseAttDstTable2:
-		return "kEobBaseMonsterCloseAttDstTable2";
-	case kEobBaseMonsterProximityTable:
-		return "kEobBaseMonsterProximityTable";
-	case kEobBaseFindBlockMonstersTable:
-		return "kEobBaseFindBlockMonstersTable";
-	case kEobBaseMonsterDirChangeTable:
-		return "kEobBaseMonsterDirChangeTable";
-	case kEobBaseMonsterDistAttStrings:
-		return "kEobBaseMonsterDistAttStrings";
-	case kEobBaseEncodeMonsterDefs:
-		return "kEobBaseEncodeMonsterDefs";
-	case kEobBaseNpcPresets:
-		return "kEobBaseNpcPresets";
-	case kEob2Npc1Strings:
-		return "kEob2Npc1Strings";
-	case kEob2Npc2Strings:
-		return "kEob2Npc2Strings";
-	case kEob2MonsterDustStrings:
-		return "kEob2MonsterDustStrings";
-	case kEob2DreamSteps:
-		return "kEob2DreamSteps";
-	case kEob2KheldranStrings:
-		return "kEob2KheldranStrings";
-	case kEob2HornStrings:
-		return "kEob2HornStrings";
-	case kEob2HornSounds:
-		return "kEob2HornSounds";
-	case kEob2WallOfForceDsX:
-		return "kEob2WallOfForceDsX";
-	case kEob2WallOfForceDsY:
-		return "kEob2WallOfForceDsY";
-	case kEob2WallOfForceNumW:
-		return "kEob2WallOfForceNumW";
-	case kEob2WallOfForceNumH:
-		return "kEob2WallOfForceNumH";
-	case kEob2WallOfForceShpId:
-		return "kEob2WallOfForceShpId";
-	case kLolIngamePakFiles:
-		return "kLolIngamePakFiles";
-	case kLolCharacterDefs:
-		return "kLolCharacterDefs";
-	case kLolIngameSfxFiles:
-		return "kLolIngameSfxFiles";
-	case kLolIngameSfxIndex:
-		return "kLolIngameSfxIndex";
-	case kLolMusicTrackMap:
-		return "kLolMusicTrackMap";
-	case kLolIngameGMSfxIndex:
-		return "kLolIngameGMSfxIndex";
-	case kLolIngameMT32SfxIndex:
-		return "kLolIngameMT32SfxIndex";
-	case kLolIngamePcSpkSfxIndex:
-		return "kLolIngamePcSpkSfxIndex";
-	case kLolSpellProperties:
-		return "kLolSpellProperties";
-	case kLolGameShapeMap:
-		return "kLolGameShapeMap";
-	case kLolSceneItemOffs:
-		return "kLolSceneItemOffs";
-	case kLolCharInvIndex:
-		return "kLolCharInvIndex";
-	case kLolCharInvDefs:
-		return "kLolCharInvDefs";
-	case kLolCharDefsMan:
-		return "kLolCharDefsMan";
-	case kLolCharDefsWoman:
-		return "kLolCharDefsWoman";
-	case kLolCharDefsKieran:
-		return "kLolCharDefsKieran";
-	case kLolCharDefsAkshel:
-		return "kLolCharDefsAkshel";
-	case kLolExpRequirements:
-		return "kLolExpRequirements";
-	case kLolMonsterModifiers:
-		return "kLolMonsterModifiers";
-	case kLolMonsterShiftOffsets:
-		return "kLolMonsterShiftOffsets";
-	case kLolMonsterDirFlags:
-		return "kLolMonsterDirFlags";
-	case kLolMonsterScaleY:
-		return "kLolMonsterScaleY";
-	case kLolMonsterScaleX:
-		return "kLolMonsterScaleX";
-	case kLolMonsterScaleWH:
-		return "kLolMonsterScaleWH";
-	case kLolFlyingObjectShp:
-		return "kLolFlyingObjectShp";
-	case kLolInventoryDesc:
-		return "kLolInventoryDesc";
-	case kLolLevelShpList:
-		return "kLolLevelShpList";
-	case kLolLevelDatList:
-		return "kLolLevelDatList";
-	case kLolCompassDefs:
-		return "kLolCompassDefs";
-	case kLolItemPrices:
-		return "kLolItemPrices";
-	case kLolStashSetup:
-		return "kLolStashSetup";
-	case kLolDscWalls:
-		return "kLolDscWalls";
-	case kLolEobCommonDscShapeIndex:
-		return "kLolEobCommonDscShapeIndex";
-	case kLolDscOvlMap:
-		return "kLolDscOvlMap";
-	case kLolDscScaleWidthData:
-		return "kLolDscScaleWidthData";
-	case kLolDscScaleHeightData:
-		return "kLolDscScaleHeightData";
-	case kLolEobCommonDscX:
-		return "kLolEobCommonDscX";
-	case kLolDscY:
-		return "kLolDscY";
-	case kLolEobCommonDscTileIndex:
-		return "kLolEobCommonDscTileIndex";
-	case kLolEobCommonDscUnk2:
-		return "kLolEobCommonDscUnk2";
-	case kLolEobCommonDscDoorShapeIndex:
-		return "kLolEobCommonDscDoorShapeIndex";
-	case kLolEobCommonDscDimData1:
-		return "kLolEobCommonDscDimData1";
-	case kLolEobCommonDscDimData2:
-		return "kLolEobCommonDscDimData2";
-	case kLolEobCommonDscBlockMap:
-		return "kLolEobCommonDscBlockMap";
-	case kLolEobCommonDscDimMap:
-		return "kLolEobCommonDscDimMap";
-	case kLolDscOvlIndex:
-		return "kLolDscOvlIndex";
-	case kLolEobCommonDscBlockIndex:
-		return "kLolEobCommonDscBlockIndex";
-	case kLolEobCommonDscDoorY2:
-		return "kLolEobCommonDscDoorY2";
-	case kLolDscDoorScale:
-		return "kLolDscDoorScale";
-	case kLolDscDoor4:
-		return "kLolDscDoor4";
-	case kLolDscDoorX:
-		return "kLolDscDoorX";
-	case kLolDscDoorY:
-		return "kLolDscDoorY";
-	case kLolScrollXTop:
-		return "kLolScrollXTop";
-	case kLolScrollYTop:
-		return "kLolScrollYTop";
-	case kLolScrollXBottom:
-		return "kLolScrollXBottom";
-	case kLolScrollYBottom:
-		return "kLolScrollYBottom";
-	case kLolButtonDefs:
-		return "kLolButtonDefs";
-	case kLolButtonList1:
-		return "kLolButtonList1";
-	case kLolButtonList2:
-		return "kLolButtonList2";
-	case kLolButtonList3:
-		return "kLolButtonList3";
-	case kLolButtonList4:
-		return "kLolButtonList4";
-	case kLolButtonList5:
-		return "kLolButtonList5";
-	case kLolButtonList6:
-		return "kLolButtonList6";
-	case kLolButtonList7:
-		return "kLolButtonList7";
-	case kLolButtonList8:
-		return "kLolButtonList8";
-	case kLolLegendData:
-		return "kLolLegendData";
-	case kLolMapCursorOvl:
-		return "kLolMapCursorOvl";
-	case kLolMapStringId:
-		return "kLolMapStringId";
-	case kLolSpellbookAnim:
-		return "kLolSpellbookAnim";
-	case kLolSpellbookCoords:
-		return "kLolSpellbookCoords";
-	case kLolHealShapeFrames:
-		return "kLolHealShapeFrames";
-	case kLolLightningDefs:
-		return "kLolLightningDefs";
-	case kLolFireballCoords:
-		return "kLolFireballCoords";
-	case kLolHistory:
-		return "kLolHistory";
+	case kEoBBaseChargenStrings1:
+		return "kEoBBaseChargenStrings1";
+	case kEoBBaseChargenStrings2:
+		return "kEoBBaseChargenStrings2";
+	case kEoBBaseChargenStartLevels:
+		return "kEoBBaseChargenStartLevels";
+	case kEoBBaseChargenStatStrings:
+		return "kEoBBaseChargenStatStrings";
+	case kEoBBaseChargenRaceSexStrings:
+		return "kEoBBaseChargenRaceSexStrings";
+	case kEoBBaseChargenClassStrings:
+		return "kEoBBaseChargenClassStrings";
+	case kEoBBaseChargenAlignmentStrings:
+		return "kEoBBaseChargenAlignmentStrings";
+	case kEoBBaseChargenEnterGameStrings:
+		return "kEoBBaseChargenEnterGameStrings";
+	case kEoBBaseChargenClassMinStats:
+		return "kEoBBaseChargenClassMinStats";
+	case kEoBBaseChargenRaceMinStats:
+		return "kEoBBaseChargenRaceMinStats";
+	case kEoBBaseChargenRaceMaxStats:
+		return "kEoBBaseChargenRaceMaxStats";
+	case kEoBBaseSaveThrowTable1:
+		return "kEoBBaseSaveThrowTable1";
+	case kEoBBaseSaveThrowTable2:
+		return "kEoBBaseSaveThrowTable2";
+	case kEoBBaseSaveThrowTable3:
+		return "kEoBBaseSaveThrowTable3";
+	case kEoBBaseSaveThrowTable4:
+		return "kEoBBaseSaveThrowTable4";
+	case kEoBBaseSaveThrwLvlIndex:
+		return "kEoBBaseSaveThrwLvlIndex";
+	case kEoBBaseSaveThrwModDiv:
+		return "kEoBBaseSaveThrwModDiv";
+	case kEoBBaseSaveThrwModExt:
+		return "kEoBBaseSaveThrwModExt";
+	case kEoBBasePryDoorStrings:
+		return "kEoBBasePryDoorStrings";
+	case kEoBBaseWarningStrings:
+		return "kEoBBaseWarningStrings";
+	case kEoBBaseItemSuffixStringsRings:
+		return "kEoBBaseItemSuffixStringsRings";
+	case kEoBBaseItemSuffixStringsPotions:
+		return "kEoBBaseItemSuffixStringsPotions";
+	case kEoBBaseItemSuffixStringsWands:
+		return "kEoBBaseItemSuffixStringsWands";
+	case kEoBBaseRipItemStrings:
+		return "kEoBBaseRipItemStrings";
+	case kEoBBaseCursedString:
+		return "kEoBBaseCursedString";
+	case kEoBBaseEnchantedString:
+		return "kEoBBaseEnchantedString";
+	case kEoBBaseMagicObjectStrings:
+		return "kEoBBaseMagicObjectStrings";
+	case kEoBBaseMagicObject5String:
+		return "kEoBBaseMagicObject5String";
+	case kEoBBasePatternSuffix:
+		return "kEoBBasePatternSuffix";
+	case kEoBBasePatternGrFix1:
+		return "kEoBBasePatternGrFix1";
+	case kEoBBasePatternGrFix2:
+		return "kEoBBasePatternGrFix2";
+	case kEoBBaseValidateArmorString:
+		return "kEoBBaseValidateArmorString";
+	case kEoBBaseValidateCursedString:
+		return "kEoBBaseValidateCursedString";
+	case kEoBBaseValidateNoDropString:
+		return "kEoBBaseValidateNoDropString";
+	case kEoBBasePotionStrings:
+		return "kEoBBasePotionStrings";
+	case kEoBBaseWandString:
+		return "kEoBBaseWandString";
+	case kEoBBaseItemMisuseStrings:
+		return "kEoBBaseItemMisuseStrings";
+	case kEoBBaseTakenStrings:
+		return "kEoBBaseTakenStrings";
+	case kEoBBasePotionEffectStrings:
+		return "kEoBBasePotionEffectStrings";
+	case kEoBBaseYesNoStrings:
+		return "kEoBBaseYesNoStrings";
+	case kRpgCommonMoreStrings:
+		return "kRpgCommonMoreStrings";
+	case kEoBBaseNpcMaxStrings:
+		return "kEoBBaseNpcMaxStrings";
+	case kEoBBaseOkStrings:
+		return "kEoBBaseOkStrings";
+	case kEoBBaseNpcJoinStrings:
+		return "kEoBBaseNpcJoinStrings";		
+	case kEoBBaseCancelStrings:
+		return "kEoBBaseCancelStrings";
+	case kEoBBaseAbortStrings:
+		return "kEoBBaseAbortStrings";
+	case kEoBBaseMenuStringsMain:
+		return "kEoBBaseMenuStringsMain";
+	case kEoBBaseMenuStringsSaveLoad:
+		return "kEoBBaseMenuStringsSaveLoad";
+	case kEoBBaseMenuStringsOnOff:
+		return "kEoBBaseMenuStringsOnOff";
+	case kEoBBaseMenuStringsSpells:
+		return "kEoBBaseMenuStringsSpells";
+	case kEoBBaseMenuStringsRest:
+		return "kEoBBaseMenuStringsRest";
+	case kEoBBaseMenuStringsDrop:
+		return "kEoBBaseMenuStringsDrop";
+	case kEoBBaseMenuStringsExit:
+		return "kEoBBaseMenuStringsExit";
+	case kEoBBaseMenuStringsStarve:
+		return "kEoBBaseMenuStringsStarve";
+	case kEoBBaseMenuStringsScribe:
+		return "kEoBBaseMenuStringsScribe";
+	case kEoBBaseMenuStringsDrop2:
+		return "kEoBBaseMenuStringsDrop2";
+	case kEoBBaseMenuStringsHead:
+		return "kEoBBaseMenuStringsHead";
+	case kEoBBaseMenuStringsPoison:
+		return "kEoBBaseMenuStringsPoison";
+	case kEoBBaseMenuStringsMgc:
+		return "kEoBBaseMenuStringsMgc";
+	case kEoBBaseMenuStringsPrefs:
+		return "kEoBBaseMenuStringsPrefs";
+	case kEoBBaseMenuStringsRest2:
+		return "kEoBBaseMenuStringsRest2";
+	case kEoBBaseMenuStringsRest3:
+		return "kEoBBaseMenuStringsRest3";
+	case kEoBBaseMenuStringsRest4:
+		return "kEoBBaseMenuStringsRest4";
+	case kEoBBaseMenuStringsDefeat:
+		return "kEoBBaseMenuStringsDefeat";
+	case kEoBBaseMenuStringsTransfer:
+		return "kEoBBaseMenuStringsTransfer";
+	case kEoBBaseMenuStringsSpec:
+		return "kEoBBaseMenuStringsSpec";
+	case kEoBBaseMenuStringsSpellNo:
+		return "kEoBBaseMenuStringsSpellNo";
+	case kEoBBaseMenuYesNoStrings:
+		return "kEoBBaseMenuYesNoStrings";
+	case kEoBBaseSpellLevelsMage:
+		return "kEoBBaseSpellLevelsMage";
+	case kEoBBaseSpellLevelsCleric:
+		return "kEoBBaseSpellLevelsCleric";
+	case kEoBBaseNumSpellsCleric:
+		return "kEoBBaseNumSpellsCleric";
+	case kEoBBaseNumSpellsWisAdj:
+		return "kEoBBaseNumSpellsWisAdj";
+	case kEoBBaseNumSpellsPal:
+		return "kEoBBaseNumSpellsPal";
+	case kEoBBaseNumSpellsMage:
+		return "kEoBBaseNumSpellsMage";
+	case kEoBBaseCharGuiStringsHp:
+		return "kEoBBaseCharGuiStringsHp";
+	case kEoBBaseCharGuiStringsWp1:
+		return "kEoBBaseCharGuiStringsWp1";
+	case kEoBBaseCharGuiStringsWp2:
+		return "kEoBBaseCharGuiStringsWp2";
+	case kEoBBaseCharGuiStringsWr:
+		return "kEoBBaseCharGuiStringsWr";
+	case kEoBBaseCharGuiStringsSt1:
+		return "kEoBBaseCharGuiStringsSt1";
+	case kEoBBaseCharGuiStringsSt2:
+		return "kEoBBaseCharGuiStringsSt2";
+	case kEoBBaseCharGuiStringsIn:
+		return "kEoBBaseCharGuiStringsIn";
+	case kEoBBaseCharStatusStrings7:
+		return "kEoBBaseCharStatusStrings7";
+	case kEoBBaseCharStatusStrings81:
+		return "kEoBBaseCharStatusStrings81";
+	case kEoBBaseCharStatusStrings82:
+		return "kEoBBaseCharStatusStrings82";
+	case kEoBBaseCharStatusStrings9:
+		return "kEoBBaseCharStatusStrings9";
+	case kEoBBaseCharStatusStrings12:
+		return "kEoBBaseCharStatusStrings12";
+	case kEoBBaseCharStatusStrings131:
+		return "kEoBBaseCharStatusStrings131";
+	case kEoBBaseCharStatusStrings132:
+		return "kEoBBaseCharStatusStrings132";
+	case kEoBBaseLevelGainStrings:
+		return "kEoBBaseLevelGainStrings";
+	case kEoBBaseExperienceTable0:
+		return "kEoBBaseExperienceTable0";
+	case kEoBBaseExperienceTable1:
+		return "kEoBBaseExperienceTable1";
+	case kEoBBaseExperienceTable2:
+		return "kEoBBaseExperienceTable2";
+	case kEoBBaseExperienceTable3:
+		return "kEoBBaseExperienceTable3";
+	case kEoBBaseExperienceTable4:
+		return "kEoBBaseExperienceTable4";
+	case kEoBBaseWllFlagPreset:
+		return "kEoBBaseWllFlagPreset";
+	case kEoBBaseDscShapeCoords:
+		return "kEoBBaseDscShapeCoords";
+	case kEoBBaseDscDoorScaleOffs:
+		return "kEoBBaseDscDoorScaleOffs";
+	case kEoBBaseDscDoorScaleMult1:
+		return "kEoBBaseDscDoorScaleMult1";
+	case kEoBBaseDscDoorScaleMult2:
+		return "kEoBBaseDscDoorScaleMult2";
+	case kEoBBaseDscDoorScaleMult3:
+		return "kEoBBaseDscDoorScaleMult3";
+	case kEoBBaseDscDoorScaleMult4:
+		return "kEoBBaseDscDoorScaleMult4";
+	case kEoBBaseDscDoorScaleMult5:
+		return "kEoBBaseDscDoorScaleMult5";
+	case kEoBBaseDscDoorScaleMult6:
+		return "kEoBBaseDscDoorScaleMult6";
+	case kEoBBaseDscDoorType5Offs:
+		return "kEoBBaseDscDoorType5Offs";
+	case kEoBBaseDscDoorXE:
+		return "kEoBBaseDscDoorXE";
+	case kEoBBaseDscDoorY1:
+		return "kEoBBaseDscDoorY1";
+	case kEoBBaseDscDoorY3:
+		return "kEoBBaseDscDoorY3";
+	case kEoBBaseDscDoorY4:
+		return "kEoBBaseDscDoorY4";
+	case kEoBBaseDscDoorY5:
+		return "kEoBBaseDscDoorY5";
+	case kEoBBaseDscDoorY6:
+		return "kEoBBaseDscDoorY6";
+	case kEoBBaseDscDoorY7:
+		return "kEoBBaseDscDoorY7";
+	case kEoBBaseDscDoorCoordsExt:
+		return "kEoBBaseDscDoorCoordsExt";
+	case kEoBBaseDscItemPosIndex:
+		return "kEoBBaseDscItemPosIndex";
+	case kEoBBaseDscItemShpX:
+		return "kEoBBaseDscItemShpX";
+	case kEoBBaseDscItemPosUnk:
+		return "kEoBBaseDscItemPosUnk";
+	case kEoBBaseDscItemTileIndex:
+		return "kEoBBaseDscItemTileIndex";
+	case kEoBBaseDscItemShapeMap:
+		return "kEoBBaseDscItemShapeMap";
+	case kEoBBaseDscMonsterFrmOffsTbl1:
+		return "kEoBBaseDscMonsterFrmOffsTbl1";
+	case kEoBBaseDscMonsterFrmOffsTbl2:
+		return "kEoBBaseDscMonsterFrmOffsTbl2";
+	case kEoBBaseInvSlotX:
+		return "kEoBBaseInvSlotX";
+	case kEoBBaseInvSlotY:
+		return "kEoBBaseInvSlotY";
+	case kEoBBaseSlotValidationFlags:
+		return "kEoBBaseSlotValidationFlags";
+	case kEoBBaseProjectileWeaponTypes:
+		return "kEoBBaseProjectileWeaponTypes";
+	case kEoBBaseWandTypes:
+		return "kEoBBaseWandTypes";
+	case kEoBBaseDrawObjPosIndex:
+		return "kEoBBaseDrawObjPosIndex";
+	case kEoBBaseFlightObjFlipIndex:
+		return "kEoBBaseFlightObjFlipIndex";
+	case kEoBBaseFlightObjShpMap:
+		return "kEoBBaseFlightObjShpMap";
+	case kEoBBaseFlightObjSclIndex:
+		return "kEoBBaseFlightObjSclIndex";
+	case kEoBBaseDscTelptrShpCoords:
+		return "kEoBBaseDscTelptrShpCoords";
+	case kEoBBasePortalSeqData:
+		return "kEoBBasePortalSeqData";
+	case kEoBBaseManDef:
+		return "kEoBBaseManDef";
+	case kEoBBaseManWord:
+		return "kEoBBaseManWord";
+	case kEoBBaseManPrompt:
+		return "kEoBBaseManPrompt";
+	case kEoBBaseBookNumbers:
+		return "kEoBBaseBookNumbers";
+	case kEoBBaseMageSpellsList:
+		return "kEoBBaseMageSpellsList";
+	case kEoBBaseClericSpellsList:
+		return "kEoBBaseClericSpellsList";
+	case kEoBBaseSpellNames:
+		return "kEoBBaseSpellNames";
+
+	case kEoBBaseMagicStrings1:
+		return "kEoBBaseMagicStrings1";
+	case kEoBBaseMagicStrings2:
+		return "kEoBBaseMagicStrings2";
+	case kEoBBaseMagicStrings3:
+		return "kEoBBaseMagicStrings3";
+	case kEoBBaseMagicStrings4:
+		return "kEoBBaseMagicStrings4";
+	case kEoBBaseMagicStrings6:
+		return "kEoBBaseMagicStrings6";
+	case kEoBBaseMagicStrings7:
+		return "kEoBBaseMagicStrings7";
+	case kEoBBaseMagicStrings8:
+		return "kEoBBaseMagicStrings8";
+	case kEoBBaseExpObjectTlMode:
+		return "kEoBBaseExpObjectTlMode";
+	case kEoBBaseExpObjectTblIndex:
+		return "kEoBBaseExpObjectTblIndex";
+	case kEoBBaseExpObjectShpStart:
+		return "kEoBBaseExpObjectShpStart";
+	case kEoBBaseExpObjectTbl1:
+		return "kEoBBaseExpObjectTbl1";
+	case kEoBBaseExpObjectTbl2:
+		return "kEoBBaseExpObjectTbl2";
+	case kEoBBaseExpObjectTbl3:
+		return "kEoBBaseExpObjectTbl3";
+	case kEoBBaseExpObjectY:
+		return "kEoBBaseExpObjectY";
+	case kEoBBaseSparkDefSteps:
+		return "kEoBBaseSparkDefSteps";
+	case kEoBBaseSparkDefSubSteps:
+		return "kEoBBaseSparkDefSubSteps";
+	case kEoBBaseSparkDefShift:
+		return "kEoBBaseSparkDefShift";
+	case kEoBBaseSparkDefAdd:
+		return "kEoBBaseSparkDefAdd";
+	case kEoBBaseSparkDefX:
+		return "kEoBBaseSparkDefX";
+	case kEoBBaseSparkDefY:
+		return "kEoBBaseSparkDefY";
+	case kEoBBaseSparkOfFlags1:
+		return "kEoBBaseSparkOfFlags1";
+	case kEoBBaseSparkOfFlags2:
+		return "kEoBBaseSparkOfFlags2";
+	case kEoBBaseSparkOfShift:
+		return "kEoBBaseSparkOfShift";
+	case kEoBBaseSparkOfX:
+		return "kEoBBaseSparkOfX";
+	case kEoBBaseSparkOfY:
+		return "kEoBBaseSparkOfY";
+	case kEoBBaseSpellProperties:
+		return "kEoBBaseSpellProperties";
+	case kEoBBaseMagicFlightProps:
+		return "kEoBBaseMagicFlightProps";
+	case kEoBBaseTurnUndeadEffect:
+		return "kEoBBaseTurnUndeadEffect";
+	case kEoBBaseBurningHandsDest:
+		return "kEoBBaseBurningHandsDest";
+	case kEoBBaseConeOfColdDest1:
+		return "kEoBBaseConeOfColdDest1";
+	case kEoBBaseConeOfColdDest2:
+		return "kEoBBaseConeOfColdDest2";
+	case kEoBBaseConeOfColdDest3:
+		return "kEoBBaseConeOfColdDest3";
+	case kEoBBaseConeOfColdDest4:
+		return "kEoBBaseConeOfColdDest4";
+	case kEoBBaseConeOfColdGfxTbl:
+		return "kEoBBaseConeOfColdGfxTbl";
+	case kEoB1MainMenuStrings:
+		return "kEoB1MainMenuStrings";
+	case kEoB1BonusStrings:
+		return "kEoB1BonusStrings";
+	case kEoB1IntroFilesOpening:
+		return "kEoB1IntroFilesOpening";
+	case kEoB1IntroFilesTower:
+		return "kEoB1IntroFilesTower";
+	case kEoB1IntroFilesOrb:
+		return "kEoB1IntroFilesOrb";
+	case kEoB1IntroFilesWdEntry:
+		return "kEoB1IntroFilesWdEntry";
+	case kEoB1IntroFilesKing:
+		return "kEoB1IntroFilesKing";
+	case kEoB1IntroFilesHands:
+		return "kEoB1IntroFilesHands";
+	case kEoB1IntroFilesWdExit:
+		return "kEoB1IntroFilesWdExit";
+	case kEoB1IntroFilesTunnel:
+		return "kEoB1IntroFilesTunnel";
+	case kEoB1IntroOpeningFrmDelay:
+		return "kEoB1IntroOpeningFrmDelay";
+	case kEoB1IntroWdEncodeX:
+		return "kEoB1IntroWdEncodeX";
+	case kEoB1IntroWdEncodeY:
+		return "kEoB1IntroWdEncodeY";
+	case kEoB1IntroWdEncodeWH:
+		return "kEoB1IntroWdEncodeWH";
+	case kEoB1IntroWdDsX:
+		return "kEoB1IntroWdDsX";
+	case kEoB1IntroWdDsY:
+		return "kEoB1IntroWdDsY";
+	case kEoB1IntroTvlX1:
+		return "kEoB1IntroTvlX1";
+	case kEoB1IntroTvlY1:
+		return "kEoB1IntroTvlY1";
+	case kEoB1IntroTvlX2:
+		return "kEoB1IntroTvlX2";
+	case kEoB1IntroTvlY2:
+		return "kEoB1IntroTvlY2";
+	case kEoB1IntroTvlW:
+		return "kEoB1IntroTvlW";
+	case kEoB1IntroTvlH:
+		return "kEoB1IntroTvlH";
+	case kEoB1DoorShapeDefs:
+		return "kEoB1DoorShapeDefs";
+	case kEoB1DoorSwitchCoords:
+		return "kEoB1DoorSwitchCoords";
+	case kEoB1MonsterProperties:
+		return "kEoB1MonsterProperties";
+	case kEoB1EnemyMageSpellList:
+		return "kEoB1EnemyMageSpellList";
+	case kEoB1EnemyMageSfx:
+		return "kEoB1EnemyMageSfx";
+	case kEoB1BeholderSpellList:
+		return "kEoB1BeholderSpellList";
+	case kEoB1BeholderSfx:
+		return "kEoB1BeholderSfx";
+	case kEoB1TurnUndeadString:
+		return "kEoB1TurnUndeadString";
+	case kEoB1NpcShpData:
+		return "kEoB1NpcShpData";
+	case kEoB1NpcSubShpIndex1:
+		return "kEoB1NpcSubShpIndex1";
+	case kEoB1NpcSubShpIndex2:
+		return "kEoB1NpcSubShpIndex2";
+	case kEoB1NpcSubShpY:
+		return "kEoB1NpcSubShpY";
+	case kEoB1Npc0Strings:
+		return "kEoB1Npc0Strings";
+	case kEoB1Npc11Strings:
+		return "kEoB1Npc11Strings";
+	case kEoB1Npc12Strings:
+		return "kEoB1Npc12Strings";
+	case kEoB1Npc21Strings:
+		return "kEoB1Npc21Strings";
+	case kEoB1Npc22Strings:
+		return "kEoB1Npc22Strings";
+	case kEoB1Npc31Strings:
+		return "kEoB1Npc31Strings";
+	case kEoB1Npc32Strings:
+		return "kEoB1Npc32Strings";
+	case kEoB1Npc4Strings:
+		return "kEoB1Npc4Strings";
+	case kEoB1Npc5Strings:
+		return "kEoB1Npc5Strings";
+	case kEoB1Npc6Strings:
+		return "kEoB1Npc6Strings";
+	case kEoB1Npc7Strings:
+		return "kEoB1Npc7Strings";
+	case kEoB2MainMenuStrings:
+		return "kEoB2MainMenuStrings";
+	case kEoB2TransferConvertTable:
+		return "kEoB2TransferConvertTable";
+	case kEoB2TransferExpTable:
+		return "kEoB2TransferExpTable";
+	case kEoB2IntroStrings:
+		return "kEoB2IntroStrings";
+	case kEoB2IntroCPSFiles:
+		return "kEoB2IntroCPSFiles";
+	case kEoB2IntroSeqData00:
+		return "kEoB2IntroSeqData00";
+ 	case kEoB2IntroSeqData01:
+		return "kEoB2IntroSeqData01";
+ 	case kEoB2IntroSeqData02:
+		return "kEoB2IntroSeqData02";
+ 	case kEoB2IntroSeqData03:
+		return "kEoB2IntroSeqData03";
+ 	case kEoB2IntroSeqData04:
+		return "kEoB2IntroSeqData04";
+ 	case kEoB2IntroSeqData05:
+		return "kEoB2IntroSeqData05";
+ 	case kEoB2IntroSeqData06:
+		return "kEoB2IntroSeqData06";
+ 	case kEoB2IntroSeqData07:
+		return "kEoB2IntroSeqData07";
+ 	case kEoB2IntroSeqData08:
+		return "kEoB2IntroSeqData08";
+ 	case kEoB2IntroSeqData09:
+		return "kEoB2IntroSeqData09";
+ 	case kEoB2IntroSeqData10:
+		return "kEoB2IntroSeqData10";
+ 	case kEoB2IntroSeqData11:
+		return "kEoB2IntroSeqData11";
+ 	case kEoB2IntroSeqData12:
+		return "kEoB2IntroSeqData12";
+ 	case kEoB2IntroSeqData13:
+		return "kEoB2IntroSeqData13";
+ 	case kEoB2IntroSeqData14:
+		return "kEoB2IntroSeqData14";
+ 	case kEoB2IntroSeqData15:
+		return "kEoB2IntroSeqData15";
+ 	case kEoB2IntroSeqData16:
+		return "kEoB2IntroSeqData16";
+ 	case kEoB2IntroSeqData17:
+		return "kEoB2IntroSeqData17";
+ 	case kEoB2IntroSeqData18:
+		return "kEoB2IntroSeqData18";
+ 	case kEoB2IntroSeqData19:
+		return "kEoB2IntroSeqData19";
+ 	case kEoB2IntroSeqData20:
+		return "kEoB2IntroSeqData20";
+ 	case kEoB2IntroSeqData21:
+		return "kEoB2IntroSeqData21";
+ 	case kEoB2IntroSeqData22:
+		return "kEoB2IntroSeqData22";
+ 	case kEoB2IntroSeqData23:
+		return "kEoB2IntroSeqData23";
+ 	case kEoB2IntroSeqData24:
+		return "kEoB2IntroSeqData24";
+ 	case kEoB2IntroSeqData25:
+		return "kEoB2IntroSeqData25";
+ 	case kEoB2IntroSeqData26:
+		return "kEoB2IntroSeqData26";
+ 	case kEoB2IntroSeqData27:
+		return "kEoB2IntroSeqData27";
+ 	case kEoB2IntroSeqData28:
+		return "kEoB2IntroSeqData28";
+ 	case kEoB2IntroSeqData29:
+		return "kEoB2IntroSeqData29";
+ 	case kEoB2IntroSeqData30:
+		return "kEoB2IntroSeqData30";
+ 	case kEoB2IntroSeqData31:
+		return "kEoB2IntroSeqData31";
+ 	case kEoB2IntroSeqData32:
+		return "kEoB2IntroSeqData32";
+ 	case kEoB2IntroSeqData33:
+		return "kEoB2IntroSeqData33";
+ 	case kEoB2IntroSeqData34:
+		return "kEoB2IntroSeqData34";
+ 	case kEoB2IntroSeqData35:
+		return "kEoB2IntroSeqData35";
+ 	case kEoB2IntroSeqData36:
+		return "kEoB2IntroSeqData36";
+ 	case kEoB2IntroSeqData37:
+		return "kEoB2IntroSeqData37";
+ 	case kEoB2IntroSeqData38:
+		return "kEoB2IntroSeqData38";
+ 	case kEoB2IntroSeqData39:
+		return "kEoB2IntroSeqData39";
+ 	case kEoB2IntroSeqData40:
+		return "kEoB2IntroSeqData40";
+ 	case kEoB2IntroSeqData41:
+		return "kEoB2IntroSeqData41";
+ 	case kEoB2IntroSeqData42:
+		return "kEoB2IntroSeqData42";
+ 	case kEoB2IntroSeqData43:
+		return "kEoB2IntroSeqData43";
+ 	case kEoB2IntroShapes00:
+		return "kEoB2IntroShapes00";
+ 	case kEoB2IntroShapes01:
+		return "kEoB2IntroShapes01";
+ 	case kEoB2IntroShapes04:
+		return "kEoB2IntroShapes04";
+ 	case kEoB2IntroShapes07:
+		return "kEoB2IntroShapes07";
+	case kEoB2FinaleStrings:
+		return "kEoB2FinaleStrings";
+	case kEoB2CreditsData:
+		return "kEoB2CreditsData";
+	case kEoB2FinaleCPSFiles:
+		return "kEoB2FinaleCPSFiles";		
+ 	case kEoB2FinaleSeqData00:
+		return "kEoB2FinaleSeqData00";
+ 	case kEoB2FinaleSeqData01:
+		return "kEoB2FinaleSeqData01";
+ 	case kEoB2FinaleSeqData02:
+		return "kEoB2FinaleSeqData02";
+ 	case kEoB2FinaleSeqData03:
+		return "kEoB2FinaleSeqData03";
+ 	case kEoB2FinaleSeqData04:
+		return "kEoB2FinaleSeqData04";
+ 	case kEoB2FinaleSeqData05:
+		return "kEoB2FinaleSeqData05";
+ 	case kEoB2FinaleSeqData06:
+		return "kEoB2FinaleSeqData06";
+ 	case kEoB2FinaleSeqData07:
+		return "kEoB2FinaleSeqData07";
+ 	case kEoB2FinaleSeqData08:
+		return "kEoB2FinaleSeqData08";
+ 	case kEoB2FinaleSeqData09:
+		return "kEoB2FinaleSeqData09";
+ 	case kEoB2FinaleSeqData10:
+		return "kEoB2FinaleSeqData10";
+ 	case kEoB2FinaleSeqData11:
+		return "kEoB2FinaleSeqData11";
+ 	case kEoB2FinaleSeqData12:
+		return "kEoB2FinaleSeqData12";
+ 	case kEoB2FinaleSeqData13:
+		return "kEoB2FinaleSeqData13";
+ 	case kEoB2FinaleSeqData14:
+		return "kEoB2FinaleSeqData14";
+ 	case kEoB2FinaleSeqData15:
+		return "kEoB2FinaleSeqData15";
+ 	case kEoB2FinaleSeqData16:
+		return "kEoB2FinaleSeqData16";
+ 	case kEoB2FinaleSeqData17:
+		return "kEoB2FinaleSeqData17";
+ 	case kEoB2FinaleSeqData18:
+		return "kEoB2FinaleSeqData18";
+ 	case kEoB2FinaleSeqData19:
+		return "kEoB2FinaleSeqData19";
+ 	case kEoB2FinaleSeqData20:
+		return "kEoB2FinaleSeqData20";	
+ 	case kEoB2FinaleShapes00:
+		return "kEoB2FinaleShapes00";
+ 	case kEoB2FinaleShapes03:
+		return "kEoB2FinaleShapes03";
+ 	case kEoB2FinaleShapes07:
+		return "kEoB2FinaleShapes07";
+ 	case kEoB2FinaleShapes09:
+		return "kEoB2FinaleShapes09";
+ 	case kEoB2FinaleShapes10:
+		return "kEoB2FinaleShapes10";
+	case kEoB2NpcShapeData:
+		return "kEoB2NpcShapeData";
+	case kEoBBaseClassModifierFlags:
+		return "kEoBBaseClassModifierFlags";
+	case kEoBBaseMonsterStepTable01:
+		return "kEoBBaseMonsterStepTable01";
+	case kEoBBaseMonsterStepTable02:
+		return "kEoBBaseMonsterStepTable02";
+	case kEoBBaseMonsterStepTable1:
+		return "kEoBBaseMonsterStepTable1";
+	case kEoBBaseMonsterStepTable2:
+		return "kEoBBaseMonsterStepTable2";
+	case kEoBBaseMonsterStepTable3:
+		return "kEoBBaseMonsterStepTable3";
+	case kEoBBaseMonsterCloseAttPosTable1:
+		return "kEoBBaseMonsterCloseAttPosTable1";
+	case kEoBBaseMonsterCloseAttPosTable21:
+		return "kEoBBaseMonsterCloseAttPosTable21";
+	case kEoBBaseMonsterCloseAttPosTable22:
+		return "kEoBBaseMonsterCloseAttPosTable22";
+	case kEoBBaseMonsterCloseAttUnkTable:
+		return "kEoBBaseMonsterCloseAttUnkTable";
+	case kEoBBaseMonsterCloseAttChkTable1:
+		return "kEoBBaseMonsterCloseAttChkTable1";
+	case kEoBBaseMonsterCloseAttChkTable2:
+		return "kEoBBaseMonsterCloseAttChkTable2";
+	case kEoBBaseMonsterCloseAttDstTable1:
+		return "kEoBBaseMonsterCloseAttDstTable1";
+	case kEoBBaseMonsterCloseAttDstTable2:
+		return "kEoBBaseMonsterCloseAttDstTable2";
+	case kEoBBaseMonsterProximityTable:
+		return "kEoBBaseMonsterProximityTable";
+	case kEoBBaseFindBlockMonstersTable:
+		return "kEoBBaseFindBlockMonstersTable";
+	case kEoBBaseMonsterDirChangeTable:
+		return "kEoBBaseMonsterDirChangeTable";
+	case kEoBBaseMonsterDistAttStrings:
+		return "kEoBBaseMonsterDistAttStrings";
+	case kEoBBaseEncodeMonsterDefs:
+		return "kEoBBaseEncodeMonsterDefs";
+	case kEoBBaseNpcPresets:
+		return "kEoBBaseNpcPresets";
+	case kEoB2Npc1Strings:
+		return "kEoB2Npc1Strings";
+	case kEoB2Npc2Strings:
+		return "kEoB2Npc2Strings";
+	case kEoB2MonsterDustStrings:
+		return "kEoB2MonsterDustStrings";
+	case kEoB2DreamSteps:
+		return "kEoB2DreamSteps";
+	case kEoB2KheldranStrings:
+		return "kEoB2KheldranStrings";
+	case kEoB2HornStrings:
+		return "kEoB2HornStrings";
+	case kEoB2HornSounds:
+		return "kEoB2HornSounds";
+	case kEoB2WallOfForceDsX:
+		return "kEoB2WallOfForceDsX";
+	case kEoB2WallOfForceDsY:
+		return "kEoB2WallOfForceDsY";
+	case kEoB2WallOfForceNumW:
+		return "kEoB2WallOfForceNumW";
+	case kEoB2WallOfForceNumH:
+		return "kEoB2WallOfForceNumH";
+	case kEoB2WallOfForceShpId:
+		return "kEoB2WallOfForceShpId";
+	case kLoLIngamePakFiles:
+		return "kLoLIngamePakFiles";
+	case kLoLCharacterDefs:
+		return "kLoLCharacterDefs";
+	case kLoLIngameSfxFiles:
+		return "kLoLIngameSfxFiles";
+	case kLoLIngameSfxIndex:
+		return "kLoLIngameSfxIndex";
+	case kLoLMusicTrackMap:
+		return "kLoLMusicTrackMap";
+	case kLoLIngameGMSfxIndex:
+		return "kLoLIngameGMSfxIndex";
+	case kLoLIngameMT32SfxIndex:
+		return "kLoLIngameMT32SfxIndex";
+	case kLoLIngamePcSpkSfxIndex:
+		return "kLoLIngamePcSpkSfxIndex";
+	case kLoLSpellProperties:
+		return "kLoLSpellProperties";
+	case kLoLGameShapeMap:
+		return "kLoLGameShapeMap";
+	case kLoLSceneItemOffs:
+		return "kLoLSceneItemOffs";
+	case kLoLCharInvIndex:
+		return "kLoLCharInvIndex";
+	case kLoLCharInvDefs:
+		return "kLoLCharInvDefs";
+	case kLoLCharDefsMan:
+		return "kLoLCharDefsMan";
+	case kLoLCharDefsWoman:
+		return "kLoLCharDefsWoman";
+	case kLoLCharDefsKieran:
+		return "kLoLCharDefsKieran";
+	case kLoLCharDefsAkshel:
+		return "kLoLCharDefsAkshel";
+	case kLoLExpRequirements:
+		return "kLoLExpRequirements";
+	case kLoLMonsterModifiers:
+		return "kLoLMonsterModifiers";
+	case kLoLMonsterShiftOffsets:
+		return "kLoLMonsterShiftOffsets";
+	case kLoLMonsterDirFlags:
+		return "kLoLMonsterDirFlags";
+	case kLoLMonsterScaleY:
+		return "kLoLMonsterScaleY";
+	case kLoLMonsterScaleX:
+		return "kLoLMonsterScaleX";
+	case kLoLMonsterScaleWH:
+		return "kLoLMonsterScaleWH";
+	case kLoLFlyingObjectShp:
+		return "kLoLFlyingObjectShp";
+	case kLoLInventoryDesc:
+		return "kLoLInventoryDesc";
+	case kLoLLevelShpList:
+		return "kLoLLevelShpList";
+	case kLoLLevelDatList:
+		return "kLoLLevelDatList";
+	case kLoLCompassDefs:
+		return "kLoLCompassDefs";
+	case kLoLItemPrices:
+		return "kLoLItemPrices";
+	case kLoLStashSetup:
+		return "kLoLStashSetup";
+	case kLoLDscWalls:
+		return "kLoLDscWalls";
+	case kRpgCommonDscShapeIndex:
+		return "kRpgCommonDscShapeIndex";
+	case kLoLDscOvlMap:
+		return "kLoLDscOvlMap";
+	case kLoLDscScaleWidthData:
+		return "kLoLDscScaleWidthData";
+	case kLoLDscScaleHeightData:
+		return "kLoLDscScaleHeightData";
+	case kRpgCommonDscX:
+		return "kRpgCommonDscX";
+	case kLoLDscY:
+		return "kLoLDscY";
+	case kRpgCommonDscTileIndex:
+		return "kRpgCommonDscTileIndex";
+	case kRpgCommonDscUnk2:
+		return "kRpgCommonDscUnk2";
+	case kRpgCommonDscDoorShapeIndex:
+		return "kRpgCommonDscDoorShapeIndex";
+	case kRpgCommonDscDimData1:
+		return "kRpgCommonDscDimData1";
+	case kRpgCommonDscDimData2:
+		return "kRpgCommonDscDimData2";
+	case kRpgCommonDscBlockMap:
+		return "kRpgCommonDscBlockMap";
+	case kRpgCommonDscDimMap:
+		return "kRpgCommonDscDimMap";
+	case kLoLDscOvlIndex:
+		return "kLoLDscOvlIndex";
+	case kRpgCommonDscBlockIndex:
+		return "kRpgCommonDscBlockIndex";
+	case kRpgCommonDscDoorY2:
+		return "kRpgCommonDscDoorY2";
+	case kLoLDscDoorScale:
+		return "kLoLDscDoorScale";
+	case kLoLDscDoor4:
+		return "kLoLDscDoor4";
+	case kLoLDscDoorX:
+		return "kLoLDscDoorX";
+	case kLoLDscDoorY:
+		return "kLoLDscDoorY";
+	case kLoLScrollXTop:
+		return "kLoLScrollXTop";
+	case kLoLScrollYTop:
+		return "kLoLScrollYTop";
+	case kLoLScrollXBottom:
+		return "kLoLScrollXBottom";
+	case kLoLScrollYBottom:
+		return "kLoLScrollYBottom";
+	case kLoLButtonDefs:
+		return "kLoLButtonDefs";
+	case kLoLButtonList1:
+		return "kLoLButtonList1";
+	case kLoLButtonList2:
+		return "kLoLButtonList2";
+	case kLoLButtonList3:
+		return "kLoLButtonList3";
+	case kLoLButtonList4:
+		return "kLoLButtonList4";
+	case kLoLButtonList5:
+		return "kLoLButtonList5";
+	case kLoLButtonList6:
+		return "kLoLButtonList6";
+	case kLoLButtonList7:
+		return "kLoLButtonList7";
+	case kLoLButtonList8:
+		return "kLoLButtonList8";
+	case kLoLLegendData:
+		return "kLoLLegendData";
+	case kLoLMapCursorOvl:
+		return "kLoLMapCursorOvl";
+	case kLoLMapStringId:
+		return "kLoLMapStringId";
+	case kLoLSpellbookAnim:
+		return "kLoLSpellbookAnim";
+	case kLoLSpellbookCoords:
+		return "kLoLSpellbookCoords";
+	case kLoLHealShapeFrames:
+		return "kLoLHealShapeFrames";
+	case kLoLLightningDefs:
+		return "kLoLLightningDefs";
+	case kLoLFireballCoords:
+		return "kLoLFireballCoords";
+	case kLoLHistory:
+		return "kLoLHistory";
 	default:
 		return "Unknown";
 	}
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index 08b71ee..271ffb5 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -179,463 +179,463 @@ enum kExtractID {
 	k3ItemMagicTable,
 	k3ItemStringMap,
 
-	kLolEobCommonMoreStrings,
-	kLolEobCommonDscShapeIndex,
-	kLolEobCommonDscX,
-	kLolEobCommonDscTileIndex,
-	kLolEobCommonDscUnk2,
-	kLolEobCommonDscDoorShapeIndex,
-	kLolEobCommonDscDimData1,
-	kLolEobCommonDscDimData2,
-	kLolEobCommonDscBlockMap,
-	kLolEobCommonDscDimMap,
-	kLolEobCommonDscDoorY2,
-	kLolEobCommonDscBlockIndex,
-
-	kEobBaseChargenStrings1,
-	kEobBaseChargenStrings2,
-	kEobBaseChargenStartLevels,
-	kEobBaseChargenStatStrings,
-	kEobBaseChargenRaceSexStrings,
-	kEobBaseChargenClassStrings,
-	kEobBaseChargenAlignmentStrings,
-	kEobBaseChargenEnterGameStrings,
-	kEobBaseChargenClassMinStats,
-	kEobBaseChargenRaceMinStats,
-	kEobBaseChargenRaceMaxStats,
-
-	kEobBaseSaveThrowTable1,
-	kEobBaseSaveThrowTable2,
-	kEobBaseSaveThrowTable3,
-	kEobBaseSaveThrowTable4,
-	kEobBaseSaveThrwLvlIndex,
-	kEobBaseSaveThrwModDiv,
-	kEobBaseSaveThrwModExt,
-
-	kEobBasePryDoorStrings,
-	kEobBaseWarningStrings,
-
-	kEobBaseItemSuffixStringsRings,
-	kEobBaseItemSuffixStringsPotions,
-	kEobBaseItemSuffixStringsWands,
+	kRpgCommonMoreStrings,
+	kRpgCommonDscShapeIndex,
+	kRpgCommonDscX,
+	kRpgCommonDscTileIndex,
+	kRpgCommonDscUnk2,
+	kRpgCommonDscDoorShapeIndex,
+	kRpgCommonDscDimData1,
+	kRpgCommonDscDimData2,
+	kRpgCommonDscBlockMap,
+	kRpgCommonDscDimMap,
+	kRpgCommonDscDoorY2,
+	kRpgCommonDscBlockIndex,
+
+	kEoBBaseChargenStrings1,
+	kEoBBaseChargenStrings2,
+	kEoBBaseChargenStartLevels,
+	kEoBBaseChargenStatStrings,
+	kEoBBaseChargenRaceSexStrings,
+	kEoBBaseChargenClassStrings,
+	kEoBBaseChargenAlignmentStrings,
+	kEoBBaseChargenEnterGameStrings,
+	kEoBBaseChargenClassMinStats,
+	kEoBBaseChargenRaceMinStats,
+	kEoBBaseChargenRaceMaxStats,
+
+	kEoBBaseSaveThrowTable1,
+	kEoBBaseSaveThrowTable2,
+	kEoBBaseSaveThrowTable3,
+	kEoBBaseSaveThrowTable4,
+	kEoBBaseSaveThrwLvlIndex,
+	kEoBBaseSaveThrwModDiv,
+	kEoBBaseSaveThrwModExt,
+
+	kEoBBasePryDoorStrings,
+	kEoBBaseWarningStrings,
+
+	kEoBBaseItemSuffixStringsRings,
+	kEoBBaseItemSuffixStringsPotions,
+	kEoBBaseItemSuffixStringsWands,
 	
-	kEobBaseRipItemStrings,
-	kEobBaseCursedString,
-	kEobBaseEnchantedString,
-	kEobBaseMagicObjectStrings,
-	kEobBaseMagicObject5String,
-	kEobBasePatternSuffix,
-	kEobBasePatternGrFix1,
-	kEobBasePatternGrFix2,
-	kEobBaseValidateArmorString,
-	kEobBaseValidateCursedString,
-	kEobBaseValidateNoDropString,
-	kEobBasePotionStrings,
-	kEobBaseWandString,
-	kEobBaseItemMisuseStrings,
+	kEoBBaseRipItemStrings,
+	kEoBBaseCursedString,
+	kEoBBaseEnchantedString,
+	kEoBBaseMagicObjectStrings,
+	kEoBBaseMagicObject5String,
+	kEoBBasePatternSuffix,
+	kEoBBasePatternGrFix1,
+	kEoBBasePatternGrFix2,
+	kEoBBaseValidateArmorString,
+	kEoBBaseValidateCursedString,
+	kEoBBaseValidateNoDropString,
+	kEoBBasePotionStrings,
+	kEoBBaseWandString,
+	kEoBBaseItemMisuseStrings,
 	
-	kEobBaseTakenStrings,
-	kEobBasePotionEffectStrings,
-
-	kEobBaseYesNoStrings,
-	kEobBaseNpcMaxStrings,
-	kEobBaseOkStrings,
-	kEobBaseNpcJoinStrings,
-	kEobBaseCancelStrings,
-	kEobBaseAbortStrings,
-
-	kEobBaseMenuStringsMain,
-	kEobBaseMenuStringsSaveLoad,
-	kEobBaseMenuStringsOnOff,
-	kEobBaseMenuStringsSpells,
-	kEobBaseMenuStringsRest,
-	kEobBaseMenuStringsDrop,
-	kEobBaseMenuStringsExit,
-	kEobBaseMenuStringsStarve,
-	kEobBaseMenuStringsScribe,
-	kEobBaseMenuStringsDrop2,
-	kEobBaseMenuStringsHead,
-	kEobBaseMenuStringsPoison,
-	kEobBaseMenuStringsMgc,
-	kEobBaseMenuStringsPrefs,
-	kEobBaseMenuStringsRest2,
-	kEobBaseMenuStringsRest3,
-	kEobBaseMenuStringsRest4,
-	kEobBaseMenuStringsDefeat,
-	kEobBaseMenuStringsTransfer,
-	kEobBaseMenuStringsSpec,
-	kEobBaseMenuStringsSpellNo,
-	kEobBaseMenuYesNoStrings,
-
-	kEobBaseSpellLevelsMage,
-	kEobBaseSpellLevelsCleric,
-	kEobBaseNumSpellsCleric,
-	kEobBaseNumSpellsWisAdj,
-	kEobBaseNumSpellsPal,
-	kEobBaseNumSpellsMage,
-
-	kEobBaseCharGuiStringsHp,
-	kEobBaseCharGuiStringsWp1,
-	kEobBaseCharGuiStringsWp2,
-	kEobBaseCharGuiStringsWr,
-	kEobBaseCharGuiStringsSt1,
-	kEobBaseCharGuiStringsSt2,
-	kEobBaseCharGuiStringsIn,
-
-	kEobBaseCharStatusStrings7,
-	kEobBaseCharStatusStrings81,
-	kEobBaseCharStatusStrings82,
-	kEobBaseCharStatusStrings9,
-	kEobBaseCharStatusStrings12,
-	kEobBaseCharStatusStrings131,
-	kEobBaseCharStatusStrings132,
-
-	kEobBaseLevelGainStrings,
-	kEobBaseExperienceTable0,
-	kEobBaseExperienceTable1,
-	kEobBaseExperienceTable2,
-	kEobBaseExperienceTable3,
-	kEobBaseExperienceTable4,
-
-	kEobBaseClassModifierFlags,
-
-	kEobBaseMonsterStepTable01,
-	kEobBaseMonsterStepTable02,
-	kEobBaseMonsterStepTable1,
-	kEobBaseMonsterStepTable2,
-	kEobBaseMonsterStepTable3,
-	kEobBaseMonsterCloseAttPosTable1,
-	kEobBaseMonsterCloseAttPosTable21,
-	kEobBaseMonsterCloseAttPosTable22,
-	kEobBaseMonsterCloseAttUnkTable,
-	kEobBaseMonsterCloseAttChkTable1,
-	kEobBaseMonsterCloseAttChkTable2,
-	kEobBaseMonsterCloseAttDstTable1,
-	kEobBaseMonsterCloseAttDstTable2,
-
-	kEobBaseMonsterProximityTable,
-	kEobBaseFindBlockMonstersTable,
-	kEobBaseMonsterDirChangeTable,
-	kEobBaseMonsterDistAttStrings,
-
-	kEobBaseEncodeMonsterDefs,
-	kEobBaseNpcPresets,
-
-	kEobBaseWllFlagPreset,
-	kEobBaseDscShapeCoords,
-
-	kEobBaseDscDoorScaleOffs,
-	kEobBaseDscDoorScaleMult1,
-	kEobBaseDscDoorScaleMult2,
-	kEobBaseDscDoorScaleMult3,
-	kEobBaseDscDoorScaleMult4,
-	kEobBaseDscDoorScaleMult5,
-	kEobBaseDscDoorScaleMult6,
-	kEobBaseDscDoorType5Offs,
-	kEobBaseDscDoorXE,
-	kEobBaseDscDoorY1,
-	kEobBaseDscDoorY3,
-	kEobBaseDscDoorY4,
-	kEobBaseDscDoorY5,
-	kEobBaseDscDoorY6,
-	kEobBaseDscDoorY7,
-	kEobBaseDscDoorCoordsExt,
-
-	kEobBaseDscItemPosIndex,
-	kEobBaseDscItemShpX,
-	kEobBaseDscItemPosUnk,
-	kEobBaseDscItemTileIndex,
-	kEobBaseDscItemShapeMap,
-
-	kEobBaseDscMonsterFrmOffsTbl1,
-	kEobBaseDscMonsterFrmOffsTbl2,
-
-	kEobBaseInvSlotX,
-	kEobBaseInvSlotY,
-	kEobBaseSlotValidationFlags,
-
-	kEobBaseProjectileWeaponTypes,
-	kEobBaseWandTypes,
-
-	kEobBaseDrawObjPosIndex,
-	kEobBaseFlightObjFlipIndex,
-	kEobBaseFlightObjShpMap,
-	kEobBaseFlightObjSclIndex,
-
-	kEobBaseDscTelptrShpCoords,
+	kEoBBaseTakenStrings,
+	kEoBBasePotionEffectStrings,
+
+	kEoBBaseYesNoStrings,
+	kEoBBaseNpcMaxStrings,
+	kEoBBaseOkStrings,
+	kEoBBaseNpcJoinStrings,
+	kEoBBaseCancelStrings,
+	kEoBBaseAbortStrings,
+
+	kEoBBaseMenuStringsMain,
+	kEoBBaseMenuStringsSaveLoad,
+	kEoBBaseMenuStringsOnOff,
+	kEoBBaseMenuStringsSpells,
+	kEoBBaseMenuStringsRest,
+	kEoBBaseMenuStringsDrop,
+	kEoBBaseMenuStringsExit,
+	kEoBBaseMenuStringsStarve,
+	kEoBBaseMenuStringsScribe,
+	kEoBBaseMenuStringsDrop2,
+	kEoBBaseMenuStringsHead,
+	kEoBBaseMenuStringsPoison,
+	kEoBBaseMenuStringsMgc,
+	kEoBBaseMenuStringsPrefs,
+	kEoBBaseMenuStringsRest2,
+	kEoBBaseMenuStringsRest3,
+	kEoBBaseMenuStringsRest4,
+	kEoBBaseMenuStringsDefeat,
+	kEoBBaseMenuStringsTransfer,
+	kEoBBaseMenuStringsSpec,
+	kEoBBaseMenuStringsSpellNo,
+	kEoBBaseMenuYesNoStrings,
+
+	kEoBBaseSpellLevelsMage,
+	kEoBBaseSpellLevelsCleric,
+	kEoBBaseNumSpellsCleric,
+	kEoBBaseNumSpellsWisAdj,
+	kEoBBaseNumSpellsPal,
+	kEoBBaseNumSpellsMage,
+
+	kEoBBaseCharGuiStringsHp,
+	kEoBBaseCharGuiStringsWp1,
+	kEoBBaseCharGuiStringsWp2,
+	kEoBBaseCharGuiStringsWr,
+	kEoBBaseCharGuiStringsSt1,
+	kEoBBaseCharGuiStringsSt2,
+	kEoBBaseCharGuiStringsIn,
+
+	kEoBBaseCharStatusStrings7,
+	kEoBBaseCharStatusStrings81,
+	kEoBBaseCharStatusStrings82,
+	kEoBBaseCharStatusStrings9,
+	kEoBBaseCharStatusStrings12,
+	kEoBBaseCharStatusStrings131,
+	kEoBBaseCharStatusStrings132,
+
+	kEoBBaseLevelGainStrings,
+	kEoBBaseExperienceTable0,
+	kEoBBaseExperienceTable1,
+	kEoBBaseExperienceTable2,
+	kEoBBaseExperienceTable3,
+	kEoBBaseExperienceTable4,
+
+	kEoBBaseClassModifierFlags,
+
+	kEoBBaseMonsterStepTable01,
+	kEoBBaseMonsterStepTable02,
+	kEoBBaseMonsterStepTable1,
+	kEoBBaseMonsterStepTable2,
+	kEoBBaseMonsterStepTable3,
+	kEoBBaseMonsterCloseAttPosTable1,
+	kEoBBaseMonsterCloseAttPosTable21,
+	kEoBBaseMonsterCloseAttPosTable22,
+	kEoBBaseMonsterCloseAttUnkTable,
+	kEoBBaseMonsterCloseAttChkTable1,
+	kEoBBaseMonsterCloseAttChkTable2,
+	kEoBBaseMonsterCloseAttDstTable1,
+	kEoBBaseMonsterCloseAttDstTable2,
+
+	kEoBBaseMonsterProximityTable,
+	kEoBBaseFindBlockMonstersTable,
+	kEoBBaseMonsterDirChangeTable,
+	kEoBBaseMonsterDistAttStrings,
+
+	kEoBBaseEncodeMonsterDefs,
+	kEoBBaseNpcPresets,
+
+	kEoBBaseWllFlagPreset,
+	kEoBBaseDscShapeCoords,
+
+	kEoBBaseDscDoorScaleOffs,
+	kEoBBaseDscDoorScaleMult1,
+	kEoBBaseDscDoorScaleMult2,
+	kEoBBaseDscDoorScaleMult3,
+	kEoBBaseDscDoorScaleMult4,
+	kEoBBaseDscDoorScaleMult5,
+	kEoBBaseDscDoorScaleMult6,
+	kEoBBaseDscDoorType5Offs,
+	kEoBBaseDscDoorXE,
+	kEoBBaseDscDoorY1,
+	kEoBBaseDscDoorY3,
+	kEoBBaseDscDoorY4,
+	kEoBBaseDscDoorY5,
+	kEoBBaseDscDoorY6,
+	kEoBBaseDscDoorY7,
+	kEoBBaseDscDoorCoordsExt,
+
+	kEoBBaseDscItemPosIndex,
+	kEoBBaseDscItemShpX,
+	kEoBBaseDscItemPosUnk,
+	kEoBBaseDscItemTileIndex,
+	kEoBBaseDscItemShapeMap,
+
+	kEoBBaseDscMonsterFrmOffsTbl1,
+	kEoBBaseDscMonsterFrmOffsTbl2,
+
+	kEoBBaseInvSlotX,
+	kEoBBaseInvSlotY,
+	kEoBBaseSlotValidationFlags,
+
+	kEoBBaseProjectileWeaponTypes,
+	kEoBBaseWandTypes,
+
+	kEoBBaseDrawObjPosIndex,
+	kEoBBaseFlightObjFlipIndex,
+	kEoBBaseFlightObjShpMap,
+	kEoBBaseFlightObjSclIndex,
+
+	kEoBBaseDscTelptrShpCoords,
 	
-	kEobBasePortalSeqData,
-	kEobBaseManDef,
-	kEobBaseManWord,
-	kEobBaseManPrompt,
-
-	kEobBaseBookNumbers,
-	kEobBaseMageSpellsList,
-	kEobBaseClericSpellsList,
-	kEobBaseSpellNames,
-	kEobBaseMagicStrings1,
-	kEobBaseMagicStrings2,
-	kEobBaseMagicStrings3,
-	kEobBaseMagicStrings4,
-	kEobBaseMagicStrings6,
-	kEobBaseMagicStrings7,
-	kEobBaseMagicStrings8,
-
-	kEobBaseExpObjectTlMode,
-	kEobBaseExpObjectTblIndex,
-	kEobBaseExpObjectShpStart,
-	kEobBaseExpObjectTbl1,
-	kEobBaseExpObjectTbl2,
-	kEobBaseExpObjectTbl3,
-	kEobBaseExpObjectY,
-
-	kEobBaseSparkDefSteps,
-	kEobBaseSparkDefSubSteps,
-	kEobBaseSparkDefShift,
-	kEobBaseSparkDefAdd,
-	kEobBaseSparkDefX,
-	kEobBaseSparkDefY,
-	kEobBaseSparkOfFlags1,
-	kEobBaseSparkOfFlags2,
-	kEobBaseSparkOfShift,
-	kEobBaseSparkOfX,
-	kEobBaseSparkOfY,
-
-	kEobBaseSpellProperties,
-	kEobBaseMagicFlightProps,
-	kEobBaseTurnUndeadEffect,
-	kEobBaseBurningHandsDest,
-	kEobBaseConeOfColdDest1,
-	kEobBaseConeOfColdDest2,
-	kEobBaseConeOfColdDest3,
-	kEobBaseConeOfColdDest4,
-	kEobBaseConeOfColdGfxTbl,
-
-	kEob1MainMenuStrings,
-	kEob1BonusStrings,
-
-	kEob1IntroFilesOpening,
-	kEob1IntroFilesTower,
-	kEob1IntroFilesOrb,
-	kEob1IntroFilesWdEntry,
-	kEob1IntroFilesKing,
-	kEob1IntroFilesHands,
-	kEob1IntroFilesWdExit,
-	kEob1IntroFilesTunnel,
-	kEob1IntroOpeningFrmDelay,
-	kEob1IntroWdEncodeX,
-	kEob1IntroWdEncodeY,
-	kEob1IntroWdEncodeWH,
-	kEob1IntroWdDsX,
-	kEob1IntroWdDsY,
-	kEob1IntroTvlX1,
-	kEob1IntroTvlY1,
-	kEob1IntroTvlX2,
-	kEob1IntroTvlY2,
-	kEob1IntroTvlW,
-	kEob1IntroTvlH,
-
-	kEob1DoorShapeDefs,
-	kEob1DoorSwitchShapeDefs,
-	kEob1DoorSwitchCoords,
-	kEob1MonsterProperties,
-
-	kEob1EnemyMageSpellList,
-	kEob1EnemyMageSfx,
-	kEob1BeholderSpellList,
-	kEob1BeholderSfx,
-	kEob1TurnUndeadString,
-
-	kEob1NpcShpData,
-	kEob1NpcSubShpIndex1,
-	kEob1NpcSubShpIndex2,
-	kEob1NpcSubShpY,
-	kEob1Npc0Strings,
-	kEob1Npc11Strings,
-	kEob1Npc12Strings,
-	kEob1Npc21Strings,
-	kEob1Npc22Strings,
-	kEob1Npc31Strings,
-	kEob1Npc32Strings,
-	kEob1Npc4Strings,
-	kEob1Npc5Strings,
-	kEob1Npc6Strings,
-	kEob1Npc7Strings,
-
-	kEob2MainMenuStrings,
-	kEob2TransferConvertTable,
-	kEob2TransferExpTable,
-
-	kEob2IntroStrings,
-	kEob2IntroCPSFiles,
-	kEob2IntroSeqData00,
- 	kEob2IntroSeqData01,
- 	kEob2IntroSeqData02,
- 	kEob2IntroSeqData03,
- 	kEob2IntroSeqData04,
- 	kEob2IntroSeqData05,
- 	kEob2IntroSeqData06,
- 	kEob2IntroSeqData07,
- 	kEob2IntroSeqData08,
- 	kEob2IntroSeqData09,
- 	kEob2IntroSeqData10,
- 	kEob2IntroSeqData11,
- 	kEob2IntroSeqData12,
- 	kEob2IntroSeqData13,
- 	kEob2IntroSeqData14,
- 	kEob2IntroSeqData15,
- 	kEob2IntroSeqData16,
- 	kEob2IntroSeqData17,
- 	kEob2IntroSeqData18,
- 	kEob2IntroSeqData19,
- 	kEob2IntroSeqData20,
- 	kEob2IntroSeqData21,
- 	kEob2IntroSeqData22,
- 	kEob2IntroSeqData23,
- 	kEob2IntroSeqData24,
- 	kEob2IntroSeqData25,
- 	kEob2IntroSeqData26,
- 	kEob2IntroSeqData27,
- 	kEob2IntroSeqData28,
- 	kEob2IntroSeqData29,
- 	kEob2IntroSeqData30,
- 	kEob2IntroSeqData31,
- 	kEob2IntroSeqData32,
- 	kEob2IntroSeqData33,
- 	kEob2IntroSeqData34,
- 	kEob2IntroSeqData35,
- 	kEob2IntroSeqData36,
- 	kEob2IntroSeqData37,
- 	kEob2IntroSeqData38,
- 	kEob2IntroSeqData39,
- 	kEob2IntroSeqData40,
- 	kEob2IntroSeqData41,
- 	kEob2IntroSeqData42,
- 	kEob2IntroSeqData43,
-	kEob2IntroShapes00,
- 	kEob2IntroShapes01,
- 	kEob2IntroShapes04,
- 	kEob2IntroShapes07,
-
-	kEob2FinaleStrings,
-	kEob2CreditsData,
-	kEob2FinaleCPSFiles,
-	kEob2FinaleSeqData00,
- 	kEob2FinaleSeqData01,
- 	kEob2FinaleSeqData02,
- 	kEob2FinaleSeqData03,
- 	kEob2FinaleSeqData04,
- 	kEob2FinaleSeqData05,
- 	kEob2FinaleSeqData06,
- 	kEob2FinaleSeqData07,
- 	kEob2FinaleSeqData08,
- 	kEob2FinaleSeqData09,
- 	kEob2FinaleSeqData10,
- 	kEob2FinaleSeqData11,
- 	kEob2FinaleSeqData12,
- 	kEob2FinaleSeqData13,
- 	kEob2FinaleSeqData14,
- 	kEob2FinaleSeqData15,
- 	kEob2FinaleSeqData16,
- 	kEob2FinaleSeqData17,
- 	kEob2FinaleSeqData18,
- 	kEob2FinaleSeqData19,
- 	kEob2FinaleSeqData20,
-	kEob2FinaleShapes00,
- 	kEob2FinaleShapes03,
- 	kEob2FinaleShapes07,
- 	kEob2FinaleShapes09,
- 	kEob2FinaleShapes10,
-
-	kEob2NpcShapeData,
-	kEob2Npc1Strings,
-	kEob2Npc2Strings,
-	kEob2MonsterDustStrings,
-
-	kEob2DreamSteps,
-	kEob2KheldranStrings,
-	kEob2HornStrings,
-	kEob2HornSounds,
-
-	kEob2WallOfForceDsX,
-	kEob2WallOfForceDsY,
-	kEob2WallOfForceNumW,
-	kEob2WallOfForceNumH,
-	kEob2WallOfForceShpId,
-
-	kLolIngamePakFiles,
-	kLolCharacterDefs,
-	kLolIngameSfxFiles,
-	kLolIngameSfxIndex,
-	kLolMusicTrackMap,
-	kLolIngameGMSfxIndex,
-	kLolIngameMT32SfxIndex,
-	kLolIngamePcSpkSfxIndex,
-	kLolSpellProperties,
-	kLolGameShapeMap,
-	kLolSceneItemOffs,
-	kLolCharInvIndex,
-	kLolCharInvDefs,
-	kLolCharDefsMan,
-	kLolCharDefsWoman,
-	kLolCharDefsKieran,
-	kLolCharDefsAkshel,
-	kLolExpRequirements,
-	kLolMonsterModifiers,
-	kLolMonsterShiftOffsets,
-	kLolMonsterDirFlags,
-	kLolMonsterScaleY,
-	kLolMonsterScaleX,
-	kLolMonsterScaleWH,
-	kLolFlyingObjectShp,
-	kLolInventoryDesc,
-
-	kLolLevelShpList,
-	kLolLevelDatList,
-	kLolCompassDefs,
-	kLolItemPrices,
-	kLolStashSetup,
-
-	kLolDscWalls,
-	kLolDscOvlMap,
-	kLolDscScaleWidthData,
-	kLolDscScaleHeightData,
-	kLolDscY,
-
-	kLolDscDoorScale,
-	kLolDscDoor4,
-	kLolDscDoorX,
-	kLolDscDoorY,
-	kLolDscOvlIndex,	
-
-	kLolScrollXTop,
-	kLolScrollYTop,
-	kLolScrollXBottom,
-	kLolScrollYBottom,
-
-	kLolButtonDefs,
-	kLolButtonList1,
-	kLolButtonList2,
-	kLolButtonList3,
-	kLolButtonList4,
-	kLolButtonList5,
-	kLolButtonList6,
-	kLolButtonList7,
-	kLolButtonList8,
-
-	kLolLegendData,
-	kLolMapCursorOvl,
-	kLolMapStringId,
-
-	kLolSpellbookAnim,
-	kLolSpellbookCoords,
-	kLolHealShapeFrames,
-	kLolLightningDefs,
-	kLolFireballCoords,
-
-	kLolCredits,
-
-	kLolHistory,
+	kEoBBasePortalSeqData,
+	kEoBBaseManDef,
+	kEoBBaseManWord,
+	kEoBBaseManPrompt,
+
+	kEoBBaseBookNumbers,
+	kEoBBaseMageSpellsList,
+	kEoBBaseClericSpellsList,
+	kEoBBaseSpellNames,
+	kEoBBaseMagicStrings1,
+	kEoBBaseMagicStrings2,
+	kEoBBaseMagicStrings3,
+	kEoBBaseMagicStrings4,
+	kEoBBaseMagicStrings6,
+	kEoBBaseMagicStrings7,
+	kEoBBaseMagicStrings8,
+
+	kEoBBaseExpObjectTlMode,
+	kEoBBaseExpObjectTblIndex,
+	kEoBBaseExpObjectShpStart,
+	kEoBBaseExpObjectTbl1,
+	kEoBBaseExpObjectTbl2,
+	kEoBBaseExpObjectTbl3,
+	kEoBBaseExpObjectY,
+
+	kEoBBaseSparkDefSteps,
+	kEoBBaseSparkDefSubSteps,
+	kEoBBaseSparkDefShift,
+	kEoBBaseSparkDefAdd,
+	kEoBBaseSparkDefX,
+	kEoBBaseSparkDefY,
+	kEoBBaseSparkOfFlags1,
+	kEoBBaseSparkOfFlags2,
+	kEoBBaseSparkOfShift,
+	kEoBBaseSparkOfX,
+	kEoBBaseSparkOfY,
+
+	kEoBBaseSpellProperties,
+	kEoBBaseMagicFlightProps,
+	kEoBBaseTurnUndeadEffect,
+	kEoBBaseBurningHandsDest,
+	kEoBBaseConeOfColdDest1,
+	kEoBBaseConeOfColdDest2,
+	kEoBBaseConeOfColdDest3,
+	kEoBBaseConeOfColdDest4,
+	kEoBBaseConeOfColdGfxTbl,
+
+	kEoB1MainMenuStrings,
+	kEoB1BonusStrings,
+
+	kEoB1IntroFilesOpening,
+	kEoB1IntroFilesTower,
+	kEoB1IntroFilesOrb,
+	kEoB1IntroFilesWdEntry,
+	kEoB1IntroFilesKing,
+	kEoB1IntroFilesHands,
+	kEoB1IntroFilesWdExit,
+	kEoB1IntroFilesTunnel,
+	kEoB1IntroOpeningFrmDelay,
+	kEoB1IntroWdEncodeX,
+	kEoB1IntroWdEncodeY,
+	kEoB1IntroWdEncodeWH,
+	kEoB1IntroWdDsX,
+	kEoB1IntroWdDsY,
+	kEoB1IntroTvlX1,
+	kEoB1IntroTvlY1,
+	kEoB1IntroTvlX2,
+	kEoB1IntroTvlY2,
+	kEoB1IntroTvlW,
+	kEoB1IntroTvlH,
+
+	kEoB1DoorShapeDefs,
+	kEoB1DoorSwitchShapeDefs,
+	kEoB1DoorSwitchCoords,
+	kEoB1MonsterProperties,
+
+	kEoB1EnemyMageSpellList,
+	kEoB1EnemyMageSfx,
+	kEoB1BeholderSpellList,
+	kEoB1BeholderSfx,
+	kEoB1TurnUndeadString,
+
+	kEoB1NpcShpData,
+	kEoB1NpcSubShpIndex1,
+	kEoB1NpcSubShpIndex2,
+	kEoB1NpcSubShpY,
+	kEoB1Npc0Strings,
+	kEoB1Npc11Strings,
+	kEoB1Npc12Strings,
+	kEoB1Npc21Strings,
+	kEoB1Npc22Strings,
+	kEoB1Npc31Strings,
+	kEoB1Npc32Strings,
+	kEoB1Npc4Strings,
+	kEoB1Npc5Strings,
+	kEoB1Npc6Strings,
+	kEoB1Npc7Strings,
+
+	kEoB2MainMenuStrings,
+	kEoB2TransferConvertTable,
+	kEoB2TransferExpTable,
+
+	kEoB2IntroStrings,
+	kEoB2IntroCPSFiles,
+	kEoB2IntroSeqData00,
+ 	kEoB2IntroSeqData01,
+ 	kEoB2IntroSeqData02,
+ 	kEoB2IntroSeqData03,
+ 	kEoB2IntroSeqData04,
+ 	kEoB2IntroSeqData05,
+ 	kEoB2IntroSeqData06,
+ 	kEoB2IntroSeqData07,
+ 	kEoB2IntroSeqData08,
+ 	kEoB2IntroSeqData09,
+ 	kEoB2IntroSeqData10,
+ 	kEoB2IntroSeqData11,
+ 	kEoB2IntroSeqData12,
+ 	kEoB2IntroSeqData13,
+ 	kEoB2IntroSeqData14,
+ 	kEoB2IntroSeqData15,
+ 	kEoB2IntroSeqData16,
+ 	kEoB2IntroSeqData17,
+ 	kEoB2IntroSeqData18,
+ 	kEoB2IntroSeqData19,
+ 	kEoB2IntroSeqData20,
+ 	kEoB2IntroSeqData21,
+ 	kEoB2IntroSeqData22,
+ 	kEoB2IntroSeqData23,
+ 	kEoB2IntroSeqData24,
+ 	kEoB2IntroSeqData25,
+ 	kEoB2IntroSeqData26,
+ 	kEoB2IntroSeqData27,
+ 	kEoB2IntroSeqData28,
+ 	kEoB2IntroSeqData29,
+ 	kEoB2IntroSeqData30,
+ 	kEoB2IntroSeqData31,
+ 	kEoB2IntroSeqData32,
+ 	kEoB2IntroSeqData33,
+ 	kEoB2IntroSeqData34,
+ 	kEoB2IntroSeqData35,
+ 	kEoB2IntroSeqData36,
+ 	kEoB2IntroSeqData37,
+ 	kEoB2IntroSeqData38,
+ 	kEoB2IntroSeqData39,
+ 	kEoB2IntroSeqData40,
+ 	kEoB2IntroSeqData41,
+ 	kEoB2IntroSeqData42,
+ 	kEoB2IntroSeqData43,
+	kEoB2IntroShapes00,
+ 	kEoB2IntroShapes01,
+ 	kEoB2IntroShapes04,
+ 	kEoB2IntroShapes07,
+
+	kEoB2FinaleStrings,
+	kEoB2CreditsData,
+	kEoB2FinaleCPSFiles,
+	kEoB2FinaleSeqData00,
+ 	kEoB2FinaleSeqData01,
+ 	kEoB2FinaleSeqData02,
+ 	kEoB2FinaleSeqData03,
+ 	kEoB2FinaleSeqData04,
+ 	kEoB2FinaleSeqData05,
+ 	kEoB2FinaleSeqData06,
+ 	kEoB2FinaleSeqData07,
+ 	kEoB2FinaleSeqData08,
+ 	kEoB2FinaleSeqData09,
+ 	kEoB2FinaleSeqData10,
+ 	kEoB2FinaleSeqData11,
+ 	kEoB2FinaleSeqData12,
+ 	kEoB2FinaleSeqData13,
+ 	kEoB2FinaleSeqData14,
+ 	kEoB2FinaleSeqData15,
+ 	kEoB2FinaleSeqData16,
+ 	kEoB2FinaleSeqData17,
+ 	kEoB2FinaleSeqData18,
+ 	kEoB2FinaleSeqData19,
+ 	kEoB2FinaleSeqData20,
+	kEoB2FinaleShapes00,
+ 	kEoB2FinaleShapes03,
+ 	kEoB2FinaleShapes07,
+ 	kEoB2FinaleShapes09,
+ 	kEoB2FinaleShapes10,
+
+	kEoB2NpcShapeData,
+	kEoB2Npc1Strings,
+	kEoB2Npc2Strings,
+	kEoB2MonsterDustStrings,
+
+	kEoB2DreamSteps,
+	kEoB2KheldranStrings,
+	kEoB2HornStrings,
+	kEoB2HornSounds,
+
+	kEoB2WallOfForceDsX,
+	kEoB2WallOfForceDsY,
+	kEoB2WallOfForceNumW,
+	kEoB2WallOfForceNumH,
+	kEoB2WallOfForceShpId,
+
+	kLoLIngamePakFiles,
+	kLoLCharacterDefs,
+	kLoLIngameSfxFiles,
+	kLoLIngameSfxIndex,
+	kLoLMusicTrackMap,
+	kLoLIngameGMSfxIndex,
+	kLoLIngameMT32SfxIndex,
+	kLoLIngamePcSpkSfxIndex,
+	kLoLSpellProperties,
+	kLoLGameShapeMap,
+	kLoLSceneItemOffs,
+	kLoLCharInvIndex,
+	kLoLCharInvDefs,
+	kLoLCharDefsMan,
+	kLoLCharDefsWoman,
+	kLoLCharDefsKieran,
+	kLoLCharDefsAkshel,
+	kLoLExpRequirements,
+	kLoLMonsterModifiers,
+	kLoLMonsterShiftOffsets,
+	kLoLMonsterDirFlags,
+	kLoLMonsterScaleY,
+	kLoLMonsterScaleX,
+	kLoLMonsterScaleWH,
+	kLoLFlyingObjectShp,
+	kLoLInventoryDesc,
+
+	kLoLLevelShpList,
+	kLoLLevelDatList,
+	kLoLCompassDefs,
+	kLoLItemPrices,
+	kLoLStashSetup,
+
+	kLoLDscWalls,
+	kLoLDscOvlMap,
+	kLoLDscScaleWidthData,
+	kLoLDscScaleHeightData,
+	kLoLDscY,
+
+	kLoLDscDoorScale,
+	kLoLDscDoor4,
+	kLoLDscDoorX,
+	kLoLDscDoorY,
+	kLoLDscOvlIndex,	
+
+	kLoLScrollXTop,
+	kLoLScrollYTop,
+	kLoLScrollXBottom,
+	kLoLScrollYBottom,
+
+	kLoLButtonDefs,
+	kLoLButtonList1,
+	kLoLButtonList2,
+	kLoLButtonList3,
+	kLoLButtonList4,
+	kLoLButtonList5,
+	kLoLButtonList6,
+	kLoLButtonList7,
+	kLoLButtonList8,
+
+	kLoLLegendData,
+	kLoLMapCursorOvl,
+	kLoLMapStringId,
+
+	kLoLSpellbookAnim,
+	kLoLSpellbookCoords,
+	kLoLHealShapeFrames,
+	kLoLLightningDefs,
+	kLoLFireballCoords,
+
+	kLoLCredits,
+
+	kLoLHistory,
 
 	kMaxResIDs
 };
@@ -658,9 +658,9 @@ enum kGame {
 	kKyra1 = 0,
 	kKyra2,
 	kKyra3,
-	kLol,
-	kEob1,
-	kEob2,
+	kLoL,
+	kEoB1,
+	kEoB2,
 };
 
 struct Game {
diff --git a/devtools/create_kyradat/extract.cpp b/devtools/create_kyradat/extract.cpp
index b330c46..6a97114 100644
--- a/devtools/create_kyradat/extract.cpp
+++ b/devtools/create_kyradat/extract.cpp
@@ -50,11 +50,11 @@ bool extractRaw16to8(PAKFile &out, const ExtractInformation *info, const byte *d
 bool extractMrShapeAnimData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
 bool extractRaw16(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
 bool extractRaw32(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
-bool extractLolButtonDefs(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
+bool extractLoLButtonDefs(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
 
-bool extractEob2SeqData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
-bool extractEob2ShapeData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
-bool extractEobNpcData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
+bool extractEoB2SeqData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
+bool extractEoB2ShapeData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
+bool extractEoBNpcData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
 // Extraction type table
 
 const ExtractType extractTypeTable[] = {
@@ -76,17 +76,17 @@ const ExtractType extractTypeTable[] = {
 	{ k3TypeRaw16to8, extractRaw16to8 },
 	{ k3TypeShpData, extractMrShapeAnimData },
 
-	{ kLolTypeCharData, extractRaw },
-	{ kLolTypeSpellData, extractRaw },
-	{ kLolTypeCompassData, extractRaw16to8 },
-	{ kLolTypeFlightShpData, extractRaw16to8 },
-	{ kLolTypeRaw16, extractRaw16 },
-	{ kLolTypeRaw32, extractRaw32 },
-	{ kLolTypeButtonDef, extractLolButtonDefs },
+	{ kLoLTypeCharData, extractRaw },
+	{ kLoLTypeSpellData, extractRaw },
+	{ kLoLTypeCompassData, extractRaw16to8 },
+	{ kLoLTypeFlightShpData, extractRaw16to8 },
+	{ kLoLTypeRaw16, extractRaw16 },
+	{ kLoLTypeRaw32, extractRaw32 },
+	{ kLoLTypeButtonDef, extractLoLButtonDefs },
 
-	{ kEob2TypeSeqData, extractEob2SeqData },
-	{ kEob2TypeShapeData, extractEob2ShapeData },
-	{ kEobTypeNpcData, extractEobNpcData },
+	{ kEoB2TypeSeqData, extractEoB2SeqData },
+	{ kEoB2TypeShapeData, extractEoB2ShapeData },
+	{ kEoBTypeNpcData, extractEoBNpcData },
 
 	{ -1, 0 }
 };
@@ -111,16 +111,16 @@ const TypeTable typeTable[] = {
 	{ k2TypeSfxList, 0 },
 	{ k3TypeRaw16to8, 1 },
 	{ k3TypeShpData, 7 },
-	{ kLolTypeRaw16, 13 },
-	{ kLolTypeRaw32, 14 },
-	{ kLolTypeButtonDef, 12 },
-	{ kLolTypeCharData, 8 },
-	{ kLolTypeSpellData, 9 },
-	{ kLolTypeCompassData, 10 },
-	{ kLolTypeFlightShpData, 11 },
-	{ kEob2TypeSeqData, 15 },
-	{ kEob2TypeShapeData, 16 },
-	{ kEobTypeNpcData, 17},
+	{ kLoLTypeRaw16, 13 },
+	{ kLoLTypeRaw32, 14 },
+	{ kLoLTypeButtonDef, 12 },
+	{ kLoLTypeCharData, 8 },
+	{ kLoLTypeSpellData, 9 },
+	{ kLoLTypeCompassData, 10 },
+	{ kLoLTypeFlightShpData, 11 },
+	{ kEoB2TypeSeqData, 15 },
+	{ kEoB2TypeShapeData, 16 },
+	{ kEoBTypeNpcData, 17},
 	{ -1, 1 }
 };
 
@@ -204,7 +204,7 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da
 		}
 
 		// HACK
-		if (id == k2SeqplayIntroTracks && info->game == kLol)
+		if (id == k2SeqplayIntroTracks && info->game == kLoL)
 			return extractStringsWoSuffix(out, info, data, size, filename, id);
 	}
 
@@ -1016,7 +1016,7 @@ bool extractRaw32(PAKFile &out, const ExtractInformation *info, const byte *data
 	return out.addFile(filename, buffer, size);
 }
 
-bool extractLolButtonDefs(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) {
+bool extractLoLButtonDefs(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) {
 	int num = size / 22;
 	uint8 *buffer = new uint8[size];
 	uint32 outsize = num * 18;
@@ -1047,7 +1047,7 @@ bool extractLolButtonDefs(PAKFile &out, const ExtractInformation *info, const by
 	return out.addFile(filename, buffer, outsize);
 }
 
-bool extractEob2SeqData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) {
+bool extractEoB2SeqData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) {
 	int num = size / 11;
 	uint8 *buffer = new uint8[size];
 	const uint8 *src = data;
@@ -1065,7 +1065,7 @@ bool extractEob2SeqData(PAKFile &out, const ExtractInformation *info, const byte
 	return out.addFile(filename, buffer, size);
 }
 
-bool extractEob2ShapeData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) {
+bool extractEoB2ShapeData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) {
 	int num = size / 6;
 	uint8 *buffer = new uint8[size];
 	const uint8 *src = data;
@@ -1081,14 +1081,14 @@ bool extractEob2ShapeData(PAKFile &out, const ExtractInformation *info, const by
 	return out.addFile(filename, buffer, size);
 }
 
-bool extractEobNpcData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) {
+bool extractEoBNpcData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) {
 	// We use one extraction routine for both EOB 1 and EOB 2 (in spite of the data format differences)
 	// since it is easy enough to generate a common output usable by both engines
 	
 	uint8 *buffer = 0;
 	uint32 outsize = 0;
 	
-	if (info->game == kEob1) {
+	if (info->game == kEoB1) {
 		uint16 num = size / 243;
 		outsize = num * 111 + 2;
 		buffer = new uint8[outsize];
diff --git a/devtools/create_kyradat/extract.h b/devtools/create_kyradat/extract.h
index c91e5de..4af9a14 100644
--- a/devtools/create_kyradat/extract.h
+++ b/devtools/create_kyradat/extract.h
@@ -47,17 +47,17 @@ enum kExtractType {
 	k3TypeRaw16to8,
 	k3TypeShpData,
 
-	kLolTypeRaw16,
-	kLolTypeRaw32,
-	kLolTypeButtonDef,
-	kLolTypeCharData,
-	kLolTypeSpellData,
-	kLolTypeCompassData,
-	kLolTypeFlightShpData,
+	kLoLTypeRaw16,
+	kLoLTypeRaw32,
+	kLoLTypeButtonDef,
+	kLoLTypeCharData,
+	kLoLTypeSpellData,
+	kLoLTypeCompassData,
+	kLoLTypeFlightShpData,
 
-	kEob2TypeSeqData,
-	kEob2TypeShapeData,
-	kEobTypeNpcData
+	kEoB2TypeSeqData,
+	kEoB2TypeShapeData,
+	kEoBTypeNpcData
 };
 
 struct ExtractInformation {
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 65c1a23..b3c855a 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -97,33 +97,33 @@ const Game kyra3Games[] = {
 };
 
 const Game eob1Games[] = {
-	{ kEob1, { EN_ANY, -1, -1 }, kPlatformPC, kNoSpecial, { "1bde1dd37b40ab6de8ad11be33a44c5a", "d760a605d1a1302d06975a1f209fdd72" } },
-	{ kEob1, { DE_DEU, -1, -1 }, kPlatformPC, kNoSpecial, { "0fa3c6e00a81171b9f2adb3fdeb8eea3", "756f300c62aabf1dbd3c26b3b04f8c00" } },
+	{ kEoB1, { EN_ANY, -1, -1 }, kPlatformPC, kNoSpecial, { "1bde1dd37b40ab6de8ad11be33a44c5a", "d760a605d1a1302d06975a1f209fdd72" } },
+	{ kEoB1, { DE_DEU, -1, -1 }, kPlatformPC, kNoSpecial, { "0fa3c6e00a81171b9f2adb3fdeb8eea3", "756f300c62aabf1dbd3c26b3b04f8c00" } },
 	GAME_DUMMY_ENTRY
 };
 
 const Game eob2Games[] = {
-	{ kEob2, { EN_ANY, -1, -1 }, kPlatformPC, kNoSpecial, { "e006d031c2d854f748947f777e0c59b0", 0 } },
-	{ kEob2, { DE_DEU, -1, -1 }, kPlatformPC, kNoSpecial, { "6c6c4168deb2a4cb3dee3f1be2d39746", 0 } },
+	{ kEoB2, { EN_ANY, -1, -1 }, kPlatformPC, kNoSpecial, { "e006d031c2d854f748947f777e0c59b0", 0 } },
+	{ kEoB2, { DE_DEU, -1, -1 }, kPlatformPC, kNoSpecial, { "6c6c4168deb2a4cb3dee3f1be2d39746", 0 } },
 	GAME_DUMMY_ENTRY
 };
 
 const Game lolGames[] = {
 	// DOS demo
-	{ kLol, { EN_ANY, -1, -1 }, kPlatformPC, kDemoVersion, { "30bb5af87d38adb47d3e6ce06b1cb042", 0 } },
+	{ kLoL, { EN_ANY, -1, -1 }, kPlatformPC, kDemoVersion, { "30bb5af87d38adb47d3e6ce06b1cb042", 0 } },
 
 	// DOS floppy (no language specifc strings except character presets)
-	{ kLol, { EN_ANY, -1, -1 }, kPlatformPC, kNoSpecial, { "0cc764a204f7ba8cefe1a5f14c479619", 0 } },
-	{ kLol, { RU_RUS, -1, -1 }, kPlatformPC, kNoSpecial, { "80a9f9bf243bc6ed36d98584fc6988c4", 0 } },
-	{ kLol, { DE_DEU, -1, -1 }, kPlatformPC, kNoSpecial, { "6b843869772c1b779e1386be868c15dd", 0 } },
+	{ kLoL, { EN_ANY, -1, -1 }, kPlatformPC, kNoSpecial, { "0cc764a204f7ba8cefe1a5f14c479619", 0 } },
+	{ kLoL, { RU_RUS, -1, -1 }, kPlatformPC, kNoSpecial, { "80a9f9bf243bc6ed36d98584fc6988c4", 0 } },
+	{ kLoL, { DE_DEU, -1, -1 }, kPlatformPC, kNoSpecial, { "6b843869772c1b779e1386be868c15dd", 0 } },
 
 	// PC98 (no language specifc strings)
-	{ kLol, { JA_JPN, -1, -1 }, kPlatformPC98, kNoSpecial, { "6d5bd4a2f5ce433365734ca6b7a8d984", "1b0a457c48ae6908da301b656fe0aab4" } },
+	{ kLoL, { JA_JPN, -1, -1 }, kPlatformPC98, kNoSpecial, { "6d5bd4a2f5ce433365734ca6b7a8d984", "1b0a457c48ae6908da301b656fe0aab4" } },
 
 	// DOS CD (multi language version, with no language specific strings)
-	{ kLol, { EN_ANY, FR_FRA, DE_DEU }, kPlatformPC, kTalkieVersion, { "9d1778314de80598c0b0d032e2a1a1cf", "263998ec600afca1cc7b935c473df670" } },
-	{ kLol, { IT_ITA, FR_FRA, DE_DEU }, kPlatformPC, kTalkieVersion, { "9d1778314de80598c0b0d032e2a1a1cf", "f2af366e00f79dbf832fa19701d71ed9" } }, // Italian fan translation
-	{ kLol, { EN_ANY, FR_FRA, RU_RUS }, kPlatformPC, kTalkieVersion, { "9d1778314de80598c0b0d032e2a1a1cf", "5b33478718968676343803911dd5e3e4" } }, // Russian fan translation
+	{ kLoL, { EN_ANY, FR_FRA, DE_DEU }, kPlatformPC, kTalkieVersion, { "9d1778314de80598c0b0d032e2a1a1cf", "263998ec600afca1cc7b935c473df670" } },
+	{ kLoL, { IT_ITA, FR_FRA, DE_DEU }, kPlatformPC, kTalkieVersion, { "9d1778314de80598c0b0d032e2a1a1cf", "f2af366e00f79dbf832fa19701d71ed9" } }, // Italian fan translation
+	{ kLoL, { EN_ANY, FR_FRA, RU_RUS }, kPlatformPC, kTalkieVersion, { "9d1778314de80598c0b0d032e2a1a1cf", "5b33478718968676343803911dd5e3e4" } }, // Russian fan translation
 	GAME_DUMMY_ENTRY
 };
 
@@ -777,250 +777,250 @@ const int kyra3Need[] = {
 };
 
 const int lolFloppyNeed[] = {
-	kLolIngamePakFiles,
-
-	kLolCharacterDefs,
-	kLolIngameSfxFiles,
-	kLolIngameSfxIndex,
-	kLolMusicTrackMap,
-	kLolIngameGMSfxIndex,
-	kLolIngameMT32SfxIndex,
-	kLolIngamePcSpkSfxIndex,
-	kLolSpellProperties,
-	kLolGameShapeMap,
-	kLolSceneItemOffs,
-	kLolCharInvIndex,
-	kLolCharInvDefs,
-	kLolCharDefsMan,
-	kLolCharDefsWoman,
-	kLolCharDefsKieran,
-	kLolCharDefsAkshel,
-	kLolExpRequirements,
-	kLolMonsterModifiers,
-	kLolMonsterShiftOffsets,
-	kLolMonsterDirFlags,
-	kLolMonsterScaleY,
-	kLolMonsterScaleX,
-	kLolMonsterScaleWH,
-	kLolFlyingObjectShp,
-	kLolInventoryDesc,
-
-	kLolLevelShpList,
-	kLolLevelDatList,
-	kLolCompassDefs,
-	kLolStashSetup,
-	kLolDscWalls,
-	kLolEobCommonDscShapeIndex,
-	kLolDscOvlMap,
-	kLolDscScaleWidthData,
-	kLolDscScaleHeightData,
-	kLolEobCommonDscX,
-	kLolDscY,
-	kLolEobCommonDscTileIndex,
-	kLolEobCommonDscUnk2,
-	kLolEobCommonDscDoorShapeIndex,
-	kLolEobCommonDscDimData1,
-	kLolEobCommonDscDimData2,
-	kLolEobCommonDscBlockMap,
-	kLolEobCommonDscDimMap,
-	kLolDscOvlIndex,
-	kLolEobCommonDscBlockIndex,
-	kLolEobCommonDscDoorY2,
-	kLolDscDoorScale,
-	kLolDscDoor4,
-	kLolDscDoorX,
-	kLolDscDoorY,
-
-	kLolScrollXTop,
-	kLolScrollYTop,
-	kLolScrollXBottom,
-	kLolScrollYBottom,
-
-	kLolButtonDefs,
-	kLolButtonList1,
-	kLolButtonList1,
-	kLolButtonList2,
-	kLolButtonList3,
-	kLolButtonList4,
-	kLolButtonList5,
-	kLolButtonList6,
-	kLolButtonList7,
-	kLolButtonList8,
-
-	kLolLegendData,
-	kLolMapCursorOvl,
-	kLolMapStringId,
-
-	kLolSpellbookAnim,
-	kLolSpellbookCoords,
-	kLolHealShapeFrames,
-	kLolLightningDefs,
-	kLolFireballCoords,
+	kLoLIngamePakFiles,
+
+	kLoLCharacterDefs,
+	kLoLIngameSfxFiles,
+	kLoLIngameSfxIndex,
+	kLoLMusicTrackMap,
+	kLoLIngameGMSfxIndex,
+	kLoLIngameMT32SfxIndex,
+	kLoLIngamePcSpkSfxIndex,
+	kLoLSpellProperties,
+	kLoLGameShapeMap,
+	kLoLSceneItemOffs,
+	kLoLCharInvIndex,
+	kLoLCharInvDefs,
+	kLoLCharDefsMan,
+	kLoLCharDefsWoman,
+	kLoLCharDefsKieran,
+	kLoLCharDefsAkshel,
+	kLoLExpRequirements,
+	kLoLMonsterModifiers,
+	kLoLMonsterShiftOffsets,
+	kLoLMonsterDirFlags,
+	kLoLMonsterScaleY,
+	kLoLMonsterScaleX,
+	kLoLMonsterScaleWH,
+	kLoLFlyingObjectShp,
+	kLoLInventoryDesc,
+
+	kLoLLevelShpList,
+	kLoLLevelDatList,
+	kLoLCompassDefs,
+	kLoLStashSetup,
+	kLoLDscWalls,
+	kRpgCommonDscShapeIndex,
+	kLoLDscOvlMap,
+	kLoLDscScaleWidthData,
+	kLoLDscScaleHeightData,
+	kRpgCommonDscX,
+	kLoLDscY,
+	kRpgCommonDscTileIndex,
+	kRpgCommonDscUnk2,
+	kRpgCommonDscDoorShapeIndex,
+	kRpgCommonDscDimData1,
+	kRpgCommonDscDimData2,
+	kRpgCommonDscBlockMap,
+	kRpgCommonDscDimMap,
+	kLoLDscOvlIndex,
+	kRpgCommonDscBlockIndex,
+	kRpgCommonDscDoorY2,
+	kLoLDscDoorScale,
+	kLoLDscDoor4,
+	kLoLDscDoorX,
+	kLoLDscDoorY,
+
+	kLoLScrollXTop,
+	kLoLScrollYTop,
+	kLoLScrollXBottom,
+	kLoLScrollYBottom,
+
+	kLoLButtonDefs,
+	kLoLButtonList1,
+	kLoLButtonList1,
+	kLoLButtonList2,
+	kLoLButtonList3,
+	kLoLButtonList4,
+	kLoLButtonList5,
+	kLoLButtonList6,
+	kLoLButtonList7,
+	kLoLButtonList8,
+
+	kLoLLegendData,
+	kLoLMapCursorOvl,
+	kLoLMapStringId,
+
+	kLoLSpellbookAnim,
+	kLoLSpellbookCoords,
+	kLoLHealShapeFrames,
+	kLoLLightningDefs,
+	kLoLFireballCoords,
 
 	-1
 };
 
 const int lolPC98Need[] = {
-	kLolIngamePakFiles,
-
-	kLolCharacterDefs,
-	kLolIngameSfxFiles,
-	kLolIngameSfxIndex,
-	kLolSpellProperties,
-	kLolGameShapeMap,
-	kLolSceneItemOffs,
-	kLolCharInvIndex,
-	kLolCharInvDefs,
-	kLolCharDefsMan,
-	kLolCharDefsWoman,
-	kLolCharDefsKieran,
-	kLolCharDefsAkshel,
-	kLolExpRequirements,
-	kLolMonsterModifiers,
-	kLolMonsterShiftOffsets,
-	kLolMonsterDirFlags,
-	kLolMonsterScaleY,
-	kLolMonsterScaleX,
-	kLolMonsterScaleWH,
-	kLolFlyingObjectShp,
-	kLolInventoryDesc,
-
-	kLolLevelShpList,
-	kLolLevelDatList,
-	kLolCompassDefs,
-	kLolStashSetup,
-	kLolDscWalls,
-	kLolEobCommonDscShapeIndex,
-	kLolDscOvlMap,
-	kLolDscScaleWidthData,
-	kLolDscScaleHeightData,
-	kLolEobCommonDscX,
-	kLolDscY,
-	kLolEobCommonDscTileIndex,
-	kLolEobCommonDscUnk2,
-	kLolEobCommonDscDoorShapeIndex,
-	kLolEobCommonDscDimData1,
-	kLolEobCommonDscDimData2,
-	kLolEobCommonDscBlockMap,
-	kLolEobCommonDscDimMap,
-	kLolDscOvlIndex,
-	kLolEobCommonDscBlockIndex,
-	kLolEobCommonDscDoorY2,
-	kLolDscDoorScale,
-	kLolDscDoor4,
-	kLolDscDoorX,
-	kLolDscDoorY,
-
-	kLolScrollXTop,
-	kLolScrollYTop,
-	kLolScrollXBottom,
-	kLolScrollYBottom,
-
-	kLolButtonDefs,
-	kLolButtonList1,
-	kLolButtonList1,
-	kLolButtonList2,
-	kLolButtonList3,
-	kLolButtonList4,
-	kLolButtonList5,
-	kLolButtonList6,
-	kLolButtonList7,
-	kLolButtonList8,
-
-	kLolLegendData,
-	kLolMapStringId,
-
-	kLolSpellbookAnim,
-	kLolSpellbookCoords,
-	kLolHealShapeFrames,
-	kLolLightningDefs,
-	kLolFireballCoords,
-
-	kLolCredits,
+	kLoLIngamePakFiles,
+
+	kLoLCharacterDefs,
+	kLoLIngameSfxFiles,
+	kLoLIngameSfxIndex,
+	kLoLSpellProperties,
+	kLoLGameShapeMap,
+	kLoLSceneItemOffs,
+	kLoLCharInvIndex,
+	kLoLCharInvDefs,
+	kLoLCharDefsMan,
+	kLoLCharDefsWoman,
+	kLoLCharDefsKieran,
+	kLoLCharDefsAkshel,
+	kLoLExpRequirements,
+	kLoLMonsterModifiers,
+	kLoLMonsterShiftOffsets,
+	kLoLMonsterDirFlags,
+	kLoLMonsterScaleY,
+	kLoLMonsterScaleX,
+	kLoLMonsterScaleWH,
+	kLoLFlyingObjectShp,
+	kLoLInventoryDesc,
+
+	kLoLLevelShpList,
+	kLoLLevelDatList,
+	kLoLCompassDefs,
+	kLoLStashSetup,
+	kLoLDscWalls,
+	kRpgCommonDscShapeIndex,
+	kLoLDscOvlMap,
+	kLoLDscScaleWidthData,
+	kLoLDscScaleHeightData,
+	kRpgCommonDscX,
+	kLoLDscY,
+	kRpgCommonDscTileIndex,
+	kRpgCommonDscUnk2,
+	kRpgCommonDscDoorShapeIndex,
+	kRpgCommonDscDimData1,
+	kRpgCommonDscDimData2,
+	kRpgCommonDscBlockMap,
+	kRpgCommonDscDimMap,
+	kLoLDscOvlIndex,
+	kRpgCommonDscBlockIndex,
+	kRpgCommonDscDoorY2,
+	kLoLDscDoorScale,
+	kLoLDscDoor4,
+	kLoLDscDoorX,
+	kLoLDscDoorY,
+
+	kLoLScrollXTop,
+	kLoLScrollYTop,
+	kLoLScrollXBottom,
+	kLoLScrollYBottom,
+
+	kLoLButtonDefs,
+	kLoLButtonList1,
+	kLoLButtonList1,
+	kLoLButtonList2,
+	kLoLButtonList3,
+	kLoLButtonList4,
+	kLoLButtonList5,
+	kLoLButtonList6,
+	kLoLButtonList7,
+	kLoLButtonList8,
+
+	kLoLLegendData,
+	kLoLMapStringId,
+
+	kLoLSpellbookAnim,
+	kLoLSpellbookCoords,
+	kLoLHealShapeFrames,
+	kLoLLightningDefs,
+	kLoLFireballCoords,
+
+	kLoLCredits,
 
 	-1
 };
 
 const int lolCDNeed[] = {
-	kLolHistory,
-	kLolCharacterDefs,
-	kLolIngameSfxFiles,
-	kLolIngameSfxIndex,
-	kLolMusicTrackMap,
-	kLolIngameGMSfxIndex,
-	kLolIngameMT32SfxIndex,
-	kLolIngamePcSpkSfxIndex,
-	kLolSpellProperties,
-	kLolGameShapeMap,
-	kLolSceneItemOffs,
-	kLolCharInvIndex,
-	kLolCharInvDefs,
-	kLolCharDefsMan,
-	kLolCharDefsWoman,
-	kLolCharDefsKieran,
-	kLolCharDefsAkshel,
-	kLolExpRequirements,
-	kLolMonsterModifiers,
-	kLolMonsterShiftOffsets,
-	kLolMonsterDirFlags,
-	kLolMonsterScaleY,
-	kLolMonsterScaleX,
-	kLolMonsterScaleWH,
-	kLolFlyingObjectShp,
-	kLolInventoryDesc,
-
-	kLolLevelShpList,
-	kLolLevelDatList,
-	kLolCompassDefs,
-	kLolItemPrices,
-	kLolStashSetup,
-	kLolDscWalls,
-	kLolEobCommonDscShapeIndex,
-	kLolDscOvlMap,
-	kLolDscScaleWidthData,
-	kLolDscScaleHeightData,
-	kLolEobCommonDscX,
-	kLolDscY,
-	kLolEobCommonDscTileIndex,
-	kLolEobCommonDscUnk2,
-	kLolEobCommonDscDoorShapeIndex,
-	kLolEobCommonDscDimData1,
-	kLolEobCommonDscDimData2,
-	kLolEobCommonDscBlockMap,
-	kLolEobCommonDscDimMap,
-	kLolDscOvlIndex,
-	kLolEobCommonDscBlockIndex,
-	kLolEobCommonDscDoorY2,
-	kLolDscDoorScale,
-	kLolDscDoor4,
-	kLolDscDoorX,
-	kLolDscDoorY,
-
-	kLolScrollXTop,
-	kLolScrollYTop,
-	kLolScrollXBottom,
-	kLolScrollYBottom,
-
-	kLolButtonDefs,
-	kLolButtonList1,
-	kLolButtonList1,
-	kLolButtonList2,
-	kLolButtonList3,
-	kLolButtonList4,
-	kLolButtonList5,
-	kLolButtonList6,
-	kLolButtonList7,
-	kLolButtonList8,
-
-	kLolLegendData,
-	kLolMapCursorOvl,
-	kLolMapStringId,
-
-	kLolSpellbookAnim,
-	kLolSpellbookCoords,
-	kLolHealShapeFrames,
-	kLolLightningDefs,
-	kLolFireballCoords,
+	kLoLHistory,
+	kLoLCharacterDefs,
+	kLoLIngameSfxFiles,
+	kLoLIngameSfxIndex,
+	kLoLMusicTrackMap,
+	kLoLIngameGMSfxIndex,
+	kLoLIngameMT32SfxIndex,
+	kLoLIngamePcSpkSfxIndex,
+	kLoLSpellProperties,
+	kLoLGameShapeMap,
+	kLoLSceneItemOffs,
+	kLoLCharInvIndex,
+	kLoLCharInvDefs,
+	kLoLCharDefsMan,
+	kLoLCharDefsWoman,
+	kLoLCharDefsKieran,
+	kLoLCharDefsAkshel,
+	kLoLExpRequirements,
+	kLoLMonsterModifiers,
+	kLoLMonsterShiftOffsets,
+	kLoLMonsterDirFlags,
+	kLoLMonsterScaleY,
+	kLoLMonsterScaleX,
+	kLoLMonsterScaleWH,
+	kLoLFlyingObjectShp,
+	kLoLInventoryDesc,
+
+	kLoLLevelShpList,
+	kLoLLevelDatList,
+	kLoLCompassDefs,
+	kLoLItemPrices,
+	kLoLStashSetup,
+	kLoLDscWalls,
+	kRpgCommonDscShapeIndex,
+	kLoLDscOvlMap,
+	kLoLDscScaleWidthData,
+	kLoLDscScaleHeightData,
+	kRpgCommonDscX,
+	kLoLDscY,
+	kRpgCommonDscTileIndex,
+	kRpgCommonDscUnk2,
+	kRpgCommonDscDoorShapeIndex,
+	kRpgCommonDscDimData1,
+	kRpgCommonDscDimData2,
+	kRpgCommonDscBlockMap,
+	kRpgCommonDscDimMap,
+	kLoLDscOvlIndex,
+	kRpgCommonDscBlockIndex,
+	kRpgCommonDscDoorY2,
+	kLoLDscDoorScale,
+	kLoLDscDoor4,
+	kLoLDscDoorX,
+	kLoLDscDoorY,
+
+	kLoLScrollXTop,
+	kLoLScrollYTop,
+	kLoLScrollXBottom,
+	kLoLScrollYBottom,
+
+	kLoLButtonDefs,
+	kLoLButtonList1,
+	kLoLButtonList1,
+	kLoLButtonList2,
+	kLoLButtonList3,
+	kLoLButtonList4,
+	kLoLButtonList5,
+	kLoLButtonList6,
+	kLoLButtonList7,
+	kLoLButtonList8,
+
+	kLoLLegendData,
+	kLoLMapCursorOvl,
+	kLoLMapStringId,
+
+	kLoLSpellbookAnim,
+	kLoLSpellbookCoords,
+	kLoLHealShapeFrames,
+	kLoLLightningDefs,
+	kLoLFireballCoords,
 	-1
 };
 
@@ -1034,585 +1034,585 @@ const int lolDemoNeed[] = {
 };
 
 const int eob1FloppyNeed[] = {
-	kEobBaseChargenStrings1,
-	kEobBaseChargenStrings2,
-	kEobBaseChargenStartLevels,
-	kEobBaseChargenStatStrings,
-	kEobBaseChargenRaceSexStrings,
-	kEobBaseChargenClassStrings,
-	kEobBaseChargenAlignmentStrings,
-	kEobBaseChargenEnterGameStrings,
-	kEobBaseChargenClassMinStats,
-	kEobBaseChargenRaceMinStats,
-	kEobBaseChargenRaceMaxStats,
-
-	kEobBaseSaveThrowTable1,
-	kEobBaseSaveThrowTable2,
-	kEobBaseSaveThrowTable3,
-	kEobBaseSaveThrowTable4,
-	kEobBaseSaveThrwLvlIndex,
-	kEobBaseSaveThrwModDiv,
-	kEobBaseSaveThrwModExt,
-
-	kEob1MainMenuStrings,
-	kEob1BonusStrings,
-
-	kEob1IntroFilesOpening,
-	kEob1IntroFilesTower,
-	kEob1IntroFilesOrb,
-	kEob1IntroFilesWdEntry,
-	kEob1IntroFilesKing,
-	kEob1IntroFilesHands,
-	kEob1IntroFilesWdExit,
-	kEob1IntroFilesTunnel,
-	kEob1IntroOpeningFrmDelay,
-	kEob1IntroWdEncodeX,
-	kEob1IntroWdEncodeY,
-	kEob1IntroWdEncodeWH,
-	kEob1IntroWdDsX,
-	kEob1IntroWdDsY,
-	kEob1IntroTvlX1,
-	kEob1IntroTvlY1,
-	kEob1IntroTvlX2,
-	kEob1IntroTvlY2,
-	kEob1IntroTvlW,
-	kEob1IntroTvlH,
-
-	kEob1DoorShapeDefs,
-	kEob1DoorSwitchShapeDefs,
-	kEob1DoorSwitchCoords,
-	kEob1MonsterProperties,
-	kEob1EnemyMageSpellList,
-	kEob1EnemyMageSfx,
-	kEob1BeholderSpellList,
-	kEob1BeholderSfx,
-	kEob1TurnUndeadString,
-
-	kEob1NpcShpData,
-	kEob1NpcSubShpIndex1,
-	kEob1NpcSubShpIndex2,
-	kEob1NpcSubShpY,
-	kEob1Npc0Strings,
-	kEob1Npc11Strings,
-	kEob1Npc12Strings,
-	kEob1Npc21Strings,
-	kEob1Npc22Strings,
-	kEob1Npc31Strings,
-	kEob1Npc32Strings,
-	kEob1Npc4Strings,
-	kEob1Npc5Strings,
-	kEob1Npc6Strings,
-	kEob1Npc7Strings,
-
-	kEobBasePryDoorStrings,
-	kEobBaseWarningStrings,
-
-	kEobBaseItemSuffixStringsRings,
-	kEobBaseItemSuffixStringsPotions,
-	kEobBaseItemSuffixStringsWands,
+	kEoBBaseChargenStrings1,
+	kEoBBaseChargenStrings2,
+	kEoBBaseChargenStartLevels,
+	kEoBBaseChargenStatStrings,
+	kEoBBaseChargenRaceSexStrings,
+	kEoBBaseChargenClassStrings,
+	kEoBBaseChargenAlignmentStrings,
+	kEoBBaseChargenEnterGameStrings,
+	kEoBBaseChargenClassMinStats,
+	kEoBBaseChargenRaceMinStats,
+	kEoBBaseChargenRaceMaxStats,
+
+	kEoBBaseSaveThrowTable1,
+	kEoBBaseSaveThrowTable2,
+	kEoBBaseSaveThrowTable3,
+	kEoBBaseSaveThrowTable4,
+	kEoBBaseSaveThrwLvlIndex,
+	kEoBBaseSaveThrwModDiv,
+	kEoBBaseSaveThrwModExt,
+
+	kEoB1MainMenuStrings,
+	kEoB1BonusStrings,
+
+	kEoB1IntroFilesOpening,
+	kEoB1IntroFilesTower,
+	kEoB1IntroFilesOrb,
+	kEoB1IntroFilesWdEntry,
+	kEoB1IntroFilesKing,
+	kEoB1IntroFilesHands,
+	kEoB1IntroFilesWdExit,
+	kEoB1IntroFilesTunnel,
+	kEoB1IntroOpeningFrmDelay,
+	kEoB1IntroWdEncodeX,
+	kEoB1IntroWdEncodeY,
+	kEoB1IntroWdEncodeWH,
+	kEoB1IntroWdDsX,
+	kEoB1IntroWdDsY,
+	kEoB1IntroTvlX1,
+	kEoB1IntroTvlY1,
+	kEoB1IntroTvlX2,
+	kEoB1IntroTvlY2,
+	kEoB1IntroTvlW,
+	kEoB1IntroTvlH,
+
+	kEoB1DoorShapeDefs,
+	kEoB1DoorSwitchShapeDefs,
+	kEoB1DoorSwitchCoords,
+	kEoB1MonsterProperties,
+	kEoB1EnemyMageSpellList,
+	kEoB1EnemyMageSfx,
+	kEoB1BeholderSpellList,
+	kEoB1BeholderSfx,
+	kEoB1TurnUndeadString,
+
+	kEoB1NpcShpData,
+	kEoB1NpcSubShpIndex1,
+	kEoB1NpcSubShpIndex2,
+	kEoB1NpcSubShpY,
+	kEoB1Npc0Strings,
+	kEoB1Npc11Strings,
+	kEoB1Npc12Strings,
+	kEoB1Npc21Strings,
+	kEoB1Npc22Strings,
+	kEoB1Npc31Strings,
+	kEoB1Npc32Strings,
+	kEoB1Npc4Strings,
+	kEoB1Npc5Strings,
+	kEoB1Npc6Strings,
+	kEoB1Npc7Strings,
+
+	kEoBBasePryDoorStrings,
+	kEoBBaseWarningStrings,
+
+	kEoBBaseItemSuffixStringsRings,
+	kEoBBaseItemSuffixStringsPotions,
+	kEoBBaseItemSuffixStringsWands,
 	
-	kEobBaseRipItemStrings,
-	kEobBaseCursedString,
-	kEobBaseEnchantedString,
-	kEobBaseMagicObjectStrings,
-	kEobBaseMagicObject5String,
-	kEobBasePatternSuffix,
-	kEobBasePatternGrFix1,
-	kEobBasePatternGrFix2,
-	kEobBaseValidateArmorString,
-	kEobBaseValidateNoDropString,
-	kEobBasePotionStrings,
-	kEobBaseWandString,
-	kEobBaseItemMisuseStrings,
-
-	kEobBaseTakenStrings,
-	kEobBasePotionEffectStrings,
-
-	kEobBaseYesNoStrings,
-	kLolEobCommonMoreStrings,
-	kEobBaseNpcMaxStrings,
-	kEobBaseNpcJoinStrings,
-	kEobBaseCancelStrings,
-
-	kEobBaseMenuStringsMain,
-	kEobBaseMenuStringsSaveLoad,
-	kEobBaseMenuStringsOnOff,
-	kEobBaseMenuStringsSpells,
-	kEobBaseMenuStringsRest,
-	kEobBaseMenuStringsDrop,
-	kEobBaseMenuStringsExit,
-	kEobBaseMenuStringsStarve,
-	kEobBaseMenuStringsScribe,
-	kEobBaseMenuStringsDrop2,
-	kEobBaseMenuStringsHead,
-	kEobBaseMenuStringsPoison,
-	kEobBaseMenuStringsMgc,
-	kEobBaseMenuStringsPrefs,
-	kEobBaseMenuStringsRest2,
-	kEobBaseMenuStringsRest4,
-	kEobBaseMenuStringsDefeat,
-	kEobBaseMenuYesNoStrings,
-
-	kEobBaseSpellLevelsMage,
-	kEobBaseSpellLevelsCleric,
-	kEobBaseNumSpellsCleric,
-	kEobBaseNumSpellsWisAdj,
-	kEobBaseNumSpellsPal,
-	kEobBaseNumSpellsMage,
+	kEoBBaseRipItemStrings,
+	kEoBBaseCursedString,
+	kEoBBaseEnchantedString,
+	kEoBBaseMagicObjectStrings,
+	kEoBBaseMagicObject5String,
+	kEoBBasePatternSuffix,
+	kEoBBasePatternGrFix1,
+	kEoBBasePatternGrFix2,
+	kEoBBaseValidateArmorString,
+	kEoBBaseValidateNoDropString,
+	kEoBBasePotionStrings,
+	kEoBBaseWandString,
+	kEoBBaseItemMisuseStrings,
+
+	kEoBBaseTakenStrings,
+	kEoBBasePotionEffectStrings,
+
+	kEoBBaseYesNoStrings,
+	kRpgCommonMoreStrings,
+	kEoBBaseNpcMaxStrings,
+	kEoBBaseNpcJoinStrings,
+	kEoBBaseCancelStrings,
+
+	kEoBBaseMenuStringsMain,
+	kEoBBaseMenuStringsSaveLoad,
+	kEoBBaseMenuStringsOnOff,
+	kEoBBaseMenuStringsSpells,
+	kEoBBaseMenuStringsRest,
+	kEoBBaseMenuStringsDrop,
+	kEoBBaseMenuStringsExit,
+	kEoBBaseMenuStringsStarve,
+	kEoBBaseMenuStringsScribe,
+	kEoBBaseMenuStringsDrop2,
+	kEoBBaseMenuStringsHead,
+	kEoBBaseMenuStringsPoison,
+	kEoBBaseMenuStringsMgc,
+	kEoBBaseMenuStringsPrefs,
+	kEoBBaseMenuStringsRest2,
+	kEoBBaseMenuStringsRest4,
+	kEoBBaseMenuStringsDefeat,
+	kEoBBaseMenuYesNoStrings,
+
+	kEoBBaseSpellLevelsMage,
+	kEoBBaseSpellLevelsCleric,
+	kEoBBaseNumSpellsCleric,
+	kEoBBaseNumSpellsWisAdj,
+	kEoBBaseNumSpellsPal,
+	kEoBBaseNumSpellsMage,
 	
-	kEobBaseCharGuiStringsHp,
-	kEobBaseCharGuiStringsWp1,
-	kEobBaseCharGuiStringsWr,
-	kEobBaseCharGuiStringsSt1,
-	kEobBaseCharGuiStringsIn,
-
-	kEobBaseCharStatusStrings7,
-	kEobBaseCharStatusStrings81,
-	kEobBaseCharStatusStrings9,
-	kEobBaseCharStatusStrings131,
-
-	kEobBaseLevelGainStrings,
-	kEobBaseExperienceTable0,
-	kEobBaseExperienceTable1,
-	kEobBaseExperienceTable2,
-	kEobBaseExperienceTable3,
-	kEobBaseExperienceTable4,
-
-	kEobBaseBookNumbers,
-	kEobBaseMageSpellsList,
-	kEobBaseClericSpellsList,
-	kEobBaseSpellNames,
-	kEobBaseMagicStrings1,
-	kEobBaseMagicStrings2,
-	kEobBaseMagicStrings3,
-	kEobBaseMagicStrings4,
-	kEobBaseMagicStrings6,
-	kEobBaseMagicStrings7,
-	kEobBaseMagicStrings8,
-
-	kEobBaseExpObjectTblIndex,
-	kEobBaseExpObjectShpStart,
-	kEobBaseExpObjectTbl1,
-	kEobBaseExpObjectTbl2,
-	kEobBaseExpObjectTbl3,
-	kEobBaseExpObjectY,
-
-	kEobBaseSparkDefSteps,
-	kEobBaseSparkDefSubSteps,
-	kEobBaseSparkDefShift,
-	kEobBaseSparkDefAdd,
-	kEobBaseSparkDefX,
-	kEobBaseSparkDefY,
-	kEobBaseSparkOfFlags1,
-	kEobBaseSparkOfFlags2,
-	kEobBaseSparkOfShift,
-	kEobBaseSparkOfX,
-	kEobBaseSparkOfY,
-
-	kEobBaseSpellProperties,
-	kEobBaseMagicFlightProps,
-	kEobBaseTurnUndeadEffect,
-	kEobBaseBurningHandsDest,
-	kEobBaseConeOfColdDest1,
-	kEobBaseConeOfColdDest2,
-	kEobBaseConeOfColdDest3,
-	kEobBaseConeOfColdDest4,
-	kEobBaseConeOfColdGfxTbl,
-
-	kLolEobCommonDscDoorShapeIndex,
-	kEobBaseWllFlagPreset,
-	kEobBaseDscShapeCoords,
-	kEobBaseDscDoorScaleOffs,
-	kEobBaseDscDoorScaleMult1,
-	kEobBaseDscDoorScaleMult2,
-	kEobBaseDscDoorScaleMult3,
-	kEobBaseDscDoorScaleMult4,
-	kEobBaseDscDoorScaleMult5,
-	kEobBaseDscDoorScaleMult6,
-	kEobBaseDscDoorXE,
-	kEobBaseDscDoorY1,
-	kEobBaseDscDoorY3,
-	kEobBaseDscDoorY4,
-	kEobBaseDscDoorY5,
-	kEobBaseDscDoorY6,
-	kEobBaseDscDoorY7,
-	kEobBaseDscDoorCoordsExt,
-
-	kEobBaseDscItemPosIndex,
-	kEobBaseDscItemShpX,
-	kEobBaseDscItemPosUnk,
-	kEobBaseDscItemTileIndex,
-	kEobBaseDscItemShapeMap,
-	kEobBaseDscTelptrShpCoords,
-
-	kEobBasePortalSeqData,
-	kEobBaseManDef,
-	kEobBaseManWord,
-	kEobBaseManPrompt,
-
-	kEobBaseDscMonsterFrmOffsTbl1,
-	kEobBaseDscMonsterFrmOffsTbl2,
-
-	kEobBaseInvSlotX,
-	kEobBaseInvSlotY,
-	kEobBaseSlotValidationFlags,
-
-	kEobBaseProjectileWeaponTypes,
-	kEobBaseWandTypes,
-
-	kEobBaseDrawObjPosIndex,
-	kEobBaseFlightObjFlipIndex,
-	kEobBaseFlightObjShpMap,
-	kEobBaseFlightObjSclIndex,
-
-	kLolEobCommonDscShapeIndex,
-	kLolEobCommonDscX,
-	kLolEobCommonDscTileIndex,
-	kLolEobCommonDscUnk2,	
-	kLolEobCommonDscDimData1,
-	kLolEobCommonDscDimData2,
-	kLolEobCommonDscBlockMap,
-	kLolEobCommonDscDimMap,	
-	kLolEobCommonDscBlockIndex,
-
-	kEobBaseClassModifierFlags,
-
-	kEobBaseMonsterStepTable01,
-	//kEobBaseMonsterStepTable1,
-	kEobBaseMonsterStepTable2,
-	kEobBaseMonsterStepTable3,
-	kEobBaseMonsterCloseAttPosTable1,
-	kEobBaseMonsterCloseAttPosTable21,
-	//kEobBaseMonsterCloseAttUnkTable,
-	kEobBaseMonsterCloseAttChkTable1,
-	kEobBaseMonsterCloseAttChkTable2,
-	kEobBaseMonsterCloseAttDstTable1,
-	kEobBaseMonsterCloseAttDstTable2,
-
-	kEobBaseMonsterProximityTable,
-	kEobBaseFindBlockMonstersTable,
-	kEobBaseMonsterDirChangeTable,
-	kEobBaseMonsterDistAttStrings,
-	kEobBaseEncodeMonsterDefs,
-	kEobBaseNpcPresets,
-	//kEob1Npc1Strings,
-	//kEob1Npc2Strings,
+	kEoBBaseCharGuiStringsHp,
+	kEoBBaseCharGuiStringsWp1,
+	kEoBBaseCharGuiStringsWr,
+	kEoBBaseCharGuiStringsSt1,
+	kEoBBaseCharGuiStringsIn,
+
+	kEoBBaseCharStatusStrings7,
+	kEoBBaseCharStatusStrings81,
+	kEoBBaseCharStatusStrings9,
+	kEoBBaseCharStatusStrings131,
+
+	kEoBBaseLevelGainStrings,
+	kEoBBaseExperienceTable0,
+	kEoBBaseExperienceTable1,
+	kEoBBaseExperienceTable2,
+	kEoBBaseExperienceTable3,
+	kEoBBaseExperienceTable4,
+
+	kEoBBaseBookNumbers,
+	kEoBBaseMageSpellsList,
+	kEoBBaseClericSpellsList,
+	kEoBBaseSpellNames,
+	kEoBBaseMagicStrings1,
+	kEoBBaseMagicStrings2,
+	kEoBBaseMagicStrings3,
+	kEoBBaseMagicStrings4,
+	kEoBBaseMagicStrings6,
+	kEoBBaseMagicStrings7,
+	kEoBBaseMagicStrings8,
+
+	kEoBBaseExpObjectTblIndex,
+	kEoBBaseExpObjectShpStart,
+	kEoBBaseExpObjectTbl1,
+	kEoBBaseExpObjectTbl2,
+	kEoBBaseExpObjectTbl3,
+	kEoBBaseExpObjectY,
+
+	kEoBBaseSparkDefSteps,
+	kEoBBaseSparkDefSubSteps,
+	kEoBBaseSparkDefShift,
+	kEoBBaseSparkDefAdd,
+	kEoBBaseSparkDefX,
+	kEoBBaseSparkDefY,
+	kEoBBaseSparkOfFlags1,
+	kEoBBaseSparkOfFlags2,
+	kEoBBaseSparkOfShift,
+	kEoBBaseSparkOfX,
+	kEoBBaseSparkOfY,
+
+	kEoBBaseSpellProperties,
+	kEoBBaseMagicFlightProps,
+	kEoBBaseTurnUndeadEffect,
+	kEoBBaseBurningHandsDest,
+	kEoBBaseConeOfColdDest1,
+	kEoBBaseConeOfColdDest2,
+	kEoBBaseConeOfColdDest3,
+	kEoBBaseConeOfColdDest4,
+	kEoBBaseConeOfColdGfxTbl,
+
+	kRpgCommonDscDoorShapeIndex,
+	kEoBBaseWllFlagPreset,
+	kEoBBaseDscShapeCoords,
+	kEoBBaseDscDoorScaleOffs,
+	kEoBBaseDscDoorScaleMult1,
+	kEoBBaseDscDoorScaleMult2,
+	kEoBBaseDscDoorScaleMult3,
+	kEoBBaseDscDoorScaleMult4,
+	kEoBBaseDscDoorScaleMult5,
+	kEoBBaseDscDoorScaleMult6,
+	kEoBBaseDscDoorXE,
+	kEoBBaseDscDoorY1,
+	kEoBBaseDscDoorY3,
+	kEoBBaseDscDoorY4,
+	kEoBBaseDscDoorY5,
+	kEoBBaseDscDoorY6,
+	kEoBBaseDscDoorY7,
+	kEoBBaseDscDoorCoordsExt,
+
+	kEoBBaseDscItemPosIndex,
+	kEoBBaseDscItemShpX,
+	kEoBBaseDscItemPosUnk,
+	kEoBBaseDscItemTileIndex,
+	kEoBBaseDscItemShapeMap,
+	kEoBBaseDscTelptrShpCoords,
+
+	kEoBBasePortalSeqData,
+	kEoBBaseManDef,
+	kEoBBaseManWord,
+	kEoBBaseManPrompt,
+
+	kEoBBaseDscMonsterFrmOffsTbl1,
+	kEoBBaseDscMonsterFrmOffsTbl2,
+
+	kEoBBaseInvSlotX,
+	kEoBBaseInvSlotY,
+	kEoBBaseSlotValidationFlags,
+
+	kEoBBaseProjectileWeaponTypes,
+	kEoBBaseWandTypes,
+
+	kEoBBaseDrawObjPosIndex,
+	kEoBBaseFlightObjFlipIndex,
+	kEoBBaseFlightObjShpMap,
+	kEoBBaseFlightObjSclIndex,
+
+	kRpgCommonDscShapeIndex,
+	kRpgCommonDscX,
+	kRpgCommonDscTileIndex,
+	kRpgCommonDscUnk2,	
+	kRpgCommonDscDimData1,
+	kRpgCommonDscDimData2,
+	kRpgCommonDscBlockMap,
+	kRpgCommonDscDimMap,	
+	kRpgCommonDscBlockIndex,
+
+	kEoBBaseClassModifierFlags,
+
+	kEoBBaseMonsterStepTable01,
+	//kEoBBaseMonsterStepTable1,
+	kEoBBaseMonsterStepTable2,
+	kEoBBaseMonsterStepTable3,
+	kEoBBaseMonsterCloseAttPosTable1,
+	kEoBBaseMonsterCloseAttPosTable21,
+	//kEoBBaseMonsterCloseAttUnkTable,
+	kEoBBaseMonsterCloseAttChkTable1,
+	kEoBBaseMonsterCloseAttChkTable2,
+	kEoBBaseMonsterCloseAttDstTable1,
+	kEoBBaseMonsterCloseAttDstTable2,
+
+	kEoBBaseMonsterProximityTable,
+	kEoBBaseFindBlockMonstersTable,
+	kEoBBaseMonsterDirChangeTable,
+	kEoBBaseMonsterDistAttStrings,
+	kEoBBaseEncodeMonsterDefs,
+	kEoBBaseNpcPresets,
+	//kEoB1Npc1Strings,
+	//kEoB1Npc2Strings,
 	-1
 };
 
 const int eob2FloppyNeed[] = {
-	kEobBaseChargenStrings1,
-	kEobBaseChargenStrings2,
-	kEobBaseChargenStartLevels,
-	kEobBaseChargenStatStrings,
-	kEobBaseChargenRaceSexStrings,
-	kEobBaseChargenClassStrings,
-	kEobBaseChargenAlignmentStrings,
-	kEobBaseChargenEnterGameStrings,
-	kEobBaseChargenClassMinStats,
-	kEobBaseChargenRaceMinStats,
-	kEobBaseChargenRaceMaxStats,
-
-	kEobBaseSaveThrowTable1,
-	kEobBaseSaveThrowTable2,
-	kEobBaseSaveThrowTable3,
-	kEobBaseSaveThrowTable4,
-	kEobBaseSaveThrwLvlIndex,
-	kEobBaseSaveThrwModDiv,
-	kEobBaseSaveThrwModExt,
-
-	kEobBasePryDoorStrings,
-	kEobBaseWarningStrings,
-
-	kEobBaseItemSuffixStringsRings,
-	kEobBaseItemSuffixStringsPotions,
-	kEobBaseItemSuffixStringsWands,
-
-	kEobBaseRipItemStrings,
-	kEobBaseCursedString,
-	kEobBaseEnchantedString,
-	kEobBaseMagicObjectStrings,
-	kEobBaseMagicObject5String,
-	kEobBasePatternSuffix,
-	kEobBasePatternGrFix1,
-	kEobBasePatternGrFix2,
-	kEobBaseValidateArmorString,
-	kEobBaseValidateCursedString,
-	kEobBaseValidateNoDropString,
-	kEobBasePotionStrings,
-	kEobBaseWandString,
-	kEobBaseItemMisuseStrings,
-
-	kEobBaseTakenStrings,
-	kEobBasePotionEffectStrings,
-
-	kEobBaseYesNoStrings,
-	kLolEobCommonMoreStrings,
-	kEobBaseNpcMaxStrings,
-	kEobBaseOkStrings,
-	kEobBaseNpcJoinStrings,
-	kEobBaseCancelStrings,
-	kEobBaseAbortStrings,
-
-	kEobBaseMenuStringsMain,
-	kEobBaseMenuStringsSaveLoad,
-	kEobBaseMenuStringsOnOff,
-	kEobBaseMenuStringsSpells,
-	kEobBaseMenuStringsRest,
-	kEobBaseMenuStringsDrop,
-	kEobBaseMenuStringsExit,
-	kEobBaseMenuStringsStarve,
-	kEobBaseMenuStringsScribe,
-	kEobBaseMenuStringsDrop2,
-	kEobBaseMenuStringsHead,
-	kEobBaseMenuStringsPoison,
-	kEobBaseMenuStringsMgc,
-	kEobBaseMenuStringsPrefs,
-	kEobBaseMenuStringsRest2,
-	kEobBaseMenuStringsRest3,
-	kEobBaseMenuStringsRest4,
-	kEobBaseMenuStringsDefeat,
-	kEobBaseMenuStringsTransfer,
-	kEobBaseMenuStringsSpec,
-	kEobBaseMenuStringsSpellNo,
-	kEobBaseMenuYesNoStrings,
-
-	kEobBaseSpellLevelsMage,
-	kEobBaseSpellLevelsCleric,
-	kEobBaseNumSpellsCleric,
-	kEobBaseNumSpellsWisAdj,
-	kEobBaseNumSpellsPal,
-	kEobBaseNumSpellsMage,
-
-	kEobBaseCharGuiStringsHp,
-	kEobBaseCharGuiStringsWp2,
-	kEobBaseCharGuiStringsWr,
-	kEobBaseCharGuiStringsSt2,
-	kEobBaseCharGuiStringsIn,
-
-	kEobBaseCharStatusStrings7,
-	kEobBaseCharStatusStrings82,
-	kEobBaseCharStatusStrings9,
-	kEobBaseCharStatusStrings12,
-	kEobBaseCharStatusStrings132,
-
-	kEobBaseLevelGainStrings,
-	kEobBaseExperienceTable0,
-	kEobBaseExperienceTable1,
-	kEobBaseExperienceTable2,
-	kEobBaseExperienceTable3,
-	kEobBaseExperienceTable4,
-
-	kEobBaseBookNumbers,
-	kEobBaseMageSpellsList,
-	kEobBaseClericSpellsList,
-	kEobBaseSpellNames,
-	kEobBaseMagicStrings1,
-	kEobBaseMagicStrings2,
-	kEobBaseMagicStrings3,
-	kEobBaseMagicStrings4,
-	kEobBaseMagicStrings6,
-	kEobBaseMagicStrings7,
-	kEobBaseMagicStrings8,
-
-	kEobBaseExpObjectTlMode,
-	kEobBaseExpObjectTblIndex,
-	kEobBaseExpObjectShpStart,
-	kEobBaseExpObjectTbl1,
-	kEobBaseExpObjectTbl2,
-	kEobBaseExpObjectTbl3,
-	kEobBaseExpObjectY,
-
-	kEobBaseSparkDefSteps,
-	kEobBaseSparkDefSubSteps,
-	kEobBaseSparkDefShift,
-	kEobBaseSparkDefAdd,
-	kEobBaseSparkDefX,
-	kEobBaseSparkDefY,
-	kEobBaseSparkOfFlags1,
-	kEobBaseSparkOfFlags2,
-	kEobBaseSparkOfShift,
-	kEobBaseSparkOfX,
-	kEobBaseSparkOfY,
-
-	kEobBaseSpellProperties,
-	kEobBaseMagicFlightProps,
-	kEobBaseTurnUndeadEffect,
-	kEobBaseBurningHandsDest,
-	kEobBaseConeOfColdDest1,
-	kEobBaseConeOfColdDest2,
-	kEobBaseConeOfColdDest3,
-	kEobBaseConeOfColdDest4,
-	kEobBaseConeOfColdGfxTbl,
-
-	kLolEobCommonDscDoorShapeIndex,
-	kEobBaseWllFlagPreset,
-	kEobBaseDscShapeCoords,
-
-	kEobBaseDscDoorScaleOffs,
-	kEobBaseDscDoorScaleMult1,
-	kEobBaseDscDoorScaleMult2,
-	kEobBaseDscDoorScaleMult3,
-	kEobBaseDscDoorType5Offs,
-	kEobBaseDscDoorY1,
-	kLolEobCommonDscDoorY2,
-
-	kEobBaseDscItemPosIndex,
-	kEobBaseDscItemShpX,
-	kEobBaseDscItemPosUnk,
-	kEobBaseDscItemTileIndex,
-	kEobBaseDscItemShapeMap,
-	kEobBaseDscTelptrShpCoords,
-
-	kEobBasePortalSeqData,
-	kEobBaseManDef,
-	kEobBaseManWord,
-	kEobBaseManPrompt,
-
-	kEobBaseDscMonsterFrmOffsTbl1,
-	kEobBaseDscMonsterFrmOffsTbl2,
-
-	kEobBaseInvSlotX,
-	kEobBaseInvSlotY,
-	kEobBaseSlotValidationFlags,
-
-	kEobBaseProjectileWeaponTypes,
-	kEobBaseWandTypes,
-
-	kEobBaseDrawObjPosIndex,
-	kEobBaseFlightObjFlipIndex,
-	kEobBaseFlightObjShpMap,
-	kEobBaseFlightObjSclIndex,
-
-	kEob2MainMenuStrings,
-	kEob2TransferConvertTable,
-	kEob2TransferExpTable,
-
-	kEob2IntroStrings,
-	kEob2IntroCPSFiles,
-	kEob2IntroSeqData00,
- 	kEob2IntroSeqData01,
- 	kEob2IntroSeqData02,
- 	kEob2IntroSeqData03,
- 	kEob2IntroSeqData04,
- 	kEob2IntroSeqData05,
- 	kEob2IntroSeqData06,
- 	kEob2IntroSeqData07,
- 	kEob2IntroSeqData08,
- 	kEob2IntroSeqData09,
- 	kEob2IntroSeqData10,
- 	kEob2IntroSeqData11,
- 	kEob2IntroSeqData12,
- 	kEob2IntroSeqData13,
- 	kEob2IntroSeqData14,
- 	kEob2IntroSeqData15,
- 	kEob2IntroSeqData16,
- 	kEob2IntroSeqData17,
- 	kEob2IntroSeqData18,
- 	kEob2IntroSeqData19,
- 	kEob2IntroSeqData20,
- 	kEob2IntroSeqData21,
- 	kEob2IntroSeqData22,
- 	kEob2IntroSeqData23,
- 	kEob2IntroSeqData24,
- 	kEob2IntroSeqData25,
- 	kEob2IntroSeqData26,
- 	kEob2IntroSeqData27,
- 	kEob2IntroSeqData28,
- 	kEob2IntroSeqData29,
- 	kEob2IntroSeqData30,
- 	kEob2IntroSeqData31,
- 	kEob2IntroSeqData32,
- 	kEob2IntroSeqData33,
- 	kEob2IntroSeqData34,
- 	kEob2IntroSeqData35,
- 	kEob2IntroSeqData36,
- 	kEob2IntroSeqData37,
- 	kEob2IntroSeqData38,
- 	kEob2IntroSeqData39,
- 	kEob2IntroSeqData40,
- 	kEob2IntroSeqData41,
- 	kEob2IntroSeqData42,
- 	kEob2IntroSeqData43,
-
-	kEob2IntroShapes00,
- 	kEob2IntroShapes01,
- 	kEob2IntroShapes04,
- 	kEob2IntroShapes07,
-
-	kEob2FinaleStrings,
-	kEob2CreditsData,
-	kEob2FinaleCPSFiles,
-	kEob2FinaleSeqData00,
- 	kEob2FinaleSeqData01,
- 	kEob2FinaleSeqData02,
- 	kEob2FinaleSeqData03,
- 	kEob2FinaleSeqData04,
- 	kEob2FinaleSeqData05,
- 	kEob2FinaleSeqData06,
- 	kEob2FinaleSeqData07,
- 	kEob2FinaleSeqData08,
- 	kEob2FinaleSeqData09,
- 	kEob2FinaleSeqData10,
- 	kEob2FinaleSeqData11,
- 	kEob2FinaleSeqData12,
- 	kEob2FinaleSeqData13,
- 	kEob2FinaleSeqData14,
- 	kEob2FinaleSeqData15,
- 	kEob2FinaleSeqData16,
- 	kEob2FinaleSeqData17,
- 	kEob2FinaleSeqData18,
- 	kEob2FinaleSeqData19,
- 	kEob2FinaleSeqData20,
-	kEob2FinaleShapes00,
- 	kEob2FinaleShapes03,
- 	kEob2FinaleShapes07,
- 	kEob2FinaleShapes09,
- 	kEob2FinaleShapes10,
-
-	kEob2NpcShapeData,
-	kEobBaseClassModifierFlags,
-
-	kEobBaseMonsterStepTable02,
-	kEobBaseMonsterStepTable1,
-	kEobBaseMonsterStepTable2,
-	kEobBaseMonsterStepTable3,
-	kEobBaseMonsterCloseAttPosTable1,
-	kEobBaseMonsterCloseAttPosTable22,
-	kEobBaseMonsterCloseAttUnkTable,
-	kEobBaseMonsterCloseAttChkTable1,
-	kEobBaseMonsterCloseAttChkTable2,
-	kEobBaseMonsterCloseAttDstTable1,
-	kEobBaseMonsterCloseAttDstTable2,
+	kEoBBaseChargenStrings1,
+	kEoBBaseChargenStrings2,
+	kEoBBaseChargenStartLevels,
+	kEoBBaseChargenStatStrings,
+	kEoBBaseChargenRaceSexStrings,
+	kEoBBaseChargenClassStrings,
+	kEoBBaseChargenAlignmentStrings,
+	kEoBBaseChargenEnterGameStrings,
+	kEoBBaseChargenClassMinStats,
+	kEoBBaseChargenRaceMinStats,
+	kEoBBaseChargenRaceMaxStats,
+
+	kEoBBaseSaveThrowTable1,
+	kEoBBaseSaveThrowTable2,
+	kEoBBaseSaveThrowTable3,
+	kEoBBaseSaveThrowTable4,
+	kEoBBaseSaveThrwLvlIndex,
+	kEoBBaseSaveThrwModDiv,
+	kEoBBaseSaveThrwModExt,
+
+	kEoBBasePryDoorStrings,
+	kEoBBaseWarningStrings,
+
+	kEoBBaseItemSuffixStringsRings,
+	kEoBBaseItemSuffixStringsPotions,
+	kEoBBaseItemSuffixStringsWands,
+
+	kEoBBaseRipItemStrings,
+	kEoBBaseCursedString,
+	kEoBBaseEnchantedString,
+	kEoBBaseMagicObjectStrings,
+	kEoBBaseMagicObject5String,
+	kEoBBasePatternSuffix,
+	kEoBBasePatternGrFix1,
+	kEoBBasePatternGrFix2,
+	kEoBBaseValidateArmorString,
+	kEoBBaseValidateCursedString,
+	kEoBBaseValidateNoDropString,
+	kEoBBasePotionStrings,
+	kEoBBaseWandString,
+	kEoBBaseItemMisuseStrings,
+
+	kEoBBaseTakenStrings,
+	kEoBBasePotionEffectStrings,
+
+	kEoBBaseYesNoStrings,
+	kRpgCommonMoreStrings,
+	kEoBBaseNpcMaxStrings,
+	kEoBBaseOkStrings,
+	kEoBBaseNpcJoinStrings,
+	kEoBBaseCancelStrings,
+	kEoBBaseAbortStrings,
+
+	kEoBBaseMenuStringsMain,
+	kEoBBaseMenuStringsSaveLoad,
+	kEoBBaseMenuStringsOnOff,
+	kEoBBaseMenuStringsSpells,
+	kEoBBaseMenuStringsRest,
+	kEoBBaseMenuStringsDrop,
+	kEoBBaseMenuStringsExit,
+	kEoBBaseMenuStringsStarve,
+	kEoBBaseMenuStringsScribe,
+	kEoBBaseMenuStringsDrop2,
+	kEoBBaseMenuStringsHead,
+	kEoBBaseMenuStringsPoison,
+	kEoBBaseMenuStringsMgc,
+	kEoBBaseMenuStringsPrefs,
+	kEoBBaseMenuStringsRest2,
+	kEoBBaseMenuStringsRest3,
+	kEoBBaseMenuStringsRest4,
+	kEoBBaseMenuStringsDefeat,
+	kEoBBaseMenuStringsTransfer,
+	kEoBBaseMenuStringsSpec,
+	kEoBBaseMenuStringsSpellNo,
+	kEoBBaseMenuYesNoStrings,
+
+	kEoBBaseSpellLevelsMage,
+	kEoBBaseSpellLevelsCleric,
+	kEoBBaseNumSpellsCleric,
+	kEoBBaseNumSpellsWisAdj,
+	kEoBBaseNumSpellsPal,
+	kEoBBaseNumSpellsMage,
+
+	kEoBBaseCharGuiStringsHp,
+	kEoBBaseCharGuiStringsWp2,
+	kEoBBaseCharGuiStringsWr,
+	kEoBBaseCharGuiStringsSt2,
+	kEoBBaseCharGuiStringsIn,
+
+	kEoBBaseCharStatusStrings7,
+	kEoBBaseCharStatusStrings82,
+	kEoBBaseCharStatusStrings9,
+	kEoBBaseCharStatusStrings12,
+	kEoBBaseCharStatusStrings132,
+
+	kEoBBaseLevelGainStrings,
+	kEoBBaseExperienceTable0,
+	kEoBBaseExperienceTable1,
+	kEoBBaseExperienceTable2,
+	kEoBBaseExperienceTable3,
+	kEoBBaseExperienceTable4,
+
+	kEoBBaseBookNumbers,
+	kEoBBaseMageSpellsList,
+	kEoBBaseClericSpellsList,
+	kEoBBaseSpellNames,
+	kEoBBaseMagicStrings1,
+	kEoBBaseMagicStrings2,
+	kEoBBaseMagicStrings3,
+	kEoBBaseMagicStrings4,
+	kEoBBaseMagicStrings6,
+	kEoBBaseMagicStrings7,
+	kEoBBaseMagicStrings8,
+
+	kEoBBaseExpObjectTlMode,
+	kEoBBaseExpObjectTblIndex,
+	kEoBBaseExpObjectShpStart,
+	kEoBBaseExpObjectTbl1,
+	kEoBBaseExpObjectTbl2,
+	kEoBBaseExpObjectTbl3,
+	kEoBBaseExpObjectY,
+
+	kEoBBaseSparkDefSteps,
+	kEoBBaseSparkDefSubSteps,
+	kEoBBaseSparkDefShift,
+	kEoBBaseSparkDefAdd,
+	kEoBBaseSparkDefX,
+	kEoBBaseSparkDefY,
+	kEoBBaseSparkOfFlags1,
+	kEoBBaseSparkOfFlags2,
+	kEoBBaseSparkOfShift,
+	kEoBBaseSparkOfX,
+	kEoBBaseSparkOfY,
+
+	kEoBBaseSpellProperties,
+	kEoBBaseMagicFlightProps,
+	kEoBBaseTurnUndeadEffect,
+	kEoBBaseBurningHandsDest,
+	kEoBBaseConeOfColdDest1,
+	kEoBBaseConeOfColdDest2,
+	kEoBBaseConeOfColdDest3,
+	kEoBBaseConeOfColdDest4,
+	kEoBBaseConeOfColdGfxTbl,
+
+	kRpgCommonDscDoorShapeIndex,
+	kEoBBaseWllFlagPreset,
+	kEoBBaseDscShapeCoords,
+
+	kEoBBaseDscDoorScaleOffs,
+	kEoBBaseDscDoorScaleMult1,
+	kEoBBaseDscDoorScaleMult2,
+	kEoBBaseDscDoorScaleMult3,
+	kEoBBaseDscDoorType5Offs,
+	kEoBBaseDscDoorY1,
+	kRpgCommonDscDoorY2,
+
+	kEoBBaseDscItemPosIndex,
+	kEoBBaseDscItemShpX,
+	kEoBBaseDscItemPosUnk,
+	kEoBBaseDscItemTileIndex,
+	kEoBBaseDscItemShapeMap,
+	kEoBBaseDscTelptrShpCoords,
+
+	kEoBBasePortalSeqData,
+	kEoBBaseManDef,
+	kEoBBaseManWord,
+	kEoBBaseManPrompt,
+
+	kEoBBaseDscMonsterFrmOffsTbl1,
+	kEoBBaseDscMonsterFrmOffsTbl2,
+
+	kEoBBaseInvSlotX,
+	kEoBBaseInvSlotY,
+	kEoBBaseSlotValidationFlags,
+
+	kEoBBaseProjectileWeaponTypes,
+	kEoBBaseWandTypes,
+
+	kEoBBaseDrawObjPosIndex,
+	kEoBBaseFlightObjFlipIndex,
+	kEoBBaseFlightObjShpMap,
+	kEoBBaseFlightObjSclIndex,
+
+	kEoB2MainMenuStrings,
+	kEoB2TransferConvertTable,
+	kEoB2TransferExpTable,
+
+	kEoB2IntroStrings,
+	kEoB2IntroCPSFiles,
+	kEoB2IntroSeqData00,
+ 	kEoB2IntroSeqData01,
+ 	kEoB2IntroSeqData02,
+ 	kEoB2IntroSeqData03,
+ 	kEoB2IntroSeqData04,
+ 	kEoB2IntroSeqData05,
+ 	kEoB2IntroSeqData06,
+ 	kEoB2IntroSeqData07,
+ 	kEoB2IntroSeqData08,
+ 	kEoB2IntroSeqData09,
+ 	kEoB2IntroSeqData10,
+ 	kEoB2IntroSeqData11,
+ 	kEoB2IntroSeqData12,
+ 	kEoB2IntroSeqData13,
+ 	kEoB2IntroSeqData14,
+ 	kEoB2IntroSeqData15,
+ 	kEoB2IntroSeqData16,
+ 	kEoB2IntroSeqData17,
+ 	kEoB2IntroSeqData18,
+ 	kEoB2IntroSeqData19,
+ 	kEoB2IntroSeqData20,
+ 	kEoB2IntroSeqData21,
+ 	kEoB2IntroSeqData22,
+ 	kEoB2IntroSeqData23,
+ 	kEoB2IntroSeqData24,
+ 	kEoB2IntroSeqData25,
+ 	kEoB2IntroSeqData26,
+ 	kEoB2IntroSeqData27,
+ 	kEoB2IntroSeqData28,
+ 	kEoB2IntroSeqData29,
+ 	kEoB2IntroSeqData30,
+ 	kEoB2IntroSeqData31,
+ 	kEoB2IntroSeqData32,
+ 	kEoB2IntroSeqData33,
+ 	kEoB2IntroSeqData34,
+ 	kEoB2IntroSeqData35,
+ 	kEoB2IntroSeqData36,
+ 	kEoB2IntroSeqData37,
+ 	kEoB2IntroSeqData38,
+ 	kEoB2IntroSeqData39,
+ 	kEoB2IntroSeqData40,
+ 	kEoB2IntroSeqData41,
+ 	kEoB2IntroSeqData42,
+ 	kEoB2IntroSeqData43,
+
+	kEoB2IntroShapes00,
+ 	kEoB2IntroShapes01,
+ 	kEoB2IntroShapes04,
+ 	kEoB2IntroShapes07,
+
+	kEoB2FinaleStrings,
+	kEoB2CreditsData,
+	kEoB2FinaleCPSFiles,
+	kEoB2FinaleSeqData00,
+ 	kEoB2FinaleSeqData01,
+ 	kEoB2FinaleSeqData02,
+ 	kEoB2FinaleSeqData03,
+ 	kEoB2FinaleSeqData04,
+ 	kEoB2FinaleSeqData05,
+ 	kEoB2FinaleSeqData06,
+ 	kEoB2FinaleSeqData07,
+ 	kEoB2FinaleSeqData08,
+ 	kEoB2FinaleSeqData09,
+ 	kEoB2FinaleSeqData10,
+ 	kEoB2FinaleSeqData11,
+ 	kEoB2FinaleSeqData12,
+ 	kEoB2FinaleSeqData13,
+ 	kEoB2FinaleSeqData14,
+ 	kEoB2FinaleSeqData15,
+ 	kEoB2FinaleSeqData16,
+ 	kEoB2FinaleSeqData17,
+ 	kEoB2FinaleSeqData18,
+ 	kEoB2FinaleSeqData19,
+ 	kEoB2FinaleSeqData20,
+	kEoB2FinaleShapes00,
+ 	kEoB2FinaleShapes03,
+ 	kEoB2FinaleShapes07,
+ 	kEoB2FinaleShapes09,
+ 	kEoB2FinaleShapes10,
+
+	kEoB2NpcShapeData,
+	kEoBBaseClassModifierFlags,
+
+	kEoBBaseMonsterStepTable02,
+	kEoBBaseMonsterStepTable1,
+	kEoBBaseMonsterStepTable2,
+	kEoBBaseMonsterStepTable3,
+	kEoBBaseMonsterCloseAttPosTable1,
+	kEoBBaseMonsterCloseAttPosTable22,
+	kEoBBaseMonsterCloseAttUnkTable,
+	kEoBBaseMonsterCloseAttChkTable1,
+	kEoBBaseMonsterCloseAttChkTable2,
+	kEoBBaseMonsterCloseAttDstTable1,
+	kEoBBaseMonsterCloseAttDstTable2,
 	
-	kEobBaseMonsterProximityTable,
-	kEobBaseFindBlockMonstersTable,
-	kEobBaseMonsterDirChangeTable,
-	kEobBaseMonsterDistAttStrings,
-	kEobBaseEncodeMonsterDefs,
-	kEobBaseNpcPresets,
-	kEob2Npc1Strings,
-	kEob2Npc2Strings,
-	kEob2MonsterDustStrings,
-	kEob2DreamSteps,
-	kEob2KheldranStrings,
-	kEob2HornStrings,
-	kEob2HornSounds,
-	kEob2WallOfForceDsX,
-	kEob2WallOfForceDsY,
-	kEob2WallOfForceNumW,
-	kEob2WallOfForceNumH,
-	kEob2WallOfForceShpId,
-
-	kLolEobCommonDscShapeIndex,
-	kLolEobCommonDscX,
-	kLolEobCommonDscTileIndex,
-	kLolEobCommonDscUnk2,
-	kLolEobCommonDscDimData1,
-	kLolEobCommonDscDimData2,
-	kLolEobCommonDscBlockMap,
-	kLolEobCommonDscDimMap,	
-	kLolEobCommonDscBlockIndex,
+	kEoBBaseMonsterProximityTable,
+	kEoBBaseFindBlockMonstersTable,
+	kEoBBaseMonsterDirChangeTable,
+	kEoBBaseMonsterDistAttStrings,
+	kEoBBaseEncodeMonsterDefs,
+	kEoBBaseNpcPresets,
+	kEoB2Npc1Strings,
+	kEoB2Npc2Strings,
+	kEoB2MonsterDustStrings,
+	kEoB2DreamSteps,
+	kEoB2KheldranStrings,
+	kEoB2HornStrings,
+	kEoB2HornSounds,
+	kEoB2WallOfForceDsX,
+	kEoB2WallOfForceDsY,
+	kEoB2WallOfForceNumW,
+	kEoB2WallOfForceNumH,
+	kEoB2WallOfForceShpId,
+
+	kRpgCommonDscShapeIndex,
+	kRpgCommonDscX,
+	kRpgCommonDscTileIndex,
+	kRpgCommonDscUnk2,
+	kRpgCommonDscDimData1,
+	kRpgCommonDscDimData2,
+	kRpgCommonDscBlockMap,
+	kRpgCommonDscDimMap,	
+	kRpgCommonDscBlockIndex,
 
 	-1
 };
@@ -1652,18 +1652,18 @@ const GameNeed gameNeedTable[] = {
 
 	{ kKyra2, kPlatformPC, kDemoVersion, kyra2DemoNeed },
 
-	{ kLol, kPlatformPC, kDemoVersion, lolDemoNeed },
+	{ kLoL, kPlatformPC, kDemoVersion, lolDemoNeed },
 
 	{ kKyra3, kPlatformPC, kTalkieVersion, kyra3Need },
 
-	{ kLol, kPlatformPC, kNoSpecial, lolFloppyNeed },
-	{ kLol, kPlatformPC98, kNoSpecial, lolPC98Need },
+	{ kLoL, kPlatformPC, kNoSpecial, lolFloppyNeed },
+	{ kLoL, kPlatformPC98, kNoSpecial, lolPC98Need },
 
-	{ kLol, kPlatformPC, kTalkieVersion, lolCDNeed },
+	{ kLoL, kPlatformPC, kTalkieVersion, lolCDNeed },
 
-	{ kEob1, kPlatformPC, kNoSpecial, eob1FloppyNeed },
+	{ kEoB1, kPlatformPC, kNoSpecial, eob1FloppyNeed },
 
-	{ kEob2, kPlatformPC, kNoSpecial, eob2FloppyNeed },
+	{ kEoB2, kPlatformPC, kNoSpecial, eob2FloppyNeed },
 
 	{ -1, -1, -1, 0 }
 };
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index c854780..a606cc4 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -1331,112 +1331,112 @@ const ExtractEntrySearchData k3ItemStringMapProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseChargenStrings1Provider[] = {
+const ExtractEntrySearchData kEoBBaseChargenStrings1Provider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x000000CA, 0x00003BC8, { { 0x27, 0xEA, 0xE3, 0x0D, 0x55, 0xB3, 0x69, 0x3E, 0xC2, 0x66, 0x58, 0x64, 0xAA, 0xC2, 0x80, 0x58 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x000000C3, 0x000038F6, { { 0x20, 0x68, 0xAB, 0xD4, 0xBF, 0x49, 0x04, 0xC0, 0x91, 0xB4, 0x71, 0xB0, 0xB6, 0xC9, 0x11, 0xF0 } } } }, // EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x000000C7, 0x00003ADB, { { 0x0D, 0x03, 0x7A, 0xE6, 0x7D, 0x41, 0x89, 0x49, 0x0C, 0xB6, 0xD0, 0x4F, 0xEA, 0x1E, 0x54, 0xFF } } } }, // EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseChargenStrings2Provider[] = {
+const ExtractEntrySearchData kEoBBaseChargenStrings2Provider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000004B, 0x000011AE, { { 0x28, 0x98, 0x4C, 0xA3, 0x98, 0xB0, 0xA2, 0x17, 0x9C, 0x80, 0x4F, 0x3F, 0x58, 0x3B, 0x2C, 0xFB } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000004E, 0x0000129D, { { 0xED, 0xF3, 0x36, 0x16, 0xE2, 0x1B, 0x32, 0x95, 0xFE, 0xE8, 0x3E, 0x7D, 0xE6, 0x32, 0x34, 0xD4 } } } }, // EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x0000004A, 0x00001267, { { 0xD6, 0xE2, 0x27, 0x6A, 0x6F, 0x7E, 0xB4, 0xCE, 0xA8, 0xE9, 0x79, 0x31, 0x5C, 0x13, 0xA1, 0x8F } } } }, // EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseChargenStartLevelsProvider[] = {
+const ExtractEntrySearchData kEoBBaseChargenStartLevelsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000003C, 0x00000054, { { 0xAB, 0x68, 0x74, 0x3E, 0x0D, 0x45, 0xA3, 0x50, 0xA7, 0x72, 0x6A, 0xDF, 0x9C, 0x23, 0x98, 0x74 } } } },	// EOB 1
 	{ UNK_LANG, kPlatformUnknown, { 0x0000003C, 0x000000B1, { { 0xFD, 0x3F, 0x6B, 0xB5, 0xE4, 0xEE, 0x32, 0x3B, 0xBD, 0x72, 0x37, 0x88, 0x52, 0x84, 0xBD, 0xC6 } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseChargenStatStringsProvider[] = {
+const ExtractEntrySearchData kEoBBaseChargenStatStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000055, 0x000015D6, { { 0xB8, 0x29, 0x4B, 0xA4, 0x4F, 0x45, 0x16, 0x1A, 0x07, 0x28, 0x14, 0x86, 0x1B, 0xDF, 0xAC, 0xDF } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000056, 0x000015F9, { { 0xBB, 0x5A, 0x7D, 0xCF, 0xC3, 0x90, 0x9A, 0xB3, 0x73, 0xB2, 0x4D, 0x46, 0xB8, 0x89, 0x7D, 0xAE } } } }, // EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x00000053, 0x0000159A, { { 0x1D, 0xA6, 0x84, 0xDB, 0xC5, 0x81, 0xC7, 0xF0, 0x1C, 0xA4, 0xE3, 0x10, 0x4F, 0x8A, 0xF3, 0xCE } } } }, // EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseChargenRaceSexStringsProvider[] = {
+const ExtractEntrySearchData kEoBBaseChargenRaceSexStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000098, 0x00002572, { { 0x8D, 0xF9, 0xDE, 0x92, 0xFC, 0xA8, 0xFC, 0xE9, 0x0A, 0x98, 0x6D, 0xA4, 0x6F, 0x21, 0xCD, 0xF4 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x000000AA, 0x00002A1E, { { 0x8E, 0xAF, 0x4B, 0x20, 0xEA, 0xFE, 0x71, 0x8E, 0x8B, 0x4B, 0x46, 0x62, 0x91, 0x48, 0x08, 0xAF } } } }, // EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x00000098, 0x00002502, { { 0xA4, 0x8B, 0x20, 0xF5, 0x97, 0xFE, 0x34, 0x6D, 0x9F, 0xF0, 0xA8, 0xE9, 0xE8, 0xFA, 0x23, 0x9B } } } }, // EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseChargenClassStringsProvider[] = {
+const ExtractEntrySearchData kEoBBaseChargenClassStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x000000D5, 0x000035A7, { { 0xAF, 0x89, 0x9A, 0x11, 0x9A, 0x8D, 0x39, 0x6F, 0x26, 0x41, 0x4E, 0x20, 0xAD, 0x91, 0xC5, 0xDA } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x000000FA, 0x00003FD8, { { 0xBD, 0x78, 0xF7, 0xEC, 0x9D, 0x9A, 0x3A, 0x22, 0xAB, 0xD9, 0x10, 0xAD, 0x8E, 0x1D, 0x4D, 0xDE } } } }, // EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x000000E4, 0x00003BE5, { { 0xDE, 0x1B, 0x25, 0x4F, 0xE6, 0xD0, 0xB5, 0x95, 0xD0, 0xA6, 0x69, 0xE6, 0x53, 0xB8, 0x20, 0x1E } } } }, // EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseChargenAlignmentStringsProvider[] = {
+const ExtractEntrySearchData kEoBBaseChargenAlignmentStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000078, 0x00001F44, { { 0xBB, 0x52, 0x3C, 0xA6, 0x79, 0x87, 0xDC, 0xB8, 0x21, 0x7A, 0xA0, 0x17, 0x45, 0xEA, 0xF2, 0x50 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000008A, 0x00002423, { { 0xA3, 0x36, 0x0D, 0x64, 0x33, 0xFD, 0x54, 0xA5, 0xA9, 0xD7, 0xFA, 0x34, 0x39, 0xAD, 0x6A, 0x98 } } } }, // EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x0000007F, 0x000021F8, { { 0xBD, 0xB2, 0x06, 0xF9, 0xC9, 0x36, 0x5D, 0x91, 0x43, 0x08, 0x3A, 0x2C, 0x5F, 0x1C, 0xF3, 0x9C } } } }, // EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseChargenEnterGameStringsProvider[] = {
+const ExtractEntrySearchData kEoBBaseChargenEnterGameStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000020, 0x00000A0E, { { 0x98, 0x7F, 0x2C, 0x2E, 0xBB, 0x5E, 0xAA, 0xD0, 0x72, 0xF5, 0xBC, 0x4A, 0x34, 0x5B, 0xB4, 0xF5 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000021, 0x00000AB6, { { 0x02, 0x7F, 0x19, 0x5A, 0xA9, 0xB7, 0x8C, 0xE2, 0xF7, 0x35, 0xB0, 0xD8, 0xA8, 0x0C, 0x24, 0x44 } } } }, // EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x0000001E, 0x00000925, { { 0xDA, 0x83, 0x00, 0xD2, 0x94, 0xF0, 0xD8, 0xFC, 0x3D, 0xA8, 0xD2, 0x4E, 0xF2, 0xD7, 0x2B, 0x7E } } } }, // EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseChargenClassMinStatsProvider[] = {
+const ExtractEntrySearchData kEoBBaseChargenClassMinStatsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x000000B4, 0x00000165, { { 0x83, 0x5E, 0x91, 0x10, 0x4D, 0x75, 0x6B, 0xF9, 0x45, 0x1B, 0x65, 0x13, 0x37, 0x3E, 0xC0, 0xAE } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseChargenRaceMinStatsProvider[] = {
+const ExtractEntrySearchData kEoBBaseChargenRaceMinStatsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000048, 0x000000B2, { { 0x08, 0xF0, 0x8F, 0x22, 0x9D, 0xD8, 0xBE, 0x52, 0x70, 0x7C, 0xCA, 0x8D, 0xB2, 0xF5, 0xC6, 0xB8 } } } },	
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseChargenRaceMaxStatsProvider[] = {
+const ExtractEntrySearchData kEoBBaseChargenRaceMaxStatsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000048, 0x00000479, { { 0xBD, 0xA0, 0x8C, 0xC2, 0x05, 0xCA, 0x0D, 0x4B, 0x82, 0x9B, 0x3D, 0xB5, 0x4B, 0xDB, 0xD2, 0xC1 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSaveThrowTable1Provider[] = {
+const ExtractEntrySearchData kEoBBaseSaveThrowTable1Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000032, 0x00000214, { { 0x3D, 0x89, 0x30, 0x0A, 0x5C, 0x4A, 0x0F, 0xC3, 0xC7, 0x6B, 0x72, 0x7C, 0x12, 0x51, 0x8D, 0x8E } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSaveThrowTable2Provider[] = {
+const ExtractEntrySearchData kEoBBaseSaveThrowTable2Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000019, 0x000000E7, { { 0xF4, 0x0D, 0xDF, 0xA3, 0x23, 0x71, 0x76, 0x2A, 0xC5, 0x6F, 0xF1, 0x59, 0x5F, 0x45, 0x73, 0x05 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSaveThrowTable3Provider[] = {
+const ExtractEntrySearchData kEoBBaseSaveThrowTable3Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000023, 0x00000155, { { 0x42, 0x98, 0x84, 0x00, 0x70, 0x8A, 0x7B, 0x26, 0xC0, 0x96, 0xA3, 0x28, 0x41, 0x36, 0x4B, 0x21 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSaveThrowTable4Provider[] = {
+const ExtractEntrySearchData kEoBBaseSaveThrowTable4Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000001E, 0x0000013B, { { 0xAB, 0x84, 0x2B, 0x0A, 0xC2, 0x46, 0xFF, 0x83, 0x03, 0xF8, 0x3F, 0x32, 0x53, 0xA2, 0x95, 0x65 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSaveThrwLvlIndexProvider[] = {
+const ExtractEntrySearchData kEoBBaseSaveThrwLvlIndexProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000006, 0x00000070, { { 0x57, 0x48, 0x5F, 0x75, 0x79, 0xD4, 0xAA, 0x7D, 0xB7, 0xEB, 0x19, 0x9F, 0xCF, 0x99, 0x29, 0x29 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSaveThrwModDivProvider[] = {
+const ExtractEntrySearchData kEoBBaseSaveThrwModDivProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000006, 0x00000012, { { 0x50, 0x29, 0x51, 0x65, 0x0B, 0xF1, 0xCC, 0xDA, 0x2C, 0xA4, 0x7E, 0xEE, 0x20, 0xB0, 0x29, 0xB1 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSaveThrwModExtProvider[] = {
+const ExtractEntrySearchData kEoBBaseSaveThrwModExtProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000006, 0x00000030, { { 0x07, 0x7D, 0x61, 0x1C, 0x95, 0xEC, 0x9A, 0xCE, 0xA1, 0x29, 0x83, 0x2F, 0xCA, 0x95, 0x95, 0xF5 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBasePryDoorStringsProvider[] = {
+const ExtractEntrySearchData kEoBBasePryDoorStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x000000E8, 0x00004D9F, { { 0xDE, 0x01, 0x69, 0x00, 0x0B, 0x32, 0xFA, 0x20, 0xB8, 0x11, 0xD6, 0xD9, 0xE2, 0xEA, 0xF5, 0xE8 } } } },	// EOB 1
 	{ EN_ANY, kPlatformUnknown, { 0x000000D2, 0x000043D2, { { 0x82, 0x3C, 0xF4, 0x4A, 0x87, 0x84, 0xFE, 0xF9, 0xBA, 0xC6, 0x67, 0x3A, 0x0D, 0x0F, 0x76, 0x78 } } } },	// EOB 2
 	{ DE_DEU, kPlatformUnknown, { 0x00000128, 0x0000657C, { { 0xA3, 0xC8, 0x48, 0xA7, 0x1F, 0x75, 0xDF, 0xB0, 0x37, 0xDA, 0x75, 0x2E, 0x9F, 0x4E, 0x45, 0xB0 } } } },	// EOB 1
@@ -1444,7 +1444,7 @@ const ExtractEntrySearchData kEobBasePryDoorStringsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseWarningStringsProvider[] = {
+const ExtractEntrySearchData kEoBBaseWarningStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000052, 0x00001A7B, { { 0x81, 0x7A, 0xDF, 0xD2, 0x4F, 0xA7, 0x92, 0xA7, 0x44, 0xE5, 0x22, 0x73, 0xF6, 0xB3, 0x29, 0x5C } } } },	// EOB 1
 	{ EN_ANY, kPlatformUnknown, { 0x00000085, 0x00002B5C, { { 0xF1, 0xCE, 0x7C, 0x53, 0xEF, 0x5B, 0x59, 0x71, 0xA9, 0xEB, 0x00, 0xBA, 0xB7, 0x59, 0xC5, 0x2E } } } },	// EOB 2
 	{ DE_DEU, kPlatformUnknown, { 0x0000005F, 0x00001FD2, { { 0xBA, 0x85, 0x97, 0x63, 0x84, 0x80, 0x79, 0x44, 0x50, 0x99, 0x1A, 0x01, 0x37, 0x37, 0x0E, 0xD1 } } } },	// EOB 1
@@ -1452,21 +1452,21 @@ const ExtractEntrySearchData kEobBaseWarningStringsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseItemSuffixStringsRingsProvider[] = {
+const ExtractEntrySearchData kEoBBaseItemSuffixStringsRingsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000002B, 0x00000F7B, { { 0x8A, 0x27, 0x87, 0x81, 0x5F, 0x74, 0x27, 0xA9, 0x5E, 0x1B, 0xEE, 0xC0, 0xF7, 0x22, 0x8F, 0x57 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000022, 0x00000C02, { { 0x7D, 0x5F, 0x40, 0xEA, 0xAD, 0xDD, 0x1B, 0xA0, 0xA6, 0xE0, 0x57, 0x7D, 0x0D, 0x60, 0xF4, 0x2C } } } },	// EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x0000002E, 0x00000FF2, { { 0xE1, 0x50, 0xB7, 0xE2, 0xEF, 0xAD, 0x5B, 0x6D, 0x27, 0x35, 0x9C, 0xE7, 0x2D, 0xB2, 0x2E, 0xD0 } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseItemSuffixStringsPotionsProvider[] = {
+const ExtractEntrySearchData kEoBBaseItemSuffixStringsPotionsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000054, 0x00001DDB, { { 0xB6, 0x78, 0xD9, 0x09, 0x1D, 0x09, 0x63, 0xF8, 0x96, 0x74, 0xF0, 0x75, 0x23, 0xF5, 0xD4, 0xC4 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000064, 0x000024ED, { { 0x10, 0x5A, 0xB8, 0xCA, 0x0F, 0x0D, 0x44, 0x19, 0x9D, 0x3D, 0x76, 0x54, 0xA1, 0x69, 0x97, 0x8B } } } },	// EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x0000006F, 0x00002792, { { 0x1A, 0x71, 0x2B, 0xCC, 0xCA, 0xDA, 0xF6, 0xED, 0x5E, 0xF0, 0x24, 0x20, 0xD7, 0x2D, 0x18, 0x49 } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseItemSuffixStringsWandsProvider[] = {
+const ExtractEntrySearchData kEoBBaseItemSuffixStringsWandsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000003C, 0x000014EB, { { 0xB5, 0x38, 0x35, 0x57, 0xF2, 0xF8, 0x0E, 0xBA, 0x75, 0x03, 0x1C, 0xCD, 0x46, 0x7D, 0x03, 0x83 } } } },	// EOB 1
 	{ EN_ANY, kPlatformUnknown, { 0x0000004A, 0x000019B2, { { 0x44, 0x10, 0xE4, 0xAF, 0xAB, 0x19, 0x25, 0x87, 0x2B, 0x15, 0x1C, 0x4C, 0x03, 0x50, 0x41, 0xC4 } } } },	// EOB 2
 	{ DE_DEU, kPlatformUnknown, { 0x00000040, 0x000016B5, { { 0xEC, 0xF4, 0x71, 0xC1, 0x69, 0x5C, 0xF9, 0xC1, 0xED, 0xC1, 0xED, 0x0C, 0x25, 0x3E, 0x13, 0xB1 } } } },	// EOB 1
@@ -1474,14 +1474,14 @@ const ExtractEntrySearchData kEobBaseItemSuffixStringsWandsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseRipItemStringsProvider[] = {
+const ExtractEntrySearchData kEoBBaseRipItemStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000025, 0x00000AEA, { { 0x7A, 0x2D, 0x03, 0xA5, 0x94, 0xD1, 0xA2, 0x2C, 0x41, 0x1F, 0xEB, 0x5C, 0xFB, 0xB2, 0xC6, 0x9E } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000024, 0x00000B1B, { { 0xD0, 0x26, 0x19, 0x0B, 0xA5, 0x8A, 0x38, 0x73, 0x14, 0x25, 0x40, 0x5D, 0x24, 0xB8, 0x4E, 0xC5 } } } },	// EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x0000002E, 0x00000D38, { { 0xCE, 0xC5, 0x00, 0x63, 0xBB, 0xF0, 0xC4, 0x0D, 0x50, 0x2B, 0x82, 0x1C, 0xC0, 0xCD, 0xF1, 0xAF } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseCursedStringProvider[] = {
+const ExtractEntrySearchData kEoBBaseCursedStringProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000000D, 0x000003C7, { { 0x7F, 0x6B, 0x6A, 0xFE, 0x63, 0xF4, 0x17, 0xAF, 0xFD, 0x00, 0x31, 0x4A, 0x20, 0x9E, 0x8C, 0xEB } } } },	// EOB 1
 	{ EN_ANY, kPlatformUnknown, { 0x0000000D, 0x000003C7, { { 0x59, 0xD8, 0x84, 0x25, 0xE0, 0x06, 0x51, 0xA4, 0x70, 0xC5, 0x78, 0x22, 0xF0, 0x2D, 0xA0, 0x43 } } } },	// EOB 2
 	{ DE_DEU, kPlatformUnknown, { 0x00000010, 0x00000514, { { 0x97, 0x41, 0xA6, 0xAE, 0xF8, 0xA8, 0x3E, 0x85, 0xA8, 0x16, 0x01, 0x15, 0x0E, 0x46, 0x13, 0x45 } } } },	// EOB 1
@@ -1489,61 +1489,61 @@ const ExtractEntrySearchData kEobBaseCursedStringProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseEnchantedStringProvider[] = {
+const ExtractEntrySearchData kEoBBaseEnchantedStringProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000007, 0x0000016C, { { 0x98, 0x62, 0xD3, 0xA3, 0x11, 0xAE, 0x0A, 0xBA, 0x8F, 0xE8, 0x30, 0x0B, 0xDC, 0x12, 0x90, 0x3B } } } },	// EOB 1
 	{ UNK_LANG, kPlatformUnknown, { 0x00000007, 0x0000016C, { { 0x01, 0x91, 0xBD, 0x89, 0xAE, 0x0E, 0x71, 0xEE, 0xBE, 0x31, 0xD9, 0x55, 0x21, 0x61, 0x19, 0xAE } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMagicObjectStringsProvider[] = {
+const ExtractEntrySearchData kEoBBaseMagicObjectStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000002B, 0x00000E7D, { { 0x7E, 0x8F, 0x17, 0xEB, 0xE5, 0x5D, 0xEB, 0x9A, 0x84, 0xFF, 0x86, 0x6A, 0x01, 0x3E, 0x04, 0x84 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000003A, 0x000014E4, { { 0x3D, 0x34, 0x3C, 0xCA, 0xDC, 0xD1, 0xCF, 0x15, 0x69, 0x57, 0xC3, 0xB1, 0x58, 0xDF, 0xE9, 0x9D } } } },	// EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x0000002A, 0x00000EE4, { { 0x9C, 0x38, 0x4B, 0x9B, 0x67, 0x30, 0x4E, 0x88, 0xA9, 0xA2, 0xF8, 0x78, 0x8E, 0xC7, 0xC3, 0x86 } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMagicObject5StringProvider[] = {
+const ExtractEntrySearchData kEoBBaseMagicObject5StringProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000006, 0x000001FE, { { 0x74, 0x8D, 0xB9, 0x76, 0xD2, 0x2F, 0x60, 0xD2, 0x36, 0x45, 0x98, 0x4C, 0x0A, 0xE5, 0xE5, 0x0D } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000006, 0x00000204, { { 0xE4, 0xC1, 0xAD, 0x71, 0x87, 0x80, 0x9D, 0x97, 0x91, 0x80, 0x3F, 0x71, 0xD3, 0x62, 0x06, 0xD5 } } } }, // EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x00000007, 0x0000027A, { { 0x44, 0x47, 0x79, 0x46, 0x9B, 0xE5, 0xBD, 0x3C, 0xE8, 0x8D, 0xC6, 0xC5, 0x4E, 0x88, 0x13, 0xC0 } } } }, // EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBasePatternSuffixProvider[] = {
+const ExtractEntrySearchData kEoBBasePatternSuffixProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000009, 0x00000245, { { 0x67, 0x3F, 0x33, 0xA5, 0x3B, 0x5D, 0x2C, 0x9E, 0x15, 0x82, 0x04, 0xE2, 0xD7, 0x34, 0x42, 0x24 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000006, 0x0000015D, { { 0x33, 0xD6, 0x91, 0x2D, 0xED, 0xE1, 0x43, 0x42, 0x23, 0xB9, 0xE9, 0x3D, 0x48, 0x82, 0x92, 0x1E } } } },	// EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x00000008, 0x00000219, { { 0xCD, 0xDC, 0x7F, 0x8B, 0xBE, 0xD6, 0x05, 0x37, 0xDA, 0xDC, 0x11, 0xC3, 0x1E, 0x7A, 0xE7, 0x13 } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBasePatternGrFix1Provider[] = {
+const ExtractEntrySearchData kEoBBasePatternGrFix1Provider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000009, 0x00000245, { { 0x67, 0x3F, 0x33, 0xA5, 0x3B, 0x5D, 0x2C, 0x9E, 0x15, 0x82, 0x04, 0xE2, 0xD7, 0x34, 0x42, 0x24 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000006, 0x0000015D, { { 0x33, 0xD6, 0x91, 0x2D, 0xED, 0xE1, 0x43, 0x42, 0x23, 0xB9, 0xE9, 0x3D, 0x48, 0x82, 0x92, 0x1E } } } },	// EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x00000007, 0x0000018A, { { 0x02, 0x5C, 0x86, 0xD9, 0x62, 0x0C, 0x71, 0xB3, 0x77, 0x9C, 0x7B, 0xBC, 0x4D, 0x5B, 0xDB, 0xE7 } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBasePatternGrFix2Provider[] = {
+const ExtractEntrySearchData kEoBBasePatternGrFix2Provider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000009, 0x00000245, { { 0x67, 0x3F, 0x33, 0xA5, 0x3B, 0x5D, 0x2C, 0x9E, 0x15, 0x82, 0x04, 0xE2, 0xD7, 0x34, 0x42, 0x24 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000006, 0x0000015D, { { 0x33, 0xD6, 0x91, 0x2D, 0xED, 0xE1, 0x43, 0x42, 0x23, 0xB9, 0xE9, 0x3D, 0x48, 0x82, 0x92, 0x1E } } } },	// EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x00000006, 0x00000150, { { 0x48, 0xBE, 0xED, 0xD3, 0xA5, 0x2E, 0xCD, 0xE0, 0x34, 0xBA, 0xA6, 0x8D, 0x7D, 0x00, 0xA2, 0xFF } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseValidateArmorStringProvider[] = {
+const ExtractEntrySearchData kEoBBaseValidateArmorStringProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000023, 0x00000B78, { { 0xC2, 0x33, 0x6B, 0xB9, 0xE1, 0x5E, 0x88, 0x5E, 0x22, 0xF2, 0x97, 0x83, 0xF8, 0xC8, 0x8C, 0xAB } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000026, 0x00000D19, { { 0xAD, 0x19, 0xE2, 0xDE, 0x04, 0xF9, 0x8F, 0x92, 0xAC, 0x1A, 0x05, 0xEA, 0x7B, 0xB5, 0x9F, 0x09 } } } },	// EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x00000029, 0x00000E7A, { { 0xEC, 0xA8, 0x2E, 0x8D, 0xB1, 0xC8, 0x0F, 0xCD, 0x24, 0xBD, 0x4B, 0x39, 0x16, 0xC9, 0x53, 0x08 } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseValidateCursedStringProvider[] = {
+const ExtractEntrySearchData kEoBBaseValidateCursedStringProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000002E, 0x00000F35, { { 0xE7, 0x0E, 0xA1, 0xCE, 0xCC, 0x13, 0xBC, 0x4B, 0x2B, 0x19, 0xEB, 0xA4, 0x05, 0xCF, 0xCF, 0x65 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000037, 0x000012D8, { { 0x3C, 0x7F, 0x16, 0xCE, 0x40, 0x58, 0xF1, 0x3A, 0xAB, 0x4C, 0x37, 0x82, 0x32, 0x88, 0xA4, 0x2D } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseValidateNoDropStringProvider[] = {
+const ExtractEntrySearchData kEoBBaseValidateNoDropStringProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000001F, 0x00000A8F, { { 0x61, 0x99, 0x3E, 0x36, 0x49, 0x19, 0xB4, 0xE4, 0xBC, 0xFA, 0xB5, 0x71, 0x0E, 0xD6, 0x15, 0x3C } } } },	// EOB 1
 	{ EN_ANY, kPlatformUnknown, { 0x00000020, 0x00000AB6, { { 0xAA, 0x0E, 0x64, 0xD1, 0xA2, 0xA6, 0x62, 0x76, 0x51, 0xDF, 0x9E, 0x76, 0x85, 0x42, 0xE1, 0x4A } } } },	// EOB 2
 	{ DE_DEU, kPlatformUnknown, { 0x00000024, 0x00000C31, { { 0x10, 0xD9, 0x55, 0x69, 0xFE, 0x0A, 0x8C, 0xE5, 0xF7, 0x05, 0x5F, 0x09, 0x3B, 0xC9, 0x93, 0x38 } } } },	// EOB 1
@@ -1551,14 +1551,14 @@ const ExtractEntrySearchData kEobBaseValidateNoDropStringProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBasePotionStringsProvider[] = {
+const ExtractEntrySearchData kEoBBasePotionStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000017, 0x0000070E, { { 0xD9, 0xCB, 0x26, 0xB6, 0x6F, 0x17, 0x12, 0xB7, 0xB0, 0x95, 0x1B, 0x2A, 0xD8, 0x83, 0x0D, 0x2B } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000001E, 0x000009BD, { { 0xCA, 0xD0, 0x29, 0xB0, 0x7A, 0x2B, 0x0B, 0x69, 0xCA, 0xA4, 0xCA, 0x97, 0xCF, 0x8B, 0x03, 0xAD } } } },	// EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x0000001D, 0x00000964, { { 0x5D, 0xE2, 0xA5, 0x0D, 0x72, 0xE9, 0x8F, 0xC9, 0xFA, 0xF3, 0x41, 0x5A, 0x3F, 0x33, 0xAA, 0x15 } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseWandStringProvider[] = {
+const ExtractEntrySearchData kEoBBaseWandStringProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000035, 0x000011EC, { { 0x7C, 0x3D, 0xF1, 0x28, 0x0C, 0x23, 0xD3, 0x18, 0xEE, 0xAD, 0xA7, 0xF4, 0x58, 0xD7, 0x1C, 0x8E } } } },	// EOB 1
 	{ EN_ANY, kPlatformUnknown, { 0x00000029, 0x00000E47, { { 0xED, 0x2E, 0xD4, 0x4D, 0xDB, 0x90, 0x3F, 0xD0, 0xFB, 0x95, 0xB8, 0xF2, 0xCF, 0x06, 0x08, 0xAF } } } },	// EOB 2
 	{ DE_DEU, kPlatformUnknown, { 0x00000046, 0x0000186E, { { 0x54, 0x8F, 0x53, 0x34, 0xE8, 0x81, 0x76, 0x71, 0x53, 0x3F, 0x99, 0xE7, 0xCF, 0xB7, 0xC9, 0xD9 } } } },	// EOB 1
@@ -1566,20 +1566,20 @@ const ExtractEntrySearchData kEobBaseWandStringProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseItemMisuseStringsProvider[] = {
+const ExtractEntrySearchData kEoBBaseItemMisuseStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000066, 0x000022F6, { { 0xE8, 0xB9, 0x07, 0x61, 0x29, 0x90, 0xB0, 0x22, 0x30, 0xC5, 0x0F, 0xAD, 0xCA, 0x6C, 0x83, 0xC6 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000068, 0x00002472, { { 0xCA, 0xD7, 0xFD, 0x5B, 0x65, 0x72, 0xC7, 0x15, 0xB3, 0xFE, 0xFC, 0xEF, 0x53, 0xFB, 0x57, 0x6C } } } },	// EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x0000007E, 0x00002C87, { { 0x5E, 0x11, 0xC9, 0x93, 0xF4, 0xAB, 0x1A, 0x9D, 0xA7, 0x62, 0x71, 0x94, 0x37, 0xCA, 0xE2, 0x25 } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseTakenStringsProvider[] = {
+const ExtractEntrySearchData kEoBBaseTakenStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000009, 0x0000026E, { { 0x3B, 0x73, 0x70, 0x2E, 0x22, 0x90, 0x0D, 0xC1, 0xDE, 0x32, 0x11, 0xCC, 0x97, 0xBA, 0xA3, 0x58 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000000F, 0x000004ED, { { 0x8D, 0x12, 0x1E, 0x91, 0xD3, 0xF4, 0x34, 0x15, 0xC7, 0x4F, 0xE7, 0x23, 0x5B, 0xE8, 0x66, 0xB7 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBasePotionEffectStringsProvider[] = {
+const ExtractEntrySearchData kEoBBasePotionEffectStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000065, 0x0000248F, { { 0x4F, 0x60, 0x7F, 0xA7, 0x6F, 0x81, 0xD4, 0xAA, 0x68, 0xD5, 0xAA, 0xBE, 0xBC, 0xD4, 0x92, 0x3A } } } },	// EOB 1
 	{ EN_ANY, kPlatformUnknown, { 0x0000005D, 0x0000219D, { { 0x87, 0x60, 0x9F, 0xF3, 0x1B, 0x30, 0x4B, 0x2B, 0xE4, 0x94, 0xEF, 0x22, 0xEA, 0x36, 0xE4, 0x7F } } } },	// EOB 2
 	{ DE_DEU, kPlatformUnknown, { 0x0000006E, 0x00002840, { { 0x04, 0xF8, 0x53, 0x38, 0x09, 0xD8, 0x58, 0xFC, 0x5F, 0xE9, 0x69, 0xFB, 0x9C, 0x0D, 0x92, 0x2E } } } },	// EOB 1
@@ -1587,59 +1587,59 @@ const ExtractEntrySearchData kEobBasePotionEffectStringsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseYesNoStringsProvider[] = {
+const ExtractEntrySearchData kEoBBaseYesNoStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000007, 0x0000022E, { { 0xF1, 0x30, 0x61, 0xA7, 0x20, 0x71, 0x3B, 0x75, 0xBE, 0xA7, 0xD6, 0x78, 0x34, 0xF7, 0x19, 0x06 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000008, 0x00000275, { { 0xAF, 0x3E, 0xC5, 0x5A, 0x60, 0x34, 0x9B, 0x39, 0x37, 0x9E, 0xE2, 0x17, 0x23, 0x8E, 0x23, 0x23 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolEobCommonMoreStringsProvider[] = {
+const ExtractEntrySearchData kRpgCommonMoreStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000005, 0x00000133, { { 0xA6, 0x1A, 0x3A, 0xB8, 0xCC, 0x92, 0xB8, 0xBE, 0x28, 0xD6, 0x64, 0x8F, 0x0A, 0x2A, 0x39, 0xCD } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000005, 0x0000012C, { { 0x82, 0x30, 0x00, 0xD6, 0xFA, 0x53, 0x17, 0x69, 0x64, 0xCA, 0xFE, 0x0F, 0x92, 0xEF, 0x87, 0x7A } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseNpcMaxStringsProvider[] = {
+const ExtractEntrySearchData kEoBBaseNpcMaxStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000052, 0x00001D23, { { 0x95, 0xB0, 0xBF, 0xF9, 0xE6, 0x8C, 0xCF, 0x9B, 0x36, 0xE3, 0x81, 0x22, 0x1E, 0x68, 0x9E, 0xBE } } } },
-	{ DE_DEU, kPlatformUnknown, { 0x00000064, 0x00002341, { { 0xC0, 0xA6, 0xCD, 0x5E, 0x8E, 0xFA, 0x89, 0xE4, 0x98, 0xE5, 0x3D, 0x13, 0x6B, 0xE7, 0x8F, 0x6E } } } },	// Eob 1
-	{ DE_DEU, kPlatformUnknown, { 0x0000003E, 0x00001613, { { 0x4E, 0x31, 0x7F, 0xC4, 0xC7, 0x9C, 0xB5, 0x7D, 0x36, 0x85, 0xD8, 0x81, 0xE2, 0x06, 0xF9, 0xAE } } } },	// Eob 2
+	{ DE_DEU, kPlatformUnknown, { 0x00000064, 0x00002341, { { 0xC0, 0xA6, 0xCD, 0x5E, 0x8E, 0xFA, 0x89, 0xE4, 0x98, 0xE5, 0x3D, 0x13, 0x6B, 0xE7, 0x8F, 0x6E } } } },	// EoB 1
+	{ DE_DEU, kPlatformUnknown, { 0x0000003E, 0x00001613, { { 0x4E, 0x31, 0x7F, 0xC4, 0xC7, 0x9C, 0xB5, 0x7D, 0x36, 0x85, 0xD8, 0x81, 0xE2, 0x06, 0xF9, 0xAE } } } },	// EoB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseOkStringsProvider[] = {
+const ExtractEntrySearchData kEoBBaseOkStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000003, 0x0000009A, { { 0x88, 0xD2, 0x76, 0x1C, 0x80, 0x02, 0xC5, 0x5B, 0x35, 0x57, 0x0E, 0xEB, 0xCA, 0xD6, 0xC9, 0x2E } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000003, 0x0000009A, { { 0x88, 0xD2, 0x76, 0x1C, 0x80, 0x02, 0xC5, 0x5B, 0x35, 0x57, 0x0E, 0xEB, 0xCA, 0xD6, 0xC9, 0x2E } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseNpcJoinStringsProvider[] = {
+const ExtractEntrySearchData kEoBBaseNpcJoinStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000015, 0x000006C7, { { 0x5A, 0xBF, 0xA2, 0x3E, 0x36, 0xC4, 0x23, 0xC8, 0xA8, 0x86, 0x06, 0x80, 0xAF, 0xB1, 0xDD, 0xAB } } } },
-	{ DE_DEU, kPlatformUnknown, { 0x00000020, 0x00000A93, { { 0x4A, 0xFD, 0x70, 0xB7, 0x7A, 0x0B, 0x7C, 0x32, 0x07, 0x5A, 0x4A, 0xC7, 0x84, 0x9D, 0x2D, 0xF3 } } } },	// Eob 1
-	{ DE_DEU, kPlatformUnknown, { 0x00000018, 0x00000848, { { 0xC9, 0xEE, 0x71, 0x04, 0xA2, 0xA5, 0x52, 0x87, 0x7C, 0x6D, 0x3C, 0x15, 0x7D, 0x41, 0xE0, 0xE7 } } } },	// Eob 2
+	{ DE_DEU, kPlatformUnknown, { 0x00000020, 0x00000A93, { { 0x4A, 0xFD, 0x70, 0xB7, 0x7A, 0x0B, 0x7C, 0x32, 0x07, 0x5A, 0x4A, 0xC7, 0x84, 0x9D, 0x2D, 0xF3 } } } },	// EoB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000018, 0x00000848, { { 0xC9, 0xEE, 0x71, 0x04, 0xA2, 0xA5, 0x52, 0x87, 0x7C, 0x6D, 0x3C, 0x15, 0x7D, 0x41, 0xE0, 0xE7 } } } },	// EoB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseCancelStringsProvider[] = {
+const ExtractEntrySearchData kEoBBaseCancelStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000007, 0x000001A6, { { 0x21, 0xED, 0xF9, 0x71, 0xEF, 0x74, 0xD7, 0x9E, 0xF3, 0x02, 0xE5, 0x03, 0x06, 0xDE, 0xD5, 0x09 } } } },
-	{ DE_DEU, kPlatformUnknown, { 0x0000000A, 0x0000027A, { { 0xBD, 0x88, 0xB2, 0xA0, 0xAF, 0x8D, 0xFE, 0x5B, 0xAC, 0xDF, 0xB5, 0x9F, 0xA0, 0x23, 0x6E, 0xAE } } } },	// Eob 1
-	{ DE_DEU, kPlatformUnknown, { 0x00000006, 0x00000145, { { 0x22, 0x45, 0x35, 0xC6, 0x28, 0x00, 0x22, 0xAA, 0xD1, 0x15, 0x48, 0xE6, 0xE5, 0x62, 0x73, 0x37 } } } },	// Eob 2
+	{ DE_DEU, kPlatformUnknown, { 0x0000000A, 0x0000027A, { { 0xBD, 0x88, 0xB2, 0xA0, 0xAF, 0x8D, 0xFE, 0x5B, 0xAC, 0xDF, 0xB5, 0x9F, 0xA0, 0x23, 0x6E, 0xAE } } } },	// EoB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000006, 0x00000145, { { 0x22, 0x45, 0x35, 0xC6, 0x28, 0x00, 0x22, 0xAA, 0xD1, 0x15, 0x48, 0xE6, 0xE5, 0x62, 0x73, 0x37 } } } },	// EoB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseAbortStringsProvider[] = {
+const ExtractEntrySearchData kEoBBaseAbortStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000006, 0x00000178, { { 0xDD, 0xEC, 0x68, 0x6D, 0x2E, 0x10, 0x34, 0x94, 0x46, 0x25, 0xF9, 0xAB, 0x29, 0x27, 0x32, 0xA8 } } } }, 
 	{ DE_DEU, kPlatformUnknown, { 0x00000006, 0x00000145, { { 0x22, 0x45, 0x35, 0xC6, 0x28, 0x00, 0x22, 0xAA, 0xD1, 0x15, 0x48, 0xE6, 0xE5, 0x62, 0x73, 0x37 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsMainProvider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsMainProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000067, 0x0000245E, { { 0xD9, 0xE0, 0x74, 0x9D, 0x43, 0x96, 0xDC, 0x3B, 0xDF, 0x90, 0x03, 0xDE, 0x91, 0xE6, 0xA0, 0x1E } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x00000068, 0x000025D9, { { 0x17, 0xEB, 0xAB, 0x4F, 0x95, 0xD1, 0x7F, 0xEB, 0xF4, 0x92, 0x42, 0xD1, 0xD2, 0xA8, 0xC4, 0xA8 } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x00000069, 0x0000265B, { { 0x4C, 0xA9, 0x38, 0x28, 0xE1, 0xD0, 0xE3, 0x35, 0xBB, 0xDC, 0xFB, 0x6B, 0xAB, 0xB1, 0x62, 0x88 } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsSaveLoadProvider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsSaveLoadProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000077, 0x00002513, { { 0x70, 0xD9, 0x48, 0xC2, 0x3A, 0x38, 0x1D, 0xD0, 0x8B, 0x90, 0x08, 0x8D, 0x80, 0xF5, 0x24, 0x59 } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x00000086, 0x00002D2F, { { 0x2B, 0x48, 0x5C, 0x78, 0xF9, 0xB9, 0xD6, 0xA8, 0x1D, 0xF4, 0x97, 0xAC, 0xF1, 0x09, 0x26, 0xA7 } } } }, // EOB1
 	{ EN_ANY, kPlatformUnknown, { 0x000000A9, 0x00003850, { { 0xC3, 0x09, 0x7B, 0x18, 0xD6, 0x08, 0x0E, 0x2A, 0xB6, 0x66, 0x43, 0x14, 0xD7, 0x59, 0x34, 0xF7 } } } }, // EOB2
@@ -1647,13 +1647,13 @@ const ExtractEntrySearchData kEobBaseMenuStringsSaveLoadProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsOnOffProvider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsOnOffProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000007, 0x00000178, { { 0x4D, 0xA7, 0x13, 0x00, 0x05, 0xF2, 0x44, 0xCB, 0xF7, 0x12, 0x72, 0x54, 0xDE, 0x35, 0x04, 0xEC } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x00000007, 0x00000178, { { 0xC7, 0x6F, 0x60, 0x72, 0x47, 0x89, 0x47, 0xF0, 0x29, 0x57, 0x45, 0x41, 0xD5, 0x80, 0x40, 0x7B } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsSpellsProvider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsSpellsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x000001EF, 0x0000A0D0, { { 0xBA, 0x80, 0x5C, 0xAB, 0x93, 0x19, 0x53, 0x45, 0x17, 0xBC, 0x86, 0x5B, 0x1B, 0x01, 0x3E, 0x98 } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x000001EA, 0x00009DE0, { { 0x00, 0xB0, 0x1F, 0xE7, 0x16, 0x48, 0x51, 0x25, 0xE5, 0xD8, 0xA1, 0x31, 0x13, 0x81, 0x8D, 0xB6 } } } }, // EOB1
 	{ EN_ANY, kPlatformUnknown, { 0x000001FB, 0x0000A658, { { 0xAD, 0x6A, 0xFE, 0x13, 0xE5, 0xEA, 0x6A, 0xD1, 0xC9, 0x80, 0x1C, 0xEE, 0xD7, 0x2A, 0xF8, 0xB2 } } } }, // EOB2
@@ -1661,42 +1661,42 @@ const ExtractEntrySearchData kEobBaseMenuStringsSpellsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsRestProvider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsRestProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x000000B3, 0x00003CED, { { 0x82, 0xF9, 0xA1, 0x74, 0xE6, 0x95, 0xA4, 0xFC, 0xE6, 0x5E, 0xB4, 0x43, 0x7D, 0x10, 0xFD, 0x12 } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x000000B3, 0x00003BE4, { { 0x7F, 0xE8, 0xFE, 0xA4, 0xD9, 0x5C, 0x49, 0x66, 0x38, 0x8F, 0x84, 0xB8, 0xF5, 0x03, 0xCD, 0x70 } } } }, // EOB
 	{ DE_DEU, kPlatformUnknown, { 0x000000C0, 0x000040A6, { { 0x05, 0x97, 0x45, 0x72, 0xE2, 0x33, 0xBE, 0xDE, 0x56, 0x26, 0x26, 0x15, 0x3A, 0x56, 0x93, 0xFD } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsDropProvider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsDropProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000002E, 0x00000FCA, { { 0x88, 0xCB, 0xD2, 0xB3, 0xDA, 0x36, 0x97, 0x3D, 0xB8, 0x75, 0xFF, 0x36, 0xE1, 0x4E, 0xF4, 0x6D } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x00000039, 0x0000131E, { { 0x74, 0x0B, 0xE9, 0x04, 0x76, 0x26, 0xD2, 0xE8, 0x03, 0x48, 0x38, 0x18, 0xAC, 0x19, 0xBD, 0x7E } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x00000033, 0x0000119C, { { 0x8F, 0x2B, 0xC3, 0x01, 0xB2, 0xDE, 0x1F, 0xC6, 0x82, 0xC3, 0x58, 0x7C, 0x50, 0x23, 0x37, 0x65 } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsExitProvider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsExitProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000002B, 0x00000E3D, { { 0x1C, 0xD6, 0x39, 0xA9, 0xC7, 0x3D, 0x32, 0x4A, 0xF2, 0xAE, 0xEC, 0x08, 0x6F, 0xC7, 0xA6, 0x7B } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x0000002D, 0x00000E68, { { 0x4B, 0x2F, 0x65, 0x39, 0x69, 0xE7, 0x3D, 0x7B, 0x10, 0x15, 0x6F, 0x1F, 0xD8, 0x8E, 0xEA, 0x55 } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x00000026, 0x00000CBD, { { 0x0C, 0x5D, 0xE4, 0xD2, 0x6F, 0xA3, 0x91, 0xDA, 0x5F, 0xE2, 0x57, 0x77, 0x74, 0x22, 0xE7, 0x85 } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsStarveProvider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsStarveProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000003D, 0x0000150C, { { 0x40, 0xEB, 0x79, 0xC3, 0x99, 0x4C, 0xEA, 0xCD, 0x8A, 0xB4, 0x54, 0xB8, 0xAA, 0xEC, 0xAD, 0x4F } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x00000037, 0x00001296, { { 0x51, 0x3C, 0x90, 0x91, 0x4E, 0x1C, 0x73, 0x2F, 0x0C, 0x7A, 0x6D, 0x03, 0x1E, 0x54, 0x65, 0xF1 } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x00000030, 0x00001057, { { 0xF3, 0x5E, 0xFC, 0xC3, 0x9D, 0xB5, 0xFE, 0x4E, 0x66, 0x9D, 0x6A, 0xC6, 0x61, 0xC8, 0x0A, 0x17 } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsScribeProvider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsScribeProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000103, 0x000055E1, { { 0x1B, 0x56, 0xD2, 0x78, 0x3F, 0x67, 0x7A, 0x5B, 0xB6, 0x2B, 0x70, 0x3D, 0x6A, 0xBB, 0x08, 0x0A } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x0000010C, 0x00005B1C, { { 0xD7, 0xBF, 0x37, 0x21, 0xA2, 0x63, 0x8C, 0x6A, 0x02, 0x92, 0x13, 0x32, 0xD6, 0xA6, 0x1C, 0xDC } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x00000100, 0x0000560F, { { 0x69, 0x15, 0x2C, 0x2D, 0xE7, 0x40, 0x4A, 0xE0, 0x86, 0x0D, 0xC8, 0x66, 0x87, 0x1C, 0x27, 0x0B } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsDrop2Provider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsDrop2Provider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000084, 0x00002ACE, { { 0xAB, 0x78, 0x42, 0x29, 0xFB, 0xC5, 0x34, 0x96, 0x9D, 0x8A, 0x21, 0x46, 0xE7, 0x6B, 0x06, 0xBA } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x0000008C, 0x00002D02, { { 0x11, 0x3F, 0x0C, 0xB2, 0xBF, 0xA7, 0x39, 0x23, 0xDC, 0x00, 0xB4, 0xEA, 0x5E, 0xFE, 0x40, 0xB7 } } } }, // EOB1
 	{ EN_ANY, kPlatformUnknown, { 0x0000008E, 0x00002FFB, { { 0xCE, 0x7A, 0xCC, 0xA4, 0x02, 0x54, 0x1A, 0x78, 0xF1, 0xFC, 0xE6, 0x6C, 0x76, 0xCD, 0xFD, 0x9E } } } }, // EOB2
@@ -1704,14 +1704,14 @@ const ExtractEntrySearchData kEobBaseMenuStringsDrop2Provider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsHeadProvider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsHeadProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000021, 0x00000B27, { { 0x04, 0x06, 0x01, 0xF8, 0x50, 0x54, 0x11, 0x61, 0xFF, 0xB4, 0xE1, 0x97, 0xFA, 0x08, 0xAA, 0x1B } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x00000024, 0x00000CF5, { { 0x96, 0xD6, 0xB5, 0xB0, 0x2E, 0x71, 0xA4, 0x0A, 0x34, 0x41, 0x94, 0x02, 0x2F, 0xB0, 0x4C, 0x36 } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x00000025, 0x00000D92, { { 0xE4, 0x73, 0x2D, 0x29, 0xAD, 0x30, 0xE5, 0x8D, 0xAE, 0xC6, 0xD7, 0xF5, 0x35, 0xD8, 0xA4, 0x98 } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsPoisonProvider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsPoisonProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000002E, 0x00001077, { { 0x14, 0x7E, 0xFC, 0xE0, 0x88, 0xFE, 0x86, 0xA8, 0x96, 0x94, 0xB1, 0x71, 0x90, 0x47, 0x2D, 0x78 } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x00000036, 0x000013A2, { { 0x18, 0xD9, 0x1D, 0xE5, 0x3D, 0xFD, 0x52, 0xB6, 0x18, 0x17, 0x61, 0xE8, 0xA5, 0x32, 0x9F, 0xA8 } } } }, // EOB1
 	{ EN_ANY, kPlatformUnknown, { 0x0000002D, 0x00001006, { { 0xD6, 0x0B, 0x11, 0x79, 0xAD, 0x61, 0x5B, 0x3A, 0x72, 0x7D, 0x53, 0x6F, 0xA9, 0x08, 0x73, 0xDC } } } }, // EOB2
@@ -1719,21 +1719,21 @@ const ExtractEntrySearchData kEobBaseMenuStringsPoisonProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsMgcProvider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsMgcProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000020, 0x00000857, { { 0xD1, 0x9E, 0xBF, 0xF7, 0xCF, 0xF7, 0xD0, 0x94, 0x14, 0x56, 0xD2, 0x4F, 0x59, 0x91, 0x57, 0x52 } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x00000020, 0x0000086C, { { 0x12, 0x36, 0x84, 0x2F, 0x00, 0xAD, 0x12, 0x42, 0x3A, 0xA2, 0xC5, 0xC9, 0x59, 0x90, 0x64, 0x5F } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x00000021, 0x0000090B, { { 0x26, 0xA7, 0x58, 0x7C, 0x0C, 0x9E, 0x67, 0xB9, 0x05, 0xE6, 0x91, 0x59, 0xE3, 0xDF, 0x9C, 0x52 } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsPrefsProvider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsPrefsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000041, 0x00001392, { { 0xB1, 0x7E, 0xE3, 0x73, 0xB2, 0xA2, 0x63, 0x39, 0x20, 0xE8, 0xF3, 0x38, 0x45, 0xB6, 0xAC, 0xC8 } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x00000045, 0x000015F6, { { 0x53, 0xBA, 0x7E, 0x6D, 0x24, 0x88, 0x2C, 0x19, 0x10, 0x71, 0x6F, 0xAB, 0x85, 0x8E, 0x97, 0xF6 } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x0000003D, 0x00001246, { { 0x03, 0xFB, 0x7C, 0x80, 0x33, 0x45, 0x6C, 0x27, 0x89, 0x7B, 0x7C, 0xAC, 0x7A, 0xE1, 0xDE, 0x49 } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsRest2Provider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsRest2Provider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000004D, 0x00001744, { { 0x63, 0xA5, 0x6F, 0x09, 0x6F, 0x5E, 0x4B, 0x89, 0xFF, 0x33, 0x63, 0xCB, 0xAA, 0x04, 0x59, 0x63 } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x0000004D, 0x00001769, { { 0x2C, 0xA9, 0x7D, 0x4C, 0xC5, 0x13, 0xE2, 0xEB, 0x89, 0x6C, 0xAE, 0x25, 0xC3, 0x3E, 0x56, 0x7E } } } }, // EOB1
 	{ EN_ANY, kPlatformUnknown, { 0x00000052, 0x000017F6, { { 0x7C, 0x49, 0xFC, 0x89, 0x90, 0x5D, 0xFF, 0x86, 0x86, 0xE9, 0xB2, 0x29, 0x60, 0xB2, 0x22, 0x7F } } } }, // EOB2
@@ -1741,13 +1741,13 @@ const ExtractEntrySearchData kEobBaseMenuStringsRest2Provider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsRest3Provider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsRest3Provider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000002B, 0x00000DF4, { { 0x42, 0x90, 0x49, 0xA7, 0x2E, 0x61, 0x77, 0x7F, 0x9F, 0x53, 0xAD, 0x3C, 0x87, 0xE2, 0x0E, 0x36 } } } }, // EOB2
 	{ DE_DEU, kPlatformUnknown, { 0x00000027, 0x00000D45, { { 0x8D, 0xAB, 0xBF, 0x57, 0xF3, 0x2C, 0x3F, 0x93, 0xBF, 0x33, 0x58, 0x2D, 0x97, 0x78, 0x71, 0x7F } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsRest4Provider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsRest4Provider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000029, 0x00000DEC, { { 0x1C, 0x86, 0x3D, 0x40, 0x2C, 0x5E, 0xCA, 0xA0, 0xA1, 0xB8, 0x23, 0x42, 0x9C, 0x6B, 0xFA, 0xBB } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x00000034, 0x00001238, { { 0xE9, 0x95, 0x27, 0x79, 0x1C, 0x0D, 0xF5, 0x94, 0x92, 0xFC, 0xCA, 0x22, 0x17, 0xA8, 0x36, 0x96 } } } }, // EOB1
 	{ EN_ANY, kPlatformUnknown, { 0x0000002A, 0x00000DEB, { { 0x0E, 0xD3, 0xC5, 0xA9, 0x8B, 0x06, 0x57, 0xB0, 0x20, 0x1A, 0xEE, 0x42, 0x49, 0x2E, 0xA1, 0x50 } } } }, // EOB2
@@ -1755,7 +1755,7 @@ const ExtractEntrySearchData kEobBaseMenuStringsRest4Provider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsDefeatProvider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsDefeatProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000006D, 0x00002643, { { 0x94, 0xBA, 0xAC, 0xA4, 0x87, 0x6A, 0xEA, 0x7D, 0x98, 0x6E, 0x09, 0x82, 0xE0, 0x16, 0x65, 0x4F } } } }, // EOB1
 	{ DE_DEU, kPlatformUnknown, { 0x0000006A, 0x00002456, { { 0xE0, 0x9A, 0x10, 0xE2, 0x73, 0x42, 0xF6, 0x79, 0xCB, 0x65, 0xA2, 0x50, 0xF0, 0x2B, 0xFD, 0x9B } } } }, // EOB1
 	{ EN_ANY, kPlatformUnknown, { 0x00000056, 0x00001E4F, { { 0x97, 0x07, 0x5F, 0xA2, 0x0D, 0x58, 0xD2, 0xDF, 0xD6, 0x04, 0xA2, 0x16, 0x0B, 0x1F, 0x7E, 0x23 } } } }, // EOB2
@@ -1763,154 +1763,154 @@ const ExtractEntrySearchData kEobBaseMenuStringsDefeatProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsTransferProvider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsTransferProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000114, 0x00005E09, { { 0xBF, 0xCE, 0x7F, 0xE4, 0x17, 0x15, 0xC6, 0x10, 0xDF, 0x16, 0xF9, 0x3C, 0xDA, 0x29, 0xA0, 0xA6 } } } }, // EOB2
 	{ DE_DEU, kPlatformUnknown, { 0x000000D1, 0x00004811, { { 0x2E, 0x00, 0xD1, 0xA6, 0x9F, 0x53, 0xC5, 0x4B, 0x25, 0x4A, 0xAC, 0x9E, 0x11, 0x6C, 0x58, 0x5E } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsSpecProvider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsSpecProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000006F, 0x00002785, { { 0xAE, 0xC7, 0x88, 0x89, 0x39, 0xB8, 0xF7, 0xB4, 0xD5, 0x82, 0xBC, 0x46, 0xA1, 0xCB, 0x04, 0x1F } } } }, // EOB2
 	{ DE_DEU, kPlatformUnknown, { 0x00000075, 0x00002871, { { 0xB4, 0x38, 0x0F, 0x94, 0x8B, 0xB1, 0x8D, 0xA3, 0xF8, 0xDA, 0x37, 0x75, 0x6F, 0x39, 0x3E, 0xB5 } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuStringsSpellNoProvider[] = {
+const ExtractEntrySearchData kEoBBaseMenuStringsSpellNoProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000006, 0x000000A5, { { 0x0D, 0x4A, 0x8B, 0x40, 0x70, 0x79, 0xCD, 0xB3, 0x0F, 0x5A, 0x5A, 0x3F, 0x6E, 0xE8, 0xF9, 0x74 } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMenuYesNoStringsProvider[] = {
+const ExtractEntrySearchData kEoBBaseMenuYesNoStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000007, 0x000001EE, { { 0x8C, 0xF1, 0x35, 0x1F, 0xD6, 0x1F, 0xA4, 0xA1, 0xD6, 0xD6, 0x0A, 0x27, 0xB9, 0xFC, 0x9E, 0x62 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000008, 0x00000235, { { 0xC7, 0x06, 0xCF, 0xA8, 0xC0, 0xDE, 0xD4, 0x8C, 0x7F, 0xA2, 0x3A, 0xD3, 0x48, 0x51, 0x36, 0x89 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSpellLevelsMageProvider[] = {
+const ExtractEntrySearchData kEoBBaseSpellLevelsMageProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000001A, 0x00000042, { { 0x4F, 0xA3, 0x70, 0x0F, 0x6D, 0xB4, 0xC2, 0xAF, 0x12, 0xB4, 0x2E, 0x26, 0xEF, 0x0B, 0x37, 0x92 } } } }, // EOB1
 	{ UNK_LANG, kPlatformUnknown, { 0x00000023, 0x00000074, { { 0xBE, 0x10, 0xFA, 0xD9, 0xB3, 0xB0, 0x4E, 0x73, 0xC9, 0xA1, 0xE2, 0xCE, 0xE8, 0xEC, 0x85, 0x0F } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSpellLevelsClericProvider[] = {
+const ExtractEntrySearchData kEoBBaseSpellLevelsClericProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000019, 0x00000045, { { 0x9E, 0xDA, 0xF2, 0x94, 0x3E, 0x0B, 0xA0, 0x23, 0x08, 0x41, 0xD5, 0x3C, 0x61, 0x77, 0xFD, 0x78 } } } }, // EOB1
 	{ UNK_LANG, kPlatformUnknown, { 0x0000001D, 0x00000066, { { 0xDB, 0x7F, 0x93, 0xE2, 0x2E, 0xCF, 0x69, 0xCC, 0x2A, 0xEF, 0x7C, 0x1E, 0x92, 0x6B, 0x51, 0x4E } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseNumSpellsClericProvider[] = {
+const ExtractEntrySearchData kEoBBaseNumSpellsClericProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000032, 0x0000004C, { { 0x87, 0xDD, 0xD0, 0xF8, 0x52, 0x84, 0x26, 0xC4, 0x9C, 0x5D, 0x0E, 0x46, 0x1A, 0xE8, 0x19, 0xD6 } } } }, // EOB1
 	{ UNK_LANG, kPlatformUnknown, { 0x00000088, 0x00000114, { { 0xA0, 0xB7, 0x2F, 0xED, 0x50, 0xE7, 0xC6, 0x11, 0xC9, 0x25, 0xB2, 0xB9, 0x81, 0xFB, 0xD8, 0x59 } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseNumSpellsWisAdjProvider[] = {
+const ExtractEntrySearchData kEoBBaseNumSpellsWisAdjProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000028, 0x0000001D, { { 0xA5, 0xCA, 0x1D, 0x96, 0xAE, 0x89, 0xBC, 0x7A, 0x32, 0x50, 0xCE, 0x44, 0x5D, 0x93, 0x25, 0x4B } } } }, // EOB1
 	{ UNK_LANG, kPlatformUnknown, { 0x00000040, 0x0000001D, { { 0x07, 0x31, 0x0D, 0x12, 0x55, 0x11, 0x11, 0xB6, 0x68, 0xC7, 0xEE, 0xDE, 0xC6, 0xED, 0x82, 0x5A } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseNumSpellsPalProvider[] = {
+const ExtractEntrySearchData kEoBBaseNumSpellsPalProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000003C, 0x00000012, { { 0x96, 0x7E, 0x17, 0x9E, 0xFD, 0x39, 0xC9, 0x3A, 0xB7, 0x3E, 0x8D, 0xA8, 0xED, 0xA3, 0x07, 0xEB } } } }, // EOB1
 	{ UNK_LANG, kPlatformUnknown, { 0x00000088, 0x0000002F, { { 0x19, 0x1A, 0x9B, 0x42, 0xA0, 0x67, 0x10, 0x1A, 0xAC, 0x00, 0x0F, 0xF7, 0xBE, 0x04, 0x61, 0x36 } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseNumSpellsMageProvider[] = {
+const ExtractEntrySearchData kEoBBaseNumSpellsMageProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000037, 0x0000005E, { { 0x61, 0x30, 0x1A, 0x74, 0x9B, 0x4C, 0x8C, 0x83, 0xD5, 0xE6, 0x39, 0x6E, 0xCA, 0x18, 0x16, 0x63 } } } }, // EOB1
 	{ UNK_LANG, kPlatformUnknown, { 0x00000114, 0x00000102, { { 0x33, 0xEE, 0x32, 0x9C, 0xB2, 0xB3, 0x60, 0x66, 0x91, 0xE0, 0x90, 0x0E, 0x8F, 0xE1, 0xA5, 0x4A } } } }, // EOB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseCharGuiStringsHpProvider[] = {
+const ExtractEntrySearchData kEoBBaseCharGuiStringsHpProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000000F, 0x00000352, { { 0x9C, 0x13, 0x3D, 0x2A, 0x68, 0x11, 0x81, 0xA4, 0x77, 0x54, 0x47, 0x43, 0xA1, 0xDA, 0x55, 0x50 } } } }, 
-	{ DE_DEU, kPlatformUnknown, { 0x0000000E, 0x000002AC, { { 0xBB, 0xD5, 0x36, 0xB2, 0x8A, 0x60, 0x78, 0x04, 0x46, 0x2D, 0x35, 0x59, 0x3E, 0x42, 0xB9, 0x83 } } } },	// Eob 1
-	{ DE_DEU, kPlatformUnknown, { 0x0000000E, 0x000002B8, { { 0x77, 0x76, 0xA0, 0x38, 0xE9, 0xB6, 0x0C, 0x43, 0xFE, 0x5A, 0x51, 0xC7, 0x1B, 0x59, 0xD3, 0x63 } } } },	// Eob 2
+	{ DE_DEU, kPlatformUnknown, { 0x0000000E, 0x000002AC, { { 0xBB, 0xD5, 0x36, 0xB2, 0x8A, 0x60, 0x78, 0x04, 0x46, 0x2D, 0x35, 0x59, 0x3E, 0x42, 0xB9, 0x83 } } } },	// EoB 1
+	{ DE_DEU, kPlatformUnknown, { 0x0000000E, 0x000002B8, { { 0x77, 0x76, 0xA0, 0x38, 0xE9, 0xB6, 0x0C, 0x43, 0xFE, 0x5A, 0x51, 0xC7, 0x1B, 0x59, 0xD3, 0x63 } } } },	// EoB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseCharGuiStringsWp1Provider[] = {
+const ExtractEntrySearchData kEoBBaseCharGuiStringsWp1Provider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000000A, 0x00000253, { { 0x1D, 0xF4, 0xB9, 0x56, 0xE6, 0x16, 0x7D, 0x08, 0xA4, 0x00, 0x1E, 0x1A, 0x60, 0x49, 0xE9, 0x29 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000000A, 0x00000236, { { 0x17, 0xEC, 0x54, 0xA0, 0x43, 0xFB, 0x52, 0x66, 0xC5, 0x44, 0x1B, 0xDF, 0x95, 0x47, 0x62, 0xB3 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseCharGuiStringsWp2Provider[] = {
+const ExtractEntrySearchData kEoBBaseCharGuiStringsWp2Provider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000000F, 0x00000371, { { 0x42, 0xF4, 0x52, 0x60, 0x20, 0xFC, 0x34, 0x94, 0x49, 0x1E, 0x67, 0x54, 0xB5, 0x6A, 0x97, 0x2A } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000010, 0x000003D6, { { 0x10, 0xD1, 0x77, 0x6C, 0xCD, 0x00, 0x94, 0xC7, 0xD0, 0x53, 0x47, 0x9F, 0x70, 0x77, 0x50, 0xD1 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseCharGuiStringsWrProvider[] = {
+const ExtractEntrySearchData kEoBBaseCharGuiStringsWrProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000014, 0x00000477, { { 0xAA, 0x26, 0xD5, 0xFD, 0xE6, 0x16, 0x53, 0x19, 0x39, 0x46, 0xEB, 0xCD, 0x88, 0xEC, 0x5E, 0xCB } } } }, 
-	{ DE_DEU, kPlatformUnknown, { 0x00000015, 0x000004A4, { { 0x53, 0x54, 0x37, 0x35, 0x27, 0x1F, 0xB9, 0x09, 0x9C, 0xE9, 0x5E, 0x11, 0xBD, 0x8F, 0x15, 0xAE } } } },	// Eob 1
-	{ DE_DEU, kPlatformUnknown, { 0x00000011, 0x00000402, { { 0xE0, 0x92, 0xF4, 0x49, 0xB7, 0x74, 0xBB, 0xEB, 0x90, 0x0D, 0x75, 0x65, 0xBB, 0xF6, 0xB6, 0xE9 } } } },	// Eob 2
+	{ DE_DEU, kPlatformUnknown, { 0x00000015, 0x000004A4, { { 0x53, 0x54, 0x37, 0x35, 0x27, 0x1F, 0xB9, 0x09, 0x9C, 0xE9, 0x5E, 0x11, 0xBD, 0x8F, 0x15, 0xAE } } } },	// EoB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000011, 0x00000402, { { 0xE0, 0x92, 0xF4, 0x49, 0xB7, 0x74, 0xBB, 0xEB, 0x90, 0x0D, 0x75, 0x65, 0xBB, 0xF6, 0xB6, 0xE9 } } } },	// EoB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseCharGuiStringsSt1Provider[] = {
+const ExtractEntrySearchData kEoBBaseCharGuiStringsSt1Provider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000003B, 0x0000104B, { { 0xC0, 0xD9, 0x0F, 0x7B, 0x6D, 0x17, 0x02, 0xBD, 0x7B, 0xB1, 0x76, 0x72, 0xA1, 0xEE, 0x5E, 0xAD } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000039, 0x00000F69, { { 0x09, 0x42, 0x35, 0x47, 0x48, 0x50, 0x05, 0x09, 0x3B, 0x81, 0x14, 0x01, 0xF9, 0xB5, 0x04, 0xB2 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseCharGuiStringsSt2Provider[] = {
+const ExtractEntrySearchData kEoBBaseCharGuiStringsSt2Provider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000045, 0x000012E7, { { 0x49, 0x48, 0x30, 0x73, 0xDA, 0x42, 0xDB, 0xB9, 0xF4, 0x07, 0x00, 0x26, 0x96, 0x1F, 0x02, 0x4E } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000042, 0x0000114D, { { 0x88, 0x6E, 0x45, 0xF9, 0xAE, 0xEF, 0xE8, 0x54, 0x9C, 0xEF, 0xD2, 0x73, 0x78, 0x41, 0xD9, 0xAF } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseCharGuiStringsInProvider[] = {
+const ExtractEntrySearchData kEoBBaseCharGuiStringsInProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000023, 0x000008CB, { { 0xF0, 0xE9, 0xF1, 0x05, 0x47, 0x3A, 0x5D, 0xCA, 0x9F, 0x75, 0x9D, 0x51, 0x9E, 0xEC, 0x9B, 0x67 } } } }, 
-	{ DE_DEU, kPlatformUnknown, { 0x00000020, 0x00000810, { { 0xF5, 0x39, 0x1E, 0x0E, 0x65, 0xEF, 0x09, 0xF2, 0x8D, 0x90, 0xC4, 0xF6, 0x8A, 0xED, 0xAD, 0xDF } } } },	// Eob 1
-	{ DE_DEU, kPlatformUnknown, { 0x00000023, 0x00000940, { { 0xAB, 0xF6, 0xE4, 0xD4, 0x07, 0x07, 0xDA, 0x92, 0x71, 0xE2, 0x73, 0x1F, 0x06, 0xE3, 0x12, 0xEB } } } },	// Eob 2
+	{ DE_DEU, kPlatformUnknown, { 0x00000020, 0x00000810, { { 0xF5, 0x39, 0x1E, 0x0E, 0x65, 0xEF, 0x09, 0xF2, 0x8D, 0x90, 0xC4, 0xF6, 0x8A, 0xED, 0xAD, 0xDF } } } },	// EoB 1
+	{ DE_DEU, kPlatformUnknown, { 0x00000023, 0x00000940, { { 0xAB, 0xF6, 0xE4, 0xD4, 0x07, 0x07, 0xDA, 0x92, 0x71, 0xE2, 0x73, 0x1F, 0x06, 0xE3, 0x12, 0xEB } } } },	// EoB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseCharStatusStrings7Provider[] = {
+const ExtractEntrySearchData kEoBBaseCharStatusStrings7Provider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000022, 0x00000B95, { { 0xCB, 0xB7, 0x16, 0x77, 0x9C, 0xEB, 0x70, 0x83, 0xB2, 0xBE, 0xF7, 0x67, 0xB1, 0xE9, 0xD0, 0x5E } } } },	// EOB 1 + 2
 	{ DE_DEU, kPlatformUnknown, { 0x0000002B, 0x00000EE3, { { 0xC8, 0x81, 0x23, 0xC3, 0x03, 0xBD, 0x4C, 0xF5, 0x41, 0x47, 0xFA, 0x32, 0xA0, 0x98, 0x0A, 0x8E } } } },	// EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x00000023, 0x00000C68, { { 0xF5, 0x55, 0x09, 0xD8, 0x73, 0xF8, 0xF0, 0xE3, 0x14, 0xCD, 0x78, 0x84, 0x58, 0xB0, 0x64, 0x5B } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseCharStatusStrings81Provider[] = {
+const ExtractEntrySearchData kEoBBaseCharStatusStrings81Provider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000021, 0x00000B03, { { 0x44, 0xFC, 0xC2, 0x23, 0x4B, 0x78, 0xA8, 0xF8, 0xA5, 0x46, 0x5B, 0x89, 0x1F, 0x9D, 0x4E, 0xFA } } } },	// EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x00000020, 0x00000A52, { { 0x81, 0xDA, 0x22, 0x8A, 0xD3, 0x7D, 0xE7, 0xF5, 0x39, 0x6A, 0x62, 0x41, 0xE5, 0x8D, 0x45, 0x20 } } } },	// EOB 1
 };
 
-const ExtractEntrySearchData kEobBaseCharStatusStrings82Provider[] = {
+const ExtractEntrySearchData kEoBBaseCharStatusStrings82Provider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000023, 0x00000B0F, { { 0xBD, 0xED, 0xFE, 0xFD, 0x40, 0x95, 0x42, 0x21, 0x1F, 0x55, 0x67, 0x65, 0xA8, 0xC3, 0x99, 0xA1 } } } },	// EOB 2
 	{ DE_DEU, kPlatformUnknown, { 0x0000001A, 0x00000789, { { 0x8C, 0xF3, 0xB8, 0x3C, 0x6E, 0x85, 0xED, 0xD6, 0x2B, 0xD7, 0xAE, 0x8A, 0xFC, 0x25, 0x5E, 0x8F } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseCharStatusStrings9Provider[] = {
+const ExtractEntrySearchData kEoBBaseCharStatusStrings9Provider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000001C, 0x00000952, { { 0x2F, 0x41, 0x17, 0x95, 0xF8, 0xC8, 0x4E, 0x88, 0xC6, 0x83, 0x38, 0x9B, 0xAB, 0x23, 0x48, 0xB9 } } } },	// EOB 1 + 2
 	{ DE_DEU, kPlatformUnknown, { 0x0000001D, 0x0000099F, { { 0x5E, 0xB4, 0xBE, 0xA9, 0x0C, 0xB2, 0xF2, 0x4E, 0x63, 0xF8, 0x7B, 0x98, 0x67, 0x2D, 0xC9, 0xBF } } } },	// EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x0000001E, 0x00000A52, { { 0xD4, 0x65, 0x3F, 0x35, 0xDD, 0x8A, 0x33, 0x44, 0x2F, 0x8C, 0xAC, 0x2F, 0xEC, 0x96, 0x5B, 0x02 } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseCharStatusStrings12Provider[] = {
+const ExtractEntrySearchData kEoBBaseCharStatusStrings12Provider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000010, 0x00000503, { { 0x81, 0x22, 0xE9, 0x0F, 0xA5, 0xEA, 0xFE, 0xB5, 0xB6, 0x43, 0x36, 0x22, 0x87, 0x24, 0x2C, 0x40 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000014, 0x00000683, { { 0x5A, 0xF8, 0xAA, 0x16, 0x97, 0xBE, 0xD5, 0x22, 0xCE, 0x3F, 0xBC, 0x00, 0x44, 0xC1, 0x27, 0xD3 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseCharStatusStrings131Provider[] = {
+const ExtractEntrySearchData kEoBBaseCharStatusStrings131Provider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000000B, 0x0000027A, { { 0x70, 0x1A, 0x83, 0x35, 0x0A, 0x51, 0xEA, 0x27, 0x6E, 0xCD, 0xEB, 0xAD, 0x20, 0x74, 0x28, 0x7D } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000000C, 0x000002EE, { { 0xFE, 0xF9, 0x45, 0xE7, 0x89, 0x7B, 0xA4, 0x82, 0x90, 0x63, 0x91, 0x5B, 0x9E, 0x83, 0x80, 0x10 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseCharStatusStrings132Provider[] = {
+const ExtractEntrySearchData kEoBBaseCharStatusStrings132Provider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000000D, 0x00000286, { { 0x00, 0x1E, 0x11, 0xCC, 0x57, 0xFA, 0xEF, 0x2A, 0x0A, 0xFF, 0xFF, 0xE9, 0x3E, 0xA3, 0x62, 0x21 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000000A, 0x0000018A, { { 0x10, 0x54, 0x6F, 0xC3, 0x08, 0xC4, 0xD2, 0xBB, 0x34, 0x0A, 0x04, 0x65, 0x49, 0xFC, 0x5E, 0x15 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseLevelGainStringsProvider[] = {
+const ExtractEntrySearchData kEoBBaseLevelGainStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000002A, 0x00000CC9, { { 0xF2, 0x1F, 0xDF, 0xE0, 0xA5, 0x86, 0x46, 0xF4, 0xFC, 0x71, 0xB0, 0x22, 0x32, 0x46, 0x71, 0xB6 } } } },	// EOB 1
 	{ DE_DEU, kPlatformUnknown, { 0x00000029, 0x00000D38, { { 0x18, 0xA3, 0xFD, 0xCC, 0xF2, 0x68, 0x18, 0x9E, 0x80, 0x5A, 0xC0, 0x22, 0xFD, 0x15, 0x83, 0x84 } } } },	// EOB 1
 	{ EN_ANY, kPlatformUnknown, { 0x0000001C, 0x0000078C, { { 0x15, 0x70, 0x37, 0xE4, 0x0B, 0x50, 0x32, 0xCA, 0xAE, 0xF6, 0x81, 0xD0, 0x98, 0x9B, 0x36, 0x8A } } } },	// EOB 2
@@ -1918,250 +1918,250 @@ const ExtractEntrySearchData kEobBaseLevelGainStringsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseExperienceTable0Provider[] = {
-	{ UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000C9E, { { 0xDB, 0x47, 0xD9, 0x0D, 0x6E, 0x68, 0x04, 0xE4, 0x17, 0xCB, 0x60, 0x89, 0x35, 0x3E, 0xA9, 0xEE } } } },	// Eob 1
-	{ UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00000E24, { { 0xBC, 0xF3, 0x96, 0x8A, 0xD5, 0x0C, 0xAA, 0x94, 0xBB, 0xB5, 0x08, 0x73, 0xF8, 0x5C, 0xF0, 0xA9 } } } }, // Eob 2
+const ExtractEntrySearchData kEoBBaseExperienceTable0Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000C9E, { { 0xDB, 0x47, 0xD9, 0x0D, 0x6E, 0x68, 0x04, 0xE4, 0x17, 0xCB, 0x60, 0x89, 0x35, 0x3E, 0xA9, 0xEE } } } },	// EoB 1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00000E24, { { 0xBC, 0xF3, 0x96, 0x8A, 0xD5, 0x0C, 0xAA, 0x94, 0xBB, 0xB5, 0x08, 0x73, 0xF8, 0x5C, 0xF0, 0xA9 } } } }, // EoB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseExperienceTable1Provider[] = {
-	{ UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000C80, { { 0x35, 0x45, 0x0D, 0x4F, 0xE0, 0x84, 0xA2, 0x1B, 0xB0, 0x0D, 0x60, 0x4D, 0x1D, 0xD5, 0x6C, 0x72 } } } },	// Eob 1
-	{ UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00000E6F, { { 0xBD, 0x3F, 0x42, 0x54, 0x75, 0x41, 0xAA, 0x58, 0x0D, 0xD8, 0xC0, 0x07, 0x63, 0x35, 0x83, 0x6B } } } }, // Eob 2
+const ExtractEntrySearchData kEoBBaseExperienceTable1Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000C80, { { 0x35, 0x45, 0x0D, 0x4F, 0xE0, 0x84, 0xA2, 0x1B, 0xB0, 0x0D, 0x60, 0x4D, 0x1D, 0xD5, 0x6C, 0x72 } } } },	// EoB 1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00000E6F, { { 0xBD, 0x3F, 0x42, 0x54, 0x75, 0x41, 0xAA, 0x58, 0x0D, 0xD8, 0xC0, 0x07, 0x63, 0x35, 0x83, 0x6B } } } }, // EoB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseExperienceTable2Provider[] = {
-	{ UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x00000E10, { { 0xA5, 0x4D, 0xCB, 0xF3, 0x5F, 0x89, 0x71, 0x24, 0x6F, 0x70, 0xCA, 0x51, 0xAA, 0x1C, 0x0A, 0x97 } } } },	// Eob 1
-	{ UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00001149, { { 0xF9, 0xF1, 0x7E, 0x6B, 0xB2, 0xFE, 0x04, 0xC4, 0x29, 0x3D, 0xE3, 0x42, 0x5D, 0x92, 0x77, 0x53 } } } }, // Eob 2
+const ExtractEntrySearchData kEoBBaseExperienceTable2Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x00000E10, { { 0xA5, 0x4D, 0xCB, 0xF3, 0x5F, 0x89, 0x71, 0x24, 0x6F, 0x70, 0xCA, 0x51, 0xAA, 0x1C, 0x0A, 0x97 } } } },	// EoB 1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00001149, { { 0xF9, 0xF1, 0x7E, 0x6B, 0xB2, 0xFE, 0x04, 0xC4, 0x29, 0x3D, 0xE3, 0x42, 0x5D, 0x92, 0x77, 0x53 } } } }, // EoB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseExperienceTable3Provider[] = {
-	{ UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000ADC, { { 0x42, 0x2E, 0x2E, 0xF5, 0xF8, 0x65, 0x69, 0x28, 0x50, 0x67, 0x43, 0xDF, 0x91, 0x67, 0x9B, 0x09 } } } },	// Eob 1
-	{ UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00000C94, { { 0x67, 0x09, 0x98, 0x19, 0x1F, 0x6B, 0x4D, 0xEB, 0x1D, 0x4D, 0x55, 0xA8, 0xFF, 0xD1, 0xAB, 0xE1 } } } }, // Eob 2
+const ExtractEntrySearchData kEoBBaseExperienceTable3Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000ADC, { { 0x42, 0x2E, 0x2E, 0xF5, 0xF8, 0x65, 0x69, 0x28, 0x50, 0x67, 0x43, 0xDF, 0x91, 0x67, 0x9B, 0x09 } } } },	// EoB 1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00000C94, { { 0x67, 0x09, 0x98, 0x19, 0x1F, 0x6B, 0x4D, 0xEB, 0x1D, 0x4D, 0x55, 0xA8, 0xFF, 0xD1, 0xAB, 0xE1 } } } }, // EoB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseExperienceTable4Provider[] = {
-	{ UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000DA7, { { 0x45, 0x58, 0x34, 0xC9, 0x09, 0x61, 0xD7, 0xE1, 0xF8, 0x68, 0x80, 0xBC, 0xEF, 0x7A, 0x24, 0x03 } } } },	// Eob 1
-	{ UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00000FE1, { { 0x26, 0x7F, 0x83, 0x53, 0x4A, 0xC6, 0xA2, 0x7B, 0xD2, 0xFB, 0x73, 0xB2, 0x08, 0x0A, 0xF7, 0xFD } } } }, // Eob 2
+const ExtractEntrySearchData kEoBBaseExperienceTable4Provider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000DA7, { { 0x45, 0x58, 0x34, 0xC9, 0x09, 0x61, 0xD7, 0xE1, 0xF8, 0x68, 0x80, 0xBC, 0xEF, 0x7A, 0x24, 0x03 } } } },	// EoB 1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00000FE1, { { 0x26, 0x7F, 0x83, 0x53, 0x4A, 0xC6, 0xA2, 0x7B, 0xD2, 0xFB, 0x73, 0xB2, 0x08, 0x0A, 0xF7, 0xFD } } } }, // EoB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseWllFlagPresetProvider[] = {
-	{ UNK_LANG, kPlatformUnknown, { 0x00000019, 0x00000BD9, { { 0xBE, 0x5A, 0xA6, 0xC8, 0xE4, 0x04, 0x4C, 0x32, 0x35, 0x61, 0x48, 0x73, 0x29, 0xA9, 0x99, 0x54 } } } },	// Eob 1
-	{ UNK_LANG, kPlatformUnknown, { 0x00000019, 0x00000BC9, { { 0x56, 0xC0, 0x66, 0x4D, 0xE1, 0x3A, 0x27, 0x89, 0x9D, 0x73, 0x63, 0x93, 0x08, 0x2B, 0x13, 0xBC } } } }, // Eob 2
+const ExtractEntrySearchData kEoBBaseWllFlagPresetProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000019, 0x00000BD9, { { 0xBE, 0x5A, 0xA6, 0xC8, 0xE4, 0x04, 0x4C, 0x32, 0x35, 0x61, 0x48, 0x73, 0x29, 0xA9, 0x99, 0x54 } } } },	// EoB 1
+	{ UNK_LANG, kPlatformUnknown, { 0x00000019, 0x00000BC9, { { 0x56, 0xC0, 0x66, 0x4D, 0xE1, 0x3A, 0x27, 0x89, 0x9D, 0x73, 0x63, 0x93, 0x08, 0x2B, 0x13, 0xBC } } } }, // EoB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscShapeCoordsProvider[] = {
+const ExtractEntrySearchData kEoBBaseDscShapeCoordsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000168, 0x0000F206, { { 0xB8, 0xDF, 0x10, 0xBB, 0x06, 0xA1, 0x46, 0xC6, 0xD2, 0xE3, 0xD7, 0x64, 0x4A, 0xC6, 0x40, 0xC0 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscDoorScaleOffsProvider[] = {
-	{ UNK_LANG, kPlatformPC, { 0x00000020, 0x0000010F, { { 0x7B, 0x7D, 0x03, 0xDE, 0x33, 0x95, 0xB8, 0xFD, 0xAD, 0x72, 0x44, 0x7D, 0x47, 0xFE, 0x04, 0x3D } } } },	// Eob1
-	{ UNK_LANG, kPlatformPC, { 0x00000035, 0x00000139, { { 0x74, 0x63, 0x18, 0xE7, 0xAB, 0xA4, 0x22, 0xCF, 0x32, 0x19, 0x28, 0x9E, 0x7F, 0x97, 0xA7, 0x37 } } } },	// Eob2
+const ExtractEntrySearchData kEoBBaseDscDoorScaleOffsProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x00000020, 0x0000010F, { { 0x7B, 0x7D, 0x03, 0xDE, 0x33, 0x95, 0xB8, 0xFD, 0xAD, 0x72, 0x44, 0x7D, 0x47, 0xFE, 0x04, 0x3D } } } },	// EoB1
+	{ UNK_LANG, kPlatformPC, { 0x00000035, 0x00000139, { { 0x74, 0x63, 0x18, 0xE7, 0xAB, 0xA4, 0x22, 0xCF, 0x32, 0x19, 0x28, 0x9E, 0x7F, 0x97, 0xA7, 0x37 } } } },	// EoB2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscDoorScaleMult1Provider[] = {
+const ExtractEntrySearchData kEoBBaseDscDoorScaleMult1Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000026, { { 0x5D, 0x17, 0xFB, 0x6A, 0x7F, 0x51, 0x55, 0xFB, 0x55, 0xB9, 0x50, 0xB0, 0x7F, 0xE4, 0xDF, 0x67 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscDoorScaleMult2Provider[] = {
+const ExtractEntrySearchData kEoBBaseDscDoorScaleMult2Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000006, { { 0x98, 0xD8, 0xF8, 0x0C, 0x98, 0xC4, 0xF1, 0x87, 0x59, 0x32, 0x78, 0x31, 0xFA, 0x98, 0x8A, 0x43 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscDoorScaleMult3Provider[] = {
+const ExtractEntrySearchData kEoBBaseDscDoorScaleMult3Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000013, { { 0xEE, 0xB6, 0xA5, 0x6E, 0x0C, 0x8E, 0xAB, 0x38, 0xD9, 0x23, 0xC6, 0x21, 0xB3, 0x7E, 0x97, 0x78 } } } },	// EOB 1
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000019, { { 0x86, 0xD8, 0x04, 0xD2, 0x66, 0x6F, 0x43, 0x24, 0x2E, 0x93, 0xB9, 0xAE, 0xEB, 0x44, 0xCA, 0x48 } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscDoorScaleMult4Provider[] = {
+const ExtractEntrySearchData kEoBBaseDscDoorScaleMult4Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000006, { { 0x98, 0xD8, 0xF8, 0x0C, 0x98, 0xC4, 0xF1, 0x87, 0x59, 0x32, 0x78, 0x31, 0xFA, 0x98, 0x8A, 0x43 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscDoorScaleMult5Provider[] = {
+const ExtractEntrySearchData kEoBBaseDscDoorScaleMult5Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000020, { { 0x37, 0xA1, 0x0D, 0x64, 0xD6, 0x1E, 0xBA, 0xA3, 0xD9, 0x0A, 0x6C, 0xAB, 0x6B, 0xA3, 0x59, 0x24 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscDoorScaleMult6Provider[] = {
+const ExtractEntrySearchData kEoBBaseDscDoorScaleMult6Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000006, { { 0x98, 0xD8, 0xF8, 0x0C, 0x98, 0xC4, 0xF1, 0x87, 0x59, 0x32, 0x78, 0x31, 0xFA, 0x98, 0x8A, 0x43 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscDoorType5OffsProvider[] = {
+const ExtractEntrySearchData kEoBBaseDscDoorType5OffsProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x00000012, { { 0x73, 0xBB, 0x61, 0xD6, 0xA7, 0x75, 0xC8, 0x7B, 0xD6, 0xA4, 0x53, 0x1B, 0x54, 0xE9, 0x30, 0x3F } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscDoorXEProvider[] = {
+const ExtractEntrySearchData kEoBBaseDscDoorXEProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000020, 0x0000010F, { { 0x7B, 0x7D, 0x03, 0xDE, 0x33, 0x95, 0xB8, 0xFD, 0xAD, 0x72, 0x44, 0x7D, 0x47, 0xFE, 0x04, 0x3D } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscDoorY1Provider[] = {
+const ExtractEntrySearchData kEoBBaseDscDoorY1Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x000000D7, { { 0x25, 0xAE, 0xF4, 0x99, 0xE8, 0x97, 0x47, 0xAE, 0x75, 0xF3, 0xA9, 0x70, 0x4C, 0x70, 0xF3, 0x11 } } } },	// EOB 1
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x000000D8, { { 0xB4, 0xAA, 0x0D, 0x91, 0x58, 0x22, 0x16, 0xCF, 0xC5, 0x9D, 0x8D, 0xA1, 0xB4, 0x40, 0x83, 0x0E } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscDoorY3Provider[] = {
+const ExtractEntrySearchData kEoBBaseDscDoorY3Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000058, { { 0xF0, 0x3C, 0x3B, 0x97, 0x10, 0x95, 0x89, 0x18, 0x3B, 0xA9, 0xE8, 0x77, 0x9B, 0x10, 0xDC, 0xF1 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscDoorY4Provider[] = {
+const ExtractEntrySearchData kEoBBaseDscDoorY4Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000076, { { 0x84, 0xB6, 0x8F, 0x7E, 0x9A, 0x17, 0xAC, 0x59, 0xB1, 0x4C, 0xDE, 0x11, 0xA6, 0x95, 0xE3, 0x76 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscDoorY5Provider[] = {
+const ExtractEntrySearchData kEoBBaseDscDoorY5Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x000000D9, { { 0x5D, 0x27, 0x1D, 0xD6, 0x5F, 0x98, 0xF9, 0x7D, 0x65, 0x7B, 0xE0, 0x67, 0x34, 0xA0, 0xE8, 0x30 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscDoorY6Provider[] = {
+const ExtractEntrySearchData kEoBBaseDscDoorY6Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x000000D9, { { 0x4D, 0x15, 0x4A, 0xF1, 0x17, 0x09, 0xC1, 0xA6, 0x08, 0x4A, 0xCD, 0xB2, 0x68, 0xC2, 0x59, 0x52 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscDoorY7Provider[] = {
+const ExtractEntrySearchData kEoBBaseDscDoorY7Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x000000DA, { { 0xA9, 0x24, 0x71, 0x8A, 0x18, 0x24, 0x6D, 0x0A, 0x65, 0x12, 0xBB, 0x1F, 0xE7, 0x95, 0xC5, 0xA4 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscDoorCoordsExtProvider[] = {
+const ExtractEntrySearchData kEoBBaseDscDoorCoordsExtProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000048, 0x00000C8E, { { 0x2E, 0x0E, 0xB2, 0xAC, 0xE7, 0x0F, 0xDF, 0x38, 0xDF, 0x92, 0xB7, 0xB5, 0xA2, 0xFD, 0x40, 0x2D } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscItemPosIndexProvider[] = {
+const ExtractEntrySearchData kEoBBaseDscItemPosIndexProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000010, 0x00000018, { { 0x74, 0x90, 0x47, 0xE6, 0xFB, 0xC0, 0x34, 0xDF, 0x92, 0x5B, 0xA1, 0xCB, 0x06, 0x33, 0xCA, 0x6B } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscItemShpXProvider[] = {
+const ExtractEntrySearchData kEoBBaseDscItemShpXProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000024, 0x00000F2C, { { 0x9E, 0x22, 0x3F, 0x8F, 0x31, 0x83, 0xF7, 0x7C, 0x59, 0x60, 0x7C, 0x0A, 0xEB, 0xD2, 0x18, 0x85 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscItemPosUnkProvider[] = {
+const ExtractEntrySearchData kEoBBaseDscItemPosUnkProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000012, 0x00000433, { { 0xA4, 0x7B, 0x08, 0x07, 0x81, 0xEA, 0x4F, 0x99, 0x77, 0x74, 0x93, 0x65, 0xBF, 0x0C, 0x3B, 0x94 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscItemTileIndexProvider[] = {
+const ExtractEntrySearchData kEoBBaseDscItemTileIndexProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000012, 0x00000D23, { { 0x0E, 0x17, 0xE1, 0x1F, 0x34, 0x7D, 0x30, 0xF6, 0xAE, 0x0B, 0xAC, 0x9D, 0x21, 0xB6, 0x97, 0xCC } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscItemShapeMapProvider[] = {
-	{ UNK_LANG, kPlatformPC, { 0x0000005A, 0x00000B23, { { 0x41, 0x4A, 0x95, 0x7F, 0x82, 0x85, 0x28, 0x55, 0xD4, 0xD5, 0xD6, 0xD8, 0xA9, 0xAE, 0xF4, 0xC0 } } } },	// Eob 1
-	{ UNK_LANG, kPlatformPC, { 0x00000071, 0x00000860, { { 0xEA, 0x5D, 0x33, 0xB6, 0x38, 0x30, 0x65, 0x29, 0x7F, 0x08, 0x89, 0x04, 0xC5, 0x97, 0x76, 0xCB } } } },	// Eob 2
+const ExtractEntrySearchData kEoBBaseDscItemShapeMapProvider[] = {
+	{ UNK_LANG, kPlatformPC, { 0x0000005A, 0x00000B23, { { 0x41, 0x4A, 0x95, 0x7F, 0x82, 0x85, 0x28, 0x55, 0xD4, 0xD5, 0xD6, 0xD8, 0xA9, 0xAE, 0xF4, 0xC0 } } } },	// EoB 1
+	{ UNK_LANG, kPlatformPC, { 0x00000071, 0x00000860, { { 0xEA, 0x5D, 0x33, 0xB6, 0x38, 0x30, 0x65, 0x29, 0x7F, 0x08, 0x89, 0x04, 0xC5, 0x97, 0x76, 0xCB } } } },	// EoB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscTelptrShpCoordsProvider[] = {
+const ExtractEntrySearchData kEoBBaseDscTelptrShpCoordsProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000009C, 0x00000EBE, { { 0x2D, 0x1D, 0x74, 0x39, 0x29, 0xC3, 0x6F, 0x53, 0xD9, 0xA5, 0x4B, 0x9F, 0xD6, 0xDD, 0x73, 0xE9 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBasePortalSeqDataProvider[] = {
+const ExtractEntrySearchData kEoBBasePortalSeqDataProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000007E, 0x000002D0, { { 0x18, 0x7E, 0x65, 0x17, 0x4C, 0xD2, 0xB5, 0x2E, 0x81, 0xF8, 0x1C, 0xAC, 0x37, 0x21, 0x62, 0x2A } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseManDefProvider[] = {
-	{ EN_ANY, kPlatformPC, { 0x00000078, 0x000002CD, { { 0x33, 0x9B, 0x0C, 0x6A, 0x2E, 0x4F, 0xE9, 0x02, 0x7B, 0xEE, 0xF1, 0x04, 0xA3, 0xBA, 0xD4, 0xF3 } } } },	// Eob 1
-	{ DE_DEU, kPlatformPC, { 0x00000078, 0x000002C4, { { 0x92, 0x20, 0x58, 0x5F, 0x44, 0x09, 0x0B, 0xF0, 0xDA, 0x09, 0xE2, 0x44, 0x0B, 0xB7, 0x95, 0x96 } } } },	// Eob 1
-	{ EN_ANY, kPlatformPC, { 0x000000C8, 0x00000834, { { 0x18, 0xEA, 0x33, 0xB7, 0x4B, 0x72, 0x23, 0x8D, 0x0E, 0x9F, 0x4E, 0xF5, 0x09, 0xA3, 0x9C, 0xEA } } } },	// Eob 2
-	{ DE_DEU, kPlatformPC, { 0x000000C8, 0x00000622, { { 0xFE, 0x1D, 0x94, 0x3A, 0x0B, 0x17, 0x89, 0xEF, 0x60, 0x18, 0xB2, 0x43, 0x7A, 0x02, 0xDB, 0x61 } } } },	// Eob 2
+const ExtractEntrySearchData kEoBBaseManDefProvider[] = {
+	{ EN_ANY, kPlatformPC, { 0x00000078, 0x000002CD, { { 0x33, 0x9B, 0x0C, 0x6A, 0x2E, 0x4F, 0xE9, 0x02, 0x7B, 0xEE, 0xF1, 0x04, 0xA3, 0xBA, 0xD4, 0xF3 } } } },	// EoB 1
+	{ DE_DEU, kPlatformPC, { 0x00000078, 0x000002C4, { { 0x92, 0x20, 0x58, 0x5F, 0x44, 0x09, 0x0B, 0xF0, 0xDA, 0x09, 0xE2, 0x44, 0x0B, 0xB7, 0x95, 0x96 } } } },	// EoB 1
+	{ EN_ANY, kPlatformPC, { 0x000000C8, 0x00000834, { { 0x18, 0xEA, 0x33, 0xB7, 0x4B, 0x72, 0x23, 0x8D, 0x0E, 0x9F, 0x4E, 0xF5, 0x09, 0xA3, 0x9C, 0xEA } } } },	// EoB 2
+	{ DE_DEU, kPlatformPC, { 0x000000C8, 0x00000622, { { 0xFE, 0x1D, 0x94, 0x3A, 0x0B, 0x17, 0x89, 0xEF, 0x60, 0x18, 0xB2, 0x43, 0x7A, 0x02, 0xDB, 0x61 } } } },	// EoB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseManWordProvider[] = {
-	{ EN_ANY, kPlatformPC, { 0x000000E0, 0x00005134, { { 0x68, 0x9C, 0x19, 0x2B, 0x5F, 0x38, 0x36, 0x41, 0xA7, 0x7E, 0xB7, 0x51, 0x41, 0x60, 0x1D, 0x67 } } } },	// Eob 1
-	{ DE_DEU, kPlatformPC, { 0x000000EA, 0x00005458, { { 0xEC, 0x14, 0x11, 0xE9, 0x19, 0xFD, 0xF8, 0xFC, 0xA8, 0x46, 0x3D, 0xCD, 0x56, 0x08, 0xC3, 0x4A } } } },	// Eob 1
-	{ EN_ANY, kPlatformPC, { 0x0000017E, 0x00008B64, { { 0x66, 0x38, 0x09, 0x5B, 0x2E, 0x50, 0x54, 0x43, 0x1C, 0xEC, 0x56, 0x3B, 0x72, 0x39, 0xF9, 0xC3 } } } },	// Eob 2
-	{ DE_DEU, kPlatformPC, { 0x0000015B, 0x00007C37, { { 0x44, 0xA3, 0x32, 0x88, 0x9F, 0x63, 0x28, 0xA0, 0xBD, 0x00, 0xF1, 0x08, 0xCA, 0xE5, 0xFE, 0x5F } } } },	// Eob 2
+const ExtractEntrySearchData kEoBBaseManWordProvider[] = {
+	{ EN_ANY, kPlatformPC, { 0x000000E0, 0x00005134, { { 0x68, 0x9C, 0x19, 0x2B, 0x5F, 0x38, 0x36, 0x41, 0xA7, 0x7E, 0xB7, 0x51, 0x41, 0x60, 0x1D, 0x67 } } } },	// EoB 1
+	{ DE_DEU, kPlatformPC, { 0x000000EA, 0x00005458, { { 0xEC, 0x14, 0x11, 0xE9, 0x19, 0xFD, 0xF8, 0xFC, 0xA8, 0x46, 0x3D, 0xCD, 0x56, 0x08, 0xC3, 0x4A } } } },	// EoB 1
+	{ EN_ANY, kPlatformPC, { 0x0000017E, 0x00008B64, { { 0x66, 0x38, 0x09, 0x5B, 0x2E, 0x50, 0x54, 0x43, 0x1C, 0xEC, 0x56, 0x3B, 0x72, 0x39, 0xF9, 0xC3 } } } },	// EoB 2
+	{ DE_DEU, kPlatformPC, { 0x0000015B, 0x00007C37, { { 0x44, 0xA3, 0x32, 0x88, 0x9F, 0x63, 0x28, 0xA0, 0xBD, 0x00, 0xF1, 0x08, 0xCA, 0xE5, 0xFE, 0x5F } } } },	// EoB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseManPromptProvider[] = {
-	{ EN_ANY, kPlatformPC, { 0x00000041, 0x000013AC, { { 0x40, 0x2B, 0xB5, 0x99, 0xEF, 0x8F, 0x3C, 0x9F, 0xB1, 0x5A, 0xBE, 0xE4, 0x80, 0x8E, 0xBB, 0x96 } } } },	// Eob 1
-	{ DE_DEU, kPlatformPC, { 0x00000048, 0x000015A5, { { 0x0B, 0xB4, 0x9E, 0xAD, 0xB3, 0x56, 0x75, 0xC1, 0xAE, 0x29, 0xF7, 0xB5, 0x82, 0x14, 0xD1, 0x27 } } } },	// Eob 1
-	{ EN_ANY, kPlatformPC, { 0x00000041, 0x000013AC, { { 0x40, 0x2B, 0xB5, 0x99, 0xEF, 0x8F, 0x3C, 0x9F, 0xB1, 0x5A, 0xBE, 0xE4, 0x80, 0x8E, 0xBB, 0x96 } } } },	// Eob 2
-	{ DE_DEU, kPlatformPC, { 0x0000005C, 0x00001D08, { { 0x10, 0xCE, 0x2D, 0xED, 0xA9, 0xA0, 0x7C, 0xA1, 0x91, 0x3F, 0xD8, 0x43, 0x03, 0x53, 0x97, 0xCA } } } },	// Eob 2
+const ExtractEntrySearchData kEoBBaseManPromptProvider[] = {
+	{ EN_ANY, kPlatformPC, { 0x00000041, 0x000013AC, { { 0x40, 0x2B, 0xB5, 0x99, 0xEF, 0x8F, 0x3C, 0x9F, 0xB1, 0x5A, 0xBE, 0xE4, 0x80, 0x8E, 0xBB, 0x96 } } } },	// EoB 1
+	{ DE_DEU, kPlatformPC, { 0x00000048, 0x000015A5, { { 0x0B, 0xB4, 0x9E, 0xAD, 0xB3, 0x56, 0x75, 0xC1, 0xAE, 0x29, 0xF7, 0xB5, 0x82, 0x14, 0xD1, 0x27 } } } },	// EoB 1
+	{ EN_ANY, kPlatformPC, { 0x00000041, 0x000013AC, { { 0x40, 0x2B, 0xB5, 0x99, 0xEF, 0x8F, 0x3C, 0x9F, 0xB1, 0x5A, 0xBE, 0xE4, 0x80, 0x8E, 0xBB, 0x96 } } } },	// EoB 2
+	{ DE_DEU, kPlatformPC, { 0x0000005C, 0x00001D08, { { 0x10, 0xCE, 0x2D, 0xED, 0xA9, 0xA0, 0x7C, 0xA1, 0x91, 0x3F, 0xD8, 0x43, 0x03, 0x53, 0x97, 0xCA } } } },	// EoB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscMonsterFrmOffsTbl1Provider[] = {
+const ExtractEntrySearchData kEoBBaseDscMonsterFrmOffsTbl1Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000020, 0x00001000, { { 0x98, 0x27, 0x57, 0x25, 0x3B, 0x04, 0x7D, 0x14, 0x3A, 0xD4, 0xA2, 0x5D, 0xBA, 0x04, 0x45, 0xAC } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDscMonsterFrmOffsTbl2Provider[] = {
+const ExtractEntrySearchData kEoBBaseDscMonsterFrmOffsTbl2Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000020, 0x00000828, { { 0x7E, 0x8A, 0x0C, 0xEB, 0x5C, 0xBC, 0x6C, 0xBD, 0xD2, 0x48, 0x08, 0xCC, 0xF7, 0x7B, 0x81, 0x03 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseInvSlotXProvider[] = {
+const ExtractEntrySearchData kEoBBaseInvSlotXProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000036, 0x000010BF, { { 0x50, 0x6E, 0x67, 0x2B, 0x7D, 0x6C, 0xF2, 0x21, 0x73, 0xA2, 0xD5, 0xBB, 0xCE, 0x3B, 0x71, 0xAA } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseInvSlotYProvider[] = {
+const ExtractEntrySearchData kEoBBaseInvSlotYProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000001B, 0x00000A5B, { { 0x47, 0x55, 0x7D, 0x84, 0x45, 0x91, 0xC4, 0x44, 0x10, 0xD5, 0x39, 0xC4, 0xC8, 0x4F, 0x01, 0xA4 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSlotValidationFlagsProvider[] = {
+const ExtractEntrySearchData kEoBBaseSlotValidationFlagsProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000036, 0x00001F6B, { { 0x87, 0x4F, 0x9A, 0x97, 0x20, 0x20, 0xB2, 0xA6, 0xF7, 0xC2, 0x5F, 0xAA, 0x17, 0xEA, 0xB4, 0x50 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseProjectileWeaponTypesProvider[] = {
+const ExtractEntrySearchData kEoBBaseProjectileWeaponTypesProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000008, 0x0000061C, { { 0x05, 0x55, 0xA6, 0xD1, 0x3C, 0x12, 0x84, 0xDA, 0xA9, 0x33, 0xCF, 0x07, 0x05, 0x2A, 0xB2, 0x29 } } } }, // EOB 1
 	{ UNK_LANG, kPlatformPC, { 0x0000000F, 0x00000829, { { 0x9F, 0x6A, 0x13, 0x8A, 0xA7, 0x40, 0xE8, 0x40, 0x2E, 0x87, 0x49, 0x6B, 0x67, 0xED, 0xE8, 0xCE } } } }, // EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseWandTypesProvider[] = {
+const ExtractEntrySearchData kEoBBaseWandTypesProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000007, 0x00000162, { { 0xDB, 0x5D, 0x34, 0x70, 0x41, 0xAB, 0x8F, 0x75, 0xC8, 0x61, 0x8E, 0x44, 0x82, 0xCF, 0x28, 0x03 } } } }, // EOB 1
 	{ UNK_LANG, kPlatformPC, { 0x00000008, 0x00000175, { { 0x01, 0xC2, 0xF0, 0xC6, 0x1C, 0xD0, 0x14, 0xD9, 0xB8, 0xF5, 0x9C, 0xFC, 0x22, 0xE4, 0xA0, 0xA7 } } } }, // EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseDrawObjPosIndexProvider[] = {
+const ExtractEntrySearchData kEoBBaseDrawObjPosIndexProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000014, 0x00000028, { { 0x44, 0x46, 0x8C, 0x94, 0x76, 0x24, 0x08, 0xC7, 0x1F, 0x1B, 0x10, 0xD7, 0xDF, 0x18, 0x6C, 0x0D } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseFlightObjFlipIndexProvider[] = {
+const ExtractEntrySearchData kEoBBaseFlightObjFlipIndexProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000010, 0x00000008, { { 0xEB, 0xF0, 0x27, 0x7E, 0xA8, 0x09, 0x3A, 0x95, 0x3B, 0x71, 0x2A, 0x43, 0x2E, 0xCF, 0x22, 0x0B } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseFlightObjShpMapProvider[] = {
+const ExtractEntrySearchData kEoBBaseFlightObjShpMapProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000058, 0x000051BD, { { 0xC3, 0xD2, 0xD1, 0xE5, 0x78, 0xEE, 0xA7, 0xAA, 0x71, 0xD1, 0xDD, 0xDF, 0x40, 0xBB, 0xAF, 0x66 } } } },	// EOB 1
 	{ UNK_LANG, kPlatformPC, { 0x0000002D, 0x000025E6, { { 0x64, 0x26, 0x3D, 0xDC, 0x6C, 0x1A, 0xFC, 0x36, 0x9E, 0x5A, 0xBF, 0x64, 0xAD, 0xF4, 0xA3, 0x5D } } } },	// EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseFlightObjSclIndexProvider[] = {
+const ExtractEntrySearchData kEoBBaseFlightObjSclIndexProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000048, 0x00002A0E, { { 0xAC, 0xBB, 0x7D, 0x73, 0x98, 0xF4, 0x1E, 0x4A, 0x77, 0xF0, 0x98, 0x75, 0x11, 0xBF, 0xF7, 0xD5 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseBookNumbersProvider[] = {
+const ExtractEntrySearchData kEoBBaseBookNumbersProvider[] = {
 	{ EN_ANY, kPlatformPC, { 0x00000020, 0x00000AC8, { { 0x35, 0x05, 0x37, 0x4C, 0x05, 0x74, 0x04, 0x08, 0xAD, 0xA3, 0x64, 0xBF, 0xC0, 0x67, 0xF2, 0xF7 } } } },
 	{ DE_DEU, kPlatformPC, { 0x00000028, 0x00000E5D, { { 0x80, 0x98, 0x05, 0x54, 0x84, 0x90, 0xD3, 0xB3, 0x9B, 0xFB, 0x8F, 0xB9, 0xA0, 0x43, 0xAA, 0xFD } } } },
 	{ EN_ANY, kPlatformPC, { 0x00000020, 0x00000AC8, { { 0x35, 0x05, 0x37, 0x4C, 0x05, 0x74, 0x04, 0x08, 0xAD, 0xA3, 0x64, 0xBF, 0xC0, 0x67, 0xF2, 0xF7 } } } },
@@ -2169,7 +2169,7 @@ const ExtractEntrySearchData kEobBaseBookNumbersProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMageSpellsListProvider[] = {
+const ExtractEntrySearchData kEoBBaseMageSpellsListProvider[] = {
 	{ EN_ANY, kPlatformPC, { 0x00000122, 0x00006304, { { 0xD7, 0x14, 0x28, 0x83, 0x04, 0xC3, 0x42, 0x5A, 0x15, 0x49, 0x91, 0x12, 0x1D, 0x49, 0x17, 0x5B } } } },
 	{ DE_DEU, kPlatformPC, { 0x0000013A, 0x00007155, { { 0x94, 0x45, 0xB9, 0x15, 0x57, 0x6E, 0xC6, 0x70, 0x66, 0x5F, 0xA7, 0x90, 0xA0, 0xC7, 0xC9, 0xE9 } } } },
 	{ EN_ANY, kPlatformPC, { 0x00000195, 0x00008AC0, { { 0x55, 0xB8, 0x75, 0x35, 0x09, 0x23, 0x83, 0x11, 0x22, 0xF8, 0x23, 0x1E, 0x8F, 0x08, 0x57, 0x66 } } } },
@@ -2177,7 +2177,7 @@ const ExtractEntrySearchData kEobBaseMageSpellsListProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseClericSpellsListProvider[] = {
+const ExtractEntrySearchData kEoBBaseClericSpellsListProvider[] = {
 	{ EN_ANY, kPlatformPC, { 0x0000013B, 0x00006BE6, { { 0x34, 0x63, 0x0B, 0xBA, 0xED, 0xC2, 0x9B, 0x31, 0xC3, 0x65, 0x51, 0xFF, 0xEF, 0xD8, 0x25, 0x92 } } } },
 	{ DE_DEU, kPlatformPC, { 0x0000016D, 0x00007E74, { { 0x6E, 0xDE, 0x28, 0xE6, 0x13, 0x3D, 0xA6, 0x42, 0x80, 0xAB, 0xE7, 0xED, 0xAD, 0xC8, 0x62, 0x48 } } } },
 	{ EN_ANY, kPlatformPC, { 0x00000164, 0x000079B3, { { 0x93, 0x16, 0x25, 0xFB, 0x76, 0xFF, 0xBC, 0x70, 0x9A, 0xB7, 0x93, 0xFC, 0x2E, 0xC3, 0x61, 0x7F } } } },
@@ -2185,7 +2185,7 @@ const ExtractEntrySearchData kEobBaseClericSpellsListProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSpellNamesProvider[] = {
+const ExtractEntrySearchData kEoBBaseSpellNamesProvider[] = {
 	{ EN_ANY, kPlatformPC, { 0x0000029A, 0x0000F1C8, { { 0xCA, 0xE1, 0x30, 0xDC, 0xAB, 0xD1, 0x87, 0xE8, 0x51, 0xA2, 0xA2, 0x1C, 0x23, 0x4A, 0x34, 0x58 } } } },
 	{ DE_DEU, kPlatformPC, { 0x000002D3, 0x0001080D, { { 0x5F, 0xDB, 0x9E, 0x48, 0x30, 0x03, 0xE1, 0x8E, 0xC7, 0xDC, 0x98, 0x10, 0xCE, 0xA1, 0x28, 0x31 } } } },
 	{ EN_ANY, kPlatformPC, { 0x00000366, 0x00013B1A, { { 0x15, 0xCB, 0x0E, 0xA9, 0x4E, 0x78, 0x30, 0x99, 0xA1, 0xCF, 0xF7, 0x05, 0xAB, 0x00, 0x66, 0x82 } } } },
@@ -2193,7 +2193,7 @@ const ExtractEntrySearchData kEobBaseSpellNamesProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMagicStrings1Provider[] = {
+const ExtractEntrySearchData kEoBBaseMagicStrings1Provider[] = {
 	{ EN_ANY, kPlatformPC, { 0x00000084, 0x000029B0, { { 0xC6, 0x90, 0x19, 0x61, 0xA1, 0x66, 0xF6, 0x03, 0x7A, 0x1F, 0x10, 0x00, 0xCA, 0x8F, 0x69, 0x3B } } } },
 	{ DE_DEU, kPlatformPC, { 0x0000009D, 0x000033E4, { { 0x4B, 0xCF, 0x40, 0xCE, 0x0F, 0x86, 0x98, 0x36, 0x03, 0x59, 0xFE, 0x32, 0xFA, 0x4C, 0x14, 0x75 } } } },
 	{ EN_ANY, kPlatformPC, { 0x00000085, 0x000029BD, { { 0xAB, 0x22, 0x4A, 0x70, 0xBB, 0x29, 0xB8, 0xBD, 0xAF, 0xC5, 0x0D, 0x1F, 0x23, 0x38, 0xBD, 0x06 } } } },
@@ -2201,7 +2201,7 @@ const ExtractEntrySearchData kEobBaseMagicStrings1Provider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMagicStrings2Provider[] = {
+const ExtractEntrySearchData kEoBBaseMagicStrings2Provider[] = {
 	{ EN_ANY, kPlatformPC, { 0x00000051, 0x00001AD6, { { 0x28, 0x18, 0x2B, 0xF0, 0x0E, 0xC6, 0xEB, 0x01, 0xB0, 0x9A, 0x0A, 0x65, 0x05, 0xCB, 0x8F, 0x41 } } } },
 	{ DE_DEU, kPlatformPC, { 0x0000004F, 0x00001A82, { { 0x77, 0x85, 0x17, 0x25, 0x07, 0x72, 0x4A, 0x7F, 0x4F, 0x39, 0x6C, 0xDD, 0xB6, 0x70, 0x11, 0x02 } } } },
 	{ EN_ANY, kPlatformPC, { 0x00000090, 0x00002E35, { { 0x39, 0xD7, 0xA3, 0x21, 0xF0, 0xB7, 0x93, 0x9D, 0xDD, 0xEE, 0x33, 0xC2, 0x05, 0xE6, 0xE3, 0x63 } } } },
@@ -2209,7 +2209,7 @@ const ExtractEntrySearchData kEobBaseMagicStrings2Provider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMagicStrings3Provider[] = {
+const ExtractEntrySearchData kEoBBaseMagicStrings3Provider[] = {
 	{ EN_ANY, kPlatformPC, { 0x0000008D, 0x00002DC8, { { 0x35, 0x5E, 0xDD, 0x32, 0x2D, 0x55, 0x1E, 0xBC, 0x93, 0x49, 0x55, 0x48, 0x8F, 0xCD, 0x87, 0xEB } } } },
 	{ DE_DEU, kPlatformPC, { 0x000000A8, 0x0000381C, { { 0x12, 0x95, 0x55, 0x57, 0x2B, 0xA0, 0x1A, 0x75, 0xD3, 0x43, 0xFF, 0x3E, 0x00, 0xB6, 0xEC, 0x35 } } } },
 	{ EN_ANY, kPlatformPC, { 0x00000088, 0x00002CD4, { { 0xD8, 0xBA, 0x5D, 0x14, 0x92, 0x84, 0x5A, 0x07, 0xC6, 0x76, 0xDF, 0x11, 0x1D, 0x84, 0x7A, 0x98 } } } },
@@ -2217,7 +2217,7 @@ const ExtractEntrySearchData kEobBaseMagicStrings3Provider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMagicStrings4Provider[] = {
+const ExtractEntrySearchData kEoBBaseMagicStrings4Provider[] = {
 	{ EN_ANY, kPlatformPC, { 0x00000017, 0x0000071C, { { 0x96, 0x50, 0xA8, 0x08, 0x1B, 0x2D, 0x0C, 0xF6, 0x90, 0x6A, 0xE7, 0x9F, 0x65, 0xCC, 0x71, 0xA0 } } } },
 	{ DE_DEU, kPlatformPC, { 0x0000001B, 0x00000840, { { 0xA2, 0xCF, 0x81, 0x3E, 0x87, 0xA8, 0x10, 0x1B, 0x44, 0x8D, 0x5B, 0x8B, 0xAE, 0x23, 0x30, 0xD3 } } } },
 	{ EN_ANY, kPlatformPC, { 0x0000000C, 0x000003A5, { { 0x72, 0x64, 0xBD, 0x1C, 0xED, 0x05, 0x28, 0xFC, 0x94, 0x4B, 0x8F, 0x3C, 0x38, 0x08, 0x77, 0xED } } } },
@@ -2225,7 +2225,7 @@ const ExtractEntrySearchData kEobBaseMagicStrings4Provider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMagicStrings6Provider[] = {
+const ExtractEntrySearchData kEoBBaseMagicStrings6Provider[] = {
 	{ EN_ANY, kPlatformPC, { 0x00000029, 0x00000DA4, { { 0x5C, 0x6F, 0xA1, 0xC2, 0x56, 0xDE, 0xFE, 0xD5, 0x01, 0xFB, 0x65, 0x00, 0x24, 0xD1, 0x49, 0x7B } } } },
 	{ DE_DEU, kPlatformPC, { 0x00000032, 0x00001211, { { 0x13, 0xBC, 0xF1, 0x03, 0x49, 0xDB, 0x16, 0xA5, 0xC3, 0x7C, 0xBF, 0x14, 0x8F, 0x40, 0x07, 0x8E } } } },
 	{ EN_ANY, kPlatformPC, { 0x00000030, 0x00000FF5, { { 0xE4, 0x2B, 0xB9, 0xF0, 0x26, 0x3D, 0x30, 0xCD, 0xEF, 0xCD, 0xF5, 0xC0, 0x4E, 0xA4, 0xC4, 0x92 } } } },
@@ -2233,7 +2233,7 @@ const ExtractEntrySearchData kEobBaseMagicStrings6Provider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMagicStrings7Provider[] = {
+const ExtractEntrySearchData kEoBBaseMagicStrings7Provider[] = {
 	{ EN_ANY, kPlatformPC, { 0x00000014, 0x00000406, { { 0xBD, 0xE1, 0x0A, 0x75, 0xD1, 0x18, 0xF7, 0x08, 0x2D, 0x2B, 0x65, 0x36, 0xA7, 0x59, 0x2E, 0x13 } } } },
 	{ DE_DEU, kPlatformPC, { 0x0000000F, 0x000001E5, { { 0x1F, 0xC9, 0x46, 0x8B, 0x41, 0xAD, 0xAD, 0x2B, 0x5A, 0xA9, 0xAB, 0x94, 0x9A, 0x1E, 0x36, 0xAC } } } },
 	{ EN_ANY, kPlatformPC, { 0x00000065, 0x000021AF, { { 0x76, 0x35, 0xAE, 0x1D, 0xC2, 0x54, 0x36, 0x11, 0x4D, 0x3E, 0x96, 0x11, 0xB2, 0xDC, 0x15, 0x20 } } } },
@@ -2241,7 +2241,7 @@ const ExtractEntrySearchData kEobBaseMagicStrings7Provider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMagicStrings8Provider[] = {
+const ExtractEntrySearchData kEoBBaseMagicStrings8Provider[] = {
 	{ EN_ANY, kPlatformPC, { 0x00000056, 0x00001C95, { { 0x7E, 0x43, 0x73, 0xEC, 0x94, 0x0D, 0xF8, 0x1B, 0xF3, 0x1A, 0x62, 0x19, 0x96, 0x6A, 0x2C, 0xB5 } } } },
 	{ DE_DEU, kPlatformPC, { 0x00000061, 0x0000213B, { { 0xE2, 0x3B, 0xA7, 0xB7, 0xE6, 0xA5, 0x0D, 0x0F, 0xE0, 0x94, 0x9B, 0xAE, 0xE1, 0x11, 0x97, 0x93 } } } },
 	{ EN_ANY, kPlatformPC, { 0x00000085, 0x00002C0E, { { 0x6A, 0xEC, 0xF2, 0x5F, 0xA6, 0x3F, 0xB1, 0x1A, 0x74, 0x49, 0x5A, 0x47, 0xB0, 0x7A, 0xE6, 0x99 } } } },
@@ -2249,93 +2249,93 @@ const ExtractEntrySearchData kEobBaseMagicStrings8Provider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseExpObjectTlModeProvider[] = {
+const ExtractEntrySearchData kEoBBaseExpObjectTlModeProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000012, 0x0000000C, { { 0x98, 0x29, 0x54, 0xCD, 0xED, 0xAC, 0x7B, 0x61, 0x8D, 0x4F, 0x19, 0xE8, 0xA6, 0xB1, 0x51, 0x80 } } } },
 	EXTRACT_END_ENTRY
 };
-const ExtractEntrySearchData kEobBaseExpObjectTblIndexProvider[] = {
+const ExtractEntrySearchData kEoBBaseExpObjectTblIndexProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000009, 0x00000005, { { 0xFE, 0xEA, 0xC4, 0x54, 0x62, 0x7E, 0x43, 0x6E, 0x89, 0x48, 0x03, 0xE7, 0x47, 0xBF, 0x7D, 0x9D } } } }, // EOB 1
 	{ UNK_LANG, kPlatformPC, { 0x0000000E, 0x00000004, { { 0x63, 0x27, 0x19, 0x17, 0xBD, 0xC3, 0x8A, 0xA7, 0x1E, 0xF7, 0xD1, 0x78, 0x39, 0x3B, 0xD4, 0x4F } } } }, // EOB 2
 	EXTRACT_END_ENTRY
 };
-const ExtractEntrySearchData kEobBaseExpObjectShpStartProvider[] = {
+const ExtractEntrySearchData kEoBBaseExpObjectShpStartProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000034, { { 0x27, 0xC5, 0x09, 0x97, 0x8E, 0xD4, 0xF1, 0x8D, 0x77, 0xEB, 0x1D, 0x34, 0x55, 0xB2, 0x48, 0x38 } } } },
 	EXTRACT_END_ENTRY
 };
-const ExtractEntrySearchData kEobBaseExpObjectTbl1Provider[] = {
+const ExtractEntrySearchData kEoBBaseExpObjectTbl1Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000000D, 0x0000005D, { { 0x49, 0xC4, 0x47, 0x55, 0xDC, 0x25, 0x08, 0x03, 0x3D, 0x23, 0xAD, 0x09, 0x5F, 0x9C, 0x34, 0x06 } } } },
 	EXTRACT_END_ENTRY
 };
-const ExtractEntrySearchData kEobBaseExpObjectTbl2Provider[] = {
+const ExtractEntrySearchData kEoBBaseExpObjectTbl2Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000005C, { { 0xAB, 0x6A, 0x97, 0x35, 0xCC, 0x13, 0xC4, 0x17, 0x0B, 0xF2, 0xD3, 0xFD, 0xA2, 0x1C, 0x6C, 0xA8 } } } },
 	EXTRACT_END_ENTRY
 };
-const ExtractEntrySearchData kEobBaseExpObjectTbl3Provider[] = {
+const ExtractEntrySearchData kEoBBaseExpObjectTbl3Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000000B, 0x00000032, { { 0x59, 0x23, 0xB9, 0xBE, 0x0E, 0xFA, 0xEB, 0xDD, 0x82, 0x68, 0x5B, 0xB0, 0xBE, 0x9B, 0x1D, 0x8E } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseExpObjectYProvider[] = {
+const ExtractEntrySearchData kEoBBaseExpObjectYProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000008, 0x0000016C, { { 0xCF, 0x5B, 0x04, 0xAB, 0x1A, 0xAF, 0xDD, 0x56, 0xAC, 0xF6, 0x23, 0x86, 0x33, 0x06, 0x5A, 0xC6 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSparkDefStepsProvider[] = {
+const ExtractEntrySearchData kEoBBaseSparkDefStepsProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000008, 0x000002FD, { { 0xB5, 0x6F, 0x31, 0x5F, 0xC6, 0x47, 0xE9, 0x23, 0x0E, 0x73, 0xBF, 0x77, 0xC7, 0xEE, 0xDB, 0x27 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSparkDefSubStepsProvider[] = {
+const ExtractEntrySearchData kEoBBaseSparkDefSubStepsProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x000000FF, { { 0x18, 0x27, 0x73, 0x45, 0x26, 0x58, 0x81, 0x82, 0x70, 0x86, 0x7A, 0x0D, 0xDE, 0xC1, 0x08, 0x52 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSparkDefShiftProvider[] = {
+const ExtractEntrySearchData kEoBBaseSparkDefShiftProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x0000000C, { { 0xCC, 0xDC, 0x78, 0xF9, 0xFE, 0x88, 0xF3, 0x87, 0xFD, 0x08, 0xE8, 0x8A, 0x38, 0xD5, 0x4C, 0x53 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSparkDefAddProvider[] = {
+const ExtractEntrySearchData kEoBBaseSparkDefAddProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000008, 0x0000007F, { { 0x7F, 0x86, 0x2E, 0x14, 0xDB, 0x36, 0xED, 0x99, 0xD9, 0xCE, 0xAF, 0x11, 0xC2, 0x89, 0x21, 0x6B } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSparkDefXProvider[] = {
+const ExtractEntrySearchData kEoBBaseSparkDefXProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000000C, 0x000000A5, { { 0x77, 0xD7, 0xE0, 0x2D, 0xD4, 0x25, 0x94, 0x6E, 0x59, 0x3B, 0xAF, 0x9B, 0x16, 0x4F, 0x6D, 0x4C } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSparkDefYProvider[] = {
+const ExtractEntrySearchData kEoBBaseSparkDefYProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x00000138, { { 0xB9, 0xA2, 0x72, 0x01, 0x2A, 0xD7, 0x61, 0xAB, 0x02, 0x57, 0x87, 0xC8, 0x86, 0x83, 0xDF, 0xB3 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSparkOfFlags1Provider[] = {
+const ExtractEntrySearchData kEoBBaseSparkOfFlags1Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000002C, 0x00000BF4, { { 0x94, 0x8C, 0x1B, 0x77, 0xBF, 0x3A, 0x51, 0x17, 0x89, 0x16, 0xD0, 0x74, 0x95, 0xBD, 0x85, 0x98 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSparkOfFlags2Provider[] = {
+const ExtractEntrySearchData kEoBBaseSparkOfFlags2Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000040, 0x000003FC, { { 0x40, 0x13, 0x5A, 0x9D, 0xBD, 0x29, 0x2E, 0x9C, 0xC1, 0xE7, 0xD4, 0xC9, 0x26, 0xFA, 0xF2, 0x70 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSparkOfShiftProvider[] = {
+const ExtractEntrySearchData kEoBBaseSparkOfShiftProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000010, 0x000000F0, { { 0xC5, 0xC8, 0x91, 0x7E, 0x78, 0x2F, 0xF1, 0xE5, 0xE0, 0x06, 0xB2, 0x39, 0xDC, 0x0D, 0x7A, 0x5F } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSparkOfXProvider[] = {
+const ExtractEntrySearchData kEoBBaseSparkOfXProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000010, 0x00000528, { { 0x58, 0xE6, 0x24, 0x6A, 0xD3, 0xA4, 0xEF, 0x58, 0x4A, 0x9C, 0x32, 0x31, 0x4C, 0x61, 0xBC, 0x1C } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSparkOfYProvider[] = {
+const ExtractEntrySearchData kEoBBaseSparkOfYProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000010, 0x000002D4, { { 0x74, 0x31, 0xFE, 0x7C, 0x38, 0x16, 0x0C, 0x05, 0x64, 0xAB, 0x8A, 0x69, 0xEA, 0x66, 0x29, 0x2F } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseSpellPropertiesProvider[] = {
+const ExtractEntrySearchData kEoBBaseSpellPropertiesProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x000003EF, 0x0000BE7A, { { 0x10, 0xEA, 0x14, 0x26, 0xE2, 0xFC, 0xA1, 0xCB, 0xD9, 0x80, 0xFE, 0x9F, 0x69, 0x58, 0x4A, 0xCA } } } },
 	{ UNK_LANG, kPlatformPC, { 0x000003EF, 0x00008FCE, { { 0xC9, 0x36, 0xDD, 0x7B, 0x05, 0x6E, 0x92, 0xBA, 0x2B, 0x39, 0x87, 0xA7, 0x3A, 0x7E, 0xB0, 0xAD } } } },
 	{ UNK_LANG, kPlatformPC, { 0x000006D6, 0x0000CA78, { { 0xEB, 0x3B, 0x9F, 0xFD, 0x4E, 0x3F, 0x5C, 0xDE, 0xC6, 0xBA, 0xFE, 0x83, 0xB4, 0x10, 0x6D, 0x95 } } } },
@@ -2343,814 +2343,814 @@ const ExtractEntrySearchData kEobBaseSpellPropertiesProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMagicFlightPropsProvider[] = {
+const ExtractEntrySearchData kEoBBaseMagicFlightPropsProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000060, 0x0000166F, { { 0x38, 0x30, 0xCA, 0x07, 0x64, 0xBA, 0xC4, 0xA4, 0x4F, 0x75, 0xB4, 0x84, 0x3A, 0x92, 0xFD, 0xE3 } } } },
 	{ UNK_LANG, kPlatformPC, { 0x00000038, 0x00000DDC, { { 0x23, 0x32, 0x8D, 0x34, 0x4F, 0x72, 0x37, 0xE1, 0x0C, 0x1B, 0x47, 0x17, 0x5D, 0xDF, 0xDB, 0xF5 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseTurnUndeadEffectProvider[] = {
+const ExtractEntrySearchData kEoBBaseTurnUndeadEffectProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000008C, 0x00002E8B, { { 0x96, 0x15, 0x61, 0x12, 0x43, 0xCF, 0x3A, 0x84, 0x1A, 0x89, 0xB5, 0x32, 0x0D, 0xB3, 0x20, 0x67 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseBurningHandsDestProvider[] = {
+const ExtractEntrySearchData kEoBBaseBurningHandsDestProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000008, 0x0000000C, { { 0x61, 0xD7, 0xAB, 0xE1, 0x56, 0x54, 0x51, 0x5B, 0xD9, 0x59, 0x2D, 0x3D, 0xAE, 0xA4, 0x49, 0x31 } } } },	// EOB1
 	{ UNK_LANG, kPlatformPC, { 0x00000020, 0x0000003E, { { 0xA5, 0x8C, 0xCA, 0x13, 0xED, 0x0F, 0xB7, 0xA2, 0xD7, 0x9C, 0xCD, 0x11, 0x65, 0x11, 0x4B, 0xD8 } } } },	// EOB2
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseConeOfColdDest1Provider[] = {
+const ExtractEntrySearchData kEoBBaseConeOfColdDest1Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000007, 0x00000500, { { 0x48, 0xF1, 0xFE, 0x48, 0xEC, 0x64, 0x17, 0x51, 0x5C, 0x9A, 0x91, 0x35, 0x95, 0xC3, 0x73, 0x8E } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseConeOfColdDest2Provider[] = {
+const ExtractEntrySearchData kEoBBaseConeOfColdDest2Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000007, 0x00000210, { { 0xBA, 0x62, 0xA0, 0x4F, 0x50, 0x0C, 0x02, 0xC3, 0xAD, 0x7C, 0x39, 0x63, 0x5F, 0x41, 0xB4, 0xFB } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseConeOfColdDest3Provider[] = {
+const ExtractEntrySearchData kEoBBaseConeOfColdDest3Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000007, 0x00000200, { { 0xA0, 0x1F, 0xAC, 0x3A, 0x2D, 0x25, 0x1F, 0x5C, 0xD2, 0x04, 0xAC, 0xAB, 0x97, 0x8B, 0x61, 0xD7 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseConeOfColdDest4Provider[] = {
+const ExtractEntrySearchData kEoBBaseConeOfColdDest4Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000007, 0x000004F0, { { 0xB3, 0x9A, 0x2B, 0x3A, 0x51, 0x24, 0x95, 0xBE, 0xDE, 0x0F, 0xD5, 0xE9, 0xE9, 0x21, 0x96, 0x04 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseConeOfColdGfxTblProvider[] = {
+const ExtractEntrySearchData kEoBBaseConeOfColdGfxTblProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000010, 0x0000003E, { { 0x0A, 0xBA, 0xFD, 0x3F, 0xD8, 0x49, 0x3F, 0xD2, 0x26, 0x1B, 0x19, 0x53, 0x4F, 0x84, 0xB9, 0x4F } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1MainMenuStringsProvider[] = {
+const ExtractEntrySearchData kEoB1MainMenuStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000037, 0x00000D79, { { 0x1D, 0x72, 0x7F, 0x8F, 0xEB, 0x4A, 0xBF, 0x82, 0xB7, 0xB5, 0x9D, 0xB0, 0x7B, 0xDA, 0xEC, 0xEE } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000034, 0x00000C6F, { { 0xF2, 0x5F, 0xBE, 0xFB, 0x27, 0x1C, 0x91, 0x33, 0x25, 0x09, 0xC1, 0xA0, 0x27, 0x89, 0xD7, 0xD5 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1BonusStringsProvider[] = {
+const ExtractEntrySearchData kEoB1BonusStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000093, 0x000031B6, { { 0xC1, 0x54, 0x1D, 0x02, 0x4A, 0x35, 0x7F, 0x5D, 0x84, 0x2D, 0x2C, 0x9C, 0x06, 0x97, 0x29, 0x8D } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000093, 0x000031CD, { { 0x3E, 0x0F, 0x52, 0x02, 0xC7, 0x9E, 0x83, 0xB3, 0xB1, 0xAB, 0x03, 0x3A, 0x18, 0xE2, 0x87, 0x2E } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroFilesOpeningProvider[] = {
+const ExtractEntrySearchData kEoB1IntroFilesOpeningProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000003F, 0x00001044, { { 0xF5, 0x8C, 0xC8, 0x39, 0x38, 0xBB, 0x0B, 0xCA, 0x34, 0x38, 0x1D, 0x11, 0x46, 0x91, 0xEF, 0x7E } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroFilesTowerProvider[] = {
+const ExtractEntrySearchData kEoB1IntroFilesTowerProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000001A, 0x000006E6, { { 0xBD, 0x06, 0x3B, 0x7D, 0x24, 0x79, 0xD6, 0xC2, 0xFA, 0xDA, 0x31, 0x15, 0x3E, 0xE2, 0x75, 0xF8 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroFilesOrbProvider[] = {
+const ExtractEntrySearchData kEoB1IntroFilesOrbProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000015, 0x00000565, { { 0xA7, 0x91, 0x97, 0x5B, 0x29, 0xE8, 0x27, 0x90, 0xB3, 0x8F, 0xD5, 0x13, 0x77, 0x4A, 0x93, 0x37 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroFilesWdEntryProvider[] = {
+const ExtractEntrySearchData kEoB1IntroFilesWdEntryProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000002C, 0x00000B42, { { 0x5C, 0xDF, 0xB1, 0x2A, 0x83, 0x03, 0x73, 0x47, 0x1E, 0x29, 0x7C, 0x16, 0x2E, 0x5D, 0x0F, 0xA4 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroFilesKingProvider[] = {
+const ExtractEntrySearchData kEoB1IntroFilesKingProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000016, 0x000005AE, { { 0xB5, 0xB5, 0x80, 0xD3, 0xC0, 0xF4, 0x9F, 0xE1, 0x12, 0x3C, 0xCB, 0xD6, 0xF2, 0x7F, 0x15, 0x5B } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroFilesHandsProvider[] = {
+const ExtractEntrySearchData kEoB1IntroFilesHandsProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000027C, { { 0x90, 0xC7, 0x36, 0xE6, 0x7D, 0x6D, 0xCB, 0x77, 0xA0, 0x03, 0x45, 0x48, 0x46, 0xF3, 0x80, 0xC8 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroFilesWdExitProvider[] = {
+const ExtractEntrySearchData kEoB1IntroFilesWdExitProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000033, 0x00000D2A, { { 0xA8, 0xF0, 0x36, 0x0E, 0x37, 0xC6, 0xCC, 0xDB, 0x9B, 0xB8, 0x52, 0x64, 0x02, 0x1E, 0x9D, 0x1C } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroFilesTunnelProvider[] = {
+const ExtractEntrySearchData kEoB1IntroFilesTunnelProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000001A, 0x000006E2, { { 0xA1, 0xDD, 0x20, 0x50, 0x7A, 0xB6, 0x89, 0x67, 0x13, 0xAA, 0x47, 0x6B, 0xC0, 0xA0, 0x8A, 0xFD } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroOpeningFrmDelayProvider[] = {
+const ExtractEntrySearchData kEoB1IntroOpeningFrmDelayProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000000A, 0x000001E0, { { 0xDA, 0xE3, 0x06, 0xA2, 0x41, 0xF6, 0x5A, 0x6A, 0xBD, 0x0B, 0xA6, 0x09, 0x69, 0x03, 0x1D, 0x2C } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroWdEncodeXProvider[] = {
+const ExtractEntrySearchData kEoB1IntroWdEncodeXProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000001F, 0x000001BB, { { 0x00, 0x50, 0x8E, 0xF5, 0x51, 0xA6, 0xF5, 0x57, 0x0D, 0x55, 0x6C, 0x14, 0x62, 0xCD, 0xD0, 0x7E } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroWdEncodeYProvider[] = {
+const ExtractEntrySearchData kEoB1IntroWdEncodeYProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000001F, 0x0000000B, { { 0x39, 0x38, 0x02, 0xCE, 0x9D, 0x89, 0x1E, 0xBF, 0x32, 0x86, 0xA0, 0x79, 0xA4, 0xBE, 0xC5, 0x81 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroWdEncodeWHProvider[] = {
+const ExtractEntrySearchData kEoB1IntroWdEncodeWHProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000001F, 0x00000027, { { 0xA8, 0x6C, 0x13, 0x2B, 0x4C, 0x26, 0x38, 0x3D, 0xDA, 0xC2, 0x90, 0xB3, 0x97, 0xA9, 0x45, 0x84 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroWdDsXProvider[] = {
+const ExtractEntrySearchData kEoB1IntroWdDsXProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000003E, 0x0000104A, { { 0xAC, 0x1F, 0xA6, 0x20, 0xD0, 0x02, 0xF0, 0x9D, 0x75, 0x93, 0x6C, 0x12, 0x0A, 0x76, 0x1B, 0x3F } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroWdDsYProvider[] = {
+const ExtractEntrySearchData kEoB1IntroWdDsYProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000001F, 0x00000655, { { 0xF3, 0xF7, 0x65, 0xEC, 0xEA, 0x5C, 0x08, 0xCF, 0xAD, 0x48, 0x35, 0xA2, 0x5B, 0x82, 0xB0, 0xC5 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroTvlX1Provider[] = {
+const ExtractEntrySearchData kEoB1IntroTvlX1Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x00000027, { { 0x7F, 0x14, 0x7D, 0x8C, 0x20, 0x49, 0xDB, 0xC3, 0x31, 0x1A, 0xC3, 0x95, 0xA4, 0x8C, 0x96, 0xDC } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroTvlY1Provider[] = {
+const ExtractEntrySearchData kEoB1IntroTvlY1Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x000000EC, { { 0x29, 0xB4, 0x8D, 0xE1, 0xDF, 0x36, 0x39, 0x27, 0xC8, 0xF6, 0x32, 0x1A, 0x3B, 0x74, 0xA1, 0x4F } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroTvlX2Provider[] = {
+const ExtractEntrySearchData kEoB1IntroTvlX2Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x00000051, { { 0x51, 0x33, 0x0A, 0x55, 0x76, 0xA2, 0x91, 0xDA, 0x59, 0xD6, 0x09, 0xD9, 0x3D, 0xD4, 0xB8, 0xFE } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroTvlY2Provider[] = {
+const ExtractEntrySearchData kEoB1IntroTvlY2Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x0000016A, { { 0xD5, 0xA3, 0xF6, 0x12, 0x90, 0x87, 0xF2, 0xC7, 0x6A, 0x22, 0x77, 0xB5, 0x48, 0xB2, 0xCB, 0xCA } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroTvlWProvider[] = {
+const ExtractEntrySearchData kEoB1IntroTvlWProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x0000004E, { { 0xCF, 0xC7, 0xA8, 0x59, 0x6A, 0x5B, 0x35, 0x7F, 0xC9, 0xEC, 0x59, 0x7E, 0x88, 0x31, 0x32, 0xA6 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1IntroTvlHProvider[] = {
+const ExtractEntrySearchData kEoB1IntroTvlHProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x0000013D, { { 0x26, 0x7B, 0x3D, 0x5F, 0x64, 0x97, 0xF9, 0x1B, 0xB6, 0x65, 0x99, 0x95, 0x0A, 0x98, 0x38, 0x92 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1DoorShapeDefsProvider[] = {
+const ExtractEntrySearchData kEoB1DoorShapeDefsProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000060, 0x00000F8A, { { 0x95, 0x53, 0x1B, 0x07, 0x64, 0x81, 0x0E, 0x04, 0xC0, 0xDA, 0xB5, 0x74, 0x57, 0x04, 0x10, 0xE2 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1DoorSwitchShapeDefsProvider[] = {
+const ExtractEntrySearchData kEoB1DoorSwitchShapeDefsProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000060, 0x0000119E, { { 0xA4, 0xE6, 0x96, 0x36, 0x59, 0x05, 0xB8, 0x57, 0xF4, 0x6D, 0x79, 0x1D, 0x29, 0x52, 0xA0, 0xEE } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1DoorSwitchCoordsProvider[] = {
+const ExtractEntrySearchData kEoB1DoorSwitchCoordsProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000030, 0x000007F7, { { 0x85, 0x20, 0x98, 0x20, 0xE1, 0xD6, 0xA5, 0xBD, 0x9E, 0x59, 0x63, 0x6A, 0xEF, 0xEF, 0x80, 0x19 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1MonsterPropertiesProvider[] = {
+const ExtractEntrySearchData kEoB1MonsterPropertiesProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000252, 0x000038E5, { { 0x5E, 0xD7, 0xEF, 0x3B, 0xD5, 0xDA, 0x2A, 0x09, 0x78, 0xF6, 0xD8, 0x57, 0x68, 0xB4, 0x90, 0xCA } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1EnemyMageSpellListProvider[] = {
+const ExtractEntrySearchData kEoB1EnemyMageSpellListProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000000F, { { 0x01, 0x1B, 0x9C, 0x51, 0xC9, 0xA2, 0x10, 0xBB, 0xA7, 0x82, 0xD4, 0x91, 0x7E, 0x84, 0x54, 0x93 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1EnemyMageSfxProvider[] = {
+const ExtractEntrySearchData kEoB1EnemyMageSfxProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000029B, { { 0xA2, 0x9F, 0x2E, 0xDE, 0x15, 0x23, 0x78, 0xDD, 0x26, 0x98, 0x6E, 0xA3, 0x77, 0xEA, 0xB5, 0x80 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1BeholderSpellListProvider[] = {
+const ExtractEntrySearchData kEoB1BeholderSpellListProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000079, { { 0x8E, 0x13, 0x54, 0x9D, 0x54, 0xF6, 0xC9, 0x6E, 0x10, 0xF1, 0xC0, 0xE9, 0x66, 0xDD, 0x95, 0xED } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1BeholderSfxProvider[] = {
+const ExtractEntrySearchData kEoB1BeholderSfxProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x000000F5, { { 0xA9, 0x90, 0x41, 0x0D, 0xB5, 0xE0, 0x28, 0xFD, 0x0A, 0xC3, 0xF9, 0xEC, 0xC8, 0x47, 0xC1, 0x57 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1TurnUndeadStringProvider[] = {
+const ExtractEntrySearchData kEoB1TurnUndeadStringProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000027, 0x00000BF2, { { 0x43, 0x0A, 0x1E, 0xEE, 0x84, 0xD6, 0xD6, 0x87, 0x20, 0x9F, 0x15, 0x22, 0x9B, 0x65, 0x24, 0xDB } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000030, 0x00000F48, { { 0xDA, 0x59, 0xEC, 0xC1, 0x9B, 0xCF, 0x90, 0x4A, 0x93, 0x3E, 0xE5, 0x26, 0x20, 0x8B, 0x74, 0x92 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1NpcShpDataProvider[] = {
+const ExtractEntrySearchData kEoB1NpcShpDataProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000004C, 0x00000A42, { { 0x70, 0x21, 0x85, 0x8C, 0xD4, 0x04, 0xAA, 0x20, 0x1D, 0x0E, 0x9D, 0xB7, 0x74, 0x58, 0xCC, 0x0C } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1NpcSubShpIndex1Provider[] = {
+const ExtractEntrySearchData kEoB1NpcSubShpIndex1Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x00000035, { { 0x9A, 0x83, 0xF9, 0xA4, 0x27, 0xBA, 0xFC, 0xD2, 0xDE, 0x03, 0x65, 0xF2, 0xFA, 0x37, 0xDA, 0xF1 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1NpcSubShpIndex2Provider[] = {
+const ExtractEntrySearchData kEoB1NpcSubShpIndex2Provider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x00000051, { { 0x7E, 0xAC, 0x0E, 0x54, 0x59, 0x5D, 0xF6, 0x53, 0x03, 0x22, 0x1D, 0xC7, 0xFC, 0x16, 0xC8, 0x88 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1NpcSubShpYProvider[] = {
+const ExtractEntrySearchData kEoB1NpcSubShpYProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000006, 0x00000143, { { 0xC1, 0xED, 0x93, 0x5E, 0x84, 0xCE, 0x48, 0xCF, 0x4C, 0xF3, 0x9C, 0x93, 0xBF, 0xFE, 0xB8, 0x6F } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1Npc0StringsProvider[] = {
+const ExtractEntrySearchData kEoB1Npc0StringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000044, 0x000016E2, { { 0x7C, 0x28, 0x72, 0xC9, 0x57, 0xF5, 0xAB, 0x02, 0xD1, 0x42, 0xE8, 0xA3, 0xF9, 0x33, 0x70, 0xEE } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000050, 0x00001B13, { { 0x69, 0x05, 0xEB, 0xB6, 0x86, 0x81, 0xAC, 0x09, 0x53, 0x35, 0x4D, 0x55, 0xF3, 0x13, 0x6F, 0xC0 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1Npc11StringsProvider[] = {
+const ExtractEntrySearchData kEoB1Npc11StringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000001B, 0x00000928, { { 0x86, 0x08, 0x95, 0x6B, 0xBF, 0x12, 0x2D, 0xF9, 0x62, 0x25, 0xD9, 0xAE, 0x25, 0x10, 0xDF, 0xDC } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000001A, 0x000008DB, { { 0xBD, 0xBB, 0x48, 0x8E, 0x04, 0x7D, 0xE4, 0x78, 0xBB, 0x59, 0x6E, 0x86, 0xE1, 0x06, 0x27, 0x50 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1Npc12StringsProvider[] = {
+const ExtractEntrySearchData kEoB1Npc12StringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000016, 0x0000079C, { { 0x22, 0x57, 0x3A, 0x9C, 0x7C, 0xDB, 0x55, 0xD0, 0x9C, 0x84, 0x28, 0xA6, 0x9D, 0x40, 0x38, 0x6E } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000014, 0x000006ED, { { 0x88, 0x1C, 0x09, 0x61, 0x5D, 0x9D, 0xDE, 0x8A, 0x54, 0x1C, 0x40, 0xCF, 0x28, 0x2B, 0x52, 0x9D } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1Npc21StringsProvider[] = {
+const ExtractEntrySearchData kEoB1Npc21StringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000014, 0x000006FD, { { 0x55, 0x77, 0x2F, 0xB0, 0xB3, 0x2D, 0x81, 0x29, 0xDE, 0x71, 0x83, 0x41, 0x06, 0x5B, 0x72, 0x21 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000015, 0x00000748, { { 0x3E, 0x15, 0x27, 0xFD, 0x76, 0xFB, 0x14, 0x8C, 0xF6, 0x14, 0x3E, 0x20, 0x0A, 0x04, 0xF5, 0x32 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1Npc22StringsProvider[] = {
+const ExtractEntrySearchData kEoB1Npc22StringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000000F, 0x000004D4, { { 0xE5, 0x97, 0x06, 0x45, 0x6A, 0xAC, 0x96, 0x6D, 0x0A, 0xC9, 0xDF, 0x8F, 0x96, 0x2D, 0x01, 0x5D } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000000D, 0x00000439, { { 0x87, 0xCB, 0x17, 0xD2, 0xC8, 0x7F, 0x34, 0xDA, 0x82, 0x30, 0xB2, 0x68, 0xB0, 0x10, 0xD9, 0x52 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1Npc31StringsProvider[] = {
+const ExtractEntrySearchData kEoB1Npc31StringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000011, 0x00000597, { { 0x5C, 0xEB, 0x0A, 0xE6, 0xB1, 0x37, 0x0E, 0x8F, 0x14, 0xB4, 0x68, 0x86, 0xE5, 0xD2, 0xDE, 0xC7 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000012, 0x00000603, { { 0x8E, 0x68, 0x55, 0xCD, 0x29, 0x1E, 0x3C, 0x06, 0x7B, 0x97, 0xE1, 0x07, 0x49, 0x09, 0xF0, 0x57 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1Npc32StringsProvider[] = {
+const ExtractEntrySearchData kEoB1Npc32StringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000020, 0x00000AE4, { { 0xED, 0x09, 0x04, 0xEC, 0xE3, 0x43, 0xDA, 0xEE, 0x5D, 0x78, 0x32, 0x63, 0x68, 0xFC, 0x4F, 0x9E } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000020, 0x00000B13, { { 0x87, 0x40, 0x88, 0xA5, 0xE2, 0x6F, 0x83, 0xBC, 0x99, 0x2B, 0xD3, 0xF5, 0x8D, 0x6B, 0x6E, 0x7D } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1Npc4StringsProvider[] = {
+const ExtractEntrySearchData kEoB1Npc4StringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000000D, 0x0000043C, { { 0x2C, 0xE7, 0xE5, 0xAA, 0xF3, 0x50, 0xA8, 0x6D, 0xC2, 0xC6, 0x88, 0xFE, 0x12, 0x96, 0xFE, 0x54 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000014, 0x00000720, { { 0xF8, 0x58, 0x9A, 0xDB, 0xE5, 0x3F, 0x67, 0x53, 0x1F, 0x27, 0x2E, 0x8D, 0x6E, 0xAD, 0x45, 0xF5 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1Npc5StringsProvider[] = {
+const ExtractEntrySearchData kEoB1Npc5StringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000021, 0x00000ABC, { { 0xF1, 0xB5, 0x9E, 0x51, 0x9E, 0xF8, 0x84, 0x95, 0x55, 0x55, 0xE7, 0xDF, 0x36, 0xE1, 0x78, 0x9A } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000001D, 0x00000A8C, { { 0x4A, 0xAE, 0x5B, 0x3B, 0xAD, 0x18, 0x91, 0x3F, 0xC9, 0x5A, 0x82, 0x5D, 0xA7, 0x06, 0x1A, 0xAE } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1Npc6StringsProvider[] = {
+const ExtractEntrySearchData kEoB1Npc6StringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000011, 0x00000612, { { 0x1B, 0xE2, 0x23, 0xD9, 0x00, 0x5C, 0xB9, 0x54, 0xCE, 0xA7, 0x6A, 0x51, 0xF6, 0xBB, 0x8A, 0xC9 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000012, 0x00000647, { { 0x6C, 0x3F, 0xE2, 0xD0, 0xB0, 0x75, 0x2D, 0x73, 0xEE, 0x6F, 0x17, 0x74, 0xAA, 0x7D, 0xA2, 0x21 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob1Npc7StringsProvider[] = {
+const ExtractEntrySearchData kEoB1Npc7StringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000018, 0x00000777, { { 0x60, 0xB4, 0x17, 0x72, 0x89, 0x87, 0x47, 0xE3, 0xD9, 0xC3, 0x59, 0x16, 0xFD, 0x03, 0x31, 0xD4 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000016, 0x000007B6, { { 0xAE, 0xB6, 0x3C, 0x14, 0x2B, 0x34, 0xB8, 0x7C, 0xCF, 0x87, 0xDA, 0x70, 0xBF, 0x0D, 0xAB, 0xE2 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2MainMenuStringsProvider[] = {
+const ExtractEntrySearchData kEoB2MainMenuStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000005F, 0x000017BE, { { 0x77, 0x8A, 0x50, 0x9F, 0x42, 0xD8, 0x00, 0x05, 0x60, 0x2A, 0x80, 0x25, 0x00, 0xDC, 0x7C, 0x92 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000005E, 0x000017F3, { { 0xD0, 0x93, 0x2E, 0x5F, 0x9D, 0xDB, 0xC4, 0xFB, 0x9E, 0x9F, 0x14, 0xD6, 0xB4, 0xBE, 0x3D, 0x0C } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2TransferConvertTableProvider[] = {
+const ExtractEntrySearchData kEoB2TransferConvertTableProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000031, 0x000004BC, { { 0x96, 0x53, 0xA2, 0xF1, 0x26, 0xFE, 0x1B, 0x5E, 0xDF, 0x62, 0x2C, 0x8C, 0xBD, 0x62, 0x5A, 0xF9 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2TransferExpTableProvider[] = {
+const ExtractEntrySearchData kEoB2TransferExpTableProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000018, 0x0000076B, { { 0x91, 0x65, 0x5B, 0x8D, 0xE8, 0x5B, 0x28, 0x32, 0x4D, 0x7A, 0x57, 0x8E, 0x18, 0x5B, 0x1A, 0xE9 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroStringsProvider[] = {
+const ExtractEntrySearchData kEoB2IntroStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000321, 0x0000DBC3, { { 0x11, 0x9B, 0x54, 0xB3, 0x34, 0xF0, 0xB5, 0xE1, 0xFA, 0x6A, 0x31, 0x02, 0x59, 0x29, 0xCA, 0x94 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000038E, 0x0001119C, { { 0x92, 0x63, 0x18, 0xDD, 0x9F, 0x62, 0xF5, 0xBC, 0x3D, 0x93, 0xDC, 0x6E, 0xE5, 0xBE, 0x8C, 0x0B } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroCPSFilesProvider[] = {
+const ExtractEntrySearchData kEoB2IntroCPSFilesProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x000000A2, 0x0000296A, { { 0xE9, 0x28, 0x4A, 0x6E, 0xAA, 0x44, 0xF4, 0xD7, 0xD1, 0x29, 0xBF, 0x90, 0x6B, 0x82, 0xD1, 0x77 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x000000A2, 0x0000296B, { { 0x03, 0xA2, 0x0A, 0xAB, 0x76, 0x78, 0x04, 0x88, 0x6A, 0xE0, 0x36, 0x8B, 0x3A, 0x87, 0x44, 0xC8 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData00Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData00Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000037, 0x000003E1, { { 0x38, 0xC2, 0x0F, 0xE1, 0x43, 0x6A, 0xE8, 0x7C, 0x82, 0x65, 0x9B, 0x4A, 0x9F, 0x83, 0xCD, 0xC8 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData01Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData01Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000037, 0x000003A3, { { 0x84, 0x44, 0xF4, 0x46, 0x4E, 0x2B, 0xD7, 0xC6, 0xAD, 0x14, 0xF1, 0x9E, 0x8A, 0xBE, 0x7B, 0x42 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData02Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData02Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000037, 0x00000446, { { 0x0C, 0xCA, 0x41, 0x0C, 0x89, 0x59, 0xD5, 0x28, 0x9A, 0xDC, 0x51, 0x1C, 0x0B, 0x8C, 0xD2, 0xDB } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData03Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData03Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x0000010E, { { 0xAB, 0x48, 0x64, 0x02, 0xB3, 0xF3, 0x6C, 0x82, 0x9D, 0x37, 0x5F, 0x52, 0x0F, 0x5B, 0xDF, 0x96 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData04Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData04Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000021, 0x00000149, { { 0x3B, 0xAC, 0x14, 0x51, 0xDF, 0x5D, 0x22, 0x15, 0x46, 0x4E, 0xCD, 0xF3, 0xD4, 0x61, 0x29, 0x4A } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData05Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData05Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x0000010E, { { 0x28, 0x29, 0x5F, 0x31, 0x23, 0x53, 0xBA, 0xD7, 0x24, 0xB9, 0x21, 0x70, 0x84, 0x8A, 0x1C, 0x2E } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData06Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData06Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x000000B0, 0x00001365, { { 0x91, 0x28, 0x2F, 0x10, 0x45, 0x4D, 0xCF, 0x3E, 0x70, 0x1E, 0xD4, 0xBA, 0x0E, 0x70, 0xDE, 0xD0 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData07Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData07Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000037, 0x000003C4, { { 0x8C, 0x72, 0xDE, 0x4F, 0x92, 0x52, 0x0A, 0xED, 0xF4, 0x79, 0xD6, 0x3D, 0x8F, 0x59, 0x9D, 0x69 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData08Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData08Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000042, 0x00000442, { { 0xD2, 0x91, 0x51, 0xEB, 0x91, 0x13, 0x43, 0xCE, 0x7E, 0x60, 0xB8, 0xFF, 0xA7, 0xE2, 0x4C, 0x11 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData09Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData09Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x000004BC, { { 0xD6, 0xC7, 0x44, 0x2E, 0xE7, 0x2A, 0x44, 0x09, 0x39, 0xC3, 0xD3, 0xA8, 0x02, 0xC8, 0xA0, 0x19 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData10Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData10Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000006E, 0x00000C12, { { 0x91, 0xDB, 0x41, 0x7A, 0x4F, 0x7C, 0x7B, 0x83, 0x32, 0x13, 0x68, 0xF6, 0x58, 0x79, 0xDA, 0x99 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData11Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData11Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x000000B0, 0x0000073C, { { 0x17, 0x1F, 0x4D, 0x05, 0x3F, 0x14, 0x2E, 0x77, 0xD3, 0xDB, 0x78, 0x67, 0xBB, 0x18, 0xDC, 0x85 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData12Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData12Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000021, 0x00000228, { { 0xC9, 0x50, 0x68, 0x51, 0xD0, 0xC1, 0x5D, 0xD4, 0xFF, 0x08, 0x28, 0xDE, 0xC4, 0x41, 0x8C, 0xDB } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData13Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData13Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x00000340, { { 0x03, 0xCA, 0x5D, 0xD1, 0x15, 0xFA, 0x60, 0xD7, 0x70, 0x64, 0x3D, 0x44, 0x08, 0xB8, 0xDB, 0xAD } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData14Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData14Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000042, 0x000007C0, { { 0x82, 0xA9, 0x0B, 0x90, 0x9D, 0x65, 0x1E, 0xC7, 0x03, 0x5E, 0xB7, 0xDF, 0x6E, 0x1F, 0xED, 0xD6 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData15Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData15Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x00000504, { { 0xA7, 0x91, 0x4F, 0xAD, 0xB1, 0x77, 0x80, 0x3A, 0xC7, 0xDE, 0x35, 0x7A, 0x96, 0x16, 0xD2, 0x13 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData16Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData16Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000079, 0x00000B3D, { { 0xCC, 0x63, 0x5A, 0x11, 0xEE, 0x8A, 0xAE, 0x3A, 0x14, 0xC3, 0xBC, 0xDA, 0xAF, 0x1D, 0xD4, 0x2C } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData17Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData17Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000084, 0x00000911, { { 0x09, 0x1C, 0x4B, 0xD9, 0x0B, 0x2A, 0xD6, 0xC1, 0xE3, 0x8D, 0xFE, 0x43, 0x8F, 0x2E, 0x21, 0x51 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData18Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData18Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000058, 0x000008FA, { { 0xFE, 0x58, 0xD9, 0x67, 0x78, 0x97, 0xE2, 0xCD, 0x82, 0xB8, 0xC9, 0xC0, 0x1F, 0xCA, 0x7C, 0xF5 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData19Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData19Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000009A, 0x00000D6B, { { 0xA1, 0xDD, 0x7B, 0x8B, 0x25, 0xA5, 0x96, 0x5A, 0x33, 0x5E, 0x80, 0x5F, 0xA5, 0xBB, 0xAC, 0x11 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData20Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData20Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000009A, 0x00000D6C, { { 0x19, 0xF9, 0x93, 0x1D, 0x01, 0xEE, 0x7C, 0x8B, 0x6C, 0x3E, 0x35, 0x2C, 0x5C, 0x88, 0xCD, 0xB6 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData21Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData21Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000009A, 0x00000D83, { { 0xCB, 0x4F, 0x21, 0x29, 0x63, 0x5B, 0x8C, 0xF2, 0xBA, 0x03, 0x49, 0xD1, 0xAF, 0x22, 0xB0, 0xD5 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData22Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData22Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000200, { { 0x66, 0xEE, 0x45, 0xB1, 0x87, 0x66, 0xC4, 0x55, 0xCE, 0x60, 0x0C, 0x5B, 0xBB, 0x3C, 0x7D, 0x33 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData23Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData23Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x0000020D, { { 0xC4, 0x49, 0xE2, 0x5B, 0x2E, 0x17, 0x68, 0xC4, 0xBA, 0x20, 0xEC, 0xB1, 0xEB, 0x1A, 0xFB, 0xE0 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData24Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData24Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000214, { { 0xF1, 0x46, 0x82, 0xEF, 0x6D, 0xCA, 0x68, 0xA2, 0xF3, 0x55, 0x63, 0xD2, 0x13, 0x25, 0x19, 0xF7 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData25Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData25Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000256, { { 0x8F, 0xB9, 0xCD, 0xB8, 0x58, 0xCB, 0x90, 0x03, 0xFC, 0xB6, 0x95, 0x6F, 0x52, 0xF8, 0x7D, 0x19 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData26Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData26Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000263, { { 0x7A, 0x37, 0x07, 0xC4, 0x67, 0x72, 0x1F, 0xCB, 0xAC, 0x98, 0x46, 0x9A, 0xF3, 0x5F, 0xBA, 0x78 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData27Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData27Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x0000026A, { { 0x80, 0x11, 0xEE, 0x44, 0xDA, 0xE1, 0x26, 0x1F, 0x14, 0x7E, 0x93, 0x99, 0x44, 0x44, 0x9F, 0x85 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData28Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData28Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x000001F6, { { 0x45, 0xA1, 0xA5, 0xEC, 0x85, 0x06, 0xE2, 0x91, 0x28, 0xE0, 0xBB, 0x53, 0x74, 0x44, 0xD9, 0xA6 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData29Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData29Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x000001F9, { { 0x3F, 0x03, 0x2F, 0x8B, 0xFB, 0x6A, 0x97, 0x05, 0xED, 0xBB, 0xD6, 0xA0, 0xF5, 0x7A, 0x6D, 0x08 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData30Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData30Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000204, { { 0xA1, 0x37, 0x57, 0xC3, 0x72, 0x08, 0x98, 0xA6, 0xF4, 0x5E, 0x58, 0x9E, 0xF3, 0x11, 0x88, 0x1E } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData31Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData31Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000212, { { 0x19, 0xCC, 0x6F, 0xA8, 0x29, 0xB5, 0x3B, 0x15, 0x2F, 0x2C, 0x43, 0xED, 0x7A, 0xF5, 0xC5, 0x69 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData32Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData32Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000037, 0x000006C9, { { 0xBF, 0x65, 0xBA, 0x3F, 0x44, 0xEE, 0xB0, 0x5C, 0x8B, 0xBD, 0x15, 0xAB, 0x03, 0xD1, 0x55, 0x21 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData33Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData33Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000009A, 0x00001585, { { 0xB5, 0x44, 0x06, 0xC9, 0xE8, 0x27, 0x75, 0x6E, 0x63, 0x77, 0xE9, 0xA9, 0x68, 0x73, 0xF5, 0x78 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData34Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData34Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000058, 0x00000B43, { { 0x52, 0xB4, 0x1E, 0x14, 0x88, 0xBD, 0x8A, 0xD7, 0x38, 0xDF, 0x25, 0xB0, 0xAF, 0xAE, 0x76, 0xE1 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData35Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData35Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000037, 0x000005A4, { { 0xFB, 0x82, 0xE7, 0xB2, 0x54, 0xDB, 0xB5, 0xE1, 0xCE, 0xFB, 0xD1, 0x23, 0x39, 0x8F, 0xA1, 0x0D } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData36Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData36Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000042, 0x00000572, { { 0x2C, 0x16, 0xD9, 0xBE, 0xDB, 0xBA, 0x04, 0xCA, 0x97, 0xB5, 0x88, 0x43, 0xA8, 0x62, 0xE2, 0x04 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData37Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData37Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x0000024E, { { 0xFF, 0x28, 0xD8, 0x62, 0xC6, 0xAD, 0x48, 0xC7, 0x31, 0x84, 0x6C, 0xBA, 0x9F, 0x4D, 0x15, 0xDA } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData38Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData38Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x000001D9, 0x00001FB1, { { 0x16, 0xB0, 0xDF, 0x86, 0x8C, 0xB3, 0x52, 0xEF, 0x21, 0x04, 0x22, 0x6D, 0xC0, 0x03, 0xB8, 0xC6 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData39Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData39Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000004D, 0x00000582, { { 0x11, 0x6C, 0xBB, 0xF6, 0x1B, 0x3C, 0xAE, 0xAA, 0x40, 0x27, 0x3F, 0x86, 0x33, 0x92, 0xCB, 0xA9 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData40Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData40Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000160, 0x000010A2, { { 0xD9, 0x9D, 0xF1, 0x7D, 0xE1, 0x7C, 0x61, 0xC0, 0xD4, 0xD3, 0x05, 0x0C, 0x79, 0xDD, 0xDB, 0xD1 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData41Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData41Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000037, 0x00000355, { { 0x92, 0x85, 0xBE, 0x5A, 0x38, 0x08, 0xF3, 0xDF, 0xC6, 0x56, 0x74, 0xC3, 0x0B, 0x3F, 0x72, 0x4D } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData42Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData42Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000021, 0x0000010B, { { 0x68, 0xF8, 0x1D, 0x74, 0x6D, 0x32, 0x1E, 0x3A, 0x1C, 0xD1, 0x1D, 0x4B, 0x89, 0x3D, 0x5F, 0x2B } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroSeqData43Provider[] = {
+const ExtractEntrySearchData kEoB2IntroSeqData43Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000037, 0x00000116, { { 0xD5, 0x46, 0xCB, 0x3F, 0x27, 0xBD, 0x2B, 0xD6, 0x35, 0x69, 0x9E, 0x0A, 0x28, 0xDA, 0xC9, 0x84 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroShapes00Provider[] = {
+const ExtractEntrySearchData kEoB2IntroShapes00Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000005A, 0x00000A86, { { 0xF9, 0xD5, 0xD2, 0x93, 0xBC, 0xC4, 0x86, 0x3F, 0x83, 0x0D, 0xDB, 0x38, 0x60, 0x6E, 0xA7, 0xDA } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroShapes01Provider[] = {
+const ExtractEntrySearchData kEoB2IntroShapes01Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000000C, 0x0000009B, { { 0xAA, 0xDD, 0x25, 0x21, 0x57, 0x6A, 0xB7, 0xEB, 0xDA, 0xFD, 0x72, 0x3B, 0xCA, 0x68, 0xDB, 0x34 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroShapes04Provider[] = {
+const ExtractEntrySearchData kEoB2IntroShapes04Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000003C, 0x00000417, { { 0x13, 0x95, 0x81, 0x46, 0x84, 0x36, 0xF2, 0xFC, 0xDE, 0x15, 0x85, 0x81, 0xB3, 0x9A, 0x9D, 0x20 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2IntroShapes07Provider[] = {
+const ExtractEntrySearchData kEoB2IntroShapes07Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000006C, 0x000021F1, { { 0x6F, 0x7C, 0x28, 0xBB, 0xC3, 0x52, 0xE4, 0x13, 0xB4, 0xE9, 0xA4, 0x47, 0x9A, 0xBE, 0x19, 0xDA } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleStringsProvider[] = {
+const ExtractEntrySearchData kEoB2FinaleStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000031C, 0x0000E287, { { 0x1E, 0x73, 0x93, 0x79, 0xB7, 0xF8, 0x17, 0xEE, 0xE4, 0xFC, 0xF0, 0x34, 0x9D, 0x06, 0x4F, 0x55 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000039F, 0x00011660, { { 0xBC, 0x1D, 0x95, 0x20, 0x32, 0xF5, 0x83, 0xCF, 0xF7, 0x11, 0xE4, 0x1D, 0x89, 0x47, 0xF0, 0x65 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2CreditsDataProvider[] = {
+const ExtractEntrySearchData kEoB2CreditsDataProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000090C, 0x00023464, { { 0x55, 0x31, 0x9D, 0x60, 0x2C, 0xA1, 0x0B, 0xF9, 0xED, 0x46, 0xDF, 0x44, 0x1A, 0x9F, 0xB1, 0xB0 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000B11, 0x0002BBD7, { { 0x46, 0x24, 0x78, 0xE9, 0xCE, 0x75, 0x45, 0x7B, 0x3B, 0xAA, 0x15, 0xD8, 0x5B, 0xCB, 0x06, 0x3A } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleCPSFilesProvider[] = {
+const ExtractEntrySearchData kEoB2FinaleCPSFilesProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000009C, 0x00002853, { { 0x1F, 0xB9, 0x3D, 0x48, 0x47, 0x31, 0x0D, 0xA8, 0x92, 0x52, 0xD1, 0x54, 0x48, 0x42, 0x47, 0xBD } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000009C, 0x00002878, { { 0x48, 0x3B, 0x7A, 0xC2, 0x9C, 0xEC, 0x10, 0x07, 0xD1, 0xB6, 0x9E, 0x89, 0xE9, 0xE1, 0xBF, 0xBF } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData00Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData00Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000079, 0x00000B66, { { 0x9B, 0x8C, 0x17, 0xFA, 0xD2, 0x4F, 0x4B, 0x0E, 0x3A, 0x43, 0xB1, 0x86, 0x0C, 0xDC, 0x73, 0xAB } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData01Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData01Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000063, 0x00000A03, { { 0xBB, 0x31, 0xEA, 0x35, 0xFB, 0x99, 0x4C, 0x3E, 0x72, 0xBD, 0x36, 0x6B, 0x5C, 0x03, 0x19, 0x7F } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData02Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData02Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x000007C2, { { 0xF6, 0x83, 0x37, 0x58, 0x3C, 0x59, 0x84, 0x8F, 0x97, 0x80, 0xE2, 0xD8, 0xFD, 0x77, 0xA9, 0x54 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData03Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData03Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000042, 0x0000092B, { { 0x47, 0xE4, 0x34, 0xE8, 0x72, 0xCC, 0xA4, 0x4A, 0xA4, 0x8F, 0xBA, 0xBC, 0x0C, 0x04, 0x18, 0xAF } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData04Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData04Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000058, 0x0000080B, { { 0x16, 0xDB, 0x77, 0x4C, 0x8E, 0xFD, 0x44, 0xF6, 0x5E, 0x28, 0x0B, 0x74, 0x93, 0x45, 0x8F, 0xD9 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData05Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData05Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000004D, 0x00000C72, { { 0x6C, 0x57, 0x56, 0x7E, 0x87, 0x10, 0x9C, 0xE7, 0x69, 0xAC, 0x3B, 0x3F, 0xF6, 0x43, 0x5C, 0xD4 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData06Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData06Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000264, { { 0x48, 0x49, 0x5D, 0x78, 0xE2, 0xF1, 0x0D, 0x87, 0xEE, 0xEE, 0xD1, 0xA1, 0xC6, 0x64, 0xCA, 0x13 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData07Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData07Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000042, 0x00000ABE, { { 0xFE, 0xA9, 0x5D, 0x87, 0xAF, 0x55, 0x04, 0x92, 0x41, 0xD3, 0xAD, 0x1D, 0xFF, 0x03, 0x81, 0x3C } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData08Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData08Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000021, 0x000004D8, { { 0x4E, 0xA7, 0xCC, 0x0B, 0x1B, 0x48, 0x22, 0x09, 0x33, 0xF7, 0x23, 0xF1, 0xF5, 0x9F, 0xA5, 0x7B } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData09Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData09Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000058, 0x000004BE, { { 0xF6, 0xEA, 0xA0, 0x7F, 0x54, 0x61, 0x79, 0x4C, 0x71, 0xD7, 0x9B, 0xA6, 0xC3, 0x45, 0xEE, 0x3E } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData10Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData10Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000009A, 0x00000FC4, { { 0xA9, 0xFB, 0x31, 0x55, 0xB8, 0x28, 0x63, 0xC3, 0x4B, 0x9E, 0x7D, 0x41, 0xC7, 0x1F, 0x2F, 0xBD } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData11Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData11Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x000000C6, 0x0000166B, { { 0xCC, 0x16, 0x50, 0xFF, 0xFF, 0xD5, 0xAE, 0x03, 0x40, 0xA3, 0x9A, 0x1F, 0xF8, 0x8E, 0x23, 0x7A } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData12Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData12Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x000000FD, 0x00001A69, { { 0x6A, 0x80, 0x89, 0x7E, 0xFC, 0xE4, 0x01, 0xF5, 0xA2, 0x11, 0xE7, 0x26, 0x20, 0x96, 0x62, 0x7B } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData13Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData13Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x000000FD, 0x00001886, { { 0xF9, 0x5B, 0x62, 0xDD, 0xAB, 0x14, 0x35, 0x77, 0x53, 0x05, 0xDB, 0xC5, 0xFD, 0x4D, 0x4F, 0x12 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData14Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData14Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000108, 0x00001895, { { 0x22, 0xA1, 0x88, 0x69, 0xF9, 0x1C, 0xA2, 0x64, 0x44, 0xCD, 0x00, 0xFA, 0xB1, 0x94, 0xEB, 0x3A } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData15Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData15Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x000000D1, 0x000016E5, { { 0xD8, 0xE9, 0xA5, 0xEE, 0x54, 0x1B, 0x3E, 0x32, 0xDA, 0x78, 0x90, 0xC2, 0x54, 0xFC, 0xD5, 0x39 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData16Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData16Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000008F, 0x00000C69, { { 0xBC, 0x41, 0xE5, 0xAF, 0x89, 0xE2, 0x54, 0x12, 0x9E, 0xB0, 0x5F, 0x28, 0xFF, 0x92, 0x9D, 0x89 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData17Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData17Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x000000DC, 0x0000170D, { { 0x7A, 0x7B, 0x74, 0xCB, 0x68, 0xC2, 0xFF, 0xC7, 0xBE, 0x47, 0xE9, 0x43, 0xF7, 0x15, 0x8D, 0x59 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData18Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData18Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000134, 0x00002651, { { 0x71, 0x26, 0x47, 0x0D, 0x7C, 0x96, 0x45, 0x0B, 0x82, 0xD0, 0x37, 0xB9, 0xD4, 0xD0, 0x84, 0xFC } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData19Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData19Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000004D, 0x000009C3, { { 0xDA, 0x96, 0xDF, 0x16, 0xEB, 0x5D, 0x49, 0xA4, 0x3F, 0xD3, 0x31, 0xBE, 0x49, 0x72, 0xF2, 0x71 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleSeqData20Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleSeqData20Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000021, 0x000003D8, { { 0xD9, 0xC8, 0x58, 0x4B, 0x7D, 0x79, 0x86, 0xCB, 0xEB, 0x77, 0xC2, 0xD4, 0xB7, 0xB4, 0xE9, 0x6A } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleShapes00Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleShapes00Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000018, 0x0000071C, { { 0xE8, 0x67, 0xCB, 0x76, 0x6D, 0x49, 0xC2, 0x05, 0x0D, 0xAD, 0xB6, 0x83, 0x35, 0xB3, 0xBE, 0xE5 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleShapes03Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleShapes03Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000012, 0x00000571, { { 0x91, 0xEC, 0xAC, 0x12, 0x08, 0x33, 0xDA, 0x7C, 0xBD, 0x51, 0x64, 0xE3, 0xAE, 0x43, 0x75, 0x14 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleShapes07Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleShapes07Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000018, 0x00000166, { { 0xED, 0x6E, 0x0C, 0x85, 0x13, 0x6F, 0xAC, 0xEB, 0xCA, 0x74, 0x2E, 0x2D, 0x0E, 0xCE, 0x17, 0xD6 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleShapes09Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleShapes09Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000036, 0x00000898, { { 0xEB, 0xB0, 0xD9, 0xC4, 0xB6, 0xBC, 0xE3, 0xAF, 0xB2, 0x5D, 0xE3, 0xCE, 0xF7, 0x26, 0x07, 0xE5 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2FinaleShapes10Provider[] = {
+const ExtractEntrySearchData kEoB2FinaleShapes10Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000018, 0x0000017F, { { 0x0F, 0x37, 0x94, 0xA6, 0xCE, 0x23, 0xE3, 0x2E, 0x5E, 0x2B, 0x78, 0x5B, 0x66, 0xC8, 0xE5, 0x96 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2NpcShapeDataProvider[] = {
+const ExtractEntrySearchData kEoB2NpcShapeDataProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000018, 0x0000045D, { { 0x69, 0xE0, 0x5E, 0x86, 0xEB, 0x7D, 0x25, 0x95, 0xC2, 0xA0, 0xE9, 0xD5, 0x3A, 0x4A, 0x65, 0xBC } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseClassModifierFlagsProvider[] = {
+const ExtractEntrySearchData kEoBBaseClassModifierFlagsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000000F, 0x00000059, { { 0x17, 0x2B, 0x23, 0x14, 0x0F, 0x9D, 0x94, 0xD3, 0xBF, 0x94, 0x83, 0x0B, 0x79, 0xDB, 0xC0, 0xA9 } } } }, // EOB 1
 	{ UNK_LANG, kPlatformUnknown, { 0x0000000F, 0x00000083, { { 0x54, 0x68, 0xF4, 0x07, 0x3E, 0x2A, 0xD4, 0x06, 0xF3, 0x10, 0x88, 0x6C, 0xE3, 0x34, 0x08, 0x30 } } } }, // EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMonsterStepTable01Provider[] = {
+const ExtractEntrySearchData kEoBBaseMonsterStepTable01Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000004, 0x00000200, { { 0x26, 0x86, 0x10, 0x04, 0xC1, 0x48, 0xDD, 0xC0, 0x9F, 0x92, 0xD6, 0x20, 0x38, 0x36, 0xE2, 0xDD } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMonsterStepTable02Provider[] = {
+const ExtractEntrySearchData kEoBBaseMonsterStepTable02Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000008, 0x00000400, { { 0x6E, 0x53, 0x3C, 0x7A, 0x11, 0x46, 0x8B, 0xDC, 0x73, 0x24, 0xF8, 0x13, 0xCB, 0x6C, 0x9B, 0xE6 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMonsterStepTable1Provider[] = {
+const ExtractEntrySearchData kEoBBaseMonsterStepTable1Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000400, { { 0x8B, 0x4C, 0x6B, 0x86, 0x93, 0xDA, 0x82, 0x1B, 0x04, 0x23, 0x92, 0x5B, 0x79, 0xB9, 0xFB, 0x06 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMonsterStepTable2Provider[] = {
+const ExtractEntrySearchData kEoBBaseMonsterStepTable2Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000601, { { 0xE4, 0x36, 0x12, 0x93, 0x44, 0xDE, 0x6E, 0xA0, 0x4B, 0x98, 0x4B, 0x47, 0x87, 0xE3, 0x40, 0xD4 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMonsterStepTable3Provider[] = {
+const ExtractEntrySearchData kEoBBaseMonsterStepTable3Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000010, 0x000007F8, { { 0x00, 0x0C, 0xB0, 0xDA, 0xE1, 0xC8, 0x45, 0x11, 0x57, 0xE4, 0x72, 0xD2, 0x32, 0xC6, 0x16, 0x2B } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMonsterCloseAttPosTable1Provider[] = {
+const ExtractEntrySearchData kEoBBaseMonsterCloseAttPosTable1Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000004, 0x00000006, { { 0x4F, 0x9D, 0x50, 0xDA, 0xA1, 0x75, 0xB0, 0xD5, 0x90, 0xCA, 0xFF, 0x3E, 0xB5, 0xE8, 0x0D, 0xAA } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMonsterCloseAttPosTable21Provider[] = {
+const ExtractEntrySearchData kEoBBaseMonsterCloseAttPosTable21Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000008, 0x0000000C, { { 0x6A, 0xED, 0x15, 0xCE, 0x69, 0x54, 0x7D, 0x7B, 0x6D, 0xCE, 0xC7, 0x2A, 0x01, 0xD7, 0xDC, 0xB0 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMonsterCloseAttPosTable22Provider[] = {
+const ExtractEntrySearchData kEoBBaseMonsterCloseAttPosTable22Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000018, { { 0x6D, 0xB9, 0x69, 0x4A, 0xE3, 0x72, 0x03, 0x5B, 0x5A, 0xBB, 0x15, 0x4A, 0xDA, 0xFB, 0x99, 0x87 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMonsterCloseAttUnkTableProvider[] = {////
+const ExtractEntrySearchData kEoBBaseMonsterCloseAttUnkTableProvider[] = {////
 	{ UNK_LANG, kPlatformUnknown, { 0x0000000C, 0x000007FE, { { 0xF0, 0xCB, 0x3A, 0x53, 0xDD, 0x59, 0x04, 0x87, 0x6F, 0x1B, 0x5A, 0x13, 0xBA, 0x78, 0x62, 0xEC } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMonsterCloseAttChkTable1Provider[] = {
+const ExtractEntrySearchData kEoBBaseMonsterCloseAttChkTable1Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000008, { { 0x93, 0x27, 0x19, 0xA7, 0xA7, 0x49, 0x0E, 0xC9, 0xED, 0x5C, 0x8F, 0x9F, 0xC2, 0x34, 0x62, 0x07 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMonsterCloseAttChkTable2Provider[] = {
+const ExtractEntrySearchData kEoBBaseMonsterCloseAttChkTable2Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000008, { { 0xEB, 0xF0, 0x27, 0x7E, 0xA8, 0x09, 0x3A, 0x95, 0x3B, 0x71, 0x2A, 0x43, 0x2E, 0xCF, 0x22, 0x0B } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMonsterCloseAttDstTable1Provider[] = {
+const ExtractEntrySearchData kEoBBaseMonsterCloseAttDstTable1Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000018, { { 0x1E, 0xC9, 0x6C, 0x5D, 0xDF, 0xD4, 0xC0, 0x87, 0xAD, 0xEE, 0x86, 0x29, 0xD5, 0x3E, 0x8D, 0xB4 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMonsterCloseAttDstTable2Provider[] = {
+const ExtractEntrySearchData kEoBBaseMonsterCloseAttDstTable2Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000078, { { 0x4C, 0xA8, 0x2A, 0x53, 0xB3, 0xAA, 0x52, 0x96, 0x1D, 0xE8, 0x37, 0xDB, 0x4A, 0x77, 0xD8, 0x5B } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMonsterProximityTableProvider[] = {
+const ExtractEntrySearchData kEoBBaseMonsterProximityTableProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000020, 0x00000030, { { 0x25, 0xFC, 0xA3, 0xEB, 0x44, 0x93, 0x9B, 0x33, 0xB5, 0x86, 0xC4, 0xCB, 0x17, 0xEF, 0x2D, 0x47 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseFindBlockMonstersTableProvider[] = {
+const ExtractEntrySearchData kEoBBaseFindBlockMonstersTableProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000040, 0x00000088, { { 0x6F, 0xEE, 0x8B, 0x4C, 0x21, 0xF0, 0xC6, 0x4F, 0x1D, 0x05, 0x95, 0x41, 0xD7, 0xD6, 0x52, 0x66 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMonsterDirChangeTableProvider[] = {
+const ExtractEntrySearchData kEoBBaseMonsterDirChangeTableProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000030, 0x0000180C, { { 0xCD, 0xBB, 0xFD, 0xAB, 0xFB, 0x1D, 0x5C, 0x0F, 0xA2, 0xAC, 0x32, 0xA9, 0xA1, 0x93, 0x2D, 0x1C } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseMonsterDistAttStringsProvider[] = {
+const ExtractEntrySearchData kEoBBaseMonsterDistAttStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000076, 0x00002965, { { 0x1A, 0x22, 0x50, 0x04, 0x27, 0x05, 0xE9, 0x61, 0xF9, 0x0A, 0xF0, 0x50, 0x01, 0x0E, 0x65, 0xB4 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000008C, 0x00003274, { { 0xE7, 0x24, 0x17, 0x13, 0x4F, 0xB3, 0xF9, 0xB7, 0x90, 0xFA, 0x3D, 0xFF, 0xA7, 0xFB, 0x3F, 0x1F } } } },
 	{ EN_ANY, kPlatformUnknown, { 0x00000054, 0x00001D03, { { 0xEB, 0x07, 0xD4, 0x22, 0xFD, 0xA0, 0x77, 0x80, 0x22, 0x04, 0x2E, 0x27, 0x7F, 0x64, 0x99, 0x4E } } } },
@@ -3158,92 +3158,92 @@ const ExtractEntrySearchData kEobBaseMonsterDistAttStringsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseEncodeMonsterDefsProvider[] = {
+const ExtractEntrySearchData kEoBBaseEncodeMonsterDefsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000150, 0x00001ACB, { { 0x73, 0x67, 0x5B, 0x64, 0x22, 0xDB, 0x08, 0x3A, 0xCD, 0xEB, 0x30, 0x28, 0xBD, 0xAD, 0xF8, 0x9B } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEobBaseNpcPresetsProvider[] = {
+const ExtractEntrySearchData kEoBBaseNpcPresetsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000088B, 0x000038D0, { { 0x2E, 0xAE, 0xF0, 0x2A, 0x71, 0x6F, 0x7C, 0x5C, 0xF5, 0xAF, 0xB8, 0xBB, 0x47, 0xE5, 0xB6, 0xC3 } } } }, // EOB 1
 	{ UNK_LANG, kPlatformUnknown, { 0x00000816, 0x00002C8E, { { 0xAB, 0xEE, 0x18, 0x0E, 0x59, 0xF6, 0xE0, 0x26, 0x93, 0xAB, 0x3B, 0x23, 0x29, 0x7A, 0x2C, 0x97 } } } }, // EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2Npc1StringsProvider[] = {
+const ExtractEntrySearchData kEoB2Npc1StringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000000B, 0x000003B9, { { 0xB1, 0x67, 0x80, 0x21, 0x92, 0xDD, 0xFA, 0x4C, 0x4D, 0x64, 0x7C, 0x05, 0x08, 0xDC, 0x55, 0xFD } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000000D, 0x0000049E, { { 0x2D, 0x78, 0xF6, 0x20, 0x30, 0xEC, 0x62, 0x6E, 0x58, 0xF7, 0xC7, 0x6D, 0xD7, 0xBD, 0x70, 0x76 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2Npc2StringsProvider[] = {
+const ExtractEntrySearchData kEoB2Npc2StringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000012, 0x0000064C, { { 0xB0, 0x66, 0x0D, 0xDE, 0x16, 0xEB, 0x5E, 0x51, 0xAF, 0x4D, 0x19, 0xD1, 0x1E, 0x0B, 0xCB, 0xD6 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000018, 0x000008FF, { { 0x59, 0x29, 0x01, 0x6F, 0xF0, 0x49, 0xC8, 0x57, 0x3E, 0x70, 0x01, 0x7E, 0x5E, 0xF2, 0xEB, 0x35 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2MonsterDustStringsProvider[] = {
+const ExtractEntrySearchData kEoB2MonsterDustStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000001F, 0x00000AD7, { { 0x2B, 0x66, 0x27, 0xFD, 0xC6, 0x17, 0x0B, 0x6B, 0xFC, 0x7D, 0x7F, 0xD2, 0xC4, 0x12, 0x8F, 0x33 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000001F, 0x00000A91, { { 0x1D, 0x7D, 0xEE, 0xB8, 0x9B, 0x37, 0x2E, 0x64, 0x13, 0xB6, 0x39, 0xED, 0x88, 0xB6, 0x8B, 0xD7 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2DreamStepsProvider[] = {
+const ExtractEntrySearchData kEoB2DreamStepsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000000E, 0x00000114, { { 0x27, 0x32, 0xCB, 0x89, 0x27, 0xC5, 0xDD, 0x91, 0xBE, 0x97, 0x62, 0xF5, 0x76, 0xF7, 0xCD, 0x25 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2KheldranStringsProvider[] = {
+const ExtractEntrySearchData kEoB2KheldranStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000001A, 0x00000887, { { 0xA6, 0xB4, 0x45, 0x1B, 0x33, 0x54, 0x36, 0xAD, 0x1D, 0xB1, 0xDA, 0xC3, 0x12, 0x85, 0x3C, 0x58 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000012, 0x00000511, { { 0xEE, 0x21, 0xA8, 0x6E, 0xF7, 0xEC, 0x9A, 0x8D, 0xBA, 0x8D, 0xE3, 0x4A, 0x17, 0x15, 0xCA, 0x8C } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2HornStringsProvider[] = {
+const ExtractEntrySearchData kEoB2HornStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x0000009A, 0x00003541, { { 0xA5, 0x4D, 0x88, 0xAC, 0x1C, 0xCD, 0x57, 0xD4, 0x1E, 0x9F, 0xAE, 0x13, 0x46, 0xAD, 0xA0, 0x22 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x000000AB, 0x00003B6C, { { 0x36, 0x34, 0xB3, 0xB1, 0x55, 0x66, 0x7A, 0x90, 0x97, 0x01, 0xDC, 0x4A, 0xAF, 0x17, 0x6B, 0x5A } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2HornSoundsProvider[] = {
+const ExtractEntrySearchData kEoB2HornSoundsProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000004, 0x00000106, { { 0x3E, 0x7B, 0x96, 0xFD, 0xCA, 0x4E, 0xA7, 0xA6, 0xB8, 0x82, 0x67, 0xCF, 0x93, 0x86, 0xE4, 0x45 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2WallOfForceDsXProvider[] = {
+const ExtractEntrySearchData kEoB2WallOfForceDsXProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000024, 0x00000D67, { { 0x51, 0xCF, 0xAB, 0x1E, 0xB4, 0xE0, 0xE3, 0x44, 0x29, 0xD1, 0xDC, 0x82, 0xCD, 0x08, 0x50, 0xF5 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2WallOfForceDsYProvider[] = {
+const ExtractEntrySearchData kEoB2WallOfForceDsYProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000003, 0x00000048, { { 0x45, 0xFC, 0xEA, 0x8C, 0x34, 0xD7, 0xBE, 0x74, 0x05, 0x03, 0xE6, 0x94, 0x34, 0xB5, 0x45, 0x4D } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2WallOfForceNumWProvider[] = {
+const ExtractEntrySearchData kEoB2WallOfForceNumWProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000003, 0x00000006, { { 0x52, 0x89, 0xDF, 0x73, 0x7D, 0xF5, 0x73, 0x26, 0xFC, 0xDD, 0x22, 0x59, 0x7A, 0xFB, 0x1F, 0xAC } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2WallOfForceNumHProvider[] = {
+const ExtractEntrySearchData kEoB2WallOfForceNumHProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000003, 0x00000011, { { 0x33, 0x86, 0x06, 0xBE, 0x8D, 0xC8, 0x37, 0x2D, 0x0F, 0x61, 0x97, 0xA4, 0x26, 0xA9, 0xBC, 0x60 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kEob2WallOfForceShpIdProvider[] = {
+const ExtractEntrySearchData kEoB2WallOfForceShpIdProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000003, 0x00000006, { { 0x77, 0xAE, 0x9B, 0x52, 0x9E, 0xF7, 0xEB, 0x48, 0xA8, 0x5E, 0xED, 0xC2, 0x08, 0x53, 0xCE, 0x3C } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolIngamePakFilesProvider[] = {
+const ExtractEntrySearchData kLoLIngamePakFilesProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000088, 0x0000224F, { { 0xDA, 0x24, 0x18, 0xA3, 0xEF, 0x16, 0x70, 0x8F, 0xA8, 0xC2, 0x2E, 0xC2, 0xED, 0x39, 0x03, 0xD1 } } } },
 	{ UNK_LANG, kPlatformPC98, { 0x00000084, 0x00002125, { { 0x7A, 0x89, 0xE2, 0x36, 0xEC, 0x6F, 0x52, 0x2B, 0xEF, 0xBA, 0x3D, 0x28, 0x54, 0xDA, 0xFB, 0x72 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolCharacterDefsProvider[] = {
+const ExtractEntrySearchData kLoLCharacterDefsProvider[] = {
 	{ RU_RUS, kPlatformPC, { 0x00000492, 0x000052BA, { { 0x52, 0x29, 0x0D, 0x49, 0xFD, 0x17, 0xD7, 0x70, 0x6D, 0xCA, 0xEB, 0xB6, 0x7E, 0xFA, 0xBE, 0x08 } } } }, // floppy
 	{ EN_ANY, kPlatformPC, { 0x00000492, 0x000046B0, { { 0x7A, 0x94, 0x8B, 0xC6, 0xF7, 0xF1, 0x2F, 0xF3, 0xBC, 0x1B, 0x0B, 0x4E, 0x00, 0xC9, 0x44, 0x58 } } } }, // floppy
 	{ DE_DEU, kPlatformPC, { 0x00000492, 0x000047FD, { { 0x8C, 0x0B, 0x8B, 0xCE, 0xE0, 0xB0, 0x8F, 0xA9, 0x06, 0xC3, 0x98, 0xE6, 0x2E, 0x09, 0xB6, 0x93 } } } }, // floppy
@@ -3257,7 +3257,7 @@ const ExtractEntrySearchData kLolCharacterDefsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolIngameSfxFilesProvider[] = {
+const ExtractEntrySearchData kLoLIngameSfxFilesProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x000008F2, 0x0001E5B6, { { 0x63, 0x5E, 0x37, 0xAA, 0x27, 0x80, 0x4C, 0x85, 0xB1, 0x9D, 0x7B, 0x1D, 0x64, 0xA3, 0xEB, 0x97 } } } }, // floppy
 	{ UNK_LANG, kPlatformPC, { 0x000008F2, 0x0001E5B7, { { 0x9E, 0xC8, 0xE8, 0x19, 0x2F, 0x58, 0x0B, 0xC7, 0x2D, 0x41, 0x72, 0xE7, 0xF4, 0x80, 0x03, 0xCB } } } }, // CD
 	{ UNK_LANG, kPlatformPC98, { 0x000008EF, 0x0001E585, { { 0x85, 0x81, 0x5C, 0xA4, 0x34, 0x44, 0xF4, 0x58, 0xF9, 0x82, 0xEE, 0x0F, 0x6A, 0x0D, 0xA2, 0x7F } } } },
@@ -3265,185 +3265,185 @@ const ExtractEntrySearchData kLolIngameSfxFilesProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolIngameSfxIndexProvider[] = {
+const ExtractEntrySearchData kLoLIngameSfxIndexProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x000003E8, 0x0000E8D2, { { 0x19, 0x39, 0x17, 0xED, 0xAE, 0xDC, 0x7A, 0xAC, 0x45, 0x5F, 0x2D, 0xCD, 0x65, 0x8D, 0xAD, 0xAE } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolMusicTrackMapProvider[] = {
+const ExtractEntrySearchData kLoLMusicTrackMapProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x000000F0, 0x0000210D, { { 0x55, 0x25, 0x3E, 0x35, 0xD2, 0xD8, 0x13, 0xE3, 0x1D, 0xB1, 0xB3, 0x00, 0x2E, 0x17, 0x91, 0x2F } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolIngameGMSfxIndexProvider[] = {
+const ExtractEntrySearchData kLoLIngameGMSfxIndexProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x000000FA, 0x00006281, { { 0x25, 0x89, 0xB0, 0x3B, 0x12, 0x09, 0x02, 0xF6, 0xFE, 0x76, 0xD5, 0xC9, 0x5B, 0x88, 0xAC, 0xAA } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolIngameMT32SfxIndexProvider[] = {
+const ExtractEntrySearchData kLoLIngameMT32SfxIndexProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x000000FA, 0x00006579, { { 0x16, 0x40, 0x1C, 0x09, 0x69, 0xA9, 0x0D, 0x6D, 0x4B, 0x0C, 0x99, 0xF0, 0x40, 0x5D, 0xBB, 0x6E } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolIngamePcSpkSfxIndexProvider[] = {
+const ExtractEntrySearchData kLoLIngamePcSpkSfxIndexProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x000000FA, 0x00005EFC, { { 0xA3, 0x5C, 0x69, 0xED, 0x13, 0xEC, 0x08, 0x0E, 0xFA, 0x72, 0x83, 0x0D, 0xD7, 0x8D, 0x9C, 0x70 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolSpellPropertiesProvider[] = {
+const ExtractEntrySearchData kLoLSpellPropertiesProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000118, 0x00000B06, { { 0x27, 0x69, 0x53, 0x01, 0xA0, 0xE3, 0x76, 0xAA, 0x33, 0xA4, 0x52, 0x11, 0x52, 0xB1, 0x0E, 0xDA } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolGameShapeMapProvider[] = {
+const ExtractEntrySearchData kLoLGameShapeMapProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000114, 0x000038D3, { { 0xB2, 0x8A, 0x5D, 0x9A, 0x51, 0x63, 0x4D, 0x65, 0xE4, 0xF5, 0xBA, 0x88, 0x70, 0x6C, 0xA6, 0xF8 } } } }, // floppy + PC98
 	{ UNK_LANG, kPlatformPC, { 0x00000114, 0x00003B97, { { 0x29, 0xE5, 0x0F, 0x51, 0xF0, 0x10, 0x35, 0x3E, 0x70, 0x3A, 0xAA, 0xFE, 0xD7, 0xD5, 0xAA, 0x9F } } } }, // CD
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolSceneItemOffsProvider[] = {
+const ExtractEntrySearchData kLoLSceneItemOffsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000008, 0x00000300, { { 0x69, 0x80, 0x5A, 0x3E, 0x63, 0xC1, 0x04, 0x60, 0x09, 0x2F, 0x49, 0xD7, 0x26, 0x32, 0xAA, 0xE2 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolCharInvIndexProvider[] = {
+const ExtractEntrySearchData kLoLCharInvIndexProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000000A, 0x00000006, { { 0x19, 0x79, 0x4E, 0xFC, 0x05, 0x14, 0x89, 0x23, 0xEB, 0xCA, 0x94, 0x50, 0xE8, 0xD3, 0x81, 0x24 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolCharInvDefsProvider[] = {
+const ExtractEntrySearchData kLoLCharInvDefsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000058, 0x00001D7A, { { 0x25, 0xE4, 0xEB, 0x6D, 0xBE, 0xEA, 0xBD, 0x9A, 0x9F, 0xA5, 0x9E, 0xEB, 0x3D, 0x03, 0x1D, 0x72 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolCharDefsManProvider[] = {
+const ExtractEntrySearchData kLoLCharDefsManProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000012, 0x0000003D, { { 0xEB, 0x82, 0x32, 0x9D, 0x76, 0xC8, 0x3D, 0x5E, 0x8C, 0x26, 0x53, 0xDF, 0xC1, 0xFD, 0x0F, 0xC5 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolCharDefsWomanProvider[] = {
+const ExtractEntrySearchData kLoLCharDefsWomanProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000012, 0x0000003D, { { 0xEB, 0x82, 0x32, 0x9D, 0x76, 0xC8, 0x3D, 0x5E, 0x8C, 0x26, 0x53, 0xDF, 0xC1, 0xFD, 0x0F, 0xC5 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolCharDefsKieranProvider[] = {
+const ExtractEntrySearchData kLoLCharDefsKieranProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000012, 0x000002E3, { { 0xBF, 0xB1, 0x0F, 0x40, 0xBF, 0xA1, 0xD0, 0x2B, 0xC9, 0x80, 0x35, 0x40, 0xA9, 0xA3, 0x01, 0xC8 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolCharDefsAkshelProvider[] = {
+const ExtractEntrySearchData kLoLCharDefsAkshelProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000012, 0x000002FB, { { 0x47, 0x3C, 0x07, 0x15, 0x20, 0xE6, 0x90, 0x59, 0x55, 0xF2, 0xA7, 0xC3, 0x27, 0x22, 0xAB, 0xDC } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolExpRequirementsProvider[] = {
+const ExtractEntrySearchData kLoLExpRequirementsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x00000C0A, { { 0x3F, 0x36, 0xFA, 0xE3, 0xB0, 0x76, 0x5E, 0xFF, 0xE9, 0xBA, 0xDF, 0xD0, 0x9D, 0xFF, 0xDD, 0x27 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolMonsterModifiersProvider[] = {
+const ExtractEntrySearchData kLoLMonsterModifiersProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000018, 0x000002C6, { { 0x38, 0x9A, 0x8B, 0x50, 0xD2, 0x9B, 0x95, 0x38, 0x91, 0x02, 0xA9, 0xBE, 0x78, 0xE5, 0x89, 0x65 } } } }, // floppy + PC98
 	{ UNK_LANG, kPlatformPC, { 0x00000018, 0x000002EE, { { 0x4E, 0x37, 0x56, 0xE3, 0x42, 0xB3, 0x15, 0x2C, 0x7E, 0x9B, 0x7E, 0x50, 0x32, 0x91, 0x55, 0xBE } } } }, // CD
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolMonsterShiftOffsetsProvider[] = {
+const ExtractEntrySearchData kLoLMonsterShiftOffsetsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000020, 0x00000803, { { 0x30, 0x55, 0x74, 0x0D, 0xC7, 0x3B, 0xD9, 0x5C, 0x26, 0xF0, 0x4E, 0x8F, 0xE4, 0x4D, 0xCB, 0x2A } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolMonsterDirFlagsProvider[] = {
+const ExtractEntrySearchData kLoLMonsterDirFlagsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000080, { { 0xE5, 0xA1, 0xE3, 0xCE, 0xA0, 0x5F, 0x15, 0xE9, 0x5B, 0x28, 0x90, 0xC0, 0xDF, 0x21, 0xEC, 0x24 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolMonsterScaleYProvider[] = {
+const ExtractEntrySearchData kLoLMonsterScaleYProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000001E, 0x00000982, { { 0xE2, 0x71, 0x5F, 0x57, 0x4A, 0x8F, 0x50, 0xDB, 0x3E, 0xDA, 0xAB, 0x10, 0xEB, 0xDB, 0x0D, 0x14 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolMonsterScaleXProvider[] = {
+const ExtractEntrySearchData kLoLMonsterScaleXProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000020, 0x00000918, { { 0xF6, 0x14, 0xE6, 0x48, 0x4E, 0x5B, 0x43, 0xCC, 0xCE, 0x4E, 0x98, 0x71, 0x5A, 0xC2, 0x00, 0x1E } } } },
 	{ UNK_LANG, kPlatformPC98, { 0x0000001D, 0x000008D2, { { 0x1C, 0x25, 0x38, 0xE2, 0xBB, 0xB2, 0xDB, 0x93, 0x1B, 0x25, 0xB6, 0x89, 0xA9, 0x9B, 0x0A, 0xFE } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolMonsterScaleWHProvider[] = {
+const ExtractEntrySearchData kLoLMonsterScaleWHProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000082, 0x00001D2A, { { 0x85, 0x7E, 0x18, 0xDD, 0x74, 0x1C, 0x62, 0x6F, 0xF4, 0xE5, 0xAF, 0x65, 0xEC, 0x6A, 0x90, 0xAD } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolFlyingObjectShpProvider[] = {
+const ExtractEntrySearchData kLoLFlyingObjectShpProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000082, 0x00000252, { { 0xDE, 0x9D, 0x89, 0xAF, 0x0F, 0x50, 0x14, 0x60, 0x68, 0xAF, 0x19, 0xD8, 0x54, 0x8A, 0x36, 0x27 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolInventoryDescProvider[] = {
+const ExtractEntrySearchData kLoLInventoryDescProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x0000082D, { { 0x86, 0xB4, 0xB9, 0x50, 0xB6, 0xDA, 0x29, 0xB2, 0xC0, 0x0D, 0x34, 0x3F, 0x8D, 0x88, 0xAA, 0xE4 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolLevelShpListProvider[] = {
+const ExtractEntrySearchData kLoLLevelShpListProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000007F, 0x00002090, { { 0x17, 0x31, 0x8A, 0xB5, 0x9B, 0x3A, 0xDA, 0x16, 0x9E, 0xE3, 0xD1, 0x5F, 0xB4, 0x7B, 0xB2, 0x25 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolLevelDatListProvider[] = {
+const ExtractEntrySearchData kLoLLevelDatListProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000007F, 0x00001FB8, { { 0xF6, 0xE9, 0x98, 0x79, 0x51, 0xCA, 0xA0, 0x35, 0xE4, 0xD0, 0xA1, 0xCD, 0x23, 0x89, 0x7D, 0x11 } } } }, // floppy + PC98
 	{ UNK_LANG, kPlatformPC, { 0x000000FF, 0x000047EC, { { 0x0D, 0xA5, 0xFD, 0x8A, 0x33, 0xDB, 0x93, 0x43, 0xE2, 0x57, 0x35, 0xEC, 0xA6, 0xCF, 0x7A, 0xA1 } } } }, // CD
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolCompassDefsProvider[] = {
+const ExtractEntrySearchData kLoLCompassDefsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000100, 0x000030EF, { { 0x6F, 0xF0, 0x46, 0x6E, 0xB3, 0x72, 0xCF, 0xC7, 0xE3, 0xAF, 0xBE, 0x63, 0xA1, 0x1C, 0x33, 0x20 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolItemPricesProvider[] = {
+const ExtractEntrySearchData kLoLItemPricesProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000005C, 0x00001251, { { 0x18, 0x62, 0x5E, 0xE2, 0xE4, 0x2A, 0xB0, 0xA0, 0x8B, 0x8D, 0x9D, 0x07, 0x5F, 0x83, 0x53, 0xF7 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolStashSetupProvider[] = {
+const ExtractEntrySearchData kLoLStashSetupProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000000C, 0x0000001E, { { 0x1C, 0x93, 0x66, 0x56, 0xDB, 0xD7, 0xA4, 0xB3, 0xE7, 0x2F, 0xEA, 0x88, 0xE2, 0xC8, 0x79, 0xD0 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscWallsProvider[] = {
+const ExtractEntrySearchData kLoLDscWallsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000024, 0x00000A2A, { { 0xAC, 0x4E, 0x73, 0x2C, 0xB0, 0xEE, 0x24, 0x0E, 0x66, 0x8D, 0x48, 0xE5, 0xCA, 0x6B, 0x7F, 0x7F } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolEobCommonDscShapeIndexProvider[] = {
+const ExtractEntrySearchData kRpgCommonDscShapeIndexProvider[] = {
 	// LOL:
 	{ UNK_LANG, kPlatformUnknown, { 0x00000024, 0x00000728, { { 0x14, 0xBA, 0x6D, 0x5C, 0x7D, 0x20, 0x0D, 0x35, 0xA7, 0xB0, 0x8D, 0x2F, 0x1D, 0x2A, 0x49, 0xA4 } } } },
 	// EOB:
@@ -3452,24 +3452,24 @@ const ExtractEntrySearchData kLolEobCommonDscShapeIndexProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscOvlMapProvider[] = {
+const ExtractEntrySearchData kLoLDscOvlMapProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000000A, 0x0000001F, { { 0x9C, 0xF2, 0xCC, 0x48, 0x42, 0xC6, 0x76, 0x83, 0xD3, 0x1A, 0x43, 0x42, 0x7F, 0xEF, 0x19, 0x0F } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscScaleWidthDataProvider[] = {
+const ExtractEntrySearchData kLoLDscScaleWidthDataProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000048, 0x00000ABE, { { 0x28, 0x9A, 0xAA, 0x16, 0xC4, 0xFD, 0x52, 0xA9, 0x76, 0x98, 0x72, 0x0C, 0x2D, 0xE4, 0xB0, 0x57 } } } },
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscScaleHeightDataProvider[] = {
+const ExtractEntrySearchData kLoLDscScaleHeightDataProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000048, 0x000009E8, { { 0x25, 0x35, 0x07, 0xBC, 0xF9, 0x82, 0x8B, 0x5B, 0x67, 0x7C, 0x38, 0xD1, 0xF8, 0x35, 0x81, 0xC7 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolEobCommonDscXProvider[] = {
+const ExtractEntrySearchData kRpgCommonDscXProvider[] = {
 	// LOL
 	{ UNK_LANG, kPlatformUnknown, { 0x00000048, 0x00001468, { { 0x55, 0xC5, 0x30, 0x76, 0x0A, 0xDC, 0xEC, 0xAB, 0x68, 0x9B, 0x61, 0xF0, 0x58, 0x78, 0x56, 0xA6 } } } },
 	// EOB
@@ -3478,32 +3478,32 @@ const ExtractEntrySearchData kLolEobCommonDscXProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscYProvider[] = {
+const ExtractEntrySearchData kLoLDscYProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000024, 0x00000282, { { 0x09, 0x98, 0x3A, 0x33, 0x15, 0xA1, 0x4A, 0xFF, 0x76, 0x19, 0x2B, 0xB1, 0x74, 0x89, 0xF4, 0x37 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolEobCommonDscTileIndexProvider[] = {
+const ExtractEntrySearchData kRpgCommonDscTileIndexProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000012, 0x00000099, { { 0x18, 0xD9, 0x39, 0x27, 0x5B, 0x34, 0xAE, 0x7C, 0xA9, 0xA9, 0xDB, 0x42, 0x49, 0x61, 0x6B, 0x37 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolEobCommonDscUnk2Provider[] = {
+const ExtractEntrySearchData kRpgCommonDscUnk2Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000017, 0x000000D2, { { 0xDE, 0xDA, 0x75, 0x15, 0x2B, 0xDC, 0x90, 0x3F, 0xC9, 0x92, 0x04, 0x01, 0x23, 0x7A, 0xDA, 0x2E } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolEobCommonDscDoorShapeIndexProvider[] = {
+const ExtractEntrySearchData kRpgCommonDscDoorShapeIndexProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000017, 0x0000000A, { { 0x2E, 0xC4, 0xA1, 0x47, 0x7C, 0xAE, 0xAD, 0xD8, 0x8A, 0x72, 0x95, 0x2F, 0x18, 0xC5, 0x08, 0x19 } } } }, // LOL
 	{ UNK_LANG, kPlatformUnknown, { 0x00000020, 0x00000021, { { 0xE3, 0x00, 0x85, 0x1C, 0x13, 0xCE, 0x5D, 0xA7, 0xA2, 0x93, 0x9B, 0x56, 0x1A, 0x0C, 0x43, 0x3E } } } }, // EOB 1
 	{ UNK_LANG, kPlatformUnknown, { 0x00000035, 0x0000000B, { { 0xC2, 0xBC, 0xCA, 0x95, 0x69, 0xE8, 0x3F, 0x1F, 0xC2, 0x1C, 0x37, 0x90, 0x63, 0x8F, 0xE6, 0x1D } } } }, // EOB 2
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolEobCommonDscDimData1Provider[] = {
+const ExtractEntrySearchData kRpgCommonDscDimData1Provider[] = {
 	// LOL
 	{ UNK_LANG, kPlatformUnknown, { 0x00000144, 0x0001007D, { { 0x18, 0x3D, 0xA5, 0xF7, 0x1A, 0x5A, 0x90, 0xA7, 0x4E, 0x66, 0x1A, 0x4E, 0x0C, 0x69, 0x58, 0x31 } } } },
 	// EOB
@@ -3511,91 +3511,91 @@ const ExtractEntrySearchData kLolEobCommonDscDimData1Provider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolEobCommonDscDimData2Provider[] = {
+const ExtractEntrySearchData kRpgCommonDscDimData2Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000288, 0x00001BC2, { { 0x30, 0xD1, 0xD1, 0x35, 0x74, 0x2C, 0x86, 0x81, 0x23, 0xE2, 0x05, 0xCE, 0x75, 0x60, 0x3C, 0x55 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolEobCommonDscBlockMapProvider[] = {
+const ExtractEntrySearchData kRpgCommonDscBlockMapProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000000C, 0x00000012, { { 0x01, 0xEE, 0x32, 0xA6, 0x71, 0x15, 0x8D, 0xFB, 0x33, 0xF2, 0xD6, 0x8A, 0x30, 0x00, 0x10, 0x4B } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolEobCommonDscDimMapProvider[] = {
+const ExtractEntrySearchData kRpgCommonDscDimMapProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000012, 0x00000014, { { 0x4D, 0x53, 0x2E, 0xF2, 0xA3, 0xF9, 0xE2, 0xEC, 0x44, 0xBE, 0x5F, 0x04, 0x91, 0xF8, 0xE1, 0x04 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscOvlIndexProvider[] = {
+const ExtractEntrySearchData kLoLDscOvlIndexProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000028, 0x00000048, { { 0x3E, 0x8E, 0x62, 0xAF, 0xD1, 0x28, 0x39, 0x73, 0x0D, 0xD8, 0x4A, 0xA7, 0xF4, 0xD7, 0x32, 0x25 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolEobCommonDscBlockIndexProvider[] = {
+const ExtractEntrySearchData kRpgCommonDscBlockIndexProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000048, 0x00002200, { { 0xF4, 0x8B, 0x32, 0xC3, 0xD3, 0xFB, 0x46, 0xF2, 0xB8, 0x3A, 0x58, 0x39, 0x94, 0x57, 0x97, 0x4B } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolEobCommonDscDoorY2Provider[] = {
+const ExtractEntrySearchData kRpgCommonDscDoorY2Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000080, 0x00000348, { { 0xC6, 0x58, 0x8B, 0xFE, 0x18, 0x72, 0x47, 0xF1, 0xB6, 0x3A, 0x0F, 0xFB, 0x3D, 0x99, 0x74, 0xD0 } } } }, // LOL
 	{ UNK_LANG, kPlatformUnknown, { 0x00000004, 0x00000046, { { 0x35, 0x36, 0xBC, 0xD8, 0x63, 0x25, 0x31, 0xA9, 0x61, 0x8E, 0xF6, 0x54, 0x4A, 0x79, 0x17, 0xF8 } } } }, // EOB
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscDoorScaleProvider[] = {
+const ExtractEntrySearchData kLoLDscDoorScaleProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000010, 0x0000024C, { { 0x8D, 0x83, 0x26, 0xEE, 0xDC, 0xF7, 0x13, 0xC0, 0xAA, 0x88, 0xC2, 0xAA, 0x66, 0xA7, 0x59, 0x41 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscDoor4Provider[] = {
+const ExtractEntrySearchData kLoLDscDoor4Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000008, 0x00000103, { { 0x29, 0xC0, 0x4B, 0x7F, 0x36, 0x23, 0xBB, 0x38, 0x4C, 0x83, 0xC6, 0x9D, 0xB4, 0x8F, 0x29, 0x2E } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscDoorXProvider[] = {
+const ExtractEntrySearchData kLoLDscDoorXProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000480, 0x0001654D, { { 0x2A, 0x1F, 0xBF, 0xE3, 0xC4, 0xEF, 0x7E, 0xD1, 0x61, 0x51, 0xFE, 0x88, 0x8D, 0x1F, 0x59, 0x70 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolDscDoorYProvider[] = {
+const ExtractEntrySearchData kLoLDscDoorYProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000480, 0x00026666, { { 0x06, 0xBF, 0xA4, 0xD4, 0x6E, 0x29, 0x42, 0xA2, 0xA0, 0x8E, 0x3C, 0x14, 0xF3, 0xD6, 0x3F, 0x87 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolScrollXTopProvider[] = {
+const ExtractEntrySearchData kLoLScrollXTopProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000000A, 0x0000004B, { { 0x18, 0x1E, 0x6E, 0xE9, 0x34, 0xF0, 0x02, 0xC6, 0x57, 0x34, 0xDF, 0x55, 0xD9, 0x39, 0xE8, 0x98 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolScrollYTopProvider[] = {
+const ExtractEntrySearchData kLoLScrollYTopProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000000A, 0x00000022, { { 0xF3, 0x20, 0x5A, 0xC1, 0xBB, 0x0C, 0x79, 0x52, 0x23, 0xC1, 0x36, 0x81, 0x70, 0x2F, 0x92, 0xFC } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolScrollXBottomProvider[] = {
+const ExtractEntrySearchData kLoLScrollXBottomProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000000A, 0x0000004B, { { 0x18, 0x1E, 0x6E, 0xE9, 0x34, 0xF0, 0x02, 0xC6, 0x57, 0x34, 0xDF, 0x55, 0xD9, 0x39, 0xE8, 0x98 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolScrollYBottomProvider[] = {
+const ExtractEntrySearchData kLoLScrollYBottomProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000000A, 0x0000003C, { { 0x5B, 0x4F, 0xB7, 0xB5, 0x55, 0xA2, 0x9A, 0x21, 0xEF, 0xB4, 0x98, 0x47, 0x05, 0x57, 0x49, 0x55 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolButtonDefsProvider[] = {
+const ExtractEntrySearchData kLoLButtonDefsProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x0000082A, 0x0000CAAE, { { 0xC1, 0x83, 0x0D, 0xA0, 0x66, 0x16, 0x3D, 0x31, 0xCE, 0x30, 0x9F, 0x4E, 0x00, 0x65, 0x5A, 0xC8 } } } }, // floppy
 	{ UNK_LANG, kPlatformPC, { 0x0000082A, 0x0000C34E, { { 0x7F, 0x9A, 0x0F, 0x28, 0x1A, 0x8F, 0x03, 0x46, 0x48, 0xEB, 0xC9, 0xB9, 0x23, 0x29, 0x5E, 0x50 } } } }, // floppy
 	{ UNK_LANG, kPlatformPC, { 0x0000082A, 0x0000C47B, { { 0xDF, 0x1A, 0x18, 0x1F, 0x58, 0x05, 0x1F, 0x56, 0xD8, 0x6D, 0xBB, 0x93, 0xEC, 0x35, 0x9D, 0xA5 } } } }, // CD
@@ -3604,110 +3604,110 @@ const ExtractEntrySearchData kLolButtonDefsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolButtonList1Provider[] = {
+const ExtractEntrySearchData kLoLButtonList1Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000050, 0x00000A37, { { 0x0F, 0x73, 0xEC, 0xDD, 0xAB, 0xFF, 0x49, 0x46, 0x5E, 0x8F, 0x0D, 0xC3, 0xE7, 0x1B, 0x89, 0x51 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolButtonList2Provider[] = {
+const ExtractEntrySearchData kLoLButtonList2Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000001E, 0x00000522, { { 0xEA, 0x41, 0x46, 0xE2, 0xFE, 0xAA, 0x7D, 0x5E, 0x89, 0x7F, 0xBF, 0x9B, 0x30, 0x60, 0x74, 0xF3 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolButtonList3Provider[] = {
+const ExtractEntrySearchData kLoLButtonList3Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000004, 0x0000023E, { { 0x70, 0xAA, 0xCA, 0xAC, 0x5C, 0x21, 0xCF, 0xA5, 0xBF, 0x7F, 0x5F, 0xBC, 0xF1, 0x24, 0x8A, 0xAF } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolButtonList4Provider[] = {
+const ExtractEntrySearchData kLoLButtonList4Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000001E, 0x0000054D, { { 0x19, 0x2A, 0xBE, 0x7F, 0x94, 0x10, 0xA0, 0x60, 0x2A, 0x33, 0xD6, 0x11, 0x85, 0xF0, 0xA4, 0xA9 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolButtonList5Provider[] = {
+const ExtractEntrySearchData kLoLButtonList5Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000020, 0x0000045D, { { 0xE3, 0x7C, 0xC2, 0x36, 0x21, 0x46, 0xDB, 0xF3, 0xDD, 0x38, 0x4B, 0x40, 0xE0, 0x35, 0x09, 0xC3 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolButtonList6Provider[] = {
+const ExtractEntrySearchData kLoLButtonList6Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000001C, 0x000004C4, { { 0x21, 0x7C, 0x29, 0x3F, 0x95, 0x6F, 0x91, 0x8C, 0xB2, 0x30, 0x09, 0xA6, 0x7B, 0x48, 0x44, 0x8F } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolButtonList7Provider[] = {
+const ExtractEntrySearchData kLoLButtonList7Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000006, 0x0000021D, { { 0xDC, 0xCE, 0x1B, 0xEB, 0x11, 0x6D, 0xDE, 0x37, 0x17, 0xC8, 0x06, 0x51, 0xC3, 0x0C, 0xCB, 0xA6 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolButtonList8Provider[] = {
+const ExtractEntrySearchData kLoLButtonList8Provider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000004, 0x00000253, { { 0x0C, 0x7B, 0x10, 0x99, 0x93, 0xD0, 0x33, 0xCA, 0xAB, 0x8D, 0x7E, 0x24, 0xE5, 0x7E, 0x6C, 0x91 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolLegendDataProvider[] = {
+const ExtractEntrySearchData kLoLLegendDataProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000858, { { 0x63, 0x5E, 0x60, 0xC7, 0x62, 0x2C, 0x5D, 0x8F, 0x74, 0x71, 0x98, 0xB7, 0x09, 0xD2, 0x51, 0xC7 } } } },
 	{ UNK_LANG, kPlatformUnknown, { 0x0000003C, 0x00000A52, { { 0x81, 0xC5, 0xA4, 0xE7, 0x60, 0xDA, 0xD6, 0x5E, 0x19, 0xAB, 0xF3, 0xC7, 0xDD, 0xDB, 0x92, 0x5E } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolMapCursorOvlProvider[] = {
+const ExtractEntrySearchData kLoLMapCursorOvlProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x00000019, 0x000009CD, { { 0xF6, 0xD2, 0xFA, 0x36, 0x62, 0x95, 0x1D, 0x99, 0x7F, 0x11, 0x5F, 0xA8, 0x4D, 0x47, 0x72, 0x40 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolMapStringIdProvider[] = {
+const ExtractEntrySearchData kLoLMapStringIdProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x0000003C, 0x00000CFB, { { 0xE3, 0xC3, 0x41, 0x06, 0xD1, 0x71, 0x77, 0x78, 0xAD, 0x39, 0xAE, 0x2C, 0x16, 0x21, 0x45, 0xB7 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolSpellbookAnimProvider[] = {
+const ExtractEntrySearchData kLoLSpellbookAnimProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000038, 0x000003A1, { { 0x50, 0xA0, 0xF6, 0xA7, 0x53, 0x96, 0x86, 0x49, 0xB0, 0x8D, 0xA8, 0xB2, 0x2D, 0x9A, 0xE2, 0x1F } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolSpellbookCoordsProvider[] = {
+const ExtractEntrySearchData kLoLSpellbookCoordsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000018, 0x0000018F, { { 0xA5, 0xF6, 0x8A, 0x58, 0x9A, 0xC7, 0x3C, 0x3A, 0xB5, 0x87, 0x89, 0x87, 0x73, 0x51, 0x9B, 0x1B } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolHealShapeFramesProvider[] = {
+const ExtractEntrySearchData kLoLHealShapeFramesProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000050, 0x000000F4, { { 0xC9, 0x6E, 0x39, 0xE1, 0xD7, 0xAD, 0x10, 0x4F, 0xE2, 0xFE, 0xDC, 0xAD, 0x00, 0x9D, 0x41, 0xEF } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolLightningDefsProvider[] = {
+const ExtractEntrySearchData kLoLLightningDefsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000014, 0x00000385, { { 0x68, 0x39, 0x65, 0xCB, 0xA9, 0x80, 0x90, 0xFB, 0xDD, 0x77, 0x0C, 0x76, 0x5A, 0xB5, 0x05, 0x03 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolFireballCoordsProvider[] = {
+const ExtractEntrySearchData kLoLFireballCoordsProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000200, 0x0000FD81, { { 0xB3, 0xE0, 0x6F, 0x89, 0xCD, 0xE5, 0xA9, 0x6A, 0x4B, 0x61, 0x7A, 0x3F, 0x47, 0x26, 0x73, 0x58 } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolCreditsProvider[] = {
+const ExtractEntrySearchData kLoLCreditsProvider[] = {
 	{ JA_JPN , kPlatformPC98, { 0x000005E7, 0x0001A1B0, { { 0x2A, 0xD0, 0x38, 0x84, 0x0C, 0x38, 0xCB, 0x52, 0x5D, 0x82, 0xBE, 0x03, 0x76, 0xFA, 0x0A, 0x4A } } } },
 
 	EXTRACT_END_ENTRY
 };
 
-const ExtractEntrySearchData kLolHistoryProvider[] = {
+const ExtractEntrySearchData kLoLHistoryProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x000001D1, 0x00007F9B, { { 0x25, 0x10, 0x86, 0x40, 0xAC, 0x53, 0xFE, 0x11, 0x4D, 0xE2, 0xD9, 0x35, 0xD6, 0x89, 0xBB, 0x09 } } } },
 
 	EXTRACT_END_ENTRY
@@ -3848,446 +3848,446 @@ const ExtractEntry extractProviders[] = {
 	{ k3ItemMagicTable, k3ItemMagicTableProvider },
 	{ k3ItemStringMap, k3ItemStringMapProvider },	
 	
-	{ kEobBaseChargenStrings1, kEobBaseChargenStrings1Provider },
-	{ kEobBaseChargenStrings2, kEobBaseChargenStrings2Provider },
-	{ kEobBaseChargenStartLevels, kEobBaseChargenStartLevelsProvider },
-	{ kEobBaseChargenStatStrings, kEobBaseChargenStatStringsProvider },
-	{ kEobBaseChargenRaceSexStrings, kEobBaseChargenRaceSexStringsProvider },
-	{ kEobBaseChargenClassStrings, kEobBaseChargenClassStringsProvider },
-	{ kEobBaseChargenAlignmentStrings, kEobBaseChargenAlignmentStringsProvider },
-	{ kEobBaseChargenEnterGameStrings, kEobBaseChargenEnterGameStringsProvider },
-	{ kEobBaseChargenClassMinStats, kEobBaseChargenClassMinStatsProvider },
-	{ kEobBaseChargenRaceMinStats, kEobBaseChargenRaceMinStatsProvider },
-	{ kEobBaseChargenRaceMaxStats, kEobBaseChargenRaceMaxStatsProvider },
-
-	{ kEobBaseSaveThrowTable1, kEobBaseSaveThrowTable1Provider },
-	{ kEobBaseSaveThrowTable2, kEobBaseSaveThrowTable2Provider },
-	{ kEobBaseSaveThrowTable3, kEobBaseSaveThrowTable3Provider },
-	{ kEobBaseSaveThrowTable4, kEobBaseSaveThrowTable4Provider },
-	{ kEobBaseSaveThrwLvlIndex, kEobBaseSaveThrwLvlIndexProvider },
-	{ kEobBaseSaveThrwModDiv, kEobBaseSaveThrwModDivProvider },
-	{ kEobBaseSaveThrwModExt, kEobBaseSaveThrwModExtProvider },
+	{ kEoBBaseChargenStrings1, kEoBBaseChargenStrings1Provider },
+	{ kEoBBaseChargenStrings2, kEoBBaseChargenStrings2Provider },
+	{ kEoBBaseChargenStartLevels, kEoBBaseChargenStartLevelsProvider },
+	{ kEoBBaseChargenStatStrings, kEoBBaseChargenStatStringsProvider },
+	{ kEoBBaseChargenRaceSexStrings, kEoBBaseChargenRaceSexStringsProvider },
+	{ kEoBBaseChargenClassStrings, kEoBBaseChargenClassStringsProvider },
+	{ kEoBBaseChargenAlignmentStrings, kEoBBaseChargenAlignmentStringsProvider },
+	{ kEoBBaseChargenEnterGameStrings, kEoBBaseChargenEnterGameStringsProvider },
+	{ kEoBBaseChargenClassMinStats, kEoBBaseChargenClassMinStatsProvider },
+	{ kEoBBaseChargenRaceMinStats, kEoBBaseChargenRaceMinStatsProvider },
+	{ kEoBBaseChargenRaceMaxStats, kEoBBaseChargenRaceMaxStatsProvider },
+
+	{ kEoBBaseSaveThrowTable1, kEoBBaseSaveThrowTable1Provider },
+	{ kEoBBaseSaveThrowTable2, kEoBBaseSaveThrowTable2Provider },
+	{ kEoBBaseSaveThrowTable3, kEoBBaseSaveThrowTable3Provider },
+	{ kEoBBaseSaveThrowTable4, kEoBBaseSaveThrowTable4Provider },
+	{ kEoBBaseSaveThrwLvlIndex, kEoBBaseSaveThrwLvlIndexProvider },
+	{ kEoBBaseSaveThrwModDiv, kEoBBaseSaveThrwModDivProvider },
+	{ kEoBBaseSaveThrwModExt, kEoBBaseSaveThrwModExtProvider },
 	
-	{ kEobBasePryDoorStrings, kEobBasePryDoorStringsProvider },
-	{ kEobBaseWarningStrings, kEobBaseWarningStringsProvider },
-
-	{ kEobBaseItemSuffixStringsRings, kEobBaseItemSuffixStringsRingsProvider },
-	{ kEobBaseItemSuffixStringsPotions, kEobBaseItemSuffixStringsPotionsProvider },
-	{ kEobBaseItemSuffixStringsWands, kEobBaseItemSuffixStringsWandsProvider },
-
-	{ kEobBaseRipItemStrings, kEobBaseRipItemStringsProvider },
-	{ kEobBaseCursedString, kEobBaseCursedStringProvider },
-	{ kEobBaseEnchantedString, kEobBaseEnchantedStringProvider },
-	{ kEobBaseMagicObjectStrings, kEobBaseMagicObjectStringsProvider },
-	{ kEobBaseMagicObject5String, kEobBaseMagicObject5StringProvider },
-	{ kEobBasePatternSuffix, kEobBasePatternSuffixProvider },
-	{ kEobBasePatternGrFix1, kEobBasePatternGrFix1Provider },
-	{ kEobBasePatternGrFix2, kEobBasePatternGrFix2Provider },
-	{ kEobBaseValidateArmorString, kEobBaseValidateArmorStringProvider },
-	{ kEobBaseValidateCursedString, kEobBaseValidateCursedStringProvider },
-	{ kEobBaseValidateNoDropString, kEobBaseValidateNoDropStringProvider },
-	{ kEobBasePotionStrings, kEobBasePotionStringsProvider },
-	{ kEobBaseWandString, kEobBaseWandStringProvider },
-	{ kEobBaseItemMisuseStrings, kEobBaseItemMisuseStringsProvider },
-
-	{ kEobBaseTakenStrings, kEobBaseTakenStringsProvider },
-	{ kEobBasePotionEffectStrings, kEobBasePotionEffectStringsProvider },
-
-	{ kEobBaseYesNoStrings, kEobBaseYesNoStringsProvider },
-	{ kLolEobCommonMoreStrings, kLolEobCommonMoreStringsProvider },
-	{ kEobBaseNpcMaxStrings, kEobBaseNpcMaxStringsProvider },
-	{ kEobBaseOkStrings, kEobBaseOkStringsProvider },
-	{ kEobBaseNpcJoinStrings, kEobBaseNpcJoinStringsProvider },
-	{ kEobBaseCancelStrings, kEobBaseCancelStringsProvider },
-	{ kEobBaseAbortStrings, kEobBaseAbortStringsProvider },
-
-	{ kEobBaseMenuStringsMain, kEobBaseMenuStringsMainProvider },
-	{ kEobBaseMenuStringsSaveLoad, kEobBaseMenuStringsSaveLoadProvider },
-	{ kEobBaseMenuStringsOnOff, kEobBaseMenuStringsOnOffProvider },
-	{ kEobBaseMenuStringsSpells, kEobBaseMenuStringsSpellsProvider },
-	{ kEobBaseMenuStringsRest, kEobBaseMenuStringsRestProvider },
-	{ kEobBaseMenuStringsDrop, kEobBaseMenuStringsDropProvider },
-	{ kEobBaseMenuStringsExit, kEobBaseMenuStringsExitProvider },
-	{ kEobBaseMenuStringsStarve, kEobBaseMenuStringsStarveProvider },
-	{ kEobBaseMenuStringsScribe, kEobBaseMenuStringsScribeProvider },
-	{ kEobBaseMenuStringsDrop2, kEobBaseMenuStringsDrop2Provider },
-	{ kEobBaseMenuStringsHead, kEobBaseMenuStringsHeadProvider },
-	{ kEobBaseMenuStringsPoison, kEobBaseMenuStringsPoisonProvider },
-	{ kEobBaseMenuStringsMgc, kEobBaseMenuStringsMgcProvider },
-	{ kEobBaseMenuStringsPrefs, kEobBaseMenuStringsPrefsProvider },
-	{ kEobBaseMenuStringsRest2, kEobBaseMenuStringsRest2Provider },
-	{ kEobBaseMenuStringsRest3, kEobBaseMenuStringsRest3Provider },
-	{ kEobBaseMenuStringsRest4, kEobBaseMenuStringsRest4Provider },
-	{ kEobBaseMenuStringsDefeat, kEobBaseMenuStringsDefeatProvider },
-	{ kEobBaseMenuStringsTransfer, kEobBaseMenuStringsTransferProvider },
-	{ kEobBaseMenuStringsSpec, kEobBaseMenuStringsSpecProvider },
-	{ kEobBaseMenuStringsSpellNo, kEobBaseMenuStringsSpellNoProvider },
-	{ kEobBaseMenuYesNoStrings, kEobBaseMenuYesNoStringsProvider },
+	{ kEoBBasePryDoorStrings, kEoBBasePryDoorStringsProvider },
+	{ kEoBBaseWarningStrings, kEoBBaseWarningStringsProvider },
+
+	{ kEoBBaseItemSuffixStringsRings, kEoBBaseItemSuffixStringsRingsProvider },
+	{ kEoBBaseItemSuffixStringsPotions, kEoBBaseItemSuffixStringsPotionsProvider },
+	{ kEoBBaseItemSuffixStringsWands, kEoBBaseItemSuffixStringsWandsProvider },
+
+	{ kEoBBaseRipItemStrings, kEoBBaseRipItemStringsProvider },
+	{ kEoBBaseCursedString, kEoBBaseCursedStringProvider },
+	{ kEoBBaseEnchantedString, kEoBBaseEnchantedStringProvider },
+	{ kEoBBaseMagicObjectStrings, kEoBBaseMagicObjectStringsProvider },
+	{ kEoBBaseMagicObject5String, kEoBBaseMagicObject5StringProvider },
+	{ kEoBBasePatternSuffix, kEoBBasePatternSuffixProvider },
+	{ kEoBBasePatternGrFix1, kEoBBasePatternGrFix1Provider },
+	{ kEoBBasePatternGrFix2, kEoBBasePatternGrFix2Provider },
+	{ kEoBBaseValidateArmorString, kEoBBaseValidateArmorStringProvider },
+	{ kEoBBaseValidateCursedString, kEoBBaseValidateCursedStringProvider },
+	{ kEoBBaseValidateNoDropString, kEoBBaseValidateNoDropStringProvider },
+	{ kEoBBasePotionStrings, kEoBBasePotionStringsProvider },
+	{ kEoBBaseWandString, kEoBBaseWandStringProvider },
+	{ kEoBBaseItemMisuseStrings, kEoBBaseItemMisuseStringsProvider },
+
+	{ kEoBBaseTakenStrings, kEoBBaseTakenStringsProvider },
+	{ kEoBBasePotionEffectStrings, kEoBBasePotionEffectStringsProvider },
+
+	{ kEoBBaseYesNoStrings, kEoBBaseYesNoStringsProvider },
+	{ kRpgCommonMoreStrings, kRpgCommonMoreStringsProvider },
+	{ kEoBBaseNpcMaxStrings, kEoBBaseNpcMaxStringsProvider },
+	{ kEoBBaseOkStrings, kEoBBaseOkStringsProvider },
+	{ kEoBBaseNpcJoinStrings, kEoBBaseNpcJoinStringsProvider },
+	{ kEoBBaseCancelStrings, kEoBBaseCancelStringsProvider },
+	{ kEoBBaseAbortStrings, kEoBBaseAbortStringsProvider },
+
+	{ kEoBBaseMenuStringsMain, kEoBBaseMenuStringsMainProvider },
+	{ kEoBBaseMenuStringsSaveLoad, kEoBBaseMenuStringsSaveLoadProvider },
+	{ kEoBBaseMenuStringsOnOff, kEoBBaseMenuStringsOnOffProvider },
+	{ kEoBBaseMenuStringsSpells, kEoBBaseMenuStringsSpellsProvider },
+	{ kEoBBaseMenuStringsRest, kEoBBaseMenuStringsRestProvider },
+	{ kEoBBaseMenuStringsDrop, kEoBBaseMenuStringsDropProvider },
+	{ kEoBBaseMenuStringsExit, kEoBBaseMenuStringsExitProvider },
+	{ kEoBBaseMenuStringsStarve, kEoBBaseMenuStringsStarveProvider },
+	{ kEoBBaseMenuStringsScribe, kEoBBaseMenuStringsScribeProvider },
+	{ kEoBBaseMenuStringsDrop2, kEoBBaseMenuStringsDrop2Provider },
+	{ kEoBBaseMenuStringsHead, kEoBBaseMenuStringsHeadProvider },
+	{ kEoBBaseMenuStringsPoison, kEoBBaseMenuStringsPoisonProvider },
+	{ kEoBBaseMenuStringsMgc, kEoBBaseMenuStringsMgcProvider },
+	{ kEoBBaseMenuStringsPrefs, kEoBBaseMenuStringsPrefsProvider },
+	{ kEoBBaseMenuStringsRest2, kEoBBaseMenuStringsRest2Provider },
+	{ kEoBBaseMenuStringsRest3, kEoBBaseMenuStringsRest3Provider },
+	{ kEoBBaseMenuStringsRest4, kEoBBaseMenuStringsRest4Provider },
+	{ kEoBBaseMenuStringsDefeat, kEoBBaseMenuStringsDefeatProvider },
+	{ kEoBBaseMenuStringsTransfer, kEoBBaseMenuStringsTransferProvider },
+	{ kEoBBaseMenuStringsSpec, kEoBBaseMenuStringsSpecProvider },
+	{ kEoBBaseMenuStringsSpellNo, kEoBBaseMenuStringsSpellNoProvider },
+	{ kEoBBaseMenuYesNoStrings, kEoBBaseMenuYesNoStringsProvider },
 	
-	{ kEobBaseSpellLevelsMage, kEobBaseSpellLevelsMageProvider },
-	{ kEobBaseSpellLevelsCleric, kEobBaseSpellLevelsClericProvider },
-	{ kEobBaseNumSpellsCleric, kEobBaseNumSpellsClericProvider },
-	{ kEobBaseNumSpellsWisAdj, kEobBaseNumSpellsWisAdjProvider },
-	{ kEobBaseNumSpellsPal, kEobBaseNumSpellsPalProvider },
-	{ kEobBaseNumSpellsMage, kEobBaseNumSpellsMageProvider },
-
-	{ kEobBaseCharGuiStringsHp, kEobBaseCharGuiStringsHpProvider },
-	{ kEobBaseCharGuiStringsWp1, kEobBaseCharGuiStringsWp1Provider },
-	{ kEobBaseCharGuiStringsWp2, kEobBaseCharGuiStringsWp2Provider },
-	{ kEobBaseCharGuiStringsWr, kEobBaseCharGuiStringsWrProvider },
-	{ kEobBaseCharGuiStringsSt1, kEobBaseCharGuiStringsSt1Provider },
-	{ kEobBaseCharGuiStringsSt2, kEobBaseCharGuiStringsSt2Provider },
-	{ kEobBaseCharGuiStringsIn, kEobBaseCharGuiStringsInProvider },
-
-	{ kEobBaseCharStatusStrings7, kEobBaseCharStatusStrings7Provider },
-	{ kEobBaseCharStatusStrings81, kEobBaseCharStatusStrings81Provider },
-	{ kEobBaseCharStatusStrings82, kEobBaseCharStatusStrings82Provider },
-	{ kEobBaseCharStatusStrings9, kEobBaseCharStatusStrings9Provider },
-	{ kEobBaseCharStatusStrings12, kEobBaseCharStatusStrings12Provider },
-	{ kEobBaseCharStatusStrings131, kEobBaseCharStatusStrings131Provider },
-	{ kEobBaseCharStatusStrings132, kEobBaseCharStatusStrings132Provider },
-
-	{ kEobBaseLevelGainStrings, kEobBaseLevelGainStringsProvider },
-	{ kEobBaseExperienceTable0, kEobBaseExperienceTable0Provider },
-	{ kEobBaseExperienceTable1, kEobBaseExperienceTable1Provider },
-	{ kEobBaseExperienceTable2, kEobBaseExperienceTable2Provider },
-	{ kEobBaseExperienceTable3, kEobBaseExperienceTable3Provider },
-	{ kEobBaseExperienceTable4, kEobBaseExperienceTable4Provider },
-
-	{ kEobBaseWllFlagPreset, kEobBaseWllFlagPresetProvider },
-	{ kEobBaseDscShapeCoords, kEobBaseDscShapeCoordsProvider },
-	{ kEobBaseDscDoorScaleOffs, kEobBaseDscDoorScaleOffsProvider },
-	{ kEobBaseDscDoorScaleMult1, kEobBaseDscDoorScaleMult1Provider },
-	{ kEobBaseDscDoorScaleMult2, kEobBaseDscDoorScaleMult2Provider },
-	{ kEobBaseDscDoorScaleMult3, kEobBaseDscDoorScaleMult3Provider },
-	{ kEobBaseDscDoorScaleMult4, kEobBaseDscDoorScaleMult4Provider },
-	{ kEobBaseDscDoorScaleMult5, kEobBaseDscDoorScaleMult5Provider },
-	{ kEobBaseDscDoorScaleMult6, kEobBaseDscDoorScaleMult6Provider },
-	{ kEobBaseDscDoorType5Offs, kEobBaseDscDoorType5OffsProvider },
-	{ kEobBaseDscDoorXE, kEobBaseDscDoorXEProvider },
-	{ kEobBaseDscDoorY1, kEobBaseDscDoorY1Provider },
-	{ kEobBaseDscDoorY3, kEobBaseDscDoorY3Provider },
-	{ kEobBaseDscDoorY4, kEobBaseDscDoorY4Provider },
-	{ kEobBaseDscDoorY5, kEobBaseDscDoorY5Provider },
-	{ kEobBaseDscDoorY6, kEobBaseDscDoorY6Provider },
-	{ kEobBaseDscDoorY7, kEobBaseDscDoorY7Provider },
-	{ kEobBaseDscDoorCoordsExt, kEobBaseDscDoorCoordsExtProvider },
-	{ kEobBaseDscItemPosIndex, kEobBaseDscItemPosIndexProvider },
-	{ kEobBaseDscItemShpX, kEobBaseDscItemShpXProvider },
-	{ kEobBaseDscItemPosUnk, kEobBaseDscItemPosUnkProvider },
-	{ kEobBaseDscItemTileIndex, kEobBaseDscItemTileIndexProvider },
-	{ kEobBaseDscItemShapeMap, kEobBaseDscItemShapeMapProvider },
-	{ kEobBaseDscTelptrShpCoords, kEobBaseDscTelptrShpCoordsProvider },
-
-	{ kEobBasePortalSeqData, kEobBasePortalSeqDataProvider },
-	{ kEobBaseManDef, kEobBaseManDefProvider },	
-	{ kEobBaseManWord, kEobBaseManWordProvider },
-	{ kEobBaseManPrompt, kEobBaseManPromptProvider },
-
-	{ kEobBaseDscMonsterFrmOffsTbl1, kEobBaseDscMonsterFrmOffsTbl1Provider },
-	{ kEobBaseDscMonsterFrmOffsTbl2, kEobBaseDscMonsterFrmOffsTbl2Provider },
-
-	{ kEobBaseInvSlotX, kEobBaseInvSlotXProvider },
-	{ kEobBaseInvSlotY, kEobBaseInvSlotYProvider },
-	{ kEobBaseSlotValidationFlags, kEobBaseSlotValidationFlagsProvider },
-
-	{ kEobBaseProjectileWeaponTypes, kEobBaseProjectileWeaponTypesProvider },
-	{ kEobBaseWandTypes, kEobBaseWandTypesProvider },
-
-	{ kEobBaseDrawObjPosIndex, kEobBaseDrawObjPosIndexProvider },
-	{ kEobBaseFlightObjFlipIndex, kEobBaseFlightObjFlipIndexProvider },
-	{ kEobBaseFlightObjShpMap, kEobBaseFlightObjShpMapProvider },
-	{ kEobBaseFlightObjSclIndex, kEobBaseFlightObjSclIndexProvider },
-
-	{ kEobBaseBookNumbers, kEobBaseBookNumbersProvider },
-	{ kEobBaseMageSpellsList, kEobBaseMageSpellsListProvider },
-	{ kEobBaseClericSpellsList, kEobBaseClericSpellsListProvider },
-	{ kEobBaseSpellNames, kEobBaseSpellNamesProvider },
-	{ kEobBaseMagicStrings1, kEobBaseMagicStrings1Provider },
-	{ kEobBaseMagicStrings2, kEobBaseMagicStrings2Provider },
-	{ kEobBaseMagicStrings3, kEobBaseMagicStrings3Provider },
-	{ kEobBaseMagicStrings4, kEobBaseMagicStrings4Provider },
-	{ kEobBaseMagicStrings6, kEobBaseMagicStrings6Provider },
-	{ kEobBaseMagicStrings7, kEobBaseMagicStrings7Provider },
-	{ kEobBaseMagicStrings8, kEobBaseMagicStrings8Provider },
-
-	{ kEobBaseExpObjectTlMode, kEobBaseExpObjectTlModeProvider },
-	{ kEobBaseExpObjectTblIndex, kEobBaseExpObjectTblIndexProvider },
-	{ kEobBaseExpObjectShpStart, kEobBaseExpObjectShpStartProvider },
-	{ kEobBaseExpObjectTbl1, kEobBaseExpObjectTbl1Provider },
-	{ kEobBaseExpObjectTbl2, kEobBaseExpObjectTbl2Provider },
-	{ kEobBaseExpObjectTbl3, kEobBaseExpObjectTbl3Provider },
-	{ kEobBaseExpObjectY, kEobBaseExpObjectYProvider },
+	{ kEoBBaseSpellLevelsMage, kEoBBaseSpellLevelsMageProvider },
+	{ kEoBBaseSpellLevelsCleric, kEoBBaseSpellLevelsClericProvider },
+	{ kEoBBaseNumSpellsCleric, kEoBBaseNumSpellsClericProvider },
+	{ kEoBBaseNumSpellsWisAdj, kEoBBaseNumSpellsWisAdjProvider },
+	{ kEoBBaseNumSpellsPal, kEoBBaseNumSpellsPalProvider },
+	{ kEoBBaseNumSpellsMage, kEoBBaseNumSpellsMageProvider },
+
+	{ kEoBBaseCharGuiStringsHp, kEoBBaseCharGuiStringsHpProvider },
+	{ kEoBBaseCharGuiStringsWp1, kEoBBaseCharGuiStringsWp1Provider },
+	{ kEoBBaseCharGuiStringsWp2, kEoBBaseCharGuiStringsWp2Provider },
+	{ kEoBBaseCharGuiStringsWr, kEoBBaseCharGuiStringsWrProvider },
+	{ kEoBBaseCharGuiStringsSt1, kEoBBaseCharGuiStringsSt1Provider },
+	{ kEoBBaseCharGuiStringsSt2, kEoBBaseCharGuiStringsSt2Provider },
+	{ kEoBBaseCharGuiStringsIn, kEoBBaseCharGuiStringsInProvider },
+
+	{ kEoBBaseCharStatusStrings7, kEoBBaseCharStatusStrings7Provider },
+	{ kEoBBaseCharStatusStrings81, kEoBBaseCharStatusStrings81Provider },
+	{ kEoBBaseCharStatusStrings82, kEoBBaseCharStatusStrings82Provider },
+	{ kEoBBaseCharStatusStrings9, kEoBBaseCharStatusStrings9Provider },
+	{ kEoBBaseCharStatusStrings12, kEoBBaseCharStatusStrings12Provider },
+	{ kEoBBaseCharStatusStrings131, kEoBBaseCharStatusStrings131Provider },
+	{ kEoBBaseCharStatusStrings132, kEoBBaseCharStatusStrings132Provider },
+
+	{ kEoBBaseLevelGainStrings, kEoBBaseLevelGainStringsProvider },
+	{ kEoBBaseExperienceTable0, kEoBBaseExperienceTable0Provider },
+	{ kEoBBaseExperienceTable1, kEoBBaseExperienceTable1Provider },
+	{ kEoBBaseExperienceTable2, kEoBBaseExperienceTable2Provider },
+	{ kEoBBaseExperienceTable3, kEoBBaseExperienceTable3Provider },
+	{ kEoBBaseExperienceTable4, kEoBBaseExperienceTable4Provider },
+
+	{ kEoBBaseWllFlagPreset, kEoBBaseWllFlagPresetProvider },
+	{ kEoBBaseDscShapeCoords, kEoBBaseDscShapeCoordsProvider },
+	{ kEoBBaseDscDoorScaleOffs, kEoBBaseDscDoorScaleOffsProvider },
+	{ kEoBBaseDscDoorScaleMult1, kEoBBaseDscDoorScaleMult1Provider },
+	{ kEoBBaseDscDoorScaleMult2, kEoBBaseDscDoorScaleMult2Provider },
+	{ kEoBBaseDscDoorScaleMult3, kEoBBaseDscDoorScaleMult3Provider },
+	{ kEoBBaseDscDoorScaleMult4, kEoBBaseDscDoorScaleMult4Provider },
+	{ kEoBBaseDscDoorScaleMult5, kEoBBaseDscDoorScaleMult5Provider },
+	{ kEoBBaseDscDoorScaleMult6, kEoBBaseDscDoorScaleMult6Provider },
+	{ kEoBBaseDscDoorType5Offs, kEoBBaseDscDoorType5OffsProvider },
+	{ kEoBBaseDscDoorXE, kEoBBaseDscDoorXEProvider },
+	{ kEoBBaseDscDoorY1, kEoBBaseDscDoorY1Provider },
+	{ kEoBBaseDscDoorY3, kEoBBaseDscDoorY3Provider },
+	{ kEoBBaseDscDoorY4, kEoBBaseDscDoorY4Provider },
+	{ kEoBBaseDscDoorY5, kEoBBaseDscDoorY5Provider },
+	{ kEoBBaseDscDoorY6, kEoBBaseDscDoorY6Provider },
+	{ kEoBBaseDscDoorY7, kEoBBaseDscDoorY7Provider },
+	{ kEoBBaseDscDoorCoordsExt, kEoBBaseDscDoorCoordsExtProvider },
+	{ kEoBBaseDscItemPosIndex, kEoBBaseDscItemPosIndexProvider },
+	{ kEoBBaseDscItemShpX, kEoBBaseDscItemShpXProvider },
+	{ kEoBBaseDscItemPosUnk, kEoBBaseDscItemPosUnkProvider },
+	{ kEoBBaseDscItemTileIndex, kEoBBaseDscItemTileIndexProvider },
+	{ kEoBBaseDscItemShapeMap, kEoBBaseDscItemShapeMapProvider },
+	{ kEoBBaseDscTelptrShpCoords, kEoBBaseDscTelptrShpCoordsProvider },
+
+	{ kEoBBasePortalSeqData, kEoBBasePortalSeqDataProvider },
+	{ kEoBBaseManDef, kEoBBaseManDefProvider },	
+	{ kEoBBaseManWord, kEoBBaseManWordProvider },
+	{ kEoBBaseManPrompt, kEoBBaseManPromptProvider },
+
+	{ kEoBBaseDscMonsterFrmOffsTbl1, kEoBBaseDscMonsterFrmOffsTbl1Provider },
+	{ kEoBBaseDscMonsterFrmOffsTbl2, kEoBBaseDscMonsterFrmOffsTbl2Provider },
+
+	{ kEoBBaseInvSlotX, kEoBBaseInvSlotXProvider },
+	{ kEoBBaseInvSlotY, kEoBBaseInvSlotYProvider },
+	{ kEoBBaseSlotValidationFlags, kEoBBaseSlotValidationFlagsProvider },
+
+	{ kEoBBaseProjectileWeaponTypes, kEoBBaseProjectileWeaponTypesProvider },
+	{ kEoBBaseWandTypes, kEoBBaseWandTypesProvider },
+
+	{ kEoBBaseDrawObjPosIndex, kEoBBaseDrawObjPosIndexProvider },
+	{ kEoBBaseFlightObjFlipIndex, kEoBBaseFlightObjFlipIndexProvider },
+	{ kEoBBaseFlightObjShpMap, kEoBBaseFlightObjShpMapProvider },
+	{ kEoBBaseFlightObjSclIndex, kEoBBaseFlightObjSclIndexProvider },
+
+	{ kEoBBaseBookNumbers, kEoBBaseBookNumbersProvider },
+	{ kEoBBaseMageSpellsList, kEoBBaseMageSpellsListProvider },
+	{ kEoBBaseClericSpellsList, kEoBBaseClericSpellsListProvider },
+	{ kEoBBaseSpellNames, kEoBBaseSpellNamesProvider },
+	{ kEoBBaseMagicStrings1, kEoBBaseMagicStrings1Provider },
+	{ kEoBBaseMagicStrings2, kEoBBaseMagicStrings2Provider },
+	{ kEoBBaseMagicStrings3, kEoBBaseMagicStrings3Provider },
+	{ kEoBBaseMagicStrings4, kEoBBaseMagicStrings4Provider },
+	{ kEoBBaseMagicStrings6, kEoBBaseMagicStrings6Provider },
+	{ kEoBBaseMagicStrings7, kEoBBaseMagicStrings7Provider },
+	{ kEoBBaseMagicStrings8, kEoBBaseMagicStrings8Provider },
+
+	{ kEoBBaseExpObjectTlMode, kEoBBaseExpObjectTlModeProvider },
+	{ kEoBBaseExpObjectTblIndex, kEoBBaseExpObjectTblIndexProvider },
+	{ kEoBBaseExpObjectShpStart, kEoBBaseExpObjectShpStartProvider },
+	{ kEoBBaseExpObjectTbl1, kEoBBaseExpObjectTbl1Provider },
+	{ kEoBBaseExpObjectTbl2, kEoBBaseExpObjectTbl2Provider },
+	{ kEoBBaseExpObjectTbl3, kEoBBaseExpObjectTbl3Provider },
+	{ kEoBBaseExpObjectY, kEoBBaseExpObjectYProvider },
 	
-	{ kEobBaseSparkDefSteps, kEobBaseSparkDefStepsProvider },
-	{ kEobBaseSparkDefSubSteps, kEobBaseSparkDefSubStepsProvider },
-	{ kEobBaseSparkDefShift, kEobBaseSparkDefShiftProvider },
-	{ kEobBaseSparkDefAdd, kEobBaseSparkDefAddProvider },
-	{ kEobBaseSparkDefX, kEobBaseSparkDefXProvider },
-	{ kEobBaseSparkDefY, kEobBaseSparkDefYProvider },
-	{ kEobBaseSparkOfFlags1, kEobBaseSparkOfFlags1Provider },
-	{ kEobBaseSparkOfFlags2, kEobBaseSparkOfFlags2Provider },
-	{ kEobBaseSparkOfShift, kEobBaseSparkOfShiftProvider },
-	{ kEobBaseSparkOfX, kEobBaseSparkOfXProvider },
-	{ kEobBaseSparkOfY, kEobBaseSparkOfYProvider },
-
-	{ kEobBaseSpellProperties, kEobBaseSpellPropertiesProvider },
-	{ kEobBaseMagicFlightProps, kEobBaseMagicFlightPropsProvider },
-	{ kEobBaseTurnUndeadEffect, kEobBaseTurnUndeadEffectProvider },
-	{ kEobBaseBurningHandsDest, kEobBaseBurningHandsDestProvider },
-	{ kEobBaseConeOfColdDest1, kEobBaseConeOfColdDest1Provider },
-	{ kEobBaseConeOfColdDest2, kEobBaseConeOfColdDest2Provider },
-	{ kEobBaseConeOfColdDest3, kEobBaseConeOfColdDest3Provider },
-	{ kEobBaseConeOfColdDest4, kEobBaseConeOfColdDest4Provider },
-	{ kEobBaseConeOfColdGfxTbl, kEobBaseConeOfColdGfxTblProvider },	
-
-	{ kEob1MainMenuStrings, kEob1MainMenuStringsProvider },
-	{ kEob1BonusStrings, kEob1BonusStringsProvider },
-
-	{ kEob1IntroFilesOpening, kEob1IntroFilesOpeningProvider },
-	{ kEob1IntroFilesTower, kEob1IntroFilesTowerProvider },
-	{ kEob1IntroFilesOrb, kEob1IntroFilesOrbProvider },
-	{ kEob1IntroFilesWdEntry, kEob1IntroFilesWdEntryProvider },
-	{ kEob1IntroFilesKing, kEob1IntroFilesKingProvider },
-	{ kEob1IntroFilesHands, kEob1IntroFilesHandsProvider },
-	{ kEob1IntroFilesWdExit, kEob1IntroFilesWdExitProvider },
-	{ kEob1IntroFilesTunnel, kEob1IntroFilesTunnelProvider },
-	{ kEob1IntroOpeningFrmDelay, kEob1IntroOpeningFrmDelayProvider },
-	{ kEob1IntroWdEncodeX, kEob1IntroWdEncodeXProvider },
-	{ kEob1IntroWdEncodeY, kEob1IntroWdEncodeYProvider },
-	{ kEob1IntroWdEncodeWH, kEob1IntroWdEncodeWHProvider },
-	{ kEob1IntroWdDsX, kEob1IntroWdDsXProvider },
-	{ kEob1IntroWdDsY, kEob1IntroWdDsYProvider },
-	{ kEob1IntroTvlX1, kEob1IntroTvlX1Provider },
-	{ kEob1IntroTvlY1, kEob1IntroTvlY1Provider },
-	{ kEob1IntroTvlX2, kEob1IntroTvlX2Provider },
-	{ kEob1IntroTvlY2, kEob1IntroTvlY2Provider },
-	{ kEob1IntroTvlW, kEob1IntroTvlWProvider },
-	{ kEob1IntroTvlH, kEob1IntroTvlHProvider },
-
-	{ kEob1DoorShapeDefs, kEob1DoorShapeDefsProvider },
-	{ kEob1DoorSwitchShapeDefs, kEob1DoorSwitchShapeDefsProvider },
-	{ kEob1DoorSwitchCoords, kEob1DoorSwitchCoordsProvider },
-	{ kEob1MonsterProperties, kEob1MonsterPropertiesProvider },
-
-	{ kEob1EnemyMageSpellList, kEob1EnemyMageSpellListProvider },
-	{ kEob1EnemyMageSfx, kEob1EnemyMageSfxProvider },
-	{ kEob1BeholderSpellList, kEob1BeholderSpellListProvider },
-	{ kEob1BeholderSfx, kEob1BeholderSfxProvider },
-	{ kEob1TurnUndeadString, kEob1TurnUndeadStringProvider },
-
-	{ kEob1NpcShpData, kEob1NpcShpDataProvider },
-	{ kEob1NpcSubShpIndex1, kEob1NpcSubShpIndex1Provider },
-	{ kEob1NpcSubShpIndex2, kEob1NpcSubShpIndex2Provider },
-	{ kEob1NpcSubShpY, kEob1NpcSubShpYProvider },
-	{ kEob1Npc0Strings, kEob1Npc0StringsProvider },
-	{ kEob1Npc11Strings, kEob1Npc11StringsProvider },
-	{ kEob1Npc12Strings, kEob1Npc12StringsProvider },
-	{ kEob1Npc21Strings, kEob1Npc21StringsProvider },
-	{ kEob1Npc22Strings, kEob1Npc22StringsProvider },
-	{ kEob1Npc31Strings, kEob1Npc31StringsProvider },
-	{ kEob1Npc32Strings, kEob1Npc32StringsProvider },
-	{ kEob1Npc4Strings, kEob1Npc4StringsProvider },
-	{ kEob1Npc5Strings, kEob1Npc5StringsProvider },
-	{ kEob1Npc6Strings, kEob1Npc6StringsProvider },
-	{ kEob1Npc7Strings, kEob1Npc7StringsProvider },
-
-	{ kEob2MainMenuStrings, kEob2MainMenuStringsProvider },
-	{ kEob2TransferConvertTable, kEob2TransferConvertTableProvider },
-	{ kEob2TransferExpTable, kEob2TransferExpTableProvider },
-
-	{ kEob2IntroStrings, kEob2IntroStringsProvider },
-	{ kEob2IntroCPSFiles, kEob2IntroCPSFilesProvider },
-	{ kEob2IntroSeqData00, kEob2IntroSeqData00Provider },
- 	{ kEob2IntroSeqData01, kEob2IntroSeqData01Provider },
- 	{ kEob2IntroSeqData02, kEob2IntroSeqData02Provider },
- 	{ kEob2IntroSeqData03, kEob2IntroSeqData03Provider },
- 	{ kEob2IntroSeqData04, kEob2IntroSeqData04Provider },
- 	{ kEob2IntroSeqData05, kEob2IntroSeqData05Provider },
- 	{ kEob2IntroSeqData06, kEob2IntroSeqData06Provider },
- 	{ kEob2IntroSeqData07, kEob2IntroSeqData07Provider },
- 	{ kEob2IntroSeqData08, kEob2IntroSeqData08Provider },
- 	{ kEob2IntroSeqData09, kEob2IntroSeqData09Provider },
- 	{ kEob2IntroSeqData10, kEob2IntroSeqData10Provider },
- 	{ kEob2IntroSeqData11, kEob2IntroSeqData11Provider },
- 	{ kEob2IntroSeqData12, kEob2IntroSeqData12Provider },
- 	{ kEob2IntroSeqData13, kEob2IntroSeqData13Provider },
- 	{ kEob2IntroSeqData14, kEob2IntroSeqData14Provider },
- 	{ kEob2IntroSeqData15, kEob2IntroSeqData15Provider },
- 	{ kEob2IntroSeqData16, kEob2IntroSeqData16Provider },
- 	{ kEob2IntroSeqData17, kEob2IntroSeqData17Provider },
- 	{ kEob2IntroSeqData18, kEob2IntroSeqData18Provider },
- 	{ kEob2IntroSeqData19, kEob2IntroSeqData19Provider },
- 	{ kEob2IntroSeqData20, kEob2IntroSeqData20Provider },
- 	{ kEob2IntroSeqData21, kEob2IntroSeqData21Provider },
- 	{ kEob2IntroSeqData22, kEob2IntroSeqData22Provider },
- 	{ kEob2IntroSeqData23, kEob2IntroSeqData23Provider },
- 	{ kEob2IntroSeqData24, kEob2IntroSeqData24Provider },
- 	{ kEob2IntroSeqData25, kEob2IntroSeqData25Provider },
- 	{ kEob2IntroSeqData26, kEob2IntroSeqData26Provider },
- 	{ kEob2IntroSeqData27, kEob2IntroSeqData27Provider },
- 	{ kEob2IntroSeqData28, kEob2IntroSeqData28Provider },
- 	{ kEob2IntroSeqData29, kEob2IntroSeqData29Provider },
- 	{ kEob2IntroSeqData30, kEob2IntroSeqData30Provider },
- 	{ kEob2IntroSeqData31, kEob2IntroSeqData31Provider },
- 	{ kEob2IntroSeqData32, kEob2IntroSeqData32Provider },
- 	{ kEob2IntroSeqData33, kEob2IntroSeqData33Provider },
- 	{ kEob2IntroSeqData34, kEob2IntroSeqData34Provider },
- 	{ kEob2IntroSeqData35, kEob2IntroSeqData35Provider },
- 	{ kEob2IntroSeqData36, kEob2IntroSeqData36Provider },
- 	{ kEob2IntroSeqData37, kEob2IntroSeqData37Provider },
- 	{ kEob2IntroSeqData38, kEob2IntroSeqData38Provider },
- 	{ kEob2IntroSeqData39, kEob2IntroSeqData39Provider },
- 	{ kEob2IntroSeqData40, kEob2IntroSeqData40Provider },
- 	{ kEob2IntroSeqData41, kEob2IntroSeqData41Provider },
- 	{ kEob2IntroSeqData42, kEob2IntroSeqData42Provider },
- 	{ kEob2IntroSeqData43, kEob2IntroSeqData43Provider },
-	{ kEob2IntroShapes00, kEob2IntroShapes00Provider },
- 	{ kEob2IntroShapes01, kEob2IntroShapes01Provider },
- 	{ kEob2IntroShapes04, kEob2IntroShapes04Provider },
- 	{ kEob2IntroShapes07, kEob2IntroShapes07Provider },
-
-	{ kEob2FinaleStrings, kEob2FinaleStringsProvider },
-	{ kEob2CreditsData, kEob2CreditsDataProvider },
-	{ kEob2FinaleCPSFiles, kEob2FinaleCPSFilesProvider },
-	{ kEob2FinaleSeqData00, kEob2FinaleSeqData00Provider },
- 	{ kEob2FinaleSeqData01, kEob2FinaleSeqData01Provider },
- 	{ kEob2FinaleSeqData02, kEob2FinaleSeqData02Provider },
- 	{ kEob2FinaleSeqData03, kEob2FinaleSeqData03Provider },
- 	{ kEob2FinaleSeqData04, kEob2FinaleSeqData04Provider },
- 	{ kEob2FinaleSeqData05, kEob2FinaleSeqData05Provider },
- 	{ kEob2FinaleSeqData06, kEob2FinaleSeqData06Provider },
- 	{ kEob2FinaleSeqData07, kEob2FinaleSeqData07Provider },
- 	{ kEob2FinaleSeqData08, kEob2FinaleSeqData08Provider },
- 	{ kEob2FinaleSeqData09, kEob2FinaleSeqData09Provider },
- 	{ kEob2FinaleSeqData10, kEob2FinaleSeqData10Provider },
- 	{ kEob2FinaleSeqData11, kEob2FinaleSeqData11Provider },
- 	{ kEob2FinaleSeqData12, kEob2FinaleSeqData12Provider },
- 	{ kEob2FinaleSeqData13, kEob2FinaleSeqData13Provider },
- 	{ kEob2FinaleSeqData14, kEob2FinaleSeqData14Provider },
- 	{ kEob2FinaleSeqData15, kEob2FinaleSeqData15Provider },
- 	{ kEob2FinaleSeqData16, kEob2FinaleSeqData16Provider },
- 	{ kEob2FinaleSeqData17, kEob2FinaleSeqData17Provider },
- 	{ kEob2FinaleSeqData18, kEob2FinaleSeqData18Provider },
- 	{ kEob2FinaleSeqData19, kEob2FinaleSeqData19Provider },
- 	{ kEob2FinaleSeqData20, kEob2FinaleSeqData20Provider },
-	{ kEob2FinaleShapes00, kEob2FinaleShapes00Provider },
- 	{ kEob2FinaleShapes03, kEob2FinaleShapes03Provider },
- 	{ kEob2FinaleShapes07, kEob2FinaleShapes07Provider },
- 	{ kEob2FinaleShapes09, kEob2FinaleShapes09Provider },
- 	{ kEob2FinaleShapes10, kEob2FinaleShapes10Provider },
-
-	{ kEob2NpcShapeData, kEob2NpcShapeDataProvider },
-	{ kEobBaseClassModifierFlags, kEobBaseClassModifierFlagsProvider },
-
-	{ kEobBaseMonsterStepTable01, kEobBaseMonsterStepTable01Provider },
-	{ kEobBaseMonsterStepTable02, kEobBaseMonsterStepTable02Provider },
-	{ kEobBaseMonsterStepTable1, kEobBaseMonsterStepTable1Provider },
-	{ kEobBaseMonsterStepTable2, kEobBaseMonsterStepTable2Provider },
-	{ kEobBaseMonsterStepTable3, kEobBaseMonsterStepTable3Provider },
-	{ kEobBaseMonsterCloseAttPosTable1, kEobBaseMonsterCloseAttPosTable1Provider },
-	{ kEobBaseMonsterCloseAttPosTable21, kEobBaseMonsterCloseAttPosTable21Provider },
-	{ kEobBaseMonsterCloseAttPosTable22, kEobBaseMonsterCloseAttPosTable22Provider },
-	{ kEobBaseMonsterCloseAttUnkTable, kEobBaseMonsterCloseAttUnkTableProvider },
-	{ kEobBaseMonsterCloseAttChkTable1, kEobBaseMonsterCloseAttChkTable1Provider },
-	{ kEobBaseMonsterCloseAttChkTable2, kEobBaseMonsterCloseAttChkTable2Provider },
-	{ kEobBaseMonsterCloseAttDstTable1, kEobBaseMonsterCloseAttDstTable1Provider },
-	{ kEobBaseMonsterCloseAttDstTable2, kEobBaseMonsterCloseAttDstTable2Provider },
+	{ kEoBBaseSparkDefSteps, kEoBBaseSparkDefStepsProvider },
+	{ kEoBBaseSparkDefSubSteps, kEoBBaseSparkDefSubStepsProvider },
+	{ kEoBBaseSparkDefShift, kEoBBaseSparkDefShiftProvider },
+	{ kEoBBaseSparkDefAdd, kEoBBaseSparkDefAddProvider },
+	{ kEoBBaseSparkDefX, kEoBBaseSparkDefXProvider },
+	{ kEoBBaseSparkDefY, kEoBBaseSparkDefYProvider },
+	{ kEoBBaseSparkOfFlags1, kEoBBaseSparkOfFlags1Provider },
+	{ kEoBBaseSparkOfFlags2, kEoBBaseSparkOfFlags2Provider },
+	{ kEoBBaseSparkOfShift, kEoBBaseSparkOfShiftProvider },
+	{ kEoBBaseSparkOfX, kEoBBaseSparkOfXProvider },
+	{ kEoBBaseSparkOfY, kEoBBaseSparkOfYProvider },
+
+	{ kEoBBaseSpellProperties, kEoBBaseSpellPropertiesProvider },
+	{ kEoBBaseMagicFlightProps, kEoBBaseMagicFlightPropsProvider },
+	{ kEoBBaseTurnUndeadEffect, kEoBBaseTurnUndeadEffectProvider },
+	{ kEoBBaseBurningHandsDest, kEoBBaseBurningHandsDestProvider },
+	{ kEoBBaseConeOfColdDest1, kEoBBaseConeOfColdDest1Provider },
+	{ kEoBBaseConeOfColdDest2, kEoBBaseConeOfColdDest2Provider },
+	{ kEoBBaseConeOfColdDest3, kEoBBaseConeOfColdDest3Provider },
+	{ kEoBBaseConeOfColdDest4, kEoBBaseConeOfColdDest4Provider },
+	{ kEoBBaseConeOfColdGfxTbl, kEoBBaseConeOfColdGfxTblProvider },	
+
+	{ kEoB1MainMenuStrings, kEoB1MainMenuStringsProvider },
+	{ kEoB1BonusStrings, kEoB1BonusStringsProvider },
+
+	{ kEoB1IntroFilesOpening, kEoB1IntroFilesOpeningProvider },
+	{ kEoB1IntroFilesTower, kEoB1IntroFilesTowerProvider },
+	{ kEoB1IntroFilesOrb, kEoB1IntroFilesOrbProvider },
+	{ kEoB1IntroFilesWdEntry, kEoB1IntroFilesWdEntryProvider },
+	{ kEoB1IntroFilesKing, kEoB1IntroFilesKingProvider },
+	{ kEoB1IntroFilesHands, kEoB1IntroFilesHandsProvider },
+	{ kEoB1IntroFilesWdExit, kEoB1IntroFilesWdExitProvider },
+	{ kEoB1IntroFilesTunnel, kEoB1IntroFilesTunnelProvider },
+	{ kEoB1IntroOpeningFrmDelay, kEoB1IntroOpeningFrmDelayProvider },
+	{ kEoB1IntroWdEncodeX, kEoB1IntroWdEncodeXProvider },
+	{ kEoB1IntroWdEncodeY, kEoB1IntroWdEncodeYProvider },
+	{ kEoB1IntroWdEncodeWH, kEoB1IntroWdEncodeWHProvider },
+	{ kEoB1IntroWdDsX, kEoB1IntroWdDsXProvider },
+	{ kEoB1IntroWdDsY, kEoB1IntroWdDsYProvider },
+	{ kEoB1IntroTvlX1, kEoB1IntroTvlX1Provider },
+	{ kEoB1IntroTvlY1, kEoB1IntroTvlY1Provider },
+	{ kEoB1IntroTvlX2, kEoB1IntroTvlX2Provider },
+	{ kEoB1IntroTvlY2, kEoB1IntroTvlY2Provider },
+	{ kEoB1IntroTvlW, kEoB1IntroTvlWProvider },
+	{ kEoB1IntroTvlH, kEoB1IntroTvlHProvider },
+
+	{ kEoB1DoorShapeDefs, kEoB1DoorShapeDefsProvider },
+	{ kEoB1DoorSwitchShapeDefs, kEoB1DoorSwitchShapeDefsProvider },
+	{ kEoB1DoorSwitchCoords, kEoB1DoorSwitchCoordsProvider },
+	{ kEoB1MonsterProperties, kEoB1MonsterPropertiesProvider },
+
+	{ kEoB1EnemyMageSpellList, kEoB1EnemyMageSpellListProvider },
+	{ kEoB1EnemyMageSfx, kEoB1EnemyMageSfxProvider },
+	{ kEoB1BeholderSpellList, kEoB1BeholderSpellListProvider },
+	{ kEoB1BeholderSfx, kEoB1BeholderSfxProvider },
+	{ kEoB1TurnUndeadString, kEoB1TurnUndeadStringProvider },
+
+	{ kEoB1NpcShpData, kEoB1NpcShpDataProvider },
+	{ kEoB1NpcSubShpIndex1, kEoB1NpcSubShpIndex1Provider },
+	{ kEoB1NpcSubShpIndex2, kEoB1NpcSubShpIndex2Provider },
+	{ kEoB1NpcSubShpY, kEoB1NpcSubShpYProvider },
+	{ kEoB1Npc0Strings, kEoB1Npc0StringsProvider },
+	{ kEoB1Npc11Strings, kEoB1Npc11StringsProvider },
+	{ kEoB1Npc12Strings, kEoB1Npc12StringsProvider },
+	{ kEoB1Npc21Strings, kEoB1Npc21StringsProvider },
+	{ kEoB1Npc22Strings, kEoB1Npc22StringsProvider },
+	{ kEoB1Npc31Strings, kEoB1Npc31StringsProvider },
+	{ kEoB1Npc32Strings, kEoB1Npc32StringsProvider },
+	{ kEoB1Npc4Strings, kEoB1Npc4StringsProvider },
+	{ kEoB1Npc5Strings, kEoB1Npc5StringsProvider },
+	{ kEoB1Npc6Strings, kEoB1Npc6StringsProvider },
+	{ kEoB1Npc7Strings, kEoB1Npc7StringsProvider },
+
+	{ kEoB2MainMenuStrings, kEoB2MainMenuStringsProvider },
+	{ kEoB2TransferConvertTable, kEoB2TransferConvertTableProvider },
+	{ kEoB2TransferExpTable, kEoB2TransferExpTableProvider },
+
+	{ kEoB2IntroStrings, kEoB2IntroStringsProvider },
+	{ kEoB2IntroCPSFiles, kEoB2IntroCPSFilesProvider },
+	{ kEoB2IntroSeqData00, kEoB2IntroSeqData00Provider },
+ 	{ kEoB2IntroSeqData01, kEoB2IntroSeqData01Provider },
+ 	{ kEoB2IntroSeqData02, kEoB2IntroSeqData02Provider },
+ 	{ kEoB2IntroSeqData03, kEoB2IntroSeqData03Provider },
+ 	{ kEoB2IntroSeqData04, kEoB2IntroSeqData04Provider },
+ 	{ kEoB2IntroSeqData05, kEoB2IntroSeqData05Provider },
+ 	{ kEoB2IntroSeqData06, kEoB2IntroSeqData06Provider },
+ 	{ kEoB2IntroSeqData07, kEoB2IntroSeqData07Provider },
+ 	{ kEoB2IntroSeqData08, kEoB2IntroSeqData08Provider },
+ 	{ kEoB2IntroSeqData09, kEoB2IntroSeqData09Provider },
+ 	{ kEoB2IntroSeqData10, kEoB2IntroSeqData10Provider },
+ 	{ kEoB2IntroSeqData11, kEoB2IntroSeqData11Provider },
+ 	{ kEoB2IntroSeqData12, kEoB2IntroSeqData12Provider },
+ 	{ kEoB2IntroSeqData13, kEoB2IntroSeqData13Provider },
+ 	{ kEoB2IntroSeqData14, kEoB2IntroSeqData14Provider },
+ 	{ kEoB2IntroSeqData15, kEoB2IntroSeqData15Provider },
+ 	{ kEoB2IntroSeqData16, kEoB2IntroSeqData16Provider },
+ 	{ kEoB2IntroSeqData17, kEoB2IntroSeqData17Provider },
+ 	{ kEoB2IntroSeqData18, kEoB2IntroSeqData18Provider },
+ 	{ kEoB2IntroSeqData19, kEoB2IntroSeqData19Provider },
+ 	{ kEoB2IntroSeqData20, kEoB2IntroSeqData20Provider },
+ 	{ kEoB2IntroSeqData21, kEoB2IntroSeqData21Provider },
+ 	{ kEoB2IntroSeqData22, kEoB2IntroSeqData22Provider },
+ 	{ kEoB2IntroSeqData23, kEoB2IntroSeqData23Provider },
+ 	{ kEoB2IntroSeqData24, kEoB2IntroSeqData24Provider },
+ 	{ kEoB2IntroSeqData25, kEoB2IntroSeqData25Provider },
+ 	{ kEoB2IntroSeqData26, kEoB2IntroSeqData26Provider },
+ 	{ kEoB2IntroSeqData27, kEoB2IntroSeqData27Provider },
+ 	{ kEoB2IntroSeqData28, kEoB2IntroSeqData28Provider },
+ 	{ kEoB2IntroSeqData29, kEoB2IntroSeqData29Provider },
+ 	{ kEoB2IntroSeqData30, kEoB2IntroSeqData30Provider },
+ 	{ kEoB2IntroSeqData31, kEoB2IntroSeqData31Provider },
+ 	{ kEoB2IntroSeqData32, kEoB2IntroSeqData32Provider },
+ 	{ kEoB2IntroSeqData33, kEoB2IntroSeqData33Provider },
+ 	{ kEoB2IntroSeqData34, kEoB2IntroSeqData34Provider },
+ 	{ kEoB2IntroSeqData35, kEoB2IntroSeqData35Provider },
+ 	{ kEoB2IntroSeqData36, kEoB2IntroSeqData36Provider },
+ 	{ kEoB2IntroSeqData37, kEoB2IntroSeqData37Provider },
+ 	{ kEoB2IntroSeqData38, kEoB2IntroSeqData38Provider },
+ 	{ kEoB2IntroSeqData39, kEoB2IntroSeqData39Provider },
+ 	{ kEoB2IntroSeqData40, kEoB2IntroSeqData40Provider },
+ 	{ kEoB2IntroSeqData41, kEoB2IntroSeqData41Provider },
+ 	{ kEoB2IntroSeqData42, kEoB2IntroSeqData42Provider },
+ 	{ kEoB2IntroSeqData43, kEoB2IntroSeqData43Provider },
+	{ kEoB2IntroShapes00, kEoB2IntroShapes00Provider },
+ 	{ kEoB2IntroShapes01, kEoB2IntroShapes01Provider },
+ 	{ kEoB2IntroShapes04, kEoB2IntroShapes04Provider },
+ 	{ kEoB2IntroShapes07, kEoB2IntroShapes07Provider },
+
+	{ kEoB2FinaleStrings, kEoB2FinaleStringsProvider },
+	{ kEoB2CreditsData, kEoB2CreditsDataProvider },
+	{ kEoB2FinaleCPSFiles, kEoB2FinaleCPSFilesProvider },
+	{ kEoB2FinaleSeqData00, kEoB2FinaleSeqData00Provider },
+ 	{ kEoB2FinaleSeqData01, kEoB2FinaleSeqData01Provider },
+ 	{ kEoB2FinaleSeqData02, kEoB2FinaleSeqData02Provider },
+ 	{ kEoB2FinaleSeqData03, kEoB2FinaleSeqData03Provider },
+ 	{ kEoB2FinaleSeqData04, kEoB2FinaleSeqData04Provider },
+ 	{ kEoB2FinaleSeqData05, kEoB2FinaleSeqData05Provider },
+ 	{ kEoB2FinaleSeqData06, kEoB2FinaleSeqData06Provider },
+ 	{ kEoB2FinaleSeqData07, kEoB2FinaleSeqData07Provider },
+ 	{ kEoB2FinaleSeqData08, kEoB2FinaleSeqData08Provider },
+ 	{ kEoB2FinaleSeqData09, kEoB2FinaleSeqData09Provider },
+ 	{ kEoB2FinaleSeqData10, kEoB2FinaleSeqData10Provider },
+ 	{ kEoB2FinaleSeqData11, kEoB2FinaleSeqData11Provider },
+ 	{ kEoB2FinaleSeqData12, kEoB2FinaleSeqData12Provider },
+ 	{ kEoB2FinaleSeqData13, kEoB2FinaleSeqData13Provider },
+ 	{ kEoB2FinaleSeqData14, kEoB2FinaleSeqData14Provider },
+ 	{ kEoB2FinaleSeqData15, kEoB2FinaleSeqData15Provider },
+ 	{ kEoB2FinaleSeqData16, kEoB2FinaleSeqData16Provider },
+ 	{ kEoB2FinaleSeqData17, kEoB2FinaleSeqData17Provider },
+ 	{ kEoB2FinaleSeqData18, kEoB2FinaleSeqData18Provider },
+ 	{ kEoB2FinaleSeqData19, kEoB2FinaleSeqData19Provider },
+ 	{ kEoB2FinaleSeqData20, kEoB2FinaleSeqData20Provider },
+	{ kEoB2FinaleShapes00, kEoB2FinaleShapes00Provider },
+ 	{ kEoB2FinaleShapes03, kEoB2FinaleShapes03Provider },
+ 	{ kEoB2FinaleShapes07, kEoB2FinaleShapes07Provider },
+ 	{ kEoB2FinaleShapes09, kEoB2FinaleShapes09Provider },
+ 	{ kEoB2FinaleShapes10, kEoB2FinaleShapes10Provider },
+
+	{ kEoB2NpcShapeData, kEoB2NpcShapeDataProvider },
+	{ kEoBBaseClassModifierFlags, kEoBBaseClassModifierFlagsProvider },
+
+	{ kEoBBaseMonsterStepTable01, kEoBBaseMonsterStepTable01Provider },
+	{ kEoBBaseMonsterStepTable02, kEoBBaseMonsterStepTable02Provider },
+	{ kEoBBaseMonsterStepTable1, kEoBBaseMonsterStepTable1Provider },
+	{ kEoBBaseMonsterStepTable2, kEoBBaseMonsterStepTable2Provider },
+	{ kEoBBaseMonsterStepTable3, kEoBBaseMonsterStepTable3Provider },
+	{ kEoBBaseMonsterCloseAttPosTable1, kEoBBaseMonsterCloseAttPosTable1Provider },
+	{ kEoBBaseMonsterCloseAttPosTable21, kEoBBaseMonsterCloseAttPosTable21Provider },
+	{ kEoBBaseMonsterCloseAttPosTable22, kEoBBaseMonsterCloseAttPosTable22Provider },
+	{ kEoBBaseMonsterCloseAttUnkTable, kEoBBaseMonsterCloseAttUnkTableProvider },
+	{ kEoBBaseMonsterCloseAttChkTable1, kEoBBaseMonsterCloseAttChkTable1Provider },
+	{ kEoBBaseMonsterCloseAttChkTable2, kEoBBaseMonsterCloseAttChkTable2Provider },
+	{ kEoBBaseMonsterCloseAttDstTable1, kEoBBaseMonsterCloseAttDstTable1Provider },
+	{ kEoBBaseMonsterCloseAttDstTable2, kEoBBaseMonsterCloseAttDstTable2Provider },
 	
-	{ kEobBaseMonsterProximityTable, kEobBaseMonsterProximityTableProvider },
-	{ kEobBaseFindBlockMonstersTable, kEobBaseFindBlockMonstersTableProvider },
-	{ kEobBaseMonsterDirChangeTable, kEobBaseMonsterDirChangeTableProvider },
-	{ kEobBaseMonsterDistAttStrings, kEobBaseMonsterDistAttStringsProvider },
-	{ kEobBaseEncodeMonsterDefs, kEobBaseEncodeMonsterDefsProvider },
-	{ kEobBaseNpcPresets, kEobBaseNpcPresetsProvider },
-	{ kEob2Npc1Strings, kEob2Npc1StringsProvider },
-	{ kEob2Npc2Strings, kEob2Npc2StringsProvider },
-	{ kEob2MonsterDustStrings, kEob2MonsterDustStringsProvider },
-	{ kEob2DreamSteps, kEob2DreamStepsProvider },
-	{ kEob2KheldranStrings, kEob2KheldranStringsProvider },
-	{ kEob2HornStrings, kEob2HornStringsProvider },
-	{ kEob2HornSounds, kEob2HornSoundsProvider },
-	{ kEob2WallOfForceDsX, kEob2WallOfForceDsXProvider },
-	{ kEob2WallOfForceDsY, kEob2WallOfForceDsYProvider },
-	{ kEob2WallOfForceNumW, kEob2WallOfForceNumWProvider },
-	{ kEob2WallOfForceNumH, kEob2WallOfForceNumHProvider },
-	{ kEob2WallOfForceShpId, kEob2WallOfForceShpIdProvider },
+	{ kEoBBaseMonsterProximityTable, kEoBBaseMonsterProximityTableProvider },
+	{ kEoBBaseFindBlockMonstersTable, kEoBBaseFindBlockMonstersTableProvider },
+	{ kEoBBaseMonsterDirChangeTable, kEoBBaseMonsterDirChangeTableProvider },
+	{ kEoBBaseMonsterDistAttStrings, kEoBBaseMonsterDistAttStringsProvider },
+	{ kEoBBaseEncodeMonsterDefs, kEoBBaseEncodeMonsterDefsProvider },
+	{ kEoBBaseNpcPresets, kEoBBaseNpcPresetsProvider },
+	{ kEoB2Npc1Strings, kEoB2Npc1StringsProvider },
+	{ kEoB2Npc2Strings, kEoB2Npc2StringsProvider },
+	{ kEoB2MonsterDustStrings, kEoB2MonsterDustStringsProvider },
+	{ kEoB2DreamSteps, kEoB2DreamStepsProvider },
+	{ kEoB2KheldranStrings, kEoB2KheldranStringsProvider },
+	{ kEoB2HornStrings, kEoB2HornStringsProvider },
+	{ kEoB2HornSounds, kEoB2HornSoundsProvider },
+	{ kEoB2WallOfForceDsX, kEoB2WallOfForceDsXProvider },
+	{ kEoB2WallOfForceDsY, kEoB2WallOfForceDsYProvider },
+	{ kEoB2WallOfForceNumW, kEoB2WallOfForceNumWProvider },
+	{ kEoB2WallOfForceNumH, kEoB2WallOfForceNumHProvider },
+	{ kEoB2WallOfForceShpId, kEoB2WallOfForceShpIdProvider },
 	
-	{ kLolIngamePakFiles, kLolIngamePakFilesProvider },
-	{ kLolCharacterDefs, kLolCharacterDefsProvider },
-	{ kLolIngameSfxFiles, kLolIngameSfxFilesProvider },
-	{ kLolIngameSfxIndex, kLolIngameSfxIndexProvider },
-	{ kLolMusicTrackMap, kLolMusicTrackMapProvider },
-	{ kLolIngameGMSfxIndex, kLolIngameGMSfxIndexProvider },
-	{ kLolIngameMT32SfxIndex, kLolIngameMT32SfxIndexProvider },
-	{ kLolIngamePcSpkSfxIndex, kLolIngamePcSpkSfxIndexProvider },
-	{ kLolSpellProperties, kLolSpellPropertiesProvider },
-	{ kLolGameShapeMap, kLolGameShapeMapProvider },
-	{ kLolSceneItemOffs, kLolSceneItemOffsProvider },
-	{ kLolCharInvIndex, kLolCharInvIndexProvider },
-	{ kLolCharInvDefs, kLolCharInvDefsProvider },
-	{ kLolCharDefsMan, kLolCharDefsManProvider },
-	{ kLolCharDefsWoman, kLolCharDefsWomanProvider },
-	{ kLolCharDefsKieran, kLolCharDefsKieranProvider },
-	{ kLolCharDefsAkshel, kLolCharDefsAkshelProvider },
-	{ kLolExpRequirements, kLolExpRequirementsProvider },
-	{ kLolMonsterModifiers, kLolMonsterModifiersProvider },
-	{ kLolMonsterShiftOffsets, kLolMonsterShiftOffsetsProvider },
-	{ kLolMonsterDirFlags, kLolMonsterDirFlagsProvider },
-	{ kLolMonsterScaleY, kLolMonsterScaleYProvider },
-	{ kLolMonsterScaleX, kLolMonsterScaleXProvider },
-	{ kLolMonsterScaleWH, kLolMonsterScaleWHProvider },
-	{ kLolFlyingObjectShp, kLolFlyingObjectShpProvider },
-	{ kLolInventoryDesc, kLolInventoryDescProvider },
-	{ kLolLevelShpList, kLolLevelShpListProvider },
-	{ kLolLevelDatList, kLolLevelDatListProvider },
-	{ kLolCompassDefs, kLolCompassDefsProvider },
-	{ kLolItemPrices, kLolItemPricesProvider },
-	{ kLolStashSetup, kLolStashSetupProvider },
-	{ kLolDscWalls, kLolDscWallsProvider },
-	{ kLolEobCommonDscShapeIndex, kLolEobCommonDscShapeIndexProvider },
-	{ kLolDscOvlMap, kLolDscOvlMapProvider },
-	{ kLolDscScaleWidthData, kLolDscScaleWidthDataProvider },
-	{ kLolDscScaleHeightData, kLolDscScaleHeightDataProvider },
-	{ kLolEobCommonDscX, kLolEobCommonDscXProvider },
-	{ kLolDscY, kLolDscYProvider },
-	{ kLolEobCommonDscTileIndex, kLolEobCommonDscTileIndexProvider },
-	{ kLolEobCommonDscUnk2, kLolEobCommonDscUnk2Provider },
-	{ kLolEobCommonDscDoorShapeIndex, kLolEobCommonDscDoorShapeIndexProvider },
-	{ kLolEobCommonDscDimData1, kLolEobCommonDscDimData1Provider },
-	{ kLolEobCommonDscDimData2, kLolEobCommonDscDimData2Provider },
-	{ kLolEobCommonDscBlockMap, kLolEobCommonDscBlockMapProvider },
-	{ kLolEobCommonDscDimMap, kLolEobCommonDscDimMapProvider },
-	{ kLolDscOvlIndex, kLolDscOvlIndexProvider },
-	{ kLolEobCommonDscBlockIndex, kLolEobCommonDscBlockIndexProvider },
-	{ kLolEobCommonDscDoorY2, kLolEobCommonDscDoorY2Provider },
-	{ kLolDscDoorScale, kLolDscDoorScaleProvider },
-	{ kLolDscDoor4, kLolDscDoor4Provider },
-	{ kLolDscDoorX, kLolDscDoorXProvider },
-	{ kLolDscDoorY, kLolDscDoorYProvider },
-	{ kLolScrollXTop, kLolScrollXTopProvider },
-	{ kLolScrollYTop, kLolScrollYTopProvider },
-	{ kLolScrollXBottom, kLolScrollXBottomProvider },
-	{ kLolScrollYBottom, kLolScrollYBottomProvider },
-	{ kLolButtonDefs, kLolButtonDefsProvider },
-	{ kLolButtonList1, kLolButtonList1Provider },
-	{ kLolButtonList2, kLolButtonList2Provider },
-	{ kLolButtonList3, kLolButtonList3Provider },
-	{ kLolButtonList4, kLolButtonList4Provider },
-	{ kLolButtonList5, kLolButtonList5Provider },
-	{ kLolButtonList6, kLolButtonList6Provider },
-	{ kLolButtonList7, kLolButtonList7Provider },
-	{ kLolButtonList8, kLolButtonList8Provider },
-	{ kLolLegendData, kLolLegendDataProvider },
-	{ kLolMapCursorOvl, kLolMapCursorOvlProvider },
-	{ kLolMapStringId, kLolMapStringIdProvider },
-	{ kLolSpellbookAnim, kLolSpellbookAnimProvider },
-	{ kLolSpellbookCoords, kLolSpellbookCoordsProvider },
-	{ kLolHealShapeFrames, kLolHealShapeFramesProvider },
-	{ kLolLightningDefs, kLolLightningDefsProvider },
-	{ kLolFireballCoords, kLolFireballCoordsProvider },
-	{ kLolCredits, kLolCreditsProvider },
-	{ kLolHistory, kLolHistoryProvider },
+	{ kLoLIngamePakFiles, kLoLIngamePakFilesProvider },
+	{ kLoLCharacterDefs, kLoLCharacterDefsProvider },
+	{ kLoLIngameSfxFiles, kLoLIngameSfxFilesProvider },
+	{ kLoLIngameSfxIndex, kLoLIngameSfxIndexProvider },
+	{ kLoLMusicTrackMap, kLoLMusicTrackMapProvider },
+	{ kLoLIngameGMSfxIndex, kLoLIngameGMSfxIndexProvider },
+	{ kLoLIngameMT32SfxIndex, kLoLIngameMT32SfxIndexProvider },
+	{ kLoLIngamePcSpkSfxIndex, kLoLIngamePcSpkSfxIndexProvider },
+	{ kLoLSpellProperties, kLoLSpellPropertiesProvider },
+	{ kLoLGameShapeMap, kLoLGameShapeMapProvider },
+	{ kLoLSceneItemOffs, kLoLSceneItemOffsProvider },
+	{ kLoLCharInvIndex, kLoLCharInvIndexProvider },
+	{ kLoLCharInvDefs, kLoLCharInvDefsProvider },
+	{ kLoLCharDefsMan, kLoLCharDefsManProvider },
+	{ kLoLCharDefsWoman, kLoLCharDefsWomanProvider },
+	{ kLoLCharDefsKieran, kLoLCharDefsKieranProvider },
+	{ kLoLCharDefsAkshel, kLoLCharDefsAkshelProvider },
+	{ kLoLExpRequirements, kLoLExpRequirementsProvider },
+	{ kLoLMonsterModifiers, kLoLMonsterModifiersProvider },
+	{ kLoLMonsterShiftOffsets, kLoLMonsterShiftOffsetsProvider },
+	{ kLoLMonsterDirFlags, kLoLMonsterDirFlagsProvider },
+	{ kLoLMonsterScaleY, kLoLMonsterScaleYProvider },
+	{ kLoLMonsterScaleX, kLoLMonsterScaleXProvider },
+	{ kLoLMonsterScaleWH, kLoLMonsterScaleWHProvider },
+	{ kLoLFlyingObjectShp, kLoLFlyingObjectShpProvider },
+	{ kLoLInventoryDesc, kLoLInventoryDescProvider },
+	{ kLoLLevelShpList, kLoLLevelShpListProvider },
+	{ kLoLLevelDatList, kLoLLevelDatListProvider },
+	{ kLoLCompassDefs, kLoLCompassDefsProvider },
+	{ kLoLItemPrices, kLoLItemPricesProvider },
+	{ kLoLStashSetup, kLoLStashSetupProvider },
+	{ kLoLDscWalls, kLoLDscWallsProvider },
+	{ kRpgCommonDscShapeIndex, kRpgCommonDscShapeIndexProvider },
+	{ kLoLDscOvlMap, kLoLDscOvlMapProvider },
+	{ kLoLDscScaleWidthData, kLoLDscScaleWidthDataProvider },
+	{ kLoLDscScaleHeightData, kLoLDscScaleHeightDataProvider },
+	{ kRpgCommonDscX, kRpgCommonDscXProvider },
+	{ kLoLDscY, kLoLDscYProvider },
+	{ kRpgCommonDscTileIndex, kRpgCommonDscTileIndexProvider },
+	{ kRpgCommonDscUnk2, kRpgCommonDscUnk2Provider },
+	{ kRpgCommonDscDoorShapeIndex, kRpgCommonDscDoorShapeIndexProvider },
+	{ kRpgCommonDscDimData1, kRpgCommonDscDimData1Provider },
+	{ kRpgCommonDscDimData2, kRpgCommonDscDimData2Provider },
+	{ kRpgCommonDscBlockMap, kRpgCommonDscBlockMapProvider },
+	{ kRpgCommonDscDimMap, kRpgCommonDscDimMapProvider },
+	{ kLoLDscOvlIndex, kLoLDscOvlIndexProvider },
+	{ kRpgCommonDscBlockIndex, kRpgCommonDscBlockIndexProvider },
+	{ kRpgCommonDscDoorY2, kRpgCommonDscDoorY2Provider },
+	{ kLoLDscDoorScale, kLoLDscDoorScaleProvider },
+	{ kLoLDscDoor4, kLoLDscDoor4Provider },
+	{ kLoLDscDoorX, kLoLDscDoorXProvider },
+	{ kLoLDscDoorY, kLoLDscDoorYProvider },
+	{ kLoLScrollXTop, kLoLScrollXTopProvider },
+	{ kLoLScrollYTop, kLoLScrollYTopProvider },
+	{ kLoLScrollXBottom, kLoLScrollXBottomProvider },
+	{ kLoLScrollYBottom, kLoLScrollYBottomProvider },
+	{ kLoLButtonDefs, kLoLButtonDefsProvider },
+	{ kLoLButtonList1, kLoLButtonList1Provider },
+	{ kLoLButtonList2, kLoLButtonList2Provider },
+	{ kLoLButtonList3, kLoLButtonList3Provider },
+	{ kLoLButtonList4, kLoLButtonList4Provider },
+	{ kLoLButtonList5, kLoLButtonList5Provider },
+	{ kLoLButtonList6, kLoLButtonList6Provider },
+	{ kLoLButtonList7, kLoLButtonList7Provider },
+	{ kLoLButtonList8, kLoLButtonList8Provider },
+	{ kLoLLegendData, kLoLLegendDataProvider },
+	{ kLoLMapCursorOvl, kLoLMapCursorOvlProvider },
+	{ kLoLMapStringId, kLoLMapStringIdProvider },
+	{ kLoLSpellbookAnim, kLoLSpellbookAnimProvider },
+	{ kLoLSpellbookCoords, kLoLSpellbookCoordsProvider },
+	{ kLoLHealShapeFrames, kLoLHealShapeFramesProvider },
+	{ kLoLLightningDefs, kLoLLightningDefsProvider },
+	{ kLoLFireballCoords, kLoLFireballCoordsProvider },
+	{ kLoLCredits, kLoLCreditsProvider },
+	{ kLoLHistory, kLoLHistoryProvider },
 	{ -1, NULL }
 };
 
diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index b190e11..2990c6e 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -30,10 +30,10 @@ namespace Kyra {
 
 class CharacterGenerator {
 public:
-	CharacterGenerator(EobCoreEngine *vm, Screen_Eob *screen);
+	CharacterGenerator(EoBCoreEngine *vm, Screen_EoB *screen);
 	~CharacterGenerator();
 
-	bool start(EobCharacter *characters, uint8 ***faceShapes);
+	bool start(EoBCharacter *characters, uint8 ***faceShapes);
 
 private:
 	void init();
@@ -89,9 +89,9 @@ private:
 	const uint8 *_chargenRaceMinStats;
 	const uint16 *_chargenRaceMaxStats;
 
-	static const EobChargenButtonDef _chargenButtonDefs[];
+	static const EoBChargenButtonDef _chargenButtonDefs[];
 	static const CreatePartyModButton _chargenModButtons[];
-	static const EobRect8 _chargenButtonBodyCoords[];
+	static const EoBRect8 _chargenButtonBodyCoords[];
 	static const int16 _chargenBoxX[];
 	static const int16 _chargenBoxY[];
 	static const int16 _chargenNameFieldX[];
@@ -102,14 +102,14 @@ private:
 
 	static const int16 _raceModifiers[];
 
-	EobCharacter *_characters;
+	EoBCharacter *_characters;
 	uint8 **_faceShapes;
 
-	EobCoreEngine *_vm;
-	Screen_Eob *_screen;
+	EoBCoreEngine *_vm;
+	Screen_EoB *_screen;
 };
 
-CharacterGenerator::CharacterGenerator(EobCoreEngine *vm, Screen_Eob *screen) : _vm(vm), _screen(screen),
+CharacterGenerator::CharacterGenerator(EoBCoreEngine *vm, Screen_EoB *screen) : _vm(vm), _screen(screen),
 	_characters(0), _faceShapes(0), _chargenMagicShapes(0), _chargenButtonLabels(0), _chargenMagicShapeTimer(0),
 	_updateBoxShapesIndex(0), _lastUpdateBoxShapesIndex(0), _magicShapesBox(6), _activeBox(0) {
 
@@ -124,13 +124,13 @@ CharacterGenerator::CharacterGenerator(EobCoreEngine *vm, Screen_Eob *screen) :
 	memset(_chargenMaxStats, 0, sizeof(_chargenMaxStats));
 
 	int temp;
-	_chargenStrings1 = _vm->staticres()->loadStrings(kEobBaseChargenStrings1, temp);
-	_chargenStrings2 = _vm->staticres()->loadStrings(kEobBaseChargenStrings2, temp);
-	_chargenStartLevels = _vm->staticres()->loadRawData(kEobBaseChargenStartLevels, temp);
-	_chargenEnterGameStrings = _vm->staticres()->loadStrings(kEobBaseChargenEnterGameStrings, temp);
-	_chargenClassMinStats = _vm->staticres()->loadRawData(kEobBaseChargenClassMinStats, temp);
-	_chargenRaceMinStats = _vm->staticres()->loadRawData(kEobBaseChargenRaceMinStats, temp);
-	_chargenRaceMaxStats = _vm->staticres()->loadRawDataBe16(kEobBaseChargenRaceMaxStats, temp);
+	_chargenStrings1 = _vm->staticres()->loadStrings(kEoBBaseChargenStrings1, temp);
+	_chargenStrings2 = _vm->staticres()->loadStrings(kEoBBaseChargenStrings2, temp);
+	_chargenStartLevels = _vm->staticres()->loadRawData(kEoBBaseChargenStartLevels, temp);
+	_chargenEnterGameStrings = _vm->staticres()->loadStrings(kEoBBaseChargenEnterGameStrings, temp);
+	_chargenClassMinStats = _vm->staticres()->loadRawData(kEoBBaseChargenClassMinStats, temp);
+	_chargenRaceMinStats = _vm->staticres()->loadRawData(kEoBBaseChargenRaceMinStats, temp);
+	_chargenRaceMaxStats = _vm->staticres()->loadRawDataBe16(kEoBBaseChargenRaceMaxStats, temp);
 }
 
 CharacterGenerator::~CharacterGenerator() {
@@ -147,7 +147,7 @@ CharacterGenerator::~CharacterGenerator() {
 	}
 }
 
-bool CharacterGenerator::start(EobCharacter *characters, uint8 ***faceShapes) {
+bool CharacterGenerator::start(EoBCharacter *characters, uint8 ***faceShapes) {
 	if (!characters && !faceShapes)
 		return true;
 
@@ -244,7 +244,7 @@ void CharacterGenerator::init() {
 		_faceShapes[i] = _screen->encodeShape((i % 10) << 2, (i / 10) << 5, 4, 32, true);
 	_screen->_curPage = 0;
 
-	_screen->loadEobBitmap("CHARGEN", 0, 3, 3, 0);
+	_screen->loadEoBBitmap("CHARGEN", 0, 3, 3, 0);
 	_screen->loadShapeSetBitmap("CHARGENB", 3, 3);
 	if (_chargenMagicShapes) {
 		for (int i = 0; i < 10; i++)
@@ -272,7 +272,7 @@ void CharacterGenerator::initButtonsFromList(int first, int numButtons) {
 	_vm->gui_resetButtonList();
 
 	for (int i = 0; i < numButtons; i++) {
-		const EobChargenButtonDef *e = &_chargenButtonDefs[first + i];
+		const EoBChargenButtonDef *e = &_chargenButtonDefs[first + i];
 		initButton(i, e->x, e->y, e->w, e->h, e->keyCode);
 	}
 
@@ -343,7 +343,7 @@ void CharacterGenerator::toggleSpecialButton(int index, int bodyCustom, int page
 		return;
 
 	const CreatePartyModButton *c = &_chargenModButtons[index];
-	const EobRect8 *p = &_chargenButtonBodyCoords[c->bodyIndex + bodyCustom];
+	const EoBRect8 *p = &_chargenButtonBodyCoords[c->bodyIndex + bodyCustom];
 
 	int x2 = 20;
 	int y2 = 0;
@@ -627,7 +627,7 @@ void CharacterGenerator::updateMagicShapes() {
 }
 
 void CharacterGenerator::generateStats(int index) {
-	EobCharacter *c = &_characters[index];
+	EoBCharacter *c = &_characters[index];
 
 	for (int i = 0; i < 3; i++) {
 		c->level[i] = _chargenStartLevels[(c->cClass << 2) + i];
@@ -674,7 +674,7 @@ void CharacterGenerator::modifyMenu() {
 	_vm->removeInputTop();
 	printStats(_activeBox, 3);
 
-	EobCharacter *c = &_characters[_activeBox];
+	EoBCharacter *c = &_characters[_activeBox];
 	int8 hpLO = c->hitPointsCur;
 
 	for (int i = 0; i >= 0 && i < 7; ) {
@@ -874,7 +874,7 @@ void CharacterGenerator::printStats(int index, int mode) {
 	_screen->copyRegion(0, 0, 160, 0, 160, 128, 2, 2, Screen::CR_NO_P_CHECK);
 	_screen->_curPage = 2;
 
-	EobCharacter *c = &_characters[index];
+	EoBCharacter *c = &_characters[index];
 
 	if (mode != 4)
 		_screen->drawShape(2, c->faceShape, 224, 2, 0);
@@ -973,7 +973,7 @@ int CharacterGenerator::modifyStat(int index, int8 *stat1, int8 *stat2) {
 	_screen->printShadedText(statStr.c_str(), b->x + 32, b->y, 6, 0);
 	_screen->updateScreen();
 
-	EobCharacter *c = &_characters[_activeBox];
+	EoBCharacter *c = &_characters[_activeBox];
 
 	int ci = index;
 	uint8 v2 = s2 ? *s2 : 0;
@@ -1145,7 +1145,7 @@ void CharacterGenerator::finish() {
 		_characters[0].inventory[2] = _vm->duplicateItem(35);
 
 		for (int i = 0; i < 4; i++) {
-			EobCharacter *c = &_characters[i];
+			EoBCharacter *c = &_characters[i];
 			c->flags = 1;
 			c->food = 100;
 			c->id = i;
@@ -1193,7 +1193,7 @@ void CharacterGenerator::finish() {
 		static const int8 *itemList[] = { itemList0, itemList1, itemList2, itemList3 };
 
 		for (int i = 0; i < 4; i++) {
-			EobCharacter *c = &_characters[i];
+			EoBCharacter *c = &_characters[i];
 			c->flags = 1;
 			c->food = 100;
 			c->id = i;
@@ -1283,7 +1283,7 @@ void CharacterGenerator::finish() {
 	}
 
 	for (int i = 0; i < 4; i++) {
-		EobCharacter *c = &_characters[i];
+		EoBCharacter *c = &_characters[i];
 		c->strengthMax = c->strengthCur;
 		c->strengthExtMax = c->strengthExtCur;
 		c->intelligenceMax = c->intelligenceCur;
@@ -1325,7 +1325,7 @@ void CharacterGenerator::finish() {
 	}
 }
 
-const EobChargenButtonDef CharacterGenerator::_chargenButtonDefs[] = {
+const EoBChargenButtonDef CharacterGenerator::_chargenButtonDefs[] = {
 	{ 0x01, 0x37, 0x31, 0x32, 0x70 },
 	{ 0x09, 0x37, 0x31, 0x32, 0x71 },
 	{ 0x01, 0x77, 0x31, 0x32, 0x72 },
@@ -1389,7 +1389,7 @@ const CreatePartyModButton CharacterGenerator::_chargenModButtons[] = {
 	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x1C, 0xAC }
 };
 
-const EobRect8 CharacterGenerator::_chargenButtonBodyCoords[] = {
+const EoBRect8 CharacterGenerator::_chargenButtonBodyCoords[] = {
 	{ 0x00, 0x80, 0x04, 0x20 },
 	{ 0x04, 0x80, 0x04, 0x20 },
 	{ 0x08, 0x80, 0x04, 0x20 },
@@ -1426,11 +1426,11 @@ const int16 CharacterGenerator::_raceModifiers[] = {
 	0, 0, 0, 0,	1, -1, 0, 1, -1, 0, 0, 0, -1, 0, 0, 1, 0, 0
 };
 
-bool EobCoreEngine::startCharacterGeneration() {
+bool EoBCoreEngine::startCharacterGeneration() {
 	return CharacterGenerator(this, _screen).start(_characters, &_faceShapes);
 }
 
-bool EobCoreEngine::transferParty() {
+bool EoBCoreEngine::transferParty() {
 
 	return false;
 }
diff --git a/engines/kyra/darkmoon.cpp b/engines/kyra/darkmoon.cpp
index e44040b..304e5c9 100644
--- a/engines/kyra/darkmoon.cpp
+++ b/engines/kyra/darkmoon.cpp
@@ -28,7 +28,7 @@
 
 namespace Kyra {
 
-DarkMoonEngine::DarkMoonEngine(OSystem *system, const GameFlags &flags) : EobCoreEngine(system, flags) {
+DarkMoonEngine::DarkMoonEngine(OSystem *system, const GameFlags &flags) : EoBCoreEngine(system, flags) {
 	_seqIntro = _seqFinale = 0;
 	_shapesIntro = _shapesFinale = 0;
 	_dscDoorType5Offs = 0;
@@ -50,13 +50,13 @@ DarkMoonEngine::~DarkMoonEngine() {
 }
 
 Common::Error DarkMoonEngine::init() {
-	Common::Error err = EobCoreEngine::init();
+	Common::Error err = EoBCoreEngine::init();
 	if (err.getCode() != Common::kNoError)
 		return err;
 
 	initStaticResource();
 
-	_monsterProps = new EobMonsterProperty[10];
+	_monsterProps = new EoBMonsterProperty[10];
 
 	static const uint16 wX[] = { 221, 76 };
 	static const uint8 wY[] = { 189, 162 };
@@ -93,7 +93,7 @@ void DarkMoonEngine::startupNew() {
 	_currentBlock = 171;
 	_currentDirection = 2;
 	setHandItem(0);
-	EobCoreEngine::startupNew();
+	EoBCoreEngine::startupNew();
 }
 
 void DarkMoonEngine::drawNpcScene(int npcIndex) {
@@ -149,7 +149,7 @@ void DarkMoonEngine::runNpcDialogue(int npcIndex) {
 }
 
 void DarkMoonEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
-	EobItem *itm = &_items[_characters[charIndex].inventory[slot]];
+	EoBItem *itm = &_items[_characters[charIndex].inventory[slot]];
 	if (itm->type == 48 || itm->type == 62) {
 		if (itm->value == 5)
 			return;
@@ -278,7 +278,7 @@ void DarkMoonEngine::replaceMonster(int unit, uint16 block, int pos, int dir, in
 	initMonster(index, unit, block, pos, dir, type, shpIndex, mode, h2, randItem, fixedItem);
 }
 
-bool DarkMoonEngine::killMonsterExtra(EobMonsterInPlay *m) {
+bool DarkMoonEngine::killMonsterExtra(EoBMonsterInPlay *m) {
 	if (_currentLevel == 16 && _currentSub == 1 && (_monsterProps[m->type].capsFlags & 4)) {
 		if (m->type) {
 			_playFinale = true;
@@ -464,7 +464,7 @@ int DarkMoonEngine::charSelectDialogue() {
 }
 
 void DarkMoonEngine::characterLevelGain(int charIndex) {
-	EobCharacter *c = &_characters[charIndex];
+	EoBCharacter *c = &_characters[charIndex];
 	int s = _numLevelsPerClass[c->cClass];
 	for (int i = 0; i < s; i++) {
 		uint32 er = getRequiredExperience(c->cClass, i, c->level[i] + 1);
diff --git a/engines/kyra/darkmoon.h b/engines/kyra/darkmoon.h
index 35eb90a..590b2f4 100644
--- a/engines/kyra/darkmoon.h
+++ b/engines/kyra/darkmoon.h
@@ -31,7 +31,7 @@ namespace Kyra {
 
 class DarkmoonSequenceHelper;
 
-struct EobSequenceStep {
+struct EoBSequenceStep {
 	uint8 command;
 	uint8 obj;
 	int16 x1;
@@ -44,8 +44,8 @@ struct EobSequenceStep {
 	uint8 h;
 };
 
-class DarkMoonEngine : public EobCoreEngine {
-friend class GUI_Eob;
+class DarkMoonEngine : public EoBCoreEngine {
+friend class GUI_EoB;
 friend class DarkmoonSequenceHelper;
 public:
 	DarkMoonEngine(OSystem *system, const GameFlags &flags);
@@ -74,14 +74,14 @@ private:
 
 	const char * const *_introStrings;
 	const char * const *_cpsFilesIntro;
-	const EobSequenceStep **_seqIntro;
-	const EobShapeDef **_shapesIntro;
+	const EoBSequenceStep **_seqIntro;
+	const EoBShapeDef **_shapesIntro;
 
 	const char * const *_finaleStrings;
 	const uint8 *_creditsData;
 	const char * const *_cpsFilesFinale;
-	const EobSequenceStep **_seqFinale;
-	const EobShapeDef **_shapesFinale;
+	const EoBSequenceStep **_seqFinale;
+	const EoBShapeDef **_shapesFinale;
 
 	static const char *_palFilesIntro[];
 	static const char *_palFilesFinale[];
@@ -108,7 +108,7 @@ private:
 	void generateMonsterPalettes(const char *file, int16 monsterIndex);
 	void loadMonsterDecoration(const char *file, int16 monsterIndex);
 	void replaceMonster(int unit, uint16 block, int d, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem);
-	bool killMonsterExtra(EobMonsterInPlay *m);
+	bool killMonsterExtra(EoBMonsterInPlay *m);
 
 	// Level
 	const uint8 *loadDoorShapes(const char *filename, int doorIndex, const uint8 *shapeDefs);
diff --git a/engines/kyra/debugger.cpp b/engines/kyra/debugger.cpp
index 6a4b88c..96003d9 100644
--- a/engines/kyra/debugger.cpp
+++ b/engines/kyra/debugger.cpp
@@ -472,7 +472,7 @@ Debugger_LoL::Debugger_LoL(LoLEngine *vm) : Debugger(vm), _vm(vm) {
 #endif // ENABLE_LOL
 
 #ifdef ENABLE_EOB
-Debugger_Eob::Debugger_Eob(EobCoreEngine *vm) : Debugger(vm), _vm(vm) {
+Debugger_EoB::Debugger_EoB(EoBCoreEngine *vm) : Debugger(vm), _vm(vm) {
 }
 #endif // ENABLE_EOB
 
diff --git a/engines/kyra/debugger.h b/engines/kyra/debugger.h
index 1bd8363..77f1a9a 100644
--- a/engines/kyra/debugger.h
+++ b/engines/kyra/debugger.h
@@ -109,14 +109,14 @@ protected:
 #endif // ENABLE_LOL
 
 #ifdef ENABLE_EOB
-class EobCoreEngine;
+class EoBCoreEngine;
 
-class Debugger_Eob : public Debugger {
+class Debugger_EoB : public Debugger {
 public:
-	Debugger_Eob(EobCoreEngine *vm);
+	Debugger_EoB(EoBCoreEngine *vm);
 
 protected:
-	EobCoreEngine *_vm;
+	EoBCoreEngine *_vm;
 };
 #endif // ENABLE_EOB
 
diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp
index e021a3a..56ad427 100644
--- a/engines/kyra/detection.cpp
+++ b/engines/kyra/detection.cpp
@@ -134,7 +134,7 @@ bool KyraMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGame
 #endif // ENABLE_LOL
 #ifdef ENABLE_EOB
 	case Kyra::GI_EOB1:
-		*engine = new Kyra::EobEngine(syst, flags);
+		*engine = new Kyra::EoBEngine(syst, flags);
 		break;
 	case Kyra::GI_EOB2:
 		*engine = new Kyra::DarkMoonEngine(syst, flags);
diff --git a/engines/kyra/eob.cpp b/engines/kyra/eob.cpp
index d90a3ca..0010a51 100644
--- a/engines/kyra/eob.cpp
+++ b/engines/kyra/eob.cpp
@@ -28,7 +28,7 @@
 
 namespace Kyra {
 
-EobEngine::EobEngine(OSystem *system, const GameFlags &flags) : EobCoreEngine(system, flags) {
+EoBEngine::EoBEngine(OSystem *system, const GameFlags &flags) : EoBCoreEngine(system, flags) {
 	_numSpells = 53;
 	_menuChoiceInit = 4;
 
@@ -42,12 +42,12 @@ EobEngine::EobEngine(OSystem *system, const GameFlags &flags) : EobCoreEngine(sy
 	_dscDoorCoordsExt = 0;
 }
 
-EobEngine::~EobEngine() {
+EoBEngine::~EoBEngine() {
 	delete[] _itemsOverlay;
 }
 
-Common::Error EobEngine::init() {
-	Common::Error err = EobCoreEngine::init();
+Common::Error EoBEngine::init() {
+	Common::Error err = EoBCoreEngine::init();
 	if (err.getCode() != Common::kNoError)
 		return err;
 
@@ -90,21 +90,21 @@ Common::Error EobEngine::init() {
 	return Common::kNoError;
 }
 
-void EobEngine::startupNew() {
+void EoBEngine::startupNew() {
 	_currentLevel = 1;
 	_currentSub = 0;
 	loadLevel(1, 0);
 	_currentBlock = 490;
 	_currentDirection = 0;
 	setHandItem(0);
-	EobCoreEngine::startupNew();
+	EoBCoreEngine::startupNew();
 }
 
-void EobEngine::startupLoad() {
+void EoBEngine::startupLoad() {
 	_sound->loadSoundFile("ADLIB");
 }
 
-void EobEngine::drawNpcScene(int npcIndex) {
+void EoBEngine::drawNpcScene(int npcIndex) {
 	_screen->copyRegion(0, 0, 0, 0, 176, 120, 6, 0, Screen::CR_NO_P_CHECK);
 	switch (npcIndex) {
 	case 0:
@@ -155,7 +155,7 @@ void EobEngine::drawNpcScene(int npcIndex) {
 	}
 }
 
-void EobEngine::encodeDrawNpcSeqShape(int npcIndex, int drawX, int drawY) {
+void EoBEngine::encodeDrawNpcSeqShape(int npcIndex, int drawX, int drawY) {
 	const uint8 *shpDef = &_npcShpData[npcIndex << 2];
 	_screen->_curPage = 2;
 	const uint8 *shp = _screen->encodeShape(shpDef[0], shpDef[1], shpDef[2], shpDef[3]);
@@ -169,7 +169,7 @@ void EobEngine::encodeDrawNpcSeqShape(int npcIndex, int drawX, int drawY) {
 #define DLG2A3(cond, txt, buttonstr1, buttonstr2) ((cond) ? (DLG2(txt, buttonstr1) ? 2 : 0) : DLG3(txt, buttonstr2))
 #define TXT(txt) _txt->printDialogueText(txt, _moreStrings[0])
 
-void EobEngine::runNpcDialogue(int npcIndex) {
+void EoBEngine::runNpcDialogue(int npcIndex) {
 	int r = 0;
 	int a = 0;
 	Item itm = 0;
@@ -327,8 +327,8 @@ void EobEngine::runNpcDialogue(int npcIndex) {
 #undef DLG3
 #undef DLG2A3
 
-void EobEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
-	EobItem *itm = &_items[_characters[charIndex].inventory[slot]];
+void EoBEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
+	EoBItem *itm = &_items[_characters[charIndex].inventory[slot]];
 	if (itm->type == 48) {
 		int charges = itm->flags & 0x3f;
 		if (--charges)
@@ -340,7 +340,7 @@ void EobEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
 	}
 }
 
-void EobEngine::replaceMonster(int unit, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem) {
+void EoBEngine::replaceMonster(int unit, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem) {
 	if (_levelBlockProperties[block].flags & 7)
 		return;
 
@@ -352,7 +352,7 @@ void EobEngine::replaceMonster(int unit, uint16 block, int pos, int dir, int typ
 	}
 }
 
-void EobEngine::updateScriptTimersExtra() {
+void EoBEngine::updateScriptTimersExtra() {
 	int cnt = 0;
 	for (int i = 1; i < 30; i++) {
 		if (_monsters[i].hitPointsCur <= 0)
@@ -369,7 +369,7 @@ void EobEngine::updateScriptTimersExtra() {
 	}
 }
 
-void EobEngine::loadDoorShapes(int doorType1, int shapeId1, int doorType2, int shapeId2) {
+void EoBEngine::loadDoorShapes(int doorType1, int shapeId1, int doorType2, int shapeId2) {
 	_screen->loadShapeSetBitmap("DOOR", 5, 3);
 	_screen->_curPage = 2;
 
@@ -398,7 +398,7 @@ void EobEngine::loadDoorShapes(int doorType1, int shapeId1, int doorType2, int s
 	_screen->_curPage = 0;
 }
 
-void EobEngine::drawDoorIntern(int type, int index, int x, int y, int w, int wall, int mDim, int16 y1, int16 y2) {
+void EoBEngine::drawDoorIntern(int type, int index, int x, int y, int w, int wall, int mDim, int16 y1, int16 y2) {
 	int shapeIndex = type + 2 - mDim;
 	uint8 *shp = _doorShapes[shapeIndex];
 
@@ -467,7 +467,7 @@ void EobEngine::drawDoorIntern(int type, int index, int x, int y, int w, int wal
 	}
 }
 
-void EobEngine::turnUndeadAuto() {
+void EoBEngine::turnUndeadAuto() {
 	if (_currentLevel != 2 && _currentLevel != 7)
 		return;
 
@@ -477,7 +477,7 @@ void EobEngine::turnUndeadAuto() {
 		if (!testCharacter(i, 0x0d))
 			continue;
 
-		EobCharacter *c = &_characters[i];
+		EoBCharacter *c = &_characters[i];
 
 		if (_itemTypes[_items[c->inventory[0]].type].extraProperties != 6 && _itemTypes[_items[c->inventory[1]].type].extraProperties != 6)
 			continue;
@@ -506,12 +506,12 @@ void EobEngine::turnUndeadAuto() {
 	_openBookCasterLevel = 0;
 }
 
-void EobEngine::turnUndeadAutoHit() {
+void EoBEngine::turnUndeadAutoHit() {
 	_txt->printMessage(_turnUndeadString[0], -1, _characters[_openBookChar].name);
 	sparkEffectOffensive();
 }
 
-bool EobEngine::checkPartyStatusExtra() {
+bool EoBEngine::checkPartyStatusExtra() {
 	_screen->copyPage(0, 10);
 	int cd = _screen->curDimIndex();
 	gui_drawBox(0, 121, 320, 80, _color1_1, _color2_1, _bkgColor_1);
@@ -529,7 +529,7 @@ bool EobEngine::checkPartyStatusExtra() {
 	return true;
 }
 
-int EobEngine::resurrectionSelectDialogue() {
+int EoBEngine::resurrectionSelectDialogue() {
 	gui_drawDialogueBox();
 	_txt->printDialogueText(_npcStrings[0][1]);
 
@@ -548,7 +548,7 @@ int EobEngine::resurrectionSelectDialogue() {
 	return 1;
 }
 
-void EobEngine::healParty() {
+void EoBEngine::healParty() {
 	int cnt = rollDice(1, 3, 2);
 	for (int i = 0; i < 6 && cnt; i++) {
 		if (testCharacter(i, 3))
diff --git a/engines/kyra/eob.h b/engines/kyra/eob.h
index 2dfccca..0f83c47 100644
--- a/engines/kyra/eob.h
+++ b/engines/kyra/eob.h
@@ -29,11 +29,11 @@
 
 namespace Kyra {
 
-class EobEngine : public EobCoreEngine {
-friend class GUI_Eob;
+class EoBEngine : public EoBCoreEngine {
+friend class GUI_EoB;
 public:
-	EobEngine(OSystem *system, const GameFlags &flags);
-	~EobEngine();
+	EoBEngine(OSystem *system, const GameFlags &flags);
+	~EoBEngine();
 
 private:
 	// Init / Release
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index dfa465c..ebd26d3 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -36,7 +36,7 @@
 
 namespace Kyra {
 
-EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : KyraRpgEngine(system, flags), _numLargeItemShapes(flags.gameID == GI_EOB1 ? 14 : 11),
+EoBCoreEngine::EoBCoreEngine(OSystem *system, const GameFlags &flags) : KyraRpgEngine(system, flags), _numLargeItemShapes(flags.gameID == GI_EOB1 ? 14 : 11),
 	_numSmallItemShapes(flags.gameID == GI_EOB1 ? 23 : 26), _numThrownItemShapes(flags.gameID == GI_EOB1 ? 12 : 9), _numItemIconShapes(flags.gameID == GI_EOB1 ? 89 : 112),
 	_teleporterWallId(flags.gameID == GI_EOB1 ? 52 : 44) {
 	_screen = 0;
@@ -212,7 +212,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : KyraRpgE
 #undef DWM0
 }
 
-EobCoreEngine::~EobCoreEngine() {
+EoBCoreEngine::~EoBCoreEngine() {
 	releaseItemsAndDecorationsShapes();
 	releaseTempData();
 
@@ -292,12 +292,12 @@ EobCoreEngine::~EobCoreEngine() {
 	_txt = 0;
 }
 
-Common::Error EobCoreEngine::init() {
+Common::Error EoBCoreEngine::init() {
 	// In EOB the timer proc is directly invoked via interrupt 0x1c, 18.2 times per second.
 	// This makes a tick length of 54.94.
 	_tickLength = 55;
 
-	_screen = new Screen_Eob(this, _system);
+	_screen = new Screen_EoB(this, _system);
 
 	assert(_screen);
 	_screen->setResolution();
@@ -333,13 +333,13 @@ Common::Error EobCoreEngine::init() {
 	}
 
 	setupKeyMap();
-	_gui = new GUI_Eob(this);
+	_gui = new GUI_EoB(this);
 	assert(_gui);
 	_txt = new TextDisplayer_rpg(this, _screen);
 	assert(_txt);
-	_inf = new EobInfProcessor(this, _screen);
+	_inf = new EoBInfProcessor(this, _screen);
 	assert(_inf);
-	_debugger = new Debugger_Eob(this);
+	_debugger = new Debugger_EoB(this);
 	assert(_debugger);
 
 	_screen->loadFont(Screen::FID_6_FNT, "FONT6.FNT");
@@ -375,14 +375,14 @@ Common::Error EobCoreEngine::init() {
 
 	_wllVcnOffset = 16;
 
-	_monsters = new EobMonsterInPlay[30];
-	memset(_monsters, 0, 30 * sizeof(EobMonsterInPlay));
+	_monsters = new EoBMonsterInPlay[30];
+	memset(_monsters, 0, 30 * sizeof(EoBMonsterInPlay));
 
-	_characters = new EobCharacter[6];
-	memset(_characters, 0, sizeof(EobCharacter) * 6);
+	_characters = new EoBCharacter[6];
+	memset(_characters, 0, sizeof(EoBCharacter) * 6);
 
-	_items = new EobItem[600];
-	memset(_items, 0, sizeof(EobItem) * 600);
+	_items = new EoBItem[600];
+	memset(_items, 0, sizeof(EoBItem) * 600);
 
 	_itemNames = new char*[130];
 	for (int i = 0; i < 130; i++) {
@@ -390,9 +390,9 @@ Common::Error EobCoreEngine::init() {
 		memset(_itemNames[i], 0, 35);
 	}
 
-	_flyingObjects = new EobFlyingObject[_numFlyingObjects];
+	_flyingObjects = new EoBFlyingObject[_numFlyingObjects];
 	_flyingObjectsPtr = _flyingObjects;
-	memset(_flyingObjects, 0, _numFlyingObjects * sizeof(EobFlyingObject));
+	memset(_flyingObjects, 0, _numFlyingObjects * sizeof(EoBFlyingObject));
 
 	_spellAnimBuffer = new uint8[4096];
 	memset(_spellAnimBuffer, 0, 4096);
@@ -426,7 +426,7 @@ Common::Error EobCoreEngine::init() {
 	return Common::kNoError;
 }
 
-Common::Error EobCoreEngine::go() {
+Common::Error EoBCoreEngine::go() {
 	_txt->removePageBreakFlag();
 	_screen->loadPalette("palette.col", _screen->getPalette(0));
 	_screen->setScreenPalette(_screen->getPalette(0));
@@ -482,12 +482,12 @@ Common::Error EobCoreEngine::go() {
 	return Common::kNoError;
 }
 
-void EobCoreEngine::registerDefaultSettings() {
+void EoBCoreEngine::registerDefaultSettings() {
 	KyraEngine_v1::registerDefaultSettings();
 	ConfMan.registerDefault("hpbargraphs", true);
 }
 
-void EobCoreEngine::readSettings() {
+void EoBCoreEngine::readSettings() {
 	_configHpBarGraphs = ConfMan.getBool("hpbargraphs");
 	_configSounds = ConfMan.getBool("sfx_mute") ? 0 : 1;
 	_configMusic = _configSounds ? 1 : 0;
@@ -496,7 +496,7 @@ void EobCoreEngine::readSettings() {
 		_sound->enableSFX(_configSounds);
 }
 
-void EobCoreEngine::writeSettings() {
+void EoBCoreEngine::writeSettings() {
 	ConfMan.setBool("hpbargraphs", _configHpBarGraphs);
 	ConfMan.setBool("sfx_mute", _configSounds == 0);
 
@@ -510,7 +510,7 @@ void EobCoreEngine::writeSettings() {
 	ConfMan.flushToDisk();
 }
 
-void EobCoreEngine::startupNew() {
+void EoBCoreEngine::startupNew() {
 	gui_setPlayFieldButtons();
 	_screen->_curPage = 0;
 	gui_drawPlayField(false);
@@ -521,7 +521,7 @@ void EobCoreEngine::startupNew() {
 	_updateCharNum = 0;
 }
 
-void EobCoreEngine::runLoop() {
+void EoBCoreEngine::runLoop() {
 	_envAudioTimer = _system->getMillis() + (rollDice(1, 10, 3) * 18 * _tickLength);
 	_flashShapeTimer = 0;
 	_drawSceneTimer = _system->getMillis();
@@ -556,7 +556,7 @@ void EobCoreEngine::runLoop() {
 	}
 }
 
-bool EobCoreEngine::checkPartyStatus(bool handleDeath) {
+bool EoBCoreEngine::checkPartyStatus(bool handleDeath) {
 	int numChars = 0;
 	for (int i = 0; i < 6; i++)
 		numChars += testCharacter(i, 13);
@@ -582,7 +582,7 @@ bool EobCoreEngine::checkPartyStatus(bool handleDeath) {
 	return false;
 }
 
-void EobCoreEngine::loadItemsAndDecorationsShapes() {
+void EoBCoreEngine::loadItemsAndDecorationsShapes() {
 	releaseItemsAndDecorationsShapes();
 	_screen->setCurPage(2);
 
@@ -653,7 +653,7 @@ void EobCoreEngine::loadItemsAndDecorationsShapes() {
 	}
 }
 
-void EobCoreEngine::releaseItemsAndDecorationsShapes() {
+void EoBCoreEngine::releaseItemsAndDecorationsShapes() {
 	if (_largeItemShapes) {
 		for (int i = 0; i < _numLargeItemShapes; i++) {
 			if (_largeItemShapes[i])
@@ -745,7 +745,7 @@ void EobCoreEngine::releaseItemsAndDecorationsShapes() {
 	delete[] _lightningColumnShape;
 }
 
-void EobCoreEngine::setHandItem(Item itemIndex) {
+void EoBCoreEngine::setHandItem(Item itemIndex) {
 	if (itemIndex == -1)
 		return;
 
@@ -771,13 +771,13 @@ void EobCoreEngine::setHandItem(Item itemIndex) {
 	_screen->setMouseCursor(mouseOffs, mouseOffs, shp);
 }
 
-int EobCoreEngine::getDexterityArmorClassModifier(int dexterity) {
+int EoBCoreEngine::getDexterityArmorClassModifier(int dexterity) {
 	static const int8 mod[] = { 5, 5, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, -2, -3, -4, -4, -5, -5, -5, -6, -6 };
 	return mod[dexterity];
 }
 
-int EobCoreEngine::generateCharacterHitpointsByLevel(int charIndex, int levelIndex) {
-	EobCharacter *c = &_characters[charIndex];
+int EoBCoreEngine::generateCharacterHitpointsByLevel(int charIndex, int levelIndex) {
+	EoBCharacter *c = &_characters[charIndex];
 	int m = getClassAndConstHitpointsModifier(c->cClass, c->constitutionCur);
 
 	int h = 0;
@@ -804,7 +804,7 @@ int EobCoreEngine::generateCharacterHitpointsByLevel(int charIndex, int levelInd
 	return h;
 }
 
-int EobCoreEngine::getClassAndConstHitpointsModifier(int cclass, int constitution) {
+int EoBCoreEngine::getClassAndConstHitpointsModifier(int cclass, int constitution) {
 	int res = _hpConstModifiers[constitution];
 	// This also applies to EOB1 despite being coded differently there
 	if (res <= 2 || (_classModifierFlags[cclass] & 0x31))
@@ -813,11 +813,11 @@ int EobCoreEngine::getClassAndConstHitpointsModifier(int cclass, int constitutio
 	return 2;
 }
 
-int EobCoreEngine::getCharacterClassType(int cclass, int levelIndex) {
+int EoBCoreEngine::getCharacterClassType(int cclass, int levelIndex) {
 	return _characterClassType[cclass * 3 + levelIndex];
 }
 
-int EobCoreEngine::getModifiedHpLimits(int hpModifier, int constModifier, int level, bool mode) {
+int EoBCoreEngine::getModifiedHpLimits(int hpModifier, int constModifier, int level, bool mode) {
 	int s = _hpIncrPerLevel[6 + hpModifier] > level ? level : _hpIncrPerLevel[6 + hpModifier];
 	int res = s;
 
@@ -835,7 +835,7 @@ int EobCoreEngine::getModifiedHpLimits(int hpModifier, int constModifier, int le
 	return res;
 }
 
-Common::String EobCoreEngine::getCharStrength(int str, int strExt) {
+Common::String EoBCoreEngine::getCharStrength(int str, int strExt) {
 	if (strExt) {
 		if (strExt == 100)
 			strExt = 0;
@@ -847,11 +847,11 @@ Common::String EobCoreEngine::getCharStrength(int str, int strExt) {
 	return _strenghtStr;
 }
 
-int EobCoreEngine::testCharacter(int index, int flags) {
+int EoBCoreEngine::testCharacter(int index, int flags) {
 	if (index == -1)
 		return 0;
 
-	EobCharacter *c = &_characters[index];
+	EoBCharacter *c = &_characters[index];
 	int res = 1;
 
 	if (flags & 1)
@@ -878,7 +878,7 @@ int EobCoreEngine::testCharacter(int index, int flags) {
 	return res;
 }
 
-int EobCoreEngine::getNextValidCharIndex(int curCharIndex, int searchStep) {
+int EoBCoreEngine::getNextValidCharIndex(int curCharIndex, int searchStep) {
 	do {
 		curCharIndex += searchStep;
 		if (curCharIndex < 0)
@@ -890,8 +890,8 @@ int EobCoreEngine::getNextValidCharIndex(int curCharIndex, int searchStep) {
 	return curCharIndex;
 }
 
-void EobCoreEngine::recalcArmorClass(int index) {
-	EobCharacter *c = &_characters[index];
+void EoBCoreEngine::recalcArmorClass(int index) {
+	EoBCharacter *c = &_characters[index];
 	int acm = getDexterityArmorClassModifier(c->dexterityCur);
 	c->armorClass = 10 + acm;
 
@@ -958,8 +958,8 @@ void EobCoreEngine::recalcArmorClass(int index) {
 		c->armorClass = -10;
 }
 
-int EobCoreEngine::validateWeaponSlotItem(int index, int slot) {
-	EobCharacter *c = &_characters[index];
+int EoBCoreEngine::validateWeaponSlotItem(int index, int slot) {
+	EoBCharacter *c = &_characters[index];
 	int itm1 = c->inventory[0];
 	int r = itemUsableByCharacter(index, itm1);
 	int tp1 = _items[itm1].type;
@@ -987,7 +987,7 @@ int EobCoreEngine::validateWeaponSlotItem(int index, int slot) {
 	return r;
 }
 
-int EobCoreEngine::getClericPaladinLevel(int index) {
+int EoBCoreEngine::getClericPaladinLevel(int index) {
 	if (_castScrollSlot)
 		return 9;
 
@@ -1007,7 +1007,7 @@ int EobCoreEngine::getClericPaladinLevel(int index) {
 	return 1;
 }
 
-int EobCoreEngine::getMageLevel(int index) {
+int EoBCoreEngine::getMageLevel(int index) {
 	if (_castScrollSlot)
 		return 9;
 
@@ -1018,7 +1018,7 @@ int EobCoreEngine::getMageLevel(int index) {
 	return (l > -1) ? _characters[index].level[l] : 1;
 }
 
-int EobCoreEngine::getCharacterLevelIndex(int type, int cClass) {
+int EoBCoreEngine::getCharacterLevelIndex(int type, int cClass) {
 	if (getCharacterClassType(cClass, 0) == type)
 		return 0;
 
@@ -1031,7 +1031,7 @@ int EobCoreEngine::getCharacterLevelIndex(int type, int cClass) {
 	return -1;
 }
 
-int EobCoreEngine::countCharactersWithSpecificItems(int16 itemType, int16 itemValue) {
+int EoBCoreEngine::countCharactersWithSpecificItems(int16 itemType, int16 itemValue) {
 	int res = 0;
 	for (int i = 0; i < 6; i++) {
 		if (!testCharacter(i, 1))
@@ -1042,7 +1042,7 @@ int EobCoreEngine::countCharactersWithSpecificItems(int16 itemType, int16 itemVa
 	return res;
 }
 
-int EobCoreEngine::checkInventoryForItem(int character, int16 itemType, int16 itemValue) {
+int EoBCoreEngine::checkInventoryForItem(int character, int16 itemType, int16 itemValue) {
 	for (int i = 0; i < 27; i++) {
 		uint16 inv = _characters[character].inventory[i];
 		if (!inv)
@@ -1055,11 +1055,11 @@ int EobCoreEngine::checkInventoryForItem(int character, int16 itemType, int16 it
 	return -1;
 }
 
-void EobCoreEngine::modifyCharacterHitpoints(int character, int16 points) {
+void EoBCoreEngine::modifyCharacterHitpoints(int character, int16 points) {
 	if (!testCharacter(character, 3))
 		return;
 
-	EobCharacter *c = &_characters[character];
+	EoBCharacter *c = &_characters[character];
 	c->hitPointsCur += points;
 	if (c->hitPointsCur > c->hitPointsMax)
 		c->hitPointsCur = c->hitPointsMax;
@@ -1068,14 +1068,14 @@ void EobCoreEngine::modifyCharacterHitpoints(int character, int16 points) {
 	gui_drawCharPortraitWithStats(character);
 }
 
-void EobCoreEngine::neutralizePoison(int character) {
+void EoBCoreEngine::neutralizePoison(int character) {
 	_characters[character].flags &= ~2;
 	_characters[character].effectFlags &= ~0x2000;
 	deleteCharEventTimer(character, -34);
 	gui_drawCharPortraitWithStats(character);
 }
 
-void EobCoreEngine::npcSequence(int npcIndex) {
+void EoBCoreEngine::npcSequence(int npcIndex) {
 	_screen->loadShapeSetBitmap("OUTTAKE", 5, 3);
 	_screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 6, Screen::CR_NO_P_CHECK);
 
@@ -1095,8 +1095,8 @@ void EobCoreEngine::npcSequence(int npcIndex) {
 	gui_restorePlayField();
 }
 
-void EobCoreEngine::initNpc(int npcIndex) {
-	EobCharacter *c = _characters;
+void EoBCoreEngine::initNpc(int npcIndex) {
+	EoBCharacter *c = _characters;
 	int i = 0;
 	for (; i < 6; i++) {
 		if (!(_characters[i].flags & 1)) {
@@ -1106,7 +1106,7 @@ void EobCoreEngine::initNpc(int npcIndex) {
 	}
 
 	delete[] c->faceShape;
-	memcpy(c, &_npcPreset[npcIndex], sizeof(EobCharacter));
+	memcpy(c, &_npcPreset[npcIndex], sizeof(EoBCharacter));
 	recalcArmorClass(i);
 
 	for (i = 0; i < 25; i++) {
@@ -1121,7 +1121,7 @@ void EobCoreEngine::initNpc(int npcIndex) {
 	_screen->_curPage = 0;
 }
 
-int EobCoreEngine::npcJoinDialogue(int npcIndex, int queryJoinTextId, int confirmJoinTextId, int noJoinTextId) {
+int EoBCoreEngine::npcJoinDialogue(int npcIndex, int queryJoinTextId, int confirmJoinTextId, int noJoinTextId) {
 	gui_drawDialogueBox();
 	_txt->printDialogueText(queryJoinTextId, 0);
 
@@ -1144,7 +1144,7 @@ int EobCoreEngine::npcJoinDialogue(int npcIndex, int queryJoinTextId, int confir
 	return r ^ 1;
 }
 
-int EobCoreEngine::prepareForNewPartyMember(int16 itemType, int16 itemValue) {


Commit: 8716ed1703f55b4c0e33a87cf40b65d06151c641
    https://github.com/scummvm/scummvm/commit/8716ed1703f55b4c0e33a87cf40b65d06151c641
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:16-08:00

Commit Message:
KYRA: (EOB/LOL) - again fix static resource loading for EOB when LOL is disabled

Changed paths:
    engines/kyra/resource.h
    engines/kyra/staticres.cpp
    engines/kyra/staticres_rpg.cpp



diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index f5d70e0..30cf17d 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -841,8 +841,8 @@ private:
 		kLoLCompassData = 10,
 		kLoLFlightShpData = 11,
 		kLoLButtonData = 12,
-		kLoLRawDataBe16 = 13,
-		kLoLRawDataBe32 = 14,
+		kRawDataBe16 = 13,
+		kRawDataBe32 = 14,
 
 		kEoB2SequenceData = 15,
 		kEoB2ShapeData = 16,
diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp
index 888b515..cd49b03 100644
--- a/engines/kyra/staticres.cpp
+++ b/engines/kyra/staticres.cpp
@@ -254,24 +254,27 @@ bool StaticResource::init() {
 		{ kLoLSpellData, proc(loadSpellData), proc(freeSpellData) },
 		{ kLoLCompassData, proc(loadCompassData), proc(freeCompassData) },
 		{ kLoLFlightShpData, proc(loadFlyingObjectData), proc(freeFlyingObjectData) },
-		{ kLoLRawDataBe16, proc(loadRawDataBe16), proc(freeRawDataBe16) },
-		{ kLoLRawDataBe32, proc(loadRawDataBe32), proc(freeRawDataBe32) },
-		{ kLoLButtonData, proc(loadButtonDefs), proc(freeButtonDefs) },
 #else
 		{ kLoLCharData, proc(loadDummy), proc(freeDummy) },
 		{ kLoLSpellData, proc(loadDummy), proc(freeDummy) },
 		{ kLoLCompassData, proc(loadDummy), proc(freeDummy) },
 		{ kLoLFlightShpData, proc(loadDummy), proc(freeDummy) },
-		{ kLoLRawDataBe16, proc(loadDummy), proc(freeDummy) },
-		{ kLoLRawDataBe32, proc(loadDummy), proc(freeDummy) },
+#endif
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+		{ kRawDataBe16, proc(loadRawDataBe16), proc(freeRawDataBe16) },
+		{ kRawDataBe32, proc(loadRawDataBe32), proc(freeRawDataBe32) },
+#endif
+#ifdef ENABLE_LOL
+		{ kLoLButtonData, proc(loadButtonDefs), proc(freeButtonDefs) },
+#else
 		{ kLoLButtonData, proc(loadDummy), proc(freeDummy) },
-#endif // ENABLE_LOL
+#endif
 
 #ifdef ENABLE_EOB
 		{ kEoB2SequenceData, proc(loadEoB2SeqData), proc(freeEoB2SeqData) },
 		{ kEoB2ShapeData, proc(loadEoB2ShapeData), proc(freeEoB2ShapeData) },
 		{ kEoBNpcData, proc(loadEoBNpcData), proc(freeEoBNpcData) },
-#endif // ENABLE_EOB
+#endif
 
 		{ 0, 0, 0 }
 	};
diff --git a/engines/kyra/staticres_rpg.cpp b/engines/kyra/staticres_rpg.cpp
index 0dfdb38..efee3be 100644
--- a/engines/kyra/staticres_rpg.cpp
+++ b/engines/kyra/staticres_rpg.cpp
@@ -28,11 +28,11 @@ namespace Kyra {
 
 #if defined(ENABLE_EOB) || defined(ENABLE_LOL)
 const uint16 *StaticResource::loadRawDataBe16(int id, int &entries) {
-	return (const uint16 *)getData(id, kLoLRawDataBe16, entries);
+	return (const uint16 *)getData(id, kRawDataBe16, entries);
 }
 
 const uint32 *StaticResource::loadRawDataBe32(int id, int &entries) {
-	return (const uint32 *)getData(id, kLoLRawDataBe32, entries);
+	return (const uint32 *)getData(id, kRawDataBe32, entries);
 }
 
 bool StaticResource::loadRawDataBe16(Common::SeekableReadStream &stream, void *&ptr, int &size) {


Commit: 60330556ff5bf319db7815e6f3c635bc98edecc5
    https://github.com/scummvm/scummvm/commit/60330556ff5bf319db7815e6f3c635bc98edecc5
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:16-08:00

Commit Message:
KYRA: (EOB/LOL) - move eob/lol specific screen code to new class

Changed paths:
  A engines/kyra/screen_rpg.cpp
  A engines/kyra/screen_rpg.h
    engines/kyra/eobcommon.h
    engines/kyra/kyra_rpg.h
    engines/kyra/lol.cpp
    engines/kyra/lol.h
    engines/kyra/module.mk
    engines/kyra/scene_rpg.cpp
    engines/kyra/screen.h
    engines/kyra/screen_eob.cpp
    engines/kyra/screen_eob.h
    engines/kyra/screen_hof.cpp
    engines/kyra/screen_lol.cpp
    engines/kyra/screen_lol.h
    engines/kyra/screen_mr.cpp
    engines/kyra/screen_v2.h
    engines/kyra/text_lol.cpp
    engines/kyra/text_lol.h
    engines/kyra/text_rpg.cpp
    engines/kyra/text_rpg.h



diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 77a8198..18fe893 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -250,6 +250,7 @@ public:
 	virtual ~EoBCoreEngine();
 
 	Screen *screen() { return _screen; }
+	Screen_Rpg *screen_rpg() { return _screen; }
 	GUI *gui() const { return _gui; }
 
 protected:
diff --git a/engines/kyra/kyra_rpg.h b/engines/kyra/kyra_rpg.h
index 31fb9bc..5d217b6 100644
--- a/engines/kyra/kyra_rpg.h
+++ b/engines/kyra/kyra_rpg.h
@@ -87,6 +87,7 @@ public:
 	virtual ~KyraRpgEngine();
 
 	virtual Screen *screen() = 0;
+	virtual Screen_Rpg *screen_rpg() = 0;
 	virtual GUI *gui() const = 0;
 
 protected:
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 01b1bdf..d90b5c9 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -361,6 +361,10 @@ Screen *LoLEngine::screen() {
 	return _screen;
 }
 
+Screen_Rpg *LoLEngine::screen_rpg() {
+	return _screen;
+}
+
 GUI *LoLEngine::gui() const {
 	return _gui;
 }
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index eeaa1b5..3a6486b 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -279,6 +279,7 @@ public:
 	virtual void initKeymap();
 
 	Screen *screen();
+	Screen_Rpg *screen_rpg();
 	GUI *gui() const;
 
 private:
diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk
index 21e3ba3..edadcdb 100644
--- a/engines/kyra/module.mk
+++ b/engines/kyra/module.mk
@@ -78,6 +78,7 @@ KYRARPG_COMMON_OBJ = \
 	kyra_rpg.o \
 	saveload_rpg.o \
 	scene_rpg.o \
+	screen_rpg.o \
 	sprites_rpg.o \
 	staticres_rpg.o \
 	text_rpg.o \
diff --git a/engines/kyra/scene_rpg.cpp b/engines/kyra/scene_rpg.cpp
index 07a7a87..88e992f 100644
--- a/engines/kyra/scene_rpg.cpp
+++ b/engines/kyra/scene_rpg.cpp
@@ -23,6 +23,7 @@
 #if defined(ENABLE_EOB) || defined(ENABLE_LOL)
 
 #include "kyra/kyra_rpg.h"
+#include "kyra/screen_rpg.h"
 #include "kyra/resource.h"
 #include "kyra/timer.h"
 #include "kyra/sound.h"
@@ -117,11 +118,11 @@ void KyraRpgEngine::scaleLevelShapesDim(int index, int16 &y1, int16 &y2, int dim
 
 	const ScreenDim *cDim = screen()->getScreenDim(dim);
 
-	screen()->modifyScreenDim(dim, cDim->sx, y1, cDim->w, y2 - y1);
+	screen_rpg()->modifyScreenDim(dim, cDim->sx, y1, cDim->w, y2 - y1);
 }
 
 void KyraRpgEngine::drawLevelModifyScreenDim(int dim, int16 x1, int16 y1, int16 x2, int16 y2) {
-	screen()->modifyScreenDim(dim, x1, y1 << 3, x2 - x1, (y2 - y1) << 3);
+	screen_rpg()->modifyScreenDim(dim, x1, y1 << 3, x2 - x1, (y2 - y1) << 3);
 }
 
 void KyraRpgEngine::generateBlockDrawingBuffer() {
diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h
index 192e267..f58a072 100644
--- a/engines/kyra/screen.h
+++ b/engines/kyra/screen.h
@@ -458,8 +458,6 @@ public:
 
 	virtual void setScreenDim(int dim) = 0;
 	virtual const ScreenDim *getScreenDim(int dim) = 0;
-	virtual int curDimIndex() const { return 0; }
-	virtual void modifyScreenDim(int dim, int x, int y, int w, int h) {}
 	virtual int screenDimTableCount() const = 0;
 
 	const ScreenDim *_curDim;
diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp
index 869f437..15a9fef 100644
--- a/engines/kyra/screen_eob.cpp
+++ b/engines/kyra/screen_eob.cpp
@@ -36,7 +36,7 @@
 
 namespace Kyra {
 
-Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system) {
+Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system), Screen_Rpg(vm, system, _screenDimTable, _screenDimTableCount) {
 	_shapeFadeMode[0] = _shapeFadeMode[1] = 0;
 	_shapeFadeInternal = 0;
 	_fadeData = 0;
@@ -44,9 +44,7 @@ Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system)
 	_dsX1 = _dsX2 = _dsY1 = _dsY2 = 0;
 	_gfxX = _gfxY = 0;
 	_gfxCol = 0;
-	_customDimTable = 0;
 	_dsTempPage = 0;
-	_curDimIndex = 0;
 	_dsDiv = 0;
 	_dsRem = 0;
 	_dsScaleTmp = 0;
@@ -55,19 +53,11 @@ Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system)
 
 Screen_EoB::~Screen_EoB() {
 	delete[] _fadeData;
-	if (_customDimTable) {
-		for (int i = 0; i < _screenDimTableCount; i++)
-			delete _customDimTable[i];
-	}
-	delete[] _customDimTable;
 	delete[] _dsTempPage;
 }
 
 bool Screen_EoB::init() {
 	if (Screen::init()) {
-		_customDimTable = new ScreenDim*[_screenDimTableCount];
-		memset(_customDimTable, 0, sizeof(ScreenDim*) * _screenDimTableCount);
-
 		int temp;
 		_gfxMaxY = _vm->staticres()->loadRawData(kEoBBaseExpObjectY, temp);
 		_fadeData = _vm->resource()->fileData("FADING.DAT", 0);
@@ -88,30 +78,6 @@ bool Screen_EoB::init() {
 	return false;
 }
 
-void Screen_EoB::setScreenDim(int dim) {
-	assert(dim < _screenDimTableCount);
-	_curDim = _customDimTable[dim] ? (const ScreenDim *)_customDimTable[dim] : &_screenDimTable[dim];
-	_curDimIndex = dim;
-}
-
-const ScreenDim *Screen_EoB::getScreenDim(int dim) {
-	assert(dim < _screenDimTableCount);
-	return _customDimTable[dim] ? (const ScreenDim *)_customDimTable[dim] : &_screenDimTable[dim];
-}
-
-void Screen_EoB::modifyScreenDim(int dim, int x, int y, int w, int h) {
-	if (!_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;
-	if (dim == _curDimIndex)
-		setScreenDim(dim);
-}
-
 void Screen_EoB::setClearScreenDim(int dim) {
 	setScreenDim(dim);
 	clearCurDim();
diff --git a/engines/kyra/screen_eob.h b/engines/kyra/screen_eob.h
index 6406587..2ede813 100644
--- a/engines/kyra/screen_eob.h
+++ b/engines/kyra/screen_eob.h
@@ -25,22 +25,18 @@
 
 #ifdef ENABLE_EOB
 
-#include "kyra/screen.h"
+#include "kyra/screen_rpg.h"
 
 namespace Kyra {
 
 class EoBCoreEngine;
-class Screen_EoB : public Screen{
+class Screen_EoB : public Screen_Rpg{
 public:
 	Screen_EoB(EoBCoreEngine *vm, OSystem *system);
 	virtual ~Screen_EoB();
 
 	bool init();
 
-	void setScreenDim(int dim);
-	const ScreenDim *getScreenDim(int dim);
-	int curDimIndex() const { return _curDimIndex; }
-	void modifyScreenDim(int dim, int x, int y, int w, int h);
 	int screenDimTableCount() const { return _screenDimTableCount; }
 
 	void setClearScreenDim(int dim);
@@ -98,9 +94,6 @@ private:
 
 	static const ScreenDim _screenDimTable[];
 	static const int _screenDimTableCount;
-
-	ScreenDim **_customDimTable;
-	int _curDimIndex;
 };
 
 }	// End of namespace Kyra
diff --git a/engines/kyra/screen_hof.cpp b/engines/kyra/screen_hof.cpp
index 24e0751..7d4d074 100644
--- a/engines/kyra/screen_hof.cpp
+++ b/engines/kyra/screen_hof.cpp
@@ -26,7 +26,7 @@
 namespace Kyra {
 
 Screen_HoF::Screen_HoF(KyraEngine_HoF *vm, OSystem *system)
-	: Screen_v2(vm, system), _vm(vm) {
+	: Screen(vm, system), Screen_v2(vm, system), _vm(vm) {
 }
 
 void Screen_HoF::setScreenDim(int dim) {
diff --git a/engines/kyra/screen_lol.cpp b/engines/kyra/screen_lol.cpp
index 0f02165..bef83f4 100644
--- a/engines/kyra/screen_lol.cpp
+++ b/engines/kyra/screen_lol.cpp
@@ -31,7 +31,7 @@
 
 namespace Kyra {
 
-Screen_LoL::Screen_LoL(LoLEngine *vm, OSystem *system) : Screen_v2(vm, system), _vm(vm) {
+Screen_LoL::Screen_LoL(LoLEngine *vm, OSystem *system) : Screen(vm, system), Screen_v2(vm, system), Screen_Rpg(vm, system, _screenDimTable = vm->gameFlags().use16ColorMode ? _screenDimTable16C : _screenDimTable256C, _screenDimTableCount), _vm(vm) {
 	_paletteOverlay1 = new uint8[0x100];
 	_paletteOverlay2 = new uint8[0x100];
 	_grayOverlay = new uint8[0x100];
@@ -43,16 +43,10 @@ Screen_LoL::Screen_LoL(LoLEngine *vm, OSystem *system) : Screen_v2(vm, system),
 		_levelOverlays[i] = new uint8[256];
 
 	_screenDimTable = 0;
-	_customDimTable = 0;
-	_curDimIndex = 0;
 	_fadeFlag = 2;
 }
 
 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];
 
@@ -61,39 +55,6 @@ Screen_LoL::~Screen_LoL() {
 	delete[] _grayOverlay;
 }
 
-bool Screen_LoL::init() {
-	if (Screen::init()) {
-		_screenDimTable = _use16ColorMode ? _screenDimTable16C : _screenDimTable256C;
-		_customDimTable = new ScreenDim*[_screenDimTableCount];
-		memset(_customDimTable, 0, sizeof(ScreenDim *)* _screenDimTableCount);
-		return true;
-	}
-	return false;
-}
-
-
-void Screen_LoL::setScreenDim(int dim) {
-	assert(dim < _screenDimTableCount);
-	_curDim = _customDimTable[dim] ? (const ScreenDim *)_customDimTable[dim] : &_screenDimTable[dim];
-	_curDimIndex = dim;
-}
-
-const ScreenDim *Screen_LoL::getScreenDim(int dim) {
-	assert(dim < _screenDimTableCount);
-	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::fprintString(const char *format, int x, int y, uint8 col1, uint8 col2, uint16 flags, ...) {
 	if (!format)
 		return;
diff --git a/engines/kyra/screen_lol.h b/engines/kyra/screen_lol.h
index 02b7860..eb025fb 100644
--- a/engines/kyra/screen_lol.h
+++ b/engines/kyra/screen_lol.h
@@ -26,22 +26,17 @@
 #define KYRA_SCREEN_LOL_H
 
 #include "kyra/screen_v2.h"
+#include "kyra/screen_rpg.h"
 
 namespace Kyra {
 
 class LoLEngine;
 
-class Screen_LoL : public Screen_v2 {
+class Screen_LoL : public Screen_v2, public Screen_Rpg {
 public:
 	Screen_LoL(LoLEngine *vm, OSystem *system);
 	~Screen_LoL();
 
-	bool init();
-
-	void setScreenDim(int dim);
-	const ScreenDim *getScreenDim(int dim);
-	int curDimIndex() const { return _curDimIndex; }
-	void modifyScreenDim(int dim, int x, int y, int w, int h);
 	int screenDimTableCount() const { return _screenDimTableCount; }
 
 	void fprintString(const char *format, int x, int y, uint8 col1, uint8 col2, uint16 flags, ...) GCC_PRINTF(2, 8);
@@ -105,9 +100,6 @@ private:
 	static const ScreenDim _screenDimTable256C[];
 	static const ScreenDim _screenDimTable16C[];
 
-	ScreenDim **_customDimTable;
-	int _curDimIndex;
-
 	uint8 *_levelOverlays[8];
 
 	void mergeOverlay(int x, int y, int w, int h);
diff --git a/engines/kyra/screen_mr.cpp b/engines/kyra/screen_mr.cpp
index 2687dc8..d4446c6 100644
--- a/engines/kyra/screen_mr.cpp
+++ b/engines/kyra/screen_mr.cpp
@@ -25,7 +25,7 @@
 
 namespace Kyra {
 
-Screen_MR::Screen_MR(KyraEngine_MR *vm, OSystem *system) : Screen_v2(vm, system) {
+Screen_MR::Screen_MR(KyraEngine_MR *vm, OSystem *system) : Screen(vm, system), Screen_v2(vm, system) {
 }
 
 Screen_MR::~Screen_MR() {
diff --git a/engines/kyra/screen_rpg.cpp b/engines/kyra/screen_rpg.cpp
new file mode 100644
index 0000000..3b29f0a
--- /dev/null
+++ b/engines/kyra/screen_rpg.cpp
@@ -0,0 +1,126 @@
+/* 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.

+ *

+ */

+

+

+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)

+

+#include "kyra/screen_rpg.h"

+#include "kyra/kyra_v1.h"

+

+#include "common/endian.h"

+

+namespace Kyra {

+

+Screen_Rpg::Screen_Rpg(KyraEngine_v1 *vm, OSystem *system, const ScreenDim *dimTable, int dimTableSize) : Screen(vm, system), _screenDimTable(dimTable), _screenDimTableCount(dimTableSize) {

+	_customDimTable = new ScreenDim*[_screenDimTableCount];

+	memset(_customDimTable, 0, sizeof(ScreenDim *)* _screenDimTableCount);

+	_curDimIndex = 0;

+}

+

+Screen_Rpg::~Screen_Rpg() {

+	for (int i = 0; i < _screenDimTableCount; i++)

+		delete _customDimTable[i];

+	delete[] _customDimTable;

+}

+

+void Screen_Rpg::setScreenDim(int dim) {

+	assert(dim < _screenDimTableCount);

+	_curDim = _customDimTable[dim] ? (const ScreenDim *)_customDimTable[dim] : &_screenDimTable[dim];

+	_curDimIndex = dim;

+}

+

+const ScreenDim *Screen_Rpg::getScreenDim(int dim) {

+	assert(dim < _screenDimTableCount);

+	return _customDimTable[dim] ? (const ScreenDim *)_customDimTable[dim] : &_screenDimTable[dim];

+}

+

+void Screen_Rpg::modifyScreenDim(int dim, int x, int y, int w, int h) {

+	if (!_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;

+	if (dim == _curDimIndex || _vm->game() == GI_LOL)

+		setScreenDim(dim);

+}

+

+void Screen_Rpg::crossFadeRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage) {

+	if (srcPage > 13 || dstPage > 13)

+		error("Screen_Rpg::crossFadeRegion(): attempting to use temp page as source or dest page.");

+

+	hideMouse();

+

+	uint16 *wB = (uint16*)_pagePtrs[14];

+	uint8 *hB = _pagePtrs[14] + 640;

+

+	for (int i = 0; i < w; i++)

+		wB[i] = i;

+

+	for (int i = 0; i < h; i++)

+		hB[i] = i;

+

+	for (int i = 0; i < w; i++)

+		SWAP(wB[_vm->_rnd.getRandomNumberRng(0, w - 1)], wB[i]);

+

+	for (int i = 0; i < h; i++)

+		SWAP(hB[_vm->_rnd.getRandomNumberRng(0, h - 1)], hB[i]);

+

+	uint8 *s = _pagePtrs[srcPage];

+	uint8 *d = _pagePtrs[dstPage];

+

+	for (int i = 0; i < h; i++) {

+		int iH = i;

+		uint32 end = _system->getMillis() + 3;

+		for (int ii = 0; ii < w; ii++) {

+			int sX = x1 + wB[ii];

+			int sY = y1 + hB[iH];

+			int dX = x2 + wB[ii];

+			int dY = y2 + hB[iH];

+

+			if (++iH >= h)

+				iH = 0;

+

+			d[dY * 320 + dX] = s[sY * 320 + sX];

+			addDirtyRect(dX, dY, 1, 1);

+		}

+

+		// This tries to speed things up, to get similiar speeds as in DOSBox etc.

+		// We can't write single pixels directly into the video memory like the original did.

+		// We also (unlike the original) want to aim at similiar speeds for all platforms.

+		if (!(i % 10))

+			updateScreen();

+

+		uint32 cur = _system->getMillis();

+		if (end > cur)

+			_system->delayMillis(end - cur);

+	}

+

+	updateScreen();

+	showMouse();

+}

+

+}	// End of namespace Kyra

+

+#endif // ENABLE_EOB || ENABLE_LOL

diff --git a/engines/kyra/screen_rpg.h b/engines/kyra/screen_rpg.h
new file mode 100644
index 0000000..e9b15c2
--- /dev/null
+++ b/engines/kyra/screen_rpg.h
@@ -0,0 +1,61 @@
+/* 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.

+ *

+ */

+

+#ifndef KYRA_SCREEN_RPG_H

+#define KYRA_SCREEN_RPG_H

+

+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)

+

+#include "kyra/screen.h"

+#include "common/system.h"

+

+namespace Kyra {

+

+class Screen;

+class KyraEngine_v1;

+

+class Screen_Rpg : virtual public Screen {

+public:

+	Screen_Rpg(KyraEngine_v1 *vm, OSystem *system, const ScreenDim *dimTable, int dimTableSize);

+	virtual ~Screen_Rpg();

+

+	virtual void setScreenDim(int dim);

+	virtual const ScreenDim *getScreenDim(int dim);

+	virtual int screenDimTableCount() const = 0;

+

+	void modifyScreenDim(int dim, int x, int y, int w, int h);

+	int curDimIndex() const { return _curDimIndex; }

+

+	void crossFadeRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage);

+

+private:

+	int _curDimIndex;

+	int _screenDimTableCount;

+	ScreenDim **_customDimTable;

+	const ScreenDim *_screenDimTable;

+};

+

+}	// End of namespace Kyra

+

+#endif // ENABLE_EOB || ENABLE_LOL

+

+#endif

diff --git a/engines/kyra/screen_v2.h b/engines/kyra/screen_v2.h
index d85c762..f50c81e 100644
--- a/engines/kyra/screen_v2.h
+++ b/engines/kyra/screen_v2.h
@@ -28,7 +28,7 @@
 
 namespace Kyra {
 
-class Screen_v2 : public Screen {
+class Screen_v2 : virtual public Screen {
 public:
 	Screen_v2(KyraEngine_v1 *vm, OSystem *system);
 	~Screen_v2();
diff --git a/engines/kyra/text_lol.cpp b/engines/kyra/text_lol.cpp
index d07956b..8535516 100644
--- a/engines/kyra/text_lol.cpp
+++ b/engines/kyra/text_lol.cpp
@@ -32,7 +32,7 @@
 
 namespace Kyra {
 
-TextDisplayer_LoL::TextDisplayer_LoL(LoLEngine *engine, Screen_LoL *screenLoL) : TextDisplayer_rpg(engine, engine->screen()),
+TextDisplayer_LoL::TextDisplayer_LoL(LoLEngine *engine, Screen_LoL *screenLoL) : TextDisplayer_rpg(engine, engine->screen_rpg()),
 	_vm(engine), _screen(screenLoL), _scriptTextParameter(0) {
 
 	memset(_stringParameters, 0, 15 * sizeof(char *));
@@ -337,7 +337,7 @@ KyraRpgEngine *TextDisplayer_LoL::vm() {
 	return _vm;
 }
 
-Screen *TextDisplayer_LoL::screen() {
+Screen_Rpg *TextDisplayer_LoL::screen() {
 	return _screen;
 }
 
diff --git a/engines/kyra/text_lol.h b/engines/kyra/text_lol.h
index 6da217e..baf0f2f 100644
--- a/engines/kyra/text_lol.h
+++ b/engines/kyra/text_lol.h
@@ -51,7 +51,7 @@ public:
 
 private:
 	KyraRpgEngine *vm();
-	Screen *screen();
+	Screen_Rpg *screen();
 
 	void preprocessString(char *str, EMCState *script, const uint16 *paramList, int16 paramIndex);
 	void textPageBreak();
diff --git a/engines/kyra/text_rpg.cpp b/engines/kyra/text_rpg.cpp
index 1201cdc..ca1fd04 100644
--- a/engines/kyra/text_rpg.cpp
+++ b/engines/kyra/text_rpg.cpp
@@ -24,7 +24,7 @@
 #if defined(ENABLE_EOB) || defined(ENABLE_LOL)
 
 #include "kyra/kyra_rpg.h"
-#include "kyra/screen.h"
+#include "kyra/screen_rpg.h"
 #include "kyra/timer.h"
 
 #include "common/system.h"
@@ -35,7 +35,7 @@ enum {
 	kEoBTextBufferSize = 2048
 };
 
-TextDisplayer_rpg::TextDisplayer_rpg(KyraRpgEngine *engine, Screen *sScreen) : _vm(engine), _screen(sScreen),
+TextDisplayer_rpg::TextDisplayer_rpg(KyraRpgEngine *engine, Screen_Rpg *scr) : _vm(engine), _screen(scr),
 	_lineCount(0), _printFlag(false), _lineWidth(0), _numCharsTotal(0), _allowPageBreak(true),
 	_numCharsLeft(0), _numCharsPrinted(0), _sjisLineBreakFlag(false), _waitButtonMode(1) {
 
@@ -462,7 +462,7 @@ void TextDisplayer_rpg::printLine(char *str) {
 }
 
 void TextDisplayer_rpg::printDialogueText(int stringId, const char *pageBreakString) {
-	const char * str = (const char *)(screen()->getCPagePtr(5) + READ_LE_UINT16(&screen()->getCPagePtr(5)[(stringId - 1) << 1]));
+	const char * str = (const char *)(_screen->getCPagePtr(5) + READ_LE_UINT16(&_screen->getCPagePtr(5)[(stringId - 1) << 1]));
 	assert (strlen(str) < kEoBTextBufferSize);
 	Common::strlcpy(_dialogueBuffer, str, kEoBTextBufferSize);
 
@@ -488,10 +488,10 @@ void TextDisplayer_rpg::printDialogueText(const char *str, bool wait) {
 }
 
 void TextDisplayer_rpg::printMessage(const char *str, int textColor, ...) {
-	int tc = _textDimData[screen()->curDimIndex()].color1;
+	int tc = _textDimData[_screen->curDimIndex()].color1;
 
 	if (textColor != -1)
-		_textDimData[screen()->curDimIndex()].color1 = textColor;
+		_textDimData[_screen->curDimIndex()].color1 = textColor;
 
 	va_list args;
 	va_start(args, textColor);
@@ -501,28 +501,28 @@ void TextDisplayer_rpg::printMessage(const char *str, int textColor, ...) {
 	displayText(_dialogueBuffer);
 
 	if (vm()->game() != GI_EOB1)
-		_textDimData[screen()->curDimIndex()].color1 = tc;
+		_textDimData[_screen->curDimIndex()].color1 = tc;
 
-	if (!screen()->_curPage)
-		screen()->updateScreen();
+	if (!_screen->_curPage)
+		_screen->updateScreen();
 }
 
 int TextDisplayer_rpg::clearDim(int dim) {
-	int res = screen()->curDimIndex();
-	screen()->setScreenDim(dim);
-	_textDimData[dim].color1 = screen()->_curDim->unk8;
-	_textDimData[dim].color2 = vm()->game() == GI_LOL ? screen()->_curDim->unkA : vm()->_bkgColor_1;
+	int res = _screen->curDimIndex();
+	_screen->setScreenDim(dim);
+	_textDimData[dim].color1 = _screen->_curDim->unk8;
+	_textDimData[dim].color2 = vm()->game() == GI_LOL ? _screen->_curDim->unkA : vm()->_bkgColor_1;
 	clearCurDim();
 	return res;
 }
 
 void TextDisplayer_rpg::clearCurDim() {
-	int d = screen()->curDimIndex();
-	const ScreenDim *tmp = screen()->getScreenDim(d);
+	int d = _screen->curDimIndex();
+	const ScreenDim *tmp = _screen->getScreenDim(d);
 	if (vm()->gameFlags().use16ColorMode) {
-		screen()->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 2, (tmp->sy + tmp->h) - 2, _textDimData[d].color2);
+		_screen->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 2, (tmp->sy + tmp->h) - 2, _textDimData[d].color2);
 	} else
-		screen()->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 1, (tmp->sy + tmp->h) - 1, _textDimData[d].color2);
+		_screen->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 1, (tmp->sy + tmp->h) - 1, _textDimData[d].color2);
 
 	_lineCount = 0;
 	_textDimData[d].column = _textDimData[d].line = 0;
@@ -533,7 +533,7 @@ void TextDisplayer_rpg::textPageBreak() {
 		SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2);
 
 	int cp = _screen->setCurPage(0);
-	Screen::FontId cf = screen()->setFont(vm()->gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : Screen::FID_6_FNT);
+	Screen::FontId cf = _screen->setFont(vm()->gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : Screen::FID_6_FNT);
 
 	if (vm()->game() == GI_LOL)
 		vm()->_timer->pauseSingleTimer(11, true);
@@ -554,7 +554,7 @@ void TextDisplayer_rpg::textPageBreak() {
 	if (vm()->speechEnabled() && vm()->_activeVoiceFileTotalTime && _numCharsTotal)
 		speechPartTime = vm()->_system->getMillis() + ((_numCharsPrinted * vm()->_activeVoiceFileTotalTime) / _numCharsTotal);
 
-	const ScreenDim *dim = screen()->getScreenDim(screen()->curDimIndex());
+	const ScreenDim *dim = _screen->getScreenDim(_screen->curDimIndex());
 
 	int x = ((dim->sx + dim->w) << 3) - (_vm->_dialogueButtonW + 3);
 	int y = 0;
@@ -579,10 +579,10 @@ void TextDisplayer_rpg::textPageBreak() {
 
 	if (vm()->gameFlags().use16ColorMode) {
 		vm()->gui_drawBox(x + 8, (y & ~7) - 1, 66, 10, 0xee, 0xcc, -1);
-		screen()->printText(_pageBreakString, (x + 37 - (strlen(_pageBreakString) << 1) + 4) & ~3, (y + 2) & ~7, 0xc1, 0);
+		_screen->printText(_pageBreakString, (x + 37 - (strlen(_pageBreakString) << 1) + 4) & ~3, (y + 2) & ~7, 0xc1, 0);
 	} else {
 		vm()->gui_drawBox(x, y, w, vm()->_dialogueButtonH, vm()->_color1_1, vm()->_color2_1, vm()->_bkgColor_1);
-		screen()->printText(_pageBreakString, x + (w >> 1) - (vm()->screen()->getTextWidth(_pageBreakString) >> 1), y + 2, vm()->_dialogueButtonLabelCol1, 0);
+		_screen->printText(_pageBreakString, x + (w >> 1) - (vm()->screen()->getTextWidth(_pageBreakString) >> 1), y + 2, vm()->_dialogueButtonLabelCol1, 0);
 	}
 
 	vm()->removeInputTop();
@@ -627,9 +627,9 @@ void TextDisplayer_rpg::textPageBreak() {
 	} while (loop && !_vm->shouldQuit());
 
 	if (vm()->gameFlags().use16ColorMode)
-		screen()->fillRect(x + 8, y, x + 57, y + 9, _textDimData[screen()->curDimIndex()].color2);
+		_screen->fillRect(x + 8, y, x + 57, y + 9, _textDimData[_screen->curDimIndex()].color2);
 	else
-		screen()->fillRect(x, y, x + w - 1, y + 8, _textDimData[screen()->curDimIndex()].color2);
+		_screen->fillRect(x, y, x + w - 1, y + 8, _textDimData[_screen->curDimIndex()].color2);
 
 	clearCurDim();
 	_screen->updateScreen();
@@ -647,8 +647,8 @@ void TextDisplayer_rpg::textPageBreak() {
 		vm()->_updatePortraitSpeechAnimDuration = updatePortraitSpeechAnimDuration;
 	}
 
-	screen()->setFont(cf);
-	screen()->setCurPage(cp);
+	_screen->setFont(cf);
+	_screen->setCurPage(cp);
 
 	if (vm()->game() != GI_LOL)
 		SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2);
diff --git a/engines/kyra/text_rpg.h b/engines/kyra/text_rpg.h
index fcafcc0..ff3473d 100644
--- a/engines/kyra/text_rpg.h
+++ b/engines/kyra/text_rpg.h
@@ -29,12 +29,12 @@
 
 namespace Kyra {
 
-class Screen;
+class Screen_Rpg;
 class KyraRpgEngine;
 
 class TextDisplayer_rpg {
 public:
-	TextDisplayer_rpg(KyraRpgEngine *engine, Screen *sScreen);
+	TextDisplayer_rpg(KyraRpgEngine *engine, Screen_Rpg *scr);
 	virtual ~TextDisplayer_rpg();
 
 	virtual void setupField(int dim, bool mode);
@@ -57,7 +57,7 @@ public:
 
 protected:
 	virtual KyraRpgEngine *vm() { return _vm; }
-	virtual Screen *screen() { return _screen; }
+	virtual Screen_Rpg *screen() { return _screen; }
 
 	void displayText(char *str, ...);
 	char parseCommand();
@@ -102,7 +102,7 @@ protected:
 
 private:
 	KyraRpgEngine *_vm;
-	Screen *_screen;
+	Screen_Rpg *_screen;
 
 	char *_table1;
 	char *_table2;


Commit: 0c7fbd788b2dbcded5114ec8c15efcab5072d9e9
    https://github.com/scummvm/scummvm/commit/0c7fbd788b2dbcded5114ec8c15efcab5072d9e9
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:17-08:00

Commit Message:
KYRA: (EOB) - remove unneeded virtual declarations in screen.h

Changed paths:
    engines/kyra/scene_lol.cpp
    engines/kyra/screen.h



diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp
index d8fb70a..8610d20 100644
--- a/engines/kyra/scene_lol.cpp
+++ b/engines/kyra/scene_lol.cpp
@@ -262,7 +262,7 @@ void LoLEngine::loadBlockProperties(const char *cmzFile) {
 
 const uint8 *LoLEngine::getBlockFileData(int levelIndex) {
 	_screen->loadBitmap(Common::String::format("LEVEL%d.CMZ", levelIndex).c_str(), 15, 15, 0);
-	return screen()->getCPagePtr(14);
+	return _screen->getCPagePtr(14);
 }
 
 void LoLEngine::loadLevelShpDat(const char *shpFile, const char *datFile, bool flag) {
@@ -1490,7 +1490,7 @@ void LoLEngine::drawDecorations(int index) {
 					else
 						ov = 0;
 				}
-				ovl = screen()->getLevelOverlay(ov);
+				ovl = _screen->getLevelOverlay(ov);
 			} else if (_levelDecorationProperties[l].shapeIndex[shpIx] != 0xffff) {
 				scaleW = scaleH = 0x100;
 				int ov = 7;
@@ -1501,7 +1501,7 @@ void LoLEngine::drawDecorations(int index) {
 					else
 						ov = 0;
 				}
-				ovl = screen()->getLevelOverlay(ov);
+				ovl = _screen->getLevelOverlay(ov);
 			}
 
 			if (_levelDecorationProperties[l].shapeIndex[shpIx] != 0xffff) {
@@ -1511,7 +1511,7 @@ void LoLEngine::drawDecorations(int index) {
 						x = _dscShapeX[s] + xOffs + ((_levelDecorationProperties[l].shapeX[shpIx] * scaleW) >> 8);
 						if (ix == _dscShapeIndex[s]) {
 							x = _dscShapeX[s] - ((_levelDecorationProperties[l].shapeX[shpIx] * scaleW) >> 8) -
-								screen()->getShapeScaledWidth(shapeData, scaleW) - xOffs;
+								_screen->getShapeScaledWidth(shapeData, scaleW) - xOffs;
 						}
 						flags = 0x105;
 					} else {
@@ -1520,13 +1520,13 @@ void LoLEngine::drawDecorations(int index) {
 					}
 
 					y = _dscShapeY[s] + yOffs + ((_levelDecorationProperties[l].shapeY[shpIx] * scaleH) >> 8);
-					screen()->drawShape(_sceneDrawPage1, shapeData, x + 112, y, _sceneShpDim, flags, ovl, 1, scaleW, scaleH);
+					_screen->drawShape(_sceneDrawPage1, shapeData, x + 112, y, _sceneShpDim, flags, ovl, 1, scaleW, scaleH);
 
 					if ((_levelDecorationProperties[l].flags & 1) && shpIx < 4) {
 						//draw shadow
-						x += (screen()->getShapeScaledWidth(shapeData, scaleW));
+						x += (_screen->getShapeScaledWidth(shapeData, scaleW));
 						flags ^= 1;
-						screen()->drawShape(_sceneDrawPage1, shapeData, x + 112, y, _sceneShpDim, flags, ovl, 1, scaleW, scaleH);
+						_screen->drawShape(_sceneDrawPage1, shapeData, x + 112, y, _sceneShpDim, flags, ovl, 1, scaleW, scaleH);
 					}
 				}
 			}
diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h
index f58a072..2db8415 100644
--- a/engines/kyra/screen.h
+++ b/engines/kyra/screen.h
@@ -468,8 +468,6 @@ public:
 	int setNewShapeHeight(uint8 *shape, int height);
 	int resetShapeHeight(uint8 *shape);
 
-	virtual int getShapeScaledWidth( const uint8*, int) { return 0; }
-
 	virtual void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...);
 
 	// mouse handling
@@ -503,8 +501,6 @@ public:
 	void blockInRegion(int x, int y, int width, int height);
 	void blockOutRegion(int x, int y, int width, int height);
 
-	virtual uint8 *getLevelOverlay(int) { return 0; }
-
 	int _charWidth;
 	int _charOffset;
 	int _curPage;


Commit: 692f9ee6d524752bf1b1d169f81f68309901187a
    https://github.com/scummvm/scummvm/commit/692f9ee6d524752bf1b1d169f81f68309901187a
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:17-08:00

Commit Message:
KYRA: whitespace cleanup

Changed paths:
    engines/kyra/detection.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui.cpp
    engines/kyra/gui_eob.cpp
    engines/kyra/gui_rpg.cpp
    engines/kyra/gui_v1.cpp
    engines/kyra/gui_v1.h
    engines/kyra/items_eob.cpp
    engines/kyra/items_lok.cpp
    engines/kyra/kyra_rpg.h
    engines/kyra/kyra_v1.cpp
    engines/kyra/resource.h
    engines/kyra/screen.cpp
    engines/kyra/screen_eob.cpp
    engines/kyra/screen_eob.h
    engines/kyra/staticres_eob.cpp
    engines/kyra/staticres_rpg.cpp
    engines/kyra/text_lol.h
    engines/kyra/wsamovie.cpp



diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp
index 56ad427..ceb3ef6 100644
--- a/engines/kyra/detection.cpp
+++ b/engines/kyra/detection.cpp
@@ -84,7 +84,7 @@ bool KyraMetaEngine::hasFeature(MetaEngineFeature f) const {
 		(f == kSupportsListSaves) ||
 		(f == kSupportsLoadingDuringStartup) ||
 		(f == kSupportsDeleteSave) ||
-	  	(f == kSavesSupportMetaInfo) ||
+		(f == kSavesSupportMetaInfo) ||
 		(f == kSavesSupportThumbnail);
 }
 
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 18fe893..af16df7 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -1147,4 +1147,4 @@ protected:
 
 #endif // ENABLE_EOB
 
-#endif
\ No newline at end of file
+#endif
diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp
index 9c0adf1..e2195ca 100644
--- a/engines/kyra/gui.cpp
+++ b/engines/kyra/gui.cpp
@@ -139,5 +139,3 @@ void GUI::updateSaveSlotsList() {
 }
 
 } // End of namespace Kyra
-
-
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 76b4b35..1930ab1 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -3632,7 +3632,7 @@ void GUI_EoB::displayTextBox(int id) {
 	_screen->updateScreen();
 
 	for (uint32 timeOut = _vm->_system->getMillis() + 1440; _vm->_system->getMillis() < timeOut && !_vm->shouldQuit(); ) {
-	 	int in = _vm->checkInput(0, false, 0);
+		int in = _vm->checkInput(0, false, 0);
 		_vm->removeInputTop();
 		if (in && !(in & 0x800))
 			break;
@@ -3963,4 +3963,3 @@ const EoBRect16 GUI_EoB::_updateBoxFrameHighLights[] = {
 }	// End of namespace Kyra
 
 #endif // ENABLE_EOB
-
diff --git a/engines/kyra/gui_rpg.cpp b/engines/kyra/gui_rpg.cpp
index 8b2a593..718722f 100644
--- a/engines/kyra/gui_rpg.cpp
+++ b/engines/kyra/gui_rpg.cpp
@@ -131,4 +131,3 @@ bool KyraRpgEngine::clickedShape(int shapeIndex) {
 }	// End of namespace Kyra
 
 #endif // defined(ENABLE_EOB) || defined(ENABLE_LOL)
-
diff --git a/engines/kyra/gui_v1.cpp b/engines/kyra/gui_v1.cpp
index c38c828..ab44187 100644
--- a/engines/kyra/gui_v1.cpp
+++ b/engines/kyra/gui_v1.cpp
@@ -627,4 +627,3 @@ void MainMenu::printString(const char *format, int x, int y, int col1, int col2,
 }
 
 } // End of namespace Kyra
-
diff --git a/engines/kyra/gui_v1.h b/engines/kyra/gui_v1.h
index ec0d577..260edae 100644
--- a/engines/kyra/gui_v1.h
+++ b/engines/kyra/gui_v1.h
@@ -195,4 +195,3 @@ private:
 } // end of namesapce Kyra
 
 #endif
-
diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
index 8ade6e1..28764df 100644
--- a/engines/kyra/items_eob.cpp
+++ b/engines/kyra/items_eob.cpp
@@ -729,4 +729,3 @@ void EoBCoreEngine::reloadWeaponSlot(int charIndex, int slotIndex, int itemType,
 } // End of namespace Kyra
 
 #endif // ENABLE_EOB
-
diff --git a/engines/kyra/items_lok.cpp b/engines/kyra/items_lok.cpp
index d598a17..7e41811 100644
--- a/engines/kyra/items_lok.cpp
+++ b/engines/kyra/items_lok.cpp
@@ -575,7 +575,7 @@ void KyraEngine_LoK::dropItem(int unk1, int item, int x, int y, int unk2) {
 	if (processItemDrop(_currentCharacter->sceneId, item, x, y, unk1, unk2))
 		return;
 	snd_playSoundEffect(54);
-	
+
 	// Old floppy versions don't print warning messages and don't have the necessary string resources.
 	// These versions will only play the warning sound effect.
 	if (_flags.isOldFloppy && !_noDropList)
diff --git a/engines/kyra/kyra_rpg.h b/engines/kyra/kyra_rpg.h
index 5d217b6..13a67c6 100644
--- a/engines/kyra/kyra_rpg.h
+++ b/engines/kyra/kyra_rpg.h
@@ -353,4 +353,4 @@ protected:
 
 #endif // ENABLE_EOB || ENABLE_LOL
 
-#endif
\ No newline at end of file
+#endif
diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp
index c1b9f2a..b818243 100644
--- a/engines/kyra/kyra_v1.cpp
+++ b/engines/kyra/kyra_v1.cpp
@@ -406,7 +406,7 @@ void KyraEngine_v1::setupKeyMap() {
 		{ KC(s), 32, 32 },
 		{ KC(w), 18, 18 },
 		{ KC(y), 22, 22 },
-		{ KC(z), 46, 46 },		
+		{ KC(z), 46, 46 },
 		{ KC(1), 2, 0/*unknown*/ },
 		{ KC(2), 3, 0/*unknown*/ },
 		{ KC(3), 4, 0/*unknown*/ },
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 30cf17d..45c1851 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -291,7 +291,7 @@ enum KyraResources {
 	kEoBBaseItemSuffixStringsRings,
 	kEoBBaseItemSuffixStringsPotions,
 	kEoBBaseItemSuffixStringsWands,
-	
+
 	kEoBBaseRipItemStrings,
 	kEoBBaseCursedString,
 	kEoBBaseEnchantedString,
@@ -543,83 +543,83 @@ enum KyraResources {
 	kEoB2IntroStrings,
 	kEoB2IntroCPSFiles,
 	kEoB2IntroSeqData00,
- 	kEoB2IntroSeqData01,
- 	kEoB2IntroSeqData02,
- 	kEoB2IntroSeqData03,
- 	kEoB2IntroSeqData04,
- 	kEoB2IntroSeqData05,
- 	kEoB2IntroSeqData06,
- 	kEoB2IntroSeqData07,
- 	kEoB2IntroSeqData08,
- 	kEoB2IntroSeqData09,
- 	kEoB2IntroSeqData10,
- 	kEoB2IntroSeqData11,
- 	kEoB2IntroSeqData12,
- 	kEoB2IntroSeqData13,
- 	kEoB2IntroSeqData14,
- 	kEoB2IntroSeqData15,
- 	kEoB2IntroSeqData16,
- 	kEoB2IntroSeqData17,
- 	kEoB2IntroSeqData18,
- 	kEoB2IntroSeqData19,
- 	kEoB2IntroSeqData20,
- 	kEoB2IntroSeqData21,
- 	kEoB2IntroSeqData22,
- 	kEoB2IntroSeqData23,
- 	kEoB2IntroSeqData24,
- 	kEoB2IntroSeqData25,
- 	kEoB2IntroSeqData26,
- 	kEoB2IntroSeqData27,
- 	kEoB2IntroSeqData28,
- 	kEoB2IntroSeqData29,
- 	kEoB2IntroSeqData30,
- 	kEoB2IntroSeqData31,
- 	kEoB2IntroSeqData32,
- 	kEoB2IntroSeqData33,
- 	kEoB2IntroSeqData34,
- 	kEoB2IntroSeqData35,
- 	kEoB2IntroSeqData36,
- 	kEoB2IntroSeqData37,
- 	kEoB2IntroSeqData38,
- 	kEoB2IntroSeqData39,
- 	kEoB2IntroSeqData40,
- 	kEoB2IntroSeqData41,
- 	kEoB2IntroSeqData42,
- 	kEoB2IntroSeqData43,
+	kEoB2IntroSeqData01,
+	kEoB2IntroSeqData02,
+	kEoB2IntroSeqData03,
+	kEoB2IntroSeqData04,
+	kEoB2IntroSeqData05,
+	kEoB2IntroSeqData06,
+	kEoB2IntroSeqData07,
+	kEoB2IntroSeqData08,
+	kEoB2IntroSeqData09,
+	kEoB2IntroSeqData10,
+	kEoB2IntroSeqData11,
+	kEoB2IntroSeqData12,
+	kEoB2IntroSeqData13,
+	kEoB2IntroSeqData14,
+	kEoB2IntroSeqData15,
+	kEoB2IntroSeqData16,
+	kEoB2IntroSeqData17,
+	kEoB2IntroSeqData18,
+	kEoB2IntroSeqData19,
+	kEoB2IntroSeqData20,
+	kEoB2IntroSeqData21,
+	kEoB2IntroSeqData22,
+	kEoB2IntroSeqData23,
+	kEoB2IntroSeqData24,
+	kEoB2IntroSeqData25,
+	kEoB2IntroSeqData26,
+	kEoB2IntroSeqData27,
+	kEoB2IntroSeqData28,
+	kEoB2IntroSeqData29,
+	kEoB2IntroSeqData30,
+	kEoB2IntroSeqData31,
+	kEoB2IntroSeqData32,
+	kEoB2IntroSeqData33,
+	kEoB2IntroSeqData34,
+	kEoB2IntroSeqData35,
+	kEoB2IntroSeqData36,
+	kEoB2IntroSeqData37,
+	kEoB2IntroSeqData38,
+	kEoB2IntroSeqData39,
+	kEoB2IntroSeqData40,
+	kEoB2IntroSeqData41,
+	kEoB2IntroSeqData42,
+	kEoB2IntroSeqData43,
 	kEoB2IntroShapes00,
- 	kEoB2IntroShapes01,
- 	kEoB2IntroShapes04,
- 	kEoB2IntroShapes07,
+	kEoB2IntroShapes01,
+	kEoB2IntroShapes04,
+	kEoB2IntroShapes07,
 
 	kEoB2FinaleStrings,
 	kEoB2CreditsData,
 	kEoB2FinaleCPSFiles,
 	kEoB2FinaleSeqData00,
- 	kEoB2FinaleSeqData01,
- 	kEoB2FinaleSeqData02,
- 	kEoB2FinaleSeqData03,
- 	kEoB2FinaleSeqData04,
- 	kEoB2FinaleSeqData05,
- 	kEoB2FinaleSeqData06,
- 	kEoB2FinaleSeqData07,
- 	kEoB2FinaleSeqData08,
- 	kEoB2FinaleSeqData09,
- 	kEoB2FinaleSeqData10,
- 	kEoB2FinaleSeqData11,
- 	kEoB2FinaleSeqData12,
- 	kEoB2FinaleSeqData13,
- 	kEoB2FinaleSeqData14,
- 	kEoB2FinaleSeqData15,
- 	kEoB2FinaleSeqData16,
- 	kEoB2FinaleSeqData17,
- 	kEoB2FinaleSeqData18,
- 	kEoB2FinaleSeqData19,
- 	kEoB2FinaleSeqData20,
+	kEoB2FinaleSeqData01,
+	kEoB2FinaleSeqData02,
+	kEoB2FinaleSeqData03,
+	kEoB2FinaleSeqData04,
+	kEoB2FinaleSeqData05,
+	kEoB2FinaleSeqData06,
+	kEoB2FinaleSeqData07,
+	kEoB2FinaleSeqData08,
+	kEoB2FinaleSeqData09,
+	kEoB2FinaleSeqData10,
+	kEoB2FinaleSeqData11,
+	kEoB2FinaleSeqData12,
+	kEoB2FinaleSeqData13,
+	kEoB2FinaleSeqData14,
+	kEoB2FinaleSeqData15,
+	kEoB2FinaleSeqData16,
+	kEoB2FinaleSeqData17,
+	kEoB2FinaleSeqData18,
+	kEoB2FinaleSeqData19,
+	kEoB2FinaleSeqData20,
 	kEoB2FinaleShapes00,
- 	kEoB2FinaleShapes03,
- 	kEoB2FinaleShapes07,
- 	kEoB2FinaleShapes09,
- 	kEoB2FinaleShapes10,
+	kEoB2FinaleShapes03,
+	kEoB2FinaleShapes07,
+	kEoB2FinaleShapes09,
+	kEoB2FinaleShapes10,
 
 	kEoB2NpcShapeData,
 	kEoB2Npc1Strings,
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index e4613e2..9a8bff6 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -2062,7 +2062,7 @@ void Screen::decodeFrame1(const uint8 *src, uint8 *dst, uint32 size) {
 
 	Pattern *patterns = new Pattern[3840];
 	uint16 numPatterns = 0;
-	uint8 nib = 0;	
+	uint8 nib = 0;
 
 	uint16 code = decodeEGAGetCode(src, nib);
 	uint8 last = code & 0xff;
@@ -2125,7 +2125,7 @@ void Screen::decodeFrame1(const uint8 *src, uint8 *dst, uint32 size) {
 uint16 Screen::decodeEGAGetCode(const uint8 *&pos, uint8 &nib) {
 	uint16 res = READ_BE_UINT16(pos++);
 	if ((++nib) & 1) {
-		res >>= 4;		
+		res >>= 4;
 	} else {
 		pos++;
 		res &= 0xfff;
@@ -3057,7 +3057,7 @@ bool Screen::loadPalette(const char *filename, Palette &pal) {
 	} else if (_vm->gameFlags().platform == Common::kPlatformPC98 && _use16ColorMode) {
 		numCols = stream->size() / Palette::kPC98BytesPerColor;
 		pal.loadPC98Palette(*stream, 0, MIN(maxCols, numCols));
-	} else if (_vm->gameFlags().gameID == GI_EOB1) {		
+	} else if (_vm->gameFlags().gameID == GI_EOB1) {
 		numCols = stream->size() / Palette::kVGABytesPerColor;
 		pal.loadVGAPalette7bit(*stream, 0, MIN(maxCols, numCols));
 	} else {
diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp
index 15a9fef..62d8bca 100644
--- a/engines/kyra/screen_eob.cpp
+++ b/engines/kyra/screen_eob.cpp
@@ -285,7 +285,7 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4b
 			srcPage += 320;
 			src = srcPage;
 		}
-    	delete [] colorMap;
+		delete [] colorMap;
 	}
 
 	return shp;
diff --git a/engines/kyra/screen_eob.h b/engines/kyra/screen_eob.h
index 2ede813..2efed83 100644
--- a/engines/kyra/screen_eob.h
+++ b/engines/kyra/screen_eob.h
@@ -101,5 +101,3 @@ private:
 #endif // ENABLE_EOB
 
 #endif
-
-
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index f3460bc..c99e0a8 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -1204,10 +1204,10 @@ void DarkMoonEngine::initStaticResource() {
 
 	_shapesIntro = new const EoBShapeDef*[13];
 	memset(_shapesIntro, 0, sizeof(EoBShapeDef*) * 13);
- 	_shapesIntro[0] = _staticres->loadEoB2ShapeData(kEoB2IntroShapes00, temp);
- 	_shapesIntro[1] = _staticres->loadEoB2ShapeData(kEoB2IntroShapes01, temp);
- 	_shapesIntro[4] = _staticres->loadEoB2ShapeData(kEoB2IntroShapes04, temp);
- 	_shapesIntro[7] = _staticres->loadEoB2ShapeData(kEoB2IntroShapes07, temp);
+	_shapesIntro[0] = _staticres->loadEoB2ShapeData(kEoB2IntroShapes00, temp);
+	_shapesIntro[1] = _staticres->loadEoB2ShapeData(kEoB2IntroShapes01, temp);
+	_shapesIntro[4] = _staticres->loadEoB2ShapeData(kEoB2IntroShapes04, temp);
+	_shapesIntro[7] = _staticres->loadEoB2ShapeData(kEoB2IntroShapes07, temp);
 
 	_finaleStrings = _staticres->loadStrings(kEoB2FinaleStrings, temp);
 	_creditsData = _staticres->loadRawData(kEoB2CreditsData, temp);
@@ -1220,10 +1220,10 @@ void DarkMoonEngine::initStaticResource() {
 	_shapesFinale = new const EoBShapeDef*[13];
 	memset(_shapesFinale, 0, sizeof(EoBShapeDef*) * 13);
 	_shapesFinale[0] = _staticres->loadEoB2ShapeData(kEoB2FinaleShapes00, temp);
- 	_shapesFinale[3] = _staticres->loadEoB2ShapeData(kEoB2FinaleShapes03, temp);
- 	_shapesFinale[7] = _staticres->loadEoB2ShapeData(kEoB2FinaleShapes07, temp);
- 	_shapesFinale[9] = _staticres->loadEoB2ShapeData(kEoB2FinaleShapes09, temp);
- 	_shapesFinale[10] = _staticres->loadEoB2ShapeData(kEoB2FinaleShapes10, temp);
+	_shapesFinale[3] = _staticres->loadEoB2ShapeData(kEoB2FinaleShapes03, temp);
+	_shapesFinale[7] = _staticres->loadEoB2ShapeData(kEoB2FinaleShapes07, temp);
+	_shapesFinale[9] = _staticres->loadEoB2ShapeData(kEoB2FinaleShapes09, temp);
+	_shapesFinale[10] = _staticres->loadEoB2ShapeData(kEoB2FinaleShapes10, temp);
 
 	_dscDoorType5Offs = _staticres->loadRawData(kEoBBaseDscDoorType5Offs, temp);
 
@@ -1286,4 +1286,3 @@ const char *DarkMoonEngine::_palFilesFinale[] = {
 #endif // ENABLE_EOB
 
 } // End of namespace Kyra
-
diff --git a/engines/kyra/staticres_rpg.cpp b/engines/kyra/staticres_rpg.cpp
index efee3be..cc75ae3 100644
--- a/engines/kyra/staticres_rpg.cpp
+++ b/engines/kyra/staticres_rpg.cpp
@@ -94,4 +94,3 @@ void KyraRpgEngine::initStaticResource() {
 #endif // (ENABLE_EOB || ENABLE_LOL)
 
 } // End of namespace Kyra
-
diff --git a/engines/kyra/text_lol.h b/engines/kyra/text_lol.h
index baf0f2f..a5eebd6 100644
--- a/engines/kyra/text_lol.h
+++ b/engines/kyra/text_lol.h
@@ -68,4 +68,3 @@ private:
 #endif // ENABLE_LOL
 
 #endif
-
diff --git a/engines/kyra/wsamovie.cpp b/engines/kyra/wsamovie.cpp
index 21ff80f..076c586 100644
--- a/engines/kyra/wsamovie.cpp
+++ b/engines/kyra/wsamovie.cpp
@@ -95,7 +95,7 @@ int WSAMovie_v1::open(const char *filename, int offscreenDecode, Palette *palBuf
 
 	for (int i = 1; i < _numFrames + 2; ++i) {
 		_frameOffsTable[i] = READ_LE_UINT32(wsaData);
-	   	if (_frameOffsTable[i])
+		if (_frameOffsTable[i])
 			_frameOffsTable[i] -= frameDataOffs;
 		wsaData += 4;
 	}


Commit: 40b1b794ae1cdc8524271f5cc522c82cb5a7fd59
    https://github.com/scummvm/scummvm/commit/40b1b794ae1cdc8524271f5cc522c82cb5a7fd59
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:17-08:00

Commit Message:
KYRA: make bool variable const (again)

Changed paths:
    engines/kyra/detection.cpp



diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp
index ceb3ef6..56687d6 100644
--- a/engines/kyra/detection.cpp
+++ b/engines/kyra/detection.cpp
@@ -202,7 +202,7 @@ void KyraMetaEngine::removeSaveState(const char *target, int slot) const {
 SaveStateDescriptor KyraMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
 	Common::String filename = Kyra::KyraEngine_v1::getSavegameFilename(target, slot);
 	Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename);
-	bool nonKyraGame = ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("lol") || ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob") || ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob2");
+	const bool nonKyraGame = ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("lol") || ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob") || ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob2");
 
 	if (in) {
 		Kyra::KyraEngine_v1::SaveHeader header;


Commit: 53e1bf21ecced447192f75067f0232c08d24d647
    https://github.com/scummvm/scummvm/commit/53e1bf21ecced447192f75067f0232c08d24d647
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:17-08:00

Commit Message:
KYRA: (EOB) - get rid of loadVGAPalette7bit()

(slightly change VGA palette loader to accomodate EOB1 palettes)

Changed paths:
    engines/kyra/screen.cpp
    engines/kyra/screen.h



diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index 9a8bff6..8dc53ba 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -3057,9 +3057,6 @@ bool Screen::loadPalette(const char *filename, Palette &pal) {
 	} else if (_vm->gameFlags().platform == Common::kPlatformPC98 && _use16ColorMode) {
 		numCols = stream->size() / Palette::kPC98BytesPerColor;
 		pal.loadPC98Palette(*stream, 0, MIN(maxCols, numCols));
-	} else if (_vm->gameFlags().gameID == GI_EOB1) {
-		numCols = stream->size() / Palette::kVGABytesPerColor;
-		pal.loadVGAPalette7bit(*stream, 0, MIN(maxCols, numCols));
 	} else {
 		numCols = stream->size() / Palette::kVGABytesPerColor;
 		pal.loadVGAPalette(*stream, 0, MIN(maxCols, numCols));
@@ -3524,19 +3521,9 @@ Palette::~Palette() {
 void Palette::loadVGAPalette(Common::ReadStream &stream, int startIndex, int colors) {
 	assert(startIndex + colors <= _numColors);
 
-	stream.read(_palData + startIndex * 3, colors * 3);
-}
-
-void Palette::loadVGAPalette7bit(Common::ReadStream &stream, int startIndex, int colors) {
-	assert(startIndex + colors <= _numColors);
-
-	stream.read(_palData + startIndex * 3, colors * 3);
 	uint8 *pos = _palData + startIndex * 3;
-	for (int i = 0 ; i < colors; i++) {
-		*pos++ &= 0x3f;
-		*pos++ &= 0x3f;
-		*pos++ &= 0x3f;
-	}
+	for (int i = 0 ; i < colors * 3; i++)
+		*pos++ = stream.readByte() & 0x3f;
 }
 
 void Palette::loadAmigaPalette(Common::ReadStream &stream, int startIndex, int colors) {
diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h
index 2db8415..7912e59 100644
--- a/engines/kyra/screen.h
+++ b/engines/kyra/screen.h
@@ -252,11 +252,6 @@ public:
 	void loadVGAPalette(Common::ReadStream &stream, int startIndex, int colors);
 
 	/**
-	 * Load a VGA palette from the given stream masking out the upper bit.
-	 */
-	void loadVGAPalette7bit(Common::ReadStream &stream, int startIndex, int colors);
-
-	/**
 	 * Load a AMIGA palette from the given stream.
 	 */
 	void loadAmigaPalette(Common::ReadStream &stream, int startIndex, int colors);


Commit: c0e782fd0b2ba9de69563e8bcb4fb43e2f311b35
    https://github.com/scummvm/scummvm/commit/c0e782fd0b2ba9de69563e8bcb4fb43e2f311b35
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:17-08:00

Commit Message:
KYRA: (EOB) - Start implementing EOB1 party transfer (not working yet)

(ScummVM specific solution which allows the selection of save files of all configured EOB1 targets)

Changed paths:
    engines/kyra/chargen.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui.cpp
    engines/kyra/gui.h
    engines/kyra/gui_eob.cpp
    engines/kyra/gui_eob.h
    engines/kyra/gui_hof.cpp
    engines/kyra/gui_lok.cpp
    engines/kyra/gui_lol.cpp
    engines/kyra/gui_mr.cpp
    engines/kyra/gui_v2.cpp
    engines/kyra/kyra_v1.h
    engines/kyra/saveload.cpp
    engines/kyra/saveload_eob.cpp
    engines/kyra/staticres_eob.cpp



diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index 2990c6e..b326f92 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -26,8 +26,13 @@
 #include "kyra/resource.h"
 #include "kyra/sound_intern.h"
 
+#include "common/savefile.h"
+#include "common/str-array.h"
+
 namespace Kyra {
 
+// Character Generator
+
 class CharacterGenerator {
 public:
 	CharacterGenerator(EoBCoreEngine *vm, Screen_EoB *screen);
@@ -191,7 +196,7 @@ bool CharacterGenerator::start(EoBCharacter *characters, uint8 ***faceShapes) {
 				loop = false;
 			} else {
 				_activeBox = inputFlag;
-				inputFlag = 43;
+				inputFlag = _vm->_keyMap[Common::KEYCODE_RETURN];
 			}
 		}
 
@@ -1426,13 +1431,157 @@ const int16 CharacterGenerator::_raceModifiers[] = {
 	0, 0, 0, 0,	1, -1, 0, 1, -1, 0, 0, 0, -1, 0, 0, 1, 0, 0
 };
 
+// Transfer Party
+
+class TransferPartyWiz {
+public:
+	TransferPartyWiz(EoBCoreEngine *vm, Screen_EoB *screen);
+	~TransferPartyWiz();
+
+	bool start();
+
+private:
+	bool selectAndLoadTransferFile();
+	Common::String transferFileDialogue();
+
+	void convertStats();
+
+	EoBCoreEngine *_vm;
+	Screen_EoB *_screen;
+};
+
+TransferPartyWiz::TransferPartyWiz(EoBCoreEngine *vm, Screen_EoB *screen) : _vm(vm), _screen(screen) {
+}
+
+TransferPartyWiz::~TransferPartyWiz() {
+
+}
+
+bool TransferPartyWiz::start() {
+	_screen->copyPage(0, 12);
+
+	if (!selectAndLoadTransferFile())
+		return false;
+
+	convertStats();
+
+	return true;
+}
+
+bool TransferPartyWiz::selectAndLoadTransferFile() {
+	for (int numLoops = 1; numLoops; numLoops--)  {
+		_screen->copyPage(12, 0);
+		_vm->_savegameFilename = transferFileDialogue();
+		if (_vm->_savegameFilename.empty()) {
+			if (_vm->_gui->confirmDialogue2(15, 68, 1))
+				numLoops++;
+		}
+	}
+
+	if (_vm->_savegameFilename.equals(_vm->_saveLoadStrings[1]))
+		return false;
+
+	if (_vm->loadGameState(-1).getCode() != Common::kNoError)
+		return false;
+
+	return true;
+}
+
+Common::String TransferPartyWiz::transferFileDialogue() {
+	Common::StringArray saveFileList = _vm->_saveFileMan->listSavefiles("*.*");
+	Common::StringArray targets;
+	Common::String tfile;
+
+	KyraEngine_v1::SaveHeader header;
+	Common::InSaveFile *in;
+
+	for (Common::StringArray::iterator i = saveFileList.begin(); i != saveFileList.end(); ++i) {
+		if (!(in = _vm->_saveFileMan->openForLoading(*i)))
+			continue;
+
+		if (KyraEngine_v1::readSaveHeader(in, false, header)) {
+			delete in;
+			continue;
+		}
+
+		delete in;
+
+		if (header.gameID != GI_EOB1)
+			continue;
+
+		i->insertChar('\0', i->size() - 4);
+
+		Common::StringArray::iterator ii = targets.begin();
+		for (; ii != targets.end(); ++ii) {
+			if (!i->compareToIgnoreCase(*ii))
+				break;
+		}
+
+		if (ii == targets.end())
+			targets.push_back(*i);
+	}
+
+	if (targets.begin() == targets.end())
+		return tfile;
+
+	Common::String target = _vm->_gui->transferTargetMenu(targets);
+	_screen->copyPage(12, 0);
+
+	if (target.equals(_vm->_saveLoadStrings[1]))
+		return target;
+
+	tfile = target + ".fin";
+	in = _vm->_saveFileMan->openForLoading(tfile);
+	if (in) {
+		delete in;
+		if (_vm->_gui->confirmDialogue2(15, -2, 1))
+			return tfile;
+	}
+
+	_screen->copyPage(12, 0);
+
+	tfile = _vm->_gui->transferFileMenu(target);
+	_screen->copyPage(12, 0);
+
+	return tfile;
+}
+
+void TransferPartyWiz::convertStats() {
+	for (int i = 0; i < 6; i++) {
+		EoBCharacter *c = &_vm->_characters[i];
+		uint32 aflags = 0;
+
+		for (int ii = 0; ii < 25; ii++) {
+			if (c->mageSpellsAvailableFlags & (1 << ii)) {
+				int8 f = (int8)_vm->_transferConvertTable[i + 1] - 1;
+				if (f != -1)
+					aflags |= (1 << f);
+			}
+		}
+		c->mageSpellsAvailableFlags = aflags;
+
+		c->flags &= 1;
+		c->hitPointsCur = c->hitPointsMax;
+		c->food = 100;
+
+		for (int ii = 0; ii < 3; ii++) {
+			int t = _vm->getCharacterClassType(c->cClass, ii);
+			if (t == -1)
+				continue;
+			if (c->experience[ii] < _vm->_transferExpTable[t])
+				c->experience[ii] = _vm->_transferExpTable[t];
+		}
+	}
+}
+
+// Start functions
+
 bool EoBCoreEngine::startCharacterGeneration() {
 	return CharacterGenerator(this, _screen).start(_characters, &_faceShapes);
 }
 
-bool EoBCoreEngine::transferParty() {
-
-	return false;
+bool EoBCoreEngine::startPartyTransfer() {
+	return TransferPartyWiz(this, _screen).start();
 }
 
 }	// End of namespace Kyra
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index ebd26d3..c64f60b 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -167,6 +167,7 @@ EoBCoreEngine::EoBCoreEngine(OSystem *system, const GameFlags &flags) : KyraRpgE
 	_expObjectAnimTbl1Size = _expObjectAnimTbl2Size = _expObjectAnimTbl3Size = _wllFlagPresetSize = _scriptTimersCount = _buttonList1Size = _buttonList2Size =
 		_buttonList3Size = _buttonList4Size = _buttonList5Size = _buttonList6Size = _buttonList7Size = _buttonList8Size = 0;
 	_inventorySlotsY = _mnDef = 0;
+	_transferStringsScummVM = 0;
 	_buttonDefs = 0;
 	_npcPreset = 0;
 	_chargenStatStrings	= _chargenRaceSexStrings = _chargenClassStrings = _chargenAlignmentStrings = _pryDoorStrings = _warningStrings = _ripItemStrings =
@@ -463,7 +464,7 @@ Common::Error EoBCoreEngine::go() {
 				startupNew();
 		} else if (action == -3) {
 			// transfer party
-			repeatLoop = transferParty();
+			repeatLoop = startPartyTransfer();
 			if (repeatLoop && !shouldQuit())
 				startupNew();
 		}
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index af16df7..f489f87 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -245,6 +245,7 @@ friend class GUI_EoB;
 friend class EoBInfProcessor;
 friend class DarkmoonSequenceHelper;
 friend class CharacterGenerator;
+friend class TransferPartyWiz;
 public:
 	EoBCoreEngine(OSystem *system, const GameFlags &flags);
 	virtual ~EoBCoreEngine();
@@ -318,7 +319,7 @@ protected:
 
 	// Character generation / party transfer
 	bool startCharacterGeneration();
-	bool transferParty();
+	bool startPartyTransfer();
 
 	uint8 **_faceShapes;
 
@@ -1125,6 +1126,7 @@ protected:
 	const char *_menuOkString;
 
 	const char *const *_menuStringsTransfer;
+	const char *const *_transferStringsScummVM;
 	const char *const *_menuStringsSpec;
 	const char *const *_menuStringsSpellNo;
 	const char *const *_menuYesNoStrings;
diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp
index e2195ca..cc32a97 100644
--- a/engines/kyra/gui.cpp
+++ b/engines/kyra/gui.cpp
@@ -46,8 +46,8 @@ GUI::~GUI() {
 	}
 }
 
-void GUI::updateSaveFileList(bool excludeQuickSaves) {
-	Common::String pattern = _vm->_targetName + ".???";
+void GUI::updateSaveFileList(Common::String targetName, bool excludeQuickSaves) {
+	Common::String pattern = targetName + ".???";
 	Common::StringArray saveFileList = _vm->_saveFileMan->listSavefiles(pattern);
 	_saveSlots.clear();
 
@@ -93,8 +93,8 @@ int GUI::getNextSavegameSlot() {
 	return 0;
 }
 
-void GUI::updateSaveSlotsList() {
-	if (!_saveSlotsListUpdateNeeded)
+void GUI::updateSaveSlotsList(Common::String targetName, bool force) {
+	if (!_saveSlotsListUpdateNeeded && !force)
 		return;
 
 	_saveSlotsListUpdateNeeded = false;
@@ -105,7 +105,7 @@ void GUI::updateSaveSlotsList() {
 		delete[] _savegameList;
 	}
 
-	updateSaveFileList(true);
+	updateSaveFileList(targetName, true);
 	int numSaves = _savegameListSize = _saveSlots.size();
 	bool allowEmptySlots = (_vm->game() == GI_EOB1 || _vm->game() == GI_EOB2);
 
@@ -120,7 +120,7 @@ void GUI::updateSaveSlotsList() {
 		memset(_savegameList, 0, _savegameListSize * sizeof(char*));
 
 		for (int i = 0; i < numSaves; i++) {
-			in = _vm->openSaveForReading(_vm->getSavegameFilename(_saveSlots[i]), header);
+			in = _vm->openSaveForReading(_vm->getSavegameFilename(targetName, _saveSlots[i]).c_str(), header, targetName == _vm->_targetName);
 			char **listEntry = &_savegameList[allowEmptySlots? _saveSlots[i] : i];
 			if (in) {
 				*listEntry = new char[header.description.size() + 1];
diff --git a/engines/kyra/gui.h b/engines/kyra/gui.h
index 2b32bf3..854f10e 100644
--- a/engines/kyra/gui.h
+++ b/engines/kyra/gui.h
@@ -118,9 +118,9 @@ protected:
 	// Since ScummVM's savegame indices aren't, we re-index them.
 	// The integers stored in _saveSlots are ScummVM savegame indices.
 	Common::Array<int> _saveSlots;
-	void updateSaveFileList(bool excludeQuickSaves = false);
+	void updateSaveFileList(Common::String targetName, bool excludeQuickSaves = false);
 	int getNextSavegameSlot();
-	void updateSaveSlotsList();
+	void updateSaveSlotsList(Common::String targetName, bool force = false);
 
 	virtual void sortSaveSlots();
 
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 1930ab1..ab92e08 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -2220,6 +2220,7 @@ bool GUI_EoB::runLoadMenu(int x, int y) {
 	_screen->modifyScreenDim(11, dm->sx + (x >> 3), dm->sy + y, dm->w, dm->h);
 
 	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
+		updateSaveSlotsList(_vm->_targetName);
 		int slot = selectSaveSlotDialogue(x, y, 1);
 		if (slot > 5) {
 			runLoop = result = false;
@@ -2495,6 +2496,66 @@ int GUI_EoB::getTextInput(char *dest, int x, int y, int destMaxLen, int textColo
 	return _keyPressed.keycode == Common::KEYCODE_ESCAPE ? -1 : len;
 }
 
+Common::String GUI_EoB::transferTargetMenu(Common::Array<Common::String> &targets) {
+	_savegameListSize = targets.size();
+	if (_savegameList) {
+		for (int i = 0; i < _savegameListSize; i++)
+			delete[] _savegameList[i];
+		delete[] _savegameList;
+	}
+	_savegameList = new char*[_savegameListSize];
+	memset(_savegameList, 0, _savegameListSize * sizeof(char*));
+
+	Common::StringArray::iterator ii = targets.begin();
+	for (int i = 0; i < _savegameListSize; ++i) {
+		_savegameList[i] = new char[(*ii).size() + 1];
+		strcpy(_savegameList[i], (*ii++).c_str());
+	}
+
+	const ScreenDim *dm = _screen->getScreenDim(11);
+	int xo = dm->sx;
+	int yo = dm->sy;
+	_screen->modifyScreenDim(11, dm->sx + 9, dm->sy + 14, dm->w, dm->h);
+
+	int slot = 0;
+	do {
+		slot = selectSaveSlotDialogue(72, 14, 2);
+		if (slot == 6)
+			break;
+	} while (_saveSlotIdTemp[slot] == -1);
+
+	_screen->copyRegion(72, 14, 72, 14, 176, 144, 12, 0, Screen::CR_NO_P_CHECK);
+	_screen->modifyScreenDim(11, xo, yo, dm->w, dm->h);
+
+	return (slot < 6) ? _savegameList[_savegameOffset + slot] : _vm->_saveLoadStrings[1];
+}
+
+Common::String GUI_EoB::transferFileMenu(Common::String &target) {
+	updateSaveSlotsList(target, true);
+	_saveSlotsListUpdateNeeded = true;
+
+	const ScreenDim *dm = _screen->getScreenDim(11);
+	int xo = dm->sx;
+	int yo = dm->sy;
+	_screen->modifyScreenDim(11, dm->sx + 9, dm->sy + 14, dm->w, dm->h);
+
+	int slot = 0;
+	do {
+		slot = selectSaveSlotDialogue(72, 14, 4);
+		if (slot < 6) {
+			if (_saveSlotIdTemp[slot] == -1)
+				messageDialogue(11, 65, 6);
+			else {
+				_screen->modifyScreenDim(11, xo, yo, dm->w, dm->h);
+				return _vm->getSavegameFilename(target, _saveSlotIdTemp[slot]);
+			}
+		}
+	} while (_saveSlotIdTemp[slot] == -1);
+
+	_screen->modifyScreenDim(11, xo, yo, dm->w, dm->h);
+	return _vm->_saveLoadStrings[1];
+}
+
 void GUI_EoB::createScreenThumbnail(Graphics::Surface &dst) {
 	uint8 *screenPal = new uint8[768];
 	_screen->getRealPalette(0, screenPal);
@@ -2528,6 +2589,7 @@ bool GUI_EoB::runSaveMenu(int x, int y) {
 	_screen->modifyScreenDim(11, dm->sx + (x >> 3), dm->sy + y, dm->w, dm->h);
 
 	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
+		updateSaveSlotsList(_vm->_targetName);
 		int slot = selectSaveSlotDialogue(x, y, 0);
 		if (slot > 5) {
 			runLoop = result = false;
@@ -2575,16 +2637,14 @@ bool GUI_EoB::runSaveMenu(int x, int y) {
 }
 
 int GUI_EoB::selectSaveSlotDialogue(int x, int y, int id) {
-	assert (id < 2);
-
 	_saveSlotX = _saveSlotY = 0;
 	_screen->setCurPage(2);
 
-	updateSaveSlotsList();
 	_savegameOffset = 0;
 
 	drawMenuButtonBox(0, 0, 176, 144, false, false);
-	_screen->printShadedText(_vm->_saveLoadStrings[2 + id], 52, 5, 15, 0);
+	const char *title = (id < 2) ? _vm->_saveLoadStrings[2 + id] : _vm->_transferStringsScummVM[id - 1];
+	_screen->printShadedText(title, 52, 5, 15, 0);
 
 	_screen->copyRegion(0, 0, x, y, 176, 144, 2, 0, Screen::CR_NO_P_CHECK);
 	_screen->setCurPage(0);
@@ -3806,8 +3866,10 @@ const char *GUI_EoB::getMenuString(int id) {
 
 	if (id >= 69)
 		return _vm->_menuStringsTransfer[id - 69];
-	else if (id >= 67)
-		return _vm->_menuStringsDefeat[id - 67];
+	else  if (id == 68)
+		return _vm->_transferStringsScummVM[0];
+	else if (id == 67)
+		return _vm->_menuStringsDefeat[0];
 	else if (id == 66)
 		return _vm->_errorSlotEmptyString;
 	else if (id == 65)
@@ -3846,6 +3908,8 @@ const char *GUI_EoB::getMenuString(int id) {
 		return _vm->_menuStringsSaveLoad[id - 9];
 	else if (id >= 1)
 		return _vm->_menuStringsMain[id - 1];
+	else if (id < 0)
+		return _vm->_transferStringsScummVM[-id];
 	return empty;
 }
 
diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h
index 95dedcf..d8ce9bd 100644
--- a/engines/kyra/gui_eob.h
+++ b/engines/kyra/gui_eob.h
@@ -69,6 +69,10 @@ public:
 
 	int getTextInput(char *dest, int x, int y, int destMaxLen, int textColor1, int textColor2, int cursorColor);
 
+	// Transfer party
+	Common::String transferTargetMenu(Common::Array<Common::String> &targets);
+	Common::String transferFileMenu(Common::String &target);
+
 	// utilities for thumbnail creation
 	void createScreenThumbnail(Graphics::Surface &dst);
 
diff --git a/engines/kyra/gui_hof.cpp b/engines/kyra/gui_hof.cpp
index 8d968ec..c1bfee0 100644
--- a/engines/kyra/gui_hof.cpp
+++ b/engines/kyra/gui_hof.cpp
@@ -1148,7 +1148,7 @@ int GUI_HoF::sliderHandler(Button *caller) {
 }
 
 int GUI_HoF::loadMenu(Button *caller) {
-	updateSaveFileList();
+	updateSaveFileList(_vm->_targetName);
 
 	if (!_vm->_menuDirectlyToLoad) {
 		updateMenuButton(caller);
diff --git a/engines/kyra/gui_lok.cpp b/engines/kyra/gui_lok.cpp
index e66b3ce..2a2828d 100644
--- a/engines/kyra/gui_lok.cpp
+++ b/engines/kyra/gui_lok.cpp
@@ -596,7 +596,7 @@ void GUI_LoK::setupSavegames(Menu &menu, int num) {
 }
 
 int GUI_LoK::saveGameMenu(Button *button) {
-	updateSaveFileList();
+	updateSaveFileList(_vm->_targetName);
 
 	updateMenuButton(button);
 	_menu[2].item[5].enabled = true;
@@ -636,7 +636,7 @@ int GUI_LoK::saveGameMenu(Button *button) {
 }
 
 int GUI_LoK::loadGameMenu(Button *button) {
-	updateSaveFileList();
+	updateSaveFileList(_vm->_targetName);
 
 	if (_vm->_menuDirectlyToLoad) {
 		_menu[2].item[5].enabled = false;
diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp
index 6a8e6e1..2494713 100644
--- a/engines/kyra/gui_lol.cpp
+++ b/engines/kyra/gui_lol.cpp
@@ -2228,7 +2228,7 @@ int GUI_LoL::runMenu(Menu &menu) {
 		_vm->_mouseX = _vm->_mouseY = 0;
 
 		if (_currentMenu == &_loadMenu || _currentMenu == &_saveMenu || _currentMenu == &_deleteMenu) {
-			updateSaveSlotsList();
+			updateSaveSlotsList(_vm->_targetName);
 			setupSaveMenuSlots(*_currentMenu, 4);
 		}
 
diff --git a/engines/kyra/gui_mr.cpp b/engines/kyra/gui_mr.cpp
index b8bf8f4..e88b7fd 100644
--- a/engines/kyra/gui_mr.cpp
+++ b/engines/kyra/gui_mr.cpp
@@ -1277,7 +1277,7 @@ int GUI_MR::optionsButton(Button *button) {
 }
 
 int GUI_MR::loadMenu(Button *caller) {
-	updateSaveFileList();
+	updateSaveFileList(_vm->_targetName);
 
 	if (!_vm->_menuDirectlyToLoad) {
 		updateMenuButton(caller);
diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp
index 27b329c..0e19d48 100644
--- a/engines/kyra/gui_v2.cpp
+++ b/engines/kyra/gui_v2.cpp
@@ -594,7 +594,7 @@ int GUI_v2::cancelLoadMenu(Button *caller) {
 }
 
 int GUI_v2::saveMenu(Button *caller) {
-	updateSaveFileList();
+	updateSaveFileList(_vm->_targetName);
 
 	updateMenuButton(caller);
 
@@ -690,7 +690,7 @@ int GUI_v2::cancelSaveMenu(Button *caller) {
 }
 
 int GUI_v2::deleteMenu(Button *caller) {
-	updateSaveFileList();
+	updateSaveFileList(_vm->_targetName);
 
 	updateMenuButton(caller);
 	if (_saveSlots.size() < 2) {
diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h
index f530c02..e66f0fb 100644
--- a/engines/kyra/kyra_v1.h
+++ b/engines/kyra/kyra_v1.h
@@ -424,7 +424,7 @@ protected:
 	Common::Error saveGameState(int slot, const Common::String &desc) { return saveGameStateIntern(slot, desc.c_str(), 0); }
 	virtual Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) = 0;
 
-	Common::SeekableReadStream *openSaveForReading(const char *filename, SaveHeader &header);
+	Common::SeekableReadStream *openSaveForReading(const char *filename, SaveHeader &header, bool checkID = true);
 	Common::WriteStream *openSaveForWriting(const char *filename, const char *saveName, const Graphics::Surface *thumbnail) const;
 
 	// TODO: Consider moving this to Screen
diff --git a/engines/kyra/saveload.cpp b/engines/kyra/saveload.cpp
index 42c5d3e..e9c61b0 100644
--- a/engines/kyra/saveload.cpp
+++ b/engines/kyra/saveload.cpp
@@ -122,7 +122,7 @@ KyraEngine_v1::kReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::Seekab
 	return ((in->err() || in->eos()) ? kRSHEIoError : kRSHENoError);
 }
 
-Common::SeekableReadStream *KyraEngine_v1::openSaveForReading(const char *filename, SaveHeader &header) {
+Common::SeekableReadStream *KyraEngine_v1::openSaveForReading(const char *filename, SaveHeader &header, bool checkID) {
 	Common::SeekableReadStream *in = 0;
 	if (!(in = _saveFileMan->openForLoading(filename)))
 		return 0;
@@ -142,7 +142,7 @@ Common::SeekableReadStream *KyraEngine_v1::openSaveForReading(const char *filena
 
 	if (!header.originalSave) {
 		if (!header.oldHeader) {
-			if (header.gameID != _flags.gameID) {
+			if (header.gameID != _flags.gameID && checkID) {
 				warning("Trying to load game state from other game (save game: %u, running game: %u)", header.gameID, _flags.gameID);
 				delete in;
 				return 0;
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index 31f2023..714033b 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -32,23 +32,19 @@
 namespace Kyra {
 
 Common::Error EoBCoreEngine::loadGameState(int slot) {
-	const char *fileName = 0;
-
-	if (slot == -1) {
-		_savegameFilename = /*_targetName + */Common::String("eob.fin");
-		fileName = _savegameFilename.c_str();
-	} else {
-		fileName = getSavegameFilename(slot);
-	}
+	// Special slot id -1 for EOB1 party transfer
+	const char *fileName = (slot == -1) ? _savegameFilename.c_str() : getSavegameFilename(slot);
 
 	SaveHeader header;
-	Common::InSaveFile *saveFile = openSaveForReading(fileName, header);
+	Common::InSaveFile *saveFile = openSaveForReading(fileName, header, (slot != -1));
 	if (!saveFile)
 		return Common::Error(Common::kReadingFailed);
 
 	Common::SeekableSubReadStreamEndian in(saveFile, saveFile->pos(), saveFile->size(), !header.originalSave, DisposeAfterUse::YES);
 	_loading = true;
-	_screen->fadeToBlack(10);
+
+	if (slot != -1)
+		_screen->fadeToBlack(10);
 
 	for (int i = 0; i < 6; i++) {
 		EoBCharacter *c = &_characters[i];
@@ -77,6 +73,8 @@ Common::Error EoBCoreEngine::loadGameState(int slot) {
 		c->cClass = in.readByte();
 		c->alignment = in.readByte();
 		c->portrait = in.readSByte();
+		if (slot == -1 && c->portrait < 0)
+			c->portrait += 43;
 		c->food = in.readByte();
 		in.read(c->level, 3);
 		for (int ii = 0; ii < 3; ii++)
@@ -120,6 +118,10 @@ Common::Error EoBCoreEngine::loadGameState(int slot) {
 	}
 	_screen->_curPage = 0;
 
+	// No more data required for party transfer
+	if (slot == -1)
+		return Common::kNoError;
+
 	_currentLevel = in.readByte();
 	_currentSub = in.readSByte();
 	_currentBlock = in.readUint16BE();
@@ -303,6 +305,7 @@ Common::Error EoBCoreEngine::saveGameStateIntern(int slot, const char *saveName,
 	Common::String saveNameTmp;
 	const char *fileName = 0;
 
+	// Special slot id -1 to create final save for party transfer
 	if (slot == -1) {
 		_savegameFilename = _targetName + Common::String(".fin");
 		fileName = _savegameFilename.c_str();
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index c99e0a8..8ab16f5 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -473,15 +473,8 @@ void EoBCoreEngine::initStaticResource() {
 		0
 	};
 
-	static const char *errorSlotNoNameString[3] = {
-		" You must specify\r a name for your\r save game!",
-		" Spielstände müssen\r einen Namen haben!",
-		0
-	};
-
 	_saveLoadStrings = saveLoadStrings[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
 	_errorSlotEmptyString = errorSlotEmptyString[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
-	_errorSlotNoNameString = errorSlotNoNameString[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
 	_menuOkString = "OK";
 }
 
@@ -1107,6 +1100,14 @@ void EoBEngine::initStaticResource() {
 		p->tuResist = (int8)*ps++;
 		p->dmgModifierEvade = *ps++;
 	}
+
+	static const char *errorSlotNoNameString[3] = {
+		" You must specify\r a name for your\r save game!",
+		" Spielstaende mues-\r sen einen Namen\r haben!",
+		0
+	};
+
+	_errorSlotNoNameString = errorSlotNoNameString[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
 }
 
 void EoBEngine::initSpells() {
@@ -1241,6 +1242,32 @@ void DarkMoonEngine::initStaticResource() {
 	_wallOfForceDsNumW = _staticres->loadRawData(kEoB2WallOfForceNumW, temp);
 	_wallOfForceDsNumH = _staticres->loadRawData(kEoB2WallOfForceNumH, temp);
 	_wallOfForceShpId = _staticres->loadRawData(kEoB2WallOfForceShpId, temp);
+
+	static const char *errorSlotNoNameString[3] = {
+		" You must specify\r a name for your\r save game!",
+		" Spielst[nde m]ssen\r einen Namen haben!",
+		0
+	};
+
+	_errorSlotNoNameString = errorSlotNoNameString[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
+
+	// ScummVM specific
+	static const char *transferStringsScummVM[3][4] = {
+		{	"\r We cannot find any EOB save game\r file. Please make sure that the\r save game file with the party\r you wish to transfer is located\r in your ScummVM save game\r directory. If you have set up\r multiple save directories you\r have to copy the EOB save file\r into your EOB II save directory.\r Do you wish to try again?",
+			"Game ID",
+			"\r It seems that you have already\r defeated Xanathar here. Do you\r wish to transfer the party that\r finished the game? If not, you\r will be able to select a save\r game from the save game\r dialogue.",
+			"Select File"
+		},
+		{	"\r Kein EOB-Spielstand zu finden.\r Bitte Spielstandsdatei mit der\r zu ]bernehmenden Gruppe in das\r ScummVM Spielstands-Verzeichnis\r kopieren. Bei mehreren Spiel-\r stands-Verzeichnissen bitte\r den EOB-Spielstand in das\r EOB II-Spielstands-Verzeichnis\r kopieren. Nochmal versuchen?",
+			"Game ID",
+			"\r Wie es scheint, wurde Xanathar\r hier bereits besiegt. Soll die\r Gruppe, mit der das Spiel be-\r endet wurde, ]bernommen werden?\r Falls nicht, kann ein Spielstand\r aus der Spielstandsliste gew[hlt\r werden.",
+			"Spiel W[hlen"
+		},
+		{	0, 0, 0, 0
+		}
+	};
+
+	_transferStringsScummVM = transferStringsScummVM[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
 }
 
 void DarkMoonEngine::initSpells() {


Commit: d807b3d42b4a49dfe8262f496f9b341aef3c8bdd
    https://github.com/scummvm/scummvm/commit/d807b3d42b4a49dfe8262f496f9b341aef3c8bdd
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:17-08:00

Commit Message:
KYRA: (EOB) - implement EOB1 party transfer

Changed paths:
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/extract.cpp
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/tables.cpp
    dists/engine-data/kyra.dat
    engines/kyra/chargen.cpp
    engines/kyra/eobcommon.cpp
    engines/kyra/eobcommon.h
    engines/kyra/gui_eob.cpp
    engines/kyra/gui_eob.h
    engines/kyra/items_eob.cpp
    engines/kyra/resource.h
    engines/kyra/saveload_eob.cpp
    engines/kyra/staticres_eob.cpp



diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index 207385e..13f9711 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -298,7 +298,7 @@ const ExtractFilename extractFilenames[] = {
 	{ kEoBBaseNumSpellsWisAdj, kTypeRawData, false },
 	{ kEoBBaseNumSpellsPal, kTypeRawData, false },
 	{ kEoBBaseNumSpellsMage, kTypeRawData, false },
-	
+
 	{ kEoBBaseCharGuiStringsHp, kTypeStringList, true },
 	{ kEoBBaseCharGuiStringsWp1, kTypeStringList, true },
 	{ kEoBBaseCharGuiStringsWp2, kTypeStringList, true },
@@ -380,7 +380,7 @@ const ExtractFilename extractFilenames[] = {
 	{ kEoBBaseMagicStrings6, kTypeStringList, true },
 	{ kEoBBaseMagicStrings7, kTypeStringList, true },
 	{ kEoBBaseMagicStrings8, kTypeStringList, true },
-	
+
 	{ kEoBBaseExpObjectTlMode, kTypeRawData, false },
 	{ kEoBBaseExpObjectTblIndex, kTypeRawData, false },
 	{ kEoBBaseExpObjectShpStart, kTypeRawData, false },
@@ -463,89 +463,95 @@ const ExtractFilename extractFilenames[] = {
 
 	// EYE OF THE BEHOLDER II
 	{ kEoB2MainMenuStrings, kTypeStringList, true },
+
+	{ kEoB2TransferPortraitFrames, kLoLTypeRaw16, false },
 	{ kEoB2TransferConvertTable, kTypeRawData, false },
+	{ kEoB2TransferItemTable, kTypeRawData, false },
 	{ kEoB2TransferExpTable, kLoLTypeRaw32, false },
+	{ kEoB2TransferStrings1, kTypeStringList, true },
+	{ kEoB2TransferStrings2, kTypeStringList, true },
+	{ kEoB2TransferLabels, kTypeStringList, true },
 
 	{ kEoB2IntroStrings, k2TypeSfxList, true },
 	{ kEoB2IntroCPSFiles, kTypeStringList, true },
 	{ kEoB2IntroSeqData00, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData01, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData02, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData03, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData04, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData05, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData06, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData07, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData08, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData09, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData10, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData11, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData12, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData13, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData14, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData15, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData16, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData17, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData18, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData19, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData20, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData21, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData22, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData23, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData24, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData25, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData26, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData27, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData28, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData29, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData30, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData31, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData32, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData33, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData34, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData35, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData36, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData37, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData38, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData39, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData40, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData41, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData42, kEoB2TypeSeqData, false },
- 	{ kEoB2IntroSeqData43, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData01, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData02, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData03, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData04, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData05, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData06, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData07, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData08, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData09, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData10, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData11, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData12, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData13, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData14, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData15, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData16, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData17, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData18, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData19, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData20, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData21, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData22, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData23, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData24, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData25, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData26, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData27, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData28, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData29, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData30, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData31, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData32, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData33, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData34, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData35, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData36, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData37, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData38, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData39, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData40, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData41, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData42, kEoB2TypeSeqData, false },
+	{ kEoB2IntroSeqData43, kEoB2TypeSeqData, false },
 	{ kEoB2IntroShapes00, kEoB2TypeShapeData, false },
- 	{ kEoB2IntroShapes01, kEoB2TypeShapeData, false },
- 	{ kEoB2IntroShapes04, kEoB2TypeShapeData, false },
- 	{ kEoB2IntroShapes07, kEoB2TypeShapeData, false },
+	{ kEoB2IntroShapes01, kEoB2TypeShapeData, false },
+	{ kEoB2IntroShapes04, kEoB2TypeShapeData, false },
+	{ kEoB2IntroShapes07, kEoB2TypeShapeData, false },
 
 	{ kEoB2FinaleStrings, k2TypeSfxList, true },
 	{ kEoB2CreditsData, kTypeRawData, true },
 	{ kEoB2FinaleCPSFiles, kTypeStringList, true },
 	{ kEoB2FinaleSeqData00, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData01, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData02, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData03, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData04, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData05, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData06, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData07, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData08, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData09, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData10, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData11, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData12, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData13, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData14, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData15, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData16, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData17, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData18, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData19, kEoB2TypeSeqData, false },
- 	{ kEoB2FinaleSeqData20, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData01, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData02, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData03, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData04, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData05, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData06, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData07, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData08, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData09, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData10, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData11, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData12, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData13, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData14, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData15, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData16, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData17, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData18, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData19, kEoB2TypeSeqData, false },
+	{ kEoB2FinaleSeqData20, kEoB2TypeSeqData, false },
 	{ kEoB2FinaleShapes00, kEoB2TypeShapeData, false },
- 	{ kEoB2FinaleShapes03, kEoB2TypeShapeData, false },
- 	{ kEoB2FinaleShapes07, kEoB2TypeShapeData, false },
- 	{ kEoB2FinaleShapes09, kEoB2TypeShapeData, false },
- 	{ kEoB2FinaleShapes10, kEoB2TypeShapeData, false },
+	{ kEoB2FinaleShapes03, kEoB2TypeShapeData, false },
+	{ kEoB2FinaleShapes07, kEoB2TypeShapeData, false },
+	{ kEoB2FinaleShapes09, kEoB2TypeShapeData, false },
+	{ kEoB2FinaleShapes10, kEoB2TypeShapeData, false },
 	{ kEoB2NpcShapeData, kTypeRawData, false },
 	{ kEoBBaseClassModifierFlags, kTypeRawData, false },
 	{ kEoBBaseMonsterStepTable01, kTypeRawData, false },
@@ -579,7 +585,7 @@ const ExtractFilename extractFilenames[] = {
 	{ kEoB2WallOfForceNumW, kTypeRawData, false },
 	{ kEoB2WallOfForceNumH, kTypeRawData, false },
 	{ kEoB2WallOfForceShpId, kTypeRawData, false },
-	
+
 	// LANDS OF LORE
 
 	// Ingame
@@ -1434,7 +1440,7 @@ const char *getIdString(const int id) {
 	case kEoBBaseOkStrings:
 		return "kEoBBaseOkStrings";
 	case kEoBBaseNpcJoinStrings:
-		return "kEoBBaseNpcJoinStrings";		
+		return "kEoBBaseNpcJoinStrings";
 	case kEoBBaseCancelStrings:
 		return "kEoBBaseCancelStrings";
 	case kEoBBaseAbortStrings:
@@ -1782,167 +1788,177 @@ const char *getIdString(const int id) {
 		return "kEoB1Npc7Strings";
 	case kEoB2MainMenuStrings:
 		return "kEoB2MainMenuStrings";
+	case kEoB2TransferPortraitFrames:
+		return "kEoB2TransferPortraitFrames";
 	case kEoB2TransferConvertTable:
 		return "kEoB2TransferConvertTable";
+	case kEoB2TransferItemTable:
+		return "kEoB2TransferItemTable";
 	case kEoB2TransferExpTable:
 		return "kEoB2TransferExpTable";
+	case kEoB2TransferStrings1:
+		return "kEoB2TransferStrings1";
+	case kEoB2TransferStrings2:
+		return "kEoB2TransferStrings2";
+	case kEoB2TransferLabels:
+		return "kEoB2TransferLabels";
 	case kEoB2IntroStrings:
 		return "kEoB2IntroStrings";
 	case kEoB2IntroCPSFiles:
 		return "kEoB2IntroCPSFiles";
 	case kEoB2IntroSeqData00:
 		return "kEoB2IntroSeqData00";
- 	case kEoB2IntroSeqData01:
+	case kEoB2IntroSeqData01:
 		return "kEoB2IntroSeqData01";
- 	case kEoB2IntroSeqData02:
+	case kEoB2IntroSeqData02:
 		return "kEoB2IntroSeqData02";
- 	case kEoB2IntroSeqData03:
+	case kEoB2IntroSeqData03:
 		return "kEoB2IntroSeqData03";
- 	case kEoB2IntroSeqData04:
+	case kEoB2IntroSeqData04:
 		return "kEoB2IntroSeqData04";
- 	case kEoB2IntroSeqData05:
+	case kEoB2IntroSeqData05:
 		return "kEoB2IntroSeqData05";
- 	case kEoB2IntroSeqData06:
+	case kEoB2IntroSeqData06:
 		return "kEoB2IntroSeqData06";
- 	case kEoB2IntroSeqData07:
+	case kEoB2IntroSeqData07:
 		return "kEoB2IntroSeqData07";
- 	case kEoB2IntroSeqData08:
+	case kEoB2IntroSeqData08:
 		return "kEoB2IntroSeqData08";
- 	case kEoB2IntroSeqData09:
+	case kEoB2IntroSeqData09:
 		return "kEoB2IntroSeqData09";
- 	case kEoB2IntroSeqData10:
+	case kEoB2IntroSeqData10:
 		return "kEoB2IntroSeqData10";
- 	case kEoB2IntroSeqData11:
+	case kEoB2IntroSeqData11:
 		return "kEoB2IntroSeqData11";
- 	case kEoB2IntroSeqData12:
+	case kEoB2IntroSeqData12:
 		return "kEoB2IntroSeqData12";
- 	case kEoB2IntroSeqData13:
+	case kEoB2IntroSeqData13:
 		return "kEoB2IntroSeqData13";
- 	case kEoB2IntroSeqData14:
+	case kEoB2IntroSeqData14:
 		return "kEoB2IntroSeqData14";
- 	case kEoB2IntroSeqData15:
+	case kEoB2IntroSeqData15:
 		return "kEoB2IntroSeqData15";
- 	case kEoB2IntroSeqData16:
+	case kEoB2IntroSeqData16:
 		return "kEoB2IntroSeqData16";
- 	case kEoB2IntroSeqData17:
+	case kEoB2IntroSeqData17:
 		return "kEoB2IntroSeqData17";
- 	case kEoB2IntroSeqData18:
+	case kEoB2IntroSeqData18:
 		return "kEoB2IntroSeqData18";
- 	case kEoB2IntroSeqData19:
+	case kEoB2IntroSeqData19:
 		return "kEoB2IntroSeqData19";
- 	case kEoB2IntroSeqData20:
+	case kEoB2IntroSeqData20:
 		return "kEoB2IntroSeqData20";
- 	case kEoB2IntroSeqData21:
+	case kEoB2IntroSeqData21:
 		return "kEoB2IntroSeqData21";
- 	case kEoB2IntroSeqData22:
+	case kEoB2IntroSeqData22:
 		return "kEoB2IntroSeqData22";
- 	case kEoB2IntroSeqData23:
+	case kEoB2IntroSeqData23:
 		return "kEoB2IntroSeqData23";
- 	case kEoB2IntroSeqData24:
+	case kEoB2IntroSeqData24:
 		return "kEoB2IntroSeqData24";
- 	case kEoB2IntroSeqData25:
+	case kEoB2IntroSeqData25:
 		return "kEoB2IntroSeqData25";
- 	case kEoB2IntroSeqData26:
+	case kEoB2IntroSeqData26:
 		return "kEoB2IntroSeqData26";
- 	case kEoB2IntroSeqData27:
+	case kEoB2IntroSeqData27:
 		return "kEoB2IntroSeqData27";
- 	case kEoB2IntroSeqData28:
+	case kEoB2IntroSeqData28:
 		return "kEoB2IntroSeqData28";
- 	case kEoB2IntroSeqData29:
+	case kEoB2IntroSeqData29:
 		return "kEoB2IntroSeqData29";
- 	case kEoB2IntroSeqData30:
+	case kEoB2IntroSeqData30:
 		return "kEoB2IntroSeqData30";
- 	case kEoB2IntroSeqData31:
+	case kEoB2IntroSeqData31:
 		return "kEoB2IntroSeqData31";
- 	case kEoB2IntroSeqData32:
+	case kEoB2IntroSeqData32:
 		return "kEoB2IntroSeqData32";
- 	case kEoB2IntroSeqData33:
+	case kEoB2IntroSeqData33:
 		return "kEoB2IntroSeqData33";
- 	case kEoB2IntroSeqData34:
+	case kEoB2IntroSeqData34:
 		return "kEoB2IntroSeqData34";
- 	case kEoB2IntroSeqData35:
+	case kEoB2IntroSeqData35:
 		return "kEoB2IntroSeqData35";
- 	case kEoB2IntroSeqData36:
+	case kEoB2IntroSeqData36:
 		return "kEoB2IntroSeqData36";
- 	case kEoB2IntroSeqData37:
+	case kEoB2IntroSeqData37:
 		return "kEoB2IntroSeqData37";
- 	case kEoB2IntroSeqData38:
+	case kEoB2IntroSeqData38:
 		return "kEoB2IntroSeqData38";
- 	case kEoB2IntroSeqData39:
+	case kEoB2IntroSeqData39:
 		return "kEoB2IntroSeqData39";
- 	case kEoB2IntroSeqData40:
+	case kEoB2IntroSeqData40:
 		return "kEoB2IntroSeqData40";
- 	case kEoB2IntroSeqData41:
+	case kEoB2IntroSeqData41:
 		return "kEoB2IntroSeqData41";
- 	case kEoB2IntroSeqData42:
+	case kEoB2IntroSeqData42:
 		return "kEoB2IntroSeqData42";
- 	case kEoB2IntroSeqData43:
+	case kEoB2IntroSeqData43:
 		return "kEoB2IntroSeqData43";
- 	case kEoB2IntroShapes00:
+	case kEoB2IntroShapes00:
 		return "kEoB2IntroShapes00";
- 	case kEoB2IntroShapes01:
+	case kEoB2IntroShapes01:
 		return "kEoB2IntroShapes01";
- 	case kEoB2IntroShapes04:
+	case kEoB2IntroShapes04:
 		return "kEoB2IntroShapes04";
- 	case kEoB2IntroShapes07:
+	case kEoB2IntroShapes07:
 		return "kEoB2IntroShapes07";
 	case kEoB2FinaleStrings:
 		return "kEoB2FinaleStrings";
 	case kEoB2CreditsData:
 		return "kEoB2CreditsData";
 	case kEoB2FinaleCPSFiles:
-		return "kEoB2FinaleCPSFiles";		
- 	case kEoB2FinaleSeqData00:
+		return "kEoB2FinaleCPSFiles";
+	case kEoB2FinaleSeqData00:
 		return "kEoB2FinaleSeqData00";
- 	case kEoB2FinaleSeqData01:
+	case kEoB2FinaleSeqData01:
 		return "kEoB2FinaleSeqData01";
- 	case kEoB2FinaleSeqData02:
+	case kEoB2FinaleSeqData02:
 		return "kEoB2FinaleSeqData02";
- 	case kEoB2FinaleSeqData03:
+	case kEoB2FinaleSeqData03:
 		return "kEoB2FinaleSeqData03";
- 	case kEoB2FinaleSeqData04:
+	case kEoB2FinaleSeqData04:
 		return "kEoB2FinaleSeqData04";
- 	case kEoB2FinaleSeqData05:
+	case kEoB2FinaleSeqData05:
 		return "kEoB2FinaleSeqData05";
- 	case kEoB2FinaleSeqData06:
+	case kEoB2FinaleSeqData06:
 		return "kEoB2FinaleSeqData06";
- 	case kEoB2FinaleSeqData07:
+	case kEoB2FinaleSeqData07:
 		return "kEoB2FinaleSeqData07";
- 	case kEoB2FinaleSeqData08:
+	case kEoB2FinaleSeqData08:
 		return "kEoB2FinaleSeqData08";
- 	case kEoB2FinaleSeqData09:
+	case kEoB2FinaleSeqData09:
 		return "kEoB2FinaleSeqData09";
- 	case kEoB2FinaleSeqData10:
+	case kEoB2FinaleSeqData10:
 		return "kEoB2FinaleSeqData10";
- 	case kEoB2FinaleSeqData11:
+	case kEoB2FinaleSeqData11:
 		return "kEoB2FinaleSeqData11";
- 	case kEoB2FinaleSeqData12:
+	case kEoB2FinaleSeqData12:
 		return "kEoB2FinaleSeqData12";
- 	case kEoB2FinaleSeqData13:
+	case kEoB2FinaleSeqData13:
 		return "kEoB2FinaleSeqData13";
- 	case kEoB2FinaleSeqData14:
+	case kEoB2FinaleSeqData14:
 		return "kEoB2FinaleSeqData14";
- 	case kEoB2FinaleSeqData15:
+	case kEoB2FinaleSeqData15:
 		return "kEoB2FinaleSeqData15";
- 	case kEoB2FinaleSeqData16:
+	case kEoB2FinaleSeqData16:
 		return "kEoB2FinaleSeqData16";
- 	case kEoB2FinaleSeqData17:
+	case kEoB2FinaleSeqData17:
 		return "kEoB2FinaleSeqData17";
- 	case kEoB2FinaleSeqData18:
+	case kEoB2FinaleSeqData18:
 		return "kEoB2FinaleSeqData18";
- 	case kEoB2FinaleSeqData19:
+	case kEoB2FinaleSeqData19:
 		return "kEoB2FinaleSeqData19";
- 	case kEoB2FinaleSeqData20:
-		return "kEoB2FinaleSeqData20";	
- 	case kEoB2FinaleShapes00:
+	case kEoB2FinaleSeqData20:
+		return "kEoB2FinaleSeqData20";
+	case kEoB2FinaleShapes00:
 		return "kEoB2FinaleShapes00";
- 	case kEoB2FinaleShapes03:
+	case kEoB2FinaleShapes03:
 		return "kEoB2FinaleShapes03";
- 	case kEoB2FinaleShapes07:
+	case kEoB2FinaleShapes07:
 		return "kEoB2FinaleShapes07";
- 	case kEoB2FinaleShapes09:
+	case kEoB2FinaleShapes09:
 		return "kEoB2FinaleShapes09";
- 	case kEoB2FinaleShapes10:
+	case kEoB2FinaleShapes10:
 		return "kEoB2FinaleShapes10";
 	case kEoB2NpcShapeData:
 		return "kEoB2NpcShapeData";
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index 271ffb5..3de785d 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -218,7 +218,7 @@ enum kExtractID {
 	kEoBBaseItemSuffixStringsRings,
 	kEoBBaseItemSuffixStringsPotions,
 	kEoBBaseItemSuffixStringsWands,
-	
+
 	kEoBBaseRipItemStrings,
 	kEoBBaseCursedString,
 	kEoBBaseEnchantedString,
@@ -233,7 +233,7 @@ enum kExtractID {
 	kEoBBasePotionStrings,
 	kEoBBaseWandString,
 	kEoBBaseItemMisuseStrings,
-	
+
 	kEoBBaseTakenStrings,
 	kEoBBasePotionEffectStrings,
 
@@ -363,7 +363,7 @@ enum kExtractID {
 	kEoBBaseFlightObjSclIndex,
 
 	kEoBBaseDscTelptrShpCoords,
-	
+
 	kEoBBasePortalSeqData,
 	kEoBBaseManDef,
 	kEoBBaseManWord,
@@ -463,89 +463,95 @@ enum kExtractID {
 	kEoB1Npc7Strings,
 
 	kEoB2MainMenuStrings,
+
+	kEoB2TransferPortraitFrames,
 	kEoB2TransferConvertTable,
+	kEoB2TransferItemTable,
 	kEoB2TransferExpTable,
+	kEoB2TransferStrings1,
+	kEoB2TransferStrings2,
+	kEoB2TransferLabels,
 
 	kEoB2IntroStrings,
 	kEoB2IntroCPSFiles,
 	kEoB2IntroSeqData00,
- 	kEoB2IntroSeqData01,
- 	kEoB2IntroSeqData02,
- 	kEoB2IntroSeqData03,
- 	kEoB2IntroSeqData04,
- 	kEoB2IntroSeqData05,
- 	kEoB2IntroSeqData06,
- 	kEoB2IntroSeqData07,
- 	kEoB2IntroSeqData08,
- 	kEoB2IntroSeqData09,
- 	kEoB2IntroSeqData10,
- 	kEoB2IntroSeqData11,
- 	kEoB2IntroSeqData12,
- 	kEoB2IntroSeqData13,
- 	kEoB2IntroSeqData14,
- 	kEoB2IntroSeqData15,
- 	kEoB2IntroSeqData16,
- 	kEoB2IntroSeqData17,
- 	kEoB2IntroSeqData18,
- 	kEoB2IntroSeqData19,
- 	kEoB2IntroSeqData20,
- 	kEoB2IntroSeqData21,
- 	kEoB2IntroSeqData22,
- 	kEoB2IntroSeqData23,
- 	kEoB2IntroSeqData24,
- 	kEoB2IntroSeqData25,
- 	kEoB2IntroSeqData26,
- 	kEoB2IntroSeqData27,
- 	kEoB2IntroSeqData28,
- 	kEoB2IntroSeqData29,
- 	kEoB2IntroSeqData30,
- 	kEoB2IntroSeqData31,
- 	kEoB2IntroSeqData32,
- 	kEoB2IntroSeqData33,
- 	kEoB2IntroSeqData34,
- 	kEoB2IntroSeqData35,
- 	kEoB2IntroSeqData36,
- 	kEoB2IntroSeqData37,
- 	kEoB2IntroSeqData38,
- 	kEoB2IntroSeqData39,
- 	kEoB2IntroSeqData40,
- 	kEoB2IntroSeqData41,
- 	kEoB2IntroSeqData42,
- 	kEoB2IntroSeqData43,
+	kEoB2IntroSeqData01,
+	kEoB2IntroSeqData02,
+	kEoB2IntroSeqData03,
+	kEoB2IntroSeqData04,
+	kEoB2IntroSeqData05,
+	kEoB2IntroSeqData06,
+	kEoB2IntroSeqData07,
+	kEoB2IntroSeqData08,
+	kEoB2IntroSeqData09,
+	kEoB2IntroSeqData10,
+	kEoB2IntroSeqData11,
+	kEoB2IntroSeqData12,
+	kEoB2IntroSeqData13,
+	kEoB2IntroSeqData14,
+	kEoB2IntroSeqData15,
+	kEoB2IntroSeqData16,
+	kEoB2IntroSeqData17,
+	kEoB2IntroSeqData18,
+	kEoB2IntroSeqData19,
+	kEoB2IntroSeqData20,
+	kEoB2IntroSeqData21,
+	kEoB2IntroSeqData22,
+	kEoB2IntroSeqData23,
+	kEoB2IntroSeqData24,
+	kEoB2IntroSeqData25,
+	kEoB2IntroSeqData26,
+	kEoB2IntroSeqData27,
+	kEoB2IntroSeqData28,
+	kEoB2IntroSeqData29,
+	kEoB2IntroSeqData30,
+	kEoB2IntroSeqData31,
+	kEoB2IntroSeqData32,
+	kEoB2IntroSeqData33,
+	kEoB2IntroSeqData34,
+	kEoB2IntroSeqData35,
+	kEoB2IntroSeqData36,
+	kEoB2IntroSeqData37,
+	kEoB2IntroSeqData38,
+	kEoB2IntroSeqData39,
+	kEoB2IntroSeqData40,
+	kEoB2IntroSeqData41,
+	kEoB2IntroSeqData42,
+	kEoB2IntroSeqData43,
 	kEoB2IntroShapes00,
- 	kEoB2IntroShapes01,
- 	kEoB2IntroShapes04,
- 	kEoB2IntroShapes07,
+	kEoB2IntroShapes01,
+	kEoB2IntroShapes04,
+	kEoB2IntroShapes07,
 
 	kEoB2FinaleStrings,
 	kEoB2CreditsData,
 	kEoB2FinaleCPSFiles,
 	kEoB2FinaleSeqData00,
- 	kEoB2FinaleSeqData01,
- 	kEoB2FinaleSeqData02,
- 	kEoB2FinaleSeqData03,
- 	kEoB2FinaleSeqData04,
- 	kEoB2FinaleSeqData05,
- 	kEoB2FinaleSeqData06,
- 	kEoB2FinaleSeqData07,
- 	kEoB2FinaleSeqData08,
- 	kEoB2FinaleSeqData09,
- 	kEoB2FinaleSeqData10,
- 	kEoB2FinaleSeqData11,
- 	kEoB2FinaleSeqData12,
- 	kEoB2FinaleSeqData13,
- 	kEoB2FinaleSeqData14,
- 	kEoB2FinaleSeqData15,
- 	kEoB2FinaleSeqData16,
- 	kEoB2FinaleSeqData17,
- 	kEoB2FinaleSeqData18,
- 	kEoB2FinaleSeqData19,
- 	kEoB2FinaleSeqData20,
+	kEoB2FinaleSeqData01,
+	kEoB2FinaleSeqData02,
+	kEoB2FinaleSeqData03,
+	kEoB2FinaleSeqData04,
+	kEoB2FinaleSeqData05,
+	kEoB2FinaleSeqData06,
+	kEoB2FinaleSeqData07,
+	kEoB2FinaleSeqData08,
+	kEoB2FinaleSeqData09,
+	kEoB2FinaleSeqData10,
+	kEoB2FinaleSeqData11,
+	kEoB2FinaleSeqData12,
+	kEoB2FinaleSeqData13,
+	kEoB2FinaleSeqData14,
+	kEoB2FinaleSeqData15,
+	kEoB2FinaleSeqData16,
+	kEoB2FinaleSeqData17,
+	kEoB2FinaleSeqData18,
+	kEoB2FinaleSeqData19,
+	kEoB2FinaleSeqData20,
 	kEoB2FinaleShapes00,
- 	kEoB2FinaleShapes03,
- 	kEoB2FinaleShapes07,
- 	kEoB2FinaleShapes09,
- 	kEoB2FinaleShapes10,
+	kEoB2FinaleShapes03,
+	kEoB2FinaleShapes07,
+	kEoB2FinaleShapes09,
+	kEoB2FinaleShapes10,
 
 	kEoB2NpcShapeData,
 	kEoB2Npc1Strings,
@@ -606,7 +612,7 @@ enum kExtractID {
 	kLoLDscDoor4,
 	kLoLDscDoorX,
 	kLoLDscDoorY,
-	kLoLDscOvlIndex,	
+	kLoLDscOvlIndex,
 
 	kLoLScrollXTop,
 	kLoLScrollYTop,
diff --git a/devtools/create_kyradat/extract.cpp b/devtools/create_kyradat/extract.cpp
index 6a97114..420b661 100644
--- a/devtools/create_kyradat/extract.cpp
+++ b/devtools/create_kyradat/extract.cpp
@@ -394,7 +394,7 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da
 					}
 				}
 			}
-		
+
 		} while (input < c);
 	} else {
 		uint32 copySize = size;
@@ -1084,10 +1084,10 @@ bool extractEoB2ShapeData(PAKFile &out, const ExtractInformation *info, const by
 bool extractEoBNpcData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) {
 	// We use one extraction routine for both EOB 1 and EOB 2 (in spite of the data format differences)
 	// since it is easy enough to generate a common output usable by both engines
-	
+
 	uint8 *buffer = 0;
 	uint32 outsize = 0;
-	
+
 	if (info->game == kEoB1) {
 		uint16 num = size / 243;
 		outsize = num * 111 + 2;
@@ -1120,7 +1120,7 @@ bool extractEoBNpcData(PAKFile &out, const ExtractInformation *info, const byte
 			for (int ii = 0; ii < 27; ii++) {
 				WRITE_BE_UINT16(dst, READ_LE_UINT16(src));
 				src += 2; dst += 2;
-			}			
+			}
 			// skipping more zero space
 			src += 70;
 		}
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index b3c855a..74f8517 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1110,7 +1110,7 @@ const int eob1FloppyNeed[] = {
 	kEoBBaseItemSuffixStringsRings,
 	kEoBBaseItemSuffixStringsPotions,
 	kEoBBaseItemSuffixStringsWands,
-	
+
 	kEoBBaseRipItemStrings,
 	kEoBBaseCursedString,
 	kEoBBaseEnchantedString,
@@ -1159,7 +1159,7 @@ const int eob1FloppyNeed[] = {
 	kEoBBaseNumSpellsWisAdj,
 	kEoBBaseNumSpellsPal,
 	kEoBBaseNumSpellsMage,
-	
+
 	kEoBBaseCharGuiStringsHp,
 	kEoBBaseCharGuiStringsWp1,
 	kEoBBaseCharGuiStringsWr,
@@ -1268,11 +1268,11 @@ const int eob1FloppyNeed[] = {
 	kRpgCommonDscShapeIndex,
 	kRpgCommonDscX,
 	kRpgCommonDscTileIndex,
-	kRpgCommonDscUnk2,	
+	kRpgCommonDscUnk2,
 	kRpgCommonDscDimData1,
 	kRpgCommonDscDimData2,
 	kRpgCommonDscBlockMap,
-	kRpgCommonDscDimMap,	
+	kRpgCommonDscDimMap,
 	kRpgCommonDscBlockIndex,
 
 	kEoBBaseClassModifierFlags,
@@ -1485,90 +1485,96 @@ const int eob2FloppyNeed[] = {
 	kEoBBaseFlightObjSclIndex,
 
 	kEoB2MainMenuStrings,
+
+	kEoB2TransferPortraitFrames,
 	kEoB2TransferConvertTable,
+	kEoB2TransferItemTable,
 	kEoB2TransferExpTable,
+	kEoB2TransferStrings1,
+	kEoB2TransferStrings2,
+	kEoB2TransferLabels,
 
 	kEoB2IntroStrings,
 	kEoB2IntroCPSFiles,
 	kEoB2IntroSeqData00,
- 	kEoB2IntroSeqData01,
- 	kEoB2IntroSeqData02,
- 	kEoB2IntroSeqData03,
- 	kEoB2IntroSeqData04,
- 	kEoB2IntroSeqData05,
- 	kEoB2IntroSeqData06,
- 	kEoB2IntroSeqData07,
- 	kEoB2IntroSeqData08,
- 	kEoB2IntroSeqData09,
- 	kEoB2IntroSeqData10,
- 	kEoB2IntroSeqData11,
- 	kEoB2IntroSeqData12,
- 	kEoB2IntroSeqData13,
- 	kEoB2IntroSeqData14,
- 	kEoB2IntroSeqData15,
- 	kEoB2IntroSeqData16,
- 	kEoB2IntroSeqData17,
- 	kEoB2IntroSeqData18,
- 	kEoB2IntroSeqData19,
- 	kEoB2IntroSeqData20,
- 	kEoB2IntroSeqData21,
- 	kEoB2IntroSeqData22,
- 	kEoB2IntroSeqData23,
- 	kEoB2IntroSeqData24,
- 	kEoB2IntroSeqData25,
- 	kEoB2IntroSeqData26,
- 	kEoB2IntroSeqData27,
- 	kEoB2IntroSeqData28,
- 	kEoB2IntroSeqData29,
- 	kEoB2IntroSeqData30,
- 	kEoB2IntroSeqData31,
- 	kEoB2IntroSeqData32,
- 	kEoB2IntroSeqData33,
- 	kEoB2IntroSeqData34,
- 	kEoB2IntroSeqData35,
- 	kEoB2IntroSeqData36,
- 	kEoB2IntroSeqData37,
- 	kEoB2IntroSeqData38,
- 	kEoB2IntroSeqData39,
- 	kEoB2IntroSeqData40,
- 	kEoB2IntroSeqData41,
- 	kEoB2IntroSeqData42,
- 	kEoB2IntroSeqData43,
+	kEoB2IntroSeqData01,
+	kEoB2IntroSeqData02,
+	kEoB2IntroSeqData03,
+	kEoB2IntroSeqData04,
+	kEoB2IntroSeqData05,
+	kEoB2IntroSeqData06,
+	kEoB2IntroSeqData07,
+	kEoB2IntroSeqData08,
+	kEoB2IntroSeqData09,
+	kEoB2IntroSeqData10,
+	kEoB2IntroSeqData11,
+	kEoB2IntroSeqData12,
+	kEoB2IntroSeqData13,
+	kEoB2IntroSeqData14,
+	kEoB2IntroSeqData15,
+	kEoB2IntroSeqData16,
+	kEoB2IntroSeqData17,
+	kEoB2IntroSeqData18,
+	kEoB2IntroSeqData19,
+	kEoB2IntroSeqData20,
+	kEoB2IntroSeqData21,
+	kEoB2IntroSeqData22,
+	kEoB2IntroSeqData23,
+	kEoB2IntroSeqData24,
+	kEoB2IntroSeqData25,
+	kEoB2IntroSeqData26,
+	kEoB2IntroSeqData27,
+	kEoB2IntroSeqData28,
+	kEoB2IntroSeqData29,
+	kEoB2IntroSeqData30,
+	kEoB2IntroSeqData31,
+	kEoB2IntroSeqData32,
+	kEoB2IntroSeqData33,
+	kEoB2IntroSeqData34,
+	kEoB2IntroSeqData35,
+	kEoB2IntroSeqData36,
+	kEoB2IntroSeqData37,
+	kEoB2IntroSeqData38,
+	kEoB2IntroSeqData39,
+	kEoB2IntroSeqData40,
+	kEoB2IntroSeqData41,
+	kEoB2IntroSeqData42,
+	kEoB2IntroSeqData43,
 
 	kEoB2IntroShapes00,
- 	kEoB2IntroShapes01,
- 	kEoB2IntroShapes04,
- 	kEoB2IntroShapes07,
+	kEoB2IntroShapes01,
+	kEoB2IntroShapes04,
+	kEoB2IntroShapes07,
 
 	kEoB2FinaleStrings,
 	kEoB2CreditsData,
 	kEoB2FinaleCPSFiles,
 	kEoB2FinaleSeqData00,
- 	kEoB2FinaleSeqData01,
- 	kEoB2FinaleSeqData02,
- 	kEoB2FinaleSeqData03,
- 	kEoB2FinaleSeqData04,
- 	kEoB2FinaleSeqData05,
- 	kEoB2FinaleSeqData06,
- 	kEoB2FinaleSeqData07,
- 	kEoB2FinaleSeqData08,
- 	kEoB2FinaleSeqData09,
- 	kEoB2FinaleSeqData10,
- 	kEoB2FinaleSeqData11,
- 	kEoB2FinaleSeqData12,
- 	kEoB2FinaleSeqData13,
- 	kEoB2FinaleSeqData14,
- 	kEoB2FinaleSeqData15,
- 	kEoB2FinaleSeqData16,
- 	kEoB2FinaleSeqData17,
- 	kEoB2FinaleSeqData18,
- 	kEoB2FinaleSeqData19,
- 	kEoB2FinaleSeqData20,
+	kEoB2FinaleSeqData01,
+	kEoB2FinaleSeqData02,
+	kEoB2FinaleSeqData03,
+	kEoB2FinaleSeqData04,
+	kEoB2FinaleSeqData05,
+	kEoB2FinaleSeqData06,
+	kEoB2FinaleSeqData07,
+	kEoB2FinaleSeqData08,
+	kEoB2FinaleSeqData09,
+	kEoB2FinaleSeqData10,
+	kEoB2FinaleSeqData11,
+	kEoB2FinaleSeqData12,
+	kEoB2FinaleSeqData13,
+	kEoB2FinaleSeqData14,
+	kEoB2FinaleSeqData15,
+	kEoB2FinaleSeqData16,
+	kEoB2FinaleSeqData17,
+	kEoB2FinaleSeqData18,
+	kEoB2FinaleSeqData19,
+	kEoB2FinaleSeqData20,
 	kEoB2FinaleShapes00,
- 	kEoB2FinaleShapes03,
- 	kEoB2FinaleShapes07,
- 	kEoB2FinaleShapes09,
- 	kEoB2FinaleShapes10,
+	kEoB2FinaleShapes03,
+	kEoB2FinaleShapes07,
+	kEoB2FinaleShapes09,
+	kEoB2FinaleShapes10,
 
 	kEoB2NpcShapeData,
 	kEoBBaseClassModifierFlags,
@@ -1584,7 +1590,7 @@ const int eob2FloppyNeed[] = {
 	kEoBBaseMonsterCloseAttChkTable2,
 	kEoBBaseMonsterCloseAttDstTable1,
 	kEoBBaseMonsterCloseAttDstTable2,
-	
+
 	kEoBBaseMonsterProximityTable,
 	kEoBBaseFindBlockMonstersTable,
 	kEoBBaseMonsterDirChangeTable,
@@ -1611,7 +1617,7 @@ const int eob2FloppyNeed[] = {
 	kRpgCommonDscDimData1,
 	kRpgCommonDscDimData2,
 	kRpgCommonDscBlockMap,
-	kRpgCommonDscDimMap,	
+	kRpgCommonDscDimMap,
 	kRpgCommonDscBlockIndex,
 
 	-1
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index a606cc4..3ff10c2 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -342,9 +342,9 @@ const ExtractEntrySearchData k1PlacedStringsProvider[] = {
 
 	{ IT_ITA, kPlatformPC, { 0x0000000D, 0x0000040D, { { 0x9C, 0x71, 0x53, 0x35, 0xC3, 0xE8, 0x46, 0xB9, 0xD2, 0xFA, 0x1C, 0x8C, 0xC3, 0xFF, 0xBC, 0x1F } } } }, // floppy
 	{ IT_ITA, kPlatformPC, { 0x00000011, 0x000003B8, { { 0xC8, 0xA6, 0xE4, 0x8A, 0xF7, 0x4C, 0x3F, 0xA6, 0x24, 0x7F, 0xEF, 0xE4, 0x63, 0x8B, 0x72, 0xF3 } } } }, // (fan) CD
-	
+
 	{ ES_ESP, kPlatformPC, { 0x0000000D, 0x00000439, { { 0x57, 0xAE, 0x1C, 0xC1, 0xF5, 0xE8, 0x5B, 0x9E, 0x90, 0x02, 0xB9, 0x8D, 0x86, 0x38, 0xFB, 0xA8 } } } },
-	
+
 	{ RU_RUS, kPlatformPC, { 0x00000009, 0x00000203, { { 0x7D, 0xAE, 0x67, 0x94, 0x8E, 0x73, 0x35, 0xC1, 0x11, 0xB4, 0x55, 0x6E, 0x92, 0x25, 0x39, 0xE4 } } } },
 
 	EXTRACT_END_ENTRY
@@ -563,7 +563,7 @@ const ExtractEntrySearchData k1ThePoisonStringsProvider[] = {
 	{ ES_ESP, kPlatformPC, { 0x00000059, 0x00001DF7, { { 0x16, 0x7B, 0x5F, 0x91, 0x06, 0x5B, 0xFC, 0x9C, 0x88, 0x61, 0xCC, 0x1B, 0x52, 0x4F, 0x91, 0xC5 } } } },
 
 	{ RU_RUS, kPlatformPC, { 0x00000052, 0x0000136F, { { 0xEF, 0xD2, 0xA0, 0x5F, 0xD5, 0xE6, 0x77, 0x96, 0xFA, 0xC5, 0x60, 0x7C, 0xB7, 0xA8, 0x7C, 0x7A } } } },
-	
+
 	{ EN_ANY, kPlatformAmiga, { 0x00000058, 0x00001C24, { { 0xBA, 0x1F, 0xBD, 0x5C, 0x85, 0x3D, 0x3C, 0x92, 0xD1, 0x13, 0xF3, 0x40, 0x2E, 0xBB, 0x1C, 0xE2 } } } },
 	{ DE_DEU, kPlatformAmiga, { 0x00000073, 0x00002690, { { 0x44, 0xAE, 0xC9, 0xFD, 0x9F, 0x8E, 0x1B, 0xDD, 0x3F, 0xE4, 0x4D, 0x4B, 0x5A, 0x13, 0xE5, 0x99 } } } },
 
@@ -1222,7 +1222,7 @@ const ExtractEntrySearchData k2IngamePakFilesProvider[] = {
 const ExtractEntrySearchData k2IngameSfxFilesProvider[] = {
 	{ UNK_LANG, kPlatformPC, { 0x000006F1, 0x0001545E, { { 0xD3, 0x8A, 0xA1, 0xD4, 0x83, 0x77, 0x96, 0x6D, 0x87, 0xB1, 0x71, 0x8F, 0x38, 0x6A, 0x34, 0xDC } } } },
 	{ UNK_LANG, kPlatformFMTowns, { 0x00000967, 0x0002101A, { { 0x09, 0xC7, 0xB7, 0x2A, 0x76, 0xF1, 0x4B, 0x87, 0xC5, 0x83, 0xFF, 0xF3, 0xDB, 0x3C, 0x66, 0x60 } } } },
-	{ UNK_LANG, kPlatformPC98, 	{ 0x000006F1, 0x0001545E, { { 0xD3, 0x8A, 0xA1, 0xD4, 0x83, 0x77, 0x96, 0x6D, 0x87, 0xB1, 0x71, 0x8F, 0x38, 0x6A, 0x34, 0xDC } } } },
+	{ UNK_LANG, kPlatformPC98,	{ 0x000006F1, 0x0001545E, { { 0xD3, 0x8A, 0xA1, 0xD4, 0x83, 0x77, 0x96, 0x6D, 0x87, 0xB1, 0x71, 0x8F, 0x38, 0x6A, 0x34, 0xDC } } } },
 
 	EXTRACT_END_ENTRY
 };
@@ -1392,7 +1392,7 @@ const ExtractEntrySearchData kEoBBaseChargenClassMinStatsProvider[] = {
 };
 
 const ExtractEntrySearchData kEoBBaseChargenRaceMinStatsProvider[] = {
-	{ UNK_LANG, kPlatformUnknown, { 0x00000048, 0x000000B2, { { 0x08, 0xF0, 0x8F, 0x22, 0x9D, 0xD8, 0xBE, 0x52, 0x70, 0x7C, 0xCA, 0x8D, 0xB2, 0xF5, 0xC6, 0xB8 } } } },	
+	{ UNK_LANG, kPlatformUnknown, { 0x00000048, 0x000000B2, { { 0x08, 0xF0, 0x8F, 0x22, 0x9D, 0xD8, 0xBE, 0x52, 0x70, 0x7C, 0xCA, 0x8D, 0xB2, 0xF5, 0xC6, 0xB8 } } } },
 	EXTRACT_END_ENTRY
 };
 
@@ -1627,7 +1627,7 @@ const ExtractEntrySearchData kEoBBaseCancelStringsProvider[] = {
 };
 
 const ExtractEntrySearchData kEoBBaseAbortStringsProvider[] = {
-	{ EN_ANY, kPlatformUnknown, { 0x00000006, 0x00000178, { { 0xDD, 0xEC, 0x68, 0x6D, 0x2E, 0x10, 0x34, 0x94, 0x46, 0x25, 0xF9, 0xAB, 0x29, 0x27, 0x32, 0xA8 } } } }, 
+	{ EN_ANY, kPlatformUnknown, { 0x00000006, 0x00000178, { { 0xDD, 0xEC, 0x68, 0x6D, 0x2E, 0x10, 0x34, 0x94, 0x46, 0x25, 0xF9, 0xAB, 0x29, 0x27, 0x32, 0xA8 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000006, 0x00000145, { { 0x22, 0x45, 0x35, 0xC6, 0x28, 0x00, 0x22, 0xAA, 0xD1, 0x15, 0x48, 0xE6, 0xE5, 0x62, 0x73, 0x37 } } } },
 	EXTRACT_END_ENTRY
 };
@@ -1823,7 +1823,7 @@ const ExtractEntrySearchData kEoBBaseNumSpellsMageProvider[] = {
 };
 
 const ExtractEntrySearchData kEoBBaseCharGuiStringsHpProvider[] = {
-	{ EN_ANY, kPlatformUnknown, { 0x0000000F, 0x00000352, { { 0x9C, 0x13, 0x3D, 0x2A, 0x68, 0x11, 0x81, 0xA4, 0x77, 0x54, 0x47, 0x43, 0xA1, 0xDA, 0x55, 0x50 } } } }, 
+	{ EN_ANY, kPlatformUnknown, { 0x0000000F, 0x00000352, { { 0x9C, 0x13, 0x3D, 0x2A, 0x68, 0x11, 0x81, 0xA4, 0x77, 0x54, 0x47, 0x43, 0xA1, 0xDA, 0x55, 0x50 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000000E, 0x000002AC, { { 0xBB, 0xD5, 0x36, 0xB2, 0x8A, 0x60, 0x78, 0x04, 0x46, 0x2D, 0x35, 0x59, 0x3E, 0x42, 0xB9, 0x83 } } } },	// EoB 1
 	{ DE_DEU, kPlatformUnknown, { 0x0000000E, 0x000002B8, { { 0x77, 0x76, 0xA0, 0x38, 0xE9, 0xB6, 0x0C, 0x43, 0xFE, 0x5A, 0x51, 0xC7, 0x1B, 0x59, 0xD3, 0x63 } } } },	// EoB 2
 	EXTRACT_END_ENTRY
@@ -1842,7 +1842,7 @@ const ExtractEntrySearchData kEoBBaseCharGuiStringsWp2Provider[] = {
 };
 
 const ExtractEntrySearchData kEoBBaseCharGuiStringsWrProvider[] = {
-	{ EN_ANY, kPlatformUnknown, { 0x00000014, 0x00000477, { { 0xAA, 0x26, 0xD5, 0xFD, 0xE6, 0x16, 0x53, 0x19, 0x39, 0x46, 0xEB, 0xCD, 0x88, 0xEC, 0x5E, 0xCB } } } }, 
+	{ EN_ANY, kPlatformUnknown, { 0x00000014, 0x00000477, { { 0xAA, 0x26, 0xD5, 0xFD, 0xE6, 0x16, 0x53, 0x19, 0x39, 0x46, 0xEB, 0xCD, 0x88, 0xEC, 0x5E, 0xCB } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000015, 0x000004A4, { { 0x53, 0x54, 0x37, 0x35, 0x27, 0x1F, 0xB9, 0x09, 0x9C, 0xE9, 0x5E, 0x11, 0xBD, 0x8F, 0x15, 0xAE } } } },	// EoB 1
 	{ DE_DEU, kPlatformUnknown, { 0x00000011, 0x00000402, { { 0xE0, 0x92, 0xF4, 0x49, 0xB7, 0x74, 0xBB, 0xEB, 0x90, 0x0D, 0x75, 0x65, 0xBB, 0xF6, 0xB6, 0xE9 } } } },	// EoB 2
 	EXTRACT_END_ENTRY
@@ -1861,7 +1861,7 @@ const ExtractEntrySearchData kEoBBaseCharGuiStringsSt2Provider[] = {
 };
 
 const ExtractEntrySearchData kEoBBaseCharGuiStringsInProvider[] = {
-	{ EN_ANY, kPlatformUnknown, { 0x00000023, 0x000008CB, { { 0xF0, 0xE9, 0xF1, 0x05, 0x47, 0x3A, 0x5D, 0xCA, 0x9F, 0x75, 0x9D, 0x51, 0x9E, 0xEC, 0x9B, 0x67 } } } }, 
+	{ EN_ANY, kPlatformUnknown, { 0x00000023, 0x000008CB, { { 0xF0, 0xE9, 0xF1, 0x05, 0x47, 0x3A, 0x5D, 0xCA, 0x9F, 0x75, 0x9D, 0x51, 0x9E, 0xEC, 0x9B, 0x67 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x00000020, 0x00000810, { { 0xF5, 0x39, 0x1E, 0x0E, 0x65, 0xEF, 0x09, 0xF2, 0x8D, 0x90, 0xC4, 0xF6, 0x8A, 0xED, 0xAD, 0xDF } } } },	// EoB 1
 	{ DE_DEU, kPlatformUnknown, { 0x00000023, 0x00000940, { { 0xAB, 0xF6, 0xE4, 0xD4, 0x07, 0x07, 0xDA, 0x92, 0x71, 0xE2, 0x73, 0x1F, 0x06, 0xE3, 0x12, 0xEB } } } },	// EoB 2
 	EXTRACT_END_ENTRY
@@ -2649,16 +2649,44 @@ const ExtractEntrySearchData kEoB2MainMenuStringsProvider[] = {
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEoB2TransferPortraitFramesProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x00000040, 0x00000B25, { { 0x13, 0x25, 0x69, 0xC6, 0xE4, 0x9D, 0x35, 0x11, 0xAB, 0xE2, 0xC1, 0xEF, 0x21, 0x8B, 0xB8, 0x28 } } } },
+	EXTRACT_END_ENTRY
+};
+
 const ExtractEntrySearchData kEoB2TransferConvertTableProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000031, 0x000004BC, { { 0x96, 0x53, 0xA2, 0xF1, 0x26, 0xFE, 0x1B, 0x5E, 0xDF, 0x62, 0x2C, 0x8C, 0xBD, 0x62, 0x5A, 0xF9 } } } },
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEoB2TransferItemTableProvider[] = {
+	{ UNK_LANG, kPlatformUnknown, { 0x0000003C, 0x00000025, { { 0xD0, 0xA4, 0xB3, 0x7D, 0x74, 0x4D, 0x16, 0x43, 0x56, 0x07, 0x84, 0xAA, 0x96, 0xBD, 0x82, 0x25 } } } },
+	EXTRACT_END_ENTRY
+};
+
 const ExtractEntrySearchData kEoB2TransferExpTableProvider[] = {
 	{ UNK_LANG, kPlatformUnknown, { 0x00000018, 0x0000076B, { { 0x91, 0x65, 0x5B, 0x8D, 0xE8, 0x5B, 0x28, 0x32, 0x4D, 0x7A, 0x57, 0x8E, 0x18, 0x5B, 0x1A, 0xE9 } } } },
 	EXTRACT_END_ENTRY
 };
 
+const ExtractEntrySearchData kEoB2TransferStrings1Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x00000010, 0x000003D3, { { 0x31, 0xE4, 0x65, 0x69, 0x0A, 0xA1, 0x1D, 0xD1, 0xFE, 0xF8, 0x5C, 0x29, 0xB1, 0x46, 0xBD, 0xBE } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000010, 0x000003E2, { { 0xF0, 0x10, 0xF8, 0x9F, 0x05, 0x1E, 0x31, 0x33, 0x4E, 0xC8, 0x49, 0xBC, 0x9E, 0xAD, 0xD4, 0x99 } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2TransferStrings2Provider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000006A, 0x00002681, { { 0x12, 0x4D, 0x29, 0x9D, 0xD3, 0xFC, 0x39, 0x22, 0x73, 0x1E, 0x5C, 0xAF, 0x1F, 0xD1, 0xAA, 0x87 } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000057, 0x00001F8E, { { 0x85, 0xD8, 0x39, 0x1E, 0x6D, 0x97, 0xBD, 0x0E, 0xDD, 0xCF, 0x19, 0x47, 0x31, 0xDC, 0x7C, 0x1A } } } },
+	EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2TransferLabelsProvider[] = {
+	{ EN_ANY, kPlatformUnknown, { 0x0000000A, 0x00000240, { { 0x2A, 0x8B, 0x54, 0x99, 0x94, 0x35, 0x2B, 0xAB, 0x7F, 0x7F, 0x98, 0xA3, 0xFD, 0x57, 0x20, 0xDE } } } },
+	{ DE_DEU, kPlatformUnknown, { 0x00000009, 0x000001DF, { { 0x47, 0x6B, 0xBA, 0xCD, 0x99, 0x74, 0xCA, 0x3C, 0xAA, 0xC6, 0xB4, 0x50, 0x38, 0x90, 0x25, 0xB8 } } } },
+	EXTRACT_END_ENTRY
+};
+
 const ExtractEntrySearchData kEoB2IntroStringsProvider[] = {
 	{ EN_ANY, kPlatformUnknown, { 0x00000321, 0x0000DBC3, { { 0x11, 0x9B, 0x54, 0xB3, 0x34, 0xF0, 0xB5, 0xE1, 0xFA, 0x6A, 0x31, 0x02, 0x59, 0x29, 0xCA, 0x94 } } } },
 	{ DE_DEU, kPlatformUnknown, { 0x0000038E, 0x0001119C, { { 0x92, 0x63, 0x18, 0xDD, 0x9F, 0x62, 0xF5, 0xBC, 0x3D, 0x93, 0xDC, 0x6E, 0xE5, 0xBE, 0x8C, 0x0B } } } },
@@ -3846,8 +3874,8 @@ const ExtractEntry extractProviders[] = {
 	{ k3SfxMap, k3SfxMapProvider },
 	{ k3ItemAnimData, k3ItemAnimDataProvider },
 	{ k3ItemMagicTable, k3ItemMagicTableProvider },
-	{ k3ItemStringMap, k3ItemStringMapProvider },	
-	
+	{ k3ItemStringMap, k3ItemStringMapProvider },
+
 	{ kEoBBaseChargenStrings1, kEoBBaseChargenStrings1Provider },
 	{ kEoBBaseChargenStrings2, kEoBBaseChargenStrings2Provider },
 	{ kEoBBaseChargenStartLevels, kEoBBaseChargenStartLevelsProvider },
@@ -3867,7 +3895,7 @@ const ExtractEntry extractProviders[] = {
 	{ kEoBBaseSaveThrwLvlIndex, kEoBBaseSaveThrwLvlIndexProvider },
 	{ kEoBBaseSaveThrwModDiv, kEoBBaseSaveThrwModDivProvider },
 	{ kEoBBaseSaveThrwModExt, kEoBBaseSaveThrwModExtProvider },
-	
+
 	{ kEoBBasePryDoorStrings, kEoBBasePryDoorStringsProvider },
 	{ kEoBBaseWarningStrings, kEoBBaseWarningStringsProvider },
 
@@ -3923,7 +3951,7 @@ const ExtractEntry extractProviders[] = {
 	{ kEoBBaseMenuStringsSpec, kEoBBaseMenuStringsSpecProvider },
 	{ kEoBBaseMenuStringsSpellNo, kEoBBaseMenuStringsSpellNoProvider },
 	{ kEoBBaseMenuYesNoStrings, kEoBBaseMenuYesNoStringsProvider },
-	
+
 	{ kEoBBaseSpellLevelsMage, kEoBBaseSpellLevelsMageProvider },
 	{ kEoBBaseSpellLevelsCleric, kEoBBaseSpellLevelsClericProvider },
 	{ kEoBBaseNumSpellsCleric, kEoBBaseNumSpellsClericProvider },
@@ -3980,7 +4008,7 @@ const ExtractEntry extractProviders[] = {
 	{ kEoBBaseDscTelptrShpCoords, kEoBBaseDscTelptrShpCoordsProvider },
 
 	{ kEoBBasePortalSeqData, kEoBBasePortalSeqDataProvider },
-	{ kEoBBaseManDef, kEoBBaseManDefProvider },	
+	{ kEoBBaseManDef, kEoBBaseManDefProvider },
 	{ kEoBBaseManWord, kEoBBaseManWordProvider },
 	{ kEoBBaseManPrompt, kEoBBaseManPromptProvider },
 
@@ -4018,7 +4046,7 @@ const ExtractEntry extractProviders[] = {
 	{ kEoBBaseExpObjectTbl2, kEoBBaseExpObjectTbl2Provider },
 	{ kEoBBaseExpObjectTbl3, kEoBBaseExpObjectTbl3Provider },
 	{ kEoBBaseExpObjectY, kEoBBaseExpObjectYProvider },
-	
+
 	{ kEoBBaseSparkDefSteps, kEoBBaseSparkDefStepsProvider },
 	{ kEoBBaseSparkDefSubSteps, kEoBBaseSparkDefSubStepsProvider },
 	{ kEoBBaseSparkDefShift, kEoBBaseSparkDefShiftProvider },
@@ -4039,7 +4067,7 @@ const ExtractEntry extractProviders[] = {
 	{ kEoBBaseConeOfColdDest2, kEoBBaseConeOfColdDest2Provider },
 	{ kEoBBaseConeOfColdDest3, kEoBBaseConeOfColdDest3Provider },
 	{ kEoBBaseConeOfColdDest4, kEoBBaseConeOfColdDest4Provider },
-	{ kEoBBaseConeOfColdGfxTbl, kEoBBaseConeOfColdGfxTblProvider },	
+	{ kEoBBaseConeOfColdGfxTbl, kEoBBaseConeOfColdGfxTblProvider },
 
 	{ kEoB1MainMenuStrings, kEoB1MainMenuStringsProvider },
 	{ kEoB1BonusStrings, kEoB1BonusStringsProvider },
@@ -4093,89 +4121,95 @@ const ExtractEntry extractProviders[] = {
 	{ kEoB1Npc7Strings, kEoB1Npc7StringsProvider },
 
 	{ kEoB2MainMenuStrings, kEoB2MainMenuStringsProvider },
+
+	{ kEoB2TransferPortraitFrames, kEoB2TransferPortraitFramesProvider },
 	{ kEoB2TransferConvertTable, kEoB2TransferConvertTableProvider },
+	{ kEoB2TransferItemTable, kEoB2TransferItemTableProvider },
 	{ kEoB2TransferExpTable, kEoB2TransferExpTableProvider },
+	{ kEoB2TransferStrings1, kEoB2TransferStrings1Provider },
+	{ kEoB2TransferStrings2, kEoB2TransferStrings2Provider },
+	{ kEoB2TransferLabels, kEoB2TransferLabelsProvider },
 
 	{ kEoB2IntroStrings, kEoB2IntroStringsProvider },
 	{ kEoB2IntroCPSFiles, kEoB2IntroCPSFilesProvider },
 	{ kEoB2IntroSeqData00, kEoB2IntroSeqData00Provider },
- 	{ kEoB2IntroSeqData01, kEoB2IntroSeqData01Provider },
- 	{ kEoB2IntroSeqData02, kEoB2IntroSeqData02Provider },
- 	{ kEoB2IntroSeqData03, kEoB2IntroSeqData03Provider },
- 	{ kEoB2IntroSeqData04, kEoB2IntroSeqData04Provider },
- 	{ kEoB2IntroSeqData05, kEoB2IntroSeqData05Provider },
- 	{ kEoB2IntroSeqData06, kEoB2IntroSeqData06Provider },
- 	{ kEoB2IntroSeqData07, kEoB2IntroSeqData07Provider },
- 	{ kEoB2IntroSeqData08, kEoB2IntroSeqData08Provider },
- 	{ kEoB2IntroSeqData09, kEoB2IntroSeqData09Provider },
- 	{ kEoB2IntroSeqData10, kEoB2IntroSeqData10Provider },
- 	{ kEoB2IntroSeqData11, kEoB2IntroSeqData11Provider },
- 	{ kEoB2IntroSeqData12, kEoB2IntroSeqData12Provider },
- 	{ kEoB2IntroSeqData13, kEoB2IntroSeqData13Provider },
- 	{ kEoB2IntroSeqData14, kEoB2IntroSeqData14Provider },
- 	{ kEoB2IntroSeqData15, kEoB2IntroSeqData15Provider },
- 	{ kEoB2IntroSeqData16, kEoB2IntroSeqData16Provider },
- 	{ kEoB2IntroSeqData17, kEoB2IntroSeqData17Provider },
- 	{ kEoB2IntroSeqData18, kEoB2IntroSeqData18Provider },
- 	{ kEoB2IntroSeqData19, kEoB2IntroSeqData19Provider },
- 	{ kEoB2IntroSeqData20, kEoB2IntroSeqData20Provider },
- 	{ kEoB2IntroSeqData21, kEoB2IntroSeqData21Provider },
- 	{ kEoB2IntroSeqData22, kEoB2IntroSeqData22Provider },
- 	{ kEoB2IntroSeqData23, kEoB2IntroSeqData23Provider },
- 	{ kEoB2IntroSeqData24, kEoB2IntroSeqData24Provider },
- 	{ kEoB2IntroSeqData25, kEoB2IntroSeqData25Provider },
- 	{ kEoB2IntroSeqData26, kEoB2IntroSeqData26Provider },
- 	{ kEoB2IntroSeqData27, kEoB2IntroSeqData27Provider },
- 	{ kEoB2IntroSeqData28, kEoB2IntroSeqData28Provider },
- 	{ kEoB2IntroSeqData29, kEoB2IntroSeqData29Provider },
- 	{ kEoB2IntroSeqData30, kEoB2IntroSeqData30Provider },
- 	{ kEoB2IntroSeqData31, kEoB2IntroSeqData31Provider },
- 	{ kEoB2IntroSeqData32, kEoB2IntroSeqData32Provider },
- 	{ kEoB2IntroSeqData33, kEoB2IntroSeqData33Provider },
- 	{ kEoB2IntroSeqData34, kEoB2IntroSeqData34Provider },
- 	{ kEoB2IntroSeqData35, kEoB2IntroSeqData35Provider },
- 	{ kEoB2IntroSeqData36, kEoB2IntroSeqData36Provider },
- 	{ kEoB2IntroSeqData37, kEoB2IntroSeqData37Provider },
- 	{ kEoB2IntroSeqData38, kEoB2IntroSeqData38Provider },
- 	{ kEoB2IntroSeqData39, kEoB2IntroSeqData39Provider },
- 	{ kEoB2IntroSeqData40, kEoB2IntroSeqData40Provider },
- 	{ kEoB2IntroSeqData41, kEoB2IntroSeqData41Provider },
- 	{ kEoB2IntroSeqData42, kEoB2IntroSeqData42Provider },
- 	{ kEoB2IntroSeqData43, kEoB2IntroSeqData43Provider },
+	{ kEoB2IntroSeqData01, kEoB2IntroSeqData01Provider },
+	{ kEoB2IntroSeqData02, kEoB2IntroSeqData02Provider },
+	{ kEoB2IntroSeqData03, kEoB2IntroSeqData03Provider },
+	{ kEoB2IntroSeqData04, kEoB2IntroSeqData04Provider },
+	{ kEoB2IntroSeqData05, kEoB2IntroSeqData05Provider },
+	{ kEoB2IntroSeqData06, kEoB2IntroSeqData06Provider },
+	{ kEoB2IntroSeqData07, kEoB2IntroSeqData07Provider },
+	{ kEoB2IntroSeqData08, kEoB2IntroSeqData08Provider },
+	{ kEoB2IntroSeqData09, kEoB2IntroSeqData09Provider },
+	{ kEoB2IntroSeqData10, kEoB2IntroSeqData10Provider },
+	{ kEoB2IntroSeqData11, kEoB2IntroSeqData11Provider },
+	{ kEoB2IntroSeqData12, kEoB2IntroSeqData12Provider },
+	{ kEoB2IntroSeqData13, kEoB2IntroSeqData13Provider },
+	{ kEoB2IntroSeqData14, kEoB2IntroSeqData14Provider },
+	{ kEoB2IntroSeqData15, kEoB2IntroSeqData15Provider },
+	{ kEoB2IntroSeqData16, kEoB2IntroSeqData16Provider },
+	{ kEoB2IntroSeqData17, kEoB2IntroSeqData17Provider },
+	{ kEoB2IntroSeqData18, kEoB2IntroSeqData18Provider },
+	{ kEoB2IntroSeqData19, kEoB2IntroSeqData19Provider },
+	{ kEoB2IntroSeqData20, kEoB2IntroSeqData20Provider },
+	{ kEoB2IntroSeqData21, kEoB2IntroSeqData21Provider },
+	{ kEoB2IntroSeqData22, kEoB2IntroSeqData22Provider },
+	{ kEoB2IntroSeqData23, kEoB2IntroSeqData23Provider },
+	{ kEoB2IntroSeqData24, kEoB2IntroSeqData24Provider },
+	{ kEoB2IntroSeqData25, kEoB2IntroSeqData25Provider },
+	{ kEoB2IntroSeqData26, kEoB2IntroSeqData26Provider },
+	{ kEoB2IntroSeqData27, kEoB2IntroSeqData27Provider },
+	{ kEoB2IntroSeqData28, kEoB2IntroSeqData28Provider },
+	{ kEoB2IntroSeqData29, kEoB2IntroSeqData29Provider },
+	{ kEoB2IntroSeqData30, kEoB2IntroSeqData30Provider },
+	{ kEoB2IntroSeqData31, kEoB2IntroSeqData31Provider },
+	{ kEoB2IntroSeqData32, kEoB2IntroSeqData32Provider },
+	{ kEoB2IntroSeqData33, kEoB2IntroSeqData33Provider },
+	{ kEoB2IntroSeqData34, kEoB2IntroSeqData34Provider },
+	{ kEoB2IntroSeqData35, kEoB2IntroSeqData35Provider },
+	{ kEoB2IntroSeqData36, kEoB2IntroSeqData36Provider },
+	{ kEoB2IntroSeqData37, kEoB2IntroSeqData37Provider },
+	{ kEoB2IntroSeqData38, kEoB2IntroSeqData38Provider },
+	{ kEoB2IntroSeqData39, kEoB2IntroSeqData39Provider },
+	{ kEoB2IntroSeqData40, kEoB2IntroSeqData40Provider },
+	{ kEoB2IntroSeqData41, kEoB2IntroSeqData41Provider },
+	{ kEoB2IntroSeqData42, kEoB2IntroSeqData42Provider },
+	{ kEoB2IntroSeqData43, kEoB2IntroSeqData43Provider },
 	{ kEoB2IntroShapes00, kEoB2IntroShapes00Provider },
- 	{ kEoB2IntroShapes01, kEoB2IntroShapes01Provider },
- 	{ kEoB2IntroShapes04, kEoB2IntroShapes04Provider },
- 	{ kEoB2IntroShapes07, kEoB2IntroShapes07Provider },
+	{ kEoB2IntroShapes01, kEoB2IntroShapes01Provider },
+	{ kEoB2IntroShapes04, kEoB2IntroShapes04Provider },
+	{ kEoB2IntroShapes07, kEoB2IntroShapes07Provider },
 
 	{ kEoB2FinaleStrings, kEoB2FinaleStringsProvider },
 	{ kEoB2CreditsData, kEoB2CreditsDataProvider },
 	{ kEoB2FinaleCPSFiles, kEoB2FinaleCPSFilesProvider },
 	{ kEoB2FinaleSeqData00, kEoB2FinaleSeqData00Provider },
- 	{ kEoB2FinaleSeqData01, kEoB2FinaleSeqData01Provider },
- 	{ kEoB2FinaleSeqData02, kEoB2FinaleSeqData02Provider },
- 	{ kEoB2FinaleSeqData03, kEoB2FinaleSeqData03Provider },
- 	{ kEoB2FinaleSeqData04, kEoB2FinaleSeqData04Provider },
- 	{ kEoB2FinaleSeqData05, kEoB2FinaleSeqData05Provider },
- 	{ kEoB2FinaleSeqData06, kEoB2FinaleSeqData06Provider },
- 	{ kEoB2FinaleSeqData07, kEoB2FinaleSeqData07Provider },
- 	{ kEoB2FinaleSeqData08, kEoB2FinaleSeqData08Provider },
- 	{ kEoB2FinaleSeqData09, kEoB2FinaleSeqData09Provider },
- 	{ kEoB2FinaleSeqData10, kEoB2FinaleSeqData10Provider },
- 	{ kEoB2FinaleSeqData11, kEoB2FinaleSeqData11Provider },
- 	{ kEoB2FinaleSeqData12, kEoB2FinaleSeqData12Provider },
- 	{ kEoB2FinaleSeqData13, kEoB2FinaleSeqData13Provider },
- 	{ kEoB2FinaleSeqData14, kEoB2FinaleSeqData14Provider },
- 	{ kEoB2FinaleSeqData15, kEoB2FinaleSeqData15Provider },
- 	{ kEoB2FinaleSeqData16, kEoB2FinaleSeqData16Provider },
- 	{ kEoB2FinaleSeqData17, kEoB2FinaleSeqData17Provider },
- 	{ kEoB2FinaleSeqData18, kEoB2FinaleSeqData18Provider },
- 	{ kEoB2FinaleSeqData19, kEoB2FinaleSeqData19Provider },
- 	{ kEoB2FinaleSeqData20, kEoB2FinaleSeqData20Provider },
+	{ kEoB2FinaleSeqData01, kEoB2FinaleSeqData01Provider },
+	{ kEoB2FinaleSeqData02, kEoB2FinaleSeqData02Provider },
+	{ kEoB2FinaleSeqData03, kEoB2FinaleSeqData03Provider },
+	{ kEoB2FinaleSeqData04, kEoB2FinaleSeqData04Provider },
+	{ kEoB2FinaleSeqData05, kEoB2FinaleSeqData05Provider },
+	{ kEoB2FinaleSeqData06, kEoB2FinaleSeqData06Provider },
+	{ kEoB2FinaleSeqData07, kEoB2FinaleSeqData07Provider },
+	{ kEoB2FinaleSeqData08, kEoB2FinaleSeqData08Provider },
+	{ kEoB2FinaleSeqData09, kEoB2FinaleSeqData09Provider },
+	{ kEoB2FinaleSeqData10, kEoB2FinaleSeqData10Provider },
+	{ kEoB2FinaleSeqData11, kEoB2FinaleSeqData11Provider },
+	{ kEoB2FinaleSeqData12, kEoB2FinaleSeqData12Provider },
+	{ kEoB2FinaleSeqData13, kEoB2FinaleSeqData13Provider },
+	{ kEoB2FinaleSeqData14, kEoB2FinaleSeqData14Provider },
+	{ kEoB2FinaleSeqData15, kEoB2FinaleSeqData15Provider },
+	{ kEoB2FinaleSeqData16, kEoB2FinaleSeqData16Provider },
+	{ kEoB2FinaleSeqData17, kEoB2FinaleSeqData17Provider },
+	{ kEoB2FinaleSeqData18, kEoB2FinaleSeqData18Provider },
+	{ kEoB2FinaleSeqData19, kEoB2FinaleSeqData19Provider },
+	{ kEoB2FinaleSeqData20, kEoB2FinaleSeqData20Provider },
 	{ kEoB2FinaleShapes00, kEoB2FinaleShapes00Provider },
- 	{ kEoB2FinaleShapes03, kEoB2FinaleShapes03Provider },
- 	{ kEoB2FinaleShapes07, kEoB2FinaleShapes07Provider },
- 	{ kEoB2FinaleShapes09, kEoB2FinaleShapes09Provider },
- 	{ kEoB2FinaleShapes10, kEoB2FinaleShapes10Provider },
+	{ kEoB2FinaleShapes03, kEoB2FinaleShapes03Provider },
+	{ kEoB2FinaleShapes07, kEoB2FinaleShapes07Provider },
+	{ kEoB2FinaleShapes09, kEoB2FinaleShapes09Provider },
+	{ kEoB2FinaleShapes10, kEoB2FinaleShapes10Provider },
 
 	{ kEoB2NpcShapeData, kEoB2NpcShapeDataProvider },
 	{ kEoBBaseClassModifierFlags, kEoBBaseClassModifierFlagsProvider },
@@ -4193,7 +4227,7 @@ const ExtractEntry extractProviders[] = {
 	{ kEoBBaseMonsterCloseAttChkTable2, kEoBBaseMonsterCloseAttChkTable2Provider },
 	{ kEoBBaseMonsterCloseAttDstTable1, kEoBBaseMonsterCloseAttDstTable1Provider },
 	{ kEoBBaseMonsterCloseAttDstTable2, kEoBBaseMonsterCloseAttDstTable2Provider },
-	
+
 	{ kEoBBaseMonsterProximityTable, kEoBBaseMonsterProximityTableProvider },
 	{ kEoBBaseFindBlockMonstersTable, kEoBBaseFindBlockMonstersTableProvider },
 	{ kEoBBaseMonsterDirChangeTable, kEoBBaseMonsterDirChangeTableProvider },
@@ -4212,7 +4246,7 @@ const ExtractEntry extractProviders[] = {
 	{ kEoB2WallOfForceNumW, kEoB2WallOfForceNumWProvider },
 	{ kEoB2WallOfForceNumH, kEoB2WallOfForceNumHProvider },
 	{ kEoB2WallOfForceShpId, kEoB2WallOfForceShpIdProvider },
-	
+
 	{ kLoLIngamePakFiles, kLoLIngamePakFilesProvider },
 	{ kLoLCharacterDefs, kLoLCharacterDefsProvider },
 	{ kLoLIngameSfxFiles, kLoLIngameSfxFilesProvider },
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index 704c8ad..56c7184 100644
Binary files a/dists/engine-data/kyra.dat and b/dists/engine-data/kyra.dat differ
diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index b326f92..16911a3 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -69,7 +69,7 @@ private:
 	void finish();
 
 	uint8 **_chargenMagicShapes;
-	uint8 **_chargenButtonLabels;
+	uint8 *_chargenButtonLabels[17];
 	int _activeBox;
 	int _magicShapesBox;
 	int _updateBoxShapesIndex;
@@ -115,7 +115,7 @@ private:
 };
 
 CharacterGenerator::CharacterGenerator(EoBCoreEngine *vm, Screen_EoB *screen) : _vm(vm), _screen(screen),
-	_characters(0), _faceShapes(0), _chargenMagicShapes(0), _chargenButtonLabels(0), _chargenMagicShapeTimer(0),
+	_characters(0), _faceShapes(0), _chargenMagicShapes(0), _chargenMagicShapeTimer(0),
 	_updateBoxShapesIndex(0), _lastUpdateBoxShapesIndex(0), _magicShapesBox(6), _activeBox(0) {
 
 	_chargenStatStrings = _vm->_chargenStatStrings;
@@ -145,11 +145,8 @@ CharacterGenerator::~CharacterGenerator() {
 		delete[] _chargenMagicShapes;
 	}
 
-	if (_chargenButtonLabels) {
-		for (int i = 0; i < 17; i++)
-			delete[] _chargenButtonLabels[i];
-		delete[] _chargenButtonLabels;
-	}
+	for (int i = 0; i < 17; i++)
+		delete[] _chargenButtonLabels[i];
 }
 
 bool CharacterGenerator::start(EoBCharacter *characters, uint8 ***faceShapes) {
@@ -261,7 +258,6 @@ void CharacterGenerator::init() {
 	for (int i = 0; i < 10; i++)
 		_chargenMagicShapes[i] = _screen->encodeShape(i << 2, 0, 4, 32, true);
 
-	_chargenButtonLabels = new uint8*[17];
 	for (int i = 0; i < 17; i++) {
 		const CreatePartyModButton *c = &_chargenModButtons[i];
 		_chargenButtonLabels[i] = c->labelW? _screen->encodeShape(c->encodeLabelX, c->encodeLabelY, c->labelW, c->labelH, true) : 0;
@@ -1322,12 +1318,8 @@ void CharacterGenerator::finish() {
 		_chargenMagicShapes = 0;
 	}
 
-	if (_chargenButtonLabels) {
-		for (int i = 0; i < 17; i++)
-			delete[] _chargenButtonLabels[i];
-		delete[] _chargenButtonLabels;
-		_chargenButtonLabels = 0;
-	}
+	for (int i = 0; i < 17; i++)
+		delete[] _chargenButtonLabels[i];
 }
 
 const EoBChargenButtonDef CharacterGenerator::_chargenButtonDefs[] = {
@@ -1444,17 +1436,45 @@ private:
 	bool selectAndLoadTransferFile();
 	Common::String transferFileDialogue();
 
+	int selectCharactersMenu();
+	void drawCharPortraitWithStats(int charIndex, bool enabled);
+	void updateHighlight(int index);
+
 	void convertStats();
+	void convertInventory();
+	Item convertItem(Item eob1Item);
+	void giveKhelbensCoin();
 
 	EoBCoreEngine *_vm;
 	Screen_EoB *_screen;
+
+	int _highlight;
+	EoBItem *_oldItems;
+
+	const uint16 *_portraitFrames;
+	const uint8 *_convertTable;
+	const uint8 *_itemTable;
+	const uint32 *_expTable;
+	const char *const *_strings1;
+	const char *const *_strings2;
+	const char *const *_labels;
 };
 
 TransferPartyWiz::TransferPartyWiz(EoBCoreEngine *vm, Screen_EoB *screen) : _vm(vm), _screen(screen) {
+	int temp;
+	_portraitFrames = _vm->staticres()->loadRawDataBe16(kEoB2TransferPortraitFrames, temp);
+	_convertTable = _vm->staticres()->loadRawData(kEoB2TransferConvertTable, temp);
+	_itemTable = _vm->staticres()->loadRawData(kEoB2TransferItemTable, temp);
+	_expTable = _vm->staticres()->loadRawDataBe32(kEoB2TransferExpTable, temp);
+	_strings1 = _vm->staticres()->loadStrings(kEoB2TransferStrings1, temp);
+	_strings2 = _vm->staticres()->loadStrings(kEoB2TransferStrings2, temp);
+	_labels = _vm->staticres()->loadStrings(kEoB2TransferLabels, temp);
+	_highlight = -1;
+	_oldItems = 0;
 }
 
 TransferPartyWiz::~TransferPartyWiz() {
-
+	delete[] _oldItems;
 }
 
 bool TransferPartyWiz::start() {
@@ -1465,11 +1485,39 @@ bool TransferPartyWiz::start() {
 
 	convertStats();
 
+	_oldItems = new EoBItem[600];
+	memcpy(_oldItems, _vm->_items, sizeof(EoBItem) * 600);
+	_vm->loadItemDefs();
+
+	int selection = selectCharactersMenu();
+	if (selection == 0) {
+		for (int i = 0; i < 6; i++)
+			delete[] _vm->_characters[i].faceShape;
+		memset(_vm->_characters, 0, sizeof(EoBCharacter) * 6);
+		return false;
+	}
+
+	int ch = 0;
+	for (int i = 0; i < 6; i++) {
+		if (selection & (1 << i)) {
+			if (ch != i) {
+				delete[] _vm->_characters[ch].faceShape;
+				memcpy(&_vm->_characters[ch], &_vm->_characters[i], sizeof(EoBCharacter));
+				_vm->_characters[i].faceShape = 0;
+			}
+			ch++;
+		}
+	}
+	memset(&_vm->_characters[4], 0, sizeof(EoBCharacter) * 2);
+
+	convertInventory();
+	giveKhelbensCoin();
+
 	return true;
 }
 
 bool TransferPartyWiz::selectAndLoadTransferFile() {
-	for (int numLoops = 1; numLoops; numLoops--)  {
+	for (int numLoops = 1; numLoops; numLoops--) {
 		_screen->copyPage(12, 0);
 		_vm->_savegameFilename = transferFileDialogue();
 		if (_vm->_savegameFilename.empty()) {
@@ -1493,9 +1541,14 @@ Common::String TransferPartyWiz::transferFileDialogue() {
 	Common::String tfile;
 
 	KyraEngine_v1::SaveHeader header;
+	memset(&header, 0, sizeof(KyraEngine_v1::SaveHeader));
 	Common::InSaveFile *in;
 
+	_vm->_gui->transferWaitBox();
+
 	for (Common::StringArray::iterator i = saveFileList.begin(); i != saveFileList.end(); ++i) {
+		_vm->updateInput();
+
 		if (!(in = _vm->_saveFileMan->openForLoading(*i)))
 			continue;
 
@@ -1546,6 +1599,170 @@ Common::String TransferPartyWiz::transferFileDialogue() {
 	return tfile;
 }
 
+int TransferPartyWiz::selectCharactersMenu() {
+	_screen->setCurPage(2);
+	_screen->setFont(Screen::FID_6_FNT);
+	_screen->clearCurPage();
+
+	_vm->gui_drawBox(0, 0, 320, 163, _vm->_color1_1, _vm->_color2_1, _vm->_bkgColor_1);
+	_screen->printText(_strings2[0], 5, 3, 15, 0);
+	_screen->printText(_strings2[1], 5, 10, 15, 0);
+
+	for (int i = 0; i < 6; i++)
+		drawCharPortraitWithStats(i, 0);
+
+	_vm->gui_drawBox(4, 148, 43, 12, _vm->_color1_1, _vm->_color2_1, _vm->_bkgColor_1);
+	_vm->gui_drawBox(272, 148, 43, 12, _vm->_color1_1, _vm->_color2_1, _vm->_bkgColor_1);
+
+	_screen->printShadedText(_labels[0], 9, 151, 15, 0);
+	_screen->printShadedText(_labels[1], 288, 151, 15, 0);
+
+	_screen->setCurPage(0);
+	_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->updateScreen();
+
+	int selection = 0;
+	int highlight = 0;
+	bool update = false;
+
+	for (bool loop = true; loop && (!_vm->shouldQuit()); ) {
+		int inputFlag = _vm->checkInput(0, false, 0) & 0x8ff;
+		_vm->removeInputTop();
+
+		if (inputFlag) {
+			if (inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT]) {
+				highlight ^= 1;
+			} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_UP]) {
+				highlight -= 2;
+				if (highlight < 0)
+					highlight += 8;
+			} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN]) {
+				highlight += 2;
+				if (highlight >= 8)
+					highlight -= 8;
+			} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE]) {
+				update = true;
+			} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE]) {
+				update = true;
+				highlight = 6;
+			} else if (inputFlag == 199) {
+				for (int i = 0; i < 8; i++) {
+					int t = i << 2;
+					if (_vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, _portraitFrames[t], _portraitFrames[t + 1], _portraitFrames[t + 2], _portraitFrames[t + 3])) {
+						highlight = i;
+						update = true;
+						break;
+					}
+				}
+			}
+		}
+
+		updateHighlight(highlight);
+
+		if (!update)
+			continue;
+
+		update = false;
+
+		if (highlight < 6) {
+			if (_vm->_characters[highlight].flags & 1) {
+				selection ^= (1 << highlight);
+				drawCharPortraitWithStats(highlight, (selection & (1 << highlight)) ? true : false);
+				_screen->updateScreen();
+			}
+			continue;
+		}
+
+		int x = (highlight - 6) * 268 + 4;
+		_vm->gui_drawBox(x, 148, 43, 12, _vm->_bkgColor_1, _vm->_bkgColor_1, -1);
+		_screen->updateScreen();
+		_vm->_system->delayMillis(80);
+		_vm->gui_drawBox(x, 148, 43, 12, _vm->_color1_1, _vm->_color2_1, -1);
+		_screen->updateScreen();
+
+		if (highlight == 6 || _vm->shouldQuit()) {
+			_screen->setFont(Screen::FID_8_FNT);
+			return 0;
+		}
+
+		int count = 0;
+		for (int i = 0; i < 6; i++) {
+			if (selection & (1 << i))
+				count++;
+		}
+
+		if (count == 4 || _vm->shouldQuit())
+			loop = false;
+		else
+			_vm->_gui->messageDialogue(16, count < 4 ? 69 : 70, 6);
+
+		_screen->updateScreen();
+	}
+
+	_screen->setFont(Screen::FID_8_FNT);
+	if (_vm->shouldQuit())
+		return 0;
+	else
+		_vm->_gui->messageDialogue(16, 71, 6);
+
+	return selection;
+}
+
+void TransferPartyWiz::drawCharPortraitWithStats(int charIndex, bool enabled) {
+	int16 x = (charIndex % 2) * 159;
+	int16 y = (charIndex / 2) * 40;
+	EoBCharacter *c = &_vm->_characters[charIndex];
+
+	_screen->fillRect(x + 4, y + 24, x + 36, y + 57, 12);
+	_vm->gui_drawBox(x + 40, y + 24, 118, 34, _vm->_color1_1, _vm->_color2_1, _vm->_bkgColor_1);
+
+	if (!(c->flags & 1))
+		return;
+
+	_screen->drawShape(_screen->_curPage, c->faceShape, x + 4, y + 25, 0);
+
+	int color1 = 15;
+	int color2 = 12;
+
+	if (enabled) {
+		color1 = 6;
+		color2 = 15;
+	} else {
+		_screen->drawShape(_screen->_curPage, _vm->_disabledCharGrid, x + 4, y + 25, 0);
+	}
+
+	_screen->printShadedText(c->name, x + 44, y + 27, color1, 0);
+	_screen->printText(_vm->_chargenRaceSexStrings[c->raceSex], x + 43, y + 36, color2, 0);
+	_screen->printText(_vm->_chargenClassStrings[c->cClass], x + 43, y + 43, color2, 0);
+
+	Common::String tmp = Common::String::format(_strings1[0], c->level[0]);
+	for (int i = 1; i < _vm->_numLevelsPerClass[c->cClass]; i++)
+		tmp += Common::String::format(_strings1[1], c->level[i]);
+	_screen->printText(tmp.c_str(), x + 43, y + 50, color2, 0);
+}
+
+void TransferPartyWiz::updateHighlight(int index) {
+	static const int16 xPos[] = { 9, 288 };
+	if (_highlight > 5 && _highlight != index)
+		_screen->printText(_labels[_highlight - 6], xPos[_highlight - 6], 151, 15, 0);
+
+	if (index < 6) {
+		_vm->_gui->updateBoxFrameHighLight(14 + index);
+		_highlight = index;
+		return;
+	}
+
+	if (_highlight == index)
+		return;
+
+	if (_highlight < 6)
+		_vm->_gui->updateBoxFrameHighLight(-1);
+
+	_screen->printText(_labels[index - 6], xPos[index - 6], 151, 6, 0);
+	_screen->updateScreen();
+	_highlight = index;
+}
+
 void TransferPartyWiz::convertStats() {
 	for (int i = 0; i < 6; i++) {
 		EoBCharacter *c = &_vm->_characters[i];
@@ -1553,25 +1770,182 @@ void TransferPartyWiz::convertStats() {
 
 		for (int ii = 0; ii < 25; ii++) {
 			if (c->mageSpellsAvailableFlags & (1 << ii)) {
-				int8 f = (int8)_vm->_transferConvertTable[i + 1] - 1;
+				int8 f = (int8)_convertTable[ii + 1] - 1;
 				if (f != -1)
 					aflags |= (1 << f);
 			}
 		}
 		c->mageSpellsAvailableFlags = aflags;
 
+		c->armorClass = 0;
+		c->disabledSlots = 0;
 		c->flags &= 1;
 		c->hitPointsCur = c->hitPointsMax;
 		c->food = 100;
 
+		c->effectFlags = 0;
+		c->damageTaken = 0;
+		memset(c->clericSpells, 0, sizeof(int8) * 80);
+		memset(c->mageSpells, 0, sizeof(int8) * 80);
+		memset(c->timers, 0, sizeof(uint32) * 10);
+		memset(c->events, 0, sizeof(int8) * 10);
+		memset(c->effectsRemainder, 0, sizeof(uint8) * 4);
+		memset(c->slotStatus, 0, sizeof(int8) * 5);
+
 		for (int ii = 0; ii < 3; ii++) {
 			int t = _vm->getCharacterClassType(c->cClass, ii);
 			if (t == -1)
 				continue;
-			if (c->experience[ii] < _vm->_transferExpTable[t])
-				c->experience[ii] = _vm->_transferExpTable[t];
+			if (c->experience[ii] > _expTable[t])
+				c->experience[ii] = _expTable[t];
+		}
+	}
+}
+
+void TransferPartyWiz::convertInventory() {
+	for (int i = 0; i < 4; i++) {
+		EoBCharacter *c = &_vm->_characters[i];
+
+		for (int slot = 0; slot < 27; slot++) {
+			Item itm = c->inventory[slot];
+			if (slot == 16) {
+				Item first = itm;
+				c->inventory[slot] = 0;
+
+				for (bool forceLoop = true; (itm && (itm != first)) || forceLoop; itm = _oldItems[itm].prev) {
+					forceLoop = false;
+					_vm->setItemPosition(&c->inventory[slot], -2, convertItem(itm), 0);
+				}
+			} else {
+				c->inventory[slot] = convertItem(itm);
+			}
+		}
+	}
+}
+
+Item TransferPartyWiz::convertItem(Item eob1Item) {
+	if (!eob1Item)
+		return 0;
+
+	EoBItem *itm1 = &_oldItems[eob1Item];
+
+	if (!_itemTable[itm1->type])
+		return 0;
+
+	Item newItem = _vm->duplicateItem(1);
+	EoBItem *itm2 = &_vm->_items[newItem];
+	bool match = false;
+
+	itm2->flags = itm1->flags | 0x40;
+	itm2->icon = itm1->icon;
+	itm2->type = itm1->type;
+	itm2->level = 0xff;
+
+	switch(itm2->type) {
+	case 35:
+		itm1->value += 25;
+		// fall through
+	case 34:
+		itm2->value = _convertTable[itm1->value];
+		if (!itm2->value) {
+			itm2->block = -1;
+			return 0;
+		}
+		break;
+	case 39:
+		itm2->value = itm1->value - 1;
+		break;
+	case 48:
+		if (itm1->value == 5) {
+			memset(itm2, 0, sizeof(EoBItem));
+			itm2->block = -1;
+			return 0;
+		}
+		itm2->value = itm1->value;
+		itm2->flags = ((itm1->flags & 0x3f) + 3) | 0x40;
+		break;
+	case 18:
+		itm2->icon = 19;
+		// fall through
+	default:
+		itm2->value = itm1->value;
+		break;
+	}
+
+	switch ((_vm->_itemTypes[itm2->type].extraProperties & 0x7f) - 1) {
+	case 0:
+	case 1:
+	case 2:
+		if (itm2->value)
+			itm2->flags |= 0x80;
+		break;
+	case 4:
+	case 5:
+	case 8:
+	case 9:
+	case 13:
+	case 15:
+	case 17:
+		itm2->flags |= 0x80;
+		break;
+	default:
+		break;
+	}
+
+	for (int i = 1; i < 600; i++) {
+		if (i == 60 || i == 62 || i == 63 || i == 83)
+			continue;
+		EoBItem *tmp = &_vm->_items[i];
+		if (tmp->level || tmp->block == -2 || tmp->type != itm2->type || tmp->icon != itm2->icon)
+			continue;
+		itm2->nameUnid = tmp->nameUnid;
+		itm2->nameId = tmp->nameId;
+		match = true;
+		break;
+	}
+
+	if (!match) {
+		for (int i = 1; i < 600; i++) {
+			if (i == 60 || i == 62 || i == 63 || i == 83)
+				continue;
+			EoBItem *tmp = &_vm->_items[i];
+			if (tmp->level || tmp->block == -2 || tmp->type != itm2->type)
+				continue;
+			itm2->nameUnid = tmp->nameUnid;
+			itm2->nameId = tmp->nameId;
+			match = true;
+			break;
 		}
 	}
+
+	if (!match) {
+		memset(itm2, 0, sizeof(EoBItem));
+		itm2->block = -1;
+		return 0;
+	}
+
+	itm2->level = 0;
+	return newItem;
+}
+
+void TransferPartyWiz::giveKhelbensCoin() {
+	bool success = false;
+	for (int i = 0; i < 4 && !success; i++) {
+		EoBCharacter *c = &_vm->_characters[i];
+
+		for (int slot = 2; slot < 16; slot++) {
+			if (c->inventory[slot])
+				continue;
+			_vm->createInventoryItem(c, 93, -1, slot);
+			success = true;
+			break;
+		}
+	}
+
+	if (!success) {
+		_vm->_characters[0].inventory[2] = 0;
+		_vm->createInventoryItem(&_vm->_characters[0], 93, -1, 2);
+	}
 }
 
 // Start functions
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index c64f60b..f3e644b 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -64,9 +64,6 @@ EoBCoreEngine::EoBCoreEngine(OSystem *system, const GameFlags &flags) : KyraRpgE
 	_beholderSpellList = 0;
 	_beholderSfx = 0;
 
-	_transferConvertTable = 0;
-	_transferExpTable = 0;
-
 	_faceShapes = 0;
 	_characters = 0;
 	_items = 0;
@@ -470,7 +467,7 @@ Common::Error EoBCoreEngine::go() {
 		}
 	}
 
-	if (!shouldQuit() && action > -3) {
+	if (!shouldQuit() && action >= -3) {
 		runLoop();
 
 		if (_playFinale) {
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index f489f87..399eff7 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -331,9 +331,6 @@ protected:
 
 	const uint8 *_classModifierFlags;
 
-	const uint8 *_transferConvertTable;
-	const uint32 *_transferExpTable;
-
 	// timers
 	void setupTimers();
 	void setCharEventTimer(int charIndex, uint32 countdown, int evnt, int updateExistingTimer);
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index ab92e08..080af94 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -2308,6 +2308,46 @@ bool GUI_EoB::confirmDialogue2(int dim, int id, int deflt) {
 	return newHighlight ? false : true;
 }
 
+void GUI_EoB::messageDialogue(int dim, int id, int buttonTextCol) {
+	int od = _screen->curDimIndex();
+	_screen->setScreenDim(dim);
+	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+
+	drawTextBox(dim, id);
+	const ScreenDim *dm = _screen->getScreenDim(dim);
+
+	int bx = ((dm->sx + dm->w) << 3) - ((strlen(_vm->_menuOkString) << 3) + 16);
+	int by = dm->sy + dm->h - 19;
+	int bw = (strlen(_vm->_menuOkString) << 3) + 7;
+
+	drawMenuButtonBox(bx, by, bw, 14, false, false);
+	_screen->printShadedText(_vm->_menuOkString, bx + 4, by + 3, buttonTextCol, 0);
+	_screen->updateScreen();
+
+	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
+		int inputFlag = _vm->checkInput(0, false, 0) & 0x8ff;
+		_vm->removeInputTop();
+
+		if (inputFlag == 199 || inputFlag == 201) {
+			if (_vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, bx, by, bx + bw, by + 14))
+				runLoop = false;
+		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_o]) {
+			runLoop = false;
+		}
+	}
+
+	drawMenuButtonBox(bx, by, bw, 14, true, true);
+	_screen->updateScreen();
+	_vm->_system->delayMillis(80);
+	drawMenuButtonBox(bx, by, bw, 14, false, true);
+	_screen->updateScreen();
+
+	_screen->copyRegion(0, dm->h, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->setScreenDim(od);
+	_screen->setFont(of);
+	dm = _screen->getScreenDim(dim);
+}
+
 void GUI_EoB::messageDialogue2(int dim, int id, int buttonTextCol) {
 	drawMenuButtonBox(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, false, false);
 
@@ -2496,6 +2536,15 @@ int GUI_EoB::getTextInput(char *dest, int x, int y, int destMaxLen, int textColo
 	return _keyPressed.keycode == Common::KEYCODE_ESCAPE ? -1 : len;
 }
 
+void GUI_EoB::transferWaitBox() {
+	const ScreenDim *dm = _screen->getScreenDim(11);
+	int xo = dm->sx;
+	int yo = dm->sy;
+	_screen->modifyScreenDim(11, dm->sx + 9, dm->sy + 24, dm->w, dm->h);
+	displayTextBox(-4);
+	_screen->modifyScreenDim(11, xo, yo, dm->w, dm->h);
+}
+
 Common::String GUI_EoB::transferTargetMenu(Common::Array<Common::String> &targets) {
 	_savegameListSize = targets.size();
 	if (_savegameList) {
@@ -2542,13 +2591,14 @@ Common::String GUI_EoB::transferFileMenu(Common::String &target) {
 	int slot = 0;
 	do {
 		slot = selectSaveSlotDialogue(72, 14, 4);
-		if (slot < 6) {
-			if (_saveSlotIdTemp[slot] == -1)
-				messageDialogue(11, 65, 6);
-			else {
-				_screen->modifyScreenDim(11, xo, yo, dm->w, dm->h);
-				return _vm->getSavegameFilename(target, _saveSlotIdTemp[slot]);
-			}
+		if (slot == 6)
+			break;
+		
+		if (_saveSlotIdTemp[slot] == -1)
+			messageDialogue(11, 65, 6);
+		else {
+			_screen->modifyScreenDim(11, xo, yo, dm->w, dm->h);
+			return _vm->getSavegameFilename(target, _saveSlotIdTemp[slot]);
 		}
 	} while (_saveSlotIdTemp[slot] == -1);
 
@@ -3488,46 +3538,6 @@ bool GUI_EoB::confirmDialogue(int id) {
 	return result;
 }
 
-void GUI_EoB::messageDialogue(int dim, int id, int buttonTextCol) {
-	int od = _screen->curDimIndex();
-	_screen->setScreenDim(dim);
-	Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
-
-	drawTextBox(dim, id);
-	const ScreenDim *dm = _screen->getScreenDim(dim);
-
-	int bx = ((dm->sx + dm->w) << 3) - ((strlen(_vm->_menuOkString) << 3) + 16);
-	int by = dm->sy + dm->h - 19;
-	int bw = (strlen(_vm->_menuOkString) << 3) + 7;
-
-	drawMenuButtonBox(bx, by, bw, 14, false, false);
-	_screen->printShadedText(_vm->_menuOkString, bx + 4, by + 3, buttonTextCol, 0);
-	_screen->updateScreen();
-
-	for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
-		int inputFlag = _vm->checkInput(0, false, 0) & 0x8ff;
-		_vm->removeInputTop();
-
-		if (inputFlag == 199 || inputFlag == 201) {
-			if (_vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, bx, by, bx + bw, by + 14))
-				runLoop = false;
-		} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_o]) {
-			runLoop = false;
-		}
-	}
-
-	drawMenuButtonBox(bx, by, bw, 14, true, true);
-	_screen->updateScreen();
-	_vm->_system->delayMillis(80);
-	drawMenuButtonBox(bx, by, bw, 14, false, true);
-	_screen->updateScreen();
-
-	_screen->copyRegion(0, dm->h, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK);
-	_screen->setScreenDim(od);
-	_screen->setFont(of);
-	dm = _screen->getScreenDim(dim);
-}
-
 int GUI_EoB::selectCharacterDialogue(int id) {
 	uint8 flags = (id == 26) ? (_vm->game() == GI_EOB1 ? 0x04 : 0x14) : 0x02;
 	_vm->removeInputTop();
diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h
index d8ce9bd..ec4000e 100644
--- a/engines/kyra/gui_eob.h
+++ b/engines/kyra/gui_eob.h
@@ -63,6 +63,7 @@ public:
 	bool runLoadMenu(int x, int y);
 
 	bool confirmDialogue2(int dim, int id, int deflt);
+	void messageDialogue(int dim, int id, int buttonTextCol);
 	void messageDialogue2(int dim, int id, int buttonTextCol);
 
 	void updateBoxFrameHighLight(int box);
@@ -70,6 +71,7 @@ public:
 	int getTextInput(char *dest, int x, int y, int destMaxLen, int textColor1, int textColor2, int cursorColor);
 
 	// Transfer party
+	void transferWaitBox();
 	Common::String transferTargetMenu(Common::Array<Common::String> &targets);
 	Common::String transferFileMenu(Common::String &target);
 
@@ -88,7 +90,6 @@ private:
 	bool restParty();
 
 	bool confirmDialogue(int id);
-	void messageDialogue(int dim, int id, int buttonTextCol);
 	int selectCharacterDialogue(int id);
 	void displayTextBox(int id);
 
diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
index 28764df..c58fd08 100644
--- a/engines/kyra/items_eob.cpp
+++ b/engines/kyra/items_eob.cpp
@@ -30,6 +30,7 @@ namespace Kyra {
 
 void EoBCoreEngine::loadItemDefs() {
 	Common::SeekableReadStream *s = _res->createReadStream("item.dat");
+	memset(_items, 0, sizeof(EoBItem) * 600);
 	_numItems = s->readUint16LE();
 
 	for (int i = 0; i < 600; i++)
@@ -58,6 +59,7 @@ void EoBCoreEngine::loadItemDefs() {
 	s = _res->createReadStream("itemtype.dat");
 	uint16 numTypes = s->readUint16LE();
 
+	delete[] _itemTypes;
 	_itemTypes = new EoBItemType[65];
 	memset(_itemTypes, 0, sizeof(EoBItemType) * 65);
 
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 45c1851..5b0af98 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -537,8 +537,14 @@ enum KyraResources {
 	kEoB1Npc7Strings,
 
 	kEoB2MainMenuStrings,
+
+	kEoB2TransferPortraitFrames,
 	kEoB2TransferConvertTable,
+	kEoB2TransferItemTable,
 	kEoB2TransferExpTable,
+	kEoB2TransferStrings1,
+	kEoB2TransferStrings2,
+	kEoB2TransferLabels,
 
 	kEoB2IntroStrings,
 	kEoB2IntroCPSFiles,
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index 714033b..1f982aa 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -74,7 +74,7 @@ Common::Error EoBCoreEngine::loadGameState(int slot) {
 		c->alignment = in.readByte();
 		c->portrait = in.readSByte();
 		if (slot == -1 && c->portrait < 0)
-			c->portrait += 43;
+			c->portrait = -c->portrait + 43;
 		c->food = in.readByte();
 		in.read(c->level, 3);
 		for (int ii = 0; ii < 3; ii++)
@@ -118,35 +118,37 @@ Common::Error EoBCoreEngine::loadGameState(int slot) {
 	}
 	_screen->_curPage = 0;
 
-	// No more data required for party transfer
-	if (slot == -1)
-		return Common::kNoError;
-
-	_currentLevel = in.readByte();
-	_currentSub = in.readSByte();
-	_currentBlock = in.readUint16BE();
-	_currentDirection = in.readUint16BE();
-	_itemInHand = in.readSint16BE();
-	_hasTempDataFlags = in.readUint32BE();
-	_partyEffectFlags = in.readUint32BE();
-
-	_updateFlags = in.readUint16BE();
-	_compassDirection = in.readUint16BE();
-	_currentControlMode = in.readUint16BE();
-	_updateCharNum = in.readUint16BE();
-	_openBookSpellLevel = in.readSByte();
-	_openBookSpellSelectedItem  = in.readSByte();
-	_openBookSpellListOffset = in.readSByte();
-	_openBookChar = in.readByte();
-	_openBookType = in.readByte();
-	_openBookCharBackup = in.readByte();
-	_openBookTypeBackup = in.readByte();
-	_activeSpellCharId = in.readByte();
-	_activeSpellCharacterPos = in.readByte();
-	_activeSpell = in.readByte();
-	_returnAfterSpellCallback = in.readByte() ? true : false;
-
-	_inf->loadState(in);
+	if (slot == -1) {
+		// Skip all settings which aren't necessary for party transfer.
+		// Jump directly to the items list.
+		in.skip(108);
+	} else {
+		_currentLevel = in.readByte();
+		_currentSub = in.readSByte();
+		_currentBlock = in.readUint16BE();
+		_currentDirection = in.readUint16BE();
+		_itemInHand = in.readSint16BE();
+		_hasTempDataFlags = in.readUint32BE();
+		_partyEffectFlags = in.readUint32BE();
+
+		_updateFlags = in.readUint16BE();
+		_compassDirection = in.readUint16BE();
+		_currentControlMode = in.readUint16BE();
+		_updateCharNum = in.readUint16BE();
+		_openBookSpellLevel = in.readSByte();
+		_openBookSpellSelectedItem  = in.readSByte();
+		_openBookSpellListOffset = in.readSByte();
+		_openBookChar = in.readByte();
+		_openBookType = in.readByte();
+		_openBookCharBackup = in.readByte();
+		_openBookTypeBackup = in.readByte();
+		_activeSpellCharId = in.readByte();
+		_activeSpellCharacterPos = in.readByte();
+		_activeSpell = in.readByte();
+		_returnAfterSpellCallback = in.readByte() ? true : false;
+
+		_inf->loadState(in);
+	}
 
 	for (int i = 0; i < 600; i++) {
 		EoBItem *t = &_items[i];
@@ -163,6 +165,12 @@ Common::Error EoBCoreEngine::loadGameState(int slot) {
 		t->value = in.readSByte();
 	}
 
+	// No more data needed for party transfer
+	if (slot == -1) {
+		_loading = false;
+		return Common::kNoError;
+	}
+
 	for (int i = 51; i < 65; i++) {
 		EoBItemType *t = &_itemTypes[i];
 		t->invFlags = in.readUint16BE();
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 8ab16f5..7bbe9f5 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -1193,9 +1193,6 @@ void EoBEngine::initSpells() {
 void DarkMoonEngine::initStaticResource() {
 	int temp;
 	_mainMenuStrings = _staticres->loadStrings(kEoB2MainMenuStrings, temp);
-	_transferConvertTable = _staticres->loadRawData(kEoB2TransferConvertTable, temp);
-	_transferExpTable = _staticres->loadRawDataBe32(kEoB2TransferExpTable, temp);
-
 	_introStrings = _staticres->loadStrings(kEoB2IntroStrings, temp);
 	_cpsFilesIntro = _staticres->loadStrings(kEoB2IntroCPSFiles, temp);
 
@@ -1252,16 +1249,18 @@ void DarkMoonEngine::initStaticResource() {
 	_errorSlotNoNameString = errorSlotNoNameString[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
 
 	// ScummVM specific
-	static const char *transferStringsScummVM[3][4] = {
+	static const char *transferStringsScummVM[3][5] = {
 		{	"\r We cannot find any EOB save game\r file. Please make sure that the\r save game file with the party\r you wish to transfer is located\r in your ScummVM save game\r directory. If you have set up\r multiple save directories you\r have to copy the EOB save file\r into your EOB II save directory.\r Do you wish to try again?",
 			"Game ID",
 			"\r It seems that you have already\r defeated Xanathar here. Do you\r wish to transfer the party that\r finished the game? If not, you\r will be able to select a save\r game from the save game\r dialogue.",
-			"Select File"
+			"Select File",
+			"\r\r   Please wait..."
 		},
 		{	"\r Kein EOB-Spielstand zu finden.\r Bitte Spielstandsdatei mit der\r zu ]bernehmenden Gruppe in das\r ScummVM Spielstands-Verzeichnis\r kopieren. Bei mehreren Spiel-\r stands-Verzeichnissen bitte\r den EOB-Spielstand in das\r EOB II-Spielstands-Verzeichnis\r kopieren. Nochmal versuchen?",
 			"Game ID",
 			"\r Wie es scheint, wurde Xanathar\r hier bereits besiegt. Soll die\r Gruppe, mit der das Spiel be-\r endet wurde, ]bernommen werden?\r Falls nicht, kann ein Spielstand\r aus der Spielstandsliste gew[hlt\r werden.",
-			"Spiel W[hlen"
+			"Spiel W[hlen",
+			"\r\r  Bitte warten..."
 		},
 		{	0, 0, 0, 0
 		}


Commit: 2e517cc9ec65a535d580fee607b9b920e41a3019
    https://github.com/scummvm/scummvm/commit/2e517cc9ec65a535d580fee607b9b920e41a3019
Author: athrxx (athrxx at scummvm.org)
Date: 2011-12-26T07:18:17-08:00

Commit Message:
KYRA: (EOB) - add EOB copyright strings to KyraMetaEngine::getOriginalCopyright()

Changed paths:
    engines/kyra/detection.cpp



diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp
index 56687d6..74c949b 100644
--- a/engines/kyra/detection.cpp
+++ b/engines/kyra/detection.cpp
@@ -68,6 +68,9 @@ public:
 #ifdef ENABLE_LOL
 				"\nLands of Lore (C) Westwood Studios"
 #endif
+#ifdef ENABLE_EOB
+				"\nEye of the Beholder (C) TSR, Inc., (C) Strategic Simulations, Inc."
+#endif
 		    ;
 	}
 






More information about the Scummvm-git-logs mailing list