[Scummvm-git-logs] scummvm master -> d84c1ac7e01b7594f500d8d7f5b60a715eadf1be

sev- sev at scummvm.org
Sat May 5 23:18:14 CEST 2018


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

Summary:
919013d7f2 JANITORIAL: Fix formatting
132f77fd16 PRINCE: Rename sound.cpp to music.cpp
faf579c48f PRINCE: Move resource loading methods to separate file
951c365591 PRINCE: Move cursor manipulation to cursor.cpp
67abcc36a7 PRINCE: Moved audio-related methods to separate files
788a1fab82 PRINCE: More prince.cpp restructuring
7352737a69 PRINCE: Even more prince.cpp refactoring. Inventory and pathfinding
c95cbdc2c9 JANITORIAL: Fix formatting
c234630931 PRINCE: Initial support for packed Russian version
e3b9be6679 JANITORIAL: Whitespace fixes
6e58c5aaa5 PRINCE: Added support for unbundled compressed files
a97a3c3886 PRINCE: Further work on support for extracted games
5a9eba989a PRINCE: Rename resources.cpp
85aa17d9ac PRINCE: Move decompression method to reusable place
5515f414af PRINCE: Decompress files if they're extracted
44e44c1f1a PRINCE: Optimize decompression for bundled games
dbc60f55e2 PRINCE: Added Russian options
d84c1ac7e0 PRINCE: Fix header dependency


Commit: 919013d7f2f130d528d32c2879b19761292e1197
    https://github.com/scummvm/scummvm/commit/919013d7f2f130d528d32c2879b19761292e1197
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2018-05-05T23:17:34+02:00

Commit Message:
JANITORIAL: Fix formatting

Changed paths:
    engines/prince/prince.cpp
    engines/prince/script.cpp


diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp
index 0164289..6cca0b9 100644
--- a/engines/prince/prince.cpp
+++ b/engines/prince/prince.cpp
@@ -464,8 +464,7 @@ void PrinceEngine::pauseEngineIntern(bool pause) {
 	Engine::pauseEngineIntern(pause);
 	if (pause) {
 		_midiPlayer->pause();
-	}
-	else {
+	} else {
 		_midiPlayer->resume();
 	}
 }
diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp
index 23ef24a..7d8f834 100644
--- a/engines/prince/script.cpp
+++ b/engines/prince/script.cpp
@@ -916,8 +916,7 @@ void Interpreter::O_ADDFLAG() {
 	_flags->setFlagValue(flagId, _flags->getFlagValue(flagId) + value);
 	if (_flags->getFlagValue(flagId)) {
 		_result = 1;
-	}
-	else {
+	} else {
 		_result = 0;
 	}
 	debugInterpreter("O_ADDFLAG flagId %04x (%s), value %d", flagId, Flags::getFlagName(flagId), value);
@@ -936,8 +935,7 @@ void Interpreter::O_SUBFLAG() {
 	_flags->setFlagValue(flagId, _flags->getFlagValue(flagId) - value);
 	if (_flags->getFlagValue(flagId)) {
 		_result = 1;
-	}
-	else {
+	} else {
 		_result = 0;
 	}
 	debugInterpreter("O_SUBFLAG flagId %d, value %d", flagId, value);
@@ -949,8 +947,7 @@ void Interpreter::O_SETSTRING() {
 	if (offset >= 80000) {
 		_string = _vm->_variaTxt->getString(offset - 80000);
 		debugInterpreter("GetVaria %s", _string);
-	}
-	else if (offset < 2000) {
+	} else if (offset < 2000) {
 		_vm->_dialogData = &_vm->_dialogDat[offset * 4 - 4];
 		uint32 of = READ_LE_UINT32(_vm->_talkTxt + offset * 4);
 		const char *txt = (const char *)&_vm->_talkTxt[of];


Commit: 132f77fd1629158e27c2487ef94cc9b6cb1c0150
    https://github.com/scummvm/scummvm/commit/132f77fd1629158e27c2487ef94cc9b6cb1c0150
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2018-05-05T23:17:34+02:00

Commit Message:
PRINCE: Rename sound.cpp to music.cpp

Changed paths:
  A engines/prince/music.cpp
  A engines/prince/music.h
  R engines/prince/sound.cpp
  R engines/prince/sound.h
    engines/prince/module.mk
    engines/prince/prince.cpp


diff --git a/engines/prince/module.mk b/engines/prince/module.mk
index 27bbc21..6e9e80d 100644
--- a/engines/prince/module.mk
+++ b/engines/prince/module.mk
@@ -12,13 +12,13 @@ MODULE_OBJS = \
 	graphics.o \
 	hero.o \
 	mhwanh.o \
+	music.o \
 	mob.o \
 	object.o \
 	prince.o \
 	pscr.o \
 	saveload.o \
 	script.o \
-	sound.o \
 	variatxt.o \
 	videoplayer.o
 
diff --git a/engines/prince/music.cpp b/engines/prince/music.cpp
new file mode 100644
index 0000000..6d208e2
--- /dev/null
+++ b/engines/prince/music.cpp
@@ -0,0 +1,210 @@
+/* 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 "prince/music.h"
+#include "prince/musNum.h"
+
+#include "common/archive.h"
+#include "common/debug.h"
+#include "audio/mididrv.h"
+#include "audio/midiparser.h"
+
+namespace Prince {
+
+const char *MusicPlayer::_musTable[] = {
+	"",
+	"Battlfld.mid",
+	"Cave.mid",
+	"Cemetery.mid",
+	"Credits.mid",
+	"Fjord.mid",
+	"Guitar.mid",
+	"Hell.mid",
+	"Jingle.mid",
+	"Main.mid",
+	"Night.mid",
+	"Reality.mid",
+	"Sunlord.mid",
+	"Tavern.mid",
+	"Temple.mid",
+	"Boruta.mid",
+	"Intro.mid"
+};
+
+const uint8 MusicPlayer::_musRoomTable[] = {
+	0,
+	ROOM01MUS,
+	ROOM02MUS,
+	ROOM03MUS,
+	ROOM04MUS,
+	ROOM05MUS,
+	ROOM06MUS,
+	ROOM07MUS,
+	ROOM08MUS,
+	ROOM09MUS,
+	ROOM10MUS,
+	ROOM11MUS,
+	ROOM12MUS,
+	ROOM13MUS,
+	ROOM14MUS,
+	ROOM15MUS,
+	ROOM16MUS,
+	ROOM17MUS,
+	ROOM18MUS,
+	ROOM19MUS,
+	ROOM20MUS,
+	ROOM21MUS,
+	ROOM22MUS,
+	ROOM23MUS,
+	ROOM24MUS,
+	ROOM25MUS,
+	ROOM26MUS,
+	ROOM27MUS,
+	ROOM28MUS,
+	ROOM29MUS,
+	ROOM30MUS,
+	ROOM31MUS,
+	ROOM32MUS,
+	ROOM33MUS,
+	ROOM34MUS,
+	ROOM35MUS,
+	ROOM36MUS,
+	ROOM37MUS,
+	ROOM38MUS,
+	ROOM39MUS,
+	ROOM40MUS,
+	ROOM41MUS,
+	ROOM42MUS,
+	ROOM43MUS,
+	0,
+	0,
+	ROOM46MUS,
+	ROOM47MUS,
+	ROOM48MUS,
+	ROOM49MUS,
+	ROOM50MUS,
+	ROOM51MUS,
+	ROOM52MUS,
+	ROOM53MUS,
+	ROOM54MUS,
+	ROOM55MUS,
+	ROOM56MUS,
+	ROOM57MUS,
+	ROOM58MUS,
+	ROOM59MUS,
+	ROOM60MUS,
+	ROOM61MUS
+};
+
+
+MusicPlayer::MusicPlayer(PrinceEngine *vm) : _vm(vm) {
+	_data = nullptr;
+	_dataSize = 0;
+	_isGM = false;
+
+	MidiPlayer::createDriver();
+
+	int ret = _driver->open();
+	if (ret == 0) {
+		if (_nativeMT32)
+			_driver->sendMT32Reset();
+		else
+			_driver->sendGMReset();
+
+		_driver->setTimerCallback(this, &timerCallback);
+	}
+}
+
+MusicPlayer::~MusicPlayer() {
+	killMidi();
+}
+
+void MusicPlayer::killMidi() {
+	Audio::MidiPlayer::stop();
+
+	free(_data);
+	_data = nullptr;
+}
+
+void MusicPlayer::loadMidi(const char *name) {
+	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(name);
+	if (!stream) {
+		debug("Can't load midi stream %s", name);
+		return;
+	}
+
+	// Stop any currently playing MIDI file
+	killMidi();
+
+	// Read in the data for the file
+	_dataSize = stream->size();
+	_data = (byte *)malloc(_dataSize);
+	stream->read(_data, _dataSize);
+
+	delete stream;
+
+	// Start playing the music
+	sndMidiStart();
+}
+
+void MusicPlayer::sndMidiStart() {
+	_isGM = true;
+
+	MidiParser *parser = MidiParser::createParser_SMF();
+	if (parser->loadMusic(_data, _dataSize)) {
+		parser->setTrack(0);
+		parser->setMidiDriver(this);
+		parser->setTimerRate(_driver->getBaseTempo());
+		parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
+
+		_parser = parser;
+
+		syncVolume();
+
+		// Al the tracks are supposed to loop
+		_isLooping = true;
+		_isPlaying = true;
+	}
+}
+
+void MusicPlayer::send(uint32 b) {
+	if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) {
+		b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8;
+	}
+
+	Audio::MidiPlayer::send(b);
+}
+
+void MusicPlayer::sendToChannel(byte channel, uint32 b) {
+	if (!_channelsTable[channel]) {
+		_channelsTable[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
+		// If a new channel is allocated during the playback, make sure
+		// its volume is correctly initialized.
+		if (_channelsTable[channel])
+			_channelsTable[channel]->volume(_channelsVolume[channel] * _masterVolume / 255);
+	}
+
+	if (_channelsTable[channel])
+		_channelsTable[channel]->send(b);
+}
+
+} // End of namespace Prince
diff --git a/engines/prince/music.h b/engines/prince/music.h
new file mode 100644
index 0000000..061e10c
--- /dev/null
+++ b/engines/prince/music.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 PRINCE_MUSIC_H
+#define PRINCE_MUSIC_H
+
+#include "audio/midiplayer.h"
+#include "common/memstream.h"
+
+namespace Prince {
+
+class PrinceEngine;
+
+class MusicPlayer: public Audio::MidiPlayer {
+private:
+	PrinceEngine *_vm;
+	byte *_data;
+	int _dataSize;
+	bool _isGM;
+
+	// Start MIDI File
+	void sndMidiStart();
+
+	// Stop MIDI File
+	void sndMidiStop();
+public:
+	MusicPlayer(PrinceEngine *vm);
+	~MusicPlayer();
+
+	void loadMidi(const char *);
+	void killMidi();
+
+	virtual void send(uint32 b);
+	virtual void sendToChannel(byte channel, uint32 b);
+
+	static const char *_musTable[];
+	static const uint8 _musRoomTable[];
+};
+
+} // End of namespace Prince
+
+#endif
diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp
index 6cca0b9..fcdf3f5 100644
--- a/engines/prince/prince.cpp
+++ b/engines/prince/prince.cpp
@@ -49,7 +49,7 @@
 #include "prince/debugger.h"
 #include "prince/object.h"
 #include "prince/mob.h"
-#include "prince/sound.h"
+#include "prince/music.h"
 #include "prince/variatxt.h"
 #include "prince/flags.h"
 #include "prince/font.h"
diff --git a/engines/prince/sound.cpp b/engines/prince/sound.cpp
deleted file mode 100644
index 206b131..0000000
--- a/engines/prince/sound.cpp
+++ /dev/null
@@ -1,210 +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.
- *
- */
-
-#include "prince/sound.h"
-#include "prince/musNum.h"
-
-#include "common/archive.h"
-#include "common/debug.h"
-#include "audio/mididrv.h"
-#include "audio/midiparser.h"
-
-namespace Prince {
-
-const char *MusicPlayer::_musTable[] = {
-	"",
-	"Battlfld.mid",
-	"Cave.mid",
-	"Cemetery.mid",
-	"Credits.mid",
-	"Fjord.mid",
-	"Guitar.mid",
-	"Hell.mid",
-	"Jingle.mid",
-	"Main.mid",
-	"Night.mid",
-	"Reality.mid",
-	"Sunlord.mid",
-	"Tavern.mid",
-	"Temple.mid",
-	"Boruta.mid",
-	"Intro.mid"
-};
-
-const uint8 MusicPlayer::_musRoomTable[] = {
-	0,
-	ROOM01MUS,
-	ROOM02MUS,
-	ROOM03MUS,
-	ROOM04MUS,
-	ROOM05MUS,
-	ROOM06MUS,
-	ROOM07MUS,
-	ROOM08MUS,
-	ROOM09MUS,
-	ROOM10MUS,
-	ROOM11MUS,
-	ROOM12MUS,
-	ROOM13MUS,
-	ROOM14MUS,
-	ROOM15MUS,
-	ROOM16MUS,
-	ROOM17MUS,
-	ROOM18MUS,
-	ROOM19MUS,
-	ROOM20MUS,
-	ROOM21MUS,
-	ROOM22MUS,
-	ROOM23MUS,
-	ROOM24MUS,
-	ROOM25MUS,
-	ROOM26MUS,
-	ROOM27MUS,
-	ROOM28MUS,
-	ROOM29MUS,
-	ROOM30MUS,
-	ROOM31MUS,
-	ROOM32MUS,
-	ROOM33MUS,
-	ROOM34MUS,
-	ROOM35MUS,
-	ROOM36MUS,
-	ROOM37MUS,
-	ROOM38MUS,
-	ROOM39MUS,
-	ROOM40MUS,
-	ROOM41MUS,
-	ROOM42MUS,
-	ROOM43MUS,
-	0,
-	0,
-	ROOM46MUS,
-	ROOM47MUS,
-	ROOM48MUS,
-	ROOM49MUS,
-	ROOM50MUS,
-	ROOM51MUS,
-	ROOM52MUS,
-	ROOM53MUS,
-	ROOM54MUS,
-	ROOM55MUS,
-	ROOM56MUS,
-	ROOM57MUS,
-	ROOM58MUS,
-	ROOM59MUS,
-	ROOM60MUS,
-	ROOM61MUS
-};
-
-
-MusicPlayer::MusicPlayer(PrinceEngine *vm) : _vm(vm) {
-	_data = nullptr;
-	_dataSize = 0;
-	_isGM = false;
-
-	MidiPlayer::createDriver();
-
-	int ret = _driver->open();
-	if (ret == 0) {
-		if (_nativeMT32)
-			_driver->sendMT32Reset();
-		else
-			_driver->sendGMReset();
-
-		_driver->setTimerCallback(this, &timerCallback);
-	}
-}
-
-MusicPlayer::~MusicPlayer() {
-	killMidi();
-}
-
-void MusicPlayer::killMidi() {
-	Audio::MidiPlayer::stop();
-
-	free(_data);
-	_data = nullptr;
-}
-
-void MusicPlayer::loadMidi(const char *name) {
-	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(name);
-	if (!stream) {
-		debug("Can't load midi stream %s", name);
-		return;
-	}
-
-	// Stop any currently playing MIDI file
-	killMidi();
-
-	// Read in the data for the file
-	_dataSize = stream->size();
-	_data = (byte *)malloc(_dataSize);
-	stream->read(_data, _dataSize);
-
-	delete stream;
-
-	// Start playing the music
-	sndMidiStart();
-}
-
-void MusicPlayer::sndMidiStart() {
-	_isGM = true;
-
-	MidiParser *parser = MidiParser::createParser_SMF();
-	if (parser->loadMusic(_data, _dataSize)) {
-		parser->setTrack(0);
-		parser->setMidiDriver(this);
-		parser->setTimerRate(_driver->getBaseTempo());
-		parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
-
-		_parser = parser;
-
-		syncVolume();
-
-		// Al the tracks are supposed to loop
-		_isLooping = true;
-		_isPlaying = true;
-	}
-}
-
-void MusicPlayer::send(uint32 b) {
-	if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) {
-		b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8;
-	}
-
-	Audio::MidiPlayer::send(b);
-}
-
-void MusicPlayer::sendToChannel(byte channel, uint32 b) {
-	if (!_channelsTable[channel]) {
-		_channelsTable[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
-		// If a new channel is allocated during the playback, make sure
-		// its volume is correctly initialized.
-		if (_channelsTable[channel])
-			_channelsTable[channel]->volume(_channelsVolume[channel] * _masterVolume / 255);
-	}
-
-	if (_channelsTable[channel])
-		_channelsTable[channel]->send(b);
-}
-
-} // End of namespace Prince
diff --git a/engines/prince/sound.h b/engines/prince/sound.h
deleted file mode 100644
index 21f9e48..0000000
--- a/engines/prince/sound.h
+++ /dev/null
@@ -1,61 +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 PRINCE_SOUND_H
-#define PRINCE_SOUND_H
-
-#include "audio/midiplayer.h"
-#include "common/memstream.h"
-
-namespace Prince {
-
-class PrinceEngine;
-
-class MusicPlayer: public Audio::MidiPlayer {
-private:
-	PrinceEngine *_vm;
-	byte *_data;
-	int _dataSize;
-	bool _isGM;
-
-	// Start MIDI File
-	void sndMidiStart();
-
-	// Stop MIDI File
-	void sndMidiStop();
-public:
-	MusicPlayer(PrinceEngine *vm);
-	~MusicPlayer();
-
-	void loadMidi(const char *);
-	void killMidi();
-
-	virtual void send(uint32 b);
-	virtual void sendToChannel(byte channel, uint32 b);
-
-	static const char *_musTable[];
-	static const uint8 _musRoomTable[];
-};
-
-} // End of namespace Prince
-
-#endif


Commit: faf579c48ffe7dfb8f49130cf30b47f27156acc3
    https://github.com/scummvm/scummvm/commit/faf579c48ffe7dfb8f49130cf30b47f27156acc3
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2018-05-05T23:17:34+02:00

Commit Message:
PRINCE: Move resource loading methods to separate file

Changed paths:
  A engines/prince/resources.cpp
    engines/prince/module.mk
    engines/prince/prince.cpp


diff --git a/engines/prince/module.mk b/engines/prince/module.mk
index 6e9e80d..1a9e4ac 100644
--- a/engines/prince/module.mk
+++ b/engines/prince/module.mk
@@ -17,6 +17,7 @@ MODULE_OBJS = \
 	object.o \
 	prince.o \
 	pscr.o \
+	resources.o \
 	saveload.o \
 	script.o \
 	variatxt.o \
diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp
index fcdf3f5..18fea8a 100644
--- a/engines/prince/prince.cpp
+++ b/engines/prince/prince.cpp
@@ -57,7 +57,6 @@
 #include "prince/cursor.h"
 #include "prince/archive.h"
 #include "prince/hero.h"
-#include "prince/resource.h"
 #include "prince/animation.h"
 #include "prince/option_text.h"
 #include "prince/curve_values.h"
@@ -469,142 +468,6 @@ void PrinceEngine::pauseEngineIntern(bool pause) {
 	}
 }
 
-bool AnimListItem::loadFromStream(Common::SeekableReadStream &stream) {
-	int32 pos = stream.pos();
-
-	uint16 type = stream.readUint16LE();
-	if (type == 0xFFFF) {
-		return false;
-	}
-	_type = type;
-	_fileNumber = stream.readUint16LE();
-	_startPhase = stream.readUint16LE();
-	_endPhase = stream.readUint16LE();
-	_loopPhase = stream.readUint16LE();
-	_x = stream.readSint16LE();
-	_y = stream.readSint16LE();
-	_loopType = stream.readUint16LE();
-	_nextAnim = stream.readUint16LE();
-	_flags = stream.readUint16LE();
-
-	//debug("AnimListItem type %d, fileNumber %d, x %d, y %d, flags %d", _type, _fileNumber, _x, _y, _flags);
-	//debug("startPhase %d, endPhase %d, loopPhase %d", _startPhase, _endPhase, _loopPhase);
-
-	// 32 byte aligment
-	stream.seek(pos + 32);
-
-	return true;
-}
-
-bool PrinceEngine::loadLocation(uint16 locationNr) {
-
-	blackPalette();
-
-	_flicPlayer.close();
-
-	memset(_textSlots, 0, sizeof(_textSlots));
-	freeAllSamples();
-
-	debugEngine("PrinceEngine::loadLocation %d", locationNr);
-	const Common::FSNode gameDataDir(ConfMan.get("path"));
-	SearchMan.remove(Common::String::format("%02d", _locationNr));
-
-	_locationNr = locationNr;
-	_debugger->_locationNr = locationNr;
-
-	_flags->setFlagValue(Flags::CURRROOM, _locationNr);
-	_interpreter->stopBg();
-
-	changeCursor(0);
-
-	const Common::String locationNrStr = Common::String::format("%02d", _locationNr);
-	debugEngine("loadLocation %s", locationNrStr.c_str());
-
-	PtcArchive *locationArchive = new PtcArchive();
-	if (!locationArchive->open(locationNrStr + "/databank.ptc"))
-		error("Can't open location %s", locationNrStr.c_str());
-
-	SearchMan.add(locationNrStr, locationArchive);
-
-	loadMusic(_locationNr);
-
-	// load location background, replace old one
-	Resource::loadResource(_roomBmp, "room", true);
-	if (_roomBmp->getSurface()) {
-		_sceneWidth = _roomBmp->getSurface()->w;
-	}
-
-	loadZoom(_zoomBitmap, kZoomBitmapLen, "zoom");
-	loadShadow(_shadowBitmap, kShadowBitmapSize, "shadow", "shadow2");
-	loadTrans(_transTable, "trans");
-	loadPath("path");
-
-	for (uint32 i = 0; i < _pscrList.size(); i++) {
-		delete _pscrList[i];
-	}
-	_pscrList.clear();
-	Resource::loadResource(_pscrList, "pscr.lst", false);
-
-	loadMobPriority("mobpri");
-
-	_mobList.clear();
-	if (getGameType() == kPrinceDataDE) {
-		const Common::String mobLstName = Common::String::format("mob%02d.lst", _locationNr);
-		debug("name: %s", mobLstName.c_str());
-		Resource::loadResource(_mobList, mobLstName.c_str(), false);
-	} else if (getGameType() == kPrinceDataPL) {
-		Resource::loadResource(_mobList, "mob.lst", false);
-	}
-	if (getFeatures() & GF_TRANSLATED) {
-		// update Mob texts for translated version
-		setMobTranslationTexts();
-	}
-
-	_animList.clear();
-	Resource::loadResource(_animList, "anim.lst", false);
-
-	for (uint32 i = 0; i < _objList.size(); i++) {
-		delete _objList[i];
-	}
-	_objList.clear();
-	Resource::loadResource(_objList, "obj.lst", false);
-
-	_room->loadRoom(_script->getRoomOffset(_locationNr));
-
-	for (uint i = 0; i < _maskList.size(); i++) {
-		free(_maskList[i]._data);
-	}
-	_maskList.clear();
-	_script->loadAllMasks(_maskList, _room->_nak);
-
-	_picWindowX = 0;
-
-	_lightX = _script->getLightX(_locationNr);
-	_lightY = _script->getLightY(_locationNr);
-	setShadowScale(_script->getShadowScale(_locationNr));
-
-	for (uint i = 0; i < _mobList.size(); i++) {
-		_mobList[i]._visible = _script->getMobVisible(_room->_mobs, i);
-	}
-
-	_script->installObjects(_room->_obj);
-
-	freeAllNormAnims();
-
-	clearBackAnimList();
-	_script->installBackAnims(_backAnimList, _room->_backAnim);
-
-	_graph->makeShadowTable(70, _graph->_shadowTable70);
-	_graph->makeShadowTable(50, _graph->_shadowTable50);
-
-	_mainHero->freeOldMove();
-	_secondHero->freeOldMove();
-
-	_mainHero->scrollHero();
-
-	return true;
-}
-
 void PrinceEngine::setShadowScale(int32 shadowScale) {
 	shadowScale = 100 - shadowScale;
 	if (!shadowScale) {
@@ -886,156 +749,6 @@ void PrinceEngine::setVoice(uint16 slot, uint32 sampleSlot, uint16 flag) {
 	loadVoice(slot, sampleSlot, sampleName);
 }
 
-bool PrinceEngine::loadAnim(uint16 animNr, bool loop) {
-	Common::String streamName = Common::String::format("AN%02d", animNr);
-	Common::SeekableReadStream *flicStream = SearchMan.createReadStreamForMember(streamName);
-
-	if (!flicStream) {
-		error("Can't open %s", streamName.c_str());
-		return false;
-	}
-
-	if (!_flicPlayer.loadStream(flicStream)) {
-		error("Can't load flic stream %s", streamName.c_str());
-	}
-
-	debugEngine("%s loaded", streamName.c_str());
-	_flicLooped = loop;
-	_flicPlayer.start();
-	playNextFLCFrame();
-	return true;
-}
-
-bool PrinceEngine::loadZoom(byte *zoomBitmap, uint32 dataSize, const char *resourceName) {
-	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName);
-	if (!stream) {
-		delete stream;
-		return false;
-	}
-	if (stream->read(zoomBitmap, dataSize) != dataSize) {
-		free(zoomBitmap);
-		delete stream;
-		return false;
-	}
-	delete stream;
-	return true;
-}
-
-bool PrinceEngine::loadShadow(byte *shadowBitmap, uint32 dataSize, const char *resourceName1, const char *resourceName2) {
-	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName1);
-	if (!stream) {
-		delete stream;
-		return false;
-	}
-
-	if (stream->read(shadowBitmap, dataSize) != dataSize) {
-		free(shadowBitmap);
-		delete stream;
-		return false;
-	}
-
-	Common::SeekableReadStream *stream2 = SearchMan.createReadStreamForMember(resourceName2);
-	if (!stream2) {
-		delete stream;
-		delete stream2;
-		return false;
-	}
-
-	byte *shadowBitmap2 = shadowBitmap + dataSize;
-	if (stream2->read(shadowBitmap2, dataSize) != dataSize) {
-		free(shadowBitmap);
-		delete stream;
-		delete stream2;
-		return false;
-	}
-
-	delete stream;
-	delete stream2;
-	return true;
-}
-
-bool PrinceEngine::loadTrans(byte *transTable, const char *resourceName) {
-	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName);
-	if (!stream) {
-		delete stream;
-		for (int i = 0; i < 256; i++) {
-			for (int j = 0; j < 256; j++) {
-				transTable[i * 256 + j] = j;
-			}
-		}
-		return true;
-	}
-	if (stream->read(transTable, kTransTableSize) != kTransTableSize) {
-		delete stream;
-		return false;
-	}
-	delete stream;
-	return true;
-}
-
-bool PrinceEngine::loadPath(const char *resourceName) {
-	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName);
-	if (!stream) {
-		delete stream;
-		return false;
-	}
-	if (stream->read(_roomPathBitmap, kPathBitmapLen) != kPathBitmapLen) {
-		delete stream;
-		return false;
-	}
-	delete stream;
-	return true;
-}
-
-bool PrinceEngine::loadAllInv() {
-	for (int i = 0; i < kMaxInv; i++) {
-		InvItem tempInvItem;
-
-		const Common::String invStreamName = Common::String::format("INV%02d", i);
-		Common::SeekableReadStream *invStream = SearchMan.createReadStreamForMember(invStreamName);
-		if (!invStream) {
-			delete invStream;
-			return true;
-		}
-
-		tempInvItem._x = invStream->readUint16LE();
-		tempInvItem._y = invStream->readUint16LE();
-		int width = invStream->readUint16LE();
-		int height = invStream->readUint16LE();
-		tempInvItem._surface = new Graphics::Surface();
-		tempInvItem._surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
-
-		for (int h = 0; h < tempInvItem._surface->h; h++) {
-			invStream->read(tempInvItem._surface->getBasePtr(0, h), tempInvItem._surface->w);
-		}
-
-		_allInvList.push_back(tempInvItem);
-		delete invStream;
-	}
-
-	return true;
-}
-
-bool PrinceEngine::loadMobPriority(const char *resourceName) {
-	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName);
-	if (!stream) {
-		delete stream;
-		return false;
-	}
-
-	_mobPriorityList.clear();
-	uint mobId;
-	while (1) {
-		mobId = stream->readUint32LE();
-		if (mobId == 0xFFFFFFFF) {
-			break;
-		}
-		_mobPriorityList.push_back(mobId);
-	}
-	delete stream;
-	return true;
-}
-
 void PrinceEngine::loadMobTranslationTexts() {
 	Common::SeekableReadStream *mobTranslationStream = SearchMan.createReadStreamForMember("mob_translate.dat");
 	if (!mobTranslationStream) {
diff --git a/engines/prince/resources.cpp b/engines/prince/resources.cpp
new file mode 100644
index 0000000..bb3db04
--- /dev/null
+++ b/engines/prince/resources.cpp
@@ -0,0 +1,321 @@
+/* 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 "common/config-manager.h"
+
+#include "prince/prince.h"
+#include "prince/graphics.h"
+#include "prince/debugger.h"
+#include "prince/script.h"
+#include "prince/hero.h"
+#include "prince/resource.h"
+#include "prince/archive.h"
+
+namespace Prince {
+
+bool AnimListItem::loadFromStream(Common::SeekableReadStream &stream) {
+	int32 pos = stream.pos();
+
+	uint16 type = stream.readUint16LE();
+	if (type == 0xFFFF) {
+		return false;
+	}
+	_type = type;
+	_fileNumber = stream.readUint16LE();
+	_startPhase = stream.readUint16LE();
+	_endPhase = stream.readUint16LE();
+	_loopPhase = stream.readUint16LE();
+	_x = stream.readSint16LE();
+	_y = stream.readSint16LE();
+	_loopType = stream.readUint16LE();
+	_nextAnim = stream.readUint16LE();
+	_flags = stream.readUint16LE();
+
+	//debug("AnimListItem type %d, fileNumber %d, x %d, y %d, flags %d", _type, _fileNumber, _x, _y, _flags);
+	//debug("startPhase %d, endPhase %d, loopPhase %d", _startPhase, _endPhase, _loopPhase);
+
+	// 32 byte aligment
+	stream.seek(pos + 32);
+
+	return true;
+}
+
+bool PrinceEngine::loadLocation(uint16 locationNr) {
+
+	blackPalette();
+
+	_flicPlayer.close();
+
+	memset(_textSlots, 0, sizeof(_textSlots));
+	freeAllSamples();
+
+	debugEngine("PrinceEngine::loadLocation %d", locationNr);
+	const Common::FSNode gameDataDir(ConfMan.get("path"));
+	SearchMan.remove(Common::String::format("%02d", _locationNr));
+
+	_locationNr = locationNr;
+	_debugger->_locationNr = locationNr;
+
+	_flags->setFlagValue(Flags::CURRROOM, _locationNr);
+	_interpreter->stopBg();
+
+	changeCursor(0);
+
+	const Common::String locationNrStr = Common::String::format("%02d", _locationNr);
+	debugEngine("loadLocation %s", locationNrStr.c_str());
+
+	PtcArchive *locationArchive = new PtcArchive();
+	if (!locationArchive->open(locationNrStr + "/databank.ptc"))
+		error("Can't open location %s", locationNrStr.c_str());
+
+	SearchMan.add(locationNrStr, locationArchive);
+
+	loadMusic(_locationNr);
+
+	// load location background, replace old one
+	Resource::loadResource(_roomBmp, "room", true);
+	if (_roomBmp->getSurface()) {
+		_sceneWidth = _roomBmp->getSurface()->w;
+	}
+
+	loadZoom(_zoomBitmap, kZoomBitmapLen, "zoom");
+	loadShadow(_shadowBitmap, kShadowBitmapSize, "shadow", "shadow2");
+	loadTrans(_transTable, "trans");
+	loadPath("path");
+
+	for (uint32 i = 0; i < _pscrList.size(); i++) {
+		delete _pscrList[i];
+	}
+	_pscrList.clear();
+	Resource::loadResource(_pscrList, "pscr.lst", false);
+
+	loadMobPriority("mobpri");
+
+	_mobList.clear();
+	if (getGameType() == kPrinceDataDE) {
+		const Common::String mobLstName = Common::String::format("mob%02d.lst", _locationNr);
+		debug("name: %s", mobLstName.c_str());
+		Resource::loadResource(_mobList, mobLstName.c_str(), false);
+	} else if (getGameType() == kPrinceDataPL) {
+		Resource::loadResource(_mobList, "mob.lst", false);
+	}
+	if (getFeatures() & GF_TRANSLATED) {
+		// update Mob texts for translated version
+		setMobTranslationTexts();
+	}
+
+	_animList.clear();
+	Resource::loadResource(_animList, "anim.lst", false);
+
+	for (uint32 i = 0; i < _objList.size(); i++) {
+		delete _objList[i];
+	}
+	_objList.clear();
+	Resource::loadResource(_objList, "obj.lst", false);
+
+	_room->loadRoom(_script->getRoomOffset(_locationNr));
+
+	for (uint i = 0; i < _maskList.size(); i++) {
+		free(_maskList[i]._data);
+	}
+	_maskList.clear();
+	_script->loadAllMasks(_maskList, _room->_nak);
+
+	_picWindowX = 0;
+
+	_lightX = _script->getLightX(_locationNr);
+	_lightY = _script->getLightY(_locationNr);
+	setShadowScale(_script->getShadowScale(_locationNr));
+
+	for (uint i = 0; i < _mobList.size(); i++) {
+		_mobList[i]._visible = _script->getMobVisible(_room->_mobs, i);
+	}
+
+	_script->installObjects(_room->_obj);
+
+	freeAllNormAnims();
+
+	clearBackAnimList();
+	_script->installBackAnims(_backAnimList, _room->_backAnim);
+
+	_graph->makeShadowTable(70, _graph->_shadowTable70);
+	_graph->makeShadowTable(50, _graph->_shadowTable50);
+
+	_mainHero->freeOldMove();
+	_secondHero->freeOldMove();
+
+	_mainHero->scrollHero();
+
+	return true;
+}
+
+bool PrinceEngine::loadAnim(uint16 animNr, bool loop) {
+	Common::String streamName = Common::String::format("AN%02d", animNr);
+	Common::SeekableReadStream *flicStream = SearchMan.createReadStreamForMember(streamName);
+
+	if (!flicStream) {
+		error("Can't open %s", streamName.c_str());
+		return false;
+	}
+
+	if (!_flicPlayer.loadStream(flicStream)) {
+		error("Can't load flic stream %s", streamName.c_str());
+	}
+
+	debugEngine("%s loaded", streamName.c_str());
+	_flicLooped = loop;
+	_flicPlayer.start();
+	playNextFLCFrame();
+	return true;
+}
+
+bool PrinceEngine::loadZoom(byte *zoomBitmap, uint32 dataSize, const char *resourceName) {
+	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName);
+	if (!stream) {
+		delete stream;
+		return false;
+	}
+	if (stream->read(zoomBitmap, dataSize) != dataSize) {
+		free(zoomBitmap);
+		delete stream;
+		return false;
+	}
+	delete stream;
+	return true;
+}
+
+bool PrinceEngine::loadShadow(byte *shadowBitmap, uint32 dataSize, const char *resourceName1, const char *resourceName2) {
+	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName1);
+	if (!stream) {
+		delete stream;
+		return false;
+	}
+
+	if (stream->read(shadowBitmap, dataSize) != dataSize) {
+		free(shadowBitmap);
+		delete stream;
+		return false;
+	}
+
+	Common::SeekableReadStream *stream2 = SearchMan.createReadStreamForMember(resourceName2);
+	if (!stream2) {
+		delete stream;
+		delete stream2;
+		return false;
+	}
+
+	byte *shadowBitmap2 = shadowBitmap + dataSize;
+	if (stream2->read(shadowBitmap2, dataSize) != dataSize) {
+		free(shadowBitmap);
+		delete stream;
+		delete stream2;
+		return false;
+	}
+
+	delete stream;
+	delete stream2;
+	return true;
+}
+
+bool PrinceEngine::loadTrans(byte *transTable, const char *resourceName) {
+	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName);
+	if (!stream) {
+		delete stream;
+		for (int i = 0; i < 256; i++) {
+			for (int j = 0; j < 256; j++) {
+				transTable[i * 256 + j] = j;
+			}
+		}
+		return true;
+	}
+	if (stream->read(transTable, kTransTableSize) != kTransTableSize) {
+		delete stream;
+		return false;
+	}
+	delete stream;
+	return true;
+}
+
+bool PrinceEngine::loadPath(const char *resourceName) {
+	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName);
+	if (!stream) {
+		delete stream;
+		return false;
+	}
+	if (stream->read(_roomPathBitmap, kPathBitmapLen) != kPathBitmapLen) {
+		delete stream;
+		return false;
+	}
+	delete stream;
+	return true;
+}
+
+bool PrinceEngine::loadAllInv() {
+	for (int i = 0; i < kMaxInv; i++) {
+		InvItem tempInvItem;
+
+		const Common::String invStreamName = Common::String::format("INV%02d", i);
+		Common::SeekableReadStream *invStream = SearchMan.createReadStreamForMember(invStreamName);
+		if (!invStream) {
+			delete invStream;
+			return true;
+		}
+
+		tempInvItem._x = invStream->readUint16LE();
+		tempInvItem._y = invStream->readUint16LE();
+		int width = invStream->readUint16LE();
+		int height = invStream->readUint16LE();
+		tempInvItem._surface = new Graphics::Surface();
+		tempInvItem._surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+
+		for (int h = 0; h < tempInvItem._surface->h; h++) {
+			invStream->read(tempInvItem._surface->getBasePtr(0, h), tempInvItem._surface->w);
+		}
+
+		_allInvList.push_back(tempInvItem);
+		delete invStream;
+	}
+
+	return true;
+}
+
+bool PrinceEngine::loadMobPriority(const char *resourceName) {
+	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName);
+	if (!stream) {
+		delete stream;
+		return false;
+	}
+
+	_mobPriorityList.clear();
+	uint mobId;
+	while (1) {
+		mobId = stream->readUint32LE();
+		if (mobId == 0xFFFFFFFF) {
+			break;
+		}
+		_mobPriorityList.push_back(mobId);
+	}
+	delete stream;
+	return true;
+}
+
+} // End of namespace Prince


Commit: 951c365591bd75e8b2a16eb96c32a24c232153d4
    https://github.com/scummvm/scummvm/commit/951c365591bd75e8b2a16eb96c32a24c232153d4
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2018-05-05T23:17:34+02:00

Commit Message:
PRINCE: Move cursor manipulation to cursor.cpp

Changed paths:
    engines/prince/cursor.cpp
    engines/prince/prince.cpp


diff --git a/engines/prince/cursor.cpp b/engines/prince/cursor.cpp
index ab3a52e..a4e58dc 100644
--- a/engines/prince/cursor.cpp
+++ b/engines/prince/cursor.cpp
@@ -20,7 +20,12 @@
  *
  */
 
+#include "graphics/cursorman.h"
+
+#include "prince/prince.h"
 #include "prince/cursor.h"
+#include "prince/debugger.h"
+#include "prince/script.h"
 
 #include "common/debug.h"
 
@@ -51,4 +56,98 @@ bool Cursor::loadStream(Common::SeekableReadStream &stream) {
 	return true;
 }
 
+void PrinceEngine::changeCursor(uint16 curId) {
+	_debugger->_cursorNr = curId;
+	_mouseFlag = curId;
+	_flags->setFlagValue(Flags::MOUSEENABLED, curId);
+
+	const Graphics::Surface *curSurface = nullptr;
+
+	switch (curId) {
+	default:
+		error("Unknown cursor Id: %d", curId);
+	case 0:
+		CursorMan.showMouse(false);
+		_optionsFlag = 0;
+		_selectedMob = -1;
+		return;
+	case 1:
+		curSurface = _cursor1->getSurface();
+		break;
+	case 2:
+		curSurface = _cursor2;
+		break;
+	case 3:
+		curSurface = _cursor3->getSurface();
+		Common::Point mousePos = _system->getEventManager()->getMousePos();
+		mousePos.x = CLIP(mousePos.x, (int16) 315, (int16) 639);
+		mousePos.y = CLIP(mousePos.y, (int16) 0, (int16) 170);
+		_system->warpMouse(mousePos.x, mousePos.y);
+		break;
+	}
+
+	CursorMan.replaceCursorPalette(_roomBmp->getPalette(), 0, 255);
+	CursorMan.replaceCursor(
+		curSurface->getBasePtr(0, 0),
+		curSurface->w, curSurface->h,
+		0, 0,
+		255, false,
+		&curSurface->format
+	);
+	CursorMan.showMouse(true);
+}
+
+void PrinceEngine::makeInvCursor(int itemNr) {
+	const Graphics::Surface *cur1Surface = _cursor1->getSurface();
+	int cur1W = cur1Surface->w;
+	int cur1H = cur1Surface->h;
+	const Common::Rect cur1Rect(0, 0, cur1W, cur1H);
+
+	const Graphics::Surface *itemSurface = _allInvList[itemNr].getSurface();
+	int itemW = itemSurface->w;
+	int itemH = itemSurface->h;
+
+	int cur2W = cur1W + itemW / 2;
+	int cur2H = cur1H + itemH / 2;
+
+	if (_cursor2 != nullptr) {
+		_cursor2->free();
+		delete _cursor2;
+	}
+	_cursor2 = new Graphics::Surface();
+	_cursor2->create(cur2W, cur2H, Graphics::PixelFormat::createFormatCLUT8());
+	Common::Rect cur2Rect(0, 0, cur2W, cur2H);
+	_cursor2->fillRect(cur2Rect, 255);
+	_cursor2->copyRectToSurface(*cur1Surface, 0, 0, cur1Rect);
+
+	const byte *src1 = (const byte *)itemSurface->getBasePtr(0, 0);
+	byte *dst1 = (byte *)_cursor2->getBasePtr(cur1W, cur1H);
+
+	if (itemH % 2) {
+		itemH--;
+	}
+	if (itemW % 2) {
+		itemW--;
+	}
+
+	for (int y = 0; y < itemH; y++) {
+		const byte *src2 = src1;
+		byte *dst2 = dst1;
+		if (y % 2 == 0) {
+			for (int x = 0; x < itemW; x++, src2++) {
+				if (x % 2 == 0) {
+					if (*src2) {
+						*dst2 = *src2;
+					} else {
+						*dst2 = 255;
+					}
+					dst2++;
+				}
+			}
+			dst1 += _cursor2->pitch;
+		}
+		src1 += itemSurface->pitch;
+	}
+}
+
 } // End of namespace Prince
diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp
index 18fea8a..9e3b73e 100644
--- a/engines/prince/prince.cpp
+++ b/engines/prince/prince.cpp
@@ -32,7 +32,6 @@
 #include "common/substream.h"
 #include "common/str.h"
 
-#include "graphics/cursorman.h"
 #include "graphics/surface.h"
 #include "graphics/palette.h"
 #include "graphics/pixelformat.h"
@@ -484,100 +483,6 @@ void PrinceEngine::plotShadowLinePoint(int x, int y, int color, void *data) {
 	vm->_shadLineLen++;
 }
 
-void PrinceEngine::changeCursor(uint16 curId) {
-	_debugger->_cursorNr = curId;
-	_mouseFlag = curId;
-	_flags->setFlagValue(Flags::MOUSEENABLED, curId);
-
-	const Graphics::Surface *curSurface = nullptr;
-
-	switch (curId) {
-	default:
-		error("Unknown cursor Id: %d", curId);
-	case 0:
-		CursorMan.showMouse(false);
-		_optionsFlag = 0;
-		_selectedMob = -1;
-		return;
-	case 1:
-		curSurface = _cursor1->getSurface();
-		break;
-	case 2:
-		curSurface = _cursor2;
-		break;
-	case 3:
-		curSurface = _cursor3->getSurface();
-		Common::Point mousePos = _system->getEventManager()->getMousePos();
-		mousePos.x = CLIP(mousePos.x, (int16) 315, (int16) 639);
-		mousePos.y = CLIP(mousePos.y, (int16) 0, (int16) 170);
-		_system->warpMouse(mousePos.x, mousePos.y);
-		break;
-	}
-
-	CursorMan.replaceCursorPalette(_roomBmp->getPalette(), 0, 255);
-	CursorMan.replaceCursor(
-		curSurface->getBasePtr(0, 0),
-		curSurface->w, curSurface->h,
-		0, 0,
-		255, false,
-		&curSurface->format
-	);
-	CursorMan.showMouse(true);
-}
-
-void PrinceEngine::makeInvCursor(int itemNr) {
-	const Graphics::Surface *cur1Surface = _cursor1->getSurface();
-	int cur1W = cur1Surface->w;
-	int cur1H = cur1Surface->h;
-	const Common::Rect cur1Rect(0, 0, cur1W, cur1H);
-
-	const Graphics::Surface *itemSurface = _allInvList[itemNr].getSurface();
-	int itemW = itemSurface->w;
-	int itemH = itemSurface->h;
-
-	int cur2W = cur1W + itemW / 2;
-	int cur2H = cur1H + itemH / 2;
-
-	if (_cursor2 != nullptr) {
-		_cursor2->free();
-		delete _cursor2;
-	}
-	_cursor2 = new Graphics::Surface();
-	_cursor2->create(cur2W, cur2H, Graphics::PixelFormat::createFormatCLUT8());
-	Common::Rect cur2Rect(0, 0, cur2W, cur2H);
-	_cursor2->fillRect(cur2Rect, 255);
-	_cursor2->copyRectToSurface(*cur1Surface, 0, 0, cur1Rect);
-
-	const byte *src1 = (const byte *)itemSurface->getBasePtr(0, 0);
-	byte *dst1 = (byte *)_cursor2->getBasePtr(cur1W, cur1H);
-
-	if (itemH % 2) {
-		itemH--;
-	}
-	if (itemW % 2) {
-		itemW--;
-	}
-
-	for (int y = 0; y < itemH; y++) {
-		const byte *src2 = src1;
-		byte *dst2 = dst1;
-		if (y % 2 == 0) {
-			for (int x = 0; x < itemW; x++, src2++) {
-				if (x % 2 == 0) {
-					if (*src2) {
-						*dst2 = *src2;
-					} else {
-						*dst2 = 255;
-					}
-					dst2++;
-				}
-			}
-			dst1 += _cursor2->pitch;
-		}
-		src1 += itemSurface->pitch;
-	}
-}
-
 bool PrinceEngine::loadMusic(int musNumber) {
 	uint8 midiNumber = MusicPlayer::_musRoomTable[musNumber];
 	if (midiNumber) {


Commit: 67abcc36a7eb7b3eecc3a557f72e26013a499e72
    https://github.com/scummvm/scummvm/commit/67abcc36a7eb7b3eecc3a557f72e26013a499e72
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2018-05-05T23:17:35+02:00

Commit Message:
PRINCE: Moved audio-related methods to separate files

Changed paths:
  A engines/prince/sound.cpp
    engines/prince/module.mk
    engines/prince/music.cpp
    engines/prince/prince.cpp


diff --git a/engines/prince/module.mk b/engines/prince/module.mk
index 1a9e4ac..d045c1f 100644
--- a/engines/prince/module.mk
+++ b/engines/prince/module.mk
@@ -20,6 +20,7 @@ MODULE_OBJS = \
 	resources.o \
 	saveload.o \
 	script.o \
+	sound.o \
 	variatxt.o \
 	videoplayer.o
 
diff --git a/engines/prince/music.cpp b/engines/prince/music.cpp
index 6d208e2..ca72e9c 100644
--- a/engines/prince/music.cpp
+++ b/engines/prince/music.cpp
@@ -20,6 +20,7 @@
  *
  */
 
+#include "prince/prince.h"
 #include "prince/music.h"
 #include "prince/musNum.h"
 
@@ -207,4 +208,26 @@ void MusicPlayer::sendToChannel(byte channel, uint32 b) {
 		_channelsTable[channel]->send(b);
 }
 
+bool PrinceEngine::loadMusic(int musNumber) {
+	uint8 midiNumber = MusicPlayer::_musRoomTable[musNumber];
+	if (midiNumber) {
+		if (midiNumber != 100) {
+			 if (_currentMidi != midiNumber) {
+				_currentMidi = midiNumber;
+				const char *musName = MusicPlayer::_musTable[_currentMidi];
+				_midiPlayer->loadMidi(musName);
+			 }
+		}
+	} else {
+		stopMusic();
+	}
+	return true;
+}
+
+void PrinceEngine::stopMusic() {
+	if (_midiPlayer->isPlaying()) {
+		_midiPlayer->stop();
+	}
+}
+
 } // End of namespace Prince
diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp
index 9e3b73e..321c4f1 100644
--- a/engines/prince/prince.cpp
+++ b/engines/prince/prince.cpp
@@ -38,9 +38,6 @@
 
 #include "engines/util.h"
 
-#include "audio/audiostream.h"
-#include "audio/decoders/wave.h"
-
 #include "prince/prince.h"
 #include "prince/font.h"
 #include "prince/graphics.h"
@@ -483,28 +480,6 @@ void PrinceEngine::plotShadowLinePoint(int x, int y, int color, void *data) {
 	vm->_shadLineLen++;
 }
 
-bool PrinceEngine::loadMusic(int musNumber) {
-	uint8 midiNumber = MusicPlayer::_musRoomTable[musNumber];
-	if (midiNumber) {
-		if (midiNumber != 100) {
-			 if (_currentMidi != midiNumber) {
-				_currentMidi = midiNumber;
-				const char *musName = MusicPlayer::_musTable[_currentMidi];
-				_midiPlayer->loadMidi(musName);
-			 }
-		}
-	} else {
-		stopMusic();
-	}
-	return true;
-}
-
-void PrinceEngine::stopMusic() {
-	if (_midiPlayer->isPlaying()) {
-		_midiPlayer->stop();
-	}
-}
-
 bool PrinceEngine::playNextFLCFrame() {
 	if (!_flicPlayer.isVideoLoaded())
 		return false;
@@ -525,135 +500,6 @@ bool PrinceEngine::playNextFLCFrame() {
 	return true;
 }
 
-void PrinceEngine::playSample(uint16 sampleId, uint16 loopType) {
-	if (_audioStream[sampleId]) {
-		if (_mixer->isSoundIDActive(sampleId)) {
-			return;
-		}
-		_audioStream[sampleId]->rewind();
-		if (sampleId < 28) {
-			_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle[sampleId], _audioStream[sampleId], sampleId, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
-		} else {
-			_mixer->playStream(Audio::Mixer::kSpeechSoundType, &_soundHandle[sampleId], _audioStream[sampleId], sampleId, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
-		}
-	}
-}
-
-void PrinceEngine::stopSample(uint16 sampleId) {
-	_mixer->stopID(sampleId);
-}
-
-void PrinceEngine::stopAllSamples() {
-	_mixer->stopAll();
-}
-
-void PrinceEngine::freeSample(uint16 sampleId) {
-	stopSample(sampleId);
-	if (_audioStream[sampleId] != nullptr) {
-		delete _audioStream[sampleId];
-		_audioStream[sampleId] = nullptr;
-	}
-}
-
-void PrinceEngine::freeAllSamples() {
-	for (int sampleId = 0; sampleId < kMaxSamples; sampleId++) {
-		freeSample(sampleId);
-	}
-}
-
-bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamName) {
-	// FIXME: This is just a workaround streamName is a path
-	// SOUND\\SCIERKA1.WAV for now only last path component is used
-	Common::String normalizedPath = lastPathComponent(streamName, '\\');
-
-	// WALKAROUND: Wrong name in script, not existing sound in data files
-	if (!normalizedPath.compareTo("9997BEKA.WAV")) {
-		return 0;
-	}
-
-	debugEngine("loadSample slot %d, name %s", sampleSlot, normalizedPath.c_str());
-
-	freeSample(sampleSlot);
-	Common::SeekableReadStream *sampleStream = SearchMan.createReadStreamForMember(normalizedPath);
-	if (sampleStream == nullptr) {
-		delete sampleStream;
-		error("Can't load sample %s to slot %d", normalizedPath.c_str(), sampleSlot);
-	}
-	_audioStream[sampleSlot] = Audio::makeWAVStream(sampleStream, DisposeAfterUse::NO);
-	delete sampleStream;
-	return true;
-}
-
-bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::String &streamName) {
-	debugEngine("Loading wav %s slot %d", streamName.c_str(), slot);
-
-	if (slot >= kMaxTexts) {
-		error("Text slot bigger than MAXTEXTS %d", kMaxTexts - 1);
-		return false;
-	}
-
-	freeSample(sampleSlot);
-	Common::SeekableReadStream *sampleStream = SearchMan.createReadStreamForMember(streamName);
-	if (sampleStream == nullptr) {
-		debug("Can't open %s", streamName.c_str());
-		return false;
-	}
-
-	uint32 id = sampleStream->readUint32LE();
-	if (id != MKTAG('F', 'F', 'I', 'R')) {
-		error("It's not RIFF file %s", streamName.c_str());
-		return false;
-	}
-
-	sampleStream->skip(0x20);
-	id = sampleStream->readUint32LE();
-	if (id != MKTAG('a', 't', 'a', 'd')) {
-		error("No data section in %s id %04x", streamName.c_str(), id);
-		return false;
-	}
-
-	id = sampleStream->readUint32LE();
-	debugEngine("SetVoice slot %d time %04x", slot, id);
-	id <<= 3;
-	id /= 22050;
-	id += 2;
-
-	_textSlots[slot]._time = id;
-	if (!slot) {
-		_mainHero->_talkTime = id;
-	} else if (slot == 1) {
-		_secondHero->_talkTime = id;
-	}
-
-	debugEngine("SetVoice slot %d time %04x", slot, id);
-	sampleStream->seek(SEEK_SET);
-	_audioStream[sampleSlot] = Audio::makeWAVStream(sampleStream, DisposeAfterUse::NO);
-	delete sampleStream;
-	return true;
-}
-
-void PrinceEngine::setVoice(uint16 slot, uint32 sampleSlot, uint16 flag) {
-	Common::String sampleName;
-	uint32 currentString = _interpreter->getCurrentString();
-
-	if (currentString >= 80000) {
-		uint32 nr = currentString - 80000;
-		sampleName = Common::String::format("%02d0%02d-%02d.WAV", nr / 100, nr % 100, flag);
-	} else if (currentString >= 70000) {
-		sampleName = Common::String::format("inv%02d-01.WAV", currentString - 70000);
-	} else if (currentString >= 60000) {
-		sampleName = Common::String::format("M%04d-%02d.WAV", currentString - 60000, flag);
-	} else if (currentString >= 2000) {
-		return;
-	} else if (flag >= 100) {
-		sampleName = Common::String::format("%03d-%03d.WAV", currentString, flag);
-	} else {
-		sampleName = Common::String::format("%03d-%02d.WAV", currentString, flag);
-	}
-
-	loadVoice(slot, sampleSlot, sampleName);
-}
-
 void PrinceEngine::loadMobTranslationTexts() {
 	Common::SeekableReadStream *mobTranslationStream = SearchMan.createReadStreamForMember("mob_translate.dat");
 	if (!mobTranslationStream) {
diff --git a/engines/prince/sound.cpp b/engines/prince/sound.cpp
new file mode 100644
index 0000000..54eebdc
--- /dev/null
+++ b/engines/prince/sound.cpp
@@ -0,0 +1,161 @@
+/* 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 "audio/audiostream.h"
+#include "audio/decoders/wave.h"
+
+#include "prince/prince.h"
+#include "prince/hero.h"
+#include "prince/script.h"
+
+namespace Prince {
+
+void PrinceEngine::playSample(uint16 sampleId, uint16 loopType) {
+	if (_audioStream[sampleId]) {
+		if (_mixer->isSoundIDActive(sampleId)) {
+			return;
+		}
+		_audioStream[sampleId]->rewind();
+		if (sampleId < 28) {
+			_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle[sampleId], _audioStream[sampleId], sampleId, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
+		} else {
+			_mixer->playStream(Audio::Mixer::kSpeechSoundType, &_soundHandle[sampleId], _audioStream[sampleId], sampleId, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
+		}
+	}
+}
+
+void PrinceEngine::stopSample(uint16 sampleId) {
+	_mixer->stopID(sampleId);
+}
+
+void PrinceEngine::stopAllSamples() {
+	_mixer->stopAll();
+}
+
+void PrinceEngine::freeSample(uint16 sampleId) {
+	stopSample(sampleId);
+	if (_audioStream[sampleId] != nullptr) {
+		delete _audioStream[sampleId];
+		_audioStream[sampleId] = nullptr;
+	}
+}
+
+void PrinceEngine::freeAllSamples() {
+	for (int sampleId = 0; sampleId < kMaxSamples; sampleId++) {
+		freeSample(sampleId);
+	}
+}
+
+bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamName) {
+	// FIXME: This is just a workaround streamName is a path
+	// SOUND\\SCIERKA1.WAV for now only last path component is used
+	Common::String normalizedPath = lastPathComponent(streamName, '\\');
+
+	// WALKAROUND: Wrong name in script, not existing sound in data files
+	if (!normalizedPath.compareTo("9997BEKA.WAV")) {
+		return 0;
+	}
+
+	debugEngine("loadSample slot %d, name %s", sampleSlot, normalizedPath.c_str());
+
+	freeSample(sampleSlot);
+	Common::SeekableReadStream *sampleStream = SearchMan.createReadStreamForMember(normalizedPath);
+	if (sampleStream == nullptr) {
+		delete sampleStream;
+		error("Can't load sample %s to slot %d", normalizedPath.c_str(), sampleSlot);
+	}
+	_audioStream[sampleSlot] = Audio::makeWAVStream(sampleStream, DisposeAfterUse::NO);
+	delete sampleStream;
+	return true;
+}
+
+bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::String &streamName) {
+	debugEngine("Loading wav %s slot %d", streamName.c_str(), slot);
+
+	if (slot >= kMaxTexts) {
+		error("Text slot bigger than MAXTEXTS %d", kMaxTexts - 1);
+		return false;
+	}
+
+	freeSample(sampleSlot);
+	Common::SeekableReadStream *sampleStream = SearchMan.createReadStreamForMember(streamName);
+	if (sampleStream == nullptr) {
+		debug("Can't open %s", streamName.c_str());
+		return false;
+	}
+
+	uint32 id = sampleStream->readUint32LE();
+	if (id != MKTAG('F', 'F', 'I', 'R')) {
+		error("It's not RIFF file %s", streamName.c_str());
+		return false;
+	}
+
+	sampleStream->skip(0x20);
+	id = sampleStream->readUint32LE();
+	if (id != MKTAG('a', 't', 'a', 'd')) {
+		error("No data section in %s id %04x", streamName.c_str(), id);
+		return false;
+	}
+
+	id = sampleStream->readUint32LE();
+	debugEngine("SetVoice slot %d time %04x", slot, id);
+	id <<= 3;
+	id /= 22050;
+	id += 2;
+
+	_textSlots[slot]._time = id;
+	if (!slot) {
+		_mainHero->_talkTime = id;
+	} else if (slot == 1) {
+		_secondHero->_talkTime = id;
+	}
+
+	debugEngine("SetVoice slot %d time %04x", slot, id);
+	sampleStream->seek(SEEK_SET);
+	_audioStream[sampleSlot] = Audio::makeWAVStream(sampleStream, DisposeAfterUse::NO);
+	delete sampleStream;
+	return true;
+}
+
+void PrinceEngine::setVoice(uint16 slot, uint32 sampleSlot, uint16 flag) {
+	Common::String sampleName;
+	uint32 currentString = _interpreter->getCurrentString();
+
+	if (currentString >= 80000) {
+		uint32 nr = currentString - 80000;
+		sampleName = Common::String::format("%02d0%02d-%02d.WAV", nr / 100, nr % 100, flag);
+	} else if (currentString >= 70000) {
+		sampleName = Common::String::format("inv%02d-01.WAV", currentString - 70000);
+	} else if (currentString >= 60000) {
+		sampleName = Common::String::format("M%04d-%02d.WAV", currentString - 60000, flag);
+	} else if (currentString >= 2000) {
+		return;
+	} else if (flag >= 100) {
+		sampleName = Common::String::format("%03d-%03d.WAV", currentString, flag);
+	} else {
+		sampleName = Common::String::format("%03d-%02d.WAV", currentString, flag);
+	}
+
+	loadVoice(slot, sampleSlot, sampleName);
+}
+
+} // End of namespace Prince


Commit: 788a1fab82177d7964f4c16ca20366fa18a8bc6a
    https://github.com/scummvm/scummvm/commit/788a1fab82177d7964f4c16ca20366fa18a8bc6a
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2018-05-05T23:17:35+02:00

Commit Message:
PRINCE: More prince.cpp restructuring

Changed paths:
  A engines/prince/draw.cpp
    engines/prince/mob.cpp
    engines/prince/module.mk
    engines/prince/prince.cpp


diff --git a/engines/prince/draw.cpp b/engines/prince/draw.cpp
new file mode 100644
index 0000000..6d330f6
--- /dev/null
+++ b/engines/prince/draw.cpp
@@ -0,0 +1,705 @@
+/* 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 "graphics/palette.h"
+
+#include "prince/prince.h"
+
+#include "prince/animation.h"
+#include "prince/graphics.h"
+#include "prince/hero.h"
+#include "prince/script.h"
+
+namespace Prince {
+
+bool PrinceEngine::spriteCheck(int sprWidth, int sprHeight, int destX, int destY) {
+	destX -= _picWindowX;
+	destY -= _picWindowY;
+
+	 // if x1 is on visible part of screen
+	if (destX < 0) {
+		if (destX + sprWidth < 1) {
+			//x2 is negative - out of window
+			return false;
+		}
+	}
+	 // if x1 is outside of screen on right side
+	if (destX >= kNormalWidth) {
+		return false;
+	}
+
+	if (destY < 0) {
+		if (destY + sprHeight < 1) {
+			//y2 is negative - out of window
+			return false;
+		}
+	}
+	if (destY >= kNormalHeight) {
+		return false;
+	}
+
+	return true;
+}
+
+// CheckNak
+void PrinceEngine::checkMasks(int x1, int y1, int sprWidth, int sprHeight, int z) {
+	int x2 = x1 + sprWidth - 1;
+	int y2 = y1 + sprHeight - 1;
+	if (x1 < 0) {
+		x1 = 0;
+	}
+	for (uint i = 0; i < _maskList.size(); i++) {
+		if (!_maskList[i]._state && !_maskList[i]._flags) {
+			if (_maskList[i]._z > z) {
+				if (_maskList[i]._x1 <= x2 && _maskList[i]._x2 >= x1) {
+					if (_maskList[i]._y1 <= y2 && _maskList[i]._y2 >= y1) {
+						_maskList[i]._state = 1;
+					}
+				}
+			}
+		}
+	}
+}
+
+// ClsNak
+void PrinceEngine::clsMasks() {
+	for (uint i = 0; i < _maskList.size(); i++) {
+		if (_maskList[i]._state) {
+			_maskList[i]._state = 0;
+		}
+	}
+}
+
+// InsertNakladki
+void PrinceEngine::insertMasks(Graphics::Surface *originalRoomSurface) {
+	for (uint i = 0; i < _maskList.size(); i++) {
+		if (_maskList[i]._state) {
+			if (_maskList[i]._data != nullptr) {
+				showMask(i, originalRoomSurface);
+			} else {
+				error("insertMasks() - Wrong mask data- nr %d", i);
+			}
+		}
+	}
+}
+
+// ShowNak
+void PrinceEngine::showMask(int maskNr, Graphics::Surface *originalRoomSurface) {
+	if (!_maskList[maskNr]._flags) {
+		if (spriteCheck(_maskList[maskNr]._width, _maskList[maskNr]._height, _maskList[maskNr]._x1, _maskList[maskNr]._y1)) {
+			int destX = _maskList[maskNr]._x1 - _picWindowX;
+			int destY = _maskList[maskNr]._y1 - _picWindowY;
+			DrawNode newDrawNode;
+			newDrawNode.posX = destX;
+			newDrawNode.posY = destY;
+			newDrawNode.posZ = _maskList[maskNr]._z;
+			newDrawNode.width = _maskList[maskNr]._width;
+			newDrawNode.height = _maskList[maskNr]._height;
+			newDrawNode.s = nullptr;
+			newDrawNode.originalRoomSurface = originalRoomSurface;
+			newDrawNode.data = _maskList[maskNr].getMask();
+			newDrawNode.drawFunction = &_graph->drawMaskDrawNode;
+			_drawNodeList.push_back(newDrawNode);
+		}
+	}
+}
+
+void PrinceEngine::showSprite(Graphics::Surface *spriteSurface, int destX, int destY, int destZ) {
+	if (spriteCheck(spriteSurface->w, spriteSurface->h, destX, destY)) {
+		destX -= _picWindowX;
+		destY -= _picWindowY;
+		DrawNode newDrawNode;
+		newDrawNode.posX = destX;
+		newDrawNode.posY = destY;
+		newDrawNode.posZ = destZ;
+		newDrawNode.width = 0;
+		newDrawNode.height = 0;
+		newDrawNode.s = spriteSurface;
+		newDrawNode.originalRoomSurface = nullptr;
+		newDrawNode.data = _transTable;
+		newDrawNode.drawFunction = &_graph->drawTransparentWithTransDrawNode;
+		_drawNodeList.push_back(newDrawNode);
+	}
+}
+
+void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY, int destZ) {
+	if (spriteCheck(shadowSurface->w, shadowSurface->h, destX, destY)) {
+		destX -= _picWindowX;
+		destY -= _picWindowY;
+		DrawNode newDrawNode;
+		newDrawNode.posX = destX;
+		newDrawNode.posY = destY;
+		newDrawNode.posZ = destZ;
+		newDrawNode.width = 0;
+		newDrawNode.height = 0;
+		newDrawNode.s = shadowSurface;
+		newDrawNode.originalRoomSurface = nullptr;
+		newDrawNode.data = _graph->_shadowTable70;
+		newDrawNode.drawFunction = &_graph->drawAsShadowDrawNode;
+		_drawNodeList.push_back(newDrawNode);
+	}
+}
+
+void PrinceEngine::showAnim(Anim &anim) {
+	//ShowFrameCode
+	//ShowAnimFrame
+	int phase = anim._showFrame;
+	int phaseFrameIndex = anim._animData->getPhaseFrameIndex(phase);
+	int x = anim._x + anim._animData->getPhaseOffsetX(phase);
+	int y = anim._y + anim._animData->getPhaseOffsetY(phase);
+	int animFlag = anim._flags;
+	int checkMaskFlag = (animFlag & 1);
+	int maxFrontFlag = (animFlag & 2);
+	int specialZFlag = anim._nextAnim;
+	int z = anim._nextAnim;
+	Graphics::Surface *animSurface = anim._animData->getFrame(phaseFrameIndex);
+	int frameWidth = animSurface->w;
+	int frameHeight = animSurface->h;
+	int shadowZ = 0;
+
+	if (checkMaskFlag) {
+		if (!anim._nextAnim) {
+			z = y + frameHeight - 1;
+		}
+		checkMasks(x, y, frameWidth, frameHeight, z);
+	}
+
+	if (specialZFlag) {
+		z = specialZFlag;
+	} else if (maxFrontFlag) {
+		z = kMaxPicHeight + 1;
+	} else {
+		z = y + frameHeight - 1;
+	}
+	shadowZ = z;
+
+	anim._currX = x;
+	anim._currY = y;
+	anim._currW = frameWidth;
+	anim._currH = frameHeight;
+	showSprite(animSurface, x, y, z);
+
+	// make_special_shadow
+	if ((anim._flags & 0x80)) {
+		DrawNode newDrawNode;
+		newDrawNode.posX = x;
+		newDrawNode.posY = y + animSurface->h - anim._shadowBack;
+		newDrawNode.posZ = Hero::kHeroShadowZ;
+		newDrawNode.width = 0;
+		newDrawNode.height = 0;
+		newDrawNode.scaleValue = _scaleValue;
+		newDrawNode.originalRoomSurface = nullptr;
+		newDrawNode.data = this;
+		newDrawNode.drawFunction = &Hero::showHeroShadow;
+		newDrawNode.s = animSurface;
+		_drawNodeList.push_back(newDrawNode);
+	}
+
+	//ShowFrameCodeShadow
+	//ShowAnimFrameShadow
+	if (anim._shadowData != nullptr) {
+		int shadowPhaseFrameIndex = anim._shadowData->getPhaseFrameIndex(phase);
+		int shadowX = anim._shadowData->getBaseX() + anim._shadowData->getPhaseOffsetX(phase);
+		int shadowY = anim._shadowData->getBaseY() + anim._shadowData->getPhaseOffsetY(phase);
+		Graphics::Surface *shadowSurface = anim._shadowData->getFrame(shadowPhaseFrameIndex);
+		int shadowFrameWidth = shadowSurface->w;
+		int shadowFrameHeight = shadowSurface->h;
+
+		if (checkMaskFlag) {
+			checkMasks(shadowX, shadowY, shadowFrameWidth, shadowFrameHeight, shadowY + shadowFrameWidth - 1);
+		}
+
+		if (!shadowZ) {
+			if (maxFrontFlag) {
+				shadowZ = kMaxPicHeight + 1;
+			} else {
+				shadowZ = shadowY + shadowFrameWidth - 1;
+			}
+		}
+		showSpriteShadow(shadowSurface, shadowX, shadowY, shadowZ);
+	}
+}
+
+void PrinceEngine::showNormAnims() {
+	for (int i = 0; i < kMaxNormAnims; i++) {
+		Anim &anim = _normAnimList[i];
+		if (anim._animData != nullptr) {
+			int phaseCount = anim._animData->getPhaseCount();
+			if (!anim._state) {
+				if (anim._frame == anim._lastFrame - 1) {
+					if (anim._loopType) {
+						if (anim._loopType == 1) {
+							anim._frame = anim._loopFrame;
+						} else {
+							continue;
+						}
+					}
+				} else {
+					anim._frame++;
+				}
+				anim._showFrame = anim._frame;
+				if (anim._showFrame >= phaseCount) {
+					anim._showFrame = phaseCount - 1;
+				}
+				showAnim(anim);
+			}
+		}
+	}
+}
+
+void PrinceEngine::setBackAnim(Anim &backAnim) {
+	int start = backAnim._basaData._start;
+	if (start != -1) {
+		backAnim._frame = start;
+		backAnim._showFrame = start;
+		backAnim._loopFrame = start;
+	}
+	int end = backAnim._basaData._end;
+	if (end != -1) {
+		backAnim._lastFrame = end;
+	}
+	backAnim._state = 0;
+}
+
+void PrinceEngine::showBackAnims() {
+	for (int i = 0; i < kMaxBackAnims; i++) {
+		BAS &seq = _backAnimList[i]._seq;
+		int activeSubAnim = seq._currRelative;
+		if (!_backAnimList[i].backAnims.empty()) {
+			if (_backAnimList[i].backAnims[activeSubAnim]._animData != nullptr) {
+				if (!_backAnimList[i].backAnims[activeSubAnim]._state) {
+					seq._counter++;
+					if (seq._type == 2) {
+						if (!seq._currRelative) {
+							if (seq._counter >= seq._data) {
+								if (seq._anims > 2) {
+									seq._currRelative = _randomSource.getRandomNumber(seq._anims - 2) + 1;
+									activeSubAnim = seq._currRelative;
+									seq._current = _backAnimList[i].backAnims[activeSubAnim]._basaData._num;
+								}
+								setBackAnim(_backAnimList[i].backAnims[activeSubAnim]);
+								seq._counter = 0;
+							}
+						}
+					}
+
+					if (seq._type == 3) {
+						if (!seq._currRelative) {
+							if (seq._counter < seq._data2) {
+								continue;
+							} else {
+								setBackAnim(_backAnimList[i].backAnims[activeSubAnim]);
+							}
+						}
+					}
+
+					if (_backAnimList[i].backAnims[activeSubAnim]._frame == _backAnimList[i].backAnims[activeSubAnim]._lastFrame - 1) {
+						_backAnimList[i].backAnims[activeSubAnim]._frame = _backAnimList[i].backAnims[activeSubAnim]._loopFrame;
+						switch (seq._type) {
+						case 1:
+							if (seq._anims > 1) {
+								int rnd;
+								do {
+									rnd = _randomSource.getRandomNumber(seq._anims - 1);
+								} while (rnd == seq._currRelative);
+								seq._currRelative = rnd;
+								seq._current = _backAnimList[i].backAnims[rnd]._basaData._num;
+								activeSubAnim = rnd;
+								setBackAnim(_backAnimList[i].backAnims[activeSubAnim]);
+								seq._counter = 0;
+							}
+							break;
+						case 2:
+							if (seq._currRelative) {
+								seq._currRelative = 0;
+								seq._current = _backAnimList[i].backAnims[0]._basaData._num;
+								activeSubAnim = 0;
+								setBackAnim(_backAnimList[i].backAnims[activeSubAnim]);
+								seq._counter = 0;
+							}
+							break;
+						case 3:
+							seq._currRelative = 0;
+							seq._current = _backAnimList[i].backAnims[0]._basaData._num;
+							seq._counter = 0;
+							seq._data2 = _randomSource.getRandomNumber(seq._data - 1);
+							continue; // for bug in original game
+							break;
+						}
+					} else {
+						_backAnimList[i].backAnims[activeSubAnim]._frame++;
+					}
+					_backAnimList[i].backAnims[activeSubAnim]._showFrame = _backAnimList[i].backAnims[activeSubAnim]._frame;
+					showAnim(_backAnimList[i].backAnims[activeSubAnim]);
+				}
+			}
+		}
+	}
+}
+
+void PrinceEngine::removeSingleBackAnim(int slot) {
+	if (!_backAnimList[slot].backAnims.empty()) {
+		for (uint j = 0; j < _backAnimList[slot].backAnims.size(); j++) {
+			if (_backAnimList[slot].backAnims[j]._animData != nullptr) {
+				delete _backAnimList[slot].backAnims[j]._animData;
+				_backAnimList[slot].backAnims[j]._animData = nullptr;
+			}
+			if (_backAnimList[slot].backAnims[j]._shadowData != nullptr) {
+				delete _backAnimList[slot].backAnims[j]._shadowData;
+				_backAnimList[slot].backAnims[j]._shadowData = nullptr;
+			}
+		}
+		_backAnimList[slot].backAnims.clear();
+		_backAnimList[slot]._seq._currRelative = 0;
+	}
+}
+
+void PrinceEngine::clearBackAnimList() {
+	for (int i = 0; i < kMaxBackAnims; i++) {
+		removeSingleBackAnim(i);
+	}
+}
+
+void PrinceEngine::grabMap() {
+	_graph->_frontScreen->copyFrom(*_roomBmp->getSurface());
+	showObjects();
+	runDrawNodes();
+	_graph->_mapScreen->copyFrom(*_graph->_frontScreen);
+}
+
+void PrinceEngine::initZoomIn(int slot) {
+	freeZoomObject(slot);
+	Object *object = _objList[slot];
+	if (object != nullptr) {
+		Graphics::Surface *zoomSource = object->getSurface();
+		if (zoomSource != nullptr) {
+			object->_flags |= 0x8000;
+			object->_zoomSurface = new Graphics::Surface();
+			object->_zoomSurface->create(zoomSource->w, zoomSource->h, Graphics::PixelFormat::createFormatCLUT8());
+			object->_zoomSurface->fillRect(Common::Rect(zoomSource->w, zoomSource->h), 0xFF);
+			object->_zoomTime = 20;
+		}
+	}
+}
+
+void PrinceEngine::initZoomOut(int slot) {
+	freeZoomObject(slot);
+	Object *object = _objList[slot];
+	if (object != nullptr) {
+		Graphics::Surface *zoomSource = object->getSurface();
+		if (zoomSource != nullptr) {
+			object->_flags |= 0x4000;
+			object->_zoomSurface = new Graphics::Surface();
+			object->_zoomSurface->copyFrom(*zoomSource);
+			object->_zoomTime = 10;
+		}
+	}
+}
+
+void PrinceEngine::doZoomIn(int slot) {
+	Object *object = _objList[slot];
+	if (object != nullptr) {
+		Graphics::Surface *orgSurface = object->getSurface();
+		if (orgSurface != nullptr) {
+			byte *src1 = (byte *)orgSurface->getBasePtr(0, 0);
+			byte *dst1 = (byte *)object->_zoomSurface->getBasePtr(0, 0);
+			int x = 0;
+			int surfaceHeight = orgSurface->h;
+			for (int y = 0; y < surfaceHeight; y++) {
+				byte *src2 = src1;
+				byte *dst2 = dst1;
+				int w = orgSurface->w - x;
+				src2 += x;
+				dst2 += x;
+				while (w > 0) {
+					int randVal = _randomSource.getRandomNumber(zoomInStep - 1);
+					if (randVal < w) {
+						*(dst2 + randVal) = *(src2 + randVal);
+						src2 += zoomInStep;
+						dst2 += zoomInStep;
+					} else if (y + 1 != surfaceHeight) {
+						*(dst1 + orgSurface->pitch + randVal - w) = *(src1 + orgSurface->pitch + randVal - w);
+					}
+					w -= zoomInStep;
+				}
+				x = -1 * w;
+				src1 += orgSurface->pitch;
+				dst1 += orgSurface->pitch;
+			}
+		}
+	}
+}
+
+void PrinceEngine::doZoomOut(int slot) {
+	Object *object = _objList[slot];
+	if (object != nullptr) {
+		Graphics::Surface *orgSurface = object->getSurface();
+		if (orgSurface != nullptr) {
+			byte *dst1 = (byte *)object->_zoomSurface->getBasePtr(0, 0);
+			int x = 0;
+			int surfaceHeight = orgSurface->h;
+			for (int y = 0; y < surfaceHeight; y++) {
+				byte *dst2 = dst1;
+				int w = orgSurface->w - x;
+				dst2 += x;
+				while (w > 0) {
+					int randVal = _randomSource.getRandomNumber(zoomInStep - 1);
+					if (randVal < w) {
+						*(dst2 + randVal) = 255;
+						dst2 += zoomInStep;
+					} else if (y + 1 != surfaceHeight) {
+						*(dst1 + orgSurface->pitch + randVal - w) = 255;
+					}
+					w -= zoomInStep;
+				}
+				x = -1 * w;
+				dst1 += orgSurface->pitch;
+			}
+		}
+	}
+}
+
+void PrinceEngine::freeZoomObject(int slot) {
+	Object *object = _objList[slot];
+	if (object != nullptr) {
+		if (object->_zoomSurface != nullptr) {
+			object->_zoomSurface->free();
+			delete object->_zoomSurface;
+			object->_zoomSurface = nullptr;
+		}
+	}
+}
+
+void PrinceEngine::showObjects() {
+	for (int i = 0; i < kMaxObjects; i++) {
+		int nr = _objSlot[i];
+		if (nr != 0xFF) {
+			Graphics::Surface *objSurface = nullptr;
+			if ((_objList[nr]->_flags & 0x8000)) {
+				_objList[nr]->_zoomTime--;
+				if (!_objList[nr]->_zoomTime) {
+					freeZoomObject(nr);
+					_objList[nr]->_flags &= 0x7FFF;
+					objSurface = _objList[nr]->getSurface();
+				} else {
+					doZoomIn(nr);
+					objSurface = _objList[nr]->_zoomSurface;
+				}
+			} else if ((_objList[nr]->_flags & 0x4000)) {
+				_objList[nr]->_zoomTime--;
+				if (!_objList[nr]->_zoomTime) {
+					freeZoomObject(nr);
+					_objList[nr]->_flags &= 0xBFFF;
+					objSurface = _objList[nr]->getSurface();
+				} else {
+					doZoomOut(nr);
+					objSurface = _objList[nr]->_zoomSurface;
+				}
+			} else {
+				objSurface = _objList[nr]->getSurface();
+			}
+
+			if (objSurface != nullptr) {
+				if (spriteCheck(objSurface->w, objSurface->h, _objList[nr]->_x, _objList[nr]->_y)) {
+					int destX = _objList[nr]->_x - _picWindowX;
+					int destY = _objList[nr]->_y - _picWindowY;
+					DrawNode newDrawNode;
+					newDrawNode.posX = destX;
+					newDrawNode.posY = destY;
+					newDrawNode.posZ = _objList[nr]->_z;
+					newDrawNode.width = 0;
+					newDrawNode.height = 0;
+					newDrawNode.s = objSurface;
+					newDrawNode.originalRoomSurface = nullptr;
+					if ((_objList[nr]->_flags & 0x2000)) {
+						newDrawNode.data = nullptr;
+						newDrawNode.drawFunction = &_graph->drawBackSpriteDrawNode;
+					} else {
+						newDrawNode.data = _transTable;
+						if (_flags->getFlagValue(Flags::NOANTIALIAS)) {
+							newDrawNode.drawFunction = &_graph->drawTransparentDrawNode;
+						} else {
+							newDrawNode.drawFunction = &_graph->drawTransparentWithTransDrawNode;
+						}
+					}
+					_drawNodeList.push_back(newDrawNode);
+				}
+
+				if ((_objList[nr]->_flags & 1)) {
+					checkMasks(_objList[nr]->_x, _objList[nr]->_y, objSurface->w, objSurface->h, _objList[nr]->_z);
+				}
+			}
+		}
+	}
+}
+
+void PrinceEngine::showParallax() {
+	if (!_pscrList.empty()) {
+		for (uint i = 0; i < _pscrList.size(); i++) {
+			Graphics::Surface *pscrSurface = _pscrList[i]->getSurface();
+			if (pscrSurface != nullptr) {
+				int x = _pscrList[i]->_x - (_pscrList[i]->_step * _picWindowX / 4);
+				int y = _pscrList[i]->_y;
+				int z = PScr::kPScrZ;
+				if (spriteCheck(pscrSurface->w, pscrSurface->h, x, y)) {
+					showSprite(pscrSurface, x, y, z);
+				}
+			}
+		}
+	}
+}
+
+bool PrinceEngine::compareDrawNodes(DrawNode d1, DrawNode d2) {
+	if (d1.posZ < d2.posZ) {
+		return true;
+	}
+	return false;
+}
+
+void PrinceEngine::runDrawNodes() {
+	Common::sort(_drawNodeList.begin(), _drawNodeList.end(), compareDrawNodes);
+
+	for (uint i = 0; i < _drawNodeList.size(); i++) {
+		(*_drawNodeList[i].drawFunction)(_graph->_frontScreen, &_drawNodeList[i]);
+	}
+	_graph->change();
+}
+
+void PrinceEngine::drawScreen() {
+	if (!_showInventoryFlag || _inventoryBackgroundRemember) {
+		clsMasks();
+
+		_mainHero->showHero();
+		_mainHero->scrollHero();
+		_mainHero->drawHero();
+
+		_secondHero->showHero();
+		_secondHero->_drawX -= _picWindowX;
+		_secondHero->drawHero();
+
+		const Graphics::Surface *roomSurface;
+		if (_locationNr != 50) {
+			roomSurface = _roomBmp->getSurface();
+		} else {
+			roomSurface = _graph->_mapScreen;
+		}
+		Graphics::Surface visiblePart;
+		if (roomSurface) {
+			visiblePart = roomSurface->getSubArea(Common::Rect(_picWindowX, 0, roomSurface->w, roomSurface->h));
+			_graph->draw(_graph->_frontScreen, &visiblePart);
+		}
+
+		showBackAnims();
+
+		showNormAnims();
+
+		playNextFLCFrame();
+
+		showObjects();
+
+		if (roomSurface) {
+			insertMasks(&visiblePart);
+		}
+
+		showParallax();
+
+		runDrawNodes();
+
+		_drawNodeList.clear();
+
+		if (!_inventoryBackgroundRemember && !_dialogFlag) {
+			if (!_optionsFlag) {
+				_selectedMob = checkMob(_graph->_frontScreen, _mobList, true);
+			}
+			showTexts(_graph->_frontScreen);
+			checkOptions();
+		} else {
+			_inventoryBackgroundRemember = false;
+		}
+
+		showPower();
+
+		getDebugger()->onFrame();
+
+	} else {
+		displayInventory();
+	}
+}
+
+void PrinceEngine::blackPalette() {
+	byte *paletteBackup = (byte *)malloc(256 * 3);
+	byte *blackPalette1 = (byte *)malloc(256 * 3);
+
+	int fadeStep = kFadeStep - 1;
+	for (int i = 0; i < kFadeStep; i++) {
+		_system->getPaletteManager()->grabPalette(paletteBackup, 0, 256);
+		for (int j = 0; j < 256; j++) {
+			blackPalette1[3 * j] = paletteBackup[3 * j] * fadeStep / 4;
+			blackPalette1[3 * j + 1] = paletteBackup[3 * j + 1] * fadeStep / 4;
+			blackPalette1[3 * j + 2] = paletteBackup[3 * j + 2] * fadeStep / 4;
+		}
+		fadeStep--;
+		_graph->setPalette(blackPalette1);
+		_system->updateScreen();
+		Common::Event event;
+		Common::EventManager *eventMan = _system->getEventManager();
+		eventMan->pollEvent(event);
+		if (shouldQuit()) {
+			free(paletteBackup);
+			free(blackPalette1);
+			return;
+		}
+		pausePrinceEngine();
+	}
+	free(paletteBackup);
+	free(blackPalette1);
+}
+
+void PrinceEngine::setPalette(const byte *palette) {
+	if (palette != nullptr) {
+		byte *blackPalette_ = (byte *)malloc(256 * 3);
+		int fadeStep = 0;
+		for (int i = 0; i <= kFadeStep; i++) {
+			for (int j = 0; j < 256; j++) {
+				blackPalette_[3 * j] = palette[3 * j] * fadeStep / 4;
+				blackPalette_[3 * j + 1] = palette[3 * j + 1] * fadeStep / 4;
+				blackPalette_[3 * j + 2] = palette[3 * j + 2] * fadeStep / 4;
+			}
+			fadeStep++;
+			_graph->setPalette(blackPalette_);
+			_system->updateScreen();
+			Common::Event event;
+			Common::EventManager *eventMan = _system->getEventManager();
+			eventMan->pollEvent(event);
+			if (shouldQuit()) {
+				_graph->setPalette(palette);
+				free(blackPalette_);
+				return;
+			}
+			pausePrinceEngine();
+		}
+		_graph->setPalette(palette);
+		free(blackPalette_);
+	}
+}
+
+} // End of namespace Prince
diff --git a/engines/prince/mob.cpp b/engines/prince/mob.cpp
index b170ba3..de15991 100644
--- a/engines/prince/mob.cpp
+++ b/engines/prince/mob.cpp
@@ -20,7 +20,11 @@
  *
  */
 
+#include "prince/prince.h"
+
 #include "prince/mob.h"
+#include "prince/animation.h"
+#include "prince/font.h"
 
 namespace Prince {
 
@@ -105,4 +109,158 @@ uint16 Mob::getData(AttrId dataId) {
 	}
 }
 
+int PrinceEngine::getMob(Common::Array<Mob> &mobList, bool usePriorityList, int posX, int posY) {
+
+	Common::Point pointPos(posX, posY);
+
+	int mobListSize;
+	if (usePriorityList) {
+		mobListSize = _mobPriorityList.size();
+	} else {
+		mobListSize = mobList.size();
+	}
+
+	for (int mobNumber = 0; mobNumber < mobListSize; mobNumber++) {
+		Mob *mob = nullptr;
+		if (usePriorityList) {
+			mob = &mobList[_mobPriorityList[mobNumber]];
+		} else {
+			mob = &mobList[mobNumber];
+		}
+
+		if (mob->_visible) {
+			continue;
+		}
+
+		int type = mob->_type & 7;
+		switch (type) {
+		case 0:
+		case 1:
+			//normal_mob
+			if (!mob->_rect.contains(pointPos)) {
+				continue;
+			}
+			break;
+		case 3:
+			//mob_obj
+			if (mob->_mask < kMaxObjects) {
+				int nr = _objSlot[mob->_mask];
+				if (nr != 0xFF) {
+					Object &obj = *_objList[nr];
+					Common::Rect objectRect(obj._x, obj._y, obj._x + obj._width, obj._y + obj._height);
+					if (objectRect.contains(pointPos)) {
+						Graphics::Surface *objSurface = obj.getSurface();
+						byte *pixel = (byte *)objSurface->getBasePtr(posX - obj._x, posY - obj._y);
+						if (*pixel != 255) {
+							break;
+						}
+					}
+				}
+			}
+			continue;
+			break;
+		case 2:
+		case 5:
+			//check_ba_mob
+			if (!_backAnimList[mob->_mask].backAnims.empty()) {
+				int currentAnim = _backAnimList[mob->_mask]._seq._currRelative;
+				Anim &backAnim = _backAnimList[mob->_mask].backAnims[currentAnim];
+				if (backAnim._animData != nullptr) {
+					if (!backAnim._state) {
+						Common::Rect backAnimRect(backAnim._currX, backAnim._currY, backAnim._currX + backAnim._currW, backAnim._currY + backAnim._currH);
+						if (backAnimRect.contains(pointPos)) {
+							int phase = backAnim._showFrame;
+							int phaseFrameIndex = backAnim._animData->getPhaseFrameIndex(phase);
+							Graphics::Surface *backAnimSurface = backAnim._animData->getFrame(phaseFrameIndex);
+							byte pixel = *(byte *)backAnimSurface->getBasePtr(posX - backAnim._currX, posY - backAnim._currY);
+							if (pixel != 255) {
+								if (type == 5) {
+									if (mob->_rect.contains(pointPos)) {
+										break;
+									}
+								} else {
+									break;
+								}
+							}
+						}
+					}
+				}
+			}
+			continue;
+			break;
+		default:
+			//not_part_ba
+			continue;
+			break;
+		}
+
+		if (usePriorityList) {
+			return _mobPriorityList[mobNumber];
+		} else {
+			return mobNumber;
+		}
+	}
+	return -1;
+}
+
+int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array<Mob> &mobList, bool usePriorityList) {
+	if (_mouseFlag == 0 || _mouseFlag == 3) {
+		return -1;
+	}
+	Common::Point mousePos = _system->getEventManager()->getMousePos();
+	int mobNumber = getMob(mobList, usePriorityList, mousePos.x + _picWindowX, mousePos.y);
+
+	if (mobNumber != -1) {
+		Common::String mobName = mobList[mobNumber]._name;
+
+		if (getLanguage() == Common::DE_DEU) {
+			for (uint i = 0; i < mobName.size(); i++) {
+				switch (mobName[i]) {
+				case '\xc4':
+					mobName.setChar('\x83', i);
+					break;
+				case '\xd6':
+					mobName.setChar('\x84', i);
+					break;
+				case '\xdc':
+					mobName.setChar('\x85', i);
+					break;
+				case '\xdf':
+					mobName.setChar('\x7f', i);
+					break;
+				case '\xe4':
+					mobName.setChar('\x80', i);
+					break;
+				case '\xf6':
+					mobName.setChar('\x81', i);
+					break;
+				case '\xfc':
+					mobName.setChar('\x82', i);
+					break;
+				}
+			}
+		}
+
+		uint16 textW = getTextWidth(mobName.c_str());
+
+		uint16 x = mousePos.x - textW / 2;
+		if (x > screen->w) {
+			x = 0;
+		}
+
+		if (x + textW > screen->w) {
+			x = screen->w - textW;
+		}
+
+		uint16 y = mousePos.y - _font->getFontHeight();
+		if (y > screen->h) {
+			y = _font->getFontHeight() - 2;
+		}
+
+		_font->drawString(screen, mobName, x, y, screen->w, 216);
+	}
+
+	return mobNumber;
+}
+
 } // End of namespace Prince
diff --git a/engines/prince/module.mk b/engines/prince/module.mk
index d045c1f..8446d07 100644
--- a/engines/prince/module.mk
+++ b/engines/prince/module.mk
@@ -7,6 +7,7 @@ MODULE_OBJS = \
 	debugger.o \
 	decompress.o \
 	detection.o \
+	draw.o \
 	flags.o \
 	font.o \
 	graphics.o \
diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp
index 321c4f1..654b87e 100644
--- a/engines/prince/prince.cpp
+++ b/engines/prince/prince.cpp
@@ -33,13 +33,11 @@
 #include "common/str.h"
 
 #include "graphics/surface.h"
-#include "graphics/palette.h"
 #include "graphics/pixelformat.h"
 
 #include "engines/util.h"
 
 #include "prince/prince.h"
-#include "prince/font.h"
 #include "prince/graphics.h"
 #include "prince/script.h"
 #include "prince/debugger.h"
@@ -47,7 +45,6 @@
 #include "prince/mob.h"
 #include "prince/music.h"
 #include "prince/variatxt.h"
-#include "prince/flags.h"
 #include "prince/font.h"
 #include "prince/mhwanh.h"
 #include "prince/cursor.h"
@@ -563,160 +560,6 @@ void PrinceEngine::keyHandler(Common::Event event) {
 	}
 }
 
-int PrinceEngine::getMob(Common::Array<Mob> &mobList, bool usePriorityList, int posX, int posY) {
-
-	Common::Point pointPos(posX, posY);
-
-	int mobListSize;
-	if (usePriorityList) {
-		mobListSize = _mobPriorityList.size();
-	} else {
-		mobListSize = mobList.size();
-	}
-
-	for (int mobNumber = 0; mobNumber < mobListSize; mobNumber++) {
-		Mob *mob = nullptr;
-		if (usePriorityList) {
-			mob = &mobList[_mobPriorityList[mobNumber]];
-		} else {
-			mob = &mobList[mobNumber];
-		}
-
-		if (mob->_visible) {
-			continue;
-		}
-
-		int type = mob->_type & 7;
-		switch (type) {
-		case 0:
-		case 1:
-			//normal_mob
-			if (!mob->_rect.contains(pointPos)) {
-				continue;
-			}
-			break;
-		case 3:
-			//mob_obj
-			if (mob->_mask < kMaxObjects) {
-				int nr = _objSlot[mob->_mask];
-				if (nr != 0xFF) {
-					Object &obj = *_objList[nr];
-					Common::Rect objectRect(obj._x, obj._y, obj._x + obj._width, obj._y + obj._height);
-					if (objectRect.contains(pointPos)) {
-						Graphics::Surface *objSurface = obj.getSurface();
-						byte *pixel = (byte *)objSurface->getBasePtr(posX - obj._x, posY - obj._y);
-						if (*pixel != 255) {
-							break;
-						}
-					}
-				}
-			}
-			continue;
-			break;
-		case 2:
-		case 5:
-			//check_ba_mob
-			if (!_backAnimList[mob->_mask].backAnims.empty()) {
-				int currentAnim = _backAnimList[mob->_mask]._seq._currRelative;
-				Anim &backAnim = _backAnimList[mob->_mask].backAnims[currentAnim];
-				if (backAnim._animData != nullptr) {
-					if (!backAnim._state) {
-						Common::Rect backAnimRect(backAnim._currX, backAnim._currY, backAnim._currX + backAnim._currW, backAnim._currY + backAnim._currH);
-						if (backAnimRect.contains(pointPos)) {
-							int phase = backAnim._showFrame;
-							int phaseFrameIndex = backAnim._animData->getPhaseFrameIndex(phase);
-							Graphics::Surface *backAnimSurface = backAnim._animData->getFrame(phaseFrameIndex);
-							byte pixel = *(byte *)backAnimSurface->getBasePtr(posX - backAnim._currX, posY - backAnim._currY);
-							if (pixel != 255) {
-								if (type == 5) {
-									if (mob->_rect.contains(pointPos)) {
-										break;
-									}
-								} else {
-									break;
-								}
-							}
-						}
-					}
-				}
-			}
-			continue;
-			break;
-		default:
-			//not_part_ba
-			continue;
-			break;
-		}
-
-		if (usePriorityList) {
-			return _mobPriorityList[mobNumber];
-		} else {
-			return mobNumber;
-		}
-	}
-	return -1;
-}
-
-int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array<Mob> &mobList, bool usePriorityList) {
-	if (_mouseFlag == 0 || _mouseFlag == 3) {
-		return -1;
-	}
-	Common::Point mousePos = _system->getEventManager()->getMousePos();
-	int mobNumber = getMob(mobList, usePriorityList, mousePos.x + _picWindowX, mousePos.y);
-
-	if (mobNumber != -1) {
-		Common::String mobName = mobList[mobNumber]._name;
-
-		if (getLanguage() == Common::DE_DEU) {
-			for (uint i = 0; i < mobName.size(); i++) {
-				switch (mobName[i]) {
-				case '\xc4':
-					mobName.setChar('\x83', i);
-					break;
-				case '\xd6':
-					mobName.setChar('\x84', i);
-					break;
-				case '\xdc':
-					mobName.setChar('\x85', i);
-					break;
-				case '\xdf':
-					mobName.setChar('\x7f', i);
-					break;
-				case '\xe4':
-					mobName.setChar('\x80', i);
-					break;
-				case '\xf6':
-					mobName.setChar('\x81', i);
-					break;
-				case '\xfc':
-					mobName.setChar('\x82', i);
-					break;
-				}
-			}
-		}
-
-		uint16 textW = getTextWidth(mobName.c_str());
-
-		uint16 x = mousePos.x - textW / 2;
-		if (x > screen->w) {
-			x = 0;
-		}
-
-		if (x + textW > screen->w) {
-			x = screen->w - textW;
-		}
-
-		uint16 y = mousePos.y - _font->getFontHeight();
-		if (y > screen->h) {
-			y = _font->getFontHeight() - 2;
-		}
-
-		_font->drawString(screen, mobName, x, y, screen->w, 216);
-	}
-
-	return mobNumber;
-}
-
 void PrinceEngine::printAt(uint32 slot, uint8 color, char *s, uint16 x, uint16 y) {
 	debugC(1, DebugChannel::kEngine, "PrinceEngine::printAt slot %d, color %d, x %02d, y %02d, str %s", slot, color, x, y, s);
 
@@ -846,677 +689,6 @@ void PrinceEngine::showTexts(Graphics::Surface *screen) {
 	}
 }
 
-bool PrinceEngine::spriteCheck(int sprWidth, int sprHeight, int destX, int destY) {
-	destX -= _picWindowX;
-	destY -= _picWindowY;
-
-	 // if x1 is on visible part of screen
-	if (destX < 0) {
-		if (destX + sprWidth < 1) {
-			//x2 is negative - out of window
-			return false;
-		}
-	}
-	 // if x1 is outside of screen on right side
-	if (destX >= kNormalWidth) {
-		return false;
-	}
-
-	if (destY < 0) {
-		if (destY + sprHeight < 1) {
-			//y2 is negative - out of window
-			return false;
-		}
-	}
-	if (destY >= kNormalHeight) {
-		return false;
-	}
-
-	return true;
-}
-
-// CheckNak
-void PrinceEngine::checkMasks(int x1, int y1, int sprWidth, int sprHeight, int z) {
-	int x2 = x1 + sprWidth - 1;
-	int y2 = y1 + sprHeight - 1;
-	if (x1 < 0) {
-		x1 = 0;
-	}
-	for (uint i = 0; i < _maskList.size(); i++) {
-		if (!_maskList[i]._state && !_maskList[i]._flags) {
-			if (_maskList[i]._z > z) {
-				if (_maskList[i]._x1 <= x2 && _maskList[i]._x2 >= x1) {
-					if (_maskList[i]._y1 <= y2 && _maskList[i]._y2 >= y1) {
-						_maskList[i]._state = 1;
-					}
-				}
-			}
-		}
-	}
-}
-
-// ClsNak
-void PrinceEngine::clsMasks() {
-	for (uint i = 0; i < _maskList.size(); i++) {
-		if (_maskList[i]._state) {
-			_maskList[i]._state = 0;
-		}
-	}
-}
-
-// InsertNakladki
-void PrinceEngine::insertMasks(Graphics::Surface *originalRoomSurface) {
-	for (uint i = 0; i < _maskList.size(); i++) {
-		if (_maskList[i]._state) {
-			if (_maskList[i]._data != nullptr) {
-				showMask(i, originalRoomSurface);
-			} else {
-				error("insertMasks() - Wrong mask data- nr %d", i);
-			}
-		}
-	}
-}
-
-// ShowNak
-void PrinceEngine::showMask(int maskNr, Graphics::Surface *originalRoomSurface) {
-	if (!_maskList[maskNr]._flags) {
-		if (spriteCheck(_maskList[maskNr]._width, _maskList[maskNr]._height, _maskList[maskNr]._x1, _maskList[maskNr]._y1)) {
-			int destX = _maskList[maskNr]._x1 - _picWindowX;
-			int destY = _maskList[maskNr]._y1 - _picWindowY;
-			DrawNode newDrawNode;
-			newDrawNode.posX = destX;
-			newDrawNode.posY = destY;
-			newDrawNode.posZ = _maskList[maskNr]._z;
-			newDrawNode.width = _maskList[maskNr]._width;
-			newDrawNode.height = _maskList[maskNr]._height;
-			newDrawNode.s = nullptr;
-			newDrawNode.originalRoomSurface = originalRoomSurface;
-			newDrawNode.data = _maskList[maskNr].getMask();
-			newDrawNode.drawFunction = &_graph->drawMaskDrawNode;
-			_drawNodeList.push_back(newDrawNode);
-		}
-	}
-}
-
-void PrinceEngine::showSprite(Graphics::Surface *spriteSurface, int destX, int destY, int destZ) {
-	if (spriteCheck(spriteSurface->w, spriteSurface->h, destX, destY)) {
-		destX -= _picWindowX;
-		destY -= _picWindowY;
-		DrawNode newDrawNode;
-		newDrawNode.posX = destX;
-		newDrawNode.posY = destY;
-		newDrawNode.posZ = destZ;
-		newDrawNode.width = 0;
-		newDrawNode.height = 0;
-		newDrawNode.s = spriteSurface;
-		newDrawNode.originalRoomSurface = nullptr;
-		newDrawNode.data = _transTable;
-		newDrawNode.drawFunction = &_graph->drawTransparentWithTransDrawNode;
-		_drawNodeList.push_back(newDrawNode);
-	}
-}
-
-void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY, int destZ) {
-	if (spriteCheck(shadowSurface->w, shadowSurface->h, destX, destY)) {
-		destX -= _picWindowX;
-		destY -= _picWindowY;
-		DrawNode newDrawNode;
-		newDrawNode.posX = destX;
-		newDrawNode.posY = destY;
-		newDrawNode.posZ = destZ;
-		newDrawNode.width = 0;
-		newDrawNode.height = 0;
-		newDrawNode.s = shadowSurface;
-		newDrawNode.originalRoomSurface = nullptr;
-		newDrawNode.data = _graph->_shadowTable70;
-		newDrawNode.drawFunction = &_graph->drawAsShadowDrawNode;
-		_drawNodeList.push_back(newDrawNode);
-	}
-}
-
-void PrinceEngine::showAnim(Anim &anim) {
-	//ShowFrameCode
-	//ShowAnimFrame
-	int phase = anim._showFrame;
-	int phaseFrameIndex = anim._animData->getPhaseFrameIndex(phase);
-	int x = anim._x + anim._animData->getPhaseOffsetX(phase);
-	int y = anim._y + anim._animData->getPhaseOffsetY(phase);
-	int animFlag = anim._flags;
-	int checkMaskFlag = (animFlag & 1);
-	int maxFrontFlag = (animFlag & 2);
-	int specialZFlag = anim._nextAnim;
-	int z = anim._nextAnim;
-	Graphics::Surface *animSurface = anim._animData->getFrame(phaseFrameIndex);
-	int frameWidth = animSurface->w;
-	int frameHeight = animSurface->h;
-	int shadowZ = 0;
-
-	if (checkMaskFlag) {
-		if (!anim._nextAnim) {
-			z = y + frameHeight - 1;
-		}
-		checkMasks(x, y, frameWidth, frameHeight, z);
-	}
-
-	if (specialZFlag) {
-		z = specialZFlag;
-	} else if (maxFrontFlag) {
-		z = kMaxPicHeight + 1;
-	} else {
-		z = y + frameHeight - 1;
-	}
-	shadowZ = z;
-
-	anim._currX = x;
-	anim._currY = y;
-	anim._currW = frameWidth;
-	anim._currH = frameHeight;
-	showSprite(animSurface, x, y, z);
-
-	// make_special_shadow
-	if ((anim._flags & 0x80)) {
-		DrawNode newDrawNode;
-		newDrawNode.posX = x;
-		newDrawNode.posY = y + animSurface->h - anim._shadowBack;
-		newDrawNode.posZ = Hero::kHeroShadowZ;
-		newDrawNode.width = 0;
-		newDrawNode.height = 0;
-		newDrawNode.scaleValue = _scaleValue;
-		newDrawNode.originalRoomSurface = nullptr;
-		newDrawNode.data = this;
-		newDrawNode.drawFunction = &Hero::showHeroShadow;
-		newDrawNode.s = animSurface;
-		_drawNodeList.push_back(newDrawNode);
-	}
-
-	//ShowFrameCodeShadow
-	//ShowAnimFrameShadow
-	if (anim._shadowData != nullptr) {
-		int shadowPhaseFrameIndex = anim._shadowData->getPhaseFrameIndex(phase);
-		int shadowX = anim._shadowData->getBaseX() + anim._shadowData->getPhaseOffsetX(phase);
-		int shadowY = anim._shadowData->getBaseY() + anim._shadowData->getPhaseOffsetY(phase);
-		Graphics::Surface *shadowSurface = anim._shadowData->getFrame(shadowPhaseFrameIndex);
-		int shadowFrameWidth = shadowSurface->w;
-		int shadowFrameHeight = shadowSurface->h;
-
-		if (checkMaskFlag) {
-			checkMasks(shadowX, shadowY, shadowFrameWidth, shadowFrameHeight, shadowY + shadowFrameWidth - 1);
-		}
-
-		if (!shadowZ) {
-			if (maxFrontFlag) {
-				shadowZ = kMaxPicHeight + 1;
-			} else {
-				shadowZ = shadowY + shadowFrameWidth - 1;
-			}
-		}
-		showSpriteShadow(shadowSurface, shadowX, shadowY, shadowZ);
-	}
-}
-
-void PrinceEngine::showNormAnims() {
-	for (int i = 0; i < kMaxNormAnims; i++) {
-		Anim &anim = _normAnimList[i];
-		if (anim._animData != nullptr) {
-			int phaseCount = anim._animData->getPhaseCount();
-			if (!anim._state) {
-				if (anim._frame == anim._lastFrame - 1) {
-					if (anim._loopType) {
-						if (anim._loopType == 1) {
-							anim._frame = anim._loopFrame;
-						} else {
-							continue;
-						}
-					}
-				} else {
-					anim._frame++;
-				}
-				anim._showFrame = anim._frame;
-				if (anim._showFrame >= phaseCount) {
-					anim._showFrame = phaseCount - 1;
-				}
-				showAnim(anim);
-			}
-		}
-	}
-}
-
-void PrinceEngine::setBackAnim(Anim &backAnim) {
-	int start = backAnim._basaData._start;
-	if (start != -1) {
-		backAnim._frame = start;
-		backAnim._showFrame = start;
-		backAnim._loopFrame = start;
-	}
-	int end = backAnim._basaData._end;
-	if (end != -1) {
-		backAnim._lastFrame = end;
-	}
-	backAnim._state = 0;
-}
-
-void PrinceEngine::showBackAnims() {
-	for (int i = 0; i < kMaxBackAnims; i++) {
-		BAS &seq = _backAnimList[i]._seq;
-		int activeSubAnim = seq._currRelative;
-		if (!_backAnimList[i].backAnims.empty()) {
-			if (_backAnimList[i].backAnims[activeSubAnim]._animData != nullptr) {
-				if (!_backAnimList[i].backAnims[activeSubAnim]._state) {
-					seq._counter++;
-					if (seq._type == 2) {
-						if (!seq._currRelative) {
-							if (seq._counter >= seq._data) {
-								if (seq._anims > 2) {
-									seq._currRelative = _randomSource.getRandomNumber(seq._anims - 2) + 1;
-									activeSubAnim = seq._currRelative;
-									seq._current = _backAnimList[i].backAnims[activeSubAnim]._basaData._num;
-								}
-								setBackAnim(_backAnimList[i].backAnims[activeSubAnim]);
-								seq._counter = 0;
-							}
-						}
-					}
-
-					if (seq._type == 3) {
-						if (!seq._currRelative) {
-							if (seq._counter < seq._data2) {
-								continue;
-							} else {
-								setBackAnim(_backAnimList[i].backAnims[activeSubAnim]);
-							}
-						}
-					}
-
-					if (_backAnimList[i].backAnims[activeSubAnim]._frame == _backAnimList[i].backAnims[activeSubAnim]._lastFrame - 1) {
-						_backAnimList[i].backAnims[activeSubAnim]._frame = _backAnimList[i].backAnims[activeSubAnim]._loopFrame;
-						switch (seq._type) {
-						case 1:
-							if (seq._anims > 1) {
-								int rnd;
-								do {
-									rnd = _randomSource.getRandomNumber(seq._anims - 1);
-								} while (rnd == seq._currRelative);
-								seq._currRelative = rnd;
-								seq._current = _backAnimList[i].backAnims[rnd]._basaData._num;
-								activeSubAnim = rnd;
-								setBackAnim(_backAnimList[i].backAnims[activeSubAnim]);
-								seq._counter = 0;
-							}
-							break;
-						case 2:
-							if (seq._currRelative) {
-								seq._currRelative = 0;
-								seq._current = _backAnimList[i].backAnims[0]._basaData._num;
-								activeSubAnim = 0;
-								setBackAnim(_backAnimList[i].backAnims[activeSubAnim]);
-								seq._counter = 0;
-							}
-							break;
-						case 3:
-							seq._currRelative = 0;
-							seq._current = _backAnimList[i].backAnims[0]._basaData._num;
-							seq._counter = 0;
-							seq._data2 = _randomSource.getRandomNumber(seq._data - 1);
-							continue; // for bug in original game
-							break;
-						}
-					} else {
-						_backAnimList[i].backAnims[activeSubAnim]._frame++;
-					}
-					_backAnimList[i].backAnims[activeSubAnim]._showFrame = _backAnimList[i].backAnims[activeSubAnim]._frame;
-					showAnim(_backAnimList[i].backAnims[activeSubAnim]);
-				}
-			}
-		}
-	}
-}
-
-void PrinceEngine::removeSingleBackAnim(int slot) {
-	if (!_backAnimList[slot].backAnims.empty()) {
-		for (uint j = 0; j < _backAnimList[slot].backAnims.size(); j++) {
-			if (_backAnimList[slot].backAnims[j]._animData != nullptr) {
-				delete _backAnimList[slot].backAnims[j]._animData;
-				_backAnimList[slot].backAnims[j]._animData = nullptr;
-			}
-			if (_backAnimList[slot].backAnims[j]._shadowData != nullptr) {
-				delete _backAnimList[slot].backAnims[j]._shadowData;
-				_backAnimList[slot].backAnims[j]._shadowData = nullptr;
-			}
-		}
-		_backAnimList[slot].backAnims.clear();
-		_backAnimList[slot]._seq._currRelative = 0;
-	}
-}
-
-void PrinceEngine::clearBackAnimList() {
-	for (int i = 0; i < kMaxBackAnims; i++) {
-		removeSingleBackAnim(i);
-	}
-}
-
-void PrinceEngine::grabMap() {
-	_graph->_frontScreen->copyFrom(*_roomBmp->getSurface());
-	showObjects();
-	runDrawNodes();
-	_graph->_mapScreen->copyFrom(*_graph->_frontScreen);
-}
-
-void PrinceEngine::initZoomIn(int slot) {
-	freeZoomObject(slot);
-	Object *object = _objList[slot];
-	if (object != nullptr) {
-		Graphics::Surface *zoomSource = object->getSurface();
-		if (zoomSource != nullptr) {
-			object->_flags |= 0x8000;
-			object->_zoomSurface = new Graphics::Surface();
-			object->_zoomSurface->create(zoomSource->w, zoomSource->h, Graphics::PixelFormat::createFormatCLUT8());
-			object->_zoomSurface->fillRect(Common::Rect(zoomSource->w, zoomSource->h), 0xFF);
-			object->_zoomTime = 20;
-		}
-	}
-}
-
-void PrinceEngine::initZoomOut(int slot) {
-	freeZoomObject(slot);
-	Object *object = _objList[slot];
-	if (object != nullptr) {
-		Graphics::Surface *zoomSource = object->getSurface();
-		if (zoomSource != nullptr) {
-			object->_flags |= 0x4000;
-			object->_zoomSurface = new Graphics::Surface();
-			object->_zoomSurface->copyFrom(*zoomSource);
-			object->_zoomTime = 10;
-		}
-	}
-}
-
-void PrinceEngine::doZoomIn(int slot) {
-	Object *object = _objList[slot];
-	if (object != nullptr) {
-		Graphics::Surface *orgSurface = object->getSurface();
-		if (orgSurface != nullptr) {
-			byte *src1 = (byte *)orgSurface->getBasePtr(0, 0);
-			byte *dst1 = (byte *)object->_zoomSurface->getBasePtr(0, 0);
-			int x = 0;
-			int surfaceHeight = orgSurface->h;
-			for (int y = 0; y < surfaceHeight; y++) {
-				byte *src2 = src1;
-				byte *dst2 = dst1;
-				int w = orgSurface->w - x;
-				src2 += x;
-				dst2 += x;
-				while (w > 0) {
-					int randVal = _randomSource.getRandomNumber(zoomInStep - 1);
-					if (randVal < w) {
-						*(dst2 + randVal) = *(src2 + randVal);
-						src2 += zoomInStep;
-						dst2 += zoomInStep;
-					} else if (y + 1 != surfaceHeight) {
-						*(dst1 + orgSurface->pitch + randVal - w) = *(src1 + orgSurface->pitch + randVal - w);
-					}
-					w -= zoomInStep;
-				}
-				x = -1 * w;
-				src1 += orgSurface->pitch;
-				dst1 += orgSurface->pitch;
-			}
-		}
-	}
-}
-
-void PrinceEngine::doZoomOut(int slot) {
-	Object *object = _objList[slot];
-	if (object != nullptr) {
-		Graphics::Surface *orgSurface = object->getSurface();
-		if (orgSurface != nullptr) {
-			byte *dst1 = (byte *)object->_zoomSurface->getBasePtr(0, 0);
-			int x = 0;
-			int surfaceHeight = orgSurface->h;
-			for (int y = 0; y < surfaceHeight; y++) {
-				byte *dst2 = dst1;
-				int w = orgSurface->w - x;
-				dst2 += x;
-				while (w > 0) {
-					int randVal = _randomSource.getRandomNumber(zoomInStep - 1);
-					if (randVal < w) {
-						*(dst2 + randVal) = 255;
-						dst2 += zoomInStep;
-					} else if (y + 1 != surfaceHeight) {
-						*(dst1 + orgSurface->pitch + randVal - w) = 255;
-					}
-					w -= zoomInStep;
-				}
-				x = -1 * w;
-				dst1 += orgSurface->pitch;
-			}
-		}
-	}
-}
-
-void PrinceEngine::freeZoomObject(int slot) {
-	Object *object = _objList[slot];
-	if (object != nullptr) {
-		if (object->_zoomSurface != nullptr) {
-			object->_zoomSurface->free();
-			delete object->_zoomSurface;
-			object->_zoomSurface = nullptr;
-		}
-	}
-}
-
-void PrinceEngine::showObjects() {
-	for (int i = 0; i < kMaxObjects; i++) {
-		int nr = _objSlot[i];
-		if (nr != 0xFF) {
-			Graphics::Surface *objSurface = nullptr;
-			if ((_objList[nr]->_flags & 0x8000)) {
-				_objList[nr]->_zoomTime--;
-				if (!_objList[nr]->_zoomTime) {
-					freeZoomObject(nr);
-					_objList[nr]->_flags &= 0x7FFF;
-					objSurface = _objList[nr]->getSurface();
-				} else {
-					doZoomIn(nr);
-					objSurface = _objList[nr]->_zoomSurface;
-				}
-			} else if ((_objList[nr]->_flags & 0x4000)) {
-				_objList[nr]->_zoomTime--;
-				if (!_objList[nr]->_zoomTime) {
-					freeZoomObject(nr);
-					_objList[nr]->_flags &= 0xBFFF;
-					objSurface = _objList[nr]->getSurface();
-				} else {
-					doZoomOut(nr);
-					objSurface = _objList[nr]->_zoomSurface;
-				}
-			} else {
-				objSurface = _objList[nr]->getSurface();
-			}
-
-			if (objSurface != nullptr) {
-				if (spriteCheck(objSurface->w, objSurface->h, _objList[nr]->_x, _objList[nr]->_y)) {
-					int destX = _objList[nr]->_x - _picWindowX;
-					int destY = _objList[nr]->_y - _picWindowY;
-					DrawNode newDrawNode;
-					newDrawNode.posX = destX;
-					newDrawNode.posY = destY;
-					newDrawNode.posZ = _objList[nr]->_z;
-					newDrawNode.width = 0;
-					newDrawNode.height = 0;
-					newDrawNode.s = objSurface;
-					newDrawNode.originalRoomSurface = nullptr;
-					if ((_objList[nr]->_flags & 0x2000)) {
-						newDrawNode.data = nullptr;
-						newDrawNode.drawFunction = &_graph->drawBackSpriteDrawNode;
-					} else {
-						newDrawNode.data = _transTable;
-						if (_flags->getFlagValue(Flags::NOANTIALIAS)) {
-							newDrawNode.drawFunction = &_graph->drawTransparentDrawNode;
-						} else {
-							newDrawNode.drawFunction = &_graph->drawTransparentWithTransDrawNode;
-						}
-					}
-					_drawNodeList.push_back(newDrawNode);
-				}
-
-				if ((_objList[nr]->_flags & 1)) {
-					checkMasks(_objList[nr]->_x, _objList[nr]->_y, objSurface->w, objSurface->h, _objList[nr]->_z);
-				}
-			}
-		}
-	}
-}
-
-void PrinceEngine::showParallax() {
-	if (!_pscrList.empty()) {
-		for (uint i = 0; i < _pscrList.size(); i++) {
-			Graphics::Surface *pscrSurface = _pscrList[i]->getSurface();
-			if (pscrSurface != nullptr) {
-				int x = _pscrList[i]->_x - (_pscrList[i]->_step * _picWindowX / 4);
-				int y = _pscrList[i]->_y;
-				int z = PScr::kPScrZ;
-				if (spriteCheck(pscrSurface->w, pscrSurface->h, x, y)) {
-					showSprite(pscrSurface, x, y, z);
-				}
-			}
-		}
-	}
-}
-
-bool PrinceEngine::compareDrawNodes(DrawNode d1, DrawNode d2) {
-	if (d1.posZ < d2.posZ) {
-		return true;
-	}
-	return false;
-}
-
-void PrinceEngine::runDrawNodes() {
-	Common::sort(_drawNodeList.begin(), _drawNodeList.end(), compareDrawNodes);
-
-	for (uint i = 0; i < _drawNodeList.size(); i++) {
-		(*_drawNodeList[i].drawFunction)(_graph->_frontScreen, &_drawNodeList[i]);
-	}
-	_graph->change();
-}
-
-void PrinceEngine::drawScreen() {
-	if (!_showInventoryFlag || _inventoryBackgroundRemember) {
-		clsMasks();
-
-		_mainHero->showHero();
-		_mainHero->scrollHero();
-		_mainHero->drawHero();
-
-		_secondHero->showHero();
-		_secondHero->_drawX -= _picWindowX;
-		_secondHero->drawHero();
-
-		const Graphics::Surface *roomSurface;
-		if (_locationNr != 50) {
-			roomSurface = _roomBmp->getSurface();
-		} else {
-			roomSurface = _graph->_mapScreen;
-		}
-		Graphics::Surface visiblePart;
-		if (roomSurface) {
-			visiblePart = roomSurface->getSubArea(Common::Rect(_picWindowX, 0, roomSurface->w, roomSurface->h));
-			_graph->draw(_graph->_frontScreen, &visiblePart);
-		}
-
-		showBackAnims();
-
-		showNormAnims();
-
-		playNextFLCFrame();
-
-		showObjects();
-
-		if (roomSurface) {
-			insertMasks(&visiblePart);
-		}
-
-		showParallax();
-
-		runDrawNodes();
-
-		_drawNodeList.clear();
-
-		if (!_inventoryBackgroundRemember && !_dialogFlag) {
-			if (!_optionsFlag) {
-				_selectedMob = checkMob(_graph->_frontScreen, _mobList, true);
-			}
-			showTexts(_graph->_frontScreen);
-			checkOptions();
-		} else {
-			_inventoryBackgroundRemember = false;
-		}
-
-		showPower();
-
-		getDebugger()->onFrame();
-
-	} else {
-		displayInventory();
-	}
-}
-
-void PrinceEngine::blackPalette() {
-	byte *paletteBackup = (byte *)malloc(256 * 3);
-	byte *blackPalette1 = (byte *)malloc(256 * 3);
-
-	int fadeStep = kFadeStep - 1;
-	for (int i = 0; i < kFadeStep; i++) {
-		_system->getPaletteManager()->grabPalette(paletteBackup, 0, 256);
-		for (int j = 0; j < 256; j++) {
-			blackPalette1[3 * j] = paletteBackup[3 * j] * fadeStep / 4;
-			blackPalette1[3 * j + 1] = paletteBackup[3 * j + 1] * fadeStep / 4;
-			blackPalette1[3 * j + 2] = paletteBackup[3 * j + 2] * fadeStep / 4;
-		}
-		fadeStep--;
-		_graph->setPalette(blackPalette1);
-		_system->updateScreen();
-		Common::Event event;
-		Common::EventManager *eventMan = _system->getEventManager();
-		eventMan->pollEvent(event);
-		if (shouldQuit()) {
-			free(paletteBackup);
-			free(blackPalette1);
-			return;
-		}
-		pausePrinceEngine();
-	}
-	free(paletteBackup);
-	free(blackPalette1);
-}
-
-void PrinceEngine::setPalette(const byte *palette) {
-	if (palette != nullptr) {
-		byte *blackPalette_ = (byte *)malloc(256 * 3);
-		int fadeStep = 0;
-		for (int i = 0; i <= kFadeStep; i++) {
-			for (int j = 0; j < 256; j++) {
-				blackPalette_[3 * j] = palette[3 * j] * fadeStep / 4;
-				blackPalette_[3 * j + 1] = palette[3 * j + 1] * fadeStep / 4;
-				blackPalette_[3 * j + 2] = palette[3 * j + 2] * fadeStep / 4;
-			}
-			fadeStep++;
-			_graph->setPalette(blackPalette_);
-			_system->updateScreen();
-			Common::Event event;
-			Common::EventManager *eventMan = _system->getEventManager();
-			eventMan->pollEvent(event);
-			if (shouldQuit()) {
-				_graph->setPalette(palette);
-				free(blackPalette_);
-				return;
-			}
-			pausePrinceEngine();
-		}
-		_graph->setPalette(palette);
-		free(blackPalette_);
-	}
-}
-
 void PrinceEngine::pausePrinceEngine(int fps) {
 	int delay = 1000 / fps - int32(_system->getMillis() - _currentTime);
 	delay = delay < 0 ? 0 : delay;


Commit: 7352737a696e8b9889dce408482f8860cf92d287
    https://github.com/scummvm/scummvm/commit/7352737a696e8b9889dce408482f8860cf92d287
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2018-05-05T23:17:35+02:00

Commit Message:
PRINCE: Even more prince.cpp refactoring. Inventory and pathfinding

Changed paths:
  A engines/prince/inventory.cpp
  A engines/prince/walk.cpp
    engines/prince/draw.cpp
    engines/prince/module.mk
    engines/prince/prince.cpp


diff --git a/engines/prince/draw.cpp b/engines/prince/draw.cpp
index 6d330f6..a924f99 100644
--- a/engines/prince/draw.cpp
+++ b/engines/prince/draw.cpp
@@ -702,4 +702,64 @@ void PrinceEngine::setPalette(const byte *palette) {
 	}
 }
 
+void PrinceEngine::doTalkAnim(int animNumber, int slot, AnimType animType) {
+	Text &text = _textSlots[slot];
+	int lines = calcTextLines((const char *)_interpreter->getString());
+	int time = lines * 30;
+	if (animType == kNormalAnimation) {
+		Anim &normAnim = _normAnimList[animNumber];
+		if (normAnim._animData != nullptr) {
+			if (!normAnim._state) {
+				if (normAnim._currW && normAnim._currH) {
+					text._color = _flags->getFlagValue(Flags::KOLOR);
+					text._x = normAnim._currX + normAnim._currW / 2;
+					text._y = normAnim._currY - 10;
+				}
+			}
+		}
+	} else if (animType == kBackgroundAnimation) {
+		if (!_backAnimList[animNumber].backAnims.empty()) {
+			int currAnim = _backAnimList[animNumber]._seq._currRelative;
+			Anim &backAnim = _backAnimList[animNumber].backAnims[currAnim];
+			if (backAnim._animData != nullptr) {
+				if (!backAnim._state) {
+					if (backAnim._currW && backAnim._currH) {
+						text._color = _flags->getFlagValue(Flags::KOLOR);
+						text._x = backAnim._currX + backAnim._currW / 2;
+						text._y = backAnim._currY - 10;
+					}
+				}
+			}
+		}
+	} else {
+		error("doTalkAnim() - wrong animType: %d", animType);
+	}
+	text._time = time;
+	if (getLanguage() == Common::DE_DEU) {
+		correctStringDEU((char *)_interpreter->getString());
+	}
+	text._str = (const char *)_interpreter->getString();
+	_interpreter->increaseString();
+}
+
+void PrinceEngine::freeNormAnim(int slot) {
+	if (!_normAnimList.empty()) {
+		_normAnimList[slot]._state = 1;
+		if (_normAnimList[slot]._animData != nullptr) {
+			delete _normAnimList[slot]._animData;
+			_normAnimList[slot]._animData = nullptr;
+		}
+		if (_normAnimList[slot]._shadowData != nullptr) {
+			delete _normAnimList[slot]._shadowData;
+			_normAnimList[slot]._shadowData = nullptr;
+		}
+	}
+}
+
+void PrinceEngine::freeAllNormAnims() {
+	for (int i = 0; i < kMaxNormAnims; i++) {
+		freeNormAnim(i);
+	}
+}
+
 } // End of namespace Prince
diff --git a/engines/prince/inventory.cpp b/engines/prince/inventory.cpp
new file mode 100644
index 0000000..509eace
--- /dev/null
+++ b/engines/prince/inventory.cpp
@@ -0,0 +1,700 @@
+/* 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 "prince/prince.h"
+
+#include "prince/graphics.h"
+#include "prince/hero.h"
+#include "prince/script.h"
+#include "prince/mhwanh.h"
+#include "prince/variatxt.h"
+#include "prince/option_text.h"
+#include "prince/font.h"
+
+namespace Prince {
+
+void PrinceEngine::addInv(int heroId, int item, bool addItemQuiet) {
+	Hero *hero = nullptr;
+	if (!heroId) {
+		hero = _mainHero;
+	} else if (heroId == 1) {
+		hero = _secondHero;
+	}
+	if (hero != nullptr) {
+		if (hero->_inventory.size() < kMaxItems) {
+			if (item != 0x7FFF) {
+				hero->_inventory.push_back(item);
+			}
+			if (!addItemQuiet) {
+				addInvObj();
+			}
+			_interpreter->setResult(0);
+		} else {
+			_interpreter->setResult(1);
+		}
+	}
+}
+
+void PrinceEngine::remInv(int heroId, int item) {
+	Hero *hero = nullptr;
+	if (!heroId) {
+		hero = _mainHero;
+	} else if (heroId == 1) {
+		hero = _secondHero;
+	}
+	if (hero != nullptr) {
+		for (uint i = 0; i < hero->_inventory.size(); i++) {
+			if (hero->_inventory[i] == item) {
+				hero->_inventory.remove_at(i);
+				_interpreter->setResult(0);
+				return;
+			}
+		}
+	}
+	_interpreter->setResult(1);
+}
+
+void PrinceEngine::clearInv(int heroId) {
+	switch (heroId) {
+	case 0:
+		_mainHero->_inventory.clear();
+		break;
+	case 1:
+		_secondHero->_inventory.clear();
+		break;
+	default:
+		error("clearInv() - wrong hero slot");
+		break;
+	}
+}
+
+void PrinceEngine::swapInv(int heroId) {
+	Common::Array<int> tempInv;
+	Hero *hero = nullptr;
+	if (!heroId) {
+		hero = _mainHero;
+	} else if (heroId == 1) {
+		hero = _secondHero;
+	}
+	if (hero != nullptr) {
+		for (uint i = 0; i < hero->_inventory.size(); i++) {
+			tempInv.push_back(hero->_inventory[i]);
+		}
+		hero->_inventory.clear();
+		for (uint i = 0; i < hero->_inventory2.size(); i++) {
+			hero->_inventory.push_back(hero->_inventory2[i]);
+		}
+		hero->_inventory2.clear();
+		for (uint i = 0; i < tempInv.size(); i++) {
+			hero->_inventory2.push_back(tempInv[i]);
+		}
+		tempInv.clear();
+	}
+}
+
+void PrinceEngine::addInvObj() {
+	changeCursor(0);
+	prepareInventoryToView();
+
+	_inventoryBackgroundRemember = true;
+	drawScreen();
+
+	Graphics::Surface *suitcase = _suitcaseBmp->getSurface();
+
+	if (!_flags->getFlagValue(Flags::CURSEBLINK)) {
+
+		loadSample(27, "PRZEDMIO.WAV");
+		playSample(27, 0);
+
+		_mst_shadow2 = 1;
+
+		while (_mst_shadow2 < 512) {
+			rememberScreenInv();
+			_graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase);
+			drawInvItems();
+			_graph->update(_graph->_screenForInventory);
+			_mst_shadow2 += 50;
+			Common::Event event;
+			Common::EventManager *eventMan = _system->getEventManager();
+			eventMan->pollEvent(event);
+			if (shouldQuit()) {
+				return;
+			}
+			pausePrinceEngine();
+		}
+		while (_mst_shadow2 > 256) {
+			rememberScreenInv();
+			_graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase);
+			drawInvItems();
+			_graph->update(_graph->_screenForInventory);
+			_mst_shadow2 -= 42;
+			Common::Event event;
+			Common::EventManager *eventMan = _system->getEventManager();
+			eventMan->pollEvent(event);
+			if (shouldQuit()) {
+				return;
+			}
+			pausePrinceEngine();
+		}
+	} else {
+		//CURSEBLINK:
+		for (int i = 0; i < 3; i++) {
+			_mst_shadow2 = 256;
+			while (_mst_shadow2 < 512) {
+				rememberScreenInv();
+				_graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase);
+				drawInvItems();
+				_graph->update(_graph->_screenForInventory);
+				_mst_shadow2 += 50;
+				Common::Event event;
+				Common::EventManager *eventMan = _system->getEventManager();
+				eventMan->pollEvent(event);
+				if (shouldQuit()) {
+					return;
+				}
+				pausePrinceEngine();
+			}
+			while (_mst_shadow2 > 256) {
+				rememberScreenInv();
+				_graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase);
+				drawInvItems();
+				_graph->update(_graph->_screenForInventory);
+				_mst_shadow2 -= 50;
+				Common::Event event;
+				Common::EventManager *eventMan = _system->getEventManager();
+				eventMan->pollEvent(event);
+				if (shouldQuit()) {
+					return;
+				}
+				pausePrinceEngine();
+			}
+		}
+	}
+	_mst_shadow2 = 0;
+	for (int i = 0; i < 20; i++) {
+		rememberScreenInv();
+		_graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase);
+		drawInvItems();
+		_graph->update(_graph->_screenForInventory);
+		Common::Event event;
+		Common::EventManager *eventMan = _system->getEventManager();
+		eventMan->pollEvent(event);
+		if (shouldQuit()) {
+			return;
+		}
+		pausePrinceEngine();
+	}
+}
+
+void PrinceEngine::rememberScreenInv() {
+	_graph->_screenForInventory->copyFrom(*_graph->_frontScreen);
+}
+
+void PrinceEngine::inventoryFlagChange(bool inventoryState) {
+	if (inventoryState) {
+		_showInventoryFlag = true;
+		_inventoryBackgroundRemember = true;
+	} else {
+		_showInventoryFlag = false;
+	}
+}
+
+void PrinceEngine::prepareInventoryToView() {
+	_invMobList.clear();
+	int invItem = _mainHero->_inventory.size();
+	_invLine =  invItem / 3;
+	if (invItem % 3) {
+		_invLine++;
+	}
+	if (_invLine < 4) {
+		_invLine = 4;
+	}
+	_maxInvW = (374 - 2 * _invLine) / _invLine;
+	_invLineW = _maxInvW - 2;
+
+	int currInvX = _invLineX;
+	int currInvY = _invLineY;
+
+	Common::MemoryReadStream stream(_invTxt, _invTxtSize);
+	byte c;
+
+	uint item = 0;
+	for (int i = 0; i < _invLines; i++) {
+		for (int j = 0; j < _invLine; j++) {
+			Mob tempMobItem;
+			if (item < _mainHero->_inventory.size()) {
+				int itemNr = _mainHero->_inventory[item];
+				tempMobItem._visible = 0;
+				tempMobItem._mask =  itemNr;
+				tempMobItem._rect = Common::Rect(currInvX + _picWindowX, currInvY, currInvX + _picWindowX + _invLineW  - 1, currInvY + _invLineH - 1);
+				tempMobItem._type = 0; // to work with checkMob()
+
+				tempMobItem._name = "";
+				tempMobItem._examText = "";
+				int txtOffset = READ_LE_UINT32(&_invTxt[itemNr * 8]);
+				int examTxtOffset = READ_LE_UINT32(&_invTxt[itemNr * 8 + 4]);
+
+				stream.seek(txtOffset);
+				while ((c = stream.readByte())) {
+					tempMobItem._name += c;
+				}
+
+				stream.seek(examTxtOffset);
+				while ((c = stream.readByte())) {
+					tempMobItem._examText += c;
+				}
+				_invMobList.push_back(tempMobItem);
+			}
+			currInvX += _invLineW + _invLineSkipX;
+			item++;
+		}
+		currInvX = _invLineX;
+		currInvY += _invLineSkipY + _invLineH;
+	}
+}
+
+void PrinceEngine::drawInvItems() {
+	int currInvX = _invLineX;
+	int currInvY = _invLineY;
+	uint item = 0;
+	for (int i = 0; i < _invLines; i++) {
+		for (int j = 0; j < _invLine; j++) {
+			if (item < _mainHero->_inventory.size()) {
+				int itemNr = _mainHero->_inventory[item];
+				_mst_shadow = 0;
+				if (_mst_shadow2) {
+					if (!_flags->getFlagValue(Flags::CURSEBLINK)) {
+						if (item + 1 == _mainHero->_inventory.size()) { // last item in inventory
+							_mst_shadow = 1;
+						}
+					} else if (itemNr == 1 || itemNr == 3 || itemNr == 4 || itemNr == 7) {
+						_mst_shadow = 1;
+					}
+				}
+
+				int drawX = currInvX;
+				int drawY = currInvY;
+				Graphics::Surface *itemSurface = nullptr;
+				if (itemNr != 68) {
+					itemSurface = _allInvList[itemNr].getSurface();
+					if (itemSurface->h < _maxInvH) {
+						drawY += (_maxInvH - itemSurface->h) / 2;
+					}
+				} else {
+					// candle item:
+					if (_candleCounter == 8) {
+						_candleCounter = 0;
+					}
+					itemNr = _candleCounter;
+					_candleCounter++;
+					itemNr &= 7;
+					itemNr += 71;
+					itemSurface = _allInvList[itemNr].getSurface();
+					drawY += _allInvList[itemNr]._y + (_maxInvH - 76) / 2 - 200;
+				}
+				if (itemSurface->w < _maxInvW) {
+					drawX += (_maxInvW - itemSurface->w) / 2;
+				}
+				if (!_mst_shadow) {
+					_graph->drawTransparentSurface(_graph->_screenForInventory, drawX, drawY, itemSurface);
+				} else {
+					_mst_shadow = _mst_shadow2;
+					_graph->drawTransparentWithBlendSurface(_graph->_screenForInventory, drawX, drawY, itemSurface);
+				}
+			}
+			currInvX += _invLineW + _invLineSkipX;
+			item++;
+		}
+		currInvX = _invLineX;
+		currInvY += _invLineSkipY + _invLineH;
+	}
+}
+
+void PrinceEngine::inventoryLeftMouseButton() {
+	if (!_mouseFlag) {
+		_textSlots[0]._time = 0;
+		_textSlots[0]._str = nullptr;
+		stopSample(28);
+	}
+
+	if (_optionsFlag == 1) {
+		if (_selectedMob != -1)  {
+			if (_optionEnabled < _invOptionsNumber) {
+				_optionsFlag = 0;
+			} else {
+				return;
+			}
+		} else {
+			error("PrinceEngine::inventoryLeftMouseButton() - optionsFlag = 1, selectedMob = 0");
+			if (_currentPointerNumber == 2) {
+				changeCursor(1);
+				_currentPointerNumber = 1;
+				_selectedMob = -1;
+				_optionsMob = -1;
+				return;
+			} else {
+				return;
+			}
+		}
+	} else {
+		if (_selectedMob != -1) {
+			if (_currentPointerNumber != 2) {
+				if (_invMobList[_selectedMob]._mask != 29) {
+					_optionEnabled = 0;
+				} else {
+					// map item
+					_optionEnabled = 1;
+				}
+			} else {
+				//use_item_on_item
+				int invObjUU = _script->scanMobEventsWithItem(_invMobList[_selectedMob]._mask, _script->_scriptInfo.invObjUU, _selectedItem);
+				if (invObjUU == -1) {
+					int textNr = 80011; // "I can't do it."
+					if (_selectedItem == 31 || _invMobList[_selectedMob]._mask == 31) {
+						textNr = 80020; // "Nothing is happening."
+					}
+					_interpreter->setCurrentString(textNr);
+					printAt(0, 216, (char *)_variaTxt->getString(textNr - 80000), kNormalWidth / 2, 100);
+					setVoice(0, 28, 1);
+					playSample(28, 0);
+					_selectedMob = -1;
+					_optionsMob = -1;
+					return;
+				} else {
+					_interpreter->storeNewPC(invObjUU);
+					_flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask);
+					_showInventoryFlag = false;
+				}
+			}
+		} else {
+			return;
+		}
+	}
+	//do_option
+	if (_optionEnabled == 0) {
+		int invObjExamEvent = _script->scanMobEvents(_invMobList[_selectedMob]._mask, _script->_scriptInfo.invObjExam);
+		if (invObjExamEvent == -1) {
+			// do_standard
+			printAt(0, 216, (char *)_invMobList[_selectedMob]._examText.c_str(), kNormalWidth / 2, _invExamY);
+			_interpreter->setCurrentString(_invMobList[_selectedMob]._mask + 70000);
+			setVoice(0, 28, 1);
+			playSample(28, 0);
+			// disableuseuse
+			changeCursor(0);
+			_currentPointerNumber = 1;
+		} else {
+			_interpreter->storeNewPC(invObjExamEvent);
+			_flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask);
+			_showInventoryFlag = false;
+		}
+	} else if (_optionEnabled == 1) {
+		// not_examine
+		int invObjUse = _script->scanMobEvents(_invMobList[_selectedMob]._mask, _script->_scriptInfo.invObjUse);
+		if (invObjUse == -1) {
+			// do_standard_use
+			_selectedMode = 0;
+			_selectedItem = _invMobList[_selectedMob]._mask;
+			makeInvCursor(_invMobList[_selectedMob]._mask);
+			_currentPointerNumber = 2;
+			changeCursor(2);
+		} else {
+			_interpreter->storeNewPC(invObjUse);
+			_flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask);
+			_showInventoryFlag = false;
+		}
+	} else if (_optionEnabled == 4) {
+		// do_standard_give
+		_selectedMode = 1;
+		_selectedItem = _invMobList[_selectedMob]._mask;
+		makeInvCursor(_invMobList[_selectedMob]._mask);
+		_currentPointerNumber = 2;
+		changeCursor(2);
+	} else {
+		// use_item_on_item
+		int invObjUU = _script->scanMobEventsWithItem(_invMobList[_selectedMob]._mask, _script->_scriptInfo.invObjUU, _selectedItem);
+		if (invObjUU == -1) {
+			int textNr = 80011; // "I can't do it."
+			if (_selectedItem == 31 || _invMobList[_selectedMob]._mask == 31) {
+				textNr = 80020; // "Nothing is happening."
+			}
+			_interpreter->setCurrentString(textNr);
+			printAt(0, 216, (char *)_variaTxt->getString(textNr - 80000), kNormalWidth / 2, 100);
+			setVoice(0, 28, 1);
+			playSample(28, 0);
+		} else {
+			_interpreter->storeNewPC(invObjUU);
+			_flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask);
+			_showInventoryFlag = false;
+		}
+	}
+	_selectedMob = -1;
+	_optionsMob = -1;
+}
+
+void PrinceEngine::inventoryRightMouseButton() {
+	if (_textSlots[0]._str == nullptr) {
+		enableOptions(false);
+	}
+}
+
+void PrinceEngine::enableOptions(bool checkType) {
+	if (_optionsFlag != 1) {
+		changeCursor(1);
+		_currentPointerNumber = 1;
+		if (_selectedMob != -1) {
+			if (checkType) {
+				if (_mobList[_selectedMob]._type & 0x100) {
+					return;
+				}
+			}
+			Common::Point mousePos = _system->getEventManager()->getMousePos();
+			int x1 = mousePos.x - _optionsWidth / 2;
+			int x2 = mousePos.x + _optionsWidth / 2;
+			if (x1 < 0) {
+				x1 = 0;
+				x2 = _optionsWidth;
+			} else if (x2 >= kNormalWidth) {
+				x1 = kNormalWidth - _optionsWidth;
+				x2 = kNormalWidth;
+			}
+			int y1 = mousePos.y - 10;
+			if (y1 < 0) {
+				y1 = 0;
+			}
+			if (y1 + _optionsHeight >= kNormalHeight) {
+				y1 = kNormalHeight - _optionsHeight;
+			}
+			_optionsMob = _selectedMob;
+			_optionsX = x1;
+			_optionsY = y1;
+			_optionsFlag = 1;
+		}
+	}
+}
+
+void PrinceEngine::checkOptions() {
+	if (_optionsFlag) {
+		Common::Rect optionsRect(_optionsX, _optionsY, _optionsX + _optionsWidth, _optionsY + _optionsHeight);
+		Common::Point mousePos = _system->getEventManager()->getMousePos();
+		if (!optionsRect.contains(mousePos)) {
+			_optionsFlag = 0;
+			_selectedMob = -1;
+			return;
+		}
+		_graph->drawAsShadowSurface(_graph->_frontScreen, _optionsX, _optionsY, _optionsPic, _graph->_shadowTable50);
+
+		_optionEnabled = -1;
+		int optionsYCord = mousePos.y - (_optionsY + 16);
+		if (optionsYCord >= 0) {
+			int selectedOptionNr = optionsYCord / _optionsStep;
+			if (selectedOptionNr < _optionsNumber) {
+				_optionEnabled = selectedOptionNr;
+			}
+		}
+		int optionsColor;
+		int textY = _optionsY + 16;
+		for (int i = 0; i < _optionsNumber; i++) {
+			if (i != _optionEnabled) {
+				optionsColor = _optionsColor1;
+			} else {
+				optionsColor = _optionsColor2;
+			}
+			Common::String optText;
+			switch(getLanguage()) {
+			case Common::PL_POL:
+				optText = optionsTextPL[i];
+				break;
+			case Common::DE_DEU:
+				optText = optionsTextDE[i];
+				break;
+			case Common::EN_ANY:
+				optText = optionsTextEN[i];
+				break;
+			default:
+				break;
+			};
+			uint16 textW = getTextWidth(optText.c_str());
+			uint16 textX = _optionsX + _optionsWidth / 2 - textW / 2;
+			_font->drawString(_graph->_frontScreen, optText, textX, textY, textW, optionsColor);
+			textY += _optionsStep;
+		}
+	}
+}
+
+void PrinceEngine::checkInvOptions() {
+	if (_optionsFlag) {
+		Common::Rect optionsRect(_optionsX, _optionsY, _optionsX + _invOptionsWidth, _optionsY + _invOptionsHeight);
+		Common::Point mousePos = _system->getEventManager()->getMousePos();
+		if (!optionsRect.contains(mousePos)) {
+			_optionsFlag = 0;
+			_selectedMob = -1;
+			return;
+		}
+		_graph->drawAsShadowSurface(_graph->_screenForInventory, _optionsX, _optionsY, _optionsPicInInventory, _graph->_shadowTable50);
+
+		_optionEnabled = -1;
+		int optionsYCord = mousePos.y - (_optionsY + 16);
+		if (optionsYCord >= 0) {
+			int selectedOptionNr = optionsYCord / _invOptionsStep;
+			if (selectedOptionNr < _invOptionsNumber) {
+				_optionEnabled = selectedOptionNr;
+			}
+		}
+		int optionsColor;
+		int textY = _optionsY + 16;
+		for (int i = 0; i < _invOptionsNumber; i++) {
+			if (i != _optionEnabled) {
+				optionsColor = _optionsColor1;
+			} else {
+				optionsColor = _optionsColor2;
+			}
+			Common::String invText;
+			switch(getLanguage()) {
+			case Common::PL_POL:
+				invText = invOptionsTextPL[i];
+				break;
+			case Common::DE_DEU:
+				invText = invOptionsTextDE[i];
+				break;
+			case Common::EN_ANY:
+				invText = invOptionsTextEN[i];
+				break;
+			default:
+				error("Unknown game language %d", getLanguage());
+				break;
+			};
+			uint16 textW = getTextWidth(invText.c_str());
+			uint16 textX = _optionsX + _invOptionsWidth / 2 - textW / 2;
+			_font->drawString(_graph->_screenForInventory, invText, textX, textY, _graph->_screenForInventory->w, optionsColor);
+			textY += _invOptionsStep;
+		}
+	}
+}
+
+void PrinceEngine::displayInventory() {
+
+	_mainHero->freeOldMove();
+	_secondHero->freeOldMove();
+
+	_interpreter->setFgOpcodePC(0);
+
+	stopAllSamples();
+
+	prepareInventoryToView();
+
+	while (!shouldQuit()) {
+
+		if (_textSlots[0]._str != nullptr) {
+			changeCursor(0);
+		} else {
+			changeCursor(_currentPointerNumber);
+
+			Common::Rect inventoryRect(_invX1, _invY1, _invX1 + _invWidth, _invY1 + _invHeight);
+			Common::Point mousePos = _system->getEventManager()->getMousePos();
+
+			if (!_invCurInside && inventoryRect.contains(mousePos)) {
+				_invCurInside = true;
+			}
+
+			if (_invCurInside && !inventoryRect.contains(mousePos)) {
+				inventoryFlagChange(false);
+				_invCurInside = false;
+				break;
+			}
+		}
+
+		rememberScreenInv();
+
+		Graphics::Surface *suitcase = _suitcaseBmp->getSurface();
+		_graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase);
+
+		drawInvItems();
+
+		showTexts(_graph->_screenForInventory);
+
+		if (!_optionsFlag && _textSlots[0]._str == nullptr) {
+			_selectedMob = checkMob(_graph->_screenForInventory, _invMobList, false);
+		}
+
+		checkInvOptions();
+
+		Common::Event event;
+		Common::EventManager *eventMan = _system->getEventManager();
+		while (eventMan->pollEvent(event)) {
+			switch (event.type) {
+			case Common::EVENT_KEYDOWN:
+				keyHandler(event);
+				break;
+			case Common::EVENT_LBUTTONDOWN:
+				inventoryLeftMouseButton();
+				break;
+			case Common::EVENT_RBUTTONDOWN:
+				inventoryRightMouseButton();
+				break;
+			default:
+				break;
+			}
+		}
+
+		if (!_showInventoryFlag) {
+			break;
+		}
+
+		if (shouldQuit())
+			return;
+
+		getDebugger()->onFrame();
+		_graph->update(_graph->_screenForInventory);
+		pausePrinceEngine();
+	}
+
+	if (_currentPointerNumber == 2) {
+		_flags->setFlagValue(Flags::SELITEM, _selectedItem);
+	} else {
+		_flags->setFlagValue(Flags::SELITEM, 0);
+	}
+}
+
+void PrinceEngine::openInventoryCheck() {
+	if (!_optionsFlag) {
+		if (_mouseFlag == 1 || _mouseFlag == 2) {
+			if (_mainHero->_visible) {
+				if (!_flags->getFlagValue(Flags::INVALLOWED)) {
+					// 29 - Basement, 50 - Map
+					if (_locationNr != 29 && _locationNr != 50) {
+						Common::Point mousePos = _system->getEventManager()->getMousePos();
+						if (mousePos.y < 4 && !_showInventoryFlag) {
+							_invCounter++;
+						} else {
+							_invCounter = 0;
+						}
+						if (_invCounter >= _invMaxCount) {
+							inventoryFlagChange(true);
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+} // End of namespace Prince
diff --git a/engines/prince/module.mk b/engines/prince/module.mk
index 8446d07..ecc109a 100644
--- a/engines/prince/module.mk
+++ b/engines/prince/module.mk
@@ -12,6 +12,7 @@ MODULE_OBJS = \
 	font.o \
 	graphics.o \
 	hero.o \
+	inventory.o \
 	mhwanh.o \
 	music.o \
 	mob.o \
@@ -23,7 +24,8 @@ MODULE_OBJS = \
 	script.o \
 	sound.o \
 	variatxt.o \
-	videoplayer.o
+	videoplayer.o \
+	walk.o
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_PRINCE), DYNAMIC_PLUGIN)
diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp
index 654b87e..f29b8c2 100644
--- a/engines/prince/prince.cpp
+++ b/engines/prince/prince.cpp
@@ -51,7 +51,6 @@
 #include "prince/archive.h"
 #include "prince/hero.h"
 #include "prince/animation.h"
-#include "prince/option_text.h"
 #include "prince/curve_values.h"
 
 namespace Prince {
@@ -696,369 +695,6 @@ void PrinceEngine::pausePrinceEngine(int fps) {
 	_currentTime = _system->getMillis();
 }
 
-void PrinceEngine::addInv(int heroId, int item, bool addItemQuiet) {
-	Hero *hero = nullptr;
-	if (!heroId) {
-		hero = _mainHero;
-	} else if (heroId == 1) {
-		hero = _secondHero;
-	}
-	if (hero != nullptr) {
-		if (hero->_inventory.size() < kMaxItems) {
-			if (item != 0x7FFF) {
-				hero->_inventory.push_back(item);
-			}
-			if (!addItemQuiet) {
-				addInvObj();
-			}
-			_interpreter->setResult(0);
-		} else {
-			_interpreter->setResult(1);
-		}
-	}
-}
-
-void PrinceEngine::remInv(int heroId, int item) {
-	Hero *hero = nullptr;
-	if (!heroId) {
-		hero = _mainHero;
-	} else if (heroId == 1) {
-		hero = _secondHero;
-	}
-	if (hero != nullptr) {
-		for (uint i = 0; i < hero->_inventory.size(); i++) {
-			if (hero->_inventory[i] == item) {
-				hero->_inventory.remove_at(i);
-				_interpreter->setResult(0);
-				return;
-			}
-		}
-	}
-	_interpreter->setResult(1);
-}
-
-void PrinceEngine::clearInv(int heroId) {
-	switch (heroId) {
-	case 0:
-		_mainHero->_inventory.clear();
-		break;
-	case 1:
-		_secondHero->_inventory.clear();
-		break;
-	default:
-		error("clearInv() - wrong hero slot");
-		break;
-	}
-}
-
-void PrinceEngine::swapInv(int heroId) {
-	Common::Array<int> tempInv;
-	Hero *hero = nullptr;
-	if (!heroId) {
-		hero = _mainHero;
-	} else if (heroId == 1) {
-		hero = _secondHero;
-	}
-	if (hero != nullptr) {
-		for (uint i = 0; i < hero->_inventory.size(); i++) {
-			tempInv.push_back(hero->_inventory[i]);
-		}
-		hero->_inventory.clear();
-		for (uint i = 0; i < hero->_inventory2.size(); i++) {
-			hero->_inventory.push_back(hero->_inventory2[i]);
-		}
-		hero->_inventory2.clear();
-		for (uint i = 0; i < tempInv.size(); i++) {
-			hero->_inventory2.push_back(tempInv[i]);
-		}
-		tempInv.clear();
-	}
-}
-
-void PrinceEngine::addInvObj() {
-	changeCursor(0);
-	prepareInventoryToView();
-
-	_inventoryBackgroundRemember = true;
-	drawScreen();
-
-	Graphics::Surface *suitcase = _suitcaseBmp->getSurface();
-
-	if (!_flags->getFlagValue(Flags::CURSEBLINK)) {
-
-		loadSample(27, "PRZEDMIO.WAV");
-		playSample(27, 0);
-
-		_mst_shadow2 = 1;
-
-		while (_mst_shadow2 < 512) {
-			rememberScreenInv();
-			_graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase);
-			drawInvItems();
-			_graph->update(_graph->_screenForInventory);
-			_mst_shadow2 += 50;
-			Common::Event event;
-			Common::EventManager *eventMan = _system->getEventManager();
-			eventMan->pollEvent(event);
-			if (shouldQuit()) {
-				return;
-			}
-			pausePrinceEngine();
-		}
-		while (_mst_shadow2 > 256) {
-			rememberScreenInv();
-			_graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase);
-			drawInvItems();
-			_graph->update(_graph->_screenForInventory);
-			_mst_shadow2 -= 42;
-			Common::Event event;
-			Common::EventManager *eventMan = _system->getEventManager();
-			eventMan->pollEvent(event);
-			if (shouldQuit()) {
-				return;
-			}
-			pausePrinceEngine();
-		}
-	} else {
-		//CURSEBLINK:
-		for (int i = 0; i < 3; i++) {
-			_mst_shadow2 = 256;
-			while (_mst_shadow2 < 512) {
-				rememberScreenInv();
-				_graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase);
-				drawInvItems();
-				_graph->update(_graph->_screenForInventory);
-				_mst_shadow2 += 50;
-				Common::Event event;
-				Common::EventManager *eventMan = _system->getEventManager();
-				eventMan->pollEvent(event);
-				if (shouldQuit()) {
-					return;
-				}
-				pausePrinceEngine();
-			}
-			while (_mst_shadow2 > 256) {
-				rememberScreenInv();
-				_graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase);
-				drawInvItems();
-				_graph->update(_graph->_screenForInventory);
-				_mst_shadow2 -= 50;
-				Common::Event event;
-				Common::EventManager *eventMan = _system->getEventManager();
-				eventMan->pollEvent(event);
-				if (shouldQuit()) {
-					return;
-				}
-				pausePrinceEngine();
-			}
-		}
-	}
-	_mst_shadow2 = 0;
-	for (int i = 0; i < 20; i++) {
-		rememberScreenInv();
-		_graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase);
-		drawInvItems();
-		_graph->update(_graph->_screenForInventory);
-		Common::Event event;
-		Common::EventManager *eventMan = _system->getEventManager();
-		eventMan->pollEvent(event);
-		if (shouldQuit()) {
-			return;
-		}
-		pausePrinceEngine();
-	}
-}
-
-void PrinceEngine::rememberScreenInv() {
-	_graph->_screenForInventory->copyFrom(*_graph->_frontScreen);
-}
-
-void PrinceEngine::inventoryFlagChange(bool inventoryState) {
-	if (inventoryState) {
-		_showInventoryFlag = true;
-		_inventoryBackgroundRemember = true;
-	} else {
-		_showInventoryFlag = false;
-	}
-}
-
-void PrinceEngine::prepareInventoryToView() {
-	_invMobList.clear();
-	int invItem = _mainHero->_inventory.size();
-	_invLine =  invItem / 3;
-	if (invItem % 3) {
-		_invLine++;
-	}
-	if (_invLine < 4) {
-		_invLine = 4;
-	}
-	_maxInvW = (374 - 2 * _invLine) / _invLine;
-	_invLineW = _maxInvW - 2;
-
-	int currInvX = _invLineX;
-	int currInvY = _invLineY;
-
-	Common::MemoryReadStream stream(_invTxt, _invTxtSize);
-	byte c;
-
-	uint item = 0;
-	for (int i = 0; i < _invLines; i++) {
-		for (int j = 0; j < _invLine; j++) {
-			Mob tempMobItem;
-			if (item < _mainHero->_inventory.size()) {
-				int itemNr = _mainHero->_inventory[item];
-				tempMobItem._visible = 0;
-				tempMobItem._mask =  itemNr;
-				tempMobItem._rect = Common::Rect(currInvX + _picWindowX, currInvY, currInvX + _picWindowX + _invLineW  - 1, currInvY + _invLineH - 1);
-				tempMobItem._type = 0; // to work with checkMob()
-
-				tempMobItem._name = "";
-				tempMobItem._examText = "";
-				int txtOffset = READ_LE_UINT32(&_invTxt[itemNr * 8]);
-				int examTxtOffset = READ_LE_UINT32(&_invTxt[itemNr * 8 + 4]);
-
-				stream.seek(txtOffset);
-				while ((c = stream.readByte())) {
-					tempMobItem._name += c;
-				}
-
-				stream.seek(examTxtOffset);
-				while ((c = stream.readByte())) {
-					tempMobItem._examText += c;
-				}
-				_invMobList.push_back(tempMobItem);
-			}
-			currInvX += _invLineW + _invLineSkipX;
-			item++;
-		}
-		currInvX = _invLineX;
-		currInvY += _invLineSkipY + _invLineH;
-	}
-}
-
-void PrinceEngine::drawInvItems() {
-	int currInvX = _invLineX;
-	int currInvY = _invLineY;
-	uint item = 0;
-	for (int i = 0; i < _invLines; i++) {
-		for (int j = 0; j < _invLine; j++) {
-			if (item < _mainHero->_inventory.size()) {
-				int itemNr = _mainHero->_inventory[item];
-				_mst_shadow = 0;
-				if (_mst_shadow2) {
-					if (!_flags->getFlagValue(Flags::CURSEBLINK)) {
-						if (item + 1 == _mainHero->_inventory.size()) { // last item in inventory
-							_mst_shadow = 1;
-						}
-					} else if (itemNr == 1 || itemNr == 3 || itemNr == 4 || itemNr == 7) {
-						_mst_shadow = 1;
-					}
-				}
-
-				int drawX = currInvX;
-				int drawY = currInvY;
-				Graphics::Surface *itemSurface = nullptr;
-				if (itemNr != 68) {
-					itemSurface = _allInvList[itemNr].getSurface();
-					if (itemSurface->h < _maxInvH) {
-						drawY += (_maxInvH - itemSurface->h) / 2;
-					}
-				} else {
-					// candle item:
-					if (_candleCounter == 8) {
-						_candleCounter = 0;
-					}
-					itemNr = _candleCounter;
-					_candleCounter++;
-					itemNr &= 7;
-					itemNr += 71;
-					itemSurface = _allInvList[itemNr].getSurface();
-					drawY += _allInvList[itemNr]._y + (_maxInvH - 76) / 2 - 200;
-				}
-				if (itemSurface->w < _maxInvW) {
-					drawX += (_maxInvW - itemSurface->w) / 2;
-				}
-				if (!_mst_shadow) {
-					_graph->drawTransparentSurface(_graph->_screenForInventory, drawX, drawY, itemSurface);
-				} else {
-					_mst_shadow = _mst_shadow2;
-					_graph->drawTransparentWithBlendSurface(_graph->_screenForInventory, drawX, drawY, itemSurface);
-				}
-			}
-			currInvX += _invLineW + _invLineSkipX;
-			item++;
-		}
-		currInvX = _invLineX;
-		currInvY += _invLineSkipY + _invLineH;
-	}
-}
-
-void PrinceEngine::walkTo() {
-	if (_mainHero->_visible) {
-		_mainHero->freeHeroAnim();
-		_mainHero->freeOldMove();
-		_interpreter->storeNewPC(_script->_scriptInfo.usdCode);
-		int destX, destY;
-		if (_optionsMob != -1) {
-			destX = _mobList[_optionsMob]._examPosition.x;
-			destY = _mobList[_optionsMob]._examPosition.y;
-			_mainHero->_destDirection = _mobList[_optionsMob]._examDirection;
-		} else {
-			Common::Point mousePos = _system->getEventManager()->getMousePos();
-			destX = mousePos.x + _picWindowX;
-			destY = mousePos.y + _picWindowY;
-			_mainHero->_destDirection = 0;
-		}
-		_mainHero->_coords = makePath(kMainHero, _mainHero->_middleX, _mainHero->_middleY, destX, destY);
-		if (_mainHero->_coords != nullptr) {
-			_mainHero->_currCoords = _mainHero->_coords;
-			_mainHero->_dirTab = _directionTable;
-			_mainHero->_currDirTab = _directionTable;
-			_directionTable = nullptr;
-			_mainHero->_state = Hero::kHeroStateMove;
-			moveShandria();
-		}
-	}
-}
-
-void PrinceEngine::moveRunHero(int heroId, int x, int y, int dir, bool runHeroFlag) {
-	Hero *hero = nullptr;
-	if (!heroId) {
-		hero = _mainHero;
-	} else if (heroId == 1) {
-		hero = _secondHero;
-	}
-
-	if (hero != nullptr) {
-		if (dir) {
-			hero->_destDirection = dir;
-		}
-		if (x || y) {
-			hero->freeOldMove();
-			hero->_coords = makePath(heroId, hero->_middleX, hero->_middleY, x, y);
-			if (hero->_coords != nullptr) {
-				hero->_currCoords = hero->_coords;
-				hero->_dirTab = _directionTable;
-				hero->_currDirTab = _directionTable;
-				_directionTable = nullptr;
-				if (runHeroFlag) {
-					hero->_state = Hero::kHeroStateRun;
-				} else {
-					hero->_state = Hero::kHeroStateMove;
-				}
-				if (heroId == kMainHero && _mouseFlag) {
-					moveShandria();
-				}
-			}
-		} else {
-			hero->freeOldMove();
-			hero->_state = Hero::kHeroStateTurn;
-		}
-		hero->freeHeroAnim();
-		hero->_visible = 1;
-	}
-}
-
 void PrinceEngine::leftMouseButton() {
 	_flags->setFlagValue(Flags::ESCAPED2, 1); // skip intro animation
 	_flags->setFlagValue(Flags::LMOUSE, 1);
@@ -1159,351 +795,6 @@ void PrinceEngine::rightMouseButton() {
 	}
 }
 
-void PrinceEngine::inventoryLeftMouseButton() {
-	if (!_mouseFlag) {
-		_textSlots[0]._time = 0;
-		_textSlots[0]._str = nullptr;
-		stopSample(28);
-	}
-
-	if (_optionsFlag == 1) {
-		if (_selectedMob != -1)  {
-			if (_optionEnabled < _invOptionsNumber) {
-				_optionsFlag = 0;
-			} else {
-				return;
-			}
-		} else {
-			error("PrinceEngine::inventoryLeftMouseButton() - optionsFlag = 1, selectedMob = 0");
-			if (_currentPointerNumber == 2) {
-				changeCursor(1);
-				_currentPointerNumber = 1;
-				_selectedMob = -1;
-				_optionsMob = -1;
-				return;
-			} else {
-				return;
-			}
-		}
-	} else {
-		if (_selectedMob != -1) {
-			if (_currentPointerNumber != 2) {
-				if (_invMobList[_selectedMob]._mask != 29) {
-					_optionEnabled = 0;
-				} else {
-					// map item
-					_optionEnabled = 1;
-				}
-			} else {
-				//use_item_on_item
-				int invObjUU = _script->scanMobEventsWithItem(_invMobList[_selectedMob]._mask, _script->_scriptInfo.invObjUU, _selectedItem);
-				if (invObjUU == -1) {
-					int textNr = 80011; // "I can't do it."
-					if (_selectedItem == 31 || _invMobList[_selectedMob]._mask == 31) {
-						textNr = 80020; // "Nothing is happening."
-					}
-					_interpreter->setCurrentString(textNr);
-					printAt(0, 216, (char *)_variaTxt->getString(textNr - 80000), kNormalWidth / 2, 100);
-					setVoice(0, 28, 1);
-					playSample(28, 0);
-					_selectedMob = -1;
-					_optionsMob = -1;
-					return;
-				} else {
-					_interpreter->storeNewPC(invObjUU);
-					_flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask);
-					_showInventoryFlag = false;
-				}
-			}
-		} else {
-			return;
-		}
-	}
-	//do_option
-	if (_optionEnabled == 0) {
-		int invObjExamEvent = _script->scanMobEvents(_invMobList[_selectedMob]._mask, _script->_scriptInfo.invObjExam);
-		if (invObjExamEvent == -1) {
-			// do_standard
-			printAt(0, 216, (char *)_invMobList[_selectedMob]._examText.c_str(), kNormalWidth / 2, _invExamY);
-			_interpreter->setCurrentString(_invMobList[_selectedMob]._mask + 70000);
-			setVoice(0, 28, 1);
-			playSample(28, 0);
-			// disableuseuse
-			changeCursor(0);
-			_currentPointerNumber = 1;
-		} else {
-			_interpreter->storeNewPC(invObjExamEvent);
-			_flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask);
-			_showInventoryFlag = false;
-		}
-	} else if (_optionEnabled == 1) {
-		// not_examine
-		int invObjUse = _script->scanMobEvents(_invMobList[_selectedMob]._mask, _script->_scriptInfo.invObjUse);
-		if (invObjUse == -1) {
-			// do_standard_use
-			_selectedMode = 0;
-			_selectedItem = _invMobList[_selectedMob]._mask;
-			makeInvCursor(_invMobList[_selectedMob]._mask);
-			_currentPointerNumber = 2;
-			changeCursor(2);
-		} else {
-			_interpreter->storeNewPC(invObjUse);
-			_flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask);
-			_showInventoryFlag = false;
-		}
-	} else if (_optionEnabled == 4) {
-		// do_standard_give
-		_selectedMode = 1;
-		_selectedItem = _invMobList[_selectedMob]._mask;
-		makeInvCursor(_invMobList[_selectedMob]._mask);
-		_currentPointerNumber = 2;
-		changeCursor(2);
-	} else {
-		// use_item_on_item
-		int invObjUU = _script->scanMobEventsWithItem(_invMobList[_selectedMob]._mask, _script->_scriptInfo.invObjUU, _selectedItem);
-		if (invObjUU == -1) {
-			int textNr = 80011; // "I can't do it."
-			if (_selectedItem == 31 || _invMobList[_selectedMob]._mask == 31) {
-				textNr = 80020; // "Nothing is happening."
-			}
-			_interpreter->setCurrentString(textNr);
-			printAt(0, 216, (char *)_variaTxt->getString(textNr - 80000), kNormalWidth / 2, 100);
-			setVoice(0, 28, 1);
-			playSample(28, 0);
-		} else {
-			_interpreter->storeNewPC(invObjUU);
-			_flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask);
-			_showInventoryFlag = false;
-		}
-	}
-	_selectedMob = -1;
-	_optionsMob = -1;
-}
-
-void PrinceEngine::inventoryRightMouseButton() {
-	if (_textSlots[0]._str == nullptr) {
-		enableOptions(false);
-	}
-}
-
-void PrinceEngine::enableOptions(bool checkType) {
-	if (_optionsFlag != 1) {
-		changeCursor(1);
-		_currentPointerNumber = 1;
-		if (_selectedMob != -1) {
-			if (checkType) {
-				if (_mobList[_selectedMob]._type & 0x100) {
-					return;
-				}
-			}
-			Common::Point mousePos = _system->getEventManager()->getMousePos();
-			int x1 = mousePos.x - _optionsWidth / 2;
-			int x2 = mousePos.x + _optionsWidth / 2;
-			if (x1 < 0) {
-				x1 = 0;
-				x2 = _optionsWidth;
-			} else if (x2 >= kNormalWidth) {
-				x1 = kNormalWidth - _optionsWidth;
-				x2 = kNormalWidth;
-			}
-			int y1 = mousePos.y - 10;
-			if (y1 < 0) {
-				y1 = 0;
-			}
-			if (y1 + _optionsHeight >= kNormalHeight) {
-				y1 = kNormalHeight - _optionsHeight;
-			}
-			_optionsMob = _selectedMob;
-			_optionsX = x1;
-			_optionsY = y1;
-			_optionsFlag = 1;
-		}
-	}
-}
-
-void PrinceEngine::checkOptions() {
-	if (_optionsFlag) {
-		Common::Rect optionsRect(_optionsX, _optionsY, _optionsX + _optionsWidth, _optionsY + _optionsHeight);
-		Common::Point mousePos = _system->getEventManager()->getMousePos();
-		if (!optionsRect.contains(mousePos)) {
-			_optionsFlag = 0;
-			_selectedMob = -1;
-			return;
-		}
-		_graph->drawAsShadowSurface(_graph->_frontScreen, _optionsX, _optionsY, _optionsPic, _graph->_shadowTable50);
-
-		_optionEnabled = -1;
-		int optionsYCord = mousePos.y - (_optionsY + 16);
-		if (optionsYCord >= 0) {
-			int selectedOptionNr = optionsYCord / _optionsStep;
-			if (selectedOptionNr < _optionsNumber) {
-				_optionEnabled = selectedOptionNr;
-			}
-		}
-		int optionsColor;
-		int textY = _optionsY + 16;
-		for (int i = 0; i < _optionsNumber; i++) {
-			if (i != _optionEnabled) {
-				optionsColor = _optionsColor1;
-			} else {
-				optionsColor = _optionsColor2;
-			}
-			Common::String optText;
-			switch(getLanguage()) {
-			case Common::PL_POL:
-				optText = optionsTextPL[i];
-				break;
-			case Common::DE_DEU:
-				optText = optionsTextDE[i];
-				break;
-			case Common::EN_ANY:
-				optText = optionsTextEN[i];
-				break;
-			default:
-				break;
-			};
-			uint16 textW = getTextWidth(optText.c_str());
-			uint16 textX = _optionsX + _optionsWidth / 2 - textW / 2;
-			_font->drawString(_graph->_frontScreen, optText, textX, textY, textW, optionsColor);
-			textY += _optionsStep;
-		}
-	}
-}
-
-void PrinceEngine::checkInvOptions() {
-	if (_optionsFlag) {
-		Common::Rect optionsRect(_optionsX, _optionsY, _optionsX + _invOptionsWidth, _optionsY + _invOptionsHeight);
-		Common::Point mousePos = _system->getEventManager()->getMousePos();
-		if (!optionsRect.contains(mousePos)) {
-			_optionsFlag = 0;
-			_selectedMob = -1;
-			return;
-		}
-		_graph->drawAsShadowSurface(_graph->_screenForInventory, _optionsX, _optionsY, _optionsPicInInventory, _graph->_shadowTable50);
-
-		_optionEnabled = -1;
-		int optionsYCord = mousePos.y - (_optionsY + 16);
-		if (optionsYCord >= 0) {
-			int selectedOptionNr = optionsYCord / _invOptionsStep;
-			if (selectedOptionNr < _invOptionsNumber) {
-				_optionEnabled = selectedOptionNr;
-			}
-		}
-		int optionsColor;
-		int textY = _optionsY + 16;
-		for (int i = 0; i < _invOptionsNumber; i++) {
-			if (i != _optionEnabled) {
-				optionsColor = _optionsColor1;
-			} else {
-				optionsColor = _optionsColor2;
-			}
-			Common::String invText;
-			switch(getLanguage()) {
-			case Common::PL_POL:
-				invText = invOptionsTextPL[i];
-				break;
-			case Common::DE_DEU:
-				invText = invOptionsTextDE[i];
-				break;
-			case Common::EN_ANY:
-				invText = invOptionsTextEN[i];
-				break;
-			default:
-				error("Unknown game language %d", getLanguage());
-				break;
-			};
-			uint16 textW = getTextWidth(invText.c_str());
-			uint16 textX = _optionsX + _invOptionsWidth / 2 - textW / 2;
-			_font->drawString(_graph->_screenForInventory, invText, textX, textY, _graph->_screenForInventory->w, optionsColor);
-			textY += _invOptionsStep;
-		}
-	}
-}
-
-void PrinceEngine::displayInventory() {
-
-	_mainHero->freeOldMove();
-	_secondHero->freeOldMove();
-
-	_interpreter->setFgOpcodePC(0);
-
-	stopAllSamples();
-
-	prepareInventoryToView();
-
-	while (!shouldQuit()) {
-
-		if (_textSlots[0]._str != nullptr) {
-			changeCursor(0);
-		} else {
-			changeCursor(_currentPointerNumber);
-
-			Common::Rect inventoryRect(_invX1, _invY1, _invX1 + _invWidth, _invY1 + _invHeight);
-			Common::Point mousePos = _system->getEventManager()->getMousePos();
-
-			if (!_invCurInside && inventoryRect.contains(mousePos)) {
-				_invCurInside = true;
-			}
-
-			if (_invCurInside && !inventoryRect.contains(mousePos)) {
-				inventoryFlagChange(false);
-				_invCurInside = false;
-				break;
-			}
-		}
-
-		rememberScreenInv();
-
-		Graphics::Surface *suitcase = _suitcaseBmp->getSurface();
-		_graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase);
-
-		drawInvItems();
-
-		showTexts(_graph->_screenForInventory);
-
-		if (!_optionsFlag && _textSlots[0]._str == nullptr) {
-			_selectedMob = checkMob(_graph->_screenForInventory, _invMobList, false);
-		}
-
-		checkInvOptions();
-
-		Common::Event event;
-		Common::EventManager *eventMan = _system->getEventManager();
-		while (eventMan->pollEvent(event)) {
-			switch (event.type) {
-			case Common::EVENT_KEYDOWN:
-				keyHandler(event);
-				break;
-			case Common::EVENT_LBUTTONDOWN:
-				inventoryLeftMouseButton();
-				break;
-			case Common::EVENT_RBUTTONDOWN:
-				inventoryRightMouseButton();
-				break;
-			default:
-				break;
-			}
-		}
-
-		if (!_showInventoryFlag) {
-			break;
-		}
-
-		if (shouldQuit())
-			return;
-
-		getDebugger()->onFrame();
-		_graph->update(_graph->_screenForInventory);
-		pausePrinceEngine();
-	}
-
-	if (_currentPointerNumber == 2) {
-		_flags->setFlagValue(Flags::SELITEM, _selectedItem);
-	} else {
-		_flags->setFlagValue(Flags::SELITEM, 0);
-	}
-}
-
 void PrinceEngine::createDialogBox(int dialogBoxNr) {
 	_dialogLines = 0;
 	int amountOfDialogOptions = 0;
@@ -1672,66 +963,6 @@ void PrinceEngine::talkHero(int slot) {
 	_interpreter->increaseString();
 }
 
-void PrinceEngine::doTalkAnim(int animNumber, int slot, AnimType animType) {
-	Text &text = _textSlots[slot];
-	int lines = calcTextLines((const char *)_interpreter->getString());
-	int time = lines * 30;
-	if (animType == kNormalAnimation) {
-		Anim &normAnim = _normAnimList[animNumber];
-		if (normAnim._animData != nullptr) {
-			if (!normAnim._state) {
-				if (normAnim._currW && normAnim._currH) {
-					text._color = _flags->getFlagValue(Flags::KOLOR);
-					text._x = normAnim._currX + normAnim._currW / 2;
-					text._y = normAnim._currY - 10;
-				}
-			}
-		}
-	} else if (animType == kBackgroundAnimation) {
-		if (!_backAnimList[animNumber].backAnims.empty()) {
-			int currAnim = _backAnimList[animNumber]._seq._currRelative;
-			Anim &backAnim = _backAnimList[animNumber].backAnims[currAnim];
-			if (backAnim._animData != nullptr) {
-				if (!backAnim._state) {
-					if (backAnim._currW && backAnim._currH) {
-						text._color = _flags->getFlagValue(Flags::KOLOR);
-						text._x = backAnim._currX + backAnim._currW / 2;
-						text._y = backAnim._currY - 10;
-					}
-				}
-			}
-		}
-	} else {
-		error("doTalkAnim() - wrong animType: %d", animType);
-	}
-	text._time = time;
-	if (getLanguage() == Common::DE_DEU) {
-		correctStringDEU((char *)_interpreter->getString());
-	}
-	text._str = (const char *)_interpreter->getString();
-	_interpreter->increaseString();
-}
-
-void PrinceEngine::freeNormAnim(int slot) {
-	if (!_normAnimList.empty()) {
-		_normAnimList[slot]._state = 1;
-		if (_normAnimList[slot]._animData != nullptr) {
-			delete _normAnimList[slot]._animData;
-			_normAnimList[slot]._animData = nullptr;
-		}
-		if (_normAnimList[slot]._shadowData != nullptr) {
-			delete _normAnimList[slot]._shadowData;
-			_normAnimList[slot]._shadowData = nullptr;
-		}
-	}
-}
-
-void PrinceEngine::freeAllNormAnims() {
-	for (int i = 0; i < kMaxNormAnims; i++) {
-		freeNormAnim(i);
-	}
-}
-
 void PrinceEngine::getCurve() {
 	_flags->setFlagValue(Flags::TORX1, _curveData[_curvPos]);
 	_flags->setFlagValue(Flags::TORY1, _curveData[_curvPos + 1]);
@@ -1905,1544 +1136,6 @@ void PrinceEngine::scrollCredits() {
 	blackPalette();
 }
 
-// Modified version of Graphics::drawLine() to allow breaking the loop and return value
-int PrinceEngine::drawLine(int x0, int y0, int x1, int y1, int (*plotProc)(int, int, void *), void *data) {
-	// Bresenham's line algorithm, as described by Wikipedia
-	const bool steep = ABS(y1 - y0) > ABS(x1 - x0);
-
-	if (steep) {
-		SWAP(x0, y0);
-		SWAP(x1, y1);
-	}
-
-	const int delta_x = ABS(x1 - x0);
-	const int delta_y = ABS(y1 - y0);
-	const int delta_err = delta_y;
-	int x = x0;
-	int y = y0;
-	int err = 0;
-
-	const int x_step = (x0 < x1) ? 1 : -1;
-	const int y_step = (y0 < y1) ? 1 : -1;
-
-	int stopFlag = 0;
-	if (steep)
-		stopFlag = (*plotProc)(y, x, data);
-	else
-		stopFlag = (*plotProc)(x, y, data);
-
-	while (x != x1 && !stopFlag) {
-		x += x_step;
-		err += delta_err;
-		if (2 * err > delta_x) {
-			y += y_step;
-			err -= delta_x;
-		}
-		if (steep)
-			stopFlag = (*plotProc)(y, x, data);
-		else
-			stopFlag = (*plotProc)(x, y, data);
-	}
-	return stopFlag;
-}
-
-int PrinceEngine::getPixelAddr(byte *pathBitmap, int x, int y) {
-	int mask = 128 >> (x & 7);
-	byte value = pathBitmap[x / 8 + y * 80];
-	return (mask & value);
-}
-
-void PrinceEngine::findPoint(int x, int y) {
-	_fpX = x;
-	_fpY = y;
-
-	if (getPixelAddr(_roomPathBitmap, x, y)) {
-		return;
-	}
-
-	int fpL = x;
-	int fpU = y;
-	int fpR = x;
-	int fpD = y;
-
-	while (1) {
-		if (fpD != kMaxPicHeight) {
-			if (getPixelAddr(_roomPathBitmap, x, fpD)) {
-				_fpX = x;
-				_fpY = fpD;
-				break;
-			}
-			fpD++;
-		}
-		if (fpU) {
-			if (getPixelAddr(_roomPathBitmap, x, fpU)) {
-				_fpX = x;
-				_fpY = fpU;
-				break;
-			}
-			fpU--;
-		}
-		if (fpL) {
-			if (getPixelAddr(_roomPathBitmap, fpL, y)) {
-				_fpX = fpL;
-				_fpY = y;
-				break;
-			}
-			fpL--;
-		}
-		if (fpR != _sceneWidth) {
-			if (getPixelAddr(_roomPathBitmap, fpR, y)) {
-				_fpX = fpR;
-				_fpY = y;
-				break;
-			}
-			fpR++;
-		}
-		if (!fpU && (fpD == kMaxPicHeight)) {
-			if (!fpL && (fpR == _sceneWidth)) {
-				break;
-			}
-		}
-	}
-}
-
-Direction PrinceEngine::makeDirection(int x1, int y1, int x2, int y2) {
-	if (x1 != x2) {
-		if (y1 != y2) {
-			if (x1 > x2) {
-				if (y1 > y2) {
-					if (x1 - x2 >= y1 - y2) {
-						return kDirLU;
-					} else {
-						return kDirUL;
-					}
-				} else {
-					if (x1 - x2 >= y2 - y1) {
-						return kDirLD;
-					} else {
-						return kDirDL;
-					}
-				}
-			} else {
-				if (y1 > y2) {
-					if (x2 - x1 >= y1 - y2) {
-						return kDirRU;
-					} else {
-						return kDirUR;
-					}
-				} else {
-					if (x2 - x1 >= y2 - y1) {
-						return kDirRD;
-					} else {
-						return kDirDR;
-					}
-				}
-			}
-		} else {
-			if (x1 >= x2) {
-				return kDirL;
-			} else {
-				return kDirR;
-			}
-		}
-	} else {
-		if (y1 >= y2) {
-			return kDirU;
-		} else {
-			return kDirD;
-		}
-	}
-}
-
-void PrinceEngine::specialPlot(int x, int y) {
-	if (_coords < _coordsBufEnd) {
-		WRITE_LE_UINT16(_coords, x);
-		_coords += 2;
-		WRITE_LE_UINT16(_coords, y);
-		_coords += 2;
-		specialPlot2(x, y);
-	}
-}
-
-void PrinceEngine::specialPlot2(int x, int y) {
-	int mask = 128 >> (x & 7);
-	_roomPathBitmapTemp[x / 8 + y * 80] |= mask;
-}
-
-void PrinceEngine::specialPlotInside(int x, int y) {
-	if (_coords < _coordsBufEnd) {
-		WRITE_LE_UINT16(_coords, x);
-		_coords += 2;
-		WRITE_LE_UINT16(_coords, y);
-		_coords += 2;
-	}
-}
-
-int PrinceEngine::plotTraceLine(int x, int y, void *data) {
-	PrinceEngine *traceLine = (PrinceEngine *)data;
-	if (!traceLine->_traceLineFirstPointFlag) {
-		if (!traceLine->getPixelAddr(traceLine->_roomPathBitmapTemp, x, y)) {
-			if (traceLine->getPixelAddr(traceLine->_roomPathBitmap, x, y)) {
-				traceLine->specialPlotInside(x, y);
-				traceLine->_traceLineLen++;
-				return 0;
-			} else {
-				return -1;
-			}
-		} else {
-			return 1;
-		}
-	} else {
-		traceLine->_traceLineFirstPointFlag = false;
-		return 0;
-	}
-}
-
-int PrinceEngine::leftDownDir() {
-	if (!checkLeftDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	return -1;
-}
-
-int PrinceEngine::leftDir() {
-	if (!checkLeftDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	return -1;
-}
-
-int PrinceEngine::leftUpDir() {
-	if (!checkLeftUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	return -1;
-}
-
-int PrinceEngine::rightDownDir() {
-	if (!checkRightDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	return -1;
-}
-
-int PrinceEngine::rightDir() {
-	if (!checkRightDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	return -1;
-}
-
-int PrinceEngine::rightUpDir() {
-	if (!checkRightUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	return -1;
-}
-
-int PrinceEngine::upLeftDir() {
-	if (!checkLeftUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	return -1;
-}
-
-int PrinceEngine::upDir() {
-	if (!checkUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	return -1;
-}
-
-int PrinceEngine::upRightDir() {
-	if (!checkRightUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	return -1;
-}
-
-int PrinceEngine::downLeftDir() {
-	if (!checkLeftDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	return -1;
-}
-
-int PrinceEngine::downDir() {
-	if (!checkDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	return -1;
-}
-
-int PrinceEngine::downRightDir() {
-	if (!checkRightDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDownDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkRightUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	if (!checkLeftUpDir()) {
-		specialPlot(_checkX, _checkY);
-		return 0;
-	}
-	return -1;
-}
-
-int PrinceEngine::cpe() {
-	if ((*(_checkBitmap - kPBW) & _checkMask)) {
-		if ((*(_checkBitmap + kPBW) & _checkMask)) {
-			int value;
-			switch (_checkMask) {
-			case 128:
-				value = READ_LE_UINT16(_checkBitmap - 1);
-				value &= 0x4001;
-				if (value != 0x4001) {
-					return 0;
-				}
-				break;
-			case 64:
-				value = *_checkBitmap;
-				value &= 0xA0;
-				if (value != 0xA0) {
-					return 0;
-				}
-				break;
-			case 32:
-				value = *_checkBitmap;
-				value &= 0x50;
-				if (value != 0x50) {
-					return 0;
-				}
-				break;
-			case 16:
-				value = *_checkBitmap;
-				value &= 0x28;
-				if (value != 0x28) {
-					return 0;
-				}
-				break;
-			case 8:
-				value = *_checkBitmap;
-				value &= 0x14;
-				if (value != 0x14) {
-					return 0;
-				}
-				break;
-			case 4:
-				value = *_checkBitmap;
-				value &= 0xA;
-				if (value != 0xA) {
-					return 0;
-				}
-				break;
-			case 2:
-				value = *_checkBitmap;
-				value &= 0x5;
-				if (value != 0x5) {
-					return 0;
-				}
-				break;
-			case 1:
-				value = READ_LE_UINT16(_checkBitmap);
-				value &= 0x8002;
-				if (value != 0x8002) {
-					return 0;
-				}
-				break;
-			default:
-				error("Wrong _checkMask value - cpe()");
-				break;
-			}
-			_checkX = _rembX;
-			_checkY = _rembY;
-			_checkBitmapTemp = _rembBitmapTemp;
-			_checkBitmap = _rembBitmap;
-			_checkMask = _rembMask;
-			return -1;
-		}
-		return 0;
-	}
-	return 0;
-}
-
-int PrinceEngine::checkLeftDownDir() {
-	if (_checkX && _checkY != (kMaxPicHeight / 2 - 1)) {
-		int tempMask = _checkMask;
-		if (tempMask != 128) {
-			tempMask <<= 1;
-			if ((*(_checkBitmap + kPBW) & tempMask)) {
-				if (!(*(_checkBitmapTemp + kPBW) & tempMask)) {
-					_checkBitmap += kPBW;
-					_checkBitmapTemp += kPBW;
-					_checkMask = tempMask;
-				} else {
-					return 1;
-				}
-			} else {
-				return -1;
-			}
-		} else {
-			if ((*(_checkBitmap + kPBW - 1) & 1)) {
-				if (!(*(_checkBitmapTemp + kPBW - 1) & 1)) {
-					_checkBitmap += (kPBW - 1);
-					_checkBitmapTemp += (kPBW - 1);
-					_checkMask = 1;
-				} else {
-					return 1;
-				}
-			} else {
-				return -1;
-			}
-		}
-		_checkX--;
-		_checkY++;
-		return cpe();
-	} else {
-		return -1;
-	}
-}
-
-int PrinceEngine::checkLeftDir() {
-	if (_checkX) {
-		int tempMask = _checkMask;
-		if (tempMask != 128) {
-			tempMask <<= 1;
-			if ((*(_checkBitmap) & tempMask)) {
-				if (!(*(_checkBitmapTemp) & tempMask)) {
-					_checkMask = tempMask;
-				} else {
-					return 1;
-				}
-			} else {
-				return -1;
-			}
-		} else {
-			if ((*(_checkBitmap - 1) & 1)) {
-				if (!(*(_checkBitmapTemp - 1) & 1)) {
-					_checkBitmap--;
-					_checkBitmapTemp--;
-					_checkMask = 1;
-				} else {
-					return 1;
-				}
-			} else {
-				return -1;
-			}
-		}
-		_checkX--;
-		return cpe();
-	} else {
-		return -1;
-	}
-}
-
-int PrinceEngine::checkDownDir() {
-	if (_checkY != (kMaxPicHeight / 2 - 1)) {
-		if ((*(_checkBitmap + kPBW) & _checkMask)) {
-			if (!(*(_checkBitmapTemp + kPBW) & _checkMask)) {
-				_checkBitmap += kPBW;
-				_checkBitmapTemp += kPBW;
-				_checkY++;
-				return cpe();
-			} else {
-				return 1;
-			}
-		} else {
-			return -1;
-		}
-	} else {
-		return -1;
-	}
-}
-
-int PrinceEngine::checkUpDir() {
-	if (_checkY) {
-		if ((*(_checkBitmap - kPBW) & _checkMask)) {
-			if (!(*(_checkBitmapTemp - kPBW) & _checkMask)) {
-				_checkBitmap -= kPBW;
-				_checkBitmapTemp -= kPBW;
-				_checkY--;
-				return cpe();
-			} else {
-				return 1;
-			}
-		} else {
-			return -1;
-		}
-	} else {
-		return -1;
-	}
-}
-
-int PrinceEngine::checkRightDir() {
-	if (_checkX != (kMaxPicWidth / 2 - 1)) {
-		int tempMask = _checkMask;
-		if (tempMask != 1) {
-			tempMask >>= 1;
-			if ((*(_checkBitmap) & tempMask)) {
-				if (!(*(_checkBitmapTemp) & tempMask)) {
-					_checkMask = tempMask;
-				} else {
-					return 1;
-				}
-			} else {
-				return -1;
-			}
-		} else {
-			if ((*(_checkBitmap + 1) & 128)) {
-				if (!(*(_checkBitmapTemp + 1) & 128)) {
-					_checkBitmap++;
-					_checkBitmapTemp++;
-					_checkMask = 128;
-				} else {
-					return 1;
-				}
-			} else {
-				return -1;
-			}
-		}
-		_checkX++;
-		return cpe();
-	} else {
-		return -1;
-	}
-}
-
-int PrinceEngine::checkLeftUpDir() {
-	if (_checkX && _checkY) {
-		int tempMask = _checkMask;
-		if (tempMask != 128) {
-			tempMask <<= 1;
-			if ((*(_checkBitmap - kPBW) & tempMask)) {
-				if (!(*(_checkBitmapTemp - kPBW) & tempMask)) {
-					_checkBitmap -= kPBW;
-					_checkBitmapTemp -= kPBW;
-					_checkMask = tempMask;
-				} else {
-					return 1;
-				}
-			} else {
-				return -1;
-			}
-		} else {
-			if ((*(_checkBitmap - (kPBW + 1)) & 1)) {
-				if (!(*(_checkBitmapTemp - (kPBW + 1)) & 1)) {
-					_checkBitmap -= (kPBW + 1);
-					_checkBitmapTemp -= (kPBW + 1);
-					_checkMask = 1;
-				} else {
-					return 1;
-				}
-			} else {
-				return -1;
-			}
-		}
-		_checkX--;
-		_checkY--;
-		return cpe();
-	} else {
-		return -1;
-	}
-}
-
-int PrinceEngine::checkRightDownDir() {
-	if (_checkX != (kMaxPicWidth / 2 - 1) && _checkY != (kMaxPicHeight / 2 - 1)) {
-		int tempMask = _checkMask;
-		if (tempMask != 1) {
-			tempMask >>= 1;
-			if ((*(_checkBitmap + kPBW) & tempMask)) {
-				if (!(*(_checkBitmapTemp + kPBW) & tempMask)) {
-					_checkBitmap += kPBW;
-					_checkBitmapTemp += kPBW;
-					_checkMask = tempMask;
-				} else {
-					return 1;
-				}
-			} else {
-				return -1;
-			}
-		} else {
-			if ((*(_checkBitmap + kPBW + 1) & 128)) {
-				if (!(*(_checkBitmapTemp + kPBW + 1) & 128)) {
-					_checkBitmap += kPBW + 1;
-					_checkBitmapTemp += kPBW + 1;
-					_checkMask = 128;
-				} else {
-					return 1;
-				}
-			} else {
-				return -1;
-			}
-		}
-		_checkX++;
-		_checkY++;
-		return cpe();
-	} else {
-		return -1;
-	}
-}
-
-int PrinceEngine::checkRightUpDir() {
-	if (_checkX != (kMaxPicWidth / 2 - 1) && _checkY) {
-		int tempMask = _checkMask;
-		if (tempMask != 1) {
-			tempMask >>= 1;
-			if ((*(_checkBitmap - kPBW) & tempMask)) {
-				if (!(*(_checkBitmapTemp - kPBW) & tempMask)) {
-					_checkBitmap -= kPBW;
-					_checkBitmapTemp -= kPBW;
-					_checkMask = tempMask;
-				} else {
-					return 1;
-				}
-			} else {
-				return -1;
-			}
-		} else {
-			if ((*(_checkBitmap - kPBW + 1) & 128)) {
-				if (!(*(_checkBitmapTemp - kPBW + 1) & 128)) {
-					_checkBitmap -= (kPBW - 1);
-					_checkBitmapTemp -= (kPBW - 1);
-					_checkMask = 128;
-				} else {
-					return 1;
-				}
-			} else {
-				return -1;
-			}
-		}
-		_checkX++;
-		_checkY--;
-		return cpe();
-	} else {
-		return -1;
-	}
-}
-
-bool PrinceEngine::tracePath(int x1, int y1, int x2, int y2) {
-	for (uint i = 0; i < kPathBitmapLen; i++) {
-		_roomPathBitmapTemp[i] = 0;
-	}
-	if (x1 != x2 || y1 != y2) {
-		if (getPixelAddr(_roomPathBitmap, x1, y1)) {
-			if (getPixelAddr(_roomPathBitmap, x2, y2)) {
-				_coords = _coordsBuf;
-				specialPlot(x1, y1);
-
-				int x = x1;
-				int y = y1;
-
-				while (1) {
-					int btx = x;
-					int bty = y;
-					byte *bcad = _coords;
-
-					_traceLineLen = 0;
-					_traceLineFirstPointFlag = true;
-					int drawLineFlag = drawLine(x, y, x2, y2, &this->plotTraceLine, this);
-
-					if (!drawLineFlag) {
-						return true;
-					} else if (drawLineFlag == -1 && _traceLineLen >= 2) {
-						byte *tempCorrds = bcad;
-						while (tempCorrds != _coords) {
-							x = READ_LE_UINT16(tempCorrds);
-							y = READ_LE_UINT16(tempCorrds + 2);
-							tempCorrds += 4;
-							specialPlot2(x, y);
-						}
-					} else {
-						_coords = bcad;
-						x = btx;
-						y = bty;
-					}
-
-					Direction dir = makeDirection(x, y, x2, y2);
-
-					_rembBitmapTemp = &_roomPathBitmapTemp[x / 8 + y * 80];
-					_rembBitmap = &_roomPathBitmap[x / 8 + y * 80];
-					_rembMask = 128 >> (x & 7);
-					_rembX = x;
-					_rembY = y;
-
-					_checkBitmapTemp = _rembBitmapTemp;
-					_checkBitmap = _rembBitmap;
-					_checkMask = _rembMask;
-					_checkX = _rembX;
-					_checkY = _rembY;
-
-					int result;
-					switch (dir) {
-					case kDirLD:
-						result = leftDownDir();
-						break;
-					case kDirL:
-						result = leftDir();
-						break;
-					case kDirLU:
-						result = leftUpDir();
-						break;
-					case kDirRD:
-						result = rightDownDir();
-						break;
-					case kDirR:
-						result = rightDir();
-						break;
-					case kDirRU:
-						result = rightUpDir();
-						break;
-					case kDirUL:
-						result = upLeftDir();
-						break;
-					case kDirU:
-						result = upDir();
-						break;
-					case kDirUR:
-						result = upRightDir();
-						break;
-					case kDirDL:
-						result = downLeftDir();
-						break;
-					case kDirD:
-						result = downDir();
-						break;
-					case kDirDR:
-						result = downRightDir();
-						break;
-					default:
-						result = -1;
-						error("tracePath: wrong direction %d", dir);
-						break;
-					}
-
-					if (result) {
-						byte *tempCoords = _coords;
-						tempCoords -= 4;
-						if (tempCoords > _coordsBuf) {
-							int tempX = READ_LE_UINT16(tempCoords);
-							int tempY = READ_LE_UINT16(tempCoords + 2);
-							if (_checkX == tempX && _checkY == tempY) {
-								_coords = tempCoords;
-							}
-							x = READ_LE_UINT16(tempCoords);
-							y = READ_LE_UINT16(tempCoords + 2);
-						} else {
-							return false;
-						}
-					} else {
-						x = _checkX;
-						y = _checkY;
-					}
-				}
-				return true;
-			} else {
-				error("tracePath: wrong destination point");
-			}
-		} else {
-			error("tracePath: wrong start point");
-		}
-	} else {
-		error("tracePath: same point");
-	}
-}
-
-void PrinceEngine::specialPlotInside2(int x, int y) {
-	WRITE_LE_UINT16(_coords2, x);
-	_coords2 += 2;
-	WRITE_LE_UINT16(_coords2, y);
-	_coords2 += 2;
-}
-
-int PrinceEngine::plotTracePoint(int x, int y, void *data) {
-	PrinceEngine *tracePoint = (PrinceEngine *)data;
-	if (!tracePoint->_tracePointFirstPointFlag) {
-		if (tracePoint->getPixelAddr(tracePoint->_roomPathBitmap, x, y)) {
-			tracePoint->specialPlotInside2(x, y);
-			return 0;
-		} else {
-			return -1;
-		}
-	} else {
-		tracePoint->_tracePointFirstPointFlag = false;
-		return 0;
-	}
-}
-
-void PrinceEngine::approxPath() {
-	byte *oldCoords;
-	_coords2 = _coordsBuf2;
-	byte *tempCoordsBuf = _coordsBuf; // first point on path
-	byte *tempCoords = _coords;
-	if (tempCoordsBuf != tempCoords) {
-		tempCoords -= 4; // last point on path
-		while (tempCoordsBuf != tempCoords) {
-			int x1 = READ_LE_UINT16(tempCoords);
-			int y1 = READ_LE_UINT16(tempCoords + 2);
-			int x2 = READ_LE_UINT16(tempCoordsBuf);
-			int y2 = READ_LE_UINT16(tempCoordsBuf + 2);
-			tempCoordsBuf += 4;
-			//TracePoint
-			oldCoords = _coords2;
-			if (_coords2 == _coordsBuf2) {
-				WRITE_LE_UINT16(_coords2, x1);
-				WRITE_LE_UINT16(_coords2 + 2, y1);
-				_coords2 += 4;
-			} else {
-				int testX = READ_LE_UINT16(_coords2 - 4);
-				int testY = READ_LE_UINT16(_coords2 - 2);
-				if (testX != x1 || testY != y1) {
-					WRITE_LE_UINT16(_coords2, x1);
-					WRITE_LE_UINT16(_coords2 + 2, y1);
-					_coords2 += 4;
-				}
-			}
-			_tracePointFirstPointFlag = true;
-			bool drawLineFlag = drawLine(x1, y1, x2, y2, &this->plotTracePoint, this);
-			if (!drawLineFlag) {
-				tempCoords = tempCoordsBuf - 4;
-				tempCoordsBuf = _coordsBuf;
-			} else {
-				_coords2 = oldCoords;
-			}
-		}
-	}
-}
-
-void PrinceEngine::freeDirectionTable() {
-	if (_directionTable != nullptr) {
-		free(_directionTable);
-		_directionTable = nullptr;
-	}
-}
-
-int PrinceEngine::scanDirectionsFindNext(byte *tempCoordsBuf, int xDiff, int yDiff) {
-
-	int tempX, tempY, direction;
-
-	tempX = Hero::kHeroDirLeft;
-	if (xDiff < 0) {
-		tempX = Hero::kHeroDirRight;
-	}
-
-	tempY = Hero::kHeroDirUp;
-	if (yDiff < 0) {
-		tempY = Hero::kHeroDirDown;
-	}
-
-	while (1) {
-		int againPointX1 = READ_LE_UINT16(tempCoordsBuf);
-		int againPointY1 = READ_LE_UINT16(tempCoordsBuf + 2);
-		tempCoordsBuf += 4;
-
-		if (tempCoordsBuf == _coords) {
-			direction = tempX;
-			break;
-		}
-
-		int dX = againPointX1 - READ_LE_UINT16(tempCoordsBuf);
-		int dY = againPointY1 - READ_LE_UINT16(tempCoordsBuf + 2);
-
-		if (dX != xDiff) {
-			direction = tempY;
-			break;
-		}
-
-		if (dY != yDiff) {
-			direction = tempX;
-			break;
-		}
-	}
-	return direction;
-}
-
-void PrinceEngine::scanDirections() {
-	freeDirectionTable();
-	byte *tempCoordsBuf = _coordsBuf;
-	if (tempCoordsBuf != _coords) {
-		int size = (_coords - tempCoordsBuf) / 4 + 1; // number of coord points plus one for end marker
-		_directionTable = (byte *)malloc(size);
-		byte *tempDirTab = _directionTable;
-		int direction = -1;
-		int lastDirection = -1;
-
-		while (1) {
-			int x1 = READ_LE_UINT16(tempCoordsBuf);
-			int y1 = READ_LE_UINT16(tempCoordsBuf + 2);
-			tempCoordsBuf += 4;
-			if (tempCoordsBuf == _coords) {
-				break;
-			}
-			int x2 = READ_LE_UINT16(tempCoordsBuf);
-			int y2 = READ_LE_UINT16(tempCoordsBuf + 2);
-
-			int xDiff = x1 - x2;
-			int yDiff = y1 - y2;
-
-			if (xDiff) {
-				if (yDiff) {
-					if (lastDirection != -1) {
-						direction = lastDirection;
-						if (direction == Hero::kHeroDirLeft) {
-							if (xDiff < 0) {
-								direction = scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff);
-							}
-						} else if (direction == Hero::kHeroDirRight) {
-							if (xDiff >= 0) {
-								direction = scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff);
-							}
-						} else if (direction == Hero::kHeroDirUp) {
-							if (yDiff < 0) {
-								direction = scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff);
-							}
-						} else {
-							if (yDiff >= 0) {
-								direction = scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff);
-							}
-						}
-					} else {
-						direction = scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff);
-					}
-				} else {
-					direction = Hero::kHeroDirLeft;
-					if (xDiff < 0) {
-						direction = Hero::kHeroDirRight;
-					}
-				}
-			} else {
-				if (yDiff) {
-					direction = Hero::kHeroDirUp;
-					if (yDiff < 0) {
-						direction = Hero::kHeroDirDown;
-					}
-				} else {
-					direction = lastDirection;
-				}
-			}
-			lastDirection = direction;
-			*tempDirTab = direction;
-			tempDirTab++;
-		}
-		*tempDirTab = *(tempDirTab - 1);
-		tempDirTab++;
-		*tempDirTab = 0;
-	}
-}
-
-void PrinceEngine::moveShandria() {
-	int shanLen1 = _shanLen;
-	if (_flags->getFlagValue(Flags::SHANDOG)) {
-		_secondHero->freeHeroAnim();
-		_secondHero->freeOldMove();
-		byte *shanCoords = _mainHero->_currCoords + shanLen1 * 4 - 4;
-		int shanX = READ_LE_UINT16(shanCoords - 4);
-		int shanY = READ_LE_UINT16(shanCoords - 2);
-		int xDiff = shanX - _secondHero->_middleX;
-		if (xDiff < 0) {
-			xDiff *= -1;
-		}
-		int yDiff = shanY - _secondHero->_middleY;
-		if (yDiff < 0) {
-			yDiff *= -1;
-		}
-		shanCoords -= 4;
-		if (shanCoords != _mainHero->_currCoords) {
-			yDiff *= 1.5;
-			int shanDis =  xDiff * xDiff + yDiff * yDiff;
-			if (shanDis >= kMinDistance) {
-				while (1) {
-					shanCoords -= 4;
-					if (shanCoords == _mainHero->_currCoords) {
-						break;
-					}
-					int x = READ_LE_UINT16(shanCoords);
-					int y = READ_LE_UINT16(shanCoords + 2);
-					int pointDiffX = x - shanX;
-					if (pointDiffX < 0) {
-						pointDiffX *= -1;
-					}
-					int pointDiffY = y - shanY;
-					if (pointDiffY < 0) {
-						pointDiffY *= -1;
-					}
-					pointDiffY *= 1.5;
-					int distance = pointDiffX * pointDiffX + pointDiffY * pointDiffY;
-					if (distance >= kMinDistance) {
-						break;
-					}
-				}
-				int pathSizeDiff = (shanCoords - _mainHero->_currCoords) / 4;
-				int destDir = *(_mainHero->_currDirTab + pathSizeDiff);
-				_secondHero->_destDirection = destDir;
-				int destX = READ_LE_UINT16(shanCoords);
-				int destY = READ_LE_UINT16(shanCoords + 2);
-				_secondHero->_coords = makePath(kSecondHero, _secondHero->_middleX, _secondHero->_middleY, destX, destY);
-				if (_secondHero->_coords != nullptr) {
-					_secondHero->_currCoords = _secondHero->_coords;
-					int delay = shanLen1 - _shanLen;
-					if (delay < 6) {
-						delay = 6;
-					}
-					_secondHero->_moveDelay = delay / 2;
-					_secondHero->_state = Hero::kHeroStateDelayMove;
-					_secondHero->_dirTab = _directionTable;
-					_secondHero->_currDirTab = _directionTable;
-					_directionTable = nullptr;
-				}
-			}
-		}
-	}
-}
-
-byte *PrinceEngine::makePath(int heroId, int currX, int currY, int destX, int destY) {
-	int realDestX = destX;
-	int realDestY = destY;
-	_flags->setFlagValue(Flags::MOVEDESTX, destX);
-	_flags->setFlagValue(Flags::MOVEDESTY, destY);
-
-	int x1 = currX / 2;
-	int y1 = currY / 2;
-	int x2 = destX / 2;
-	int y2 = destY / 2;
-
-	if ((x1 != x2) || (y1 != y2)) {
-		findPoint(x1, y1);
-		if (!getPixelAddr(_roomPathBitmap, _fpX, _fpY)) {
-			return nullptr;
-		}
-		if ((x1 != _fpX) || (y1 != _fpY)) {
-			x1 = _fpX;
-			y1 = _fpY;
-		}
-		findPoint(x2, y2);
-		if (!getPixelAddr(_roomPathBitmap, _fpX, _fpY)) {
-			return nullptr;
-		}
-		if ((x2 != _fpX) || (y2 != _fpY)) {
-			x2 = _fpX;
-			y2 = _fpY;
-			if (!_flags->getFlagValue(Flags::EXACTMOVE)) {
-				realDestX = x2 * 2;
-				realDestY = y2 * 2;
-				_flags->setFlagValue(Flags::MOVEDESTX, realDestX);
-				_flags->setFlagValue(Flags::MOVEDESTY, realDestY);
-			} else {
-				return nullptr;
-			}
-		}
-
-		if ((x1 == x2) && (y1 == y2)) {
-			if (!heroId) {
-				_mainHero->freeOldMove();
-				_mainHero->_state = Hero::kHeroStateTurn;
-			} else if (heroId == 1) {
-				_secondHero->freeOldMove();
-				_secondHero->_state = Hero::kHeroStateTurn;
-			}
-			return nullptr;
-		}
-
-		int pathLen1 = 0;
-		int pathLen2 = 0;
-		int stX = x1;
-		int stY = y1;
-		int sizeCoords2 = 0;
-
-		if (tracePath(x1, y1, x2, y2)) {
-			allocCoords2();
-			approxPath();
-			sizeCoords2 = _coords2 - _coordsBuf2;
-			for (int i = 0; i < sizeCoords2; i++) {
-				_coordsBuf[i] = _coordsBuf2[i];
-			}
-			_coords = _coordsBuf + sizeCoords2;
-			approxPath();
-			_coordsBuf3 = _coordsBuf2;
-			_coordsBuf2 = nullptr;
-			_coords3 = _coords2;
-			_coords2 = nullptr;
-			pathLen1 = _coords3 - _coordsBuf3;
-		}
-		if (tracePath(x2, y2, x1, y1)) {
-			allocCoords2();
-			approxPath();
-			sizeCoords2 = _coords2 - _coordsBuf2;
-			for (int i = 0; i < sizeCoords2; i++) {
-				_coordsBuf[i] = _coordsBuf2[i];
-			}
-			_coords = _coordsBuf + sizeCoords2;
-			approxPath();
-			pathLen2 = _coords2 - _coordsBuf2;
-		}
-
-		byte *chosenCoordsBuf = _coordsBuf2;
-		byte *choosenCoords = _coords2;
-		int choosenLength = pathLen1;
-		if (pathLen1 < pathLen2) {
-			chosenCoordsBuf = _coordsBuf3;
-			choosenCoords = _coords3;
-			choosenLength = pathLen2;
-		}
-
-		if (choosenLength) {
-			if (chosenCoordsBuf != nullptr) {
-				int tempXBegin = READ_LE_UINT16(chosenCoordsBuf);
-				int tempYBegin = READ_LE_UINT16(chosenCoordsBuf + 2);
-				if (stX != tempXBegin || stY != tempYBegin) {
-					SWAP(chosenCoordsBuf, choosenCoords);
-					chosenCoordsBuf -= 4;
-					byte *tempCoordsBuf = _coordsBuf;
-					while (1) {
-						int cord = READ_LE_UINT32(chosenCoordsBuf);
-						WRITE_LE_UINT32(tempCoordsBuf, cord);
-						tempCoordsBuf += 4;
-						if (chosenCoordsBuf == choosenCoords) {
-							break;
-						}
-						chosenCoordsBuf -= 4;
-					}
-					_coords = tempCoordsBuf;
-				} else {
-					int sizeChoosen = choosenCoords - chosenCoordsBuf;
-					for (int i = 0; i < sizeChoosen; i++) {
-						_coordsBuf[i] = chosenCoordsBuf[i];
-					}
-					_coords = _coordsBuf + sizeChoosen;
-				}
-				WRITE_LE_UINT32(_coords, 0xFFFFFFFF);
-				freeCoords2();
-				freeCoords3();
-				scanDirections();
-
-				byte *tempCoordsBuf = _coordsBuf;
-				byte *tempCoords = _coords;
-				byte *newCoords;
-				if (tempCoordsBuf != tempCoords) {
-					int normCoordsSize = _coords - _coordsBuf + 4;
-					newCoords = (byte *)malloc(normCoordsSize);
-					byte *newCoordsBegin = newCoords;
-					while (tempCoordsBuf != tempCoords) {
-						int newValueX = READ_LE_UINT16(tempCoordsBuf);
-						WRITE_LE_UINT16(newCoords, newValueX * 2);
-						newCoords += 2;
-						int newValueY = READ_LE_UINT16(tempCoordsBuf + 2);
-						WRITE_LE_UINT16(newCoords, newValueY * 2);
-						newCoords += 2;
-						tempCoordsBuf += 4;
-					}
-					WRITE_LE_UINT16(newCoords - 4, realDestX);
-					WRITE_LE_UINT16(newCoords - 2, realDestY);
-					WRITE_LE_UINT32(newCoords, 0xFFFFFFFF);
-					newCoords += 4;
-					_shanLen = (newCoords - newCoordsBegin);
-					_shanLen /= 4;
-					return newCoordsBegin;
-				}
-			}
-		}
-		_coords = _coordsBuf;
-		freeCoords2();
-		freeCoords3();
-		return nullptr;
-	} else {
-		if (!heroId) {
-			_mainHero->freeOldMove();
-			_mainHero->_state = Hero::kHeroStateTurn;
-		} else if (heroId == 1) {
-			_secondHero->freeOldMove();
-			_secondHero->_state = Hero::kHeroStateTurn;
-		}
-		return nullptr;
-	}
-}
-
-void PrinceEngine::allocCoords2() {
-	if (_coordsBuf2 == nullptr) {
-		_coordsBuf2 = (byte *)malloc(kTracePts * 4);
-		_coords2 = _coordsBuf2;
-	}
-}
-
-void PrinceEngine::freeCoords2() {
-	if (_coordsBuf2 != nullptr) {
-		free(_coordsBuf2);
-		_coordsBuf2 = nullptr;
-		_coords2 = nullptr;
-	}
-}
-
-void PrinceEngine::freeCoords3() {
-	if (_coordsBuf3 != nullptr) {
-		free(_coordsBuf3);
-		_coordsBuf3 = nullptr;
-		_coords3 = nullptr;
-	}
-}
-
-void PrinceEngine::openInventoryCheck() {
-	if (!_optionsFlag) {
-		if (_mouseFlag == 1 || _mouseFlag == 2) {
-			if (_mainHero->_visible) {
-				if (!_flags->getFlagValue(Flags::INVALLOWED)) {
-					// 29 - Basement, 50 - Map
-					if (_locationNr != 29 && _locationNr != 50) {
-						Common::Point mousePos = _system->getEventManager()->getMousePos();
-						if (mousePos.y < 4 && !_showInventoryFlag) {
-							_invCounter++;
-						} else {
-							_invCounter = 0;
-						}
-						if (_invCounter >= _invMaxCount) {
-							inventoryFlagChange(true);
-						}
-					}
-				}
-			}
-		}
-	}
-}
-
 void PrinceEngine::mainLoop() {
 	changeCursor(0);
 	_currentTime = _system->getMillis();
diff --git a/engines/prince/walk.cpp b/engines/prince/walk.cpp
new file mode 100644
index 0000000..0e81c36
--- /dev/null
+++ b/engines/prince/walk.cpp
@@ -0,0 +1,1610 @@
+/* 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 "prince/prince.h"
+#include "prince/hero.h"
+#include "prince/script.h"
+
+namespace Prince {
+
+void PrinceEngine::walkTo() {
+	if (_mainHero->_visible) {
+		_mainHero->freeHeroAnim();
+		_mainHero->freeOldMove();
+		_interpreter->storeNewPC(_script->_scriptInfo.usdCode);
+		int destX, destY;
+		if (_optionsMob != -1) {
+			destX = _mobList[_optionsMob]._examPosition.x;
+			destY = _mobList[_optionsMob]._examPosition.y;
+			_mainHero->_destDirection = _mobList[_optionsMob]._examDirection;
+		} else {
+			Common::Point mousePos = _system->getEventManager()->getMousePos();
+			destX = mousePos.x + _picWindowX;
+			destY = mousePos.y + _picWindowY;
+			_mainHero->_destDirection = 0;
+		}
+		_mainHero->_coords = makePath(kMainHero, _mainHero->_middleX, _mainHero->_middleY, destX, destY);
+		if (_mainHero->_coords != nullptr) {
+			_mainHero->_currCoords = _mainHero->_coords;
+			_mainHero->_dirTab = _directionTable;
+			_mainHero->_currDirTab = _directionTable;
+			_directionTable = nullptr;
+			_mainHero->_state = Hero::kHeroStateMove;
+			moveShandria();
+		}
+	}
+}
+
+void PrinceEngine::moveRunHero(int heroId, int x, int y, int dir, bool runHeroFlag) {
+	Hero *hero = nullptr;
+	if (!heroId) {
+		hero = _mainHero;
+	} else if (heroId == 1) {
+		hero = _secondHero;
+	}
+
+	if (hero != nullptr) {
+		if (dir) {
+			hero->_destDirection = dir;
+		}
+		if (x || y) {
+			hero->freeOldMove();
+			hero->_coords = makePath(heroId, hero->_middleX, hero->_middleY, x, y);
+			if (hero->_coords != nullptr) {
+				hero->_currCoords = hero->_coords;
+				hero->_dirTab = _directionTable;
+				hero->_currDirTab = _directionTable;
+				_directionTable = nullptr;
+				if (runHeroFlag) {
+					hero->_state = Hero::kHeroStateRun;
+				} else {
+					hero->_state = Hero::kHeroStateMove;
+				}
+				if (heroId == kMainHero && _mouseFlag) {
+					moveShandria();
+				}
+			}
+		} else {
+			hero->freeOldMove();
+			hero->_state = Hero::kHeroStateTurn;
+		}
+		hero->freeHeroAnim();
+		hero->_visible = 1;
+	}
+}
+
+// Modified version of Graphics::drawLine() to allow breaking the loop and return value
+int PrinceEngine::drawLine(int x0, int y0, int x1, int y1, int (*plotProc)(int, int, void *), void *data) {
+	// Bresenham's line algorithm, as described by Wikipedia
+	const bool steep = ABS(y1 - y0) > ABS(x1 - x0);
+
+	if (steep) {
+		SWAP(x0, y0);
+		SWAP(x1, y1);
+	}
+
+	const int delta_x = ABS(x1 - x0);
+	const int delta_y = ABS(y1 - y0);
+	const int delta_err = delta_y;
+	int x = x0;
+	int y = y0;
+	int err = 0;
+
+	const int x_step = (x0 < x1) ? 1 : -1;
+	const int y_step = (y0 < y1) ? 1 : -1;
+
+	int stopFlag = 0;
+	if (steep)
+		stopFlag = (*plotProc)(y, x, data);
+	else
+		stopFlag = (*plotProc)(x, y, data);
+
+	while (x != x1 && !stopFlag) {
+		x += x_step;
+		err += delta_err;
+		if (2 * err > delta_x) {
+			y += y_step;
+			err -= delta_x;
+		}
+		if (steep)
+			stopFlag = (*plotProc)(y, x, data);
+		else
+			stopFlag = (*plotProc)(x, y, data);
+	}
+	return stopFlag;
+}
+
+int PrinceEngine::getPixelAddr(byte *pathBitmap, int x, int y) {
+	int mask = 128 >> (x & 7);
+	byte value = pathBitmap[x / 8 + y * 80];
+	return (mask & value);
+}
+
+void PrinceEngine::findPoint(int x, int y) {
+	_fpX = x;
+	_fpY = y;
+
+	if (getPixelAddr(_roomPathBitmap, x, y)) {
+		return;
+	}
+
+	int fpL = x;
+	int fpU = y;
+	int fpR = x;
+	int fpD = y;
+
+	while (1) {
+		if (fpD != kMaxPicHeight) {
+			if (getPixelAddr(_roomPathBitmap, x, fpD)) {
+				_fpX = x;
+				_fpY = fpD;
+				break;
+			}
+			fpD++;
+		}
+		if (fpU) {
+			if (getPixelAddr(_roomPathBitmap, x, fpU)) {
+				_fpX = x;
+				_fpY = fpU;
+				break;
+			}
+			fpU--;
+		}
+		if (fpL) {
+			if (getPixelAddr(_roomPathBitmap, fpL, y)) {
+				_fpX = fpL;
+				_fpY = y;
+				break;
+			}
+			fpL--;
+		}
+		if (fpR != _sceneWidth) {
+			if (getPixelAddr(_roomPathBitmap, fpR, y)) {
+				_fpX = fpR;
+				_fpY = y;
+				break;
+			}
+			fpR++;
+		}
+		if (!fpU && (fpD == kMaxPicHeight)) {
+			if (!fpL && (fpR == _sceneWidth)) {
+				break;
+			}
+		}
+	}
+}
+
+Direction PrinceEngine::makeDirection(int x1, int y1, int x2, int y2) {
+	if (x1 != x2) {
+		if (y1 != y2) {
+			if (x1 > x2) {
+				if (y1 > y2) {
+					if (x1 - x2 >= y1 - y2) {
+						return kDirLU;
+					} else {
+						return kDirUL;
+					}
+				} else {
+					if (x1 - x2 >= y2 - y1) {
+						return kDirLD;
+					} else {
+						return kDirDL;
+					}
+				}
+			} else {
+				if (y1 > y2) {
+					if (x2 - x1 >= y1 - y2) {
+						return kDirRU;
+					} else {
+						return kDirUR;
+					}
+				} else {
+					if (x2 - x1 >= y2 - y1) {
+						return kDirRD;
+					} else {
+						return kDirDR;
+					}
+				}
+			}
+		} else {
+			if (x1 >= x2) {
+				return kDirL;
+			} else {
+				return kDirR;
+			}
+		}
+	} else {
+		if (y1 >= y2) {
+			return kDirU;
+		} else {
+			return kDirD;
+		}
+	}
+}
+
+void PrinceEngine::specialPlot(int x, int y) {
+	if (_coords < _coordsBufEnd) {
+		WRITE_LE_UINT16(_coords, x);
+		_coords += 2;
+		WRITE_LE_UINT16(_coords, y);
+		_coords += 2;
+		specialPlot2(x, y);
+	}
+}
+
+void PrinceEngine::specialPlot2(int x, int y) {
+	int mask = 128 >> (x & 7);
+	_roomPathBitmapTemp[x / 8 + y * 80] |= mask;
+}
+
+void PrinceEngine::specialPlotInside(int x, int y) {
+	if (_coords < _coordsBufEnd) {
+		WRITE_LE_UINT16(_coords, x);
+		_coords += 2;
+		WRITE_LE_UINT16(_coords, y);
+		_coords += 2;
+	}
+}
+
+int PrinceEngine::plotTraceLine(int x, int y, void *data) {
+	PrinceEngine *traceLine = (PrinceEngine *)data;
+	if (!traceLine->_traceLineFirstPointFlag) {
+		if (!traceLine->getPixelAddr(traceLine->_roomPathBitmapTemp, x, y)) {
+			if (traceLine->getPixelAddr(traceLine->_roomPathBitmap, x, y)) {
+				traceLine->specialPlotInside(x, y);
+				traceLine->_traceLineLen++;
+				return 0;
+			} else {
+				return -1;
+			}
+		} else {
+			return 1;
+		}
+	} else {
+		traceLine->_traceLineFirstPointFlag = false;
+		return 0;
+	}
+}
+
+int PrinceEngine::leftDownDir() {
+	if (!checkLeftDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	return -1;
+}
+
+int PrinceEngine::leftDir() {
+	if (!checkLeftDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	return -1;
+}
+
+int PrinceEngine::leftUpDir() {
+	if (!checkLeftUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	return -1;
+}
+
+int PrinceEngine::rightDownDir() {
+	if (!checkRightDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	return -1;
+}
+
+int PrinceEngine::rightDir() {
+	if (!checkRightDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	return -1;
+}
+
+int PrinceEngine::rightUpDir() {
+	if (!checkRightUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	return -1;
+}
+
+int PrinceEngine::upLeftDir() {
+	if (!checkLeftUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	return -1;
+}
+
+int PrinceEngine::upDir() {
+	if (!checkUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	return -1;
+}
+
+int PrinceEngine::upRightDir() {
+	if (!checkRightUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	return -1;
+}
+
+int PrinceEngine::downLeftDir() {
+	if (!checkLeftDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	return -1;
+}
+
+int PrinceEngine::downDir() {
+	if (!checkDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	return -1;
+}
+
+int PrinceEngine::downRightDir() {
+	if (!checkRightDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDownDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkRightUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	if (!checkLeftUpDir()) {
+		specialPlot(_checkX, _checkY);
+		return 0;
+	}
+	return -1;
+}
+
+int PrinceEngine::cpe() {
+	if ((*(_checkBitmap - kPBW) & _checkMask)) {
+		if ((*(_checkBitmap + kPBW) & _checkMask)) {
+			int value;
+			switch (_checkMask) {
+			case 128:
+				value = READ_LE_UINT16(_checkBitmap - 1);
+				value &= 0x4001;
+				if (value != 0x4001) {
+					return 0;
+				}
+				break;
+			case 64:
+				value = *_checkBitmap;
+				value &= 0xA0;
+				if (value != 0xA0) {
+					return 0;
+				}
+				break;
+			case 32:
+				value = *_checkBitmap;
+				value &= 0x50;
+				if (value != 0x50) {
+					return 0;
+				}
+				break;
+			case 16:
+				value = *_checkBitmap;
+				value &= 0x28;
+				if (value != 0x28) {
+					return 0;
+				}
+				break;
+			case 8:
+				value = *_checkBitmap;
+				value &= 0x14;
+				if (value != 0x14) {
+					return 0;
+				}
+				break;
+			case 4:
+				value = *_checkBitmap;
+				value &= 0xA;
+				if (value != 0xA) {
+					return 0;
+				}
+				break;
+			case 2:
+				value = *_checkBitmap;
+				value &= 0x5;
+				if (value != 0x5) {
+					return 0;
+				}
+				break;
+			case 1:
+				value = READ_LE_UINT16(_checkBitmap);
+				value &= 0x8002;
+				if (value != 0x8002) {
+					return 0;
+				}
+				break;
+			default:
+				error("Wrong _checkMask value - cpe()");
+				break;
+			}
+			_checkX = _rembX;
+			_checkY = _rembY;
+			_checkBitmapTemp = _rembBitmapTemp;
+			_checkBitmap = _rembBitmap;
+			_checkMask = _rembMask;
+			return -1;
+		}
+		return 0;
+	}
+	return 0;
+}
+
+int PrinceEngine::checkLeftDownDir() {
+	if (_checkX && _checkY != (kMaxPicHeight / 2 - 1)) {
+		int tempMask = _checkMask;
+		if (tempMask != 128) {
+			tempMask <<= 1;
+			if ((*(_checkBitmap + kPBW) & tempMask)) {
+				if (!(*(_checkBitmapTemp + kPBW) & tempMask)) {
+					_checkBitmap += kPBW;
+					_checkBitmapTemp += kPBW;
+					_checkMask = tempMask;
+				} else {
+					return 1;
+				}
+			} else {
+				return -1;
+			}
+		} else {
+			if ((*(_checkBitmap + kPBW - 1) & 1)) {
+				if (!(*(_checkBitmapTemp + kPBW - 1) & 1)) {
+					_checkBitmap += (kPBW - 1);
+					_checkBitmapTemp += (kPBW - 1);
+					_checkMask = 1;
+				} else {
+					return 1;
+				}
+			} else {
+				return -1;
+			}
+		}
+		_checkX--;
+		_checkY++;
+		return cpe();
+	} else {
+		return -1;
+	}
+}
+
+int PrinceEngine::checkLeftDir() {
+	if (_checkX) {
+		int tempMask = _checkMask;
+		if (tempMask != 128) {
+			tempMask <<= 1;
+			if ((*(_checkBitmap) & tempMask)) {
+				if (!(*(_checkBitmapTemp) & tempMask)) {
+					_checkMask = tempMask;
+				} else {
+					return 1;
+				}
+			} else {
+				return -1;
+			}
+		} else {
+			if ((*(_checkBitmap - 1) & 1)) {
+				if (!(*(_checkBitmapTemp - 1) & 1)) {
+					_checkBitmap--;
+					_checkBitmapTemp--;
+					_checkMask = 1;
+				} else {
+					return 1;
+				}
+			} else {
+				return -1;
+			}
+		}
+		_checkX--;
+		return cpe();
+	} else {
+		return -1;
+	}
+}
+
+int PrinceEngine::checkDownDir() {
+	if (_checkY != (kMaxPicHeight / 2 - 1)) {
+		if ((*(_checkBitmap + kPBW) & _checkMask)) {
+			if (!(*(_checkBitmapTemp + kPBW) & _checkMask)) {
+				_checkBitmap += kPBW;
+				_checkBitmapTemp += kPBW;
+				_checkY++;
+				return cpe();
+			} else {
+				return 1;
+			}
+		} else {
+			return -1;
+		}
+	} else {
+		return -1;
+	}
+}
+
+int PrinceEngine::checkUpDir() {
+	if (_checkY) {
+		if ((*(_checkBitmap - kPBW) & _checkMask)) {
+			if (!(*(_checkBitmapTemp - kPBW) & _checkMask)) {
+				_checkBitmap -= kPBW;
+				_checkBitmapTemp -= kPBW;
+				_checkY--;
+				return cpe();
+			} else {
+				return 1;
+			}
+		} else {
+			return -1;
+		}
+	} else {
+		return -1;
+	}
+}
+
+int PrinceEngine::checkRightDir() {
+	if (_checkX != (kMaxPicWidth / 2 - 1)) {
+		int tempMask = _checkMask;
+		if (tempMask != 1) {
+			tempMask >>= 1;
+			if ((*(_checkBitmap) & tempMask)) {
+				if (!(*(_checkBitmapTemp) & tempMask)) {
+					_checkMask = tempMask;
+				} else {
+					return 1;
+				}
+			} else {
+				return -1;
+			}
+		} else {
+			if ((*(_checkBitmap + 1) & 128)) {
+				if (!(*(_checkBitmapTemp + 1) & 128)) {
+					_checkBitmap++;
+					_checkBitmapTemp++;
+					_checkMask = 128;
+				} else {
+					return 1;
+				}
+			} else {
+				return -1;
+			}
+		}
+		_checkX++;
+		return cpe();
+	} else {
+		return -1;
+	}
+}
+
+int PrinceEngine::checkLeftUpDir() {
+	if (_checkX && _checkY) {
+		int tempMask = _checkMask;
+		if (tempMask != 128) {
+			tempMask <<= 1;
+			if ((*(_checkBitmap - kPBW) & tempMask)) {
+				if (!(*(_checkBitmapTemp - kPBW) & tempMask)) {
+					_checkBitmap -= kPBW;
+					_checkBitmapTemp -= kPBW;
+					_checkMask = tempMask;
+				} else {
+					return 1;
+				}
+			} else {
+				return -1;
+			}
+		} else {
+			if ((*(_checkBitmap - (kPBW + 1)) & 1)) {
+				if (!(*(_checkBitmapTemp - (kPBW + 1)) & 1)) {
+					_checkBitmap -= (kPBW + 1);
+					_checkBitmapTemp -= (kPBW + 1);
+					_checkMask = 1;
+				} else {
+					return 1;
+				}
+			} else {
+				return -1;
+			}
+		}
+		_checkX--;
+		_checkY--;
+		return cpe();
+	} else {
+		return -1;
+	}
+}
+
+int PrinceEngine::checkRightDownDir() {
+	if (_checkX != (kMaxPicWidth / 2 - 1) && _checkY != (kMaxPicHeight / 2 - 1)) {
+		int tempMask = _checkMask;
+		if (tempMask != 1) {
+			tempMask >>= 1;
+			if ((*(_checkBitmap + kPBW) & tempMask)) {
+				if (!(*(_checkBitmapTemp + kPBW) & tempMask)) {
+					_checkBitmap += kPBW;
+					_checkBitmapTemp += kPBW;
+					_checkMask = tempMask;
+				} else {
+					return 1;
+				}
+			} else {
+				return -1;
+			}
+		} else {
+			if ((*(_checkBitmap + kPBW + 1) & 128)) {
+				if (!(*(_checkBitmapTemp + kPBW + 1) & 128)) {
+					_checkBitmap += kPBW + 1;
+					_checkBitmapTemp += kPBW + 1;
+					_checkMask = 128;
+				} else {
+					return 1;
+				}
+			} else {
+				return -1;
+			}
+		}
+		_checkX++;
+		_checkY++;
+		return cpe();
+	} else {
+		return -1;
+	}
+}
+
+int PrinceEngine::checkRightUpDir() {
+	if (_checkX != (kMaxPicWidth / 2 - 1) && _checkY) {
+		int tempMask = _checkMask;
+		if (tempMask != 1) {
+			tempMask >>= 1;
+			if ((*(_checkBitmap - kPBW) & tempMask)) {
+				if (!(*(_checkBitmapTemp - kPBW) & tempMask)) {
+					_checkBitmap -= kPBW;
+					_checkBitmapTemp -= kPBW;
+					_checkMask = tempMask;
+				} else {
+					return 1;
+				}
+			} else {
+				return -1;
+			}
+		} else {
+			if ((*(_checkBitmap - kPBW + 1) & 128)) {
+				if (!(*(_checkBitmapTemp - kPBW + 1) & 128)) {
+					_checkBitmap -= (kPBW - 1);
+					_checkBitmapTemp -= (kPBW - 1);
+					_checkMask = 128;
+				} else {
+					return 1;
+				}
+			} else {
+				return -1;
+			}
+		}
+		_checkX++;
+		_checkY--;
+		return cpe();
+	} else {
+		return -1;
+	}
+}
+
+bool PrinceEngine::tracePath(int x1, int y1, int x2, int y2) {
+	for (uint i = 0; i < kPathBitmapLen; i++) {
+		_roomPathBitmapTemp[i] = 0;
+	}
+	if (x1 != x2 || y1 != y2) {
+		if (getPixelAddr(_roomPathBitmap, x1, y1)) {
+			if (getPixelAddr(_roomPathBitmap, x2, y2)) {
+				_coords = _coordsBuf;
+				specialPlot(x1, y1);
+
+				int x = x1;
+				int y = y1;
+
+				while (1) {
+					int btx = x;
+					int bty = y;
+					byte *bcad = _coords;
+
+					_traceLineLen = 0;
+					_traceLineFirstPointFlag = true;
+					int drawLineFlag = drawLine(x, y, x2, y2, &this->plotTraceLine, this);
+
+					if (!drawLineFlag) {
+						return true;
+					} else if (drawLineFlag == -1 && _traceLineLen >= 2) {
+						byte *tempCorrds = bcad;
+						while (tempCorrds != _coords) {
+							x = READ_LE_UINT16(tempCorrds);
+							y = READ_LE_UINT16(tempCorrds + 2);
+							tempCorrds += 4;
+							specialPlot2(x, y);
+						}
+					} else {
+						_coords = bcad;
+						x = btx;
+						y = bty;
+					}
+
+					Direction dir = makeDirection(x, y, x2, y2);
+
+					_rembBitmapTemp = &_roomPathBitmapTemp[x / 8 + y * 80];
+					_rembBitmap = &_roomPathBitmap[x / 8 + y * 80];
+					_rembMask = 128 >> (x & 7);
+					_rembX = x;
+					_rembY = y;
+
+					_checkBitmapTemp = _rembBitmapTemp;
+					_checkBitmap = _rembBitmap;
+					_checkMask = _rembMask;
+					_checkX = _rembX;
+					_checkY = _rembY;
+
+					int result;
+					switch (dir) {
+					case kDirLD:
+						result = leftDownDir();
+						break;
+					case kDirL:
+						result = leftDir();
+						break;
+					case kDirLU:
+						result = leftUpDir();
+						break;
+					case kDirRD:
+						result = rightDownDir();
+						break;
+					case kDirR:
+						result = rightDir();
+						break;
+					case kDirRU:
+						result = rightUpDir();
+						break;
+					case kDirUL:
+						result = upLeftDir();
+						break;
+					case kDirU:
+						result = upDir();
+						break;
+					case kDirUR:
+						result = upRightDir();
+						break;
+					case kDirDL:
+						result = downLeftDir();
+						break;
+					case kDirD:
+						result = downDir();
+						break;
+					case kDirDR:
+						result = downRightDir();
+						break;
+					default:
+						result = -1;
+						error("tracePath: wrong direction %d", dir);
+						break;
+					}
+
+					if (result) {
+						byte *tempCoords = _coords;
+						tempCoords -= 4;
+						if (tempCoords > _coordsBuf) {
+							int tempX = READ_LE_UINT16(tempCoords);
+							int tempY = READ_LE_UINT16(tempCoords + 2);
+							if (_checkX == tempX && _checkY == tempY) {
+								_coords = tempCoords;
+							}
+							x = READ_LE_UINT16(tempCoords);
+							y = READ_LE_UINT16(tempCoords + 2);
+						} else {
+							return false;
+						}
+					} else {
+						x = _checkX;
+						y = _checkY;
+					}
+				}
+				return true;
+			} else {
+				error("tracePath: wrong destination point");
+			}
+		} else {
+			error("tracePath: wrong start point");
+		}
+	} else {
+		error("tracePath: same point");
+	}
+}
+
+void PrinceEngine::specialPlotInside2(int x, int y) {
+	WRITE_LE_UINT16(_coords2, x);
+	_coords2 += 2;
+	WRITE_LE_UINT16(_coords2, y);
+	_coords2 += 2;
+}
+
+int PrinceEngine::plotTracePoint(int x, int y, void *data) {
+	PrinceEngine *tracePoint = (PrinceEngine *)data;
+	if (!tracePoint->_tracePointFirstPointFlag) {
+		if (tracePoint->getPixelAddr(tracePoint->_roomPathBitmap, x, y)) {
+			tracePoint->specialPlotInside2(x, y);
+			return 0;
+		} else {
+			return -1;
+		}
+	} else {
+		tracePoint->_tracePointFirstPointFlag = false;
+		return 0;
+	}
+}
+
+void PrinceEngine::approxPath() {
+	byte *oldCoords;
+	_coords2 = _coordsBuf2;
+	byte *tempCoordsBuf = _coordsBuf; // first point on path
+	byte *tempCoords = _coords;
+	if (tempCoordsBuf != tempCoords) {
+		tempCoords -= 4; // last point on path
+		while (tempCoordsBuf != tempCoords) {
+			int x1 = READ_LE_UINT16(tempCoords);
+			int y1 = READ_LE_UINT16(tempCoords + 2);
+			int x2 = READ_LE_UINT16(tempCoordsBuf);
+			int y2 = READ_LE_UINT16(tempCoordsBuf + 2);
+			tempCoordsBuf += 4;
+			//TracePoint
+			oldCoords = _coords2;
+			if (_coords2 == _coordsBuf2) {
+				WRITE_LE_UINT16(_coords2, x1);
+				WRITE_LE_UINT16(_coords2 + 2, y1);
+				_coords2 += 4;
+			} else {
+				int testX = READ_LE_UINT16(_coords2 - 4);
+				int testY = READ_LE_UINT16(_coords2 - 2);
+				if (testX != x1 || testY != y1) {
+					WRITE_LE_UINT16(_coords2, x1);
+					WRITE_LE_UINT16(_coords2 + 2, y1);
+					_coords2 += 4;
+				}
+			}
+			_tracePointFirstPointFlag = true;
+			bool drawLineFlag = drawLine(x1, y1, x2, y2, &this->plotTracePoint, this);
+			if (!drawLineFlag) {
+				tempCoords = tempCoordsBuf - 4;
+				tempCoordsBuf = _coordsBuf;
+			} else {
+				_coords2 = oldCoords;
+			}
+		}
+	}
+}
+
+void PrinceEngine::freeDirectionTable() {
+	if (_directionTable != nullptr) {
+		free(_directionTable);
+		_directionTable = nullptr;
+	}
+}
+
+int PrinceEngine::scanDirectionsFindNext(byte *tempCoordsBuf, int xDiff, int yDiff) {
+
+	int tempX, tempY, direction;
+
+	tempX = Hero::kHeroDirLeft;
+	if (xDiff < 0) {
+		tempX = Hero::kHeroDirRight;
+	}
+
+	tempY = Hero::kHeroDirUp;
+	if (yDiff < 0) {
+		tempY = Hero::kHeroDirDown;
+	}
+
+	while (1) {
+		int againPointX1 = READ_LE_UINT16(tempCoordsBuf);
+		int againPointY1 = READ_LE_UINT16(tempCoordsBuf + 2);
+		tempCoordsBuf += 4;
+
+		if (tempCoordsBuf == _coords) {
+			direction = tempX;
+			break;
+		}
+
+		int dX = againPointX1 - READ_LE_UINT16(tempCoordsBuf);
+		int dY = againPointY1 - READ_LE_UINT16(tempCoordsBuf + 2);
+
+		if (dX != xDiff) {
+			direction = tempY;
+			break;
+		}
+
+		if (dY != yDiff) {
+			direction = tempX;
+			break;
+		}
+	}
+	return direction;
+}
+
+void PrinceEngine::scanDirections() {
+	freeDirectionTable();
+	byte *tempCoordsBuf = _coordsBuf;
+	if (tempCoordsBuf != _coords) {
+		int size = (_coords - tempCoordsBuf) / 4 + 1; // number of coord points plus one for end marker
+		_directionTable = (byte *)malloc(size);
+		byte *tempDirTab = _directionTable;
+		int direction = -1;
+		int lastDirection = -1;
+
+		while (1) {
+			int x1 = READ_LE_UINT16(tempCoordsBuf);
+			int y1 = READ_LE_UINT16(tempCoordsBuf + 2);
+			tempCoordsBuf += 4;
+			if (tempCoordsBuf == _coords) {
+				break;
+			}
+			int x2 = READ_LE_UINT16(tempCoordsBuf);
+			int y2 = READ_LE_UINT16(tempCoordsBuf + 2);
+
+			int xDiff = x1 - x2;
+			int yDiff = y1 - y2;
+
+			if (xDiff) {
+				if (yDiff) {
+					if (lastDirection != -1) {
+						direction = lastDirection;
+						if (direction == Hero::kHeroDirLeft) {
+							if (xDiff < 0) {
+								direction = scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff);
+							}
+						} else if (direction == Hero::kHeroDirRight) {
+							if (xDiff >= 0) {
+								direction = scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff);
+							}
+						} else if (direction == Hero::kHeroDirUp) {
+							if (yDiff < 0) {
+								direction = scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff);
+							}
+						} else {
+							if (yDiff >= 0) {
+								direction = scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff);
+							}
+						}
+					} else {
+						direction = scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff);
+					}
+				} else {
+					direction = Hero::kHeroDirLeft;
+					if (xDiff < 0) {
+						direction = Hero::kHeroDirRight;
+					}
+				}
+			} else {
+				if (yDiff) {
+					direction = Hero::kHeroDirUp;
+					if (yDiff < 0) {
+						direction = Hero::kHeroDirDown;
+					}
+				} else {
+					direction = lastDirection;
+				}
+			}
+			lastDirection = direction;
+			*tempDirTab = direction;
+			tempDirTab++;
+		}
+		*tempDirTab = *(tempDirTab - 1);
+		tempDirTab++;
+		*tempDirTab = 0;
+	}
+}
+
+void PrinceEngine::moveShandria() {
+	int shanLen1 = _shanLen;
+	if (_flags->getFlagValue(Flags::SHANDOG)) {
+		_secondHero->freeHeroAnim();
+		_secondHero->freeOldMove();
+		byte *shanCoords = _mainHero->_currCoords + shanLen1 * 4 - 4;
+		int shanX = READ_LE_UINT16(shanCoords - 4);
+		int shanY = READ_LE_UINT16(shanCoords - 2);
+		int xDiff = shanX - _secondHero->_middleX;
+		if (xDiff < 0) {
+			xDiff *= -1;
+		}
+		int yDiff = shanY - _secondHero->_middleY;
+		if (yDiff < 0) {
+			yDiff *= -1;
+		}
+		shanCoords -= 4;
+		if (shanCoords != _mainHero->_currCoords) {
+			yDiff *= 1.5;
+			int shanDis =  xDiff * xDiff + yDiff * yDiff;
+			if (shanDis >= kMinDistance) {
+				while (1) {
+					shanCoords -= 4;
+					if (shanCoords == _mainHero->_currCoords) {
+						break;
+					}
+					int x = READ_LE_UINT16(shanCoords);
+					int y = READ_LE_UINT16(shanCoords + 2);
+					int pointDiffX = x - shanX;
+					if (pointDiffX < 0) {
+						pointDiffX *= -1;
+					}
+					int pointDiffY = y - shanY;
+					if (pointDiffY < 0) {
+						pointDiffY *= -1;
+					}
+					pointDiffY *= 1.5;
+					int distance = pointDiffX * pointDiffX + pointDiffY * pointDiffY;
+					if (distance >= kMinDistance) {
+						break;
+					}
+				}
+				int pathSizeDiff = (shanCoords - _mainHero->_currCoords) / 4;
+				int destDir = *(_mainHero->_currDirTab + pathSizeDiff);
+				_secondHero->_destDirection = destDir;
+				int destX = READ_LE_UINT16(shanCoords);
+				int destY = READ_LE_UINT16(shanCoords + 2);
+				_secondHero->_coords = makePath(kSecondHero, _secondHero->_middleX, _secondHero->_middleY, destX, destY);
+				if (_secondHero->_coords != nullptr) {
+					_secondHero->_currCoords = _secondHero->_coords;
+					int delay = shanLen1 - _shanLen;
+					if (delay < 6) {
+						delay = 6;
+					}
+					_secondHero->_moveDelay = delay / 2;
+					_secondHero->_state = Hero::kHeroStateDelayMove;
+					_secondHero->_dirTab = _directionTable;
+					_secondHero->_currDirTab = _directionTable;
+					_directionTable = nullptr;
+				}
+			}
+		}
+	}
+}
+
+byte *PrinceEngine::makePath(int heroId, int currX, int currY, int destX, int destY) {
+	int realDestX = destX;
+	int realDestY = destY;
+	_flags->setFlagValue(Flags::MOVEDESTX, destX);
+	_flags->setFlagValue(Flags::MOVEDESTY, destY);
+
+	int x1 = currX / 2;
+	int y1 = currY / 2;
+	int x2 = destX / 2;
+	int y2 = destY / 2;
+
+	if ((x1 != x2) || (y1 != y2)) {
+		findPoint(x1, y1);
+		if (!getPixelAddr(_roomPathBitmap, _fpX, _fpY)) {
+			return nullptr;
+		}
+		if ((x1 != _fpX) || (y1 != _fpY)) {
+			x1 = _fpX;
+			y1 = _fpY;
+		}
+		findPoint(x2, y2);
+		if (!getPixelAddr(_roomPathBitmap, _fpX, _fpY)) {
+			return nullptr;
+		}
+		if ((x2 != _fpX) || (y2 != _fpY)) {
+			x2 = _fpX;
+			y2 = _fpY;
+			if (!_flags->getFlagValue(Flags::EXACTMOVE)) {
+				realDestX = x2 * 2;
+				realDestY = y2 * 2;
+				_flags->setFlagValue(Flags::MOVEDESTX, realDestX);
+				_flags->setFlagValue(Flags::MOVEDESTY, realDestY);
+			} else {
+				return nullptr;
+			}
+		}
+
+		if ((x1 == x2) && (y1 == y2)) {
+			if (!heroId) {
+				_mainHero->freeOldMove();
+				_mainHero->_state = Hero::kHeroStateTurn;
+			} else if (heroId == 1) {
+				_secondHero->freeOldMove();
+				_secondHero->_state = Hero::kHeroStateTurn;
+			}
+			return nullptr;
+		}
+
+		int pathLen1 = 0;
+		int pathLen2 = 0;
+		int stX = x1;
+		int stY = y1;
+		int sizeCoords2 = 0;
+
+		if (tracePath(x1, y1, x2, y2)) {
+			allocCoords2();
+			approxPath();
+			sizeCoords2 = _coords2 - _coordsBuf2;
+			for (int i = 0; i < sizeCoords2; i++) {
+				_coordsBuf[i] = _coordsBuf2[i];
+			}
+			_coords = _coordsBuf + sizeCoords2;
+			approxPath();
+			_coordsBuf3 = _coordsBuf2;
+			_coordsBuf2 = nullptr;
+			_coords3 = _coords2;
+			_coords2 = nullptr;
+			pathLen1 = _coords3 - _coordsBuf3;
+		}
+		if (tracePath(x2, y2, x1, y1)) {
+			allocCoords2();
+			approxPath();
+			sizeCoords2 = _coords2 - _coordsBuf2;
+			for (int i = 0; i < sizeCoords2; i++) {
+				_coordsBuf[i] = _coordsBuf2[i];
+			}
+			_coords = _coordsBuf + sizeCoords2;
+			approxPath();
+			pathLen2 = _coords2 - _coordsBuf2;
+		}
+
+		byte *chosenCoordsBuf = _coordsBuf2;
+		byte *choosenCoords = _coords2;
+		int choosenLength = pathLen1;
+		if (pathLen1 < pathLen2) {
+			chosenCoordsBuf = _coordsBuf3;
+			choosenCoords = _coords3;
+			choosenLength = pathLen2;
+		}
+
+		if (choosenLength) {
+			if (chosenCoordsBuf != nullptr) {
+				int tempXBegin = READ_LE_UINT16(chosenCoordsBuf);
+				int tempYBegin = READ_LE_UINT16(chosenCoordsBuf + 2);
+				if (stX != tempXBegin || stY != tempYBegin) {
+					SWAP(chosenCoordsBuf, choosenCoords);
+					chosenCoordsBuf -= 4;
+					byte *tempCoordsBuf = _coordsBuf;
+					while (1) {
+						int cord = READ_LE_UINT32(chosenCoordsBuf);
+						WRITE_LE_UINT32(tempCoordsBuf, cord);
+						tempCoordsBuf += 4;
+						if (chosenCoordsBuf == choosenCoords) {
+							break;
+						}
+						chosenCoordsBuf -= 4;
+					}
+					_coords = tempCoordsBuf;
+				} else {
+					int sizeChoosen = choosenCoords - chosenCoordsBuf;
+					for (int i = 0; i < sizeChoosen; i++) {
+						_coordsBuf[i] = chosenCoordsBuf[i];
+					}
+					_coords = _coordsBuf + sizeChoosen;
+				}
+				WRITE_LE_UINT32(_coords, 0xFFFFFFFF);
+				freeCoords2();
+				freeCoords3();
+				scanDirections();
+
+				byte *tempCoordsBuf = _coordsBuf;
+				byte *tempCoords = _coords;
+				byte *newCoords;
+				if (tempCoordsBuf != tempCoords) {
+					int normCoordsSize = _coords - _coordsBuf + 4;
+					newCoords = (byte *)malloc(normCoordsSize);
+					byte *newCoordsBegin = newCoords;
+					while (tempCoordsBuf != tempCoords) {
+						int newValueX = READ_LE_UINT16(tempCoordsBuf);
+						WRITE_LE_UINT16(newCoords, newValueX * 2);
+						newCoords += 2;
+						int newValueY = READ_LE_UINT16(tempCoordsBuf + 2);
+						WRITE_LE_UINT16(newCoords, newValueY * 2);
+						newCoords += 2;
+						tempCoordsBuf += 4;
+					}
+					WRITE_LE_UINT16(newCoords - 4, realDestX);
+					WRITE_LE_UINT16(newCoords - 2, realDestY);
+					WRITE_LE_UINT32(newCoords, 0xFFFFFFFF);
+					newCoords += 4;
+					_shanLen = (newCoords - newCoordsBegin);
+					_shanLen /= 4;
+					return newCoordsBegin;
+				}
+			}
+		}
+		_coords = _coordsBuf;
+		freeCoords2();
+		freeCoords3();
+		return nullptr;
+	} else {
+		if (!heroId) {
+			_mainHero->freeOldMove();
+			_mainHero->_state = Hero::kHeroStateTurn;
+		} else if (heroId == 1) {
+			_secondHero->freeOldMove();
+			_secondHero->_state = Hero::kHeroStateTurn;
+		}
+		return nullptr;
+	}
+}
+
+void PrinceEngine::allocCoords2() {
+	if (_coordsBuf2 == nullptr) {
+		_coordsBuf2 = (byte *)malloc(kTracePts * 4);
+		_coords2 = _coordsBuf2;
+	}
+}
+
+void PrinceEngine::freeCoords2() {
+	if (_coordsBuf2 != nullptr) {
+		free(_coordsBuf2);
+		_coordsBuf2 = nullptr;
+		_coords2 = nullptr;
+	}
+}
+
+void PrinceEngine::freeCoords3() {
+	if (_coordsBuf3 != nullptr) {
+		free(_coordsBuf3);
+		_coordsBuf3 = nullptr;
+		_coords3 = nullptr;
+	}
+}
+
+} // End of namespace Prince


Commit: c95cbdc2c913d4234554e3643051e1ca1e124d33
    https://github.com/scummvm/scummvm/commit/c95cbdc2c913d4234554e3643051e1ca1e124d33
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2018-05-05T23:17:35+02:00

Commit Message:
JANITORIAL: Fix formatting

Changed paths:
    engines/prince/resource.h


diff --git a/engines/prince/resource.h b/engines/prince/resource.h
index 6c823a7..a2cd8a6 100644
--- a/engines/prince/resource.h
+++ b/engines/prince/resource.h
@@ -32,66 +32,66 @@ namespace Prince {
 
 namespace Resource {
 
-	template <typename T>
-	bool loadFromStream(T &resource, Common::SeekableReadStream &stream) {
-		return resource.loadStream(stream);
-	}
-
-	template<typename T>
-	bool loadResource(T *resource, const char *resourceName, bool required) {
-		Common::ScopedPtr<Common::SeekableReadStream> stream(SearchMan.createReadStreamForMember(resourceName));
-		if (!stream) {
-			if (required)
-				error("Can't load %s", resourceName);
-			return false;
-		}
+template <typename T>
+bool loadFromStream(T &resource, Common::SeekableReadStream &stream) {
+	return resource.loadStream(stream);
+}
 
-		return loadFromStream(*resource, *stream);
+template<typename T>
+bool loadResource(T *resource, const char *resourceName, bool required) {
+	Common::ScopedPtr<Common::SeekableReadStream> stream(SearchMan.createReadStreamForMember(resourceName));
+	if (!stream) {
+		if (required)
+			error("Can't load %s", resourceName);
+		return false;
 	}
 
-	template <typename T>
-	bool loadResource(Common::Array<T> &array, Common::SeekableReadStream &stream, bool required = true) {
-		T t;
-		while (t.loadFromStream(stream))
-			array.push_back(t);
+	return loadFromStream(*resource, *stream);
+}
 
-		return true;
-	}
+template <typename T>
+bool loadResource(Common::Array<T> &array, Common::SeekableReadStream &stream, bool required = true) {
+	T t;
+	while (t.loadFromStream(stream))
+		array.push_back(t);
 
+	return true;
+}
 
-	template <typename T>
-	bool loadResource(Common::Array<T> &array, const char *resourceName, bool required = true) {
-		Common::ScopedPtr<Common::SeekableReadStream> stream(SearchMan.createReadStreamForMember(resourceName));
-		if (!stream) {
-			if (required)
-				error("Can't load %s", resourceName);
-			return false;
-		}
 
-		return loadResource(array, *stream, required);
+template <typename T>
+bool loadResource(Common::Array<T> &array, const char *resourceName, bool required = true) {
+	Common::ScopedPtr<Common::SeekableReadStream> stream(SearchMan.createReadStreamForMember(resourceName));
+	if (!stream) {
+		if (required)
+			error("Can't load %s", resourceName);
+		return false;
 	}
 
-	template <typename T>
-	bool loadResource(Common::Array<T *> &array, const char *resourceName, bool required = true) {
+	return loadResource(array, *stream, required);
+}
 
-		Common::ScopedPtr<Common::SeekableReadStream> stream(SearchMan.createReadStreamForMember(resourceName));
-		if (!stream) {
-			if (required)
-				error("Can't load %s", resourceName);
-			return false;
-		}
+template <typename T>
+bool loadResource(Common::Array<T *> &array, const char *resourceName, bool required = true) {
 
-		// FIXME: This is stupid. Maybe loadFromStream should be helper method that returns initialized object
-		while (true) {
-			T* t = new T();
-			if (!t->loadFromStream(*stream)) {
-				delete t;
-				break;
-			}
-			array.push_back(t);
+	Common::ScopedPtr<Common::SeekableReadStream> stream(SearchMan.createReadStreamForMember(resourceName));
+	if (!stream) {
+		if (required)
+			error("Can't load %s", resourceName);
+		return false;
+	}
+
+	// FIXME: This is stupid. Maybe loadFromStream should be helper method that returns initialized object
+	while (true) {
+		T* t = new T();
+		if (!t->loadFromStream(*stream)) {
+			delete t;
+			break;
 		}
-		return true;
+		array.push_back(t);
 	}
+	return true;
+}
 
 }
 


Commit: c2346309312f61597d39d3934096265c2d72fe66
    https://github.com/scummvm/scummvm/commit/c2346309312f61597d39d3934096265c2d72fe66
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2018-05-05T23:17:35+02:00

Commit Message:
PRINCE: Initial support for packed Russian version

Changed paths:
    engines/prince/archive.cpp
    engines/prince/detection.cpp
    engines/prince/prince.cpp
    engines/prince/prince.h
    engines/prince/sound.cpp


diff --git a/engines/prince/archive.cpp b/engines/prince/archive.cpp
index 984c078..3eb37b6 100644
--- a/engines/prince/archive.cpp
+++ b/engines/prince/archive.cpp
@@ -55,8 +55,8 @@ bool PtcArchive::open(const Common::String &filename) {
 	uint32 fileTableOffset = _stream->readUint32LE() ^ 0x4D4F4B2D; // MOK-
 	uint32 fileTableSize = _stream->readUint32LE() ^ 0x534F4654; // SOFT
 
-	//debug("fileTableOffset : %08X", fileTableOffset);
-	//debug("fileTableSize: %08X", fileTableSize);
+	debug(8, "fileTableOffset : %08X", fileTableOffset);
+	debug(8, "fileTableSize: %08X", fileTableSize);
 
 	_stream->seek(fileTableOffset);
 
@@ -70,7 +70,7 @@ bool PtcArchive::open(const Common::String &filename) {
 		Common::String name = (const char*)fileItem;
 		item._offset = READ_LE_UINT32(fileItem + 24);
 		item._size = READ_LE_UINT32(fileItem + 28);
-		//debug("%12s %8X %d", name.c_str(), item._offset, item._size);
+		debug(8, "%12s %8X %d", name.c_str(), item._offset, item._size);
 		_items[name] = item;
 	}
 
diff --git a/engines/prince/detection.cpp b/engines/prince/detection.cpp
index e382346..8fb63dd 100644
--- a/engines/prince/detection.cpp
+++ b/engines/prince/detection.cpp
@@ -86,7 +86,7 @@ static const PrinceGameDescription gameDescriptions[] = {
 			AD_ENTRY1s("talktxt.dat", "02bb2372f19aca3c65896ed81b2cefb3", 125702),
 			Common::RU_RUS,
 			Common::kPlatformWindows,
-			ADGF_TESTING,
+			ADGF_TESTING | GF_EXTRACTED,
 			GUIO1(GUIO_NONE)
 		},
 		kPrinceDataDE
@@ -98,7 +98,7 @@ static const PrinceGameDescription gameDescriptions[] = {
 			AD_ENTRY1s("databank.ptc", "a67b55730f3d7064921bd2a59e1063a3", 3892982),
 			Common::RU_RUS,
 			Common::kPlatformWindows,
-			ADGF_TESTING,
+			ADGF_TESTING | GF_NOVOICES,
 			GUIO1(GUIO_NONE)
 		},
 		kPrinceDataPL
diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp
index f29b8c2..a8448a0 100644
--- a/engines/prince/prince.cpp
+++ b/engines/prince/prince.cpp
@@ -208,14 +208,17 @@ void PrinceEngine::init() {
 
 	debugEngine("Adding all path: %s", gameDataDir.getPath().c_str());
 
-	if (getLanguage() != Common::RU_RUS) {
+	if (!(getFeatures() & GF_EXTRACTED)) {
 		PtcArchive *all = new PtcArchive();
 		if (!all->open("all/databank.ptc"))
 			error("Can't open all/databank.ptc");
 
 		PtcArchive *voices = new PtcArchive();
-		if (!voices->open("voices/databank.ptc"))
-			error("Can't open voices/databank.ptc");
+
+		if (!(getFeatures() & GF_NOVOICES)) {
+			if (!voices->open("voices/databank.ptc"))
+				error("Can't open voices/databank.ptc");
+		}
 
 		PtcArchive *sound = new PtcArchive();
 		if (!sound->open("sound/databank.ptc"))
diff --git a/engines/prince/prince.h b/engines/prince/prince.h
index 8ff71db..fcab7eb 100644
--- a/engines/prince/prince.h
+++ b/engines/prince/prince.h
@@ -77,7 +77,9 @@ class Room;
 class Pscr;
 
 enum {
-	GF_TRANSLATED = 1 << 0
+	GF_TRANSLATED = 1 << 0,
+	GF_EXTRACTED  = 1 << 1,
+	GF_NOVOICES   = 1 << 2
 };
 
 struct SavegameHeader {
diff --git a/engines/prince/sound.cpp b/engines/prince/sound.cpp
index 54eebdc..c062c42 100644
--- a/engines/prince/sound.cpp
+++ b/engines/prince/sound.cpp
@@ -89,6 +89,9 @@ bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamNam
 }
 
 bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::String &streamName) {
+	if (getFeatures() & GF_NOVOICES)
+		return false;
+
 	debugEngine("Loading wav %s slot %d", streamName.c_str(), slot);
 
 	if (slot >= kMaxTexts) {


Commit: e3b9be66799cfa907930b96fd67475dbcb36f308
    https://github.com/scummvm/scummvm/commit/e3b9be66799cfa907930b96fd67475dbcb36f308
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2018-05-05T23:17:35+02:00

Commit Message:
JANITORIAL: Whitespace fixes

Changed paths:
    engines/prince/decompress.cpp


diff --git a/engines/prince/decompress.cpp b/engines/prince/decompress.cpp
index 2b56391..eda992c 100644
--- a/engines/prince/decompress.cpp
+++ b/engines/prince/decompress.cpp
@@ -27,145 +27,145 @@
 namespace Prince {
 
 static const uint16 table1[] = {
-    0x8000, 0x0002,
-    0x4000, 0x0004,
-    0x2000, 0x0008,
-    0x1000, 0x0010,
-    0x0800, 0x0020,
-    0x0400, 0x0040,
-    0x0200, 0x0080,
-    0x0100, 0x0100,
-    0x0080, 0x0200,
-    0x0040, 0x0400
+	0x8000, 0x0002,
+	0x4000, 0x0004,
+	0x2000, 0x0008,
+	0x1000, 0x0010,
+	0x0800, 0x0020,
+	0x0400, 0x0040,
+	0x0200, 0x0080,
+	0x0100, 0x0100,
+	0x0080, 0x0200,
+	0x0040, 0x0400
 };
 
 static const uint32 table2[] = {
-    0x0000F000,
-    0x0020FC00,
-    0x00A0FF00,
-    0x02A0FF80,
-    0x06A0FFC0,
-    0x0EA0FFE0,
-    0x1EA0FFF0,
-    0x3EA0FFF8
+	0x0000F000,
+	0x0020FC00,
+	0x00A0FF00,
+	0x02A0FF80,
+	0x06A0FFC0,
+	0x0EA0FFE0,
+	0x1EA0FFF0,
+	0x3EA0FFF8
 };
 
 static const uint16 table3[] = {
-    0x8000, 0x0000,
-    0x4000, 0x0002,
-    0x2000, 0x0006,
-    0x1000, 0x000E,
-    0x0800, 0x001E,
-    0x0400, 0x003E,
-    0x0200, 0x007E,
-    0x0100, 0x00FE,
-    0x0080, 0x01FE,
-    0x0040, 0x03FE,
-    0x0020, 0x07FE,
-    0x0010, 0x0FFE,
-    0x0008, 0x1FFE,
-    0x0004, 0x3FFE,
-    0x0002, 0x7FFE,
-    0x0001, 0xFFFE
+	0x8000, 0x0000,
+	0x4000, 0x0002,
+	0x2000, 0x0006,
+	0x1000, 0x000E,
+	0x0800, 0x001E,
+	0x0400, 0x003E,
+	0x0200, 0x007E,
+	0x0100, 0x00FE,
+	0x0080, 0x01FE,
+	0x0040, 0x03FE,
+	0x0020, 0x07FE,
+	0x0010, 0x0FFE,
+	0x0008, 0x1FFE,
+	0x0004, 0x3FFE,
+	0x0002, 0x7FFE,
+	0x0001, 0xFFFE
 };
 
 void Decompressor::decompress(byte *source, byte *dest, uint32 destSize) {
-    byte *destEnd = dest + destSize;
-    int more;
-    _src = source;
-    _dst = dest;
-    _bitBuffer = 0x80;
-    while (_dst < destEnd) {
-        uint32 ebp;
-        uint16 offset, length;
-        if (getBit()) {
-            if (getBit()) {
-                if (getBit()) {
-                    if (getBit()) {
-                        if (getBit()) {
-                            if (getBit()) {
-                                uint32 tableIndex = 0;
-                                while (getBit())
-                                    tableIndex++;
-                                length = table3[tableIndex * 2 + 0];
-                                do {
-                                    more = !(length & 0x8000);
-                                    length = (length << 1) | getBit();
-                                } while (more);
-                                length += table3[tableIndex * 2 + 1];
-                                length++;
-                                memcpy(_dst, _src, length);
-                                _src += length;
-                                _dst += length;
-                            }
-                            *_dst++ = *_src++;
-                        }
-                        *_dst++ = *_src++;
-                    }
-                    *_dst++ = *_src++;
-                }
-                *_dst++ = *_src++;
-            }
-            *_dst++ = *_src++;
-        }
-        if (!getBit()) {
-            if (getBit()) {
-                uint32 tableIndex = getBit();
-                tableIndex = (tableIndex << 1) | getBit();
-                tableIndex = (tableIndex << 1) | getBit();
-                ebp = table2[tableIndex];
-                length = 1;
-            } else {
-                ebp = 0x0000FF00;
-                length = 0;
-            }
-        } else {
-            uint32 tableIndex = 0;
-            while (getBit())
-                tableIndex++;
-            length = table1[tableIndex * 2 + 0];
-            do {
-                more = !(length & 0x8000);
-                length = (length << 1) | getBit();
-            } while (more);
-            length += table1[tableIndex * 2 + 1];
-            tableIndex = getBit();
-            tableIndex = (tableIndex << 1) | getBit();
-            tableIndex = (tableIndex << 1) | getBit();
-            ebp = table2[tableIndex];
-        }
-        offset = ebp & 0xFFFF;
-        do {
-            if (_bitBuffer == 0x80) {
-                if (offset >= 0xFF00) {
-                    offset = (offset << 8) | *_src++;
-                }
-            }
-            more = offset & 0x8000;
-            offset = (offset << 1) | getBit();
-        } while (more);
-        offset += (ebp >> 16);
-        length += 2;
-        while (length--) {
-            if (_dst >= destEnd) {
-                return;
-            }
-            *_dst = *(_dst - offset);
-            _dst++;
-        }
-    }
+	byte *destEnd = dest + destSize;
+	int more;
+	_src = source;
+	_dst = dest;
+	_bitBuffer = 0x80;
+	while (_dst < destEnd) {
+		uint32 ebp;
+		uint16 offset, length;
+		if (getBit()) {
+			if (getBit()) {
+				if (getBit()) {
+					if (getBit()) {
+						if (getBit()) {
+							if (getBit()) {
+								uint32 tableIndex = 0;
+								while (getBit())
+									tableIndex++;
+								length = table3[tableIndex * 2 + 0];
+								do {
+									more = !(length & 0x8000);
+									length = (length << 1) | getBit();
+								} while (more);
+								length += table3[tableIndex * 2 + 1];
+								length++;
+								memcpy(_dst, _src, length);
+								_src += length;
+								_dst += length;
+							}
+							*_dst++ = *_src++;
+						}
+						*_dst++ = *_src++;
+					}
+					*_dst++ = *_src++;
+				}
+				*_dst++ = *_src++;
+			}
+			*_dst++ = *_src++;
+		}
+		if (!getBit()) {
+			if (getBit()) {
+				uint32 tableIndex = getBit();
+				tableIndex = (tableIndex << 1) | getBit();
+				tableIndex = (tableIndex << 1) | getBit();
+				ebp = table2[tableIndex];
+				length = 1;
+			} else {
+				ebp = 0x0000FF00;
+				length = 0;
+			}
+		} else {
+			uint32 tableIndex = 0;
+			while (getBit())
+				tableIndex++;
+			length = table1[tableIndex * 2 + 0];
+			do {
+				more = !(length & 0x8000);
+				length = (length << 1) | getBit();
+			} while (more);
+			length += table1[tableIndex * 2 + 1];
+			tableIndex = getBit();
+			tableIndex = (tableIndex << 1) | getBit();
+			tableIndex = (tableIndex << 1) | getBit();
+			ebp = table2[tableIndex];
+		}
+		offset = ebp & 0xFFFF;
+		do {
+			if (_bitBuffer == 0x80) {
+				if (offset >= 0xFF00) {
+					offset = (offset << 8) | *_src++;
+				}
+			}
+			more = offset & 0x8000;
+			offset = (offset << 1) | getBit();
+		} while (more);
+		offset += (ebp >> 16);
+		length += 2;
+		while (length--) {
+			if (_dst >= destEnd) {
+				return;
+			}
+			*_dst = *(_dst - offset);
+			_dst++;
+		}
+	}
 }
 
 int Decompressor::getBit() {
-    int bit = (_bitBuffer & 0x80) >> 7;
-    _bitBuffer <<= 1;
-    if (_bitBuffer == 0) {
-        _bitBuffer = *_src++;
-        bit = (_bitBuffer & 0x80) >> 7;
-        _bitBuffer <<= 1;
-        _bitBuffer |= 1;
-    }
-    return bit;
+	int bit = (_bitBuffer & 0x80) >> 7;
+	_bitBuffer <<= 1;
+	if (_bitBuffer == 0) {
+		_bitBuffer = *_src++;
+		bit = (_bitBuffer & 0x80) >> 7;
+		_bitBuffer <<= 1;
+		_bitBuffer |= 1;
+	}
+	return bit;
 }
 
 } // End of namespace Prince


Commit: 6e58c5aaa521d450878786eaf00c8a71191962ae
    https://github.com/scummvm/scummvm/commit/6e58c5aaa521d450878786eaf00c8a71191962ae
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2018-05-05T23:17:35+02:00

Commit Message:
PRINCE: Added support for unbundled compressed files

Changed paths:
    engines/prince/resource.h


diff --git a/engines/prince/resource.h b/engines/prince/resource.h
index a2cd8a6..8fb2b94 100644
--- a/engines/prince/resource.h
+++ b/engines/prince/resource.h
@@ -24,14 +24,19 @@
 #define PRINCE_RESOURCE_H
 
 #include "common/stream.h"
+#include "common/memstream.h"
 #include "common/archive.h"
 #include "common/debug-channels.h"
 #include "common/ptr.h"
 
+#include "prince/decompress.h"
+
 namespace Prince {
 
 namespace Resource {
 
+static Common::SeekableReadStream *getDecompressedStream(Common::SeekableReadStream *stream);
+
 template <typename T>
 bool loadFromStream(T &resource, Common::SeekableReadStream &stream) {
 	return resource.loadStream(stream);
@@ -39,13 +44,15 @@ bool loadFromStream(T &resource, Common::SeekableReadStream &stream) {
 
 template<typename T>
 bool loadResource(T *resource, const char *resourceName, bool required) {
-	Common::ScopedPtr<Common::SeekableReadStream> stream(SearchMan.createReadStreamForMember(resourceName));
-	if (!stream) {
+	Common::SeekableReadStream *stream_(SearchMan.createReadStreamForMember(resourceName));
+	if (!stream_) {
 		if (required)
 			error("Can't load %s", resourceName);
 		return false;
 	}
 
+	Common::ScopedPtr<Common::SeekableReadStream> stream(getDecompressedStream(stream_));
+
 	return loadFromStream(*resource, *stream);
 }
 
@@ -61,26 +68,30 @@ bool loadResource(Common::Array<T> &array, Common::SeekableReadStream &stream, b
 
 template <typename T>
 bool loadResource(Common::Array<T> &array, const char *resourceName, bool required = true) {
-	Common::ScopedPtr<Common::SeekableReadStream> stream(SearchMan.createReadStreamForMember(resourceName));
-	if (!stream) {
+	Common::SeekableReadStream *stream_(SearchMan.createReadStreamForMember(resourceName));
+	if (!stream_) {
 		if (required)
 			error("Can't load %s", resourceName);
 		return false;
 	}
 
+	Common::ScopedPtr<Common::SeekableReadStream> stream(getDecompressedStream(stream_));
+
 	return loadResource(array, *stream, required);
 }
 
 template <typename T>
 bool loadResource(Common::Array<T *> &array, const char *resourceName, bool required = true) {
 
-	Common::ScopedPtr<Common::SeekableReadStream> stream(SearchMan.createReadStreamForMember(resourceName));
-	if (!stream) {
+	Common::SeekableReadStream *stream_(SearchMan.createReadStreamForMember(resourceName));
+	if (!stream_) {
 		if (required)
 			error("Can't load %s", resourceName);
 		return false;
 	}
 
+	Common::ScopedPtr<Common::SeekableReadStream> stream(getDecompressedStream(stream_));
+
 	// FIXME: This is stupid. Maybe loadFromStream should be helper method that returns initialized object
 	while (true) {
 		T* t = new T();
@@ -93,6 +104,28 @@ bool loadResource(Common::Array<T *> &array, const char *resourceName, bool requ
 	return true;
 }
 
+static Common::SeekableReadStream *getDecompressedStream(Common::SeekableReadStream *stream) {
+	byte header[4];
+
+	stream->read(header, 4);
+	stream->seek(0);
+
+	if (READ_BE_UINT32(header) == MKTAG('M', 'A', 'S', 'M')) {
+		byte *buffer = (byte *)malloc(stream->size());
+		stream->read(buffer, stream->size());
+
+		Decompressor dec;
+		uint32 decompLen = READ_BE_UINT32(buffer + 14);
+		byte *decompData = (byte *)malloc(decompLen);
+		dec.decompress(buffer + 18, decompData, decompLen);
+		free(buffer);
+
+		return new Common::MemoryReadStream(decompData, decompLen, DisposeAfterUse::YES);
+	} else {
+		return stream;
+	}
+}
+
 }
 
 } // End of namespace Prince


Commit: a97a3c388675a76f9def98db441e8904232d118a
    https://github.com/scummvm/scummvm/commit/a97a3c388675a76f9def98db441e8904232d118a
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2018-05-05T23:17:35+02:00

Commit Message:
PRINCE: Further work on support for extracted games

Changed paths:
    engines/prince/resources.cpp


diff --git a/engines/prince/resources.cpp b/engines/prince/resources.cpp
index bb3db04..342c16e 100644
--- a/engines/prince/resources.cpp
+++ b/engines/prince/resources.cpp
@@ -83,11 +83,15 @@ bool PrinceEngine::loadLocation(uint16 locationNr) {
 	const Common::String locationNrStr = Common::String::format("%02d", _locationNr);
 	debugEngine("loadLocation %s", locationNrStr.c_str());
 
-	PtcArchive *locationArchive = new PtcArchive();
-	if (!locationArchive->open(locationNrStr + "/databank.ptc"))
-		error("Can't open location %s", locationNrStr.c_str());
-
-	SearchMan.add(locationNrStr, locationArchive);
+	if (!(getFeatures() & GF_EXTRACTED)) {
+		PtcArchive *locationArchive = new PtcArchive();
+		if (!locationArchive->open(locationNrStr + "/databank.ptc"))
+			error("Can't open location %s", locationNrStr.c_str());
+
+		SearchMan.add(locationNrStr, locationArchive);
+	} else {
+		SearchMan.addSubDirectoryMatching(gameDataDir, locationNrStr);
+	}
 
 	loadMusic(_locationNr);
 


Commit: 5a9eba989aa14483c5fea98f920ba02acb9e7cdd
    https://github.com/scummvm/scummvm/commit/5a9eba989aa14483c5fea98f920ba02acb9e7cdd
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2018-05-05T23:17:35+02:00

Commit Message:
PRINCE: Rename resources.cpp

Changed paths:
  A engines/prince/resource.cpp
  R engines/prince/resources.cpp
    engines/prince/module.mk


diff --git a/engines/prince/module.mk b/engines/prince/module.mk
index ecc109a..0a24c0c 100644
--- a/engines/prince/module.mk
+++ b/engines/prince/module.mk
@@ -19,7 +19,7 @@ MODULE_OBJS = \
 	object.o \
 	prince.o \
 	pscr.o \
-	resources.o \
+	resource.o \
 	saveload.o \
 	script.o \
 	sound.o \
diff --git a/engines/prince/resource.cpp b/engines/prince/resource.cpp
new file mode 100644
index 0000000..342c16e
--- /dev/null
+++ b/engines/prince/resource.cpp
@@ -0,0 +1,325 @@
+/* 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 "common/config-manager.h"
+
+#include "prince/prince.h"
+#include "prince/graphics.h"
+#include "prince/debugger.h"
+#include "prince/script.h"
+#include "prince/hero.h"
+#include "prince/resource.h"
+#include "prince/archive.h"
+
+namespace Prince {
+
+bool AnimListItem::loadFromStream(Common::SeekableReadStream &stream) {
+	int32 pos = stream.pos();
+
+	uint16 type = stream.readUint16LE();
+	if (type == 0xFFFF) {
+		return false;
+	}
+	_type = type;
+	_fileNumber = stream.readUint16LE();
+	_startPhase = stream.readUint16LE();
+	_endPhase = stream.readUint16LE();
+	_loopPhase = stream.readUint16LE();
+	_x = stream.readSint16LE();
+	_y = stream.readSint16LE();
+	_loopType = stream.readUint16LE();
+	_nextAnim = stream.readUint16LE();
+	_flags = stream.readUint16LE();
+
+	//debug("AnimListItem type %d, fileNumber %d, x %d, y %d, flags %d", _type, _fileNumber, _x, _y, _flags);
+	//debug("startPhase %d, endPhase %d, loopPhase %d", _startPhase, _endPhase, _loopPhase);
+
+	// 32 byte aligment
+	stream.seek(pos + 32);
+
+	return true;
+}
+
+bool PrinceEngine::loadLocation(uint16 locationNr) {
+
+	blackPalette();
+
+	_flicPlayer.close();
+
+	memset(_textSlots, 0, sizeof(_textSlots));
+	freeAllSamples();
+
+	debugEngine("PrinceEngine::loadLocation %d", locationNr);
+	const Common::FSNode gameDataDir(ConfMan.get("path"));
+	SearchMan.remove(Common::String::format("%02d", _locationNr));
+
+	_locationNr = locationNr;
+	_debugger->_locationNr = locationNr;
+
+	_flags->setFlagValue(Flags::CURRROOM, _locationNr);
+	_interpreter->stopBg();
+
+	changeCursor(0);
+
+	const Common::String locationNrStr = Common::String::format("%02d", _locationNr);
+	debugEngine("loadLocation %s", locationNrStr.c_str());
+
+	if (!(getFeatures() & GF_EXTRACTED)) {
+		PtcArchive *locationArchive = new PtcArchive();
+		if (!locationArchive->open(locationNrStr + "/databank.ptc"))
+			error("Can't open location %s", locationNrStr.c_str());
+
+		SearchMan.add(locationNrStr, locationArchive);
+	} else {
+		SearchMan.addSubDirectoryMatching(gameDataDir, locationNrStr);
+	}
+
+	loadMusic(_locationNr);
+
+	// load location background, replace old one
+	Resource::loadResource(_roomBmp, "room", true);
+	if (_roomBmp->getSurface()) {
+		_sceneWidth = _roomBmp->getSurface()->w;
+	}
+
+	loadZoom(_zoomBitmap, kZoomBitmapLen, "zoom");
+	loadShadow(_shadowBitmap, kShadowBitmapSize, "shadow", "shadow2");
+	loadTrans(_transTable, "trans");
+	loadPath("path");
+
+	for (uint32 i = 0; i < _pscrList.size(); i++) {
+		delete _pscrList[i];
+	}
+	_pscrList.clear();
+	Resource::loadResource(_pscrList, "pscr.lst", false);
+
+	loadMobPriority("mobpri");
+
+	_mobList.clear();
+	if (getGameType() == kPrinceDataDE) {
+		const Common::String mobLstName = Common::String::format("mob%02d.lst", _locationNr);
+		debug("name: %s", mobLstName.c_str());
+		Resource::loadResource(_mobList, mobLstName.c_str(), false);
+	} else if (getGameType() == kPrinceDataPL) {
+		Resource::loadResource(_mobList, "mob.lst", false);
+	}
+	if (getFeatures() & GF_TRANSLATED) {
+		// update Mob texts for translated version
+		setMobTranslationTexts();
+	}
+
+	_animList.clear();
+	Resource::loadResource(_animList, "anim.lst", false);
+
+	for (uint32 i = 0; i < _objList.size(); i++) {
+		delete _objList[i];
+	}
+	_objList.clear();
+	Resource::loadResource(_objList, "obj.lst", false);
+
+	_room->loadRoom(_script->getRoomOffset(_locationNr));
+
+	for (uint i = 0; i < _maskList.size(); i++) {
+		free(_maskList[i]._data);
+	}
+	_maskList.clear();
+	_script->loadAllMasks(_maskList, _room->_nak);
+
+	_picWindowX = 0;
+
+	_lightX = _script->getLightX(_locationNr);
+	_lightY = _script->getLightY(_locationNr);
+	setShadowScale(_script->getShadowScale(_locationNr));
+
+	for (uint i = 0; i < _mobList.size(); i++) {
+		_mobList[i]._visible = _script->getMobVisible(_room->_mobs, i);
+	}
+
+	_script->installObjects(_room->_obj);
+
+	freeAllNormAnims();
+
+	clearBackAnimList();
+	_script->installBackAnims(_backAnimList, _room->_backAnim);
+
+	_graph->makeShadowTable(70, _graph->_shadowTable70);
+	_graph->makeShadowTable(50, _graph->_shadowTable50);
+
+	_mainHero->freeOldMove();
+	_secondHero->freeOldMove();
+
+	_mainHero->scrollHero();
+
+	return true;
+}
+
+bool PrinceEngine::loadAnim(uint16 animNr, bool loop) {
+	Common::String streamName = Common::String::format("AN%02d", animNr);
+	Common::SeekableReadStream *flicStream = SearchMan.createReadStreamForMember(streamName);
+
+	if (!flicStream) {
+		error("Can't open %s", streamName.c_str());
+		return false;
+	}
+
+	if (!_flicPlayer.loadStream(flicStream)) {
+		error("Can't load flic stream %s", streamName.c_str());
+	}
+
+	debugEngine("%s loaded", streamName.c_str());
+	_flicLooped = loop;
+	_flicPlayer.start();
+	playNextFLCFrame();
+	return true;
+}
+
+bool PrinceEngine::loadZoom(byte *zoomBitmap, uint32 dataSize, const char *resourceName) {
+	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName);
+	if (!stream) {
+		delete stream;
+		return false;
+	}
+	if (stream->read(zoomBitmap, dataSize) != dataSize) {
+		free(zoomBitmap);
+		delete stream;
+		return false;
+	}
+	delete stream;
+	return true;
+}
+
+bool PrinceEngine::loadShadow(byte *shadowBitmap, uint32 dataSize, const char *resourceName1, const char *resourceName2) {
+	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName1);
+	if (!stream) {
+		delete stream;
+		return false;
+	}
+
+	if (stream->read(shadowBitmap, dataSize) != dataSize) {
+		free(shadowBitmap);
+		delete stream;
+		return false;
+	}
+
+	Common::SeekableReadStream *stream2 = SearchMan.createReadStreamForMember(resourceName2);
+	if (!stream2) {
+		delete stream;
+		delete stream2;
+		return false;
+	}
+
+	byte *shadowBitmap2 = shadowBitmap + dataSize;
+	if (stream2->read(shadowBitmap2, dataSize) != dataSize) {
+		free(shadowBitmap);
+		delete stream;
+		delete stream2;
+		return false;
+	}
+
+	delete stream;
+	delete stream2;
+	return true;
+}
+
+bool PrinceEngine::loadTrans(byte *transTable, const char *resourceName) {
+	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName);
+	if (!stream) {
+		delete stream;
+		for (int i = 0; i < 256; i++) {
+			for (int j = 0; j < 256; j++) {
+				transTable[i * 256 + j] = j;
+			}
+		}
+		return true;
+	}
+	if (stream->read(transTable, kTransTableSize) != kTransTableSize) {
+		delete stream;
+		return false;
+	}
+	delete stream;
+	return true;
+}
+
+bool PrinceEngine::loadPath(const char *resourceName) {
+	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName);
+	if (!stream) {
+		delete stream;
+		return false;
+	}
+	if (stream->read(_roomPathBitmap, kPathBitmapLen) != kPathBitmapLen) {
+		delete stream;
+		return false;
+	}
+	delete stream;
+	return true;
+}
+
+bool PrinceEngine::loadAllInv() {
+	for (int i = 0; i < kMaxInv; i++) {
+		InvItem tempInvItem;
+
+		const Common::String invStreamName = Common::String::format("INV%02d", i);
+		Common::SeekableReadStream *invStream = SearchMan.createReadStreamForMember(invStreamName);
+		if (!invStream) {
+			delete invStream;
+			return true;
+		}
+
+		tempInvItem._x = invStream->readUint16LE();
+		tempInvItem._y = invStream->readUint16LE();
+		int width = invStream->readUint16LE();
+		int height = invStream->readUint16LE();
+		tempInvItem._surface = new Graphics::Surface();
+		tempInvItem._surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+
+		for (int h = 0; h < tempInvItem._surface->h; h++) {
+			invStream->read(tempInvItem._surface->getBasePtr(0, h), tempInvItem._surface->w);
+		}
+
+		_allInvList.push_back(tempInvItem);
+		delete invStream;
+	}
+
+	return true;
+}
+
+bool PrinceEngine::loadMobPriority(const char *resourceName) {
+	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName);
+	if (!stream) {
+		delete stream;
+		return false;
+	}
+
+	_mobPriorityList.clear();
+	uint mobId;
+	while (1) {
+		mobId = stream->readUint32LE();
+		if (mobId == 0xFFFFFFFF) {
+			break;
+		}
+		_mobPriorityList.push_back(mobId);
+	}
+	delete stream;
+	return true;
+}
+
+} // End of namespace Prince
diff --git a/engines/prince/resources.cpp b/engines/prince/resources.cpp
deleted file mode 100644
index 342c16e..0000000
--- a/engines/prince/resources.cpp
+++ /dev/null
@@ -1,325 +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.
- *
- */
-
-#include "common/config-manager.h"
-
-#include "prince/prince.h"
-#include "prince/graphics.h"
-#include "prince/debugger.h"
-#include "prince/script.h"
-#include "prince/hero.h"
-#include "prince/resource.h"
-#include "prince/archive.h"
-
-namespace Prince {
-
-bool AnimListItem::loadFromStream(Common::SeekableReadStream &stream) {
-	int32 pos = stream.pos();
-
-	uint16 type = stream.readUint16LE();
-	if (type == 0xFFFF) {
-		return false;
-	}
-	_type = type;
-	_fileNumber = stream.readUint16LE();
-	_startPhase = stream.readUint16LE();
-	_endPhase = stream.readUint16LE();
-	_loopPhase = stream.readUint16LE();
-	_x = stream.readSint16LE();
-	_y = stream.readSint16LE();
-	_loopType = stream.readUint16LE();
-	_nextAnim = stream.readUint16LE();
-	_flags = stream.readUint16LE();
-
-	//debug("AnimListItem type %d, fileNumber %d, x %d, y %d, flags %d", _type, _fileNumber, _x, _y, _flags);
-	//debug("startPhase %d, endPhase %d, loopPhase %d", _startPhase, _endPhase, _loopPhase);
-
-	// 32 byte aligment
-	stream.seek(pos + 32);
-
-	return true;
-}
-
-bool PrinceEngine::loadLocation(uint16 locationNr) {
-
-	blackPalette();
-
-	_flicPlayer.close();
-
-	memset(_textSlots, 0, sizeof(_textSlots));
-	freeAllSamples();
-
-	debugEngine("PrinceEngine::loadLocation %d", locationNr);
-	const Common::FSNode gameDataDir(ConfMan.get("path"));
-	SearchMan.remove(Common::String::format("%02d", _locationNr));
-
-	_locationNr = locationNr;
-	_debugger->_locationNr = locationNr;
-
-	_flags->setFlagValue(Flags::CURRROOM, _locationNr);
-	_interpreter->stopBg();
-
-	changeCursor(0);
-
-	const Common::String locationNrStr = Common::String::format("%02d", _locationNr);
-	debugEngine("loadLocation %s", locationNrStr.c_str());
-
-	if (!(getFeatures() & GF_EXTRACTED)) {
-		PtcArchive *locationArchive = new PtcArchive();
-		if (!locationArchive->open(locationNrStr + "/databank.ptc"))
-			error("Can't open location %s", locationNrStr.c_str());
-
-		SearchMan.add(locationNrStr, locationArchive);
-	} else {
-		SearchMan.addSubDirectoryMatching(gameDataDir, locationNrStr);
-	}
-
-	loadMusic(_locationNr);
-
-	// load location background, replace old one
-	Resource::loadResource(_roomBmp, "room", true);
-	if (_roomBmp->getSurface()) {
-		_sceneWidth = _roomBmp->getSurface()->w;
-	}
-
-	loadZoom(_zoomBitmap, kZoomBitmapLen, "zoom");
-	loadShadow(_shadowBitmap, kShadowBitmapSize, "shadow", "shadow2");
-	loadTrans(_transTable, "trans");
-	loadPath("path");
-
-	for (uint32 i = 0; i < _pscrList.size(); i++) {
-		delete _pscrList[i];
-	}
-	_pscrList.clear();
-	Resource::loadResource(_pscrList, "pscr.lst", false);
-
-	loadMobPriority("mobpri");
-
-	_mobList.clear();
-	if (getGameType() == kPrinceDataDE) {
-		const Common::String mobLstName = Common::String::format("mob%02d.lst", _locationNr);
-		debug("name: %s", mobLstName.c_str());
-		Resource::loadResource(_mobList, mobLstName.c_str(), false);
-	} else if (getGameType() == kPrinceDataPL) {
-		Resource::loadResource(_mobList, "mob.lst", false);
-	}
-	if (getFeatures() & GF_TRANSLATED) {
-		// update Mob texts for translated version
-		setMobTranslationTexts();
-	}
-
-	_animList.clear();
-	Resource::loadResource(_animList, "anim.lst", false);
-
-	for (uint32 i = 0; i < _objList.size(); i++) {
-		delete _objList[i];
-	}
-	_objList.clear();
-	Resource::loadResource(_objList, "obj.lst", false);
-
-	_room->loadRoom(_script->getRoomOffset(_locationNr));
-
-	for (uint i = 0; i < _maskList.size(); i++) {
-		free(_maskList[i]._data);
-	}
-	_maskList.clear();
-	_script->loadAllMasks(_maskList, _room->_nak);
-
-	_picWindowX = 0;
-
-	_lightX = _script->getLightX(_locationNr);
-	_lightY = _script->getLightY(_locationNr);
-	setShadowScale(_script->getShadowScale(_locationNr));
-
-	for (uint i = 0; i < _mobList.size(); i++) {
-		_mobList[i]._visible = _script->getMobVisible(_room->_mobs, i);
-	}
-
-	_script->installObjects(_room->_obj);
-
-	freeAllNormAnims();
-
-	clearBackAnimList();
-	_script->installBackAnims(_backAnimList, _room->_backAnim);
-
-	_graph->makeShadowTable(70, _graph->_shadowTable70);
-	_graph->makeShadowTable(50, _graph->_shadowTable50);
-
-	_mainHero->freeOldMove();
-	_secondHero->freeOldMove();
-
-	_mainHero->scrollHero();
-
-	return true;
-}
-
-bool PrinceEngine::loadAnim(uint16 animNr, bool loop) {
-	Common::String streamName = Common::String::format("AN%02d", animNr);
-	Common::SeekableReadStream *flicStream = SearchMan.createReadStreamForMember(streamName);
-
-	if (!flicStream) {
-		error("Can't open %s", streamName.c_str());
-		return false;
-	}
-
-	if (!_flicPlayer.loadStream(flicStream)) {
-		error("Can't load flic stream %s", streamName.c_str());
-	}
-
-	debugEngine("%s loaded", streamName.c_str());
-	_flicLooped = loop;
-	_flicPlayer.start();
-	playNextFLCFrame();
-	return true;
-}
-
-bool PrinceEngine::loadZoom(byte *zoomBitmap, uint32 dataSize, const char *resourceName) {
-	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName);
-	if (!stream) {
-		delete stream;
-		return false;
-	}
-	if (stream->read(zoomBitmap, dataSize) != dataSize) {
-		free(zoomBitmap);
-		delete stream;
-		return false;
-	}
-	delete stream;
-	return true;
-}
-
-bool PrinceEngine::loadShadow(byte *shadowBitmap, uint32 dataSize, const char *resourceName1, const char *resourceName2) {
-	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName1);
-	if (!stream) {
-		delete stream;
-		return false;
-	}
-
-	if (stream->read(shadowBitmap, dataSize) != dataSize) {
-		free(shadowBitmap);
-		delete stream;
-		return false;
-	}
-
-	Common::SeekableReadStream *stream2 = SearchMan.createReadStreamForMember(resourceName2);
-	if (!stream2) {
-		delete stream;
-		delete stream2;
-		return false;
-	}
-
-	byte *shadowBitmap2 = shadowBitmap + dataSize;
-	if (stream2->read(shadowBitmap2, dataSize) != dataSize) {
-		free(shadowBitmap);
-		delete stream;
-		delete stream2;
-		return false;
-	}
-
-	delete stream;
-	delete stream2;
-	return true;
-}
-
-bool PrinceEngine::loadTrans(byte *transTable, const char *resourceName) {
-	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName);
-	if (!stream) {
-		delete stream;
-		for (int i = 0; i < 256; i++) {
-			for (int j = 0; j < 256; j++) {
-				transTable[i * 256 + j] = j;
-			}
-		}
-		return true;
-	}
-	if (stream->read(transTable, kTransTableSize) != kTransTableSize) {
-		delete stream;
-		return false;
-	}
-	delete stream;
-	return true;
-}
-
-bool PrinceEngine::loadPath(const char *resourceName) {
-	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName);
-	if (!stream) {
-		delete stream;
-		return false;
-	}
-	if (stream->read(_roomPathBitmap, kPathBitmapLen) != kPathBitmapLen) {
-		delete stream;
-		return false;
-	}
-	delete stream;
-	return true;
-}
-
-bool PrinceEngine::loadAllInv() {
-	for (int i = 0; i < kMaxInv; i++) {
-		InvItem tempInvItem;
-
-		const Common::String invStreamName = Common::String::format("INV%02d", i);
-		Common::SeekableReadStream *invStream = SearchMan.createReadStreamForMember(invStreamName);
-		if (!invStream) {
-			delete invStream;
-			return true;
-		}
-
-		tempInvItem._x = invStream->readUint16LE();
-		tempInvItem._y = invStream->readUint16LE();
-		int width = invStream->readUint16LE();
-		int height = invStream->readUint16LE();
-		tempInvItem._surface = new Graphics::Surface();
-		tempInvItem._surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
-
-		for (int h = 0; h < tempInvItem._surface->h; h++) {
-			invStream->read(tempInvItem._surface->getBasePtr(0, h), tempInvItem._surface->w);
-		}
-
-		_allInvList.push_back(tempInvItem);
-		delete invStream;
-	}
-
-	return true;
-}
-
-bool PrinceEngine::loadMobPriority(const char *resourceName) {
-	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName);
-	if (!stream) {
-		delete stream;
-		return false;
-	}
-
-	_mobPriorityList.clear();
-	uint mobId;
-	while (1) {
-		mobId = stream->readUint32LE();
-		if (mobId == 0xFFFFFFFF) {
-			break;
-		}
-		_mobPriorityList.push_back(mobId);
-	}
-	delete stream;
-	return true;
-}
-
-} // End of namespace Prince


Commit: 85aa17d9ac8c97f0939bdd9380f97c8a71fcd140
    https://github.com/scummvm/scummvm/commit/85aa17d9ac8c97f0939bdd9380f97c8a71fcd140
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2018-05-05T23:17:35+02:00

Commit Message:
PRINCE: Move decompression method to reusable place

Changed paths:
    engines/prince/resource.cpp
    engines/prince/resource.h


diff --git a/engines/prince/resource.cpp b/engines/prince/resource.cpp
index 342c16e..96a831c 100644
--- a/engines/prince/resource.cpp
+++ b/engines/prince/resource.cpp
@@ -32,6 +32,28 @@
 
 namespace Prince {
 
+Common::SeekableReadStream *Resource::getDecompressedStream(Common::SeekableReadStream *stream) {
+	byte header[4];
+
+	stream->read(header, 4);
+	stream->seek(0);
+
+	if (READ_BE_UINT32(header) == MKTAG('M', 'A', 'S', 'M')) {
+		byte *buffer = (byte *)malloc(stream->size());
+		stream->read(buffer, stream->size());
+
+		Decompressor dec;
+		uint32 decompLen = READ_BE_UINT32(buffer + 14);
+		byte *decompData = (byte *)malloc(decompLen);
+		dec.decompress(buffer + 18, decompData, decompLen);
+		free(buffer);
+
+		return new Common::MemoryReadStream(decompData, decompLen, DisposeAfterUse::YES);
+	} else {
+		return stream;
+	}
+}
+
 bool AnimListItem::loadFromStream(Common::SeekableReadStream &stream) {
 	int32 pos = stream.pos();
 
diff --git a/engines/prince/resource.h b/engines/prince/resource.h
index 8fb2b94..1746f2b 100644
--- a/engines/prince/resource.h
+++ b/engines/prince/resource.h
@@ -35,7 +35,7 @@ namespace Prince {
 
 namespace Resource {
 
-static Common::SeekableReadStream *getDecompressedStream(Common::SeekableReadStream *stream);
+Common::SeekableReadStream *getDecompressedStream(Common::SeekableReadStream *stream);
 
 template <typename T>
 bool loadFromStream(T &resource, Common::SeekableReadStream &stream) {
@@ -104,28 +104,6 @@ bool loadResource(Common::Array<T *> &array, const char *resourceName, bool requ
 	return true;
 }
 
-static Common::SeekableReadStream *getDecompressedStream(Common::SeekableReadStream *stream) {
-	byte header[4];
-
-	stream->read(header, 4);
-	stream->seek(0);
-
-	if (READ_BE_UINT32(header) == MKTAG('M', 'A', 'S', 'M')) {
-		byte *buffer = (byte *)malloc(stream->size());
-		stream->read(buffer, stream->size());
-
-		Decompressor dec;
-		uint32 decompLen = READ_BE_UINT32(buffer + 14);
-		byte *decompData = (byte *)malloc(decompLen);
-		dec.decompress(buffer + 18, decompData, decompLen);
-		free(buffer);
-
-		return new Common::MemoryReadStream(decompData, decompLen, DisposeAfterUse::YES);
-	} else {
-		return stream;
-	}
-}
-
 }
 
 } // End of namespace Prince


Commit: 5515f414afd062b78a60c71fb465e978dfef62ae
    https://github.com/scummvm/scummvm/commit/5515f414afd062b78a60c71fb465e978dfef62ae
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2018-05-05T23:17:35+02:00

Commit Message:
PRINCE: Decompress files if they're extracted

Changed paths:
    engines/prince/music.cpp
    engines/prince/object.cpp
    engines/prince/prince.cpp
    engines/prince/pscr.cpp
    engines/prince/resource.cpp
    engines/prince/script.cpp


diff --git a/engines/prince/music.cpp b/engines/prince/music.cpp
index ca72e9c..f1846f9 100644
--- a/engines/prince/music.cpp
+++ b/engines/prince/music.cpp
@@ -23,6 +23,7 @@
 #include "prince/prince.h"
 #include "prince/music.h"
 #include "prince/musNum.h"
+#include "prince/resource.h"
 
 #include "common/archive.h"
 #include "common/debug.h"
@@ -153,6 +154,8 @@ void MusicPlayer::loadMidi(const char *name) {
 		return;
 	}
 
+	stream = Resource::getDecompressedStream(stream);
+
 	// Stop any currently playing MIDI file
 	killMidi();
 
diff --git a/engines/prince/object.cpp b/engines/prince/object.cpp
index e4a3eda..109d180 100644
--- a/engines/prince/object.cpp
+++ b/engines/prince/object.cpp
@@ -28,6 +28,7 @@
 #include "graphics/surface.h"
 
 #include "prince/object.h"
+#include "prince/resource.h"
 
 namespace Prince {
 
@@ -73,6 +74,8 @@ bool Object::loadFromStream(Common::SeekableReadStream &stream) {
 	const Common::String obStreamName = Common::String::format("OB%02d", stream.readUint16LE());
 	Common::SeekableReadStream *obStream = SearchMan.createReadStreamForMember(obStreamName);
 	if (obStream) {
+		obStream = Resource::getDecompressedStream(obStream);
+
 		loadSurface(*obStream);
 	}
 	delete obStream;
diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp
index a8448a0..06cc739 100644
--- a/engines/prince/prince.cpp
+++ b/engines/prince/prince.cpp
@@ -325,6 +325,9 @@ void PrinceEngine::init() {
 		error("Can't load dialogDatStream");
 		return;
 	}
+
+	dialogDatStream = Resource::getDecompressedStream(dialogDatStream);
+
 	_dialogDatSize = dialogDatStream->size();
 	_dialogDat = (byte *)malloc(_dialogDatSize);
 	dialogDatStream->read(_dialogDat, _dialogDatSize);
diff --git a/engines/prince/pscr.cpp b/engines/prince/pscr.cpp
index 4f79704..481d17c 100644
--- a/engines/prince/pscr.cpp
+++ b/engines/prince/pscr.cpp
@@ -24,6 +24,7 @@
 #include "common/stream.h"
 
 #include "prince/pscr.h"
+#include "prince/resource.h"
 
 namespace Prince {
 
@@ -64,6 +65,8 @@ bool PScr::loadFromStream(Common::SeekableReadStream &stream) {
 	const Common::String pscrStreamName = Common::String::format("PS%02d", file);
 	Common::SeekableReadStream *pscrStream = SearchMan.createReadStreamForMember(pscrStreamName);
 	if (pscrStream != nullptr) {
+		pscrStream = Resource::getDecompressedStream(pscrStream);
+
 		loadSurface(*pscrStream);
 	}
 	delete pscrStream;
diff --git a/engines/prince/resource.cpp b/engines/prince/resource.cpp
index 96a831c..96e7dce 100644
--- a/engines/prince/resource.cpp
+++ b/engines/prince/resource.cpp
@@ -203,6 +203,8 @@ bool PrinceEngine::loadAnim(uint16 animNr, bool loop) {
 		return false;
 	}
 
+	flicStream = Resource::getDecompressedStream(flicStream);
+
 	if (!_flicPlayer.loadStream(flicStream)) {
 		error("Can't load flic stream %s", streamName.c_str());
 	}
@@ -220,6 +222,8 @@ bool PrinceEngine::loadZoom(byte *zoomBitmap, uint32 dataSize, const char *resou
 		delete stream;
 		return false;
 	}
+	stream = Resource::getDecompressedStream(stream);
+
 	if (stream->read(zoomBitmap, dataSize) != dataSize) {
 		free(zoomBitmap);
 		delete stream;
@@ -236,6 +240,8 @@ bool PrinceEngine::loadShadow(byte *shadowBitmap, uint32 dataSize, const char *r
 		return false;
 	}
 
+	stream = Resource::getDecompressedStream(stream);
+
 	if (stream->read(shadowBitmap, dataSize) != dataSize) {
 		free(shadowBitmap);
 		delete stream;
@@ -249,6 +255,8 @@ bool PrinceEngine::loadShadow(byte *shadowBitmap, uint32 dataSize, const char *r
 		return false;
 	}
 
+	stream2 = Resource::getDecompressedStream(stream2);
+
 	byte *shadowBitmap2 = shadowBitmap + dataSize;
 	if (stream2->read(shadowBitmap2, dataSize) != dataSize) {
 		free(shadowBitmap);
@@ -273,6 +281,9 @@ bool PrinceEngine::loadTrans(byte *transTable, const char *resourceName) {
 		}
 		return true;
 	}
+
+	stream = Resource::getDecompressedStream(stream);
+
 	if (stream->read(transTable, kTransTableSize) != kTransTableSize) {
 		delete stream;
 		return false;
@@ -287,6 +298,9 @@ bool PrinceEngine::loadPath(const char *resourceName) {
 		delete stream;
 		return false;
 	}
+
+	stream = Resource::getDecompressedStream(stream);
+
 	if (stream->read(_roomPathBitmap, kPathBitmapLen) != kPathBitmapLen) {
 		delete stream;
 		return false;
@@ -306,6 +320,8 @@ bool PrinceEngine::loadAllInv() {
 			return true;
 		}
 
+		invStream = Resource::getDecompressedStream(invStream);
+
 		tempInvItem._x = invStream->readUint16LE();
 		tempInvItem._y = invStream->readUint16LE();
 		int width = invStream->readUint16LE();
@@ -331,6 +347,8 @@ bool PrinceEngine::loadMobPriority(const char *resourceName) {
 		return false;
 	}
 
+	stream = Resource::getDecompressedStream(stream);
+
 	_mobPriorityList.clear();
 	uint mobId;
 	while (1) {
diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp
index 7d8f834..e40492f 100644
--- a/engines/prince/script.cpp
+++ b/engines/prince/script.cpp
@@ -391,6 +391,8 @@ bool Script::loadAllMasks(Common::Array<Mask> &maskList, int offset) {
 			debug("Can't load %s", msStreamName.c_str());
 			delete msStream;
 		} else {
+			msStream = Resource::getDecompressedStream(msStream);
+
 			int32 dataSize = msStream->size();
 			if (dataSize != -1) {
 				tempMask._data = (byte *)malloc(dataSize);


Commit: 44e44c1f1ae948225179fe572665cf1e2a5339de
    https://github.com/scummvm/scummvm/commit/44e44c1f1ae948225179fe572665cf1e2a5339de
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2018-05-05T23:17:35+02:00

Commit Message:
PRINCE: Optimize decompression for bundled games

Changed paths:
    engines/prince/resource.cpp


diff --git a/engines/prince/resource.cpp b/engines/prince/resource.cpp
index 96e7dce..8d4326c 100644
--- a/engines/prince/resource.cpp
+++ b/engines/prince/resource.cpp
@@ -33,6 +33,9 @@
 namespace Prince {
 
 Common::SeekableReadStream *Resource::getDecompressedStream(Common::SeekableReadStream *stream) {
+	if (!(((PrinceEngine *)g_engine)->getFeatures() & GF_EXTRACTED))
+		return stream;
+
 	byte header[4];
 
 	stream->read(header, 4);


Commit: dbc60f55e2c7fb8e6a09258b4c820b827063be5b
    https://github.com/scummvm/scummvm/commit/dbc60f55e2c7fb8e6a09258b4c820b827063be5b
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2018-05-05T23:17:35+02:00

Commit Message:
PRINCE: Added Russian options

Changed paths:
    engines/prince/inventory.cpp
    engines/prince/option_text.h


diff --git a/engines/prince/inventory.cpp b/engines/prince/inventory.cpp
index 509eace..fdb17b1 100644
--- a/engines/prince/inventory.cpp
+++ b/engines/prince/inventory.cpp
@@ -529,6 +529,9 @@ void PrinceEngine::checkOptions() {
 			case Common::EN_ANY:
 				optText = optionsTextEN[i];
 				break;
+			case Common::RU_RUS:
+				optText = optionsTextRU[i];
+				break;
 			default:
 				break;
 			};
@@ -578,6 +581,9 @@ void PrinceEngine::checkInvOptions() {
 			case Common::EN_ANY:
 				invText = invOptionsTextEN[i];
 				break;
+			case Common::RU_RUS:
+				invText = invOptionsTextRU[i];
+				break;
 			default:
 				error("Unknown game language %d", getLanguage());
 				break;
diff --git a/engines/prince/option_text.h b/engines/prince/option_text.h
index f56dd42..cc97f04 100644
--- a/engines/prince/option_text.h
+++ b/engines/prince/option_text.h
@@ -82,4 +82,23 @@ const char *optionsTextEN[] = {
 	"Talk to"
 };
 
+// RU
+const char *invOptionsTextRU[] = {
+	"Cvjnhtnm",
+	"Bcgjkmp.",
+	"Jnrhsnm/""\x83""bnm ",
+	"Pfrhsnm/Nzyenm  ",
+	"Lfnm "
+};
+
+const char *optionsTextRU[] = {
+	"Gjlevfnm",
+	"Jcvjnhtnm",
+	"Dpznm ",
+	"Bcgjkmp.",
+	"Jnrhsnm/""\x83""bnm ",
+	"Pfrhsnm/Nzyenm  ",
+	"Ujdjhbnm  "
+};
+
 } // End of namespace Prince


Commit: d84c1ac7e01b7594f500d8d7f5b60a715eadf1be
    https://github.com/scummvm/scummvm/commit/d84c1ac7e01b7594f500d8d7f5b60a715eadf1be
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2018-05-05T23:17:35+02:00

Commit Message:
PRINCE: Fix header dependency

Changed paths:
    engines/prince/resource.cpp
    engines/prince/sound.cpp


diff --git a/engines/prince/resource.cpp b/engines/prince/resource.cpp
index 8d4326c..ce0396a 100644
--- a/engines/prince/resource.cpp
+++ b/engines/prince/resource.cpp
@@ -20,6 +20,7 @@
  *
  */
 
+#include "common/fs.h"
 #include "common/config-manager.h"
 
 #include "prince/prince.h"
diff --git a/engines/prince/sound.cpp b/engines/prince/sound.cpp
index c062c42..a742005 100644
--- a/engines/prince/sound.cpp
+++ b/engines/prince/sound.cpp
@@ -20,6 +20,8 @@
  *
  */
 
+#include "common/archive.h"
+
 #include "audio/audiostream.h"
 #include "audio/decoders/wave.h"
 





More information about the Scummvm-git-logs mailing list