[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