From 1a55957647a10540f5c11935c2ede372e593f713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Fri, 11 Oct 2013 01:01:56 +0100 Subject: [PATCH 001/374] PRINCE: Detection of german and polish game --- engines/configure.engines | 1 + engines/engines.mk | 5 ++ engines/plugins_table.h | 3 + engines/prince/detection.cpp | 145 +++++++++++++++++++++++++++++++++++ engines/prince/module.mk | 13 ++++ engines/prince/prince.cpp | 70 +++++++++++++++++ engines/prince/prince.h | 79 +++++++++++++++++++ 7 files changed, 316 insertions(+) create mode 100644 engines/prince/detection.cpp create mode 100644 engines/prince/module.mk create mode 100644 engines/prince/prince.cpp create mode 100644 engines/prince/prince.h diff --git a/engines/configure.engines b/engines/configure.engines index 20e5a56ef100..fab0862407c7 100644 --- a/engines/configure.engines +++ b/engines/configure.engines @@ -33,6 +33,7 @@ add_engine myst "Myst" no "" "" "16bit" add_engine neverhood "Neverhood" no add_engine parallaction "Parallaction" yes add_engine pegasus "The Journeyman Project: Pegasus Prime" yes "" "" "16bit" +add_engine prince "The Prince & The Coward" no add_engine queen "Flight of the Amazon Queen" yes add_engine saga "SAGA" yes "ihnm saga2" "ITE" add_engine ihnm "IHNM" yes diff --git a/engines/engines.mk b/engines/engines.mk index 5b3eeea61cca..7ad9dd666d0b 100644 --- a/engines/engines.mk +++ b/engines/engines.mk @@ -155,6 +155,11 @@ DEFINES += -DENABLE_PEGASUS=$(ENABLE_PEGASUS) MODULES += engines/pegasus endif +ifdef ENABLE_PRINCE +DEFINES += -DENABLE_PRINCE=$(ENABLE_PRINCE) +MODULES += engines/prince +endif + ifdef ENABLE_QUEEN DEFINES += -DENABLE_QUEEN=$(ENABLE_QUEEN) MODULES += engines/queen diff --git a/engines/plugins_table.h b/engines/plugins_table.h index ee7713bb76b2..85283b2e8a37 100644 --- a/engines/plugins_table.h +++ b/engines/plugins_table.h @@ -122,3 +122,6 @@ LINK_PLUGIN(TUCKER) #if PLUGIN_ENABLED_STATIC(WINTERMUTE) LINK_PLUGIN(WINTERMUTE) #endif +#if PLUGIN_ENABLED_STATIC(PRINCE) +LINK_PLUGIN(PRINCE) +#endif diff --git a/engines/prince/detection.cpp b/engines/prince/detection.cpp new file mode 100644 index 000000000000..e7f1ac01dd18 --- /dev/null +++ b/engines/prince/detection.cpp @@ -0,0 +1,145 @@ +/* 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 "base/plugins.h" +#include "engines/advancedDetector.h" + +#include "prince/prince.h" + +namespace Prince { + +struct PrinceGameDescription { + ADGameDescription desc; + + int gameType; +}; + +int PrinceEngine::getGameType() const { + return _gameDescription->gameType; +} + +const char *PrinceEngine::getGameId() const { + return _gameDescription->desc.gameid; +} + +uint32 PrinceEngine::getFeatures() const { + return _gameDescription->desc.flags; +} + +Common::Language PrinceEngine::getLanguage() const { + return _gameDescription->desc.language; +} + +} + +static const PlainGameDescriptor princeGames[] = { + {"prince", "Prince Game"}, + {0, 0} +}; + +namespace Prince { + +static const PrinceGameDescription gameDescriptions[] = { + + // German + { + { + "prince", + "Galador", + AD_ENTRY1s("databank.ptc", "5fa03833177331214ec1354761b1d2ee", 3565031), + Common::DE_DEU, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NONE) + }, + 0 + }, + // Polish + { + { + "prince", + "Ksiaze i Tchorz", + AD_ENTRY1s("databank.ptc", "48ec9806bda9d152acbea8ce31c93c49", 3435298), + Common::PL_POL, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NONE) + }, + 1 + }, + + + { AD_TABLE_END_MARKER, 0 } +}; + +} // End of namespace Prince + +using namespace Prince; + +// we match from data too, to stop detection from a non-top-level directory +const static char *directoryGlobs[] = { + "all", + 0 +}; + +class PrinceMetaEngine : public AdvancedMetaEngine { +public: + PrinceMetaEngine() : AdvancedMetaEngine(Prince::gameDescriptions, sizeof(Prince::PrinceGameDescription), princeGames) { + _singleid = "prince"; + _maxScanDepth = 2; + _directoryGlobs = directoryGlobs; + } + + virtual const char *getName() const { + return "Prince Engine"; + } + + virtual const char *getOriginalCopyright() const { + return "Copyright (C)"; + } + + virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; + virtual bool hasFeature(MetaEngineFeature f) const; +}; + +bool PrinceMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { + using namespace Prince; + const PrinceGameDescription *gd = (const PrinceGameDescription *)desc; + if (gd) { + *engine = new PrinceEngine(syst, gd); + } + return gd != 0; +} + +bool PrinceMetaEngine::hasFeature(MetaEngineFeature f) const { + return false; +} + +bool Prince::PrinceEngine::hasFeature(EngineFeature f) const { + return false;//(f == kSupportsRTL); +} + +#if PLUGIN_ENABLED_DYNAMIC(PRINCE) +REGISTER_PLUGIN_DYNAMIC(PRINCE, PLUGIN_TYPE_ENGINE, PrinceMetaEngine); +#else +REGISTER_PLUGIN_STATIC(PRINCE, PLUGIN_TYPE_ENGINE, PrinceMetaEngine); +#endif diff --git a/engines/prince/module.mk b/engines/prince/module.mk new file mode 100644 index 000000000000..1621e48ce763 --- /dev/null +++ b/engines/prince/module.mk @@ -0,0 +1,13 @@ +MODULE := engines/prince + +MODULE_OBJS = \ + detection.o \ + prince.o + +# This module can be built as a plugin +ifeq ($(ENABLE_PRINCE), DYNAMIC_PLUGIN) +PLUGIN := 1 +endif + +# Include common rules +include $(srcdir)/rules.mk diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp new file mode 100644 index 000000000000..e2149e991917 --- /dev/null +++ b/engines/prince/prince.cpp @@ -0,0 +1,70 @@ +/* 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/scummsys.h" + +#include "common/config-manager.h" +#include "common/debug-channels.h" +#include "common/debug.h" +#include "common/events.h" +#include "common/file.h" +#include "common/random.h" +#include "common/fs.h" +#include "common/keyboard.h" +#include "common/substream.h" + +#include "graphics/cursorman.h" +#include "graphics/surface.h" +#include "graphics/palette.h" +#include "graphics/pixelformat.h" + +#include "engines/util.h" +#include "engines/advancedDetector.h" + +#include "audio/audiostream.h" + +#include "prince/prince.h" + +namespace Prince { + +PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) { + _rnd = new Common::RandomSource("prince"); +} + +PrinceEngine::~PrinceEngine() { + DebugMan.clearAllDebugChannels(); + + delete _rnd; +} + +Common::Error PrinceEngine::run() { + + initGraphics(640, 480, true); + + return Common::kNoError; +} + +void PrinceEngine::setFullPalette() { + _system->getPaletteManager()->setPalette(_palette, 0, 256); +} + + +} // End of namespace Prince diff --git a/engines/prince/prince.h b/engines/prince/prince.h new file mode 100644 index 000000000000..e73deb63e344 --- /dev/null +++ b/engines/prince/prince.h @@ -0,0 +1,79 @@ +/* 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_H +#define PRINCE_H + +#include "common/random.h" +#include "common/system.h" +#include "common/debug.h" +#include "common/debug-channels.h" +#include "common/textconsole.h" +#include "common/rect.h" + +#include "engines/engine.h" +#include "engines/util.h" + +#include "graphics/surface.h" + +#include "audio/mixer.h" + +namespace Prince { + +struct PrinceGameDescription; + +class PrinceEngine; + +class PrinceEngine : public Engine { +protected: + Common::Error run(); + +public: + PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc); + virtual ~PrinceEngine(); + + virtual bool hasFeature(EngineFeature f) const; + + int getGameType() const; + const char *getGameId() const; + uint32 getFeatures() const; + Common::Language getLanguage() const; + + const PrinceGameDescription *_gameDescription; + +private: + Common::RandomSource *_rnd; + + byte _palette[768]; + Graphics::Surface *_frontScreen; + Graphics::Surface *_roomBackground; + + void loadBackground(Common::SeekableReadStream *stream); + void setFullPalette(); + + void drawSprite(Graphics::Surface *sprite, int32 x, int32 y, int32 mod); + +}; + +} // End of namespace Prince + +#endif From b49707d9485c4d1eaf05fc079e15625b4e2672da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Sat, 12 Oct 2013 14:50:57 +0100 Subject: [PATCH 002/374] PRINCE: archive added --- engines/prince/archive.cpp | 0 engines/prince/archive.h | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 engines/prince/archive.cpp create mode 100644 engines/prince/archive.h diff --git a/engines/prince/archive.cpp b/engines/prince/archive.cpp new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/engines/prince/archive.h b/engines/prince/archive.h new file mode 100644 index 000000000000..3624a87a332d --- /dev/null +++ b/engines/prince/archive.h @@ -0,0 +1,34 @@ +/* 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_ARCHIVE_H +#define PRINCE_ARCHIVE_H + +#include "common/archive.h" + +namespace Price { + +class Archive : public Common::Archive { +}; + +} + +#endif From fb2627569e03f3a1f51d7619db381253b30b9a0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Sun, 13 Oct 2013 02:42:09 +0100 Subject: [PATCH 003/374] PRINCE: mhwanh decoder added. simple game loop works --- engines/prince/font.cpp | 94 +++++++++++++++++++++++++++++++++++++++ engines/prince/font.h | 66 +++++++++++++++++++++++++++ engines/prince/mhwanh.cpp | 77 ++++++++++++++++++++++++++++++++ engines/prince/mhwanh.h | 52 ++++++++++++++++++++++ engines/prince/module.mk | 2 + engines/prince/prince.cpp | 90 +++++++++++++++++++++++++++++++++++++ engines/prince/prince.h | 4 +- 7 files changed, 384 insertions(+), 1 deletion(-) create mode 100644 engines/prince/font.cpp create mode 100644 engines/prince/font.h create mode 100644 engines/prince/mhwanh.cpp create mode 100644 engines/prince/mhwanh.h diff --git a/engines/prince/font.cpp b/engines/prince/font.cpp new file mode 100644 index 000000000000..d3ae4d6b8374 --- /dev/null +++ b/engines/prince/font.cpp @@ -0,0 +1,94 @@ +/* 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/archive.h" +#include "common/debug.h" +#include "common/stream.h" +#include "common/str.h" + +#include "graphics/surface.h" + +#include "prince/font.h" + +namespace Prince { + +Font::Font() +{ +} + +Font::~Font() +{ + delete _fontData; +} + +bool Font::load(Common::SeekableReadStream &stream) +{ + stream.seek(0); + _fontData = new byte[stream.size()]; + stream.read(_fontData, stream.size()); + return true; +} + +int Font::getFontHeight() const +{ + debug("Font::getFontHeight %d", _fontData[5]); + return _fontData[5]; +} + +int Font::getMaxCharWidth() const +{ + return 0; +} + +Font::ChrData Font::getChrData(byte chr) const +{ + chr -= 32; + uint16 chrOffset = 4*chr+6; + + ChrData chrData; + chrData._width = _fontData[chrOffset+2]; + chrData._height = _fontData[chrOffset+3]; + chrData._pixels = _fontData + READ_LE_UINT16(_fontData + chrOffset); + + return chrData; +} + +int Font::getCharWidth(byte chr) const +{ + return getChrData(chr)._width; +} + +void Font::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const +{ + const ChrData chrData = getChrData(chr); + const byte *src = chrData._pixels; + byte *target = (byte *)dst->getBasePtr(x, y); + + for (int i = 0; i < chrData._height; i++) { + memcpy(target, src, chrData._width); + src += chrData._width; + target += dst->pitch; + } + +} + +} diff --git a/engines/prince/font.h b/engines/prince/font.h new file mode 100644 index 000000000000..0bffcf601be7 --- /dev/null +++ b/engines/prince/font.h @@ -0,0 +1,66 @@ +/* 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_FONT_H +#define PRINCE_FONT_H + +#include "graphics/font.h" + +namespace Graphics { + class Surface; +} + +namespace Common { + class String; +} + +namespace Prince { + +class Font : public Graphics::Font { +public: + Font(); + virtual ~Font(); + + bool load(Common::SeekableReadStream &stream); + + virtual int getFontHeight() const override; + + virtual int getMaxCharWidth() const override; + + virtual int getCharWidth(byte chr) const override; + + virtual void drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const override; + +private: + struct ChrData { + byte * _pixels; + byte _width; + byte _height; + }; + + ChrData getChrData(byte chr) const; + + byte * _fontData; +}; + +} + +#endif diff --git a/engines/prince/mhwanh.cpp b/engines/prince/mhwanh.cpp new file mode 100644 index 000000000000..4ce7beded985 --- /dev/null +++ b/engines/prince/mhwanh.cpp @@ -0,0 +1,77 @@ +/* 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/stream.h" + +#include "graphics/surface.h" + +#include "prince/mhwanh.h" + +namespace Prince { + +MhwanhDecoder::MhwanhDecoder() : _surface(0), _palette(0), _paletteColorCount(0) +{ +} + +MhwanhDecoder::~MhwanhDecoder() +{ + destroy(); +} + +void MhwanhDecoder::destroy() +{ + if (_surface) + { + _surface->free(); + delete _surface; _surface = 0; + } + + delete [] _palette; _palette = 0; + _paletteColorCount = 0; +} + +bool MhwanhDecoder::loadStream(Common::SeekableReadStream &stream) +{ + _paletteColorCount = 256; + stream.seek(0); + stream.skip(0x20); + // Read the palette + _palette = new byte[_paletteColorCount * 3]; + for (uint16 i = 0; i < _paletteColorCount; i++) { + _palette[i * 3 + 0] = stream.readByte(); + _palette[i * 3 + 1] = stream.readByte(); + _palette[i * 3 + 2] = stream.readByte(); + } + + _surface = new Graphics::Surface(); + _surface->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); + for (int h = 0; h < 480; ++h) + { + stream.read(_surface->getBasePtr(0, h - 1), 640); + } + + return true; +} + +} + + diff --git a/engines/prince/mhwanh.h b/engines/prince/mhwanh.h new file mode 100644 index 000000000000..44f957372e3c --- /dev/null +++ b/engines/prince/mhwanh.h @@ -0,0 +1,52 @@ +/* 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_MHWANH_H +#define PRINCE_MHWANH_H + +#include "graphics/decoders/image_decoder.h" + +namespace Prince { + +class MhwanhDecoder : public Graphics::ImageDecoder +{ +public: + MhwanhDecoder(); + virtual ~MhwanhDecoder(); + + // ImageDecoder API + void destroy(); + virtual bool loadStream(Common::SeekableReadStream &stream); + virtual Graphics::Surface *getSurface() const { return _surface; } + const byte *getPalette() const { return _palette; } + uint16 getPaletteCount() const { return _paletteColorCount; } + +private: + Graphics::Surface *_surface; + byte *_palette; + uint16 _paletteColorCount; +}; + +} + + +#endif diff --git a/engines/prince/module.mk b/engines/prince/module.mk index 1621e48ce763..e4a792f84d34 100644 --- a/engines/prince/module.mk +++ b/engines/prince/module.mk @@ -1,7 +1,9 @@ MODULE := engines/prince MODULE_OBJS = \ + mhwanh.o \ detection.o \ + font.o \ prince.o # This module can be built as a plugin diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index e2149e991917..2791bda86cab 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -35,6 +35,7 @@ #include "graphics/surface.h" #include "graphics/palette.h" #include "graphics/pixelformat.h" +#include "graphics/decoders/bmp.h" #include "engines/util.h" #include "engines/advancedDetector.h" @@ -42,11 +43,14 @@ #include "audio/audiostream.h" #include "prince/prince.h" +#include "prince/font.h" +#include "prince/mhwanh.h" namespace Prince { PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) { _rnd = new Common::RandomSource("prince"); + } PrinceEngine::~PrinceEngine() { @@ -59,9 +63,95 @@ Common::Error PrinceEngine::run() { initGraphics(640, 480, true); + const Common::FSNode gameDataDir(ConfMan.get("path")); + + debug("Adding all path: %s", gameDataDir.getPath().c_str()); + + SearchMan.addSubDirectoryMatching(gameDataDir, "all", 0, 2); + SearchMan.addSubDirectoryMatching(gameDataDir, "01", 0, 2); + + Common::SeekableReadStream * walizka = SearchMan.createReadStreamForMember("walizka"); + + Common::SeekableReadStream *font1stream = SearchMan.createReadStreamForMember("font1.raw"); + if (!font1stream) + return Common::kPathNotFile; + + Font font1 = Font(); + if (font1.load(*font1stream)) + { + font1.getCharWidth(103); + } + + Common::SeekableReadStream *room = SearchMan.createReadStreamForMember("room"); + + _frontScreen = new Graphics::Surface(); + _frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); + + if (room) + { + Graphics::BitmapDecoder roomBmp; + roomBmp.loadStream(*room); + _roomBackground = roomBmp.getSurface(); + _system->getPaletteManager()->setPalette(roomBmp.getPalette(), 0, 256); + + font1.drawString(_frontScreen, "Hello World", 10, 10, 640, 1); + + MhwanhDecoder walizkaBmp; + if (walizka) + { + debug("Loading walizka"); + if (walizkaBmp.loadStream(*walizka)) + { + _roomBackground = walizkaBmp.getSurface(); + _system->getPaletteManager()->setPalette(walizkaBmp.getPalette(), 0, 256); + } + } + + + mainLoop(); + } + delete room; + + + return Common::kNoError; } +void PrinceEngine::mainLoop() { + uint32 nextFrameTime = 0; + while (!shouldQuit()) { + Common::Event event; + Common::EventManager *eventMan = _system->getEventManager(); + while (eventMan->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_KEYDOWN: + break; + case Common::EVENT_KEYUP: + break; + case Common::EVENT_MOUSEMOVE: + break; + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_RBUTTONDOWN: + break; + case Common::EVENT_LBUTTONUP: + case Common::EVENT_RBUTTONUP: + break; + case Common::EVENT_QUIT: + _system->quit(); + break; + default: + break; + } + } + _system->copyRectToScreen((byte*)_roomBackground->getBasePtr(0,0), 640, 0, 0, 640, 480); + + _system->updateScreen(); + + _system->delayMillis(40); + + } +} + void PrinceEngine::setFullPalette() { _system->getPaletteManager()->setPalette(_palette, 0, 256); } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index e73deb63e344..3ae6c6a221d8 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -65,7 +65,9 @@ class PrinceEngine : public Engine { byte _palette[768]; Graphics::Surface *_frontScreen; - Graphics::Surface *_roomBackground; + const Graphics::Surface *_roomBackground; + + void mainLoop(); void loadBackground(Common::SeekableReadStream *stream); void setFullPalette(); From dce5c876c5faa7577e8e6cdb47a8a3f071c62db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Sun, 13 Oct 2013 22:17:39 +0100 Subject: [PATCH 004/374] PRINCE: graphic routines moved to separate file --- engines/prince/graphics.cpp | 34 ++++++++++++++++++++++ engines/prince/graphics.h | 58 +++++++++++++++++++++++++++++++++++++ engines/prince/mhwanh.cpp | 2 +- engines/prince/module.mk | 1 + engines/prince/prince.cpp | 35 +++++++++++----------- engines/prince/prince.h | 15 ++-------- 6 files changed, 114 insertions(+), 31 deletions(-) create mode 100644 engines/prince/graphics.cpp create mode 100644 engines/prince/graphics.h diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp new file mode 100644 index 000000000000..2d26dc044376 --- /dev/null +++ b/engines/prince/graphics.cpp @@ -0,0 +1,34 @@ +#include "prince/graphics.h" + +#include "prince/prince.h" + +#include "graphics/palette.h" + +namespace Prince { + +GraphicsMan::GraphicsMan(PrinceEngine *vm) : _vm(vm), _changed(false) +{ + initGraphics(640, 480, true); +} + +void GraphicsMan::update() +{ + if (_changed) + { + _vm->_system->copyRectToScreen((byte*)_roomBackground->getBasePtr(0,0), 640, 0, 0, 640, 480); + + _vm->_system->updateScreen(); + } +} + +void GraphicsMan::setPalette(const byte *palette) +{ + _vm->_system->getPaletteManager()->setPalette(palette, 0, 256); +} + +void GraphicsMan::change() +{ + _changed = true; +} + +} diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h new file mode 100644 index 000000000000..3599cbc346a3 --- /dev/null +++ b/engines/prince/graphics.h @@ -0,0 +1,58 @@ +/* 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_GRAPHICS_H +#define PRINCE_GRAPHICS_H + +#include "graphics/surface.h" + + +namespace Prince { + +class PrinceEngine; + +class GraphicsMan +{ +public: + GraphicsMan(PrinceEngine *vm); + + void update(); + + void change(); + + void setPalette(const byte *palette); + + Graphics::Surface *_backScreen; + const Graphics::Surface *_roomBackground; + +private: + + PrinceEngine *_vm; + + bool _changed; + byte _palette[3 * 256]; + Graphics::Surface *_frontScreen; +}; + +} + +#endif diff --git a/engines/prince/mhwanh.cpp b/engines/prince/mhwanh.cpp index 4ce7beded985..5ad39313a03b 100644 --- a/engines/prince/mhwanh.cpp +++ b/engines/prince/mhwanh.cpp @@ -42,7 +42,7 @@ void MhwanhDecoder::destroy() if (_surface) { _surface->free(); - delete _surface; _surface = 0; + _surface = 0; } delete [] _palette; _palette = 0; diff --git a/engines/prince/module.mk b/engines/prince/module.mk index e4a792f84d34..8997ee1daa5b 100644 --- a/engines/prince/module.mk +++ b/engines/prince/module.mk @@ -1,6 +1,7 @@ MODULE := engines/prince MODULE_OBJS = \ + graphics.o \ mhwanh.o \ detection.o \ font.o \ diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 2791bda86cab..29451c8e66aa 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ + #include "common/scummsys.h" #include "common/config-manager.h" @@ -45,6 +46,7 @@ #include "prince/prince.h" #include "prince/font.h" #include "prince/mhwanh.h" +#include "prince/graphics.h" namespace Prince { @@ -61,7 +63,7 @@ PrinceEngine::~PrinceEngine() { Common::Error PrinceEngine::run() { - initGraphics(640, 480, true); + _graph = new GraphicsMan(this); const Common::FSNode gameDataDir(ConfMan.get("path")); @@ -81,20 +83,21 @@ Common::Error PrinceEngine::run() { { font1.getCharWidth(103); } + delete font1stream; Common::SeekableReadStream *room = SearchMan.createReadStreamForMember("room"); - _frontScreen = new Graphics::Surface(); - _frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); + //_frontScreen = new Graphics::Surface(); + //_frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); if (room) { Graphics::BitmapDecoder roomBmp; roomBmp.loadStream(*room); - _roomBackground = roomBmp.getSurface(); + //_roomBackground = roomBmp.getSurface(); _system->getPaletteManager()->setPalette(roomBmp.getPalette(), 0, 256); - font1.drawString(_frontScreen, "Hello World", 10, 10, 640, 1); + //font1.drawString(_frontScreen, "Hello World", 10, 10, 640, 1); MhwanhDecoder walizkaBmp; if (walizka) @@ -102,23 +105,23 @@ Common::Error PrinceEngine::run() { debug("Loading walizka"); if (walizkaBmp.loadStream(*walizka)) { - _roomBackground = walizkaBmp.getSurface(); - _system->getPaletteManager()->setPalette(walizkaBmp.getPalette(), 0, 256); + _graph->_roomBackground = walizkaBmp.getSurface(); + _graph->setPalette(walizkaBmp.getPalette()); } } + _graph->change(); + mainLoop(); } delete room; - - return Common::kNoError; } void PrinceEngine::mainLoop() { - uint32 nextFrameTime = 0; + //uint32 nextFrameTime = 0; while (!shouldQuit()) { Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); @@ -137,24 +140,20 @@ void PrinceEngine::mainLoop() { case Common::EVENT_RBUTTONUP: break; case Common::EVENT_QUIT: - _system->quit(); break; default: break; } } - _system->copyRectToScreen((byte*)_roomBackground->getBasePtr(0,0), 640, 0, 0, 640, 480); - _system->updateScreen(); + if (shouldQuit()) + return; + + _graph->update(); _system->delayMillis(40); } } -void PrinceEngine::setFullPalette() { - _system->getPaletteManager()->setPalette(_palette, 0, 256); -} - - } // End of namespace Prince diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 3ae6c6a221d8..0c79d36ca476 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -33,8 +33,6 @@ #include "engines/engine.h" #include "engines/util.h" -#include "graphics/surface.h" - #include "audio/mixer.h" namespace Prince { @@ -42,6 +40,7 @@ namespace Prince { struct PrinceGameDescription; class PrinceEngine; +class GraphicsMan; class PrinceEngine : public Engine { protected: @@ -62,17 +61,9 @@ class PrinceEngine : public Engine { private: Common::RandomSource *_rnd; - - byte _palette[768]; - Graphics::Surface *_frontScreen; - const Graphics::Surface *_roomBackground; - - void mainLoop(); - - void loadBackground(Common::SeekableReadStream *stream); - void setFullPalette(); + GraphicsMan *_graph; - void drawSprite(Graphics::Surface *sprite, int32 x, int32 y, int32 mod); + void mainLoop(); }; From 71f8ce0894117a9b5431c7066ad1352203d89c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Sun, 13 Oct 2013 22:34:26 +0100 Subject: [PATCH 005/374] PRINCE: script added --- engines/prince/module.mk | 1 + engines/prince/script.cpp | 58 +++++++++++++++++++++++++++++++ engines/prince/script.h | 73 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 engines/prince/script.cpp create mode 100644 engines/prince/script.h diff --git a/engines/prince/module.mk b/engines/prince/module.mk index 8997ee1daa5b..853592b50365 100644 --- a/engines/prince/module.mk +++ b/engines/prince/module.mk @@ -1,6 +1,7 @@ MODULE := engines/prince MODULE_OBJS = \ + script.o \ graphics.o \ mhwanh.o \ detection.o \ diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp new file mode 100644 index 000000000000..da1dd4cf289c --- /dev/null +++ b/engines/prince/script.cpp @@ -0,0 +1,58 @@ +#include "prince/script.h" + +#include "common/debug-channels.h" +#include "common/stream.h" + +namespace Prince { + +Script::Script(PrinceEngine *vm) : + _code(NULL), _stacktop(0), _vm(vm), _random("GroovieScripts") { +} + +Script::~Script() { +} + +bool Script::loadFromStream(Common::SeekableReadStream &stream) { + _codeSize = stream.size(); + _code = new byte[_codeSize]; + + if (!_code) + return false; + + stream.read(_code, _codeSize); + // Initialize the script + _currentInstruction = 0; + + return true; +} + +void Script::step() { +} + +uint8 Script::getCodeByte(uint16 address) { + if (address >= _codeSize) + error("Trying to read a script byte at address 0x%04X, while the " + "script is just 0x%04X bytes long", address, _codeSize); + return _code[address]; +} + +uint8 Script::readScript8bits() { + uint8 data = getCodeByte(_currentInstruction); + _currentInstruction++; + return data; +} + +uint16 Script::readScript16bits() { + uint8 lower = readScript8bits(); + uint8 upper = readScript8bits(); + return lower | (upper << 8); +} + +uint32 Script::readScript32bits() { + uint16 lower = readScript16bits(); + uint16 upper = readScript16bits(); + return lower | (upper << 16); +} + +} + diff --git a/engines/prince/script.h b/engines/prince/script.h new file mode 100644 index 000000000000..1365fb7ec5ba --- /dev/null +++ b/engines/prince/script.h @@ -0,0 +1,73 @@ +/* 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_SCRIPT_H +#define PRINCE_SCRIPT_H + +#include "common/random.h" + +namespace Common { + class SeekableReadStream; +} + +namespace Prince { + +class PrinceEngine; + +class Script +{ +public: + Script(PrinceEngine *vm); + virtual ~Script(); + + bool loadFromStream(Common::SeekableReadStream &stream); + + void step(); + +private: + PrinceEngine *_vm; + + Common::RandomSource _random; + + byte *_code; + uint16 _codeSize; + uint16 _currentInstruction; + + // Stack + uint16 _stack[0x20]; + uint8 _stacktop; + uint8 _savedStacktop; + + // Helper functions + uint8 getCodeByte(uint16 address); + uint8 readScript8bits(); + uint16 readScript16bits(); + uint32 readScript32bits(); + uint16 readScript8or16bits(); + + typedef void (Script::*OpcodeFunc)(); + static OpcodeFunc _opcodes[]; +}; + +} + +#endif From 30ad6df5fccbfcd1097d498e8dc01965e4e5cb2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Sun, 13 Oct 2013 22:36:21 +0100 Subject: [PATCH 006/374] PRINCE: code convention cleanup --- engines/prince/font.cpp | 25 ++++++++----------------- engines/prince/graphics.cpp | 16 ++++++---------- engines/prince/mhwanh.cpp | 19 +++++++------------ engines/prince/prince.cpp | 12 ++++-------- 4 files changed, 25 insertions(+), 47 deletions(-) diff --git a/engines/prince/font.cpp b/engines/prince/font.cpp index d3ae4d6b8374..8d812c4d150c 100644 --- a/engines/prince/font.cpp +++ b/engines/prince/font.cpp @@ -31,36 +31,30 @@ namespace Prince { -Font::Font() -{ +Font::Font() { } -Font::~Font() -{ +Font::~Font() { delete _fontData; } -bool Font::load(Common::SeekableReadStream &stream) -{ +bool Font::load(Common::SeekableReadStream &stream) { stream.seek(0); _fontData = new byte[stream.size()]; stream.read(_fontData, stream.size()); return true; } -int Font::getFontHeight() const -{ +int Font::getFontHeight() const { debug("Font::getFontHeight %d", _fontData[5]); return _fontData[5]; } -int Font::getMaxCharWidth() const -{ +int Font::getMaxCharWidth() const { return 0; } -Font::ChrData Font::getChrData(byte chr) const -{ +Font::ChrData Font::getChrData(byte chr) const { chr -= 32; uint16 chrOffset = 4*chr+6; @@ -72,13 +66,11 @@ Font::ChrData Font::getChrData(byte chr) const return chrData; } -int Font::getCharWidth(byte chr) const -{ +int Font::getCharWidth(byte chr) const { return getChrData(chr)._width; } -void Font::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const -{ +void Font::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const { const ChrData chrData = getChrData(chr); const byte *src = chrData._pixels; byte *target = (byte *)dst->getBasePtr(x, y); @@ -88,7 +80,6 @@ void Font::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color src += chrData._width; target += dst->pitch; } - } } diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 2d26dc044376..356b35f83211 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -6,28 +6,24 @@ namespace Prince { -GraphicsMan::GraphicsMan(PrinceEngine *vm) : _vm(vm), _changed(false) -{ +GraphicsMan::GraphicsMan(PrinceEngine *vm) + : _vm(vm), _changed(false) { initGraphics(640, 480, true); } -void GraphicsMan::update() -{ - if (_changed) - { +void GraphicsMan::update() { + if (_changed) { _vm->_system->copyRectToScreen((byte*)_roomBackground->getBasePtr(0,0), 640, 0, 0, 640, 480); _vm->_system->updateScreen(); } } -void GraphicsMan::setPalette(const byte *palette) -{ +void GraphicsMan::setPalette(const byte *palette) { _vm->_system->getPaletteManager()->setPalette(palette, 0, 256); } -void GraphicsMan::change() -{ +void GraphicsMan::change() { _changed = true; } diff --git a/engines/prince/mhwanh.cpp b/engines/prince/mhwanh.cpp index 5ad39313a03b..0847220a70a5 100644 --- a/engines/prince/mhwanh.cpp +++ b/engines/prince/mhwanh.cpp @@ -28,19 +28,16 @@ namespace Prince { -MhwanhDecoder::MhwanhDecoder() : _surface(0), _palette(0), _paletteColorCount(0) -{ +MhwanhDecoder::MhwanhDecoder() + : _surface(0), _palette(0), _paletteColorCount(0) { } -MhwanhDecoder::~MhwanhDecoder() -{ +MhwanhDecoder::~MhwanhDecoder() { destroy(); } -void MhwanhDecoder::destroy() -{ - if (_surface) - { +void MhwanhDecoder::destroy() { + if (_surface) { _surface->free(); _surface = 0; } @@ -49,8 +46,7 @@ void MhwanhDecoder::destroy() _paletteColorCount = 0; } -bool MhwanhDecoder::loadStream(Common::SeekableReadStream &stream) -{ +bool MhwanhDecoder::loadStream(Common::SeekableReadStream &stream) { _paletteColorCount = 256; stream.seek(0); stream.skip(0x20); @@ -64,8 +60,7 @@ bool MhwanhDecoder::loadStream(Common::SeekableReadStream &stream) _surface = new Graphics::Surface(); _surface->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); - for (int h = 0; h < 480; ++h) - { + for (int h = 0; h < 480; ++h) { stream.read(_surface->getBasePtr(0, h - 1), 640); } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 29451c8e66aa..9cd7056a4168 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -79,8 +79,7 @@ Common::Error PrinceEngine::run() { return Common::kPathNotFile; Font font1 = Font(); - if (font1.load(*font1stream)) - { + if (font1.load(*font1stream)) { font1.getCharWidth(103); } delete font1stream; @@ -90,8 +89,7 @@ Common::Error PrinceEngine::run() { //_frontScreen = new Graphics::Surface(); //_frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); - if (room) - { + if (room) { Graphics::BitmapDecoder roomBmp; roomBmp.loadStream(*room); //_roomBackground = roomBmp.getSurface(); @@ -100,11 +98,9 @@ Common::Error PrinceEngine::run() { //font1.drawString(_frontScreen, "Hello World", 10, 10, 640, 1); MhwanhDecoder walizkaBmp; - if (walizka) - { + if (walizka) { debug("Loading walizka"); - if (walizkaBmp.loadStream(*walizka)) - { + if (walizkaBmp.loadStream(*walizka)) { _graph->_roomBackground = walizkaBmp.getSurface(); _graph->setPalette(walizkaBmp.getPalette()); } From e63b902def40e38e9b5163894adad9017e4fe3cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Mon, 14 Oct 2013 02:31:26 +0100 Subject: [PATCH 007/374] PRINCE: some opcodes in script added --- engines/prince/font.cpp | 2 +- engines/prince/font.h | 2 +- engines/prince/mhwanh.cpp | 7 +- engines/prince/prince.cpp | 31 +++- engines/prince/prince.h | 2 + engines/prince/script.cpp | 366 +++++++++++++++++++++++++++++++++++++- engines/prince/script.h | 336 +++++++++++++++++++++++++++++++--- 7 files changed, 712 insertions(+), 34 deletions(-) diff --git a/engines/prince/font.cpp b/engines/prince/font.cpp index 8d812c4d150c..e72d73e61a65 100644 --- a/engines/prince/font.cpp +++ b/engines/prince/font.cpp @@ -35,7 +35,7 @@ Font::Font() { } Font::~Font() { - delete _fontData; + delete [] _fontData; } bool Font::load(Common::SeekableReadStream &stream) { diff --git a/engines/prince/font.h b/engines/prince/font.h index 0bffcf601be7..ceae67df85bc 100644 --- a/engines/prince/font.h +++ b/engines/prince/font.h @@ -25,7 +25,7 @@ #include "graphics/font.h" namespace Graphics { - class Surface; + struct Surface; } namespace Common { diff --git a/engines/prince/mhwanh.cpp b/engines/prince/mhwanh.cpp index 0847220a70a5..4240ed40974e 100644 --- a/engines/prince/mhwanh.cpp +++ b/engines/prince/mhwanh.cpp @@ -29,7 +29,7 @@ namespace Prince { MhwanhDecoder::MhwanhDecoder() - : _surface(0), _palette(0), _paletteColorCount(0) { + : _surface(NULL), _palette(0), _paletteColorCount(0) { } MhwanhDecoder::~MhwanhDecoder() { @@ -39,7 +39,7 @@ MhwanhDecoder::~MhwanhDecoder() { void MhwanhDecoder::destroy() { if (_surface) { _surface->free(); - _surface = 0; + delete _surface; _surface = 0; } delete [] _palette; _palette = 0; @@ -47,6 +47,7 @@ void MhwanhDecoder::destroy() { } bool MhwanhDecoder::loadStream(Common::SeekableReadStream &stream) { + destroy(); _paletteColorCount = 256; stream.seek(0); stream.skip(0x20); @@ -61,7 +62,7 @@ bool MhwanhDecoder::loadStream(Common::SeekableReadStream &stream) { _surface = new Graphics::Surface(); _surface->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); for (int h = 0; h < 480; ++h) { - stream.read(_surface->getBasePtr(0, h - 1), 640); + stream.read(_surface->getBasePtr(0, h), 640); } return true; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 9cd7056a4168..c82dfd67238a 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -47,10 +47,12 @@ #include "prince/font.h" #include "prince/mhwanh.h" #include "prince/graphics.h" +#include "prince/script.h" namespace Prince { -PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) { +PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : + Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL) { _rnd = new Common::RandomSource("prince"); } @@ -96,22 +98,33 @@ Common::Error PrinceEngine::run() { _system->getPaletteManager()->setPalette(roomBmp.getPalette(), 0, 256); //font1.drawString(_frontScreen, "Hello World", 10, 10, 640, 1); - - MhwanhDecoder walizkaBmp; + // + _graph->_roomBackground = roomBmp.getSurface(); +#if 1 + MhwanhDecoder *walizkaBmp = new MhwanhDecoder(); if (walizka) { debug("Loading walizka"); - if (walizkaBmp.loadStream(*walizka)) { - _graph->_roomBackground = walizkaBmp.getSurface(); - _graph->setPalette(walizkaBmp.getPalette()); + if (walizkaBmp->loadStream(*walizka)) { + _graph->_roomBackground = walizkaBmp->getSurface(); + _graph->setPalette(walizkaBmp->getPalette()); } } - +#endif _graph->change(); + + Common::SeekableReadStream * skryptStream = SearchMan.createReadStreamForMember("skrypt.dat"); + if (!skryptStream) + return Common::kPathNotFile; + _script = new Script(this); + _script->loadFromStream(*skryptStream); + + delete skryptStream; mainLoop(); + delete room; + delete walizkaBmp; } - delete room; return Common::kNoError; } @@ -145,6 +158,8 @@ void PrinceEngine::mainLoop() { if (shouldQuit()) return; + _script->step(); + _graph->update(); _system->delayMillis(40); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 0c79d36ca476..966cee982e83 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -41,6 +41,7 @@ struct PrinceGameDescription; class PrinceEngine; class GraphicsMan; +class Script; class PrinceEngine : public Engine { protected: @@ -62,6 +63,7 @@ class PrinceEngine : public Engine { private: Common::RandomSource *_rnd; GraphicsMan *_graph; + Script *_script; void mainLoop(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index da1dd4cf289c..611b75152f88 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1,15 +1,19 @@ #include "prince/script.h" +#include "common/debug.h" #include "common/debug-channels.h" #include "common/stream.h" namespace Prince { +static const uint16 NUM_OPCODES = 144; + Script::Script(PrinceEngine *vm) : _code(NULL), _stacktop(0), _vm(vm), _random("GroovieScripts") { } Script::~Script() { + delete[] _code; } bool Script::loadFromStream(Common::SeekableReadStream &stream) { @@ -21,12 +25,43 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) { stream.read(_code, _codeSize); // Initialize the script - _currentInstruction = 0; + _currentInstruction = READ_LE_UINT32(_code + 4); return true; } +void Script::debugScript(const char *s, ...) { + char buf[STRINGBUFLEN]; + va_list va; + + va_start(va, s); + vsnprintf(buf, STRINGBUFLEN, s, va); + va_end(va); + + Common::String str = Common::String::format("@0x%04X: ", _lastInstruction); + str += Common::String::format("op 0x%02X: ", _lastOpcode); + debug("%s %s", str.c_str(), buf); +} + void Script::step() { + _lastInstruction = _currentInstruction; + // Prepare the base debug string + Common::String dstr = Common::String::format("@0x%04X: ", _currentInstruction); + + // Get the current opcode + _lastOpcode = readScript16bits(); + + dstr += Common::String::format("op 0x%02X: ", _lastOpcode); + + if (_lastOpcode > NUM_OPCODES) + error("Trying to execute unknown opcode %s", dstr.c_str()); + + + //debug("%s", _debugString.c_str()); + + // Execute the current opcode + OpcodeFunc op = _opcodes[_lastOpcode]; + (this->*op)(); } uint8 Script::getCodeByte(uint16 address) { @@ -54,5 +89,334 @@ uint32 Script::readScript32bits() { return lower | (upper << 16); } +void Script::O_WAITFOREVER() { + debugScript("O_WAITFOREVER"); +} +void Script::O_BLACKPALETTE() { + debugScript("O_BLACKPALETTE"); +} +void Script::O_SETUPPALETTE() { + debugScript("O_SETUPPALETTE"); +} +void Script::O_INITROOM() { + uint16 roomId = readScript16bits(); + debugScript("O_INITROOM %d", roomId); +} +void Script::O_SETSAMPLE() {} +void Script::O_FREESAMPLE() {} +void Script::O_PLAYSAMPLE() {} +void Script::O_PUTOBJECT() {} +void Script::O_REMOBJECT() {} +void Script::O_SHOWANIM() {} +void Script::O_CHECKANIMEND() {} +void Script::O_FREEANIM() {} +void Script::O_CHECKANIMFRAME() {} +void Script::O_PUTBACKANIM() {} +void Script::O_REMBACKANIM() {} +void Script::O_CHECKBACKANIMFRAME() {} +void Script::O_FREEALLSAMPLES() {} +void Script::O_SETMUSIC() {} +void Script::O_STOPMUSIC() {} +void Script::O__WAIT() {} +void Script::O_UPDATEOFF() {} +void Script::O_UPDATEON() {} +void Script::O_UPDATE () {} +void Script::O_CLS() {} +void Script::O__CALL() { + int32 address = readScript32bits(); + _stack[_stacktop] = _currentInstruction; + _stacktop++; + _currentInstruction += address - 4; + debugScript("O__CALL 0x%04X", _currentInstruction); +} +void Script::O_RETURN() { + // Get the return address + if (_stacktop > 0) { + _stacktop--; + _currentInstruction = _stack[_stacktop]; + } else { + error("Return: Stack is empty"); + } +} +void Script::O_GO() { + uint32 opPC = readScript32bits(); + debugScript("O_GO 0x%04X", opPC); + _currentInstruction += opPC - 4; +} +void Script::O_BACKANIMUPDATEOFF() {} +void Script::O_BACKANIMUPDATEON() {} +void Script::O_CHANGECURSOR() { + uint16 cursorId = readScript16bits(); + debugScript("O_CHANGECURSOR %x", cursorId); +} +void Script::O_CHANGEANIMTYPE() {} +void Script::O__SETFLAG() { + uint16 flagId = readScript16bits(); + uint16 value = readScript16bits(); + debugScript("O__SETFLAG 0x%04X %d", flagId, value); +} +void Script::O_COMPARE() {} +void Script::O_JUMPZ() {} +void Script::O_JUMPNZ() {} +void Script::O_EXIT() {} +void Script::O_ADDFLAG() {} +void Script::O_TALKANIM() {} +void Script::O_SUBFLAG() {} +void Script::O_SETSTRING() {} +void Script::O_ANDFLAG() {} +void Script::O_GETMOBDATA() {} +void Script::O_ORFLAG() {} +void Script::O_SETMOBDATA() {} +void Script::O_XORFLAG() {} +void Script::O_GETMOBTEXT() {} +void Script::O_MOVEHERO() {} +void Script::O_WALKHERO() {} +void Script::O_SETHERO() {} +void Script::O_HEROOFF() { + uint16 heroId = readScript16bits(); + debugScript("O_HEROOFF %d", heroId); +} +void Script::O_HEROON() {} +void Script::O_CLSTEXT() {} +void Script::O_CALLTABLE() {} +void Script::O_CHANGEMOB() {} +void Script::O_ADDINV() {} +void Script::O_REMINV() {} +void Script::O_REPINV() {} +void Script::O_OBSOLETE_GETACTION() {} +void Script::O_ADDWALKAREA() {} +void Script::O_REMWALKAREA() {} +void Script::O_RESTOREWALKAREA() {} +void Script::O_WAITFRAME() {} +void Script::O_SETFRAME() {} +void Script::O_RUNACTION() {} +void Script::O_COMPAREHI() {} +void Script::O_COMPARELO() {} +void Script::O_PRELOADSET() {} +void Script::O_FREEPRELOAD() {} +void Script::O_CHECKINV() {} +void Script::O_TALKHERO() {} +void Script::O_WAITTEXT() {} +void Script::O_SETHEROANIM() {} +void Script::O_WAITHEROANIM() {} +void Script::O_GETHERODATA() {} +void Script::O_GETMOUSEBUTTON() {} +void Script::O_CHANGEFRAMES() {} +void Script::O_CHANGEBACKFRAMES() {} +void Script::O_GETBACKANIMDATA() {} +void Script::O_GETANIMDATA() {} +void Script::O_SETBGCODE() {} +void Script::O_SETBACKFRAME() {} +void Script::O_GETRND() {} +void Script::O_TALKBACKANIM() {} +void Script::O_LOADPATH() {} +void Script::O_GETCHAR() {} +void Script::O_SETDFLAG() {} +void Script::O_CALLDFLAG() {} +void Script::O_PRINTAT() {} +void Script::O_ZOOMIN() {} +void Script::O_ZOOMOUT() {} +void Script::O_SETSTRINGOFFSET() {} +void Script::O_GETOBJDATA() {} +void Script::O_SETOBJDATA() {} +void Script::O_SWAPOBJECTS() {} +void Script::O_CHANGEHEROSET() {} +void Script::O_ADDSTRING() {} +void Script::O_SUBSTRING() {} +void Script::O_INITDIALOG() {} +void Script::O_ENABLEDIALOGOPT() {} +void Script::O_DISABLEDIALOGOPT() {} +void Script::O_SHOWDIALOGBOX() {} +void Script::O_STOPSAMPLE() {} +void Script::O_BACKANIMRANGE() {} +void Script::O_CLEARPATH() {} +void Script::O_SETPATH() {} +void Script::O_GETHEROX() {} +void Script::O_GETHEROY() {} +void Script::O_GETHEROD() {} +void Script::O_PUSHSTRING() {} +void Script::O_POPSTRING() {} +void Script::O_SETFGCODE() {} +void Script::O_STOPHERO() {} +void Script::O_ANIMUPDATEOFF() {} +void Script::O_ANIMUPDATEON() {} +void Script::O_FREECURSOR() {} +void Script::O_ADDINVQUIET() {} +void Script::O_RUNHERO() {} +void Script::O_SETBACKANIMDATA() {} +void Script::O_VIEWFLC() {} +void Script::O_CHECKFLCFRAME() {} +void Script::O_CHECKFLCEND() {} +void Script::O_FREEFLC() {} +void Script::O_TALKHEROSTOP() {} +void Script::O_HEROCOLOR() {} +void Script::O_GRABMAPA() {} +void Script::O_ENABLENAK() {} +void Script::O_DISABLENAK() {} +void Script::O_GETMOBNAME() {} +void Script::O_SWAPINVENTORY() {} +void Script::O_CLEARINVENTORY() {} +void Script::O_SKIPTEXT() {} +void Script::O_SETVOICEH() {} +void Script::O_SETVOICEA() {} +void Script::O_SETVOICEB() {} +void Script::O_SETVOICEC() {} +void Script::O_VIEWFLCLOOP() {} +void Script::O_FLCSPEED() {} +void Script::O_OPENINVENTORY() {} +void Script::O_KRZYWA() {} +void Script::O_GETKRZYWA() {} +void Script::O_GETMOB() {} +void Script::O_INPUTLINE() {} +void Script::O_SETVOICED() {} +void Script::O_BREAK_POINT() {} + +Script::OpcodeFunc Script::_opcodes[NUM_OPCODES] = { + &Script::O_WAITFOREVER, + &Script::O_BLACKPALETTE, + &Script::O_SETUPPALETTE, + &Script::O_INITROOM, + &Script::O_SETSAMPLE, + &Script::O_FREESAMPLE, + &Script::O_PLAYSAMPLE, + &Script::O_PUTOBJECT, + &Script::O_REMOBJECT, + &Script::O_SHOWANIM, + &Script::O_CHECKANIMEND, + &Script::O_FREEANIM, + &Script::O_CHECKANIMFRAME, + &Script::O_PUTBACKANIM, + &Script::O_REMBACKANIM, + &Script::O_CHECKBACKANIMFRAME, + &Script::O_FREEALLSAMPLES, + &Script::O_SETMUSIC, + &Script::O_STOPMUSIC, + &Script::O__WAIT, + &Script::O_UPDATEOFF, + &Script::O_UPDATEON, + &Script::O_UPDATE , + &Script::O_CLS, + &Script::O__CALL, + &Script::O_RETURN, + &Script::O_GO, + &Script::O_BACKANIMUPDATEOFF, + &Script::O_BACKANIMUPDATEON, + &Script::O_CHANGECURSOR, + &Script::O_CHANGEANIMTYPE, + &Script::O__SETFLAG, + &Script::O_COMPARE, + &Script::O_JUMPZ, + &Script::O_JUMPNZ, + &Script::O_EXIT, + &Script::O_ADDFLAG, + &Script::O_TALKANIM, + &Script::O_SUBFLAG, + &Script::O_SETSTRING, + &Script::O_ANDFLAG, + &Script::O_GETMOBDATA, + &Script::O_ORFLAG, + &Script::O_SETMOBDATA, + &Script::O_XORFLAG, + &Script::O_GETMOBTEXT, + &Script::O_MOVEHERO, + &Script::O_WALKHERO, + &Script::O_SETHERO, + &Script::O_HEROOFF, + &Script::O_HEROON, + &Script::O_CLSTEXT, + &Script::O_CALLTABLE, + &Script::O_CHANGEMOB, + &Script::O_ADDINV, + &Script::O_REMINV, + &Script::O_REPINV, + &Script::O_OBSOLETE_GETACTION, + &Script::O_ADDWALKAREA, + &Script::O_REMWALKAREA, + &Script::O_RESTOREWALKAREA, + &Script::O_WAITFRAME, + &Script::O_SETFRAME, + &Script::O_RUNACTION, + &Script::O_COMPAREHI, + &Script::O_COMPARELO, + &Script::O_PRELOADSET, + &Script::O_FREEPRELOAD, + &Script::O_CHECKINV, + &Script::O_TALKHERO, + &Script::O_WAITTEXT, + &Script::O_SETHEROANIM, + &Script::O_WAITHEROANIM, + &Script::O_GETHERODATA, + &Script::O_GETMOUSEBUTTON, + &Script::O_CHANGEFRAMES, + &Script::O_CHANGEBACKFRAMES, + &Script::O_GETBACKANIMDATA, + &Script::O_GETANIMDATA, + &Script::O_SETBGCODE, + &Script::O_SETBACKFRAME, + &Script::O_GETRND, + &Script::O_TALKBACKANIM, + &Script::O_LOADPATH, + &Script::O_GETCHAR, + &Script::O_SETDFLAG, + &Script::O_CALLDFLAG, + &Script::O_PRINTAT, + &Script::O_ZOOMIN, + &Script::O_ZOOMOUT, + &Script::O_SETSTRINGOFFSET, + &Script::O_GETOBJDATA, + &Script::O_SETOBJDATA, + &Script::O_SWAPOBJECTS, + &Script::O_CHANGEHEROSET, + &Script::O_ADDSTRING, + &Script::O_SUBSTRING, + &Script::O_INITDIALOG, + &Script::O_ENABLEDIALOGOPT, + &Script::O_DISABLEDIALOGOPT, + &Script::O_SHOWDIALOGBOX, + &Script::O_STOPSAMPLE, + &Script::O_BACKANIMRANGE, + &Script::O_CLEARPATH, + &Script::O_SETPATH, + &Script::O_GETHEROX, + &Script::O_GETHEROY, + &Script::O_GETHEROD, + &Script::O_PUSHSTRING, + &Script::O_POPSTRING, + &Script::O_SETFGCODE, + &Script::O_STOPHERO, + &Script::O_ANIMUPDATEOFF, + &Script::O_ANIMUPDATEON, + &Script::O_FREECURSOR, + &Script::O_ADDINVQUIET, + &Script::O_RUNHERO, + &Script::O_SETBACKANIMDATA, + &Script::O_VIEWFLC, + &Script::O_CHECKFLCFRAME, + &Script::O_CHECKFLCEND, + &Script::O_FREEFLC, + &Script::O_TALKHEROSTOP, + &Script::O_HEROCOLOR, + &Script::O_GRABMAPA, + &Script::O_ENABLENAK, + &Script::O_DISABLENAK, + &Script::O_GETMOBNAME, + &Script::O_SWAPINVENTORY, + &Script::O_CLEARINVENTORY, + &Script::O_SKIPTEXT, + &Script::O_SETVOICEH, + &Script::O_SETVOICEA, + &Script::O_SETVOICEB, + &Script::O_SETVOICEC, + &Script::O_VIEWFLCLOOP, + &Script::O_FLCSPEED, + &Script::O_OPENINVENTORY, + &Script::O_KRZYWA, + &Script::O_GETKRZYWA, + &Script::O_GETMOB, + &Script::O_INPUTLINE, + &Script::O_SETVOICED, + &Script::O_BREAK_POINT, +}; + } diff --git a/engines/prince/script.h b/engines/prince/script.h index 1365fb7ec5ba..93bac064336c 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -46,26 +46,322 @@ class Script private: PrinceEngine *_vm; - Common::RandomSource _random; - - byte *_code; - uint16 _codeSize; - uint16 _currentInstruction; - - // Stack - uint16 _stack[0x20]; - uint8 _stacktop; - uint8 _savedStacktop; - - // Helper functions - uint8 getCodeByte(uint16 address); - uint8 readScript8bits(); - uint16 readScript16bits(); - uint32 readScript32bits(); - uint16 readScript8or16bits(); - - typedef void (Script::*OpcodeFunc)(); - static OpcodeFunc _opcodes[]; + Common::RandomSource _random; + + byte *_code; + uint16 _codeSize; + uint32 _currentInstruction; + uint16 _lastOpcode; + uint32 _lastInstruction; + + // Stack + uint16 _stack[500]; + uint8 _stacktop; + uint8 _savedStacktop; + + // Helper functions + uint8 getCodeByte(uint16 address); + uint8 readScript8bits(); + uint16 readScript16bits(); + uint32 readScript32bits(); + uint16 readScript8or16bits(); + void debugScript(const char *s, ...); + + typedef void (Script::*OpcodeFunc)(); + static OpcodeFunc _opcodes[]; + + void O_WAITFOREVER(); + void O_BLACKPALETTE(); + void O_SETUPPALETTE(); + void O_INITROOM(); + void O_SETSAMPLE(); + void O_FREESAMPLE(); + void O_PLAYSAMPLE(); + void O_PUTOBJECT(); + void O_REMOBJECT(); + void O_SHOWANIM(); + void O_CHECKANIMEND(); + void O_FREEANIM(); + void O_CHECKANIMFRAME(); + void O_PUTBACKANIM(); + void O_REMBACKANIM(); + void O_CHECKBACKANIMFRAME(); + void O_FREEALLSAMPLES(); + void O_SETMUSIC(); + void O_STOPMUSIC(); + void O__WAIT(); + void O_UPDATEOFF(); + void O_UPDATEON(); + void O_UPDATE (); + void O_CLS(); + void O__CALL(); + void O_RETURN(); + void O_GO(); + void O_BACKANIMUPDATEOFF(); + void O_BACKANIMUPDATEON(); + void O_CHANGECURSOR(); + void O_CHANGEANIMTYPE(); + void O__SETFLAG(); + void O_COMPARE(); + void O_JUMPZ(); + void O_JUMPNZ(); + void O_EXIT(); + void O_ADDFLAG(); + void O_TALKANIM(); + void O_SUBFLAG(); + void O_SETSTRING(); + void O_ANDFLAG(); + void O_GETMOBDATA(); + void O_ORFLAG(); + void O_SETMOBDATA(); + void O_XORFLAG(); + void O_GETMOBTEXT(); + void O_MOVEHERO(); + void O_WALKHERO(); + void O_SETHERO(); + void O_HEROOFF(); + void O_HEROON(); + void O_CLSTEXT(); + void O_CALLTABLE(); + void O_CHANGEMOB(); + void O_ADDINV(); + void O_REMINV(); + void O_REPINV(); + void O_OBSOLETE_GETACTION(); + void O_ADDWALKAREA(); + void O_REMWALKAREA(); + void O_RESTOREWALKAREA(); + void O_WAITFRAME(); + void O_SETFRAME(); + void O_RUNACTION(); + void O_COMPAREHI(); + void O_COMPARELO(); + void O_PRELOADSET(); + void O_FREEPRELOAD(); + void O_CHECKINV(); + void O_TALKHERO(); + void O_WAITTEXT(); + void O_SETHEROANIM(); + void O_WAITHEROANIM(); + void O_GETHERODATA(); + void O_GETMOUSEBUTTON(); + void O_CHANGEFRAMES(); + void O_CHANGEBACKFRAMES(); + void O_GETBACKANIMDATA(); + void O_GETANIMDATA(); + void O_SETBGCODE(); + void O_SETBACKFRAME(); + void O_GETRND(); + void O_TALKBACKANIM(); + void O_LOADPATH(); + void O_GETCHAR(); + void O_SETDFLAG(); + void O_CALLDFLAG(); + void O_PRINTAT(); + void O_ZOOMIN(); + void O_ZOOMOUT(); + void O_SETSTRINGOFFSET(); + void O_GETOBJDATA(); + void O_SETOBJDATA(); + void O_SWAPOBJECTS(); + void O_CHANGEHEROSET(); + void O_ADDSTRING(); + void O_SUBSTRING(); + void O_INITDIALOG(); + void O_ENABLEDIALOGOPT(); + void O_DISABLEDIALOGOPT(); + void O_SHOWDIALOGBOX(); + void O_STOPSAMPLE(); + void O_BACKANIMRANGE(); + void O_CLEARPATH(); + void O_SETPATH(); + void O_GETHEROX(); + void O_GETHEROY(); + void O_GETHEROD(); + void O_PUSHSTRING(); + void O_POPSTRING(); + void O_SETFGCODE(); + void O_STOPHERO(); + void O_ANIMUPDATEOFF(); + void O_ANIMUPDATEON(); + void O_FREECURSOR(); + void O_ADDINVQUIET(); + void O_RUNHERO(); + void O_SETBACKANIMDATA(); + void O_VIEWFLC(); + void O_CHECKFLCFRAME(); + void O_CHECKFLCEND(); + void O_FREEFLC(); + void O_TALKHEROSTOP(); + void O_HEROCOLOR(); + void O_GRABMAPA(); + void O_ENABLENAK(); + void O_DISABLENAK(); + void O_GETMOBNAME(); + void O_SWAPINVENTORY(); + void O_CLEARINVENTORY(); + void O_SKIPTEXT(); + void O_SETVOICEH(); + void O_SETVOICEA(); + void O_SETVOICEB(); + void O_SETVOICEC(); + void O_VIEWFLCLOOP(); + void O_FLCSPEED(); + void O_OPENINVENTORY(); + void O_KRZYWA(); + void O_GETKRZYWA(); + void O_GETMOB(); + void O_INPUTLINE(); + void O_SETVOICED(); + void O_BREAK_POINT(); + + +#if 0 + O_WAITFOREVER ;00 + O_BLACKPALETTE ;01 + O_SETUPPALETTE ;02 + O_INITROOM ;03 + O_SETSAMPLE ;04 + O_FREESAMPLE ;05 + O_PLAYSAMPLE ;06 + O_PUTOBJECT ;07 + O_REMOBJECT ;08 + O_SHOWANIM ;09 + O_CHECKANIMEND ;10 + O_FREEANIM ;11 + O_CHECKANIMFRAME ;12 + O_PUTBACKANIM ;13 + O_REMBACKANIM ;14 + O_CHECKBACKANIMFRAME ;15 + O_FREEALLSAMPLES ;16 + O_SETMUSIC ;17 + O_STOPMUSIC ;18 + O__WAIT ;19 + O_UPDATEOFF ;20 + O_UPDATEON ;21 + O_UPDATE ;22 + O_CLS ;23 + O__CALL ;24 + O_RETURN ;25 + O_GO ;26 + O_BACKANIMUPDATEOFF ;27 + O_BACKANIMUPDATEON ;28 + O_CHANGECURSOR ;29 + O_CHANGEANIMTYPE ;30 + O__SETFLAG ;31 + O_COMPARE ;32 + O_JUMPZ ;33 + O_JUMPNZ ;34 + O_EXIT ;35 + O_ADDFLAG ;36 + O_TALKANIM ;37 + O_SUBFLAG ;38 + O_SETSTRING ;39 + O_ANDFLAG ;40 + O_GETMOBDATA ;41 + O_ORFLAG ;42 + O_SETMOBDATA ;43 + O_XORFLAG ;44 + O_GETMOBTEXT ;45 + O_MOVEHERO ;46 + O_WALKHERO ;47 + O_SETHERO ;48 + O_HEROOFF ;49 + O_HEROON ;50 + O_CLSTEXT ;51 + O_CALLTABLE ;52 + O_CHANGEMOB ;53 + O_ADDINV ;54 + O_REMINV ;55 + O_REPINV ;56 + O_OBSOLETE_GETACTION ;57 + O_ADDWALKAREA ;58 + O_REMWALKAREA ;59 + O_RESTOREWALKAREA ;60 + O_WAITFRAME ;61 + O_SETFRAME ;62 + O_RUNACTION ;63 + O_COMPAREHI ;64 + O_COMPARELO ;65 + O_PRELOADSET ;66 + O_FREEPRELOAD ;67 + O_CHECKINV ;68 + O_TALKHERO ;69 + O_WAITTEXT ;70 + O_SETHEROANIM ;71 + O_WAITHEROANIM ;72 + O_GETHERODATA ;73 + O_GETMOUSEBUTTON ;74 + O_CHANGEFRAMES ;75 + O_CHANGEBACKFRAMES ;76 + O_GETBACKANIMDATA ;77 + O_GETANIMDATA ;78 + O_SETBGCODE ;79 + O_SETBACKFRAME ;80 + O_GETRND ;81 + O_TALKBACKANIM ;82 + O_LOADPATH ;83 + O_GETCHAR ;84 + O_SETDFLAG ;85 + O_CALLDFLAG ;86 + O_PRINTAT ;87 + O_ZOOMIN ;88 + O_ZOOMOUT ;89 + O_SETSTRINGOFFSET ;90 + O_GETOBJDATA ;91 + O_SETOBJDATA ;92 + O_SWAPOBJECTS ;93 + O_CHANGEHEROSET ;94 + O_ADDSTRING ;95 + O_SUBSTRING ;96 + O_INITDIALOG ;97 + O_ENABLEDIALOGOPT ;98 + O_DISABLEDIALOGOPT ;99 + O_SHOWDIALOGBOX ;100 + O_STOPSAMPLE ;101 + O_BACKANIMRANGE ;102 + O_CLEARPATH ;103 + O_SETPATH ;104 + O_GETHEROX ;105 + O_GETHEROY ;106 + O_GETHEROD ;107 + O_PUSHSTRING ;108 + O_POPSTRING ;109 + O_SETFGCODE ;110 + O_STOPHERO ;111 + O_ANIMUPDATEOFF ;112 + O_ANIMUPDATEON ;113 + O_FREECURSOR ;114 + O_ADDINVQUIET ;115 + O_RUNHERO ;116 + O_SETBACKANIMDATA ;117 + O_VIEWFLC ;118 + O_CHECKFLCFRAME ;119 + O_CHECKFLCEND ;120 + O_FREEFLC ;121 + O_TALKHEROSTOP ;122 + O_HEROCOLOR ;123 + O_GRABMAPA ;124 + O_ENABLENAK ;125 + O_DISABLENAK ;126 + O_GETMOBNAME ;127 + O_SWAPINVENTORY ;128 + O_CLEARINVENTORY ;129 + O_SKIPTEXT ;130 + O_SETVOICEH ;131 + O_SETVOICEA ;132 + O_SETVOICEB ;133 + O_SETVOICEC ;134 + O_VIEWFLCLOOP ;135 + O_FLCSPEED ;136 + O_OPENINVENTORY ;137 + O_KRZYWA ;138 + O_GETKRZYWA ;139 + O_GETMOB ;140 + O_INPUTLINE ;141 + O_SETVOICED ;142 + O_BREAK_POINT ;143 +#endif }; } From 1027f8ac16f2ef01eda2a92bd9d2ad702a076d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Tue, 15 Oct 2013 00:10:29 +0100 Subject: [PATCH 008/374] PRINCE: script extended --- engines/prince/script.cpp | 160 ++++++++++++++++++++++++++++++++------ engines/prince/script.h | 7 +- 2 files changed, 141 insertions(+), 26 deletions(-) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 611b75152f88..dd6400c235e2 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -39,7 +39,7 @@ void Script::debugScript(const char *s, ...) { va_end(va); Common::String str = Common::String::format("@0x%04X: ", _lastInstruction); - str += Common::String::format("op 0x%02X: ", _lastOpcode); + str += Common::String::format("op %02d: ", _lastOpcode); debug("%s %s", str.c_str(), buf); } @@ -51,20 +51,20 @@ void Script::step() { // Get the current opcode _lastOpcode = readScript16bits(); - dstr += Common::String::format("op 0x%02X: ", _lastOpcode); + dstr += Common::String::format("op %02d: ", _lastOpcode); if (_lastOpcode > NUM_OPCODES) error("Trying to execute unknown opcode %s", dstr.c_str()); - //debug("%s", _debugString.c_str()); + debug("%s", dstr.c_str()); // Execute the current opcode OpcodeFunc op = _opcodes[_lastOpcode]; (this->*op)(); } -uint8 Script::getCodeByte(uint16 address) { +uint8 Script::getCodeByte(uint32 address) { if (address >= _codeSize) error("Trying to read a script byte at address 0x%04X, while the " "script is just 0x%04X bytes long", address, _codeSize); @@ -102,16 +102,36 @@ void Script::O_INITROOM() { uint16 roomId = readScript16bits(); debugScript("O_INITROOM %d", roomId); } -void Script::O_SETSAMPLE() {} -void Script::O_FREESAMPLE() {} +void Script::O_SETSAMPLE() { + uint16 sampleId = readScript16bits(); + int32 sampleNameOffset = readScript32bits(); + const char * sampleName = (const char *)_code + _currentInstruction + sampleNameOffset - 4; + debugScript("O_SETSAMPLE %d %s", sampleName, sampleName); +} + +void Script::O_FREESAMPLE() { + uint16 sample = readScript16bits(); + debugScript("O_FREESAMPLE %d", sample); +} + void Script::O_PLAYSAMPLE() {} void Script::O_PUTOBJECT() {} void Script::O_REMOBJECT() {} void Script::O_SHOWANIM() {} void Script::O_CHECKANIMEND() {} -void Script::O_FREEANIM() {} + +void Script::O_FREEANIM() { + uint16 slot = readScript16bits(); + debugScript("O_FREEANIM slot %d", slot); +} + void Script::O_CHECKANIMFRAME() {} -void Script::O_PUTBACKANIM() {} +void Script::O_PUTBACKANIM() { + uint16 roomId = readScript16bits(); + uint16 slot = readScript16bits(); + uint32 animId = readScript32bits(); + debugScript("O_PUTBACKANIM %d %d %d", roomId, slot, animId); +} void Script::O_REMBACKANIM() {} void Script::O_CHECKBACKANIMFRAME() {} void Script::O_FREEALLSAMPLES() {} @@ -134,17 +154,23 @@ void Script::O_RETURN() { if (_stacktop > 0) { _stacktop--; _currentInstruction = _stack[_stacktop]; + debugScript("O_RETURN 0x%04X", _currentInstruction); } else { error("Return: Stack is empty"); } } void Script::O_GO() { - uint32 opPC = readScript32bits(); + int32 opPC = readScript32bits(); debugScript("O_GO 0x%04X", opPC); _currentInstruction += opPC - 4; } void Script::O_BACKANIMUPDATEOFF() {} -void Script::O_BACKANIMUPDATEON() {} + +void Script::O_BACKANIMUPDATEON() { + uint16 slot = readScript16bits(); + debugScript("O_BACKANIMUPDATEON %d", slot); +} + void Script::O_CHANGECURSOR() { uint16 cursorId = readScript16bits(); debugScript("O_CHANGECURSOR %x", cursorId); @@ -154,29 +180,89 @@ void Script::O__SETFLAG() { uint16 flagId = readScript16bits(); uint16 value = readScript16bits(); debugScript("O__SETFLAG 0x%04X %d", flagId, value); + _flags[flagId-0x8000] = value; +} + +void Script::O_COMPARE() { + uint16 flagId = readScript16bits(); + uint16 value = readScript16bits(); + debugScript("O_COMPARE flagId 0x%04X, value %d", flagId, value); + _result = (_flags[flagId-0x8000] == value); +} + +void Script::O_JUMPZ() { + int32 offset = readScript32bits(); + debugScript("O_JUMPZ offset 0x%04X", offset); + if (_result == 0) + { + _currentInstruction += offset - 4; + } +} + +void Script::O_JUMPNZ() { + int32 offset = readScript32bits(); + debugScript("O_JUMPNZ offset 0x%04X", offset); + if (_result) + { + _currentInstruction += offset - 4; + } } -void Script::O_COMPARE() {} -void Script::O_JUMPZ() {} -void Script::O_JUMPNZ() {} + void Script::O_EXIT() {} -void Script::O_ADDFLAG() {} + +void Script::O_ADDFLAG() { + uint16 flagId = readScript16bits(); + uint16 value = readScript16bits(); + + _flags[flagId-0x8000] += value; + if (_flags[flagId-0x8000]) + _result = 1; + else + _result = 0; +} + void Script::O_TALKANIM() {} void Script::O_SUBFLAG() {} -void Script::O_SETSTRING() {} + +void Script::O_SETSTRING() { + int32 offset = readScript32bits(); + + debugScript("O_SETSTRING 0x%04X", offset); +} + void Script::O_ANDFLAG() {} void Script::O_GETMOBDATA() {} void Script::O_ORFLAG() {} void Script::O_SETMOBDATA() {} void Script::O_XORFLAG() {} void Script::O_GETMOBTEXT() {} -void Script::O_MOVEHERO() {} -void Script::O_WALKHERO() {} + +void Script::O_MOVEHERO() { + uint16 heroId = readScript16bits(); + uint16 x = readScript16bits(); + uint16 y = readScript16bits(); + uint16 dir = readScript16bits(); + + debugScript("O_MOVEHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); +} + +void Script::O_WALKHERO() { + uint16 heroId = readScript16bits(); + + debugScript("O_WALKHERO %d", heroId); +} + void Script::O_SETHERO() {} void Script::O_HEROOFF() { uint16 heroId = readScript16bits(); debugScript("O_HEROOFF %d", heroId); } -void Script::O_HEROON() {} + +void Script::O_HEROON() { + uint16 heroId = readScript16bits(); + debugScript("O_HEROON %d", heroId); +} + void Script::O_CLSTEXT() {} void Script::O_CALLTABLE() {} void Script::O_CHANGEMOB() {} @@ -196,7 +282,12 @@ void Script::O_PRELOADSET() {} void Script::O_FREEPRELOAD() {} void Script::O_CHECKINV() {} void Script::O_TALKHERO() {} -void Script::O_WAITTEXT() {} + +void Script::O_WAITTEXT() { + uint16 slot = readScript16bits(); + debugScript("O_WAITTEXT slot %d", slot); +} + void Script::O_SETHEROANIM() {} void Script::O_WAITHEROANIM() {} void Script::O_GETHERODATA() {} @@ -205,12 +296,20 @@ void Script::O_CHANGEFRAMES() {} void Script::O_CHANGEBACKFRAMES() {} void Script::O_GETBACKANIMDATA() {} void Script::O_GETANIMDATA() {} -void Script::O_SETBGCODE() {} +void Script::O_SETBGCODE() { + int32 bgcode = readScript32bits(); + debugScript("O_SETBGCODE %d", bgcode); +} void Script::O_SETBACKFRAME() {} void Script::O_GETRND() {} void Script::O_TALKBACKANIM() {} void Script::O_LOADPATH() {} -void Script::O_GETCHAR() {} + +void Script::O_GETCHAR() { + uint16 flagId = readScript16bits(); + debugScript("O_GETCHAR %d", flagId); +} + void Script::O_SETDFLAG() {} void Script::O_CALLDFLAG() {} void Script::O_PRINTAT() {} @@ -227,7 +326,12 @@ void Script::O_INITDIALOG() {} void Script::O_ENABLEDIALOGOPT() {} void Script::O_DISABLEDIALOGOPT() {} void Script::O_SHOWDIALOGBOX() {} -void Script::O_STOPSAMPLE() {} + +void Script::O_STOPSAMPLE() { + uint16 slot = readScript16bits(); + debugScript("O_STOPSAMPLE slot %d", slot); +} + void Script::O_BACKANIMRANGE() {} void Script::O_CLEARPATH() {} void Script::O_SETPATH() {} @@ -240,7 +344,11 @@ void Script::O_SETFGCODE() {} void Script::O_STOPHERO() {} void Script::O_ANIMUPDATEOFF() {} void Script::O_ANIMUPDATEON() {} -void Script::O_FREECURSOR() {} + +void Script::O_FREECURSOR() { + debugScript("O_FREECURSOR"); +} + void Script::O_ADDINVQUIET() {} void Script::O_RUNHERO() {} void Script::O_SETBACKANIMDATA() {} @@ -256,7 +364,11 @@ void Script::O_DISABLENAK() {} void Script::O_GETMOBNAME() {} void Script::O_SWAPINVENTORY() {} void Script::O_CLEARINVENTORY() {} -void Script::O_SKIPTEXT() {} + +void Script::O_SKIPTEXT() { + debugScript("O_SKIPTEXT"); +} + void Script::O_SETVOICEH() {} void Script::O_SETVOICEA() {} void Script::O_SETVOICEB() {} diff --git a/engines/prince/script.h b/engines/prince/script.h index 93bac064336c..08488d3877b8 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -49,10 +49,12 @@ class Script Common::RandomSource _random; byte *_code; - uint16 _codeSize; + uint32 _codeSize; uint32 _currentInstruction; uint16 _lastOpcode; uint32 _lastInstruction; + byte _result; + int16 _flags[2000]; // Stack uint16 _stack[500]; @@ -60,7 +62,8 @@ class Script uint8 _savedStacktop; // Helper functions - uint8 getCodeByte(uint16 address); + void checkPC(uint32 address); + uint8 getCodeByte(uint32 address); uint8 readScript8bits(); uint16 readScript16bits(); uint32 readScript32bits(); From 3a4068f87be678bd7446c32a1baa8869522ebd71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Tue, 15 Oct 2013 23:21:00 +0100 Subject: [PATCH 009/374] PRINCE: more debugScript added --- engines/prince/script.cpp | 131 +++++++++++++++++++++++++++++++++----- 1 file changed, 116 insertions(+), 15 deletions(-) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index dd6400c235e2..d59b373a2bc9 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -92,16 +92,20 @@ uint32 Script::readScript32bits() { void Script::O_WAITFOREVER() { debugScript("O_WAITFOREVER"); } + void Script::O_BLACKPALETTE() { debugScript("O_BLACKPALETTE"); } + void Script::O_SETUPPALETTE() { debugScript("O_SETUPPALETTE"); } + void Script::O_INITROOM() { uint16 roomId = readScript16bits(); debugScript("O_INITROOM %d", roomId); } + void Script::O_SETSAMPLE() { uint16 sampleId = readScript16bits(); int32 sampleNameOffset = readScript32bits(); @@ -114,34 +118,85 @@ void Script::O_FREESAMPLE() { debugScript("O_FREESAMPLE %d", sample); } -void Script::O_PLAYSAMPLE() {} -void Script::O_PUTOBJECT() {} -void Script::O_REMOBJECT() {} -void Script::O_SHOWANIM() {} -void Script::O_CHECKANIMEND() {} +void Script::O_PLAYSAMPLE() { + uint16 sampleId = readScript16bits(); + uint16 loopType = readScript16bits(); + debugScript("O_PLAYSAMPLE sampleId %d loopType %d", sampleId, loopType); +} + +void Script::O_PUTOBJECT() { + uint16 roomId = readScript16bits(); + uint16 slot = readScript16bits(); + uint16 objectId = readScript16bits(); + debugScript("O_PUTOBJECT roomId %d, slot %d, objectId %d", roomId, slot, objectId); +} + +void Script::O_REMOBJECT() { + uint16 roomId = readScript16bits(); + uint16 objectId = readScript16bits(); + + debugScript("O_REMOBJECT roomId %d objectId %d", roomId, objectId); +} + +void Script::O_SHOWANIM() { + uint16 slot = readScript16bits(); + uint16 animId = readScript16bits(); + + debugScript("O_SHOWANIM slot %d, animId %d", slot, animId); +} + +void Script::O_CHECKANIMEND() { + uint16 slot = readScript16bits(); + uint16 frameId = readScript16bits(); + + debugScript("O_CHECKANIMEND slot %d, frameId %d", slot, frameId); +} void Script::O_FREEANIM() { uint16 slot = readScript16bits(); debugScript("O_FREEANIM slot %d", slot); } -void Script::O_CHECKANIMFRAME() {} +void Script::O_CHECKANIMFRAME() { + uint16 slot = readScript16bits(); + uint16 frameId = readScript16bits(); + + debugScript("O_CHECKANIMFRAME slot %d, frameId %d", slot, frameId); +} + void Script::O_PUTBACKANIM() { uint16 roomId = readScript16bits(); uint16 slot = readScript16bits(); uint32 animId = readScript32bits(); - debugScript("O_PUTBACKANIM %d %d %d", roomId, slot, animId); + debugScript("O_PUTBACKANIM roomId %d, slot %d, animId %d", roomId, slot, animId); } -void Script::O_REMBACKANIM() {} + +void Script::O_REMBACKANIM() { + uint16 roomId = readScript16bits(); + uint16 slot = readScript16bits(); + + debugScript("O_REMBACKANIM roomId %d, slot %d", roomId, slot); +} + void Script::O_CHECKBACKANIMFRAME() {} + void Script::O_FREEALLSAMPLES() {} + void Script::O_SETMUSIC() {} + void Script::O_STOPMUSIC() {} + void Script::O__WAIT() {} + void Script::O_UPDATEOFF() {} + void Script::O_UPDATEON() {} + void Script::O_UPDATE () {} + void Script::O_CLS() {} + + void Script::O__CALL() { int32 address = readScript32bits(); _stack[_stacktop] = _currentInstruction; @@ -219,10 +274,29 @@ void Script::O_ADDFLAG() { _result = 1; else _result = 0; + + debugScript("O_ADDFLAG flagId %d, value %d", flagId, value); +} + +void Script::O_TALKANIM() { + uint16 animSlot = readScript16bits(); + uint16 slot = readScript16bits(); + + debugScript("O_TALKANIM animSlot %d, slot %d", animSlot, slot); } -void Script::O_TALKANIM() {} -void Script::O_SUBFLAG() {} +void Script::O_SUBFLAG() { + uint16 flagId = readScript16bits(); + uint16 value = readScript16bits(); + + _flags[flagId-0x8000] -= value; + if (_flags[flagId-0x8000]) + _result = 1; + else + _result = 0; + + debugScript("O_SUBFLAG flagId %d, value %d", flagId, value); +} void Script::O_SETSTRING() { int32 offset = readScript32bits(); @@ -231,10 +305,15 @@ void Script::O_SETSTRING() { } void Script::O_ANDFLAG() {} + void Script::O_GETMOBDATA() {} + void Script::O_ORFLAG() {} + void Script::O_SETMOBDATA() {} + void Script::O_XORFLAG() {} + void Script::O_GETMOBTEXT() {} void Script::O_MOVEHERO() { @@ -370,18 +449,40 @@ void Script::O_SKIPTEXT() { } void Script::O_SETVOICEH() {} + void Script::O_SETVOICEA() {} + void Script::O_SETVOICEB() {} + void Script::O_SETVOICEC() {} + void Script::O_VIEWFLCLOOP() {} + void Script::O_FLCSPEED() {} -void Script::O_OPENINVENTORY() {} -void Script::O_KRZYWA() {} -void Script::O_GETKRZYWA() {} + +void Script::O_OPENINVENTORY() { + debugScript("O_OPENINVENTORY"); +} + +void Script::O_KRZYWA() { + debugScript("O_KRZYWA"); +} + +void Script::O_GETKRZYWA() { + debugScript("O_GETKRZYWA"); +} + void Script::O_GETMOB() {} -void Script::O_INPUTLINE() {} + +void Script::O_INPUTLINE() { + debugScript("O_INPUTLINE"); +} + void Script::O_SETVOICED() {} -void Script::O_BREAK_POINT() {} + +void Script::O_BREAK_POINT() { + debugScript("O_BREAK_POINT"); +} Script::OpcodeFunc Script::_opcodes[NUM_OPCODES] = { &Script::O_WAITFOREVER, From 263b02eb6156dcbc9e8f6bf3a5301c855cce3af9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Mon, 21 Oct 2013 01:18:27 +0100 Subject: [PATCH 010/374] PRINCE: flic anim decoder works with room 59 (intro) --- engines/prince/graphics.cpp | 25 +++++- engines/prince/graphics.h | 5 +- engines/prince/prince.cpp | 117 +++++++++++++++++----------- engines/prince/prince.h | 12 +++ engines/prince/script.cpp | 31 ++++---- engines/prince/script.h | 149 +----------------------------------- 6 files changed, 131 insertions(+), 208 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 356b35f83211..2b6366b00bee 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -9,11 +9,13 @@ namespace Prince { GraphicsMan::GraphicsMan(PrinceEngine *vm) : _vm(vm), _changed(false) { initGraphics(640, 480, true); + _frontScreen = new Graphics::Surface(); + _frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); } void GraphicsMan::update() { if (_changed) { - _vm->_system->copyRectToScreen((byte*)_roomBackground->getBasePtr(0,0), 640, 0, 0, 640, 480); + _vm->_system->copyRectToScreen((byte*)_frontScreen->getBasePtr(0,0), 640, 0, 0, 640, 480); _vm->_system->updateScreen(); } @@ -27,4 +29,25 @@ void GraphicsMan::change() { _changed = true; } +void GraphicsMan::draw(const Graphics::Surface *s) +{ + for (uint y = 0; y < 480; y++) + memcpy((byte*)_frontScreen->getBasePtr(0, y), (byte*)s->getBasePtr(0, y), 640); +} + +void GraphicsMan::drawTransparent(const Graphics::Surface *s) +{ + for (uint y = 0; y < 480; ++y) + { + for (uint x = 0; x < 640; ++x) + { + byte pixel = *((byte*)s->getBasePtr(x,y)); + if (pixel != 255) + { + *((byte*)_frontScreen->getBasePtr(x, y)) = pixel; + } + } + } +} + } diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index 3599cbc346a3..0f12c734c6b6 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -41,6 +41,10 @@ class GraphicsMan void setPalette(const byte *palette); + void draw(const Graphics::Surface *s); + void drawTransparent(const Graphics::Surface *s); + + Graphics::Surface *_frontScreen; Graphics::Surface *_backScreen; const Graphics::Surface *_roomBackground; @@ -50,7 +54,6 @@ class GraphicsMan bool _changed; byte _palette[3 * 256]; - Graphics::Surface *_frontScreen; }; } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index c82dfd67238a..72d5e55fe865 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -36,7 +36,6 @@ #include "graphics/surface.h" #include "graphics/palette.h" #include "graphics/pixelformat.h" -#include "graphics/decoders/bmp.h" #include "engines/util.h" #include "engines/advancedDetector.h" @@ -49,18 +48,20 @@ #include "prince/graphics.h" #include "prince/script.h" +#include "video/flic_decoder.h" + namespace Prince { PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL) { - _rnd = new Common::RandomSource("prince"); + _rnd = new Common::RandomSource("prince"); } PrinceEngine::~PrinceEngine() { - DebugMan.clearAllDebugChannels(); + DebugMan.clearAllDebugChannels(); - delete _rnd; + delete _rnd; } Common::Error PrinceEngine::run() { @@ -71,8 +72,8 @@ Common::Error PrinceEngine::run() { debug("Adding all path: %s", gameDataDir.getPath().c_str()); - SearchMan.addSubDirectoryMatching(gameDataDir, "all", 0, 2); - SearchMan.addSubDirectoryMatching(gameDataDir, "01", 0, 2); + SearchMan.addSubDirectoryMatching(gameDataDir, "all", 0, 2); + SearchMan.addSubDirectoryMatching(gameDataDir, "59", 0, 2); Common::SeekableReadStream * walizka = SearchMan.createReadStreamForMember("walizka"); @@ -80,27 +81,24 @@ Common::Error PrinceEngine::run() { if (!font1stream) return Common::kPathNotFile; - Font font1 = Font(); - if (font1.load(*font1stream)) { - font1.getCharWidth(103); + if (_font.load(*font1stream)) { + _font.getCharWidth(103); } delete font1stream; Common::SeekableReadStream *room = SearchMan.createReadStreamForMember("room"); - //_frontScreen = new Graphics::Surface(); - //_frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); + //_frontScreen = new Graphics::Surface(); + //_frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); if (room) { - Graphics::BitmapDecoder roomBmp; - roomBmp.loadStream(*room); + _roomBmp.loadStream(*room); //_roomBackground = roomBmp.getSurface(); - _system->getPaletteManager()->setPalette(roomBmp.getPalette(), 0, 256); + _system->getPaletteManager()->setPalette(_roomBmp.getPalette(), 0, 256); //font1.drawString(_frontScreen, "Hello World", 10, 10, 640, 1); // - _graph->_roomBackground = roomBmp.getSurface(); -#if 1 +#if 0 MhwanhDecoder *walizkaBmp = new MhwanhDecoder(); if (walizka) { debug("Loading walizka"); @@ -123,46 +121,77 @@ Common::Error PrinceEngine::run() { mainLoop(); delete room; - delete walizkaBmp; + //delete walizkaBmp; } - return Common::kNoError; + return Common::kNoError; +} + +bool PrinceEngine::PlayNextFrame() +{ + _graph->draw(_roomBmp.getSurface()); + + const Graphics::Surface *s = _flicPlayer.decodeNextFrame(); + if (s) + { + _graph->drawTransparent(s); + _graph->change(); + } + + return true; } void PrinceEngine::mainLoop() { - //uint32 nextFrameTime = 0; - while (!shouldQuit()) { - Common::Event event; - Common::EventManager *eventMan = _system->getEventManager(); - while (eventMan->pollEvent(event)) { - switch (event.type) { - case Common::EVENT_KEYDOWN: - break; - case Common::EVENT_KEYUP: - break; - case Common::EVENT_MOUSEMOVE: - break; - case Common::EVENT_LBUTTONDOWN: - case Common::EVENT_RBUTTONDOWN: - break; - case Common::EVENT_LBUTTONUP: - case Common::EVENT_RBUTTONUP: - break; - case Common::EVENT_QUIT: - break; - default: - break; - } - } + //uint32 nextFrameTime = 0; + uint32 an = 1; + + while (!shouldQuit()) { + Common::Event event; + Common::EventManager *eventMan = _system->getEventManager(); + while (eventMan->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_KEYDOWN: + break; + case Common::EVENT_KEYUP: + break; + case Common::EVENT_MOUSEMOVE: + break; + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_RBUTTONDOWN: + break; + case Common::EVENT_LBUTTONUP: + case Common::EVENT_RBUTTONUP: + break; + case Common::EVENT_QUIT: + break; + default: + break; + } + } if (shouldQuit()) return; - _script->step(); + //_script->step(); + if (_flicPlayer.endOfVideo()) + { + Common::String streamName = Common::String::format("AN%02d", an++); + Common::SeekableReadStream * flicStream = SearchMan.createReadStreamForMember(streamName); + + if (flicStream) + { + if (_flicPlayer.loadStream(flicStream)) + { + debug("%s loaded", streamName.c_str()); + _flicPlayer.start(); + } + } + } + PlayNextFrame(); _graph->update(); - _system->delayMillis(40); + _system->delayMillis(40); } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 966cee982e83..58a446682536 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -30,11 +30,17 @@ #include "common/textconsole.h" #include "common/rect.h" +#include "graphics/decoders/bmp.h" + #include "engines/engine.h" #include "engines/util.h" #include "audio/mixer.h" +#include "video/flic_decoder.h" + +#include "prince/font.h" + namespace Prince { struct PrinceGameDescription; @@ -61,9 +67,15 @@ class PrinceEngine : public Engine { const PrinceGameDescription *_gameDescription; private: + bool PlayNextFrame(); + Common::RandomSource *_rnd; + Video::FlicDecoder _flicPlayer; + Graphics::BitmapDecoder _roomBmp; + GraphicsMan *_graph; Script *_script; + Font _font; void mainLoop(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index d59b373a2bc9..c2f1706ee50b 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -9,7 +9,7 @@ namespace Prince { static const uint16 NUM_OPCODES = 144; Script::Script(PrinceEngine *vm) : - _code(NULL), _stacktop(0), _vm(vm), _random("GroovieScripts") { + _code(NULL), _stacktop(0), _vm(vm), _random("GroovieScripts"), _opcodeNF(false) { } Script::~Script() { @@ -44,24 +44,27 @@ void Script::debugScript(const char *s, ...) { } void Script::step() { - _lastInstruction = _currentInstruction; - // Prepare the base debug string - Common::String dstr = Common::String::format("@0x%04X: ", _currentInstruction); + while (!_opcodeNF) + { + _lastInstruction = _currentInstruction; + // Prepare the base debug string + Common::String dstr = Common::String::format("@0x%04X: ", _currentInstruction); - // Get the current opcode - _lastOpcode = readScript16bits(); + // Get the current opcode + _lastOpcode = readScript16bits(); - dstr += Common::String::format("op %02d: ", _lastOpcode); + dstr += Common::String::format("op %02d: ", _lastOpcode); - if (_lastOpcode > NUM_OPCODES) - error("Trying to execute unknown opcode %s", dstr.c_str()); + if (_lastOpcode > NUM_OPCODES) + error("Trying to execute unknown opcode %s", dstr.c_str()); - debug("%s", dstr.c_str()); + debug("%s", dstr.c_str()); - // Execute the current opcode - OpcodeFunc op = _opcodes[_lastOpcode]; - (this->*op)(); + // Execute the current opcode + OpcodeFunc op = _opcodes[_lastOpcode]; + (this->*op)(); + } } uint8 Script::getCodeByte(uint32 address) { @@ -110,7 +113,7 @@ void Script::O_SETSAMPLE() { uint16 sampleId = readScript16bits(); int32 sampleNameOffset = readScript32bits(); const char * sampleName = (const char *)_code + _currentInstruction + sampleNameOffset - 4; - debugScript("O_SETSAMPLE %d %s", sampleName, sampleName); + debugScript("O_SETSAMPLE %d %s", sampleId, sampleName); } void Script::O_FREESAMPLE() { diff --git a/engines/prince/script.h b/engines/prince/script.h index 08488d3877b8..a68e834c688c 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -55,6 +55,7 @@ class Script uint32 _lastInstruction; byte _result; int16 _flags[2000]; + bool _opcodeNF; // Stack uint16 _stack[500]; @@ -217,154 +218,6 @@ class Script void O_INPUTLINE(); void O_SETVOICED(); void O_BREAK_POINT(); - - -#if 0 - O_WAITFOREVER ;00 - O_BLACKPALETTE ;01 - O_SETUPPALETTE ;02 - O_INITROOM ;03 - O_SETSAMPLE ;04 - O_FREESAMPLE ;05 - O_PLAYSAMPLE ;06 - O_PUTOBJECT ;07 - O_REMOBJECT ;08 - O_SHOWANIM ;09 - O_CHECKANIMEND ;10 - O_FREEANIM ;11 - O_CHECKANIMFRAME ;12 - O_PUTBACKANIM ;13 - O_REMBACKANIM ;14 - O_CHECKBACKANIMFRAME ;15 - O_FREEALLSAMPLES ;16 - O_SETMUSIC ;17 - O_STOPMUSIC ;18 - O__WAIT ;19 - O_UPDATEOFF ;20 - O_UPDATEON ;21 - O_UPDATE ;22 - O_CLS ;23 - O__CALL ;24 - O_RETURN ;25 - O_GO ;26 - O_BACKANIMUPDATEOFF ;27 - O_BACKANIMUPDATEON ;28 - O_CHANGECURSOR ;29 - O_CHANGEANIMTYPE ;30 - O__SETFLAG ;31 - O_COMPARE ;32 - O_JUMPZ ;33 - O_JUMPNZ ;34 - O_EXIT ;35 - O_ADDFLAG ;36 - O_TALKANIM ;37 - O_SUBFLAG ;38 - O_SETSTRING ;39 - O_ANDFLAG ;40 - O_GETMOBDATA ;41 - O_ORFLAG ;42 - O_SETMOBDATA ;43 - O_XORFLAG ;44 - O_GETMOBTEXT ;45 - O_MOVEHERO ;46 - O_WALKHERO ;47 - O_SETHERO ;48 - O_HEROOFF ;49 - O_HEROON ;50 - O_CLSTEXT ;51 - O_CALLTABLE ;52 - O_CHANGEMOB ;53 - O_ADDINV ;54 - O_REMINV ;55 - O_REPINV ;56 - O_OBSOLETE_GETACTION ;57 - O_ADDWALKAREA ;58 - O_REMWALKAREA ;59 - O_RESTOREWALKAREA ;60 - O_WAITFRAME ;61 - O_SETFRAME ;62 - O_RUNACTION ;63 - O_COMPAREHI ;64 - O_COMPARELO ;65 - O_PRELOADSET ;66 - O_FREEPRELOAD ;67 - O_CHECKINV ;68 - O_TALKHERO ;69 - O_WAITTEXT ;70 - O_SETHEROANIM ;71 - O_WAITHEROANIM ;72 - O_GETHERODATA ;73 - O_GETMOUSEBUTTON ;74 - O_CHANGEFRAMES ;75 - O_CHANGEBACKFRAMES ;76 - O_GETBACKANIMDATA ;77 - O_GETANIMDATA ;78 - O_SETBGCODE ;79 - O_SETBACKFRAME ;80 - O_GETRND ;81 - O_TALKBACKANIM ;82 - O_LOADPATH ;83 - O_GETCHAR ;84 - O_SETDFLAG ;85 - O_CALLDFLAG ;86 - O_PRINTAT ;87 - O_ZOOMIN ;88 - O_ZOOMOUT ;89 - O_SETSTRINGOFFSET ;90 - O_GETOBJDATA ;91 - O_SETOBJDATA ;92 - O_SWAPOBJECTS ;93 - O_CHANGEHEROSET ;94 - O_ADDSTRING ;95 - O_SUBSTRING ;96 - O_INITDIALOG ;97 - O_ENABLEDIALOGOPT ;98 - O_DISABLEDIALOGOPT ;99 - O_SHOWDIALOGBOX ;100 - O_STOPSAMPLE ;101 - O_BACKANIMRANGE ;102 - O_CLEARPATH ;103 - O_SETPATH ;104 - O_GETHEROX ;105 - O_GETHEROY ;106 - O_GETHEROD ;107 - O_PUSHSTRING ;108 - O_POPSTRING ;109 - O_SETFGCODE ;110 - O_STOPHERO ;111 - O_ANIMUPDATEOFF ;112 - O_ANIMUPDATEON ;113 - O_FREECURSOR ;114 - O_ADDINVQUIET ;115 - O_RUNHERO ;116 - O_SETBACKANIMDATA ;117 - O_VIEWFLC ;118 - O_CHECKFLCFRAME ;119 - O_CHECKFLCEND ;120 - O_FREEFLC ;121 - O_TALKHEROSTOP ;122 - O_HEROCOLOR ;123 - O_GRABMAPA ;124 - O_ENABLENAK ;125 - O_DISABLENAK ;126 - O_GETMOBNAME ;127 - O_SWAPINVENTORY ;128 - O_CLEARINVENTORY ;129 - O_SKIPTEXT ;130 - O_SETVOICEH ;131 - O_SETVOICEA ;132 - O_SETVOICEB ;133 - O_SETVOICEC ;134 - O_VIEWFLCLOOP ;135 - O_FLCSPEED ;136 - O_OPENINVENTORY ;137 - O_KRZYWA ;138 - O_GETKRZYWA ;139 - O_GETMOB ;140 - O_INPUTLINE ;141 - O_SETVOICED ;142 - O_BREAK_POINT ;143 -#endif }; } From 78434a5f534010825bad0092c30c1b02549220fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Tue, 22 Oct 2013 01:05:24 +0100 Subject: [PATCH 011/374] PRINCE: code cleanup. debugger added --- engines/prince/debugger.cpp | 111 ++++++++++++++++++++++++++ engines/prince/debugger.h | 50 ++++++++++++ engines/prince/graphics.cpp | 2 + engines/prince/mhwanh.h | 1 + engines/prince/module.mk | 1 + engines/prince/prince.cpp | 155 +++++++++++++++++++++++------------- engines/prince/prince.h | 20 ++++- engines/prince/script.cpp | 21 ++++- 8 files changed, 298 insertions(+), 63 deletions(-) create mode 100644 engines/prince/debugger.cpp create mode 100644 engines/prince/debugger.h diff --git a/engines/prince/debugger.cpp b/engines/prince/debugger.cpp new file mode 100644 index 000000000000..56053afb2830 --- /dev/null +++ b/engines/prince/debugger.cpp @@ -0,0 +1,111 @@ +/* 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/debugger.h" +#include "prince/prince.h" + +namespace Prince { + +Debugger::Debugger(PrinceEngine *vm) : GUI::Debugger(), _vm(vm) { + DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); + DCmd_Register("setflag", WRAP_METHOD(Debugger, Cmd_SetFlag)); + DCmd_Register("getflag", WRAP_METHOD(Debugger, Cmd_GetFlag)); + DCmd_Register("clearflag", WRAP_METHOD(Debugger, Cmd_ClearFlag)); + DCmd_Register("viewflc", WRAP_METHOD(Debugger, Cmd_ViewFlc)); +} + +static int strToInt(const char *s) { + if (!*s) + // No string at all + return 0; + else if (toupper(s[strlen(s) - 1]) != 'H') + // Standard decimal string + return atoi(s); + + // Hexadecimal string + uint tmp = 0; + int read = sscanf(s, "%xh", &tmp); + if (read < 1) + error("strToInt failed on string \"%s\"", s); + return (int)tmp; +} + +/* + * This command sets a flag + */ +bool Debugger::Cmd_SetFlag(int argc, const char **argv) { + // Check for a flag to set + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + //g_globals->setFlag(flagNum); + return true; +} + +/* + * This command gets the value of a flag + */ +bool Debugger::Cmd_GetFlag(int argc, const char **argv) { + // Check for an flag to display + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + //DebugPrintf("Value: %d\n", g_globals->getFlag(flagNum)); + return true; +} + +/* + * This command clears a flag + */ +bool Debugger::Cmd_ClearFlag(int argc, const char **argv) { + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + //g_globals->clearFlag(flagNum); + return true; +} + +/* + * This command starts new flc anim + */ +bool Debugger::Cmd_ViewFlc(int argc, const char **argv) { + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + _vm->loadAnim(flagNum); + return true; +} +} diff --git a/engines/prince/debugger.h b/engines/prince/debugger.h new file mode 100644 index 000000000000..d47e439c8b5b --- /dev/null +++ b/engines/prince/debugger.h @@ -0,0 +1,50 @@ +/* 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_DEBUGGER_H +#define PRINCE_DEBUGGER_H + +#include "common/scummsys.h" +#include "gui/debugger.h" + +namespace Prince { + +class PrinceEngine; + +class Debugger : public GUI::Debugger { +public: + Debugger(PrinceEngine *vm); + virtual ~Debugger() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ + +private: + bool Cmd_SetFlag(int argc, const char **argv); + bool Cmd_GetFlag(int argc, const char **argv); + bool Cmd_ClearFlag(int argc, const char **argv); + bool Cmd_ViewFlc(int argc, const char **argv); + + PrinceEngine *_vm; +}; + + +} + +#endif diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 2b6366b00bee..eae94748f61a 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -33,6 +33,7 @@ void GraphicsMan::draw(const Graphics::Surface *s) { for (uint y = 0; y < 480; y++) memcpy((byte*)_frontScreen->getBasePtr(0, y), (byte*)s->getBasePtr(0, y), 640); + change(); } void GraphicsMan::drawTransparent(const Graphics::Surface *s) @@ -48,6 +49,7 @@ void GraphicsMan::drawTransparent(const Graphics::Surface *s) } } } + change(); } } diff --git a/engines/prince/mhwanh.h b/engines/prince/mhwanh.h index 44f957372e3c..21822759e873 100644 --- a/engines/prince/mhwanh.h +++ b/engines/prince/mhwanh.h @@ -24,6 +24,7 @@ #define PRINCE_MHWANH_H #include "graphics/decoders/image_decoder.h" +#include "graphics/surface.h" namespace Prince { diff --git a/engines/prince/module.mk b/engines/prince/module.mk index 853592b50365..a177e670ed41 100644 --- a/engines/prince/module.mk +++ b/engines/prince/module.mk @@ -1,6 +1,7 @@ MODULE := engines/prince MODULE_OBJS = \ + debugger.o \ script.o \ graphics.o \ mhwanh.o \ diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 72d5e55fe865..4ad1863ba512 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -44,17 +44,19 @@ #include "prince/prince.h" #include "prince/font.h" -#include "prince/mhwanh.h" #include "prince/graphics.h" #include "prince/script.h" +#include "prince/debugger.h" #include "video/flic_decoder.h" namespace Prince { PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : - Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL) { + Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL), + _locationNr(0), _debugger(NULL) { _rnd = new Common::RandomSource("prince"); + _debugger = new Debugger(this); } @@ -62,6 +64,12 @@ PrinceEngine::~PrinceEngine() { DebugMan.clearAllDebugChannels(); delete _rnd; + delete _debugger; +} + +GUI::Debugger *PrinceEngine::getDebugger() +{ + return _debugger; } Common::Error PrinceEngine::run() { @@ -73,9 +81,6 @@ Common::Error PrinceEngine::run() { debug("Adding all path: %s", gameDataDir.getPath().c_str()); SearchMan.addSubDirectoryMatching(gameDataDir, "all", 0, 2); - SearchMan.addSubDirectoryMatching(gameDataDir, "59", 0, 2); - - Common::SeekableReadStream * walizka = SearchMan.createReadStreamForMember("walizka"); Common::SeekableReadStream *font1stream = SearchMan.createReadStreamForMember("font1.raw"); if (!font1stream) @@ -86,51 +91,65 @@ Common::Error PrinceEngine::run() { } delete font1stream; - Common::SeekableReadStream *room = SearchMan.createReadStreamForMember("room"); - - //_frontScreen = new Graphics::Surface(); - //_frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); - - if (room) { - _roomBmp.loadStream(*room); - //_roomBackground = roomBmp.getSurface(); - _system->getPaletteManager()->setPalette(_roomBmp.getPalette(), 0, 256); + Common::SeekableReadStream * walizka = SearchMan.createReadStreamForMember("walizka"); + if (!walizka) + return Common::kPathDoesNotExist; - //font1.drawString(_frontScreen, "Hello World", 10, 10, 640, 1); - // -#if 0 - MhwanhDecoder *walizkaBmp = new MhwanhDecoder(); - if (walizka) { - debug("Loading walizka"); - if (walizkaBmp->loadStream(*walizka)) { - _graph->_roomBackground = walizkaBmp->getSurface(); - _graph->setPalette(walizkaBmp->getPalette()); - } - } -#endif - _graph->change(); + debug("Loading walizka"); + if (!_walizkaBmp.loadStream(*walizka)) { + return Common::kPathDoesNotExist; + } - Common::SeekableReadStream * skryptStream = SearchMan.createReadStreamForMember("skrypt.dat"); - if (!skryptStream) - return Common::kPathNotFile; + Common::SeekableReadStream * skryptStream = SearchMan.createReadStreamForMember("skrypt.dat"); + if (!skryptStream) + return Common::kPathNotFile; - _script = new Script(this); - _script->loadFromStream(*skryptStream); + debug("Loading skrypt"); + _script = new Script(this); + _script->loadFromStream(*skryptStream); - delete skryptStream; + delete skryptStream; - mainLoop(); - delete room; - //delete walizkaBmp; - } + mainLoop(); return Common::kNoError; } -bool PrinceEngine::PlayNextFrame() +bool PrinceEngine::loadLocation(uint16 locationNr) { - _graph->draw(_roomBmp.getSurface()); + debug("PrinceEngine::loadLocation %d", locationNr); + const Common::FSNode gameDataDir(ConfMan.get("path")); + SearchMan.remove(Common::String::format("%02d", _locationNr)); + _locationNr = locationNr; + + const Common::String locationNrStr = Common::String::format("%02d", _locationNr); + debug("loadLocation %s", locationNrStr.c_str()); + SearchMan.addSubDirectoryMatching(gameDataDir, locationNrStr, 0, 2); + + // load location background + Common::SeekableReadStream *room = SearchMan.createReadStreamForMember("room"); + if (!room) + { + error("Can't load room bitmap"); + return false; + } + + if(_roomBmp.loadStream(*room)) + { + debug("Room bitmap loaded"); + _system->getPaletteManager()->setPalette(_roomBmp.getPalette(), 0, 256); + } + + delete room; + + return true; +} + +bool PrinceEngine::playNextFrame() +{ + if (_flicPlayer.endOfVideo()) + _flicPlayer.rewind(); const Graphics::Surface *s = _flicPlayer.decodeNextFrame(); if (s) { @@ -141,9 +160,40 @@ bool PrinceEngine::PlayNextFrame() return true; } +bool PrinceEngine::loadAnim(uint16 animNr) +{ + 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()); + } + + debug("%s loaded", streamName.c_str()); + _flicPlayer.start(); + return true; +} + +void PrinceEngine::keyHandler(Common::Event event) { + uint16 nChar = event.kbd.keycode; + if (event.kbd.hasFlags(Common::KBD_CTRL)) { + switch (nChar) { + case Common::KEYCODE_d: + getDebugger()->attach(); + getDebugger()->onFrame(); + break; + } + } +} + void PrinceEngine::mainLoop() { - //uint32 nextFrameTime = 0; - uint32 an = 1; while (!shouldQuit()) { Common::Event event; @@ -151,6 +201,7 @@ void PrinceEngine::mainLoop() { while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_KEYDOWN: + keyHandler(event); break; case Common::EVENT_KEYUP: break; @@ -172,23 +223,13 @@ void PrinceEngine::mainLoop() { if (shouldQuit()) return; - //_script->step(); - if (_flicPlayer.endOfVideo()) - { - Common::String streamName = Common::String::format("AN%02d", an++); - Common::SeekableReadStream * flicStream = SearchMan.createReadStreamForMember(streamName); - - if (flicStream) - { - if (_flicPlayer.loadStream(flicStream)) - { - debug("%s loaded", streamName.c_str()); - _flicPlayer.start(); - } - } - } + _script->step(); + + if (_roomBmp.getSurface()) + _graph->draw(_roomBmp.getSurface()); + + playNextFrame(); - PlayNextFrame(); _graph->update(); _system->delayMillis(40); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 58a446682536..efaf643cb7f5 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -29,9 +29,12 @@ #include "common/debug-channels.h" #include "common/textconsole.h" #include "common/rect.h" +#include "common/events.h" #include "graphics/decoders/bmp.h" +#include "gui/debugger.h" + #include "engines/engine.h" #include "engines/util.h" @@ -40,6 +43,7 @@ #include "video/flic_decoder.h" #include "prince/font.h" +#include "prince/mhwanh.h" namespace Prince { @@ -48,6 +52,7 @@ struct PrinceGameDescription; class PrinceEngine; class GraphicsMan; class Script; +class Debugger; class PrinceEngine : public Engine { protected: @@ -65,14 +70,23 @@ class PrinceEngine : public Engine { Common::Language getLanguage() const; const PrinceGameDescription *_gameDescription; - + Video::FlicDecoder _flicPlayer; + + bool loadLocation(uint16 locationNr); + bool loadAnim(uint16 animNr); + + virtual GUI::Debugger *getDebugger(); + private: - bool PlayNextFrame(); + bool playNextFrame(); + void keyHandler(Common::Event event); Common::RandomSource *_rnd; - Video::FlicDecoder _flicPlayer; Graphics::BitmapDecoder _roomBmp; + uint16 _locationNr; + MhwanhDecoder _walizkaBmp; + Debugger *_debugger; GraphicsMan *_graph; Script *_script; Font _font; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index c2f1706ee50b..239b26b35590 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1,4 +1,5 @@ #include "prince/script.h" +#include "prince/prince.h" #include "common/debug.h" #include "common/debug-channels.h" @@ -44,7 +45,7 @@ void Script::debugScript(const char *s, ...) { } void Script::step() { - while (!_opcodeNF) + //while (!_opcodeNF) { _lastInstruction = _currentInstruction; // Prepare the base debug string @@ -94,6 +95,7 @@ uint32 Script::readScript32bits() { void Script::O_WAITFOREVER() { debugScript("O_WAITFOREVER"); + _currentInstruction -= 2; } void Script::O_BLACKPALETTE() { @@ -107,6 +109,7 @@ void Script::O_SETUPPALETTE() { void Script::O_INITROOM() { uint16 roomId = readScript16bits(); debugScript("O_INITROOM %d", roomId); + _vm->loadLocation(roomId); } void Script::O_SETSAMPLE() { @@ -355,7 +358,12 @@ void Script::O_OBSOLETE_GETACTION() {} void Script::O_ADDWALKAREA() {} void Script::O_REMWALKAREA() {} void Script::O_RESTOREWALKAREA() {} -void Script::O_WAITFRAME() {} + +void Script::O_WAITFRAME() { + debugScript("O_WAITFRAME"); + _opcodeNF = true; +} + void Script::O_SETFRAME() {} void Script::O_RUNACTION() {} void Script::O_COMPAREHI() {} @@ -434,9 +442,16 @@ void Script::O_FREECURSOR() { void Script::O_ADDINVQUIET() {} void Script::O_RUNHERO() {} void Script::O_SETBACKANIMDATA() {} -void Script::O_VIEWFLC() {} + +void Script::O_VIEWFLC() { + uint16 animNr = readScript16bits(); + debugScript("O_VIEWFLC animNr %d", animNr); +} + void Script::O_CHECKFLCFRAME() {} + void Script::O_CHECKFLCEND() {} + void Script::O_FREEFLC() {} void Script::O_TALKHEROSTOP() {} void Script::O_HEROCOLOR() {} From 677c82763c8d175d965837743c5ad8819afc6b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Tue, 22 Oct 2013 01:13:52 +0100 Subject: [PATCH 012/374] PRINCE: logo shown at startup --- engines/prince/prince.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 4ad1863ba512..a6bf076c63e8 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -110,6 +110,18 @@ Common::Error PrinceEngine::run() { delete skryptStream; + Common::SeekableReadStream *logoStrema = SearchMan.createReadStreamForMember("logo.raw"); + if (logoStrema) + { + MhwanhDecoder logo; + logo.loadStream(*logoStrema); + _graph->setPalette(logo.getPalette()); + _graph->draw(logo.getSurface()); + _graph->update(); + _system->delayMillis(700); + } + + mainLoop(); return Common::kNoError; From accb9e10e8ee0c607c9fd2ec048af34b5058336f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Thu, 24 Oct 2013 01:01:55 +0100 Subject: [PATCH 013/374] PRINCE: more scrip opcodes added --- engines/prince/prince.cpp | 4 +- engines/prince/script.cpp | 230 ++++++++++++++++++++++++++++++++------ engines/prince/script.h | 2 - 3 files changed, 196 insertions(+), 40 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index a6bf076c63e8..aec84684a7f5 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -120,7 +120,7 @@ Common::Error PrinceEngine::run() { _graph->update(); _system->delayMillis(700); } - + delete logoStrema; mainLoop(); @@ -160,8 +160,6 @@ bool PrinceEngine::loadLocation(uint16 locationNr) bool PrinceEngine::playNextFrame() { - if (_flicPlayer.endOfVideo()) - _flicPlayer.rewind(); const Graphics::Surface *s = _flicPlayer.decodeNextFrame(); if (s) { diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 239b26b35590..66e0c598f96e 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -10,7 +10,7 @@ namespace Prince { static const uint16 NUM_OPCODES = 144; Script::Script(PrinceEngine *vm) : - _code(NULL), _stacktop(0), _vm(vm), _random("GroovieScripts"), _opcodeNF(false) { + _code(NULL), _stacktop(0), _vm(vm), _opcodeNF(false) { } Script::~Script() { @@ -422,61 +422,213 @@ void Script::O_STOPSAMPLE() { debugScript("O_STOPSAMPLE slot %d", slot); } -void Script::O_BACKANIMRANGE() {} -void Script::O_CLEARPATH() {} -void Script::O_SETPATH() {} -void Script::O_GETHEROX() {} -void Script::O_GETHEROY() {} -void Script::O_GETHEROD() {} -void Script::O_PUSHSTRING() {} -void Script::O_POPSTRING() {} -void Script::O_SETFGCODE() {} -void Script::O_STOPHERO() {} -void Script::O_ANIMUPDATEOFF() {} -void Script::O_ANIMUPDATEON() {} +void Script::O_BACKANIMRANGE() { + uint16 slotId = readScript16bits(); + uint16 animId = readScript16bits(); + uint16 low = readScript16bits(); + uint16 high = readScript16bits(); + + debugScript("O_BACKANIMRANGE slotId %d, animId %d, low %d, high %d", slotId, animId, low, high); +} + +void Script::O_CLEARPATH() { + debugScript("O_CLEARPATH"); +} + +void Script::O_SETPATH() { + debugScript("O_SETPATH"); +} + +void Script::O_GETHEROX() { + uint16 heroId = readScript16bits(); + uint16 flagId = readScript16bits(); + + debugScript("O_GETHEROX heroId %d, flagId %d", heroId, flagId); +} + +void Script::O_GETHEROY() { + uint16 heroId = readScript16bits(); + uint16 flagId = readScript16bits(); + + debugScript("O_GETHEROY heroId %d, flagId %d", heroId, flagId); +} + +void Script::O_GETHEROD() { + uint16 heroId = readScript16bits(); + uint16 flagId = readScript16bits(); + + debugScript("O_GETHEROD heroId %d, flagId %d", heroId, flagId); +} + +void Script::O_PUSHSTRING() { + debugScript("O_PUSHSTRING"); +} + +void Script::O_POPSTRING() { + debugScript("O_POPSTRING"); +} + +void Script::O_SETFGCODE() { + int32 offset = readScript32bits(); + + debugScript("O_SETFGCODE offset %04X", offset); +} + +void Script::O_STOPHERO() { + uint16 heroId = readScript16bits(); + + debugScript("O_STOPHERO heroId %d", heroId); +} + +void Script::O_ANIMUPDATEOFF() { + uint16 slotId = readScript16bits(); + debugScript("O_ANIMUPDATEOFF slotId %d", slotId); +} + +void Script::O_ANIMUPDATEON() { + uint16 slotId = readScript16bits(); + debugScript("O_ANIMUPDATEON slotId %d", slotId); +} void Script::O_FREECURSOR() { debugScript("O_FREECURSOR"); } -void Script::O_ADDINVQUIET() {} -void Script::O_RUNHERO() {} -void Script::O_SETBACKANIMDATA() {} +void Script::O_ADDINVQUIET() { + uint16 heroId = readScript16bits(); + uint16 itemId = readScript16bits(); + + debugScript("O_ADDINVQUIET heorId %d, itemId %d", heroId, itemId); +} + +void Script::O_RUNHERO() { + uint16 heroId = readScript16bits(); + uint16 x = readScript16bits(); + uint16 y = readScript16bits(); + uint16 dir = readScript16bits(); + + debugScript("O_RUNHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); +} + +void Script::O_SETBACKANIMDATA() { + uint16 animId = readScript16bits(); + uint16 animOffset = readScript16bits(); + uint16 wart = readScript16bits(); + + debugScript("O_SETBACKANIMDATA animId %d, animOffset %d, wart %d", animId, animOffset, wart); +} void Script::O_VIEWFLC() { uint16 animNr = readScript16bits(); debugScript("O_VIEWFLC animNr %d", animNr); } -void Script::O_CHECKFLCFRAME() {} +void Script::O_CHECKFLCFRAME() { + uint16 frameNr = readScript16bits(); + + debugScript("O_CHECKFLCFRAME frame number %d", frameNr); + + const Video::FlicDecoder &flicPlayer = _vm->_flicPlayer; + + if (flicPlayer.getCurFrame() != frameNr) + { + // Move instruction pointer before current instruciton + // must do this check once again till it's false + _currentInstruction -= 2; + } +} + +void Script::O_CHECKFLCEND() { + + debugScript("O_CHECKFLCEND"); + + const Video::FlicDecoder &flicPlayer = _vm->_flicPlayer; + + if (flicPlayer.getFrameCount() - flicPlayer.getCurFrame() <= 1) + { + // Move instruction pointer before current instruciton + // must do this check once again till it's false + _currentInstruction -= 2; + } +} + +void Script::O_FREEFLC() { + debugScript("O_FREEFLC"); +} -void Script::O_CHECKFLCEND() {} +void Script::O_TALKHEROSTOP() { + uint16 heroId = readScript16bits(); + debugScript("O_TALKHEROSTOP %d", heroId); +} -void Script::O_FREEFLC() {} -void Script::O_TALKHEROSTOP() {} -void Script::O_HEROCOLOR() {} -void Script::O_GRABMAPA() {} -void Script::O_ENABLENAK() {} -void Script::O_DISABLENAK() {} -void Script::O_GETMOBNAME() {} -void Script::O_SWAPINVENTORY() {} -void Script::O_CLEARINVENTORY() {} +void Script::O_HEROCOLOR() { + uint16 heroId = readScript16bits(); + uint16 kolorr = readScript16bits(); + debugScript("O_HEROCOLOR heroId %d, kolorr %d", heroId, kolorr); +} + +void Script::O_GRABMAPA() { + debugScript("O_GRABMAPA"); +} + +void Script::O_ENABLENAK() { + uint16 nakId = readScript16bits(); + debugScript("O_ENABLENAK nakId %d", nakId); +} + +void Script::O_DISABLENAK() { + uint16 nakId = readScript16bits(); + debugScript("O_DISABLENAK nakId %d", nakId); +} + +void Script::O_GETMOBNAME() { + uint16 war = readScript16bits(); + debugScript("O_GETMOBNAME war %d", war); +} + +void Script::O_SWAPINVENTORY() { + uint16 heroId = readScript16bits(); + debugScript("O_SWAPINVENTORY heroId %d", heroId); +} + +void Script::O_CLEARINVENTORY() { + uint16 heroId = readScript16bits(); + debugScript("O_CLEARINVENTORY heroId %d", heroId); +} void Script::O_SKIPTEXT() { debugScript("O_SKIPTEXT"); } -void Script::O_SETVOICEH() {} +void Script::O_SETVOICEH() { + uint16 txn = readScript16bits(); + debugScript("O_SETVOICEH txn %d", txn); +} -void Script::O_SETVOICEA() {} +void Script::O_SETVOICEA() { + uint16 txn = readScript16bits(); + debugScript("O_SETVOICEA txn %d", txn); +} -void Script::O_SETVOICEB() {} +void Script::O_SETVOICEB() { + uint16 txn = readScript16bits(); + debugScript("O_SETVOICEB txn %d", txn); +} -void Script::O_SETVOICEC() {} +void Script::O_SETVOICEC() { + uint16 txn = readScript16bits(); + debugScript("O_SETVOICEC txn %d", txn); +} -void Script::O_VIEWFLCLOOP() {} +void Script::O_VIEWFLCLOOP() { + uint16 animId = readScript16bits(); + debugScript("O_VIEWFLCLOOP animId %d", animId); +} -void Script::O_FLCSPEED() {} +void Script::O_FLCSPEED() { + uint16 speed = readScript16bits(); + debugScript("O_FLCSPEED speed %d", speed); +} void Script::O_OPENINVENTORY() { debugScript("O_OPENINVENTORY"); @@ -490,13 +642,21 @@ void Script::O_GETKRZYWA() { debugScript("O_GETKRZYWA"); } -void Script::O_GETMOB() {} +void Script::O_GETMOB() { + uint16 flagId = readScript16bits(); + uint16 mx = readScript16bits(); + uint16 my = readScript16bits(); + debugScript("O_GETMOB flagId %d, mx %d, my %d", flagId, mx, my); +} void Script::O_INPUTLINE() { debugScript("O_INPUTLINE"); } -void Script::O_SETVOICED() {} +void Script::O_SETVOICED() { + uint16 txn = readScript16bits(); + debugScript("O_SETVOICED txn %d", txn); +} void Script::O_BREAK_POINT() { debugScript("O_BREAK_POINT"); diff --git a/engines/prince/script.h b/engines/prince/script.h index a68e834c688c..982e7aae61f5 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -46,8 +46,6 @@ class Script private: PrinceEngine *_vm; - Common::RandomSource _random; - byte *_code; uint32 _codeSize; uint32 _currentInstruction; From fdf1fc361bf0283785d21827f5cf27d36988e766 Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Tue, 22 Oct 2013 00:22:19 +0300 Subject: [PATCH 014/374] FULLPIPE: Implement MovGraph2::getShortSide() --- engines/fullpipe/motion.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp index a6d32cfb482d..94635a3b9130 100644 --- a/engines/fullpipe/motion.cpp +++ b/engines/fullpipe/motion.cpp @@ -924,9 +924,17 @@ MovGraphNode *MovGraph2::findNode(int x, int y, int fuzzyMatch) { } int MovGraph2::getShortSide(MovGraphLink *lnk, int x, int y) { - warning("STUB: MovGraph2::getShortSide()"); + bool cond; - return 0; + if (lnk) + cond = abs(lnk->_movGraphNode2->_x - lnk->_movGraphNode1->_x) > abs(lnk->_movGraphNode2->_y - lnk->_movGraphNode1->_y); + else + cond = abs(x) > abs(y); + + if (cond) + return x <= 0; + else + return ((y > 0) + 2); } int MovGraph2::findLink(Common::Array *linkList, int idx, Common::Rect *rect, Common::Point *point) { From 26631f18a981c83b78e0379a85754e819db49388 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 21 Oct 2013 22:49:10 -0400 Subject: [PATCH 015/374] TSAGE: Fix for R2R conversations playing when playing voice without subtitles --- engines/tsage/ringworld2/ringworld2_speakers.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/engines/tsage/ringworld2/ringworld2_speakers.cpp b/engines/tsage/ringworld2/ringworld2_speakers.cpp index 4be3212e770e..8b6ce4a1f31b 100644 --- a/engines/tsage/ringworld2/ringworld2_speakers.cpp +++ b/engines/tsage/ringworld2/ringworld2_speakers.cpp @@ -76,7 +76,7 @@ void VisualSpeaker::signal() { _fieldF8 = 1; } - if ((R2_GLOBALS._speechSubtitles & SPEECH_TEXT) || _soundId) + if ((R2_GLOBALS._speechSubtitles & SPEECH_TEXT) || !_soundId) _sceneText.show(); if ((R2_GLOBALS._speechSubtitles & SPEECH_VOICE) && _soundId) { @@ -132,6 +132,7 @@ void VisualSpeaker::dispatch() { _object1.setFrame(1); if (!(R2_GLOBALS._speechSubtitles & SPEECH_TEXT)) { + // Don't bother waiting for a mouse click to start the next speech segment _action->setDelay(1); } } @@ -244,8 +245,13 @@ void VisualSpeaker::setText(const Common::String &msg) { _sceneText.hide(); } else { if ((R2_GLOBALS._speechSubtitles & SPEECH_VOICE) && _soundId) { - if (!R2_GLOBALS._playStream.play(_soundId, NULL)) + if (!R2_GLOBALS._playStream.play(_soundId, NULL)) { + // Couldn't play voice, so fall back on showing text _sceneText.show(); + } else { + _numFrames = 2; + _soundId = 0; + } } } } From bd26d01a26c8bf07639ad6d93e8aacecf4a80fc5 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Tue, 22 Oct 2013 06:00:00 +0200 Subject: [PATCH 016/374] Avalanche: Replace some British English by American English pointed by clone2727 --- engines/avalanche/avalanche.cpp | 20 ++++++++++---------- engines/avalanche/avalanche.h | 2 +- engines/avalanche/avalot.cpp | 6 +++--- engines/avalanche/dialogs.cpp | 4 ++-- engines/avalanche/parser.cpp | 4 ++-- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/engines/avalanche/avalanche.cpp b/engines/avalanche/avalanche.cpp index 4f3868768a12..ef56459c3a00 100644 --- a/engines/avalanche/avalanche.cpp +++ b/engines/avalanche/avalanche.cpp @@ -166,17 +166,17 @@ void AvalancheEngine::synchronize(Common::Serializer &sz) { sz.syncAsByte(_arrowInTheDoor); if (sz.isSaving()) { - uint16 like2drinkSize = _favouriteDrink.size(); + uint16 like2drinkSize = _favoriteDrink.size(); sz.syncAsUint16LE(like2drinkSize); for (uint16 i = 0; i < like2drinkSize; i++) { - char actChr = _favouriteDrink[i]; + char actChr = _favoriteDrink[i]; sz.syncAsByte(actChr); } - uint16 favourite_songSize = _favouriteSong.size(); + uint16 favourite_songSize = _favoriteSong.size(); sz.syncAsUint16LE(favourite_songSize); for (uint16 i = 0; i < favourite_songSize; i++) { - char actChr = _favouriteSong[i]; + char actChr = _favoriteSong[i]; sz.syncAsByte(actChr); } @@ -194,23 +194,23 @@ void AvalancheEngine::synchronize(Common::Serializer &sz) { sz.syncAsByte(actChr); } } else { - if (!_favouriteDrink.empty()) - _favouriteDrink.clear(); + if (!_favoriteDrink.empty()) + _favoriteDrink.clear(); uint16 like2drinkSize = 0; char actChr = ' '; sz.syncAsUint16LE(like2drinkSize); for (uint16 i = 0; i < like2drinkSize; i++) { sz.syncAsByte(actChr); - _favouriteDrink += actChr; + _favoriteDrink += actChr; } - if (!_favouriteSong.empty()) - _favouriteSong.clear(); + if (!_favoriteSong.empty()) + _favoriteSong.clear(); uint16 favourite_songSize = 0; sz.syncAsUint16LE(favourite_songSize); for (uint16 i = 0; i < favourite_songSize; i++) { sz.syncAsByte(actChr); - _favouriteSong += actChr; + _favoriteSong += actChr; } if (!_worstPlaceOnEarth.empty()) diff --git a/engines/avalanche/avalanche.h b/engines/avalanche/avalanche.h index cc9a34d82b39..cff0970d2257 100644 --- a/engines/avalanche/avalanche.h +++ b/engines/avalanche/avalanche.h @@ -207,7 +207,7 @@ class AvalancheEngine : public Engine { bool _standingOnDais; // In room 71, inside Cardiff Castle. bool _takenPen; // Have you taken the pen (in Cardiff?) bool _arrowInTheDoor; // Did the arrow hit the wall? - Common::String _favouriteDrink, _favouriteSong, _worstPlaceOnEarth, _spareEvening; // Personalisation str's + Common::String _favoriteDrink, _favoriteSong, _worstPlaceOnEarth, _spareEvening; // Personalisation str's uint32 _totalTime; // Your total time playing this game, in ticks. byte _jumpStatus; // Fixes how high you're jumping. bool _mushroomGrowing; // Is the mushroom growing in 42? diff --git a/engines/avalanche/avalot.cpp b/engines/avalanche/avalot.cpp index 8ef41a2c9386..a7108841d4cd 100644 --- a/engines/avalanche/avalot.cpp +++ b/engines/avalanche/avalot.cpp @@ -1448,8 +1448,8 @@ void AvalancheEngine::resetVariables() { _standingOnDais = false; _takenPen = false; _arrowInTheDoor = false; - _favouriteDrink = ""; - _favouriteSong = ""; + _favoriteDrink = ""; + _favoriteSong = ""; _worstPlaceOnEarth = ""; _spareEvening = ""; _totalTime = 0; @@ -1502,7 +1502,7 @@ void AvalancheEngine::newGame() { _dialogs->setBubbleStateNatural(); _spareEvening = "answer a questionnaire"; - _favouriteDrink = "beer"; + _favoriteDrink = "beer"; _money = 30; // 2/6 _animation->setDirection(kDirStopped); _parser->_wearing = kObjectClothes; diff --git a/engines/avalanche/dialogs.cpp b/engines/avalanche/dialogs.cpp index e5acd9cae25c..e121141a2a9d 100644 --- a/engines/avalanche/dialogs.cpp +++ b/engines/avalanche/dialogs.cpp @@ -729,10 +729,10 @@ void Dialogs::displayText(Common::String text) { } break; case 3: - displayText(_vm->_favouriteDrink + kControlToBuffer); + displayText(_vm->_favoriteDrink + kControlToBuffer); break; case 4: - displayText(_vm->_favouriteSong + kControlToBuffer); + displayText(_vm->_favoriteSong + kControlToBuffer); break; case 5: displayText(_vm->_worstPlaceOnEarth + kControlToBuffer); diff --git a/engines/avalanche/parser.cpp b/engines/avalanche/parser.cpp index fc176c78b010..4cc184bfd918 100644 --- a/engines/avalanche/parser.cpp +++ b/engines/avalanche/parser.cpp @@ -692,13 +692,13 @@ void Parser::storeInterrogation(byte interrogation) { case 1: _inputText.toLowercase(); _vm->_dialogs->sayIt(_inputText); - _vm->_favouriteDrink = _inputText; + _vm->_favoriteDrink = _inputText; _vm->_cardiffQuestionNum = 2; break; case 2: properNouns(); _vm->_dialogs->sayIt(_inputText); - _vm->_favouriteSong = _inputText; + _vm->_favoriteSong = _inputText; _vm->_cardiffQuestionNum = 3; break; case 3: From 00d2552eb078deff5839fec25bd48f5d2c4f3242 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Tue, 22 Oct 2013 10:49:13 +0200 Subject: [PATCH 017/374] AVALANCHE: last modification wasn't in previous commit, fixed. --- engines/avalanche/avalanche.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/engines/avalanche/avalanche.cpp b/engines/avalanche/avalanche.cpp index ef56459c3a00..43e99945dcf2 100644 --- a/engines/avalanche/avalanche.cpp +++ b/engines/avalanche/avalanche.cpp @@ -173,9 +173,9 @@ void AvalancheEngine::synchronize(Common::Serializer &sz) { sz.syncAsByte(actChr); } - uint16 favourite_songSize = _favoriteSong.size(); - sz.syncAsUint16LE(favourite_songSize); - for (uint16 i = 0; i < favourite_songSize; i++) { + uint16 favoriteSongSize = _favoriteSong.size(); + sz.syncAsUint16LE(favoriteSongSize); + for (uint16 i = 0; i < favoriteSongSize; i++) { char actChr = _favoriteSong[i]; sz.syncAsByte(actChr); } From e053dcb1cf82c501599aefc1b3fed3473a428326 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Tue, 22 Oct 2013 10:55:08 +0200 Subject: [PATCH 018/374] AVALANCHE: Fix CID 1109698 - Uninitialized scalar field in Sequence --- engines/avalanche/sequence.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/engines/avalanche/sequence.cpp b/engines/avalanche/sequence.cpp index 10fa7f0a0050..3a60c4ec1d84 100644 --- a/engines/avalanche/sequence.cpp +++ b/engines/avalanche/sequence.cpp @@ -34,6 +34,8 @@ namespace Avalanche { Sequence::Sequence(AvalancheEngine *vm) { _vm = vm; + + resetVariables(); } void Sequence::resetVariables() { From 7d8fef72ab36e1055511244d470c3fc68ed7067e Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Wed, 23 Oct 2013 00:36:43 +0300 Subject: [PATCH 019/374] FULLPIPE: Implement MovGraph::calcOffset() --- engines/fullpipe/motion.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp index 94635a3b9130..ebf896cf1e45 100644 --- a/engines/fullpipe/motion.cpp +++ b/engines/fullpipe/motion.cpp @@ -1132,9 +1132,22 @@ double MovGraph2::findMinPath(LinkInfo *linkInfoSource, LinkInfo *linkInfoDest, } MovGraphNode *MovGraph::calcOffset(int ox, int oy) { - warning("STUB: MovGraph::calcOffset()"); + MovGraphNode *res = 0; + double mindist = 1.0e10; - return 0; + for (ObList::iterator i = _nodes.begin(); i != _nodes.end(); ++i) { + assert(((CObject *)*i)->_objtype == kObjTypeMovGraphNode); + + MovGraphNode *node = (MovGraphNode *)*i; + + double dist = sqrt((double)((node->_x - oy) * (node->_x - oy) + (node->_x - ox) * (node->_x - ox))); + if (dist < mindist) { + mindist = dist; + res = node; + } + } + + return res; } void MGM::clear() { From aebe01f7ecf2faf884a027f5dabf7989bfaae32a Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Wed, 23 Oct 2013 00:49:55 +0300 Subject: [PATCH 020/374] FULLPIPE: Implement MovGraph::calcNodeDistancesAndAngles() --- engines/fullpipe/motion.cpp | 22 ++++++++++++++++++++++ engines/fullpipe/motion.h | 3 +++ 2 files changed, 25 insertions(+) diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp index ebf896cf1e45..750c2de5ea98 100644 --- a/engines/fullpipe/motion.cpp +++ b/engines/fullpipe/motion.cpp @@ -357,6 +357,18 @@ double MovGraph::calcDistance(Common::Point *point, MovGraphLink *link, int fuzz return res; } +void MovGraph::calcNodeDistancesAndAngles() { + for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) { + assert(((CObject *)*i)->_objtype == kObjTypeMovGraphLink); + + MovGraphLink *lnk = (MovGraphLink *)*i; + + lnk->_flags &= 0x7FFFFFFF; + + lnk->calcNodeDistanceAndAngle(); + } +} + int MovGraph2::getItemIndexByGameObjectId(int objectId) { for (uint i = 0; i < _items.size(); i++) if (_items[i]->_objectId == objectId) @@ -1248,6 +1260,16 @@ bool MovGraphLink::load(MfcArchive &file) { return true; } +void MovGraphLink::calcNodeDistanceAndAngle() { + if (_movGraphNode1) { + double dx = _movGraphNode2->_x - _movGraphNode1->_x; + double dy = _movGraphNode2->_y - _movGraphNode1->_y; + + _distance = sqrt(dy * dy + dx * dx); + _angle = atan2(dx, dy); + } +} + bool MovGraphNode::load(MfcArchive &file) { debug(5, "MovGraphNode::load()"); diff --git a/engines/fullpipe/motion.h b/engines/fullpipe/motion.h index 85ad084f6040..7da0c47fb2cc 100644 --- a/engines/fullpipe/motion.h +++ b/engines/fullpipe/motion.h @@ -206,6 +206,8 @@ class MovGraphLink : public CObject { public: MovGraphLink(); virtual bool load(MfcArchive &file); + + void calcNodeDistanceAndAngle(); }; struct MovGraphItem { @@ -255,6 +257,7 @@ class MovGraph : public MotionController { virtual int method50(); double calcDistance(Common::Point *point, MovGraphLink *link, int fuzzyMatch); + void calcNodeDistancesAndAngles(); MovGraphNode *calcOffset(int ox, int oy); }; From 2784901dac98f5972327a82bde147026cf7d7aee Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 20 Oct 2013 22:27:50 +0200 Subject: [PATCH 021/374] SDL: Clean up graphics manager switching slighty. Sadly this also requires us to extend GraphicsManager for this SDL specific feature. However, since that's only used in the SDL backend and Tizen it should be fine for now... --- backends/graphics/graphics.h | 21 ++++++++++++++++ .../graphics/openglsdl/openglsdl-graphics.cpp | 17 +++++++++---- .../graphics/openglsdl/openglsdl-graphics.h | 5 ++-- backends/graphics/sdl/sdl-graphics.cpp | 9 +++++-- backends/graphics/sdl/sdl-graphics.h | 3 +++ .../surfacesdl/surfacesdl-graphics.cpp | 19 +++++++++++---- .../graphics/surfacesdl/surfacesdl-graphics.h | 3 ++- backends/platform/sdl/sdl.cpp | 24 +++++++------------ 8 files changed, 72 insertions(+), 29 deletions(-) diff --git a/backends/graphics/graphics.h b/backends/graphics/graphics.h index 24397228e6ac..74258b891059 100644 --- a/backends/graphics/graphics.h +++ b/backends/graphics/graphics.h @@ -37,6 +37,27 @@ class GraphicsManager : public PaletteManager { public: virtual ~GraphicsManager() {} + /** + * Makes this graphics manager active. That means it should be ready to + * process inputs now. However, even without being active it should be + * able to query the supported modes and other bits. + * + * HACK: Actually this is specific to SdlGraphicsManager subclasses. + * But sadly we cannot cast from GraphicsManager to SdlGraphicsManager + * because there is no relation between these two. + */ + virtual void activateManager() {} + + /** + * Makes this graphics manager inactive. This should allow another + * graphics manager to become active again. + * + * HACK: Actually this is specific to SdlGraphicsManager subclasses. + * But sadly we cannot cast from GraphicsManager to SdlGraphicsManager + * because there is no relation between these two. + */ + virtual void deactivateManager() {} + virtual bool hasFeature(OSystem::Feature f) = 0; virtual void setFeatureState(OSystem::Feature f, bool enable) = 0; virtual bool getFeatureState(OSystem::Feature f) = 0; diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp index 925237b75eb9..088e97b1f79f 100644 --- a/backends/graphics/openglsdl/openglsdl-graphics.cpp +++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp @@ -82,15 +82,24 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt } OpenGLSdlGraphicsManager::~OpenGLSdlGraphicsManager() { +} + +void OpenGLSdlGraphicsManager::activateManager() { + OpenGLGraphicsManager::activateManager(); + initEventSource(); + + // Register the graphics manager as a event observer + g_system->getEventManager()->getEventDispatcher()->registerObserver(this, 10, false); +} + +void OpenGLSdlGraphicsManager::deactivateManager() { // Unregister the event observer if (g_system->getEventManager()->getEventDispatcher()) { g_system->getEventManager()->getEventDispatcher()->unregisterObserver(this); } -} -void OpenGLSdlGraphicsManager::initEventObserver() { - // Register the graphics manager as a event observer - g_system->getEventManager()->getEventDispatcher()->registerObserver(this, 10, false); + deinitEventSource(); + OpenGLGraphicsManager::deactivateManager(); } bool OpenGLSdlGraphicsManager::hasFeature(OSystem::Feature f) { diff --git a/backends/graphics/openglsdl/openglsdl-graphics.h b/backends/graphics/openglsdl/openglsdl-graphics.h index 0644f27602cd..9934ca79e23e 100644 --- a/backends/graphics/openglsdl/openglsdl-graphics.h +++ b/backends/graphics/openglsdl/openglsdl-graphics.h @@ -35,9 +35,10 @@ class OpenGLSdlGraphicsManager : public OpenGL::OpenGLGraphicsManager, public Sd OpenGLSdlGraphicsManager(uint desktopWidth, uint desktopHeight, SdlEventSource *eventSource); virtual ~OpenGLSdlGraphicsManager(); - void initEventObserver(); - // GraphicsManager API + virtual void activateManager(); + virtual void deactivateManager(); + virtual bool hasFeature(OSystem::Feature f); virtual void setFeatureState(OSystem::Feature f, bool enable); virtual bool getFeatureState(OSystem::Feature f); diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp index 2eca4b8aabea..417f4faf54ca 100644 --- a/backends/graphics/sdl/sdl-graphics.cpp +++ b/backends/graphics/sdl/sdl-graphics.cpp @@ -26,10 +26,15 @@ SdlGraphicsManager::SdlGraphicsManager(SdlEventSource *source) : _eventSource(source) { - _eventSource->setGraphicsManager(this); } SdlGraphicsManager::~SdlGraphicsManager() { - _eventSource->setGraphicsManager(0); } +void SdlGraphicsManager::initEventSource() { + _eventSource->setGraphicsManager(this); +} + +void SdlGraphicsManager::deinitEventSource() { + _eventSource->setGraphicsManager(0); +} diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h index ea9149fccb7e..4d4338af16e1 100644 --- a/backends/graphics/sdl/sdl-graphics.h +++ b/backends/graphics/sdl/sdl-graphics.h @@ -80,6 +80,9 @@ class SdlGraphicsManager { virtual void notifyMousePos(Common::Point mouse) = 0; protected: + void initEventSource(); + void deinitEventSource(); + SdlEventSource *_eventSource; }; diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp index 871c6c49b2d7..ba8807aaf4d5 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp @@ -193,10 +193,6 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou } SurfaceSdlGraphicsManager::~SurfaceSdlGraphicsManager() { - // Unregister the event observer - if (g_system->getEventManager()->getEventDispatcher() != NULL) - g_system->getEventManager()->getEventDispatcher()->unregisterObserver(this); - unloadGFXMode(); if (_mouseSurface) SDL_FreeSurface(_mouseSurface); @@ -211,11 +207,24 @@ SurfaceSdlGraphicsManager::~SurfaceSdlGraphicsManager() { free(_mouseData); } -void SurfaceSdlGraphicsManager::initEventObserver() { +void SurfaceSdlGraphicsManager::activateManager() { + GraphicsManager::activateManager(); + initEventSource(); + // Register the graphics manager as a event observer g_system->getEventManager()->getEventDispatcher()->registerObserver(this, 10, false); } +void SurfaceSdlGraphicsManager::deactivateManager() { + // Unregister the event observer + if (g_system->getEventManager()->getEventDispatcher()) { + g_system->getEventManager()->getEventDispatcher()->unregisterObserver(this); + } + + deinitEventSource(); + GraphicsManager::deactivateManager(); +} + bool SurfaceSdlGraphicsManager::hasFeature(OSystem::Feature f) { return (f == OSystem::kFeatureFullscreenMode) || diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h index 97de0f9c9797..0bee70bf0c73 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.h +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h @@ -80,7 +80,8 @@ class SurfaceSdlGraphicsManager : public GraphicsManager, public SdlGraphicsMana SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSource); virtual ~SurfaceSdlGraphicsManager(); - virtual void initEventObserver(); + virtual void activateManager(); + virtual void deactivateManager(); virtual bool hasFeature(OSystem::Feature f); virtual void setFeatureState(OSystem::Feature f, bool enable); diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 1431e1fc5ec9..84187f96387b 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -89,6 +89,9 @@ OSystem_SDL::~OSystem_SDL() { // Hence, we perform the destruction on our own. delete _savefileManager; _savefileManager = 0; + if (_graphicsManager) { + _graphicsManager->deactivateManager(); + } delete _graphicsManager; _graphicsManager = 0; delete _eventManager; @@ -161,8 +164,6 @@ void OSystem_SDL::initBackend() { if (_eventSource == 0) _eventSource = new SdlEventSource(); - int graphicsManagerType = 0; - #ifdef USE_OPENGL // Query the desktop resolution. We simply hope nothing tried to change // the resolution so far. @@ -193,13 +194,11 @@ void OSystem_SDL::initBackend() { // If the gfx_mode is from OpenGL, create the OpenGL graphics manager if (use_opengl) { _graphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource); - graphicsManagerType = 1; } } #endif if (_graphicsManager == 0) { _graphicsManager = new SurfaceSdlGraphicsManager(_eventSource); - graphicsManagerType = 0; } } @@ -242,13 +241,7 @@ void OSystem_SDL::initBackend() { // so the virtual keyboard can be initialized, but we have to add the // graphics manager as an event observer after initializing the event // manager. - if (graphicsManagerType == 0) - ((SurfaceSdlGraphicsManager *)_graphicsManager)->initEventObserver(); -#ifdef USE_OPENGL - else if (graphicsManagerType == 1) - ((OpenGLSdlGraphicsManager *)_graphicsManager)->initEventObserver(); -#endif - + _graphicsManager->activateManager(); } #if defined(USE_TASKBAR) @@ -595,18 +588,16 @@ bool OSystem_SDL::setGraphicsMode(int mode) { // manager, delete and create the new mode graphics manager if (_graphicsMode >= _sdlModesCount && mode < _sdlModesCount) { debug(1, "switching to plain SDL graphics"); + _graphicsManager->deactivateManager(); delete _graphicsManager; _graphicsManager = new SurfaceSdlGraphicsManager(_eventSource); - ((SurfaceSdlGraphicsManager *)_graphicsManager)->initEventObserver(); - _graphicsManager->beginGFXTransaction(); switchedManager = true; } else if (_graphicsMode < _sdlModesCount && mode >= _sdlModesCount) { debug(1, "switching to OpenGL graphics"); + _graphicsManager->deactivateManager(); delete _graphicsManager; _graphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource); - ((OpenGLSdlGraphicsManager *)_graphicsManager)->initEventObserver(); - _graphicsManager->beginGFXTransaction(); switchedManager = true; } @@ -614,6 +605,9 @@ bool OSystem_SDL::setGraphicsMode(int mode) { _graphicsMode = mode; if (switchedManager) { + _graphicsManager->activateManager(); + + _graphicsManager->beginGFXTransaction(); #ifdef USE_RGB_COLOR _graphicsManager->initSize(screenWidth, screenHeight, &pixelFormat); #else From b53770366bdc5a79c81a35b5c04bb7b1804f233f Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 20 Oct 2013 23:00:28 +0200 Subject: [PATCH 022/374] SDL: Always initialize video subsystem in initSDL. --- .../graphics/openglsdl/openglsdl-graphics.cpp | 12 ------------ .../graphics/surfacesdl/surfacesdl-graphics.cpp | 10 ---------- backends/platform/gph/gph-backend.cpp | 8 +++++++- backends/platform/openpandora/op-backend.cpp | 8 +++++++- backends/platform/sdl/sdl.cpp | 16 +++++++++------- backends/platform/wince/wince-sdl.cpp | 5 ++++- 6 files changed, 27 insertions(+), 32 deletions(-) diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp index 088e97b1f79f..e39cd3587021 100644 --- a/backends/graphics/openglsdl/openglsdl-graphics.cpp +++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp @@ -32,11 +32,6 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt : SdlGraphicsManager(eventSource), _lastVideoModeLoad(0), _hwScreen(nullptr), _lastRequestedWidth(0), _lastRequestedHeight(0), _graphicsScale(2), _ignoreLoadVideoMode(false), _gotResize(false), _wantsFullScreen(false), _ignoreResizeEvents(0), _desiredFullscreenWidth(0), _desiredFullscreenHeight(0) { - // Initialize SDL video subsystem - if (SDL_InitSubSystem(SDL_INIT_VIDEO) == -1) { - error("Could not initialize SDL: %s", SDL_GetError()); - } - // Setup OpenGL attributes for SDL SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); @@ -44,13 +39,6 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - // This is also called in initSDL(), but initializing graphics - // may reset it. - SDL_EnableUNICODE(1); - - // Disable OS cursor - SDL_ShowCursor(SDL_DISABLE); - // Retrieve a list of working fullscreen modes const SDL_Rect *const *availableModes = SDL_ListModes(NULL, SDL_OPENGL | SDL_FULLSCREEN); if (availableModes != (void *)-1) { diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp index ba8807aaf4d5..8ad0bcbdd753 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp @@ -142,14 +142,6 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou #endif _transactionMode(kTransactionNone) { - if (SDL_InitSubSystem(SDL_INIT_VIDEO) == -1) { - error("Could not initialize SDL: %s", SDL_GetError()); - } - - // This is also called in initSDL(), but initializing graphics - // may reset it. - SDL_EnableUNICODE(1); - // allocate palette storage _currentPalette = (SDL_Color *)calloc(sizeof(SDL_Color), 256); _cursorPalette = (SDL_Color *)calloc(sizeof(SDL_Color), 256); @@ -165,8 +157,6 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou _enableFocusRectDebugCode = ConfMan.getBool("use_sdl_debug_focusrect"); #endif - SDL_ShowCursor(SDL_DISABLE); - memset(&_oldVideoMode, 0, sizeof(_oldVideoMode)); memset(&_videoMode, 0, sizeof(_videoMode)); memset(&_transactionDetails, 0, sizeof(_transactionDetails)); diff --git a/backends/platform/gph/gph-backend.cpp b/backends/platform/gph/gph-backend.cpp index 485780b47230..7239fdb2b4aa 100644 --- a/backends/platform/gph/gph-backend.cpp +++ b/backends/platform/gph/gph-backend.cpp @@ -172,7 +172,7 @@ void OSystem_GPH::initSDL() { // Check if SDL has not been initialized if (!_initedSDL) { - uint32 sdlFlags = SDL_INIT_EVENTTHREAD; + uint32 sdlFlags = SDL_INIT_EVENTTHREAD | SDL_INIT_VIDEO; if (ConfMan.hasKey("disable_sdl_parachute")) sdlFlags |= SDL_INIT_NOPARACHUTE; @@ -180,6 +180,12 @@ void OSystem_GPH::initSDL() { if (SDL_Init(sdlFlags) == -1) error("Could not initialize SDL: %s", SDL_GetError()); + // Enable unicode support if possible + SDL_EnableUNICODE(1); + + // Disable OS cursor + SDL_ShowCursor(SDL_DISABLE); + _initedSDL = true; } } diff --git a/backends/platform/openpandora/op-backend.cpp b/backends/platform/openpandora/op-backend.cpp index 354aa24b243c..4350d697e234 100644 --- a/backends/platform/openpandora/op-backend.cpp +++ b/backends/platform/openpandora/op-backend.cpp @@ -160,7 +160,7 @@ void OSystem_OP::initSDL() { // Check if SDL has not been initialized if (!_initedSDL) { - uint32 sdlFlags = SDL_INIT_EVENTTHREAD; + uint32 sdlFlags = SDL_INIT_EVENTTHREAD | SDL_INIT_VIDEO; if (ConfMan.hasKey("disable_sdl_parachute")) sdlFlags |= SDL_INIT_NOPARACHUTE; @@ -168,6 +168,12 @@ void OSystem_OP::initSDL() { if (SDL_Init(sdlFlags) == -1) error("Could not initialize SDL: %s", SDL_GetError()); + // Enable unicode support if possible + SDL_EnableUNICODE(1); + + // Disable OS cursor + SDL_ShowCursor(SDL_DISABLE); + _initedSDL = true; } } diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 84187f96387b..e8a7f7b9afc6 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -262,16 +262,15 @@ void OSystem_SDL::engineDone() { void OSystem_SDL::initSDL() { // Check if SDL has not been initialized if (!_initedSDL) { - uint32 sdlFlags = 0; + // We always initialize the video subsystem because we will need it to + // be initialized before the graphics managers to retrieve the desktop + // resolution, for example. WebOS also requires this initialization + // or otherwise the application won't start. + uint32 sdlFlags = SDL_INIT_VIDEO; + if (ConfMan.hasKey("disable_sdl_parachute")) sdlFlags |= SDL_INIT_NOPARACHUTE; -#if defined(WEBOS) || defined(USE_OPENGL) - // WebOS needs this flag or otherwise the application won't start. - // OpenGL SDL needs this to query the desktop resolution on startup. - sdlFlags |= SDL_INIT_VIDEO; -#endif - // Initialize SDL (SDL Subsystems are initiliazed in the corresponding sdl managers) if (SDL_Init(sdlFlags) == -1) error("Could not initialize SDL: %s", SDL_GetError()); @@ -279,6 +278,9 @@ void OSystem_SDL::initSDL() { // Enable unicode support if possible SDL_EnableUNICODE(1); + // Disable OS cursor + SDL_ShowCursor(SDL_DISABLE); + _initedSDL = true; } } diff --git a/backends/platform/wince/wince-sdl.cpp b/backends/platform/wince/wince-sdl.cpp index 3897731db429..ea2bc42301de 100644 --- a/backends/platform/wince/wince-sdl.cpp +++ b/backends/platform/wince/wince-sdl.cpp @@ -563,7 +563,7 @@ void OSystem_WINCE3::setGraphicsModeIntern() { void OSystem_WINCE3::initSDL() { // Check if SDL has not been initialized if (!_initedSDL) { - uint32 sdlFlags = SDL_INIT_EVENTTHREAD; + uint32 sdlFlags = SDL_INIT_EVENTTHREAD | SDL_INIT_VIDEO; if (ConfMan.hasKey("disable_sdl_parachute")) sdlFlags |= SDL_INIT_NOPARACHUTE; @@ -579,6 +579,9 @@ void OSystem_WINCE3::initSDL() { // Enable unicode support if possible SDL_EnableUNICODE(1); + // Disable OS cursor + SDL_ShowCursor(SDL_DISABLE); + _initedSDL = true; } } From b85989bd8e19e153d95182761a9d3df1b8d1f85e Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 20 Oct 2013 23:29:40 +0200 Subject: [PATCH 023/374] SDL: Clean up graphics mode handling for OpenGL backend. Instead of custom memory management Common::Array is used now. --- backends/platform/sdl/sdl.cpp | 27 ++++++++++----------------- backends/platform/sdl/sdl.h | 5 ++++- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index e8a7f7b9afc6..5aab1b7b3b97 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -67,7 +67,7 @@ OSystem_SDL::OSystem_SDL() #ifdef USE_OPENGL _desktopWidth(0), _desktopHeight(0), - _graphicsModes(0), + _graphicsModes(), _graphicsMode(0), _sdlModesCount(0), _glModesCount(0), @@ -115,10 +115,6 @@ OSystem_SDL::~OSystem_SDL() { delete _mutexManager; _mutexManager = 0; -#ifdef USE_OPENGL - delete[] _graphicsModes; -#endif - delete _logger; _logger = 0; @@ -543,7 +539,7 @@ Common::TimerManager *OSystem_SDL::getTimerManager() { #ifdef USE_OPENGL const OSystem::GraphicsMode *OSystem_SDL::getSupportedGraphicsModes() const { - return _graphicsModes; + return _graphicsModes.begin(); } int OSystem_SDL::getDefaultGraphicsMode() const { @@ -658,6 +654,8 @@ int OSystem_SDL::getGraphicsMode() const { } void OSystem_SDL::setupGraphicsModes() { + _graphicsModes.clear(); + const OSystem::GraphicsMode *sdlGraphicsModes = SurfaceSdlGraphicsManager::supportedGraphicsModes(); const OSystem::GraphicsMode *openglGraphicsModes = OpenGLSdlGraphicsManager::supportedGraphicsModes(); _sdlModesCount = 0; @@ -667,29 +665,24 @@ void OSystem_SDL::setupGraphicsModes() { const OSystem::GraphicsMode *srcMode = sdlGraphicsModes; while (srcMode->name) { _sdlModesCount++; + _graphicsModes.push_back(*srcMode); srcMode++; } srcMode = openglGraphicsModes; while (srcMode->name) { _glModesCount++; + _graphicsModes.push_back(*srcMode); srcMode++; } - // Allocate enough space for merged array of modes - _graphicsModes = new OSystem::GraphicsMode[_glModesCount + _sdlModesCount + 1]; - - // Copy SDL graphics modes - memcpy((void *)_graphicsModes, sdlGraphicsModes, _sdlModesCount * sizeof(OSystem::GraphicsMode)); - - // Copy OpenGL graphics modes - memcpy((void *)(_graphicsModes + _sdlModesCount), openglGraphicsModes, _glModesCount * sizeof(OSystem::GraphicsMode)); - // Set a null mode at the end - memset((void *)(_graphicsModes + _sdlModesCount + _glModesCount), 0, sizeof(OSystem::GraphicsMode)); + GraphicsMode nullMode; + memset(&nullMode, 0, sizeof(nullMode)); + _graphicsModes.push_back(nullMode); // Set new internal ids for all modes int i = 0; - OSystem::GraphicsMode *mode = _graphicsModes; + OSystem::GraphicsMode *mode = _graphicsModes.begin(); while (mode->name) { mode->id = i++; mode++; diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h index 590354b69958..634851968100 100644 --- a/backends/platform/sdl/sdl.h +++ b/backends/platform/sdl/sdl.h @@ -30,6 +30,8 @@ #include "backends/events/sdl/sdl-events.h" #include "backends/log/log.h" +#include "common/array.h" + /** * Base OSystem class for all SDL ports. */ @@ -108,7 +110,8 @@ class OSystem_SDL : public ModularBackend { #ifdef USE_OPENGL int _desktopWidth, _desktopHeight; - OSystem::GraphicsMode *_graphicsModes; + typedef Common::Array GraphicsModeArray; + GraphicsModeArray _graphicsModes; int _graphicsMode; int _sdlModesCount; int _glModesCount; From 960b47dbded2668051da8f5b0e4267d167f2403e Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 20 Oct 2013 23:39:46 +0200 Subject: [PATCH 024/374] SDL: Get rid of loop in OSystem_SDL::setGraphicsMode. --- backends/platform/sdl/sdl.cpp | 113 +++++++++++++++------------------- backends/platform/sdl/sdl.h | 1 + 2 files changed, 50 insertions(+), 64 deletions(-) diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 5aab1b7b3b97..b0ebc476e109 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -551,16 +551,9 @@ int OSystem_SDL::getDefaultGraphicsMode() const { } bool OSystem_SDL::setGraphicsMode(int mode) { - const OSystem::GraphicsMode *srcMode; - int i; - - // Check if mode is from SDL or OpenGL - if (mode < _sdlModesCount) { - srcMode = SurfaceSdlGraphicsManager::supportedGraphicsModes(); - i = 0; - } else { - srcMode = OpenGLSdlGraphicsManager::supportedGraphicsModes(); - i = _sdlModesCount; + // Check whether a invalid mode is requested. + if (mode < 0 || (uint)mode >= _graphicsModeIds.size()) { + return false; } // Very hacky way to set up the old graphics manager state, in case we @@ -579,74 +572,64 @@ bool OSystem_SDL::setGraphicsMode(int mode) { bool switchedManager = false; - // Loop through modes - while (srcMode->name) { - if (i == mode) { - // If the new mode and the current mode are not from the same graphics - // manager, delete and create the new mode graphics manager - if (_graphicsMode >= _sdlModesCount && mode < _sdlModesCount) { - debug(1, "switching to plain SDL graphics"); - _graphicsManager->deactivateManager(); - delete _graphicsManager; - _graphicsManager = new SurfaceSdlGraphicsManager(_eventSource); - - switchedManager = true; - } else if (_graphicsMode < _sdlModesCount && mode >= _sdlModesCount) { - debug(1, "switching to OpenGL graphics"); - _graphicsManager->deactivateManager(); - delete _graphicsManager; - _graphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource); + // If the new mode and the current mode are not from the same graphics + // manager, delete and create the new mode graphics manager + if (_graphicsMode >= _sdlModesCount && mode < _sdlModesCount) { + debug(1, "switching to plain SDL graphics"); + _graphicsManager->deactivateManager(); + delete _graphicsManager; + _graphicsManager = new SurfaceSdlGraphicsManager(_eventSource); - switchedManager = true; - } + switchedManager = true; + } else if (_graphicsMode < _sdlModesCount && mode >= _sdlModesCount) { + debug(1, "switching to OpenGL graphics"); + _graphicsManager->deactivateManager(); + delete _graphicsManager; + _graphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource); + + switchedManager = true; + } - _graphicsMode = mode; + _graphicsMode = mode; - if (switchedManager) { - _graphicsManager->activateManager(); + if (switchedManager) { + _graphicsManager->activateManager(); - _graphicsManager->beginGFXTransaction(); + _graphicsManager->beginGFXTransaction(); #ifdef USE_RGB_COLOR - _graphicsManager->initSize(screenWidth, screenHeight, &pixelFormat); + _graphicsManager->initSize(screenWidth, screenHeight, &pixelFormat); #else - _graphicsManager->initSize(screenWidth, screenHeight, 0); + _graphicsManager->initSize(screenWidth, screenHeight, 0); #endif - _graphicsManager->setFeatureState(kFeatureAspectRatioCorrection, arState); - _graphicsManager->setFeatureState(kFeatureFullscreenMode, fullscreen); - _graphicsManager->setFeatureState(kFeatureCursorPalette, cursorPalette); + _graphicsManager->setFeatureState(kFeatureAspectRatioCorrection, arState); + _graphicsManager->setFeatureState(kFeatureFullscreenMode, fullscreen); + _graphicsManager->setFeatureState(kFeatureCursorPalette, cursorPalette); - // Worst part about this right now, tell the cursor manager to - // resetup the cursor + cursor palette if necessarily + // Worst part about this right now, tell the cursor manager to + // resetup the cursor + cursor palette if necessarily - // First we need to try to setup the old state on the new manager... - if (_graphicsManager->endGFXTransaction() != kTransactionSuccess) { - // Oh my god if this failed the client code might just explode. - return false; - } - - // Next setup the cursor again - CursorMan.pushCursor(0, 0, 0, 0, 0, 0); - CursorMan.popCursor(); + // First we need to try to setup the old state on the new manager... + if (_graphicsManager->endGFXTransaction() != kTransactionSuccess) { + // Oh my god if this failed the client code might just explode. + return false; + } - // Next setup cursor palette if needed - if (cursorPalette) { - CursorMan.pushCursorPalette(0, 0, 0); - CursorMan.popCursorPalette(); - } + // Next setup the cursor again + CursorMan.pushCursor(0, 0, 0, 0, 0, 0); + CursorMan.popCursor(); - _graphicsManager->beginGFXTransaction(); - // Oh my god if this failed the client code might just explode. - return _graphicsManager->setGraphicsMode(srcMode->id); - } else { - return _graphicsManager->setGraphicsMode(srcMode->id); - } + // Next setup cursor palette if needed + if (cursorPalette) { + CursorMan.pushCursorPalette(0, 0, 0); + CursorMan.popCursorPalette(); } - i++; - srcMode++; + _graphicsManager->beginGFXTransaction(); + // Oh my god if this failed the client code might just explode. + return _graphicsManager->setGraphicsMode(_graphicsModeIds[mode]); + } else { + return _graphicsManager->setGraphicsMode(_graphicsModeIds[mode]); } - - return false; } int OSystem_SDL::getGraphicsMode() const { @@ -655,6 +638,7 @@ int OSystem_SDL::getGraphicsMode() const { void OSystem_SDL::setupGraphicsModes() { _graphicsModes.clear(); + _graphicsModeIds.clear(); const OSystem::GraphicsMode *sdlGraphicsModes = SurfaceSdlGraphicsManager::supportedGraphicsModes(); const OSystem::GraphicsMode *openglGraphicsModes = OpenGLSdlGraphicsManager::supportedGraphicsModes(); @@ -684,6 +668,7 @@ void OSystem_SDL::setupGraphicsModes() { int i = 0; OSystem::GraphicsMode *mode = _graphicsModes.begin(); while (mode->name) { + _graphicsModeIds.push_back(mode->id); mode->id = i++; mode++; } diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h index 634851968100..983b7a8237ea 100644 --- a/backends/platform/sdl/sdl.h +++ b/backends/platform/sdl/sdl.h @@ -112,6 +112,7 @@ class OSystem_SDL : public ModularBackend { typedef Common::Array GraphicsModeArray; GraphicsModeArray _graphicsModes; + Common::Array _graphicsModeIds; int _graphicsMode; int _sdlModesCount; int _glModesCount; From c820e212ebf146e51bcc3285da325195d6afa536 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Mon, 21 Oct 2013 00:21:51 +0200 Subject: [PATCH 025/374] SDL: Get rid of _glModesCount. --- backends/platform/sdl/sdl.cpp | 18 +++++++----------- backends/platform/sdl/sdl.h | 3 +-- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index b0ebc476e109..620d3c58ee4b 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -69,8 +69,7 @@ OSystem_SDL::OSystem_SDL() _desktopHeight(0), _graphicsModes(), _graphicsMode(0), - _sdlModesCount(0), - _glModesCount(0), + _firstGLMode(0), #endif _inited(false), _initedSDL(false), @@ -179,7 +178,7 @@ void OSystem_SDL::initBackend() { int i = 0; while (mode->name) { if (scumm_stricmp(mode->name, gfxMode.c_str()) == 0) { - _graphicsMode = i + _sdlModesCount; + _graphicsMode = i + _firstGLMode; use_opengl = true; } @@ -544,10 +543,10 @@ const OSystem::GraphicsMode *OSystem_SDL::getSupportedGraphicsModes() const { int OSystem_SDL::getDefaultGraphicsMode() const { // Return the default graphics mode from the current graphics manager - if (_graphicsMode < _sdlModesCount) + if (_graphicsMode < _firstGLMode) return _graphicsManager->getDefaultGraphicsMode(); else - return _graphicsManager->getDefaultGraphicsMode() + _sdlModesCount; + return _graphicsManager->getDefaultGraphicsMode() + _firstGLMode; } bool OSystem_SDL::setGraphicsMode(int mode) { @@ -574,14 +573,14 @@ bool OSystem_SDL::setGraphicsMode(int mode) { // If the new mode and the current mode are not from the same graphics // manager, delete and create the new mode graphics manager - if (_graphicsMode >= _sdlModesCount && mode < _sdlModesCount) { + if (_graphicsMode >= _firstGLMode && mode < _firstGLMode) { debug(1, "switching to plain SDL graphics"); _graphicsManager->deactivateManager(); delete _graphicsManager; _graphicsManager = new SurfaceSdlGraphicsManager(_eventSource); switchedManager = true; - } else if (_graphicsMode < _sdlModesCount && mode >= _sdlModesCount) { + } else if (_graphicsMode < _firstGLMode && mode >= _firstGLMode) { debug(1, "switching to OpenGL graphics"); _graphicsManager->deactivateManager(); delete _graphicsManager; @@ -642,19 +641,16 @@ void OSystem_SDL::setupGraphicsModes() { const OSystem::GraphicsMode *sdlGraphicsModes = SurfaceSdlGraphicsManager::supportedGraphicsModes(); const OSystem::GraphicsMode *openglGraphicsModes = OpenGLSdlGraphicsManager::supportedGraphicsModes(); - _sdlModesCount = 0; - _glModesCount = 0; // Count the number of graphics modes const OSystem::GraphicsMode *srcMode = sdlGraphicsModes; while (srcMode->name) { - _sdlModesCount++; _graphicsModes.push_back(*srcMode); srcMode++; } + _firstGLMode = _graphicsModes.size(); srcMode = openglGraphicsModes; while (srcMode->name) { - _glModesCount++; _graphicsModes.push_back(*srcMode); srcMode++; } diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h index 983b7a8237ea..6389bdfbeeeb 100644 --- a/backends/platform/sdl/sdl.h +++ b/backends/platform/sdl/sdl.h @@ -114,8 +114,7 @@ class OSystem_SDL : public ModularBackend { GraphicsModeArray _graphicsModes; Common::Array _graphicsModeIds; int _graphicsMode; - int _sdlModesCount; - int _glModesCount; + int _firstGLMode; /** * Creates the merged graphics modes list From 3523ec449ea8ccbe63d97b806c8ba9314808d080 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Mon, 21 Oct 2013 00:34:06 +0200 Subject: [PATCH 026/374] SDL: Simplify initial graphics manager selection for OpenGL. --- backends/platform/sdl/sdl.cpp | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 620d3c58ee4b..113e77937e46 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -172,26 +172,18 @@ void OSystem_SDL::initBackend() { if (_graphicsManager == 0) { #ifdef USE_OPENGL if (ConfMan.hasKey("gfx_mode")) { + // If the gfx_mode is from OpenGL, create the OpenGL graphics manager Common::String gfxMode(ConfMan.get("gfx_mode")); - bool use_opengl = false; - const OSystem::GraphicsMode *mode = OpenGLSdlGraphicsManager::supportedGraphicsModes(); - int i = 0; - while (mode->name) { - if (scumm_stricmp(mode->name, gfxMode.c_str()) == 0) { - _graphicsMode = i + _firstGLMode; - use_opengl = true; + for (uint i = _firstGLMode; i < _graphicsModeIds.size(); ++i) { + if (!scumm_stricmp(_graphicsModes[i].name, gfxMode.c_str())) { + _graphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource); + _graphicsMode = i; + break; } - - mode++; - ++i; - } - - // If the gfx_mode is from OpenGL, create the OpenGL graphics manager - if (use_opengl) { - _graphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource); } } #endif + if (_graphicsManager == 0) { _graphicsManager = new SurfaceSdlGraphicsManager(_eventSource); } From c5f1ee5b281e6e9c2291ff03bc9e71429a8e153b Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Mon, 21 Oct 2013 00:50:35 +0200 Subject: [PATCH 027/374] SDL: Make setupGraphicsModes non-virtual. The logic of switching the managers is pretty much fixed at the same level and cannot be easily overwritten. --- backends/platform/sdl/sdl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h index 6389bdfbeeeb..6c7f371f2eae 100644 --- a/backends/platform/sdl/sdl.h +++ b/backends/platform/sdl/sdl.h @@ -119,7 +119,7 @@ class OSystem_SDL : public ModularBackend { /** * Creates the merged graphics modes list */ - virtual void setupGraphicsModes(); + void setupGraphicsModes(); virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const; virtual int getDefaultGraphicsMode() const; From 4834017476f0abf8a4724179191c7fd1ed319fa2 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Mon, 21 Oct 2013 00:56:13 +0200 Subject: [PATCH 028/374] SDL: Only allow switching of SurfaceSDL <-> OpenGL when no custom manager is used. --- backends/platform/sdl/sdl.cpp | 40 ++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 113e77937e46..39865c85c6a2 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -144,10 +144,6 @@ void OSystem_SDL::init() { _taskbarManager = new Common::TaskbarManager(); #endif -#ifdef USE_OPENGL - // Setup a list with both SDL and OpenGL graphics modes - setupGraphicsModes(); -#endif } void OSystem_SDL::initBackend() { @@ -171,6 +167,14 @@ void OSystem_SDL::initBackend() { if (_graphicsManager == 0) { #ifdef USE_OPENGL + // Setup a list with both SDL and OpenGL graphics modes. We only do + // this whenever the subclass did not already set up an graphics + // manager yet. This is because we don't know the type of the graphics + // manager of the subclass, thus we cannot easily switch between the + // OpenGL one and the set up one. It also is to be expected that the + // subclass does not want any switching of graphics managers anyway. + setupGraphicsModes(); + if (ConfMan.hasKey("gfx_mode")) { // If the gfx_mode is from OpenGL, create the OpenGL graphics manager Common::String gfxMode(ConfMan.get("gfx_mode")); @@ -530,18 +534,30 @@ Common::TimerManager *OSystem_SDL::getTimerManager() { #ifdef USE_OPENGL const OSystem::GraphicsMode *OSystem_SDL::getSupportedGraphicsModes() const { - return _graphicsModes.begin(); + if (_graphicsModes.empty()) { + return _graphicsManager->getSupportedGraphicsModes(); + } else { + return _graphicsModes.begin(); + } } int OSystem_SDL::getDefaultGraphicsMode() const { - // Return the default graphics mode from the current graphics manager - if (_graphicsMode < _firstGLMode) + if (_graphicsModes.empty()) { return _graphicsManager->getDefaultGraphicsMode(); - else - return _graphicsManager->getDefaultGraphicsMode() + _firstGLMode; + } else { + // Return the default graphics mode from the current graphics manager + if (_graphicsMode < _firstGLMode) + return _graphicsManager->getDefaultGraphicsMode(); + else + return _graphicsManager->getDefaultGraphicsMode() + _firstGLMode; + } } bool OSystem_SDL::setGraphicsMode(int mode) { + if (_graphicsModes.empty()) { + return _graphicsManager->setGraphicsMode(mode); + } + // Check whether a invalid mode is requested. if (mode < 0 || (uint)mode >= _graphicsModeIds.size()) { return false; @@ -624,7 +640,11 @@ bool OSystem_SDL::setGraphicsMode(int mode) { } int OSystem_SDL::getGraphicsMode() const { - return _graphicsMode; + if (_graphicsModes.empty()) { + return _graphicsManager->getGraphicsMode(); + } else { + return _graphicsMode; + } } void OSystem_SDL::setupGraphicsModes() { From 06e4b3e060756dd1be1d86919af48afa8496e24b Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Mon, 21 Oct 2013 01:03:29 +0200 Subject: [PATCH 029/374] SDL: Do not require a static graphics mode list in OpenGL and SurfaceSDL. --- backends/graphics/opengl/opengl-graphics.cpp | 4 ---- backends/graphics/opengl/opengl-graphics.h | 4 ---- .../graphics/surfacesdl/surfacesdl-graphics.cpp | 4 ---- .../graphics/surfacesdl/surfacesdl-graphics.h | 1 - backends/platform/sdl/sdl.cpp | 15 ++++++++++----- 5 files changed, 10 insertions(+), 18 deletions(-) diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp index 00e8dc358ec6..9ad0e62f374e 100644 --- a/backends/graphics/opengl/opengl-graphics.cpp +++ b/backends/graphics/opengl/opengl-graphics.cpp @@ -122,10 +122,6 @@ const OSystem::GraphicsMode glGraphicsModes[] = { } // End of anonymous namespace -const OSystem::GraphicsMode *OpenGLGraphicsManager::supportedGraphicsModes() { - return glGraphicsModes; -} - const OSystem::GraphicsMode *OpenGLGraphicsManager::getSupportedGraphicsModes() const { return glGraphicsModes; } diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h index ebfe38fb602f..d2d035840724 100644 --- a/backends/graphics/opengl/opengl-graphics.h +++ b/backends/graphics/opengl/opengl-graphics.h @@ -57,10 +57,6 @@ class OpenGLGraphicsManager : public GraphicsManager { virtual void setFeatureState(OSystem::Feature f, bool enable); virtual bool getFeatureState(OSystem::Feature f); - // HACK: This is required for the SDL backend to switch between OpenGL SDL - // and Surface SDL. - static const OSystem::GraphicsMode *supportedGraphicsModes(); - virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const; virtual int getDefaultGraphicsMode() const; virtual bool setGraphicsMode(int mode); diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp index 8ad0bcbdd753..c946b8e74703 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp @@ -262,10 +262,6 @@ bool SurfaceSdlGraphicsManager::getFeatureState(OSystem::Feature f) { } } -const OSystem::GraphicsMode *SurfaceSdlGraphicsManager::supportedGraphicsModes() { - return s_supportedGraphicsModes; -} - const OSystem::GraphicsMode *SurfaceSdlGraphicsManager::getSupportedGraphicsModes() const { return s_supportedGraphicsModes; } diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h index 0bee70bf0c73..00c05ff2bf6c 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.h +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h @@ -87,7 +87,6 @@ class SurfaceSdlGraphicsManager : public GraphicsManager, public SdlGraphicsMana virtual void setFeatureState(OSystem::Feature f, bool enable); virtual bool getFeatureState(OSystem::Feature f); - static const OSystem::GraphicsMode *supportedGraphicsModes(); virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const; virtual int getDefaultGraphicsMode() const; virtual bool setGraphicsMode(int mode); diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 39865c85c6a2..327dfe21b91a 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -651,21 +651,26 @@ void OSystem_SDL::setupGraphicsModes() { _graphicsModes.clear(); _graphicsModeIds.clear(); - const OSystem::GraphicsMode *sdlGraphicsModes = SurfaceSdlGraphicsManager::supportedGraphicsModes(); - const OSystem::GraphicsMode *openglGraphicsModes = OpenGLSdlGraphicsManager::supportedGraphicsModes(); - // Count the number of graphics modes - const OSystem::GraphicsMode *srcMode = sdlGraphicsModes; + const OSystem::GraphicsMode *srcMode; + + GraphicsManager *manager = new SurfaceSdlGraphicsManager(_eventSource); + srcMode = manager->getSupportedGraphicsModes(); while (srcMode->name) { _graphicsModes.push_back(*srcMode); srcMode++; } + delete manager; + _firstGLMode = _graphicsModes.size(); - srcMode = openglGraphicsModes; + manager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource); + srcMode = manager->getSupportedGraphicsModes(); while (srcMode->name) { _graphicsModes.push_back(*srcMode); srcMode++; } + delete manager; + manager = nullptr; // Set a null mode at the end GraphicsMode nullMode; From ce92499e470f18ae8132ead53cda24f9516fe8e4 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Mon, 21 Oct 2013 01:10:09 +0200 Subject: [PATCH 030/374] SDL: Fix default graphics mode for switchable case. The former code (incorrectly) assumed that the getDefaultGraphicsMode returns the index in the table returned by getSupportedGraphicsModes. Now the correct ID is searched and then used. --- backends/platform/sdl/sdl.cpp | 18 ++++++++++++++++-- backends/platform/sdl/sdl.h | 2 ++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 327dfe21b91a..3272033df919 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -70,6 +70,8 @@ OSystem_SDL::OSystem_SDL() _graphicsModes(), _graphicsMode(0), _firstGLMode(0), + _defaultSDLMode(0), + _defaultGLMode(0), #endif _inited(false), _initedSDL(false), @@ -547,9 +549,9 @@ int OSystem_SDL::getDefaultGraphicsMode() const { } else { // Return the default graphics mode from the current graphics manager if (_graphicsMode < _firstGLMode) - return _graphicsManager->getDefaultGraphicsMode(); + return _defaultSDLMode; else - return _graphicsManager->getDefaultGraphicsMode() + _firstGLMode; + return _defaultGLMode; } } @@ -650,27 +652,39 @@ int OSystem_SDL::getGraphicsMode() const { void OSystem_SDL::setupGraphicsModes() { _graphicsModes.clear(); _graphicsModeIds.clear(); + _defaultSDLMode = _defaultGLMode = -1; // Count the number of graphics modes const OSystem::GraphicsMode *srcMode; + int defaultMode; GraphicsManager *manager = new SurfaceSdlGraphicsManager(_eventSource); srcMode = manager->getSupportedGraphicsModes(); + defaultMode = manager->getDefaultGraphicsMode(); while (srcMode->name) { + if (defaultMode == srcMode->id) { + _defaultSDLMode = _graphicsModes.size(); + } _graphicsModes.push_back(*srcMode); srcMode++; } delete manager; + assert(_defaultSDLMode != -1); _firstGLMode = _graphicsModes.size(); manager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource); srcMode = manager->getSupportedGraphicsModes(); + defaultMode = manager->getDefaultGraphicsMode(); while (srcMode->name) { + if (defaultMode == srcMode->id) { + _defaultGLMode = _graphicsModes.size(); + } _graphicsModes.push_back(*srcMode); srcMode++; } delete manager; manager = nullptr; + assert(_defaultGLMode != -1); // Set a null mode at the end GraphicsMode nullMode; diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h index 6c7f371f2eae..814cdd7c1b2d 100644 --- a/backends/platform/sdl/sdl.h +++ b/backends/platform/sdl/sdl.h @@ -115,6 +115,8 @@ class OSystem_SDL : public ModularBackend { Common::Array _graphicsModeIds; int _graphicsMode; int _firstGLMode; + int _defaultSDLMode; + int _defaultGLMode; /** * Creates the merged graphics modes list From a6f0d090cfe372484af05a528bead36021cc6e4d Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Tue, 22 Oct 2013 12:24:20 +0200 Subject: [PATCH 031/374] SDL: Reduce code duplication a bit. Now instead of initializing this in OSystem_SDL::initSDL (and in subclasses overwriting this) we simply initialize it in OSystem_SDL::init. --- backends/platform/gph/gph-backend.cpp | 6 ------ backends/platform/openpandora/op-backend.cpp | 6 ------ backends/platform/sdl/sdl.cpp | 12 ++++++------ backends/platform/wince/wince-sdl.cpp | 6 ------ 4 files changed, 6 insertions(+), 24 deletions(-) diff --git a/backends/platform/gph/gph-backend.cpp b/backends/platform/gph/gph-backend.cpp index 7239fdb2b4aa..e51d7d07815a 100644 --- a/backends/platform/gph/gph-backend.cpp +++ b/backends/platform/gph/gph-backend.cpp @@ -180,12 +180,6 @@ void OSystem_GPH::initSDL() { if (SDL_Init(sdlFlags) == -1) error("Could not initialize SDL: %s", SDL_GetError()); - // Enable unicode support if possible - SDL_EnableUNICODE(1); - - // Disable OS cursor - SDL_ShowCursor(SDL_DISABLE); - _initedSDL = true; } } diff --git a/backends/platform/openpandora/op-backend.cpp b/backends/platform/openpandora/op-backend.cpp index 4350d697e234..60c3cc7191c6 100644 --- a/backends/platform/openpandora/op-backend.cpp +++ b/backends/platform/openpandora/op-backend.cpp @@ -168,12 +168,6 @@ void OSystem_OP::initSDL() { if (SDL_Init(sdlFlags) == -1) error("Could not initialize SDL: %s", SDL_GetError()); - // Enable unicode support if possible - SDL_EnableUNICODE(1); - - // Disable OS cursor - SDL_ShowCursor(SDL_DISABLE); - _initedSDL = true; } } diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 3272033df919..c24072706930 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -126,6 +126,12 @@ void OSystem_SDL::init() { // Initialize SDL initSDL(); + // Enable unicode support if possible + SDL_EnableUNICODE(1); + + // Disable OS cursor + SDL_ShowCursor(SDL_DISABLE); + if (!_logger) _logger = new Backends::Log::Log(this); @@ -268,12 +274,6 @@ void OSystem_SDL::initSDL() { if (SDL_Init(sdlFlags) == -1) error("Could not initialize SDL: %s", SDL_GetError()); - // Enable unicode support if possible - SDL_EnableUNICODE(1); - - // Disable OS cursor - SDL_ShowCursor(SDL_DISABLE); - _initedSDL = true; } } diff --git a/backends/platform/wince/wince-sdl.cpp b/backends/platform/wince/wince-sdl.cpp index ea2bc42301de..1c5cd5565be8 100644 --- a/backends/platform/wince/wince-sdl.cpp +++ b/backends/platform/wince/wince-sdl.cpp @@ -576,12 +576,6 @@ void OSystem_WINCE3::initSDL() { if (SDL_Init(sdlFlags) == -1) error("Could not initialize SDL: %s", SDL_GetError()); - // Enable unicode support if possible - SDL_EnableUNICODE(1); - - // Disable OS cursor - SDL_ShowCursor(SDL_DISABLE); - _initedSDL = true; } } From d04a86c20b3ab501f81115246b622c1628f74077 Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Thu, 24 Oct 2013 01:08:24 +0300 Subject: [PATCH 032/374] FULLPIPE: Implement MessageQueue::transferExCommands() --- engines/fullpipe/messages.cpp | 7 +++++++ engines/fullpipe/messages.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp index d58212dc29cf..b5f3c7fa65fd 100644 --- a/engines/fullpipe/messages.cpp +++ b/engines/fullpipe/messages.cpp @@ -344,6 +344,13 @@ void MessageQueue::deleteExCommandByIndex(uint idx, bool doFree) { delete *it; } +void MessageQueue::transferExCommands(MessageQueue *mq) { + while (mq->_exCommands.size()) { + _exCommands.push_back(mq->_exCommands.front()); + mq->_exCommands.pop_front(); + } +} + void MessageQueue::sendNextCommand() { if (_exCommands.size()) { if (!(_flags & 4) && (_flags & 1)) { diff --git a/engines/fullpipe/messages.h b/engines/fullpipe/messages.h index a3533e1bd2b4..5238ba7db3f6 100644 --- a/engines/fullpipe/messages.h +++ b/engines/fullpipe/messages.h @@ -123,6 +123,8 @@ class MessageQueue : public CObject { ExCommand *getExCommandByIndex(uint idx); void deleteExCommandByIndex(uint idx, bool doFree); + void transferExCommands(MessageQueue *mq); + void replaceKeyCode(int key1, int key2); bool chain(StaticANIObject *ani); From 29033e357b1bdffd18a0d82fa6c5876dc3ee1769 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Thu, 24 Oct 2013 07:56:32 +0200 Subject: [PATCH 033/374] AVALANCHE: Fix a couple of (theoretical) out of bounds accesses (CID 1109650) --- engines/avalanche/avalot.cpp | 2 +- engines/avalanche/parser.cpp | 15 ++++++++++----- engines/avalanche/parser.h | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/engines/avalanche/avalot.cpp b/engines/avalanche/avalot.cpp index a7108841d4cd..072ad00ed6fc 100644 --- a/engines/avalanche/avalot.cpp +++ b/engines/avalanche/avalot.cpp @@ -1229,7 +1229,7 @@ void AvalancheEngine::checkClick() { _parser->_thing += 49; _parser->_person = kPeoplePardon; } else { - _parser->_person = (People) _thinks; + _parser->_person = (People)_thinks; _parser->_thing = _parser->kPardon; } callVerb(kVerbCodeExam); diff --git a/engines/avalanche/parser.cpp b/engines/avalanche/parser.cpp index 4cc184bfd918..297f27ffb834 100644 --- a/engines/avalanche/parser.cpp +++ b/engines/avalanche/parser.cpp @@ -1015,10 +1015,13 @@ bool Parser::isHolding() { if (_thing > 100) _vm->_dialogs->displayText("Be reasonable!"); - else if (!_vm->_objects[_thing - 1]) - // Verbs that need "_thing" to be in the inventory. - _vm->_dialogs->displayText("You're not holding it, Avvy."); - else + else if (_thing <= kObjectNum) { + if (!_vm->_objects[_thing - 1]) + // Verbs that need "_thing" to be in the inventory. + _vm->_dialogs->displayText("You're not holding it, Avvy."); + else + holdingResult = true; + } else holdingResult = true; return holdingResult; @@ -1053,8 +1056,10 @@ void Parser::examine() { examineObject(); else if ((50 <= _thing) && (_thing <= 100)) { // Also _thing + int id = _thing - 50; + assert(id < 31); openBox(true); - _vm->_dialogs->displayText(*_vm->_also[_thing - 50][1]); + _vm->_dialogs->displayText(*_vm->_also[id][1]); openBox(false); } } diff --git a/engines/avalanche/parser.h b/engines/avalanche/parser.h index 261e5ecefea5..bdb5ab9bc1a0 100644 --- a/engines/avalanche/parser.h +++ b/engines/avalanche/parser.h @@ -66,7 +66,7 @@ class Parser { Common::String _inputText; // Original name: current Common::String _inputTextBackup; byte _inputTextPos; // Original name: curpos - bool _quote; // 66 or 99 next? + bool _quote; bool _cursorState; bool _weirdWord; From e64c3dc002a083cb7ff471be89817015b35345dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Thu, 24 Oct 2013 13:28:06 +0100 Subject: [PATCH 034/374] PRINCE: code cleanup --- engines/prince/detection.cpp | 120 +++++++++++++++++------------------ engines/prince/graphics.cpp | 9 +-- engines/prince/prince.cpp | 28 +++----- 3 files changed, 72 insertions(+), 85 deletions(-) diff --git a/engines/prince/detection.cpp b/engines/prince/detection.cpp index e7f1ac01dd18..c5f6039ca129 100644 --- a/engines/prince/detection.cpp +++ b/engines/prince/detection.cpp @@ -28,32 +28,32 @@ namespace Prince { struct PrinceGameDescription { - ADGameDescription desc; + ADGameDescription desc; - int gameType; + int gameType; }; int PrinceEngine::getGameType() const { - return _gameDescription->gameType; + return _gameDescription->gameType; } const char *PrinceEngine::getGameId() const { - return _gameDescription->desc.gameid; + return _gameDescription->desc.gameid; } uint32 PrinceEngine::getFeatures() const { - return _gameDescription->desc.flags; + return _gameDescription->desc.flags; } Common::Language PrinceEngine::getLanguage() const { - return _gameDescription->desc.language; + return _gameDescription->desc.language; } } static const PlainGameDescriptor princeGames[] = { - {"prince", "Prince Game"}, - {0, 0} + {"prince", "Prince Game"}, + {0, 0} }; namespace Prince { @@ -61,34 +61,34 @@ namespace Prince { static const PrinceGameDescription gameDescriptions[] = { // German - { - { - "prince", - "Galador", - AD_ENTRY1s("databank.ptc", "5fa03833177331214ec1354761b1d2ee", 3565031), - Common::DE_DEU, - Common::kPlatformWindows, - ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) - }, - 0 - }, + { + { + "prince", + "Galador", + AD_ENTRY1s("databank.ptc", "5fa03833177331214ec1354761b1d2ee", 3565031), + Common::DE_DEU, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NONE) + }, + 0 + }, // Polish - { - { - "prince", - "Ksiaze i Tchorz", - AD_ENTRY1s("databank.ptc", "48ec9806bda9d152acbea8ce31c93c49", 3435298), - Common::PL_POL, - Common::kPlatformWindows, - ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) - }, - 1 - }, - - - { AD_TABLE_END_MARKER, 0 } + { + { + "prince", + "Ksiaze i Tchorz", + AD_ENTRY1s("databank.ptc", "48ec9806bda9d152acbea8ce31c93c49", 3435298), + Common::PL_POL, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NONE) + }, + 1 + }, + + + { AD_TABLE_END_MARKER, 0 } }; } // End of namespace Prince @@ -97,45 +97,45 @@ using namespace Prince; // we match from data too, to stop detection from a non-top-level directory const static char *directoryGlobs[] = { - "all", - 0 + "all", + 0 }; class PrinceMetaEngine : public AdvancedMetaEngine { public: - PrinceMetaEngine() : AdvancedMetaEngine(Prince::gameDescriptions, sizeof(Prince::PrinceGameDescription), princeGames) { - _singleid = "prince"; - _maxScanDepth = 2; - _directoryGlobs = directoryGlobs; - } - - virtual const char *getName() const { - return "Prince Engine"; - } - - virtual const char *getOriginalCopyright() const { - return "Copyright (C)"; - } - - virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; - virtual bool hasFeature(MetaEngineFeature f) const; + PrinceMetaEngine() : AdvancedMetaEngine(Prince::gameDescriptions, sizeof(Prince::PrinceGameDescription), princeGames) { + _singleid = "prince"; + _maxScanDepth = 2; + _directoryGlobs = directoryGlobs; + } + + virtual const char *getName() const { + return "Prince Engine"; + } + + virtual const char *getOriginalCopyright() const { + return "Copyright (C)"; + } + + virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; + virtual bool hasFeature(MetaEngineFeature f) const; }; bool PrinceMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { using namespace Prince; - const PrinceGameDescription *gd = (const PrinceGameDescription *)desc; - if (gd) { - *engine = new PrinceEngine(syst, gd); - } - return gd != 0; + const PrinceGameDescription *gd = (const PrinceGameDescription *)desc; + if (gd) { + *engine = new PrinceEngine(syst, gd); + } + return gd != 0; } bool PrinceMetaEngine::hasFeature(MetaEngineFeature f) const { - return false; + return false; } bool Prince::PrinceEngine::hasFeature(EngineFeature f) const { - return false;//(f == kSupportsRTL); + return false;//(f == kSupportsRTL); } #if PLUGIN_ENABLED_DYNAMIC(PRINCE) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index eae94748f61a..29fbd6a6110f 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -38,13 +38,10 @@ void GraphicsMan::draw(const Graphics::Surface *s) void GraphicsMan::drawTransparent(const Graphics::Surface *s) { - for (uint y = 0; y < 480; ++y) - { - for (uint x = 0; x < 640; ++x) - { + for (uint y = 0; y < 480; ++y) { + for (uint x = 0; x < 640; ++x) { byte pixel = *((byte*)s->getBasePtr(x,y)); - if (pixel != 255) - { + if (pixel != 255) { *((byte*)_frontScreen->getBasePtr(x, y)) = pixel; } } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index aec84684a7f5..1dd54bafd887 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -67,13 +67,11 @@ PrinceEngine::~PrinceEngine() { delete _debugger; } -GUI::Debugger *PrinceEngine::getDebugger() -{ +GUI::Debugger *PrinceEngine::getDebugger() { return _debugger; } Common::Error PrinceEngine::run() { - _graph = new GraphicsMan(this); const Common::FSNode gameDataDir(ConfMan.get("path")); @@ -127,8 +125,7 @@ Common::Error PrinceEngine::run() { return Common::kNoError; } -bool PrinceEngine::loadLocation(uint16 locationNr) -{ +bool PrinceEngine::loadLocation(uint16 locationNr) { debug("PrinceEngine::loadLocation %d", locationNr); const Common::FSNode gameDataDir(ConfMan.get("path")); SearchMan.remove(Common::String::format("%02d", _locationNr)); @@ -141,14 +138,12 @@ bool PrinceEngine::loadLocation(uint16 locationNr) // load location background Common::SeekableReadStream *room = SearchMan.createReadStreamForMember("room"); - if (!room) - { + if (!room) { error("Can't load room bitmap"); return false; } - if(_roomBmp.loadStream(*room)) - { + if(_roomBmp.loadStream(*room)) { debug("Room bitmap loaded"); _system->getPaletteManager()->setPalette(_roomBmp.getPalette(), 0, 256); } @@ -158,11 +153,9 @@ bool PrinceEngine::loadLocation(uint16 locationNr) return true; } -bool PrinceEngine::playNextFrame() -{ +bool PrinceEngine::playNextFrame() { const Graphics::Surface *s = _flicPlayer.decodeNextFrame(); - if (s) - { + if (s) { _graph->drawTransparent(s); _graph->change(); } @@ -170,19 +163,16 @@ bool PrinceEngine::playNextFrame() return true; } -bool PrinceEngine::loadAnim(uint16 animNr) -{ +bool PrinceEngine::loadAnim(uint16 animNr) { Common::String streamName = Common::String::format("AN%02d", animNr); Common::SeekableReadStream * flicStream = SearchMan.createReadStreamForMember(streamName); - if (!flicStream) - { + if (!flicStream) { error("Can't open %s", streamName.c_str()); return false; } - if (!_flicPlayer.loadStream(flicStream)) - { + if (!_flicPlayer.loadStream(flicStream)) { error("Can't load flic stream %s", streamName.c_str()); } From 026390145b0e947be7cccf3d9ba329eb2270a2ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Thu, 24 Oct 2013 14:24:27 +0100 Subject: [PATCH 035/374] PRINCE: Another code cleanup --- engines/prince/archive.cpp | 23 +++++++++ engines/prince/archive.h | 1 + engines/prince/debugger.cpp | 98 ++++++++++++++++++------------------- engines/prince/debugger.h | 14 +++--- engines/prince/font.cpp | 18 +++---- engines/prince/font.h | 8 +-- engines/prince/graphics.cpp | 24 ++++++++- engines/prince/prince.cpp | 14 +++--- engines/prince/prince.h | 22 ++++----- engines/prince/script.cpp | 94 +++++++++++++++++++++-------------- engines/prince/script.h | 3 +- 11 files changed, 194 insertions(+), 125 deletions(-) diff --git a/engines/prince/archive.cpp b/engines/prince/archive.cpp index e69de29bb2d1..b474c9517276 100644 --- a/engines/prince/archive.cpp +++ b/engines/prince/archive.cpp @@ -0,0 +1,23 @@ +/* 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/archive.h" diff --git a/engines/prince/archive.h b/engines/prince/archive.h index 3624a87a332d..3f5c5be4efb6 100644 --- a/engines/prince/archive.h +++ b/engines/prince/archive.h @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ + #ifndef PRINCE_ARCHIVE_H #define PRINCE_ARCHIVE_H diff --git a/engines/prince/debugger.cpp b/engines/prince/debugger.cpp index 56053afb2830..5da11acd88ae 100644 --- a/engines/prince/debugger.cpp +++ b/engines/prince/debugger.cpp @@ -11,7 +11,7 @@ * 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 + * 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 @@ -26,86 +26,86 @@ namespace Prince { Debugger::Debugger(PrinceEngine *vm) : GUI::Debugger(), _vm(vm) { - DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); - DCmd_Register("setflag", WRAP_METHOD(Debugger, Cmd_SetFlag)); - DCmd_Register("getflag", WRAP_METHOD(Debugger, Cmd_GetFlag)); - DCmd_Register("clearflag", WRAP_METHOD(Debugger, Cmd_ClearFlag)); - DCmd_Register("viewflc", WRAP_METHOD(Debugger, Cmd_ViewFlc)); + DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); + DCmd_Register("setflag", WRAP_METHOD(Debugger, Cmd_SetFlag)); + DCmd_Register("getflag", WRAP_METHOD(Debugger, Cmd_GetFlag)); + DCmd_Register("clearflag", WRAP_METHOD(Debugger, Cmd_ClearFlag)); + DCmd_Register("viewflc", WRAP_METHOD(Debugger, Cmd_ViewFlc)); } static int strToInt(const char *s) { - if (!*s) - // No string at all - return 0; - else if (toupper(s[strlen(s) - 1]) != 'H') - // Standard decimal string - return atoi(s); + if (!*s) + // No string at all + return 0; + else if (toupper(s[strlen(s) - 1]) != 'H') + // Standard decimal string + return atoi(s); - // Hexadecimal string - uint tmp = 0; - int read = sscanf(s, "%xh", &tmp); - if (read < 1) - error("strToInt failed on string \"%s\"", s); - return (int)tmp; + // Hexadecimal string + uint tmp = 0; + int read = sscanf(s, "%xh", &tmp); + if (read < 1) + error("strToInt failed on string \"%s\"", s); + return (int)tmp; } /* * This command sets a flag */ bool Debugger::Cmd_SetFlag(int argc, const char **argv) { - // Check for a flag to set - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } + // Check for a flag to set + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } - int flagNum = strToInt(argv[1]); - //g_globals->setFlag(flagNum); - return true; + int flagNum = strToInt(argv[1]); + //g_globals->setFlag(flagNum); + return true; } /* * This command gets the value of a flag */ bool Debugger::Cmd_GetFlag(int argc, const char **argv) { - // Check for an flag to display - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } + // Check for an flag to display + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } - int flagNum = strToInt(argv[1]); - //DebugPrintf("Value: %d\n", g_globals->getFlag(flagNum)); - return true; + int flagNum = strToInt(argv[1]); + //DebugPrintf("Value: %d\n", g_globals->getFlag(flagNum)); + return true; } /* * This command clears a flag */ bool Debugger::Cmd_ClearFlag(int argc, const char **argv) { - // Check for a flag to clear - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } - int flagNum = strToInt(argv[1]); - //g_globals->clearFlag(flagNum); - return true; + int flagNum = strToInt(argv[1]); + //g_globals->clearFlag(flagNum); + return true; } /* * This command starts new flc anim */ bool Debugger::Cmd_ViewFlc(int argc, const char **argv) { - // Check for a flag to clear - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } - int flagNum = strToInt(argv[1]); + int flagNum = strToInt(argv[1]); _vm->loadAnim(flagNum); - return true; + return true; } } diff --git a/engines/prince/debugger.h b/engines/prince/debugger.h index d47e439c8b5b..c5a8be60c6e5 100644 --- a/engines/prince/debugger.h +++ b/engines/prince/debugger.h @@ -11,7 +11,7 @@ * 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 + * 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 @@ -32,14 +32,14 @@ class PrinceEngine; class Debugger : public GUI::Debugger { public: - Debugger(PrinceEngine *vm); - virtual ~Debugger() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ + Debugger(PrinceEngine *vm); + virtual ~Debugger() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ private: - bool Cmd_SetFlag(int argc, const char **argv); - bool Cmd_GetFlag(int argc, const char **argv); - bool Cmd_ClearFlag(int argc, const char **argv); - bool Cmd_ViewFlc(int argc, const char **argv); + bool Cmd_SetFlag(int argc, const char **argv); + bool Cmd_GetFlag(int argc, const char **argv); + bool Cmd_ClearFlag(int argc, const char **argv); + bool Cmd_ViewFlc(int argc, const char **argv); PrinceEngine *_vm; }; diff --git a/engines/prince/font.cpp b/engines/prince/font.cpp index e72d73e61a65..8c72f1b91294 100644 --- a/engines/prince/font.cpp +++ b/engines/prince/font.cpp @@ -71,15 +71,15 @@ int Font::getCharWidth(byte chr) const { } void Font::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const { - const ChrData chrData = getChrData(chr); - const byte *src = chrData._pixels; - byte *target = (byte *)dst->getBasePtr(x, y); - - for (int i = 0; i < chrData._height; i++) { - memcpy(target, src, chrData._width); - src += chrData._width; - target += dst->pitch; - } + const ChrData chrData = getChrData(chr); + const byte *src = chrData._pixels; + byte *target = (byte *)dst->getBasePtr(x, y); + + for (int i = 0; i < chrData._height; i++) { + memcpy(target, src, chrData._width); + src += chrData._width; + target += dst->pitch; + } } } diff --git a/engines/prince/font.h b/engines/prince/font.h index ceae67df85bc..54e6b6b0a56c 100644 --- a/engines/prince/font.h +++ b/engines/prince/font.h @@ -41,13 +41,13 @@ class Font : public Graphics::Font { bool load(Common::SeekableReadStream &stream); - virtual int getFontHeight() const override; + virtual int getFontHeight() const override; - virtual int getMaxCharWidth() const override; + virtual int getMaxCharWidth() const override; - virtual int getCharWidth(byte chr) const override; + virtual int getCharWidth(byte chr) const override; - virtual void drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const override; + virtual void drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const override; private: struct ChrData { diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 29fbd6a6110f..74b46aad4c77 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -1,3 +1,25 @@ +/* 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/graphics.h" #include "prince/prince.h" @@ -8,7 +30,7 @@ namespace Prince { GraphicsMan::GraphicsMan(PrinceEngine *vm) : _vm(vm), _changed(false) { - initGraphics(640, 480, true); + initGraphics(640, 480, true); _frontScreen = new Graphics::Surface(); _frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 1dd54bafd887..4fb2082bafe0 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -182,13 +182,13 @@ bool PrinceEngine::loadAnim(uint16 animNr) { } void PrinceEngine::keyHandler(Common::Event event) { - uint16 nChar = event.kbd.keycode; - if (event.kbd.hasFlags(Common::KBD_CTRL)) { - switch (nChar) { - case Common::KEYCODE_d: - getDebugger()->attach(); - getDebugger()->onFrame(); - break; + uint16 nChar = event.kbd.keycode; + if (event.kbd.hasFlags(Common::KBD_CTRL)) { + switch (nChar) { + case Common::KEYCODE_d: + getDebugger()->attach(); + getDebugger()->onFrame(); + break; } } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index efaf643cb7f5..b289c75553a7 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -56,20 +56,20 @@ class Debugger; class PrinceEngine : public Engine { protected: - Common::Error run(); + Common::Error run(); public: - PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc); - virtual ~PrinceEngine(); + PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc); + virtual ~PrinceEngine(); - virtual bool hasFeature(EngineFeature f) const; + virtual bool hasFeature(EngineFeature f) const; - int getGameType() const; - const char *getGameId() const; - uint32 getFeatures() const; - Common::Language getLanguage() const; + int getGameType() const; + const char *getGameId() const; + uint32 getFeatures() const; + Common::Language getLanguage() const; - const PrinceGameDescription *_gameDescription; + const PrinceGameDescription *_gameDescription; Video::FlicDecoder _flicPlayer; bool loadLocation(uint16 locationNr); @@ -81,7 +81,7 @@ class PrinceEngine : public Engine { bool playNextFrame(); void keyHandler(Common::Event event); - Common::RandomSource *_rnd; + Common::RandomSource *_rnd; Graphics::BitmapDecoder _roomBmp; uint16 _locationNr; MhwanhDecoder _walizkaBmp; @@ -90,7 +90,7 @@ class PrinceEngine : public Engine { GraphicsMan *_graph; Script *_script; Font _font; - + void mainLoop(); }; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 66e0c598f96e..d790d6d9c33d 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1,3 +1,25 @@ +/* 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/script.h" #include "prince/prince.h" @@ -10,37 +32,37 @@ namespace Prince { static const uint16 NUM_OPCODES = 144; Script::Script(PrinceEngine *vm) : - _code(NULL), _stacktop(0), _vm(vm), _opcodeNF(false) { + _code(NULL), _stacktop(0), _vm(vm), _opcodeNF(false) { } Script::~Script() { - delete[] _code; + delete[] _code; } bool Script::loadFromStream(Common::SeekableReadStream &stream) { - _codeSize = stream.size(); - _code = new byte[_codeSize]; + _codeSize = stream.size(); + _code = new byte[_codeSize]; - if (!_code) - return false; + if (!_code) + return false; - stream.read(_code, _codeSize); - // Initialize the script - _currentInstruction = READ_LE_UINT32(_code + 4); + stream.read(_code, _codeSize); + // Initialize the script + _currentInstruction = READ_LE_UINT32(_code + 4); - return true; + return true; } void Script::debugScript(const char *s, ...) { - char buf[STRINGBUFLEN]; - va_list va; + char buf[STRINGBUFLEN]; + va_list va; - va_start(va, s); - vsnprintf(buf, STRINGBUFLEN, s, va); - va_end(va); + va_start(va, s); + vsnprintf(buf, STRINGBUFLEN, s, va); + va_end(va); Common::String str = Common::String::format("@0x%04X: ", _lastInstruction); - str += Common::String::format("op %02d: ", _lastOpcode); + str += Common::String::format("op %02d: ", _lastOpcode); debug("%s %s", str.c_str(), buf); } @@ -69,28 +91,28 @@ void Script::step() { } uint8 Script::getCodeByte(uint32 address) { - if (address >= _codeSize) - error("Trying to read a script byte at address 0x%04X, while the " - "script is just 0x%04X bytes long", address, _codeSize); - return _code[address]; + if (address >= _codeSize) + error("Trying to read a script byte at address 0x%04X, while the " + "script is just 0x%04X bytes long", address, _codeSize); + return _code[address]; } uint8 Script::readScript8bits() { - uint8 data = getCodeByte(_currentInstruction); - _currentInstruction++; - return data; + uint8 data = getCodeByte(_currentInstruction); + _currentInstruction++; + return data; } uint16 Script::readScript16bits() { - uint8 lower = readScript8bits(); - uint8 upper = readScript8bits(); - return lower | (upper << 8); + uint8 lower = readScript8bits(); + uint8 upper = readScript8bits(); + return lower | (upper << 8); } uint32 Script::readScript32bits() { - uint16 lower = readScript16bits(); - uint16 upper = readScript16bits(); - return lower | (upper << 16); + uint16 lower = readScript16bits(); + uint16 upper = readScript16bits(); + return lower | (upper << 16); } void Script::O_WAITFOREVER() { @@ -211,14 +233,14 @@ void Script::O__CALL() { debugScript("O__CALL 0x%04X", _currentInstruction); } void Script::O_RETURN() { - // Get the return address - if (_stacktop > 0) { - _stacktop--; - _currentInstruction = _stack[_stacktop]; + // Get the return address + if (_stacktop > 0) { + _stacktop--; + _currentInstruction = _stack[_stacktop]; debugScript("O_RETURN 0x%04X", _currentInstruction); - } else { - error("Return: Stack is empty"); - } + } else { + error("Return: Stack is empty"); + } } void Script::O_GO() { int32 opPC = readScript32bits(); diff --git a/engines/prince/script.h b/engines/prince/script.h index 982e7aae61f5..43d5759a0b3a 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -56,7 +56,8 @@ class Script bool _opcodeNF; // Stack - uint16 _stack[500]; + static const uint32 _STACK_SIZE = 500; + uint16 _stack[_STACK_SIZE]; uint8 _stacktop; uint8 _savedStacktop; From 5357724657bff809b10b1f2bfe8547d1b53d6dcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Thu, 24 Oct 2013 20:31:08 +0100 Subject: [PATCH 036/374] PRINCE: code cleanup --- engines/prince/archive.cpp | 23 +++++++ engines/prince/archive.h | 1 + engines/prince/debugger.cpp | 98 ++++++++++++++-------------- engines/prince/debugger.h | 14 ++-- engines/prince/detection.cpp | 120 +++++++++++++++++------------------ engines/prince/font.cpp | 18 +++--- engines/prince/font.h | 8 +-- engines/prince/graphics.cpp | 33 ++++++++-- engines/prince/prince.cpp | 42 +++++------- engines/prince/prince.h | 22 +++---- engines/prince/script.cpp | 94 ++++++++++++++++----------- engines/prince/script.h | 6 +- 12 files changed, 267 insertions(+), 212 deletions(-) diff --git a/engines/prince/archive.cpp b/engines/prince/archive.cpp index e69de29bb2d1..b474c9517276 100644 --- a/engines/prince/archive.cpp +++ b/engines/prince/archive.cpp @@ -0,0 +1,23 @@ +/* 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/archive.h" diff --git a/engines/prince/archive.h b/engines/prince/archive.h index 3624a87a332d..3f5c5be4efb6 100644 --- a/engines/prince/archive.h +++ b/engines/prince/archive.h @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ + #ifndef PRINCE_ARCHIVE_H #define PRINCE_ARCHIVE_H diff --git a/engines/prince/debugger.cpp b/engines/prince/debugger.cpp index 56053afb2830..5da11acd88ae 100644 --- a/engines/prince/debugger.cpp +++ b/engines/prince/debugger.cpp @@ -11,7 +11,7 @@ * 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 + * 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 @@ -26,86 +26,86 @@ namespace Prince { Debugger::Debugger(PrinceEngine *vm) : GUI::Debugger(), _vm(vm) { - DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); - DCmd_Register("setflag", WRAP_METHOD(Debugger, Cmd_SetFlag)); - DCmd_Register("getflag", WRAP_METHOD(Debugger, Cmd_GetFlag)); - DCmd_Register("clearflag", WRAP_METHOD(Debugger, Cmd_ClearFlag)); - DCmd_Register("viewflc", WRAP_METHOD(Debugger, Cmd_ViewFlc)); + DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); + DCmd_Register("setflag", WRAP_METHOD(Debugger, Cmd_SetFlag)); + DCmd_Register("getflag", WRAP_METHOD(Debugger, Cmd_GetFlag)); + DCmd_Register("clearflag", WRAP_METHOD(Debugger, Cmd_ClearFlag)); + DCmd_Register("viewflc", WRAP_METHOD(Debugger, Cmd_ViewFlc)); } static int strToInt(const char *s) { - if (!*s) - // No string at all - return 0; - else if (toupper(s[strlen(s) - 1]) != 'H') - // Standard decimal string - return atoi(s); + if (!*s) + // No string at all + return 0; + else if (toupper(s[strlen(s) - 1]) != 'H') + // Standard decimal string + return atoi(s); - // Hexadecimal string - uint tmp = 0; - int read = sscanf(s, "%xh", &tmp); - if (read < 1) - error("strToInt failed on string \"%s\"", s); - return (int)tmp; + // Hexadecimal string + uint tmp = 0; + int read = sscanf(s, "%xh", &tmp); + if (read < 1) + error("strToInt failed on string \"%s\"", s); + return (int)tmp; } /* * This command sets a flag */ bool Debugger::Cmd_SetFlag(int argc, const char **argv) { - // Check for a flag to set - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } + // Check for a flag to set + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } - int flagNum = strToInt(argv[1]); - //g_globals->setFlag(flagNum); - return true; + int flagNum = strToInt(argv[1]); + //g_globals->setFlag(flagNum); + return true; } /* * This command gets the value of a flag */ bool Debugger::Cmd_GetFlag(int argc, const char **argv) { - // Check for an flag to display - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } + // Check for an flag to display + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } - int flagNum = strToInt(argv[1]); - //DebugPrintf("Value: %d\n", g_globals->getFlag(flagNum)); - return true; + int flagNum = strToInt(argv[1]); + //DebugPrintf("Value: %d\n", g_globals->getFlag(flagNum)); + return true; } /* * This command clears a flag */ bool Debugger::Cmd_ClearFlag(int argc, const char **argv) { - // Check for a flag to clear - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } - int flagNum = strToInt(argv[1]); - //g_globals->clearFlag(flagNum); - return true; + int flagNum = strToInt(argv[1]); + //g_globals->clearFlag(flagNum); + return true; } /* * This command starts new flc anim */ bool Debugger::Cmd_ViewFlc(int argc, const char **argv) { - // Check for a flag to clear - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } - int flagNum = strToInt(argv[1]); + int flagNum = strToInt(argv[1]); _vm->loadAnim(flagNum); - return true; + return true; } } diff --git a/engines/prince/debugger.h b/engines/prince/debugger.h index d47e439c8b5b..c5a8be60c6e5 100644 --- a/engines/prince/debugger.h +++ b/engines/prince/debugger.h @@ -11,7 +11,7 @@ * 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 + * 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 @@ -32,14 +32,14 @@ class PrinceEngine; class Debugger : public GUI::Debugger { public: - Debugger(PrinceEngine *vm); - virtual ~Debugger() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ + Debugger(PrinceEngine *vm); + virtual ~Debugger() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ private: - bool Cmd_SetFlag(int argc, const char **argv); - bool Cmd_GetFlag(int argc, const char **argv); - bool Cmd_ClearFlag(int argc, const char **argv); - bool Cmd_ViewFlc(int argc, const char **argv); + bool Cmd_SetFlag(int argc, const char **argv); + bool Cmd_GetFlag(int argc, const char **argv); + bool Cmd_ClearFlag(int argc, const char **argv); + bool Cmd_ViewFlc(int argc, const char **argv); PrinceEngine *_vm; }; diff --git a/engines/prince/detection.cpp b/engines/prince/detection.cpp index e7f1ac01dd18..c5f6039ca129 100644 --- a/engines/prince/detection.cpp +++ b/engines/prince/detection.cpp @@ -28,32 +28,32 @@ namespace Prince { struct PrinceGameDescription { - ADGameDescription desc; + ADGameDescription desc; - int gameType; + int gameType; }; int PrinceEngine::getGameType() const { - return _gameDescription->gameType; + return _gameDescription->gameType; } const char *PrinceEngine::getGameId() const { - return _gameDescription->desc.gameid; + return _gameDescription->desc.gameid; } uint32 PrinceEngine::getFeatures() const { - return _gameDescription->desc.flags; + return _gameDescription->desc.flags; } Common::Language PrinceEngine::getLanguage() const { - return _gameDescription->desc.language; + return _gameDescription->desc.language; } } static const PlainGameDescriptor princeGames[] = { - {"prince", "Prince Game"}, - {0, 0} + {"prince", "Prince Game"}, + {0, 0} }; namespace Prince { @@ -61,34 +61,34 @@ namespace Prince { static const PrinceGameDescription gameDescriptions[] = { // German - { - { - "prince", - "Galador", - AD_ENTRY1s("databank.ptc", "5fa03833177331214ec1354761b1d2ee", 3565031), - Common::DE_DEU, - Common::kPlatformWindows, - ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) - }, - 0 - }, + { + { + "prince", + "Galador", + AD_ENTRY1s("databank.ptc", "5fa03833177331214ec1354761b1d2ee", 3565031), + Common::DE_DEU, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NONE) + }, + 0 + }, // Polish - { - { - "prince", - "Ksiaze i Tchorz", - AD_ENTRY1s("databank.ptc", "48ec9806bda9d152acbea8ce31c93c49", 3435298), - Common::PL_POL, - Common::kPlatformWindows, - ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) - }, - 1 - }, - - - { AD_TABLE_END_MARKER, 0 } + { + { + "prince", + "Ksiaze i Tchorz", + AD_ENTRY1s("databank.ptc", "48ec9806bda9d152acbea8ce31c93c49", 3435298), + Common::PL_POL, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NONE) + }, + 1 + }, + + + { AD_TABLE_END_MARKER, 0 } }; } // End of namespace Prince @@ -97,45 +97,45 @@ using namespace Prince; // we match from data too, to stop detection from a non-top-level directory const static char *directoryGlobs[] = { - "all", - 0 + "all", + 0 }; class PrinceMetaEngine : public AdvancedMetaEngine { public: - PrinceMetaEngine() : AdvancedMetaEngine(Prince::gameDescriptions, sizeof(Prince::PrinceGameDescription), princeGames) { - _singleid = "prince"; - _maxScanDepth = 2; - _directoryGlobs = directoryGlobs; - } - - virtual const char *getName() const { - return "Prince Engine"; - } - - virtual const char *getOriginalCopyright() const { - return "Copyright (C)"; - } - - virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; - virtual bool hasFeature(MetaEngineFeature f) const; + PrinceMetaEngine() : AdvancedMetaEngine(Prince::gameDescriptions, sizeof(Prince::PrinceGameDescription), princeGames) { + _singleid = "prince"; + _maxScanDepth = 2; + _directoryGlobs = directoryGlobs; + } + + virtual const char *getName() const { + return "Prince Engine"; + } + + virtual const char *getOriginalCopyright() const { + return "Copyright (C)"; + } + + virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; + virtual bool hasFeature(MetaEngineFeature f) const; }; bool PrinceMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { using namespace Prince; - const PrinceGameDescription *gd = (const PrinceGameDescription *)desc; - if (gd) { - *engine = new PrinceEngine(syst, gd); - } - return gd != 0; + const PrinceGameDescription *gd = (const PrinceGameDescription *)desc; + if (gd) { + *engine = new PrinceEngine(syst, gd); + } + return gd != 0; } bool PrinceMetaEngine::hasFeature(MetaEngineFeature f) const { - return false; + return false; } bool Prince::PrinceEngine::hasFeature(EngineFeature f) const { - return false;//(f == kSupportsRTL); + return false;//(f == kSupportsRTL); } #if PLUGIN_ENABLED_DYNAMIC(PRINCE) diff --git a/engines/prince/font.cpp b/engines/prince/font.cpp index e72d73e61a65..8c72f1b91294 100644 --- a/engines/prince/font.cpp +++ b/engines/prince/font.cpp @@ -71,15 +71,15 @@ int Font::getCharWidth(byte chr) const { } void Font::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const { - const ChrData chrData = getChrData(chr); - const byte *src = chrData._pixels; - byte *target = (byte *)dst->getBasePtr(x, y); - - for (int i = 0; i < chrData._height; i++) { - memcpy(target, src, chrData._width); - src += chrData._width; - target += dst->pitch; - } + const ChrData chrData = getChrData(chr); + const byte *src = chrData._pixels; + byte *target = (byte *)dst->getBasePtr(x, y); + + for (int i = 0; i < chrData._height; i++) { + memcpy(target, src, chrData._width); + src += chrData._width; + target += dst->pitch; + } } } diff --git a/engines/prince/font.h b/engines/prince/font.h index ceae67df85bc..54e6b6b0a56c 100644 --- a/engines/prince/font.h +++ b/engines/prince/font.h @@ -41,13 +41,13 @@ class Font : public Graphics::Font { bool load(Common::SeekableReadStream &stream); - virtual int getFontHeight() const override; + virtual int getFontHeight() const override; - virtual int getMaxCharWidth() const override; + virtual int getMaxCharWidth() const override; - virtual int getCharWidth(byte chr) const override; + virtual int getCharWidth(byte chr) const override; - virtual void drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const override; + virtual void drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const override; private: struct ChrData { diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index eae94748f61a..74b46aad4c77 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -1,3 +1,25 @@ +/* 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/graphics.h" #include "prince/prince.h" @@ -8,7 +30,7 @@ namespace Prince { GraphicsMan::GraphicsMan(PrinceEngine *vm) : _vm(vm), _changed(false) { - initGraphics(640, 480, true); + initGraphics(640, 480, true); _frontScreen = new Graphics::Surface(); _frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); } @@ -38,13 +60,10 @@ void GraphicsMan::draw(const Graphics::Surface *s) void GraphicsMan::drawTransparent(const Graphics::Surface *s) { - for (uint y = 0; y < 480; ++y) - { - for (uint x = 0; x < 640; ++x) - { + for (uint y = 0; y < 480; ++y) { + for (uint x = 0; x < 640; ++x) { byte pixel = *((byte*)s->getBasePtr(x,y)); - if (pixel != 255) - { + if (pixel != 255) { *((byte*)_frontScreen->getBasePtr(x, y)) = pixel; } } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index aec84684a7f5..4fb2082bafe0 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -67,13 +67,11 @@ PrinceEngine::~PrinceEngine() { delete _debugger; } -GUI::Debugger *PrinceEngine::getDebugger() -{ +GUI::Debugger *PrinceEngine::getDebugger() { return _debugger; } Common::Error PrinceEngine::run() { - _graph = new GraphicsMan(this); const Common::FSNode gameDataDir(ConfMan.get("path")); @@ -127,8 +125,7 @@ Common::Error PrinceEngine::run() { return Common::kNoError; } -bool PrinceEngine::loadLocation(uint16 locationNr) -{ +bool PrinceEngine::loadLocation(uint16 locationNr) { debug("PrinceEngine::loadLocation %d", locationNr); const Common::FSNode gameDataDir(ConfMan.get("path")); SearchMan.remove(Common::String::format("%02d", _locationNr)); @@ -141,14 +138,12 @@ bool PrinceEngine::loadLocation(uint16 locationNr) // load location background Common::SeekableReadStream *room = SearchMan.createReadStreamForMember("room"); - if (!room) - { + if (!room) { error("Can't load room bitmap"); return false; } - if(_roomBmp.loadStream(*room)) - { + if(_roomBmp.loadStream(*room)) { debug("Room bitmap loaded"); _system->getPaletteManager()->setPalette(_roomBmp.getPalette(), 0, 256); } @@ -158,11 +153,9 @@ bool PrinceEngine::loadLocation(uint16 locationNr) return true; } -bool PrinceEngine::playNextFrame() -{ +bool PrinceEngine::playNextFrame() { const Graphics::Surface *s = _flicPlayer.decodeNextFrame(); - if (s) - { + if (s) { _graph->drawTransparent(s); _graph->change(); } @@ -170,19 +163,16 @@ bool PrinceEngine::playNextFrame() return true; } -bool PrinceEngine::loadAnim(uint16 animNr) -{ +bool PrinceEngine::loadAnim(uint16 animNr) { Common::String streamName = Common::String::format("AN%02d", animNr); Common::SeekableReadStream * flicStream = SearchMan.createReadStreamForMember(streamName); - if (!flicStream) - { + if (!flicStream) { error("Can't open %s", streamName.c_str()); return false; } - if (!_flicPlayer.loadStream(flicStream)) - { + if (!_flicPlayer.loadStream(flicStream)) { error("Can't load flic stream %s", streamName.c_str()); } @@ -192,13 +182,13 @@ bool PrinceEngine::loadAnim(uint16 animNr) } void PrinceEngine::keyHandler(Common::Event event) { - uint16 nChar = event.kbd.keycode; - if (event.kbd.hasFlags(Common::KBD_CTRL)) { - switch (nChar) { - case Common::KEYCODE_d: - getDebugger()->attach(); - getDebugger()->onFrame(); - break; + uint16 nChar = event.kbd.keycode; + if (event.kbd.hasFlags(Common::KBD_CTRL)) { + switch (nChar) { + case Common::KEYCODE_d: + getDebugger()->attach(); + getDebugger()->onFrame(); + break; } } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index efaf643cb7f5..b289c75553a7 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -56,20 +56,20 @@ class Debugger; class PrinceEngine : public Engine { protected: - Common::Error run(); + Common::Error run(); public: - PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc); - virtual ~PrinceEngine(); + PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc); + virtual ~PrinceEngine(); - virtual bool hasFeature(EngineFeature f) const; + virtual bool hasFeature(EngineFeature f) const; - int getGameType() const; - const char *getGameId() const; - uint32 getFeatures() const; - Common::Language getLanguage() const; + int getGameType() const; + const char *getGameId() const; + uint32 getFeatures() const; + Common::Language getLanguage() const; - const PrinceGameDescription *_gameDescription; + const PrinceGameDescription *_gameDescription; Video::FlicDecoder _flicPlayer; bool loadLocation(uint16 locationNr); @@ -81,7 +81,7 @@ class PrinceEngine : public Engine { bool playNextFrame(); void keyHandler(Common::Event event); - Common::RandomSource *_rnd; + Common::RandomSource *_rnd; Graphics::BitmapDecoder _roomBmp; uint16 _locationNr; MhwanhDecoder _walizkaBmp; @@ -90,7 +90,7 @@ class PrinceEngine : public Engine { GraphicsMan *_graph; Script *_script; Font _font; - + void mainLoop(); }; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 66e0c598f96e..d790d6d9c33d 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1,3 +1,25 @@ +/* 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/script.h" #include "prince/prince.h" @@ -10,37 +32,37 @@ namespace Prince { static const uint16 NUM_OPCODES = 144; Script::Script(PrinceEngine *vm) : - _code(NULL), _stacktop(0), _vm(vm), _opcodeNF(false) { + _code(NULL), _stacktop(0), _vm(vm), _opcodeNF(false) { } Script::~Script() { - delete[] _code; + delete[] _code; } bool Script::loadFromStream(Common::SeekableReadStream &stream) { - _codeSize = stream.size(); - _code = new byte[_codeSize]; + _codeSize = stream.size(); + _code = new byte[_codeSize]; - if (!_code) - return false; + if (!_code) + return false; - stream.read(_code, _codeSize); - // Initialize the script - _currentInstruction = READ_LE_UINT32(_code + 4); + stream.read(_code, _codeSize); + // Initialize the script + _currentInstruction = READ_LE_UINT32(_code + 4); - return true; + return true; } void Script::debugScript(const char *s, ...) { - char buf[STRINGBUFLEN]; - va_list va; + char buf[STRINGBUFLEN]; + va_list va; - va_start(va, s); - vsnprintf(buf, STRINGBUFLEN, s, va); - va_end(va); + va_start(va, s); + vsnprintf(buf, STRINGBUFLEN, s, va); + va_end(va); Common::String str = Common::String::format("@0x%04X: ", _lastInstruction); - str += Common::String::format("op %02d: ", _lastOpcode); + str += Common::String::format("op %02d: ", _lastOpcode); debug("%s %s", str.c_str(), buf); } @@ -69,28 +91,28 @@ void Script::step() { } uint8 Script::getCodeByte(uint32 address) { - if (address >= _codeSize) - error("Trying to read a script byte at address 0x%04X, while the " - "script is just 0x%04X bytes long", address, _codeSize); - return _code[address]; + if (address >= _codeSize) + error("Trying to read a script byte at address 0x%04X, while the " + "script is just 0x%04X bytes long", address, _codeSize); + return _code[address]; } uint8 Script::readScript8bits() { - uint8 data = getCodeByte(_currentInstruction); - _currentInstruction++; - return data; + uint8 data = getCodeByte(_currentInstruction); + _currentInstruction++; + return data; } uint16 Script::readScript16bits() { - uint8 lower = readScript8bits(); - uint8 upper = readScript8bits(); - return lower | (upper << 8); + uint8 lower = readScript8bits(); + uint8 upper = readScript8bits(); + return lower | (upper << 8); } uint32 Script::readScript32bits() { - uint16 lower = readScript16bits(); - uint16 upper = readScript16bits(); - return lower | (upper << 16); + uint16 lower = readScript16bits(); + uint16 upper = readScript16bits(); + return lower | (upper << 16); } void Script::O_WAITFOREVER() { @@ -211,14 +233,14 @@ void Script::O__CALL() { debugScript("O__CALL 0x%04X", _currentInstruction); } void Script::O_RETURN() { - // Get the return address - if (_stacktop > 0) { - _stacktop--; - _currentInstruction = _stack[_stacktop]; + // Get the return address + if (_stacktop > 0) { + _stacktop--; + _currentInstruction = _stack[_stacktop]; debugScript("O_RETURN 0x%04X", _currentInstruction); - } else { - error("Return: Stack is empty"); - } + } else { + error("Return: Stack is empty"); + } } void Script::O_GO() { int32 opPC = readScript32bits(); diff --git a/engines/prince/script.h b/engines/prince/script.h index 982e7aae61f5..e801529187f0 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -33,8 +33,7 @@ namespace Prince { class PrinceEngine; -class Script -{ +class Script { public: Script(PrinceEngine *vm); virtual ~Script(); @@ -56,7 +55,8 @@ class Script bool _opcodeNF; // Stack - uint16 _stack[500]; + static const uint32 _STACK_SIZE = 500; + uint16 _stack[_STACK_SIZE]; uint8 _stacktop; uint8 _savedStacktop; From 84784add6811aa1b285b70e139d0bdf9738c858c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Mon, 28 Oct 2013 00:06:21 +0000 Subject: [PATCH 037/374] PRINCE: midi music player added. mob and object lists added --- engines/prince/debugger.cpp | 27 +++++ engines/prince/debugger.h | 2 + engines/prince/font.cpp | 20 ++-- engines/prince/graphics.cpp | 15 ++- engines/prince/graphics.h | 1 - engines/prince/mhwanh.h | 3 +- engines/prince/mob.cpp | 63 ++++++++++++ engines/prince/mob.h | 48 +++++++++ engines/prince/module.mk | 3 + engines/prince/object.cpp | 77 ++++++++++++++ engines/prince/object.h | 47 +++++++++ engines/prince/prince.cpp | 193 ++++++++++++++++++++++++++++++++++-- engines/prince/prince.h | 12 +++ engines/prince/script.cpp | 173 ++++++++++++++++++++++++++------ engines/prince/sound.cpp | 160 ++++++++++++++++++++++++++++++ engines/prince/sound.h | 73 ++++++++++++++ 16 files changed, 864 insertions(+), 53 deletions(-) create mode 100644 engines/prince/mob.cpp create mode 100644 engines/prince/mob.h create mode 100644 engines/prince/object.cpp create mode 100644 engines/prince/object.h create mode 100644 engines/prince/sound.cpp create mode 100644 engines/prince/sound.h diff --git a/engines/prince/debugger.cpp b/engines/prince/debugger.cpp index 5da11acd88ae..817e4fb2b5d9 100644 --- a/engines/prince/debugger.cpp +++ b/engines/prince/debugger.cpp @@ -31,6 +31,8 @@ Debugger::Debugger(PrinceEngine *vm) : GUI::Debugger(), _vm(vm) { DCmd_Register("getflag", WRAP_METHOD(Debugger, Cmd_GetFlag)); DCmd_Register("clearflag", WRAP_METHOD(Debugger, Cmd_ClearFlag)); DCmd_Register("viewflc", WRAP_METHOD(Debugger, Cmd_ViewFlc)); + DCmd_Register("initroom", WRAP_METHOD(Debugger, Cmd_InitRoom)); + DCmd_Register("changecursor", WRAP_METHOD(Debugger, Cmd_ChangeCursor)); } static int strToInt(const char *s) { @@ -108,4 +110,29 @@ bool Debugger::Cmd_ViewFlc(int argc, const char **argv) { _vm->loadAnim(flagNum); return true; } + +bool Debugger::Cmd_InitRoom(int argc, const char **argv) { + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + _vm->loadLocation(flagNum); + return true; +} + +bool Debugger::Cmd_ChangeCursor(int argc, const char **argv) { + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + _vm->changeCursor(flagNum); + return true; +} + } diff --git a/engines/prince/debugger.h b/engines/prince/debugger.h index c5a8be60c6e5..dabcd970eaeb 100644 --- a/engines/prince/debugger.h +++ b/engines/prince/debugger.h @@ -40,6 +40,8 @@ class Debugger : public GUI::Debugger { bool Cmd_GetFlag(int argc, const char **argv); bool Cmd_ClearFlag(int argc, const char **argv); bool Cmd_ViewFlc(int argc, const char **argv); + bool Cmd_InitRoom(int argc, const char **argv); + bool Cmd_ChangeCursor(int argc, const char **argv); PrinceEngine *_vm; }; diff --git a/engines/prince/font.cpp b/engines/prince/font.cpp index 8c72f1b91294..aac790dfe0d9 100644 --- a/engines/prince/font.cpp +++ b/engines/prince/font.cpp @@ -46,7 +46,6 @@ bool Font::load(Common::SeekableReadStream &stream) { } int Font::getFontHeight() const { - debug("Font::getFontHeight %d", _fontData[5]); return _fontData[5]; } @@ -70,15 +69,20 @@ int Font::getCharWidth(byte chr) const { return getChrData(chr)._width; } -void Font::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const { +void Font::drawChar(Graphics::Surface *dst, byte chr, int posX, int posY, uint32 color) const { const ChrData chrData = getChrData(chr); - const byte *src = chrData._pixels; - byte *target = (byte *)dst->getBasePtr(x, y); - for (int i = 0; i < chrData._height; i++) { - memcpy(target, src, chrData._width); - src += chrData._width; - target += dst->pitch; + for (int y = 0; y < chrData._height; ++y) { + for (int x = 0; x < chrData._width; ++x) { + byte d = chrData._pixels[x + (chrData._width * y)]; + if (d == 0) d = 255; + else if (d == 1) d = 0; + else if (d == 2) d = color; + else if (d == 3) d = 0; + if (d != 255) { + *(byte*)dst->getBasePtr(posX + x, posY + y) = d; + } + } } } diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 74b46aad4c77..94cab7bb3793 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -40,6 +40,7 @@ void GraphicsMan::update() { _vm->_system->copyRectToScreen((byte*)_frontScreen->getBasePtr(0,0), 640, 0, 0, 640, 480); _vm->_system->updateScreen(); + _changed = false; } } @@ -53,15 +54,19 @@ void GraphicsMan::change() { void GraphicsMan::draw(const Graphics::Surface *s) { - for (uint y = 0; y < 480; y++) - memcpy((byte*)_frontScreen->getBasePtr(0, y), (byte*)s->getBasePtr(0, y), 640); - change(); + uint16 w = MIN(_frontScreen->w, s->w); + for (uint y = 0; y < s->h; y++) { + if (y < _frontScreen->h) { + memcpy((byte*)_frontScreen->getBasePtr(0, y), (byte*)s->getBasePtr(0, y), w); + } + } + change(); } void GraphicsMan::drawTransparent(const Graphics::Surface *s) { - for (uint y = 0; y < 480; ++y) { - for (uint x = 0; x < 640; ++x) { + for (uint y = 0; y < s->h; ++y) { + for (uint x = 0; x < s->w; ++x) { byte pixel = *((byte*)s->getBasePtr(x,y)); if (pixel != 255) { *((byte*)_frontScreen->getBasePtr(x, y)) = pixel; diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index 0f12c734c6b6..0e29c5c97a38 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -53,7 +53,6 @@ class GraphicsMan PrinceEngine *_vm; bool _changed; - byte _palette[3 * 256]; }; } diff --git a/engines/prince/mhwanh.h b/engines/prince/mhwanh.h index 21822759e873..24472da7a523 100644 --- a/engines/prince/mhwanh.h +++ b/engines/prince/mhwanh.h @@ -28,8 +28,7 @@ namespace Prince { -class MhwanhDecoder : public Graphics::ImageDecoder -{ +class MhwanhDecoder : public Graphics::ImageDecoder { public: MhwanhDecoder(); virtual ~MhwanhDecoder(); diff --git a/engines/prince/mob.cpp b/engines/prince/mob.cpp new file mode 100644 index 000000000000..caf44fef12f2 --- /dev/null +++ b/engines/prince/mob.cpp @@ -0,0 +1,63 @@ +/* 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/mob.h" + +#include "common/stream.h" + +namespace Prince { + +bool Mob::loadFromStream(Common::SeekableReadStream &stream) { + int32 pos = stream.pos(); + + uint16 visible = stream.readUint16LE(); + + if (visible == 0xFFFF) + return false; + + _visible = visible; + _type = stream.readUint16LE(); + _rect.left = stream.readUint16LE(); + _rect.top = stream.readUint16LE(); + _rect.right = stream.readUint16LE(); + _rect.bottom = stream.readUint16LE(); + + stream.skip(6 * sizeof(uint16)); + uint32 nameOffset = stream.readUint32LE(); + uint32 examTextOffset = stream.readUint32LE(); + + byte c; + stream.seek(nameOffset); + _name.clear(); + while ((c = stream.readByte())) + _name += c; + + stream.seek(examTextOffset); + _examText.clear(); + while ((c = stream.readByte())) + _examText += c; + stream.seek(pos + 32); + + return true; +} + +} diff --git a/engines/prince/mob.h b/engines/prince/mob.h new file mode 100644 index 000000000000..5b2a6f9d6ef5 --- /dev/null +++ b/engines/prince/mob.h @@ -0,0 +1,48 @@ +/* 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/scummsys.h" +#include "common/rect.h" +#include "common/str.h" + +namespace Common { + class SeekableReadStream; +} + +namespace Prince { + +class Mob { +public: + Mob() {} + + bool loadFromStream(Common::SeekableReadStream &stream); + + + bool _visible; + uint16 _type; + Common::Rect _rect; + Common::String _name; + Common::String _examText; +}; + +} + diff --git a/engines/prince/module.mk b/engines/prince/module.mk index a177e670ed41..6b519d4d5751 100644 --- a/engines/prince/module.mk +++ b/engines/prince/module.mk @@ -7,6 +7,9 @@ MODULE_OBJS = \ mhwanh.o \ detection.o \ font.o \ + mob.o \ + object.o \ + sound.o \ prince.o # This module can be built as a plugin diff --git a/engines/prince/object.cpp b/engines/prince/object.cpp new file mode 100644 index 000000000000..72d4f1103a38 --- /dev/null +++ b/engines/prince/object.cpp @@ -0,0 +1,77 @@ +/* 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/archive.h" +#include "common/debug-channels.h" +#include "common/debug.h" +#include "common/stream.h" + + +#include "graphics/surface.h" + +#include "prince/object.h" + +namespace Prince { + +Object::Object() : _surface(NULL) { +} + +void Object::loadSurface(Common::SeekableReadStream &stream) { + stream.skip(4); + + _surface = new Graphics::Surface(); + _surface->create(stream.readUint16LE(), stream.readUint16LE(), Graphics::PixelFormat::createFormatCLUT8()); + for (int h = 0; h < _surface->h; ++h) { + stream.read(_surface->getBasePtr(0, h), _surface->w); + } + +} + +bool Object::loadFromStream(Common::SeekableReadStream &stream) { + + int32 pos = stream.pos(); + uint16 x = stream.readUint16LE(); + if (x == 0xFFFF) + return false; + _x = x; + _y = stream.readUint16LE(); + + const Common::String obStreamName = Common::String::format("OB%02d", stream.readUint16LE()); + Common::SeekableReadStream *obStream = SearchMan.createReadStreamForMember(obStreamName); + if (!obStream) { + error("Can't load %s", obStreamName.c_str()); + return false; + } + + loadSurface(*obStream); + delete obStream; + + _z = stream.readUint16LE(); + + stream.seek(pos + 16); + + debug("Object x %d, y %d, z %d", _x, _y, _z); + + return true; +} + +} diff --git a/engines/prince/object.h b/engines/prince/object.h new file mode 100644 index 000000000000..3a8859c196c8 --- /dev/null +++ b/engines/prince/object.h @@ -0,0 +1,47 @@ +/* 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_OBJECT_H +#define PRINCE_OBJECT_H + +#include "graphics/decoders/image_decoder.h" +#include "graphics/surface.h" + +namespace Prince { + +class Object { +public: + Object(); + + bool loadFromStream(Common::SeekableReadStream &stream); + Graphics::Surface *getSurface() const { return _surface; } + +private: + void loadSurface(Common::SeekableReadStream &stream); + + Graphics::Surface *_surface; + uint16 _x, _y, _z; +}; + +} + +#endif diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 4fb2082bafe0..a9f243ce11b5 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -47,17 +47,46 @@ #include "prince/graphics.h" #include "prince/script.h" #include "prince/debugger.h" +#include "prince/object.h" +#include "prince/mob.h" +#include "prince/sound.h" #include "video/flic_decoder.h" namespace Prince { +Graphics::Surface *loadCursor(const char *curName) +{ + Common::SeekableReadStream *curStream = SearchMan.createReadStreamForMember(curName); + if (!curStream) { + error("Can't load %s", curName); + return NULL; + } + + curStream->skip(4); + uint16 w = curStream->readUint16LE(); + uint16 h = curStream->readUint16LE(); + + debug("Loading cursor %s, w %d, h %d", curName, w, h); + + Graphics::Surface *curSurface = new Graphics::Surface(); + curSurface->create(w, h, Graphics::PixelFormat::createFormatCLUT8()); + for (int ih = 0; ih < h; ++ih) { + curStream->read(curSurface->getBasePtr(0, ih), w); + } + + delete curStream; + return curSurface; +} + + + PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL), - _locationNr(0), _debugger(NULL) { + _locationNr(0), _debugger(NULL), _objectList(NULL), _mobList(NULL), _midiPlayer(NULL) { _rnd = new Common::RandomSource("prince"); _debugger = new Debugger(this); - + _midiPlayer = new MusicPlayer(this); } PrinceEngine::~PrinceEngine() { @@ -65,6 +94,9 @@ PrinceEngine::~PrinceEngine() { delete _rnd; delete _debugger; + delete _cur1; + delete _cur2; + delete _midiPlayer; } GUI::Debugger *PrinceEngine::getDebugger() { @@ -108,23 +140,59 @@ Common::Error PrinceEngine::run() { delete skryptStream; - Common::SeekableReadStream *logoStrema = SearchMan.createReadStreamForMember("logo.raw"); - if (logoStrema) + + _cur1 = loadCursor("mouse1.cur"); + _cur2 = loadCursor("mouse2.cur"); + + Common::SeekableReadStream *logoStream = SearchMan.createReadStreamForMember("logo.raw"); + if (logoStream) { MhwanhDecoder logo; - logo.loadStream(*logoStrema); + logo.loadStream(*logoStream); _graph->setPalette(logo.getPalette()); _graph->draw(logo.getSurface()); _graph->update(); _system->delayMillis(700); } - delete logoStrema; + delete logoStream; mainLoop(); return Common::kNoError; } +class MobList { +public: + bool loadFromStream(Common::SeekableReadStream &stream); + + Common::Array _mobList; +}; + +bool MobList::loadFromStream(Common::SeekableReadStream &stream) +{ + Mob mob; + while (mob.loadFromStream(stream)) + _mobList.push_back(mob); + + return true; +} + +class ObjectList { +public: + bool loadFromStream(Common::SeekableReadStream &stream); + + Common::Array _objList; +}; + +bool ObjectList::loadFromStream(Common::SeekableReadStream &stream) +{ + Object obj; + while (obj.loadFromStream(stream)) + _objList.push_back(obj); + + return true; +} + bool PrinceEngine::loadLocation(uint16 locationNr) { debug("PrinceEngine::loadLocation %d", locationNr); const Common::FSNode gameDataDir(ConfMan.get("path")); @@ -145,14 +213,75 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { if(_roomBmp.loadStream(*room)) { debug("Room bitmap loaded"); - _system->getPaletteManager()->setPalette(_roomBmp.getPalette(), 0, 256); } delete room; + delete _mobList; + _mobList = NULL; + + Common::SeekableReadStream *mobListStream = SearchMan.createReadStreamForMember("mob.lst"); + if (!mobListStream) { + error("Can't read mob.lst"); + return false; + } + + _mobList = new MobList(); + _mobList->loadFromStream(*mobListStream); + + delete mobListStream; + + delete _objectList; + _objectList = NULL; + + Common::SeekableReadStream *objListStream = SearchMan.createReadStreamForMember("obj.lst"); + if (!objListStream) { + error("Can't read obj.lst"); + return false; + } + + _objectList = new ObjectList(); + _objectList->loadFromStream(*objListStream); + delete objListStream; + + const char *musName = MusicPlayer::_musTable[MusicPlayer::_musRoomTable[locationNr]]; + _midiPlayer->loadMidi(musName); + return true; } +void PrinceEngine::changeCursor(uint16 curId) +{ + Graphics::Surface *curSurface = NULL; + + uint16 hotspotX = 0; + uint16 hotspotY = 0; + + switch(curId) { + case 0: + CursorMan.showMouse(false); + return; + case 1: + curSurface = _cur1; + break; + case 2: + curSurface = _cur2; + hotspotX = curSurface->w >> 1; + hotspotY = curSurface->h >> 1; + break; + } + + CursorMan.replaceCursorPalette(_roomBmp.getPalette(), 0, 255); + CursorMan.replaceCursor( + curSurface->getBasePtr(0, 0), + curSurface->w, curSurface->h, + hotspotX, hotspotY, + 255, false, + &curSurface->format + ); + CursorMan.showMouse(true); +} + bool PrinceEngine::playNextFrame() { const Graphics::Surface *s = _flicPlayer.decodeNextFrame(); if (s) { @@ -193,9 +322,46 @@ void PrinceEngine::keyHandler(Common::Event event) { } } +void PrinceEngine::hotspot() { + Common::Point mousepos = _system->getEventManager()->getMousePos(); + + Common::Array::iterator it = _mobList->_mobList.begin(); + for (; it != _mobList->_mobList.end(); ++it) { + if (it->_visible) + continue; + if (it->_rect.contains(mousepos)) { + uint16 textW = 0; + for (int i = 0; i < it->_name.size(); ++i) + textW += _font.getCharWidth(it->_name[i]); + + uint16 x = mousepos.x - textW/2; + if (x > _graph->_frontScreen->w) + x = 0; + + if (x + textW > _graph->_frontScreen->w) + x = _graph->_frontScreen->w - textW; + + _font.drawString( + _graph->_frontScreen, + it->_name, + x, + mousepos.y - _font.getFontHeight(), + _graph->_frontScreen->w, + 216 + ); + break; + } + } +} + void PrinceEngine::mainLoop() { + loadLocation(1); + changeCursor(1); + CursorMan.showMouse(true); + while (!shouldQuit()) { + _debugger->onFrame(); Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); while (eventMan->pollEvent(event)) { @@ -223,13 +389,22 @@ void PrinceEngine::mainLoop() { if (shouldQuit()) return; - _script->step(); + //_script->step(); - if (_roomBmp.getSurface()) + if (_roomBmp.getSurface()) { + _graph->setPalette(_roomBmp.getPalette()); _graph->draw(_roomBmp.getSurface()); + } playNextFrame(); + //debug("Cursor visible %d", CursorMan.isVisible()); + + //if (_objectList) + // _graph->drawTransparent(_objectList->getSurface()); + + hotspot(); + _graph->update(); _system->delayMillis(40); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index b289c75553a7..6340733255c5 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -53,6 +53,9 @@ class PrinceEngine; class GraphicsMan; class Script; class Debugger; +class ObjectList; +class MobList; +class MusicPlayer; class PrinceEngine : public Engine { protected: @@ -77,19 +80,28 @@ class PrinceEngine : public Engine { virtual GUI::Debugger *getDebugger(); + void changeCursor(uint16 curId); + private: bool playNextFrame(); void keyHandler(Common::Event event); + void hotspot(); Common::RandomSource *_rnd; Graphics::BitmapDecoder _roomBmp; uint16 _locationNr; MhwanhDecoder _walizkaBmp; + Graphics::Surface *_cur1; + Graphics::Surface *_cur2; + Debugger *_debugger; GraphicsMan *_graph; Script *_script; Font _font; + ObjectList *_objectList; + MobList *_mobList; + MusicPlayer *_midiPlayer; void mainLoop(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index d790d6d9c33d..e2360debc8c2 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -206,24 +206,48 @@ void Script::O_REMBACKANIM() { debugScript("O_REMBACKANIM roomId %d, slot %d", roomId, slot); } -void Script::O_CHECKBACKANIMFRAME() {} +void Script::O_CHECKBACKANIMFRAME() { + uint16 slotId = readScript16bits(); + uint16 frameId = readScript16bits(); -void Script::O_FREEALLSAMPLES() {} + debugScript("O_CHECKBACKANIMFRAME slotId %d, frameId %d", slotId, frameId); +} -void Script::O_SETMUSIC() {} +void Script::O_FREEALLSAMPLES() { + debugScript("O_FREEALLSAMPLES"); +} -void Script::O_STOPMUSIC() {} +void Script::O_SETMUSIC() { + uint16 musicId = readScript16bits(); -void Script::O__WAIT() {} + debugScript("O_SETMUSIC musicId %d", musicId); +} -void Script::O_UPDATEOFF() {} +void Script::O_STOPMUSIC() { + debugScript("O_STOPMUSIC"); +} -void Script::O_UPDATEON() {} +void Script::O__WAIT() { + uint16 pause = readScript16bits(); -void Script::O_UPDATE () {} + debugScript("O__WAIT pause %d", pause); +} -void Script::O_CLS() {} +void Script::O_UPDATEOFF() { + debugScript("O_UPDATEOFF"); +} +void Script::O_UPDATEON() { + debugScript("O_UPDATEON"); +} + +void Script::O_UPDATE () { + debugScript("O_UPDATE"); +} + +void Script::O_CLS() { + debugScript("O_CLS"); +} void Script::O__CALL() { int32 address = readScript32bits(); @@ -247,7 +271,10 @@ void Script::O_GO() { debugScript("O_GO 0x%04X", opPC); _currentInstruction += opPC - 4; } -void Script::O_BACKANIMUPDATEOFF() {} +void Script::O_BACKANIMUPDATEOFF() { + uint16 slotId = readScript32bits(); + debugScript("O_BACKANIMUPDATEOFF slotId %d", slotId); +} void Script::O_BACKANIMUPDATEON() { uint16 slot = readScript16bits(); @@ -258,26 +285,39 @@ void Script::O_CHANGECURSOR() { uint16 cursorId = readScript16bits(); debugScript("O_CHANGECURSOR %x", cursorId); } -void Script::O_CHANGEANIMTYPE() {} + +void Script::O_CHANGEANIMTYPE() { + // NOT IMPLEMENTED +} + void Script::O__SETFLAG() { uint16 flagId = readScript16bits(); uint16 value = readScript16bits(); + + if (value & 0x8000) { + value = _flags[value - 0x8000]; + } + debugScript("O__SETFLAG 0x%04X %d", flagId, value); - _flags[flagId-0x8000] = value; + _flags[flagId - 0x8000] = value; } void Script::O_COMPARE() { uint16 flagId = readScript16bits(); uint16 value = readScript16bits(); + + if (value & 0x8000) { + value = _flags[value - 0x8000]; + } + debugScript("O_COMPARE flagId 0x%04X, value %d", flagId, value); - _result = (_flags[flagId-0x8000] == value); + _result = (_flags[flagId - 0x8000] == value); } void Script::O_JUMPZ() { int32 offset = readScript32bits(); debugScript("O_JUMPZ offset 0x%04X", offset); - if (_result == 0) - { + if (! _result) { _currentInstruction += offset - 4; } } @@ -285,20 +325,26 @@ void Script::O_JUMPZ() { void Script::O_JUMPNZ() { int32 offset = readScript32bits(); debugScript("O_JUMPNZ offset 0x%04X", offset); - if (_result) - { + if (_result) { _currentInstruction += offset - 4; } } -void Script::O_EXIT() {} +void Script::O_EXIT() { + uint16 exitCode = readScript16bits(); + debugScript("O_EXIT exitCode %d", exitCode); +} void Script::O_ADDFLAG() { uint16 flagId = readScript16bits(); uint16 value = readScript16bits(); - _flags[flagId-0x8000] += value; - if (_flags[flagId-0x8000]) + if (value & 0x8000) { + value = _flags[value - 0x8000]; + } + + _flags[flagId - 0x8000] += value; + if (_flags[flagId - 0x8000]) _result = 1; else _result = 0; @@ -317,8 +363,12 @@ void Script::O_SUBFLAG() { uint16 flagId = readScript16bits(); uint16 value = readScript16bits(); - _flags[flagId-0x8000] -= value; - if (_flags[flagId-0x8000]) + if (value & 0x8000) { + value = _flags[value - 0x8000]; + } + + _flags[flagId - 0x8000] -= value; + if (_flags[flagId - 0x8000]) _result = 1; else _result = 0; @@ -332,17 +382,84 @@ void Script::O_SETSTRING() { debugScript("O_SETSTRING 0x%04X", offset); } -void Script::O_ANDFLAG() {} +void Script::O_ANDFLAG() { + uint16 flagId = readScript16bits(); + uint16 value = readScript16bits(); -void Script::O_GETMOBDATA() {} + debugScript("O_ANDFLAG flagId %d, value %d", flagId, value); -void Script::O_ORFLAG() {} + if (value & 0x8000) { + value = _flags[value - 0x8000]; + } -void Script::O_SETMOBDATA() {} + _flags[flagId - 0x8000] &= value; -void Script::O_XORFLAG() {} + if (_flags[flagId - 0x8000]) { + _result = 1; + } else { + _result = 0; + } +} -void Script::O_GETMOBTEXT() {} +void Script::O_GETMOBDATA() { + uint16 flagId = readScript16bits(); + uint16 mobId = readScript16bits(); + uint16 mobOffset = readScript16bits(); + + debugScript("O_GETMOBDATA flagId %d, modId %d, mobOffset %d", flagId, mobId, mobOffset); +} + +void Script::O_ORFLAG() { + uint16 flagId = readScript16bits(); + uint16 value = readScript16bits(); + + debugScript("O_ORFLAG flagId %d, value %d", flagId, value); + + if (value & 0x8000) { + value = _flags[value - 0x8000]; + } + + _flags[flagId - 0x8000] |= value; + + if (_flags[flagId - 0x8000]) { + _result = 1; + } else { + _result = 0; + } +} + +void Script::O_SETMOBDATA() { + uint16 mobId = readScript16bits(); + uint16 mobOffset = readScript16bits(); + uint16 value = readScript16bits(); + + debugScript("O_SETMOBDATA mobId %d, mobOffset %d, value %d", mobId, mobOffset, value); +} + +void Script::O_XORFLAG() { + uint16 flagId = readScript16bits(); + uint16 value = readScript16bits(); + + debugScript("O_XORFLAG flagId %d, value %d", flagId, value); + + if (value & 0x8000) { + value = _flags[value - 0x8000]; + } + + _flags[flagId - 0x8000] ^= value; + + if (_flags[flagId - 0x8000]) { + _result = 1; + } else { + _result = 0; + } +} + +void Script::O_GETMOBTEXT() { + uint16 value = readScript16bits(); + + debugScript("O_GETMOBTEXT value %d", value); +} void Script::O_MOVEHERO() { uint16 heroId = readScript16bits(); diff --git a/engines/prince/sound.cpp b/engines/prince/sound.cpp new file mode 100644 index 000000000000..2e2e53e664d6 --- /dev/null +++ b/engines/prince/sound.cpp @@ -0,0 +1,160 @@ +/* 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. + * + */ + +/* + * This code is based on original Soltys source code + * Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon + */ + +#include "prince/prince.h" +#include "prince/sound.h" +#include "common/config-manager.h" +#include "common/memstream.h" +#include "common/archive.h" +#include "audio/decoders/raw.h" +#include "audio/audiostream.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, + 3, + 9, + 9, + 9, + 13, + 9, + 9 +}; + + +MusicPlayer::MusicPlayer(PrinceEngine *vm) : _vm(vm) { + _data = NULL; + _isGM = false; + + MidiPlayer::createDriver(); + + int ret = _driver->open(); + if (ret == 0) { + if (_nativeMT32) + _driver->sendMT32Reset(); + else + _driver->sendGMReset(); + + // TODO: Load cmf.ins with the instrument table. It seems that an + // interface for such an operation is supported for AdLib. Maybe for + // this card, setting instruments is necessary. + + _driver->setTimerCallback(this, &timerCallback); + } +} + +MusicPlayer::~MusicPlayer() { + killMidi(); +} + +void MusicPlayer::killMidi() { + Audio::MidiPlayer::stop(); + + free(_data); + _data = NULL; +} + +void MusicPlayer::loadMidi(const char * name) { + Common::SeekableReadStream * stream = SearchMan.createReadStreamForMember(name); + if (!stream) + 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); + + // 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 CGE diff --git a/engines/prince/sound.h b/engines/prince/sound.h new file mode 100644 index 000000000000..779fe563f942 --- /dev/null +++ b/engines/prince/sound.h @@ -0,0 +1,73 @@ +/* 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. + * + */ + +/* + * This code is based on original Soltys source code + * Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon + */ + +#ifndef PRINCE_SOUND_H +#define PRINCE_SOUND_H + +#include "audio/audiostream.h" +#include "audio/decoders/wave.h" +#include "audio/fmopl.h" +#include "audio/mididrv.h" +#include "audio/midiparser.h" +#include "audio/midiplayer.h" +#include "audio/mixer.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 + From 39265b7a4b3e39348165b126ae53c9d89ccf32a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Mon, 28 Oct 2013 17:06:12 +0000 Subject: [PATCH 038/374] PRINCE: replace space with tabs in indent --- engines/prince/debugger.cpp | 148 ++++++++++++++++++------------------ engines/prince/debugger.h | 20 ++--- engines/prince/sound.cpp | 26 +++---- engines/prince/sound.h | 28 +++---- 4 files changed, 111 insertions(+), 111 deletions(-) diff --git a/engines/prince/debugger.cpp b/engines/prince/debugger.cpp index 817e4fb2b5d9..1a78049f9151 100644 --- a/engines/prince/debugger.cpp +++ b/engines/prince/debugger.cpp @@ -26,113 +26,113 @@ namespace Prince { Debugger::Debugger(PrinceEngine *vm) : GUI::Debugger(), _vm(vm) { - DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); - DCmd_Register("setflag", WRAP_METHOD(Debugger, Cmd_SetFlag)); - DCmd_Register("getflag", WRAP_METHOD(Debugger, Cmd_GetFlag)); - DCmd_Register("clearflag", WRAP_METHOD(Debugger, Cmd_ClearFlag)); - DCmd_Register("viewflc", WRAP_METHOD(Debugger, Cmd_ViewFlc)); - DCmd_Register("initroom", WRAP_METHOD(Debugger, Cmd_InitRoom)); - DCmd_Register("changecursor", WRAP_METHOD(Debugger, Cmd_ChangeCursor)); + DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); + DCmd_Register("setflag", WRAP_METHOD(Debugger, Cmd_SetFlag)); + DCmd_Register("getflag", WRAP_METHOD(Debugger, Cmd_GetFlag)); + DCmd_Register("clearflag", WRAP_METHOD(Debugger, Cmd_ClearFlag)); + DCmd_Register("viewflc", WRAP_METHOD(Debugger, Cmd_ViewFlc)); + DCmd_Register("initroom", WRAP_METHOD(Debugger, Cmd_InitRoom)); + DCmd_Register("changecursor", WRAP_METHOD(Debugger, Cmd_ChangeCursor)); } static int strToInt(const char *s) { - if (!*s) - // No string at all - return 0; - else if (toupper(s[strlen(s) - 1]) != 'H') - // Standard decimal string - return atoi(s); - - // Hexadecimal string - uint tmp = 0; - int read = sscanf(s, "%xh", &tmp); - if (read < 1) - error("strToInt failed on string \"%s\"", s); - return (int)tmp; + if (!*s) + // No string at all + return 0; + else if (toupper(s[strlen(s) - 1]) != 'H') + // Standard decimal string + return atoi(s); + + // Hexadecimal string + uint tmp = 0; + int read = sscanf(s, "%xh", &tmp); + if (read < 1) + error("strToInt failed on string \"%s\"", s); + return (int)tmp; } /* * This command sets a flag */ bool Debugger::Cmd_SetFlag(int argc, const char **argv) { - // Check for a flag to set - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } - - int flagNum = strToInt(argv[1]); - //g_globals->setFlag(flagNum); - return true; + // Check for a flag to set + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + //g_globals->setFlag(flagNum); + return true; } /* * This command gets the value of a flag */ bool Debugger::Cmd_GetFlag(int argc, const char **argv) { - // Check for an flag to display - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } - - int flagNum = strToInt(argv[1]); - //DebugPrintf("Value: %d\n", g_globals->getFlag(flagNum)); - return true; + // Check for an flag to display + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + //DebugPrintf("Value: %d\n", g_globals->getFlag(flagNum)); + return true; } /* * This command clears a flag */ bool Debugger::Cmd_ClearFlag(int argc, const char **argv) { - // Check for a flag to clear - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } - - int flagNum = strToInt(argv[1]); - //g_globals->clearFlag(flagNum); - return true; + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + //g_globals->clearFlag(flagNum); + return true; } /* * This command starts new flc anim */ bool Debugger::Cmd_ViewFlc(int argc, const char **argv) { - // Check for a flag to clear - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } - - int flagNum = strToInt(argv[1]); - _vm->loadAnim(flagNum); - return true; + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + _vm->loadAnim(flagNum); + return true; } bool Debugger::Cmd_InitRoom(int argc, const char **argv) { - // Check for a flag to clear - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } - - int flagNum = strToInt(argv[1]); - _vm->loadLocation(flagNum); - return true; + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + _vm->loadLocation(flagNum); + return true; } bool Debugger::Cmd_ChangeCursor(int argc, const char **argv) { - // Check for a flag to clear - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } - - int flagNum = strToInt(argv[1]); - _vm->changeCursor(flagNum); - return true; + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + _vm->changeCursor(flagNum); + return true; } } diff --git a/engines/prince/debugger.h b/engines/prince/debugger.h index dabcd970eaeb..087f29e550e8 100644 --- a/engines/prince/debugger.h +++ b/engines/prince/debugger.h @@ -32,18 +32,18 @@ class PrinceEngine; class Debugger : public GUI::Debugger { public: - Debugger(PrinceEngine *vm); - virtual ~Debugger() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ + Debugger(PrinceEngine *vm); + virtual ~Debugger() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ private: - bool Cmd_SetFlag(int argc, const char **argv); - bool Cmd_GetFlag(int argc, const char **argv); - bool Cmd_ClearFlag(int argc, const char **argv); - bool Cmd_ViewFlc(int argc, const char **argv); - bool Cmd_InitRoom(int argc, const char **argv); - bool Cmd_ChangeCursor(int argc, const char **argv); - - PrinceEngine *_vm; + bool Cmd_SetFlag(int argc, const char **argv); + bool Cmd_GetFlag(int argc, const char **argv); + bool Cmd_ClearFlag(int argc, const char **argv); + bool Cmd_ViewFlc(int argc, const char **argv); + bool Cmd_InitRoom(int argc, const char **argv); + bool Cmd_ChangeCursor(int argc, const char **argv); + + PrinceEngine *_vm; }; diff --git a/engines/prince/sound.cpp b/engines/prince/sound.cpp index 2e2e53e664d6..3285390aca6e 100644 --- a/engines/prince/sound.cpp +++ b/engines/prince/sound.cpp @@ -36,7 +36,7 @@ namespace Prince { const char * MusicPlayer::_musTable[] = { - "", + "", "Battlfld.mid", "Cave.mid", "Cemetery.mid", @@ -56,14 +56,14 @@ const char * MusicPlayer::_musTable[] = { }; const uint8 MusicPlayer::_musRoomTable[] = { - 0, - 3, - 9, - 9, - 9, - 13, - 9, - 9 + 0, + 3, + 9, + 9, + 9, + 13, + 9, + 9 }; @@ -81,7 +81,7 @@ MusicPlayer::MusicPlayer(PrinceEngine *vm) : _vm(vm) { _driver->sendGMReset(); // TODO: Load cmf.ins with the instrument table. It seems that an - // interface for such an operation is supported for AdLib. Maybe for + // interface for such an operation is supported for AdLib. Maybe for // this card, setting instruments is necessary. _driver->setTimerCallback(this, &timerCallback); @@ -100,8 +100,8 @@ void MusicPlayer::killMidi() { } void MusicPlayer::loadMidi(const char * name) { - Common::SeekableReadStream * stream = SearchMan.createReadStreamForMember(name); - if (!stream) + Common::SeekableReadStream * stream = SearchMan.createReadStreamForMember(name); + if (!stream) return; // Stop any currently playing MIDI file @@ -110,7 +110,7 @@ void MusicPlayer::loadMidi(const char * name) { // Read in the data for the file _dataSize = stream->size(); _data = (byte *)malloc(_dataSize); - stream->read(_data, _dataSize); + stream->read(_data, _dataSize); // Start playing the music sndMidiStart(); diff --git a/engines/prince/sound.h b/engines/prince/sound.h index 779fe563f942..f4ba9ba45f82 100644 --- a/engines/prince/sound.h +++ b/engines/prince/sound.h @@ -43,25 +43,25 @@ class PrinceEngine; class MusicPlayer: public Audio::MidiPlayer { private: - PrinceEngine *_vm; - byte *_data; - int _dataSize; - bool _isGM; + PrinceEngine *_vm; + byte *_data; + int _dataSize; + bool _isGM; - // Start MIDI File - void sndMidiStart(); + // Start MIDI File + void sndMidiStart(); - // Stop MIDI File - void sndMidiStop(); + // Stop MIDI File + void sndMidiStop(); public: - MusicPlayer(PrinceEngine *vm); - ~MusicPlayer(); + MusicPlayer(PrinceEngine *vm); + ~MusicPlayer(); - void loadMidi(const char *); - void killMidi(); + void loadMidi(const char *); + void killMidi(); - virtual void send(uint32 b); - virtual void sendToChannel(byte channel, uint32 b); + virtual void send(uint32 b); + virtual void sendToChannel(byte channel, uint32 b); static const char * _musTable[]; static const uint8 _musRoomTable[]; From 25fbc0617f31540e526f2b29162f4e240b97e3a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Wed, 30 Oct 2013 02:24:41 +0000 Subject: [PATCH 039/374] PRINCE: script support extended --- engines/prince/flags.cpp | 410 ++++++++++++++++++++++++++++++++++++ engines/prince/flags.h | 409 +++++++++++++++++++++++++++++++++++ engines/prince/musNum.h | 92 ++++++++ engines/prince/variatxt.cpp | 59 ++++++ engines/prince/variatxt.h | 44 ++++ 5 files changed, 1014 insertions(+) create mode 100644 engines/prince/flags.cpp create mode 100644 engines/prince/flags.h create mode 100644 engines/prince/musNum.h create mode 100644 engines/prince/variatxt.cpp create mode 100644 engines/prince/variatxt.h diff --git a/engines/prince/flags.cpp b/engines/prince/flags.cpp new file mode 100644 index 000000000000..5fb93ac4b1f9 --- /dev/null +++ b/engines/prince/flags.cpp @@ -0,0 +1,410 @@ +/* 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/flags.h" + +namespace Prince { + +const char * Flags::getFlagName(uint16 flagId) +{ + switch (flagId) { + default: return "unknown_flag"; + case FLAGA1: return "FLAGA1"; + case FLAGA2: return "FLAGA2"; + case FLAGA3: return "FLAGA3"; + case DESTX: return "DESTX"; + case DESTY: return "DESTY"; + case DESTD: return "DESTD"; + case DwarfDone: return "DwarfDone"; + case GRABARZCOUNTER: return "GRABARZCOUNTER"; + case KIERUNEK: return "KIERUNEK"; + case BACKFLAG1: return "BACKFLAG1"; + case BACKFLAG2: return "BACKFLAG2"; + case BACKFLAG3: return "BACKFLAG3"; + case BACKFLAG4: return "BACKFLAG4"; + case MACROFLAG1: return "MACROFLAG1"; + case MACROFLAG2: return "MACROFLAG2"; + case MACROFLAG3: return "MACROFLAG3"; + case HEROLDDONE: return "HEROLDDONE"; + case BRIDGESET: return "BRIDGESET"; + case U_BT_1: return "U_BT_1"; + case U_BT_2: return "U_BT_2"; + case U_BT_3: return "U_BT_3"; + case U_BT_4: return "U_BT_4"; + case U_BT_5: return "U_BT_5"; + case U_BT_6: return "U_BT_6"; + case U_BT_7: return "U_BT_7"; + case U_BT_8: return "U_BT_8"; + case U_BT_9: return "U_BT_9"; + case U_BT_COUNTER: return "U_BT_COUNTER"; + case ARIVALDALIVE: return "ARIVALDALIVE"; + case TALKCHAR1: return "TALKCHAR1"; + case TalkType1: return "TalkType1"; + case TALKROUT1: return "TALKROUT1"; + case TALKROUT2: return "TALKROUT2"; + case TALKROUT3: return "TALKROUT3"; + case TALKROUT4: return "TALKROUT4"; + case TALKANIM1: return "TALKANIM1"; + case TALKANIM2: return "TALKANIM2"; + case TALKCOLOR1: return "TALKCOLOR1"; + case TALKCOLOR2: return "TALKCOLOR2"; + case KapciuchTaken: return "KapciuchTaken"; + case CurrentBeggarA: return "CurrentBeggarA"; + case TempKapc: return "TempKapc"; + case HomTaken: return "HomTaken"; + case WizardTalk: return "WizardTalk"; + case SunlordTalk: return "SunlordTalk"; + case HermitTalk: return "HermitTalk"; + case RunyMode: return "RunyMode"; + case FatMerchantTalk: return "FatMerchantTalk"; + case HotDogTalk: return "HotDogTalk"; + case ThiefTalk: return "ThiefTalk"; + case BeggarTalk: return "BeggarTalk"; + case MonkTalk: return "MonkTalk"; + case BardTalk: return "BardTalk"; + case BarmanTalk: return "BarmanTalk"; + case LeftPlayerTalk: return "LeftPlayerTalk"; + case OczySowy: return "OczySowy"; + case CzachySpeed1: return "CzachySpeed1"; + case CzachySpeed2: return "CzachySpeed2"; + case CzachySpeed3: return "CzachySpeed3"; + case CzachySlowDown1: return "CzachySlowDown1"; + case CzachySlowDown2: return "CzachySlowDown2"; + case CzachySlowDown3: return "CzachySlowDown3"; + case FjordDane: return "FjordDane"; + case GKopany1: return "GKopany1"; + case GKopany2: return "GKopany2"; + case GKopany3: return "GKopany3"; + case GKopany4: return "GKopany4"; + case KnowGodWord: return "KnowGodWord"; + case TALKROUT21: return "TALKROUT21"; + case TALKROUT22: return "TALKROUT22"; + case TALKROUT23: return "TALKROUT23"; + case TALKROUT24: return "TALKROUT24"; + case TalkType2: return "TalkType2"; + case GrabarzTalk: return "GrabarzTalk"; + case LastTalker: return "LastTalker"; + case MapaPustelniaEnabled: return "MapaPustelniaEnabled"; + case MapaTempleEnabled: return "MapaTempleEnabled"; + case MapaFjordEnabled: return "MapaFjordEnabled"; + case MapaSilmanionaEnabled: return "MapaSilmanionaEnabled"; + case MapaKurhanEnabled: return "MapaKurhanEnabled"; + case MapaDragonEnabled: return "MapaDragonEnabled"; + case MapaMillEnabled: return "MapaMillEnabled"; + case DwarfRunning: return "DwarfRunning"; + case DwarfTalk: return "DwarfTalk"; + case CurseLift: return "CurseLift"; + case KosciSwapped: return "KosciSwapped"; + case BookStolen: return "BookStolen"; + case MapaUsable: return "MapaUsable"; + case FjordBoss: return "FjordBoss"; + case FjordHotDog: return "FjordHotDog"; + case FjordLewy: return "FjordLewy"; + case FjordPrawy: return "FjordPrawy"; + case TalkArivald: return "TalkArivald"; + case ShootDone: return "ShootDone"; + case ShootRunning: return "ShootRunning"; + case ShootKnow: return "ShootKnow"; + case MirrorKnow: return "MirrorKnow"; + case Gar1stTime: return "Gar1stTime"; + case KosciTaken: return "KosciTaken"; + case ArivGotSpell: return "ArivGotSpell"; + case BookGiven: return "BookGiven"; + case Wywieszka: return "Wywieszka"; + case TalkSheila: return "TalkSheila"; + case TalkSheila2: return "TalkSheila2"; + case BackHuman: return "BackHuman"; + case SkarbiecOpen: return "SkarbiecOpen"; + case LustroTaken: return "LustroTaken"; + case GargoyleHom: return "GargoyleHom"; + case GargoyleBroken: return "GargoyleBroken"; + case FjordDzien: return "FjordDzien"; + case GargoyleHom2: return "GargoyleHom2"; + case RunMonstersRunning: return "RunMonstersRunning"; + case FoundPaperInCoffin: return "FoundPaperInCoffin"; + case KnowSunlord: return "KnowSunlord"; + case KnowSunlordTalk: return "KnowSunlordTalk"; + case ArivaldCzyta: return "ArivaldCzyta"; + case TelepX: return "TelepX"; + case TelepY: return "TelepY"; + case TelepDir: return "TelepDir"; + case TelepRoom: return "TelepRoom"; + case ListStolen: return "ListStolen"; + case WifeInDoor: return "WifeInDoor"; + case TalkWifeFlag: return "TalkWifeFlag"; + case LetterGiven: return "LetterGiven"; + case LutniaTaken: return "LutniaTaken"; + case BardHomeOpen: return "BardHomeOpen"; + case FjordNoMonsters: return "FjordNoMonsters"; + case ShandriaWallTalking: return "ShandriaWallTalking"; + case ShandriaWallCounter: return "ShandriaWallCounter"; + case ShandriaWallDone: return "ShandriaWallDone"; + case FutureDone: return "FutureDone"; + case TalkButch: return "TalkButch"; + case GotSzalik: return "GotSzalik"; + case GotCzosnek: return "GotCzosnek"; + case BearDone: return "BearDone"; + case NekrVisited: return "NekrVisited"; + case SunRiddle: return "SunRiddle"; + case PtaszekAway: return "PtaszekAway"; + case KotGadanie: return "KotGadanie"; + case SzlafmycaTaken: return "SzlafmycaTaken"; + case BabkaTalk: return "BabkaTalk"; + case SellerTalk: return "SellerTalk"; + case CzosnekDone: return "CzosnekDone"; + case PriestCounter: return "PriestCounter"; + case PriestGest1: return "PriestGest1"; + case PriestGest2: return "PriestGest2"; + case PriestGest3: return "PriestGest3"; + case PriestGest4: return "PriestGest4"; + case PriestAnim: return "PriestAnim"; + case HolyWaterTaken: return "HolyWaterTaken"; + case AxeTaken: return "AxeTaken"; + case BadylTaken1: return "BadylTaken1"; + case BadylTaken2: return "BadylTaken2"; + case BadylSharpened: return "BadylSharpened"; + case PorwanieSmoka: return "PorwanieSmoka"; + case ShopReOpen: return "ShopReOpen"; + case LuskaShown: return "LuskaShown"; + case CudKnow: return "CudKnow"; + case VampireDead: return "VampireDead"; + case MapaVisible1: return "MapaVisible1"; + case MapaVisible2: return "MapaVisible2"; + case MapaVisible3: return "MapaVisible3"; + case MapaVisible4: return "MapaVisible4"; + case MapaVisible5: return "MapaVisible5"; + case MapaVisible6: return "MapaVisible6"; + case MapaVisible7: return "MapaVisible7"; + case MapaVisible8: return "MapaVisible8"; + case MapaVisible9: return "MapaVisible9"; + case MapaX: return "MapaX"; + case MapaY: return "MapaY"; + case MapaD: return "MapaD"; + case OldMapaX: return "OldMapaX"; + case OldMapaY: return "OldMapaY"; + case OldMapaD: return "OldMapaD"; + case MovingBack: return "MovingBack"; + case MapaCount: return "MapaCount"; + case Pustelnia1st: return "Pustelnia1st"; + case CzarnePole1st: return "CzarnePole1st"; + case TalkArivNum: return "TalkArivNum"; + case Pfui: return "Pfui"; + case MapaSunlordEnabled: return "MapaSunlordEnabled"; + case WebDone: return "WebDone"; + case DragonDone: return "DragonDone"; + case KanPlay: return "KanPlay"; + case OldKanPlay: return "OldKanPlay"; + case LapkiWait: return "LapkiWait"; + case WebNoCheck: return "WebNoCheck"; + case Perfumeria: return "Perfumeria"; + case SmokNoCheck: return "SmokNoCheck"; + case IluzjaBroken: return "IluzjaBroken"; + case IluzjaWorking: return "IluzjaWorking"; + case IluzjaCounter: return "IluzjaCounter"; + case KurhanOpen1: return "KurhanOpen1"; + case KastetTaken: return "KastetTaken"; + case KastetDown: return "KastetDown"; + case KurhanDone: return "KurhanDone"; + case SkelCounter: return "SkelCounter"; + case SkelDial1: return "SkelDial1"; + case SkelDial2: return "SkelDial2"; + case SkelDial3: return "SkelDial3"; + case SkelDial4: return "SkelDial4"; + case SameTalker: return "SameTalker"; + case RunMonstersText: return "RunMonstersText"; + case PiwnicaChecked: return "PiwnicaChecked"; + case DragonTalked: return "DragonTalked"; + case ToldAboutBook: return "ToldAboutBook"; + case SilmanionaDone: return "SilmanionaDone"; + case ToldBookCount: return "ToldBookCount"; + case SmrodNoCheck: return "SmrodNoCheck"; + case RopeTaken: return "RopeTaken"; + case RopeTime: return "RopeTime"; + case LaskaFree: return "LaskaFree"; + case ShanSmokTalked: return "ShanSmokTalked"; + case SwordTaken: return "SwordTaken"; + case Mill1st: return "Mill1st"; + case SawRat: return "SawRat"; + case KnowRat: return "KnowRat"; + case DziuraTimer: return "DziuraTimer"; + case LaskaInside: return "LaskaInside"; + case HoleBig: return "HoleBig"; + case EnableWiedzmin: return "EnableWiedzmin"; + case EnableTrucizna: return "EnableTrucizna"; + case KnowPoison: return "KnowPoison"; + case KufelTaken: return "KufelTaken"; + case BojkaEnabled: return "BojkaEnabled"; + case BitwaNot1st: return "BitwaNot1st"; + case BojkaTimer: return "BojkaTimer"; + case BojkaGirl: return "BojkaGirl"; + case Look1st: return "Look1st"; + case RatTaken: return "RatTaken"; + case LaskaTalkedGr: return "LaskaTalkedGr"; + case RatusGivus: return "RatusGivus"; + case MamObole: return "MamObole"; + case Speed1st: return "Speed1st"; + case SpeedTimer: return "SpeedTimer"; + case ProveIt: return "ProveIt"; + case Proven: return "Proven"; + case ShowWoalka: return "ShowWoalka"; + case PoisonTaken: return "PoisonTaken"; + case HellOpened: return "HellOpened"; + case HellNoCheck: return "HellNoCheck"; + case TalAn1: return "TalAn1"; + case TalAn2: return "TalAn2"; + case TalAn3: return "TalAn3"; + case TalkDevilGuard: return "TalkDevilGuard"; + case Sword1st: return "Sword1st"; + case IluzjaNoCheck: return "IluzjaNoCheck"; + case RozdzielniaNumber: return "RozdzielniaNumber"; + case JailChecked: return "JailChecked"; + case JailTalked: return "JailTalked"; + case TrickFailed: return "TrickFailed"; + case WegielVisible: return "WegielVisible"; + case WegielTimer1: return "WegielTimer1"; + case RandomSample: return "RandomSample"; + case RandomSampleTimer: return "RandomSampleTimer"; + case SampleTimer: return "SampleTimer"; + case ZonaSample: return "ZonaSample"; + case HoleTryAgain: return "HoleTryAgain"; + case TeleportTimer: return "TeleportTimer"; + case RozLezy: return "RozLezy"; + case UdkoTimer: return "UdkoTimer"; + case ZaworZatkany: return "ZaworZatkany"; + case ZaworOpened: return "ZaworOpened"; + case DoorExploded: return "DoorExploded"; + case SkoraTaken: return "SkoraTaken"; + case CiezkieByl: return "CiezkieByl"; + case MamWegiel: return "MamWegiel"; + case SwiecaAway: return "SwiecaAway"; + case ITSAVE: return "ITSAVE"; + case RozpadlSie: return "RozpadlSie"; + case WegielFullTimer: return "WegielFullTimer"; + case WegielDown: return "WegielDown"; + case WegielDownTimer: return "WegielDownTimer"; + case PaliSie: return "PaliSie"; + case DiabGuardTalked: return "DiabGuardTalked"; + case GuardsNoCheck: return "GuardsNoCheck"; + case TalkedPowloka: return "TalkedPowloka"; + case JailOpen: return "JailOpen"; + case PrzytulTimer: return "PrzytulTimer"; + case JailDone: return "JailDone"; + case MamMonety: return "MamMonety"; + case LotTimer: return "LotTimer"; + case LotObj: return "LotObj"; + case PtakTimer: return "PtakTimer"; + case BookTimer: return "BookTimer"; + case BookGiba: return "BookGiba"; + case PtakLata: return "PtakLata"; + case Podej: return "Podej"; + case GotHint: return "GotHint"; + case LawaLeci: return "LawaLeci"; + case PowerKlik: return "PowerKlik"; + case LucekBad: return "LucekBad"; + case LucekBad1st: return "LucekBad1st"; + case IntroDial1: return "IntroDial1"; + case IntroDial2: return "IntroDial2"; + case ItsOutro: return "ItsOutro"; + case KamienComment: return "KamienComment"; + case KamienSkip: return "KamienSkip"; + case TesterFlag: return "TesterFlag"; + case RememberLine: return "RememberLine"; + case OpisLapek: return "OpisLapek"; + // case OpisKamienia: return "//OpisKamienia"; + case TalWait: return "TalWait"; + case OpisKamienia: return "OpisKamienia"; + case JumpBox: return "JumpBox"; + case JumpBox1: return "JumpBox1"; + case JumpBox2: return "JumpBox2"; + case JumpBox3: return "JumpBox3"; + case SpecPiesek: return "SpecPiesek"; + case SpecPiesekCount: return "SpecPiesekCount"; + case SpecPiesekGadanie: return "SpecPiesekGadanie"; + case ZnikaFlag: return "ZnikaFlag"; + case ZnikaTimer: return "ZnikaTimer"; + case SowaTimer: return "SowaTimer"; + case MamrotanieOff: return "MamrotanieOff"; + + case CURRMOB: return "CURRMOB"; + case KOLOR: return "KOLOR"; + case MBFLAG: return "MBFLAG"; + case MXFLAG: return "MXFLAG"; + case MYFLAG: return "MYFLAG"; + case SCROLLTYPE: return "SCROLLTYPE"; + case SCROLLVALUE: return "SCROLLVALUE"; + case SCROLLVALUE2: return "SCROLLVALUE2"; + case TALKEXITCODE: return "TALKEXITCODE"; + case SPECROUTFLAG1: return "SPECROUTFLAG1"; + case SPECROUTFLAG2: return "SPECROUTFLAG2"; + case SPECROUTFLAG3: return "SPECROUTFLAG3"; + case TALKFLAGCODE: return "TALKFLAGCODE"; + case CURRROOM: return "CURRROOM"; + case Talker1Init: return "Talker1Init"; + case Talker2Init: return "Talker2Init"; + case RESTOREROOM: return "RESTOREROOM"; + case INVALLOWED: return "INVALLOWED"; + case BOXSEL: return "BOXSEL"; + case CURSEBLINK: return "CURSEBLINK"; + case EXACTMOVE: return "EXACTMOVE"; + case MOVEDESTX: return "MOVEDESTX"; + case MOVEDESTY: return "MOVEDESTY"; + case NOANTIALIAS: return "NOANTIALIAS"; + case ESCAPED: return "ESCAPED"; + case ALLOW1OPTION: return "ALLOW1OPTION"; + case VOICE_H_LINE: return "VOICE_H_LINE"; + case VOICE_A_LINE: return "VOICE_A_LINE"; + case VOICE_B_LINE: return "VOICE_B_LINE"; + case VOICE_C_LINE: return "VOICE_C_LINE"; + case NOHEROATALL: return "NOHEROATALL"; + case MOUSEENABLED: return "MOUSEENABLED"; + case DIALINES: return "DIALINES"; + + //case SELITEM: return "SELITEM"; + + case SHANWALK: return "SHANWALK"; + case SHANDOG: return "SHANDOG"; + case GETACTIONBACK: return "GETACTIONBACK"; + case GETACTIONDATA: return "GETACTIONDATA"; + case GETACTION: return "GETACTION"; + case HEROFAST: return "HEROFAST"; + case SELITEM: return "SELITEM"; + case LMOUSE: return "LMOUSE"; + case MINMX: return "MINMX"; + case MAXMX: return "MAXMX"; + case MINMY: return "MINMY"; + case MAXMY: return "MAXMY"; + case TORX1: return "TORX1"; + case TORY1: return "TORY1"; + case TORX2: return "TORX2"; + case TORY2: return "TORY2"; + case POWER: return "POWER"; + case POWERENABLED: return "POWERENABLED"; + case FLCRESTORE: return "FLCRESTORE"; + case NOCLSTEXT: return "NOCLSTEXT"; + case ESCAPED2: return "ESCAPED2"; + } +} + + +} + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/flags.h b/engines/prince/flags.h new file mode 100644 index 000000000000..d36091252676 --- /dev/null +++ b/engines/prince/flags.h @@ -0,0 +1,409 @@ +/* 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/scummsys.h" + +namespace Prince { + +struct Flags { + + static const char * getFlagName(uint16 flagId); + + enum Id { + FLAGA1 = 0x8000, + FLAGA2 = 0x8002, + FLAGA3 = 0x8004, + DESTX = 0x8006, + DESTY = 0x8008, + DESTD = 0x800A, + DwarfDone = 0x800C, + GRABARZCOUNTER = 0x800E, + KIERUNEK = 0x8010, + BACKFLAG1 = 0x8012, + BACKFLAG2 = 0x8014, + BACKFLAG3 = 0x8016, + BACKFLAG4 = 0x8018, + MACROFLAG1 = 0x801A, + MACROFLAG2 = 0x801C, + MACROFLAG3 = 0x801E, + HEROLDDONE = 0x8020, + BRIDGESET = 0x8022, + U_BT_1 = 0x8024, + U_BT_2 = 0x8026, + U_BT_3 = 0x8028, + U_BT_4 = 0x802A, + U_BT_5 = 0x802C, + U_BT_6 = 0x802E, + U_BT_7 = 0x8030, + U_BT_8 = 0x8032, + U_BT_9 = 0x8034, + U_BT_COUNTER = 0x8036, + ARIVALDALIVE = 0x8038, + TALKCHAR1 = 0x803A, + TalkType1 = 0x803C, + TALKROUT1 = 0x803E, + TALKROUT2 = 0x8042, + TALKROUT3 = 0x8046, + TALKROUT4 = 0x804A, + TALKANIM1 = 0x804E, + TALKANIM2 = 0x8050, + TALKCOLOR1 = 0x8052, + TALKCOLOR2 = 0x8054, + KapciuchTaken = 0x8056, + CurrentBeggarA = 0x8058, + TempKapc = 0x805A, + HomTaken = 0x805C, + WizardTalk = 0x805E, + SunlordTalk = 0x8060, + HermitTalk = 0x8062, + RunyMode = 0x8064, + FatMerchantTalk = 0x8066, + HotDogTalk = 0x8068, + ThiefTalk = 0x806A, + BeggarTalk = 0x806C, + // DwarfTalk = 0x806E, // Redefinition + MonkTalk = 0x8070, + BardTalk = 0x8072, + BarmanTalk = 0x8074, + LeftPlayerTalk = 0x8076, + OczySowy = 0x8078, + CzachySpeed1 = 0x807A, + CzachySpeed2 = 0x807C, + CzachySpeed3 = 0x807E, + CzachySlowDown1 = 0x8080, + CzachySlowDown2 = 0x8082, + CzachySlowDown3 = 0x8084, + FjordDane = 0x8086, + GKopany1 = 0x8088, + GKopany2 = 0x808A, + GKopany3 = 0x808C, + GKopany4 = 0x808E, + KnowGodWord = 0x8090, + TALKROUT21 = 0x8092, + TALKROUT22 = 0x8096, + TALKROUT23 = 0x809A, + TALKROUT24 = 0x809E, + TalkType2 = 0x80A2, + GrabarzTalk = 0x80A4, + LastTalker = 0x80A6, + MapaPustelniaEnabled = 0x80A8, + MapaTempleEnabled = 0x80AA, + MapaFjordEnabled = 0x80AC, + MapaSilmanionaEnabled = 0x80AE, + MapaKurhanEnabled = 0x80B0, + MapaDragonEnabled = 0x80B2, + MapaMillEnabled = 0x80B4, + DwarfRunning = 0x80B6, + DwarfTalk = 0x80B8, + CurseLift = 0x80BA, + KosciSwapped = 0x80BC, + BookStolen = 0x80BE, + MapaUsable = 0x80C0, + FjordBoss = 0x80C2, + FjordHotDog = 0x80C4, + FjordLewy = 0x80C6, + FjordPrawy = 0x80C8, + TalkArivald = 0x80CA, + ShootDone = 0x80CC, + ShootRunning = 0x80CE, + ShootKnow = 0x80D0, + MirrorKnow = 0x80D2, + Gar1stTime = 0x80D4, + KosciTaken = 0x80D6, + ArivGotSpell = 0x80D8, + BookGiven = 0x80DA, + Wywieszka = 0x80DC, + TalkSheila = 0x80DE, + TalkSheila2 = 0x80E0, + BackHuman = 0x80E2, + SkarbiecOpen = 0x80E4, + LustroTaken = 0x80E6, + GargoyleHom = 0x80E8, + GargoyleBroken = 0x80EA, + FjordDzien = 0x80EC, + GargoyleHom2 = 0x80EE, + RunMonstersRunning = 0x80F0, + FoundPaperInCoffin = 0x80F2, + KnowSunlord = 0x80F4, + KnowSunlordTalk = 0x80F6, + ArivaldCzyta = 0x80F8, + TelepX = 0x80FA, + TelepY = 0x80FC, + TelepDir = 0x80FE, + TelepRoom = 0x8100, + ListStolen = 0x8102, + WifeInDoor = 0x8104, + TalkWifeFlag = 0x8106, + LetterGiven = 0x8108, + LutniaTaken = 0x810A, + BardHomeOpen = 0x810C, + FjordNoMonsters = 0x810E, + ShandriaWallTalking = 0x8110, + ShandriaWallCounter = 0x8112, + ShandriaWallDone = 0x8114, + FutureDone = 0x8116, + TalkButch = 0x8118, + GotSzalik = 0x811A, + GotCzosnek = 0x811C, + BearDone = 0x811E, + NekrVisited = 0x8120, + SunRiddle = 0x8122, + PtaszekAway = 0x8124, + KotGadanie = 0x8126, + SzlafmycaTaken = 0x8128, + BabkaTalk = 0x812A, + SellerTalk = 0x812C, + CzosnekDone = 0x812E, + PriestCounter = 0x8130, + PriestGest1 = 0x8132, + PriestGest2 = 0x8134, + PriestGest3 = 0x8136, + PriestGest4 = 0x8138, + PriestAnim = 0x813A, + HolyWaterTaken = 0x813C, + AxeTaken = 0x813E, + BadylTaken1 = 0x8140, + BadylTaken2 = 0x8142, + BadylSharpened = 0x8144, + PorwanieSmoka = 0x8146, + ShopReOpen = 0x8148, + LuskaShown = 0x814A, + CudKnow = 0x814C, + VampireDead = 0x814E, + MapaVisible1 = 0x8150, + MapaVisible2 = 0x8152, + MapaVisible3 = 0x8154, + MapaVisible4 = 0x8156, + MapaVisible5 = 0x8158, + MapaVisible6 = 0x815A, + MapaVisible7 = 0x815C, + MapaVisible8 = 0x815E, + MapaVisible9 = 0x8160, + MapaX = 0x8162, + MapaY = 0x8164, + MapaD = 0x8166, + OldMapaX = 0x8168, + OldMapaY = 0x816A, + OldMapaD = 0x816C, + MovingBack = 0x816E, + MapaCount = 0x8170, + Pustelnia1st = 0x8172, + CzarnePole1st = 0x8174, + TalkArivNum = 0x8176, + Pfui = 0x8178, + MapaSunlordEnabled = 0x817A, + WebDone = 0x817C, + DragonDone = 0x817E, + KanPlay = 0x8180, + OldKanPlay = 0x8182, + LapkiWait = 0x8184, + WebNoCheck = 0x8186, + Perfumeria = 0x8188, + SmokNoCheck = 0x818A, + IluzjaBroken = 0x818C, + IluzjaWorking = 0x818E, + IluzjaCounter = 0x8190, + KurhanOpen1 = 0x8192, + KastetTaken = 0x8194, + KastetDown = 0x8196, + KurhanDone = 0x8198, + SkelCounter = 0x819A, + SkelDial1 = 0x819C, + SkelDial2 = 0x819E, + SkelDial3 = 0x81A0, + SkelDial4 = 0x81A2, + SameTalker = 0x81A4, + RunMonstersText = 0x81A6, + PiwnicaChecked = 0x81A8, + DragonTalked = 0x81AA, + ToldAboutBook = 0x81AC, + SilmanionaDone = 0x81AE, + ToldBookCount = 0x81B0, + SmrodNoCheck = 0x81B2, + RopeTaken = 0x81B4, + RopeTime = 0x81B6, + LaskaFree = 0x81B8, + ShanSmokTalked = 0x81BA, + SwordTaken = 0x81BC, + Mill1st = 0x81BE, + SawRat = 0x81C0, + KnowRat = 0x81C2, + DziuraTimer = 0x81C4, + LaskaInside = 0x81C6, + HoleBig = 0x81C8, + EnableWiedzmin = 0x81CA, + EnableTrucizna = 0x81CC, + KnowPoison = 0x81CE, + KufelTaken = 0x81D0, + BojkaEnabled = 0x81D2, + BitwaNot1st = 0x81D4, + BojkaTimer = 0x81D6, + BojkaGirl = 0x81D8, + Look1st = 0x81DA, + RatTaken = 0x81DC, + LaskaTalkedGr = 0x81DE, + RatusGivus = 0x81E0, + MamObole = 0x81E2, + Speed1st = 0x81E4, + SpeedTimer = 0x81E6, + ProveIt = 0x81E8, + Proven = 0x81EA, + ShowWoalka = 0x81EC, + PoisonTaken = 0x81EE, + HellOpened = 0x81F0, + HellNoCheck = 0x81F2, + TalAn1 = 0x81F4, + TalAn2 = 0x81F6, + TalAn3 = 0x81F8, + TalkDevilGuard = 0x81fA, + Sword1st = 0x81FC, + IluzjaNoCheck = 0x81FE, + RozdzielniaNumber = 0x8200, + JailChecked = 0x8202, + JailTalked = 0x8204, + TrickFailed = 0x8206, + WegielVisible = 0x8208, + WegielTimer1 = 0x820A, + RandomSample = 0x820C, + RandomSampleTimer = 0x820E, + SampleTimer = 0x8210, + ZonaSample = 0x8212, + HoleTryAgain = 0x8214, + TeleportTimer = 0x8216, + RozLezy = 0x8218, + UdkoTimer = 0x821A, + ZaworZatkany = 0x821C, + ZaworOpened = 0x821E, + DoorExploded = 0x8220, + SkoraTaken = 0x8222, + CiezkieByl = 0x8224, + MamWegiel = 0x8226, + SwiecaAway = 0x8228, + ITSAVE = 0x822A, + RozpadlSie = 0x822C, + WegielFullTimer = 0x822E, + WegielDown = 0x8230, + WegielDownTimer = 0x8232, + PaliSie = 0x8234, + DiabGuardTalked = 0x8236, + GuardsNoCheck = 0x8238, + TalkedPowloka = 0x823A, + JailOpen = 0x823C, + PrzytulTimer = 0x823E, + JailDone = 0x8240, + MamMonety = 0x8242, + LotTimer = 0x8244, + LotObj = 0x8246, + PtakTimer = 0x8248, + BookTimer = 0x824A, + BookGiba = 0x824C, + PtakLata = 0x824E, + Podej = 0x8250, + GotHint = 0x8252, + LawaLeci = 0x8254, + PowerKlik = 0x8258, + LucekBad = 0x825A, + LucekBad1st = 0x825C, + IntroDial1 = 0x825E, + IntroDial2 = 0x8260, + ItsOutro = 0x8262, + KamienComment = 0x8264, + KamienSkip = 0x8266, + TesterFlag = 0x8268, + RememberLine = 0x826A, + OpisLapek = 0x826C, + //OpisKamienia = 0x826E, // Redefinition + TalWait = 0x8270, + OpisKamienia = 0x8272, + JumpBox = 0x8274, + JumpBox1 = 0x8276, + JumpBox2 = 0x8278, + JumpBox3 = 0x827A, + SpecPiesek = 0x827C, + SpecPiesekCount = 0x827E, + SpecPiesekGadanie = 0x8282, + ZnikaFlag = 0x8284, + ZnikaTimer = 0x8286, + SowaTimer = 0x8288, + MamrotanieOff = 0x828A, + // Flagi systemowe do kontroli przez skrypt + // System flags controlled by script + CURRMOB = 0x8400, + KOLOR = 0x8402, + MBFLAG = 0x8404, + MXFLAG = 0x8406, + MYFLAG = 0x8408, + SCROLLTYPE = 0x840A, + SCROLLVALUE = 0x840C, + SCROLLVALUE2 = 0x840E, + TALKEXITCODE = 0x8410, + SPECROUTFLAG1 = 0x8412, + SPECROUTFLAG2 = 0x8414, + SPECROUTFLAG3 = 0x8416, + TALKFLAGCODE = 0x8418, + CURRROOM = 0x841A, + Talker1Init = 0x841C, + Talker2Init = 0x841E, + RESTOREROOM = 0x8420, + INVALLOWED = 0x8422, + BOXSEL = 0x8424, + CURSEBLINK = 0x8426, + EXACTMOVE = 0x8428, + MOVEDESTX = 0x842A, + MOVEDESTY = 0x842C, + NOANTIALIAS = 0x842E, + ESCAPED = 0x8430, + ALLOW1OPTION = 0x8432, + VOICE_H_LINE = 0x8434, + VOICE_A_LINE = 0x8436, + VOICE_B_LINE = 0x8438, + VOICE_C_LINE = 0x843A, + NOHEROATALL = 0x843C, + MOUSEENABLED = 0x843E, + DIALINES = 0x8440, + //SELITEM = 0x8442, // Redefinition + SHANWALK = 0x8444, + SHANDOG = 0x8446, + GETACTIONBACK = 0x8448, + GETACTIONDATA = 0x844C, + GETACTION = 0x8450, + HEROFAST = 0x8452, + SELITEM = 0x8454, + LMOUSE = 0x8456, + MINMX = 0x8458, + MAXMX = 0x845A, + MINMY = 0x845C, + MAXMY = 0x845E, + TORX1 = 0x8460, + TORY1 = 0x8462, + TORX2 = 0x8464, + TORY2 = 0x8466, + POWER = 0x8468, + POWERENABLED = 0x846A, + FLCRESTORE = 0x846C, + NOCLSTEXT = 0x846E, + ESCAPED2 = 0x8470 + }; +}; + +} +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/musNum.h b/engines/prince/musNum.h new file mode 100644 index 000000000000..131943894000 --- /dev/null +++ b/engines/prince/musNum.h @@ -0,0 +1,92 @@ +/* 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. + * + */ + +/* + * This code is based on original Soltys source code + * Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon + */ + +namespace Prince { + +enum RoomMus { +ROOM01MUS =3, +ROOM02MUS =9, +ROOM03MUS =9, +ROOM04MUS =9, +ROOM05MUS =13, +ROOM06MUS =9, +ROOM07MUS =9, +ROOM08MUS =9, +ROOM09MUS =14, +ROOM10MUS =9, +ROOM11MUS =9, +ROOM12MUS =9, +ROOM13MUS =9, +ROOM14MUS =9, +ROOM15MUS =5, +ROOM16MUS =5, +ROOM17MUS =5, +ROOM18MUS =5, +ROOM19MUS =5, +ROOM20MUS =12, +ROOM21MUS =9, +ROOM22MUS =9, +ROOM23MUS =1, +ROOM24MUS =1, +ROOM25MUS =2, +ROOM26MUS =10, +ROOM27MUS =7, +ROOM28MUS =10, +ROOM29MUS =10, +ROOM30MUS =11, +ROOM31MUS =14, +ROOM32MUS =11, +ROOM33MUS =7, +ROOM34MUS =7, +ROOM35MUS =7, +ROOM36MUS =7, +ROOM37MUS =7, +ROOM38MUS =7, +ROOM39MUS =7, +ROOM40MUS =7, +ROOM41MUS =7, +ROOM42MUS =7, +ROOM43MUS =15, +ROOM46MUS =100, +ROOM47MUS =100, +ROOM48MUS =100, +ROOM49MUS =100, +ROOM50MUS =100, +ROOM51MUS =12, +ROOM52MUS =9, +ROOM53MUS =5, +ROOM54MUS =11, +ROOM55MUS =11, +ROOM56MUS =11, +ROOM57MUS =7, +ROOM58MUS =13, +ROOM59MUS =16, +ROOM60MUS =4, +ROOM61MUS =0 +}; + +} diff --git a/engines/prince/variatxt.cpp b/engines/prince/variatxt.cpp new file mode 100644 index 000000000000..073080e5053b --- /dev/null +++ b/engines/prince/variatxt.cpp @@ -0,0 +1,59 @@ +/* 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/variatxt.h" +#include "common/debug.h" + +namespace Prince { + +VariaTxt::VariaTxt() : _dataSize(0), _data(NULL) { +} + +VariaTxt::~VariaTxt() { + _dataSize = 0; + delete[] _data; + _dataSize = NULL; +} + + +bool VariaTxt::loadFromStream(Common::SeekableReadStream &stream) { + _dataSize = stream.size(); + _data = new byte [_dataSize]; + stream.read(_data, _dataSize); + return true; +} + +const char * VariaTxt::getString(uint32 stringId) { + uint32 stringOffset = READ_LE_UINT32(_data + stringId); + + if (stringOffset > _dataSize) { + assert(false); + } + + debug("VariaTxt::getString %04X %04X", stringId, stringOffset); + + return (const char *)_data + stringOffset; +} + +} + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/variatxt.h b/engines/prince/variatxt.h new file mode 100644 index 000000000000..5983054d5758 --- /dev/null +++ b/engines/prince/variatxt.h @@ -0,0 +1,44 @@ +/* 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/stream.h" + +namespace Prince { + +class VariaTxt { +public: + VariaTxt(); + + ~VariaTxt(); + + bool loadFromStream(Common::SeekableReadStream &stream); + + const char * getString(uint32 stringId); + +private: + uint32 _dataSize; + byte *_data; +}; + +} + +/* vim: set tabstop=4 noexpandtab: */ From fcd2273d78d81bdd91d05ef28a0c349415a7317b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Wed, 30 Oct 2013 02:28:07 +0000 Subject: [PATCH 040/374] PRINCE: spaces converted to tabs --- engines/prince/debugger.cpp | 2 +- engines/prince/graphics.cpp | 56 +- engines/prince/graphics.h | 22 +- engines/prince/module.mk | 2 + engines/prince/musNum.h | 184 +++---- engines/prince/object.cpp | 61 +- engines/prince/object.h | 13 +- engines/prince/prince.cpp | 920 +++++++++++++++++-------------- engines/prince/prince.h | 244 ++++---- engines/prince/script.cpp | 1042 +++++++++++++++++++---------------- engines/prince/script.h | 360 ++++++------ engines/prince/sound.cpp | 70 ++- engines/prince/sound.h | 32 +- engines/prince/variatxt.cpp | 16 +- engines/prince/variatxt.h | 8 +- 15 files changed, 1636 insertions(+), 1396 deletions(-) diff --git a/engines/prince/debugger.cpp b/engines/prince/debugger.cpp index 1a78049f9151..2415c1c7ceea 100644 --- a/engines/prince/debugger.cpp +++ b/engines/prince/debugger.cpp @@ -107,7 +107,7 @@ bool Debugger::Cmd_ViewFlc(int argc, const char **argv) { } int flagNum = strToInt(argv[1]); - _vm->loadAnim(flagNum); + _vm->loadAnim(flagNum, false); return true; } diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 94cab7bb3793..29d3a331df87 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -29,51 +29,53 @@ namespace Prince { GraphicsMan::GraphicsMan(PrinceEngine *vm) - : _vm(vm), _changed(false) { - initGraphics(640, 480, true); - _frontScreen = new Graphics::Surface(); - _frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); + : _vm(vm), _changed(false) { + initGraphics(640, 480, true); + _frontScreen = new Graphics::Surface(); + _frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); } void GraphicsMan::update() { - if (_changed) { - _vm->_system->copyRectToScreen((byte*)_frontScreen->getBasePtr(0,0), 640, 0, 0, 640, 480); + if (_changed) { + _vm->_system->copyRectToScreen((byte*)_frontScreen->getBasePtr(0,0), 640, 0, 0, 640, 480); - _vm->_system->updateScreen(); - _changed = false; - } + _vm->_system->updateScreen(); + _changed = false; + } } void GraphicsMan::setPalette(const byte *palette) { - _vm->_system->getPaletteManager()->setPalette(palette, 0, 256); + _vm->_system->getPaletteManager()->setPalette(palette, 0, 256); } void GraphicsMan::change() { - _changed = true; + _changed = true; } -void GraphicsMan::draw(const Graphics::Surface *s) +void GraphicsMan::draw(uint16 posX, uint16 posY, const Graphics::Surface *s) { - uint16 w = MIN(_frontScreen->w, s->w); - for (uint y = 0; y < s->h; y++) { - if (y < _frontScreen->h) { - memcpy((byte*)_frontScreen->getBasePtr(0, y), (byte*)s->getBasePtr(0, y), w); - } - } - change(); + uint16 w = MIN(_frontScreen->w, s->w); + for (uint y = 0; y < s->h; y++) { + if (y < _frontScreen->h) { + memcpy((byte*)_frontScreen->getBasePtr(0, y), (byte*)s->getBasePtr(0, y), w); + } + } + change(); } void GraphicsMan::drawTransparent(const Graphics::Surface *s) { - for (uint y = 0; y < s->h; ++y) { - for (uint x = 0; x < s->w; ++x) { - byte pixel = *((byte*)s->getBasePtr(x,y)); - if (pixel != 255) { - *((byte*)_frontScreen->getBasePtr(x, y)) = pixel; - } - } - } + for (uint y = 0; y < s->h; ++y) { + for (uint x = 0; x < s->w; ++x) { + byte pixel = *((byte*)s->getBasePtr(x,y)); + if (pixel != 255) { + *((byte*)_frontScreen->getBasePtr(x, y)) = pixel; + } + } + } change(); } } + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index 0e29c5c97a38..3ef768a0735b 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -33,26 +33,26 @@ class PrinceEngine; class GraphicsMan { public: - GraphicsMan(PrinceEngine *vm); + GraphicsMan(PrinceEngine *vm); - void update(); + void update(); - void change(); + void change(); - void setPalette(const byte *palette); + void setPalette(const byte *palette); - void draw(const Graphics::Surface *s); - void drawTransparent(const Graphics::Surface *s); + void draw(uint16 x, uint16 y, const Graphics::Surface *s); + void drawTransparent(const Graphics::Surface *s); - Graphics::Surface *_frontScreen; - Graphics::Surface *_backScreen; - const Graphics::Surface *_roomBackground; + Graphics::Surface *_frontScreen; + Graphics::Surface *_backScreen; + const Graphics::Surface *_roomBackground; private: - PrinceEngine *_vm; + PrinceEngine *_vm; - bool _changed; + bool _changed; }; } diff --git a/engines/prince/module.mk b/engines/prince/module.mk index 6b519d4d5751..8bdccdf74de4 100644 --- a/engines/prince/module.mk +++ b/engines/prince/module.mk @@ -10,6 +10,8 @@ MODULE_OBJS = \ mob.o \ object.o \ sound.o \ + flags.o \ + variatxt.o \ prince.o # This module can be built as a plugin diff --git a/engines/prince/musNum.h b/engines/prince/musNum.h index 131943894000..cb8133260425 100644 --- a/engines/prince/musNum.h +++ b/engines/prince/musNum.h @@ -1,92 +1,92 @@ -/* 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. - * - */ - -/* - * This code is based on original Soltys source code - * Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon - */ - -namespace Prince { - -enum RoomMus { -ROOM01MUS =3, -ROOM02MUS =9, -ROOM03MUS =9, -ROOM04MUS =9, -ROOM05MUS =13, -ROOM06MUS =9, -ROOM07MUS =9, -ROOM08MUS =9, -ROOM09MUS =14, -ROOM10MUS =9, -ROOM11MUS =9, -ROOM12MUS =9, -ROOM13MUS =9, -ROOM14MUS =9, -ROOM15MUS =5, -ROOM16MUS =5, -ROOM17MUS =5, -ROOM18MUS =5, -ROOM19MUS =5, -ROOM20MUS =12, -ROOM21MUS =9, -ROOM22MUS =9, -ROOM23MUS =1, -ROOM24MUS =1, -ROOM25MUS =2, -ROOM26MUS =10, -ROOM27MUS =7, -ROOM28MUS =10, -ROOM29MUS =10, -ROOM30MUS =11, -ROOM31MUS =14, -ROOM32MUS =11, -ROOM33MUS =7, -ROOM34MUS =7, -ROOM35MUS =7, -ROOM36MUS =7, -ROOM37MUS =7, -ROOM38MUS =7, -ROOM39MUS =7, -ROOM40MUS =7, -ROOM41MUS =7, -ROOM42MUS =7, -ROOM43MUS =15, -ROOM46MUS =100, -ROOM47MUS =100, -ROOM48MUS =100, -ROOM49MUS =100, -ROOM50MUS =100, -ROOM51MUS =12, -ROOM52MUS =9, -ROOM53MUS =5, -ROOM54MUS =11, -ROOM55MUS =11, -ROOM56MUS =11, -ROOM57MUS =7, -ROOM58MUS =13, -ROOM59MUS =16, -ROOM60MUS =4, -ROOM61MUS =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. + * + */ + +/* + * This code is based on original Soltys source code + * Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon + */ + +namespace Prince { + +enum RoomMus { +ROOM01MUS =3, +ROOM02MUS =9, +ROOM03MUS =9, +ROOM04MUS =9, +ROOM05MUS =13, +ROOM06MUS =9, +ROOM07MUS =9, +ROOM08MUS =9, +ROOM09MUS =14, +ROOM10MUS =9, +ROOM11MUS =9, +ROOM12MUS =9, +ROOM13MUS =9, +ROOM14MUS =9, +ROOM15MUS =5, +ROOM16MUS =5, +ROOM17MUS =5, +ROOM18MUS =5, +ROOM19MUS =5, +ROOM20MUS =12, +ROOM21MUS =9, +ROOM22MUS =9, +ROOM23MUS =1, +ROOM24MUS =1, +ROOM25MUS =2, +ROOM26MUS =10, +ROOM27MUS =7, +ROOM28MUS =10, +ROOM29MUS =10, +ROOM30MUS =11, +ROOM31MUS =14, +ROOM32MUS =11, +ROOM33MUS =7, +ROOM34MUS =7, +ROOM35MUS =7, +ROOM36MUS =7, +ROOM37MUS =7, +ROOM38MUS =7, +ROOM39MUS =7, +ROOM40MUS =7, +ROOM41MUS =7, +ROOM42MUS =7, +ROOM43MUS =15, +ROOM46MUS =100, +ROOM47MUS =100, +ROOM48MUS =100, +ROOM49MUS =100, +ROOM50MUS =100, +ROOM51MUS =12, +ROOM52MUS =9, +ROOM53MUS =5, +ROOM54MUS =11, +ROOM55MUS =11, +ROOM56MUS =11, +ROOM57MUS =7, +ROOM58MUS =13, +ROOM59MUS =16, +ROOM60MUS =4, +ROOM61MUS =0 +}; + +} diff --git a/engines/prince/object.cpp b/engines/prince/object.cpp index 72d4f1103a38..9f7efcfb88d7 100644 --- a/engines/prince/object.cpp +++ b/engines/prince/object.cpp @@ -36,42 +36,43 @@ Object::Object() : _surface(NULL) { } void Object::loadSurface(Common::SeekableReadStream &stream) { - stream.skip(4); + stream.skip(4); - _surface = new Graphics::Surface(); - _surface->create(stream.readUint16LE(), stream.readUint16LE(), Graphics::PixelFormat::createFormatCLUT8()); - for (int h = 0; h < _surface->h; ++h) { - stream.read(_surface->getBasePtr(0, h), _surface->w); - } + _surface = new Graphics::Surface(); + _surface->create(stream.readUint16LE(), stream.readUint16LE(), Graphics::PixelFormat::createFormatCLUT8()); + for (int h = 0; h < _surface->h; ++h) { + stream.read(_surface->getBasePtr(0, h), _surface->w); + } } bool Object::loadFromStream(Common::SeekableReadStream &stream) { - int32 pos = stream.pos(); - uint16 x = stream.readUint16LE(); - if (x == 0xFFFF) - return false; - _x = x; - _y = stream.readUint16LE(); - - const Common::String obStreamName = Common::String::format("OB%02d", stream.readUint16LE()); - Common::SeekableReadStream *obStream = SearchMan.createReadStreamForMember(obStreamName); - if (!obStream) { - error("Can't load %s", obStreamName.c_str()); - return false; - } - - loadSurface(*obStream); - delete obStream; - - _z = stream.readUint16LE(); - - stream.seek(pos + 16); - - debug("Object x %d, y %d, z %d", _x, _y, _z); - - return true; + int32 pos = stream.pos(); + uint16 x = stream.readUint16LE(); + if (x == 0xFFFF) + return false; + _x = x; + _y = stream.readUint16LE(); + + const Common::String obStreamName = Common::String::format("OB%02d", stream.readUint16LE()); + Common::SeekableReadStream *obStream = SearchMan.createReadStreamForMember(obStreamName); + if (!obStream) { + error("Can't load %s", obStreamName.c_str()); + return false; + } + + loadSurface(*obStream); + delete obStream; + + _z = stream.readUint16LE(); + + stream.seek(pos + 16); + + debug("Object x %d, y %d, z %d", _x, _y, _z); + + return true; } } +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/object.h b/engines/prince/object.h index 3a8859c196c8..2c2dbc9fbf1e 100644 --- a/engines/prince/object.h +++ b/engines/prince/object.h @@ -30,18 +30,19 @@ namespace Prince { class Object { public: - Object(); + Object(); - bool loadFromStream(Common::SeekableReadStream &stream); - Graphics::Surface *getSurface() const { return _surface; } + bool loadFromStream(Common::SeekableReadStream &stream); + Graphics::Surface *getSurface() const { return _surface; } private: - void loadSurface(Common::SeekableReadStream &stream); + void loadSurface(Common::SeekableReadStream &stream); - Graphics::Surface *_surface; - uint16 _x, _y, _z; + Graphics::Surface *_surface; + uint16 _x, _y, _z; }; } #endif +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index a9f243ce11b5..9ca7a62fad05 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1,415 +1,505 @@ -/* 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/scummsys.h" - -#include "common/config-manager.h" -#include "common/debug-channels.h" -#include "common/debug.h" -#include "common/events.h" -#include "common/file.h" -#include "common/random.h" -#include "common/fs.h" -#include "common/keyboard.h" -#include "common/substream.h" - -#include "graphics/cursorman.h" -#include "graphics/surface.h" -#include "graphics/palette.h" -#include "graphics/pixelformat.h" - -#include "engines/util.h" -#include "engines/advancedDetector.h" - -#include "audio/audiostream.h" - -#include "prince/prince.h" -#include "prince/font.h" -#include "prince/graphics.h" -#include "prince/script.h" -#include "prince/debugger.h" -#include "prince/object.h" -#include "prince/mob.h" -#include "prince/sound.h" - -#include "video/flic_decoder.h" - -namespace Prince { - -Graphics::Surface *loadCursor(const char *curName) -{ - Common::SeekableReadStream *curStream = SearchMan.createReadStreamForMember(curName); - if (!curStream) { - error("Can't load %s", curName); - return NULL; - } - - curStream->skip(4); - uint16 w = curStream->readUint16LE(); - uint16 h = curStream->readUint16LE(); - - debug("Loading cursor %s, w %d, h %d", curName, w, h); - - Graphics::Surface *curSurface = new Graphics::Surface(); - curSurface->create(w, h, Graphics::PixelFormat::createFormatCLUT8()); - for (int ih = 0; ih < h; ++ih) { - curStream->read(curSurface->getBasePtr(0, ih), w); - } - - delete curStream; - return curSurface; -} - - - -PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : - Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL), - _locationNr(0), _debugger(NULL), _objectList(NULL), _mobList(NULL), _midiPlayer(NULL) { - _rnd = new Common::RandomSource("prince"); - _debugger = new Debugger(this); - _midiPlayer = new MusicPlayer(this); -} - -PrinceEngine::~PrinceEngine() { - DebugMan.clearAllDebugChannels(); - - delete _rnd; - delete _debugger; - delete _cur1; - delete _cur2; - delete _midiPlayer; -} - -GUI::Debugger *PrinceEngine::getDebugger() { - return _debugger; -} - -Common::Error PrinceEngine::run() { - _graph = new GraphicsMan(this); - - const Common::FSNode gameDataDir(ConfMan.get("path")); - - debug("Adding all path: %s", gameDataDir.getPath().c_str()); - - SearchMan.addSubDirectoryMatching(gameDataDir, "all", 0, 2); - - Common::SeekableReadStream *font1stream = SearchMan.createReadStreamForMember("font1.raw"); - if (!font1stream) - return Common::kPathNotFile; - - if (_font.load(*font1stream)) { - _font.getCharWidth(103); - } - delete font1stream; - - Common::SeekableReadStream * walizka = SearchMan.createReadStreamForMember("walizka"); - if (!walizka) - return Common::kPathDoesNotExist; - - debug("Loading walizka"); - if (!_walizkaBmp.loadStream(*walizka)) { - return Common::kPathDoesNotExist; - } - - Common::SeekableReadStream * skryptStream = SearchMan.createReadStreamForMember("skrypt.dat"); - if (!skryptStream) - return Common::kPathNotFile; - - debug("Loading skrypt"); - _script = new Script(this); - _script->loadFromStream(*skryptStream); - - delete skryptStream; - - - _cur1 = loadCursor("mouse1.cur"); - _cur2 = loadCursor("mouse2.cur"); - - Common::SeekableReadStream *logoStream = SearchMan.createReadStreamForMember("logo.raw"); - if (logoStream) - { - MhwanhDecoder logo; - logo.loadStream(*logoStream); - _graph->setPalette(logo.getPalette()); - _graph->draw(logo.getSurface()); - _graph->update(); - _system->delayMillis(700); - } - delete logoStream; - - mainLoop(); - - return Common::kNoError; -} - -class MobList { -public: - bool loadFromStream(Common::SeekableReadStream &stream); - - Common::Array _mobList; -}; - -bool MobList::loadFromStream(Common::SeekableReadStream &stream) -{ - Mob mob; - while (mob.loadFromStream(stream)) - _mobList.push_back(mob); - - return true; -} - -class ObjectList { -public: - bool loadFromStream(Common::SeekableReadStream &stream); - - Common::Array _objList; -}; - -bool ObjectList::loadFromStream(Common::SeekableReadStream &stream) -{ - Object obj; - while (obj.loadFromStream(stream)) - _objList.push_back(obj); - - return true; -} - -bool PrinceEngine::loadLocation(uint16 locationNr) { - debug("PrinceEngine::loadLocation %d", locationNr); - const Common::FSNode gameDataDir(ConfMan.get("path")); - SearchMan.remove(Common::String::format("%02d", _locationNr)); - _locationNr = locationNr; - - const Common::String locationNrStr = Common::String::format("%02d", _locationNr); - debug("loadLocation %s", locationNrStr.c_str()); - SearchMan.addSubDirectoryMatching(gameDataDir, locationNrStr, 0, 2); - - // load location background - Common::SeekableReadStream *room = SearchMan.createReadStreamForMember("room"); - - if (!room) { - error("Can't load room bitmap"); - return false; - } - - if(_roomBmp.loadStream(*room)) { - debug("Room bitmap loaded"); - } - - delete room; - - delete _mobList; - _mobList = NULL; - - Common::SeekableReadStream *mobListStream = SearchMan.createReadStreamForMember("mob.lst"); - if (!mobListStream) { - error("Can't read mob.lst"); - return false; - } - - _mobList = new MobList(); - _mobList->loadFromStream(*mobListStream); - - delete mobListStream; - - delete _objectList; - _objectList = NULL; - - Common::SeekableReadStream *objListStream = SearchMan.createReadStreamForMember("obj.lst"); - if (!objListStream) { - error("Can't read obj.lst"); - return false; - } - - _objectList = new ObjectList(); - _objectList->loadFromStream(*objListStream); - delete objListStream; - - const char *musName = MusicPlayer::_musTable[MusicPlayer::_musRoomTable[locationNr]]; - _midiPlayer->loadMidi(musName); - - return true; -} - -void PrinceEngine::changeCursor(uint16 curId) -{ - Graphics::Surface *curSurface = NULL; - - uint16 hotspotX = 0; - uint16 hotspotY = 0; - - switch(curId) { - case 0: - CursorMan.showMouse(false); - return; - case 1: - curSurface = _cur1; - break; - case 2: - curSurface = _cur2; - hotspotX = curSurface->w >> 1; - hotspotY = curSurface->h >> 1; - break; - } - - CursorMan.replaceCursorPalette(_roomBmp.getPalette(), 0, 255); - CursorMan.replaceCursor( - curSurface->getBasePtr(0, 0), - curSurface->w, curSurface->h, - hotspotX, hotspotY, - 255, false, - &curSurface->format - ); - CursorMan.showMouse(true); -} - -bool PrinceEngine::playNextFrame() { - const Graphics::Surface *s = _flicPlayer.decodeNextFrame(); - if (s) { - _graph->drawTransparent(s); - _graph->change(); - } - - return true; -} - -bool PrinceEngine::loadAnim(uint16 animNr) { - 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()); - } - - debug("%s loaded", streamName.c_str()); - _flicPlayer.start(); - return true; -} - -void PrinceEngine::keyHandler(Common::Event event) { - uint16 nChar = event.kbd.keycode; - if (event.kbd.hasFlags(Common::KBD_CTRL)) { - switch (nChar) { - case Common::KEYCODE_d: - getDebugger()->attach(); - getDebugger()->onFrame(); - break; - } - } -} - -void PrinceEngine::hotspot() { - Common::Point mousepos = _system->getEventManager()->getMousePos(); - - Common::Array::iterator it = _mobList->_mobList.begin(); - for (; it != _mobList->_mobList.end(); ++it) { - if (it->_visible) - continue; - if (it->_rect.contains(mousepos)) { - uint16 textW = 0; - for (int i = 0; i < it->_name.size(); ++i) - textW += _font.getCharWidth(it->_name[i]); - - uint16 x = mousepos.x - textW/2; - if (x > _graph->_frontScreen->w) - x = 0; - - if (x + textW > _graph->_frontScreen->w) - x = _graph->_frontScreen->w - textW; - - _font.drawString( - _graph->_frontScreen, - it->_name, - x, - mousepos.y - _font.getFontHeight(), - _graph->_frontScreen->w, - 216 - ); - break; - } - } -} - -void PrinceEngine::mainLoop() { - - loadLocation(1); - changeCursor(1); - CursorMan.showMouse(true); - - while (!shouldQuit()) { - _debugger->onFrame(); - 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_KEYUP: - break; - case Common::EVENT_MOUSEMOVE: - break; - case Common::EVENT_LBUTTONDOWN: - case Common::EVENT_RBUTTONDOWN: - break; - case Common::EVENT_LBUTTONUP: - case Common::EVENT_RBUTTONUP: - break; - case Common::EVENT_QUIT: - break; - default: - break; - } - } - - if (shouldQuit()) - return; - - //_script->step(); - - if (_roomBmp.getSurface()) { - _graph->setPalette(_roomBmp.getPalette()); - _graph->draw(_roomBmp.getSurface()); - } - - playNextFrame(); - - //debug("Cursor visible %d", CursorMan.isVisible()); - - //if (_objectList) - // _graph->drawTransparent(_objectList->getSurface()); - - hotspot(); - - _graph->update(); - - _system->delayMillis(40); - - } -} - -} // End of namespace Prince +/* 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/scummsys.h" + +#include "common/config-manager.h" +#include "common/debug-channels.h" +#include "common/debug.h" +#include "common/events.h" +#include "common/file.h" +#include "common/random.h" +#include "common/fs.h" +#include "common/keyboard.h" +#include "common/substream.h" + +#include "graphics/cursorman.h" +#include "graphics/surface.h" +#include "graphics/palette.h" +#include "graphics/pixelformat.h" + +#include "engines/util.h" +#include "engines/advancedDetector.h" + +#include "audio/audiostream.h" + +#include "prince/prince.h" +#include "prince/font.h" +#include "prince/graphics.h" +#include "prince/script.h" +#include "prince/debugger.h" +#include "prince/object.h" +#include "prince/mob.h" +#include "prince/sound.h" +#include "prince/variatxt.h" + +#include "video/flic_decoder.h" + +namespace Prince { + +Graphics::Surface *loadCursor(const char *curName) +{ + Common::SeekableReadStream *curStream = SearchMan.createReadStreamForMember(curName); + if (!curStream) { + error("Can't load %s", curName); + return NULL; + } + + curStream->skip(4); + uint16 w = curStream->readUint16LE(); + uint16 h = curStream->readUint16LE(); + + debug("Loading cursor %s, w %d, h %d", curName, w, h); + + Graphics::Surface *curSurface = new Graphics::Surface(); + curSurface->create(w, h, Graphics::PixelFormat::createFormatCLUT8()); + for (int ih = 0; ih < h; ++ih) { + curStream->read(curSurface->getBasePtr(0, ih), w); + } + + delete curStream; + return curSurface; +} + + + +PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : + Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL), + _locationNr(0), _debugger(NULL), _objectList(NULL), _mobList(NULL), _midiPlayer(NULL), + _cameraX(0), _newCameraX(0) { + _rnd = new Common::RandomSource("prince"); + _debugger = new Debugger(this); + _midiPlayer = new MusicPlayer(this); + _textSlots[0] = ""; +} + +PrinceEngine::~PrinceEngine() { + DebugMan.clearAllDebugChannels(); + + delete _rnd; + delete _debugger; + delete _cur1; + delete _cur2; + delete _midiPlayer; +} + +GUI::Debugger *PrinceEngine::getDebugger() { + return _debugger; +} + +Common::Error PrinceEngine::run() { + _graph = new GraphicsMan(this); + + const Common::FSNode gameDataDir(ConfMan.get("path")); + + debug("Adding all path: %s", gameDataDir.getPath().c_str()); + + SearchMan.addSubDirectoryMatching(gameDataDir, "all", 0, 2); + + Common::SeekableReadStream *font1stream = SearchMan.createReadStreamForMember("font1.raw"); + if (!font1stream) + return Common::kPathNotFile; + + if (_font.load(*font1stream)) { + _font.getCharWidth(103); + } + delete font1stream; + + Common::SeekableReadStream * walizka = SearchMan.createReadStreamForMember("walizka"); + if (!walizka) + return Common::kPathDoesNotExist; + + debug("Loading walizka"); + if (!_walizkaBmp.loadStream(*walizka)) { + return Common::kPathDoesNotExist; + } + + Common::SeekableReadStream * skryptStream = SearchMan.createReadStreamForMember("skrypt.dat"); + if (!skryptStream) + return Common::kPathNotFile; + + debug("Loading skrypt"); + _script = new Script(this); + _script->loadFromStream(*skryptStream); + + delete skryptStream; + + Common::SeekableReadStream *variaTxtStream = SearchMan.createReadStreamForMember("variatxt.dat"); + + if (!variaTxtStream) { + error("Can't load variatxt.dat"); + return Common::kPathNotFile; + } + + _variaTxt = new VariaTxt(); + _variaTxt->loadFromStream(*variaTxtStream); + delete variaTxtStream; + + Common::SeekableReadStream *talkTxtStream = SearchMan.createReadStreamForMember("talktxt.dat"); + if (!talkTxtStream) { + error("Can't load talkTxtStream"); + return Common::kPathDoesNotExist; + } + + _talkTxtSize = talkTxtStream->size(); + _talkTxt = new byte[_talkTxtSize]; + talkTxtStream->read(_talkTxt, _talkTxtSize); + + delete talkTxtStream; + + + _cur1 = loadCursor("mouse1.cur"); + _cur2 = loadCursor("mouse2.cur"); +#if 0 + Common::SeekableReadStream *logoStream = SearchMan.createReadStreamForMember("logo.raw"); + if (logoStream) + { + MhwanhDecoder logo; + logo.loadStream(*logoStream); + _graph->setPalette(logo.getPalette()); + _graph->draw(0, 0, logo.getSurface()); + _graph->update(); + _system->delayMillis(700); + } + delete logoStream; +#endif + mainLoop(); + + return Common::kNoError; +} + +class MobList { +public: + bool loadFromStream(Common::SeekableReadStream &stream); + + Common::Array _mobList; +}; + +bool MobList::loadFromStream(Common::SeekableReadStream &stream) +{ + Mob mob; + while (mob.loadFromStream(stream)) + _mobList.push_back(mob); + + return true; +} + +class ObjectList { +public: + bool loadFromStream(Common::SeekableReadStream &stream); + + Common::Array _objList; +}; + +bool ObjectList::loadFromStream(Common::SeekableReadStream &stream) +{ + Object obj; + while (obj.loadFromStream(stream)) + _objList.push_back(obj); + + return true; +} + +bool PrinceEngine::loadLocation(uint16 locationNr) { + debug("PrinceEngine::loadLocation %d", locationNr); + const Common::FSNode gameDataDir(ConfMan.get("path")); + SearchMan.remove(Common::String::format("%02d", _locationNr)); + _locationNr = locationNr; + + const Common::String locationNrStr = Common::String::format("%02d", _locationNr); + debug("loadLocation %s", locationNrStr.c_str()); + SearchMan.addSubDirectoryMatching(gameDataDir, locationNrStr, 0, 2); + + // load location background + Common::SeekableReadStream *room = SearchMan.createReadStreamForMember("room"); + + if (!room) { + error("Can't load room bitmap"); + return false; + } + + if(_roomBmp.loadStream(*room)) { + debug("Room bitmap loaded"); + _sceneWidth = _roomBmp.getSurface()->w; + } + + delete room; + + delete _mobList; + _mobList = NULL; + + Common::SeekableReadStream *mobListStream = SearchMan.createReadStreamForMember("mob.lst"); + if (!mobListStream) { + error("Can't read mob.lst"); + return false; + } + + _mobList = new MobList(); + _mobList->loadFromStream(*mobListStream); + + delete mobListStream; + + delete _objectList; + _objectList = NULL; + + Common::SeekableReadStream *objListStream = SearchMan.createReadStreamForMember("obj.lst"); + if (!objListStream) { + error("Can't read obj.lst"); + return false; + } + + _objectList = new ObjectList(); + _objectList->loadFromStream(*objListStream); + delete objListStream; + + const char *musName = MusicPlayer::_musTable[MusicPlayer::_musRoomTable[locationNr]]; + _midiPlayer->loadMidi(musName); + + return true; +} + +void PrinceEngine::changeCursor(uint16 curId) +{ + Graphics::Surface *curSurface = NULL; + + uint16 hotspotX = 0; + uint16 hotspotY = 0; + + switch(curId) { + case 0: + CursorMan.showMouse(false); + return; + case 1: + curSurface = _cur1; + break; + case 2: + curSurface = _cur2; + hotspotX = curSurface->w >> 1; + hotspotY = curSurface->h >> 1; + break; + } + + CursorMan.replaceCursorPalette(_roomBmp.getPalette(), 0, 255); + CursorMan.replaceCursor( + curSurface->getBasePtr(0, 0), + curSurface->w, curSurface->h, + hotspotX, hotspotY, + 255, false, + &curSurface->format + ); + CursorMan.showMouse(true); +} + +bool PrinceEngine::playNextFrame() { + if (!_flicPlayer.isVideoLoaded()) + return false; + + const Graphics::Surface *s = _flicPlayer.decodeNextFrame(); + if (s) { + _graph->drawTransparent(s); + _graph->change(); + } else if (_flicLooped) { + _flicPlayer.rewind(); + playNextFrame(); + } + + 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()); + } + + debug("%s loaded", streamName.c_str()); + _flicLooped = loop; + _flicPlayer.start(); + playNextFrame(); + return true; +} + +void PrinceEngine::scrollCameraLeft(int16 delta) { + if (_newCameraX > 0) { + if (_newCameraX < delta) + _newCameraX = 0; + else + _newCameraX -= delta; + } +} + +void PrinceEngine::scrollCameraRight(int16 delta) { + if (_newCameraX != _sceneWidth - 640) { + if (_sceneWidth - 640 < delta + _newCameraX) + delta += (_sceneWidth - 640) - (delta + _newCameraX); + _newCameraX += delta; + debug(0, "PrinceEngine::scrollCameraRight() _newCameraX = %d; delta = %d", _newCameraX, delta); + } +} + +void PrinceEngine::keyHandler(Common::Event event) { + uint16 nChar = event.kbd.keycode; + if (event.kbd.hasFlags(Common::KBD_CTRL)) { + switch (nChar) { + case Common::KEYCODE_d: + getDebugger()->attach(); + break; + case Common::KEYCODE_LEFT: + scrollCameraLeft(32); + break; + case Common::KEYCODE_RIGHT: + scrollCameraRight(32); + break; + } + } +} + +void PrinceEngine::hotspot() { + if (!_mobList) + return; + Common::Point mousepos = _system->getEventManager()->getMousePos(); + Common::Point mousePosCamera(mousepos.x + _cameraX, mousepos.y); + + for (Common::Array::const_iterator it = _mobList->_mobList.begin() + ; it != _mobList->_mobList.end() ; ++it) { + if (it->_visible) + continue; + if (it->_rect.contains(mousePosCamera)) { + uint16 textW = 0; + for (int i = 0; i < it->_name.size(); ++i) + textW += _font.getCharWidth(it->_name[i]); + + uint16 x = mousepos.x - textW/2; + if (x > _graph->_frontScreen->w) + x = 0; + + if (x + textW > _graph->_frontScreen->w) + x = _graph->_frontScreen->w - textW; + + _font.drawString( + _graph->_frontScreen, + it->_name, + x, + mousepos.y - _font.getFontHeight(), + _graph->_frontScreen->w, + 216 + ); + break; + } + } +} + +void PrinceEngine::printAt(const char *s, uint16 x, uint16 y) { + _textSlots[0] = s; +} + +uint32 PrinceEngine::getTextWidth(const char *s) { + uint16 textW = 0; + while (*s) { + textW += *s; + ++s; + } + return textW; +} + + +void PrinceEngine::drawScreen() { + const Graphics::Surface *roomSurface = _roomBmp.getSurface(); + if (roomSurface) { + _graph->setPalette(_roomBmp.getPalette()); + const Graphics::Surface visiblePart = roomSurface->getSubArea(Common::Rect(_cameraX, 0, roomSurface->w, roomSurface->h)); + _graph->draw(0, 0, &visiblePart); + } + + playNextFrame(); + + //if (_objectList) + // _graph->drawTransparent(_objectList->getSurface()); + hotspot(); + + _font.drawString( + _graph->_frontScreen, + _textSlots[0], + 320 - getTextWidth(_textSlots[0])/2, + 470 - _font.getFontHeight(), + _graph->_frontScreen->w, + 216 + ); + + + getDebugger()->onFrame(); + + _graph->update(); +} + +void PrinceEngine::mainLoop() { + + //loadLocation(1); + //changeCursor(1); + //CursorMan.showMouse(true); + + while (!shouldQuit()) { + 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_KEYUP: + break; + case Common::EVENT_MOUSEMOVE: + break; + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_RBUTTONDOWN: + break; + case Common::EVENT_LBUTTONUP: + case Common::EVENT_RBUTTONUP: + break; + case Common::EVENT_QUIT: + break; + default: + break; + } + } + + if (shouldQuit()) + return; + + _script->step(); + drawScreen(); + + _system->delayMillis(10); + + _cameraX = _newCameraX; + } +} + +} // End of namespace Prince +/* vim: set tabstop=4 expandtab!: */ diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 6340733255c5..080eca5ead90 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -1,112 +1,132 @@ -/* 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_H -#define PRINCE_H - -#include "common/random.h" -#include "common/system.h" -#include "common/debug.h" -#include "common/debug-channels.h" -#include "common/textconsole.h" -#include "common/rect.h" -#include "common/events.h" - -#include "graphics/decoders/bmp.h" - -#include "gui/debugger.h" - -#include "engines/engine.h" -#include "engines/util.h" - -#include "audio/mixer.h" - -#include "video/flic_decoder.h" - -#include "prince/font.h" -#include "prince/mhwanh.h" - -namespace Prince { - -struct PrinceGameDescription; - -class PrinceEngine; -class GraphicsMan; -class Script; -class Debugger; -class ObjectList; -class MobList; -class MusicPlayer; - -class PrinceEngine : public Engine { -protected: - Common::Error run(); - -public: - PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc); - virtual ~PrinceEngine(); - - virtual bool hasFeature(EngineFeature f) const; - - int getGameType() const; - const char *getGameId() const; - uint32 getFeatures() const; - Common::Language getLanguage() const; - - const PrinceGameDescription *_gameDescription; - Video::FlicDecoder _flicPlayer; - - bool loadLocation(uint16 locationNr); - bool loadAnim(uint16 animNr); - - virtual GUI::Debugger *getDebugger(); - - void changeCursor(uint16 curId); - -private: - bool playNextFrame(); - void keyHandler(Common::Event event); - void hotspot(); - - Common::RandomSource *_rnd; - Graphics::BitmapDecoder _roomBmp; - uint16 _locationNr; - MhwanhDecoder _walizkaBmp; - - Graphics::Surface *_cur1; - Graphics::Surface *_cur2; - - Debugger *_debugger; - GraphicsMan *_graph; - Script *_script; - Font _font; - ObjectList *_objectList; - MobList *_mobList; - MusicPlayer *_midiPlayer; - - void mainLoop(); - -}; - -} // End of namespace Prince - -#endif +/* 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_H +#define PRINCE_H + +#include "common/random.h" +#include "common/system.h" +#include "common/debug.h" +#include "common/debug-channels.h" +#include "common/textconsole.h" +#include "common/rect.h" +#include "common/events.h" + +#include "graphics/decoders/bmp.h" + +#include "gui/debugger.h" + +#include "engines/engine.h" +#include "engines/util.h" + +#include "audio/mixer.h" + +#include "video/flic_decoder.h" + +#include "prince/font.h" +#include "prince/mhwanh.h" + +namespace Prince { + +struct PrinceGameDescription; + +class PrinceEngine; +class GraphicsMan; +class Script; +class Debugger; +class ObjectList; +class MobList; +class MusicPlayer; +class VariaTxt; + +class PrinceEngine : public Engine { +protected: + Common::Error run(); + +public: + PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc); + virtual ~PrinceEngine(); + + virtual bool hasFeature(EngineFeature f) const; + + int getGameType() const; + const char *getGameId() const; + uint32 getFeatures() const; + Common::Language getLanguage() const; + + const PrinceGameDescription *_gameDescription; + Video::FlicDecoder _flicPlayer; + VariaTxt *_variaTxt; + + uint32 _talkTxtSize; + byte *_talkTxt; + + bool loadLocation(uint16 locationNr); + bool loadAnim(uint16 animNr, bool loop); + + virtual GUI::Debugger *getDebugger(); + + void changeCursor(uint16 curId); + void printAt(const char *s, uint16 x, uint16 y); + + const char * _textSlots[1000]; + +private: + bool playNextFrame(); + void keyHandler(Common::Event event); + void hotspot(); + void scrollCameraRight(int16 delta); + void scrollCameraLeft(int16 delta); + void drawScreen(); + + uint32 getTextWidth(const char *s); + + Common::RandomSource *_rnd; + Graphics::BitmapDecoder _roomBmp; + uint16 _locationNr; + MhwanhDecoder _walizkaBmp; + + Graphics::Surface *_cur1; + Graphics::Surface *_cur2; + + Debugger *_debugger; + GraphicsMan *_graph; + Script *_script; + Font _font; + ObjectList *_objectList; + MobList *_mobList; + MusicPlayer *_midiPlayer; + uint16 _cameraX; + uint16 _newCameraX; + uint16 _sceneWidth; + + bool _flicLooped; + + void mainLoop(); + +}; + +} // End of namespace Prince + +#endif + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index e2360debc8c2..7ab723a4fbdc 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -22,6 +22,9 @@ #include "prince/script.h" #include "prince/prince.h" +#include "prince/flags.h" +#include "prince/variatxt.h" +#include "prince/font.h" #include "common/debug.h" #include "common/debug-channels.h" @@ -32,459 +35,487 @@ namespace Prince { static const uint16 NUM_OPCODES = 144; Script::Script(PrinceEngine *vm) : - _code(NULL), _stacktop(0), _vm(vm), _opcodeNF(false) { + _code(NULL), _stacktop(0), _vm(vm), _opcodeNF(false) { } Script::~Script() { - delete[] _code; + delete[] _code; } bool Script::loadFromStream(Common::SeekableReadStream &stream) { - _codeSize = stream.size(); - _code = new byte[_codeSize]; + _codeSize = stream.size(); + _code = new byte[_codeSize]; - if (!_code) - return false; + if (!_code) + return false; - stream.read(_code, _codeSize); - // Initialize the script - _currentInstruction = READ_LE_UINT32(_code + 4); + stream.read(_code, _codeSize); + // Initialize the script + _currentInstruction = READ_LE_UINT32(_code + 4); - return true; + return true; } void Script::debugScript(const char *s, ...) { - char buf[STRINGBUFLEN]; - va_list va; + char buf[STRINGBUFLEN]; + va_list va; - va_start(va, s); - vsnprintf(buf, STRINGBUFLEN, s, va); - va_end(va); + va_start(va, s); + vsnprintf(buf, STRINGBUFLEN, s, va); + va_end(va); - Common::String str = Common::String::format("@0x%04X: ", _lastInstruction); - str += Common::String::format("op %02d: ", _lastOpcode); - debug("%s %s", str.c_str(), buf); + Common::String str = Common::String::format("@0x%04X: ", _lastInstruction); + str += Common::String::format("op %02d: ", _lastOpcode); + debug("%s %s", str.c_str(), buf); } void Script::step() { - //while (!_opcodeNF) - { - _lastInstruction = _currentInstruction; - // Prepare the base debug string - Common::String dstr = Common::String::format("@0x%04X: ", _currentInstruction); + while (!_opcodeNF) + { + _lastInstruction = _currentInstruction; + // Prepare the base debug string + Common::String dstr = Common::String::format("@0x%04X: ", _currentInstruction); - // Get the current opcode - _lastOpcode = readScript16bits(); + // Get the current opcode + _lastOpcode = readScript16bits(); - dstr += Common::String::format("op %02d: ", _lastOpcode); + dstr += Common::String::format("op %02d: ", _lastOpcode); - if (_lastOpcode > NUM_OPCODES) - error("Trying to execute unknown opcode %s", dstr.c_str()); + if (_lastOpcode > NUM_OPCODES) + error("Trying to execute unknown opcode %s", dstr.c_str()); - debug("%s", dstr.c_str()); + debug("%s", dstr.c_str()); - // Execute the current opcode - OpcodeFunc op = _opcodes[_lastOpcode]; - (this->*op)(); - } + // Execute the current opcode + OpcodeFunc op = _opcodes[_lastOpcode]; + (this->*op)(); + if (_opcodeNF) { + + _opcodeNF = 0; + break; + } + } } uint8 Script::getCodeByte(uint32 address) { - if (address >= _codeSize) - error("Trying to read a script byte at address 0x%04X, while the " - "script is just 0x%04X bytes long", address, _codeSize); - return _code[address]; + if (address >= _codeSize) + error("Trying to read a script byte at address 0x%04X, while the " + "script is just 0x%04X bytes long", address, _codeSize); + return _code[address]; } uint8 Script::readScript8bits() { - uint8 data = getCodeByte(_currentInstruction); - _currentInstruction++; - return data; + uint8 data = getCodeByte(_currentInstruction); + _currentInstruction++; + return data; } uint16 Script::readScript16bits() { - uint8 lower = readScript8bits(); - uint8 upper = readScript8bits(); - return lower | (upper << 8); + uint8 lower = readScript8bits(); + uint8 upper = readScript8bits(); + return lower | (upper << 8); } uint32 Script::readScript32bits() { - uint16 lower = readScript16bits(); - uint16 upper = readScript16bits(); - return lower | (upper << 16); + uint16 lower = readScript16bits(); + uint16 upper = readScript16bits(); + return lower | (upper << 16); } void Script::O_WAITFOREVER() { - debugScript("O_WAITFOREVER"); - _currentInstruction -= 2; + debugScript("O_WAITFOREVER"); + _opcodeNF = 1; + _currentInstruction -= 2; } void Script::O_BLACKPALETTE() { - debugScript("O_BLACKPALETTE"); + debugScript("O_BLACKPALETTE"); } void Script::O_SETUPPALETTE() { - debugScript("O_SETUPPALETTE"); + debugScript("O_SETUPPALETTE"); } void Script::O_INITROOM() { - uint16 roomId = readScript16bits(); - debugScript("O_INITROOM %d", roomId); - _vm->loadLocation(roomId); + uint16 roomId = readScript16bits(); + debugScript("O_INITROOM %d", roomId); + _vm->loadLocation(roomId); + _opcodeNF = 1; } void Script::O_SETSAMPLE() { - uint16 sampleId = readScript16bits(); - int32 sampleNameOffset = readScript32bits(); - const char * sampleName = (const char *)_code + _currentInstruction + sampleNameOffset - 4; - debugScript("O_SETSAMPLE %d %s", sampleId, sampleName); + uint16 sampleId = readScript16bits(); + int32 sampleNameOffset = readScript32bits(); + const char * sampleName = (const char *)_code + _currentInstruction + sampleNameOffset - 4; + debugScript("O_SETSAMPLE %d %s", sampleId, sampleName); } void Script::O_FREESAMPLE() { - uint16 sample = readScript16bits(); - debugScript("O_FREESAMPLE %d", sample); + uint16 sample = readScript16bits(); + debugScript("O_FREESAMPLE %d", sample); } void Script::O_PLAYSAMPLE() { - uint16 sampleId = readScript16bits(); - uint16 loopType = readScript16bits(); - debugScript("O_PLAYSAMPLE sampleId %d loopType %d", sampleId, loopType); + uint16 sampleId = readScript16bits(); + uint16 loopType = readScript16bits(); + debugScript("O_PLAYSAMPLE sampleId %d loopType %d", sampleId, loopType); } void Script::O_PUTOBJECT() { - uint16 roomId = readScript16bits(); - uint16 slot = readScript16bits(); - uint16 objectId = readScript16bits(); - debugScript("O_PUTOBJECT roomId %d, slot %d, objectId %d", roomId, slot, objectId); + uint16 roomId = readScript16bits(); + uint16 slot = readScript16bits(); + uint16 objectId = readScript16bits(); + debugScript("O_PUTOBJECT roomId %d, slot %d, objectId %d", roomId, slot, objectId); } void Script::O_REMOBJECT() { - uint16 roomId = readScript16bits(); - uint16 objectId = readScript16bits(); + uint16 roomId = readScript16bits(); + uint16 objectId = readScript16bits(); - debugScript("O_REMOBJECT roomId %d objectId %d", roomId, objectId); + debugScript("O_REMOBJECT roomId %d objectId %d", roomId, objectId); } void Script::O_SHOWANIM() { - uint16 slot = readScript16bits(); - uint16 animId = readScript16bits(); + uint16 slot = readScript16bits(); + uint16 animId = readScript16bits(); - debugScript("O_SHOWANIM slot %d, animId %d", slot, animId); + debugScript("O_SHOWANIM slot %d, animId %d", slot, animId); } void Script::O_CHECKANIMEND() { - uint16 slot = readScript16bits(); - uint16 frameId = readScript16bits(); + uint16 slot = readScript16bits(); + uint16 frameId = readScript16bits(); - debugScript("O_CHECKANIMEND slot %d, frameId %d", slot, frameId); + debugScript("O_CHECKANIMEND slot %d, frameId %d", slot, frameId); + _opcodeNF = 1; } void Script::O_FREEANIM() { - uint16 slot = readScript16bits(); - debugScript("O_FREEANIM slot %d", slot); + uint16 slot = readScript16bits(); + debugScript("O_FREEANIM slot %d", slot); } void Script::O_CHECKANIMFRAME() { - uint16 slot = readScript16bits(); - uint16 frameId = readScript16bits(); + uint16 slot = readScript16bits(); + uint16 frameId = readScript16bits(); - debugScript("O_CHECKANIMFRAME slot %d, frameId %d", slot, frameId); + debugScript("O_CHECKANIMFRAME slot %d, frameId %d", slot, frameId); + _opcodeNF = 1; } void Script::O_PUTBACKANIM() { - uint16 roomId = readScript16bits(); - uint16 slot = readScript16bits(); - uint32 animId = readScript32bits(); - debugScript("O_PUTBACKANIM roomId %d, slot %d, animId %d", roomId, slot, animId); + uint16 roomId = readScript16bits(); + uint16 slot = readScript16bits(); + uint32 animId = readScript32bits(); + debugScript("O_PUTBACKANIM roomId %d, slot %d, animId %d", roomId, slot, animId); } void Script::O_REMBACKANIM() { - uint16 roomId = readScript16bits(); - uint16 slot = readScript16bits(); + uint16 roomId = readScript16bits(); + uint16 slot = readScript16bits(); - debugScript("O_REMBACKANIM roomId %d, slot %d", roomId, slot); + debugScript("O_REMBACKANIM roomId %d, slot %d", roomId, slot); } void Script::O_CHECKBACKANIMFRAME() { - uint16 slotId = readScript16bits(); - uint16 frameId = readScript16bits(); + uint16 slotId = readScript16bits(); + uint16 frameId = readScript16bits(); - debugScript("O_CHECKBACKANIMFRAME slotId %d, frameId %d", slotId, frameId); + debugScript("O_CHECKBACKANIMFRAME slotId %d, frameId %d", slotId, frameId); + _opcodeNF = 1; } void Script::O_FREEALLSAMPLES() { - debugScript("O_FREEALLSAMPLES"); + debugScript("O_FREEALLSAMPLES"); } void Script::O_SETMUSIC() { - uint16 musicId = readScript16bits(); + uint16 musicId = readScript16bits(); - debugScript("O_SETMUSIC musicId %d", musicId); + debugScript("O_SETMUSIC musicId %d", musicId); } void Script::O_STOPMUSIC() { - debugScript("O_STOPMUSIC"); + debugScript("O_STOPMUSIC"); } void Script::O__WAIT() { - uint16 pause = readScript16bits(); + uint16 pause = readScript16bits(); + + debugScript("O__WAIT pause %d", pause); - debugScript("O__WAIT pause %d", pause); + _opcodeNF = 1; + } void Script::O_UPDATEOFF() { - debugScript("O_UPDATEOFF"); + debugScript("O_UPDATEOFF"); } void Script::O_UPDATEON() { - debugScript("O_UPDATEON"); + debugScript("O_UPDATEON"); } void Script::O_UPDATE () { - debugScript("O_UPDATE"); + debugScript("O_UPDATE"); } void Script::O_CLS() { - debugScript("O_CLS"); + debugScript("O_CLS"); } void Script::O__CALL() { - int32 address = readScript32bits(); - _stack[_stacktop] = _currentInstruction; - _stacktop++; - _currentInstruction += address - 4; - debugScript("O__CALL 0x%04X", _currentInstruction); + int32 address = readScript32bits(); + _stack[_stacktop] = _currentInstruction; + _stacktop++; + _currentInstruction += address - 4; + debugScript("O__CALL 0x%04X", _currentInstruction); } void Script::O_RETURN() { - // Get the return address - if (_stacktop > 0) { - _stacktop--; - _currentInstruction = _stack[_stacktop]; - debugScript("O_RETURN 0x%04X", _currentInstruction); - } else { - error("Return: Stack is empty"); - } + // Get the return address + if (_stacktop > 0) { + _stacktop--; + _currentInstruction = _stack[_stacktop]; + debugScript("O_RETURN 0x%04X", _currentInstruction); + } else { + error("Return: Stack is empty"); + } } void Script::O_GO() { - int32 opPC = readScript32bits(); - debugScript("O_GO 0x%04X", opPC); - _currentInstruction += opPC - 4; + int32 opPC = readScript32bits(); + debugScript("O_GO 0x%04X", opPC); + _currentInstruction += opPC - 4; } void Script::O_BACKANIMUPDATEOFF() { - uint16 slotId = readScript32bits(); - debugScript("O_BACKANIMUPDATEOFF slotId %d", slotId); + uint16 slotId = readScript32bits(); + debugScript("O_BACKANIMUPDATEOFF slotId %d", slotId); } void Script::O_BACKANIMUPDATEON() { - uint16 slot = readScript16bits(); - debugScript("O_BACKANIMUPDATEON %d", slot); + uint16 slot = readScript16bits(); + debugScript("O_BACKANIMUPDATEON %d", slot); } void Script::O_CHANGECURSOR() { - uint16 cursorId = readScript16bits(); - debugScript("O_CHANGECURSOR %x", cursorId); + uint16 cursorId = readScript16bits(); + debugScript("O_CHANGECURSOR %x", cursorId); } void Script::O_CHANGEANIMTYPE() { - // NOT IMPLEMENTED + // NOT IMPLEMENTED } void Script::O__SETFLAG() { - uint16 flagId = readScript16bits(); - uint16 value = readScript16bits(); + uint16 flagId = readScript16bits(); + uint16 value = readScript16bits(); - if (value & 0x8000) { - value = _flags[value - 0x8000]; - } + if (value & 0x8000) { + value = _flags[value - 0x8000]; + } - debugScript("O__SETFLAG 0x%04X %d", flagId, value); - _flags[flagId - 0x8000] = value; + debugScript("O__SETFLAG 0x%04X (%s) = %d", flagId, Flags::getFlagName(flagId), value); + + _flags[flagId - 0x8000] = value; } void Script::O_COMPARE() { - uint16 flagId = readScript16bits(); - uint16 value = readScript16bits(); + uint16 flagId = readScript16bits(); + uint16 value = readScript16bits(); + + if (value & 0x8000) { + uint16 val = _flags[value - 0x8000]; + debugScript("GetFlagValue 0x%04X (%s), value %d", value, Flags::getFlagName(value), val); - if (value & 0x8000) { - value = _flags[value - 0x8000]; - } + value = val; + } - debugScript("O_COMPARE flagId 0x%04X, value %d", flagId, value); - _result = (_flags[flagId - 0x8000] == value); + debugScript("O_COMPARE flagId 0x%04X (%s), value %d", flagId, Flags::getFlagName(flagId), value); + _result = (_flags[flagId - 0x8000] == value); } void Script::O_JUMPZ() { - int32 offset = readScript32bits(); - debugScript("O_JUMPZ offset 0x%04X", offset); - if (! _result) { - _currentInstruction += offset - 4; - } + int32 offset = readScript32bits(); + debugScript("O_JUMPZ offset 0x%04X", offset); + if (! _result) { + _currentInstruction += offset - 4; + } } void Script::O_JUMPNZ() { - int32 offset = readScript32bits(); - debugScript("O_JUMPNZ offset 0x%04X", offset); - if (_result) { - _currentInstruction += offset - 4; - } + int32 offset = readScript32bits(); + debugScript("O_JUMPNZ offset 0x%04X", offset); + if (_result) { + _currentInstruction += offset - 4; + } } void Script::O_EXIT() { - uint16 exitCode = readScript16bits(); - debugScript("O_EXIT exitCode %d", exitCode); + uint16 exitCode = readScript16bits(); + debugScript("O_EXIT exitCode %d", exitCode); } void Script::O_ADDFLAG() { - uint16 flagId = readScript16bits(); - uint16 value = readScript16bits(); + uint16 flagId = readScript16bits(); + uint16 value = readScript16bits(); - if (value & 0x8000) { - value = _flags[value - 0x8000]; - } + if (value & 0x8000) { + value = _flags[value - 0x8000]; + } - _flags[flagId - 0x8000] += value; - if (_flags[flagId - 0x8000]) - _result = 1; - else - _result = 0; + _flags[flagId - 0x8000] += value; + if (_flags[flagId - 0x8000]) + _result = 1; + else + _result = 0; - debugScript("O_ADDFLAG flagId %d, value %d", flagId, value); + debugScript("O_ADDFLAG flagId %04x (%s), value %d", flagId, Flags::getFlagName(flagId), value); } void Script::O_TALKANIM() { - uint16 animSlot = readScript16bits(); - uint16 slot = readScript16bits(); + uint16 animSlot = readScript16bits(); + uint16 slot = readScript16bits(); - debugScript("O_TALKANIM animSlot %d, slot %d", animSlot, slot); + debugScript("O_TALKANIM animSlot %d, slot %d", animSlot, slot); } void Script::O_SUBFLAG() { - uint16 flagId = readScript16bits(); - uint16 value = readScript16bits(); + uint16 flagId = readScript16bits(); + uint16 value = readScript16bits(); - if (value & 0x8000) { - value = _flags[value - 0x8000]; - } + if (value & 0x8000) { + value = _flags[value - 0x8000]; + } - _flags[flagId - 0x8000] -= value; - if (_flags[flagId - 0x8000]) - _result = 1; - else - _result = 0; + _flags[flagId - 0x8000] -= value; + if (_flags[flagId - 0x8000]) + _result = 1; + else + _result = 0; - debugScript("O_SUBFLAG flagId %d, value %d", flagId, value); + debugScript("O_SUBFLAG flagId %d, value %d", flagId, value); } void Script::O_SETSTRING() { - int32 offset = readScript32bits(); + int32 offset = readScript32bits(); - debugScript("O_SETSTRING 0x%04X", offset); + if (offset >= 80000) { + debug("GetVaria %s", _vm->_variaTxt->getString(offset - 80000)); + } + else if (offset < 2000) { + uint32 of = READ_LE_UINT32(_vm->_talkTxt+offset*4); + const char * txt = (const char *)&_vm->_talkTxt[of]; + _string = &_vm->_talkTxt[of]; + debug("TalkTxt %d %s", of, txt); + } + + debugScript("O_SETSTRING 0x%04X", offset); } void Script::O_ANDFLAG() { - uint16 flagId = readScript16bits(); - uint16 value = readScript16bits(); + uint16 flagId = readScript16bits(); + uint16 value = readScript16bits(); - debugScript("O_ANDFLAG flagId %d, value %d", flagId, value); + debugScript("O_ANDFLAG flagId %d, value %d", flagId, value); - if (value & 0x8000) { - value = _flags[value - 0x8000]; - } + if (value & 0x8000) { + value = _flags[value - 0x8000]; + } - _flags[flagId - 0x8000] &= value; + _flags[flagId - 0x8000] &= value; - if (_flags[flagId - 0x8000]) { - _result = 1; - } else { - _result = 0; - } + if (_flags[flagId - 0x8000]) { + _result = 1; + } else { + _result = 0; + } } void Script::O_GETMOBDATA() { - uint16 flagId = readScript16bits(); - uint16 mobId = readScript16bits(); - uint16 mobOffset = readScript16bits(); + uint16 flagId = readScript16bits(); + uint16 mobId = readScript16bits(); + uint16 mobOffset = readScript16bits(); - debugScript("O_GETMOBDATA flagId %d, modId %d, mobOffset %d", flagId, mobId, mobOffset); + debugScript("O_GETMOBDATA flagId %d, modId %d, mobOffset %d", flagId, mobId, mobOffset); } void Script::O_ORFLAG() { - uint16 flagId = readScript16bits(); - uint16 value = readScript16bits(); - - debugScript("O_ORFLAG flagId %d, value %d", flagId, value); + uint16 flagId = readScript16bits(); + uint16 value = readScript16bits(); + + debugScript("O_ORFLAG flagId %d, value %d", flagId, value); - if (value & 0x8000) { - value = _flags[value - 0x8000]; - } + if (value & 0x8000) { + value = _flags[value - 0x8000]; + } - _flags[flagId - 0x8000] |= value; + _flags[flagId - 0x8000] |= value; - if (_flags[flagId - 0x8000]) { - _result = 1; - } else { - _result = 0; - } + if (_flags[flagId - 0x8000]) { + _result = 1; + } else { + _result = 0; + } } void Script::O_SETMOBDATA() { - uint16 mobId = readScript16bits(); - uint16 mobOffset = readScript16bits(); - uint16 value = readScript16bits(); + uint16 mobId = readScript16bits(); + uint16 mobOffset = readScript16bits(); + uint16 value = readScript16bits(); - debugScript("O_SETMOBDATA mobId %d, mobOffset %d, value %d", mobId, mobOffset, value); + debugScript("O_SETMOBDATA mobId %d, mobOffset %d, value %d", mobId, mobOffset, value); } void Script::O_XORFLAG() { - uint16 flagId = readScript16bits(); - uint16 value = readScript16bits(); + uint16 flagId = readScript16bits(); + uint16 value = readScript16bits(); - debugScript("O_XORFLAG flagId %d, value %d", flagId, value); + debugScript("O_XORFLAG flagId %d, value %d", flagId, value); - if (value & 0x8000) { - value = _flags[value - 0x8000]; - } + if (value & 0x8000) { + value = _flags[value - 0x8000]; + } - _flags[flagId - 0x8000] ^= value; + _flags[flagId - 0x8000] ^= value; - if (_flags[flagId - 0x8000]) { - _result = 1; - } else { - _result = 0; - } + if (_flags[flagId - 0x8000]) { + _result = 1; + } else { + _result = 0; + } } void Script::O_GETMOBTEXT() { - uint16 value = readScript16bits(); + uint16 value = readScript16bits(); - debugScript("O_GETMOBTEXT value %d", value); + debugScript("O_GETMOBTEXT value %d", value); } void Script::O_MOVEHERO() { - uint16 heroId = readScript16bits(); - uint16 x = readScript16bits(); - uint16 y = readScript16bits(); - uint16 dir = readScript16bits(); - - debugScript("O_MOVEHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); + uint16 heroId = readScript16bits(); + uint16 x = readScript16bits(); + uint16 y = readScript16bits(); + uint16 dir = readScript16bits(); + + debugScript("O_MOVEHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); } void Script::O_WALKHERO() { - uint16 heroId = readScript16bits(); + uint16 heroId = readScript16bits(); - debugScript("O_WALKHERO %d", heroId); + debugScript("O_WALKHERO %d", heroId); + _opcodeNF = 1; } void Script::O_SETHERO() {} void Script::O_HEROOFF() { - uint16 heroId = readScript16bits(); - debugScript("O_HEROOFF %d", heroId); + uint16 heroId = readScript16bits(); + debugScript("O_HEROOFF %d", heroId); } void Script::O_HEROON() { - uint16 heroId = readScript16bits(); - debugScript("O_HEROON %d", heroId); + uint16 heroId = readScript16bits(); + debugScript("O_HEROON %d", heroId); } void Script::O_CLSTEXT() {} @@ -499,8 +530,8 @@ void Script::O_REMWALKAREA() {} void Script::O_RESTOREWALKAREA() {} void Script::O_WAITFRAME() { - debugScript("O_WAITFRAME"); - _opcodeNF = true; + debugScript("O_WAITFRAME"); + _opcodeNF = true; } void Script::O_SETFRAME() {} @@ -513,8 +544,9 @@ void Script::O_CHECKINV() {} void Script::O_TALKHERO() {} void Script::O_WAITTEXT() { - uint16 slot = readScript16bits(); - debugScript("O_WAITTEXT slot %d", slot); + uint16 slot = readScript16bits(); + debugScript("O_WAITTEXT slot %d", slot); + _opcodeNF = 1; } void Script::O_SETHEROANIM() {} @@ -526,8 +558,8 @@ void Script::O_CHANGEBACKFRAMES() {} void Script::O_GETBACKANIMDATA() {} void Script::O_GETANIMDATA() {} void Script::O_SETBGCODE() { - int32 bgcode = readScript32bits(); - debugScript("O_SETBGCODE %d", bgcode); + int32 bgcode = readScript32bits(); + debugScript("O_SETBGCODE %d", bgcode); } void Script::O_SETBACKFRAME() {} void Script::O_GETRND() {} @@ -535,13 +567,32 @@ void Script::O_TALKBACKANIM() {} void Script::O_LOADPATH() {} void Script::O_GETCHAR() { - uint16 flagId = readScript16bits(); - debugScript("O_GETCHAR %d", flagId); + uint16 flagId = readScript16bits(); + debugScript("O_GETCHAR %04X (%s)", flagId, Flags::getFlagName(flagId)); + + _flags[flagId - 0x8000] = *_string; + + _string++; } void Script::O_SETDFLAG() {} void Script::O_CALLDFLAG() {} -void Script::O_PRINTAT() {} + +void Script::O_PRINTAT() { + uint16 slot = readScript16bits(); + uint16 fr1 = readScript16bits(); + uint16 fr2 = readScript16bits(); + + debugScript("O_PRINTAT slot %d, fr1 %d, fr2 %d", slot, fr1, fr2); + + _vm->printAt((const char *)_string, 0, fr1); + + while (*_string) { + ++_string; + } + ++_string; +} + void Script::O_ZOOMIN() {} void Script::O_ZOOMOUT() {} void Script::O_SETSTRINGOFFSET() {} @@ -557,396 +608,409 @@ void Script::O_DISABLEDIALOGOPT() {} void Script::O_SHOWDIALOGBOX() {} void Script::O_STOPSAMPLE() { - uint16 slot = readScript16bits(); - debugScript("O_STOPSAMPLE slot %d", slot); + uint16 slot = readScript16bits(); + debugScript("O_STOPSAMPLE slot %d", slot); } void Script::O_BACKANIMRANGE() { - uint16 slotId = readScript16bits(); - uint16 animId = readScript16bits(); - uint16 low = readScript16bits(); - uint16 high = readScript16bits(); + uint16 slotId = readScript16bits(); + uint16 animId = readScript16bits(); + uint16 low = readScript16bits(); + uint16 high = readScript16bits(); - debugScript("O_BACKANIMRANGE slotId %d, animId %d, low %d, high %d", slotId, animId, low, high); + debugScript("O_BACKANIMRANGE slotId %d, animId %d, low %d, high %d", slotId, animId, low, high); } void Script::O_CLEARPATH() { - debugScript("O_CLEARPATH"); + debugScript("O_CLEARPATH"); } void Script::O_SETPATH() { - debugScript("O_SETPATH"); + debugScript("O_SETPATH"); } void Script::O_GETHEROX() { - uint16 heroId = readScript16bits(); - uint16 flagId = readScript16bits(); + uint16 heroId = readScript16bits(); + uint16 flagId = readScript16bits(); - debugScript("O_GETHEROX heroId %d, flagId %d", heroId, flagId); + debugScript("O_GETHEROX heroId %d, flagId %d", heroId, flagId); } void Script::O_GETHEROY() { - uint16 heroId = readScript16bits(); - uint16 flagId = readScript16bits(); + uint16 heroId = readScript16bits(); + uint16 flagId = readScript16bits(); - debugScript("O_GETHEROY heroId %d, flagId %d", heroId, flagId); + debugScript("O_GETHEROY heroId %d, flagId %d", heroId, flagId); } void Script::O_GETHEROD() { - uint16 heroId = readScript16bits(); - uint16 flagId = readScript16bits(); + uint16 heroId = readScript16bits(); + uint16 flagId = readScript16bits(); - debugScript("O_GETHEROD heroId %d, flagId %d", heroId, flagId); + debugScript("O_GETHEROD heroId %d, flagId %d", heroId, flagId); } void Script::O_PUSHSTRING() { - debugScript("O_PUSHSTRING"); + debugScript("O_PUSHSTRING"); } void Script::O_POPSTRING() { - debugScript("O_POPSTRING"); + debugScript("O_POPSTRING"); } void Script::O_SETFGCODE() { - int32 offset = readScript32bits(); + int32 offset = readScript32bits(); - debugScript("O_SETFGCODE offset %04X", offset); + debugScript("O_SETFGCODE offset %04X", offset); } void Script::O_STOPHERO() { - uint16 heroId = readScript16bits(); + uint16 heroId = readScript16bits(); - debugScript("O_STOPHERO heroId %d", heroId); + debugScript("O_STOPHERO heroId %d", heroId); } void Script::O_ANIMUPDATEOFF() { - uint16 slotId = readScript16bits(); - debugScript("O_ANIMUPDATEOFF slotId %d", slotId); + uint16 slotId = readScript16bits(); + debugScript("O_ANIMUPDATEOFF slotId %d", slotId); } void Script::O_ANIMUPDATEON() { - uint16 slotId = readScript16bits(); - debugScript("O_ANIMUPDATEON slotId %d", slotId); + uint16 slotId = readScript16bits(); + debugScript("O_ANIMUPDATEON slotId %d", slotId); } void Script::O_FREECURSOR() { - debugScript("O_FREECURSOR"); + debugScript("O_FREECURSOR"); } void Script::O_ADDINVQUIET() { - uint16 heroId = readScript16bits(); - uint16 itemId = readScript16bits(); + uint16 heroId = readScript16bits(); + uint16 itemId = readScript16bits(); - debugScript("O_ADDINVQUIET heorId %d, itemId %d", heroId, itemId); + debugScript("O_ADDINVQUIET heorId %d, itemId %d", heroId, itemId); } void Script::O_RUNHERO() { - uint16 heroId = readScript16bits(); - uint16 x = readScript16bits(); - uint16 y = readScript16bits(); - uint16 dir = readScript16bits(); + uint16 heroId = readScript16bits(); + uint16 x = readScript16bits(); + uint16 y = readScript16bits(); + uint16 dir = readScript16bits(); - debugScript("O_RUNHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); + debugScript("O_RUNHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); } void Script::O_SETBACKANIMDATA() { - uint16 animId = readScript16bits(); - uint16 animOffset = readScript16bits(); - uint16 wart = readScript16bits(); + uint16 animId = readScript16bits(); + uint16 animOffset = readScript16bits(); + uint16 wart = readScript16bits(); - debugScript("O_SETBACKANIMDATA animId %d, animOffset %d, wart %d", animId, animOffset, wart); + debugScript("O_SETBACKANIMDATA animId %d, animOffset %d, wart %d", animId, animOffset, wart); } void Script::O_VIEWFLC() { - uint16 animNr = readScript16bits(); - debugScript("O_VIEWFLC animNr %d", animNr); + uint16 animNr = readScript16bits(); + debugScript("O_VIEWFLC animNr %d", animNr); + _vm->loadAnim(animNr, false); } void Script::O_CHECKFLCFRAME() { - uint16 frameNr = readScript16bits(); + uint16 frameNr = readScript16bits(); - debugScript("O_CHECKFLCFRAME frame number %d", frameNr); + debugScript("O_CHECKFLCFRAME frame number %d", frameNr); - const Video::FlicDecoder &flicPlayer = _vm->_flicPlayer; + const Video::FlicDecoder &flicPlayer = _vm->_flicPlayer; - if (flicPlayer.getCurFrame() != frameNr) - { - // Move instruction pointer before current instruciton - // must do this check once again till it's false - _currentInstruction -= 2; - } + if (flicPlayer.getCurFrame() != frameNr) + { + // Move instruction pointer before current instruciton + // must do this check once again till it's false + _currentInstruction -= 2; + _opcodeNF = 1; + } } void Script::O_CHECKFLCEND() { - debugScript("O_CHECKFLCEND"); + debugScript("O_CHECKFLCEND"); + + const Video::FlicDecoder &flicPlayer = _vm->_flicPlayer; - const Video::FlicDecoder &flicPlayer = _vm->_flicPlayer; + //debug("frameCount %d, currentFrame %d", flicPlayer.getFrameCount(), flicPlayer.getCurFrame()); - if (flicPlayer.getFrameCount() - flicPlayer.getCurFrame() <= 1) - { - // Move instruction pointer before current instruciton - // must do this check once again till it's false - _currentInstruction -= 2; - } + if (flicPlayer.getFrameCount() - flicPlayer.getCurFrame() > 1) + { + // Move instruction pointer before current instruciton + // must do this check once again till it's false + _currentInstruction -= 2; + _opcodeNF = 1; + } } void Script::O_FREEFLC() { - debugScript("O_FREEFLC"); + debugScript("O_FREEFLC"); } void Script::O_TALKHEROSTOP() { - uint16 heroId = readScript16bits(); - debugScript("O_TALKHEROSTOP %d", heroId); + uint16 heroId = readScript16bits(); + debugScript("O_TALKHEROSTOP %d", heroId); } void Script::O_HEROCOLOR() { - uint16 heroId = readScript16bits(); - uint16 kolorr = readScript16bits(); - debugScript("O_HEROCOLOR heroId %d, kolorr %d", heroId, kolorr); + uint16 heroId = readScript16bits(); + uint16 kolorr = readScript16bits(); + debugScript("O_HEROCOLOR heroId %d, kolorr %d", heroId, kolorr); } void Script::O_GRABMAPA() { - debugScript("O_GRABMAPA"); + debugScript("O_GRABMAPA"); } void Script::O_ENABLENAK() { - uint16 nakId = readScript16bits(); - debugScript("O_ENABLENAK nakId %d", nakId); + uint16 nakId = readScript16bits(); + debugScript("O_ENABLENAK nakId %d", nakId); } void Script::O_DISABLENAK() { - uint16 nakId = readScript16bits(); - debugScript("O_DISABLENAK nakId %d", nakId); + uint16 nakId = readScript16bits(); + debugScript("O_DISABLENAK nakId %d", nakId); } void Script::O_GETMOBNAME() { - uint16 war = readScript16bits(); - debugScript("O_GETMOBNAME war %d", war); + uint16 war = readScript16bits(); + debugScript("O_GETMOBNAME war %d", war); } void Script::O_SWAPINVENTORY() { - uint16 heroId = readScript16bits(); - debugScript("O_SWAPINVENTORY heroId %d", heroId); + uint16 heroId = readScript16bits(); + debugScript("O_SWAPINVENTORY heroId %d", heroId); } void Script::O_CLEARINVENTORY() { - uint16 heroId = readScript16bits(); - debugScript("O_CLEARINVENTORY heroId %d", heroId); + uint16 heroId = readScript16bits(); + debugScript("O_CLEARINVENTORY heroId %d", heroId); } void Script::O_SKIPTEXT() { - debugScript("O_SKIPTEXT"); + debugScript("O_SKIPTEXT"); } void Script::O_SETVOICEH() { - uint16 txn = readScript16bits(); - debugScript("O_SETVOICEH txn %d", txn); + uint16 txn = readScript16bits(); + debugScript("O_SETVOICEH txn %d", txn); } void Script::O_SETVOICEA() { - uint16 txn = readScript16bits(); - debugScript("O_SETVOICEA txn %d", txn); + uint16 txn = readScript16bits(); + debugScript("O_SETVOICEA txn %d", txn); } void Script::O_SETVOICEB() { - uint16 txn = readScript16bits(); - debugScript("O_SETVOICEB txn %d", txn); + uint16 txn = readScript16bits(); + debugScript("O_SETVOICEB txn %d", txn); } void Script::O_SETVOICEC() { - uint16 txn = readScript16bits(); - debugScript("O_SETVOICEC txn %d", txn); + uint16 txn = readScript16bits(); + debugScript("O_SETVOICEC txn %d", txn); } void Script::O_VIEWFLCLOOP() { - uint16 animId = readScript16bits(); - debugScript("O_VIEWFLCLOOP animId %d", animId); + uint16 value = readScript16bits(); + debugScript("O_VIEWFLCLOOP animId %d", value); + + if (value & 0x8000) { + value = _flags[value - 0x8000]; + } + + _vm->loadAnim(value, true); } void Script::O_FLCSPEED() { - uint16 speed = readScript16bits(); - debugScript("O_FLCSPEED speed %d", speed); + uint16 speed = readScript16bits(); + debugScript("O_FLCSPEED speed %d", speed); } void Script::O_OPENINVENTORY() { - debugScript("O_OPENINVENTORY"); + debugScript("O_OPENINVENTORY"); + _opcodeNF = 1; } void Script::O_KRZYWA() { - debugScript("O_KRZYWA"); + debugScript("O_KRZYWA"); } void Script::O_GETKRZYWA() { - debugScript("O_GETKRZYWA"); + debugScript("O_GETKRZYWA"); } void Script::O_GETMOB() { - uint16 flagId = readScript16bits(); - uint16 mx = readScript16bits(); - uint16 my = readScript16bits(); - debugScript("O_GETMOB flagId %d, mx %d, my %d", flagId, mx, my); + uint16 flagId = readScript16bits(); + uint16 mx = readScript16bits(); + uint16 my = readScript16bits(); + debugScript("O_GETMOB flagId %d, mx %d, my %d", flagId, mx, my); } void Script::O_INPUTLINE() { - debugScript("O_INPUTLINE"); + debugScript("O_INPUTLINE"); } void Script::O_SETVOICED() { - uint16 txn = readScript16bits(); - debugScript("O_SETVOICED txn %d", txn); + uint16 txn = readScript16bits(); + debugScript("O_SETVOICED txn %d", txn); } void Script::O_BREAK_POINT() { - debugScript("O_BREAK_POINT"); + debugScript("O_BREAK_POINT"); } Script::OpcodeFunc Script::_opcodes[NUM_OPCODES] = { - &Script::O_WAITFOREVER, - &Script::O_BLACKPALETTE, - &Script::O_SETUPPALETTE, - &Script::O_INITROOM, - &Script::O_SETSAMPLE, - &Script::O_FREESAMPLE, - &Script::O_PLAYSAMPLE, - &Script::O_PUTOBJECT, - &Script::O_REMOBJECT, - &Script::O_SHOWANIM, - &Script::O_CHECKANIMEND, - &Script::O_FREEANIM, - &Script::O_CHECKANIMFRAME, - &Script::O_PUTBACKANIM, - &Script::O_REMBACKANIM, - &Script::O_CHECKBACKANIMFRAME, - &Script::O_FREEALLSAMPLES, - &Script::O_SETMUSIC, - &Script::O_STOPMUSIC, - &Script::O__WAIT, - &Script::O_UPDATEOFF, - &Script::O_UPDATEON, - &Script::O_UPDATE , - &Script::O_CLS, - &Script::O__CALL, - &Script::O_RETURN, - &Script::O_GO, - &Script::O_BACKANIMUPDATEOFF, - &Script::O_BACKANIMUPDATEON, - &Script::O_CHANGECURSOR, - &Script::O_CHANGEANIMTYPE, - &Script::O__SETFLAG, - &Script::O_COMPARE, - &Script::O_JUMPZ, - &Script::O_JUMPNZ, - &Script::O_EXIT, - &Script::O_ADDFLAG, - &Script::O_TALKANIM, - &Script::O_SUBFLAG, - &Script::O_SETSTRING, - &Script::O_ANDFLAG, - &Script::O_GETMOBDATA, - &Script::O_ORFLAG, - &Script::O_SETMOBDATA, - &Script::O_XORFLAG, - &Script::O_GETMOBTEXT, - &Script::O_MOVEHERO, - &Script::O_WALKHERO, - &Script::O_SETHERO, - &Script::O_HEROOFF, - &Script::O_HEROON, - &Script::O_CLSTEXT, - &Script::O_CALLTABLE, - &Script::O_CHANGEMOB, - &Script::O_ADDINV, - &Script::O_REMINV, - &Script::O_REPINV, - &Script::O_OBSOLETE_GETACTION, - &Script::O_ADDWALKAREA, - &Script::O_REMWALKAREA, - &Script::O_RESTOREWALKAREA, - &Script::O_WAITFRAME, - &Script::O_SETFRAME, - &Script::O_RUNACTION, - &Script::O_COMPAREHI, - &Script::O_COMPARELO, - &Script::O_PRELOADSET, - &Script::O_FREEPRELOAD, - &Script::O_CHECKINV, - &Script::O_TALKHERO, - &Script::O_WAITTEXT, - &Script::O_SETHEROANIM, - &Script::O_WAITHEROANIM, - &Script::O_GETHERODATA, - &Script::O_GETMOUSEBUTTON, - &Script::O_CHANGEFRAMES, - &Script::O_CHANGEBACKFRAMES, - &Script::O_GETBACKANIMDATA, - &Script::O_GETANIMDATA, - &Script::O_SETBGCODE, - &Script::O_SETBACKFRAME, - &Script::O_GETRND, - &Script::O_TALKBACKANIM, - &Script::O_LOADPATH, - &Script::O_GETCHAR, - &Script::O_SETDFLAG, - &Script::O_CALLDFLAG, - &Script::O_PRINTAT, - &Script::O_ZOOMIN, - &Script::O_ZOOMOUT, - &Script::O_SETSTRINGOFFSET, - &Script::O_GETOBJDATA, - &Script::O_SETOBJDATA, - &Script::O_SWAPOBJECTS, - &Script::O_CHANGEHEROSET, - &Script::O_ADDSTRING, - &Script::O_SUBSTRING, - &Script::O_INITDIALOG, - &Script::O_ENABLEDIALOGOPT, - &Script::O_DISABLEDIALOGOPT, - &Script::O_SHOWDIALOGBOX, - &Script::O_STOPSAMPLE, - &Script::O_BACKANIMRANGE, - &Script::O_CLEARPATH, - &Script::O_SETPATH, - &Script::O_GETHEROX, - &Script::O_GETHEROY, - &Script::O_GETHEROD, - &Script::O_PUSHSTRING, - &Script::O_POPSTRING, - &Script::O_SETFGCODE, - &Script::O_STOPHERO, - &Script::O_ANIMUPDATEOFF, - &Script::O_ANIMUPDATEON, - &Script::O_FREECURSOR, - &Script::O_ADDINVQUIET, - &Script::O_RUNHERO, - &Script::O_SETBACKANIMDATA, - &Script::O_VIEWFLC, - &Script::O_CHECKFLCFRAME, - &Script::O_CHECKFLCEND, - &Script::O_FREEFLC, - &Script::O_TALKHEROSTOP, - &Script::O_HEROCOLOR, - &Script::O_GRABMAPA, - &Script::O_ENABLENAK, - &Script::O_DISABLENAK, - &Script::O_GETMOBNAME, - &Script::O_SWAPINVENTORY, - &Script::O_CLEARINVENTORY, - &Script::O_SKIPTEXT, - &Script::O_SETVOICEH, - &Script::O_SETVOICEA, - &Script::O_SETVOICEB, - &Script::O_SETVOICEC, - &Script::O_VIEWFLCLOOP, - &Script::O_FLCSPEED, - &Script::O_OPENINVENTORY, - &Script::O_KRZYWA, - &Script::O_GETKRZYWA, - &Script::O_GETMOB, - &Script::O_INPUTLINE, - &Script::O_SETVOICED, - &Script::O_BREAK_POINT, + &Script::O_WAITFOREVER, + &Script::O_BLACKPALETTE, + &Script::O_SETUPPALETTE, + &Script::O_INITROOM, + &Script::O_SETSAMPLE, + &Script::O_FREESAMPLE, + &Script::O_PLAYSAMPLE, + &Script::O_PUTOBJECT, + &Script::O_REMOBJECT, + &Script::O_SHOWANIM, + &Script::O_CHECKANIMEND, + &Script::O_FREEANIM, + &Script::O_CHECKANIMFRAME, + &Script::O_PUTBACKANIM, + &Script::O_REMBACKANIM, + &Script::O_CHECKBACKANIMFRAME, + &Script::O_FREEALLSAMPLES, + &Script::O_SETMUSIC, + &Script::O_STOPMUSIC, + &Script::O__WAIT, + &Script::O_UPDATEOFF, + &Script::O_UPDATEON, + &Script::O_UPDATE , + &Script::O_CLS, + &Script::O__CALL, + &Script::O_RETURN, + &Script::O_GO, + &Script::O_BACKANIMUPDATEOFF, + &Script::O_BACKANIMUPDATEON, + &Script::O_CHANGECURSOR, + &Script::O_CHANGEANIMTYPE, + &Script::O__SETFLAG, + &Script::O_COMPARE, + &Script::O_JUMPZ, + &Script::O_JUMPNZ, + &Script::O_EXIT, + &Script::O_ADDFLAG, + &Script::O_TALKANIM, + &Script::O_SUBFLAG, + &Script::O_SETSTRING, + &Script::O_ANDFLAG, + &Script::O_GETMOBDATA, + &Script::O_ORFLAG, + &Script::O_SETMOBDATA, + &Script::O_XORFLAG, + &Script::O_GETMOBTEXT, + &Script::O_MOVEHERO, + &Script::O_WALKHERO, + &Script::O_SETHERO, + &Script::O_HEROOFF, + &Script::O_HEROON, + &Script::O_CLSTEXT, + &Script::O_CALLTABLE, + &Script::O_CHANGEMOB, + &Script::O_ADDINV, + &Script::O_REMINV, + &Script::O_REPINV, + &Script::O_OBSOLETE_GETACTION, + &Script::O_ADDWALKAREA, + &Script::O_REMWALKAREA, + &Script::O_RESTOREWALKAREA, + &Script::O_WAITFRAME, + &Script::O_SETFRAME, + &Script::O_RUNACTION, + &Script::O_COMPAREHI, + &Script::O_COMPARELO, + &Script::O_PRELOADSET, + &Script::O_FREEPRELOAD, + &Script::O_CHECKINV, + &Script::O_TALKHERO, + &Script::O_WAITTEXT, + &Script::O_SETHEROANIM, + &Script::O_WAITHEROANIM, + &Script::O_GETHERODATA, + &Script::O_GETMOUSEBUTTON, + &Script::O_CHANGEFRAMES, + &Script::O_CHANGEBACKFRAMES, + &Script::O_GETBACKANIMDATA, + &Script::O_GETANIMDATA, + &Script::O_SETBGCODE, + &Script::O_SETBACKFRAME, + &Script::O_GETRND, + &Script::O_TALKBACKANIM, + &Script::O_LOADPATH, + &Script::O_GETCHAR, + &Script::O_SETDFLAG, + &Script::O_CALLDFLAG, + &Script::O_PRINTAT, + &Script::O_ZOOMIN, + &Script::O_ZOOMOUT, + &Script::O_SETSTRINGOFFSET, + &Script::O_GETOBJDATA, + &Script::O_SETOBJDATA, + &Script::O_SWAPOBJECTS, + &Script::O_CHANGEHEROSET, + &Script::O_ADDSTRING, + &Script::O_SUBSTRING, + &Script::O_INITDIALOG, + &Script::O_ENABLEDIALOGOPT, + &Script::O_DISABLEDIALOGOPT, + &Script::O_SHOWDIALOGBOX, + &Script::O_STOPSAMPLE, + &Script::O_BACKANIMRANGE, + &Script::O_CLEARPATH, + &Script::O_SETPATH, + &Script::O_GETHEROX, + &Script::O_GETHEROY, + &Script::O_GETHEROD, + &Script::O_PUSHSTRING, + &Script::O_POPSTRING, + &Script::O_SETFGCODE, + &Script::O_STOPHERO, + &Script::O_ANIMUPDATEOFF, + &Script::O_ANIMUPDATEON, + &Script::O_FREECURSOR, + &Script::O_ADDINVQUIET, + &Script::O_RUNHERO, + &Script::O_SETBACKANIMDATA, + &Script::O_VIEWFLC, + &Script::O_CHECKFLCFRAME, + &Script::O_CHECKFLCEND, + &Script::O_FREEFLC, + &Script::O_TALKHEROSTOP, + &Script::O_HEROCOLOR, + &Script::O_GRABMAPA, + &Script::O_ENABLENAK, + &Script::O_DISABLENAK, + &Script::O_GETMOBNAME, + &Script::O_SWAPINVENTORY, + &Script::O_CLEARINVENTORY, + &Script::O_SKIPTEXT, + &Script::O_SETVOICEH, + &Script::O_SETVOICEA, + &Script::O_SETVOICEB, + &Script::O_SETVOICEC, + &Script::O_VIEWFLCLOOP, + &Script::O_FLCSPEED, + &Script::O_OPENINVENTORY, + &Script::O_KRZYWA, + &Script::O_GETKRZYWA, + &Script::O_GETMOB, + &Script::O_INPUTLINE, + &Script::O_SETVOICED, + &Script::O_BREAK_POINT, }; } +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/script.h b/engines/prince/script.h index e801529187f0..dc050daeea28 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -26,7 +26,7 @@ #include "common/random.h" namespace Common { - class SeekableReadStream; + class SeekableReadStream; } namespace Prince { @@ -35,189 +35,193 @@ class PrinceEngine; class Script { public: - Script(PrinceEngine *vm); - virtual ~Script(); + Script(PrinceEngine *vm); + virtual ~Script(); - bool loadFromStream(Common::SeekableReadStream &stream); + bool loadFromStream(Common::SeekableReadStream &stream); - void step(); + void step(); private: - PrinceEngine *_vm; - - byte *_code; - uint32 _codeSize; - uint32 _currentInstruction; - uint16 _lastOpcode; - uint32 _lastInstruction; - byte _result; - int16 _flags[2000]; - bool _opcodeNF; - - // Stack - static const uint32 _STACK_SIZE = 500; - uint16 _stack[_STACK_SIZE]; - uint8 _stacktop; - uint8 _savedStacktop; - - // Helper functions - void checkPC(uint32 address); - uint8 getCodeByte(uint32 address); - uint8 readScript8bits(); - uint16 readScript16bits(); - uint32 readScript32bits(); - uint16 readScript8or16bits(); - void debugScript(const char *s, ...); - - typedef void (Script::*OpcodeFunc)(); - static OpcodeFunc _opcodes[]; - - void O_WAITFOREVER(); - void O_BLACKPALETTE(); - void O_SETUPPALETTE(); - void O_INITROOM(); - void O_SETSAMPLE(); - void O_FREESAMPLE(); - void O_PLAYSAMPLE(); - void O_PUTOBJECT(); - void O_REMOBJECT(); - void O_SHOWANIM(); - void O_CHECKANIMEND(); - void O_FREEANIM(); - void O_CHECKANIMFRAME(); - void O_PUTBACKANIM(); - void O_REMBACKANIM(); - void O_CHECKBACKANIMFRAME(); - void O_FREEALLSAMPLES(); - void O_SETMUSIC(); - void O_STOPMUSIC(); - void O__WAIT(); - void O_UPDATEOFF(); - void O_UPDATEON(); - void O_UPDATE (); - void O_CLS(); - void O__CALL(); - void O_RETURN(); - void O_GO(); - void O_BACKANIMUPDATEOFF(); - void O_BACKANIMUPDATEON(); - void O_CHANGECURSOR(); - void O_CHANGEANIMTYPE(); - void O__SETFLAG(); - void O_COMPARE(); - void O_JUMPZ(); - void O_JUMPNZ(); - void O_EXIT(); - void O_ADDFLAG(); - void O_TALKANIM(); - void O_SUBFLAG(); - void O_SETSTRING(); - void O_ANDFLAG(); - void O_GETMOBDATA(); - void O_ORFLAG(); - void O_SETMOBDATA(); - void O_XORFLAG(); - void O_GETMOBTEXT(); - void O_MOVEHERO(); - void O_WALKHERO(); - void O_SETHERO(); - void O_HEROOFF(); - void O_HEROON(); - void O_CLSTEXT(); - void O_CALLTABLE(); - void O_CHANGEMOB(); - void O_ADDINV(); - void O_REMINV(); - void O_REPINV(); - void O_OBSOLETE_GETACTION(); - void O_ADDWALKAREA(); - void O_REMWALKAREA(); - void O_RESTOREWALKAREA(); - void O_WAITFRAME(); - void O_SETFRAME(); - void O_RUNACTION(); - void O_COMPAREHI(); - void O_COMPARELO(); - void O_PRELOADSET(); - void O_FREEPRELOAD(); - void O_CHECKINV(); - void O_TALKHERO(); - void O_WAITTEXT(); - void O_SETHEROANIM(); - void O_WAITHEROANIM(); - void O_GETHERODATA(); - void O_GETMOUSEBUTTON(); - void O_CHANGEFRAMES(); - void O_CHANGEBACKFRAMES(); - void O_GETBACKANIMDATA(); - void O_GETANIMDATA(); - void O_SETBGCODE(); - void O_SETBACKFRAME(); - void O_GETRND(); - void O_TALKBACKANIM(); - void O_LOADPATH(); - void O_GETCHAR(); - void O_SETDFLAG(); - void O_CALLDFLAG(); - void O_PRINTAT(); - void O_ZOOMIN(); - void O_ZOOMOUT(); - void O_SETSTRINGOFFSET(); - void O_GETOBJDATA(); - void O_SETOBJDATA(); - void O_SWAPOBJECTS(); - void O_CHANGEHEROSET(); - void O_ADDSTRING(); - void O_SUBSTRING(); - void O_INITDIALOG(); - void O_ENABLEDIALOGOPT(); - void O_DISABLEDIALOGOPT(); - void O_SHOWDIALOGBOX(); - void O_STOPSAMPLE(); - void O_BACKANIMRANGE(); - void O_CLEARPATH(); - void O_SETPATH(); - void O_GETHEROX(); - void O_GETHEROY(); - void O_GETHEROD(); - void O_PUSHSTRING(); - void O_POPSTRING(); - void O_SETFGCODE(); - void O_STOPHERO(); - void O_ANIMUPDATEOFF(); - void O_ANIMUPDATEON(); - void O_FREECURSOR(); - void O_ADDINVQUIET(); - void O_RUNHERO(); - void O_SETBACKANIMDATA(); - void O_VIEWFLC(); - void O_CHECKFLCFRAME(); - void O_CHECKFLCEND(); - void O_FREEFLC(); - void O_TALKHEROSTOP(); - void O_HEROCOLOR(); - void O_GRABMAPA(); - void O_ENABLENAK(); - void O_DISABLENAK(); - void O_GETMOBNAME(); - void O_SWAPINVENTORY(); - void O_CLEARINVENTORY(); - void O_SKIPTEXT(); - void O_SETVOICEH(); - void O_SETVOICEA(); - void O_SETVOICEB(); - void O_SETVOICEC(); - void O_VIEWFLCLOOP(); - void O_FLCSPEED(); - void O_OPENINVENTORY(); - void O_KRZYWA(); - void O_GETKRZYWA(); - void O_GETMOB(); - void O_INPUTLINE(); - void O_SETVOICED(); - void O_BREAK_POINT(); + PrinceEngine *_vm; + + byte *_code; + uint32 _codeSize; + uint32 _currentInstruction; + uint16 _lastOpcode; + uint32 _lastInstruction; + byte _result; + int16 _flags[2000]; + bool _opcodeNF; + + // Stack + static const uint32 _STACK_SIZE = 500; + uint32 _stack[_STACK_SIZE]; + uint8 _stacktop; + uint8 _savedStacktop; + + const byte * _string; + + // Helper functions + void checkPC(uint32 address); + uint8 getCodeByte(uint32 address); + uint8 readScript8bits(); + uint16 readScript16bits(); + uint32 readScript32bits(); + uint16 readScript8or16bits(); + void debugScript(const char *s, ...); + + typedef void (Script::*OpcodeFunc)(); + static OpcodeFunc _opcodes[]; + + void O_WAITFOREVER(); + void O_BLACKPALETTE(); + void O_SETUPPALETTE(); + void O_INITROOM(); + void O_SETSAMPLE(); + void O_FREESAMPLE(); + void O_PLAYSAMPLE(); + void O_PUTOBJECT(); + void O_REMOBJECT(); + void O_SHOWANIM(); + void O_CHECKANIMEND(); + void O_FREEANIM(); + void O_CHECKANIMFRAME(); + void O_PUTBACKANIM(); + void O_REMBACKANIM(); + void O_CHECKBACKANIMFRAME(); + void O_FREEALLSAMPLES(); + void O_SETMUSIC(); + void O_STOPMUSIC(); + void O__WAIT(); + void O_UPDATEOFF(); + void O_UPDATEON(); + void O_UPDATE (); + void O_CLS(); + void O__CALL(); + void O_RETURN(); + void O_GO(); + void O_BACKANIMUPDATEOFF(); + void O_BACKANIMUPDATEON(); + void O_CHANGECURSOR(); + void O_CHANGEANIMTYPE(); + void O__SETFLAG(); + void O_COMPARE(); + void O_JUMPZ(); + void O_JUMPNZ(); + void O_EXIT(); + void O_ADDFLAG(); + void O_TALKANIM(); + void O_SUBFLAG(); + void O_SETSTRING(); + void O_ANDFLAG(); + void O_GETMOBDATA(); + void O_ORFLAG(); + void O_SETMOBDATA(); + void O_XORFLAG(); + void O_GETMOBTEXT(); + void O_MOVEHERO(); + void O_WALKHERO(); + void O_SETHERO(); + void O_HEROOFF(); + void O_HEROON(); + void O_CLSTEXT(); + void O_CALLTABLE(); + void O_CHANGEMOB(); + void O_ADDINV(); + void O_REMINV(); + void O_REPINV(); + void O_OBSOLETE_GETACTION(); + void O_ADDWALKAREA(); + void O_REMWALKAREA(); + void O_RESTOREWALKAREA(); + void O_WAITFRAME(); + void O_SETFRAME(); + void O_RUNACTION(); + void O_COMPAREHI(); + void O_COMPARELO(); + void O_PRELOADSET(); + void O_FREEPRELOAD(); + void O_CHECKINV(); + void O_TALKHERO(); + void O_WAITTEXT(); + void O_SETHEROANIM(); + void O_WAITHEROANIM(); + void O_GETHERODATA(); + void O_GETMOUSEBUTTON(); + void O_CHANGEFRAMES(); + void O_CHANGEBACKFRAMES(); + void O_GETBACKANIMDATA(); + void O_GETANIMDATA(); + void O_SETBGCODE(); + void O_SETBACKFRAME(); + void O_GETRND(); + void O_TALKBACKANIM(); + void O_LOADPATH(); + void O_GETCHAR(); + void O_SETDFLAG(); + void O_CALLDFLAG(); + void O_PRINTAT(); + void O_ZOOMIN(); + void O_ZOOMOUT(); + void O_SETSTRINGOFFSET(); + void O_GETOBJDATA(); + void O_SETOBJDATA(); + void O_SWAPOBJECTS(); + void O_CHANGEHEROSET(); + void O_ADDSTRING(); + void O_SUBSTRING(); + void O_INITDIALOG(); + void O_ENABLEDIALOGOPT(); + void O_DISABLEDIALOGOPT(); + void O_SHOWDIALOGBOX(); + void O_STOPSAMPLE(); + void O_BACKANIMRANGE(); + void O_CLEARPATH(); + void O_SETPATH(); + void O_GETHEROX(); + void O_GETHEROY(); + void O_GETHEROD(); + void O_PUSHSTRING(); + void O_POPSTRING(); + void O_SETFGCODE(); + void O_STOPHERO(); + void O_ANIMUPDATEOFF(); + void O_ANIMUPDATEON(); + void O_FREECURSOR(); + void O_ADDINVQUIET(); + void O_RUNHERO(); + void O_SETBACKANIMDATA(); + void O_VIEWFLC(); + void O_CHECKFLCFRAME(); + void O_CHECKFLCEND(); + void O_FREEFLC(); + void O_TALKHEROSTOP(); + void O_HEROCOLOR(); + void O_GRABMAPA(); + void O_ENABLENAK(); + void O_DISABLENAK(); + void O_GETMOBNAME(); + void O_SWAPINVENTORY(); + void O_CLEARINVENTORY(); + void O_SKIPTEXT(); + void O_SETVOICEH(); + void O_SETVOICEA(); + void O_SETVOICEB(); + void O_SETVOICEC(); + void O_VIEWFLCLOOP(); + void O_FLCSPEED(); + void O_OPENINVENTORY(); + void O_KRZYWA(); + void O_GETKRZYWA(); + void O_GETMOB(); + void O_INPUTLINE(); + void O_SETVOICED(); + void O_BREAK_POINT(); }; } #endif + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/sound.cpp b/engines/prince/sound.cpp index 3285390aca6e..40f182e63039 100644 --- a/engines/prince/sound.cpp +++ b/engines/prince/sound.cpp @@ -27,6 +27,8 @@ #include "prince/prince.h" #include "prince/sound.h" +#include "prince/musNum.h" + #include "common/config-manager.h" #include "common/memstream.h" #include "common/archive.h" @@ -57,13 +59,67 @@ const char * MusicPlayer::_musTable[] = { const uint8 MusicPlayer::_musRoomTable[] = { 0, - 3, - 9, - 9, - 9, - 13, - 9, - 9 + 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 }; diff --git a/engines/prince/sound.h b/engines/prince/sound.h index f4ba9ba45f82..7219411b3674 100644 --- a/engines/prince/sound.h +++ b/engines/prince/sound.h @@ -43,28 +43,28 @@ class PrinceEngine; class MusicPlayer: public Audio::MidiPlayer { private: - PrinceEngine *_vm; - byte *_data; - int _dataSize; - bool _isGM; + PrinceEngine *_vm; + byte *_data; + int _dataSize; + bool _isGM; - // Start MIDI File - void sndMidiStart(); + // Start MIDI File + void sndMidiStart(); - // Stop MIDI File - void sndMidiStop(); + // Stop MIDI File + void sndMidiStop(); public: - MusicPlayer(PrinceEngine *vm); - ~MusicPlayer(); + MusicPlayer(PrinceEngine *vm); + ~MusicPlayer(); - void loadMidi(const char *); - void killMidi(); + void loadMidi(const char *); + void killMidi(); - virtual void send(uint32 b); - virtual void sendToChannel(byte channel, uint32 b); + virtual void send(uint32 b); + virtual void sendToChannel(byte channel, uint32 b); - static const char * _musTable[]; - static const uint8 _musRoomTable[]; + static const char * _musTable[]; + static const uint8 _musRoomTable[]; }; } // End of namespace Prince diff --git a/engines/prince/variatxt.cpp b/engines/prince/variatxt.cpp index 073080e5053b..0788d449e3be 100644 --- a/engines/prince/variatxt.cpp +++ b/engines/prince/variatxt.cpp @@ -29,21 +29,21 @@ VariaTxt::VariaTxt() : _dataSize(0), _data(NULL) { } VariaTxt::~VariaTxt() { - _dataSize = 0; - delete[] _data; - _dataSize = NULL; + _dataSize = 0; + delete[] _data; + _dataSize = NULL; } bool VariaTxt::loadFromStream(Common::SeekableReadStream &stream) { - _dataSize = stream.size(); - _data = new byte [_dataSize]; - stream.read(_data, _dataSize); - return true; + _dataSize = stream.size(); + _data = new byte [_dataSize]; + stream.read(_data, _dataSize); + return true; } const char * VariaTxt::getString(uint32 stringId) { - uint32 stringOffset = READ_LE_UINT32(_data + stringId); + uint32 stringOffset = READ_LE_UINT32(_data + stringId); if (stringOffset > _dataSize) { assert(false); diff --git a/engines/prince/variatxt.h b/engines/prince/variatxt.h index 5983054d5758..dcdba7bd8ae4 100644 --- a/engines/prince/variatxt.h +++ b/engines/prince/variatxt.h @@ -30,13 +30,13 @@ class VariaTxt { ~VariaTxt(); - bool loadFromStream(Common::SeekableReadStream &stream); + bool loadFromStream(Common::SeekableReadStream &stream); - const char * getString(uint32 stringId); + const char * getString(uint32 stringId); private: - uint32 _dataSize; - byte *_data; + uint32 _dataSize; + byte *_data; }; } From cb31768e3df03b7ed0f5740ee7c46e8987a54154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Sat, 2 Nov 2013 01:29:26 +0000 Subject: [PATCH 041/374] PRINCE: Arivald's monolog during intro kinda works --- engines/prince/font.h | 2 ++ engines/prince/prince.cpp | 60 +++++++++++++++++++++++++--------- engines/prince/prince.h | 25 ++++++++++++-- engines/prince/script.cpp | 68 +++++++++++++++++++++++++++++++++------ engines/prince/script.h | 2 ++ 5 files changed, 131 insertions(+), 26 deletions(-) diff --git a/engines/prince/font.h b/engines/prince/font.h index 54e6b6b0a56c..629b5d61ebfb 100644 --- a/engines/prince/font.h +++ b/engines/prince/font.h @@ -49,6 +49,8 @@ class Font : public Graphics::Font { virtual void drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const override; + virtual int getKerningOffset(byte left, byte right) const { return -2; } + private: struct ChrData { byte * _pixels; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 9ca7a62fad05..98bf4b71784f 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -86,10 +86,17 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL), _locationNr(0), _debugger(NULL), _objectList(NULL), _mobList(NULL), _midiPlayer(NULL), _cameraX(0), _newCameraX(0) { + + // Debug/console setup + DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); + DebugMan.addDebugChannel(DebugChannel::kEngine, "engine", "Prince Engine debug channel"); + + DebugMan.enableDebugChannel("script"); + _rnd = new Common::RandomSource("prince"); _debugger = new Debugger(this); _midiPlayer = new MusicPlayer(this); - _textSlots[0] = ""; + } PrinceEngine::~PrinceEngine() { @@ -114,6 +121,7 @@ Common::Error PrinceEngine::run() { debug("Adding all path: %s", gameDataDir.getPath().c_str()); SearchMan.addSubDirectoryMatching(gameDataDir, "all", 0, 2); + SearchMan.addSubDirectoryMatching(gameDataDir, "data/voices/output", 0, 2); Common::SeekableReadStream *font1stream = SearchMan.createReadStreamForMember("font1.raw"); if (!font1stream) @@ -415,19 +423,49 @@ void PrinceEngine::hotspot() { } } -void PrinceEngine::printAt(const char *s, uint16 x, uint16 y) { - _textSlots[0] = s; +void PrinceEngine::printAt(uint32 slot, uint8 color, const 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); + + Text &text = _textSlots[slot]; + text._str = s; + text._x = x; + text._y = y; + text._color = color; } uint32 PrinceEngine::getTextWidth(const char *s) { uint16 textW = 0; - while (*s) { - textW += *s; - ++s; + while (*s) { + textW += _font.getCharWidth(*s) + _font.getKerningOffset(0, 0); + ++s; } return textW; } +void PrinceEngine::showTexts() { + for (uint32 slot = 0; slot < MAXTEXTS; ++slot) { + Text& text = _textSlots[slot]; + if (!text._str && !text._time) + continue; + + Common::Array lines; + _font.wordWrapText(text._str, _graph->_frontScreen->w, lines); + + for (int i = 0; i < lines.size(); ++i) { + _font.drawString( + _graph->_frontScreen, + lines[i], + text._x - getTextWidth(lines[i].c_str())/2, + text._y - (lines.size() - i) * (_font.getFontHeight()), + _graph->_frontScreen->w, + text._color + ); + } + + --text._time; + } +} void PrinceEngine::drawScreen() { const Graphics::Surface *roomSurface = _roomBmp.getSurface(); @@ -443,15 +481,7 @@ void PrinceEngine::drawScreen() { // _graph->drawTransparent(_objectList->getSurface()); hotspot(); - _font.drawString( - _graph->_frontScreen, - _textSlots[0], - 320 - getTextWidth(_textSlots[0])/2, - 470 - _font.getFontHeight(), - _graph->_frontScreen->w, - 216 - ); - + showTexts(); getDebugger()->onFrame(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 080eca5ead90..43d94654c788 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -58,6 +58,25 @@ class MobList; class MusicPlayer; class VariaTxt; +struct Text { + const char *_str; + uint16 _x, _y; + uint16 _time; + uint32 _color; + + Text() : _str(NULL), _x(0), _y(0), _time(0), _color(255){ + } +}; + +struct DebugChannel { + +enum Type { + kScript, + kEngine +}; + +}; + class PrinceEngine : public Engine { protected: Common::Error run(); @@ -86,9 +105,10 @@ class PrinceEngine : public Engine { virtual GUI::Debugger *getDebugger(); void changeCursor(uint16 curId); - void printAt(const char *s, uint16 x, uint16 y); + void printAt(uint32 slot, uint8 color, const char *s, uint16 x, uint16 y); - const char * _textSlots[1000]; + static const uint8 MAXTEXTS = 32; + Text _textSlots[MAXTEXTS]; private: bool playNextFrame(); @@ -97,6 +117,7 @@ class PrinceEngine : public Engine { void scrollCameraRight(int16 delta); void scrollCameraLeft(int16 delta); void drawScreen(); + void showTexts(); uint32 getTextWidth(const char *s); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 7ab723a4fbdc..5e2b095b653e 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -29,6 +29,7 @@ #include "common/debug.h" #include "common/debug-channels.h" #include "common/stream.h" +#include "common/archive.h" namespace Prince { @@ -66,7 +67,7 @@ void Script::debugScript(const char *s, ...) { Common::String str = Common::String::format("@0x%04X: ", _lastInstruction); str += Common::String::format("op %02d: ", _lastOpcode); - debug("%s %s", str.c_str(), buf); + debugC(10, DebugChannel::kScript, "PrinceEngine::Script %s %s", str.c_str(), buf); } void Script::step() { @@ -85,7 +86,7 @@ void Script::step() { error("Trying to execute unknown opcode %s", dstr.c_str()); - debug("%s", dstr.c_str()); + debugScript("%s", dstr.c_str()); // Execute the current opcode OpcodeFunc op = _opcodes[_lastOpcode]; @@ -330,7 +331,7 @@ void Script::O_COMPARE() { value = val; } - debugScript("O_COMPARE flagId 0x%04X (%s), value %d", flagId, Flags::getFlagName(flagId), value); + debugScript("O_COMPARE flagId 0x%04X (%s), value %d ?= %d", flagId, Flags::getFlagName(flagId), value, _flags[flagId - 0x8000]); _result = (_flags[flagId - 0x8000] == value); } @@ -398,6 +399,7 @@ void Script::O_SUBFLAG() { void Script::O_SETSTRING() { int32 offset = readScript32bits(); + _currentString = offset; if (offset >= 80000) { debug("GetVaria %s", _vm->_variaTxt->getString(offset - 80000)); @@ -409,7 +411,7 @@ void Script::O_SETSTRING() { debug("TalkTxt %d %s", of, txt); } - debugScript("O_SETSTRING 0x%04X", offset); + debugScript("O_SETSTRING %04d", offset); } void Script::O_ANDFLAG() { @@ -545,8 +547,15 @@ void Script::O_TALKHERO() {} void Script::O_WAITTEXT() { uint16 slot = readScript16bits(); - debugScript("O_WAITTEXT slot %d", slot); - _opcodeNF = 1; + if (slot & 0x8000) { + slot = _flags[slot - 0x8000]; + } + //debugScript("O_WAITTEXT slot %d", slot); + Text &text = _vm->_textSlots[slot]; + if (text._time) { + _opcodeNF = 1; + _currentInstruction -= 4; + } } void Script::O_SETHEROANIM() {} @@ -568,10 +577,11 @@ void Script::O_LOADPATH() {} void Script::O_GETCHAR() { uint16 flagId = readScript16bits(); - debugScript("O_GETCHAR %04X (%s)", flagId, Flags::getFlagName(flagId)); _flags[flagId - 0x8000] = *_string; + debugScript("O_GETCHAR %04X (%s) %02x", flagId, Flags::getFlagName(flagId), _flags[flagId - 0x8000]); + _string++; } @@ -585,12 +595,15 @@ void Script::O_PRINTAT() { debugScript("O_PRINTAT slot %d, fr1 %d, fr2 %d", slot, fr1, fr2); - _vm->printAt((const char *)_string, 0, fr1); + uint8 color = _flags[Flags::KOLOR - 0x8000]; + + _vm->printAt(slot, color, (const char *)_string, fr1, fr2); while (*_string) { ++_string; } ++_string; + debug("O_PRINTAT %x", *_string); } void Script::O_ZOOMIN() {} @@ -732,7 +745,7 @@ void Script::O_CHECKFLCFRAME() { void Script::O_CHECKFLCEND() { - debugScript("O_CHECKFLCEND"); + //debugScript("O_CHECKFLCEND"); const Video::FlicDecoder &flicPlayer = _vm->_flicPlayer; @@ -795,24 +808,60 @@ void Script::O_SKIPTEXT() { debugScript("O_SKIPTEXT"); } +void Script::SetVoice(uint32 slot) { + const Common::String streamName = Common::String::format("%03d-01.WAV", _currentString); + debugScript("Loading wav %s slot %d", streamName.c_str(), slot); + + Common::SeekableReadStream *voiceStream = SearchMan.createReadStreamForMember(streamName); + if (!voiceStream) { + error("Can't open %s", streamName.c_str()); + } + uint32 id = voiceStream->readUint32LE(); + if (id != 0x46464952) { + error("It's not RIFF file %s", streamName.c_str()); + return; + } + + voiceStream->skip(0x20); + id = voiceStream->readUint32LE(); + if (id != 0x61746164) { + error("No data section in %s id %04x", streamName.c_str(), id); + return; + } + + id = voiceStream->readUint32LE(); + id <<= 3; + id /= 22050; + id += 2; + + _vm->_textSlots[slot]._time = voiceStream->readUint32LE(); + + debugScript("SetVoice slot %d time %04x", slot, _vm->_textSlots[slot]._time); + delete voiceStream; +} + void Script::O_SETVOICEH() { uint16 txn = readScript16bits(); debugScript("O_SETVOICEH txn %d", txn); + SetVoice(txn); } void Script::O_SETVOICEA() { uint16 txn = readScript16bits(); debugScript("O_SETVOICEA txn %d", txn); + SetVoice(txn); } void Script::O_SETVOICEB() { uint16 txn = readScript16bits(); debugScript("O_SETVOICEB txn %d", txn); + SetVoice(txn); } void Script::O_SETVOICEC() { uint16 txn = readScript16bits(); debugScript("O_SETVOICEC txn %d", txn); + SetVoice(txn); } void Script::O_VIEWFLCLOOP() { @@ -858,6 +907,7 @@ void Script::O_INPUTLINE() { void Script::O_SETVOICED() { uint16 txn = readScript16bits(); debugScript("O_SETVOICED txn %d", txn); + SetVoice(txn); } void Script::O_BREAK_POINT() { diff --git a/engines/prince/script.h b/engines/prince/script.h index dc050daeea28..68b44cb1e356 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -61,6 +61,7 @@ class Script { uint8 _savedStacktop; const byte * _string; + uint32 _currentString; // Helper functions void checkPC(uint32 address); @@ -70,6 +71,7 @@ class Script { uint32 readScript32bits(); uint16 readScript8or16bits(); void debugScript(const char *s, ...); + void SetVoice(uint32 slot); typedef void (Script::*OpcodeFunc)(); static OpcodeFunc _opcodes[]; From 9250a6f6f8804fec74704ea9e01bdb6d8af7d0ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Sat, 2 Nov 2013 02:02:53 +0000 Subject: [PATCH 042/374] PRINCE: More intro cleanup --- engines/prince/prince.cpp | 10 ++++++++-- engines/prince/script.cpp | 40 ++++++++++++++++++++++++++------------- engines/prince/script.h | 1 + 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 98bf4b71784f..5910ca5e3595 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -495,6 +495,8 @@ void PrinceEngine::mainLoop() { //CursorMan.showMouse(true); while (!shouldQuit()) { + uint32 currentTime = _system->getMillis(); + Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); while (eventMan->pollEvent(event)) { @@ -524,9 +526,13 @@ void PrinceEngine::mainLoop() { _script->step(); drawScreen(); - - _system->delayMillis(10); + // Calculate the frame delay based off a desired frame time + int delay = 1000/15 - int32(_system->getMillis() - currentTime); + // Ensure non-negative + delay = delay < 0 ? 0 : delay; + _system->delayMillis(delay); + _cameraX = _newCameraX; } } diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 5e2b095b653e..b3fdf3536dd1 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -36,7 +36,8 @@ namespace Prince { static const uint16 NUM_OPCODES = 144; Script::Script(PrinceEngine *vm) : - _code(NULL), _stacktop(0), _vm(vm), _opcodeNF(false) { + _code(NULL), _stacktop(0), _vm(vm), _opcodeNF(false), + _waitFlag(0) { } Script::~Script() { @@ -59,15 +60,17 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) { void Script::debugScript(const char *s, ...) { char buf[STRINGBUFLEN]; - va_list va; + va_list va; va_start(va, s); vsnprintf(buf, STRINGBUFLEN, s, va); va_end(va); Common::String str = Common::String::format("@0x%04X: ", _lastInstruction); - str += Common::String::format("op %02d: ", _lastOpcode); - debugC(10, DebugChannel::kScript, "PrinceEngine::Script %s %s", str.c_str(), buf); + str += Common::String::format("op %04d: ", _lastOpcode); + //debugC(10, DebugChannel::kScript, "PrinceEngine::Script %s %s", str.c_str(), buf); + + debug("PrinceEngine::Script %s %s", str.c_str(), buf); } void Script::step() { @@ -86,7 +89,7 @@ void Script::step() { error("Trying to execute unknown opcode %s", dstr.c_str()); - debugScript("%s", dstr.c_str()); + debugScript(""); // Execute the current opcode OpcodeFunc op = _opcodes[_lastOpcode]; @@ -246,8 +249,21 @@ void Script::O__WAIT() { debugScript("O__WAIT pause %d", pause); - _opcodeNF = 1; - + if (_waitFlag == 0) { + // set new wait flag value and continue + _waitFlag = pause; + _opcodeNF = 1; + _currentInstruction -= 4; + return; + } + + --_waitFlag; + + if (_waitFlag > 0) { + _opcodeNF = 1; + _currentInstruction -= 4; + return; + } } void Script::O_UPDATEOFF() { @@ -331,8 +347,8 @@ void Script::O_COMPARE() { value = val; } - debugScript("O_COMPARE flagId 0x%04X (%s), value %d ?= %d", flagId, Flags::getFlagName(flagId), value, _flags[flagId - 0x8000]); - _result = (_flags[flagId - 0x8000] == value); + _result = !(_flags[flagId - 0x8000] == value); + debugScript("O_COMPARE flagId 0x%04X (%s), value %d == %d (%d)", flagId, Flags::getFlagName(flagId), value, _flags[flagId - 0x8000], _result); } void Script::O_JUMPZ() { @@ -550,7 +566,6 @@ void Script::O_WAITTEXT() { if (slot & 0x8000) { slot = _flags[slot - 0x8000]; } - //debugScript("O_WAITTEXT slot %d", slot); Text &text = _vm->_textSlots[slot]; if (text._time) { _opcodeNF = 1; @@ -582,7 +597,7 @@ void Script::O_GETCHAR() { debugScript("O_GETCHAR %04X (%s) %02x", flagId, Flags::getFlagName(flagId), _flags[flagId - 0x8000]); - _string++; + ++_string; } void Script::O_SETDFLAG() {} @@ -603,7 +618,6 @@ void Script::O_PRINTAT() { ++_string; } ++_string; - debug("O_PRINTAT %x", *_string); } void Script::O_ZOOMIN() {} @@ -723,7 +737,7 @@ void Script::O_SETBACKANIMDATA() { void Script::O_VIEWFLC() { uint16 animNr = readScript16bits(); - debugScript("O_VIEWFLC animNr %d", animNr); + debug("O_VIEWFLC animNr %d", animNr); _vm->loadAnim(animNr, false); } diff --git a/engines/prince/script.h b/engines/prince/script.h index 68b44cb1e356..de8db0bfb50a 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -59,6 +59,7 @@ class Script { uint32 _stack[_STACK_SIZE]; uint8 _stacktop; uint8 _savedStacktop; + uint32 _waitFlag; const byte * _string; uint32 _currentString; From e72742d0e3c040869e57c559cbc6ed8504dd5d09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Sat, 2 Nov 2013 15:28:56 +0000 Subject: [PATCH 043/374] PRINCE: intro works much beter. Still some synchronization issues --- engines/prince/prince.cpp | 10 ++++----- engines/prince/prince.h | 2 ++ engines/prince/script.cpp | 46 +++++++++++++++++++++++++++++---------- engines/prince/script.h | 4 ++++ 4 files changed, 45 insertions(+), 17 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 5910ca5e3595..1d8f71ddcbcd 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -85,7 +85,7 @@ Graphics::Surface *loadCursor(const char *curName) PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL), _locationNr(0), _debugger(NULL), _objectList(NULL), _mobList(NULL), _midiPlayer(NULL), - _cameraX(0), _newCameraX(0) { + _cameraX(0), _newCameraX(0), _frameNr(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -479,6 +479,7 @@ void PrinceEngine::drawScreen() { //if (_objectList) // _graph->drawTransparent(_objectList->getSurface()); + hotspot(); showTexts(); @@ -490,10 +491,6 @@ void PrinceEngine::drawScreen() { void PrinceEngine::mainLoop() { - //loadLocation(1); - //changeCursor(1); - //CursorMan.showMouse(true); - while (!shouldQuit()) { uint32 currentTime = _system->getMillis(); @@ -524,8 +521,8 @@ void PrinceEngine::mainLoop() { if (shouldQuit()) return; - _script->step(); drawScreen(); + _script->step(); // Calculate the frame delay based off a desired frame time int delay = 1000/15 - int32(_system->getMillis() - currentTime); @@ -534,6 +531,7 @@ void PrinceEngine::mainLoop() { _system->delayMillis(delay); _cameraX = _newCameraX; + ++_frameNr; } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 43d94654c788..68a7793157f6 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -110,6 +110,8 @@ class PrinceEngine : public Engine { static const uint8 MAXTEXTS = 32; Text _textSlots[MAXTEXTS]; + uint64 _frameNr; + private: bool playNextFrame(); void keyHandler(Common::Event event); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index b3fdf3536dd1..49a0a9751ce1 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -31,13 +31,16 @@ #include "common/stream.h" #include "common/archive.h" +#include "audio/decoders/wave.h" +#include "audio/audiostream.h" + namespace Prince { static const uint16 NUM_OPCODES = 144; Script::Script(PrinceEngine *vm) : _code(NULL), _stacktop(0), _vm(vm), _opcodeNF(false), - _waitFlag(0) { + _waitFlag(0), _voiceStream(NULL) { } Script::~Script() { @@ -70,7 +73,7 @@ void Script::debugScript(const char *s, ...) { str += Common::String::format("op %04d: ", _lastOpcode); //debugC(10, DebugChannel::kScript, "PrinceEngine::Script %s %s", str.c_str(), buf); - debug("PrinceEngine::Script %s %s", str.c_str(), buf); + debug("PrinceEngine::Script frame %ld %s %s", _vm->_frameNr, str.c_str(), buf); } void Script::step() { @@ -164,6 +167,12 @@ void Script::O_PLAYSAMPLE() { uint16 sampleId = readScript16bits(); uint16 loopType = readScript16bits(); debugScript("O_PLAYSAMPLE sampleId %d loopType %d", sampleId, loopType); + + if (_voiceStream) { + + Audio::RewindableAudioStream *audioStream = Audio::makeWAVStream(_voiceStream, DisposeAfterUse::YES); + _vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, audioStream, sampleId); + } } void Script::O_PUTOBJECT() { @@ -621,22 +630,36 @@ void Script::O_PRINTAT() { } void Script::O_ZOOMIN() {} + void Script::O_ZOOMOUT() {} + void Script::O_SETSTRINGOFFSET() {} + void Script::O_GETOBJDATA() {} + void Script::O_SETOBJDATA() {} + void Script::O_SWAPOBJECTS() {} + void Script::O_CHANGEHEROSET() {} + void Script::O_ADDSTRING() {} + void Script::O_SUBSTRING() {} + void Script::O_INITDIALOG() {} + void Script::O_ENABLEDIALOGOPT() {} + void Script::O_DISABLEDIALOGOPT() {} + void Script::O_SHOWDIALOGBOX() {} void Script::O_STOPSAMPLE() { uint16 slot = readScript16bits(); debugScript("O_STOPSAMPLE slot %d", slot); + + _vm->_mixer->stopID(slot); } void Script::O_BACKANIMRANGE() { @@ -826,32 +849,33 @@ void Script::SetVoice(uint32 slot) { const Common::String streamName = Common::String::format("%03d-01.WAV", _currentString); debugScript("Loading wav %s slot %d", streamName.c_str(), slot); - Common::SeekableReadStream *voiceStream = SearchMan.createReadStreamForMember(streamName); - if (!voiceStream) { + _voiceStream = SearchMan.createReadStreamForMember(streamName); + if (!_voiceStream) { error("Can't open %s", streamName.c_str()); } - uint32 id = voiceStream->readUint32LE(); + uint32 id = _voiceStream->readUint32LE(); if (id != 0x46464952) { error("It's not RIFF file %s", streamName.c_str()); return; } - voiceStream->skip(0x20); - id = voiceStream->readUint32LE(); + _voiceStream->skip(0x20); + id = _voiceStream->readUint32LE(); if (id != 0x61746164) { error("No data section in %s id %04x", streamName.c_str(), id); return; } - id = voiceStream->readUint32LE(); + id = _voiceStream->readUint32LE(); + debugScript("SetVoice slot %d time %04x", slot, id); id <<= 3; id /= 22050; id += 2; - _vm->_textSlots[slot]._time = voiceStream->readUint32LE(); + _vm->_textSlots[slot]._time = id; - debugScript("SetVoice slot %d time %04x", slot, _vm->_textSlots[slot]._time); - delete voiceStream; + debugScript("SetVoice slot %d time %04x", slot, id); + _voiceStream->seek(0); } void Script::O_SETVOICEH() { diff --git a/engines/prince/script.h b/engines/prince/script.h index de8db0bfb50a..1343051fc9b7 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -25,6 +25,8 @@ #include "common/random.h" +#include "audio/mixer.h" + namespace Common { class SeekableReadStream; } @@ -60,9 +62,11 @@ class Script { uint8 _stacktop; uint8 _savedStacktop; uint32 _waitFlag; + Audio::SoundHandle _soundHandle; const byte * _string; uint32 _currentString; + Common::SeekableReadStream *_voiceStream; // Helper functions void checkPC(uint32 address); From 8c85eff622e3bcec7685b6daf44aef094b6bdb09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Mon, 4 Nov 2013 11:28:10 +0000 Subject: [PATCH 044/374] PRINCE: code formating fixed --- engines/prince/archive.h | 1 + engines/prince/debugger.cpp | 165 +++++++++-------- engines/prince/debugger.h | 1 + engines/prince/detection.cpp | 292 +++++++++++++++--------------- engines/prince/flags.cpp | 334 +++++++++++++++++------------------ engines/prince/flags.h | 5 + engines/prince/font.cpp | 60 ++++--- engines/prince/font.h | 34 ++-- engines/prince/mhwanh.cpp | 56 +++--- engines/prince/mhwanh.h | 25 +-- engines/prince/mob.cpp | 50 +++--- engines/prince/mob.h | 23 ++- engines/prince/module.mk | 46 ++--- engines/prince/musNum.h | 123 +++++++------ engines/prince/prince.cpp | 34 ++-- engines/prince/script.cpp | 41 ++++- engines/prince/script.h | 11 ++ 17 files changed, 691 insertions(+), 610 deletions(-) diff --git a/engines/prince/archive.h b/engines/prince/archive.h index 3f5c5be4efb6..8e106693dcd7 100644 --- a/engines/prince/archive.h +++ b/engines/prince/archive.h @@ -25,6 +25,7 @@ #include "common/archive.h" +// This is here just as remainder that archive support is missing namespace Price { class Archive : public Common::Archive { diff --git a/engines/prince/debugger.cpp b/engines/prince/debugger.cpp index 2415c1c7ceea..be9677b99f3e 100644 --- a/engines/prince/debugger.cpp +++ b/engines/prince/debugger.cpp @@ -26,113 +26,130 @@ namespace Prince { Debugger::Debugger(PrinceEngine *vm) : GUI::Debugger(), _vm(vm) { - DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); - DCmd_Register("setflag", WRAP_METHOD(Debugger, Cmd_SetFlag)); - DCmd_Register("getflag", WRAP_METHOD(Debugger, Cmd_GetFlag)); - DCmd_Register("clearflag", WRAP_METHOD(Debugger, Cmd_ClearFlag)); - DCmd_Register("viewflc", WRAP_METHOD(Debugger, Cmd_ViewFlc)); - DCmd_Register("initroom", WRAP_METHOD(Debugger, Cmd_InitRoom)); - DCmd_Register("changecursor", WRAP_METHOD(Debugger, Cmd_ChangeCursor)); + DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); + DCmd_Register("level", WRAP_METHOD(Debugger, Cmd_DebugLevel)); + DCmd_Register("setflag", WRAP_METHOD(Debugger, Cmd_SetFlag)); + DCmd_Register("getflag", WRAP_METHOD(Debugger, Cmd_GetFlag)); + DCmd_Register("clearflag", WRAP_METHOD(Debugger, Cmd_ClearFlag)); + DCmd_Register("viewflc", WRAP_METHOD(Debugger, Cmd_ViewFlc)); + DCmd_Register("initroom", WRAP_METHOD(Debugger, Cmd_InitRoom)); + DCmd_Register("changecursor", WRAP_METHOD(Debugger, Cmd_ChangeCursor)); } static int strToInt(const char *s) { - if (!*s) - // No string at all - return 0; - else if (toupper(s[strlen(s) - 1]) != 'H') - // Standard decimal string - return atoi(s); - - // Hexadecimal string - uint tmp = 0; - int read = sscanf(s, "%xh", &tmp); - if (read < 1) - error("strToInt failed on string \"%s\"", s); - return (int)tmp; + if (!*s) + // No string at all + return 0; + else if (toupper(s[strlen(s) - 1]) != 'H') + // Standard decimal string + return atoi(s); + + // Hexadecimal string + uint tmp = 0; + int read = sscanf(s, "%xh", &tmp); + if (read < 1) + error("strToInt failed on string \"%s\"", s); + return (int)tmp; +} + +bool Debugger::Cmd_DebugLevel(int argc, const char **argv) { + if (argc == 1) { + DebugPrintf("Debugging is currently set at level %d\n", gDebugLevel); + } else { // set level + gDebugLevel = atoi(argv[1]); + if (0 <= gDebugLevel && gDebugLevel < 11) { + DebugPrintf("Debug level set to level %d\n", gDebugLevel); + } else if (gDebugLevel < 0) { + DebugPrintf("Debugging is now disabled\n"); + } else + DebugPrintf("Not a valid debug level (0 - 10)\n"); + } + + return true; } /* * This command sets a flag */ bool Debugger::Cmd_SetFlag(int argc, const char **argv) { - // Check for a flag to set - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } - - int flagNum = strToInt(argv[1]); - //g_globals->setFlag(flagNum); - return true; + // Check for a flag to set + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + //g_globals->setFlag(flagNum); + return true; } /* * This command gets the value of a flag */ bool Debugger::Cmd_GetFlag(int argc, const char **argv) { - // Check for an flag to display - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } - - int flagNum = strToInt(argv[1]); - //DebugPrintf("Value: %d\n", g_globals->getFlag(flagNum)); - return true; + // Check for an flag to display + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + //DebugPrintf("Value: %d\n", g_globals->getFlag(flagNum)); + return true; } /* * This command clears a flag */ bool Debugger::Cmd_ClearFlag(int argc, const char **argv) { - // Check for a flag to clear - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } - - int flagNum = strToInt(argv[1]); - //g_globals->clearFlag(flagNum); - return true; + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + //g_globals->clearFlag(flagNum); + return true; } /* * This command starts new flc anim */ bool Debugger::Cmd_ViewFlc(int argc, const char **argv) { - // Check for a flag to clear - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } - - int flagNum = strToInt(argv[1]); - _vm->loadAnim(flagNum, false); - return true; + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + _vm->loadAnim(flagNum, false); + return true; } bool Debugger::Cmd_InitRoom(int argc, const char **argv) { - // Check for a flag to clear - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } - - int flagNum = strToInt(argv[1]); - _vm->loadLocation(flagNum); - return true; + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + _vm->loadLocation(flagNum); + return true; } bool Debugger::Cmd_ChangeCursor(int argc, const char **argv) { - // Check for a flag to clear - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } - - int flagNum = strToInt(argv[1]); - _vm->changeCursor(flagNum); - return true; + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + _vm->changeCursor(flagNum); + return true; } } diff --git a/engines/prince/debugger.h b/engines/prince/debugger.h index 087f29e550e8..08b1676fd738 100644 --- a/engines/prince/debugger.h +++ b/engines/prince/debugger.h @@ -36,6 +36,7 @@ class Debugger : public GUI::Debugger { virtual ~Debugger() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ private: + bool Cmd_DebugLevel(int argc, const char **argv); bool Cmd_SetFlag(int argc, const char **argv); bool Cmd_GetFlag(int argc, const char **argv); bool Cmd_ClearFlag(int argc, const char **argv); diff --git a/engines/prince/detection.cpp b/engines/prince/detection.cpp index c5f6039ca129..fa9df38c9007 100644 --- a/engines/prince/detection.cpp +++ b/engines/prince/detection.cpp @@ -1,145 +1,147 @@ -/* 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 "base/plugins.h" -#include "engines/advancedDetector.h" - -#include "prince/prince.h" - -namespace Prince { - -struct PrinceGameDescription { - ADGameDescription desc; - - int gameType; -}; - -int PrinceEngine::getGameType() const { - return _gameDescription->gameType; -} - -const char *PrinceEngine::getGameId() const { - return _gameDescription->desc.gameid; -} - -uint32 PrinceEngine::getFeatures() const { - return _gameDescription->desc.flags; -} - -Common::Language PrinceEngine::getLanguage() const { - return _gameDescription->desc.language; -} - -} - -static const PlainGameDescriptor princeGames[] = { - {"prince", "Prince Game"}, - {0, 0} -}; - -namespace Prince { - -static const PrinceGameDescription gameDescriptions[] = { - - // German - { - { - "prince", - "Galador", - AD_ENTRY1s("databank.ptc", "5fa03833177331214ec1354761b1d2ee", 3565031), - Common::DE_DEU, - Common::kPlatformWindows, - ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) - }, - 0 - }, - // Polish - { - { - "prince", - "Ksiaze i Tchorz", - AD_ENTRY1s("databank.ptc", "48ec9806bda9d152acbea8ce31c93c49", 3435298), - Common::PL_POL, - Common::kPlatformWindows, - ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) - }, - 1 - }, - - - { AD_TABLE_END_MARKER, 0 } -}; - -} // End of namespace Prince - -using namespace Prince; - -// we match from data too, to stop detection from a non-top-level directory -const static char *directoryGlobs[] = { - "all", - 0 -}; - -class PrinceMetaEngine : public AdvancedMetaEngine { -public: - PrinceMetaEngine() : AdvancedMetaEngine(Prince::gameDescriptions, sizeof(Prince::PrinceGameDescription), princeGames) { - _singleid = "prince"; - _maxScanDepth = 2; - _directoryGlobs = directoryGlobs; - } - - virtual const char *getName() const { - return "Prince Engine"; - } - - virtual const char *getOriginalCopyright() const { - return "Copyright (C)"; - } - - virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; - virtual bool hasFeature(MetaEngineFeature f) const; -}; - -bool PrinceMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { - using namespace Prince; - const PrinceGameDescription *gd = (const PrinceGameDescription *)desc; - if (gd) { - *engine = new PrinceEngine(syst, gd); - } - return gd != 0; -} - -bool PrinceMetaEngine::hasFeature(MetaEngineFeature f) const { - return false; -} - -bool Prince::PrinceEngine::hasFeature(EngineFeature f) const { - return false;//(f == kSupportsRTL); -} - -#if PLUGIN_ENABLED_DYNAMIC(PRINCE) -REGISTER_PLUGIN_DYNAMIC(PRINCE, PLUGIN_TYPE_ENGINE, PrinceMetaEngine); -#else -REGISTER_PLUGIN_STATIC(PRINCE, PLUGIN_TYPE_ENGINE, PrinceMetaEngine); -#endif +/* 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 "base/plugins.h" +#include "engines/advancedDetector.h" + +#include "prince/prince.h" + +namespace Prince { + +struct PrinceGameDescription { + ADGameDescription desc; + + int gameType; +}; + +int PrinceEngine::getGameType() const { + return _gameDescription->gameType; +} + +const char *PrinceEngine::getGameId() const { + return _gameDescription->desc.gameid; +} + +uint32 PrinceEngine::getFeatures() const { + return _gameDescription->desc.flags; +} + +Common::Language PrinceEngine::getLanguage() const { + return _gameDescription->desc.language; +} + +} + +static const PlainGameDescriptor princeGames[] = { + {"prince", "Prince Game"}, + {0, 0} +}; + +namespace Prince { + +static const PrinceGameDescription gameDescriptions[] = { + + // German + { + { + "prince", + "Galador", + AD_ENTRY1s("databank.ptc", "5fa03833177331214ec1354761b1d2ee", 3565031), + Common::DE_DEU, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NONE) + }, + 0 + }, + // Polish + { + { + "prince", + "Ksiaze i Tchorz", + AD_ENTRY1s("databank.ptc", "48ec9806bda9d152acbea8ce31c93c49", 3435298), + Common::PL_POL, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NONE) + }, + 1 + }, + + + { AD_TABLE_END_MARKER, 0 } +}; + +} // End of namespace Prince + +using namespace Prince; + +// we match from data too, to stop detection from a non-top-level directory +const static char *directoryGlobs[] = { + "all", + 0 +}; + +class PrinceMetaEngine : public AdvancedMetaEngine { +public: + PrinceMetaEngine() : AdvancedMetaEngine(Prince::gameDescriptions, sizeof(Prince::PrinceGameDescription), princeGames) { + _singleid = "prince"; + _maxScanDepth = 2; + _directoryGlobs = directoryGlobs; + } + + virtual const char *getName() const { + return "Prince Engine"; + } + + virtual const char *getOriginalCopyright() const { + return "Copyright (C)"; + } + + virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; + virtual bool hasFeature(MetaEngineFeature f) const; +}; + +bool PrinceMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { + using namespace Prince; + const PrinceGameDescription *gd = (const PrinceGameDescription *)desc; + if (gd) { + *engine = new PrinceEngine(syst, gd); + } + return gd != 0; +} + +bool PrinceMetaEngine::hasFeature(MetaEngineFeature f) const { + return false; +} + +bool Prince::PrinceEngine::hasFeature(EngineFeature f) const { + return false;//(f == kSupportsRTL); +} + +#if PLUGIN_ENABLED_DYNAMIC(PRINCE) +REGISTER_PLUGIN_DYNAMIC(PRINCE, PLUGIN_TYPE_ENGINE, PrinceMetaEngine); +#else +REGISTER_PLUGIN_STATIC(PRINCE, PLUGIN_TYPE_ENGINE, PrinceMetaEngine); +#endif + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/flags.cpp b/engines/prince/flags.cpp index 5fb93ac4b1f9..d6d577a575d9 100644 --- a/engines/prince/flags.cpp +++ b/engines/prince/flags.cpp @@ -27,15 +27,15 @@ namespace Prince { const char * Flags::getFlagName(uint16 flagId) { switch (flagId) { - default: return "unknown_flag"; + default: return "unknown_flag"; case FLAGA1: return "FLAGA1"; case FLAGA2: return "FLAGA2"; case FLAGA3: return "FLAGA3"; - case DESTX: return "DESTX"; - case DESTY: return "DESTY"; - case DESTD: return "DESTD"; + case DESTX: return "DESTX"; + case DESTY: return "DESTY"; + case DESTD: return "DESTD"; case DwarfDone: return "DwarfDone"; - case GRABARZCOUNTER: return "GRABARZCOUNTER"; + case GRABARZCOUNTER: return "GRABARZCOUNTER"; case KIERUNEK: return "KIERUNEK"; case BACKFLAG1: return "BACKFLAG1"; case BACKFLAG2: return "BACKFLAG2"; @@ -154,159 +154,159 @@ const char * Flags::getFlagName(uint16 flagId) case LetterGiven: return "LetterGiven"; case LutniaTaken: return "LutniaTaken"; case BardHomeOpen: return "BardHomeOpen"; - case FjordNoMonsters: return "FjordNoMonsters"; - case ShandriaWallTalking: return "ShandriaWallTalking"; - case ShandriaWallCounter: return "ShandriaWallCounter"; - case ShandriaWallDone: return "ShandriaWallDone"; - case FutureDone: return "FutureDone"; + case FjordNoMonsters: return "FjordNoMonsters"; + case ShandriaWallTalking: return "ShandriaWallTalking"; + case ShandriaWallCounter: return "ShandriaWallCounter"; + case ShandriaWallDone: return "ShandriaWallDone"; + case FutureDone: return "FutureDone"; case TalkButch: return "TalkButch"; case GotSzalik: return "GotSzalik"; - case GotCzosnek: return "GotCzosnek"; + case GotCzosnek: return "GotCzosnek"; case BearDone: return "BearDone"; - case NekrVisited: return "NekrVisited"; + case NekrVisited: return "NekrVisited"; case SunRiddle: return "SunRiddle"; - case PtaszekAway: return "PtaszekAway"; - case KotGadanie: return "KotGadanie"; - case SzlafmycaTaken: return "SzlafmycaTaken"; + case PtaszekAway: return "PtaszekAway"; + case KotGadanie: return "KotGadanie"; + case SzlafmycaTaken: return "SzlafmycaTaken"; case BabkaTalk: return "BabkaTalk"; - case SellerTalk: return "SellerTalk"; - case CzosnekDone: return "CzosnekDone"; - case PriestCounter: return "PriestCounter"; - case PriestGest1: return "PriestGest1"; - case PriestGest2: return "PriestGest2"; - case PriestGest3: return "PriestGest3"; - case PriestGest4: return "PriestGest4"; - case PriestAnim: return "PriestAnim"; - case HolyWaterTaken: return "HolyWaterTaken"; + case SellerTalk: return "SellerTalk"; + case CzosnekDone: return "CzosnekDone"; + case PriestCounter: return "PriestCounter"; + case PriestGest1: return "PriestGest1"; + case PriestGest2: return "PriestGest2"; + case PriestGest3: return "PriestGest3"; + case PriestGest4: return "PriestGest4"; + case PriestAnim: return "PriestAnim"; + case HolyWaterTaken: return "HolyWaterTaken"; case AxeTaken: return "AxeTaken"; - case BadylTaken1: return "BadylTaken1"; - case BadylTaken2: return "BadylTaken2"; - case BadylSharpened: return "BadylSharpened"; - case PorwanieSmoka: return "PorwanieSmoka"; - case ShopReOpen: return "ShopReOpen"; - case LuskaShown: return "LuskaShown"; + case BadylTaken1: return "BadylTaken1"; + case BadylTaken2: return "BadylTaken2"; + case BadylSharpened: return "BadylSharpened"; + case PorwanieSmoka: return "PorwanieSmoka"; + case ShopReOpen: return "ShopReOpen"; + case LuskaShown: return "LuskaShown"; case CudKnow: return "CudKnow"; - case VampireDead: return "VampireDead"; - case MapaVisible1: return "MapaVisible1"; - case MapaVisible2: return "MapaVisible2"; - case MapaVisible3: return "MapaVisible3"; - case MapaVisible4: return "MapaVisible4"; - case MapaVisible5: return "MapaVisible5"; - case MapaVisible6: return "MapaVisible6"; - case MapaVisible7: return "MapaVisible7"; - case MapaVisible8: return "MapaVisible8"; - case MapaVisible9: return "MapaVisible9"; - case MapaX: return "MapaX"; - case MapaY: return "MapaY"; - case MapaD: return "MapaD"; + case VampireDead: return "VampireDead"; + case MapaVisible1: return "MapaVisible1"; + case MapaVisible2: return "MapaVisible2"; + case MapaVisible3: return "MapaVisible3"; + case MapaVisible4: return "MapaVisible4"; + case MapaVisible5: return "MapaVisible5"; + case MapaVisible6: return "MapaVisible6"; + case MapaVisible7: return "MapaVisible7"; + case MapaVisible8: return "MapaVisible8"; + case MapaVisible9: return "MapaVisible9"; + case MapaX: return "MapaX"; + case MapaY: return "MapaY"; + case MapaD: return "MapaD"; case OldMapaX: return "OldMapaX"; case OldMapaY: return "OldMapaY"; case OldMapaD: return "OldMapaD"; - case MovingBack: return "MovingBack"; + case MovingBack: return "MovingBack"; case MapaCount: return "MapaCount"; - case Pustelnia1st: return "Pustelnia1st"; - case CzarnePole1st: return "CzarnePole1st"; - case TalkArivNum: return "TalkArivNum"; - case Pfui: return "Pfui"; - case MapaSunlordEnabled: return "MapaSunlordEnabled"; + case Pustelnia1st: return "Pustelnia1st"; + case CzarnePole1st: return "CzarnePole1st"; + case TalkArivNum: return "TalkArivNum"; + case Pfui: return "Pfui"; + case MapaSunlordEnabled:return "MapaSunlordEnabled"; case WebDone: return "WebDone"; - case DragonDone: return "DragonDone"; + case DragonDone: return "DragonDone"; case KanPlay: return "KanPlay"; - case OldKanPlay: return "OldKanPlay"; + case OldKanPlay: return "OldKanPlay"; case LapkiWait: return "LapkiWait"; - case WebNoCheck: return "WebNoCheck"; - case Perfumeria: return "Perfumeria"; - case SmokNoCheck: return "SmokNoCheck"; - case IluzjaBroken: return "IluzjaBroken"; - case IluzjaWorking: return "IluzjaWorking"; - case IluzjaCounter: return "IluzjaCounter"; - case KurhanOpen1: return "KurhanOpen1"; - case KastetTaken: return "KastetTaken"; - case KastetDown: return "KastetDown"; - case KurhanDone: return "KurhanDone"; - case SkelCounter: return "SkelCounter"; + case WebNoCheck: return "WebNoCheck"; + case Perfumeria: return "Perfumeria"; + case SmokNoCheck: return "SmokNoCheck"; + case IluzjaBroken: return "IluzjaBroken"; + case IluzjaWorking: return "IluzjaWorking"; + case IluzjaCounter: return "IluzjaCounter"; + case KurhanOpen1: return "KurhanOpen1"; + case KastetTaken: return "KastetTaken"; + case KastetDown: return "KastetDown"; + case KurhanDone: return "KurhanDone"; + case SkelCounter: return "SkelCounter"; case SkelDial1: return "SkelDial1"; case SkelDial2: return "SkelDial2"; case SkelDial3: return "SkelDial3"; case SkelDial4: return "SkelDial4"; - case SameTalker: return "SameTalker"; - case RunMonstersText: return "RunMonstersText"; - case PiwnicaChecked: return "PiwnicaChecked"; - case DragonTalked: return "DragonTalked"; - case ToldAboutBook: return "ToldAboutBook"; - case SilmanionaDone: return "SilmanionaDone"; - case ToldBookCount: return "ToldBookCount"; - case SmrodNoCheck: return "SmrodNoCheck"; + case SameTalker: return "SameTalker"; + case RunMonstersText: return "RunMonstersText"; + case PiwnicaChecked: return "PiwnicaChecked"; + case DragonTalked: return "DragonTalked"; + case ToldAboutBook: return "ToldAboutBook"; + case SilmanionaDone: return "SilmanionaDone"; + case ToldBookCount: return "ToldBookCount"; + case SmrodNoCheck: return "SmrodNoCheck"; case RopeTaken: return "RopeTaken"; case RopeTime: return "RopeTime"; case LaskaFree: return "LaskaFree"; - case ShanSmokTalked: return "ShanSmokTalked"; - case SwordTaken: return "SwordTaken"; + case ShanSmokTalked: return "ShanSmokTalked"; + case SwordTaken: return "SwordTaken"; case Mill1st: return "Mill1st"; case SawRat: return "SawRat"; case KnowRat: return "KnowRat"; - case DziuraTimer: return "DziuraTimer"; - case LaskaInside: return "LaskaInside"; + case DziuraTimer: return "DziuraTimer"; + case LaskaInside: return "LaskaInside"; case HoleBig: return "HoleBig"; - case EnableWiedzmin: return "EnableWiedzmin"; - case EnableTrucizna: return "EnableTrucizna"; - case KnowPoison: return "KnowPoison"; - case KufelTaken: return "KufelTaken"; - case BojkaEnabled: return "BojkaEnabled"; - case BitwaNot1st: return "BitwaNot1st"; - case BojkaTimer: return "BojkaTimer"; + case EnableWiedzmin: return "EnableWiedzmin"; + case EnableTrucizna: return "EnableTrucizna"; + case KnowPoison: return "KnowPoison"; + case KufelTaken: return "KufelTaken"; + case BojkaEnabled: return "BojkaEnabled"; + case BitwaNot1st: return "BitwaNot1st"; + case BojkaTimer: return "BojkaTimer"; case BojkaGirl: return "BojkaGirl"; case Look1st: return "Look1st"; case RatTaken: return "RatTaken"; - case LaskaTalkedGr: return "LaskaTalkedGr"; - case RatusGivus: return "RatusGivus"; + case LaskaTalkedGr: return "LaskaTalkedGr"; + case RatusGivus: return "RatusGivus"; case MamObole: return "MamObole"; case Speed1st: return "Speed1st"; - case SpeedTimer: return "SpeedTimer"; + case SpeedTimer: return "SpeedTimer"; case ProveIt: return "ProveIt"; case Proven: return "Proven"; - case ShowWoalka: return "ShowWoalka"; - case PoisonTaken: return "PoisonTaken"; - case HellOpened: return "HellOpened"; - case HellNoCheck: return "HellNoCheck"; + case ShowWoalka: return "ShowWoalka"; + case PoisonTaken: return "PoisonTaken"; + case HellOpened: return "HellOpened"; + case HellNoCheck: return "HellNoCheck"; case TalAn1: return "TalAn1"; case TalAn2: return "TalAn2"; case TalAn3: return "TalAn3"; - case TalkDevilGuard: return "TalkDevilGuard"; + case TalkDevilGuard: return "TalkDevilGuard"; case Sword1st: return "Sword1st"; - case IluzjaNoCheck: return "IluzjaNoCheck"; - case RozdzielniaNumber: return "RozdzielniaNumber"; - case JailChecked: return "JailChecked"; - case JailTalked: return "JailTalked"; - case TrickFailed: return "TrickFailed"; - case WegielVisible: return "WegielVisible"; - case WegielTimer1: return "WegielTimer1"; - case RandomSample: return "RandomSample"; - case RandomSampleTimer: return "RandomSampleTimer"; - case SampleTimer: return "SampleTimer"; - case ZonaSample: return "ZonaSample"; - case HoleTryAgain: return "HoleTryAgain"; - case TeleportTimer: return "TeleportTimer"; + case IluzjaNoCheck: return "IluzjaNoCheck"; + case RozdzielniaNumber: return "RozdzielniaNumber"; + case JailChecked: return "JailChecked"; + case JailTalked: return "JailTalked"; + case TrickFailed: return "TrickFailed"; + case WegielVisible: return "WegielVisible"; + case WegielTimer1: return "WegielTimer1"; + case RandomSample: return "RandomSample"; + case RandomSampleTimer: return "RandomSampleTimer"; + case SampleTimer: return "SampleTimer"; + case ZonaSample: return "ZonaSample"; + case HoleTryAgain: return "HoleTryAgain"; + case TeleportTimer: return "TeleportTimer"; case RozLezy: return "RozLezy"; case UdkoTimer: return "UdkoTimer"; - case ZaworZatkany: return "ZaworZatkany"; - case ZaworOpened: return "ZaworOpened"; - case DoorExploded: return "DoorExploded"; - case SkoraTaken: return "SkoraTaken"; - case CiezkieByl: return "CiezkieByl"; + case ZaworZatkany: return "ZaworZatkany"; + case ZaworOpened: return "ZaworOpened"; + case DoorExploded: return "DoorExploded"; + case SkoraTaken: return "SkoraTaken"; + case CiezkieByl: return "CiezkieByl"; case MamWegiel: return "MamWegiel"; - case SwiecaAway: return "SwiecaAway"; + case SwiecaAway: return "SwiecaAway"; case ITSAVE: return "ITSAVE"; - case RozpadlSie: return "RozpadlSie"; - case WegielFullTimer: return "WegielFullTimer"; - case WegielDown: return "WegielDown"; - case WegielDownTimer: return "WegielDownTimer"; + case RozpadlSie: return "RozpadlSie"; + case WegielFullTimer: return "WegielFullTimer"; + case WegielDown: return "WegielDown"; + case WegielDownTimer: return "WegielDownTimer"; case PaliSie: return "PaliSie"; - case DiabGuardTalked: return "DiabGuardTalked"; - case GuardsNoCheck: return "GuardsNoCheck"; - case TalkedPowloka: return "TalkedPowloka"; + case DiabGuardTalked: return "DiabGuardTalked"; + case GuardsNoCheck: return "GuardsNoCheck"; + case TalkedPowloka: return "TalkedPowloka"; case JailOpen: return "JailOpen"; - case PrzytulTimer: return "PrzytulTimer"; + case PrzytulTimer: return "PrzytulTimer"; case JailDone: return "JailDone"; case MamMonety: return "MamMonety"; case LotTimer: return "LotTimer"; @@ -315,96 +315,92 @@ const char * Flags::getFlagName(uint16 flagId) case BookTimer: return "BookTimer"; case BookGiba: return "BookGiba"; case PtakLata: return "PtakLata"; - case Podej: return "Podej"; + case Podej: return "Podej"; case GotHint: return "GotHint"; case LawaLeci: return "LawaLeci"; case PowerKlik: return "PowerKlik"; case LucekBad: return "LucekBad"; - case LucekBad1st: return "LucekBad1st"; - case IntroDial1: return "IntroDial1"; - case IntroDial2: return "IntroDial2"; + case LucekBad1st: return "LucekBad1st"; + case IntroDial1: return "IntroDial1"; + case IntroDial2: return "IntroDial2"; case ItsOutro: return "ItsOutro"; - case KamienComment: return "KamienComment"; - case KamienSkip: return "KamienSkip"; - case TesterFlag: return "TesterFlag"; - case RememberLine: return "RememberLine"; + case KamienComment: return "KamienComment"; + case KamienSkip: return "KamienSkip"; + case TesterFlag: return "TesterFlag"; + case RememberLine: return "RememberLine"; case OpisLapek: return "OpisLapek"; - // case OpisKamienia: return "//OpisKamienia"; case TalWait: return "TalWait"; - case OpisKamienia: return "OpisKamienia"; + case OpisKamienia: return "OpisKamienia"; case JumpBox: return "JumpBox"; case JumpBox1: return "JumpBox1"; case JumpBox2: return "JumpBox2"; case JumpBox3: return "JumpBox3"; - case SpecPiesek: return "SpecPiesek"; - case SpecPiesekCount: return "SpecPiesekCount"; - case SpecPiesekGadanie: return "SpecPiesekGadanie"; + case SpecPiesek: return "SpecPiesek"; + case SpecPiesekCount: return "SpecPiesekCount"; + case SpecPiesekGadanie: return "SpecPiesekGadanie"; case ZnikaFlag: return "ZnikaFlag"; - case ZnikaTimer: return "ZnikaTimer"; + case ZnikaTimer: return "ZnikaTimer"; case SowaTimer: return "SowaTimer"; - case MamrotanieOff: return "MamrotanieOff"; + case MamrotanieOff: return "MamrotanieOff"; case CURRMOB: return "CURRMOB"; - case KOLOR: return "KOLOR"; + case KOLOR: return "KOLOR"; case MBFLAG: return "MBFLAG"; case MXFLAG: return "MXFLAG"; case MYFLAG: return "MYFLAG"; - case SCROLLTYPE: return "SCROLLTYPE"; - case SCROLLVALUE: return "SCROLLVALUE"; - case SCROLLVALUE2: return "SCROLLVALUE2"; - case TALKEXITCODE: return "TALKEXITCODE"; - case SPECROUTFLAG1: return "SPECROUTFLAG1"; - case SPECROUTFLAG2: return "SPECROUTFLAG2"; - case SPECROUTFLAG3: return "SPECROUTFLAG3"; - case TALKFLAGCODE: return "TALKFLAGCODE"; + case SCROLLTYPE: return "SCROLLTYPE"; + case SCROLLVALUE: return "SCROLLVALUE"; + case SCROLLVALUE2: return "SCROLLVALUE2"; + case TALKEXITCODE: return "TALKEXITCODE"; + case SPECROUTFLAG1: return "SPECROUTFLAG1"; + case SPECROUTFLAG2: return "SPECROUTFLAG2"; + case SPECROUTFLAG3: return "SPECROUTFLAG3"; + case TALKFLAGCODE: return "TALKFLAGCODE"; case CURRROOM: return "CURRROOM"; - case Talker1Init: return "Talker1Init"; - case Talker2Init: return "Talker2Init"; - case RESTOREROOM: return "RESTOREROOM"; - case INVALLOWED: return "INVALLOWED"; + case Talker1Init: return "Talker1Init"; + case Talker2Init: return "Talker2Init"; + case RESTOREROOM: return "RESTOREROOM"; + case INVALLOWED: return "INVALLOWED"; case BOXSEL: return "BOXSEL"; - case CURSEBLINK: return "CURSEBLINK"; + case CURSEBLINK: return "CURSEBLINK"; case EXACTMOVE: return "EXACTMOVE"; case MOVEDESTX: return "MOVEDESTX"; case MOVEDESTY: return "MOVEDESTY"; - case NOANTIALIAS: return "NOANTIALIAS"; + case NOANTIALIAS: return "NOANTIALIAS"; case ESCAPED: return "ESCAPED"; - case ALLOW1OPTION: return "ALLOW1OPTION"; - case VOICE_H_LINE: return "VOICE_H_LINE"; - case VOICE_A_LINE: return "VOICE_A_LINE"; - case VOICE_B_LINE: return "VOICE_B_LINE"; - case VOICE_C_LINE: return "VOICE_C_LINE"; - case NOHEROATALL: return "NOHEROATALL"; - case MOUSEENABLED: return "MOUSEENABLED"; + case ALLOW1OPTION: return "ALLOW1OPTION"; + case VOICE_H_LINE: return "VOICE_H_LINE"; + case VOICE_A_LINE: return "VOICE_A_LINE"; + case VOICE_B_LINE: return "VOICE_B_LINE"; + case VOICE_C_LINE: return "VOICE_C_LINE"; + case NOHEROATALL: return "NOHEROATALL"; + case MOUSEENABLED: return "MOUSEENABLED"; case DIALINES: return "DIALINES"; - //case SELITEM: return "SELITEM"; - case SHANWALK: return "SHANWALK"; case SHANDOG: return "SHANDOG"; - case GETACTIONBACK: return "GETACTIONBACK"; - case GETACTIONDATA: return "GETACTIONDATA"; + case GETACTIONBACK: return "GETACTIONBACK"; + case GETACTIONDATA: return "GETACTIONDATA"; case GETACTION: return "GETACTION"; case HEROFAST: return "HEROFAST"; case SELITEM: return "SELITEM"; case LMOUSE: return "LMOUSE"; - case MINMX: return "MINMX"; - case MAXMX: return "MAXMX"; - case MINMY: return "MINMY"; - case MAXMY: return "MAXMY"; - case TORX1: return "TORX1"; - case TORY1: return "TORY1"; - case TORX2: return "TORX2"; - case TORY2: return "TORY2"; - case POWER: return "POWER"; - case POWERENABLED: return "POWERENABLED"; - case FLCRESTORE: return "FLCRESTORE"; + case MINMX: return "MINMX"; + case MAXMX: return "MAXMX"; + case MINMY: return "MINMY"; + case MAXMY: return "MAXMY"; + case TORX1: return "TORX1"; + case TORY1: return "TORY1"; + case TORX2: return "TORX2"; + case TORY2: return "TORY2"; + case POWER: return "POWER"; + case POWERENABLED: return "POWERENABLED"; + case FLCRESTORE: return "FLCRESTORE"; case NOCLSTEXT: return "NOCLSTEXT"; case ESCAPED2: return "ESCAPED2"; } } - } /* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/flags.h b/engines/prince/flags.h index d36091252676..7eb8d7f1b7ea 100644 --- a/engines/prince/flags.h +++ b/engines/prince/flags.h @@ -20,6 +20,9 @@ * */ +#ifndef PRINCE_FLAGS_H +#define PRINCE_FLAGS_H + #include "common/scummsys.h" namespace Prince { @@ -406,4 +409,6 @@ struct Flags { }; } +#endif /* vim: set tabstop=4 noexpandtab: */ + diff --git a/engines/prince/font.cpp b/engines/prince/font.cpp index aac790dfe0d9..30e7b5aee2e9 100644 --- a/engines/prince/font.cpp +++ b/engines/prince/font.cpp @@ -35,55 +35,57 @@ Font::Font() { } Font::~Font() { - delete [] _fontData; + delete [] _fontData; } bool Font::load(Common::SeekableReadStream &stream) { - stream.seek(0); - _fontData = new byte[stream.size()]; - stream.read(_fontData, stream.size()); - return true; + stream.seek(0); + _fontData = new byte[stream.size()]; + stream.read(_fontData, stream.size()); + return true; } int Font::getFontHeight() const { - return _fontData[5]; + return _fontData[5]; } int Font::getMaxCharWidth() const { - return 0; + return 0; } Font::ChrData Font::getChrData(byte chr) const { - chr -= 32; - uint16 chrOffset = 4*chr+6; + chr -= 32; + uint16 chrOffset = 4*chr+6; - ChrData chrData; - chrData._width = _fontData[chrOffset+2]; - chrData._height = _fontData[chrOffset+3]; - chrData._pixels = _fontData + READ_LE_UINT16(_fontData + chrOffset); + ChrData chrData; + chrData._width = _fontData[chrOffset+2]; + chrData._height = _fontData[chrOffset+3]; + chrData._pixels = _fontData + READ_LE_UINT16(_fontData + chrOffset); - return chrData; + return chrData; } int Font::getCharWidth(byte chr) const { - return getChrData(chr)._width; + return getChrData(chr)._width; } void Font::drawChar(Graphics::Surface *dst, byte chr, int posX, int posY, uint32 color) const { - const ChrData chrData = getChrData(chr); - - for (int y = 0; y < chrData._height; ++y) { - for (int x = 0; x < chrData._width; ++x) { - byte d = chrData._pixels[x + (chrData._width * y)]; - if (d == 0) d = 255; - else if (d == 1) d = 0; - else if (d == 2) d = color; - else if (d == 3) d = 0; - if (d != 255) { - *(byte*)dst->getBasePtr(posX + x, posY + y) = d; - } - } - } + const ChrData chrData = getChrData(chr); + + for (int y = 0; y < chrData._height; ++y) { + for (int x = 0; x < chrData._width; ++x) { + byte d = chrData._pixels[x + (chrData._width * y)]; + if (d == 0) d = 255; + else if (d == 1) d = 0; + else if (d == 2) d = color; + else if (d == 3) d = 0; + if (d != 255) { + *(byte*)dst->getBasePtr(posX + x, posY + y) = d; + } + } + } } } + +/* vim: set tabstop=4 expandtab!: */ diff --git a/engines/prince/font.h b/engines/prince/font.h index 629b5d61ebfb..8b622ce08a60 100644 --- a/engines/prince/font.h +++ b/engines/prince/font.h @@ -25,44 +25,46 @@ #include "graphics/font.h" namespace Graphics { - struct Surface; + struct Surface; } namespace Common { - class String; + class String; } namespace Prince { class Font : public Graphics::Font { public: - Font(); - virtual ~Font(); + Font(); + virtual ~Font(); - bool load(Common::SeekableReadStream &stream); + bool load(Common::SeekableReadStream &stream); - virtual int getFontHeight() const override; + virtual int getFontHeight() const override; - virtual int getMaxCharWidth() const override; + virtual int getMaxCharWidth() const override; - virtual int getCharWidth(byte chr) const override; + virtual int getCharWidth(byte chr) const override; - virtual void drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const override; + virtual void drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const override; virtual int getKerningOffset(byte left, byte right) const { return -2; } private: - struct ChrData { - byte * _pixels; - byte _width; - byte _height; - }; + struct ChrData { + byte *_pixels; + byte _width; + byte _height; + }; - ChrData getChrData(byte chr) const; + ChrData getChrData(byte chr) const; - byte * _fontData; + byte *_fontData; }; } #endif + +/* vim: set tabstop=4 expandtab!: */ diff --git a/engines/prince/mhwanh.cpp b/engines/prince/mhwanh.cpp index 4240ed40974e..92a6a900f517 100644 --- a/engines/prince/mhwanh.cpp +++ b/engines/prince/mhwanh.cpp @@ -29,45 +29,45 @@ namespace Prince { MhwanhDecoder::MhwanhDecoder() - : _surface(NULL), _palette(0), _paletteColorCount(0) { + : _surface(NULL), _palette(0), _paletteColorCount(0) { } MhwanhDecoder::~MhwanhDecoder() { - destroy(); + destroy(); } void MhwanhDecoder::destroy() { - if (_surface) { - _surface->free(); - delete _surface; _surface = 0; - } + if (_surface) { + _surface->free(); + delete _surface; _surface = 0; + } - delete [] _palette; _palette = 0; - _paletteColorCount = 0; + delete [] _palette; _palette = 0; + _paletteColorCount = 0; } bool MhwanhDecoder::loadStream(Common::SeekableReadStream &stream) { - destroy(); - _paletteColorCount = 256; - stream.seek(0); - stream.skip(0x20); - // Read the palette - _palette = new byte[_paletteColorCount * 3]; - for (uint16 i = 0; i < _paletteColorCount; i++) { - _palette[i * 3 + 0] = stream.readByte(); - _palette[i * 3 + 1] = stream.readByte(); - _palette[i * 3 + 2] = stream.readByte(); - } - - _surface = new Graphics::Surface(); - _surface->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); - for (int h = 0; h < 480; ++h) { - stream.read(_surface->getBasePtr(0, h), 640); - } - - return true; + destroy(); + _paletteColorCount = 256; + stream.seek(0); + stream.skip(0x20); + // Read the palette + _palette = new byte[_paletteColorCount * 3]; + for (uint16 i = 0; i < _paletteColorCount; i++) { + _palette[i * 3 + 0] = stream.readByte(); + _palette[i * 3 + 1] = stream.readByte(); + _palette[i * 3 + 2] = stream.readByte(); + } + + _surface = new Graphics::Surface(); + _surface->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); + for (int h = 0; h < 480; ++h) { + stream.read(_surface->getBasePtr(0, h), 640); + } + + return true; } } - +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/mhwanh.h b/engines/prince/mhwanh.h index 24472da7a523..2b70ae525b13 100644 --- a/engines/prince/mhwanh.h +++ b/engines/prince/mhwanh.h @@ -30,23 +30,24 @@ namespace Prince { class MhwanhDecoder : public Graphics::ImageDecoder { public: - MhwanhDecoder(); - virtual ~MhwanhDecoder(); + MhwanhDecoder(); + virtual ~MhwanhDecoder(); - // ImageDecoder API - void destroy(); - virtual bool loadStream(Common::SeekableReadStream &stream); - virtual Graphics::Surface *getSurface() const { return _surface; } - const byte *getPalette() const { return _palette; } - uint16 getPaletteCount() const { return _paletteColorCount; } + // ImageDecoder API + void destroy(); + virtual bool loadStream(Common::SeekableReadStream &stream); + virtual Graphics::Surface *getSurface() const { return _surface; } + const byte *getPalette() const { return _palette; } + uint16 getPaletteCount() const { return _paletteColorCount; } private: - Graphics::Surface *_surface; - byte *_palette; - uint16 _paletteColorCount; + Graphics::Surface *_surface; + byte *_palette; + uint16 _paletteColorCount; }; } - #endif + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/mob.cpp b/engines/prince/mob.cpp index caf44fef12f2..3df7235d2d84 100644 --- a/engines/prince/mob.cpp +++ b/engines/prince/mob.cpp @@ -27,37 +27,39 @@ namespace Prince { bool Mob::loadFromStream(Common::SeekableReadStream &stream) { - int32 pos = stream.pos(); + int32 pos = stream.pos(); - uint16 visible = stream.readUint16LE(); + uint16 visible = stream.readUint16LE(); - if (visible == 0xFFFF) - return false; + if (visible == 0xFFFF) + return false; - _visible = visible; - _type = stream.readUint16LE(); - _rect.left = stream.readUint16LE(); - _rect.top = stream.readUint16LE(); - _rect.right = stream.readUint16LE(); - _rect.bottom = stream.readUint16LE(); + _visible = visible; + _type = stream.readUint16LE(); + _rect.left = stream.readUint16LE(); + _rect.top = stream.readUint16LE(); + _rect.right = stream.readUint16LE(); + _rect.bottom = stream.readUint16LE(); - stream.skip(6 * sizeof(uint16)); - uint32 nameOffset = stream.readUint32LE(); - uint32 examTextOffset = stream.readUint32LE(); + stream.skip(6 * sizeof(uint16)); + uint32 nameOffset = stream.readUint32LE(); + uint32 examTextOffset = stream.readUint32LE(); - byte c; - stream.seek(nameOffset); - _name.clear(); - while ((c = stream.readByte())) - _name += c; + byte c; + stream.seek(nameOffset); + _name.clear(); + while ((c = stream.readByte())) + _name += c; - stream.seek(examTextOffset); - _examText.clear(); - while ((c = stream.readByte())) - _examText += c; - stream.seek(pos + 32); + stream.seek(examTextOffset); + _examText.clear(); + while ((c = stream.readByte())) + _examText += c; + stream.seek(pos + 32); - return true; + return true; } } + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/mob.h b/engines/prince/mob.h index 5b2a6f9d6ef5..b8208246a19e 100644 --- a/engines/prince/mob.h +++ b/engines/prince/mob.h @@ -20,29 +20,34 @@ * */ +#ifndef PRINCE_MOB_H +#define PRINCE_MOB_H + #include "common/scummsys.h" #include "common/rect.h" #include "common/str.h" namespace Common { - class SeekableReadStream; + class SeekableReadStream; } namespace Prince { class Mob { public: - Mob() {} + Mob() {} - bool loadFromStream(Common::SeekableReadStream &stream); - + bool loadFromStream(Common::SeekableReadStream &stream); - bool _visible; - uint16 _type; - Common::Rect _rect; - Common::String _name; - Common::String _examText; + bool _visible; + uint16 _type; + Common::Rect _rect; + Common::String _name; + Common::String _examText; }; } +#endif + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/module.mk b/engines/prince/module.mk index 8bdccdf74de4..f8003f834acb 100644 --- a/engines/prince/module.mk +++ b/engines/prince/module.mk @@ -1,23 +1,23 @@ -MODULE := engines/prince - -MODULE_OBJS = \ - debugger.o \ - script.o \ - graphics.o \ - mhwanh.o \ - detection.o \ - font.o \ - mob.o \ - object.o \ - sound.o \ - flags.o \ - variatxt.o \ - prince.o - -# This module can be built as a plugin -ifeq ($(ENABLE_PRINCE), DYNAMIC_PLUGIN) -PLUGIN := 1 -endif - -# Include common rules -include $(srcdir)/rules.mk +MODULE := engines/prince + +MODULE_OBJS = \ + debugger.o \ + script.o \ + graphics.o \ + mhwanh.o \ + detection.o \ + font.o \ + mob.o \ + object.o \ + sound.o \ + flags.o \ + variatxt.o \ + prince.o + +# This module can be built as a plugin +ifeq ($(ENABLE_PRINCE), DYNAMIC_PLUGIN) +PLUGIN := 1 +endif + +# Include common rules +include $(srcdir)/rules.mk diff --git a/engines/prince/musNum.h b/engines/prince/musNum.h index cb8133260425..65b31f817509 100644 --- a/engines/prince/musNum.h +++ b/engines/prince/musNum.h @@ -20,73 +20,68 @@ * */ -/* - * This code is based on original Soltys source code - * Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon - */ - namespace Prince { enum RoomMus { -ROOM01MUS =3, -ROOM02MUS =9, -ROOM03MUS =9, -ROOM04MUS =9, -ROOM05MUS =13, -ROOM06MUS =9, -ROOM07MUS =9, -ROOM08MUS =9, -ROOM09MUS =14, -ROOM10MUS =9, -ROOM11MUS =9, -ROOM12MUS =9, -ROOM13MUS =9, -ROOM14MUS =9, -ROOM15MUS =5, -ROOM16MUS =5, -ROOM17MUS =5, -ROOM18MUS =5, -ROOM19MUS =5, -ROOM20MUS =12, -ROOM21MUS =9, -ROOM22MUS =9, -ROOM23MUS =1, -ROOM24MUS =1, -ROOM25MUS =2, -ROOM26MUS =10, -ROOM27MUS =7, -ROOM28MUS =10, -ROOM29MUS =10, -ROOM30MUS =11, -ROOM31MUS =14, -ROOM32MUS =11, -ROOM33MUS =7, -ROOM34MUS =7, -ROOM35MUS =7, -ROOM36MUS =7, -ROOM37MUS =7, -ROOM38MUS =7, -ROOM39MUS =7, -ROOM40MUS =7, -ROOM41MUS =7, -ROOM42MUS =7, -ROOM43MUS =15, -ROOM46MUS =100, -ROOM47MUS =100, -ROOM48MUS =100, -ROOM49MUS =100, -ROOM50MUS =100, -ROOM51MUS =12, -ROOM52MUS =9, -ROOM53MUS =5, -ROOM54MUS =11, -ROOM55MUS =11, -ROOM56MUS =11, -ROOM57MUS =7, -ROOM58MUS =13, -ROOM59MUS =16, -ROOM60MUS =4, -ROOM61MUS =0 + ROOM01MUS = 3, + ROOM02MUS = 9, + ROOM03MUS = 9, + ROOM04MUS = 9, + ROOM05MUS = 13, + ROOM06MUS = 9, + ROOM07MUS = 9, + ROOM08MUS = 9, + ROOM09MUS = 14, + ROOM10MUS = 9, + ROOM11MUS = 9, + ROOM12MUS = 9, + ROOM13MUS = 9, + ROOM14MUS = 9, + ROOM15MUS = 5, + ROOM16MUS = 5, + ROOM17MUS = 5, + ROOM18MUS = 5, + ROOM19MUS = 5, + ROOM20MUS = 12, + ROOM21MUS = 9, + ROOM22MUS = 9, + ROOM23MUS = 1, + ROOM24MUS = 1, + ROOM25MUS = 2, + ROOM26MUS = 10, + ROOM27MUS = 7, + ROOM28MUS = 10, + ROOM29MUS = 10, + ROOM30MUS = 11, + ROOM31MUS = 14, + ROOM32MUS = 11, + ROOM33MUS = 7, + ROOM34MUS = 7, + ROOM35MUS = 7, + ROOM36MUS = 7, + ROOM37MUS = 7, + ROOM38MUS = 7, + ROOM39MUS = 7, + ROOM40MUS = 7, + ROOM41MUS = 7, + ROOM42MUS = 7, + ROOM43MUS = 15, + ROOM46MUS = 100, + ROOM47MUS = 100, + ROOM48MUS = 100, + ROOM49MUS = 100, + ROOM50MUS = 100, + ROOM51MUS = 12, + ROOM52MUS = 9, + ROOM53MUS = 5, + ROOM54MUS = 11, + ROOM55MUS = 11, + ROOM56MUS = 11, + ROOM57MUS = 7, + ROOM58MUS = 13, + ROOM59MUS = 16, + ROOM60MUS = 4, + ROOM61MUS = 0 }; } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 1d8f71ddcbcd..2fc4407f6e07 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -21,7 +21,7 @@ */ #include "common/scummsys.h" - + #include "common/config-manager.h" #include "common/debug-channels.h" #include "common/debug.h" @@ -51,6 +51,7 @@ #include "prince/mob.h" #include "prince/sound.h" #include "prince/variatxt.h" +#include "prince/flags.h" #include "video/flic_decoder.h" @@ -93,6 +94,9 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) DebugMan.enableDebugChannel("script"); + gDebugLevel = 10; + + _rnd = new Common::RandomSource("prince"); _debugger = new Debugger(this); _midiPlayer = new MusicPlayer(this); @@ -373,18 +377,21 @@ void PrinceEngine::scrollCameraRight(int16 delta) { void PrinceEngine::keyHandler(Common::Event event) { uint16 nChar = event.kbd.keycode; - if (event.kbd.hasFlags(Common::KBD_CTRL)) { - switch (nChar) { - case Common::KEYCODE_d: + switch (nChar) { + case Common::KEYCODE_d: + if (event.kbd.hasFlags(Common::KBD_CTRL)) { getDebugger()->attach(); - break; - case Common::KEYCODE_LEFT: - scrollCameraLeft(32); - break; - case Common::KEYCODE_RIGHT: - scrollCameraRight(32); - break; } + break; + case Common::KEYCODE_LEFT: + scrollCameraLeft(32); + break; + case Common::KEYCODE_RIGHT: + scrollCameraRight(32); + break; + case Common::KEYCODE_ESCAPE: + _script->setFlag(Flags::ESCAPED2, 1); + break; } } @@ -464,6 +471,9 @@ void PrinceEngine::showTexts() { } --text._time; + if (text._time == 0) { + text._str = NULL; + } } } @@ -521,8 +531,8 @@ void PrinceEngine::mainLoop() { if (shouldQuit()) return; - drawScreen(); _script->step(); + drawScreen(); // Calculate the frame delay based off a desired frame time int delay = 1000/15 - int32(_system->getMillis() - currentTime); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 49a0a9751ce1..55264a35a667 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -47,6 +47,10 @@ Script::~Script() { delete[] _code; } +void Script::setFlag(Flags::Id flagId, uint16 value) { + _flags[flagId - 0x8000] = value; +} + bool Script::loadFromStream(Common::SeekableReadStream &stream) { _codeSize = stream.size(); _code = new byte[_codeSize]; @@ -56,7 +60,8 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) { stream.read(_code, _codeSize); // Initialize the script - _currentInstruction = READ_LE_UINT32(_code + 4); + _fgOpcodePC = READ_LE_UINT32(_code + 4); + _bgOpcodePC = 0; return true; } @@ -73,10 +78,21 @@ void Script::debugScript(const char *s, ...) { str += Common::String::format("op %04d: ", _lastOpcode); //debugC(10, DebugChannel::kScript, "PrinceEngine::Script %s %s", str.c_str(), buf); - debug("PrinceEngine::Script frame %ld %s %s", _vm->_frameNr, str.c_str(), buf); + debug("Prince::Script frame %ld %s %s", _vm->_frameNr, str.c_str(), buf); } void Script::step() { + if (_bgOpcodePC) { + _bgOpcodePC = step(_bgOpcodePC); + } + if (_fgOpcodePC) { + _fgOpcodePC = step(_fgOpcodePC); + } +} + +uint32 Script::step(uint32 opcodePC) { + + _currentInstruction = opcodePC; while (!_opcodeNF) { _lastInstruction = _currentInstruction; @@ -103,6 +119,8 @@ void Script::step() { break; } } + + return _currentInstruction; } uint8 Script::getCodeByte(uint32 address) { @@ -593,6 +611,7 @@ void Script::O_GETANIMDATA() {} void Script::O_SETBGCODE() { int32 bgcode = readScript32bits(); debugScript("O_SETBGCODE %d", bgcode); + _bgOpcodePC = _currentInstruction + bgcode; } void Script::O_SETBACKFRAME() {} void Script::O_GETRND() {} @@ -633,7 +652,8 @@ void Script::O_ZOOMIN() {} void Script::O_ZOOMOUT() {} -void Script::O_SETSTRINGOFFSET() {} +void Script::O_SETSTRINGOFFSET() { +} void Script::O_GETOBJDATA() {} @@ -641,7 +661,12 @@ void Script::O_SETOBJDATA() {} void Script::O_SWAPOBJECTS() {} -void Script::O_CHANGEHEROSET() {} +void Script::O_CHANGEHEROSET() { + uint16 hero = readScript16bits(); + uint16 heroSet = readScript16bits(); + + debugScript("O_CHANGEHEROSET hero %d, heroSet %d", hero, heroSet); +} void Script::O_ADDSTRING() {} @@ -660,6 +685,7 @@ void Script::O_STOPSAMPLE() { debugScript("O_STOPSAMPLE slot %d", slot); _vm->_mixer->stopID(slot); + _voiceStream = NULL; } void Script::O_BACKANIMRANGE() { @@ -712,6 +738,8 @@ void Script::O_SETFGCODE() { int32 offset = readScript32bits(); debugScript("O_SETFGCODE offset %04X", offset); + + _fgOpcodePC = _currentInstruction + offset; } void Script::O_STOPHERO() { @@ -846,7 +874,10 @@ void Script::O_SKIPTEXT() { } void Script::SetVoice(uint32 slot) { - const Common::String streamName = Common::String::format("%03d-01.WAV", _currentString); + + const uint16 VOICE_H_LINE = _flags[Flags::VOICE_H_LINE - 0x8000]; + + const Common::String streamName = Common::String::format("%03d-%02d.WAV", _currentString, VOICE_H_LINE); debugScript("Loading wav %s slot %d", streamName.c_str(), slot); _voiceStream = SearchMan.createReadStreamForMember(streamName); diff --git a/engines/prince/script.h b/engines/prince/script.h index 1343051fc9b7..984b2d93e970 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -27,6 +27,8 @@ #include "audio/mixer.h" +#include "prince/flags.h" + namespace Common { class SeekableReadStream; } @@ -43,6 +45,7 @@ class Script { bool loadFromStream(Common::SeekableReadStream &stream); void step(); + void setFlag(Flags::Id flag, uint16 value); private: PrinceEngine *_vm; @@ -50,12 +53,17 @@ class Script { byte *_code; uint32 _codeSize; uint32 _currentInstruction; + + uint32 _bgOpcodePC; + uint32 _fgOpcodePC; + uint16 _lastOpcode; uint32 _lastInstruction; byte _result; int16 _flags[2000]; bool _opcodeNF; + // Stack static const uint32 _STACK_SIZE = 500; uint32 _stack[_STACK_SIZE]; @@ -69,6 +77,7 @@ class Script { Common::SeekableReadStream *_voiceStream; // Helper functions + uint32 step(uint32 opcodePC); void checkPC(uint32 address); uint8 getCodeByte(uint32 address); uint8 readScript8bits(); @@ -81,6 +90,8 @@ class Script { typedef void (Script::*OpcodeFunc)(); static OpcodeFunc _opcodes[]; + // Keep opcode handlers names as they are in original code + // it easier to switch back and forth void O_WAITFOREVER(); void O_BLACKPALETTE(); void O_SETUPPALETTE(); From c56c85265f0ae4df7cf11dd3e2170f5c6c6f6edb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Mon, 4 Nov 2013 11:30:46 +0000 Subject: [PATCH 045/374] PRINCE: small comments here and there --- engines/prince/flags.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/engines/prince/flags.h b/engines/prince/flags.h index 7eb8d7f1b7ea..aa607a01fe5e 100644 --- a/engines/prince/flags.h +++ b/engines/prince/flags.h @@ -29,6 +29,8 @@ namespace Prince { struct Flags { + // TODO: Remove from release build + // useful just for debugging static const char * getFlagName(uint16 flagId); enum Id { @@ -39,7 +41,7 @@ struct Flags { DESTY = 0x8008, DESTD = 0x800A, DwarfDone = 0x800C, - GRABARZCOUNTER = 0x800E, + GRABARZCOUNTER = 0x800E, KIERUNEK = 0x8010, BACKFLAG1 = 0x8012, BACKFLAG2 = 0x8014, @@ -59,8 +61,8 @@ struct Flags { U_BT_7 = 0x8030, U_BT_8 = 0x8032, U_BT_9 = 0x8034, - U_BT_COUNTER = 0x8036, - ARIVALDALIVE = 0x8038, + U_BT_COUNTER = 0x8036, + ARIVALDALIVE = 0x8038, TALKCHAR1 = 0x803A, TalkType1 = 0x803C, TALKROUT1 = 0x803E, @@ -71,15 +73,15 @@ struct Flags { TALKANIM2 = 0x8050, TALKCOLOR1 = 0x8052, TALKCOLOR2 = 0x8054, - KapciuchTaken = 0x8056, - CurrentBeggarA = 0x8058, + KapciuchTaken = 0x8056, + CurrentBeggarA = 0x8058, TempKapc = 0x805A, HomTaken = 0x805C, WizardTalk = 0x805E, SunlordTalk = 0x8060, HermitTalk = 0x8062, RunyMode = 0x8064, - FatMerchantTalk = 0x8066, + FatMerchantTalk = 0x8066, HotDogTalk = 0x8068, ThiefTalk = 0x806A, BeggarTalk = 0x806C, From 4b2a7606299acd1e16eff45a9deea2c14b04cafd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Mon, 4 Nov 2013 16:07:19 +0000 Subject: [PATCH 046/374] PRICE: compilation warnings fixed --- engines/prince/prince.cpp | 4 +- engines/prince/script.cpp | 314 ++++++++++++++++++++++++++++++------ engines/prince/script.h | 3 +- engines/prince/variatxt.cpp | 2 +- 4 files changed, 269 insertions(+), 54 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 2fc4407f6e07..aaad8e96ede5 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -407,7 +407,7 @@ void PrinceEngine::hotspot() { continue; if (it->_rect.contains(mousePosCamera)) { uint16 textW = 0; - for (int i = 0; i < it->_name.size(); ++i) + for (uint16 i = 0; i < it->_name.size(); ++i) textW += _font.getCharWidth(it->_name[i]); uint16 x = mousepos.x - textW/2; @@ -459,7 +459,7 @@ void PrinceEngine::showTexts() { Common::Array lines; _font.wordWrapText(text._str, _graph->_frontScreen->w, lines); - for (int i = 0; i < lines.size(); ++i) { + for (uint8 i = 0; i < lines.size(); ++i) { _font.drawString( _graph->_frontScreen, lines[i], diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 55264a35a667..7e368eea5285 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -40,7 +40,7 @@ static const uint16 NUM_OPCODES = 144; Script::Script(PrinceEngine *vm) : _code(NULL), _stacktop(0), _vm(vm), _opcodeNF(false), - _waitFlag(0), _voiceStream(NULL) { + _waitFlag(0), _voiceStream(NULL), _result(true) { } Script::~Script() { @@ -60,6 +60,7 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) { stream.read(_code, _codeSize); // Initialize the script + _mode = "fg"; _fgOpcodePC = READ_LE_UINT32(_code + 4); _bgOpcodePC = 0; @@ -74,18 +75,22 @@ void Script::debugScript(const char *s, ...) { vsnprintf(buf, STRINGBUFLEN, s, va); va_end(va); - Common::String str = Common::String::format("@0x%04X: ", _lastInstruction); + Common::String str = Common::String::format("@0x%08X: ", _lastInstruction); str += Common::String::format("op %04d: ", _lastOpcode); //debugC(10, DebugChannel::kScript, "PrinceEngine::Script %s %s", str.c_str(), buf); - debug("Prince::Script frame %ld %s %s", _vm->_frameNr, str.c_str(), buf); + debug("Prince::Script mode %s frame %ld %s %s", _mode, _vm->_frameNr, str.c_str(), buf); } void Script::step() { +#if 1 if (_bgOpcodePC) { + _mode = "bg"; _bgOpcodePC = step(_bgOpcodePC); } +#endif if (_fgOpcodePC) { + _mode = "fg"; _fgOpcodePC = step(_fgOpcodePC); } } @@ -108,7 +113,7 @@ uint32 Script::step(uint32 opcodePC) { error("Trying to execute unknown opcode %s", dstr.c_str()); - debugScript(""); + //debugScript(""); // Execute the current opcode OpcodeFunc op = _opcodes[_lastOpcode]; @@ -388,9 +393,10 @@ void Script::O_JUMPZ() { void Script::O_JUMPNZ() { int32 offset = readScript32bits(); - debugScript("O_JUMPNZ offset 0x%04X", offset); + debugScript("O_JUMPNZ offset 0x%08X", offset); if (_result) { _currentInstruction += offset - 4; + debugScript("O_JUMPNZ next 0x%08X", _currentInstruction); } } @@ -552,7 +558,14 @@ void Script::O_WALKHERO() { _opcodeNF = 1; } -void Script::O_SETHERO() {} +void Script::O_SETHERO() { + uint16 hero = readScript16bits(); + uint16 x = readScript16bits(); + uint16 y = readScript16bits(); + uint16 dir = readScript16bits(); + debugScript("O_SETHERO hero %d, x %d, y %d, dir %d", hero, x, y, dir); +} + void Script::O_HEROOFF() { uint16 heroId = readScript16bits(); debugScript("O_HEROOFF %d", heroId); @@ -563,30 +576,115 @@ void Script::O_HEROON() { debugScript("O_HEROON %d", heroId); } -void Script::O_CLSTEXT() {} -void Script::O_CALLTABLE() {} -void Script::O_CHANGEMOB() {} -void Script::O_ADDINV() {} -void Script::O_REMINV() {} -void Script::O_REPINV() {} -void Script::O_OBSOLETE_GETACTION() {} -void Script::O_ADDWALKAREA() {} -void Script::O_REMWALKAREA() {} -void Script::O_RESTOREWALKAREA() {} +void Script::O_CLSTEXT() { + uint16 slot = readScript16bits(); + debugScript("O_CLSTEXT slot %d", slot); +} + +void Script::O_CALLTABLE() { + uint16 flag = readScript16bits(); + int32 table = readScript32bits(); + + debugScript("O_CALLTABLE flag %d, table %d", flag, table); +} + +void Script::O_CHANGEMOB() { + uint16 mob = readScript16bits(); + uint16 value = readScript16bits(); + debugScript("O_CHANGEMOB mob %d, value %d", mob, value); +} + +void Script::O_ADDINV() { + uint16 hero = readScript16bits(); + uint16 item = readScript16bits(); + debugScript("O_ADDINV hero %d, item %d", hero, item); +} + +void Script::O_REMINV() { + uint16 hero = readScript16bits(); + uint16 item = readScript16bits(); + debugScript("O_REMINV hero %d, item %d", hero, item); +} + +void Script::O_REPINV() { + uint16 hero = readScript16bits(); + uint16 item1 = readScript16bits(); + uint16 item2 = readScript16bits(); + debugScript("O_REPINV hero %d, item1 %d, item2 %d", hero, item1, item2); +} + +void Script::O_OBSOLETE_GETACTION() { + debugScript("O_OBSOLETE_GETACTION"); +} + +void Script::O_ADDWALKAREA() { + uint16 x1 = readScript16bits(); + uint16 y1 = readScript16bits(); + uint16 x2 = readScript16bits(); + uint16 y2 = readScript16bits(); + debugScript("O_ADDWALKAREA x1 %d, y1 %d, x2 %d, y2 %d", x1, y1, x2, y2); +} + +void Script::O_REMWALKAREA() { + uint16 x1 = readScript16bits(); + uint16 y1 = readScript16bits(); + uint16 x2 = readScript16bits(); + uint16 y2 = readScript16bits(); + debugScript("O_REMWALKAREA x1 %d, y1 %d, x2 %d, y2 %d", x1, y1, x2, y2); +} + +void Script::O_RESTOREWALKAREA() { + debugScript("O_RESTOREWALKAREA"); +} void Script::O_WAITFRAME() { debugScript("O_WAITFRAME"); _opcodeNF = true; } -void Script::O_SETFRAME() {} -void Script::O_RUNACTION() {} -void Script::O_COMPAREHI() {} -void Script::O_COMPARELO() {} -void Script::O_PRELOADSET() {} -void Script::O_FREEPRELOAD() {} -void Script::O_CHECKINV() {} -void Script::O_TALKHERO() {} +void Script::O_SETFRAME() { + uint16 anim = readScript16bits(); + uint16 frame = readScript16bits(); + debugScript("O_SETFRAME anim %d, frame %d", anim, frame); +} + +void Script::O_RUNACTION() { + debugScript("O_RUNACTION"); +} + +void Script::O_COMPAREHI() { + uint16 flag = readScript16bits(); + uint16 value = readScript16bits(); + + debugScript("O_COMPAREHI flag %d, value %d", flag, value); +} + +void Script::O_COMPARELO() { + uint16 flag = readScript16bits(); + uint16 value = readScript16bits(); + + debugScript("O_COMPARELO flag %d, value %d", flag, value); +} + +void Script::O_PRELOADSET() { + int32 offset = readScript32bits(); + debugScript("O_PRELOADSET offset %04x", offset); +} + +void Script::O_FREEPRELOAD() { + debugScript("O_FREEPRELOAD"); +} + +void Script::O_CHECKINV() { + uint16 hero = readScript16bits(); + uint16 item = readScript16bits(); + debugScript("O_CHECKINV hero %d, item %d", hero, item); +} + +void Script::O_TALKHERO() { + uint16 hero = readScript16bits(); + debugScript("O_TALKHERO hero %d", hero); +} void Script::O_WAITTEXT() { uint16 slot = readScript16bits(); @@ -600,23 +698,92 @@ void Script::O_WAITTEXT() { } } -void Script::O_SETHEROANIM() {} -void Script::O_WAITHEROANIM() {} -void Script::O_GETHERODATA() {} -void Script::O_GETMOUSEBUTTON() {} -void Script::O_CHANGEFRAMES() {} -void Script::O_CHANGEBACKFRAMES() {} -void Script::O_GETBACKANIMDATA() {} -void Script::O_GETANIMDATA() {} +void Script::O_SETHEROANIM() { + uint16 hero = readScript16bits(); + int32 offset = readScript32bits(); + debugScript("O_SETHEROANIM hero %d, offset %d", hero, offset); +} + +void Script::O_WAITHEROANIM() { + uint16 hero = readScript16bits(); + + debugScript("O_WAITHEROANIM hero %d", hero); +} + +void Script::O_GETHERODATA() { + uint16 flag = readScript16bits(); + uint16 hero = readScript16bits(); + uint16 heroOffset =readScript16bits(); + debugScript("O_GETHERODATA flag %d, hero %d, heroOffset %d", flag, hero, heroOffset); +} + +void Script::O_GETMOUSEBUTTON() { + debugScript("O_GETMOUSEBUTTON"); +} + +void Script::O_CHANGEFRAMES() { + uint16 anim = readScript16bits(); + uint16 fr1 = readScript16bits(); + uint16 fr2 = readScript16bits(); + uint16 fr3 = readScript16bits(); + + debugScript("O_CHANGFRAMES anim %d, fr1 %d, fr2 %d, fr3 %d", anim, fr1, fr2, fr3); + +} + +void Script::O_CHANGEBACKFRAMES() { + uint16 anim = readScript16bits(); + uint16 fr1 = readScript16bits(); + uint16 fr2 = readScript16bits(); + uint16 fr3 = readScript16bits(); + + debugScript("O_CHANGEBACKFRAMES anim %d, fr1 %d, fr2 %d, fr3 %d", anim, fr1, fr2, fr3); +} + +void Script::O_GETBACKANIMDATA() { + uint16 flag = readScript16bits(); + uint16 anim = readScript16bits(); + uint16 animOffset = readScript16bits(); + debugScript("O_GETBACKANIMDATA flag %d, anim %d, animOffset %d", flag, anim, animOffset); +} + +void Script::O_GETANIMDATA() { + uint16 flag = readScript16bits(); + uint16 anim = readScript16bits(); + uint16 animOffset = readScript16bits(); + debugScript("O_GETANIMDATA flag %d, anim %d, animOffset %d", flag, anim, animOffset); +} + void Script::O_SETBGCODE() { int32 bgcode = readScript32bits(); debugScript("O_SETBGCODE %d", bgcode); _bgOpcodePC = _currentInstruction + bgcode; + debugScript("O_SETBGCODE next %08X", _bgOpcodePC); +} + +void Script::O_SETBACKFRAME() { + uint16 anim = readScript16bits(); + uint16 frame = readScript16bits(); + + debugScript("O_SETBACKFRAME anim %d, frame %d", anim, frame); +} + +void Script::O_GETRND() { + uint16 flag = readScript16bits(); + uint16 rndSeed = readScript16bits(); + debugScript("O_GETRND flag %d, rndSeed %d", flag, rndSeed); +} + +void Script::O_TALKBACKANIM() { + uint16 animSlot = readScript16bits(); + uint16 slot = readScript16bits(); + debugScript("O_TALKBACKANIM animSlot %d, slot %d", animSlot, slot); +} + +void Script::O_LOADPATH() { + int32 offset = readScript32bits(); + debugScript("O_LOADPATH offset %d", offset); } -void Script::O_SETBACKFRAME() {} -void Script::O_GETRND() {} -void Script::O_TALKBACKANIM() {} -void Script::O_LOADPATH() {} void Script::O_GETCHAR() { uint16 flagId = readScript16bits(); @@ -628,8 +795,16 @@ void Script::O_GETCHAR() { ++_string; } -void Script::O_SETDFLAG() {} -void Script::O_CALLDFLAG() {} +void Script::O_SETDFLAG() { + uint16 flag = readScript16bits(); + int32 offset = readScript32bits(); + debugScript("O_SETDFLAG flag %d, offset %04x", flag, offset); +} + +void Script::O_CALLDFLAG() { + uint16 flag = readScript16bits(); + debugScript("O_CALLDFLAG flag %d", flag); +} void Script::O_PRINTAT() { uint16 slot = readScript16bits(); @@ -648,37 +823,75 @@ void Script::O_PRINTAT() { ++_string; } -void Script::O_ZOOMIN() {} +void Script::O_ZOOMIN() { + uint16 slot = readScript16bits(); + debugScript("O_ZOOMIN slot %04d", slot); +} -void Script::O_ZOOMOUT() {} +void Script::O_ZOOMOUT() { + uint16 slot = readScript16bits(); + debugScript("O_ZOOMOUT slot %d", slot); +} void Script::O_SETSTRINGOFFSET() { + int32 offset = readScript32bits(); + debugScript("O_SETSTRINGOFFSET offset %04x", offset); } -void Script::O_GETOBJDATA() {} +void Script::O_GETOBJDATA() { + uint16 flag = readScript16bits(); + uint16 obj = readScript16bits(); + int16 objOffset = readScript16bits(); + debugScript("O_GETOBJDATA flag %d, obj %d, objOffset %d", flag, obj, objOffset); +} -void Script::O_SETOBJDATA() {} +void Script::O_SETOBJDATA() { + uint16 obj = readScript16bits(); + int16 objOffset = readScript16bits(); + uint16 value = readScript16bits(); + debugScript("O_SETOBJDATA obj %d, objOffset %d, value %d", obj, objOffset, value); +} -void Script::O_SWAPOBJECTS() {} +void Script::O_SWAPOBJECTS() { + uint16 obj1 = readScript16bits(); + uint16 obj2 = readScript16bits(); + debugScript("O_SWAPOBJECTS obj1 %d, obj2 %d", obj1, obj2); +} void Script::O_CHANGEHEROSET() { uint16 hero = readScript16bits(); uint16 heroSet = readScript16bits(); - debugScript("O_CHANGEHEROSET hero %d, heroSet %d", hero, heroSet); } -void Script::O_ADDSTRING() {} +void Script::O_ADDSTRING() { + uint16 value = readScript16bits(); + debugScript("O_ADDSTRING value %d", value); +} -void Script::O_SUBSTRING() {} +void Script::O_SUBSTRING() { + uint16 value = readScript16bits(); + debugScript("O_SUBSTRING value %d", value); +} -void Script::O_INITDIALOG() {} +void Script::O_INITDIALOG() { + debugScript("O_INITDIALOG"); +} -void Script::O_ENABLEDIALOGOPT() {} +void Script::O_ENABLEDIALOGOPT() { + uint16 opt = readScript16bits(); + debugScript("O_ENABLEDIALOGOPT opt %d", opt); +} -void Script::O_DISABLEDIALOGOPT() {} +void Script::O_DISABLEDIALOGOPT() { + uint16 opt = readScript16bits(); + debugScript("O_DISABLEDIALOGOPT opt %d", opt); +} -void Script::O_SHOWDIALOGBOX() {} +void Script::O_SHOWDIALOGBOX() { + uint16 box = readScript16bits(); + debugScript("O_SHOWDIALOGBOX box %d", box); +} void Script::O_STOPSAMPLE() { uint16 slot = readScript16bits(); @@ -740,6 +953,7 @@ void Script::O_SETFGCODE() { debugScript("O_SETFGCODE offset %04X", offset); _fgOpcodePC = _currentInstruction + offset; + debugScript("O_SETFGCODE next %08X", _fgOpcodePC); } void Script::O_STOPHERO() { diff --git a/engines/prince/script.h b/engines/prince/script.h index 984b2d93e970..8f1ede3a8300 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -72,9 +72,10 @@ class Script { uint32 _waitFlag; Audio::SoundHandle _soundHandle; - const byte * _string; + const byte *_string; uint32 _currentString; Common::SeekableReadStream *_voiceStream; + const char *_mode; // Helper functions uint32 step(uint32 opcodePC); diff --git a/engines/prince/variatxt.cpp b/engines/prince/variatxt.cpp index 0788d449e3be..427044479356 100644 --- a/engines/prince/variatxt.cpp +++ b/engines/prince/variatxt.cpp @@ -31,7 +31,7 @@ VariaTxt::VariaTxt() : _dataSize(0), _data(NULL) { VariaTxt::~VariaTxt() { _dataSize = 0; delete[] _data; - _dataSize = NULL; + _data = NULL; } From 91466575eb8fa7e192ce1385a4bf3bb86be5a8c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Tue, 5 Nov 2013 18:45:40 +0000 Subject: [PATCH 047/374] PRINCE: unified debug output --- engines/prince/prince.cpp | 26 ++++++++++++++++++-------- engines/prince/prince.h | 1 + engines/prince/script.cpp | 28 +++++++++++++--------------- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 5543499b28e3..b5cb26739b35 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -81,6 +81,16 @@ Graphics::Surface *loadCursor(const char *curName) return curSurface; } +void PrinceEngine::debugEngine(const char *s, ...) { + char buf[STRINGBUFLEN]; + va_list va; + + va_start(va, s); + vsnprintf(buf, STRINGBUFLEN, s, va); + va_end(va); + + debug("Prince::Engine frame %08ld %s", _frameNr, buf); +} PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : @@ -122,7 +132,7 @@ Common::Error PrinceEngine::run() { const Common::FSNode gameDataDir(ConfMan.get("path")); - debug("Adding all path: %s", gameDataDir.getPath().c_str()); + debugEngine("Adding all path: %s", gameDataDir.getPath().c_str()); SearchMan.addSubDirectoryMatching(gameDataDir, "all", 0, 2); SearchMan.addSubDirectoryMatching(gameDataDir, "data/voices/output", 0, 2); @@ -140,7 +150,7 @@ Common::Error PrinceEngine::run() { if (!walizka) return Common::kPathDoesNotExist; - debug("Loading walizka"); + debugEngine("Loading walizka"); if (!_walizkaBmp.loadStream(*walizka)) { return Common::kPathDoesNotExist; } @@ -149,7 +159,7 @@ Common::Error PrinceEngine::run() { if (!skryptStream) return Common::kPathNotFile; - debug("Loading skrypt"); + debugEngine("Loading skrypt"); _script = new Script(this); _script->loadFromStream(*skryptStream); @@ -232,13 +242,13 @@ bool ObjectList::loadFromStream(Common::SeekableReadStream &stream) } bool PrinceEngine::loadLocation(uint16 locationNr) { - debug("PrinceEngine::loadLocation %d", locationNr); + debugEngine("PrinceEngine::loadLocation %d", locationNr); const Common::FSNode gameDataDir(ConfMan.get("path")); SearchMan.remove(Common::String::format("%02d", _locationNr)); _locationNr = locationNr; const Common::String locationNrStr = Common::String::format("%02d", _locationNr); - debug("loadLocation %s", locationNrStr.c_str()); + debugEngine("loadLocation %s", locationNrStr.c_str()); SearchMan.addSubDirectoryMatching(gameDataDir, locationNrStr, 0, 2); // load location background @@ -250,7 +260,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { } if(_roomBmp.loadStream(*room)) { - debug("Room bitmap loaded"); + debugEngine("Room bitmap loaded"); _sceneWidth = _roomBmp.getSurface()->w; } @@ -350,7 +360,7 @@ bool PrinceEngine::loadAnim(uint16 animNr, bool loop) { error("Can't load flic stream %s", streamName.c_str()); } - debug("%s loaded", streamName.c_str()); + debugEngine("%s loaded", streamName.c_str()); _flicLooped = loop; _flicPlayer.start(); playNextFrame(); @@ -371,7 +381,7 @@ void PrinceEngine::scrollCameraRight(int16 delta) { if (_sceneWidth - 640 < delta + _newCameraX) delta += (_sceneWidth - 640) - (delta + _newCameraX); _newCameraX += delta; - debug(0, "PrinceEngine::scrollCameraRight() _newCameraX = %d; delta = %d", _newCameraX, delta); + debugEngine("PrinceEngine::scrollCameraRight() _newCameraX = %d; delta = %d", _newCameraX, delta); } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 68a7793157f6..977f178b1897 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -122,6 +122,7 @@ class PrinceEngine : public Engine { void showTexts(); uint32 getTextWidth(const char *s); + void debugEngine(const char *s, ...); Common::RandomSource *_rnd; Graphics::BitmapDecoder _roomBmp; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 1da3d44036b3..f32c1724b934 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -79,7 +79,7 @@ void Script::debugScript(const char *s, ...) { str += Common::String::format("op %04d: ", _lastOpcode); //debugC(10, DebugChannel::kScript, "PrinceEngine::Script %s %s", str.c_str(), buf); - debug("Prince::Script mode %s frame %ld %s %s", _mode, _vm->_frameNr, str.c_str(), buf); + debug("Prince::Script frame %08ld mode %s %s %s", _vm->_frameNr, _mode, str.c_str(), buf); } void Script::step() { @@ -388,19 +388,20 @@ void Script::O_COMPARE() { void Script::O_JUMPZ() { int32 offset = readScript32bits(); - debugScript("O_JUMPZ offset 0x%04X", offset); if (! _result) { _currentInstruction += offset - 4; } + + debugScript("O_JUMPZ result = %d, next %08x, offset 0x%08X", _result, _currentInstruction, offset); } void Script::O_JUMPNZ() { int32 offset = readScript32bits(); - debugScript("O_JUMPNZ offset 0x%08X", offset); if (_result) { _currentInstruction += offset - 4; - debugScript("O_JUMPNZ next 0x%08X", _currentInstruction); } + + debugScript("O_JUMPNZ result = %d, next %08x, offset 0x%08X", _result, _currentInstruction, offset); } void Script::O_EXIT() { @@ -454,13 +455,13 @@ void Script::O_SETSTRING() { _currentString = offset; if (offset >= 80000) { - debug("GetVaria %s", _vm->_variaTxt->getString(offset - 80000)); + debugScript("GetVaria %s", _vm->_variaTxt->getString(offset - 80000)); } else if (offset < 2000) { uint32 of = READ_LE_UINT32(_vm->_talkTxt+offset*4); const char * txt = (const char *)&_vm->_talkTxt[of]; _string = &_vm->_talkTxt[of]; - debug("TalkTxt %d %s", of, txt); + debugScript("TalkTxt %d %s", of, txt); } debugScript("O_SETSTRING %04d", offset); @@ -758,10 +759,9 @@ void Script::O_GETANIMDATA() { } void Script::O_SETBGCODE() { - int32 bgcode = readScript32bits(); - debugScript("O_SETBGCODE %d", bgcode); - _bgOpcodePC = _currentInstruction + bgcode; - debugScript("O_SETBGCODE next %08X", _bgOpcodePC); + int32 offset = readScript32bits(); + _bgOpcodePC = _currentInstruction + offset; + debugScript("O_SETBGCODE next %08x, offset %08x", _bgOpcodePC, offset); } void Script::O_SETBACKFRAME() { @@ -952,11 +952,9 @@ void Script::O_POPSTRING() { void Script::O_SETFGCODE() { int32 offset = readScript32bits(); - - debugScript("O_SETFGCODE offset %04X", offset); - _fgOpcodePC = _currentInstruction + offset; - debugScript("O_SETFGCODE next %08X", _fgOpcodePC); + + debugScript("O_SETFGCODE next %08x, offset %08x", _fgOpcodePC, offset); } void Script::O_STOPHERO() { @@ -1005,7 +1003,7 @@ void Script::O_SETBACKANIMDATA() { void Script::O_VIEWFLC() { uint16 animNr = readScript16bits(); - debug("O_VIEWFLC animNr %d", animNr); + debugScript("O_VIEWFLC animNr %d", animNr); _vm->loadAnim(animNr, false); } From 4722d0e5becee530b1ca11e5a1ef0f35b23fe721 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Tue, 5 Nov 2013 21:20:46 +0000 Subject: [PATCH 048/374] PRINCE: code cleanup, mostly loading resources --- engines/prince/cursor.cpp | 54 ++++++++++ engines/prince/cursor.h | 50 ++++++++++ engines/prince/font.cpp | 2 +- engines/prince/font.h | 2 +- engines/prince/module.mk | 1 + engines/prince/prince.cpp | 203 +++++++++++++++----------------------- engines/prince/prince.h | 20 ++-- 7 files changed, 197 insertions(+), 135 deletions(-) create mode 100644 engines/prince/cursor.cpp create mode 100644 engines/prince/cursor.h diff --git a/engines/prince/cursor.cpp b/engines/prince/cursor.cpp new file mode 100644 index 000000000000..9a9162fd278a --- /dev/null +++ b/engines/prince/cursor.cpp @@ -0,0 +1,54 @@ +/* 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/cursor.h" + +#include "common/debug.h" +#include "common/stream.h" + +namespace Prince { + +Cursor::Cursor() : _surface(NULL) { +} + +Cursor::~Cursor() { + delete _surface; + _surface = NULL; +} + +bool Cursor::loadFromStream(Common::SeekableReadStream &stream) { + stream.skip(4); + uint16 w = stream.readUint16LE(); + uint16 h = stream.readUint16LE(); + + _surface = new Graphics::Surface(); + _surface->create(w, h, Graphics::PixelFormat::createFormatCLUT8()); + + for (int ih = 0; ih < h; ++ih) { + stream.read(_surface->getBasePtr(0, ih), w); + } + return true; +} + +} + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/cursor.h b/engines/prince/cursor.h new file mode 100644 index 000000000000..05c7da9f3337 --- /dev/null +++ b/engines/prince/cursor.h @@ -0,0 +1,50 @@ +/* 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 CURSOR_PRINCE_H +#define CURSOR_PRINCE_H + +#include "graphics/surface.h" + +namespace Common { + class SeekableReadStream; +} + +namespace Prince { + +class Cursor { +public: + Cursor(); + ~Cursor(); + + bool loadFromStream(Common::SeekableReadStream &stream); + Graphics::Surface *getSurface() const { return _surface; } + +private: + Graphics::Surface *_surface; +}; + +} + +#endif + +/* vim: set tabstop=4 expandtab!: */ diff --git a/engines/prince/font.cpp b/engines/prince/font.cpp index 30e7b5aee2e9..33149c14e467 100644 --- a/engines/prince/font.cpp +++ b/engines/prince/font.cpp @@ -38,7 +38,7 @@ Font::~Font() { delete [] _fontData; } -bool Font::load(Common::SeekableReadStream &stream) { +bool Font::loadFromStream(Common::SeekableReadStream &stream) { stream.seek(0); _fontData = new byte[stream.size()]; stream.read(_fontData, stream.size()); diff --git a/engines/prince/font.h b/engines/prince/font.h index 1afafa3be3f4..020e12bf5482 100644 --- a/engines/prince/font.h +++ b/engines/prince/font.h @@ -39,7 +39,7 @@ class Font : public Graphics::Font { Font(); virtual ~Font(); - bool load(Common::SeekableReadStream &stream); + bool loadFromStream(Common::SeekableReadStream &stream); virtual int getFontHeight() const override; diff --git a/engines/prince/module.mk b/engines/prince/module.mk index f8003f834acb..593c59dcffc3 100644 --- a/engines/prince/module.mk +++ b/engines/prince/module.mk @@ -12,6 +12,7 @@ MODULE_OBJS = \ sound.o \ flags.o \ variatxt.o \ + cursor.o \ prince.o # This module can be built as a plugin diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index b5cb26739b35..e1d35091ed48 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -52,35 +52,12 @@ #include "prince/sound.h" #include "prince/variatxt.h" #include "prince/flags.h" - -#include "video/flic_decoder.h" +#include "prince/font.h" +#include "prince/mhwanh.h" +#include "prince/cursor.h" namespace Prince { -Graphics::Surface *loadCursor(const char *curName) -{ - Common::SeekableReadStream *curStream = SearchMan.createReadStreamForMember(curName); - if (!curStream) { - error("Can't load %s", curName); - return NULL; - } - - curStream->skip(4); - uint16 w = curStream->readUint16LE(); - uint16 h = curStream->readUint16LE(); - - debug("Loading cursor %s, w %d, h %d", curName, w, h); - - Graphics::Surface *curSurface = new Graphics::Surface(); - curSurface->create(w, h, Graphics::PixelFormat::createFormatCLUT8()); - for (int ih = 0; ih < h; ++ih) { - curStream->read(curSurface->getBasePtr(0, ih), w); - } - - delete curStream; - return curSurface; -} - void PrinceEngine::debugEngine(const char *s, ...) { char buf[STRINGBUFLEN]; va_list va; @@ -92,11 +69,11 @@ void PrinceEngine::debugEngine(const char *s, ...) { debug("Prince::Engine frame %08ld %s", _frameNr, buf); } - PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL), _locationNr(0), _debugger(NULL), _objectList(NULL), _mobList(NULL), _midiPlayer(NULL), - _cameraX(0), _newCameraX(0), _frameNr(0) { + _cameraX(0), _newCameraX(0), _frameNr(0), _cursor1(NULL), _cursor2(NULL), _font(NULL), + _walizkaBmp(NULL), _roomBmp(NULL) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -105,7 +82,6 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) DebugMan.enableDebugChannel("script"); gDebugLevel = 10; - _rnd = new Common::RandomSource("prince"); _debugger = new Debugger(this); @@ -118,15 +94,49 @@ PrinceEngine::~PrinceEngine() { delete _rnd; delete _debugger; - delete _cur1; - delete _cur2; + delete _cursor1; + delete _cursor2; delete _midiPlayer; + delete _script; + delete _font; + delete _roomBmp; + delete _walizkaBmp; } GUI::Debugger *PrinceEngine::getDebugger() { return _debugger; } +template +bool loadFromStream(T &resource, Common::SeekableReadStream &stream) { + return resource.loadFromStream(stream); +} + +template <> +bool loadFromStream(MhwanhDecoder &image, Common::SeekableReadStream &stream) { + return image.loadStream(stream); +} + +template <> +bool loadFromStream(Graphics::BitmapDecoder &image, Common::SeekableReadStream &stream) { + return image.loadStream(stream); +} + +template +bool loadResource(T *resource, const char *resourceName) { + Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); + if (!stream) { + error("Can't load %s", resourceName); + return NULL; + } + + bool ret = loadFromStream(*resource, *stream); + + delete stream; + + return ret; +} + Common::Error PrinceEngine::run() { _graph = new GraphicsMan(this); @@ -136,45 +146,23 @@ Common::Error PrinceEngine::run() { SearchMan.addSubDirectoryMatching(gameDataDir, "all", 0, 2); SearchMan.addSubDirectoryMatching(gameDataDir, "data/voices/output", 0, 2); + + _font = new Font(); + loadResource(_font, "font1.raw"); + _walizkaBmp = new MhwanhDecoder(); + loadResource(_walizkaBmp, "walizka"); - Common::SeekableReadStream *font1stream = SearchMan.createReadStreamForMember("font1.raw"); - if (!font1stream) - return Common::kPathNotFile; - - if (_font.load(*font1stream)) { - _font.getCharWidth(103); - } - delete font1stream; - - Common::SeekableReadStream * walizka = SearchMan.createReadStreamForMember("walizka"); - if (!walizka) - return Common::kPathDoesNotExist; - - debugEngine("Loading walizka"); - if (!_walizkaBmp.loadStream(*walizka)) { - return Common::kPathDoesNotExist; - } - - Common::SeekableReadStream * skryptStream = SearchMan.createReadStreamForMember("skrypt.dat"); - if (!skryptStream) - return Common::kPathNotFile; - - debugEngine("Loading skrypt"); _script = new Script(this); - _script->loadFromStream(*skryptStream); - - delete skryptStream; - - Common::SeekableReadStream *variaTxtStream = SearchMan.createReadStreamForMember("variatxt.dat"); - - if (!variaTxtStream) { - error("Can't load variatxt.dat"); - return Common::kPathNotFile; - } + loadResource(_script, "skrypt.dat"); _variaTxt = new VariaTxt(); - _variaTxt->loadFromStream(*variaTxtStream); - delete variaTxtStream; + loadResource(_variaTxt, "variatxt.dat"); + + _cursor1 = new Cursor(); + loadResource(_cursor1, "mouse1.cur"); + + _cursor2 = new Cursor(); + loadResource(_cursor2, "mouse2.cur"); Common::SeekableReadStream *talkTxtStream = SearchMan.createReadStreamForMember("talktxt.dat"); if (!talkTxtStream) { @@ -188,22 +176,17 @@ Common::Error PrinceEngine::run() { delete talkTxtStream; - - _cur1 = loadCursor("mouse1.cur"); - _cur2 = loadCursor("mouse2.cur"); -#if 0 - Common::SeekableReadStream *logoStream = SearchMan.createReadStreamForMember("logo.raw"); - if (logoStream) + MhwanhDecoder *logo = new MhwanhDecoder(); + loadResource(logo, "logo.raw"); + if (logo) { - MhwanhDecoder logo; - logo.loadStream(*logoStream); - _graph->setPalette(logo.getPalette()); - _graph->draw(0, 0, logo.getSurface()); + _graph->setPalette(logo->getPalette()); + _graph->draw(0, 0, logo->getSurface()); _graph->update(); _system->delayMillis(700); } - delete logoStream; -#endif + delete logo; + mainLoop(); return Common::kNoError; @@ -251,47 +234,21 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { debugEngine("loadLocation %s", locationNrStr.c_str()); SearchMan.addSubDirectoryMatching(gameDataDir, locationNrStr, 0, 2); + delete _roomBmp; // load location background - Common::SeekableReadStream *room = SearchMan.createReadStreamForMember("room"); - - if (!room) { - error("Can't load room bitmap"); - return false; - } - - if(_roomBmp.loadStream(*room)) { - debugEngine("Room bitmap loaded"); - _sceneWidth = _roomBmp.getSurface()->w; + _roomBmp = new Graphics::BitmapDecoder(); + loadResource(_roomBmp, "room"); + if (_roomBmp->getSurface()) { + _sceneWidth = _roomBmp->getSurface()->w; } - delete room; - delete _mobList; - _mobList = NULL; - - Common::SeekableReadStream *mobListStream = SearchMan.createReadStreamForMember("mob.lst"); - if (!mobListStream) { - error("Can't read mob.lst"); - return false; - } - _mobList = new MobList(); - _mobList->loadFromStream(*mobListStream); - - delete mobListStream; + loadResource(_mobList, "mob.lst"); delete _objectList; - _objectList = NULL; - - Common::SeekableReadStream *objListStream = SearchMan.createReadStreamForMember("obj.lst"); - if (!objListStream) { - error("Can't read obj.lst"); - return false; - } - _objectList = new ObjectList(); - _objectList->loadFromStream(*objListStream); - delete objListStream; + loadResource(_objectList, "obj.lst"); const char *musName = MusicPlayer::_musTable[MusicPlayer::_musRoomTable[locationNr]]; _midiPlayer->loadMidi(musName); @@ -311,16 +268,16 @@ void PrinceEngine::changeCursor(uint16 curId) CursorMan.showMouse(false); return; case 1: - curSurface = _cur1; + curSurface = _cursor1->getSurface(); break; case 2: - curSurface = _cur2; + curSurface = _cursor2->getSurface(); hotspotX = curSurface->w >> 1; hotspotY = curSurface->h >> 1; break; } - CursorMan.replaceCursorPalette(_roomBmp.getPalette(), 0, 255); + CursorMan.replaceCursorPalette(_roomBmp->getPalette(), 0, 255); CursorMan.replaceCursor( curSurface->getBasePtr(0, 0), curSurface->w, curSurface->h, @@ -418,7 +375,7 @@ void PrinceEngine::hotspot() { if (it->_rect.contains(mousePosCamera)) { uint16 textW = 0; for (uint16 i = 0; i < it->_name.size(); ++i) - textW += _font.getCharWidth(it->_name[i]); + textW += _font->getCharWidth(it->_name[i]); uint16 x = mousepos.x - textW/2; if (x > _graph->_frontScreen->w) @@ -427,11 +384,11 @@ void PrinceEngine::hotspot() { if (x + textW > _graph->_frontScreen->w) x = _graph->_frontScreen->w - textW; - _font.drawString( + _font->drawString( _graph->_frontScreen, it->_name, x, - mousepos.y - _font.getFontHeight(), + mousepos.y - _font->getFontHeight(), _graph->_frontScreen->w, 216 ); @@ -454,7 +411,7 @@ void PrinceEngine::printAt(uint32 slot, uint8 color, const char *s, uint16 x, ui uint32 PrinceEngine::getTextWidth(const char *s) { uint16 textW = 0; while (*s) { - textW += _font.getCharWidth(*s) + _font.getKerningOffset(0, 0); + textW += _font->getCharWidth(*s) + _font->getKerningOffset(0, 0); ++s; } return textW; @@ -467,14 +424,14 @@ void PrinceEngine::showTexts() { continue; Common::Array lines; - _font.wordWrapText(text._str, _graph->_frontScreen->w, lines); + _font->wordWrapText(text._str, _graph->_frontScreen->w, lines); for (uint8 i = 0; i < lines.size(); ++i) { - _font.drawString( + _font->drawString( _graph->_frontScreen, lines[i], text._x - getTextWidth(lines[i].c_str())/2, - text._y - (lines.size() - i) * (_font.getFontHeight()), + text._y - (lines.size() - i) * (_font->getFontHeight()), _graph->_frontScreen->w, text._color ); @@ -488,9 +445,9 @@ void PrinceEngine::showTexts() { } void PrinceEngine::drawScreen() { - const Graphics::Surface *roomSurface = _roomBmp.getSurface(); + const Graphics::Surface *roomSurface = _roomBmp->getSurface(); if (roomSurface) { - _graph->setPalette(_roomBmp.getPalette()); + _graph->setPalette(_roomBmp->getPalette()); const Graphics::Surface visiblePart = roomSurface->getSubArea(Common::Rect(_cameraX, 0, roomSurface->w, roomSurface->h)); _graph->draw(0, 0, &visiblePart); } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 977f178b1897..c97a9022a670 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -42,9 +42,6 @@ #include "video/flic_decoder.h" -#include "prince/font.h" -#include "prince/mhwanh.h" - namespace Prince { struct PrinceGameDescription; @@ -57,6 +54,9 @@ class ObjectList; class MobList; class MusicPlayer; class VariaTxt; +class Cursor; +class MhwanhDecoder; +class Font; struct Text { const char *_str; @@ -124,21 +124,21 @@ class PrinceEngine : public Engine { uint32 getTextWidth(const char *s); void debugEngine(const char *s, ...); - Common::RandomSource *_rnd; - Graphics::BitmapDecoder _roomBmp; uint16 _locationNr; - MhwanhDecoder _walizkaBmp; - - Graphics::Surface *_cur1; - Graphics::Surface *_cur2; + Common::RandomSource *_rnd; + Graphics::BitmapDecoder *_roomBmp; + Cursor *_cursor1; + Cursor *_cursor2; + MhwanhDecoder *_walizkaBmp; Debugger *_debugger; GraphicsMan *_graph; Script *_script; - Font _font; + Font *_font; ObjectList *_objectList; MobList *_mobList; MusicPlayer *_midiPlayer; + uint16 _cameraX; uint16 _newCameraX; uint16 _sceneWidth; From d6a76d98145bae11dbdff212e79784c060f49b9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Tue, 5 Nov 2013 21:57:10 +0000 Subject: [PATCH 049/374] PRINCE: major code cleanup, flag handling rewritten in script --- engines/prince/debugger.cpp | 178 ++++++++++++++++++------------------ engines/prince/debugger.h | 3 +- engines/prince/prince.cpp | 2 +- engines/prince/script.cpp | 136 +++++++++++---------------- engines/prince/script.h | 13 ++- 5 files changed, 158 insertions(+), 174 deletions(-) diff --git a/engines/prince/debugger.cpp b/engines/prince/debugger.cpp index be9677b99f3e..449ba5001ab7 100644 --- a/engines/prince/debugger.cpp +++ b/engines/prince/debugger.cpp @@ -26,130 +26,132 @@ namespace Prince { Debugger::Debugger(PrinceEngine *vm) : GUI::Debugger(), _vm(vm) { - DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); - DCmd_Register("level", WRAP_METHOD(Debugger, Cmd_DebugLevel)); - DCmd_Register("setflag", WRAP_METHOD(Debugger, Cmd_SetFlag)); - DCmd_Register("getflag", WRAP_METHOD(Debugger, Cmd_GetFlag)); - DCmd_Register("clearflag", WRAP_METHOD(Debugger, Cmd_ClearFlag)); - DCmd_Register("viewflc", WRAP_METHOD(Debugger, Cmd_ViewFlc)); - DCmd_Register("initroom", WRAP_METHOD(Debugger, Cmd_InitRoom)); - DCmd_Register("changecursor", WRAP_METHOD(Debugger, Cmd_ChangeCursor)); + DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); + DCmd_Register("level", WRAP_METHOD(Debugger, Cmd_DebugLevel)); + DCmd_Register("setflag", WRAP_METHOD(Debugger, Cmd_SetFlag)); + DCmd_Register("getflag", WRAP_METHOD(Debugger, Cmd_GetFlag)); + DCmd_Register("clearflag", WRAP_METHOD(Debugger, Cmd_ClearFlag)); + DCmd_Register("viewflc", WRAP_METHOD(Debugger, Cmd_ViewFlc)); + DCmd_Register("initroom", WRAP_METHOD(Debugger, Cmd_InitRoom)); + DCmd_Register("changecursor", WRAP_METHOD(Debugger, Cmd_ChangeCursor)); } static int strToInt(const char *s) { - if (!*s) - // No string at all - return 0; - else if (toupper(s[strlen(s) - 1]) != 'H') - // Standard decimal string - return atoi(s); - - // Hexadecimal string - uint tmp = 0; - int read = sscanf(s, "%xh", &tmp); - if (read < 1) - error("strToInt failed on string \"%s\"", s); - return (int)tmp; + if (!*s) + // No string at all + return 0; + else if (toupper(s[strlen(s) - 1]) != 'H') + // Standard decimal string + return atoi(s); + + // Hexadecimal string + uint tmp = 0; + int read = sscanf(s, "%xh", &tmp); + if (read < 1) + error("strToInt failed on string \"%s\"", s); + return (int)tmp; } bool Debugger::Cmd_DebugLevel(int argc, const char **argv) { - if (argc == 1) { - DebugPrintf("Debugging is currently set at level %d\n", gDebugLevel); - } else { // set level - gDebugLevel = atoi(argv[1]); - if (0 <= gDebugLevel && gDebugLevel < 11) { - DebugPrintf("Debug level set to level %d\n", gDebugLevel); - } else if (gDebugLevel < 0) { - DebugPrintf("Debugging is now disabled\n"); - } else - DebugPrintf("Not a valid debug level (0 - 10)\n"); - } - - return true; + if (argc == 1) { + DebugPrintf("Debugging is currently set at level %d\n", gDebugLevel); + } else { // set level + gDebugLevel = atoi(argv[1]); + if (0 <= gDebugLevel && gDebugLevel < 11) { + DebugPrintf("Debug level set to level %d\n", gDebugLevel); + } else if (gDebugLevel < 0) { + DebugPrintf("Debugging is now disabled\n"); + } else + DebugPrintf("Not a valid debug level (0 - 10)\n"); + } + + return true; } /* * This command sets a flag */ bool Debugger::Cmd_SetFlag(int argc, const char **argv) { - // Check for a flag to set - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } - - int flagNum = strToInt(argv[1]); - //g_globals->setFlag(flagNum); - return true; + // Check for a flag to set + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + //g_globals->setFlag(flagNum); + return true; } /* * This command gets the value of a flag */ bool Debugger::Cmd_GetFlag(int argc, const char **argv) { - // Check for an flag to display - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } - - int flagNum = strToInt(argv[1]); - //DebugPrintf("Value: %d\n", g_globals->getFlag(flagNum)); - return true; + // Check for an flag to display + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + //DebugPrintf("Value: %d\n", g_globals->getFlag(flagNum)); + return true; } /* * This command clears a flag */ bool Debugger::Cmd_ClearFlag(int argc, const char **argv) { - // Check for a flag to clear - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } - - int flagNum = strToInt(argv[1]); - //g_globals->clearFlag(flagNum); - return true; + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + //g_globals->clearFlag(flagNum); + return true; } /* * This command starts new flc anim */ bool Debugger::Cmd_ViewFlc(int argc, const char **argv) { - // Check for a flag to clear - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } - - int flagNum = strToInt(argv[1]); - _vm->loadAnim(flagNum, false); - return true; + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + _vm->loadAnim(flagNum, false); + return true; } bool Debugger::Cmd_InitRoom(int argc, const char **argv) { - // Check for a flag to clear - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } - - int flagNum = strToInt(argv[1]); - _vm->loadLocation(flagNum); - return true; + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + _vm->loadLocation(flagNum); + return true; } bool Debugger::Cmd_ChangeCursor(int argc, const char **argv) { - // Check for a flag to clear - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); - return true; - } - - int flagNum = strToInt(argv[1]); - _vm->changeCursor(flagNum); - return true; + // Check for a flag to clear + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int flagNum = strToInt(argv[1]); + _vm->changeCursor(flagNum); + return true; } } + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/debugger.h b/engines/prince/debugger.h index 08b1676fd738..cbb609466853 100644 --- a/engines/prince/debugger.h +++ b/engines/prince/debugger.h @@ -47,7 +47,8 @@ class Debugger : public GUI::Debugger { PrinceEngine *_vm; }; - } #endif + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index e1d35091ed48..2d1f6ce880cc 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -357,7 +357,7 @@ void PrinceEngine::keyHandler(Common::Event event) { scrollCameraRight(32); break; case Common::KEYCODE_ESCAPE: - _script->setFlag(Flags::ESCAPED2, 1); + _script->setFlagValue(Flags::ESCAPED2, 1); break; } } diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index f32c1724b934..1c09ddb50f03 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -47,8 +47,12 @@ Script::~Script() { delete[] _code; } -void Script::setFlag(Flags::Id flagId, uint16 value) { - _flags[flagId - 0x8000] = value; +void Script::setFlagValue(Flags::Id flagId, uint16 value) { + _flags[(uint16)flagId - FLAG_MASK] = value; +} + +uint16 Script::getFlagValue(Flags::Id flagId) { + return _flags[(uint16)flagId - FLAG_MASK]; } bool Script::loadFromStream(Common::SeekableReadStream &stream) { @@ -83,12 +87,10 @@ void Script::debugScript(const char *s, ...) { } void Script::step() { -#if 1 if (_bgOpcodePC) { _mode = "bg"; _bgOpcodePC = step(_bgOpcodePC); } -#endif if (_fgOpcodePC) { _mode = "fg"; _fgOpcodePC = step(_fgOpcodePC); @@ -147,6 +149,14 @@ uint16 Script::readScript16bits() { return lower | (upper << 8); } +uint16 Script::readScriptValue() { + uint16 value = readScript16bits(); + if (value & FLAG_MASK) { + value = _flags[value - FLAG_MASK]; + } + return value; +} + uint32 Script::readScript32bits() { uint16 lower = readScript16bits(); uint16 upper = readScript16bits(); @@ -359,31 +369,20 @@ void Script::O_CHANGEANIMTYPE() { } void Script::O__SETFLAG() { - uint16 flagId = readScript16bits(); - uint16 value = readScript16bits(); - - if (value & 0x8000) { - value = _flags[value - 0x8000]; - } + Flags::Id flagId = readScriptFlagId(); + uint16 value = readScriptValue(); debugScript("O__SETFLAG 0x%04X (%s) = %d", flagId, Flags::getFlagName(flagId), value); - _flags[flagId - 0x8000] = value; + setFlagValue((Flags::Id)(flagId), value); } void Script::O_COMPARE() { - uint16 flagId = readScript16bits(); - uint16 value = readScript16bits(); - - if (value & 0x8000) { - uint16 val = _flags[value - 0x8000]; - debugScript("GetFlagValue 0x%04X (%s), value %d", value, Flags::getFlagName(value), val); + Flags::Id flagId = readScriptFlagId(); + uint16 value = readScriptValue(); - value = val; - } - - _result = !(_flags[flagId - 0x8000] == value); - debugScript("O_COMPARE flagId 0x%04X (%s), value %d == %d (%d)", flagId, Flags::getFlagName(flagId), value, _flags[flagId - 0x8000], _result); + _result = getFlagValue(flagId) != value; + debugScript("O_COMPARE flagId 0x%04X (%s), value %d == %d (%d)", flagId, Flags::getFlagName(flagId), value, getFlagValue(flagId), _result); } void Script::O_JUMPZ() { @@ -410,15 +409,11 @@ void Script::O_EXIT() { } void Script::O_ADDFLAG() { - uint16 flagId = readScript16bits(); - uint16 value = readScript16bits(); + Flags::Id flagId = readScriptFlagId(); + uint16 value = readScriptValue(); - if (value & 0x8000) { - value = _flags[value - 0x8000]; - } - - _flags[flagId - 0x8000] += value; - if (_flags[flagId - 0x8000]) + setFlagValue(flagId, getFlagValue(flagId) + value); + if (getFlagValue(flagId)) _result = 1; else _result = 0; @@ -434,15 +429,11 @@ void Script::O_TALKANIM() { } void Script::O_SUBFLAG() { - uint16 flagId = readScript16bits(); - uint16 value = readScript16bits(); + Flags::Id flagId = readScriptFlagId(); + uint16 value = readScriptValue(); - if (value & 0x8000) { - value = _flags[value - 0x8000]; - } - - _flags[flagId - 0x8000] -= value; - if (_flags[flagId - 0x8000]) + setFlagValue(flagId, getFlagValue(flagId) - value); + if (getFlagValue(flagId)) _result = 1; else _result = 0; @@ -468,18 +459,14 @@ void Script::O_SETSTRING() { } void Script::O_ANDFLAG() { - uint16 flagId = readScript16bits(); - uint16 value = readScript16bits(); + Flags::Id flagId = readScriptFlagId(); + uint16 value = readScriptValue(); debugScript("O_ANDFLAG flagId %d, value %d", flagId, value); - if (value & 0x8000) { - value = _flags[value - 0x8000]; - } + setFlagValue(flagId, getFlagValue(flagId) & value); - _flags[flagId - 0x8000] &= value; - - if (_flags[flagId - 0x8000]) { + if (getFlagValue(flagId)) { _result = 1; } else { _result = 0; @@ -487,7 +474,7 @@ void Script::O_ANDFLAG() { } void Script::O_GETMOBDATA() { - uint16 flagId = readScript16bits(); + Flags::Id flagId = readScriptFlagId(); uint16 mobId = readScript16bits(); uint16 mobOffset = readScript16bits(); @@ -495,18 +482,14 @@ void Script::O_GETMOBDATA() { } void Script::O_ORFLAG() { - uint16 flagId = readScript16bits(); - uint16 value = readScript16bits(); + Flags::Id flagId = readScriptFlagId(); + uint16 value = readScriptValue(); debugScript("O_ORFLAG flagId %d, value %d", flagId, value); + + setFlagValue(flagId, getFlagValue(flagId) | value); - if (value & 0x8000) { - value = _flags[value - 0x8000]; - } - - _flags[flagId - 0x8000] |= value; - - if (_flags[flagId - 0x8000]) { + if (getFlagValue(flagId)) { _result = 1; } else { _result = 0; @@ -522,18 +505,14 @@ void Script::O_SETMOBDATA() { } void Script::O_XORFLAG() { - uint16 flagId = readScript16bits(); - uint16 value = readScript16bits(); + Flags::Id flagId = readScriptFlagId(); + uint16 value = readScriptValue(); debugScript("O_XORFLAG flagId %d, value %d", flagId, value); - if (value & 0x8000) { - value = _flags[value - 0x8000]; - } - - _flags[flagId - 0x8000] ^= value; + setFlagValue(flagId, getFlagValue(flagId) ^ value); - if (_flags[flagId - 0x8000]) { + if (getFlagValue(flagId)) { _result = 1; } else { _result = 0; @@ -691,10 +670,7 @@ void Script::O_TALKHERO() { } void Script::O_WAITTEXT() { - uint16 slot = readScript16bits(); - if (slot & 0x8000) { - slot = _flags[slot - 0x8000]; - } + uint16 slot = readScriptValue(); Text &text = _vm->_textSlots[slot]; if (text._time) { _opcodeNF = 1; @@ -789,11 +765,11 @@ void Script::O_LOADPATH() { } void Script::O_GETCHAR() { - uint16 flagId = readScript16bits(); + Flags::Id flagId = readScriptFlagId(); - _flags[flagId - 0x8000] = *_string; + setFlagValue(flagId, *_string); - debugScript("O_GETCHAR %04X (%s) %02x", flagId, Flags::getFlagName(flagId), _flags[flagId - 0x8000]); + debugScript("O_GETCHAR %04X (%s) %02x", flagId, Flags::getFlagName(flagId), getFlagValue(flagId)); ++_string; } @@ -816,7 +792,7 @@ void Script::O_PRINTAT() { debugScript("O_PRINTAT slot %d, fr1 %d, fr2 %d", slot, fr1, fr2); - uint8 color = _flags[Flags::KOLOR - 0x8000]; + uint8 color = getFlagValue(Flags::KOLOR); _vm->printAt(slot, color, (const char *)_string, fr1, fr2); @@ -923,21 +899,21 @@ void Script::O_SETPATH() { void Script::O_GETHEROX() { uint16 heroId = readScript16bits(); - uint16 flagId = readScript16bits(); + Flags::Id flagId = readScriptFlagId(); debugScript("O_GETHEROX heroId %d, flagId %d", heroId, flagId); } void Script::O_GETHEROY() { uint16 heroId = readScript16bits(); - uint16 flagId = readScript16bits(); + Flags::Id flagId = readScriptFlagId(); debugScript("O_GETHEROY heroId %d, flagId %d", heroId, flagId); } void Script::O_GETHEROD() { uint16 heroId = readScript16bits(); - uint16 flagId = readScript16bits(); + Flags::Id flagId = readScriptFlagId(); debugScript("O_GETHEROD heroId %d, flagId %d", heroId, flagId); } @@ -1090,7 +1066,7 @@ void Script::O_SKIPTEXT() { void Script::SetVoice(uint32 slot) { - const uint16 VOICE_H_LINE = _flags[Flags::VOICE_H_LINE - 0x8000]; + const uint16 VOICE_H_LINE = getFlagValue(Flags::VOICE_H_LINE); const Common::String streamName = Common::String::format("%03d-%02d.WAV", _currentString, VOICE_H_LINE); debugScript("Loading wav %s slot %d", streamName.c_str(), slot); @@ -1149,13 +1125,9 @@ void Script::O_SETVOICEC() { } void Script::O_VIEWFLCLOOP() { - uint16 value = readScript16bits(); + uint16 value = readScriptValue(); debugScript("O_VIEWFLCLOOP animId %d", value); - if (value & 0x8000) { - value = _flags[value - 0x8000]; - } - _vm->loadAnim(value, true); } @@ -1178,7 +1150,7 @@ void Script::O_GETKRZYWA() { } void Script::O_GETMOB() { - uint16 flagId = readScript16bits(); + Flags::Id flagId = readScriptFlagId(); uint16 mx = readScript16bits(); uint16 my = readScript16bits(); debugScript("O_GETMOB flagId %d, mx %d, my %d", flagId, mx, my); diff --git a/engines/prince/script.h b/engines/prince/script.h index 8f1ede3a8300..a323c1784dc0 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -45,7 +45,9 @@ class Script { bool loadFromStream(Common::SeekableReadStream &stream); void step(); - void setFlag(Flags::Id flag, uint16 value); + + void setFlagValue(Flags::Id flag, uint16 value); + uint16 getFlagValue(Flags::Id flag); private: PrinceEngine *_vm; @@ -60,7 +62,9 @@ class Script { uint16 _lastOpcode; uint32 _lastInstruction; byte _result; - int16 _flags[2000]; + static const uint16 MAX_FLAGS = 2000; + static const uint16 FLAG_MASK = 0x8000; + int16 _flags[MAX_FLAGS]; bool _opcodeNF; @@ -83,8 +87,13 @@ class Script { uint8 getCodeByte(uint32 address); uint8 readScript8bits(); uint16 readScript16bits(); + uint32 readScript32bits(); uint16 readScript8or16bits(); + + uint16 readScriptValue(); + Flags::Id readScriptFlagId() { return (Flags::Id)readScript16bits(); } + void debugScript(const char *s, ...); void SetVoice(uint32 slot); From 2b5b0b9ca2c8415156c730a9f043562d39f3914c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Tue, 5 Nov 2013 22:15:55 +0000 Subject: [PATCH 050/374] PRINCE: voice sample handling moved to prince module --- engines/prince/prince.cpp | 51 +++++++++++++++++++++++++++++++++++- engines/prince/prince.h | 7 +++++ engines/prince/script.cpp | 54 ++++++++------------------------------- engines/prince/script.h | 2 -- 4 files changed, 68 insertions(+), 46 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 2d1f6ce880cc..2b4390c75523 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -73,7 +73,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL), _locationNr(0), _debugger(NULL), _objectList(NULL), _mobList(NULL), _midiPlayer(NULL), _cameraX(0), _newCameraX(0), _frameNr(0), _cursor1(NULL), _cursor2(NULL), _font(NULL), - _walizkaBmp(NULL), _roomBmp(NULL) { + _walizkaBmp(NULL), _roomBmp(NULL), _voiceStream(NULL) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -304,6 +304,55 @@ bool PrinceEngine::playNextFrame() { return true; } +void PrinceEngine::playSample(uint16 sampleId, uint16 loopType) { + if (_voiceStream) { + + Audio::RewindableAudioStream *audioStream = Audio::makeWAVStream(_voiceStream, DisposeAfterUse::YES); + _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, audioStream, sampleId); + } +} + +void PrinceEngine::stopSample(uint16 sampleId) { + _mixer->stopID(sampleId); + _voiceStream = NULL; +} + +bool PrinceEngine::loadVoice(uint32 slot, const Common::String &streamName) { + debugEngine("Loading wav %s slot %d", streamName.c_str(), slot); + + _voiceStream = SearchMan.createReadStreamForMember(streamName); + if (!_voiceStream) { + error("Can't open %s", streamName.c_str()); + return false; + } + + uint32 id = _voiceStream->readUint32LE(); + if (id != 0x46464952) { + error("It's not RIFF file %s", streamName.c_str()); + return false; + } + + _voiceStream->skip(0x20); + id = _voiceStream->readUint32LE(); + if (id != 0x61746164) { + error("No data section in %s id %04x", streamName.c_str(), id); + return false; + } + + id = _voiceStream->readUint32LE(); + debugEngine("SetVoice slot %d time %04x", slot, id); + id <<= 3; + id /= 22050; + id += 2; + + _textSlots[slot]._time = id; + + debugEngine("SetVoice slot %d time %04x", slot, id); + _voiceStream->seek(0); + + return true; +} + bool PrinceEngine::loadAnim(uint16 animNr, bool loop) { Common::String streamName = Common::String::format("AN%02d", animNr); Common::SeekableReadStream * flicStream = SearchMan.createReadStreamForMember(streamName); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index c97a9022a670..4f2ddf827a68 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -101,6 +101,10 @@ class PrinceEngine : public Engine { bool loadLocation(uint16 locationNr); bool loadAnim(uint16 animNr, bool loop); + bool loadVoice(uint32 slot, const Common::String &name); + + void playSample(uint16 sampleId, uint16 loopType); + void stopSample(uint16 sampleId); virtual GUI::Debugger *getDebugger(); @@ -139,6 +143,9 @@ class PrinceEngine : public Engine { MobList *_mobList; MusicPlayer *_midiPlayer; + Audio::SoundHandle _soundHandle; + Common::SeekableReadStream *_voiceStream; + uint16 _cameraX; uint16 _newCameraX; uint16 _sceneWidth; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 1c09ddb50f03..fd0dc7326406 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -40,7 +40,7 @@ static const uint16 NUM_OPCODES = 144; Script::Script(PrinceEngine *vm) : _code(NULL), _stacktop(0), _vm(vm), _opcodeNF(false), - _waitFlag(0), _voiceStream(NULL), _result(true) { + _waitFlag(0), _result(true) { } Script::~Script() { @@ -200,12 +200,7 @@ void Script::O_PLAYSAMPLE() { uint16 sampleId = readScript16bits(); uint16 loopType = readScript16bits(); debugScript("O_PLAYSAMPLE sampleId %d loopType %d", sampleId, loopType); - - if (_voiceStream) { - - Audio::RewindableAudioStream *audioStream = Audio::makeWAVStream(_voiceStream, DisposeAfterUse::YES); - _vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, audioStream, sampleId); - } + _vm->playSample(sampleId, loopType); } void Script::O_PUTOBJECT() { @@ -875,9 +870,7 @@ void Script::O_SHOWDIALOGBOX() { void Script::O_STOPSAMPLE() { uint16 slot = readScript16bits(); debugScript("O_STOPSAMPLE slot %d", slot); - - _vm->_mixer->stopID(slot); - _voiceStream = NULL; + _vm->stopSample(slot); } void Script::O_BACKANIMRANGE() { @@ -1065,39 +1058,14 @@ void Script::O_SKIPTEXT() { } void Script::SetVoice(uint32 slot) { - - const uint16 VOICE_H_LINE = getFlagValue(Flags::VOICE_H_LINE); - - const Common::String streamName = Common::String::format("%03d-%02d.WAV", _currentString, VOICE_H_LINE); - debugScript("Loading wav %s slot %d", streamName.c_str(), slot); - - _voiceStream = SearchMan.createReadStreamForMember(streamName); - if (!_voiceStream) { - error("Can't open %s", streamName.c_str()); - } - uint32 id = _voiceStream->readUint32LE(); - if (id != 0x46464952) { - error("It's not RIFF file %s", streamName.c_str()); - return; - } - - _voiceStream->skip(0x20); - id = _voiceStream->readUint32LE(); - if (id != 0x61746164) { - error("No data section in %s id %04x", streamName.c_str(), id); - return; - } - - id = _voiceStream->readUint32LE(); - debugScript("SetVoice slot %d time %04x", slot, id); - id <<= 3; - id /= 22050; - id += 2; - - _vm->_textSlots[slot]._time = id; - - debugScript("SetVoice slot %d time %04x", slot, id); - _voiceStream->seek(0); + _vm->loadVoice( + slot, + Common::String::format( + "%03d-%02d.WAV", + _currentString, + getFlagValue(Flags::VOICE_H_LINE) + ) + ); } void Script::O_SETVOICEH() { diff --git a/engines/prince/script.h b/engines/prince/script.h index a323c1784dc0..86b998829f2d 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -74,11 +74,9 @@ class Script { uint8 _stacktop; uint8 _savedStacktop; uint32 _waitFlag; - Audio::SoundHandle _soundHandle; const byte *_string; uint32 _currentString; - Common::SeekableReadStream *_voiceStream; const char *_mode; // Helper functions From 3ed4e36ee4e00802a50e04133f84bee1fc68e41d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Tue, 5 Nov 2013 22:22:51 +0000 Subject: [PATCH 051/374] PRINCE: fixed indentation --- engines/prince/script.cpp | 44 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index fd0dc7326406..a25e8241e1d6 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -44,7 +44,7 @@ Script::Script(PrinceEngine *vm) : } Script::~Script() { - delete[] _code; + delete[] _code; } void Script::setFlagValue(Flags::Id flagId, uint16 value) { @@ -56,11 +56,11 @@ uint16 Script::getFlagValue(Flags::Id flagId) { } bool Script::loadFromStream(Common::SeekableReadStream &stream) { - _codeSize = stream.size(); - _code = new byte[_codeSize]; + _codeSize = stream.size(); + _code = new byte[_codeSize]; - if (!_code) - return false; + if (!_code) + return false; stream.read(_code, _codeSize); // Initialize the script @@ -68,16 +68,16 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) { _fgOpcodePC = READ_LE_UINT32(_code + 4); _bgOpcodePC = 0; - return true; + return true; } void Script::debugScript(const char *s, ...) { char buf[STRINGBUFLEN]; va_list va; - va_start(va, s); - vsnprintf(buf, STRINGBUFLEN, s, va); - va_end(va); + va_start(va, s); + vsnprintf(buf, STRINGBUFLEN, s, va); + va_end(va); Common::String str = Common::String::format("@0x%08X: ", _lastInstruction); str += Common::String::format("op %04d: ", _lastOpcode); @@ -131,22 +131,22 @@ uint32 Script::step(uint32 opcodePC) { } uint8 Script::getCodeByte(uint32 address) { - if (address >= _codeSize) - error("Trying to read a script byte at address 0x%04X, while the " - "script is just 0x%04X bytes long", address, _codeSize); - return _code[address]; + if (address >= _codeSize) + error("Trying to read a script byte at address 0x%04X, while the " + "script is just 0x%04X bytes long", address, _codeSize); + return _code[address]; } uint8 Script::readScript8bits() { - uint8 data = getCodeByte(_currentInstruction); - _currentInstruction++; - return data; + uint8 data = getCodeByte(_currentInstruction); + _currentInstruction++; + return data; } uint16 Script::readScript16bits() { - uint8 lower = readScript8bits(); - uint8 upper = readScript8bits(); - return lower | (upper << 8); + uint8 lower = readScript8bits(); + uint8 upper = readScript8bits(); + return lower | (upper << 8); } uint16 Script::readScriptValue() { @@ -158,9 +158,9 @@ uint16 Script::readScriptValue() { } uint32 Script::readScript32bits() { - uint16 lower = readScript16bits(); - uint16 upper = readScript16bits(); - return lower | (upper << 16); + uint16 lower = readScript16bits(); + uint16 upper = readScript16bits(); + return lower | (upper << 16); } void Script::O_WAITFOREVER() { From dfdff8db0848429266376941813cb3456b14233e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Tue, 5 Nov 2013 22:25:17 +0000 Subject: [PATCH 052/374] PRINCE: memory leak fixed in object --- engines/prince/object.cpp | 8 +++++--- engines/prince/object.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/engines/prince/object.cpp b/engines/prince/object.cpp index 9f7efcfb88d7..19dd7034a153 100644 --- a/engines/prince/object.cpp +++ b/engines/prince/object.cpp @@ -32,7 +32,11 @@ namespace Prince { -Object::Object() : _surface(NULL) { +Object::Object() : _surface(NULL), _x(0), _y(0), _z(0) { +} + +Object::~Object() { + delete _surface; } void Object::loadSurface(Common::SeekableReadStream &stream) { @@ -43,11 +47,9 @@ void Object::loadSurface(Common::SeekableReadStream &stream) { for (int h = 0; h < _surface->h; ++h) { stream.read(_surface->getBasePtr(0, h), _surface->w); } - } bool Object::loadFromStream(Common::SeekableReadStream &stream) { - int32 pos = stream.pos(); uint16 x = stream.readUint16LE(); if (x == 0xFFFF) diff --git a/engines/prince/object.h b/engines/prince/object.h index 2c2dbc9fbf1e..052b88dad6be 100644 --- a/engines/prince/object.h +++ b/engines/prince/object.h @@ -31,6 +31,7 @@ namespace Prince { class Object { public: Object(); + ~Object(); bool loadFromStream(Common::SeekableReadStream &stream); Graphics::Surface *getSurface() const { return _surface; } From 6c0cd59dff1139ff56c366fb3d5d04b3e998d42e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Fri, 8 Nov 2013 23:17:20 +0000 Subject: [PATCH 053/374] PRINCE: some memory leaks removed. Initialization moved to separate method --- engines/plugins_table.h | 6 ++-- engines/prince/archive.h | 2 +- engines/prince/cursor.cpp | 1 + engines/prince/graphics.cpp | 5 +++ engines/prince/graphics.h | 1 + engines/prince/prince.cpp | 71 ++++++++++++++----------------------- engines/prince/prince.h | 22 ++++++++++-- engines/prince/script.cpp | 6 ++-- 8 files changed, 61 insertions(+), 53 deletions(-) diff --git a/engines/plugins_table.h b/engines/plugins_table.h index de2a8069de1f..939c75658151 100644 --- a/engines/plugins_table.h +++ b/engines/plugins_table.h @@ -74,6 +74,9 @@ LINK_PLUGIN(PARALLACTION) #if PLUGIN_ENABLED_STATIC(PEGASUS) LINK_PLUGIN(PEGASUS) #endif +#if PLUGIN_ENABLED_STATIC(PRINCE) +LINK_PLUGIN(PRINCE) +#endif #if PLUGIN_ENABLED_STATIC(QUEEN) LINK_PLUGIN(QUEEN) #endif @@ -125,9 +128,6 @@ LINK_PLUGIN(TUCKER) #if PLUGIN_ENABLED_STATIC(WINTERMUTE) LINK_PLUGIN(WINTERMUTE) #endif -#if PLUGIN_ENABLED_STATIC(PRINCE) -LINK_PLUGIN(PRINCE) -#endif #if PLUGIN_ENABLED_STATIC(ZVISION) LINK_PLUGIN(ZVISION) #endif diff --git a/engines/prince/archive.h b/engines/prince/archive.h index 8e106693dcd7..94503b65ced3 100644 --- a/engines/prince/archive.h +++ b/engines/prince/archive.h @@ -28,7 +28,7 @@ // This is here just as remainder that archive support is missing namespace Price { -class Archive : public Common::Archive { +class PtcArchive : public Common::Archive { }; } diff --git a/engines/prince/cursor.cpp b/engines/prince/cursor.cpp index 9a9162fd278a..414e7ce39737 100644 --- a/engines/prince/cursor.cpp +++ b/engines/prince/cursor.cpp @@ -31,6 +31,7 @@ Cursor::Cursor() : _surface(NULL) { } Cursor::~Cursor() { + _surface->free(); delete _surface; _surface = NULL; } diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 29d3a331df87..025fa7000362 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -35,6 +35,11 @@ GraphicsMan::GraphicsMan(PrinceEngine *vm) _frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); } +GraphicsMan::~GraphicsMan() { + _frontScreen->free(); + delete _frontScreen; +} + void GraphicsMan::update() { if (_changed) { _vm->_system->copyRectToScreen((byte*)_frontScreen->getBasePtr(0,0), 640, 0, 0, 640, 480); diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index 3ef768a0735b..884aac2c84ac 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -34,6 +34,7 @@ class GraphicsMan { public: GraphicsMan(PrinceEngine *vm); + ~GraphicsMan(); void update(); diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 2b4390c75523..d184f84518bc 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -83,9 +83,6 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) gDebugLevel = 10; - _rnd = new Common::RandomSource("prince"); - _debugger = new Debugger(this); - _midiPlayer = new MusicPlayer(this); } @@ -101,6 +98,13 @@ PrinceEngine::~PrinceEngine() { delete _font; delete _roomBmp; delete _walizkaBmp; + delete _variaTxt; + delete[] _talkTxt; + delete _graph; + delete _mobList; + delete _objectList; + _midiPlayer->killMidi(); + delete _midiPlayer; } GUI::Debugger *PrinceEngine::getDebugger() { @@ -137,9 +141,14 @@ bool loadResource(T *resource, const char *resourceName) { return ret; } -Common::Error PrinceEngine::run() { +void PrinceEngine::init() { + _graph = new GraphicsMan(this); + _rnd = new Common::RandomSource("prince"); + _debugger = new Debugger(this); + _midiPlayer = new MusicPlayer(this); + const Common::FSNode gameDataDir(ConfMan.get("path")); debugEngine("Adding all path: %s", gameDataDir.getPath().c_str()); @@ -167,7 +176,7 @@ Common::Error PrinceEngine::run() { Common::SeekableReadStream *talkTxtStream = SearchMan.createReadStreamForMember("talktxt.dat"); if (!talkTxtStream) { error("Can't load talkTxtStream"); - return Common::kPathDoesNotExist; + return; } _talkTxtSize = talkTxtStream->size(); @@ -175,53 +184,27 @@ Common::Error PrinceEngine::run() { talkTxtStream->read(_talkTxt, _talkTxtSize); delete talkTxtStream; +} - MhwanhDecoder *logo = new MhwanhDecoder(); - loadResource(logo, "logo.raw"); - if (logo) - { - _graph->setPalette(logo->getPalette()); - _graph->draw(0, 0, logo->getSurface()); +void PrinceEngine::showLogo() { + MhwanhDecoder logo; + if (loadResource(&logo, "logo.raw")) { + _graph->setPalette(logo.getPalette()); + _graph->draw(0, 0, logo.getSurface()); _graph->update(); _system->delayMillis(700); } - delete logo; - - mainLoop(); - - return Common::kNoError; } -class MobList { -public: - bool loadFromStream(Common::SeekableReadStream &stream); - - Common::Array _mobList; -}; - -bool MobList::loadFromStream(Common::SeekableReadStream &stream) -{ - Mob mob; - while (mob.loadFromStream(stream)) - _mobList.push_back(mob); - - return true; -} +Common::Error PrinceEngine::run() { -class ObjectList { -public: - bool loadFromStream(Common::SeekableReadStream &stream); + init(); - Common::Array _objList; -}; + showLogo(); -bool ObjectList::loadFromStream(Common::SeekableReadStream &stream) -{ - Object obj; - while (obj.loadFromStream(stream)) - _objList.push_back(obj); + mainLoop(); - return true; + return Common::kNoError; } bool PrinceEngine::loadLocation(uint16 locationNr) { @@ -417,8 +400,8 @@ void PrinceEngine::hotspot() { Common::Point mousepos = _system->getEventManager()->getMousePos(); Common::Point mousePosCamera(mousepos.x + _cameraX, mousepos.y); - for (Common::Array::const_iterator it = _mobList->_mobList.begin() - ; it != _mobList->_mobList.end() ; ++it) { + for (Common::Array::const_iterator it = _mobList->_list.begin() + ; it != _mobList->_list.end() ; ++it) { if (it->_visible) continue; if (it->_rect.contains(mousePosCamera)) { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 4f2ddf827a68..85ed3cec0e4f 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -42,16 +42,32 @@ #include "video/flic_decoder.h" +#include "prince/mob.h" +#include "prince/object.h" + + namespace Prince { +template +struct ResourceList { + bool loadFromStream(Common::SeekableReadStream &stream) { + ResourceType resource; + while (resource.loadFromStream(stream)) + _list.push_back(resource); + return true; + } + Common::Array _list; +}; + +typedef ResourceList MobList; +typedef ResourceList ObjectList; + struct PrinceGameDescription; class PrinceEngine; class GraphicsMan; class Script; class Debugger; -class ObjectList; -class MobList; class MusicPlayer; class VariaTxt; class Cursor; @@ -124,6 +140,8 @@ class PrinceEngine : public Engine { void scrollCameraLeft(int16 delta); void drawScreen(); void showTexts(); + void init(); + void showLogo(); uint32 getTextWidth(const char *s); void debugEngine(const char *s, ...); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index a25e8241e1d6..94fbcba688fc 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -246,9 +246,9 @@ void Script::O_CHECKANIMFRAME() { } void Script::O_PUTBACKANIM() { - uint16 roomId = readScript16bits(); - uint16 slot = readScript16bits(); - uint32 animId = readScript32bits(); + uint16 roomId = readScriptValue(); + uint16 slot = readScriptValue(); + int32 animId = readScript32bits(); debugScript("O_PUTBACKANIM roomId %d, slot %d, animId %d", roomId, slot, animId); } From cdc1409dc77c57b083a60e6118c29dd9aad0be9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Sat, 9 Nov 2013 23:07:40 +0000 Subject: [PATCH 054/374] PRINCE: databank.ptc base archive with decompression --- engines/prince/archive.cpp | 122 ++++++++++++++++++++++++ engines/prince/archive.h | 33 ++++++- engines/prince/debugger.cpp | 5 +- engines/prince/debugger.h | 2 + engines/prince/decompress.cpp | 169 ++++++++++++++++++++++++++++++++++ engines/prince/decompress.h | 42 +++++++++ engines/prince/mob.h | 3 +- engines/prince/module.mk | 6 +- engines/prince/object.cpp | 2 + engines/prince/prince.cpp | 116 ++++++++++++++--------- engines/prince/prince.h | 19 ++-- engines/prince/sound.cpp | 2 + 12 files changed, 458 insertions(+), 63 deletions(-) create mode 100644 engines/prince/decompress.cpp create mode 100644 engines/prince/decompress.h diff --git a/engines/prince/archive.cpp b/engines/prince/archive.cpp index b474c9517276..2cf3126f0ce9 100644 --- a/engines/prince/archive.cpp +++ b/engines/prince/archive.cpp @@ -21,3 +21,125 @@ */ #include "prince/archive.h" +#include "prince/decompress.h" + +#include "common/stream.h" +#include "common/debug.h" +#include "common/memstream.h" + +namespace Prince { + +PtcArchive::PtcArchive() : _stream(NULL) { +} + +PtcArchive::~PtcArchive() { + close(); +} + +static void decrypt(byte *buffer, uint32 size) { + uint32 key = 0xDEADF00D; + while (size--) { + *buffer++ += key & 0xFF; + key ^= 0x2E84299A; + key += 0x424C4148; + key = ((key & 1) << 31) | (key >> 1); + } +} + +bool PtcArchive::open(const Common::String &filename) { + _stream = SearchMan.createReadStreamForMember(filename); + if (!_stream) + return false; + + uint32 magic = _stream->readUint32LE(); + uint32 fileTableOffset = _stream->readUint32LE() ^ 0x4D4F4B2D; // MOK- + uint32 fileTableSize = _stream->readUint32LE() ^ 0x534F4654; // SOFT + + debug("fileTableOffset : %08X", fileTableOffset); + debug("fileTableSize: %08X", fileTableSize); + + _stream->seek(fileTableOffset); + + byte *fileTable = new byte[fileTableSize]; + byte *fileTableEnd = fileTable + fileTableSize; + _stream->read(fileTable, fileTableSize); + decrypt(fileTable, fileTableSize); + + for (byte *fileItem = fileTable; fileItem < fileTableEnd; fileItem += 32) { + FileEntry item; + 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); + _items[name] = item; + } + + delete[] fileTable; + + return true; +} + +void PtcArchive::close() { + delete _stream; + _stream = NULL; + _items.clear(); +} + +bool PtcArchive::hasFile(const Common::String &name) const { + return _items.contains(name); +} + +int PtcArchive::listMembers(Common::ArchiveMemberList &list) const { + int matches = 0; + + for (FileMap::const_iterator it = _items.begin(); it != _items.end(); ++it) { + list.push_back(Common::ArchiveMemberList::value_type(new Common::GenericArchiveMember(it->_key, this))); + matches++; + } + + return matches; +} + +const Common::ArchiveMemberPtr PtcArchive::getMember(const Common::String &name) const { + if (!_items.contains(name)) { + Common::ArchiveMemberPtr(); + } + return Common::ArchiveMemberList::value_type(new Common::GenericArchiveMember(name, this)); +} + +Common::SeekableReadStream *PtcArchive::createReadStreamForMember(const Common::String &name) const { + if (!_items.contains(name)) { + return 0; + } + + const FileEntry &entryHeader = _items[name]; + + if (entryHeader._size < 4) + return 0; + + uint32 size = entryHeader._size; + + _stream->seek(entryHeader._offset); + + // This *HAS* to be malloc (not new[]) because MemoryReadStream uses free() to free the memory + byte* buffer = (byte *)malloc(size); + _stream->read(buffer, size); + + if (READ_BE_UINT32(buffer) == 0x4D41534D) { + Decompressor dec; + uint32 decompLen = READ_BE_UINT32(buffer + 14); + byte *decompData = (byte*)malloc(decompLen); + dec.decompress(buffer + 18, decompData, decompLen); + free(buffer); + size = decompLen; + buffer = decompData; + } + + debug("PtcArchive::createReadStreamForMember name %s", name.c_str()); + + return new Common::MemoryReadStream(buffer, size, DisposeAfterUse::YES); +} + +} + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/archive.h b/engines/prince/archive.h index 94503b65ced3..29d3d585603c 100644 --- a/engines/prince/archive.h +++ b/engines/prince/archive.h @@ -24,13 +24,40 @@ #define PRINCE_ARCHIVE_H #include "common/archive.h" +#include "common/hashmap.h" +#include "common/hash-str.h" -// This is here just as remainder that archive support is missing -namespace Price { +namespace Prince { class PtcArchive : public Common::Archive { +public: + PtcArchive(); + ~PtcArchive(); + + bool open(const Common::String &filename); + void close(); + bool isOpen() const { return _stream != 0; } + + // Common::Archive API implementation + bool hasFile(const Common::String &name) const; + int listMembers(Common::ArchiveMemberList &list) const; + const Common::ArchiveMemberPtr getMember(const Common::String &name) const; + Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const; + +private: + struct FileEntry { + uint32 _offset; + uint32 _size; + }; + + Common::SeekableReadStream *_stream; + + typedef Common::HashMap FileMap; + FileMap _items; }; -} +} // End of namespace Prince #endif + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/debugger.cpp b/engines/prince/debugger.cpp index 449ba5001ab7..e04fa432152f 100644 --- a/engines/prince/debugger.cpp +++ b/engines/prince/debugger.cpp @@ -25,7 +25,7 @@ namespace Prince { -Debugger::Debugger(PrinceEngine *vm) : GUI::Debugger(), _vm(vm) { +Debugger::Debugger(PrinceEngine *vm) : GUI::Debugger(), _vm(vm), _locationNr(0) { DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); DCmd_Register("level", WRAP_METHOD(Debugger, Cmd_DebugLevel)); DCmd_Register("setflag", WRAP_METHOD(Debugger, Cmd_SetFlag)); @@ -135,8 +135,7 @@ bool Debugger::Cmd_InitRoom(int argc, const char **argv) { return true; } - int flagNum = strToInt(argv[1]); - _vm->loadLocation(flagNum); + _locationNr = strToInt(argv[1]); return true; } diff --git a/engines/prince/debugger.h b/engines/prince/debugger.h index cbb609466853..edf89e81978d 100644 --- a/engines/prince/debugger.h +++ b/engines/prince/debugger.h @@ -35,6 +35,8 @@ class Debugger : public GUI::Debugger { Debugger(PrinceEngine *vm); virtual ~Debugger() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ + uint32 _locationNr; + private: bool Cmd_DebugLevel(int argc, const char **argv); bool Cmd_SetFlag(int argc, const char **argv); diff --git a/engines/prince/decompress.cpp b/engines/prince/decompress.cpp new file mode 100644 index 000000000000..8eca653e0a97 --- /dev/null +++ b/engines/prince/decompress.cpp @@ -0,0 +1,169 @@ +/* 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/decompress.h" + +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 +}; + +static const uint32 table2[] = { + 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 +}; + +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++; + } + } +} + +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; +} + +} // End of namespace Prince diff --git a/engines/prince/decompress.h b/engines/prince/decompress.h new file mode 100644 index 000000000000..19c7906eda4d --- /dev/null +++ b/engines/prince/decompress.h @@ -0,0 +1,42 @@ +/* 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_DECOMPRESS_H +#define PRINCE_DECOMPRESS_H + +#include "engines/util.h" + +namespace Prince { + +class Decompressor { +public: + void decompress(byte *source, byte *dest, uint32 destSize); +protected: + byte *_src, *_dst; + byte _bitBuffer; + int _bitsLeft; + int getBit(); +}; + +} // End of namespace Prince + +#endif diff --git a/engines/prince/mob.h b/engines/prince/mob.h index b8208246a19e..7db059e485b5 100644 --- a/engines/prince/mob.h +++ b/engines/prince/mob.h @@ -35,7 +35,8 @@ namespace Prince { class Mob { public: - Mob() {} + + Mob() : _name(""), _examText("") {} bool loadFromStream(Common::SeekableReadStream &stream); diff --git a/engines/prince/module.mk b/engines/prince/module.mk index 593c59dcffc3..48edcec9ddac 100644 --- a/engines/prince/module.mk +++ b/engines/prince/module.mk @@ -12,8 +12,10 @@ MODULE_OBJS = \ sound.o \ flags.o \ variatxt.o \ - cursor.o \ - prince.o + prince.o \ + archive.o \ + decompress.o \ + cursor.o # This module can be built as a plugin ifeq ($(ENABLE_PRINCE), DYNAMIC_PLUGIN) diff --git a/engines/prince/object.cpp b/engines/prince/object.cpp index 19dd7034a153..c4d843892607 100644 --- a/engines/prince/object.cpp +++ b/engines/prince/object.cpp @@ -36,7 +36,9 @@ Object::Object() : _surface(NULL), _x(0), _y(0), _z(0) { } Object::~Object() { + _surface->free(); delete _surface; + _surface = NULL; } void Object::loadSurface(Common::SeekableReadStream &stream) { diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index d184f84518bc..005a829444f6 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -55,6 +55,7 @@ #include "prince/font.h" #include "prince/mhwanh.h" #include "prince/cursor.h" +#include "prince/archive.h" namespace Prince { @@ -71,7 +72,7 @@ void PrinceEngine::debugEngine(const char *s, ...) { PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL), - _locationNr(0), _debugger(NULL), _objectList(NULL), _mobList(NULL), _midiPlayer(NULL), + _locationNr(0), _debugger(NULL), _midiPlayer(NULL), _cameraX(0), _newCameraX(0), _frameNr(0), _cursor1(NULL), _cursor2(NULL), _font(NULL), _walizkaBmp(NULL), _roomBmp(NULL), _voiceStream(NULL) { @@ -82,8 +83,6 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) DebugMan.enableDebugChannel("script"); gDebugLevel = 10; - - } PrinceEngine::~PrinceEngine() { @@ -101,10 +100,6 @@ PrinceEngine::~PrinceEngine() { delete _variaTxt; delete[] _talkTxt; delete _graph; - delete _mobList; - delete _objectList; - _midiPlayer->killMidi(); - delete _midiPlayer; } GUI::Debugger *PrinceEngine::getDebugger() { @@ -127,11 +122,12 @@ bool loadFromStream(Graphics::BitmapDecoder &image, Com } template -bool loadResource(T *resource, const char *resourceName) { +bool loadResource(T *resource, const char *resourceName, bool required = true) { Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); if (!stream) { - error("Can't load %s", resourceName); - return NULL; + if (required) + error("Can't load %s", resourceName); + return false; } bool ret = loadFromStream(*resource, *stream); @@ -141,44 +137,73 @@ bool loadResource(T *resource, const char *resourceName) { return ret; } -void PrinceEngine::init() { +template +bool loadResource(Common::Array &array, const char *resourceName, bool required = true) { + Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); + if (!stream) { + if (required) { + error("Can't load %s", resourceName); + return false; + } + } - _graph = new GraphicsMan(this); + typename Common::Array::value_type t; + while (t.loadFromStream(*stream)) + array.push_back(t); - _rnd = new Common::RandomSource("prince"); - _debugger = new Debugger(this); - _midiPlayer = new MusicPlayer(this); + delete stream; + return true; +} + +void PrinceEngine::init() { const Common::FSNode gameDataDir(ConfMan.get("path")); debugEngine("Adding all path: %s", gameDataDir.getPath().c_str()); + PtcArchive *all = new PtcArchive(); + if (!all->open("all/databank.ptc")) + error("Can't open all/databank.ptc"); + + PtcArchive *voices = new PtcArchive(); + if (!voices->open("data/voices/databank.ptc")) + error("Can't open data/voices/databank.ptc"); + + SearchMan.add("all", all); + SearchMan.add("data/voices", voices); + + _graph = new GraphicsMan(this); + + _rnd = new Common::RandomSource("prince"); + _debugger = new Debugger(this); + SearchMan.addSubDirectoryMatching(gameDataDir, "all", 0, 2); - SearchMan.addSubDirectoryMatching(gameDataDir, "data/voices/output", 0, 2); + SearchMan.addSubDirectoryMatching(gameDataDir, "data/voices", 0, 2); + + _midiPlayer = new MusicPlayer(this); _font = new Font(); - loadResource(_font, "font1.raw"); + loadResource(_font, "all/font1.raw"); _walizkaBmp = new MhwanhDecoder(); - loadResource(_walizkaBmp, "walizka"); + loadResource(_walizkaBmp, "all/walizka"); _script = new Script(this); - loadResource(_script, "skrypt.dat"); + loadResource(_script, "all/skrypt.dat"); _variaTxt = new VariaTxt(); - loadResource(_variaTxt, "variatxt.dat"); + loadResource(_variaTxt, "all/variatxt.dat"); _cursor1 = new Cursor(); - loadResource(_cursor1, "mouse1.cur"); + loadResource(_cursor1, "all/mouse1.cur"); _cursor2 = new Cursor(); - loadResource(_cursor2, "mouse2.cur"); + loadResource(_cursor2, "all/mouse2.cur"); - Common::SeekableReadStream *talkTxtStream = SearchMan.createReadStreamForMember("talktxt.dat"); + Common::SeekableReadStream *talkTxtStream = SearchMan.createReadStreamForMember("all/talktxt.dat"); if (!talkTxtStream) { error("Can't load talkTxtStream"); return; } - _talkTxtSize = talkTxtStream->size(); _talkTxt = new byte[_talkTxtSize]; talkTxtStream->read(_talkTxt, _talkTxtSize); @@ -202,12 +227,15 @@ Common::Error PrinceEngine::run() { showLogo(); +// return Common::kNoError; + mainLoop(); return Common::kNoError; } bool PrinceEngine::loadLocation(uint16 locationNr) { + _debugger->_locationNr = locationNr; debugEngine("PrinceEngine::loadLocation %d", locationNr); const Common::FSNode gameDataDir(ConfMan.get("path")); SearchMan.remove(Common::String::format("%02d", _locationNr)); @@ -215,7 +243,12 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { const Common::String locationNrStr = Common::String::format("%02d", _locationNr); debugEngine("loadLocation %s", locationNrStr.c_str()); - SearchMan.addSubDirectoryMatching(gameDataDir, locationNrStr, 0, 2); + + PtcArchive *locationArchive = new PtcArchive(); + if (!locationArchive->open(locationNrStr + "/databank.ptc")) + error("Can't open location %s", locationNrStr.c_str()); + + SearchMan.add(locationNrStr, locationArchive); delete _roomBmp; // load location background @@ -225,14 +258,9 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _sceneWidth = _roomBmp->getSurface()->w; } - delete _mobList; - _mobList = new MobList(); + _mobList.clear(); loadResource(_mobList, "mob.lst"); - delete _objectList; - _objectList = new ObjectList(); - loadResource(_objectList, "obj.lst"); - const char *musName = MusicPlayer::_musTable[MusicPlayer::_musRoomTable[locationNr]]; _midiPlayer->loadMidi(musName); @@ -395,19 +423,18 @@ void PrinceEngine::keyHandler(Common::Event event) { } void PrinceEngine::hotspot() { - if (!_mobList) - return; Common::Point mousepos = _system->getEventManager()->getMousePos(); Common::Point mousePosCamera(mousepos.x + _cameraX, mousepos.y); - for (Common::Array::const_iterator it = _mobList->_list.begin() - ; it != _mobList->_list.end() ; ++it) { - if (it->_visible) + for (Common::Array::const_iterator it = _mobList.begin() + ; it != _mobList.end() ; ++it) { + const Mob& mob = *it; + if (mob._visible) continue; - if (it->_rect.contains(mousePosCamera)) { + if (mob._rect.contains(mousePosCamera)) { uint16 textW = 0; - for (uint16 i = 0; i < it->_name.size(); ++i) - textW += _font->getCharWidth(it->_name[i]); + for (uint16 i = 0; i < mob._name.size(); ++i) + textW += _font->getCharWidth(mob._name[i]); uint16 x = mousepos.x - textW/2; if (x > _graph->_frontScreen->w) @@ -418,7 +445,7 @@ void PrinceEngine::hotspot() { _font->drawString( _graph->_frontScreen, - it->_name, + mob._name, x, mousepos.y - _font->getFontHeight(), _graph->_frontScreen->w, @@ -500,6 +527,9 @@ void PrinceEngine::drawScreen() { void PrinceEngine::mainLoop() { + loadLocation(2); + changeCursor(1); + while (!shouldQuit()) { uint32 currentTime = _system->getMillis(); @@ -530,7 +560,7 @@ void PrinceEngine::mainLoop() { if (shouldQuit()) return; - _script->step(); + //_script->step(); drawScreen(); // Calculate the frame delay based off a desired frame time @@ -541,6 +571,10 @@ void PrinceEngine::mainLoop() { _cameraX = _newCameraX; ++_frameNr; + + if (_debugger->_locationNr != _locationNr) { + loadLocation(_debugger->_locationNr); + } } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 85ed3cec0e4f..2df8e6682537 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -47,21 +47,14 @@ namespace Prince { - -template -struct ResourceList { +#if 0 bool loadFromStream(Common::SeekableReadStream &stream) { - ResourceType resource; - while (resource.loadFromStream(stream)) + ResourceType *resource = new ResourceType(); + while (resource->loadFromStream(stream)) _list.push_back(resource); return true; } - Common::Array _list; -}; - -typedef ResourceList MobList; -typedef ResourceList ObjectList; - +#endif struct PrinceGameDescription; class PrinceEngine; @@ -157,12 +150,12 @@ class PrinceEngine : public Engine { GraphicsMan *_graph; Script *_script; Font *_font; - ObjectList *_objectList; - MobList *_mobList; MusicPlayer *_midiPlayer; Audio::SoundHandle _soundHandle; Common::SeekableReadStream *_voiceStream; + Common::Array _mobList; + Common::Array _objectList; uint16 _cameraX; uint16 _newCameraX; diff --git a/engines/prince/sound.cpp b/engines/prince/sound.cpp index 40f182e63039..fcdca8a0d120 100644 --- a/engines/prince/sound.cpp +++ b/engines/prince/sound.cpp @@ -168,6 +168,8 @@ void MusicPlayer::loadMidi(const char * name) { _data = (byte *)malloc(_dataSize); stream->read(_data, _dataSize); + delete stream; + // Start playing the music sndMidiStart(); } From bd59732ce20df7d62b74b9a88bf510e4e2305c54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Sun, 10 Nov 2013 22:49:34 +0000 Subject: [PATCH 055/374] PRINCE: code indentation cleanup --- engines/prince/archive.cpp | 42 +++++++++++++++++------------------ engines/prince/decompress.cpp | 2 ++ engines/prince/decompress.h | 2 ++ engines/prince/object.h | 2 +- engines/prince/prince.cpp | 17 +++++++++++--- engines/prince/prince.h | 9 +------- 6 files changed, 41 insertions(+), 33 deletions(-) diff --git a/engines/prince/archive.cpp b/engines/prince/archive.cpp index 2cf3126f0ce9..a6927baf0c15 100644 --- a/engines/prince/archive.cpp +++ b/engines/prince/archive.cpp @@ -37,13 +37,13 @@ PtcArchive::~PtcArchive() { } static void decrypt(byte *buffer, uint32 size) { - uint32 key = 0xDEADF00D; - while (size--) { - *buffer++ += key & 0xFF; - key ^= 0x2E84299A; - key += 0x424C4148; - key = ((key & 1) << 31) | (key >> 1); - } + uint32 key = 0xDEADF00D; + while (size--) { + *buffer++ += key & 0xFF; + key ^= 0x2E84299A; + key += 0x424C4148; + key = ((key & 1) << 31) | (key >> 1); + } } bool PtcArchive::open(const Common::String &filename) { @@ -55,26 +55,26 @@ 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("fileTableOffset : %08X", fileTableOffset); + debug("fileTableSize: %08X", fileTableSize); _stream->seek(fileTableOffset); - byte *fileTable = new byte[fileTableSize]; - byte *fileTableEnd = fileTable + fileTableSize; - _stream->read(fileTable, fileTableSize); - decrypt(fileTable, fileTableSize); - - for (byte *fileItem = fileTable; fileItem < fileTableEnd; fileItem += 32) { - FileEntry item; + byte *fileTable = new byte[fileTableSize]; + byte *fileTableEnd = fileTable + fileTableSize; + _stream->read(fileTable, fileTableSize); + decrypt(fileTable, fileTableSize); + + for (byte *fileItem = fileTable; fileItem < fileTableEnd; fileItem += 32) { + FileEntry item; 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); + 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); _items[name] = item; } - - delete[] fileTable; + + delete[] fileTable; return true; } diff --git a/engines/prince/decompress.cpp b/engines/prince/decompress.cpp index 8eca653e0a97..ed52aaf6f7de 100644 --- a/engines/prince/decompress.cpp +++ b/engines/prince/decompress.cpp @@ -20,6 +20,8 @@ * */ +// John_Doe's implementation + #include "prince/decompress.h" namespace Prince { diff --git a/engines/prince/decompress.h b/engines/prince/decompress.h index 19c7906eda4d..88b19c6ae325 100644 --- a/engines/prince/decompress.h +++ b/engines/prince/decompress.h @@ -20,6 +20,8 @@ * */ +// John_Doe's implementation + #ifndef PRINCE_DECOMPRESS_H #define PRINCE_DECOMPRESS_H diff --git a/engines/prince/object.h b/engines/prince/object.h index 052b88dad6be..aa55bf06a604 100644 --- a/engines/prince/object.h +++ b/engines/prince/object.h @@ -34,7 +34,7 @@ class Object { ~Object(); bool loadFromStream(Common::SeekableReadStream &stream); - Graphics::Surface *getSurface() const { return _surface; } + const Graphics::Surface *getSurface() const { return _surface; } private: void loadSurface(Common::SeekableReadStream &stream); diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 005a829444f6..53c8684a6d89 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -143,8 +143,8 @@ bool loadResource(Common::Array &array, const char *resourceName, bool requir if (!stream) { if (required) { error("Can't load %s", resourceName); - return false; } + return false; } typename Common::Array::value_type t; @@ -235,6 +235,8 @@ Common::Error PrinceEngine::run() { } bool PrinceEngine::loadLocation(uint16 locationNr) { + _cameraX = 0; + _newCameraX = 0; _debugger->_locationNr = locationNr; debugEngine("PrinceEngine::loadLocation %d", locationNr); const Common::FSNode gameDataDir(ConfMan.get("path")); @@ -259,7 +261,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { } _mobList.clear(); - loadResource(_mobList, "mob.lst"); + loadResource(_mobList, "mob.lst", false); const char *musName = MusicPlayer::_musTable[MusicPlayer::_musRoomTable[locationNr]]; _midiPlayer->loadMidi(musName); @@ -331,6 +333,11 @@ void PrinceEngine::stopSample(uint16 sampleId) { bool PrinceEngine::loadVoice(uint32 slot, const Common::String &streamName) { debugEngine("Loading wav %s slot %d", streamName.c_str(), slot); + if (slot > MAXTEXTS) { + error("Text slot bigger than MAXTEXTS %d", MAXTEXTS); + return false; + } + _voiceStream = SearchMan.createReadStreamForMember(streamName); if (!_voiceStream) { error("Can't open %s", streamName.c_str()); @@ -443,11 +450,15 @@ void PrinceEngine::hotspot() { if (x + textW > _graph->_frontScreen->w) x = _graph->_frontScreen->w - textW; + uint16 y = mousepos.y - _font->getFontHeight(); + if (y > _graph->_frontScreen->h) + y = _font->getFontHeight() - 2; + _font->drawString( _graph->_frontScreen, mob._name, x, - mousepos.y - _font->getFontHeight(), + y, _graph->_frontScreen->w, 216 ); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 2df8e6682537..0da0bcfe719e 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -47,14 +47,7 @@ namespace Prince { -#if 0 - bool loadFromStream(Common::SeekableReadStream &stream) { - ResourceType *resource = new ResourceType(); - while (resource->loadFromStream(stream)) - _list.push_back(resource); - return true; - } -#endif + struct PrinceGameDescription; class PrinceEngine; From 87e2229df264c36dd2809eb85544b9377e0ddfd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Mon, 11 Nov 2013 12:00:19 +0000 Subject: [PATCH 056/374] PRINCE: initroom from debugger --- engines/prince/cursor.cpp | 3 +-- engines/prince/debugger.cpp | 4 ++-- engines/prince/debugger.h | 3 ++- engines/prince/prince.cpp | 10 ++++++---- engines/prince/prince.h | 1 + 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/engines/prince/cursor.cpp b/engines/prince/cursor.cpp index 414e7ce39737..865ae99cadd3 100644 --- a/engines/prince/cursor.cpp +++ b/engines/prince/cursor.cpp @@ -44,9 +44,8 @@ bool Cursor::loadFromStream(Common::SeekableReadStream &stream) { _surface = new Graphics::Surface(); _surface->create(w, h, Graphics::PixelFormat::createFormatCLUT8()); - for (int ih = 0; ih < h; ++ih) { + for (int ih = 0; ih < h; ++ih) stream.read(_surface->getBasePtr(0, ih), w); - } return true; } diff --git a/engines/prince/debugger.cpp b/engines/prince/debugger.cpp index e04fa432152f..d9264cb02dba 100644 --- a/engines/prince/debugger.cpp +++ b/engines/prince/debugger.cpp @@ -146,8 +146,8 @@ bool Debugger::Cmd_ChangeCursor(int argc, const char **argv) { return true; } - int flagNum = strToInt(argv[1]); - _vm->changeCursor(flagNum); + _cursorNr = strToInt(argv[1]); + return true; } diff --git a/engines/prince/debugger.h b/engines/prince/debugger.h index edf89e81978d..f3608af81d0b 100644 --- a/engines/prince/debugger.h +++ b/engines/prince/debugger.h @@ -35,7 +35,8 @@ class Debugger : public GUI::Debugger { Debugger(PrinceEngine *vm); virtual ~Debugger() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ - uint32 _locationNr; + uint8 _locationNr; + uint8 _cursorNr; private: bool Cmd_DebugLevel(int argc, const char **argv); diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 53c8684a6d89..fdd9219b13d4 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -269,8 +269,9 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { return true; } -void PrinceEngine::changeCursor(uint16 curId) -{ +void PrinceEngine::changeCursor(uint16 curId) { + _debugger->_cursorNr = curId; + Graphics::Surface *curSurface = NULL; uint16 hotspotX = 0; @@ -583,9 +584,10 @@ void PrinceEngine::mainLoop() { _cameraX = _newCameraX; ++_frameNr; - if (_debugger->_locationNr != _locationNr) { + if (_debugger->_locationNr != _locationNr) loadLocation(_debugger->_locationNr); - } + if (_debugger->_cursorNr != _cursorNr) + changeCursor(_debugger->_cursorNr); } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 0da0bcfe719e..25fac64435bb 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -133,6 +133,7 @@ class PrinceEngine : public Engine { void debugEngine(const char *s, ...); uint16 _locationNr; + uint8 _cursorNr; Common::RandomSource *_rnd; Graphics::BitmapDecoder *_roomBmp; From 7b1fed7331df8e4f4071445626d1ca67a5e7ff7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Thu, 14 Nov 2013 14:44:24 +0000 Subject: [PATCH 057/374] PRINCE: get/set mob data added --- engines/prince/common.h | 47 +++++++++++++++++++++++++++++++++++++++ engines/prince/mob.cpp | 38 ++++++++++++++++++++++++++++++- engines/prince/mob.h | 32 ++++++++++++++++++++++++++ engines/prince/object.cpp | 8 ++++--- engines/prince/prince.cpp | 31 +++++++++++++++++++++----- engines/prince/prince.h | 2 +- engines/prince/script.cpp | 14 ++++++------ 7 files changed, 154 insertions(+), 18 deletions(-) create mode 100644 engines/prince/common.h diff --git a/engines/prince/common.h b/engines/prince/common.h new file mode 100644 index 000000000000..6dc1bad6a802 --- /dev/null +++ b/engines/prince/common.h @@ -0,0 +1,47 @@ +/* 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_COMMON_H +#define PRINCE_COMMON_H + +namespace Prince { + +enum Direction { + LD = 0, + L = 1, + LG = 2, + PD = 3, + P = 4, + PG = 5, + GL = 6, + G = 7, + GP = 8, + DL = 9, + D = 10, + DP = 11 +}; + +} + +#endif + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/mob.cpp b/engines/prince/mob.cpp index 3df7235d2d84..c4bb6073470d 100644 --- a/engines/prince/mob.cpp +++ b/engines/prince/mob.cpp @@ -41,7 +41,16 @@ bool Mob::loadFromStream(Common::SeekableReadStream &stream) { _rect.right = stream.readUint16LE(); _rect.bottom = stream.readUint16LE(); - stream.skip(6 * sizeof(uint16)); + _mask = stream.readUint16LE(); + + _examPosition.x = stream.readUint16LE(); + _examPosition.y = stream.readUint16LE(); + _examDirection = (Direction)stream.readUint16LE(); + + _usePosition.x = stream.readByte(); + _usePosition.y = stream.readByte(); + _useDirection = (Direction)stream.readUint16LE(); + uint32 nameOffset = stream.readUint32LE(); uint32 examTextOffset = stream.readUint32LE(); @@ -60,6 +69,33 @@ bool Mob::loadFromStream(Common::SeekableReadStream &stream) { return true; } +void Mob::setData(AttrId dataId, uint16 value) { + switch (dataId) { + case ExamDir: + _examDirection = (Direction)value; + break; + case ExamX: + _examPosition.x = value; + break; + case ExamY: + _examPosition.y = value; + break; + default: + assert(false); + } +} + +uint16 Mob::getData(AttrId dataId) { + switch (dataId) { + case Visible: return _visible; + case ExamDir: return _examDirection; + case ExamX: return _examPosition.x; + case ExamY: return _examPosition.y; + default: + assert(false); + } +} + } /* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/mob.h b/engines/prince/mob.h index 7db059e485b5..36630eb6eb89 100644 --- a/engines/prince/mob.h +++ b/engines/prince/mob.h @@ -27,6 +27,8 @@ #include "common/rect.h" #include "common/str.h" +#include "prince/common.h" + namespace Common { class SeekableReadStream; } @@ -40,9 +42,39 @@ class Mob { bool loadFromStream(Common::SeekableReadStream &stream); + // Used instead of offset in setData and getData + enum AttrId { + Visible = 0, + Type = 2, + X1 = 4, + Y1 = 6, + X2 = 8, + Y2 = 10, + Mask = 12, + ExamX = 14, + ExamY = 16, + ExamDir = 18, + UseX = 20, + UseY = 21, + UseDir = 22, + Name = 24, + ExamText = 28 + }; + + void setData(AttrId dataId, uint16 value); + uint16 getData(AttrId dataId); + bool _visible; uint16 _type; + uint16 _mask; Common::Rect _rect; + + Common::Point _examPosition; + Direction _examDirection; + + Common::Point _usePosition; + Direction _useDirection; + Common::String _name; Common::String _examText; }; diff --git a/engines/prince/object.cpp b/engines/prince/object.cpp index c4d843892607..4148cdf854a5 100644 --- a/engines/prince/object.cpp +++ b/engines/prince/object.cpp @@ -36,9 +36,11 @@ Object::Object() : _surface(NULL), _x(0), _y(0), _z(0) { } Object::~Object() { - _surface->free(); - delete _surface; - _surface = NULL; + if (_surface) { + _surface->free(); + delete _surface; + _surface = NULL; + } } void Object::loadSurface(Common::SeekableReadStream &stream) { diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index fdd9219b13d4..4a8fa9ae714d 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -74,7 +74,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL), _locationNr(0), _debugger(NULL), _midiPlayer(NULL), _cameraX(0), _newCameraX(0), _frameNr(0), _cursor1(NULL), _cursor2(NULL), _font(NULL), - _walizkaBmp(NULL), _roomBmp(NULL), _voiceStream(NULL) { + _walizkaBmp(NULL), _roomBmp(NULL), _voiceStream(NULL), _cursorNr(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -141,19 +141,36 @@ template bool loadResource(Common::Array &array, const char *resourceName, bool required = true) { Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); if (!stream) { - if (required) { + if (required) error("Can't load %s", resourceName); - } return false; } - typename Common::Array::value_type t; + T t; while (t.loadFromStream(*stream)) array.push_back(t); delete stream; return true; } +#if 0 +template +bool loadResource(T * array[], const char *resourceName, bool required = true) { + Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); + if (!stream) { + if (required) + error("Can't load %s", resourceName); + return false; + } + + T* t = new T(); + while (t->loadFromStream(*stream)) + array.push_back(t); + + delete stream; + return true; +} +#endif void PrinceEngine::init() { @@ -539,8 +556,8 @@ void PrinceEngine::drawScreen() { void PrinceEngine::mainLoop() { - loadLocation(2); - changeCursor(1); + loadLocation(4); + changeCursor(0); while (!shouldQuit()) { uint32 currentTime = _system->getMillis(); @@ -572,6 +589,8 @@ void PrinceEngine::mainLoop() { if (shouldQuit()) return; + // TODO: Update all structures, animations, naks, heros etc. + //_script->step(); drawScreen(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 25fac64435bb..374048f28508 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -149,7 +149,7 @@ class PrinceEngine : public Engine { Audio::SoundHandle _soundHandle; Common::SeekableReadStream *_voiceStream; Common::Array _mobList; - Common::Array _objectList; + Common::Array _objList; uint16 _cameraX; uint16 _newCameraX; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 94fbcba688fc..7ad2df2a56e9 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -492,9 +492,9 @@ void Script::O_ORFLAG() { } void Script::O_SETMOBDATA() { - uint16 mobId = readScript16bits(); - uint16 mobOffset = readScript16bits(); - uint16 value = readScript16bits(); + uint16 mobId = readScriptValue(); + uint16 mobOffset = readScriptValue(); + uint16 value = readScriptValue(); debugScript("O_SETMOBDATA mobId %d, mobOffset %d, value %d", mobId, mobOffset, value); } @@ -537,10 +537,10 @@ void Script::O_WALKHERO() { } void Script::O_SETHERO() { - uint16 hero = readScript16bits(); - uint16 x = readScript16bits(); - uint16 y = readScript16bits(); - uint16 dir = readScript16bits(); + uint16 hero = readScriptValue(); + uint16 x = readScriptValue(); + uint16 y = readScriptValue(); + uint16 dir = readScriptValue(); debugScript("O_SETHERO hero %d, x %d, y %d, dir %d", hero, x, y, dir); } From 3d1d1884324a240b73fea6de3b5df6f7310eeb53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Mon, 18 Nov 2013 16:19:21 +0000 Subject: [PATCH 058/374] PRINCE: script updated to read value when necessary --- engines/prince/animation.cpp | 0 engines/prince/animation.h | 39 ++++ engines/prince/archive.cpp | 8 +- engines/prince/cursor.h | 2 +- engines/prince/mhwanh.cpp | 3 +- engines/prince/mhwanh.h | 4 +- engines/prince/prince.cpp | 55 +++-- engines/prince/script.cpp | 392 ++++++++++++++++++++--------------- engines/prince/script.h | 2 + 9 files changed, 317 insertions(+), 188 deletions(-) create mode 100644 engines/prince/animation.cpp create mode 100644 engines/prince/animation.h diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/engines/prince/animation.h b/engines/prince/animation.h new file mode 100644 index 000000000000..e6a76d33d24d --- /dev/null +++ b/engines/prince/animation.h @@ -0,0 +1,39 @@ +/* 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_ANIMATION_H +#define PRINCE_ANIMATION_H + +namespace Prince { + +class Animation { + + bool loadFromStream(Common::SeekableReadStream &stream); + + const Graphics::Surface *getSurface(uint16 frameIndex) const; +}; + +} + +#endif + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/archive.cpp b/engines/prince/archive.cpp index a6927baf0c15..0b1367f96634 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("fileTableOffset : %08X", fileTableOffset); + //debug("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("%12s %8X %d", name.c_str(), item._offset, item._size); _items[name] = item; } @@ -135,7 +135,7 @@ Common::SeekableReadStream *PtcArchive::createReadStreamForMember(const Common:: buffer = decompData; } - debug("PtcArchive::createReadStreamForMember name %s", name.c_str()); + //debug("PtcArchive::createReadStreamForMember name %s", name.c_str()); return new Common::MemoryReadStream(buffer, size, DisposeAfterUse::YES); } diff --git a/engines/prince/cursor.h b/engines/prince/cursor.h index 05c7da9f3337..70516519e66e 100644 --- a/engines/prince/cursor.h +++ b/engines/prince/cursor.h @@ -37,7 +37,7 @@ class Cursor { ~Cursor(); bool loadFromStream(Common::SeekableReadStream &stream); - Graphics::Surface *getSurface() const { return _surface; } + const Graphics::Surface *getSurface() const { return _surface; } private: Graphics::Surface *_surface; diff --git a/engines/prince/mhwanh.cpp b/engines/prince/mhwanh.cpp index 92a6a900f517..3bd034e4a761 100644 --- a/engines/prince/mhwanh.cpp +++ b/engines/prince/mhwanh.cpp @@ -39,7 +39,8 @@ MhwanhDecoder::~MhwanhDecoder() { void MhwanhDecoder::destroy() { if (_surface) { _surface->free(); - delete _surface; _surface = 0; + delete _surface; + _surface = 0; } delete [] _palette; _palette = 0; diff --git a/engines/prince/mhwanh.h b/engines/prince/mhwanh.h index 2b70ae525b13..b11ecd08e638 100644 --- a/engines/prince/mhwanh.h +++ b/engines/prince/mhwanh.h @@ -36,8 +36,8 @@ class MhwanhDecoder : public Graphics::ImageDecoder { // ImageDecoder API void destroy(); virtual bool loadStream(Common::SeekableReadStream &stream); - virtual Graphics::Surface *getSurface() const { return _surface; } - const byte *getPalette() const { return _palette; } + virtual const Graphics::Surface *getSurface() const { return _surface; } + virtual const byte *getPalette() const { return _palette; } uint16 getPaletteCount() const { return _paletteColorCount; } private: diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 4a8fa9ae714d..9f4ae19af3e5 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -100,6 +100,11 @@ PrinceEngine::~PrinceEngine() { delete _variaTxt; delete[] _talkTxt; delete _graph; + + for (uint32 i = 0; i < _objList.size(); ++i) { + delete _objList[i]; + } + _objList.clear(); } GUI::Debugger *PrinceEngine::getDebugger() { @@ -153,9 +158,9 @@ bool loadResource(Common::Array &array, const char *resourceName, bool requir delete stream; return true; } -#if 0 + template -bool loadResource(T * array[], const char *resourceName, bool required = true) { +bool loadResource(Common::Array &array, const char *resourceName, bool required = true) { Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); if (!stream) { if (required) @@ -163,14 +168,19 @@ bool loadResource(T * array[], const char *resourceName, bool required = true) { return false; } - T* t = new T(); - while (t->loadFromStream(*stream)) + // FIXME: This is stupid. Maybe loadFromStream should be helper method that returns initiailzed object + while (true) { + T* t = new T(); + if (!t->loadFromStream(*stream)) { + delete t; + break; + } array.push_back(t); + } delete stream; return true; } -#endif void PrinceEngine::init() { @@ -201,6 +211,7 @@ void PrinceEngine::init() { _font = new Font(); loadResource(_font, "all/font1.raw"); + _walizkaBmp = new MhwanhDecoder(); loadResource(_walizkaBmp, "all/walizka"); @@ -226,6 +237,8 @@ void PrinceEngine::init() { talkTxtStream->read(_talkTxt, _talkTxtSize); delete talkTxtStream; + + _roomBmp = new Graphics::BitmapDecoder(); } void PrinceEngine::showLogo() { @@ -244,21 +257,25 @@ Common::Error PrinceEngine::run() { showLogo(); -// return Common::kNoError; - mainLoop(); return Common::kNoError; } bool PrinceEngine::loadLocation(uint16 locationNr) { - _cameraX = 0; - _newCameraX = 0; - _debugger->_locationNr = locationNr; debugEngine("PrinceEngine::loadLocation %d", locationNr); const Common::FSNode gameDataDir(ConfMan.get("path")); SearchMan.remove(Common::String::format("%02d", _locationNr)); + _locationNr = locationNr; + _debugger->_locationNr = locationNr; + _cameraX = 0; + _newCameraX = 0; + + _script->setFlagValue(Flags::CURRROOM, _locationNr); + _script->stopBg(); + + changeCursor(0); const Common::String locationNrStr = Common::String::format("%02d", _locationNr); debugEngine("loadLocation %s", locationNrStr.c_str()); @@ -269,9 +286,10 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { SearchMan.add(locationNrStr, locationArchive); - delete _roomBmp; - // load location background - _roomBmp = new Graphics::BitmapDecoder(); + const char *musName = MusicPlayer::_musTable[MusicPlayer::_musRoomTable[locationNr]]; + _midiPlayer->loadMidi(musName); + + // load location background, replace old one loadResource(_roomBmp, "room"); if (_roomBmp->getSurface()) { _sceneWidth = _roomBmp->getSurface()->w; @@ -280,8 +298,11 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mobList.clear(); loadResource(_mobList, "mob.lst", false); - const char *musName = MusicPlayer::_musTable[MusicPlayer::_musRoomTable[locationNr]]; - _midiPlayer->loadMidi(musName); + for (uint32 i = 0; i < _objList.size(); ++i) { + delete _objList[i]; + } + _objList.clear(); + loadResource(_objList, "obj.lst", false); return true; } @@ -289,7 +310,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { void PrinceEngine::changeCursor(uint16 curId) { _debugger->_cursorNr = curId; - Graphics::Surface *curSurface = NULL; + const Graphics::Surface *curSurface = NULL; uint16 hotspotX = 0; uint16 hotspotY = 0; @@ -591,7 +612,7 @@ void PrinceEngine::mainLoop() { // TODO: Update all structures, animations, naks, heros etc. - //_script->step(); + _script->step(); drawScreen(); // Calculate the frame delay based off a desired frame time diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 7ad2df2a56e9..07821f27a872 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -98,30 +98,24 @@ void Script::step() { } uint32 Script::step(uint32 opcodePC) { - _currentInstruction = opcodePC; - while (!_opcodeNF) - { + + while (!_opcodeNF) { _lastInstruction = _currentInstruction; - // Prepare the base debug string - Common::String dstr = Common::String::format("@0x%04X: ", _currentInstruction); // Get the current opcode _lastOpcode = readScript16bits(); - dstr += Common::String::format("op %02d: ", _lastOpcode); - - if (_lastOpcode > NUM_OPCODES) - error("Trying to execute unknown opcode %s", dstr.c_str()); - - - //debugScript(""); + if (_lastOpcode > NUM_OPCODES) + error( + "Trying to execute unknown opcode @0x%04X: %02d", + _currentInstruction, + _lastOpcode); // Execute the current opcode OpcodeFunc op = _opcodes[_lastOpcode]; (this->*op)(); if (_opcodeNF) { - _opcodeNF = 0; break; } @@ -178,68 +172,68 @@ void Script::O_SETUPPALETTE() { } void Script::O_INITROOM() { - uint16 roomId = readScript16bits(); + uint16 roomId = readScriptValue(); debugScript("O_INITROOM %d", roomId); _vm->loadLocation(roomId); _opcodeNF = 1; } void Script::O_SETSAMPLE() { - uint16 sampleId = readScript16bits(); + uint16 sampleId = readScriptValue(); int32 sampleNameOffset = readScript32bits(); - const char * sampleName = (const char *)_code + _currentInstruction + sampleNameOffset - 4; + const char * sampleName = (const char *)&_code[_currentInstruction + sampleNameOffset - 4]; debugScript("O_SETSAMPLE %d %s", sampleId, sampleName); } void Script::O_FREESAMPLE() { - uint16 sample = readScript16bits(); + uint16 sample = readScriptValue(); debugScript("O_FREESAMPLE %d", sample); } void Script::O_PLAYSAMPLE() { - uint16 sampleId = readScript16bits(); + uint16 sampleId = readScriptValue(); uint16 loopType = readScript16bits(); debugScript("O_PLAYSAMPLE sampleId %d loopType %d", sampleId, loopType); _vm->playSample(sampleId, loopType); } void Script::O_PUTOBJECT() { - uint16 roomId = readScript16bits(); - uint16 slot = readScript16bits(); - uint16 objectId = readScript16bits(); + uint16 roomId = readScriptValue(); + uint16 slot = readScriptValue(); + uint16 objectId = readScriptValue(); debugScript("O_PUTOBJECT roomId %d, slot %d, objectId %d", roomId, slot, objectId); } void Script::O_REMOBJECT() { - uint16 roomId = readScript16bits(); - uint16 objectId = readScript16bits(); + uint16 roomId = readScriptValue(); + uint16 objectId = readScriptValue(); debugScript("O_REMOBJECT roomId %d objectId %d", roomId, objectId); } void Script::O_SHOWANIM() { - uint16 slot = readScript16bits(); - uint16 animId = readScript16bits(); + uint16 slot = readScriptValue(); + uint16 animId = readScriptValue(); debugScript("O_SHOWANIM slot %d, animId %d", slot, animId); } void Script::O_CHECKANIMEND() { - uint16 slot = readScript16bits(); - uint16 frameId = readScript16bits(); + uint16 slot = readScriptValue(); + uint16 frameId = readScriptValue(); debugScript("O_CHECKANIMEND slot %d, frameId %d", slot, frameId); _opcodeNF = 1; } void Script::O_FREEANIM() { - uint16 slot = readScript16bits(); + uint16 slot = readScriptValue(); debugScript("O_FREEANIM slot %d", slot); } void Script::O_CHECKANIMFRAME() { - uint16 slot = readScript16bits(); - uint16 frameId = readScript16bits(); + uint16 slot = readScriptValue(); + uint16 frameId = readScriptValue(); debugScript("O_CHECKANIMFRAME slot %d, frameId %d", slot, frameId); _opcodeNF = 1; @@ -253,15 +247,15 @@ void Script::O_PUTBACKANIM() { } void Script::O_REMBACKANIM() { - uint16 roomId = readScript16bits(); - uint16 slot = readScript16bits(); + uint16 roomId = readScriptValue(); + uint16 slot = readScriptValue(); debugScript("O_REMBACKANIM roomId %d, slot %d", roomId, slot); } void Script::O_CHECKBACKANIMFRAME() { - uint16 slotId = readScript16bits(); - uint16 frameId = readScript16bits(); + uint16 slotId = readScriptValue(); + uint16 frameId = readScriptValue(); debugScript("O_CHECKBACKANIMFRAME slotId %d, frameId %d", slotId, frameId); _opcodeNF = 1; @@ -282,7 +276,7 @@ void Script::O_STOPMUSIC() { } void Script::O__WAIT() { - uint16 pause = readScript16bits(); + uint16 pause = readScriptValue(); debugScript("O__WAIT pause %d", pause); @@ -305,18 +299,22 @@ void Script::O__WAIT() { void Script::O_UPDATEOFF() { debugScript("O_UPDATEOFF"); + //_updateEnable = false; } void Script::O_UPDATEON() { debugScript("O_UPDATEON"); + //_updateEnable = true; } void Script::O_UPDATE () { debugScript("O_UPDATE"); + // Refresh screen } void Script::O_CLS() { debugScript("O_CLS"); + // do nothing } void Script::O__CALL() { @@ -345,17 +343,17 @@ void Script::O_GO() { } void Script::O_BACKANIMUPDATEOFF() { - uint16 slotId = readScript32bits(); + uint16 slotId = readScriptValue(); debugScript("O_BACKANIMUPDATEOFF slotId %d", slotId); } void Script::O_BACKANIMUPDATEON() { - uint16 slot = readScript16bits(); + uint16 slot = readScriptValue(); debugScript("O_BACKANIMUPDATEON %d", slot); } void Script::O_CHANGECURSOR() { - uint16 cursorId = readScript16bits(); + uint16 cursorId = readScriptValue(); debugScript("O_CHANGECURSOR %x", cursorId); } @@ -399,8 +397,10 @@ void Script::O_JUMPNZ() { } void Script::O_EXIT() { - uint16 exitCode = readScript16bits(); + uint16 exitCode = readScriptValue(); debugScript("O_EXIT exitCode %d", exitCode); + // Set exit code and shows credits + // if exit code == 0x02EAD } void Script::O_ADDFLAG() { @@ -417,8 +417,8 @@ void Script::O_ADDFLAG() { } void Script::O_TALKANIM() { - uint16 animSlot = readScript16bits(); - uint16 slot = readScript16bits(); + uint16 animSlot = readScriptValue(); + uint16 slot = readScriptValue(); debugScript("O_TALKANIM animSlot %d, slot %d", animSlot, slot); } @@ -440,6 +440,7 @@ void Script::O_SETSTRING() { int32 offset = readScript32bits(); _currentString = offset; + // FIXME: Make it better ;) if (offset >= 80000) { debugScript("GetVaria %s", _vm->_variaTxt->getString(offset - 80000)); } @@ -515,22 +516,23 @@ void Script::O_XORFLAG() { } void Script::O_GETMOBTEXT() { - uint16 value = readScript16bits(); + uint16 value = readScriptValue(); debugScript("O_GETMOBTEXT value %d", value); + // Use Mob::ExamText as current string } void Script::O_MOVEHERO() { - uint16 heroId = readScript16bits(); - uint16 x = readScript16bits(); - uint16 y = readScript16bits(); - uint16 dir = readScript16bits(); + uint16 heroId = readScriptValue(); + uint16 x = readScriptValue(); + uint16 y = readScriptValue(); + uint16 dir = readScriptValue(); debugScript("O_MOVEHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); } void Script::O_WALKHERO() { - uint16 heroId = readScript16bits(); + uint16 heroId = readScriptValue(); debugScript("O_WALKHERO %d", heroId); _opcodeNF = 1; @@ -545,18 +547,22 @@ void Script::O_SETHERO() { } void Script::O_HEROOFF() { - uint16 heroId = readScript16bits(); + uint16 heroId = readScriptValue(); debugScript("O_HEROOFF %d", heroId); + // sets hero visible flag to false } void Script::O_HEROON() { - uint16 heroId = readScript16bits(); + uint16 heroId = readScriptValue(); debugScript("O_HEROON %d", heroId); + // sets hero visible flag to true } void Script::O_CLSTEXT() { - uint16 slot = readScript16bits(); + uint16 slot = readScriptValue(); debugScript("O_CLSTEXT slot %d", slot); + // Sets text line to null + // Sets text timeout to zero } void Script::O_CALLTABLE() { @@ -564,23 +570,27 @@ void Script::O_CALLTABLE() { int32 table = readScript32bits(); debugScript("O_CALLTABLE flag %d, table %d", flag, table); + // makes a call from script function table + // must read table pointer from _code and + // use table entry as next opcode } void Script::O_CHANGEMOB() { - uint16 mob = readScript16bits(); - uint16 value = readScript16bits(); + uint16 mob = readScriptValue(); + uint16 value = readScriptValue(); debugScript("O_CHANGEMOB mob %d, value %d", mob, value); + // Probably sets mobs visible flag to value } void Script::O_ADDINV() { - uint16 hero = readScript16bits(); - uint16 item = readScript16bits(); + uint16 hero = readScriptValue(); + uint16 item = readScriptValue(); debugScript("O_ADDINV hero %d, item %d", hero, item); } void Script::O_REMINV() { - uint16 hero = readScript16bits(); - uint16 item = readScript16bits(); + uint16 hero = readScriptValue(); + uint16 item = readScriptValue(); debugScript("O_REMINV hero %d, item %d", hero, item); } @@ -588,11 +598,13 @@ void Script::O_REPINV() { uint16 hero = readScript16bits(); uint16 item1 = readScript16bits(); uint16 item2 = readScript16bits(); - debugScript("O_REPINV hero %d, item1 %d, item2 %d", hero, item1, item2); + // shouldn't be uses + error("O_REPINV hero %d, item1 %d, item2 %d", hero, item1, item2); } void Script::O_OBSOLETE_GETACTION() { - debugScript("O_OBSOLETE_GETACTION"); + // shouldn't be uses + error("O_OBSOLETE_GETACTION"); } void Script::O_ADDWALKAREA() { @@ -600,7 +612,8 @@ void Script::O_ADDWALKAREA() { uint16 y1 = readScript16bits(); uint16 x2 = readScript16bits(); uint16 y2 = readScript16bits(); - debugScript("O_ADDWALKAREA x1 %d, y1 %d, x2 %d, y2 %d", x1, y1, x2, y2); + // shouldn't be uses + error("O_ADDWALKAREA x1 %d, y1 %d, x2 %d, y2 %d", x1, y1, x2, y2); } void Script::O_REMWALKAREA() { @@ -608,7 +621,9 @@ void Script::O_REMWALKAREA() { uint16 y1 = readScript16bits(); uint16 x2 = readScript16bits(); uint16 y2 = readScript16bits(); - debugScript("O_REMWALKAREA x1 %d, y1 %d, x2 %d, y2 %d", x1, y1, x2, y2); + + // shouldn't be uses + error("O_REMWALKAREA x1 %d, y1 %d, x2 %d, y2 %d", x1, y1, x2, y2); } void Script::O_RESTOREWALKAREA() { @@ -621,46 +636,53 @@ void Script::O_WAITFRAME() { } void Script::O_SETFRAME() { - uint16 anim = readScript16bits(); - uint16 frame = readScript16bits(); + uint16 anim = readScriptValue(); + uint16 frame = readScriptValue(); debugScript("O_SETFRAME anim %d, frame %d", anim, frame); } void Script::O_RUNACTION() { - debugScript("O_RUNACTION"); + // It's empty in original and never used in script + // it's better to report error + error("O_RUNACTION"); } void Script::O_COMPAREHI() { - uint16 flag = readScript16bits(); - uint16 value = readScript16bits(); + Flags::Id flag = readScriptFlagId(); + uint16 value = readScriptValue(); debugScript("O_COMPAREHI flag %d, value %d", flag, value); + _result = value < getFlagValue(flag); } void Script::O_COMPARELO() { - uint16 flag = readScript16bits(); - uint16 value = readScript16bits(); + Flags::Id flag = readScriptFlagId(); + uint16 value = readScriptValue(); debugScript("O_COMPARELO flag %d, value %d", flag, value); + _result = value > getFlagValue(flag); } void Script::O_PRELOADSET() { + // not used in script int32 offset = readScript32bits(); debugScript("O_PRELOADSET offset %04x", offset); } void Script::O_FREEPRELOAD() { + // not used in script debugScript("O_FREEPRELOAD"); } void Script::O_CHECKINV() { - uint16 hero = readScript16bits(); - uint16 item = readScript16bits(); + uint16 hero = readScriptValue(); + uint16 item = readScriptValue(); debugScript("O_CHECKINV hero %d, item %d", hero, item); + // checks if item is in heros inventory } void Script::O_TALKHERO() { - uint16 hero = readScript16bits(); + uint16 hero = readScriptValue(); debugScript("O_TALKHERO hero %d", hero); } @@ -674,21 +696,21 @@ void Script::O_WAITTEXT() { } void Script::O_SETHEROANIM() { - uint16 hero = readScript16bits(); + uint16 hero = readScriptValue(); int32 offset = readScript32bits(); debugScript("O_SETHEROANIM hero %d, offset %d", hero, offset); } void Script::O_WAITHEROANIM() { - uint16 hero = readScript16bits(); + uint16 hero = readScriptValue(); debugScript("O_WAITHEROANIM hero %d", hero); } void Script::O_GETHERODATA() { uint16 flag = readScript16bits(); - uint16 hero = readScript16bits(); - uint16 heroOffset =readScript16bits(); + uint16 hero = readScriptValue(); + uint16 heroOffset = readScriptValue(); debugScript("O_GETHERODATA flag %d, hero %d, heroOffset %d", flag, hero, heroOffset); } @@ -697,22 +719,32 @@ void Script::O_GETMOUSEBUTTON() { } void Script::O_CHANGEFRAMES() { - uint16 anim = readScript16bits(); - uint16 fr1 = readScript16bits(); - uint16 fr2 = readScript16bits(); - uint16 fr3 = readScript16bits(); + uint16 anim = readScriptValue(); + uint16 frame = readScriptValue(); + uint16 lastFrame = readScriptValue(); + uint16 loopFrame = readScriptValue(); - debugScript("O_CHANGFRAMES anim %d, fr1 %d, fr2 %d, fr3 %d", anim, fr1, fr2, fr3); + debugScript( + "O_CHANGFRAMES anim %d, fr1 %d, fr2 %d, fr3 %d", + anim, + frame, + lastFrame, + loopFrame); } void Script::O_CHANGEBACKFRAMES() { - uint16 anim = readScript16bits(); - uint16 fr1 = readScript16bits(); - uint16 fr2 = readScript16bits(); - uint16 fr3 = readScript16bits(); + uint16 anim = readScriptValue(); + uint16 frame = readScriptValue(); + uint16 lastFrame = readScriptValue(); + uint16 loopFrame = readScriptValue(); - debugScript("O_CHANGEBACKFRAMES anim %d, fr1 %d, fr2 %d, fr3 %d", anim, fr1, fr2, fr3); + debugScript( + "O_CHANGEBACKFRAMES anim %d, fr1 %d, fr2 %d, fr3 %d", + anim, + frame, + lastFrame, + loopFrame); } void Script::O_GETBACKANIMDATA() { @@ -724,9 +756,11 @@ void Script::O_GETBACKANIMDATA() { void Script::O_GETANIMDATA() { uint16 flag = readScript16bits(); - uint16 anim = readScript16bits(); - uint16 animOffset = readScript16bits(); + uint16 anim = readScriptValue(); + uint16 animOffset = readScriptValue(); debugScript("O_GETANIMDATA flag %d, anim %d, animOffset %d", flag, anim, animOffset); + // Gets value of anim data + // use anim offset as attribute id not an offset } void Script::O_SETBGCODE() { @@ -736,27 +770,33 @@ void Script::O_SETBGCODE() { } void Script::O_SETBACKFRAME() { - uint16 anim = readScript16bits(); - uint16 frame = readScript16bits(); + uint16 anim = readScriptValue(); + uint16 frame = readScriptValue(); debugScript("O_SETBACKFRAME anim %d, frame %d", anim, frame); } void Script::O_GETRND() { - uint16 flag = readScript16bits(); + Flags::Id flag = readScriptFlagId(); uint16 rndSeed = readScript16bits(); debugScript("O_GETRND flag %d, rndSeed %d", flag, rndSeed); + // puts and random value as flag value + // fairly random value ;) + // setFlagValue(flag, 4); } void Script::O_TALKBACKANIM() { - uint16 animSlot = readScript16bits(); - uint16 slot = readScript16bits(); + uint16 animSlot = readScriptValue(); + uint16 slot = readScriptValue(); debugScript("O_TALKBACKANIM animSlot %d, slot %d", animSlot, slot); } void Script::O_LOADPATH() { int32 offset = readScript32bits(); debugScript("O_LOADPATH offset %d", offset); + // _currentInstruction + offset path file name ptr + // free path bitmap + // load packet path bitmap and puts in Sala } void Script::O_GETCHAR() { @@ -764,7 +804,11 @@ void Script::O_GETCHAR() { setFlagValue(flagId, *_string); - debugScript("O_GETCHAR %04X (%s) %02x", flagId, Flags::getFlagName(flagId), getFlagValue(flagId)); + debugScript( + "O_GETCHAR %04X (%s) %02x", + flagId, + Flags::getFlagName(flagId), + getFlagValue(flagId)); ++_string; } @@ -773,17 +817,20 @@ void Script::O_SETDFLAG() { uint16 flag = readScript16bits(); int32 offset = readScript32bits(); debugScript("O_SETDFLAG flag %d, offset %04x", flag, offset); + // run this through debugger looks strange + // it looks like this one store two 16 bit value in one go } void Script::O_CALLDFLAG() { uint16 flag = readScript16bits(); debugScript("O_CALLDFLAG flag %d", flag); + // it seems that some flags are 32 bit long } void Script::O_PRINTAT() { - uint16 slot = readScript16bits(); - uint16 fr1 = readScript16bits(); - uint16 fr2 = readScript16bits(); + uint16 slot = readScriptValue(); + uint16 fr1 = readScriptValue(); + uint16 fr2 = readScriptValue(); debugScript("O_PRINTAT slot %d, fr1 %d, fr2 %d", slot, fr1, fr2); @@ -798,31 +845,33 @@ void Script::O_PRINTAT() { } void Script::O_ZOOMIN() { - uint16 slot = readScript16bits(); + uint16 slot = readScriptValue(); debugScript("O_ZOOMIN slot %04d", slot); } void Script::O_ZOOMOUT() { - uint16 slot = readScript16bits(); + uint16 slot = readScriptValue(); debugScript("O_ZOOMOUT slot %d", slot); } void Script::O_SETSTRINGOFFSET() { int32 offset = readScript32bits(); debugScript("O_SETSTRINGOFFSET offset %04x", offset); + // _currentString = "" + // _string = (const char *)_currentInstruction + offset } void Script::O_GETOBJDATA() { - uint16 flag = readScript16bits(); - uint16 obj = readScript16bits(); - int16 objOffset = readScript16bits(); + Flags::Id flag = readScriptFlagId(); + uint16 obj = readScriptValue(); + int16 objOffset = readScriptValue(); debugScript("O_GETOBJDATA flag %d, obj %d, objOffset %d", flag, obj, objOffset); } void Script::O_SETOBJDATA() { - uint16 obj = readScript16bits(); - int16 objOffset = readScript16bits(); - uint16 value = readScript16bits(); + uint16 obj = readScriptValue(); + int16 objOffset = readScriptValue(); + uint16 value = readScriptValue(); debugScript("O_SETOBJDATA obj %d, objOffset %d, value %d", obj, objOffset, value); } @@ -833,19 +882,21 @@ void Script::O_SWAPOBJECTS() { } void Script::O_CHANGEHEROSET() { - uint16 hero = readScript16bits(); - uint16 heroSet = readScript16bits(); + uint16 hero = readScriptValue(); + uint16 heroSet = readScriptValue(); debugScript("O_CHANGEHEROSET hero %d, heroSet %d", hero, heroSet); } void Script::O_ADDSTRING() { - uint16 value = readScript16bits(); + uint16 value = readScriptValue(); debugScript("O_ADDSTRING value %d", value); + // _string += value } void Script::O_SUBSTRING() { - uint16 value = readScript16bits(); + uint16 value = readScriptValue(); debugScript("O_SUBSTRING value %d", value); + // _string -= value } void Script::O_INITDIALOG() { @@ -853,45 +904,47 @@ void Script::O_INITDIALOG() { } void Script::O_ENABLEDIALOGOPT() { - uint16 opt = readScript16bits(); + uint16 opt = readScriptValue(); debugScript("O_ENABLEDIALOGOPT opt %d", opt); } void Script::O_DISABLEDIALOGOPT() { - uint16 opt = readScript16bits(); + uint16 opt = readScriptValue(); debugScript("O_DISABLEDIALOGOPT opt %d", opt); } void Script::O_SHOWDIALOGBOX() { - uint16 box = readScript16bits(); + uint16 box = readScriptValue(); debugScript("O_SHOWDIALOGBOX box %d", box); } void Script::O_STOPSAMPLE() { - uint16 slot = readScript16bits(); + uint16 slot = readScriptValue(); debugScript("O_STOPSAMPLE slot %d", slot); _vm->stopSample(slot); } void Script::O_BACKANIMRANGE() { - uint16 slotId = readScript16bits(); - uint16 animId = readScript16bits(); - uint16 low = readScript16bits(); - uint16 high = readScript16bits(); + uint16 slotId = readScriptValue(); + uint16 animId = readScriptValue(); + uint16 low = readScriptValue(); + uint16 high = readScriptValue(); debugScript("O_BACKANIMRANGE slotId %d, animId %d, low %d, high %d", slotId, animId, low, high); } void Script::O_CLEARPATH() { debugScript("O_CLEARPATH"); + // Fill Sala with 255 } void Script::O_SETPATH() { debugScript("O_SETPATH"); + // CopyPath } void Script::O_GETHEROX() { - uint16 heroId = readScript16bits(); + uint16 heroId = readScriptValue(); Flags::Id flagId = readScriptFlagId(); debugScript("O_GETHEROX heroId %d, flagId %d", heroId, flagId); @@ -905,7 +958,7 @@ void Script::O_GETHEROY() { } void Script::O_GETHEROD() { - uint16 heroId = readScript16bits(); + uint16 heroId = readScriptValue(); Flags::Id flagId = readScriptFlagId(); debugScript("O_GETHEROD heroId %d, flagId %d", heroId, flagId); @@ -913,10 +966,18 @@ void Script::O_GETHEROD() { void Script::O_PUSHSTRING() { debugScript("O_PUSHSTRING"); + // push on the stack + // _currentString + // _dialogData + // _string } void Script::O_POPSTRING() { debugScript("O_POPSTRING"); + // pop from the stack + // _currentString + // _dialogData + // _string } void Script::O_SETFGCODE() { @@ -927,9 +988,11 @@ void Script::O_SETFGCODE() { } void Script::O_STOPHERO() { - uint16 heroId = readScript16bits(); + uint16 heroId = readScriptValue(); debugScript("O_STOPHERO heroId %d", heroId); + + // clear move steps for hero } void Script::O_ANIMUPDATEOFF() { @@ -938,53 +1001,54 @@ void Script::O_ANIMUPDATEOFF() { } void Script::O_ANIMUPDATEON() { - uint16 slotId = readScript16bits(); + uint16 slotId = readScriptValue(); debugScript("O_ANIMUPDATEON slotId %d", slotId); } void Script::O_FREECURSOR() { debugScript("O_FREECURSOR"); + // Change cursor to 0 + // free inv cursor 1 } void Script::O_ADDINVQUIET() { - uint16 heroId = readScript16bits(); - uint16 itemId = readScript16bits(); + uint16 heroId = readScriptValue(); + uint16 itemId = readScriptValue(); debugScript("O_ADDINVQUIET heorId %d, itemId %d", heroId, itemId); } void Script::O_RUNHERO() { - uint16 heroId = readScript16bits(); - uint16 x = readScript16bits(); - uint16 y = readScript16bits(); - uint16 dir = readScript16bits(); + uint16 heroId = readScriptValue(); + uint16 x = readScriptValue(); + uint16 y = readScriptValue(); + uint16 dir = readScriptValue(); debugScript("O_RUNHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); } void Script::O_SETBACKANIMDATA() { - uint16 animId = readScript16bits(); - uint16 animOffset = readScript16bits(); - uint16 wart = readScript16bits(); + uint16 animId = readScriptValue(); + uint16 animOffset = readScriptValue(); + uint16 wart = readScriptValue(); debugScript("O_SETBACKANIMDATA animId %d, animOffset %d, wart %d", animId, animOffset, wart); } void Script::O_VIEWFLC() { - uint16 animNr = readScript16bits(); + uint16 animNr = readScriptValue(); debugScript("O_VIEWFLC animNr %d", animNr); _vm->loadAnim(animNr, false); } void Script::O_CHECKFLCFRAME() { - uint16 frameNr = readScript16bits(); + uint16 frameNr = readScriptValue(); debugScript("O_CHECKFLCFRAME frame number %d", frameNr); const Video::FlicDecoder &flicPlayer = _vm->_flicPlayer; - if (flicPlayer.getCurFrame() != frameNr) - { + if (flicPlayer.getCurFrame() != frameNr) { // Move instruction pointer before current instruciton // must do this check once again till it's false _currentInstruction -= 2; @@ -1000,8 +1064,7 @@ void Script::O_CHECKFLCEND() { //debug("frameCount %d, currentFrame %d", flicPlayer.getFrameCount(), flicPlayer.getCurFrame()); - if (flicPlayer.getFrameCount() - flicPlayer.getCurFrame() > 1) - { + if (flicPlayer.getFrameCount() - flicPlayer.getCurFrame() > 1) { // Move instruction pointer before current instruciton // must do this check once again till it's false _currentInstruction -= 2; @@ -1014,13 +1077,13 @@ void Script::O_FREEFLC() { } void Script::O_TALKHEROSTOP() { - uint16 heroId = readScript16bits(); + uint16 heroId = readScriptValue(); debugScript("O_TALKHEROSTOP %d", heroId); } void Script::O_HEROCOLOR() { - uint16 heroId = readScript16bits(); - uint16 kolorr = readScript16bits(); + uint16 heroId = readScriptValue(); + uint16 kolorr = readScriptValue(); debugScript("O_HEROCOLOR heroId %d, kolorr %d", heroId, kolorr); } @@ -1029,27 +1092,27 @@ void Script::O_GRABMAPA() { } void Script::O_ENABLENAK() { - uint16 nakId = readScript16bits(); + uint16 nakId = readScriptValue(); debugScript("O_ENABLENAK nakId %d", nakId); } void Script::O_DISABLENAK() { - uint16 nakId = readScript16bits(); + uint16 nakId = readScriptValue(); debugScript("O_DISABLENAK nakId %d", nakId); } void Script::O_GETMOBNAME() { - uint16 war = readScript16bits(); + uint16 war = readScriptValue(); debugScript("O_GETMOBNAME war %d", war); } void Script::O_SWAPINVENTORY() { - uint16 heroId = readScript16bits(); + uint16 heroId = readScriptValue(); debugScript("O_SWAPINVENTORY heroId %d", heroId); } void Script::O_CLEARINVENTORY() { - uint16 heroId = readScript16bits(); + uint16 heroId = readScriptValue(); debugScript("O_CLEARINVENTORY heroId %d", heroId); } @@ -1057,7 +1120,9 @@ void Script::O_SKIPTEXT() { debugScript("O_SKIPTEXT"); } -void Script::SetVoice(uint32 slot) { +void Script::SetVoice(uint32 sampleSlot) { + // TODO: use sample slot + uint16 slot = readScriptValue(); _vm->loadVoice( slot, Common::String::format( @@ -1069,27 +1134,28 @@ void Script::SetVoice(uint32 slot) { } void Script::O_SETVOICEH() { - uint16 txn = readScript16bits(); - debugScript("O_SETVOICEH txn %d", txn); - SetVoice(txn); + static const uint32 VOICE_H_SLOT = 28; + SetVoice(VOICE_H_SLOT); } void Script::O_SETVOICEA() { - uint16 txn = readScript16bits(); - debugScript("O_SETVOICEA txn %d", txn); - SetVoice(txn); + static const uint32 VOICE_A_SLOT = 29; + SetVoice(VOICE_A_SLOT); } void Script::O_SETVOICEB() { - uint16 txn = readScript16bits(); - debugScript("O_SETVOICEB txn %d", txn); - SetVoice(txn); + static const uint32 VOICE_B_SLOT = 30; + SetVoice(VOICE_B_SLOT); } void Script::O_SETVOICEC() { - uint16 txn = readScript16bits(); - debugScript("O_SETVOICEC txn %d", txn); - SetVoice(txn); + static const uint32 VOICE_C_SLOT = 31; + SetVoice(VOICE_C_SLOT); +} + +void Script::O_SETVOICED() { + static const uint32 VOICE_D_SLOT = 32; + SetVoice(VOICE_D_SLOT); } void Script::O_VIEWFLCLOOP() { @@ -1100,13 +1166,14 @@ void Script::O_VIEWFLCLOOP() { } void Script::O_FLCSPEED() { - uint16 speed = readScript16bits(); + uint16 speed = readScriptValue(); debugScript("O_FLCSPEED speed %d", speed); } void Script::O_OPENINVENTORY() { debugScript("O_OPENINVENTORY"); _opcodeNF = 1; + // _showInventoryFlag = true } void Script::O_KRZYWA() { @@ -1115,24 +1182,23 @@ void Script::O_KRZYWA() { void Script::O_GETKRZYWA() { debugScript("O_GETKRZYWA"); + // setFlagValue(Flags::TORX1, krzywa[_krzywaIndex++]) + // setFlagValue(Flags::TORY1, krzywa[_krzywaIndex++]) + // Check _krzywaIndex } void Script::O_GETMOB() { Flags::Id flagId = readScriptFlagId(); - uint16 mx = readScript16bits(); - uint16 my = readScript16bits(); + uint16 mx = readScriptValue(); + uint16 my = readScriptValue(); debugScript("O_GETMOB flagId %d, mx %d, my %d", flagId, mx, my); + // check if current mob pos = (mx, my) } void Script::O_INPUTLINE() { debugScript("O_INPUTLINE"); } -void Script::O_SETVOICED() { - uint16 txn = readScript16bits(); - debugScript("O_SETVOICED txn %d", txn); - SetVoice(txn); -} void Script::O_BREAK_POINT() { debugScript("O_BREAK_POINT"); diff --git a/engines/prince/script.h b/engines/prince/script.h index 86b998829f2d..d9b42baf3932 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -49,6 +49,8 @@ class Script { void setFlagValue(Flags::Id flag, uint16 value); uint16 getFlagValue(Flags::Id flag); + void stopBg() { _bgOpcodePC = 0; } + private: PrinceEngine *_vm; From 0f013bf6e1bed6a1e18aa1a4ea16ed1c0105f33d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Tue, 26 Nov 2013 19:21:00 +0000 Subject: [PATCH 059/374] PRINCE: compilation fix after merge from master --- engines/prince/configure.engine | 3 +++ engines/prince/font.cpp | 4 ++-- engines/prince/font.h | 6 +++--- 3 files changed, 8 insertions(+), 5 deletions(-) create mode 100644 engines/prince/configure.engine diff --git a/engines/prince/configure.engine b/engines/prince/configure.engine new file mode 100644 index 000000000000..50740d9f4167 --- /dev/null +++ b/engines/prince/configure.engine @@ -0,0 +1,3 @@ +# This file is included from the main "configure" script +# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] +add_engine prince "The Prince and The Coward" no diff --git a/engines/prince/font.cpp b/engines/prince/font.cpp index 33149c14e467..40b6d014e6ce 100644 --- a/engines/prince/font.cpp +++ b/engines/prince/font.cpp @@ -65,11 +65,11 @@ Font::ChrData Font::getChrData(byte chr) const { return chrData; } -int Font::getCharWidth(byte chr) const { +int Font::getCharWidth(uint32 chr) const { return getChrData(chr)._width; } -void Font::drawChar(Graphics::Surface *dst, byte chr, int posX, int posY, uint32 color) const { +void Font::drawChar(Graphics::Surface *dst, uint32 chr, int posX, int posY, uint32 color) const { const ChrData chrData = getChrData(chr); for (int y = 0; y < chrData._height; ++y) { diff --git a/engines/prince/font.h b/engines/prince/font.h index 020e12bf5482..c41b176c726b 100644 --- a/engines/prince/font.h +++ b/engines/prince/font.h @@ -45,11 +45,11 @@ class Font : public Graphics::Font { virtual int getMaxCharWidth() const override; - virtual int getCharWidth(byte chr) const override; + virtual int getCharWidth(uint32 chr) const override; - virtual void drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const override; + virtual void drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const override; - virtual int getKerningOffset(byte left, byte right) const { return -2; } + virtual int getKerningOffset(uint32 left, uint32 right) const override { return -2; } private: struct ChrData { From 69a58457744c662930f5f19b90d95d7647d580b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Tue, 3 Dec 2013 14:46:24 +0000 Subject: [PATCH 060/374] PRINCE: loadSample with sample looping added, escaping from intro works --- engines/prince/archive.cpp | 1 + engines/prince/font.h | 8 ++-- engines/prince/hero.cpp | 34 +++++++++++++++ engines/prince/hero.h | 88 ++++++++++++++++++++++++++++++++++++++ engines/prince/module.mk | 1 + engines/prince/prince.cpp | 68 ++++++++++++++++++++++------- engines/prince/prince.h | 13 ++++-- engines/prince/script.cpp | 19 ++++++-- 8 files changed, 205 insertions(+), 27 deletions(-) create mode 100644 engines/prince/hero.cpp create mode 100644 engines/prince/hero.h diff --git a/engines/prince/archive.cpp b/engines/prince/archive.cpp index 0b1367f96634..d1b680c20426 100644 --- a/engines/prince/archive.cpp +++ b/engines/prince/archive.cpp @@ -86,6 +86,7 @@ void PtcArchive::close() { } bool PtcArchive::hasFile(const Common::String &name) const { + // TODO: check if path matching should be added return _items.contains(name); } diff --git a/engines/prince/font.h b/engines/prince/font.h index c41b176c726b..bf9c09d0e90e 100644 --- a/engines/prince/font.h +++ b/engines/prince/font.h @@ -41,13 +41,13 @@ class Font : public Graphics::Font { bool loadFromStream(Common::SeekableReadStream &stream); - virtual int getFontHeight() const override; + virtual int getFontHeight() const override; - virtual int getMaxCharWidth() const override; + virtual int getMaxCharWidth() const override; - virtual int getCharWidth(uint32 chr) const override; + virtual int getCharWidth(uint32 chr) const override; - virtual void drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const override; + virtual void drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const override; virtual int getKerningOffset(uint32 left, uint32 right) const override { return -2; } diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp new file mode 100644 index 000000000000..277e521bee5a --- /dev/null +++ b/engines/prince/hero.cpp @@ -0,0 +1,34 @@ +/* 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/hero.h" + +namespace Prince { + +Hero::Hero() : _number(0), _visible(false), _state(STAY), _middleX(0), _middleY(0) + , _boreNum(0), _currHeight(0), _moveDelay(0), _shadMinus(1) +{ +} + +} + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/hero.h b/engines/prince/hero.h new file mode 100644 index 000000000000..e11a0f739550 --- /dev/null +++ b/engines/prince/hero.h @@ -0,0 +1,88 @@ +/* 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_HERO_H +#define PRINCE_HERO_H + +#include "common/scummsys.h" + +namespace Prince { + +class Hero { +public: + enum State { + STAY = 0, + TURN = 1, + MOVE = 2, + BORE = 3, + SPEC = 4, + TALK = 5, + MVAN = 6, + TRAN = 7, + RUN = 8, + DMOVE = 9 + }; + + Hero(); + +private: + uint16 _number; + uint16 _visible; + State _state; + uint16 _middleX; + uint16 _middleY; + + // Coords array of coordinates + // DirTab array of directions + // CurrCoords current coordinations + // CurrDirTab current direction + // LastDir previous move direction + // DestDir + // LeftRight previous left/right direction + // UpDown previous up/down direction + // Phase animation phase + // Step x/y step size depends on direction + // MaxBoredom stand still timeout + // Boredom current boredom time in frames + uint16 _boreNum; // Bore anim frame + // TalkTime time of talk anim + // SpecAnim additional anim + + uint16 _currHeight; // height of current anim phase + + // Inventory array of items + // Inventory2 array of items + // Font subtitiles font + // Color subtitiles color + // AnimSet number of animation set + // MoveAnims MoveSet + // TurnAnim ?? + + uint32 _moveDelay; + uint32 _shadMinus; //?? +}; + +} + +#endif + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/module.mk b/engines/prince/module.mk index 48edcec9ddac..2e5f0592b1f6 100644 --- a/engines/prince/module.mk +++ b/engines/prince/module.mk @@ -15,6 +15,7 @@ MODULE_OBJS = \ prince.o \ archive.o \ decompress.o \ + hero.o \ cursor.o # This module can be built as a plugin diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 9f4ae19af3e5..f82f9e0e0c55 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -31,6 +31,7 @@ #include "common/fs.h" #include "common/keyboard.h" #include "common/substream.h" +#include "common/str.h" #include "graphics/cursorman.h" #include "graphics/surface.h" @@ -56,6 +57,7 @@ #include "prince/mhwanh.h" #include "prince/cursor.h" #include "prince/archive.h" +#include "prince/hero.h" namespace Prince { @@ -74,7 +76,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL), _locationNr(0), _debugger(NULL), _midiPlayer(NULL), _cameraX(0), _newCameraX(0), _frameNr(0), _cursor1(NULL), _cursor2(NULL), _font(NULL), - _walizkaBmp(NULL), _roomBmp(NULL), _voiceStream(NULL), _cursorNr(0) { + _walizkaBmp(NULL), _roomBmp(NULL), _cursorNr(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -82,6 +84,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) DebugMan.enableDebugChannel("script"); + memset(_voiceStream, 0, sizeof(_voiceStream)); + gDebugLevel = 10; } @@ -196,17 +200,19 @@ void PrinceEngine::init() { if (!voices->open("data/voices/databank.ptc")) error("Can't open data/voices/databank.ptc"); + PtcArchive *sound = new PtcArchive(); + if (!sound->open("sound/databank.ptc")) + error("Can't open sound/databank.ptc"); + SearchMan.add("all", all); SearchMan.add("data/voices", voices); + SearchMan.add("sound", sound); _graph = new GraphicsMan(this); _rnd = new Common::RandomSource("prince"); _debugger = new Debugger(this); - SearchMan.addSubDirectoryMatching(gameDataDir, "all", 0, 2); - SearchMan.addSubDirectoryMatching(gameDataDir, "data/voices", 0, 2); - _midiPlayer = new MusicPlayer(this); _font = new Font(); @@ -263,6 +269,13 @@ Common::Error PrinceEngine::run() { } bool PrinceEngine::loadLocation(uint16 locationNr) { + _flicPlayer.close(); + + memset(_textSlots, 0, sizeof(_textSlots)); + for(uint32 sampleId = 0; sampleId < MAX_SAMPLES; ++sampleId) { + stopSample(sampleId); + } + debugEngine("PrinceEngine::loadLocation %d", locationNr); const Common::FSNode gameDataDir(ConfMan.get("path")); SearchMan.remove(Common::String::format("%02d", _locationNr)); @@ -357,19 +370,42 @@ bool PrinceEngine::playNextFrame() { } void PrinceEngine::playSample(uint16 sampleId, uint16 loopType) { - if (_voiceStream) { + if (_voiceStream[sampleId]) { - Audio::RewindableAudioStream *audioStream = Audio::makeWAVStream(_voiceStream, DisposeAfterUse::YES); - _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, audioStream, sampleId); + if (_mixer->isSoundIDActive(sampleId)) { + return; + } + + Audio::AudioStream *audioStream = Audio::makeWAVStream(_voiceStream[sampleId], DisposeAfterUse::YES); + if (loopType) { + audioStream = new Audio::LoopingAudioStream((Audio::RewindableAudioStream*)audioStream, 0, DisposeAfterUse::NO); + } + _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle[sampleId], audioStream, sampleId); } } void PrinceEngine::stopSample(uint16 sampleId) { _mixer->stopID(sampleId); - _voiceStream = NULL; + _voiceStream[sampleId] = NULL; +} + +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, '\\'); + + debugEngine("loadSample slot %d, name %s", sampleSlot, normalizedPath.c_str()); + + _mixer->stopID(sampleSlot); + _voiceStream[sampleSlot] = NULL; + _voiceStream[sampleSlot] = SearchMan.createReadStreamForMember(normalizedPath); + if (_voiceStream[sampleSlot] == NULL) { + error("Can't load sample %s to slot %d", normalizedPath.c_str(), sampleSlot); + } + return _voiceStream[sampleSlot] == NULL; } -bool PrinceEngine::loadVoice(uint32 slot, const Common::String &streamName) { +bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::String &streamName) { debugEngine("Loading wav %s slot %d", streamName.c_str(), slot); if (slot > MAXTEXTS) { @@ -377,26 +413,26 @@ bool PrinceEngine::loadVoice(uint32 slot, const Common::String &streamName) { return false; } - _voiceStream = SearchMan.createReadStreamForMember(streamName); - if (!_voiceStream) { + _voiceStream[sampleSlot] = SearchMan.createReadStreamForMember(streamName); + if (!_voiceStream[sampleSlot]) { error("Can't open %s", streamName.c_str()); return false; } - uint32 id = _voiceStream->readUint32LE(); + uint32 id = _voiceStream[sampleSlot]->readUint32LE(); if (id != 0x46464952) { error("It's not RIFF file %s", streamName.c_str()); return false; } - _voiceStream->skip(0x20); - id = _voiceStream->readUint32LE(); + _voiceStream[sampleSlot]->skip(0x20); + id = _voiceStream[sampleSlot]->readUint32LE(); if (id != 0x61746164) { error("No data section in %s id %04x", streamName.c_str(), id); return false; } - id = _voiceStream->readUint32LE(); + id = _voiceStream[sampleSlot]->readUint32LE(); debugEngine("SetVoice slot %d time %04x", slot, id); id <<= 3; id /= 22050; @@ -405,7 +441,7 @@ bool PrinceEngine::loadVoice(uint32 slot, const Common::String &streamName) { _textSlots[slot]._time = id; debugEngine("SetVoice slot %d time %04x", slot, id); - _voiceStream->seek(0); + _voiceStream[sampleSlot]->seek(0); return true; } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 374048f28508..d2c75e76cb70 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -59,6 +59,7 @@ class VariaTxt; class Cursor; class MhwanhDecoder; class Font; +class Hero; struct Text { const char *_str; @@ -103,7 +104,8 @@ class PrinceEngine : public Engine { bool loadLocation(uint16 locationNr); bool loadAnim(uint16 animNr, bool loop); - bool loadVoice(uint32 slot, const Common::String &name); + bool loadVoice(uint32 textSlot, uint32 sampleSlot, const Common::String &name); + bool loadSample(uint32 sampleSlot, const Common::String &name); void playSample(uint16 sampleId, uint16 loopType); void stopSample(uint16 sampleId); @@ -146,8 +148,11 @@ class PrinceEngine : public Engine { Font *_font; MusicPlayer *_midiPlayer; - Audio::SoundHandle _soundHandle; - Common::SeekableReadStream *_voiceStream; + + static const uint32 MAX_SAMPLES = 60; + Common::SeekableReadStream *_voiceStream[MAX_SAMPLES]; + Audio::SoundHandle _soundHandle[MAX_SAMPLES]; + Common::Array _mobList; Common::Array _objList; @@ -155,6 +160,8 @@ class PrinceEngine : public Engine { uint16 _newCameraX; uint16 _sceneWidth; + Hero* _mainHero; + bool _flicLooped; void mainLoop(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 07821f27a872..9daf3048ab51 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -41,6 +41,7 @@ static const uint16 NUM_OPCODES = 144; Script::Script(PrinceEngine *vm) : _code(NULL), _stacktop(0), _vm(vm), _opcodeNF(false), _waitFlag(0), _result(true) { + memset(_flags, 0, sizeof(_flags)); } Script::~Script() { @@ -146,7 +147,7 @@ uint16 Script::readScript16bits() { uint16 Script::readScriptValue() { uint16 value = readScript16bits(); if (value & FLAG_MASK) { - value = _flags[value - FLAG_MASK]; + return getFlagValue((Flags::Id)value); } return value; } @@ -183,6 +184,7 @@ void Script::O_SETSAMPLE() { int32 sampleNameOffset = readScript32bits(); const char * sampleName = (const char *)&_code[_currentInstruction + sampleNameOffset - 4]; debugScript("O_SETSAMPLE %d %s", sampleId, sampleName); + _vm->loadSample(sampleId, sampleName); } void Script::O_FREESAMPLE() { @@ -355,6 +357,7 @@ void Script::O_BACKANIMUPDATEON() { void Script::O_CHANGECURSOR() { uint16 cursorId = readScriptValue(); debugScript("O_CHANGECURSOR %x", cursorId); + _vm->changeCursor(cursorId); } void Script::O_CHANGEANIMTYPE() { @@ -765,7 +768,7 @@ void Script::O_GETANIMDATA() { void Script::O_SETBGCODE() { int32 offset = readScript32bits(); - _bgOpcodePC = _currentInstruction + offset; + _bgOpcodePC = _currentInstruction + offset - 4; debugScript("O_SETBGCODE next %08x, offset %08x", _bgOpcodePC, offset); } @@ -926,11 +929,18 @@ void Script::O_STOPSAMPLE() { void Script::O_BACKANIMRANGE() { uint16 slotId = readScriptValue(); - uint16 animId = readScriptValue(); + uint16 animId = readScript16bits(); uint16 low = readScriptValue(); uint16 high = readScriptValue(); + if (animId != 0xFFFF) { + if (animId & FLAG_MASK) { + animId = getFlagValue((Flags::Id)animId); + } + } + debugScript("O_BACKANIMRANGE slotId %d, animId %d, low %d, high %d", slotId, animId, low, high); + _result = 1; } void Script::O_CLEARPATH() { @@ -982,7 +992,7 @@ void Script::O_POPSTRING() { void Script::O_SETFGCODE() { int32 offset = readScript32bits(); - _fgOpcodePC = _currentInstruction + offset; + _fgOpcodePC = _currentInstruction + offset - 4; debugScript("O_SETFGCODE next %08x, offset %08x", _fgOpcodePC, offset); } @@ -1125,6 +1135,7 @@ void Script::SetVoice(uint32 sampleSlot) { uint16 slot = readScriptValue(); _vm->loadVoice( slot, + sampleSlot, Common::String::format( "%03d-%02d.WAV", _currentString, From 8e772f936c43a68e4ae7c68b178bd9fa3a3e4f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Thu, 5 Dec 2013 00:02:31 +0000 Subject: [PATCH 061/374] PRINCE: animation added --- engines/prince/animation.cpp | 67 ++++++++ engines/prince/animation.h | 20 ++- engines/prince/detail/animation.cpp | 102 ++++++++++++ engines/prince/detail/animation.h | 51 ++++++ engines/prince/graphics.cpp | 2 +- engines/prince/graphics.h | 2 +- engines/prince/hero.cpp | 44 ++++- engines/prince/hero.h | 27 +++- engines/prince/hero_set.cpp | 243 ++++++++++++++++++++++++++++ engines/prince/hero_set.h | 30 ++++ engines/prince/mhwanh.h | 14 ++ engines/prince/module.mk | 3 + engines/prince/prince.cpp | 139 +++++++--------- engines/prince/prince.h | 20 ++- engines/prince/resource.h | 101 ++++++++++++ engines/prince/script.cpp | 10 +- 16 files changed, 777 insertions(+), 98 deletions(-) create mode 100644 engines/prince/detail/animation.cpp create mode 100644 engines/prince/detail/animation.h create mode 100644 engines/prince/hero_set.cpp create mode 100644 engines/prince/hero_set.h create mode 100644 engines/prince/resource.h diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index e69de29bb2d1..f4db81ec4dc1 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -0,0 +1,67 @@ +/* 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/animation.h" +#include "prince/detail/animation.h" + + +namespace Prince { + +Animation::Animation() : _helper(NULL) { +} + +Animation::~Animation() { + delete _helper; +} + +bool Animation::loadFromStream(Common::SeekableReadStream &stream) { + + uint32 dataSize = stream.size(); + + byte *data = (byte*)malloc(dataSize); + + if(stream.read(data, dataSize) != dataSize) { + free(data); + return false; + } + + delete _helper; + + _helper = new Detail::Animation(data, dataSize); + + return true; +} + +const Graphics::Surface * Animation::getSurface(uint16 frameIndex) { + // bida kaszing + if (frameIndex >= _frameList.size()) { + _frameList.resize(frameIndex); + _frameList.push_back(_helper->getFrame(frameIndex)); + + } + return _frameList[frameIndex]; +} + +} + + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/animation.h b/engines/prince/animation.h index e6a76d33d24d..b0ef25d4933b 100644 --- a/engines/prince/animation.h +++ b/engines/prince/animation.h @@ -23,13 +23,29 @@ #ifndef PRINCE_ANIMATION_H #define PRINCE_ANIMATION_H +#include "common/array.h" +#include "common/stream.h" + +#include "graphics/surface.h" + namespace Prince { -class Animation { +// FIXME: temp hack !!! +namespace Detail { + class Animation; +} +class Animation { +public: + Animation(); + ~Animation(); bool loadFromStream(Common::SeekableReadStream &stream); - const Graphics::Surface *getSurface(uint16 frameIndex) const; + const Graphics::Surface *getSurface(uint16 frameIndex); + +private: + Common::Array _frameList; + Detail::Animation *_helper; }; } diff --git a/engines/prince/detail/animation.cpp b/engines/prince/detail/animation.cpp new file mode 100644 index 000000000000..8b4a72b2f8e0 --- /dev/null +++ b/engines/prince/detail/animation.cpp @@ -0,0 +1,102 @@ +/* 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/detail/animation.h" +#include "prince/decompress.h" + +#include "common/debug.h" +#include "common/endian.h" + +namespace Prince { namespace Detail { + +Animation::Animation(byte *data, uint32 dataSize) + : _data(data), _dataSize(dataSize) { +} + +Animation::~Animation() { + free(_data); +} + +int16 Animation::getLoopCount() const { + return READ_LE_UINT16(_data + 2); +} + +int16 Animation::getBaseX() const { + return READ_LE_UINT16(_data + 8); +} + +int16 Animation::getBaseY() const { + return READ_LE_UINT16(_data + 10); +} + +uint Animation::getPhaseCount() const { + return READ_LE_UINT16(_data + 4); +} + +uint Animation::getFrameCount() const { + return READ_LE_UINT16(_data + 6); +} + +int16 Animation::getPhaseOffsetX(uint phaseIndex) const { + return READ_LE_UINT16(getPhaseEntry(phaseIndex) + 0); +} + +int16 Animation::getPhaseOffsetY(uint phaseIndex) const { + return READ_LE_UINT16(getPhaseEntry(phaseIndex) + 2); +} + +int16 Animation::getPhaseFrameIndex(uint phaseIndex) const { + return READ_LE_UINT16(getPhaseEntry(phaseIndex) + 4); +} + +Graphics::Surface *Animation::getFrame(uint frameIndex) { + byte *frameData = _data + READ_LE_UINT32(_data + 16 + frameIndex * 4); + int16 width = READ_LE_UINT16(frameData + 0); + int16 height = READ_LE_UINT16(frameData + 2); + debug("width = %d; height = %d", width, height); + Graphics::Surface *surf = new Graphics::Surface(); + surf->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); + debug("frameData %p", frameData); + if (READ_BE_UINT32(frameData + 4) == 0x6D61736D) { + // Compressed + Decompressor dec; + uint32 ddataSize = READ_LE_UINT32(frameData + 8); + byte *ddata = new byte[ddataSize]; + dec.decompress(frameData + 12, ddata, ddataSize); + for (uint16 i = 0; i < height; ++i) { + memcpy(surf->getBasePtr(0, i), ddata + width * i, width); + } + delete[] ddata; + } else { + // Uncompressed + for (uint16 i = 0; i < height; ++i) { + memcpy(surf->getBasePtr(0, i), frameData + 4 + width * i, width); + } + } + return surf; +} + +byte *Animation::getPhaseEntry(uint phaseIndex) const { + return _data + READ_LE_UINT32(_data + 12) + phaseIndex * 8; +} + +} } diff --git a/engines/prince/detail/animation.h b/engines/prince/detail/animation.h new file mode 100644 index 000000000000..f9f289dc7147 --- /dev/null +++ b/engines/prince/detail/animation.h @@ -0,0 +1,51 @@ +/* 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_DETAIL_ANIMATION_H +#define PRINCE_DETAIL_ANIMATION_H + +#include "graphics/surface.h" + +namespace Prince { namespace Detail { + +class Animation { +public: + Animation(byte *data, uint32 dataSize); + ~Animation(); + int16 getLoopCount() const; + int16 getBaseX() const; + int16 getBaseY() const; + uint getPhaseCount() const; + uint getFrameCount() const; + int16 getPhaseOffsetX(uint phaseIndex) const; + int16 getPhaseOffsetY(uint phaseIndex) const; + int16 getPhaseFrameIndex(uint phaseIndex) const; + Graphics::Surface *getFrame(uint frameIndex); +protected: + byte *_data; + uint32 _dataSize; + byte *getPhaseEntry(uint phaseIndex) const; +}; + +} } + +#endif diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 025fa7000362..97e2686f5450 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -68,7 +68,7 @@ void GraphicsMan::draw(uint16 posX, uint16 posY, const Graphics::Surface *s) change(); } -void GraphicsMan::drawTransparent(const Graphics::Surface *s) +void GraphicsMan::drawTransparent(uint16 posX, uint16 posY, const Graphics::Surface *s) { for (uint y = 0; y < s->h; ++y) { for (uint x = 0; x < s->w; ++x) { diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index 884aac2c84ac..1766e2a04e2d 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -43,7 +43,7 @@ class GraphicsMan void setPalette(const byte *palette); void draw(uint16 x, uint16 y, const Graphics::Surface *s); - void drawTransparent(const Graphics::Surface *s); + void drawTransparent(uint16 x, uint16 y, const Graphics::Surface *s); Graphics::Surface *_frontScreen; Graphics::Surface *_backScreen; diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 277e521bee5a..621a9b8ee143 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -19,16 +19,56 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ +#include "common/debug.h" #include "prince/hero.h" +#include "prince/hero_set.h" +#include "prince/animation.h" +#include "prince/resource.h" + namespace Prince { +static const uint32 kMoveSetSize = 26; + Hero::Hero() : _number(0), _visible(false), _state(STAY), _middleX(0), _middleY(0) - , _boreNum(0), _currHeight(0), _moveDelay(0), _shadMinus(1) -{ + , _boreNum(0), _currHeight(0), _moveDelay(0), _shadMinus(1) { } +bool Hero::loadAnimSet(uint32 animSetNr) { + animSetNr = 6; + if (animSetNr > sizeof(heroSetTable)) { + return false; + } + + for (uint32 i = 0; i < _moveSet.size(); ++i) { + delete _moveSet[i]; + } + + const HeroSetAnimNames &animSet = *heroSetTable[animSetNr]; + + _moveSet.resize(kMoveSetSize); + for (uint32 i = 0; i < kMoveSetSize; ++i) { + debug("Anim set item %d %s", i, animSet[i]); + Animation *anim = NULL; + if (animSet[i] != NULL) { + anim = new Animation(); + Resource::loadResource(anim, animSet[i]); + } + _moveSet[i] = anim; + } + + + return true; +} + +const Graphics::Surface * Hero::getSurface() { + if (_moveSet[3]) { + return _moveSet[3]->getSurface(0); + } + return NULL; +} + } /* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/hero.h b/engines/prince/hero.h index e11a0f739550..77333d3643f8 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -24,9 +24,14 @@ #define PRINCE_HERO_H #include "common/scummsys.h" +#include "common/array.h" + +#include "graphics/surface.h" namespace Prince { +class Animation; + class Hero { public: enum State { @@ -42,14 +47,28 @@ class Hero { DMOVE = 9 }; + enum Direction { + LEFT = 1, + RIGHT = 2, + UP = 3, + DOWN = 4 + }; + Hero(); -private: + bool loadAnimSet(uint32 heroAnimNumber); + + const Graphics::Surface * getSurface(); + + void setPos(int16 x, int16 y) { _middleX = x; _middleX = y; } + void setVisible(bool flag) { _visible = flag; } + +//private: uint16 _number; uint16 _visible; State _state; - uint16 _middleX; - uint16 _middleY; + int16 _middleX; + int16 _middleY; // Coords array of coordinates // DirTab array of directions @@ -74,7 +93,7 @@ class Hero { // Font subtitiles font // Color subtitiles color // AnimSet number of animation set - // MoveAnims MoveSet + Common::Array _moveSet; // MoveAnims MoveSet // TurnAnim ?? uint32 _moveDelay; diff --git a/engines/prince/hero_set.cpp b/engines/prince/hero_set.cpp new file mode 100644 index 000000000000..a8c05de724c0 --- /dev/null +++ b/engines/prince/hero_set.cpp @@ -0,0 +1,243 @@ + +/* 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/hero_set.h" +#include "common/scummsys.h" + +namespace Prince { + +static HeroSetAnimNames heroSet5= { + "SL_DIAB.ANI", + "SR_DIAB.ANI", + "SU_DIAB.ANI", + "SD_DIAB.ANI", + NULL, + NULL, + "MU_DIAB.ANI", + "MD_DIAB.ANI", + "TL_DIAB.ANI", + "TR_DIAB.ANI", + "TU_DIAB.ANI", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +static HeroSetAnimNames heroSet1= { + "SL_HERO1.ANI", + "SR_HERO1.ANI", + "SU_HERO1.ANI", + "SD_HERO1.ANI", + "ML_HERO1.ANI", + "MR_HERO1.ANI", + "MU_HERO1.ANI", + "MD_HERO1.ANI", + "TL_HERO1.ANI", + "TR_HERO1.ANI", + "TU_HERO1.ANI", + "TD_HERO1.ANI", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "KSI_KURZ.ANI", + "KS_WLOSY.ANI" +}; + +static HeroSetAnimNames heroSet2= { + "SL_HERO2.ANI", + "SR_HERO2.ANI", + "SU_HERO2.ANI", + "SD_HERO2.ANI", + "ML_HERO2.ANI", + "MR_HERO2.ANI", + "MU_HERO2.ANI", + "MD_HERO2.ANI", + "TL_HERO2.ANI", + "TR_HERO2.ANI", + "TU_HERO2.ANI", + "TD_HERO2.ANI", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "KSI_KU_S.ANI", + "KS_WLO_S.ANI" +}; + +static HeroSetAnimNames heroSet3= { + "SL_BEAR.ANI", + "SR_BEAR.ANI", + "SU_BEAR.ANI", + "SD_BEAR.ANI", + "NIED-LEW.ANI", + "NIED-PRW.ANI", + "NIED-TYL.ANI", + "NIED-PRZ.ANI", + "SL_BEAR.ANI", + "SR_BEAR.ANI", + "SU_BEAR.ANI", + "SD_BEAR.ANI", + "N_LW-TYL.ANI", + "N_LW-PRZ.ANI", + "N_LW-PR.ANI", + "N_PR-TYL.ANI", + "N_PR-PRZ.ANI", + "N_PR-LW.ANI", + "N_TYL-LW.ANI", + "N_TYL-PR.ANI", + "N_TL-PRZ.ANI", + "N_PRZ-LW.ANI", + "N_PRZ-PR.ANI", + "N_PRZ-TL.ANI", + NULL, + NULL, +}; + +static HeroSetAnimNames shanSet1= { + "SL_SHAN.ANI", + "SR_SHAN.ANI", + "SU_SHAN.ANI", + "SD_SHAN.ANI", + "ML_SHAN.ANI", + "MR_SHAN.ANI", + "MU_SHAN.ANI", + "MD_SHAN.ANI", + "TL_SHAN.ANI", + "TR_SHAN.ANI", + "TU_SHAN.ANI", + "TD_SHAN.ANI", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "B1_SHAN.ANI", + "B2_SHAN.ANI", +}; + +static HeroSetAnimNames shanSet2= { + "SL_SHAN2.ANI", + "SR_SHAN2.ANI", + "SU_SHAN.ANI", + "SD_SHAN2.ANI", + "ML_SHAN2.ANI", + "MR_SHAN2.ANI", + "MU_SHAN.ANI", + "MD_SHAN2.ANI", + "TL_SHAN2.ANI", + "TR_SHAN2.ANI", + "TU_SHAN.ANI", + "TD_SHAN2.ANI", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "B1_SHAN2.ANI", + "B2_SHAN2.ANI" +}; + +static HeroSetAnimNames arivSet1= { + "SL_ARIV.ANI", + "SR_ARIV.ANI", + "SU_ARIV.ANI", + "SD_ARIV.ANI", + "ML_ARIV.ANI", + "MR_ARIV.ANI", + "MU_ARIV.ANI", + "MD_ARIV.ANI", + "TL_ARIV.ANI", + "TR_ARIV.ANI", + "TU_ARIV.ANI", + "TD_ARIV.ANI", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +const HeroSetAnimNames *heroSetTable[7] = { + &heroSet1, + &heroSet2, + &heroSet3, + &shanSet1, + &arivSet1, + &heroSet5, + &shanSet2, +}; + +} +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/hero_set.h b/engines/prince/hero_set.h new file mode 100644 index 000000000000..335f70a6abd2 --- /dev/null +++ b/engines/prince/hero_set.h @@ -0,0 +1,30 @@ +/* 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. + * + */ + +namespace Prince { + +typedef const char *HeroSetAnimNames[26]; + +extern const HeroSetAnimNames *heroSetTable[7]; + +} +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/mhwanh.h b/engines/prince/mhwanh.h index b11ecd08e638..9344312ccefb 100644 --- a/engines/prince/mhwanh.h +++ b/engines/prince/mhwanh.h @@ -24,7 +24,9 @@ #define PRINCE_MHWANH_H #include "graphics/decoders/image_decoder.h" +#include "graphics/decoders/bmp.h" #include "graphics/surface.h" +#include "resource.h" namespace Prince { @@ -46,6 +48,18 @@ class MhwanhDecoder : public Graphics::ImageDecoder { uint16 _paletteColorCount; }; +namespace Resource { + template <> inline + bool loadFromStream(MhwanhDecoder &image, Common::SeekableReadStream &stream) { + return image.loadStream(stream); + } + + template <> inline + bool loadFromStream(Graphics::BitmapDecoder &image, Common::SeekableReadStream &stream) { + return image.loadStream(stream); + } +} + } #endif diff --git a/engines/prince/module.mk b/engines/prince/module.mk index 2e5f0592b1f6..e5319f8fe8b9 100644 --- a/engines/prince/module.mk +++ b/engines/prince/module.mk @@ -1,6 +1,7 @@ MODULE := engines/prince MODULE_OBJS = \ + animation.o \ debugger.o \ script.o \ graphics.o \ @@ -16,6 +17,8 @@ MODULE_OBJS = \ archive.o \ decompress.o \ hero.o \ + hero_set.o \ + detail/animation.o \ cursor.o # This module can be built as a plugin diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index f82f9e0e0c55..207c60181081 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -58,6 +58,7 @@ #include "prince/cursor.h" #include "prince/archive.h" #include "prince/hero.h" +#include "prince/resource.h" namespace Prince { @@ -104,6 +105,8 @@ PrinceEngine::~PrinceEngine() { delete _variaTxt; delete[] _talkTxt; delete _graph; + delete _mainHero; + delete _secondHero; for (uint32 i = 0; i < _objList.size(); ++i) { delete _objList[i]; @@ -115,77 +118,6 @@ GUI::Debugger *PrinceEngine::getDebugger() { return _debugger; } -template -bool loadFromStream(T &resource, Common::SeekableReadStream &stream) { - return resource.loadFromStream(stream); -} - -template <> -bool loadFromStream(MhwanhDecoder &image, Common::SeekableReadStream &stream) { - return image.loadStream(stream); -} - -template <> -bool loadFromStream(Graphics::BitmapDecoder &image, Common::SeekableReadStream &stream) { - return image.loadStream(stream); -} - -template -bool loadResource(T *resource, const char *resourceName, bool required = true) { - Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); - if (!stream) { - if (required) - error("Can't load %s", resourceName); - return false; - } - - bool ret = loadFromStream(*resource, *stream); - - delete stream; - - return ret; -} - -template -bool loadResource(Common::Array &array, const char *resourceName, bool required = true) { - Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); - if (!stream) { - if (required) - error("Can't load %s", resourceName); - return false; - } - - T t; - while (t.loadFromStream(*stream)) - array.push_back(t); - - delete stream; - return true; -} - -template -bool loadResource(Common::Array &array, const char *resourceName, bool required = true) { - 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 initiailzed object - while (true) { - T* t = new T(); - if (!t->loadFromStream(*stream)) { - delete t; - break; - } - array.push_back(t); - } - - delete stream; - return true; -} - void PrinceEngine::init() { const Common::FSNode gameDataDir(ConfMan.get("path")); @@ -216,22 +148,22 @@ void PrinceEngine::init() { _midiPlayer = new MusicPlayer(this); _font = new Font(); - loadResource(_font, "all/font1.raw"); + Resource::loadResource(_font, "all/font1.raw"); _walizkaBmp = new MhwanhDecoder(); - loadResource(_walizkaBmp, "all/walizka"); + Resource::loadResource(_walizkaBmp, "all/walizka"); _script = new Script(this); - loadResource(_script, "all/skrypt.dat"); + Resource::loadResource(_script, "all/skrypt.dat"); _variaTxt = new VariaTxt(); - loadResource(_variaTxt, "all/variatxt.dat"); + Resource::loadResource(_variaTxt, "all/variatxt.dat"); _cursor1 = new Cursor(); - loadResource(_cursor1, "all/mouse1.cur"); + Resource::loadResource(_cursor1, "all/mouse1.cur"); _cursor2 = new Cursor(); - loadResource(_cursor2, "all/mouse2.cur"); + Resource::loadResource(_cursor2, "all/mouse2.cur"); Common::SeekableReadStream *talkTxtStream = SearchMan.createReadStreamForMember("all/talktxt.dat"); if (!talkTxtStream) { @@ -245,11 +177,16 @@ void PrinceEngine::init() { delete talkTxtStream; _roomBmp = new Graphics::BitmapDecoder(); + + _mainHero = new Hero(); + _secondHero = new Hero(); + + _mainHero->loadAnimSet(0); } void PrinceEngine::showLogo() { MhwanhDecoder logo; - if (loadResource(&logo, "logo.raw")) { + if (Resource::loadResource(&logo, "logo.raw")) { _graph->setPalette(logo.getPalette()); _graph->draw(0, 0, logo.getSurface()); _graph->update(); @@ -268,6 +205,33 @@ Common::Error PrinceEngine::run() { return Common::kNoError; } +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); + + + // 32 byte aligment + stream.seek(pos + 32); + + return true; +} + bool PrinceEngine::loadLocation(uint16 locationNr) { _flicPlayer.close(); @@ -303,19 +267,22 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _midiPlayer->loadMidi(musName); // load location background, replace old one - loadResource(_roomBmp, "room"); + Resource::loadResource(_roomBmp, "room"); if (_roomBmp->getSurface()) { _sceneWidth = _roomBmp->getSurface()->w; } _mobList.clear(); - loadResource(_mobList, "mob.lst", false); + Resource::loadResource(_mobList, "mob.lst", false); for (uint32 i = 0; i < _objList.size(); ++i) { delete _objList[i]; } _objList.clear(); - loadResource(_objList, "obj.lst", false); + Resource::loadResource(_objList, "obj.lst", false); + + _animList.clear(); + Resource::loadResource(_animList, "anim.lst", false); return true; } @@ -359,7 +326,7 @@ bool PrinceEngine::playNextFrame() { const Graphics::Surface *s = _flicPlayer.decodeNextFrame(); if (s) { - _graph->drawTransparent(s); + _graph->drawTransparent(0, 0, s); _graph->change(); } else if (_flicLooped) { _flicPlayer.rewind(); @@ -597,6 +564,13 @@ void PrinceEngine::drawScreen() { _graph->draw(0, 0, &visiblePart); } + if (_mainHero->_visible) { + const Graphics::Surface *mainHeroSurface = _mainHero->getSurface(); + + if (mainHeroSurface) + _graph->drawTransparent(_mainHero->_middleX, _mainHero->_middleY, mainHeroSurface); + } + playNextFrame(); //if (_objectList) @@ -649,6 +623,7 @@ void PrinceEngine::mainLoop() { // TODO: Update all structures, animations, naks, heros etc. _script->step(); + drawScreen(); // Calculate the frame delay based off a desired frame time diff --git a/engines/prince/prince.h b/engines/prince/prince.h index d2c75e76cb70..edb4f1999fed 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -71,6 +71,21 @@ struct Text { } }; +struct AnimListItem { + uint16 _type; + uint16 _fileNumber; + uint16 _startPhase; + uint16 _endPhase; + uint16 _loopPhase; + int16 _x; + int16 _y; + uint16 _loopType; + uint16 _nextAnim; + uint16 _flags; + + bool loadFromStream(Common::SeekableReadStream &stream); +}; + struct DebugChannel { enum Type { @@ -119,6 +134,8 @@ class PrinceEngine : public Engine { Text _textSlots[MAXTEXTS]; uint64 _frameNr; + Hero* _mainHero; + Hero* _secondHero; private: bool playNextFrame(); @@ -155,13 +172,12 @@ class PrinceEngine : public Engine { Common::Array _mobList; Common::Array _objList; + Common::Array _animList; uint16 _cameraX; uint16 _newCameraX; uint16 _sceneWidth; - Hero* _mainHero; - bool _flicLooped; void mainLoop(); diff --git a/engines/prince/resource.h b/engines/prince/resource.h new file mode 100644 index 000000000000..a5e389a37d6c --- /dev/null +++ b/engines/prince/resource.h @@ -0,0 +1,101 @@ +/* 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_RESOURCE_H +#define PRINCE_RESOURCE_H + +#include "common/stream.h" +#include "common/archive.h" +#include "common/debug-channels.h" + +namespace Prince { + +namespace Resource { + + template + bool loadFromStream(T &resource, Common::SeekableReadStream &stream) { + return resource.loadFromStream(stream); + } + + + template + bool loadResource(T *resource, const char *resourceName, bool required = true) { + Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); + if (!stream) { + if (required) + error("Can't load %s", resourceName); + return false; + } + + bool ret = loadFromStream(*resource, *stream); + + delete stream; + + return ret; + } + + template + bool loadResource(Common::Array &array, const char *resourceName, bool required = true) { + Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); + if (!stream) { + if (required) + error("Can't load %s", resourceName); + return false; + } + + T t; + while (t.loadFromStream(*stream)) + array.push_back(t); + + delete stream; + return true; + } + + template + bool loadResource(Common::Array &array, const char *resourceName, bool required = true) { + 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 initiailzed object + while (true) { + T* t = new T(); + if (!t->loadFromStream(*stream)) { + delete t; + break; + } + array.push_back(t); + } + + delete stream; + return true; + } +} + +} + +#endif + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 9daf3048ab51..3011bc78ee5d 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -25,6 +25,7 @@ #include "prince/flags.h" #include "prince/variatxt.h" #include "prince/font.h" +#include "prince/hero.h" #include "common/debug.h" #include "common/debug-channels.h" @@ -543,22 +544,23 @@ void Script::O_WALKHERO() { void Script::O_SETHERO() { uint16 hero = readScriptValue(); - uint16 x = readScriptValue(); - uint16 y = readScriptValue(); + int16 x = readScriptValue(); + int16 y = readScriptValue(); uint16 dir = readScriptValue(); debugScript("O_SETHERO hero %d, x %d, y %d, dir %d", hero, x, y, dir); + _vm->_mainHero->setPos(x, y); } void Script::O_HEROOFF() { uint16 heroId = readScriptValue(); debugScript("O_HEROOFF %d", heroId); - // sets hero visible flag to false + _vm->_mainHero->setVisible(false); } void Script::O_HEROON() { uint16 heroId = readScriptValue(); debugScript("O_HEROON %d", heroId); - // sets hero visible flag to true + _vm->_mainHero->setVisible(true); } void Script::O_CLSTEXT() { From 14566d5c271da0710fecacc2496a05d85708f70a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Tue, 10 Dec 2013 00:26:42 +0000 Subject: [PATCH 062/374] PRINCE: script code refactored --- engines/prince/prince.cpp | 36 +- engines/prince/prince.h | 4 + engines/prince/script.cpp | 1087 +++++++++++++++++++------------------ engines/prince/script.h | 77 ++- 4 files changed, 627 insertions(+), 577 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 207c60181081..687081d60c0b 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -74,10 +74,10 @@ void PrinceEngine::debugEngine(const char *s, ...) { } PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : - Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL), - _locationNr(0), _debugger(NULL), _midiPlayer(NULL), - _cameraX(0), _newCameraX(0), _frameNr(0), _cursor1(NULL), _cursor2(NULL), _font(NULL), - _walizkaBmp(NULL), _roomBmp(NULL), _cursorNr(0) { + Engine(syst), _gameDescription(gameDesc), _graph(nullptr), _script(nullptr), _interpreter(nullptr), _flags(nullptr), + _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), + _cameraX(0), _newCameraX(0), _frameNr(0), _cursor1(nullptr), _cursor2(nullptr), _font(nullptr), + _walizkaBmp(nullptr), _roomBmp(nullptr), _cursorNr(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -99,6 +99,8 @@ PrinceEngine::~PrinceEngine() { delete _cursor2; delete _midiPlayer; delete _script; + delete _flags; + delete _interpreter; delete _font; delete _roomBmp; delete _walizkaBmp; @@ -153,9 +155,12 @@ void PrinceEngine::init() { _walizkaBmp = new MhwanhDecoder(); Resource::loadResource(_walizkaBmp, "all/walizka"); - _script = new Script(this); + _script = new Script(); Resource::loadResource(_script, "all/skrypt.dat"); + _flags = new InterpreterFlags(); + _interpreter = new Interpreter(this, _script, _flags); + _variaTxt = new VariaTxt(); Resource::loadResource(_variaTxt, "all/variatxt.dat"); @@ -249,8 +254,8 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _cameraX = 0; _newCameraX = 0; - _script->setFlagValue(Flags::CURRROOM, _locationNr); - _script->stopBg(); + _flags->setFlagValue(Flags::CURRROOM, _locationNr); + _interpreter->stopBg(); changeCursor(0); @@ -290,7 +295,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { void PrinceEngine::changeCursor(uint16 curId) { _debugger->_cursorNr = curId; - const Graphics::Surface *curSurface = NULL; + const Graphics::Surface *curSurface = nullptr; uint16 hotspotX = 0; uint16 hotspotY = 0; @@ -353,7 +358,7 @@ void PrinceEngine::playSample(uint16 sampleId, uint16 loopType) { void PrinceEngine::stopSample(uint16 sampleId) { _mixer->stopID(sampleId); - _voiceStream[sampleId] = NULL; + _voiceStream[sampleId] = nullptr; } bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamName) { @@ -364,12 +369,12 @@ bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamNam debugEngine("loadSample slot %d, name %s", sampleSlot, normalizedPath.c_str()); _mixer->stopID(sampleSlot); - _voiceStream[sampleSlot] = NULL; + _voiceStream[sampleSlot] = nullptr; _voiceStream[sampleSlot] = SearchMan.createReadStreamForMember(normalizedPath); - if (_voiceStream[sampleSlot] == NULL) { + if (_voiceStream[sampleSlot] == nullptr) { error("Can't load sample %s to slot %d", normalizedPath.c_str(), sampleSlot); } - return _voiceStream[sampleSlot] == NULL; + return _voiceStream[sampleSlot] == nullptr; } bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::String &streamName) { @@ -466,7 +471,7 @@ void PrinceEngine::keyHandler(Common::Event event) { scrollCameraRight(32); break; case Common::KEYCODE_ESCAPE: - _script->setFlagValue(Flags::ESCAPED2, 1); + _flags->setFlagValue(Flags::ESCAPED2, 1); break; } } @@ -551,7 +556,7 @@ void PrinceEngine::showTexts() { --text._time; if (text._time == 0) { - text._str = NULL; + text._str = nullptr; } } } @@ -587,7 +592,6 @@ void PrinceEngine::drawScreen() { void PrinceEngine::mainLoop() { - loadLocation(4); changeCursor(0); while (!shouldQuit()) { @@ -622,7 +626,7 @@ void PrinceEngine::mainLoop() { // TODO: Update all structures, animations, naks, heros etc. - _script->step(); + _interpreter->step(); drawScreen(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index edb4f1999fed..9802769ed9a7 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -53,6 +53,8 @@ struct PrinceGameDescription; class PrinceEngine; class GraphicsMan; class Script; +class Interpreter; +class InterpreterFlags; class Debugger; class MusicPlayer; class VariaTxt; @@ -162,6 +164,8 @@ class PrinceEngine : public Engine { Debugger *_debugger; GraphicsMan *_graph; Script *_script; + InterpreterFlags *_flags; + Interpreter *_interpreter; Font *_font; MusicPlayer *_midiPlayer; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 3011bc78ee5d..afd4311ea6d4 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -39,41 +39,58 @@ namespace Prince { static const uint16 NUM_OPCODES = 144; -Script::Script(PrinceEngine *vm) : - _code(NULL), _stacktop(0), _vm(vm), _opcodeNF(false), - _waitFlag(0), _result(true) { - memset(_flags, 0, sizeof(_flags)); +Script::Script() : _data(nullptr), _dataSize(0) { } Script::~Script() { - delete[] _code; + delete[] _data; + _dataSize = 0; + _data = nullptr; +} + +bool Script::loadFromStream(Common::SeekableReadStream &stream) { + _dataSize = stream.size(); + if (!_dataSize) + return false; + + _data = new byte[_dataSize]; + + if (!_data) + return false; + + stream.read(_data, _dataSize); + + return true; +} + +InterpreterFlags::InterpreterFlags() { + resetAllFlags(); } -void Script::setFlagValue(Flags::Id flagId, uint16 value) { +void InterpreterFlags::resetAllFlags() { + memset(_flags, 0, sizeof(_flags)); +} + +void InterpreterFlags::setFlagValue(Flags::Id flagId, uint16 value) { _flags[(uint16)flagId - FLAG_MASK] = value; } -uint16 Script::getFlagValue(Flags::Id flagId) { +uint16 InterpreterFlags::getFlagValue(Flags::Id flagId) { return _flags[(uint16)flagId - FLAG_MASK]; } -bool Script::loadFromStream(Common::SeekableReadStream &stream) { - _codeSize = stream.size(); - _code = new byte[_codeSize]; - - if (!_code) - return false; +Interpreter::Interpreter(PrinceEngine *vm, Script *script, InterpreterFlags *flags) : + _vm(vm), _script(script), _flags(flags), + _stacktop(0), _opcodeNF(false), + _waitFlag(0), _result(true) { - stream.read(_code, _codeSize); // Initialize the script _mode = "fg"; - _fgOpcodePC = READ_LE_UINT32(_code + 4); + _fgOpcodePC = _script->getStartGameOffset(); _bgOpcodePC = 0; - - return true; } -void Script::debugScript(const char *s, ...) { +void Interpreter::debugInterpreter(const char *s, ...) { char buf[STRINGBUFLEN]; va_list va; @@ -88,7 +105,7 @@ void Script::debugScript(const char *s, ...) { debug("Prince::Script frame %08ld mode %s %s %s", _vm->_frameNr, _mode, str.c_str(), buf); } -void Script::step() { +void Interpreter::step() { if (_bgOpcodePC) { _mode = "bg"; _bgOpcodePC = step(_bgOpcodePC); @@ -99,14 +116,14 @@ void Script::step() { } } -uint32 Script::step(uint32 opcodePC) { +uint32 Interpreter::step(uint32 opcodePC) { _currentInstruction = opcodePC; while (!_opcodeNF) { _lastInstruction = _currentInstruction; // Get the current opcode - _lastOpcode = readScript16bits(); + _lastOpcode = readScript(); if (_lastOpcode > NUM_OPCODES) error( @@ -126,162 +143,148 @@ uint32 Script::step(uint32 opcodePC) { return _currentInstruction; } -uint8 Script::getCodeByte(uint32 address) { - if (address >= _codeSize) - error("Trying to read a script byte at address 0x%04X, while the " - "script is just 0x%04X bytes long", address, _codeSize); - return _code[address]; -} - -uint8 Script::readScript8bits() { - uint8 data = getCodeByte(_currentInstruction); - _currentInstruction++; +template +T Interpreter::readScript() { + T data = _script->read(_currentInstruction); + _currentInstruction += sizeof(data); return data; } -uint16 Script::readScript16bits() { - uint8 lower = readScript8bits(); - uint8 upper = readScript8bits(); - return lower | (upper << 8); -} - -uint16 Script::readScriptValue() { - uint16 value = readScript16bits(); - if (value & FLAG_MASK) { - return getFlagValue((Flags::Id)value); +uint16 Interpreter::readScriptValue() { + uint16 value = readScript(); + if (value & InterpreterFlags::FLAG_MASK) { + return _flags->getFlagValue((Flags::Id)value); } return value; } -uint32 Script::readScript32bits() { - uint16 lower = readScript16bits(); - uint16 upper = readScript16bits(); - return lower | (upper << 16); +Flags::Id Interpreter::readScriptFlagId() { + return (Flags::Id)readScript(); } -void Script::O_WAITFOREVER() { - debugScript("O_WAITFOREVER"); +void Interpreter::O_WAITFOREVER() { + debugInterpreter("O_WAITFOREVER"); _opcodeNF = 1; _currentInstruction -= 2; } -void Script::O_BLACKPALETTE() { - debugScript("O_BLACKPALETTE"); +void Interpreter::O_BLACKPALETTE() { + debugInterpreter("O_BLACKPALETTE"); } -void Script::O_SETUPPALETTE() { - debugScript("O_SETUPPALETTE"); +void Interpreter::O_SETUPPALETTE() { + debugInterpreter("O_SETUPPALETTE"); } -void Script::O_INITROOM() { +void Interpreter::O_INITROOM() { uint16 roomId = readScriptValue(); - debugScript("O_INITROOM %d", roomId); + debugInterpreter("O_INITROOM %d", roomId); _vm->loadLocation(roomId); _opcodeNF = 1; } -void Script::O_SETSAMPLE() { +void Interpreter::O_SETSAMPLE() { uint16 sampleId = readScriptValue(); - int32 sampleNameOffset = readScript32bits(); - const char * sampleName = (const char *)&_code[_currentInstruction + sampleNameOffset - 4]; - debugScript("O_SETSAMPLE %d %s", sampleId, sampleName); + int32 sampleNameOffset = readScript(); + const char * sampleName = _script->getString(_currentInstruction + sampleNameOffset - 4); + debugInterpreter("O_SETSAMPLE %d %s", sampleId, sampleName); _vm->loadSample(sampleId, sampleName); } -void Script::O_FREESAMPLE() { +void Interpreter::O_FREESAMPLE() { uint16 sample = readScriptValue(); - debugScript("O_FREESAMPLE %d", sample); + debugInterpreter("O_FREESAMPLE %d", sample); } -void Script::O_PLAYSAMPLE() { +void Interpreter::O_PLAYSAMPLE() { uint16 sampleId = readScriptValue(); - uint16 loopType = readScript16bits(); - debugScript("O_PLAYSAMPLE sampleId %d loopType %d", sampleId, loopType); + uint16 loopType = readScript(); + debugInterpreter("O_PLAYSAMPLE sampleId %d loopType %d", sampleId, loopType); _vm->playSample(sampleId, loopType); } -void Script::O_PUTOBJECT() { +void Interpreter::O_PUTOBJECT() { uint16 roomId = readScriptValue(); uint16 slot = readScriptValue(); uint16 objectId = readScriptValue(); - debugScript("O_PUTOBJECT roomId %d, slot %d, objectId %d", roomId, slot, objectId); + debugInterpreter("O_PUTOBJECT roomId %d, slot %d, objectId %d", roomId, slot, objectId); } -void Script::O_REMOBJECT() { +void Interpreter::O_REMOBJECT() { uint16 roomId = readScriptValue(); uint16 objectId = readScriptValue(); - debugScript("O_REMOBJECT roomId %d objectId %d", roomId, objectId); + debugInterpreter("O_REMOBJECT roomId %d objectId %d", roomId, objectId); } -void Script::O_SHOWANIM() { +void Interpreter::O_SHOWANIM() { uint16 slot = readScriptValue(); uint16 animId = readScriptValue(); - debugScript("O_SHOWANIM slot %d, animId %d", slot, animId); + debugInterpreter("O_SHOWANIM slot %d, animId %d", slot, animId); } -void Script::O_CHECKANIMEND() { +void Interpreter::O_CHECKANIMEND() { uint16 slot = readScriptValue(); uint16 frameId = readScriptValue(); - debugScript("O_CHECKANIMEND slot %d, frameId %d", slot, frameId); + debugInterpreter("O_CHECKANIMEND slot %d, frameId %d", slot, frameId); _opcodeNF = 1; } -void Script::O_FREEANIM() { +void Interpreter::O_FREEANIM() { uint16 slot = readScriptValue(); - debugScript("O_FREEANIM slot %d", slot); + debugInterpreter("O_FREEANIM slot %d", slot); } -void Script::O_CHECKANIMFRAME() { +void Interpreter::O_CHECKANIMFRAME() { uint16 slot = readScriptValue(); uint16 frameId = readScriptValue(); - debugScript("O_CHECKANIMFRAME slot %d, frameId %d", slot, frameId); + debugInterpreter("O_CHECKANIMFRAME slot %d, frameId %d", slot, frameId); _opcodeNF = 1; } -void Script::O_PUTBACKANIM() { +void Interpreter::O_PUTBACKANIM() { uint16 roomId = readScriptValue(); uint16 slot = readScriptValue(); - int32 animId = readScript32bits(); - debugScript("O_PUTBACKANIM roomId %d, slot %d, animId %d", roomId, slot, animId); + int32 animId = readScript(); + debugInterpreter("O_PUTBACKANIM roomId %d, slot %d, animId %d", roomId, slot, animId); } -void Script::O_REMBACKANIM() { +void Interpreter::O_REMBACKANIM() { uint16 roomId = readScriptValue(); uint16 slot = readScriptValue(); - debugScript("O_REMBACKANIM roomId %d, slot %d", roomId, slot); + debugInterpreter("O_REMBACKANIM roomId %d, slot %d", roomId, slot); } -void Script::O_CHECKBACKANIMFRAME() { +void Interpreter::O_CHECKBACKANIMFRAME() { uint16 slotId = readScriptValue(); uint16 frameId = readScriptValue(); - debugScript("O_CHECKBACKANIMFRAME slotId %d, frameId %d", slotId, frameId); + debugInterpreter("O_CHECKBACKANIMFRAME slotId %d, frameId %d", slotId, frameId); _opcodeNF = 1; } -void Script::O_FREEALLSAMPLES() { - debugScript("O_FREEALLSAMPLES"); +void Interpreter::O_FREEALLSAMPLES() { + debugInterpreter("O_FREEALLSAMPLES"); } -void Script::O_SETMUSIC() { - uint16 musicId = readScript16bits(); +void Interpreter::O_SETMUSIC() { + uint16 musicId = readScript(); - debugScript("O_SETMUSIC musicId %d", musicId); + debugInterpreter("O_SETMUSIC musicId %d", musicId); } -void Script::O_STOPMUSIC() { - debugScript("O_STOPMUSIC"); +void Interpreter::O_STOPMUSIC() { + debugInterpreter("O_STOPMUSIC"); } -void Script::O__WAIT() { +void Interpreter::O__WAIT() { uint16 pause = readScriptValue(); - debugScript("O__WAIT pause %d", pause); + debugInterpreter("O__WAIT pause %d", pause); if (_waitFlag == 0) { // set new wait flag value and continue @@ -300,398 +303,398 @@ void Script::O__WAIT() { } } -void Script::O_UPDATEOFF() { - debugScript("O_UPDATEOFF"); +void Interpreter::O_UPDATEOFF() { + debugInterpreter("O_UPDATEOFF"); //_updateEnable = false; } -void Script::O_UPDATEON() { - debugScript("O_UPDATEON"); +void Interpreter::O_UPDATEON() { + debugInterpreter("O_UPDATEON"); //_updateEnable = true; } -void Script::O_UPDATE () { - debugScript("O_UPDATE"); +void Interpreter::O_UPDATE () { + debugInterpreter("O_UPDATE"); // Refresh screen } -void Script::O_CLS() { - debugScript("O_CLS"); +void Interpreter::O_CLS() { + debugInterpreter("O_CLS"); // do nothing } -void Script::O__CALL() { - int32 address = readScript32bits(); +void Interpreter::O__CALL() { + int32 address = readScript(); _stack[_stacktop] = _currentInstruction; _stacktop++; _currentInstruction += address - 4; - debugScript("O__CALL 0x%04X", _currentInstruction); + debugInterpreter("O__CALL 0x%04X", _currentInstruction); } -void Script::O_RETURN() { +void Interpreter::O_RETURN() { // Get the return address if (_stacktop > 0) { _stacktop--; _currentInstruction = _stack[_stacktop]; - debugScript("O_RETURN 0x%04X", _currentInstruction); + debugInterpreter("O_RETURN 0x%04X", _currentInstruction); } else { error("Return: Stack is empty"); } } -void Script::O_GO() { - int32 opPC = readScript32bits(); - debugScript("O_GO 0x%04X", opPC); +void Interpreter::O_GO() { + int32 opPC = readScript(); + debugInterpreter("O_GO 0x%04X", opPC); _currentInstruction += opPC - 4; } -void Script::O_BACKANIMUPDATEOFF() { +void Interpreter::O_BACKANIMUPDATEOFF() { uint16 slotId = readScriptValue(); - debugScript("O_BACKANIMUPDATEOFF slotId %d", slotId); + debugInterpreter("O_BACKANIMUPDATEOFF slotId %d", slotId); } -void Script::O_BACKANIMUPDATEON() { +void Interpreter::O_BACKANIMUPDATEON() { uint16 slot = readScriptValue(); - debugScript("O_BACKANIMUPDATEON %d", slot); + debugInterpreter("O_BACKANIMUPDATEON %d", slot); } -void Script::O_CHANGECURSOR() { +void Interpreter::O_CHANGECURSOR() { uint16 cursorId = readScriptValue(); - debugScript("O_CHANGECURSOR %x", cursorId); + debugInterpreter("O_CHANGECURSOR %x", cursorId); _vm->changeCursor(cursorId); } -void Script::O_CHANGEANIMTYPE() { +void Interpreter::O_CHANGEANIMTYPE() { // NOT IMPLEMENTED } -void Script::O__SETFLAG() { +void Interpreter::O__SETFLAG() { Flags::Id flagId = readScriptFlagId(); uint16 value = readScriptValue(); - debugScript("O__SETFLAG 0x%04X (%s) = %d", flagId, Flags::getFlagName(flagId), value); + debugInterpreter("O__SETFLAG 0x%04X (%s) = %d", flagId, Flags::getFlagName(flagId), value); - setFlagValue((Flags::Id)(flagId), value); + _flags->setFlagValue((Flags::Id)(flagId), value); } -void Script::O_COMPARE() { +void Interpreter::O_COMPARE() { Flags::Id flagId = readScriptFlagId(); uint16 value = readScriptValue(); - _result = getFlagValue(flagId) != value; - debugScript("O_COMPARE flagId 0x%04X (%s), value %d == %d (%d)", flagId, Flags::getFlagName(flagId), value, getFlagValue(flagId), _result); + _result = _flags->getFlagValue(flagId) != value; + debugInterpreter("O_COMPARE flagId 0x%04X (%s), value %d == %d (%d)", flagId, Flags::getFlagName(flagId), value, _flags->getFlagValue(flagId), _result); } -void Script::O_JUMPZ() { - int32 offset = readScript32bits(); +void Interpreter::O_JUMPZ() { + int32 offset = readScript(); if (! _result) { _currentInstruction += offset - 4; } - debugScript("O_JUMPZ result = %d, next %08x, offset 0x%08X", _result, _currentInstruction, offset); + debugInterpreter("O_JUMPZ result = %d, next %08x, offset 0x%08X", _result, _currentInstruction, offset); } -void Script::O_JUMPNZ() { - int32 offset = readScript32bits(); +void Interpreter::O_JUMPNZ() { + int32 offset = readScript(); if (_result) { _currentInstruction += offset - 4; } - debugScript("O_JUMPNZ result = %d, next %08x, offset 0x%08X", _result, _currentInstruction, offset); + debugInterpreter("O_JUMPNZ result = %d, next %08x, offset 0x%08X", _result, _currentInstruction, offset); } -void Script::O_EXIT() { +void Interpreter::O_EXIT() { uint16 exitCode = readScriptValue(); - debugScript("O_EXIT exitCode %d", exitCode); + debugInterpreter("O_EXIT exitCode %d", exitCode); // Set exit code and shows credits // if exit code == 0x02EAD } -void Script::O_ADDFLAG() { +void Interpreter::O_ADDFLAG() { Flags::Id flagId = readScriptFlagId(); uint16 value = readScriptValue(); - setFlagValue(flagId, getFlagValue(flagId) + value); - if (getFlagValue(flagId)) + _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) + value); + if (_flags->getFlagValue(flagId)) _result = 1; else _result = 0; - debugScript("O_ADDFLAG flagId %04x (%s), value %d", flagId, Flags::getFlagName(flagId), value); + debugInterpreter("O_ADDFLAG flagId %04x (%s), value %d", flagId, Flags::getFlagName(flagId), value); } -void Script::O_TALKANIM() { +void Interpreter::O_TALKANIM() { uint16 animSlot = readScriptValue(); uint16 slot = readScriptValue(); - debugScript("O_TALKANIM animSlot %d, slot %d", animSlot, slot); + debugInterpreter("O_TALKANIM animSlot %d, slot %d", animSlot, slot); } -void Script::O_SUBFLAG() { +void Interpreter::O_SUBFLAG() { Flags::Id flagId = readScriptFlagId(); uint16 value = readScriptValue(); - setFlagValue(flagId, getFlagValue(flagId) - value); - if (getFlagValue(flagId)) + _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) - value); + if (_flags->getFlagValue(flagId)) _result = 1; else _result = 0; - debugScript("O_SUBFLAG flagId %d, value %d", flagId, value); + debugInterpreter("O_SUBFLAG flagId %d, value %d", flagId, value); } -void Script::O_SETSTRING() { - int32 offset = readScript32bits(); +void Interpreter::O_SETSTRING() { + int32 offset = readScript(); _currentString = offset; // FIXME: Make it better ;) if (offset >= 80000) { - debugScript("GetVaria %s", _vm->_variaTxt->getString(offset - 80000)); + debugInterpreter("GetVaria %s", _vm->_variaTxt->getString(offset - 80000)); } else if (offset < 2000) { uint32 of = READ_LE_UINT32(_vm->_talkTxt+offset*4); const char * txt = (const char *)&_vm->_talkTxt[of]; _string = &_vm->_talkTxt[of]; - debugScript("TalkTxt %d %s", of, txt); + debugInterpreter("TalkTxt %d %s", of, txt); } - debugScript("O_SETSTRING %04d", offset); + debugInterpreter("O_SETSTRING %04d", offset); } -void Script::O_ANDFLAG() { +void Interpreter::O_ANDFLAG() { Flags::Id flagId = readScriptFlagId(); uint16 value = readScriptValue(); - debugScript("O_ANDFLAG flagId %d, value %d", flagId, value); + debugInterpreter("O_ANDFLAG flagId %d, value %d", flagId, value); - setFlagValue(flagId, getFlagValue(flagId) & value); + _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) & value); - if (getFlagValue(flagId)) { + if (_flags->getFlagValue(flagId)) { _result = 1; } else { _result = 0; } } -void Script::O_GETMOBDATA() { +void Interpreter::O_GETMOBDATA() { Flags::Id flagId = readScriptFlagId(); - uint16 mobId = readScript16bits(); - uint16 mobOffset = readScript16bits(); + uint16 mobId = readScript(); + uint16 mobOffset = readScript(); - debugScript("O_GETMOBDATA flagId %d, modId %d, mobOffset %d", flagId, mobId, mobOffset); + debugInterpreter("O_GETMOBDATA flagId %d, modId %d, mobOffset %d", flagId, mobId, mobOffset); } -void Script::O_ORFLAG() { +void Interpreter::O_ORFLAG() { Flags::Id flagId = readScriptFlagId(); uint16 value = readScriptValue(); - debugScript("O_ORFLAG flagId %d, value %d", flagId, value); + debugInterpreter("O_ORFLAG flagId %d, value %d", flagId, value); - setFlagValue(flagId, getFlagValue(flagId) | value); + _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) | value); - if (getFlagValue(flagId)) { + if (_flags->getFlagValue(flagId)) { _result = 1; } else { _result = 0; } } -void Script::O_SETMOBDATA() { +void Interpreter::O_SETMOBDATA() { uint16 mobId = readScriptValue(); uint16 mobOffset = readScriptValue(); uint16 value = readScriptValue(); - debugScript("O_SETMOBDATA mobId %d, mobOffset %d, value %d", mobId, mobOffset, value); + debugInterpreter("O_SETMOBDATA mobId %d, mobOffset %d, value %d", mobId, mobOffset, value); } -void Script::O_XORFLAG() { +void Interpreter::O_XORFLAG() { Flags::Id flagId = readScriptFlagId(); uint16 value = readScriptValue(); - debugScript("O_XORFLAG flagId %d, value %d", flagId, value); + debugInterpreter("O_XORFLAG flagId %d, value %d", flagId, value); - setFlagValue(flagId, getFlagValue(flagId) ^ value); + _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) ^ value); - if (getFlagValue(flagId)) { + if (_flags->getFlagValue(flagId)) { _result = 1; } else { _result = 0; } } -void Script::O_GETMOBTEXT() { +void Interpreter::O_GETMOBTEXT() { uint16 value = readScriptValue(); - debugScript("O_GETMOBTEXT value %d", value); + debugInterpreter("O_GETMOBTEXT value %d", value); // Use Mob::ExamText as current string } -void Script::O_MOVEHERO() { +void Interpreter::O_MOVEHERO() { uint16 heroId = readScriptValue(); uint16 x = readScriptValue(); uint16 y = readScriptValue(); uint16 dir = readScriptValue(); - debugScript("O_MOVEHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); + debugInterpreter("O_MOVEHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); } -void Script::O_WALKHERO() { +void Interpreter::O_WALKHERO() { uint16 heroId = readScriptValue(); - debugScript("O_WALKHERO %d", heroId); + debugInterpreter("O_WALKHERO %d", heroId); _opcodeNF = 1; } -void Script::O_SETHERO() { +void Interpreter::O_SETHERO() { uint16 hero = readScriptValue(); int16 x = readScriptValue(); int16 y = readScriptValue(); uint16 dir = readScriptValue(); - debugScript("O_SETHERO hero %d, x %d, y %d, dir %d", hero, x, y, dir); + debugInterpreter("O_SETHERO hero %d, x %d, y %d, dir %d", hero, x, y, dir); _vm->_mainHero->setPos(x, y); } -void Script::O_HEROOFF() { +void Interpreter::O_HEROOFF() { uint16 heroId = readScriptValue(); - debugScript("O_HEROOFF %d", heroId); + debugInterpreter("O_HEROOFF %d", heroId); _vm->_mainHero->setVisible(false); } -void Script::O_HEROON() { +void Interpreter::O_HEROON() { uint16 heroId = readScriptValue(); - debugScript("O_HEROON %d", heroId); + debugInterpreter("O_HEROON %d", heroId); _vm->_mainHero->setVisible(true); } -void Script::O_CLSTEXT() { +void Interpreter::O_CLSTEXT() { uint16 slot = readScriptValue(); - debugScript("O_CLSTEXT slot %d", slot); + debugInterpreter("O_CLSTEXT slot %d", slot); // Sets text line to null // Sets text timeout to zero } -void Script::O_CALLTABLE() { - uint16 flag = readScript16bits(); - int32 table = readScript32bits(); +void Interpreter::O_CALLTABLE() { + uint16 flag = readScript(); + int32 table = readScript(); - debugScript("O_CALLTABLE flag %d, table %d", flag, table); + debugInterpreter("O_CALLTABLE flag %d, table %d", flag, table); // makes a call from script function table // must read table pointer from _code and // use table entry as next opcode } -void Script::O_CHANGEMOB() { +void Interpreter::O_CHANGEMOB() { uint16 mob = readScriptValue(); uint16 value = readScriptValue(); - debugScript("O_CHANGEMOB mob %d, value %d", mob, value); + debugInterpreter("O_CHANGEMOB mob %d, value %d", mob, value); // Probably sets mobs visible flag to value } -void Script::O_ADDINV() { +void Interpreter::O_ADDINV() { uint16 hero = readScriptValue(); uint16 item = readScriptValue(); - debugScript("O_ADDINV hero %d, item %d", hero, item); + debugInterpreter("O_ADDINV hero %d, item %d", hero, item); } -void Script::O_REMINV() { +void Interpreter::O_REMINV() { uint16 hero = readScriptValue(); uint16 item = readScriptValue(); - debugScript("O_REMINV hero %d, item %d", hero, item); + debugInterpreter("O_REMINV hero %d, item %d", hero, item); } -void Script::O_REPINV() { - uint16 hero = readScript16bits(); - uint16 item1 = readScript16bits(); - uint16 item2 = readScript16bits(); +void Interpreter::O_REPINV() { + uint16 hero = readScript(); + uint16 item1 = readScript(); + uint16 item2 = readScript(); // shouldn't be uses error("O_REPINV hero %d, item1 %d, item2 %d", hero, item1, item2); } -void Script::O_OBSOLETE_GETACTION() { +void Interpreter::O_OBSOLETE_GETACTION() { // shouldn't be uses error("O_OBSOLETE_GETACTION"); } -void Script::O_ADDWALKAREA() { - uint16 x1 = readScript16bits(); - uint16 y1 = readScript16bits(); - uint16 x2 = readScript16bits(); - uint16 y2 = readScript16bits(); +void Interpreter::O_ADDWALKAREA() { + uint16 x1 = readScript(); + uint16 y1 = readScript(); + uint16 x2 = readScript(); + uint16 y2 = readScript(); // shouldn't be uses error("O_ADDWALKAREA x1 %d, y1 %d, x2 %d, y2 %d", x1, y1, x2, y2); } -void Script::O_REMWALKAREA() { - uint16 x1 = readScript16bits(); - uint16 y1 = readScript16bits(); - uint16 x2 = readScript16bits(); - uint16 y2 = readScript16bits(); +void Interpreter::O_REMWALKAREA() { + uint16 x1 = readScript(); + uint16 y1 = readScript(); + uint16 x2 = readScript(); + uint16 y2 = readScript(); // shouldn't be uses error("O_REMWALKAREA x1 %d, y1 %d, x2 %d, y2 %d", x1, y1, x2, y2); } -void Script::O_RESTOREWALKAREA() { - debugScript("O_RESTOREWALKAREA"); +void Interpreter::O_RESTOREWALKAREA() { + debugInterpreter("O_RESTOREWALKAREA"); } -void Script::O_WAITFRAME() { - debugScript("O_WAITFRAME"); +void Interpreter::O_WAITFRAME() { + debugInterpreter("O_WAITFRAME"); _opcodeNF = true; } -void Script::O_SETFRAME() { +void Interpreter::O_SETFRAME() { uint16 anim = readScriptValue(); uint16 frame = readScriptValue(); - debugScript("O_SETFRAME anim %d, frame %d", anim, frame); + debugInterpreter("O_SETFRAME anim %d, frame %d", anim, frame); } -void Script::O_RUNACTION() { +void Interpreter::O_RUNACTION() { // It's empty in original and never used in script // it's better to report error error("O_RUNACTION"); } -void Script::O_COMPAREHI() { +void Interpreter::O_COMPAREHI() { Flags::Id flag = readScriptFlagId(); uint16 value = readScriptValue(); - debugScript("O_COMPAREHI flag %d, value %d", flag, value); - _result = value < getFlagValue(flag); + debugInterpreter("O_COMPAREHI flag %d, value %d", flag, value); + _result = value < _flags->getFlagValue(flag); } -void Script::O_COMPARELO() { +void Interpreter::O_COMPARELO() { Flags::Id flag = readScriptFlagId(); uint16 value = readScriptValue(); - debugScript("O_COMPARELO flag %d, value %d", flag, value); - _result = value > getFlagValue(flag); + debugInterpreter("O_COMPARELO flag %d, value %d", flag, value); + _result = value > _flags->getFlagValue(flag); } -void Script::O_PRELOADSET() { +void Interpreter::O_PRELOADSET() { // not used in script - int32 offset = readScript32bits(); - debugScript("O_PRELOADSET offset %04x", offset); + int32 offset = readScript(); + debugInterpreter("O_PRELOADSET offset %04x", offset); } -void Script::O_FREEPRELOAD() { +void Interpreter::O_FREEPRELOAD() { // not used in script - debugScript("O_FREEPRELOAD"); + debugInterpreter("O_FREEPRELOAD"); } -void Script::O_CHECKINV() { +void Interpreter::O_CHECKINV() { uint16 hero = readScriptValue(); uint16 item = readScriptValue(); - debugScript("O_CHECKINV hero %d, item %d", hero, item); + debugInterpreter("O_CHECKINV hero %d, item %d", hero, item); // checks if item is in heros inventory } -void Script::O_TALKHERO() { +void Interpreter::O_TALKHERO() { uint16 hero = readScriptValue(); - debugScript("O_TALKHERO hero %d", hero); + debugInterpreter("O_TALKHERO hero %d", hero); } -void Script::O_WAITTEXT() { +void Interpreter::O_WAITTEXT() { uint16 slot = readScriptValue(); Text &text = _vm->_textSlots[slot]; if (text._time) { @@ -700,36 +703,36 @@ void Script::O_WAITTEXT() { } } -void Script::O_SETHEROANIM() { +void Interpreter::O_SETHEROANIM() { uint16 hero = readScriptValue(); - int32 offset = readScript32bits(); - debugScript("O_SETHEROANIM hero %d, offset %d", hero, offset); + int32 offset = readScript(); + debugInterpreter("O_SETHEROANIM hero %d, offset %d", hero, offset); } -void Script::O_WAITHEROANIM() { +void Interpreter::O_WAITHEROANIM() { uint16 hero = readScriptValue(); - debugScript("O_WAITHEROANIM hero %d", hero); + debugInterpreter("O_WAITHEROANIM hero %d", hero); } -void Script::O_GETHERODATA() { - uint16 flag = readScript16bits(); +void Interpreter::O_GETHERODATA() { + uint16 flag = readScript(); uint16 hero = readScriptValue(); uint16 heroOffset = readScriptValue(); - debugScript("O_GETHERODATA flag %d, hero %d, heroOffset %d", flag, hero, heroOffset); + debugInterpreter("O_GETHERODATA flag %d, hero %d, heroOffset %d", flag, hero, heroOffset); } -void Script::O_GETMOUSEBUTTON() { - debugScript("O_GETMOUSEBUTTON"); +void Interpreter::O_GETMOUSEBUTTON() { + debugInterpreter("O_GETMOUSEBUTTON"); } -void Script::O_CHANGEFRAMES() { +void Interpreter::O_CHANGEFRAMES() { uint16 anim = readScriptValue(); uint16 frame = readScriptValue(); uint16 lastFrame = readScriptValue(); uint16 loopFrame = readScriptValue(); - debugScript( + debugInterpreter( "O_CHANGFRAMES anim %d, fr1 %d, fr2 %d, fr3 %d", anim, frame, @@ -738,13 +741,13 @@ void Script::O_CHANGEFRAMES() { } -void Script::O_CHANGEBACKFRAMES() { +void Interpreter::O_CHANGEBACKFRAMES() { uint16 anim = readScriptValue(); uint16 frame = readScriptValue(); uint16 lastFrame = readScriptValue(); uint16 loopFrame = readScriptValue(); - debugScript( + debugInterpreter( "O_CHANGEBACKFRAMES anim %d, fr1 %d, fr2 %d, fr3 %d", anim, frame, @@ -752,94 +755,94 @@ void Script::O_CHANGEBACKFRAMES() { loopFrame); } -void Script::O_GETBACKANIMDATA() { - uint16 flag = readScript16bits(); - uint16 anim = readScript16bits(); - uint16 animOffset = readScript16bits(); - debugScript("O_GETBACKANIMDATA flag %d, anim %d, animOffset %d", flag, anim, animOffset); +void Interpreter::O_GETBACKANIMDATA() { + uint16 flag = readScript(); + uint16 anim = readScript(); + uint16 animOffset = readScript(); + debugInterpreter("O_GETBACKANIMDATA flag %d, anim %d, animOffset %d", flag, anim, animOffset); } -void Script::O_GETANIMDATA() { - uint16 flag = readScript16bits(); +void Interpreter::O_GETANIMDATA() { + uint16 flag = readScript(); uint16 anim = readScriptValue(); uint16 animOffset = readScriptValue(); - debugScript("O_GETANIMDATA flag %d, anim %d, animOffset %d", flag, anim, animOffset); + debugInterpreter("O_GETANIMDATA flag %d, anim %d, animOffset %d", flag, anim, animOffset); // Gets value of anim data // use anim offset as attribute id not an offset } -void Script::O_SETBGCODE() { - int32 offset = readScript32bits(); +void Interpreter::O_SETBGCODE() { + int32 offset = readScript(); _bgOpcodePC = _currentInstruction + offset - 4; - debugScript("O_SETBGCODE next %08x, offset %08x", _bgOpcodePC, offset); + debugInterpreter("O_SETBGCODE next %08x, offset %08x", _bgOpcodePC, offset); } -void Script::O_SETBACKFRAME() { +void Interpreter::O_SETBACKFRAME() { uint16 anim = readScriptValue(); uint16 frame = readScriptValue(); - debugScript("O_SETBACKFRAME anim %d, frame %d", anim, frame); + debugInterpreter("O_SETBACKFRAME anim %d, frame %d", anim, frame); } -void Script::O_GETRND() { +void Interpreter::O_GETRND() { Flags::Id flag = readScriptFlagId(); - uint16 rndSeed = readScript16bits(); - debugScript("O_GETRND flag %d, rndSeed %d", flag, rndSeed); + uint16 rndSeed = readScript(); + debugInterpreter("O_GETRND flag %d, rndSeed %d", flag, rndSeed); // puts and random value as flag value // fairly random value ;) - // setFlagValue(flag, 4); + // _flags->setFlagValue(flag, 4); } -void Script::O_TALKBACKANIM() { +void Interpreter::O_TALKBACKANIM() { uint16 animSlot = readScriptValue(); uint16 slot = readScriptValue(); - debugScript("O_TALKBACKANIM animSlot %d, slot %d", animSlot, slot); + debugInterpreter("O_TALKBACKANIM animSlot %d, slot %d", animSlot, slot); } -void Script::O_LOADPATH() { - int32 offset = readScript32bits(); - debugScript("O_LOADPATH offset %d", offset); +void Interpreter::O_LOADPATH() { + int32 offset = readScript(); + debugInterpreter("O_LOADPATH offset %d", offset); // _currentInstruction + offset path file name ptr // free path bitmap // load packet path bitmap and puts in Sala } -void Script::O_GETCHAR() { +void Interpreter::O_GETCHAR() { Flags::Id flagId = readScriptFlagId(); - setFlagValue(flagId, *_string); + _flags->setFlagValue(flagId, *_string); - debugScript( + debugInterpreter( "O_GETCHAR %04X (%s) %02x", flagId, Flags::getFlagName(flagId), - getFlagValue(flagId)); + _flags->getFlagValue(flagId)); ++_string; } -void Script::O_SETDFLAG() { - uint16 flag = readScript16bits(); - int32 offset = readScript32bits(); - debugScript("O_SETDFLAG flag %d, offset %04x", flag, offset); +void Interpreter::O_SETDFLAG() { + uint16 flag = readScript(); + int32 offset = readScript(); + debugInterpreter("O_SETDFLAG flag %d, offset %04x", flag, offset); // run this through debugger looks strange // it looks like this one store two 16 bit value in one go } -void Script::O_CALLDFLAG() { - uint16 flag = readScript16bits(); - debugScript("O_CALLDFLAG flag %d", flag); +void Interpreter::O_CALLDFLAG() { + uint16 flag = readScript(); + debugInterpreter("O_CALLDFLAG flag %d", flag); // it seems that some flags are 32 bit long } -void Script::O_PRINTAT() { +void Interpreter::O_PRINTAT() { uint16 slot = readScriptValue(); uint16 fr1 = readScriptValue(); uint16 fr2 = readScriptValue(); - debugScript("O_PRINTAT slot %d, fr1 %d, fr2 %d", slot, fr1, fr2); + debugInterpreter("O_PRINTAT slot %d, fr1 %d, fr2 %d", slot, fr1, fr2); - uint8 color = getFlagValue(Flags::KOLOR); + uint8 color = _flags->getFlagValue(Flags::KOLOR); _vm->printAt(slot, color, (const char *)_string, fr1, fr2); @@ -849,214 +852,214 @@ void Script::O_PRINTAT() { ++_string; } -void Script::O_ZOOMIN() { +void Interpreter::O_ZOOMIN() { uint16 slot = readScriptValue(); - debugScript("O_ZOOMIN slot %04d", slot); + debugInterpreter("O_ZOOMIN slot %04d", slot); } -void Script::O_ZOOMOUT() { +void Interpreter::O_ZOOMOUT() { uint16 slot = readScriptValue(); - debugScript("O_ZOOMOUT slot %d", slot); + debugInterpreter("O_ZOOMOUT slot %d", slot); } -void Script::O_SETSTRINGOFFSET() { - int32 offset = readScript32bits(); - debugScript("O_SETSTRINGOFFSET offset %04x", offset); +void Interpreter::O_SETSTRINGOFFSET() { + int32 offset = readScript(); + debugInterpreter("O_SETSTRINGOFFSET offset %04x", offset); // _currentString = "" // _string = (const char *)_currentInstruction + offset } -void Script::O_GETOBJDATA() { +void Interpreter::O_GETOBJDATA() { Flags::Id flag = readScriptFlagId(); uint16 obj = readScriptValue(); int16 objOffset = readScriptValue(); - debugScript("O_GETOBJDATA flag %d, obj %d, objOffset %d", flag, obj, objOffset); + debugInterpreter("O_GETOBJDATA flag %d, obj %d, objOffset %d", flag, obj, objOffset); } -void Script::O_SETOBJDATA() { +void Interpreter::O_SETOBJDATA() { uint16 obj = readScriptValue(); int16 objOffset = readScriptValue(); uint16 value = readScriptValue(); - debugScript("O_SETOBJDATA obj %d, objOffset %d, value %d", obj, objOffset, value); + debugInterpreter("O_SETOBJDATA obj %d, objOffset %d, value %d", obj, objOffset, value); } -void Script::O_SWAPOBJECTS() { - uint16 obj1 = readScript16bits(); - uint16 obj2 = readScript16bits(); - debugScript("O_SWAPOBJECTS obj1 %d, obj2 %d", obj1, obj2); +void Interpreter::O_SWAPOBJECTS() { + uint16 obj1 = readScript(); + uint16 obj2 = readScript(); + debugInterpreter("O_SWAPOBJECTS obj1 %d, obj2 %d", obj1, obj2); } -void Script::O_CHANGEHEROSET() { +void Interpreter::O_CHANGEHEROSET() { uint16 hero = readScriptValue(); uint16 heroSet = readScriptValue(); - debugScript("O_CHANGEHEROSET hero %d, heroSet %d", hero, heroSet); + debugInterpreter("O_CHANGEHEROSET hero %d, heroSet %d", hero, heroSet); } -void Script::O_ADDSTRING() { +void Interpreter::O_ADDSTRING() { uint16 value = readScriptValue(); - debugScript("O_ADDSTRING value %d", value); + debugInterpreter("O_ADDSTRING value %d", value); // _string += value } -void Script::O_SUBSTRING() { +void Interpreter::O_SUBSTRING() { uint16 value = readScriptValue(); - debugScript("O_SUBSTRING value %d", value); + debugInterpreter("O_SUBSTRING value %d", value); // _string -= value } -void Script::O_INITDIALOG() { - debugScript("O_INITDIALOG"); +void Interpreter::O_INITDIALOG() { + debugInterpreter("O_INITDIALOG"); } -void Script::O_ENABLEDIALOGOPT() { +void Interpreter::O_ENABLEDIALOGOPT() { uint16 opt = readScriptValue(); - debugScript("O_ENABLEDIALOGOPT opt %d", opt); + debugInterpreter("O_ENABLEDIALOGOPT opt %d", opt); } -void Script::O_DISABLEDIALOGOPT() { +void Interpreter::O_DISABLEDIALOGOPT() { uint16 opt = readScriptValue(); - debugScript("O_DISABLEDIALOGOPT opt %d", opt); + debugInterpreter("O_DISABLEDIALOGOPT opt %d", opt); } -void Script::O_SHOWDIALOGBOX() { +void Interpreter::O_SHOWDIALOGBOX() { uint16 box = readScriptValue(); - debugScript("O_SHOWDIALOGBOX box %d", box); + debugInterpreter("O_SHOWDIALOGBOX box %d", box); } -void Script::O_STOPSAMPLE() { +void Interpreter::O_STOPSAMPLE() { uint16 slot = readScriptValue(); - debugScript("O_STOPSAMPLE slot %d", slot); + debugInterpreter("O_STOPSAMPLE slot %d", slot); _vm->stopSample(slot); } -void Script::O_BACKANIMRANGE() { +void Interpreter::O_BACKANIMRANGE() { uint16 slotId = readScriptValue(); - uint16 animId = readScript16bits(); + uint16 animId = readScript(); uint16 low = readScriptValue(); uint16 high = readScriptValue(); if (animId != 0xFFFF) { - if (animId & FLAG_MASK) { - animId = getFlagValue((Flags::Id)animId); + if (animId & InterpreterFlags::FLAG_MASK) { + animId = _flags->getFlagValue((Flags::Id)animId); } } - debugScript("O_BACKANIMRANGE slotId %d, animId %d, low %d, high %d", slotId, animId, low, high); + debugInterpreter("O_BACKANIMRANGE slotId %d, animId %d, low %d, high %d", slotId, animId, low, high); _result = 1; } -void Script::O_CLEARPATH() { - debugScript("O_CLEARPATH"); +void Interpreter::O_CLEARPATH() { + debugInterpreter("O_CLEARPATH"); // Fill Sala with 255 } -void Script::O_SETPATH() { - debugScript("O_SETPATH"); +void Interpreter::O_SETPATH() { + debugInterpreter("O_SETPATH"); // CopyPath } -void Script::O_GETHEROX() { +void Interpreter::O_GETHEROX() { uint16 heroId = readScriptValue(); Flags::Id flagId = readScriptFlagId(); - debugScript("O_GETHEROX heroId %d, flagId %d", heroId, flagId); + debugInterpreter("O_GETHEROX heroId %d, flagId %d", heroId, flagId); } -void Script::O_GETHEROY() { - uint16 heroId = readScript16bits(); +void Interpreter::O_GETHEROY() { + uint16 heroId = readScript(); Flags::Id flagId = readScriptFlagId(); - debugScript("O_GETHEROY heroId %d, flagId %d", heroId, flagId); + debugInterpreter("O_GETHEROY heroId %d, flagId %d", heroId, flagId); } -void Script::O_GETHEROD() { +void Interpreter::O_GETHEROD() { uint16 heroId = readScriptValue(); Flags::Id flagId = readScriptFlagId(); - debugScript("O_GETHEROD heroId %d, flagId %d", heroId, flagId); + debugInterpreter("O_GETHEROD heroId %d, flagId %d", heroId, flagId); } -void Script::O_PUSHSTRING() { - debugScript("O_PUSHSTRING"); +void Interpreter::O_PUSHSTRING() { + debugInterpreter("O_PUSHSTRING"); // push on the stack // _currentString // _dialogData // _string } -void Script::O_POPSTRING() { - debugScript("O_POPSTRING"); +void Interpreter::O_POPSTRING() { + debugInterpreter("O_POPSTRING"); // pop from the stack // _currentString // _dialogData // _string } -void Script::O_SETFGCODE() { - int32 offset = readScript32bits(); +void Interpreter::O_SETFGCODE() { + int32 offset = readScript(); _fgOpcodePC = _currentInstruction + offset - 4; - debugScript("O_SETFGCODE next %08x, offset %08x", _fgOpcodePC, offset); + debugInterpreter("O_SETFGCODE next %08x, offset %08x", _fgOpcodePC, offset); } -void Script::O_STOPHERO() { +void Interpreter::O_STOPHERO() { uint16 heroId = readScriptValue(); - debugScript("O_STOPHERO heroId %d", heroId); + debugInterpreter("O_STOPHERO heroId %d", heroId); // clear move steps for hero } -void Script::O_ANIMUPDATEOFF() { - uint16 slotId = readScript16bits(); - debugScript("O_ANIMUPDATEOFF slotId %d", slotId); +void Interpreter::O_ANIMUPDATEOFF() { + uint16 slotId = readScript(); + debugInterpreter("O_ANIMUPDATEOFF slotId %d", slotId); } -void Script::O_ANIMUPDATEON() { +void Interpreter::O_ANIMUPDATEON() { uint16 slotId = readScriptValue(); - debugScript("O_ANIMUPDATEON slotId %d", slotId); + debugInterpreter("O_ANIMUPDATEON slotId %d", slotId); } -void Script::O_FREECURSOR() { - debugScript("O_FREECURSOR"); +void Interpreter::O_FREECURSOR() { + debugInterpreter("O_FREECURSOR"); // Change cursor to 0 // free inv cursor 1 } -void Script::O_ADDINVQUIET() { +void Interpreter::O_ADDINVQUIET() { uint16 heroId = readScriptValue(); uint16 itemId = readScriptValue(); - debugScript("O_ADDINVQUIET heorId %d, itemId %d", heroId, itemId); + debugInterpreter("O_ADDINVQUIET heorId %d, itemId %d", heroId, itemId); } -void Script::O_RUNHERO() { +void Interpreter::O_RUNHERO() { uint16 heroId = readScriptValue(); uint16 x = readScriptValue(); uint16 y = readScriptValue(); uint16 dir = readScriptValue(); - debugScript("O_RUNHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); + debugInterpreter("O_RUNHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); } -void Script::O_SETBACKANIMDATA() { +void Interpreter::O_SETBACKANIMDATA() { uint16 animId = readScriptValue(); uint16 animOffset = readScriptValue(); uint16 wart = readScriptValue(); - debugScript("O_SETBACKANIMDATA animId %d, animOffset %d, wart %d", animId, animOffset, wart); + debugInterpreter("O_SETBACKANIMDATA animId %d, animOffset %d, wart %d", animId, animOffset, wart); } -void Script::O_VIEWFLC() { +void Interpreter::O_VIEWFLC() { uint16 animNr = readScriptValue(); - debugScript("O_VIEWFLC animNr %d", animNr); + debugInterpreter("O_VIEWFLC animNr %d", animNr); _vm->loadAnim(animNr, false); } -void Script::O_CHECKFLCFRAME() { +void Interpreter::O_CHECKFLCFRAME() { uint16 frameNr = readScriptValue(); - debugScript("O_CHECKFLCFRAME frame number %d", frameNr); + debugInterpreter("O_CHECKFLCFRAME frame number %d", frameNr); const Video::FlicDecoder &flicPlayer = _vm->_flicPlayer; @@ -1068,9 +1071,9 @@ void Script::O_CHECKFLCFRAME() { } } -void Script::O_CHECKFLCEND() { +void Interpreter::O_CHECKFLCEND() { - //debugScript("O_CHECKFLCEND"); + //debugInterpreter("O_CHECKFLCEND"); const Video::FlicDecoder &flicPlayer = _vm->_flicPlayer; @@ -1084,55 +1087,55 @@ void Script::O_CHECKFLCEND() { } } -void Script::O_FREEFLC() { - debugScript("O_FREEFLC"); +void Interpreter::O_FREEFLC() { + debugInterpreter("O_FREEFLC"); } -void Script::O_TALKHEROSTOP() { +void Interpreter::O_TALKHEROSTOP() { uint16 heroId = readScriptValue(); - debugScript("O_TALKHEROSTOP %d", heroId); + debugInterpreter("O_TALKHEROSTOP %d", heroId); } -void Script::O_HEROCOLOR() { +void Interpreter::O_HEROCOLOR() { uint16 heroId = readScriptValue(); uint16 kolorr = readScriptValue(); - debugScript("O_HEROCOLOR heroId %d, kolorr %d", heroId, kolorr); + debugInterpreter("O_HEROCOLOR heroId %d, kolorr %d", heroId, kolorr); } -void Script::O_GRABMAPA() { - debugScript("O_GRABMAPA"); +void Interpreter::O_GRABMAPA() { + debugInterpreter("O_GRABMAPA"); } -void Script::O_ENABLENAK() { +void Interpreter::O_ENABLENAK() { uint16 nakId = readScriptValue(); - debugScript("O_ENABLENAK nakId %d", nakId); + debugInterpreter("O_ENABLENAK nakId %d", nakId); } -void Script::O_DISABLENAK() { +void Interpreter::O_DISABLENAK() { uint16 nakId = readScriptValue(); - debugScript("O_DISABLENAK nakId %d", nakId); + debugInterpreter("O_DISABLENAK nakId %d", nakId); } -void Script::O_GETMOBNAME() { +void Interpreter::O_GETMOBNAME() { uint16 war = readScriptValue(); - debugScript("O_GETMOBNAME war %d", war); + debugInterpreter("O_GETMOBNAME war %d", war); } -void Script::O_SWAPINVENTORY() { +void Interpreter::O_SWAPINVENTORY() { uint16 heroId = readScriptValue(); - debugScript("O_SWAPINVENTORY heroId %d", heroId); + debugInterpreter("O_SWAPINVENTORY heroId %d", heroId); } -void Script::O_CLEARINVENTORY() { +void Interpreter::O_CLEARINVENTORY() { uint16 heroId = readScriptValue(); - debugScript("O_CLEARINVENTORY heroId %d", heroId); + debugInterpreter("O_CLEARINVENTORY heroId %d", heroId); } -void Script::O_SKIPTEXT() { - debugScript("O_SKIPTEXT"); +void Interpreter::O_SKIPTEXT() { + debugInterpreter("O_SKIPTEXT"); } -void Script::SetVoice(uint32 sampleSlot) { +void Interpreter::SetVoice(uint32 sampleSlot) { // TODO: use sample slot uint16 slot = readScriptValue(); _vm->loadVoice( @@ -1141,227 +1144,227 @@ void Script::SetVoice(uint32 sampleSlot) { Common::String::format( "%03d-%02d.WAV", _currentString, - getFlagValue(Flags::VOICE_H_LINE) + _flags->getFlagValue(Flags::VOICE_H_LINE) ) ); } -void Script::O_SETVOICEH() { +void Interpreter::O_SETVOICEH() { static const uint32 VOICE_H_SLOT = 28; SetVoice(VOICE_H_SLOT); } -void Script::O_SETVOICEA() { +void Interpreter::O_SETVOICEA() { static const uint32 VOICE_A_SLOT = 29; SetVoice(VOICE_A_SLOT); } -void Script::O_SETVOICEB() { +void Interpreter::O_SETVOICEB() { static const uint32 VOICE_B_SLOT = 30; SetVoice(VOICE_B_SLOT); } -void Script::O_SETVOICEC() { +void Interpreter::O_SETVOICEC() { static const uint32 VOICE_C_SLOT = 31; SetVoice(VOICE_C_SLOT); } -void Script::O_SETVOICED() { +void Interpreter::O_SETVOICED() { static const uint32 VOICE_D_SLOT = 32; SetVoice(VOICE_D_SLOT); } -void Script::O_VIEWFLCLOOP() { +void Interpreter::O_VIEWFLCLOOP() { uint16 value = readScriptValue(); - debugScript("O_VIEWFLCLOOP animId %d", value); + debugInterpreter("O_VIEWFLCLOOP animId %d", value); _vm->loadAnim(value, true); } -void Script::O_FLCSPEED() { +void Interpreter::O_FLCSPEED() { uint16 speed = readScriptValue(); - debugScript("O_FLCSPEED speed %d", speed); + debugInterpreter("O_FLCSPEED speed %d", speed); } -void Script::O_OPENINVENTORY() { - debugScript("O_OPENINVENTORY"); +void Interpreter::O_OPENINVENTORY() { + debugInterpreter("O_OPENINVENTORY"); _opcodeNF = 1; // _showInventoryFlag = true } -void Script::O_KRZYWA() { - debugScript("O_KRZYWA"); +void Interpreter::O_KRZYWA() { + debugInterpreter("O_KRZYWA"); } -void Script::O_GETKRZYWA() { - debugScript("O_GETKRZYWA"); - // setFlagValue(Flags::TORX1, krzywa[_krzywaIndex++]) - // setFlagValue(Flags::TORY1, krzywa[_krzywaIndex++]) +void Interpreter::O_GETKRZYWA() { + debugInterpreter("O_GETKRZYWA"); + // _flags->setFlagValue(Flags::TORX1, krzywa[_krzywaIndex++]) + // _flags->setFlagValue(Flags::TORY1, krzywa[_krzywaIndex++]) // Check _krzywaIndex } -void Script::O_GETMOB() { +void Interpreter::O_GETMOB() { Flags::Id flagId = readScriptFlagId(); uint16 mx = readScriptValue(); uint16 my = readScriptValue(); - debugScript("O_GETMOB flagId %d, mx %d, my %d", flagId, mx, my); + debugInterpreter("O_GETMOB flagId %d, mx %d, my %d", flagId, mx, my); // check if current mob pos = (mx, my) } -void Script::O_INPUTLINE() { - debugScript("O_INPUTLINE"); -} - - -void Script::O_BREAK_POINT() { - debugScript("O_BREAK_POINT"); -} - -Script::OpcodeFunc Script::_opcodes[NUM_OPCODES] = { - &Script::O_WAITFOREVER, - &Script::O_BLACKPALETTE, - &Script::O_SETUPPALETTE, - &Script::O_INITROOM, - &Script::O_SETSAMPLE, - &Script::O_FREESAMPLE, - &Script::O_PLAYSAMPLE, - &Script::O_PUTOBJECT, - &Script::O_REMOBJECT, - &Script::O_SHOWANIM, - &Script::O_CHECKANIMEND, - &Script::O_FREEANIM, - &Script::O_CHECKANIMFRAME, - &Script::O_PUTBACKANIM, - &Script::O_REMBACKANIM, - &Script::O_CHECKBACKANIMFRAME, - &Script::O_FREEALLSAMPLES, - &Script::O_SETMUSIC, - &Script::O_STOPMUSIC, - &Script::O__WAIT, - &Script::O_UPDATEOFF, - &Script::O_UPDATEON, - &Script::O_UPDATE , - &Script::O_CLS, - &Script::O__CALL, - &Script::O_RETURN, - &Script::O_GO, - &Script::O_BACKANIMUPDATEOFF, - &Script::O_BACKANIMUPDATEON, - &Script::O_CHANGECURSOR, - &Script::O_CHANGEANIMTYPE, - &Script::O__SETFLAG, - &Script::O_COMPARE, - &Script::O_JUMPZ, - &Script::O_JUMPNZ, - &Script::O_EXIT, - &Script::O_ADDFLAG, - &Script::O_TALKANIM, - &Script::O_SUBFLAG, - &Script::O_SETSTRING, - &Script::O_ANDFLAG, - &Script::O_GETMOBDATA, - &Script::O_ORFLAG, - &Script::O_SETMOBDATA, - &Script::O_XORFLAG, - &Script::O_GETMOBTEXT, - &Script::O_MOVEHERO, - &Script::O_WALKHERO, - &Script::O_SETHERO, - &Script::O_HEROOFF, - &Script::O_HEROON, - &Script::O_CLSTEXT, - &Script::O_CALLTABLE, - &Script::O_CHANGEMOB, - &Script::O_ADDINV, - &Script::O_REMINV, - &Script::O_REPINV, - &Script::O_OBSOLETE_GETACTION, - &Script::O_ADDWALKAREA, - &Script::O_REMWALKAREA, - &Script::O_RESTOREWALKAREA, - &Script::O_WAITFRAME, - &Script::O_SETFRAME, - &Script::O_RUNACTION, - &Script::O_COMPAREHI, - &Script::O_COMPARELO, - &Script::O_PRELOADSET, - &Script::O_FREEPRELOAD, - &Script::O_CHECKINV, - &Script::O_TALKHERO, - &Script::O_WAITTEXT, - &Script::O_SETHEROANIM, - &Script::O_WAITHEROANIM, - &Script::O_GETHERODATA, - &Script::O_GETMOUSEBUTTON, - &Script::O_CHANGEFRAMES, - &Script::O_CHANGEBACKFRAMES, - &Script::O_GETBACKANIMDATA, - &Script::O_GETANIMDATA, - &Script::O_SETBGCODE, - &Script::O_SETBACKFRAME, - &Script::O_GETRND, - &Script::O_TALKBACKANIM, - &Script::O_LOADPATH, - &Script::O_GETCHAR, - &Script::O_SETDFLAG, - &Script::O_CALLDFLAG, - &Script::O_PRINTAT, - &Script::O_ZOOMIN, - &Script::O_ZOOMOUT, - &Script::O_SETSTRINGOFFSET, - &Script::O_GETOBJDATA, - &Script::O_SETOBJDATA, - &Script::O_SWAPOBJECTS, - &Script::O_CHANGEHEROSET, - &Script::O_ADDSTRING, - &Script::O_SUBSTRING, - &Script::O_INITDIALOG, - &Script::O_ENABLEDIALOGOPT, - &Script::O_DISABLEDIALOGOPT, - &Script::O_SHOWDIALOGBOX, - &Script::O_STOPSAMPLE, - &Script::O_BACKANIMRANGE, - &Script::O_CLEARPATH, - &Script::O_SETPATH, - &Script::O_GETHEROX, - &Script::O_GETHEROY, - &Script::O_GETHEROD, - &Script::O_PUSHSTRING, - &Script::O_POPSTRING, - &Script::O_SETFGCODE, - &Script::O_STOPHERO, - &Script::O_ANIMUPDATEOFF, - &Script::O_ANIMUPDATEON, - &Script::O_FREECURSOR, - &Script::O_ADDINVQUIET, - &Script::O_RUNHERO, - &Script::O_SETBACKANIMDATA, - &Script::O_VIEWFLC, - &Script::O_CHECKFLCFRAME, - &Script::O_CHECKFLCEND, - &Script::O_FREEFLC, - &Script::O_TALKHEROSTOP, - &Script::O_HEROCOLOR, - &Script::O_GRABMAPA, - &Script::O_ENABLENAK, - &Script::O_DISABLENAK, - &Script::O_GETMOBNAME, - &Script::O_SWAPINVENTORY, - &Script::O_CLEARINVENTORY, - &Script::O_SKIPTEXT, - &Script::O_SETVOICEH, - &Script::O_SETVOICEA, - &Script::O_SETVOICEB, - &Script::O_SETVOICEC, - &Script::O_VIEWFLCLOOP, - &Script::O_FLCSPEED, - &Script::O_OPENINVENTORY, - &Script::O_KRZYWA, - &Script::O_GETKRZYWA, - &Script::O_GETMOB, - &Script::O_INPUTLINE, - &Script::O_SETVOICED, - &Script::O_BREAK_POINT, +void Interpreter::O_INPUTLINE() { + debugInterpreter("O_INPUTLINE"); +} + + +void Interpreter::O_BREAK_POINT() { + debugInterpreter("O_BREAK_POINT"); +} + +Interpreter::OpcodeFunc Interpreter::_opcodes[NUM_OPCODES] = { + &Interpreter::O_WAITFOREVER, + &Interpreter::O_BLACKPALETTE, + &Interpreter::O_SETUPPALETTE, + &Interpreter::O_INITROOM, + &Interpreter::O_SETSAMPLE, + &Interpreter::O_FREESAMPLE, + &Interpreter::O_PLAYSAMPLE, + &Interpreter::O_PUTOBJECT, + &Interpreter::O_REMOBJECT, + &Interpreter::O_SHOWANIM, + &Interpreter::O_CHECKANIMEND, + &Interpreter::O_FREEANIM, + &Interpreter::O_CHECKANIMFRAME, + &Interpreter::O_PUTBACKANIM, + &Interpreter::O_REMBACKANIM, + &Interpreter::O_CHECKBACKANIMFRAME, + &Interpreter::O_FREEALLSAMPLES, + &Interpreter::O_SETMUSIC, + &Interpreter::O_STOPMUSIC, + &Interpreter::O__WAIT, + &Interpreter::O_UPDATEOFF, + &Interpreter::O_UPDATEON, + &Interpreter::O_UPDATE , + &Interpreter::O_CLS, + &Interpreter::O__CALL, + &Interpreter::O_RETURN, + &Interpreter::O_GO, + &Interpreter::O_BACKANIMUPDATEOFF, + &Interpreter::O_BACKANIMUPDATEON, + &Interpreter::O_CHANGECURSOR, + &Interpreter::O_CHANGEANIMTYPE, + &Interpreter::O__SETFLAG, + &Interpreter::O_COMPARE, + &Interpreter::O_JUMPZ, + &Interpreter::O_JUMPNZ, + &Interpreter::O_EXIT, + &Interpreter::O_ADDFLAG, + &Interpreter::O_TALKANIM, + &Interpreter::O_SUBFLAG, + &Interpreter::O_SETSTRING, + &Interpreter::O_ANDFLAG, + &Interpreter::O_GETMOBDATA, + &Interpreter::O_ORFLAG, + &Interpreter::O_SETMOBDATA, + &Interpreter::O_XORFLAG, + &Interpreter::O_GETMOBTEXT, + &Interpreter::O_MOVEHERO, + &Interpreter::O_WALKHERO, + &Interpreter::O_SETHERO, + &Interpreter::O_HEROOFF, + &Interpreter::O_HEROON, + &Interpreter::O_CLSTEXT, + &Interpreter::O_CALLTABLE, + &Interpreter::O_CHANGEMOB, + &Interpreter::O_ADDINV, + &Interpreter::O_REMINV, + &Interpreter::O_REPINV, + &Interpreter::O_OBSOLETE_GETACTION, + &Interpreter::O_ADDWALKAREA, + &Interpreter::O_REMWALKAREA, + &Interpreter::O_RESTOREWALKAREA, + &Interpreter::O_WAITFRAME, + &Interpreter::O_SETFRAME, + &Interpreter::O_RUNACTION, + &Interpreter::O_COMPAREHI, + &Interpreter::O_COMPARELO, + &Interpreter::O_PRELOADSET, + &Interpreter::O_FREEPRELOAD, + &Interpreter::O_CHECKINV, + &Interpreter::O_TALKHERO, + &Interpreter::O_WAITTEXT, + &Interpreter::O_SETHEROANIM, + &Interpreter::O_WAITHEROANIM, + &Interpreter::O_GETHERODATA, + &Interpreter::O_GETMOUSEBUTTON, + &Interpreter::O_CHANGEFRAMES, + &Interpreter::O_CHANGEBACKFRAMES, + &Interpreter::O_GETBACKANIMDATA, + &Interpreter::O_GETANIMDATA, + &Interpreter::O_SETBGCODE, + &Interpreter::O_SETBACKFRAME, + &Interpreter::O_GETRND, + &Interpreter::O_TALKBACKANIM, + &Interpreter::O_LOADPATH, + &Interpreter::O_GETCHAR, + &Interpreter::O_SETDFLAG, + &Interpreter::O_CALLDFLAG, + &Interpreter::O_PRINTAT, + &Interpreter::O_ZOOMIN, + &Interpreter::O_ZOOMOUT, + &Interpreter::O_SETSTRINGOFFSET, + &Interpreter::O_GETOBJDATA, + &Interpreter::O_SETOBJDATA, + &Interpreter::O_SWAPOBJECTS, + &Interpreter::O_CHANGEHEROSET, + &Interpreter::O_ADDSTRING, + &Interpreter::O_SUBSTRING, + &Interpreter::O_INITDIALOG, + &Interpreter::O_ENABLEDIALOGOPT, + &Interpreter::O_DISABLEDIALOGOPT, + &Interpreter::O_SHOWDIALOGBOX, + &Interpreter::O_STOPSAMPLE, + &Interpreter::O_BACKANIMRANGE, + &Interpreter::O_CLEARPATH, + &Interpreter::O_SETPATH, + &Interpreter::O_GETHEROX, + &Interpreter::O_GETHEROY, + &Interpreter::O_GETHEROD, + &Interpreter::O_PUSHSTRING, + &Interpreter::O_POPSTRING, + &Interpreter::O_SETFGCODE, + &Interpreter::O_STOPHERO, + &Interpreter::O_ANIMUPDATEOFF, + &Interpreter::O_ANIMUPDATEON, + &Interpreter::O_FREECURSOR, + &Interpreter::O_ADDINVQUIET, + &Interpreter::O_RUNHERO, + &Interpreter::O_SETBACKANIMDATA, + &Interpreter::O_VIEWFLC, + &Interpreter::O_CHECKFLCFRAME, + &Interpreter::O_CHECKFLCEND, + &Interpreter::O_FREEFLC, + &Interpreter::O_TALKHEROSTOP, + &Interpreter::O_HEROCOLOR, + &Interpreter::O_GRABMAPA, + &Interpreter::O_ENABLENAK, + &Interpreter::O_DISABLENAK, + &Interpreter::O_GETMOBNAME, + &Interpreter::O_SWAPINVENTORY, + &Interpreter::O_CLEARINVENTORY, + &Interpreter::O_SKIPTEXT, + &Interpreter::O_SETVOICEH, + &Interpreter::O_SETVOICEA, + &Interpreter::O_SETVOICEB, + &Interpreter::O_SETVOICEC, + &Interpreter::O_VIEWFLCLOOP, + &Interpreter::O_FLCSPEED, + &Interpreter::O_OPENINVENTORY, + &Interpreter::O_KRZYWA, + &Interpreter::O_GETKRZYWA, + &Interpreter::O_GETMOB, + &Interpreter::O_INPUTLINE, + &Interpreter::O_SETVOICED, + &Interpreter::O_BREAK_POINT, }; } diff --git a/engines/prince/script.h b/engines/prince/script.h index d9b42baf3932..386951a0c9f5 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -24,6 +24,7 @@ #define PRINCE_SCRIPT_H #include "common/random.h" +#include "common/endian.h" #include "audio/mixer.h" @@ -37,25 +38,68 @@ namespace Prince { class PrinceEngine; +namespace Detail { + template T LittleEndianReader(void *data); + template <> inline uint8 LittleEndianReader(void *data) { return *(uint8*)(data); } + template <> inline uint16 LittleEndianReader(void *data) { return READ_LE_UINT16(data); } + template <> inline uint32 LittleEndianReader(void *data) { return READ_LE_UINT32(data); } +} + class Script { public: - Script(PrinceEngine *vm); - virtual ~Script(); + Script(); + ~Script(); bool loadFromStream(Common::SeekableReadStream &stream); - void step(); + template + T read(uint32 address) { + assert((_data + address + sizeof(T)) <= (_data + _dataSize)); + return Detail::LittleEndianReader(&_data[address]); + } + + // Some magic numbers for now, data stored in header + uint32 getRoomTableOffset() { return read(0); } + uint32 getStartGameOffset() { return read(4); } + + const char *getString(uint32 offset) { + return (const char *)(&_data[offset]); + } + +private: + uint8 *_data; + uint32 _dataSize; +}; + +class InterpreterFlags { +public: + InterpreterFlags(); void setFlagValue(Flags::Id flag, uint16 value); uint16 getFlagValue(Flags::Id flag); + void resetAllFlags(); + + static const uint16 FLAG_MASK = 0x8000; + +private: + static const uint16 MAX_FLAGS = 2000; + int16 _flags[MAX_FLAGS]; +}; + +class Interpreter { +public: + Interpreter(PrinceEngine *vm, Script *script, InterpreterFlags *flags); + void stopBg() { _bgOpcodePC = 0; } + void step(); + private: PrinceEngine *_vm; + Script *_script; + InterpreterFlags *_flags; - byte *_code; - uint32 _codeSize; uint32 _currentInstruction; uint32 _bgOpcodePC; @@ -64,13 +108,9 @@ class Script { uint16 _lastOpcode; uint32 _lastInstruction; byte _result; - static const uint16 MAX_FLAGS = 2000; - static const uint16 FLAG_MASK = 0x8000; - int16 _flags[MAX_FLAGS]; - bool _opcodeNF; + bool _opcodeNF; // break interpreter loop - // Stack static const uint32 _STACK_SIZE = 500; uint32 _stack[_STACK_SIZE]; uint8 _stacktop; @@ -83,21 +123,19 @@ class Script { // Helper functions uint32 step(uint32 opcodePC); - void checkPC(uint32 address); - uint8 getCodeByte(uint32 address); - uint8 readScript8bits(); - uint16 readScript16bits(); - uint32 readScript32bits(); - uint16 readScript8or16bits(); + void checkPC(uint32 address); uint16 readScriptValue(); - Flags::Id readScriptFlagId() { return (Flags::Id)readScript16bits(); } + Flags::Id readScriptFlagId(); + + // instantiation not needed here + template T readScript(); - void debugScript(const char *s, ...); + void debugInterpreter(const char *s, ...); void SetVoice(uint32 slot); - typedef void (Script::*OpcodeFunc)(); + typedef void (Interpreter::*OpcodeFunc)(); static OpcodeFunc _opcodes[]; // Keep opcode handlers names as they are in original code @@ -246,6 +284,7 @@ class Script { void O_INPUTLINE(); void O_SETVOICED(); void O_BREAK_POINT(); + }; } From 0a05365e1dc46a0ef6dbbac1d5c839aa56a6c0ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Tue, 10 Dec 2013 00:32:07 +0000 Subject: [PATCH 063/374] PRINCE: small script refactoring --- engines/prince/script.cpp | 273 +++++++++++++++++++------------------- engines/prince/script.h | 2 +- 2 files changed, 136 insertions(+), 139 deletions(-) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index afd4311ea6d4..ce250f1c5a79 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -150,7 +150,7 @@ T Interpreter::readScript() { return data; } -uint16 Interpreter::readScriptValue() { +uint16 Interpreter::readScriptFlagValue() { uint16 value = readScript(); if (value & InterpreterFlags::FLAG_MASK) { return _flags->getFlagValue((Flags::Id)value); @@ -177,14 +177,14 @@ void Interpreter::O_SETUPPALETTE() { } void Interpreter::O_INITROOM() { - uint16 roomId = readScriptValue(); + uint16 roomId = readScriptFlagValue(); debugInterpreter("O_INITROOM %d", roomId); _vm->loadLocation(roomId); _opcodeNF = 1; } void Interpreter::O_SETSAMPLE() { - uint16 sampleId = readScriptValue(); + uint16 sampleId = readScriptFlagValue(); int32 sampleNameOffset = readScript(); const char * sampleName = _script->getString(_currentInstruction + sampleNameOffset - 4); debugInterpreter("O_SETSAMPLE %d %s", sampleId, sampleName); @@ -192,76 +192,76 @@ void Interpreter::O_SETSAMPLE() { } void Interpreter::O_FREESAMPLE() { - uint16 sample = readScriptValue(); + uint16 sample = readScriptFlagValue(); debugInterpreter("O_FREESAMPLE %d", sample); } void Interpreter::O_PLAYSAMPLE() { - uint16 sampleId = readScriptValue(); + uint16 sampleId = readScriptFlagValue(); uint16 loopType = readScript(); debugInterpreter("O_PLAYSAMPLE sampleId %d loopType %d", sampleId, loopType); _vm->playSample(sampleId, loopType); } void Interpreter::O_PUTOBJECT() { - uint16 roomId = readScriptValue(); - uint16 slot = readScriptValue(); - uint16 objectId = readScriptValue(); + uint16 roomId = readScriptFlagValue(); + uint16 slot = readScriptFlagValue(); + uint16 objectId = readScriptFlagValue(); debugInterpreter("O_PUTOBJECT roomId %d, slot %d, objectId %d", roomId, slot, objectId); } void Interpreter::O_REMOBJECT() { - uint16 roomId = readScriptValue(); - uint16 objectId = readScriptValue(); + uint16 roomId = readScriptFlagValue(); + uint16 objectId = readScriptFlagValue(); debugInterpreter("O_REMOBJECT roomId %d objectId %d", roomId, objectId); } void Interpreter::O_SHOWANIM() { - uint16 slot = readScriptValue(); - uint16 animId = readScriptValue(); + uint16 slot = readScriptFlagValue(); + uint16 animId = readScriptFlagValue(); debugInterpreter("O_SHOWANIM slot %d, animId %d", slot, animId); } void Interpreter::O_CHECKANIMEND() { - uint16 slot = readScriptValue(); - uint16 frameId = readScriptValue(); + uint16 slot = readScriptFlagValue(); + uint16 frameId = readScriptFlagValue(); debugInterpreter("O_CHECKANIMEND slot %d, frameId %d", slot, frameId); _opcodeNF = 1; } void Interpreter::O_FREEANIM() { - uint16 slot = readScriptValue(); + uint16 slot = readScriptFlagValue(); debugInterpreter("O_FREEANIM slot %d", slot); } void Interpreter::O_CHECKANIMFRAME() { - uint16 slot = readScriptValue(); - uint16 frameId = readScriptValue(); + uint16 slot = readScriptFlagValue(); + uint16 frameId = readScriptFlagValue(); debugInterpreter("O_CHECKANIMFRAME slot %d, frameId %d", slot, frameId); _opcodeNF = 1; } void Interpreter::O_PUTBACKANIM() { - uint16 roomId = readScriptValue(); - uint16 slot = readScriptValue(); + uint16 roomId = readScriptFlagValue(); + uint16 slot = readScriptFlagValue(); int32 animId = readScript(); debugInterpreter("O_PUTBACKANIM roomId %d, slot %d, animId %d", roomId, slot, animId); } void Interpreter::O_REMBACKANIM() { - uint16 roomId = readScriptValue(); - uint16 slot = readScriptValue(); + uint16 roomId = readScriptFlagValue(); + uint16 slot = readScriptFlagValue(); debugInterpreter("O_REMBACKANIM roomId %d, slot %d", roomId, slot); } void Interpreter::O_CHECKBACKANIMFRAME() { - uint16 slotId = readScriptValue(); - uint16 frameId = readScriptValue(); + uint16 slotId = readScriptFlagValue(); + uint16 frameId = readScriptFlagValue(); debugInterpreter("O_CHECKBACKANIMFRAME slotId %d, frameId %d", slotId, frameId); _opcodeNF = 1; @@ -282,7 +282,7 @@ void Interpreter::O_STOPMUSIC() { } void Interpreter::O__WAIT() { - uint16 pause = readScriptValue(); + uint16 pause = readScriptFlagValue(); debugInterpreter("O__WAIT pause %d", pause); @@ -349,17 +349,17 @@ void Interpreter::O_GO() { } void Interpreter::O_BACKANIMUPDATEOFF() { - uint16 slotId = readScriptValue(); + uint16 slotId = readScriptFlagValue(); debugInterpreter("O_BACKANIMUPDATEOFF slotId %d", slotId); } void Interpreter::O_BACKANIMUPDATEON() { - uint16 slot = readScriptValue(); + uint16 slot = readScriptFlagValue(); debugInterpreter("O_BACKANIMUPDATEON %d", slot); } void Interpreter::O_CHANGECURSOR() { - uint16 cursorId = readScriptValue(); + uint16 cursorId = readScriptFlagValue(); debugInterpreter("O_CHANGECURSOR %x", cursorId); _vm->changeCursor(cursorId); } @@ -370,7 +370,7 @@ void Interpreter::O_CHANGEANIMTYPE() { void Interpreter::O__SETFLAG() { Flags::Id flagId = readScriptFlagId(); - uint16 value = readScriptValue(); + uint16 value = readScriptFlagValue(); debugInterpreter("O__SETFLAG 0x%04X (%s) = %d", flagId, Flags::getFlagName(flagId), value); @@ -379,7 +379,7 @@ void Interpreter::O__SETFLAG() { void Interpreter::O_COMPARE() { Flags::Id flagId = readScriptFlagId(); - uint16 value = readScriptValue(); + uint16 value = readScriptFlagValue(); _result = _flags->getFlagValue(flagId) != value; debugInterpreter("O_COMPARE flagId 0x%04X (%s), value %d == %d (%d)", flagId, Flags::getFlagName(flagId), value, _flags->getFlagValue(flagId), _result); @@ -404,7 +404,7 @@ void Interpreter::O_JUMPNZ() { } void Interpreter::O_EXIT() { - uint16 exitCode = readScriptValue(); + uint16 exitCode = readScriptFlagValue(); debugInterpreter("O_EXIT exitCode %d", exitCode); // Set exit code and shows credits // if exit code == 0x02EAD @@ -412,7 +412,7 @@ void Interpreter::O_EXIT() { void Interpreter::O_ADDFLAG() { Flags::Id flagId = readScriptFlagId(); - uint16 value = readScriptValue(); + uint16 value = readScriptFlagValue(); _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) + value); if (_flags->getFlagValue(flagId)) @@ -424,15 +424,15 @@ void Interpreter::O_ADDFLAG() { } void Interpreter::O_TALKANIM() { - uint16 animSlot = readScriptValue(); - uint16 slot = readScriptValue(); + uint16 animSlot = readScriptFlagValue(); + uint16 slot = readScriptFlagValue(); debugInterpreter("O_TALKANIM animSlot %d, slot %d", animSlot, slot); } void Interpreter::O_SUBFLAG() { Flags::Id flagId = readScriptFlagId(); - uint16 value = readScriptValue(); + uint16 value = readScriptFlagValue(); _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) - value); if (_flags->getFlagValue(flagId)) @@ -463,7 +463,7 @@ void Interpreter::O_SETSTRING() { void Interpreter::O_ANDFLAG() { Flags::Id flagId = readScriptFlagId(); - uint16 value = readScriptValue(); + uint16 value = readScriptFlagValue(); debugInterpreter("O_ANDFLAG flagId %d, value %d", flagId, value); @@ -486,7 +486,7 @@ void Interpreter::O_GETMOBDATA() { void Interpreter::O_ORFLAG() { Flags::Id flagId = readScriptFlagId(); - uint16 value = readScriptValue(); + uint16 value = readScriptFlagValue(); debugInterpreter("O_ORFLAG flagId %d, value %d", flagId, value); @@ -500,16 +500,16 @@ void Interpreter::O_ORFLAG() { } void Interpreter::O_SETMOBDATA() { - uint16 mobId = readScriptValue(); - uint16 mobOffset = readScriptValue(); - uint16 value = readScriptValue(); + uint16 mobId = readScriptFlagValue(); + uint16 mobOffset = readScriptFlagValue(); + uint16 value = readScriptFlagValue(); debugInterpreter("O_SETMOBDATA mobId %d, mobOffset %d, value %d", mobId, mobOffset, value); } void Interpreter::O_XORFLAG() { Flags::Id flagId = readScriptFlagId(); - uint16 value = readScriptValue(); + uint16 value = readScriptFlagValue(); debugInterpreter("O_XORFLAG flagId %d, value %d", flagId, value); @@ -523,51 +523,51 @@ void Interpreter::O_XORFLAG() { } void Interpreter::O_GETMOBTEXT() { - uint16 value = readScriptValue(); + uint16 value = readScriptFlagValue(); debugInterpreter("O_GETMOBTEXT value %d", value); // Use Mob::ExamText as current string } void Interpreter::O_MOVEHERO() { - uint16 heroId = readScriptValue(); - uint16 x = readScriptValue(); - uint16 y = readScriptValue(); - uint16 dir = readScriptValue(); + uint16 heroId = readScriptFlagValue(); + uint16 x = readScriptFlagValue(); + uint16 y = readScriptFlagValue(); + uint16 dir = readScriptFlagValue(); debugInterpreter("O_MOVEHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); } void Interpreter::O_WALKHERO() { - uint16 heroId = readScriptValue(); + uint16 heroId = readScriptFlagValue(); debugInterpreter("O_WALKHERO %d", heroId); _opcodeNF = 1; } void Interpreter::O_SETHERO() { - uint16 hero = readScriptValue(); - int16 x = readScriptValue(); - int16 y = readScriptValue(); - uint16 dir = readScriptValue(); + uint16 hero = readScriptFlagValue(); + int16 x = readScriptFlagValue(); + int16 y = readScriptFlagValue(); + uint16 dir = readScriptFlagValue(); debugInterpreter("O_SETHERO hero %d, x %d, y %d, dir %d", hero, x, y, dir); _vm->_mainHero->setPos(x, y); } void Interpreter::O_HEROOFF() { - uint16 heroId = readScriptValue(); + uint16 heroId = readScriptFlagValue(); debugInterpreter("O_HEROOFF %d", heroId); _vm->_mainHero->setVisible(false); } void Interpreter::O_HEROON() { - uint16 heroId = readScriptValue(); + uint16 heroId = readScriptFlagValue(); debugInterpreter("O_HEROON %d", heroId); _vm->_mainHero->setVisible(true); } void Interpreter::O_CLSTEXT() { - uint16 slot = readScriptValue(); + uint16 slot = readScriptFlagValue(); debugInterpreter("O_CLSTEXT slot %d", slot); // Sets text line to null // Sets text timeout to zero @@ -584,21 +584,21 @@ void Interpreter::O_CALLTABLE() { } void Interpreter::O_CHANGEMOB() { - uint16 mob = readScriptValue(); - uint16 value = readScriptValue(); + uint16 mob = readScriptFlagValue(); + uint16 value = readScriptFlagValue(); debugInterpreter("O_CHANGEMOB mob %d, value %d", mob, value); // Probably sets mobs visible flag to value } void Interpreter::O_ADDINV() { - uint16 hero = readScriptValue(); - uint16 item = readScriptValue(); + uint16 hero = readScriptFlagValue(); + uint16 item = readScriptFlagValue(); debugInterpreter("O_ADDINV hero %d, item %d", hero, item); } void Interpreter::O_REMINV() { - uint16 hero = readScriptValue(); - uint16 item = readScriptValue(); + uint16 hero = readScriptFlagValue(); + uint16 item = readScriptFlagValue(); debugInterpreter("O_REMINV hero %d, item %d", hero, item); } @@ -644,8 +644,8 @@ void Interpreter::O_WAITFRAME() { } void Interpreter::O_SETFRAME() { - uint16 anim = readScriptValue(); - uint16 frame = readScriptValue(); + uint16 anim = readScriptFlagValue(); + uint16 frame = readScriptFlagValue(); debugInterpreter("O_SETFRAME anim %d, frame %d", anim, frame); } @@ -657,7 +657,7 @@ void Interpreter::O_RUNACTION() { void Interpreter::O_COMPAREHI() { Flags::Id flag = readScriptFlagId(); - uint16 value = readScriptValue(); + uint16 value = readScriptFlagValue(); debugInterpreter("O_COMPAREHI flag %d, value %d", flag, value); _result = value < _flags->getFlagValue(flag); @@ -665,7 +665,7 @@ void Interpreter::O_COMPAREHI() { void Interpreter::O_COMPARELO() { Flags::Id flag = readScriptFlagId(); - uint16 value = readScriptValue(); + uint16 value = readScriptFlagValue(); debugInterpreter("O_COMPARELO flag %d, value %d", flag, value); _result = value > _flags->getFlagValue(flag); @@ -683,19 +683,19 @@ void Interpreter::O_FREEPRELOAD() { } void Interpreter::O_CHECKINV() { - uint16 hero = readScriptValue(); - uint16 item = readScriptValue(); + uint16 hero = readScriptFlagValue(); + uint16 item = readScriptFlagValue(); debugInterpreter("O_CHECKINV hero %d, item %d", hero, item); // checks if item is in heros inventory } void Interpreter::O_TALKHERO() { - uint16 hero = readScriptValue(); + uint16 hero = readScriptFlagValue(); debugInterpreter("O_TALKHERO hero %d", hero); } void Interpreter::O_WAITTEXT() { - uint16 slot = readScriptValue(); + uint16 slot = readScriptFlagValue(); Text &text = _vm->_textSlots[slot]; if (text._time) { _opcodeNF = 1; @@ -704,21 +704,21 @@ void Interpreter::O_WAITTEXT() { } void Interpreter::O_SETHEROANIM() { - uint16 hero = readScriptValue(); + uint16 hero = readScriptFlagValue(); int32 offset = readScript(); debugInterpreter("O_SETHEROANIM hero %d, offset %d", hero, offset); } void Interpreter::O_WAITHEROANIM() { - uint16 hero = readScriptValue(); + uint16 hero = readScriptFlagValue(); debugInterpreter("O_WAITHEROANIM hero %d", hero); } void Interpreter::O_GETHERODATA() { uint16 flag = readScript(); - uint16 hero = readScriptValue(); - uint16 heroOffset = readScriptValue(); + uint16 hero = readScriptFlagValue(); + uint16 heroOffset = readScriptFlagValue(); debugInterpreter("O_GETHERODATA flag %d, hero %d, heroOffset %d", flag, hero, heroOffset); } @@ -727,10 +727,10 @@ void Interpreter::O_GETMOUSEBUTTON() { } void Interpreter::O_CHANGEFRAMES() { - uint16 anim = readScriptValue(); - uint16 frame = readScriptValue(); - uint16 lastFrame = readScriptValue(); - uint16 loopFrame = readScriptValue(); + uint16 anim = readScriptFlagValue(); + uint16 frame = readScriptFlagValue(); + uint16 lastFrame = readScriptFlagValue(); + uint16 loopFrame = readScriptFlagValue(); debugInterpreter( "O_CHANGFRAMES anim %d, fr1 %d, fr2 %d, fr3 %d", @@ -742,10 +742,10 @@ void Interpreter::O_CHANGEFRAMES() { } void Interpreter::O_CHANGEBACKFRAMES() { - uint16 anim = readScriptValue(); - uint16 frame = readScriptValue(); - uint16 lastFrame = readScriptValue(); - uint16 loopFrame = readScriptValue(); + uint16 anim = readScriptFlagValue(); + uint16 frame = readScriptFlagValue(); + uint16 lastFrame = readScriptFlagValue(); + uint16 loopFrame = readScriptFlagValue(); debugInterpreter( "O_CHANGEBACKFRAMES anim %d, fr1 %d, fr2 %d, fr3 %d", @@ -764,8 +764,8 @@ void Interpreter::O_GETBACKANIMDATA() { void Interpreter::O_GETANIMDATA() { uint16 flag = readScript(); - uint16 anim = readScriptValue(); - uint16 animOffset = readScriptValue(); + uint16 anim = readScriptFlagValue(); + uint16 animOffset = readScriptFlagValue(); debugInterpreter("O_GETANIMDATA flag %d, anim %d, animOffset %d", flag, anim, animOffset); // Gets value of anim data // use anim offset as attribute id not an offset @@ -778,8 +778,8 @@ void Interpreter::O_SETBGCODE() { } void Interpreter::O_SETBACKFRAME() { - uint16 anim = readScriptValue(); - uint16 frame = readScriptValue(); + uint16 anim = readScriptFlagValue(); + uint16 frame = readScriptFlagValue(); debugInterpreter("O_SETBACKFRAME anim %d, frame %d", anim, frame); } @@ -794,8 +794,8 @@ void Interpreter::O_GETRND() { } void Interpreter::O_TALKBACKANIM() { - uint16 animSlot = readScriptValue(); - uint16 slot = readScriptValue(); + uint16 animSlot = readScriptFlagValue(); + uint16 slot = readScriptFlagValue(); debugInterpreter("O_TALKBACKANIM animSlot %d, slot %d", animSlot, slot); } @@ -836,9 +836,9 @@ void Interpreter::O_CALLDFLAG() { } void Interpreter::O_PRINTAT() { - uint16 slot = readScriptValue(); - uint16 fr1 = readScriptValue(); - uint16 fr2 = readScriptValue(); + uint16 slot = readScriptFlagValue(); + uint16 fr1 = readScriptFlagValue(); + uint16 fr2 = readScriptFlagValue(); debugInterpreter("O_PRINTAT slot %d, fr1 %d, fr2 %d", slot, fr1, fr2); @@ -853,12 +853,12 @@ void Interpreter::O_PRINTAT() { } void Interpreter::O_ZOOMIN() { - uint16 slot = readScriptValue(); + uint16 slot = readScriptFlagValue(); debugInterpreter("O_ZOOMIN slot %04d", slot); } void Interpreter::O_ZOOMOUT() { - uint16 slot = readScriptValue(); + uint16 slot = readScriptFlagValue(); debugInterpreter("O_ZOOMOUT slot %d", slot); } @@ -871,15 +871,15 @@ void Interpreter::O_SETSTRINGOFFSET() { void Interpreter::O_GETOBJDATA() { Flags::Id flag = readScriptFlagId(); - uint16 obj = readScriptValue(); - int16 objOffset = readScriptValue(); + uint16 obj = readScriptFlagValue(); + int16 objOffset = readScriptFlagValue(); debugInterpreter("O_GETOBJDATA flag %d, obj %d, objOffset %d", flag, obj, objOffset); } void Interpreter::O_SETOBJDATA() { - uint16 obj = readScriptValue(); - int16 objOffset = readScriptValue(); - uint16 value = readScriptValue(); + uint16 obj = readScriptFlagValue(); + int16 objOffset = readScriptFlagValue(); + uint16 value = readScriptFlagValue(); debugInterpreter("O_SETOBJDATA obj %d, objOffset %d, value %d", obj, objOffset, value); } @@ -890,19 +890,19 @@ void Interpreter::O_SWAPOBJECTS() { } void Interpreter::O_CHANGEHEROSET() { - uint16 hero = readScriptValue(); - uint16 heroSet = readScriptValue(); + uint16 hero = readScriptFlagValue(); + uint16 heroSet = readScriptFlagValue(); debugInterpreter("O_CHANGEHEROSET hero %d, heroSet %d", hero, heroSet); } void Interpreter::O_ADDSTRING() { - uint16 value = readScriptValue(); + uint16 value = readScriptFlagValue(); debugInterpreter("O_ADDSTRING value %d", value); // _string += value } void Interpreter::O_SUBSTRING() { - uint16 value = readScriptValue(); + uint16 value = readScriptFlagValue(); debugInterpreter("O_SUBSTRING value %d", value); // _string -= value } @@ -912,31 +912,31 @@ void Interpreter::O_INITDIALOG() { } void Interpreter::O_ENABLEDIALOGOPT() { - uint16 opt = readScriptValue(); + uint16 opt = readScriptFlagValue(); debugInterpreter("O_ENABLEDIALOGOPT opt %d", opt); } void Interpreter::O_DISABLEDIALOGOPT() { - uint16 opt = readScriptValue(); + uint16 opt = readScriptFlagValue(); debugInterpreter("O_DISABLEDIALOGOPT opt %d", opt); } void Interpreter::O_SHOWDIALOGBOX() { - uint16 box = readScriptValue(); + uint16 box = readScriptFlagValue(); debugInterpreter("O_SHOWDIALOGBOX box %d", box); } void Interpreter::O_STOPSAMPLE() { - uint16 slot = readScriptValue(); + uint16 slot = readScriptFlagValue(); debugInterpreter("O_STOPSAMPLE slot %d", slot); _vm->stopSample(slot); } void Interpreter::O_BACKANIMRANGE() { - uint16 slotId = readScriptValue(); + uint16 slotId = readScriptFlagValue(); uint16 animId = readScript(); - uint16 low = readScriptValue(); - uint16 high = readScriptValue(); + uint16 low = readScriptFlagValue(); + uint16 high = readScriptFlagValue(); if (animId != 0xFFFF) { if (animId & InterpreterFlags::FLAG_MASK) { @@ -959,7 +959,7 @@ void Interpreter::O_SETPATH() { } void Interpreter::O_GETHEROX() { - uint16 heroId = readScriptValue(); + uint16 heroId = readScriptFlagValue(); Flags::Id flagId = readScriptFlagId(); debugInterpreter("O_GETHEROX heroId %d, flagId %d", heroId, flagId); @@ -973,7 +973,7 @@ void Interpreter::O_GETHEROY() { } void Interpreter::O_GETHEROD() { - uint16 heroId = readScriptValue(); + uint16 heroId = readScriptFlagValue(); Flags::Id flagId = readScriptFlagId(); debugInterpreter("O_GETHEROD heroId %d, flagId %d", heroId, flagId); @@ -1003,7 +1003,7 @@ void Interpreter::O_SETFGCODE() { } void Interpreter::O_STOPHERO() { - uint16 heroId = readScriptValue(); + uint16 heroId = readScriptFlagValue(); debugInterpreter("O_STOPHERO heroId %d", heroId); @@ -1016,7 +1016,7 @@ void Interpreter::O_ANIMUPDATEOFF() { } void Interpreter::O_ANIMUPDATEON() { - uint16 slotId = readScriptValue(); + uint16 slotId = readScriptFlagValue(); debugInterpreter("O_ANIMUPDATEON slotId %d", slotId); } @@ -1027,43 +1027,41 @@ void Interpreter::O_FREECURSOR() { } void Interpreter::O_ADDINVQUIET() { - uint16 heroId = readScriptValue(); - uint16 itemId = readScriptValue(); + uint16 heroId = readScriptFlagValue(); + uint16 itemId = readScriptFlagValue(); debugInterpreter("O_ADDINVQUIET heorId %d, itemId %d", heroId, itemId); } void Interpreter::O_RUNHERO() { - uint16 heroId = readScriptValue(); - uint16 x = readScriptValue(); - uint16 y = readScriptValue(); - uint16 dir = readScriptValue(); + uint16 heroId = readScriptFlagValue(); + uint16 x = readScriptFlagValue(); + uint16 y = readScriptFlagValue(); + uint16 dir = readScriptFlagValue(); debugInterpreter("O_RUNHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); } void Interpreter::O_SETBACKANIMDATA() { - uint16 animId = readScriptValue(); - uint16 animOffset = readScriptValue(); - uint16 wart = readScriptValue(); + uint16 animId = readScriptFlagValue(); + uint16 animOffset = readScriptFlagValue(); + uint16 wart = readScriptFlagValue(); debugInterpreter("O_SETBACKANIMDATA animId %d, animOffset %d, wart %d", animId, animOffset, wart); } void Interpreter::O_VIEWFLC() { - uint16 animNr = readScriptValue(); + uint16 animNr = readScriptFlagValue(); debugInterpreter("O_VIEWFLC animNr %d", animNr); _vm->loadAnim(animNr, false); } void Interpreter::O_CHECKFLCFRAME() { - uint16 frameNr = readScriptValue(); + uint16 frameNr = readScriptFlagValue(); debugInterpreter("O_CHECKFLCFRAME frame number %d", frameNr); - const Video::FlicDecoder &flicPlayer = _vm->_flicPlayer; - - if (flicPlayer.getCurFrame() != frameNr) { + if (_vm->_flicPlayer.getCurFrame() != frameNr) { // Move instruction pointer before current instruciton // must do this check once again till it's false _currentInstruction -= 2; @@ -1092,13 +1090,13 @@ void Interpreter::O_FREEFLC() { } void Interpreter::O_TALKHEROSTOP() { - uint16 heroId = readScriptValue(); + uint16 heroId = readScriptFlagValue(); debugInterpreter("O_TALKHEROSTOP %d", heroId); } void Interpreter::O_HEROCOLOR() { - uint16 heroId = readScriptValue(); - uint16 kolorr = readScriptValue(); + uint16 heroId = readScriptFlagValue(); + uint16 kolorr = readScriptFlagValue(); debugInterpreter("O_HEROCOLOR heroId %d, kolorr %d", heroId, kolorr); } @@ -1107,27 +1105,27 @@ void Interpreter::O_GRABMAPA() { } void Interpreter::O_ENABLENAK() { - uint16 nakId = readScriptValue(); + uint16 nakId = readScriptFlagValue(); debugInterpreter("O_ENABLENAK nakId %d", nakId); } void Interpreter::O_DISABLENAK() { - uint16 nakId = readScriptValue(); + uint16 nakId = readScriptFlagValue(); debugInterpreter("O_DISABLENAK nakId %d", nakId); } void Interpreter::O_GETMOBNAME() { - uint16 war = readScriptValue(); + uint16 war = readScriptFlagValue(); debugInterpreter("O_GETMOBNAME war %d", war); } void Interpreter::O_SWAPINVENTORY() { - uint16 heroId = readScriptValue(); + uint16 heroId = readScriptFlagValue(); debugInterpreter("O_SWAPINVENTORY heroId %d", heroId); } void Interpreter::O_CLEARINVENTORY() { - uint16 heroId = readScriptValue(); + uint16 heroId = readScriptFlagValue(); debugInterpreter("O_CLEARINVENTORY heroId %d", heroId); } @@ -1136,8 +1134,7 @@ void Interpreter::O_SKIPTEXT() { } void Interpreter::SetVoice(uint32 sampleSlot) { - // TODO: use sample slot - uint16 slot = readScriptValue(); + uint16 slot = readScriptFlagValue(); _vm->loadVoice( slot, sampleSlot, @@ -1175,14 +1172,14 @@ void Interpreter::O_SETVOICED() { } void Interpreter::O_VIEWFLCLOOP() { - uint16 value = readScriptValue(); + uint16 value = readScriptFlagValue(); debugInterpreter("O_VIEWFLCLOOP animId %d", value); _vm->loadAnim(value, true); } void Interpreter::O_FLCSPEED() { - uint16 speed = readScriptValue(); + uint16 speed = readScriptFlagValue(); debugInterpreter("O_FLCSPEED speed %d", speed); } @@ -1205,8 +1202,8 @@ void Interpreter::O_GETKRZYWA() { void Interpreter::O_GETMOB() { Flags::Id flagId = readScriptFlagId(); - uint16 mx = readScriptValue(); - uint16 my = readScriptValue(); + uint16 mx = readScriptFlagValue(); + uint16 my = readScriptFlagValue(); debugInterpreter("O_GETMOB flagId %d, mx %d, my %d", flagId, mx, my); // check if current mob pos = (mx, my) } diff --git a/engines/prince/script.h b/engines/prince/script.h index 386951a0c9f5..8f139950bec9 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -126,7 +126,7 @@ class Interpreter { void checkPC(uint32 address); - uint16 readScriptValue(); + uint16 readScriptFlagValue(); Flags::Id readScriptFlagId(); // instantiation not needed here From eecc6f3e8462440a26170b2a62941df5101f9c3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Zbr=C3=B3g?= Date: Fri, 13 Dec 2013 07:05:37 +0000 Subject: [PATCH 064/374] PRINCE: Room resource loading started --- engines/prince/resource.h | 33 +++++++-------- engines/prince/script.cpp | 85 +++++++++++++++++++++++++++++++++++++-- engines/prince/script.h | 37 ++++++++++++++--- 3 files changed, 131 insertions(+), 24 deletions(-) diff --git a/engines/prince/resource.h b/engines/prince/resource.h index a5e389a37d6c..2f7e6ba3a800 100644 --- a/engines/prince/resource.h +++ b/engines/prince/resource.h @@ -26,6 +26,7 @@ #include "common/stream.h" #include "common/archive.h" #include "common/debug-channels.h" +#include "common/ptr.h" namespace Prince { @@ -36,43 +37,44 @@ namespace Resource { return resource.loadFromStream(stream); } - template bool loadResource(T *resource, const char *resourceName, bool required = true) { - Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); + Common::ScopedPtr stream(SearchMan.createReadStreamForMember(resourceName)); if (!stream) { if (required) error("Can't load %s", resourceName); return false; } - bool ret = loadFromStream(*resource, *stream); + return loadFromStream(*resource, *stream); + } - delete stream; + template + bool loadResource(Common::Array &array, Common::SeekableReadStream &stream, bool required = true) { + T t; + while (t.loadFromStream(stream)) + array.push_back(t); + + return true; + } - return ret; - } template bool loadResource(Common::Array &array, const char *resourceName, bool required = true) { - Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); + Common::ScopedPtr stream(SearchMan.createReadStreamForMember(resourceName)); if (!stream) { if (required) error("Can't load %s", resourceName); return false; } - T t; - while (t.loadFromStream(*stream)) - array.push_back(t); - - delete stream; - return true; + return loadResource(array, *stream, required); } template bool loadResource(Common::Array &array, const char *resourceName, bool required = true) { - Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); + + Common::ScopedPtr stream(SearchMan.createReadStreamForMember(resourceName)); if (!stream) { if (required) error("Can't load %s", resourceName); @@ -88,10 +90,9 @@ namespace Resource { } array.push_back(t); } - - delete stream; return true; } + } } diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index ce250f1c5a79..84174ec23c21 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -26,19 +26,92 @@ #include "prince/variatxt.h" #include "prince/font.h" #include "prince/hero.h" +#include "prince/resource.h" #include "common/debug.h" #include "common/debug-channels.h" #include "common/stream.h" #include "common/archive.h" - -#include "audio/decoders/wave.h" -#include "audio/audiostream.h" +#include "common/memstream.h" namespace Prince { static const uint16 NUM_OPCODES = 144; +Room::Room() {} + +void Room::loadMobs(Common::SeekableReadStream &stream) { + debug("loadMobs %d", stream.pos()); + static const uint8 MAX_MOBS = 64; + uint8 mobs[MAX_MOBS]; + stream.read(&mobs, sizeof(mobs)); + for(uint8 i = 0; i < sizeof(mobs); ++i) { + debug("mob %d flag %d", i, mobs[i]); + } +} + +void Room::loadBackAnim(Common::SeekableReadStream &stream) { + debug("loadBackAnim %d", stream.pos()); + static const uint8 MAX_BACK_ANIMS = 64; + uint32 backAnim[MAX_BACK_ANIMS]; + debug("loadBackAnim sizeof %lu", sizeof(backAnim)); + stream.read(backAnim, sizeof(backAnim)); + for(uint8 i = 0; i < MAX_BACK_ANIMS; ++i) { + debug("back anim offset %d", backAnim[i]); + } +} + +void Room::loadObj(Common::SeekableReadStream &stream) {} +void Room::loadNak(Common::SeekableReadStream &stream) {} +void Room::loadItemUse(Common::SeekableReadStream &stream) {} +void Room::loadItemGive(Common::SeekableReadStream &stream) {} +void Room::loadWalkTo(Common::SeekableReadStream &stream) {} +void Room::loadExamine(Common::SeekableReadStream &stream) {} +void Room::loadPickup(Common::SeekableReadStream &stream) {} +void Room::loadUse(Common::SeekableReadStream &stream) {} +void Room::loadPushOpen(Common::SeekableReadStream &stream) {} +void Room::loadPullClose(Common::SeekableReadStream &stream) {} +void Room::loadTalk(Common::SeekableReadStream &stream) {} +void Room::loadGive(Common::SeekableReadStream &stream) {} + +void Room::nextLoadStep(Common::SeekableReadStream &stream, LoadingStep step) { + uint32 offset = stream.readUint32LE(); + uint32 pos = stream.pos(); + stream.seek(offset); + + debug("nextLoadStep offset %d, pos %d", offset, pos); + + (this->*step)(stream); + + stream.seek(pos); +} + +bool Room::loadFromStream(Common::SeekableReadStream &stream) { + + uint32 pos = stream.pos(); + + nextLoadStep(stream, &Room::loadMobs); + nextLoadStep(stream, &Room::loadBackAnim); + nextLoadStep(stream, &Room::loadObj); + nextLoadStep(stream, &Room::loadNak); + nextLoadStep(stream, &Room::loadItemUse); + nextLoadStep(stream, &Room::loadItemGive); + nextLoadStep(stream, &Room::loadWalkTo); + nextLoadStep(stream, &Room::loadExamine); + nextLoadStep(stream, &Room::loadPickup); + nextLoadStep(stream, &Room::loadUse); + nextLoadStep(stream, &Room::loadPushOpen); + nextLoadStep(stream, &Room::loadPullClose); + nextLoadStep(stream, &Room::loadTalk); + nextLoadStep(stream, &Room::loadGive); + + // skip some data for now + static const uint8 ROOM_ENTRY_SIZE = 64; + stream.seek(pos + ROOM_ENTRY_SIZE); + + return true;; +} + Script::Script() : _data(nullptr), _dataSize(0) { } @@ -59,6 +132,12 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) { return false; stream.read(_data, _dataSize); + + Common::MemoryReadStream scriptDataStream(_data, _dataSize); + scriptDataStream.seek(getRoomTableOffset()+64); + debug("room table offset %d", scriptDataStream.pos()); + Room room; + room.loadFromStream(scriptDataStream); return true; } diff --git a/engines/prince/script.h b/engines/prince/script.h index 8f139950bec9..d51e01b5590f 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -25,8 +25,7 @@ #include "common/random.h" #include "common/endian.h" - -#include "audio/mixer.h" +#include "common/array.h" #include "prince/flags.h" @@ -45,6 +44,35 @@ namespace Detail { template <> inline uint32 LittleEndianReader(void *data) { return READ_LE_UINT32(data); } } +class Room { +public: + Room(); + + bool loadFromStream(Common::SeekableReadStream &stream); + +private: + + typedef void (Room::*LoadingStep)(Common::SeekableReadStream &stream); + + void nextLoadStep(Common::SeekableReadStream &stream, LoadingStep step); + + void loadMobs(Common::SeekableReadStream &stream); + void loadBackAnim(Common::SeekableReadStream &stream); + void loadObj(Common::SeekableReadStream &stream); + void loadNak(Common::SeekableReadStream &stream); + void loadItemUse(Common::SeekableReadStream &stream); + void loadItemGive(Common::SeekableReadStream &stream); + void loadWalkTo(Common::SeekableReadStream &stream); + void loadExamine(Common::SeekableReadStream &stream); + void loadPickup(Common::SeekableReadStream &stream); + void loadUse(Common::SeekableReadStream &stream); + void loadPushOpen(Common::SeekableReadStream &stream); + void loadPullClose(Common::SeekableReadStream &stream); + void loadTalk(Common::SeekableReadStream &stream); + void loadGive(Common::SeekableReadStream &stream); +}; + + class Script { public: Script(); @@ -69,6 +97,7 @@ class Script { private: uint8 *_data; uint32 _dataSize; + Common::Array _roomList; }; class InterpreterFlags { @@ -114,7 +143,7 @@ class Interpreter { static const uint32 _STACK_SIZE = 500; uint32 _stack[_STACK_SIZE]; uint8 _stacktop; - uint8 _savedStacktop; + //uint8 _savedStacktop; uint32 _waitFlag; const byte *_string; @@ -124,8 +153,6 @@ class Interpreter { // Helper functions uint32 step(uint32 opcodePC); - void checkPC(uint32 address); - uint16 readScriptFlagValue(); Flags::Id readScriptFlagId(); From 4c7326cfae914639bb5aa974b886f549cefdc4c5 Mon Sep 17 00:00:00 2001 From: Kamil Zbrog Date: Sat, 29 Mar 2014 22:23:20 +0100 Subject: [PATCH 065/374] PRINCE: Compilation fix after merge --- engines/prince/mhwanh.h | 8 ++++---- engines/prince/object.h | 2 +- engines/prince/prince.cpp | 2 +- engines/prince/prince.h | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/engines/prince/mhwanh.h b/engines/prince/mhwanh.h index 9344312ccefb..5364c5d20af0 100644 --- a/engines/prince/mhwanh.h +++ b/engines/prince/mhwanh.h @@ -23,14 +23,14 @@ #ifndef PRINCE_MHWANH_H #define PRINCE_MHWANH_H -#include "graphics/decoders/image_decoder.h" -#include "graphics/decoders/bmp.h" +#include "image/image_decoder.h" +#include "image/bmp.h" #include "graphics/surface.h" #include "resource.h" namespace Prince { -class MhwanhDecoder : public Graphics::ImageDecoder { +class MhwanhDecoder : public Image::ImageDecoder { public: MhwanhDecoder(); virtual ~MhwanhDecoder(); @@ -55,7 +55,7 @@ namespace Resource { } template <> inline - bool loadFromStream(Graphics::BitmapDecoder &image, Common::SeekableReadStream &stream) { + bool loadFromStream(Image::BitmapDecoder &image, Common::SeekableReadStream &stream) { return image.loadStream(stream); } } diff --git a/engines/prince/object.h b/engines/prince/object.h index aa55bf06a604..7a3d19e906c3 100644 --- a/engines/prince/object.h +++ b/engines/prince/object.h @@ -23,7 +23,7 @@ #ifndef PRINCE_OBJECT_H #define PRINCE_OBJECT_H -#include "graphics/decoders/image_decoder.h" +#include "image/image_decoder.h" #include "graphics/surface.h" namespace Prince { diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 687081d60c0b..d778f48b100a 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -181,7 +181,7 @@ void PrinceEngine::init() { delete talkTxtStream; - _roomBmp = new Graphics::BitmapDecoder(); + _roomBmp = new Image::BitmapDecoder(); _mainHero = new Hero(); _secondHero = new Hero(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 9802769ed9a7..f1707c04ec50 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -31,7 +31,7 @@ #include "common/rect.h" #include "common/events.h" -#include "graphics/decoders/bmp.h" +#include "image/bmp.h" #include "gui/debugger.h" @@ -157,7 +157,7 @@ class PrinceEngine : public Engine { uint8 _cursorNr; Common::RandomSource *_rnd; - Graphics::BitmapDecoder *_roomBmp; + Image::BitmapDecoder *_roomBmp; Cursor *_cursor1; Cursor *_cursor2; MhwanhDecoder *_walizkaBmp; From 8e9f08cf433b556751d74aac94c09c224d58383f Mon Sep 17 00:00:00 2001 From: Kamil Zbrog Date: Mon, 31 Mar 2014 19:28:54 +0200 Subject: [PATCH 066/374] PRINCE: Fixed 'All' subdirectory handling --- engines/prince/prince.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index d778f48b100a..bdb05bfedabf 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -150,27 +150,27 @@ void PrinceEngine::init() { _midiPlayer = new MusicPlayer(this); _font = new Font(); - Resource::loadResource(_font, "all/font1.raw"); + Resource::loadResource(_font, "font1.raw"); _walizkaBmp = new MhwanhDecoder(); - Resource::loadResource(_walizkaBmp, "all/walizka"); + Resource::loadResource(_walizkaBmp, "walizka"); _script = new Script(); - Resource::loadResource(_script, "all/skrypt.dat"); + Resource::loadResource(_script, "skrypt.dat"); _flags = new InterpreterFlags(); _interpreter = new Interpreter(this, _script, _flags); _variaTxt = new VariaTxt(); - Resource::loadResource(_variaTxt, "all/variatxt.dat"); + Resource::loadResource(_variaTxt, "variatxt.dat"); _cursor1 = new Cursor(); - Resource::loadResource(_cursor1, "all/mouse1.cur"); + Resource::loadResource(_cursor1, "mouse1.cur"); _cursor2 = new Cursor(); - Resource::loadResource(_cursor2, "all/mouse2.cur"); + Resource::loadResource(_cursor2, "mouse2.cur"); - Common::SeekableReadStream *talkTxtStream = SearchMan.createReadStreamForMember("all/talktxt.dat"); + Common::SeekableReadStream *talkTxtStream = SearchMan.createReadStreamForMember("talktxt.dat"); if (!talkTxtStream) { error("Can't load talkTxtStream"); return; From 94f51358508cacc1b8fa1aa4745dbba4917128ca Mon Sep 17 00:00:00 2001 From: Kamil Zbrog Date: Mon, 31 Mar 2014 22:56:01 +0200 Subject: [PATCH 067/374] PRINCE: Fixed background music playback --- engines/prince/prince.cpp | 4 +++- engines/prince/sound.cpp | 7 ++++++- engines/prince/sound.h | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index bdb05bfedabf..685c397edbf4 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -138,8 +138,10 @@ void PrinceEngine::init() { if (!sound->open("sound/databank.ptc")) error("Can't open sound/databank.ptc"); + SearchMan.addSubDirectoryMatching(gameDataDir, "all"); + SearchMan.add("all", all); - SearchMan.add("data/voices", voices); + SearchMan.add("voices", voices); SearchMan.add("sound", sound); _graph = new GraphicsMan(this); diff --git a/engines/prince/sound.cpp b/engines/prince/sound.cpp index fcdca8a0d120..425a710aa1ee 100644 --- a/engines/prince/sound.cpp +++ b/engines/prince/sound.cpp @@ -158,7 +158,10 @@ void MusicPlayer::killMidi() { 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(); @@ -168,7 +171,7 @@ void MusicPlayer::loadMidi(const char * name) { _data = (byte *)malloc(_dataSize); stream->read(_data, _dataSize); - delete stream; + delete stream; // Start playing the music sndMidiStart(); @@ -216,3 +219,5 @@ void MusicPlayer::sendToChannel(byte channel, uint32 b) { } } // End of namespace CGE + +/* vim: set tabstop=4 expandtab!: */ diff --git a/engines/prince/sound.h b/engines/prince/sound.h index 7219411b3674..07ac9f38d920 100644 --- a/engines/prince/sound.h +++ b/engines/prince/sound.h @@ -71,3 +71,4 @@ class MusicPlayer: public Audio::MidiPlayer { #endif +/* vim: set tabstop=4 expandtab!: */ From ebf362571807ca514c521c8fbeac340edead7a1b Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 2 Apr 2014 01:35:07 +0200 Subject: [PATCH 068/374] PRINCE: Animation classes fix. --- engines/prince/animation.cpp | 100 +++++++++++++++++++++------ engines/prince/animation.h | 25 ++++--- engines/prince/detail/animation.cpp | 102 ---------------------------- engines/prince/detail/animation.h | 51 -------------- engines/prince/hero.cpp | 8 +-- engines/prince/hero.h | 31 +++++++++ engines/prince/module.mk | 1 - engines/prince/sound.cpp | 3 +- 8 files changed, 133 insertions(+), 188 deletions(-) delete mode 100644 engines/prince/detail/animation.cpp delete mode 100644 engines/prince/detail/animation.h diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index f4db81ec4dc1..f595e7af6804 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -21,36 +21,24 @@ */ #include "prince/animation.h" -#include "prince/detail/animation.h" +#include "prince/decompress.h" +#include "common/debug.h" +#include "common/endian.h" namespace Prince { -Animation::Animation() : _helper(NULL) { -} - -Animation::~Animation() { - delete _helper; -} - bool Animation::loadFromStream(Common::SeekableReadStream &stream) { - uint32 dataSize = stream.size(); + _data = (byte*) malloc(dataSize); - byte *data = (byte*)malloc(dataSize); - - if(stream.read(data, dataSize) != dataSize) { - free(data); + if(stream.read(_data, dataSize) != dataSize) { + free(_data); return false; } - - delete _helper; - - _helper = new Detail::Animation(data, dataSize); - return true; } - +/* const Graphics::Surface * Animation::getSurface(uint16 frameIndex) { // bida kaszing if (frameIndex >= _frameList.size()) { @@ -60,8 +48,82 @@ const Graphics::Surface * Animation::getSurface(uint16 frameIndex) { } return _frameList[frameIndex]; } +*/ +Animation::Animation() { + +} + +Animation::Animation(byte *data, uint32 dataSize) + : _data(data), _dataSize(dataSize) { +} + +Animation::~Animation() { + free(_data); +} + +int16 Animation::getLoopCount() const { + return READ_LE_UINT16(_data + 2); +} + +int16 Animation::getBaseX() const { + return READ_LE_UINT16(_data + 8); +} + +int16 Animation::getBaseY() const { + return READ_LE_UINT16(_data + 10); +} +uint Animation::getPhaseCount() const { + return READ_LE_UINT16(_data + 4); } +uint Animation::getFrameCount() const { + return READ_LE_UINT16(_data + 6); +} + +int16 Animation::getPhaseOffsetX(uint phaseIndex) const { + return READ_LE_UINT16(getPhaseEntry(phaseIndex) + 0); +} + +int16 Animation::getPhaseOffsetY(uint phaseIndex) const { + return READ_LE_UINT16(getPhaseEntry(phaseIndex) + 2); +} + +int16 Animation::getPhaseFrameIndex(uint phaseIndex) const { + return READ_LE_UINT16(getPhaseEntry(phaseIndex) + 4); +} + +Graphics::Surface *Animation::getFrame(uint frameIndex) { + byte *frameData = _data + READ_LE_UINT32(_data + 16 + frameIndex * 4); + int16 width = READ_LE_UINT16(frameData + 0); + int16 height = READ_LE_UINT16(frameData + 2); + debug("width = %d; height = %d", width, height); + Graphics::Surface *surf = new Graphics::Surface(); + surf->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); + debug("frameData %p", frameData); + if (READ_BE_UINT32(frameData + 4) == 0x6D61736D) { + // Compressed + Decompressor dec; + uint32 ddataSize = READ_LE_UINT32(frameData + 8); + byte *ddata = new byte[ddataSize]; + dec.decompress(frameData + 12, ddata, ddataSize); + for (uint16 i = 0; i < height; ++i) { + memcpy(surf->getBasePtr(0, i), ddata + width * i, width); + } + delete[] ddata; + } else { + // Uncompressed + for (uint16 i = 0; i < height; ++i) { + memcpy(surf->getBasePtr(0, i), frameData + 4 + width * i, width); + } + } + return surf; +} + +byte *Animation::getPhaseEntry(uint phaseIndex) const { + return _data + READ_LE_UINT32(_data + 12) + phaseIndex * 8; +} + +} /* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/animation.h b/engines/prince/animation.h index b0ef25d4933b..9eb7a703e2aa 100644 --- a/engines/prince/animation.h +++ b/engines/prince/animation.h @@ -30,22 +30,29 @@ namespace Prince { -// FIXME: temp hack !!! -namespace Detail { - class Animation; -} - class Animation { public: - Animation(); - ~Animation(); bool loadFromStream(Common::SeekableReadStream &stream); + //const Graphics::Surface *getSurface(uint16 frameIndex); - const Graphics::Surface *getSurface(uint16 frameIndex); + Animation(); + Animation(byte *data, uint32 dataSize); + ~Animation(); + int16 getLoopCount() const; + int16 getBaseX() const; + int16 getBaseY() const; + uint getPhaseCount() const; + uint getFrameCount() const; + int16 getPhaseOffsetX(uint phaseIndex) const; + int16 getPhaseOffsetY(uint phaseIndex) const; + int16 getPhaseFrameIndex(uint phaseIndex) const; + Graphics::Surface *getFrame(uint frameIndex); private: Common::Array _frameList; - Detail::Animation *_helper; + byte *_data; + uint32 _dataSize; + byte *getPhaseEntry(uint phaseIndex) const; }; } diff --git a/engines/prince/detail/animation.cpp b/engines/prince/detail/animation.cpp deleted file mode 100644 index 8b4a72b2f8e0..000000000000 --- a/engines/prince/detail/animation.cpp +++ /dev/null @@ -1,102 +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/detail/animation.h" -#include "prince/decompress.h" - -#include "common/debug.h" -#include "common/endian.h" - -namespace Prince { namespace Detail { - -Animation::Animation(byte *data, uint32 dataSize) - : _data(data), _dataSize(dataSize) { -} - -Animation::~Animation() { - free(_data); -} - -int16 Animation::getLoopCount() const { - return READ_LE_UINT16(_data + 2); -} - -int16 Animation::getBaseX() const { - return READ_LE_UINT16(_data + 8); -} - -int16 Animation::getBaseY() const { - return READ_LE_UINT16(_data + 10); -} - -uint Animation::getPhaseCount() const { - return READ_LE_UINT16(_data + 4); -} - -uint Animation::getFrameCount() const { - return READ_LE_UINT16(_data + 6); -} - -int16 Animation::getPhaseOffsetX(uint phaseIndex) const { - return READ_LE_UINT16(getPhaseEntry(phaseIndex) + 0); -} - -int16 Animation::getPhaseOffsetY(uint phaseIndex) const { - return READ_LE_UINT16(getPhaseEntry(phaseIndex) + 2); -} - -int16 Animation::getPhaseFrameIndex(uint phaseIndex) const { - return READ_LE_UINT16(getPhaseEntry(phaseIndex) + 4); -} - -Graphics::Surface *Animation::getFrame(uint frameIndex) { - byte *frameData = _data + READ_LE_UINT32(_data + 16 + frameIndex * 4); - int16 width = READ_LE_UINT16(frameData + 0); - int16 height = READ_LE_UINT16(frameData + 2); - debug("width = %d; height = %d", width, height); - Graphics::Surface *surf = new Graphics::Surface(); - surf->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); - debug("frameData %p", frameData); - if (READ_BE_UINT32(frameData + 4) == 0x6D61736D) { - // Compressed - Decompressor dec; - uint32 ddataSize = READ_LE_UINT32(frameData + 8); - byte *ddata = new byte[ddataSize]; - dec.decompress(frameData + 12, ddata, ddataSize); - for (uint16 i = 0; i < height; ++i) { - memcpy(surf->getBasePtr(0, i), ddata + width * i, width); - } - delete[] ddata; - } else { - // Uncompressed - for (uint16 i = 0; i < height; ++i) { - memcpy(surf->getBasePtr(0, i), frameData + 4 + width * i, width); - } - } - return surf; -} - -byte *Animation::getPhaseEntry(uint phaseIndex) const { - return _data + READ_LE_UINT32(_data + 12) + phaseIndex * 8; -} - -} } diff --git a/engines/prince/detail/animation.h b/engines/prince/detail/animation.h deleted file mode 100644 index f9f289dc7147..000000000000 --- a/engines/prince/detail/animation.h +++ /dev/null @@ -1,51 +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_DETAIL_ANIMATION_H -#define PRINCE_DETAIL_ANIMATION_H - -#include "graphics/surface.h" - -namespace Prince { namespace Detail { - -class Animation { -public: - Animation(byte *data, uint32 dataSize); - ~Animation(); - int16 getLoopCount() const; - int16 getBaseX() const; - int16 getBaseY() const; - uint getPhaseCount() const; - uint getFrameCount() const; - int16 getPhaseOffsetX(uint phaseIndex) const; - int16 getPhaseOffsetY(uint phaseIndex) const; - int16 getPhaseFrameIndex(uint phaseIndex) const; - Graphics::Surface *getFrame(uint frameIndex); -protected: - byte *_data; - uint32 _dataSize; - byte *getPhaseEntry(uint phaseIndex) const; -}; - -} } - -#endif diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 621a9b8ee143..3e3c5d692915 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -32,11 +32,10 @@ namespace Prince { static const uint32 kMoveSetSize = 26; Hero::Hero() : _number(0), _visible(false), _state(STAY), _middleX(0), _middleY(0) - , _boreNum(0), _currHeight(0), _moveDelay(0), _shadMinus(1) { + , _boreNum(0), _currHeight(0), _moveDelay(0), _shadMinus(1), _moveSetType(0), _frame(0) { } bool Hero::loadAnimSet(uint32 animSetNr) { - animSetNr = 6; if (animSetNr > sizeof(heroSetTable)) { return false; } @@ -63,8 +62,9 @@ bool Hero::loadAnimSet(uint32 animSetNr) { } const Graphics::Surface * Hero::getSurface() { - if (_moveSet[3]) { - return _moveSet[3]->getSurface(0); + if (_moveSet[_moveSetType]) { + int16 phaseFrameIndex = _moveSet[_moveSetType]->getPhaseFrameIndex(_frame); + return _moveSet[_moveSetType]->getFrame(phaseFrameIndex); } return NULL; } diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 77333d3643f8..45c0d700e301 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -54,6 +54,35 @@ class Hero { DOWN = 4 }; + enum MoveSet { + Move_SL, + Move_SR, + Move_SU, + Move_SD, + Move_ML, + Move_MR, + Move_MU, + Move_MD, + Move_TL, + Move_TR, + Move_TU, + Move_TD, + Move_MLU, + Move_MLD, + Move_MLR, + Move_MRU, + Move_MRD, + Move_MRL, + Move_MUL, + Move_MUR, + Move_MUD, + Move_MDL, + Move_MDR, + Move_MDU, + Move_BORED1, + Move_BORED2 + }; + Hero(); bool loadAnimSet(uint32 heroAnimNumber); @@ -69,6 +98,8 @@ class Hero { State _state; int16 _middleX; int16 _middleY; + int16 _moveSetType; + int16 _frame; // Coords array of coordinates // DirTab array of directions diff --git a/engines/prince/module.mk b/engines/prince/module.mk index e5319f8fe8b9..228e5990e2eb 100644 --- a/engines/prince/module.mk +++ b/engines/prince/module.mk @@ -18,7 +18,6 @@ MODULE_OBJS = \ decompress.o \ hero.o \ hero_set.o \ - detail/animation.o \ cursor.o # This module can be built as a plugin diff --git a/engines/prince/sound.cpp b/engines/prince/sound.cpp index 425a710aa1ee..af139f708e78 100644 --- a/engines/prince/sound.cpp +++ b/engines/prince/sound.cpp @@ -157,8 +157,7 @@ void MusicPlayer::killMidi() { void MusicPlayer::loadMidi(const char * name) { Common::SeekableReadStream * stream = SearchMan.createReadStreamForMember(name); - if (!stream) - { + if (!stream) { debug("Can't load midi stream %s", name); return; } From 07a4f82c6336333be6d3d2930830be17184fbb99 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 4 Apr 2014 16:16:15 +0200 Subject: [PATCH 069/374] PRINCE: Hero animation - beginning of showHero() --- engines/prince/animation.cpp | 34 ++++- engines/prince/animation.h | 4 + engines/prince/graphics.cpp | 5 +- engines/prince/hero.cpp | 271 ++++++++++++++++++++++++++++++++++- engines/prince/hero.h | 42 ++++-- engines/prince/prince.cpp | 56 +++++++- engines/prince/prince.h | 2 + engines/prince/script.cpp | 6 +- 8 files changed, 396 insertions(+), 24 deletions(-) diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index f595e7af6804..8edf9d04eeda 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -29,10 +29,10 @@ namespace Prince { bool Animation::loadFromStream(Common::SeekableReadStream &stream) { - uint32 dataSize = stream.size(); - _data = (byte*) malloc(dataSize); + _dataSize = stream.size(); + _data = (byte*) malloc(_dataSize); - if(stream.read(_data, dataSize) != dataSize) { + if (stream.read(_data, _dataSize) != _dataSize) { free(_data); return false; } @@ -49,7 +49,7 @@ const Graphics::Surface * Animation::getSurface(uint16 frameIndex) { return _frameList[frameIndex]; } */ -Animation::Animation() { +Animation::Animation(): _data(NULL) { } @@ -61,6 +61,22 @@ Animation::~Animation() { free(_data); } +void Animation::clear() { + if (_data != NULL) { + free(_data); + } +} + +// TEMP +/* +int8 Animation::getZoom(uint16 offset) const { + return *(uint8*)(_data+offset); +} +*/ +int16 Animation::getZoom(uint16 offset) const { + return READ_LE_UINT16(_data + offset); +} + int16 Animation::getLoopCount() const { return READ_LE_UINT16(_data + 2); } @@ -93,6 +109,16 @@ int16 Animation::getPhaseFrameIndex(uint phaseIndex) const { return READ_LE_UINT16(getPhaseEntry(phaseIndex) + 4); } +int16 Animation::getFrameWidth(uint frameIndex) const { + byte *frameData = _data + READ_LE_UINT32(_data + 16 + frameIndex * 4); + return READ_LE_UINT16(frameData + 0); +} + +int16 Animation::getFrameHeight(uint frameIndex) const { + byte *frameData = _data + READ_LE_UINT32(_data + 16 + frameIndex * 4); + return READ_LE_UINT16(frameData + 2); +} + Graphics::Surface *Animation::getFrame(uint frameIndex) { byte *frameData = _data + READ_LE_UINT32(_data + 16 + frameIndex * 4); int16 width = READ_LE_UINT16(frameData + 0); diff --git a/engines/prince/animation.h b/engines/prince/animation.h index 9eb7a703e2aa..710f8730ccd8 100644 --- a/engines/prince/animation.h +++ b/engines/prince/animation.h @@ -47,6 +47,10 @@ class Animation { int16 getPhaseOffsetY(uint phaseIndex) const; int16 getPhaseFrameIndex(uint phaseIndex) const; Graphics::Surface *getFrame(uint frameIndex); + int16 getFrameWidth(uint frameIndex) const; + int16 getFrameHeight(uint frameIndex) const; + int16 getZoom(uint16 offset) const; + void clear(); private: Common::Array _frameList; diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 97e2686f5450..3f9517a6e9c8 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -72,9 +72,10 @@ void GraphicsMan::drawTransparent(uint16 posX, uint16 posY, const Graphics::Surf { for (uint y = 0; y < s->h; ++y) { for (uint x = 0; x < s->w; ++x) { - byte pixel = *((byte*)s->getBasePtr(x,y)); + byte pixel = *((byte*)s->getBasePtr(x, y)); if (pixel != 255) { - *((byte*)_frontScreen->getBasePtr(x, y)) = pixel; + //*((byte*)_frontScreen->getBasePtr(x, y)) = pixel; + *((byte*)_frontScreen->getBasePtr(x + posX, y + posY)) = pixel; } } } diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 3e3c5d692915..81e686c7402c 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -20,6 +20,7 @@ * */ #include "common/debug.h" +#include "common/random.h" #include "prince/hero.h" #include "prince/hero_set.h" @@ -29,11 +30,17 @@ namespace Prince { -static const uint32 kMoveSetSize = 26; +Hero::Hero() : _number(0), _visible(false), _state(MOVE), _middleX(0), _middleY(0) + , _boreNum(1), _currHeight(0), _moveDelay(0), _shadMinus(1), _moveSetType(0) + , _lastDirection(DOWN), _destDirection(DOWN), _talkTime(0), _boredomTime(0), _phase(0) + , _specAnim(0), _drawX(0), _drawY(0), _randomSource("prince"), _zoomFactor(0), _scaleValue(0) +{ + _zoomBitmap = new Animation(); +} -Hero::Hero() : _number(0), _visible(false), _state(STAY), _middleX(0), _middleY(0) - , _boreNum(0), _currHeight(0), _moveDelay(0), _shadMinus(1), _moveSetType(0), _frame(0) { -} +Hero::~Hero() { + delete _zoomBitmap; +} bool Hero::loadAnimSet(uint32 animSetNr) { if (animSetNr > sizeof(heroSetTable)) { @@ -57,18 +64,270 @@ bool Hero::loadAnimSet(uint32 animSetNr) { _moveSet[i] = anim; } - return true; } const Graphics::Surface * Hero::getSurface() { if (_moveSet[_moveSetType]) { - int16 phaseFrameIndex = _moveSet[_moveSetType]->getPhaseFrameIndex(_frame); + //debug("BaseX: %d", _moveSet[_moveSetType]->getBaseX()); + //debug("BaseY: %d", _moveSet[_moveSetType]->getBaseY()); + //debug("FrameCount: %d", _moveSet[_moveSetType]->getFrameCount()); + //debug("LoopCount: %d", _moveSet[_moveSetType]->getLoopCount()); + //debug("PhaseCount: %d", _moveSet[_moveSetType]->getPhaseCount()); + //debug("PhaseFrameIndex(%d): %d", _frame, _moveSet[_moveSetType]->getPhaseFrameIndex(_frame)); + //debug("PhaseOffsetX(%d): %d", _frame, _moveSet[_moveSetType]->getPhaseOffsetX(_frame)); + //debug("PhaseOffsetY(%d) %d", _frame, _moveSet[_moveSetType]->getPhaseOffsetY(_frame)); + //debug("FrameSizeX(%d) %d", _frame, _moveSet[_moveSetType]->getFrameWidth(_frame)); + //debug("FrameSizeY(%d) %d", _frame, _moveSet[_moveSetType]->getFrameHeight(_frame)); + //getState(); + int16 phaseFrameIndex = _moveSet[_moveSetType]->getPhaseFrameIndex(_phase); return _moveSet[_moveSetType]->getFrame(phaseFrameIndex); } return NULL; } +//TEMP +void Hero::getState() { + switch (_state) { + case STAY: + debug("STAY"); + break; + case TURN: + debug("TURN"); + break; + case MOVE: + debug("MOVE"); + break; + case BORE: + debug("BORE"); + break; + case SPEC: + debug("SPEC"); + break; + case TALK: + debug("TALK"); + break; + case MVAN: + debug("MVAN"); + break; + case TRAN: + debug("TRAN"); + break; + case RUN: + debug("RUN"); + break; + case DMOVE: + debug("DMOVE"); + break; + } +} + +//TODO +void Hero::countDrawPosition() { + int16 frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); + int16 frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); + _drawX = _middleX - frameXSize/2; + _drawY = _middleY - frameYSize; +} + +void Hero::showHeroAnimFrame() { + if (_phase < _moveSet[_moveSetType]->getFrameCount() - 1) { + _phase++; + } else { + _phase = 0; + } + countDrawPosition(); + //debug("_drawX: %d", _drawX); + //debug("_drawY: %d", _drawY); + //debug("_middleX: %d", _middleX); + //debug("_middleY: %d", _middleY); +} + +void Hero::setScale(int8 zoomBitmapValue) { + if (zoomBitmapValue == 0) { + _zoomFactor = 1; + } else { + _zoomFactor = zoomBitmapValue; + } + _scaleValue = 10000 / _zoomFactor; + debug("_scaleValue: %d", _scaleValue); +} + +void Hero::selectZoom() { + int8 zoomBitmapValue = _zoomBitmap->getZoom(_middleY / 4 * kZoomBitmapWidth + _middleX / 4); + debug("offset: %d", _middleY / 4 * kZoomBitmapWidth + _middleX / 4); + debug("zoomBitmapValue: %d", _zoomFactor); + setScale(zoomBitmapValue); +} + +void Hero::specialAnim() { +} + +void Hero::rotateHero() { + switch (_lastDirection) { + case LEFT: + switch (_destDirection) { + case RIGHT: + _moveSetType = Move_MLR; + break; + case UP: + _moveSetType = Move_MLU; + break; + case DOWN: + _moveSetType = Move_MLD; + break; + } + break; + case RIGHT: + switch (_destDirection) { + case LEFT: + _moveSetType = Move_MRL; + break; + case UP: + _moveSetType = Move_MRU; + break; + case DOWN: + _moveSetType = Move_MRD; + break; + } + break; + case UP: + switch (_destDirection) { + case LEFT: + _moveSetType = Move_MUL; + break; + case RIGHT: + _moveSetType = Move_MUR; + break; + case DOWN: + _moveSetType = Move_MUD; + break; + } + break; + case DOWN: + switch (_destDirection) { + case LEFT: + _moveSetType = Move_MDL; + break; + case RIGHT: + _moveSetType = Move_MDR; + break; + case UP: + _moveSetType = Move_MDU; + break; + } + break; + } +} + +void Hero::showHero() { + if (_visible) { + // Is he talking? + if (_talkTime == 0) { //? + // Scale of hero + selectZoom(); + switch (_state) { + case STAY: + //if(OptionsFlag == false) { + //if(OpcodePC == null) { + _boredomTime++; + if (_boredomTime == 200) { // 140 for second hero + _boredomTime = 0; + _state = BORE; + } + switch (_lastDirection) { + case LEFT: + _moveSetType = Move_SL; + break; + case RIGHT: + _moveSetType = Move_SR; + break; + case UP: + _moveSetType = Move_SU; + break; + case DOWN: + _moveSetType = Move_SD; + break; + } + break; + case TURN: + /* + if(_lastDirection == _destDirection) { + _state = STAY; + } else { + _frame = 0; + rotateHero(); + _lastDirection = _destDirection; + } + */ + break; + case MOVE: + switch (_lastDirection) { + case LEFT: + _moveSetType = Move_ML; + break; + case RIGHT: + _moveSetType = Move_MR; + break; + case UP: + _moveSetType = Move_MU; + break; + case DOWN: + _moveSetType = Move_MD; + break; + } + break; + case BORE: + //if (_direction == UP) { + switch (_boreNum) { + case 0: + _moveSetType = Move_BORED1; + break; + case 1: + _moveSetType = Move_BORED2; + break; + } + if (_phase == _moveSet[_moveSetType]->getFrameCount() - 1) { + _boreNum = _randomSource.getRandomNumber(1); // rand one of two 'bored' animation + _lastDirection = DOWN; + _state = STAY; + } + break; + case SPEC: + //specialAnim(); + break; + case TALK: + switch (_lastDirection) { + case LEFT: + _moveSetType = Move_TL; + break; + case RIGHT: + _moveSetType = Move_TR; + break; + case UP: + _moveSetType = Move_TU; + break; + case DOWN: + _moveSetType = Move_TD; + break; + } + break; + case TRAN: + break; + case RUN: + break; + case DMOVE: + break; + } + } else { + _talkTime--; // o ile? + } + showHeroAnimFrame(); + } else { + // no hero visible + return; + } +} } /* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 45c0d700e301..e01a5c071f47 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -34,6 +34,11 @@ class Animation; class Hero { public: + static const uint32 kMoveSetSize = 26; + static const int16 kZoomStep = 4; + static const int16 kMaxPicWidth = 1280; + static const int16 kZoomBitmapWidth = kMaxPicWidth / kZoomStep; + enum State { STAY = 0, TURN = 1, @@ -84,22 +89,38 @@ class Hero { }; Hero(); - + ~Hero(); + Common::RandomSource _randomSource; bool loadAnimSet(uint32 heroAnimNumber); const Graphics::Surface * getSurface(); - void setPos(int16 x, int16 y) { _middleX = x; _middleX = y; } + void setPos(int16 x, int16 y) { _middleX = x; _middleY = y; } void setVisible(bool flag) { _visible = flag; } + void showHero(); + void moveHero(); + void rotateHero(); + void setScale(int8 zoomBitmapValue); + void selectZoom(); + void countDrawPosition(); + void showHeroAnimFrame(); + void specialAnim(); + void getState(); + //private: uint16 _number; uint16 _visible; - State _state; - int16 _middleX; - int16 _middleY; + int16 _state; + int16 _middleX; // middle of X + int16 _middleY; // lower part of hero + int16 _drawX; + int16 _drawY; + int16 _lastDirection; + int16 _destDirection; int16 _moveSetType; - int16 _frame; + int8 _zoomFactor; + int16 _scaleValue; // Coords array of coordinates // DirTab array of directions @@ -109,13 +130,13 @@ class Hero { // DestDir // LeftRight previous left/right direction // UpDown previous up/down direction - // Phase animation phase + uint _phase; // Phase animation phase // Step x/y step size depends on direction // MaxBoredom stand still timeout - // Boredom current boredom time in frames + int16 _boredomTime;// Boredom current boredom time in frames uint16 _boreNum; // Bore anim frame - // TalkTime time of talk anim - // SpecAnim additional anim + int16 _talkTime; // TalkTime time of talk anim + int32 _specAnim; // SpecAnim additional anim uint16 _currHeight; // height of current anim phase @@ -126,6 +147,7 @@ class Hero { // AnimSet number of animation set Common::Array _moveSet; // MoveAnims MoveSet // TurnAnim ?? + Animation *_zoomBitmap; // change to sth else, not Animation ?? uint32 _moveDelay; uint32 _shadMinus; //?? diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 685c397edbf4..324c4592aed5 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -59,6 +59,7 @@ #include "prince/archive.h" #include "prince/hero.h" #include "prince/resource.h" +#include "prince/animation.h" namespace Prince { @@ -279,6 +280,9 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _sceneWidth = _roomBmp->getSurface()->w; } + _mainHero->_zoomBitmap->clear(); + Resource::loadResource(_mainHero->_zoomBitmap, "zoom", false); + _mobList.clear(); Resource::loadResource(_mobList, "mob.lst", false); @@ -475,6 +479,54 @@ void PrinceEngine::keyHandler(Common::Event event) { case Common::KEYCODE_ESCAPE: _flags->setFlagValue(Flags::ESCAPED2, 1); break; + case Common::KEYCODE_UP: + _mainHero->_phase++; + debugEngine("%d", _mainHero->_phase); + break; + case Common::KEYCODE_DOWN: + if(_mainHero->_phase > 0) { + _mainHero->_phase--; + } + debugEngine("%d", _mainHero->_phase); + break; + case Common::KEYCODE_w: + _mainHero->_lastDirection = _mainHero->UP; + debugEngine("UP"); + break; + case Common::KEYCODE_s: + _mainHero->_lastDirection = _mainHero->DOWN; + debugEngine("DOWN"); + break; + case Common::KEYCODE_a: + _mainHero->_lastDirection = _mainHero->LEFT; + debugEngine("LEFT"); + break; + case Common::KEYCODE_f: + _mainHero->_lastDirection = _mainHero->RIGHT; + debugEngine("RIGHT"); + break; + case Common::KEYCODE_1: + if(_mainHero->_state > 0) { + _mainHero->_state--; + } + debugEngine("%d", _mainHero->_state); + break; + case Common::KEYCODE_2: + _mainHero->_state++; + debugEngine("%d", _mainHero->_state); + break; + case Common::KEYCODE_i: + _mainHero->_middleY -= 10; + break; + case Common::KEYCODE_k: + _mainHero->_middleY += 10; + break; + case Common::KEYCODE_j: + _mainHero->_middleX -= 10; + break; + case Common::KEYCODE_l: + _mainHero->_middleX += 10; + break; } } @@ -575,7 +627,8 @@ void PrinceEngine::drawScreen() { const Graphics::Surface *mainHeroSurface = _mainHero->getSurface(); if (mainHeroSurface) - _graph->drawTransparent(_mainHero->_middleX, _mainHero->_middleY, mainHeroSurface); + //_graph->drawTransparent(_mainHero->_middleX, _mainHero->_middleY, mainHeroSurface); + _graph->drawTransparent(_mainHero->_drawX, _mainHero->_drawY, mainHeroSurface); } playNextFrame(); @@ -627,6 +680,7 @@ void PrinceEngine::mainLoop() { return; // TODO: Update all structures, animations, naks, heros etc. + _mainHero -> showHero(); _interpreter->step(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index f1707c04ec50..a48f056d4d7f 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -62,6 +62,7 @@ class Cursor; class MhwanhDecoder; class Font; class Hero; +class Animation; struct Text { const char *_str; @@ -174,6 +175,7 @@ class PrinceEngine : public Engine { Common::SeekableReadStream *_voiceStream[MAX_SAMPLES]; Audio::SoundHandle _soundHandle[MAX_SAMPLES]; + Animation *_zoom; Common::Array _mobList; Common::Array _objList; Common::Array _animList; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 84174ec23c21..84ae64791e28 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -181,7 +181,7 @@ void Interpreter::debugInterpreter(const char *s, ...) { str += Common::String::format("op %04d: ", _lastOpcode); //debugC(10, DebugChannel::kScript, "PrinceEngine::Script %s %s", str.c_str(), buf); - debug("Prince::Script frame %08ld mode %s %s %s", _vm->_frameNr, _mode, str.c_str(), buf); + //debug("Prince::Script frame %08ld mode %s %s %s", _vm->_frameNr, _mode, str.c_str(), buf); } void Interpreter::step() { @@ -631,6 +631,10 @@ void Interpreter::O_SETHERO() { uint16 dir = readScriptFlagValue(); debugInterpreter("O_SETHERO hero %d, x %d, y %d, dir %d", hero, x, y, dir); _vm->_mainHero->setPos(x, y); + _vm->_mainHero->_lastDirection = dir; + _vm->_mainHero->_state = _vm->_mainHero->STAY; + _vm->_mainHero->_moveSetType = _vm->_mainHero->_lastDirection - 1; // for countDrawPosition + _vm->_mainHero->countDrawPosition(); //setting drawX, drawY } void Interpreter::O_HEROOFF() { From 770a45390d4422dc9cbcb213808861297ba8e620 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 22 Jun 2014 19:56:56 +0200 Subject: [PATCH 070/374] PRINCE: Fix endlines --- engines/prince/decompress.cpp | 342 +++++++++++++++++----------------- engines/prince/decompress.h | 88 ++++----- 2 files changed, 215 insertions(+), 215 deletions(-) diff --git a/engines/prince/decompress.cpp b/engines/prince/decompress.cpp index ed52aaf6f7de..7fba179541e2 100644 --- a/engines/prince/decompress.cpp +++ b/engines/prince/decompress.cpp @@ -1,171 +1,171 @@ -/* 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. - * - */ - -// John_Doe's implementation - -#include "prince/decompress.h" - -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 -}; - -static const uint32 table2[] = { - 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 -}; - -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++; - } - } -} - -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; -} - -} // End of namespace Prince +/* 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. + * + */ + +// John_Doe's implementation + +#include "prince/decompress.h" + +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 +}; + +static const uint32 table2[] = { + 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 +}; + +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++; + } + } +} + +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; +} + +} // End of namespace Prince diff --git a/engines/prince/decompress.h b/engines/prince/decompress.h index 88b19c6ae325..ef495db65ec7 100644 --- a/engines/prince/decompress.h +++ b/engines/prince/decompress.h @@ -1,44 +1,44 @@ -/* 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. - * - */ - -// John_Doe's implementation - -#ifndef PRINCE_DECOMPRESS_H -#define PRINCE_DECOMPRESS_H - -#include "engines/util.h" - -namespace Prince { - -class Decompressor { -public: - void decompress(byte *source, byte *dest, uint32 destSize); -protected: - byte *_src, *_dst; - byte _bitBuffer; - int _bitsLeft; - int getBit(); -}; - -} // End of namespace Prince - -#endif +/* 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. + * + */ + +// John_Doe's implementation + +#ifndef PRINCE_DECOMPRESS_H +#define PRINCE_DECOMPRESS_H + +#include "engines/util.h" + +namespace Prince { + +class Decompressor { +public: + void decompress(byte *source, byte *dest, uint32 destSize); +protected: + byte *_src, *_dst; + byte _bitBuffer; + int _bitsLeft; + int getBit(); +}; + +} // End of namespace Prince + +#endif From 43385406ba9a3394ddec4deb8c6690afb550fcca Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 28 Apr 2014 12:15:54 +0200 Subject: [PATCH 071/374] PRINCE: Begin of hero zooming --- engines/prince/animation.cpp | 26 +++++---- engines/prince/hero.cpp | 104 ++++++++++++++++++++++++++++++++++- engines/prince/hero.h | 3 + 3 files changed, 119 insertions(+), 14 deletions(-) diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index 8edf9d04eeda..587316fc1969 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -77,24 +77,33 @@ int16 Animation::getZoom(uint16 offset) const { return READ_LE_UINT16(_data + offset); } +// AH_Loop int16 Animation::getLoopCount() const { return READ_LE_UINT16(_data + 2); } +// AH_Fazy +uint Animation::getPhaseCount() const { + return READ_LE_UINT16(_data + 4); +} + +// AH_Ramki +uint Animation::getFrameCount() const { + return READ_LE_UINT16(_data + 6); +} + +// AH_X int16 Animation::getBaseX() const { return READ_LE_UINT16(_data + 8); } +// AH_Y int16 Animation::getBaseY() const { return READ_LE_UINT16(_data + 10); } -uint Animation::getPhaseCount() const { - return READ_LE_UINT16(_data + 4); -} - -uint Animation::getFrameCount() const { - return READ_LE_UINT16(_data + 6); +byte *Animation::getPhaseEntry(uint phaseIndex) const { + return _data + READ_LE_UINT32(_data + 12) + phaseIndex * 8; } int16 Animation::getPhaseOffsetX(uint phaseIndex) const { @@ -145,11 +154,6 @@ Graphics::Surface *Animation::getFrame(uint frameIndex) { } return surf; } - -byte *Animation::getPhaseEntry(uint phaseIndex) const { - return _data + READ_LE_UINT32(_data + 12) + phaseIndex * 8; -} - } /* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 81e686c7402c..070a2fe82cc5 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -69,8 +69,8 @@ bool Hero::loadAnimSet(uint32 animSetNr) { const Graphics::Surface * Hero::getSurface() { if (_moveSet[_moveSetType]) { - //debug("BaseX: %d", _moveSet[_moveSetType]->getBaseX()); - //debug("BaseY: %d", _moveSet[_moveSetType]->getBaseY()); + debug("BaseX: %d", _moveSet[_moveSetType]->getBaseX()); + debug("BaseY: %d", _moveSet[_moveSetType]->getBaseY()); //debug("FrameCount: %d", _moveSet[_moveSetType]->getFrameCount()); //debug("LoopCount: %d", _moveSet[_moveSetType]->getLoopCount()); //debug("PhaseCount: %d", _moveSet[_moveSetType]->getPhaseCount()); @@ -81,7 +81,9 @@ const Graphics::Surface * Hero::getSurface() { //debug("FrameSizeY(%d) %d", _frame, _moveSet[_moveSetType]->getFrameHeight(_frame)); //getState(); int16 phaseFrameIndex = _moveSet[_moveSetType]->getPhaseFrameIndex(_phase); - return _moveSet[_moveSetType]->getFrame(phaseFrameIndex); + Graphics::Surface *heroFrame = _moveSet[_moveSetType]->getFrame(phaseFrameIndex); + //return _moveSet[_moveSetType]->getFrame(phaseFrameIndex); + return heroFrame; } return NULL; } @@ -122,14 +124,110 @@ void Hero::getState() { } } +int Hero::getScaledValue(int size) { + int newSize = 0; + int16 initScaleValue = _scaleValue; + if(_scaleValue != 10000) { + for(int i = 0; i < size; i++) { + initScaleValue -= 100; + if(initScaleValue >= 0) { + newSize++; + } else { + initScaleValue += _scaleValue; + } + } + return newSize; + } else { + return size; + } +} + +void Hero::checkNak() { + +} + +void Hero::zoomSprite(int16 tempMiddleY) { + if(_zoomFactor == 0) { + //notfullSize + int sprWidth = _moveSet[_moveSetType]->getFrameWidth(_phase); + int temp = sprWidth / 2; + int sprFullHeight = _moveSet[_moveSetType]->getFrameHeight(_phase); // edx + int sprModulo = tempMiddleY; // ebp ??? + int sprSkipX = 0; + int sprSkipY = 0; + + } else { + //fullSize + + } +} + //TODO +/* void Hero::countDrawPosition() { int16 frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); int16 frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); _drawX = _middleX - frameXSize/2; _drawY = _middleY - frameYSize; } +*/ +void Hero::countDrawPosition() { + int16 tempMiddleX; + int16 tempMiddleY; + int16 baseX = _moveSet[_moveSetType]->getBaseX(); + int16 baseY = _moveSet[_moveSetType]->getBaseY(); + if(baseX == 320) { + tempMiddleY = _middleY - (baseY - 240); + } + int16 frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); + int16 frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); + int scaledX = getScaledValue(frameXSize); // ebx + int scaledY = getScaledValue(frameYSize); // edx + int tempHeroHeight = scaledY; + + int width = scaledX / 2; + tempMiddleX = _middleX - width; //eax + int z = _middleY; //ebp + int y = _middleY - scaledY; //ecx + + //TODO + checkNak(); + //zoomSprite(tempMiddleY); + // zoomSprite: + if(_zoomFactor == 0) { + //notfullSize + int sprFullHeight = _moveSet[_moveSetType]->getFrameHeight(_phase); // edx + int sprModulo = tempMiddleY; // ebp ??? + int sprSkipX = 0; + int sprSkipY = 0; + int sprWidth = scaledX; + int sprHeight = scaledY; + } else { + //fullSize + int sprWidth = frameXSize; + int temp = sprWidth / 2; + int lowerYPosition = y + 1; + } + + debug("scaledX: %d", scaledX); + debug("scaledY: %d", scaledY); + _drawX = _middleX - frameXSize/2; + _drawY = _middleY - frameYSize; + + +} +/* +AnimHeader struc ;struktura naglowka pliku z animacja +AH_ID dw 0 ;ID = "AN" +AH_Loop dw 0 ;numer fazy do petli +AH_Fazy dw 0 ;ilosc faz animacji +AH_Ramki dw 0 ;ilosc ramek grafiki +AH_X dw 0 ;poczatkowa wsp¢lrzedna X +AH_Y dw 0 ;poczatkowa wsp¢lrzedna Y +AH_Tablica dd 0 ;offset tablicy faz +AH_RamkiAddr dd 0 ;poczatek tablicy z offsetami ramek +*/ void Hero::showHeroAnimFrame() { if (_phase < _moveSet[_moveSetType]->getFrameCount() - 1) { _phase++; diff --git a/engines/prince/hero.h b/engines/prince/hero.h index e01a5c071f47..2914b1f01ade 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -102,8 +102,11 @@ class Hero { void moveHero(); void rotateHero(); void setScale(int8 zoomBitmapValue); + int getScaledValue(int size); void selectZoom(); void countDrawPosition(); + void checkNak(); + void zoomSprite(int16 tempMiddleY); void showHeroAnimFrame(); void specialAnim(); void getState(); From eb9a0009bb1b4699ce60be7b3638c3a63ee0dfda Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 28 Apr 2014 20:59:42 +0200 Subject: [PATCH 072/374] PRINCE: Small update to hero zooming. --- engines/prince/hero.cpp | 85 ++++++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 19 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 070a2fe82cc5..deccb7d24dbc 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -83,6 +83,7 @@ const Graphics::Surface * Hero::getSurface() { int16 phaseFrameIndex = _moveSet[_moveSetType]->getPhaseFrameIndex(_phase); Graphics::Surface *heroFrame = _moveSet[_moveSetType]->getFrame(phaseFrameIndex); //return _moveSet[_moveSetType]->getFrame(phaseFrameIndex); + return heroFrame; } return NULL; @@ -176,46 +177,90 @@ void Hero::countDrawPosition() { int16 tempMiddleY; int16 baseX = _moveSet[_moveSetType]->getBaseX(); int16 baseY = _moveSet[_moveSetType]->getBaseY(); + // any chance? if(baseX == 320) { tempMiddleY = _middleY - (baseY - 240); + } else { + tempMiddleY = _middleY; } int16 frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); int16 frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); int scaledX = getScaledValue(frameXSize); // ebx int scaledY = getScaledValue(frameYSize); // edx - int tempHeroHeight = scaledY; + int tempHeroHeight = scaledY; // not used? global? int width = scaledX / 2; tempMiddleX = _middleX - width; //eax int z = _middleY; //ebp int y = _middleY - scaledY; //ecx - //TODO checkNak(); + //zoomSprite(tempMiddleY); // zoomSprite: - if(_zoomFactor == 0) { + int sprModulo; + if(_zoomFactor != 0) { //notfullSize - int sprFullHeight = _moveSet[_moveSetType]->getFrameHeight(_phase); // edx - int sprModulo = tempMiddleY; // ebp ??? - int sprSkipX = 0; - int sprSkipY = 0; + int sprFullHeight = frameXSize; + sprModulo = tempMiddleY; // ebp ??? + //int sprSkipX = 0; + //int sprSkipY = 0; int sprWidth = scaledX; - int sprHeight = scaledY; + int sprHeight = scaledY; // after resize + int allocMemSize = sprWidth*sprHeight; + sprFullHeight--; + int imulEDX = sprFullHeight*sprModulo; // edx + int sprZoomX; + int sprZoomY = _scaleValue; + int loop_lin; + for(int i = 0; i < sprHeight; i++) { + // linear_loop: + while(1) { + sprZoomY -= 100; + if(sprZoomY >= 0 || _scaleValue == 10000) { + // all_r_y + // push esi + loop_lin = sprWidth; + // mov ah, -1 + sprZoomX = _scaleValue; + break; // to loop_lin + } else { + sprZoomY += _scaleValue; + // add esi, sprModulo /? + } + } + // end of linear_loop + // loop_lin: + for(int i = 0; i < loop_lin; i++) { + // mov al, b[esi] + // inc esi + sprZoomX -= 100; + if(sprZoomX >= 0) { + //its_all_r + // without ZOOMFIX + //mov [edi], al + // inc edi + } else { + sprZoomX += _scaleValue; + } + } + //pop esi + //add esi, sprModulo + debug("loop_lin: %d", loop_lin); + } + debug("scaledX: %d", scaledX); + debug("scaledY: %d", scaledY); + _drawX = _middleX - frameXSize/2; + _drawY = _middleY - frameYSize; } else { //fullSize - int sprWidth = frameXSize; - int temp = sprWidth / 2; - int lowerYPosition = y + 1; + sprModulo = 0; //? + _drawX = _middleX - frameXSize / 2; + _drawY = tempMiddleY + 1 - frameYSize; } - debug("scaledX: %d", scaledX); - debug("scaledY: %d", scaledY); - _drawX = _middleX - frameXSize/2; - _drawY = _middleY - frameYSize; - - + // ShowSprite } /* AnimHeader struc ;struktura naglowka pliku z animacja @@ -243,11 +288,13 @@ void Hero::showHeroAnimFrame() { void Hero::setScale(int8 zoomBitmapValue) { if (zoomBitmapValue == 0) { - _zoomFactor = 1; + _zoomFactor = 0; + _scaleValue = 10000; } else { _zoomFactor = zoomBitmapValue; + _scaleValue = 10000 / _zoomFactor; } - _scaleValue = 10000 / _zoomFactor; + debug("_zoomFactor: %d", _zoomFactor); debug("_scaleValue: %d", _scaleValue); } From 991ca05fd4e48706523f22435a18b5f70e08277f Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 29 Apr 2014 16:57:14 +0200 Subject: [PATCH 073/374] PRINCE: Hero zooming progress --- engines/prince/hero.cpp | 156 +++++++++++++++++++++++----------------- engines/prince/hero.h | 2 +- 2 files changed, 92 insertions(+), 66 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index deccb7d24dbc..f4a1c9ece13e 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -83,8 +83,8 @@ const Graphics::Surface * Hero::getSurface() { int16 phaseFrameIndex = _moveSet[_moveSetType]->getPhaseFrameIndex(_phase); Graphics::Surface *heroFrame = _moveSet[_moveSetType]->getFrame(phaseFrameIndex); //return _moveSet[_moveSetType]->getFrame(phaseFrameIndex); - - return heroFrame; + //return heroFrame; + return zoomSprite(heroFrame); } return NULL; } @@ -128,7 +128,7 @@ void Hero::getState() { int Hero::getScaledValue(int size) { int newSize = 0; int16 initScaleValue = _scaleValue; - if(_scaleValue != 10000) { + if (_scaleValue != 10000) { for(int i = 0; i < size; i++) { initScaleValue -= 100; if(initScaleValue >= 0) { @@ -147,38 +147,13 @@ void Hero::checkNak() { } -void Hero::zoomSprite(int16 tempMiddleY) { - if(_zoomFactor == 0) { - //notfullSize - int sprWidth = _moveSet[_moveSetType]->getFrameWidth(_phase); - int temp = sprWidth / 2; - int sprFullHeight = _moveSet[_moveSetType]->getFrameHeight(_phase); // edx - int sprModulo = tempMiddleY; // ebp ??? - int sprSkipX = 0; - int sprSkipY = 0; - - } else { - //fullSize - - } -} - -//TODO -/* -void Hero::countDrawPosition() { - int16 frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); - int16 frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); - _drawX = _middleX - frameXSize/2; - _drawY = _middleY - frameYSize; -} -*/ -void Hero::countDrawPosition() { +Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) { int16 tempMiddleX; int16 tempMiddleY; int16 baseX = _moveSet[_moveSetType]->getBaseX(); int16 baseY = _moveSet[_moveSetType]->getBaseY(); // any chance? - if(baseX == 320) { + if (baseX == 320) { tempMiddleY = _middleY - (baseY - 240); } else { tempMiddleY = _middleY; @@ -187,38 +162,46 @@ void Hero::countDrawPosition() { int16 frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); int scaledX = getScaledValue(frameXSize); // ebx int scaledY = getScaledValue(frameYSize); // edx - int tempHeroHeight = scaledY; // not used? global? - - int width = scaledX / 2; - tempMiddleX = _middleX - width; //eax - int z = _middleY; //ebp - int y = _middleY - scaledY; //ecx - //TODO - checkNak(); - - //zoomSprite(tempMiddleY); - // zoomSprite: int sprModulo; - if(_zoomFactor != 0) { + + Graphics::Surface *surf = new Graphics::Surface(); + surf->create(scaledX, scaledY, Graphics::PixelFormat::createFormatCLUT8()); + + if (_zoomFactor != 0) { //notfullSize - int sprFullHeight = frameXSize; - sprModulo = tempMiddleY; // ebp ??? + //int sprFullHeight = frameXSize; + sprModulo = frameXSize; //int sprSkipX = 0; //int sprSkipY = 0; int sprWidth = scaledX; int sprHeight = scaledY; // after resize - int allocMemSize = sprWidth*sprHeight; - sprFullHeight--; - int imulEDX = sprFullHeight*sprModulo; // edx + //int allocMemSize = sprWidth*sprHeight; + //sprFullHeight--; + //int imulEDX = sprFullHeight*sprModulo; // hop do ostatniej linii int sprZoomX; int sprZoomY = _scaleValue; int loop_lin; + /* + for (uint y = 0; y < heroFrame->h; ++y) { + for (uint x = 0; x < heroFrame->w; ++x) { + byte pixel = *((byte*)heroFrame->getBasePtr(x, y)); + *((byte*)surf->getBasePtr(x, y)) = pixel; + } + } + */ + + uint x1 = 0; + uint y1 = 0; + + uint x2 = 0; + uint y2 = 0; + for(int i = 0; i < sprHeight; i++) { // linear_loop: while(1) { sprZoomY -= 100; - if(sprZoomY >= 0 || _scaleValue == 10000) { + if (sprZoomY >= 0 || _scaleValue == 10000) { // all_r_y // push esi loop_lin = sprWidth; @@ -228,10 +211,15 @@ void Hero::countDrawPosition() { } else { sprZoomY += _scaleValue; // add esi, sprModulo /? + //heroFrame += sprModulo; + x1 = 0; + y1++; } } // end of linear_loop // loop_lin: + debug("loop_lin: %d", loop_lin); + for(int i = 0; i < loop_lin; i++) { // mov al, b[esi] // inc esi @@ -240,39 +228,77 @@ void Hero::countDrawPosition() { //its_all_r // without ZOOMFIX //mov [edi], al + //memcpy(surf->getBasePtr(0, i), frameData + 4 + width * i, width); + memcpy(surf->getBasePtr(x2, y2), heroFrame->getBasePtr(x1, y1), 1); // inc edi + //surf++; + x2++; + if(x2 > scaledX) { + x2 = 0; + y2++; + } + } else { sprZoomX += _scaleValue; } + //heroFrame++; + x1++; + if(x1 > frameXSize) { + x1 = 0; + y1++; + } + } //pop esi //add esi, sprModulo - debug("loop_lin: %d", loop_lin); + //heroFrame += (sprModulo - loop_lin); + x2 = 0; + y2++; + x1 = 0; + y1++; } + return surf; + } + return heroFrame; +} + +void Hero::countDrawPosition() { + //int16 tempMiddleX; + int16 tempMiddleY; + int16 baseX = _moveSet[_moveSetType]->getBaseX(); + int16 baseY = _moveSet[_moveSetType]->getBaseY(); + // any chance? + if (baseX == 320) { + tempMiddleY = _middleY - (baseY - 240); + } else { + tempMiddleY = _middleY; + } + int16 frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); + int16 frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); + int scaledX = getScaledValue(frameXSize); + int scaledY = getScaledValue(frameYSize); + + //TODO + //int tempHeroHeight = scaledY; // not used? global? + //int width = scaledX / 2; + //tempMiddleX = _middleX - width; //eax + //int z = _middleY; //ebp + //int y = _middleY - scaledY; //ecx + //checkNak(); + + if (_zoomFactor != 0) { + //notfullSize debug("scaledX: %d", scaledX); debug("scaledY: %d", scaledY); - _drawX = _middleX - frameXSize/2; - _drawY = _middleY - frameYSize; + _drawX = _middleX - scaledX/2; + _drawY = tempMiddleY + 1 - scaledY; } else { //fullSize - sprModulo = 0; //? _drawX = _middleX - frameXSize / 2; _drawY = tempMiddleY + 1 - frameYSize; } - - // ShowSprite } -/* -AnimHeader struc ;struktura naglowka pliku z animacja -AH_ID dw 0 ;ID = "AN" -AH_Loop dw 0 ;numer fazy do petli -AH_Fazy dw 0 ;ilosc faz animacji -AH_Ramki dw 0 ;ilosc ramek grafiki -AH_X dw 0 ;poczatkowa wsp¢lrzedna X -AH_Y dw 0 ;poczatkowa wsp¢lrzedna Y -AH_Tablica dd 0 ;offset tablicy faz -AH_RamkiAddr dd 0 ;poczatek tablicy z offsetami ramek -*/ + void Hero::showHeroAnimFrame() { if (_phase < _moveSet[_moveSetType]->getFrameCount() - 1) { _phase++; diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 2914b1f01ade..6f6c614315b4 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -106,7 +106,7 @@ class Hero { void selectZoom(); void countDrawPosition(); void checkNak(); - void zoomSprite(int16 tempMiddleY); + Graphics::Surface *zoomSprite(Graphics::Surface *heroFrame); void showHeroAnimFrame(); void specialAnim(); void getState(); From 4bf4847cc36dd9c45792f21f285a1f6778d60eb5 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 30 Apr 2014 15:12:07 +0200 Subject: [PATCH 074/374] PRINCE: Code clean up. loadShadow() implement --- engines/prince/hero.cpp | 102 +++++++++----------------------------- engines/prince/hero.h | 1 + engines/prince/prince.cpp | 5 ++ 3 files changed, 30 insertions(+), 78 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index f4a1c9ece13e..2ef16cc61726 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -36,6 +36,7 @@ Hero::Hero() : _number(0), _visible(false), _state(MOVE), _middleX(0), _middleY( , _specAnim(0), _drawX(0), _drawY(0), _randomSource("prince"), _zoomFactor(0), _scaleValue(0) { _zoomBitmap = new Animation(); + _shadowBitmap = new Animation(); } Hero::~Hero() { @@ -82,8 +83,6 @@ const Graphics::Surface * Hero::getSurface() { //getState(); int16 phaseFrameIndex = _moveSet[_moveSetType]->getPhaseFrameIndex(_phase); Graphics::Surface *heroFrame = _moveSet[_moveSetType]->getFrame(phaseFrameIndex); - //return _moveSet[_moveSetType]->getFrame(phaseFrameIndex); - //return heroFrame; return zoomSprite(heroFrame); } return NULL; @@ -148,7 +147,6 @@ void Hero::checkNak() { } Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) { - int16 tempMiddleX; int16 tempMiddleY; int16 baseX = _moveSet[_moveSetType]->getBaseX(); int16 baseY = _moveSet[_moveSetType]->getBaseY(); @@ -160,110 +158,58 @@ Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) { } int16 frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); int16 frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); - int scaledX = getScaledValue(frameXSize); // ebx - int scaledY = getScaledValue(frameYSize); // edx - int sprModulo; + int scaledXSize = getScaledValue(frameXSize); + int scaledYSize = getScaledValue(frameYSize); - Graphics::Surface *surf = new Graphics::Surface(); - surf->create(scaledX, scaledY, Graphics::PixelFormat::createFormatCLUT8()); + Graphics::Surface *zoomedFrame = new Graphics::Surface(); + zoomedFrame->create(scaledXSize, scaledYSize, Graphics::PixelFormat::createFormatCLUT8()); if (_zoomFactor != 0) { - //notfullSize - //int sprFullHeight = frameXSize; - sprModulo = frameXSize; - //int sprSkipX = 0; - //int sprSkipY = 0; - int sprWidth = scaledX; - int sprHeight = scaledY; // after resize - //int allocMemSize = sprWidth*sprHeight; - //sprFullHeight--; - //int imulEDX = sprFullHeight*sprModulo; // hop do ostatniej linii int sprZoomX; int sprZoomY = _scaleValue; - int loop_lin; - - /* - for (uint y = 0; y < heroFrame->h; ++y) { - for (uint x = 0; x < heroFrame->w; ++x) { - byte pixel = *((byte*)heroFrame->getBasePtr(x, y)); - *((byte*)surf->getBasePtr(x, y)) = pixel; - } - } - */ - - uint x1 = 0; - uint y1 = 0; + uint xSource = 0; + uint ySource = 0; + uint xDest = 0; + uint yDest = 0; - uint x2 = 0; - uint y2 = 0; - - for(int i = 0; i < sprHeight; i++) { + for (int i = 0; i < scaledYSize; i++) { // linear_loop: while(1) { sprZoomY -= 100; if (sprZoomY >= 0 || _scaleValue == 10000) { // all_r_y - // push esi - loop_lin = sprWidth; - // mov ah, -1 sprZoomX = _scaleValue; break; // to loop_lin } else { sprZoomY += _scaleValue; - // add esi, sprModulo /? - //heroFrame += sprModulo; - x1 = 0; - y1++; + xSource = 0; + ySource++; } } - // end of linear_loop // loop_lin: - debug("loop_lin: %d", loop_lin); - - for(int i = 0; i < loop_lin; i++) { - // mov al, b[esi] - // inc esi + for (int i = 0; i < scaledXSize; i++) { sprZoomX -= 100; - if(sprZoomX >= 0) { - //its_all_r - // without ZOOMFIX - //mov [edi], al - //memcpy(surf->getBasePtr(0, i), frameData + 4 + width * i, width); - memcpy(surf->getBasePtr(x2, y2), heroFrame->getBasePtr(x1, y1), 1); - // inc edi - //surf++; - x2++; - if(x2 > scaledX) { - x2 = 0; - y2++; - } - + if (sprZoomX >= 0) { + // its_all_r + memcpy(zoomedFrame->getBasePtr(xDest, yDest), heroFrame->getBasePtr(xSource, ySource), 1); + xDest++; } else { sprZoomX += _scaleValue; + i--; } - //heroFrame++; - x1++; - if(x1 > frameXSize) { - x1 = 0; - y1++; - } - + xSource++; } - //pop esi - //add esi, sprModulo - //heroFrame += (sprModulo - loop_lin); - x2 = 0; - y2++; - x1 = 0; - y1++; + xDest = 0; + yDest++; + xSource = 0; + ySource++; } - return surf; + return zoomedFrame; } return heroFrame; } void Hero::countDrawPosition() { - //int16 tempMiddleX; int16 tempMiddleY; int16 baseX = _moveSet[_moveSetType]->getBaseX(); int16 baseY = _moveSet[_moveSetType]->getBaseY(); diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 6f6c614315b4..3d09f8a965d1 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -151,6 +151,7 @@ class Hero { Common::Array _moveSet; // MoveAnims MoveSet // TurnAnim ?? Animation *_zoomBitmap; // change to sth else, not Animation ?? + Animation *_shadowBitmap; uint32 _moveDelay; uint32 _shadMinus; //?? diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 324c4592aed5..37581318e56b 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -283,6 +283,11 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mainHero->_zoomBitmap->clear(); Resource::loadResource(_mainHero->_zoomBitmap, "zoom", false); + _mainHero->_shadowBitmap->clear(); + if(Resource::loadResource(_mainHero->_shadowBitmap, "shadow", false) == false) { + Resource::loadResource(_mainHero->_shadowBitmap, "shadow2", false); + } + _mobList.clear(); Resource::loadResource(_mobList, "mob.lst", false); From 3751e7ba25088b941eed55ee56e7a67593e32b8d Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 1 May 2014 13:14:06 +0200 Subject: [PATCH 075/374] PRINCE: lightX, lightY and setShadowScale() --- engines/prince/hero.cpp | 14 ++++++++++++++ engines/prince/hero.h | 6 ++++++ engines/prince/prince.cpp | 6 ++++++ engines/prince/script.cpp | 2 +- engines/prince/script.h | 4 ++++ 5 files changed, 31 insertions(+), 1 deletion(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 2ef16cc61726..b4c1f8304bbd 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -34,6 +34,7 @@ Hero::Hero() : _number(0), _visible(false), _state(MOVE), _middleX(0), _middleY( , _boreNum(1), _currHeight(0), _moveDelay(0), _shadMinus(1), _moveSetType(0) , _lastDirection(DOWN), _destDirection(DOWN), _talkTime(0), _boredomTime(0), _phase(0) , _specAnim(0), _drawX(0), _drawY(0), _randomSource("prince"), _zoomFactor(0), _scaleValue(0) + , _shadZoomFactor(0), _shadScaleValue(0) { _zoomBitmap = new Animation(); _shadowBitmap = new Animation(); @@ -277,6 +278,19 @@ void Hero::selectZoom() { setScale(zoomBitmapValue); } +void Hero::setShadowScale(int32 shadowScale) { + shadowScale = 100 - shadowScale; + if (shadowScale == 0) { + _shadZoomFactor = 0; + _shadScaleValue = 10000; + } else { + _shadZoomFactor = shadowScale; + _shadScaleValue = 10000 / _shadZoomFactor; + } + debug("_shadZoomFactor: %d", _shadZoomFactor); + debug("_shadScaleValue: %d", _shadScaleValue); +} + void Hero::specialAnim() { } diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 3d09f8a965d1..36856ea921d3 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -108,6 +108,7 @@ class Hero { void checkNak(); Graphics::Surface *zoomSprite(Graphics::Surface *heroFrame); void showHeroAnimFrame(); + void setShadowScale(int32 shadowScale); void specialAnim(); void getState(); @@ -124,6 +125,11 @@ class Hero { int16 _moveSetType; int8 _zoomFactor; int16 _scaleValue; + int16 _lightX; // for hero's shadow + int16 _lightY; + int32 _shadZoomFactor; + int32 _shadScaleValue; + // Coords array of coordinates // DirTab array of directions diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 37581318e56b..61d1ce5ef566 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -288,6 +288,12 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { Resource::loadResource(_mainHero->_shadowBitmap, "shadow2", false); } + _mainHero->_lightX = _script->getLightX(_locationNr); + _mainHero->_lightY = _script->getLightY(_locationNr); + debug("lightX: %d", _mainHero->_lightX); + debug("lightY: %d", _mainHero->_lightX); + _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); + _mobList.clear(); Resource::loadResource(_mobList, "mob.lst", false); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 84ae64791e28..264d5bbae277 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -132,7 +132,7 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) { return false; stream.read(_data, _dataSize); - + Common::MemoryReadStream scriptDataStream(_data, _dataSize); scriptDataStream.seek(getRoomTableOffset()+64); debug("room table offset %d", scriptDataStream.pos()); diff --git a/engines/prince/script.h b/engines/prince/script.h index d51e01b5590f..2a3bb6424580 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -42,6 +42,7 @@ namespace Detail { template <> inline uint8 LittleEndianReader(void *data) { return *(uint8*)(data); } template <> inline uint16 LittleEndianReader(void *data) { return READ_LE_UINT16(data); } template <> inline uint32 LittleEndianReader(void *data) { return READ_LE_UINT32(data); } + template <> inline int8 LittleEndianReader(void *data) { return *(int8*)(data); } } class Room { @@ -89,6 +90,9 @@ class Script { // Some magic numbers for now, data stored in header uint32 getRoomTableOffset() { return read(0); } uint32 getStartGameOffset() { return read(4); } + int8 getLightX(int locationNr) { return read(4*15 + locationNr*8); } + int8 getLightY(int locationNr) { return read(4*15 + locationNr*8 + 2); } + uint16 getShadowScale(int locationNr) { return read(4*15 + locationNr*8 + 4); } const char *getString(uint32 offset) { return (const char *)(&_data[offset]); From 05ef38f7d9f912f8613d56764aa93c85e3365bbc Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 1 May 2014 16:40:12 +0200 Subject: [PATCH 076/374] PRINCE: getLightX, getLightY, getShadowScale fix --- engines/prince/prince.cpp | 2 +- engines/prince/script.cpp | 20 +++++++++++++++++++- engines/prince/script.h | 6 +++--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 61d1ce5ef566..7bb51411f14d 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -291,7 +291,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mainHero->_lightX = _script->getLightX(_locationNr); _mainHero->_lightY = _script->getLightY(_locationNr); debug("lightX: %d", _mainHero->_lightX); - debug("lightY: %d", _mainHero->_lightX); + debug("lightY: %d", _mainHero->_lightY); _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); _mobList.clear(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 264d5bbae277..5070236c729e 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -132,7 +132,7 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) { return false; stream.read(_data, _dataSize); - + Common::MemoryReadStream scriptDataStream(_data, _dataSize); scriptDataStream.seek(getRoomTableOffset()+64); debug("room table offset %d", scriptDataStream.pos()); @@ -142,6 +142,24 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) { return true; } +int16 Script::getLightX(int locationNr) { + Common::MemoryReadStream readS(_data, _dataSize); + readS.seek(4*15 + locationNr*8); + return readS.readSint16LE(); +} + +int16 Script::getLightY(int locationNr) { + Common::MemoryReadStream readS(_data, _dataSize); + readS.seek(4*15 + locationNr*8 + 2); + return readS.readSint16LE(); +} + +int32 Script::getShadowScale(int locationNr) { + Common::MemoryReadStream readS(_data, _dataSize); + readS.seek(4*15 + locationNr*8 + 4); + return readS.readSint32LE(); +} + InterpreterFlags::InterpreterFlags() { resetAllFlags(); } diff --git a/engines/prince/script.h b/engines/prince/script.h index 2a3bb6424580..4d3c822ad671 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -90,9 +90,9 @@ class Script { // Some magic numbers for now, data stored in header uint32 getRoomTableOffset() { return read(0); } uint32 getStartGameOffset() { return read(4); } - int8 getLightX(int locationNr) { return read(4*15 + locationNr*8); } - int8 getLightY(int locationNr) { return read(4*15 + locationNr*8 + 2); } - uint16 getShadowScale(int locationNr) { return read(4*15 + locationNr*8 + 4); } + int16 getLightX(int locationNr); + int16 getLightY(int locationNr); + int32 getShadowScale(int locationNr); const char *getString(uint32 offset) { return (const char *)(&_data[offset]); From acf9ac241eb1d23d435643f0d0ff2c04d78945d9 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 1 May 2014 18:50:20 +0200 Subject: [PATCH 077/374] PRINCE: Proper memory reading for lightX, lightY, shadowScale --- engines/prince/script.cpp | 40 ++++++++++++++++++++++++++------------- engines/prince/script.h | 30 +++++++++++++++++++++++++---- 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 5070236c729e..11cba8fdf962 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -134,30 +134,44 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) { stream.read(_data, _dataSize); Common::MemoryReadStream scriptDataStream(_data, _dataSize); - scriptDataStream.seek(getRoomTableOffset()+64); - debug("room table offset %d", scriptDataStream.pos()); - Room room; - room.loadFromStream(scriptDataStream); + _scriptInfo.rooms = scriptDataStream.readSint32LE(); + _scriptInfo.startGame = scriptDataStream.readSint32LE(); + _scriptInfo.restoreGame = scriptDataStream.readSint32LE(); + _scriptInfo.stdExamine = scriptDataStream.readSint32LE(); + _scriptInfo.stdPickup = scriptDataStream.readSint32LE(); + _scriptInfo.stdUse = scriptDataStream.readSint32LE(); + _scriptInfo.stdOpen = scriptDataStream.readSint32LE(); + _scriptInfo.stdClose = scriptDataStream.readSint32LE(); + _scriptInfo.stdTalk = scriptDataStream.readSint32LE(); + _scriptInfo.stdGive = scriptDataStream.readSint32LE(); + _scriptInfo.usdCode = scriptDataStream.readSint32LE(); + _scriptInfo.invObjExam = scriptDataStream.readSint32LE(); + _scriptInfo.invObjUse = scriptDataStream.readSint32LE(); + _scriptInfo.invObjUU = scriptDataStream.readSint32LE(); + _scriptInfo.stdUseItem = scriptDataStream.readSint32LE(); + _scriptInfo.lightSources = scriptDataStream.readSint32LE(); + _scriptInfo.specRout = scriptDataStream.readSint32LE(); + _scriptInfo.invObjGive = scriptDataStream.readSint32LE(); + _scriptInfo.stdGiveItem = scriptDataStream.readSint32LE(); + _scriptInfo.goTester = scriptDataStream.readSint32LE(); return true; } int16 Script::getLightX(int locationNr) { - Common::MemoryReadStream readS(_data, _dataSize); - readS.seek(4*15 + locationNr*8); - return readS.readSint16LE(); + return (int)READ_UINT16(&_data[_scriptInfo.lightSources + locationNr * 8]); } int16 Script::getLightY(int locationNr) { - Common::MemoryReadStream readS(_data, _dataSize); - readS.seek(4*15 + locationNr*8 + 2); - return readS.readSint16LE(); + return (int)READ_UINT16(&_data[_scriptInfo.lightSources + locationNr * 8 + 2]); } int32 Script::getShadowScale(int locationNr) { - Common::MemoryReadStream readS(_data, _dataSize); - readS.seek(4*15 + locationNr*8 + 4); - return readS.readSint32LE(); + return (int)READ_UINT16(&_data[_scriptInfo.lightSources + locationNr * 8 + 4]); +} + +uint32 Script::getStartGameOffset() { + return _scriptInfo.startGame; } InterpreterFlags::InterpreterFlags() { diff --git a/engines/prince/script.h b/engines/prince/script.h index 4d3c822ad671..f21df1d717cb 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -42,7 +42,6 @@ namespace Detail { template <> inline uint8 LittleEndianReader(void *data) { return *(uint8*)(data); } template <> inline uint16 LittleEndianReader(void *data) { return READ_LE_UINT16(data); } template <> inline uint32 LittleEndianReader(void *data) { return READ_LE_UINT32(data); } - template <> inline int8 LittleEndianReader(void *data) { return *(int8*)(data); } } class Room { @@ -79,6 +78,29 @@ class Script { Script(); ~Script(); + struct ScriptInfo { + int rooms; + int startGame; + int restoreGame; + int stdExamine; + int stdPickup; + int stdUse; + int stdOpen; + int stdClose; + int stdTalk; + int stdGive; + int usdCode; + int invObjExam; + int invObjUse; + int invObjUU; + int stdUseItem; + int lightSources; + int specRout; + int invObjGive; + int stdGiveItem; + int goTester; + }; + bool loadFromStream(Common::SeekableReadStream &stream); template @@ -87,9 +109,8 @@ class Script { return Detail::LittleEndianReader(&_data[address]); } - // Some magic numbers for now, data stored in header - uint32 getRoomTableOffset() { return read(0); } - uint32 getStartGameOffset() { return read(4); } + //uint32 getRoomTableOffset(); + uint32 getStartGameOffset(); int16 getLightX(int locationNr); int16 getLightY(int locationNr); int32 getShadowScale(int locationNr); @@ -102,6 +123,7 @@ class Script { uint8 *_data; uint32 _dataSize; Common::Array _roomList; + ScriptInfo _scriptInfo; }; class InterpreterFlags { From 6565c95279cbea8c2f94fc3d5d05adb675e7f327 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 2 May 2014 22:31:18 +0200 Subject: [PATCH 078/374] PRINCE: makeShadowTable(), shadowMinus, begin of showHeroShadow() --- engines/prince/graphics.cpp | 18 ++++++++++++++++++ engines/prince/graphics.h | 4 ++++ engines/prince/hero.cpp | 38 ++++++++++++++++++++++++++++++++++--- engines/prince/hero.h | 5 ++++- engines/prince/hero_set.h | 1 + engines/prince/prince.cpp | 5 ++++- engines/prince/prince.h | 1 + 7 files changed, 67 insertions(+), 5 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 3f9517a6e9c8..c4e994fe7ed7 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -26,6 +26,8 @@ #include "graphics/palette.h" +#include "common/memstream.h" + namespace Prince { GraphicsMan::GraphicsMan(PrinceEngine *vm) @@ -33,11 +35,15 @@ GraphicsMan::GraphicsMan(PrinceEngine *vm) initGraphics(640, 480, true); _frontScreen = new Graphics::Surface(); _frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); + _shadowTable70 = new byte[256 * 3]; + _shadowTable50 = new byte[256 * 3]; } GraphicsMan::~GraphicsMan() { _frontScreen->free(); delete _frontScreen; + delete[] _shadowTable70; + delete[] _shadowTable50; } void GraphicsMan::update() { @@ -82,6 +88,18 @@ void GraphicsMan::drawTransparent(uint16 posX, uint16 posY, const Graphics::Surf change(); } +void GraphicsMan::makeShadowTable(int brightness, byte *shadowPallete) { + int shadow = brightness * 256 / 100; + byte *orginalPallete = new byte[256 * 3]; + _vm->_system->getPaletteManager()->grabPalette(orginalPallete, 0, 256); + Common::MemoryReadStream readS(orginalPallete, 256 * 3); + Common::MemoryWriteStream writeS(shadowPallete, 256 * 3); + for(int i = 0; i < 256 * 3; i++) { + writeS.writeByte(readS.readByte() * shadow / 256); + } + delete[] orginalPallete; +} + } /* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index 1766e2a04e2d..62dd89c9eeb5 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -41,6 +41,7 @@ class GraphicsMan void change(); void setPalette(const byte *palette); + void makeShadowTable(int brightness, byte *shadowTable); void draw(uint16 x, uint16 y, const Graphics::Surface *s); void drawTransparent(uint16 x, uint16 y, const Graphics::Surface *s); @@ -49,6 +50,9 @@ class GraphicsMan Graphics::Surface *_backScreen; const Graphics::Surface *_roomBackground; + byte *_shadowTable70; + byte *_shadowTable50; + private: PrinceEngine *_vm; diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index b4c1f8304bbd..251f31f7c115 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -31,7 +31,7 @@ namespace Prince { Hero::Hero() : _number(0), _visible(false), _state(MOVE), _middleX(0), _middleY(0) - , _boreNum(1), _currHeight(0), _moveDelay(0), _shadMinus(1), _moveSetType(0) + , _boreNum(1), _currHeight(0), _moveDelay(0), _shadMinus(0), _moveSetType(0) , _lastDirection(DOWN), _destDirection(DOWN), _talkTime(0), _boredomTime(0), _phase(0) , _specAnim(0), _drawX(0), _drawY(0), _randomSource("prince"), _zoomFactor(0), _scaleValue(0) , _shadZoomFactor(0), _shadScaleValue(0) @@ -49,6 +49,8 @@ bool Hero::loadAnimSet(uint32 animSetNr) { return false; } + _shadMinus = heroSetBack[animSetNr]; + for (uint32 i = 0; i < _moveSet.size(); ++i) { delete _moveSet[i]; } @@ -188,7 +190,7 @@ Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) { } } // loop_lin: - for (int i = 0; i < scaledXSize; i++) { + for (int j = 0; j < scaledXSize; j++) { sprZoomX -= 100; if (sprZoomX >= 0) { // its_all_r @@ -196,7 +198,7 @@ Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) { xDest++; } else { sprZoomX += _scaleValue; - i--; + j--; } xSource++; } @@ -246,6 +248,35 @@ void Hero::countDrawPosition() { } } +Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { + int16 frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); + int16 frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); + + Graphics::Surface *makeShadow = new Graphics::Surface(); + makeShadow->create(frameXSize, frameYSize, Graphics::PixelFormat::createFormatCLUT8()); + + //make_shadow: + for (int y = 0; y < frameYSize; y++) { + //ms_loop: + for (int x = 0; x < frameXSize; x++) { + byte pixel = *(byte*) makeShadow->getBasePtr(x, y); + if (pixel == -1) { + *(byte*)(makeShadow->getBasePtr(x, y)) = kShadowColor; + } else { + memcpy(makeShadow->getBasePtr(x, y), heroFrame->getBasePtr(x, y), 1); + //*(byte*)(makeShadow->getBasePtr(x, y)) = pixel; + } + } + } + return makeShadow; + // TODO + /* + int scaledX = getScaledValue(frameXSize); + int drawX = _middleX - scaledX / 2; // just _drawX + int DN_ECX5070 = _middleY - _shadMinus; + */ +} + void Hero::showHeroAnimFrame() { if (_phase < _moveSet[_moveSetType]->getFrameCount() - 1) { _phase++; @@ -253,6 +284,7 @@ void Hero::showHeroAnimFrame() { _phase = 0; } countDrawPosition(); + //showHeroShadow(); //debug("_drawX: %d", _drawX); //debug("_drawY: %d", _drawY); //debug("_middleX: %d", _middleX); diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 36856ea921d3..211eed8a3ab9 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -39,6 +39,8 @@ class Hero { static const int16 kMaxPicWidth = 1280; static const int16 kZoomBitmapWidth = kMaxPicWidth / kZoomStep; + static const uint8 kShadowColor = 191; + enum State { STAY = 0, TURN = 1, @@ -108,6 +110,7 @@ class Hero { void checkNak(); Graphics::Surface *zoomSprite(Graphics::Surface *heroFrame); void showHeroAnimFrame(); + Graphics::Surface *showHeroShadow(Graphics::Surface *heroFrame); void setShadowScale(int32 shadowScale); void specialAnim(); void getState(); @@ -160,7 +163,7 @@ class Hero { Animation *_shadowBitmap; uint32 _moveDelay; - uint32 _shadMinus; //?? + uint32 _shadMinus; }; } diff --git a/engines/prince/hero_set.h b/engines/prince/hero_set.h index 335f70a6abd2..e0c7887b94dc 100644 --- a/engines/prince/hero_set.h +++ b/engines/prince/hero_set.h @@ -24,6 +24,7 @@ namespace Prince { typedef const char *HeroSetAnimNames[26]; +const int heroSetBack[7] = { 0, 0, 10, 0, 6, 0, 0 }; extern const HeroSetAnimNames *heroSetTable[7]; } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 7bb51411f14d..1402581b0d84 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -290,9 +290,9 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mainHero->_lightX = _script->getLightX(_locationNr); _mainHero->_lightY = _script->getLightY(_locationNr); + _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); debug("lightX: %d", _mainHero->_lightX); debug("lightY: %d", _mainHero->_lightY); - _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); _mobList.clear(); Resource::loadResource(_mobList, "mob.lst", false); @@ -306,6 +306,9 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _animList.clear(); Resource::loadResource(_animList, "anim.lst", false); + _graph->makeShadowTable(70, _graph->_shadowTable70); + _graph->makeShadowTable(50, _graph->_shadowTable50); + return true; } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index a48f056d4d7f..487a19717739 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -150,6 +150,7 @@ class PrinceEngine : public Engine { void showTexts(); void init(); void showLogo(); + void makeShadowTable(int brightness); uint32 getTextWidth(const char *s); void debugEngine(const char *s, ...); From 452895e6503dce66d0cdc6a66d44a0c02e381443 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 3 May 2014 01:57:37 +0200 Subject: [PATCH 079/374] PRINCE: makeShadowTable() update --- engines/prince/graphics.cpp | 60 +++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index c4e994fe7ed7..ea0320465777 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -35,8 +35,8 @@ GraphicsMan::GraphicsMan(PrinceEngine *vm) initGraphics(640, 480, true); _frontScreen = new Graphics::Surface(); _frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); - _shadowTable70 = new byte[256 * 3]; - _shadowTable50 = new byte[256 * 3]; + _shadowTable70 = new byte[256]; + _shadowTable50 = new byte[256]; } GraphicsMan::~GraphicsMan() { @@ -89,15 +89,57 @@ void GraphicsMan::drawTransparent(uint16 posX, uint16 posY, const Graphics::Surf } void GraphicsMan::makeShadowTable(int brightness, byte *shadowPallete) { + int32 redFirstOrg, greenFirstOrg, blueFirstOrg; + int32 redSecondOrg, greenSecondOrg, blueSecondOrg; + int32 redNew, greenNew, blueNew; + + int32 sumOfColorValues; + int32 bigValue; + int32 currColor; + int shadow = brightness * 256 / 100; - byte *orginalPallete = new byte[256 * 3]; - _vm->_system->getPaletteManager()->grabPalette(orginalPallete, 0, 256); - Common::MemoryReadStream readS(orginalPallete, 256 * 3); - Common::MemoryWriteStream writeS(shadowPallete, 256 * 3); - for(int i = 0; i < 256 * 3; i++) { - writeS.writeByte(readS.readByte() * shadow / 256); + byte *originalPallete = new byte[256 * 3]; + + _vm->_system->getPaletteManager()->grabPalette(originalPallete, 0, 256); + Common::MemoryReadStream readFirstStream(originalPallete, 256 * 3); + Common::MemoryWriteStream writeStream(shadowPallete, 256); + + for (int i = 0; i < 256; i++) { + redFirstOrg = readFirstStream.readByte() * shadow / 256; + greenFirstOrg = readFirstStream.readByte() * shadow / 256; + blueFirstOrg = readFirstStream.readByte() * shadow / 256; + + currColor = 0; + Common::MemoryReadStream readSecondStream(originalPallete, 256 * 3); + bigValue = 999999999; // infinity + + for (int j = 0; j < 256; j++) { + redSecondOrg = readSecondStream.readByte(); + redNew = redFirstOrg - redSecondOrg; + redNew = redNew * redNew; + + greenSecondOrg = readSecondStream.readByte(); + greenNew = greenFirstOrg - greenSecondOrg; + greenNew = greenNew * greenNew; + + blueSecondOrg = readSecondStream.readByte(); + blueNew = blueFirstOrg - blueSecondOrg; + blueNew = blueNew * blueNew; + + sumOfColorValues = redNew + greenNew + blueNew; + + if (sumOfColorValues < bigValue) { + bigValue = sumOfColorValues; + currColor = j; + } + + if (sumOfColorValues == 0) { + break; + } + } + writeStream.writeByte(currColor); } - delete[] orginalPallete; + delete[] originalPallete; } } From 583d6bdca10deb14578fa68bbee23e77c154d0f0 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 4 May 2014 18:02:53 +0200 Subject: [PATCH 080/374] PRINCE: scrollHero() --- engines/prince/hero.cpp | 82 +++++++++++++++++++++++++++++++++++---- engines/prince/hero.h | 7 +++- engines/prince/prince.cpp | 13 +++++-- engines/prince/prince.h | 9 +++-- 4 files changed, 95 insertions(+), 16 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 251f31f7c115..177ee0c98197 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -26,11 +26,12 @@ #include "prince/hero_set.h" #include "prince/animation.h" #include "prince/resource.h" +#include "prince/prince.h" namespace Prince { -Hero::Hero() : _number(0), _visible(false), _state(MOVE), _middleX(0), _middleY(0) +Hero::Hero(PrinceEngine *vm) : _vm(vm), _number(0), _visible(false), _state(MOVE), _middleX(0), _middleY(0) , _boreNum(1), _currHeight(0), _moveDelay(0), _shadMinus(0), _moveSetType(0) , _lastDirection(DOWN), _destDirection(DOWN), _talkTime(0), _boredomTime(0), _phase(0) , _specAnim(0), _drawX(0), _drawY(0), _randomSource("prince"), _zoomFactor(0), _scaleValue(0) @@ -269,12 +270,44 @@ Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { } } return makeShadow; - // TODO - /* - int scaledX = getScaledValue(frameXSize); - int drawX = _middleX - scaledX / 2; // just _drawX - int DN_ECX5070 = _middleY - _shadMinus; - */ + + // source Bitmap of sprite - esi + //int destX = _drawX; // eax + int destY = _middleY - _shadMinus; // ecx + // modulo of source Bitmap - ebp + //int scaledX = getScaledValue(frameXSize); // ebx + //int scaledY = getScaledValue(frameYSize); // edx + // shadowTable70 - edi + + if (destY > 1 && destY < kMaxPicHeight) { + // pushad + // edx = destY + // ecx = destX + // ebx = _lightY + // eax = _lightX + + int shadowDirection; + if (_lightY > destY) { + shadowDirection = 1; + } else { + shadowDirection = 0; + } + //int shadowLineLen = 0; + //int shadWallDown = 0; + // int shadowLine = Linijka(); + // push lineCode + // mov lineCode <- @@Nopik + // Line(); + // pop lineCode + // popad + + // sprShadow = shadowTable70 + // sprModulo = modulo of source Bitmap + // sprWidth = scaledX + // sprHeight = scaledY + //int sprDestX = destX - PicWindowX; + //int sprDestY = destY - PicWindowY; + } } void Hero::showHeroAnimFrame() { @@ -491,6 +524,41 @@ void Hero::showHero() { return; } } + +void Hero::scrollHero() { + //FLAGI+SCROLLTYPE ?? + //int scrollType = 0; + int position = _middleX; + + /* + switch (scrollType) { + case 0: + position = _middleX; + break; + case 1: + break; + case 2: + break; + } + */ + + int locationWidth = _vm->_sceneWidth; + int difference = locationWidth - kNormalWidth / 2; + + int destValue = 0; + if (position > kNormalWidth / 2) { + destValue = difference - kNormalWidth / 2; + } + if (position < difference) { + destValue = position - kNormalWidth / 2; + } + if(destValue < 0) { + destValue = 0; + } + _vm->_picWindowX = destValue; + _drawX -= destValue; +} + } /* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 211eed8a3ab9..edc95e12caea 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -31,13 +31,16 @@ namespace Prince { class Animation; +class PrinceEngine; class Hero { public: static const uint32 kMoveSetSize = 26; static const int16 kZoomStep = 4; static const int16 kMaxPicWidth = 1280; + static const int16 kMaxPicHeight = 480; static const int16 kZoomBitmapWidth = kMaxPicWidth / kZoomStep; + static const int16 kNormalWidth = 640; static const uint8 kShadowColor = 191; @@ -90,7 +93,7 @@ class Hero { Move_BORED2 }; - Hero(); + Hero(PrinceEngine *vm); ~Hero(); Common::RandomSource _randomSource; bool loadAnimSet(uint32 heroAnimNumber); @@ -103,6 +106,7 @@ class Hero { void showHero(); void moveHero(); void rotateHero(); + void scrollHero(); void setScale(int8 zoomBitmapValue); int getScaledValue(int size); void selectZoom(); @@ -116,6 +120,7 @@ class Hero { void getState(); //private: + PrinceEngine *_vm; uint16 _number; uint16 _visible; int16 _state; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 1402581b0d84..fc109b31cee4 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -78,7 +78,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) Engine(syst), _gameDescription(gameDesc), _graph(nullptr), _script(nullptr), _interpreter(nullptr), _flags(nullptr), _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), _cameraX(0), _newCameraX(0), _frameNr(0), _cursor1(nullptr), _cursor2(nullptr), _font(nullptr), - _walizkaBmp(nullptr), _roomBmp(nullptr), _cursorNr(0) { + _walizkaBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -186,8 +186,8 @@ void PrinceEngine::init() { _roomBmp = new Image::BitmapDecoder(); - _mainHero = new Hero(); - _secondHero = new Hero(); + _mainHero = new Hero(this); + _secondHero = new Hero(this); _mainHero->loadAnimSet(0); } @@ -288,6 +288,8 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { Resource::loadResource(_mainHero->_shadowBitmap, "shadow2", false); } + _picWindowX = 0; + _mainHero->_lightX = _script->getLightX(_locationNr); _mainHero->_lightY = _script->getLightY(_locationNr); _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); @@ -633,7 +635,7 @@ void PrinceEngine::drawScreen() { const Graphics::Surface *roomSurface = _roomBmp->getSurface(); if (roomSurface) { _graph->setPalette(_roomBmp->getPalette()); - const Graphics::Surface visiblePart = roomSurface->getSubArea(Common::Rect(_cameraX, 0, roomSurface->w, roomSurface->h)); + const Graphics::Surface visiblePart = roomSurface->getSubArea(Common::Rect(_picWindowX, 0, roomSurface->w, roomSurface->h)); _graph->draw(0, 0, &visiblePart); } @@ -695,6 +697,9 @@ void PrinceEngine::mainLoop() { // TODO: Update all structures, animations, naks, heros etc. _mainHero -> showHero(); + if(_mainHero->_visible == 1) { + _mainHero -> scrollHero(); + } _interpreter->step(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 487a19717739..3dd372dd48ea 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -140,6 +140,11 @@ class PrinceEngine : public Engine { Hero* _mainHero; Hero* _secondHero; + uint16 _cameraX; + uint16 _newCameraX; + uint16 _sceneWidth; + uint32 _picWindowX; + private: bool playNextFrame(); void keyHandler(Common::Event event); @@ -181,10 +186,6 @@ class PrinceEngine : public Engine { Common::Array _objList; Common::Array _animList; - uint16 _cameraX; - uint16 _newCameraX; - uint16 _sceneWidth; - bool _flicLooped; void mainLoop(); From fff1ff5b1a4dc6d24d8592d73677e5a69471c1a0 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 6 May 2014 22:46:45 +0200 Subject: [PATCH 081/374] PRINCE: showHeroShadow update, line() implementation --- engines/prince/hero.cpp | 126 +++++++++++++++++++++++++++++++++++++- engines/prince/hero.h | 1 + engines/prince/prince.cpp | 2 +- engines/prince/prince.h | 1 + 4 files changed, 126 insertions(+), 4 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 177ee0c98197..57743b706987 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -249,6 +249,79 @@ void Hero::countDrawPosition() { } } +void Hero::line(int x1, int y1, int x2, int y2) { + //EAX - x1 <- LightX + //EBX - y1 <- LightY + //ECX - x2 <- DestX + //EDX - y2 <- DestY + + //pushad + int dX = 1; + int vx = y2 - y1; + if(x2 <= x1) { + dX = -1; + vx = -1 * vx; + } + // pl_1 + int lvx = vx; + int dY = 1; + int vy = x1 - x2; + if (y2 <= y1) { + dY = -1; + vy = -1 * vy; + } + // pl_2 + int lvy = vy; + int lx = x1; + int ly = y1; + int lx2 = x2; + int ly2 = y2; + int lfa = 0; + + //loop + //if (x1 != x2 && y1 != y2) { + while (lx != lx2 && ly != ly2) { + // not_end + // pushad + // LineCode() ? + // popad + int lfx = lfa + lvx; + int lfy = lfa + lvy; + int lfxy = lfx + lfy - lfa; + if (lfxy < 0) { + lfxy = -1 * lfxy; + } + //abs_fxy_done + if (lfx < 0) { + lfx = -1 * lfx; + } + //abs_fx_done + if (lfy < 0) { + lfy = -1 * lfy; + } + //abs_fy_done + if (lfx > lfy || lfx > lfxy) { + //c2 + if (lfy >= lfx || lfy > lfxy) { + //c3 + ly += dY; + lx += dX; + lfa = lfxy; + } else { + ly += dY; + lfa = lfa + lvy; // lfx / lfy = ? + } + } else { + lx += dX; + lfa = lfa + lvx; //9600 ??? + // jump to @@next + } + //next + // + } + +} + Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { int16 frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); int16 frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); @@ -272,7 +345,7 @@ Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { return makeShadow; // source Bitmap of sprite - esi - //int destX = _drawX; // eax + int destX = _drawX; // eax int destY = _middleY - _shadMinus; // ecx // modulo of source Bitmap - ebp //int scaledX = getScaledValue(frameXSize); // ebx @@ -305,8 +378,55 @@ Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { // sprModulo = modulo of source Bitmap // sprWidth = scaledX // sprHeight = scaledY - //int sprDestX = destX - PicWindowX; - //int sprDestY = destY - PicWindowY; + int sprDestX = destX - _vm->_picWindowX; + int sprDestY = destY - _vm->_picWindowY; + + int shadPosX = sprDestX; + int shadMinX = sprDestX; + int shadMaxX = sprDestX; + + int shadPosY = sprDestY; + int shadMinY = sprDestY; + int shadMaxY = sprDestY; + // destY * kMaxPicWidth / 8 + destX / 8 + int shadBitAddr = _shadowBitmap->getZoom(destY * kMaxPicWidth / 8 + destX / 8); + int shadBitMask = 128 / (destX % 8); + + int shadZoomY2 = _shadScaleValue; + int shadZoomY = _scaleValue; + + // lockscreen etc + + // banked2 + // edx = linijka() + 8 + + // linear_loop + //for(int i = 0; i < ; i++) { + int ebx16795 = shadPosY; + int sprModulo = 0; + int shadSkipX = 0; + //retry_line: + for(int j = 0; j < shadPosY; j++) { + shadZoomY -= 100; + if(shadZoomY < 0 || _scaleValue != 10000) { + shadZoomY += _scaleValue; + // esi -= sprWidth + } else { + break; //to line_y_ok + } + // esp += 4*4 + // koniec_bajki + } + //line_y_ok + int shadLastY = 0; + if (shadPosY < 0 || shadPosY == shadLastY || shadPosY >= 480 || shadPosX >= 640) { + shadLastY = shadPosY; + //skip_line + + } else if (shadPosX < 0) { + shadSkipX = -1 * shadPosX; + } + //} } } diff --git a/engines/prince/hero.h b/engines/prince/hero.h index edc95e12caea..efa9027d4cc1 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -114,6 +114,7 @@ class Hero { void checkNak(); Graphics::Surface *zoomSprite(Graphics::Surface *heroFrame); void showHeroAnimFrame(); + void line(int x1, int y1, int x2, int y2); Graphics::Surface *showHeroShadow(Graphics::Surface *heroFrame); void setShadowScale(int32 shadowScale); void specialAnim(); diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index fc109b31cee4..39183d35f199 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -78,7 +78,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) Engine(syst), _gameDescription(gameDesc), _graph(nullptr), _script(nullptr), _interpreter(nullptr), _flags(nullptr), _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), _cameraX(0), _newCameraX(0), _frameNr(0), _cursor1(nullptr), _cursor2(nullptr), _font(nullptr), - _walizkaBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0) { + _walizkaBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 3dd372dd48ea..8213b2d32b43 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -144,6 +144,7 @@ class PrinceEngine : public Engine { uint16 _newCameraX; uint16 _sceneWidth; uint32 _picWindowX; + uint32 _picWindowY; private: bool playNextFrame(); From 2dc0b21bea761af1e216cae768ed02529a1038ed Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 7 May 2014 02:17:30 +0200 Subject: [PATCH 082/374] PRINCE: line() fix, shadowHeroShadow() testing --- engines/prince/hero.cpp | 66 +++++++++++++++++++++++++++-------------- engines/prince/hero.h | 5 +++- 2 files changed, 47 insertions(+), 24 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 57743b706987..3e89b23a70ed 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -39,10 +39,12 @@ Hero::Hero(PrinceEngine *vm) : _vm(vm), _number(0), _visible(false), _state(MOVE { _zoomBitmap = new Animation(); _shadowBitmap = new Animation(); + _linijka = new byte[2*1280*4]; } Hero::~Hero() { delete _zoomBitmap; + delete[] _linijka; } bool Hero::loadAnimSet(uint32 animSetNr) { @@ -278,54 +280,67 @@ void Hero::line(int x1, int y1, int x2, int y2) { int ly2 = y2; int lfa = 0; + int shadowLineLen = 0; + Common::MemoryWriteStream writeStream(_linijka, 2*1280*4); //loop - //if (x1 != x2 && y1 != y2) { - while (lx != lx2 && ly != ly2) { - // not_end - // pushad - // LineCode() ? - // popad + while (lx != lx2 || ly != ly2) { + //not_end + //nopik + if(shadowLineLen == 1280) { + break; + } + writeStream.writeUint16LE(lx); + writeStream.writeUint16LE(ly); + shadowLineLen++; + int lfx = lfa + lvx; int lfy = lfa + lvy; int lfxy = lfx + lfy - lfa; + int abs_lfxy, abs_lfx, abs_lfy; + if (lfxy < 0) { - lfxy = -1 * lfxy; + abs_lfxy = -1 * lfxy; + } else { + abs_lfxy = lfxy; } //abs_fxy_done if (lfx < 0) { - lfx = -1 * lfx; + abs_lfx = -1 * lfx; + } else { + abs_lfx = lfx; } //abs_fx_done if (lfy < 0) { - lfy = -1 * lfy; + abs_lfy = -1 * lfy; + } else { + abs_lfy = lfy; } //abs_fy_done - if (lfx > lfy || lfx > lfxy) { + + if (abs_lfx > abs_lfy || abs_lfx > abs_lfxy) { //c2 - if (lfy >= lfx || lfy > lfxy) { + if (abs_lfy >= abs_lfx || abs_lfy > abs_lfxy) { //c3 ly += dY; lx += dX; lfa = lfxy; } else { ly += dY; - lfa = lfa + lvy; // lfx / lfy = ? + lfa = lfa + lvy; } } else { lx += dX; - lfa = lfa + lvx; //9600 ??? - // jump to @@next + lfa = lfa + lvx; } //next - // } - } -Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { +void Hero::showHeroShadow() { +//Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { int16 frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); int16 frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); - + /* Graphics::Surface *makeShadow = new Graphics::Surface(); makeShadow->create(frameXSize, frameYSize, Graphics::PixelFormat::createFormatCLUT8()); @@ -342,8 +357,7 @@ Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { } } } - return makeShadow; - + */ // source Bitmap of sprite - esi int destX = _drawX; // eax int destY = _middleY - _shadMinus; // ecx @@ -370,7 +384,11 @@ Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { // int shadowLine = Linijka(); // push lineCode // mov lineCode <- @@Nopik - // Line(); + //EAX - x1 <- LightX + //EBX - y1 <- LightY + //ECX - x2 <- DestX + //EDX - y2 <- DestY + line(_lightX, _lightY, destX, destY); // pop lineCode // popad @@ -390,7 +408,7 @@ Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { int shadMaxY = sprDestY; // destY * kMaxPicWidth / 8 + destX / 8 int shadBitAddr = _shadowBitmap->getZoom(destY * kMaxPicWidth / 8 + destX / 8); - int shadBitMask = 128 / (destX % 8); + int shadBitMask = 128 / pow(2.0, (destX % 8)); int shadZoomY2 = _shadScaleValue; int shadZoomY = _scaleValue; @@ -428,6 +446,7 @@ Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { } //} } + //return makeShadow; } void Hero::showHeroAnimFrame() { @@ -437,7 +456,8 @@ void Hero::showHeroAnimFrame() { _phase = 0; } countDrawPosition(); - //showHeroShadow(); + //temp: + showHeroShadow(); //debug("_drawX: %d", _drawX); //debug("_drawY: %d", _drawY); //debug("_middleX: %d", _middleX); diff --git a/engines/prince/hero.h b/engines/prince/hero.h index efa9027d4cc1..4016e3519b4a 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -25,6 +25,7 @@ #include "common/scummsys.h" #include "common/array.h" +#include "common/memstream.h" #include "graphics/surface.h" @@ -115,7 +116,8 @@ class Hero { Graphics::Surface *zoomSprite(Graphics::Surface *heroFrame); void showHeroAnimFrame(); void line(int x1, int y1, int x2, int y2); - Graphics::Surface *showHeroShadow(Graphics::Surface *heroFrame); + //Graphics::Surface *showHeroShadow(Graphics::Surface *heroFrame); + void showHeroShadow(); void setShadowScale(int32 shadowScale); void specialAnim(); void getState(); @@ -167,6 +169,7 @@ class Hero { // TurnAnim ?? Animation *_zoomBitmap; // change to sth else, not Animation ?? Animation *_shadowBitmap; + byte *_linijka; uint32 _moveDelay; uint32 _shadMinus; From 11fc17fc50d171d567e21ba49e39f10f448cb769 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 7 May 2014 21:55:25 +0200 Subject: [PATCH 083/374] PRINCE: Change init() to Graphics::drawLine(), code clean up --- engines/prince/animation.cpp | 32 +++----- engines/prince/debugger.cpp | 2 +- engines/prince/flags.cpp | 2 +- engines/prince/graphics.cpp | 21 +++-- engines/prince/graphics.h | 4 +- engines/prince/hero.cpp | 143 ++++++++--------------------------- engines/prince/hero.h | 9 ++- engines/prince/hero_set.cpp | 14 ++-- engines/prince/mob.cpp | 38 +++++----- engines/prince/prince.cpp | 71 ++++++++--------- engines/prince/prince.h | 6 +- engines/prince/script.cpp | 6 +- engines/prince/variatxt.h | 2 +- 13 files changed, 131 insertions(+), 219 deletions(-) diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index 587316fc1969..9911f5f99e9e 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -30,7 +30,7 @@ namespace Prince { bool Animation::loadFromStream(Common::SeekableReadStream &stream) { _dataSize = stream.size(); - _data = (byte*) malloc(_dataSize); + _data = (byte *)malloc(_dataSize); if (stream.read(_data, _dataSize) != _dataSize) { free(_data); @@ -38,17 +38,7 @@ bool Animation::loadFromStream(Common::SeekableReadStream &stream) { } return true; } -/* -const Graphics::Surface * Animation::getSurface(uint16 frameIndex) { - // bida kaszing - if (frameIndex >= _frameList.size()) { - _frameList.resize(frameIndex); - _frameList.push_back(_helper->getFrame(frameIndex)); - - } - return _frameList[frameIndex]; -} -*/ + Animation::Animation(): _data(NULL) { } @@ -135,20 +125,20 @@ Graphics::Surface *Animation::getFrame(uint frameIndex) { debug("width = %d; height = %d", width, height); Graphics::Surface *surf = new Graphics::Surface(); surf->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); - debug("frameData %p", frameData); - if (READ_BE_UINT32(frameData + 4) == 0x6D61736D) { + debug("frameData %p", frameData); + if (READ_BE_UINT32(frameData + 4) == MKTAG('m', 'a', 's', 'm')) { // Compressed Decompressor dec; - uint32 ddataSize = READ_LE_UINT32(frameData + 8); - byte *ddata = new byte[ddataSize]; + uint32 ddataSize = READ_LE_UINT32(frameData + 8); + byte *ddata = (byte *)malloc(ddataSize); dec.decompress(frameData + 12, ddata, ddataSize); - for (uint16 i = 0; i < height; ++i) { - memcpy(surf->getBasePtr(0, i), ddata + width * i, width); - } - delete[] ddata; + for (uint16 i = 0; i < height; i++) { + memcpy(surf->getBasePtr(0, i), ddata + width * i, width); + } + free(ddata); } else { // Uncompressed - for (uint16 i = 0; i < height; ++i) { + for (uint16 i = 0; i < height; i++) { memcpy(surf->getBasePtr(0, i), frameData + 4 + width * i, width); } } diff --git a/engines/prince/debugger.cpp b/engines/prince/debugger.cpp index d9264cb02dba..58c10f1200f0 100644 --- a/engines/prince/debugger.cpp +++ b/engines/prince/debugger.cpp @@ -54,7 +54,7 @@ static int strToInt(const char *s) { bool Debugger::Cmd_DebugLevel(int argc, const char **argv) { if (argc == 1) { - DebugPrintf("Debugging is currently set at level %d\n", gDebugLevel); + DebugPrintf("Debugging is currently set at level %d\n", gDebugLevel); } else { // set level gDebugLevel = atoi(argv[1]); if (0 <= gDebugLevel && gDebugLevel < 11) { diff --git a/engines/prince/flags.cpp b/engines/prince/flags.cpp index d6d577a575d9..18d9e212c149 100644 --- a/engines/prince/flags.cpp +++ b/engines/prince/flags.cpp @@ -24,7 +24,7 @@ namespace Prince { -const char * Flags::getFlagName(uint16 flagId) +const char *Flags::getFlagName(uint16 flagId) { switch (flagId) { default: return "unknown_flag"; diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index ea0320465777..1edf22cfac9e 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -98,31 +98,28 @@ void GraphicsMan::makeShadowTable(int brightness, byte *shadowPallete) { int32 currColor; int shadow = brightness * 256 / 100; - byte *originalPallete = new byte[256 * 3]; + byte *originalPallete = (byte *)malloc(256 * 3); _vm->_system->getPaletteManager()->grabPalette(originalPallete, 0, 256); - Common::MemoryReadStream readFirstStream(originalPallete, 256 * 3); - Common::MemoryWriteStream writeStream(shadowPallete, 256); for (int i = 0; i < 256; i++) { - redFirstOrg = readFirstStream.readByte() * shadow / 256; - greenFirstOrg = readFirstStream.readByte() * shadow / 256; - blueFirstOrg = readFirstStream.readByte() * shadow / 256; + redFirstOrg = originalPallete[3 * i] * shadow / 256; + greenFirstOrg = originalPallete[3 * i + 1] * shadow / 256; + blueFirstOrg = originalPallete[3 * i + 2] * shadow / 256; currColor = 0; - Common::MemoryReadStream readSecondStream(originalPallete, 256 * 3); bigValue = 999999999; // infinity for (int j = 0; j < 256; j++) { - redSecondOrg = readSecondStream.readByte(); + redSecondOrg = originalPallete[3 * j]; redNew = redFirstOrg - redSecondOrg; redNew = redNew * redNew; - greenSecondOrg = readSecondStream.readByte(); + greenSecondOrg = originalPallete[3 * j + 1]; greenNew = greenFirstOrg - greenSecondOrg; greenNew = greenNew * greenNew; - blueSecondOrg = readSecondStream.readByte(); + blueSecondOrg = originalPallete[3 * j + 2]; blueNew = blueFirstOrg - blueSecondOrg; blueNew = blueNew * blueNew; @@ -137,9 +134,9 @@ void GraphicsMan::makeShadowTable(int brightness, byte *shadowPallete) { break; } } - writeStream.writeByte(currColor); + shadowPallete[i] = currColor; } - delete[] originalPallete; + free(originalPallete); } } diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index 62dd89c9eeb5..3e43503c584d 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -34,8 +34,8 @@ class GraphicsMan { public: GraphicsMan(PrinceEngine *vm); - ~GraphicsMan(); - + ~GraphicsMan(); + void update(); void change(); diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 3e89b23a70ed..7010b42507bc 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -35,16 +35,16 @@ Hero::Hero(PrinceEngine *vm) : _vm(vm), _number(0), _visible(false), _state(MOVE , _boreNum(1), _currHeight(0), _moveDelay(0), _shadMinus(0), _moveSetType(0) , _lastDirection(DOWN), _destDirection(DOWN), _talkTime(0), _boredomTime(0), _phase(0) , _specAnim(0), _drawX(0), _drawY(0), _randomSource("prince"), _zoomFactor(0), _scaleValue(0) - , _shadZoomFactor(0), _shadScaleValue(0) + , _shadZoomFactor(0), _shadScaleValue(0), _shadowLineLen(0) { _zoomBitmap = new Animation(); _shadowBitmap = new Animation(); - _linijka = new byte[2*1280*4]; + _shadowLine = new byte[kShadowLineArraySize]; } Hero::~Hero() { delete _zoomBitmap; - delete[] _linijka; + delete[] _shadowLine; } bool Hero::loadAnimSet(uint32 animSetNr) { @@ -242,7 +242,7 @@ void Hero::countDrawPosition() { //notfullSize debug("scaledX: %d", scaledX); debug("scaledY: %d", scaledY); - _drawX = _middleX - scaledX/2; + _drawX = _middleX - scaledX / 2; _drawY = tempMiddleY + 1 - scaledY; } else { //fullSize @@ -251,113 +251,37 @@ void Hero::countDrawPosition() { } } -void Hero::line(int x1, int y1, int x2, int y2) { - //EAX - x1 <- LightX - //EBX - y1 <- LightY - //ECX - x2 <- DestX - //EDX - y2 <- DestY - - //pushad - int dX = 1; - int vx = y2 - y1; - if(x2 <= x1) { - dX = -1; - vx = -1 * vx; - } - // pl_1 - int lvx = vx; - int dY = 1; - int vy = x1 - x2; - if (y2 <= y1) { - dY = -1; - vy = -1 * vy; - } - // pl_2 - int lvy = vy; - int lx = x1; - int ly = y1; - int lx2 = x2; - int ly2 = y2; - int lfa = 0; - - int shadowLineLen = 0; - Common::MemoryWriteStream writeStream(_linijka, 2*1280*4); - //loop - while (lx != lx2 || ly != ly2) { - //not_end - //nopik - if(shadowLineLen == 1280) { - break; - } - writeStream.writeUint16LE(lx); - writeStream.writeUint16LE(ly); - shadowLineLen++; - - int lfx = lfa + lvx; - int lfy = lfa + lvy; - int lfxy = lfx + lfy - lfa; - int abs_lfxy, abs_lfx, abs_lfy; +void Hero::plotPoint(int x, int y) { + WRITE_UINT16(&_shadowLine[_shadowLineLen * 4], x); + WRITE_UINT16(&_shadowLine[_shadowLineLen * 4 + 2], y); +} - if (lfxy < 0) { - abs_lfxy = -1 * lfxy; - } else { - abs_lfxy = lfxy; - } - //abs_fxy_done - if (lfx < 0) { - abs_lfx = -1 * lfx; - } else { - abs_lfx = lfx; - } - //abs_fx_done - if (lfy < 0) { - abs_lfy = -1 * lfy; - } else { - abs_lfy = lfy; - } - //abs_fy_done - - if (abs_lfx > abs_lfy || abs_lfx > abs_lfxy) { - //c2 - if (abs_lfy >= abs_lfx || abs_lfy > abs_lfxy) { - //c3 - ly += dY; - lx += dX; - lfa = lfxy; - } else { - ly += dY; - lfa = lfa + lvy; - } - } else { - lx += dX; - lfa = lfa + lvx; - } - //next - } +static void plot(int x, int y, int color, void *data) { + Hero *shadowLine = (Hero *)data; + shadowLine->plotPoint(x, y); + shadowLine->_shadowLineLen++; } -void Hero::showHeroShadow() { -//Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { +Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { int16 frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); int16 frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); - /* + Graphics::Surface *makeShadow = new Graphics::Surface(); makeShadow->create(frameXSize, frameYSize, Graphics::PixelFormat::createFormatCLUT8()); - //make_shadow: for (int y = 0; y < frameYSize; y++) { - //ms_loop: - for (int x = 0; x < frameXSize; x++) { - byte pixel = *(byte*) makeShadow->getBasePtr(x, y); - if (pixel == -1) { - *(byte*)(makeShadow->getBasePtr(x, y)) = kShadowColor; + byte *dst = (byte *)makeShadow->getBasePtr(0, y); + byte *src = (byte *)heroFrame->getBasePtr(0, y); + + for (int x = 0; x < frameXSize; x++, dst++, src++) { + if (*dst == 0xFF) { + *dst = kShadowColor; } else { - memcpy(makeShadow->getBasePtr(x, y), heroFrame->getBasePtr(x, y), 1); - //*(byte*)(makeShadow->getBasePtr(x, y)) = pixel; + *dst = *src; } } } - */ + // source Bitmap of sprite - esi int destX = _drawX; // eax int destY = _middleY - _shadMinus; // ecx @@ -379,18 +303,10 @@ void Hero::showHeroShadow() { } else { shadowDirection = 0; } - //int shadowLineLen = 0; + //int shadWallDown = 0; - // int shadowLine = Linijka(); - // push lineCode - // mov lineCode <- @@Nopik - //EAX - x1 <- LightX - //EBX - y1 <- LightY - //ECX - x2 <- DestX - //EDX - y2 <- DestY - line(_lightX, _lightY, destX, destY); - // pop lineCode - // popad + _shadowLineLen = 0; + Graphics::drawLine(_lightX, _lightY, destX, destY, 0, &plot, this); // sprShadow = shadowTable70 // sprModulo = modulo of source Bitmap @@ -408,7 +324,7 @@ void Hero::showHeroShadow() { int shadMaxY = sprDestY; // destY * kMaxPicWidth / 8 + destX / 8 int shadBitAddr = _shadowBitmap->getZoom(destY * kMaxPicWidth / 8 + destX / 8); - int shadBitMask = 128 / pow(2.0, (destX % 8)); + int shadBitMask = 128 / (2 << (destX % 8)); int shadZoomY2 = _shadScaleValue; int shadZoomY = _scaleValue; @@ -416,7 +332,8 @@ void Hero::showHeroShadow() { // lockscreen etc // banked2 - // edx = linijka() + 8 + byte *start = _shadowLine + 8; + // linear_loop //for(int i = 0; i < ; i++) { @@ -446,7 +363,7 @@ void Hero::showHeroShadow() { } //} } - //return makeShadow; + return makeShadow; } void Hero::showHeroAnimFrame() { @@ -457,7 +374,7 @@ void Hero::showHeroAnimFrame() { } countDrawPosition(); //temp: - showHeroShadow(); + //showHeroShadow(); //debug("_drawX: %d", _drawX); //debug("_drawY: %d", _drawY); //debug("_middleX: %d", _middleX); diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 4016e3519b4a..6640bcf3df99 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -28,6 +28,7 @@ #include "common/memstream.h" #include "graphics/surface.h" +#include "graphics/primitives.h" namespace Prince { @@ -42,6 +43,7 @@ class Hero { static const int16 kMaxPicHeight = 480; static const int16 kZoomBitmapWidth = kMaxPicWidth / kZoomStep; static const int16 kNormalWidth = 640; + static const int16 kShadowLineArraySize = 2 * 1280 * 4; static const uint8 kShadowColor = 191; @@ -116,8 +118,8 @@ class Hero { Graphics::Surface *zoomSprite(Graphics::Surface *heroFrame); void showHeroAnimFrame(); void line(int x1, int y1, int x2, int y2); - //Graphics::Surface *showHeroShadow(Graphics::Surface *heroFrame); - void showHeroShadow(); + void plotPoint(int x, int y); + Graphics::Surface *showHeroShadow(Graphics::Surface *heroFrame); void setShadowScale(int32 shadowScale); void specialAnim(); void getState(); @@ -140,6 +142,7 @@ class Hero { int16 _lightY; int32 _shadZoomFactor; int32 _shadScaleValue; + int32 _shadowLineLen; // Coords array of coordinates @@ -169,7 +172,7 @@ class Hero { // TurnAnim ?? Animation *_zoomBitmap; // change to sth else, not Animation ?? Animation *_shadowBitmap; - byte *_linijka; + byte *_shadowLine; uint32 _moveDelay; uint32 _shadMinus; diff --git a/engines/prince/hero_set.cpp b/engines/prince/hero_set.cpp index a8c05de724c0..1d235a567aac 100644 --- a/engines/prince/hero_set.cpp +++ b/engines/prince/hero_set.cpp @@ -26,7 +26,7 @@ namespace Prince { -static HeroSetAnimNames heroSet5= { +static HeroSetAnimNames heroSet5 = { "SL_DIAB.ANI", "SR_DIAB.ANI", "SU_DIAB.ANI", @@ -55,7 +55,7 @@ static HeroSetAnimNames heroSet5= { NULL }; -static HeroSetAnimNames heroSet1= { +static HeroSetAnimNames heroSet1 = { "SL_HERO1.ANI", "SR_HERO1.ANI", "SU_HERO1.ANI", @@ -84,7 +84,7 @@ static HeroSetAnimNames heroSet1= { "KS_WLOSY.ANI" }; -static HeroSetAnimNames heroSet2= { +static HeroSetAnimNames heroSet2 = { "SL_HERO2.ANI", "SR_HERO2.ANI", "SU_HERO2.ANI", @@ -113,7 +113,7 @@ static HeroSetAnimNames heroSet2= { "KS_WLO_S.ANI" }; -static HeroSetAnimNames heroSet3= { +static HeroSetAnimNames heroSet3 = { "SL_BEAR.ANI", "SR_BEAR.ANI", "SU_BEAR.ANI", @@ -142,7 +142,7 @@ static HeroSetAnimNames heroSet3= { NULL, }; -static HeroSetAnimNames shanSet1= { +static HeroSetAnimNames shanSet1 = { "SL_SHAN.ANI", "SR_SHAN.ANI", "SU_SHAN.ANI", @@ -171,7 +171,7 @@ static HeroSetAnimNames shanSet1= { "B2_SHAN.ANI", }; -static HeroSetAnimNames shanSet2= { +static HeroSetAnimNames shanSet2 = { "SL_SHAN2.ANI", "SR_SHAN2.ANI", "SU_SHAN.ANI", @@ -200,7 +200,7 @@ static HeroSetAnimNames shanSet2= { "B2_SHAN2.ANI" }; -static HeroSetAnimNames arivSet1= { +static HeroSetAnimNames arivSet1 = { "SL_ARIV.ANI", "SR_ARIV.ANI", "SU_ARIV.ANI", diff --git a/engines/prince/mob.cpp b/engines/prince/mob.cpp index c4bb6073470d..1ca9931a590f 100644 --- a/engines/prince/mob.cpp +++ b/engines/prince/mob.cpp @@ -71,28 +71,32 @@ bool Mob::loadFromStream(Common::SeekableReadStream &stream) { void Mob::setData(AttrId dataId, uint16 value) { switch (dataId) { - case ExamDir: - _examDirection = (Direction)value; - break; - case ExamX: - _examPosition.x = value; - break; - case ExamY: - _examPosition.y = value; - break; - default: - assert(false); + case ExamDir: + _examDirection = (Direction)value; + break; + case ExamX: + _examPosition.x = value; + break; + case ExamY: + _examPosition.y = value; + break; + default: + assert(false); } } uint16 Mob::getData(AttrId dataId) { switch (dataId) { - case Visible: return _visible; - case ExamDir: return _examDirection; - case ExamX: return _examPosition.x; - case ExamY: return _examPosition.y; - default: - assert(false); + case Visible: + return _visible; + case ExamDir: + return _examDirection; + case ExamX: + return _examPosition.x; + case ExamY: + return _examPosition.y; + default: + assert(false); } } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 39183d35f199..0439bae840b7 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -67,9 +67,9 @@ void PrinceEngine::debugEngine(const char *s, ...) { char buf[STRINGBUFLEN]; va_list va; - va_start(va, s); - vsnprintf(buf, STRINGBUFLEN, s, va); - va_end(va); + va_start(va, s); + vsnprintf(buf, STRINGBUFLEN, s, va); + va_end(va); debug("Prince::Engine frame %08ld %s", _frameNr, buf); } @@ -78,7 +78,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) Engine(syst), _gameDescription(gameDesc), _graph(nullptr), _script(nullptr), _interpreter(nullptr), _flags(nullptr), _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), _cameraX(0), _newCameraX(0), _frameNr(0), _cursor1(nullptr), _cursor2(nullptr), _font(nullptr), - _walizkaBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0) { + _suitcaseBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -104,14 +104,14 @@ PrinceEngine::~PrinceEngine() { delete _interpreter; delete _font; delete _roomBmp; - delete _walizkaBmp; + delete _suitcaseBmp; delete _variaTxt; delete[] _talkTxt; delete _graph; delete _mainHero; delete _secondHero; - for (uint32 i = 0; i < _objList.size(); ++i) { + for (uint i = 0; i < _objList.size(); ++i) { delete _objList[i]; } _objList.clear(); @@ -155,8 +155,8 @@ void PrinceEngine::init() { _font = new Font(); Resource::loadResource(_font, "font1.raw"); - _walizkaBmp = new MhwanhDecoder(); - Resource::loadResource(_walizkaBmp, "walizka"); + _suitcaseBmp = new MhwanhDecoder(); + Resource::loadResource(_suitcaseBmp, "walizka"); _script = new Script(); Resource::loadResource(_script, "skrypt.dat"); @@ -244,7 +244,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _flicPlayer.close(); memset(_textSlots, 0, sizeof(_textSlots)); - for(uint32 sampleId = 0; sampleId < MAX_SAMPLES; ++sampleId) { + for(uint32 sampleId = 0; sampleId < MAX_SAMPLES; sampleId++) { stopSample(sampleId); } @@ -284,7 +284,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { Resource::loadResource(_mainHero->_zoomBitmap, "zoom", false); _mainHero->_shadowBitmap->clear(); - if(Resource::loadResource(_mainHero->_shadowBitmap, "shadow", false) == false) { + if (Resource::loadResource(_mainHero->_shadowBitmap, "shadow", false) == false) { Resource::loadResource(_mainHero->_shadowBitmap, "shadow2", false); } @@ -299,7 +299,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mobList.clear(); Resource::loadResource(_mobList, "mob.lst", false); - for (uint32 i = 0; i < _objList.size(); ++i) { + for (uint32 i = 0; i < _objList.size(); i++) { delete _objList[i]; } _objList.clear(); @@ -323,17 +323,17 @@ void PrinceEngine::changeCursor(uint16 curId) { uint16 hotspotY = 0; switch(curId) { - case 0: - CursorMan.showMouse(false); - return; - case 1: - curSurface = _cursor1->getSurface(); - break; - case 2: - curSurface = _cursor2->getSurface(); - hotspotX = curSurface->w >> 1; - hotspotY = curSurface->h >> 1; - break; + case 0: + CursorMan.showMouse(false); + return; + case 1: + curSurface = _cursor1->getSurface(); + break; + case 2: + curSurface = _cursor2->getSurface(); + hotspotX = curSurface->w >> 1; + hotspotY = curSurface->h >> 1; + break; } CursorMan.replaceCursorPalette(_roomBmp->getPalette(), 0, 255); @@ -356,9 +356,9 @@ bool PrinceEngine::playNextFrame() { _graph->drawTransparent(0, 0, s); _graph->change(); } else if (_flicLooped) { - _flicPlayer.rewind(); - playNextFrame(); - } + _flicPlayer.rewind(); + playNextFrame(); + } return true; } @@ -414,14 +414,16 @@ bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::Strin } uint32 id = _voiceStream[sampleSlot]->readUint32LE(); - if (id != 0x46464952) { + //if (id != 0x46464952) { + if (id != MKTAG('F', 'F', 'I', 'R')) { error("It's not RIFF file %s", streamName.c_str()); return false; } _voiceStream[sampleSlot]->skip(0x20); id = _voiceStream[sampleSlot]->readUint32LE(); - if (id != 0x61746164) { + //if (id != 0x61746164) { + if (id != MKTAG('a', 't', 'a', 'd')) { error("No data section in %s id %04x", streamName.c_str(), id); return false; } @@ -454,7 +456,7 @@ bool PrinceEngine::loadAnim(uint16 animNr, bool loop) { } debugEngine("%s loaded", streamName.c_str()); - _flicLooped = loop; + _flicLooped = loop; _flicPlayer.start(); playNextFrame(); return true; @@ -550,8 +552,7 @@ void PrinceEngine::hotspot() { Common::Point mousepos = _system->getEventManager()->getMousePos(); Common::Point mousePosCamera(mousepos.x + _cameraX, mousepos.y); - for (Common::Array::const_iterator it = _mobList.begin() - ; it != _mobList.end() ; ++it) { + for (Common::Array::const_iterator it = _mobList.begin(); it != _mobList.end() ; it++) { const Mob& mob = *it; if (mob._visible) continue; @@ -596,12 +597,12 @@ void PrinceEngine::printAt(uint32 slot, uint8 color, const char *s, uint16 x, ui } uint32 PrinceEngine::getTextWidth(const char *s) { - uint16 textW = 0; + uint16 textW = 0; while (*s) { - textW += _font->getCharWidth(*s) + _font->getKerningOffset(0, 0); - ++s; - } - return textW; + textW += _font->getCharWidth(*s) + _font->getKerningOffset(0, 0); + s++; + } + return textW; } void PrinceEngine::showTexts() { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 8213b2d32b43..7793545526d1 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -137,8 +137,8 @@ class PrinceEngine : public Engine { Text _textSlots[MAXTEXTS]; uint64 _frameNr; - Hero* _mainHero; - Hero* _secondHero; + Hero *_mainHero; + Hero *_secondHero; uint16 _cameraX; uint16 _newCameraX; @@ -168,7 +168,7 @@ class PrinceEngine : public Engine { Image::BitmapDecoder *_roomBmp; Cursor *_cursor1; Cursor *_cursor2; - MhwanhDecoder *_walizkaBmp; + MhwanhDecoder *_suitcaseBmp; Debugger *_debugger; GraphicsMan *_graph; Script *_script; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 11cba8fdf962..78704eb6f877 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -45,7 +45,7 @@ void Room::loadMobs(Common::SeekableReadStream &stream) { static const uint8 MAX_MOBS = 64; uint8 mobs[MAX_MOBS]; stream.read(&mobs, sizeof(mobs)); - for(uint8 i = 0; i < sizeof(mobs); ++i) { + for (uint8 i = 0; i < sizeof(mobs); i++) { debug("mob %d flag %d", i, mobs[i]); } } @@ -56,7 +56,7 @@ void Room::loadBackAnim(Common::SeekableReadStream &stream) { uint32 backAnim[MAX_BACK_ANIMS]; debug("loadBackAnim sizeof %lu", sizeof(backAnim)); stream.read(backAnim, sizeof(backAnim)); - for(uint8 i = 0; i < MAX_BACK_ANIMS; ++i) { + for (uint8 i = 0; i < MAX_BACK_ANIMS; i++) { debug("back anim offset %d", backAnim[i]); } } @@ -498,7 +498,7 @@ void Interpreter::O_COMPARE() { void Interpreter::O_JUMPZ() { int32 offset = readScript(); - if (! _result) { + if (!_result) { _currentInstruction += offset - 4; } diff --git a/engines/prince/variatxt.h b/engines/prince/variatxt.h index dcdba7bd8ae4..2a7a5fda9c56 100644 --- a/engines/prince/variatxt.h +++ b/engines/prince/variatxt.h @@ -32,7 +32,7 @@ class VariaTxt { bool loadFromStream(Common::SeekableReadStream &stream); - const char * getString(uint32 stringId); + const char *getString(uint32 stringId); private: uint32 _dataSize; From fb60ffd683a10d31585838c6ef90559755370dd7 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 8 May 2014 16:47:34 +0200 Subject: [PATCH 084/374] PRINCE: makeShadowTable() variable names fix --- engines/prince/graphics.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 1edf22cfac9e..ab6eec3d0b23 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -88,7 +88,7 @@ void GraphicsMan::drawTransparent(uint16 posX, uint16 posY, const Graphics::Surf change(); } -void GraphicsMan::makeShadowTable(int brightness, byte *shadowPallete) { +void GraphicsMan::makeShadowTable(int brightness, byte *shadowPalette) { int32 redFirstOrg, greenFirstOrg, blueFirstOrg; int32 redSecondOrg, greenSecondOrg, blueSecondOrg; int32 redNew, greenNew, blueNew; @@ -98,28 +98,28 @@ void GraphicsMan::makeShadowTable(int brightness, byte *shadowPallete) { int32 currColor; int shadow = brightness * 256 / 100; - byte *originalPallete = (byte *)malloc(256 * 3); + byte *originalPalette = (byte *)malloc(256 * 3); - _vm->_system->getPaletteManager()->grabPalette(originalPallete, 0, 256); + _vm->_system->getPaletteManager()->grabPalette(originalPalette, 0, 256); for (int i = 0; i < 256; i++) { - redFirstOrg = originalPallete[3 * i] * shadow / 256; - greenFirstOrg = originalPallete[3 * i + 1] * shadow / 256; - blueFirstOrg = originalPallete[3 * i + 2] * shadow / 256; + redFirstOrg = originalPalette[3 * i] * shadow / 256; + greenFirstOrg = originalPalette[3 * i + 1] * shadow / 256; + blueFirstOrg = originalPalette[3 * i + 2] * shadow / 256; currColor = 0; bigValue = 999999999; // infinity for (int j = 0; j < 256; j++) { - redSecondOrg = originalPallete[3 * j]; + redSecondOrg = originalPalette[3 * j]; redNew = redFirstOrg - redSecondOrg; redNew = redNew * redNew; - greenSecondOrg = originalPallete[3 * j + 1]; + greenSecondOrg = originalPalette[3 * j + 1]; greenNew = greenFirstOrg - greenSecondOrg; greenNew = greenNew * greenNew; - blueSecondOrg = originalPallete[3 * j + 2]; + blueSecondOrg = originalPalette[3 * j + 2]; blueNew = blueFirstOrg - blueSecondOrg; blueNew = blueNew * blueNew; @@ -134,9 +134,9 @@ void GraphicsMan::makeShadowTable(int brightness, byte *shadowPallete) { break; } } - shadowPallete[i] = currColor; + shadowPalette[i] = currColor; } - free(originalPallete); + free(originalPalette); } } From 6463c04b93d59f1e993848bde7cd7b8aa77d2b50 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 9 May 2014 14:01:08 +0200 Subject: [PATCH 085/374] PRINCE: showHeroShadow progress --- engines/prince/hero.cpp | 111 +++++++++++++++++++++++++++++++++++----- 1 file changed, 97 insertions(+), 14 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 7010b42507bc..feec86efbbdc 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -286,8 +286,8 @@ Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { int destX = _drawX; // eax int destY = _middleY - _shadMinus; // ecx // modulo of source Bitmap - ebp - //int scaledX = getScaledValue(frameXSize); // ebx - //int scaledY = getScaledValue(frameYSize); // edx + int scaledX = getScaledValue(frameXSize); // ebx + int scaledY = getScaledValue(frameYSize); // edx // shadowTable70 - edi if (destY > 1 && destY < kMaxPicHeight) { @@ -310,8 +310,8 @@ Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { // sprShadow = shadowTable70 // sprModulo = modulo of source Bitmap - // sprWidth = scaledX - // sprHeight = scaledY + int sprWidth = scaledX; + int sprHeight = scaledY; int sprDestX = destX - _vm->_picWindowX; int sprDestY = destY - _vm->_picWindowY; @@ -324,7 +324,7 @@ Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { int shadMaxY = sprDestY; // destY * kMaxPicWidth / 8 + destX / 8 int shadBitAddr = _shadowBitmap->getZoom(destY * kMaxPicWidth / 8 + destX / 8); - int shadBitMask = 128 / (2 << (destX % 8)); + int shadBitMask = 128 >> (destX % 8); int shadZoomY2 = _shadScaleValue; int shadZoomY = _scaleValue; @@ -334,33 +334,116 @@ Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { // banked2 byte *start = _shadowLine + 8; - // linear_loop //for(int i = 0; i < ; i++) { int ebx16795 = shadPosY; int sprModulo = 0; int shadSkipX = 0; + + int ebxOnStack; //retry_line: - for(int j = 0; j < shadPosY; j++) { + for (ebxOnStack = sprHeight; ebxOnStack > 0; ebxOnStack--) { shadZoomY -= 100; - if(shadZoomY < 0 || _scaleValue != 10000) { + if (shadZoomY < 0 && _scaleValue != 10000) { shadZoomY += _scaleValue; // esi -= sprWidth } else { break; //to line_y_ok } + } + if(ebxOnStack == 0) { // esp += 4*4 // koniec_bajki } //line_y_ok - int shadLastY = 0; - if (shadPosY < 0 || shadPosY == shadLastY || shadPosY >= 480 || shadPosX >= 640) { + int shadLastY = 0; //? + if (shadPosY >= 0 && shadPosY != shadLastY) { shadLastY = shadPosY; - //skip_line - - } else if (shadPosX < 0) { - shadSkipX = -1 * shadPosX; + if (shadPosY < 480 && shadPosX < 640) { + if (shadPosX < 0) { + shadSkipX = -1 * shadPosX; + //add eax, ebp + if (sprWidth > shadSkipX) { //? + //add esi, ebp + shadBitAddr += shadSkipX / 8; + int ebp16844 = shadSkipX % 8; + if (ebp16844 != 0) { + //loop_rotate: + for (int k = 0; k < ebp16844; k++) { + //ror shaBitMask ! + shadBitMask /= 2; + if (shadBitMask == 1) { + shadBitMask = 128; + shadBitAddr++; + } + } + } + //draw_line1 + if (shadPosX < shadMinX) { + shadMinX = shadPosX; + } + //bigger_x + if (shadPosX + sprWidth > shadMaxX) { + shadMaxX = shadPosX + sprWidth; + } + //smaller_x + if (shadPosY < shadMinY) { + shadMinY = shadPosY; + } + //bigger_y + if (shadPosY > shadMaxY) { + shadMaxY = shadPosY; + } + //smaller_y + //retry_line2 + int ebxOnStack2; + for(ebxOnStack2 = ebxOnStack; ebxOnStack2 > 0; ebxOnStack2--) { + shadZoomY2 -= 100; + if (shadZoomY2 < 0 && _shadScaleValue != 10000) { + shadZoomY2 += _shadScaleValue; + // esi -= sprWidth + } else { + break; //to line_y_ok_2 + } + } + if (ebxOnStack2 == 0) { + // esp += 4*4 + // koniec_bajki + } + //line_y_ok_2: + // push esi + // push ecx + // int lineDestAddr = eax; + // edi = eax + // eax = shadBitMask + // push eax // push shadBitMask + // lineBitAddr = shadBitMask + // eax = shadBitAddr + // push eax + // LineBitAddr = eax + + //copy_trans + //push eax, ebx, edx, ebp + int shadWDFlag = 0; + int shadZoomX = _scaleValue; + //ebx17061 = shadowTable70; + int ebp17062 = shadBitAddr; + int ah = shadBitMask; + + //ct_loop: + shadZoomX -= 100; + if (shadZoomX < 0 && _scaleValue != 10000) { + // esi++; + shadZoomX += _scaleValue; + } + + } + } else { + //x1_ok + } + } } + //skip_line //} } return makeShadow; From be565bf4f025fc64bd2cbc986fee111869cbd38a Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 11 May 2014 13:57:52 +0200 Subject: [PATCH 086/374] PRINCE: hero's shadow drawing progress --- engines/prince/hero.cpp | 290 ++++++++++++++++++++++++++------------ engines/prince/hero.h | 14 +- engines/prince/prince.cpp | 13 +- 3 files changed, 220 insertions(+), 97 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index feec86efbbdc..9d4d43eefc8b 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -27,15 +27,17 @@ #include "prince/animation.h" #include "prince/resource.h" #include "prince/prince.h" - +#include "prince/graphics.h" namespace Prince { -Hero::Hero(PrinceEngine *vm) : _vm(vm), _number(0), _visible(false), _state(MOVE), _middleX(0), _middleY(0) +Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph) + , _number(0), _visible(false), _state(MOVE), _middleX(0), _middleY(0) , _boreNum(1), _currHeight(0), _moveDelay(0), _shadMinus(0), _moveSetType(0) , _lastDirection(DOWN), _destDirection(DOWN), _talkTime(0), _boredomTime(0), _phase(0) , _specAnim(0), _drawX(0), _drawY(0), _randomSource("prince"), _zoomFactor(0), _scaleValue(0) - , _shadZoomFactor(0), _shadScaleValue(0), _shadowLineLen(0) + , _shadZoomFactor(0), _shadScaleValue(0), _shadowLineLen(0), _shadowDrawX(0), _shadowDrawY(0) + , _shadLastY(0) { _zoomBitmap = new Animation(); _shadowBitmap = new Animation(); @@ -262,19 +264,32 @@ static void plot(int x, int y, int color, void *data) { shadowLine->_shadowLineLen++; } -Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { +void Hero::showHeroShadow() { +//Graphics::Surface *Hero::showHeroShadow() { + int16 phaseFrameIndex = _moveSet[_moveSetType]->getPhaseFrameIndex(_phase); + Graphics::Surface *heroFrame = _moveSet[_moveSetType]->getFrame(phaseFrameIndex); int16 frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); int16 frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); Graphics::Surface *makeShadow = new Graphics::Surface(); makeShadow->create(frameXSize, frameYSize, Graphics::PixelFormat::createFormatCLUT8()); + //Graphics::Surface *destShadow = new Graphics::Surface(); + //destShadow->create(frameXSize, frameYSize, Graphics::PixelFormat::createFormatCLUT8()); + /* + for (int y = 0; y < frameYSize; y++) { + byte *src = (byte *)destShadow->getBasePtr(0, y); + for (int x = 0; x < frameXSize; x++, src++) { + *src = 0xFF; + } + } + */ for (int y = 0; y < frameYSize; y++) { - byte *dst = (byte *)makeShadow->getBasePtr(0, y); byte *src = (byte *)heroFrame->getBasePtr(0, y); + byte *dst = (byte *)makeShadow->getBasePtr(0, y); for (int x = 0; x < frameXSize; x++, dst++, src++) { - if (*dst == 0xFF) { + if (*src != 0xFF) { *dst = kShadowColor; } else { *dst = *src; @@ -297,23 +312,26 @@ Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { // ebx = _lightY // eax = _lightX - int shadowDirection; + int shadDirection; if (_lightY > destY) { - shadowDirection = 1; + shadDirection = 1; } else { - shadowDirection = 0; + shadDirection = 0; } - //int shadWallDown = 0; + int shadWallDown = 0; _shadowLineLen = 0; Graphics::drawLine(_lightX, _lightY, destX, destY, 0, &plot, this); - // sprShadow = shadowTable70 + byte *sprShadow = (byte *)_graph->_shadowTable70; // sprModulo = modulo of source Bitmap int sprWidth = scaledX; int sprHeight = scaledY; - int sprDestX = destX - _vm->_picWindowX; - int sprDestY = destY - _vm->_picWindowY; + int sprDestX = destX - _vm->_picWindowX; //test this + int sprDestY = destY - _vm->_picWindowY; //test this + + _shadowDrawX = sprDestX; // to fix + _shadowDrawY = sprDestY; int shadPosX = sprDestX; int shadMinX = sprDestX; @@ -322,31 +340,36 @@ Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { int shadPosY = sprDestY; int shadMinY = sprDestY; int shadMaxY = sprDestY; - // destY * kMaxPicWidth / 8 + destX / 8 - int shadBitAddr = _shadowBitmap->getZoom(destY * kMaxPicWidth / 8 + destX / 8); + int shadBitAddr = destY * kMaxPicWidth / 8 + destX / 8; // for temp _shadowBitmap->getZoom() int shadBitMask = 128 >> (destX % 8); int shadZoomY2 = _shadScaleValue; int shadZoomY = _scaleValue; // lockscreen etc + //byte *destShadowStart = (byte *)destShadow->getBasePtr(0, 0); // need this? + byte *shadowStart = (byte *)makeShadow->getBasePtr(0, frameYSize - 1); // !TEST IT! esi, first pixel from last row of black hero + byte *background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX, sprDestY); // !TEST IT! eax, pixel of background where shadow sprite starts + //byte *background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX, sprDestY + frameYSize); + int diff = 0; + // banked2 - byte *start = _shadowLine + 8; + byte *shadowLineStart = _shadowLine + 8; // linear_loop - //for(int i = 0; i < ; i++) { + for(int i = 0; i < sprHeight; i++) { int ebx16795 = shadPosY; int sprModulo = 0; int shadSkipX = 0; int ebxOnStack; //retry_line: - for (ebxOnStack = sprHeight; ebxOnStack > 0; ebxOnStack--) { + for (ebxOnStack = sprHeight - i; ebxOnStack > 0; ebxOnStack--) { shadZoomY -= 100; if (shadZoomY < 0 && _scaleValue != 10000) { shadZoomY += _scaleValue; - // esi -= sprWidth + shadowStart -= sprWidth; } else { break; //to line_y_ok } @@ -356,97 +379,190 @@ Graphics::Surface *Hero::showHeroShadow(Graphics::Surface *heroFrame) { // koniec_bajki } //line_y_ok - int shadLastY = 0; //? - if (shadPosY >= 0 && shadPosY != shadLastY) { - shadLastY = shadPosY; + //if (shadPosY >= 0 && shadPosY != _shadLastY) { + if (shadPosY >= 0) { + //_shadLastY = shadPosY; if (shadPosY < 480 && shadPosX < 640) { - if (shadPosX < 0) { + if (shadPosX < 0) { //? shadSkipX = -1 * shadPosX; - //add eax, ebp - if (sprWidth > shadSkipX) { //? - //add esi, ebp + background += shadSkipX; + if (sprWidth > shadSkipX) { + shadowStart += shadSkipX; shadBitAddr += shadSkipX / 8; int ebp16844 = shadSkipX % 8; if (ebp16844 != 0) { //loop_rotate: for (int k = 0; k < ebp16844; k++) { - //ror shaBitMask ! - shadBitMask /= 2; + //ror(shadBitMask, 1) if (shadBitMask == 1) { shadBitMask = 128; shadBitAddr++; + } else { + shadBitMask /= 2; } } } - //draw_line1 - if (shadPosX < shadMinX) { - shadMinX = shadPosX; - } - //bigger_x - if (shadPosX + sprWidth > shadMaxX) { - shadMaxX = shadPosX + sprWidth; - } - //smaller_x - if (shadPosY < shadMinY) { - shadMinY = shadPosY; - } - //bigger_y - if (shadPosY > shadMaxY) { - shadMaxY = shadPosY; - } - //smaller_y - //retry_line2 - int ebxOnStack2; - for(ebxOnStack2 = ebxOnStack; ebxOnStack2 > 0; ebxOnStack2--) { - shadZoomY2 -= 100; - if (shadZoomY2 < 0 && _shadScaleValue != 10000) { - shadZoomY2 += _shadScaleValue; - // esi -= sprWidth + } else { + //skip_line //? + // no draw_line1 + } + } else { + //x1_ok + if (shadPosX + sprWidth > 640) { + int ecx16861 = sprWidth - (shadPosX + sprWidth - 640); + sprModulo = shadPosX + sprWidth - 640; + } else { + //draw_line + int ecx16868 = sprWidth; + } + } + //draw_line1 + if (shadPosX < shadMinX) { + shadMinX = shadPosX; + } + //bigger_x + if (shadPosX + sprWidth > shadMaxX) { + shadMaxX = shadPosX + sprWidth; + } + //smaller_x + if (shadPosY < shadMinY) { + shadMinY = shadPosY; + } + //bigger_y + if (shadPosY > shadMaxY) { //? + shadMaxY = shadPosY; + } + //smaller_y + //retry_line2 + int ebxOnStack2; + for(ebxOnStack2 = ebxOnStack; ebxOnStack2 > 0; ebxOnStack2--) { + shadZoomY2 -= 100; + if (shadZoomY2 < 0 && _shadScaleValue != 10000) { + shadZoomY2 += _shadScaleValue; + shadowStart -= sprWidth; + } else { + break; //to line_y_ok_2 + } + } + if (ebxOnStack2 == 0) { + // esp += 4*4 + // koniec_bajki + } + //line_y_ok_2: + // push esi + // push ecx + // int lineDestAddr = eax; + // edi = eax + // eax = shadBitMask + // push eax // push shadBitMask + // lineBitAddr = shadBitMask + // eax = shadBitAddr + // push eax + // LineBitAddr = eax + + //copy_trans + //push eax, ebx, edx, ebp + int shadWDFlag = 0; + int shadZoomX = _scaleValue; + //ct_loop: + for (int j = 0; j < sprWidth; j++) { //? ecx to check + shadZoomX -= 100; + if (shadZoomX < 0 && _scaleValue != 10000) { + shadowStart++; + shadZoomX += _scaleValue; + } else { + //point_ok: + if (*shadowStart == kShadowColor) { + if (shadBitMask != _shadowBitmap->getZoom(shadBitAddr)) { //tofix + if (shadWallDown == 0) { + if (shadBitMask != _shadowBitmap->getZoom(shadBitAddr + kShadowBitmapSize)) { + shadWDFlag = 1; + //shadow + *background = *(sprShadow + *background); + } + } } else { - break; //to line_y_ok_2 + //shadow + *background = *(sprShadow + *background); } } - if (ebxOnStack2 == 0) { - // esp += 4*4 - // koniec_bajki + //ct_next + //ror(shadBitMask, 1) + if (shadBitMask == 1) { + shadBitMask = 128; + shadBitAddr++; + } else { + shadBitMask /= 2; } - //line_y_ok_2: - // push esi - // push ecx - // int lineDestAddr = eax; - // edi = eax - // eax = shadBitMask - // push eax // push shadBitMask - // lineBitAddr = shadBitMask - // eax = shadBitAddr - // push eax - // LineBitAddr = eax - - //copy_trans - //push eax, ebx, edx, ebp - int shadWDFlag = 0; - int shadZoomX = _scaleValue; - //ebx17061 = shadowTable70; - int ebp17062 = shadBitAddr; - int ah = shadBitMask; - - //ct_loop: - shadZoomX -= 100; - if (shadZoomX < 0 && _scaleValue != 10000) { - // esi++; - shadZoomX += _scaleValue; - } - + //okok + shadowStart++; + background++; + //destShadowStart++; } - } else { - //x1_ok } + //byebyebye + if (shadWallDown == 0 && shadWDFlag != 0) { + //shadWall itp + // + } + //byebye + // pop ... + if (shadDirection != 0 && shadWallDown != 0) { + // push... + // krap2 + // WALL_copy_trans + } + //next_line + //int ecx16965 = sprWidth; + if (*(shadowLineStart + 2) < *(shadowLineStart - 2)) { + //minus_y + shadBitAddr += kMaxPicWidth / 8; + shadPosY++; + //add eax, VESA_ScanLine + background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX + diff, sprDestY + i); + } else if (*(shadowLineStart + 2) > *(shadowLineStart - 2)) { + shadBitAddr -= kMaxPicWidth / 8; + shadPosY--; + //sub eax, VESA_ScanLine + background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX + diff, sprDestY - i); + } + //no_change_y + if (*shadowLineStart < *(shadowLineStart - 4)) { + //minus_x + shadPosX--; + //rol + if (shadBitMask == 128) { + shadBitMask = 1; + shadBitAddr--; + } else { + shadBitMask *= 2; + } + //eax--; + //background--; + diff--; + } else if (*shadowLineStart > *(shadowLineStart - 4)) { + shadPosX++; + //ror + if (shadBitMask == 1) { + shadBitMask = 128; + shadBitAddr++; + } else { + shadBitMask /= 2; + } + //background++; + diff++; + } + //no_change_x + shadowLineStart += 4; + shadowStart = (byte *)makeShadow->getBasePtr(0, frameYSize - 1 - i); + //background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX, sprDestY + i); } } //skip_line - //} + } } - return makeShadow; + //return makeShadow; + //return destShadow; } void Hero::showHeroAnimFrame() { diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 6640bcf3df99..76ca51a43ad7 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -34,6 +34,7 @@ namespace Prince { class Animation; class PrinceEngine; +class GraphicsMan; class Hero { public: @@ -44,8 +45,9 @@ class Hero { static const int16 kZoomBitmapWidth = kMaxPicWidth / kZoomStep; static const int16 kNormalWidth = 640; static const int16 kShadowLineArraySize = 2 * 1280 * 4; + static const int16 kShadowBitmapSize = kMaxPicWidth * kMaxPicHeight / 8; - static const uint8 kShadowColor = 191; + static const byte kShadowColor = 191; enum State { STAY = 0, @@ -96,7 +98,7 @@ class Hero { Move_BORED2 }; - Hero(PrinceEngine *vm); + Hero(PrinceEngine *vm, GraphicsMan *graph); ~Hero(); Common::RandomSource _randomSource; bool loadAnimSet(uint32 heroAnimNumber); @@ -119,13 +121,15 @@ class Hero { void showHeroAnimFrame(); void line(int x1, int y1, int x2, int y2); void plotPoint(int x, int y); - Graphics::Surface *showHeroShadow(Graphics::Surface *heroFrame); + //Graphics::Surface *showHeroShadow(); + void showHeroShadow(); void setShadowScale(int32 shadowScale); void specialAnim(); void getState(); //private: PrinceEngine *_vm; + GraphicsMan *_graph; uint16 _number; uint16 _visible; int16 _state; @@ -143,7 +147,9 @@ class Hero { int32 _shadZoomFactor; int32 _shadScaleValue; int32 _shadowLineLen; - + int16 _shadowDrawX; + int16 _shadowDrawY; + int16 _shadLastY; // Coords array of coordinates // DirTab array of directions diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 0439bae840b7..533d2f4c578e 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -186,8 +186,8 @@ void PrinceEngine::init() { _roomBmp = new Image::BitmapDecoder(); - _mainHero = new Hero(this); - _secondHero = new Hero(this); + _mainHero = new Hero(this, _graph); + _secondHero = new Hero(this, _graph); _mainHero->loadAnimSet(0); } @@ -414,7 +414,6 @@ bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::Strin } uint32 id = _voiceStream[sampleSlot]->readUint32LE(); - //if (id != 0x46464952) { if (id != MKTAG('F', 'F', 'I', 'R')) { error("It's not RIFF file %s", streamName.c_str()); return false; @@ -422,7 +421,6 @@ bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::Strin _voiceStream[sampleSlot]->skip(0x20); id = _voiceStream[sampleSlot]->readUint32LE(); - //if (id != 0x61746164) { if (id != MKTAG('a', 't', 'a', 'd')) { error("No data section in %s id %04x", streamName.c_str(), id); return false; @@ -642,10 +640,13 @@ void PrinceEngine::drawScreen() { if (_mainHero->_visible) { const Graphics::Surface *mainHeroSurface = _mainHero->getSurface(); + //const Graphics::Surface *mainHeroShadow = _mainHero->showHeroShadow(); - if (mainHeroSurface) - //_graph->drawTransparent(_mainHero->_middleX, _mainHero->_middleY, mainHeroSurface); + if (mainHeroSurface) { + _mainHero->showHeroShadow(); _graph->drawTransparent(_mainHero->_drawX, _mainHero->_drawY, mainHeroSurface); + //_graph->drawTransparent(_mainHero->_shadowDrawX, _mainHero->_shadowDrawY, mainHeroShadow); + } } playNextFrame(); From 9e88e738ea2b09c4294efd16939c3a3271c2874f Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 12 May 2014 03:47:16 +0200 Subject: [PATCH 087/374] PRINCE: showHeroShadow() first actual shadow drawing --- engines/prince/hero.cpp | 388 ++++++++++++++++++++-------------------- engines/prince/hero.h | 1 - 2 files changed, 193 insertions(+), 196 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 9d4d43eefc8b..de23fc1a8af4 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -265,7 +265,6 @@ static void plot(int x, int y, int color, void *data) { } void Hero::showHeroShadow() { -//Graphics::Surface *Hero::showHeroShadow() { int16 phaseFrameIndex = _moveSet[_moveSetType]->getPhaseFrameIndex(_phase); Graphics::Surface *heroFrame = _moveSet[_moveSetType]->getFrame(phaseFrameIndex); int16 frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); @@ -274,16 +273,6 @@ void Hero::showHeroShadow() { Graphics::Surface *makeShadow = new Graphics::Surface(); makeShadow->create(frameXSize, frameYSize, Graphics::PixelFormat::createFormatCLUT8()); - //Graphics::Surface *destShadow = new Graphics::Surface(); - //destShadow->create(frameXSize, frameYSize, Graphics::PixelFormat::createFormatCLUT8()); - /* - for (int y = 0; y < frameYSize; y++) { - byte *src = (byte *)destShadow->getBasePtr(0, y); - for (int x = 0; x < frameXSize; x++, src++) { - *src = 0xFF; - } - } - */ for (int y = 0; y < frameYSize; y++) { byte *src = (byte *)heroFrame->getBasePtr(0, y); byte *dst = (byte *)makeShadow->getBasePtr(0, y); @@ -301,17 +290,11 @@ void Hero::showHeroShadow() { int destX = _drawX; // eax int destY = _middleY - _shadMinus; // ecx // modulo of source Bitmap - ebp - int scaledX = getScaledValue(frameXSize); // ebx - int scaledY = getScaledValue(frameYSize); // edx + //int scaledX = getScaledValue(frameXSize); // ebx + //int scaledY = getScaledValue(frameYSize); // edx // shadowTable70 - edi if (destY > 1 && destY < kMaxPicHeight) { - // pushad - // edx = destY - // ecx = destX - // ebx = _lightY - // eax = _lightX - int shadDirection; if (_lightY > destY) { shadDirection = 1; @@ -325,10 +308,14 @@ void Hero::showHeroShadow() { byte *sprShadow = (byte *)_graph->_shadowTable70; // sprModulo = modulo of source Bitmap - int sprWidth = scaledX; - int sprHeight = scaledY; - int sprDestX = destX - _vm->_picWindowX; //test this - int sprDestY = destY - _vm->_picWindowY; //test this + //int sprWidth = scaledX; // this or normal size? + //int sprHeight = scaledY; + int sprWidth = frameXSize; + int sprHeight = frameYSize; + //int sprDestX = destX - _vm->_picWindowX; //test this + //int sprDestY = destY - _vm->_picWindowY; //test this + int sprDestX = destX; + int sprDestY = destY; _shadowDrawX = sprDestX; // to fix _shadowDrawY = sprDestY; @@ -340,28 +327,29 @@ void Hero::showHeroShadow() { int shadPosY = sprDestY; int shadMinY = sprDestY; int shadMaxY = sprDestY; - int shadBitAddr = destY * kMaxPicWidth / 8 + destX / 8; // for temp _shadowBitmap->getZoom() + int shadBitAddr = destY * kMaxPicWidth / 8 + destX / 8; int shadBitMask = 128 >> (destX % 8); int shadZoomY2 = _shadScaleValue; int shadZoomY = _scaleValue; - // lockscreen etc - //byte *destShadowStart = (byte *)destShadow->getBasePtr(0, 0); // need this? - byte *shadowStart = (byte *)makeShadow->getBasePtr(0, frameYSize - 1); // !TEST IT! esi, first pixel from last row of black hero - byte *background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX, sprDestY); // !TEST IT! eax, pixel of background where shadow sprite starts - //byte *background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX, sprDestY + frameYSize); - int diff = 0; - + int diffX = 0; + int diffY = 0; + + int blackHeroX = 0; + int blackHeroY = frameYSize - 1; + + byte *shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY); // esi, first pixel from last row of black hero + byte *background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX, sprDestY); // eax, pixel of background where shadow sprite starts // banked2 byte *shadowLineStart = _shadowLine + 8; // linear_loop for(int i = 0; i < sprHeight; i++) { - int ebx16795 = shadPosY; int sprModulo = 0; int shadSkipX = 0; + int ct_loop = 0; int ebxOnStack; //retry_line: @@ -369,200 +357,210 @@ void Hero::showHeroShadow() { shadZoomY -= 100; if (shadZoomY < 0 && _scaleValue != 10000) { shadZoomY += _scaleValue; - shadowStart -= sprWidth; + blackHeroY--; + if (blackHeroY < 0) { + break; + } + shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY); } else { break; //to line_y_ok } } if(ebxOnStack == 0) { - // esp += 4*4 - // koniec_bajki + break; + } + if (blackHeroY < 0) { + break; } //line_y_ok - //if (shadPosY >= 0 && shadPosY != _shadLastY) { - if (shadPosY >= 0) { - //_shadLastY = shadPosY; - if (shadPosY < 480 && shadPosX < 640) { - if (shadPosX < 0) { //? - shadSkipX = -1 * shadPosX; - background += shadSkipX; - if (sprWidth > shadSkipX) { - shadowStart += shadSkipX; - shadBitAddr += shadSkipX / 8; - int ebp16844 = shadSkipX % 8; - if (ebp16844 != 0) { - //loop_rotate: - for (int k = 0; k < ebp16844; k++) { - //ror(shadBitMask, 1) - if (shadBitMask == 1) { - shadBitMask = 128; - shadBitAddr++; - } else { - shadBitMask /= 2; - } + if (shadPosY >= 0 && shadPosY < 480 && shadPosX < 640) { + if (shadPosX < 0) { //when it happens? + shadSkipX = -1 * shadPosX; + background += shadSkipX; + if (sprWidth > shadSkipX) { + shadowStart += shadSkipX; + shadBitAddr += shadSkipX / 8; + int ebp16844 = shadSkipX % 8; + if (ebp16844 != 0) { + //loop_rotate: + for (int k = 0; k < ebp16844; k++) { + //ror(shadBitMask, 1) + if (shadBitMask == 1) { + shadBitMask = 128; + shadBitAddr++; + } else { + shadBitMask /= 2; } } - } else { - //skip_line //? - // no draw_line1 } } else { - //x1_ok - if (shadPosX + sprWidth > 640) { - int ecx16861 = sprWidth - (shadPosX + sprWidth - 640); - sprModulo = shadPosX + sprWidth - 640; - } else { - //draw_line - int ecx16868 = sprWidth; - } - } - //draw_line1 - if (shadPosX < shadMinX) { - shadMinX = shadPosX; + //skip_line //? + // no draw_line1 + //no ct_loop? } - //bigger_x - if (shadPosX + sprWidth > shadMaxX) { - shadMaxX = shadPosX + sprWidth; - } - //smaller_x - if (shadPosY < shadMinY) { - shadMinY = shadPosY; - } - //bigger_y - if (shadPosY > shadMaxY) { //? - shadMaxY = shadPosY; + } else { + //x1_ok + if (shadPosX + sprWidth > 640) { + ct_loop = 640 - shadPosX; // test it + sprModulo = shadPosX + sprWidth - 640; + } else { + //draw_line + ct_loop = sprWidth; } - //smaller_y - //retry_line2 - int ebxOnStack2; - for(ebxOnStack2 = ebxOnStack; ebxOnStack2 > 0; ebxOnStack2--) { - shadZoomY2 -= 100; - if (shadZoomY2 < 0 && _shadScaleValue != 10000) { - shadZoomY2 += _shadScaleValue; - shadowStart -= sprWidth; - } else { - break; //to line_y_ok_2 + } + //draw_line1 + if (shadPosX < shadMinX) { + shadMinX = shadPosX; + } + //bigger_x + if (shadPosX + sprWidth > shadMaxX) { + shadMaxX = shadPosX + sprWidth; + } + //smaller_x + if (shadPosY < shadMinY) { + shadMinY = shadPosY; + } + //bigger_y + if (shadPosY > shadMaxY) { + shadMaxY = shadPosY; + } + //smaller_y + //retry_line2 + int ebxOnStack2; + for(ebxOnStack2 = ebxOnStack; ebxOnStack2 > 0; ebxOnStack2--) { + shadZoomY2 -= 100; + if (shadZoomY2 < 0 && _shadScaleValue != 10000) { + shadZoomY2 += _shadScaleValue; + blackHeroY--; + if (blackHeroY < 0) { + break; } + shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY); + } else { + break; //to line_y_ok_2 } - if (ebxOnStack2 == 0) { - // esp += 4*4 - // koniec_bajki - } - //line_y_ok_2: - // push esi - // push ecx - // int lineDestAddr = eax; - // edi = eax - // eax = shadBitMask - // push eax // push shadBitMask - // lineBitAddr = shadBitMask - // eax = shadBitAddr - // push eax - // LineBitAddr = eax - - //copy_trans - //push eax, ebx, edx, ebp - int shadWDFlag = 0; - int shadZoomX = _scaleValue; - //ct_loop: - for (int j = 0; j < sprWidth; j++) { //? ecx to check - shadZoomX -= 100; - if (shadZoomX < 0 && _scaleValue != 10000) { - shadowStart++; - shadZoomX += _scaleValue; - } else { - //point_ok: - if (*shadowStart == kShadowColor) { - if (shadBitMask != _shadowBitmap->getZoom(shadBitAddr)) { //tofix - if (shadWallDown == 0) { - if (shadBitMask != _shadowBitmap->getZoom(shadBitAddr + kShadowBitmapSize)) { - shadWDFlag = 1; - //shadow - *background = *(sprShadow + *background); - } + } + if (blackHeroY < 0) { + break; + } + if (ebxOnStack2 == 0) { + break; + } + //line_y_ok_2: + // push esi + // push ecx + // int lineDestAddr = eax; + // edi = eax + // eax = shadBitMask + // push eax // push shadBitMask + // lineBitAddr = shadBitMask + // eax = shadBitAddr + // push eax + // LineBitAddr = eax + + //copy_trans + //push eax, ebx, edx, ebp + int shadWDFlag = 0; + int shadZoomX = _scaleValue; + int backgroundDiff = 0; + //ct_loop: + for (int j = 0; j < ct_loop; j++) { + shadZoomX -= 100; + if (shadZoomX < 0 && _scaleValue != 10000) { + blackHeroX++; + shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY); + shadZoomX += _scaleValue; + } else { + //point_ok: + if (*shadowStart == kShadowColor) { + if (shadBitMask != _shadowBitmap->getZoom(shadBitAddr)) { //tofix + if (shadWallDown == 0) { + if (shadBitMask != _shadowBitmap->getZoom(shadBitAddr + kShadowBitmapSize)) { //tofix + shadWDFlag = 1; } - } else { - //shadow - *background = *(sprShadow + *background); } } - //ct_next - //ror(shadBitMask, 1) - if (shadBitMask == 1) { - shadBitMask = 128; - shadBitAddr++; - } else { - shadBitMask /= 2; - } - //okok - shadowStart++; - background++; - //destShadowStart++; + //shadow + //*background = *(sprShadow + *background); //wrong color + *background = 0; } - } - //byebyebye - if (shadWallDown == 0 && shadWDFlag != 0) { - //shadWall itp - // - } - //byebye - // pop ... - if (shadDirection != 0 && shadWallDown != 0) { - // push... - // krap2 - // WALL_copy_trans - } - //next_line - //int ecx16965 = sprWidth; - if (*(shadowLineStart + 2) < *(shadowLineStart - 2)) { - //minus_y - shadBitAddr += kMaxPicWidth / 8; - shadPosY++; - //add eax, VESA_ScanLine - background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX + diff, sprDestY + i); - } else if (*(shadowLineStart + 2) > *(shadowLineStart - 2)) { - shadBitAddr -= kMaxPicWidth / 8; - shadPosY--; - //sub eax, VESA_ScanLine - background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX + diff, sprDestY - i); - } - //no_change_y - if (*shadowLineStart < *(shadowLineStart - 4)) { - //minus_x - shadPosX--; - //rol - if (shadBitMask == 128) { - shadBitMask = 1; - shadBitAddr--; - } else { - shadBitMask *= 2; - } - //eax--; - //background--; - diff--; - } else if (*shadowLineStart > *(shadowLineStart - 4)) { - shadPosX++; - //ror + //ct_next + //ror(shadBitMask, 1) if (shadBitMask == 1) { shadBitMask = 128; shadBitAddr++; } else { shadBitMask /= 2; } - //background++; - diff++; + //okok + blackHeroX++; + shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY); + backgroundDiff++; + background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX + diffX + backgroundDiff, sprDestY + diffY); } - //no_change_x - shadowLineStart += 4; - shadowStart = (byte *)makeShadow->getBasePtr(0, frameYSize - 1 - i); - //background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX, sprDestY + i); + } + //byebyebye + if (shadWallDown == 0 && shadWDFlag != 0) { + //shadWall etc + } + //byebye + // pop ... + if (shadDirection != 0 && shadWallDown != 0) { + // push... + // krap2 + // WALL_copy_trans } } //skip_line + //add esi, sprWidth - don't need it? + + //next_line + if (*(shadowLineStart + 2) < *(shadowLineStart - 2)) { + //minus_y + shadBitAddr += kMaxPicWidth / 8; + shadPosY++; + diffY--; + background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX + diffX, sprDestY + diffY); + } else if (*(shadowLineStart + 2) > *(shadowLineStart - 2)) { + shadBitAddr -= kMaxPicWidth / 8; + shadPosY--; + diffY++; + background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX + diffX, sprDestY + diffY); + } + //no_change_y + if (*shadowLineStart < *(shadowLineStart - 4)) { + //minus_x + shadPosX--; + //rol + if (shadBitMask == 128) { + shadBitMask = 1; + shadBitAddr--; + } else { + shadBitMask *= 2; + } + diffX--; + } else if (*shadowLineStart > *(shadowLineStart - 4)) { + shadPosX++; + //ror + if (shadBitMask == 1) { + shadBitMask = 128; + shadBitAddr++; + } else { + shadBitMask /= 2; + } + diffX++; + } + //no_change_x + shadowLineStart += 4; + blackHeroY--; + if (blackHeroY < 0) { + break; + } + blackHeroX = 0; + shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY); } + //koniec_bajki } - //return makeShadow; - //return destShadow; } void Hero::showHeroAnimFrame() { diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 76ca51a43ad7..75f6a3a78bc7 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -121,7 +121,6 @@ class Hero { void showHeroAnimFrame(); void line(int x1, int y1, int x2, int y2); void plotPoint(int x, int y); - //Graphics::Surface *showHeroShadow(); void showHeroShadow(); void setShadowScale(int32 shadowScale); void specialAnim(); From 07b232804f2e3dcaf7935b794e31a68fe03eb824 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 13 May 2014 02:55:28 +0200 Subject: [PATCH 088/374] PRINCE: showHeroShadow() memory and shadPosY fix --- engines/prince/hero.cpp | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index de23fc1a8af4..884c9b9adf74 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -46,6 +46,7 @@ Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph) Hero::~Hero() { delete _zoomBitmap; + delete _shadowBitmap; delete[] _shadowLine; } @@ -286,13 +287,11 @@ void Hero::showHeroShadow() { } } - // source Bitmap of sprite - esi - int destX = _drawX; // eax - int destY = _middleY - _shadMinus; // ecx - // modulo of source Bitmap - ebp - //int scaledX = getScaledValue(frameXSize); // ebx - //int scaledY = getScaledValue(frameYSize); // edx - // shadowTable70 - edi + int scaledX = getScaledValue(frameXSize); + //int scaledY = getScaledValue(frameYSize); + + int destX = _middleX - scaledX / 2; + int destY = _middleY - _shadMinus; if (destY > 1 && destY < kMaxPicHeight) { int shadDirection; @@ -307,15 +306,10 @@ void Hero::showHeroShadow() { Graphics::drawLine(_lightX, _lightY, destX, destY, 0, &plot, this); byte *sprShadow = (byte *)_graph->_shadowTable70; - // sprModulo = modulo of source Bitmap - //int sprWidth = scaledX; // this or normal size? - //int sprHeight = scaledY; int sprWidth = frameXSize; int sprHeight = frameYSize; - //int sprDestX = destX - _vm->_picWindowX; //test this - //int sprDestY = destY - _vm->_picWindowY; //test this - int sprDestX = destX; - int sprDestY = destY; + int sprDestX = destX - _vm->_picWindowX; + int sprDestY = destY - _vm->_picWindowY; _shadowDrawX = sprDestX; // to fix _shadowDrawY = sprDestY; @@ -347,7 +341,6 @@ void Hero::showHeroShadow() { // linear_loop for(int i = 0; i < sprHeight; i++) { - int sprModulo = 0; int shadSkipX = 0; int ct_loop = 0; @@ -402,7 +395,6 @@ void Hero::showHeroShadow() { //x1_ok if (shadPosX + sprWidth > 640) { ct_loop = 640 - shadPosX; // test it - sprModulo = shadPosX + sprWidth - 640; } else { //draw_line ct_loop = sprWidth; @@ -517,13 +509,13 @@ void Hero::showHeroShadow() { //next_line if (*(shadowLineStart + 2) < *(shadowLineStart - 2)) { //minus_y - shadBitAddr += kMaxPicWidth / 8; - shadPosY++; + shadBitAddr -= kMaxPicWidth / 8; + shadPosY--; diffY--; background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX + diffX, sprDestY + diffY); } else if (*(shadowLineStart + 2) > *(shadowLineStart - 2)) { - shadBitAddr -= kMaxPicWidth / 8; - shadPosY--; + shadBitAddr += kMaxPicWidth / 8; + shadPosY++; diffY++; background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX + diffX, sprDestY + diffY); } @@ -561,6 +553,7 @@ void Hero::showHeroShadow() { } //koniec_bajki } + delete makeShadow; } void Hero::showHeroAnimFrame() { From 2c9559b620def087f1d7e9bff3b2a07686c946f6 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 14 May 2014 00:21:59 +0200 Subject: [PATCH 089/374] PRINCE: Hero drawing - memory leak fix, shadow palette working --- engines/prince/graphics.cpp | 13 +-- engines/prince/hero.cpp | 170 ++++++++++++++++++++---------------- engines/prince/hero.h | 4 +- engines/prince/prince.cpp | 46 ++++++---- engines/prince/prince.h | 2 +- 5 files changed, 134 insertions(+), 101 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index ab6eec3d0b23..5b66994b478b 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -63,8 +63,7 @@ void GraphicsMan::change() { _changed = true; } -void GraphicsMan::draw(uint16 posX, uint16 posY, const Graphics::Surface *s) -{ +void GraphicsMan::draw(uint16 posX, uint16 posY, const Graphics::Surface *s) { uint16 w = MIN(_frontScreen->w, s->w); for (uint y = 0; y < s->h; y++) { if (y < _frontScreen->h) { @@ -74,18 +73,16 @@ void GraphicsMan::draw(uint16 posX, uint16 posY, const Graphics::Surface *s) change(); } -void GraphicsMan::drawTransparent(uint16 posX, uint16 posY, const Graphics::Surface *s) -{ +void GraphicsMan::drawTransparent(uint16 posX, uint16 posY, const Graphics::Surface *s) { for (uint y = 0; y < s->h; ++y) { for (uint x = 0; x < s->w; ++x) { byte pixel = *((byte*)s->getBasePtr(x, y)); if (pixel != 255) { - //*((byte*)_frontScreen->getBasePtr(x, y)) = pixel; *((byte*)_frontScreen->getBasePtr(x + posX, y + posY)) = pixel; } } } - change(); + change(); } void GraphicsMan::makeShadowTable(int brightness, byte *shadowPalette) { @@ -98,9 +95,8 @@ void GraphicsMan::makeShadowTable(int brightness, byte *shadowPalette) { int32 currColor; int shadow = brightness * 256 / 100; - byte *originalPalette = (byte *)malloc(256 * 3); - _vm->_system->getPaletteManager()->grabPalette(originalPalette, 0, 256); + const byte *originalPalette = _vm->_roomBmp->getPalette(); for (int i = 0; i < 256; i++) { redFirstOrg = originalPalette[3 * i] * shadow / 256; @@ -136,7 +132,6 @@ void GraphicsMan::makeShadowTable(int brightness, byte *shadowPalette) { } shadowPalette[i] = currColor; } - free(originalPalette); } } diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 884c9b9adf74..de4a3524cd56 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -57,7 +57,7 @@ bool Hero::loadAnimSet(uint32 animSetNr) { _shadMinus = heroSetBack[animSetNr]; - for (uint32 i = 0; i < _moveSet.size(); ++i) { + for (uint32 i = 0; i < _moveSet.size(); i++) { delete _moveSet[i]; } @@ -77,22 +77,11 @@ bool Hero::loadAnimSet(uint32 animSetNr) { return true; } -const Graphics::Surface * Hero::getSurface() { +Graphics::Surface *Hero::getSurface() { if (_moveSet[_moveSetType]) { - debug("BaseX: %d", _moveSet[_moveSetType]->getBaseX()); - debug("BaseY: %d", _moveSet[_moveSetType]->getBaseY()); - //debug("FrameCount: %d", _moveSet[_moveSetType]->getFrameCount()); - //debug("LoopCount: %d", _moveSet[_moveSetType]->getLoopCount()); - //debug("PhaseCount: %d", _moveSet[_moveSetType]->getPhaseCount()); - //debug("PhaseFrameIndex(%d): %d", _frame, _moveSet[_moveSetType]->getPhaseFrameIndex(_frame)); - //debug("PhaseOffsetX(%d): %d", _frame, _moveSet[_moveSetType]->getPhaseOffsetX(_frame)); - //debug("PhaseOffsetY(%d) %d", _frame, _moveSet[_moveSetType]->getPhaseOffsetY(_frame)); - //debug("FrameSizeX(%d) %d", _frame, _moveSet[_moveSetType]->getFrameWidth(_frame)); - //debug("FrameSizeY(%d) %d", _frame, _moveSet[_moveSetType]->getFrameHeight(_frame)); - //getState(); int16 phaseFrameIndex = _moveSet[_moveSetType]->getPhaseFrameIndex(_phase); Graphics::Surface *heroFrame = _moveSet[_moveSetType]->getFrame(phaseFrameIndex); - return zoomSprite(heroFrame); + return heroFrame; } return NULL; } @@ -173,49 +162,46 @@ Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) { Graphics::Surface *zoomedFrame = new Graphics::Surface(); zoomedFrame->create(scaledXSize, scaledYSize, Graphics::PixelFormat::createFormatCLUT8()); - if (_zoomFactor != 0) { - int sprZoomX; - int sprZoomY = _scaleValue; - uint xSource = 0; - uint ySource = 0; - uint xDest = 0; - uint yDest = 0; - - for (int i = 0; i < scaledYSize; i++) { - // linear_loop: - while(1) { - sprZoomY -= 100; - if (sprZoomY >= 0 || _scaleValue == 10000) { - // all_r_y - sprZoomX = _scaleValue; - break; // to loop_lin - } else { - sprZoomY += _scaleValue; - xSource = 0; - ySource++; - } + int sprZoomX; + int sprZoomY = _scaleValue; + uint xSource = 0; + uint ySource = 0; + uint xDest = 0; + uint yDest = 0; + + for (int i = 0; i < scaledYSize; i++) { + // linear_loop: + while(1) { + sprZoomY -= 100; + if (sprZoomY >= 0 || _scaleValue == 10000) { + // all_r_y + sprZoomX = _scaleValue; + break; // to loop_lin + } else { + sprZoomY += _scaleValue; + xSource = 0; + ySource++; } - // loop_lin: - for (int j = 0; j < scaledXSize; j++) { - sprZoomX -= 100; - if (sprZoomX >= 0) { - // its_all_r - memcpy(zoomedFrame->getBasePtr(xDest, yDest), heroFrame->getBasePtr(xSource, ySource), 1); - xDest++; - } else { - sprZoomX += _scaleValue; - j--; - } - xSource++; + } + // loop_lin: + for (int j = 0; j < scaledXSize; j++) { + sprZoomX -= 100; + if (sprZoomX >= 0) { + // its_all_r + memcpy(zoomedFrame->getBasePtr(xDest, yDest), heroFrame->getBasePtr(xSource, ySource), 1); + xDest++; + } else { + sprZoomX += _scaleValue; + j--; } - xDest = 0; - yDest++; - xSource = 0; - ySource++; + xSource++; } - return zoomedFrame; + xDest = 0; + yDest++; + xSource = 0; + ySource++; } - return heroFrame; + return zoomedFrame; } void Hero::countDrawPosition() { @@ -243,8 +229,6 @@ void Hero::countDrawPosition() { if (_zoomFactor != 0) { //notfullSize - debug("scaledX: %d", scaledX); - debug("scaledY: %d", scaledY); _drawX = _middleX - scaledX / 2; _drawY = tempMiddleY + 1 - scaledY; } else { @@ -265,9 +249,7 @@ static void plot(int x, int y, int color, void *data) { shadowLine->_shadowLineLen++; } -void Hero::showHeroShadow() { - int16 phaseFrameIndex = _moveSet[_moveSetType]->getPhaseFrameIndex(_phase); - Graphics::Surface *heroFrame = _moveSet[_moveSetType]->getFrame(phaseFrameIndex); +void Hero::showHeroShadow(Graphics::Surface *heroFrame) { int16 frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); int16 frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); @@ -419,7 +401,7 @@ void Hero::showHeroShadow() { //smaller_y //retry_line2 int ebxOnStack2; - for(ebxOnStack2 = ebxOnStack; ebxOnStack2 > 0; ebxOnStack2--) { + for (ebxOnStack2 = ebxOnStack; ebxOnStack2 > 0; ebxOnStack2--) { shadZoomY2 -= 100; if (shadZoomY2 < 0 && _shadScaleValue != 10000) { shadZoomY2 += _shadScaleValue; @@ -441,14 +423,12 @@ void Hero::showHeroShadow() { //line_y_ok_2: // push esi // push ecx - // int lineDestAddr = eax; - // edi = eax - // eax = shadBitMask - // push eax // push shadBitMask - // lineBitAddr = shadBitMask - // eax = shadBitAddr - // push eax - // LineBitAddr = eax + // lineDestAddr = eax; + // edi = eax -> needed in copy trans + // push shadBitMask + // lineBitAddr = shadBitMask; + // push shadBitAddr; + // lineBitAddr = shadBitAddr; //copy_trans //push eax, ebx, edx, ebp @@ -473,8 +453,7 @@ void Hero::showHeroShadow() { } } //shadow - //*background = *(sprShadow + *background); //wrong color - *background = 0; + *background = *(sprShadow + *background); } //ct_next //ror(shadBitMask, 1) @@ -493,14 +472,56 @@ void Hero::showHeroShadow() { } //byebyebye if (shadWallDown == 0 && shadWDFlag != 0) { - //shadWall etc + //shadWallDown = shadPosX; + //shadWallBitAddr = lineBitAddr; + //shadWallDestAddr = lineDestAddr; + //shadWallBitMask = lineBitMask; + //shadWallPosY = shadPosY; + //shadWallSkipX = shadSkipX; + //shadWallModulo = sprModulo; } //byebye - // pop ... + //pop ebp edx ebx eax + //pop shadBitAddr + //pop shadBitMask + //pop ecx + //pop edi if (shadDirection != 0 && shadWallDown != 0) { - // push... - // krap2 - // WALL_copy_trans + //push esi + //esi = edi; + //push shadBitMask + //push shadBitAddr + //shadBitMask = shadWallBitMask; + //shadBitAddr = shadWallBitAddr; + //eax = shadWallSkipX; + //edi = shadWallDestAddr; + //esi += shadWallSkipX; + //if (ct_loop > shadWallSkipX && ct_loop - shadWallSkipX > shadWallModulo) { + //WALL_copy_trans + //} else { + //krap2 + //pop shadBitAddr + //pop shadBitMask + //pop esi + //ebx = VESA_ScanLine + if (shadDirection != 0) { + //shadWallDestAddr -= ebx; //SCREENWIDTH + //shadWallBitAddr -= kMaxPicWidth / 8; + //shadWallPosY--; + } else { + //down_direct + //shadWallDestAddr += ebx; //SCREENWIDTH + //shadWallBitAddr += kMaxPicWidth / 8; + //shadWallPosY++; + } + //compareagain + //if (shadWallPosY < shadMinY) { + // shadMinY = shadWallPosY; + //} + //if (shadWallPosY > shadMaxY) { + // shadMaxY = shadWallPosY; + //} + //} } } //skip_line @@ -553,6 +574,7 @@ void Hero::showHeroShadow() { } //koniec_bajki } + makeShadow->free(); delete makeShadow; } diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 75f6a3a78bc7..9e67cda6c3ec 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -103,7 +103,7 @@ class Hero { Common::RandomSource _randomSource; bool loadAnimSet(uint32 heroAnimNumber); - const Graphics::Surface * getSurface(); + Graphics::Surface *getSurface(); void setPos(int16 x, int16 y) { _middleX = x; _middleY = y; } void setVisible(bool flag) { _visible = flag; } @@ -121,7 +121,7 @@ class Hero { void showHeroAnimFrame(); void line(int x1, int y1, int x2, int y2); void plotPoint(int x, int y); - void showHeroShadow(); + void showHeroShadow(Graphics::Surface *heroFrame); void setShadowScale(int32 shadowScale); void specialAnim(); void getState(); diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 533d2f4c578e..f987ff222fe8 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -108,13 +108,22 @@ PrinceEngine::~PrinceEngine() { delete _variaTxt; delete[] _talkTxt; delete _graph; - delete _mainHero; - delete _secondHero; - for (uint i = 0; i < _objList.size(); ++i) { + for (uint i = 0; i < _objList.size(); i++) { delete _objList[i]; } _objList.clear(); + + for (uint i = 0; i < _mainHero->_moveSet.size(); i++) { + delete _mainHero->_moveSet[i]; + } + + for (uint i = 0; i < _secondHero->_moveSet.size(); i++) { + delete _secondHero->_moveSet[i]; + } + + delete _mainHero; + delete _secondHero; } GUI::Debugger *PrinceEngine::getDebugger() { @@ -189,7 +198,8 @@ void PrinceEngine::init() { _mainHero = new Hero(this, _graph); _secondHero = new Hero(this, _graph); - _mainHero->loadAnimSet(0); + _mainHero->loadAnimSet(1); + _secondHero->loadAnimSet(3); } void PrinceEngine::showLogo() { @@ -278,6 +288,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { Resource::loadResource(_roomBmp, "room"); if (_roomBmp->getSurface()) { _sceneWidth = _roomBmp->getSurface()->w; + _graph->setPalette(_roomBmp->getPalette()); } _mainHero->_zoomBitmap->clear(); @@ -532,16 +543,16 @@ void PrinceEngine::keyHandler(Common::Event event) { debugEngine("%d", _mainHero->_state); break; case Common::KEYCODE_i: - _mainHero->_middleY -= 10; + _mainHero->_middleY -= 5; break; case Common::KEYCODE_k: - _mainHero->_middleY += 10; + _mainHero->_middleY += 5; break; case Common::KEYCODE_j: - _mainHero->_middleX -= 10; + _mainHero->_middleX -= 5; break; case Common::KEYCODE_l: - _mainHero->_middleX += 10; + _mainHero->_middleX += 5; break; } } @@ -633,20 +644,25 @@ void PrinceEngine::showTexts() { void PrinceEngine::drawScreen() { const Graphics::Surface *roomSurface = _roomBmp->getSurface(); if (roomSurface) { - _graph->setPalette(_roomBmp->getPalette()); const Graphics::Surface visiblePart = roomSurface->getSubArea(Common::Rect(_picWindowX, 0, roomSurface->w, roomSurface->h)); _graph->draw(0, 0, &visiblePart); } if (_mainHero->_visible) { - const Graphics::Surface *mainHeroSurface = _mainHero->getSurface(); - //const Graphics::Surface *mainHeroShadow = _mainHero->showHeroShadow(); - + Graphics::Surface *mainHeroSurface = _mainHero->getSurface(); if (mainHeroSurface) { - _mainHero->showHeroShadow(); - _graph->drawTransparent(_mainHero->_drawX, _mainHero->_drawY, mainHeroSurface); - //_graph->drawTransparent(_mainHero->_shadowDrawX, _mainHero->_shadowDrawY, mainHeroShadow); + _mainHero->showHeroShadow(mainHeroSurface); + if (_mainHero->_zoomFactor != 0) { + Graphics::Surface *zoomedHeroSurface = _mainHero->zoomSprite(mainHeroSurface); + _graph->drawTransparent(_mainHero->_drawX, _mainHero->_drawY, zoomedHeroSurface); + zoomedHeroSurface->free(); + delete zoomedHeroSurface; + } else { + _graph->drawTransparent(_mainHero->_drawX, _mainHero->_drawY, mainHeroSurface); + } } + mainHeroSurface->free(); + delete mainHeroSurface; } playNextFrame(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 7793545526d1..e7cdce5af16b 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -145,6 +145,7 @@ class PrinceEngine : public Engine { uint16 _sceneWidth; uint32 _picWindowX; uint32 _picWindowY; + Image::BitmapDecoder *_roomBmp; private: bool playNextFrame(); @@ -165,7 +166,6 @@ class PrinceEngine : public Engine { uint8 _cursorNr; Common::RandomSource *_rnd; - Image::BitmapDecoder *_roomBmp; Cursor *_cursor1; Cursor *_cursor2; MhwanhDecoder *_suitcaseBmp; From 7239843ba743792d1f3dc8fab600715d0a1667bd Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 14 May 2014 03:20:26 +0200 Subject: [PATCH 090/374] PRINCE: showHeroShadow - small fix for doubled lines and wrong colors --- engines/prince/hero.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index de4a3524cd56..1697998c432d 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -315,6 +315,8 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { int blackHeroX = 0; int blackHeroY = frameYSize - 1; + int shadLastY = 0; + byte *shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY); // esi, first pixel from last row of black hero byte *background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX, sprDestY); // eax, pixel of background where shadow sprite starts @@ -348,7 +350,8 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { break; } //line_y_ok - if (shadPosY >= 0 && shadPosY < 480 && shadPosX < 640) { + if (shadLastY != shadPosY && shadPosY >= 0 && shadPosY < 480 && shadPosX < 640) { + shadLastY = shadPosY; if (shadPosX < 0) { //when it happens? shadSkipX = -1 * shadPosX; background += shadSkipX; @@ -533,12 +536,10 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { shadBitAddr -= kMaxPicWidth / 8; shadPosY--; diffY--; - background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX + diffX, sprDestY + diffY); } else if (*(shadowLineStart + 2) > *(shadowLineStart - 2)) { shadBitAddr += kMaxPicWidth / 8; shadPosY++; diffY++; - background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX + diffX, sprDestY + diffY); } //no_change_y if (*shadowLineStart < *(shadowLineStart - 4)) { @@ -570,6 +571,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { break; } blackHeroX = 0; + background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX + diffX, sprDestY + diffY); shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY); } //koniec_bajki From 29dff92dba67e1986535837b0717ebb9cb335da7 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 14 May 2014 05:04:12 +0200 Subject: [PATCH 091/374] PRINCE: Hero class clean up --- engines/prince/hero.cpp | 120 ++++++++++++++-------------------------- engines/prince/hero.h | 18 ++++-- 2 files changed, 54 insertions(+), 84 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 1697998c432d..2b4f156df23b 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -36,8 +36,8 @@ Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph) , _boreNum(1), _currHeight(0), _moveDelay(0), _shadMinus(0), _moveSetType(0) , _lastDirection(DOWN), _destDirection(DOWN), _talkTime(0), _boredomTime(0), _phase(0) , _specAnim(0), _drawX(0), _drawY(0), _randomSource("prince"), _zoomFactor(0), _scaleValue(0) - , _shadZoomFactor(0), _shadScaleValue(0), _shadowLineLen(0), _shadowDrawX(0), _shadowDrawY(0) - , _shadLastY(0) + , _shadZoomFactor(0), _shadScaleValue(0), _shadLineLen(0), _shadDrawX(0), _shadDrawY(0) + , _frameXSize(0), _frameYSize(0), _scaledFrameXSize(0), _scaledFrameYSize(0) { _zoomBitmap = new Animation(); _shadowBitmap = new Animation(); @@ -145,22 +145,8 @@ void Hero::checkNak() { } Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) { - int16 tempMiddleY; - int16 baseX = _moveSet[_moveSetType]->getBaseX(); - int16 baseY = _moveSet[_moveSetType]->getBaseY(); - // any chance? - if (baseX == 320) { - tempMiddleY = _middleY - (baseY - 240); - } else { - tempMiddleY = _middleY; - } - int16 frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); - int16 frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); - int scaledXSize = getScaledValue(frameXSize); - int scaledYSize = getScaledValue(frameYSize); - Graphics::Surface *zoomedFrame = new Graphics::Surface(); - zoomedFrame->create(scaledXSize, scaledYSize, Graphics::PixelFormat::createFormatCLUT8()); + zoomedFrame->create(_scaledFrameXSize, _scaledFrameYSize, Graphics::PixelFormat::createFormatCLUT8()); int sprZoomX; int sprZoomY = _scaleValue; @@ -169,7 +155,7 @@ Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) { uint xDest = 0; uint yDest = 0; - for (int i = 0; i < scaledYSize; i++) { + for (int i = 0; i < _scaledFrameYSize; i++) { // linear_loop: while(1) { sprZoomY -= 100; @@ -184,7 +170,7 @@ Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) { } } // loop_lin: - for (int j = 0; j < scaledXSize; j++) { + for (int j = 0; j < _scaledFrameXSize; j++) { sprZoomX -= 100; if (sprZoomX >= 0) { // its_all_r @@ -214,10 +200,10 @@ void Hero::countDrawPosition() { } else { tempMiddleY = _middleY; } - int16 frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); - int16 frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); - int scaledX = getScaledValue(frameXSize); - int scaledY = getScaledValue(frameYSize); + _frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); + _frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); + _scaledFrameXSize = getScaledValue(_frameXSize); + _scaledFrameYSize = getScaledValue(_frameYSize); //TODO //int tempHeroHeight = scaledY; // not used? global? @@ -229,38 +215,35 @@ void Hero::countDrawPosition() { if (_zoomFactor != 0) { //notfullSize - _drawX = _middleX - scaledX / 2; - _drawY = tempMiddleY + 1 - scaledY; + _drawX = _middleX - _scaledFrameXSize / 2; + _drawY = tempMiddleY + 1 - _scaledFrameYSize; } else { //fullSize - _drawX = _middleX - frameXSize / 2; - _drawY = tempMiddleY + 1 - frameYSize; + _drawX = _middleX - _frameXSize / 2; + _drawY = tempMiddleY + 1 - _frameYSize; } } void Hero::plotPoint(int x, int y) { - WRITE_UINT16(&_shadowLine[_shadowLineLen * 4], x); - WRITE_UINT16(&_shadowLine[_shadowLineLen * 4 + 2], y); + WRITE_UINT16(&_shadowLine[_shadLineLen * 4], x); + WRITE_UINT16(&_shadowLine[_shadLineLen * 4 + 2], y); } static void plot(int x, int y, int color, void *data) { Hero *shadowLine = (Hero *)data; shadowLine->plotPoint(x, y); - shadowLine->_shadowLineLen++; + shadowLine->_shadLineLen++; } void Hero::showHeroShadow(Graphics::Surface *heroFrame) { - int16 frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); - int16 frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); - Graphics::Surface *makeShadow = new Graphics::Surface(); - makeShadow->create(frameXSize, frameYSize, Graphics::PixelFormat::createFormatCLUT8()); + makeShadow->create(_frameXSize, _frameYSize, Graphics::PixelFormat::createFormatCLUT8()); - for (int y = 0; y < frameYSize; y++) { + for (int y = 0; y < _frameYSize; y++) { byte *src = (byte *)heroFrame->getBasePtr(0, y); byte *dst = (byte *)makeShadow->getBasePtr(0, y); - for (int x = 0; x < frameXSize; x++, dst++, src++) { + for (int x = 0; x < _frameXSize; x++, dst++, src++) { if (*src != 0xFF) { *dst = kShadowColor; } else { @@ -269,11 +252,8 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { } } - int scaledX = getScaledValue(frameXSize); - //int scaledY = getScaledValue(frameYSize); - - int destX = _middleX - scaledX / 2; - int destY = _middleY - _shadMinus; + int destX = _middleX - _scaledFrameXSize / 2; + int destY = _middleY - _shadMinus - 1; if (destY > 1 && destY < kMaxPicHeight) { int shadDirection; @@ -284,25 +264,21 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { } int shadWallDown = 0; - _shadowLineLen = 0; + _shadLineLen = 0; Graphics::drawLine(_lightX, _lightY, destX, destY, 0, &plot, this); byte *sprShadow = (byte *)_graph->_shadowTable70; - int sprWidth = frameXSize; - int sprHeight = frameYSize; - int sprDestX = destX - _vm->_picWindowX; - int sprDestY = destY - _vm->_picWindowY; - _shadowDrawX = sprDestX; // to fix - _shadowDrawY = sprDestY; + _shadDrawX = destX - _vm->_picWindowX; + _shadDrawY = destY - _vm->_picWindowY; - int shadPosX = sprDestX; - int shadMinX = sprDestX; - int shadMaxX = sprDestX; + int shadPosX = _shadDrawX; + int shadMinX = _shadDrawX; + int shadMaxX = _shadDrawX; - int shadPosY = sprDestY; - int shadMinY = sprDestY; - int shadMaxY = sprDestY; + int shadPosY = _shadDrawY; + int shadMinY = _shadDrawY; + int shadMaxY = _shadDrawY; int shadBitAddr = destY * kMaxPicWidth / 8 + destX / 8; int shadBitMask = 128 >> (destX % 8); @@ -313,24 +289,24 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { int diffY = 0; int blackHeroX = 0; - int blackHeroY = frameYSize - 1; + int blackHeroY = _frameYSize - 1; int shadLastY = 0; - byte *shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY); // esi, first pixel from last row of black hero - byte *background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX, sprDestY); // eax, pixel of background where shadow sprite starts + byte *shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY); // first pixel from last row of black hero + byte *background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX, _shadDrawY); // pixel of background where shadow sprite starts // banked2 byte *shadowLineStart = _shadowLine + 8; // linear_loop - for(int i = 0; i < sprHeight; i++) { + for(int i = 0; i < _frameYSize; i++) { int shadSkipX = 0; int ct_loop = 0; int ebxOnStack; //retry_line: - for (ebxOnStack = sprHeight - i; ebxOnStack > 0; ebxOnStack--) { + for (ebxOnStack = _frameYSize - i; ebxOnStack > 0; ebxOnStack--) { shadZoomY -= 100; if (shadZoomY < 0 && _scaleValue != 10000) { shadZoomY += _scaleValue; @@ -355,7 +331,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { if (shadPosX < 0) { //when it happens? shadSkipX = -1 * shadPosX; background += shadSkipX; - if (sprWidth > shadSkipX) { + if (_frameXSize > shadSkipX) { shadowStart += shadSkipX; shadBitAddr += shadSkipX / 8; int ebp16844 = shadSkipX % 8; @@ -378,11 +354,11 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { } } else { //x1_ok - if (shadPosX + sprWidth > 640) { + if (shadPosX + _frameXSize > 640) { ct_loop = 640 - shadPosX; // test it } else { //draw_line - ct_loop = sprWidth; + ct_loop = _frameXSize; } } //draw_line1 @@ -390,8 +366,8 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { shadMinX = shadPosX; } //bigger_x - if (shadPosX + sprWidth > shadMaxX) { - shadMaxX = shadPosX + sprWidth; + if (shadPosX + _frameXSize > shadMaxX) { + shadMaxX = shadPosX + _frameXSize; } //smaller_x if (shadPosY < shadMinY) { @@ -470,7 +446,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { blackHeroX++; shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY); backgroundDiff++; - background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX + diffX + backgroundDiff, sprDestY + diffY); + background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX + backgroundDiff, _shadDrawY + diffY); } } //byebyebye @@ -571,7 +547,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { break; } blackHeroX = 0; - background = (byte *)_graph->_frontScreen->getBasePtr(sprDestX + diffX, sprDestY + diffY); + background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX, _shadDrawY + diffY); shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY); } //koniec_bajki @@ -587,12 +563,6 @@ void Hero::showHeroAnimFrame() { _phase = 0; } countDrawPosition(); - //temp: - //showHeroShadow(); - //debug("_drawX: %d", _drawX); - //debug("_drawY: %d", _drawY); - //debug("_middleX: %d", _middleX); - //debug("_middleY: %d", _middleY); } void Hero::setScale(int8 zoomBitmapValue) { @@ -603,14 +573,10 @@ void Hero::setScale(int8 zoomBitmapValue) { _zoomFactor = zoomBitmapValue; _scaleValue = 10000 / _zoomFactor; } - debug("_zoomFactor: %d", _zoomFactor); - debug("_scaleValue: %d", _scaleValue); } void Hero::selectZoom() { int8 zoomBitmapValue = _zoomBitmap->getZoom(_middleY / 4 * kZoomBitmapWidth + _middleX / 4); - debug("offset: %d", _middleY / 4 * kZoomBitmapWidth + _middleX / 4); - debug("zoomBitmapValue: %d", _zoomFactor); setScale(zoomBitmapValue); } @@ -623,8 +589,6 @@ void Hero::setShadowScale(int32 shadowScale) { _shadZoomFactor = shadowScale; _shadScaleValue = 10000 / _shadZoomFactor; } - debug("_shadZoomFactor: %d", _shadZoomFactor); - debug("_shadScaleValue: %d", _shadScaleValue); } void Hero::specialAnim() { diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 9e67cda6c3ec..28b97d9b68d6 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -129,26 +129,32 @@ class Hero { //private: PrinceEngine *_vm; GraphicsMan *_graph; + uint16 _number; uint16 _visible; int16 _state; int16 _middleX; // middle of X int16 _middleY; // lower part of hero - int16 _drawX; - int16 _drawY; int16 _lastDirection; int16 _destDirection; int16 _moveSetType; + int8 _zoomFactor; int16 _scaleValue; + int16 _frameXSize; + int16 _frameYSize; + int16 _scaledFrameXSize; + int16 _scaledFrameYSize; + int16 _drawX; + int16 _drawY; + int16 _lightX; // for hero's shadow int16 _lightY; int32 _shadZoomFactor; int32 _shadScaleValue; - int32 _shadowLineLen; - int16 _shadowDrawX; - int16 _shadowDrawY; - int16 _shadLastY; + int32 _shadLineLen; + int16 _shadDrawX; + int16 _shadDrawY; // Coords array of coordinates // DirTab array of directions From 42bdde956a6cba01ea5712c9fbdd8ee0b7ccbb36 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 15 May 2014 15:12:56 +0200 Subject: [PATCH 092/374] PRINCE: loadShadow() fix, begin of drawing shadows on walls --- engines/prince/animation.cpp | 5 -- engines/prince/hero.cpp | 148 ++++++++++++++++++++++++----------- engines/prince/hero.h | 5 +- engines/prince/prince.cpp | 30 ++++++- engines/prince/prince.h | 1 + 5 files changed, 133 insertions(+), 56 deletions(-) diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index 9911f5f99e9e..e27d556f1b84 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -58,11 +58,6 @@ void Animation::clear() { } // TEMP -/* -int8 Animation::getZoom(uint16 offset) const { - return *(uint8*)(_data+offset); -} -*/ int16 Animation::getZoom(uint16 offset) const { return READ_LE_UINT16(_data + offset); } diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 2b4f156df23b..8afa0ca37258 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -40,13 +40,13 @@ Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph) , _frameXSize(0), _frameYSize(0), _scaledFrameXSize(0), _scaledFrameYSize(0) { _zoomBitmap = new Animation(); - _shadowBitmap = new Animation(); + _shadowBitmap = (byte *)malloc(2 * kShadowBitmapSize); _shadowLine = new byte[kShadowLineArraySize]; } Hero::~Hero() { delete _zoomBitmap; - delete _shadowBitmap; + free(_shadowBitmap); delete[] _shadowLine; } @@ -280,7 +280,12 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { int shadMinY = _shadDrawY; int shadMaxY = _shadDrawY; int shadBitAddr = destY * kMaxPicWidth / 8 + destX / 8; + debug("destX: %d", destX); + debug("destY: %d", destY); + debug("shadBitmap: %d", _shadowBitmap[shadBitAddr]); + debug("shadBitmap2: %d", _shadowBitmap[shadBitAddr + kShadowBitmapSize]); int shadBitMask = 128 >> (destX % 8); + debug("shadBitMask: %d", shadBitMask); int shadZoomY2 = _shadScaleValue; int shadZoomY = _scaleValue; @@ -299,10 +304,18 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { // banked2 byte *shadowLineStart = _shadowLine + 8; + int shadWallBitAddr = 0; + int shadWallBitMask = 0; + byte *shadWallDestAddr = 0; + int shadWallPosY = 0; + int shadWallSkipX = 0; + int shadWallModulo = 0; + // linear_loop for(int i = 0; i < _frameYSize; i++) { int shadSkipX = 0; int ct_loop = 0; + int sprModulo = 0; int ebxOnStack; //retry_line: @@ -356,6 +369,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { //x1_ok if (shadPosX + _frameXSize > 640) { ct_loop = 640 - shadPosX; // test it + sprModulo = shadPosX + _frameXSize - 640; } else { //draw_line ct_loop = _frameXSize; @@ -400,14 +414,14 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { break; } //line_y_ok_2: - // push esi - // push ecx - // lineDestAddr = eax; + // push esi - background + // push ecx - ct_loop + byte *lineDestAddr = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX, _shadDrawY + diffY); // edi = eax -> needed in copy trans // push shadBitMask - // lineBitAddr = shadBitMask; + int lineBitMask = shadBitMask; // before copy_trans ct_loop // push shadBitAddr; - // lineBitAddr = shadBitAddr; + int lineBitAddr = shadBitAddr; // before copy_trans ct_loop //copy_trans //push eax, ebx, edx, ebp @@ -422,17 +436,21 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY); shadZoomX += _scaleValue; } else { - //point_ok: if (*shadowStart == kShadowColor) { - if (shadBitMask != _shadowBitmap->getZoom(shadBitAddr)) { //tofix + if (shadBitMask != _shadowBitmap[shadBitAddr]) { + //debug("shadBitMask: %d", shadBitMask); + //debug("_shadBitmap: %d", _shadowBitmap->getShadow(shadBitAddr)); if (shadWallDown == 0) { - if (shadBitMask != _shadowBitmap->getZoom(shadBitAddr + kShadowBitmapSize)) { //tofix + if (shadBitMask != _shadowBitmap[shadBitAddr + kShadowBitmapSize]) { shadWDFlag = 1; + //shadow + *background = *(sprShadow + *background); } } + } else { + //shadow + *background = *(sprShadow + *background); } - //shadow - *background = *(sprShadow + *background); } //ct_next //ror(shadBitMask, 1) @@ -449,59 +467,99 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX + backgroundDiff, _shadDrawY + diffY); } } + /* //byebyebye if (shadWallDown == 0 && shadWDFlag != 0) { - //shadWallDown = shadPosX; - //shadWallBitAddr = lineBitAddr; - //shadWallDestAddr = lineDestAddr; - //shadWallBitMask = lineBitMask; - //shadWallPosY = shadPosY; - //shadWallSkipX = shadSkipX; - //shadWallModulo = sprModulo; + shadWallDown = shadPosX; + shadWallBitAddr = lineBitAddr; + shadWallDestAddr = lineDestAddr; + shadWallBitMask = lineBitMask; + shadWallPosY = shadPosY; + shadWallSkipX = shadSkipX; + shadWallModulo = sprModulo; } //byebye //pop ebp edx ebx eax //pop shadBitAddr //pop shadBitMask - //pop ecx - //pop edi + //pop ecx - ct_loop + //pop edi - shadowStart if (shadDirection != 0 && shadWallDown != 0) { //push esi - //esi = edi; - //push shadBitMask - //push shadBitAddr - //shadBitMask = shadWallBitMask; - //shadBitAddr = shadWallBitAddr; - //eax = shadWallSkipX; - //edi = shadWallDestAddr; - //esi += shadWallSkipX; - //if (ct_loop > shadWallSkipX && ct_loop - shadWallSkipX > shadWallModulo) { + //esi = edi; // shadowStart + //push shadBitMask + //push shadBitAddr + shadBitMask = shadWallBitMask; + shadBitAddr = shadWallBitAddr; + //eax = shadWallSkipX; -not needed in wall_copy_trans + background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX, _shadDrawY + diffY); //edi = shadWallDestAddr; + shadowStart = (byte *)makeShadow->getBasePtr(shadWallSkipX, blackHeroY); //esi += shadWallSkipX; + + if (ct_loop > shadWallSkipX && ct_loop - shadWallSkipX > shadWallModulo) { //WALL_copy_trans - //} else { + //push eax, ebx, edx, ebp + //ebx = SprShadow; + //ebp = ShadBitAddr; + //ah = ShadBitMask; + shadWDFlag = 0; + int shadZoomX = _scaleValue; + int backgroundDiff = 0; + int blackHeroXWall = 0; + //ct_loop: + for (int j = 0; j < ct_loop; j++) { + shadZoomX -= 100; + if (shadZoomX < 0 && _scaleValue != 10000) { + blackHeroXWall++; + shadowStart = (byte *)makeShadow->getBasePtr(shadWallSkipX + blackHeroXWall, blackHeroY); + shadZoomX += _scaleValue; + } else { + //point_ok: + if (*shadowStart == kShadowColor) { + if (shadBitMask != _shadowBitmap->getShadow(shadBitAddr + kShadowBitmapSize)) { + //*background = *(sprShadow + *background); + *background = 50; + } + } + //ct_next + //ror(shadBitMask, 1) + if (shadBitMask == 1) { + shadBitMask = 128; + shadBitAddr++; + } else { + shadBitMask /= 2; + } + //okok + blackHeroXWall++; + shadowStart = (byte *)makeShadow->getBasePtr(shadWallSkipX + blackHeroXWall, blackHeroY); + backgroundDiff++; + background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX + backgroundDiff, _shadDrawY + diffY); + } + } + } else { //krap2 //pop shadBitAddr //pop shadBitMask //pop esi - //ebx = VESA_ScanLine if (shadDirection != 0) { - //shadWallDestAddr -= ebx; //SCREENWIDTH - //shadWallBitAddr -= kMaxPicWidth / 8; - //shadWallPosY--; + shadWallDestAddr -= kScreenWidth; + shadWallBitAddr -= kMaxPicWidth / 8; + shadWallPosY--; } else { //down_direct - //shadWallDestAddr += ebx; //SCREENWIDTH - //shadWallBitAddr += kMaxPicWidth / 8; - //shadWallPosY++; + shadWallDestAddr += kScreenWidth; + shadWallBitAddr += kMaxPicWidth / 8; + shadWallPosY++; } //compareagain - //if (shadWallPosY < shadMinY) { - // shadMinY = shadWallPosY; - //} - //if (shadWallPosY > shadMaxY) { - // shadMaxY = shadWallPosY; - //} - //} + if (shadWallPosY < shadMinY) { + shadMinY = shadWallPosY; + } + if (shadWallPosY > shadMaxY) { + shadMaxY = shadWallPosY; + } + } } + */ } //skip_line //add esi, sprWidth - don't need it? diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 28b97d9b68d6..7fe3218b91a6 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -45,7 +45,8 @@ class Hero { static const int16 kZoomBitmapWidth = kMaxPicWidth / kZoomStep; static const int16 kNormalWidth = 640; static const int16 kShadowLineArraySize = 2 * 1280 * 4; - static const int16 kShadowBitmapSize = kMaxPicWidth * kMaxPicHeight / 8; + static const int32 kShadowBitmapSize = kMaxPicWidth * kMaxPicHeight / 8; + static const int16 kScreenWidth = 640; static const byte kShadowColor = 191; @@ -182,7 +183,7 @@ class Hero { Common::Array _moveSet; // MoveAnims MoveSet // TurnAnim ?? Animation *_zoomBitmap; // change to sth else, not Animation ?? - Animation *_shadowBitmap; + byte *_shadowBitmap; byte *_shadowLine; uint32 _moveDelay; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index f987ff222fe8..98f9689b9aa2 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -294,10 +294,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mainHero->_zoomBitmap->clear(); Resource::loadResource(_mainHero->_zoomBitmap, "zoom", false); - _mainHero->_shadowBitmap->clear(); - if (Resource::loadResource(_mainHero->_shadowBitmap, "shadow", false) == false) { - Resource::loadResource(_mainHero->_shadowBitmap, "shadow2", false); - } + loadShadow(_mainHero->_shadowBitmap, _mainHero->kShadowBitmapSize, "shadow", "shadow2"); _picWindowX = 0; @@ -471,6 +468,31 @@ bool PrinceEngine::loadAnim(uint16 animNr, bool loop) { return true; } +bool PrinceEngine::loadShadow(byte *shadowBitmap, uint32 dataSize, const char *resourceName1, const char *resourceName2) { + + Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName1); + if (!stream) { + return false; + } + + if (stream->read(shadowBitmap, dataSize) != dataSize) { + free(shadowBitmap); + return false; + } + + stream = SearchMan.createReadStreamForMember(resourceName2); + if (!stream) { + return false; + } + + byte *shadowBitmap2 = shadowBitmap + dataSize; + if (stream->read(shadowBitmap2, dataSize) != dataSize) { + free(shadowBitmap); + return false; + } + return true; +} + void PrinceEngine::scrollCameraLeft(int16 delta) { if (_newCameraX > 0) { if (_newCameraX < delta) diff --git a/engines/prince/prince.h b/engines/prince/prince.h index e7cdce5af16b..dd00abb7886c 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -124,6 +124,7 @@ class PrinceEngine : public Engine { bool loadAnim(uint16 animNr, bool loop); bool loadVoice(uint32 textSlot, uint32 sampleSlot, const Common::String &name); bool loadSample(uint32 sampleSlot, const Common::String &name); + bool loadShadow(byte *shadowBitmap, uint32 dataSize, const char *resourceName1, const char *resourceName2); void playSample(uint16 sampleId, uint16 loopType); void stopSample(uint16 sampleId); From c9f6def2bdfc2ccc1a13c709d81f4c2357bacea7 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 15 May 2014 22:17:24 +0200 Subject: [PATCH 093/374] PRINCE: showHeroShadow - proper shadow masking on objects --- engines/prince/hero.cpp | 80 +++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 8afa0ca37258..302bd01064a3 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -280,12 +280,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { int shadMinY = _shadDrawY; int shadMaxY = _shadDrawY; int shadBitAddr = destY * kMaxPicWidth / 8 + destX / 8; - debug("destX: %d", destX); - debug("destY: %d", destY); - debug("shadBitmap: %d", _shadowBitmap[shadBitAddr]); - debug("shadBitmap2: %d", _shadowBitmap[shadBitAddr + kShadowBitmapSize]); int shadBitMask = 128 >> (destX % 8); - debug("shadBitMask: %d", shadBitMask); int shadZoomY2 = _shadScaleValue; int shadZoomY = _scaleValue; @@ -428,6 +423,8 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { int shadWDFlag = 0; int shadZoomX = _scaleValue; int backgroundDiff = 0; + int shadBitMaskCopyTrans = shadBitMask; + int shadBitAddrCopyTrans = shadBitAddr; //ct_loop: for (int j = 0; j < ct_loop; j++) { shadZoomX -= 100; @@ -437,11 +434,9 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { shadZoomX += _scaleValue; } else { if (*shadowStart == kShadowColor) { - if (shadBitMask != _shadowBitmap[shadBitAddr]) { - //debug("shadBitMask: %d", shadBitMask); - //debug("_shadBitmap: %d", _shadowBitmap->getShadow(shadBitAddr)); + if ((shadBitMaskCopyTrans & _shadowBitmap[shadBitAddrCopyTrans]) != 0) { if (shadWallDown == 0) { - if (shadBitMask != _shadowBitmap[shadBitAddr + kShadowBitmapSize]) { + if ((shadBitMaskCopyTrans & _shadowBitmap[shadBitAddrCopyTrans + kShadowBitmapSize]) != 0) { shadWDFlag = 1; //shadow *background = *(sprShadow + *background); @@ -454,11 +449,11 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { } //ct_next //ror(shadBitMask, 1) - if (shadBitMask == 1) { - shadBitMask = 128; - shadBitAddr++; + if (shadBitMaskCopyTrans == 1) { + shadBitMaskCopyTrans = 128; + shadBitAddrCopyTrans++; } else { - shadBitMask /= 2; + shadBitMaskCopyTrans /= 2; } //okok blackHeroX++; @@ -467,7 +462,6 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX + backgroundDiff, _shadDrawY + diffY); } } - /* //byebyebye if (shadWallDown == 0 && shadWDFlag != 0) { shadWallDown = shadPosX; @@ -478,19 +472,20 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { shadWallSkipX = shadSkipX; shadWallModulo = sprModulo; } + /* //byebye //pop ebp edx ebx eax //pop shadBitAddr //pop shadBitMask //pop ecx - ct_loop //pop edi - shadowStart - if (shadDirection != 0 && shadWallDown != 0) { + if (shadDirection != 0 && shadWallDown != 0) { //only when shadow draw up //push esi //esi = edi; // shadowStart //push shadBitMask //push shadBitAddr - shadBitMask = shadWallBitMask; - shadBitAddr = shadWallBitAddr; + int shadBitMaskWallCopyTrans = shadWallBitMask; + int shadBitAddrWallCopyTrans = shadWallBitAddr; //eax = shadWallSkipX; -not needed in wall_copy_trans background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX, _shadDrawY + diffY); //edi = shadWallDestAddr; shadowStart = (byte *)makeShadow->getBasePtr(shadWallSkipX, blackHeroY); //esi += shadWallSkipX; @@ -515,18 +510,18 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { } else { //point_ok: if (*shadowStart == kShadowColor) { - if (shadBitMask != _shadowBitmap->getShadow(shadBitAddr + kShadowBitmapSize)) { + if (shadBitMaskWallCopyTrans != _shadowBitmap[shadBitAddrWallCopyTrans + kShadowBitmapSize]) { //*background = *(sprShadow + *background); *background = 50; } } //ct_next //ror(shadBitMask, 1) - if (shadBitMask == 1) { - shadBitMask = 128; - shadBitAddr++; + if (shadBitMaskWallCopyTrans == 1) { + shadBitMaskWallCopyTrans = 128; + shadBitAddrWallCopyTrans++; } else { - shadBitMask /= 2; + shadBitMaskWallCopyTrans /= 2; } //okok blackHeroXWall++; @@ -535,28 +530,27 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX + backgroundDiff, _shadDrawY + diffY); } } + } + //krap2 + //pop shadBitAddr + //pop shadBitMask + //pop esi + if (shadDirection != 0) { + shadWallDestAddr -= kScreenWidth; + shadWallBitAddr -= kMaxPicWidth / 8; + shadWallPosY--; } else { - //krap2 - //pop shadBitAddr - //pop shadBitMask - //pop esi - if (shadDirection != 0) { - shadWallDestAddr -= kScreenWidth; - shadWallBitAddr -= kMaxPicWidth / 8; - shadWallPosY--; - } else { - //down_direct - shadWallDestAddr += kScreenWidth; - shadWallBitAddr += kMaxPicWidth / 8; - shadWallPosY++; - } - //compareagain - if (shadWallPosY < shadMinY) { - shadMinY = shadWallPosY; - } - if (shadWallPosY > shadMaxY) { - shadMaxY = shadWallPosY; - } + //down_direct + shadWallDestAddr += kScreenWidth; + shadWallBitAddr += kMaxPicWidth / 8; + shadWallPosY++; + } + //compareagain + if (shadWallPosY < shadMinY) { + shadMinY = shadWallPosY; + } + if (shadWallPosY > shadMaxY) { + shadMaxY = shadWallPosY; } } */ From fd326107406be347e52e2a9611563a30915c2737 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 16 May 2014 03:21:13 +0200 Subject: [PATCH 094/374] PRINCE: showHeroShadow - drawing shadow on walls working --- engines/prince/hero.cpp | 64 +++++++++++------------------------------ 1 file changed, 17 insertions(+), 47 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 302bd01064a3..8de072d6524f 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -356,9 +356,9 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { } } } else { - //skip_line //? - // no draw_line1 - //no ct_loop? + //skip_line + //no draw_line1 + //no ct_loop } } else { //x1_ok @@ -409,17 +409,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { break; } //line_y_ok_2: - // push esi - background - // push ecx - ct_loop - byte *lineDestAddr = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX, _shadDrawY + diffY); - // edi = eax -> needed in copy trans - // push shadBitMask - int lineBitMask = shadBitMask; // before copy_trans ct_loop - // push shadBitAddr; - int lineBitAddr = shadBitAddr; // before copy_trans ct_loop - //copy_trans - //push eax, ebx, edx, ebp int shadWDFlag = 0; int shadZoomX = _scaleValue; int backgroundDiff = 0; @@ -465,40 +455,26 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { //byebyebye if (shadWallDown == 0 && shadWDFlag != 0) { shadWallDown = shadPosX; - shadWallBitAddr = lineBitAddr; - shadWallDestAddr = lineDestAddr; - shadWallBitMask = lineBitMask; + shadWallBitAddr = shadBitAddr; + shadWallDestAddr = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX, _shadDrawY + diffY); + shadWallBitMask = shadBitMask; shadWallPosY = shadPosY; shadWallSkipX = shadSkipX; shadWallModulo = sprModulo; } - /* //byebye - //pop ebp edx ebx eax - //pop shadBitAddr - //pop shadBitMask - //pop ecx - ct_loop - //pop edi - shadowStart - if (shadDirection != 0 && shadWallDown != 0) { //only when shadow draw up - //push esi - //esi = edi; // shadowStart - //push shadBitMask - //push shadBitAddr + if (shadDirection != 0 && shadWallDown != 0) { int shadBitMaskWallCopyTrans = shadWallBitMask; int shadBitAddrWallCopyTrans = shadWallBitAddr; - //eax = shadWallSkipX; -not needed in wall_copy_trans - background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX, _shadDrawY + diffY); //edi = shadWallDestAddr; - shadowStart = (byte *)makeShadow->getBasePtr(shadWallSkipX, blackHeroY); //esi += shadWallSkipX; + //background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX, _shadDrawY + diffY); + background = shadWallDestAddr; + shadowStart = (byte *)makeShadow->getBasePtr(shadWallSkipX, blackHeroY); if (ct_loop > shadWallSkipX && ct_loop - shadWallSkipX > shadWallModulo) { //WALL_copy_trans - //push eax, ebx, edx, ebp - //ebx = SprShadow; - //ebp = ShadBitAddr; - //ah = ShadBitMask; shadWDFlag = 0; int shadZoomX = _scaleValue; - int backgroundDiff = 0; + int backgroundDiffWall = 0; int blackHeroXWall = 0; //ct_loop: for (int j = 0; j < ct_loop; j++) { @@ -510,9 +486,8 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { } else { //point_ok: if (*shadowStart == kShadowColor) { - if (shadBitMaskWallCopyTrans != _shadowBitmap[shadBitAddrWallCopyTrans + kShadowBitmapSize]) { - //*background = *(sprShadow + *background); - *background = 50; + if ((shadBitMaskWallCopyTrans & _shadowBitmap[shadBitAddrWallCopyTrans + kShadowBitmapSize]) != 0) { + *background = *(sprShadow + *background); } } //ct_next @@ -526,21 +501,19 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { //okok blackHeroXWall++; shadowStart = (byte *)makeShadow->getBasePtr(shadWallSkipX + blackHeroXWall, blackHeroY); - backgroundDiff++; - background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX + backgroundDiff, _shadDrawY + diffY); + backgroundDiffWall++; + //background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX + backgroundDiffWall, _shadDrawY + diffY); + background = shadWallDestAddr + backgroundDiffWall; } } } //krap2 - //pop shadBitAddr - //pop shadBitMask - //pop esi if (shadDirection != 0) { shadWallDestAddr -= kScreenWidth; shadWallBitAddr -= kMaxPicWidth / 8; shadWallPosY--; } else { - //down_direct + //down_direct - when?? shadWallDestAddr += kScreenWidth; shadWallBitAddr += kMaxPicWidth / 8; shadWallPosY++; @@ -553,11 +526,8 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { shadMaxY = shadWallPosY; } } - */ } //skip_line - //add esi, sprWidth - don't need it? - //next_line if (*(shadowLineStart + 2) < *(shadowLineStart - 2)) { //minus_y From d5f2b97c3e291832317e950773997e3f206b8975 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 16 May 2014 04:29:08 +0200 Subject: [PATCH 095/374] PRINCE: showHeroShadow - code clean up --- engines/prince/hero.cpp | 146 ++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 96 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 8de072d6524f..e6ddc1fed7c3 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -263,7 +263,6 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { shadDirection = 0; } - int shadWallDown = 0; _shadLineLen = 0; Graphics::drawLine(_lightX, _lightY, destX, destY, 0, &plot, this); @@ -273,12 +272,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { _shadDrawY = destY - _vm->_picWindowY; int shadPosX = _shadDrawX; - int shadMinX = _shadDrawX; - int shadMaxX = _shadDrawX; - int shadPosY = _shadDrawY; - int shadMinY = _shadDrawY; - int shadMaxY = _shadDrawY; int shadBitAddr = destY * kMaxPicWidth / 8 + destX / 8; int shadBitMask = 128 >> (destX % 8); @@ -288,17 +282,18 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { int diffX = 0; int diffY = 0; - int blackHeroX = 0; - int blackHeroY = _frameYSize - 1; + int shadowHeroX = 0; + int shadowHeroY = _frameYSize - 1; int shadLastY = 0; - byte *shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY); // first pixel from last row of black hero + byte *shadowHero = (byte *)makeShadow->getBasePtr(shadowHeroX, shadowHeroY); // first pixel from last row of shadow hero byte *background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX, _shadDrawY); // pixel of background where shadow sprite starts // banked2 byte *shadowLineStart = _shadowLine + 8; + int shadWallDown = 0; int shadWallBitAddr = 0; int shadWallBitMask = 0; byte *shadWallDestAddr = 0; @@ -307,58 +302,55 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { int shadWallModulo = 0; // linear_loop - for(int i = 0; i < _frameYSize; i++) { + for (int i = 0; i < _frameYSize; i++) { int shadSkipX = 0; int ct_loop = 0; int sprModulo = 0; - int ebxOnStack; + int j; //retry_line: - for (ebxOnStack = _frameYSize - i; ebxOnStack > 0; ebxOnStack--) { + for (j = _frameYSize - i; j > 0; j--) { shadZoomY -= 100; if (shadZoomY < 0 && _scaleValue != 10000) { shadZoomY += _scaleValue; - blackHeroY--; - if (blackHeroY < 0) { + shadowHeroY--; + if (shadowHeroY < 0) { break; } - shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY); + shadowHero = (byte *)makeShadow->getBasePtr(shadowHeroX, shadowHeroY); } else { - break; //to line_y_ok + break; } } - if(ebxOnStack == 0) { + if(j == 0) { break; } - if (blackHeroY < 0) { + if (shadowHeroY < 0) { break; } //line_y_ok if (shadLastY != shadPosY && shadPosY >= 0 && shadPosY < 480 && shadPosX < 640) { shadLastY = shadPosY; - if (shadPosX < 0) { //when it happens? + if (shadPosX < 0) { shadSkipX = -1 * shadPosX; background += shadSkipX; if (_frameXSize > shadSkipX) { - shadowStart += shadSkipX; + shadowHero += shadSkipX; shadBitAddr += shadSkipX / 8; - int ebp16844 = shadSkipX % 8; - if (ebp16844 != 0) { + if ((shadSkipX % 8) != 0) { //loop_rotate: - for (int k = 0; k < ebp16844; k++) { - //ror(shadBitMask, 1) + for (int a = 0; a < (shadSkipX % 8); a++) { if (shadBitMask == 1) { shadBitMask = 128; shadBitAddr++; } else { - shadBitMask /= 2; + shadBitMask = shadBitMask >> 1; } } } } else { //skip_line - //no draw_line1 - //no ct_loop + //test it } } else { //x1_ok @@ -371,46 +363,30 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { } } //draw_line1 - if (shadPosX < shadMinX) { - shadMinX = shadPosX; - } - //bigger_x - if (shadPosX + _frameXSize > shadMaxX) { - shadMaxX = shadPosX + _frameXSize; - } - //smaller_x - if (shadPosY < shadMinY) { - shadMinY = shadPosY; - } - //bigger_y - if (shadPosY > shadMaxY) { - shadMaxY = shadPosY; - } - //smaller_y //retry_line2 - int ebxOnStack2; - for (ebxOnStack2 = ebxOnStack; ebxOnStack2 > 0; ebxOnStack2--) { + int k; + for (k = j; k > 0; k--) { shadZoomY2 -= 100; if (shadZoomY2 < 0 && _shadScaleValue != 10000) { shadZoomY2 += _shadScaleValue; - blackHeroY--; - if (blackHeroY < 0) { + shadowHeroY--; + if (shadowHeroY < 0) { break; } - shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY); + shadowHero = (byte *)makeShadow->getBasePtr(shadowHeroX, shadowHeroY); } else { - break; //to line_y_ok_2 + break; } } - if (blackHeroY < 0) { + if (shadowHeroY < 0) { break; } - if (ebxOnStack2 == 0) { + if (k == 0) { break; } //line_y_ok_2: //copy_trans - int shadWDFlag = 0; + bool shadWDFlag = false; int shadZoomX = _scaleValue; int backgroundDiff = 0; int shadBitMaskCopyTrans = shadBitMask; @@ -419,15 +395,13 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { for (int j = 0; j < ct_loop; j++) { shadZoomX -= 100; if (shadZoomX < 0 && _scaleValue != 10000) { - blackHeroX++; - shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY); shadZoomX += _scaleValue; } else { - if (*shadowStart == kShadowColor) { + if (*shadowHero == kShadowColor) { if ((shadBitMaskCopyTrans & _shadowBitmap[shadBitAddrCopyTrans]) != 0) { if (shadWallDown == 0) { if ((shadBitMaskCopyTrans & _shadowBitmap[shadBitAddrCopyTrans + kShadowBitmapSize]) != 0) { - shadWDFlag = 1; + shadWDFlag = true; //shadow *background = *(sprShadow + *background); } @@ -438,22 +412,21 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { } } //ct_next - //ror(shadBitMask, 1) if (shadBitMaskCopyTrans == 1) { shadBitMaskCopyTrans = 128; shadBitAddrCopyTrans++; } else { - shadBitMaskCopyTrans /= 2; + shadBitMaskCopyTrans = shadBitMaskCopyTrans >> 1; } //okok - blackHeroX++; - shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY); backgroundDiff++; background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX + backgroundDiff, _shadDrawY + diffY); } + shadowHeroX++; + shadowHero = (byte *)makeShadow->getBasePtr(shadowHeroX, shadowHeroY); } //byebyebye - if (shadWallDown == 0 && shadWDFlag != 0) { + if (shadWallDown == 0 && shadWDFlag == true) { shadWallDown = shadPosX; shadWallBitAddr = shadBitAddr; shadWallDestAddr = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX, _shadDrawY + diffY); @@ -466,65 +439,46 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { if (shadDirection != 0 && shadWallDown != 0) { int shadBitMaskWallCopyTrans = shadWallBitMask; int shadBitAddrWallCopyTrans = shadWallBitAddr; - //background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX, _shadDrawY + diffY); background = shadWallDestAddr; - shadowStart = (byte *)makeShadow->getBasePtr(shadWallSkipX, blackHeroY); + shadowHero = (byte *)makeShadow->getBasePtr(shadWallSkipX, shadowHeroY); if (ct_loop > shadWallSkipX && ct_loop - shadWallSkipX > shadWallModulo) { //WALL_copy_trans - shadWDFlag = 0; + shadWDFlag = false; int shadZoomX = _scaleValue; int backgroundDiffWall = 0; - int blackHeroXWall = 0; + int shadowHeroXWall = 0; //ct_loop: for (int j = 0; j < ct_loop; j++) { shadZoomX -= 100; if (shadZoomX < 0 && _scaleValue != 10000) { - blackHeroXWall++; - shadowStart = (byte *)makeShadow->getBasePtr(shadWallSkipX + blackHeroXWall, blackHeroY); shadZoomX += _scaleValue; } else { //point_ok: - if (*shadowStart == kShadowColor) { + if (*shadowHero == kShadowColor) { if ((shadBitMaskWallCopyTrans & _shadowBitmap[shadBitAddrWallCopyTrans + kShadowBitmapSize]) != 0) { *background = *(sprShadow + *background); } } //ct_next - //ror(shadBitMask, 1) if (shadBitMaskWallCopyTrans == 1) { shadBitMaskWallCopyTrans = 128; shadBitAddrWallCopyTrans++; } else { - shadBitMaskWallCopyTrans /= 2; + shadBitMaskWallCopyTrans= shadBitMaskWallCopyTrans >> 1; } //okok - blackHeroXWall++; - shadowStart = (byte *)makeShadow->getBasePtr(shadWallSkipX + blackHeroXWall, blackHeroY); backgroundDiffWall++; - //background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX + backgroundDiffWall, _shadDrawY + diffY); background = shadWallDestAddr + backgroundDiffWall; } + shadowHeroXWall++; + shadowHero = (byte *)makeShadow->getBasePtr(shadWallSkipX + shadowHeroXWall, shadowHeroY); } } //krap2 - if (shadDirection != 0) { - shadWallDestAddr -= kScreenWidth; - shadWallBitAddr -= kMaxPicWidth / 8; - shadWallPosY--; - } else { - //down_direct - when?? - shadWallDestAddr += kScreenWidth; - shadWallBitAddr += kMaxPicWidth / 8; - shadWallPosY++; - } - //compareagain - if (shadWallPosY < shadMinY) { - shadMinY = shadWallPosY; - } - if (shadWallPosY > shadMaxY) { - shadMaxY = shadWallPosY; - } + shadWallDestAddr -= kScreenWidth; + shadWallBitAddr -= kMaxPicWidth / 8; + shadWallPosY--; } } //skip_line @@ -548,7 +502,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { shadBitMask = 1; shadBitAddr--; } else { - shadBitMask *= 2; + shadBitMask = shadBitMask << 1; } diffX--; } else if (*shadowLineStart > *(shadowLineStart - 4)) { @@ -558,19 +512,19 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { shadBitMask = 128; shadBitAddr++; } else { - shadBitMask /= 2; + shadBitMask = shadBitMask >> 1; } diffX++; } //no_change_x shadowLineStart += 4; - blackHeroY--; - if (blackHeroY < 0) { + shadowHeroY--; + if (shadowHeroY < 0) { break; } - blackHeroX = 0; + shadowHeroX = 0; background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX, _shadDrawY + diffY); - shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY); + shadowHero = (byte *)makeShadow->getBasePtr(shadowHeroX, shadowHeroY); } //koniec_bajki } From 3d590627eda86a56080bbb55f5b51c19b55cd3a1 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 17 May 2014 23:25:31 +0200 Subject: [PATCH 096/374] PRINCE: Room struct implementation and objects drawing fix --- engines/prince/object.cpp | 11 +++++++---- engines/prince/object.h | 4 +--- engines/prince/prince.cpp | 28 +++++++++++++++++----------- engines/prince/prince.h | 3 ++- engines/prince/script.cpp | 36 +++++++++++++++++++++++++++++++++--- engines/prince/script.h | 18 +++++++++++++++++- 6 files changed, 77 insertions(+), 23 deletions(-) diff --git a/engines/prince/object.cpp b/engines/prince/object.cpp index 4148cdf854a5..9386eaa4963d 100644 --- a/engines/prince/object.cpp +++ b/engines/prince/object.cpp @@ -32,7 +32,7 @@ namespace Prince { -Object::Object() : _surface(NULL), _x(0), _y(0), _z(0) { +Object::Object() : _surface(NULL), _x(0), _y(0), _z(0), _overlay(0) { } Object::~Object() { @@ -45,9 +45,11 @@ Object::~Object() { void Object::loadSurface(Common::SeekableReadStream &stream) { stream.skip(4); - + int width = stream.readUint16LE(); + int height = stream.readUint16LE(); _surface = new Graphics::Surface(); - _surface->create(stream.readUint16LE(), stream.readUint16LE(), Graphics::PixelFormat::createFormatCLUT8()); + _surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); + for (int h = 0; h < _surface->h; ++h) { stream.read(_surface->getBasePtr(0, h), _surface->w); } @@ -71,11 +73,12 @@ bool Object::loadFromStream(Common::SeekableReadStream &stream) { loadSurface(*obStream); delete obStream; + _overlay = stream.readUint16LE(); _z = stream.readUint16LE(); stream.seek(pos + 16); - debug("Object x %d, y %d, z %d", _x, _y, _z); + debug("Object x %d, y %d, z %d overlay %d", _x, _y, _z, _overlay); return true; } diff --git a/engines/prince/object.h b/engines/prince/object.h index 7a3d19e906c3..66f2a725f834 100644 --- a/engines/prince/object.h +++ b/engines/prince/object.h @@ -35,12 +35,10 @@ class Object { bool loadFromStream(Common::SeekableReadStream &stream); const Graphics::Surface *getSurface() const { return _surface; } - + uint16 _x, _y, _z, _overlay; private: void loadSurface(Common::SeekableReadStream &stream); - Graphics::Surface *_surface; - uint16 _x, _y, _z; }; } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 98f9689b9aa2..ea7b9e8b0cc2 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -76,7 +76,7 @@ void PrinceEngine::debugEngine(const char *s, ...) { PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _graph(nullptr), _script(nullptr), _interpreter(nullptr), _flags(nullptr), - _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), + _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), _room(nullptr), _cameraX(0), _newCameraX(0), _frameNr(0), _cursor1(nullptr), _cursor2(nullptr), _font(nullptr), _suitcaseBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0) { @@ -108,6 +108,7 @@ PrinceEngine::~PrinceEngine() { delete _variaTxt; delete[] _talkTxt; delete _graph; + delete _room; for (uint i = 0; i < _objList.size(); i++) { delete _objList[i]; @@ -195,6 +196,8 @@ void PrinceEngine::init() { _roomBmp = new Image::BitmapDecoder(); + _room = new Room(); + _mainHero = new Hero(this, _graph); _secondHero = new Hero(this, _graph); @@ -298,12 +301,6 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _picWindowX = 0; - _mainHero->_lightX = _script->getLightX(_locationNr); - _mainHero->_lightY = _script->getLightY(_locationNr); - _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); - debug("lightX: %d", _mainHero->_lightX); - debug("lightY: %d", _mainHero->_lightY); - _mobList.clear(); Resource::loadResource(_mobList, "mob.lst", false); @@ -316,6 +313,12 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _animList.clear(); Resource::loadResource(_animList, "anim.lst", false); + _mainHero->_lightX = _script->getLightX(_locationNr); + _mainHero->_lightY = _script->getLightY(_locationNr); + _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); + + _room->loadRoom(_script->getRoomOffset(_locationNr)); + _graph->makeShadowTable(70, _graph->_shadowTable70); _graph->makeShadowTable(50, _graph->_shadowTable50); @@ -688,10 +691,13 @@ void PrinceEngine::drawScreen() { } playNextFrame(); - - //if (_objectList) - // _graph->drawTransparent(_objectList->getSurface()); - + /* + if (!_objList.empty()) { + for (int i = 0; i < _objList.size(); i++) { + _graph->drawTransparent(_objList[i]->_x, _objList[i]->_y, _objList[i]->getSurface()); + } + } + */ hotspot(); showTexts(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index dd00abb7886c..5dd039beec6e 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -63,6 +63,7 @@ class MhwanhDecoder; class Font; class Hero; class Animation; +class Room; struct Text { const char *_str; @@ -177,7 +178,7 @@ class PrinceEngine : public Engine { Interpreter *_interpreter; Font *_font; MusicPlayer *_midiPlayer; - + Room *_room; static const uint32 MAX_SAMPLES = 60; Common::SeekableReadStream *_voiceStream[MAX_SAMPLES]; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 78704eb6f877..a0c015d48b54 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -40,6 +40,29 @@ static const uint16 NUM_OPCODES = 144; Room::Room() {} +bool Room::loadRoom(byte *roomData) { + int roomSize = 64; + Common::MemoryReadStream roomStream(roomData, roomSize); + + _mobs = roomStream.readSint32LE(); + _backAnim = roomStream.readSint32LE(); + _obj = roomStream.readSint32LE(); + _nak = roomStream.readSint32LE(); + _itemUse = roomStream.readSint32LE(); + _itemGive = roomStream.readSint32LE(); + _walkTo = roomStream.readSint32LE(); + _examine = roomStream.readSint32LE(); + _pickup = roomStream.readSint32LE(); + _use = roomStream.readSint32LE(); + _pushOpen = roomStream.readSint32LE(); + _pullClose = roomStream.readSint32LE(); + _talk = roomStream.readSint32LE(); + _give = roomStream.readSint32LE(); + + return true; +} + +/* void Room::loadMobs(Common::SeekableReadStream &stream) { debug("loadMobs %d", stream.pos()); static const uint8 MAX_MOBS = 64; @@ -73,7 +96,8 @@ void Room::loadPushOpen(Common::SeekableReadStream &stream) {} void Room::loadPullClose(Common::SeekableReadStream &stream) {} void Room::loadTalk(Common::SeekableReadStream &stream) {} void Room::loadGive(Common::SeekableReadStream &stream) {} - +*/ +/* void Room::nextLoadStep(Common::SeekableReadStream &stream, LoadingStep step) { uint32 offset = stream.readUint32LE(); uint32 pos = stream.pos(); @@ -85,7 +109,8 @@ void Room::nextLoadStep(Common::SeekableReadStream &stream, LoadingStep step) { stream.seek(pos); } - +*/ +/* bool Room::loadFromStream(Common::SeekableReadStream &stream) { uint32 pos = stream.pos(); @@ -109,8 +134,9 @@ bool Room::loadFromStream(Common::SeekableReadStream &stream) { static const uint8 ROOM_ENTRY_SIZE = 64; stream.seek(pos + ROOM_ENTRY_SIZE); - return true;; + return true; } +*/ Script::Script() : _data(nullptr), _dataSize(0) { } @@ -174,6 +200,10 @@ uint32 Script::getStartGameOffset() { return _scriptInfo.startGame; } +uint8 *Script::getRoomOffset(int locationNr) { + return &_data[_scriptInfo.rooms + locationNr * 64]; // Room_Len (64?) +} + InterpreterFlags::InterpreterFlags() { resetAllFlags(); } diff --git a/engines/prince/script.h b/engines/prince/script.h index f21df1d717cb..5a1e49ab2384 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -47,8 +47,24 @@ namespace Detail { class Room { public: Room(); + int _mobs; // mob flag offset + int _backAnim; // offset to array of animation numbers + int _obj; // offset to array of object numbers + int _nak; // offset to array of overlays + int _itemUse; + int _itemGive; + int _walkTo; // offset to array of WALKTO events or 0 + int _examine; // offset to array of EXAMINE events or 0 + int _pickup; + int _use; + int _pushOpen; + int _pullClose; + int _talk; + int _give; + //Room_Pad db 64-(Room_Pad-Room_Mobs) dup (0) ??? bool loadFromStream(Common::SeekableReadStream &stream); + bool loadRoom(byte *roomData); private: @@ -109,11 +125,11 @@ class Script { return Detail::LittleEndianReader(&_data[address]); } - //uint32 getRoomTableOffset(); uint32 getStartGameOffset(); int16 getLightX(int locationNr); int16 getLightY(int locationNr); int32 getShadowScale(int locationNr); + uint8 *getRoomOffset(int locationNr); const char *getString(uint32 offset) { return (const char *)(&_data[offset]); From 55112318a52155f3fef95173380364c647b8ccf2 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 21 May 2014 16:55:48 +0200 Subject: [PATCH 097/374] PRINCE: showHeroShadow - code formatting --- engines/prince/hero.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index e6ddc1fed7c3..ad682cfb1873 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -322,7 +322,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { break; } } - if(j == 0) { + if (j == 0) { break; } if (shadowHeroY < 0) { @@ -344,7 +344,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { shadBitMask = 128; shadBitAddr++; } else { - shadBitMask = shadBitMask >> 1; + shadBitMask >>= 1; } } } @@ -416,7 +416,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { shadBitMaskCopyTrans = 128; shadBitAddrCopyTrans++; } else { - shadBitMaskCopyTrans = shadBitMaskCopyTrans >> 1; + shadBitMaskCopyTrans >>= 1; } //okok backgroundDiff++; @@ -426,7 +426,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { shadowHero = (byte *)makeShadow->getBasePtr(shadowHeroX, shadowHeroY); } //byebyebye - if (shadWallDown == 0 && shadWDFlag == true) { + if (!shadWallDown && shadWDFlag) { shadWallDown = shadPosX; shadWallBitAddr = shadBitAddr; shadWallDestAddr = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX, _shadDrawY + diffY); @@ -465,7 +465,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { shadBitMaskWallCopyTrans = 128; shadBitAddrWallCopyTrans++; } else { - shadBitMaskWallCopyTrans= shadBitMaskWallCopyTrans >> 1; + shadBitMaskWallCopyTrans >>= 1; } //okok backgroundDiffWall++; @@ -502,7 +502,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { shadBitMask = 1; shadBitAddr--; } else { - shadBitMask = shadBitMask << 1; + shadBitMask <<= 1; } diffX--; } else if (*shadowLineStart > *(shadowLineStart - 4)) { @@ -512,7 +512,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { shadBitMask = 128; shadBitAddr++; } else { - shadBitMask = shadBitMask >> 1; + shadBitMask >>= 1; } diffX++; } @@ -526,7 +526,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX, _shadDrawY + diffY); shadowHero = (byte *)makeShadow->getBasePtr(shadowHeroX, shadowHeroY); } - //koniec_bajki + //koniec_bajki - end_of_a_story } makeShadow->free(); delete makeShadow; From 67956c58052e1141b97bb35d3096aa83f08478cd Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 22 May 2014 15:40:02 +0200 Subject: [PATCH 098/374] PRINCE: installBackAnims() - memory offset testing --- engines/prince/script.cpp | 14 +++++++++++++- engines/prince/script.h | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index a0c015d48b54..4c90dd545469 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -46,6 +46,7 @@ bool Room::loadRoom(byte *roomData) { _mobs = roomStream.readSint32LE(); _backAnim = roomStream.readSint32LE(); + debug("%d", _backAnim); _obj = roomStream.readSint32LE(); _nak = roomStream.readSint32LE(); _itemUse = roomStream.readSint32LE(); @@ -201,7 +202,18 @@ uint32 Script::getStartGameOffset() { } uint8 *Script::getRoomOffset(int locationNr) { - return &_data[_scriptInfo.rooms + locationNr * 64]; // Room_Len (64?) + return &_data[_scriptInfo.rooms + locationNr * 64]; +} + +void Script::installBackAnims(int offset) { + // 3760 + int numberOfSubAnimations = READ_UINT32(&_data[offset]); + debug("nrOfSubAnimations: %d", numberOfSubAnimations); + // begin data of animations: + int value1 = READ_UINT32(&_data[offset + 28]); //size of BAS - first anim Nr + debug("firstAnimNr: %d", value1); + int value2 = READ_UINT32(&_data[offset + 28 + 8]); // + size of BASA - next anim Nr + debug("secondAnimNr: %d", value2); } InterpreterFlags::InterpreterFlags() { diff --git a/engines/prince/script.h b/engines/prince/script.h index 5a1e49ab2384..ee8f5a3bf743 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -130,6 +130,7 @@ class Script { int16 getLightY(int locationNr); int32 getShadowScale(int locationNr); uint8 *getRoomOffset(int locationNr); + void installBackAnims(int offset); const char *getString(uint32 offset) { return (const char *)(&_data[offset]); From 277ac367613d166a057c394f2033ab9a54c5206f Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 22 May 2014 19:52:38 +0200 Subject: [PATCH 099/374] PRINCE: installBackAnims implementation, first frames drawing --- engines/prince/animation.cpp | 4 +-- engines/prince/animation.h | 1 - engines/prince/hero.cpp | 2 +- engines/prince/prince.cpp | 36 +++++++++++++++------- engines/prince/prince.h | 56 +++++++++++++++++++++++++++++++-- engines/prince/resource.h | 2 +- engines/prince/script.cpp | 60 ++++++++++++++++++++++++++++++------ engines/prince/script.h | 7 +++-- 8 files changed, 138 insertions(+), 30 deletions(-) diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index e27d556f1b84..c27505735e4e 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -117,10 +117,10 @@ Graphics::Surface *Animation::getFrame(uint frameIndex) { byte *frameData = _data + READ_LE_UINT32(_data + 16 + frameIndex * 4); int16 width = READ_LE_UINT16(frameData + 0); int16 height = READ_LE_UINT16(frameData + 2); - debug("width = %d; height = %d", width, height); + //debug("width = %d; height = %d", width, height); Graphics::Surface *surf = new Graphics::Surface(); surf->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); - debug("frameData %p", frameData); + //debug("frameData %p", frameData); if (READ_BE_UINT32(frameData + 4) == MKTAG('m', 'a', 's', 'm')) { // Compressed Decompressor dec; diff --git a/engines/prince/animation.h b/engines/prince/animation.h index 710f8730ccd8..d5b5938ce070 100644 --- a/engines/prince/animation.h +++ b/engines/prince/animation.h @@ -33,7 +33,6 @@ namespace Prince { class Animation { public: bool loadFromStream(Common::SeekableReadStream &stream); - //const Graphics::Surface *getSurface(uint16 frameIndex); Animation(); Animation(byte *data, uint32 dataSize); diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index ad682cfb1873..215ca6cef013 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -69,7 +69,7 @@ bool Hero::loadAnimSet(uint32 animSetNr) { Animation *anim = NULL; if (animSet[i] != NULL) { anim = new Animation(); - Resource::loadResource(anim, animSet[i]); + Resource::loadResource(anim, animSet[i], true); } _moveSet[i] = anim; } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index ea7b9e8b0cc2..124aed12efb1 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -76,7 +76,7 @@ void PrinceEngine::debugEngine(const char *s, ...) { PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _graph(nullptr), _script(nullptr), _interpreter(nullptr), _flags(nullptr), - _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), _room(nullptr), + _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), _room(nullptr), testAnimNr(0), testAnimFrame(0), _cameraX(0), _newCameraX(0), _frameNr(0), _cursor1(nullptr), _cursor2(nullptr), _font(nullptr), _suitcaseBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0) { @@ -163,25 +163,25 @@ void PrinceEngine::init() { _midiPlayer = new MusicPlayer(this); _font = new Font(); - Resource::loadResource(_font, "font1.raw"); + Resource::loadResource(_font, "font1.raw", true); _suitcaseBmp = new MhwanhDecoder(); - Resource::loadResource(_suitcaseBmp, "walizka"); + Resource::loadResource(_suitcaseBmp, "walizka", true); - _script = new Script(); - Resource::loadResource(_script, "skrypt.dat"); + _script = new Script(this); + Resource::loadResource(_script, "skrypt.dat", true); _flags = new InterpreterFlags(); _interpreter = new Interpreter(this, _script, _flags); _variaTxt = new VariaTxt(); - Resource::loadResource(_variaTxt, "variatxt.dat"); + Resource::loadResource(_variaTxt, "variatxt.dat", true); _cursor1 = new Cursor(); - Resource::loadResource(_cursor1, "mouse1.cur"); + Resource::loadResource(_cursor1, "mouse1.cur", true); _cursor2 = new Cursor(); - Resource::loadResource(_cursor2, "mouse2.cur"); + Resource::loadResource(_cursor2, "mouse2.cur", true); Common::SeekableReadStream *talkTxtStream = SearchMan.createReadStreamForMember("talktxt.dat"); if (!talkTxtStream) { @@ -207,7 +207,7 @@ void PrinceEngine::init() { void PrinceEngine::showLogo() { MhwanhDecoder logo; - if (Resource::loadResource(&logo, "logo.raw")) { + if (Resource::loadResource(&logo, "logo.raw", true)) { _graph->setPalette(logo.getPalette()); _graph->draw(0, 0, logo.getSurface()); _graph->update(); @@ -246,7 +246,6 @@ bool AnimListItem::loadFromStream(Common::SeekableReadStream &stream) { debug("AnimListItem type %d, fileNumber %d, x %d, y %d, flags %d", _type, _fileNumber, _x, _y, _flags); - // 32 byte aligment stream.seek(pos + 32); @@ -288,7 +287,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _midiPlayer->loadMidi(musName); // load location background, replace old one - Resource::loadResource(_roomBmp, "room"); + Resource::loadResource(_roomBmp, "room", true); if (_roomBmp->getSurface()) { _sceneWidth = _roomBmp->getSurface()->w; _graph->setPalette(_roomBmp->getPalette()); @@ -318,6 +317,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); _room->loadRoom(_script->getRoomOffset(_locationNr)); + _script->installBackAnims(_backAnimList, _room->_backAnim); _graph->makeShadowTable(70, _graph->_shadowTable70); _graph->makeShadowTable(50, _graph->_shadowTable50); @@ -524,9 +524,15 @@ void PrinceEngine::keyHandler(Common::Event event) { break; case Common::KEYCODE_LEFT: scrollCameraLeft(32); + if(testAnimNr > 0) { + testAnimNr--; + } + debug("testAnimNr: %d", testAnimNr); break; case Common::KEYCODE_RIGHT: scrollCameraRight(32); + testAnimNr++; + debug("testAnimNr: %d", testAnimNr); break; case Common::KEYCODE_ESCAPE: _flags->setFlagValue(Flags::ESCAPED2, 1); @@ -534,11 +540,15 @@ void PrinceEngine::keyHandler(Common::Event event) { case Common::KEYCODE_UP: _mainHero->_phase++; debugEngine("%d", _mainHero->_phase); + testAnimFrame++; break; case Common::KEYCODE_DOWN: if(_mainHero->_phase > 0) { _mainHero->_phase--; } + if (testAnimFrame > 0) { + testAnimFrame--; + } debugEngine("%d", _mainHero->_phase); break; case Common::KEYCODE_w: @@ -698,6 +708,10 @@ void PrinceEngine::drawScreen() { } } */ + for (int i = 0; i < _backAnimList.size() ; i++) { + _graph->drawTransparent(_backAnimList[i]._x, _backAnimList[i]._y, _backAnimList[i]._animData->getFrame(testAnimFrame)); + } + hotspot(); showTexts(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 5dd039beec6e..d30a9c1f723b 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -86,10 +86,57 @@ struct AnimListItem { uint16 _loopType; uint16 _nextAnim; uint16 _flags; - bool loadFromStream(Common::SeekableReadStream &stream); }; +struct BAS { + int32 _type; // type of sequence + int32 _data; // additional data + int32 _anims; // number of animations + int32 _current; // actual number of animation + int32 _counter; // time counter for animation + int32 _currRelative; //actual relative number for animation + int32 _data2; // additional data for measurements +}; + +struct BASA { + int16 _num; // animation number + int16 _start; // initial frame + int16 _end; // final frame + int16 _pad; // fulfilment to 8 bytes +}; + +// background and normal animation +struct Anim { + int32 _addr; //animation adress + int32 _seq; + int16 _usage; + int16 _state; // state of animation: 0 - turning on, 1 - turning off + int16 _flags; + int16 _frame; // number of phase to show + int16 _lastFrame; // last phase + int16 _loopFrame; // first frame of loop + int16 _showFrame; // actual visible frame of animation + int16 _loopType; // type of loop (0 - last frame; 1 - normal loop (begin from _loopFrame); 2 - no loop; 3 - load new animation) + int16 _nextAnim; // number of next animation to load after actual + int16 _x; + int16 _y; + int32 _currFrame; + int16 _currX; + int16 _currY; + int16 _currW; + int16 _currH; + int16 _packFlag; + int32 _shadow; + int32 _currShadowFrame; + int16 _packShadowFlag; + int32 _shadowBack; + int16 _relX; + int16 _relY; + Animation *_animData; + Animation *_shadowData; +}; + struct DebugChannel { enum Type { @@ -149,6 +196,12 @@ class PrinceEngine : public Engine { uint32 _picWindowY; Image::BitmapDecoder *_roomBmp; + Common::Array _animList; + Common::Array _backAnimList; + + int testAnimNr; + int testAnimFrame; + private: bool playNextFrame(); void keyHandler(Common::Event event); @@ -187,7 +240,6 @@ class PrinceEngine : public Engine { Animation *_zoom; Common::Array _mobList; Common::Array _objList; - Common::Array _animList; bool _flicLooped; diff --git a/engines/prince/resource.h b/engines/prince/resource.h index 2f7e6ba3a800..c30bec0e0961 100644 --- a/engines/prince/resource.h +++ b/engines/prince/resource.h @@ -38,7 +38,7 @@ namespace Resource { } template - bool loadResource(T *resource, const char *resourceName, bool required = true) { + bool loadResource(T *resource, const char *resourceName, bool required) { Common::ScopedPtr stream(SearchMan.createReadStreamForMember(resourceName)); if (!stream) { if (required) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 4c90dd545469..2b05e073f71e 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -27,6 +27,7 @@ #include "prince/font.h" #include "prince/hero.h" #include "prince/resource.h" +#include "prince/animation.h" #include "common/debug.h" #include "common/debug-channels.h" @@ -139,7 +140,7 @@ bool Room::loadFromStream(Common::SeekableReadStream &stream) { } */ -Script::Script() : _data(nullptr), _dataSize(0) { +Script::Script(PrinceEngine *vm) : _vm(vm), _data(nullptr), _dataSize(0) { } Script::~Script() { @@ -205,15 +206,54 @@ uint8 *Script::getRoomOffset(int locationNr) { return &_data[_scriptInfo.rooms + locationNr * 64]; } -void Script::installBackAnims(int offset) { - // 3760 - int numberOfSubAnimations = READ_UINT32(&_data[offset]); - debug("nrOfSubAnimations: %d", numberOfSubAnimations); - // begin data of animations: - int value1 = READ_UINT32(&_data[offset + 28]); //size of BAS - first anim Nr - debug("firstAnimNr: %d", value1); - int value2 = READ_UINT32(&_data[offset + 28 + 8]); // + size of BASA - next anim Nr - debug("secondAnimNr: %d", value2); +void Script::installBackAnims(Common::Array &_backanimList, int offset) { + for (uint i = 0; i < 64; i++) { + int animOffset = READ_UINT32(&_data[offset]); + int animNumber = READ_UINT16(&_data[animOffset + 28]); + Anim newAnim; + if (animOffset != 0) { + const Common::String animName = Common::String::format("AN%02d", animNumber); + const Common::String shadowName = Common::String::format("AN%02dS", animNumber, false); + newAnim._animData = new Animation(); + newAnim._shadowData = new Animation(); + Resource::loadResource(newAnim._animData, animName.c_str(), true); + if (!Resource::loadResource(newAnim._shadowData, shadowName.c_str(), false)) { + newAnim._shadowData = nullptr; + } + newAnim._seq = 0; + newAnim._usage = 0; + newAnim._state = 0; // enabled + if ((_vm->_animList[animNumber]._flags & 4) != 0) { + newAnim._state = 1; + newAnim._frame = _vm->_animList[animNumber]._endPhase; + newAnim._showFrame = _vm->_animList[animNumber]._endPhase; + } else { + newAnim._frame = _vm->_animList[animNumber]._startPhase; + newAnim._showFrame = _vm->_animList[animNumber]._startPhase; + } + newAnim._flags = _vm->_animList[animNumber]._flags; + newAnim._lastFrame = _vm->_animList[animNumber]._endPhase; + newAnim._loopFrame = _vm->_animList[animNumber]._loopPhase; + newAnim._loopType = _vm->_animList[animNumber]._loopType; + newAnim._nextAnim = _vm->_animList[animNumber]._nextAnim; + newAnim._x = _vm->_animList[animNumber]._x; + newAnim._y = _vm->_animList[animNumber]._y; + newAnim._currFrame = 0; + newAnim._currX = _vm->_animList[animNumber]._x; + newAnim._currY = _vm->_animList[animNumber]._y; + newAnim._currW = 0; + newAnim._currH = 0; + newAnim._packFlag = 0; + //newAnim._currShadowFrame = + //newAnim._packShadowFlag = + newAnim._shadowBack = _vm->_animList[animNumber]._type; + //newAnim._relX = + //newAnim._relY = + _backanimList.push_back(newAnim); + debug("animNo: %d", animNumber); + } + offset += 4; + } } InterpreterFlags::InterpreterFlags() { diff --git a/engines/prince/script.h b/engines/prince/script.h index ee8f5a3bf743..31da31dffda3 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -36,6 +36,8 @@ namespace Common { namespace Prince { class PrinceEngine; +class Animation; +struct Anim; namespace Detail { template T LittleEndianReader(void *data); @@ -91,7 +93,7 @@ class Room { class Script { public: - Script(); + Script(PrinceEngine *vm); ~Script(); struct ScriptInfo { @@ -130,13 +132,14 @@ class Script { int16 getLightY(int locationNr); int32 getShadowScale(int locationNr); uint8 *getRoomOffset(int locationNr); - void installBackAnims(int offset); + void installBackAnims(Common::Array &_backanimList, int offset); const char *getString(uint32 offset) { return (const char *)(&_data[offset]); } private: + PrinceEngine *_vm; uint8 *_data; uint32 _dataSize; Common::Array _roomList; From e366a21f18eaf42ed0ff3eab56dc91183842ca53 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 23 May 2014 00:22:31 +0200 Subject: [PATCH 100/374] PRINCE: Memory leak fixes, backAnimList clearing in new location --- engines/prince/prince.cpp | 34 ++++++++++++--- engines/prince/script.cpp | 90 +++++++++++++++++++-------------------- engines/prince/script.h | 1 + 3 files changed, 75 insertions(+), 50 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 124aed12efb1..a575d15820fd 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -115,6 +115,12 @@ PrinceEngine::~PrinceEngine() { } _objList.clear(); + for (uint32 i = 0; i < _backAnimList.size(); i++) { + delete _backAnimList[i]._animData; + delete _backAnimList[i]._shadowData; + } + _backAnimList.clear(); + for (uint i = 0; i < _mainHero->_moveSet.size(); i++) { delete _mainHero->_moveSet[i]; } @@ -317,6 +323,11 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); _room->loadRoom(_script->getRoomOffset(_locationNr)); + for (uint32 i = 0; i < _backAnimList.size(); i++) { + delete _backAnimList[i]._animData; + delete _backAnimList[i]._shadowData; + } + _backAnimList.clear(); _script->installBackAnims(_backAnimList, _room->_backAnim); _graph->makeShadowTable(70, _graph->_shadowTable70); @@ -475,24 +486,33 @@ bool PrinceEngine::loadShadow(byte *shadowBitmap, uint32 dataSize, const char *r Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName1); if (!stream) { + delete stream; return false; } if (stream->read(shadowBitmap, dataSize) != dataSize) { free(shadowBitmap); + delete stream; return false; } - stream = SearchMan.createReadStreamForMember(resourceName2); - if (!stream) { + Common::SeekableReadStream *stream2 = SearchMan.createReadStreamForMember(resourceName2); + if (!stream2) { + delete stream; + delete stream2; return false; } byte *shadowBitmap2 = shadowBitmap + dataSize; - if (stream->read(shadowBitmap2, dataSize) != dataSize) { + if (stream2->read(shadowBitmap2, dataSize) != dataSize) { free(shadowBitmap); + delete stream; + delete stream2; return false; } + + delete stream; + delete stream2; return true; } @@ -700,7 +720,6 @@ void PrinceEngine::drawScreen() { delete mainHeroSurface; } - playNextFrame(); /* if (!_objList.empty()) { for (int i = 0; i < _objList.size(); i++) { @@ -709,9 +728,14 @@ void PrinceEngine::drawScreen() { } */ for (int i = 0; i < _backAnimList.size() ; i++) { - _graph->drawTransparent(_backAnimList[i]._x, _backAnimList[i]._y, _backAnimList[i]._animData->getFrame(testAnimFrame)); + Graphics::Surface *backAnimSurface = _backAnimList[i]._animData->getFrame(testAnimFrame); + _graph->drawTransparent(_backAnimList[i]._x, _backAnimList[i]._y, backAnimSurface); // out of range now - crash .exe + backAnimSurface->free(); + delete backAnimSurface; } + playNextFrame(); + hotspot(); showTexts(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 2b05e073f71e..0dae2b1b5bcf 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -47,7 +47,6 @@ bool Room::loadRoom(byte *roomData) { _mobs = roomStream.readSint32LE(); _backAnim = roomStream.readSint32LE(); - debug("%d", _backAnim); _obj = roomStream.readSint32LE(); _nak = roomStream.readSint32LE(); _itemUse = roomStream.readSint32LE(); @@ -206,52 +205,53 @@ uint8 *Script::getRoomOffset(int locationNr) { return &_data[_scriptInfo.rooms + locationNr * 64]; } +void Script::installSingleBackAnim(Common::Array &_backanimList, int offset) { + int animOffset = READ_UINT32(&_data[offset]); + int animNumber = READ_UINT16(&_data[animOffset + 28]); + Anim newAnim; + if (animOffset != 0) { + const Common::String animName = Common::String::format("AN%02d", animNumber); + const Common::String shadowName = Common::String::format("AN%02dS", animNumber); + newAnim._animData = new Animation(); + newAnim._shadowData = new Animation(); + Resource::loadResource(newAnim._animData, animName.c_str(), true); + if (!Resource::loadResource(newAnim._shadowData, shadowName.c_str(), false)) { + delete newAnim._shadowData; + newAnim._shadowData = nullptr; + } + newAnim._seq = 0; + newAnim._usage = 0; + newAnim._state = 0; // enabled + if ((_vm->_animList[animNumber]._flags & 4) != 0) { + newAnim._state = 1; + newAnim._frame = _vm->_animList[animNumber]._endPhase; + newAnim._showFrame = _vm->_animList[animNumber]._endPhase; + } else { + newAnim._frame = _vm->_animList[animNumber]._startPhase; + newAnim._showFrame = _vm->_animList[animNumber]._startPhase; + } + newAnim._flags = _vm->_animList[animNumber]._flags; + newAnim._lastFrame = _vm->_animList[animNumber]._endPhase; + newAnim._loopFrame = _vm->_animList[animNumber]._loopPhase; + newAnim._loopType = _vm->_animList[animNumber]._loopType; + newAnim._nextAnim = _vm->_animList[animNumber]._nextAnim; + newAnim._x = _vm->_animList[animNumber]._x; + newAnim._y = _vm->_animList[animNumber]._y; + newAnim._currFrame = 0; + newAnim._currX = _vm->_animList[animNumber]._x; + newAnim._currY = _vm->_animList[animNumber]._y; + newAnim._currW = 0; + newAnim._currH = 0; + newAnim._packFlag = 0; + newAnim._shadowBack = _vm->_animList[animNumber]._type; + _backanimList.push_back(newAnim); + //debug("animNo: %d", animNumber); + } +} + void Script::installBackAnims(Common::Array &_backanimList, int offset) { for (uint i = 0; i < 64; i++) { - int animOffset = READ_UINT32(&_data[offset]); - int animNumber = READ_UINT16(&_data[animOffset + 28]); - Anim newAnim; - if (animOffset != 0) { - const Common::String animName = Common::String::format("AN%02d", animNumber); - const Common::String shadowName = Common::String::format("AN%02dS", animNumber, false); - newAnim._animData = new Animation(); - newAnim._shadowData = new Animation(); - Resource::loadResource(newAnim._animData, animName.c_str(), true); - if (!Resource::loadResource(newAnim._shadowData, shadowName.c_str(), false)) { - newAnim._shadowData = nullptr; - } - newAnim._seq = 0; - newAnim._usage = 0; - newAnim._state = 0; // enabled - if ((_vm->_animList[animNumber]._flags & 4) != 0) { - newAnim._state = 1; - newAnim._frame = _vm->_animList[animNumber]._endPhase; - newAnim._showFrame = _vm->_animList[animNumber]._endPhase; - } else { - newAnim._frame = _vm->_animList[animNumber]._startPhase; - newAnim._showFrame = _vm->_animList[animNumber]._startPhase; - } - newAnim._flags = _vm->_animList[animNumber]._flags; - newAnim._lastFrame = _vm->_animList[animNumber]._endPhase; - newAnim._loopFrame = _vm->_animList[animNumber]._loopPhase; - newAnim._loopType = _vm->_animList[animNumber]._loopType; - newAnim._nextAnim = _vm->_animList[animNumber]._nextAnim; - newAnim._x = _vm->_animList[animNumber]._x; - newAnim._y = _vm->_animList[animNumber]._y; - newAnim._currFrame = 0; - newAnim._currX = _vm->_animList[animNumber]._x; - newAnim._currY = _vm->_animList[animNumber]._y; - newAnim._currW = 0; - newAnim._currH = 0; - newAnim._packFlag = 0; - //newAnim._currShadowFrame = - //newAnim._packShadowFlag = - newAnim._shadowBack = _vm->_animList[animNumber]._type; - //newAnim._relX = - //newAnim._relY = - _backanimList.push_back(newAnim); - debug("animNo: %d", animNumber); - } + installSingleBackAnim(_backanimList, offset); offset += 4; } } diff --git a/engines/prince/script.h b/engines/prince/script.h index 31da31dffda3..b2087c7b12a5 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -133,6 +133,7 @@ class Script { int32 getShadowScale(int locationNr); uint8 *getRoomOffset(int locationNr); void installBackAnims(Common::Array &_backanimList, int offset); + void installSingleBackAnim(Common::Array &_backanimList, int offset); const char *getString(uint32 offset) { return (const char *)(&_data[offset]); From 555672618f270c29a7649bb3615a7ce9e5b3459f Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 23 May 2014 00:48:52 +0200 Subject: [PATCH 101/374] PRINCE: Cleaning up warnings --- engines/prince/archive.cpp | 2 +- engines/prince/debugger.cpp | 6 +++--- engines/prince/hero.cpp | 4 ++-- engines/prince/mob.cpp | 1 + engines/prince/prince.cpp | 4 ++-- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/engines/prince/archive.cpp b/engines/prince/archive.cpp index d1b680c20426..ac00261337a1 100644 --- a/engines/prince/archive.cpp +++ b/engines/prince/archive.cpp @@ -51,7 +51,7 @@ bool PtcArchive::open(const Common::String &filename) { if (!_stream) return false; - uint32 magic = _stream->readUint32LE(); + _stream->readUint32LE(); // magic uint32 fileTableOffset = _stream->readUint32LE() ^ 0x4D4F4B2D; // MOK- uint32 fileTableSize = _stream->readUint32LE() ^ 0x534F4654; // SOFT diff --git a/engines/prince/debugger.cpp b/engines/prince/debugger.cpp index 58c10f1200f0..95df1ec4bf60 100644 --- a/engines/prince/debugger.cpp +++ b/engines/prince/debugger.cpp @@ -78,7 +78,7 @@ bool Debugger::Cmd_SetFlag(int argc, const char **argv) { return true; } - int flagNum = strToInt(argv[1]); + //int flagNum = strToInt(argv[1]); //g_globals->setFlag(flagNum); return true; } @@ -93,7 +93,7 @@ bool Debugger::Cmd_GetFlag(int argc, const char **argv) { return true; } - int flagNum = strToInt(argv[1]); + //int flagNum = strToInt(argv[1]); //DebugPrintf("Value: %d\n", g_globals->getFlag(flagNum)); return true; } @@ -108,7 +108,7 @@ bool Debugger::Cmd_ClearFlag(int argc, const char **argv) { return true; } - int flagNum = strToInt(argv[1]); + //int flagNum = strToInt(argv[1]); //g_globals->clearFlag(flagNum); return true; } diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 215ca6cef013..3e8b2ac5b538 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -392,7 +392,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { int shadBitMaskCopyTrans = shadBitMask; int shadBitAddrCopyTrans = shadBitAddr; //ct_loop: - for (int j = 0; j < ct_loop; j++) { + for (int l = 0; l < ct_loop; l++) { shadZoomX -= 100; if (shadZoomX < 0 && _scaleValue != 10000) { shadZoomX += _scaleValue; @@ -449,7 +449,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { int backgroundDiffWall = 0; int shadowHeroXWall = 0; //ct_loop: - for (int j = 0; j < ct_loop; j++) { + for (int m = 0; m < ct_loop; m++) { shadZoomX -= 100; if (shadZoomX < 0 && _scaleValue != 10000) { shadZoomX += _scaleValue; diff --git a/engines/prince/mob.cpp b/engines/prince/mob.cpp index 1ca9931a590f..7ddb13dc6426 100644 --- a/engines/prince/mob.cpp +++ b/engines/prince/mob.cpp @@ -97,6 +97,7 @@ uint16 Mob::getData(AttrId dataId) { return _examPosition.y; default: assert(false); + return 0; } } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index a575d15820fd..4ef4e886850c 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -115,7 +115,7 @@ PrinceEngine::~PrinceEngine() { } _objList.clear(); - for (uint32 i = 0; i < _backAnimList.size(); i++) { + for (uint i = 0; i < _backAnimList.size(); i++) { delete _backAnimList[i]._animData; delete _backAnimList[i]._shadowData; } @@ -727,7 +727,7 @@ void PrinceEngine::drawScreen() { } } */ - for (int i = 0; i < _backAnimList.size() ; i++) { + for (uint i = 0; i < _backAnimList.size() ; i++) { Graphics::Surface *backAnimSurface = _backAnimList[i]._animData->getFrame(testAnimFrame); _graph->drawTransparent(_backAnimList[i]._x, _backAnimList[i]._y, backAnimSurface); // out of range now - crash .exe backAnimSurface->free(); From eff8b0fd91b190a11370bff8e68110723b27489d Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 23 May 2014 21:24:05 +0200 Subject: [PATCH 102/374] PRINCE: installSingleBackAnim update --- engines/prince/prince.cpp | 24 ++++++-- engines/prince/prince.h | 11 +++- engines/prince/script.cpp | 123 ++++++++++++++++++++++++++------------ engines/prince/script.h | 5 +- 4 files changed, 115 insertions(+), 48 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 4ef4e886850c..844944184fbd 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -115,11 +115,13 @@ PrinceEngine::~PrinceEngine() { } _objList.clear(); + /* for (uint i = 0; i < _backAnimList.size(); i++) { delete _backAnimList[i]._animData; delete _backAnimList[i]._shadowData; } _backAnimList.clear(); + */ for (uint i = 0; i < _mainHero->_moveSet.size(); i++) { delete _mainHero->_moveSet[i]; @@ -323,11 +325,13 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); _room->loadRoom(_script->getRoomOffset(_locationNr)); + /* for (uint32 i = 0; i < _backAnimList.size(); i++) { delete _backAnimList[i]._animData; delete _backAnimList[i]._shadowData; } _backAnimList.clear(); + */ _script->installBackAnims(_backAnimList, _room->_backAnim); _graph->makeShadowTable(70, _graph->_shadowTable70); @@ -696,6 +700,18 @@ void PrinceEngine::showTexts() { } } +void PrinceEngine::showBackAnims() { + int tempAnimNr = 0; + for (uint i = 0; i < _backAnimList.size(); i++) { + if (_backAnimList[i].backAnims[tempAnimNr]._state == 0) { + Graphics::Surface *backAnimSurface = _backAnimList[i].backAnims[tempAnimNr]._animData->getFrame(testAnimFrame); + _graph->drawTransparent(_backAnimList[i].backAnims[tempAnimNr]._x, _backAnimList[i].backAnims[tempAnimNr]._y, backAnimSurface); // out of range now - crash .exe + backAnimSurface->free(); + delete backAnimSurface; + } + } +} + void PrinceEngine::drawScreen() { const Graphics::Surface *roomSurface = _roomBmp->getSurface(); if (roomSurface) { @@ -727,12 +743,8 @@ void PrinceEngine::drawScreen() { } } */ - for (uint i = 0; i < _backAnimList.size() ; i++) { - Graphics::Surface *backAnimSurface = _backAnimList[i]._animData->getFrame(testAnimFrame); - _graph->drawTransparent(_backAnimList[i]._x, _backAnimList[i]._y, backAnimSurface); // out of range now - crash .exe - backAnimSurface->free(); - delete backAnimSurface; - } + + showBackAnims(); playNextFrame(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index d30a9c1f723b..3f8e3f9c7859 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -109,7 +109,7 @@ struct BASA { // background and normal animation struct Anim { int32 _addr; //animation adress - int32 _seq; + //int32 _seq; int16 _usage; int16 _state; // state of animation: 0 - turning on, 1 - turning off int16 _flags; @@ -137,6 +137,11 @@ struct Anim { Animation *_shadowData; }; +struct BackgroundAnim { + BAS _seq; + Common::Array backAnims; +}; + struct DebugChannel { enum Type { @@ -197,7 +202,8 @@ class PrinceEngine : public Engine { Image::BitmapDecoder *_roomBmp; Common::Array _animList; - Common::Array _backAnimList; + //Common::Array _backAnimList; + Common::Array _backAnimList; int testAnimNr; int testAnimFrame; @@ -212,6 +218,7 @@ class PrinceEngine : public Engine { void showTexts(); void init(); void showLogo(); + void showBackAnims(); void makeShadowTable(int brightness); uint32 getTextWidth(const char *s); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 0dae2b1b5bcf..0c52e6a97e00 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -205,51 +205,98 @@ uint8 *Script::getRoomOffset(int locationNr) { return &_data[_scriptInfo.rooms + locationNr * 64]; } -void Script::installSingleBackAnim(Common::Array &_backanimList, int offset) { +void Script::installSingleBackAnim(Common::Array &_backanimList, int offset) { + + BackgroundAnim newBackgroundAnim; + int animOffset = READ_UINT32(&_data[offset]); - int animNumber = READ_UINT16(&_data[animOffset + 28]); - Anim newAnim; + int anims = READ_UINT32(&_data[animOffset + 8]); + + if (anims == 0) { + anims = 1; + } + if (animOffset != 0) { - const Common::String animName = Common::String::format("AN%02d", animNumber); - const Common::String shadowName = Common::String::format("AN%02dS", animNumber); - newAnim._animData = new Animation(); - newAnim._shadowData = new Animation(); - Resource::loadResource(newAnim._animData, animName.c_str(), true); - if (!Resource::loadResource(newAnim._shadowData, shadowName.c_str(), false)) { - delete newAnim._shadowData; - newAnim._shadowData = nullptr; + for (int i = 0; i < anims; i++) { + Anim newAnim; + int animNumber = READ_UINT16(&_data[animOffset + 28 + i * 8]); + const Common::String animName = Common::String::format("AN%02d", animNumber); + const Common::String shadowName = Common::String::format("AN%02dS", animNumber); + newAnim._animData = new Animation(); + newAnim._shadowData = new Animation(); + Resource::loadResource(newAnim._animData, animName.c_str(), true); + if (!Resource::loadResource(newAnim._shadowData, shadowName.c_str(), false)) { + delete newAnim._shadowData; + newAnim._shadowData = nullptr; + } + //newAnim._seq = 0; + newAnim._usage = 0; + newAnim._state = 0; // enabled + if ((_vm->_animList[animNumber]._flags & 4) != 0) { + newAnim._state = 1; + newAnim._frame = _vm->_animList[animNumber]._endPhase; + newAnim._showFrame = _vm->_animList[animNumber]._endPhase; + } else { + newAnim._frame = _vm->_animList[animNumber]._startPhase; + newAnim._showFrame = _vm->_animList[animNumber]._startPhase; + } + newAnim._flags = _vm->_animList[animNumber]._flags; + newAnim._lastFrame = _vm->_animList[animNumber]._endPhase; + newAnim._loopFrame = _vm->_animList[animNumber]._loopPhase; + newAnim._loopType = _vm->_animList[animNumber]._loopType; + newAnim._nextAnim = _vm->_animList[animNumber]._nextAnim; + newAnim._x = _vm->_animList[animNumber]._x; + newAnim._y = _vm->_animList[animNumber]._y; + newAnim._currFrame = 0; + newAnim._currX = _vm->_animList[animNumber]._x; + newAnim._currY = _vm->_animList[animNumber]._y; + newAnim._currW = 0; + newAnim._currH = 0; + newAnim._packFlag = 0; + newAnim._shadowBack = _vm->_animList[animNumber]._type; + newBackgroundAnim.backAnims.push_back(newAnim); + debug("%d - animNo: %d", i, animNumber); } - newAnim._seq = 0; - newAnim._usage = 0; - newAnim._state = 0; // enabled - if ((_vm->_animList[animNumber]._flags & 4) != 0) { - newAnim._state = 1; - newAnim._frame = _vm->_animList[animNumber]._endPhase; - newAnim._showFrame = _vm->_animList[animNumber]._endPhase; - } else { - newAnim._frame = _vm->_animList[animNumber]._startPhase; - newAnim._showFrame = _vm->_animList[animNumber]._startPhase; + + newBackgroundAnim._seq._type = READ_UINT32(&_data[animOffset]); + debug("type: %d", newBackgroundAnim._seq._type); + newBackgroundAnim._seq._data = READ_UINT32(&_data[animOffset + 4]); + debug("data: %d", newBackgroundAnim._seq._data); + newBackgroundAnim._seq._anims = READ_UINT32(&_data[animOffset + 8]); + anims = newBackgroundAnim._seq._anims; + debug("anims: %d", newBackgroundAnim._seq._anims); + //newBackgroundAnim._seq._current = READ_UINT32(&_data[animOffset + 12]); + newBackgroundAnim._seq._current = 0; // nr on list like now or should it be fileNr of anim - check it + debug("current: %d", newBackgroundAnim._seq._current); + //newBackgroundAnim._seq._counter = READ_UINT32(&_data[animOffset + 16]); + newBackgroundAnim._seq._counter = 0; + debug("counter: %d", newBackgroundAnim._seq._counter); + //newBackgroundAnim._seq._currRelative = READ_UINT32(&_data[animOffset + 20]); + newBackgroundAnim._seq._currRelative = 0; + debug("currRelative: %d", newBackgroundAnim._seq._currRelative); + newBackgroundAnim._seq._data2 = READ_UINT32(&_data[animOffset + 24]); + debug("data2: %d", newBackgroundAnim._seq._data2); + + int start = READ_UINT16(&_data[animOffset + 28 + 2]); // BASA_Start of first frame + debug("start: %d", start); + int end = READ_UINT16(&_data[animOffset + 28 + 2]); //BASA_End of first frame + debug("end: %d", end); + + if (start != 65535) { + newBackgroundAnim.backAnims[0]._frame = start; + newBackgroundAnim.backAnims[0]._showFrame = start; + newBackgroundAnim.backAnims[0]._loopFrame = start; + } + + if (end != 65535) { + newBackgroundAnim.backAnims[0]._lastFrame = end; } - newAnim._flags = _vm->_animList[animNumber]._flags; - newAnim._lastFrame = _vm->_animList[animNumber]._endPhase; - newAnim._loopFrame = _vm->_animList[animNumber]._loopPhase; - newAnim._loopType = _vm->_animList[animNumber]._loopType; - newAnim._nextAnim = _vm->_animList[animNumber]._nextAnim; - newAnim._x = _vm->_animList[animNumber]._x; - newAnim._y = _vm->_animList[animNumber]._y; - newAnim._currFrame = 0; - newAnim._currX = _vm->_animList[animNumber]._x; - newAnim._currY = _vm->_animList[animNumber]._y; - newAnim._currW = 0; - newAnim._currH = 0; - newAnim._packFlag = 0; - newAnim._shadowBack = _vm->_animList[animNumber]._type; - _backanimList.push_back(newAnim); - //debug("animNo: %d", animNumber); + + _backanimList.push_back(newBackgroundAnim); } } -void Script::installBackAnims(Common::Array &_backanimList, int offset) { +void Script::installBackAnims(Common::Array &_backanimList, int offset) { for (uint i = 0; i < 64; i++) { installSingleBackAnim(_backanimList, offset); offset += 4; diff --git a/engines/prince/script.h b/engines/prince/script.h index b2087c7b12a5..b05d5ca84d27 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -38,6 +38,7 @@ namespace Prince { class PrinceEngine; class Animation; struct Anim; +struct BackgroundAnim; namespace Detail { template T LittleEndianReader(void *data); @@ -132,8 +133,8 @@ class Script { int16 getLightY(int locationNr); int32 getShadowScale(int locationNr); uint8 *getRoomOffset(int locationNr); - void installBackAnims(Common::Array &_backanimList, int offset); - void installSingleBackAnim(Common::Array &_backanimList, int offset); + void installBackAnims(Common::Array &_backanimList, int offset); + void installSingleBackAnim(Common::Array &_backanimList, int offset); const char *getString(uint32 offset) { return (const char *)(&_data[offset]); From aded3f0e4504e5db32d1cf92412da19e5a6950bd Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 24 May 2014 16:35:16 +0200 Subject: [PATCH 103/374] PRINCE: Begin of showBackAnims --- engines/prince/prince.cpp | 60 ++++++++++++++++++++++++++++++++++++++- engines/prince/prince.h | 8 +++--- engines/prince/script.cpp | 1 + 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 844944184fbd..092fa9315653 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -253,6 +253,7 @@ bool AnimListItem::loadFromStream(Common::SeekableReadStream &stream) { _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); @@ -704,7 +705,64 @@ void PrinceEngine::showBackAnims() { int tempAnimNr = 0; for (uint i = 0; i < _backAnimList.size(); i++) { if (_backAnimList[i].backAnims[tempAnimNr]._state == 0) { - Graphics::Surface *backAnimSurface = _backAnimList[i].backAnims[tempAnimNr]._animData->getFrame(testAnimFrame); + _backAnimList[i]._seq._counter++; + + if (_backAnimList[i]._seq._type == 2) { + if (_backAnimList[i]._seq._currRelative == 0) { + if (_backAnimList[i]._seq._counter >= _backAnimList[i]._seq._data) { + //change_back_anim + } else { + //not_type_2_1 + } + } else { + //not_type_2_1 + } + } + + //not_type_2_1: + if (_backAnimList[i]._seq._type == 3) { + if (_backAnimList[i]._seq._currRelative == 0) { + if (_backAnimList[i]._seq._counter < _backAnimList[i]._seq._data2) { + //empty_frame - do not show anything + } else { + //movzx eax,w [ebx+size BAS+BASA_Num] + //mov d [ebx.BAS_Current],eax + //call SetBackAnim + //inc d [ebx.BAS_CurrRelative] + } + } else { + //not_type_3_1 + } + } + //not_type_3_1: + + //show_bugger + + debug("frame: %d", _backAnimList[i].backAnims[tempAnimNr]._lastFrame); + if (_backAnimList[i].backAnims[tempAnimNr]._frame == _backAnimList[i].backAnims[tempAnimNr]._lastFrame) { + //loop_back_anim + _backAnimList[i].backAnims[tempAnimNr]._frame = _backAnimList[i].backAnims[tempAnimNr]._loopFrame; + + //change_back_anim + if (_backAnimList[i]._seq._type == 0) { + //show_bugger ?? + _backAnimList[i].backAnims[tempAnimNr]._frame++; //?? + //not_end + } else if (_backAnimList[i]._seq._type == 1) { + //repeat_rnd + } + } else { + _backAnimList[i].backAnims[tempAnimNr]._frame++; + //not_end + } + + //not_end: + _backAnimList[i].backAnims[tempAnimNr]._showFrame = _backAnimList[i].backAnims[tempAnimNr]._frame; + //ShowFrameCode + //ShowFrameCodeShadow + + int frame = _backAnimList[i].backAnims[tempAnimNr]._frame; + Graphics::Surface *backAnimSurface = _backAnimList[i].backAnims[tempAnimNr]._animData->getFrame(frame); _graph->drawTransparent(_backAnimList[i].backAnims[tempAnimNr]._x, _backAnimList[i].backAnims[tempAnimNr]._y, backAnimSurface); // out of range now - crash .exe backAnimSurface->free(); delete backAnimSurface; diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 3f8e3f9c7859..efa6033c93ec 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -76,16 +76,16 @@ struct Text { }; struct AnimListItem { - uint16 _type; + uint16 _type; // type of animation - for background anims RND of frame uint16 _fileNumber; - uint16 _startPhase; + uint16 _startPhase; // first phase number uint16 _endPhase; uint16 _loopPhase; int16 _x; int16 _y; uint16 _loopType; - uint16 _nextAnim; - uint16 _flags; + uint16 _nextAnim; // number of animation to do for loop = 3 + uint16 _flags; // byte 0 - draw overlays, byte 1 - draw in front of overlay, byte 2 - load but turn off drawing bool loadFromStream(Common::SeekableReadStream &stream); }; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 0c52e6a97e00..16439dd604a9 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -242,6 +242,7 @@ void Script::installSingleBackAnim(Common::Array &_backanimList, } newAnim._flags = _vm->_animList[animNumber]._flags; newAnim._lastFrame = _vm->_animList[animNumber]._endPhase; + debug("lastFrame: %d", _vm->_animList[animNumber]._endPhase); newAnim._loopFrame = _vm->_animList[animNumber]._loopPhase; newAnim._loopType = _vm->_animList[animNumber]._loopType; newAnim._nextAnim = _vm->_animList[animNumber]._nextAnim; From c9ed2074b5e7964e52b494f135767d7b8bc96c8b Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 26 May 2014 19:16:31 +0200 Subject: [PATCH 104/374] PRINCE: ShowBackAnim progress - still with random crashes --- engines/prince/hero.cpp | 4 +- engines/prince/hero.h | 1 - engines/prince/prince.cpp | 153 +++++++++++++++++++++++++++++++------- engines/prince/prince.h | 4 + engines/prince/script.cpp | 19 +++-- 5 files changed, 144 insertions(+), 37 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 3e8b2ac5b538..a91ef9460255 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -35,7 +35,7 @@ Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph) , _number(0), _visible(false), _state(MOVE), _middleX(0), _middleY(0) , _boreNum(1), _currHeight(0), _moveDelay(0), _shadMinus(0), _moveSetType(0) , _lastDirection(DOWN), _destDirection(DOWN), _talkTime(0), _boredomTime(0), _phase(0) - , _specAnim(0), _drawX(0), _drawY(0), _randomSource("prince"), _zoomFactor(0), _scaleValue(0) + , _specAnim(0), _drawX(0), _drawY(0), _zoomFactor(0), _scaleValue(0) , _shadZoomFactor(0), _shadScaleValue(0), _shadLineLen(0), _shadDrawX(0), _shadDrawY(0) , _frameXSize(0), _frameYSize(0), _scaledFrameXSize(0), _scaledFrameYSize(0) { @@ -695,7 +695,7 @@ void Hero::showHero() { break; } if (_phase == _moveSet[_moveSetType]->getFrameCount() - 1) { - _boreNum = _randomSource.getRandomNumber(1); // rand one of two 'bored' animation + _boreNum = _vm->_randomSource.getRandomNumber(1); // rand one of two 'bored' animation _lastDirection = DOWN; _state = STAY; } diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 7fe3218b91a6..0b3935637d72 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -101,7 +101,6 @@ class Hero { Hero(PrinceEngine *vm, GraphicsMan *graph); ~Hero(); - Common::RandomSource _randomSource; bool loadAnimSet(uint32 heroAnimNumber); Graphics::Surface *getSurface(); diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 092fa9315653..4d221fdfeb3d 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -78,7 +78,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) Engine(syst), _gameDescription(gameDesc), _graph(nullptr), _script(nullptr), _interpreter(nullptr), _flags(nullptr), _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), _room(nullptr), testAnimNr(0), testAnimFrame(0), _cameraX(0), _newCameraX(0), _frameNr(0), _cursor1(nullptr), _cursor2(nullptr), _font(nullptr), - _suitcaseBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0) { + _suitcaseBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0), _randomSource("prince") { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -244,7 +244,8 @@ bool AnimListItem::loadFromStream(Common::SeekableReadStream &stream) { _type = type; _fileNumber = stream.readUint16LE(); _startPhase = stream.readUint16LE(); - _endPhase = stream.readUint16LE(); + //_endPhase = stream.readUint16LE(); + _endPhase = stream.readSint16LE(); _loopPhase = stream.readUint16LE(); _x = stream.readSint16LE(); _y = stream.readSint16LE(); @@ -333,6 +334,8 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { } _backAnimList.clear(); */ + _backAnimList.clear(); + _script->installBackAnims(_backAnimList, _room->_backAnim); _graph->makeShadowTable(70, _graph->_shadowTable70); @@ -701,21 +704,22 @@ void PrinceEngine::showTexts() { } } +void PrinceEngine::setBackAnim() { + +} + void PrinceEngine::showBackAnims() { - int tempAnimNr = 0; + for (uint i = 0; i < _backAnimList.size(); i++) { - if (_backAnimList[i].backAnims[tempAnimNr]._state == 0) { + int activeSubAnim = _backAnimList[i]._seq._currRelative; + if (_backAnimList[i].backAnims[activeSubAnim]._state == 0) { _backAnimList[i]._seq._counter++; if (_backAnimList[i]._seq._type == 2) { if (_backAnimList[i]._seq._currRelative == 0) { if (_backAnimList[i]._seq._counter >= _backAnimList[i]._seq._data) { //change_back_anim - } else { - //not_type_2_1 } - } else { - //not_type_2_1 } } @@ -725,45 +729,140 @@ void PrinceEngine::showBackAnims() { if (_backAnimList[i]._seq._counter < _backAnimList[i]._seq._data2) { //empty_frame - do not show anything } else { - //movzx eax,w [ebx+size BAS+BASA_Num] - //mov d [ebx.BAS_Current],eax - //call SetBackAnim - //inc d [ebx.BAS_CurrRelative] + _backAnimList[i]._seq._current++; // or change to nr of animation + _backAnimList[i]._seq._currRelative++; + //SetBackAnim + int start = _backAnimList[i].backAnims[activeSubAnim]._basaData._start; + if (start != -1) { + _backAnimList[i].backAnims[activeSubAnim]._frame = start; + _backAnimList[i].backAnims[activeSubAnim]._showFrame = start; + _backAnimList[i].backAnims[activeSubAnim]._loopFrame = start; + } + int end = _backAnimList[i].backAnims[activeSubAnim]._basaData._end; + if (end != -1) { + _backAnimList[i].backAnims[activeSubAnim]._lastFrame = end; + } + _backAnimList[i]._seq._counter = 0; + _backAnimList[i].backAnims[activeSubAnim]._state = 0; } - } else { - //not_type_3_1 } } //not_type_3_1: - //show_bugger - - debug("frame: %d", _backAnimList[i].backAnims[tempAnimNr]._lastFrame); - if (_backAnimList[i].backAnims[tempAnimNr]._frame == _backAnimList[i].backAnims[tempAnimNr]._lastFrame) { + if (_backAnimList[i].backAnims[activeSubAnim]._frame == _backAnimList[i].backAnims[activeSubAnim]._lastFrame) { //loop_back_anim - _backAnimList[i].backAnims[tempAnimNr]._frame = _backAnimList[i].backAnims[tempAnimNr]._loopFrame; - + _backAnimList[i].backAnims[activeSubAnim]._frame = _backAnimList[i].backAnims[activeSubAnim]._loopFrame; + //debug("loopFrame: %d", _backAnimList[i].backAnims[tempAnimNr]._loopFrame); //change_back_anim if (_backAnimList[i]._seq._type == 0) { - //show_bugger ?? - _backAnimList[i].backAnims[tempAnimNr]._frame++; //?? + //show_bugger + _backAnimList[i].backAnims[activeSubAnim]._frame++; //not_end } else if (_backAnimList[i]._seq._type == 1) { //repeat_rnd + if (_backAnimList[i]._seq._anims <= 1) { + //show_bugger + _backAnimList[i].backAnims[activeSubAnim]._frame++; + //not_end + } else { + int rnd; + do { + rnd = _randomSource.getRandomNumber(_backAnimList[i]._seq._anims - 1); + } while (rnd == _backAnimList[i]._seq._currRelative); + //debug("rnd: %d", rnd); + _backAnimList[i]._seq._currRelative = rnd; + _backAnimList[i]._seq._current = rnd; // or nr of animation from lst + activeSubAnim = rnd; + //only_1_type_1: + //SetBackAnim + int start = _backAnimList[i].backAnims[activeSubAnim]._basaData._start; + if (start != -1) { + _backAnimList[i].backAnims[activeSubAnim]._frame = start; + _backAnimList[i].backAnims[activeSubAnim]._showFrame = start; + _backAnimList[i].backAnims[activeSubAnim]._loopFrame = start; + } + int end = _backAnimList[i].backAnims[activeSubAnim]._basaData._end; + if (end != -1) { + _backAnimList[i].backAnims[activeSubAnim]._lastFrame = end; + } + _backAnimList[i]._seq._counter = 0; + _backAnimList[i].backAnims[activeSubAnim]._state = 0; + //show_bugger + _backAnimList[i].backAnims[activeSubAnim]._frame++; + //not_end + } + } else if (_backAnimList[i]._seq._type == 2) { + //not_type_1 + if (_backAnimList[i]._seq._currRelative == 0) { + //zero + if (_backAnimList[i]._seq._counter < _backAnimList[i]._seq._data) { + //show_bugger + _backAnimList[i].backAnims[activeSubAnim]._frame++; + //not_end + } else { + if (_backAnimList[i]._seq._anims > 2) { //?? + int rnd = _randomSource.getRandomNumber(_backAnimList[i]._seq._anims - 2); //? + rnd++; + //debug("rnd: %d", rnd); + _backAnimList[i]._seq._currRelative = rnd; + _backAnimList[i]._seq._current = rnd; // or nr of animation from lst + activeSubAnim = rnd; + } + //only_1_type_2 + } + } else { + _backAnimList[i]._seq._currRelative = 0; + _backAnimList[i]._seq._current = 0; // or nr of animation from lst + activeSubAnim = 0; + //only_1_type_1 + } + //SetBackAnim + int start = _backAnimList[i].backAnims[activeSubAnim]._basaData._start; + if (start != -1) { + _backAnimList[i].backAnims[activeSubAnim]._frame = start; + _backAnimList[i].backAnims[activeSubAnim]._showFrame = start; + _backAnimList[i].backAnims[activeSubAnim]._loopFrame = start; + } + int end = _backAnimList[i].backAnims[activeSubAnim]._basaData._end; + if (end != -1) { + _backAnimList[i].backAnims[activeSubAnim]._lastFrame = end; + } + _backAnimList[i]._seq._counter = 0; + _backAnimList[i].backAnims[activeSubAnim]._state = 0; + //show_bugger + _backAnimList[i].backAnims[activeSubAnim]._frame++; + //not_end + } else if (_backAnimList[i]._seq._type == 3) { + //not_type_2 + _backAnimList[i]._seq._currRelative = 0; + //_backAnimList[i]._seq._current = 0; // or nr of animation from lst + _backAnimList[i]._seq._counter = 0; + int rnd = _randomSource.getRandomNumber(_backAnimList[i]._seq._data - 1); //? + _backAnimList[i]._seq._data2 = rnd; + //show_bugger + _backAnimList[i].backAnims[activeSubAnim]._frame++; + //not_end + } else { + //show_bugger + _backAnimList[i].backAnims[activeSubAnim]._frame++; + //not_end } } else { - _backAnimList[i].backAnims[tempAnimNr]._frame++; + _backAnimList[i].backAnims[activeSubAnim]._frame++; //not_end } //not_end: - _backAnimList[i].backAnims[tempAnimNr]._showFrame = _backAnimList[i].backAnims[tempAnimNr]._frame; + _backAnimList[i].backAnims[activeSubAnim]._showFrame = _backAnimList[i].backAnims[activeSubAnim]._frame; //ShowFrameCode //ShowFrameCodeShadow - int frame = _backAnimList[i].backAnims[tempAnimNr]._frame; - Graphics::Surface *backAnimSurface = _backAnimList[i].backAnims[tempAnimNr]._animData->getFrame(frame); - _graph->drawTransparent(_backAnimList[i].backAnims[tempAnimNr]._x, _backAnimList[i].backAnims[tempAnimNr]._y, backAnimSurface); // out of range now - crash .exe + int frame = _backAnimList[i].backAnims[activeSubAnim]._showFrame; + int phaseFrameIndex = _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseFrameIndex(frame); + Graphics::Surface *backAnimSurface = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrame(phaseFrameIndex); + int x = _backAnimList[i].backAnims[activeSubAnim]._x + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetX(frame); + int y = _backAnimList[i].backAnims[activeSubAnim]._y + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetY(frame); + _graph->drawTransparent(x, y, backAnimSurface); // out of range now - crash .exe backAnimSurface->free(); delete backAnimSurface; } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index efa6033c93ec..356c4dd9609d 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -108,6 +108,7 @@ struct BASA { // background and normal animation struct Anim { + BASA _basaData; int32 _addr; //animation adress //int32 _seq; int16 _usage; @@ -205,6 +206,8 @@ class PrinceEngine : public Engine { //Common::Array _backAnimList; Common::Array _backAnimList; + Common::RandomSource _randomSource; + int testAnimNr; int testAnimFrame; @@ -219,6 +222,7 @@ class PrinceEngine : public Engine { void init(); void showLogo(); void showBackAnims(); + void setBackAnim(); void makeShadowTable(int brightness); uint32 getTextWidth(const char *s); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 16439dd604a9..d87cd8b9e26c 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -219,7 +219,12 @@ void Script::installSingleBackAnim(Common::Array &_backanimList, if (animOffset != 0) { for (int i = 0; i < anims; i++) { Anim newAnim; - int animNumber = READ_UINT16(&_data[animOffset + 28 + i * 8]); + newAnim._basaData._num = READ_UINT16(&_data[animOffset + 28 + i * 8]); + newAnim._basaData._start = READ_UINT16(&_data[animOffset + 28 + i * 8 + 2]); + newAnim._basaData._end = READ_UINT16(&_data[animOffset + 28 + i * 8 + 4]); + debug("start1: %d", newAnim._basaData._start); + debug("end1: %d", newAnim._basaData._end); + int animNumber = newAnim._basaData._num; const Common::String animName = Common::String::format("AN%02d", animNumber); const Common::String shadowName = Common::String::format("AN%02dS", animNumber); newAnim._animData = new Animation(); @@ -278,18 +283,18 @@ void Script::installSingleBackAnim(Common::Array &_backanimList, newBackgroundAnim._seq._data2 = READ_UINT32(&_data[animOffset + 24]); debug("data2: %d", newBackgroundAnim._seq._data2); - int start = READ_UINT16(&_data[animOffset + 28 + 2]); // BASA_Start of first frame - debug("start: %d", start); - int end = READ_UINT16(&_data[animOffset + 28 + 2]); //BASA_End of first frame - debug("end: %d", end); + int start = newBackgroundAnim.backAnims[0]._basaData._start; // BASA_Start of first frame + debug("start2: %d", start); + int end = newBackgroundAnim.backAnims[0]._basaData._end; //BASA_End of first frame + debug("end2: %d", end); - if (start != 65535) { + if (start != -1) { newBackgroundAnim.backAnims[0]._frame = start; newBackgroundAnim.backAnims[0]._showFrame = start; newBackgroundAnim.backAnims[0]._loopFrame = start; } - if (end != 65535) { + if (end != -1) { newBackgroundAnim.backAnims[0]._lastFrame = end; } From bc1553def6d7cc8a2cae014b35e0e963acc825b4 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 27 May 2014 16:29:08 +0200 Subject: [PATCH 105/374] PRINCE: showSprite first implementation, showBackAnims small update --- engines/prince/hero.cpp | 8 ++-- engines/prince/hero.h | 1 - engines/prince/prince.cpp | 88 ++++++++++++++++++++++++++++++--------- engines/prince/prince.h | 5 ++- 4 files changed, 77 insertions(+), 25 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index a91ef9460255..d5123cc337d2 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -754,14 +754,14 @@ void Hero::scrollHero() { */ int locationWidth = _vm->_sceneWidth; - int difference = locationWidth - kNormalWidth / 2; + int difference = locationWidth - _vm->kNormalWidth / 2; int destValue = 0; - if (position > kNormalWidth / 2) { - destValue = difference - kNormalWidth / 2; + if (position > _vm->kNormalWidth / 2) { + destValue = difference - _vm->kNormalWidth / 2; } if (position < difference) { - destValue = position - kNormalWidth / 2; + destValue = position - _vm->kNormalWidth / 2; } if(destValue < 0) { destValue = 0; diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 0b3935637d72..c430cc3861e9 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -43,7 +43,6 @@ class Hero { static const int16 kMaxPicWidth = 1280; static const int16 kMaxPicHeight = 480; static const int16 kZoomBitmapWidth = kMaxPicWidth / kZoomStep; - static const int16 kNormalWidth = 640; static const int16 kShadowLineArraySize = 2 * 1280 * 4; static const int32 kShadowBitmapSize = kMaxPicWidth * kMaxPicHeight / 8; static const int16 kScreenWidth = 640; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 4d221fdfeb3d..be4fb1544efa 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -115,13 +115,15 @@ PrinceEngine::~PrinceEngine() { } _objList.clear(); - /* - for (uint i = 0; i < _backAnimList.size(); i++) { - delete _backAnimList[i]._animData; - delete _backAnimList[i]._shadowData; + for (uint32 i = 0; i < _backAnimList.size(); i++) { + int anims = _backAnimList[i]._seq._anims != 0 ? _backAnimList[i]._seq._anims : 1; + for (uint32 j = 0; j < anims; j++) { + delete _backAnimList[i].backAnims[j]._animData; + delete _backAnimList[i].backAnims[j]._shadowData; + } + _backAnimList[i].backAnims.clear(); } _backAnimList.clear(); - */ for (uint i = 0; i < _mainHero->_moveSet.size(); i++) { delete _mainHero->_moveSet[i]; @@ -244,8 +246,7 @@ bool AnimListItem::loadFromStream(Common::SeekableReadStream &stream) { _type = type; _fileNumber = stream.readUint16LE(); _startPhase = stream.readUint16LE(); - //_endPhase = stream.readUint16LE(); - _endPhase = stream.readSint16LE(); + _endPhase = stream.readUint16LE(); _loopPhase = stream.readUint16LE(); _x = stream.readSint16LE(); _y = stream.readSint16LE(); @@ -327,14 +328,15 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); _room->loadRoom(_script->getRoomOffset(_locationNr)); - /* for (uint32 i = 0; i < _backAnimList.size(); i++) { - delete _backAnimList[i]._animData; - delete _backAnimList[i]._shadowData; + int anims = _backAnimList[i]._seq._anims != 0 ? _backAnimList[i]._seq._anims : 1; + for (uint32 j = 0; j < anims; j++) { + delete _backAnimList[i].backAnims[j]._animData; + delete _backAnimList[i].backAnims[j]._shadowData; + } + _backAnimList[i].backAnims.clear(); } _backAnimList.clear(); - */ - _backAnimList.clear(); _script->installBackAnims(_backAnimList, _room->_backAnim); @@ -704,15 +706,59 @@ void PrinceEngine::showTexts() { } } -void PrinceEngine::setBackAnim() { +void PrinceEngine::showSprite(Graphics::Surface *backAnimSurface, int destX, int destY) { + int sprWidth = backAnimSurface->w; + int sprHeight = backAnimSurface->h; + int sprModulo = 0; + + if (destX - _picWindowX < 0) { // x1 on visible part of screen? + // X1 signed, we add spriteWidth for x2 + if (sprWidth + destX - _picWindowX - 1 < 0) { + //exit - x2 is negative - out of window + return; // don't draw + } else { + //esi += _picWindowX - destX; + sprWidth -= _picWindowX - destX; + sprModulo += _picWindowX - destX; + destX = 0; // x1 = 0; + } + } + //left_x_check_ok + if (destX >= kNormalWidth) { // x1 outside of screen on right side + return; // don't draw + } + if (destX + sprWidth > kNormalWidth) { // x2 too far? + sprWidth -= destX - kNormalWidth; + sprModulo += destX - kNormalWidth; + } + //right_x_check_ok + if (destY - _picWindowY < 0) { + if (sprHeight + destY - _picWindowY - 1 < 0) { + //exit - y2 is negative - out of window + return; // don't draw + } else { + sprHeight -= _picWindowY - destY; + //esi += (sprWidth + sprModulo) * (_picWindowY - destY); + destY = 0; + } + } + //upper_y_check_ok + if (destY >= kNormalHeight) { + return; // don't draw + } + if (destY + sprHeight > kNormalHeight) { + sprHeight -= destY + sprHeight - kNormalHeight; + } + //lower_y_check_ok + _graph->drawTransparent(destX - _picWindowX, destY - _picWindowY, backAnimSurface); // TODO } void PrinceEngine::showBackAnims() { for (uint i = 0; i < _backAnimList.size(); i++) { int activeSubAnim = _backAnimList[i]._seq._currRelative; - if (_backAnimList[i].backAnims[activeSubAnim]._state == 0) { + if (_backAnimList[i].backAnims[activeSubAnim]._state == 0 && _backAnimList[i]._seq._type != 2 && _backAnimList[i]._seq._type != 3 && _backAnimList[i]._seq._type != 4) { //TEMP _backAnimList[i]._seq._counter++; if (_backAnimList[i]._seq._type == 2) { @@ -749,10 +795,9 @@ void PrinceEngine::showBackAnims() { } //not_type_3_1: //show_bugger - if (_backAnimList[i].backAnims[activeSubAnim]._frame == _backAnimList[i].backAnims[activeSubAnim]._lastFrame) { + if (_backAnimList[i].backAnims[activeSubAnim]._frame == _backAnimList[i].backAnims[activeSubAnim]._lastFrame - 1) { // TEST //loop_back_anim _backAnimList[i].backAnims[activeSubAnim]._frame = _backAnimList[i].backAnims[activeSubAnim]._loopFrame; - //debug("loopFrame: %d", _backAnimList[i].backAnims[tempAnimNr]._loopFrame); //change_back_anim if (_backAnimList[i]._seq._type == 0) { //show_bugger @@ -854,17 +899,22 @@ void PrinceEngine::showBackAnims() { //not_end: _backAnimList[i].backAnims[activeSubAnim]._showFrame = _backAnimList[i].backAnims[activeSubAnim]._frame; - //ShowFrameCode - //ShowFrameCodeShadow + //ShowFrameCode int frame = _backAnimList[i].backAnims[activeSubAnim]._showFrame; int phaseFrameIndex = _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseFrameIndex(frame); Graphics::Surface *backAnimSurface = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrame(phaseFrameIndex); int x = _backAnimList[i].backAnims[activeSubAnim]._x + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetX(frame); int y = _backAnimList[i].backAnims[activeSubAnim]._y + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetY(frame); - _graph->drawTransparent(x, y, backAnimSurface); // out of range now - crash .exe + //debug("x: %d", x); + //debug("picWindowX: %d", _picWindowX); + if (x - _picWindowX >= 0) { // || x - _picWindowX + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetX(frame) >= 0 ?? + showSprite(backAnimSurface, x, y); + } backAnimSurface->free(); delete backAnimSurface; + + //ShowFrameCodeShadow } } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 356c4dd9609d..34e6c753eb24 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -208,6 +208,9 @@ class PrinceEngine : public Engine { Common::RandomSource _randomSource; + static const int16 kNormalWidth = 640; + static const int16 kNormalHeight = 480; + int testAnimNr; int testAnimFrame; @@ -222,7 +225,7 @@ class PrinceEngine : public Engine { void init(); void showLogo(); void showBackAnims(); - void setBackAnim(); + void showSprite(Graphics::Surface *backAnimSurface, int destX, int destY); void makeShadowTable(int brightness); uint32 getTextWidth(const char *s); From 905a95e0ce327d603e4b1778f62c8358217f2373 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 27 May 2014 21:19:24 +0200 Subject: [PATCH 106/374] PRINCE: showSprite fix --- engines/prince/prince.cpp | 26 ++++++++++++++------------ engines/prince/prince.h | 4 ++-- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index be4fb1544efa..6abc4bf6b4fb 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -711,15 +711,16 @@ void PrinceEngine::showSprite(Graphics::Surface *backAnimSurface, int destX, int int sprHeight = backAnimSurface->h; int sprModulo = 0; - if (destX - _picWindowX < 0) { // x1 on visible part of screen? + destX -= _picWindowX; + if (destX < 0) { // x1 on visible part of screen? // X1 signed, we add spriteWidth for x2 - if (sprWidth + destX - _picWindowX - 1 < 0) { + if (sprWidth + destX < 1) { //exit - x2 is negative - out of window return; // don't draw } else { - //esi += _picWindowX - destX; - sprWidth -= _picWindowX - destX; - sprModulo += _picWindowX - destX; + //esi += -1 * destX; + sprWidth -= -1 * destX; + sprModulo += -1 * destX; destX = 0; // x1 = 0; } } @@ -732,13 +733,14 @@ void PrinceEngine::showSprite(Graphics::Surface *backAnimSurface, int destX, int sprModulo += destX - kNormalWidth; } //right_x_check_ok - if (destY - _picWindowY < 0) { - if (sprHeight + destY - _picWindowY - 1 < 0) { + destY -= _picWindowY; + if (destY < 0) { + if (sprHeight + destY < 1) { //exit - y2 is negative - out of window return; // don't draw } else { - sprHeight -= _picWindowY - destY; - //esi += (sprWidth + sprModulo) * (_picWindowY - destY); + sprHeight -= -1 * destY; + //esi += (sprWidth + sprModulo) * (-1 * destY); destY = 0; } } @@ -751,7 +753,7 @@ void PrinceEngine::showSprite(Graphics::Surface *backAnimSurface, int destX, int } //lower_y_check_ok - _graph->drawTransparent(destX - _picWindowX, destY - _picWindowY, backAnimSurface); // TODO + _graph->drawTransparent(destX, destY, backAnimSurface); // TODO } void PrinceEngine::showBackAnims() { @@ -908,9 +910,9 @@ void PrinceEngine::showBackAnims() { int y = _backAnimList[i].backAnims[activeSubAnim]._y + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetY(frame); //debug("x: %d", x); //debug("picWindowX: %d", _picWindowX); - if (x - _picWindowX >= 0) { // || x - _picWindowX + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetX(frame) >= 0 ?? + //if (x >= _picWindowX) { // || x - _picWindowX + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetX(frame) >= 0 ?? showSprite(backAnimSurface, x, y); - } + //} backAnimSurface->free(); delete backAnimSurface; diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 34e6c753eb24..0ced4b650359 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -198,8 +198,8 @@ class PrinceEngine : public Engine { uint16 _cameraX; uint16 _newCameraX; uint16 _sceneWidth; - uint32 _picWindowX; - uint32 _picWindowY; + int32 _picWindowX; + int32 _picWindowY; Image::BitmapDecoder *_roomBmp; Common::Array _animList; From b92d7762df557ff03600035a5fbf862a05a47f13 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 27 May 2014 21:30:57 +0200 Subject: [PATCH 107/374] PRINCE: showHeroShadow warning fix --- engines/prince/hero.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index d5123cc337d2..58f729a73e81 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -445,14 +445,14 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { if (ct_loop > shadWallSkipX && ct_loop - shadWallSkipX > shadWallModulo) { //WALL_copy_trans shadWDFlag = false; - int shadZoomX = _scaleValue; + int shadZoomXWall = _scaleValue; int backgroundDiffWall = 0; int shadowHeroXWall = 0; //ct_loop: for (int m = 0; m < ct_loop; m++) { - shadZoomX -= 100; - if (shadZoomX < 0 && _scaleValue != 10000) { - shadZoomX += _scaleValue; + shadZoomXWall -= 100; + if (shadZoomXWall < 0 && _scaleValue != 10000) { + shadZoomXWall += _scaleValue; } else { //point_ok: if (*shadowHero == kShadowColor) { From ada532cf2ead17e5e7e2483328a14d1907ad9e7b Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 28 May 2014 05:13:25 +0200 Subject: [PATCH 108/374] PRINCE: showSprite and drawTransparent update --- engines/prince/graphics.cpp | 12 ++++++--- engines/prince/graphics.h | 2 +- engines/prince/prince.cpp | 51 ++++++++++++------------------------- 3 files changed, 25 insertions(+), 40 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 5b66994b478b..551ae70a34de 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -73,12 +73,16 @@ void GraphicsMan::draw(uint16 posX, uint16 posY, const Graphics::Surface *s) { change(); } -void GraphicsMan::drawTransparent(uint16 posX, uint16 posY, const Graphics::Surface *s) { - for (uint y = 0; y < s->h; ++y) { - for (uint x = 0; x < s->w; ++x) { +void GraphicsMan::drawTransparent(int32 posX, int32 posY, const Graphics::Surface *s) { + for (int y = 0; y < s->h; y++) { + for (int x = 0; x < s->w; x++) { byte pixel = *((byte*)s->getBasePtr(x, y)); if (pixel != 255) { - *((byte*)_frontScreen->getBasePtr(x + posX, y + posY)) = pixel; + if (x + posX < _frontScreen->w && x + posX >= 0) { + if (y + posY < _frontScreen->h && y + posY >= 0) { + *((byte*)_frontScreen->getBasePtr(x + posX, y + posY)) = pixel; + } + } } } } diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index 3e43503c584d..50a0b16dbc12 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -44,7 +44,7 @@ class GraphicsMan void makeShadowTable(int brightness, byte *shadowTable); void draw(uint16 x, uint16 y, const Graphics::Surface *s); - void drawTransparent(uint16 x, uint16 y, const Graphics::Surface *s); + void drawTransparent(int32 posX, int32 poxY, const Graphics::Surface *s); Graphics::Surface *_frontScreen; Graphics::Surface *_backScreen; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 6abc4bf6b4fb..48bf932f412d 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -709,51 +709,32 @@ void PrinceEngine::showTexts() { void PrinceEngine::showSprite(Graphics::Surface *backAnimSurface, int destX, int destY) { int sprWidth = backAnimSurface->w; int sprHeight = backAnimSurface->h; - int sprModulo = 0; - destX -= _picWindowX; - if (destX < 0) { // x1 on visible part of screen? - // X1 signed, we add spriteWidth for x2 - if (sprWidth + destX < 1) { - //exit - x2 is negative - out of window - return; // don't draw - } else { - //esi += -1 * destX; - sprWidth -= -1 * destX; - sprModulo += -1 * destX; - destX = 0; // x1 = 0; + destY -= _picWindowY; + + // if x1 is on visible part of screen + if (destX < 0) { + if (destX + sprWidth < 1) { + //x2 is negative - out of window + return; } } - //left_x_check_ok - if (destX >= kNormalWidth) { // x1 outside of screen on right side - return; // don't draw - } - if (destX + sprWidth > kNormalWidth) { // x2 too far? - sprWidth -= destX - kNormalWidth; - sprModulo += destX - kNormalWidth; + // if x1 is outside of screen on right side + if (destX >= kNormalWidth) { + return; } - //right_x_check_ok - destY -= _picWindowY; + if (destY < 0) { - if (sprHeight + destY < 1) { - //exit - y2 is negative - out of window - return; // don't draw - } else { - sprHeight -= -1 * destY; - //esi += (sprWidth + sprModulo) * (-1 * destY); - destY = 0; + if (destY + sprHeight < 1) { + //y2 is negative - out of window + return; } } - //upper_y_check_ok if (destY >= kNormalHeight) { - return; // don't draw - } - if (destY + sprHeight > kNormalHeight) { - sprHeight -= destY + sprHeight - kNormalHeight; + return; } - //lower_y_check_ok - _graph->drawTransparent(destX, destY, backAnimSurface); // TODO + _graph->drawTransparent(destX, destY, backAnimSurface); } void PrinceEngine::showBackAnims() { From ac845b5b98849ed328534abe5dd82e528255ae05 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 28 May 2014 15:57:46 +0200 Subject: [PATCH 109/374] PRINCE: showBackAnims bug fixing --- engines/prince/prince.cpp | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 48bf932f412d..73789efedb30 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -784,13 +784,17 @@ void PrinceEngine::showBackAnims() { //change_back_anim if (_backAnimList[i]._seq._type == 0) { //show_bugger - _backAnimList[i].backAnims[activeSubAnim]._frame++; + if (_backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() > 1) { + _backAnimList[i].backAnims[activeSubAnim]._frame++; + } //not_end } else if (_backAnimList[i]._seq._type == 1) { //repeat_rnd if (_backAnimList[i]._seq._anims <= 1) { //show_bugger - _backAnimList[i].backAnims[activeSubAnim]._frame++; + if (_backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() > 1) { + _backAnimList[i].backAnims[activeSubAnim]._frame++; + } //not_end } else { int rnd; @@ -816,7 +820,9 @@ void PrinceEngine::showBackAnims() { _backAnimList[i]._seq._counter = 0; _backAnimList[i].backAnims[activeSubAnim]._state = 0; //show_bugger - _backAnimList[i].backAnims[activeSubAnim]._frame++; + if (_backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() > 1) { + _backAnimList[i].backAnims[activeSubAnim]._frame++; + } //not_end } } else if (_backAnimList[i]._seq._type == 2) { @@ -884,11 +890,27 @@ void PrinceEngine::showBackAnims() { _backAnimList[i].backAnims[activeSubAnim]._showFrame = _backAnimList[i].backAnims[activeSubAnim]._frame; //ShowFrameCode - int frame = _backAnimList[i].backAnims[activeSubAnim]._showFrame; - int phaseFrameIndex = _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseFrameIndex(frame); - Graphics::Surface *backAnimSurface = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrame(phaseFrameIndex); - int x = _backAnimList[i].backAnims[activeSubAnim]._x + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetX(frame); - int y = _backAnimList[i].backAnims[activeSubAnim]._y + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetY(frame); + int phaseCount = _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount(); + int frameCount = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrameCount(); + //debug("frameCount: %d", frameCount); + //debug("phaseCount: %d", phaseCount); + int phase = _backAnimList[i].backAnims[activeSubAnim]._showFrame; + if (phase >= phaseCount) { + debug("p >= pC: i-%d, activ-%d, phase-%d, phaseC-%d", i, activeSubAnim, phase, phaseCount); + debug("type: %d", _backAnimList[i]._seq._type); + } + int phaseFrameIndex = _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseFrameIndex(phase); + if (phaseFrameIndex < 0) { + debug("pFrameIndex: i-%d, activ-%d, phaseFrInd-%d, frameC-%d", i, activeSubAnim, phaseFrameIndex, frameCount); + debug("type: %d", _backAnimList[i]._seq._type); + } + if (phaseFrameIndex >= frameCount) { + debug("pFrameIndex2: i-%d, activ-%d, phaseFrInd-%d, frameC-%d", i, activeSubAnim, phaseFrameIndex, frameCount); + debug("type: %d", _backAnimList[i]._seq._type); + } + Graphics::Surface *backAnimSurface = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrame(phaseFrameIndex); //still out of bounds + int x = _backAnimList[i].backAnims[activeSubAnim]._x + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetX(phase); + int y = _backAnimList[i].backAnims[activeSubAnim]._y + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetY(phase); //debug("x: %d", x); //debug("picWindowX: %d", _picWindowX); //if (x >= _picWindowX) { // || x - _picWindowX + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetX(frame) >= 0 ?? From 2e1f7db043b0f960c2325e2ec3946ba375d78988 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 29 May 2014 19:46:48 +0200 Subject: [PATCH 110/374] PRINCE: showBackAnims anim type 2, memory leaks debugging --- engines/prince/animation.cpp | 7 +- engines/prince/animation.h | 6 +- engines/prince/hero.cpp | 2 +- engines/prince/prince.cpp | 187 ++++++++++++++++++++++++++--------- engines/prince/script.cpp | 22 +++-- 5 files changed, 160 insertions(+), 64 deletions(-) diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index c27505735e4e..e2197c22f25d 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -68,12 +68,12 @@ int16 Animation::getLoopCount() const { } // AH_Fazy -uint Animation::getPhaseCount() const { +int32 Animation::getPhaseCount() const { return READ_LE_UINT16(_data + 4); } // AH_Ramki -uint Animation::getFrameCount() const { +int32 Animation::getFrameCount() const { return READ_LE_UINT16(_data + 6); } @@ -113,7 +113,7 @@ int16 Animation::getFrameHeight(uint frameIndex) const { return READ_LE_UINT16(frameData + 2); } -Graphics::Surface *Animation::getFrame(uint frameIndex) { +Graphics::Surface *Animation::getFrame(uint frameIndex, int i, int phase) { byte *frameData = _data + READ_LE_UINT32(_data + 16 + frameIndex * 4); int16 width = READ_LE_UINT16(frameData + 0); int16 height = READ_LE_UINT16(frameData + 2); @@ -132,6 +132,7 @@ Graphics::Surface *Animation::getFrame(uint frameIndex) { } free(ddata); } else { + debug("nr: %d, phase: %d", i, phase); // Uncompressed for (uint16 i = 0; i < height; i++) { memcpy(surf->getBasePtr(0, i), frameData + 4 + width * i, width); diff --git a/engines/prince/animation.h b/engines/prince/animation.h index d5b5938ce070..03ea220c9158 100644 --- a/engines/prince/animation.h +++ b/engines/prince/animation.h @@ -40,12 +40,12 @@ class Animation { int16 getLoopCount() const; int16 getBaseX() const; int16 getBaseY() const; - uint getPhaseCount() const; - uint getFrameCount() const; + int32 getPhaseCount() const; + int32 getFrameCount() const; int16 getPhaseOffsetX(uint phaseIndex) const; int16 getPhaseOffsetY(uint phaseIndex) const; int16 getPhaseFrameIndex(uint phaseIndex) const; - Graphics::Surface *getFrame(uint frameIndex); + Graphics::Surface *getFrame(uint frameIndex, int i, int phase); int16 getFrameWidth(uint frameIndex) const; int16 getFrameHeight(uint frameIndex) const; int16 getZoom(uint16 offset) const; diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 58f729a73e81..37b9679dbc49 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -80,7 +80,7 @@ bool Hero::loadAnimSet(uint32 animSetNr) { Graphics::Surface *Hero::getSurface() { if (_moveSet[_moveSetType]) { int16 phaseFrameIndex = _moveSet[_moveSetType]->getPhaseFrameIndex(_phase); - Graphics::Surface *heroFrame = _moveSet[_moveSetType]->getFrame(phaseFrameIndex); + Graphics::Surface *heroFrame = _moveSet[_moveSetType]->getFrame(phaseFrameIndex, 0, 0); return heroFrame; } return NULL; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 73789efedb30..c631038fe8d4 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -619,6 +619,16 @@ void PrinceEngine::keyHandler(Common::Event event) { case Common::KEYCODE_l: _mainHero->_middleX += 5; break; + case Common::KEYCODE_EQUALS: + if (_debugger->_locationNr > 1) { + _debugger->_locationNr--; + } + break; + case Common::KEYCODE_BACKSPACE: + if (_debugger->_locationNr < 43) { + _debugger->_locationNr++; + } + break; } } @@ -741,9 +751,10 @@ void PrinceEngine::showBackAnims() { for (uint i = 0; i < _backAnimList.size(); i++) { int activeSubAnim = _backAnimList[i]._seq._currRelative; - if (_backAnimList[i].backAnims[activeSubAnim]._state == 0 && _backAnimList[i]._seq._type != 2 && _backAnimList[i]._seq._type != 3 && _backAnimList[i]._seq._type != 4) { //TEMP + if (_backAnimList[i].backAnims[activeSubAnim]._state == 0 && _backAnimList[i]._seq._type != 0 && _backAnimList[i]._seq._type != 1 && _backAnimList[i]._seq._type != 3 && _backAnimList[i]._seq._type != 4) { //TEMP _backAnimList[i]._seq._counter++; + /* if (_backAnimList[i]._seq._type == 2) { if (_backAnimList[i]._seq._currRelative == 0) { if (_backAnimList[i]._seq._counter >= _backAnimList[i]._seq._data) { @@ -751,6 +762,68 @@ void PrinceEngine::showBackAnims() { } } } + */ + if (_backAnimList[i]._seq._type == 2) { + //not_type_1 + if (_backAnimList[i]._seq._currRelative == 0) { + //zero + debug("counter: %d, data: %d", _backAnimList[i]._seq._counter, _backAnimList[i]._seq._data); + if (_backAnimList[i]._seq._counter >= _backAnimList[i]._seq._data) { + if (_backAnimList[i]._seq._anims > 2) { + int rnd = _randomSource.getRandomNumber(_backAnimList[i]._seq._anims - 2); //? + rnd++; + //debug("rnd: %d", rnd); + _backAnimList[i]._seq._currRelative = rnd; + _backAnimList[i]._seq._current = rnd; // or nr of animation from lst + activeSubAnim = rnd; + } + //only_1_type_2 + //SetBackAnim + int start = _backAnimList[i].backAnims[activeSubAnim]._basaData._start; + if (start != -1) { + _backAnimList[i].backAnims[activeSubAnim]._frame = start; + _backAnimList[i].backAnims[activeSubAnim]._showFrame = start; + _backAnimList[i].backAnims[activeSubAnim]._loopFrame = start; + } + int end = _backAnimList[i].backAnims[activeSubAnim]._basaData._end; + if (end != -1) { + _backAnimList[i].backAnims[activeSubAnim]._lastFrame = end; + } + _backAnimList[i]._seq._counter = 0; + _backAnimList[i].backAnims[activeSubAnim]._state = 0; + //show_bugger + if (_backAnimList[i].backAnims[activeSubAnim]._frame < _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() - 1) { + _backAnimList[i].backAnims[activeSubAnim]._frame++; + } + //not_end + } + } else { + /* + _backAnimList[i]._seq._currRelative = 0; + _backAnimList[i]._seq._current = 0; // or nr of animation from lst + activeSubAnim = 0; + //only_1_type_1 + //SetBackAnim + int start = _backAnimList[i].backAnims[activeSubAnim]._basaData._start; + if (start != -1) { + _backAnimList[i].backAnims[activeSubAnim]._frame = start; + _backAnimList[i].backAnims[activeSubAnim]._showFrame = start; + _backAnimList[i].backAnims[activeSubAnim]._loopFrame = start; + } + int end = _backAnimList[i].backAnims[activeSubAnim]._basaData._end; + if (end != -1) { + _backAnimList[i].backAnims[activeSubAnim]._lastFrame = end; + } + _backAnimList[i]._seq._counter = 0; + _backAnimList[i].backAnims[activeSubAnim]._state = 0; + //show_bugger + if (_backAnimList[i].backAnims[activeSubAnim]._frame < _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() - 1) { + _backAnimList[i].backAnims[activeSubAnim]._frame++; + } + //not_end + */ + } + } //not_type_2_1: if (_backAnimList[i]._seq._type == 3) { @@ -778,13 +851,14 @@ void PrinceEngine::showBackAnims() { } //not_type_3_1: //show_bugger + debug("lastFrame: %d", _backAnimList[i].backAnims[activeSubAnim]._lastFrame); if (_backAnimList[i].backAnims[activeSubAnim]._frame == _backAnimList[i].backAnims[activeSubAnim]._lastFrame - 1) { // TEST //loop_back_anim _backAnimList[i].backAnims[activeSubAnim]._frame = _backAnimList[i].backAnims[activeSubAnim]._loopFrame; //change_back_anim if (_backAnimList[i]._seq._type == 0) { //show_bugger - if (_backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() > 1) { + if (_backAnimList[i].backAnims[activeSubAnim]._frame < _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() - 1) { _backAnimList[i].backAnims[activeSubAnim]._frame++; } //not_end @@ -792,7 +866,7 @@ void PrinceEngine::showBackAnims() { //repeat_rnd if (_backAnimList[i]._seq._anims <= 1) { //show_bugger - if (_backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() > 1) { + if (_backAnimList[i].backAnims[activeSubAnim]._frame < _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() - 1) { _backAnimList[i].backAnims[activeSubAnim]._frame++; } //not_end @@ -820,52 +894,44 @@ void PrinceEngine::showBackAnims() { _backAnimList[i]._seq._counter = 0; _backAnimList[i].backAnims[activeSubAnim]._state = 0; //show_bugger - if (_backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() > 1) { + if (_backAnimList[i].backAnims[activeSubAnim]._frame < _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() - 1) { _backAnimList[i].backAnims[activeSubAnim]._frame++; } //not_end } } else if (_backAnimList[i]._seq._type == 2) { - //not_type_1 - if (_backAnimList[i]._seq._currRelative == 0) { - //zero - if (_backAnimList[i]._seq._counter < _backAnimList[i]._seq._data) { - //show_bugger - _backAnimList[i].backAnims[activeSubAnim]._frame++; - //not_end - } else { - if (_backAnimList[i]._seq._anims > 2) { //?? - int rnd = _randomSource.getRandomNumber(_backAnimList[i]._seq._anims - 2); //? - rnd++; - //debug("rnd: %d", rnd); - _backAnimList[i]._seq._currRelative = rnd; - _backAnimList[i]._seq._current = rnd; // or nr of animation from lst - activeSubAnim = rnd; - } - //only_1_type_2 - } - } else { + if (_backAnimList[i]._seq._currRelative != 0) { _backAnimList[i]._seq._currRelative = 0; _backAnimList[i]._seq._current = 0; // or nr of animation from lst activeSubAnim = 0; //only_1_type_1 - } - //SetBackAnim - int start = _backAnimList[i].backAnims[activeSubAnim]._basaData._start; - if (start != -1) { - _backAnimList[i].backAnims[activeSubAnim]._frame = start; - _backAnimList[i].backAnims[activeSubAnim]._showFrame = start; - _backAnimList[i].backAnims[activeSubAnim]._loopFrame = start; - } - int end = _backAnimList[i].backAnims[activeSubAnim]._basaData._end; - if (end != -1) { - _backAnimList[i].backAnims[activeSubAnim]._lastFrame = end; - } - _backAnimList[i]._seq._counter = 0; - _backAnimList[i].backAnims[activeSubAnim]._state = 0; - //show_bugger - _backAnimList[i].backAnims[activeSubAnim]._frame++; - //not_end + //SetBackAnim + int start = _backAnimList[i].backAnims[activeSubAnim]._basaData._start; + if (start != -1) { + _backAnimList[i].backAnims[activeSubAnim]._frame = start; + _backAnimList[i].backAnims[activeSubAnim]._showFrame = start; + _backAnimList[i].backAnims[activeSubAnim]._loopFrame = start; + } + int end = _backAnimList[i].backAnims[activeSubAnim]._basaData._end; + if (end != -1) { + _backAnimList[i].backAnims[activeSubAnim]._lastFrame = end; + } + _backAnimList[i]._seq._counter = 0; + _backAnimList[i].backAnims[activeSubAnim]._state = 0; + /* + //show_bugger + if (_backAnimList[i].backAnims[activeSubAnim]._frame < _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() - 1) { + _backAnimList[i].backAnims[activeSubAnim]._frame++; + } + //not_end + */ + } /*else if (_backAnimList[i]._seq._counter < _backAnimList[i]._seq._data) { + //show_bugger + if (_backAnimList[i].backAnims[activeSubAnim]._frame < _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() - 1) { + _backAnimList[i].backAnims[activeSubAnim]._frame++; + } + //not_end + }*/ } else if (_backAnimList[i]._seq._type == 3) { //not_type_2 _backAnimList[i]._seq._currRelative = 0; @@ -895,6 +961,9 @@ void PrinceEngine::showBackAnims() { //debug("frameCount: %d", frameCount); //debug("phaseCount: %d", phaseCount); int phase = _backAnimList[i].backAnims[activeSubAnim]._showFrame; + if (phase < 0) { + debug("phase < 0"); + } if (phase >= phaseCount) { debug("p >= pC: i-%d, activ-%d, phase-%d, phaseC-%d", i, activeSubAnim, phase, phaseCount); debug("type: %d", _backAnimList[i]._seq._type); @@ -908,17 +977,39 @@ void PrinceEngine::showBackAnims() { debug("pFrameIndex2: i-%d, activ-%d, phaseFrInd-%d, frameC-%d", i, activeSubAnim, phaseFrameIndex, frameCount); debug("type: %d", _backAnimList[i]._seq._type); } - Graphics::Surface *backAnimSurface = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrame(phaseFrameIndex); //still out of bounds + int x = _backAnimList[i].backAnims[activeSubAnim]._x + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetX(phase); int y = _backAnimList[i].backAnims[activeSubAnim]._y + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetY(phase); - //debug("x: %d", x); - //debug("picWindowX: %d", _picWindowX); - //if (x >= _picWindowX) { // || x - _picWindowX + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetX(frame) >= 0 ?? - showSprite(backAnimSurface, x, y); - //} - backAnimSurface->free(); - delete backAnimSurface; + if (x != 0 || y != 0 || phaseCount != 1 || frameCount != 1) { // fix for room no. 5 - animation 8 (propably unnecessary anim) + Graphics::Surface *backAnimSurface = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrame(phaseFrameIndex, i, phase); //still out of bounds + + //debug("x: %d", x); + //debug("picWindowX: %d", _picWindowX); + //if (x >= _picWindowX) { // || x - _picWindowX + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetX(frame) >= 0 ?? + showSprite(backAnimSurface, x, y); + //} + backAnimSurface->free(); + delete backAnimSurface; + + //if (_backAnimList[i].backAnims[activeSubAnim]._lastFrame == 1) { + debug("nr: %d, phase: %d, frame: %d", i, phase, phaseFrameIndex); + debug("phaseCount: %d, frameCount: %d, lastFrame: %d", phaseCount, frameCount, _backAnimList[i].backAnims[activeSubAnim]._lastFrame); + //debug("x: %d", _backAnimList[i].backAnims[activeSubAnim]._x); + //debug("y: %d", _backAnimList[i].backAnims[activeSubAnim]._y); + //debug("offX: %d", _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetX(phase)); + //debug("offX: %d", _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetY(phase)); + //debug("x: %d, y: %d", x, y); + //} + + if (_backAnimList[i].backAnims[activeSubAnim]._x == 0 && _backAnimList[i].backAnims[activeSubAnim]._y == 0) { + debug("x = 0, y = 0"); + } + + if (phaseCount == 1 && frameCount == 1) { + debug("pC = 1, fC = 1"); + } + } //ShowFrameCodeShadow } } diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index d87cd8b9e26c..7806bf04bb50 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -222,8 +222,12 @@ void Script::installSingleBackAnim(Common::Array &_backanimList, newAnim._basaData._num = READ_UINT16(&_data[animOffset + 28 + i * 8]); newAnim._basaData._start = READ_UINT16(&_data[animOffset + 28 + i * 8 + 2]); newAnim._basaData._end = READ_UINT16(&_data[animOffset + 28 + i * 8 + 4]); - debug("start1: %d", newAnim._basaData._start); - debug("end1: %d", newAnim._basaData._end); + if (newAnim._basaData._start != -1) { + debug("start1: %d", newAnim._basaData._start); + } + if (newAnim._basaData._end != -1) { + debug("end1: %d", newAnim._basaData._end); + } int animNumber = newAnim._basaData._num; const Common::String animName = Common::String::format("AN%02d", animNumber); const Common::String shadowName = Common::String::format("AN%02dS", animNumber); @@ -267,34 +271,34 @@ void Script::installSingleBackAnim(Common::Array &_backanimList, newBackgroundAnim._seq._type = READ_UINT32(&_data[animOffset]); debug("type: %d", newBackgroundAnim._seq._type); newBackgroundAnim._seq._data = READ_UINT32(&_data[animOffset + 4]); - debug("data: %d", newBackgroundAnim._seq._data); + //debug("data: %d", newBackgroundAnim._seq._data); newBackgroundAnim._seq._anims = READ_UINT32(&_data[animOffset + 8]); anims = newBackgroundAnim._seq._anims; debug("anims: %d", newBackgroundAnim._seq._anims); //newBackgroundAnim._seq._current = READ_UINT32(&_data[animOffset + 12]); newBackgroundAnim._seq._current = 0; // nr on list like now or should it be fileNr of anim - check it - debug("current: %d", newBackgroundAnim._seq._current); + //debug("current: %d", newBackgroundAnim._seq._current); //newBackgroundAnim._seq._counter = READ_UINT32(&_data[animOffset + 16]); newBackgroundAnim._seq._counter = 0; - debug("counter: %d", newBackgroundAnim._seq._counter); + //debug("counter: %d", newBackgroundAnim._seq._counter); //newBackgroundAnim._seq._currRelative = READ_UINT32(&_data[animOffset + 20]); newBackgroundAnim._seq._currRelative = 0; - debug("currRelative: %d", newBackgroundAnim._seq._currRelative); + //debug("currRelative: %d", newBackgroundAnim._seq._currRelative); newBackgroundAnim._seq._data2 = READ_UINT32(&_data[animOffset + 24]); - debug("data2: %d", newBackgroundAnim._seq._data2); + //debug("data2: %d", newBackgroundAnim._seq._data2); int start = newBackgroundAnim.backAnims[0]._basaData._start; // BASA_Start of first frame - debug("start2: %d", start); int end = newBackgroundAnim.backAnims[0]._basaData._end; //BASA_End of first frame - debug("end2: %d", end); if (start != -1) { + debug("start2: %d", start); newBackgroundAnim.backAnims[0]._frame = start; newBackgroundAnim.backAnims[0]._showFrame = start; newBackgroundAnim.backAnims[0]._loopFrame = start; } if (end != -1) { + debug("end2: %d", end); newBackgroundAnim.backAnims[0]._lastFrame = end; } From c4c20eca6cc6d44a42f565e634b03e69c67a6272 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 30 May 2014 15:07:47 +0200 Subject: [PATCH 111/374] PRINCE: showBackAnims anim type 3, memory leaks debugging --- engines/prince/prince.cpp | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index c631038fe8d4..9d5d789d60e4 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -751,7 +751,7 @@ void PrinceEngine::showBackAnims() { for (uint i = 0; i < _backAnimList.size(); i++) { int activeSubAnim = _backAnimList[i]._seq._currRelative; - if (_backAnimList[i].backAnims[activeSubAnim]._state == 0 && _backAnimList[i]._seq._type != 0 && _backAnimList[i]._seq._type != 1 && _backAnimList[i]._seq._type != 3 && _backAnimList[i]._seq._type != 4) { //TEMP + if (_backAnimList[i].backAnims[activeSubAnim]._state == 0 && _backAnimList[i]._seq._type != 0 && _backAnimList[i]._seq._type != 1 && _backAnimList[i]._seq._type != 2) { //TEMP _backAnimList[i]._seq._counter++; /* @@ -791,11 +791,13 @@ void PrinceEngine::showBackAnims() { } _backAnimList[i]._seq._counter = 0; _backAnimList[i].backAnims[activeSubAnim]._state = 0; + /* //show_bugger if (_backAnimList[i].backAnims[activeSubAnim]._frame < _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() - 1) { _backAnimList[i].backAnims[activeSubAnim]._frame++; } //not_end + */ } } else { /* @@ -828,11 +830,14 @@ void PrinceEngine::showBackAnims() { //not_type_2_1: if (_backAnimList[i]._seq._type == 3) { if (_backAnimList[i]._seq._currRelative == 0) { + //debug("count: %d, data2: %d", _backAnimList[i]._seq._counter, _backAnimList[i]._seq._data2); if (_backAnimList[i]._seq._counter < _backAnimList[i]._seq._data2) { //empty_frame - do not show anything + continue; } else { - _backAnimList[i]._seq._current++; // or change to nr of animation - _backAnimList[i]._seq._currRelative++; + //_backAnimList[i]._seq._current++; // or change to nr of animation + //_backAnimList[i]._seq._currRelative++; //sth wrong + //activeSubAnim++; //SetBackAnim int start = _backAnimList[i].backAnims[activeSubAnim]._basaData._start; if (start != -1) { @@ -844,32 +849,34 @@ void PrinceEngine::showBackAnims() { if (end != -1) { _backAnimList[i].backAnims[activeSubAnim]._lastFrame = end; } - _backAnimList[i]._seq._counter = 0; + //_backAnimList[i]._seq._counter = 0; _backAnimList[i].backAnims[activeSubAnim]._state = 0; } } } //not_type_3_1: //show_bugger - debug("lastFrame: %d", _backAnimList[i].backAnims[activeSubAnim]._lastFrame); + //debug("lastFrame: %d", _backAnimList[i].backAnims[activeSubAnim]._lastFrame); if (_backAnimList[i].backAnims[activeSubAnim]._frame == _backAnimList[i].backAnims[activeSubAnim]._lastFrame - 1) { // TEST //loop_back_anim _backAnimList[i].backAnims[activeSubAnim]._frame = _backAnimList[i].backAnims[activeSubAnim]._loopFrame; //change_back_anim if (_backAnimList[i]._seq._type == 0) { //show_bugger - if (_backAnimList[i].backAnims[activeSubAnim]._frame < _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() - 1) { - _backAnimList[i].backAnims[activeSubAnim]._frame++; - } + //if (_backAnimList[i].backAnims[activeSubAnim]._frame < _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() - 1) { + //_backAnimList[i].backAnims[activeSubAnim]._frame++; + //} //not_end } else if (_backAnimList[i]._seq._type == 1) { //repeat_rnd if (_backAnimList[i]._seq._anims <= 1) { + /* //show_bugger if (_backAnimList[i].backAnims[activeSubAnim]._frame < _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() - 1) { _backAnimList[i].backAnims[activeSubAnim]._frame++; } //not_end + */ } else { int rnd; do { @@ -893,10 +900,12 @@ void PrinceEngine::showBackAnims() { } _backAnimList[i]._seq._counter = 0; _backAnimList[i].backAnims[activeSubAnim]._state = 0; + /* //show_bugger if (_backAnimList[i].backAnims[activeSubAnim]._frame < _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() - 1) { _backAnimList[i].backAnims[activeSubAnim]._frame++; } + */ //not_end } } else if (_backAnimList[i]._seq._type == 2) { @@ -937,14 +946,16 @@ void PrinceEngine::showBackAnims() { _backAnimList[i]._seq._currRelative = 0; //_backAnimList[i]._seq._current = 0; // or nr of animation from lst _backAnimList[i]._seq._counter = 0; - int rnd = _randomSource.getRandomNumber(_backAnimList[i]._seq._data - 1); //? + //debug("data: %d", _backAnimList[i]._seq._data); + int rnd = _randomSource.getRandomNumber(_backAnimList[i]._seq._data - 1); _backAnimList[i]._seq._data2 = rnd; + continue; // for bug in original game //show_bugger - _backAnimList[i].backAnims[activeSubAnim]._frame++; + //_backAnimList[i].backAnims[activeSubAnim]._frame++; //not_end } else { //show_bugger - _backAnimList[i].backAnims[activeSubAnim]._frame++; + //_backAnimList[i].backAnims[activeSubAnim]._frame++; //not_end } } else { @@ -993,8 +1004,8 @@ void PrinceEngine::showBackAnims() { delete backAnimSurface; //if (_backAnimList[i].backAnims[activeSubAnim]._lastFrame == 1) { - debug("nr: %d, phase: %d, frame: %d", i, phase, phaseFrameIndex); - debug("phaseCount: %d, frameCount: %d, lastFrame: %d", phaseCount, frameCount, _backAnimList[i].backAnims[activeSubAnim]._lastFrame); + //debug("nr: %d, phase: %d, frame: %d", i, phase, phaseFrameIndex); + //debug("phaseCount: %d, frameCount: %d, lastFrame: %d", phaseCount, frameCount, _backAnimList[i].backAnims[activeSubAnim]._lastFrame); //debug("x: %d", _backAnimList[i].backAnims[activeSubAnim]._x); //debug("y: %d", _backAnimList[i].backAnims[activeSubAnim]._y); //debug("offX: %d", _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetX(phase)); From b1eeeb63ba8811a318c200c667e6bf2862993bea Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 30 May 2014 17:48:00 +0200 Subject: [PATCH 112/374] PRINCE: showBackAnims code clean up --- engines/prince/animation.cpp | 3 +- engines/prince/animation.h | 2 +- engines/prince/hero.cpp | 2 +- engines/prince/prince.cpp | 155 +++-------------------------------- 4 files changed, 13 insertions(+), 149 deletions(-) diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index e2197c22f25d..0aa5d464d1c0 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -113,7 +113,7 @@ int16 Animation::getFrameHeight(uint frameIndex) const { return READ_LE_UINT16(frameData + 2); } -Graphics::Surface *Animation::getFrame(uint frameIndex, int i, int phase) { +Graphics::Surface *Animation::getFrame(uint frameIndex) { byte *frameData = _data + READ_LE_UINT32(_data + 16 + frameIndex * 4); int16 width = READ_LE_UINT16(frameData + 0); int16 height = READ_LE_UINT16(frameData + 2); @@ -132,7 +132,6 @@ Graphics::Surface *Animation::getFrame(uint frameIndex, int i, int phase) { } free(ddata); } else { - debug("nr: %d, phase: %d", i, phase); // Uncompressed for (uint16 i = 0; i < height; i++) { memcpy(surf->getBasePtr(0, i), frameData + 4 + width * i, width); diff --git a/engines/prince/animation.h b/engines/prince/animation.h index 03ea220c9158..941f1ba6dd63 100644 --- a/engines/prince/animation.h +++ b/engines/prince/animation.h @@ -45,7 +45,7 @@ class Animation { int16 getPhaseOffsetX(uint phaseIndex) const; int16 getPhaseOffsetY(uint phaseIndex) const; int16 getPhaseFrameIndex(uint phaseIndex) const; - Graphics::Surface *getFrame(uint frameIndex, int i, int phase); + Graphics::Surface *getFrame(uint frameIndex); int16 getFrameWidth(uint frameIndex) const; int16 getFrameHeight(uint frameIndex) const; int16 getZoom(uint16 offset) const; diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 37b9679dbc49..58f729a73e81 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -80,7 +80,7 @@ bool Hero::loadAnimSet(uint32 animSetNr) { Graphics::Surface *Hero::getSurface() { if (_moveSet[_moveSetType]) { int16 phaseFrameIndex = _moveSet[_moveSetType]->getPhaseFrameIndex(_phase); - Graphics::Surface *heroFrame = _moveSet[_moveSetType]->getFrame(phaseFrameIndex, 0, 0); + Graphics::Surface *heroFrame = _moveSet[_moveSetType]->getFrame(phaseFrameIndex); return heroFrame; } return NULL; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 9d5d789d60e4..1a6cd70f0793 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -748,31 +748,19 @@ void PrinceEngine::showSprite(Graphics::Surface *backAnimSurface, int destX, int } void PrinceEngine::showBackAnims() { - for (uint i = 0; i < _backAnimList.size(); i++) { int activeSubAnim = _backAnimList[i]._seq._currRelative; - if (_backAnimList[i].backAnims[activeSubAnim]._state == 0 && _backAnimList[i]._seq._type != 0 && _backAnimList[i]._seq._type != 1 && _backAnimList[i]._seq._type != 2) { //TEMP - _backAnimList[i]._seq._counter++; - /* - if (_backAnimList[i]._seq._type == 2) { - if (_backAnimList[i]._seq._currRelative == 0) { - if (_backAnimList[i]._seq._counter >= _backAnimList[i]._seq._data) { - //change_back_anim - } - } - } - */ + if (_backAnimList[i].backAnims[activeSubAnim]._state == 0) { + _backAnimList[i]._seq._counter++; if (_backAnimList[i]._seq._type == 2) { //not_type_1 if (_backAnimList[i]._seq._currRelative == 0) { //zero - debug("counter: %d, data: %d", _backAnimList[i]._seq._counter, _backAnimList[i]._seq._data); if (_backAnimList[i]._seq._counter >= _backAnimList[i]._seq._data) { if (_backAnimList[i]._seq._anims > 2) { - int rnd = _randomSource.getRandomNumber(_backAnimList[i]._seq._anims - 2); //? + int rnd = _randomSource.getRandomNumber(_backAnimList[i]._seq._anims - 2); rnd++; - //debug("rnd: %d", rnd); _backAnimList[i]._seq._currRelative = rnd; _backAnimList[i]._seq._current = rnd; // or nr of animation from lst activeSubAnim = rnd; @@ -791,53 +779,17 @@ void PrinceEngine::showBackAnims() { } _backAnimList[i]._seq._counter = 0; _backAnimList[i].backAnims[activeSubAnim]._state = 0; - /* - //show_bugger - if (_backAnimList[i].backAnims[activeSubAnim]._frame < _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() - 1) { - _backAnimList[i].backAnims[activeSubAnim]._frame++; - } - //not_end - */ - } - } else { - /* - _backAnimList[i]._seq._currRelative = 0; - _backAnimList[i]._seq._current = 0; // or nr of animation from lst - activeSubAnim = 0; - //only_1_type_1 - //SetBackAnim - int start = _backAnimList[i].backAnims[activeSubAnim]._basaData._start; - if (start != -1) { - _backAnimList[i].backAnims[activeSubAnim]._frame = start; - _backAnimList[i].backAnims[activeSubAnim]._showFrame = start; - _backAnimList[i].backAnims[activeSubAnim]._loopFrame = start; } - int end = _backAnimList[i].backAnims[activeSubAnim]._basaData._end; - if (end != -1) { - _backAnimList[i].backAnims[activeSubAnim]._lastFrame = end; - } - _backAnimList[i]._seq._counter = 0; - _backAnimList[i].backAnims[activeSubAnim]._state = 0; - //show_bugger - if (_backAnimList[i].backAnims[activeSubAnim]._frame < _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() - 1) { - _backAnimList[i].backAnims[activeSubAnim]._frame++; - } - //not_end - */ } } //not_type_2_1: if (_backAnimList[i]._seq._type == 3) { if (_backAnimList[i]._seq._currRelative == 0) { - //debug("count: %d, data2: %d", _backAnimList[i]._seq._counter, _backAnimList[i]._seq._data2); if (_backAnimList[i]._seq._counter < _backAnimList[i]._seq._data2) { //empty_frame - do not show anything continue; } else { - //_backAnimList[i]._seq._current++; // or change to nr of animation - //_backAnimList[i]._seq._currRelative++; //sth wrong - //activeSubAnim++; //SetBackAnim int start = _backAnimList[i].backAnims[activeSubAnim]._basaData._start; if (start != -1) { @@ -849,40 +801,23 @@ void PrinceEngine::showBackAnims() { if (end != -1) { _backAnimList[i].backAnims[activeSubAnim]._lastFrame = end; } - //_backAnimList[i]._seq._counter = 0; _backAnimList[i].backAnims[activeSubAnim]._state = 0; } } } //not_type_3_1: //show_bugger - //debug("lastFrame: %d", _backAnimList[i].backAnims[activeSubAnim]._lastFrame); - if (_backAnimList[i].backAnims[activeSubAnim]._frame == _backAnimList[i].backAnims[activeSubAnim]._lastFrame - 1) { // TEST + if (_backAnimList[i].backAnims[activeSubAnim]._frame == _backAnimList[i].backAnims[activeSubAnim]._lastFrame - 1) { //loop_back_anim _backAnimList[i].backAnims[activeSubAnim]._frame = _backAnimList[i].backAnims[activeSubAnim]._loopFrame; //change_back_anim - if (_backAnimList[i]._seq._type == 0) { - //show_bugger - //if (_backAnimList[i].backAnims[activeSubAnim]._frame < _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() - 1) { - //_backAnimList[i].backAnims[activeSubAnim]._frame++; - //} - //not_end - } else if (_backAnimList[i]._seq._type == 1) { + if (_backAnimList[i]._seq._type == 1) { //repeat_rnd - if (_backAnimList[i]._seq._anims <= 1) { - /* - //show_bugger - if (_backAnimList[i].backAnims[activeSubAnim]._frame < _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() - 1) { - _backAnimList[i].backAnims[activeSubAnim]._frame++; - } - //not_end - */ - } else { + if (_backAnimList[i]._seq._anims > 1) { int rnd; do { rnd = _randomSource.getRandomNumber(_backAnimList[i]._seq._anims - 1); } while (rnd == _backAnimList[i]._seq._currRelative); - //debug("rnd: %d", rnd); _backAnimList[i]._seq._currRelative = rnd; _backAnimList[i]._seq._current = rnd; // or nr of animation from lst activeSubAnim = rnd; @@ -900,13 +835,6 @@ void PrinceEngine::showBackAnims() { } _backAnimList[i]._seq._counter = 0; _backAnimList[i].backAnims[activeSubAnim]._state = 0; - /* - //show_bugger - if (_backAnimList[i].backAnims[activeSubAnim]._frame < _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() - 1) { - _backAnimList[i].backAnims[activeSubAnim]._frame++; - } - */ - //not_end } } else if (_backAnimList[i]._seq._type == 2) { if (_backAnimList[i]._seq._currRelative != 0) { @@ -927,40 +855,18 @@ void PrinceEngine::showBackAnims() { } _backAnimList[i]._seq._counter = 0; _backAnimList[i].backAnims[activeSubAnim]._state = 0; - /* - //show_bugger - if (_backAnimList[i].backAnims[activeSubAnim]._frame < _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() - 1) { - _backAnimList[i].backAnims[activeSubAnim]._frame++; - } - //not_end - */ - } /*else if (_backAnimList[i]._seq._counter < _backAnimList[i]._seq._data) { - //show_bugger - if (_backAnimList[i].backAnims[activeSubAnim]._frame < _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount() - 1) { - _backAnimList[i].backAnims[activeSubAnim]._frame++; - } - //not_end - }*/ + } } else if (_backAnimList[i]._seq._type == 3) { //not_type_2 _backAnimList[i]._seq._currRelative = 0; - //_backAnimList[i]._seq._current = 0; // or nr of animation from lst + _backAnimList[i]._seq._current = 0; // or nr of animation from lst _backAnimList[i]._seq._counter = 0; - //debug("data: %d", _backAnimList[i]._seq._data); int rnd = _randomSource.getRandomNumber(_backAnimList[i]._seq._data - 1); _backAnimList[i]._seq._data2 = rnd; continue; // for bug in original game - //show_bugger - //_backAnimList[i].backAnims[activeSubAnim]._frame++; - //not_end - } else { - //show_bugger - //_backAnimList[i].backAnims[activeSubAnim]._frame++; - //not_end } } else { _backAnimList[i].backAnims[activeSubAnim]._frame++; - //not_end } //not_end: @@ -969,57 +875,16 @@ void PrinceEngine::showBackAnims() { //ShowFrameCode int phaseCount = _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount(); int frameCount = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrameCount(); - //debug("frameCount: %d", frameCount); - //debug("phaseCount: %d", phaseCount); int phase = _backAnimList[i].backAnims[activeSubAnim]._showFrame; - if (phase < 0) { - debug("phase < 0"); - } - if (phase >= phaseCount) { - debug("p >= pC: i-%d, activ-%d, phase-%d, phaseC-%d", i, activeSubAnim, phase, phaseCount); - debug("type: %d", _backAnimList[i]._seq._type); - } int phaseFrameIndex = _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseFrameIndex(phase); - if (phaseFrameIndex < 0) { - debug("pFrameIndex: i-%d, activ-%d, phaseFrInd-%d, frameC-%d", i, activeSubAnim, phaseFrameIndex, frameCount); - debug("type: %d", _backAnimList[i]._seq._type); - } - if (phaseFrameIndex >= frameCount) { - debug("pFrameIndex2: i-%d, activ-%d, phaseFrInd-%d, frameC-%d", i, activeSubAnim, phaseFrameIndex, frameCount); - debug("type: %d", _backAnimList[i]._seq._type); - } - int x = _backAnimList[i].backAnims[activeSubAnim]._x + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetX(phase); int y = _backAnimList[i].backAnims[activeSubAnim]._y + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetY(phase); if (x != 0 || y != 0 || phaseCount != 1 || frameCount != 1) { // fix for room no. 5 - animation 8 (propably unnecessary anim) - Graphics::Surface *backAnimSurface = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrame(phaseFrameIndex, i, phase); //still out of bounds - - //debug("x: %d", x); - //debug("picWindowX: %d", _picWindowX); - //if (x >= _picWindowX) { // || x - _picWindowX + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetX(frame) >= 0 ?? - showSprite(backAnimSurface, x, y); - //} + Graphics::Surface *backAnimSurface = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrame(phaseFrameIndex); //still with memory leak + showSprite(backAnimSurface, x, y); backAnimSurface->free(); delete backAnimSurface; - - //if (_backAnimList[i].backAnims[activeSubAnim]._lastFrame == 1) { - //debug("nr: %d, phase: %d, frame: %d", i, phase, phaseFrameIndex); - //debug("phaseCount: %d, frameCount: %d, lastFrame: %d", phaseCount, frameCount, _backAnimList[i].backAnims[activeSubAnim]._lastFrame); - //debug("x: %d", _backAnimList[i].backAnims[activeSubAnim]._x); - //debug("y: %d", _backAnimList[i].backAnims[activeSubAnim]._y); - //debug("offX: %d", _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetX(phase)); - //debug("offX: %d", _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetY(phase)); - //debug("x: %d, y: %d", x, y); - //} - - if (_backAnimList[i].backAnims[activeSubAnim]._x == 0 && _backAnimList[i].backAnims[activeSubAnim]._y == 0) { - debug("x = 0, y = 0"); - } - - if (phaseCount == 1 && frameCount == 1) { - debug("pC = 1, fC = 1"); - } } //ShowFrameCodeShadow } From 5df6b9a4f48a10a397cf4642f8695beece4e5704 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 30 May 2014 19:07:45 +0200 Subject: [PATCH 113/374] PRINCE: Shadow drawing for background animations --- engines/prince/graphics.cpp | 17 ++++++++++++++ engines/prince/graphics.h | 1 + engines/prince/prince.cpp | 44 ++++++++++++++++++++++++++++++------- engines/prince/prince.h | 4 ++-- engines/prince/script.h | 1 - 5 files changed, 56 insertions(+), 11 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 551ae70a34de..6265d9476606 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -89,6 +89,23 @@ void GraphicsMan::drawTransparent(int32 posX, int32 posY, const Graphics::Surfac change(); } +void GraphicsMan::drawAsShadow(int32 posX, int32 posY, const Graphics::Surface *s, byte *shadowTable) { + for (int y = 0; y < s->h; y++) { + for (int x = 0; x < s->w; x++) { + byte pixel = *((byte*)s->getBasePtr(x, y)); + if (pixel != 255) { + if (x + posX < _frontScreen->w && x + posX >= 0) { + if (y + posY < _frontScreen->h && y + posY >= 0) { + byte *background = (byte *)_frontScreen->getBasePtr(x + posX, y + posY); + *background = *(shadowTable + *background); + } + } + } + } + } + change(); +} + void GraphicsMan::makeShadowTable(int brightness, byte *shadowPalette) { int32 redFirstOrg, greenFirstOrg, blueFirstOrg; int32 redSecondOrg, greenSecondOrg, blueSecondOrg; diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index 50a0b16dbc12..fea7d14744ae 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -45,6 +45,7 @@ class GraphicsMan void draw(uint16 x, uint16 y, const Graphics::Surface *s); void drawTransparent(int32 posX, int32 poxY, const Graphics::Surface *s); + void drawAsShadow(int32 posX, int32 poxY, const Graphics::Surface *s, byte *shadowTable); Graphics::Surface *_frontScreen; Graphics::Surface *_backScreen; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 1a6cd70f0793..8b294eb3352e 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -115,9 +115,9 @@ PrinceEngine::~PrinceEngine() { } _objList.clear(); - for (uint32 i = 0; i < _backAnimList.size(); i++) { + for (uint i = 0; i < _backAnimList.size(); i++) { int anims = _backAnimList[i]._seq._anims != 0 ? _backAnimList[i]._seq._anims : 1; - for (uint32 j = 0; j < anims; j++) { + for (uint j = 0; j < anims; j++) { delete _backAnimList[i].backAnims[j]._animData; delete _backAnimList[i].backAnims[j]._shadowData; } @@ -716,7 +716,7 @@ void PrinceEngine::showTexts() { } } -void PrinceEngine::showSprite(Graphics::Surface *backAnimSurface, int destX, int destY) { +bool PrinceEngine::spriteCheck(Graphics::Surface *backAnimSurface, int destX, int destY) { int sprWidth = backAnimSurface->w; int sprHeight = backAnimSurface->h; destX -= _picWindowX; @@ -726,25 +726,41 @@ void PrinceEngine::showSprite(Graphics::Surface *backAnimSurface, int destX, int if (destX < 0) { if (destX + sprWidth < 1) { //x2 is negative - out of window - return; + return false; } } // if x1 is outside of screen on right side if (destX >= kNormalWidth) { - return; + return false; } if (destY < 0) { if (destY + sprHeight < 1) { //y2 is negative - out of window - return; + return false; } } if (destY >= kNormalHeight) { - return; + return false; } - _graph->drawTransparent(destX, destY, backAnimSurface); + return true; +} + +void PrinceEngine::showSprite(Graphics::Surface *backAnimSurface, int destX, int destY) { + if (spriteCheck(backAnimSurface, destX, destY)) { + destX -= _picWindowX; + destY -= _picWindowY; + _graph->drawTransparent(destX, destY, backAnimSurface); + } +} + +void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY) { + if (spriteCheck(shadowSurface, destX, destY)) { + destX -= _picWindowX; + destY -= _picWindowY; + _graph->drawAsShadow(destX, destY, shadowSurface, _graph->_shadowTable70); + } } void PrinceEngine::showBackAnims() { @@ -873,6 +889,7 @@ void PrinceEngine::showBackAnims() { _backAnimList[i].backAnims[activeSubAnim]._showFrame = _backAnimList[i].backAnims[activeSubAnim]._frame; //ShowFrameCode + //ShowAnimFrame int phaseCount = _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount(); int frameCount = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrameCount(); int phase = _backAnimList[i].backAnims[activeSubAnim]._showFrame; @@ -886,7 +903,18 @@ void PrinceEngine::showBackAnims() { backAnimSurface->free(); delete backAnimSurface; } + //ShowFrameCodeShadow + //ShowAnimFrameShadow + if (_backAnimList[i].backAnims[activeSubAnim]._shadowData != nullptr) { + int shadowPhaseFrameIndex = _backAnimList[i].backAnims[activeSubAnim]._shadowData->getPhaseFrameIndex(phase); + int shadowX = _backAnimList[i].backAnims[activeSubAnim]._shadowData->getBaseX() + _backAnimList[i].backAnims[activeSubAnim]._shadowData->getPhaseOffsetX(phase); + int shadowY = _backAnimList[i].backAnims[activeSubAnim]._shadowData->getBaseY() + _backAnimList[i].backAnims[activeSubAnim]._shadowData->getPhaseOffsetY(phase); + Graphics::Surface *shadowSurface = _backAnimList[i].backAnims[activeSubAnim]._shadowData->getFrame(shadowPhaseFrameIndex); //still with memory leak + showSpriteShadow(shadowSurface, shadowX, shadowY); + shadowSurface->free(); + delete shadowSurface; + } } } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 0ced4b650359..034255290bb5 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -110,7 +110,6 @@ struct BASA { struct Anim { BASA _basaData; int32 _addr; //animation adress - //int32 _seq; int16 _usage; int16 _state; // state of animation: 0 - turning on, 1 - turning off int16 _flags; @@ -128,7 +127,6 @@ struct Anim { int16 _currW; int16 _currH; int16 _packFlag; - int32 _shadow; int32 _currShadowFrame; int16 _packShadowFlag; int32 _shadowBack; @@ -225,7 +223,9 @@ class PrinceEngine : public Engine { void init(); void showLogo(); void showBackAnims(); + bool spriteCheck(Graphics::Surface *backAnimSurface, int destX, int destY); void showSprite(Graphics::Surface *backAnimSurface, int destX, int destY); + void showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY); void makeShadowTable(int brightness); uint32 getTextWidth(const char *s); diff --git a/engines/prince/script.h b/engines/prince/script.h index b05d5ca84d27..5f0f1e139ea1 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -64,7 +64,6 @@ class Room { int _pullClose; int _talk; int _give; - //Room_Pad db 64-(Room_Pad-Room_Mobs) dup (0) ??? bool loadFromStream(Common::SeekableReadStream &stream); bool loadRoom(byte *roomData); From 63834499f78cd9b1513344d2cd2b84bbae9e9b0e Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 30 May 2014 19:25:11 +0200 Subject: [PATCH 114/374] PRINCE: installSingleBackAnim and showBackAnims clean up --- engines/prince/prince.cpp | 8 ++++---- engines/prince/script.cpp | 24 +----------------------- 2 files changed, 5 insertions(+), 27 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 8b294eb3352e..a46393f94ced 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -778,7 +778,7 @@ void PrinceEngine::showBackAnims() { int rnd = _randomSource.getRandomNumber(_backAnimList[i]._seq._anims - 2); rnd++; _backAnimList[i]._seq._currRelative = rnd; - _backAnimList[i]._seq._current = rnd; // or nr of animation from lst + _backAnimList[i]._seq._current = _backAnimList[i].backAnims[rnd]._basaData._num; activeSubAnim = rnd; } //only_1_type_2 @@ -835,7 +835,7 @@ void PrinceEngine::showBackAnims() { rnd = _randomSource.getRandomNumber(_backAnimList[i]._seq._anims - 1); } while (rnd == _backAnimList[i]._seq._currRelative); _backAnimList[i]._seq._currRelative = rnd; - _backAnimList[i]._seq._current = rnd; // or nr of animation from lst + _backAnimList[i]._seq._current = _backAnimList[i].backAnims[rnd]._basaData._num; activeSubAnim = rnd; //only_1_type_1: //SetBackAnim @@ -855,7 +855,7 @@ void PrinceEngine::showBackAnims() { } else if (_backAnimList[i]._seq._type == 2) { if (_backAnimList[i]._seq._currRelative != 0) { _backAnimList[i]._seq._currRelative = 0; - _backAnimList[i]._seq._current = 0; // or nr of animation from lst + _backAnimList[i]._seq._current = _backAnimList[i].backAnims[0]._basaData._num; activeSubAnim = 0; //only_1_type_1 //SetBackAnim @@ -875,7 +875,7 @@ void PrinceEngine::showBackAnims() { } else if (_backAnimList[i]._seq._type == 3) { //not_type_2 _backAnimList[i]._seq._currRelative = 0; - _backAnimList[i]._seq._current = 0; // or nr of animation from lst + _backAnimList[i]._seq._current = _backAnimList[i].backAnims[0]._basaData._num; _backAnimList[i]._seq._counter = 0; int rnd = _randomSource.getRandomNumber(_backAnimList[i]._seq._data - 1); _backAnimList[i]._seq._data2 = rnd; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 7806bf04bb50..48617f16f599 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -222,12 +222,6 @@ void Script::installSingleBackAnim(Common::Array &_backanimList, newAnim._basaData._num = READ_UINT16(&_data[animOffset + 28 + i * 8]); newAnim._basaData._start = READ_UINT16(&_data[animOffset + 28 + i * 8 + 2]); newAnim._basaData._end = READ_UINT16(&_data[animOffset + 28 + i * 8 + 4]); - if (newAnim._basaData._start != -1) { - debug("start1: %d", newAnim._basaData._start); - } - if (newAnim._basaData._end != -1) { - debug("end1: %d", newAnim._basaData._end); - } int animNumber = newAnim._basaData._num; const Common::String animName = Common::String::format("AN%02d", animNumber); const Common::String shadowName = Common::String::format("AN%02dS", animNumber); @@ -238,7 +232,6 @@ void Script::installSingleBackAnim(Common::Array &_backanimList, delete newAnim._shadowData; newAnim._shadowData = nullptr; } - //newAnim._seq = 0; newAnim._usage = 0; newAnim._state = 0; // enabled if ((_vm->_animList[animNumber]._flags & 4) != 0) { @@ -251,7 +244,6 @@ void Script::installSingleBackAnim(Common::Array &_backanimList, } newAnim._flags = _vm->_animList[animNumber]._flags; newAnim._lastFrame = _vm->_animList[animNumber]._endPhase; - debug("lastFrame: %d", _vm->_animList[animNumber]._endPhase); newAnim._loopFrame = _vm->_animList[animNumber]._loopPhase; newAnim._loopType = _vm->_animList[animNumber]._loopType; newAnim._nextAnim = _vm->_animList[animNumber]._nextAnim; @@ -265,40 +257,26 @@ void Script::installSingleBackAnim(Common::Array &_backanimList, newAnim._packFlag = 0; newAnim._shadowBack = _vm->_animList[animNumber]._type; newBackgroundAnim.backAnims.push_back(newAnim); - debug("%d - animNo: %d", i, animNumber); } newBackgroundAnim._seq._type = READ_UINT32(&_data[animOffset]); - debug("type: %d", newBackgroundAnim._seq._type); newBackgroundAnim._seq._data = READ_UINT32(&_data[animOffset + 4]); - //debug("data: %d", newBackgroundAnim._seq._data); newBackgroundAnim._seq._anims = READ_UINT32(&_data[animOffset + 8]); - anims = newBackgroundAnim._seq._anims; - debug("anims: %d", newBackgroundAnim._seq._anims); - //newBackgroundAnim._seq._current = READ_UINT32(&_data[animOffset + 12]); - newBackgroundAnim._seq._current = 0; // nr on list like now or should it be fileNr of anim - check it - //debug("current: %d", newBackgroundAnim._seq._current); - //newBackgroundAnim._seq._counter = READ_UINT32(&_data[animOffset + 16]); + newBackgroundAnim._seq._current = newBackgroundAnim.backAnims[0]._basaData._num; newBackgroundAnim._seq._counter = 0; - //debug("counter: %d", newBackgroundAnim._seq._counter); - //newBackgroundAnim._seq._currRelative = READ_UINT32(&_data[animOffset + 20]); newBackgroundAnim._seq._currRelative = 0; - //debug("currRelative: %d", newBackgroundAnim._seq._currRelative); newBackgroundAnim._seq._data2 = READ_UINT32(&_data[animOffset + 24]); - //debug("data2: %d", newBackgroundAnim._seq._data2); int start = newBackgroundAnim.backAnims[0]._basaData._start; // BASA_Start of first frame int end = newBackgroundAnim.backAnims[0]._basaData._end; //BASA_End of first frame if (start != -1) { - debug("start2: %d", start); newBackgroundAnim.backAnims[0]._frame = start; newBackgroundAnim.backAnims[0]._showFrame = start; newBackgroundAnim.backAnims[0]._loopFrame = start; } if (end != -1) { - debug("end2: %d", end); newBackgroundAnim.backAnims[0]._lastFrame = end; } From a2b1f2fb7bac421074aee600f86900162be9c834 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 30 May 2014 19:37:33 +0200 Subject: [PATCH 115/374] PRINCE: Warings fix, drawAsShadow update - kShadowColor to graphics.h --- engines/prince/graphics.cpp | 2 +- engines/prince/graphics.h | 2 ++ engines/prince/hero.cpp | 6 +++--- engines/prince/hero.h | 4 +--- engines/prince/prince.cpp | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 6265d9476606..5bcadc442aaf 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -93,7 +93,7 @@ void GraphicsMan::drawAsShadow(int32 posX, int32 posY, const Graphics::Surface * for (int y = 0; y < s->h; y++) { for (int x = 0; x < s->w; x++) { byte pixel = *((byte*)s->getBasePtr(x, y)); - if (pixel != 255) { + if (pixel == kShadowColor) { if (x + posX < _frontScreen->w && x + posX >= 0) { if (y + posY < _frontScreen->h && y + posY >= 0) { byte *background = (byte *)_frontScreen->getBasePtr(x + posX, y + posY); diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index fea7d14744ae..af2bfe716dff 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -54,6 +54,8 @@ class GraphicsMan byte *_shadowTable70; byte *_shadowTable50; + static const byte kShadowColor = 191; + private: PrinceEngine *_vm; diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 58f729a73e81..6576901838c3 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -245,7 +245,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { for (int x = 0; x < _frameXSize; x++, dst++, src++) { if (*src != 0xFF) { - *dst = kShadowColor; + *dst = _graph->kShadowColor; } else { *dst = *src; } @@ -397,7 +397,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { if (shadZoomX < 0 && _scaleValue != 10000) { shadZoomX += _scaleValue; } else { - if (*shadowHero == kShadowColor) { + if (*shadowHero == _graph->kShadowColor) { if ((shadBitMaskCopyTrans & _shadowBitmap[shadBitAddrCopyTrans]) != 0) { if (shadWallDown == 0) { if ((shadBitMaskCopyTrans & _shadowBitmap[shadBitAddrCopyTrans + kShadowBitmapSize]) != 0) { @@ -455,7 +455,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { shadZoomXWall += _scaleValue; } else { //point_ok: - if (*shadowHero == kShadowColor) { + if (*shadowHero == _graph->kShadowColor) { if ((shadBitMaskWallCopyTrans & _shadowBitmap[shadBitAddrWallCopyTrans + kShadowBitmapSize]) != 0) { *background = *(sprShadow + *background); } diff --git a/engines/prince/hero.h b/engines/prince/hero.h index c430cc3861e9..00a81bdc7e47 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -47,8 +47,6 @@ class Hero { static const int32 kShadowBitmapSize = kMaxPicWidth * kMaxPicHeight / 8; static const int16 kScreenWidth = 640; - static const byte kShadowColor = 191; - enum State { STAY = 0, TURN = 1, @@ -163,7 +161,7 @@ class Hero { // DestDir // LeftRight previous left/right direction // UpDown previous up/down direction - uint _phase; // Phase animation phase + int32 _phase; // Phase animation phase // Step x/y step size depends on direction // MaxBoredom stand still timeout int16 _boredomTime;// Boredom current boredom time in frames diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index a46393f94ced..859db8c3e303 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -117,7 +117,7 @@ PrinceEngine::~PrinceEngine() { for (uint i = 0; i < _backAnimList.size(); i++) { int anims = _backAnimList[i]._seq._anims != 0 ? _backAnimList[i]._seq._anims : 1; - for (uint j = 0; j < anims; j++) { + for (int j = 0; j < anims; j++) { delete _backAnimList[i].backAnims[j]._animData; delete _backAnimList[i].backAnims[j]._shadowData; } @@ -328,9 +328,9 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); _room->loadRoom(_script->getRoomOffset(_locationNr)); - for (uint32 i = 0; i < _backAnimList.size(); i++) { + for (uint i = 0; i < _backAnimList.size(); i++) { int anims = _backAnimList[i]._seq._anims != 0 ? _backAnimList[i]._seq._anims : 1; - for (uint32 j = 0; j < anims; j++) { + for (int j = 0; j < anims; j++) { delete _backAnimList[i].backAnims[j]._animData; delete _backAnimList[i].backAnims[j]._shadowData; } From 775944de6217c85d139e226a00ca700e81d4753d Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 30 May 2014 19:44:43 +0200 Subject: [PATCH 116/374] PRINCE: clearBackAnimList function implementation --- engines/prince/prince.cpp | 33 ++++++++++++++------------------- engines/prince/prince.h | 2 +- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 859db8c3e303..74c9820e6a9a 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -115,15 +115,7 @@ PrinceEngine::~PrinceEngine() { } _objList.clear(); - for (uint i = 0; i < _backAnimList.size(); i++) { - int anims = _backAnimList[i]._seq._anims != 0 ? _backAnimList[i]._seq._anims : 1; - for (int j = 0; j < anims; j++) { - delete _backAnimList[i].backAnims[j]._animData; - delete _backAnimList[i].backAnims[j]._shadowData; - } - _backAnimList[i].backAnims.clear(); - } - _backAnimList.clear(); + clearBackAnimList(); for (uint i = 0; i < _mainHero->_moveSet.size(); i++) { delete _mainHero->_moveSet[i]; @@ -328,16 +320,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); _room->loadRoom(_script->getRoomOffset(_locationNr)); - for (uint i = 0; i < _backAnimList.size(); i++) { - int anims = _backAnimList[i]._seq._anims != 0 ? _backAnimList[i]._seq._anims : 1; - for (int j = 0; j < anims; j++) { - delete _backAnimList[i].backAnims[j]._animData; - delete _backAnimList[i].backAnims[j]._shadowData; - } - _backAnimList[i].backAnims.clear(); - } - _backAnimList.clear(); - + clearBackAnimList(); _script->installBackAnims(_backAnimList, _room->_backAnim); _graph->makeShadowTable(70, _graph->_shadowTable70); @@ -919,6 +902,18 @@ void PrinceEngine::showBackAnims() { } } +void PrinceEngine::clearBackAnimList() { + for (uint i = 0; i < _backAnimList.size(); i++) { + int anims = _backAnimList[i]._seq._anims != 0 ? _backAnimList[i]._seq._anims : 1; + for (int j = 0; j < anims; j++) { + delete _backAnimList[i].backAnims[j]._animData; + delete _backAnimList[i].backAnims[j]._shadowData; + } + _backAnimList[i].backAnims.clear(); + } + _backAnimList.clear(); +} + void PrinceEngine::drawScreen() { const Graphics::Surface *roomSurface = _roomBmp->getSurface(); if (roomSurface) { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 034255290bb5..5a32f8e580c0 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -201,7 +201,6 @@ class PrinceEngine : public Engine { Image::BitmapDecoder *_roomBmp; Common::Array _animList; - //Common::Array _backAnimList; Common::Array _backAnimList; Common::RandomSource _randomSource; @@ -223,6 +222,7 @@ class PrinceEngine : public Engine { void init(); void showLogo(); void showBackAnims(); + void clearBackAnimList(); bool spriteCheck(Graphics::Surface *backAnimSurface, int destX, int destY); void showSprite(Graphics::Surface *backAnimSurface, int destX, int destY); void showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY); From 4f291feadd7ee75b91213df677bf71f5f85e6700 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 30 May 2014 20:15:00 +0200 Subject: [PATCH 117/374] PRINCE: zoomBitmap update - loadZoom(), selectZoom() --- engines/prince/animation.cpp | 5 ----- engines/prince/animation.h | 1 - engines/prince/hero.cpp | 6 +++--- engines/prince/hero.h | 8 +++++--- engines/prince/prince.cpp | 20 ++++++++++++++++---- engines/prince/prince.h | 1 + 6 files changed, 25 insertions(+), 16 deletions(-) diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index 0aa5d464d1c0..a4df4e30cc6c 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -57,11 +57,6 @@ void Animation::clear() { } } -// TEMP -int16 Animation::getZoom(uint16 offset) const { - return READ_LE_UINT16(_data + offset); -} - // AH_Loop int16 Animation::getLoopCount() const { return READ_LE_UINT16(_data + 2); diff --git a/engines/prince/animation.h b/engines/prince/animation.h index 941f1ba6dd63..acf689e05f9b 100644 --- a/engines/prince/animation.h +++ b/engines/prince/animation.h @@ -48,7 +48,6 @@ class Animation { Graphics::Surface *getFrame(uint frameIndex); int16 getFrameWidth(uint frameIndex) const; int16 getFrameHeight(uint frameIndex) const; - int16 getZoom(uint16 offset) const; void clear(); private: diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 6576901838c3..b8e5780a4c8b 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -39,13 +39,13 @@ Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph) , _shadZoomFactor(0), _shadScaleValue(0), _shadLineLen(0), _shadDrawX(0), _shadDrawY(0) , _frameXSize(0), _frameYSize(0), _scaledFrameXSize(0), _scaledFrameYSize(0) { - _zoomBitmap = new Animation(); + _zoomBitmap = (byte *)malloc(kZoomBitmapLen); _shadowBitmap = (byte *)malloc(2 * kShadowBitmapSize); _shadowLine = new byte[kShadowLineArraySize]; } Hero::~Hero() { - delete _zoomBitmap; + free(_zoomBitmap); free(_shadowBitmap); delete[] _shadowLine; } @@ -552,7 +552,7 @@ void Hero::setScale(int8 zoomBitmapValue) { } void Hero::selectZoom() { - int8 zoomBitmapValue = _zoomBitmap->getZoom(_middleY / 4 * kZoomBitmapWidth + _middleX / 4); + int8 zoomBitmapValue = *(_zoomBitmap + _middleY / 4 * kZoomBitmapWidth + _middleX / 4); setScale(zoomBitmapValue); } diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 00a81bdc7e47..839907a574e4 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -38,11 +38,13 @@ class GraphicsMan; class Hero { public: - static const uint32 kMoveSetSize = 26; - static const int16 kZoomStep = 4; static const int16 kMaxPicWidth = 1280; static const int16 kMaxPicHeight = 480; + static const uint32 kMoveSetSize = 26; + static const int16 kZoomStep = 4; + static const int32 kZoomBitmapLen = kMaxPicHeight / kZoomStep * kMaxPicWidth / kZoomStep; static const int16 kZoomBitmapWidth = kMaxPicWidth / kZoomStep; + static const int16 kZoomBitmapHeight = kMaxPicHeight / kZoomStep; static const int16 kShadowLineArraySize = 2 * 1280 * 4; static const int32 kShadowBitmapSize = kMaxPicWidth * kMaxPicHeight / 8; static const int16 kScreenWidth = 640; @@ -178,7 +180,7 @@ class Hero { // AnimSet number of animation set Common::Array _moveSet; // MoveAnims MoveSet // TurnAnim ?? - Animation *_zoomBitmap; // change to sth else, not Animation ?? + byte *_zoomBitmap; byte *_shadowBitmap; byte *_shadowLine; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 74c9820e6a9a..5e1b49e48ea2 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -296,9 +296,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _graph->setPalette(_roomBmp->getPalette()); } - _mainHero->_zoomBitmap->clear(); - Resource::loadResource(_mainHero->_zoomBitmap, "zoom", false); - + loadZoom(_mainHero->_zoomBitmap, _mainHero->kZoomBitmapLen, "zoom"); loadShadow(_mainHero->_shadowBitmap, _mainHero->kShadowBitmapSize, "shadow", "shadow2"); _picWindowX = 0; @@ -475,8 +473,22 @@ bool PrinceEngine::loadAnim(uint16 animNr, bool loop) { return true; } -bool PrinceEngine::loadShadow(byte *shadowBitmap, uint32 dataSize, const char *resourceName1, const char *resourceName2) { +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; diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 5a32f8e580c0..8b840d3cabc2 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -176,6 +176,7 @@ class PrinceEngine : public Engine { bool loadAnim(uint16 animNr, bool loop); bool loadVoice(uint32 textSlot, uint32 sampleSlot, const Common::String &name); bool loadSample(uint32 sampleSlot, const Common::String &name); + bool loadZoom(byte *zoomBitmap, uint32 dataSize, const char *resourceName); bool loadShadow(byte *shadowBitmap, uint32 dataSize, const char *resourceName1, const char *resourceName2); void playSample(uint16 sampleId, uint16 loopType); From 16a6d99a861c75ff2a142cc604b5ea9d87063072 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 30 May 2014 22:05:40 +0200 Subject: [PATCH 118/374] PRINCE: loadOverlays(), checkNak() --- engines/prince/hero.cpp | 17 +++++++---------- engines/prince/hero.h | 1 - engines/prince/prince.cpp | 23 +++++++++++++++++++++++ engines/prince/prince.h | 15 +++++++++++++++ engines/prince/script.cpp | 33 +++++++++++++++++++++++++++++++-- engines/prince/script.h | 2 ++ 6 files changed, 78 insertions(+), 13 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index b8e5780a4c8b..2f984c18147f 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -140,10 +140,6 @@ int Hero::getScaledValue(int size) { } } -void Hero::checkNak() { - -} - Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) { Graphics::Surface *zoomedFrame = new Graphics::Surface(); zoomedFrame->create(_scaledFrameXSize, _scaledFrameYSize, Graphics::PixelFormat::createFormatCLUT8()); @@ -191,6 +187,7 @@ Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) { } void Hero::countDrawPosition() { + int16 tempMiddleX; int16 tempMiddleY; int16 baseX = _moveSet[_moveSetType]->getBaseX(); int16 baseY = _moveSet[_moveSetType]->getBaseY(); @@ -206,12 +203,12 @@ void Hero::countDrawPosition() { _scaledFrameYSize = getScaledValue(_frameYSize); //TODO - //int tempHeroHeight = scaledY; // not used? global? - //int width = scaledX / 2; - //tempMiddleX = _middleX - width; //eax - //int z = _middleY; //ebp - //int y = _middleY - scaledY; //ecx - //checkNak(); + int tempHeroHeight = _scaledFrameYSize; // not used? global? + int width = _frameXSize / 2; + tempMiddleX = _middleX - width; //eax + int z = _middleY; //ebp + int y = _middleY - _scaledFrameYSize; //ecx + _vm->checkNak(tempMiddleX, y, _scaledFrameXSize, _scaledFrameYSize, z); if (_zoomFactor != 0) { //notfullSize diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 839907a574e4..565212447b47 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -115,7 +115,6 @@ class Hero { int getScaledValue(int size); void selectZoom(); void countDrawPosition(); - void checkNak(); Graphics::Surface *zoomSprite(Graphics::Surface *heroFrame); void showHeroAnimFrame(); void line(int x1, int y1, int x2, int y2); diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 5e1b49e48ea2..beaa997184ee 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -318,6 +318,10 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); _room->loadRoom(_script->getRoomOffset(_locationNr)); + + _overlayList.clear(); + _script->loadOverlays(_overlayList, _room->_nak); + clearBackAnimList(); _script->installBackAnims(_backAnimList, _room->_backAnim); @@ -742,6 +746,25 @@ bool PrinceEngine::spriteCheck(Graphics::Surface *backAnimSurface, int destX, in return true; } +void PrinceEngine::checkNak(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 < _overlayList.size() ; i++) { + if (_overlayList[i]._state != 1 && _overlayList[i]._flags != 1) { + if (_overlayList[i]._z > z) { + if (_overlayList[i]._x1 <= x2 && _overlayList[i]._x2 >= x1) { + if (_overlayList[i]._y1 <= y2 && _overlayList[i]._y2 >= y1) { + _overlayList[i]._state = 1; + } + } + } + } + } +} + void PrinceEngine::showSprite(Graphics::Surface *backAnimSurface, int destX, int destY) { if (spriteCheck(backAnimSurface, destX, destY)) { destX -= _picWindowX; diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 8b840d3cabc2..988f468a72df 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -141,6 +141,18 @@ struct BackgroundAnim { Common::Array backAnims; }; +// Nak (PL - Nakladka) +struct Overlay { + int16 _state; // visible / invisible + int16 _flags; // turning on / turning off of an overlay + int16 _x1; + int16 _y1; + int16 _x2; + int16 _y2; + int16 _z; + int16 _number; // number of mask for background recreating +}; + struct DebugChannel { enum Type { @@ -209,6 +221,8 @@ class PrinceEngine : public Engine { static const int16 kNormalWidth = 640; static const int16 kNormalHeight = 480; + void checkNak(int x1, int y1, int sprWidth, int sprHeight, int z); + int testAnimNr; int testAnimFrame; @@ -255,6 +269,7 @@ class PrinceEngine : public Engine { Animation *_zoom; Common::Array _mobList; Common::Array _objList; + Common::Array _overlayList; bool _flicLooped; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 48617f16f599..9798882bbcde 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -284,13 +284,42 @@ void Script::installSingleBackAnim(Common::Array &_backanimList, } } -void Script::installBackAnims(Common::Array &_backanimList, int offset) { +void Script::installBackAnims(Common::Array &backanimList, int offset) { for (uint i = 0; i < 64; i++) { - installSingleBackAnim(_backanimList, offset); + installSingleBackAnim(backanimList, offset); offset += 4; } } +void Script::loadOverlays(Common::Array &overlayList, int offset) { + Overlay tempOverlay; + while (1) { + tempOverlay._state = READ_UINT32(&_data[offset]); + if (tempOverlay._state == -1) { + break; + } + debug("tempOverlay._state: %d", tempOverlay._state); + tempOverlay._flags = READ_UINT32(&_data[offset + 2]); + debug("tempOverlay._flags: %d", tempOverlay._flags); + tempOverlay._x1 = READ_UINT32(&_data[offset + 4]); + debug("tempOverlay._x1: %d", tempOverlay._x1); + tempOverlay._y1 = READ_UINT32(&_data[offset + 6]); + debug("tempOverlay._y1: %d", tempOverlay._y1); + tempOverlay._x2 = READ_UINT32(&_data[offset + 8]); + debug("tempOverlay._x2: %d", tempOverlay._x2); + tempOverlay._y2 = READ_UINT32(&_data[offset + 10]); + debug("tempOverlay._y2: %d", tempOverlay._y2); + tempOverlay._z = READ_UINT32(&_data[offset + 12]); + debug("tempOverlay._z: %d", tempOverlay._z); + tempOverlay._number = READ_UINT32(&_data[offset + 14]); + debug("tempOverlay._number: %d\n", tempOverlay._number); + overlayList.push_back(tempOverlay); + offset += 16; // size of Overlay (Nak) struct + } + debug("NAK size: %d", sizeof(Overlay)); + debug("overlayList size: %d", overlayList.size()); +} + InterpreterFlags::InterpreterFlags() { resetAllFlags(); } diff --git a/engines/prince/script.h b/engines/prince/script.h index 5f0f1e139ea1..d0693ca11f66 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -39,6 +39,7 @@ class PrinceEngine; class Animation; struct Anim; struct BackgroundAnim; +struct Overlay; namespace Detail { template T LittleEndianReader(void *data); @@ -134,6 +135,7 @@ class Script { uint8 *getRoomOffset(int locationNr); void installBackAnims(Common::Array &_backanimList, int offset); void installSingleBackAnim(Common::Array &_backanimList, int offset); + void loadOverlays(Common::Array &overlayList, int offset); const char *getString(uint32 offset) { return (const char *)(&_data[offset]); From 4be66f5110a84bc4d6b8444e80fc846dbb88340b Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 30 May 2014 23:36:49 +0200 Subject: [PATCH 119/374] PRINCE: Rename Overlay to Mask, loadAllMasks update --- engines/prince/hero.cpp | 2 +- engines/prince/prince.cpp | 52 ++++++++++++++++++++---------- engines/prince/prince.h | 13 +++++--- engines/prince/script.cpp | 66 +++++++++++++++++++++++++-------------- engines/prince/script.h | 6 ++-- 5 files changed, 91 insertions(+), 48 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 2f984c18147f..51ba4529fe61 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -208,7 +208,7 @@ void Hero::countDrawPosition() { tempMiddleX = _middleX - width; //eax int z = _middleY; //ebp int y = _middleY - _scaledFrameYSize; //ecx - _vm->checkNak(tempMiddleX, y, _scaledFrameXSize, _scaledFrameYSize, z); + _vm->checkMasks(tempMiddleX, y, _scaledFrameXSize, _scaledFrameYSize, z); if (_zoomFactor != 0) { //notfullSize diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index beaa997184ee..36f0ea7bc8fd 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -299,29 +299,32 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { loadZoom(_mainHero->_zoomBitmap, _mainHero->kZoomBitmapLen, "zoom"); loadShadow(_mainHero->_shadowBitmap, _mainHero->kShadowBitmapSize, "shadow", "shadow2"); - _picWindowX = 0; - _mobList.clear(); Resource::loadResource(_mobList, "mob.lst", false); + _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); - _animList.clear(); - Resource::loadResource(_animList, "anim.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; _mainHero->_lightX = _script->getLightX(_locationNr); _mainHero->_lightY = _script->getLightY(_locationNr); _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); - _room->loadRoom(_script->getRoomOffset(_locationNr)); - - _overlayList.clear(); - _script->loadOverlays(_overlayList, _room->_nak); - clearBackAnimList(); _script->installBackAnims(_backAnimList, _room->_backAnim); @@ -746,18 +749,19 @@ bool PrinceEngine::spriteCheck(Graphics::Surface *backAnimSurface, int destX, in return true; } -void PrinceEngine::checkNak(int x1, int y1, int sprWidth, int sprHeight, int z) { +// 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 < _overlayList.size() ; i++) { - if (_overlayList[i]._state != 1 && _overlayList[i]._flags != 1) { - if (_overlayList[i]._z > z) { - if (_overlayList[i]._x1 <= x2 && _overlayList[i]._x2 >= x1) { - if (_overlayList[i]._y1 <= y2 && _overlayList[i]._y2 >= y1) { - _overlayList[i]._state = 1; + for (uint i = 0; i < _maskList.size() ; i++) { + if (_maskList[i]._state != 1 && _maskList[i]._flags != 1) { + 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; } } } @@ -765,6 +769,22 @@ void PrinceEngine::checkNak(int x1, int y1, int sprWidth, int sprHeight, int z) } } +// InsertNakladki +void PrinceEngine::insertMasks() { + for (uint i = 0; i < _maskList.size(); i++) { + if (_maskList[i]._state == 1) { + showMask(i); + } + } +} + +// ShowNak +void PrinceEngine::showMask(int maskNr) { + if (_maskList[maskNr]._flags == 0) { + + } +} + void PrinceEngine::showSprite(Graphics::Surface *backAnimSurface, int destX, int destY) { if (spriteCheck(backAnimSurface, destX, destY)) { destX -= _picWindowX; diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 988f468a72df..68a4159be28c 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -85,7 +85,7 @@ struct AnimListItem { int16 _y; uint16 _loopType; uint16 _nextAnim; // number of animation to do for loop = 3 - uint16 _flags; // byte 0 - draw overlays, byte 1 - draw in front of overlay, byte 2 - load but turn off drawing + uint16 _flags; // byte 0 - draw masks, byte 1 - draw in front of mask, byte 2 - load but turn off drawing bool loadFromStream(Common::SeekableReadStream &stream); }; @@ -142,15 +142,16 @@ struct BackgroundAnim { }; // Nak (PL - Nakladka) -struct Overlay { +struct Mask { int16 _state; // visible / invisible - int16 _flags; // turning on / turning off of an overlay + int16 _flags; // turning on / turning off of an mask int16 _x1; int16 _y1; int16 _x2; int16 _y2; int16 _z; int16 _number; // number of mask for background recreating + byte *_data; }; struct DebugChannel { @@ -221,7 +222,9 @@ class PrinceEngine : public Engine { static const int16 kNormalWidth = 640; static const int16 kNormalHeight = 480; - void checkNak(int x1, int y1, int sprWidth, int sprHeight, int z); + void checkMasks(int x1, int y1, int sprWidth, int sprHeight, int z); + void insertMasks(); + void showMask(int maskNr); int testAnimNr; int testAnimFrame; @@ -269,7 +272,7 @@ class PrinceEngine : public Engine { Animation *_zoom; Common::Array _mobList; Common::Array _objList; - Common::Array _overlayList; + Common::Array _maskList; bool _flicLooped; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 9798882bbcde..9f2f54a74e48 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -291,33 +291,53 @@ void Script::installBackAnims(Common::Array &backanimList, int o } } -void Script::loadOverlays(Common::Array &overlayList, int offset) { - Overlay tempOverlay; +bool Script::loadAllMasks(Common::Array &maskList, int offset) { + Mask tempMask; while (1) { - tempOverlay._state = READ_UINT32(&_data[offset]); - if (tempOverlay._state == -1) { + tempMask._state = READ_UINT32(&_data[offset]); + if (tempMask._state == -1) { break; } - debug("tempOverlay._state: %d", tempOverlay._state); - tempOverlay._flags = READ_UINT32(&_data[offset + 2]); - debug("tempOverlay._flags: %d", tempOverlay._flags); - tempOverlay._x1 = READ_UINT32(&_data[offset + 4]); - debug("tempOverlay._x1: %d", tempOverlay._x1); - tempOverlay._y1 = READ_UINT32(&_data[offset + 6]); - debug("tempOverlay._y1: %d", tempOverlay._y1); - tempOverlay._x2 = READ_UINT32(&_data[offset + 8]); - debug("tempOverlay._x2: %d", tempOverlay._x2); - tempOverlay._y2 = READ_UINT32(&_data[offset + 10]); - debug("tempOverlay._y2: %d", tempOverlay._y2); - tempOverlay._z = READ_UINT32(&_data[offset + 12]); - debug("tempOverlay._z: %d", tempOverlay._z); - tempOverlay._number = READ_UINT32(&_data[offset + 14]); - debug("tempOverlay._number: %d\n", tempOverlay._number); - overlayList.push_back(tempOverlay); - offset += 16; // size of Overlay (Nak) struct + debug("tempMask._state: %d", tempMask._state); + tempMask._flags = READ_UINT32(&_data[offset + 2]); + debug("tempMask._flags: %d", tempMask._flags); + tempMask._x1 = READ_UINT32(&_data[offset + 4]); + debug("tempMask._x1: %d", tempMask._x1); + tempMask._y1 = READ_UINT32(&_data[offset + 6]); + debug("tempMask._y1: %d", tempMask._y1); + tempMask._x2 = READ_UINT32(&_data[offset + 8]); + debug("tempMask._x2: %d", tempMask._x2); + tempMask._y2 = READ_UINT32(&_data[offset + 10]); + debug("tempMask._y2: %d", tempMask._y2); + tempMask._z = READ_UINT32(&_data[offset + 12]); + debug("tempMask._z: %d", tempMask._z); + tempMask._number = READ_UINT32(&_data[offset + 14]); + debug("tempMask._number: %d\n", tempMask._number); + + const Common::String msStreamName = Common::String::format("MS%02d", tempMask._number); + Common::SeekableReadStream *msStream = SearchMan.createReadStreamForMember(msStreamName); + if (!msStream) { + error("Can't load %s", msStreamName.c_str()); + delete msStream; + return false; + } + uint32 dataSize = msStream->size(); + if (dataSize != -1) { + tempMask._data = (byte *)malloc(dataSize); + if (msStream->read(tempMask._data, dataSize) != dataSize) { + free(tempMask._data); + delete msStream; + return false; + } + delete msStream; + } + + maskList.push_back(tempMask); + offset += 16; // size of tempMask (Nak) struct } - debug("NAK size: %d", sizeof(Overlay)); - debug("overlayList size: %d", overlayList.size()); + debug("Mask size: %d", sizeof(tempMask)); + debug("maskList size: %d", maskList.size()); + return true; } InterpreterFlags::InterpreterFlags() { diff --git a/engines/prince/script.h b/engines/prince/script.h index d0693ca11f66..4b9f85a61ec3 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -39,7 +39,7 @@ class PrinceEngine; class Animation; struct Anim; struct BackgroundAnim; -struct Overlay; +struct Mask; namespace Detail { template T LittleEndianReader(void *data); @@ -54,7 +54,7 @@ class Room { int _mobs; // mob flag offset int _backAnim; // offset to array of animation numbers int _obj; // offset to array of object numbers - int _nak; // offset to array of overlays + int _nak; // offset to array of masks int _itemUse; int _itemGive; int _walkTo; // offset to array of WALKTO events or 0 @@ -135,7 +135,7 @@ class Script { uint8 *getRoomOffset(int locationNr); void installBackAnims(Common::Array &_backanimList, int offset); void installSingleBackAnim(Common::Array &_backanimList, int offset); - void loadOverlays(Common::Array &overlayList, int offset); + bool loadAllMasks(Common::Array &maskList, int offset); const char *getString(uint32 offset) { return (const char *)(&_data[offset]); From dab83cc3ebe13ec604ba117ad163bc8a005bc7b2 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 31 May 2014 16:45:10 +0200 Subject: [PATCH 120/374] PRINCE: showMask, drawMask update --- engines/prince/graphics.cpp | 14 ++++++++++++++ engines/prince/graphics.h | 1 + engines/prince/prince.cpp | 14 +++++++++----- engines/prince/prince.h | 25 +++++++++++++++++++++++-- engines/prince/script.cpp | 8 ++++++-- 5 files changed, 53 insertions(+), 9 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 5bcadc442aaf..93b558a03b12 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -89,6 +89,20 @@ void GraphicsMan::drawTransparent(int32 posX, int32 posY, const Graphics::Surfac change(); } +void GraphicsMan::drawMask(int32 posX, int32 posY, int32 width, int32 height, byte *maskData, const Graphics::Surface *originalRoomSurface) { + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + if (x + posX < _frontScreen->w && x + posX >= 0) { + if (y + posY < _frontScreen->h && y + posY >= 0) { + byte orgPixel = *((byte*)originalRoomSurface->getBasePtr(x + posX, y + posY)); + *((byte*)_frontScreen->getBasePtr(x + posX, y + posY)) = orgPixel; + } + } + } + } + change(); +} + void GraphicsMan::drawAsShadow(int32 posX, int32 posY, const Graphics::Surface *s, byte *shadowTable) { for (int y = 0; y < s->h; y++) { for (int x = 0; x < s->w; x++) { diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index af2bfe716dff..e6293bbeee74 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -46,6 +46,7 @@ class GraphicsMan void draw(uint16 x, uint16 y, const Graphics::Surface *s); void drawTransparent(int32 posX, int32 poxY, const Graphics::Surface *s); void drawAsShadow(int32 posX, int32 poxY, const Graphics::Surface *s, byte *shadowTable); + void drawMask(int32 posX, int32 posY, int32 width, int32 height, byte *maskData, const Graphics::Surface *originalRoomSurface); Graphics::Surface *_frontScreen; Graphics::Surface *_backScreen; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 36f0ea7bc8fd..e63986dc3c72 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -770,18 +770,18 @@ void PrinceEngine::checkMasks(int x1, int y1, int sprWidth, int sprHeight, int z } // InsertNakladki -void PrinceEngine::insertMasks() { +void PrinceEngine::insertMasks(const Graphics::Surface *originalRoomSurface) { for (uint i = 0; i < _maskList.size(); i++) { if (_maskList[i]._state == 1) { - showMask(i); + showMask(i, originalRoomSurface); } } } // ShowNak -void PrinceEngine::showMask(int maskNr) { +void PrinceEngine::showMask(int maskNr, const Graphics::Surface *originalRoomSurface) { if (_maskList[maskNr]._flags == 0) { - + _graph->drawMask(_maskList[maskNr]._x1, _maskList[maskNr]._y1, _maskList[maskNr]._width, _maskList[maskNr]._height, _maskList[maskNr].getMask(), originalRoomSurface); } } @@ -971,8 +971,9 @@ void PrinceEngine::clearBackAnimList() { void PrinceEngine::drawScreen() { const Graphics::Surface *roomSurface = _roomBmp->getSurface(); + Graphics::Surface visiblePart; if (roomSurface) { - const Graphics::Surface visiblePart = roomSurface->getSubArea(Common::Rect(_picWindowX, 0, roomSurface->w, roomSurface->h)); + visiblePart = roomSurface->getSubArea(Common::Rect(_picWindowX, 0, roomSurface->w, roomSurface->h)); _graph->draw(0, 0, &visiblePart); } @@ -1002,6 +1003,9 @@ void PrinceEngine::drawScreen() { */ showBackAnims(); + if (roomSurface) { + insertMasks(&visiblePart); + } playNextFrame(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 68a4159be28c..1a6fa14e0d0d 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -151,7 +151,28 @@ struct Mask { int16 _y2; int16 _z; int16 _number; // number of mask for background recreating + int16 _width; + int16 _height; byte *_data; + + int16 Mask::getX() const { + return READ_LE_UINT16(_data); + } + + int16 Mask::getY() const { + return READ_LE_UINT16(_data + 2); + } + + int16 Mask::getWidth() const { + return READ_LE_UINT16(_data + 4); + } + + int16 Mask::getHeight() const { + return READ_LE_UINT16(_data + 6); + } + byte *Mask::getMask() const { + return (byte *)(_data + 8); + } }; struct DebugChannel { @@ -223,8 +244,8 @@ class PrinceEngine : public Engine { static const int16 kNormalHeight = 480; void checkMasks(int x1, int y1, int sprWidth, int sprHeight, int z); - void insertMasks(); - void showMask(int maskNr); + void insertMasks(const Graphics::Surface *originalRoomSurface); + void showMask(int maskNr, const Graphics::Surface *originalRoomSurface); int testAnimNr; int testAnimFrame; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 9f2f54a74e48..13234971cdc8 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -312,7 +312,7 @@ bool Script::loadAllMasks(Common::Array &maskList, int offset) { tempMask._z = READ_UINT32(&_data[offset + 12]); debug("tempMask._z: %d", tempMask._z); tempMask._number = READ_UINT32(&_data[offset + 14]); - debug("tempMask._number: %d\n", tempMask._number); + debug("tempMask._number: %d", tempMask._number); const Common::String msStreamName = Common::String::format("MS%02d", tempMask._number); Common::SeekableReadStream *msStream = SearchMan.createReadStreamForMember(msStreamName); @@ -321,6 +321,7 @@ bool Script::loadAllMasks(Common::Array &maskList, int offset) { delete msStream; return false; } + uint32 dataSize = msStream->size(); if (dataSize != -1) { tempMask._data = (byte *)malloc(dataSize); @@ -331,9 +332,12 @@ bool Script::loadAllMasks(Common::Array &maskList, int offset) { } delete msStream; } + tempMask._width = tempMask.getHeight(); + tempMask._height = tempMask.getHeight(); + debug("width: %d, height: %d\n", tempMask._width, tempMask._height); maskList.push_back(tempMask); - offset += 16; // size of tempMask (Nak) struct + offset += 16; // size of Mask (Nak) struct } debug("Mask size: %d", sizeof(tempMask)); debug("maskList size: %d", maskList.size()); From 7874a4e7820378c8ca260f646e0ee8ee84bf6b9c Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 31 May 2014 20:57:46 +0200 Subject: [PATCH 121/374] PRINCE: drawMask progress, changes in spriteCheck --- engines/prince/graphics.cpp | 17 +++++++++++++-- engines/prince/hero.cpp | 2 +- engines/prince/prince.cpp | 41 ++++++++++++++++++++++++++++++++++--- engines/prince/prince.h | 3 ++- engines/prince/script.cpp | 3 ++- 5 files changed, 58 insertions(+), 8 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 93b558a03b12..4f55b5a23e19 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -90,15 +90,28 @@ void GraphicsMan::drawTransparent(int32 posX, int32 posY, const Graphics::Surfac } void GraphicsMan::drawMask(int32 posX, int32 posY, int32 width, int32 height, byte *maskData, const Graphics::Surface *originalRoomSurface) { + int maskWidth = width >> 3; + int maskPostion = 0; + int maskCounter = 128; for (int y = 0; y < height; y++) { + int tempMaskPostion = maskPostion; for (int x = 0; x < width; x++) { if (x + posX < _frontScreen->w && x + posX >= 0) { if (y + posY < _frontScreen->h && y + posY >= 0) { - byte orgPixel = *((byte*)originalRoomSurface->getBasePtr(x + posX, y + posY)); - *((byte*)_frontScreen->getBasePtr(x + posX, y + posY)) = orgPixel; + if ((maskData[tempMaskPostion] & maskCounter) != 0) { + byte orgPixel = *((byte*)originalRoomSurface->getBasePtr(x + posX, y + posY)); + *((byte*)_frontScreen->getBasePtr(x + posX, y + posY)) = orgPixel; + } + maskCounter >>= 1; + if (maskCounter == 0) { + maskCounter = 128; + tempMaskPostion++; + } } } } + maskPostion += maskWidth; + maskCounter = 128; } change(); } diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 51ba4529fe61..aeef68d4b2c0 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -203,7 +203,7 @@ void Hero::countDrawPosition() { _scaledFrameYSize = getScaledValue(_frameYSize); //TODO - int tempHeroHeight = _scaledFrameYSize; // not used? global? + //int tempHeroHeight = _scaledFrameYSize; // not used? global? int width = _frameXSize / 2; tempMiddleX = _middleX - width; //eax int z = _middleY; //ebp diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index e63986dc3c72..5b8903b49c9e 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -718,6 +718,35 @@ void PrinceEngine::showTexts() { } } +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; +} +/* bool PrinceEngine::spriteCheck(Graphics::Surface *backAnimSurface, int destX, int destY) { int sprWidth = backAnimSurface->w; int sprHeight = backAnimSurface->h; @@ -748,6 +777,7 @@ bool PrinceEngine::spriteCheck(Graphics::Surface *backAnimSurface, int destX, in return true; } +*/ // CheckNak void PrinceEngine::checkMasks(int x1, int y1, int sprWidth, int sprHeight, int z) { @@ -774,6 +804,7 @@ void PrinceEngine::insertMasks(const Graphics::Surface *originalRoomSurface) { for (uint i = 0; i < _maskList.size(); i++) { if (_maskList[i]._state == 1) { showMask(i, originalRoomSurface); + _maskList[i]._state = 0; // here or somewhere else? } } } @@ -781,12 +812,16 @@ void PrinceEngine::insertMasks(const Graphics::Surface *originalRoomSurface) { // ShowNak void PrinceEngine::showMask(int maskNr, const Graphics::Surface *originalRoomSurface) { if (_maskList[maskNr]._flags == 0) { - _graph->drawMask(_maskList[maskNr]._x1, _maskList[maskNr]._y1, _maskList[maskNr]._width, _maskList[maskNr]._height, _maskList[maskNr].getMask(), originalRoomSurface); + 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; + _graph->drawMask(destX, destY, _maskList[maskNr]._width, _maskList[maskNr]._height, _maskList[maskNr].getMask(), originalRoomSurface); + } } } void PrinceEngine::showSprite(Graphics::Surface *backAnimSurface, int destX, int destY) { - if (spriteCheck(backAnimSurface, destX, destY)) { + if (spriteCheck(backAnimSurface->w, backAnimSurface->h, destX, destY)) { destX -= _picWindowX; destY -= _picWindowY; _graph->drawTransparent(destX, destY, backAnimSurface); @@ -794,7 +829,7 @@ void PrinceEngine::showSprite(Graphics::Surface *backAnimSurface, int destX, int } void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY) { - if (spriteCheck(shadowSurface, destX, destY)) { + if (spriteCheck(shadowSurface->w, shadowSurface->h, destX, destY)) { destX -= _picWindowX; destY -= _picWindowY; _graph->drawAsShadow(destX, destY, shadowSurface, _graph->_shadowTable70); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 1a6fa14e0d0d..6747f5cab9db 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -30,6 +30,7 @@ #include "common/textconsole.h" #include "common/rect.h" #include "common/events.h" +#include "common/endian.h" #include "image/bmp.h" @@ -262,7 +263,7 @@ class PrinceEngine : public Engine { void showLogo(); void showBackAnims(); void clearBackAnimList(); - bool spriteCheck(Graphics::Surface *backAnimSurface, int destX, int destY); + bool spriteCheck(int sprWidth, int sprHeight, int destX, int destY); void showSprite(Graphics::Surface *backAnimSurface, int destX, int destY); void showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY); void makeShadowTable(int brightness); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 13234971cdc8..91da9abdc53e 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -332,9 +332,10 @@ bool Script::loadAllMasks(Common::Array &maskList, int offset) { } delete msStream; } - tempMask._width = tempMask.getHeight(); + tempMask._width = tempMask.getWidth(); tempMask._height = tempMask.getHeight(); debug("width: %d, height: %d\n", tempMask._width, tempMask._height); + debug("dataSize: %d", dataSize); maskList.push_back(tempMask); offset += 16; // size of Mask (Nak) struct From 421b27f2c7bc20ed90fbee36d3873145a5bb2f6a Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 31 May 2014 22:37:51 +0200 Subject: [PATCH 122/374] PRINCE: drawMask() fix for wider locations, delete old spriteCheck --- engines/prince/graphics.cpp | 10 +++++----- engines/prince/prince.cpp | 32 -------------------------------- 2 files changed, 5 insertions(+), 37 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 4f55b5a23e19..46c52a86ca2c 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -102,13 +102,13 @@ void GraphicsMan::drawMask(int32 posX, int32 posY, int32 width, int32 height, by byte orgPixel = *((byte*)originalRoomSurface->getBasePtr(x + posX, y + posY)); *((byte*)_frontScreen->getBasePtr(x + posX, y + posY)) = orgPixel; } - maskCounter >>= 1; - if (maskCounter == 0) { - maskCounter = 128; - tempMaskPostion++; - } } } + maskCounter >>= 1; + if (maskCounter == 0) { + maskCounter = 128; + tempMaskPostion++; + } } maskPostion += maskWidth; maskCounter = 128; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 5b8903b49c9e..1c5aaa183453 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -746,38 +746,6 @@ bool PrinceEngine::spriteCheck(int sprWidth, int sprHeight, int destX, int destY return true; } -/* -bool PrinceEngine::spriteCheck(Graphics::Surface *backAnimSurface, int destX, int destY) { - int sprWidth = backAnimSurface->w; - int sprHeight = backAnimSurface->h; - 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) { From 806b633f553a51b976156b7f6653549716b80d0d Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 31 May 2014 22:55:22 +0200 Subject: [PATCH 123/374] PRINCE: _maskList memory clearing fix --- engines/prince/prince.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 1c5aaa183453..6a65ee162b5b 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -115,6 +115,11 @@ PrinceEngine::~PrinceEngine() { } _objList.clear(); + for (uint i = 0; i < _maskList.size(); i++) { + free(_maskList[i]._data); + } + _maskList.clear(); + clearBackAnimList(); for (uint i = 0; i < _mainHero->_moveSet.size(); i++) { From 0c798b234ec66abc1adc03c5662b7264551e8626 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 31 May 2014 22:57:55 +0200 Subject: [PATCH 124/374] PRINCE: loadAllMasks clean up --- engines/prince/script.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 91da9abdc53e..331e425a42c0 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -298,21 +298,13 @@ bool Script::loadAllMasks(Common::Array &maskList, int offset) { if (tempMask._state == -1) { break; } - debug("tempMask._state: %d", tempMask._state); tempMask._flags = READ_UINT32(&_data[offset + 2]); - debug("tempMask._flags: %d", tempMask._flags); tempMask._x1 = READ_UINT32(&_data[offset + 4]); - debug("tempMask._x1: %d", tempMask._x1); tempMask._y1 = READ_UINT32(&_data[offset + 6]); - debug("tempMask._y1: %d", tempMask._y1); tempMask._x2 = READ_UINT32(&_data[offset + 8]); - debug("tempMask._x2: %d", tempMask._x2); tempMask._y2 = READ_UINT32(&_data[offset + 10]); - debug("tempMask._y2: %d", tempMask._y2); tempMask._z = READ_UINT32(&_data[offset + 12]); - debug("tempMask._z: %d", tempMask._z); tempMask._number = READ_UINT32(&_data[offset + 14]); - debug("tempMask._number: %d", tempMask._number); const Common::String msStreamName = Common::String::format("MS%02d", tempMask._number); Common::SeekableReadStream *msStream = SearchMan.createReadStreamForMember(msStreamName); @@ -334,14 +326,10 @@ bool Script::loadAllMasks(Common::Array &maskList, int offset) { } tempMask._width = tempMask.getWidth(); tempMask._height = tempMask.getHeight(); - debug("width: %d, height: %d\n", tempMask._width, tempMask._height); - debug("dataSize: %d", dataSize); maskList.push_back(tempMask); offset += 16; // size of Mask (Nak) struct } - debug("Mask size: %d", sizeof(tempMask)); - debug("maskList size: %d", maskList.size()); return true; } From 9933505bf5ed72894bfa696ae5b2d4085dc1c242 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 31 May 2014 23:24:36 +0200 Subject: [PATCH 125/374] PRINCE: Mask struct - functions change --- engines/prince/prince.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 6747f5cab9db..443a5bd1482b 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -156,22 +156,22 @@ struct Mask { int16 _height; byte *_data; - int16 Mask::getX() const { + int16 getX() const { return READ_LE_UINT16(_data); } - int16 Mask::getY() const { + int16 getY() const { return READ_LE_UINT16(_data + 2); } - int16 Mask::getWidth() const { + int16 getWidth() const { return READ_LE_UINT16(_data + 4); } - int16 Mask::getHeight() const { + int16 getHeight() const { return READ_LE_UINT16(_data + 6); } - byte *Mask::getMask() const { + byte *getMask() const { return (byte *)(_data + 8); } }; From 6f19bd82f48ffb7c9f772c8b3112449df36ce6eb Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 1 Jun 2014 02:58:27 +0200 Subject: [PATCH 126/374] PRINCE: Object class update, showObjects() beginning --- engines/prince/graphics.cpp | 1 + engines/prince/object.cpp | 8 +++--- engines/prince/object.h | 10 +++++++- engines/prince/prince.cpp | 49 +++++++++++++++++++++++++++++++------ engines/prince/prince.h | 2 ++ 5 files changed, 58 insertions(+), 12 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 46c52a86ca2c..679885f7b83c 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -101,6 +101,7 @@ void GraphicsMan::drawMask(int32 posX, int32 posY, int32 width, int32 height, by if ((maskData[tempMaskPostion] & maskCounter) != 0) { byte orgPixel = *((byte*)originalRoomSurface->getBasePtr(x + posX, y + posY)); *((byte*)_frontScreen->getBasePtr(x + posX, y + posY)) = orgPixel; + //*((byte*)_frontScreen->getBasePtr(x + posX, y + posY)) = 0; // for debugging } } } diff --git a/engines/prince/object.cpp b/engines/prince/object.cpp index 9386eaa4963d..11c553ffbc3d 100644 --- a/engines/prince/object.cpp +++ b/engines/prince/object.cpp @@ -32,7 +32,9 @@ namespace Prince { -Object::Object() : _surface(NULL), _x(0), _y(0), _z(0), _overlay(0) { +Object::Object() : _surface(NULL), _x(0), _y(0), _z(0), _mask(0), + _zoomInSource(0), _zoomInLen(0), _zoomInAddr(0), _zoomInTime(0) +{ } Object::~Object() { @@ -73,12 +75,12 @@ bool Object::loadFromStream(Common::SeekableReadStream &stream) { loadSurface(*obStream); delete obStream; - _overlay = stream.readUint16LE(); + _mask = stream.readUint16LE(); _z = stream.readUint16LE(); stream.seek(pos + 16); - debug("Object x %d, y %d, z %d overlay %d", _x, _y, _z, _overlay); + debug("Object x %d, y %d, z %d overlay %d", _x, _y, _z, _mask); return true; } diff --git a/engines/prince/object.h b/engines/prince/object.h index 66f2a725f834..5bc7c580daad 100644 --- a/engines/prince/object.h +++ b/engines/prince/object.h @@ -33,9 +33,17 @@ class Object { Object(); ~Object(); + int32 _x; + int32 _y; + int32 _z; + int32 _mask; // or flags + int32 _zoomInSource; + int32 _zoomInLen; + int32 _zoomInAddr; + int32 _zoomInTime; + bool loadFromStream(Common::SeekableReadStream &stream); const Graphics::Surface *getSurface() const { return _surface; } - uint16 _x, _y, _z, _overlay; private: void loadSurface(Common::SeekableReadStream &stream); Graphics::Surface *_surface; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 6a65ee162b5b..a82fe9569dfc 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -977,6 +977,44 @@ void PrinceEngine::clearBackAnimList() { _backAnimList.clear(); } +void PrinceEngine::showObjects() { + if (!_objList.empty()) { + for (uint i = 0; i < _objList.size(); i++) { + if ((_objList[i]->_mask & 32768) != 0) { // 8000h + _objList[i]->_zoomInTime--; + if (_objList[i]->_zoomInTime == 0) { + _objList[i]->_mask &= 32767; //7FFFh + } else { + // doZoomIn(); + // mov edx, d [esi.Obj_ZoomInAddr] + } + } + if ((_objList[i]->_mask & 16384) != 0) { // 4000h + _objList[i]->_zoomInTime--; + if (_objList[i]->_zoomInTime == 0) { + _objList[i]->_mask &= 49151; //0BFFFh + } else { + // doZoomOut(); + // mov edx, d [esi.Obj_ZoomInAddr] + } + } + const Graphics::Surface *objSurface = _objList[i]->getSurface(); + if (spriteCheck(objSurface->w, objSurface->h, _objList[i]->_x, _objList[i]->_y)) { + if ((_objList[i]->_mask & 512) == 0) { // 0200h + int destX = _objList[i]->_x - _picWindowX; + int destY = _objList[i]->_y - _picWindowY; + _graph->drawTransparent(destX, destY, objSurface); + } else { + // showBackSprite(); + } + } + if ((_objList[i]->_mask & 1) != 0) { + checkMasks(_objList[i]->_x, _objList[i]->_y, objSurface->w, objSurface->h, _objList[i]->_z); + } + } + } +} + void PrinceEngine::drawScreen() { const Graphics::Surface *roomSurface = _roomBmp->getSurface(); Graphics::Surface visiblePart; @@ -1002,15 +1040,10 @@ void PrinceEngine::drawScreen() { delete mainHeroSurface; } - /* - if (!_objList.empty()) { - for (int i = 0; i < _objList.size(); i++) { - _graph->drawTransparent(_objList[i]->_x, _objList[i]->_y, _objList[i]->getSurface()); - } - } - */ - showBackAnims(); + + showObjects(); + if (roomSurface) { insertMasks(&visiblePart); } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 443a5bd1482b..15dfdb4b7b21 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -171,6 +171,7 @@ struct Mask { int16 getHeight() const { return READ_LE_UINT16(_data + 6); } + byte *getMask() const { return (byte *)(_data + 8); } @@ -266,6 +267,7 @@ class PrinceEngine : public Engine { bool spriteCheck(int sprWidth, int sprHeight, int destX, int destY); void showSprite(Graphics::Surface *backAnimSurface, int destX, int destY); void showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY); + void showObjects(); void makeShadowTable(int brightness); uint32 getTextWidth(const char *s); From b9e63a41a46e4366ccd97e9eb5ca6b2a2c782dc0 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 1 Jun 2014 04:25:01 +0200 Subject: [PATCH 127/374] PRINCE: Hero checkNak - small clean up --- engines/prince/hero.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index aeef68d4b2c0..ea786f289df9 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -201,13 +201,12 @@ void Hero::countDrawPosition() { _frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); _scaledFrameXSize = getScaledValue(_frameXSize); _scaledFrameYSize = getScaledValue(_frameYSize); - - //TODO + //int tempHeroHeight = _scaledFrameYSize; // not used? global? int width = _frameXSize / 2; - tempMiddleX = _middleX - width; //eax - int z = _middleY; //ebp - int y = _middleY - _scaledFrameYSize; //ecx + tempMiddleX = _middleX - width; + int z = _middleY; + int y = _middleY - _scaledFrameYSize; _vm->checkMasks(tempMiddleX, y, _scaledFrameXSize, _scaledFrameYSize, z); if (_zoomFactor != 0) { From 3864655978c9fd6af94122a8305a0cc69395e683 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 1 Jun 2014 04:26:41 +0200 Subject: [PATCH 128/374] PRINCE: checkNak for showBackAnims, beginning of Z axis for it --- engines/prince/prince.cpp | 19 +++++++++++++++++++ engines/prince/prince.h | 2 ++ 2 files changed, 21 insertions(+) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index a82fe9569dfc..77e21fbf8d90 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -942,8 +942,27 @@ void PrinceEngine::showBackAnims() { int phaseFrameIndex = _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseFrameIndex(phase); int x = _backAnimList[i].backAnims[activeSubAnim]._x + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetX(phase); int y = _backAnimList[i].backAnims[activeSubAnim]._y + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetY(phase); + int animFlag = _backAnimList[i].backAnims[activeSubAnim]._flags; + int checkMaskFlag = (animFlag & 1); + int maxFrontFlag = (animFlag & 2); + int specialZFlag = _backAnimList[i].backAnims[activeSubAnim]._nextAnim; + int z = _backAnimList[i].backAnims[activeSubAnim]._nextAnim; + int frameWidth = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrameWidth(phaseFrameIndex); + int frameHeight = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrameHeight(phaseFrameIndex); if (x != 0 || y != 0 || phaseCount != 1 || frameCount != 1) { // fix for room no. 5 - animation 8 (propably unnecessary anim) + if (checkMaskFlag != 0) { + if (_backAnimList[i].backAnims[activeSubAnim]._nextAnim == 0) { + z = y + frameHeight - 1; + } + checkMasks(x, y, frameWidth, frameHeight, z); + } + if (maxFrontFlag != 0) { + z = kMaxPicHeight + 1; + } + if (specialZFlag != 0) { + z = specialZFlag; + } Graphics::Surface *backAnimSurface = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrame(phaseFrameIndex); //still with memory leak showSprite(backAnimSurface, x, y); backAnimSurface->free(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 15dfdb4b7b21..b9e61f67d3a9 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -244,6 +244,8 @@ class PrinceEngine : public Engine { static const int16 kNormalWidth = 640; static const int16 kNormalHeight = 480; + static const int16 kMaxPicWidth = 1280; + static const int16 kMaxPicHeight = 480; void checkMasks(int x1, int y1, int sprWidth, int sprHeight, int z); void insertMasks(const Graphics::Surface *originalRoomSurface); From 5f222a55ef9c04e41c0bf66001e0e2511c4bbbdd Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 1 Jun 2014 14:28:48 +0200 Subject: [PATCH 129/374] PRINCE: Hero - checkMasks fix --- engines/prince/hero.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index ea786f289df9..4b582d6cc648 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -187,7 +187,6 @@ Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) { } void Hero::countDrawPosition() { - int16 tempMiddleX; int16 tempMiddleY; int16 baseX = _moveSet[_moveSetType]->getBaseX(); int16 baseY = _moveSet[_moveSetType]->getBaseY(); @@ -202,21 +201,16 @@ void Hero::countDrawPosition() { _scaledFrameXSize = getScaledValue(_frameXSize); _scaledFrameYSize = getScaledValue(_frameYSize); - //int tempHeroHeight = _scaledFrameYSize; // not used? global? - int width = _frameXSize / 2; - tempMiddleX = _middleX - width; - int z = _middleY; - int y = _middleY - _scaledFrameYSize; - _vm->checkMasks(tempMiddleX, y, _scaledFrameXSize, _scaledFrameYSize, z); - if (_zoomFactor != 0) { //notfullSize _drawX = _middleX - _scaledFrameXSize / 2; _drawY = tempMiddleY + 1 - _scaledFrameYSize; + _vm->checkMasks(_drawX, _drawY - 1, _scaledFrameXSize, _scaledFrameYSize, _middleY); } else { //fullSize _drawX = _middleX - _frameXSize / 2; _drawY = tempMiddleY + 1 - _frameYSize; + _vm->checkMasks(_drawX, _drawY - 1, _frameXSize, _frameYSize, _middleY); } } From 8b8329a214db34276bcc6231999d460ade6005f9 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 1 Jun 2014 14:35:50 +0200 Subject: [PATCH 130/374] PRINCE: clsMasks() --- engines/prince/prince.cpp | 11 ++++++++++- engines/prince/prince.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 77e21fbf8d90..22064b05afe4 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -772,12 +772,19 @@ void PrinceEngine::checkMasks(int x1, int y1, int sprWidth, int sprHeight, int z } } +void PrinceEngine::clsMasks() { + for (uint i = 0; i < _maskList.size(); i++) { + if (_maskList[i]._state == 1) { + _maskList[i]._state = 0; + } + } +} + // InsertNakladki void PrinceEngine::insertMasks(const Graphics::Surface *originalRoomSurface) { for (uint i = 0; i < _maskList.size(); i++) { if (_maskList[i]._state == 1) { showMask(i, originalRoomSurface); - _maskList[i]._state = 0; // here or somewhere else? } } } @@ -1042,6 +1049,8 @@ void PrinceEngine::drawScreen() { _graph->draw(0, 0, &visiblePart); } + clsMasks(); + if (_mainHero->_visible) { Graphics::Surface *mainHeroSurface = _mainHero->getSurface(); if (mainHeroSurface) { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index b9e61f67d3a9..1deb26f92625 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -250,6 +250,7 @@ class PrinceEngine : public Engine { void checkMasks(int x1, int y1, int sprWidth, int sprHeight, int z); void insertMasks(const Graphics::Surface *originalRoomSurface); void showMask(int maskNr, const Graphics::Surface *originalRoomSurface); + void clsMasks(); int testAnimNr; int testAnimFrame; From 8223124c095dc571849871d69ed37b214680b961 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 1 Jun 2014 14:39:11 +0200 Subject: [PATCH 131/374] PRINCE: clsMasks call in proper place --- engines/prince/prince.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 22064b05afe4..f83f7ad45b64 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1049,8 +1049,6 @@ void PrinceEngine::drawScreen() { _graph->draw(0, 0, &visiblePart); } - clsMasks(); - if (_mainHero->_visible) { Graphics::Surface *mainHeroSurface = _mainHero->getSurface(); if (mainHeroSurface) { @@ -1076,6 +1074,8 @@ void PrinceEngine::drawScreen() { insertMasks(&visiblePart); } + clsMasks(); + playNextFrame(); hotspot(); From 445229c196042e80de421d0f0e8fc7ba444dd144 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 1 Jun 2014 15:32:24 +0200 Subject: [PATCH 132/374] PRINCE: checkMasks for shadows in ShowBackAnims, Z axis value for them --- engines/prince/prince.cpp | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index f83f7ad45b64..afef9d460810 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -772,6 +772,7 @@ void PrinceEngine::checkMasks(int x1, int y1, int sprWidth, int sprHeight, int z } } +// ClsNak void PrinceEngine::clsMasks() { for (uint i = 0; i < _maskList.size(); i++) { if (_maskList[i]._state == 1) { @@ -956,20 +957,26 @@ void PrinceEngine::showBackAnims() { int z = _backAnimList[i].backAnims[activeSubAnim]._nextAnim; int frameWidth = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrameWidth(phaseFrameIndex); int frameHeight = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrameHeight(phaseFrameIndex); + int shadowZ = 0; if (x != 0 || y != 0 || phaseCount != 1 || frameCount != 1) { // fix for room no. 5 - animation 8 (propably unnecessary anim) + if (checkMaskFlag != 0) { if (_backAnimList[i].backAnims[activeSubAnim]._nextAnim == 0) { z = y + frameHeight - 1; } checkMasks(x, y, frameWidth, frameHeight, z); } - if (maxFrontFlag != 0) { - z = kMaxPicHeight + 1; - } + if (specialZFlag != 0) { z = specialZFlag; + } else if (maxFrontFlag != 0) { + z = kMaxPicHeight + 1; + } else { + z = y + frameHeight - 1; } + shadowZ = z; + Graphics::Surface *backAnimSurface = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrame(phaseFrameIndex); //still with memory leak showSprite(backAnimSurface, x, y); backAnimSurface->free(); @@ -982,6 +989,21 @@ void PrinceEngine::showBackAnims() { int shadowPhaseFrameIndex = _backAnimList[i].backAnims[activeSubAnim]._shadowData->getPhaseFrameIndex(phase); int shadowX = _backAnimList[i].backAnims[activeSubAnim]._shadowData->getBaseX() + _backAnimList[i].backAnims[activeSubAnim]._shadowData->getPhaseOffsetX(phase); int shadowY = _backAnimList[i].backAnims[activeSubAnim]._shadowData->getBaseY() + _backAnimList[i].backAnims[activeSubAnim]._shadowData->getPhaseOffsetY(phase); + int shadowFrameWidth = _backAnimList[i].backAnims[activeSubAnim]._shadowData->getFrameWidth(shadowPhaseFrameIndex); + int shadowFrameHeight = _backAnimList[i].backAnims[activeSubAnim]._shadowData->getFrameHeight(shadowPhaseFrameIndex); + + if (checkMaskFlag != 0) { + checkMasks(shadowX, shadowY, shadowFrameWidth, shadowFrameHeight, shadowY + shadowFrameWidth - 1); + } + + if (shadowZ == 0) { + if (maxFrontFlag != 0) { + shadowZ = kMaxPicHeight + 1; + } else { + shadowZ = shadowY + shadowFrameWidth - 1; + } + } + Graphics::Surface *shadowSurface = _backAnimList[i].backAnims[activeSubAnim]._shadowData->getFrame(shadowPhaseFrameIndex); //still with memory leak showSpriteShadow(shadowSurface, shadowX, shadowY); shadowSurface->free(); From 46ce47dbca3d046121b6aaa5f3cd4827e7bfe0a7 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 1 Jun 2014 20:44:04 +0200 Subject: [PATCH 133/374] PRINCE: Parallax bitmaps loading, showParallax() implementation --- engines/prince/module.mk | 3 +- engines/prince/object.cpp | 2 +- engines/prince/prince.cpp | 37 +++++++++++++--- engines/prince/prince.h | 6 ++- engines/prince/pscr.cpp | 90 +++++++++++++++++++++++++++++++++++++++ engines/prince/pscr.h | 53 +++++++++++++++++++++++ 6 files changed, 183 insertions(+), 8 deletions(-) create mode 100644 engines/prince/pscr.cpp create mode 100644 engines/prince/pscr.h diff --git a/engines/prince/module.mk b/engines/prince/module.mk index 228e5990e2eb..ad5b20aeb1b0 100644 --- a/engines/prince/module.mk +++ b/engines/prince/module.mk @@ -18,7 +18,8 @@ MODULE_OBJS = \ decompress.o \ hero.o \ hero_set.o \ - cursor.o + cursor.o \ + pscr.o # This module can be built as a plugin ifeq ($(ENABLE_PRINCE), DYNAMIC_PLUGIN) diff --git a/engines/prince/object.cpp b/engines/prince/object.cpp index 11c553ffbc3d..94d55b5716a0 100644 --- a/engines/prince/object.cpp +++ b/engines/prince/object.cpp @@ -80,7 +80,7 @@ bool Object::loadFromStream(Common::SeekableReadStream &stream) { stream.seek(pos + 16); - debug("Object x %d, y %d, z %d overlay %d", _x, _y, _z, _mask); + //debug("Object x %d, y %d, z %d overlay %d", _x, _y, _z, _mask); return true; } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index afef9d460810..b19ac29d6b9b 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -115,6 +115,11 @@ PrinceEngine::~PrinceEngine() { } _objList.clear(); + for (uint32 i = 0; i < _pscrList.size(); i++) { + delete _pscrList[i]; + } + _pscrList.clear(); + for (uint i = 0; i < _maskList.size(); i++) { free(_maskList[i]._data); } @@ -251,8 +256,8 @@ bool AnimListItem::loadFromStream(Common::SeekableReadStream &stream) { _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); + //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); @@ -304,6 +309,12 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { loadZoom(_mainHero->_zoomBitmap, _mainHero->kZoomBitmapLen, "zoom"); loadShadow(_mainHero->_shadowBitmap, _mainHero->kShadowBitmapSize, "shadow", "shadow2"); + for (uint32 i = 0; i < _pscrList.size(); i++) { + delete _pscrList[i]; + } + _pscrList.clear(); + Resource::loadResource(_pscrList, "pscr.lst", false); + _mobList.clear(); Resource::loadResource(_mobList, "mob.lst", false); @@ -801,11 +812,11 @@ void PrinceEngine::showMask(int maskNr, const Graphics::Surface *originalRoomSur } } -void PrinceEngine::showSprite(Graphics::Surface *backAnimSurface, int destX, int destY) { - if (spriteCheck(backAnimSurface->w, backAnimSurface->h, destX, destY)) { +void PrinceEngine::showSprite(const Graphics::Surface *spriteSurface, int destX, int destY) { + if (spriteCheck(spriteSurface->w, spriteSurface->h, destX, destY)) { destX -= _picWindowX; destY -= _picWindowY; - _graph->drawTransparent(destX, destY, backAnimSurface); + _graph->drawTransparent(destX, destY, spriteSurface); } } @@ -1063,6 +1074,20 @@ void PrinceEngine::showObjects() { } } +void PrinceEngine::showParallax() { + if (!_pscrList.empty()) { + for (uint i = 0; i < _pscrList.size(); i++) { + const Graphics::Surface *pscrSurface = _pscrList[i]->getSurface(); + int x = _pscrList[i]->_x - (_pscrList[i]->_step * _picWindowX / 4); + int y = _pscrList[i]->_y; + //int z = 1000; + if (spriteCheck(pscrSurface->w, pscrSurface->h, x, y)) { + showSprite(pscrSurface, x, y); + } + } + } +} + void PrinceEngine::drawScreen() { const Graphics::Surface *roomSurface = _roomBmp->getSurface(); Graphics::Surface visiblePart; @@ -1096,6 +1121,8 @@ void PrinceEngine::drawScreen() { insertMasks(&visiblePart); } + showParallax(); + clsMasks(); playNextFrame(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 1deb26f92625..d30b51432d6c 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -45,6 +45,7 @@ #include "prince/mob.h" #include "prince/object.h" +#include "prince/pscr.h" namespace Prince { @@ -65,6 +66,7 @@ class Font; class Hero; class Animation; class Room; +class Pscr; struct Text { const char *_str; @@ -268,9 +270,10 @@ class PrinceEngine : public Engine { void showBackAnims(); void clearBackAnimList(); bool spriteCheck(int sprWidth, int sprHeight, int destX, int destY); - void showSprite(Graphics::Surface *backAnimSurface, int destX, int destY); + void showSprite(const Graphics::Surface *spriteSurface, int destX, int destY); void showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY); void showObjects(); + void showParallax(); void makeShadowTable(int brightness); uint32 getTextWidth(const char *s); @@ -297,6 +300,7 @@ class PrinceEngine : public Engine { Audio::SoundHandle _soundHandle[MAX_SAMPLES]; Animation *_zoom; + Common::Array _pscrList; Common::Array _mobList; Common::Array _objList; Common::Array _maskList; diff --git a/engines/prince/pscr.cpp b/engines/prince/pscr.cpp new file mode 100644 index 000000000000..7402e46e43f0 --- /dev/null +++ b/engines/prince/pscr.cpp @@ -0,0 +1,90 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/archive.h" +#include "common/debug-channels.h" +#include "common/debug.h" +#include "common/stream.h" + +#include "graphics/surface.h" + +#include "prince/pscr.h" + +namespace Prince { + +PScr::PScr() :_file(0), _x(0), _y(0), _step(0), _addr(0), _len(0), _surface(NULL) +{ +} + +PScr::~PScr() { + if (_surface) { + _surface->free(); + delete _surface; + _surface = NULL; + } +} + +void PScr::loadSurface(Common::SeekableReadStream &stream) { + //stream.skip(4); + int x = stream.readUint16LE(); + int y = stream.readUint16LE(); + int width = stream.readUint16LE(); + int height = stream.readUint16LE(); + debug("x: %d, y: %d", x, y); + debug("w: %d, h: %d", width, height); + _surface = new Graphics::Surface(); + _surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); + + for (int h = 0; h < _surface->h; h++) { + stream.read(_surface->getBasePtr(0, h), _surface->w); + } +} + +bool PScr::loadFromStream(Common::SeekableReadStream &stream) { + int32 pos = stream.pos(); + uint16 file = stream.readUint16LE(); + if (file == 0xFFFF) + return false; + _file = file; + _x = stream.readUint16LE(); + _y = stream.readUint16LE(); + _step = stream.readUint16LE(); + _addr = stream.readUint32LE(); + + const Common::String pscrStreamName = Common::String::format("PS%02d", _file); + Common::SeekableReadStream *pscrStream = SearchMan.createReadStreamForMember(pscrStreamName); + if (!pscrStream) { + error("Can't load %s", pscrStreamName.c_str()); + return false; + } + + loadSurface(*pscrStream); + delete pscrStream; + + stream.seek(pos + 12); // size of PScrList struct + + debug("Parallex nr %d, x %d, y %d, step %d", _file, _x, _y, _step); + + return true; +} + +} \ No newline at end of file diff --git a/engines/prince/pscr.h b/engines/prince/pscr.h new file mode 100644 index 000000000000..3564a571e7b5 --- /dev/null +++ b/engines/prince/pscr.h @@ -0,0 +1,53 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef PRINCE_PSCR_H +#define PRINCE_PSCR_H + +#include "image/image_decoder.h" +#include "graphics/surface.h" + +namespace Prince { + +class PScr { +public: + PScr(); + ~PScr(); + + int16 _file; + int16 _x; + int16 _y; + int16 _step; + int32 _addr; + byte _len; + + bool loadFromStream(Common::SeekableReadStream &stream); + const Graphics::Surface *getSurface() const { return _surface; } +private: + void loadSurface(Common::SeekableReadStream &stream); + Graphics::Surface *_surface; +}; + +} + +#endif + From 94ab6b268c1132f39f96ee10ae6db76d8c5dec89 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 2 Jun 2014 18:19:02 +0200 Subject: [PATCH 134/374] PRINCE: DrawNode struct, runDrawNodes(), freeDrawNodes() --- engines/prince/graphics.cpp | 55 +++++++----- engines/prince/graphics.h | 11 ++- engines/prince/hero.cpp | 3 +- engines/prince/hero.h | 1 + engines/prince/object.h | 2 +- engines/prince/prince.cpp | 169 ++++++++++++++++++++++++++++++------ engines/prince/prince.h | 26 +++++- engines/prince/pscr.h | 2 +- 8 files changed, 213 insertions(+), 56 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 679885f7b83c..bc15faf9a999 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -73,7 +73,7 @@ void GraphicsMan::draw(uint16 posX, uint16 posY, const Graphics::Surface *s) { change(); } -void GraphicsMan::drawTransparent(int32 posX, int32 posY, const Graphics::Surface *s) { +void GraphicsMan::drawTransparentIntro(int32 posX, int32 posY, const Graphics::Surface *s) { for (int y = 0; y < s->h; y++) { for (int x = 0; x < s->w; x++) { byte pixel = *((byte*)s->getBasePtr(x, y)); @@ -89,19 +89,34 @@ void GraphicsMan::drawTransparent(int32 posX, int32 posY, const Graphics::Surfac change(); } -void GraphicsMan::drawMask(int32 posX, int32 posY, int32 width, int32 height, byte *maskData, const Graphics::Surface *originalRoomSurface) { - int maskWidth = width >> 3; +void GraphicsMan::drawTransparent(Graphics::Surface *frontScreen, DrawNode *drawNode) { + for (int y = 0; y < drawNode->s->h; y++) { + for (int x = 0; x < drawNode->s->w; x++) { + byte pixel = *((byte*)drawNode->s->getBasePtr(x, y)); + if (pixel != 255) { + if (x + drawNode->posX < frontScreen->w && x + drawNode->posX >= 0) { + if (y + drawNode->posY < frontScreen->h && y + drawNode->posY >= 0) { + *((byte*)frontScreen->getBasePtr(x + drawNode->posX, y + drawNode->posY)) = pixel; + } + } + } + } + } +} + +void GraphicsMan::drawMask(Graphics::Surface *frontScreen, DrawNode *drawNode) { + int maskWidth = drawNode->width >> 3; int maskPostion = 0; int maskCounter = 128; - for (int y = 0; y < height; y++) { + for (int y = 0; y < drawNode->height; y++) { int tempMaskPostion = maskPostion; - for (int x = 0; x < width; x++) { - if (x + posX < _frontScreen->w && x + posX >= 0) { - if (y + posY < _frontScreen->h && y + posY >= 0) { - if ((maskData[tempMaskPostion] & maskCounter) != 0) { - byte orgPixel = *((byte*)originalRoomSurface->getBasePtr(x + posX, y + posY)); - *((byte*)_frontScreen->getBasePtr(x + posX, y + posY)) = orgPixel; - //*((byte*)_frontScreen->getBasePtr(x + posX, y + posY)) = 0; // for debugging + for (int x = 0; x < drawNode->width; x++) { + if (x + drawNode->posX < frontScreen->w && x + drawNode->posX >= 0) { + if (y + drawNode->posY < frontScreen->h && y + drawNode->posY >= 0) { + if ((drawNode->data[tempMaskPostion] & maskCounter) != 0) { + byte orgPixel = *((byte*)drawNode->originalRoomSurface->getBasePtr(x + drawNode->posX, y + drawNode->posY)); + *((byte*)frontScreen->getBasePtr(x + drawNode->posX, y + drawNode->posY)) = orgPixel; + //*((byte*)frontScreen->getBasePtr(x + posX, y + posY)) = 0; // for debugging } } } @@ -114,24 +129,22 @@ void GraphicsMan::drawMask(int32 posX, int32 posY, int32 width, int32 height, by maskPostion += maskWidth; maskCounter = 128; } - change(); } -void GraphicsMan::drawAsShadow(int32 posX, int32 posY, const Graphics::Surface *s, byte *shadowTable) { - for (int y = 0; y < s->h; y++) { - for (int x = 0; x < s->w; x++) { - byte pixel = *((byte*)s->getBasePtr(x, y)); +void GraphicsMan::drawAsShadow(Graphics::Surface *frontScreen, DrawNode *drawNode) { + for (int y = 0; y < drawNode->s->h; y++) { + for (int x = 0; x < drawNode->s->w; x++) { + byte pixel = *((byte*)drawNode->s->getBasePtr(x, y)); if (pixel == kShadowColor) { - if (x + posX < _frontScreen->w && x + posX >= 0) { - if (y + posY < _frontScreen->h && y + posY >= 0) { - byte *background = (byte *)_frontScreen->getBasePtr(x + posX, y + posY); - *background = *(shadowTable + *background); + if (x + drawNode->posX < frontScreen->w && x + drawNode->posX >= 0) { + if (y + drawNode->posY < frontScreen->h && y + drawNode->posY >= 0) { + byte *background = (byte *)frontScreen->getBasePtr(x + drawNode->posX, y + drawNode->posY); + *background = *(drawNode->data + *background); } } } } } - change(); } void GraphicsMan::makeShadowTable(int brightness, byte *shadowPalette) { diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index e6293bbeee74..dca25088381b 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -29,6 +29,7 @@ namespace Prince { class PrinceEngine; +struct DrawNode; class GraphicsMan { @@ -44,9 +45,13 @@ class GraphicsMan void makeShadowTable(int brightness, byte *shadowTable); void draw(uint16 x, uint16 y, const Graphics::Surface *s); - void drawTransparent(int32 posX, int32 poxY, const Graphics::Surface *s); - void drawAsShadow(int32 posX, int32 poxY, const Graphics::Surface *s, byte *shadowTable); - void drawMask(int32 posX, int32 posY, int32 width, int32 height, byte *maskData, const Graphics::Surface *originalRoomSurface); + void drawTransparentIntro(int32 posX, int32 poxY, const Graphics::Surface *s); + //void drawAsShadow(int32 posX, int32 poxY, const Graphics::Surface *s, byte *shadowTable); + //void drawMask(int32 posX, int32 posY, int32 width, int32 height, byte *maskData, const Graphics::Surface *originalRoomSurface); + + static void drawTransparent(Graphics::Surface *frontScreen, DrawNode *drawNode); + static void drawAsShadow(Graphics::Surface *frontScreen, DrawNode *drawNode); + static void drawMask(Graphics::Surface *frontScreen, DrawNode *drawNode); Graphics::Surface *_frontScreen; Graphics::Surface *_backScreen; diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 4b582d6cc648..22ddf645d817 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -35,7 +35,7 @@ Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph) , _number(0), _visible(false), _state(MOVE), _middleX(0), _middleY(0) , _boreNum(1), _currHeight(0), _moveDelay(0), _shadMinus(0), _moveSetType(0) , _lastDirection(DOWN), _destDirection(DOWN), _talkTime(0), _boredomTime(0), _phase(0) - , _specAnim(0), _drawX(0), _drawY(0), _zoomFactor(0), _scaleValue(0) + , _specAnim(0), _drawX(0), _drawY(0), _drawZ(0), _zoomFactor(0), _scaleValue(0) , _shadZoomFactor(0), _shadScaleValue(0), _shadLineLen(0), _shadDrawX(0), _shadDrawY(0) , _frameXSize(0), _frameYSize(0), _scaledFrameXSize(0), _scaledFrameYSize(0) { @@ -205,6 +205,7 @@ void Hero::countDrawPosition() { //notfullSize _drawX = _middleX - _scaledFrameXSize / 2; _drawY = tempMiddleY + 1 - _scaledFrameYSize; + _drawZ = _drawY - 1; _vm->checkMasks(_drawX, _drawY - 1, _scaledFrameXSize, _scaledFrameYSize, _middleY); } else { //fullSize diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 565212447b47..5b8391c10cd0 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -145,6 +145,7 @@ class Hero { int16 _scaledFrameYSize; int16 _drawX; int16 _drawY; + int16 _drawZ; int16 _lightX; // for hero's shadow int16 _lightY; diff --git a/engines/prince/object.h b/engines/prince/object.h index 5bc7c580daad..ea1ad9dc0d71 100644 --- a/engines/prince/object.h +++ b/engines/prince/object.h @@ -43,7 +43,7 @@ class Object { int32 _zoomInTime; bool loadFromStream(Common::SeekableReadStream &stream); - const Graphics::Surface *getSurface() const { return _surface; } + Graphics::Surface *getSurface() const { return _surface; } private: void loadSurface(Common::SeekableReadStream &stream); Graphics::Surface *_surface; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index b19ac29d6b9b..d85a5eadb99d 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -389,7 +389,7 @@ bool PrinceEngine::playNextFrame() { const Graphics::Surface *s = _flicPlayer.decodeNextFrame(); if (s) { - _graph->drawTransparent(0, 0, s); + _graph->drawTransparentIntro(0, 0, s); _graph->change(); } else if (_flicLooped) { _flicPlayer.rewind(); @@ -793,7 +793,7 @@ void PrinceEngine::clsMasks() { } // InsertNakladki -void PrinceEngine::insertMasks(const Graphics::Surface *originalRoomSurface) { +void PrinceEngine::insertMasks(Graphics::Surface *originalRoomSurface) { for (uint i = 0; i < _maskList.size(); i++) { if (_maskList[i]._state == 1) { showMask(i, originalRoomSurface); @@ -801,6 +801,30 @@ void PrinceEngine::insertMasks(const Graphics::Surface *originalRoomSurface) { } } +// ShowNak +void PrinceEngine::showMask(int maskNr, Graphics::Surface *originalRoomSurface) { + if (_maskList[maskNr]._flags == 0) { + 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.freeSurfaceSMemory = false; + newDrawNode.drawFunction = &_graph->drawMask; + _drawNodeList.push_back(newDrawNode); + //_graph->drawMask(destX, destY, _maskList[maskNr]._width, _maskList[maskNr]._height, _maskList[maskNr].getMask(), originalRoomSurface); + } + } +} + +/* // ShowNak void PrinceEngine::showMask(int maskNr, const Graphics::Surface *originalRoomSurface) { if (_maskList[maskNr]._flags == 0) { @@ -811,20 +835,44 @@ void PrinceEngine::showMask(int maskNr, const Graphics::Surface *originalRoomSur } } } - -void PrinceEngine::showSprite(const Graphics::Surface *spriteSurface, int destX, int destY) { +*/ +void PrinceEngine::showSprite(Graphics::Surface *spriteSurface, int destX, int destY, int destZ, bool freeSurfaceMemory) { if (spriteCheck(spriteSurface->w, spriteSurface->h, destX, destY)) { destX -= _picWindowX; destY -= _picWindowY; - _graph->drawTransparent(destX, destY, spriteSurface); + 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 = nullptr; + newDrawNode.freeSurfaceSMemory = freeSurfaceMemory; + newDrawNode.drawFunction = &_graph->drawTransparent; + _drawNodeList.push_back(newDrawNode); + //_graph->drawTransparent(destX, destY, spriteSurface); } } -void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY) { +void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY, int destZ, bool freeSurfaceMemory) { if (spriteCheck(shadowSurface->w, shadowSurface->h, destX, destY)) { destX -= _picWindowX; destY -= _picWindowY; - _graph->drawAsShadow(destX, destY, shadowSurface, _graph->_shadowTable70); + 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.freeSurfaceSMemory = freeSurfaceMemory; + newDrawNode.drawFunction = &_graph->drawAsShadow; + _drawNodeList.push_back(newDrawNode); + //_graph->drawAsShadow(destX, destY, shadowSurface, _graph->_shadowTable70); } } @@ -989,9 +1037,9 @@ void PrinceEngine::showBackAnims() { shadowZ = z; Graphics::Surface *backAnimSurface = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrame(phaseFrameIndex); //still with memory leak - showSprite(backAnimSurface, x, y); - backAnimSurface->free(); - delete backAnimSurface; + showSprite(backAnimSurface, x, y, z, true); + //backAnimSurface->free(); + //delete backAnimSurface; } //ShowFrameCodeShadow @@ -1016,9 +1064,9 @@ void PrinceEngine::showBackAnims() { } Graphics::Surface *shadowSurface = _backAnimList[i].backAnims[activeSubAnim]._shadowData->getFrame(shadowPhaseFrameIndex); //still with memory leak - showSpriteShadow(shadowSurface, shadowX, shadowY); - shadowSurface->free(); - delete shadowSurface; + showSpriteShadow(shadowSurface, shadowX, shadowY, shadowZ, true); + //shadowSurface->free(); + //delete shadowSurface; } } } @@ -1057,12 +1105,24 @@ void PrinceEngine::showObjects() { // mov edx, d [esi.Obj_ZoomInAddr] } } - const Graphics::Surface *objSurface = _objList[i]->getSurface(); + Graphics::Surface *objSurface = _objList[i]->getSurface(); if (spriteCheck(objSurface->w, objSurface->h, _objList[i]->_x, _objList[i]->_y)) { if ((_objList[i]->_mask & 512) == 0) { // 0200h int destX = _objList[i]->_x - _picWindowX; int destY = _objList[i]->_y - _picWindowY; - _graph->drawTransparent(destX, destY, objSurface); + DrawNode newDrawNode; + newDrawNode.posX = destX; + newDrawNode.posY = destY; + newDrawNode.posZ = _objList[i]->_z; + newDrawNode.width = 0; + newDrawNode.height = 0; + newDrawNode.s = objSurface; + newDrawNode.originalRoomSurface = nullptr; + newDrawNode.data = nullptr; + newDrawNode.freeSurfaceSMemory = false; + newDrawNode.drawFunction = &_graph->drawTransparent; + _drawNodeList.push_back(newDrawNode); + //_graph->drawTransparent(destX, destY, objSurface); } else { // showBackSprite(); } @@ -1077,17 +1137,44 @@ void PrinceEngine::showObjects() { void PrinceEngine::showParallax() { if (!_pscrList.empty()) { for (uint i = 0; i < _pscrList.size(); i++) { - const Graphics::Surface *pscrSurface = _pscrList[i]->getSurface(); + Graphics::Surface *pscrSurface = _pscrList[i]->getSurface(); int x = _pscrList[i]->_x - (_pscrList[i]->_step * _picWindowX / 4); int y = _pscrList[i]->_y; - //int z = 1000; + int z = 1000; if (spriteCheck(pscrSurface->w, pscrSurface->h, x, y)) { - showSprite(pscrSurface, x, y); + showSprite(pscrSurface, x, y, z, false); } } } } +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::freeDrawNodes() { + for (uint i = 0; i < _drawNodeList.size(); i++) { + if (_drawNodeList[i].freeSurfaceSMemory) { + _drawNodeList[i].s->free(); + delete _drawNodeList[i].s; + } + } + _drawNodeList.clear(); +} + void PrinceEngine::drawScreen() { const Graphics::Surface *roomSurface = _roomBmp->getSurface(); Graphics::Surface visiblePart; @@ -1096,21 +1183,44 @@ void PrinceEngine::drawScreen() { _graph->draw(0, 0, &visiblePart); } + Graphics::Surface *mainHeroSurface; if (_mainHero->_visible) { - Graphics::Surface *mainHeroSurface = _mainHero->getSurface(); + mainHeroSurface = _mainHero->getSurface(); if (mainHeroSurface) { _mainHero->showHeroShadow(mainHeroSurface); if (_mainHero->_zoomFactor != 0) { Graphics::Surface *zoomedHeroSurface = _mainHero->zoomSprite(mainHeroSurface); - _graph->drawTransparent(_mainHero->_drawX, _mainHero->_drawY, zoomedHeroSurface); - zoomedHeroSurface->free(); - delete zoomedHeroSurface; + DrawNode newDrawNode; + newDrawNode.posX = _mainHero->_drawX; + newDrawNode.posY = _mainHero->_drawY; + newDrawNode.posZ = _mainHero->_drawZ; + newDrawNode.width = 0; + newDrawNode.height = 0; + newDrawNode.s = zoomedHeroSurface; + newDrawNode.originalRoomSurface = nullptr; + newDrawNode.data = nullptr; + newDrawNode.freeSurfaceSMemory = true; + newDrawNode.drawFunction = &_graph->drawTransparent; + _drawNodeList.push_back(newDrawNode); + //_graph->drawTransparent(_mainHero->_drawX, _mainHero->_drawY, zoomedHeroSurface); + //zoomedHeroSurface->free(); + //delete zoomedHeroSurface; } else { - _graph->drawTransparent(_mainHero->_drawX, _mainHero->_drawY, mainHeroSurface); + DrawNode newDrawNode; + newDrawNode.posX = _mainHero->_drawX; + newDrawNode.posY = _mainHero->_drawY; + newDrawNode.posZ = _mainHero->_drawZ; + newDrawNode.width = 0; + newDrawNode.height = 0; + newDrawNode.s = mainHeroSurface; + newDrawNode.originalRoomSurface = nullptr; + newDrawNode.data = nullptr; + newDrawNode.freeSurfaceSMemory = false; + newDrawNode.drawFunction = &_graph->drawTransparent; + _drawNodeList.push_back(newDrawNode); + //_graph->drawTransparent(_mainHero->_drawX, _mainHero->_drawY, mainHeroSurface); } } - mainHeroSurface->free(); - delete mainHeroSurface; } showBackAnims(); @@ -1123,6 +1233,15 @@ void PrinceEngine::drawScreen() { showParallax(); + runDrawNodes(); + + freeDrawNodes(); + + if (_mainHero->_visible) { + mainHeroSurface->free(); + delete mainHeroSurface; + } + clsMasks(); playNextFrame(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index d30b51432d6c..f888d9bb6b40 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -179,6 +179,19 @@ struct Mask { } }; +struct DrawNode { + int posX; + int posY; + int posZ; + int32 width; + int32 height; + Graphics::Surface *s; + Graphics::Surface *originalRoomSurface; + byte *data; + bool freeSurfaceSMemory; + void (*drawFunction)(Graphics::Surface *, DrawNode *); +}; + struct DebugChannel { enum Type { @@ -250,8 +263,8 @@ class PrinceEngine : public Engine { static const int16 kMaxPicHeight = 480; void checkMasks(int x1, int y1, int sprWidth, int sprHeight, int z); - void insertMasks(const Graphics::Surface *originalRoomSurface); - void showMask(int maskNr, const Graphics::Surface *originalRoomSurface); + void insertMasks(Graphics::Surface *originalRoomSurface); + void showMask(int maskNr, Graphics::Surface *originalRoomSurface); void clsMasks(); int testAnimNr; @@ -270,10 +283,13 @@ class PrinceEngine : public Engine { void showBackAnims(); void clearBackAnimList(); bool spriteCheck(int sprWidth, int sprHeight, int destX, int destY); - void showSprite(const Graphics::Surface *spriteSurface, int destX, int destY); - void showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY); + void showSprite(Graphics::Surface *spriteSurface, int destX, int destY, int destZ, bool freeSurfaceMemory); + void showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY, int destZ, bool freeSurfaceMemory); void showObjects(); void showParallax(); + static bool compareDrawNodes(DrawNode d1, DrawNode d2); + void runDrawNodes(); + void freeDrawNodes(); void makeShadowTable(int brightness); uint32 getTextWidth(const char *s); @@ -305,6 +321,8 @@ class PrinceEngine : public Engine { Common::Array _objList; Common::Array _maskList; + Common::Array _drawNodeList; + bool _flicLooped; void mainLoop(); diff --git a/engines/prince/pscr.h b/engines/prince/pscr.h index 3564a571e7b5..76add9602dd9 100644 --- a/engines/prince/pscr.h +++ b/engines/prince/pscr.h @@ -41,7 +41,7 @@ class PScr { byte _len; bool loadFromStream(Common::SeekableReadStream &stream); - const Graphics::Surface *getSurface() const { return _surface; } + Graphics::Surface *getSurface() const { return _surface; } private: void loadSurface(Common::SeekableReadStream &stream); Graphics::Surface *_surface; From 2739a8639a2a9a50d36e8033896d6a760cc1d5d8 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 2 Jun 2014 22:26:56 +0200 Subject: [PATCH 135/374] PRINCE: Code clean up after adding DrawNode --- engines/prince/graphics.h | 2 -- engines/prince/prince.cpp | 56 +++++++++------------------------------ 2 files changed, 12 insertions(+), 46 deletions(-) diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index dca25088381b..2756bf477708 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -46,8 +46,6 @@ class GraphicsMan void draw(uint16 x, uint16 y, const Graphics::Surface *s); void drawTransparentIntro(int32 posX, int32 poxY, const Graphics::Surface *s); - //void drawAsShadow(int32 posX, int32 poxY, const Graphics::Surface *s, byte *shadowTable); - //void drawMask(int32 posX, int32 posY, int32 width, int32 height, byte *maskData, const Graphics::Surface *originalRoomSurface); static void drawTransparent(Graphics::Surface *frontScreen, DrawNode *drawNode); static void drawAsShadow(Graphics::Surface *frontScreen, DrawNode *drawNode); diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index d85a5eadb99d..ac7bde8f620c 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -819,23 +819,10 @@ void PrinceEngine::showMask(int maskNr, Graphics::Surface *originalRoomSurface) newDrawNode.freeSurfaceSMemory = false; newDrawNode.drawFunction = &_graph->drawMask; _drawNodeList.push_back(newDrawNode); - //_graph->drawMask(destX, destY, _maskList[maskNr]._width, _maskList[maskNr]._height, _maskList[maskNr].getMask(), originalRoomSurface); } } } -/* -// ShowNak -void PrinceEngine::showMask(int maskNr, const Graphics::Surface *originalRoomSurface) { - if (_maskList[maskNr]._flags == 0) { - 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; - _graph->drawMask(destX, destY, _maskList[maskNr]._width, _maskList[maskNr]._height, _maskList[maskNr].getMask(), originalRoomSurface); - } - } -} -*/ void PrinceEngine::showSprite(Graphics::Surface *spriteSurface, int destX, int destY, int destZ, bool freeSurfaceMemory) { if (spriteCheck(spriteSurface->w, spriteSurface->h, destX, destY)) { destX -= _picWindowX; @@ -852,7 +839,6 @@ void PrinceEngine::showSprite(Graphics::Surface *spriteSurface, int destX, int d newDrawNode.freeSurfaceSMemory = freeSurfaceMemory; newDrawNode.drawFunction = &_graph->drawTransparent; _drawNodeList.push_back(newDrawNode); - //_graph->drawTransparent(destX, destY, spriteSurface); } } @@ -872,7 +858,6 @@ void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX, newDrawNode.freeSurfaceSMemory = freeSurfaceMemory; newDrawNode.drawFunction = &_graph->drawAsShadow; _drawNodeList.push_back(newDrawNode); - //_graph->drawAsShadow(destX, destY, shadowSurface, _graph->_shadowTable70); } } @@ -1038,8 +1023,6 @@ void PrinceEngine::showBackAnims() { Graphics::Surface *backAnimSurface = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrame(phaseFrameIndex); //still with memory leak showSprite(backAnimSurface, x, y, z, true); - //backAnimSurface->free(); - //delete backAnimSurface; } //ShowFrameCodeShadow @@ -1065,8 +1048,6 @@ void PrinceEngine::showBackAnims() { Graphics::Surface *shadowSurface = _backAnimList[i].backAnims[activeSubAnim]._shadowData->getFrame(shadowPhaseFrameIndex); //still with memory leak showSpriteShadow(shadowSurface, shadowX, shadowY, shadowZ, true); - //shadowSurface->free(); - //delete shadowSurface; } } } @@ -1122,7 +1103,6 @@ void PrinceEngine::showObjects() { newDrawNode.freeSurfaceSMemory = false; newDrawNode.drawFunction = &_graph->drawTransparent; _drawNodeList.push_back(newDrawNode); - //_graph->drawTransparent(destX, destY, objSurface); } else { // showBackSprite(); } @@ -1188,38 +1168,26 @@ void PrinceEngine::drawScreen() { mainHeroSurface = _mainHero->getSurface(); if (mainHeroSurface) { _mainHero->showHeroShadow(mainHeroSurface); + + DrawNode newDrawNode; + newDrawNode.posX = _mainHero->_drawX; + newDrawNode.posY = _mainHero->_drawY; + newDrawNode.posZ = _mainHero->_drawZ; + newDrawNode.width = 0; + newDrawNode.height = 0; + newDrawNode.originalRoomSurface = nullptr; + newDrawNode.data = nullptr; + newDrawNode.drawFunction = &_graph->drawTransparent; + if (_mainHero->_zoomFactor != 0) { Graphics::Surface *zoomedHeroSurface = _mainHero->zoomSprite(mainHeroSurface); - DrawNode newDrawNode; - newDrawNode.posX = _mainHero->_drawX; - newDrawNode.posY = _mainHero->_drawY; - newDrawNode.posZ = _mainHero->_drawZ; - newDrawNode.width = 0; - newDrawNode.height = 0; newDrawNode.s = zoomedHeroSurface; - newDrawNode.originalRoomSurface = nullptr; - newDrawNode.data = nullptr; newDrawNode.freeSurfaceSMemory = true; - newDrawNode.drawFunction = &_graph->drawTransparent; - _drawNodeList.push_back(newDrawNode); - //_graph->drawTransparent(_mainHero->_drawX, _mainHero->_drawY, zoomedHeroSurface); - //zoomedHeroSurface->free(); - //delete zoomedHeroSurface; } else { - DrawNode newDrawNode; - newDrawNode.posX = _mainHero->_drawX; - newDrawNode.posY = _mainHero->_drawY; - newDrawNode.posZ = _mainHero->_drawZ; - newDrawNode.width = 0; - newDrawNode.height = 0; newDrawNode.s = mainHeroSurface; - newDrawNode.originalRoomSurface = nullptr; - newDrawNode.data = nullptr; newDrawNode.freeSurfaceSMemory = false; - newDrawNode.drawFunction = &_graph->drawTransparent; - _drawNodeList.push_back(newDrawNode); - //_graph->drawTransparent(_mainHero->_drawX, _mainHero->_drawY, mainHeroSurface); } + _drawNodeList.push_back(newDrawNode); } } From 854de5845bdcc44b00edeb74c1fd9e8bb1db089d Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 2 Jun 2014 22:59:13 +0200 Subject: [PATCH 136/374] PRINCE: Hero Z coordinate fix --- engines/prince/hero.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 22ddf645d817..3293c9c697dc 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -205,7 +205,6 @@ void Hero::countDrawPosition() { //notfullSize _drawX = _middleX - _scaledFrameXSize / 2; _drawY = tempMiddleY + 1 - _scaledFrameYSize; - _drawZ = _drawY - 1; _vm->checkMasks(_drawX, _drawY - 1, _scaledFrameXSize, _scaledFrameYSize, _middleY); } else { //fullSize @@ -213,6 +212,8 @@ void Hero::countDrawPosition() { _drawY = tempMiddleY + 1 - _frameYSize; _vm->checkMasks(_drawX, _drawY - 1, _frameXSize, _frameYSize, _middleY); } + + _drawZ = tempMiddleY; } void Hero::plotPoint(int x, int y) { From c61ccb031956a61e8bb5804f267e945032989fcb Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 5 Jun 2014 16:42:33 +0200 Subject: [PATCH 137/374] PRINCE: hotspot() - name of mobs in wider locations fix, clean up --- engines/prince/graphics.cpp | 2 +- engines/prince/prince.cpp | 33 +++++---------------------------- engines/prince/prince.h | 4 ---- 3 files changed, 6 insertions(+), 33 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index bc15faf9a999..210b9d9ef984 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -116,7 +116,7 @@ void GraphicsMan::drawMask(Graphics::Surface *frontScreen, DrawNode *drawNode) { if ((drawNode->data[tempMaskPostion] & maskCounter) != 0) { byte orgPixel = *((byte*)drawNode->originalRoomSurface->getBasePtr(x + drawNode->posX, y + drawNode->posY)); *((byte*)frontScreen->getBasePtr(x + drawNode->posX, y + drawNode->posY)) = orgPixel; - //*((byte*)frontScreen->getBasePtr(x + posX, y + posY)) = 0; // for debugging + //*((byte*)frontScreen->getBasePtr(x + drawNode->posX, y + drawNode->posY)) = 0; // for debugging } } } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index ac7bde8f620c..529e17d7fd1c 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -77,7 +77,7 @@ void PrinceEngine::debugEngine(const char *s, ...) { PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _graph(nullptr), _script(nullptr), _interpreter(nullptr), _flags(nullptr), _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), _room(nullptr), testAnimNr(0), testAnimFrame(0), - _cameraX(0), _newCameraX(0), _frameNr(0), _cursor1(nullptr), _cursor2(nullptr), _font(nullptr), + _frameNr(0), _cursor1(nullptr), _cursor2(nullptr), _font(nullptr), _suitcaseBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0), _randomSource("prince") { // Debug/console setup @@ -279,9 +279,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _locationNr = locationNr; _debugger->_locationNr = locationNr; - _cameraX = 0; - _newCameraX = 0; - + _flags->setFlagValue(Flags::CURRROOM, _locationNr); _interpreter->stopBg(); @@ -544,24 +542,6 @@ bool PrinceEngine::loadShadow(byte *shadowBitmap, uint32 dataSize, const char *r return true; } -void PrinceEngine::scrollCameraLeft(int16 delta) { - if (_newCameraX > 0) { - if (_newCameraX < delta) - _newCameraX = 0; - else - _newCameraX -= delta; - } -} - -void PrinceEngine::scrollCameraRight(int16 delta) { - if (_newCameraX != _sceneWidth - 640) { - if (_sceneWidth - 640 < delta + _newCameraX) - delta += (_sceneWidth - 640) - (delta + _newCameraX); - _newCameraX += delta; - debugEngine("PrinceEngine::scrollCameraRight() _newCameraX = %d; delta = %d", _newCameraX, delta); - } -} - void PrinceEngine::keyHandler(Common::Event event) { uint16 nChar = event.kbd.keycode; switch (nChar) { @@ -571,14 +551,12 @@ void PrinceEngine::keyHandler(Common::Event event) { } break; case Common::KEYCODE_LEFT: - scrollCameraLeft(32); if(testAnimNr > 0) { testAnimNr--; } debug("testAnimNr: %d", testAnimNr); break; case Common::KEYCODE_RIGHT: - scrollCameraRight(32); testAnimNr++; debug("testAnimNr: %d", testAnimNr); break; @@ -652,7 +630,7 @@ void PrinceEngine::keyHandler(Common::Event event) { void PrinceEngine::hotspot() { Common::Point mousepos = _system->getEventManager()->getMousePos(); - Common::Point mousePosCamera(mousepos.x + _cameraX, mousepos.y); + Common::Point mousePosCamera(mousepos.x + _picWindowX, mousepos.y); for (Common::Array::const_iterator it = _mobList.begin(); it != _mobList.end() ; it++) { const Mob& mob = *it; @@ -1272,9 +1250,8 @@ void PrinceEngine::mainLoop() { // Ensure non-negative delay = delay < 0 ? 0 : delay; _system->delayMillis(delay); - - _cameraX = _newCameraX; - ++_frameNr; + + _frameNr++; if (_debugger->_locationNr != _locationNr) loadLocation(_debugger->_locationNr); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index f888d9bb6b40..41281dc64ec4 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -245,8 +245,6 @@ class PrinceEngine : public Engine { Hero *_mainHero; Hero *_secondHero; - uint16 _cameraX; - uint16 _newCameraX; uint16 _sceneWidth; int32 _picWindowX; int32 _picWindowY; @@ -274,8 +272,6 @@ class PrinceEngine : public Engine { bool playNextFrame(); void keyHandler(Common::Event event); void hotspot(); - void scrollCameraRight(int16 delta); - void scrollCameraLeft(int16 delta); void drawScreen(); void showTexts(); void init(); From c7e178d098f770b6dfaa0e0ca837975ed29e39bd Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 5 Jun 2014 21:09:43 +0200 Subject: [PATCH 138/374] PRINCE: Hero inventory beginning, prepareInventoryToView() implementation --- engines/prince/hero.h | 5 +-- engines/prince/mob.h | 4 +++ engines/prince/prince.cpp | 67 +++++++++++++++++++++++++++++++++++++-- engines/prince/prince.h | 19 ++++++++++- 4 files changed, 90 insertions(+), 5 deletions(-) diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 5b8391c10cd0..31ffac3b6a58 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -35,6 +35,7 @@ namespace Prince { class Animation; class PrinceEngine; class GraphicsMan; +struct InventoryItem; class Hero { public: @@ -173,8 +174,8 @@ class Hero { uint16 _currHeight; // height of current anim phase - // Inventory array of items - // Inventory2 array of items + Common::Array _inventory; // Inventory array of items + Common::Array _inventory2; // Inventory2 array of items // Font subtitiles font // Color subtitiles color // AnimSet number of animation set diff --git a/engines/prince/mob.h b/engines/prince/mob.h index 36630eb6eb89..1c095c2fc432 100644 --- a/engines/prince/mob.h +++ b/engines/prince/mob.h @@ -66,6 +66,10 @@ class Mob { bool _visible; uint16 _type; + uint16 _x1; // initialize this? + uint16 _y1; + uint16 _x2; + uint16 _y2; uint16 _mask; Common::Rect _rect; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 529e17d7fd1c..346342462d1a 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -78,7 +78,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) Engine(syst), _gameDescription(gameDesc), _graph(nullptr), _script(nullptr), _interpreter(nullptr), _flags(nullptr), _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), _room(nullptr), testAnimNr(0), testAnimFrame(0), _frameNr(0), _cursor1(nullptr), _cursor2(nullptr), _font(nullptr), - _suitcaseBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0), _randomSource("prince") { + _suitcaseBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0), _randomSource("prince"), + _invLineX(134), _invLineY(176), _invLine(5), _invLines(3), _invLineW(70), _invLineH(76), _invLineSkipX(2), _invLineSkipY(3) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -107,6 +108,7 @@ PrinceEngine::~PrinceEngine() { delete _suitcaseBmp; delete _variaTxt; delete[] _talkTxt; + delete[] _invTxt; delete _graph; delete _room; @@ -206,6 +208,17 @@ void PrinceEngine::init() { delete talkTxtStream; + Common::SeekableReadStream *invTxtStream = SearchMan.createReadStreamForMember("invtxt.dat"); + if (!invTxtStream) { + error("Can't load invTxtStream"); + return; + } + _invTxtSize = invTxtStream->size(); + _invTxt = new byte[_invTxtSize]; + invTxtStream->read(_invTxt, _invTxtSize); + + delete invTxtStream; + _roomBmp = new Image::BitmapDecoder(); _room = new Room(); @@ -1141,7 +1154,7 @@ void PrinceEngine::drawScreen() { _graph->draw(0, 0, &visiblePart); } - Graphics::Surface *mainHeroSurface; + Graphics::Surface *mainHeroSurface = NULL; if (_mainHero->_visible) { mainHeroSurface = _mainHero->getSurface(); if (mainHeroSurface) { @@ -1201,6 +1214,56 @@ void PrinceEngine::drawScreen() { _graph->update(); } +void PrinceEngine::rememberScreenInv() { + +} + +void PrinceEngine::prepareInventoryToView() { + int invItem = _mainHero->_inventory.size(); + _invLine = invItem / 3; + if (invItem % 3 != 0) { + _invLine++; + } + if (_invLine < 4) { + _invLine = 4; + } + _maxInvW = (374 - 2 * _invLine) / _invLine; + _invLineW = _maxInvW - 2; + + rememberScreenInv(); + + int currInvX = _invLineX; + int currInvY = _invLineY; + + int item = 0; + for (int i = 0 ; i < _invLines; i++) { + for (int j = 0; j < _invLine; j++) { + Mob tempMobItem; + tempMobItem._mask = _mainHero->_inventory[item] - 1; + tempMobItem._x1 = currInvX + _picWindowX; //picWindowX2 ? + tempMobItem._x2 = currInvX + _picWindowX + _invLineW - 1; // picWindowX2 ? + tempMobItem._y1 = currInvY; + tempMobItem._y2 = currInvY + _invLineH - 1; + //tempMobItem._name = ; + //tempMobItem._examText = ; + _invMobList.push_back(tempMobItem); + currInvX += _invLineW + _invLineSkipX; + item++; + } + currInvX = _invLineX; + currInvY += _invLineSkipY + _invLineH; + } + //moblistcreated: + //mov w [edi.Mob_Visible],-1 + //mov eax,d InvMobList + //mov d MobListAddr,eax + //mov d MobPriAddr,o InvMobPri +} + +void PrinceEngine::displayInventory() { + +} + void PrinceEngine::mainLoop() { changeCursor(0); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 41281dc64ec4..4e1073b375f3 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -265,6 +265,23 @@ class PrinceEngine : public Engine { void showMask(int maskNr, Graphics::Surface *originalRoomSurface); void clsMasks(); + uint32 _invTxtSize; + byte *_invTxt; + + int _invLineX; + int _invLineY; + int _invLine; + int _invLines; + int _invLineW; + int _invLineH; + int _maxInvW; + int _invLineSkipX; + int _invLineSkipY; + + void rememberScreenInv(); + void prepareInventoryToView(); + void displayInventory(); + int testAnimNr; int testAnimFrame; @@ -316,8 +333,8 @@ class PrinceEngine : public Engine { Common::Array _mobList; Common::Array _objList; Common::Array _maskList; - Common::Array _drawNodeList; + Common::Array _invMobList; bool _flicLooped; From 870d1be7c3b4e40b98710d0190aaaaaeffff621c Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 6 Jun 2014 00:01:08 +0200 Subject: [PATCH 139/374] PRINCE: loadAllInv(), drawInvItems() --- engines/prince/prince.cpp | 94 +++++++++++++++++++++++++++++++++++---- engines/prince/prince.h | 14 +++++- 2 files changed, 97 insertions(+), 11 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 346342462d1a..ad825fb14017 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -129,6 +129,12 @@ PrinceEngine::~PrinceEngine() { clearBackAnimList(); + for (uint i = 0; i < _allInvList.size(); i++) { + _allInvList[i]._surface->free(); + delete _allInvList[i]._surface; + } + _allInvList.clear(); + for (uint i = 0; i < _mainHero->_moveSet.size(); i++) { delete _mainHero->_moveSet[i]; } @@ -219,6 +225,8 @@ void PrinceEngine::init() { delete invTxtStream; + loadAllInv(); + _roomBmp = new Image::BitmapDecoder(); _room = new Room(); @@ -555,6 +563,34 @@ bool PrinceEngine::loadShadow(byte *shadowBitmap, uint32 dataSize, const char *r 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; + } + + invStream->skip(4); + 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; +} + void PrinceEngine::keyHandler(Common::Event event) { uint16 nChar = event.kbd.keycode; switch (nChar) { @@ -1192,6 +1228,8 @@ void PrinceEngine::drawScreen() { showParallax(); + displayInventory(); // temp + runDrawNodes(); freeDrawNodes(); @@ -1219,6 +1257,7 @@ void PrinceEngine::rememberScreenInv() { } void PrinceEngine::prepareInventoryToView() { + _invMobList.clear(); int invItem = _mainHero->_inventory.size(); _invLine = invItem / 3; if (invItem % 3 != 0) { @@ -1239,14 +1278,16 @@ void PrinceEngine::prepareInventoryToView() { for (int i = 0 ; i < _invLines; i++) { for (int j = 0; j < _invLine; j++) { Mob tempMobItem; - tempMobItem._mask = _mainHero->_inventory[item] - 1; - tempMobItem._x1 = currInvX + _picWindowX; //picWindowX2 ? - tempMobItem._x2 = currInvX + _picWindowX + _invLineW - 1; // picWindowX2 ? - tempMobItem._y1 = currInvY; - tempMobItem._y2 = currInvY + _invLineH - 1; - //tempMobItem._name = ; - //tempMobItem._examText = ; - _invMobList.push_back(tempMobItem); + if (item < _mainHero->_inventory.size()) { + tempMobItem._mask = _mainHero->_inventory[item] - 1; + tempMobItem._x1 = currInvX + _picWindowX; //picWindowX2 ? + tempMobItem._x2 = currInvX + _picWindowX + _invLineW - 1; // picWindowX2 ? + tempMobItem._y1 = currInvY; + tempMobItem._y2 = currInvY + _invLineH - 1; + //tempMobItem._name = ; + //tempMobItem._examText = ; + _invMobList.push_back(tempMobItem); + } currInvX += _invLineW + _invLineSkipX; item++; } @@ -1260,8 +1301,43 @@ void PrinceEngine::prepareInventoryToView() { //mov d MobPriAddr,o InvMobPri } -void PrinceEngine::displayInventory() { +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()) { + //MST_Shadow + // TODO! + //shad0: + if (_mainHero->_inventory[item] != 0) { + int itemNr = _mainHero->_inventory[item]; + if (itemNr != 68) { + showSprite(_allInvList[itemNr].getSurface(), currInvX, currInvY, 10000, false); // temp + } else { + // candle item: + } + } + } + currInvX += _invLineW + _invLineSkipX; + item++; + } + currInvX = _invLineX; + currInvY += _invLineSkipY + _invLineH; + } +} +void PrinceEngine::displayInventory() { + _mainHero->_inventory.clear(); + _mainHero->_inventory.push_back(0); + _mainHero->_inventory.push_back(1); + _mainHero->_inventory.push_back(2); + _mainHero->_inventory.push_back(3); + _mainHero->_inventory.push_back(4); + _mainHero->_inventory.push_back(5); + prepareInventoryToView(); + drawInvItems(); } void PrinceEngine::mainLoop() { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 4e1073b375f3..0f76ffc1e406 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -179,6 +179,11 @@ struct Mask { } }; +struct InvItem { + Graphics::Surface *_surface; + Graphics::Surface *getSurface() const { return _surface; } +}; + struct DrawNode { int posX; int posY; @@ -265,21 +270,25 @@ class PrinceEngine : public Engine { void showMask(int maskNr, Graphics::Surface *originalRoomSurface); void clsMasks(); + static const int16 kMaxInv = 90; // max amount of inventory items in whole game + uint32 _invTxtSize; byte *_invTxt; int _invLineX; int _invLineY; - int _invLine; - int _invLines; + int _invLine; // number of items in one line + int _invLines; // number of lines with inventory items int _invLineW; int _invLineH; int _maxInvW; int _invLineSkipX; int _invLineSkipY; + bool loadAllInv(); void rememberScreenInv(); void prepareInventoryToView(); + void drawInvItems(); void displayInventory(); int testAnimNr; @@ -334,6 +343,7 @@ class PrinceEngine : public Engine { Common::Array _objList; Common::Array _maskList; Common::Array _drawNodeList; + Common::Array _allInvList; Common::Array _invMobList; bool _flicLooped; From bb85844e7336baaa09fe7edcf16007c7ebe259d9 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 6 Jun 2014 03:21:47 +0200 Subject: [PATCH 140/374] PRINCE: Inventory update - first suitcase drawing --- engines/prince/graphics.cpp | 4 +- engines/prince/graphics.h | 2 +- engines/prince/mhwanh.h | 2 +- engines/prince/prince.cpp | 136 +++++++++++++++++++++--------------- engines/prince/prince.h | 5 ++ 5 files changed, 88 insertions(+), 61 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 210b9d9ef984..49cc88c8ae17 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -73,11 +73,11 @@ void GraphicsMan::draw(uint16 posX, uint16 posY, const Graphics::Surface *s) { change(); } -void GraphicsMan::drawTransparentIntro(int32 posX, int32 posY, const Graphics::Surface *s) { +void GraphicsMan::drawTransparentSurface(int32 posX, int32 posY, const Graphics::Surface *s, int transColor) { for (int y = 0; y < s->h; y++) { for (int x = 0; x < s->w; x++) { byte pixel = *((byte*)s->getBasePtr(x, y)); - if (pixel != 255) { + if (pixel != transColor) { if (x + posX < _frontScreen->w && x + posX >= 0) { if (y + posY < _frontScreen->h && y + posY >= 0) { *((byte*)_frontScreen->getBasePtr(x + posX, y + posY)) = pixel; diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index 2756bf477708..cd3d8b4f354d 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -45,7 +45,7 @@ class GraphicsMan void makeShadowTable(int brightness, byte *shadowTable); void draw(uint16 x, uint16 y, const Graphics::Surface *s); - void drawTransparentIntro(int32 posX, int32 poxY, const Graphics::Surface *s); + void drawTransparentSurface(int32 posX, int32 poxY, const Graphics::Surface *s, int transColor); static void drawTransparent(Graphics::Surface *frontScreen, DrawNode *drawNode); static void drawAsShadow(Graphics::Surface *frontScreen, DrawNode *drawNode); diff --git a/engines/prince/mhwanh.h b/engines/prince/mhwanh.h index 5364c5d20af0..02256569cea3 100644 --- a/engines/prince/mhwanh.h +++ b/engines/prince/mhwanh.h @@ -38,7 +38,7 @@ class MhwanhDecoder : public Image::ImageDecoder { // ImageDecoder API void destroy(); virtual bool loadStream(Common::SeekableReadStream &stream); - virtual const Graphics::Surface *getSurface() const { return _surface; } + virtual Graphics::Surface *getSurface() const { return _surface; } virtual const byte *getPalette() const { return _palette; } uint16 getPaletteCount() const { return _paletteColorCount; } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index ad825fb14017..a535e4f234fd 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -79,7 +79,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), _room(nullptr), testAnimNr(0), testAnimFrame(0), _frameNr(0), _cursor1(nullptr), _cursor2(nullptr), _font(nullptr), _suitcaseBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0), _randomSource("prince"), - _invLineX(134), _invLineY(176), _invLine(5), _invLines(3), _invLineW(70), _invLineH(76), _invLineSkipX(2), _invLineSkipY(3) { + _invLineX(134), _invLineY(176), _invLine(5), _invLines(3), _invLineW(70), _invLineH(76), _invLineSkipX(2), _invLineSkipY(3), + _showInventoryFlag(false), _inventoryBackgroundRemember(false) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -408,7 +409,7 @@ bool PrinceEngine::playNextFrame() { const Graphics::Surface *s = _flicPlayer.decodeNextFrame(); if (s) { - _graph->drawTransparentIntro(0, 0, s); + _graph->drawTransparentSurface(0, 0, s, 255); _graph->change(); } else if (_flicLooped) { _flicPlayer.rewind(); @@ -654,6 +655,7 @@ void PrinceEngine::keyHandler(Common::Event event) { break; case Common::KEYCODE_i: _mainHero->_middleY -= 5; + inventoryFlagChange(); break; case Common::KEYCODE_k: _mainHero->_middleY += 5; @@ -1183,69 +1185,76 @@ void PrinceEngine::freeDrawNodes() { } void PrinceEngine::drawScreen() { - const Graphics::Surface *roomSurface = _roomBmp->getSurface(); - Graphics::Surface visiblePart; - if (roomSurface) { - visiblePart = roomSurface->getSubArea(Common::Rect(_picWindowX, 0, roomSurface->w, roomSurface->h)); - _graph->draw(0, 0, &visiblePart); - } - - Graphics::Surface *mainHeroSurface = NULL; - if (_mainHero->_visible) { - mainHeroSurface = _mainHero->getSurface(); - if (mainHeroSurface) { - _mainHero->showHeroShadow(mainHeroSurface); + if (!_showInventoryFlag || _inventoryBackgroundRemember) { + const Graphics::Surface *roomSurface = _roomBmp->getSurface(); + Graphics::Surface visiblePart; + if (roomSurface) { + visiblePart = roomSurface->getSubArea(Common::Rect(_picWindowX, 0, roomSurface->w, roomSurface->h)); + _graph->draw(0, 0, &visiblePart); + } - DrawNode newDrawNode; - newDrawNode.posX = _mainHero->_drawX; - newDrawNode.posY = _mainHero->_drawY; - newDrawNode.posZ = _mainHero->_drawZ; - newDrawNode.width = 0; - newDrawNode.height = 0; - newDrawNode.originalRoomSurface = nullptr; - newDrawNode.data = nullptr; - newDrawNode.drawFunction = &_graph->drawTransparent; - - if (_mainHero->_zoomFactor != 0) { - Graphics::Surface *zoomedHeroSurface = _mainHero->zoomSprite(mainHeroSurface); - newDrawNode.s = zoomedHeroSurface; - newDrawNode.freeSurfaceSMemory = true; - } else { - newDrawNode.s = mainHeroSurface; - newDrawNode.freeSurfaceSMemory = false; + Graphics::Surface *mainHeroSurface = NULL; + if (_mainHero->_visible) { + mainHeroSurface = _mainHero->getSurface(); + if (mainHeroSurface) { + _mainHero->showHeroShadow(mainHeroSurface); + + DrawNode newDrawNode; + newDrawNode.posX = _mainHero->_drawX; + newDrawNode.posY = _mainHero->_drawY; + newDrawNode.posZ = _mainHero->_drawZ; + newDrawNode.width = 0; + newDrawNode.height = 0; + newDrawNode.originalRoomSurface = nullptr; + newDrawNode.data = nullptr; + newDrawNode.drawFunction = &_graph->drawTransparent; + + if (_mainHero->_zoomFactor != 0) { + Graphics::Surface *zoomedHeroSurface = _mainHero->zoomSprite(mainHeroSurface); + newDrawNode.s = zoomedHeroSurface; + newDrawNode.freeSurfaceSMemory = true; + } else { + newDrawNode.s = mainHeroSurface; + newDrawNode.freeSurfaceSMemory = false; + } + _drawNodeList.push_back(newDrawNode); } - _drawNodeList.push_back(newDrawNode); } - } - showBackAnims(); + showBackAnims(); - showObjects(); + showObjects(); - if (roomSurface) { - insertMasks(&visiblePart); - } - - showParallax(); + if (roomSurface) { + insertMasks(&visiblePart); + } - displayInventory(); // temp + showParallax(); - runDrawNodes(); + runDrawNodes(); - freeDrawNodes(); + freeDrawNodes(); - if (_mainHero->_visible) { - mainHeroSurface->free(); - delete mainHeroSurface; - } + if (_mainHero->_visible) { + mainHeroSurface->free(); + delete mainHeroSurface; + } - clsMasks(); + clsMasks(); - playNextFrame(); + playNextFrame(); - hotspot(); + if (!_inventoryBackgroundRemember) { + hotspot(); + showTexts(); + } else { + rememberScreenInv(); + _inventoryBackgroundRemember = false; + } - showTexts(); + } else { + displayInventory(); + } getDebugger()->onFrame(); @@ -1253,7 +1262,16 @@ void PrinceEngine::drawScreen() { } void PrinceEngine::rememberScreenInv() { + _backgroundForInventory = _graph->_frontScreen; +} +void PrinceEngine::inventoryFlagChange() { + if (!_showInventoryFlag) { + _showInventoryFlag = true; + _inventoryBackgroundRemember = true; + } else { + _showInventoryFlag = false; + } } void PrinceEngine::prepareInventoryToView() { @@ -1269,12 +1287,10 @@ void PrinceEngine::prepareInventoryToView() { _maxInvW = (374 - 2 * _invLine) / _invLine; _invLineW = _maxInvW - 2; - rememberScreenInv(); - int currInvX = _invLineX; int currInvY = _invLineY; - int item = 0; + uint item = 0; for (int i = 0 ; i < _invLines; i++) { for (int j = 0; j < _invLine; j++) { Mob tempMobItem; @@ -1311,14 +1327,14 @@ void PrinceEngine::drawInvItems() { //MST_Shadow // TODO! //shad0: - if (_mainHero->_inventory[item] != 0) { + //if (_mainHero->_inventory[item] != 0) { int itemNr = _mainHero->_inventory[item]; if (itemNr != 68) { - showSprite(_allInvList[itemNr].getSurface(), currInvX, currInvY, 10000, false); // temp + _graph->drawTransparentSurface(currInvX, currInvY, _allInvList[itemNr].getSurface(), 0); } else { // candle item: } - } + //} } currInvX += _invLineW + _invLineSkipX; item++; @@ -1336,7 +1352,13 @@ void PrinceEngine::displayInventory() { _mainHero->_inventory.push_back(3); _mainHero->_inventory.push_back(4); _mainHero->_inventory.push_back(5); + prepareInventoryToView(); + + _graph->drawTransparentSurface(0, 0, _backgroundForInventory, 0); + Graphics::Surface *suitcase = _suitcaseBmp->getSurface(); + _graph->drawTransparentSurface(0, 0, suitcase, 0); + drawInvItems(); } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 0f76ffc1e406..69195872713c 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -275,6 +275,8 @@ class PrinceEngine : public Engine { uint32 _invTxtSize; byte *_invTxt; + bool _showInventoryFlag; + bool _inventoryBackgroundRemember; int _invLineX; int _invLineY; int _invLine; // number of items in one line @@ -285,12 +287,15 @@ class PrinceEngine : public Engine { int _invLineSkipX; int _invLineSkipY; + void inventoryFlagChange(); bool loadAllInv(); void rememberScreenInv(); void prepareInventoryToView(); void drawInvItems(); void displayInventory(); + Graphics::Surface *_backgroundForInventory; + int testAnimNr; int testAnimFrame; From 5309e52259d65899015af6e9bdaed578f9d52b52 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 6 Jun 2014 13:28:14 +0200 Subject: [PATCH 141/374] PRINCE: Items in inventory - drawing position fix --- engines/prince/prince.cpp | 19 ++++++++++++++----- engines/prince/prince.h | 3 +-- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index a535e4f234fd..6e3b22e07be1 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -79,8 +79,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), _room(nullptr), testAnimNr(0), testAnimFrame(0), _frameNr(0), _cursor1(nullptr), _cursor2(nullptr), _font(nullptr), _suitcaseBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0), _randomSource("prince"), - _invLineX(134), _invLineY(176), _invLine(5), _invLines(3), _invLineW(70), _invLineH(76), _invLineSkipX(2), _invLineSkipY(3), - _showInventoryFlag(false), _inventoryBackgroundRemember(false) { + _invLineX(134), _invLineY(176), _invLine(5), _invLines(3), _invLineW(70), _invLineH(76), _maxInvW(72), _maxInvH(76), + _invLineSkipX(2), _invLineSkipY(3), _showInventoryFlag(false), _inventoryBackgroundRemember(false) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -1262,7 +1262,6 @@ void PrinceEngine::drawScreen() { } void PrinceEngine::rememberScreenInv() { - _backgroundForInventory = _graph->_frontScreen; } void PrinceEngine::inventoryFlagChange() { @@ -1330,7 +1329,16 @@ void PrinceEngine::drawInvItems() { //if (_mainHero->_inventory[item] != 0) { int itemNr = _mainHero->_inventory[item]; if (itemNr != 68) { - _graph->drawTransparentSurface(currInvX, currInvY, _allInvList[itemNr].getSurface(), 0); + Graphics::Surface *itemSurface = _allInvList[itemNr].getSurface(); + int drawX = currInvX; + int drawY = currInvY; + if (itemSurface->w < _maxInvW) { + drawX += (_maxInvW - itemSurface->w) / 2; + } + if (itemSurface->h < _maxInvH) { + drawY += (_maxInvH - itemSurface->h) / 2; + } + _graph->drawTransparentSurface(drawX, drawY, itemSurface, 0); } else { // candle item: } @@ -1345,6 +1353,7 @@ void PrinceEngine::drawInvItems() { } void PrinceEngine::displayInventory() { + // temp: _mainHero->_inventory.clear(); _mainHero->_inventory.push_back(0); _mainHero->_inventory.push_back(1); @@ -1355,7 +1364,7 @@ void PrinceEngine::displayInventory() { prepareInventoryToView(); - _graph->drawTransparentSurface(0, 0, _backgroundForInventory, 0); + _graph->drawTransparentSurface(0, 0, _graph->_frontScreen, 0); Graphics::Surface *suitcase = _suitcaseBmp->getSurface(); _graph->drawTransparentSurface(0, 0, suitcase, 0); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 69195872713c..036043ff1391 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -284,6 +284,7 @@ class PrinceEngine : public Engine { int _invLineW; int _invLineH; int _maxInvW; + int _maxInvH; int _invLineSkipX; int _invLineSkipY; @@ -294,8 +295,6 @@ class PrinceEngine : public Engine { void drawInvItems(); void displayInventory(); - Graphics::Surface *_backgroundForInventory; - int testAnimNr; int testAnimFrame; From aeea3302d537d66d3f144f72bcfa9d083e8b512c Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 6 Jun 2014 17:34:40 +0200 Subject: [PATCH 142/374] PRINCE: addInvObj() implementation, drawInvItems() update --- engines/prince/prince.cpp | 98 ++++++++++++++++++++++++++++++++------- engines/prince/prince.h | 3 ++ 2 files changed, 83 insertions(+), 18 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 6e3b22e07be1..7a716fd98a7c 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -80,7 +80,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _frameNr(0), _cursor1(nullptr), _cursor2(nullptr), _font(nullptr), _suitcaseBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0), _randomSource("prince"), _invLineX(134), _invLineY(176), _invLine(5), _invLines(3), _invLineW(70), _invLineH(76), _maxInvW(72), _maxInvH(76), - _invLineSkipX(2), _invLineSkipY(3), _showInventoryFlag(false), _inventoryBackgroundRemember(false) { + _invLineSkipX(2), _invLineSkipY(3), _showInventoryFlag(false), _inventoryBackgroundRemember(false), + _mst_shadow(0), _mst_shadow2(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -659,6 +660,7 @@ void PrinceEngine::keyHandler(Common::Event event) { break; case Common::KEYCODE_k: _mainHero->_middleY += 5; + addInvObj(); break; case Common::KEYCODE_j: _mainHero->_middleX -= 5; @@ -1261,6 +1263,55 @@ void PrinceEngine::drawScreen() { _graph->update(); } +void PrinceEngine::addInvObj() { + changeCursor(0); // turn on cursor later? + //prepareInventoryToView(); + //inventoryFlagChange(); + + if (!_flags->getFlagValue(Flags::CURSEBLINK)) { + + loadSample(27, "PRZEDMIO.WAV"); + playSample(27, 0); + + _mst_shadow2 = 1; + while (_mst_shadow2 < 512) { + uint32 currentTime = _system->getMillis(); + displayInventory(); + //getDebugger()->onFrame(); + _graph->update(); + _mst_shadow2 += 50; + int delay = 1000/15 - int32(_system->getMillis() - currentTime); + delay = delay < 0 ? 0 : delay; + _system->delayMillis(delay); + } + while (_mst_shadow2 > 256) { + uint32 currentTime = _system->getMillis(); + displayInventory(); + //getDebugger()->onFrame(); + _graph->update(); + _mst_shadow2 -= 42; + int delay = 1000/15 - int32(_system->getMillis() - currentTime); + delay = delay < 0 ? 0 : delay; + _system->delayMillis(delay); + } + _mst_shadow2 = 0; + + for (int i = 0; i < 20; i++) { + uint32 currentTime = _system->getMillis(); + displayInventory(); + //getDebugger()->onFrame(); + _graph->update(); + int delay = 1000/15 - int32(_system->getMillis() - currentTime); + delay = delay < 0 ? 0 : delay; + _system->delayMillis(delay); + } + + } else { + //CURSEBLINK: + + } +} + void PrinceEngine::rememberScreenInv() { } @@ -1323,26 +1374,37 @@ void PrinceEngine::drawInvItems() { for (int i = 0 ; i < _invLines; i++) { for (int j = 0; j < _invLine; j++) { if (item < _mainHero->_inventory.size()) { - //MST_Shadow - // TODO! - //shad0: - //if (_mainHero->_inventory[item] != 0) { - int itemNr = _mainHero->_inventory[item]; - if (itemNr != 68) { - Graphics::Surface *itemSurface = _allInvList[itemNr].getSurface(); - int drawX = currInvX; - int drawY = currInvY; - if (itemSurface->w < _maxInvW) { - drawX += (_maxInvW - itemSurface->w) / 2; - } - if (itemSurface->h < _maxInvH) { - drawY += (_maxInvH - itemSurface->h) / 2; + int itemNr = _mainHero->_inventory[item]; + _mst_shadow = 0; + if (_mst_shadow2 != 0) { + if (!_flags->getFlagValue(Flags::CURSEBLINK)) { + //normal: + if (item + 1 == _mainHero->_inventory.size()) { // last item in inventory + _mst_shadow = 1; } - _graph->drawTransparentSurface(drawX, drawY, itemSurface, 0); + } else if (itemNr == 1 || itemNr == 3 || itemNr == 4 || itemNr == 7) { + _mst_shadow = 1; + } + } + //shad0: + if (itemNr != 68) { + Graphics::Surface *itemSurface = _allInvList[itemNr].getSurface(); + int drawX = currInvX; + int drawY = currInvY; + if (itemSurface->w < _maxInvW) { + drawX += (_maxInvW - itemSurface->w) / 2; + } + if (itemSurface->h < _maxInvH) { + drawY += (_maxInvH - itemSurface->h) / 2; + } + if (!_mst_shadow) { + _graph->drawTransparentSurface(drawX, drawY, itemSurface, 0); //TODO - ShowSprite0 } else { - // candle item: + _graph->drawTransparentSurface(drawX, drawY, itemSurface, 0); //TODO - ShowSprite01 } - //} + } else { + // candle item: + } } currInvX += _invLineW + _invLineSkipX; item++; diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 036043ff1391..1694286f5407 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -287,6 +287,8 @@ class PrinceEngine : public Engine { int _maxInvH; int _invLineSkipX; int _invLineSkipY; + int _mst_shadow; + int _mst_shadow2; // blinking after adding new item void inventoryFlagChange(); bool loadAllInv(); @@ -294,6 +296,7 @@ class PrinceEngine : public Engine { void prepareInventoryToView(); void drawInvItems(); void displayInventory(); + void addInvObj(); int testAnimNr; int testAnimFrame; From dcd9c48906f9039d05c9545a4f90418f10aeef2a Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 6 Jun 2014 22:21:39 +0200 Subject: [PATCH 143/374] PRINCE: getBlendTableColor(), drawTransparentWithBlend() --- engines/prince/graphics.cpp | 122 ++++++++++++++++++++++++++++++++++++ engines/prince/graphics.h | 6 ++ engines/prince/prince.cpp | 10 ++- engines/prince/prince.h | 2 +- 4 files changed, 133 insertions(+), 7 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 49cc88c8ae17..298337673fba 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -24,6 +24,8 @@ #include "prince/prince.h" +#include "prince/mhwanh.h" + #include "graphics/palette.h" #include "common/memstream.h" @@ -89,6 +91,29 @@ void GraphicsMan::drawTransparentSurface(int32 posX, int32 posY, const Graphics: change(); } +void GraphicsMan::drawTransparentWithBlend(int32 posX, int32 posY, const Graphics::Surface *s, int transColor) { + _blendTable = new byte[256]; + for (int i = 0; i < 256; i++) { + _blendTable[i] = 255; + } + for (int y = 0; y < s->h; y++) { + for (int x = 0; x < s->w; x++) { + byte pixel = *((byte*)s->getBasePtr(x, y)); + if (pixel != transColor) { + if (x + posX < _frontScreen->w && x + posX >= 0) { + if (y + posY < _frontScreen->h && y + posY >= 0) { + byte backgroundPixel = *((byte*)_frontScreen->getBasePtr(x + posX, y + posY)); + byte blendPixel = getBlendTableColor(pixel, backgroundPixel); + *((byte*)_frontScreen->getBasePtr(x + posX, y + posY)) = blendPixel; + } + } + } + } + } + delete _blendTable; + change(); +} + void GraphicsMan::drawTransparent(Graphics::Surface *frontScreen, DrawNode *drawNode) { for (int y = 0; y < drawNode->s->h; y++) { for (int x = 0; x < drawNode->s->w; x++) { @@ -147,6 +172,103 @@ void GraphicsMan::drawAsShadow(Graphics::Surface *frontScreen, DrawNode *drawNod } } +byte GraphicsMan::getBlendTableColor(byte pixelColor, byte backgroundPixelColor) { + int32 redFirstOrg, greenFirstOrg, blueFirstOrg; + int32 redFirstBack, greenFirstBack, blueFirstBack; + int32 redSecondOrg, greenSecondOrg, blueSecondOrg; + int32 redNew, greenNew, blueNew; + + int32 sumOfColorValues; + int32 bigValue; + int32 currColor; + + if (_blendTable[pixelColor] != 255) { + currColor = _blendTable[pixelColor]; + } else { + const byte *originalPalette = _vm->_roomBmp->getPalette(); //? + const byte *suitcasePalette = _vm->_suitcaseBmp->getPalette(); //? + + //debug("backgroundPixelColor: %d", backgroundPixelColor); + //debug("orgpalette: %d", pixelColor); + //debug("mst_shadow: %d", _vm->_mst_shadow); + + redFirstOrg = originalPalette[pixelColor * 4] * _vm->_mst_shadow / 256; + if (redFirstOrg >= 256) { + redFirstOrg = 255; + } + if (_vm->_mst_shadow <= 256) { + redFirstBack = suitcasePalette[backgroundPixelColor * 4] * (256 - _vm->_mst_shadow) / 256; + if (redFirstBack >= 256) { + redFirstBack = 255; + } + redFirstOrg += redFirstBack; + if (redFirstOrg >= 256) { + redFirstOrg = 255; + } + } + + greenFirstOrg = originalPalette[pixelColor * 4 + 1] * _vm->_mst_shadow / 256; + if (greenFirstOrg >= 256) { + greenFirstOrg = 255; + } + if (_vm->_mst_shadow <= 256) { + greenFirstBack = suitcasePalette[backgroundPixelColor * 4 + 1] * (256 - _vm->_mst_shadow) / 256; + if (greenFirstBack >= 256) { + greenFirstBack = 255; + } + greenFirstOrg += greenFirstBack; + if (greenFirstOrg >= 256) { + greenFirstOrg = 255; + } + } + + blueFirstOrg = originalPalette[pixelColor * 4 + 2] * _vm->_mst_shadow / 256; + if (blueFirstOrg >= 256) { + blueFirstOrg = 255; + } + if (_vm->_mst_shadow <= 256) { + blueFirstBack = suitcasePalette[backgroundPixelColor * 4 + 2] * (256 - _vm->_mst_shadow) / 256; + if (blueFirstBack >= 256) { + blueFirstBack = 255; + } + blueFirstOrg += blueFirstBack; + if (blueFirstOrg >= 256) { + blueFirstOrg = 255; + } + } + + currColor = 0; + bigValue = 999999999; // infinity + for (int j = 0; j < 256; j++) { + redSecondOrg = originalPalette[3 * j]; + redNew = redFirstOrg - redSecondOrg; + redNew = redNew * redNew; + + greenSecondOrg = originalPalette[3 * j + 1]; + greenNew = greenFirstOrg - greenSecondOrg; + greenNew = greenNew * greenNew; + + blueSecondOrg = originalPalette[3 * j + 2]; + blueNew = blueFirstOrg - blueSecondOrg; + blueNew = blueNew * blueNew; + + sumOfColorValues = redNew + greenNew + blueNew; + + if (sumOfColorValues < bigValue) { + bigValue = sumOfColorValues; + currColor = j; + } + + if (sumOfColorValues == 0) { + break; + } + } + _blendTable[pixelColor] = currColor; + } + //debug("currColor: %d", currColor); + return currColor; +} + void GraphicsMan::makeShadowTable(int brightness, byte *shadowPalette) { int32 redFirstOrg, greenFirstOrg, blueFirstOrg; int32 redSecondOrg, greenSecondOrg, blueSecondOrg; diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index cd3d8b4f354d..7651dae7a196 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -30,6 +30,7 @@ namespace Prince { class PrinceEngine; struct DrawNode; +class MhwanhDecoder; class GraphicsMan { @@ -46,11 +47,14 @@ class GraphicsMan void draw(uint16 x, uint16 y, const Graphics::Surface *s); void drawTransparentSurface(int32 posX, int32 poxY, const Graphics::Surface *s, int transColor); + void drawTransparentWithBlend(int32 posX, int32 poxY, const Graphics::Surface *s, int transColor); static void drawTransparent(Graphics::Surface *frontScreen, DrawNode *drawNode); static void drawAsShadow(Graphics::Surface *frontScreen, DrawNode *drawNode); static void drawMask(Graphics::Surface *frontScreen, DrawNode *drawNode); + byte getBlendTableColor(byte pixelColor, byte backgroundPixelColor); + Graphics::Surface *_frontScreen; Graphics::Surface *_backScreen; const Graphics::Surface *_roomBackground; @@ -60,6 +64,8 @@ class GraphicsMan static const byte kShadowColor = 191; + byte *_blendTable; + private: PrinceEngine *_vm; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 7a716fd98a7c..a0405c76db36 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1398,9 +1398,10 @@ void PrinceEngine::drawInvItems() { drawY += (_maxInvH - itemSurface->h) / 2; } if (!_mst_shadow) { - _graph->drawTransparentSurface(drawX, drawY, itemSurface, 0); //TODO - ShowSprite0 + _graph->drawTransparentSurface(drawX, drawY, itemSurface, 0); } else { - _graph->drawTransparentSurface(drawX, drawY, itemSurface, 0); //TODO - ShowSprite01 + _mst_shadow = _mst_shadow2; + _graph->drawTransparentWithBlend(drawX, drawY, itemSurface, 0); //TODO - ShowSprite01 } } else { // candle item: @@ -1418,11 +1419,8 @@ void PrinceEngine::displayInventory() { // temp: _mainHero->_inventory.clear(); _mainHero->_inventory.push_back(0); - _mainHero->_inventory.push_back(1); _mainHero->_inventory.push_back(2); - _mainHero->_inventory.push_back(3); - _mainHero->_inventory.push_back(4); - _mainHero->_inventory.push_back(5); + _mainHero->_inventory.push_back(1); prepareInventoryToView(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 1694286f5407..71512f0d8ade 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -254,6 +254,7 @@ class PrinceEngine : public Engine { int32 _picWindowX; int32 _picWindowY; Image::BitmapDecoder *_roomBmp; + MhwanhDecoder *_suitcaseBmp; Common::Array _animList; Common::Array _backAnimList; @@ -330,7 +331,6 @@ class PrinceEngine : public Engine { Common::RandomSource *_rnd; Cursor *_cursor1; Cursor *_cursor2; - MhwanhDecoder *_suitcaseBmp; Debugger *_debugger; GraphicsMan *_graph; Script *_script; From bc3ce22fe3a3fb6dfcf03cd230634bd6a96e5dcc Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 7 Jun 2014 00:49:03 +0200 Subject: [PATCH 144/374] PRINCE: getBlendTableColor() - fix for wrong colors --- engines/prince/graphics.cpp | 20 +++++++------------- engines/prince/prince.cpp | 4 +--- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 298337673fba..e516cd7980be 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -185,19 +185,14 @@ byte GraphicsMan::getBlendTableColor(byte pixelColor, byte backgroundPixelColor) if (_blendTable[pixelColor] != 255) { currColor = _blendTable[pixelColor]; } else { - const byte *originalPalette = _vm->_roomBmp->getPalette(); //? - const byte *suitcasePalette = _vm->_suitcaseBmp->getPalette(); //? + const byte *originalPalette = _vm->_roomBmp->getPalette(); - //debug("backgroundPixelColor: %d", backgroundPixelColor); - //debug("orgpalette: %d", pixelColor); - //debug("mst_shadow: %d", _vm->_mst_shadow); - - redFirstOrg = originalPalette[pixelColor * 4] * _vm->_mst_shadow / 256; + redFirstOrg = originalPalette[pixelColor * 3] * _vm->_mst_shadow / 256; if (redFirstOrg >= 256) { redFirstOrg = 255; } if (_vm->_mst_shadow <= 256) { - redFirstBack = suitcasePalette[backgroundPixelColor * 4] * (256 - _vm->_mst_shadow) / 256; + redFirstBack = originalPalette[backgroundPixelColor * 3] * (256 - _vm->_mst_shadow) / 256; if (redFirstBack >= 256) { redFirstBack = 255; } @@ -207,12 +202,12 @@ byte GraphicsMan::getBlendTableColor(byte pixelColor, byte backgroundPixelColor) } } - greenFirstOrg = originalPalette[pixelColor * 4 + 1] * _vm->_mst_shadow / 256; + greenFirstOrg = originalPalette[pixelColor * 3 + 1] * _vm->_mst_shadow / 256; if (greenFirstOrg >= 256) { greenFirstOrg = 255; } if (_vm->_mst_shadow <= 256) { - greenFirstBack = suitcasePalette[backgroundPixelColor * 4 + 1] * (256 - _vm->_mst_shadow) / 256; + greenFirstBack = originalPalette[backgroundPixelColor * 3 + 1] * (256 - _vm->_mst_shadow) / 256; if (greenFirstBack >= 256) { greenFirstBack = 255; } @@ -222,12 +217,12 @@ byte GraphicsMan::getBlendTableColor(byte pixelColor, byte backgroundPixelColor) } } - blueFirstOrg = originalPalette[pixelColor * 4 + 2] * _vm->_mst_shadow / 256; + blueFirstOrg = originalPalette[pixelColor * 3 + 2] * _vm->_mst_shadow / 256; if (blueFirstOrg >= 256) { blueFirstOrg = 255; } if (_vm->_mst_shadow <= 256) { - blueFirstBack = suitcasePalette[backgroundPixelColor * 4 + 2] * (256 - _vm->_mst_shadow) / 256; + blueFirstBack = originalPalette[backgroundPixelColor * 3 + 2] * (256 - _vm->_mst_shadow) / 256; if (blueFirstBack >= 256) { blueFirstBack = 255; } @@ -265,7 +260,6 @@ byte GraphicsMan::getBlendTableColor(byte pixelColor, byte backgroundPixelColor) } _blendTable[pixelColor] = currColor; } - //debug("currColor: %d", currColor); return currColor; } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index a0405c76db36..1e365be7628f 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1378,7 +1378,6 @@ void PrinceEngine::drawInvItems() { _mst_shadow = 0; if (_mst_shadow2 != 0) { if (!_flags->getFlagValue(Flags::CURSEBLINK)) { - //normal: if (item + 1 == _mainHero->_inventory.size()) { // last item in inventory _mst_shadow = 1; } @@ -1386,7 +1385,6 @@ void PrinceEngine::drawInvItems() { _mst_shadow = 1; } } - //shad0: if (itemNr != 68) { Graphics::Surface *itemSurface = _allInvList[itemNr].getSurface(); int drawX = currInvX; @@ -1401,7 +1399,7 @@ void PrinceEngine::drawInvItems() { _graph->drawTransparentSurface(drawX, drawY, itemSurface, 0); } else { _mst_shadow = _mst_shadow2; - _graph->drawTransparentWithBlend(drawX, drawY, itemSurface, 0); //TODO - ShowSprite01 + _graph->drawTransparentWithBlend(drawX, drawY, itemSurface, 0); } } else { // candle item: From 3bd4ccac9795226e83e00658ae171818aad7f584 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 7 Jun 2014 01:51:40 +0200 Subject: [PATCH 145/374] PRINCE: Candle inventory item animation - drawInvItems() update --- engines/prince/prince.cpp | 48 +++++++++++++++++++++++++-------------- engines/prince/prince.h | 3 +++ 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 1e365be7628f..93c82701a9d1 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -81,7 +81,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _suitcaseBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0), _randomSource("prince"), _invLineX(134), _invLineY(176), _invLine(5), _invLines(3), _invLineW(70), _invLineH(76), _maxInvW(72), _maxInvH(76), _invLineSkipX(2), _invLineSkipY(3), _showInventoryFlag(false), _inventoryBackgroundRemember(false), - _mst_shadow(0), _mst_shadow2(0) { + _mst_shadow(0), _mst_shadow2(0), _candleCounter(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -576,7 +576,8 @@ bool PrinceEngine::loadAllInv() { return true; } - invStream->skip(4); + tempInvItem._x = invStream->readUint16LE(); + tempInvItem._y = invStream->readUint16LE(); int width = invStream->readUint16LE(); int height = invStream->readUint16LE(); tempInvItem._surface = new Graphics::Surface(); @@ -1374,7 +1375,7 @@ void PrinceEngine::drawInvItems() { for (int i = 0 ; i < _invLines; i++) { for (int j = 0; j < _invLine; j++) { if (item < _mainHero->_inventory.size()) { - int itemNr = _mainHero->_inventory[item]; + int itemNr = _mainHero->_inventory[item]; // itemNr =- 1 ? _mst_shadow = 0; if (_mst_shadow2 != 0) { if (!_flags->getFlagValue(Flags::CURSEBLINK)) { @@ -1385,24 +1386,35 @@ void PrinceEngine::drawInvItems() { _mst_shadow = 1; } } + + int drawX = currInvX; + int drawY = currInvY; + Graphics::Surface *itemSurface = NULL; if (itemNr != 68) { - Graphics::Surface *itemSurface = _allInvList[itemNr].getSurface(); - int drawX = currInvX; - int drawY = currInvY; - if (itemSurface->w < _maxInvW) { - drawX += (_maxInvW - itemSurface->w) / 2; - } + itemSurface = _allInvList[itemNr].getSurface(); if (itemSurface->h < _maxInvH) { drawY += (_maxInvH - itemSurface->h) / 2; } - if (!_mst_shadow) { - _graph->drawTransparentSurface(drawX, drawY, itemSurface, 0); - } else { - _mst_shadow = _mst_shadow2; - _graph->drawTransparentWithBlend(drawX, drawY, itemSurface, 0); - } } 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(drawX, drawY, itemSurface, 0); + } else { + _mst_shadow = _mst_shadow2; + _graph->drawTransparentWithBlend(drawX, drawY, itemSurface, 0); } } currInvX += _invLineW + _invLineSkipX; @@ -1416,9 +1428,11 @@ void PrinceEngine::drawInvItems() { void PrinceEngine::displayInventory() { // temp: _mainHero->_inventory.clear(); - _mainHero->_inventory.push_back(0); - _mainHero->_inventory.push_back(2); _mainHero->_inventory.push_back(1); + _mainHero->_inventory.push_back(3); + _mainHero->_inventory.push_back(7); + _mainHero->_inventory.push_back(4); + _mainHero->_inventory.push_back(68); prepareInventoryToView(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 71512f0d8ade..2822c5099e5a 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -180,6 +180,8 @@ struct Mask { }; struct InvItem { + int _x; + int _y; Graphics::Surface *_surface; Graphics::Surface *getSurface() const { return _surface; } }; @@ -290,6 +292,7 @@ class PrinceEngine : public Engine { int _invLineSkipY; int _mst_shadow; int _mst_shadow2; // blinking after adding new item + int _candleCounter; // special counter for candle inventory item void inventoryFlagChange(); bool loadAllInv(); From 43732d60274bb44ae995ad294ba94c363460344a Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 7 Jun 2014 01:56:35 +0200 Subject: [PATCH 146/374] PRINCE: pause() implementation --- engines/prince/prince.cpp | 25 ++++++++++--------------- engines/prince/prince.h | 1 + 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 93c82701a9d1..240133fbedb1 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1264,6 +1264,13 @@ void PrinceEngine::drawScreen() { _graph->update(); } +void PrinceEngine::pause() { + uint32 currentTime = _system->getMillis(); + int delay = 1000/15 - int32(_system->getMillis() - currentTime); + delay = delay < 0 ? 0 : delay; + _system->delayMillis(delay); +} + void PrinceEngine::addInvObj() { changeCursor(0); // turn on cursor later? //prepareInventoryToView(); @@ -1276,35 +1283,23 @@ void PrinceEngine::addInvObj() { _mst_shadow2 = 1; while (_mst_shadow2 < 512) { - uint32 currentTime = _system->getMillis(); displayInventory(); - //getDebugger()->onFrame(); _graph->update(); _mst_shadow2 += 50; - int delay = 1000/15 - int32(_system->getMillis() - currentTime); - delay = delay < 0 ? 0 : delay; - _system->delayMillis(delay); + pause(); } while (_mst_shadow2 > 256) { - uint32 currentTime = _system->getMillis(); displayInventory(); - //getDebugger()->onFrame(); _graph->update(); _mst_shadow2 -= 42; - int delay = 1000/15 - int32(_system->getMillis() - currentTime); - delay = delay < 0 ? 0 : delay; - _system->delayMillis(delay); + pause(); } _mst_shadow2 = 0; for (int i = 0; i < 20; i++) { - uint32 currentTime = _system->getMillis(); displayInventory(); - //getDebugger()->onFrame(); _graph->update(); - int delay = 1000/15 - int32(_system->getMillis() - currentTime); - delay = delay < 0 ? 0 : delay; - _system->delayMillis(delay); + pause(); } } else { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 2822c5099e5a..cb80529d4e3c 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -324,6 +324,7 @@ class PrinceEngine : public Engine { void runDrawNodes(); void freeDrawNodes(); void makeShadowTable(int brightness); + void pause(); uint32 getTextWidth(const char *s); void debugEngine(const char *s, ...); From 2f1c6cec41c6b1e951c6f4c1e4f6b7f519769b91 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 7 Jun 2014 02:11:31 +0200 Subject: [PATCH 147/374] PRINCE: addInvObj() - when CURSEBLINK flag on --- engines/prince/prince.cpp | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 240133fbedb1..c7c5a8fbcfc2 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -665,6 +665,9 @@ void PrinceEngine::keyHandler(Common::Event event) { break; case Common::KEYCODE_j: _mainHero->_middleX -= 5; + _flags->setFlagValue(Flags::CURSEBLINK, 1); + addInvObj(); + _flags->setFlagValue(Flags::CURSEBLINK, 0); break; case Common::KEYCODE_l: _mainHero->_middleX += 5; @@ -1274,7 +1277,6 @@ void PrinceEngine::pause() { void PrinceEngine::addInvObj() { changeCursor(0); // turn on cursor later? //prepareInventoryToView(); - //inventoryFlagChange(); if (!_flags->getFlagValue(Flags::CURSEBLINK)) { @@ -1294,17 +1296,29 @@ void PrinceEngine::addInvObj() { _mst_shadow2 -= 42; pause(); } - _mst_shadow2 = 0; - - for (int i = 0; i < 20; i++) { - displayInventory(); - _graph->update(); - pause(); - } - } else { //CURSEBLINK: - + for (int i = 0; i < 3; i++) { + _mst_shadow2 = 256; + while (_mst_shadow2 < 512) { + displayInventory(); + _graph->update(); + _mst_shadow2 += 50; + pause(); + } + while (_mst_shadow2 > 256) { + displayInventory(); + _graph->update(); + _mst_shadow2 -= 50; + pause(); + } + } + } + _mst_shadow2 = 0; + for (int i = 0; i < 20; i++) { + displayInventory(); + _graph->update(); + pause(); } } From 206211c21179297edc6ecee728cf67bc45573504 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 7 Jun 2014 14:17:37 +0200 Subject: [PATCH 148/374] PRINCE: Inventory closing - mouse handling --- engines/prince/prince.cpp | 23 ++++++++++++++++++++++- engines/prince/prince.h | 6 ++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index c7c5a8fbcfc2..1a09e83c65f6 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -81,7 +81,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _suitcaseBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0), _randomSource("prince"), _invLineX(134), _invLineY(176), _invLine(5), _invLines(3), _invLineW(70), _invLineH(76), _maxInvW(72), _maxInvH(76), _invLineSkipX(2), _invLineSkipY(3), _showInventoryFlag(false), _inventoryBackgroundRemember(false), - _mst_shadow(0), _mst_shadow2(0), _candleCounter(0) { + _mst_shadow(0), _mst_shadow2(0), _candleCounter(0), _invX1(53), _invY1(18), _invWidth(536), _invHeight(438), + _invCurInside(false) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -1450,6 +1451,26 @@ void PrinceEngine::displayInventory() { _graph->drawTransparentSurface(0, 0, suitcase, 0); drawInvItems(); + + Common::Rect _inventoryRect; + _inventoryRect.left = _invX1; + _inventoryRect.top = _invY1; + _inventoryRect.right = _invX1 + _invWidth; + _inventoryRect.bottom = _invY1 + _invHeight; + Common::Point mousePos = _system->getEventManager()->getMousePos(); + + if (!_invCurInside && _inventoryRect.contains(mousePos)) { + _invCurInside = true; + } + + if (_invCurInside && !_inventoryRect.contains(mousePos)) { + inventoryFlagChange(); + _invCurInside = false; + } +} + +void PrinceEngine::makeInvCursor() { + } void PrinceEngine::mainLoop() { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index cb80529d4e3c..9259fe703aaa 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -290,6 +290,11 @@ class PrinceEngine : public Engine { int _maxInvH; int _invLineSkipX; int _invLineSkipY; + int _invX1; + int _invY1; + int _invWidth; + int _invHeight; + bool _invCurInside; int _mst_shadow; int _mst_shadow2; // blinking after adding new item int _candleCounter; // special counter for candle inventory item @@ -301,6 +306,7 @@ class PrinceEngine : public Engine { void drawInvItems(); void displayInventory(); void addInvObj(); + void makeInvCursor(); int testAnimNr; int testAnimFrame; From 3cd6589c26ac16f707972367e528442e6b4f451d Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 8 Jun 2014 14:51:13 +0200 Subject: [PATCH 149/374] PRINCE: prepareInventoryToView() update - name, examText --- engines/prince/prince.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 1a09e83c65f6..0f0683ba291d 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1351,18 +1351,35 @@ void PrinceEngine::prepareInventoryToView() { 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()) { - tempMobItem._mask = _mainHero->_inventory[item] - 1; + int itemNr = _mainHero->_inventory[item]; + tempMobItem._mask = itemNr; // itemNr - 1?? tempMobItem._x1 = currInvX + _picWindowX; //picWindowX2 ? tempMobItem._x2 = currInvX + _picWindowX + _invLineW - 1; // picWindowX2 ? tempMobItem._y1 = currInvY; tempMobItem._y2 = currInvY + _invLineH - 1; - //tempMobItem._name = ; - //tempMobItem._examText = ; + + tempMobItem._name = ""; + tempMobItem._examText = ""; + int txtOffset = READ_UINT32(&_invTxt[itemNr * 8]); + int examTxtOffset = READ_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; From 3bf8d86a57ef54ba3f87fbbd12ee5e41ec254bf8 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 8 Jun 2014 19:01:05 +0200 Subject: [PATCH 150/374] PRINCE: Inventory update, drawing functions improvements --- engines/prince/graphics.cpp | 58 ++++++------ engines/prince/graphics.h | 16 ++-- engines/prince/prince.cpp | 183 +++++++++++++++++++++++------------- engines/prince/prince.h | 4 +- 4 files changed, 160 insertions(+), 101 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index e516cd7980be..593390ea56d7 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -37,6 +37,8 @@ GraphicsMan::GraphicsMan(PrinceEngine *vm) initGraphics(640, 480, true); _frontScreen = new Graphics::Surface(); _frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); + _screenForInventory = new Graphics::Surface(); + _screenForInventory->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); _shadowTable70 = new byte[256]; _shadowTable50 = new byte[256]; } @@ -48,9 +50,9 @@ GraphicsMan::~GraphicsMan() { delete[] _shadowTable50; } -void GraphicsMan::update() { +void GraphicsMan::update(Graphics::Surface *screen) { if (_changed) { - _vm->_system->copyRectToScreen((byte*)_frontScreen->getBasePtr(0,0), 640, 0, 0, 640, 480); + _vm->_system->copyRectToScreen((byte*)screen->getBasePtr(0,0), 640, 0, 0, 640, 480); _vm->_system->updateScreen(); _changed = false; @@ -65,24 +67,24 @@ void GraphicsMan::change() { _changed = true; } -void GraphicsMan::draw(uint16 posX, uint16 posY, const Graphics::Surface *s) { - uint16 w = MIN(_frontScreen->w, s->w); +void GraphicsMan::draw(Graphics::Surface *screen, uint16 posX, uint16 posY, const Graphics::Surface *s) { + uint16 w = MIN(screen->w, s->w); for (uint y = 0; y < s->h; y++) { - if (y < _frontScreen->h) { - memcpy((byte*)_frontScreen->getBasePtr(0, y), (byte*)s->getBasePtr(0, y), w); + if (y < screen->h) { + memcpy((byte*)screen->getBasePtr(0, y), (byte*)s->getBasePtr(0, y), w); } } change(); } -void GraphicsMan::drawTransparentSurface(int32 posX, int32 posY, const Graphics::Surface *s, int transColor) { +void GraphicsMan::drawTransparentSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, int transColor) { for (int y = 0; y < s->h; y++) { for (int x = 0; x < s->w; x++) { byte pixel = *((byte*)s->getBasePtr(x, y)); if (pixel != transColor) { - if (x + posX < _frontScreen->w && x + posX >= 0) { - if (y + posY < _frontScreen->h && y + posY >= 0) { - *((byte*)_frontScreen->getBasePtr(x + posX, y + posY)) = pixel; + if (x + posX < screen->w && x + posX >= 0) { + if (y + posY < screen->h && y + posY >= 0) { + *((byte*)screen->getBasePtr(x + posX, y + posY)) = pixel; } } } @@ -91,7 +93,7 @@ void GraphicsMan::drawTransparentSurface(int32 posX, int32 posY, const Graphics: change(); } -void GraphicsMan::drawTransparentWithBlend(int32 posX, int32 posY, const Graphics::Surface *s, int transColor) { +void GraphicsMan::drawTransparentWithBlend(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, int transColor) { _blendTable = new byte[256]; for (int i = 0; i < 256; i++) { _blendTable[i] = 255; @@ -100,11 +102,11 @@ void GraphicsMan::drawTransparentWithBlend(int32 posX, int32 posY, const Graphic for (int x = 0; x < s->w; x++) { byte pixel = *((byte*)s->getBasePtr(x, y)); if (pixel != transColor) { - if (x + posX < _frontScreen->w && x + posX >= 0) { - if (y + posY < _frontScreen->h && y + posY >= 0) { - byte backgroundPixel = *((byte*)_frontScreen->getBasePtr(x + posX, y + posY)); + if (x + posX < screen->w && x + posX >= 0) { + if (y + posY < screen->h && y + posY >= 0) { + byte backgroundPixel = *((byte*)screen->getBasePtr(x + posX, y + posY)); byte blendPixel = getBlendTableColor(pixel, backgroundPixel); - *((byte*)_frontScreen->getBasePtr(x + posX, y + posY)) = blendPixel; + *((byte*)screen->getBasePtr(x + posX, y + posY)) = blendPixel; } } } @@ -114,14 +116,14 @@ void GraphicsMan::drawTransparentWithBlend(int32 posX, int32 posY, const Graphic change(); } -void GraphicsMan::drawTransparent(Graphics::Surface *frontScreen, DrawNode *drawNode) { +void GraphicsMan::drawTransparent(Graphics::Surface *screen, DrawNode *drawNode) { for (int y = 0; y < drawNode->s->h; y++) { for (int x = 0; x < drawNode->s->w; x++) { byte pixel = *((byte*)drawNode->s->getBasePtr(x, y)); if (pixel != 255) { - if (x + drawNode->posX < frontScreen->w && x + drawNode->posX >= 0) { - if (y + drawNode->posY < frontScreen->h && y + drawNode->posY >= 0) { - *((byte*)frontScreen->getBasePtr(x + drawNode->posX, y + drawNode->posY)) = pixel; + if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { + if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { + *((byte*)screen->getBasePtr(x + drawNode->posX, y + drawNode->posY)) = pixel; } } } @@ -129,19 +131,19 @@ void GraphicsMan::drawTransparent(Graphics::Surface *frontScreen, DrawNode *draw } } -void GraphicsMan::drawMask(Graphics::Surface *frontScreen, DrawNode *drawNode) { +void GraphicsMan::drawMask(Graphics::Surface *screen, DrawNode *drawNode) { int maskWidth = drawNode->width >> 3; int maskPostion = 0; int maskCounter = 128; for (int y = 0; y < drawNode->height; y++) { int tempMaskPostion = maskPostion; for (int x = 0; x < drawNode->width; x++) { - if (x + drawNode->posX < frontScreen->w && x + drawNode->posX >= 0) { - if (y + drawNode->posY < frontScreen->h && y + drawNode->posY >= 0) { + if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { + if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { if ((drawNode->data[tempMaskPostion] & maskCounter) != 0) { byte orgPixel = *((byte*)drawNode->originalRoomSurface->getBasePtr(x + drawNode->posX, y + drawNode->posY)); - *((byte*)frontScreen->getBasePtr(x + drawNode->posX, y + drawNode->posY)) = orgPixel; - //*((byte*)frontScreen->getBasePtr(x + drawNode->posX, y + drawNode->posY)) = 0; // for debugging + *((byte*)screen->getBasePtr(x + drawNode->posX, y + drawNode->posY)) = orgPixel; + //*((byte*)screen->getBasePtr(x + drawNode->posX, y + drawNode->posY)) = 0; // for debugging } } } @@ -156,14 +158,14 @@ void GraphicsMan::drawMask(Graphics::Surface *frontScreen, DrawNode *drawNode) { } } -void GraphicsMan::drawAsShadow(Graphics::Surface *frontScreen, DrawNode *drawNode) { +void GraphicsMan::drawAsShadow(Graphics::Surface *screen, DrawNode *drawNode) { for (int y = 0; y < drawNode->s->h; y++) { for (int x = 0; x < drawNode->s->w; x++) { byte pixel = *((byte*)drawNode->s->getBasePtr(x, y)); if (pixel == kShadowColor) { - if (x + drawNode->posX < frontScreen->w && x + drawNode->posX >= 0) { - if (y + drawNode->posY < frontScreen->h && y + drawNode->posY >= 0) { - byte *background = (byte *)frontScreen->getBasePtr(x + drawNode->posX, y + drawNode->posY); + if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { + if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { + byte *background = (byte *)screen->getBasePtr(x + drawNode->posX, y + drawNode->posY); *background = *(drawNode->data + *background); } } diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index 7651dae7a196..c383c03bacfc 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -38,25 +38,25 @@ class GraphicsMan GraphicsMan(PrinceEngine *vm); ~GraphicsMan(); - void update(); + void update(Graphics::Surface *screen); void change(); void setPalette(const byte *palette); void makeShadowTable(int brightness, byte *shadowTable); - void draw(uint16 x, uint16 y, const Graphics::Surface *s); - void drawTransparentSurface(int32 posX, int32 poxY, const Graphics::Surface *s, int transColor); - void drawTransparentWithBlend(int32 posX, int32 poxY, const Graphics::Surface *s, int transColor); + void draw(Graphics::Surface *screen, uint16 x, uint16 y, const Graphics::Surface *s); + void drawTransparentSurface(Graphics::Surface *screen, int32 posX, int32 poxY, const Graphics::Surface *s, int transColor); + void drawTransparentWithBlend(Graphics::Surface *screen, int32 posX, int32 poxY, const Graphics::Surface *s, int transColor); - static void drawTransparent(Graphics::Surface *frontScreen, DrawNode *drawNode); - static void drawAsShadow(Graphics::Surface *frontScreen, DrawNode *drawNode); - static void drawMask(Graphics::Surface *frontScreen, DrawNode *drawNode); + static void drawTransparent(Graphics::Surface *screen, DrawNode *drawNode); + static void drawAsShadow(Graphics::Surface *screen, DrawNode *drawNode); + static void drawMask(Graphics::Surface *screen, DrawNode *drawNode); byte getBlendTableColor(byte pixelColor, byte backgroundPixelColor); Graphics::Surface *_frontScreen; - Graphics::Surface *_backScreen; + Graphics::Surface *_screenForInventory; const Graphics::Surface *_roomBackground; byte *_shadowTable70; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 0f0683ba291d..261ba70b2693 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -245,8 +245,8 @@ void PrinceEngine::showLogo() { MhwanhDecoder logo; if (Resource::loadResource(&logo, "logo.raw", true)) { _graph->setPalette(logo.getPalette()); - _graph->draw(0, 0, logo.getSurface()); - _graph->update(); + _graph->draw(_graph->_frontScreen, 0, 0, logo.getSurface()); + _graph->update(_graph->_frontScreen); _system->delayMillis(700); } } @@ -411,7 +411,7 @@ bool PrinceEngine::playNextFrame() { const Graphics::Surface *s = _flicPlayer.decodeNextFrame(); if (s) { - _graph->drawTransparentSurface(0, 0, s, 255); + _graph->drawTransparentSurface(_graph->_frontScreen, 0, 0, s, 255); _graph->change(); } else if (_flicLooped) { _flicPlayer.rewind(); @@ -658,7 +658,6 @@ void PrinceEngine::keyHandler(Common::Event event) { break; case Common::KEYCODE_i: _mainHero->_middleY -= 5; - inventoryFlagChange(); break; case Common::KEYCODE_k: _mainHero->_middleY += 5; @@ -686,38 +685,36 @@ void PrinceEngine::keyHandler(Common::Event event) { } } -void PrinceEngine::hotspot() { +void PrinceEngine::hotspot(Graphics::Surface *screen, Common::Array &mobList) { Common::Point mousepos = _system->getEventManager()->getMousePos(); Common::Point mousePosCamera(mousepos.x + _picWindowX, mousepos.y); - for (Common::Array::const_iterator it = _mobList.begin(); it != _mobList.end() ; it++) { + for (Common::Array::const_iterator it = mobList.begin(); it != mobList.end() ; it++) { const Mob& mob = *it; - if (mob._visible) + if (mob._visible != 0) { // 0 is for visible continue; + } if (mob._rect.contains(mousePosCamera)) { uint16 textW = 0; - for (uint16 i = 0; i < mob._name.size(); ++i) + for (uint16 i = 0; i < mob._name.size(); i++) { textW += _font->getCharWidth(mob._name[i]); + } uint16 x = mousepos.x - textW/2; - if (x > _graph->_frontScreen->w) + if (x > screen->w) { x = 0; + } - if (x + textW > _graph->_frontScreen->w) - x = _graph->_frontScreen->w - textW; + if (x + textW > screen->w) { + x = screen->w - textW; + } uint16 y = mousepos.y - _font->getFontHeight(); - if (y > _graph->_frontScreen->h) + if (y > screen->h) { y = _font->getFontHeight() - 2; + } - _font->drawString( - _graph->_frontScreen, - mob._name, - x, - y, - _graph->_frontScreen->w, - 216 - ); + _font->drawString(screen, mob._name, x, y, screen->w, 216); break; } } @@ -1197,7 +1194,7 @@ void PrinceEngine::drawScreen() { Graphics::Surface visiblePart; if (roomSurface) { visiblePart = roomSurface->getSubArea(Common::Rect(_picWindowX, 0, roomSurface->w, roomSurface->h)); - _graph->draw(0, 0, &visiblePart); + _graph->draw(_graph->_frontScreen, 0, 0, &visiblePart); } Graphics::Surface *mainHeroSurface = NULL; @@ -1252,20 +1249,18 @@ void PrinceEngine::drawScreen() { playNextFrame(); if (!_inventoryBackgroundRemember) { - hotspot(); + hotspot(_graph->_frontScreen, _mobList); showTexts(); } else { - rememberScreenInv(); _inventoryBackgroundRemember = false; } + getDebugger()->onFrame(); + _graph->update(_graph->_frontScreen); + } else { displayInventory(); } - - getDebugger()->onFrame(); - - _graph->update(); } void PrinceEngine::pause() { @@ -1276,24 +1271,34 @@ void PrinceEngine::pause() { } void PrinceEngine::addInvObj() { - changeCursor(0); // turn on cursor later? + 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) { - displayInventory(); - _graph->update(); + rememberScreenInv(); + _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase, 0); + drawInvItems(); + _graph->update(_graph->_screenForInventory); _mst_shadow2 += 50; pause(); } while (_mst_shadow2 > 256) { - displayInventory(); - _graph->update(); + rememberScreenInv(); + _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase, 0); + drawInvItems(); + _graph->update(_graph->_screenForInventory); _mst_shadow2 -= 42; pause(); } @@ -1302,14 +1307,18 @@ void PrinceEngine::addInvObj() { for (int i = 0; i < 3; i++) { _mst_shadow2 = 256; while (_mst_shadow2 < 512) { - displayInventory(); - _graph->update(); + rememberScreenInv(); + _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase, 0); + drawInvItems(); + _graph->update(_graph->_screenForInventory); _mst_shadow2 += 50; pause(); } while (_mst_shadow2 > 256) { - displayInventory(); - _graph->update(); + rememberScreenInv(); + _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase, 0); + drawInvItems(); + _graph->update(_graph->_screenForInventory); _mst_shadow2 -= 50; pause(); } @@ -1317,17 +1326,21 @@ void PrinceEngine::addInvObj() { } _mst_shadow2 = 0; for (int i = 0; i < 20; i++) { - displayInventory(); - _graph->update(); + rememberScreenInv(); + _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase, 0); + drawInvItems(); + _graph->update(_graph->_screenForInventory); pause(); } + changeCursor(1); // here? } void PrinceEngine::rememberScreenInv() { + _graph->_screenForInventory->copyFrom(*_graph->_frontScreen); } -void PrinceEngine::inventoryFlagChange() { - if (!_showInventoryFlag) { +void PrinceEngine::inventoryFlagChange(bool inventoryState) { + if (inventoryState) { _showInventoryFlag = true; _inventoryBackgroundRemember = true; } else { @@ -1360,12 +1373,18 @@ void PrinceEngine::prepareInventoryToView() { Mob tempMobItem; if (item < _mainHero->_inventory.size()) { int itemNr = _mainHero->_inventory[item]; + tempMobItem._visible = 0; tempMobItem._mask = itemNr; // itemNr - 1?? tempMobItem._x1 = currInvX + _picWindowX; //picWindowX2 ? tempMobItem._x2 = currInvX + _picWindowX + _invLineW - 1; // picWindowX2 ? tempMobItem._y1 = currInvY; tempMobItem._y2 = currInvY + _invLineH - 1; + tempMobItem._rect.left = tempMobItem._x1; + tempMobItem._rect.right = tempMobItem._x2; + tempMobItem._rect.top = tempMobItem._y1; + tempMobItem._rect.bottom = tempMobItem._y2; + tempMobItem._name = ""; tempMobItem._examText = ""; int txtOffset = READ_UINT32(&_invTxt[itemNr * 8]); @@ -1388,11 +1407,6 @@ void PrinceEngine::prepareInventoryToView() { currInvX = _invLineX; currInvY += _invLineSkipY + _invLineH; } - //moblistcreated: - //mov w [edi.Mob_Visible],-1 - //mov eax,d InvMobList - //mov d MobListAddr,eax - //mov d MobPriAddr,o InvMobPri } void PrinceEngine::drawInvItems() { @@ -1438,10 +1452,10 @@ void PrinceEngine::drawInvItems() { drawX += (_maxInvW - itemSurface->w) / 2; } if (!_mst_shadow) { - _graph->drawTransparentSurface(drawX, drawY, itemSurface, 0); + _graph->drawTransparentSurface(_graph->_screenForInventory, drawX, drawY, itemSurface, 0); } else { _mst_shadow = _mst_shadow2; - _graph->drawTransparentWithBlend(drawX, drawY, itemSurface, 0); + _graph->drawTransparentWithBlend(_graph->_screenForInventory, drawX, drawY, itemSurface, 0); } } currInvX += _invLineW + _invLineSkipX; @@ -1463,26 +1477,63 @@ void PrinceEngine::displayInventory() { prepareInventoryToView(); - _graph->drawTransparentSurface(0, 0, _graph->_frontScreen, 0); - Graphics::Surface *suitcase = _suitcaseBmp->getSurface(); - _graph->drawTransparentSurface(0, 0, suitcase, 0); + while (!shouldQuit()) { + + 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_KEYUP: + break; + case Common::EVENT_MOUSEMOVE: + break; + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_RBUTTONDOWN: + break; + case Common::EVENT_LBUTTONUP: + case Common::EVENT_RBUTTONUP: + break; + case Common::EVENT_QUIT: + break; + default: + break; + } + } + + if (shouldQuit()) + return; - drawInvItems(); + rememberScreenInv(); - Common::Rect _inventoryRect; - _inventoryRect.left = _invX1; - _inventoryRect.top = _invY1; - _inventoryRect.right = _invX1 + _invWidth; - _inventoryRect.bottom = _invY1 + _invHeight; - Common::Point mousePos = _system->getEventManager()->getMousePos(); + Graphics::Surface *suitcase = _suitcaseBmp->getSurface(); + _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase, 0); - if (!_invCurInside && _inventoryRect.contains(mousePos)) { - _invCurInside = true; - } + drawInvItems(); - if (_invCurInside && !_inventoryRect.contains(mousePos)) { - inventoryFlagChange(); - _invCurInside = false; + Common::Rect _inventoryRect; + _inventoryRect.left = _invX1; + _inventoryRect.top = _invY1; + _inventoryRect.right = _invX1 + _invWidth; + _inventoryRect.bottom = _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; + } + + hotspot(_graph->_screenForInventory, _invMobList); + getDebugger()->onFrame(); + _graph->update(_graph->_screenForInventory); + pause(); } } @@ -1542,6 +1593,12 @@ void PrinceEngine::mainLoop() { _frameNr++; + // inventory turning on: + Common::Point mousePos = _system->getEventManager()->getMousePos(); + if (mousePos.y == 0 && !_showInventoryFlag) { + inventoryFlagChange(true); + } + if (_debugger->_locationNr != _locationNr) loadLocation(_debugger->_locationNr); if (_debugger->_cursorNr != _cursorNr) diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 9259fe703aaa..b85a1610c8e7 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -299,7 +299,7 @@ class PrinceEngine : public Engine { int _mst_shadow2; // blinking after adding new item int _candleCounter; // special counter for candle inventory item - void inventoryFlagChange(); + void inventoryFlagChange(bool inventoryState); bool loadAllInv(); void rememberScreenInv(); void prepareInventoryToView(); @@ -314,7 +314,7 @@ class PrinceEngine : public Engine { private: bool playNextFrame(); void keyHandler(Common::Event event); - void hotspot(); + void hotspot(Graphics::Surface *screen, Common::Array &mobList); void drawScreen(); void showTexts(); void init(); From 98525c1145f8b62c1e12d463754ff3777bcc7db7 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 9 Jun 2014 00:57:08 +0200 Subject: [PATCH 151/374] PRINCE: Inventory - left mouse button handling --- engines/prince/mob.h | 4 -- engines/prince/prince.cpp | 146 ++++++++++++++++++++++++++------------ engines/prince/prince.h | 12 +++- engines/prince/script.cpp | 21 ++++++ engines/prince/script.h | 2 + 5 files changed, 135 insertions(+), 50 deletions(-) diff --git a/engines/prince/mob.h b/engines/prince/mob.h index 1c095c2fc432..36630eb6eb89 100644 --- a/engines/prince/mob.h +++ b/engines/prince/mob.h @@ -66,10 +66,6 @@ class Mob { bool _visible; uint16 _type; - uint16 _x1; // initialize this? - uint16 _y1; - uint16 _x2; - uint16 _y2; uint16 _mask; Common::Rect _rect; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 261ba70b2693..ae7530997a39 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -82,7 +82,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _invLineX(134), _invLineY(176), _invLine(5), _invLines(3), _invLineW(70), _invLineH(76), _maxInvW(72), _maxInvH(76), _invLineSkipX(2), _invLineSkipY(3), _showInventoryFlag(false), _inventoryBackgroundRemember(false), _mst_shadow(0), _mst_shadow2(0), _candleCounter(0), _invX1(53), _invY1(18), _invWidth(536), _invHeight(438), - _invCurInside(false) { + _invCurInside(false), _optionsFlag(false), _currentMob(0), _optionEnabled(0), _invOptionsNumber(5), + _invExamY(120) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -685,7 +686,7 @@ void PrinceEngine::keyHandler(Common::Event event) { } } -void PrinceEngine::hotspot(Graphics::Surface *screen, Common::Array &mobList) { +int PrinceEngine::hotspot(Graphics::Surface *screen, Common::Array &mobList) { Common::Point mousepos = _system->getEventManager()->getMousePos(); Common::Point mousePosCamera(mousepos.x + _picWindowX, mousepos.y); @@ -700,7 +701,7 @@ void PrinceEngine::hotspot(Graphics::Surface *screen, Common::Array &mobLis textW += _font->getCharWidth(mob._name[i]); } - uint16 x = mousepos.x - textW/2; + uint16 x = mousepos.x - textW / 2; if (x > screen->w) { x = 0; } @@ -715,9 +716,10 @@ void PrinceEngine::hotspot(Graphics::Surface *screen, Common::Array &mobLis } _font->drawString(screen, mob._name, x, y, screen->w, 216); - break; + return mob._mask; } } + return 0; } void PrinceEngine::printAt(uint32 slot, uint8 color, const char *s, uint16 x, uint16 y) { @@ -740,7 +742,7 @@ uint32 PrinceEngine::getTextWidth(const char *s) { return textW; } -void PrinceEngine::showTexts() { +void PrinceEngine::showTexts(Graphics::Surface *screen) { for (uint32 slot = 0; slot < MAXTEXTS; ++slot) { Text& text = _textSlots[slot]; if (!text._str && !text._time) @@ -751,11 +753,11 @@ void PrinceEngine::showTexts() { for (uint8 i = 0; i < lines.size(); ++i) { _font->drawString( - _graph->_frontScreen, + screen, lines[i], text._x - getTextWidth(lines[i].c_str())/2, text._y - (lines.size() - i) * (_font->getFontHeight()), - _graph->_frontScreen->w, + screen->w, text._color ); } @@ -1249,8 +1251,8 @@ void PrinceEngine::drawScreen() { playNextFrame(); if (!_inventoryBackgroundRemember) { - hotspot(_graph->_frontScreen, _mobList); - showTexts(); + _currentMob = hotspot(_graph->_frontScreen, _mobList); + showTexts(_graph->_frontScreen); } else { _inventoryBackgroundRemember = false; } @@ -1372,18 +1374,13 @@ void PrinceEngine::prepareInventoryToView() { for (int j = 0; j < _invLine; j++) { Mob tempMobItem; if (item < _mainHero->_inventory.size()) { - int itemNr = _mainHero->_inventory[item]; + int itemNr = _mainHero->_inventory[item]; tempMobItem._visible = 0; tempMobItem._mask = itemNr; // itemNr - 1?? - tempMobItem._x1 = currInvX + _picWindowX; //picWindowX2 ? - tempMobItem._x2 = currInvX + _picWindowX + _invLineW - 1; // picWindowX2 ? - tempMobItem._y1 = currInvY; - tempMobItem._y2 = currInvY + _invLineH - 1; - - tempMobItem._rect.left = tempMobItem._x1; - tempMobItem._rect.right = tempMobItem._x2; - tempMobItem._rect.top = tempMobItem._y1; - tempMobItem._rect.bottom = tempMobItem._y2; + tempMobItem._rect.left = currInvX + _picWindowX; //picWindowX2 ? + tempMobItem._rect.right = currInvX + _picWindowX + _invLineW - 1; // picWindowX2 ? + tempMobItem._rect.top = currInvY; + tempMobItem._rect.bottom = currInvY + _invLineH - 1; tempMobItem._name = ""; tempMobItem._examText = ""; @@ -1466,6 +1463,59 @@ void PrinceEngine::drawInvItems() { } } +void PrinceEngine::inventoryLeftButton() { + if (_optionsFlag == 1) { + //check_opt + if (_currentMob != 0) { + if (_optionEnabled < _invOptionsNumber) { + _optionsFlag = 0; + // ebp = _currentMob; + } else { + return; + } + } else { + // test bx, RMBMask 7996 ? + } + } else { + if (_currentMob != 0) { + //if (_currentPointerNumber != 2) { + if (_currentMob != 29) { + _optionEnabled = 0; + } else { + _optionEnabled = 1; + } + //do_option + //} else { + //use_item_on_item + //} + } + } + //do_option + int selectedMob = _currentMob; // no _currentMob just selectedMob as global for _currentMob.mask ? + if (_optionEnabled == 0) { + int invObjExamEvent = _script->scanInvObjExamEvents(selectedMob); // test this + if (invObjExamEvent == -1) { + // do_standard + printAt(0, 216, _invMobList[selectedMob]._examText.c_str(), kNormalWidth / 2, _invExamY); + showTexts(_graph->_screenForInventory); // here? + // setSpecVoice(); + } else { + //store_new_pc + // storeNewPC(); + _flags->setFlagValue(Flags::CURRMOB, selectedMob); + _currentMob = 0; + //_optionsMob = 0; + } + } else { + // not_examine + + } +} + +void PrinceEngine::inventoryRightButton() { + +} + void PrinceEngine::displayInventory() { // temp: _mainHero->_inventory.clear(); @@ -1475,10 +1525,41 @@ void PrinceEngine::displayInventory() { _mainHero->_inventory.push_back(4); _mainHero->_inventory.push_back(68); + _mainHero->_inventory.push_back(29); + _mainHero->_inventory.push_back(13); + _mainHero->_inventory.push_back(44); + _mainHero->_inventory.push_back(67); + prepareInventoryToView(); while (!shouldQuit()) { + rememberScreenInv(); + + Graphics::Surface *suitcase = _suitcaseBmp->getSurface(); + _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase, 0); + + drawInvItems(); + + Common::Rect _inventoryRect; + _inventoryRect.left = _invX1; + _inventoryRect.top = _invY1; + _inventoryRect.right = _invX1 + _invWidth; + _inventoryRect.bottom = _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; + } + + _currentMob = hotspot(_graph->_screenForInventory, _invMobList); + Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); while (eventMan->pollEvent(event)) { @@ -1491,6 +1572,8 @@ void PrinceEngine::displayInventory() { case Common::EVENT_MOUSEMOVE: break; case Common::EVENT_LBUTTONDOWN: + inventoryLeftButton(); + break; case Common::EVENT_RBUTTONDOWN: break; case Common::EVENT_LBUTTONUP: @@ -1506,31 +1589,6 @@ void PrinceEngine::displayInventory() { if (shouldQuit()) return; - rememberScreenInv(); - - Graphics::Surface *suitcase = _suitcaseBmp->getSurface(); - _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase, 0); - - drawInvItems(); - - Common::Rect _inventoryRect; - _inventoryRect.left = _invX1; - _inventoryRect.top = _invY1; - _inventoryRect.right = _invX1 + _invWidth; - _inventoryRect.bottom = _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; - } - - hotspot(_graph->_screenForInventory, _invMobList); getDebugger()->onFrame(); _graph->update(_graph->_screenForInventory); pause(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index b85a1610c8e7..46c573b0a6a9 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -273,12 +273,18 @@ class PrinceEngine : public Engine { void showMask(int maskNr, Graphics::Surface *originalRoomSurface); void clsMasks(); + int _currentMob; // number of selected Mob / inventory item + static const int16 kMaxInv = 90; // max amount of inventory items in whole game uint32 _invTxtSize; byte *_invTxt; bool _showInventoryFlag; + bool _optionsFlag; + int _optionEnabled; + int _invOptionsNumber; + int _invExamY; bool _inventoryBackgroundRemember; int _invLineX; int _invLineY; @@ -307,6 +313,8 @@ class PrinceEngine : public Engine { void displayInventory(); void addInvObj(); void makeInvCursor(); + void inventoryLeftButton(); + void inventoryRightButton(); int testAnimNr; int testAnimFrame; @@ -314,9 +322,9 @@ class PrinceEngine : public Engine { private: bool playNextFrame(); void keyHandler(Common::Event event); - void hotspot(Graphics::Surface *screen, Common::Array &mobList); + int hotspot(Graphics::Surface *screen, Common::Array &mobList); void drawScreen(); - void showTexts(); + void showTexts(Graphics::Surface *screen); void init(); void showLogo(); void showBackAnims(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 331e425a42c0..4eed60d7e5e0 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -205,6 +205,27 @@ uint8 *Script::getRoomOffset(int locationNr) { return &_data[_scriptInfo.rooms + locationNr * 64]; } +struct RE { + int16 _mob; // number of Mob, -1 for end of list + int32 _code; // offset of code in script +}; + +int Script::scanInvObjExamEvents(int mobMask) { + RE tempRE; + int i = 0; + do { + tempRE._mob = (int)READ_UINT16(&_data[_scriptInfo.invObjExam + i * 6]); + debug("mob: %d", tempRE._mob); + tempRE._code = (int)READ_UINT32(&_data[_scriptInfo.invObjExam + i * 6 + 2]); + debug("code: %d", tempRE._code); + if (tempRE._mob == mobMask) { + return tempRE._code; + } + i++; + } while (tempRE._mob != -1); //?? || i <= 1 or without this (no items there) + return -1; // or sth else? +} + void Script::installSingleBackAnim(Common::Array &_backanimList, int offset) { BackgroundAnim newBackgroundAnim; diff --git a/engines/prince/script.h b/engines/prince/script.h index 4b9f85a61ec3..06b09b94c4b8 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -137,6 +137,8 @@ class Script { void installSingleBackAnim(Common::Array &_backanimList, int offset); bool loadAllMasks(Common::Array &maskList, int offset); + int scanInvObjExamEvents(int mobMask); + const char *getString(uint32 offset) { return (const char *)(&_data[offset]); } From ffa438afeb80f967573852bcdd3ba51f7c24ca84 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 9 Jun 2014 19:51:50 +0200 Subject: [PATCH 152/374] PRINCE: drawTransparent() update --- engines/prince/graphics.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 593390ea56d7..fe7ea0bc9908 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -117,17 +117,23 @@ void GraphicsMan::drawTransparentWithBlend(Graphics::Surface *screen, int32 posX } void GraphicsMan::drawTransparent(Graphics::Surface *screen, DrawNode *drawNode) { + byte *src1 = (byte *)drawNode->s->getBasePtr(0, 0); + byte *dst1 = (byte *)screen->getBasePtr(drawNode->posX, drawNode->posY); + for (int y = 0; y < drawNode->s->h; y++) { - for (int x = 0; x < drawNode->s->w; x++) { - byte pixel = *((byte*)drawNode->s->getBasePtr(x, y)); - if (pixel != 255) { - if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { - if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { - *((byte*)screen->getBasePtr(x + drawNode->posX, y + drawNode->posY)) = pixel; - } - } + byte *src2 = src1; + byte *dst2 = dst1; + for (int x = 0; x < drawNode->s->w; x++, src2++, dst2++) { + if (*src2 != 255) { + if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { + if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { + *dst2 = *src2; + } + } } } + src1 += drawNode->s->pitch; + dst1 += screen->pitch; } } From 26db9ae9f57f90fa67bd1b406e5b14696229e1fc Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 9 Jun 2014 20:03:33 +0200 Subject: [PATCH 153/374] PRINCE: drawAsShadow() update --- engines/prince/graphics.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index fe7ea0bc9908..8b07796538dd 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -165,18 +165,23 @@ void GraphicsMan::drawMask(Graphics::Surface *screen, DrawNode *drawNode) { } void GraphicsMan::drawAsShadow(Graphics::Surface *screen, DrawNode *drawNode) { + byte *src1 = (byte *)drawNode->s->getBasePtr(0, 0); + byte *dst1 = (byte *)screen->getBasePtr(drawNode->posX, drawNode->posY); + for (int y = 0; y < drawNode->s->h; y++) { - for (int x = 0; x < drawNode->s->w; x++) { - byte pixel = *((byte*)drawNode->s->getBasePtr(x, y)); - if (pixel == kShadowColor) { + byte *src2 = src1; + byte *dst2 = dst1; + for (int x = 0; x < drawNode->s->w; x++, src2++, dst2++) { + if (*src2 == kShadowColor) { if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { - byte *background = (byte *)screen->getBasePtr(x + drawNode->posX, y + drawNode->posY); - *background = *(drawNode->data + *background); + *dst2 = *(drawNode->data + *dst2); } } } } + src1 += drawNode->s->pitch; + dst1 += screen->pitch; } } From 8f98d80f4eec40e93977fda2315f09a59a722960 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 9 Jun 2014 20:19:15 +0200 Subject: [PATCH 154/374] PRINCE: drawMask() update --- engines/prince/graphics.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 8b07796538dd..2ca6370df467 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -138,18 +138,22 @@ void GraphicsMan::drawTransparent(Graphics::Surface *screen, DrawNode *drawNode) } void GraphicsMan::drawMask(Graphics::Surface *screen, DrawNode *drawNode) { + byte *src1 = (byte *)drawNode->originalRoomSurface->getBasePtr(drawNode->posX, drawNode->posY); + byte *dst1 = (byte *)screen->getBasePtr(drawNode->posX, drawNode->posY); int maskWidth = drawNode->width >> 3; int maskPostion = 0; int maskCounter = 128; + for (int y = 0; y < drawNode->height; y++) { + byte *src2 = src1; + byte *dst2 = dst1; int tempMaskPostion = maskPostion; - for (int x = 0; x < drawNode->width; x++) { + for (int x = 0; x < drawNode->width; x++, src2++, dst2++) { if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { if ((drawNode->data[tempMaskPostion] & maskCounter) != 0) { - byte orgPixel = *((byte*)drawNode->originalRoomSurface->getBasePtr(x + drawNode->posX, y + drawNode->posY)); - *((byte*)screen->getBasePtr(x + drawNode->posX, y + drawNode->posY)) = orgPixel; - //*((byte*)screen->getBasePtr(x + drawNode->posX, y + drawNode->posY)) = 0; // for debugging + *dst2 = *src2; + //*dst2 = 0; // for debugging } } } @@ -159,6 +163,8 @@ void GraphicsMan::drawMask(Graphics::Surface *screen, DrawNode *drawNode) { tempMaskPostion++; } } + src1 += drawNode->originalRoomSurface->pitch; + dst1 += screen->pitch; maskPostion += maskWidth; maskCounter = 128; } From ca6f59217f8cd2f55daae670cbe3c085820e88d1 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 9 Jun 2014 20:32:39 +0200 Subject: [PATCH 155/374] PRINCE: PScr class - clean up --- engines/prince/pscr.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/engines/prince/pscr.cpp b/engines/prince/pscr.cpp index 7402e46e43f0..ea6de2a5b608 100644 --- a/engines/prince/pscr.cpp +++ b/engines/prince/pscr.cpp @@ -44,13 +44,9 @@ PScr::~PScr() { } void PScr::loadSurface(Common::SeekableReadStream &stream) { - //stream.skip(4); - int x = stream.readUint16LE(); - int y = stream.readUint16LE(); + stream.skip(4); int width = stream.readUint16LE(); int height = stream.readUint16LE(); - debug("x: %d, y: %d", x, y); - debug("w: %d, h: %d", width, height); _surface = new Graphics::Surface(); _surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); @@ -87,4 +83,4 @@ bool PScr::loadFromStream(Common::SeekableReadStream &stream) { return true; } -} \ No newline at end of file +} From 31115ad946d626435000e2457a4462e05fdc021c Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 9 Jun 2014 20:39:02 +0200 Subject: [PATCH 156/374] PRINCE: GraphicsMan class - opening brace in previous line --- engines/prince/graphics.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index c383c03bacfc..9969fbca5e86 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -32,8 +32,7 @@ class PrinceEngine; struct DrawNode; class MhwanhDecoder; -class GraphicsMan -{ +class GraphicsMan { public: GraphicsMan(PrinceEngine *vm); ~GraphicsMan(); From 1beaf46210cf3709d7cbd973b43e02542a0031f3 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 10 Jun 2014 13:15:46 +0200 Subject: [PATCH 157/374] PRINCE: GrahicsMan - update(), formatting fix --- engines/prince/graphics.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 2ca6370df467..8947f18e8466 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -52,7 +52,7 @@ GraphicsMan::~GraphicsMan() { void GraphicsMan::update(Graphics::Surface *screen) { if (_changed) { - _vm->_system->copyRectToScreen((byte*)screen->getBasePtr(0,0), 640, 0, 0, 640, 480); + _vm->_system->copyRectToScreen((byte *)screen->getBasePtr(0, 0), 640, 0, 0, 640, 480); _vm->_system->updateScreen(); _changed = false; From f4f09efa5fefb9c05edaf95b68938530f5b9f5d2 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 10 Jun 2014 13:51:45 +0200 Subject: [PATCH 158/374] PRINCE: drawTransparentWithBlend(), getBlendTableColor() - update --- engines/prince/graphics.cpp | 65 ++++++++++++++----------------------- engines/prince/graphics.h | 4 +-- 2 files changed, 26 insertions(+), 43 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 8947f18e8466..54861dfba6d0 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -94,25 +94,28 @@ void GraphicsMan::drawTransparentSurface(Graphics::Surface *screen, int32 posX, } void GraphicsMan::drawTransparentWithBlend(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, int transColor) { - _blendTable = new byte[256]; + byte *src1 = (byte *)s->getBasePtr(0, 0); + byte *dst1 = (byte *)screen->getBasePtr(posX, posY); + byte *blendTable = (byte *)malloc(256); for (int i = 0; i < 256; i++) { - _blendTable[i] = 255; + blendTable[i] = 255; } for (int y = 0; y < s->h; y++) { - for (int x = 0; x < s->w; x++) { - byte pixel = *((byte*)s->getBasePtr(x, y)); - if (pixel != transColor) { + byte *src2 = src1; + byte *dst2 = dst1; + for (int x = 0; x < s->w; x++, src2++, dst2++) { + if (*src2 != transColor) { if (x + posX < screen->w && x + posX >= 0) { if (y + posY < screen->h && y + posY >= 0) { - byte backgroundPixel = *((byte*)screen->getBasePtr(x + posX, y + posY)); - byte blendPixel = getBlendTableColor(pixel, backgroundPixel); - *((byte*)screen->getBasePtr(x + posX, y + posY)) = blendPixel; + *dst2 = getBlendTableColor(*src2, *dst2, blendTable); } } } } + src1 += s->pitch; + dst1 += screen->pitch; } - delete _blendTable; + free(blendTable); change(); } @@ -191,7 +194,7 @@ void GraphicsMan::drawAsShadow(Graphics::Surface *screen, DrawNode *drawNode) { } } -byte GraphicsMan::getBlendTableColor(byte pixelColor, byte backgroundPixelColor) { +byte GraphicsMan::getBlendTableColor(byte pixelColor, byte backgroundPixelColor, byte *blendTable) { int32 redFirstOrg, greenFirstOrg, blueFirstOrg; int32 redFirstBack, greenFirstBack, blueFirstBack; int32 redSecondOrg, greenSecondOrg, blueSecondOrg; @@ -201,54 +204,36 @@ byte GraphicsMan::getBlendTableColor(byte pixelColor, byte backgroundPixelColor) int32 bigValue; int32 currColor; - if (_blendTable[pixelColor] != 255) { - currColor = _blendTable[pixelColor]; + if (blendTable[pixelColor] != 255) { + currColor = blendTable[pixelColor]; } else { const byte *originalPalette = _vm->_roomBmp->getPalette(); redFirstOrg = originalPalette[pixelColor * 3] * _vm->_mst_shadow / 256; - if (redFirstOrg >= 256) { - redFirstOrg = 255; - } + CLIP(redFirstOrg, 0, 255); if (_vm->_mst_shadow <= 256) { redFirstBack = originalPalette[backgroundPixelColor * 3] * (256 - _vm->_mst_shadow) / 256; - if (redFirstBack >= 256) { - redFirstBack = 255; - } + CLIP(redFirstBack, 0, 255); redFirstOrg += redFirstBack; - if (redFirstOrg >= 256) { - redFirstOrg = 255; - } + CLIP(redFirstOrg, 0, 255); } greenFirstOrg = originalPalette[pixelColor * 3 + 1] * _vm->_mst_shadow / 256; - if (greenFirstOrg >= 256) { - greenFirstOrg = 255; - } + CLIP(greenFirstOrg, 0, 255); if (_vm->_mst_shadow <= 256) { greenFirstBack = originalPalette[backgroundPixelColor * 3 + 1] * (256 - _vm->_mst_shadow) / 256; - if (greenFirstBack >= 256) { - greenFirstBack = 255; - } + CLIP(greenFirstBack, 0, 255); greenFirstOrg += greenFirstBack; - if (greenFirstOrg >= 256) { - greenFirstOrg = 255; - } + CLIP(greenFirstOrg, 0, 255); } blueFirstOrg = originalPalette[pixelColor * 3 + 2] * _vm->_mst_shadow / 256; - if (blueFirstOrg >= 256) { - blueFirstOrg = 255; - } + CLIP(blueFirstOrg, 0, 255); if (_vm->_mst_shadow <= 256) { blueFirstBack = originalPalette[backgroundPixelColor * 3 + 2] * (256 - _vm->_mst_shadow) / 256; - if (blueFirstBack >= 256) { - blueFirstBack = 255; - } + CLIP(blueFirstBack, 0, 255); blueFirstOrg += blueFirstBack; - if (blueFirstOrg >= 256) { - blueFirstOrg = 255; - } + CLIP(blueFirstOrg, 0, 255); } currColor = 0; @@ -277,7 +262,7 @@ byte GraphicsMan::getBlendTableColor(byte pixelColor, byte backgroundPixelColor) break; } } - _blendTable[pixelColor] = currColor; + blendTable[pixelColor] = currColor; } return currColor; } diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index 9969fbca5e86..0ebf3aa7ef49 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -52,7 +52,7 @@ class GraphicsMan { static void drawAsShadow(Graphics::Surface *screen, DrawNode *drawNode); static void drawMask(Graphics::Surface *screen, DrawNode *drawNode); - byte getBlendTableColor(byte pixelColor, byte backgroundPixelColor); + byte getBlendTableColor(byte pixelColor, byte backgroundPixelColor, byte *blendTable); Graphics::Surface *_frontScreen; Graphics::Surface *_screenForInventory; @@ -63,8 +63,6 @@ class GraphicsMan { static const byte kShadowColor = 191; - byte *_blendTable; - private: PrinceEngine *_vm; From 1c02028ddd647d829f61d95ec964d46d7a0d180f Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 10 Jun 2014 14:29:06 +0200 Subject: [PATCH 159/374] PRINCE: draw(), drawTransparentDrawNode() update --- engines/prince/graphics.cpp | 23 ++++++++++++++++------- engines/prince/graphics.h | 4 ++-- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 54861dfba6d0..4f80c8cbe364 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -67,28 +67,37 @@ void GraphicsMan::change() { _changed = true; } -void GraphicsMan::draw(Graphics::Surface *screen, uint16 posX, uint16 posY, const Graphics::Surface *s) { +void GraphicsMan::draw(Graphics::Surface *screen, const Graphics::Surface *s) { uint16 w = MIN(screen->w, s->w); + byte *src = (byte *)s->getBasePtr(0, 0); + byte *dst = (byte *)screen->getBasePtr(0, 0); for (uint y = 0; y < s->h; y++) { if (y < screen->h) { - memcpy((byte*)screen->getBasePtr(0, y), (byte*)s->getBasePtr(0, y), w); + memcpy(dst, src, w); } + src += s->pitch; + dst += screen->pitch; } change(); } void GraphicsMan::drawTransparentSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, int transColor) { + byte *src1 = (byte *)s->getBasePtr(0, 0); + byte *dst1 = (byte *)screen->getBasePtr(posX, posY); for (int y = 0; y < s->h; y++) { - for (int x = 0; x < s->w; x++) { - byte pixel = *((byte*)s->getBasePtr(x, y)); - if (pixel != transColor) { + byte *src2 = src1; + byte *dst2 = dst1; + for (int x = 0; x < s->w; x++, src2++, dst2++) { + if (*src2 != transColor) { if (x + posX < screen->w && x + posX >= 0) { if (y + posY < screen->h && y + posY >= 0) { - *((byte*)screen->getBasePtr(x + posX, y + posY)) = pixel; + *dst2 = *src2; } } } } + src1 += s->pitch; + dst1 += screen->pitch; } change(); } @@ -119,7 +128,7 @@ void GraphicsMan::drawTransparentWithBlend(Graphics::Surface *screen, int32 posX change(); } -void GraphicsMan::drawTransparent(Graphics::Surface *screen, DrawNode *drawNode) { +void GraphicsMan::drawTransparentDrawNode(Graphics::Surface *screen, DrawNode *drawNode) { byte *src1 = (byte *)drawNode->s->getBasePtr(0, 0); byte *dst1 = (byte *)screen->getBasePtr(drawNode->posX, drawNode->posY); diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index 0ebf3aa7ef49..d2f112656ecd 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -44,11 +44,11 @@ class GraphicsMan { void setPalette(const byte *palette); void makeShadowTable(int brightness, byte *shadowTable); - void draw(Graphics::Surface *screen, uint16 x, uint16 y, const Graphics::Surface *s); + void draw(Graphics::Surface *screen, const Graphics::Surface *s); void drawTransparentSurface(Graphics::Surface *screen, int32 posX, int32 poxY, const Graphics::Surface *s, int transColor); void drawTransparentWithBlend(Graphics::Surface *screen, int32 posX, int32 poxY, const Graphics::Surface *s, int transColor); - static void drawTransparent(Graphics::Surface *screen, DrawNode *drawNode); + static void drawTransparentDrawNode(Graphics::Surface *screen, DrawNode *drawNode); static void drawAsShadow(Graphics::Surface *screen, DrawNode *drawNode); static void drawMask(Graphics::Surface *screen, DrawNode *drawNode); From 60f23ecb574369ea341773efba4b9bfa31577210 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 10 Jun 2014 20:09:28 +0200 Subject: [PATCH 160/374] PRINCE: DrawNode functions update; Closing game in inventory loops fix --- engines/prince/prince.cpp | 44 +++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index ae7530997a39..2707146b93cd 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -246,7 +246,7 @@ void PrinceEngine::showLogo() { MhwanhDecoder logo; if (Resource::loadResource(&logo, "logo.raw", true)) { _graph->setPalette(logo.getPalette()); - _graph->draw(_graph->_frontScreen, 0, 0, logo.getSurface()); + _graph->draw(_graph->_frontScreen, logo.getSurface()); _graph->update(_graph->_frontScreen); _system->delayMillis(700); } @@ -872,7 +872,7 @@ void PrinceEngine::showSprite(Graphics::Surface *spriteSurface, int destX, int d newDrawNode.originalRoomSurface = nullptr; newDrawNode.data = nullptr; newDrawNode.freeSurfaceSMemory = freeSurfaceMemory; - newDrawNode.drawFunction = &_graph->drawTransparent; + newDrawNode.drawFunction = &_graph->drawTransparentDrawNode; _drawNodeList.push_back(newDrawNode); } } @@ -1136,7 +1136,7 @@ void PrinceEngine::showObjects() { newDrawNode.originalRoomSurface = nullptr; newDrawNode.data = nullptr; newDrawNode.freeSurfaceSMemory = false; - newDrawNode.drawFunction = &_graph->drawTransparent; + newDrawNode.drawFunction = &_graph->drawTransparentDrawNode; _drawNodeList.push_back(newDrawNode); } else { // showBackSprite(); @@ -1196,7 +1196,7 @@ void PrinceEngine::drawScreen() { Graphics::Surface visiblePart; if (roomSurface) { visiblePart = roomSurface->getSubArea(Common::Rect(_picWindowX, 0, roomSurface->w, roomSurface->h)); - _graph->draw(_graph->_frontScreen, 0, 0, &visiblePart); + _graph->draw(_graph->_frontScreen, &visiblePart); } Graphics::Surface *mainHeroSurface = NULL; @@ -1213,7 +1213,7 @@ void PrinceEngine::drawScreen() { newDrawNode.height = 0; newDrawNode.originalRoomSurface = nullptr; newDrawNode.data = nullptr; - newDrawNode.drawFunction = &_graph->drawTransparent; + newDrawNode.drawFunction = &_graph->drawTransparentDrawNode; if (_mainHero->_zoomFactor != 0) { Graphics::Surface *zoomedHeroSurface = _mainHero->zoomSprite(mainHeroSurface); @@ -1294,6 +1294,12 @@ void PrinceEngine::addInvObj() { drawInvItems(); _graph->update(_graph->_screenForInventory); _mst_shadow2 += 50; + Common::Event event; + Common::EventManager *eventMan = _system->getEventManager(); + eventMan->pollEvent(event); + if (shouldQuit()) { + return; + } pause(); } while (_mst_shadow2 > 256) { @@ -1302,6 +1308,12 @@ void PrinceEngine::addInvObj() { drawInvItems(); _graph->update(_graph->_screenForInventory); _mst_shadow2 -= 42; + Common::Event event; + Common::EventManager *eventMan = _system->getEventManager(); + eventMan->pollEvent(event); + if (shouldQuit()) { + return; + } pause(); } } else { @@ -1314,6 +1326,12 @@ void PrinceEngine::addInvObj() { drawInvItems(); _graph->update(_graph->_screenForInventory); _mst_shadow2 += 50; + Common::Event event; + Common::EventManager *eventMan = _system->getEventManager(); + eventMan->pollEvent(event); + if (shouldQuit()) { + return; + } pause(); } while (_mst_shadow2 > 256) { @@ -1322,6 +1340,12 @@ void PrinceEngine::addInvObj() { drawInvItems(); _graph->update(_graph->_screenForInventory); _mst_shadow2 -= 50; + Common::Event event; + Common::EventManager *eventMan = _system->getEventManager(); + eventMan->pollEvent(event); + if (shouldQuit()) { + return; + } pause(); } } @@ -1332,6 +1356,12 @@ void PrinceEngine::addInvObj() { _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase, 0); drawInvItems(); _graph->update(_graph->_screenForInventory); + Common::Event event; + Common::EventManager *eventMan = _system->getEventManager(); + eventMan->pollEvent(event); + if (shouldQuit()) { + return; + } pause(); } changeCursor(1); // here? @@ -1467,6 +1497,7 @@ void PrinceEngine::inventoryLeftButton() { if (_optionsFlag == 1) { //check_opt if (_currentMob != 0) { + //inv_check_mob if (_optionEnabled < _invOptionsNumber) { _optionsFlag = 0; // ebp = _currentMob; @@ -1474,7 +1505,7 @@ void PrinceEngine::inventoryLeftButton() { return; } } else { - // test bx, RMBMask 7996 ? + // test bx, RMBMask 7996 ? right mouse button here? } } else { if (_currentMob != 0) { @@ -1575,6 +1606,7 @@ void PrinceEngine::displayInventory() { inventoryLeftButton(); break; case Common::EVENT_RBUTTONDOWN: + inventoryRightButton(); break; case Common::EVENT_LBUTTONUP: case Common::EVENT_RBUTTONUP: From ee4c67e113511cd4d792b226e393f53d2324816f Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 10 Jun 2014 20:18:49 +0200 Subject: [PATCH 161/374] PRINCE: showObjects() - change to hex values --- engines/prince/prince.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 2707146b93cd..e8260c4faf32 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1103,19 +1103,19 @@ void PrinceEngine::clearBackAnimList() { void PrinceEngine::showObjects() { if (!_objList.empty()) { for (uint i = 0; i < _objList.size(); i++) { - if ((_objList[i]->_mask & 32768) != 0) { // 8000h + if ((_objList[i]->_mask & 0x8000) != 0) { _objList[i]->_zoomInTime--; if (_objList[i]->_zoomInTime == 0) { - _objList[i]->_mask &= 32767; //7FFFh + _objList[i]->_mask &= 0x7FFF; } else { // doZoomIn(); // mov edx, d [esi.Obj_ZoomInAddr] } } - if ((_objList[i]->_mask & 16384) != 0) { // 4000h + if ((_objList[i]->_mask & 0x4000) != 0) { _objList[i]->_zoomInTime--; if (_objList[i]->_zoomInTime == 0) { - _objList[i]->_mask &= 49151; //0BFFFh + _objList[i]->_mask &= 0xBFFF; } else { // doZoomOut(); // mov edx, d [esi.Obj_ZoomInAddr] @@ -1123,7 +1123,7 @@ void PrinceEngine::showObjects() { } Graphics::Surface *objSurface = _objList[i]->getSurface(); if (spriteCheck(objSurface->w, objSurface->h, _objList[i]->_x, _objList[i]->_y)) { - if ((_objList[i]->_mask & 512) == 0) { // 0200h + if ((_objList[i]->_mask & 0x0200) == 0) { int destX = _objList[i]->_x - _picWindowX; int destY = _objList[i]->_y - _picWindowY; DrawNode newDrawNode; From a9536b621fdf636fcc83550ffa34ec939cda0b60 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 12 Jun 2014 00:49:57 +0200 Subject: [PATCH 162/374] PRINCE: Inventory - mouse buttons handling progress --- engines/prince/prince.cpp | 108 +++++++++++++++++++++++++++++++------- engines/prince/prince.h | 10 +++- engines/prince/script.cpp | 16 ++++++ engines/prince/script.h | 1 + 4 files changed, 113 insertions(+), 22 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index e8260c4faf32..b432cdc76539 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -82,8 +82,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _invLineX(134), _invLineY(176), _invLine(5), _invLines(3), _invLineW(70), _invLineH(76), _maxInvW(72), _maxInvH(76), _invLineSkipX(2), _invLineSkipY(3), _showInventoryFlag(false), _inventoryBackgroundRemember(false), _mst_shadow(0), _mst_shadow2(0), _candleCounter(0), _invX1(53), _invY1(18), _invWidth(536), _invHeight(438), - _invCurInside(false), _optionsFlag(false), _currentMob(0), _optionEnabled(0), _invOptionsNumber(5), - _invExamY(120) { + _invCurInside(false), _optionsFlag(false), _optionEnabled(0), _invOptionsNumber(5), _invExamY(120), + _optionsMob(0), _currentPointerNumber(1), _selectedMob(0), _selectedItem(0), _selectedMode(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -1251,7 +1251,7 @@ void PrinceEngine::drawScreen() { playNextFrame(); if (!_inventoryBackgroundRemember) { - _currentMob = hotspot(_graph->_frontScreen, _mobList); + _selectedMob = hotspot(_graph->_frontScreen, _mobList); showTexts(_graph->_frontScreen); } else { _inventoryBackgroundRemember = false; @@ -1496,54 +1496,122 @@ void PrinceEngine::drawInvItems() { void PrinceEngine::inventoryLeftButton() { if (_optionsFlag == 1) { //check_opt - if (_currentMob != 0) { + if (_selectedMob != 0) { //inv_check_mob if (_optionEnabled < _invOptionsNumber) { _optionsFlag = 0; - // ebp = _currentMob; + //do_option } else { return; } } else { - // test bx, RMBMask 7996 ? right mouse button here? + // test bx, RMBMask 7996 ? right mouse button here? - > return; + //disable_use + if (_currentPointerNumber == 2) { + //disableuseuse + changeCursor(1); + _currentPointerNumber = 1; + //exit_normally + } else { + return; + } } } else { - if (_currentMob != 0) { - //if (_currentPointerNumber != 2) { - if (_currentMob != 29) { + if (_selectedMob != 0) { + if (_currentPointerNumber != 2) { + if (_selectedMob != 29) { _optionEnabled = 0; } else { + // map item _optionEnabled = 1; } //do_option - //} else { + } else { //use_item_on_item - //} + + } + } else { + return; } } //do_option - int selectedMob = _currentMob; // no _currentMob just selectedMob as global for _currentMob.mask ? if (_optionEnabled == 0) { - int invObjExamEvent = _script->scanInvObjExamEvents(selectedMob); // test this + int invObjExamEvent = _script->scanInvObjExamEvents(_selectedMob); // test this if (invObjExamEvent == -1) { // do_standard - printAt(0, 216, _invMobList[selectedMob]._examText.c_str(), kNormalWidth / 2, _invExamY); + printAt(0, 216, _invMobList[_selectedMob]._examText.c_str(), kNormalWidth / 2, _invExamY); showTexts(_graph->_screenForInventory); // here? // setSpecVoice(); + // disableuseuse + changeCursor(0); + _currentPointerNumber = 1; + //exit_normally } else { //store_new_pc // storeNewPC(); - _flags->setFlagValue(Flags::CURRMOB, selectedMob); - _currentMob = 0; - //_optionsMob = 0; + _flags->setFlagValue(Flags::CURRMOB, _selectedMob); + _selectedMob = 0; + _optionsMob = 0; + //bye_inv } - } else { + } else if (_optionEnabled == 1) { // not_examine + int invObjUse = _script->scanInvObjUseEvents(_selectedMob); // test this + if (invObjUse == -1) { + // do_standard_use + _selectedMode = 0; + _selectedItem = _selectedMob; + makeInvCursor(_selectedMob); + _currentPointerNumber = 2; + changeCursor(2); + //exit_normally + } else { + //store_new_pc + // storeNewPC(); + _flags->setFlagValue(Flags::CURRMOB, _selectedMob); + _selectedMob = 0; + _optionsMob = 0; + //bye_inv + } + } else if (_optionEnabled == 4) { + // not_use_inv + // do_standard_give + _selectedMode = 1; + _selectedItem = _selectedMob; + makeInvCursor(_selectedMob); + _currentPointerNumber = 2; + changeCursor(2); + //exit_normally + } else { + // use_item_on_item } + //exit_normally + _selectedMob = 0; + _optionsMob = 0; } void PrinceEngine::inventoryRightButton() { + enableOptions(); +} + +void PrinceEngine::enableOptions() { + if (_optionsFlag != 1) { + changeCursor(1); + _currentPointerNumber = 1; + if (_selectedMob != 0) { + //if (_mobType != 0x100) { + _optionsMob = _selectedMob; + // test opt sprite here + //_optionsX = + //_optionsY = + _optionsFlag = 1; + //} + } + } +} + +void PrinceEngine::checkInvOptions() { } @@ -1589,7 +1657,7 @@ void PrinceEngine::displayInventory() { break; } - _currentMob = hotspot(_graph->_screenForInventory, _invMobList); + _selectedMob = hotspot(_graph->_screenForInventory, _invMobList); Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); @@ -1627,7 +1695,7 @@ void PrinceEngine::displayInventory() { } } -void PrinceEngine::makeInvCursor() { +void PrinceEngine::makeInvCursor(int itemNr) { } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 46c573b0a6a9..fb30d9091813 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -273,7 +273,10 @@ class PrinceEngine : public Engine { void showMask(int maskNr, Graphics::Surface *originalRoomSurface); void clsMasks(); - int _currentMob; // number of selected Mob / inventory item + int _selectedMob; // number of selected Mob / inventory item + int _selectedItem; // number of item on mouse cursor + int _selectedMode; + int _currentPointerNumber; static const int16 kMaxInv = 90; // max amount of inventory items in whole game @@ -283,6 +286,7 @@ class PrinceEngine : public Engine { bool _showInventoryFlag; bool _optionsFlag; int _optionEnabled; + int _optionsMob; int _invOptionsNumber; int _invExamY; bool _inventoryBackgroundRemember; @@ -312,7 +316,9 @@ class PrinceEngine : public Engine { void drawInvItems(); void displayInventory(); void addInvObj(); - void makeInvCursor(); + void makeInvCursor(int itemNr); + void enableOptions(); + void checkInvOptions(); void inventoryLeftButton(); void inventoryRightButton(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 4eed60d7e5e0..9c915ca6bcd7 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -226,6 +226,22 @@ int Script::scanInvObjExamEvents(int mobMask) { return -1; // or sth else? } +int Script::scanInvObjUseEvents(int mobMask) { + RE tempRE; + int i = 0; + do { + tempRE._mob = (int)READ_UINT16(&_data[_scriptInfo.invObjUse + i * 6]); + debug("mob: %d", tempRE._mob); + tempRE._code = (int)READ_UINT32(&_data[_scriptInfo.invObjUse + i * 6 + 2]); + debug("code: %d", tempRE._code); + if (tempRE._mob == mobMask) { + return tempRE._code; + } + i++; + } while (tempRE._mob != -1); //?? || i <= 1 or without this (no items there) + return -1; // or sth else? +} + void Script::installSingleBackAnim(Common::Array &_backanimList, int offset) { BackgroundAnim newBackgroundAnim; diff --git a/engines/prince/script.h b/engines/prince/script.h index 06b09b94c4b8..d53f95185926 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -138,6 +138,7 @@ class Script { bool loadAllMasks(Common::Array &maskList, int offset); int scanInvObjExamEvents(int mobMask); + int scanInvObjUseEvents(int mobMask); const char *getString(uint32 offset) { return (const char *)(&_data[offset]); From 5163d6ce4e4e793491fc15416892bf7b0ed16dcc Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 12 Jun 2014 03:46:30 +0200 Subject: [PATCH 163/374] PRINCE: GraphicsMan - name changing; Options window - right mouse button handling progress --- engines/prince/graphics.cpp | 27 +++++++++-- engines/prince/graphics.h | 7 +-- engines/prince/prince.cpp | 90 ++++++++++++++++++++++++++++++------- engines/prince/prince.h | 12 ++++- 4 files changed, 113 insertions(+), 23 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 4f80c8cbe364..b86628009f33 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -102,7 +102,28 @@ void GraphicsMan::drawTransparentSurface(Graphics::Surface *screen, int32 posX, change(); } -void GraphicsMan::drawTransparentWithBlend(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, int transColor) { +void GraphicsMan::drawAsShadowSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, byte *shadowTable) { + byte *src1 = (byte *)s->getBasePtr(0, 0); + byte *dst1 = (byte *)screen->getBasePtr(posX, posY); + + for (int y = 0; y < s->h; y++) { + byte *src2 = src1; + byte *dst2 = dst1; + for (int x = 0; x < s->w; x++, src2++, dst2++) { + if (*src2 == kShadowColor) { + if (x + posX < screen->w && x + posX >= 0) { + if (y + posY < screen->h && y + posY >= 0) { + *dst2 = *(shadowTable + *dst2); + } + } + } + } + src1 += s->pitch; + dst1 += screen->pitch; + } +} + +void GraphicsMan::drawTransparentWithBlendSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, int transColor) { byte *src1 = (byte *)s->getBasePtr(0, 0); byte *dst1 = (byte *)screen->getBasePtr(posX, posY); byte *blendTable = (byte *)malloc(256); @@ -149,7 +170,7 @@ void GraphicsMan::drawTransparentDrawNode(Graphics::Surface *screen, DrawNode *d } } -void GraphicsMan::drawMask(Graphics::Surface *screen, DrawNode *drawNode) { +void GraphicsMan::drawMaskDrawNode(Graphics::Surface *screen, DrawNode *drawNode) { byte *src1 = (byte *)drawNode->originalRoomSurface->getBasePtr(drawNode->posX, drawNode->posY); byte *dst1 = (byte *)screen->getBasePtr(drawNode->posX, drawNode->posY); int maskWidth = drawNode->width >> 3; @@ -182,7 +203,7 @@ void GraphicsMan::drawMask(Graphics::Surface *screen, DrawNode *drawNode) { } } -void GraphicsMan::drawAsShadow(Graphics::Surface *screen, DrawNode *drawNode) { +void GraphicsMan::drawAsShadowDrawNode(Graphics::Surface *screen, DrawNode *drawNode) { byte *src1 = (byte *)drawNode->s->getBasePtr(0, 0); byte *dst1 = (byte *)screen->getBasePtr(drawNode->posX, drawNode->posY); diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index d2f112656ecd..76f6723d81d3 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -46,11 +46,12 @@ class GraphicsMan { void draw(Graphics::Surface *screen, const Graphics::Surface *s); void drawTransparentSurface(Graphics::Surface *screen, int32 posX, int32 poxY, const Graphics::Surface *s, int transColor); - void drawTransparentWithBlend(Graphics::Surface *screen, int32 posX, int32 poxY, const Graphics::Surface *s, int transColor); + void drawAsShadowSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, byte *shadowTable); + void drawTransparentWithBlendSurface(Graphics::Surface *screen, int32 posX, int32 poxY, const Graphics::Surface *s, int transColor); static void drawTransparentDrawNode(Graphics::Surface *screen, DrawNode *drawNode); - static void drawAsShadow(Graphics::Surface *screen, DrawNode *drawNode); - static void drawMask(Graphics::Surface *screen, DrawNode *drawNode); + static void drawAsShadowDrawNode(Graphics::Surface *screen, DrawNode *drawNode); + static void drawMaskDrawNode(Graphics::Surface *screen, DrawNode *drawNode); byte getBlendTableColor(byte pixelColor, byte backgroundPixelColor, byte *blendTable); diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index b432cdc76539..68bc41269b35 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -83,7 +83,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _invLineSkipX(2), _invLineSkipY(3), _showInventoryFlag(false), _inventoryBackgroundRemember(false), _mst_shadow(0), _mst_shadow2(0), _candleCounter(0), _invX1(53), _invY1(18), _invWidth(536), _invHeight(438), _invCurInside(false), _optionsFlag(false), _optionEnabled(0), _invOptionsNumber(5), _invExamY(120), - _optionsMob(0), _currentPointerNumber(1), _selectedMob(0), _selectedItem(0), _selectedMode(0) { + _optionsMob(0), _currentPointerNumber(1), _selectedMob(0), _selectedItem(0), _selectedMode(0), + _optionsWidth(210), _optionsHeight(170), _invOptionsWidth(210), _invOptionsHeight(130) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -139,6 +140,12 @@ PrinceEngine::~PrinceEngine() { } _allInvList.clear(); + _optionsPic->free(); + delete _optionsPic; + + _optionsPicInInventory->free(); + delete _optionsPicInInventory; + for (uint i = 0; i < _mainHero->_moveSet.size(); i++) { delete _mainHero->_moveSet[i]; } @@ -231,6 +238,24 @@ void PrinceEngine::init() { loadAllInv(); + _optionsPic = new Graphics::Surface(); + _optionsPic->create(_optionsWidth, _optionsHeight, Graphics::PixelFormat::createFormatCLUT8()); + Common::Rect picRect; + picRect.left = 0; + picRect.top = 0; + picRect.right = _optionsWidth; + picRect.bottom = _optionsHeight; + _optionsPic->fillRect(picRect, _graph->kShadowColor); + + _optionsPicInInventory = new Graphics::Surface(); + _optionsPicInInventory->create(_invOptionsWidth, _invOptionsHeight, Graphics::PixelFormat::createFormatCLUT8()); + Common::Rect invPicRect; + invPicRect.left = 0; + invPicRect.top = 0; + invPicRect.right = _invOptionsWidth; + invPicRect.bottom = _invOptionsHeight; + _optionsPicInInventory->fillRect(invPicRect, _graph->kShadowColor); + _roomBmp = new Image::BitmapDecoder(); _room = new Room(); @@ -852,7 +877,7 @@ void PrinceEngine::showMask(int maskNr, Graphics::Surface *originalRoomSurface) newDrawNode.originalRoomSurface = originalRoomSurface; newDrawNode.data = _maskList[maskNr].getMask(); newDrawNode.freeSurfaceSMemory = false; - newDrawNode.drawFunction = &_graph->drawMask; + newDrawNode.drawFunction = &_graph->drawMaskDrawNode; _drawNodeList.push_back(newDrawNode); } } @@ -891,7 +916,7 @@ void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX, newDrawNode.originalRoomSurface = nullptr; newDrawNode.data = _graph->_shadowTable70; newDrawNode.freeSurfaceSMemory = freeSurfaceMemory; - newDrawNode.drawFunction = &_graph->drawAsShadow; + newDrawNode.drawFunction = &_graph->drawAsShadowDrawNode; _drawNodeList.push_back(newDrawNode); } } @@ -1482,7 +1507,7 @@ void PrinceEngine::drawInvItems() { _graph->drawTransparentSurface(_graph->_screenForInventory, drawX, drawY, itemSurface, 0); } else { _mst_shadow = _mst_shadow2; - _graph->drawTransparentWithBlend(_graph->_screenForInventory, drawX, drawY, itemSurface, 0); + _graph->drawTransparentWithBlendSurface(_graph->_screenForInventory, drawX, drawY, itemSurface, 0); } } currInvX += _invLineW + _invLineSkipX; @@ -1601,10 +1626,26 @@ void PrinceEngine::enableOptions() { _currentPointerNumber = 1; if (_selectedMob != 0) { //if (_mobType != 0x100) { + 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; - // test opt sprite here - //_optionsX = - //_optionsY = + _optionsX = x1; + _optionsY = y1; _optionsFlag = 1; //} } @@ -1612,7 +1653,20 @@ void PrinceEngine::enableOptions() { } void PrinceEngine::checkInvOptions() { - + if (_optionsFlag) { + Common::Rect optionsRect; + optionsRect.left = _optionsX; + optionsRect.top = _optionsY; + optionsRect.right = _optionsX + _invOptionsWidth; + optionsRect.bottom = _optionsY + _invOptionsHeight; + Common::Point mousePos = _system->getEventManager()->getMousePos(); + if (!optionsRect.contains(mousePos)) { + _optionsFlag = 0; + _selectedMob = 0; + return; + } + _graph->drawAsShadowSurface(_graph->_screenForInventory, _optionsX, _optionsY, _optionsPicInInventory, _graph->_shadowTable50); + } } void PrinceEngine::displayInventory() { @@ -1640,24 +1694,28 @@ void PrinceEngine::displayInventory() { drawInvItems(); - Common::Rect _inventoryRect; - _inventoryRect.left = _invX1; - _inventoryRect.top = _invY1; - _inventoryRect.right = _invX1 + _invWidth; - _inventoryRect.bottom = _invY1 + _invHeight; + Common::Rect inventoryRect; + inventoryRect.left = _invX1; + inventoryRect.top = _invY1; + inventoryRect.right = _invX1 + _invWidth; + inventoryRect.bottom = _invY1 + _invHeight; Common::Point mousePos = _system->getEventManager()->getMousePos(); - if (!_invCurInside && _inventoryRect.contains(mousePos)) { + if (!_invCurInside && inventoryRect.contains(mousePos)) { _invCurInside = true; } - if (_invCurInside && !_inventoryRect.contains(mousePos)) { + if (_invCurInside && !inventoryRect.contains(mousePos)) { inventoryFlagChange(false); _invCurInside = false; break; } - _selectedMob = hotspot(_graph->_screenForInventory, _invMobList); + if (!_optionsFlag) { // test this + _selectedMob = hotspot(_graph->_screenForInventory, _invMobList); + } + + checkInvOptions(); Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index fb30d9091813..172aa565ed8c 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -283,10 +283,20 @@ class PrinceEngine : public Engine { uint32 _invTxtSize; byte *_invTxt; - bool _showInventoryFlag; + Graphics::Surface *_optionsPic; + Graphics::Surface *_optionsPicInInventory; + bool _optionsFlag; int _optionEnabled; int _optionsMob; + int _optionsX; + int _optionsY; + int _optionsWidth; + int _optionsHeight; + int _invOptionsWidth; + int _invOptionsHeight; + + bool _showInventoryFlag; int _invOptionsNumber; int _invExamY; bool _inventoryBackgroundRemember; From 8fd44cbbf3e0d34c71ab2b65d0e861a0e5a6c169 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 12 Jun 2014 23:57:45 +0200 Subject: [PATCH 164/374] PRINCE: Option window texts drawing and highlighting --- engines/prince/option_text.h | 84 ++++++++++++++++++++++++++++++++++++ engines/prince/prince.cpp | 47 +++++++++++++++++++- engines/prince/prince.h | 7 ++- 3 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 engines/prince/option_text.h diff --git a/engines/prince/option_text.h b/engines/prince/option_text.h new file mode 100644 index 000000000000..090470454763 --- /dev/null +++ b/engines/prince/option_text.h @@ -0,0 +1,84 @@ +/* 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. + * + */ + +namespace Prince { + +// Mazovia coding (with U2 negation) + +const char invOptionsTextPL[5][18] = { + { 'O', 'b', 'e', 'j', 'r', 'z', 'y', 'j', '\0' }, + { 'U', -89, 'y', 'j', '\0' }, + { 'O', 't', 'w', -94, 'r', 'z', '/', 'P', 'c', 'h', 'n', 'i', 'j', '\0' }, + { 'Z', 'a', 'm', 'k', 'n', 'i', 'j', '/', 'P', 'o', 'c', 'i', -122, 'g', 'n', 'i', 'j', '\0' }, + { 'D', 'a', 'j', '\0' } +}; + +// TODO +const char *invOptionsTextDE[] = { + "Anschauen", + "Benutzen", + "Öffnen/Stoßen", + "Schließen/Ziehen", + "Geben" +}; + +const char *invOptionsTextEN[] = { + "Examine", + "Use", + "Open/Push", + "Close/Pull", + "Give" +}; + +const char optionsTextPL[7][18] = { + { 'P', 'o', 'd', 'e', 'j', 'd', -90, '\0' }, + { 'O', 'b', 'e', 'j', 'r', 'z', 'y', 'j', '\0' }, + { 'Z', 'a', 'b', 'i', 'e', 'r', 'z', '\0' }, + { 'U', -89, 'y', 'j' }, + { 'O', 't', 'w', -94, 'r', 'z', '/', 'P', 'c', 'h', 'n', 'i', 'j', '\0' }, + { 'Z', 'a', 'm', 'k', 'n', 'i', 'j', '/', 'P', 'o', 'c', 'i', -122, 'g', 'n', 'i', 'j', '\0' }, + { 'P', 'o', 'r', 'o', 'z', 'm', 'a', 'w', 'i', 'a', 'j', '\0' } +}; + +// TODO +const char *optionsTextDE[] = { + "Hingehen", + "Anschauen", + "Wegnehmen", + "Benutzen", + "Öffnen/Stoßen", + "Schließen/Ziehen", + "Ansprechen" +}; + +const char *optionsTextEN[] = { + "Walk to", + "Examine", + "Pick up", + "Use", + "Open/Push", + "Close/Pull", + "Talk to" +}; + +} + diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 68bc41269b35..908d9dbe5055 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -60,6 +60,7 @@ #include "prince/hero.h" #include "prince/resource.h" #include "prince/animation.h" +#include "prince/option_text.h" namespace Prince { @@ -82,9 +83,10 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _invLineX(134), _invLineY(176), _invLine(5), _invLines(3), _invLineW(70), _invLineH(76), _maxInvW(72), _maxInvH(76), _invLineSkipX(2), _invLineSkipY(3), _showInventoryFlag(false), _inventoryBackgroundRemember(false), _mst_shadow(0), _mst_shadow2(0), _candleCounter(0), _invX1(53), _invY1(18), _invWidth(536), _invHeight(438), - _invCurInside(false), _optionsFlag(false), _optionEnabled(0), _invOptionsNumber(5), _invExamY(120), + _invCurInside(false), _optionsFlag(false), _optionEnabled(0), _invExamY(120), _optionsMob(0), _currentPointerNumber(1), _selectedMob(0), _selectedItem(0), _selectedMode(0), - _optionsWidth(210), _optionsHeight(170), _invOptionsWidth(210), _invOptionsHeight(130) { + _optionsWidth(210), _optionsHeight(170), _invOptionsWidth(210), _invOptionsHeight(130), _optionsStep(20), + _invOptionsStep(20), _optionsNumber(7), _invOptionsNumber(5), _optionsColor1(0xFF00EC), _optionsColor2(0xFF00FC) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -1666,6 +1668,47 @@ void PrinceEngine::checkInvOptions() { 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 < _optionsNumber) { + _optionEnabled = selectedOptionNr; + } + } + //NoBackgroundFlag = 1; + //int eax = _optionsX + _invOptionsWidth / 2; + //int ecx = _optionsNumber; + 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; + }; + uint16 textW = 0; + for (uint16 i = 0; i < invText.size(); i++) { + textW += _font->getCharWidth(invText[i]); + } + uint16 textX = _optionsX + _optionsWidth / 2 - textW / 2; + _font->drawString(_graph->_screenForInventory, invText, textX, textY, _graph->_screenForInventory->w, optionsColor); + textY += _invOptionsStep; + } + //NoBackgroundFlag = 1; } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 172aa565ed8c..6ec49dad6569 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -295,9 +295,14 @@ class PrinceEngine : public Engine { int _optionsHeight; int _invOptionsWidth; int _invOptionsHeight; + int _optionsStep; + int _invOptionsStep; + int _optionsNumber; + int _invOptionsNumber; + int _optionsColor1; // color for non-selected options + int _optionsColor2; // color for selected option bool _showInventoryFlag; - int _invOptionsNumber; int _invExamY; bool _inventoryBackgroundRemember; int _invLineX; From 8536dcc7a3c50b50f76894c4b44f4108712cc257 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 13 Jun 2014 00:40:09 +0200 Subject: [PATCH 165/374] PRINCE: option_text.h small update --- engines/prince/option_text.h | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/engines/prince/option_text.h b/engines/prince/option_text.h index 090470454763..7bd0f3bc9963 100644 --- a/engines/prince/option_text.h +++ b/engines/prince/option_text.h @@ -22,22 +22,23 @@ namespace Prince { -// Mazovia coding (with U2 negation) +// PL - Mazovia coding (with U2 negation for special letters) +// DE - Still problem with special letters const char invOptionsTextPL[5][18] = { - { 'O', 'b', 'e', 'j', 'r', 'z', 'y', 'j', '\0' }, + "Obejrzyj", { 'U', -89, 'y', 'j', '\0' }, { 'O', 't', 'w', -94, 'r', 'z', '/', 'P', 'c', 'h', 'n', 'i', 'j', '\0' }, { 'Z', 'a', 'm', 'k', 'n', 'i', 'j', '/', 'P', 'o', 'c', 'i', -122, 'g', 'n', 'i', 'j', '\0' }, - { 'D', 'a', 'j', '\0' } + "Daj" }; // TODO -const char *invOptionsTextDE[] = { +const char invOptionsTextDE[5][17] = { "Anschauen", "Benutzen", - "Öffnen/Stoßen", - "Schließen/Ziehen", + { 'Ö', 'f', 'f', 'n', 'e', 'n', '/', 'S', 't', 'o', 'ß', 'e', 'n', '\0' }, + { 'S', 'c', 'h', 'l', 'i', 'e', 'ß', 'e', 'n', '/', 'Z', 'i', 'e', 'h', 'e', 'n', '\0' }, "Geben" }; @@ -51,22 +52,22 @@ const char *invOptionsTextEN[] = { const char optionsTextPL[7][18] = { { 'P', 'o', 'd', 'e', 'j', 'd', -90, '\0' }, - { 'O', 'b', 'e', 'j', 'r', 'z', 'y', 'j', '\0' }, - { 'Z', 'a', 'b', 'i', 'e', 'r', 'z', '\0' }, + "Obejrzyj", + "Zabierz", { 'U', -89, 'y', 'j' }, { 'O', 't', 'w', -94, 'r', 'z', '/', 'P', 'c', 'h', 'n', 'i', 'j', '\0' }, { 'Z', 'a', 'm', 'k', 'n', 'i', 'j', '/', 'P', 'o', 'c', 'i', -122, 'g', 'n', 'i', 'j', '\0' }, - { 'P', 'o', 'r', 'o', 'z', 'm', 'a', 'w', 'i', 'a', 'j', '\0' } + "Porozmawiaj" }; // TODO -const char *optionsTextDE[] = { +const char optionsTextDE[7][17] = { "Hingehen", "Anschauen", "Wegnehmen", "Benutzen", - "Öffnen/Stoßen", - "Schließen/Ziehen", + { 'Ö', 'f', 'f', 'n', 'e', 'n', '/', 'S', 't', 'o', 'ß', 'e', 'n', '\0' }, + { 'S', 'c', 'h', 'l', 'i', 'e', 'ß', 'e', 'n', '/', 'Z', 'i', 'e', 'h', 'e', 'n', '\0' }, "Ansprechen" }; From db19f9282cce98f8adf2aba07f12e3caf51f793c Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 14 Jun 2014 12:51:50 +0200 Subject: [PATCH 166/374] PRINCE: German font loading, letters fix in options menu --- engines/prince/option_text.h | 47 +++++++++++++++++++----------------- engines/prince/prince.cpp | 11 ++++++--- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/engines/prince/option_text.h b/engines/prince/option_text.h index 7bd0f3bc9963..ac5d7588b391 100644 --- a/engines/prince/option_text.h +++ b/engines/prince/option_text.h @@ -23,8 +23,6 @@ namespace Prince { // PL - Mazovia coding (with U2 negation for special letters) -// DE - Still problem with special letters - const char invOptionsTextPL[5][18] = { "Obejrzyj", { 'U', -89, 'y', 'j', '\0' }, @@ -33,23 +31,6 @@ const char invOptionsTextPL[5][18] = { "Daj" }; -// TODO -const char invOptionsTextDE[5][17] = { - "Anschauen", - "Benutzen", - { 'Ö', 'f', 'f', 'n', 'e', 'n', '/', 'S', 't', 'o', 'ß', 'e', 'n', '\0' }, - { 'S', 'c', 'h', 'l', 'i', 'e', 'ß', 'e', 'n', '/', 'Z', 'i', 'e', 'h', 'e', 'n', '\0' }, - "Geben" -}; - -const char *invOptionsTextEN[] = { - "Examine", - "Use", - "Open/Push", - "Close/Pull", - "Give" -}; - const char optionsTextPL[7][18] = { { 'P', 'o', 'd', 'e', 'j', 'd', -90, '\0' }, "Obejrzyj", @@ -60,17 +41,39 @@ const char optionsTextPL[7][18] = { "Porozmawiaj" }; -// TODO +// DE - Other font then for PL + ISO 8859-2 or Windows-1250 +// + special letter values changing (with U2 negation) +// Normal value: 196, 214, 220, 223, 228, 246, 252 +// Prince change: 131, 132, 133, 127, 128, 129, 130 +// U2 neg: -125, -124, -123, 127, 128, -127, -126 + +char invOptionsTextDE[5][17] = { + "Anschauen", + "Benutzen", + { -124, 'f', 'f', 'n', 'e', 'n', '/', 'S', 't', 'o', 127, 'e', 'n', '\0' }, + { 'S', 'c', 'h', 'l', 'i', 'e', 127, 'e', 'n', '/', 'Z', 'i', 'e', 'h', 'e', 'n', '\0' }, + "Geben" +}; + const char optionsTextDE[7][17] = { "Hingehen", "Anschauen", "Wegnehmen", "Benutzen", - { 'Ö', 'f', 'f', 'n', 'e', 'n', '/', 'S', 't', 'o', 'ß', 'e', 'n', '\0' }, - { 'S', 'c', 'h', 'l', 'i', 'e', 'ß', 'e', 'n', '/', 'Z', 'i', 'e', 'h', 'e', 'n', '\0' }, + { -124, 'f', 'f', 'n', 'e', 'n', '/', 'S', 't', 'o', 127, 'e', 'n', '\0' }, + { 'S', 'c', 'h', 'l', 'i', 'e', 127, 'e', 'n', '/', 'Z', 'i', 'e', 'h', 'e', 'n', '\0' }, "Ansprechen" }; +// EN +const char *invOptionsTextEN[] = { + "Examine", + "Use", + "Open/Push", + "Close/Pull", + "Give" +}; + const char *optionsTextEN[] = { "Walk to", "Examine", diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 908d9dbe5055..0f52e97e8020 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -194,9 +194,14 @@ void PrinceEngine::init() { _debugger = new Debugger(this); _midiPlayer = new MusicPlayer(this); - - _font = new Font(); - Resource::loadResource(_font, "font1.raw", true); + + if (getLanguage() == Common::DE_DEU) { + _font = new Font(); + Resource::loadResource(_font, "font3.raw", true); + } else { + _font = new Font(); + Resource::loadResource(_font, "font1.raw", true); + } _suitcaseBmp = new MhwanhDecoder(); Resource::loadResource(_suitcaseBmp, "walizka", true); From 9e94888fa288ef9a4388eb13c118d0b7ac0ada2c Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 14 Jun 2014 16:29:49 +0200 Subject: [PATCH 167/374] PRINCE: German special letters fix in intro - printAt function --- engines/prince/option_text.h | 2 +- engines/prince/prince.cpp | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/engines/prince/option_text.h b/engines/prince/option_text.h index ac5d7588b391..55fc23770e31 100644 --- a/engines/prince/option_text.h +++ b/engines/prince/option_text.h @@ -45,7 +45,7 @@ const char optionsTextPL[7][18] = { // + special letter values changing (with U2 negation) // Normal value: 196, 214, 220, 223, 228, 246, 252 // Prince change: 131, 132, 133, 127, 128, 129, 130 -// U2 neg: -125, -124, -123, 127, 128, -127, -126 +// U2 neg: -125, -124, -123, 127, -128, -127, -126 char invOptionsTextDE[5][17] = { "Anschauen", diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 0f52e97e8020..95f006881110 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -758,8 +758,41 @@ void PrinceEngine::printAt(uint32 slot, uint8 color, const char *s, uint16 x, ui debugC(1, DebugChannel::kEngine, "PrinceEngine::printAt slot %d, color %d, x %02d, y %02d, str %s", slot, color, x, y, s); + char *destStr = (char *)malloc(strlen(s)); + strcpy(destStr, s); + char *strPointer = destStr; + + if (getLanguage() == Common::DE_DEU) { + while (*strPointer) { + switch(*strPointer) { + case -60: + *strPointer = -125; + break; + case -42: + *strPointer = -124; + break; + case -36: + *strPointer = -123; + break; + case -33: + *strPointer = 127; + break; + case -28: + *strPointer = -128; + break; + case -10: + *strPointer = -127; + break; + case -4: + *strPointer = -126; + break; + } + strPointer++; + } + } + Text &text = _textSlots[slot]; - text._str = s; + text._str = destStr; text._x = x; text._y = y; text._color = color; From db542d00f0ecf250e639cea1104889561518b59a Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 14 Jun 2014 19:26:24 +0200 Subject: [PATCH 168/374] PRINCE: German letters fix for inventory names --- engines/prince/prince.cpp | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 95f006881110..4e7e0cdb2f6a 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -728,9 +728,39 @@ int PrinceEngine::hotspot(Graphics::Surface *screen, Common::Array &mobList continue; } if (mob._rect.contains(mousePosCamera)) { + Common::String mobName = mob._name; + + if (getLanguage() == Common::DE_DEU) { + for (uint16 i = 0; i < mobName.size(); i++) { + switch (mobName[i]) { + case -60: + mobName.setChar(-125, i); + break; + case -42: + mobName.setChar(-124, i); + break; + case -36: + mobName.setChar(-123, i); + break; + case -33: + mobName.setChar(127, i); + break; + case -28: + mobName.setChar(-128, i); + break; + case -10: + mobName.setChar(-127, i); + break; + case -4: + mobName.setChar(-126, i); + break; + } + } + } + uint16 textW = 0; - for (uint16 i = 0; i < mob._name.size(); i++) { - textW += _font->getCharWidth(mob._name[i]); + for (uint16 i = 0; i < mobName.size(); i++) { + textW += _font->getCharWidth(mobName[i]); } uint16 x = mousepos.x - textW / 2; @@ -747,7 +777,7 @@ int PrinceEngine::hotspot(Graphics::Surface *screen, Common::Array &mobList y = _font->getFontHeight() - 2; } - _font->drawString(screen, mob._name, x, y, screen->w, 216); + _font->drawString(screen, mobName, x, y, screen->w, 216); return mob._mask; } } From f1b36cffeacf9de7b17fe9673412176d44cbc468 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 14 Jun 2014 20:30:50 +0200 Subject: [PATCH 169/374] PRINCE: German mob list loading fix --- engines/prince/prince.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 4e7e0cdb2f6a..b48a5101e6dc 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -371,7 +371,13 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { Resource::loadResource(_pscrList, "pscr.lst", false); _mobList.clear(); - Resource::loadResource(_mobList, "mob.lst", false); + if (getLanguage() == Common::DE_DEU) { + 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 { + Resource::loadResource(_mobList, "mob.lst", false); + } _animList.clear(); Resource::loadResource(_animList, "anim.lst", false); From 7c9d66bbe98048ebe83d7cd7a580c55d0be51f97 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 14 Jun 2014 22:22:39 +0200 Subject: [PATCH 170/374] PRINCE: Texts X position fix in options window and hotspot() --- engines/prince/prince.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index b48a5101e6dc..402bce9fafe0 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -764,10 +764,7 @@ int PrinceEngine::hotspot(Graphics::Surface *screen, Common::Array &mobList } } - uint16 textW = 0; - for (uint16 i = 0; i < mobName.size(); i++) { - textW += _font->getCharWidth(mobName[i]); - } + uint16 textW = getTextWidth(mobName.c_str()); uint16 x = mousepos.x - textW / 2; if (x > screen->w) { @@ -1752,8 +1749,6 @@ void PrinceEngine::checkInvOptions() { } } //NoBackgroundFlag = 1; - //int eax = _optionsX + _invOptionsWidth / 2; - //int ecx = _optionsNumber; int optionsColor; int textY = _optionsY + 16; for (int i = 0; i < _invOptionsNumber; i++) { @@ -1774,12 +1769,9 @@ void PrinceEngine::checkInvOptions() { invText = invOptionsTextEN[i]; break; }; - uint16 textW = 0; - for (uint16 i = 0; i < invText.size(); i++) { - textW += _font->getCharWidth(invText[i]); - } - uint16 textX = _optionsX + _optionsWidth / 2 - textW / 2; - _font->drawString(_graph->_screenForInventory, invText, textX, textY, _graph->_screenForInventory->w, optionsColor); + uint16 textW = getTextWidth(invText.c_str()); + uint16 textX = _optionsX + _invOptionsWidth / 2 - textW / 2; + _font->drawString(_graph->_screenForInventory, invText, textX, textY, textW, optionsColor); textY += _invOptionsStep; } //NoBackgroundFlag = 1; From 9e4e84166d6368e08ef42dbebc281b65d6dce8af Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 15 Jun 2014 13:30:20 +0200 Subject: [PATCH 171/374] PRINCE: option_text.h update --- engines/prince/option_text.h | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/engines/prince/option_text.h b/engines/prince/option_text.h index 55fc23770e31..13178d984034 100644 --- a/engines/prince/option_text.h +++ b/engines/prince/option_text.h @@ -22,36 +22,34 @@ namespace Prince { -// PL - Mazovia coding (with U2 negation for special letters) +// PL - Mazovia coding const char invOptionsTextPL[5][18] = { "Obejrzyj", - { 'U', -89, 'y', 'j', '\0' }, - { 'O', 't', 'w', -94, 'r', 'z', '/', 'P', 'c', 'h', 'n', 'i', 'j', '\0' }, - { 'Z', 'a', 'm', 'k', 'n', 'i', 'j', '/', 'P', 'o', 'c', 'i', -122, 'g', 'n', 'i', 'j', '\0' }, + "U\xa7""yj", + "Otw\xa2""rz/Pchnij", + "Zamknij/Poci\x86""gnij", "Daj" }; const char optionsTextPL[7][18] = { - { 'P', 'o', 'd', 'e', 'j', 'd', -90, '\0' }, + "Podejd\xa6", "Obejrzyj", "Zabierz", - { 'U', -89, 'y', 'j' }, - { 'O', 't', 'w', -94, 'r', 'z', '/', 'P', 'c', 'h', 'n', 'i', 'j', '\0' }, - { 'Z', 'a', 'm', 'k', 'n', 'i', 'j', '/', 'P', 'o', 'c', 'i', -122, 'g', 'n', 'i', 'j', '\0' }, + "U\xa7""yj", + "Otw\xa2""rz/Pchnij", + "Zamknij/Poci\x86""gnij", "Porozmawiaj" }; // DE - Other font then for PL + ISO 8859-2 or Windows-1250 -// + special letter values changing (with U2 negation) +// + special letter values changing // Normal value: 196, 214, 220, 223, 228, 246, 252 // Prince change: 131, 132, 133, 127, 128, 129, 130 -// U2 neg: -125, -124, -123, 127, -128, -127, -126 - char invOptionsTextDE[5][17] = { "Anschauen", "Benutzen", - { -124, 'f', 'f', 'n', 'e', 'n', '/', 'S', 't', 'o', 127, 'e', 'n', '\0' }, - { 'S', 'c', 'h', 'l', 'i', 'e', 127, 'e', 'n', '/', 'Z', 'i', 'e', 'h', 'e', 'n', '\0' }, + "\x84""ffnen/Sto\x7f""en", + "Schlie\x7f""en/Ziehen", "Geben" }; @@ -60,8 +58,8 @@ const char optionsTextDE[7][17] = { "Anschauen", "Wegnehmen", "Benutzen", - { -124, 'f', 'f', 'n', 'e', 'n', '/', 'S', 't', 'o', 127, 'e', 'n', '\0' }, - { 'S', 'c', 'h', 'l', 'i', 'e', 127, 'e', 'n', '/', 'Z', 'i', 'e', 'h', 'e', 'n', '\0' }, + "\x84""ffnen/Sto\x7f""en", + "Schlie\x7""en/Ziehen", "Ansprechen" }; From e6da7b538775d5ce0f3179789d04c13a9b76fb74 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 15 Jun 2014 15:04:24 +0200 Subject: [PATCH 172/374] PRINCE: hotspot() update - proper exam text, German letters fix --- engines/prince/prince.cpp | 56 ++++++++++++++++++++++----------------- engines/prince/prince.h | 1 + 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 402bce9fafe0..375f719bb379 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -475,6 +475,10 @@ void PrinceEngine::playSample(uint16 sampleId, uint16 loopType) { } } +void PrinceEngine::setSpecVoice() { + +} + void PrinceEngine::stopSample(uint16 sampleId) { _mixer->stopID(sampleId); _voiceStream[sampleId] = nullptr; @@ -728,6 +732,7 @@ int PrinceEngine::hotspot(Graphics::Surface *screen, Common::Array &mobList Common::Point mousepos = _system->getEventManager()->getMousePos(); Common::Point mousePosCamera(mousepos.x + _picWindowX, mousepos.y); + int i = 0; for (Common::Array::const_iterator it = mobList.begin(); it != mobList.end() ; it++) { const Mob& mob = *it; if (mob._visible != 0) { // 0 is for visible @@ -737,28 +742,28 @@ int PrinceEngine::hotspot(Graphics::Surface *screen, Common::Array &mobList Common::String mobName = mob._name; if (getLanguage() == Common::DE_DEU) { - for (uint16 i = 0; i < mobName.size(); i++) { + for (uint i = 0; i < mobName.size(); i++) { switch (mobName[i]) { - case -60: - mobName.setChar(-125, i); + case '\xc4': + mobName.setChar('\x83', i); break; - case -42: - mobName.setChar(-124, i); + case '\xd6': + mobName.setChar('\x84', i); break; - case -36: - mobName.setChar(-123, i); + case '\xdc': + mobName.setChar('\x85', i); break; - case -33: - mobName.setChar(127, i); + case '\xdf': + mobName.setChar('\x7f', i); break; - case -28: - mobName.setChar(-128, i); + case '\xe4': + mobName.setChar('\x80', i); break; - case -10: - mobName.setChar(-127, i); + case '\xf6': + mobName.setChar('\x81', i); break; - case -4: - mobName.setChar(-126, i); + case '\xfc': + mobName.setChar('\x82', i); break; } } @@ -781,8 +786,9 @@ int PrinceEngine::hotspot(Graphics::Surface *screen, Common::Array &mobList } _font->drawString(screen, mobName, x, y, screen->w, 216); - return mob._mask; + return i + 1; } + i++; } return 0; } @@ -1617,7 +1623,8 @@ void PrinceEngine::inventoryLeftButton() { } else { if (_selectedMob != 0) { if (_currentPointerNumber != 2) { - if (_selectedMob != 29) { + //if (_selectedMob != 29) { + if (_invMobList[_selectedMob - 1]._mask != 29) { _optionEnabled = 0; } else { // map item @@ -1637,9 +1644,8 @@ void PrinceEngine::inventoryLeftButton() { int invObjExamEvent = _script->scanInvObjExamEvents(_selectedMob); // test this if (invObjExamEvent == -1) { // do_standard - printAt(0, 216, _invMobList[_selectedMob]._examText.c_str(), kNormalWidth / 2, _invExamY); - showTexts(_graph->_screenForInventory); // here? - // setSpecVoice(); + printAt(0, 216, _invMobList[_selectedMob - 1]._examText.c_str(), kNormalWidth / 2, _invExamY); + setSpecVoice(); // disableuseuse changeCursor(0); _currentPointerNumber = 1; @@ -1647,7 +1653,7 @@ void PrinceEngine::inventoryLeftButton() { } else { //store_new_pc // storeNewPC(); - _flags->setFlagValue(Flags::CURRMOB, _selectedMob); + _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob - 1]._mask); _selectedMob = 0; _optionsMob = 0; //bye_inv @@ -1666,7 +1672,7 @@ void PrinceEngine::inventoryLeftButton() { } else { //store_new_pc // storeNewPC(); - _flags->setFlagValue(Flags::CURRMOB, _selectedMob); + _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob - 1]._mask); _selectedMob = 0; _optionsMob = 0; //bye_inv @@ -1748,7 +1754,6 @@ void PrinceEngine::checkInvOptions() { _optionEnabled = selectedOptionNr; } } - //NoBackgroundFlag = 1; int optionsColor; int textY = _optionsY + 16; for (int i = 0; i < _invOptionsNumber; i++) { @@ -1774,7 +1779,6 @@ void PrinceEngine::checkInvOptions() { _font->drawString(_graph->_screenForInventory, invText, textX, textY, textW, optionsColor); textY += _invOptionsStep; } - //NoBackgroundFlag = 1; } } @@ -1796,6 +1800,8 @@ void PrinceEngine::displayInventory() { while (!shouldQuit()) { + // cursor check ! + rememberScreenInv(); Graphics::Surface *suitcase = _suitcaseBmp->getSurface(); @@ -1803,6 +1809,8 @@ void PrinceEngine::displayInventory() { drawInvItems(); + showTexts(_graph->_screenForInventory); + Common::Rect inventoryRect; inventoryRect.left = _invX1; inventoryRect.top = _invY1; diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 6ec49dad6569..d91037cc0d8e 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -239,6 +239,7 @@ class PrinceEngine : public Engine { void playSample(uint16 sampleId, uint16 loopType); void stopSample(uint16 sampleId); + void setSpecVoice(); virtual GUI::Debugger *getDebugger(); From cb40b5123b6befccd95e24a0563152002567bf54 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 15 Jun 2014 15:12:48 +0200 Subject: [PATCH 173/374] PRINCE: printAt() update for German letters --- engines/prince/prince.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 375f719bb379..9cacbf7a947a 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -804,26 +804,26 @@ void PrinceEngine::printAt(uint32 slot, uint8 color, const char *s, uint16 x, ui if (getLanguage() == Common::DE_DEU) { while (*strPointer) { switch(*strPointer) { - case -60: - *strPointer = -125; + case '\xc4': + *strPointer = '\x83'; break; - case -42: - *strPointer = -124; + case '\xd6': + *strPointer = '\x84'; break; - case -36: - *strPointer = -123; + case '\xdc': + *strPointer = '\x85'; break; - case -33: - *strPointer = 127; + case '\xdf': + *strPointer = '\x7f'; break; - case -28: - *strPointer = -128; + case '\xe4': + *strPointer = '\x80'; break; - case -10: - *strPointer = -127; + case '\xf6': + *strPointer = '\x81'; break; - case -4: - *strPointer = -126; + case '\xfc': + *strPointer = '\x82'; break; } strPointer++; From ca7554dae3bfce513d6a0b92be1274e168b60a87 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 15 Jun 2014 15:52:08 +0200 Subject: [PATCH 174/374] PRINCE: checkOptions() implementation --- engines/prince/prince.cpp | 53 ++++++++++++++++++++++++++++++++++++++- engines/prince/prince.h | 1 + 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 9cacbf7a947a..12d996158365 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1731,6 +1731,57 @@ void PrinceEngine::enableOptions() { } } +void PrinceEngine::checkOptions() { + if (_optionsFlag) { + Common::Rect optionsRect; + optionsRect.left = _optionsX; + optionsRect.top = _optionsY; + optionsRect.right = _optionsX + _optionsWidth; + optionsRect.bottom = _optionsY + _optionsHeight; + Common::Point mousePos = _system->getEventManager()->getMousePos(); + if (!optionsRect.contains(mousePos)) { + _optionsFlag = 0; + _selectedMob = 0; + 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; + }; + uint16 textW = getTextWidth(optText.c_str()); + uint16 textX = _optionsX + _optionsWidth / 2 - textW / 2; + _font->drawString(_graph->_screenForInventory, optText, textX, textY, textW, optionsColor); + textY += _optionsStep; + } + } +} + void PrinceEngine::checkInvOptions() { if (_optionsFlag) { Common::Rect optionsRect; @@ -1750,7 +1801,7 @@ void PrinceEngine::checkInvOptions() { int optionsYCord = mousePos.y - (_optionsY + 16); if (optionsYCord >= 0) { int selectedOptionNr = optionsYCord / _invOptionsStep; - if (selectedOptionNr < _optionsNumber) { + if (selectedOptionNr < _invOptionsNumber) { _optionEnabled = selectedOptionNr; } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index d91037cc0d8e..80666b47a98d 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -334,6 +334,7 @@ class PrinceEngine : public Engine { void addInvObj(); void makeInvCursor(int itemNr); void enableOptions(); + void checkOptions(); void checkInvOptions(); void inventoryLeftButton(); void inventoryRightButton(); From e3b5c0ecccd6516fca4dec1b487042b2bcaab9c7 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 15 Jun 2014 16:15:55 +0200 Subject: [PATCH 175/374] PRINCE: Options menu outside of inventory --- engines/prince/option_text.h | 2 +- engines/prince/prince.cpp | 27 ++++++++++++++++++++------- engines/prince/prince.h | 6 ++++-- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/engines/prince/option_text.h b/engines/prince/option_text.h index 13178d984034..0a1548a8a5ce 100644 --- a/engines/prince/option_text.h +++ b/engines/prince/option_text.h @@ -59,7 +59,7 @@ const char optionsTextDE[7][17] = { "Wegnehmen", "Benutzen", "\x84""ffnen/Sto\x7f""en", - "Schlie\x7""en/Ziehen", + "Schlie\x7f""en/Ziehen", "Ansprechen" }; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 12d996158365..6d6f3fe8efa7 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1355,8 +1355,11 @@ void PrinceEngine::drawScreen() { playNextFrame(); if (!_inventoryBackgroundRemember) { - _selectedMob = hotspot(_graph->_frontScreen, _mobList); + if (!_optionsFlag) { + _selectedMob = hotspot(_graph->_frontScreen, _mobList); + } showTexts(_graph->_frontScreen); + checkOptions(); } else { _inventoryBackgroundRemember = false; } @@ -1597,7 +1600,13 @@ void PrinceEngine::drawInvItems() { } } -void PrinceEngine::inventoryLeftButton() { +void PrinceEngine::rightMouseButton() { + if (_currentPointerNumber < 2) { + enableOptions(); + } +} + +void PrinceEngine::inventoryLeftMouseButton() { if (_optionsFlag == 1) { //check_opt if (_selectedMob != 0) { @@ -1695,7 +1704,7 @@ void PrinceEngine::inventoryLeftButton() { _optionsMob = 0; } -void PrinceEngine::inventoryRightButton() { +void PrinceEngine::inventoryRightMouseButton() { enableOptions(); } @@ -1776,7 +1785,7 @@ void PrinceEngine::checkOptions() { }; uint16 textW = getTextWidth(optText.c_str()); uint16 textX = _optionsX + _optionsWidth / 2 - textW / 2; - _font->drawString(_graph->_screenForInventory, optText, textX, textY, textW, optionsColor); + _font->drawString(_graph->_frontScreen, optText, textX, textY, textW, optionsColor); textY += _optionsStep; } } @@ -1879,7 +1888,7 @@ void PrinceEngine::displayInventory() { break; } - if (!_optionsFlag) { // test this + if (!_optionsFlag) { _selectedMob = hotspot(_graph->_screenForInventory, _invMobList); } @@ -1897,12 +1906,13 @@ void PrinceEngine::displayInventory() { case Common::EVENT_MOUSEMOVE: break; case Common::EVENT_LBUTTONDOWN: - inventoryLeftButton(); + inventoryLeftMouseButton(); break; case Common::EVENT_RBUTTONDOWN: - inventoryRightButton(); + inventoryRightMouseButton(); break; case Common::EVENT_LBUTTONUP: + break; case Common::EVENT_RBUTTONUP: break; case Common::EVENT_QUIT: @@ -1944,9 +1954,12 @@ void PrinceEngine::mainLoop() { case Common::EVENT_MOUSEMOVE: break; case Common::EVENT_LBUTTONDOWN: + break; case Common::EVENT_RBUTTONDOWN: + rightMouseButton(); break; case Common::EVENT_LBUTTONUP: + break; case Common::EVENT_RBUTTONUP: break; case Common::EVENT_QUIT: diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 80666b47a98d..0f541517cb02 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -336,8 +336,10 @@ class PrinceEngine : public Engine { void enableOptions(); void checkOptions(); void checkInvOptions(); - void inventoryLeftButton(); - void inventoryRightButton(); + + void rightMouseButton(); + void inventoryLeftMouseButton(); + void inventoryRightMouseButton(); int testAnimNr; int testAnimFrame; From 85108d6fb2ab91a6f9ae15db404f399f846407ee Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 15 Jun 2014 17:59:13 +0200 Subject: [PATCH 176/374] PRINCE: Voices for inventory exam texts --- engines/prince/prince.cpp | 9 +++------ engines/prince/prince.h | 1 - 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 6d6f3fe8efa7..0cfe9d6cd64b 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -475,10 +475,6 @@ void PrinceEngine::playSample(uint16 sampleId, uint16 loopType) { } } -void PrinceEngine::setSpecVoice() { - -} - void PrinceEngine::stopSample(uint16 sampleId) { _mixer->stopID(sampleId); _voiceStream[sampleId] = nullptr; @@ -866,7 +862,7 @@ void PrinceEngine::showTexts(Graphics::Surface *screen) { ); } - --text._time; + text._time--; if (text._time == 0) { text._str = nullptr; } @@ -1654,7 +1650,8 @@ void PrinceEngine::inventoryLeftMouseButton() { if (invObjExamEvent == -1) { // do_standard printAt(0, 216, _invMobList[_selectedMob - 1]._examText.c_str(), kNormalWidth / 2, _invExamY); - setSpecVoice(); + loadVoice(0, 28, Common::String::format("inv%02d-01.WAV", _invMobList[_selectedMob - 1]._mask)); + playSample(28, 0); // disableuseuse changeCursor(0); _currentPointerNumber = 1; diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 0f541517cb02..d3843e78cfe6 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -239,7 +239,6 @@ class PrinceEngine : public Engine { void playSample(uint16 sampleId, uint16 loopType); void stopSample(uint16 sampleId); - void setSpecVoice(); virtual GUI::Debugger *getDebugger(); From 7bc4599dadd0aad7e2bcc4e1d647f04555f377f7 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 15 Jun 2014 18:18:35 +0200 Subject: [PATCH 177/374] PRINCE: Cursor fix for inventory - check if voice is playing --- engines/prince/prince.cpp | 42 +++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 0cfe9d6cd64b..5cec882c7132 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1857,7 +1857,28 @@ void PrinceEngine::displayInventory() { while (!shouldQuit()) { - // cursor check ! + if (_textSlots[0]._str != nullptr) { + changeCursor(0); + } else { + changeCursor(_currentPointerNumber); + + Common::Rect inventoryRect; + inventoryRect.left = _invX1; + inventoryRect.top = _invY1; + inventoryRect.right = _invX1 + _invWidth; + inventoryRect.bottom = _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(); @@ -1868,24 +1889,7 @@ void PrinceEngine::displayInventory() { showTexts(_graph->_screenForInventory); - Common::Rect inventoryRect; - inventoryRect.left = _invX1; - inventoryRect.top = _invY1; - inventoryRect.right = _invX1 + _invWidth; - inventoryRect.bottom = _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; - } - - if (!_optionsFlag) { + if (!_optionsFlag && _textSlots[0]._str == nullptr) { _selectedMob = hotspot(_graph->_screenForInventory, _invMobList); } From d9e2fc15d15dbc51f398c5044ba1f13edfbe9338 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 15 Jun 2014 18:28:11 +0200 Subject: [PATCH 178/374] PRINCE: RMB - blocked while playing voice. Canceling voice with LMB --- engines/prince/prince.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 5cec882c7132..94997643336d 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1603,6 +1603,11 @@ void PrinceEngine::rightMouseButton() { } void PrinceEngine::inventoryLeftMouseButton() { + + _textSlots[0]._time = 0; + _textSlots[0]._str = nullptr; + stopSample(28); + if (_optionsFlag == 1) { //check_opt if (_selectedMob != 0) { @@ -1702,7 +1707,9 @@ void PrinceEngine::inventoryLeftMouseButton() { } void PrinceEngine::inventoryRightMouseButton() { - enableOptions(); + if (_textSlots[0]._str == nullptr) { + enableOptions(); + } } void PrinceEngine::enableOptions() { From 2ba814516c3044f541181911f0e3d24fae683d91 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 15 Jun 2014 21:04:12 +0200 Subject: [PATCH 179/374] PRINCE: Rects constructors - update --- engines/prince/prince.cpp | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 94997643336d..ed29e5f5c2bf 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -247,20 +247,12 @@ void PrinceEngine::init() { _optionsPic = new Graphics::Surface(); _optionsPic->create(_optionsWidth, _optionsHeight, Graphics::PixelFormat::createFormatCLUT8()); - Common::Rect picRect; - picRect.left = 0; - picRect.top = 0; - picRect.right = _optionsWidth; - picRect.bottom = _optionsHeight; + Common::Rect picRect(0, 0, _optionsWidth, _optionsHeight); _optionsPic->fillRect(picRect, _graph->kShadowColor); _optionsPicInInventory = new Graphics::Surface(); _optionsPicInInventory->create(_invOptionsWidth, _invOptionsHeight, Graphics::PixelFormat::createFormatCLUT8()); - Common::Rect invPicRect; - invPicRect.left = 0; - invPicRect.top = 0; - invPicRect.right = _invOptionsWidth; - invPicRect.bottom = _invOptionsHeight; + Common::Rect invPicRect(0, 0, _invOptionsWidth, _invOptionsHeight); _optionsPicInInventory->fillRect(invPicRect, _graph->kShadowColor); _roomBmp = new Image::BitmapDecoder(); @@ -1746,11 +1738,7 @@ void PrinceEngine::enableOptions() { void PrinceEngine::checkOptions() { if (_optionsFlag) { - Common::Rect optionsRect; - optionsRect.left = _optionsX; - optionsRect.top = _optionsY; - optionsRect.right = _optionsX + _optionsWidth; - optionsRect.bottom = _optionsY + _optionsHeight; + Common::Rect optionsRect(_optionsX, _optionsY, _optionsX + _optionsWidth, _optionsY + _optionsHeight); Common::Point mousePos = _system->getEventManager()->getMousePos(); if (!optionsRect.contains(mousePos)) { _optionsFlag = 0; @@ -1797,11 +1785,7 @@ void PrinceEngine::checkOptions() { void PrinceEngine::checkInvOptions() { if (_optionsFlag) { - Common::Rect optionsRect; - optionsRect.left = _optionsX; - optionsRect.top = _optionsY; - optionsRect.right = _optionsX + _invOptionsWidth; - optionsRect.bottom = _optionsY + _invOptionsHeight; + Common::Rect optionsRect(_optionsX, _optionsY, _optionsX + _invOptionsWidth, _optionsY + _invOptionsHeight); Common::Point mousePos = _system->getEventManager()->getMousePos(); if (!optionsRect.contains(mousePos)) { _optionsFlag = 0; @@ -1869,11 +1853,7 @@ void PrinceEngine::displayInventory() { } else { changeCursor(_currentPointerNumber); - Common::Rect inventoryRect; - inventoryRect.left = _invX1; - inventoryRect.top = _invY1; - inventoryRect.right = _invX1 + _invWidth; - inventoryRect.bottom = _invY1 + _invHeight; + Common::Rect inventoryRect(_invX1, _invY1, _invX1 + _invWidth, _invY1 + _invHeight); Common::Point mousePos = _system->getEventManager()->getMousePos(); if (!_invCurInside && inventoryRect.contains(mousePos)) { From e452e088f43d88a11c3fb8e820345269957da13e Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 16 Jun 2014 21:33:30 +0200 Subject: [PATCH 180/374] PRINCE: Beginning of makeInvCursor and dialog functions --- engines/prince/prince.cpp | 28 +++++++++++++++++++++++++++- engines/prince/prince.h | 11 ++++++++++- engines/prince/script.cpp | 1 + 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index ed29e5f5c2bf..2d08aa11159c 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -436,6 +436,22 @@ void PrinceEngine::changeCursor(uint16 curId) { CursorMan.showMouse(true); } +void PrinceEngine::makeInvCursor(int itemNr) { + const Graphics::Surface *cur1Surface = nullptr; + cur1Surface = _cursor1->getSurface(); + int cur1W = cur1Surface->w; + int cur1H = cur1Surface->h; + + const Graphics::Surface *itemSurface = nullptr; + itemSurface = _allInvList[itemNr].getSurface(); + int itemW = itemSurface->w; + int itemH = itemSurface->h; + + int cur2W = cur1W + itemW / 2; + int cur2H = cur1H + itemH / 2; + //TODO +} + bool PrinceEngine::playNextFrame() { if (!_flicPlayer.isVideoLoaded()) return false; @@ -1919,7 +1935,17 @@ void PrinceEngine::displayInventory() { } } -void PrinceEngine::makeInvCursor(int itemNr) { +void PrinceEngine::createDialogBox(Common::Array &dialogData) { + int lineSpace = 10; + int dBoxWidth = 600; + + int dialogLines = 0; + + int nrOfDialogLines = 0; // ebp + int nrOfSentence = 0; // edx +} + +void PrinceEngine::runDialog() { } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index d3843e78cfe6..9f4dd57f03e9 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -199,6 +199,11 @@ struct DrawNode { void (*drawFunction)(Graphics::Surface *, DrawNode *); }; +struct DialogLine { + int _nr; + Common::String _line; +}; + struct DebugChannel { enum Type { @@ -260,6 +265,7 @@ class PrinceEngine : public Engine { Common::Array _animList; Common::Array _backAnimList; + Common::Array> _dialogBoxList; Common::RandomSource _randomSource; @@ -340,6 +346,9 @@ class PrinceEngine : public Engine { void inventoryLeftMouseButton(); void inventoryRightMouseButton(); + void createDialogBox(Common::Array &dialogData); + void runDialog(); + int testAnimNr; int testAnimFrame; @@ -386,7 +395,7 @@ class PrinceEngine : public Engine { Common::SeekableReadStream *_voiceStream[MAX_SAMPLES]; Audio::SoundHandle _soundHandle[MAX_SAMPLES]; - Animation *_zoom; + //Animation *_zoom; Common::Array _pscrList; Common::Array _mobList; Common::Array _objList; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 9c915ca6bcd7..944de69c29d7 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1235,6 +1235,7 @@ void Interpreter::O_DISABLEDIALOGOPT() { void Interpreter::O_SHOWDIALOGBOX() { uint16 box = readScriptFlagValue(); debugInterpreter("O_SHOWDIALOGBOX box %d", box); + _vm->createDialogBox(_vm->_dialogBoxList[box]); } void Interpreter::O_STOPSAMPLE() { From 85628b293999f71fb8918096a273ba63651a9152 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 16 Jun 2014 22:06:53 +0200 Subject: [PATCH 181/374] PRINCE: O_INITDIALOG(), O_SHOWDIALOGBOX() update --- engines/prince/script.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 944de69c29d7..c559d3f54c96 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1220,6 +1220,14 @@ void Interpreter::O_SUBSTRING() { void Interpreter::O_INITDIALOG() { debugInterpreter("O_INITDIALOG"); + for (uint i = 0; i < _vm->_dialogBoxList.size(); i++) { + _vm->_dialogBoxList[i].clear(); + } + _vm->_dialogBoxList.clear(); + + // cut string to dialogs + // cut dialogs to nr and lines + // push them to dialogBoxList } void Interpreter::O_ENABLEDIALOGOPT() { @@ -1236,6 +1244,13 @@ void Interpreter::O_SHOWDIALOGBOX() { uint16 box = readScriptFlagValue(); debugInterpreter("O_SHOWDIALOGBOX box %d", box); _vm->createDialogBox(_vm->_dialogBoxList[box]); + int dialogLines = _vm->_dialogBoxList[box].size(); + _flags->setFlagValue(Flags::DIALINES, dialogLines); + if (dialogLines != 0) { + _vm->changeCursor(1); + _vm->runDialog(); + _vm->changeCursor(0); + } } void Interpreter::O_STOPSAMPLE() { From e18502a02e8a49d8e9a52735a924296b556edf9a Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 17 Jun 2014 18:24:56 +0200 Subject: [PATCH 182/374] PRINCE: Dialog frame drawing --- engines/prince/prince.cpp | 94 +++++++++++++++++++++++++++++++++------ engines/prince/prince.h | 6 ++- 2 files changed, 86 insertions(+), 14 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 2d08aa11159c..a425510cefbb 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -86,7 +86,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _invCurInside(false), _optionsFlag(false), _optionEnabled(0), _invExamY(120), _optionsMob(0), _currentPointerNumber(1), _selectedMob(0), _selectedItem(0), _selectedMode(0), _optionsWidth(210), _optionsHeight(170), _invOptionsWidth(210), _invOptionsHeight(130), _optionsStep(20), - _invOptionsStep(20), _optionsNumber(7), _invOptionsNumber(5), _optionsColor1(0xFF00EC), _optionsColor2(0xFF00FC) { + _invOptionsStep(20), _optionsNumber(7), _invOptionsNumber(5), _optionsColor1(0xFF00EC), _optionsColor2(0xFF00FC), + _dialogWidth(600), _dialogHeight(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -447,8 +448,8 @@ void PrinceEngine::makeInvCursor(int itemNr) { int itemW = itemSurface->w; int itemH = itemSurface->h; - int cur2W = cur1W + itemW / 2; - int cur2H = cur1H + itemH / 2; + //int cur2W = cur1W + itemW / 2; + //int cur2H = cur1H + itemH / 2; //TODO } @@ -694,10 +695,11 @@ void PrinceEngine::keyHandler(Common::Event event) { debugEngine("RIGHT"); break; case Common::KEYCODE_1: - if(_mainHero->_state > 0) { - _mainHero->_state--; - } - debugEngine("%d", _mainHero->_state); + //if(_mainHero->_state > 0) { + // _mainHero->_state--; + //} + //debugEngine("%d", _mainHero->_state); + testDialog(); break; case Common::KEYCODE_2: _mainHero->_state++; @@ -1369,7 +1371,6 @@ void PrinceEngine::drawScreen() { } getDebugger()->onFrame(); - _graph->update(_graph->_frontScreen); } else { displayInventory(); @@ -1937,16 +1938,82 @@ void PrinceEngine::displayInventory() { void PrinceEngine::createDialogBox(Common::Array &dialogData) { int lineSpace = 10; - int dBoxWidth = 600; - - int dialogLines = 0; + _dialogHeight = (_font->getFontHeight() + lineSpace) * dialogData.size() + lineSpace; - int nrOfDialogLines = 0; // ebp - int nrOfSentence = 0; // edx + _dialogImage = new Graphics::Surface(); + _dialogImage->create(_dialogWidth, _dialogHeight, Graphics::PixelFormat::createFormatCLUT8()); + Common::Rect dBoxRect(0, 0, _dialogWidth, _dialogHeight); + _dialogImage->fillRect(dBoxRect, _graph->kShadowColor); } void PrinceEngine::runDialog() { + while (!shouldQuit()) { + + drawScreen(); // without some of things - check it + + int dialogX = (640 - _dialogWidth) / 2; + int dialogY = 460 - _dialogHeight; + _graph->drawAsShadowSurface(_graph->_frontScreen, dialogX, dialogY, _dialogImage, _graph->_shadowTable50); + + 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_KEYUP: + break; + case Common::EVENT_MOUSEMOVE: + break; + case Common::EVENT_LBUTTONDOWN: + break; + case Common::EVENT_RBUTTONDOWN: + break; + case Common::EVENT_LBUTTONUP: + break; + case Common::EVENT_RBUTTONUP: + break; + case Common::EVENT_QUIT: + break; + default: + break; + } + } + + if (shouldQuit()) + return; + + getDebugger()->onFrame(); + _graph->update(_graph->_frontScreen); + pause(); + } + _dialogImage->free(); + delete _dialogImage; +} + +// Debug +void PrinceEngine::testDialog() { + Common::Array tempDialogBox; + DialogLine tempDialogLine; + + for (int i = 0; i < 4; i++) { + tempDialogLine._nr = i; + tempDialogLine._line = ""; + tempDialogLine._line += "This is " + i; + tempDialogLine._line += " dialog line."; + tempDialogBox.push_back(tempDialogLine); + } + _dialogBoxList.push_back(tempDialogBox); + + //dialogBox 0 - test: + createDialogBox(_dialogBoxList[0]); + if (_dialogBoxList[0].size() != 0) { + changeCursor(1); + runDialog(); + changeCursor(0); + } } void PrinceEngine::mainLoop() { @@ -1995,6 +2062,7 @@ void PrinceEngine::mainLoop() { _interpreter->step(); drawScreen(); + _graph->update(_graph->_frontScreen); // Calculate the frame delay based off a desired frame time int delay = 1000/15 - int32(_system->getMillis() - currentTime); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 9f4dd57f03e9..d98bfacc56f9 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -346,8 +346,13 @@ class PrinceEngine : public Engine { void inventoryLeftMouseButton(); void inventoryRightMouseButton(); + int _dialogWidth; + int _dialogHeight; + Graphics::Surface *_dialogImage; + void createDialogBox(Common::Array &dialogData); void runDialog(); + void testDialog(); int testAnimNr; int testAnimFrame; @@ -395,7 +400,6 @@ class PrinceEngine : public Engine { Common::SeekableReadStream *_voiceStream[MAX_SAMPLES]; Audio::SoundHandle _soundHandle[MAX_SAMPLES]; - //Animation *_zoom; Common::Array _pscrList; Common::Array _mobList; Common::Array _objList; From e51bbc83f32bd8441e8dd77cd9d29ef43bf859e3 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 17 Jun 2014 20:18:07 +0200 Subject: [PATCH 183/374] PRINCE: Dialog box texts drawing and highlighting --- engines/prince/prince.cpp | 50 ++++++++++++++++++++++++++++++++------- engines/prince/prince.h | 4 +++- engines/prince/script.cpp | 2 +- 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index a425510cefbb..e9847b7f0d04 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -87,7 +87,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _optionsMob(0), _currentPointerNumber(1), _selectedMob(0), _selectedItem(0), _selectedMode(0), _optionsWidth(210), _optionsHeight(170), _invOptionsWidth(210), _invOptionsHeight(130), _optionsStep(20), _invOptionsStep(20), _optionsNumber(7), _invOptionsNumber(5), _optionsColor1(0xFF00EC), _optionsColor2(0xFF00FC), - _dialogWidth(600), _dialogHeight(0) { + _dialogWidth(600), _dialogHeight(0), _dialogColor1(0xFF00DC), _dialogColor2(0xFF00DF) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -1841,7 +1841,7 @@ void PrinceEngine::checkInvOptions() { }; uint16 textW = getTextWidth(invText.c_str()); uint16 textX = _optionsX + _invOptionsWidth / 2 - textW / 2; - _font->drawString(_graph->_screenForInventory, invText, textX, textY, textW, optionsColor); + _font->drawString(_graph->_screenForInventory, invText, textX, textY, _graph->_screenForInventory->w, optionsColor); textY += _invOptionsStep; } } @@ -1946,7 +1946,7 @@ void PrinceEngine::createDialogBox(Common::Array &dialogData) { _dialogImage->fillRect(dBoxRect, _graph->kShadowColor); } -void PrinceEngine::runDialog() { +void PrinceEngine::runDialog(Common::Array &dialogData) { while (!shouldQuit()) { @@ -1956,6 +1956,36 @@ void PrinceEngine::runDialog() { int dialogY = 460 - _dialogHeight; _graph->drawAsShadowSurface(_graph->_frontScreen, dialogX, dialogY, _dialogImage, _graph->_shadowTable50); + int dialogSkipLeft = 14; + int dialogSkipUp = 10; + int lineSpace = 10; + + int dialogTextX = dialogX + dialogSkipLeft; + int dialogTextY = dialogY + dialogSkipUp; + + Common::Point mousePos = _system->getEventManager()->getMousePos(); + + int dialogSelected = -1; + + for (uint i = 0; i < dialogData.size(); i++) { + int actualColor = _dialogColor1; + + Common::Array lines; + _font->wordWrapText(dialogData[i]._line, _graph->_frontScreen->w, lines); + + Common::Rect dialogOption(dialogTextX, dialogTextY - dialogSkipUp / 2, dialogX + _dialogWidth - dialogSkipLeft, dialogTextY + lines.size() * _font->getFontHeight() + dialogSkipUp / 2 - 1); + if (dialogOption.contains(mousePos)) { + actualColor = _dialogColor2; + } + + for (uint j = 0; j < lines.size(); j++) { + Common::String dialogText = dialogData[i]._line; + _font->drawString(_graph->_frontScreen, dialogText, dialogTextX, dialogTextY, _graph->_frontScreen->w, actualColor); + dialogTextY += _font->getFontHeight(); + } + dialogTextY += lineSpace; + } + Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); while (eventMan->pollEvent(event)) { @@ -1993,25 +2023,29 @@ void PrinceEngine::runDialog() { delete _dialogImage; } -// Debug +// Test void PrinceEngine::testDialog() { Common::Array tempDialogBox; DialogLine tempDialogLine; + // dialBox 0 create: for (int i = 0; i < 4; i++) { tempDialogLine._nr = i; tempDialogLine._line = ""; - tempDialogLine._line += "This is " + i; - tempDialogLine._line += " dialog line."; tempDialogBox.push_back(tempDialogLine); } + tempDialogBox[0]._line = "Co to za miejsce?"; + tempDialogBox[1]._line = "Prosze, musi mi pan pomoc wydostac sie stad!"; + tempDialogBox[2]._line = "Tu chyba nie jest zbyt bezpiecznie, prawda?"; + tempDialogBox[3]._line = "Nie chce przeszkadzac."; + _dialogBoxList.push_back(tempDialogBox); - //dialogBox 0 - test: + //dialogBox 0 draw: createDialogBox(_dialogBoxList[0]); if (_dialogBoxList[0].size() != 0) { changeCursor(1); - runDialog(); + runDialog(_dialogBoxList[0]); changeCursor(0); } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index d98bfacc56f9..7cdd611cf950 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -348,10 +348,12 @@ class PrinceEngine : public Engine { int _dialogWidth; int _dialogHeight; + int _dialogColor1; // color for non-selected options + int _dialogColor2; // color for selected option Graphics::Surface *_dialogImage; void createDialogBox(Common::Array &dialogData); - void runDialog(); + void runDialog(Common::Array &dialogData); void testDialog(); int testAnimNr; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index c559d3f54c96..29566b7fb7c3 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1248,7 +1248,7 @@ void Interpreter::O_SHOWDIALOGBOX() { _flags->setFlagValue(Flags::DIALINES, dialogLines); if (dialogLines != 0) { _vm->changeCursor(1); - _vm->runDialog(); + _vm->runDialog(_vm->_dialogBoxList[box]); _vm->changeCursor(0); } } From 1e1d3044be4a230f8b62ebe4fbda934743bfe442 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 17 Jun 2014 20:59:38 +0200 Subject: [PATCH 184/374] PRINCE: Fix for longer lines in dialog box --- engines/prince/prince.cpp | 40 +++++++++++++++++++++++++++++---------- engines/prince/prince.h | 2 ++ 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index e9847b7f0d04..f75552d5d3c5 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -87,7 +87,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _optionsMob(0), _currentPointerNumber(1), _selectedMob(0), _selectedItem(0), _selectedMode(0), _optionsWidth(210), _optionsHeight(170), _invOptionsWidth(210), _invOptionsHeight(130), _optionsStep(20), _invOptionsStep(20), _optionsNumber(7), _invOptionsNumber(5), _optionsColor1(0xFF00EC), _optionsColor2(0xFF00FC), - _dialogWidth(600), _dialogHeight(0), _dialogColor1(0xFF00DC), _dialogColor2(0xFF00DF) { + _dialogWidth(600), _dialogHeight(0), _dialogLineSpace(10), _dialogColor1(0xFF00DC), _dialogColor2(0xFF00DF) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -1937,9 +1937,18 @@ void PrinceEngine::displayInventory() { } void PrinceEngine::createDialogBox(Common::Array &dialogData) { - int lineSpace = 10; - _dialogHeight = (_font->getFontHeight() + lineSpace) * dialogData.size() + lineSpace; + int amountOfDialogLines = 0; + int amountOfDialogOptions = dialogData.size(); + // change this to sth simpler? + Common::Array lines; + for (int i = 0; i < amountOfDialogOptions; i++) { + _font->wordWrapText(dialogData[i]._line, _graph->_frontScreen->w, lines); + amountOfDialogLines += lines.size(); + lines.clear(); + } + + _dialogHeight = _font->getFontHeight() * amountOfDialogLines + _dialogLineSpace * (amountOfDialogOptions + 1); _dialogImage = new Graphics::Surface(); _dialogImage->create(_dialogWidth, _dialogHeight, Graphics::PixelFormat::createFormatCLUT8()); Common::Rect dBoxRect(0, 0, _dialogWidth, _dialogHeight); @@ -1958,7 +1967,6 @@ void PrinceEngine::runDialog(Common::Array &dialogData) { int dialogSkipLeft = 14; int dialogSkipUp = 10; - int lineSpace = 10; int dialogTextX = dialogX + dialogSkipLeft; int dialogTextY = dialogY + dialogSkipUp; @@ -1976,14 +1984,14 @@ void PrinceEngine::runDialog(Common::Array &dialogData) { Common::Rect dialogOption(dialogTextX, dialogTextY - dialogSkipUp / 2, dialogX + _dialogWidth - dialogSkipLeft, dialogTextY + lines.size() * _font->getFontHeight() + dialogSkipUp / 2 - 1); if (dialogOption.contains(mousePos)) { actualColor = _dialogColor2; + dialogSelected = dialogData[i]._nr; } for (uint j = 0; j < lines.size(); j++) { - Common::String dialogText = dialogData[i]._line; - _font->drawString(_graph->_frontScreen, dialogText, dialogTextX, dialogTextY, _graph->_frontScreen->w, actualColor); + _font->drawString(_graph->_frontScreen, lines[j], dialogTextX, dialogTextY, _graph->_frontScreen->w, actualColor); dialogTextY += _font->getFontHeight(); } - dialogTextY += lineSpace; + dialogTextY += _dialogLineSpace; } Common::Event event; @@ -1998,6 +2006,8 @@ void PrinceEngine::runDialog(Common::Array &dialogData) { case Common::EVENT_MOUSEMOVE: break; case Common::EVENT_LBUTTONDOWN: + dialogLeftMouseButton(dialogSelected); + return; break; case Common::EVENT_RBUTTONDOWN: break; @@ -2023,21 +2033,31 @@ void PrinceEngine::runDialog(Common::Array &dialogData) { delete _dialogImage; } +void PrinceEngine::dialogLeftMouseButton(int dialogSelected) { + if (dialogSelected != -1) { + //TODO @@showa_dialoga: + } +} + // Test void PrinceEngine::testDialog() { Common::Array tempDialogBox; DialogLine tempDialogLine; + int dialogBoxSize = 6; + // dialBox 0 create: - for (int i = 0; i < 4; i++) { + for (int i = 0; i < dialogBoxSize; i++) { tempDialogLine._nr = i; tempDialogLine._line = ""; tempDialogBox.push_back(tempDialogLine); } tempDialogBox[0]._line = "Co to za miejsce?"; tempDialogBox[1]._line = "Prosze, musi mi pan pomoc wydostac sie stad!"; - tempDialogBox[2]._line = "Tu chyba nie jest zbyt bezpiecznie, prawda?"; - tempDialogBox[3]._line = "Nie chce przeszkadzac."; + tempDialogBox[2]._line = "It's very long line to check if we can draw it. \n""Like this! See, it's easy."; + tempDialogBox[3]._line = "It's very long line to check if we can draw it. \n""Like this! See, it's easy."; + tempDialogBox[4]._line = "Tu chyba nie jest zbyt bezpiecznie, prawda?"; + tempDialogBox[5]._line = "Nie chce przeszkadzac."; _dialogBoxList.push_back(tempDialogBox); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 7cdd611cf950..a9b074e85927 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -345,9 +345,11 @@ class PrinceEngine : public Engine { void rightMouseButton(); void inventoryLeftMouseButton(); void inventoryRightMouseButton(); + void dialogLeftMouseButton(int dialogSelected); int _dialogWidth; int _dialogHeight; + int _dialogLineSpace; int _dialogColor1; // color for non-selected options int _dialogColor2; // color for selected option Graphics::Surface *_dialogImage; From f00eeeda919bd636456b548c595e2062fcad37ef Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 18 Jun 2014 02:32:20 +0200 Subject: [PATCH 185/374] PRINCE: Hero talking - dialog option choosing --- engines/prince/hero.cpp | 179 +++++++++++++++++++------------------- engines/prince/prince.cpp | 77 ++++++++++++---- engines/prince/prince.h | 4 +- 3 files changed, 154 insertions(+), 106 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 3293c9c697dc..2194817fa96d 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -621,105 +621,106 @@ void Hero::rotateHero() { void Hero::showHero() { if (_visible) { - // Is he talking? - if (_talkTime == 0) { //? - // Scale of hero - selectZoom(); - switch (_state) { - case STAY: - //if(OptionsFlag == false) { - //if(OpcodePC == null) { - _boredomTime++; - if (_boredomTime == 200) { // 140 for second hero - _boredomTime = 0; - _state = BORE; - } - switch (_lastDirection) { - case LEFT: - _moveSetType = Move_SL; - break; - case RIGHT: - _moveSetType = Move_SR; - break; - case UP: - _moveSetType = Move_SU; - break; - case DOWN: - _moveSetType = Move_SD; - break; - } + if (_talkTime != 0) { + _talkTime--; + if (_talkTime == 0) { + _state = STAY; // test this + } + } + // Scale of hero + selectZoom(); + switch (_state) { + case STAY: + //if(OptionsFlag == false) { + //if(OpcodePC == null) { + _boredomTime++; + if (_boredomTime == 200) { // 140 for second hero + _boredomTime = 0; + _state = BORE; + } + switch (_lastDirection) { + case LEFT: + _moveSetType = Move_SL; break; - case TURN: - /* - if(_lastDirection == _destDirection) { - _state = STAY; - } else { - _frame = 0; - rotateHero(); - _lastDirection = _destDirection; - } - */ + case RIGHT: + _moveSetType = Move_SR; break; - case MOVE: - switch (_lastDirection) { - case LEFT: - _moveSetType = Move_ML; - break; - case RIGHT: - _moveSetType = Move_MR; - break; - case UP: - _moveSetType = Move_MU; - break; - case DOWN: - _moveSetType = Move_MD; - break; - } + case UP: + _moveSetType = Move_SU; break; - case BORE: - //if (_direction == UP) { - switch (_boreNum) { - case 0: - _moveSetType = Move_BORED1; - break; - case 1: - _moveSetType = Move_BORED2; - break; - } - if (_phase == _moveSet[_moveSetType]->getFrameCount() - 1) { - _boreNum = _vm->_randomSource.getRandomNumber(1); // rand one of two 'bored' animation - _lastDirection = DOWN; - _state = STAY; - } + case DOWN: + _moveSetType = Move_SD; + break; + } + break; + case TURN: + /* + if(_lastDirection == _destDirection) { + _state = STAY; + } else { + _frame = 0; + rotateHero(); + _lastDirection = _destDirection; + } + */ + break; + case MOVE: + switch (_lastDirection) { + case LEFT: + _moveSetType = Move_ML; break; - case SPEC: - //specialAnim(); + case RIGHT: + _moveSetType = Move_MR; break; - case TALK: - switch (_lastDirection) { - case LEFT: - _moveSetType = Move_TL; - break; - case RIGHT: - _moveSetType = Move_TR; - break; - case UP: - _moveSetType = Move_TU; - break; - case DOWN: - _moveSetType = Move_TD; - break; - } + case UP: + _moveSetType = Move_MU; break; - case TRAN: + case DOWN: + _moveSetType = Move_MD; break; - case RUN: + } + break; + case BORE: + //if (_direction == UP) { + switch (_boreNum) { + case 0: + _moveSetType = Move_BORED1; break; - case DMOVE: + case 1: + _moveSetType = Move_BORED2; break; } - } else { - _talkTime--; // o ile? + if (_phase == _moveSet[_moveSetType]->getFrameCount() - 1) { + _boreNum = _vm->_randomSource.getRandomNumber(1); // rand one of two 'bored' animation + _lastDirection = DOWN; + _state = STAY; + } + break; + case SPEC: + //specialAnim(); + break; + case TALK: + switch (_lastDirection) { + case LEFT: + _moveSetType = Move_TL; + break; + case RIGHT: + _moveSetType = Move_TR; + break; + case UP: + _moveSetType = Move_TU; + break; + case DOWN: + _moveSetType = Move_TD; + break; + } + break; + case TRAN: + break; + case RUN: + break; + case DMOVE: + break; } showHeroAnimFrame(); } else { diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index f75552d5d3c5..ab3c294cae63 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -710,13 +710,13 @@ void PrinceEngine::keyHandler(Common::Event event) { break; case Common::KEYCODE_k: _mainHero->_middleY += 5; - addInvObj(); + //addInvObj(); break; case Common::KEYCODE_j: _mainHero->_middleX -= 5; - _flags->setFlagValue(Flags::CURSEBLINK, 1); - addInvObj(); - _flags->setFlagValue(Flags::CURSEBLINK, 0); + //_flags->setFlagValue(Flags::CURSEBLINK, 1); + //addInvObj(); + //_flags->setFlagValue(Flags::CURSEBLINK, 0); break; case Common::KEYCODE_l: _mainHero->_middleX += 5; @@ -843,6 +843,18 @@ void PrinceEngine::printAt(uint32 slot, uint8 color, const char *s, uint16 x, ui text._color = color; } +int PrinceEngine::calcText(const char *s) { + int lines = 1; + while (*s) { + if (*s == '\n') { + lines++; + } + s++; + } + return lines; + //time = lines * 30 +} + uint32 PrinceEngine::getTextWidth(const char *s) { uint16 textW = 0; while (*s) { @@ -855,21 +867,20 @@ uint32 PrinceEngine::getTextWidth(const char *s) { void PrinceEngine::showTexts(Graphics::Surface *screen) { for (uint32 slot = 0; slot < MAXTEXTS; ++slot) { Text& text = _textSlots[slot]; - if (!text._str && !text._time) + if (!text._str && !text._time) { continue; + } Common::Array lines; _font->wordWrapText(text._str, _graph->_frontScreen->w, lines); - for (uint8 i = 0; i < lines.size(); ++i) { - _font->drawString( - screen, - lines[i], - text._x - getTextWidth(lines[i].c_str())/2, - text._y - (lines.size() - i) * (_font->getFontHeight()), - screen->w, - text._color - ); + for (uint8 i = 0; i < lines.size(); i++) { + int x = text._x - getTextWidth(lines[i].c_str()) / 2; + int y = text._y - (lines.size() - i) * (_font->getFontHeight()); + if (y < 0) { + y = 0; + } + _font->drawString(screen, lines[i], x, y, screen->w, text._color); } text._time--; @@ -1974,6 +1985,7 @@ void PrinceEngine::runDialog(Common::Array &dialogData) { Common::Point mousePos = _system->getEventManager()->getMousePos(); int dialogSelected = -1; + int dialogSelectedText = -1; for (uint i = 0; i < dialogData.size(); i++) { int actualColor = _dialogColor1; @@ -1985,6 +1997,7 @@ void PrinceEngine::runDialog(Common::Array &dialogData) { if (dialogOption.contains(mousePos)) { actualColor = _dialogColor2; dialogSelected = dialogData[i]._nr; + dialogSelectedText = i; } for (uint j = 0; j < lines.size(); j++) { @@ -2006,7 +2019,7 @@ void PrinceEngine::runDialog(Common::Array &dialogData) { case Common::EVENT_MOUSEMOVE: break; case Common::EVENT_LBUTTONDOWN: - dialogLeftMouseButton(dialogSelected); + dialogLeftMouseButton(dialogSelected, dialogData[dialogSelectedText]._line.c_str()); return; break; case Common::EVENT_RBUTTONDOWN: @@ -2033,12 +2046,44 @@ void PrinceEngine::runDialog(Common::Array &dialogData) { delete _dialogImage; } -void PrinceEngine::dialogLeftMouseButton(int dialogSelected) { +void PrinceEngine::dialogLeftMouseButton(int dialogSelected, const char *s) { if (dialogSelected != -1) { //TODO @@showa_dialoga: + talkHero(0, s); } } +void PrinceEngine::talkHero(int slot, const char *s) { + // heroSlot = textSlot + + Text &text = _textSlots[slot]; + int lines = calcText(s); + int time = lines * 30; + int x, y; + //int textSkip = -2; // global? + + if (slot == 0) { + text._color = 0xFF00DC; // test this + _mainHero->_state = Hero::TALK; + _mainHero->_talkTime = time; + x = _mainHero->_middleX; + y = _mainHero->_middleY - _mainHero->_scaledFrameYSize - 10; + //y -= (_font->getFontHeight() + textSkip) * lines; // need this? + } else { + //text._color = _secondHero->color; + text._color = 0xFF00DC; // test this ! + _secondHero->_state = Hero::TALK; + _secondHero->_talkTime = time; + x = _secondHero->_middleX; + y = _secondHero->_middleY - _secondHero->_currHeight - 10; // set currHeight + //y -= (_font->getFontHeight() + textSkip) * lines; // need this? + } + text._time = time; // changed by SETSPECVOICE? + text._str = s; + text._x = x; + text._y = y; +} + // Test void PrinceEngine::testDialog() { Common::Array tempDialogBox; diff --git a/engines/prince/prince.h b/engines/prince/prince.h index a9b074e85927..5e04eecb1c45 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -249,6 +249,7 @@ class PrinceEngine : public Engine { void changeCursor(uint16 curId); void printAt(uint32 slot, uint8 color, const char *s, uint16 x, uint16 y); + int calcText(const char *s); static const uint8 MAXTEXTS = 32; Text _textSlots[MAXTEXTS]; @@ -345,7 +346,7 @@ class PrinceEngine : public Engine { void rightMouseButton(); void inventoryLeftMouseButton(); void inventoryRightMouseButton(); - void dialogLeftMouseButton(int dialogSelected); + void dialogLeftMouseButton(int dialogSelected, const char *s); int _dialogWidth; int _dialogHeight; @@ -356,6 +357,7 @@ class PrinceEngine : public Engine { void createDialogBox(Common::Array &dialogData); void runDialog(Common::Array &dialogData); + void talkHero(int slot, const char *s); void testDialog(); int testAnimNr; From 78a2105bbce3b6ef4690777fcfbcc545170192d7 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 18 Jun 2014 13:57:55 +0200 Subject: [PATCH 186/374] PRINCE: showTexts(), talkHero() update --- engines/prince/prince.cpp | 44 ++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index ab3c294cae63..4f3be5f98e0a 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -874,9 +874,38 @@ void PrinceEngine::showTexts(Graphics::Surface *screen) { Common::Array lines; _font->wordWrapText(text._str, _graph->_frontScreen->w, lines); + int wideLine = 0; + for (uint8 i = 0; i < lines.size(); i++) { + int textLen = getTextWidth(lines[i].c_str()); + if (textLen > wideLine) { + wideLine = textLen; + } + } + + int leftBorderText = 6; + /* + if (text._x + wideLine / 2 > _picWindowX + kNormalWidth - leftBorderText) { + text._x = _picWindowX + kNormalWidth - leftBorderText - wideLine / 2; + } + + if (text._x - wideLine / 2 < _picWindowX + leftBorderText) { + text._x = _picWindowX + leftBorderText + wideLine / 2; + } + */ + if (text._x + wideLine / 2 > kNormalWidth - leftBorderText) { + text._x = kNormalWidth - leftBorderText - wideLine / 2; + } + + if (text._x - wideLine / 2 < leftBorderText) { + text._x = leftBorderText + wideLine / 2; + } + for (uint8 i = 0; i < lines.size(); i++) { int x = text._x - getTextWidth(lines[i].c_str()) / 2; int y = text._y - (lines.size() - i) * (_font->getFontHeight()); + if (x < 0) { + x = 0; + } if (y < 0) { y = 0; } @@ -2055,28 +2084,23 @@ void PrinceEngine::dialogLeftMouseButton(int dialogSelected, const char *s) { void PrinceEngine::talkHero(int slot, const char *s) { // heroSlot = textSlot - Text &text = _textSlots[slot]; int lines = calcText(s); int time = lines * 30; int x, y; - //int textSkip = -2; // global? if (slot == 0) { text._color = 0xFF00DC; // test this _mainHero->_state = Hero::TALK; _mainHero->_talkTime = time; - x = _mainHero->_middleX; + x = _mainHero->_middleX - _picWindowX; y = _mainHero->_middleY - _mainHero->_scaledFrameYSize - 10; - //y -= (_font->getFontHeight() + textSkip) * lines; // need this? } else { - //text._color = _secondHero->color; text._color = 0xFF00DC; // test this ! _secondHero->_state = Hero::TALK; _secondHero->_talkTime = time; - x = _secondHero->_middleX; - y = _secondHero->_middleY - _secondHero->_currHeight - 10; // set currHeight - //y -= (_font->getFontHeight() + textSkip) * lines; // need this? + x = _secondHero->_middleX - _picWindowX; + y = _secondHero->_middleY - _secondHero->_scaledFrameYSize - 10; } text._time = time; // changed by SETSPECVOICE? text._str = s; @@ -2099,8 +2123,8 @@ void PrinceEngine::testDialog() { } tempDialogBox[0]._line = "Co to za miejsce?"; tempDialogBox[1]._line = "Prosze, musi mi pan pomoc wydostac sie stad!"; - tempDialogBox[2]._line = "It's very long line to check if we can draw it. \n""Like this! See, it's easy."; - tempDialogBox[3]._line = "It's very long line to check if we can draw it. \n""Like this! See, it's easy."; + tempDialogBox[2]._line = "Sam Adanor Wszobrody odmowil mi trzydziestego\n""siodmego kubeczka krasnoludzkiego spirytusu."; + tempDialogBox[3]._line = "A co do twoich czarodziejskich sztuczek, to\n""jak mowi stare przyslowie, nie chwal sie\n""dokonaniami dnia wczorajszego..."; tempDialogBox[4]._line = "Tu chyba nie jest zbyt bezpiecznie, prawda?"; tempDialogBox[5]._line = "Nie chce przeszkadzac."; From 82bc00781962b3c4e72129052198c3c27d5e4f73 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 19 Jun 2014 00:00:44 +0200 Subject: [PATCH 187/374] PRINCE: Dialog box update; LMB outside of inventory beginning --- engines/prince/prince.cpp | 60 +++++++++++++++++++++++++++++---------- engines/prince/prince.h | 1 + engines/prince/script.cpp | 18 ++++++++++++ engines/prince/script.h | 5 +++- 4 files changed, 68 insertions(+), 16 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 4f3be5f98e0a..f7cc1c70653d 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -32,6 +32,7 @@ #include "common/keyboard.h" #include "common/substream.h" #include "common/str.h" +#include "common/str-array.h" #include "graphics/cursorman.h" #include "graphics/surface.h" @@ -86,8 +87,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _invCurInside(false), _optionsFlag(false), _optionEnabled(0), _invExamY(120), _optionsMob(0), _currentPointerNumber(1), _selectedMob(0), _selectedItem(0), _selectedMode(0), _optionsWidth(210), _optionsHeight(170), _invOptionsWidth(210), _invOptionsHeight(130), _optionsStep(20), - _invOptionsStep(20), _optionsNumber(7), _invOptionsNumber(5), _optionsColor1(0xFF00EC), _optionsColor2(0xFF00FC), - _dialogWidth(600), _dialogHeight(0), _dialogLineSpace(10), _dialogColor1(0xFF00DC), _dialogColor2(0xFF00DF) { + _invOptionsStep(20), _optionsNumber(7), _invOptionsNumber(5), _optionsColor1(236), _optionsColor2(252), + _dialogWidth(600), _dialogHeight(0), _dialogLineSpace(10), _dialogColor1(220), _dialogColor2(223) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -1645,6 +1646,38 @@ void PrinceEngine::drawInvItems() { } } +void PrinceEngine::leftMouseButton() { + if (_optionsFlag) { + if (_optionEnabled < _optionsNumber) { + _optionsFlag = 0; + } else { + return; + } + } else { + _optionsMob = _selectedMob; + if (!_selectedMob) { + // @@walkto + } + } + // edi = optionsMob + // ebp = optionsMobNumber + // selectedMob = optionsMobNumber + if (_currentPointerNumber != 2) { + //skip_use_code + } + if (_selectedMode != 0) { + //give_item + } + + if (_room->_itemUse == 0) { + //standard_useitem + //_script->_scriptInfo.stdUse; + } else { + debug("selectedMob: %d", _selectedMob); + _script->scanMobItemEvents(_mobList[_selectedMob]._mask, _room->_itemUse); + } +} + void PrinceEngine::rightMouseButton() { if (_currentPointerNumber < 2) { enableOptions(); @@ -1980,12 +2013,8 @@ void PrinceEngine::createDialogBox(Common::Array &dialogData) { int amountOfDialogLines = 0; int amountOfDialogOptions = dialogData.size(); - // change this to sth simpler? - Common::Array lines; for (int i = 0; i < amountOfDialogOptions; i++) { - _font->wordWrapText(dialogData[i]._line, _graph->_frontScreen->w, lines); - amountOfDialogLines += lines.size(); - lines.clear(); + amountOfDialogLines += calcText(dialogData[i]._line.c_str()); } _dialogHeight = _font->getFontHeight() * amountOfDialogLines + _dialogLineSpace * (amountOfDialogOptions + 1); @@ -2048,8 +2077,10 @@ void PrinceEngine::runDialog(Common::Array &dialogData) { case Common::EVENT_MOUSEMOVE: break; case Common::EVENT_LBUTTONDOWN: - dialogLeftMouseButton(dialogSelected, dialogData[dialogSelectedText]._line.c_str()); - return; + if (dialogSelected != -1) { + dialogLeftMouseButton(dialogSelected, dialogData[dialogSelectedText]._line.c_str()); + return; + } break; case Common::EVENT_RBUTTONDOWN: break; @@ -2076,10 +2107,8 @@ void PrinceEngine::runDialog(Common::Array &dialogData) { } void PrinceEngine::dialogLeftMouseButton(int dialogSelected, const char *s) { - if (dialogSelected != -1) { - //TODO @@showa_dialoga: - talkHero(0, s); - } + //TODO @@showa_dialoga: + talkHero(0, s); } void PrinceEngine::talkHero(int slot, const char *s) { @@ -2090,13 +2119,13 @@ void PrinceEngine::talkHero(int slot, const char *s) { int x, y; if (slot == 0) { - text._color = 0xFF00DC; // test this + text._color = 220; // test this _mainHero->_state = Hero::TALK; _mainHero->_talkTime = time; x = _mainHero->_middleX - _picWindowX; y = _mainHero->_middleY - _mainHero->_scaledFrameYSize - 10; } else { - text._color = 0xFF00DC; // test this ! + text._color = 220; // test this ! _secondHero->_state = Hero::TALK; _secondHero->_talkTime = time; x = _secondHero->_middleX - _picWindowX; @@ -2158,6 +2187,7 @@ void PrinceEngine::mainLoop() { case Common::EVENT_MOUSEMOVE: break; case Common::EVENT_LBUTTONDOWN: + leftMouseButton(); break; case Common::EVENT_RBUTTONDOWN: rightMouseButton(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 5e04eecb1c45..4ffedaed6fb4 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -343,6 +343,7 @@ class PrinceEngine : public Engine { void checkOptions(); void checkInvOptions(); + void leftMouseButton(); void rightMouseButton(); void inventoryLeftMouseButton(); void inventoryRightMouseButton(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 29566b7fb7c3..02234adcfadd 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -242,6 +242,23 @@ int Script::scanInvObjUseEvents(int mobMask) { return -1; // or sth else? } +int Script::scanMobItemEvents(int mobMask, int roomEventOffset) { + debug("mobMask: %d", mobMask); + RE tempRE; + int i = 0; + do { + tempRE._mob = (int)READ_UINT16(&_data[roomEventOffset + i * 6]); + debug("mob: %d", tempRE._mob); + tempRE._code = (int)READ_UINT32(&_data[roomEventOffset + i * 6 + 2]); + debug("code: %d", tempRE._code); + if (tempRE._mob == mobMask) { + return tempRE._code; + } + i++; + } while (tempRE._mob != -1); //?? || i <= 1 or without this (no items there) + return -1; // or sth else? +} + void Script::installSingleBackAnim(Common::Array &_backanimList, int offset) { BackgroundAnim newBackgroundAnim; @@ -1003,6 +1020,7 @@ void Interpreter::O_CHECKINV() { void Interpreter::O_TALKHERO() { uint16 hero = readScriptFlagValue(); debugInterpreter("O_TALKHERO hero %d", hero); + _vm->talkHero(hero, (const char *)_string); } void Interpreter::O_WAITTEXT() { diff --git a/engines/prince/script.h b/engines/prince/script.h index d53f95185926..e7e444de133b 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -120,6 +120,8 @@ class Script { int goTester; }; + ScriptInfo _scriptInfo; + bool loadFromStream(Common::SeekableReadStream &stream); template @@ -129,6 +131,7 @@ class Script { } uint32 getStartGameOffset(); + uint32 getStdUseItem(); int16 getLightX(int locationNr); int16 getLightY(int locationNr); int32 getShadowScale(int locationNr); @@ -139,6 +142,7 @@ class Script { int scanInvObjExamEvents(int mobMask); int scanInvObjUseEvents(int mobMask); + int scanMobItemEvents(int mobMask, int roomEventOffset); const char *getString(uint32 offset) { return (const char *)(&_data[offset]); @@ -149,7 +153,6 @@ class Script { uint8 *_data; uint32 _dataSize; Common::Array _roomList; - ScriptInfo _scriptInfo; }; class InterpreterFlags { From 306c234eb79798234dc9294cf06bcf175271a8f6 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 19 Jun 2014 00:05:54 +0200 Subject: [PATCH 188/374] PRINCE: moveSet - names change --- engines/prince/hero.cpp | 52 ++++++++++++++++++++--------------------- engines/prince/hero.h | 52 ++++++++++++++++++++--------------------- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 2194817fa96d..eadfd899b68e 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -567,52 +567,52 @@ void Hero::rotateHero() { case LEFT: switch (_destDirection) { case RIGHT: - _moveSetType = Move_MLR; + _moveSetType = kMove_MLR; break; case UP: - _moveSetType = Move_MLU; + _moveSetType = kMove_MLU; break; case DOWN: - _moveSetType = Move_MLD; + _moveSetType = kMove_MLD; break; } break; case RIGHT: switch (_destDirection) { case LEFT: - _moveSetType = Move_MRL; + _moveSetType = kMove_MRL; break; case UP: - _moveSetType = Move_MRU; + _moveSetType = kMove_MRU; break; case DOWN: - _moveSetType = Move_MRD; + _moveSetType = kMove_MRD; break; } break; case UP: switch (_destDirection) { case LEFT: - _moveSetType = Move_MUL; + _moveSetType = kMove_MUL; break; case RIGHT: - _moveSetType = Move_MUR; + _moveSetType = kMove_MUR; break; case DOWN: - _moveSetType = Move_MUD; + _moveSetType = kMove_MUD; break; } break; case DOWN: switch (_destDirection) { case LEFT: - _moveSetType = Move_MDL; + _moveSetType = kMove_MDL; break; case RIGHT: - _moveSetType = Move_MDR; + _moveSetType = kMove_MDR; break; case UP: - _moveSetType = Move_MDU; + _moveSetType = kMove_MDU; break; } break; @@ -640,16 +640,16 @@ void Hero::showHero() { } switch (_lastDirection) { case LEFT: - _moveSetType = Move_SL; + _moveSetType = kMove_SL; break; case RIGHT: - _moveSetType = Move_SR; + _moveSetType = kMove_SR; break; case UP: - _moveSetType = Move_SU; + _moveSetType = kMove_SU; break; case DOWN: - _moveSetType = Move_SD; + _moveSetType = kMove_SD; break; } break; @@ -667,16 +667,16 @@ void Hero::showHero() { case MOVE: switch (_lastDirection) { case LEFT: - _moveSetType = Move_ML; + _moveSetType = kMove_ML; break; case RIGHT: - _moveSetType = Move_MR; + _moveSetType = kMove_MR; break; case UP: - _moveSetType = Move_MU; + _moveSetType = kMove_MU; break; case DOWN: - _moveSetType = Move_MD; + _moveSetType = kMove_MD; break; } break; @@ -684,10 +684,10 @@ void Hero::showHero() { //if (_direction == UP) { switch (_boreNum) { case 0: - _moveSetType = Move_BORED1; + _moveSetType = kMove_BORED1; break; case 1: - _moveSetType = Move_BORED2; + _moveSetType = kMove_BORED2; break; } if (_phase == _moveSet[_moveSetType]->getFrameCount() - 1) { @@ -702,16 +702,16 @@ void Hero::showHero() { case TALK: switch (_lastDirection) { case LEFT: - _moveSetType = Move_TL; + _moveSetType = kMove_TL; break; case RIGHT: - _moveSetType = Move_TR; + _moveSetType = kMove_TR; break; case UP: - _moveSetType = Move_TU; + _moveSetType = kMove_TU; break; case DOWN: - _moveSetType = Move_TD; + _moveSetType = kMove_TD; break; } break; diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 31ffac3b6a58..3db21816532f 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -71,32 +71,32 @@ class Hero { }; enum MoveSet { - Move_SL, - Move_SR, - Move_SU, - Move_SD, - Move_ML, - Move_MR, - Move_MU, - Move_MD, - Move_TL, - Move_TR, - Move_TU, - Move_TD, - Move_MLU, - Move_MLD, - Move_MLR, - Move_MRU, - Move_MRD, - Move_MRL, - Move_MUL, - Move_MUR, - Move_MUD, - Move_MDL, - Move_MDR, - Move_MDU, - Move_BORED1, - Move_BORED2 + kMove_SL, + kMove_SR, + kMove_SU, + kMove_SD, + kMove_ML, + kMove_MR, + kMove_MU, + kMove_MD, + kMove_TL, + kMove_TR, + kMove_TU, + kMove_TD, + kMove_MLU, + kMove_MLD, + kMove_MLR, + kMove_MRU, + kMove_MRD, + kMove_MRL, + kMove_MUL, + kMove_MUR, + kMove_MUD, + kMove_MDL, + kMove_MDR, + kMove_MDU, + kMove_BORED1, + kMove_BORED2 }; Hero(PrinceEngine *vm, GraphicsMan *graph); From 25f51bfb8223044a6cb7766a8ab361106b9923fc Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 19 Jun 2014 01:08:38 +0200 Subject: [PATCH 189/374] PRINCE: scanMobEvents() --- engines/prince/prince.cpp | 8 ++---- engines/prince/script.cpp | 58 ++++++++------------------------------- engines/prince/script.h | 5 +--- 3 files changed, 15 insertions(+), 56 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index f7cc1c70653d..bda91af137c9 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -32,7 +32,6 @@ #include "common/keyboard.h" #include "common/substream.h" #include "common/str.h" -#include "common/str-array.h" #include "graphics/cursorman.h" #include "graphics/surface.h" @@ -1674,7 +1673,7 @@ void PrinceEngine::leftMouseButton() { //_script->_scriptInfo.stdUse; } else { debug("selectedMob: %d", _selectedMob); - _script->scanMobItemEvents(_mobList[_selectedMob]._mask, _room->_itemUse); + _script->scanMobEvents(_mobList[_selectedMob]._mask, _room->_itemUse); } } @@ -1715,7 +1714,6 @@ void PrinceEngine::inventoryLeftMouseButton() { } else { if (_selectedMob != 0) { if (_currentPointerNumber != 2) { - //if (_selectedMob != 29) { if (_invMobList[_selectedMob - 1]._mask != 29) { _optionEnabled = 0; } else { @@ -1733,7 +1731,7 @@ void PrinceEngine::inventoryLeftMouseButton() { } //do_option if (_optionEnabled == 0) { - int invObjExamEvent = _script->scanInvObjExamEvents(_selectedMob); // test this + int invObjExamEvent = _script->scanMobEvents(_selectedMob, _script->_scriptInfo.invObjExam); if (invObjExamEvent == -1) { // do_standard printAt(0, 216, _invMobList[_selectedMob - 1]._examText.c_str(), kNormalWidth / 2, _invExamY); @@ -1753,7 +1751,7 @@ void PrinceEngine::inventoryLeftMouseButton() { } } else if (_optionEnabled == 1) { // not_examine - int invObjUse = _script->scanInvObjUseEvents(_selectedMob); // test this + int invObjUse = _script->scanMobEvents(_selectedMob, _script->_scriptInfo.invObjUse); if (invObjUse == -1) { // do_standard_use _selectedMode = 0; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 02234adcfadd..5c81ee682c69 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -205,58 +205,22 @@ uint8 *Script::getRoomOffset(int locationNr) { return &_data[_scriptInfo.rooms + locationNr * 64]; } -struct RE { - int16 _mob; // number of Mob, -1 for end of list - int32 _code; // offset of code in script -}; - -int Script::scanInvObjExamEvents(int mobMask) { - RE tempRE; - int i = 0; - do { - tempRE._mob = (int)READ_UINT16(&_data[_scriptInfo.invObjExam + i * 6]); - debug("mob: %d", tempRE._mob); - tempRE._code = (int)READ_UINT32(&_data[_scriptInfo.invObjExam + i * 6 + 2]); - debug("code: %d", tempRE._code); - if (tempRE._mob == mobMask) { - return tempRE._code; - } - i++; - } while (tempRE._mob != -1); //?? || i <= 1 or without this (no items there) - return -1; // or sth else? -} - -int Script::scanInvObjUseEvents(int mobMask) { - RE tempRE; - int i = 0; - do { - tempRE._mob = (int)READ_UINT16(&_data[_scriptInfo.invObjUse + i * 6]); - debug("mob: %d", tempRE._mob); - tempRE._code = (int)READ_UINT32(&_data[_scriptInfo.invObjUse + i * 6 + 2]); - debug("code: %d", tempRE._code); - if (tempRE._mob == mobMask) { - return tempRE._code; - } - i++; - } while (tempRE._mob != -1); //?? || i <= 1 or without this (no items there) - return -1; // or sth else? -} - -int Script::scanMobItemEvents(int mobMask, int roomEventOffset) { +int Script::scanMobEvents(int mobMask, int dataEventOffset) { debug("mobMask: %d", mobMask); - RE tempRE; int i = 0; + int16 mob; + int32 code; do { - tempRE._mob = (int)READ_UINT16(&_data[roomEventOffset + i * 6]); - debug("mob: %d", tempRE._mob); - tempRE._code = (int)READ_UINT32(&_data[roomEventOffset + i * 6 + 2]); - debug("code: %d", tempRE._code); - if (tempRE._mob == mobMask) { - return tempRE._code; + mob = (int)READ_UINT16(&_data[dataEventOffset + i * 6]); + debug("mob: %d", mob); + code = (int)READ_UINT32(&_data[dataEventOffset + i * 6 + 2]); + debug("code: %d", code); + if (mob == mobMask) { + return code; } i++; - } while (tempRE._mob != -1); //?? || i <= 1 or without this (no items there) - return -1; // or sth else? + } while (mob != -1); + return -1; } void Script::installSingleBackAnim(Common::Array &_backanimList, int offset) { diff --git a/engines/prince/script.h b/engines/prince/script.h index e7e444de133b..489647ad914d 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -131,7 +131,6 @@ class Script { } uint32 getStartGameOffset(); - uint32 getStdUseItem(); int16 getLightX(int locationNr); int16 getLightY(int locationNr); int32 getShadowScale(int locationNr); @@ -140,9 +139,7 @@ class Script { void installSingleBackAnim(Common::Array &_backanimList, int offset); bool loadAllMasks(Common::Array &maskList, int offset); - int scanInvObjExamEvents(int mobMask); - int scanInvObjUseEvents(int mobMask); - int scanMobItemEvents(int mobMask, int roomEventOffset); + int scanMobEvents(int mobMask, int dataEventOffset); const char *getString(uint32 offset) { return (const char *)(&_data[offset]); From daf91dcf74e63e7f38ce2d794cf51f36e52387dd Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 19 Jun 2014 14:53:56 +0200 Subject: [PATCH 190/374] PRINCE: Inventory LMB update, VariaTxt::getString fix --- engines/prince/prince.cpp | 54 +++++++++++++++++++++++++------------ engines/prince/script.cpp | 29 +++++++++++++++++--- engines/prince/script.h | 1 + engines/prince/variatxt.cpp | 8 ++---- 4 files changed, 66 insertions(+), 26 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index bda91af137c9..ae07bebfad0e 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -883,15 +883,6 @@ void PrinceEngine::showTexts(Graphics::Surface *screen) { } int leftBorderText = 6; - /* - if (text._x + wideLine / 2 > _picWindowX + kNormalWidth - leftBorderText) { - text._x = _picWindowX + kNormalWidth - leftBorderText - wideLine / 2; - } - - if (text._x - wideLine / 2 < _picWindowX + leftBorderText) { - text._x = _picWindowX + leftBorderText + wideLine / 2; - } - */ if (text._x + wideLine / 2 > kNormalWidth - leftBorderText) { text._x = kNormalWidth - leftBorderText - wideLine / 2; } @@ -902,7 +893,7 @@ void PrinceEngine::showTexts(Graphics::Surface *screen) { for (uint8 i = 0; i < lines.size(); i++) { int x = text._x - getTextWidth(lines[i].c_str()) / 2; - int y = text._y - (lines.size() - i) * (_font->getFontHeight()); + int y = text._y - (lines.size() - i) * (_font->getFontHeight()); // to fix if (x < 0) { x = 0; } @@ -1673,7 +1664,10 @@ void PrinceEngine::leftMouseButton() { //_script->_scriptInfo.stdUse; } else { debug("selectedMob: %d", _selectedMob); - _script->scanMobEvents(_mobList[_selectedMob]._mask, _room->_itemUse); + int mobEvent = _script->scanMobEventsWithItem(_mobList[_selectedMob - 1]._mask, _room->_itemUse, _selectedItem); + if (mobEvent == -1) { + + } } } @@ -1723,7 +1717,20 @@ void PrinceEngine::inventoryLeftMouseButton() { //do_option } else { //use_item_on_item + int invObjUU = _script->scanMobEventsWithItem(_invMobList[_selectedMob - 1]._mask, _script->_scriptInfo.invObjUU, _selectedItem); + if (invObjUU == -1) { + int textNr = 11; + if (_selectedItem == 31 || _invMobList[_selectedMob - 1]._mask == 31) { + textNr = 20; + } + printAt(0, 216, _variaTxt->getString(textNr), kNormalWidth / 2, 100); + //loadVoice(0, 28, Common::String::format("%05d-00.WAV", text)); + //playSample(28, 0); + } else { + //store_new_pc + // storeNewPC(); + } } } else { return; @@ -1731,7 +1738,7 @@ void PrinceEngine::inventoryLeftMouseButton() { } //do_option if (_optionEnabled == 0) { - int invObjExamEvent = _script->scanMobEvents(_selectedMob, _script->_scriptInfo.invObjExam); + int invObjExamEvent = _script->scanMobEvents(_invMobList[_selectedMob - 1]._mask, _script->_scriptInfo.invObjExam); if (invObjExamEvent == -1) { // do_standard printAt(0, 216, _invMobList[_selectedMob - 1]._examText.c_str(), kNormalWidth / 2, _invExamY); @@ -1751,12 +1758,12 @@ void PrinceEngine::inventoryLeftMouseButton() { } } else if (_optionEnabled == 1) { // not_examine - int invObjUse = _script->scanMobEvents(_selectedMob, _script->_scriptInfo.invObjUse); + int invObjUse = _script->scanMobEvents(_invMobList[_selectedMob - 1]._mask, _script->_scriptInfo.invObjUse); if (invObjUse == -1) { // do_standard_use _selectedMode = 0; - _selectedItem = _selectedMob; - makeInvCursor(_selectedMob); + _selectedItem = _invMobList[_selectedMob - 1]._mask; + makeInvCursor(_invMobList[_selectedMob - 1]._mask); _currentPointerNumber = 2; changeCursor(2); //exit_normally @@ -1772,14 +1779,27 @@ void PrinceEngine::inventoryLeftMouseButton() { // not_use_inv // do_standard_give _selectedMode = 1; - _selectedItem = _selectedMob; - makeInvCursor(_selectedMob); + _selectedItem = _invMobList[_selectedMob - 1]._mask; + makeInvCursor(_invMobList[_selectedMob - 1]._mask); _currentPointerNumber = 2; changeCursor(2); //exit_normally } else { // use_item_on_item + int invObjUU = _script->scanMobEventsWithItem(_invMobList[_selectedMob - 1]._mask, _script->_scriptInfo.invObjUU, _selectedItem); + if (invObjUU == -1) { + int textNr = 11; + if (_selectedItem == 31 || _invMobList[_selectedMob - 1]._mask == 31) { + textNr = 20; + } + printAt(0, 216, _variaTxt->getString(textNr), kNormalWidth / 2, 100); + //loadVoice(0, 28, Common::String::format("%05d-00.WAV", text)); + //playSample(28, 0); + } else { + //store_new_pc + // storeNewPC(); + } } //exit_normally _selectedMob = 0; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 5c81ee682c69..a8efe71ca8fc 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -212,10 +212,10 @@ int Script::scanMobEvents(int mobMask, int dataEventOffset) { int32 code; do { mob = (int)READ_UINT16(&_data[dataEventOffset + i * 6]); - debug("mob: %d", mob); - code = (int)READ_UINT32(&_data[dataEventOffset + i * 6 + 2]); - debug("code: %d", code); if (mob == mobMask) { + code = (int)READ_UINT32(&_data[dataEventOffset + i * 6 + 2]); + debug("mob: %d", mob); + debug("code: %d", code); return code; } i++; @@ -223,6 +223,29 @@ int Script::scanMobEvents(int mobMask, int dataEventOffset) { return -1; } +int Script::scanMobEventsWithItem(int mobMask, int dataEventOffset, int itemNr) { + debug("mobMask: %d", mobMask); + int i = 0; + int16 mob; + int16 item; + int32 code; + do { + mob = (int)READ_UINT16(&_data[dataEventOffset + i * 8]); + if (mob == mobMask) { + item = (int)READ_UINT16(&_data[dataEventOffset + i * 8 + 2]); + if (item == itemNr) { + code = (int)READ_UINT32(&_data[dataEventOffset + i * 8 + 4]); + debug("mob: %d", mob); + debug("item: %d", item); + debug("code: %d", code); + return code; + } + } + i++; + } while (mob != -1); + return -1; +} + void Script::installSingleBackAnim(Common::Array &_backanimList, int offset) { BackgroundAnim newBackgroundAnim; diff --git a/engines/prince/script.h b/engines/prince/script.h index 489647ad914d..4a7316c9d5cb 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -140,6 +140,7 @@ class Script { bool loadAllMasks(Common::Array &maskList, int offset); int scanMobEvents(int mobMask, int dataEventOffset); + int scanMobEventsWithItem(int mobMask, int dataEventOffset, int item); const char *getString(uint32 offset) { return (const char *)(&_data[offset]); diff --git a/engines/prince/variatxt.cpp b/engines/prince/variatxt.cpp index 427044479356..fdca8c2c775b 100644 --- a/engines/prince/variatxt.cpp +++ b/engines/prince/variatxt.cpp @@ -42,15 +42,11 @@ bool VariaTxt::loadFromStream(Common::SeekableReadStream &stream) { return true; } -const char * VariaTxt::getString(uint32 stringId) { - uint32 stringOffset = READ_LE_UINT32(_data + stringId); - +const char *VariaTxt::getString(uint32 stringId) { + uint32 stringOffset = READ_LE_UINT32(_data + stringId * 4); if (stringOffset > _dataSize) { assert(false); } - - debug("VariaTxt::getString %04X %04X", stringId, stringOffset); - return (const char *)_data + stringOffset; } From 1ca309f50ac955c14e7d24328632934fae25b4c8 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 19 Jun 2014 16:00:11 +0200 Subject: [PATCH 191/374] PRINCE: Voice sample for options Open/Push, Close/Pull in inventory --- engines/prince/prince.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index ae07bebfad0e..003b9578226d 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1719,13 +1719,13 @@ void PrinceEngine::inventoryLeftMouseButton() { //use_item_on_item int invObjUU = _script->scanMobEventsWithItem(_invMobList[_selectedMob - 1]._mask, _script->_scriptInfo.invObjUU, _selectedItem); if (invObjUU == -1) { - int textNr = 11; + int textNr = 11; // "I can't do it." if (_selectedItem == 31 || _invMobList[_selectedMob - 1]._mask == 31) { - textNr = 20; + textNr = 20; // "Nothing is happening." } printAt(0, 216, _variaTxt->getString(textNr), kNormalWidth / 2, 100); - //loadVoice(0, 28, Common::String::format("%05d-00.WAV", text)); - //playSample(28, 0); + loadVoice(0, 28, Common::String::format("%05d-01.WAV", textNr)); + playSample(28, 0); } else { //store_new_pc // storeNewPC(); @@ -1788,13 +1788,13 @@ void PrinceEngine::inventoryLeftMouseButton() { // use_item_on_item int invObjUU = _script->scanMobEventsWithItem(_invMobList[_selectedMob - 1]._mask, _script->_scriptInfo.invObjUU, _selectedItem); if (invObjUU == -1) { - int textNr = 11; + int textNr = 11; // "I can't do it." if (_selectedItem == 31 || _invMobList[_selectedMob - 1]._mask == 31) { - textNr = 20; + textNr = 20; // "Nothing is happening." } printAt(0, 216, _variaTxt->getString(textNr), kNormalWidth / 2, 100); - //loadVoice(0, 28, Common::String::format("%05d-00.WAV", text)); - //playSample(28, 0); + loadVoice(0, 28, Common::String::format("%05d-01.WAV", textNr)); + playSample(28, 0); } else { //store_new_pc // storeNewPC(); From 96a1d24a4ad3416ae3afc7aae19edadeb936b49a Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 19 Jun 2014 16:38:02 +0200 Subject: [PATCH 192/374] PRINCE: LMB in inventory - update --- engines/prince/prince.cpp | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 003b9578226d..031d827285d9 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1694,6 +1694,7 @@ void PrinceEngine::inventoryLeftMouseButton() { return; } } else { + // when this happens? // test bx, RMBMask 7996 ? right mouse button here? - > return; //disable_use if (_currentPointerNumber == 2) { @@ -1701,6 +1702,9 @@ void PrinceEngine::inventoryLeftMouseButton() { changeCursor(1); _currentPointerNumber = 1; //exit_normally + _selectedMob = 0; + _optionsMob = 0; + return; } else { return; } @@ -1726,10 +1730,13 @@ void PrinceEngine::inventoryLeftMouseButton() { printAt(0, 216, _variaTxt->getString(textNr), kNormalWidth / 2, 100); loadVoice(0, 28, Common::String::format("%05d-01.WAV", textNr)); playSample(28, 0); + //exit_normally } else { //store_new_pc // storeNewPC(); - + _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob - 1]._mask); + //byeinv + _showInventoryFlag = false; } } } else { @@ -1752,9 +1759,8 @@ void PrinceEngine::inventoryLeftMouseButton() { //store_new_pc // storeNewPC(); _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob - 1]._mask); - _selectedMob = 0; - _optionsMob = 0; //bye_inv + _showInventoryFlag = false; } } else if (_optionEnabled == 1) { // not_examine @@ -1771,9 +1777,8 @@ void PrinceEngine::inventoryLeftMouseButton() { //store_new_pc // storeNewPC(); _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob - 1]._mask); - _selectedMob = 0; - _optionsMob = 0; //bye_inv + _showInventoryFlag = false; } } else if (_optionEnabled == 4) { // not_use_inv @@ -1795,10 +1800,13 @@ void PrinceEngine::inventoryLeftMouseButton() { printAt(0, 216, _variaTxt->getString(textNr), kNormalWidth / 2, 100); loadVoice(0, 28, Common::String::format("%05d-01.WAV", textNr)); playSample(28, 0); + //exit_normally } else { //store_new_pc // storeNewPC(); - + _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob - 1]._mask); + //byeinv + _showInventoryFlag = false; } } //exit_normally @@ -2018,6 +2026,10 @@ void PrinceEngine::displayInventory() { } } + if (!_showInventoryFlag) { + break; + } + if (shouldQuit()) return; @@ -2025,6 +2037,12 @@ void PrinceEngine::displayInventory() { _graph->update(_graph->_screenForInventory); pause(); } + + if (_currentPointerNumber == 2) { + _flags->setFlagValue(Flags::SELITEM, _selectedItem); + } else { + _flags->setFlagValue(Flags::SELITEM, 0); + } } void PrinceEngine::createDialogBox(Common::Array &dialogData) { From c8046f85915d5a02742f16decb60568ee448a246 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 19 Jun 2014 18:17:22 +0200 Subject: [PATCH 193/374] PRINCE: PrinceEngine:: makeInvCursor() --- engines/prince/prince.cpp | 69 ++++++++++++++++++++++++++++++++------- engines/prince/prince.h | 3 +- 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 031d827285d9..cf187b722bfc 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -78,7 +78,7 @@ void PrinceEngine::debugEngine(const char *s, ...) { PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _graph(nullptr), _script(nullptr), _interpreter(nullptr), _flags(nullptr), _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), _room(nullptr), testAnimNr(0), testAnimFrame(0), - _frameNr(0), _cursor1(nullptr), _cursor2(nullptr), _font(nullptr), + _frameNr(0), _cursor1(nullptr), _cursor2(nullptr), _cursor3(nullptr), _font(nullptr), _suitcaseBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0), _randomSource("prince"), _invLineX(134), _invLineY(176), _invLine(5), _invLines(3), _invLineW(70), _invLineH(76), _maxInvW(72), _maxInvH(76), _invLineSkipX(2), _invLineSkipY(3), _showInventoryFlag(false), _inventoryBackgroundRemember(false), @@ -106,7 +106,7 @@ PrinceEngine::~PrinceEngine() { delete _rnd; delete _debugger; delete _cursor1; - delete _cursor2; + delete _cursor3; delete _midiPlayer; delete _script; delete _flags; @@ -120,6 +120,11 @@ PrinceEngine::~PrinceEngine() { delete _graph; delete _room; + if (_cursor2 != nullptr) { + _cursor2->free(); + delete _cursor2; + } + for (uint i = 0; i < _objList.size(); i++) { delete _objList[i]; } @@ -219,8 +224,8 @@ void PrinceEngine::init() { _cursor1 = new Cursor(); Resource::loadResource(_cursor1, "mouse1.cur", true); - _cursor2 = new Cursor(); - Resource::loadResource(_cursor2, "mouse2.cur", true); + _cursor3 = new Cursor(); + Resource::loadResource(_cursor3, "mouse2.cur", true); Common::SeekableReadStream *talkTxtStream = SearchMan.createReadStreamForMember("talktxt.dat"); if (!talkTxtStream) { @@ -420,7 +425,10 @@ void PrinceEngine::changeCursor(uint16 curId) { curSurface = _cursor1->getSurface(); break; case 2: - curSurface = _cursor2->getSurface(); + curSurface = _cursor2; + break; + case 3: + curSurface = _cursor3->getSurface(); hotspotX = curSurface->w >> 1; hotspotY = curSurface->h >> 1; break; @@ -438,19 +446,56 @@ void PrinceEngine::changeCursor(uint16 curId) { } void PrinceEngine::makeInvCursor(int itemNr) { - const Graphics::Surface *cur1Surface = nullptr; - cur1Surface = _cursor1->getSurface(); + 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 = nullptr; - itemSurface = _allInvList[itemNr].getSurface(); + 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; - //TODO + 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); + + byte *src1 = (byte *)itemSurface->getBasePtr(0, 0); + byte *dst1 = (byte *)_cursor2->getBasePtr(cur1W, cur1H); + + if (itemH % 2 != 0) { + itemH--; + } + if (itemW % 2 != 0) { + itemW--; + } + + for (int y = 0; y < itemH; y++) { + byte *src2 = src1; + byte *dst2 = dst1; + if (y % 2 == 0) { + for (int x = 0; x < itemW; x++, src2++) { + if (x % 2 == 0) { + if (*src2 != 0) { + *dst2 = *src2; + } else { + *dst2 = 255; + } + dst2++; + } + } + dst1 += _cursor2->pitch; + } + src1 += itemSurface->pitch; + } } bool PrinceEngine::playNextFrame() { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 4ffedaed6fb4..c6f1026ace3e 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -393,7 +393,8 @@ class PrinceEngine : public Engine { Common::RandomSource *_rnd; Cursor *_cursor1; - Cursor *_cursor2; + Graphics::Surface *_cursor2; + Cursor *_cursor3; Debugger *_debugger; GraphicsMan *_graph; Script *_script; From fd5ee85e3d77137ec15e37b4944ad0500a812873 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 19 Jun 2014 19:06:04 +0200 Subject: [PATCH 194/374] PRINCE: PrinceEngine::showTexts() - y position fix --- engines/prince/prince.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index cf187b722bfc..da6d74a1e896 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -936,9 +936,10 @@ void PrinceEngine::showTexts(Graphics::Surface *screen) { text._x = leftBorderText + wideLine / 2; } + int textSkip = 2; for (uint8 i = 0; i < lines.size(); i++) { int x = text._x - getTextWidth(lines[i].c_str()) / 2; - int y = text._y - (lines.size() - i) * (_font->getFontHeight()); // to fix + int y = text._y - 10 - (lines.size() - i) * (_font->getFontHeight() - textSkip); if (x < 0) { x = 0; } @@ -2204,13 +2205,13 @@ void PrinceEngine::talkHero(int slot, const char *s) { _mainHero->_state = Hero::TALK; _mainHero->_talkTime = time; x = _mainHero->_middleX - _picWindowX; - y = _mainHero->_middleY - _mainHero->_scaledFrameYSize - 10; + y = _mainHero->_middleY - _mainHero->_scaledFrameYSize; } else { text._color = 220; // test this ! _secondHero->_state = Hero::TALK; _secondHero->_talkTime = time; x = _secondHero->_middleX - _picWindowX; - y = _secondHero->_middleY - _secondHero->_scaledFrameYSize - 10; + y = _secondHero->_middleY - _secondHero->_scaledFrameYSize; } text._time = time; // changed by SETSPECVOICE? text._str = s; From 422eeab07a068ade9bd70e0f9e88dd62a8d886d9 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 21 Jun 2014 17:03:26 +0200 Subject: [PATCH 195/374] PRINCE: LMB in inventory - use item on item fix --- engines/prince/prince.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index da6d74a1e896..87b9e12b0a1d 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1777,6 +1777,9 @@ void PrinceEngine::inventoryLeftMouseButton() { loadVoice(0, 28, Common::String::format("%05d-01.WAV", textNr)); playSample(28, 0); //exit_normally + _selectedMob = 0; + _optionsMob = 0; + return; } else { //store_new_pc // storeNewPC(); From 31ea2154478ed4cb0344711861f835c848e97dde Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 21 Jun 2014 20:23:17 +0200 Subject: [PATCH 196/374] PRINCE: Hero animations fix - frame height calculation --- engines/prince/animation.cpp | 21 +++++++++++++++++++++ engines/prince/animation.h | 3 +++ engines/prince/hero.cpp | 21 +++++++++++++++++---- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index a4df4e30cc6c..adf96b5f00cf 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -57,6 +57,27 @@ void Animation::clear() { } } +// AH_ID +bool Animation::testId() const { + char id[2]; + id[0] = (char)READ_LE_UINT16(_data); + id[1] = (char)READ_LE_UINT16(_data + 1); + if (id[0] == 'A' && id[1] == 'N') { + return true; // normal animation + } + return false; +} + +// AH_ID - x diff +int8 Animation::getIdXDiff() const { + return (int8)READ_LE_UINT16(_data); +} + +// AH_ID - y diff +int8 Animation::getIdYDiff() const { + return (int8)READ_LE_UINT16(_data + 1); +} + // AH_Loop int16 Animation::getLoopCount() const { return READ_LE_UINT16(_data + 2); diff --git a/engines/prince/animation.h b/engines/prince/animation.h index acf689e05f9b..09ebf7d8b94c 100644 --- a/engines/prince/animation.h +++ b/engines/prince/animation.h @@ -37,6 +37,9 @@ class Animation { Animation(); Animation(byte *data, uint32 dataSize); ~Animation(); + bool testId() const; + int8 getIdXDiff() const; + int8 getIdYDiff() const; int16 getLoopCount() const; int16 getBaseX() const; int16 getBaseY() const; diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index eadfd899b68e..44bd07f12aff 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -196,11 +196,20 @@ void Hero::countDrawPosition() { } else { tempMiddleY = _middleY; } - _frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); - _frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); + int phaseFrameIndex = _moveSet[_moveSetType]->getPhaseFrameIndex(_phase); + _frameXSize = _moveSet[_moveSetType]->getFrameWidth(phaseFrameIndex); + _frameYSize = _moveSet[_moveSetType]->getFrameHeight(phaseFrameIndex); _scaledFrameXSize = getScaledValue(_frameXSize); _scaledFrameYSize = getScaledValue(_frameYSize); + // any use of this? + /* + if (!_moveSet[_moveSetType]->testId()) { + int diffX = _moveSet[_moveSetType]->getIdXDiff(); + int diffY = _moveSet[_moveSetType]->getIdYDiff(); + } + */ + if (_zoomFactor != 0) { //notfullSize _drawX = _middleX - _scaledFrameXSize / 2; @@ -525,10 +534,14 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { } void Hero::showHeroAnimFrame() { - if (_phase < _moveSet[_moveSetType]->getFrameCount() - 1) { + if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 1) { _phase++; } else { - _phase = 0; + if (_state == TALK) { + _phase = _moveSet[_moveSetType]->getLoopCount(); + } else { + _phase = 0; + } } countDrawPosition(); } From a428f324f2a85e0a86f6751f0f27da6f1f71f967 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 21 Jun 2014 20:41:27 +0200 Subject: [PATCH 197/374] PRINCE: Dialog box loop - drawScreen() update for it --- engines/prince/prince.cpp | 9 ++++++--- engines/prince/prince.h | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 87b9e12b0a1d..da2f635d330c 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -87,7 +87,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _optionsMob(0), _currentPointerNumber(1), _selectedMob(0), _selectedItem(0), _selectedMode(0), _optionsWidth(210), _optionsHeight(170), _invOptionsWidth(210), _invOptionsHeight(130), _optionsStep(20), _invOptionsStep(20), _optionsNumber(7), _invOptionsNumber(5), _optionsColor1(236), _optionsColor2(252), - _dialogWidth(600), _dialogHeight(0), _dialogLineSpace(10), _dialogColor1(220), _dialogColor2(223) { + _dialogWidth(600), _dialogHeight(0), _dialogLineSpace(10), _dialogColor1(220), _dialogColor2(223), _dialogFlag(false) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -1438,7 +1438,7 @@ void PrinceEngine::drawScreen() { playNextFrame(); if (!_inventoryBackgroundRemember) { - if (!_optionsFlag) { + if (!_optionsFlag && !_dialogFlag) { _selectedMob = hotspot(_graph->_frontScreen, _mobList); } showTexts(_graph->_frontScreen); @@ -2111,9 +2111,12 @@ void PrinceEngine::createDialogBox(Common::Array &dialogData) { void PrinceEngine::runDialog(Common::Array &dialogData) { + _dialogFlag = true; + while (!shouldQuit()) { - drawScreen(); // without some of things - check it + drawScreen(); + // background iterpreter? int dialogX = (640 - _dialogWidth) / 2; int dialogY = 460 - _dialogHeight; diff --git a/engines/prince/prince.h b/engines/prince/prince.h index c6f1026ace3e..47822871327e 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -349,6 +349,7 @@ class PrinceEngine : public Engine { void inventoryRightMouseButton(); void dialogLeftMouseButton(int dialogSelected, const char *s); + bool _dialogFlag; int _dialogWidth; int _dialogHeight; int _dialogLineSpace; From d67690c5f6f0c839038edbb45bcc43cce2fffd86 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 21 Jun 2014 21:38:39 +0200 Subject: [PATCH 198/374] PRINCE: Inventory turning on - update --- engines/prince/prince.cpp | 16 +++++++++++++--- engines/prince/prince.h | 2 ++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index da2f635d330c..d074ff78e143 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -83,7 +83,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _invLineX(134), _invLineY(176), _invLine(5), _invLines(3), _invLineW(70), _invLineH(76), _maxInvW(72), _maxInvH(76), _invLineSkipX(2), _invLineSkipY(3), _showInventoryFlag(false), _inventoryBackgroundRemember(false), _mst_shadow(0), _mst_shadow2(0), _candleCounter(0), _invX1(53), _invY1(18), _invWidth(536), _invHeight(438), - _invCurInside(false), _optionsFlag(false), _optionEnabled(0), _invExamY(120), + _invCurInside(false), _optionsFlag(false), _optionEnabled(0), _invExamY(120), _invMaxCount(2), _invCounter(0), _optionsMob(0), _currentPointerNumber(1), _selectedMob(0), _selectedItem(0), _selectedMode(0), _optionsWidth(210), _optionsHeight(170), _invOptionsWidth(210), _invOptionsHeight(130), _optionsStep(20), _invOptionsStep(20), _optionsNumber(7), _invOptionsNumber(5), _optionsColor1(236), _optionsColor2(252), @@ -2315,8 +2315,18 @@ void PrinceEngine::mainLoop() { // inventory turning on: Common::Point mousePos = _system->getEventManager()->getMousePos(); - if (mousePos.y == 0 && !_showInventoryFlag) { - inventoryFlagChange(true); + if (mousePos.y < 4 && !_showInventoryFlag) { + _invCounter++; + } else { + _invCounter = 0; + } + if (_invCounter >= _invMaxCount) { + if (_flags->getFlagValue(Flags::INVALLOWED) != 1) { + // 29 - Basement, 50 - Map, 59 - Intro + if (_locationNr != 29 && _locationNr != 50 && _locationNr != 59) { + inventoryFlagChange(true); + } + } } if (_debugger->_locationNr != _locationNr) diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 47822871327e..de3809b92d34 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -330,6 +330,8 @@ class PrinceEngine : public Engine { int _mst_shadow; int _mst_shadow2; // blinking after adding new item int _candleCounter; // special counter for candle inventory item + int _invMaxCount; // time to turn inventory on + int _invCounter; // turning on counter void inventoryFlagChange(bool inventoryState); bool loadAllInv(); From 11d062f2b222826965fb1653aade448fa359c1ac Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 21 Jun 2014 23:24:24 +0200 Subject: [PATCH 199/374] PRINCE: Cursor update, LMB outside inventory crash fix --- engines/prince/prince.cpp | 57 ++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index d074ff78e143..7fefae9f5f60 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -420,6 +420,8 @@ void PrinceEngine::changeCursor(uint16 curId) { switch(curId) { case 0: CursorMan.showMouse(false); + _optionsFlag = 0; + _selectedMob = 0; return; case 1: curSurface = _cursor1->getSurface(); @@ -1437,8 +1439,8 @@ void PrinceEngine::drawScreen() { playNextFrame(); - if (!_inventoryBackgroundRemember) { - if (!_optionsFlag && !_dialogFlag) { + if (!_inventoryBackgroundRemember && !_dialogFlag) { + if (!_optionsFlag) { _selectedMob = hotspot(_graph->_frontScreen, _mobList); } showTexts(_graph->_frontScreen); @@ -1686,33 +1688,38 @@ void PrinceEngine::leftMouseButton() { if (_optionsFlag) { if (_optionEnabled < _optionsNumber) { _optionsFlag = 0; + // edi = optionsMob + // ebp = optionsMobNumber } else { return; } } else { + // edi = currentMob + // ebp = currentMobNumber _optionsMob = _selectedMob; - if (!_selectedMob) { - // @@walkto + if (_selectedMob == 0) { + // @@walkto - TODO + return; } } - // edi = optionsMob - // ebp = optionsMobNumber + //do_option // selectedMob = optionsMobNumber if (_currentPointerNumber != 2) { //skip_use_code - } - if (_selectedMode != 0) { + + } else if (_selectedMode != 0) { //give_item - } - if (_room->_itemUse == 0) { - //standard_useitem - //_script->_scriptInfo.stdUse; } else { - debug("selectedMob: %d", _selectedMob); - int mobEvent = _script->scanMobEventsWithItem(_mobList[_selectedMob - 1]._mask, _room->_itemUse, _selectedItem); - if (mobEvent == -1) { + if (_room->_itemUse == 0) { + //standard_useitem + //_script->_scriptInfo.stdUse; + } else { + debug("selectedMob: %d", _selectedMob); + int mobEvent = _script->scanMobEventsWithItem(_mobList[_selectedMob - 1]._mask, _room->_itemUse, _selectedItem); + if (mobEvent == -1) { + } } } } @@ -1720,6 +1727,9 @@ void PrinceEngine::leftMouseButton() { void PrinceEngine::rightMouseButton() { if (_currentPointerNumber < 2) { enableOptions(); + } else { + _currentPointerNumber = 1; + changeCursor(1); } } @@ -1871,9 +1881,11 @@ void PrinceEngine::inventoryRightMouseButton() { void PrinceEngine::enableOptions() { if (_optionsFlag != 1) { - changeCursor(1); - _currentPointerNumber = 1; + //changeCursor(1); + //_currentPointerNumber = 1; if (_selectedMob != 0) { + changeCursor(1); + _currentPointerNumber = 1; //if (_mobType != 0x100) { Common::Point mousePos = _system->getEventManager()->getMousePos(); int x1 = mousePos.x - _optionsWidth / 2; @@ -2167,7 +2179,7 @@ void PrinceEngine::runDialog(Common::Array &dialogData) { case Common::EVENT_LBUTTONDOWN: if (dialogSelected != -1) { dialogLeftMouseButton(dialogSelected, dialogData[dialogSelectedText]._line.c_str()); - return; + _dialogFlag = false; } break; case Common::EVENT_RBUTTONDOWN: @@ -2183,8 +2195,13 @@ void PrinceEngine::runDialog(Common::Array &dialogData) { } } - if (shouldQuit()) + if (shouldQuit()) { return; + } + + if (!_dialogFlag) { + break; + } getDebugger()->onFrame(); _graph->update(_graph->_frontScreen); @@ -2192,6 +2209,8 @@ void PrinceEngine::runDialog(Common::Array &dialogData) { } _dialogImage->free(); delete _dialogImage; + _dialogFlag = false; + // cursor? } void PrinceEngine::dialogLeftMouseButton(int dialogSelected, const char *s) { From a319f473f6502b4acd2b7da4aa5220a965335081 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 24 Jun 2014 03:57:40 +0200 Subject: [PATCH 200/374] PRINCE: LMB outside of inventory - update --- engines/prince/prince.cpp | 24 +++++++++++++++++++++++- engines/prince/script.cpp | 4 ++++ engines/prince/script.h | 1 + 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 7fefae9f5f60..04901d78fa68 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1685,8 +1685,11 @@ void PrinceEngine::drawInvItems() { } void PrinceEngine::leftMouseButton() { + int option = 0; + if (_optionsFlag) { if (_optionEnabled < _optionsNumber) { + option = _optionEnabled; _optionsFlag = 0; // edi = optionsMob // ebp = optionsMobNumber @@ -1701,12 +1704,31 @@ void PrinceEngine::leftMouseButton() { // @@walkto - TODO return; } + option = 0; } //do_option // selectedMob = optionsMobNumber if (_currentPointerNumber != 2) { //skip_use_code - + int optionScriptOffset = _script->getOptionScript(_room->_walkTo, option); + int optionEvent; + if (optionScriptOffset != 0) { + optionEvent = _script->scanMobEvents(_optionsMob, optionScriptOffset); + } else { + optionEvent = -1; + } + if (optionEvent == -1) { + if (option == 0) { + //@@walkto - TODO + return; + } else { + optionEvent = _script->getOptionScript(_script->_scriptInfo.stdExamine, option - 1); + } + } + // eax <- return (int)READ_UINT16(&_data[optionEvent]); + // store_new_pc: + // storeNewPC(); + return; } else if (_selectedMode != 0) { //give_item diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index a8efe71ca8fc..4122b3898e9f 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -205,6 +205,10 @@ uint8 *Script::getRoomOffset(int locationNr) { return &_data[_scriptInfo.rooms + locationNr * 64]; } +int Script::getOptionScript(int offset, int option) { + return (int)READ_UINT16(&_data[offset + option * 4]); +} + int Script::scanMobEvents(int mobMask, int dataEventOffset) { debug("mobMask: %d", mobMask); int i = 0; diff --git a/engines/prince/script.h b/engines/prince/script.h index 4a7316c9d5cb..5cdf9c64baa7 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -135,6 +135,7 @@ class Script { int16 getLightY(int locationNr); int32 getShadowScale(int locationNr); uint8 *getRoomOffset(int locationNr); + int32 getOptionScript(int offset, int option); void installBackAnims(Common::Array &_backanimList, int offset); void installSingleBackAnim(Common::Array &_backanimList, int offset); bool loadAllMasks(Common::Array &maskList, int offset); From 9a13423829ec001cf588e2607b5a90785f501f89 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 24 Jun 2014 05:03:36 +0200 Subject: [PATCH 201/374] PRINCE: LMB outside inventory - give / use item --- engines/prince/prince.cpp | 34 +++++++++++++++++++++++++--------- engines/prince/script.cpp | 8 +++----- engines/prince/script.h | 2 +- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 04901d78fa68..44e2ec9639b4 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1731,18 +1731,32 @@ void PrinceEngine::leftMouseButton() { return; } else if (_selectedMode != 0) { //give_item - + int optionEvent = -1; + if (_room->_itemGive != 0) { + optionEvent = _script->scanMobEventsWithItem(_optionsMob, _room->_itemGive, _selectedItem); + } + if (optionEvent == -1) { + //standard_giveitem + optionEvent = _script->_scriptInfo.stdGiveItem; + } + // eax <- return (int)READ_UINT16(&_data[optionEvent]); + // store_new_pc: + // storeNewPC(); + return; } else { - if (_room->_itemUse == 0) { + int optionEvent = -1; + if (_room->_itemUse != 0) { + optionEvent = _script->scanMobEventsWithItem(_optionsMob, _room->_itemUse, _selectedItem); + _flags->setFlagValue(Flags::SELITEM, _selectedItem); + } + if (optionEvent == -1) { //standard_useitem - //_script->_scriptInfo.stdUse; - } else { - debug("selectedMob: %d", _selectedMob); - int mobEvent = _script->scanMobEventsWithItem(_mobList[_selectedMob - 1]._mask, _room->_itemUse, _selectedItem); - if (mobEvent == -1) { - - } + optionEvent = _script->_scriptInfo.stdUseItem; } + // eax <- return (int)READ_UINT16(&_data[optionEvent]); + // store_new_pc: + // storeNewPC(); + return; } } @@ -2043,6 +2057,8 @@ void PrinceEngine::displayInventory() { _mainHero->_inventory.push_back(44); _mainHero->_inventory.push_back(67); + _mainHero->_inventory.push_back(8); + prepareInventoryToView(); while (!shouldQuit()) { diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 4122b3898e9f..461dbb12df05 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -218,7 +218,6 @@ int Script::scanMobEvents(int mobMask, int dataEventOffset) { mob = (int)READ_UINT16(&_data[dataEventOffset + i * 6]); if (mob == mobMask) { code = (int)READ_UINT32(&_data[dataEventOffset + i * 6 + 2]); - debug("mob: %d", mob); debug("code: %d", code); return code; } @@ -227,7 +226,7 @@ int Script::scanMobEvents(int mobMask, int dataEventOffset) { return -1; } -int Script::scanMobEventsWithItem(int mobMask, int dataEventOffset, int itemNr) { +int Script::scanMobEventsWithItem(int mobMask, int dataEventOffset, int itemMask) { debug("mobMask: %d", mobMask); int i = 0; int16 mob; @@ -237,10 +236,9 @@ int Script::scanMobEventsWithItem(int mobMask, int dataEventOffset, int itemNr) mob = (int)READ_UINT16(&_data[dataEventOffset + i * 8]); if (mob == mobMask) { item = (int)READ_UINT16(&_data[dataEventOffset + i * 8 + 2]); - if (item == itemNr) { + if (item == itemMask) { code = (int)READ_UINT32(&_data[dataEventOffset + i * 8 + 4]); - debug("mob: %d", mob); - debug("item: %d", item); + debug("itemMask: %d", item); debug("code: %d", code); return code; } diff --git a/engines/prince/script.h b/engines/prince/script.h index 5cdf9c64baa7..28e3be4ebc7e 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -141,7 +141,7 @@ class Script { bool loadAllMasks(Common::Array &maskList, int offset); int scanMobEvents(int mobMask, int dataEventOffset); - int scanMobEventsWithItem(int mobMask, int dataEventOffset, int item); + int scanMobEventsWithItem(int mobMask, int dataEventOffset, int itemMask); const char *getString(uint32 offset) { return (const char *)(&_data[offset]); From e453f23f04889c7b33276240c45e9f2e5eb70206 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 24 Jun 2014 05:21:12 +0200 Subject: [PATCH 202/374] PRINCE: leftMouseButton() - code clean up --- engines/prince/prince.cpp | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 44e2ec9639b4..358baad76216 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1686,32 +1686,27 @@ void PrinceEngine::drawInvItems() { void PrinceEngine::leftMouseButton() { int option = 0; + int optionEvent = -1; if (_optionsFlag) { if (_optionEnabled < _optionsNumber) { option = _optionEnabled; _optionsFlag = 0; - // edi = optionsMob - // ebp = optionsMobNumber } else { return; } } else { - // edi = currentMob - // ebp = currentMobNumber _optionsMob = _selectedMob; - if (_selectedMob == 0) { + if (_optionsMob == 0) { // @@walkto - TODO return; } option = 0; } //do_option - // selectedMob = optionsMobNumber if (_currentPointerNumber != 2) { //skip_use_code int optionScriptOffset = _script->getOptionScript(_room->_walkTo, option); - int optionEvent; if (optionScriptOffset != 0) { optionEvent = _script->scanMobEvents(_optionsMob, optionScriptOffset); } else { @@ -1725,13 +1720,8 @@ void PrinceEngine::leftMouseButton() { optionEvent = _script->getOptionScript(_script->_scriptInfo.stdExamine, option - 1); } } - // eax <- return (int)READ_UINT16(&_data[optionEvent]); - // store_new_pc: - // storeNewPC(); - return; } else if (_selectedMode != 0) { //give_item - int optionEvent = -1; if (_room->_itemGive != 0) { optionEvent = _script->scanMobEventsWithItem(_optionsMob, _room->_itemGive, _selectedItem); } @@ -1739,12 +1729,7 @@ void PrinceEngine::leftMouseButton() { //standard_giveitem optionEvent = _script->_scriptInfo.stdGiveItem; } - // eax <- return (int)READ_UINT16(&_data[optionEvent]); - // store_new_pc: - // storeNewPC(); - return; } else { - int optionEvent = -1; if (_room->_itemUse != 0) { optionEvent = _script->scanMobEventsWithItem(_optionsMob, _room->_itemUse, _selectedItem); _flags->setFlagValue(Flags::SELITEM, _selectedItem); @@ -1753,11 +1738,12 @@ void PrinceEngine::leftMouseButton() { //standard_useitem optionEvent = _script->_scriptInfo.stdUseItem; } - // eax <- return (int)READ_UINT16(&_data[optionEvent]); - // store_new_pc: - // storeNewPC(); - return; } + // eax <- return (int)READ_UINT16(&_data[optionEvent]); + // storeNewPC(); + _flags->setFlagValue(Flags::CURRMOB, _selectedMob); + _selectedMob = 0; + _optionsMob = 0; } void PrinceEngine::rightMouseButton() { From fc71efd7132345958f809c05e806bb84411dee01 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 26 Jun 2014 02:35:48 +0200 Subject: [PATCH 203/374] PRINCE: LMB() fix, storeNewPC() - first working script events --- engines/prince/prince.cpp | 13 ++++------ engines/prince/script.cpp | 54 +++++++++++++++++++++++++++++++++++++-- engines/prince/script.h | 4 ++- 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 358baad76216..5fd97fca7687 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1706,7 +1706,7 @@ void PrinceEngine::leftMouseButton() { //do_option if (_currentPointerNumber != 2) { //skip_use_code - int optionScriptOffset = _script->getOptionScript(_room->_walkTo, option); + int optionScriptOffset = _room->getOptionOffset(option); if (optionScriptOffset != 0) { optionEvent = _script->scanMobEvents(_optionsMob, optionScriptOffset); } else { @@ -1717,7 +1717,7 @@ void PrinceEngine::leftMouseButton() { //@@walkto - TODO return; } else { - optionEvent = _script->getOptionScript(_script->_scriptInfo.stdExamine, option - 1); + optionEvent = _script->getOptionStandardOffset(option - 1); } } } else if (_selectedMode != 0) { @@ -1739,8 +1739,7 @@ void PrinceEngine::leftMouseButton() { optionEvent = _script->_scriptInfo.stdUseItem; } } - // eax <- return (int)READ_UINT16(&_data[optionEvent]); - // storeNewPC(); + _interpreter->storeNewPC(optionEvent); _flags->setFlagValue(Flags::CURRMOB, _selectedMob); _selectedMob = 0; _optionsMob = 0; @@ -1903,11 +1902,9 @@ void PrinceEngine::inventoryRightMouseButton() { void PrinceEngine::enableOptions() { if (_optionsFlag != 1) { - //changeCursor(1); - //_currentPointerNumber = 1; + changeCursor(1); + _currentPointerNumber = 1; if (_selectedMob != 0) { - changeCursor(1); - _currentPointerNumber = 1; //if (_mobType != 0x100) { Common::Point mousePos = _system->getEventManager()->getMousePos(); int x1 = mousePos.x - _optionsWidth / 2; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 461dbb12df05..68508a89debe 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -63,6 +63,29 @@ bool Room::loadRoom(byte *roomData) { return true; } +int Room::getOptionOffset(int option) { + switch (option) { + case 0: + return _walkTo; + case 1: + return _examine; + case 2: + return _pickup; + case 3: + return _use; + case 4: + return _pushOpen; + case 5: + return _pullClose; + case 6: + return _talk; + case 7: + return _give; + default: + error("Wrong option - nr %d", option); + } +} + /* void Room::loadMobs(Common::SeekableReadStream &stream) { debug("loadMobs %d", stream.pos()); @@ -205,8 +228,25 @@ uint8 *Script::getRoomOffset(int locationNr) { return &_data[_scriptInfo.rooms + locationNr * 64]; } -int Script::getOptionScript(int offset, int option) { - return (int)READ_UINT16(&_data[offset + option * 4]); +int32 Script::getOptionStandardOffset(int option) { + switch (option) { + case 0: + return _scriptInfo.stdExamine; + case 1: + return _scriptInfo.stdPickup; + case 2: + return _scriptInfo.stdUse; + case 3: + return _scriptInfo.stdOpen; + case 4: + return _scriptInfo.stdClose; + case 5: + return _scriptInfo.stdTalk; + case 6: + return _scriptInfo.stdGive; + default: + error("Wrong standard option - nr %d", option); + } } int Script::scanMobEvents(int mobMask, int dataEventOffset) { @@ -456,6 +496,14 @@ uint32 Interpreter::step(uint32 opcodePC) { return _currentInstruction; } +void Interpreter::storeNewPC(int opcodePC) { + if (_flags->getFlagValue(Flags::GETACTION) == 1) { + _flags->setFlagValue(Flags::GETACTIONDATA, opcodePC); + opcodePC = _flags->getFlagValue(Flags::GETACTIONBACK); + } + _fgOpcodePC = opcodePC; +} + template T Interpreter::readScript() { T data = _script->read(_currentInstruction); @@ -763,6 +811,8 @@ void Interpreter::O_SETSTRING() { // FIXME: Make it better ;) if (offset >= 80000) { debugInterpreter("GetVaria %s", _vm->_variaTxt->getString(offset - 80000)); + _string = (const byte *)_vm->_variaTxt->getString(offset - 80000); + _currentString = offset - 80000; // TODO - wrong sample } else if (offset < 2000) { uint32 of = READ_LE_UINT32(_vm->_talkTxt+offset*4); diff --git a/engines/prince/script.h b/engines/prince/script.h index 28e3be4ebc7e..19c64ba5b68b 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -68,6 +68,7 @@ class Room { bool loadFromStream(Common::SeekableReadStream &stream); bool loadRoom(byte *roomData); + int getOptionOffset(int option); private: @@ -135,7 +136,7 @@ class Script { int16 getLightY(int locationNr); int32 getShadowScale(int locationNr); uint8 *getRoomOffset(int locationNr); - int32 getOptionScript(int offset, int option); + int32 getOptionStandardOffset(int option); void installBackAnims(Common::Array &_backanimList, int offset); void installSingleBackAnim(Common::Array &_backanimList, int offset); bool loadAllMasks(Common::Array &maskList, int offset); @@ -177,6 +178,7 @@ class Interpreter { void stopBg() { _bgOpcodePC = 0; } void step(); + void storeNewPC(int opcodePC); private: PrinceEngine *_vm; From 12c5a6e6e2e556383fd825bac65edb460ccee058 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 26 Jun 2014 18:29:19 +0200 Subject: [PATCH 204/374] PRINCE: setVoice update, O_GETMOBTEXT(), O_SETSTRING() --- engines/prince/prince.cpp | 46 +++++++++++++++++++++++++-------- engines/prince/prince.h | 6 +++-- engines/prince/script.cpp | 54 +++++++++++++++++++++------------------ engines/prince/script.h | 3 ++- 4 files changed, 70 insertions(+), 39 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 5fd97fca7687..35619fdc1e30 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -593,6 +593,27 @@ bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::Strin return true; } +void PrinceEngine::setVoice(uint16 slot, uint32 sampleSlot, uint16 flag) { + Common::String sampleName; + uint32 currentString = _interpreter->getCurrentString(); + + if (currentString >= 80000) { + sampleName = Common::String::format("%05d-%02d.WAV", currentString - 80000, 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); +} + bool PrinceEngine::loadAnim(uint16 animNr, bool loop) { Common::String streamName = Common::String::format("AN%02d", animNr); Common::SeekableReadStream * flicStream = SearchMan.createReadStreamForMember(streamName); @@ -922,7 +943,7 @@ void PrinceEngine::showTexts(Graphics::Surface *screen) { _font->wordWrapText(text._str, _graph->_frontScreen->w, lines); int wideLine = 0; - for (uint8 i = 0; i < lines.size(); i++) { + for (uint i = 0; i < lines.size(); i++) { int textLen = getTextWidth(lines[i].c_str()); if (textLen > wideLine) { wideLine = textLen; @@ -1771,7 +1792,7 @@ void PrinceEngine::inventoryLeftMouseButton() { return; } } else { - // when this happens? + error("PrinceEngine::inventoryLeftMouseButton() - optionsFlag = 1, selectedMob = 0"); // test bx, RMBMask 7996 ? right mouse button here? - > return; //disable_use if (_currentPointerNumber == 2) { @@ -1800,12 +1821,13 @@ void PrinceEngine::inventoryLeftMouseButton() { //use_item_on_item int invObjUU = _script->scanMobEventsWithItem(_invMobList[_selectedMob - 1]._mask, _script->_scriptInfo.invObjUU, _selectedItem); if (invObjUU == -1) { - int textNr = 11; // "I can't do it." + int textNr = 80011; // "I can't do it." if (_selectedItem == 31 || _invMobList[_selectedMob - 1]._mask == 31) { - textNr = 20; // "Nothing is happening." + textNr = 80020; // "Nothing is happening." } - printAt(0, 216, _variaTxt->getString(textNr), kNormalWidth / 2, 100); - loadVoice(0, 28, Common::String::format("%05d-01.WAV", textNr)); + _interpreter->setCurrentString(textNr); + printAt(0, 216, _variaTxt->getString(textNr - 80000), kNormalWidth / 2, 100); + setVoice(0, 28, 1); playSample(28, 0); //exit_normally _selectedMob = 0; @@ -1829,7 +1851,8 @@ void PrinceEngine::inventoryLeftMouseButton() { if (invObjExamEvent == -1) { // do_standard printAt(0, 216, _invMobList[_selectedMob - 1]._examText.c_str(), kNormalWidth / 2, _invExamY); - loadVoice(0, 28, Common::String::format("inv%02d-01.WAV", _invMobList[_selectedMob - 1]._mask)); + _interpreter->setCurrentString(_invMobList[_selectedMob - 1]._mask + 70000); + setVoice(0, 28, 1); playSample(28, 0); // disableuseuse changeCursor(0); @@ -1873,12 +1896,13 @@ void PrinceEngine::inventoryLeftMouseButton() { // use_item_on_item int invObjUU = _script->scanMobEventsWithItem(_invMobList[_selectedMob - 1]._mask, _script->_scriptInfo.invObjUU, _selectedItem); if (invObjUU == -1) { - int textNr = 11; // "I can't do it." + int textNr = 80011; // "I can't do it." if (_selectedItem == 31 || _invMobList[_selectedMob - 1]._mask == 31) { - textNr = 20; // "Nothing is happening." + textNr = 80020; // "Nothing is happening." } - printAt(0, 216, _variaTxt->getString(textNr), kNormalWidth / 2, 100); - loadVoice(0, 28, Common::String::format("%05d-01.WAV", textNr)); + _interpreter->setCurrentString(textNr); + printAt(0, 216, _variaTxt->getString(textNr - 80000), kNormalWidth / 2, 100); + setVoice(0, 28, 1); playSample(28, 0); //exit_normally } else { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index de3809b92d34..28ef4b662a76 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -245,6 +245,8 @@ class PrinceEngine : public Engine { void playSample(uint16 sampleId, uint16 loopType); void stopSample(uint16 sampleId); + void setVoice(uint16 slot, uint32 sampleSlot, uint16 flag); + virtual GUI::Debugger *getDebugger(); void changeCursor(uint16 curId); @@ -258,6 +260,7 @@ class PrinceEngine : public Engine { Hero *_mainHero; Hero *_secondHero; + uint16 _locationNr; uint16 _sceneWidth; int32 _picWindowX; int32 _picWindowY; @@ -267,6 +270,7 @@ class PrinceEngine : public Engine { Common::Array _animList; Common::Array _backAnimList; Common::Array> _dialogBoxList; + Common::Array _mobList; Common::RandomSource _randomSource; @@ -391,7 +395,6 @@ class PrinceEngine : public Engine { uint32 getTextWidth(const char *s); void debugEngine(const char *s, ...); - uint16 _locationNr; uint8 _cursorNr; Common::RandomSource *_rnd; @@ -412,7 +415,6 @@ class PrinceEngine : public Engine { Audio::SoundHandle _soundHandle[MAX_SAMPLES]; Common::Array _pscrList; - Common::Array _mobList; Common::Array _objList; Common::Array _maskList; Common::Array _drawNodeList; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 68508a89debe..86d9b78cd52f 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -454,7 +454,7 @@ void Interpreter::debugInterpreter(const char *s, ...) { Common::String str = Common::String::format("@0x%08X: ", _lastInstruction); str += Common::String::format("op %04d: ", _lastOpcode); //debugC(10, DebugChannel::kScript, "PrinceEngine::Script %s %s", str.c_str(), buf); - + debug(10, "PrinceEngine::Script %s %s", str.c_str(), buf); //debug("Prince::Script frame %08ld mode %s %s %s", _vm->_frameNr, _mode, str.c_str(), buf); } @@ -504,6 +504,14 @@ void Interpreter::storeNewPC(int opcodePC) { _fgOpcodePC = opcodePC; } +uint32 Interpreter::getCurrentString() { + return _currentString; +} + +void Interpreter::setCurrentString(uint32 value) { + _currentString = value; +} + template T Interpreter::readScript() { T data = _script->read(_currentInstruction); @@ -808,11 +816,9 @@ void Interpreter::O_SETSTRING() { int32 offset = readScript(); _currentString = offset; - // FIXME: Make it better ;) if (offset >= 80000) { - debugInterpreter("GetVaria %s", _vm->_variaTxt->getString(offset - 80000)); _string = (const byte *)_vm->_variaTxt->getString(offset - 80000); - _currentString = offset - 80000; // TODO - wrong sample + debugInterpreter("GetVaria %s", _string); } else if (offset < 2000) { uint32 of = READ_LE_UINT32(_vm->_talkTxt+offset*4); @@ -886,10 +892,11 @@ void Interpreter::O_XORFLAG() { } void Interpreter::O_GETMOBTEXT() { - uint16 value = readScriptFlagValue(); + uint16 mob = readScriptFlagValue(); + _currentString = _vm->_locationNr * 100 + mob + 60001; + _string = (const byte *)_vm->_mobList[mob]._examText.c_str(); - debugInterpreter("O_GETMOBTEXT value %d", value); - // Use Mob::ExamText as current string + debugInterpreter("O_GETMOBTEXT mob %d", mob); } void Interpreter::O_MOVEHERO() { @@ -1517,42 +1524,39 @@ void Interpreter::O_SKIPTEXT() { debugInterpreter("O_SKIPTEXT"); } -void Interpreter::SetVoice(uint32 sampleSlot) { - uint16 slot = readScriptFlagValue(); - _vm->loadVoice( - slot, - sampleSlot, - Common::String::format( - "%03d-%02d.WAV", - _currentString, - _flags->getFlagValue(Flags::VOICE_H_LINE) - ) - ); -} - void Interpreter::O_SETVOICEH() { + uint16 slot = readScriptFlagValue(); static const uint32 VOICE_H_SLOT = 28; - SetVoice(VOICE_H_SLOT); + uint16 voiceLineH = _flags->getFlagValue(Flags::VOICE_H_LINE); + _vm->setVoice(slot, VOICE_H_SLOT, voiceLineH); } void Interpreter::O_SETVOICEA() { + uint16 slot = readScriptFlagValue(); static const uint32 VOICE_A_SLOT = 29; - SetVoice(VOICE_A_SLOT); + uint16 voiceLineH = _flags->getFlagValue(Flags::VOICE_H_LINE); + _vm->setVoice(slot, VOICE_A_SLOT, voiceLineH); } void Interpreter::O_SETVOICEB() { + uint16 slot = readScriptFlagValue(); static const uint32 VOICE_B_SLOT = 30; - SetVoice(VOICE_B_SLOT); + uint16 voiceLineH = _flags->getFlagValue(Flags::VOICE_H_LINE); + _vm->setVoice(slot, VOICE_B_SLOT, voiceLineH); } void Interpreter::O_SETVOICEC() { + uint16 slot = readScriptFlagValue(); static const uint32 VOICE_C_SLOT = 31; - SetVoice(VOICE_C_SLOT); + uint16 voiceLineH = _flags->getFlagValue(Flags::VOICE_H_LINE); + _vm->setVoice(slot, VOICE_C_SLOT, voiceLineH); } void Interpreter::O_SETVOICED() { + uint16 slot = readScriptFlagValue(); static const uint32 VOICE_D_SLOT = 32; - SetVoice(VOICE_D_SLOT); + uint16 voiceLineH = _flags->getFlagValue(Flags::VOICE_H_LINE); + _vm->setVoice(slot, VOICE_D_SLOT, voiceLineH); } void Interpreter::O_VIEWFLCLOOP() { diff --git a/engines/prince/script.h b/engines/prince/script.h index 19c64ba5b68b..f3e3b3cded50 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -179,6 +179,8 @@ class Interpreter { void step(); void storeNewPC(int opcodePC); + uint32 getCurrentString(); + void setCurrentString(uint32 value); private: PrinceEngine *_vm; @@ -216,7 +218,6 @@ class Interpreter { template T readScript(); void debugInterpreter(const char *s, ...); - void SetVoice(uint32 slot); typedef void (Interpreter::*OpcodeFunc)(); static OpcodeFunc _opcodes[]; From 011ecf0c6d291407ebf85a0156f8aca249adee2a Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 26 Jun 2014 23:58:33 +0200 Subject: [PATCH 205/374] PRINCE: Fix for hotspot() and change from 0 to -1 for empty _selectedMob --- engines/prince/prince.cpp | 77 +++++++++++++++++++++------------------ engines/prince/script.cpp | 18 +++++---- engines/prince/script.h | 1 + 3 files changed, 53 insertions(+), 43 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 35619fdc1e30..1ef70d0c4b72 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -84,7 +84,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _invLineSkipX(2), _invLineSkipY(3), _showInventoryFlag(false), _inventoryBackgroundRemember(false), _mst_shadow(0), _mst_shadow2(0), _candleCounter(0), _invX1(53), _invY1(18), _invWidth(536), _invHeight(438), _invCurInside(false), _optionsFlag(false), _optionEnabled(0), _invExamY(120), _invMaxCount(2), _invCounter(0), - _optionsMob(0), _currentPointerNumber(1), _selectedMob(0), _selectedItem(0), _selectedMode(0), + _optionsMob(-1), _currentPointerNumber(1), _selectedMob(-1), _selectedItem(0), _selectedMode(0), _optionsWidth(210), _optionsHeight(170), _invOptionsWidth(210), _invOptionsHeight(130), _optionsStep(20), _invOptionsStep(20), _optionsNumber(7), _invOptionsNumber(5), _optionsColor1(236), _optionsColor2(252), _dialogWidth(600), _dialogHeight(0), _dialogLineSpace(10), _dialogColor1(220), _dialogColor2(223), _dialogFlag(false) { @@ -400,6 +400,10 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mainHero->_lightY = _script->getLightY(_locationNr); _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); + for (uint i = 0; i < _mobList.size(); i++) { + _mobList[i]._visible = _script->getMobVisible(_room->_mobs, i); + } + clearBackAnimList(); _script->installBackAnims(_backAnimList, _room->_backAnim); @@ -421,7 +425,7 @@ void PrinceEngine::changeCursor(uint16 curId) { case 0: CursorMan.showMouse(false); _optionsFlag = 0; - _selectedMob = 0; + _selectedMob = -1; return; case 1: curSurface = _cursor1->getSurface(); @@ -810,6 +814,7 @@ int PrinceEngine::hotspot(Graphics::Surface *screen, Common::Array &mobList for (Common::Array::const_iterator it = mobList.begin(); it != mobList.end() ; it++) { const Mob& mob = *it; if (mob._visible != 0) { // 0 is for visible + i++; continue; } if (mob._rect.contains(mousePosCamera)) { @@ -860,11 +865,11 @@ int PrinceEngine::hotspot(Graphics::Surface *screen, Common::Array &mobList } _font->drawString(screen, mobName, x, y, screen->w, 216); - return i + 1; + return i; } i++; } - return 0; + return -1; } void PrinceEngine::printAt(uint32 slot, uint8 color, const char *s, uint16 x, uint16 y) { @@ -1718,7 +1723,7 @@ void PrinceEngine::leftMouseButton() { } } else { _optionsMob = _selectedMob; - if (_optionsMob == 0) { + if (_optionsMob == -1) { // @@walkto - TODO return; } @@ -1738,7 +1743,7 @@ void PrinceEngine::leftMouseButton() { //@@walkto - TODO return; } else { - optionEvent = _script->getOptionStandardOffset(option - 1); + optionEvent = _script->getOptionStandardOffset(option); } } } else if (_selectedMode != 0) { @@ -1762,8 +1767,8 @@ void PrinceEngine::leftMouseButton() { } _interpreter->storeNewPC(optionEvent); _flags->setFlagValue(Flags::CURRMOB, _selectedMob); - _selectedMob = 0; - _optionsMob = 0; + _selectedMob = -1; + _optionsMob = -1; } void PrinceEngine::rightMouseButton() { @@ -1783,7 +1788,7 @@ void PrinceEngine::inventoryLeftMouseButton() { if (_optionsFlag == 1) { //check_opt - if (_selectedMob != 0) { + if (_selectedMob != -1) { //inv_check_mob if (_optionEnabled < _invOptionsNumber) { _optionsFlag = 0; @@ -1800,17 +1805,17 @@ void PrinceEngine::inventoryLeftMouseButton() { changeCursor(1); _currentPointerNumber = 1; //exit_normally - _selectedMob = 0; - _optionsMob = 0; + _selectedMob = -1; + _optionsMob = -1; return; } else { return; } } } else { - if (_selectedMob != 0) { + if (_selectedMob != -1) { if (_currentPointerNumber != 2) { - if (_invMobList[_selectedMob - 1]._mask != 29) { + if (_invMobList[_selectedMob]._mask != 29) { _optionEnabled = 0; } else { // map item @@ -1819,10 +1824,10 @@ void PrinceEngine::inventoryLeftMouseButton() { //do_option } else { //use_item_on_item - int invObjUU = _script->scanMobEventsWithItem(_invMobList[_selectedMob - 1]._mask, _script->_scriptInfo.invObjUU, _selectedItem); + 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 - 1]._mask == 31) { + if (_selectedItem == 31 || _invMobList[_selectedMob]._mask == 31) { textNr = 80020; // "Nothing is happening." } _interpreter->setCurrentString(textNr); @@ -1830,13 +1835,13 @@ void PrinceEngine::inventoryLeftMouseButton() { setVoice(0, 28, 1); playSample(28, 0); //exit_normally - _selectedMob = 0; - _optionsMob = 0; + _selectedMob = -1; + _optionsMob = -1; return; } else { //store_new_pc // storeNewPC(); - _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob - 1]._mask); + _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask); //byeinv _showInventoryFlag = false; } @@ -1847,11 +1852,11 @@ void PrinceEngine::inventoryLeftMouseButton() { } //do_option if (_optionEnabled == 0) { - int invObjExamEvent = _script->scanMobEvents(_invMobList[_selectedMob - 1]._mask, _script->_scriptInfo.invObjExam); + int invObjExamEvent = _script->scanMobEvents(_invMobList[_selectedMob]._mask, _script->_scriptInfo.invObjExam); if (invObjExamEvent == -1) { // do_standard - printAt(0, 216, _invMobList[_selectedMob - 1]._examText.c_str(), kNormalWidth / 2, _invExamY); - _interpreter->setCurrentString(_invMobList[_selectedMob - 1]._mask + 70000); + printAt(0, 216, _invMobList[_selectedMob]._examText.c_str(), kNormalWidth / 2, _invExamY); + _interpreter->setCurrentString(_invMobList[_selectedMob]._mask + 70000); setVoice(0, 28, 1); playSample(28, 0); // disableuseuse @@ -1861,25 +1866,25 @@ void PrinceEngine::inventoryLeftMouseButton() { } else { //store_new_pc // storeNewPC(); - _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob - 1]._mask); + _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask); //bye_inv _showInventoryFlag = false; } } else if (_optionEnabled == 1) { // not_examine - int invObjUse = _script->scanMobEvents(_invMobList[_selectedMob - 1]._mask, _script->_scriptInfo.invObjUse); + int invObjUse = _script->scanMobEvents(_invMobList[_selectedMob]._mask, _script->_scriptInfo.invObjUse); if (invObjUse == -1) { // do_standard_use _selectedMode = 0; - _selectedItem = _invMobList[_selectedMob - 1]._mask; - makeInvCursor(_invMobList[_selectedMob - 1]._mask); + _selectedItem = _invMobList[_selectedMob]._mask; + makeInvCursor(_invMobList[_selectedMob]._mask); _currentPointerNumber = 2; changeCursor(2); //exit_normally } else { //store_new_pc // storeNewPC(); - _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob - 1]._mask); + _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask); //bye_inv _showInventoryFlag = false; } @@ -1887,17 +1892,17 @@ void PrinceEngine::inventoryLeftMouseButton() { // not_use_inv // do_standard_give _selectedMode = 1; - _selectedItem = _invMobList[_selectedMob - 1]._mask; - makeInvCursor(_invMobList[_selectedMob - 1]._mask); + _selectedItem = _invMobList[_selectedMob]._mask; + makeInvCursor(_invMobList[_selectedMob]._mask); _currentPointerNumber = 2; changeCursor(2); //exit_normally } else { // use_item_on_item - int invObjUU = _script->scanMobEventsWithItem(_invMobList[_selectedMob - 1]._mask, _script->_scriptInfo.invObjUU, _selectedItem); + 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 - 1]._mask == 31) { + if (_selectedItem == 31 || _invMobList[_selectedMob]._mask == 31) { textNr = 80020; // "Nothing is happening." } _interpreter->setCurrentString(textNr); @@ -1908,14 +1913,14 @@ void PrinceEngine::inventoryLeftMouseButton() { } else { //store_new_pc // storeNewPC(); - _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob - 1]._mask); + _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask); //byeinv _showInventoryFlag = false; } } //exit_normally - _selectedMob = 0; - _optionsMob = 0; + _selectedMob = -1; + _optionsMob = -1; } void PrinceEngine::inventoryRightMouseButton() { @@ -1928,7 +1933,7 @@ void PrinceEngine::enableOptions() { if (_optionsFlag != 1) { changeCursor(1); _currentPointerNumber = 1; - if (_selectedMob != 0) { + if (_selectedMob != -1) { //if (_mobType != 0x100) { Common::Point mousePos = _system->getEventManager()->getMousePos(); int x1 = mousePos.x - _optionsWidth / 2; @@ -1962,7 +1967,7 @@ void PrinceEngine::checkOptions() { Common::Point mousePos = _system->getEventManager()->getMousePos(); if (!optionsRect.contains(mousePos)) { _optionsFlag = 0; - _selectedMob = 0; + _selectedMob = -1; return; } _graph->drawAsShadowSurface(_graph->_frontScreen, _optionsX, _optionsY, _optionsPic, _graph->_shadowTable50); @@ -2009,7 +2014,7 @@ void PrinceEngine::checkInvOptions() { Common::Point mousePos = _system->getEventManager()->getMousePos(); if (!optionsRect.contains(mousePos)) { _optionsFlag = 0; - _selectedMob = 0; + _selectedMob = -1; return; } _graph->drawAsShadowSurface(_graph->_screenForInventory, _optionsX, _optionsY, _optionsPicInInventory, _graph->_shadowTable50); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 86d9b78cd52f..3ed3adba0dba 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -224,25 +224,29 @@ uint32 Script::getStartGameOffset() { return _scriptInfo.startGame; } +bool Script::getMobVisible(int roomMobOffset, int mobNr) { + return _data[roomMobOffset + mobNr]; +} + uint8 *Script::getRoomOffset(int locationNr) { return &_data[_scriptInfo.rooms + locationNr * 64]; } int32 Script::getOptionStandardOffset(int option) { switch (option) { - case 0: - return _scriptInfo.stdExamine; case 1: - return _scriptInfo.stdPickup; + return _scriptInfo.stdExamine; case 2: - return _scriptInfo.stdUse; + return _scriptInfo.stdPickup; case 3: - return _scriptInfo.stdOpen; + return _scriptInfo.stdUse; case 4: - return _scriptInfo.stdClose; + return _scriptInfo.stdOpen; case 5: - return _scriptInfo.stdTalk; + return _scriptInfo.stdClose; case 6: + return _scriptInfo.stdTalk; + case 7: return _scriptInfo.stdGive; default: error("Wrong standard option - nr %d", option); diff --git a/engines/prince/script.h b/engines/prince/script.h index f3e3b3cded50..44da67a99e2d 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -143,6 +143,7 @@ class Script { int scanMobEvents(int mobMask, int dataEventOffset); int scanMobEventsWithItem(int mobMask, int dataEventOffset, int itemMask); + bool getMobVisible(int roomMobOffset, int mobNr); const char *getString(uint32 offset) { return (const char *)(&_data[offset]); From 49de202a21cd5371119267c65b49727d236871ec Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 28 Jun 2014 09:51:14 +0200 Subject: [PATCH 206/374] PRINCE: O_CHANGEMOB(), getMobVisible(), setMobVisible() --- engines/prince/prince.cpp | 2 +- engines/prince/prince.h | 4 ++-- engines/prince/script.cpp | 19 ++++++++++++++----- engines/prince/script.h | 3 ++- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 1ef70d0c4b72..6e8847e78080 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -401,7 +401,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); for (uint i = 0; i < _mobList.size(); i++) { - _mobList[i]._visible = _script->getMobVisible(_room->_mobs, i); + _mobList[i]._visible = _script->getMobVisible(i); } clearBackAnimList(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 28ef4b662a76..be0d93109f03 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -266,6 +266,8 @@ class PrinceEngine : public Engine { int32 _picWindowY; Image::BitmapDecoder *_roomBmp; MhwanhDecoder *_suitcaseBmp; + Room *_room; + Script *_script; Common::Array _animList; Common::Array _backAnimList; @@ -403,12 +405,10 @@ class PrinceEngine : public Engine { Cursor *_cursor3; Debugger *_debugger; GraphicsMan *_graph; - Script *_script; InterpreterFlags *_flags; Interpreter *_interpreter; Font *_font; MusicPlayer *_midiPlayer; - Room *_room; static const uint32 MAX_SAMPLES = 60; Common::SeekableReadStream *_voiceStream[MAX_SAMPLES]; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 3ed3adba0dba..7806218df876 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -224,8 +224,12 @@ uint32 Script::getStartGameOffset() { return _scriptInfo.startGame; } -bool Script::getMobVisible(int roomMobOffset, int mobNr) { - return _data[roomMobOffset + mobNr]; +bool Script::getMobVisible(int mob) { + return _data[_vm->_room->_mobs + mob]; +} + +void Script::setMobVisible(int mob, int value) { + _data[_vm->_room->_mobs + mob] = value; } uint8 *Script::getRoomOffset(int locationNr) { @@ -458,7 +462,9 @@ void Interpreter::debugInterpreter(const char *s, ...) { Common::String str = Common::String::format("@0x%08X: ", _lastInstruction); str += Common::String::format("op %04d: ", _lastOpcode); //debugC(10, DebugChannel::kScript, "PrinceEngine::Script %s %s", str.c_str(), buf); - debug(10, "PrinceEngine::Script %s %s", str.c_str(), buf); + if (_mode == "fg") { + debug(10, "PrinceEngine::Script %s %s", str.c_str(), buf); + } //debug("Prince::Script frame %08ld mode %s %s %s", _vm->_frameNr, _mode, str.c_str(), buf); } @@ -536,7 +542,7 @@ Flags::Id Interpreter::readScriptFlagId() { } void Interpreter::O_WAITFOREVER() { - debugInterpreter("O_WAITFOREVER"); + //debugInterpreter("O_WAITFOREVER"); _opcodeNF = 1; _currentInstruction -= 2; } @@ -965,7 +971,10 @@ void Interpreter::O_CHANGEMOB() { uint16 mob = readScriptFlagValue(); uint16 value = readScriptFlagValue(); debugInterpreter("O_CHANGEMOB mob %d, value %d", mob, value); - // Probably sets mobs visible flag to value + + value ^= 1; + _vm->_script->setMobVisible(mob, value); + _vm->_mobList[mob]._visible = value; } void Interpreter::O_ADDINV() { diff --git a/engines/prince/script.h b/engines/prince/script.h index 44da67a99e2d..cd2186b744b1 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -143,7 +143,8 @@ class Script { int scanMobEvents(int mobMask, int dataEventOffset); int scanMobEventsWithItem(int mobMask, int dataEventOffset, int itemMask); - bool getMobVisible(int roomMobOffset, int mobNr); + bool getMobVisible(int mob); + void setMobVisible(int mob, int value); const char *getString(uint32 offset) { return (const char *)(&_data[offset]); From 6878b9bc526ebb5cac4edbaaa635f3305a321493 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 28 Jun 2014 17:10:12 +0200 Subject: [PATCH 207/374] PRINCE: increaseString(), loading mob exam text update --- engines/prince/mob.cpp | 4 +++- engines/prince/prince.cpp | 1 + engines/prince/script.cpp | 17 +++++++++++------ engines/prince/script.h | 3 +++ 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/engines/prince/mob.cpp b/engines/prince/mob.cpp index 7ddb13dc6426..27d7127ccddc 100644 --- a/engines/prince/mob.cpp +++ b/engines/prince/mob.cpp @@ -62,8 +62,10 @@ bool Mob::loadFromStream(Common::SeekableReadStream &stream) { stream.seek(examTextOffset); _examText.clear(); - while ((c = stream.readByte())) + do { + c = stream.readByte(); _examText += c; + } while (c != 255); stream.seek(pos + 32); return true; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 6e8847e78080..4afe1e8c157c 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2292,6 +2292,7 @@ void PrinceEngine::talkHero(int slot, const char *s) { text._str = s; text._x = x; text._y = y; + _interpreter->increaseString(); } // Test diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 7806218df876..910c8617067b 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -522,6 +522,13 @@ void Interpreter::setCurrentString(uint32 value) { _currentString = value; } +void Interpreter::increaseString() { + while (*_string) { + _string++; + } + _string++; +} + template T Interpreter::readScript() { T data = _script->read(_currentInstruction); @@ -831,8 +838,8 @@ void Interpreter::O_SETSTRING() { debugInterpreter("GetVaria %s", _string); } else if (offset < 2000) { - uint32 of = READ_LE_UINT32(_vm->_talkTxt+offset*4); - const char * txt = (const char *)&_vm->_talkTxt[of]; + uint32 of = READ_LE_UINT32(_vm->_talkTxt + offset * 4); + const char *txt = (const char *)&_vm->_talkTxt[of]; _string = &_vm->_talkTxt[of]; debugInterpreter("TalkTxt %d %s", of, txt); } @@ -1234,10 +1241,7 @@ void Interpreter::O_PRINTAT() { _vm->printAt(slot, color, (const char *)_string, fr1, fr2); - while (*_string) { - ++_string; - } - ++_string; + increaseString(); } void Interpreter::O_ZOOMIN() { @@ -1534,6 +1538,7 @@ void Interpreter::O_CLEARINVENTORY() { } void Interpreter::O_SKIPTEXT() { + increaseString(); debugInterpreter("O_SKIPTEXT"); } diff --git a/engines/prince/script.h b/engines/prince/script.h index cd2186b744b1..36fff1ceb995 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -181,9 +181,12 @@ class Interpreter { void step(); void storeNewPC(int opcodePC); + uint32 getCurrentString(); void setCurrentString(uint32 value); + void increaseString(); + private: PrinceEngine *_vm; Script *_script; From dc400682af7f6a3e2b9c5069c0879a033598cd0d Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 29 Jun 2014 15:54:07 +0200 Subject: [PATCH 208/374] PRINCE: hotspot() name change to checkMob() and update --- engines/prince/prince.cpp | 138 ++++++++++++++++++++++++-------------- engines/prince/prince.h | 2 +- 2 files changed, 88 insertions(+), 52 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 4afe1e8c157c..80e617798754 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -806,68 +806,102 @@ void PrinceEngine::keyHandler(Common::Event event) { } } -int PrinceEngine::hotspot(Graphics::Surface *screen, Common::Array &mobList) { +int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobList) { Common::Point mousepos = _system->getEventManager()->getMousePos(); Common::Point mousePosCamera(mousepos.x + _picWindowX, mousepos.y); - int i = 0; + int mobNumber = 0; for (Common::Array::const_iterator it = mobList.begin(); it != mobList.end() ; it++) { const Mob& mob = *it; + mobNumber++; + if (mob._visible != 0) { // 0 is for visible - i++; continue; } - if (mob._rect.contains(mousePosCamera)) { - Common::String mobName = mob._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); + int type = mob._type & 7; + switch (type) { + case 0: + case 1: + //normal_mob + if (!mob._rect.contains(mousePosCamera)) { + continue; + } + break; + case 3: + //mob_obj + continue; + break; + case 2: + case 5: + //check_ba_mob + if (_backAnimList[mob._mask]._seq._current != 0) { + int currentAnim = _backAnimList[mob._mask]._seq._currRelative; + Anim &backAnim = _backAnimList[mob._mask].backAnims[currentAnim]; + if (backAnim._state == 0) { + Common::Rect backAnimRect(backAnim._currX, backAnim._currY, backAnim._currX + backAnim._currW, backAnim._currY + backAnim._currH); + if (backAnimRect.contains(mousePosCamera)) { break; } } } + continue; + break; + default: + //not_part_ba + continue; + break; + } - uint16 textW = getTextWidth(mobName.c_str()); - - uint16 x = mousepos.x - textW / 2; - if (x > screen->w) { - x = 0; + Common::String mobName = mob._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; + } } + } - if (x + textW > screen->w) { - x = screen->w - textW; - } + uint16 textW = getTextWidth(mobName.c_str()); - uint16 y = mousepos.y - _font->getFontHeight(); - if (y > screen->h) { - y = _font->getFontHeight() - 2; - } + uint16 x = mousepos.x - textW / 2; + if (x > screen->w) { + x = 0; + } + + if (x + textW > screen->w) { + x = screen->w - textW; + } - _font->drawString(screen, mobName, x, y, screen->w, 216); - return i; + uint16 y = mousepos.y - _font->getFontHeight(); + if (y > screen->h) { + y = _font->getFontHeight() - 2; } - i++; + + _font->drawString(screen, mobName, x, y, screen->w, 216); + + return mobNumber - 1; } return -1; } @@ -1271,6 +1305,10 @@ void PrinceEngine::showBackAnims() { } shadowZ = z; + _backAnimList[i].backAnims[activeSubAnim]._currX = x; + _backAnimList[i].backAnims[activeSubAnim]._currY = y; + _backAnimList[i].backAnims[activeSubAnim]._currW = frameWidth; + _backAnimList[i].backAnims[activeSubAnim]._currH = frameHeight; Graphics::Surface *backAnimSurface = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrame(phaseFrameIndex); //still with memory leak showSprite(backAnimSurface, x, y, z, true); } @@ -1467,7 +1505,7 @@ void PrinceEngine::drawScreen() { if (!_inventoryBackgroundRemember && !_dialogFlag) { if (!_optionsFlag) { - _selectedMob = hotspot(_graph->_frontScreen, _mobList); + _selectedMob = checkMob(_graph->_frontScreen, _mobList); } showTexts(_graph->_frontScreen); checkOptions(); @@ -1735,8 +1773,6 @@ void PrinceEngine::leftMouseButton() { int optionScriptOffset = _room->getOptionOffset(option); if (optionScriptOffset != 0) { optionEvent = _script->scanMobEvents(_optionsMob, optionScriptOffset); - } else { - optionEvent = -1; } if (optionEvent == -1) { if (option == 0) { @@ -1840,7 +1876,7 @@ void PrinceEngine::inventoryLeftMouseButton() { return; } else { //store_new_pc - // storeNewPC(); + _interpreter->storeNewPC(invObjUU); _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask); //byeinv _showInventoryFlag = false; @@ -1865,7 +1901,7 @@ void PrinceEngine::inventoryLeftMouseButton() { //exit_normally } else { //store_new_pc - // storeNewPC(); + _interpreter->storeNewPC(invObjExamEvent); _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask); //bye_inv _showInventoryFlag = false; @@ -1883,7 +1919,7 @@ void PrinceEngine::inventoryLeftMouseButton() { //exit_normally } else { //store_new_pc - // storeNewPC(); + _interpreter->storeNewPC(invObjUse); _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask); //bye_inv _showInventoryFlag = false; @@ -1912,7 +1948,7 @@ void PrinceEngine::inventoryLeftMouseButton() { //exit_normally } else { //store_new_pc - // storeNewPC(); + _interpreter->storeNewPC(invObjUU); _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask); //byeinv _showInventoryFlag = false; @@ -2104,7 +2140,7 @@ void PrinceEngine::displayInventory() { showTexts(_graph->_screenForInventory); if (!_optionsFlag && _textSlots[0]._str == nullptr) { - _selectedMob = hotspot(_graph->_screenForInventory, _invMobList); + _selectedMob = checkMob(_graph->_screenForInventory, _invMobList); } checkInvOptions(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index be0d93109f03..e1da3ba41bb7 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -376,7 +376,7 @@ class PrinceEngine : public Engine { private: bool playNextFrame(); void keyHandler(Common::Event event); - int hotspot(Graphics::Surface *screen, Common::Array &mobList); + int checkMob(Graphics::Surface *screen, Common::Array &mobList); void drawScreen(); void showTexts(Graphics::Surface *screen); void init(); From 7ebcbea0f9b7dae6e7c8631cfa65e1e6437b3fbc Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 29 Jun 2014 17:56:25 +0200 Subject: [PATCH 209/374] PRINCE: Object, checkMob() update, prepareInventoryToView() fix --- engines/prince/object.cpp | 12 ++++++------ engines/prince/object.h | 2 ++ engines/prince/prince.cpp | 33 ++++++++++++++++++++++++--------- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/engines/prince/object.cpp b/engines/prince/object.cpp index 94d55b5716a0..86d4238bc0a2 100644 --- a/engines/prince/object.cpp +++ b/engines/prince/object.cpp @@ -32,8 +32,8 @@ namespace Prince { -Object::Object() : _surface(NULL), _x(0), _y(0), _z(0), _mask(0), - _zoomInSource(0), _zoomInLen(0), _zoomInAddr(0), _zoomInTime(0) +Object::Object() : _surface(NULL), _x(0), _y(0), _z(0), _mask(0), _width(0), + _height(0), _zoomInSource(0), _zoomInLen(0), _zoomInAddr(0), _zoomInTime(0) { } @@ -47,12 +47,12 @@ Object::~Object() { void Object::loadSurface(Common::SeekableReadStream &stream) { stream.skip(4); - int width = stream.readUint16LE(); - int height = stream.readUint16LE(); + _width = stream.readUint16LE(); + _height = stream.readUint16LE(); _surface = new Graphics::Surface(); - _surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); + _surface->create(_width, _height, Graphics::PixelFormat::createFormatCLUT8()); - for (int h = 0; h < _surface->h; ++h) { + for (int h = 0; h < _surface->h; h++) { stream.read(_surface->getBasePtr(0, h), _surface->w); } } diff --git a/engines/prince/object.h b/engines/prince/object.h index ea1ad9dc0d71..1fb7465a0db6 100644 --- a/engines/prince/object.h +++ b/engines/prince/object.h @@ -36,6 +36,8 @@ class Object { int32 _x; int32 _y; int32 _z; + uint16 _width; + uint16 _height; int32 _mask; // or flags int32 _zoomInSource; int32 _zoomInLen; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 80e617798754..83a471a6ed28 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -815,7 +815,7 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis const Mob& mob = *it; mobNumber++; - if (mob._visible != 0) { // 0 is for visible + if (mob._visible) { continue; } @@ -830,18 +830,35 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis break; case 3: //mob_obj + if (mob._mask < _objList.size()) { + Object &obj = *_objList[mob._mask]; + Common::Rect objectRect(obj._x, obj._y, obj._x + obj._width, obj._y + obj._height); + if (objectRect.contains(mousePosCamera)) { + Graphics::Surface *objSurface = obj.getSurface(); + byte *pixel = (byte *)objSurface->getBasePtr(mousePosCamera.x - obj._x, mousePosCamera.y - obj._y); + if (*pixel != 255) { + break; + } + } + } continue; break; case 2: case 5: //check_ba_mob - if (_backAnimList[mob._mask]._seq._current != 0) { + if (mob._mask < _backAnimList.size()) { int currentAnim = _backAnimList[mob._mask]._seq._currRelative; Anim &backAnim = _backAnimList[mob._mask].backAnims[currentAnim]; - if (backAnim._state == 0) { + if (!backAnim._state) { Common::Rect backAnimRect(backAnim._currX, backAnim._currY, backAnim._currX + backAnim._currW, backAnim._currY + backAnim._currH); if (backAnimRect.contains(mousePosCamera)) { - break; + int phase = backAnim._showFrame; + int phaseFrameIndex = backAnim._animData->getPhaseFrameIndex(phase); + Graphics::Surface *backAnimSurface = backAnim._animData->getFrame(phaseFrameIndex); + byte *pixel = (byte *)backAnimSurface->getBasePtr(mousePosCamera.x - backAnim._currX, mousePosCamera.y - backAnim._currY); + if (*pixel != 255) { + break; + } } } } @@ -1661,11 +1678,9 @@ void PrinceEngine::prepareInventoryToView() { if (item < _mainHero->_inventory.size()) { int itemNr = _mainHero->_inventory[item]; tempMobItem._visible = 0; - tempMobItem._mask = itemNr; // itemNr - 1?? - tempMobItem._rect.left = currInvX + _picWindowX; //picWindowX2 ? - tempMobItem._rect.right = currInvX + _picWindowX + _invLineW - 1; // picWindowX2 ? - tempMobItem._rect.top = currInvY; - tempMobItem._rect.bottom = currInvY + _invLineH - 1; + 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 = ""; From 191b4cc8beaa25be64366f2d35406eb299a1c26f Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 29 Jun 2014 20:39:40 +0200 Subject: [PATCH 210/374] PRINCE: Memory leaks fix - showBackAnim(), printAt(), checkMob()" --- engines/prince/graphics.cpp | 2 ++ engines/prince/prince.cpp | 26 ++++++++++++++++++-------- engines/prince/prince.h | 2 +- engines/prince/script.cpp | 8 ++++---- engines/prince/script.h | 2 +- engines/prince/variatxt.cpp | 4 ++-- engines/prince/variatxt.h | 2 +- 7 files changed, 29 insertions(+), 17 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index b86628009f33..c993cc890567 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -46,6 +46,8 @@ GraphicsMan::GraphicsMan(PrinceEngine *vm) GraphicsMan::~GraphicsMan() { _frontScreen->free(); delete _frontScreen; + _screenForInventory->free(); + delete _screenForInventory; delete[] _shadowTable70; delete[] _shadowTable50; } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 83a471a6ed28..0df1f778c659 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -140,6 +140,8 @@ PrinceEngine::~PrinceEngine() { } _maskList.clear(); + freeDrawNodes(); + clearBackAnimList(); for (uint i = 0; i < _allInvList.size(); i++) { @@ -404,6 +406,8 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mobList[i]._visible = _script->getMobVisible(i); } + freeDrawNodes(); + clearBackAnimList(); _script->installBackAnims(_backAnimList, _room->_backAnim); @@ -855,8 +859,10 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis int phase = backAnim._showFrame; int phaseFrameIndex = backAnim._animData->getPhaseFrameIndex(phase); Graphics::Surface *backAnimSurface = backAnim._animData->getFrame(phaseFrameIndex); - byte *pixel = (byte *)backAnimSurface->getBasePtr(mousePosCamera.x - backAnim._currX, mousePosCamera.y - backAnim._currY); - if (*pixel != 255) { + byte pixel = *(byte *)backAnimSurface->getBasePtr(mousePosCamera.x - backAnim._currX, mousePosCamera.y - backAnim._currY); + backAnimSurface->free(); + delete backAnimSurface; + if (pixel != 255) { break; } } @@ -923,13 +929,11 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis return -1; } -void PrinceEngine::printAt(uint32 slot, uint8 color, const char *s, uint16 x, uint16 y) { +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); - char *destStr = (char *)malloc(strlen(s)); - strcpy(destStr, s); - char *strPointer = destStr; + char *strPointer = s; if (getLanguage() == Common::DE_DEU) { while (*strPointer) { @@ -961,7 +965,7 @@ void PrinceEngine::printAt(uint32 slot, uint8 color, const char *s, uint16 x, ui } Text &text = _textSlots[slot]; - text._str = destStr; + text._str = s; text._x = x; text._y = y; text._color = color; @@ -1140,6 +1144,9 @@ void PrinceEngine::showSprite(Graphics::Surface *spriteSurface, int destX, int d newDrawNode.freeSurfaceSMemory = freeSurfaceMemory; newDrawNode.drawFunction = &_graph->drawTransparentDrawNode; _drawNodeList.push_back(newDrawNode); + } else if (freeSurfaceMemory) { + spriteSurface->free(); + delete spriteSurface; } } @@ -1159,6 +1166,9 @@ void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX, newDrawNode.freeSurfaceSMemory = freeSurfaceMemory; newDrawNode.drawFunction = &_graph->drawAsShadowDrawNode; _drawNodeList.push_back(newDrawNode); + } else if (freeSurfaceMemory) { + shadowSurface->free(); + delete shadowSurface; } } @@ -1906,7 +1916,7 @@ void PrinceEngine::inventoryLeftMouseButton() { int invObjExamEvent = _script->scanMobEvents(_invMobList[_selectedMob]._mask, _script->_scriptInfo.invObjExam); if (invObjExamEvent == -1) { // do_standard - printAt(0, 216, _invMobList[_selectedMob]._examText.c_str(), kNormalWidth / 2, _invExamY); + 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); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index e1da3ba41bb7..0d3bae26f6e1 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -250,7 +250,7 @@ class PrinceEngine : public Engine { virtual GUI::Debugger *getDebugger(); void changeCursor(uint16 curId); - void printAt(uint32 slot, uint8 color, const char *s, uint16 x, uint16 y); + void printAt(uint32 slot, uint8 color, char *s, uint16 x, uint16 y); int calcText(const char *s); static const uint8 MAXTEXTS = 32; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 910c8617067b..d5284034e2d0 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -462,7 +462,7 @@ void Interpreter::debugInterpreter(const char *s, ...) { Common::String str = Common::String::format("@0x%08X: ", _lastInstruction); str += Common::String::format("op %04d: ", _lastOpcode); //debugC(10, DebugChannel::kScript, "PrinceEngine::Script %s %s", str.c_str(), buf); - if (_mode == "fg") { + if (!strcmp(_mode, "fg")) { debug(10, "PrinceEngine::Script %s %s", str.c_str(), buf); } //debug("Prince::Script frame %08ld mode %s %s %s", _vm->_frameNr, _mode, str.c_str(), buf); @@ -834,7 +834,7 @@ void Interpreter::O_SETSTRING() { _currentString = offset; if (offset >= 80000) { - _string = (const byte *)_vm->_variaTxt->getString(offset - 80000); + _string = (byte *)_vm->_variaTxt->getString(offset - 80000); debugInterpreter("GetVaria %s", _string); } else if (offset < 2000) { @@ -911,7 +911,7 @@ void Interpreter::O_XORFLAG() { void Interpreter::O_GETMOBTEXT() { uint16 mob = readScriptFlagValue(); _currentString = _vm->_locationNr * 100 + mob + 60001; - _string = (const byte *)_vm->_mobList[mob]._examText.c_str(); + _string = (byte *)_vm->_mobList[mob]._examText.c_str(); debugInterpreter("O_GETMOBTEXT mob %d", mob); } @@ -1239,7 +1239,7 @@ void Interpreter::O_PRINTAT() { uint8 color = _flags->getFlagValue(Flags::KOLOR); - _vm->printAt(slot, color, (const char *)_string, fr1, fr2); + _vm->printAt(slot, color, (char *)_string, fr1, fr2); increaseString(); } diff --git a/engines/prince/script.h b/engines/prince/script.h index 36fff1ceb995..d550ebc9bf82 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -209,7 +209,7 @@ class Interpreter { //uint8 _savedStacktop; uint32 _waitFlag; - const byte *_string; + byte *_string; uint32 _currentString; const char *_mode; diff --git a/engines/prince/variatxt.cpp b/engines/prince/variatxt.cpp index fdca8c2c775b..56fbd2911a84 100644 --- a/engines/prince/variatxt.cpp +++ b/engines/prince/variatxt.cpp @@ -42,12 +42,12 @@ bool VariaTxt::loadFromStream(Common::SeekableReadStream &stream) { return true; } -const char *VariaTxt::getString(uint32 stringId) { +char *VariaTxt::getString(uint32 stringId) { uint32 stringOffset = READ_LE_UINT32(_data + stringId * 4); if (stringOffset > _dataSize) { assert(false); } - return (const char *)_data + stringOffset; + return (char *)_data + stringOffset; } } diff --git a/engines/prince/variatxt.h b/engines/prince/variatxt.h index 2a7a5fda9c56..b7fc7e3ac54a 100644 --- a/engines/prince/variatxt.h +++ b/engines/prince/variatxt.h @@ -32,7 +32,7 @@ class VariaTxt { bool loadFromStream(Common::SeekableReadStream &stream); - const char *getString(uint32 stringId); + char *getString(uint32 stringId); private: uint32 _dataSize; From 2b2170f88a0e0dd75fd1e8c7a40e34dcb7436e94 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 1 Jul 2014 20:12:43 +0200 Subject: [PATCH 211/374] PRINCE: O_SETDFLAG(), O_CALLDFLAG(), beginning of O_INITDIALOG() --- engines/prince/script.cpp | 174 ++++++++++++++++++++++++++++++-------- engines/prince/script.h | 1 + 2 files changed, 141 insertions(+), 34 deletions(-) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index d5284034e2d0..ed96e34dd526 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -572,7 +572,7 @@ void Interpreter::O_INITROOM() { void Interpreter::O_SETSAMPLE() { uint16 sampleId = readScriptFlagValue(); int32 sampleNameOffset = readScript(); - const char * sampleName = _script->getString(_currentInstruction + sampleNameOffset - 4); + const char *sampleName = _script->getString(_currentInstruction + sampleNameOffset - 4); debugInterpreter("O_SETSAMPLE %d %s", sampleId, sampleName); _vm->loadSample(sampleId, sampleName); } @@ -838,6 +838,7 @@ void Interpreter::O_SETSTRING() { debugInterpreter("GetVaria %s", _string); } else if (offset < 2000) { + //dialogDat -> dialogData uint32 of = READ_LE_UINT32(_vm->_talkTxt + offset * 4); const char *txt = (const char *)&_vm->_talkTxt[of]; _string = &_vm->_talkTxt[of]; @@ -1204,30 +1205,24 @@ void Interpreter::O_LOADPATH() { void Interpreter::O_GETCHAR() { Flags::Id flagId = readScriptFlagId(); - _flags->setFlagValue(flagId, *_string); - - debugInterpreter( - "O_GETCHAR %04X (%s) %02x", - flagId, - Flags::getFlagName(flagId), - _flags->getFlagValue(flagId)); - - ++_string; + debugInterpreter("O_GETCHAR %04X (%s) %02x", flagId, Flags::getFlagName(flagId), _flags->getFlagValue(flagId)); + _string++; } void Interpreter::O_SETDFLAG() { - uint16 flag = readScript(); - int32 offset = readScript(); - debugInterpreter("O_SETDFLAG flag %d, offset %04x", flag, offset); - // run this through debugger looks strange - // it looks like this one store two 16 bit value in one go + Flags::Id flagId = readScriptFlagId(); + int32 address = readScript(); + debugInterpreter("O_SETDFLAG 0x%04X (%s) = 0x%04X", flagId, Flags::getFlagName(flagId), _currentInstruction + address - 4); + _flags->setFlagValue((Flags::Id)(flagId), _currentInstruction + address - 4); } void Interpreter::O_CALLDFLAG() { - uint16 flag = readScript(); - debugInterpreter("O_CALLDFLAG flag %d", flag); - // it seems that some flags are 32 bit long + Flags::Id flagId = readScriptFlagId(); + _stack[_stacktop] = _currentInstruction; + _stacktop++; + _currentInstruction = _flags->getFlagValue(flagId); + debugInterpreter("O_CALLDFLAG 0x%04X (%s) = 0x%04X", flagId, Flags::getFlagName(flagId), _currentInstruction); } void Interpreter::O_PRINTAT() { @@ -1290,25 +1285,134 @@ void Interpreter::O_CHANGEHEROSET() { void Interpreter::O_ADDSTRING() { uint16 value = readScriptFlagValue(); debugInterpreter("O_ADDSTRING value %d", value); - // _string += value + _string += value; } void Interpreter::O_SUBSTRING() { uint16 value = readScriptFlagValue(); debugInterpreter("O_SUBSTRING value %d", value); - // _string -= value + _string -= value; +} + +int Interpreter::checkSeq(byte *string) { + int freeHSlotIncrease = 0; + byte c; + while (1) { + c = string[0]; + string++; + if (c < 0xF0) { + //not_spec + freeHSlotIncrease++; + while (1) { + c = string[0]; + if (c == 0) { + break; + } + string++; + } + string++; + continue; + } + if (c == 0xFF) { + break; + } + if (c == 0xFE) { + continue; // pause + } + string++; + } + return freeHSlotIncrease; } void Interpreter::O_INITDIALOG() { debugInterpreter("O_INITDIALOG"); - for (uint i = 0; i < _vm->_dialogBoxList.size(); i++) { - _vm->_dialogBoxList[i].clear(); - } - _vm->_dialogBoxList.clear(); + if (_string[0] == 255) { + byte *stringESI = _string; + byte *stringEBP = _string; + stringESI++; + int32 adressOfFirstSequence = *stringESI; // eax + stringESI += 2; + _string = stringEBP + adressOfFirstSequence; + + // like this? + for (uint i = 0; i < _vm->_dialogBoxList.size(); i++) { + _vm->_dialogBoxList[i].clear(); + } + _vm->_dialogBoxList.clear(); + + // to global + byte *dialogBoxAddr[32]; // adresses of dialog windows + byte *dialogOptAddr[32]; // adresses of dialog options + int dialogOptLines[4 * 32]; // numbers of initial dialog lines - // cut string to dialogs - // cut dialogs to nr and lines - // push them to dialogBoxList + for (int i = 0; i < 32; i++) { + dialogBoxAddr[i] = 0; + dialogOptAddr[i] = 0; + } + + for (int i = 0; i < 4 * 32; i++) { + dialogOptLines[i] = 0; + } + + //loop_1 + int16 c; + byte *eax; + int edi = 0; + while (1) { + c = (int)READ_UINT16(stringESI); + stringESI += 2; + if (c == -1) { + break; + } + if (c != 0) { + eax = stringEBP + c; + } + dialogBoxAddr[edi] = eax; + edi++; + } + //box_done: + edi = 0; + while (1) { + c = (int)READ_UINT16(stringESI); + stringESI += 2; + if (c == -1) { + break; + } + if (c != 0) { + eax = stringEBP + c; + } + dialogOptAddr[edi] = eax; + edi++; + } + //opt_done + int freeASlot = 0; + int freeBSlot = 0; + _flags->setFlagValue(Flags::VOICE_A_LINE, 0); + _flags->setFlagValue(Flags::VOICE_B_LINE, 0); // bx in original? + + int freeHSlot = 0; + //check + for (int i = 31; i >= 0; i--) { + if (dialogOptAddr[i] != 0) { + // or i++ before break here? + debug("%s", (char *)dialogOptAddr[i]); + freeHSlot = i; + _flags->setFlagValue(Flags::VOICE_H_LINE, i); + break; + } + } + + freeHSlot += checkSeq(_string); + + for (int i = 0; i < 32; i++) { + dialogOptLines[i * 4] = freeHSlot; + dialogOptLines[i * 4 + 1] = freeHSlot; + dialogOptLines[i * 4 + 2] = freeHSlot; + if (dialogOptAddr[i]) { + freeHSlot += checkSeq(dialogOptAddr[i]); + } + } + } } void Interpreter::O_ENABLEDIALOGOPT() { @@ -1324,13 +1428,15 @@ void Interpreter::O_DISABLEDIALOGOPT() { void Interpreter::O_SHOWDIALOGBOX() { uint16 box = readScriptFlagValue(); debugInterpreter("O_SHOWDIALOGBOX box %d", box); - _vm->createDialogBox(_vm->_dialogBoxList[box]); - int dialogLines = _vm->_dialogBoxList[box].size(); - _flags->setFlagValue(Flags::DIALINES, dialogLines); - if (dialogLines != 0) { - _vm->changeCursor(1); - _vm->runDialog(_vm->_dialogBoxList[box]); - _vm->changeCursor(0); + if (box < _vm->_dialogBoxList.size()) { + _vm->createDialogBox(_vm->_dialogBoxList[box]); + int dialogLines = _vm->_dialogBoxList[box].size(); + _flags->setFlagValue(Flags::DIALINES, dialogLines); + if (dialogLines != 0) { + _vm->changeCursor(1); + _vm->runDialog(_vm->_dialogBoxList[box]); + _vm->changeCursor(0); + } } } diff --git a/engines/prince/script.h b/engines/prince/script.h index d550ebc9bf82..ddb68087f419 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -218,6 +218,7 @@ class Interpreter { uint16 readScriptFlagValue(); Flags::Id readScriptFlagId(); + int checkSeq(byte *string); // instantiation not needed here template T readScript(); From 6657a7d8cc4458026eba354fbdd459a704ba82d0 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 1 Jul 2014 20:44:56 +0200 Subject: [PATCH 212/374] PRINCE: O_SETBACKANIMDATA(), O_GETBACKANIMDATA() --- engines/prince/prince.h | 30 ++++++++++++++++++++++++++++++ engines/prince/script.cpp | 23 ++++++++++++++--------- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 0d3bae26f6e1..d6bdad376f46 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -137,6 +137,36 @@ struct Anim { int16 _relY; Animation *_animData; Animation *_shadowData; + + enum AnimOffsets { + kAnimState = 10, + kAnimFrame = 14, + kAnimLastFrame = 16, + kAnimX = 26 + }; + + int16 getAnimData(Anim::AnimOffsets offset) { + switch (offset) { + case kAnimState: + return _state; + case kAnimFrame: + return _frame; + case kAnimLastFrame: + return _lastFrame; + case kAnimX: + return _x; + default: + error("getAnimData() - Wrong offset type: %d", (int) offset); + } + } + + void setAnimData(Anim::AnimOffsets offset, int16 value) { + if (offset == kAnimX) { + _x = value; + } else { + error("setAnimData() - Wrong offset: %d, value: %d", (int) offset, value); + } + } }; struct BackgroundAnim { diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index ed96e34dd526..ade79f007124 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1152,10 +1152,13 @@ void Interpreter::O_CHANGEBACKFRAMES() { } void Interpreter::O_GETBACKANIMDATA() { - uint16 flag = readScript(); - uint16 anim = readScript(); - uint16 animOffset = readScript(); - debugInterpreter("O_GETBACKANIMDATA flag %d, anim %d, animOffset %d", flag, anim, animOffset); + Flags::Id flagId = readScriptFlagId(); + uint16 animNumber = readScript(); + uint16 animDataOffset = readScript(); + int currAnim = _vm->_backAnimList[animNumber]._seq._currRelative; + int16 value = _vm->_backAnimList[animNumber].backAnims[currAnim].getAnimData((Anim::AnimOffsets)(animDataOffset)); + _flags->setFlagValue((Flags::Id)(flagId), value); + debugInterpreter("O_GETBACKANIMDATA flag %04X (%s), animNumber %d, animDataOffset %d, value %d", flagId, Flags::getFlagName(flagId), animNumber, animDataOffset, value); } void Interpreter::O_GETANIMDATA() { @@ -1557,11 +1560,13 @@ void Interpreter::O_RUNHERO() { } void Interpreter::O_SETBACKANIMDATA() { - uint16 animId = readScriptFlagValue(); - uint16 animOffset = readScriptFlagValue(); - uint16 wart = readScriptFlagValue(); - - debugInterpreter("O_SETBACKANIMDATA animId %d, animOffset %d, wart %d", animId, animOffset, wart); + uint16 animNumber = readScript(); + uint16 animDataOffset = readScript(); + Flags::Id flagId = readScriptFlagId(); + uint16 value = _flags->getFlagValue((Flags::Id)(flagId)); + int currAnim = _vm->_backAnimList[animNumber]._seq._currRelative; + _vm->_backAnimList[animNumber].backAnims[currAnim].setAnimData((Anim::AnimOffsets)(animDataOffset), value); + debugInterpreter("O_SETBACKANIMDATA flag %04X (%s), animNumber %d, animDataOffset %d, value %d", flagId, Flags::getFlagName(flagId), animNumber, animDataOffset, value); } void Interpreter::O_VIEWFLC() { From aaa2696e48f60ee8ea5020d1d80068e80d42072f Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 1 Jul 2014 21:26:53 +0200 Subject: [PATCH 213/374] PRINCE: O_BACKANIMRANGE() --- engines/prince/script.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index ade79f007124..4dbc6df864a5 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1461,8 +1461,21 @@ void Interpreter::O_BACKANIMRANGE() { } } - debugInterpreter("O_BACKANIMRANGE slotId %d, animId %d, low %d, high %d", slotId, animId, low, high); _result = 1; + if (slotId < _vm->_backAnimList.size()) { + if (animId == 0xFFFF || _vm->_backAnimList[slotId]._seq._current == animId) { + int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; + Anim &backAnim = _vm->_backAnimList[slotId].backAnims[currAnim]; + if (!backAnim._state) { + if (backAnim._frame >= low) { + if (backAnim._frame <= high) { + _result = 0; + } + } + } + } + } + debugInterpreter("O_BACKANIMRANGE slotId %d, animId %d, low %d, high %d, _result %d", slotId, animId, low, high, _result); } void Interpreter::O_CLEARPATH() { From c4593a4b23b55b303e650ad1946fa30a4163f0e6 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 1 Jul 2014 21:54:33 +0200 Subject: [PATCH 214/374] PRINCE: O_CHECKBACKANIMFRAME, O_CHANGEBACKFRAMES(), O_BACKANIMUPDATEON(), O_BACKANIMUPDATEOFF() --- engines/prince/script.cpp | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 4dbc6df864a5..5d8ba5d996f3 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -648,9 +648,12 @@ void Interpreter::O_REMBACKANIM() { void Interpreter::O_CHECKBACKANIMFRAME() { uint16 slotId = readScriptFlagValue(); uint16 frameId = readScriptFlagValue(); - - debugInterpreter("O_CHECKBACKANIMFRAME slotId %d, frameId %d", slotId, frameId); - _opcodeNF = 1; + int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; + if (_vm->_backAnimList[slotId].backAnims[currAnim]._frame != frameId) { + debugInterpreter("O_CHECKBACKANIMFRAME slotId %d, frameId %d", slotId, frameId); + //esi -= 6; loop of this OP? + _opcodeNF = 1; + } } void Interpreter::O_FREEALLSAMPLES() { @@ -736,12 +739,16 @@ void Interpreter::O_GO() { void Interpreter::O_BACKANIMUPDATEOFF() { uint16 slotId = readScriptFlagValue(); + int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; + _vm->_backAnimList[slotId].backAnims[currAnim]._state = 1; debugInterpreter("O_BACKANIMUPDATEOFF slotId %d", slotId); } void Interpreter::O_BACKANIMUPDATEON() { - uint16 slot = readScriptFlagValue(); - debugInterpreter("O_BACKANIMUPDATEON %d", slot); + uint16 slotId = readScriptFlagValue(); + int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; + _vm->_backAnimList[slotId].backAnims[currAnim]._state = 1; + debugInterpreter("O_BACKANIMUPDATEON %d", slotId); } void Interpreter::O_CHANGECURSOR() { @@ -1127,14 +1134,7 @@ void Interpreter::O_CHANGEFRAMES() { uint16 frame = readScriptFlagValue(); uint16 lastFrame = readScriptFlagValue(); uint16 loopFrame = readScriptFlagValue(); - - debugInterpreter( - "O_CHANGFRAMES anim %d, fr1 %d, fr2 %d, fr3 %d", - anim, - frame, - lastFrame, - loopFrame); - + debugInterpreter("O_CHANGFRAMES anim %d, fr1 %d, fr2 %d, fr3 %d", anim, frame, lastFrame, loopFrame); } void Interpreter::O_CHANGEBACKFRAMES() { @@ -1142,13 +1142,12 @@ void Interpreter::O_CHANGEBACKFRAMES() { uint16 frame = readScriptFlagValue(); uint16 lastFrame = readScriptFlagValue(); uint16 loopFrame = readScriptFlagValue(); - - debugInterpreter( - "O_CHANGEBACKFRAMES anim %d, fr1 %d, fr2 %d, fr3 %d", - anim, - frame, - lastFrame, - loopFrame); + int currAnim = _vm->_backAnimList[anim]._seq._currRelative; + Anim &backAnim = _vm->_backAnimList[anim].backAnims[currAnim]; + backAnim._frame = frame; + backAnim._lastFrame = lastFrame; + backAnim._loopFrame = loopFrame; + debugInterpreter("O_CHANGEBACKFRAMES anim %d, frame %d, lastFrame %d, loopFrame %d", anim, frame, lastFrame, loopFrame); } void Interpreter::O_GETBACKANIMDATA() { From f2b28363acb689ccde227bdbad1688e088afeebd Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 1 Jul 2014 23:59:37 +0200 Subject: [PATCH 215/374] PRINCE: showAnim(), showNormAnims(), freeNormAnim(), freeAllNormAnims(), O_SHOWANIM(), O_FREEANIM() --- engines/prince/prince.cpp | 131 ++++++++++++++++++++++++++++++++++++++ engines/prince/prince.h | 8 +++ engines/prince/script.cpp | 30 ++++++++- 3 files changed, 167 insertions(+), 2 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 0df1f778c659..ddf64b7b523a 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -144,6 +144,8 @@ PrinceEngine::~PrinceEngine() { clearBackAnimList(); + freeAllNormAnims(); + for (uint i = 0; i < _allInvList.size(); i++) { _allInvList[i]._surface->free(); delete _allInvList[i]._surface; @@ -272,6 +274,13 @@ void PrinceEngine::init() { _mainHero->loadAnimSet(1); _secondHero->loadAnimSet(3); + + Anim tempAnim; + tempAnim._animData = nullptr; + tempAnim._shadowData = nullptr; + for (int i = 0; i < kMaxNormAnims; i++) { + _normAnimList.push_back(tempAnim); + } } void PrinceEngine::showLogo() { @@ -1172,6 +1181,105 @@ void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX, } } +void PrinceEngine::showAnim(Anim &anim) { + //ShowFrameCode + //ShowAnimFrame + int phaseCount = anim._animData->getPhaseCount(); + int frameCount = anim._animData->getFrameCount(); + 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; + int frameWidth = anim._animData->getFrameWidth(phaseFrameIndex); + int frameHeight = anim._animData->getFrameHeight(phaseFrameIndex); + int shadowZ = 0; + + if (x != 0 || y != 0 || phaseCount != 1 || frameCount != 1) { // TODO - check if this needed + + if (checkMaskFlag != 0) { + if (anim._nextAnim == 0) { + z = y + frameHeight - 1; + } + checkMasks(x, y, frameWidth, frameHeight, z); + } + + if (specialZFlag != 0) { + z = specialZFlag; + } else if (maxFrontFlag != 0) { + z = kMaxPicHeight + 1; + } else { + z = y + frameHeight - 1; + } + shadowZ = z; + + anim._currX = x; + anim._currY = y; + anim._currW = frameWidth; + anim._currH = frameHeight; + Graphics::Surface *backAnimSurface = anim._animData->getFrame(phaseFrameIndex); // TODO - check for memory leak + showSprite(backAnimSurface, x, y, z, true); + } + + //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); + int shadowFrameWidth = anim._shadowData->getFrameWidth(shadowPhaseFrameIndex); + int shadowFrameHeight = anim._shadowData->getFrameHeight(shadowPhaseFrameIndex); + + if (checkMaskFlag != 0) { + checkMasks(shadowX, shadowY, shadowFrameWidth, shadowFrameHeight, shadowY + shadowFrameWidth - 1); + } + + if (shadowZ == 0) { + if (maxFrontFlag != 0) { + shadowZ = kMaxPicHeight + 1; + } else { + shadowZ = shadowY + shadowFrameWidth - 1; + } + } + + Graphics::Surface *shadowSurface = anim._shadowData->getFrame(shadowPhaseFrameIndex); // TODO - check for memory leak + showSpriteShadow(shadowSurface, shadowX, shadowY, shadowZ, true); + } +} + +void PrinceEngine::showNormAnims() { + for (int i = 0; i < kMaxNormAnims; i++) { + Anim &anim = _normAnimList[i]; + if (anim._animData != nullptr) { + if (!anim._state) { + if (anim._frame == anim._lastFrame) { + if (anim._loopType) { + if (anim._loopType == 1) { + anim._frame = anim._loopFrame; + } else { + continue; + } + } else { + if (anim._frame >= 1) { + anim._frame--; + } else { + anim._frame = 0; + } + } + } else { + anim._frame++; + } + anim._showFrame = anim._frame; + showAnim(anim); + } + } + } +} + void PrinceEngine::showBackAnims() { for (uint i = 0; i < _backAnimList.size(); i++) { int activeSubAnim = _backAnimList[i]._seq._currRelative; @@ -1507,6 +1615,8 @@ void PrinceEngine::drawScreen() { } } + showNormAnims(); + showBackAnims(); showObjects(); @@ -2387,6 +2497,27 @@ void PrinceEngine::testDialog() { } } +void PrinceEngine::freeNormAnim(int slot) { + _normAnimList[slot]._state = 1; + delete _normAnimList[slot]._animData; + _normAnimList[slot]._animData = nullptr; + delete _normAnimList[slot]._shadowData; + _normAnimList[slot]._shadowData = nullptr; + _normAnimList[slot]._currFrame = 0; +} + +void PrinceEngine::freeAllNormAnims() { + for (int i = 0; i < kMaxNormAnims; i++) { + if (_normAnimList[i]._animData != nullptr) { + delete _normAnimList[i]._animData; + } + if (_normAnimList[i]._shadowData != nullptr) { + delete _normAnimList[i]._shadowData; + } + } + _normAnimList.clear(); +} + void PrinceEngine::mainLoop() { changeCursor(0); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index d6bdad376f46..fdf5aa15b84d 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -299,11 +299,17 @@ class PrinceEngine : public Engine { Room *_room; Script *_script; + static const int kMaxNormAnims = 64; + Common::Array _animList; Common::Array _backAnimList; + Common::Array _normAnimList; Common::Array> _dialogBoxList; Common::Array _mobList; + void freeNormAnim(int slot); + void freeAllNormAnims(); + Common::RandomSource _randomSource; static const int16 kNormalWidth = 640; @@ -411,6 +417,8 @@ class PrinceEngine : public Engine { void showTexts(Graphics::Surface *screen); void init(); void showLogo(); + void showAnim(Anim &anim); + void showNormAnims(); void showBackAnims(); void clearBackAnimList(); bool spriteCheck(int sprWidth, int sprHeight, int destX, int destY); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 5d8ba5d996f3..37f6724b369e 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -606,7 +606,32 @@ void Interpreter::O_REMOBJECT() { void Interpreter::O_SHOWANIM() { uint16 slot = readScriptFlagValue(); uint16 animId = readScriptFlagValue(); - + _vm->freeNormAnim(slot); + Anim &anim = _vm->_normAnimList[slot]; + AnimListItem &animList = _vm->_animList[animId]; + anim._currFrame = 0; + anim._packFlag = 0; + anim._state = 0; + anim._frame = animList._startPhase; + anim._showFrame = animList._startPhase; + anim._lastFrame = animList._endPhase; + anim._loopFrame = animList._loopPhase; + anim._x = animList._x; + anim._y = animList._y; + anim._loopType = animList._loopType; + anim._shadowBack = animList._type; + anim._flags = animList._flags; + anim._nextAnim = animList._nextAnim; + int fileNumber = animList._fileNumber; + const Common::String animName = Common::String::format("AN%02d", fileNumber); + const Common::String shadowName = Common::String::format("AN%02dS", fileNumber); + anim._animData = new Animation(); + anim._shadowData = new Animation(); + Resource::loadResource(anim._animData, animName.c_str(), true); + if (!Resource::loadResource(anim._shadowData, shadowName.c_str(), false)) { + delete anim._shadowData; + anim._shadowData = nullptr; + } debugInterpreter("O_SHOWANIM slot %d, animId %d", slot, animId); } @@ -620,6 +645,7 @@ void Interpreter::O_CHECKANIMEND() { void Interpreter::O_FREEANIM() { uint16 slot = readScriptFlagValue(); + _vm->freeNormAnim(slot); debugInterpreter("O_FREEANIM slot %d", slot); } @@ -650,10 +676,10 @@ void Interpreter::O_CHECKBACKANIMFRAME() { uint16 frameId = readScriptFlagValue(); int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; if (_vm->_backAnimList[slotId].backAnims[currAnim]._frame != frameId) { - debugInterpreter("O_CHECKBACKANIMFRAME slotId %d, frameId %d", slotId, frameId); //esi -= 6; loop of this OP? _opcodeNF = 1; } + debugInterpreter("O_CHECKBACKANIMFRAME slotId %d, frameId %d", slotId, frameId); } void Interpreter::O_FREEALLSAMPLES() { From ad8df751c35364d7de23a7d1b4fdb4d9ad678cd5 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 2 Jul 2014 02:06:45 +0200 Subject: [PATCH 216/374] PRINCE: setBackAnim(), showBackAnims() update --- engines/prince/prince.cpp | 223 ++++++++++---------------------------- engines/prince/prince.h | 1 + 2 files changed, 58 insertions(+), 166 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index ddf64b7b523a..d876f8aa53d4 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1280,198 +1280,89 @@ void PrinceEngine::showNormAnims() { } } +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 (uint i = 0; i < _backAnimList.size(); i++) { - int activeSubAnim = _backAnimList[i]._seq._currRelative; - - if (_backAnimList[i].backAnims[activeSubAnim]._state == 0) { - _backAnimList[i]._seq._counter++; - if (_backAnimList[i]._seq._type == 2) { - //not_type_1 - if (_backAnimList[i]._seq._currRelative == 0) { - //zero - if (_backAnimList[i]._seq._counter >= _backAnimList[i]._seq._data) { - if (_backAnimList[i]._seq._anims > 2) { - int rnd = _randomSource.getRandomNumber(_backAnimList[i]._seq._anims - 2); - rnd++; - _backAnimList[i]._seq._currRelative = rnd; - _backAnimList[i]._seq._current = _backAnimList[i].backAnims[rnd]._basaData._num; - activeSubAnim = rnd; + BAS &seq = _backAnimList[i]._seq; + int activeSubAnim = seq._currRelative; + + 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; } - //only_1_type_2 - //SetBackAnim - int start = _backAnimList[i].backAnims[activeSubAnim]._basaData._start; - if (start != -1) { - _backAnimList[i].backAnims[activeSubAnim]._frame = start; - _backAnimList[i].backAnims[activeSubAnim]._showFrame = start; - _backAnimList[i].backAnims[activeSubAnim]._loopFrame = start; - } - int end = _backAnimList[i].backAnims[activeSubAnim]._basaData._end; - if (end != -1) { - _backAnimList[i].backAnims[activeSubAnim]._lastFrame = end; - } - _backAnimList[i]._seq._counter = 0; - _backAnimList[i].backAnims[activeSubAnim]._state = 0; + setBackAnim(_backAnimList[i].backAnims[activeSubAnim]); + seq._counter = 0; } } } - //not_type_2_1: - if (_backAnimList[i]._seq._type == 3) { - if (_backAnimList[i]._seq._currRelative == 0) { - if (_backAnimList[i]._seq._counter < _backAnimList[i]._seq._data2) { - //empty_frame - do not show anything + if (seq._type == 3) { + if (!seq._currRelative) { + if (seq._counter < seq._data2) { continue; } else { - //SetBackAnim - int start = _backAnimList[i].backAnims[activeSubAnim]._basaData._start; - if (start != -1) { - _backAnimList[i].backAnims[activeSubAnim]._frame = start; - _backAnimList[i].backAnims[activeSubAnim]._showFrame = start; - _backAnimList[i].backAnims[activeSubAnim]._loopFrame = start; - } - int end = _backAnimList[i].backAnims[activeSubAnim]._basaData._end; - if (end != -1) { - _backAnimList[i].backAnims[activeSubAnim]._lastFrame = end; - } - _backAnimList[i].backAnims[activeSubAnim]._state = 0; + setBackAnim(_backAnimList[i].backAnims[activeSubAnim]); } } } - //not_type_3_1: - //show_bugger + if (_backAnimList[i].backAnims[activeSubAnim]._frame == _backAnimList[i].backAnims[activeSubAnim]._lastFrame - 1) { - //loop_back_anim _backAnimList[i].backAnims[activeSubAnim]._frame = _backAnimList[i].backAnims[activeSubAnim]._loopFrame; - //change_back_anim - if (_backAnimList[i]._seq._type == 1) { - //repeat_rnd - if (_backAnimList[i]._seq._anims > 1) { + switch (seq._type) { + case 1: + if (seq._anims > 1) { int rnd; do { - rnd = _randomSource.getRandomNumber(_backAnimList[i]._seq._anims - 1); - } while (rnd == _backAnimList[i]._seq._currRelative); - _backAnimList[i]._seq._currRelative = rnd; - _backAnimList[i]._seq._current = _backAnimList[i].backAnims[rnd]._basaData._num; + rnd = _randomSource.getRandomNumber(seq._anims - 1); + } while (rnd == seq._currRelative); + seq._currRelative = rnd; + seq._current = _backAnimList[i].backAnims[rnd]._basaData._num; activeSubAnim = rnd; - //only_1_type_1: - //SetBackAnim - int start = _backAnimList[i].backAnims[activeSubAnim]._basaData._start; - if (start != -1) { - _backAnimList[i].backAnims[activeSubAnim]._frame = start; - _backAnimList[i].backAnims[activeSubAnim]._showFrame = start; - _backAnimList[i].backAnims[activeSubAnim]._loopFrame = start; - } - int end = _backAnimList[i].backAnims[activeSubAnim]._basaData._end; - if (end != -1) { - _backAnimList[i].backAnims[activeSubAnim]._lastFrame = end; - } - _backAnimList[i]._seq._counter = 0; - _backAnimList[i].backAnims[activeSubAnim]._state = 0; + setBackAnim(_backAnimList[i].backAnims[activeSubAnim]); + seq._counter = 0; } - } else if (_backAnimList[i]._seq._type == 2) { - if (_backAnimList[i]._seq._currRelative != 0) { - _backAnimList[i]._seq._currRelative = 0; - _backAnimList[i]._seq._current = _backAnimList[i].backAnims[0]._basaData._num; + break; + case 2: + if (seq._currRelative) { + seq._currRelative = 0; + seq._current = _backAnimList[i].backAnims[0]._basaData._num; activeSubAnim = 0; - //only_1_type_1 - //SetBackAnim - int start = _backAnimList[i].backAnims[activeSubAnim]._basaData._start; - if (start != -1) { - _backAnimList[i].backAnims[activeSubAnim]._frame = start; - _backAnimList[i].backAnims[activeSubAnim]._showFrame = start; - _backAnimList[i].backAnims[activeSubAnim]._loopFrame = start; - } - int end = _backAnimList[i].backAnims[activeSubAnim]._basaData._end; - if (end != -1) { - _backAnimList[i].backAnims[activeSubAnim]._lastFrame = end; - } - _backAnimList[i]._seq._counter = 0; - _backAnimList[i].backAnims[activeSubAnim]._state = 0; + setBackAnim(_backAnimList[i].backAnims[activeSubAnim]); + seq._counter = 0; } - } else if (_backAnimList[i]._seq._type == 3) { - //not_type_2 - _backAnimList[i]._seq._currRelative = 0; - _backAnimList[i]._seq._current = _backAnimList[i].backAnims[0]._basaData._num; - _backAnimList[i]._seq._counter = 0; - int rnd = _randomSource.getRandomNumber(_backAnimList[i]._seq._data - 1); - _backAnimList[i]._seq._data2 = rnd; + 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++; } - - //not_end: _backAnimList[i].backAnims[activeSubAnim]._showFrame = _backAnimList[i].backAnims[activeSubAnim]._frame; - - //ShowFrameCode - //ShowAnimFrame - int phaseCount = _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseCount(); - int frameCount = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrameCount(); - int phase = _backAnimList[i].backAnims[activeSubAnim]._showFrame; - int phaseFrameIndex = _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseFrameIndex(phase); - int x = _backAnimList[i].backAnims[activeSubAnim]._x + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetX(phase); - int y = _backAnimList[i].backAnims[activeSubAnim]._y + _backAnimList[i].backAnims[activeSubAnim]._animData->getPhaseOffsetY(phase); - int animFlag = _backAnimList[i].backAnims[activeSubAnim]._flags; - int checkMaskFlag = (animFlag & 1); - int maxFrontFlag = (animFlag & 2); - int specialZFlag = _backAnimList[i].backAnims[activeSubAnim]._nextAnim; - int z = _backAnimList[i].backAnims[activeSubAnim]._nextAnim; - int frameWidth = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrameWidth(phaseFrameIndex); - int frameHeight = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrameHeight(phaseFrameIndex); - int shadowZ = 0; - - if (x != 0 || y != 0 || phaseCount != 1 || frameCount != 1) { // fix for room no. 5 - animation 8 (propably unnecessary anim) - - if (checkMaskFlag != 0) { - if (_backAnimList[i].backAnims[activeSubAnim]._nextAnim == 0) { - z = y + frameHeight - 1; - } - checkMasks(x, y, frameWidth, frameHeight, z); - } - - if (specialZFlag != 0) { - z = specialZFlag; - } else if (maxFrontFlag != 0) { - z = kMaxPicHeight + 1; - } else { - z = y + frameHeight - 1; - } - shadowZ = z; - - _backAnimList[i].backAnims[activeSubAnim]._currX = x; - _backAnimList[i].backAnims[activeSubAnim]._currY = y; - _backAnimList[i].backAnims[activeSubAnim]._currW = frameWidth; - _backAnimList[i].backAnims[activeSubAnim]._currH = frameHeight; - Graphics::Surface *backAnimSurface = _backAnimList[i].backAnims[activeSubAnim]._animData->getFrame(phaseFrameIndex); //still with memory leak - showSprite(backAnimSurface, x, y, z, true); - } - - //ShowFrameCodeShadow - //ShowAnimFrameShadow - if (_backAnimList[i].backAnims[activeSubAnim]._shadowData != nullptr) { - int shadowPhaseFrameIndex = _backAnimList[i].backAnims[activeSubAnim]._shadowData->getPhaseFrameIndex(phase); - int shadowX = _backAnimList[i].backAnims[activeSubAnim]._shadowData->getBaseX() + _backAnimList[i].backAnims[activeSubAnim]._shadowData->getPhaseOffsetX(phase); - int shadowY = _backAnimList[i].backAnims[activeSubAnim]._shadowData->getBaseY() + _backAnimList[i].backAnims[activeSubAnim]._shadowData->getPhaseOffsetY(phase); - int shadowFrameWidth = _backAnimList[i].backAnims[activeSubAnim]._shadowData->getFrameWidth(shadowPhaseFrameIndex); - int shadowFrameHeight = _backAnimList[i].backAnims[activeSubAnim]._shadowData->getFrameHeight(shadowPhaseFrameIndex); - - if (checkMaskFlag != 0) { - checkMasks(shadowX, shadowY, shadowFrameWidth, shadowFrameHeight, shadowY + shadowFrameWidth - 1); - } - - if (shadowZ == 0) { - if (maxFrontFlag != 0) { - shadowZ = kMaxPicHeight + 1; - } else { - shadowZ = shadowY + shadowFrameWidth - 1; - } - } - - Graphics::Surface *shadowSurface = _backAnimList[i].backAnims[activeSubAnim]._shadowData->getFrame(shadowPhaseFrameIndex); //still with memory leak - showSpriteShadow(shadowSurface, shadowX, shadowY, shadowZ, true); - } + showAnim(_backAnimList[i].backAnims[activeSubAnim]); } } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index fdf5aa15b84d..e046d9caf250 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -419,6 +419,7 @@ class PrinceEngine : public Engine { void showLogo(); void showAnim(Anim &anim); void showNormAnims(); + void setBackAnim(Anim &backAnim); void showBackAnims(); void clearBackAnimList(); bool spriteCheck(int sprWidth, int sprHeight, int destX, int destY); From 8378d9287192390ad60a0a9bfff7fbdcab6c452b Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 2 Jul 2014 02:22:55 +0200 Subject: [PATCH 217/374] PRINCE: O_CHANGEFRAMES(), showNormAnims() update --- engines/prince/prince.cpp | 2 +- engines/prince/script.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index d876f8aa53d4..2d59f95a6ba5 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1256,7 +1256,7 @@ void PrinceEngine::showNormAnims() { Anim &anim = _normAnimList[i]; if (anim._animData != nullptr) { if (!anim._state) { - if (anim._frame == anim._lastFrame) { + if (anim._frame == anim._lastFrame - 1) { // TODO - check if correct if (anim._loopType) { if (anim._loopType == 1) { anim._frame = anim._loopFrame; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 37f6724b369e..38179421c30d 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1160,7 +1160,10 @@ void Interpreter::O_CHANGEFRAMES() { uint16 frame = readScriptFlagValue(); uint16 lastFrame = readScriptFlagValue(); uint16 loopFrame = readScriptFlagValue(); - debugInterpreter("O_CHANGFRAMES anim %d, fr1 %d, fr2 %d, fr3 %d", anim, frame, lastFrame, loopFrame); + _vm->_normAnimList[anim]._frame = frame; + _vm->_normAnimList[anim]._lastFrame = lastFrame; + _vm->_normAnimList[anim]._loopFrame = loopFrame; + debugInterpreter("O_CHANGFRAMES anim %d, frame %d, lastFrame %d, loopFrame %d", anim, frame, lastFrame, loopFrame); } void Interpreter::O_CHANGEBACKFRAMES() { From 355b7a3e3b041d5cfbb0bba2ada253456de7c167 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 2 Jul 2014 02:38:39 +0200 Subject: [PATCH 218/374] PRINCE: O_TALKBACKANIM(), O_TALKANIM() --- engines/prince/prince.cpp | 5 +++++ engines/prince/prince.h | 6 ++++++ engines/prince/script.cpp | 11 ++++++----- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 2d59f95a6ba5..6445113cd60b 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2357,6 +2357,11 @@ void PrinceEngine::talkHero(int slot, const char *s) { _interpreter->increaseString(); } +void PrinceEngine::doTalkAnim(int animNumber, int slot, AnimType animType) { + //TODO + _interpreter->increaseString(); +} + // Test void PrinceEngine::testDialog() { Common::Array tempDialogBox; diff --git a/engines/prince/prince.h b/engines/prince/prince.h index e046d9caf250..54beda2e69b8 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -174,6 +174,11 @@ struct BackgroundAnim { Common::Array backAnims; }; +enum AnimType { + kBackgroundAnimation, + kNormalAnimation +}; + // Nak (PL - Nakladka) struct Mask { int16 _state; // visible / invisible @@ -404,6 +409,7 @@ class PrinceEngine : public Engine { void createDialogBox(Common::Array &dialogData); void runDialog(Common::Array &dialogData); void talkHero(int slot, const char *s); + void doTalkAnim(int animNumber, int slot, AnimType animType); void testDialog(); int testAnimNr; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 38179421c30d..7f5a0695566d 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -843,10 +843,10 @@ void Interpreter::O_ADDFLAG() { } void Interpreter::O_TALKANIM() { - uint16 animSlot = readScriptFlagValue(); + uint16 animNumber = readScriptFlagValue(); uint16 slot = readScriptFlagValue(); - - debugInterpreter("O_TALKANIM animSlot %d, slot %d", animSlot, slot); + _vm->doTalkAnim(animNumber, slot, kNormalAnimation); + debugInterpreter("O_TALKANIM animNumber %d, slot %d", animNumber, slot); } void Interpreter::O_SUBFLAG() { @@ -1221,9 +1221,10 @@ void Interpreter::O_GETRND() { } void Interpreter::O_TALKBACKANIM() { - uint16 animSlot = readScriptFlagValue(); + uint16 animNumber = readScriptFlagValue(); uint16 slot = readScriptFlagValue(); - debugInterpreter("O_TALKBACKANIM animSlot %d, slot %d", animSlot, slot); + _vm->doTalkAnim(animNumber, slot, kBackgroundAnimation); + debugInterpreter("O_TALKBACKANIM animNumber %d, slot %d", animNumber, slot); } void Interpreter::O_LOADPATH() { From 92f3d72f19a54b7af627c5956bcdeacc05d715ac Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 2 Jul 2014 17:29:42 +0200 Subject: [PATCH 219/374] PRINCE: doTalkAnim(), talkHero() update --- engines/prince/prince.cpp | 45 ++++++++++++++++++++++++++++++++------- engines/prince/script.cpp | 4 ++++ engines/prince/script.h | 2 ++ 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 6445113cd60b..5b0cea3066e2 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2335,30 +2335,59 @@ void PrinceEngine::talkHero(int slot, const char *s) { Text &text = _textSlots[slot]; int lines = calcText(s); int time = lines * 30; - int x, y; if (slot == 0) { text._color = 220; // test this _mainHero->_state = Hero::TALK; _mainHero->_talkTime = time; - x = _mainHero->_middleX - _picWindowX; - y = _mainHero->_middleY - _mainHero->_scaledFrameYSize; + text._x = _mainHero->_middleX - _picWindowX; + text._y = _mainHero->_middleY - _mainHero->_scaledFrameYSize; } else { text._color = 220; // test this ! _secondHero->_state = Hero::TALK; _secondHero->_talkTime = time; - x = _secondHero->_middleX - _picWindowX; - y = _secondHero->_middleY - _secondHero->_scaledFrameYSize; + text._x = _secondHero->_middleX - _picWindowX; + text._y = _secondHero->_middleY - _secondHero->_scaledFrameYSize; } text._time = time; // changed by SETSPECVOICE? text._str = s; - text._x = x; - text._y = y; _interpreter->increaseString(); } void PrinceEngine::doTalkAnim(int animNumber, int slot, AnimType animType) { - //TODO + Text &text = _textSlots[slot]; + int lines = calcText((const char *)_interpreter->getGlobalString()); + 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 (animNumber < _backAnimList.size()) { + 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; + text._str = (const char *)_interpreter->getGlobalString(); _interpreter->increaseString(); } diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 7f5a0695566d..2c4d8b66c2a5 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -522,6 +522,10 @@ void Interpreter::setCurrentString(uint32 value) { _currentString = value; } +byte *Interpreter::getGlobalString() { + return _string; +} + void Interpreter::increaseString() { while (*_string) { _string++; diff --git a/engines/prince/script.h b/engines/prince/script.h index ddb68087f419..25c71bf6a1a0 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -185,6 +185,8 @@ class Interpreter { uint32 getCurrentString(); void setCurrentString(uint32 value); + byte *getGlobalString(); + void increaseString(); private: From e853e44695d1d15898f3948a8cc8656e49b37d33 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 3 Jul 2014 04:19:52 +0200 Subject: [PATCH 220/374] PRINCE: O_INITDIALOG() update --- engines/prince/prince.cpp | 44 ++++++--------------------------------- engines/prince/prince.h | 1 - engines/prince/script.cpp | 40 ++++++++++++++++++++++++++++++++--- engines/prince/script.h | 2 +- 4 files changed, 44 insertions(+), 43 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 5b0cea3066e2..37c7ce46f65b 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -780,11 +780,10 @@ void PrinceEngine::keyHandler(Common::Event event) { debugEngine("RIGHT"); break; case Common::KEYCODE_1: - //if(_mainHero->_state > 0) { - // _mainHero->_state--; - //} - //debugEngine("%d", _mainHero->_state); - testDialog(); + if(_mainHero->_state > 0) { + _mainHero->_state--; + } + debugEngine("%d", _mainHero->_state); break; case Common::KEYCODE_2: _mainHero->_state++; @@ -2356,7 +2355,7 @@ void PrinceEngine::talkHero(int slot, const char *s) { void PrinceEngine::doTalkAnim(int animNumber, int slot, AnimType animType) { Text &text = _textSlots[slot]; - int lines = calcText((const char *)_interpreter->getGlobalString()); + int lines = calcText((const char *)_interpreter->getString()); int time = lines * 30; if (animType == kNormalAnimation) { Anim &normAnim = _normAnimList[animNumber]; @@ -2387,41 +2386,10 @@ void PrinceEngine::doTalkAnim(int animNumber, int slot, AnimType animType) { error("doTalkAnim() - wrong animType: %d", animType); } text._time = time; - text._str = (const char *)_interpreter->getGlobalString(); + text._str = (const char *)_interpreter->getString(); _interpreter->increaseString(); } -// Test -void PrinceEngine::testDialog() { - Common::Array tempDialogBox; - DialogLine tempDialogLine; - - int dialogBoxSize = 6; - - // dialBox 0 create: - for (int i = 0; i < dialogBoxSize; i++) { - tempDialogLine._nr = i; - tempDialogLine._line = ""; - tempDialogBox.push_back(tempDialogLine); - } - tempDialogBox[0]._line = "Co to za miejsce?"; - tempDialogBox[1]._line = "Prosze, musi mi pan pomoc wydostac sie stad!"; - tempDialogBox[2]._line = "Sam Adanor Wszobrody odmowil mi trzydziestego\n""siodmego kubeczka krasnoludzkiego spirytusu."; - tempDialogBox[3]._line = "A co do twoich czarodziejskich sztuczek, to\n""jak mowi stare przyslowie, nie chwal sie\n""dokonaniami dnia wczorajszego..."; - tempDialogBox[4]._line = "Tu chyba nie jest zbyt bezpiecznie, prawda?"; - tempDialogBox[5]._line = "Nie chce przeszkadzac."; - - _dialogBoxList.push_back(tempDialogBox); - - //dialogBox 0 draw: - createDialogBox(_dialogBoxList[0]); - if (_dialogBoxList[0].size() != 0) { - changeCursor(1); - runDialog(_dialogBoxList[0]); - changeCursor(0); - } -} - void PrinceEngine::freeNormAnim(int slot) { _normAnimList[slot]._state = 1; delete _normAnimList[slot]._animData; diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 54beda2e69b8..d59e62a60ecd 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -410,7 +410,6 @@ class PrinceEngine : public Engine { void runDialog(Common::Array &dialogData); void talkHero(int slot, const char *s); void doTalkAnim(int animNumber, int slot, AnimType animType); - void testDialog(); int testAnimNr; int testAnimFrame; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 2c4d8b66c2a5..d4fa216d7d9d 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -522,7 +522,7 @@ void Interpreter::setCurrentString(uint32 value) { _currentString = value; } -byte *Interpreter::getGlobalString() { +byte *Interpreter::getString() { return _string; } @@ -1370,7 +1370,6 @@ void Interpreter::O_INITDIALOG() { stringESI += 2; _string = stringEBP + adressOfFirstSequence; - // like this? for (uint i = 0; i < _vm->_dialogBoxList.size(); i++) { _vm->_dialogBoxList[i].clear(); } @@ -1420,6 +1419,41 @@ void Interpreter::O_INITDIALOG() { dialogOptAddr[edi] = eax; edi++; } + + int i = 0; + Common::Array tempDialogBox; + while (dialogBoxAddr[i] != 0) { + tempDialogBox.clear(); + byte *boxAddr = dialogBoxAddr[i]; + + byte *stream = boxAddr; + int streamSize = 0; + while (*stream != 0xFF) { + stream++; + streamSize++; + } + streamSize++; + //int dialogDataValueEDI = (int)READ_UINT32(dialogData); + byte c; + int sentenceNumber; + DialogLine tempDialogLine; + Common::MemoryReadStream dialogStream(boxAddr, streamSize); + while ((sentenceNumber = dialogStream.readSByte()) != -1) { + tempDialogLine._line.clear(); + //bt edi, eax + //jc skip_zdanko + // skip_sentence - TODO + tempDialogLine._nr = sentenceNumber; + + while ((c = dialogStream.readByte())) { + tempDialogLine._line += c; + } + tempDialogBox.push_back(tempDialogLine); + } + _vm->_dialogBoxList.push_back(tempDialogBox); + i++; + } + //opt_done int freeASlot = 0; int freeBSlot = 0; @@ -1430,7 +1464,7 @@ void Interpreter::O_INITDIALOG() { //check for (int i = 31; i >= 0; i--) { if (dialogOptAddr[i] != 0) { - // or i++ before break here? + i++; debug("%s", (char *)dialogOptAddr[i]); freeHSlot = i; _flags->setFlagValue(Flags::VOICE_H_LINE, i); diff --git a/engines/prince/script.h b/engines/prince/script.h index 25c71bf6a1a0..a822b44ccb35 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -185,7 +185,7 @@ class Interpreter { uint32 getCurrentString(); void setCurrentString(uint32 value); - byte *getGlobalString(); + byte *getString(); void increaseString(); From a9a8eb0c98ee6402dc000c048188f79b99686add Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 3 Jul 2014 14:59:38 +0200 Subject: [PATCH 221/374] PRINCE: dialogDat loading --- engines/prince/prince.cpp | 14 +++++++++++++- engines/prince/prince.h | 3 +++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 37c7ce46f65b..b91155344b6a 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -117,6 +117,7 @@ PrinceEngine::~PrinceEngine() { delete _variaTxt; delete[] _talkTxt; delete[] _invTxt; + delete[] _dialogDat; delete _graph; delete _room; @@ -255,6 +256,17 @@ void PrinceEngine::init() { loadAllInv(); + Common::SeekableReadStream *dialogDatStream = SearchMan.createReadStreamForMember("dialog.dat"); + if (!dialogDatStream) { + error("Can't load dialogDatStream"); + return; + } + _dialogDatSize = dialogDatStream->size(); + _dialogDat = new byte[_dialogDatSize]; + dialogDatStream->read(_dialogDat, _dialogDatSize); + + delete dialogDatStream; + _optionsPic = new Graphics::Surface(); _optionsPic->create(_optionsWidth, _optionsHeight, Graphics::PixelFormat::createFormatCLUT8()); Common::Rect picRect(0, 0, _optionsWidth, _optionsHeight); @@ -2369,7 +2381,7 @@ void PrinceEngine::doTalkAnim(int animNumber, int slot, AnimType animType) { } } } else if (animType == kBackgroundAnimation) { - if (animNumber < _backAnimList.size()) { + if ((uint)animNumber < _backAnimList.size()) { int currAnim = _backAnimList[animNumber]._seq._currRelative; Anim &backAnim = _backAnimList[animNumber].backAnims[currAnim]; if (backAnim._animData != nullptr) { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index d59e62a60ecd..165cc68c99c2 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -398,6 +398,9 @@ class PrinceEngine : public Engine { void inventoryRightMouseButton(); void dialogLeftMouseButton(int dialogSelected, const char *s); + uint32 _dialogDatSize; + byte *_dialogDat; + bool _dialogFlag; int _dialogWidth; int _dialogHeight; From 54d3dc903ea57cbf90eceaf1bfbaa304e9b35bbe Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 3 Jul 2014 16:47:24 +0200 Subject: [PATCH 222/374] PRINCE: O_SETSTRING(), O_INITDIALOG() update --- engines/prince/prince.h | 1 + engines/prince/script.cpp | 119 +++++++++++++++++--------------------- 2 files changed, 54 insertions(+), 66 deletions(-) diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 165cc68c99c2..3110d6d9a5ca 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -400,6 +400,7 @@ class PrinceEngine : public Engine { uint32 _dialogDatSize; byte *_dialogDat; + byte *_dialogData; // on, off flags for lines of dialog text bool _dialogFlag; int _dialogWidth; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index d4fa216d7d9d..ec31cda739a7 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -875,7 +875,8 @@ void Interpreter::O_SETSTRING() { debugInterpreter("GetVaria %s", _string); } else if (offset < 2000) { - //dialogDat -> dialogData + _vm->_dialogData = &_vm->_dialogDat[offset * 4 - 4]; + uint32 of = READ_LE_UINT32(_vm->_talkTxt + offset * 4); const char *txt = (const char *)&_vm->_talkTxt[of]; _string = &_vm->_talkTxt[of]; @@ -1363,19 +1364,18 @@ int Interpreter::checkSeq(byte *string) { void Interpreter::O_INITDIALOG() { debugInterpreter("O_INITDIALOG"); if (_string[0] == 255) { - byte *stringESI = _string; - byte *stringEBP = _string; - stringESI++; - int32 adressOfFirstSequence = *stringESI; // eax - stringESI += 2; - _string = stringEBP + adressOfFirstSequence; + byte *stringCurrOff = _string; + byte *string = _string; + stringCurrOff++; + int32 adressOfFirstSequence = (int)READ_UINT16(stringCurrOff); + stringCurrOff += 2; + _string = string + adressOfFirstSequence; for (uint i = 0; i < _vm->_dialogBoxList.size(); i++) { _vm->_dialogBoxList[i].clear(); } _vm->_dialogBoxList.clear(); - // to global byte *dialogBoxAddr[32]; // adresses of dialog windows byte *dialogOptAddr[32]; // adresses of dialog options int dialogOptLines[4 * 32]; // numbers of initial dialog lines @@ -1389,83 +1389,70 @@ void Interpreter::O_INITDIALOG() { dialogOptLines[i] = 0; } - //loop_1 - int16 c; - byte *eax; - int edi = 0; - while (1) { - c = (int)READ_UINT16(stringESI); - stringESI += 2; - if (c == -1) { - break; - } - if (c != 0) { - eax = stringEBP + c; + int16 off; + byte *line; + + int dialogBox = 0; + while ((off = (int)READ_UINT16(stringCurrOff)) != -1) { + stringCurrOff += 2; + if (off) { + line = string + off; } - dialogBoxAddr[edi] = eax; - edi++; + dialogBoxAddr[dialogBox] = line; + dialogBox++; } - //box_done: - edi = 0; - while (1) { - c = (int)READ_UINT16(stringESI); - stringESI += 2; - if (c == -1) { - break; - } - if (c != 0) { - eax = stringEBP + c; + stringCurrOff += 2; + + int dialogOpt = 0; + while ((off = (int)READ_UINT16(stringCurrOff)) != -1) { + stringCurrOff += 2; + if (off) { + line = string + off; } - dialogOptAddr[edi] = eax; - edi++; + dialogOptAddr[dialogOpt] = line; + dialogOpt++; } - int i = 0; + dialogBox = 0; + byte c; + int sentenceNumber; + DialogLine tempDialogLine; Common::Array tempDialogBox; - while (dialogBoxAddr[i] != 0) { - tempDialogBox.clear(); - byte *boxAddr = dialogBoxAddr[i]; - byte *stream = boxAddr; - int streamSize = 0; - while (*stream != 0xFF) { - stream++; - streamSize++; - } - streamSize++; - //int dialogDataValueEDI = (int)READ_UINT32(dialogData); - byte c; - int sentenceNumber; - DialogLine tempDialogLine; - Common::MemoryReadStream dialogStream(boxAddr, streamSize); - while ((sentenceNumber = dialogStream.readSByte()) != -1) { - tempDialogLine._line.clear(); - //bt edi, eax - //jc skip_zdanko - // skip_sentence - TODO - tempDialogLine._nr = sentenceNumber; - - while ((c = dialogStream.readByte())) { - tempDialogLine._line += c; + while (dialogBoxAddr[dialogBox]) { + tempDialogBox.clear(); + byte *boxAddr = dialogBoxAddr[dialogBox]; + int dialogDataValue = (int)READ_UINT32(_vm->_dialogData); + while ((sentenceNumber = *boxAddr) != 0xFF) { + boxAddr++; + if (!(dialogDataValue & (1 << sentenceNumber))) { + tempDialogLine._line.clear(); + tempDialogLine._nr = sentenceNumber; + while ((c = *boxAddr)) { + tempDialogLine._line += c; + boxAddr++; + } + boxAddr++; + tempDialogBox.push_back(tempDialogLine); + } else { + do { + c = *boxAddr; + boxAddr++; + } while (c); } - tempDialogBox.push_back(tempDialogLine); } _vm->_dialogBoxList.push_back(tempDialogBox); - i++; + dialogBox++; } - //opt_done - int freeASlot = 0; - int freeBSlot = 0; + // TODO - dialogOptAddr, dialogOptLines _flags->setFlagValue(Flags::VOICE_A_LINE, 0); _flags->setFlagValue(Flags::VOICE_B_LINE, 0); // bx in original? int freeHSlot = 0; - //check for (int i = 31; i >= 0; i--) { if (dialogOptAddr[i] != 0) { i++; - debug("%s", (char *)dialogOptAddr[i]); freeHSlot = i; _flags->setFlagValue(Flags::VOICE_H_LINE, i); break; From 4792795ac76c7103d07e9412c15fb0528c5a46a1 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 3 Jul 2014 20:53:19 +0200 Subject: [PATCH 223/374] PRINCE: createDialogBox(), runDialog(), dialogLMB(), talkHero(), O_INITDIALOG(), O_SHOWDIALOGBOX() update --- engines/prince/prince.cpp | 98 +++++++++++++++++++++++++++------------ engines/prince/prince.h | 20 ++++---- engines/prince/script.cpp | 85 +++++++++------------------------ engines/prince/script.h | 1 + 4 files changed, 102 insertions(+), 102 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index b91155344b6a..101af7b35c69 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -87,7 +87,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _optionsMob(-1), _currentPointerNumber(1), _selectedMob(-1), _selectedItem(0), _selectedMode(0), _optionsWidth(210), _optionsHeight(170), _invOptionsWidth(210), _invOptionsHeight(130), _optionsStep(20), _invOptionsStep(20), _optionsNumber(7), _invOptionsNumber(5), _optionsColor1(236), _optionsColor2(252), - _dialogWidth(600), _dialogHeight(0), _dialogLineSpace(10), _dialogColor1(220), _dialogColor2(223), _dialogFlag(false) { + _dialogWidth(600), _dialogHeight(0), _dialogLineSpace(10), _dialogColor1(220), _dialogColor2(223), + _dialogFlag(false), _dialogLines(0), _dialogText(nullptr) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -2229,22 +2230,36 @@ void PrinceEngine::displayInventory() { } } -void PrinceEngine::createDialogBox(Common::Array &dialogData) { - int amountOfDialogLines = 0; - int amountOfDialogOptions = dialogData.size(); +void PrinceEngine::createDialogBox(int dialogBoxNr) { + _dialogLines = 0; + int amountOfDialogOptions = 0; + int dialogDataValue = (int)READ_UINT32(_dialogData); - for (int i = 0; i < amountOfDialogOptions; i++) { - amountOfDialogLines += calcText(dialogData[i]._line.c_str()); + byte c; + int sentenceNumber; + _dialogText = _dialogBoxAddr[dialogBoxNr]; + byte *dialogText = _dialogText; + + while ((sentenceNumber = *dialogText) != 0xFF) { + dialogText++; + if (!(dialogDataValue & (1 << sentenceNumber))) { + _dialogLines += calcText((const char *)dialogText); + amountOfDialogOptions++; + } + do { + c = *dialogText; + dialogText++; + } while (c); } - _dialogHeight = _font->getFontHeight() * amountOfDialogLines + _dialogLineSpace * (amountOfDialogOptions + 1); + _dialogHeight = _font->getFontHeight() * _dialogLines + _dialogLineSpace * (amountOfDialogOptions + 1); _dialogImage = new Graphics::Surface(); _dialogImage->create(_dialogWidth, _dialogHeight, Graphics::PixelFormat::createFormatCLUT8()); Common::Rect dBoxRect(0, 0, _dialogWidth, _dialogHeight); _dialogImage->fillRect(dBoxRect, _graph->kShadowColor); } -void PrinceEngine::runDialog(Common::Array &dialogData) { +void PrinceEngine::runDialog() { _dialogFlag = true; @@ -2265,27 +2280,38 @@ void PrinceEngine::runDialog(Common::Array &dialogData) { Common::Point mousePos = _system->getEventManager()->getMousePos(); + byte c; + int sentenceNumber; + byte *dialogText = _dialogText; + byte *dialogCurrentText = nullptr; int dialogSelected = -1; - int dialogSelectedText = -1; + int dialogDataValue = (int)READ_UINT32(_dialogData); - for (uint i = 0; i < dialogData.size(); i++) { + while ((sentenceNumber = *dialogText) != 0xFF) { + dialogText++; int actualColor = _dialogColor1; - Common::Array lines; - _font->wordWrapText(dialogData[i]._line, _graph->_frontScreen->w, lines); + if (!(dialogDataValue & (1 << sentenceNumber))) { + Common::Array lines; + _font->wordWrapText((const char *)dialogText, _graph->_frontScreen->w, lines); - Common::Rect dialogOption(dialogTextX, dialogTextY - dialogSkipUp / 2, dialogX + _dialogWidth - dialogSkipLeft, dialogTextY + lines.size() * _font->getFontHeight() + dialogSkipUp / 2 - 1); - if (dialogOption.contains(mousePos)) { - actualColor = _dialogColor2; - dialogSelected = dialogData[i]._nr; - dialogSelectedText = i; - } + Common::Rect dialogOption(dialogTextX, dialogTextY - dialogSkipUp / 2, dialogX + _dialogWidth - dialogSkipLeft, dialogTextY + lines.size() * _font->getFontHeight() + dialogSkipUp / 2 - 1); + if (dialogOption.contains(mousePos)) { + actualColor = _dialogColor2; + dialogSelected = sentenceNumber; + dialogCurrentText = dialogText; + } - for (uint j = 0; j < lines.size(); j++) { - _font->drawString(_graph->_frontScreen, lines[j], dialogTextX, dialogTextY, _graph->_frontScreen->w, actualColor); - dialogTextY += _font->getFontHeight(); + for (uint j = 0; j < lines.size(); j++) { + _font->drawString(_graph->_frontScreen, lines[j], dialogTextX, dialogTextY, _graph->_frontScreen->w, actualColor); + dialogTextY += _font->getFontHeight(); + } + dialogTextY += _dialogLineSpace; } - dialogTextY += _dialogLineSpace; + do { + c = *dialogText; + dialogText++; + } while (c); } Common::Event event; @@ -2301,7 +2327,7 @@ void PrinceEngine::runDialog(Common::Array &dialogData) { break; case Common::EVENT_LBUTTONDOWN: if (dialogSelected != -1) { - dialogLeftMouseButton(dialogSelected, dialogData[dialogSelectedText]._line.c_str()); + dialogLeftMouseButton(dialogCurrentText, dialogSelected); _dialogFlag = false; } break; @@ -2336,15 +2362,29 @@ void PrinceEngine::runDialog(Common::Array &dialogData) { // cursor? } -void PrinceEngine::dialogLeftMouseButton(int dialogSelected, const char *s) { - //TODO @@showa_dialoga: - talkHero(0, s); +void PrinceEngine::dialogLeftMouseButton(byte *string, int dialogSelected) { + _interpreter->setString(string); + talkHero(0); + + int dialogDataValue = (int)READ_UINT32(_dialogData); + int newValue = (dialogDataValue & (1 << dialogSelected)); // FIXME + WRITE_UINT32(_dialogData, newValue); // FIXME + + _flags->setFlagValue(Flags::BOXSEL, dialogSelected + 1); + setVoice(0, 28, dialogSelected + 1); + + int dialogOpt = dialogSelected << 4; + _flags->setFlagValue(Flags::VOICE_H_LINE, _dialogOptLines[dialogOpt]); + _flags->setFlagValue(Flags::VOICE_A_LINE, _dialogOptLines[dialogOpt + 1]); + _flags->setFlagValue(Flags::VOICE_B_LINE, _dialogOptLines[dialogOpt + 2]); + + _interpreter->setString(_dialogOptAddr[dialogSelected]); } -void PrinceEngine::talkHero(int slot, const char *s) { +void PrinceEngine::talkHero(int slot) { // heroSlot = textSlot Text &text = _textSlots[slot]; - int lines = calcText(s); + int lines = calcText((const char *)_interpreter->getString()); int time = lines * 30; if (slot == 0) { @@ -2361,7 +2401,7 @@ void PrinceEngine::talkHero(int slot, const char *s) { text._y = _secondHero->_middleY - _secondHero->_scaledFrameYSize; } text._time = time; // changed by SETSPECVOICE? - text._str = s; + text._str = (const char *)_interpreter->getString(); _interpreter->increaseString(); } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 3110d6d9a5ca..d59a8888159c 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -234,11 +234,6 @@ struct DrawNode { void (*drawFunction)(Graphics::Surface *, DrawNode *); }; -struct DialogLine { - int _nr; - Common::String _line; -}; - struct DebugChannel { enum Type { @@ -309,7 +304,6 @@ class PrinceEngine : public Engine { Common::Array _animList; Common::Array _backAnimList; Common::Array _normAnimList; - Common::Array> _dialogBoxList; Common::Array _mobList; void freeNormAnim(int slot); @@ -396,12 +390,18 @@ class PrinceEngine : public Engine { void rightMouseButton(); void inventoryLeftMouseButton(); void inventoryRightMouseButton(); - void dialogLeftMouseButton(int dialogSelected, const char *s); + void dialogLeftMouseButton(byte *string, int dialogSelected); uint32 _dialogDatSize; byte *_dialogDat; byte *_dialogData; // on, off flags for lines of dialog text + byte *_dialogBoxAddr[32]; // adresses of dialog windows + byte *_dialogOptAddr[32]; // adresses of dialog options + int _dialogOptLines[4 * 32]; // numbers of initial dialog lines + + byte *_dialogText; + int _dialogLines; bool _dialogFlag; int _dialogWidth; int _dialogHeight; @@ -410,9 +410,9 @@ class PrinceEngine : public Engine { int _dialogColor2; // color for selected option Graphics::Surface *_dialogImage; - void createDialogBox(Common::Array &dialogData); - void runDialog(Common::Array &dialogData); - void talkHero(int slot, const char *s); + void createDialogBox(int dialogBoxNr); + void runDialog(); + void talkHero(int slot); void doTalkAnim(int animNumber, int slot, AnimType animType); int testAnimNr; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index ec31cda739a7..3fe03e8c1d78 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -526,6 +526,10 @@ byte *Interpreter::getString() { return _string; } +void Interpreter::setString(byte *newString) { + _string = newString; +} + void Interpreter::increaseString() { while (*_string) { _string++; @@ -1125,7 +1129,7 @@ void Interpreter::O_CHECKINV() { void Interpreter::O_TALKHERO() { uint16 hero = readScriptFlagValue(); debugInterpreter("O_TALKHERO hero %d", hero); - _vm->talkHero(hero, (const char *)_string); + _vm->talkHero(hero); } void Interpreter::O_WAITTEXT() { @@ -1371,22 +1375,13 @@ void Interpreter::O_INITDIALOG() { stringCurrOff += 2; _string = string + adressOfFirstSequence; - for (uint i = 0; i < _vm->_dialogBoxList.size(); i++) { - _vm->_dialogBoxList[i].clear(); - } - _vm->_dialogBoxList.clear(); - - byte *dialogBoxAddr[32]; // adresses of dialog windows - byte *dialogOptAddr[32]; // adresses of dialog options - int dialogOptLines[4 * 32]; // numbers of initial dialog lines - for (int i = 0; i < 32; i++) { - dialogBoxAddr[i] = 0; - dialogOptAddr[i] = 0; + _vm->_dialogBoxAddr[i] = 0; + _vm->_dialogOptAddr[i] = 0; } for (int i = 0; i < 4 * 32; i++) { - dialogOptLines[i] = 0; + _vm->_dialogOptLines[i] = 0; } int16 off; @@ -1398,7 +1393,7 @@ void Interpreter::O_INITDIALOG() { if (off) { line = string + off; } - dialogBoxAddr[dialogBox] = line; + _vm->_dialogBoxAddr[dialogBox] = line; dialogBox++; } stringCurrOff += 2; @@ -1409,49 +1404,16 @@ void Interpreter::O_INITDIALOG() { if (off) { line = string + off; } - dialogOptAddr[dialogOpt] = line; + _vm->_dialogOptAddr[dialogOpt] = line; dialogOpt++; } - dialogBox = 0; - byte c; - int sentenceNumber; - DialogLine tempDialogLine; - Common::Array tempDialogBox; - - while (dialogBoxAddr[dialogBox]) { - tempDialogBox.clear(); - byte *boxAddr = dialogBoxAddr[dialogBox]; - int dialogDataValue = (int)READ_UINT32(_vm->_dialogData); - while ((sentenceNumber = *boxAddr) != 0xFF) { - boxAddr++; - if (!(dialogDataValue & (1 << sentenceNumber))) { - tempDialogLine._line.clear(); - tempDialogLine._nr = sentenceNumber; - while ((c = *boxAddr)) { - tempDialogLine._line += c; - boxAddr++; - } - boxAddr++; - tempDialogBox.push_back(tempDialogLine); - } else { - do { - c = *boxAddr; - boxAddr++; - } while (c); - } - } - _vm->_dialogBoxList.push_back(tempDialogBox); - dialogBox++; - } - - // TODO - dialogOptAddr, dialogOptLines _flags->setFlagValue(Flags::VOICE_A_LINE, 0); _flags->setFlagValue(Flags::VOICE_B_LINE, 0); // bx in original? int freeHSlot = 0; for (int i = 31; i >= 0; i--) { - if (dialogOptAddr[i] != 0) { + if (_vm->_dialogOptAddr[i] != 0) { i++; freeHSlot = i; _flags->setFlagValue(Flags::VOICE_H_LINE, i); @@ -1462,11 +1424,11 @@ void Interpreter::O_INITDIALOG() { freeHSlot += checkSeq(_string); for (int i = 0; i < 32; i++) { - dialogOptLines[i * 4] = freeHSlot; - dialogOptLines[i * 4 + 1] = freeHSlot; - dialogOptLines[i * 4 + 2] = freeHSlot; - if (dialogOptAddr[i]) { - freeHSlot += checkSeq(dialogOptAddr[i]); + _vm->_dialogOptLines[i * 4] = freeHSlot; + _vm->_dialogOptLines[i * 4 + 1] = freeHSlot; + _vm->_dialogOptLines[i * 4 + 2] = freeHSlot; + if (_vm->_dialogOptAddr[i]) { + freeHSlot += checkSeq(_vm->_dialogOptAddr[i]); } } } @@ -1485,15 +1447,12 @@ void Interpreter::O_DISABLEDIALOGOPT() { void Interpreter::O_SHOWDIALOGBOX() { uint16 box = readScriptFlagValue(); debugInterpreter("O_SHOWDIALOGBOX box %d", box); - if (box < _vm->_dialogBoxList.size()) { - _vm->createDialogBox(_vm->_dialogBoxList[box]); - int dialogLines = _vm->_dialogBoxList[box].size(); - _flags->setFlagValue(Flags::DIALINES, dialogLines); - if (dialogLines != 0) { - _vm->changeCursor(1); - _vm->runDialog(_vm->_dialogBoxList[box]); - _vm->changeCursor(0); - } + _vm->createDialogBox(box); + _flags->setFlagValue(Flags::DIALINES, _vm->_dialogLines); + if (_vm->_dialogLines != 0) { + _vm->changeCursor(1); + _vm->runDialog(); + _vm->changeCursor(0); } } diff --git a/engines/prince/script.h b/engines/prince/script.h index a822b44ccb35..5f9cdc3ab3ed 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -186,6 +186,7 @@ class Interpreter { void setCurrentString(uint32 value); byte *getString(); + void setString(byte *newString); void increaseString(); From af7c167cc13f14c0126fc3a72ba3e96758f1aa9d Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 3 Jul 2014 22:35:41 +0200 Subject: [PATCH 224/374] PRINCE: O_ENABLEDIALOGOPT(), O_DISABLEDIALOGOPT() update. O_CHECKBACKANIMFRAME(), O_BACKANIMUPDATEOFF(), dialogLMB() fix --- engines/prince/prince.cpp | 11 +++++------ engines/prince/script.cpp | 10 ++++++++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 101af7b35c69..ea28ae3c6b4e 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2367,16 +2367,15 @@ void PrinceEngine::dialogLeftMouseButton(byte *string, int dialogSelected) { talkHero(0); int dialogDataValue = (int)READ_UINT32(_dialogData); - int newValue = (dialogDataValue & (1 << dialogSelected)); // FIXME - WRITE_UINT32(_dialogData, newValue); // FIXME + dialogDataValue |= (1u << dialogSelected); + WRITE_UINT32(_dialogData, dialogDataValue); _flags->setFlagValue(Flags::BOXSEL, dialogSelected + 1); setVoice(0, 28, dialogSelected + 1); - int dialogOpt = dialogSelected << 4; - _flags->setFlagValue(Flags::VOICE_H_LINE, _dialogOptLines[dialogOpt]); - _flags->setFlagValue(Flags::VOICE_A_LINE, _dialogOptLines[dialogOpt + 1]); - _flags->setFlagValue(Flags::VOICE_B_LINE, _dialogOptLines[dialogOpt + 2]); + _flags->setFlagValue(Flags::VOICE_H_LINE, _dialogOptLines[dialogSelected * 4]); + _flags->setFlagValue(Flags::VOICE_A_LINE, _dialogOptLines[dialogSelected * 4 + 1]); + _flags->setFlagValue(Flags::VOICE_B_LINE, _dialogOptLines[dialogSelected * 4 + 2]); _interpreter->setString(_dialogOptAddr[dialogSelected]); } diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 3fe03e8c1d78..ab75b50ade78 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -684,7 +684,7 @@ void Interpreter::O_CHECKBACKANIMFRAME() { uint16 frameId = readScriptFlagValue(); int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; if (_vm->_backAnimList[slotId].backAnims[currAnim]._frame != frameId) { - //esi -= 6; loop of this OP? + _currentInstruction -= 6; _opcodeNF = 1; } debugInterpreter("O_CHECKBACKANIMFRAME slotId %d, frameId %d", slotId, frameId); @@ -781,7 +781,7 @@ void Interpreter::O_BACKANIMUPDATEOFF() { void Interpreter::O_BACKANIMUPDATEON() { uint16 slotId = readScriptFlagValue(); int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; - _vm->_backAnimList[slotId].backAnims[currAnim]._state = 1; + _vm->_backAnimList[slotId].backAnims[currAnim]._state = 0; debugInterpreter("O_BACKANIMUPDATEON %d", slotId); } @@ -1437,11 +1437,17 @@ void Interpreter::O_INITDIALOG() { void Interpreter::O_ENABLEDIALOGOPT() { uint16 opt = readScriptFlagValue(); debugInterpreter("O_ENABLEDIALOGOPT opt %d", opt); + int dialogDataValue = (int)READ_UINT32(_vm->_dialogData); + dialogDataValue &= ~(1u << opt); + WRITE_UINT32(_vm->_dialogData, dialogDataValue); } void Interpreter::O_DISABLEDIALOGOPT() { uint16 opt = readScriptFlagValue(); debugInterpreter("O_DISABLEDIALOGOPT opt %d", opt); + int dialogDataValue = (int)READ_UINT32(_vm->_dialogData); + dialogDataValue |= (1u << opt); + WRITE_UINT32(_vm->_dialogData, dialogDataValue); } void Interpreter::O_SHOWDIALOGBOX() { From 9698ec51b3d579245f67879fb608db8c2c855bcb Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 4 Jul 2014 02:33:30 +0200 Subject: [PATCH 225/374] PRINCE: O_CHECKANIMFRAME, O_CHECKANIMEND(), O_GETMOBDATA(), O_SETMOBDATA(), O_CLSTEXT(), O_ADDINV(), O_ADDINVQUIET, O_REMINV(), O_SWAPINVENTORY(), O_CLEARINVENTORY(), O_OPENINVENTORY --- engines/prince/prince.cpp | 117 ++++++++++++++++++++++++++++++++++++-- engines/prince/prince.h | 5 ++ engines/prince/script.cpp | 68 ++++++++++++---------- engines/prince/script.h | 3 +- 4 files changed, 157 insertions(+), 36 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index ea28ae3c6b4e..30feaeca8aa9 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -807,13 +807,9 @@ void PrinceEngine::keyHandler(Common::Event event) { break; case Common::KEYCODE_k: _mainHero->_middleY += 5; - //addInvObj(); break; case Common::KEYCODE_j: _mainHero->_middleX -= 5; - //_flags->setFlagValue(Flags::CURSEBLINK, 1); - //addInvObj(); - //_flags->setFlagValue(Flags::CURSEBLINK, 0); break; case Common::KEYCODE_l: _mainHero->_middleX += 5; @@ -1567,6 +1563,116 @@ void PrinceEngine::pause() { _system->delayMillis(delay); } +void PrinceEngine::addInv(int hero, int item, bool addItemQuiet) { + switch (hero) { + case 0: + if (_mainHero->_inventory.size() < kMaxItems) { + if (item != 0x7FFF) { + _mainHero->_inventory.push_back(item); + } + if (!addItemQuiet) { + addInvObj(); + } + _interpreter->setResult(0); + } else { + _interpreter->setResult(1); + } + break; + case 1: + if (_secondHero->_inventory.size() < kMaxItems) { + if (item != 0x7FFF) { + _secondHero->_inventory.push_back(item); + } + if (!addItemQuiet) { + addInvObj(); + } + _interpreter->setResult(0); + } else { + _interpreter->setResult(1); + } + break; + default: + error("addInv() - wrong hero slot"); + break; + } +} + +void PrinceEngine::remInv(int hero, int item) { + switch (hero) { + case 0: + for (uint i = 0; i < _mainHero->_inventory.size(); i++) { + if (_mainHero->_inventory[i] == item) { + _mainHero->_inventory.remove_at(i); + _interpreter->setResult(0); + return; + } + } + _interpreter->setResult(1); + break; + case 1: + for (uint i = 0; i < _secondHero->_inventory.size(); i++) { + if (_secondHero->_inventory[i] == item) { + _secondHero->_inventory.remove_at(i); + _interpreter->setResult(0); + return; + } + } + _interpreter->setResult(1); + break; + default: + _interpreter->setResult(1); + error("remInv() - wrong hero slot"); + break; + } +} + +void PrinceEngine::clearInv(int hero) { + switch (hero) { + case 0: + _mainHero->_inventory.clear(); + break; + case 1: + _secondHero->_inventory.clear(); + break; + default: + error("clearInv() - wrong hero slot"); + break; + } +} + +void PrinceEngine::swapInv(int hero) { + Common::Array tempInv; + switch (hero) { + case 0: + for (uint i = 0; i < _mainHero->_inventory.size(); i++) { + tempInv.push_back(_mainHero->_inventory[i]); + } + for (uint i = 0; i < _mainHero->_inventory2.size(); i++) { + _mainHero->_inventory.push_back(_mainHero->_inventory2[i]); + } + for (uint i = 0; i < tempInv.size(); i++) { + _mainHero->_inventory2.push_back(tempInv[i]); + } + tempInv.clear(); + break; + case 1: + for (uint i = 0; i < _secondHero->_inventory.size(); i++) { + tempInv.push_back(_secondHero->_inventory[i]); + } + for (uint i = 0; i < _secondHero->_inventory2.size(); i++) { + _secondHero->_inventory.push_back(_secondHero->_inventory2[i]); + } + for (uint i = 0; i < tempInv.size(); i++) { + _secondHero->_inventory2.push_back(tempInv[i]); + } + tempInv.clear(); + break; + default: + error("clearInv() - wrong hero slot"); + break; + } +} + void PrinceEngine::addInvObj() { changeCursor(0); //prepareInventoryToView(); @@ -2131,6 +2237,7 @@ void PrinceEngine::checkInvOptions() { void PrinceEngine::displayInventory() { // temp: + /* _mainHero->_inventory.clear(); _mainHero->_inventory.push_back(1); _mainHero->_inventory.push_back(3); @@ -2144,7 +2251,7 @@ void PrinceEngine::displayInventory() { _mainHero->_inventory.push_back(67); _mainHero->_inventory.push_back(8); - + */ prepareInventoryToView(); while (!shouldQuit()) { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index d59a8888159c..340c2d0cbf29 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -327,6 +327,7 @@ class PrinceEngine : public Engine { int _currentPointerNumber; static const int16 kMaxInv = 90; // max amount of inventory items in whole game + static const int16 kMaxItems = 30; // size of inventory uint32 _invTxtSize; byte *_invTxt; @@ -380,6 +381,10 @@ class PrinceEngine : public Engine { void prepareInventoryToView(); void drawInvItems(); void displayInventory(); + void addInv(int hero, int item, bool addItemQuiet); + void remInv(int hero, int item); + void clearInv(int hero); + void swapInv(int hero); void addInvObj(); void makeInvCursor(int itemNr); void enableOptions(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index ab75b50ade78..bf3fbacf21f8 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -537,6 +537,10 @@ void Interpreter::increaseString() { _string++; } +void Interpreter::setResult(byte value) { + _result = value; +} + template T Interpreter::readScript() { T data = _script->read(_currentInstruction); @@ -645,10 +649,11 @@ void Interpreter::O_SHOWANIM() { void Interpreter::O_CHECKANIMEND() { uint16 slot = readScriptFlagValue(); - uint16 frameId = readScriptFlagValue(); - - debugInterpreter("O_CHECKANIMEND slot %d, frameId %d", slot, frameId); - _opcodeNF = 1; + if (_vm->_normAnimList[slot]._frame != _vm->_normAnimList[slot]._lastFrame - 1) { + _currentInstruction -= 4; + _opcodeNF = 1; + } + debugInterpreter("O_CHECKANIMEND slot %d", slot); } void Interpreter::O_FREEANIM() { @@ -659,10 +664,12 @@ void Interpreter::O_FREEANIM() { void Interpreter::O_CHECKANIMFRAME() { uint16 slot = readScriptFlagValue(); - uint16 frameId = readScriptFlagValue(); - - debugInterpreter("O_CHECKANIMFRAME slot %d, frameId %d", slot, frameId); - _opcodeNF = 1; + uint16 frameNumber = readScriptFlagValue(); + if (_vm->_normAnimList[slot]._frame != frameNumber) { + _currentInstruction -= 6; + _opcodeNF = 1; + } + debugInterpreter("O_CHECKANIMFRAME slot %d, frameNumber %d", slot, frameNumber); } void Interpreter::O_PUTBACKANIM() { @@ -675,7 +682,6 @@ void Interpreter::O_PUTBACKANIM() { void Interpreter::O_REMBACKANIM() { uint16 roomId = readScriptFlagValue(); uint16 slot = readScriptFlagValue(); - debugInterpreter("O_REMBACKANIM roomId %d, slot %d", roomId, slot); } @@ -907,9 +913,10 @@ void Interpreter::O_ANDFLAG() { void Interpreter::O_GETMOBDATA() { Flags::Id flagId = readScriptFlagId(); - uint16 mobId = readScript(); - uint16 mobOffset = readScript(); - + uint16 mobId = readScriptFlagValue(); + uint16 mobOffset = readScriptFlagValue(); + int16 value = _vm->_mobList[mobId].getData((Mob::AttrId)mobOffset); + _flags->setFlagValue(flagId, value); debugInterpreter("O_GETMOBDATA flagId %d, modId %d, mobOffset %d", flagId, mobId, mobOffset); } @@ -932,7 +939,7 @@ void Interpreter::O_SETMOBDATA() { uint16 mobId = readScriptFlagValue(); uint16 mobOffset = readScriptFlagValue(); uint16 value = readScriptFlagValue(); - + _vm->_mobList[mobId].setData((Mob::AttrId)mobOffset, value); debugInterpreter("O_SETMOBDATA mobId %d, mobOffset %d, value %d", mobId, mobOffset, value); } @@ -955,7 +962,6 @@ void Interpreter::O_GETMOBTEXT() { uint16 mob = readScriptFlagValue(); _currentString = _vm->_locationNr * 100 + mob + 60001; _string = (byte *)_vm->_mobList[mob]._examText.c_str(); - debugInterpreter("O_GETMOBTEXT mob %d", mob); } @@ -1003,8 +1009,8 @@ void Interpreter::O_HEROON() { void Interpreter::O_CLSTEXT() { uint16 slot = readScriptFlagValue(); debugInterpreter("O_CLSTEXT slot %d", slot); - // Sets text line to null - // Sets text timeout to zero + _vm->_textSlots[slot]._str = nullptr; + _vm->_textSlots[slot]._time = 0; } void Interpreter::O_CALLTABLE() { @@ -1020,22 +1026,23 @@ void Interpreter::O_CALLTABLE() { void Interpreter::O_CHANGEMOB() { uint16 mob = readScriptFlagValue(); uint16 value = readScriptFlagValue(); - debugInterpreter("O_CHANGEMOB mob %d, value %d", mob, value); - value ^= 1; _vm->_script->setMobVisible(mob, value); _vm->_mobList[mob]._visible = value; + debugInterpreter("O_CHANGEMOB mob %d, value %d", mob, value); } void Interpreter::O_ADDINV() { uint16 hero = readScriptFlagValue(); uint16 item = readScriptFlagValue(); + _vm->addInv(hero, item, false); debugInterpreter("O_ADDINV hero %d, item %d", hero, item); } void Interpreter::O_REMINV() { uint16 hero = readScriptFlagValue(); uint16 item = readScriptFlagValue(); + _vm->remInv(hero, item); debugInterpreter("O_REMINV hero %d, item %d", hero, item); } @@ -1385,7 +1392,7 @@ void Interpreter::O_INITDIALOG() { } int16 off; - byte *line; + byte *line = nullptr; int dialogBox = 0; while ((off = (int)READ_UINT16(stringCurrOff)) != -1) { @@ -1576,10 +1583,10 @@ void Interpreter::O_FREECURSOR() { } void Interpreter::O_ADDINVQUIET() { - uint16 heroId = readScriptFlagValue(); - uint16 itemId = readScriptFlagValue(); - - debugInterpreter("O_ADDINVQUIET heorId %d, itemId %d", heroId, itemId); + uint16 hero = readScriptFlagValue(); + uint16 item = readScriptFlagValue(); + _vm->addInv(hero, item, true); + debugInterpreter("O_ADDINVQUIET hero %d, item %d", hero, item); } void Interpreter::O_RUNHERO() { @@ -1671,13 +1678,15 @@ void Interpreter::O_GETMOBNAME() { } void Interpreter::O_SWAPINVENTORY() { - uint16 heroId = readScriptFlagValue(); - debugInterpreter("O_SWAPINVENTORY heroId %d", heroId); + uint16 hero = readScriptFlagValue(); + _vm->swapInv(hero); + debugInterpreter("O_SWAPINVENTORY hero %d", hero); } void Interpreter::O_CLEARINVENTORY() { - uint16 heroId = readScriptFlagValue(); - debugInterpreter("O_CLEARINVENTORY heroId %d", heroId); + uint16 hero = readScriptFlagValue(); + _vm->clearInv(hero); + debugInterpreter("O_CLEARINVENTORY hero %d", hero); } void Interpreter::O_SKIPTEXT() { @@ -1723,7 +1732,6 @@ void Interpreter::O_SETVOICED() { void Interpreter::O_VIEWFLCLOOP() { uint16 value = readScriptFlagValue(); debugInterpreter("O_VIEWFLCLOOP animId %d", value); - _vm->loadAnim(value, true); } @@ -1733,9 +1741,9 @@ void Interpreter::O_FLCSPEED() { } void Interpreter::O_OPENINVENTORY() { - debugInterpreter("O_OPENINVENTORY"); + _vm->_showInventoryFlag = true; _opcodeNF = 1; - // _showInventoryFlag = true + debugInterpreter("O_OPENINVENTORY"); } void Interpreter::O_KRZYWA() { diff --git a/engines/prince/script.h b/engines/prince/script.h index 5f9cdc3ab3ed..99a6af3427c2 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -187,9 +187,10 @@ class Interpreter { byte *getString(); void setString(byte *newString); - void increaseString(); + void setResult(byte value); + private: PrinceEngine *_vm; Script *_script; From 9d2670416ce81abeca04cb64512f7c5ebc918281 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 4 Jul 2014 03:12:06 +0200 Subject: [PATCH 226/374] PRINCE: O_SETFRAME, O_CHECKINV, O_GETANIMDATA, O_SETBACKFRAME, O_GETRND. O_GETBACKANIMDATA fix --- engines/prince/prince.cpp | 32 ++++++++++++++++++++++++++++ engines/prince/prince.h | 4 ++++ engines/prince/script.cpp | 45 ++++++++++++++++++++++----------------- 3 files changed, 62 insertions(+), 19 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 30feaeca8aa9..0430a967c1a9 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1387,6 +1387,14 @@ void PrinceEngine::clearBackAnimList() { _backAnimList.clear(); } +void PrinceEngine::initZoomIn(int slot) { + //TODO +} + +void PrinceEngine::initZoomOut(int slot) { + //TODO +} + void PrinceEngine::showObjects() { if (!_objList.empty()) { for (uint i = 0; i < _objList.size(); i++) { @@ -1673,6 +1681,30 @@ void PrinceEngine::swapInv(int hero) { } } +void PrinceEngine::checkInv(int hero, int item) { + switch (hero) { + case 0: + for (uint i = 0; i < _mainHero->_inventory.size(); i++) { + if (_mainHero->_inventory[i] == item) { + _interpreter->setResult(0); + } + } + _interpreter->setResult(1); + break; + case 1: + for (uint i = 0; i < _secondHero->_inventory.size(); i++) { + if (_secondHero->_inventory[i] == item) { + _interpreter->setResult(0); + } + } + _interpreter->setResult(1); + break; + default: + error("addInv() - wrong hero slot"); + break; + } +} + void PrinceEngine::addInvObj() { changeCursor(0); //prepareInventoryToView(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 340c2d0cbf29..b095da1fc0bd 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -385,6 +385,7 @@ class PrinceEngine : public Engine { void remInv(int hero, int item); void clearInv(int hero); void swapInv(int hero); + void checkInv(int hero, int item); void addInvObj(); void makeInvCursor(int itemNr); void enableOptions(); @@ -420,6 +421,9 @@ class PrinceEngine : public Engine { void talkHero(int slot); void doTalkAnim(int animNumber, int slot, AnimType animType); + void initZoomIn(int slot); + void initZoomOut(int slot); + int testAnimNr; int testAnimFrame; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index bf3fbacf21f8..8615b1ef9bd2 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1090,6 +1090,7 @@ void Interpreter::O_WAITFRAME() { void Interpreter::O_SETFRAME() { uint16 anim = readScriptFlagValue(); uint16 frame = readScriptFlagValue(); + _vm->_normAnimList[anim]._frame = frame; debugInterpreter("O_SETFRAME anim %d, frame %d", anim, frame); } @@ -1129,8 +1130,8 @@ void Interpreter::O_FREEPRELOAD() { void Interpreter::O_CHECKINV() { uint16 hero = readScriptFlagValue(); uint16 item = readScriptFlagValue(); + _vm->checkInv(hero, item); debugInterpreter("O_CHECKINV hero %d, item %d", hero, item); - // checks if item is in heros inventory } void Interpreter::O_TALKHERO() { @@ -1139,6 +1140,7 @@ void Interpreter::O_TALKHERO() { _vm->talkHero(hero); } +//TODO void Interpreter::O_WAITTEXT() { uint16 slot = readScriptFlagValue(); Text &text = _vm->_textSlots[slot]; @@ -1197,8 +1199,8 @@ void Interpreter::O_CHANGEBACKFRAMES() { void Interpreter::O_GETBACKANIMDATA() { Flags::Id flagId = readScriptFlagId(); - uint16 animNumber = readScript(); - uint16 animDataOffset = readScript(); + uint16 animNumber = readScriptFlagValue(); + uint16 animDataOffset = readScriptFlagValue(); int currAnim = _vm->_backAnimList[animNumber]._seq._currRelative; int16 value = _vm->_backAnimList[animNumber].backAnims[currAnim].getAnimData((Anim::AnimOffsets)(animDataOffset)); _flags->setFlagValue((Flags::Id)(flagId), value); @@ -1206,12 +1208,13 @@ void Interpreter::O_GETBACKANIMDATA() { } void Interpreter::O_GETANIMDATA() { - uint16 flag = readScript(); + Flags::Id flagId = readScriptFlagId(); uint16 anim = readScriptFlagValue(); uint16 animOffset = readScriptFlagValue(); - debugInterpreter("O_GETANIMDATA flag %d, anim %d, animOffset %d", flag, anim, animOffset); - // Gets value of anim data - // use anim offset as attribute id not an offset + if (_vm->_normAnimList[anim]._animData != nullptr) { + _flags->setFlagValue(flagId, _vm->_normAnimList[anim].getAnimData((Anim::AnimOffsets)(animOffset))); + } + debugInterpreter("O_GETANIMDATA flag %04X (%s), anim %d, animOffset %d", flagId, Flags::getFlagName(flagId), anim, animOffset); } void Interpreter::O_SETBGCODE() { @@ -1223,17 +1226,22 @@ void Interpreter::O_SETBGCODE() { void Interpreter::O_SETBACKFRAME() { uint16 anim = readScriptFlagValue(); uint16 frame = readScriptFlagValue(); - + int currAnim = _vm->_backAnimList[anim]._seq._currRelative; + if (_vm->_backAnimList[anim].backAnims[currAnim]._animData != nullptr) { + _vm->_backAnimList[anim].backAnims[currAnim]._frame = frame; + } debugInterpreter("O_SETBACKFRAME anim %d, frame %d", anim, frame); } +// TODO - check if proper max for getRandomNumber void Interpreter::O_GETRND() { Flags::Id flag = readScriptFlagId(); uint16 rndSeed = readScript(); debugInterpreter("O_GETRND flag %d, rndSeed %d", flag, rndSeed); // puts and random value as flag value // fairly random value ;) - // _flags->setFlagValue(flag, 4); + int value = _vm->_randomSource.getRandomNumber(rndSeed); + _flags->setFlagValue(flag, value); } void Interpreter::O_TALKBACKANIM() { @@ -1275,33 +1283,32 @@ void Interpreter::O_CALLDFLAG() { void Interpreter::O_PRINTAT() { uint16 slot = readScriptFlagValue(); - uint16 fr1 = readScriptFlagValue(); - uint16 fr2 = readScriptFlagValue(); - - debugInterpreter("O_PRINTAT slot %d, fr1 %d, fr2 %d", slot, fr1, fr2); - + uint16 x = readScriptFlagValue(); + uint16 y = readScriptFlagValue(); + debugInterpreter("O_PRINTAT slot %d, x %d, y %d", slot, x, y); uint8 color = _flags->getFlagValue(Flags::KOLOR); - - _vm->printAt(slot, color, (char *)_string, fr1, fr2); - + _vm->printAt(slot, color, (char *)_string, x, y); increaseString(); } void Interpreter::O_ZOOMIN() { uint16 slot = readScriptFlagValue(); + _vm->initZoomIn(slot); debugInterpreter("O_ZOOMIN slot %04d", slot); } void Interpreter::O_ZOOMOUT() { uint16 slot = readScriptFlagValue(); + _vm->initZoomOut(slot); debugInterpreter("O_ZOOMOUT slot %d", slot); } +// TODO - never used? void Interpreter::O_SETSTRINGOFFSET() { int32 offset = readScript(); debugInterpreter("O_SETSTRINGOFFSET offset %04x", offset); - // _currentString = "" - // _string = (const char *)_currentInstruction + offset + _currentString = 0; + _string = (byte *)_currentInstruction + offset; //FIXME } void Interpreter::O_GETOBJDATA() { From a838b34b4dc9968c06ab1ebf27efad85d54216a0 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 4 Jul 2014 19:10:22 +0200 Subject: [PATCH 227/374] PRINCE: Background animations update. O_PUTBACKANIM(), O_REMBACKANIM(), O_ANIMUPDATEON(), O_ANIMUPDATEOFF() --- engines/prince/prince.cpp | 175 +++++++++++++++++++++----------------- engines/prince/prince.h | 2 + engines/prince/script.cpp | 61 +++++++++---- engines/prince/script.h | 5 +- 4 files changed, 144 insertions(+), 99 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 0430a967c1a9..10f90288c0d1 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -288,6 +288,12 @@ void PrinceEngine::init() { _mainHero->loadAnimSet(1); _secondHero->loadAnimSet(3); + BackgroundAnim tempBackAnim; + tempBackAnim._seq._currRelative = 0; + for (int i = 0; i < kMaxBackAnims; i++) { + _backAnimList.push_back(tempBackAnim); + } + Anim tempAnim; tempAnim._animData = nullptr; tempAnim._shadowData = nullptr; @@ -867,20 +873,22 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis case 2: case 5: //check_ba_mob - if (mob._mask < _backAnimList.size()) { + if (!_backAnimList[mob._mask].backAnims.empty()) { int currentAnim = _backAnimList[mob._mask]._seq._currRelative; Anim &backAnim = _backAnimList[mob._mask].backAnims[currentAnim]; - if (!backAnim._state) { - Common::Rect backAnimRect(backAnim._currX, backAnim._currY, backAnim._currX + backAnim._currW, backAnim._currY + backAnim._currH); - if (backAnimRect.contains(mousePosCamera)) { - int phase = backAnim._showFrame; - int phaseFrameIndex = backAnim._animData->getPhaseFrameIndex(phase); - Graphics::Surface *backAnimSurface = backAnim._animData->getFrame(phaseFrameIndex); - byte pixel = *(byte *)backAnimSurface->getBasePtr(mousePosCamera.x - backAnim._currX, mousePosCamera.y - backAnim._currY); - backAnimSurface->free(); - delete backAnimSurface; - if (pixel != 255) { - break; + 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(mousePosCamera)) { + int phase = backAnim._showFrame; + int phaseFrameIndex = backAnim._animData->getPhaseFrameIndex(phase); + Graphics::Surface *backAnimSurface = backAnim._animData->getFrame(phaseFrameIndex); + byte pixel = *(byte *)backAnimSurface->getBasePtr(mousePosCamera.x - backAnim._currX, mousePosCamera.y - backAnim._currY); + backAnimSurface->free(); + delete backAnimSurface; + if (pixel != 255) { + break; + } } } } @@ -1264,7 +1272,7 @@ void PrinceEngine::showNormAnims() { Anim &anim = _normAnimList[i]; if (anim._animData != nullptr) { if (!anim._state) { - if (anim._frame == anim._lastFrame - 1) { // TODO - check if correct + if (anim._frame == anim._lastFrame - 1) { if (anim._loopType) { if (anim._loopType == 1) { anim._frame = anim._loopFrame; @@ -1303,88 +1311,97 @@ void PrinceEngine::setBackAnim(Anim &backAnim) { } void PrinceEngine::showBackAnims() { - for (uint i = 0; i < _backAnimList.size(); i++) { + for (uint i = 0; i < kMaxBackAnims; i++) { BAS &seq = _backAnimList[i]._seq; int activeSubAnim = seq._currRelative; - - 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; + 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; + } } - 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 (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; + 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++; } - 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; + _backAnimList[i].backAnims[activeSubAnim]._showFrame = _backAnimList[i].backAnims[activeSubAnim]._frame; + showAnim(_backAnimList[i].backAnims[activeSubAnim]); } - } else { - _backAnimList[i].backAnims[activeSubAnim]._frame++; } - _backAnimList[i].backAnims[activeSubAnim]._showFrame = _backAnimList[i].backAnims[activeSubAnim]._frame; - showAnim(_backAnimList[i].backAnims[activeSubAnim]); } } } -void PrinceEngine::clearBackAnimList() { - for (uint i = 0; i < _backAnimList.size(); i++) { - int anims = _backAnimList[i]._seq._anims != 0 ? _backAnimList[i]._seq._anims : 1; +void PrinceEngine::removeSingleBackAnim(int slot) { + if (!_backAnimList[slot].backAnims.empty()) { + int anims = _backAnimList[slot]._seq._anims != 0 ? _backAnimList[slot]._seq._anims : 1; for (int j = 0; j < anims; j++) { - delete _backAnimList[i].backAnims[j]._animData; - delete _backAnimList[i].backAnims[j]._shadowData; + delete _backAnimList[slot].backAnims[j]._animData; + delete _backAnimList[slot].backAnims[j]._shadowData; } - _backAnimList[i].backAnims.clear(); + _backAnimList[slot].backAnims.clear(); + _backAnimList[slot]._seq._currRelative = 0; + } +} + +void PrinceEngine::clearBackAnimList() { + for (int i = 0; i < kMaxBackAnims; i++) { + removeSingleBackAnim(i); } - _backAnimList.clear(); } void PrinceEngine::initZoomIn(int slot) { @@ -2559,7 +2576,7 @@ void PrinceEngine::doTalkAnim(int animNumber, int slot, AnimType animType) { } } } else if (animType == kBackgroundAnimation) { - if ((uint)animNumber < _backAnimList.size()) { + if (!_backAnimList[animNumber].backAnims.empty()) { int currAnim = _backAnimList[animNumber]._seq._currRelative; Anim &backAnim = _backAnimList[animNumber].backAnims[currAnim]; if (backAnim._animData != nullptr) { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index b095da1fc0bd..060f78f681ed 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -300,6 +300,7 @@ class PrinceEngine : public Engine { Script *_script; static const int kMaxNormAnims = 64; + static const int kMaxBackAnims = 64; Common::Array _animList; Common::Array _backAnimList; @@ -308,6 +309,7 @@ class PrinceEngine : public Engine { void freeNormAnim(int slot); void freeAllNormAnims(); + void removeSingleBackAnim(int slot); Common::RandomSource _randomSource; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 8615b1ef9bd2..ab435f2cb111 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -257,6 +257,10 @@ int32 Script::getOptionStandardOffset(int option) { } } +void Script::setBackAnimId(int offset, int animId) { + WRITE_UINT32(&_data[offset], animId); +} + int Script::scanMobEvents(int mobMask, int dataEventOffset) { debug("mobMask: %d", mobMask); int i = 0; @@ -296,7 +300,7 @@ int Script::scanMobEventsWithItem(int mobMask, int dataEventOffset, int itemMask return -1; } -void Script::installSingleBackAnim(Common::Array &_backanimList, int offset) { +void Script::installSingleBackAnim(Common::Array &backAnimList, int slot, int offset) { BackgroundAnim newBackgroundAnim; @@ -371,13 +375,13 @@ void Script::installSingleBackAnim(Common::Array &_backanimList, newBackgroundAnim.backAnims[0]._lastFrame = end; } - _backanimList.push_back(newBackgroundAnim); + backAnimList[slot] = newBackgroundAnim; } } -void Script::installBackAnims(Common::Array &backanimList, int offset) { - for (uint i = 0; i < 64; i++) { - installSingleBackAnim(backanimList, offset); +void Script::installBackAnims(Common::Array &backAnimList, int offset) { + for (uint i = 0; i < _vm->kMaxBackAnims; i++) { + installSingleBackAnim(backAnimList, i, offset); offset += 4; } } @@ -676,12 +680,28 @@ void Interpreter::O_PUTBACKANIM() { uint16 roomId = readScriptFlagValue(); uint16 slot = readScriptFlagValue(); int32 animId = readScript(); + Room *room = new Room(); + room->loadRoom(_script->getRoomOffset(roomId)); + int offset = room->_backAnim + slot * 4; + _vm->_script->setBackAnimId(offset, animId); + if (_vm->_locationNr == roomId) { + _vm->_script->installBackAnims(_vm->_backAnimList, offset); + } + delete room; debugInterpreter("O_PUTBACKANIM roomId %d, slot %d, animId %d", roomId, slot, animId); } void Interpreter::O_REMBACKANIM() { uint16 roomId = readScriptFlagValue(); uint16 slot = readScriptFlagValue(); + if (_vm->_locationNr == roomId) { + _vm->removeSingleBackAnim(slot); + } + Room *room = new Room(); + room->loadRoom(_script->getRoomOffset(roomId)); + int offset = room->_backAnim + slot * 4; + _vm->_script->setBackAnimId(offset, 0); + delete room; debugInterpreter("O_REMBACKANIM roomId %d, slot %d", roomId, slot); } @@ -1495,14 +1515,17 @@ void Interpreter::O_BACKANIMRANGE() { } _result = 1; - if (slotId < _vm->_backAnimList.size()) { - if (animId == 0xFFFF || _vm->_backAnimList[slotId]._seq._current == animId) { - int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; - Anim &backAnim = _vm->_backAnimList[slotId].backAnims[currAnim]; - if (!backAnim._state) { - if (backAnim._frame >= low) { - if (backAnim._frame <= high) { - _result = 0; + if (!_vm->_backAnimList[slotId].backAnims.empty()) { + int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; + if (_vm->_backAnimList[slotId].backAnims[currAnim]._animData != nullptr) { + if (animId == 0xFFFF || _vm->_backAnimList[slotId]._seq._current == animId) { + int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; + Anim &backAnim = _vm->_backAnimList[slotId].backAnims[currAnim]; + if (!backAnim._state) { + if (backAnim._frame >= low) { + if (backAnim._frame <= high) { + _result = 0; + } } } } @@ -1574,19 +1597,22 @@ void Interpreter::O_STOPHERO() { } void Interpreter::O_ANIMUPDATEOFF() { - uint16 slotId = readScript(); + uint16 slotId = readScriptFlagValue(); + _vm->_normAnimList[slotId]._state = 1; debugInterpreter("O_ANIMUPDATEOFF slotId %d", slotId); } void Interpreter::O_ANIMUPDATEON() { uint16 slotId = readScriptFlagValue(); + _vm->_normAnimList[slotId]._state = 0; debugInterpreter("O_ANIMUPDATEON slotId %d", slotId); } void Interpreter::O_FREECURSOR() { + _vm->changeCursor(0); + _vm->_currentPointerNumber = 1; + // free memory here? debugInterpreter("O_FREECURSOR"); - // Change cursor to 0 - // free inv cursor 1 } void Interpreter::O_ADDINVQUIET() { @@ -1601,7 +1627,6 @@ void Interpreter::O_RUNHERO() { uint16 x = readScriptFlagValue(); uint16 y = readScriptFlagValue(); uint16 dir = readScriptFlagValue(); - debugInterpreter("O_RUNHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); } @@ -1627,7 +1652,7 @@ void Interpreter::O_CHECKFLCFRAME() { debugInterpreter("O_CHECKFLCFRAME frame number %d", frameNr); if (_vm->_flicPlayer.getCurFrame() != frameNr) { - // Move instruction pointer before current instruciton + // Move instruction pointer before current instruction // must do this check once again till it's false _currentInstruction -= 2; _opcodeNF = 1; diff --git a/engines/prince/script.h b/engines/prince/script.h index 99a6af3427c2..278a8c858e44 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -137,8 +137,9 @@ class Script { int32 getShadowScale(int locationNr); uint8 *getRoomOffset(int locationNr); int32 getOptionStandardOffset(int option); - void installBackAnims(Common::Array &_backanimList, int offset); - void installSingleBackAnim(Common::Array &_backanimList, int offset); + void setBackAnimId(int offset, int animId); + void installBackAnims(Common::Array &backAnimList, int offset); + void installSingleBackAnim(Common::Array &backAnimList, int slot, int offset); bool loadAllMasks(Common::Array &maskList, int offset); int scanMobEvents(int mobMask, int dataEventOffset); From 092c3683b49288f9068a8dee5ae8db9071baab07 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 4 Jul 2014 22:00:02 +0200 Subject: [PATCH 228/374] PRINCE: O_GETOBJDATA(), O_SETOBJDATA() --- engines/prince/object.cpp | 25 +++++++++++++++++++++++++ engines/prince/object.h | 16 ++++++++++++++++ engines/prince/prince.cpp | 3 +-- engines/prince/prince.h | 2 +- engines/prince/script.cpp | 9 ++++++--- 5 files changed, 49 insertions(+), 6 deletions(-) diff --git a/engines/prince/object.cpp b/engines/prince/object.cpp index 86d4238bc0a2..22ed0a765653 100644 --- a/engines/prince/object.cpp +++ b/engines/prince/object.cpp @@ -85,5 +85,30 @@ bool Object::loadFromStream(Common::SeekableReadStream &stream) { return true; } +void Object::setData(AttrId dataId, uint16 value) { + switch (dataId) { + case kObjectX: + _x = value; + break; + case kObjectY: + _y = value; + break; + default: + assert(false); + } +} + +uint16 Object::getData(AttrId dataId) { + switch (dataId) { + case kObjectX: + return _x; + case kObjectY: + return _y; + default: + assert(false); + return 0; + } +} + } /* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/object.h b/engines/prince/object.h index 1fb7465a0db6..3d0257cad4e1 100644 --- a/engines/prince/object.h +++ b/engines/prince/object.h @@ -44,8 +44,24 @@ class Object { int32 _zoomInAddr; int32 _zoomInTime; + // Used instead of offset in setData and getData + enum AttrId { + kObjectAddr = 0, + kObjectX = 4, + kObjectY = 6, + kObjectZ = 8, + kObjectFlags = 10, + kObjectZoomInSource = 12, + kObjectZoomInLen = 16, + kObjectZoomInAddr = 20, + kObjectZoomInTime = 24 + }; + bool loadFromStream(Common::SeekableReadStream &stream); Graphics::Surface *getSurface() const { return _surface; } + uint16 getData(AttrId dataId); + void setData(AttrId dataId, uint16 value); + private: void loadSurface(Common::SeekableReadStream &stream); Graphics::Surface *_surface; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 10f90288c0d1..3140f2298f1c 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1388,8 +1388,7 @@ void PrinceEngine::showBackAnims() { void PrinceEngine::removeSingleBackAnim(int slot) { if (!_backAnimList[slot].backAnims.empty()) { - int anims = _backAnimList[slot]._seq._anims != 0 ? _backAnimList[slot]._seq._anims : 1; - for (int j = 0; j < anims; j++) { + for (uint j = 0; j < _backAnimList[slot].backAnims.size(); j++) { delete _backAnimList[slot].backAnims[j]._animData; delete _backAnimList[slot].backAnims[j]._shadowData; } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 060f78f681ed..a96aba56c1d4 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -306,6 +306,7 @@ class PrinceEngine : public Engine { Common::Array _backAnimList; Common::Array _normAnimList; Common::Array _mobList; + Common::Array _objList; void freeNormAnim(int slot); void freeAllNormAnims(); @@ -474,7 +475,6 @@ class PrinceEngine : public Engine { Audio::SoundHandle _soundHandle[MAX_SAMPLES]; Common::Array _pscrList; - Common::Array _objList; Common::Array _maskList; Common::Array _drawNodeList; Common::Array _allInvList; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index ab435f2cb111..4c9c28f1b307 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -615,7 +615,6 @@ void Interpreter::O_PUTOBJECT() { void Interpreter::O_REMOBJECT() { uint16 roomId = readScriptFlagValue(); uint16 objectId = readScriptFlagValue(); - debugInterpreter("O_REMOBJECT roomId %d objectId %d", roomId, objectId); } @@ -1335,6 +1334,8 @@ void Interpreter::O_GETOBJDATA() { Flags::Id flag = readScriptFlagId(); uint16 obj = readScriptFlagValue(); int16 objOffset = readScriptFlagValue(); + int16 value = _vm->_objList[obj]->getData((Object::AttrId)objOffset); + _flags->setFlagValue(flag, value); debugInterpreter("O_GETOBJDATA flag %d, obj %d, objOffset %d", flag, obj, objOffset); } @@ -1342,12 +1343,14 @@ void Interpreter::O_SETOBJDATA() { uint16 obj = readScriptFlagValue(); int16 objOffset = readScriptFlagValue(); uint16 value = readScriptFlagValue(); + _vm->_objList[obj]->setData((Object::AttrId)objOffset, value); debugInterpreter("O_SETOBJDATA obj %d, objOffset %d, value %d", obj, objOffset, value); } +// not used? void Interpreter::O_SWAPOBJECTS() { - uint16 obj1 = readScript(); - uint16 obj2 = readScript(); + uint16 obj1 = readScriptFlagValue(); + uint16 obj2 = readScriptFlagValue(); debugInterpreter("O_SWAPOBJECTS obj1 %d, obj2 %d", obj1, obj2); } From 727b16cf7389c9e4b0a855eafdd677e7cf0e0d1b Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 5 Jul 2014 16:05:34 +0200 Subject: [PATCH 229/374] PRINCE: checkSeq() update --- engines/prince/script.cpp | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 4c9c28f1b307..7322752e6d05 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1375,29 +1375,17 @@ void Interpreter::O_SUBSTRING() { int Interpreter::checkSeq(byte *string) { int freeHSlotIncrease = 0; byte c; - while (1) { - c = string[0]; + while ((c = string[0]) != 0xFF) { string++; if (c < 0xF0) { - //not_spec freeHSlotIncrease++; - while (1) { - c = string[0]; - if (c == 0) { - break; - } + while ((c = string[0])) { string++; } string++; - continue; - } - if (c == 0xFF) { - break; - } - if (c == 0xFE) { - continue; // pause + } else if (c != 0xFE) { + string++; } - string++; } return freeHSlotIncrease; } From 0301b635deae45fac6ea8dd66917b5e1c09213e8 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 5 Jul 2014 22:31:02 +0200 Subject: [PATCH 230/374] PRINCE: installObjects(), setObjId(), O_PUTOBJECT(), O_REMOBJECT(). checkMob(), showObjects(), O_GETRND() update --- engines/prince/prince.cpp | 63 +++++++++++++++++++++++---------------- engines/prince/prince.h | 2 ++ engines/prince/script.cpp | 47 +++++++++++++++++++++++------ engines/prince/script.h | 3 ++ 4 files changed, 81 insertions(+), 34 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 3140f2298f1c..62b5197cac1f 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -132,6 +132,8 @@ PrinceEngine::~PrinceEngine() { } _objList.clear(); + delete[] _objSlot; + for (uint32 i = 0; i < _pscrList.size(); i++) { delete _pscrList[i]; } @@ -300,6 +302,11 @@ void PrinceEngine::init() { for (int i = 0; i < kMaxNormAnims; i++) { _normAnimList.push_back(tempAnim); } + + _objSlot = new int[kMaxObjects]; + for (int i = 0; i < kMaxObjects; i++) { + _objSlot[i] = -1; + } } void PrinceEngine::showLogo() { @@ -436,6 +443,8 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { freeDrawNodes(); + _script->installObjects(_room->_obj); + clearBackAnimList(); _script->installBackAnims(_backAnimList, _room->_backAnim); @@ -857,14 +866,17 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis break; case 3: //mob_obj - if (mob._mask < _objList.size()) { - Object &obj = *_objList[mob._mask]; - Common::Rect objectRect(obj._x, obj._y, obj._x + obj._width, obj._y + obj._height); - if (objectRect.contains(mousePosCamera)) { - Graphics::Surface *objSurface = obj.getSurface(); - byte *pixel = (byte *)objSurface->getBasePtr(mousePosCamera.x - obj._x, mousePosCamera.y - obj._y); - if (*pixel != 255) { - break; + if (mob._mask < kMaxObjects) { + int nr = _objSlot[mob._mask]; + if (nr != -1) { + Object &obj = *_objList[nr]; + Common::Rect objectRect(obj._x, obj._y, obj._x + obj._width, obj._y + obj._height); + if (objectRect.contains(mousePosCamera)) { + Graphics::Surface *objSurface = obj.getSurface(); + byte *pixel = (byte *)objSurface->getBasePtr(mousePosCamera.x - obj._x, mousePosCamera.y - obj._y); + if (*pixel != 255) { + break; + } } } } @@ -1412,35 +1424,36 @@ void PrinceEngine::initZoomOut(int slot) { } void PrinceEngine::showObjects() { - if (!_objList.empty()) { - for (uint i = 0; i < _objList.size(); i++) { - if ((_objList[i]->_mask & 0x8000) != 0) { - _objList[i]->_zoomInTime--; - if (_objList[i]->_zoomInTime == 0) { - _objList[i]->_mask &= 0x7FFF; + for (int i = 0; i < kMaxObjects; i++) { + int nr = _objSlot[i]; + if (nr != -1) { + if ((_objList[nr]->_mask & 0x8000) != 0) { + _objList[nr]->_zoomInTime--; + if (_objList[nr]->_zoomInTime == 0) { + _objList[nr]->_mask &= 0x7FFF; } else { // doZoomIn(); // mov edx, d [esi.Obj_ZoomInAddr] } } - if ((_objList[i]->_mask & 0x4000) != 0) { - _objList[i]->_zoomInTime--; - if (_objList[i]->_zoomInTime == 0) { - _objList[i]->_mask &= 0xBFFF; + if ((_objList[nr]->_mask & 0x4000) != 0) { + _objList[nr]->_zoomInTime--; + if (_objList[nr]->_zoomInTime == 0) { + _objList[nr]->_mask &= 0xBFFF; } else { // doZoomOut(); // mov edx, d [esi.Obj_ZoomInAddr] } } - Graphics::Surface *objSurface = _objList[i]->getSurface(); - if (spriteCheck(objSurface->w, objSurface->h, _objList[i]->_x, _objList[i]->_y)) { + Graphics::Surface *objSurface = _objList[nr]->getSurface(); + if (spriteCheck(objSurface->w, objSurface->h, _objList[nr]->_x, _objList[nr]->_y)) { if ((_objList[i]->_mask & 0x0200) == 0) { - int destX = _objList[i]->_x - _picWindowX; - int destY = _objList[i]->_y - _picWindowY; + int destX = _objList[nr]->_x - _picWindowX; + int destY = _objList[nr]->_y - _picWindowY; DrawNode newDrawNode; newDrawNode.posX = destX; newDrawNode.posY = destY; - newDrawNode.posZ = _objList[i]->_z; + newDrawNode.posZ = _objList[nr]->_z; newDrawNode.width = 0; newDrawNode.height = 0; newDrawNode.s = objSurface; @@ -1453,8 +1466,8 @@ void PrinceEngine::showObjects() { // showBackSprite(); } } - if ((_objList[i]->_mask & 1) != 0) { - checkMasks(_objList[i]->_x, _objList[i]->_y, objSurface->w, objSurface->h, _objList[i]->_z); + if ((_objList[nr]->_mask & 1) != 0) { + checkMasks(_objList[nr]->_x, _objList[nr]->_y, objSurface->w, objSurface->h, _objList[nr]->_z); } } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index a96aba56c1d4..6ad5dd35e5d5 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -301,12 +301,14 @@ class PrinceEngine : public Engine { static const int kMaxNormAnims = 64; static const int kMaxBackAnims = 64; + static const int kMaxObjects = 64; Common::Array _animList; Common::Array _backAnimList; Common::Array _normAnimList; Common::Array _mobList; Common::Array _objList; + int *_objSlot; void freeNormAnim(int slot); void freeAllNormAnims(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 7322752e6d05..84dfd7754a7c 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -261,6 +261,10 @@ void Script::setBackAnimId(int offset, int animId) { WRITE_UINT32(&_data[offset], animId); } +void Script::setObjId(int offset, int objId) { + _data[offset] = objId; +} + int Script::scanMobEvents(int mobMask, int dataEventOffset) { debug("mobMask: %d", mobMask); int i = 0; @@ -380,12 +384,23 @@ void Script::installSingleBackAnim(Common::Array &backAnimList, } void Script::installBackAnims(Common::Array &backAnimList, int offset) { - for (uint i = 0; i < _vm->kMaxBackAnims; i++) { + for (int i = 0; i < _vm->kMaxBackAnims; i++) { installSingleBackAnim(backAnimList, i, offset); offset += 4; } } +void Script::installObjects(int offset) { + for (int i = 0; i < _vm->kMaxObjects; i++) { + if (_data[offset] != 0xFF) { + _vm->_objSlot[i] = i; + } else { + _vm->_objSlot[i] = -1; + } + offset++; + } +} + bool Script::loadAllMasks(Common::Array &maskList, int offset) { Mask tempMask; while (1) { @@ -565,9 +580,10 @@ Flags::Id Interpreter::readScriptFlagId() { } void Interpreter::O_WAITFOREVER() { - //debugInterpreter("O_WAITFOREVER"); + _vm->changeCursor(_vm->_currentPointerNumber); _opcodeNF = 1; _currentInstruction -= 2; + //debugInterpreter("O_WAITFOREVER"); } void Interpreter::O_BLACKPALETTE() { @@ -609,13 +625,29 @@ void Interpreter::O_PUTOBJECT() { uint16 roomId = readScriptFlagValue(); uint16 slot = readScriptFlagValue(); uint16 objectId = readScriptFlagValue(); + Room *room = new Room(); + room->loadRoom(_script->getRoomOffset(roomId)); + int offset = room->_obj + slot; + _vm->_script->setObjId(offset, objectId); + if (_vm->_locationNr == roomId) { + _vm->_objSlot[slot] = objectId; + } + delete room; debugInterpreter("O_PUTOBJECT roomId %d, slot %d, objectId %d", roomId, slot, objectId); } void Interpreter::O_REMOBJECT() { uint16 roomId = readScriptFlagValue(); - uint16 objectId = readScriptFlagValue(); - debugInterpreter("O_REMOBJECT roomId %d objectId %d", roomId, objectId); + uint16 slot = readScriptFlagValue(); + Room *room = new Room(); + room->loadRoom(_script->getRoomOffset(roomId)); + int offset = room->_obj + slot; + _vm->_script->setObjId(offset, 0xFF); + if (_vm->_locationNr == roomId) { + _vm->_objSlot[slot] = -1; + } + delete room; + debugInterpreter("O_REMOBJECT roomId %d slot %d", roomId, slot); } void Interpreter::O_SHOWANIM() { @@ -1252,15 +1284,12 @@ void Interpreter::O_SETBACKFRAME() { debugInterpreter("O_SETBACKFRAME anim %d, frame %d", anim, frame); } -// TODO - check if proper max for getRandomNumber void Interpreter::O_GETRND() { Flags::Id flag = readScriptFlagId(); uint16 rndSeed = readScript(); - debugInterpreter("O_GETRND flag %d, rndSeed %d", flag, rndSeed); - // puts and random value as flag value - // fairly random value ;) - int value = _vm->_randomSource.getRandomNumber(rndSeed); + int value = _vm->_randomSource.getRandomNumber(rndSeed - 1); _flags->setFlagValue(flag, value); + debugInterpreter("O_GETRND flag %d, rndSeed %d, value %d", flag, rndSeed, value); } void Interpreter::O_TALKBACKANIM() { diff --git a/engines/prince/script.h b/engines/prince/script.h index 278a8c858e44..17ae0dc91759 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -37,6 +37,7 @@ namespace Prince { class PrinceEngine; class Animation; +class Object; struct Anim; struct BackgroundAnim; struct Mask; @@ -138,8 +139,10 @@ class Script { uint8 *getRoomOffset(int locationNr); int32 getOptionStandardOffset(int option); void setBackAnimId(int offset, int animId); + void setObjId(int offset, int objId); void installBackAnims(Common::Array &backAnimList, int offset); void installSingleBackAnim(Common::Array &backAnimList, int slot, int offset); + void installObjects(int offset); bool loadAllMasks(Common::Array &maskList, int offset); int scanMobEvents(int mobMask, int dataEventOffset); From bdd7206fe2f508989331525563a586574d19bfe4 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 7 Jul 2014 00:19:15 +0200 Subject: [PATCH 231/374] PRINCE: setVoice() fix --- engines/prince/prince.cpp | 7 ++++--- engines/prince/script.cpp | 2 +- engines/prince/variatxt.cpp | 4 ++-- engines/prince/variatxt.h | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 62b5197cac1f..29cd43c079db 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -643,7 +643,8 @@ void PrinceEngine::setVoice(uint16 slot, uint32 sampleSlot, uint16 flag) { uint32 currentString = _interpreter->getCurrentString(); if (currentString >= 80000) { - sampleName = Common::String::format("%05d-%02d.WAV", currentString - 80000, flag); + 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) { @@ -2072,7 +2073,7 @@ void PrinceEngine::inventoryLeftMouseButton() { textNr = 80020; // "Nothing is happening." } _interpreter->setCurrentString(textNr); - printAt(0, 216, _variaTxt->getString(textNr - 80000), kNormalWidth / 2, 100); + printAt(0, 216, (char *)_variaTxt->getString(textNr - 80000), kNormalWidth / 2, 100); setVoice(0, 28, 1); playSample(28, 0); //exit_normally @@ -2147,7 +2148,7 @@ void PrinceEngine::inventoryLeftMouseButton() { textNr = 80020; // "Nothing is happening." } _interpreter->setCurrentString(textNr); - printAt(0, 216, _variaTxt->getString(textNr - 80000), kNormalWidth / 2, 100); + printAt(0, 216, (char *)_variaTxt->getString(textNr - 80000), kNormalWidth / 2, 100); setVoice(0, 28, 1); playSample(28, 0); //exit_normally diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 84dfd7754a7c..93a4b9621e67 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -932,7 +932,7 @@ void Interpreter::O_SETSTRING() { _currentString = offset; if (offset >= 80000) { - _string = (byte *)_vm->_variaTxt->getString(offset - 80000); + _string = _vm->_variaTxt->getString(offset - 80000); debugInterpreter("GetVaria %s", _string); } else if (offset < 2000) { diff --git a/engines/prince/variatxt.cpp b/engines/prince/variatxt.cpp index 56fbd2911a84..eb4efd88771a 100644 --- a/engines/prince/variatxt.cpp +++ b/engines/prince/variatxt.cpp @@ -42,12 +42,12 @@ bool VariaTxt::loadFromStream(Common::SeekableReadStream &stream) { return true; } -char *VariaTxt::getString(uint32 stringId) { +byte *VariaTxt::getString(uint32 stringId) { uint32 stringOffset = READ_LE_UINT32(_data + stringId * 4); if (stringOffset > _dataSize) { assert(false); } - return (char *)_data + stringOffset; + return _data + stringOffset; } } diff --git a/engines/prince/variatxt.h b/engines/prince/variatxt.h index b7fc7e3ac54a..98efad20597e 100644 --- a/engines/prince/variatxt.h +++ b/engines/prince/variatxt.h @@ -32,7 +32,7 @@ class VariaTxt { bool loadFromStream(Common::SeekableReadStream &stream); - char *getString(uint32 stringId); + byte *getString(uint32 stringId); private: uint32 _dataSize; From c7eada5b1db234f63fd25f4d397c1dbdf218fbbd Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 7 Jul 2014 03:12:35 +0200 Subject: [PATCH 232/374] PRINCE: O_COMPAREHI, O_COMPARELO fix, debugger update --- engines/prince/debugger.cpp | 34 +++++++++++++++++++++++++--------- engines/prince/debugger.h | 5 ++++- engines/prince/object.cpp | 2 +- engines/prince/prince.cpp | 3 ++- engines/prince/script.cpp | 22 +++++++++++++++------- 5 files changed, 47 insertions(+), 19 deletions(-) diff --git a/engines/prince/debugger.cpp b/engines/prince/debugger.cpp index 95df1ec4bf60..445d5ecfc46d 100644 --- a/engines/prince/debugger.cpp +++ b/engines/prince/debugger.cpp @@ -22,10 +22,12 @@ #include "prince/debugger.h" #include "prince/prince.h" +#include "prince/flags.h" +#include "prince/script.h" namespace Prince { -Debugger::Debugger(PrinceEngine *vm) : GUI::Debugger(), _vm(vm), _locationNr(0) { +Debugger::Debugger(PrinceEngine *vm, InterpreterFlags *flags) : GUI::Debugger(), _vm(vm), _locationNr(0), _flags(flags) { DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); DCmd_Register("level", WRAP_METHOD(Debugger, Cmd_DebugLevel)); DCmd_Register("setflag", WRAP_METHOD(Debugger, Cmd_SetFlag)); @@ -34,6 +36,7 @@ Debugger::Debugger(PrinceEngine *vm) : GUI::Debugger(), _vm(vm), _locationNr(0) DCmd_Register("viewflc", WRAP_METHOD(Debugger, Cmd_ViewFlc)); DCmd_Register("initroom", WRAP_METHOD(Debugger, Cmd_InitRoom)); DCmd_Register("changecursor", WRAP_METHOD(Debugger, Cmd_ChangeCursor)); + DCmd_Register("additem", WRAP_METHOD(Debugger, Cmd_AddItem)); } static int strToInt(const char *s) { @@ -73,13 +76,14 @@ bool Debugger::Cmd_DebugLevel(int argc, const char **argv) { */ bool Debugger::Cmd_SetFlag(int argc, const char **argv) { // Check for a flag to set - if (argc != 2) { - DebugPrintf("Usage: %s \n", argv[0]); + if (argc != 3) { + DebugPrintf("Usage: %s \n", argv[0]); return true; } - //int flagNum = strToInt(argv[1]); - //g_globals->setFlag(flagNum); + int flagNum = strToInt(argv[1]); + uint16 value = strToInt(argv[2]); + _flags->setFlagValue((Flags::Id)flagNum, value); return true; } @@ -93,8 +97,8 @@ bool Debugger::Cmd_GetFlag(int argc, const char **argv) { return true; } - //int flagNum = strToInt(argv[1]); - //DebugPrintf("Value: %d\n", g_globals->getFlag(flagNum)); + int flagNum = strToInt(argv[1]); + DebugPrintf("Value: %d\n", _flags->getFlagValue((Flags::Id)flagNum)); return true; } @@ -108,8 +112,8 @@ bool Debugger::Cmd_ClearFlag(int argc, const char **argv) { return true; } - //int flagNum = strToInt(argv[1]); - //g_globals->clearFlag(flagNum); + int flagNum = strToInt(argv[1]); + _flags->setFlagValue((Flags::Id)flagNum, 0); return true; } @@ -151,6 +155,18 @@ bool Debugger::Cmd_ChangeCursor(int argc, const char **argv) { return true; } +bool Debugger::Cmd_AddItem(int argc, const char **argv) { + if (argc != 2) { + DebugPrintf("Usage: %s \n", argv[0]); + return true; + } + + int itemId = strToInt(argv[1]); + _vm->addInv(0, itemId, true); + + return true; +} + } /* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/debugger.h b/engines/prince/debugger.h index f3608af81d0b..10c82d528219 100644 --- a/engines/prince/debugger.h +++ b/engines/prince/debugger.h @@ -29,10 +29,11 @@ namespace Prince { class PrinceEngine; +class InterpreterFlags; class Debugger : public GUI::Debugger { public: - Debugger(PrinceEngine *vm); + Debugger(PrinceEngine *vm, InterpreterFlags *flags); virtual ~Debugger() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ uint8 _locationNr; @@ -46,8 +47,10 @@ class Debugger : public GUI::Debugger { bool Cmd_ViewFlc(int argc, const char **argv); bool Cmd_InitRoom(int argc, const char **argv); bool Cmd_ChangeCursor(int argc, const char **argv); + bool Cmd_AddItem(int argc, const char **argv); PrinceEngine *_vm; + InterpreterFlags *_flags; }; } diff --git a/engines/prince/object.cpp b/engines/prince/object.cpp index 22ed0a765653..b7ff18c46cb3 100644 --- a/engines/prince/object.cpp +++ b/engines/prince/object.cpp @@ -68,7 +68,7 @@ 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) { - error("Can't load %s", obStreamName.c_str()); + //error("Can't load %s", obStreamName.c_str()); return false; } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 29cd43c079db..7e447376d905 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -205,7 +205,6 @@ void PrinceEngine::init() { _graph = new GraphicsMan(this); _rnd = new Common::RandomSource("prince"); - _debugger = new Debugger(this); _midiPlayer = new MusicPlayer(this); @@ -226,6 +225,8 @@ void PrinceEngine::init() { _flags = new InterpreterFlags(); _interpreter = new Interpreter(this, _script, _flags); + _debugger = new Debugger(this, _flags); + _variaTxt = new VariaTxt(); Resource::loadResource(_variaTxt, "variatxt.dat", true); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 93a4b9621e67..2ca18746deef 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -419,7 +419,7 @@ bool Script::loadAllMasks(Common::Array &maskList, int offset) { const Common::String msStreamName = Common::String::format("MS%02d", tempMask._number); Common::SeekableReadStream *msStream = SearchMan.createReadStreamForMember(msStreamName); if (!msStream) { - error("Can't load %s", msStreamName.c_str()); + //error("Can't load %s", msStreamName.c_str()); delete msStream; return false; } @@ -1154,17 +1154,25 @@ void Interpreter::O_RUNACTION() { void Interpreter::O_COMPAREHI() { Flags::Id flag = readScriptFlagId(); uint16 value = readScriptFlagValue(); - - debugInterpreter("O_COMPAREHI flag %d, value %d", flag, value); - _result = value < _flags->getFlagValue(flag); + uint16 flagValue = _flags->getFlagValue(flag); + if (flagValue > value) { + _result = 0; + } else { + _result = 1; + } + debugInterpreter("O_COMPAREHI flag %04x - (%s), value %d, flagValue %d, result %d", flag, Flags::getFlagName(flag), value, flagValue, _result); } void Interpreter::O_COMPARELO() { Flags::Id flag = readScriptFlagId(); uint16 value = readScriptFlagValue(); - - debugInterpreter("O_COMPARELO flag %d, value %d", flag, value); - _result = value > _flags->getFlagValue(flag); + uint16 flagValue = _flags->getFlagValue(flag); + if (flagValue < value) { + _result = 0; + } else { + _result = 1; + } + debugInterpreter("O_COMPARELO flag %04x - (%s), value %d, flagValue %d, result %d", flag, Flags::getFlagName(flag), value, flagValue, _result); } void Interpreter::O_PRELOADSET() { From 9df716ea9c177cd78c04950fbff896a581470b4b Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 7 Jul 2014 03:55:57 +0200 Subject: [PATCH 233/374] PRINCE: Interpreter flags fix. --- engines/prince/script.cpp | 8 ++++---- engines/prince/script.h | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 2ca18746deef..fba021d0f5e9 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -451,12 +451,12 @@ void InterpreterFlags::resetAllFlags() { memset(_flags, 0, sizeof(_flags)); } -void InterpreterFlags::setFlagValue(Flags::Id flagId, uint16 value) { - _flags[(uint16)flagId - FLAG_MASK] = value; +void InterpreterFlags::setFlagValue(Flags::Id flagId, uint32 value) { + _flags[(uint32)flagId - FLAG_MASK] = value; } -uint16 InterpreterFlags::getFlagValue(Flags::Id flagId) { - return _flags[(uint16)flagId - FLAG_MASK]; +uint32 InterpreterFlags::getFlagValue(Flags::Id flagId) { + return _flags[(uint32)flagId - FLAG_MASK]; } Interpreter::Interpreter(PrinceEngine *vm, Script *script, InterpreterFlags *flags) : diff --git a/engines/prince/script.h b/engines/prince/script.h index 17ae0dc91759..11f1cb8cd7a7 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -165,8 +165,8 @@ class InterpreterFlags { public: InterpreterFlags(); - void setFlagValue(Flags::Id flag, uint16 value); - uint16 getFlagValue(Flags::Id flag); + void setFlagValue(Flags::Id flag, uint32 value); + uint32 getFlagValue(Flags::Id flag); void resetAllFlags(); @@ -174,7 +174,7 @@ class InterpreterFlags { private: static const uint16 MAX_FLAGS = 2000; - int16 _flags[MAX_FLAGS]; + int32 _flags[MAX_FLAGS]; }; class Interpreter { From b7b65f08539f08df2eefd029bacc897fc6112d5b Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 7 Jul 2014 19:41:41 +0200 Subject: [PATCH 234/374] PRINCE: LMB, RMB update, texts skipping --- engines/prince/prince.cpp | 152 ++++++++++++++++++++++---------------- engines/prince/prince.h | 5 +- 2 files changed, 93 insertions(+), 64 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 7e447376d905..e5c523108f61 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -88,7 +88,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _optionsWidth(210), _optionsHeight(170), _invOptionsWidth(210), _invOptionsHeight(130), _optionsStep(20), _invOptionsStep(20), _optionsNumber(7), _invOptionsNumber(5), _optionsColor1(236), _optionsColor2(252), _dialogWidth(600), _dialogHeight(0), _dialogLineSpace(10), _dialogColor1(220), _dialogColor2(223), - _dialogFlag(false), _dialogLines(0), _dialogText(nullptr) { + _dialogFlag(false), _dialogLines(0), _dialogText(nullptr), _mouseFlag(1) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -457,6 +457,8 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { void PrinceEngine::changeCursor(uint16 curId) { _debugger->_cursorNr = curId; + _mouseFlag = curId; + _flags->setFlagValue(Flags::MOUSEENABLED, curId); const Graphics::Surface *curSurface = nullptr; @@ -601,8 +603,8 @@ bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamNam bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::String &streamName) { debugEngine("Loading wav %s slot %d", streamName.c_str(), slot); - if (slot > MAXTEXTS) { - error("Text slot bigger than MAXTEXTS %d", MAXTEXTS); + if (slot > kMaxTexts) { + error("Text slot bigger than MAXTEXTS %d", kMaxTexts); return false; } @@ -848,6 +850,10 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis Common::Point mousepos = _system->getEventManager()->getMousePos(); Common::Point mousePosCamera(mousepos.x + _picWindowX, mousepos.y); + if (_mouseFlag == 0 || _mouseFlag == 3) { + return -1; + } + int mobNumber = 0; for (Common::Array::const_iterator it = mobList.begin(); it != mobList.end() ; it++) { const Mob& mob = *it; @@ -1032,7 +1038,7 @@ uint32 PrinceEngine::getTextWidth(const char *s) { } void PrinceEngine::showTexts(Graphics::Surface *screen) { - for (uint32 slot = 0; slot < MAXTEXTS; ++slot) { + for (uint32 slot = 0; slot < kMaxTexts; slot++) { Text& text = _textSlots[slot]; if (!text._str && !text._time) { continue; @@ -1059,7 +1065,7 @@ void PrinceEngine::showTexts(Graphics::Surface *screen) { } int textSkip = 2; - for (uint8 i = 0; i < lines.size(); i++) { + for (uint i = 0; i < lines.size(); i++) { int x = text._x - getTextWidth(lines[i].c_str()) / 2; int y = text._y - 10 - (lines.size() - i) * (_font->getFontHeight() - textSkip); if (x < 0) { @@ -1956,78 +1962,100 @@ void PrinceEngine::drawInvItems() { } void PrinceEngine::leftMouseButton() { - int option = 0; - int optionEvent = -1; + if (_mouseFlag) { + int option = 0; + int optionEvent = -1; - if (_optionsFlag) { - if (_optionEnabled < _optionsNumber) { - option = _optionEnabled; - _optionsFlag = 0; + if (_optionsFlag) { + if (_optionEnabled < _optionsNumber) { + option = _optionEnabled; + _optionsFlag = 0; + } else { + return; + } } else { - return; - } - } else { - _optionsMob = _selectedMob; - if (_optionsMob == -1) { - // @@walkto - TODO - return; - } - option = 0; - } - //do_option - if (_currentPointerNumber != 2) { - //skip_use_code - int optionScriptOffset = _room->getOptionOffset(option); - if (optionScriptOffset != 0) { - optionEvent = _script->scanMobEvents(_optionsMob, optionScriptOffset); - } - if (optionEvent == -1) { - if (option == 0) { - //@@walkto - TODO + _optionsMob = _selectedMob; + if (_optionsMob == -1) { + // @@walkto - TODO return; - } else { - optionEvent = _script->getOptionStandardOffset(option); + } + option = 0; + } + //do_option + if (_currentPointerNumber != 2) { + //skip_use_code + int optionScriptOffset = _room->getOptionOffset(option); + if (optionScriptOffset != 0) { + optionEvent = _script->scanMobEvents(_optionsMob, optionScriptOffset); + } + if (optionEvent == -1) { + if (!option) { + //@@walkto - TODO + return; + } else { + optionEvent = _script->getOptionStandardOffset(option); + } + } + } else if (_selectedMode) { + //give_item + if (_room->_itemGive) { + optionEvent = _script->scanMobEventsWithItem(_optionsMob, _room->_itemGive, _selectedItem); + } + if (optionEvent == -1) { + //standard_giveitem + optionEvent = _script->_scriptInfo.stdGiveItem; + } + } else { + if (_room->_itemUse) { + optionEvent = _script->scanMobEventsWithItem(_optionsMob, _room->_itemUse, _selectedItem); + _flags->setFlagValue(Flags::SELITEM, _selectedItem); + } + if (optionEvent == -1) { + //standard_useitem + optionEvent = _script->_scriptInfo.stdUseItem; } } - } else if (_selectedMode != 0) { - //give_item - if (_room->_itemGive != 0) { - optionEvent = _script->scanMobEventsWithItem(_optionsMob, _room->_itemGive, _selectedItem); - } - if (optionEvent == -1) { - //standard_giveitem - optionEvent = _script->_scriptInfo.stdGiveItem; - } + _interpreter->storeNewPC(optionEvent); + _flags->setFlagValue(Flags::CURRMOB, _selectedMob); + _selectedMob = -1; + _optionsMob = -1; } else { - if (_room->_itemUse != 0) { - optionEvent = _script->scanMobEventsWithItem(_optionsMob, _room->_itemUse, _selectedItem); - _flags->setFlagValue(Flags::SELITEM, _selectedItem); - } - if (optionEvent == -1) { - //standard_useitem - optionEvent = _script->_scriptInfo.stdUseItem; + if (!_flags->getFlagValue(Flags::POWERENABLED)) { + if (!_flags->getFlagValue(Flags::NOCLSTEXT)) { + for (int slot = 0; slot < kMaxTexts; slot++) { + if (slot != kMaxTexts - 9) { + Text& text = _textSlots[slot]; + if (!text._str) { + continue; + } + text._str = 0; + text._time = 0; + } + } + _mainHero->_talkTime = 0; + _secondHero->_talkTime = 0; + } } } - _interpreter->storeNewPC(optionEvent); - _flags->setFlagValue(Flags::CURRMOB, _selectedMob); - _selectedMob = -1; - _optionsMob = -1; } void PrinceEngine::rightMouseButton() { - if (_currentPointerNumber < 2) { - enableOptions(); - } else { - _currentPointerNumber = 1; - changeCursor(1); + if (_mouseFlag) { + if (_currentPointerNumber < 2) { + enableOptions(); + } else { + _currentPointerNumber = 1; + changeCursor(1); + } } } void PrinceEngine::inventoryLeftMouseButton() { - - _textSlots[0]._time = 0; - _textSlots[0]._str = nullptr; - stopSample(28); + if (!_mouseFlag) { + _textSlots[0]._time = 0; + _textSlots[0]._str = nullptr; + stopSample(28); + } if (_optionsFlag == 1) { //check_opt diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 6ad5dd35e5d5..18a087729971 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -283,13 +283,14 @@ class PrinceEngine : public Engine { void printAt(uint32 slot, uint8 color, char *s, uint16 x, uint16 y); int calcText(const char *s); - static const uint8 MAXTEXTS = 32; - Text _textSlots[MAXTEXTS]; + static const uint8 kMaxTexts = 32; + Text _textSlots[kMaxTexts]; uint64 _frameNr; Hero *_mainHero; Hero *_secondHero; + int _mouseFlag; uint16 _locationNr; uint16 _sceneWidth; int32 _picWindowX; From 231ad30262b2b995f73849ea841c30accc49c646 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 7 Jul 2014 19:58:40 +0200 Subject: [PATCH 235/374] PRINCE: Small code clean-up --- engines/prince/prince.cpp | 57 +++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index e5c523108f61..03e2f7479c14 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -486,9 +486,9 @@ void PrinceEngine::changeCursor(uint16 curId) { CursorMan.replaceCursorPalette(_roomBmp->getPalette(), 0, 255); CursorMan.replaceCursor( - curSurface->getBasePtr(0, 0), - curSurface->w, curSurface->h, - hotspotX, hotspotY, + curSurface->getBasePtr(0, 0), + curSurface->w, curSurface->h, + hotspotX, hotspotY, 255, false, &curSurface->format ); @@ -982,7 +982,7 @@ void PrinceEngine::printAt(uint32 slot, uint8 color, char *s, uint16 x, uint16 y if (getLanguage() == Common::DE_DEU) { while (*strPointer) { - switch(*strPointer) { + switch (*strPointer) { case '\xc4': *strPointer = '\x83'; break; @@ -1078,7 +1078,7 @@ void PrinceEngine::showTexts(Graphics::Surface *screen) { } text._time--; - if (text._time == 0) { + if (!text._time) { text._str = nullptr; } } @@ -1120,8 +1120,8 @@ void PrinceEngine::checkMasks(int x1, int y1, int sprWidth, int sprHeight, int z if (x1 < 0) { x1 = 0; } - for (uint i = 0; i < _maskList.size() ; i++) { - if (_maskList[i]._state != 1 && _maskList[i]._flags != 1) { + 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) { @@ -1136,7 +1136,7 @@ void PrinceEngine::checkMasks(int x1, int y1, int sprWidth, int sprHeight, int z // ClsNak void PrinceEngine::clsMasks() { for (uint i = 0; i < _maskList.size(); i++) { - if (_maskList[i]._state == 1) { + if (_maskList[i]._state) { _maskList[i]._state = 0; } } @@ -1145,7 +1145,7 @@ void PrinceEngine::clsMasks() { // InsertNakladki void PrinceEngine::insertMasks(Graphics::Surface *originalRoomSurface) { for (uint i = 0; i < _maskList.size(); i++) { - if (_maskList[i]._state == 1) { + if (_maskList[i]._state) { showMask(i, originalRoomSurface); } } @@ -1153,7 +1153,7 @@ void PrinceEngine::insertMasks(Graphics::Surface *originalRoomSurface) { // ShowNak void PrinceEngine::showMask(int maskNr, Graphics::Surface *originalRoomSurface) { - if (_maskList[maskNr]._flags == 0) { + 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; @@ -1237,16 +1237,16 @@ void PrinceEngine::showAnim(Anim &anim) { if (x != 0 || y != 0 || phaseCount != 1 || frameCount != 1) { // TODO - check if this needed - if (checkMaskFlag != 0) { - if (anim._nextAnim == 0) { + if (checkMaskFlag) { + if (!anim._nextAnim) { z = y + frameHeight - 1; } checkMasks(x, y, frameWidth, frameHeight, z); } - if (specialZFlag != 0) { + if (specialZFlag) { z = specialZFlag; - } else if (maxFrontFlag != 0) { + } else if (maxFrontFlag) { z = kMaxPicHeight + 1; } else { z = y + frameHeight - 1; @@ -1270,12 +1270,12 @@ void PrinceEngine::showAnim(Anim &anim) { int shadowFrameWidth = anim._shadowData->getFrameWidth(shadowPhaseFrameIndex); int shadowFrameHeight = anim._shadowData->getFrameHeight(shadowPhaseFrameIndex); - if (checkMaskFlag != 0) { + if (checkMaskFlag) { checkMasks(shadowX, shadowY, shadowFrameWidth, shadowFrameHeight, shadowY + shadowFrameWidth - 1); } - if (shadowZ == 0) { - if (maxFrontFlag != 0) { + if (!shadowZ) { + if (maxFrontFlag) { shadowZ = kMaxPicHeight + 1; } else { shadowZ = shadowY + shadowFrameWidth - 1; @@ -1435,18 +1435,18 @@ void PrinceEngine::showObjects() { for (int i = 0; i < kMaxObjects; i++) { int nr = _objSlot[i]; if (nr != -1) { - if ((_objList[nr]->_mask & 0x8000) != 0) { + if ((_objList[nr]->_mask & 0x8000)) { _objList[nr]->_zoomInTime--; - if (_objList[nr]->_zoomInTime == 0) { + if (!_objList[nr]->_zoomInTime) { _objList[nr]->_mask &= 0x7FFF; } else { // doZoomIn(); // mov edx, d [esi.Obj_ZoomInAddr] } } - if ((_objList[nr]->_mask & 0x4000) != 0) { + if ((_objList[nr]->_mask & 0x4000)) { _objList[nr]->_zoomInTime--; - if (_objList[nr]->_zoomInTime == 0) { + if (!_objList[nr]->_zoomInTime) { _objList[nr]->_mask &= 0xBFFF; } else { // doZoomOut(); @@ -1474,7 +1474,7 @@ void PrinceEngine::showObjects() { // showBackSprite(); } } - if ((_objList[nr]->_mask & 1) != 0) { + if ((_objList[nr]->_mask & 1)) { checkMasks(_objList[nr]->_x, _objList[nr]->_y, objSurface->w, objSurface->h, _objList[nr]->_z); } } @@ -1547,7 +1547,7 @@ void PrinceEngine::drawScreen() { newDrawNode.data = nullptr; newDrawNode.drawFunction = &_graph->drawTransparentDrawNode; - if (_mainHero->_zoomFactor != 0) { + if (_mainHero->_zoomFactor) { Graphics::Surface *zoomedHeroSurface = _mainHero->zoomSprite(mainHeroSurface); newDrawNode.s = zoomedHeroSurface; newDrawNode.freeSurfaceSMemory = true; @@ -1834,7 +1834,6 @@ void PrinceEngine::addInvObj() { } pause(); } - changeCursor(1); // here? } void PrinceEngine::rememberScreenInv() { @@ -1854,7 +1853,7 @@ void PrinceEngine::prepareInventoryToView() { _invMobList.clear(); int invItem = _mainHero->_inventory.size(); _invLine = invItem / 3; - if (invItem % 3 != 0) { + if (invItem % 3) { _invLine++; } if (_invLine < 4) { @@ -1870,7 +1869,7 @@ void PrinceEngine::prepareInventoryToView() { byte c; uint item = 0; - for (int i = 0 ; i < _invLines; i++) { + for (int i = 0; i < _invLines; i++) { for (int j = 0; j < _invLine; j++) { Mob tempMobItem; if (item < _mainHero->_inventory.size()) { @@ -1908,12 +1907,12 @@ void PrinceEngine::drawInvItems() { int currInvX = _invLineX; int currInvY = _invLineY; uint item = 0; - for (int i = 0 ; i < _invLines; i++) { + for (int i = 0; i < _invLines; i++) { for (int j = 0; j < _invLine; j++) { if (item < _mainHero->_inventory.size()) { - int itemNr = _mainHero->_inventory[item]; // itemNr =- 1 ? + int itemNr = _mainHero->_inventory[item]; _mst_shadow = 0; - if (_mst_shadow2 != 0) { + if (_mst_shadow2) { if (!_flags->getFlagValue(Flags::CURSEBLINK)) { if (item + 1 == _mainHero->_inventory.size()) { // last item in inventory _mst_shadow = 1; From c98549a1848da36c4d5f0ba30b053335d9e65d33 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 7 Jul 2014 20:46:06 +0200 Subject: [PATCH 236/374] PRINCE: O_WAITHEROANIM(), O_WAITTEXT() --- engines/prince/script.cpp | 117 ++++++++++---------------------------- 1 file changed, 29 insertions(+), 88 deletions(-) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index fba021d0f5e9..2ffa76db44c9 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -37,7 +37,7 @@ namespace Prince { -static const uint16 NUM_OPCODES = 144; +static const uint16 kNumOpcodes = 144; Room::Room() {} @@ -86,82 +86,6 @@ int Room::getOptionOffset(int option) { } } -/* -void Room::loadMobs(Common::SeekableReadStream &stream) { - debug("loadMobs %d", stream.pos()); - static const uint8 MAX_MOBS = 64; - uint8 mobs[MAX_MOBS]; - stream.read(&mobs, sizeof(mobs)); - for (uint8 i = 0; i < sizeof(mobs); i++) { - debug("mob %d flag %d", i, mobs[i]); - } -} - -void Room::loadBackAnim(Common::SeekableReadStream &stream) { - debug("loadBackAnim %d", stream.pos()); - static const uint8 MAX_BACK_ANIMS = 64; - uint32 backAnim[MAX_BACK_ANIMS]; - debug("loadBackAnim sizeof %lu", sizeof(backAnim)); - stream.read(backAnim, sizeof(backAnim)); - for (uint8 i = 0; i < MAX_BACK_ANIMS; i++) { - debug("back anim offset %d", backAnim[i]); - } -} - -void Room::loadObj(Common::SeekableReadStream &stream) {} -void Room::loadNak(Common::SeekableReadStream &stream) {} -void Room::loadItemUse(Common::SeekableReadStream &stream) {} -void Room::loadItemGive(Common::SeekableReadStream &stream) {} -void Room::loadWalkTo(Common::SeekableReadStream &stream) {} -void Room::loadExamine(Common::SeekableReadStream &stream) {} -void Room::loadPickup(Common::SeekableReadStream &stream) {} -void Room::loadUse(Common::SeekableReadStream &stream) {} -void Room::loadPushOpen(Common::SeekableReadStream &stream) {} -void Room::loadPullClose(Common::SeekableReadStream &stream) {} -void Room::loadTalk(Common::SeekableReadStream &stream) {} -void Room::loadGive(Common::SeekableReadStream &stream) {} -*/ -/* -void Room::nextLoadStep(Common::SeekableReadStream &stream, LoadingStep step) { - uint32 offset = stream.readUint32LE(); - uint32 pos = stream.pos(); - stream.seek(offset); - - debug("nextLoadStep offset %d, pos %d", offset, pos); - - (this->*step)(stream); - - stream.seek(pos); -} -*/ -/* -bool Room::loadFromStream(Common::SeekableReadStream &stream) { - - uint32 pos = stream.pos(); - - nextLoadStep(stream, &Room::loadMobs); - nextLoadStep(stream, &Room::loadBackAnim); - nextLoadStep(stream, &Room::loadObj); - nextLoadStep(stream, &Room::loadNak); - nextLoadStep(stream, &Room::loadItemUse); - nextLoadStep(stream, &Room::loadItemGive); - nextLoadStep(stream, &Room::loadWalkTo); - nextLoadStep(stream, &Room::loadExamine); - nextLoadStep(stream, &Room::loadPickup); - nextLoadStep(stream, &Room::loadUse); - nextLoadStep(stream, &Room::loadPushOpen); - nextLoadStep(stream, &Room::loadPullClose); - nextLoadStep(stream, &Room::loadTalk); - nextLoadStep(stream, &Room::loadGive); - - // skip some data for now - static const uint8 ROOM_ENTRY_SIZE = 64; - stream.seek(pos + ROOM_ENTRY_SIZE); - - return true; -} -*/ - Script::Script(PrinceEngine *vm) : _vm(vm), _data(nullptr), _dataSize(0) { } @@ -472,8 +396,7 @@ Interpreter::Interpreter(PrinceEngine *vm, Script *script, InterpreterFlags *fla void Interpreter::debugInterpreter(const char *s, ...) { char buf[STRINGBUFLEN]; - va_list va; - + va_list va; va_start(va, s); vsnprintf(buf, STRINGBUFLEN, s, va); va_end(va); @@ -507,7 +430,7 @@ uint32 Interpreter::step(uint32 opcodePC) { // Get the current opcode _lastOpcode = readScript(); - if (_lastOpcode > NUM_OPCODES) + if (_lastOpcode > kNumOpcodes) error( "Trying to execute unknown opcode @0x%04X: %02d", _currentInstruction, @@ -766,7 +689,7 @@ void Interpreter::O__WAIT() { debugInterpreter("O__WAIT pause %d", pause); - if (_waitFlag == 0) { + if (!_waitFlag) { // set new wait flag value and continue _waitFlag = pause; _opcodeNF = 1; @@ -774,7 +697,7 @@ void Interpreter::O__WAIT() { return; } - --_waitFlag; + _waitFlag--; if (_waitFlag > 0) { _opcodeNF = 1; @@ -1199,13 +1122,21 @@ void Interpreter::O_TALKHERO() { _vm->talkHero(hero); } -//TODO void Interpreter::O_WAITTEXT() { uint16 slot = readScriptFlagValue(); Text &text = _vm->_textSlots[slot]; - if (text._time) { - _opcodeNF = 1; - _currentInstruction -= 4; + if (text._time && text._str) { + if (_flags->getFlagValue(Flags::ESCAPED)) { + text._time = 1; + if (slot == 0) { + _vm->_mainHero->_talkTime = 1; + } else if (slot == 1) { + _vm->_secondHero->_talkTime = 1; + } + } else { + _opcodeNF = 1; + _currentInstruction -= 4; + } } } @@ -1217,7 +1148,17 @@ void Interpreter::O_SETHEROANIM() { void Interpreter::O_WAITHEROANIM() { uint16 hero = readScriptFlagValue(); - + if (hero == 0) { + if (_vm->_mainHero->_state == _vm->_mainHero->SPEC) { + _currentInstruction -= 4; + _opcodeNF = 1; + } + } else if (hero == 1) { + if (_vm->_secondHero->_state == _vm->_secondHero->SPEC) { + _currentInstruction -= 4; + _opcodeNF = 1; + } + } debugInterpreter("O_WAITHEROANIM hero %d", hero); } @@ -1834,7 +1775,7 @@ void Interpreter::O_BREAK_POINT() { debugInterpreter("O_BREAK_POINT"); } -Interpreter::OpcodeFunc Interpreter::_opcodes[NUM_OPCODES] = { +Interpreter::OpcodeFunc Interpreter::_opcodes[kNumOpcodes] = { &Interpreter::O_WAITFOREVER, &Interpreter::O_BLACKPALETTE, &Interpreter::O_SETUPPALETTE, From 59e8dc2fd3f1847d724469bcaa680db750d21736 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 8 Jul 2014 16:38:09 +0200 Subject: [PATCH 237/374] PRINCE: O_SETHERO, O_GETHERODATA, O_GETHEROX, O_GETHEROY, O_GETHEROD, O_HEROCOLOR, O_TALKHEROSTOP, O_ENABLENAK, O_DISABLENAK, O_GETMOBNAME --- engines/prince/hero.cpp | 14 +++++- engines/prince/hero.h | 10 +++- engines/prince/prince.cpp | 10 ++-- engines/prince/prince.h | 2 +- engines/prince/script.cpp | 99 ++++++++++++++++++++++++++++----------- 5 files changed, 101 insertions(+), 34 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 44bd07f12aff..e91d6a971fef 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -37,7 +37,7 @@ Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph) , _lastDirection(DOWN), _destDirection(DOWN), _talkTime(0), _boredomTime(0), _phase(0) , _specAnim(0), _drawX(0), _drawY(0), _drawZ(0), _zoomFactor(0), _scaleValue(0) , _shadZoomFactor(0), _shadScaleValue(0), _shadLineLen(0), _shadDrawX(0), _shadDrawY(0) - , _frameXSize(0), _frameYSize(0), _scaledFrameXSize(0), _scaledFrameYSize(0) + , _frameXSize(0), _frameYSize(0), _scaledFrameXSize(0), _scaledFrameYSize(0), _color(0) { _zoomBitmap = (byte *)malloc(kZoomBitmapLen); _shadowBitmap = (byte *)malloc(2 * kShadowBitmapSize); @@ -122,6 +122,18 @@ void Hero::getState() { } } +uint16 Hero::getData(AttrId dataId) { + switch (dataId) { + case kHeroLastDir: + return _lastDirection; + case kHeroAnimSet: + return _moveSetType; + default: + assert(false); + return 0; + } +} + int Hero::getScaledValue(int size) { int newSize = 0; int16 initScaleValue = _scaleValue; diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 3db21816532f..ae33419176ed 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -99,6 +99,14 @@ class Hero { kMove_BORED2 }; + // Used instead of offset in getData + enum AttrId { + kHeroLastDir = 26, + kHeroAnimSet = 120 + }; + + uint16 getData(AttrId dataId); + Hero(PrinceEngine *vm, GraphicsMan *graph); ~Hero(); bool loadAnimSet(uint32 heroAnimNumber); @@ -177,7 +185,7 @@ class Hero { Common::Array _inventory; // Inventory array of items Common::Array _inventory2; // Inventory2 array of items // Font subtitiles font - // Color subtitiles color + int _color; // Color Subtitles color // AnimSet number of animation set Common::Array _moveSet; // MoveAnims MoveSet // TurnAnim ?? diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 03e2f7479c14..32baf75a9506 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1146,7 +1146,11 @@ void PrinceEngine::clsMasks() { void PrinceEngine::insertMasks(Graphics::Surface *originalRoomSurface) { for (uint i = 0; i < _maskList.size(); i++) { if (_maskList[i]._state) { - showMask(i, originalRoomSurface); + if (_maskList[i]._data != nullptr) { + showMask(i, originalRoomSurface); + } else { + error("insertMasks() - Wrong mask data- nr %d", i); + } } } } @@ -2584,13 +2588,13 @@ void PrinceEngine::talkHero(int slot) { int time = lines * 30; if (slot == 0) { - text._color = 220; // test this + text._color = 220; // TODO - test this _mainHero->_state = Hero::TALK; _mainHero->_talkTime = time; text._x = _mainHero->_middleX - _picWindowX; text._y = _mainHero->_middleY - _mainHero->_scaledFrameYSize; } else { - text._color = 220; // test this ! + text._color = _flags->getFlagValue(Flags::KOLOR); // TODO - test this _secondHero->_state = Hero::TALK; _secondHero->_talkTime = time; text._x = _secondHero->_middleX - _picWindowX; diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 18a087729971..c9f926863119 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -308,6 +308,7 @@ class PrinceEngine : public Engine { Common::Array _backAnimList; Common::Array _normAnimList; Common::Array _mobList; + Common::Array _maskList; Common::Array _objList; int *_objSlot; @@ -478,7 +479,6 @@ class PrinceEngine : public Engine { Audio::SoundHandle _soundHandle[MAX_SAMPLES]; Common::Array _pscrList; - Common::Array _maskList; Common::Array _drawNodeList; Common::Array _allInvList; Common::Array _invMobList; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 2ffa76db44c9..36cd991bfdad 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -343,23 +343,25 @@ bool Script::loadAllMasks(Common::Array &maskList, int offset) { const Common::String msStreamName = Common::String::format("MS%02d", tempMask._number); Common::SeekableReadStream *msStream = SearchMan.createReadStreamForMember(msStreamName); if (!msStream) { - //error("Can't load %s", msStreamName.c_str()); + tempMask._width = 0; + tempMask._height = 0; + tempMask._data = nullptr; + debug("Can't load %s", msStreamName.c_str()); delete msStream; - return false; - } - - uint32 dataSize = msStream->size(); - if (dataSize != -1) { - tempMask._data = (byte *)malloc(dataSize); - if (msStream->read(tempMask._data, dataSize) != dataSize) { - free(tempMask._data); + } else { + uint32 dataSize = msStream->size(); + if (dataSize != -1) { + tempMask._data = (byte *)malloc(dataSize); + if (msStream->read(tempMask._data, dataSize) != dataSize) { + free(tempMask._data); + delete msStream; + return false; + } delete msStream; - return false; } - delete msStream; + tempMask._width = tempMask.getWidth(); + tempMask._height = tempMask.getHeight(); } - tempMask._width = tempMask.getWidth(); - tempMask._height = tempMask.getHeight(); maskList.push_back(tempMask); offset += 16; // size of Mask (Nak) struct @@ -960,12 +962,22 @@ void Interpreter::O_SETHERO() { int16 x = readScriptFlagValue(); int16 y = readScriptFlagValue(); uint16 dir = readScriptFlagValue(); + if (hero == 0) { + _vm->_mainHero->setPos(x, y); + _vm->_mainHero->_lastDirection = dir; + _vm->_mainHero->_state = _vm->_mainHero->STAY; + _vm->_mainHero->_moveSetType = _vm->_mainHero->_lastDirection - 1; // for countDrawPosition + _vm->_mainHero->countDrawPosition(); //setting drawX, drawY + _vm->_mainHero->_visible = 1; + } else if (hero == 1) { + _vm->_secondHero->setPos(x, y); + _vm->_secondHero->_lastDirection = dir; + _vm->_secondHero->_state = _vm->_mainHero->STAY; + _vm->_secondHero->_moveSetType = _vm->_mainHero->_lastDirection - 1; // for countDrawPosition + _vm->_secondHero->countDrawPosition(); //setting drawX, drawY + _vm->_secondHero->_visible = 1; + } debugInterpreter("O_SETHERO hero %d, x %d, y %d, dir %d", hero, x, y, dir); - _vm->_mainHero->setPos(x, y); - _vm->_mainHero->_lastDirection = dir; - _vm->_mainHero->_state = _vm->_mainHero->STAY; - _vm->_mainHero->_moveSetType = _vm->_mainHero->_lastDirection - 1; // for countDrawPosition - _vm->_mainHero->countDrawPosition(); //setting drawX, drawY } void Interpreter::O_HEROOFF() { @@ -1163,10 +1175,15 @@ void Interpreter::O_WAITHEROANIM() { } void Interpreter::O_GETHERODATA() { - uint16 flag = readScript(); + Flags::Id flagId = readScriptFlagId(); uint16 hero = readScriptFlagValue(); uint16 heroOffset = readScriptFlagValue(); - debugInterpreter("O_GETHERODATA flag %d, hero %d, heroOffset %d", flag, hero, heroOffset); + if (hero == 0) { + _flags->setFlagValue(flagId, _vm->_mainHero->getData((Hero::AttrId)heroOffset)); + } else if (hero == 1) { + _flags->setFlagValue(flagId, _vm->_secondHero->getData((Hero::AttrId)heroOffset)); + } + debugInterpreter("O_GETHERODATA flag %04x - (%s), hero %d, heroOffset %d", flagId, Flags::getFlagName(flagId), hero, heroOffset); } void Interpreter::O_GETMOUSEBUTTON() { @@ -1516,21 +1533,33 @@ void Interpreter::O_SETPATH() { void Interpreter::O_GETHEROX() { uint16 heroId = readScriptFlagValue(); Flags::Id flagId = readScriptFlagId(); - + if (heroId == 0) { + _flags->setFlagValue(flagId, _vm->_mainHero->_middleX); + } else if (heroId == 1) { + _flags->setFlagValue(flagId, _vm->_secondHero->_middleX); + } debugInterpreter("O_GETHEROX heroId %d, flagId %d", heroId, flagId); } void Interpreter::O_GETHEROY() { - uint16 heroId = readScript(); + uint16 heroId = readScriptFlagValue(); Flags::Id flagId = readScriptFlagId(); - + if (heroId == 0) { + _flags->setFlagValue(flagId, _vm->_mainHero->_middleY); + } else if (heroId == 1) { + _flags->setFlagValue(flagId, _vm->_secondHero->_middleY); + } debugInterpreter("O_GETHEROY heroId %d, flagId %d", heroId, flagId); } void Interpreter::O_GETHEROD() { uint16 heroId = readScriptFlagValue(); Flags::Id flagId = readScriptFlagId(); - + if (heroId == 0) { + _flags->setFlagValue(flagId, _vm->_mainHero->_lastDirection); + } else if (heroId == 1) { + _flags->setFlagValue(flagId, _vm->_secondHero->_lastDirection); + } debugInterpreter("O_GETHEROD heroId %d, flagId %d", heroId, flagId); } @@ -1650,13 +1679,24 @@ void Interpreter::O_FREEFLC() { void Interpreter::O_TALKHEROSTOP() { uint16 heroId = readScriptFlagValue(); + if (heroId == 0) { + _vm->_mainHero->_state = _vm->_mainHero->STAY; + } else if (heroId == 1) { + _vm->_secondHero->_state = _vm->_secondHero->STAY; + } debugInterpreter("O_TALKHEROSTOP %d", heroId); } +// TODO - check this void Interpreter::O_HEROCOLOR() { uint16 heroId = readScriptFlagValue(); - uint16 kolorr = readScriptFlagValue(); - debugInterpreter("O_HEROCOLOR heroId %d, kolorr %d", heroId, kolorr); + uint16 color = readScriptFlagValue(); + if (heroId == 0) { + _vm->_mainHero->_color = color; + } else if (heroId == 1) { + _vm->_secondHero->_color = color; + } + debugInterpreter("O_HEROCOLOR heroId %d, color %d", heroId, color); } void Interpreter::O_GRABMAPA() { @@ -1665,17 +1705,20 @@ void Interpreter::O_GRABMAPA() { void Interpreter::O_ENABLENAK() { uint16 nakId = readScriptFlagValue(); + _vm->_maskList[nakId]._flags = 0; debugInterpreter("O_ENABLENAK nakId %d", nakId); } void Interpreter::O_DISABLENAK() { uint16 nakId = readScriptFlagValue(); + _vm->_maskList[nakId]._flags = 1; debugInterpreter("O_DISABLENAK nakId %d", nakId); } void Interpreter::O_GETMOBNAME() { - uint16 war = readScriptFlagValue(); - debugInterpreter("O_GETMOBNAME war %d", war); + uint16 modId = readScriptFlagValue(); + _string = (byte *)_vm->_mobList[modId]._name.c_str(); + debugInterpreter("O_GETMOBNAME modId %d", modId); } void Interpreter::O_SWAPINVENTORY() { From 1b1238d4b3796f487ecfd260cdb3f9607a0724b1 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 10 Jul 2014 02:22:18 +0200 Subject: [PATCH 238/374] PRINCE: Loading path data, fpGetPixelAddr(), fpGetPixel(), findPoint(), beginning of makePath() --- engines/prince/prince.cpp | 181 +++++++++++++++++++++++++++++++++++++- engines/prince/prince.h | 21 +++++ 2 files changed, 199 insertions(+), 3 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 32baf75a9506..f7c2f9e3f4d2 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -88,7 +88,9 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _optionsWidth(210), _optionsHeight(170), _invOptionsWidth(210), _invOptionsHeight(130), _optionsStep(20), _invOptionsStep(20), _optionsNumber(7), _invOptionsNumber(5), _optionsColor1(236), _optionsColor2(252), _dialogWidth(600), _dialogHeight(0), _dialogLineSpace(10), _dialogColor1(220), _dialogColor2(223), - _dialogFlag(false), _dialogLines(0), _dialogText(nullptr), _mouseFlag(1) { + _dialogFlag(false), _dialogLines(0), _dialogText(nullptr), _mouseFlag(1), + _roomPathBitmap(nullptr), _destX(0), _destY(0), _destX2(0), _destY2(0), _fpFlag(0), _fpX(0), _fpY(0), + _fpX1(0), _fpY1(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -172,6 +174,8 @@ PrinceEngine::~PrinceEngine() { delete _mainHero; delete _secondHero; + + free(_roomPathBitmap); } GUI::Debugger *PrinceEngine::getDebugger() { @@ -291,6 +295,8 @@ void PrinceEngine::init() { _mainHero->loadAnimSet(1); _secondHero->loadAnimSet(3); + _roomPathBitmap = (byte *)malloc(kPathBitmapLen); + BackgroundAnim tempBackAnim; tempBackAnim._seq._currRelative = 0; for (int i = 0; i < kMaxBackAnims; i++) { @@ -397,8 +403,9 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _graph->setPalette(_roomBmp->getPalette()); } - loadZoom(_mainHero->_zoomBitmap, _mainHero->kZoomBitmapLen, "zoom"); - loadShadow(_mainHero->_shadowBitmap, _mainHero->kShadowBitmapSize, "shadow", "shadow2"); + loadZoom(_mainHero->_zoomBitmap, _mainHero->kZoomBitmapLen, "zoom"); // TODO - second hero + loadShadow(_mainHero->_shadowBitmap, _mainHero->kShadowBitmapSize, "shadow", "shadow2"); // TODO - second hero + loadPath("path"); for (uint32 i = 0; i < _pscrList.size(); i++) { delete _pscrList[i]; @@ -731,6 +738,20 @@ bool PrinceEngine::loadShadow(byte *shadowBitmap, uint32 dataSize, const char *r 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; @@ -2663,6 +2684,160 @@ void PrinceEngine::freeAllNormAnims() { _normAnimList.clear(); } +bool PrinceEngine::fpGetPixelAddr(int x, int y) { + _fpX = x; + _fpY = y; + return fpGetPixel(x, y); +} + +bool PrinceEngine::fpGetPixel(int x, int y) { + _fpX1 = x; + _fpY1 = y; + + int mask = 128 >> (x & 7); + byte value = _roomPathBitmap[x / 8 + y * 80]; + if (mask != value) { + return true; + } + return false; +} + +void PrinceEngine::findPoint(int x1, int y1, int x2, int y2) { + // other names? + _destX = x1; + _destY = y1; + _destX2 = x2; + _destY2 = y2; + _fpFlag = 0; + + if (fpGetPixelAddr(x1, y1)) { + _fpFlag = 1; + if (fpGetPixelAddr(_destX2, _destY2)) { + //bye + //eax = _destX; + //ebx = _destY; + //ecx = _destX2; + //edx = _destY2; + return; + } + } + //got_wrong_point + + int fpL, fpU, fpR, fpD; // global? + + fpL = _fpX; + fpU = _fpY; + fpR = _fpX; + fpD = _fpY; + + //loop: + while (1) { + if (fpD != kMaxPicHeight) { + if (fpGetPixel(_fpX, fpD)) { + //gotcha + if (_fpFlag) { + _destX2 = _fpX1; + _destY2 = _fpY1; + } else { + _destX = _fpX1; + _destY = _fpY1; + } + break; + } + fpD++; + } + //no down + if (fpU != 0) { + if (fpGetPixel(_fpX, fpU)) { + //gotcha + if (_fpFlag) { + _destX2 = _fpX1; + _destY2 = _fpY1; + } else { + _destX = _fpX1; + _destY = _fpY1; + } + break; + } + fpU--; + } + //no_up + if (fpL != 0) { + if (fpGetPixel(fpL, _fpY)) { + //gotcha + if (_fpFlag) { + _destX2 = _fpX1; + _destY2 = _fpY1; + } else { + _destX = _fpX1; + _destY = _fpY1; + } + break; + } + fpL--; + } + //no_left + if (fpR != _sceneWidth) { + if (fpGetPixel(fpL, _fpY)) { + //gotcha + if (_fpFlag) { + _destX2 = _fpX1; + _destY2 = _fpY1; + } else { + _destX = _fpX1; + _destY = _fpY1; + } + break; + } + fpR++; + } + //no_right + if (fpD == kMaxPicHeight) { + if (fpL == 0) { + if (fpU == 0) { + if (fpR == _sceneWidth) { + break; + } + } + } + } + //bye + //eax = _destX; + //ebx = _destY; + //ecx = _destX2; + //edx = _destY2; + return; + } +} + +void PrinceEngine::makePath(int destX, int destY) { + + int realDestX = destX; + int realDestY = destY; + _flags->setFlagValue(Flags::MOVEDESTX, destX); + _flags->setFlagValue(Flags::MOVEDESTY, destY); + + int ebp = -2; + int currX = _mainHero->_middleX; // second hero + int currY = _mainHero->_middleY; + + int eax = currX / 2; + int ebx = currY / 2; + int ecx = destX / 2; + int edx = destY / 2; + + if ((currX / 2 != destX / 2) && (currY / 2 != destY / 2)) { + //not_just_turn + findPoint(currX / 2, currY / 2, destX / 2, destY / 2); + } else { + //byemove + //freeOldMove(); + _mainHero->_state = _mainHero->TURN; + // eax = -1 + return; + } +} + void PrinceEngine::mainLoop() { changeCursor(0); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index c9f926863119..c664d44896b7 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -431,6 +431,27 @@ class PrinceEngine : public Engine { void initZoomIn(int slot); void initZoomOut(int slot); + // Pathfinding + static const int16 kPathGridStep = 2; + static const int32 kPathBitmapLen = (kMaxPicHeight / kPathGridStep * kMaxPicWidth / kPathGridStep) / 8; + byte *_roomPathBitmap; // PL - Sala + + int _destX; + int _destY; + int _destX2; + int _destY2; + int _fpFlag; + int _fpX; + int _fpY; + int _fpX1; + int _fpY1; + + bool loadPath(const char *resourceName); + void makePath(int destX, int destY); + void findPoint(int x1, int y1, int x2, int y2); + bool fpGetPixelAddr(int x, int y); + bool fpGetPixel(int x, int y); + int testAnimNr; int testAnimFrame; From b711899a63e7e98bce9dc9509e9cc4a85486cb41 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 10 Jul 2014 16:41:13 +0200 Subject: [PATCH 239/374] PRINCE: Pathfinding progress --- engines/prince/common.h | 24 +++---- engines/prince/prince.cpp | 134 +++++++++++++++++++++++++++++++++----- engines/prince/prince.h | 12 ++++ 3 files changed, 140 insertions(+), 30 deletions(-) diff --git a/engines/prince/common.h b/engines/prince/common.h index 6dc1bad6a802..808b6900ecdb 100644 --- a/engines/prince/common.h +++ b/engines/prince/common.h @@ -26,18 +26,18 @@ namespace Prince { enum Direction { - LD = 0, - L = 1, - LG = 2, - PD = 3, - P = 4, - PG = 5, - GL = 6, - G = 7, - GP = 8, - DL = 9, - D = 10, - DP = 11 + kDirLD = 0, + kDirL = 1, + kDirLU = 2, + kDirRD = 3, + kDirR = 4, + kDirRU = 5, + kDirUL = 6, + kDirU = 7, + kDirUR = 8, + kDirDL = 9, + kDirD = 10, + kDirDR = 11 }; } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index f7c2f9e3f4d2..1fe671187a96 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -89,8 +89,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _invOptionsStep(20), _optionsNumber(7), _invOptionsNumber(5), _optionsColor1(236), _optionsColor2(252), _dialogWidth(600), _dialogHeight(0), _dialogLineSpace(10), _dialogColor1(220), _dialogColor2(223), _dialogFlag(false), _dialogLines(0), _dialogText(nullptr), _mouseFlag(1), - _roomPathBitmap(nullptr), _destX(0), _destY(0), _destX2(0), _destY2(0), _fpFlag(0), _fpX(0), _fpY(0), - _fpX1(0), _fpY1(0) { + _roomPathBitmap(nullptr), _roomPathBitmapTemp(nullptr), _destX(0), _destY(0), _destX2(0), _destY2(0), + _fpFlag(0), _fpX(0), _fpY(0), _fpX1(0), _fpY1(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -176,6 +176,7 @@ PrinceEngine::~PrinceEngine() { delete _secondHero; free(_roomPathBitmap); + free(_roomPathBitmapTemp); } GUI::Debugger *PrinceEngine::getDebugger() { @@ -296,6 +297,7 @@ void PrinceEngine::init() { _secondHero->loadAnimSet(3); _roomPathBitmap = (byte *)malloc(kPathBitmapLen); + _roomPathBitmapTemp = (byte *)malloc(kPathBitmapLen); BackgroundAnim tempBackAnim; tempBackAnim._seq._currRelative = 0; @@ -2714,10 +2716,10 @@ void PrinceEngine::findPoint(int x1, int y1, int x2, int y2) { _fpFlag = 1; if (fpGetPixelAddr(_destX2, _destY2)) { //bye - //eax = _destX; - //ebx = _destY; - //ecx = _destX2; - //edx = _destY2; + _fpResult.x1 = _destX; + _fpResult.y1 = _destY; + _fpResult.x2 = _destX2; + _fpResult.y2 = _destY2; return; } } @@ -2802,18 +2804,91 @@ void PrinceEngine::findPoint(int x1, int y1, int x2, int y2) { } } //bye - //eax = _destX; - //ebx = _destY; - //ecx = _destX2; - //edx = _destY2; + _fpResult.x1 = _destX; + _fpResult.y1 = _destY; + _fpResult.x2 = _destX2; + _fpResult.y2 = _destY2; return; } } +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; + } + } +} + +int PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { + for (int i = 0; i < kPathBitmapLen; i++) { + _roomPathBitmapTemp[i] = 0; + } + //pop ecx eax + //mov edi,o CoordsBuf + //mov d Coords,edi + if (x1 != x2 || y1 != y2) { + //not_same + _destX = x1; + _destY = y1; + _destX2 = x2; + _destY2 = y2; + makeDirection(x1, y1, x2, y2); + return 0; + } else { + //error1: + return 1; + } +} + void PrinceEngine::makePath(int destX, int destY) { + int pathLen1 = 0; // global? + int pathLen2 = 0; // global? + int stX = 0; // global? + int stY = 0; // global? - int realDestX = destX; - int realDestY = destY; + int realDestX = destX; // global? + int realDestY = destY; // global? _flags->setFlagValue(Flags::MOVEDESTX, destX); _flags->setFlagValue(Flags::MOVEDESTY, destY); @@ -2821,14 +2896,37 @@ void PrinceEngine::makePath(int destX, int destY) { int currX = _mainHero->_middleX; // second hero int currY = _mainHero->_middleY; - int eax = currX / 2; - int ebx = currY / 2; - int ecx = destX / 2; - int edx = destY / 2; + int x1 = currX / 2; + int y1 = currY / 2; + int x2 = destX / 2; + int y2 = destY / 2; - if ((currX / 2 != destX / 2) && (currY / 2 != destY / 2)) { + if ((x1 != x2) && (y1 != y2)) { //not_just_turn - findPoint(currX / 2, currY / 2, destX / 2, destY / 2); + findPoint(x1, y1, x2, y2); + if (x2 != _fpResult.x1 || y2 != _fpResult.y1) { + // differs + if (!_flags->getFlagValue(Flags::EXACTMOVE)) { + realDestX = destX; + realDestY = destY; + _flags->setFlagValue(Flags::MOVEDESTX, destX); + _flags->setFlagValue(Flags::MOVEDESTY, destY); + } else { + //byemove2 + //add esp,8 + //byemovemove + //eax = -1 + return; + } + } + // not_differs + pathLen1 = 0; + pathLen2 = 0; + stX = x1; // stXY + stY = y1; // stXY + 2 + + tracePath(x1, y1, x2, y2); + } else { //byemove //freeOldMove(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index c664d44896b7..b9dc249cc324 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -435,6 +435,7 @@ class PrinceEngine : public Engine { static const int16 kPathGridStep = 2; static const int32 kPathBitmapLen = (kMaxPicHeight / kPathGridStep * kMaxPicWidth / kPathGridStep) / 8; byte *_roomPathBitmap; // PL - Sala + byte *_roomPathBitmapTemp; // PL -SSala int _destX; int _destY; @@ -445,12 +446,23 @@ class PrinceEngine : public Engine { int _fpY; int _fpX1; int _fpY1; + Direction _direction; + + struct fpResult { + int x1; + int y1; + int x2; + int y2; + } _fpResult; bool loadPath(const char *resourceName); void makePath(int destX, int destY); void findPoint(int x1, int y1, int x2, int y2); bool fpGetPixelAddr(int x, int y); bool fpGetPixel(int x, int y); + int tracePath(int x1, int y1, int x2, int y2); + Direction makeDirection(int x1, int y1, int x2, int y2); + void approxPath(); int testAnimNr; int testAnimFrame; From 0f58b3ac6a71db4556152b987a9d6be783975217 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 10 Jul 2014 22:27:39 +0200 Subject: [PATCH 240/374] PRINCE: Pathfinding - second update --- engines/prince/prince.cpp | 96 +++++++++++++++++++++++++++++++++++---- engines/prince/prince.h | 14 +++++- 2 files changed, 99 insertions(+), 11 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 1fe671187a96..6685a065e59e 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -90,7 +90,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _dialogWidth(600), _dialogHeight(0), _dialogLineSpace(10), _dialogColor1(220), _dialogColor2(223), _dialogFlag(false), _dialogLines(0), _dialogText(nullptr), _mouseFlag(1), _roomPathBitmap(nullptr), _roomPathBitmapTemp(nullptr), _destX(0), _destY(0), _destX2(0), _destY2(0), - _fpFlag(0), _fpX(0), _fpY(0), _fpX1(0), _fpY1(0) { + _fpFlag(0), _fpX(0), _fpY(0), _fpX1(0), _fpY1(0), _coordsBufEnd(8), _coordsBuf(nullptr), _coords(nullptr), + _traceLineLen(0), _traceLineFlag(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -177,6 +178,7 @@ PrinceEngine::~PrinceEngine() { free(_roomPathBitmap); free(_roomPathBitmapTemp); + free(_coordsBuf); } GUI::Debugger *PrinceEngine::getDebugger() { @@ -298,6 +300,8 @@ void PrinceEngine::init() { _roomPathBitmap = (byte *)malloc(kPathBitmapLen); _roomPathBitmapTemp = (byte *)malloc(kPathBitmapLen); + _coordsBuf = (byte *)malloc(kTracePts * 4); + _coords = _coordsBuf; BackgroundAnim tempBackAnim; tempBackAnim._seq._currRelative = 0; @@ -2686,22 +2690,24 @@ void PrinceEngine::freeAllNormAnims() { _normAnimList.clear(); } -bool PrinceEngine::fpGetPixelAddr(int x, int y) { +int PrinceEngine::fpGetPixelAddr(int x, int y) { _fpX = x; _fpY = y; return fpGetPixel(x, y); } -bool PrinceEngine::fpGetPixel(int x, int y) { +int PrinceEngine::fpGetPixel(int x, int y) { _fpX1 = x; _fpY1 = y; - int mask = 128 >> (x & 7); byte value = _roomPathBitmap[x / 8 + y * 80]; - if (mask != value) { - return true; - } - return false; + return (mask & value); +} + +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 x1, int y1, int x2, int y2) { @@ -2860,6 +2866,45 @@ Direction PrinceEngine::makeDirection(int x1, int y1, int x2, int y2) { } } +void PrinceEngine::specialPlot(int x, int y) { + if (*_coords < _coordsBufEnd) { + WRITE_UINT16(_coords, x); + _coords += 2; + WRITE_UINT16(_coords, y); + _coords += 2; + int mask = 128 >> (x & 7); + _roomPathBitmapTemp[x / 8 + y * 80] |= mask; // set point + } +} + +void PrinceEngine::specialPlotInside(int x, int y) { + if (*_coords < _coordsBufEnd) { + WRITE_UINT16(_coords, x); + _coords += 2; + WRITE_UINT16(_coords, y); + _coords += 2; + } +} + +void PrinceEngine::plotTraceLine(int x, int y, int color, void *data) { + PrinceEngine *traceLine = (PrinceEngine *)data; + if (!traceLine->_traceLineFlag) { + if (!traceLine->getPixelAddr(traceLine->_roomPathBitmapTemp, x, y)) { + if (traceLine->getPixelAddr(traceLine->_roomPathBitmap, x, y)) { + traceLine->specialPlotInside(x, y); + traceLine->_traceLineLen++; + traceLine->_traceLineFlag = 0; + } else { + //mov eax, OldX // last correct point + //mov ebx, OldY + traceLine->_traceLineFlag = -1; + } + } else { + traceLine->_traceLineFlag = 1; + } + } +} + int PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { for (int i = 0; i < kPathBitmapLen; i++) { _roomPathBitmapTemp[i] = 0; @@ -2873,7 +2918,36 @@ int PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { _destY = y1; _destX2 = x2; _destY2 = y2; - makeDirection(x1, y1, x2, y2); + Direction dir = makeDirection(x1, y1, x2, y2); + // eax = _destX; + // ebx = _destY; + // EAX, EBX - x,y + // ESI - adres w buforze SSala (czasowy) + // EBP - adres w buforze Sala (staly) + // DL - maska bitu + if(getPixelAddr(_roomPathBitmap, _destX, _destY)) { + if (getPixelAddr(_roomPathBitmap, _destX2, _destY2)) { + //mov eax,d DestX + //mov ebx,d DestY + //mov edi,o CoordsBuf + //mov d Coords,edi + specialPlot(_destX, _destY); + //trace_loop: + int btx = _destX; + int bty = _destY; + byte *bcad = _coords; + while (1) { + _traceLineLen = 0; + Graphics::drawLine(_destX, _destY, _destX2, _destY2, 0, &this->plotTraceLine, this); + } + } else { + //error2 + return 2; + } + } else { + //error2 + return 2; + } return 0; } else { //error1: @@ -2881,6 +2955,10 @@ int PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { } } +void PrinceEngine::approxPath() { + +} + void PrinceEngine::makePath(int destX, int destY) { int pathLen1 = 0; // global? int pathLen2 = 0; // global? diff --git a/engines/prince/prince.h b/engines/prince/prince.h index b9dc249cc324..81c2bf694978 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -434,6 +434,7 @@ class PrinceEngine : public Engine { // Pathfinding static const int16 kPathGridStep = 2; static const int32 kPathBitmapLen = (kMaxPicHeight / kPathGridStep * kMaxPicWidth / kPathGridStep) / 8; + static const int32 kTracePts = 8000; byte *_roomPathBitmap; // PL - Sala byte *_roomPathBitmapTemp; // PL -SSala @@ -447,6 +448,11 @@ class PrinceEngine : public Engine { int _fpX1; int _fpY1; Direction _direction; + int _coordsBufEnd; + byte *_coordsBuf; // optimal path + byte *_coords; // last path point adress from coordsBuf + int _traceLineLen; + int _traceLineFlag; // return value of plotTraceLine struct fpResult { int x1; @@ -458,10 +464,14 @@ class PrinceEngine : public Engine { bool loadPath(const char *resourceName); void makePath(int destX, int destY); void findPoint(int x1, int y1, int x2, int y2); - bool fpGetPixelAddr(int x, int y); - bool fpGetPixel(int x, int y); + int fpGetPixelAddr(int x, int y); + int fpGetPixel(int x, int y); + int getPixelAddr(byte *pathBitmap, int x, int y); + static void plotTraceLine(int x, int y, int color, void *data); + void specialPlotInside(int x, int y); int tracePath(int x1, int y1, int x2, int y2); Direction makeDirection(int x1, int y1, int x2, int y2); + void specialPlot(int x, int y); void approxPath(); int testAnimNr; From eec9e4a84e5137930bcf8966fa7e65e2e27312f8 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 11 Jul 2014 18:14:08 +0200 Subject: [PATCH 241/374] PRINCE: Pathfinding - next update --- engines/prince/prince.cpp | 877 +++++++++++++++++++++++++++++++++++++- engines/prince/prince.h | 37 ++ 2 files changed, 911 insertions(+), 3 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 6685a065e59e..f688ae3aae55 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -91,7 +91,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _dialogFlag(false), _dialogLines(0), _dialogText(nullptr), _mouseFlag(1), _roomPathBitmap(nullptr), _roomPathBitmapTemp(nullptr), _destX(0), _destY(0), _destX2(0), _destY2(0), _fpFlag(0), _fpX(0), _fpY(0), _fpX1(0), _fpY1(0), _coordsBufEnd(8), _coordsBuf(nullptr), _coords(nullptr), - _traceLineLen(0), _traceLineFlag(0) { + _traceLineLen(0), _traceLineFlag(0), _rembBitmapTemp(nullptr), _rembBitmap(nullptr), _rembMask(0), _rembX(0), _rembY(0), + _checkBitmapTemp(nullptr), _checkBitmap(nullptr), _checkMask(0), _checkX(0), _checkY(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -2872,11 +2873,15 @@ void PrinceEngine::specialPlot(int x, int y) { _coords += 2; WRITE_UINT16(_coords, y); _coords += 2; - int mask = 128 >> (x & 7); - _roomPathBitmapTemp[x / 8 + y * 80] |= mask; // set point + specialPlot2(x, y); } } +void PrinceEngine::specialPlot2(int x, int y) { + int mask = 128 >> (x & 7); + _roomPathBitmapTemp[x / 8 + y * 80] |= mask; // set point +} + void PrinceEngine::specialPlotInside(int x, int y) { if (*_coords < _coordsBufEnd) { WRITE_UINT16(_coords, x); @@ -2905,6 +2910,778 @@ void PrinceEngine::plotTraceLine(int x, int y, int color, void *data) { } } +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() { + int value; + if ((*(_checkBitmap - kPBW) & _checkMask)) { + if ((*(_checkBitmap + kPBW) & _checkMask)) { + switch (_checkMask) { + case 128: + value = READ_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_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; + // add esp, 4 ?? + 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++; + cpe(); + return 0; + } 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--; + cpe(); + return 0; + } else { + return -1; + } +} + +int PrinceEngine::checkDownDir() { + if (_checkY != (kMaxPicHeight / 2 - 1)) { + if ((*(_checkBitmap + kPBW) & _checkMask)) { + if (!(*(_checkBitmapTemp + kPBW) & _checkMask)) { + _checkBitmap += kPBW; + _checkBitmapTemp += kPBW; + _checkY++; + cpe(); + return 0; + } 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--; + cpe(); + return 0; + } 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++; + cpe(); + return 0; + } 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--; + cpe(); + return 0; + } 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++; + cpe(); + return 0; + } 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--; + cpe(); + return 0; + } else { + return -1; + } +} + int PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { for (int i = 0; i < kPathBitmapLen; i++) { _roomPathBitmapTemp[i] = 0; @@ -2937,8 +3714,102 @@ int PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { int bty = _destY; byte *bcad = _coords; while (1) { + //TraceLine _traceLineLen = 0; Graphics::drawLine(_destX, _destY, _destX2, _destY2, 0, &this->plotTraceLine, this); + int x, y; + if (!_traceLineFlag) { + specialPlotInside(_destX2, _destY2); + return 0; + } else if (_traceLineFlag == -1 && _traceLineLen >= 2) { + //line_ok + //plotty + while (*bcad != *_coords) { + x = READ_UINT16(_coords); + y = READ_UINT16(_coords + 2); + _coords += 4; + specialPlot2(x, y); + } + //done_plotty + } else { + //bbb + _coords = bcad; + x = btx; + y = bty; + } + //same_point + Direction dir = makeDirection(x, y, _destX2, _destY2); + + _rembBitmapTemp = &_roomPathBitmapTemp[x / 8 + y * 80]; //esi + _rembBitmap = &_roomPathBitmap[x / 8 + y * 80]; // ebp + _rembMask = 128 >> (x & 7); // dl + _rembX = x; // eax + _rembY = y; // ebx + + _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; + } + + if (!result) { + byte *tempCoords = _coords; + tempCoords -= 4; + // TODO - adress comp?? + if (tempCoords > _coordsBuf) { + int tempX = READ_UINT16(tempCoords); + int tempY = READ_UINT16(tempCoords + 2); + if (_checkX == tempX && _checkY == tempY) { + _coords = tempCoords; + } + btx = READ_UINT16(_coords); // eax now! + bty = READ_UINT16(_coords + 2); // ebx now! + + } else { + //error4 + return 4; + } + } } } else { //error2 diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 81c2bf694978..ece1c4b2519a 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -435,6 +435,7 @@ class PrinceEngine : public Engine { static const int16 kPathGridStep = 2; static const int32 kPathBitmapLen = (kMaxPicHeight / kPathGridStep * kMaxPicWidth / kPathGridStep) / 8; static const int32 kTracePts = 8000; + static const int32 kPBW = kMaxPicWidth / 16; // PathBitmapWidth byte *_roomPathBitmap; // PL - Sala byte *_roomPathBitmapTemp; // PL -SSala @@ -454,6 +455,18 @@ class PrinceEngine : public Engine { int _traceLineLen; int _traceLineFlag; // return value of plotTraceLine + byte *_checkBitmapTemp; //esi + byte *_checkBitmap; // ebp + int _checkMask; // dl + int _checkX; // eax + int _checkY; // ebx + + byte *_rembBitmapTemp; // esi + byte *_rembBitmap; // ebp + int _rembMask; // dl + int _rembX; // eax + int _rembY; // ebx + struct fpResult { int x1; int y1; @@ -472,8 +485,32 @@ class PrinceEngine : public Engine { int tracePath(int x1, int y1, int x2, int y2); Direction makeDirection(int x1, int y1, int x2, int y2); void specialPlot(int x, int y); + void specialPlot2(int x, int y); void approxPath(); + int leftDownDir(); + int leftDir(); + int leftUpDir(); + int rightDownDir(); + int rightDir(); + int rightUpDir(); + int upLeftDir(); + int upDir(); + int upRightDir(); + int downLeftDir(); + int downDir(); + int downRightDir(); + + int cpe(); + int checkLeftDownDir(); + int checkLeftDir(); + int checkDownDir(); + int checkUpDir(); + int checkRightDir(); + int checkLeftUpDir(); + int checkRightDownDir(); + int checkRightUpDir(); + int testAnimNr; int testAnimFrame; From 7155db43049493fadc2f2e9779e5407ef3acc6eb Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 13 Jul 2014 18:27:13 +0200 Subject: [PATCH 242/374] PRINCE: Pathfinding - bug fixing, approxPath() --- engines/prince/graphics.cpp | 6 + engines/prince/graphics.h | 6 +- engines/prince/prince.cpp | 246 ++++++++++++++++++++++++++++-------- engines/prince/prince.h | 17 ++- 4 files changed, 221 insertions(+), 54 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index c993cc890567..7a3e310320d7 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -226,6 +226,12 @@ void GraphicsMan::drawAsShadowDrawNode(Graphics::Surface *screen, DrawNode *draw } } +void GraphicsMan::drawPixel(Graphics::Surface *screen, int32 posX, int32 posY) { + byte *dst = (byte *)screen->getBasePtr(posX, posY); + *dst = 0; + change(); +} + byte GraphicsMan::getBlendTableColor(byte pixelColor, byte backgroundPixelColor, byte *blendTable) { int32 redFirstOrg, greenFirstOrg, blueFirstOrg; int32 redFirstBack, greenFirstBack, blueFirstBack; diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index 76f6723d81d3..266177e229c2 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -45,9 +45,9 @@ class GraphicsMan { void makeShadowTable(int brightness, byte *shadowTable); void draw(Graphics::Surface *screen, const Graphics::Surface *s); - void drawTransparentSurface(Graphics::Surface *screen, int32 posX, int32 poxY, const Graphics::Surface *s, int transColor); + void drawTransparentSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, int transColor); void drawAsShadowSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, byte *shadowTable); - void drawTransparentWithBlendSurface(Graphics::Surface *screen, int32 posX, int32 poxY, const Graphics::Surface *s, int transColor); + void drawTransparentWithBlendSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, int transColor); static void drawTransparentDrawNode(Graphics::Surface *screen, DrawNode *drawNode); static void drawAsShadowDrawNode(Graphics::Surface *screen, DrawNode *drawNode); @@ -64,6 +64,8 @@ class GraphicsMan { static const byte kShadowColor = 191; + void drawPixel(Graphics::Surface *screen, int32 posX, int32 posY); + private: PrinceEngine *_vm; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index f688ae3aae55..68ef70159e03 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -90,9 +90,11 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _dialogWidth(600), _dialogHeight(0), _dialogLineSpace(10), _dialogColor1(220), _dialogColor2(223), _dialogFlag(false), _dialogLines(0), _dialogText(nullptr), _mouseFlag(1), _roomPathBitmap(nullptr), _roomPathBitmapTemp(nullptr), _destX(0), _destY(0), _destX2(0), _destY2(0), - _fpFlag(0), _fpX(0), _fpY(0), _fpX1(0), _fpY1(0), _coordsBufEnd(8), _coordsBuf(nullptr), _coords(nullptr), + _fpFlag(0), _fpX(0), _fpY(0), _fpX1(0), _fpY1(0), _coordsBufEnd(nullptr), _coordsBuf(nullptr), _coords(nullptr), _traceLineLen(0), _traceLineFlag(0), _rembBitmapTemp(nullptr), _rembBitmap(nullptr), _rembMask(0), _rembX(0), _rembY(0), - _checkBitmapTemp(nullptr), _checkBitmap(nullptr), _checkMask(0), _checkX(0), _checkY(0) { + _checkBitmapTemp(nullptr), _checkBitmap(nullptr), _checkMask(0), _checkX(0), _checkY(0), _traceLineFirstPointFlag(false), + _coordsBuf2(nullptr), _coords2(nullptr), _coordsBuf3(nullptr), _coords3(nullptr), + _tracePointFlag(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -303,6 +305,7 @@ void PrinceEngine::init() { _roomPathBitmapTemp = (byte *)malloc(kPathBitmapLen); _coordsBuf = (byte *)malloc(kTracePts * 4); _coords = _coordsBuf; + _coordsBufEnd = _coordsBuf + kTracePts * 4 - 4; // TODO - test this BackgroundAnim tempBackAnim; tempBackAnim._seq._currRelative = 0; @@ -1605,6 +1608,8 @@ void PrinceEngine::drawScreen() { runDrawNodes(); + testDrawPath(); + freeDrawNodes(); if (_mainHero->_visible) { @@ -2008,6 +2013,23 @@ void PrinceEngine::leftMouseButton() { _optionsMob = _selectedMob; if (_optionsMob == -1) { // @@walkto - TODO + if (_mainHero->_visible) { // second hero? + _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; // second hero? + } else { + Common::Point mousePos = _system->getEventManager()->getMousePos(); + destX = mousePos.x; + destY = mousePos.y; + _mainHero->_destDirection = 0; // second hero? + } + if (makePath(destX, destY)) { + // Shani movement + } + } return; } option = 0; @@ -2697,6 +2719,7 @@ int PrinceEngine::fpGetPixelAddr(int x, int y) { return fpGetPixel(x, y); } +// TODO -check int PrinceEngine::fpGetPixel(int x, int y) { _fpX1 = x; _fpY1 = y; @@ -2704,7 +2727,7 @@ int PrinceEngine::fpGetPixel(int x, int y) { byte value = _roomPathBitmap[x / 8 + y * 80]; return (mask & value); } - +// TODO -check int PrinceEngine::getPixelAddr(byte *pathBitmap, int x, int y) { int mask = 128 >> (x & 7); byte value = pathBitmap[x / 8 + y * 80]; @@ -2868,7 +2891,7 @@ Direction PrinceEngine::makeDirection(int x1, int y1, int x2, int y2) { } void PrinceEngine::specialPlot(int x, int y) { - if (*_coords < _coordsBufEnd) { + if (_coords < _coordsBufEnd) { WRITE_UINT16(_coords, x); _coords += 2; WRITE_UINT16(_coords, y); @@ -2882,8 +2905,9 @@ void PrinceEngine::specialPlot2(int x, int y) { _roomPathBitmapTemp[x / 8 + y * 80] |= mask; // set point } +//TODO - coordsBufENd void PrinceEngine::specialPlotInside(int x, int y) { - if (*_coords < _coordsBufEnd) { + if (_coords < _coordsBufEnd) { WRITE_UINT16(_coords, x); _coords += 2; WRITE_UINT16(_coords, y); @@ -2894,18 +2918,23 @@ void PrinceEngine::specialPlotInside(int x, int y) { void PrinceEngine::plotTraceLine(int x, int y, int color, void *data) { PrinceEngine *traceLine = (PrinceEngine *)data; if (!traceLine->_traceLineFlag) { - if (!traceLine->getPixelAddr(traceLine->_roomPathBitmapTemp, x, y)) { - if (traceLine->getPixelAddr(traceLine->_roomPathBitmap, x, y)) { - traceLine->specialPlotInside(x, y); - traceLine->_traceLineLen++; - traceLine->_traceLineFlag = 0; + if (!traceLine->_traceLineFirstPointFlag) { + if (!traceLine->getPixelAddr(traceLine->_roomPathBitmapTemp, x, y)) { + if (traceLine->getPixelAddr(traceLine->_roomPathBitmap, x, y)) { + traceLine->specialPlotInside(x, y); + traceLine->_traceLineLen++; + traceLine->_traceLineFlag = 0; + } else { + //mov eax, OldX // last correct point + //mov ebx, OldY + traceLine->_traceLineFlag = -1; + } } else { - //mov eax, OldX // last correct point - //mov ebx, OldY - traceLine->_traceLineFlag = -1; + traceLine->_traceLineFlag = 1; } } else { - traceLine->_traceLineFlag = 1; + traceLine->_traceLineFirstPointFlag = false; + traceLine->_traceLineFlag = 0; } } } @@ -3424,7 +3453,7 @@ int PrinceEngine::checkLeftDownDir() { if (_checkX && _checkY != (kMaxPicHeight / 2 - 1)) { int tempMask = _checkMask; if (tempMask != 128) { - tempMask << 1; + tempMask <<= 1; if ((*(_checkBitmap + kPBW) & tempMask)) { if (!(*(_checkBitmapTemp + kPBW) & tempMask)) { _checkBitmap += kPBW; @@ -3462,7 +3491,7 @@ int PrinceEngine::checkLeftDir() { if (_checkX) { int tempMask = _checkMask; if (tempMask != 128) { - tempMask << 1; + tempMask <<= 1; if ((*(_checkBitmap) & tempMask)) { if (!(*(_checkBitmapTemp) & tempMask)) { _checkMask = tempMask; @@ -3537,7 +3566,7 @@ int PrinceEngine::checkRightDir() { if (_checkX != (kMaxPicWidth / 2 - 1)) { int tempMask = _checkMask; if (tempMask != 1) { - tempMask >> 1; + tempMask >>= 1; if ((*(_checkBitmap) & tempMask)) { if (!(*(_checkBitmapTemp) & tempMask)) { _checkMask = tempMask; @@ -3572,7 +3601,7 @@ int PrinceEngine::checkLeftUpDir() { if (_checkX && _checkY) { int tempMask = _checkMask; if (tempMask != 128) { - tempMask << 1; + tempMask <<= 1; if ((*(_checkBitmap - kPBW) & tempMask)) { if (!(*(_checkBitmapTemp - kPBW) & tempMask)) { _checkBitmap -= kPBW; @@ -3610,7 +3639,7 @@ int PrinceEngine::checkRightDownDir() { if (_checkX != (kMaxPicWidth / 2 - 1) && _checkY != (kMaxPicHeight / 2 - 1)) { int tempMask = _checkMask; if (tempMask != 1) { - tempMask >> 1; + tempMask >>= 1; if ((*(_checkBitmap + kPBW) & tempMask)) { if (!(*(_checkBitmapTemp + kPBW) & tempMask)) { _checkBitmap += kPBW; @@ -3648,7 +3677,7 @@ int PrinceEngine::checkRightUpDir() { if (_checkX != (kMaxPicWidth / 2 - 1) && _checkY) { int tempMask = _checkMask; if (tempMask != 1) { - tempMask >> 1; + tempMask >>= 1; if ((*(_checkBitmap - kPBW) & tempMask)) { if (!(*(_checkBitmapTemp - kPBW) & tempMask)) { _checkBitmap -= kPBW; @@ -3696,38 +3725,41 @@ int PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { _destX2 = x2; _destY2 = y2; Direction dir = makeDirection(x1, y1, x2, y2); - // eax = _destX; - // ebx = _destY; - // EAX, EBX - x,y - // ESI - adres w buforze SSala (czasowy) - // EBP - adres w buforze Sala (staly) - // DL - maska bitu - if(getPixelAddr(_roomPathBitmap, _destX, _destY)) { + + if (getPixelAddr(_roomPathBitmap, _destX, _destY)) { if (getPixelAddr(_roomPathBitmap, _destX2, _destY2)) { - //mov eax,d DestX - //mov ebx,d DestY - //mov edi,o CoordsBuf - //mov d Coords,edi + _coords = _coordsBuf; + specialPlot(_destX, _destY); + //trace_loop: - int btx = _destX; - int bty = _destY; - byte *bcad = _coords; + int x = _destX; + int y = _destY; + byte *bcad; + int btx, bty; + while (1) { + btx = x; + bty = y; + bcad = _coords; + //TraceLine _traceLineLen = 0; - Graphics::drawLine(_destX, _destY, _destX2, _destY2, 0, &this->plotTraceLine, this); - int x, y; + _traceLineFlag = 0; + _traceLineFirstPointFlag = true; + Graphics::drawLine(x, y, _destX2, _destY2, 0, &this->plotTraceLine, this); + if (!_traceLineFlag) { specialPlotInside(_destX2, _destY2); return 0; } else if (_traceLineFlag == -1 && _traceLineLen >= 2) { //line_ok //plotty - while (*bcad != *_coords) { - x = READ_UINT16(_coords); - y = READ_UINT16(_coords + 2); - _coords += 4; + byte *tempCorrds = bcad; + while (tempCorrds != _coords) { + x = READ_UINT16(tempCorrds); + y = READ_UINT16(tempCorrds + 2); + tempCorrds += 4; specialPlot2(x, y); } //done_plotty @@ -3738,7 +3770,7 @@ int PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { y = bty; } //same_point - Direction dir = makeDirection(x, y, _destX2, _destY2); + dir = makeDirection(x, y, _destX2, _destY2); _rembBitmapTemp = &_roomPathBitmapTemp[x / 8 + y * 80]; //esi _rembBitmap = &_roomPathBitmap[x / 8 + y * 80]; // ebp @@ -3790,9 +3822,13 @@ int PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { case kDirDR: result = downRightDir(); break; + default: + result = -1; + error("tracePath() - Wrong direction %d", dir); + break; } - if (!result) { + if (result) { byte *tempCoords = _coords; tempCoords -= 4; // TODO - adress comp?? @@ -3802,13 +3838,16 @@ int PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { if (_checkX == tempX && _checkY == tempY) { _coords = tempCoords; } - btx = READ_UINT16(_coords); // eax now! - bty = READ_UINT16(_coords + 2); // ebx now! + x = READ_UINT16(_coords); // eax now! + y = READ_UINT16(_coords + 2); // ebx now! } else { //error4 return 4; } + } else { + x = _checkX; + y = _checkY; } } } else { @@ -3826,11 +3865,73 @@ int PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { } } -void PrinceEngine::approxPath() { +void PrinceEngine::specialPlotInside2(int x, int y) { + WRITE_UINT16(_coords2, x); + _coords2 += 2; + WRITE_UINT16(_coords2, y); + _coords2 += 2; +} + +void PrinceEngine::plotTracePoint(int x, int y, int color, void *data) { + PrinceEngine *tracePoint = (PrinceEngine *)data; + if (!tracePoint->_tracePointFlag) { + if (tracePoint->getPixelAddr(tracePoint->_roomPathBitmap, x, y)) { + tracePoint->specialPlotInside2(x, y); + tracePoint->_tracePointFlag = 0; + } else { + tracePoint->_tracePointFlag = -1; + } + } +} +void PrinceEngine::approxPath() { + byte *oldCoords; // like in TracePoint + _coords2 = _coordsBuf2; + byte *tempCoordsBuf = _coordsBuf; // first point on path - esi + byte *tempCoords = _coords; // edi + int x1, y1, x2, y2; + if (tempCoordsBuf != tempCoords) { + tempCoords -= 4; // last point on path + // loop + while (1) { + x1 = READ_UINT16(tempCoords); + y1 = READ_UINT16(tempCoords + 2); + if (tempCoordsBuf != tempCoords) { + x2 = READ_UINT16(tempCoordsBuf); + y2 = READ_UINT16(tempCoordsBuf + 2); + tempCoordsBuf += 4; + //TracePoint + oldCoords = _coords2; + if (_coords2 == _coordsBuf2) { + //no_compare + WRITE_UINT16(_coords2, x1); + WRITE_UINT16(_coords2 + 2, y1); + _coords2 += 4; + } else { + int testX = READ_UINT16(_coords2 - 4); + int testY = READ_UINT16(_coords2 - 2); + if (testX != x1 || testY != y1) { + //no_compare + WRITE_UINT16(_coords2, x1); + WRITE_UINT16(_coords2 + 2, y1); + _coords2 += 4; + } + } + //no_store_first + _tracePointFlag = 0; + Graphics::drawLine(x1, y1, x2, y2, 0, &this->plotTracePoint, this); + if (!_tracePointFlag) { + tempCoords = tempCoordsBuf - 4; + tempCoordsBuf = _coordsBuf; + } + } else { + break; + } + } + } } -void PrinceEngine::makePath(int destX, int destY) { +int PrinceEngine::makePath(int destX, int destY) { int pathLen1 = 0; // global? int pathLen2 = 0; // global? int stX = 0; // global? @@ -3841,7 +3942,7 @@ void PrinceEngine::makePath(int destX, int destY) { _flags->setFlagValue(Flags::MOVEDESTX, destX); _flags->setFlagValue(Flags::MOVEDESTY, destY); - int ebp = -2; + //int ebp = -2; int currX = _mainHero->_middleX; // second hero int currY = _mainHero->_middleY; @@ -3865,7 +3966,7 @@ void PrinceEngine::makePath(int destX, int destY) { //add esp,8 //byemovemove //eax = -1 - return; + return 0; //? } } // not_differs @@ -3874,15 +3975,60 @@ void PrinceEngine::makePath(int destX, int destY) { stX = x1; // stXY stY = y1; // stXY + 2 - tracePath(x1, y1, x2, y2); + if (!tracePath(x1, y1, x2, y2)) { + allocCoords2(); + approxPath(); + //copy from 2 to 1 + //approxPath(); + // ... + } else { + ///TODO - no else? + if (!tracePath(x2, y2, x1, y2)) { + //allocCoords2(); + approxPath(); + //copyFromCoords2toCoords(); + approxPath(); + // ... + } else { + } + } } else { //byemove //freeOldMove(); _mainHero->_state = _mainHero->TURN; // eax = -1 - return; + return 0; //? + } + return 0; //? +} + +void PrinceEngine::allocCoords2() { + _coordsBuf2 = (byte *)malloc(kTracePts * 4); + _coords2 = _coordsBuf2; +} + +void PrinceEngine::freeCoords2() { + free(_coordsBuf2); + free(_coords2); +} + +void PrinceEngine::freeCoords3() { + free(_coordsBuf3); + free(_coords3); +} + +void PrinceEngine::testDrawPath() { + /* + byte *tempCoords = _coords; + while (tempCoords != _coordsBuf) { + int x = READ_UINT16(tempCoords - 2); + int y = READ_UINT16(tempCoords - 4); + tempCoords -= 4; + debug("x: %d, y: %d", x, y); + _graph->drawPixel(_graph->_frontScreen, x, y); } + */ } void PrinceEngine::mainLoop() { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index ece1c4b2519a..5dffaf6f73fb 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -449,11 +449,17 @@ class PrinceEngine : public Engine { int _fpX1; int _fpY1; Direction _direction; - int _coordsBufEnd; + byte *_coordsBufEnd; byte *_coordsBuf; // optimal path byte *_coords; // last path point adress from coordsBuf + byte *_coordsBuf2; + byte *_coords2; + byte *_coordsBuf3; + byte *_coords3; int _traceLineLen; int _traceLineFlag; // return value of plotTraceLine + bool _traceLineFirstPointFlag; // if plotTraceLine after first point + int _tracePointFlag; // return value of plotTracePoint byte *_checkBitmapTemp; //esi byte *_checkBitmap; // ebp @@ -475,7 +481,7 @@ class PrinceEngine : public Engine { } _fpResult; bool loadPath(const char *resourceName); - void makePath(int destX, int destY); + int makePath(int destX, int destY); void findPoint(int x1, int y1, int x2, int y2); int fpGetPixelAddr(int x, int y); int fpGetPixel(int x, int y); @@ -486,8 +492,15 @@ class PrinceEngine : public Engine { Direction makeDirection(int x1, int y1, int x2, int y2); void specialPlot(int x, int y); void specialPlot2(int x, int y); + void allocCoords2(); + void freeCoords2(); + void freeCoords3(); + static void plotTracePoint(int x, int y, int color, void *data); + void specialPlotInside2(int x, int y); void approxPath(); + void testDrawPath(); + int leftDownDir(); int leftDir(); int leftUpDir(); From 52dbd8866e418c4f0f7861216e14a70263822949 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 14 Jul 2014 01:19:32 +0200 Subject: [PATCH 243/374] PRINCE: makePath update, bug fixing --- engines/prince/prince.cpp | 142 ++++++++++++++++++++++++++++++-------- 1 file changed, 114 insertions(+), 28 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 68ef70159e03..d6b57a39ea09 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -3923,6 +3923,8 @@ void PrinceEngine::approxPath() { if (!_tracePointFlag) { tempCoords = tempCoordsBuf - 4; tempCoordsBuf = _coordsBuf; + } else { + _coords2 = oldCoords; } } else { break; @@ -3932,13 +3934,8 @@ void PrinceEngine::approxPath() { } int PrinceEngine::makePath(int destX, int destY) { - int pathLen1 = 0; // global? - int pathLen2 = 0; // global? - int stX = 0; // global? - int stY = 0; // global? - - int realDestX = destX; // global? - int realDestY = destY; // global? + int realDestX = destX; + int realDestY = destY; _flags->setFlagValue(Flags::MOVEDESTX, destX); _flags->setFlagValue(Flags::MOVEDESTY, destY); @@ -3966,41 +3963,128 @@ int PrinceEngine::makePath(int destX, int destY) { //add esp,8 //byemovemove //eax = -1 - return 0; //? + return -1; } } // not_differs - pathLen1 = 0; - pathLen2 = 0; - stX = x1; // stXY - stY = y1; // stXY + 2 + int pathLen1 = 0; + int pathLen2 = 0; + int stX = x1; // stXY + int stY = y1; // stXY + 2 + int sizeCoords2 = 0; if (!tracePath(x1, y1, x2, y2)) { allocCoords2(); approxPath(); - //copy from 2 to 1 - //approxPath(); - // ... - } else { - ///TODO - no else? - if (!tracePath(x2, y2, x1, y2)) { - //allocCoords2(); - approxPath(); - //copyFromCoords2toCoords(); - approxPath(); - // ... - } else { + 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 = _coordsBuf2; + choosenCoords = _coords3; + choosenLength = pathLen2; + } + if (choosenLength) { + if (chosenCoordsBuf != nullptr) { + int tempXBegin = READ_UINT16(chosenCoordsBuf); + int tempYBegin = READ_UINT16(chosenCoordsBuf + 2); + if (stX != tempXBegin || stY != tempYBegin) { + SWAP(chosenCoordsBuf, choosenCoords); + chosenCoordsBuf -= 4; + int cord; + byte *tempCoordsBuf = _coordsBuf; + while (1) { + cord = READ_UINT32(chosenCoordsBuf); + WRITE_UINT32(tempCoordsBuf, cord); + if (chosenCoordsBuf == choosenCoords) { + break; + } + chosenCoordsBuf -= 4; + tempCoordsBuf += 4; + } + _coords = tempCoordsBuf; + } else { + int sizeChoosen = choosenCoords - chosenCoordsBuf; + for (int i = 0; i < sizeChoosen; i++) { + _coordsBuf[i] = chosenCoordsBuf[i]; + } + _coords = _coordsBuf + sizeChoosen; + } + //done_back + WRITE_UINT32(_coords, -1); + freeCoords2(); + freeCoords3(); + //scanDirections(); + + // normal values: + byte *tempCoordsBuf = _coordsBuf; // esi + byte *tempCoords = _coords; // eax + byte *newCoords; + byte *newCoordsBegin; + int newValueX = 0; + int newValueY = 0; + if (tempCoordsBuf != tempCoords) { + int normCoordsSize = _coords - _coordsBuf + 4; + newCoords = (byte *)malloc(normCoordsSize); // edi + newCoordsBegin = newCoords; + while (tempCoordsBuf != tempCoords) { + newValueX = READ_UINT16(tempCoordsBuf); + WRITE_UINT16(newCoords, newValueX * 2); + newCoords += 2; + newValueY = READ_UINT16(tempCoordsBuf + 2); + WRITE_UINT16(newCoords, newValueY * 2); + newCoords += 2; + tempCoordsBuf += 4; + } + //copy_coords_done: + WRITE_UINT16(newCoords - 4, realDestX); + WRITE_UINT16(newCoords - 2, realDestY); + WRITE_UINT32(newCoords, -1); + newCoords += 4; + int shanLen1 = (newCoords - newCoordsBegin); // to global? + // shr shanLen1, 2 ? + //return newCoordsBegin; + return 0; + } } } + // no_path_at_all + _coords = _coordsBuf; + _coordsBuf = nullptr; + freeCoords2(); + freeCoords3(); + return -1; } else { //byemove //freeOldMove(); _mainHero->_state = _mainHero->TURN; // eax = -1 - return 0; //? + return -1; } - return 0; //? } void PrinceEngine::allocCoords2() { @@ -4010,12 +4094,14 @@ void PrinceEngine::allocCoords2() { void PrinceEngine::freeCoords2() { free(_coordsBuf2); - free(_coords2); + _coordsBuf2 = nullptr; + _coords2 = nullptr; } void PrinceEngine::freeCoords3() { free(_coordsBuf3); - free(_coords3); + _coordsBuf3 = nullptr; + _coords3 = nullptr; } void PrinceEngine::testDrawPath() { From b0c454fc9ba282f5f72a0c69a6b897e38eaddb82 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 14 Jul 2014 03:26:17 +0200 Subject: [PATCH 244/374] PRINCE: Pathfinding - bug fixing, first correct path --- engines/prince/hero.cpp | 16 ++++++ engines/prince/hero.h | 17 +++---- engines/prince/prince.cpp | 101 +++++++++++++++++++++----------------- engines/prince/prince.h | 6 ++- engines/prince/script.cpp | 8 +-- 5 files changed, 91 insertions(+), 57 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index e91d6a971fef..94c7b8b313e2 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -38,6 +38,7 @@ Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph) , _specAnim(0), _drawX(0), _drawY(0), _drawZ(0), _zoomFactor(0), _scaleValue(0) , _shadZoomFactor(0), _shadScaleValue(0), _shadLineLen(0), _shadDrawX(0), _shadDrawY(0) , _frameXSize(0), _frameYSize(0), _scaledFrameXSize(0), _scaledFrameYSize(0), _color(0) + , _coords(nullptr), _dirTab(nullptr), _currCoords(nullptr), _currDirTab(nullptr), _step(0) { _zoomBitmap = (byte *)malloc(kZoomBitmapLen); _shadowBitmap = (byte *)malloc(2 * kShadowBitmapSize); @@ -788,6 +789,21 @@ void Hero::scrollHero() { _drawX -= destValue; } +void Hero::freeOldMove() { + if (_coords != nullptr) { + free(_coords); + _coords = nullptr; + } + if (_dirTab != nullptr) { + free(_dirTab); + _dirTab = nullptr; + } + _step = 0; + _phase = 0; + _moveDelay = 0; + _state = Hero::STAY; +} + } /* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/hero.h b/engines/prince/hero.h index ae33419176ed..82b4ac7dd77a 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -132,6 +132,7 @@ class Hero { void setShadowScale(int32 shadowScale); void specialAnim(); void getState(); + void freeOldMove(); //private: PrinceEngine *_vm; @@ -142,8 +143,6 @@ class Hero { int16 _state; int16 _middleX; // middle of X int16 _middleY; // lower part of hero - int16 _lastDirection; - int16 _destDirection; int16 _moveSetType; int8 _zoomFactor; @@ -164,16 +163,16 @@ class Hero { int16 _shadDrawX; int16 _shadDrawY; - // Coords array of coordinates - // DirTab array of directions - // CurrCoords current coordinations - // CurrDirTab current direction - // LastDir previous move direction - // DestDir + byte *_coords; // array of coordinates + byte *_dirTab; // array of directions + byte *_currCoords; // current coordinations + byte *_currDirTab; // current direction + int16 _lastDirection; // previous move direction + int16 _destDirection; // LeftRight previous left/right direction // UpDown previous up/down direction int32 _phase; // Phase animation phase - // Step x/y step size depends on direction + int16 _step; // Step x/y step size depends on direction // MaxBoredom stand still timeout int16 _boredomTime;// Boredom current boredom time in frames uint16 _boreNum; // Bore anim frame diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index d6b57a39ea09..48ffc576a816 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -94,7 +94,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _traceLineLen(0), _traceLineFlag(0), _rembBitmapTemp(nullptr), _rembBitmap(nullptr), _rembMask(0), _rembX(0), _rembY(0), _checkBitmapTemp(nullptr), _checkBitmap(nullptr), _checkMask(0), _checkX(0), _checkY(0), _traceLineFirstPointFlag(false), _coordsBuf2(nullptr), _coords2(nullptr), _coordsBuf3(nullptr), _coords3(nullptr), - _tracePointFlag(0) { + _tracePointFlag(0), _shanLen1(0), _directionTable(nullptr) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -2013,7 +2013,9 @@ void PrinceEngine::leftMouseButton() { _optionsMob = _selectedMob; if (_optionsMob == -1) { // @@walkto - TODO - if (_mainHero->_visible) { // second hero? + if (_mainHero->_visible) { + //freeHeroAnim(); + _mainHero->freeOldMove(); _interpreter->storeNewPC(_script->_scriptInfo.usdCode); int destX, destY; if (_optionsMob != -1) { @@ -2026,8 +2028,14 @@ void PrinceEngine::leftMouseButton() { destY = mousePos.y; _mainHero->_destDirection = 0; // second hero? } - if (makePath(destX, destY)) { - // Shani movement + _mainHero->_coords = makePath(destX, destY); + if (_mainHero->_coords != nullptr) { + _mainHero->_currCoords = _mainHero->_coords; + _mainHero->_dirTab = _directionTable; + _mainHero->_currDirTab = _directionTable; + _directionTable = nullptr; + _mainHero->_state = _mainHero->MOVE; + moveShandria(); } } return; @@ -2094,6 +2102,9 @@ void PrinceEngine::leftMouseButton() { void PrinceEngine::rightMouseButton() { if (_mouseFlag) { + _mainHero->freeOldMove(); + _secondHero->freeOldMove(); + _interpreter->storeNewPC(0); if (_currentPointerNumber < 2) { enableOptions(); } else { @@ -3441,7 +3452,6 @@ int PrinceEngine::cpe() { _checkBitmapTemp = _rembBitmapTemp; _checkBitmap = _rembBitmap; _checkMask = _rembMask; - // add esp, 4 ?? return -1; } return 0; @@ -3480,8 +3490,7 @@ int PrinceEngine::checkLeftDownDir() { } _checkX--; _checkY++; - cpe(); - return 0; + return cpe(); } else { return -1; } @@ -3515,8 +3524,7 @@ int PrinceEngine::checkLeftDir() { } } _checkX--; - cpe(); - return 0; + return cpe(); } else { return -1; } @@ -3529,8 +3537,7 @@ int PrinceEngine::checkDownDir() { _checkBitmap += kPBW; _checkBitmapTemp += kPBW; _checkY++; - cpe(); - return 0; + return cpe(); } else { return 1; } @@ -3549,8 +3556,7 @@ int PrinceEngine::checkUpDir() { _checkBitmap -= kPBW; _checkBitmapTemp -= kPBW; _checkY--; - cpe(); - return 0; + return cpe(); } else { return 1; } @@ -3590,8 +3596,7 @@ int PrinceEngine::checkRightDir() { } } _checkX++; - cpe(); - return 0; + return cpe(); } else { return -1; } @@ -3628,8 +3633,7 @@ int PrinceEngine::checkLeftUpDir() { } _checkX--; _checkY--; - cpe(); - return 0; + return cpe(); } else { return -1; } @@ -3666,8 +3670,7 @@ int PrinceEngine::checkRightDownDir() { } _checkX++; _checkY++; - cpe(); - return 0; + return cpe(); } else { return -1; } @@ -3704,8 +3707,7 @@ int PrinceEngine::checkRightUpDir() { } _checkX++; _checkY--; - cpe(); - return 0; + return cpe(); } else { return -1; } @@ -3933,7 +3935,17 @@ void PrinceEngine::approxPath() { } } -int PrinceEngine::makePath(int destX, int destY) { +// TODO +void PrinceEngine::scanDirections() { + +} + +// TODO +void PrinceEngine::moveShandria() { + +} + +byte *PrinceEngine::makePath(int destX, int destY) { int realDestX = destX; int realDestY = destY; _flags->setFlagValue(Flags::MOVEDESTX, destX); @@ -3963,7 +3975,7 @@ int PrinceEngine::makePath(int destX, int destY) { //add esp,8 //byemovemove //eax = -1 - return -1; + return nullptr; } } // not_differs @@ -4004,7 +4016,7 @@ int PrinceEngine::makePath(int destX, int destY) { byte *choosenCoords = _coords2; int choosenLength = pathLen1; if (pathLen1 < pathLen2) { - chosenCoordsBuf = _coordsBuf2; + chosenCoordsBuf = _coordsBuf3; choosenCoords = _coords3; choosenLength = pathLen2; } @@ -4035,10 +4047,10 @@ int PrinceEngine::makePath(int destX, int destY) { _coords = _coordsBuf + sizeChoosen; } //done_back - WRITE_UINT32(_coords, -1); + WRITE_UINT32(_coords, 0xFFFFFFFF); freeCoords2(); freeCoords3(); - //scanDirections(); + scanDirections(); // normal values: byte *tempCoordsBuf = _coordsBuf; // esi @@ -4063,12 +4075,11 @@ int PrinceEngine::makePath(int destX, int destY) { //copy_coords_done: WRITE_UINT16(newCoords - 4, realDestX); WRITE_UINT16(newCoords - 2, realDestY); - WRITE_UINT32(newCoords, -1); + WRITE_UINT32(newCoords, 0xFFFFFFFF); newCoords += 4; - int shanLen1 = (newCoords - newCoordsBegin); // to global? - // shr shanLen1, 2 ? - //return newCoordsBegin; - return 0; + _shanLen1 = (newCoords - newCoordsBegin); + //_shanLen1 /= 4 ? + return newCoordsBegin; // free memory! } } } @@ -4077,13 +4088,12 @@ int PrinceEngine::makePath(int destX, int destY) { _coordsBuf = nullptr; freeCoords2(); freeCoords3(); - return -1; + return nullptr; } else { //byemove - //freeOldMove(); + _mainHero->freeOldMove(); _mainHero->_state = _mainHero->TURN; - // eax = -1 - return -1; + return nullptr; } } @@ -4105,16 +4115,19 @@ void PrinceEngine::freeCoords3() { } void PrinceEngine::testDrawPath() { - /* - byte *tempCoords = _coords; - while (tempCoords != _coordsBuf) { - int x = READ_UINT16(tempCoords - 2); - int y = READ_UINT16(tempCoords - 4); - tempCoords -= 4; - debug("x: %d, y: %d", x, y); - _graph->drawPixel(_graph->_frontScreen, x, y); + byte *tempCoords = _mainHero->_coords; + if (tempCoords != nullptr) { + while (1) { + int flag = READ_UINT32(tempCoords); + if (flag == 0xFFFFFFFF) { + break; + } + int x = READ_UINT16(tempCoords); + int y = READ_UINT16(tempCoords + 2); + tempCoords += 4; + _graph->drawPixel(_graph->_frontScreen, x, y); + } } - */ } void PrinceEngine::mainLoop() { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 5dffaf6f73fb..89c24ec0a512 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -460,6 +460,8 @@ class PrinceEngine : public Engine { int _traceLineFlag; // return value of plotTraceLine bool _traceLineFirstPointFlag; // if plotTraceLine after first point int _tracePointFlag; // return value of plotTracePoint + byte *_directionTable; + int _shanLen1; byte *_checkBitmapTemp; //esi byte *_checkBitmap; // ebp @@ -481,7 +483,7 @@ class PrinceEngine : public Engine { } _fpResult; bool loadPath(const char *resourceName); - int makePath(int destX, int destY); + byte *makePath(int destX, int destY); void findPoint(int x1, int y1, int x2, int y2); int fpGetPixelAddr(int x, int y); int fpGetPixel(int x, int y); @@ -498,6 +500,8 @@ class PrinceEngine : public Engine { static void plotTracePoint(int x, int y, int color, void *data); void specialPlotInside2(int x, int y); void approxPath(); + void scanDirections(); + void moveShandria(); void testDrawPath(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 36cd991bfdad..14fae2b42fa4 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1588,10 +1588,12 @@ void Interpreter::O_SETFGCODE() { void Interpreter::O_STOPHERO() { uint16 heroId = readScriptFlagValue(); - + if (!heroId) { + _vm->_mainHero->freeOldMove(); + } else if (heroId == 1) { + _vm->_secondHero->freeOldMove(); + } debugInterpreter("O_STOPHERO heroId %d", heroId); - - // clear move steps for hero } void Interpreter::O_ANIMUPDATEOFF() { From 6fe1bb3c9cf8bc840b1a797debbccdf9a0d0bea8 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 16 Jul 2014 22:12:29 +0200 Subject: [PATCH 245/374] PRINCE: Pathfinding - scanDirections() --- engines/prince/graphics.cpp | 2 +- engines/prince/prince.cpp | 134 +++++++++++++++++++++++++++++++++++- engines/prince/prince.h | 2 + 3 files changed, 135 insertions(+), 3 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 7a3e310320d7..d89b9bc048c4 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -228,7 +228,7 @@ void GraphicsMan::drawAsShadowDrawNode(Graphics::Surface *screen, DrawNode *draw void GraphicsMan::drawPixel(Graphics::Surface *screen, int32 posX, int32 posY) { byte *dst = (byte *)screen->getBasePtr(posX, posY); - *dst = 0; + *dst = 255; change(); } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 48ffc576a816..3e449c61d917 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -3935,9 +3935,139 @@ void PrinceEngine::approxPath() { } } -// TODO -void PrinceEngine::scanDirections() { +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::LEFT; + if (xDiff < 0) { + tempX = Hero::RIGHT; + } + tempY = Hero::UP; + if (yDiff < 0) { + tempY = Hero::DOWN; + } + // push esi, edx + // again_point: + byte *againPointCoords = tempCoordsBuf; + while (1) { + int againPointX1 = READ_UINT16(againPointCoords); + int againPointY1 = READ_UINT16(againPointCoords + 2); + againPointCoords += 4; + if (againPointCoords == _coords) { + direction = tempX; + break; + } + int dX = againPointX1 - READ_UINT16(againPointCoords); // dx + int dY = againPointY1 - READ_UINT16(againPointCoords + 2); //bp + + if (dX != xDiff) { + direction = tempY; + break; + } + + if (dY != yDiff) { + direction = tempX; + break; + } + } + return direction; +} + +void PrinceEngine::scanDirections() { + freeDirectionTable(); + byte *tempCoordsBuf = _coordsBuf; // esi + if (tempCoordsBuf != _coords) { + int size = (_coords - tempCoordsBuf) / 2 + 1; // number of coord points plus one for end marker + _directionTable = (byte *)malloc(size); + byte *tempDirTab = _directionTable; // edi + // ebp = 0; + int direction = -1; + int lastDirection = -1; + int tempX = -1; + int tempY = -1; + + //loop + while (1) { + int x1 = READ_UINT16(tempCoordsBuf); + int y1 = READ_UINT16(tempCoordsBuf + 2); + tempCoordsBuf += 4; + if (tempCoordsBuf == _coords) { + break; + } + int x2 = READ_UINT16(tempCoordsBuf); + int y2 = READ_UINT16(tempCoordsBuf + 2); + + int xDiff = x1 - x2; // eax + int yDiff = y1 - y2; // ebx + + if (xDiff) { + if (yDiff) { + // skew + if (lastDirection != -1) { + direction = lastDirection; + if (direction == Hero::LEFT) { + if (xDiff < 0) { + //findnext + scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff); + } + } else if (direction == Hero::RIGHT) { + if (xDiff >= 0) { + //findnext + scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff); + } + } else if (direction == Hero::UP) { + if (yDiff < 0) { + //findnext + scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff); + } + } else { + if (yDiff >= 0) { + //findnext + scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff); + } + } + } else { + //no direction at all + // find next + scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff); + } + } else { + direction = Hero::LEFT; + if (xDiff < 0) { + direction = Hero::RIGHT; + } + } + } else { + //updown_dominates + if (yDiff) { + direction = Hero::UP; + if (yDiff < 0) { + direction = Hero::DOWN; + } + } else { + //skip_point + direction = lastDirection; + } + } + lastDirection = direction; + WRITE_UINT16(tempDirTab, direction); + tempDirTab += 2; + } + // finito + int end = *(tempDirTab - 1); + WRITE_UINT16(tempDirTab, end); + tempDirTab += 2; + WRITE_UINT16(tempDirTab, 0); + tempDirTab += 2; + } } // TODO diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 89c24ec0a512..7a6596ada607 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -500,7 +500,9 @@ class PrinceEngine : public Engine { static void plotTracePoint(int x, int y, int color, void *data); void specialPlotInside2(int x, int y); void approxPath(); + void freeDirectionTable(); void scanDirections(); + int scanDirectionsFindNext(byte *coords, int xDiff, int yDiff); void moveShandria(); void testDrawPath(); From dfddfbbd795156ecf2ff83b009c1fb73901a37a3 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 17 Jul 2014 14:28:44 +0200 Subject: [PATCH 246/374] PRINCE: scanDirections() fix --- engines/prince/hero.cpp | 11 ++++-- engines/prince/hero.h | 2 +- engines/prince/prince.cpp | 82 ++++++++++++++++----------------------- 3 files changed, 43 insertions(+), 52 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 94c7b8b313e2..349418bef6bf 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -649,12 +649,17 @@ void Hero::showHero() { if (_visible) { if (_talkTime != 0) { _talkTime--; - if (_talkTime == 0) { - _state = STAY; // test this - } + //if (_talkTime == 0) { + //_state = STAY; // test this + //} } // Scale of hero selectZoom(); + + if (_state != STAY) { + _boredomTime = 0; + } + switch (_state) { case STAY: //if(OptionsFlag == false) { diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 82b4ac7dd77a..9effde6228e0 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -174,7 +174,7 @@ class Hero { int32 _phase; // Phase animation phase int16 _step; // Step x/y step size depends on direction // MaxBoredom stand still timeout - int16 _boredomTime;// Boredom current boredom time in frames + int16 _boredomTime; // Boredom current boredom time in frames uint16 _boreNum; // Bore anim frame int16 _talkTime; // TalkTime time of talk anim int32 _specAnim; // SpecAnim additional anim diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 3e449c61d917..e422077427fa 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -3936,7 +3936,7 @@ void PrinceEngine::approxPath() { } void PrinceEngine::freeDirectionTable() { - if (_directionTable = nullptr) { + if (_directionTable != nullptr) { free(_directionTable); _directionTable = nullptr; } @@ -3944,29 +3944,30 @@ void PrinceEngine::freeDirectionTable() { int PrinceEngine::scanDirectionsFindNext(byte *tempCoordsBuf, int xDiff, int yDiff) { - int tempX, tempY, direction; + int tempX, tempY, direction, dX, dY, againPointX1, againPointY1; tempX = Hero::LEFT; if (xDiff < 0) { tempX = Hero::RIGHT; } + tempY = Hero::UP; if (yDiff < 0) { tempY = Hero::DOWN; } - // push esi, edx - // again_point: - byte *againPointCoords = tempCoordsBuf; + while (1) { - int againPointX1 = READ_UINT16(againPointCoords); - int againPointY1 = READ_UINT16(againPointCoords + 2); - againPointCoords += 4; - if (againPointCoords == _coords) { + againPointX1 = READ_UINT16(tempCoordsBuf); + againPointY1 = READ_UINT16(tempCoordsBuf + 2); + tempCoordsBuf += 4; + + if (tempCoordsBuf == _coords) { direction = tempX; break; } - int dX = againPointX1 - READ_UINT16(againPointCoords); // dx - int dY = againPointY1 - READ_UINT16(againPointCoords + 2); //bp + + dX = againPointX1 - READ_UINT16(tempCoordsBuf); + dY = againPointY1 - READ_UINT16(tempCoordsBuf + 2); if (dX != xDiff) { direction = tempY; @@ -3983,61 +3984,51 @@ int PrinceEngine::scanDirectionsFindNext(byte *tempCoordsBuf, int xDiff, int yDi void PrinceEngine::scanDirections() { freeDirectionTable(); - byte *tempCoordsBuf = _coordsBuf; // esi + byte *tempCoordsBuf = _coordsBuf; if (tempCoordsBuf != _coords) { - int size = (_coords - tempCoordsBuf) / 2 + 1; // number of coord points plus one for end marker + int size = (_coords - tempCoordsBuf) / 4 + 1; // number of coord points plus one for end marker _directionTable = (byte *)malloc(size); - byte *tempDirTab = _directionTable; // edi - // ebp = 0; + byte *tempDirTab = _directionTable; int direction = -1; int lastDirection = -1; - int tempX = -1; - int tempY = -1; - - //loop + int x1, y1, x2, y2, xDiff, yDiff; + while (1) { - int x1 = READ_UINT16(tempCoordsBuf); - int y1 = READ_UINT16(tempCoordsBuf + 2); + x1 = READ_UINT16(tempCoordsBuf); + y1 = READ_UINT16(tempCoordsBuf + 2); tempCoordsBuf += 4; if (tempCoordsBuf == _coords) { break; } - int x2 = READ_UINT16(tempCoordsBuf); - int y2 = READ_UINT16(tempCoordsBuf + 2); + x2 = READ_UINT16(tempCoordsBuf); + y2 = READ_UINT16(tempCoordsBuf + 2); - int xDiff = x1 - x2; // eax - int yDiff = y1 - y2; // ebx + xDiff = x1 - x2; + yDiff = y1 - y2; if (xDiff) { if (yDiff) { - // skew if (lastDirection != -1) { direction = lastDirection; if (direction == Hero::LEFT) { if (xDiff < 0) { - //findnext - scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff); + direction = scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff); } } else if (direction == Hero::RIGHT) { if (xDiff >= 0) { - //findnext - scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff); + direction = scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff); } } else if (direction == Hero::UP) { if (yDiff < 0) { - //findnext - scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff); + direction = scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff); } } else { if (yDiff >= 0) { - //findnext - scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff); + direction = scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff); } } } else { - //no direction at all - // find next - scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff); + direction = scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff); } } else { direction = Hero::LEFT; @@ -4046,27 +4037,22 @@ void PrinceEngine::scanDirections() { } } } else { - //updown_dominates if (yDiff) { direction = Hero::UP; if (yDiff < 0) { direction = Hero::DOWN; } } else { - //skip_point direction = lastDirection; } } lastDirection = direction; - WRITE_UINT16(tempDirTab, direction); - tempDirTab += 2; - } - // finito - int end = *(tempDirTab - 1); - WRITE_UINT16(tempDirTab, end); - tempDirTab += 2; - WRITE_UINT16(tempDirTab, 0); - tempDirTab += 2; + *tempDirTab = direction; + tempDirTab++; + } + *tempDirTab = *(tempDirTab - 1); + tempDirTab++; + *tempDirTab = 0; } } From f4a35de7ebc67d0888ce25d85d2021f71adeb9c5 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 18 Jul 2014 15:35:43 +0200 Subject: [PATCH 247/374] PRINCE: showHero() update --- engines/prince/hero.cpp | 243 +++++++++++++++++++++++++++----------- engines/prince/hero.h | 18 +-- engines/prince/prince.cpp | 31 ++--- engines/prince/prince.h | 4 +- engines/prince/script.cpp | 6 +- engines/prince/script.h | 1 + 6 files changed, 206 insertions(+), 97 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 349418bef6bf..07aa550f253a 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -28,17 +28,20 @@ #include "prince/resource.h" #include "prince/prince.h" #include "prince/graphics.h" +#include "prince/flags.h" +#include "prince/script.h" namespace Prince { Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph) , _number(0), _visible(false), _state(MOVE), _middleX(0), _middleY(0) , _boreNum(1), _currHeight(0), _moveDelay(0), _shadMinus(0), _moveSetType(0) - , _lastDirection(DOWN), _destDirection(DOWN), _talkTime(0), _boredomTime(0), _phase(0) + , _lastDirection(kHeroDirDown), _destDirection(kHeroDirDown), _talkTime(0), _boredomTime(0), _phase(0) , _specAnim(0), _drawX(0), _drawY(0), _drawZ(0), _zoomFactor(0), _scaleValue(0) , _shadZoomFactor(0), _shadScaleValue(0), _shadLineLen(0), _shadDrawX(0), _shadDrawY(0) , _frameXSize(0), _frameYSize(0), _scaledFrameXSize(0), _scaledFrameYSize(0), _color(0) , _coords(nullptr), _dirTab(nullptr), _currCoords(nullptr), _currDirTab(nullptr), _step(0) + , _maxBoredom(200), _turnAnim(0), _leftRightMainDir(0), _upDownMainDir(0) { _zoomBitmap = (byte *)malloc(kZoomBitmapLen); _shadowBitmap = (byte *)malloc(2 * kShadowBitmapSize); @@ -588,71 +591,60 @@ void Hero::setShadowScale(int32 shadowScale) { void Hero::specialAnim() { } -void Hero::rotateHero() { - switch (_lastDirection) { - case LEFT: - switch (_destDirection) { - case RIGHT: - _moveSetType = kMove_MLR; - break; - case UP: - _moveSetType = kMove_MLU; - break; - case DOWN: - _moveSetType = kMove_MLD; - break; +int Hero::rotateHero(int oldDirection, int newDirection) { + switch (oldDirection) { + case kHeroDirLeft: + switch (newDirection) { + case kHeroDirRight: + return kMove_MLR; + case kHeroDirUp: + return kMove_MLU; + case kHeroDirDown: + return kMove_MLD; } break; - case RIGHT: - switch (_destDirection) { - case LEFT: - _moveSetType = kMove_MRL; - break; - case UP: - _moveSetType = kMove_MRU; - break; - case DOWN: - _moveSetType = kMove_MRD; - break; + case kHeroDirRight: + switch (newDirection) { + case kHeroDirLeft: + return kMove_MRL; + case kHeroDirUp: + return kMove_MRU; + case kHeroDirDown: + return kMove_MRD; } break; - case UP: - switch (_destDirection) { - case LEFT: - _moveSetType = kMove_MUL; - break; - case RIGHT: - _moveSetType = kMove_MUR; - break; - case DOWN: - _moveSetType = kMove_MUD; - break; + case kHeroDirUp: + switch (newDirection) { + case kHeroDirLeft: + return kMove_MUL; + case kHeroDirRight: + return kMove_MUR; + case kHeroDirDown: + return kMove_MUD; } break; - case DOWN: - switch (_destDirection) { - case LEFT: - _moveSetType = kMove_MDL; - break; - case RIGHT: - _moveSetType = kMove_MDR; - break; - case UP: - _moveSetType = kMove_MDU; - break; + case kHeroDirDown: + switch (newDirection) { + case kHeroDirLeft: + return kMove_MDL; + case kHeroDirRight: + return kMove_MDR; + case kHeroDirUp: + return kMove_MDU; } break; } + return -1; } void Hero::showHero() { if (_visible) { + //cmp w FLAGI+NOHEROATALL,ax + //jnz @@no_hero_visible if (_talkTime != 0) { _talkTime--; - //if (_talkTime == 0) { - //_state = STAY; // test this - //} } + // Scale of hero selectZoom(); @@ -662,24 +654,26 @@ void Hero::showHero() { switch (_state) { case STAY: - //if(OptionsFlag == false) { - //if(OpcodePC == null) { - _boredomTime++; - if (_boredomTime == 200) { // 140 for second hero + if (!_vm->_optionsFlag && !_vm->_interpreter->getLastOPCode()) { + _boredomTime++; + if (_boredomTime == _maxBoredom) { + _boredomTime = 0; + _state = BORE; + } + } else { _boredomTime = 0; - _state = BORE; } switch (_lastDirection) { - case LEFT: + case kHeroDirLeft: _moveSetType = kMove_SL; break; - case RIGHT: + case kHeroDirRight: _moveSetType = kMove_SR; break; - case UP: + case kHeroDirUp: _moveSetType = kMove_SU; break; - case DOWN: + case kHeroDirDown: _moveSetType = kMove_SD; break; } @@ -696,17 +690,98 @@ void Hero::showHero() { */ break; case MOVE: - switch (_lastDirection) { - case LEFT: + int x, y, dir, oldMiddleX, oldMiddleY, dX, dY; + //go_for_it: + while (1) { + if (_currCoords != nullptr) { + if (READ_UINT32(_currCoords) != 0xFFFFFFFF) { + x = READ_UINT16(_currCoords); + y = READ_UINT16(_currCoords + 2); + _currCoords += 4; + dir = *_currDirTab; + _currDirTab++; + if (_lastDirection != dir) { + _phase = 0; + int rotateDir = rotateHero(_lastDirection, dir); + _lastDirection = dir; + if (!rotateDir) { + continue; + } else { + _turnAnim = rotateDir; + _state = MVAN; + break; + } + } + //no_need_direction_change + if (dir == kHeroDirLeft) { + if (_middleX - x >= _step) { + break; + } + } else if (dir == kHeroDirRight) { + if (x - _middleX >= _step) { + break; + } + } else if (dir == kHeroDirUp) { + if (_middleY - y >= _step) { + break; + } + } else if (dir == kHeroDirDown) { + if (y - _middleY >= _step) { + break; + } + } + } else { + //finito + _middleX = READ_UINT16(_currCoords - 4); + _middleY = READ_UINT16(_currCoords - 2); + selectZoom(); + free(_coords); + free(_dirTab); + _boredomTime = 0; + _coords = nullptr; + _dirTab = nullptr; + _currCoords = nullptr; + _currDirTab = nullptr; + _phase = 0; + _state = TURN; + //_destDir = 0; + + } + } + } + oldMiddleX = _middleX; + oldMiddleY = _middleY; + _middleX = x; + _middleY = y; + selectZoom(); + + // TODO - useful or not? + dX = oldMiddleX - _middleX; + dY = oldMiddleY - _middleY; + if (dX) { + _leftRightMainDir = kHeroDirLeft; + if (dX >= 0) { + _leftRightMainDir = kHeroDirRight; + } + } + if (dY) { + _upDownMainDir = kHeroDirUp; + if (dY >= 0) { + _upDownMainDir = kHeroDirDown; + } + } + + switch (dir) { + case kHeroDirLeft: _moveSetType = kMove_ML; break; - case RIGHT: + case kHeroDirRight: _moveSetType = kMove_MR; break; - case UP: + case kHeroDirUp: _moveSetType = kMove_MU; break; - case DOWN: + case kHeroDirDown: _moveSetType = kMove_MD; break; } @@ -721,9 +796,9 @@ void Hero::showHero() { _moveSetType = kMove_BORED2; break; } - if (_phase == _moveSet[_moveSetType]->getFrameCount() - 1) { + if (_phase == _moveSet[_moveSetType]->getPhaseCount() - 1) { _boreNum = _vm->_randomSource.getRandomNumber(1); // rand one of two 'bored' animation - _lastDirection = DOWN; + _lastDirection = kHeroDirDown; _state = STAY; } break; @@ -731,26 +806,54 @@ void Hero::showHero() { //specialAnim(); break; case TALK: + if (!_talkTime) { + _state = STAY; + } switch (_lastDirection) { - case LEFT: + case kHeroDirLeft: _moveSetType = kMove_TL; break; - case RIGHT: + case kHeroDirRight: _moveSetType = kMove_TR; break; - case UP: + case kHeroDirUp: _moveSetType = kMove_TU; break; - case DOWN: + case kHeroDirDown: _moveSetType = kMove_TD; break; } break; + case MVAN: case TRAN: + if (_turnAnim) { + if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 1) { + //TODO - not here? + _phase += 2; //? + } else { + //turn_anim_koniec + if (_state == MVAN) { + _state = MOVE; + } else { + _state = STAY; + } + } + } else { + //turn_anim_koniec + if (_state == MVAN) { + _state = MOVE; + } else { + _state = STAY; + } + } break; case RUN: break; case DMOVE: + _moveDelay--; + if (!_moveDelay) { + _state = MOVE; + } break; } showHeroAnimFrame(); diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 9effde6228e0..e48befc07356 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -64,10 +64,10 @@ class Hero { }; enum Direction { - LEFT = 1, - RIGHT = 2, - UP = 3, - DOWN = 4 + kHeroDirLeft = 1, + kHeroDirRight = 2, + kHeroDirUp = 3, + kHeroDirDown = 4 }; enum MoveSet { @@ -118,7 +118,7 @@ class Hero { void showHero(); void moveHero(); - void rotateHero(); + int rotateHero(int oldDirection, int newDirection); void scrollHero(); void setScale(int8 zoomBitmapValue); int getScaledValue(int size); @@ -169,11 +169,11 @@ class Hero { byte *_currDirTab; // current direction int16 _lastDirection; // previous move direction int16 _destDirection; - // LeftRight previous left/right direction - // UpDown previous up/down direction + int16 _leftRightMainDir; // left or right - dominant direction + int16 _upDownMainDir; // up or down - dominant direction int32 _phase; // Phase animation phase int16 _step; // Step x/y step size depends on direction - // MaxBoredom stand still timeout + int16 _maxBoredom; // stand still timeout int16 _boredomTime; // Boredom current boredom time in frames uint16 _boreNum; // Bore anim frame int16 _talkTime; // TalkTime time of talk anim @@ -187,7 +187,7 @@ class Hero { int _color; // Color Subtitles color // AnimSet number of animation set Common::Array _moveSet; // MoveAnims MoveSet - // TurnAnim ?? + int16 _turnAnim; byte *_zoomBitmap; byte *_shadowBitmap; byte *_shadowLine; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index e422077427fa..bbcb9bbb60ac 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -297,6 +297,7 @@ void PrinceEngine::init() { _mainHero = new Hero(this, _graph); _secondHero = new Hero(this, _graph); + _secondHero->_maxBoredom = 140; _mainHero->loadAnimSet(1); _secondHero->loadAnimSet(3); @@ -827,19 +828,19 @@ void PrinceEngine::keyHandler(Common::Event event) { debugEngine("%d", _mainHero->_phase); break; case Common::KEYCODE_w: - _mainHero->_lastDirection = _mainHero->UP; + _mainHero->_lastDirection = _mainHero->kHeroDirUp; debugEngine("UP"); break; case Common::KEYCODE_s: - _mainHero->_lastDirection = _mainHero->DOWN; + _mainHero->_lastDirection = _mainHero->kHeroDirDown; debugEngine("DOWN"); break; case Common::KEYCODE_a: - _mainHero->_lastDirection = _mainHero->LEFT; + _mainHero->_lastDirection = _mainHero->kHeroDirLeft; debugEngine("LEFT"); break; case Common::KEYCODE_f: - _mainHero->_lastDirection = _mainHero->RIGHT; + _mainHero->_lastDirection = _mainHero->kHeroDirRight; debugEngine("RIGHT"); break; case Common::KEYCODE_1: @@ -3946,14 +3947,14 @@ int PrinceEngine::scanDirectionsFindNext(byte *tempCoordsBuf, int xDiff, int yDi int tempX, tempY, direction, dX, dY, againPointX1, againPointY1; - tempX = Hero::LEFT; + tempX = Hero::kHeroDirLeft; if (xDiff < 0) { - tempX = Hero::RIGHT; + tempX = Hero::kHeroDirRight; } - tempY = Hero::UP; + tempY = Hero::kHeroDirUp; if (yDiff < 0) { - tempY = Hero::DOWN; + tempY = Hero::kHeroDirDown; } while (1) { @@ -4010,15 +4011,15 @@ void PrinceEngine::scanDirections() { if (yDiff) { if (lastDirection != -1) { direction = lastDirection; - if (direction == Hero::LEFT) { + if (direction == Hero::kHeroDirLeft) { if (xDiff < 0) { direction = scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff); } - } else if (direction == Hero::RIGHT) { + } else if (direction == Hero::kHeroDirRight) { if (xDiff >= 0) { direction = scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff); } - } else if (direction == Hero::UP) { + } else if (direction == Hero::kHeroDirUp) { if (yDiff < 0) { direction = scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff); } @@ -4031,16 +4032,16 @@ void PrinceEngine::scanDirections() { direction = scanDirectionsFindNext(tempCoordsBuf, xDiff, yDiff); } } else { - direction = Hero::LEFT; + direction = Hero::kHeroDirLeft; if (xDiff < 0) { - direction = Hero::RIGHT; + direction = Hero::kHeroDirRight; } } } else { if (yDiff) { - direction = Hero::UP; + direction = Hero::kHeroDirUp; if (yDiff < 0) { - direction = Hero::DOWN; + direction = Hero::kHeroDirDown; } } else { direction = lastDirection; diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 7a6596ada607..1f9244c58c00 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -299,6 +299,8 @@ class PrinceEngine : public Engine { MhwanhDecoder *_suitcaseBmp; Room *_room; Script *_script; + InterpreterFlags *_flags; + Interpreter *_interpreter; static const int kMaxNormAnims = 64; static const int kMaxBackAnims = 64; @@ -568,8 +570,6 @@ class PrinceEngine : public Engine { Cursor *_cursor3; Debugger *_debugger; GraphicsMan *_graph; - InterpreterFlags *_flags; - Interpreter *_interpreter; Font *_font; MusicPlayer *_midiPlayer; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 14fae2b42fa4..fdf1b7c8efd8 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -458,6 +458,10 @@ void Interpreter::storeNewPC(int opcodePC) { _fgOpcodePC = opcodePC; } +int Interpreter::getLastOPCode() { + return _lastOpcode; +} + uint32 Interpreter::getCurrentString() { return _currentString; } @@ -508,7 +512,7 @@ void Interpreter::O_WAITFOREVER() { _vm->changeCursor(_vm->_currentPointerNumber); _opcodeNF = 1; _currentInstruction -= 2; - //debugInterpreter("O_WAITFOREVER"); + debugInterpreter("O_WAITFOREVER"); } void Interpreter::O_BLACKPALETTE() { diff --git a/engines/prince/script.h b/engines/prince/script.h index 11f1cb8cd7a7..93db83ee650e 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -185,6 +185,7 @@ class Interpreter { void step(); void storeNewPC(int opcodePC); + int getLastOPCode(); uint32 getCurrentString(); void setCurrentString(uint32 value); From 40e1ddf88a191dfd15bd0644f89ef6b6bc4c9f7c Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 18 Jul 2014 21:16:16 +0200 Subject: [PATCH 248/374] PRINCE: showHero() update - hero movement and turning --- engines/prince/hero.cpp | 187 ++++++++++++++++++++++++++-------------- engines/prince/hero.h | 2 + 2 files changed, 125 insertions(+), 64 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 07aa550f253a..60a2e5191f5b 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -551,7 +551,11 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { void Hero::showHeroAnimFrame() { if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 1) { - _phase++; + if (_state == MVAN || _state == TRAN) { + _phase += 2; + } else { + _phase++; + } } else { if (_state == TALK) { _phase = _moveSet[_moveSetType]->getLoopCount(); @@ -679,15 +683,23 @@ void Hero::showHero() { } break; case TURN: - /* - if(_lastDirection == _destDirection) { - _state = STAY; + if (_destDirection) { + if (_lastDirection == _destDirection) { + _state = STAY; + } else { + _phase = 0; + int rotateDir = rotateHero(_lastDirection, _destDirection); + _lastDirection = _destDirection; + if (rotateDir) { + _turnAnim = rotateDir; + _state = TRAN; + } else { + _state = STAY; + } + } } else { - _frame = 0; - rotateHero(); - _lastDirection = _destDirection; + _state = STAY; } - */ break; case MOVE: int x, y, dir, oldMiddleX, oldMiddleY, dX, dY; @@ -735,55 +747,107 @@ void Hero::showHero() { _middleX = READ_UINT16(_currCoords - 4); _middleY = READ_UINT16(_currCoords - 2); selectZoom(); + free(_coords); - free(_dirTab); - _boredomTime = 0; _coords = nullptr; - _dirTab = nullptr; _currCoords = nullptr; + + free(_dirTab); + _dirTab = nullptr; _currDirTab = nullptr; + + _boredomTime = 0; _phase = 0; _state = TURN; - //_destDir = 0; + if (_destDirection) { + _destDirection = _lastDirection; + } + + switch (_lastDirection) { + case kHeroDirLeft: + _moveSetType = kMove_SL; + break; + case kHeroDirRight: + _moveSetType = kMove_SR; + break; + case kHeroDirUp: + _moveSetType = kMove_SU; + break; + case kHeroDirDown: + _moveSetType = kMove_SD; + break; + } + break; } + } else { + break; } } - oldMiddleX = _middleX; - oldMiddleY = _middleY; - _middleX = x; - _middleY = y; - selectZoom(); - - // TODO - useful or not? - dX = oldMiddleX - _middleX; - dY = oldMiddleY - _middleY; - if (dX) { - _leftRightMainDir = kHeroDirLeft; - if (dX >= 0) { - _leftRightMainDir = kHeroDirRight; - } - } - if (dY) { - _upDownMainDir = kHeroDirUp; - if (dY >= 0) { - _upDownMainDir = kHeroDirDown; - } - } + if (_currCoords != nullptr) { + if (READ_UINT32(_currCoords) != 0xFFFFFFFF) { + oldMiddleX = _middleX; + oldMiddleY = _middleY; + _middleX = x; + _middleY = y; + selectZoom(); + + // TODO - useful or not? + dX = oldMiddleX - _middleX; + dY = oldMiddleY - _middleY; + if (dX) { + _leftRightMainDir = kHeroDirLeft; + if (dX >= 0) { + _leftRightMainDir = kHeroDirRight; + } + } + if (dY) { + _upDownMainDir = kHeroDirUp; + if (dY >= 0) { + _upDownMainDir = kHeroDirDown; + } + } - switch (dir) { - case kHeroDirLeft: - _moveSetType = kMove_ML; - break; - case kHeroDirRight: - _moveSetType = kMove_MR; - break; - case kHeroDirUp: - _moveSetType = kMove_MU; - break; - case kHeroDirDown: - _moveSetType = kMove_MD; - break; + switch (dir) { + case kHeroDirLeft: + _moveSetType = kMove_ML; + break; + case kHeroDirRight: + _moveSetType = kMove_MR; + break; + case kHeroDirUp: + _moveSetType = kMove_MU; + break; + case kHeroDirDown: + _moveSetType = kMove_MD; + break; + } + + //TODO - frames here? + if (_moveSet[_moveSetType] != nullptr) { + if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 1) { + if (_vm->_flags->getFlagValue(Flags::HEROFAST) || _state == RUN) { + //_phase += 2; + } else { + //_phase++; + } + } else { + //_phase = 0; + } + } else { + return; + } + + _step = kStepLeftRight; + if (_moveSetType == kMove_MU || _moveSetType == kMove_MD) { + _step = kStepUpDown; + } + if (_vm->_flags->getFlagValue(Flags::HEROFAST)) { + _step *= 2.5; + } else if (_state == RUN) { + _step *= 2; + } + } } break; case BORE: @@ -825,30 +889,25 @@ void Hero::showHero() { } break; case MVAN: - case TRAN: - if (_turnAnim) { - if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 1) { - //TODO - not here? - _phase += 2; //? - } else { - //turn_anim_koniec - if (_state == MVAN) { - _state = MOVE; - } else { - _state = STAY; - } + if (_moveSet[_turnAnim] != nullptr) { + if (_phase >= _moveSet[_turnAnim]->getPhaseCount() - 1) { + _state = MOVE; } } else { - //turn_anim_koniec - if (_state == MVAN) { - _state = MOVE; - } else { + _state = MOVE; + } + break; + case TRAN: + if (_moveSet[_turnAnim] != nullptr) { + if (_phase >= _moveSet[_turnAnim]->getPhaseCount() - 1) { _state = STAY; } + } else { + _state = STAY; } break; - case RUN: - break; + //case RUN: + //break; case DMOVE: _moveDelay--; if (!_moveDelay) { diff --git a/engines/prince/hero.h b/engines/prince/hero.h index e48befc07356..918fa6dc1677 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -49,6 +49,8 @@ class Hero { static const int16 kShadowLineArraySize = 2 * 1280 * 4; static const int32 kShadowBitmapSize = kMaxPicWidth * kMaxPicHeight / 8; static const int16 kScreenWidth = 640; + static const int16 kStepLeftRight = 8; + static const int16 kStepUpDown = 4; enum State { STAY = 0, From d62a85c7859c83a2251e901ed1b235b205139016 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 18 Jul 2014 22:40:01 +0200 Subject: [PATCH 249/374] PRINCE: plotTracePoint() fix --- engines/prince/prince.cpp | 16 +++++++++++----- engines/prince/prince.h | 1 + 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index bbcb9bbb60ac..05db00086940 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -93,7 +93,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _fpFlag(0), _fpX(0), _fpY(0), _fpX1(0), _fpY1(0), _coordsBufEnd(nullptr), _coordsBuf(nullptr), _coords(nullptr), _traceLineLen(0), _traceLineFlag(0), _rembBitmapTemp(nullptr), _rembBitmap(nullptr), _rembMask(0), _rembX(0), _rembY(0), _checkBitmapTemp(nullptr), _checkBitmap(nullptr), _checkMask(0), _checkX(0), _checkY(0), _traceLineFirstPointFlag(false), - _coordsBuf2(nullptr), _coords2(nullptr), _coordsBuf3(nullptr), _coords3(nullptr), + _tracePointFirstPointFlag(false), _coordsBuf2(nullptr), _coords2(nullptr), _coordsBuf3(nullptr), _coords3(nullptr), _tracePointFlag(0), _shanLen1(0), _directionTable(nullptr) { // Debug/console setup @@ -3878,11 +3878,16 @@ void PrinceEngine::specialPlotInside2(int x, int y) { void PrinceEngine::plotTracePoint(int x, int y, int color, void *data) { PrinceEngine *tracePoint = (PrinceEngine *)data; if (!tracePoint->_tracePointFlag) { - if (tracePoint->getPixelAddr(tracePoint->_roomPathBitmap, x, y)) { - tracePoint->specialPlotInside2(x, y); - tracePoint->_tracePointFlag = 0; + if (!tracePoint->_tracePointFirstPointFlag) { + if (tracePoint->getPixelAddr(tracePoint->_roomPathBitmap, x, y)) { + tracePoint->specialPlotInside2(x, y); + tracePoint->_tracePointFlag = 0; + } else { + tracePoint->_tracePointFlag = -1; + } } else { - tracePoint->_tracePointFlag = -1; + tracePoint->_tracePointFirstPointFlag = false; + tracePoint->_tracePointFlag = 0; } } } @@ -3922,6 +3927,7 @@ void PrinceEngine::approxPath() { } //no_store_first _tracePointFlag = 0; + _tracePointFirstPointFlag = true; Graphics::drawLine(x1, y1, x2, y2, 0, &this->plotTracePoint, this); if (!_tracePointFlag) { tempCoords = tempCoordsBuf - 4; diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 1f9244c58c00..7715737b1edb 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -462,6 +462,7 @@ class PrinceEngine : public Engine { int _traceLineFlag; // return value of plotTraceLine bool _traceLineFirstPointFlag; // if plotTraceLine after first point int _tracePointFlag; // return value of plotTracePoint + bool _tracePointFirstPointFlag; // if plotTracePoint after first point byte *_directionTable; int _shanLen1; From 6016f492e54d5629e330a0b489294bf2a6f50f01 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 19 Jul 2014 01:55:58 +0200 Subject: [PATCH 250/374] PRINCE: findPoint() fix and clean-up --- engines/prince/prince.cpp | 208 ++++++++++++++------------------------ engines/prince/prince.h | 35 +++---- 2 files changed, 89 insertions(+), 154 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 05db00086940..53a79ebf734a 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -89,8 +89,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _invOptionsStep(20), _optionsNumber(7), _invOptionsNumber(5), _optionsColor1(236), _optionsColor2(252), _dialogWidth(600), _dialogHeight(0), _dialogLineSpace(10), _dialogColor1(220), _dialogColor2(223), _dialogFlag(false), _dialogLines(0), _dialogText(nullptr), _mouseFlag(1), - _roomPathBitmap(nullptr), _roomPathBitmapTemp(nullptr), _destX(0), _destY(0), _destX2(0), _destY2(0), - _fpFlag(0), _fpX(0), _fpY(0), _fpX1(0), _fpY1(0), _coordsBufEnd(nullptr), _coordsBuf(nullptr), _coords(nullptr), + _roomPathBitmap(nullptr), _roomPathBitmapTemp(nullptr), _coordsBufEnd(nullptr), _coordsBuf(nullptr), _coords(nullptr), _traceLineLen(0), _traceLineFlag(0), _rembBitmapTemp(nullptr), _rembBitmap(nullptr), _rembMask(0), _rembX(0), _rembY(0), _checkBitmapTemp(nullptr), _checkBitmap(nullptr), _checkMask(0), _checkX(0), _checkY(0), _traceLineFirstPointFlag(false), _tracePointFirstPointFlag(false), _coordsBuf2(nullptr), _coords2(nullptr), _coordsBuf3(nullptr), _coords3(nullptr), @@ -2725,21 +2724,6 @@ void PrinceEngine::freeAllNormAnims() { _normAnimList.clear(); } -int PrinceEngine::fpGetPixelAddr(int x, int y) { - _fpX = x; - _fpY = y; - return fpGetPixel(x, y); -} - -// TODO -check -int PrinceEngine::fpGetPixel(int x, int y) { - _fpX1 = x; - _fpY1 = y; - int mask = 128 >> (x & 7); - byte value = _roomPathBitmap[x / 8 + y * 80]; - return (mask & value); -} -// TODO -check int PrinceEngine::getPixelAddr(byte *pathBitmap, int x, int y) { int mask = 128 >> (x & 7); byte value = pathBitmap[x / 8 + y * 80]; @@ -2747,110 +2731,87 @@ int PrinceEngine::getPixelAddr(byte *pathBitmap, int x, int y) { } void PrinceEngine::findPoint(int x1, int y1, int x2, int y2) { - // other names? - _destX = x1; - _destY = y1; - _destX2 = x2; - _destY2 = y2; - _fpFlag = 0; - - if (fpGetPixelAddr(x1, y1)) { - _fpFlag = 1; - if (fpGetPixelAddr(_destX2, _destY2)) { - //bye - _fpResult.x1 = _destX; - _fpResult.y1 = _destY; - _fpResult.x2 = _destX2; - _fpResult.y2 = _destY2; + _fpResult.x1 = x1; + _fpResult.y1 = y1; + _fpResult.x2 = x2; + _fpResult.y2 = y2; + + bool fpFlag = false; + int fpX = x1; + int fpY = y1; + + if (getPixelAddr(_roomPathBitmap, x1, y1)) { + fpFlag = true; + fpX = x2; + fpY = y2; + if (getPixelAddr(_roomPathBitmap, x2, y2)) { return; } } - //got_wrong_point - - int fpL, fpU, fpR, fpD; // global? - fpL = _fpX; - fpU = _fpY; - fpR = _fpX; - fpD = _fpY; + int fpL = fpX; + int fpU = fpY; + int fpR = fpX; + int fpD = fpY; - //loop: while (1) { if (fpD != kMaxPicHeight) { - if (fpGetPixel(_fpX, fpD)) { - //gotcha - if (_fpFlag) { - _destX2 = _fpX1; - _destY2 = _fpY1; + if (getPixelAddr(_roomPathBitmap, fpX, fpD)) { + if (fpFlag) { + _fpResult.x2 = fpX; + _fpResult.y2 = fpD; } else { - _destX = _fpX1; - _destY = _fpY1; + _fpResult.x1 = fpX; + _fpResult.y1 = fpD; } break; } fpD++; } - //no down - if (fpU != 0) { - if (fpGetPixel(_fpX, fpU)) { - //gotcha - if (_fpFlag) { - _destX2 = _fpX1; - _destY2 = _fpY1; + if (fpU) { + if (getPixelAddr(_roomPathBitmap, fpX, fpU)) { + if (fpFlag) { + _fpResult.x2 = fpX; + _fpResult.y2 = fpU; } else { - _destX = _fpX1; - _destY = _fpY1; + _fpResult.x1 = fpX; + _fpResult.y1 = fpU; } break; } fpU--; } - //no_up - if (fpL != 0) { - if (fpGetPixel(fpL, _fpY)) { - //gotcha - if (_fpFlag) { - _destX2 = _fpX1; - _destY2 = _fpY1; + if (fpL) { + if (getPixelAddr(_roomPathBitmap, fpL, fpY)) { + if (fpFlag) { + _fpResult.x2 = fpL; + _fpResult.y2 = fpY; } else { - _destX = _fpX1; - _destY = _fpY1; + _fpResult.x1 = fpL; + _fpResult.y1 = fpY; } break; } fpL--; } - //no_left if (fpR != _sceneWidth) { - if (fpGetPixel(fpL, _fpY)) { - //gotcha - if (_fpFlag) { - _destX2 = _fpX1; - _destY2 = _fpY1; + if (getPixelAddr(_roomPathBitmap, fpR, fpY)) { + if (fpFlag) { + _fpResult.x2 = fpR; + _fpResult.y2 = fpY; } else { - _destX = _fpX1; - _destY = _fpY1; + _fpResult.x1 = fpR; + _fpResult.y1 = fpY; } break; } fpR++; } - //no_right - if (fpD == kMaxPicHeight) { - if (fpL == 0) { - if (fpU == 0) { - if (fpR == _sceneWidth) { - break; - } - } + if (!fpU && fpD == kMaxPicHeight) { + if (!fpL && fpR == _sceneWidth) { + break; } } - //bye - _fpResult.x1 = _destX; - _fpResult.y1 = _destY; - _fpResult.x2 = _destX2; - _fpResult.y2 = _destY2; - return; } } @@ -3718,26 +3679,17 @@ int PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { for (int i = 0; i < kPathBitmapLen; i++) { _roomPathBitmapTemp[i] = 0; } - //pop ecx eax - //mov edi,o CoordsBuf - //mov d Coords,edi if (x1 != x2 || y1 != y2) { - //not_same - _destX = x1; - _destY = y1; - _destX2 = x2; - _destY2 = y2; - Direction dir = makeDirection(x1, y1, x2, y2); - - if (getPixelAddr(_roomPathBitmap, _destX, _destY)) { - if (getPixelAddr(_roomPathBitmap, _destX2, _destY2)) { + //Direction dir = makeDirection(x1, y1, x2, y2); // need this? + if (getPixelAddr(_roomPathBitmap, x1, y1)) { + if (getPixelAddr(_roomPathBitmap, x2, y2)) { _coords = _coordsBuf; - specialPlot(_destX, _destY); + specialPlot(x1, y1); + + int x = x1; + int y = y1; - //trace_loop: - int x = _destX; - int y = _destY; byte *bcad; int btx, bty; @@ -3746,14 +3698,13 @@ int PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { bty = y; bcad = _coords; - //TraceLine _traceLineLen = 0; _traceLineFlag = 0; _traceLineFirstPointFlag = true; - Graphics::drawLine(x, y, _destX2, _destY2, 0, &this->plotTraceLine, this); + Graphics::drawLine(x, y, x2, y2, 0, &this->plotTraceLine, this); if (!_traceLineFlag) { - specialPlotInside(_destX2, _destY2); + specialPlotInside(x2, y2); return 0; } else if (_traceLineFlag == -1 && _traceLineLen >= 2) { //line_ok @@ -3773,13 +3724,13 @@ int PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { y = bty; } //same_point - dir = makeDirection(x, y, _destX2, _destY2); + Direction dir = makeDirection(x, y, x2, y2); - _rembBitmapTemp = &_roomPathBitmapTemp[x / 8 + y * 80]; //esi - _rembBitmap = &_roomPathBitmap[x / 8 + y * 80]; // ebp - _rembMask = 128 >> (x & 7); // dl - _rembX = x; // eax - _rembY = y; // ebx + _rembBitmapTemp = &_roomPathBitmapTemp[x / 8 + y * 80]; + _rembBitmap = &_roomPathBitmap[x / 8 + y * 80]; + _rembMask = 128 >> (x & 7); + _rembX = x; + _rembY = y; _checkBitmapTemp = _rembBitmapTemp; _checkBitmap = _rembBitmap; @@ -3841,9 +3792,8 @@ int PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { if (_checkX == tempX && _checkY == tempY) { _coords = tempCoords; } - x = READ_UINT16(_coords); // eax now! - y = READ_UINT16(_coords + 2); // ebx now! - + x = READ_UINT16(_coords); + y = READ_UINT16(_coords + 2); } else { //error4 return 4; @@ -4074,8 +4024,7 @@ byte *PrinceEngine::makePath(int destX, int destY) { _flags->setFlagValue(Flags::MOVEDESTX, destX); _flags->setFlagValue(Flags::MOVEDESTY, destY); - //int ebp = -2; - int currX = _mainHero->_middleX; // second hero + int currX = _mainHero->_middleX; // TODO - check for second hero int currY = _mainHero->_middleY; int x1 = currX / 2; @@ -4084,28 +4033,25 @@ byte *PrinceEngine::makePath(int destX, int destY) { int y2 = destY / 2; if ((x1 != x2) && (y1 != y2)) { - //not_just_turn findPoint(x1, y1, x2, y2); - if (x2 != _fpResult.x1 || y2 != _fpResult.y1) { - // differs + if (x2 != _fpResult.x2 || y2 != _fpResult.y2) { + x2 = _fpResult.x2; + y2 = _fpResult.y2; + // TODO - change of x1, y1? if (!_flags->getFlagValue(Flags::EXACTMOVE)) { - realDestX = destX; - realDestY = destY; - _flags->setFlagValue(Flags::MOVEDESTX, destX); - _flags->setFlagValue(Flags::MOVEDESTY, destY); + realDestX = x2 * 2; + realDestY = y2 * 2; + _flags->setFlagValue(Flags::MOVEDESTX, realDestX); + _flags->setFlagValue(Flags::MOVEDESTY, realDestY); } else { - //byemove2 - //add esp,8 - //byemovemove - //eax = -1 return nullptr; } } - // not_differs + int pathLen1 = 0; int pathLen2 = 0; - int stX = x1; // stXY - int stY = y1; // stXY + 2 + int stX = x1; + int stY = y1; int sizeCoords2 = 0; if (!tracePath(x1, y1, x2, y2)) { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 7715737b1edb..b5790983b993 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -439,17 +439,8 @@ class PrinceEngine : public Engine { static const int32 kTracePts = 8000; static const int32 kPBW = kMaxPicWidth / 16; // PathBitmapWidth byte *_roomPathBitmap; // PL - Sala - byte *_roomPathBitmapTemp; // PL -SSala - - int _destX; - int _destY; - int _destX2; - int _destY2; - int _fpFlag; - int _fpX; - int _fpY; - int _fpX1; - int _fpY1; + byte *_roomPathBitmapTemp; // PL - SSala + Direction _direction; byte *_coordsBufEnd; byte *_coordsBuf; // optimal path @@ -466,17 +457,17 @@ class PrinceEngine : public Engine { byte *_directionTable; int _shanLen1; - byte *_checkBitmapTemp; //esi - byte *_checkBitmap; // ebp - int _checkMask; // dl - int _checkX; // eax - int _checkY; // ebx + byte *_checkBitmapTemp; + byte *_checkBitmap; + int _checkMask; + int _checkX; + int _checkY; - byte *_rembBitmapTemp; // esi - byte *_rembBitmap; // ebp - int _rembMask; // dl - int _rembX; // eax - int _rembY; // ebx + byte *_rembBitmapTemp; + byte *_rembBitmap; + int _rembMask; + int _rembX; + int _rembY; struct fpResult { int x1; @@ -488,8 +479,6 @@ class PrinceEngine : public Engine { bool loadPath(const char *resourceName); byte *makePath(int destX, int destY); void findPoint(int x1, int y1, int x2, int y2); - int fpGetPixelAddr(int x, int y); - int fpGetPixel(int x, int y); int getPixelAddr(byte *pathBitmap, int x, int y); static void plotTraceLine(int x, int y, int color, void *data); void specialPlotInside(int x, int y); From 5a5211fbbc3e7745f28b8ed405c1ad6cf83be9b0 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 19 Jul 2014 03:11:27 +0200 Subject: [PATCH 251/374] PRINCE: tracePath() - fix --- engines/prince/hero.cpp | 2 +- engines/prince/prince.cpp | 76 +++++++++++++++++---------------------- engines/prince/prince.h | 2 +- 3 files changed, 34 insertions(+), 46 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 60a2e5191f5b..fea5a02c2554 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -638,7 +638,7 @@ int Hero::rotateHero(int oldDirection, int newDirection) { } break; } - return -1; + error("rotateHero - wrong directions - old %d, new %d", oldDirection, newDirection); } void Hero::showHero() { diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 53a79ebf734a..6b620eba8de9 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2875,10 +2875,9 @@ void PrinceEngine::specialPlot(int x, int y) { void PrinceEngine::specialPlot2(int x, int y) { int mask = 128 >> (x & 7); - _roomPathBitmapTemp[x / 8 + y * 80] |= mask; // set point + _roomPathBitmapTemp[x / 8 + y * 80] |= mask; } -//TODO - coordsBufENd void PrinceEngine::specialPlotInside(int x, int y) { if (_coords < _coordsBufEnd) { WRITE_UINT16(_coords, x); @@ -3675,21 +3674,18 @@ int PrinceEngine::checkRightUpDir() { } } -int PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { +bool PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { for (int i = 0; i < kPathBitmapLen; i++) { _roomPathBitmapTemp[i] = 0; } if (x1 != x2 || y1 != y2) { - //Direction dir = makeDirection(x1, y1, x2, y2); // need this? if (getPixelAddr(_roomPathBitmap, x1, y1)) { if (getPixelAddr(_roomPathBitmap, x2, y2)) { _coords = _coordsBuf; - specialPlot(x1, y1); int x = x1; int y = y1; - byte *bcad; int btx, bty; @@ -3705,10 +3701,8 @@ int PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { if (!_traceLineFlag) { specialPlotInside(x2, y2); - return 0; + return true; } else if (_traceLineFlag == -1 && _traceLineLen >= 2) { - //line_ok - //plotty byte *tempCorrds = bcad; while (tempCorrds != _coords) { x = READ_UINT16(tempCorrds); @@ -3716,14 +3710,12 @@ int PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { tempCorrds += 4; specialPlot2(x, y); } - //done_plotty } else { - //bbb _coords = bcad; x = btx; y = bty; } - //same_point + Direction dir = makeDirection(x, y, x2, y2); _rembBitmapTemp = &_roomPathBitmapTemp[x / 8 + y * 80]; @@ -3778,43 +3770,38 @@ int PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { break; default: result = -1; - error("tracePath() - Wrong direction %d", dir); + error("tracePath: wrong direction %d", dir); break; } if (result) { byte *tempCoords = _coords; tempCoords -= 4; - // TODO - adress comp?? if (tempCoords > _coordsBuf) { int tempX = READ_UINT16(tempCoords); int tempY = READ_UINT16(tempCoords + 2); if (_checkX == tempX && _checkY == tempY) { _coords = tempCoords; } - x = READ_UINT16(_coords); - y = READ_UINT16(_coords + 2); + x = READ_UINT16(tempCoords); + y = READ_UINT16(tempCoords + 2); } else { - //error4 - return 4; + return false; } } else { x = _checkX; y = _checkY; } } + return true; } else { - //error2 - return 2; + error("tracePath: wrong destination point"); } } else { - //error2 - return 2; + error("tracePath: wrong start point"); } - return 0; } else { - //error1: - return 1; + error("tracePath: same point"); } } @@ -4054,7 +4041,7 @@ byte *PrinceEngine::makePath(int destX, int destY) { int stY = y1; int sizeCoords2 = 0; - if (!tracePath(x1, y1, x2, y2)) { + if (tracePath(x1, y1, x2, y2)) { allocCoords2(); approxPath(); sizeCoords2 = _coords2 - _coordsBuf2; @@ -4069,7 +4056,7 @@ byte *PrinceEngine::makePath(int destX, int destY) { _coords2 = nullptr; pathLen1 = _coords3 - _coordsBuf3; } - if (!tracePath(x2, y2, x1, y1)) { + if (tracePath(x2, y2, x1, y1)) { allocCoords2(); approxPath(); sizeCoords2 = _coords2 - _coordsBuf2; @@ -4115,22 +4102,20 @@ byte *PrinceEngine::makePath(int destX, int destY) { } _coords = _coordsBuf + sizeChoosen; } - //done_back WRITE_UINT32(_coords, 0xFFFFFFFF); freeCoords2(); freeCoords3(); scanDirections(); - // normal values: - byte *tempCoordsBuf = _coordsBuf; // esi - byte *tempCoords = _coords; // eax + byte *tempCoordsBuf = _coordsBuf; + byte *tempCoords = _coords; byte *newCoords; byte *newCoordsBegin; int newValueX = 0; int newValueY = 0; if (tempCoordsBuf != tempCoords) { int normCoordsSize = _coords - _coordsBuf + 4; - newCoords = (byte *)malloc(normCoordsSize); // edi + newCoords = (byte *)malloc(normCoordsSize); newCoordsBegin = newCoords; while (tempCoordsBuf != tempCoords) { newValueX = READ_UINT16(tempCoordsBuf); @@ -4141,25 +4126,22 @@ byte *PrinceEngine::makePath(int destX, int destY) { newCoords += 2; tempCoordsBuf += 4; } - //copy_coords_done: WRITE_UINT16(newCoords - 4, realDestX); WRITE_UINT16(newCoords - 2, realDestY); WRITE_UINT32(newCoords, 0xFFFFFFFF); newCoords += 4; _shanLen1 = (newCoords - newCoordsBegin); //_shanLen1 /= 4 ? - return newCoordsBegin; // free memory! + return newCoordsBegin; } } } - // no_path_at_all _coords = _coordsBuf; _coordsBuf = nullptr; freeCoords2(); freeCoords3(); return nullptr; } else { - //byemove _mainHero->freeOldMove(); _mainHero->_state = _mainHero->TURN; return nullptr; @@ -4167,20 +4149,26 @@ byte *PrinceEngine::makePath(int destX, int destY) { } void PrinceEngine::allocCoords2() { - _coordsBuf2 = (byte *)malloc(kTracePts * 4); - _coords2 = _coordsBuf2; + if (_coordsBuf2 == nullptr) { + _coordsBuf2 = (byte *)malloc(kTracePts * 4); + _coords2 = _coordsBuf2; + } } void PrinceEngine::freeCoords2() { - free(_coordsBuf2); - _coordsBuf2 = nullptr; - _coords2 = nullptr; + if (_coordsBuf2 != nullptr) { + free(_coordsBuf2); + _coordsBuf2 = nullptr; + _coords2 = nullptr; + } } void PrinceEngine::freeCoords3() { - free(_coordsBuf3); - _coordsBuf3 = nullptr; - _coords3 = nullptr; + if (_coordsBuf3 != nullptr) { + free(_coordsBuf3); + _coordsBuf3 = nullptr; + _coords3 = nullptr; + } } void PrinceEngine::testDrawPath() { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index b5790983b993..e6542b763d04 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -482,7 +482,7 @@ class PrinceEngine : public Engine { int getPixelAddr(byte *pathBitmap, int x, int y); static void plotTraceLine(int x, int y, int color, void *data); void specialPlotInside(int x, int y); - int tracePath(int x1, int y1, int x2, int y2); + bool tracePath(int x1, int y1, int x2, int y2); Direction makeDirection(int x1, int y1, int x2, int y2); void specialPlot(int x, int y); void specialPlot2(int x, int y); From f66a285551c2e91037b7e669facc3e2e6a5173bb Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 19 Jul 2014 18:10:11 +0200 Subject: [PATCH 252/374] PRINCE: walkTo(), moveRunHero(), O_RUNHERO, O_MOVEHERO, O_CLEARPATH, O_SETPATH, O_LOADPATH --- engines/prince/hero.cpp | 5 +++ engines/prince/hero.h | 1 + engines/prince/prince.cpp | 95 ++++++++++++++++++++++++++++----------- engines/prince/prince.h | 2 + engines/prince/script.cpp | 16 ++++--- 5 files changed, 85 insertions(+), 34 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index fea5a02c2554..edfc6916eb28 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -971,6 +971,11 @@ void Hero::freeOldMove() { _state = Hero::STAY; } +//TODO +void Hero::freeHeroAnim() { + +} + } /* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 918fa6dc1677..4dd34e864caa 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -135,6 +135,7 @@ class Hero { void specialAnim(); void getState(); void freeOldMove(); + void freeHeroAnim(); //private: PrinceEngine *_vm; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 6b620eba8de9..e08c2ebb1ae1 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1997,6 +1997,72 @@ void PrinceEngine::drawInvItems() { } } +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; + destY = mousePos.y; + _mainHero->_destDirection = 0; + } + _mainHero->_coords = makePath(destX, destY); + if (_mainHero->_coords != nullptr) { + _mainHero->_currCoords = _mainHero->_coords; + _mainHero->_dirTab = _directionTable; + _mainHero->_currDirTab = _directionTable; + _directionTable = nullptr; + _mainHero->_state = _mainHero->MOVE; + 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(x, y); + if (hero->_coords != nullptr) { + hero->_currCoords = _mainHero->_coords; + hero->_dirTab = _directionTable; + hero->_currDirTab = _directionTable; + _directionTable = nullptr; + if (runHeroFlag) { + hero->_state = _mainHero->RUN; + } else { + hero->_state = _mainHero->MOVE; + } + } + } else { + hero->freeOldMove(); + hero->_state = Hero::TURN; + } + hero->freeHeroAnim(); + hero->_visible = 1; + if (heroId == 1 && _mouseFlag) { + moveShandria(); + } + } +} + void PrinceEngine::leftMouseButton() { if (_mouseFlag) { int option = 0; @@ -2012,32 +2078,7 @@ void PrinceEngine::leftMouseButton() { } else { _optionsMob = _selectedMob; if (_optionsMob == -1) { - // @@walkto - TODO - if (_mainHero->_visible) { - //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; // second hero? - } else { - Common::Point mousePos = _system->getEventManager()->getMousePos(); - destX = mousePos.x; - destY = mousePos.y; - _mainHero->_destDirection = 0; // second hero? - } - _mainHero->_coords = makePath(destX, destY); - if (_mainHero->_coords != nullptr) { - _mainHero->_currCoords = _mainHero->_coords; - _mainHero->_dirTab = _directionTable; - _mainHero->_currDirTab = _directionTable; - _directionTable = nullptr; - _mainHero->_state = _mainHero->MOVE; - moveShandria(); - } - } + walkTo(); return; } option = 0; @@ -2051,7 +2092,7 @@ void PrinceEngine::leftMouseButton() { } if (optionEvent == -1) { if (!option) { - //@@walkto - TODO + walkTo(); return; } else { optionEvent = _script->getOptionStandardOffset(option); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index e6542b763d04..54c9e65e8945 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -496,6 +496,8 @@ class PrinceEngine : public Engine { void scanDirections(); int scanDirectionsFindNext(byte *coords, int xDiff, int yDiff); void moveShandria(); + void walkTo(); + void moveRunHero(int heroId, int x, int y, int dir, bool runHeroFlag); void testDrawPath(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index fdf1b7c8efd8..3f76b91fb721 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -950,7 +950,7 @@ void Interpreter::O_MOVEHERO() { uint16 x = readScriptFlagValue(); uint16 y = readScriptFlagValue(); uint16 dir = readScriptFlagValue(); - + _vm->moveRunHero(heroId, x, y, dir, false); debugInterpreter("O_MOVEHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); } @@ -1271,10 +1271,9 @@ void Interpreter::O_TALKBACKANIM() { void Interpreter::O_LOADPATH() { int32 offset = readScript(); - debugInterpreter("O_LOADPATH offset %d", offset); - // _currentInstruction + offset path file name ptr - // free path bitmap - // load packet path bitmap and puts in Sala + // simplifying, because used only once in Location 20 + _vm->loadPath("path2"); + debugInterpreter("O_LOADPATH - path2"); } void Interpreter::O_GETCHAR() { @@ -1525,13 +1524,15 @@ void Interpreter::O_BACKANIMRANGE() { } void Interpreter::O_CLEARPATH() { + for (int i = 0; i < _vm->kPathBitmapLen; i++) { + _vm->_roomPathBitmap[i] = 255; + } debugInterpreter("O_CLEARPATH"); - // Fill Sala with 255 } void Interpreter::O_SETPATH() { + _vm->loadPath("path"); debugInterpreter("O_SETPATH"); - // CopyPath } void Interpreter::O_GETHEROX() { @@ -1631,6 +1632,7 @@ void Interpreter::O_RUNHERO() { uint16 x = readScriptFlagValue(); uint16 y = readScriptFlagValue(); uint16 dir = readScriptFlagValue(); + _vm->moveRunHero(heroId, x, y, dir, true); debugInterpreter("O_RUNHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); } From 0415d35cdb4e10bf8ead959ed6920f1d2f3be26e Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 20 Jul 2014 01:46:47 +0200 Subject: [PATCH 253/374] PRINCE: O_WALKHERO, walkTo() update --- engines/prince/prince.cpp | 4 ++-- engines/prince/script.cpp | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index e08c2ebb1ae1..b44b136895d9 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2009,8 +2009,8 @@ void PrinceEngine::walkTo() { _mainHero->_destDirection = _mobList[_optionsMob]._examDirection; } else { Common::Point mousePos = _system->getEventManager()->getMousePos(); - destX = mousePos.x; - destY = mousePos.y; + destX = mousePos.x + _picWindowX; + destY = mousePos.y + _picWindowY; _mainHero->_destDirection = 0; } _mainHero->_coords = makePath(destX, destY); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 3f76b91fb721..3ae974e4f7fa 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -956,9 +956,19 @@ void Interpreter::O_MOVEHERO() { void Interpreter::O_WALKHERO() { uint16 heroId = readScriptFlagValue(); - + Hero *hero = nullptr; + if (!heroId) { + hero = _vm->_mainHero; + } else if (heroId == 1) { + hero = _vm->_secondHero; + } + if (hero != nullptr) { + if (hero->_state != Hero::STAY) { + _currentInstruction -= 4; + _opcodeNF = 1; + } + } debugInterpreter("O_WALKHERO %d", heroId); - _opcodeNF = 1; } void Interpreter::O_SETHERO() { From e241b6ea71c0caa073d58b3775a1e8e01aa60519 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 20 Jul 2014 16:08:08 +0200 Subject: [PATCH 254/374] PRINCE: 9997BEKA.WAV fix - not exisiting sound in data files --- engines/prince/prince.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index b44b136895d9..b57cba979ee2 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -606,6 +606,11 @@ bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamNam // 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()); _mixer->stopID(sampleSlot); From 8b9d3bedf24dffed7b65edcefe142addca70ee35 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 20 Jul 2014 16:30:20 +0200 Subject: [PATCH 255/374] PRINCE: Inventory opening - fix during talking and options menu --- engines/prince/prince.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index b57cba979ee2..771741f60e6b 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -4291,17 +4291,19 @@ void PrinceEngine::mainLoop() { _frameNr++; // inventory turning on: - Common::Point mousePos = _system->getEventManager()->getMousePos(); - if (mousePos.y < 4 && !_showInventoryFlag) { - _invCounter++; - } else { - _invCounter = 0; - } - if (_invCounter >= _invMaxCount) { - if (_flags->getFlagValue(Flags::INVALLOWED) != 1) { - // 29 - Basement, 50 - Map, 59 - Intro - if (_locationNr != 29 && _locationNr != 50 && _locationNr != 59) { - inventoryFlagChange(true); + if (!_optionsFlag && _mouseFlag) { + Common::Point mousePos = _system->getEventManager()->getMousePos(); + if (mousePos.y < 4 && !_showInventoryFlag) { + _invCounter++; + } else { + _invCounter = 0; + } + if (_invCounter >= _invMaxCount) { + if (_flags->getFlagValue(Flags::INVALLOWED) != 1) { + // 29 - Basement, 50 - Map, 59 - Intro + if (_locationNr != 29 && _locationNr != 50 && _locationNr != 59) { + inventoryFlagChange(true); + } } } } From 2749f97dd9faf8f84fafc1f4065c28bfa1dc4f3b Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 20 Jul 2014 17:38:17 +0200 Subject: [PATCH 256/374] PRINCE: freeHeroAnim(), O_SETHEROANIM() --- engines/prince/hero.cpp | 9 ++++++--- engines/prince/hero.h | 2 +- engines/prince/script.cpp | 28 +++++++++++++++++++++++++++- engines/prince/script.h | 1 + 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index edfc6916eb28..fefb2ac64dff 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -37,7 +37,7 @@ Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph) , _number(0), _visible(false), _state(MOVE), _middleX(0), _middleY(0) , _boreNum(1), _currHeight(0), _moveDelay(0), _shadMinus(0), _moveSetType(0) , _lastDirection(kHeroDirDown), _destDirection(kHeroDirDown), _talkTime(0), _boredomTime(0), _phase(0) - , _specAnim(0), _drawX(0), _drawY(0), _drawZ(0), _zoomFactor(0), _scaleValue(0) + , _specAnim(nullptr), _drawX(0), _drawY(0), _drawZ(0), _zoomFactor(0), _scaleValue(0) , _shadZoomFactor(0), _shadScaleValue(0), _shadLineLen(0), _shadDrawX(0), _shadDrawY(0) , _frameXSize(0), _frameYSize(0), _scaledFrameXSize(0), _scaledFrameYSize(0), _color(0) , _coords(nullptr), _dirTab(nullptr), _currCoords(nullptr), _currDirTab(nullptr), _step(0) @@ -52,6 +52,7 @@ Hero::~Hero() { free(_zoomBitmap); free(_shadowBitmap); delete[] _shadowLine; + freeHeroAnim(); } bool Hero::loadAnimSet(uint32 animSetNr) { @@ -971,9 +972,11 @@ void Hero::freeOldMove() { _state = Hero::STAY; } -//TODO void Hero::freeHeroAnim() { - + if (_specAnim != nullptr) { + delete _specAnim; + _specAnim = nullptr; + } } } diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 4dd34e864caa..ad6b7e907766 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -180,7 +180,7 @@ class Hero { int16 _boredomTime; // Boredom current boredom time in frames uint16 _boreNum; // Bore anim frame int16 _talkTime; // TalkTime time of talk anim - int32 _specAnim; // SpecAnim additional anim + Animation *_specAnim; // additional anim uint16 _currHeight; // height of current anim phase diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 3ae974e4f7fa..1badee0da157 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -181,6 +181,10 @@ int32 Script::getOptionStandardOffset(int option) { } } +uint8 *Script::getHeroAnimName(int offset) { + return &_data[offset]; +} + void Script::setBackAnimId(int offset, int animId) { WRITE_UINT32(&_data[offset], animId); } @@ -1167,8 +1171,30 @@ void Interpreter::O_WAITTEXT() { } void Interpreter::O_SETHEROANIM() { - uint16 hero = readScriptFlagValue(); + uint16 heroId = readScriptFlagValue(); int32 offset = readScript(); + Hero *hero = nullptr; + if (!heroId) { + hero = _vm->_mainHero; + } else { + hero = _vm->_secondHero; + } + if (hero != nullptr) { + hero->freeHeroAnim(); + if (hero ->_specAnim == nullptr) { + hero->_specAnim = new Animation(); + if (offset < 100) { + const Common::String animName = Common::String::format("AN%02d", offset); + Resource::loadResource(hero->_specAnim, animName.c_str(), true); + } else { + const Common::String animName = Common::String((const char *)_script->getHeroAnimName(offset)); + Common::String normalizedPath = lastPathComponent(animName, '\\'); + Resource::loadResource(hero->_specAnim, normalizedPath.c_str(), true); + } + hero->_phase = 0; + hero->_state = Hero::SPEC; + } + } debugInterpreter("O_SETHEROANIM hero %d, offset %d", hero, offset); } diff --git a/engines/prince/script.h b/engines/prince/script.h index 93db83ee650e..af448f004bd1 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -138,6 +138,7 @@ class Script { int32 getShadowScale(int locationNr); uint8 *getRoomOffset(int locationNr); int32 getOptionStandardOffset(int option); + uint8 *getHeroAnimName(int offset); void setBackAnimId(int offset, int animId); void setObjId(int offset, int objId); void installBackAnims(Common::Array &backAnimList, int offset); From 717597b068521a4fc6a524778782f0f6c0d08fbb Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 20 Jul 2014 17:40:39 +0200 Subject: [PATCH 257/374] PRINCE: Options menu - no option error fix --- engines/prince/prince.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 771741f60e6b..0e23fcbe4aed 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2074,7 +2074,7 @@ void PrinceEngine::leftMouseButton() { int optionEvent = -1; if (_optionsFlag) { - if (_optionEnabled < _optionsNumber) { + if (_optionEnabled < _optionsNumber && _optionEnabled != -1) { option = _optionEnabled; _optionsFlag = 0; } else { From d024d998ab5d9a1babc3f1a977dd3101515b7294 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 21 Jul 2014 16:14:42 +0200 Subject: [PATCH 258/374] PRINCE: showHero() update --- engines/prince/hero.cpp | 406 ++++++++++++++++++++-------------------- engines/prince/hero.h | 5 +- 2 files changed, 210 insertions(+), 201 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index fefb2ac64dff..a2a1bd3f85e4 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -550,23 +550,6 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { delete makeShadow; } -void Hero::showHeroAnimFrame() { - if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 1) { - if (_state == MVAN || _state == TRAN) { - _phase += 2; - } else { - _phase++; - } - } else { - if (_state == TALK) { - _phase = _moveSet[_moveSetType]->getLoopCount(); - } else { - _phase = 0; - } - } - countDrawPosition(); -} - void Hero::setScale(int8 zoomBitmapValue) { if (zoomBitmapValue == 0) { _zoomFactor = 0; @@ -593,9 +576,6 @@ void Hero::setShadowScale(int32 shadowScale) { } } -void Hero::specialAnim() { -} - int Hero::rotateHero(int oldDirection, int newDirection) { switch (oldDirection) { case kHeroDirLeft: @@ -642,6 +622,24 @@ int Hero::rotateHero(int oldDirection, int newDirection) { error("rotateHero - wrong directions - old %d, new %d", oldDirection, newDirection); } +void Hero::heroStanding() { + _phase = 0; + switch (_lastDirection) { + case kHeroDirLeft: + _moveSetType = kMove_SL; + break; + case kHeroDirRight: + _moveSetType = kMove_SR; + break; + case kHeroDirUp: + _moveSetType = kMove_SU; + break; + case kHeroDirDown: + _moveSetType = kMove_SD; + break; + } +} + void Hero::showHero() { if (_visible) { //cmp w FLAGI+NOHEROATALL,ax @@ -657,53 +655,150 @@ void Hero::showHero() { _boredomTime = 0; } - switch (_state) { - case STAY: - if (!_vm->_optionsFlag && !_vm->_interpreter->getLastOPCode()) { - _boredomTime++; - if (_boredomTime == _maxBoredom) { - _boredomTime = 0; - _state = BORE; + // TODO - change in countDrawPosition() + if (_state == SPEC) { + if (_specAnim != nullptr) { + if (_phase < _specAnim->getPhaseCount() - 1) { + _phase++; + } else { + _phase = 0; + freeHeroAnim(); + if (!_talkTime) { + _state = STAY; + } else { + _state = TALK; + } } } else { - _boredomTime = 0; + _state = STAY; } - switch (_lastDirection) { - case kHeroDirLeft: - _moveSetType = kMove_SL; - break; - case kHeroDirRight: - _moveSetType = kMove_SR; - break; - case kHeroDirUp: - _moveSetType = kMove_SU; + } + + if (_state == TALK) { + if (_talkTime) { + switch (_lastDirection) { + case kHeroDirLeft: + _moveSetType = kMove_TL; + break; + case kHeroDirRight: + _moveSetType = kMove_TR; + break; + case kHeroDirUp: + _moveSetType = kMove_TU; + break; + case kHeroDirDown: + _moveSetType = kMove_TD; + break; + } + if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 1) { + _phase++; + } else { + _phase = _moveSet[_moveSetType]->getLoopCount(); + } + } else { + _state = STAY; + } + } + + if (_state == BORE) { + switch (_boreNum) { + case 0: + _moveSetType = kMove_BORED1; break; - case kHeroDirDown: - _moveSetType = kMove_SD; + case 1: + _moveSetType = kMove_BORED2; break; } - break; - case TURN: - if (_destDirection) { - if (_lastDirection == _destDirection) { - _state = STAY; + if (_moveSet[_moveSetType] != nullptr) { + if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 1) { + _phase++; } else { _phase = 0; - int rotateDir = rotateHero(_lastDirection, _destDirection); - _lastDirection = _destDirection; - if (rotateDir) { - _turnAnim = rotateDir; - _state = TRAN; + _lastDirection = kHeroDirDown; + _state = STAY; + } + } else { + _state = STAY; + } + } + + if (_state == STAY) { + if (!_vm->_optionsFlag && !_vm->_interpreter->getLastOPCode()) { // TODO - check OPCODE after right click + _boredomTime++; + if (_boredomTime == _maxBoredom) { + _boreNum =_vm->_randomSource.getRandomNumber(1); // rand one of two 'bored' animation + _phase = 0; + _state = BORE; + if (_lastDirection == kHeroDirUp) { + _lastDirection = kHeroDirLeft; } else { - _state = STAY; + _lastDirection = kHeroDirDown; } } + } else { + _boredomTime = 0; + } + heroStanding(); + } + + if (_state == TURN) { + if (_destDirection && (_lastDirection != _destDirection)) { + _phase = 0; + int rotateDir = rotateHero(_lastDirection, _destDirection); + _lastDirection = _destDirection; + if (rotateDir) { + _turnAnim = rotateDir; + _state = TRAN; + } else { + _state = STAY; + heroStanding(); + } } else { _state = STAY; + heroStanding(); } - break; - case MOVE: - int x, y, dir, oldMiddleX, oldMiddleY, dX, dY; + } + + // TODO - change in countDrawPosition() + if (_state == TRAN) { + if (_moveSet[_turnAnim] != nullptr) { + // only in bear form + if (_phase < _moveSet[_turnAnim]->getPhaseCount() - 1) { + _phase += 2; + } else { + _state = STAY; + heroStanding(); + } + } else { + _state = STAY; + heroStanding(); + } + } + + // TODO - change in countDrawPosition() + if (_state == MVAN) { + if (_moveSet[_turnAnim] != nullptr) { + // only in bear form + if (_phase < _moveSet[_turnAnim]->getPhaseCount() - 1) { + _phase += 2; + } else { + _state = MOVE; + } + } else { + _state = MOVE; + } + } + + if (_state == DMOVE) { + _moveDelay--; + if (!_moveDelay) { + _state = MOVE; + } + } + + int x, y, dir; + + if (_state == MOVE) { //go_for_it: while (1) { if (_currCoords != nullptr) { @@ -722,24 +817,40 @@ void Hero::showHero() { } else { _turnAnim = rotateDir; _state = MVAN; - break; + if (_moveSet[_turnAnim] != nullptr) { + // only in bear form + if (_phase < _moveSet[_turnAnim]->getPhaseCount() - 1) { + _phase += 2; + break; + } else { + _state = MOVE; + continue; + } + } else { + _state = MOVE; + continue; + } } } //no_need_direction_change if (dir == kHeroDirLeft) { if (_middleX - x >= _step) { + heroMoveGotIt(x, y, dir); break; } } else if (dir == kHeroDirRight) { if (x - _middleX >= _step) { + heroMoveGotIt(x, y, dir); break; } } else if (dir == kHeroDirUp) { if (_middleY - y >= _step) { + heroMoveGotIt(x, y, dir); break; } } else if (dir == kHeroDirDown) { if (y - _middleY >= _step) { + heroMoveGotIt(x, y, dir); break; } } @@ -765,161 +876,60 @@ void Hero::showHero() { _destDirection = _lastDirection; } - switch (_lastDirection) { - case kHeroDirLeft: - _moveSetType = kMove_SL; - break; - case kHeroDirRight: - _moveSetType = kMove_SR; - break; - case kHeroDirUp: - _moveSetType = kMove_SU; - break; - case kHeroDirDown: - _moveSetType = kMove_SD; - break; - } + heroStanding(); + break; } } else { + heroStanding(); break; } } - if (_currCoords != nullptr) { - if (READ_UINT32(_currCoords) != 0xFFFFFFFF) { - oldMiddleX = _middleX; - oldMiddleY = _middleY; - _middleX = x; - _middleY = y; - selectZoom(); - - // TODO - useful or not? - dX = oldMiddleX - _middleX; - dY = oldMiddleY - _middleY; - if (dX) { - _leftRightMainDir = kHeroDirLeft; - if (dX >= 0) { - _leftRightMainDir = kHeroDirRight; - } - } - if (dY) { - _upDownMainDir = kHeroDirUp; - if (dY >= 0) { - _upDownMainDir = kHeroDirDown; - } - } + } - switch (dir) { - case kHeroDirLeft: - _moveSetType = kMove_ML; - break; - case kHeroDirRight: - _moveSetType = kMove_MR; - break; - case kHeroDirUp: - _moveSetType = kMove_MU; - break; - case kHeroDirDown: - _moveSetType = kMove_MD; - break; - } + countDrawPosition(); - //TODO - frames here? - if (_moveSet[_moveSetType] != nullptr) { - if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 1) { - if (_vm->_flags->getFlagValue(Flags::HEROFAST) || _state == RUN) { - //_phase += 2; - } else { - //_phase++; - } - } else { - //_phase = 0; - } - } else { - return; - } + } +} - _step = kStepLeftRight; - if (_moveSetType == kMove_MU || _moveSetType == kMove_MD) { - _step = kStepUpDown; - } - if (_vm->_flags->getFlagValue(Flags::HEROFAST)) { - _step *= 2.5; - } else if (_state == RUN) { - _step *= 2; - } - } - } - break; - case BORE: - //if (_direction == UP) { - switch (_boreNum) { - case 0: - _moveSetType = kMove_BORED1; - break; - case 1: - _moveSetType = kMove_BORED2; - break; - } - if (_phase == _moveSet[_moveSetType]->getPhaseCount() - 1) { - _boreNum = _vm->_randomSource.getRandomNumber(1); // rand one of two 'bored' animation - _lastDirection = kHeroDirDown; - _state = STAY; - } - break; - case SPEC: - //specialAnim(); - break; - case TALK: - if (!_talkTime) { - _state = STAY; - } - switch (_lastDirection) { - case kHeroDirLeft: - _moveSetType = kMove_TL; - break; - case kHeroDirRight: - _moveSetType = kMove_TR; - break; - case kHeroDirUp: - _moveSetType = kMove_TU; - break; - case kHeroDirDown: - _moveSetType = kMove_TD; - break; - } - break; - case MVAN: - if (_moveSet[_turnAnim] != nullptr) { - if (_phase >= _moveSet[_turnAnim]->getPhaseCount() - 1) { - _state = MOVE; - } - } else { - _state = MOVE; - } - break; - case TRAN: - if (_moveSet[_turnAnim] != nullptr) { - if (_phase >= _moveSet[_turnAnim]->getPhaseCount() - 1) { - _state = STAY; - } - } else { - _state = STAY; - } - break; - //case RUN: - //break; - case DMOVE: - _moveDelay--; - if (!_moveDelay) { - _state = MOVE; - } - break; +void Hero::heroMoveGotIt(int x, int y, int dir) { + _middleX = x; + _middleY = y; + selectZoom(); + + switch (dir) { + case kHeroDirLeft: + _moveSetType = kMove_ML; + break; + case kHeroDirRight: + _moveSetType = kMove_MR; + break; + case kHeroDirUp: + _moveSetType = kMove_MU; + break; + case kHeroDirDown: + _moveSetType = kMove_MD; + break; + } + + if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 1) { + if (_vm->_flags->getFlagValue(Flags::HEROFAST) || _state == RUN) { + _phase += 2; + } else { + _phase++; } - showHeroAnimFrame(); } else { - // no hero visible - return; + _phase = 0; + } + + _step = kStepLeftRight; + if (_moveSetType == kMove_MU || _moveSetType == kMove_MD) { + _step = kStepUpDown; + } + if (_vm->_flags->getFlagValue(Flags::HEROFAST)) { + _step *= 2.5; + } else if (_state == RUN) { + _step *= 2; } } diff --git a/engines/prince/hero.h b/engines/prince/hero.h index ad6b7e907766..693cbd81e359 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -119,7 +119,8 @@ class Hero { void setVisible(bool flag) { _visible = flag; } void showHero(); - void moveHero(); + void heroStanding(); + void heroMoveGotIt(int x, int y, int dir); int rotateHero(int oldDirection, int newDirection); void scrollHero(); void setScale(int8 zoomBitmapValue); @@ -127,12 +128,10 @@ class Hero { void selectZoom(); void countDrawPosition(); Graphics::Surface *zoomSprite(Graphics::Surface *heroFrame); - void showHeroAnimFrame(); void line(int x1, int y1, int x2, int y2); void plotPoint(int x, int y); void showHeroShadow(Graphics::Surface *heroFrame); void setShadowScale(int32 shadowScale); - void specialAnim(); void getState(); void freeOldMove(); void freeHeroAnim(); From 6a4ea9ef878773057ed7c1897ac93f7959c995e6 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 21 Jul 2014 16:36:16 +0200 Subject: [PATCH 259/374] PRINCE: Destination direction of hero movement --- engines/prince/hero.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index a2a1bd3f85e4..c52420deb698 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -872,7 +872,7 @@ void Hero::showHero() { _phase = 0; _state = TURN; - if (_destDirection) { + if (!_destDirection) { _destDirection = _lastDirection; } From 2024fea1ec3d3188ed60233a5aa80f6b2c65efb6 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 21 Jul 2014 17:20:16 +0200 Subject: [PATCH 260/374] PRINCE: showHero(), scrollHero() update --- engines/prince/hero.cpp | 39 ++++++++++++++++++++++++++------------- engines/prince/prince.cpp | 3 +++ 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index c52420deb698..afcaa551dc48 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -53,6 +53,7 @@ Hero::~Hero() { free(_shadowBitmap); delete[] _shadowLine; freeHeroAnim(); + freeOldMove(); } bool Hero::loadAnimSet(uint32 animSetNr) { @@ -641,9 +642,8 @@ void Hero::heroStanding() { } void Hero::showHero() { - if (_visible) { - //cmp w FLAGI+NOHEROATALL,ax - //jnz @@no_hero_visible + if (_visible && !_vm->_flags->getFlagValue(Flags::NOHEROATALL)) { + if (_talkTime != 0) { _talkTime--; } @@ -860,13 +860,17 @@ void Hero::showHero() { _middleY = READ_UINT16(_currCoords - 2); selectZoom(); - free(_coords); - _coords = nullptr; - _currCoords = nullptr; + if (_coords != nullptr) { + free(_coords); + _coords = nullptr; + _currCoords = nullptr; + } - free(_dirTab); - _dirTab = nullptr; - _currDirTab = nullptr; + if (_dirTab != nullptr) { + free(_dirTab); + _dirTab = nullptr; + _currDirTab = nullptr; + } _boredomTime = 0; _phase = 0; @@ -933,22 +937,31 @@ void Hero::heroMoveGotIt(int x, int y, int dir) { } } +//TODO - test this void Hero::scrollHero() { - //FLAGI+SCROLLTYPE ?? - //int scrollType = 0; + int scrollType = _vm->_flags->getFlagValue(Flags::SCROLLTYPE); int position = _middleX; + int scrollValue, scrollValue2; - /* switch (scrollType) { case 0: position = _middleX; break; case 1: + scrollValue = _vm->_flags->getFlagValue(Flags::SCROLLVALUE); + position = _vm->_normAnimList[scrollValue]._currX + _vm->_normAnimList[scrollValue]._currW / 2; break; case 2: + scrollValue = _vm->_flags->getFlagValue(Flags::SCROLLVALUE); + scrollValue2 = _vm->_flags->getFlagValue(Flags::SCROLLVALUE2); + position = scrollValue; + if (scrollValue < scrollValue2) { + _vm->_flags->setFlagValue(Flags::SCROLLVALUE, 0); + } else { + _vm->_flags->setFlagValue(Flags::SCROLLVALUE, scrollValue - scrollValue2); + } break; } - */ int locationWidth = _vm->_sceneWidth; int difference = locationWidth - _vm->kNormalWidth / 2; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 0e23fcbe4aed..dedbc0d665de 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -469,6 +469,9 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _graph->makeShadowTable(70, _graph->_shadowTable70); _graph->makeShadowTable(50, _graph->_shadowTable50); + _mainHero->freeOldMove(); + _secondHero->freeOldMove(); + return true; } From 705bac0ea53ec353d1997f7567141996141b37a8 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 21 Jul 2014 22:52:55 +0200 Subject: [PATCH 261/374] PRINCE: displayInventory() - hero path clearing, makePath() crash fix --- engines/prince/prince.cpp | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index dedbc0d665de..bf74393324b0 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2440,22 +2440,10 @@ void PrinceEngine::checkInvOptions() { } void PrinceEngine::displayInventory() { - // temp: - /* - _mainHero->_inventory.clear(); - _mainHero->_inventory.push_back(1); - _mainHero->_inventory.push_back(3); - _mainHero->_inventory.push_back(7); - _mainHero->_inventory.push_back(4); - _mainHero->_inventory.push_back(68); - - _mainHero->_inventory.push_back(29); - _mainHero->_inventory.push_back(13); - _mainHero->_inventory.push_back(44); - _mainHero->_inventory.push_back(67); - - _mainHero->_inventory.push_back(8); - */ + + _mainHero->freeOldMove(); + _secondHero->freeOldMove(); + prepareInventoryToView(); while (!shouldQuit()) { @@ -4186,7 +4174,6 @@ byte *PrinceEngine::makePath(int destX, int destY) { } } _coords = _coordsBuf; - _coordsBuf = nullptr; freeCoords2(); freeCoords3(); return nullptr; From 0415b81811ad28c2e135b97b96545073b5d8f6b2 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 22 Jul 2014 00:52:39 +0200 Subject: [PATCH 262/374] PRINCE: makePath() - crash fix, tracePath() - update --- engines/prince/prince.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index bf74393324b0..362a10654f11 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -3737,7 +3737,6 @@ bool PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { Graphics::drawLine(x, y, x2, y2, 0, &this->plotTraceLine, this); if (!_traceLineFlag) { - specialPlotInside(x2, y2); return true; } else if (_traceLineFlag == -1 && _traceLineLen >= 2) { byte *tempCorrds = bcad; @@ -4113,6 +4112,7 @@ byte *PrinceEngine::makePath(int destX, int destY) { choosenCoords = _coords3; choosenLength = pathLen2; } + if (choosenLength) { if (chosenCoordsBuf != nullptr) { int tempXBegin = READ_UINT16(chosenCoordsBuf); @@ -4125,11 +4125,11 @@ byte *PrinceEngine::makePath(int destX, int destY) { while (1) { cord = READ_UINT32(chosenCoordsBuf); WRITE_UINT32(tempCoordsBuf, cord); + tempCoordsBuf += 4; if (chosenCoordsBuf == choosenCoords) { break; } chosenCoordsBuf -= 4; - tempCoordsBuf += 4; } _coords = tempCoordsBuf; } else { From 819ca0636ff9644088837cc9f0a1049277bbfddd Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 22 Jul 2014 02:10:32 +0200 Subject: [PATCH 263/374] PRINCE: approxPath(), plotTraceLine() clean up --- engines/prince/prince.cpp | 60 ++++++++++++++++----------------------- engines/prince/prince.h | 3 +- 2 files changed, 26 insertions(+), 37 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 362a10654f11..db72e0122361 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2934,8 +2934,6 @@ void PrinceEngine::plotTraceLine(int x, int y, int color, void *data) { traceLine->_traceLineLen++; traceLine->_traceLineFlag = 0; } else { - //mov eax, OldX // last correct point - //mov ebx, OldY traceLine->_traceLineFlag = -1; } } else { @@ -3866,50 +3864,42 @@ void PrinceEngine::plotTracePoint(int x, int y, int color, void *data) { } void PrinceEngine::approxPath() { - byte *oldCoords; // like in TracePoint + byte *oldCoords; _coords2 = _coordsBuf2; - byte *tempCoordsBuf = _coordsBuf; // first point on path - esi - byte *tempCoords = _coords; // edi + byte *tempCoordsBuf = _coordsBuf; // first point on path + byte *tempCoords = _coords; int x1, y1, x2, y2; if (tempCoordsBuf != tempCoords) { tempCoords -= 4; // last point on path - // loop - while (1) { + while (tempCoordsBuf != tempCoords) { x1 = READ_UINT16(tempCoords); y1 = READ_UINT16(tempCoords + 2); - if (tempCoordsBuf != tempCoords) { - x2 = READ_UINT16(tempCoordsBuf); - y2 = READ_UINT16(tempCoordsBuf + 2); - tempCoordsBuf += 4; - //TracePoint - oldCoords = _coords2; - if (_coords2 == _coordsBuf2) { - //no_compare + x2 = READ_UINT16(tempCoordsBuf); + y2 = READ_UINT16(tempCoordsBuf + 2); + tempCoordsBuf += 4; + //TracePoint + oldCoords = _coords2; + if (_coords2 == _coordsBuf2) { + WRITE_UINT16(_coords2, x1); + WRITE_UINT16(_coords2 + 2, y1); + _coords2 += 4; + } else { + int testX = READ_UINT16(_coords2 - 4); + int testY = READ_UINT16(_coords2 - 2); + if (testX != x1 || testY != y1) { WRITE_UINT16(_coords2, x1); WRITE_UINT16(_coords2 + 2, y1); _coords2 += 4; - } else { - int testX = READ_UINT16(_coords2 - 4); - int testY = READ_UINT16(_coords2 - 2); - if (testX != x1 || testY != y1) { - //no_compare - WRITE_UINT16(_coords2, x1); - WRITE_UINT16(_coords2 + 2, y1); - _coords2 += 4; - } - } - //no_store_first - _tracePointFlag = 0; - _tracePointFirstPointFlag = true; - Graphics::drawLine(x1, y1, x2, y2, 0, &this->plotTracePoint, this); - if (!_tracePointFlag) { - tempCoords = tempCoordsBuf - 4; - tempCoordsBuf = _coordsBuf; - } else { - _coords2 = oldCoords; } + } + _tracePointFlag = 0; + _tracePointFirstPointFlag = true; + Graphics::drawLine(x1, y1, x2, y2, 0, &this->plotTracePoint, this); + if (!_tracePointFlag) { + tempCoords = tempCoordsBuf - 4; + tempCoordsBuf = _coordsBuf; } else { - break; + _coords2 = oldCoords; } } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 54c9e65e8945..2f7009517f84 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -438,10 +438,9 @@ class PrinceEngine : public Engine { static const int32 kPathBitmapLen = (kMaxPicHeight / kPathGridStep * kMaxPicWidth / kPathGridStep) / 8; static const int32 kTracePts = 8000; static const int32 kPBW = kMaxPicWidth / 16; // PathBitmapWidth + byte *_roomPathBitmap; // PL - Sala byte *_roomPathBitmapTemp; // PL - SSala - - Direction _direction; byte *_coordsBufEnd; byte *_coordsBuf; // optimal path byte *_coords; // last path point adress from coordsBuf From b6d81011e3b33235cf74e568455e97065cc9d198 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 22 Jul 2014 16:52:39 +0200 Subject: [PATCH 264/374] PRINCE: plotTracePoint(), plotTraceLine(), tracePath(), approxPath() update --- engines/prince/prince.cpp | 125 ++++++++++++++++++++++---------------- engines/prince/prince.h | 11 ++-- engines/prince/script.cpp | 6 +- 3 files changed, 82 insertions(+), 60 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index db72e0122361..a1d1f2d30c8d 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -90,10 +90,10 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _dialogWidth(600), _dialogHeight(0), _dialogLineSpace(10), _dialogColor1(220), _dialogColor2(223), _dialogFlag(false), _dialogLines(0), _dialogText(nullptr), _mouseFlag(1), _roomPathBitmap(nullptr), _roomPathBitmapTemp(nullptr), _coordsBufEnd(nullptr), _coordsBuf(nullptr), _coords(nullptr), - _traceLineLen(0), _traceLineFlag(0), _rembBitmapTemp(nullptr), _rembBitmap(nullptr), _rembMask(0), _rembX(0), _rembY(0), + _traceLineLen(0), _rembBitmapTemp(nullptr), _rembBitmap(nullptr), _rembMask(0), _rembX(0), _rembY(0), _checkBitmapTemp(nullptr), _checkBitmap(nullptr), _checkMask(0), _checkX(0), _checkY(0), _traceLineFirstPointFlag(false), _tracePointFirstPointFlag(false), _coordsBuf2(nullptr), _coords2(nullptr), _coordsBuf3(nullptr), _coords3(nullptr), - _tracePointFlag(0), _shanLen1(0), _directionTable(nullptr) { + _shanLen1(0), _directionTable(nullptr) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -1466,6 +1466,10 @@ void PrinceEngine::clearBackAnimList() { } } +void PrinceEngine::grabMap() { + //TODO +} + void PrinceEngine::initZoomIn(int slot) { //TODO } @@ -1616,8 +1620,6 @@ void PrinceEngine::drawScreen() { runDrawNodes(); - testDrawPath(); - freeDrawNodes(); if (_mainHero->_visible) { @@ -2761,6 +2763,47 @@ void PrinceEngine::freeAllNormAnims() { _normAnimList.clear(); } +// 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]; @@ -2924,25 +2967,23 @@ void PrinceEngine::specialPlotInside(int x, int y) { } } -void PrinceEngine::plotTraceLine(int x, int y, int color, void *data) { +int PrinceEngine::plotTraceLine(int x, int y, void *data) { PrinceEngine *traceLine = (PrinceEngine *)data; - if (!traceLine->_traceLineFlag) { - if (!traceLine->_traceLineFirstPointFlag) { - if (!traceLine->getPixelAddr(traceLine->_roomPathBitmapTemp, x, y)) { - if (traceLine->getPixelAddr(traceLine->_roomPathBitmap, x, y)) { - traceLine->specialPlotInside(x, y); - traceLine->_traceLineLen++; - traceLine->_traceLineFlag = 0; - } else { - traceLine->_traceLineFlag = -1; - } + 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 { - traceLine->_traceLineFlag = 1; + return -1; } } else { - traceLine->_traceLineFirstPointFlag = false; - traceLine->_traceLineFlag = 0; + return 1; } + } else { + traceLine->_traceLineFirstPointFlag = false; + return 0; } } @@ -3730,13 +3771,12 @@ bool PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { bcad = _coords; _traceLineLen = 0; - _traceLineFlag = 0; _traceLineFirstPointFlag = true; - Graphics::drawLine(x, y, x2, y2, 0, &this->plotTraceLine, this); + int drawLineFlag = drawLine(x, y, x2, y2, &this->plotTraceLine, this); - if (!_traceLineFlag) { + if (!drawLineFlag) { return true; - } else if (_traceLineFlag == -1 && _traceLineLen >= 2) { + } else if (drawLineFlag == -1 && _traceLineLen >= 2) { byte *tempCorrds = bcad; while (tempCorrds != _coords) { x = READ_UINT16(tempCorrds); @@ -3846,20 +3886,18 @@ void PrinceEngine::specialPlotInside2(int x, int y) { _coords2 += 2; } -void PrinceEngine::plotTracePoint(int x, int y, int color, void *data) { +int PrinceEngine::plotTracePoint(int x, int y, void *data) { PrinceEngine *tracePoint = (PrinceEngine *)data; - if (!tracePoint->_tracePointFlag) { - if (!tracePoint->_tracePointFirstPointFlag) { - if (tracePoint->getPixelAddr(tracePoint->_roomPathBitmap, x, y)) { - tracePoint->specialPlotInside2(x, y); - tracePoint->_tracePointFlag = 0; - } else { - tracePoint->_tracePointFlag = -1; - } + if (!tracePoint->_tracePointFirstPointFlag) { + if (tracePoint->getPixelAddr(tracePoint->_roomPathBitmap, x, y)) { + tracePoint->specialPlotInside2(x, y); + return 0; } else { - tracePoint->_tracePointFirstPointFlag = false; - tracePoint->_tracePointFlag = 0; + return -1; } + } else { + tracePoint->_tracePointFirstPointFlag = false; + return 0; } } @@ -3892,10 +3930,9 @@ void PrinceEngine::approxPath() { _coords2 += 4; } } - _tracePointFlag = 0; _tracePointFirstPointFlag = true; - Graphics::drawLine(x1, y1, x2, y2, 0, &this->plotTracePoint, this); - if (!_tracePointFlag) { + bool drawLineFlag = drawLine(x1, y1, x2, y2, &this->plotTracePoint, this); + if (!drawLineFlag) { tempCoords = tempCoordsBuf - 4; tempCoordsBuf = _coordsBuf; } else { @@ -4197,22 +4234,6 @@ void PrinceEngine::freeCoords3() { } } -void PrinceEngine::testDrawPath() { - byte *tempCoords = _mainHero->_coords; - if (tempCoords != nullptr) { - while (1) { - int flag = READ_UINT32(tempCoords); - if (flag == 0xFFFFFFFF) { - break; - } - int x = READ_UINT16(tempCoords); - int y = READ_UINT16(tempCoords + 2); - tempCoords += 4; - _graph->drawPixel(_graph->_frontScreen, x, y); - } - } -} - void PrinceEngine::mainLoop() { changeCursor(0); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 2f7009517f84..4bab84b1d0c6 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -330,6 +330,8 @@ class PrinceEngine : public Engine { void showMask(int maskNr, Graphics::Surface *originalRoomSurface); void clsMasks(); + void grabMap(); + int _selectedMob; // number of selected Mob / inventory item int _selectedItem; // number of item on mouse cursor int _selectedMode; @@ -449,9 +451,7 @@ class PrinceEngine : public Engine { byte *_coordsBuf3; byte *_coords3; int _traceLineLen; - int _traceLineFlag; // return value of plotTraceLine bool _traceLineFirstPointFlag; // if plotTraceLine after first point - int _tracePointFlag; // return value of plotTracePoint bool _tracePointFirstPointFlag; // if plotTracePoint after first point byte *_directionTable; int _shanLen1; @@ -475,11 +475,12 @@ class PrinceEngine : public Engine { int y2; } _fpResult; + int drawLine(int x0, int y0, int x1, int y1, int (*plotProc)(int, int, void *), void *data); bool loadPath(const char *resourceName); byte *makePath(int destX, int destY); void findPoint(int x1, int y1, int x2, int y2); int getPixelAddr(byte *pathBitmap, int x, int y); - static void plotTraceLine(int x, int y, int color, void *data); + static int plotTraceLine(int x, int y, void *data); void specialPlotInside(int x, int y); bool tracePath(int x1, int y1, int x2, int y2); Direction makeDirection(int x1, int y1, int x2, int y2); @@ -488,7 +489,7 @@ class PrinceEngine : public Engine { void allocCoords2(); void freeCoords2(); void freeCoords3(); - static void plotTracePoint(int x, int y, int color, void *data); + static int plotTracePoint(int x, int y, void *data); void specialPlotInside2(int x, int y); void approxPath(); void freeDirectionTable(); @@ -498,8 +499,6 @@ class PrinceEngine : public Engine { void walkTo(); void moveRunHero(int heroId, int x, int y, int dir, bool runHeroFlag); - void testDrawPath(); - int leftDownDir(); int leftDir(); int leftUpDir(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 1badee0da157..f5b38cbe47d9 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -516,7 +516,7 @@ void Interpreter::O_WAITFOREVER() { _vm->changeCursor(_vm->_currentPointerNumber); _opcodeNF = 1; _currentInstruction -= 2; - debugInterpreter("O_WAITFOREVER"); + //debugInterpreter("O_WAITFOREVER"); } void Interpreter::O_BLACKPALETTE() { @@ -1306,7 +1306,8 @@ void Interpreter::O_TALKBACKANIM() { } void Interpreter::O_LOADPATH() { - int32 offset = readScript(); + readScript(); + //int32 offset = readScript(); // simplifying, because used only once in Location 20 _vm->loadPath("path2"); debugInterpreter("O_LOADPATH - path2"); @@ -1744,6 +1745,7 @@ void Interpreter::O_HEROCOLOR() { } void Interpreter::O_GRABMAPA() { + _vm->grabMap(); debugInterpreter("O_GRABMAPA"); } From 2ffc9e15239140f256a8b6a3c6fffdc134ffde12 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 23 Jul 2014 01:24:57 +0200 Subject: [PATCH 265/374] PRINCE: Map location update --- engines/prince/debugger.cpp | 10 +++++++--- engines/prince/graphics.cpp | 4 ++++ engines/prince/graphics.h | 1 + engines/prince/object.cpp | 7 ++----- engines/prince/prince.cpp | 12 ++++++++++-- 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/engines/prince/debugger.cpp b/engines/prince/debugger.cpp index 445d5ecfc46d..cf74b7b423c0 100644 --- a/engines/prince/debugger.cpp +++ b/engines/prince/debugger.cpp @@ -160,9 +160,13 @@ bool Debugger::Cmd_AddItem(int argc, const char **argv) { DebugPrintf("Usage: %s \n", argv[0]); return true; } - - int itemId = strToInt(argv[1]); - _vm->addInv(0, itemId, true); + if (!strcmp(argv[1], "map")) { + _vm->addInv(0, 29, true); + _vm->_flags->setFlagValue(Flags::MapaUsable, 1); + } else { + int itemId = strToInt(argv[1]); + _vm->addInv(0, itemId, true); + } return true; } diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index d89b9bc048c4..9b8c8746426b 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -39,6 +39,8 @@ GraphicsMan::GraphicsMan(PrinceEngine *vm) _frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); _screenForInventory = new Graphics::Surface(); _screenForInventory->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); + _mapScreen = new Graphics::Surface(); + _mapScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); _shadowTable70 = new byte[256]; _shadowTable50 = new byte[256]; } @@ -48,6 +50,8 @@ GraphicsMan::~GraphicsMan() { delete _frontScreen; _screenForInventory->free(); delete _screenForInventory; + _mapScreen->free(); + delete _mapScreen; delete[] _shadowTable70; delete[] _shadowTable50; } diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index 266177e229c2..e5d0ea99adcb 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -57,6 +57,7 @@ class GraphicsMan { Graphics::Surface *_frontScreen; Graphics::Surface *_screenForInventory; + Graphics::Surface *_mapScreen; const Graphics::Surface *_roomBackground; byte *_shadowTable70; diff --git a/engines/prince/object.cpp b/engines/prince/object.cpp index b7ff18c46cb3..df241a0dafa0 100644 --- a/engines/prince/object.cpp +++ b/engines/prince/object.cpp @@ -67,12 +67,9 @@ 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) { - //error("Can't load %s", obStreamName.c_str()); - return false; + if (obStream) { + loadSurface(*obStream); } - - loadSurface(*obStream); delete obStream; _mask = stream.readUint16LE(); diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index a1d1f2d30c8d..50766037fd39 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1467,7 +1467,10 @@ void PrinceEngine::clearBackAnimList() { } void PrinceEngine::grabMap() { - //TODO + _graph->_frontScreen->copyFrom(*_roomBmp->getSurface()); + showObjects(); + runDrawNodes(); + _graph->_mapScreen->copyFrom(*_graph->_frontScreen); } void PrinceEngine::initZoomIn(int slot) { @@ -1571,7 +1574,12 @@ void PrinceEngine::freeDrawNodes() { void PrinceEngine::drawScreen() { if (!_showInventoryFlag || _inventoryBackgroundRemember) { - const Graphics::Surface *roomSurface = _roomBmp->getSurface(); + 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)); From f81a6b47fdefb1ecd0862f234ef77a1cc7235ca9 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 23 Jul 2014 02:31:50 +0200 Subject: [PATCH 266/374] PRINCE: makePath() update --- engines/prince/prince.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 50766037fd39..11c2e810c136 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -4092,10 +4092,13 @@ byte *PrinceEngine::makePath(int destX, int destY) { if ((x1 != x2) && (y1 != y2)) { findPoint(x1, y1, x2, y2); + if (x1 != _fpResult.x1 || y1 != _fpResult.y1) { + x1 = _fpResult.x1; + y1 = _fpResult.y1; + } if (x2 != _fpResult.x2 || y2 != _fpResult.y2) { x2 = _fpResult.x2; y2 = _fpResult.y2; - // TODO - change of x1, y1? if (!_flags->getFlagValue(Flags::EXACTMOVE)) { realDestX = x2 * 2; realDestY = y2 * 2; From d7ad1b0c14af14500e0e35c447ecd579414e9203 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 23 Jul 2014 02:32:40 +0200 Subject: [PATCH 267/374] PRINCE: O_PUTBACKANIM() fix --- engines/prince/script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index f5b38cbe47d9..6e74b353f58c 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -649,7 +649,7 @@ void Interpreter::O_PUTBACKANIM() { int offset = room->_backAnim + slot * 4; _vm->_script->setBackAnimId(offset, animId); if (_vm->_locationNr == roomId) { - _vm->_script->installBackAnims(_vm->_backAnimList, offset); + _vm->_script->installSingleBackAnim(_vm->_backAnimList, slot, offset); } delete room; debugInterpreter("O_PUTBACKANIM roomId %d, slot %d, animId %d", roomId, slot, animId); From 275bc26c4bf74b19d6bf20ad51f7c70c3e7283f0 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 23 Jul 2014 15:07:54 +0200 Subject: [PATCH 268/374] PRINCE: O_PUSHSTRING, O_POPSTRING --- engines/prince/script.cpp | 14 ++++++-------- engines/prince/script.h | 5 +++++ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 6e74b353f58c..a0ee5bd3b463 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1606,19 +1606,17 @@ void Interpreter::O_GETHEROD() { } void Interpreter::O_PUSHSTRING() { + _stringStack.string = _string; + _stringStack.dialogData = _vm->_dialogData; + _stringStack.currentString = _currentString; debugInterpreter("O_PUSHSTRING"); - // push on the stack - // _currentString - // _dialogData - // _string } void Interpreter::O_POPSTRING() { + _string = _stringStack.string; + _vm->_dialogData = _stringStack.dialogData; + _currentString = _stringStack.currentString; debugInterpreter("O_POPSTRING"); - // pop from the stack - // _currentString - // _dialogData - // _string } void Interpreter::O_SETFGCODE() { diff --git a/engines/prince/script.h b/engines/prince/script.h index af448f004bd1..80afe52cb648 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -215,6 +215,11 @@ class Interpreter { static const uint32 _STACK_SIZE = 500; uint32 _stack[_STACK_SIZE]; + struct stringStack { + byte *string; + byte *dialogData; + uint32 currentString; + } _stringStack; uint8 _stacktop; //uint8 _savedStacktop; uint32 _waitFlag; From bcba6f552778f4cb132a09c57286071655056511 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 23 Jul 2014 16:11:51 +0200 Subject: [PATCH 269/374] PRINCE: Position of texts in wider locations - fix --- engines/prince/prince.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 11c2e810c136..767ef8652a14 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1083,6 +1083,9 @@ void PrinceEngine::showTexts(Graphics::Surface *screen) { continue; } + int x = text._x - _picWindowX; + int y = text._y - _picWindowY; + Common::Array lines; _font->wordWrapText(text._str, _graph->_frontScreen->w, lines); @@ -1095,25 +1098,25 @@ void PrinceEngine::showTexts(Graphics::Surface *screen) { } int leftBorderText = 6; - if (text._x + wideLine / 2 > kNormalWidth - leftBorderText) { - text._x = kNormalWidth - leftBorderText - wideLine / 2; + if (x + wideLine / 2 > kNormalWidth - leftBorderText) { + x = kNormalWidth - leftBorderText - wideLine / 2; } - if (text._x - wideLine / 2 < leftBorderText) { - text._x = leftBorderText + wideLine / 2; + if (x - wideLine / 2 < leftBorderText) { + x = leftBorderText + wideLine / 2; } int textSkip = 2; for (uint i = 0; i < lines.size(); i++) { - int x = text._x - getTextWidth(lines[i].c_str()) / 2; - int y = text._y - 10 - (lines.size() - i) * (_font->getFontHeight() - textSkip); - if (x < 0) { + int drawX = x - getTextWidth(lines[i].c_str()) / 2; + int drawY = y - 10 - (lines.size() - i) * (_font->getFontHeight() - textSkip); + if (drawX < 0) { x = 0; } - if (y < 0) { + if (drawY < 0) { y = 0; } - _font->drawString(screen, lines[i], x, y, screen->w, text._color); + _font->drawString(screen, lines[i], drawX, drawY, screen->w, text._color); } text._time--; @@ -2699,13 +2702,13 @@ void PrinceEngine::talkHero(int slot) { text._color = 220; // TODO - test this _mainHero->_state = Hero::TALK; _mainHero->_talkTime = time; - text._x = _mainHero->_middleX - _picWindowX; + text._x = _mainHero->_middleX; text._y = _mainHero->_middleY - _mainHero->_scaledFrameYSize; } else { text._color = _flags->getFlagValue(Flags::KOLOR); // TODO - test this _secondHero->_state = Hero::TALK; _secondHero->_talkTime = time; - text._x = _secondHero->_middleX - _picWindowX; + text._x = _secondHero->_middleX; text._y = _secondHero->_middleY - _secondHero->_scaledFrameYSize; } text._time = time; // changed by SETSPECVOICE? From 933b6b7997824676208404f82d7f1d82a1dbe4b1 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 23 Jul 2014 20:41:17 +0200 Subject: [PATCH 270/374] PRINCE: Spec hero animation - getSurface(), countDrawPosition(), showHero() update --- engines/prince/hero.cpp | 97 ++++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 41 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index afcaa551dc48..9df795e69cca 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -84,9 +84,16 @@ bool Hero::loadAnimSet(uint32 animSetNr) { } Graphics::Surface *Hero::getSurface() { - if (_moveSet[_moveSetType]) { - int16 phaseFrameIndex = _moveSet[_moveSetType]->getPhaseFrameIndex(_phase); - Graphics::Surface *heroFrame = _moveSet[_moveSetType]->getFrame(phaseFrameIndex); + Animation *heroAnim = nullptr; + if (_specAnim != nullptr) { + heroAnim = _specAnim; + } else { + heroAnim = _moveSet[_moveSetType]; + } + + if (heroAnim != nullptr) { + int16 phaseFrameIndex = heroAnim->getPhaseFrameIndex(_phase); + Graphics::Surface *heroFrame = heroAnim->getFrame(phaseFrameIndex); return heroFrame; } return NULL; @@ -205,42 +212,49 @@ Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) { } void Hero::countDrawPosition() { - int16 tempMiddleY; - int16 baseX = _moveSet[_moveSetType]->getBaseX(); - int16 baseY = _moveSet[_moveSetType]->getBaseY(); - // any chance? - if (baseX == 320) { - tempMiddleY = _middleY - (baseY - 240); + Animation *heroAnim = nullptr; + if (_specAnim != nullptr) { + heroAnim = _specAnim; } else { - tempMiddleY = _middleY; - } - int phaseFrameIndex = _moveSet[_moveSetType]->getPhaseFrameIndex(_phase); - _frameXSize = _moveSet[_moveSetType]->getFrameWidth(phaseFrameIndex); - _frameYSize = _moveSet[_moveSetType]->getFrameHeight(phaseFrameIndex); - _scaledFrameXSize = getScaledValue(_frameXSize); - _scaledFrameYSize = getScaledValue(_frameYSize); - - // any use of this? - /* - if (!_moveSet[_moveSetType]->testId()) { - int diffX = _moveSet[_moveSetType]->getIdXDiff(); - int diffY = _moveSet[_moveSetType]->getIdYDiff(); + heroAnim = _moveSet[_moveSetType]; } - */ + if (heroAnim != nullptr) { + int16 tempMiddleY; + int16 baseX = heroAnim->getBaseX(); + int16 baseY = heroAnim->getBaseY(); + // any chance? + if (baseX == 320) { + tempMiddleY = _middleY - (baseY - 240); + } else { + tempMiddleY = _middleY; + } + int phaseFrameIndex = heroAnim->getPhaseFrameIndex(_phase); + _frameXSize = heroAnim->getFrameWidth(phaseFrameIndex); + _frameYSize = heroAnim->getFrameHeight(phaseFrameIndex); + _scaledFrameXSize = getScaledValue(_frameXSize); + _scaledFrameYSize = getScaledValue(_frameYSize); + + // any use of this? + if (!heroAnim->testId()) { + error("countDrawPosition - !heroAnim->testId()"); + //int diffX = heroAnim->getIdXDiff(); + //int diffY = heroAnim->getIdYDiff(); + } - if (_zoomFactor != 0) { - //notfullSize - _drawX = _middleX - _scaledFrameXSize / 2; - _drawY = tempMiddleY + 1 - _scaledFrameYSize; - _vm->checkMasks(_drawX, _drawY - 1, _scaledFrameXSize, _scaledFrameYSize, _middleY); - } else { - //fullSize - _drawX = _middleX - _frameXSize / 2; - _drawY = tempMiddleY + 1 - _frameYSize; - _vm->checkMasks(_drawX, _drawY - 1, _frameXSize, _frameYSize, _middleY); - } + if (_zoomFactor != 0) { + //notfullSize + _drawX = _middleX - _scaledFrameXSize / 2; + _drawY = tempMiddleY + 1 - _scaledFrameYSize; + _vm->checkMasks(_drawX, _drawY - 1, _scaledFrameXSize, _scaledFrameYSize, _middleY); + } else { + //fullSize + _drawX = _middleX - _frameXSize / 2; + _drawY = tempMiddleY + 1 - _frameYSize; + _vm->checkMasks(_drawX, _drawY - 1, _frameXSize, _frameYSize, _middleY); + } - _drawZ = tempMiddleY; + _drawZ = tempMiddleY; + } } void Hero::plotPoint(int x, int y) { @@ -655,7 +669,6 @@ void Hero::showHero() { _boredomTime = 0; } - // TODO - change in countDrawPosition() if (_state == SPEC) { if (_specAnim != nullptr) { if (_phase < _specAnim->getPhaseCount() - 1) { @@ -759,11 +772,11 @@ void Hero::showHero() { } } - // TODO - change in countDrawPosition() if (_state == TRAN) { if (_moveSet[_turnAnim] != nullptr) { // only in bear form - if (_phase < _moveSet[_turnAnim]->getPhaseCount() - 1) { + _moveSetType = _turnAnim; + if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 1) { _phase += 2; } else { _state = STAY; @@ -775,11 +788,11 @@ void Hero::showHero() { } } - // TODO - change in countDrawPosition() if (_state == MVAN) { if (_moveSet[_turnAnim] != nullptr) { // only in bear form - if (_phase < _moveSet[_turnAnim]->getPhaseCount() - 1) { + _moveSetType = _turnAnim; + if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 1) { _phase += 2; } else { _state = MOVE; @@ -819,10 +832,12 @@ void Hero::showHero() { _state = MVAN; if (_moveSet[_turnAnim] != nullptr) { // only in bear form - if (_phase < _moveSet[_turnAnim]->getPhaseCount() - 1) { + _moveSetType = _turnAnim; + if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 1) { _phase += 2; break; } else { + _turnAnim = 0; _state = MOVE; continue; } From 35b276397a20a169d4f9301b7bfdbcb252253710 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 23 Jul 2014 21:21:33 +0200 Subject: [PATCH 271/374] PRINCE: loadSample(), loadVoice() update --- engines/prince/prince.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 767ef8652a14..1fb323b44861 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -616,8 +616,7 @@ bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamNam debugEngine("loadSample slot %d, name %s", sampleSlot, normalizedPath.c_str()); - _mixer->stopID(sampleSlot); - _voiceStream[sampleSlot] = nullptr; + stopSample(sampleSlot); _voiceStream[sampleSlot] = SearchMan.createReadStreamForMember(normalizedPath); if (_voiceStream[sampleSlot] == nullptr) { error("Can't load sample %s to slot %d", normalizedPath.c_str(), sampleSlot); @@ -633,6 +632,7 @@ bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::Strin return false; } + stopSample(sampleSlot); _voiceStream[sampleSlot] = SearchMan.createReadStreamForMember(streamName); if (!_voiceStream[sampleSlot]) { error("Can't open %s", streamName.c_str()); From 58cb15e89276106c29f95508b2451915c716b0f7 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 23 Jul 2014 21:46:50 +0200 Subject: [PATCH 272/374] PRINCE: O_CHANGEHEROSET implementation --- engines/prince/prince.cpp | 3 --- engines/prince/script.cpp | 9 +++++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 1fb323b44861..8f1710593d1e 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -298,9 +298,6 @@ void PrinceEngine::init() { _secondHero = new Hero(this, _graph); _secondHero->_maxBoredom = 140; - _mainHero->loadAnimSet(1); - _secondHero->loadAnimSet(3); - _roomPathBitmap = (byte *)malloc(kPathBitmapLen); _roomPathBitmapTemp = (byte *)malloc(kPathBitmapLen); _coordsBuf = (byte *)malloc(kTracePts * 4); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index a0ee5bd3b463..a2f22427a728 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1390,9 +1390,14 @@ void Interpreter::O_SWAPOBJECTS() { } void Interpreter::O_CHANGEHEROSET() { - uint16 hero = readScriptFlagValue(); + uint16 heroId = readScriptFlagValue(); uint16 heroSet = readScriptFlagValue(); - debugInterpreter("O_CHANGEHEROSET hero %d, heroSet %d", hero, heroSet); + if (!heroId) { + _vm->_mainHero->loadAnimSet(heroSet); + } else if (heroId == 1) { + _vm->_secondHero->loadAnimSet(heroSet); + } + debugInterpreter("O_CHANGEHEROSET hero %d, heroSet %d", heroId, heroSet); } void Interpreter::O_ADDSTRING() { From c54699721a5c92755a51608ef478c8a049445ac6 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 24 Jul 2014 13:13:16 +0200 Subject: [PATCH 273/374] PRINCE: initZoomIn(), initZoomOut(), doZoomIn(), doZoomOut(), freeZoomObject(). showObject() update --- engines/prince/object.cpp | 8 +- engines/prince/object.h | 8 +- engines/prince/prince.cpp | 178 ++++++++++++++++++++++++++++++-------- engines/prince/prince.h | 4 + 4 files changed, 152 insertions(+), 46 deletions(-) diff --git a/engines/prince/object.cpp b/engines/prince/object.cpp index df241a0dafa0..1edabb63e07b 100644 --- a/engines/prince/object.cpp +++ b/engines/prince/object.cpp @@ -32,8 +32,8 @@ namespace Prince { -Object::Object() : _surface(NULL), _x(0), _y(0), _z(0), _mask(0), _width(0), - _height(0), _zoomInSource(0), _zoomInLen(0), _zoomInAddr(0), _zoomInTime(0) +Object::Object() : _surface(nullptr), _x(0), _y(0), _z(0), _flags(0), _width(0), + _height(0), _zoomTime(0), _zoomSurface(nullptr) { } @@ -41,7 +41,7 @@ Object::~Object() { if (_surface) { _surface->free(); delete _surface; - _surface = NULL; + _surface = nullptr; } } @@ -72,7 +72,7 @@ bool Object::loadFromStream(Common::SeekableReadStream &stream) { } delete obStream; - _mask = stream.readUint16LE(); + _flags = stream.readUint16LE(); _z = stream.readUint16LE(); stream.seek(pos + 16); diff --git a/engines/prince/object.h b/engines/prince/object.h index 3d0257cad4e1..4a67336c5f23 100644 --- a/engines/prince/object.h +++ b/engines/prince/object.h @@ -38,11 +38,9 @@ class Object { int32 _z; uint16 _width; uint16 _height; - int32 _mask; // or flags - int32 _zoomInSource; - int32 _zoomInLen; - int32 _zoomInAddr; - int32 _zoomInTime; + int32 _flags; + int32 _zoomTime; + Graphics::Surface *_zoomSurface; // Used instead of offset in setData and getData enum AttrId { diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 8f1710593d1e..b48ba7630873 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1474,58 +1474,162 @@ void PrinceEngine::grabMap() { } void PrinceEngine::initZoomIn(int slot) { - //TODO + 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->_zoomTime = 20; + } + } } void PrinceEngine::initZoomOut(int slot) { - //TODO + 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 w, rand; + for (int y = 0; y < orgSurface->h; y++) { + byte *src2 = src1; + byte *dst2 = dst1; + w = orgSurface->w - x; + src2 += x; + dst2 += x; + while (w > 0) { + rand = _randomSource.getRandomNumber(zoomInStep - 1); + if (rand < w) { + *(dst2 + rand) = *(src2 + rand); + src2 += zoomInStep; + dst2 += zoomInStep; + } else { + *(dst1 + orgSurface->pitch + rand - w) = *(src1 + orgSurface->pitch + rand - 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 w, rand; + for (int y = 0; y < orgSurface->h; y++) { + byte *dst2 = dst1; + w = orgSurface->w - x; + dst2 += x; + while (w > 0) { + rand = _randomSource.getRandomNumber(zoomInStep - 1); + if (rand < w) { + *(dst2 + rand) = 255; + dst2 += zoomInStep; + } else { + *(dst1 + orgSurface->pitch + rand - 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 != -1) { - if ((_objList[nr]->_mask & 0x8000)) { - _objList[nr]->_zoomInTime--; - if (!_objList[nr]->_zoomInTime) { - _objList[nr]->_mask &= 0x7FFF; + 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(); - // mov edx, d [esi.Obj_ZoomInAddr] + doZoomIn(nr); + objSurface = _objList[nr]->_zoomSurface; } - } - if ((_objList[nr]->_mask & 0x4000)) { - _objList[nr]->_zoomInTime--; - if (!_objList[nr]->_zoomInTime) { - _objList[nr]->_mask &= 0xBFFF; + } 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(); - // mov edx, d [esi.Obj_ZoomInAddr] + doZoomOut(nr); + objSurface = _objList[nr]->_zoomSurface; } + } else { + objSurface = _objList[nr]->getSurface(); } - Graphics::Surface *objSurface = _objList[nr]->getSurface(); - if (spriteCheck(objSurface->w, objSurface->h, _objList[nr]->_x, _objList[nr]->_y)) { - if ((_objList[i]->_mask & 0x0200) == 0) { - 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; - newDrawNode.data = nullptr; - newDrawNode.freeSurfaceSMemory = false; - newDrawNode.drawFunction = &_graph->drawTransparentDrawNode; - _drawNodeList.push_back(newDrawNode); - } else { - // showBackSprite(); + + if (objSurface != nullptr) { + if (spriteCheck(objSurface->w, objSurface->h, _objList[nr]->_x, _objList[nr]->_y)) { + if ((_objList[i]->_flags & 0x0200) == 0) { + 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; + newDrawNode.data = nullptr; + newDrawNode.freeSurfaceSMemory = false; + newDrawNode.drawFunction = &_graph->drawTransparentDrawNode; + _drawNodeList.push_back(newDrawNode); + } else { + // showBackSprite(); + error("showBackSprite() - showObjects"); + } + } + + if ((_objList[nr]->_flags & 1)) { + checkMasks(_objList[nr]->_x, _objList[nr]->_y, objSurface->w, objSurface->h, _objList[nr]->_z); } - } - if ((_objList[nr]->_mask & 1)) { - checkMasks(_objList[nr]->_x, _objList[nr]->_y, objSurface->w, objSurface->h, _objList[nr]->_z); } } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 4bab84b1d0c6..239a3b2311ca 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -432,8 +432,12 @@ class PrinceEngine : public Engine { void talkHero(int slot); void doTalkAnim(int animNumber, int slot, AnimType animType); + static const uint8 zoomInStep = 8; void initZoomIn(int slot); void initZoomOut(int slot); + void doZoomIn(int slot); + void doZoomOut(int slot); + void freeZoomObject(int slot); // Pathfinding static const int16 kPathGridStep = 2; From 8829b20ce97c44b719c0cd2063f24062449a2f67 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 24 Jul 2014 18:39:39 +0200 Subject: [PATCH 274/374] PRINCE: blackPalette(), setPalette(), O_BLACKPALETTE, O_SETUPPALETTE --- engines/prince/prince.cpp | 46 ++++++++++++++++++++++++++++++++++++++- engines/prince/prince.h | 4 ++++ engines/prince/script.cpp | 2 ++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index b48ba7630873..d6981ee90d42 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -372,6 +372,9 @@ bool AnimListItem::loadFromStream(Common::SeekableReadStream &stream) { } bool PrinceEngine::loadLocation(uint16 locationNr) { + + blackPalette(); + _flicPlayer.close(); memset(_textSlots, 0, sizeof(_textSlots)); @@ -407,7 +410,6 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { Resource::loadResource(_roomBmp, "room", true); if (_roomBmp->getSurface()) { _sceneWidth = _roomBmp->getSurface()->w; - _graph->setPalette(_roomBmp->getPalette()); } loadZoom(_mainHero->_zoomBitmap, _mainHero->kZoomBitmapLen, "zoom"); // TODO - second hero @@ -1760,6 +1762,48 @@ void PrinceEngine::drawScreen() { } } +void PrinceEngine::blackPalette() { + byte *paletteBackup = (byte *)malloc(256 * 3); + byte *blackPalette = (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++) { + blackPalette[3 * j] = paletteBackup[3 * j] * fadeStep / 4; + blackPalette[3 * j + 1] = paletteBackup[3 * j + 1] * fadeStep / 4; + blackPalette[3 * j + 2] = paletteBackup[3 * j + 2] * fadeStep / 4; + } + fadeStep--; + _graph->setPalette(blackPalette); + _system->updateScreen(); + pause(); + } + free(paletteBackup); + free(blackPalette); +} + +void PrinceEngine::setPalette() { + byte *paletteBackup; + byte *blackPalette = (byte *)malloc(256 * 3); + + int fadeStep = 0; + for (int i = 0; i <= kFadeStep; i++) { + paletteBackup = (byte *)_roomBmp->getPalette(); + for (int j = 0; j < 256; j++) { + blackPalette[3 * j] = paletteBackup[3 * j] * fadeStep / 4; + blackPalette[3 * j + 1] = paletteBackup[3 * j + 1] * fadeStep / 4; + blackPalette[3 * j + 2] = paletteBackup[3 * j + 2] * fadeStep / 4; + } + fadeStep++; + _graph->setPalette(blackPalette); + _system->updateScreen(); + pause(); + } + _graph->setPalette(paletteBackup); + free(blackPalette); +} + void PrinceEngine::pause() { uint32 currentTime = _system->getMillis(); int delay = 1000/15 - int32(_system->getMillis() - currentTime); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 239a3b2311ca..311935ffedc1 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -439,6 +439,10 @@ class PrinceEngine : public Engine { void doZoomOut(int slot); void freeZoomObject(int slot); + static const uint8 kFadeStep = 4; + void blackPalette(); + void setPalette(); + // Pathfinding static const int16 kPathGridStep = 2; static const int32 kPathBitmapLen = (kMaxPicHeight / kPathGridStep * kMaxPicWidth / kPathGridStep) / 8; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index a2f22427a728..9e380a27e8be 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -520,10 +520,12 @@ void Interpreter::O_WAITFOREVER() { } void Interpreter::O_BLACKPALETTE() { + _vm->blackPalette(); debugInterpreter("O_BLACKPALETTE"); } void Interpreter::O_SETUPPALETTE() { + _vm->setPalette(); debugInterpreter("O_SETUPPALETTE"); } From 9c9da0d65a413ad1992bf066b9df922d4b93013f Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 24 Jul 2014 18:53:55 +0200 Subject: [PATCH 275/374] PRINCE: doZoomIn(), doZoomOut() - memory leak fix --- engines/prince/object.cpp | 7 ++++++- engines/prince/prince.cpp | 10 ++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/engines/prince/object.cpp b/engines/prince/object.cpp index 1edabb63e07b..e4dece4426e6 100644 --- a/engines/prince/object.cpp +++ b/engines/prince/object.cpp @@ -38,11 +38,16 @@ Object::Object() : _surface(nullptr), _x(0), _y(0), _z(0), _flags(0), _width(0), } Object::~Object() { - if (_surface) { + if (_surface != nullptr) { _surface->free(); delete _surface; _surface = nullptr; } + if (_zoomSurface) { + _zoomSurface->free(); + delete _zoomSurface; + _zoomSurface = nullptr; + } } void Object::loadSurface(Common::SeekableReadStream &stream) { diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index d6981ee90d42..31702484d89e 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1512,7 +1512,8 @@ void PrinceEngine::doZoomIn(int slot) { byte *dst1 = (byte *)object->_zoomSurface->getBasePtr(0, 0); int x = 0; int w, rand; - for (int y = 0; y < orgSurface->h; y++) { + int surfaceHeight = orgSurface->h; + for (int y = 0; y < surfaceHeight; y++) { byte *src2 = src1; byte *dst2 = dst1; w = orgSurface->w - x; @@ -1524,7 +1525,7 @@ void PrinceEngine::doZoomIn(int slot) { *(dst2 + rand) = *(src2 + rand); src2 += zoomInStep; dst2 += zoomInStep; - } else { + } else if (y + 1 != surfaceHeight) { *(dst1 + orgSurface->pitch + rand - w) = *(src1 + orgSurface->pitch + rand - w); } w -= zoomInStep; @@ -1545,7 +1546,8 @@ void PrinceEngine::doZoomOut(int slot) { byte *dst1 = (byte *)object->_zoomSurface->getBasePtr(0, 0); int x = 0; int w, rand; - for (int y = 0; y < orgSurface->h; y++) { + int surfaceHeight = orgSurface->h; + for (int y = 0; y < surfaceHeight; y++) { byte *dst2 = dst1; w = orgSurface->w - x; dst2 += x; @@ -1554,7 +1556,7 @@ void PrinceEngine::doZoomOut(int slot) { if (rand < w) { *(dst2 + rand) = 255; dst2 += zoomInStep; - } else { + } else if (y + 1 != surfaceHeight) { *(dst1 + orgSurface->pitch + rand - w) = 255; } w -= zoomInStep; From 1f88852de548a02e42c9fc8a546fc377117f87ae Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 24 Jul 2014 18:59:26 +0200 Subject: [PATCH 276/374] PRINCE: blackPalette(), setPalette() update - allow game quit --- engines/prince/object.cpp | 2 +- engines/prince/prince.cpp | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/engines/prince/object.cpp b/engines/prince/object.cpp index e4dece4426e6..c8cdc7508315 100644 --- a/engines/prince/object.cpp +++ b/engines/prince/object.cpp @@ -43,7 +43,7 @@ Object::~Object() { delete _surface; _surface = nullptr; } - if (_zoomSurface) { + if (_zoomSurface != nullptr) { _zoomSurface->free(); delete _zoomSurface; _zoomSurface = nullptr; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 31702484d89e..90629801e9a1 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1779,6 +1779,14 @@ void PrinceEngine::blackPalette() { fadeStep--; _graph->setPalette(blackPalette); _system->updateScreen(); + Common::Event event; + Common::EventManager *eventMan = _system->getEventManager(); + eventMan->pollEvent(event); + if (shouldQuit()) { + free(paletteBackup); + free(blackPalette); + return; + } pause(); } free(paletteBackup); @@ -1800,6 +1808,14 @@ void PrinceEngine::setPalette() { fadeStep++; _graph->setPalette(blackPalette); _system->updateScreen(); + Common::Event event; + Common::EventManager *eventMan = _system->getEventManager(); + eventMan->pollEvent(event); + if (shouldQuit()) { + _graph->setPalette(paletteBackup); + free(blackPalette); + return; + } pause(); } _graph->setPalette(paletteBackup); From e6e83d993d19c2ae77c37daeefd3f4a070673182 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 24 Jul 2014 21:28:47 +0200 Subject: [PATCH 277/374] PRINCE: Fix for location 49 - after first talk with Arivald --- engines/prince/prince.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 90629801e9a1..a998181e4cb8 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -471,6 +471,8 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mainHero->freeOldMove(); _secondHero->freeOldMove(); + _mainHero->scrollHero(); + return true; } @@ -634,7 +636,7 @@ bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::Strin stopSample(sampleSlot); _voiceStream[sampleSlot] = SearchMan.createReadStreamForMember(streamName); if (!_voiceStream[sampleSlot]) { - error("Can't open %s", streamName.c_str()); + debug("Can't open %s", streamName.c_str()); return false; } @@ -1052,6 +1054,7 @@ void PrinceEngine::printAt(uint32 slot, uint8 color, char *s, uint16 x, uint16 y text._x = x; text._y = y; text._color = color; + text._time = calcText(s) * 30; } int PrinceEngine::calcText(const char *s) { From 09570f8dfa6f1ddbee324bc7a8ca30c4233972c5 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 25 Jul 2014 01:57:44 +0200 Subject: [PATCH 278/374] PRINCE: Mob priority list implementation - loadMobPriority(), checkMob() fix and update --- engines/prince/prince.cpp | 86 ++++++++++++++++++++++++++++++--------- engines/prince/prince.h | 4 +- 2 files changed, 69 insertions(+), 21 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index a998181e4cb8..5141b453be51 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -181,6 +181,8 @@ PrinceEngine::~PrinceEngine() { free(_roomPathBitmap); free(_roomPathBitmapTemp); free(_coordsBuf); + + _mobPriorityList.clear(); } GUI::Debugger *PrinceEngine::getDebugger() { @@ -422,6 +424,8 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _pscrList.clear(); Resource::loadResource(_pscrList, "pscr.lst", false); + loadMobPriority("mobpri"); + _mobList.clear(); if (getLanguage() == Common::DE_DEU) { const Common::String mobLstName = Common::String::format("mob%02d.lst", _locationNr); @@ -800,6 +804,26 @@ bool PrinceEngine::loadAllInv() { return true; } +bool PrinceEngine::loadMobPriority(const char *resourceName) { + Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); + if (!stream) { + delete stream; + return false; + } + + _mobPriorityList.clear(); + int mobId; + while (1) { + mobId = stream->readUint32LE(); + if (mobId == 0xFFFFFFFF) { + break; + } + _mobPriorityList.push_back(mobId); + } + delete stream; + return true; +} + void PrinceEngine::keyHandler(Common::Event event) { uint16 nChar = event.kbd.keycode; switch (nChar) { @@ -886,7 +910,7 @@ void PrinceEngine::keyHandler(Common::Event event) { } } -int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobList) { +int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobList, bool usePriorityList) { Common::Point mousepos = _system->getEventManager()->getMousePos(); Common::Point mousePosCamera(mousepos.x + _picWindowX, mousepos.y); @@ -894,28 +918,38 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis return -1; } - int mobNumber = 0; - for (Common::Array::const_iterator it = mobList.begin(); it != mobList.end() ; it++) { - const Mob& mob = *it; - mobNumber++; + 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) { + if (mob->_visible) { continue; } - int type = mob._type & 7; + int type = mob->_type & 7; switch (type) { case 0: case 1: //normal_mob - if (!mob._rect.contains(mousePosCamera)) { + if (!mob->_rect.contains(mousePosCamera)) { continue; } break; case 3: //mob_obj - if (mob._mask < kMaxObjects) { - int nr = _objSlot[mob._mask]; + if (mob->_mask < kMaxObjects) { + int nr = _objSlot[mob->_mask]; if (nr != -1) { Object &obj = *_objList[nr]; Common::Rect objectRect(obj._x, obj._y, obj._x + obj._width, obj._y + obj._height); @@ -933,9 +967,9 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis 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 (!_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); @@ -947,7 +981,13 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis backAnimSurface->free(); delete backAnimSurface; if (pixel != 255) { - break; + if (type == 5) { + if (mob->_rect.contains(mousePosCamera)) { + break; + } + } else { + break; + } } } } @@ -961,7 +1001,7 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis break; } - Common::String mobName = mob._name; + Common::String mobName = mob->_name; if (getLanguage() == Common::DE_DEU) { for (uint i = 0; i < mobName.size(); i++) { @@ -1009,7 +1049,11 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis _font->drawString(screen, mobName, x, y, screen->w, 216); - return mobNumber - 1; + if (usePriorityList) { + return _mobPriorityList[mobNumber]; + } else { + return mobNumber; + } } return -1; } @@ -1752,7 +1796,7 @@ void PrinceEngine::drawScreen() { if (!_inventoryBackgroundRemember && !_dialogFlag) { if (!_optionsFlag) { - _selectedMob = checkMob(_graph->_frontScreen, _mobList); + _selectedMob = checkMob(_graph->_frontScreen, _mobList, true); } showTexts(_graph->_frontScreen); checkOptions(); @@ -1797,7 +1841,7 @@ void PrinceEngine::blackPalette() { } void PrinceEngine::setPalette() { - byte *paletteBackup; + byte *paletteBackup = nullptr; byte *blackPalette = (byte *)malloc(256 * 3); int fadeStep = 0; @@ -1821,7 +1865,9 @@ void PrinceEngine::setPalette() { } pause(); } - _graph->setPalette(paletteBackup); + if (paletteBackup != nullptr) { + _graph->setPalette(paletteBackup); + } free(blackPalette); } @@ -2656,7 +2702,7 @@ void PrinceEngine::displayInventory() { showTexts(_graph->_screenForInventory); if (!_optionsFlag && _textSlots[0]._str == nullptr) { - _selectedMob = checkMob(_graph->_screenForInventory, _invMobList); + _selectedMob = checkMob(_graph->_screenForInventory, _invMobList, false); } checkInvOptions(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 311935ffedc1..3e5e1a9f789c 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -271,6 +271,7 @@ class PrinceEngine : public Engine { bool loadSample(uint32 sampleSlot, const Common::String &name); bool loadZoom(byte *zoomBitmap, uint32 dataSize, const char *resourceName); bool loadShadow(byte *shadowBitmap, uint32 dataSize, const char *resourceName1, const char *resourceName2); + bool loadMobPriority(const char *resourceName); void playSample(uint16 sampleId, uint16 loopType); void stopSample(uint16 sampleId); @@ -310,6 +311,7 @@ class PrinceEngine : public Engine { Common::Array _backAnimList; Common::Array _normAnimList; Common::Array _mobList; + Common::Array _mobPriorityList; Common::Array _maskList; Common::Array _objList; int *_objSlot; @@ -536,7 +538,7 @@ class PrinceEngine : public Engine { private: bool playNextFrame(); void keyHandler(Common::Event event); - int checkMob(Graphics::Surface *screen, Common::Array &mobList); + int checkMob(Graphics::Surface *screen, Common::Array &mobList, bool usePriorityList); void drawScreen(); void showTexts(Graphics::Surface *screen); void init(); From 92647962885ec85919a79cb1b58e01275206b495 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 25 Jul 2014 02:03:02 +0200 Subject: [PATCH 279/374] PRINCE: showHero(), heroMoveGotIt() - frames counting fix --- engines/prince/animation.cpp | 2 +- engines/prince/hero.cpp | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index adf96b5f00cf..ac0d0585e1dd 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -57,7 +57,7 @@ void Animation::clear() { } } -// AH_ID +// AH_ID - TODO - if need this fix endianess bool Animation::testId() const { char id[2]; id[0] = (char)READ_LE_UINT16(_data); diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 9df795e69cca..5edbed5df75c 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -776,7 +776,7 @@ void Hero::showHero() { if (_moveSet[_turnAnim] != nullptr) { // only in bear form _moveSetType = _turnAnim; - if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 1) { + if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 2) { _phase += 2; } else { _state = STAY; @@ -792,7 +792,7 @@ void Hero::showHero() { if (_moveSet[_turnAnim] != nullptr) { // only in bear form _moveSetType = _turnAnim; - if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 1) { + if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 2) { _phase += 2; } else { _state = MOVE; @@ -833,7 +833,7 @@ void Hero::showHero() { if (_moveSet[_turnAnim] != nullptr) { // only in bear form _moveSetType = _turnAnim; - if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 1) { + if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 2) { _phase += 2; break; } else { @@ -931,14 +931,18 @@ void Hero::heroMoveGotIt(int x, int y, int dir) { break; } - if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 1) { - if (_vm->_flags->getFlagValue(Flags::HEROFAST) || _state == RUN) { + if (_vm->_flags->getFlagValue(Flags::HEROFAST) || _state == RUN) { + if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 2) { _phase += 2; } else { - _phase++; + _phase = 0; } } else { - _phase = 0; + if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 1) { + _phase++; + } else { + _phase = 0; + } } _step = kStepLeftRight; From 98dafb866709273ffa984b6f709b94fbdab1e912 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 25 Jul 2014 14:47:19 +0200 Subject: [PATCH 280/374] PRINCE: loadVoice() update - hero talk time --- engines/prince/prince.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 5141b453be51..06462421a811 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -664,6 +664,11 @@ bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::Strin 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); _voiceStream[sampleSlot]->seek(0); From 2a1b354a6df3b3d7322561b8d62f7c5626230838 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 25 Jul 2014 15:21:31 +0200 Subject: [PATCH 281/374] PRINCE: Hero bored timer - update --- engines/prince/hero.cpp | 24 ++++++++++++++---------- engines/prince/prince.cpp | 2 ++ engines/prince/script.cpp | 4 ++++ engines/prince/script.h | 1 + 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 5edbed5df75c..a0e7533c69db 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -736,17 +736,21 @@ void Hero::showHero() { } if (_state == STAY) { - if (!_vm->_optionsFlag && !_vm->_interpreter->getLastOPCode()) { // TODO - check OPCODE after right click - _boredomTime++; - if (_boredomTime == _maxBoredom) { - _boreNum =_vm->_randomSource.getRandomNumber(1); // rand one of two 'bored' animation - _phase = 0; - _state = BORE; - if (_lastDirection == kHeroDirUp) { - _lastDirection = kHeroDirLeft; - } else { - _lastDirection = kHeroDirDown; + if (!_vm->_optionsFlag) { + if (!_vm->_interpreter->getLastOPCode() || !_vm->_interpreter->getFgOpcodePC()) { + _boredomTime++; + if (_boredomTime == _maxBoredom) { + _boreNum =_vm->_randomSource.getRandomNumber(1); // rand one of two 'bored' animation + _phase = 0; + _state = BORE; + if (_lastDirection == kHeroDirUp) { + _lastDirection = kHeroDirLeft; + } else { + _lastDirection = kHeroDirDown; + } } + } else { + _boredomTime = 0; } } else { _boredomTime = 0; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 06462421a811..b218a8fe1ec4 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2674,6 +2674,8 @@ void PrinceEngine::displayInventory() { _mainHero->freeOldMove(); _secondHero->freeOldMove(); + _interpreter->storeNewPC(0); + prepareInventoryToView(); while (!shouldQuit()) { diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 9e380a27e8be..e86c9fb68fbf 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -466,6 +466,10 @@ int Interpreter::getLastOPCode() { return _lastOpcode; } +int Interpreter::getFgOpcodePC() { + return _fgOpcodePC; +} + uint32 Interpreter::getCurrentString() { return _currentString; } diff --git a/engines/prince/script.h b/engines/prince/script.h index 80afe52cb648..04f125a8ea0e 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -187,6 +187,7 @@ class Interpreter { void step(); void storeNewPC(int opcodePC); int getLastOPCode(); + int getFgOpcodePC(); uint32 getCurrentString(); void setCurrentString(uint32 value); From e6a6753ca4bc5d80efbb888db5877e2f7ae67726 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 26 Jul 2014 00:37:08 +0200 Subject: [PATCH 282/374] PRINCE: makePath() fix --- engines/prince/prince.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index b218a8fe1ec4..bcfb0b960e61 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2275,7 +2275,7 @@ void PrinceEngine::moveRunHero(int heroId, int x, int y, int dir, bool runHeroFl if (dir) { hero->_destDirection = dir; } - if (x && y) { + if (x || y) { hero->freeOldMove(); hero->_coords = makePath(x, y); if (hero->_coords != nullptr) { @@ -2912,7 +2912,7 @@ void PrinceEngine::dialogLeftMouseButton(byte *string, int dialogSelected) { } void PrinceEngine::talkHero(int slot) { - // heroSlot = textSlot + // heroSlot = textSlot (slot 0 or 1) Text &text = _textSlots[slot]; int lines = calcText((const char *)_interpreter->getString()); int time = lines * 30; @@ -2930,7 +2930,7 @@ void PrinceEngine::talkHero(int slot) { text._x = _secondHero->_middleX; text._y = _secondHero->_middleY - _secondHero->_scaledFrameYSize; } - text._time = time; // changed by SETSPECVOICE? + text._time = time; text._str = (const char *)_interpreter->getString(); _interpreter->increaseString(); } @@ -3040,6 +3040,7 @@ int PrinceEngine::getPixelAddr(byte *pathBitmap, int x, int y) { return (mask & value); } +// TODO - check when both (start point and dest) are wrong void PrinceEngine::findPoint(int x1, int y1, int x2, int y2) { _fpResult.x1 = x1; _fpResult.y1 = y1; @@ -4312,7 +4313,7 @@ byte *PrinceEngine::makePath(int destX, int destY) { int x2 = destX / 2; int y2 = destY / 2; - if ((x1 != x2) && (y1 != y2)) { + if ((x1 != x2) || (y1 != y2)) { findPoint(x1, y1, x2, y2); if (x1 != _fpResult.x1 || y1 != _fpResult.y1) { x1 = _fpResult.x1; From 89a680e90a914ff52ec8c2b490bc4eb7420a7d93 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 26 Jul 2014 00:39:57 +0200 Subject: [PATCH 283/374] PRINCE: Script update and clean up --- engines/prince/script.cpp | 293 ++++++++++++++++++-------------------- 1 file changed, 138 insertions(+), 155 deletions(-) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index e86c9fb68fbf..ddcd37695648 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -535,19 +535,20 @@ void Interpreter::O_SETUPPALETTE() { void Interpreter::O_INITROOM() { uint16 roomId = readScriptFlagValue(); - debugInterpreter("O_INITROOM %d", roomId); _vm->loadLocation(roomId); _opcodeNF = 1; + debugInterpreter("O_INITROOM %d", roomId); } void Interpreter::O_SETSAMPLE() { uint16 sampleId = readScriptFlagValue(); int32 sampleNameOffset = readScript(); const char *sampleName = _script->getString(_currentInstruction + sampleNameOffset - 4); - debugInterpreter("O_SETSAMPLE %d %s", sampleId, sampleName); _vm->loadSample(sampleId, sampleName); + debugInterpreter("O_SETSAMPLE %d %s", sampleId, sampleName); } +// TODO void Interpreter::O_FREESAMPLE() { uint16 sample = readScriptFlagValue(); debugInterpreter("O_FREESAMPLE %d", sample); @@ -556,8 +557,8 @@ void Interpreter::O_FREESAMPLE() { void Interpreter::O_PLAYSAMPLE() { uint16 sampleId = readScriptFlagValue(); uint16 loopType = readScript(); - debugInterpreter("O_PLAYSAMPLE sampleId %d loopType %d", sampleId, loopType); _vm->playSample(sampleId, loopType); + debugInterpreter("O_PLAYSAMPLE sampleId %d loopType %d", sampleId, loopType); } void Interpreter::O_PUTOBJECT() { @@ -686,25 +687,25 @@ void Interpreter::O_CHECKBACKANIMFRAME() { debugInterpreter("O_CHECKBACKANIMFRAME slotId %d, frameId %d", slotId, frameId); } +// Not used in script void Interpreter::O_FREEALLSAMPLES() { - debugInterpreter("O_FREEALLSAMPLES"); + error("O_FREEALLSAMPLES"); } +// TODO void Interpreter::O_SETMUSIC() { uint16 musicId = readScript(); - debugInterpreter("O_SETMUSIC musicId %d", musicId); } +// TODO void Interpreter::O_STOPMUSIC() { debugInterpreter("O_STOPMUSIC"); } void Interpreter::O__WAIT() { uint16 pause = readScriptFlagValue(); - debugInterpreter("O__WAIT pause %d", pause); - if (!_waitFlag) { // set new wait flag value and continue _waitFlag = pause; @@ -712,9 +713,7 @@ void Interpreter::O__WAIT() { _currentInstruction -= 4; return; } - _waitFlag--; - if (_waitFlag > 0) { _opcodeNF = 1; _currentInstruction -= 4; @@ -722,24 +721,24 @@ void Interpreter::O__WAIT() { } } +// Not used in script void Interpreter::O_UPDATEOFF() { - debugInterpreter("O_UPDATEOFF"); - //_updateEnable = false; + error("O_UPDATEOFF"); } +// Not used in script void Interpreter::O_UPDATEON() { - debugInterpreter("O_UPDATEON"); - //_updateEnable = true; + error("O_UPDATEON"); } +// Not used in script void Interpreter::O_UPDATE () { - debugInterpreter("O_UPDATE"); - // Refresh screen + error("O_UPDATE"); } +// Not used in script void Interpreter::O_CLS() { - debugInterpreter("O_CLS"); - // do nothing + error("O_CLS"); } void Interpreter::O__CALL() { @@ -751,20 +750,19 @@ void Interpreter::O__CALL() { } void Interpreter::O_RETURN() { - // Get the return address if (_stacktop > 0) { _stacktop--; _currentInstruction = _stack[_stacktop]; debugInterpreter("O_RETURN 0x%04X", _currentInstruction); } else { - error("Return: Stack is empty"); + error("O_RETURN: Stack is empty"); } } void Interpreter::O_GO() { int32 opPC = readScript(); - debugInterpreter("O_GO 0x%04X", opPC); _currentInstruction += opPC - 4; + debugInterpreter("O_GO 0x%04X", opPC); } void Interpreter::O_BACKANIMUPDATEOFF() { @@ -783,27 +781,25 @@ void Interpreter::O_BACKANIMUPDATEON() { void Interpreter::O_CHANGECURSOR() { uint16 cursorId = readScriptFlagValue(); - debugInterpreter("O_CHANGECURSOR %x", cursorId); _vm->changeCursor(cursorId); + debugInterpreter("O_CHANGECURSOR %x", cursorId); } +// Not used in script void Interpreter::O_CHANGEANIMTYPE() { - // NOT IMPLEMENTED + error("O_CHANGEANIMTYPE"); } void Interpreter::O__SETFLAG() { Flags::Id flagId = readScriptFlagId(); uint16 value = readScriptFlagValue(); - - debugInterpreter("O__SETFLAG 0x%04X (%s) = %d", flagId, Flags::getFlagName(flagId), value); - _flags->setFlagValue((Flags::Id)(flagId), value); + debugInterpreter("O__SETFLAG 0x%04X (%s) = %d", flagId, Flags::getFlagName(flagId), value); } void Interpreter::O_COMPARE() { Flags::Id flagId = readScriptFlagId(); uint16 value = readScriptFlagValue(); - _result = _flags->getFlagValue(flagId) != value; debugInterpreter("O_COMPARE flagId 0x%04X (%s), value %d == %d (%d)", flagId, Flags::getFlagName(flagId), value, _flags->getFlagValue(flagId), _result); } @@ -813,7 +809,6 @@ void Interpreter::O_JUMPZ() { if (!_result) { _currentInstruction += offset - 4; } - debugInterpreter("O_JUMPZ result = %d, next %08x, offset 0x%08X", _result, _currentInstruction, offset); } @@ -822,10 +817,10 @@ void Interpreter::O_JUMPNZ() { if (_result) { _currentInstruction += offset - 4; } - debugInterpreter("O_JUMPNZ result = %d, next %08x, offset 0x%08X", _result, _currentInstruction, offset); } +// TODO void Interpreter::O_EXIT() { uint16 exitCode = readScriptFlagValue(); debugInterpreter("O_EXIT exitCode %d", exitCode); @@ -836,13 +831,13 @@ void Interpreter::O_EXIT() { void Interpreter::O_ADDFLAG() { Flags::Id flagId = readScriptFlagId(); uint16 value = readScriptFlagValue(); - _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) + value); - if (_flags->getFlagValue(flagId)) + if (_flags->getFlagValue(flagId)) { _result = 1; - else + } + else { _result = 0; - + } debugInterpreter("O_ADDFLAG flagId %04x (%s), value %d", flagId, Flags::getFlagName(flagId), value); } @@ -856,49 +851,43 @@ void Interpreter::O_TALKANIM() { void Interpreter::O_SUBFLAG() { Flags::Id flagId = readScriptFlagId(); uint16 value = readScriptFlagValue(); - _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) - value); - if (_flags->getFlagValue(flagId)) + if (_flags->getFlagValue(flagId)) { _result = 1; - else + } + else { _result = 0; - + } debugInterpreter("O_SUBFLAG flagId %d, value %d", flagId, value); } void Interpreter::O_SETSTRING() { int32 offset = readScript(); _currentString = offset; - if (offset >= 80000) { _string = _vm->_variaTxt->getString(offset - 80000); debugInterpreter("GetVaria %s", _string); } 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]; _string = &_vm->_talkTxt[of]; debugInterpreter("TalkTxt %d %s", of, txt); } - debugInterpreter("O_SETSTRING %04d", offset); } void Interpreter::O_ANDFLAG() { Flags::Id flagId = readScriptFlagId(); uint16 value = readScriptFlagValue(); - - debugInterpreter("O_ANDFLAG flagId %d, value %d", flagId, value); - _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) & value); - if (_flags->getFlagValue(flagId)) { _result = 1; } else { _result = 0; } + debugInterpreter("O_ANDFLAG flagId %d, value %d", flagId, value); } void Interpreter::O_GETMOBDATA() { @@ -913,16 +902,13 @@ void Interpreter::O_GETMOBDATA() { void Interpreter::O_ORFLAG() { Flags::Id flagId = readScriptFlagId(); uint16 value = readScriptFlagValue(); - - debugInterpreter("O_ORFLAG flagId %d, value %d", flagId, value); - _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) | value); - if (_flags->getFlagValue(flagId)) { _result = 1; } else { _result = 0; } + debugInterpreter("O_ORFLAG flagId %d, value %d", flagId, value); } void Interpreter::O_SETMOBDATA() { @@ -936,16 +922,13 @@ void Interpreter::O_SETMOBDATA() { void Interpreter::O_XORFLAG() { Flags::Id flagId = readScriptFlagId(); uint16 value = readScriptFlagValue(); - - debugInterpreter("O_XORFLAG flagId %d, value %d", flagId, value); - _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) ^ value); - if (_flags->getFlagValue(flagId)) { _result = 1; } else { _result = 0; } + debugInterpreter("O_XORFLAG flagId %d, value %d", flagId, value); } void Interpreter::O_GETMOBTEXT() { @@ -982,47 +965,61 @@ void Interpreter::O_WALKHERO() { } void Interpreter::O_SETHERO() { - uint16 hero = readScriptFlagValue(); + uint16 heroId = readScriptFlagValue(); int16 x = readScriptFlagValue(); int16 y = readScriptFlagValue(); uint16 dir = readScriptFlagValue(); - if (hero == 0) { - _vm->_mainHero->setPos(x, y); - _vm->_mainHero->_lastDirection = dir; - _vm->_mainHero->_state = _vm->_mainHero->STAY; - _vm->_mainHero->_moveSetType = _vm->_mainHero->_lastDirection - 1; // for countDrawPosition - _vm->_mainHero->countDrawPosition(); //setting drawX, drawY - _vm->_mainHero->_visible = 1; - } else if (hero == 1) { - _vm->_secondHero->setPos(x, y); - _vm->_secondHero->_lastDirection = dir; - _vm->_secondHero->_state = _vm->_mainHero->STAY; - _vm->_secondHero->_moveSetType = _vm->_mainHero->_lastDirection - 1; // for countDrawPosition - _vm->_secondHero->countDrawPosition(); //setting drawX, drawY - _vm->_secondHero->_visible = 1; + Hero *hero = nullptr; + if (!heroId) { + hero = _vm->_mainHero; + } else if (heroId == 1) { + hero = _vm->_secondHero; } - debugInterpreter("O_SETHERO hero %d, x %d, y %d, dir %d", hero, x, y, dir); + if (hero != nullptr) { + hero->setPos(x, y); + hero->_lastDirection = dir; + hero->_visible = 1; + hero->countDrawPosition(); + } + debugInterpreter("O_SETHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); } void Interpreter::O_HEROOFF() { uint16 heroId = readScriptFlagValue(); + Hero *hero = nullptr; + if (!heroId) { + hero = _vm->_mainHero; + } else if (heroId == 1) { + hero = _vm->_secondHero; + } + if (hero != nullptr) { + hero->setVisible(false); + } debugInterpreter("O_HEROOFF %d", heroId); - _vm->_mainHero->setVisible(false); } void Interpreter::O_HEROON() { uint16 heroId = readScriptFlagValue(); + Hero *hero = nullptr; + if (!heroId) { + hero = _vm->_mainHero; + } else if (heroId == 1) { + hero = _vm->_secondHero; + } + if (hero != nullptr) { + hero->setVisible(true); + } debugInterpreter("O_HEROON %d", heroId); - _vm->_mainHero->setVisible(true); } void Interpreter::O_CLSTEXT() { uint16 slot = readScriptFlagValue(); - debugInterpreter("O_CLSTEXT slot %d", slot); _vm->_textSlots[slot]._str = nullptr; _vm->_textSlots[slot]._time = 0; + debugInterpreter("O_CLSTEXT slot %d", slot); } +// TODO - check if need this for saving void Interpreter::O_CALLTABLE() { uint16 flag = readScript(); int32 table = readScript(); @@ -1056,45 +1053,34 @@ void Interpreter::O_REMINV() { debugInterpreter("O_REMINV hero %d, item %d", hero, item); } +// Not used in script void Interpreter::O_REPINV() { - uint16 hero = readScript(); - uint16 item1 = readScript(); - uint16 item2 = readScript(); - // shouldn't be uses - error("O_REPINV hero %d, item1 %d, item2 %d", hero, item1, item2); + error("O_REPINV"); } +// Not used in script void Interpreter::O_OBSOLETE_GETACTION() { - // shouldn't be uses error("O_OBSOLETE_GETACTION"); } +// Not used in script void Interpreter::O_ADDWALKAREA() { - uint16 x1 = readScript(); - uint16 y1 = readScript(); - uint16 x2 = readScript(); - uint16 y2 = readScript(); - // shouldn't be uses - error("O_ADDWALKAREA x1 %d, y1 %d, x2 %d, y2 %d", x1, y1, x2, y2); + error("O_ADDWALKAREA"); } +// Not used in script void Interpreter::O_REMWALKAREA() { - uint16 x1 = readScript(); - uint16 y1 = readScript(); - uint16 x2 = readScript(); - uint16 y2 = readScript(); - - // shouldn't be uses - error("O_REMWALKAREA x1 %d, y1 %d, x2 %d, y2 %d", x1, y1, x2, y2); + error("O_REMWALKAREA"); } - + + // Not used in script void Interpreter::O_RESTOREWALKAREA() { - debugInterpreter("O_RESTOREWALKAREA"); + error("O_RESTOREWALKAREA"); } void Interpreter::O_WAITFRAME() { - debugInterpreter("O_WAITFRAME"); _opcodeNF = true; + debugInterpreter("O_WAITFRAME"); } void Interpreter::O_SETFRAME() { @@ -1104,9 +1090,8 @@ void Interpreter::O_SETFRAME() { debugInterpreter("O_SETFRAME anim %d, frame %d", anim, frame); } +// Not used in script void Interpreter::O_RUNACTION() { - // It's empty in original and never used in script - // it's better to report error error("O_RUNACTION"); } @@ -1134,15 +1119,14 @@ void Interpreter::O_COMPARELO() { debugInterpreter("O_COMPARELO flag %04x - (%s), value %d, flagValue %d, result %d", flag, Flags::getFlagName(flag), value, flagValue, _result); } +// Not used in script void Interpreter::O_PRELOADSET() { - // not used in script - int32 offset = readScript(); - debugInterpreter("O_PRELOADSET offset %04x", offset); + error("O_PRELOADSET"); } +// Not used in script void Interpreter::O_FREEPRELOAD() { - // not used in script - debugInterpreter("O_FREEPRELOAD"); + error("O_FREEPRELOAD"); } void Interpreter::O_CHECKINV() { @@ -1154,8 +1138,8 @@ void Interpreter::O_CHECKINV() { void Interpreter::O_TALKHERO() { uint16 hero = readScriptFlagValue(); - debugInterpreter("O_TALKHERO hero %d", hero); _vm->talkHero(hero); + debugInterpreter("O_TALKHERO hero %d", hero); } void Interpreter::O_WAITTEXT() { @@ -1164,7 +1148,7 @@ void Interpreter::O_WAITTEXT() { if (text._time && text._str) { if (_flags->getFlagValue(Flags::ESCAPED)) { text._time = 1; - if (slot == 0) { + if (!slot) { _vm->_mainHero->_talkTime = 1; } else if (slot == 1) { _vm->_secondHero->_talkTime = 1; @@ -1174,6 +1158,7 @@ void Interpreter::O_WAITTEXT() { _currentInstruction -= 4; } } + //debugInterpreter("O_WAITTEXT slot %d", slot); } void Interpreter::O_SETHEROANIM() { @@ -1205,33 +1190,39 @@ void Interpreter::O_SETHEROANIM() { } void Interpreter::O_WAITHEROANIM() { - uint16 hero = readScriptFlagValue(); - if (hero == 0) { - if (_vm->_mainHero->_state == _vm->_mainHero->SPEC) { - _currentInstruction -= 4; - _opcodeNF = 1; - } - } else if (hero == 1) { - if (_vm->_secondHero->_state == _vm->_secondHero->SPEC) { + uint16 heroId = readScriptFlagValue(); + Hero *hero = nullptr; + if (!heroId) { + hero = _vm->_mainHero; + } else { + hero = _vm->_secondHero; + } + if (hero != nullptr) { + if (hero->_state == Hero::SPEC) { _currentInstruction -= 4; _opcodeNF = 1; } } - debugInterpreter("O_WAITHEROANIM hero %d", hero); + debugInterpreter("O_WAITHEROANIM heroId %d", heroId); } void Interpreter::O_GETHERODATA() { Flags::Id flagId = readScriptFlagId(); - uint16 hero = readScriptFlagValue(); + uint16 heroId = readScriptFlagValue(); uint16 heroOffset = readScriptFlagValue(); - if (hero == 0) { - _flags->setFlagValue(flagId, _vm->_mainHero->getData((Hero::AttrId)heroOffset)); - } else if (hero == 1) { - _flags->setFlagValue(flagId, _vm->_secondHero->getData((Hero::AttrId)heroOffset)); + Hero *hero = nullptr; + if (!heroId) { + hero = _vm->_mainHero; + } else { + hero = _vm->_secondHero; + } + if (hero != nullptr) { + _flags->setFlagValue(flagId, hero->getData((Hero::AttrId)heroOffset)); } - debugInterpreter("O_GETHERODATA flag %04x - (%s), hero %d, heroOffset %d", flagId, Flags::getFlagName(flagId), hero, heroOffset); + debugInterpreter("O_GETHERODATA flag %04x - (%s), heroId %d, heroOffset %d", flagId, Flags::getFlagName(flagId), heroId, heroOffset); } +// TODO - for location 41 (prison in hell) void Interpreter::O_GETMOUSEBUTTON() { debugInterpreter("O_GETMOUSEBUTTON"); } @@ -1311,10 +1302,9 @@ void Interpreter::O_TALKBACKANIM() { debugInterpreter("O_TALKBACKANIM animNumber %d, slot %d", animNumber, slot); } +// Simplifying, because used only once in Location 20 void Interpreter::O_LOADPATH() { readScript(); - //int32 offset = readScript(); - // simplifying, because used only once in Location 20 _vm->loadPath("path2"); debugInterpreter("O_LOADPATH - path2"); } @@ -1322,15 +1312,15 @@ void Interpreter::O_LOADPATH() { void Interpreter::O_GETCHAR() { Flags::Id flagId = readScriptFlagId(); _flags->setFlagValue(flagId, *_string); - debugInterpreter("O_GETCHAR %04X (%s) %02x", flagId, Flags::getFlagName(flagId), _flags->getFlagValue(flagId)); _string++; + debugInterpreter("O_GETCHAR %04X (%s) %02x", flagId, Flags::getFlagName(flagId), _flags->getFlagValue(flagId)); } void Interpreter::O_SETDFLAG() { Flags::Id flagId = readScriptFlagId(); int32 address = readScript(); - debugInterpreter("O_SETDFLAG 0x%04X (%s) = 0x%04X", flagId, Flags::getFlagName(flagId), _currentInstruction + address - 4); _flags->setFlagValue((Flags::Id)(flagId), _currentInstruction + address - 4); + debugInterpreter("O_SETDFLAG 0x%04X (%s) = 0x%04X", flagId, Flags::getFlagName(flagId), _currentInstruction + address - 4); } void Interpreter::O_CALLDFLAG() { @@ -1345,10 +1335,10 @@ void Interpreter::O_PRINTAT() { uint16 slot = readScriptFlagValue(); uint16 x = readScriptFlagValue(); uint16 y = readScriptFlagValue(); - debugInterpreter("O_PRINTAT slot %d, x %d, y %d", slot, x, y); uint8 color = _flags->getFlagValue(Flags::KOLOR); _vm->printAt(slot, color, (char *)_string, x, y); increaseString(); + debugInterpreter("O_PRINTAT slot %d, x %d, y %d", slot, x, y); } void Interpreter::O_ZOOMIN() { @@ -1363,12 +1353,9 @@ void Interpreter::O_ZOOMOUT() { debugInterpreter("O_ZOOMOUT slot %d", slot); } -// TODO - never used? +// Not used in script void Interpreter::O_SETSTRINGOFFSET() { - int32 offset = readScript(); - debugInterpreter("O_SETSTRINGOFFSET offset %04x", offset); - _currentString = 0; - _string = (byte *)_currentInstruction + offset; //FIXME + error("O_SETSTRINGOFFSET"); } void Interpreter::O_GETOBJDATA() { @@ -1388,11 +1375,9 @@ void Interpreter::O_SETOBJDATA() { debugInterpreter("O_SETOBJDATA obj %d, objOffset %d, value %d", obj, objOffset, value); } -// not used? +// Not used in script void Interpreter::O_SWAPOBJECTS() { - uint16 obj1 = readScriptFlagValue(); - uint16 obj2 = readScriptFlagValue(); - debugInterpreter("O_SWAPOBJECTS obj1 %d, obj2 %d", obj1, obj2); + error("O_SWAPOBJECTS"); } void Interpreter::O_CHANGEHEROSET() { @@ -1406,16 +1391,15 @@ void Interpreter::O_CHANGEHEROSET() { debugInterpreter("O_CHANGEHEROSET hero %d, heroSet %d", heroId, heroSet); } +// Not used in script void Interpreter::O_ADDSTRING() { - uint16 value = readScriptFlagValue(); - debugInterpreter("O_ADDSTRING value %d", value); - _string += value; + error("O_ADDSTRING"); } void Interpreter::O_SUBSTRING() { uint16 value = readScriptFlagValue(); - debugInterpreter("O_SUBSTRING value %d", value); _string -= value; + debugInterpreter("O_SUBSTRING value %d", value); } int Interpreter::checkSeq(byte *string) { @@ -1437,7 +1421,6 @@ int Interpreter::checkSeq(byte *string) { } void Interpreter::O_INITDIALOG() { - debugInterpreter("O_INITDIALOG"); if (_string[0] == 255) { byte *stringCurrOff = _string; byte *string = _string; @@ -1503,40 +1486,41 @@ void Interpreter::O_INITDIALOG() { } } } + debugInterpreter("O_INITDIALOG"); } void Interpreter::O_ENABLEDIALOGOPT() { uint16 opt = readScriptFlagValue(); - debugInterpreter("O_ENABLEDIALOGOPT opt %d", opt); int dialogDataValue = (int)READ_UINT32(_vm->_dialogData); dialogDataValue &= ~(1u << opt); WRITE_UINT32(_vm->_dialogData, dialogDataValue); + debugInterpreter("O_ENABLEDIALOGOPT opt %d", opt); } void Interpreter::O_DISABLEDIALOGOPT() { uint16 opt = readScriptFlagValue(); - debugInterpreter("O_DISABLEDIALOGOPT opt %d", opt); int dialogDataValue = (int)READ_UINT32(_vm->_dialogData); dialogDataValue |= (1u << opt); WRITE_UINT32(_vm->_dialogData, dialogDataValue); + debugInterpreter("O_DISABLEDIALOGOPT opt %d", opt); } void Interpreter::O_SHOWDIALOGBOX() { uint16 box = readScriptFlagValue(); - debugInterpreter("O_SHOWDIALOGBOX box %d", box); _vm->createDialogBox(box); _flags->setFlagValue(Flags::DIALINES, _vm->_dialogLines); - if (_vm->_dialogLines != 0) { + if (_vm->_dialogLines) { _vm->changeCursor(1); _vm->runDialog(); _vm->changeCursor(0); } + debugInterpreter("O_SHOWDIALOGBOX box %d", box); } void Interpreter::O_STOPSAMPLE() { uint16 slot = readScriptFlagValue(); - debugInterpreter("O_STOPSAMPLE slot %d", slot); _vm->stopSample(slot); + debugInterpreter("O_STOPSAMPLE slot %d", slot); } void Interpreter::O_BACKANIMRANGE() { @@ -1544,13 +1528,11 @@ void Interpreter::O_BACKANIMRANGE() { uint16 animId = readScript(); uint16 low = readScriptFlagValue(); uint16 high = readScriptFlagValue(); - if (animId != 0xFFFF) { if (animId & InterpreterFlags::FLAG_MASK) { animId = _flags->getFlagValue((Flags::Id)animId); } } - _result = 1; if (!_vm->_backAnimList[slotId].backAnims.empty()) { int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; @@ -1586,7 +1568,7 @@ void Interpreter::O_SETPATH() { void Interpreter::O_GETHEROX() { uint16 heroId = readScriptFlagValue(); Flags::Id flagId = readScriptFlagId(); - if (heroId == 0) { + if (!heroId) { _flags->setFlagValue(flagId, _vm->_mainHero->_middleX); } else if (heroId == 1) { _flags->setFlagValue(flagId, _vm->_secondHero->_middleX); @@ -1597,7 +1579,7 @@ void Interpreter::O_GETHEROX() { void Interpreter::O_GETHEROY() { uint16 heroId = readScriptFlagValue(); Flags::Id flagId = readScriptFlagId(); - if (heroId == 0) { + if (!heroId) { _flags->setFlagValue(flagId, _vm->_mainHero->_middleY); } else if (heroId == 1) { _flags->setFlagValue(flagId, _vm->_secondHero->_middleY); @@ -1608,7 +1590,7 @@ void Interpreter::O_GETHEROY() { void Interpreter::O_GETHEROD() { uint16 heroId = readScriptFlagValue(); Flags::Id flagId = readScriptFlagId(); - if (heroId == 0) { + if (!heroId) { _flags->setFlagValue(flagId, _vm->_mainHero->_lastDirection); } else if (heroId == 1) { _flags->setFlagValue(flagId, _vm->_secondHero->_lastDirection); @@ -1633,7 +1615,6 @@ void Interpreter::O_POPSTRING() { void Interpreter::O_SETFGCODE() { int32 offset = readScript(); _fgOpcodePC = _currentInstruction + offset - 4; - debugInterpreter("O_SETFGCODE next %08x, offset %08x", _fgOpcodePC, offset); } @@ -1694,15 +1675,13 @@ void Interpreter::O_SETBACKANIMDATA() { void Interpreter::O_VIEWFLC() { uint16 animNr = readScriptFlagValue(); - debugInterpreter("O_VIEWFLC animNr %d", animNr); _vm->loadAnim(animNr, false); + debugInterpreter("O_VIEWFLC animNr %d", animNr); } void Interpreter::O_CHECKFLCFRAME() { uint16 frameNr = readScriptFlagValue(); - debugInterpreter("O_CHECKFLCFRAME frame number %d", frameNr); - if (_vm->_flicPlayer.getCurFrame() != frameNr) { // Move instruction pointer before current instruction // must do this check once again till it's false @@ -1733,7 +1712,7 @@ void Interpreter::O_FREEFLC() { void Interpreter::O_TALKHEROSTOP() { uint16 heroId = readScriptFlagValue(); - if (heroId == 0) { + if (!heroId) { _vm->_mainHero->_state = _vm->_mainHero->STAY; } else if (heroId == 1) { _vm->_secondHero->_state = _vm->_secondHero->STAY; @@ -1745,7 +1724,7 @@ void Interpreter::O_TALKHEROSTOP() { void Interpreter::O_HEROCOLOR() { uint16 heroId = readScriptFlagValue(); uint16 color = readScriptFlagValue(); - if (heroId == 0) { + if (!heroId) { _vm->_mainHero->_color = color; } else if (heroId == 1) { _vm->_secondHero->_color = color; @@ -1830,8 +1809,8 @@ void Interpreter::O_SETVOICED() { void Interpreter::O_VIEWFLCLOOP() { uint16 value = readScriptFlagValue(); - debugInterpreter("O_VIEWFLCLOOP animId %d", value); _vm->loadAnim(value, true); + debugInterpreter("O_VIEWFLCLOOP animId %d", value); } void Interpreter::O_FLCSPEED() { @@ -1845,10 +1824,12 @@ void Interpreter::O_OPENINVENTORY() { debugInterpreter("O_OPENINVENTORY"); } +// TODO void Interpreter::O_KRZYWA() { debugInterpreter("O_KRZYWA"); } +// TODO void Interpreter::O_GETKRZYWA() { debugInterpreter("O_GETKRZYWA"); // _flags->setFlagValue(Flags::TORX1, krzywa[_krzywaIndex++]) @@ -1856,6 +1837,7 @@ void Interpreter::O_GETKRZYWA() { // Check _krzywaIndex } +// TODO void Interpreter::O_GETMOB() { Flags::Id flagId = readScriptFlagId(); uint16 mx = readScriptFlagValue(); @@ -1864,13 +1846,14 @@ void Interpreter::O_GETMOB() { // check if current mob pos = (mx, my) } +// Not used in game void Interpreter::O_INPUTLINE() { - debugInterpreter("O_INPUTLINE"); + error("O_INPUTLINE"); } - +// Not used in script void Interpreter::O_BREAK_POINT() { - debugInterpreter("O_BREAK_POINT"); + error("O_BREAK_POINT"); } Interpreter::OpcodeFunc Interpreter::_opcodes[kNumOpcodes] = { From eebedf53aa6e6b7ea298eda0afc3e6fe196416cf Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 26 Jul 2014 00:54:44 +0200 Subject: [PATCH 284/374] PRINCE: Inventory functions - update --- engines/prince/prince.cpp | 131 +++++++++++--------------------------- engines/prince/prince.h | 9 ++- engines/prince/script.cpp | 6 +- 3 files changed, 43 insertions(+), 103 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index bcfb0b960e61..dec3bc4b9c27 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1883,25 +1883,17 @@ void PrinceEngine::pause() { _system->delayMillis(delay); } -void PrinceEngine::addInv(int hero, int item, bool addItemQuiet) { - switch (hero) { - case 0: - if (_mainHero->_inventory.size() < kMaxItems) { - if (item != 0x7FFF) { - _mainHero->_inventory.push_back(item); - } - if (!addItemQuiet) { - addInvObj(); - } - _interpreter->setResult(0); - } else { - _interpreter->setResult(1); - } - break; - case 1: - if (_secondHero->_inventory.size() < kMaxItems) { +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) { - _secondHero->_inventory.push_back(item); + hero->_inventory.push_back(item); } if (!addItemQuiet) { addInvObj(); @@ -1910,44 +1902,30 @@ void PrinceEngine::addInv(int hero, int item, bool addItemQuiet) { } else { _interpreter->setResult(1); } - break; - default: - error("addInv() - wrong hero slot"); - break; } } -void PrinceEngine::remInv(int hero, int item) { - switch (hero) { - case 0: - for (uint i = 0; i < _mainHero->_inventory.size(); i++) { - if (_mainHero->_inventory[i] == item) { - _mainHero->_inventory.remove_at(i); - _interpreter->setResult(0); - return; - } - } - _interpreter->setResult(1); - break; - case 1: - for (uint i = 0; i < _secondHero->_inventory.size(); i++) { - if (_secondHero->_inventory[i] == item) { - _secondHero->_inventory.remove_at(i); +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); - break; - default: - _interpreter->setResult(1); - error("remInv() - wrong hero slot"); - break; } + _interpreter->setResult(1); } -void PrinceEngine::clearInv(int hero) { - switch (hero) { +void PrinceEngine::clearInv(int heroId) { + switch (heroId) { case 0: _mainHero->_inventory.clear(); break; @@ -1960,60 +1938,25 @@ void PrinceEngine::clearInv(int hero) { } } -void PrinceEngine::swapInv(int hero) { +void PrinceEngine::swapInv(int heroId) { Common::Array tempInv; - switch (hero) { - case 0: - for (uint i = 0; i < _mainHero->_inventory.size(); i++) { - tempInv.push_back(_mainHero->_inventory[i]); - } - for (uint i = 0; i < _mainHero->_inventory2.size(); i++) { - _mainHero->_inventory.push_back(_mainHero->_inventory2[i]); - } - for (uint i = 0; i < tempInv.size(); i++) { - _mainHero->_inventory2.push_back(tempInv[i]); - } - tempInv.clear(); - break; - case 1: - for (uint i = 0; i < _secondHero->_inventory.size(); i++) { - tempInv.push_back(_secondHero->_inventory[i]); + 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]); } - for (uint i = 0; i < _secondHero->_inventory2.size(); i++) { - _secondHero->_inventory.push_back(_secondHero->_inventory2[i]); + for (uint i = 0; i < hero->_inventory2.size(); i++) { + hero->_inventory.push_back(hero->_inventory2[i]); } for (uint i = 0; i < tempInv.size(); i++) { - _secondHero->_inventory2.push_back(tempInv[i]); + hero->_inventory2.push_back(tempInv[i]); } tempInv.clear(); - break; - default: - error("clearInv() - wrong hero slot"); - break; - } -} - -void PrinceEngine::checkInv(int hero, int item) { - switch (hero) { - case 0: - for (uint i = 0; i < _mainHero->_inventory.size(); i++) { - if (_mainHero->_inventory[i] == item) { - _interpreter->setResult(0); - } - } - _interpreter->setResult(1); - break; - case 1: - for (uint i = 0; i < _secondHero->_inventory.size(); i++) { - if (_secondHero->_inventory[i] == item) { - _interpreter->setResult(0); - } - } - _interpreter->setResult(1); - break; - default: - error("addInv() - wrong hero slot"); - break; } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 3e5e1a9f789c..ada6ddf067f3 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -394,11 +394,10 @@ class PrinceEngine : public Engine { void prepareInventoryToView(); void drawInvItems(); void displayInventory(); - void addInv(int hero, int item, bool addItemQuiet); - void remInv(int hero, int item); - void clearInv(int hero); - void swapInv(int hero); - void checkInv(int hero, int item); + void addInv(int heroId, int item, bool addItemQuiet); + void remInv(int heroId, int item); + void clearInv(int heroId); + void swapInv(int heroId); void addInvObj(); void makeInvCursor(int itemNr); void enableOptions(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index ddcd37695648..fb978c1bcb05 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1129,11 +1129,9 @@ void Interpreter::O_FREEPRELOAD() { error("O_FREEPRELOAD"); } +// Not used in script void Interpreter::O_CHECKINV() { - uint16 hero = readScriptFlagValue(); - uint16 item = readScriptFlagValue(); - _vm->checkInv(hero, item); - debugInterpreter("O_CHECKINV hero %d, item %d", hero, item); + error("O_CHECKINV"); } void Interpreter::O_TALKHERO() { From 687a16874775fc54d96991b56e8b019d1eeb9413 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 26 Jul 2014 01:51:21 +0200 Subject: [PATCH 285/374] PRINCE: Block options menu on mobs in map location --- engines/prince/prince.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index dec3bc4b9c27..a05478061626 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2491,7 +2491,7 @@ void PrinceEngine::enableOptions() { changeCursor(1); _currentPointerNumber = 1; if (_selectedMob != -1) { - //if (_mobType != 0x100) { + if (_mobList[_selectedMob]._type != 0x100) { Common::Point mousePos = _system->getEventManager()->getMousePos(); int x1 = mousePos.x - _optionsWidth / 2; int x2 = mousePos.x + _optionsWidth / 2; @@ -2513,7 +2513,7 @@ void PrinceEngine::enableOptions() { _optionsX = x1; _optionsY = y1; _optionsFlag = 1; - //} + } } } } From 97d10f94ec5f026015b9d6e06494d995d8664cc3 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 26 Jul 2014 05:33:33 +0200 Subject: [PATCH 286/374] PRINCE: Sounds and voices - fix and update --- engines/prince/prince.cpp | 68 +++++++++++++++++++++++++-------------- engines/prince/prince.h | 9 ++++-- engines/prince/script.cpp | 6 ++-- engines/prince/sound.cpp | 2 +- 4 files changed, 54 insertions(+), 31 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index a05478061626..831b44137a96 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -101,7 +101,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) DebugMan.enableDebugChannel("script"); - memset(_voiceStream, 0, sizeof(_voiceStream)); + memset(_audioStream, 0, sizeof(_audioStream)); gDebugLevel = 10; } @@ -183,6 +183,8 @@ PrinceEngine::~PrinceEngine() { free(_coordsBuf); _mobPriorityList.clear(); + + freeAllSamples(); } GUI::Debugger *PrinceEngine::getDebugger() { @@ -380,9 +382,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _flicPlayer.close(); memset(_textSlots, 0, sizeof(_textSlots)); - for(uint32 sampleId = 0; sampleId < MAX_SAMPLES; sampleId++) { - stopSample(sampleId); - } + freeAllSamples(); debugEngine("PrinceEngine::loadLocation %d", locationNr); const Common::FSNode gameDataDir(ConfMan.get("path")); @@ -590,23 +590,35 @@ bool PrinceEngine::playNextFrame() { } void PrinceEngine::playSample(uint16 sampleId, uint16 loopType) { - if (_voiceStream[sampleId]) { - + if (_audioStream[sampleId]) { if (_mixer->isSoundIDActive(sampleId)) { return; } - - Audio::AudioStream *audioStream = Audio::makeWAVStream(_voiceStream[sampleId], DisposeAfterUse::YES); - if (loopType) { - audioStream = new Audio::LoopingAudioStream((Audio::RewindableAudioStream*)audioStream, 0, DisposeAfterUse::NO); - } - _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle[sampleId], audioStream, sampleId); + _audioStream[sampleId]->rewind(); + _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle[sampleId], _audioStream[sampleId], sampleId, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO); } } void PrinceEngine::stopSample(uint16 sampleId) { _mixer->stopID(sampleId); - _voiceStream[sampleId] = nullptr; +} + +void PrinceEngine::stopAllSamples() { + _mixer->stopAll(); +} + +void PrinceEngine::freeSample(uint16 sampleId) { + if (_audioStream[sampleId] != nullptr) { + delete _audioStream[sampleId]; + _audioStream[sampleId] = nullptr; + } +} + +void PrinceEngine::freeAllSamples() { + for (int sampleId = 0; sampleId < kMaxSamples; sampleId++) { + stopSample(sampleId); + freeSample(sampleId); + } } bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamName) { @@ -622,11 +634,15 @@ bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamNam debugEngine("loadSample slot %d, name %s", sampleSlot, normalizedPath.c_str()); stopSample(sampleSlot); - _voiceStream[sampleSlot] = SearchMan.createReadStreamForMember(normalizedPath); - if (_voiceStream[sampleSlot] == nullptr) { + 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); } - return _voiceStream[sampleSlot] == nullptr; + _audioStream[sampleSlot] = Audio::makeWAVStream(sampleStream, DisposeAfterUse::NO); + delete sampleStream; + return true; } bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::String &streamName) { @@ -638,26 +654,27 @@ bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::Strin } stopSample(sampleSlot); - _voiceStream[sampleSlot] = SearchMan.createReadStreamForMember(streamName); - if (!_voiceStream[sampleSlot]) { + freeSample(sampleSlot); + Common::SeekableReadStream *sampleStream = SearchMan.createReadStreamForMember(streamName); + if (sampleStream == nullptr) { debug("Can't open %s", streamName.c_str()); return false; } - uint32 id = _voiceStream[sampleSlot]->readUint32LE(); + uint32 id = sampleStream->readUint32LE(); if (id != MKTAG('F', 'F', 'I', 'R')) { error("It's not RIFF file %s", streamName.c_str()); return false; } - _voiceStream[sampleSlot]->skip(0x20); - id = _voiceStream[sampleSlot]->readUint32LE(); + 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 = _voiceStream[sampleSlot]->readUint32LE(); + id = sampleStream->readUint32LE(); debugEngine("SetVoice slot %d time %04x", slot, id); id <<= 3; id /= 22050; @@ -671,8 +688,9 @@ bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::Strin } debugEngine("SetVoice slot %d time %04x", slot, id); - _voiceStream[sampleSlot]->seek(0); - + sampleStream->seek(SEEK_SET); + _audioStream[sampleSlot] = Audio::makeWAVStream(sampleStream, DisposeAfterUse::NO); + delete sampleStream; return true; } @@ -2619,6 +2637,8 @@ void PrinceEngine::displayInventory() { _interpreter->storeNewPC(0); + stopAllSamples(); + prepareInventoryToView(); while (!shouldQuit()) { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index ada6ddf067f3..3fd03c66d4d9 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -275,6 +275,9 @@ class PrinceEngine : public Engine { void playSample(uint16 sampleId, uint16 loopType); void stopSample(uint16 sampleId); + void stopAllSamples(); + void freeSample(uint16 sampleId); + void freeAllSamples(); void setVoice(uint16 slot, uint32 sampleSlot, uint16 flag); @@ -572,9 +575,9 @@ class PrinceEngine : public Engine { Font *_font; MusicPlayer *_midiPlayer; - static const uint32 MAX_SAMPLES = 60; - Common::SeekableReadStream *_voiceStream[MAX_SAMPLES]; - Audio::SoundHandle _soundHandle[MAX_SAMPLES]; + static const uint32 kMaxSamples = 60; + Audio::RewindableAudioStream *_audioStream[kMaxSamples]; + Audio::SoundHandle _soundHandle[kMaxSamples]; Common::Array _pscrList; Common::Array _drawNodeList; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index fb978c1bcb05..4f989a18ae5b 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -548,10 +548,10 @@ void Interpreter::O_SETSAMPLE() { debugInterpreter("O_SETSAMPLE %d %s", sampleId, sampleName); } -// TODO void Interpreter::O_FREESAMPLE() { - uint16 sample = readScriptFlagValue(); - debugInterpreter("O_FREESAMPLE %d", sample); + uint16 sampleId = readScriptFlagValue(); + _vm->freeSample(sampleId); + debugInterpreter("O_FREESAMPLE sampleId: %d", sampleId); } void Interpreter::O_PLAYSAMPLE() { diff --git a/engines/prince/sound.cpp b/engines/prince/sound.cpp index af139f708e78..9a0a33b25cad 100644 --- a/engines/prince/sound.cpp +++ b/engines/prince/sound.cpp @@ -217,6 +217,6 @@ void MusicPlayer::sendToChannel(byte channel, uint32 b) { _channelsTable[channel]->send(b); } -} // End of namespace CGE +} /* vim: set tabstop=4 expandtab!: */ From e08a59ad5361d327f5c04ede44ab8fa3da733915 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 26 Jul 2014 16:38:14 +0200 Subject: [PATCH 287/374] PRINCE: freeSample() fix --- engines/prince/prince.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 831b44137a96..5f6630f6a902 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -608,6 +608,7 @@ void PrinceEngine::stopAllSamples() { } void PrinceEngine::freeSample(uint16 sampleId) { + stopSample(sampleId); if (_audioStream[sampleId] != nullptr) { delete _audioStream[sampleId]; _audioStream[sampleId] = nullptr; @@ -616,7 +617,6 @@ void PrinceEngine::freeSample(uint16 sampleId) { void PrinceEngine::freeAllSamples() { for (int sampleId = 0; sampleId < kMaxSamples; sampleId++) { - stopSample(sampleId); freeSample(sampleId); } } @@ -633,7 +633,6 @@ bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamNam debugEngine("loadSample slot %d, name %s", sampleSlot, normalizedPath.c_str()); - stopSample(sampleSlot); freeSample(sampleSlot); Common::SeekableReadStream *sampleStream = SearchMan.createReadStreamForMember(normalizedPath); if (sampleStream == nullptr) { @@ -653,7 +652,6 @@ bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::Strin return false; } - stopSample(sampleSlot); freeSample(sampleSlot); Common::SeekableReadStream *sampleStream = SearchMan.createReadStreamForMember(streamName); if (sampleStream == nullptr) { From 7c777e755c7b34e3e5da9f5f28e081a1a478da42 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 26 Jul 2014 16:51:14 +0200 Subject: [PATCH 288/374] PRINCE: showNormAnims() fix --- engines/prince/prince.cpp | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 5f6630f6a902..d1a142fab4ed 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1412,12 +1412,6 @@ void PrinceEngine::showNormAnims() { } else { continue; } - } else { - if (anim._frame >= 1) { - anim._frame--; - } else { - anim._frame = 0; - } } } else { anim._frame++; @@ -1522,8 +1516,14 @@ void PrinceEngine::showBackAnims() { void PrinceEngine::removeSingleBackAnim(int slot) { if (!_backAnimList[slot].backAnims.empty()) { for (uint j = 0; j < _backAnimList[slot].backAnims.size(); j++) { - delete _backAnimList[slot].backAnims[j]._animData; - delete _backAnimList[slot].backAnims[j]._shadowData; + 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; @@ -2935,21 +2935,19 @@ void PrinceEngine::doTalkAnim(int animNumber, int slot, AnimType animType) { void PrinceEngine::freeNormAnim(int slot) { _normAnimList[slot]._state = 1; - delete _normAnimList[slot]._animData; - _normAnimList[slot]._animData = nullptr; - delete _normAnimList[slot]._shadowData; - _normAnimList[slot]._shadowData = nullptr; - _normAnimList[slot]._currFrame = 0; + 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++) { - if (_normAnimList[i]._animData != nullptr) { - delete _normAnimList[i]._animData; - } - if (_normAnimList[i]._shadowData != nullptr) { - delete _normAnimList[i]._shadowData; - } + freeNormAnim(i); } _normAnimList.clear(); } From 0d1b5533db2ec543f34a51b9a4b0fac0231db411 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 26 Jul 2014 19:15:20 +0200 Subject: [PATCH 289/374] PRINCE: drawScreen() update --- engines/prince/prince.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index d1a142fab4ed..14e9e2844bd0 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1749,6 +1749,14 @@ void PrinceEngine::freeDrawNodes() { } void PrinceEngine::drawScreen() { + + clsMasks(); + + _mainHero->showHero(); + _secondHero->showHero(); + + _mainHero->scrollHero(); + if (!_showInventoryFlag || _inventoryBackgroundRemember) { const Graphics::Surface *roomSurface; if (_locationNr != 50) { @@ -1790,9 +1798,11 @@ void PrinceEngine::drawScreen() { } } + showBackAnims(); + showNormAnims(); - showBackAnims(); + playNextFrame(); showObjects(); @@ -1811,10 +1821,6 @@ void PrinceEngine::drawScreen() { delete mainHeroSurface; } - clsMasks(); - - playNextFrame(); - if (!_inventoryBackgroundRemember && !_dialogFlag) { if (!_optionsFlag) { _selectedMob = checkMob(_graph->_frontScreen, _mobList, true); @@ -4465,12 +4471,6 @@ void PrinceEngine::mainLoop() { if (shouldQuit()) return; - // TODO: Update all structures, animations, naks, heros etc. - _mainHero -> showHero(); - if(_mainHero->_visible == 1) { - _mainHero -> scrollHero(); - } - _interpreter->step(); drawScreen(); From 9ea766ce2bc5c1ed7c2382021d2e2635a236d7f4 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 26 Jul 2014 19:31:54 +0200 Subject: [PATCH 290/374] PRINCE: Hero state names - update --- engines/prince/hero.cpp | 102 ++++++++++++-------------------------- engines/prince/hero.h | 21 ++++---- engines/prince/prince.cpp | 14 +++--- engines/prince/script.cpp | 10 ++-- 4 files changed, 55 insertions(+), 92 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index a0e7533c69db..2cc57897819e 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -34,7 +34,7 @@ namespace Prince { Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph) - , _number(0), _visible(false), _state(MOVE), _middleX(0), _middleY(0) + , _number(0), _visible(false), _state(kHeroStateStay), _middleX(0), _middleY(0) , _boreNum(1), _currHeight(0), _moveDelay(0), _shadMinus(0), _moveSetType(0) , _lastDirection(kHeroDirDown), _destDirection(kHeroDirDown), _talkTime(0), _boredomTime(0), _phase(0) , _specAnim(nullptr), _drawX(0), _drawY(0), _drawZ(0), _zoomFactor(0), _scaleValue(0) @@ -99,42 +99,6 @@ Graphics::Surface *Hero::getSurface() { return NULL; } -//TEMP -void Hero::getState() { - switch (_state) { - case STAY: - debug("STAY"); - break; - case TURN: - debug("TURN"); - break; - case MOVE: - debug("MOVE"); - break; - case BORE: - debug("BORE"); - break; - case SPEC: - debug("SPEC"); - break; - case TALK: - debug("TALK"); - break; - case MVAN: - debug("MVAN"); - break; - case TRAN: - debug("TRAN"); - break; - case RUN: - debug("RUN"); - break; - case DMOVE: - debug("DMOVE"); - break; - } -} - uint16 Hero::getData(AttrId dataId) { switch (dataId) { case kHeroLastDir: @@ -665,11 +629,11 @@ void Hero::showHero() { // Scale of hero selectZoom(); - if (_state != STAY) { + if (_state != kHeroStateStay) { _boredomTime = 0; } - if (_state == SPEC) { + if (_state == kHeroStateSpec) { if (_specAnim != nullptr) { if (_phase < _specAnim->getPhaseCount() - 1) { _phase++; @@ -677,17 +641,17 @@ void Hero::showHero() { _phase = 0; freeHeroAnim(); if (!_talkTime) { - _state = STAY; + _state = kHeroStateStay; } else { - _state = TALK; + _state = kHeroStateTalk; } } } else { - _state = STAY; + _state = kHeroStateStay; } } - if (_state == TALK) { + if (_state == kHeroStateTalk) { if (_talkTime) { switch (_lastDirection) { case kHeroDirLeft: @@ -709,11 +673,11 @@ void Hero::showHero() { _phase = _moveSet[_moveSetType]->getLoopCount(); } } else { - _state = STAY; + _state = kHeroStateStay; } } - if (_state == BORE) { + if (_state == kHeroStateBore) { switch (_boreNum) { case 0: _moveSetType = kMove_BORED1; @@ -728,21 +692,21 @@ void Hero::showHero() { } else { _phase = 0; _lastDirection = kHeroDirDown; - _state = STAY; + _state = kHeroStateStay; } } else { - _state = STAY; + _state = kHeroStateStay; } } - if (_state == STAY) { + if (_state == kHeroStateStay) { if (!_vm->_optionsFlag) { if (!_vm->_interpreter->getLastOPCode() || !_vm->_interpreter->getFgOpcodePC()) { _boredomTime++; if (_boredomTime == _maxBoredom) { _boreNum =_vm->_randomSource.getRandomNumber(1); // rand one of two 'bored' animation _phase = 0; - _state = BORE; + _state = kHeroStateBore; if (_lastDirection == kHeroDirUp) { _lastDirection = kHeroDirLeft; } else { @@ -758,64 +722,64 @@ void Hero::showHero() { heroStanding(); } - if (_state == TURN) { + if (_state == kHeroStateTurn) { if (_destDirection && (_lastDirection != _destDirection)) { _phase = 0; int rotateDir = rotateHero(_lastDirection, _destDirection); _lastDirection = _destDirection; if (rotateDir) { _turnAnim = rotateDir; - _state = TRAN; + _state = kHeroStateTran; } else { - _state = STAY; + _state = kHeroStateStay; heroStanding(); } } else { - _state = STAY; + _state = kHeroStateStay; heroStanding(); } } - if (_state == TRAN) { + if (_state == kHeroStateTran) { if (_moveSet[_turnAnim] != nullptr) { // only in bear form _moveSetType = _turnAnim; if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 2) { _phase += 2; } else { - _state = STAY; + _state = kHeroStateStay; heroStanding(); } } else { - _state = STAY; + _state = kHeroStateStay; heroStanding(); } } - if (_state == MVAN) { + if (_state == kHeroStateMvan) { if (_moveSet[_turnAnim] != nullptr) { // only in bear form _moveSetType = _turnAnim; if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 2) { _phase += 2; } else { - _state = MOVE; + _state = kHeroStateMove; } } else { - _state = MOVE; + _state = kHeroStateMove; } } - if (_state == DMOVE) { + if (_state == kHeroStateDelayMove) { _moveDelay--; if (!_moveDelay) { - _state = MOVE; + _state = kHeroStateMove; } } int x, y, dir; - if (_state == MOVE) { + if (_state == kHeroStateMove) { //go_for_it: while (1) { if (_currCoords != nullptr) { @@ -833,7 +797,7 @@ void Hero::showHero() { continue; } else { _turnAnim = rotateDir; - _state = MVAN; + _state = kHeroStateMvan; if (_moveSet[_turnAnim] != nullptr) { // only in bear form _moveSetType = _turnAnim; @@ -842,11 +806,11 @@ void Hero::showHero() { break; } else { _turnAnim = 0; - _state = MOVE; + _state = kHeroStateMove; continue; } } else { - _state = MOVE; + _state = kHeroStateMove; continue; } } @@ -893,7 +857,7 @@ void Hero::showHero() { _boredomTime = 0; _phase = 0; - _state = TURN; + _state = kHeroStateTurn; if (!_destDirection) { _destDirection = _lastDirection; @@ -935,7 +899,7 @@ void Hero::heroMoveGotIt(int x, int y, int dir) { break; } - if (_vm->_flags->getFlagValue(Flags::HEROFAST) || _state == RUN) { + if (_vm->_flags->getFlagValue(Flags::HEROFAST) || _state == kHeroStateRun) { if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 2) { _phase += 2; } else { @@ -955,7 +919,7 @@ void Hero::heroMoveGotIt(int x, int y, int dir) { } if (_vm->_flags->getFlagValue(Flags::HEROFAST)) { _step *= 2.5; - } else if (_state == RUN) { + } else if (_state == kHeroStateRun) { _step *= 2; } } @@ -1015,7 +979,7 @@ void Hero::freeOldMove() { _step = 0; _phase = 0; _moveDelay = 0; - _state = Hero::STAY; + _state = Hero::kHeroStateStay; } void Hero::freeHeroAnim() { diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 693cbd81e359..d2ad0d9c95dc 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -53,16 +53,16 @@ class Hero { static const int16 kStepUpDown = 4; enum State { - STAY = 0, - TURN = 1, - MOVE = 2, - BORE = 3, - SPEC = 4, - TALK = 5, - MVAN = 6, - TRAN = 7, - RUN = 8, - DMOVE = 9 + kHeroStateStay, + kHeroStateTurn, + kHeroStateMove, + kHeroStateBore, + kHeroStateSpec, + kHeroStateTalk, + kHeroStateMvan, + kHeroStateTran, + kHeroStateRun, + kHeroStateDelayMove }; enum Direction { @@ -132,7 +132,6 @@ class Hero { void plotPoint(int x, int y); void showHeroShadow(Graphics::Surface *heroFrame); void setShadowScale(int32 shadowScale); - void getState(); void freeOldMove(); void freeHeroAnim(); diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 14e9e2844bd0..dee52f7634e6 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2222,7 +2222,7 @@ void PrinceEngine::walkTo() { _mainHero->_dirTab = _directionTable; _mainHero->_currDirTab = _directionTable; _directionTable = nullptr; - _mainHero->_state = _mainHero->MOVE; + _mainHero->_state = _mainHero->kHeroStateMove; moveShandria(); } } @@ -2249,14 +2249,14 @@ void PrinceEngine::moveRunHero(int heroId, int x, int y, int dir, bool runHeroFl hero->_currDirTab = _directionTable; _directionTable = nullptr; if (runHeroFlag) { - hero->_state = _mainHero->RUN; + hero->_state = _mainHero->kHeroStateRun; } else { - hero->_state = _mainHero->MOVE; + hero->_state = _mainHero->kHeroStateMove; } } } else { hero->freeOldMove(); - hero->_state = Hero::TURN; + hero->_state = Hero::kHeroStateTurn; } hero->freeHeroAnim(); hero->_visible = 1; @@ -2886,13 +2886,13 @@ void PrinceEngine::talkHero(int slot) { if (slot == 0) { text._color = 220; // TODO - test this - _mainHero->_state = Hero::TALK; + _mainHero->_state = Hero::kHeroStateTalk; _mainHero->_talkTime = time; text._x = _mainHero->_middleX; text._y = _mainHero->_middleY - _mainHero->_scaledFrameYSize; } else { text._color = _flags->getFlagValue(Flags::KOLOR); // TODO - test this - _secondHero->_state = Hero::TALK; + _secondHero->_state = Hero::kHeroStateTalk; _secondHero->_talkTime = time; text._x = _secondHero->_middleX; text._y = _secondHero->_middleY - _secondHero->_scaledFrameYSize; @@ -4405,7 +4405,7 @@ byte *PrinceEngine::makePath(int destX, int destY) { return nullptr; } else { _mainHero->freeOldMove(); - _mainHero->_state = _mainHero->TURN; + _mainHero->_state = _mainHero->kHeroStateTurn; return nullptr; } } diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 4f989a18ae5b..fbd1b649ae0f 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -956,7 +956,7 @@ void Interpreter::O_WALKHERO() { hero = _vm->_secondHero; } if (hero != nullptr) { - if (hero->_state != Hero::STAY) { + if (hero->_state != Hero::kHeroStateStay) { _currentInstruction -= 4; _opcodeNF = 1; } @@ -1181,7 +1181,7 @@ void Interpreter::O_SETHEROANIM() { Resource::loadResource(hero->_specAnim, normalizedPath.c_str(), true); } hero->_phase = 0; - hero->_state = Hero::SPEC; + hero->_state = Hero::kHeroStateSpec; } } debugInterpreter("O_SETHEROANIM hero %d, offset %d", hero, offset); @@ -1196,7 +1196,7 @@ void Interpreter::O_WAITHEROANIM() { hero = _vm->_secondHero; } if (hero != nullptr) { - if (hero->_state == Hero::SPEC) { + if (hero->_state == Hero::kHeroStateSpec) { _currentInstruction -= 4; _opcodeNF = 1; } @@ -1711,9 +1711,9 @@ void Interpreter::O_FREEFLC() { void Interpreter::O_TALKHEROSTOP() { uint16 heroId = readScriptFlagValue(); if (!heroId) { - _vm->_mainHero->_state = _vm->_mainHero->STAY; + _vm->_mainHero->_state = _vm->_mainHero->kHeroStateStay; } else if (heroId == 1) { - _vm->_secondHero->_state = _vm->_secondHero->STAY; + _vm->_secondHero->_state = _vm->_secondHero->kHeroStateStay; } debugInterpreter("O_TALKHEROSTOP %d", heroId); } From 58ce087e8010bf656ff4321f24d1fe80f93c6e41 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 26 Jul 2014 20:07:12 +0200 Subject: [PATCH 291/374] PRINCE: showTexts() update - inventory texts --- engines/prince/prince.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index dee52f7634e6..ab774c1abe24 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1145,6 +1145,12 @@ uint32 PrinceEngine::getTextWidth(const char *s) { void PrinceEngine::showTexts(Graphics::Surface *screen) { for (uint32 slot = 0; slot < kMaxTexts; slot++) { + + if (_showInventoryFlag && slot) { + // only slot 0 for inventory + break; + } + Text& text = _textSlots[slot]; if (!text._str && !text._time) { continue; From c224455e1bd2573e7399206020c057645a9d80bc Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 26 Jul 2014 20:17:50 +0200 Subject: [PATCH 292/374] PRINCE: LMB texts skipping - slot 9 exclude --- engines/prince/prince.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index ab774c1abe24..62df0c7cb0dc 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2334,7 +2334,7 @@ void PrinceEngine::leftMouseButton() { if (!_flags->getFlagValue(Flags::POWERENABLED)) { if (!_flags->getFlagValue(Flags::NOCLSTEXT)) { for (int slot = 0; slot < kMaxTexts; slot++) { - if (slot != kMaxTexts - 9) { + if (slot != 9) { Text& text = _textSlots[slot]; if (!text._str) { continue; From c1456d273469d3eb876ae5b3d4fd602bf2c488ba Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 26 Jul 2014 20:49:42 +0200 Subject: [PATCH 293/374] PRINCE: MIDI music - update. loadMusic(), stopMusic(), O_SETMUSIC, O_STOPMUSIC --- engines/prince/prince.cpp | 27 ++++++++++++++++++++++++--- engines/prince/prince.h | 4 ++++ engines/prince/script.cpp | 4 ++-- engines/prince/sound.cpp | 4 ++-- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 62df0c7cb0dc..e3b274d6744f 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -93,7 +93,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _traceLineLen(0), _rembBitmapTemp(nullptr), _rembBitmap(nullptr), _rembMask(0), _rembX(0), _rembY(0), _checkBitmapTemp(nullptr), _checkBitmap(nullptr), _checkMask(0), _checkX(0), _checkY(0), _traceLineFirstPointFlag(false), _tracePointFirstPointFlag(false), _coordsBuf2(nullptr), _coords2(nullptr), _coordsBuf3(nullptr), _coords3(nullptr), - _shanLen1(0), _directionTable(nullptr) { + _shanLen1(0), _directionTable(nullptr), _currentMidi(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -405,8 +405,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { SearchMan.add(locationNrStr, locationArchive); - const char *musName = MusicPlayer::_musTable[MusicPlayer::_musRoomTable[locationNr]]; - _midiPlayer->loadMidi(musName); + loadMusic(_locationNr); // load location background, replace old one Resource::loadResource(_roomBmp, "room", true); @@ -573,6 +572,28 @@ void PrinceEngine::makeInvCursor(int itemNr) { } } +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::playNextFrame() { if (!_flicPlayer.isVideoLoaded()) return false; diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 3fd03c66d4d9..ebc42c28fd6b 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -273,6 +273,9 @@ class PrinceEngine : public Engine { bool loadShadow(byte *shadowBitmap, uint32 dataSize, const char *resourceName1, const char *resourceName2); bool loadMobPriority(const char *resourceName); + bool loadMusic(int musNumber); + void stopMusic(); + void playSample(uint16 sampleId, uint16 loopType); void stopSample(uint16 sampleId); void stopAllSamples(); @@ -305,6 +308,7 @@ class PrinceEngine : public Engine { Script *_script; InterpreterFlags *_flags; Interpreter *_interpreter; + uint8 _currentMidi; static const int kMaxNormAnims = 64; static const int kMaxBackAnims = 64; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index fbd1b649ae0f..7344bc361e5e 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -692,14 +692,14 @@ void Interpreter::O_FREEALLSAMPLES() { error("O_FREEALLSAMPLES"); } -// TODO void Interpreter::O_SETMUSIC() { uint16 musicId = readScript(); + _vm->loadMusic(musicId); debugInterpreter("O_SETMUSIC musicId %d", musicId); } -// TODO void Interpreter::O_STOPMUSIC() { + _vm->stopMusic(); debugInterpreter("O_STOPMUSIC"); } diff --git a/engines/prince/sound.cpp b/engines/prince/sound.cpp index 9a0a33b25cad..3509bbc2916e 100644 --- a/engines/prince/sound.cpp +++ b/engines/prince/sound.cpp @@ -155,8 +155,8 @@ void MusicPlayer::killMidi() { _data = NULL; } -void MusicPlayer::loadMidi(const char * name) { - Common::SeekableReadStream * stream = SearchMan.createReadStreamForMember(name); +void MusicPlayer::loadMidi(const char *name) { + Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(name); if (!stream) { debug("Can't load midi stream %s", name); return; From 2ccea09be87257e9ff4c5d150e139cbf16742863 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 27 Jul 2014 13:27:44 +0200 Subject: [PATCH 294/374] PRINCE: showText() - fix for inventory items in wider locations --- engines/prince/prince.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index e3b274d6744f..840b94c2196f 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1177,8 +1177,13 @@ void PrinceEngine::showTexts(Graphics::Surface *screen) { continue; } - int x = text._x - _picWindowX; - int y = text._y - _picWindowY; + int x = text._x; + int y = text._y; + + if (!_showInventoryFlag) { + x -= _picWindowX; + y -= _picWindowY; + } Common::Array lines; _font->wordWrapText(text._str, _graph->_frontScreen->w, lines); From 87756b4ebd83104a02b3a9c10ad7becb8db80c98 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 27 Jul 2014 16:04:12 +0200 Subject: [PATCH 295/374] PRINCE: findPoint(), makePath() - update --- engines/prince/prince.cpp | 103 +++++++++++++++----------------------- engines/prince/prince.h | 10 ++-- 2 files changed, 42 insertions(+), 71 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 840b94c2196f..3ab9b452096f 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -90,7 +90,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _dialogWidth(600), _dialogHeight(0), _dialogLineSpace(10), _dialogColor1(220), _dialogColor2(223), _dialogFlag(false), _dialogLines(0), _dialogText(nullptr), _mouseFlag(1), _roomPathBitmap(nullptr), _roomPathBitmapTemp(nullptr), _coordsBufEnd(nullptr), _coordsBuf(nullptr), _coords(nullptr), - _traceLineLen(0), _rembBitmapTemp(nullptr), _rembBitmap(nullptr), _rembMask(0), _rembX(0), _rembY(0), + _traceLineLen(0), _rembBitmapTemp(nullptr), _rembBitmap(nullptr), _rembMask(0), _rembX(0), _rembY(0), _fpX(0), _fpY(0), _checkBitmapTemp(nullptr), _checkBitmap(nullptr), _checkMask(0), _checkX(0), _checkY(0), _traceLineFirstPointFlag(false), _tracePointFirstPointFlag(false), _coordsBuf2(nullptr), _coords2(nullptr), _coordsBuf3(nullptr), _coords3(nullptr), _shanLen1(0), _directionTable(nullptr), _currentMidi(0) { @@ -3037,86 +3037,54 @@ int PrinceEngine::getPixelAddr(byte *pathBitmap, int x, int y) { return (mask & value); } -// TODO - check when both (start point and dest) are wrong -void PrinceEngine::findPoint(int x1, int y1, int x2, int y2) { - _fpResult.x1 = x1; - _fpResult.y1 = y1; - _fpResult.x2 = x2; - _fpResult.y2 = y2; +void PrinceEngine::findPoint(int x, int y) { + _fpX = x; + _fpY = y; - bool fpFlag = false; - int fpX = x1; - int fpY = y1; - - if (getPixelAddr(_roomPathBitmap, x1, y1)) { - fpFlag = true; - fpX = x2; - fpY = y2; - if (getPixelAddr(_roomPathBitmap, x2, y2)) { - return; - } + if (getPixelAddr(_roomPathBitmap, x, y)) { + return; } - int fpL = fpX; - int fpU = fpY; - int fpR = fpX; - int fpD = fpY; + int fpL = x; + int fpU = y; + int fpR = x; + int fpD = y; while (1) { if (fpD != kMaxPicHeight) { - if (getPixelAddr(_roomPathBitmap, fpX, fpD)) { - if (fpFlag) { - _fpResult.x2 = fpX; - _fpResult.y2 = fpD; - } else { - _fpResult.x1 = fpX; - _fpResult.y1 = fpD; - } + if (getPixelAddr(_roomPathBitmap, x, fpD)) { + _fpX = x; + _fpY = fpD; break; } fpD++; } if (fpU) { - if (getPixelAddr(_roomPathBitmap, fpX, fpU)) { - if (fpFlag) { - _fpResult.x2 = fpX; - _fpResult.y2 = fpU; - } else { - _fpResult.x1 = fpX; - _fpResult.y1 = fpU; - } + if (getPixelAddr(_roomPathBitmap, x, fpU)) { + _fpX = x; + _fpY = fpU; break; } fpU--; } if (fpL) { - if (getPixelAddr(_roomPathBitmap, fpL, fpY)) { - if (fpFlag) { - _fpResult.x2 = fpL; - _fpResult.y2 = fpY; - } else { - _fpResult.x1 = fpL; - _fpResult.y1 = fpY; - } + if (getPixelAddr(_roomPathBitmap, fpL, y)) { + _fpX = fpL; + _fpY = y; break; } fpL--; } if (fpR != _sceneWidth) { - if (getPixelAddr(_roomPathBitmap, fpR, fpY)) { - if (fpFlag) { - _fpResult.x2 = fpR; - _fpResult.y2 = fpY; - } else { - _fpResult.x1 = fpR; - _fpResult.y1 = fpY; - } + if (getPixelAddr(_roomPathBitmap, fpR, y)) { + _fpX = fpR; + _fpY = y; break; } fpR++; } - if (!fpU && fpD == kMaxPicHeight) { - if (!fpL && fpR == _sceneWidth) { + if (!fpU && (fpD == kMaxPicHeight)) { + if (!fpL && (fpR == _sceneWidth)) { break; } } @@ -4311,14 +4279,15 @@ byte *PrinceEngine::makePath(int destX, int destY) { int y2 = destY / 2; if ((x1 != x2) || (y1 != y2)) { - findPoint(x1, y1, x2, y2); - if (x1 != _fpResult.x1 || y1 != _fpResult.y1) { - x1 = _fpResult.x1; - y1 = _fpResult.y1; - } - if (x2 != _fpResult.x2 || y2 != _fpResult.y2) { - x2 = _fpResult.x2; - y2 = _fpResult.y2; + findPoint(x1, y1); + if (x1 != _fpX || y1 != _fpY) { + x1 = _fpX; + y1 = _fpY; + } + findPoint(x2, y2); + if (x2 != _fpX || y2 != _fpY) { + x2 = _fpX; + y2 = _fpY; if (!_flags->getFlagValue(Flags::EXACTMOVE)) { realDestX = x2 * 2; realDestY = y2 * 2; @@ -4329,6 +4298,12 @@ byte *PrinceEngine::makePath(int destX, int destY) { } } + if ((x1 == x2) && (y1 == y2)) { + _mainHero->freeOldMove(); + _mainHero->_state = _mainHero->kHeroStateTurn; + return nullptr; + } + int pathLen1 = 0; int pathLen2 = 0; int stX = x1; diff --git a/engines/prince/prince.h b/engines/prince/prince.h index ebc42c28fd6b..fab49889bb9e 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -484,17 +484,13 @@ class PrinceEngine : public Engine { int _rembX; int _rembY; - struct fpResult { - int x1; - int y1; - int x2; - int y2; - } _fpResult; + int _fpX; + int _fpY; int drawLine(int x0, int y0, int x1, int y1, int (*plotProc)(int, int, void *), void *data); bool loadPath(const char *resourceName); byte *makePath(int destX, int destY); - void findPoint(int x1, int y1, int x2, int y2); + void findPoint(int x, int y); int getPixelAddr(byte *pathBitmap, int x, int y); static int plotTraceLine(int x, int y, void *data); void specialPlotInside(int x, int y); From 951239bfd8c25c1bab04f4bec527ed534572058c Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 27 Jul 2014 17:47:18 +0200 Subject: [PATCH 296/374] PRINCE: O_CHECKANIMFRAME, O_CHECKBACKANIMFRAME fix --- engines/prince/script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 7344bc361e5e..e2c323b415b7 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -640,7 +640,7 @@ void Interpreter::O_FREEANIM() { void Interpreter::O_CHECKANIMFRAME() { uint16 slot = readScriptFlagValue(); uint16 frameNumber = readScriptFlagValue(); - if (_vm->_normAnimList[slot]._frame != frameNumber) { + if (_vm->_normAnimList[slot]._frame != frameNumber - 1) { _currentInstruction -= 6; _opcodeNF = 1; } @@ -680,7 +680,7 @@ void Interpreter::O_CHECKBACKANIMFRAME() { uint16 slotId = readScriptFlagValue(); uint16 frameId = readScriptFlagValue(); int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; - if (_vm->_backAnimList[slotId].backAnims[currAnim]._frame != frameId) { + if (_vm->_backAnimList[slotId].backAnims[currAnim]._frame != frameId - 1) { _currentInstruction -= 6; _opcodeNF = 1; } From 822d1786b0c625bc9d1be694132c0ffc480dec60 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 28 Jul 2014 00:02:22 +0200 Subject: [PATCH 297/374] PRINCE: showTexts() fix --- engines/prince/prince.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 3ab9b452096f..89fb9e334e51 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1210,10 +1210,10 @@ void PrinceEngine::showTexts(Graphics::Surface *screen) { int drawX = x - getTextWidth(lines[i].c_str()) / 2; int drawY = y - 10 - (lines.size() - i) * (_font->getFontHeight() - textSkip); if (drawX < 0) { - x = 0; + drawX = 0; } if (drawY < 0) { - y = 0; + drawY = 0; } _font->drawString(screen, lines[i], drawX, drawY, screen->w, text._color); } From 08d781b6ad4cbd399528407702fbec73c6532ea8 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 29 Jul 2014 02:25:42 +0200 Subject: [PATCH 298/374] PRINCE: Game saving - basic implementation --- engines/prince/detection.cpp | 100 +------ engines/prince/detection.h | 101 +++++++ engines/prince/flags.h | 2 +- engines/prince/hero.cpp | 4 +- engines/prince/hero.h | 8 +- engines/prince/module.mk | 3 +- engines/prince/prince.cpp | 9 +- engines/prince/prince.h | 15 ++ engines/prince/saveload.cpp | 508 +++++++++++++++++++++++++++++++++++ engines/prince/script.cpp | 96 ++++--- engines/prince/script.h | 31 ++- 11 files changed, 729 insertions(+), 148 deletions(-) create mode 100644 engines/prince/detection.h create mode 100644 engines/prince/saveload.cpp diff --git a/engines/prince/detection.cpp b/engines/prince/detection.cpp index fa9df38c9007..285d7d1ce32f 100644 --- a/engines/prince/detection.cpp +++ b/engines/prince/detection.cpp @@ -20,19 +20,10 @@ * */ -#include "base/plugins.h" -#include "engines/advancedDetector.h" - -#include "prince/prince.h" +#include "prince/detection.h" namespace Prince { -struct PrinceGameDescription { - ADGameDescription desc; - - int gameType; -}; - int PrinceEngine::getGameType() const { return _gameDescription->gameType; } @@ -49,78 +40,6 @@ Common::Language PrinceEngine::getLanguage() const { return _gameDescription->desc.language; } -} - -static const PlainGameDescriptor princeGames[] = { - {"prince", "Prince Game"}, - {0, 0} -}; - -namespace Prince { - -static const PrinceGameDescription gameDescriptions[] = { - - // German - { - { - "prince", - "Galador", - AD_ENTRY1s("databank.ptc", "5fa03833177331214ec1354761b1d2ee", 3565031), - Common::DE_DEU, - Common::kPlatformWindows, - ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) - }, - 0 - }, - // Polish - { - { - "prince", - "Ksiaze i Tchorz", - AD_ENTRY1s("databank.ptc", "48ec9806bda9d152acbea8ce31c93c49", 3435298), - Common::PL_POL, - Common::kPlatformWindows, - ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) - }, - 1 - }, - - - { AD_TABLE_END_MARKER, 0 } -}; - -} // End of namespace Prince - -using namespace Prince; - -// we match from data too, to stop detection from a non-top-level directory -const static char *directoryGlobs[] = { - "all", - 0 -}; - -class PrinceMetaEngine : public AdvancedMetaEngine { -public: - PrinceMetaEngine() : AdvancedMetaEngine(Prince::gameDescriptions, sizeof(Prince::PrinceGameDescription), princeGames) { - _singleid = "prince"; - _maxScanDepth = 2; - _directoryGlobs = directoryGlobs; - } - - virtual const char *getName() const { - return "Prince Engine"; - } - - virtual const char *getOriginalCopyright() const { - return "Copyright (C)"; - } - - virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; - virtual bool hasFeature(MetaEngineFeature f) const; -}; - bool PrinceMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { using namespace Prince; const PrinceGameDescription *gd = (const PrinceGameDescription *)desc; @@ -131,17 +50,26 @@ bool PrinceMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGa } bool PrinceMetaEngine::hasFeature(MetaEngineFeature f) const { - return false; + return + (f == kSupportsDeleteSave) || + (f == kSavesSupportMetaInfo) || + (f == kSavesSupportThumbnail) || + (f == kSavesSupportCreationDate) || + (f == kSupportsListSaves); } bool Prince::PrinceEngine::hasFeature(EngineFeature f) const { - return false;//(f == kSupportsRTL); + return + (f == kSupportsLoadingDuringRuntime) || + (f == kSupportsSavingDuringRuntime); } +} // End of namespace Prince + #if PLUGIN_ENABLED_DYNAMIC(PRINCE) -REGISTER_PLUGIN_DYNAMIC(PRINCE, PLUGIN_TYPE_ENGINE, PrinceMetaEngine); +REGISTER_PLUGIN_DYNAMIC(PRINCE, PLUGIN_TYPE_ENGINE, Prince::PrinceMetaEngine); #else -REGISTER_PLUGIN_STATIC(PRINCE, PLUGIN_TYPE_ENGINE, PrinceMetaEngine); +REGISTER_PLUGIN_STATIC(PRINCE, PLUGIN_TYPE_ENGINE, Prince::PrinceMetaEngine); #endif /* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/detection.h b/engines/prince/detection.h new file mode 100644 index 000000000000..6137730bd0fd --- /dev/null +++ b/engines/prince/detection.h @@ -0,0 +1,101 @@ +/* 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_DETECTION_H +#define PRINCE_DETECTION_H + +#include "prince/prince.h" +#include "engines/advancedDetector.h" + +namespace Prince { + +struct PrinceGameDescription { + ADGameDescription desc; + int gameType; +}; + +static const PlainGameDescriptor princeGames[] = { + {"prince", "Prince Game"}, + {0, 0} +}; + +static const PrinceGameDescription gameDescriptions[] = { + { + { + "prince", + "Galador", + AD_ENTRY1s("databank.ptc", "5fa03833177331214ec1354761b1d2ee", 3565031), + Common::DE_DEU, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NONE) + }, + 0 + }, + { + { + "prince", + "Ksiaze i Tchorz", + AD_ENTRY1s("databank.ptc", "48ec9806bda9d152acbea8ce31c93c49", 3435298), + Common::PL_POL, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NONE) + }, + 1 + }, + { AD_TABLE_END_MARKER, 0 } +}; + +// we match from data too, to stop detection from a non-top-level directory +const static char *directoryGlobs[] = { + "all", + 0 +}; + +class PrinceMetaEngine : public AdvancedMetaEngine { +public: + PrinceMetaEngine() : AdvancedMetaEngine(Prince::gameDescriptions, sizeof(Prince::PrinceGameDescription), princeGames) { + _singleid = "prince"; + _maxScanDepth = 2; + _directoryGlobs = directoryGlobs; + } + + virtual const char *getName() const { + return "Prince Engine"; + } + + virtual const char *getOriginalCopyright() const { + return "Copyright (C)"; + } + + virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; + virtual bool hasFeature(MetaEngineFeature f) const; + virtual int getMaximumSaveSlot() const; + virtual SaveStateList listSaves(const char *target) const; + SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const; + virtual void removeSaveState(const char *target, int slot) const; +}; + +} // End of namespace Prince + +#endif diff --git a/engines/prince/flags.h b/engines/prince/flags.h index aa607a01fe5e..5af6bffa0060 100644 --- a/engines/prince/flags.h +++ b/engines/prince/flags.h @@ -31,7 +31,7 @@ struct Flags { // TODO: Remove from release build // useful just for debugging - static const char * getFlagName(uint16 flagId); + static const char *getFlagName(uint16 flagId); enum Id { FLAGA1 = 0x8000, diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 2cc57897819e..6b4cafa968f2 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -41,7 +41,7 @@ Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph) , _shadZoomFactor(0), _shadScaleValue(0), _shadLineLen(0), _shadDrawX(0), _shadDrawY(0) , _frameXSize(0), _frameYSize(0), _scaledFrameXSize(0), _scaledFrameYSize(0), _color(0) , _coords(nullptr), _dirTab(nullptr), _currCoords(nullptr), _currDirTab(nullptr), _step(0) - , _maxBoredom(200), _turnAnim(0), _leftRightMainDir(0), _upDownMainDir(0) + , _maxBoredom(200), _turnAnim(0), _leftRightMainDir(0), _upDownMainDir(0), _animSetNr(0) { _zoomBitmap = (byte *)malloc(kZoomBitmapLen); _shadowBitmap = (byte *)malloc(2 * kShadowBitmapSize); @@ -57,6 +57,8 @@ Hero::~Hero() { } bool Hero::loadAnimSet(uint32 animSetNr) { + _animSetNr = animSetNr; + if (animSetNr > sizeof(heroSetTable)) { return false; } diff --git a/engines/prince/hero.h b/engines/prince/hero.h index d2ad0d9c95dc..236818c3a18c 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -182,11 +182,11 @@ class Hero { uint16 _currHeight; // height of current anim phase - Common::Array _inventory; // Inventory array of items - Common::Array _inventory2; // Inventory2 array of items + Common::Array _inventory; // Inventory array of items + Common::Array _inventory2; // Inventory2 array of items // Font subtitiles font - int _color; // Color Subtitles color - // AnimSet number of animation set + int _color; // subtitles color + uint32 _animSetNr; // number of animation set Common::Array _moveSet; // MoveAnims MoveSet int16 _turnAnim; byte *_zoomBitmap; diff --git a/engines/prince/module.mk b/engines/prince/module.mk index ad5b20aeb1b0..584fb99a9793 100644 --- a/engines/prince/module.mk +++ b/engines/prince/module.mk @@ -19,7 +19,8 @@ MODULE_OBJS = \ hero.o \ hero_set.o \ cursor.o \ - pscr.o + pscr.o \ + saveload.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 89fb9e334e51..fe2f398b8571 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -323,7 +323,7 @@ void PrinceEngine::init() { _objSlot = new int[kMaxObjects]; for (int i = 0; i < kMaxObjects; i++) { - _objSlot[i] = -1; + _objSlot[i] = 0xFF; } } @@ -458,7 +458,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); for (uint i = 0; i < _mobList.size(); i++) { - _mobList[i]._visible = _script->getMobVisible(i); + _mobList[i]._visible = _script->getMobVisible(_room->_mobs, i); } freeDrawNodes(); @@ -992,7 +992,7 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis //mob_obj if (mob->_mask < kMaxObjects) { int nr = _objSlot[mob->_mask]; - if (nr != -1) { + 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(mousePosCamera)) { @@ -1682,7 +1682,7 @@ void PrinceEngine::freeZoomObject(int slot) { void PrinceEngine::showObjects() { for (int i = 0; i < kMaxObjects; i++) { int nr = _objSlot[i]; - if (nr != -1) { + if (nr != 0xFF) { Graphics::Surface *objSurface = nullptr; if ((_objList[nr]->_flags & 0x8000)) { _objList[nr]->_zoomTime--; @@ -4508,7 +4508,6 @@ void PrinceEngine::mainLoop() { } } } - if (_debugger->_locationNr != _locationNr) loadLocation(_debugger->_locationNr); if (_debugger->_cursorNr != _cursorNr) diff --git a/engines/prince/prince.h b/engines/prince/prince.h index fab49889bb9e..64f981cdb68b 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -31,6 +31,8 @@ #include "common/rect.h" #include "common/events.h" #include "common/endian.h" +#include "common/savefile.h" +#include "common/serializer.h" #include "image/bmp.h" @@ -51,6 +53,7 @@ namespace Prince { struct PrinceGameDescription; +struct SavegameHeader; class PrinceEngine; class GraphicsMan; @@ -252,6 +255,17 @@ class PrinceEngine : public Engine { virtual ~PrinceEngine(); virtual bool hasFeature(EngineFeature f) const; + virtual bool canSaveGameStateCurrently(); + virtual bool canLoadGameStateCurrently(); + virtual Common::Error saveGameState(int slot, const Common::String &desc); + virtual Common::Error loadGameState(int slot); + + static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header); + Common::String generateSaveName(int slot); + void writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &header); + void syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream); + bool loadGame(int slotNumber); + void resetGame(); int getGameType() const; const char *getGameId() const; @@ -313,6 +327,7 @@ class PrinceEngine : public Engine { static const int kMaxNormAnims = 64; static const int kMaxBackAnims = 64; static const int kMaxObjects = 64; + static const int kMaxMobs = 64; Common::Array _animList; Common::Array _backAnimList; diff --git a/engines/prince/saveload.cpp b/engines/prince/saveload.cpp new file mode 100644 index 000000000000..83d45a4bd794 --- /dev/null +++ b/engines/prince/saveload.cpp @@ -0,0 +1,508 @@ +/* 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/detection.h" +#include "prince/flags.h" +#include "prince/script.h" +#include "prince/hero.h" +#include "common/savefile.h" +#include "common/system.h" +#include "common/config-manager.h" +#include "common/memstream.h" +#include "graphics/thumbnail.h" +#include "graphics/surface.h" +#include "graphics/palette.h" +#include "graphics/scaler.h" + +namespace Prince { + +#define kBadSVG 99 +#define kSavegameVersion 1 +#define kSavegameStrSize 14 +#define kSavegameStr "SCUMMVM_PRINCE" + +class InterpreterFlags; +class Interpreter; + +struct SavegameHeader { + uint8 version; + Common::String saveName; + Graphics::Surface *thumbnail; + int saveYear, saveMonth, saveDay; + int saveHour, saveMinutes; +}; + +int PrinceMetaEngine::getMaximumSaveSlot() const { + return 99; +} + +SaveStateList PrinceMetaEngine::listSaves(const char *target) const { + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + Common::StringArray filenames; + Common::String pattern = target; + pattern += ".???"; + + filenames = saveFileMan->listSavefiles(pattern); + sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..) + + SaveStateList saveList; + for (Common::StringArray::const_iterator filename = filenames.begin(); filename != filenames.end(); filename++) { + // Obtain the last 3 digits of the filename, since they correspond to the save slot + int slotNum = atoi(filename->c_str() + filename->size() - 3); + + if (slotNum >= 0 && slotNum <= 99) { + + Common::InSaveFile *file = saveFileMan->openForLoading(*filename); + if (file) { + Prince::SavegameHeader header; + + // Check to see if it's a ScummVM savegame or not + char buffer[kSavegameStrSize + 1]; + file->read(buffer, kSavegameStrSize + 1); + + if (!strncmp(buffer, kSavegameStr, kSavegameStrSize + 1)) { + // Valid savegame + if (Prince::PrinceEngine::readSavegameHeader(file, header)) { + saveList.push_back(SaveStateDescriptor(slotNum, header.saveName)); + if (header.thumbnail) { + header.thumbnail->free(); + delete header.thumbnail; + } + } + } else { + // Must be an original format savegame + saveList.push_back(SaveStateDescriptor(slotNum, "Unknown")); + } + + delete file; + } + } + } + + return saveList; +} + +SaveStateDescriptor PrinceMetaEngine::querySaveMetaInfos(const char *target, int slot) const { + Common::String fileName = Common::String::format("%s.%03d", target, slot); + Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(fileName); + + if (f) { + Prince::SavegameHeader header; + + // Check to see if it's a ScummVM savegame or not + char buffer[kSavegameStrSize + 1]; + f->read(buffer, kSavegameStrSize + 1); + + bool hasHeader = !strncmp(buffer, kSavegameStr, kSavegameStrSize + 1) && + Prince::PrinceEngine::readSavegameHeader(f, header); + delete f; + + if (!hasHeader) { + // Original savegame perhaps? + SaveStateDescriptor desc(slot, "Unknown"); + return desc; + } else { + // Create the return descriptor + SaveStateDescriptor desc(slot, header.saveName); + desc.setThumbnail(header.thumbnail); + desc.setSaveDate(header.saveYear, header.saveMonth, header.saveDay); + desc.setSaveTime(header.saveHour, header.saveMinutes); + + return desc; + } + } + + return SaveStateDescriptor(); +} + +bool PrinceEngine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header) { + header.thumbnail = nullptr; + + // Get the savegame version + header.version = in->readByte(); + if (header.version > kSavegameVersion) + return false; + + // Read in the string + header.saveName.clear(); + char ch; + while ((ch = (char)in->readByte()) != '\0') + header.saveName += ch; + + // Get the thumbnail + header.thumbnail = Graphics::loadThumbnail(*in); + if (!header.thumbnail) + return false; + + // Read in save date/time + header.saveYear = in->readSint16LE(); + header.saveMonth = in->readSint16LE(); + header.saveDay = in->readSint16LE(); + header.saveHour = in->readSint16LE(); + header.saveMinutes = in->readSint16LE(); + + return true; +} + +void PrinceMetaEngine::removeSaveState(const char *target, int slot) const { + Common::String fileName = Common::String::format("%s.%03d", target, slot); + g_system->getSavefileManager()->removeSavefile(fileName); +} + +// TODO +bool PrinceEngine::canSaveGameStateCurrently() { + return true; +} + +// TODO +bool PrinceEngine::canLoadGameStateCurrently() { + return true; +} + +Common::Error PrinceEngine::saveGameState(int slot, const Common::String &desc) { + // Set up the serializer + Common::String slotName = generateSaveName(slot); + Common::OutSaveFile *saveFile = g_system->getSavefileManager()->openForSaving(slotName); + + // Write out the ScummVM savegame header + SavegameHeader header; + header.saveName = desc; + header.version = kSavegameVersion; + writeSavegameHeader(saveFile, header); + + // Write out the data of the savegame + syncGame(nullptr, saveFile); + + // Finish writing out game data + saveFile->finalize(); + delete saveFile; + + return Common::kNoError; +} + +Common::String PrinceEngine::generateSaveName(int slot) { + return Common::String::format("%s.%03d", _targetName.c_str(), slot); +} + +void PrinceEngine::writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &header) { + // Write out a savegame header + out->write(kSavegameStr, kSavegameStrSize + 1); + + out->writeByte(kSavegameVersion); + + // Write savegame name + out->write(header.saveName.c_str(), header.saveName.size() + 1); + + // Get the active palette + uint8 thumbPalette[256 * 3]; + _system->getPaletteManager()->grabPalette(thumbPalette, 0, 256); + + // Create a thumbnail and save it + Graphics::Surface *thumb = new Graphics::Surface(); + Graphics::Surface *s = _graph->_frontScreen; // check inventory / map etc.. + ::createThumbnail(thumb, (const byte *)s->getPixels(), s->w, s->h, thumbPalette); + Graphics::saveThumbnail(*out, *thumb); + thumb->free(); + delete thumb; + + // Write out the save date/time + TimeDate td; + g_system->getTimeAndDate(td); + out->writeSint16LE(td.tm_year + 1900); + out->writeSint16LE(td.tm_mon + 1); + out->writeSint16LE(td.tm_mday); + out->writeSint16LE(td.tm_hour); + out->writeSint16LE(td.tm_min); +} + +void PrinceEngine::syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream) { + int emptyRoom = 0x00; + int normRoom = 0xFF; + byte endInv = 0xFF; + + Common::Serializer s(readStream, writeStream); + + if (s.isSaving()) { + // Flag values + for (int i = 0; i < _flags->kMaxFlags; i++) { + uint32 value = _flags->getFlagValue((Flags::Id)(_flags->kFlagMask + i)); + s.syncAsUint32LE(value); + } + + // Dialog data + for (uint32 i = 0; i < _dialogDatSize; i++) { + byte value = _dialogDat[i]; + s.syncAsByte(value); + } + + // Location number + s.syncAsUint16LE(_locationNr); + + // Rooms + for (int roomId = 0; roomId < _script->kMaxRooms; roomId++) { + Room *room = new Room(); + room->loadRoom(_script->getRoomOffset(roomId)); + + if (room->_mobs) { + s.syncAsByte(normRoom); + } else { + s.syncAsByte(emptyRoom); + delete room; + continue; + } + + // Mobs + for (int mobId = 0; mobId < kMaxMobs; mobId++) { + byte value = _script->getMobVisible(room->_mobs, mobId); + s.syncAsByte(value); + } + + // Background animations + for (int backAnimSlot = 0; backAnimSlot < kMaxBackAnims; backAnimSlot++) { + uint32 value = _script->getBackAnimId(_room->_backAnim, backAnimSlot); + s.syncAsUint32LE(value); + } + + // Objects + for (int objectSlot = 0; objectSlot < kMaxObjects; objectSlot++) { + byte value = _script->getObjId(room->_obj, objectSlot); + s.syncAsByte(value); + } + + delete room; + } + + // Main hero + s.syncAsUint16LE(_mainHero->_visible); + s.syncAsUint16LE(_mainHero->_middleX); + s.syncAsUint16LE(_mainHero->_middleY); + s.syncAsUint16LE(_mainHero->_lastDirection); + s.syncAsUint32LE(_mainHero->_color); + s.syncAsUint16LE(_mainHero->_maxBoredom); + s.syncAsUint32LE(_mainHero->_animSetNr); + + for (uint inv1Slot = 0; inv1Slot < _mainHero->_inventory.size(); inv1Slot++) { + s.syncAsByte(_mainHero->_inventory[inv1Slot]); + } + s.syncAsByte(endInv); + + for (uint inv2Slot = 0; inv2Slot < _mainHero->_inventory2.size(); inv2Slot++) { + s.syncAsByte(_mainHero->_inventory2[inv2Slot]); + } + s.syncAsByte(endInv); + + // Second hero + s.syncAsUint16LE(_secondHero->_visible); + s.syncAsUint16LE(_secondHero->_middleX); + s.syncAsUint16LE(_secondHero->_middleY); + s.syncAsUint16LE(_secondHero->_lastDirection); + s.syncAsUint32LE(_secondHero->_color); + s.syncAsUint16LE(_secondHero->_maxBoredom); + s.syncAsUint32LE(_secondHero->_animSetNr); + + for (uint inv1Slot = 0; inv1Slot < _secondHero->_inventory.size(); inv1Slot++) { + s.syncAsByte(_secondHero->_inventory[inv1Slot]); + } + s.syncAsByte(endInv); + + for (uint inv2Slot = 0; inv2Slot < _secondHero->_inventory2.size(); inv2Slot++) { + s.syncAsByte(_secondHero->_inventory2[inv2Slot]); + } + s.syncAsByte(endInv); + + } else { + // Flag values + for (int i = 0; i < _flags->kMaxFlags; i++) { + uint32 value = 0; + s.syncAsUint32LE(value); + _flags->setFlagValue((Flags::Id)(_flags->kFlagMask + i), value); + } + + // Dialog data + for (uint32 i = 0; i < _dialogDatSize; i++) { + byte value = 0; + s.syncAsByte(value); + _dialogDat[i] = value; + } + + // Location number + int restoreRoom = 0; + s.syncAsUint16LE(restoreRoom); + _flags->setFlagValue(Flags::RESTOREROOM, restoreRoom); + + // Rooms + for (int roomId = 0; roomId < _script->kMaxRooms; roomId++) { + Room *room = new Room(); + room->loadRoom(_script->getRoomOffset(roomId)); + + byte roomType = emptyRoom; + s.syncAsByte(roomType); + if (roomType == emptyRoom) { + delete room; + continue; + } + + // Mobs + for (int mobId = 0; mobId < kMaxMobs; mobId++) { + byte value = 0; + s.syncAsByte(value); + _script->setMobVisible(room->_mobs, mobId, value); + } + + // Background animations + for (int backAnimSlot = 0; backAnimSlot < kMaxBackAnims; backAnimSlot++) { + uint32 value = 0; + s.syncAsUint32LE(value); + _script->setBackAnimId(_room->_backAnim, backAnimSlot, value); + } + + // Objects + for (int objectSlot = 0; objectSlot < kMaxObjects; objectSlot++) { + byte value = 0; + s.syncAsByte(value); + _script->setObjId(room->_obj, objectSlot, value); + } + + delete room; + } + + // Main hero + s.syncAsUint16LE(_mainHero->_visible); + s.syncAsUint16LE(_mainHero->_middleX); + s.syncAsUint16LE(_mainHero->_middleY); + s.syncAsUint16LE(_mainHero->_lastDirection); + s.syncAsUint32LE(_mainHero->_color); + s.syncAsUint16LE(_mainHero->_maxBoredom); + s.syncAsUint32LE(_mainHero->_animSetNr); + _mainHero->loadAnimSet(_mainHero->_animSetNr); + + _mainHero->_inventory.clear(); + byte invId = endInv; + while (1) { + s.syncAsByte(invId); + if (invId == endInv) { + break; + } + _mainHero->_inventory.push_back(invId); + } + + _mainHero->_inventory2.clear(); + invId = endInv; + while (1) { + s.syncAsByte(invId); + if (invId == endInv) { + break; + } + _mainHero->_inventory.push_back(invId); + } + + // Second hero + s.syncAsUint16LE(_secondHero->_visible); + s.syncAsUint16LE(_secondHero->_middleX); + s.syncAsUint16LE(_secondHero->_middleY); + s.syncAsUint16LE(_secondHero->_lastDirection); + s.syncAsUint32LE(_secondHero->_color); + s.syncAsUint16LE(_secondHero->_maxBoredom); + s.syncAsUint32LE(_secondHero->_animSetNr); + _secondHero->loadAnimSet(_secondHero->_animSetNr); + + _secondHero->_inventory.clear(); + invId = endInv; + while (1) { + s.syncAsByte(invId); + if (invId == endInv) { + break; + } + _secondHero->_inventory.push_back(invId); + } + + _secondHero->_inventory2.clear(); + invId = endInv; + while (1) { + s.syncAsByte(invId); + if (invId == endInv) { + break; + } + _secondHero->_inventory.push_back(invId); + } + + // Script + _interpreter->setBgOpcodePC(0); + _interpreter->setFgOpcodePC(_script->_scriptInfo.restoreGame); + + } +} + +Common::Error PrinceEngine::loadGameState(int slot) { + if (!loadGame(slot)) { + return Common::kReadingFailed; + } + return Common::kNoError; +} + +bool PrinceEngine::loadGame(int slotNumber) { + Common::MemoryReadStream *readStream; + + // Open up the savegame file + Common::String slotName = generateSaveName(slotNumber); + Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(slotName); + + // Read the data into a data buffer + int size = saveFile->size(); + byte *dataBuffer = (byte *)malloc(size); + saveFile->read(dataBuffer, size); + readStream = new Common::MemoryReadStream(dataBuffer, size, DisposeAfterUse::YES); + delete saveFile; + + // Check to see if it's a ScummVM savegame or not + char buffer[kSavegameStrSize + 1]; + readStream->read(buffer, kSavegameStrSize + 1); + + if (strncmp(buffer, kSavegameStr, kSavegameStrSize + 1) != 0) { + delete readStream; + return false; + } else { + SavegameHeader saveHeader; + + if (!readSavegameHeader(readStream, saveHeader)) { + delete readStream; + return false; + } + + // Delete the thumbnail + saveHeader.thumbnail->free(); + delete saveHeader.thumbnail; + } + + // Get in the savegame + syncGame(readStream, nullptr); + delete readStream; + + // TODO + //syncSpeechSettings(); + + return true; +} + +} // End of namespace Prince diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index e2c323b415b7..57d0b8a77082 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -148,12 +148,16 @@ uint32 Script::getStartGameOffset() { return _scriptInfo.startGame; } -bool Script::getMobVisible(int mob) { - return _data[_vm->_room->_mobs + mob]; +uint32 Script::getLocationInitScript(int initRoomTableOffset, int roomNr) { + return (uint32)READ_UINT32(&_data[initRoomTableOffset + roomNr * 4]); } -void Script::setMobVisible(int mob, int value) { - _data[_vm->_room->_mobs + mob] = value; +byte Script::getMobVisible(int roomMobOffset, uint16 mob) { + return _data[roomMobOffset + mob]; +} + +void Script::setMobVisible(int roomMobOffset, uint16 mob, byte value) { + _data[roomMobOffset + mob] = value; } uint8 *Script::getRoomOffset(int locationNr) { @@ -185,12 +189,21 @@ uint8 *Script::getHeroAnimName(int offset) { return &_data[offset]; } -void Script::setBackAnimId(int offset, int animId) { - WRITE_UINT32(&_data[offset], animId); +uint32 Script::getBackAnimId(int roomBackAnimOffset, int slot) { + uint32 animId = READ_UINT32(&_data[roomBackAnimOffset + slot * 4]); + return animId; +} + +void Script::setBackAnimId(int roomBackAnimOffset, int slot, int animId) { + WRITE_UINT32(&_data[roomBackAnimOffset + slot * 4], animId); } -void Script::setObjId(int offset, int objId) { - _data[offset] = objId; +byte Script::getObjId(int roomObjOffset, int slot) { + return _data[roomObjOffset + slot]; +} + +void Script::setObjId(int roomObjOffset, int slot, byte objectId) { + _data[roomObjOffset + slot] = objectId; } int Script::scanMobEvents(int mobMask, int dataEventOffset) { @@ -232,7 +245,9 @@ int Script::scanMobEventsWithItem(int mobMask, int dataEventOffset, int itemMask return -1; } -void Script::installSingleBackAnim(Common::Array &backAnimList, int slot, int offset) { +void Script::installSingleBackAnim(Common::Array &backAnimList, int slot, int roomBackAnimOffset) { + + int offset = roomBackAnimOffset + slot * 4; BackgroundAnim newBackgroundAnim; @@ -311,20 +326,15 @@ void Script::installSingleBackAnim(Common::Array &backAnimList, } } -void Script::installBackAnims(Common::Array &backAnimList, int offset) { +void Script::installBackAnims(Common::Array &backAnimList, int roomBackAnimOffset) { for (int i = 0; i < _vm->kMaxBackAnims; i++) { - installSingleBackAnim(backAnimList, i, offset); - offset += 4; + installSingleBackAnim(backAnimList, i, roomBackAnimOffset); } } void Script::installObjects(int offset) { for (int i = 0; i < _vm->kMaxObjects; i++) { - if (_data[offset] != 0xFF) { - _vm->_objSlot[i] = i; - } else { - _vm->_objSlot[i] = -1; - } + _vm->_objSlot[i] = _data[offset]; offset++; } } @@ -382,11 +392,11 @@ void InterpreterFlags::resetAllFlags() { } void InterpreterFlags::setFlagValue(Flags::Id flagId, uint32 value) { - _flags[(uint32)flagId - FLAG_MASK] = value; + _flags[(uint32)flagId - kFlagMask] = value; } uint32 InterpreterFlags::getFlagValue(Flags::Id flagId) { - return _flags[(uint32)flagId - FLAG_MASK]; + return _flags[(uint32)flagId - kFlagMask]; } Interpreter::Interpreter(PrinceEngine *vm, Script *script, InterpreterFlags *flags) : @@ -497,6 +507,14 @@ void Interpreter::setResult(byte value) { _result = value; } +void Interpreter::setBgOpcodePC(uint32 value) { + _bgOpcodePC = value; +} + +void Interpreter::setFgOpcodePC(uint32 value) { + _fgOpcodePC = value; +} + template T Interpreter::readScript() { T data = _script->read(_currentInstruction); @@ -506,7 +524,7 @@ T Interpreter::readScript() { uint16 Interpreter::readScriptFlagValue() { uint16 value = readScript(); - if (value & InterpreterFlags::FLAG_MASK) { + if (value & InterpreterFlags::kFlagMask) { return _flags->getFlagValue((Flags::Id)value); } return value; @@ -567,8 +585,7 @@ void Interpreter::O_PUTOBJECT() { uint16 objectId = readScriptFlagValue(); Room *room = new Room(); room->loadRoom(_script->getRoomOffset(roomId)); - int offset = room->_obj + slot; - _vm->_script->setObjId(offset, objectId); + _vm->_script->setObjId(room->_obj, slot, objectId); if (_vm->_locationNr == roomId) { _vm->_objSlot[slot] = objectId; } @@ -581,10 +598,9 @@ void Interpreter::O_REMOBJECT() { uint16 slot = readScriptFlagValue(); Room *room = new Room(); room->loadRoom(_script->getRoomOffset(roomId)); - int offset = room->_obj + slot; - _vm->_script->setObjId(offset, 0xFF); + _vm->_script->setObjId(room->_obj, slot, 0xFF); if (_vm->_locationNr == roomId) { - _vm->_objSlot[slot] = -1; + _vm->_objSlot[slot] = 0xFF; } delete room; debugInterpreter("O_REMOBJECT roomId %d slot %d", roomId, slot); @@ -653,10 +669,9 @@ void Interpreter::O_PUTBACKANIM() { int32 animId = readScript(); Room *room = new Room(); room->loadRoom(_script->getRoomOffset(roomId)); - int offset = room->_backAnim + slot * 4; - _vm->_script->setBackAnimId(offset, animId); + _vm->_script->setBackAnimId(room->_backAnim, slot, animId); if (_vm->_locationNr == roomId) { - _vm->_script->installSingleBackAnim(_vm->_backAnimList, slot, offset); + _vm->_script->installSingleBackAnim(_vm->_backAnimList, slot, room->_backAnim); } delete room; debugInterpreter("O_PUTBACKANIM roomId %d, slot %d, animId %d", roomId, slot, animId); @@ -670,8 +685,7 @@ void Interpreter::O_REMBACKANIM() { } Room *room = new Room(); room->loadRoom(_script->getRoomOffset(roomId)); - int offset = room->_backAnim + slot * 4; - _vm->_script->setBackAnimId(offset, 0); + _vm->_script->setBackAnimId(room->_backAnim, slot, 0); delete room; debugInterpreter("O_REMBACKANIM roomId %d, slot %d", roomId, slot); } @@ -1019,22 +1033,24 @@ void Interpreter::O_CLSTEXT() { debugInterpreter("O_CLSTEXT slot %d", slot); } -// TODO - check if need this for saving void Interpreter::O_CALLTABLE() { - uint16 flag = readScript(); - int32 table = readScript(); - - debugInterpreter("O_CALLTABLE flag %d, table %d", flag, table); - // makes a call from script function table - // must read table pointer from _code and - // use table entry as next opcode + Flags::Id flagId = readScriptFlagId(); + int roomNr = _flags->getFlagValue(flagId); + int32 tableOffset = readScript(); + int initLocationScript = _script->getLocationInitScript(tableOffset, roomNr); + if (initLocationScript) { + _stack[_stacktop] = _currentInstruction; + _stacktop++; + _currentInstruction = initLocationScript; + } + debugInterpreter("O_CALLTABLE loc %d", roomNr); } void Interpreter::O_CHANGEMOB() { uint16 mob = readScriptFlagValue(); uint16 value = readScriptFlagValue(); value ^= 1; - _vm->_script->setMobVisible(mob, value); + _vm->_script->setMobVisible(_vm->_room->_mobs, mob, value); _vm->_mobList[mob]._visible = value; debugInterpreter("O_CHANGEMOB mob %d, value %d", mob, value); } @@ -1527,7 +1543,7 @@ void Interpreter::O_BACKANIMRANGE() { uint16 low = readScriptFlagValue(); uint16 high = readScriptFlagValue(); if (animId != 0xFFFF) { - if (animId & InterpreterFlags::FLAG_MASK) { + if (animId & InterpreterFlags::kFlagMask) { animId = _flags->getFlagValue((Flags::Id)animId); } } diff --git a/engines/prince/script.h b/engines/prince/script.h index 04f125a8ea0e..6ebef3d94b77 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -96,6 +96,8 @@ class Room { class Script { public: + static const int16 kMaxRooms = 60; + Script(PrinceEngine *vm); ~Script(); @@ -133,23 +135,30 @@ class Script { } uint32 getStartGameOffset(); + uint32 getLocationInitScript(int initRoomTableOffset, int roomNr); int16 getLightX(int locationNr); int16 getLightY(int locationNr); int32 getShadowScale(int locationNr); uint8 *getRoomOffset(int locationNr); int32 getOptionStandardOffset(int option); uint8 *getHeroAnimName(int offset); - void setBackAnimId(int offset, int animId); - void setObjId(int offset, int objId); - void installBackAnims(Common::Array &backAnimList, int offset); - void installSingleBackAnim(Common::Array &backAnimList, int slot, int offset); + + void installBackAnims(Common::Array &backAnimList, int roomBackAnimOffset); + void installSingleBackAnim(Common::Array &backAnimList, int slot, int roomBackAnimOffset); void installObjects(int offset); bool loadAllMasks(Common::Array &maskList, int offset); int scanMobEvents(int mobMask, int dataEventOffset); int scanMobEventsWithItem(int mobMask, int dataEventOffset, int itemMask); - bool getMobVisible(int mob); - void setMobVisible(int mob, int value); + + byte getMobVisible(int roomMobOffset, uint16 mob); + void setMobVisible(int roomMobOffset, uint16 mob, byte value); + + uint32 getBackAnimId(int roomBackAnimOffset, int slot); + void setBackAnimId(int roomBackAnimOffset, int slot, int animId); + + byte getObjId(int roomObjOffset, int slot); + void setObjId(int roomObjOffset, int slot, byte objectId); const char *getString(uint32 offset) { return (const char *)(&_data[offset]); @@ -171,11 +180,10 @@ class InterpreterFlags { void resetAllFlags(); - static const uint16 FLAG_MASK = 0x8000; - + static const uint16 kFlagMask = 0x8000; + static const uint16 kMaxFlags = 2000; private: - static const uint16 MAX_FLAGS = 2000; - int32 _flags[MAX_FLAGS]; + int32 _flags[kMaxFlags]; }; class Interpreter { @@ -189,6 +197,9 @@ class Interpreter { int getLastOPCode(); int getFgOpcodePC(); + void setBgOpcodePC(uint32 value); + void setFgOpcodePC(uint32 value); + uint32 getCurrentString(); void setCurrentString(uint32 value); From 4a022e77f75c69702708dc49de44f9e844569d05 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 29 Jul 2014 04:10:19 +0200 Subject: [PATCH 299/374] PRINCE: syncGame() fix --- engines/prince/saveload.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/prince/saveload.cpp b/engines/prince/saveload.cpp index 83d45a4bd794..4bf41b43c1f6 100644 --- a/engines/prince/saveload.cpp +++ b/engines/prince/saveload.cpp @@ -280,7 +280,7 @@ void PrinceEngine::syncGame(Common::SeekableReadStream *readStream, Common::Writ // Background animations for (int backAnimSlot = 0; backAnimSlot < kMaxBackAnims; backAnimSlot++) { - uint32 value = _script->getBackAnimId(_room->_backAnim, backAnimSlot); + uint32 value = _script->getBackAnimId(room->_backAnim, backAnimSlot); s.syncAsUint32LE(value); } @@ -374,7 +374,7 @@ void PrinceEngine::syncGame(Common::SeekableReadStream *readStream, Common::Writ for (int backAnimSlot = 0; backAnimSlot < kMaxBackAnims; backAnimSlot++) { uint32 value = 0; s.syncAsUint32LE(value); - _script->setBackAnimId(_room->_backAnim, backAnimSlot, value); + _script->setBackAnimId(room->_backAnim, backAnimSlot, value); } // Objects From 956b98903fe704f0388538741c539567476bd745 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 29 Jul 2014 04:10:54 +0200 Subject: [PATCH 300/374] PRINCE: enableOptions() - update for inventory items --- engines/prince/prince.cpp | 51 +++++++++++++++++++++------------------ engines/prince/prince.h | 2 +- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index fe2f398b8571..3f0527fc02a5 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2382,7 +2382,7 @@ void PrinceEngine::rightMouseButton() { _secondHero->freeOldMove(); _interpreter->storeNewPC(0); if (_currentPointerNumber < 2) { - enableOptions(); + enableOptions(true); } else { _currentPointerNumber = 1; changeCursor(1); @@ -2536,38 +2536,41 @@ void PrinceEngine::inventoryLeftMouseButton() { void PrinceEngine::inventoryRightMouseButton() { if (_textSlots[0]._str == nullptr) { - enableOptions(); + enableOptions(false); } } -void PrinceEngine::enableOptions() { +void PrinceEngine::enableOptions(bool checkType) { if (_optionsFlag != 1) { changeCursor(1); _currentPointerNumber = 1; if (_selectedMob != -1) { - if (_mobList[_selectedMob]._type != 0x100) { - 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; + if (checkType) { + if (_mobList[_selectedMob]._type == 0x100) { + return; } - _optionsMob = _selectedMob; - _optionsX = x1; - _optionsY = y1; - _optionsFlag = 1; } + 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; } } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 64f981cdb68b..eef583222f8e 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -422,7 +422,7 @@ class PrinceEngine : public Engine { void swapInv(int heroId); void addInvObj(); void makeInvCursor(int itemNr); - void enableOptions(); + void enableOptions(bool checkType); void checkOptions(); void checkInvOptions(); From 93a552c26d2323321356ddb9cdd3400769100617 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 30 Jul 2014 19:54:39 +0200 Subject: [PATCH 301/374] PRINCE: Skull mini-game fix --- engines/prince/graphics.cpp | 23 ++++++++++++++++ engines/prince/graphics.h | 1 + engines/prince/object.cpp | 6 ++--- engines/prince/object.h | 4 +-- engines/prince/prince.cpp | 36 ++++++++++++------------- engines/prince/script.cpp | 52 +++++++++++++++++++++---------------- engines/prince/script.h | 6 ++--- 7 files changed, 79 insertions(+), 49 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 9b8c8746426b..195c61b5f051 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -230,6 +230,29 @@ void GraphicsMan::drawAsShadowDrawNode(Graphics::Surface *screen, DrawNode *draw } } +void GraphicsMan::drawBackSpriteDrawNode(Graphics::Surface *screen, DrawNode *drawNode) { + byte *src1 = (byte *)drawNode->s->getBasePtr(0, 0); + byte *dst1 = (byte *)screen->getBasePtr(drawNode->posX, drawNode->posY); + + for (int y = 0; y < drawNode->s->h; y++) { + byte *src2 = src1; + byte *dst2 = dst1; + for (int x = 0; x < drawNode->s->w; x++, src2++, dst2++) { + if (*src2 != 255) { + if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { + if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { + if (*dst2 == 255) { + *dst2 = *src2; + } + } + } + } + } + src1 += drawNode->s->pitch; + dst1 += screen->pitch; + } +} + void GraphicsMan::drawPixel(Graphics::Surface *screen, int32 posX, int32 posY) { byte *dst = (byte *)screen->getBasePtr(posX, posY); *dst = 255; diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index e5d0ea99adcb..f4e7f37d892a 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -52,6 +52,7 @@ class GraphicsMan { static void drawTransparentDrawNode(Graphics::Surface *screen, DrawNode *drawNode); static void drawAsShadowDrawNode(Graphics::Surface *screen, DrawNode *drawNode); static void drawMaskDrawNode(Graphics::Surface *screen, DrawNode *drawNode); + static void drawBackSpriteDrawNode(Graphics::Surface *screen, DrawNode *drawNode); byte getBlendTableColor(byte pixelColor, byte backgroundPixelColor, byte *blendTable); diff --git a/engines/prince/object.cpp b/engines/prince/object.cpp index c8cdc7508315..7e4bd1bbeeb8 100644 --- a/engines/prince/object.cpp +++ b/engines/prince/object.cpp @@ -68,7 +68,7 @@ bool Object::loadFromStream(Common::SeekableReadStream &stream) { if (x == 0xFFFF) return false; _x = x; - _y = stream.readUint16LE(); + _y = stream.readSint16LE(); // skull mini-game has some signed y coords const Common::String obStreamName = Common::String::format("OB%02d", stream.readUint16LE()); Common::SeekableReadStream *obStream = SearchMan.createReadStreamForMember(obStreamName); @@ -87,7 +87,7 @@ bool Object::loadFromStream(Common::SeekableReadStream &stream) { return true; } -void Object::setData(AttrId dataId, uint16 value) { +void Object::setData(AttrId dataId, int32 value) { switch (dataId) { case kObjectX: _x = value; @@ -100,7 +100,7 @@ void Object::setData(AttrId dataId, uint16 value) { } } -uint16 Object::getData(AttrId dataId) { +int32 Object::getData(AttrId dataId) { switch (dataId) { case kObjectX: return _x; diff --git a/engines/prince/object.h b/engines/prince/object.h index 4a67336c5f23..31e88ac9e4c8 100644 --- a/engines/prince/object.h +++ b/engines/prince/object.h @@ -57,8 +57,8 @@ class Object { bool loadFromStream(Common::SeekableReadStream &stream); Graphics::Surface *getSurface() const { return _surface; } - uint16 getData(AttrId dataId); - void setData(AttrId dataId, uint16 value); + int32 getData(AttrId dataId); + void setData(AttrId dataId, int32 value); private: void loadSurface(Common::SeekableReadStream &stream); diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 3f0527fc02a5..17517992be2e 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1710,25 +1710,25 @@ void PrinceEngine::showObjects() { if (objSurface != nullptr) { if (spriteCheck(objSurface->w, objSurface->h, _objList[nr]->_x, _objList[nr]->_y)) { - if ((_objList[i]->_flags & 0x0200) == 0) { - 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; - newDrawNode.data = nullptr; - newDrawNode.freeSurfaceSMemory = false; - newDrawNode.drawFunction = &_graph->drawTransparentDrawNode; - _drawNodeList.push_back(newDrawNode); + 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; + newDrawNode.data = nullptr; + newDrawNode.freeSurfaceSMemory = false; + + if ((_objList[nr]->_flags & 0x2000)) { + newDrawNode.drawFunction = &_graph->drawBackSpriteDrawNode; } else { - // showBackSprite(); - error("showBackSprite() - showObjects"); + newDrawNode.drawFunction = &_graph->drawTransparentDrawNode; } + _drawNodeList.push_back(newDrawNode); } if ((_objList[nr]->_flags & 1)) { @@ -2546,7 +2546,7 @@ void PrinceEngine::enableOptions(bool checkType) { _currentPointerNumber = 1; if (_selectedMob != -1) { if (checkType) { - if (_mobList[_selectedMob]._type == 0x100) { + if (_mobList[_selectedMob]._type & 0x100) { return; } } diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 57d0b8a77082..9dbab2f7e42c 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -391,11 +391,11 @@ void InterpreterFlags::resetAllFlags() { memset(_flags, 0, sizeof(_flags)); } -void InterpreterFlags::setFlagValue(Flags::Id flagId, uint32 value) { +void InterpreterFlags::setFlagValue(Flags::Id flagId, int32 value) { _flags[(uint32)flagId - kFlagMask] = value; } -uint32 InterpreterFlags::getFlagValue(Flags::Id flagId) { +int32 InterpreterFlags::getFlagValue(Flags::Id flagId) { return _flags[(uint32)flagId - kFlagMask]; } @@ -522,7 +522,7 @@ T Interpreter::readScript() { return data; } -uint16 Interpreter::readScriptFlagValue() { +int16 Interpreter::readScriptFlagValue() { uint16 value = readScript(); if (value & InterpreterFlags::kFlagMask) { return _flags->getFlagValue((Flags::Id)value); @@ -806,7 +806,7 @@ void Interpreter::O_CHANGEANIMTYPE() { void Interpreter::O__SETFLAG() { Flags::Id flagId = readScriptFlagId(); - uint16 value = readScriptFlagValue(); + int16 value = readScriptFlagValue(); _flags->setFlagValue((Flags::Id)(flagId), value); debugInterpreter("O__SETFLAG 0x%04X (%s) = %d", flagId, Flags::getFlagName(flagId), value); } @@ -844,7 +844,7 @@ void Interpreter::O_EXIT() { void Interpreter::O_ADDFLAG() { Flags::Id flagId = readScriptFlagId(); - uint16 value = readScriptFlagValue(); + int16 value = readScriptFlagValue(); _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) + value); if (_flags->getFlagValue(flagId)) { _result = 1; @@ -864,7 +864,7 @@ void Interpreter::O_TALKANIM() { void Interpreter::O_SUBFLAG() { Flags::Id flagId = readScriptFlagId(); - uint16 value = readScriptFlagValue(); + int16 value = readScriptFlagValue(); _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) - value); if (_flags->getFlagValue(flagId)) { _result = 1; @@ -894,7 +894,7 @@ void Interpreter::O_SETSTRING() { void Interpreter::O_ANDFLAG() { Flags::Id flagId = readScriptFlagId(); - uint16 value = readScriptFlagValue(); + int16 value = readScriptFlagValue(); _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) & value); if (_flags->getFlagValue(flagId)) { _result = 1; @@ -915,7 +915,7 @@ void Interpreter::O_GETMOBDATA() { void Interpreter::O_ORFLAG() { Flags::Id flagId = readScriptFlagId(); - uint16 value = readScriptFlagValue(); + int16 value = readScriptFlagValue(); _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) | value); if (_flags->getFlagValue(flagId)) { _result = 1; @@ -935,7 +935,7 @@ void Interpreter::O_SETMOBDATA() { void Interpreter::O_XORFLAG() { Flags::Id flagId = readScriptFlagId(); - uint16 value = readScriptFlagValue(); + int16 value = readScriptFlagValue(); _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) ^ value); if (_flags->getFlagValue(flagId)) { _result = 1; @@ -1113,8 +1113,8 @@ void Interpreter::O_RUNACTION() { void Interpreter::O_COMPAREHI() { Flags::Id flag = readScriptFlagId(); - uint16 value = readScriptFlagValue(); - uint16 flagValue = _flags->getFlagValue(flag); + int16 value = readScriptFlagValue(); + int16 flagValue = _flags->getFlagValue(flag); if (flagValue > value) { _result = 0; } else { @@ -1125,8 +1125,8 @@ void Interpreter::O_COMPAREHI() { void Interpreter::O_COMPARELO() { Flags::Id flag = readScriptFlagId(); - uint16 value = readScriptFlagValue(); - uint16 flagValue = _flags->getFlagValue(flag); + int16 value = readScriptFlagValue(); + int16 flagValue = _flags->getFlagValue(flag); if (flagValue < value) { _result = 0; } else { @@ -1374,19 +1374,25 @@ void Interpreter::O_SETSTRINGOFFSET() { void Interpreter::O_GETOBJDATA() { Flags::Id flag = readScriptFlagId(); - uint16 obj = readScriptFlagValue(); - int16 objOffset = readScriptFlagValue(); - int16 value = _vm->_objList[obj]->getData((Object::AttrId)objOffset); - _flags->setFlagValue(flag, value); - debugInterpreter("O_GETOBJDATA flag %d, obj %d, objOffset %d", flag, obj, objOffset); + uint16 slot = readScriptFlagValue(); + uint16 objOffset = readScriptFlagValue(); + int nr = _vm->_objSlot[slot]; + if (nr != 0xFF) { + int16 value = _vm->_objList[nr]->getData((Object::AttrId)objOffset); + _flags->setFlagValue(flag, value); + } + debugInterpreter("O_GETOBJDATA flag %d, objSlot %d, objOffset %d", flag, slot, objOffset); } void Interpreter::O_SETOBJDATA() { - uint16 obj = readScriptFlagValue(); - int16 objOffset = readScriptFlagValue(); - uint16 value = readScriptFlagValue(); - _vm->_objList[obj]->setData((Object::AttrId)objOffset, value); - debugInterpreter("O_SETOBJDATA obj %d, objOffset %d, value %d", obj, objOffset, value); + uint16 slot = readScriptFlagValue(); + uint16 objOffset = readScriptFlagValue(); + int16 value = readScriptFlagValue(); + int nr = _vm->_objSlot[slot]; + if (nr != 0xFF) { + _vm->_objList[nr]->setData((Object::AttrId)objOffset, value); + } + debugInterpreter("O_SETOBJDATA objSlot %d, objOffset %d, value %d", slot, objOffset, value); } // Not used in script diff --git a/engines/prince/script.h b/engines/prince/script.h index 6ebef3d94b77..57f926859891 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -175,8 +175,8 @@ class InterpreterFlags { public: InterpreterFlags(); - void setFlagValue(Flags::Id flag, uint32 value); - uint32 getFlagValue(Flags::Id flag); + void setFlagValue(Flags::Id flag, int32 value); + int32 getFlagValue(Flags::Id flag); void resetAllFlags(); @@ -243,7 +243,7 @@ class Interpreter { // Helper functions uint32 step(uint32 opcodePC); - uint16 readScriptFlagValue(); + int16 readScriptFlagValue(); Flags::Id readScriptFlagId(); int checkSeq(byte *string); From 464aea3c36ab7e7d12453cc732fc8042235744ac Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 30 Jul 2014 20:50:23 +0200 Subject: [PATCH 302/374] PRINCE: Inventory opening - mainLoop() update --- engines/prince/prince.cpp | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 17517992be2e..7f51fb284e16 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -4495,26 +4495,24 @@ void PrinceEngine::mainLoop() { _frameNr++; // inventory turning on: - if (!_optionsFlag && _mouseFlag) { - Common::Point mousePos = _system->getEventManager()->getMousePos(); - if (mousePos.y < 4 && !_showInventoryFlag) { - _invCounter++; - } else { - _invCounter = 0; - } - if (_invCounter >= _invMaxCount) { - if (_flags->getFlagValue(Flags::INVALLOWED) != 1) { - // 29 - Basement, 50 - Map, 59 - Intro - if (_locationNr != 29 && _locationNr != 50 && _locationNr != 59) { - inventoryFlagChange(true); + if (!_optionsFlag && _mouseFlag == 1) { + 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); + } } } } } - if (_debugger->_locationNr != _locationNr) - loadLocation(_debugger->_locationNr); - if (_debugger->_cursorNr != _cursorNr) - changeCursor(_debugger->_cursorNr); } } From e81acaf68be0d8dc5388dc978972e2dbbce7799c Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 30 Jul 2014 21:58:36 +0200 Subject: [PATCH 303/374] PRINCE: Mob exam texts loading - location 58 fix --- engines/prince/mob.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/engines/prince/mob.cpp b/engines/prince/mob.cpp index 27d7127ccddc..7ed4f581036f 100644 --- a/engines/prince/mob.cpp +++ b/engines/prince/mob.cpp @@ -62,10 +62,14 @@ bool Mob::loadFromStream(Common::SeekableReadStream &stream) { stream.seek(examTextOffset); _examText.clear(); - do { - c = stream.readByte(); + c = stream.readByte(); + if (c) { _examText += c; - } while (c != 255); + do { + c = stream.readByte(); + _examText += c; + } while (c != 255); + } stream.seek(pos + 32); return true; From 1b5d3e00a375acec452aee3a34fe7d508bbab4be Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 30 Jul 2014 23:44:45 +0200 Subject: [PATCH 304/374] PRINCE: FLC animations - update --- engines/prince/prince.cpp | 3 ++- engines/prince/script.cpp | 24 ++++++++---------------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 7f51fb284e16..3fe43e6ed977 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -737,7 +737,7 @@ void PrinceEngine::setVoice(uint16 slot, uint32 sampleSlot, uint16 flag) { bool PrinceEngine::loadAnim(uint16 animNr, bool loop) { Common::String streamName = Common::String::format("AN%02d", animNr); - Common::SeekableReadStream * flicStream = SearchMan.createReadStreamForMember(streamName); + Common::SeekableReadStream *flicStream = SearchMan.createReadStreamForMember(streamName); if (!flicStream) { error("Can't open %s", streamName.c_str()); @@ -2299,6 +2299,7 @@ void PrinceEngine::moveRunHero(int heroId, int x, int y, int dir, bool runHeroFl } void PrinceEngine::leftMouseButton() { + _flags->setFlagValue(Flags::LMOUSE, 1); if (_mouseFlag) { int option = 0; int optionEvent = -1; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 9dbab2f7e42c..cf45d50fdbb3 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1703,29 +1703,21 @@ void Interpreter::O_CHECKFLCFRAME() { uint16 frameNr = readScriptFlagValue(); debugInterpreter("O_CHECKFLCFRAME frame number %d", frameNr); if (_vm->_flicPlayer.getCurFrame() != frameNr) { - // Move instruction pointer before current instruction - // must do this check once again till it's false - _currentInstruction -= 2; + _currentInstruction -= 4; _opcodeNF = 1; } } void Interpreter::O_CHECKFLCEND() { - - //debugInterpreter("O_CHECKFLCEND"); - const Video::FlicDecoder &flicPlayer = _vm->_flicPlayer; - - //debug("frameCount %d, currentFrame %d", flicPlayer.getFrameCount(), flicPlayer.getCurFrame()); - + debugInterpreter("O_CHECKFLCEND frameCount %d, currentFrame %d", flicPlayer.getFrameCount(), flicPlayer.getCurFrame()); if (flicPlayer.getFrameCount() - flicPlayer.getCurFrame() > 1) { - // Move instruction pointer before current instruciton - // must do this check once again till it's false _currentInstruction -= 2; _opcodeNF = 1; } } +// TODO void Interpreter::O_FREEFLC() { debugInterpreter("O_FREEFLC"); } @@ -1828,14 +1820,14 @@ void Interpreter::O_SETVOICED() { } void Interpreter::O_VIEWFLCLOOP() { - uint16 value = readScriptFlagValue(); - _vm->loadAnim(value, true); - debugInterpreter("O_VIEWFLCLOOP animId %d", value); + uint16 animId = readScriptFlagValue(); + _vm->loadAnim(animId, true); + debugInterpreter("O_VIEWFLCLOOP animId %d", animId); } +// Not used in script void Interpreter::O_FLCSPEED() { - uint16 speed = readScriptFlagValue(); - debugInterpreter("O_FLCSPEED speed %d", speed); + error("O_FLCSPEED speed %d"); } void Interpreter::O_OPENINVENTORY() { From 08dd3f6d3724bd353f8fd9df2c0510a8600ff011 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 31 Jul 2014 00:09:12 +0200 Subject: [PATCH 305/374] PRINCE: showHero() - kHeroStateRun fix --- engines/prince/hero.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 6b4cafa968f2..3b5403532c87 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -781,7 +781,7 @@ void Hero::showHero() { int x, y, dir; - if (_state == kHeroStateMove) { + if (_state == kHeroStateMove || _state == kHeroStateRun) { //go_for_it: while (1) { if (_currCoords != nullptr) { From 60881987d058ad92366aa7fc0767f9f55d33fca4 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 31 Jul 2014 05:29:03 +0200 Subject: [PATCH 306/374] PRINCE: Animations - update --- engines/prince/animation.cpp | 179 ++++++++++++++++++++--------------- engines/prince/animation.h | 35 ++++--- engines/prince/graphics.cpp | 2 +- engines/prince/graphics.h | 1 - engines/prince/hero.cpp | 8 +- engines/prince/prince.cpp | 71 +++++--------- engines/prince/prince.h | 6 +- 7 files changed, 155 insertions(+), 147 deletions(-) diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index ac0d0585e1dd..f5beb8674fce 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -29,132 +29,155 @@ namespace Prince { bool Animation::loadFromStream(Common::SeekableReadStream &stream) { - _dataSize = stream.size(); - _data = (byte *)malloc(_dataSize); - - if (stream.read(_data, _dataSize) != _dataSize) { - free(_data); - return false; + _idXDiff = stream.readByte(); + _idYDiff = stream.readByte(); + _loopCount = stream.readUint16LE(); + _phaseCount = stream.readUint16LE(); + stream.skip(2); // skip _frameCount here + _baseX = stream.readUint16LE(); + _baseY = stream.readUint16LE(); + uint32 phaseTableOffset = stream.readUint32LE(); + uint32 tableOfFrameOffsets = stream.pos(); + + stream.seek(phaseTableOffset); + Phase tempPhase; + _frameCount = 0; + for (int phase = 0; phase < _phaseCount; phase++) { + tempPhase._phaseOffsetX = stream.readSint16LE(); + tempPhase._phaseOffsetY = stream.readSint16LE(); + tempPhase._phaseToFrameIndex = stream.readUint16LE(); + if (tempPhase._phaseToFrameIndex > _frameCount) { + _frameCount = tempPhase._phaseToFrameIndex; + } + _phaseList.push_back(tempPhase); + stream.skip(2); + } + if (_phaseCount) { + _frameCount++; } - return true; -} -Animation::Animation(): _data(NULL) { + for (int frame = 0; frame < _frameCount; frame++) { + stream.seek(tableOfFrameOffsets + frame * 4); + uint32 frameInfoOffset = stream.readUint32LE(); + stream.seek(frameInfoOffset); + uint16 frameWidth = stream.readUint16LE(); + uint16 frameHeight = stream.readUint16LE(); + uint32 frameDataPos = stream.pos(); + uint32 frameDataOffset = stream.readUint32BE(); + + Graphics::Surface *surf = new Graphics::Surface(); + surf->create(frameWidth, frameHeight, Graphics::PixelFormat::createFormatCLUT8()); + if (frameDataOffset == MKTAG('m', 'a', 's', 'm')) { + // Compressed + Decompressor dec; + uint32 ddataSize = stream.readUint32LE(); + byte *data = (byte *)malloc(ddataSize); + byte *ddata = (byte *)malloc(ddataSize); + + stream.read(data, ddataSize); + dec.decompress(data, ddata, ddataSize); + for (uint16 i = 0; i < frameHeight; i++) { + memcpy(surf->getBasePtr(0, i), ddata + frameWidth * i, frameWidth); + } + free(ddata); + free(data); + } else { + stream.seek(frameDataPos); + // Uncompressed + for (uint16 i = 0; i < frameHeight; i++) { + stream.read(surf->getBasePtr(0, i), frameWidth); + } + } + _frameList.push_back(surf); + } + return true; } -Animation::Animation(byte *data, uint32 dataSize) - : _data(data), _dataSize(dataSize) { +Animation::Animation() : _idXDiff(0), _idYDiff(0), _loopCount(0), _phaseCount(0), _frameCount(0), _baseX(0), _baseY(0) +{ } Animation::~Animation() { - free(_data); + clear(); } void Animation::clear() { - if (_data != NULL) { - free(_data); + _phaseList.clear(); + for (int i = 0; i < _frameCount; i++) { + _frameList[i]->free(); + delete _frameList[i]; + _frameList[i] = nullptr; } } -// AH_ID - TODO - if need this fix endianess bool Animation::testId() const { - char id[2]; - id[0] = (char)READ_LE_UINT16(_data); - id[1] = (char)READ_LE_UINT16(_data + 1); - if (id[0] == 'A' && id[1] == 'N') { - return true; // normal animation + if (_idXDiff == 'A' && _idYDiff == 'N') { + return true; } return false; } -// AH_ID - x diff int8 Animation::getIdXDiff() const { - return (int8)READ_LE_UINT16(_data); + return _idXDiff; } -// AH_ID - y diff int8 Animation::getIdYDiff() const { - return (int8)READ_LE_UINT16(_data + 1); + return _idYDiff; } -// AH_Loop int16 Animation::getLoopCount() const { - return READ_LE_UINT16(_data + 2); + return _loopCount; } -// AH_Fazy int32 Animation::getPhaseCount() const { - return READ_LE_UINT16(_data + 4); + return _phaseCount; } -// AH_Ramki int32 Animation::getFrameCount() const { - return READ_LE_UINT16(_data + 6); + return _frameCount; } -// AH_X int16 Animation::getBaseX() const { - return READ_LE_UINT16(_data + 8); + return _baseX; } -// AH_Y int16 Animation::getBaseY() const { - return READ_LE_UINT16(_data + 10); -} - -byte *Animation::getPhaseEntry(uint phaseIndex) const { - return _data + READ_LE_UINT32(_data + 12) + phaseIndex * 8; -} - -int16 Animation::getPhaseOffsetX(uint phaseIndex) const { - return READ_LE_UINT16(getPhaseEntry(phaseIndex) + 0); + return _baseY; } -int16 Animation::getPhaseOffsetY(uint phaseIndex) const { - return READ_LE_UINT16(getPhaseEntry(phaseIndex) + 2); -} - -int16 Animation::getPhaseFrameIndex(uint phaseIndex) const { - return READ_LE_UINT16(getPhaseEntry(phaseIndex) + 4); +int16 Animation::getPhaseOffsetX(int phaseIndex) const { + if (phaseIndex < _phaseCount) { + return _phaseList[phaseIndex]._phaseOffsetX; + } else { + error("getPhaseOffsetX() phaseIndex: %d, phaseCount: %d", phaseIndex, _phaseCount); + } } -int16 Animation::getFrameWidth(uint frameIndex) const { - byte *frameData = _data + READ_LE_UINT32(_data + 16 + frameIndex * 4); - return READ_LE_UINT16(frameData + 0); +int16 Animation::getPhaseOffsetY(int phaseIndex) const { + if (phaseIndex < _phaseCount) { + return _phaseList[phaseIndex]._phaseOffsetY; + } else { + error("getPhaseOffsetY() phaseIndex: %d, phaseCount: %d", phaseIndex, _phaseCount); + } } -int16 Animation::getFrameHeight(uint frameIndex) const { - byte *frameData = _data + READ_LE_UINT32(_data + 16 + frameIndex * 4); - return READ_LE_UINT16(frameData + 2); +int16 Animation::getPhaseFrameIndex(int phaseIndex) const { + if (phaseIndex < _phaseCount) { + return _phaseList[phaseIndex]._phaseToFrameIndex; + } else { + error("getPhaseFrameIndex() phaseIndex: %d, phaseCount: %d", phaseIndex, _phaseCount); + } } -Graphics::Surface *Animation::getFrame(uint frameIndex) { - byte *frameData = _data + READ_LE_UINT32(_data + 16 + frameIndex * 4); - int16 width = READ_LE_UINT16(frameData + 0); - int16 height = READ_LE_UINT16(frameData + 2); - //debug("width = %d; height = %d", width, height); - Graphics::Surface *surf = new Graphics::Surface(); - surf->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); - //debug("frameData %p", frameData); - if (READ_BE_UINT32(frameData + 4) == MKTAG('m', 'a', 's', 'm')) { - // Compressed - Decompressor dec; - uint32 ddataSize = READ_LE_UINT32(frameData + 8); - byte *ddata = (byte *)malloc(ddataSize); - dec.decompress(frameData + 12, ddata, ddataSize); - for (uint16 i = 0; i < height; i++) { - memcpy(surf->getBasePtr(0, i), ddata + width * i, width); - } - free(ddata); +Graphics::Surface *Animation::getFrame(int frameIndex) { + if (frameIndex < _frameCount) { + return _frameList[frameIndex]; } else { - // Uncompressed - for (uint16 i = 0; i < height; i++) { - memcpy(surf->getBasePtr(0, i), frameData + 4 + width * i, width); - } + error("getFrame() frameIndex: %d, frameCount: %d", frameIndex, _frameCount); } - return surf; -} } +} // End of namespace Prince + /* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/animation.h b/engines/prince/animation.h index 09ebf7d8b94c..23a1b5808a22 100644 --- a/engines/prince/animation.h +++ b/engines/prince/animation.h @@ -32,32 +32,39 @@ namespace Prince { class Animation { public: - bool loadFromStream(Common::SeekableReadStream &stream); - Animation(); - Animation(byte *data, uint32 dataSize); ~Animation(); + bool loadFromStream(Common::SeekableReadStream &stream); + bool testId() const; int8 getIdXDiff() const; int8 getIdYDiff() const; int16 getLoopCount() const; - int16 getBaseX() const; - int16 getBaseY() const; int32 getPhaseCount() const; int32 getFrameCount() const; - int16 getPhaseOffsetX(uint phaseIndex) const; - int16 getPhaseOffsetY(uint phaseIndex) const; - int16 getPhaseFrameIndex(uint phaseIndex) const; - Graphics::Surface *getFrame(uint frameIndex); - int16 getFrameWidth(uint frameIndex) const; - int16 getFrameHeight(uint frameIndex) const; + int16 getBaseX() const; + int16 getBaseY() const; + int16 getPhaseOffsetX(int phaseIndex) const; + int16 getPhaseOffsetY(int phaseIndex) const; + int16 getPhaseFrameIndex(int phaseIndex) const; + Graphics::Surface *getFrame(int frameIndex); void clear(); private: + struct Phase { + int16 _phaseOffsetX; + int16 _phaseOffsetY; + uint16 _phaseToFrameIndex; + }; Common::Array _frameList; - byte *_data; - uint32 _dataSize; - byte *getPhaseEntry(uint phaseIndex) const; + Common::Array _phaseList; + int8 _idXDiff; + int8 _idYDiff; + int16 _loopCount; + int16 _phaseCount; + int32 _frameCount; + int16 _baseX; + int16 _baseY; }; } diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 195c61b5f051..58ab7b0f21c4 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -381,6 +381,6 @@ void GraphicsMan::makeShadowTable(int brightness, byte *shadowPalette) { } } -} +} // End of namespace Prince /* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index f4e7f37d892a..57e28fdae51e 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -25,7 +25,6 @@ #include "graphics/surface.h" - namespace Prince { class PrinceEngine; diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 3b5403532c87..bb6d07e52411 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -191,12 +191,16 @@ void Hero::countDrawPosition() { // any chance? if (baseX == 320) { tempMiddleY = _middleY - (baseY - 240); + if (baseY != 240) { + error("Hero::countDrawPosition() - tempMiddleY"); + } } else { tempMiddleY = _middleY; } int phaseFrameIndex = heroAnim->getPhaseFrameIndex(_phase); - _frameXSize = heroAnim->getFrameWidth(phaseFrameIndex); - _frameYSize = heroAnim->getFrameHeight(phaseFrameIndex); + Graphics::Surface *heroSurface = heroAnim->getFrame(phaseFrameIndex); + _frameXSize = heroSurface->w; + _frameYSize = heroSurface->h; _scaledFrameXSize = getScaledValue(_frameXSize); _scaledFrameYSize = getScaledValue(_frameYSize); diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 3fe43e6ed977..34af04b7d2ef 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -149,7 +149,7 @@ PrinceEngine::~PrinceEngine() { } _maskList.clear(); - freeDrawNodes(); + _drawNodeList.clear(); clearBackAnimList(); @@ -461,8 +461,6 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mobList[i]._visible = _script->getMobVisible(_room->_mobs, i); } - freeDrawNodes(); - _script->installObjects(_room->_obj); clearBackAnimList(); @@ -1020,8 +1018,6 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis int phaseFrameIndex = backAnim._animData->getPhaseFrameIndex(phase); Graphics::Surface *backAnimSurface = backAnim._animData->getFrame(phaseFrameIndex); byte pixel = *(byte *)backAnimSurface->getBasePtr(mousePosCamera.x - backAnim._currX, mousePosCamera.y - backAnim._currY); - backAnimSurface->free(); - delete backAnimSurface; if (pixel != 255) { if (type == 5) { if (mob->_rect.contains(mousePosCamera)) { @@ -1311,14 +1307,13 @@ void PrinceEngine::showMask(int maskNr, Graphics::Surface *originalRoomSurface) newDrawNode.s = nullptr; newDrawNode.originalRoomSurface = originalRoomSurface; newDrawNode.data = _maskList[maskNr].getMask(); - newDrawNode.freeSurfaceSMemory = false; newDrawNode.drawFunction = &_graph->drawMaskDrawNode; _drawNodeList.push_back(newDrawNode); } } } -void PrinceEngine::showSprite(Graphics::Surface *spriteSurface, int destX, int destY, int destZ, bool freeSurfaceMemory) { +void PrinceEngine::showSprite(Graphics::Surface *spriteSurface, int destX, int destY, int destZ) { if (spriteCheck(spriteSurface->w, spriteSurface->h, destX, destY)) { destX -= _picWindowX; destY -= _picWindowY; @@ -1331,16 +1326,12 @@ void PrinceEngine::showSprite(Graphics::Surface *spriteSurface, int destX, int d newDrawNode.s = spriteSurface; newDrawNode.originalRoomSurface = nullptr; newDrawNode.data = nullptr; - newDrawNode.freeSurfaceSMemory = freeSurfaceMemory; newDrawNode.drawFunction = &_graph->drawTransparentDrawNode; _drawNodeList.push_back(newDrawNode); - } else if (freeSurfaceMemory) { - spriteSurface->free(); - delete spriteSurface; } } -void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY, int destZ, bool freeSurfaceMemory) { +void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY, int destZ) { if (spriteCheck(shadowSurface->w, shadowSurface->h, destX, destY)) { destX -= _picWindowX; destY -= _picWindowY; @@ -1353,12 +1344,8 @@ void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX, newDrawNode.s = shadowSurface; newDrawNode.originalRoomSurface = nullptr; newDrawNode.data = _graph->_shadowTable70; - newDrawNode.freeSurfaceSMemory = freeSurfaceMemory; newDrawNode.drawFunction = &_graph->drawAsShadowDrawNode; _drawNodeList.push_back(newDrawNode); - } else if (freeSurfaceMemory) { - shadowSurface->free(); - delete shadowSurface; } } @@ -1376,8 +1363,9 @@ void PrinceEngine::showAnim(Anim &anim) { int maxFrontFlag = (animFlag & 2); int specialZFlag = anim._nextAnim; int z = anim._nextAnim; - int frameWidth = anim._animData->getFrameWidth(phaseFrameIndex); - int frameHeight = anim._animData->getFrameHeight(phaseFrameIndex); + Graphics::Surface *backAnimSurface = anim._animData->getFrame(phaseFrameIndex); + int frameWidth = backAnimSurface->w; + int frameHeight = backAnimSurface->h; int shadowZ = 0; if (x != 0 || y != 0 || phaseCount != 1 || frameCount != 1) { // TODO - check if this needed @@ -1402,8 +1390,7 @@ void PrinceEngine::showAnim(Anim &anim) { anim._currY = y; anim._currW = frameWidth; anim._currH = frameHeight; - Graphics::Surface *backAnimSurface = anim._animData->getFrame(phaseFrameIndex); // TODO - check for memory leak - showSprite(backAnimSurface, x, y, z, true); + showSprite(backAnimSurface, x, y, z); } //ShowFrameCodeShadow @@ -1412,8 +1399,9 @@ void PrinceEngine::showAnim(Anim &anim) { int shadowPhaseFrameIndex = anim._shadowData->getPhaseFrameIndex(phase); int shadowX = anim._shadowData->getBaseX() + anim._shadowData->getPhaseOffsetX(phase); int shadowY = anim._shadowData->getBaseY() + anim._shadowData->getPhaseOffsetY(phase); - int shadowFrameWidth = anim._shadowData->getFrameWidth(shadowPhaseFrameIndex); - int shadowFrameHeight = anim._shadowData->getFrameHeight(shadowPhaseFrameIndex); + 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); @@ -1426,9 +1414,7 @@ void PrinceEngine::showAnim(Anim &anim) { shadowZ = shadowY + shadowFrameWidth - 1; } } - - Graphics::Surface *shadowSurface = anim._shadowData->getFrame(shadowPhaseFrameIndex); // TODO - check for memory leak - showSpriteShadow(shadowSurface, shadowX, shadowY, shadowZ, true); + showSpriteShadow(shadowSurface, shadowX, shadowY, shadowZ); } } @@ -1436,6 +1422,7 @@ 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) { @@ -1448,7 +1435,9 @@ void PrinceEngine::showNormAnims() { } else { anim._frame++; } - anim._showFrame = anim._frame; + if (anim._frame < phaseCount - 1) { + anim._showFrame = anim._frame; + } showAnim(anim); } } @@ -1721,7 +1710,6 @@ void PrinceEngine::showObjects() { newDrawNode.s = objSurface; newDrawNode.originalRoomSurface = nullptr; newDrawNode.data = nullptr; - newDrawNode.freeSurfaceSMemory = false; if ((_objList[nr]->_flags & 0x2000)) { newDrawNode.drawFunction = &_graph->drawBackSpriteDrawNode; @@ -1747,7 +1735,7 @@ void PrinceEngine::showParallax() { int y = _pscrList[i]->_y; int z = 1000; if (spriteCheck(pscrSurface->w, pscrSurface->h, x, y)) { - showSprite(pscrSurface, x, y, z, false); + showSprite(pscrSurface, x, y, z); } } } @@ -1769,17 +1757,6 @@ void PrinceEngine::runDrawNodes() { _graph->change(); } - -void PrinceEngine::freeDrawNodes() { - for (uint i = 0; i < _drawNodeList.size(); i++) { - if (_drawNodeList[i].freeSurfaceSMemory) { - _drawNodeList[i].s->free(); - delete _drawNodeList[i].s; - } - } - _drawNodeList.clear(); -} - void PrinceEngine::drawScreen() { clsMasks(); @@ -1802,7 +1779,8 @@ void PrinceEngine::drawScreen() { _graph->draw(_graph->_frontScreen, &visiblePart); } - Graphics::Surface *mainHeroSurface = NULL; + Graphics::Surface *mainHeroSurface = nullptr; + Graphics::Surface *zoomedHeroSurface = nullptr; if (_mainHero->_visible) { mainHeroSurface = _mainHero->getSurface(); if (mainHeroSurface) { @@ -1819,12 +1797,10 @@ void PrinceEngine::drawScreen() { newDrawNode.drawFunction = &_graph->drawTransparentDrawNode; if (_mainHero->_zoomFactor) { - Graphics::Surface *zoomedHeroSurface = _mainHero->zoomSprite(mainHeroSurface); + zoomedHeroSurface = _mainHero->zoomSprite(mainHeroSurface); newDrawNode.s = zoomedHeroSurface; - newDrawNode.freeSurfaceSMemory = true; } else { newDrawNode.s = mainHeroSurface; - newDrawNode.freeSurfaceSMemory = false; } _drawNodeList.push_back(newDrawNode); } @@ -1846,11 +1822,12 @@ void PrinceEngine::drawScreen() { runDrawNodes(); - freeDrawNodes(); + _drawNodeList.clear(); - if (_mainHero->_visible) { - mainHeroSurface->free(); - delete mainHeroSurface; + if (zoomedHeroSurface != nullptr) { + zoomedHeroSurface->free(); + delete zoomedHeroSurface; + zoomedHeroSurface = nullptr; } if (!_inventoryBackgroundRemember && !_dialogFlag) { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index eef583222f8e..ac898aaf576b 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -233,7 +233,6 @@ struct DrawNode { Graphics::Surface *s; Graphics::Surface *originalRoomSurface; byte *data; - bool freeSurfaceSMemory; void (*drawFunction)(Graphics::Surface *, DrawNode *); }; @@ -566,13 +565,12 @@ class PrinceEngine : public Engine { void showBackAnims(); void clearBackAnimList(); bool spriteCheck(int sprWidth, int sprHeight, int destX, int destY); - void showSprite(Graphics::Surface *spriteSurface, int destX, int destY, int destZ, bool freeSurfaceMemory); - void showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY, int destZ, bool freeSurfaceMemory); + void showSprite(Graphics::Surface *spriteSurface, int destX, int destY, int destZ); + void showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY, int destZ); void showObjects(); void showParallax(); static bool compareDrawNodes(DrawNode d1, DrawNode d2); void runDrawNodes(); - void freeDrawNodes(); void makeShadowTable(int brightness); void pause(); From 34f496c38a84347d54c47812a1e7c59001c444ec Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 31 Jul 2014 20:59:41 +0200 Subject: [PATCH 307/374] PRINCE: Second hero implementation --- engines/prince/hero.cpp | 66 +++++++++++---- engines/prince/hero.h | 16 +--- engines/prince/prince.cpp | 172 ++++++++++++++++++++++++-------------- engines/prince/prince.h | 30 +++++-- engines/prince/script.cpp | 4 +- 5 files changed, 187 insertions(+), 101 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index bb6d07e52411..c139148c8227 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -35,7 +35,7 @@ namespace Prince { Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph) , _number(0), _visible(false), _state(kHeroStateStay), _middleX(0), _middleY(0) - , _boreNum(1), _currHeight(0), _moveDelay(0), _shadMinus(0), _moveSetType(0) + , _boreNum(1), _currHeight(0), _moveDelay(0), _shadMinus(0), _moveSetType(0), _zoomedHeroSurface(nullptr) , _lastDirection(kHeroDirDown), _destDirection(kHeroDirDown), _talkTime(0), _boredomTime(0), _phase(0) , _specAnim(nullptr), _drawX(0), _drawY(0), _drawZ(0), _zoomFactor(0), _scaleValue(0) , _shadZoomFactor(0), _shadScaleValue(0), _shadLineLen(0), _shadDrawX(0), _shadDrawY(0) @@ -43,17 +43,14 @@ Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph) , _coords(nullptr), _dirTab(nullptr), _currCoords(nullptr), _currDirTab(nullptr), _step(0) , _maxBoredom(200), _turnAnim(0), _leftRightMainDir(0), _upDownMainDir(0), _animSetNr(0) { - _zoomBitmap = (byte *)malloc(kZoomBitmapLen); - _shadowBitmap = (byte *)malloc(2 * kShadowBitmapSize); _shadowLine = new byte[kShadowLineArraySize]; } Hero::~Hero() { - free(_zoomBitmap); - free(_shadowBitmap); delete[] _shadowLine; freeHeroAnim(); freeOldMove(); + freeZoomedSurface(); } bool Hero::loadAnimSet(uint32 animSetNr) { @@ -238,6 +235,7 @@ static void plot(int x, int y, int color, void *data) { shadowLine->_shadLineLen++; } +// TODO - fix me void Hero::showHeroShadow(Graphics::Surface *heroFrame) { Graphics::Surface *makeShadow = new Graphics::Surface(); makeShadow->create(_frameXSize, _frameYSize, Graphics::PixelFormat::createFormatCLUT8()); @@ -258,16 +256,16 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { int destX = _middleX - _scaledFrameXSize / 2; int destY = _middleY - _shadMinus - 1; - if (destY > 1 && destY < kMaxPicHeight) { + if (destY > 1 && destY < _vm->kMaxPicHeight) { int shadDirection; - if (_lightY > destY) { + if (_vm->_lightY > destY) { shadDirection = 1; } else { shadDirection = 0; } _shadLineLen = 0; - Graphics::drawLine(_lightX, _lightY, destX, destY, 0, &plot, this); + Graphics::drawLine(_vm->_lightX, _vm->_lightY, destX, destY, 0, &plot, this); byte *sprShadow = (byte *)_graph->_shadowTable70; @@ -276,7 +274,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { int shadPosX = _shadDrawX; int shadPosY = _shadDrawY; - int shadBitAddr = destY * kMaxPicWidth / 8 + destX / 8; + int shadBitAddr = destY * _vm->kMaxPicWidth / 8 + destX / 8; int shadBitMask = 128 >> (destX % 8); int shadZoomY2 = _shadScaleValue; @@ -401,9 +399,9 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { shadZoomX += _scaleValue; } else { if (*shadowHero == _graph->kShadowColor) { - if ((shadBitMaskCopyTrans & _shadowBitmap[shadBitAddrCopyTrans]) != 0) { + if ((shadBitMaskCopyTrans & _vm->_shadowBitmap[shadBitAddrCopyTrans]) != 0) { if (shadWallDown == 0) { - if ((shadBitMaskCopyTrans & _shadowBitmap[shadBitAddrCopyTrans + kShadowBitmapSize]) != 0) { + if ((shadBitMaskCopyTrans & _vm->_shadowBitmap[shadBitAddrCopyTrans + _vm->kShadowBitmapSize]) != 0) { shadWDFlag = true; //shadow *background = *(sprShadow + *background); @@ -459,7 +457,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { } else { //point_ok: if (*shadowHero == _graph->kShadowColor) { - if ((shadBitMaskWallCopyTrans & _shadowBitmap[shadBitAddrWallCopyTrans + kShadowBitmapSize]) != 0) { + if ((shadBitMaskWallCopyTrans & _vm->_shadowBitmap[shadBitAddrWallCopyTrans + _vm->kShadowBitmapSize]) != 0) { *background = *(sprShadow + *background); } } @@ -480,7 +478,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { } //krap2 shadWallDestAddr -= kScreenWidth; - shadWallBitAddr -= kMaxPicWidth / 8; + shadWallBitAddr -= _vm->kMaxPicWidth / 8; shadWallPosY--; } } @@ -488,11 +486,11 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { //next_line if (*(shadowLineStart + 2) < *(shadowLineStart - 2)) { //minus_y - shadBitAddr -= kMaxPicWidth / 8; + shadBitAddr -= _vm->kMaxPicWidth / 8; shadPosY--; diffY--; } else if (*(shadowLineStart + 2) > *(shadowLineStart - 2)) { - shadBitAddr += kMaxPicWidth / 8; + shadBitAddr += _vm->kMaxPicWidth / 8; shadPosY++; diffY++; } @@ -546,7 +544,7 @@ void Hero::setScale(int8 zoomBitmapValue) { } void Hero::selectZoom() { - int8 zoomBitmapValue = *(_zoomBitmap + _middleY / 4 * kZoomBitmapWidth + _middleX / 4); + int8 zoomBitmapValue = *(_vm->_zoomBitmap + _middleY / 4 * _vm->kZoomBitmapWidth + _middleX / 4); setScale(zoomBitmapValue); } @@ -879,9 +877,34 @@ void Hero::showHero() { } } } - countDrawPosition(); + } +} +void Hero::drawHero() { + if (_visible && !_vm->_flags->getFlagValue(Flags::NOHEROATALL)) { + freeZoomedSurface(); + Graphics::Surface *mainHeroSurface = getSurface(); + if (mainHeroSurface) { + //showHeroShadow(mainHeroSurface); + DrawNode newDrawNode; + newDrawNode.posX = _drawX; + newDrawNode.posY = _drawY; + newDrawNode.posZ = _drawZ; + newDrawNode.width = 0; + newDrawNode.height = 0; + newDrawNode.originalRoomSurface = nullptr; + newDrawNode.data = nullptr; + newDrawNode.drawFunction = &_graph->drawTransparentDrawNode; + + if (_zoomFactor) { + _zoomedHeroSurface = zoomSprite(mainHeroSurface); + newDrawNode.s = _zoomedHeroSurface; + } else { + newDrawNode.s = mainHeroSurface; + } + _vm->_drawNodeList.push_back(newDrawNode); + } } } @@ -966,6 +989,7 @@ void Hero::scrollHero() { if (position < difference) { destValue = position - _vm->kNormalWidth / 2; } + if(destValue < 0) { destValue = 0; } @@ -995,6 +1019,14 @@ void Hero::freeHeroAnim() { } } +void Hero::freeZoomedSurface() { + if (_zoomedHeroSurface != nullptr) { + _zoomedHeroSurface->free(); + delete _zoomedHeroSurface; + _zoomedHeroSurface = nullptr; + } +} + } /* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 236818c3a18c..7c30fda559fa 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -39,15 +39,8 @@ struct InventoryItem; class Hero { public: - static const int16 kMaxPicWidth = 1280; - static const int16 kMaxPicHeight = 480; static const uint32 kMoveSetSize = 26; - static const int16 kZoomStep = 4; - static const int32 kZoomBitmapLen = kMaxPicHeight / kZoomStep * kMaxPicWidth / kZoomStep; - static const int16 kZoomBitmapWidth = kMaxPicWidth / kZoomStep; - static const int16 kZoomBitmapHeight = kMaxPicHeight / kZoomStep; static const int16 kShadowLineArraySize = 2 * 1280 * 4; - static const int32 kShadowBitmapSize = kMaxPicWidth * kMaxPicHeight / 8; static const int16 kScreenWidth = 640; static const int16 kStepLeftRight = 8; static const int16 kStepUpDown = 4; @@ -119,6 +112,8 @@ class Hero { void setVisible(bool flag) { _visible = flag; } void showHero(); + void drawHero(); + void freeZoomedSurface(); void heroStanding(); void heroMoveGotIt(int x, int y, int dir); int rotateHero(int oldDirection, int newDirection); @@ -155,9 +150,7 @@ class Hero { int16 _drawX; int16 _drawY; int16 _drawZ; - - int16 _lightX; // for hero's shadow - int16 _lightY; + int32 _shadZoomFactor; int32 _shadScaleValue; int32 _shadLineLen; @@ -179,6 +172,7 @@ class Hero { uint16 _boreNum; // Bore anim frame int16 _talkTime; // TalkTime time of talk anim Animation *_specAnim; // additional anim + Graphics::Surface *_zoomedHeroSurface; uint16 _currHeight; // height of current anim phase @@ -189,8 +183,6 @@ class Hero { uint32 _animSetNr; // number of animation set Common::Array _moveSet; // MoveAnims MoveSet int16 _turnAnim; - byte *_zoomBitmap; - byte *_shadowBitmap; byte *_shadowLine; uint32 _moveDelay; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 34af04b7d2ef..54579820ec21 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -93,7 +93,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _traceLineLen(0), _rembBitmapTemp(nullptr), _rembBitmap(nullptr), _rembMask(0), _rembX(0), _rembY(0), _fpX(0), _fpY(0), _checkBitmapTemp(nullptr), _checkBitmap(nullptr), _checkMask(0), _checkX(0), _checkY(0), _traceLineFirstPointFlag(false), _tracePointFirstPointFlag(false), _coordsBuf2(nullptr), _coords2(nullptr), _coordsBuf3(nullptr), _coords3(nullptr), - _shanLen1(0), _directionTable(nullptr), _currentMidi(0) { + _shanLen(0), _directionTable(nullptr), _currentMidi(0), _lightX(0), _lightY(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -185,6 +185,9 @@ PrinceEngine::~PrinceEngine() { _mobPriorityList.clear(); freeAllSamples(); + + free(_zoomBitmap); + free(_shadowBitmap); } GUI::Debugger *PrinceEngine::getDebugger() { @@ -301,6 +304,7 @@ void PrinceEngine::init() { _mainHero = new Hero(this, _graph); _secondHero = new Hero(this, _graph); _secondHero->_maxBoredom = 140; + _secondHero->loadAnimSet(3); _roomPathBitmap = (byte *)malloc(kPathBitmapLen); _roomPathBitmapTemp = (byte *)malloc(kPathBitmapLen); @@ -325,6 +329,9 @@ void PrinceEngine::init() { for (int i = 0; i < kMaxObjects; i++) { _objSlot[i] = 0xFF; } + + _zoomBitmap = (byte *)malloc(kZoomBitmapLen); + _shadowBitmap = (byte *)malloc(2 * kShadowBitmapSize); } void PrinceEngine::showLogo() { @@ -413,8 +420,8 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _sceneWidth = _roomBmp->getSurface()->w; } - loadZoom(_mainHero->_zoomBitmap, _mainHero->kZoomBitmapLen, "zoom"); // TODO - second hero - loadShadow(_mainHero->_shadowBitmap, _mainHero->kShadowBitmapSize, "shadow", "shadow2"); // TODO - second hero + loadZoom(_zoomBitmap, kZoomBitmapLen, "zoom"); + loadShadow(_shadowBitmap, kShadowBitmapSize, "shadow", "shadow2"); loadPath("path"); for (uint32 i = 0; i < _pscrList.size(); i++) { @@ -453,9 +460,10 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _picWindowX = 0; - _mainHero->_lightX = _script->getLightX(_locationNr); - _mainHero->_lightY = _script->getLightY(_locationNr); + _lightX = _script->getLightX(_locationNr); + _lightY = _script->getLightY(_locationNr); _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); + _secondHero->setShadowScale(_script->getShadowScale(_locationNr)); for (uint i = 0; i < _mobList.size(); i++) { _mobList[i]._visible = _script->getMobVisible(_room->_mobs, i); @@ -1758,15 +1766,17 @@ void PrinceEngine::runDrawNodes() { } void PrinceEngine::drawScreen() { + if (!_showInventoryFlag || _inventoryBackgroundRemember) { + clsMasks(); - clsMasks(); + _mainHero->showHero(); + _secondHero->showHero(); - _mainHero->showHero(); - _secondHero->showHero(); + _mainHero->scrollHero(); - _mainHero->scrollHero(); + _mainHero->drawHero(); + _secondHero->drawHero(); - if (!_showInventoryFlag || _inventoryBackgroundRemember) { const Graphics::Surface *roomSurface; if (_locationNr != 50) { roomSurface = _roomBmp->getSurface(); @@ -1779,33 +1789,6 @@ void PrinceEngine::drawScreen() { _graph->draw(_graph->_frontScreen, &visiblePart); } - Graphics::Surface *mainHeroSurface = nullptr; - Graphics::Surface *zoomedHeroSurface = nullptr; - if (_mainHero->_visible) { - mainHeroSurface = _mainHero->getSurface(); - if (mainHeroSurface) { - _mainHero->showHeroShadow(mainHeroSurface); - - DrawNode newDrawNode; - newDrawNode.posX = _mainHero->_drawX; - newDrawNode.posY = _mainHero->_drawY; - newDrawNode.posZ = _mainHero->_drawZ; - newDrawNode.width = 0; - newDrawNode.height = 0; - newDrawNode.originalRoomSurface = nullptr; - newDrawNode.data = nullptr; - newDrawNode.drawFunction = &_graph->drawTransparentDrawNode; - - if (_mainHero->_zoomFactor) { - zoomedHeroSurface = _mainHero->zoomSprite(mainHeroSurface); - newDrawNode.s = zoomedHeroSurface; - } else { - newDrawNode.s = mainHeroSurface; - } - _drawNodeList.push_back(newDrawNode); - } - } - showBackAnims(); showNormAnims(); @@ -1824,12 +1807,6 @@ void PrinceEngine::drawScreen() { _drawNodeList.clear(); - if (zoomedHeroSurface != nullptr) { - zoomedHeroSurface->free(); - delete zoomedHeroSurface; - zoomedHeroSurface = nullptr; - } - if (!_inventoryBackgroundRemember && !_dialogFlag) { if (!_optionsFlag) { _selectedMob = checkMob(_graph->_frontScreen, _mobList, true); @@ -1909,7 +1886,7 @@ void PrinceEngine::setPalette() { void PrinceEngine::pause() { uint32 currentTime = _system->getMillis(); - int delay = 1000/15 - int32(_system->getMillis() - currentTime); + int delay = 1000 / 15 - int32(_system->getMillis() - currentTime); delay = delay < 0 ? 0 : delay; _system->delayMillis(delay); } @@ -2225,13 +2202,13 @@ void PrinceEngine::walkTo() { destY = mousePos.y + _picWindowY; _mainHero->_destDirection = 0; } - _mainHero->_coords = makePath(destX, destY); + _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 = _mainHero->kHeroStateMove; + _mainHero->_state = Hero::kHeroStateMove; moveShandria(); } } @@ -2251,16 +2228,16 @@ void PrinceEngine::moveRunHero(int heroId, int x, int y, int dir, bool runHeroFl } if (x || y) { hero->freeOldMove(); - hero->_coords = makePath(x, y); + hero->_coords = makePath(heroId, hero->_middleX, hero->_middleY, x, y); if (hero->_coords != nullptr) { - hero->_currCoords = _mainHero->_coords; + hero->_currCoords = hero->_coords; hero->_dirTab = _directionTable; hero->_currDirTab = _directionTable; _directionTable = nullptr; if (runHeroFlag) { - hero->_state = _mainHero->kHeroStateRun; + hero->_state = Hero::kHeroStateRun; } else { - hero->_state = _mainHero->kHeroStateMove; + hero->_state = Hero::kHeroStateMove; } } } else { @@ -4240,20 +4217,81 @@ void PrinceEngine::scanDirections() { } } -// TODO void PrinceEngine::moveShandria() { + int shanLen1 = _shanLen; + static const int kMinDistance = 2500; + if (_flags->getFlagValue(Flags::SHANDOG)) { + _secondHero->freeHeroAnim(); + _secondHero->freeOldMove(); + byte *shanCoords = _mainHero->_currCoords + shanLen1 * 4 - 4; + int shanX = READ_UINT16(shanCoords - 4); + int shanY = READ_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) { + //scangoodpoint: + while (1) { + shanCoords -= 4; + if (shanCoords == _mainHero->_currCoords) { + break; + } + int x = READ_UINT16(shanCoords); + int y = READ_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; + } + } + //bye2 + int pathSizeDiff = (shanCoords - _mainHero->_currCoords) / 4; + int destDir = *_mainHero->_currDirTab + pathSizeDiff; + _secondHero->_destDirection = destDir; + int destX = READ_UINT16(shanCoords); + int destY = READ_UINT16(shanCoords + 2); + _secondHero->_coords = makePath(kSecondHero, _secondHero->_middleX, _secondHero->_middleY, destX, destY); + if (_secondHero->_coords != nullptr) { + _secondHero->_currCoords = _mainHero->_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 destX, int destY) { +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 currX = _mainHero->_middleX; // TODO - check for second hero - int currY = _mainHero->_middleY; - int x1 = currX / 2; int y1 = currY / 2; int x2 = destX / 2; @@ -4280,8 +4318,13 @@ byte *PrinceEngine::makePath(int destX, int destY) { } if ((x1 == x2) && (y1 == y2)) { - _mainHero->freeOldMove(); - _mainHero->_state = _mainHero->kHeroStateTurn; + if (!heroId) { + _mainHero->freeOldMove(); + _mainHero->_state = Hero::kHeroStateTurn; + } else if (heroId == 1) { + _secondHero->freeOldMove(); + _secondHero->_state = Hero::kHeroStateTurn; + } return nullptr; } @@ -4381,8 +4424,8 @@ byte *PrinceEngine::makePath(int destX, int destY) { WRITE_UINT16(newCoords - 2, realDestY); WRITE_UINT32(newCoords, 0xFFFFFFFF); newCoords += 4; - _shanLen1 = (newCoords - newCoordsBegin); - //_shanLen1 /= 4 ? + _shanLen = (newCoords - newCoordsBegin); + //_shanLen /= 4 ? return newCoordsBegin; } } @@ -4392,8 +4435,13 @@ byte *PrinceEngine::makePath(int destX, int destY) { freeCoords3(); return nullptr; } else { - _mainHero->freeOldMove(); - _mainHero->_state = _mainHero->kHeroStateTurn; + if (!heroId) { + _mainHero->freeOldMove(); + _mainHero->_state = Hero::kHeroStateTurn; + } else if (heroId == 1) { + _secondHero->freeOldMove(); + _secondHero->_state = Hero::kHeroStateTurn; + } return nullptr; } } @@ -4465,7 +4513,7 @@ void PrinceEngine::mainLoop() { _graph->update(_graph->_frontScreen); // Calculate the frame delay based off a desired frame time - int delay = 1000/15 - int32(_system->getMillis() - currentTime); + int delay = 1000 / 15 - int32(_system->getMillis() - currentTime); // Ensure non-negative delay = delay < 0 ? 0 : delay; _system->delayMillis(delay); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index ac898aaf576b..4b8d78ad947f 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -310,11 +310,18 @@ class PrinceEngine : public Engine { Hero *_mainHero; Hero *_secondHero; + enum HeroId { + kMainHero, + kSecondHero + }; + int _mouseFlag; uint16 _locationNr; uint16 _sceneWidth; int32 _picWindowX; int32 _picWindowY; + int16 _lightX; // for hero shadow + int16 _lightY; Image::BitmapDecoder *_roomBmp; MhwanhDecoder *_suitcaseBmp; Room *_room; @@ -322,12 +329,25 @@ class PrinceEngine : public Engine { InterpreterFlags *_flags; Interpreter *_interpreter; uint8 _currentMidi; + byte *_zoomBitmap; + byte *_shadowBitmap; + + static const int16 kMaxPicWidth = 1280; + static const int16 kMaxPicHeight = 480; + static const int16 kZoomStep = 4; + static const int32 kZoomBitmapLen = kMaxPicHeight / kZoomStep * kMaxPicWidth / kZoomStep; + static const int32 kShadowBitmapSize = kMaxPicWidth * kMaxPicHeight / 8; + static const int16 kZoomBitmapWidth = kMaxPicWidth / kZoomStep; + static const int16 kZoomBitmapHeight = kMaxPicHeight / kZoomStep; + static const int16 kNormalWidth = 640; + static const int16 kNormalHeight = 480; static const int kMaxNormAnims = 64; static const int kMaxBackAnims = 64; static const int kMaxObjects = 64; static const int kMaxMobs = 64; + Common::Array _drawNodeList; Common::Array _animList; Common::Array _backAnimList; Common::Array _normAnimList; @@ -343,11 +363,6 @@ class PrinceEngine : public Engine { Common::RandomSource _randomSource; - static const int16 kNormalWidth = 640; - static const int16 kNormalHeight = 480; - static const int16 kMaxPicWidth = 1280; - static const int16 kMaxPicHeight = 480; - void checkMasks(int x1, int y1, int sprWidth, int sprHeight, int z); void insertMasks(Graphics::Surface *originalRoomSurface); void showMask(int maskNr, Graphics::Surface *originalRoomSurface); @@ -484,7 +499,7 @@ class PrinceEngine : public Engine { bool _traceLineFirstPointFlag; // if plotTraceLine after first point bool _tracePointFirstPointFlag; // if plotTracePoint after first point byte *_directionTable; - int _shanLen1; + int _shanLen; byte *_checkBitmapTemp; byte *_checkBitmap; @@ -503,7 +518,7 @@ class PrinceEngine : public Engine { int drawLine(int x0, int y0, int x1, int y1, int (*plotProc)(int, int, void *), void *data); bool loadPath(const char *resourceName); - byte *makePath(int destX, int destY); + byte *makePath(int heroId, int currX, int currY, int destX, int destY); void findPoint(int x, int y); int getPixelAddr(byte *pathBitmap, int x, int y); static int plotTraceLine(int x, int y, void *data); @@ -593,7 +608,6 @@ class PrinceEngine : public Engine { Audio::SoundHandle _soundHandle[kMaxSamples]; Common::Array _pscrList; - Common::Array _drawNodeList; Common::Array _allInvList; Common::Array _invMobList; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index cf45d50fdbb3..a621c864cb7d 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1725,9 +1725,9 @@ void Interpreter::O_FREEFLC() { void Interpreter::O_TALKHEROSTOP() { uint16 heroId = readScriptFlagValue(); if (!heroId) { - _vm->_mainHero->_state = _vm->_mainHero->kHeroStateStay; + _vm->_mainHero->_state = Hero::kHeroStateStay; } else if (heroId == 1) { - _vm->_secondHero->_state = _vm->_secondHero->kHeroStateStay; + _vm->_secondHero->_state = Hero::kHeroStateStay; } debugInterpreter("O_TALKHEROSTOP %d", heroId); } From d8853725a6c8e4830dbfe813f94ca364794779af Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 31 Jul 2014 23:02:43 +0200 Subject: [PATCH 308/374] PRINCE: Animations - update, optimization --- engines/prince/animation.cpp | 81 ++++++++++++++++++++---------------- engines/prince/animation.h | 8 +++- 2 files changed, 52 insertions(+), 37 deletions(-) diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index f5beb8674fce..39040a5181ab 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -28,6 +28,23 @@ namespace Prince { +Animation::Animation() : _idXDiff(0), _idYDiff(0), _loopCount(0), _phaseCount(0), _frameCount(0), _baseX(0), _baseY(0) +{ +} + +Animation::~Animation() { + clear(); +} + +void Animation::clear() { + _phaseList.clear(); + for (int i = 0; i < _frameCount; i++) { + _frameList[i]._surface->free(); + delete _frameList[i]._surface; + _frameList[i]._surface = nullptr; + } +} + bool Animation::loadFromStream(Common::SeekableReadStream &stream) { _idXDiff = stream.readByte(); _idYDiff = stream.readByte(); @@ -56,6 +73,7 @@ bool Animation::loadFromStream(Common::SeekableReadStream &stream) { _frameCount++; } + Frame tempFrame; for (int frame = 0; frame < _frameCount; frame++) { stream.seek(tableOfFrameOffsets + frame * 4); uint32 frameInfoOffset = stream.readUint32LE(); @@ -65,52 +83,28 @@ bool Animation::loadFromStream(Common::SeekableReadStream &stream) { uint32 frameDataPos = stream.pos(); uint32 frameDataOffset = stream.readUint32BE(); - Graphics::Surface *surf = new Graphics::Surface(); - surf->create(frameWidth, frameHeight, Graphics::PixelFormat::createFormatCLUT8()); + tempFrame._surface = new Graphics::Surface(); + tempFrame._surface->create(frameWidth, frameHeight, Graphics::PixelFormat::createFormatCLUT8()); if (frameDataOffset == MKTAG('m', 'a', 's', 'm')) { - // Compressed - Decompressor dec; - uint32 ddataSize = stream.readUint32LE(); - byte *data = (byte *)malloc(ddataSize); - byte *ddata = (byte *)malloc(ddataSize); - - stream.read(data, ddataSize); - dec.decompress(data, ddata, ddataSize); - for (uint16 i = 0; i < frameHeight; i++) { - memcpy(surf->getBasePtr(0, i), ddata + frameWidth * i, frameWidth); - } - free(ddata); - free(data); + tempFrame._isCompressed = true; + tempFrame._dataSize = stream.readUint32LE(); + tempFrame._compressedData = (byte *)malloc(tempFrame._dataSize); + stream.read(tempFrame._compressedData, tempFrame._dataSize); } else { + tempFrame._isCompressed = false; + tempFrame._dataSize = 0; + tempFrame._compressedData = nullptr; stream.seek(frameDataPos); - // Uncompressed for (uint16 i = 0; i < frameHeight; i++) { - stream.read(surf->getBasePtr(0, i), frameWidth); + stream.read(tempFrame._surface->getBasePtr(0, i), frameWidth); } } - _frameList.push_back(surf); + _frameList.push_back(tempFrame); } return true; } -Animation::Animation() : _idXDiff(0), _idYDiff(0), _loopCount(0), _phaseCount(0), _frameCount(0), _baseX(0), _baseY(0) -{ -} - -Animation::~Animation() { - clear(); -} - -void Animation::clear() { - _phaseList.clear(); - for (int i = 0; i < _frameCount; i++) { - _frameList[i]->free(); - delete _frameList[i]; - _frameList[i] = nullptr; - } -} - bool Animation::testId() const { if (_idXDiff == 'A' && _idYDiff == 'N') { return true; @@ -172,7 +166,22 @@ int16 Animation::getPhaseFrameIndex(int phaseIndex) const { Graphics::Surface *Animation::getFrame(int frameIndex) { if (frameIndex < _frameCount) { - return _frameList[frameIndex]; + if (_frameList[frameIndex]._isCompressed) { + Decompressor dec; + byte *ddata = (byte *)malloc(_frameList[frameIndex]._dataSize); + dec.decompress(_frameList[frameIndex]._compressedData, ddata, _frameList[frameIndex]._dataSize); + int frameHeight = _frameList[frameIndex]._surface->h; + int frameWidth = _frameList[frameIndex]._surface->w; + for (uint16 i = 0; i < frameHeight; i++) { + memcpy(_frameList[frameIndex]._surface->getBasePtr(0, i), ddata + frameWidth * i, frameWidth); + } + free(ddata); + free(_frameList[frameIndex]._compressedData); + _frameList[frameIndex]._compressedData = nullptr; + _frameList[frameIndex]._dataSize = 0; + _frameList[frameIndex]._isCompressed = false; + } + return _frameList[frameIndex]._surface; } else { error("getFrame() frameIndex: %d, frameCount: %d", frameIndex, _frameCount); } diff --git a/engines/prince/animation.h b/engines/prince/animation.h index 23a1b5808a22..0634d7a937d4 100644 --- a/engines/prince/animation.h +++ b/engines/prince/animation.h @@ -56,7 +56,13 @@ class Animation { int16 _phaseOffsetY; uint16 _phaseToFrameIndex; }; - Common::Array _frameList; + struct Frame { + bool _isCompressed; + uint32 _dataSize; + byte *_compressedData; + Graphics::Surface *_surface; + }; + Common::Array _frameList; Common::Array _phaseList; int8 _idXDiff; int8 _idYDiff; From 03b6b61d5175c717c4bbfc3e6c0bdadb931d3158 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 31 Jul 2014 23:42:59 +0200 Subject: [PATCH 309/374] PRINCE: Animation::clear() update --- engines/prince/animation.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index 39040a5181ab..98d1e3362062 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -42,6 +42,10 @@ void Animation::clear() { _frameList[i]._surface->free(); delete _frameList[i]._surface; _frameList[i]._surface = nullptr; + if (_frameList[i]._compressedData != nullptr) { + free(_frameList[i]._compressedData); + _frameList[i]._compressedData = nullptr; + } } } From b3589c76da856239828377a3011525a888b04920 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 1 Aug 2014 00:35:31 +0200 Subject: [PATCH 310/374] PRINCE: Parallax and animSet loading update --- engines/prince/hero.cpp | 4 ++-- engines/prince/prince.cpp | 12 +++++++----- engines/prince/pscr.cpp | 14 +++++--------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index c139148c8227..79a69da47154 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -69,12 +69,12 @@ bool Hero::loadAnimSet(uint32 animSetNr) { const HeroSetAnimNames &animSet = *heroSetTable[animSetNr]; _moveSet.resize(kMoveSetSize); - for (uint32 i = 0; i < kMoveSetSize; ++i) { + for (uint32 i = 0; i < kMoveSetSize; i++) { debug("Anim set item %d %s", i, animSet[i]); Animation *anim = NULL; if (animSet[i] != NULL) { anim = new Animation(); - Resource::loadResource(anim, animSet[i], true); + Resource::loadResource(anim, animSet[i], false); } _moveSet[i] = anim; } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 54579820ec21..ee96895d31bc 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1739,11 +1739,13 @@ void PrinceEngine::showParallax() { if (!_pscrList.empty()) { for (uint i = 0; i < _pscrList.size(); i++) { Graphics::Surface *pscrSurface = _pscrList[i]->getSurface(); - int x = _pscrList[i]->_x - (_pscrList[i]->_step * _picWindowX / 4); - int y = _pscrList[i]->_y; - int z = 1000; - if (spriteCheck(pscrSurface->w, pscrSurface->h, x, y)) { - showSprite(pscrSurface, x, y, z); + if (pscrSurface != nullptr) { + int x = _pscrList[i]->_x - (_pscrList[i]->_step * _picWindowX / 4); + int y = _pscrList[i]->_y; + int z = 1000; + if (spriteCheck(pscrSurface->w, pscrSurface->h, x, y)) { + showSprite(pscrSurface, x, y, z); + } } } } diff --git a/engines/prince/pscr.cpp b/engines/prince/pscr.cpp index ea6de2a5b608..bb4316d4657d 100644 --- a/engines/prince/pscr.cpp +++ b/engines/prince/pscr.cpp @@ -31,15 +31,15 @@ namespace Prince { -PScr::PScr() :_file(0), _x(0), _y(0), _step(0), _addr(0), _len(0), _surface(NULL) +PScr::PScr() :_file(0), _x(0), _y(0), _step(0), _addr(0), _len(0), _surface(nullptr) { } PScr::~PScr() { - if (_surface) { + if (_surface != nullptr) { _surface->free(); delete _surface; - _surface = NULL; + _surface = nullptr; } } @@ -68,14 +68,10 @@ bool PScr::loadFromStream(Common::SeekableReadStream &stream) { const Common::String pscrStreamName = Common::String::format("PS%02d", _file); Common::SeekableReadStream *pscrStream = SearchMan.createReadStreamForMember(pscrStreamName); - if (!pscrStream) { - error("Can't load %s", pscrStreamName.c_str()); - return false; + if (pscrStream != nullptr) { + loadSurface(*pscrStream); } - - loadSurface(*pscrStream); delete pscrStream; - stream.seek(pos + 12); // size of PScrList struct debug("Parallex nr %d, x %d, y %d, step %d", _file, _x, _y, _step); From 3c29d61f6705a6f05d86fa2599a6992d2d17e3ac Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 1 Aug 2014 17:38:04 +0200 Subject: [PATCH 311/374] PRINCE: Code clean-up --- engines/prince/animation.cpp | 2 - engines/prince/animation.h | 4 +- engines/prince/archive.cpp | 10 +- engines/prince/archive.h | 2 - engines/prince/common.h | 28 ++-- engines/prince/cursor.cpp | 26 ++-- engines/prince/cursor.h | 8 +- engines/prince/debugger.cpp | 4 +- engines/prince/debugger.h | 4 +- engines/prince/detection.cpp | 2 - engines/prince/flags.cpp | 7 +- engines/prince/flags.h | 5 +- engines/prince/font.cpp | 29 ++--- engines/prince/font.h | 13 +- engines/prince/graphics.cpp | 22 ++-- engines/prince/graphics.h | 6 +- engines/prince/hero.cpp | 34 ++--- engines/prince/hero.h | 5 +- engines/prince/hero_set.cpp | 243 ----------------------------------- engines/prince/hero_set.h | 221 ++++++++++++++++++++++++++++++- engines/prince/mhwanh.cpp | 27 ++-- engines/prince/mhwanh.h | 10 +- engines/prince/mob.cpp | 6 +- engines/prince/mob.h | 9 +- engines/prince/module.mk | 1 - engines/prince/musNum.h | 2 +- engines/prince/object.cpp | 9 +- engines/prince/object.h | 3 +- engines/prince/option_text.h | 3 +- engines/prince/prince.cpp | 145 ++++----------------- engines/prince/prince.h | 11 +- engines/prince/pscr.cpp | 17 +-- engines/prince/pscr.h | 9 +- engines/prince/resource.h | 4 +- engines/prince/saveload.cpp | 2 + engines/prince/script.cpp | 21 +-- engines/prince/script.h | 12 +- engines/prince/sound.cpp | 6 +- engines/prince/sound.h | 2 - engines/prince/variatxt.cpp | 14 +- engines/prince/variatxt.h | 6 +- 41 files changed, 394 insertions(+), 600 deletions(-) delete mode 100644 engines/prince/hero_set.cpp diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index 98d1e3362062..db16adacbc29 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -192,5 +192,3 @@ Graphics::Surface *Animation::getFrame(int frameIndex) { } } // End of namespace Prince - -/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/animation.h b/engines/prince/animation.h index 0634d7a937d4..87d21f5dbc89 100644 --- a/engines/prince/animation.h +++ b/engines/prince/animation.h @@ -73,8 +73,6 @@ class Animation { int16 _baseY; }; -} +} // End of namespace Prince #endif - -/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/archive.cpp b/engines/prince/archive.cpp index ac00261337a1..11be0b224a47 100644 --- a/engines/prince/archive.cpp +++ b/engines/prince/archive.cpp @@ -60,7 +60,7 @@ bool PtcArchive::open(const Common::String &filename) { _stream->seek(fileTableOffset); - byte *fileTable = new byte[fileTableSize]; + byte *fileTable = (byte *)malloc(fileTableSize); byte *fileTableEnd = fileTable + fileTableSize; _stream->read(fileTable, fileTableSize); decrypt(fileTable, fileTableSize); @@ -73,8 +73,8 @@ bool PtcArchive::open(const Common::String &filename) { //debug("%12s %8X %d", name.c_str(), item._offset, item._size); _items[name] = item; } - - delete[] fileTable; + + free(fileTable); return true; } @@ -141,6 +141,4 @@ Common::SeekableReadStream *PtcArchive::createReadStreamForMember(const Common:: return new Common::MemoryReadStream(buffer, size, DisposeAfterUse::YES); } -} - -/* vim: set tabstop=4 noexpandtab: */ +} // End of namespace Prince diff --git a/engines/prince/archive.h b/engines/prince/archive.h index 29d3d585603c..e211036ed612 100644 --- a/engines/prince/archive.h +++ b/engines/prince/archive.h @@ -59,5 +59,3 @@ class PtcArchive : public Common::Archive { } // End of namespace Prince #endif - -/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/common.h b/engines/prince/common.h index 808b6900ecdb..c846f9a751e8 100644 --- a/engines/prince/common.h +++ b/engines/prince/common.h @@ -26,22 +26,20 @@ namespace Prince { enum Direction { - kDirLD = 0, - kDirL = 1, - kDirLU = 2, - kDirRD = 3, - kDirR = 4, - kDirRU = 5, - kDirUL = 6, - kDirU = 7, - kDirUR = 8, - kDirDL = 9, - kDirD = 10, - kDirDR = 11 + kDirLD, + kDirL, + kDirLU, + kDirRD, + kDirR, + kDirRU, + kDirUL, + kDirU, + kDirUR, + kDirDL, + kDirD, + kDirDR }; -} +} // End of namespace Prince #endif - -/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/cursor.cpp b/engines/prince/cursor.cpp index 865ae99cadd3..c09fe43bfcbe 100644 --- a/engines/prince/cursor.cpp +++ b/engines/prince/cursor.cpp @@ -23,32 +23,32 @@ #include "prince/cursor.h" #include "common/debug.h" -#include "common/stream.h" namespace Prince { -Cursor::Cursor() : _surface(NULL) { +Cursor::Cursor() : _surface(nullptr) { } Cursor::~Cursor() { - _surface->free(); - delete _surface; - _surface = NULL; + if (_surface != nullptr) { + _surface->free(); + delete _surface; + _surface = nullptr; + } } bool Cursor::loadFromStream(Common::SeekableReadStream &stream) { stream.skip(4); - uint16 w = stream.readUint16LE(); - uint16 h = stream.readUint16LE(); + uint16 width = stream.readUint16LE(); + uint16 heigth = stream.readUint16LE(); _surface = new Graphics::Surface(); - _surface->create(w, h, Graphics::PixelFormat::createFormatCLUT8()); + _surface->create(width, heigth, Graphics::PixelFormat::createFormatCLUT8()); - for (int ih = 0; ih < h; ++ih) - stream.read(_surface->getBasePtr(0, ih), w); + for (int h = 0; h < heigth; h++) { + stream.read(_surface->getBasePtr(0, h), width); + } return true; } -} - -/* vim: set tabstop=4 noexpandtab: */ +} // End of namespace Prince diff --git a/engines/prince/cursor.h b/engines/prince/cursor.h index 70516519e66e..683a158ba8a4 100644 --- a/engines/prince/cursor.h +++ b/engines/prince/cursor.h @@ -25,9 +25,7 @@ #include "graphics/surface.h" -namespace Common { - class SeekableReadStream; -} +#include "common/stream.h" namespace Prince { @@ -43,8 +41,6 @@ class Cursor { Graphics::Surface *_surface; }; -} +} // End of namespace Prince #endif - -/* vim: set tabstop=4 expandtab!: */ diff --git a/engines/prince/debugger.cpp b/engines/prince/debugger.cpp index cf74b7b423c0..481ea695f54b 100644 --- a/engines/prince/debugger.cpp +++ b/engines/prince/debugger.cpp @@ -171,6 +171,4 @@ bool Debugger::Cmd_AddItem(int argc, const char **argv) { return true; } -} - -/* vim: set tabstop=4 noexpandtab: */ +} // End of namespace Prince diff --git a/engines/prince/debugger.h b/engines/prince/debugger.h index 10c82d528219..a4467e63d559 100644 --- a/engines/prince/debugger.h +++ b/engines/prince/debugger.h @@ -53,8 +53,6 @@ class Debugger : public GUI::Debugger { InterpreterFlags *_flags; }; -} +} // End of namespace Prince #endif - -/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/detection.cpp b/engines/prince/detection.cpp index 285d7d1ce32f..3f83009de836 100644 --- a/engines/prince/detection.cpp +++ b/engines/prince/detection.cpp @@ -71,5 +71,3 @@ REGISTER_PLUGIN_DYNAMIC(PRINCE, PLUGIN_TYPE_ENGINE, Prince::PrinceMetaEngine); #else REGISTER_PLUGIN_STATIC(PRINCE, PLUGIN_TYPE_ENGINE, Prince::PrinceMetaEngine); #endif - -/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/flags.cpp b/engines/prince/flags.cpp index 18d9e212c149..3b0d1d95dca3 100644 --- a/engines/prince/flags.cpp +++ b/engines/prince/flags.cpp @@ -24,8 +24,7 @@ namespace Prince { -const char *Flags::getFlagName(uint16 flagId) -{ +const char *Flags::getFlagName(uint16 flagId) { switch (flagId) { default: return "unknown_flag"; case FLAGA1: return "FLAGA1"; @@ -401,6 +400,4 @@ const char *Flags::getFlagName(uint16 flagId) } } -} - -/* vim: set tabstop=4 noexpandtab: */ +} // End of namespace Prince diff --git a/engines/prince/flags.h b/engines/prince/flags.h index 5af6bffa0060..efa97eb5eda0 100644 --- a/engines/prince/flags.h +++ b/engines/prince/flags.h @@ -410,7 +410,6 @@ struct Flags { }; }; -} -#endif -/* vim: set tabstop=4 noexpandtab: */ +} // End of namespace Prince +#endif diff --git a/engines/prince/font.cpp b/engines/prince/font.cpp index 40b6d014e6ce..0ac61f29beda 100644 --- a/engines/prince/font.cpp +++ b/engines/prince/font.cpp @@ -23,24 +23,25 @@ #include "common/archive.h" #include "common/debug.h" #include "common/stream.h" -#include "common/str.h" - -#include "graphics/surface.h" #include "prince/font.h" namespace Prince { -Font::Font() { +Font::Font() : _fontData(nullptr) { } Font::~Font() { - delete [] _fontData; + if (_fontData != nullptr) { + free(_fontData); + _fontData = nullptr; + } } bool Font::loadFromStream(Common::SeekableReadStream &stream) { stream.seek(0); - _fontData = new byte[stream.size()]; + uint32 dataSize = stream.size(); + _fontData = (byte *)malloc(dataSize); stream.read(_fontData, stream.size()); return true; } @@ -55,11 +56,11 @@ int Font::getMaxCharWidth() const { Font::ChrData Font::getChrData(byte chr) const { chr -= 32; - uint16 chrOffset = 4*chr+6; + uint16 chrOffset = 4 * chr + 6; ChrData chrData; - chrData._width = _fontData[chrOffset+2]; - chrData._height = _fontData[chrOffset+3]; + chrData._width = _fontData[chrOffset + 2]; + chrData._height = _fontData[chrOffset + 3]; chrData._pixels = _fontData + READ_LE_UINT16(_fontData + chrOffset); return chrData; @@ -72,20 +73,18 @@ int Font::getCharWidth(uint32 chr) const { void Font::drawChar(Graphics::Surface *dst, uint32 chr, int posX, int posY, uint32 color) const { const ChrData chrData = getChrData(chr); - for (int y = 0; y < chrData._height; ++y) { - for (int x = 0; x < chrData._width; ++x) { + for (int y = 0; y < chrData._height; y++) { + for (int x = 0; x < chrData._width; x++) { byte d = chrData._pixels[x + (chrData._width * y)]; if (d == 0) d = 255; else if (d == 1) d = 0; else if (d == 2) d = color; else if (d == 3) d = 0; if (d != 255) { - *(byte*)dst->getBasePtr(posX + x, posY + y) = d; + *(byte *)dst->getBasePtr(posX + x, posY + y) = d; } } } } -} - -/* vim: set tabstop=4 expandtab!: */ +} // End of namespace Prince diff --git a/engines/prince/font.h b/engines/prince/font.h index bf9c09d0e90e..001e9f7668d4 100644 --- a/engines/prince/font.h +++ b/engines/prince/font.h @@ -23,14 +23,9 @@ #define PRINCE_FONT_H #include "graphics/font.h" +#include "graphics/surface.h" -namespace Graphics { - struct Surface; -} - -namespace Common { - class String; -} +#include "common/str.h" namespace Prince { @@ -63,8 +58,6 @@ class Font : public Graphics::Font { byte *_fontData; }; -} +} // End of namespace Prince #endif - -/* vim: set tabstop=4 expandtab!: */ diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 58ab7b0f21c4..f70002c28bf4 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -21,9 +21,7 @@ */ #include "prince/graphics.h" - #include "prince/prince.h" - #include "prince/mhwanh.h" #include "graphics/palette.h" @@ -32,28 +30,34 @@ namespace Prince { -GraphicsMan::GraphicsMan(PrinceEngine *vm) - : _vm(vm), _changed(false) { +GraphicsMan::GraphicsMan(PrinceEngine *vm) : _vm(vm), _changed(false) { initGraphics(640, 480, true); + _frontScreen = new Graphics::Surface(); _frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); + _screenForInventory = new Graphics::Surface(); _screenForInventory->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); + _mapScreen = new Graphics::Surface(); _mapScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); - _shadowTable70 = new byte[256]; - _shadowTable50 = new byte[256]; + + _shadowTable70 = (byte *)malloc(256); + _shadowTable50 = (byte *)malloc(256); } GraphicsMan::~GraphicsMan() { _frontScreen->free(); delete _frontScreen; + _screenForInventory->free(); delete _screenForInventory; + _mapScreen->free(); delete _mapScreen; - delete[] _shadowTable70; - delete[] _shadowTable50; + + free(_shadowTable70); + free(_shadowTable50); } void GraphicsMan::update(Graphics::Surface *screen) { @@ -382,5 +386,3 @@ void GraphicsMan::makeShadowTable(int brightness, byte *shadowPalette) { } } // End of namespace Prince - -/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index 57e28fdae51e..95c10ec790a3 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -28,8 +28,8 @@ namespace Prince { class PrinceEngine; -struct DrawNode; class MhwanhDecoder; +struct DrawNode; class GraphicsMan { public: @@ -68,12 +68,10 @@ class GraphicsMan { void drawPixel(Graphics::Surface *screen, int32 posX, int32 posY); private: - PrinceEngine *_vm; - bool _changed; }; -} +} // End of namespace Prince #endif diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 79a69da47154..685964c78726 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ + #include "common/debug.h" #include "common/random.h" @@ -33,21 +34,24 @@ namespace Prince { -Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph) - , _number(0), _visible(false), _state(kHeroStateStay), _middleX(0), _middleY(0) - , _boreNum(1), _currHeight(0), _moveDelay(0), _shadMinus(0), _moveSetType(0), _zoomedHeroSurface(nullptr) - , _lastDirection(kHeroDirDown), _destDirection(kHeroDirDown), _talkTime(0), _boredomTime(0), _phase(0) - , _specAnim(nullptr), _drawX(0), _drawY(0), _drawZ(0), _zoomFactor(0), _scaleValue(0) - , _shadZoomFactor(0), _shadScaleValue(0), _shadLineLen(0), _shadDrawX(0), _shadDrawY(0) - , _frameXSize(0), _frameYSize(0), _scaledFrameXSize(0), _scaledFrameYSize(0), _color(0) - , _coords(nullptr), _dirTab(nullptr), _currCoords(nullptr), _currDirTab(nullptr), _step(0) - , _maxBoredom(200), _turnAnim(0), _leftRightMainDir(0), _upDownMainDir(0), _animSetNr(0) +Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph), + _number(0), _visible(false), _state(kHeroStateStay), _middleX(0), _middleY(0), + _boreNum(1), _currHeight(0), _moveDelay(0), _shadMinus(0), _moveSetType(0), _zoomedHeroSurface(nullptr), + _lastDirection(kHeroDirDown), _destDirection(kHeroDirDown), _talkTime(0), _boredomTime(0), _phase(0), + _specAnim(nullptr), _drawX(0), _drawY(0), _drawZ(0), _zoomFactor(0), _scaleValue(0), + _shadZoomFactor(0), _shadScaleValue(0), _shadLineLen(0), _shadDrawX(0), _shadDrawY(0), + _frameXSize(0), _frameYSize(0), _scaledFrameXSize(0), _scaledFrameYSize(0), _color(0), + _coords(nullptr), _dirTab(nullptr), _currCoords(nullptr), _currDirTab(nullptr), _step(0), + _maxBoredom(200), _turnAnim(0), _leftRightMainDir(0), _upDownMainDir(0), _animSetNr(0) { - _shadowLine = new byte[kShadowLineArraySize]; + _shadowLine = (byte *)malloc(kShadowLineArraySize); } Hero::~Hero() { - delete[] _shadowLine; + if (_shadowLine != nullptr) { + free(_shadowLine); + _shadowLine = nullptr; + } freeHeroAnim(); freeOldMove(); freeZoomedSurface(); @@ -141,7 +145,7 @@ Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) { for (int i = 0; i < _scaledFrameYSize; i++) { // linear_loop: - while(1) { + while (1) { sprZoomY -= 100; if (sprZoomY >= 0 || _scaleValue == 10000) { // all_r_y @@ -477,7 +481,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { } } //krap2 - shadWallDestAddr -= kScreenWidth; + shadWallDestAddr -= _vm->kNormalWidth; shadWallBitAddr -= _vm->kMaxPicWidth / 8; shadWallPosY--; } @@ -1027,6 +1031,4 @@ void Hero::freeZoomedSurface() { } } -} - -/* vim: set tabstop=4 noexpandtab: */ +} // End of namespace Prince diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 7c30fda559fa..00c47e1dc4b4 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -41,7 +41,6 @@ class Hero { public: static const uint32 kMoveSetSize = 26; static const int16 kShadowLineArraySize = 2 * 1280 * 4; - static const int16 kScreenWidth = 640; static const int16 kStepLeftRight = 8; static const int16 kStepUpDown = 4; @@ -189,8 +188,6 @@ class Hero { uint32 _shadMinus; }; -} +} // End of namespace Prince #endif - -/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/hero_set.cpp b/engines/prince/hero_set.cpp deleted file mode 100644 index 1d235a567aac..000000000000 --- a/engines/prince/hero_set.cpp +++ /dev/null @@ -1,243 +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/hero_set.h" -#include "common/scummsys.h" - -namespace Prince { - -static HeroSetAnimNames heroSet5 = { - "SL_DIAB.ANI", - "SR_DIAB.ANI", - "SU_DIAB.ANI", - "SD_DIAB.ANI", - NULL, - NULL, - "MU_DIAB.ANI", - "MD_DIAB.ANI", - "TL_DIAB.ANI", - "TR_DIAB.ANI", - "TU_DIAB.ANI", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL -}; - -static HeroSetAnimNames heroSet1 = { - "SL_HERO1.ANI", - "SR_HERO1.ANI", - "SU_HERO1.ANI", - "SD_HERO1.ANI", - "ML_HERO1.ANI", - "MR_HERO1.ANI", - "MU_HERO1.ANI", - "MD_HERO1.ANI", - "TL_HERO1.ANI", - "TR_HERO1.ANI", - "TU_HERO1.ANI", - "TD_HERO1.ANI", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "KSI_KURZ.ANI", - "KS_WLOSY.ANI" -}; - -static HeroSetAnimNames heroSet2 = { - "SL_HERO2.ANI", - "SR_HERO2.ANI", - "SU_HERO2.ANI", - "SD_HERO2.ANI", - "ML_HERO2.ANI", - "MR_HERO2.ANI", - "MU_HERO2.ANI", - "MD_HERO2.ANI", - "TL_HERO2.ANI", - "TR_HERO2.ANI", - "TU_HERO2.ANI", - "TD_HERO2.ANI", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "KSI_KU_S.ANI", - "KS_WLO_S.ANI" -}; - -static HeroSetAnimNames heroSet3 = { - "SL_BEAR.ANI", - "SR_BEAR.ANI", - "SU_BEAR.ANI", - "SD_BEAR.ANI", - "NIED-LEW.ANI", - "NIED-PRW.ANI", - "NIED-TYL.ANI", - "NIED-PRZ.ANI", - "SL_BEAR.ANI", - "SR_BEAR.ANI", - "SU_BEAR.ANI", - "SD_BEAR.ANI", - "N_LW-TYL.ANI", - "N_LW-PRZ.ANI", - "N_LW-PR.ANI", - "N_PR-TYL.ANI", - "N_PR-PRZ.ANI", - "N_PR-LW.ANI", - "N_TYL-LW.ANI", - "N_TYL-PR.ANI", - "N_TL-PRZ.ANI", - "N_PRZ-LW.ANI", - "N_PRZ-PR.ANI", - "N_PRZ-TL.ANI", - NULL, - NULL, -}; - -static HeroSetAnimNames shanSet1 = { - "SL_SHAN.ANI", - "SR_SHAN.ANI", - "SU_SHAN.ANI", - "SD_SHAN.ANI", - "ML_SHAN.ANI", - "MR_SHAN.ANI", - "MU_SHAN.ANI", - "MD_SHAN.ANI", - "TL_SHAN.ANI", - "TR_SHAN.ANI", - "TU_SHAN.ANI", - "TD_SHAN.ANI", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "B1_SHAN.ANI", - "B2_SHAN.ANI", -}; - -static HeroSetAnimNames shanSet2 = { - "SL_SHAN2.ANI", - "SR_SHAN2.ANI", - "SU_SHAN.ANI", - "SD_SHAN2.ANI", - "ML_SHAN2.ANI", - "MR_SHAN2.ANI", - "MU_SHAN.ANI", - "MD_SHAN2.ANI", - "TL_SHAN2.ANI", - "TR_SHAN2.ANI", - "TU_SHAN.ANI", - "TD_SHAN2.ANI", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "B1_SHAN2.ANI", - "B2_SHAN2.ANI" -}; - -static HeroSetAnimNames arivSet1 = { - "SL_ARIV.ANI", - "SR_ARIV.ANI", - "SU_ARIV.ANI", - "SD_ARIV.ANI", - "ML_ARIV.ANI", - "MR_ARIV.ANI", - "MU_ARIV.ANI", - "MD_ARIV.ANI", - "TL_ARIV.ANI", - "TR_ARIV.ANI", - "TU_ARIV.ANI", - "TD_ARIV.ANI", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL -}; - -const HeroSetAnimNames *heroSetTable[7] = { - &heroSet1, - &heroSet2, - &heroSet3, - &shanSet1, - &arivSet1, - &heroSet5, - &shanSet2, -}; - -} -/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/hero_set.h b/engines/prince/hero_set.h index e0c7887b94dc..1674f67503ff 100644 --- a/engines/prince/hero_set.h +++ b/engines/prince/hero_set.h @@ -20,12 +20,225 @@ * */ +#include "common/scummsys.h" + namespace Prince { +const int heroSetBack[7] = { 0, 0, 10, 0, 6, 0, 0 }; + typedef const char *HeroSetAnimNames[26]; -const int heroSetBack[7] = { 0, 0, 10, 0, 6, 0, 0 }; -extern const HeroSetAnimNames *heroSetTable[7]; +static HeroSetAnimNames heroSet5 = { + "SL_DIAB.ANI", + "SR_DIAB.ANI", + "SU_DIAB.ANI", + "SD_DIAB.ANI", + NULL, + NULL, + "MU_DIAB.ANI", + "MD_DIAB.ANI", + "TL_DIAB.ANI", + "TR_DIAB.ANI", + "TU_DIAB.ANI", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +static HeroSetAnimNames heroSet1 = { + "SL_HERO1.ANI", + "SR_HERO1.ANI", + "SU_HERO1.ANI", + "SD_HERO1.ANI", + "ML_HERO1.ANI", + "MR_HERO1.ANI", + "MU_HERO1.ANI", + "MD_HERO1.ANI", + "TL_HERO1.ANI", + "TR_HERO1.ANI", + "TU_HERO1.ANI", + "TD_HERO1.ANI", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "KSI_KURZ.ANI", + "KS_WLOSY.ANI" +}; + +static HeroSetAnimNames heroSet2 = { + "SL_HERO2.ANI", + "SR_HERO2.ANI", + "SU_HERO2.ANI", + "SD_HERO2.ANI", + "ML_HERO2.ANI", + "MR_HERO2.ANI", + "MU_HERO2.ANI", + "MD_HERO2.ANI", + "TL_HERO2.ANI", + "TR_HERO2.ANI", + "TU_HERO2.ANI", + "TD_HERO2.ANI", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "KSI_KU_S.ANI", + "KS_WLO_S.ANI" +}; + +static HeroSetAnimNames heroSet3 = { + "SL_BEAR.ANI", + "SR_BEAR.ANI", + "SU_BEAR.ANI", + "SD_BEAR.ANI", + "NIED-LEW.ANI", + "NIED-PRW.ANI", + "NIED-TYL.ANI", + "NIED-PRZ.ANI", + "SL_BEAR.ANI", + "SR_BEAR.ANI", + "SU_BEAR.ANI", + "SD_BEAR.ANI", + "N_LW-TYL.ANI", + "N_LW-PRZ.ANI", + "N_LW-PR.ANI", + "N_PR-TYL.ANI", + "N_PR-PRZ.ANI", + "N_PR-LW.ANI", + "N_TYL-LW.ANI", + "N_TYL-PR.ANI", + "N_TL-PRZ.ANI", + "N_PRZ-LW.ANI", + "N_PRZ-PR.ANI", + "N_PRZ-TL.ANI", + NULL, + NULL, +}; + +static HeroSetAnimNames shanSet1 = { + "SL_SHAN.ANI", + "SR_SHAN.ANI", + "SU_SHAN.ANI", + "SD_SHAN.ANI", + "ML_SHAN.ANI", + "MR_SHAN.ANI", + "MU_SHAN.ANI", + "MD_SHAN.ANI", + "TL_SHAN.ANI", + "TR_SHAN.ANI", + "TU_SHAN.ANI", + "TD_SHAN.ANI", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "B1_SHAN.ANI", + "B2_SHAN.ANI", +}; + +static HeroSetAnimNames shanSet2 = { + "SL_SHAN2.ANI", + "SR_SHAN2.ANI", + "SU_SHAN.ANI", + "SD_SHAN2.ANI", + "ML_SHAN2.ANI", + "MR_SHAN2.ANI", + "MU_SHAN.ANI", + "MD_SHAN2.ANI", + "TL_SHAN2.ANI", + "TR_SHAN2.ANI", + "TU_SHAN.ANI", + "TD_SHAN2.ANI", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "B1_SHAN2.ANI", + "B2_SHAN2.ANI" +}; + +static HeroSetAnimNames arivSet1 = { + "SL_ARIV.ANI", + "SR_ARIV.ANI", + "SU_ARIV.ANI", + "SD_ARIV.ANI", + "ML_ARIV.ANI", + "MR_ARIV.ANI", + "MU_ARIV.ANI", + "MD_ARIV.ANI", + "TL_ARIV.ANI", + "TR_ARIV.ANI", + "TU_ARIV.ANI", + "TD_ARIV.ANI", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +const HeroSetAnimNames *heroSetTable[7] = { + &heroSet1, + &heroSet2, + &heroSet3, + &shanSet1, + &arivSet1, + &heroSet5, + &shanSet2, +}; -} -/* vim: set tabstop=4 noexpandtab: */ +} // End of namespace Prince diff --git a/engines/prince/mhwanh.cpp b/engines/prince/mhwanh.cpp index 3bd034e4a761..ef94ef71f99b 100644 --- a/engines/prince/mhwanh.cpp +++ b/engines/prince/mhwanh.cpp @@ -28,8 +28,7 @@ namespace Prince { -MhwanhDecoder::MhwanhDecoder() - : _surface(NULL), _palette(0), _paletteColorCount(0) { +MhwanhDecoder::MhwanhDecoder() : _surface(nullptr), _palette(nullptr) { } MhwanhDecoder::~MhwanhDecoder() { @@ -37,38 +36,36 @@ MhwanhDecoder::~MhwanhDecoder() { } void MhwanhDecoder::destroy() { - if (_surface) { + if (_surface != nullptr) { _surface->free(); delete _surface; - _surface = 0; + _surface = nullptr; + } + if (_palette != nullptr) { + free(_palette); + _palette = nullptr; } - - delete [] _palette; _palette = 0; - _paletteColorCount = 0; } bool MhwanhDecoder::loadStream(Common::SeekableReadStream &stream) { destroy(); - _paletteColorCount = 256; stream.seek(0); stream.skip(0x20); // Read the palette - _palette = new byte[_paletteColorCount * 3]; - for (uint16 i = 0; i < _paletteColorCount; i++) { - _palette[i * 3 + 0] = stream.readByte(); + _palette = (byte *)malloc(kPaletteColorCount * 3); + for (uint16 i = 0; i < kPaletteColorCount; i++) { + _palette[i * 3] = stream.readByte(); _palette[i * 3 + 1] = stream.readByte(); _palette[i * 3 + 2] = stream.readByte(); } _surface = new Graphics::Surface(); _surface->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); - for (int h = 0; h < 480; ++h) { + for (int h = 0; h < 480; h++) { stream.read(_surface->getBasePtr(0, h), 640); } return true; } -} - -/* vim: set tabstop=4 noexpandtab: */ +} // End of namespace Prince diff --git a/engines/prince/mhwanh.h b/engines/prince/mhwanh.h index 02256569cea3..cfa14630b7fd 100644 --- a/engines/prince/mhwanh.h +++ b/engines/prince/mhwanh.h @@ -25,7 +25,9 @@ #include "image/image_decoder.h" #include "image/bmp.h" + #include "graphics/surface.h" + #include "resource.h" namespace Prince { @@ -40,12 +42,12 @@ class MhwanhDecoder : public Image::ImageDecoder { virtual bool loadStream(Common::SeekableReadStream &stream); virtual Graphics::Surface *getSurface() const { return _surface; } virtual const byte *getPalette() const { return _palette; } - uint16 getPaletteCount() const { return _paletteColorCount; } + uint16 getPaletteCount() const { return kPaletteColorCount; } + static const uint16 kPaletteColorCount = 256; private: Graphics::Surface *_surface; byte *_palette; - uint16 _paletteColorCount; }; namespace Resource { @@ -60,8 +62,6 @@ namespace Resource { } } -} +} // End of namespace Prince #endif - -/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/mob.cpp b/engines/prince/mob.cpp index 7ed4f581036f..9f3ff5d7b838 100644 --- a/engines/prince/mob.cpp +++ b/engines/prince/mob.cpp @@ -22,8 +22,6 @@ #include "prince/mob.h" -#include "common/stream.h" - namespace Prince { bool Mob::loadFromStream(Common::SeekableReadStream &stream) { @@ -107,6 +105,4 @@ uint16 Mob::getData(AttrId dataId) { } } -} - -/* vim: set tabstop=4 noexpandtab: */ +} // End of namespace Prince diff --git a/engines/prince/mob.h b/engines/prince/mob.h index 36630eb6eb89..aaa51988b202 100644 --- a/engines/prince/mob.h +++ b/engines/prince/mob.h @@ -26,13 +26,10 @@ #include "common/scummsys.h" #include "common/rect.h" #include "common/str.h" +#include "common/stream.h" #include "prince/common.h" -namespace Common { - class SeekableReadStream; -} - namespace Prince { class Mob { @@ -79,8 +76,6 @@ class Mob { Common::String _examText; }; -} +} // End of namespace Prince #endif - -/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/module.mk b/engines/prince/module.mk index 584fb99a9793..2dfa538a6e95 100644 --- a/engines/prince/module.mk +++ b/engines/prince/module.mk @@ -17,7 +17,6 @@ MODULE_OBJS = \ archive.o \ decompress.o \ hero.o \ - hero_set.o \ cursor.o \ pscr.o \ saveload.o diff --git a/engines/prince/musNum.h b/engines/prince/musNum.h index 65b31f817509..c24cba6ad72e 100644 --- a/engines/prince/musNum.h +++ b/engines/prince/musNum.h @@ -84,4 +84,4 @@ enum RoomMus { ROOM61MUS = 0 }; -} +} // End of namespace Prince diff --git a/engines/prince/object.cpp b/engines/prince/object.cpp index 7e4bd1bbeeb8..a9a96455b191 100644 --- a/engines/prince/object.cpp +++ b/engines/prince/object.cpp @@ -25,7 +25,6 @@ #include "common/debug.h" #include "common/stream.h" - #include "graphics/surface.h" #include "prince/object.h" @@ -65,8 +64,9 @@ void Object::loadSurface(Common::SeekableReadStream &stream) { bool Object::loadFromStream(Common::SeekableReadStream &stream) { int32 pos = stream.pos(); uint16 x = stream.readUint16LE(); - if (x == 0xFFFF) + if (x == 0xFFFF) { return false; + } _x = x; _y = stream.readSint16LE(); // skull mini-game has some signed y coords @@ -82,8 +82,6 @@ bool Object::loadFromStream(Common::SeekableReadStream &stream) { stream.seek(pos + 16); - //debug("Object x %d, y %d, z %d overlay %d", _x, _y, _z, _mask); - return true; } @@ -112,5 +110,4 @@ int32 Object::getData(AttrId dataId) { } } -} -/* vim: set tabstop=4 noexpandtab: */ +} // End of namespace Prince diff --git a/engines/prince/object.h b/engines/prince/object.h index 31e88ac9e4c8..68edd061a0d6 100644 --- a/engines/prince/object.h +++ b/engines/prince/object.h @@ -65,7 +65,6 @@ class Object { Graphics::Surface *_surface; }; -} +} // End of namespace Prince #endif -/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/option_text.h b/engines/prince/option_text.h index 0a1548a8a5ce..d4d214c98cee 100644 --- a/engines/prince/option_text.h +++ b/engines/prince/option_text.h @@ -82,5 +82,4 @@ const char *optionsTextEN[] = { "Talk to" }; -} - +} // End of namespace Prince diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index ee96895d31bc..49d76afab755 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -21,7 +21,6 @@ */ #include "common/scummsys.h" - #include "common/config-manager.h" #include "common/debug-channels.h" #include "common/debug.h" @@ -77,8 +76,8 @@ void PrinceEngine::debugEngine(const char *s, ...) { PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _graph(nullptr), _script(nullptr), _interpreter(nullptr), _flags(nullptr), - _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), _room(nullptr), testAnimNr(0), testAnimFrame(0), - _frameNr(0), _cursor1(nullptr), _cursor2(nullptr), _cursor3(nullptr), _font(nullptr), + _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), _room(nullptr), _frameNr(0), + _cursor1(nullptr), _cursor2(nullptr), _cursor3(nullptr), _font(nullptr), _suitcaseBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0), _randomSource("prince"), _invLineX(134), _invLineY(176), _invLine(5), _invLines(3), _invLineW(70), _invLineH(76), _maxInvW(72), _maxInvH(76), _invLineSkipX(2), _invLineSkipY(3), _showInventoryFlag(false), _inventoryBackgroundRemember(false), @@ -121,9 +120,9 @@ PrinceEngine::~PrinceEngine() { delete _roomBmp; delete _suitcaseBmp; delete _variaTxt; - delete[] _talkTxt; - delete[] _invTxt; - delete[] _dialogDat; + free(_talkTxt); + free(_invTxt); + free(_dialogDat); delete _graph; delete _room; @@ -137,7 +136,7 @@ PrinceEngine::~PrinceEngine() { } _objList.clear(); - delete[] _objSlot; + free(_objSlot); for (uint32 i = 0; i < _pscrList.size(); i++) { delete _pscrList[i]; @@ -258,7 +257,7 @@ void PrinceEngine::init() { return; } _talkTxtSize = talkTxtStream->size(); - _talkTxt = new byte[_talkTxtSize]; + _talkTxt = (byte *)malloc(_talkTxtSize); talkTxtStream->read(_talkTxt, _talkTxtSize); delete talkTxtStream; @@ -269,7 +268,7 @@ void PrinceEngine::init() { return; } _invTxtSize = invTxtStream->size(); - _invTxt = new byte[_invTxtSize]; + _invTxt = (byte *)malloc(_invTxtSize); invTxtStream->read(_invTxt, _invTxtSize); delete invTxtStream; @@ -282,7 +281,7 @@ void PrinceEngine::init() { return; } _dialogDatSize = dialogDatStream->size(); - _dialogDat = new byte[_dialogDatSize]; + _dialogDat = (byte *)malloc(_dialogDatSize); dialogDatStream->read(_dialogDat, _dialogDatSize); delete dialogDatStream; @@ -325,7 +324,7 @@ void PrinceEngine::init() { _normAnimList.push_back(tempAnim); } - _objSlot = new int[kMaxObjects]; + _objSlot = (uint16 *)malloc(kMaxObjects * sizeof(uint16)); for (int i = 0; i < kMaxObjects; i++) { _objSlot[i] = 0xFF; } @@ -551,10 +550,10 @@ void PrinceEngine::makeInvCursor(int itemNr) { byte *src1 = (byte *)itemSurface->getBasePtr(0, 0); byte *dst1 = (byte *)_cursor2->getBasePtr(cur1W, cur1H); - if (itemH % 2 != 0) { + if (itemH % 2) { itemH--; } - if (itemW % 2 != 0) { + if (itemW % 2) { itemW--; } @@ -564,7 +563,7 @@ void PrinceEngine::makeInvCursor(int itemNr) { if (y % 2 == 0) { for (int x = 0; x < itemW; x++, src2++) { if (x % 2 == 0) { - if (*src2 != 0) { + if (*src2) { *dst2 = *src2; } else { *dst2 = 255; @@ -880,81 +879,9 @@ void PrinceEngine::keyHandler(Common::Event event) { getDebugger()->attach(); } break; - case Common::KEYCODE_LEFT: - if(testAnimNr > 0) { - testAnimNr--; - } - debug("testAnimNr: %d", testAnimNr); - break; - case Common::KEYCODE_RIGHT: - testAnimNr++; - debug("testAnimNr: %d", testAnimNr); - break; case Common::KEYCODE_ESCAPE: _flags->setFlagValue(Flags::ESCAPED2, 1); break; - case Common::KEYCODE_UP: - _mainHero->_phase++; - debugEngine("%d", _mainHero->_phase); - testAnimFrame++; - break; - case Common::KEYCODE_DOWN: - if(_mainHero->_phase > 0) { - _mainHero->_phase--; - } - if (testAnimFrame > 0) { - testAnimFrame--; - } - debugEngine("%d", _mainHero->_phase); - break; - case Common::KEYCODE_w: - _mainHero->_lastDirection = _mainHero->kHeroDirUp; - debugEngine("UP"); - break; - case Common::KEYCODE_s: - _mainHero->_lastDirection = _mainHero->kHeroDirDown; - debugEngine("DOWN"); - break; - case Common::KEYCODE_a: - _mainHero->_lastDirection = _mainHero->kHeroDirLeft; - debugEngine("LEFT"); - break; - case Common::KEYCODE_f: - _mainHero->_lastDirection = _mainHero->kHeroDirRight; - debugEngine("RIGHT"); - break; - case Common::KEYCODE_1: - if(_mainHero->_state > 0) { - _mainHero->_state--; - } - debugEngine("%d", _mainHero->_state); - break; - case Common::KEYCODE_2: - _mainHero->_state++; - debugEngine("%d", _mainHero->_state); - break; - case Common::KEYCODE_i: - _mainHero->_middleY -= 5; - break; - case Common::KEYCODE_k: - _mainHero->_middleY += 5; - break; - case Common::KEYCODE_j: - _mainHero->_middleX -= 5; - break; - case Common::KEYCODE_l: - _mainHero->_middleX += 5; - break; - case Common::KEYCODE_EQUALS: - if (_debugger->_locationNr > 1) { - _debugger->_locationNr--; - } - break; - case Common::KEYCODE_BACKSPACE: - if (_debugger->_locationNr < 43) { - _debugger->_locationNr++; - } - break; } } @@ -1144,10 +1071,11 @@ void PrinceEngine::printAt(uint32 slot, uint8 color, char *s, uint16 x, uint16 y text._x = x; text._y = y; text._color = color; - text._time = calcText(s) * 30; + int lines = calcTextLines(s); + text._time = calcTextTime(lines); } -int PrinceEngine::calcText(const char *s) { +int PrinceEngine::calcTextLines(const char *s) { int lines = 1; while (*s) { if (*s == '\n') { @@ -1156,7 +1084,10 @@ int PrinceEngine::calcText(const char *s) { s++; } return lines; - //time = lines * 30 +} + +int PrinceEngine::calcTextTime(int numberOfLines) { + return numberOfLines * 30; } uint32 PrinceEngine::getTextWidth(const char *s) { @@ -1742,7 +1673,7 @@ void PrinceEngine::showParallax() { if (pscrSurface != nullptr) { int x = _pscrList[i]->_x - (_pscrList[i]->_step * _picWindowX / 4); int y = _pscrList[i]->_y; - int z = 1000; + int z = PScr::kPScrZ; if (spriteCheck(pscrSurface->w, pscrSurface->h, x, y)) { showSprite(pscrSurface, x, y, z); } @@ -2355,24 +2286,17 @@ void PrinceEngine::inventoryLeftMouseButton() { } if (_optionsFlag == 1) { - //check_opt if (_selectedMob != -1) { - //inv_check_mob if (_optionEnabled < _invOptionsNumber) { _optionsFlag = 0; - //do_option } else { return; } } else { error("PrinceEngine::inventoryLeftMouseButton() - optionsFlag = 1, selectedMob = 0"); - // test bx, RMBMask 7996 ? right mouse button here? - > return; - //disable_use if (_currentPointerNumber == 2) { - //disableuseuse changeCursor(1); _currentPointerNumber = 1; - //exit_normally _selectedMob = -1; _optionsMob = -1; return; @@ -2389,7 +2313,6 @@ void PrinceEngine::inventoryLeftMouseButton() { // map item _optionEnabled = 1; } - //do_option } else { //use_item_on_item int invObjUU = _script->scanMobEventsWithItem(_invMobList[_selectedMob]._mask, _script->_scriptInfo.invObjUU, _selectedItem); @@ -2402,15 +2325,12 @@ void PrinceEngine::inventoryLeftMouseButton() { printAt(0, 216, (char *)_variaTxt->getString(textNr - 80000), kNormalWidth / 2, 100); setVoice(0, 28, 1); playSample(28, 0); - //exit_normally _selectedMob = -1; _optionsMob = -1; return; } else { - //store_new_pc _interpreter->storeNewPC(invObjUU); _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask); - //byeinv _showInventoryFlag = false; } } @@ -2430,12 +2350,9 @@ void PrinceEngine::inventoryLeftMouseButton() { // disableuseuse changeCursor(0); _currentPointerNumber = 1; - //exit_normally } else { - //store_new_pc _interpreter->storeNewPC(invObjExamEvent); _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask); - //bye_inv _showInventoryFlag = false; } } else if (_optionEnabled == 1) { @@ -2448,23 +2365,18 @@ void PrinceEngine::inventoryLeftMouseButton() { makeInvCursor(_invMobList[_selectedMob]._mask); _currentPointerNumber = 2; changeCursor(2); - //exit_normally } else { - //store_new_pc _interpreter->storeNewPC(invObjUse); _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask); - //bye_inv _showInventoryFlag = false; } } else if (_optionEnabled == 4) { - // not_use_inv // do_standard_give _selectedMode = 1; _selectedItem = _invMobList[_selectedMob]._mask; makeInvCursor(_invMobList[_selectedMob]._mask); _currentPointerNumber = 2; changeCursor(2); - //exit_normally } else { // use_item_on_item int invObjUU = _script->scanMobEventsWithItem(_invMobList[_selectedMob]._mask, _script->_scriptInfo.invObjUU, _selectedItem); @@ -2477,16 +2389,12 @@ void PrinceEngine::inventoryLeftMouseButton() { printAt(0, 216, (char *)_variaTxt->getString(textNr - 80000), kNormalWidth / 2, 100); setVoice(0, 28, 1); playSample(28, 0); - //exit_normally } else { - //store_new_pc _interpreter->storeNewPC(invObjUU); _flags->setFlagValue(Flags::CURRMOB, _invMobList[_selectedMob]._mask); - //byeinv _showInventoryFlag = false; } } - //exit_normally _selectedMob = -1; _optionsMob = -1; } @@ -2733,7 +2641,7 @@ void PrinceEngine::createDialogBox(int dialogBoxNr) { while ((sentenceNumber = *dialogText) != 0xFF) { dialogText++; if (!(dialogDataValue & (1 << sentenceNumber))) { - _dialogLines += calcText((const char *)dialogText); + _dialogLines += calcTextLines((const char *)dialogText); amountOfDialogOptions++; } do { @@ -2756,7 +2664,7 @@ void PrinceEngine::runDialog() { while (!shouldQuit()) { drawScreen(); - // background iterpreter? + // TODO - background iterpreter? int dialogX = (640 - _dialogWidth) / 2; int dialogY = 460 - _dialogHeight; @@ -2849,7 +2757,6 @@ void PrinceEngine::runDialog() { _dialogImage->free(); delete _dialogImage; _dialogFlag = false; - // cursor? } void PrinceEngine::dialogLeftMouseButton(byte *string, int dialogSelected) { @@ -2873,7 +2780,7 @@ void PrinceEngine::dialogLeftMouseButton(byte *string, int dialogSelected) { void PrinceEngine::talkHero(int slot) { // heroSlot = textSlot (slot 0 or 1) Text &text = _textSlots[slot]; - int lines = calcText((const char *)_interpreter->getString()); + int lines = calcTextLines((const char *)_interpreter->getString()); int time = lines * 30; if (slot == 0) { @@ -2896,7 +2803,7 @@ void PrinceEngine::talkHero(int slot) { void PrinceEngine::doTalkAnim(int animNumber, int slot, AnimType animType) { Text &text = _textSlots[slot]; - int lines = calcText((const char *)_interpreter->getString()); + int lines = calcTextLines((const char *)_interpreter->getString()); int time = lines * 30; if (animType == kNormalAnimation) { Anim &normAnim = _normAnimList[animNumber]; @@ -4545,5 +4452,3 @@ void PrinceEngine::mainLoop() { } } // End of namespace Prince - -/* vim: set tabstop=4 expandtab!: */ diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 4b8d78ad947f..a1379d6b5976 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -49,7 +49,6 @@ #include "prince/object.h" #include "prince/pscr.h" - namespace Prince { struct PrinceGameDescription; @@ -301,7 +300,8 @@ class PrinceEngine : public Engine { void changeCursor(uint16 curId); void printAt(uint32 slot, uint8 color, char *s, uint16 x, uint16 y); - int calcText(const char *s); + int calcTextLines(const char *s); + int calcTextTime(int numberOfLines); static const uint8 kMaxTexts = 32; Text _textSlots[kMaxTexts]; @@ -355,7 +355,7 @@ class PrinceEngine : public Engine { Common::Array _mobPriorityList; Common::Array _maskList; Common::Array _objList; - int *_objSlot; + uint16 *_objSlot; void freeNormAnim(int slot); void freeAllNormAnims(); @@ -563,9 +563,6 @@ class PrinceEngine : public Engine { int checkRightDownDir(); int checkRightUpDir(); - int testAnimNr; - int testAnimFrame; - private: bool playNextFrame(); void keyHandler(Common::Event event); @@ -620,5 +617,3 @@ class PrinceEngine : public Engine { } // End of namespace Prince #endif - -/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/pscr.cpp b/engines/prince/pscr.cpp index bb4316d4657d..d9d36a335615 100644 --- a/engines/prince/pscr.cpp +++ b/engines/prince/pscr.cpp @@ -21,17 +21,13 @@ */ #include "common/archive.h" -#include "common/debug-channels.h" -#include "common/debug.h" #include "common/stream.h" -#include "graphics/surface.h" - #include "prince/pscr.h" namespace Prince { -PScr::PScr() :_file(0), _x(0), _y(0), _step(0), _addr(0), _len(0), _surface(nullptr) +PScr::PScr() : _x(0), _y(0), _step(0), _surface(nullptr) { } @@ -58,15 +54,14 @@ void PScr::loadSurface(Common::SeekableReadStream &stream) { bool PScr::loadFromStream(Common::SeekableReadStream &stream) { int32 pos = stream.pos(); uint16 file = stream.readUint16LE(); - if (file == 0xFFFF) + if (file == 0xFFFF) { return false; - _file = file; + } _x = stream.readUint16LE(); _y = stream.readUint16LE(); _step = stream.readUint16LE(); - _addr = stream.readUint32LE(); - const Common::String pscrStreamName = Common::String::format("PS%02d", _file); + const Common::String pscrStreamName = Common::String::format("PS%02d", file); Common::SeekableReadStream *pscrStream = SearchMan.createReadStreamForMember(pscrStreamName); if (pscrStream != nullptr) { loadSurface(*pscrStream); @@ -74,9 +69,7 @@ bool PScr::loadFromStream(Common::SeekableReadStream &stream) { delete pscrStream; stream.seek(pos + 12); // size of PScrList struct - debug("Parallex nr %d, x %d, y %d, step %d", _file, _x, _y, _step); - return true; } -} +} // End of namespace Prince diff --git a/engines/prince/pscr.h b/engines/prince/pscr.h index 76add9602dd9..d59fa37d8126 100644 --- a/engines/prince/pscr.h +++ b/engines/prince/pscr.h @@ -23,7 +23,6 @@ #ifndef PRINCE_PSCR_H #define PRINCE_PSCR_H -#include "image/image_decoder.h" #include "graphics/surface.h" namespace Prince { @@ -32,13 +31,10 @@ class PScr { public: PScr(); ~PScr(); - - int16 _file; int16 _x; int16 _y; int16 _step; - int32 _addr; - byte _len; + static const int16 kPScrZ = 1000; bool loadFromStream(Common::SeekableReadStream &stream); Graphics::Surface *getSurface() const { return _surface; } @@ -47,7 +43,6 @@ class PScr { Graphics::Surface *_surface; }; -} +} // End of namespace Prince #endif - diff --git a/engines/prince/resource.h b/engines/prince/resource.h index c30bec0e0961..76ac5b0505b5 100644 --- a/engines/prince/resource.h +++ b/engines/prince/resource.h @@ -95,8 +95,6 @@ namespace Resource { } -} +} // End of namespace Prince #endif - -/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/saveload.cpp b/engines/prince/saveload.cpp index 4bf41b43c1f6..094d66b292ca 100644 --- a/engines/prince/saveload.cpp +++ b/engines/prince/saveload.cpp @@ -26,10 +26,12 @@ #include "prince/flags.h" #include "prince/script.h" #include "prince/hero.h" + #include "common/savefile.h" #include "common/system.h" #include "common/config-manager.h" #include "common/memstream.h" + #include "graphics/thumbnail.h" #include "graphics/surface.h" #include "graphics/palette.h" diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index a621c864cb7d..4f122d8beccc 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -31,7 +31,6 @@ #include "common/debug.h" #include "common/debug-channels.h" -#include "common/stream.h" #include "common/archive.h" #include "common/memstream.h" @@ -90,20 +89,24 @@ Script::Script(PrinceEngine *vm) : _vm(vm), _data(nullptr), _dataSize(0) { } Script::~Script() { - delete[] _data; - _dataSize = 0; - _data = nullptr; + if (_data != nullptr) { + free(_data); + _dataSize = 0; + _data = nullptr; + } } bool Script::loadFromStream(Common::SeekableReadStream &stream) { _dataSize = stream.size(); - if (!_dataSize) + if (!_dataSize) { return false; + } - _data = new byte[_dataSize]; + _data = (byte *)malloc(_dataSize); - if (!_data) + if (!_data) { return false; + } stream.read(_data, _dataSize); @@ -2015,6 +2018,4 @@ Interpreter::OpcodeFunc Interpreter::_opcodes[kNumOpcodes] = { &Interpreter::O_BREAK_POINT, }; -} - -/* vim: set tabstop=4 noexpandtab: */ +} // End of namespace Prince diff --git a/engines/prince/script.h b/engines/prince/script.h index 57f926859891..f033128e9752 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -26,13 +26,10 @@ #include "common/random.h" #include "common/endian.h" #include "common/array.h" +#include "common/stream.h" #include "prince/flags.h" -namespace Common { - class SeekableReadStream; -} - namespace Prince { class PrinceEngine; @@ -42,9 +39,9 @@ struct Anim; struct BackgroundAnim; struct Mask; +// TODO - change this to sth else? namespace Detail { template T LittleEndianReader(void *data); - template <> inline uint8 LittleEndianReader(void *data) { return *(uint8*)(data); } template <> inline uint16 LittleEndianReader(void *data) { return READ_LE_UINT16(data); } template <> inline uint32 LittleEndianReader(void *data) { return READ_LE_UINT32(data); } } @@ -233,7 +230,6 @@ class Interpreter { uint32 currentString; } _stringStack; uint8 _stacktop; - //uint8 _savedStacktop; uint32 _waitFlag; byte *_string; @@ -404,8 +400,6 @@ class Interpreter { }; -} +} // End of namespace Prince #endif - -/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/sound.cpp b/engines/prince/sound.cpp index 3509bbc2916e..0f536973b69d 100644 --- a/engines/prince/sound.cpp +++ b/engines/prince/sound.cpp @@ -37,7 +37,7 @@ namespace Prince { -const char * MusicPlayer::_musTable[] = { +const char *MusicPlayer::_musTable[] = { "", "Battlfld.mid", "Cave.mid", @@ -217,6 +217,4 @@ void MusicPlayer::sendToChannel(byte channel, uint32 b) { _channelsTable[channel]->send(b); } -} - -/* vim: set tabstop=4 expandtab!: */ +} // End of namespace Prince diff --git a/engines/prince/sound.h b/engines/prince/sound.h index 07ac9f38d920..b1711bd682eb 100644 --- a/engines/prince/sound.h +++ b/engines/prince/sound.h @@ -70,5 +70,3 @@ class MusicPlayer: public Audio::MidiPlayer { } // End of namespace Prince #endif - -/* vim: set tabstop=4 expandtab!: */ diff --git a/engines/prince/variatxt.cpp b/engines/prince/variatxt.cpp index eb4efd88771a..839ed5e66226 100644 --- a/engines/prince/variatxt.cpp +++ b/engines/prince/variatxt.cpp @@ -25,19 +25,21 @@ namespace Prince { -VariaTxt::VariaTxt() : _dataSize(0), _data(NULL) { +VariaTxt::VariaTxt() : _dataSize(0), _data(nullptr) { } VariaTxt::~VariaTxt() { _dataSize = 0; - delete[] _data; - _data = NULL; + if (_data != nullptr) { + free(_data); + _data = nullptr; + } } bool VariaTxt::loadFromStream(Common::SeekableReadStream &stream) { _dataSize = stream.size(); - _data = new byte [_dataSize]; + _data = (byte *)malloc(_dataSize); stream.read(_data, _dataSize); return true; } @@ -50,6 +52,4 @@ byte *VariaTxt::getString(uint32 stringId) { return _data + stringOffset; } -} - -/* vim: set tabstop=4 noexpandtab: */ +} // End of namespace Prince diff --git a/engines/prince/variatxt.h b/engines/prince/variatxt.h index 98efad20597e..99b225f362a9 100644 --- a/engines/prince/variatxt.h +++ b/engines/prince/variatxt.h @@ -27,11 +27,9 @@ namespace Prince { class VariaTxt { public: VariaTxt(); - ~VariaTxt(); bool loadFromStream(Common::SeekableReadStream &stream); - byte *getString(uint32 stringId); private: @@ -39,6 +37,4 @@ class VariaTxt { byte *_data; }; -} - -/* vim: set tabstop=4 noexpandtab: */ +} // End of namespace Prince From d902842f7e76ca3b719d3a213c71cac47c25cdcd Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 1 Aug 2014 17:44:39 +0200 Subject: [PATCH 312/374] PRINCE: Cursor - typo fix --- engines/prince/cursor.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/engines/prince/cursor.cpp b/engines/prince/cursor.cpp index c09fe43bfcbe..38b5be3bca40 100644 --- a/engines/prince/cursor.cpp +++ b/engines/prince/cursor.cpp @@ -40,12 +40,12 @@ Cursor::~Cursor() { bool Cursor::loadFromStream(Common::SeekableReadStream &stream) { stream.skip(4); uint16 width = stream.readUint16LE(); - uint16 heigth = stream.readUint16LE(); + uint16 height = stream.readUint16LE(); _surface = new Graphics::Surface(); - _surface->create(width, heigth, Graphics::PixelFormat::createFormatCLUT8()); + _surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); - for (int h = 0; h < heigth; h++) { + for (int h = 0; h < height; h++) { stream.read(_surface->getBasePtr(0, h), width); } return true; From 6083701914dafbb0c8c9f2f88d6cc5b082b39260 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 1 Aug 2014 17:49:07 +0200 Subject: [PATCH 313/374] PRINCE: Second hero - scroll fix --- engines/prince/prince.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 49d76afab755..5db9231459af 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1706,6 +1706,7 @@ void PrinceEngine::drawScreen() { _secondHero->showHero(); _mainHero->scrollHero(); + _secondHero->_drawX -= _picWindowX; _mainHero->drawHero(); _secondHero->drawHero(); From 0a49ba7487abd91c267e2ea37a8075d63c64f80b Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 1 Aug 2014 17:52:29 +0200 Subject: [PATCH 314/374] PRINCE: addInvObj() - update --- engines/prince/prince.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 5db9231459af..67d3722c27b0 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1904,7 +1904,7 @@ void PrinceEngine::swapInv(int heroId) { void PrinceEngine::addInvObj() { changeCursor(0); - //prepareInventoryToView(); + prepareInventoryToView(); _inventoryBackgroundRemember = true; drawScreen(); From a1ffdcbc46f9a8e3c88224ac721f7176725b9343 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 1 Aug 2014 18:25:02 +0200 Subject: [PATCH 315/374] PRINCE: Inventory opening - update --- engines/prince/prince.cpp | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 67d3722c27b0..257e84ab4e92 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -4431,19 +4431,21 @@ void PrinceEngine::mainLoop() { _frameNr++; // inventory turning on: - if (!_optionsFlag && _mouseFlag == 1) { - 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); + 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); + } } } } From 54a78d6341ddc8af6a9e80f574b65b016fe75ebb Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 2 Aug 2014 13:39:33 +0200 Subject: [PATCH 316/374] PRINCE: mainLoop() update --- engines/prince/prince.cpp | 66 ++++++++++++++++++--------------------- engines/prince/prince.h | 2 +- engines/prince/script.cpp | 2 +- 3 files changed, 32 insertions(+), 38 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 257e84ab4e92..33750d50c73d 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -71,12 +71,12 @@ void PrinceEngine::debugEngine(const char *s, ...) { vsnprintf(buf, STRINGBUFLEN, s, va); va_end(va); - debug("Prince::Engine frame %08ld %s", _frameNr, buf); + debug("Prince::Engine %s", buf); } PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _graph(nullptr), _script(nullptr), _interpreter(nullptr), _flags(nullptr), - _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), _room(nullptr), _frameNr(0), + _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), _room(nullptr), _cursor1(nullptr), _cursor2(nullptr), _cursor3(nullptr), _font(nullptr), _suitcaseBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0), _randomSource("prince"), _invLineX(134), _invLineY(176), _invLine(5), _invLines(3), _invLineW(70), _invLineH(76), _maxInvW(72), _maxInvH(76), @@ -4379,6 +4379,29 @@ void PrinceEngine::freeCoords3() { } } +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); @@ -4393,64 +4416,35 @@ void PrinceEngine::mainLoop() { case Common::EVENT_KEYDOWN: keyHandler(event); break; - case Common::EVENT_KEYUP: - break; - case Common::EVENT_MOUSEMOVE: - break; case Common::EVENT_LBUTTONDOWN: leftMouseButton(); break; case Common::EVENT_RBUTTONDOWN: rightMouseButton(); break; - case Common::EVENT_LBUTTONUP: - break; - case Common::EVENT_RBUTTONUP: - break; - case Common::EVENT_QUIT: - break; default: break; } } - if (shouldQuit()) + if (shouldQuit()) { return; + } _interpreter->step(); drawScreen(); + _graph->update(_graph->_frontScreen); + openInventoryCheck(); + // Calculate the frame delay based off a desired frame time int delay = 1000 / 15 - int32(_system->getMillis() - currentTime); // Ensure non-negative delay = delay < 0 ? 0 : delay; _system->delayMillis(delay); - _frameNr++; - - // inventory turning on: - 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); - } - } - } - } - } - } } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index a1379d6b5976..13405a634719 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -306,7 +306,6 @@ class PrinceEngine : public Engine { static const uint8 kMaxTexts = 32; Text _textSlots[kMaxTexts]; - uint64 _frameNr; Hero *_mainHero; Hero *_secondHero; @@ -439,6 +438,7 @@ class PrinceEngine : public Engine { void enableOptions(bool checkType); void checkOptions(); void checkInvOptions(); + void openInventoryCheck(); void leftMouseButton(); void rightMouseButton(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 4f122d8beccc..9b49b749a45a 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -426,7 +426,7 @@ void Interpreter::debugInterpreter(const char *s, ...) { if (!strcmp(_mode, "fg")) { debug(10, "PrinceEngine::Script %s %s", str.c_str(), buf); } - //debug("Prince::Script frame %08ld mode %s %s %s", _vm->_frameNr, _mode, str.c_str(), buf); + //debug("Prince::Script mode %s %s %s", _mode, str.c_str(), buf); } void Interpreter::step() { From 51bc133c43227d3bf5a9fb167afcc13c911ec20e Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 2 Aug 2014 16:03:54 +0200 Subject: [PATCH 317/374] PRINCE: Background interpreter during dialog boxes --- engines/prince/prince.cpp | 5 +++-- engines/prince/script.cpp | 7 ++++++- engines/prince/script.h | 3 ++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 33750d50c73d..9f01796270c8 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2664,8 +2664,8 @@ void PrinceEngine::runDialog() { while (!shouldQuit()) { + _interpreter->stepBg(); drawScreen(); - // TODO - background iterpreter? int dialogX = (640 - _dialogWidth) / 2; int dialogY = 460 - _dialogHeight; @@ -4431,7 +4431,8 @@ void PrinceEngine::mainLoop() { return; } - _interpreter->step(); + _interpreter->stepBg(); + _interpreter->stepFg(); drawScreen(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 9b49b749a45a..e0fdff1e31ca 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -429,11 +429,14 @@ void Interpreter::debugInterpreter(const char *s, ...) { //debug("Prince::Script mode %s %s %s", _mode, str.c_str(), buf); } -void Interpreter::step() { +void Interpreter::stepBg() { if (_bgOpcodePC) { _mode = "bg"; _bgOpcodePC = step(_bgOpcodePC); } +} + +void Interpreter::stepFg() { if (_fgOpcodePC) { _mode = "fg"; _fgOpcodePC = step(_fgOpcodePC); @@ -1530,6 +1533,7 @@ void Interpreter::O_DISABLEDIALOGOPT() { void Interpreter::O_SHOWDIALOGBOX() { uint16 box = readScriptFlagValue(); + uint32 currInstr = _currentInstruction; _vm->createDialogBox(box); _flags->setFlagValue(Flags::DIALINES, _vm->_dialogLines); if (_vm->_dialogLines) { @@ -1537,6 +1541,7 @@ void Interpreter::O_SHOWDIALOGBOX() { _vm->runDialog(); _vm->changeCursor(0); } + _currentInstruction = currInstr; debugInterpreter("O_SHOWDIALOGBOX box %d", box); } diff --git a/engines/prince/script.h b/engines/prince/script.h index f033128e9752..9c397b0d1f65 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -189,7 +189,8 @@ class Interpreter { void stopBg() { _bgOpcodePC = 0; } - void step(); + void stepBg(); + void stepFg(); void storeNewPC(int opcodePC); int getLastOPCode(); int getFgOpcodePC(); From 34c977574e29bbbf95c98dcba3ba4a8b5e2d5050 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 2 Aug 2014 16:20:49 +0200 Subject: [PATCH 318/374] PRINCE: Cursor after loading fix --- engines/prince/saveload.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/engines/prince/saveload.cpp b/engines/prince/saveload.cpp index 094d66b292ca..55435f168913 100644 --- a/engines/prince/saveload.cpp +++ b/engines/prince/saveload.cpp @@ -334,6 +334,10 @@ void PrinceEngine::syncGame(Common::SeekableReadStream *readStream, Common::Writ s.syncAsByte(endInv); } else { + // Cursor reset + changeCursor(1); + _currentPointerNumber = 1; + // Flag values for (int i = 0; i < _flags->kMaxFlags; i++) { uint32 value = 0; From b761953bd3bdd499f97dfbe8d12e05f045e18eaf Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 2 Aug 2014 16:21:57 +0200 Subject: [PATCH 319/374] PRINCE: displayInventory(), runDialog() clean up --- engines/prince/prince.cpp | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 9f01796270c8..a47542e24051 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2589,22 +2589,12 @@ void PrinceEngine::displayInventory() { case Common::EVENT_KEYDOWN: keyHandler(event); break; - case Common::EVENT_KEYUP: - break; - case Common::EVENT_MOUSEMOVE: - break; case Common::EVENT_LBUTTONDOWN: inventoryLeftMouseButton(); break; case Common::EVENT_RBUTTONDOWN: inventoryRightMouseButton(); break; - case Common::EVENT_LBUTTONUP: - break; - case Common::EVENT_RBUTTONUP: - break; - case Common::EVENT_QUIT: - break; default: break; } @@ -2720,24 +2710,12 @@ void PrinceEngine::runDialog() { case Common::EVENT_KEYDOWN: keyHandler(event); break; - case Common::EVENT_KEYUP: - break; - case Common::EVENT_MOUSEMOVE: - break; case Common::EVENT_LBUTTONDOWN: if (dialogSelected != -1) { dialogLeftMouseButton(dialogCurrentText, dialogSelected); _dialogFlag = false; } break; - case Common::EVENT_RBUTTONDOWN: - break; - case Common::EVENT_LBUTTONUP: - break; - case Common::EVENT_RBUTTONUP: - break; - case Common::EVENT_QUIT: - break; default: break; } From 161f21352f7a0f35562e9955373aa04b8cfb16a4 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 2 Aug 2014 17:22:47 +0200 Subject: [PATCH 320/374] PRINCE: German texts drawing - update --- engines/prince/prince.cpp | 70 ++++++++++++++++++++++----------------- engines/prince/prince.h | 1 + 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index a47542e24051..a6a664cac61b 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1032,40 +1032,10 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis } 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); - - char *strPointer = s; - if (getLanguage() == Common::DE_DEU) { - while (*strPointer) { - switch (*strPointer) { - case '\xc4': - *strPointer = '\x83'; - break; - case '\xd6': - *strPointer = '\x84'; - break; - case '\xdc': - *strPointer = '\x85'; - break; - case '\xdf': - *strPointer = '\x7f'; - break; - case '\xe4': - *strPointer = '\x80'; - break; - case '\xf6': - *strPointer = '\x81'; - break; - case '\xfc': - *strPointer = '\x82'; - break; - } - strPointer++; - } + correctStringDEU(s); } - Text &text = _textSlots[slot]; text._str = s; text._x = x; @@ -1090,6 +1060,35 @@ int PrinceEngine::calcTextTime(int numberOfLines) { return numberOfLines * 30; } +void PrinceEngine::correctStringDEU(char *s) { + while (*s) { + switch (*s) { + case '\xc4': + *s = '\x83'; + break; + case '\xd6': + *s = '\x84'; + break; + case '\xdc': + *s = '\x85'; + break; + case '\xdf': + *s = '\x7f'; + break; + case '\xe4': + *s = '\x80'; + break; + case '\xf6': + *s = '\x81'; + break; + case '\xfc': + *s = '\x82'; + break; + } + s++; + } +} + uint32 PrinceEngine::getTextWidth(const char *s) { uint16 textW = 0; while (*s) { @@ -2681,6 +2680,9 @@ void PrinceEngine::runDialog() { int actualColor = _dialogColor1; if (!(dialogDataValue & (1 << sentenceNumber))) { + if (getLanguage() == Common::DE_DEU) { + correctStringDEU((char *)dialogText); + } Common::Array lines; _font->wordWrapText((const char *)dialogText, _graph->_frontScreen->w, lines); @@ -2776,6 +2778,9 @@ void PrinceEngine::talkHero(int slot) { text._y = _secondHero->_middleY - _secondHero->_scaledFrameYSize; } text._time = time; + if (getLanguage() == Common::DE_DEU) { + correctStringDEU((char *)_interpreter->getString()); + } text._str = (const char *)_interpreter->getString(); _interpreter->increaseString(); } @@ -2813,6 +2818,9 @@ void PrinceEngine::doTalkAnim(int animNumber, int slot, AnimType animType) { 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(); } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 13405a634719..fbd71a23163d 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -302,6 +302,7 @@ class PrinceEngine : public Engine { void printAt(uint32 slot, uint8 color, char *s, uint16 x, uint16 y); int calcTextLines(const char *s); int calcTextTime(int numberOfLines); + void correctStringDEU(char *s); static const uint8 kMaxTexts = 32; Text _textSlots[kMaxTexts]; From 85f4c2ccd2079b75c3c2d18b5b6ced7c37b14746 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 4 Aug 2014 08:55:20 +0200 Subject: [PATCH 321/374] PRINCE: showHeroShadow - update --- engines/prince/graphics.cpp | 6 +- engines/prince/hero.cpp | 129 ++++++++++++++++++++---------------- engines/prince/hero.h | 13 ++-- engines/prince/prince.h | 2 +- 4 files changed, 86 insertions(+), 64 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index f70002c28bf4..e161ddd1967b 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -181,6 +181,7 @@ void GraphicsMan::drawTransparentDrawNode(Graphics::Surface *screen, DrawNode *d } void GraphicsMan::drawMaskDrawNode(Graphics::Surface *screen, DrawNode *drawNode) { + byte *maskData = (byte *)drawNode->data; byte *src1 = (byte *)drawNode->originalRoomSurface->getBasePtr(drawNode->posX, drawNode->posY); byte *dst1 = (byte *)screen->getBasePtr(drawNode->posX, drawNode->posY); int maskWidth = drawNode->width >> 3; @@ -194,7 +195,7 @@ void GraphicsMan::drawMaskDrawNode(Graphics::Surface *screen, DrawNode *drawNode for (int x = 0; x < drawNode->width; x++, src2++, dst2++) { if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { - if ((drawNode->data[tempMaskPostion] & maskCounter) != 0) { + if ((maskData[tempMaskPostion] & maskCounter) != 0) { *dst2 = *src2; //*dst2 = 0; // for debugging } @@ -214,6 +215,7 @@ void GraphicsMan::drawMaskDrawNode(Graphics::Surface *screen, DrawNode *drawNode } void GraphicsMan::drawAsShadowDrawNode(Graphics::Surface *screen, DrawNode *drawNode) { + byte *shadowData = (byte *)drawNode->data; byte *src1 = (byte *)drawNode->s->getBasePtr(0, 0); byte *dst1 = (byte *)screen->getBasePtr(drawNode->posX, drawNode->posY); @@ -224,7 +226,7 @@ void GraphicsMan::drawAsShadowDrawNode(Graphics::Surface *screen, DrawNode *draw if (*src2 == kShadowColor) { if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { - *dst2 = *(drawNode->data + *dst2); + *dst2 = *(shadowData + *dst2); } } } diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 685964c78726..993665d833d7 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -239,64 +239,65 @@ static void plot(int x, int y, int color, void *data) { shadowLine->_shadLineLen++; } -// TODO - fix me -void Hero::showHeroShadow(Graphics::Surface *heroFrame) { +// FIXME - shadows are badly cutted off in left down corner of locations 7, 12 +// and horizontal line with wrong colors in the middle of shadow appears in loc. 12, 23 +void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { + Hero *heroData = (Hero *)drawNode->data; + int16 heroSurfaceWidth = drawNode->s->w; + int16 heroSurfaceHeight = drawNode->s->h; + Graphics::Surface *makeShadow = new Graphics::Surface(); - makeShadow->create(_frameXSize, _frameYSize, Graphics::PixelFormat::createFormatCLUT8()); + makeShadow->create(heroSurfaceWidth, heroSurfaceHeight, Graphics::PixelFormat::createFormatCLUT8()); - for (int y = 0; y < _frameYSize; y++) { - byte *src = (byte *)heroFrame->getBasePtr(0, y); + for (int y = 0; y < heroSurfaceHeight; y++) { + byte *src = (byte *)drawNode->s->getBasePtr(0, y); byte *dst = (byte *)makeShadow->getBasePtr(0, y); - - for (int x = 0; x < _frameXSize; x++, dst++, src++) { + for (int x = 0; x < heroSurfaceWidth; x++, dst++, src++) { if (*src != 0xFF) { - *dst = _graph->kShadowColor; + *dst = GraphicsMan::kShadowColor; } else { *dst = *src; } } } - int destX = _middleX - _scaledFrameXSize / 2; - int destY = _middleY - _shadMinus - 1; - - if (destY > 1 && destY < _vm->kMaxPicHeight) { + if (drawNode->posY > 1 && drawNode->posY < PrinceEngine::kMaxPicHeight) { int shadDirection; - if (_vm->_lightY > destY) { + if (heroData->_vm->_lightY > drawNode->posY) { shadDirection = 1; } else { shadDirection = 0; } - _shadLineLen = 0; - Graphics::drawLine(_vm->_lightX, _vm->_lightY, destX, destY, 0, &plot, this); + heroData->_shadLineLen = 0; + Graphics::drawLine(heroData->_vm->_lightX, heroData->_vm->_lightY, drawNode->posX, drawNode->posY, 0, &plot, heroData); - byte *sprShadow = (byte *)_graph->_shadowTable70; + byte *sprShadow = (byte *)heroData->_graph->_shadowTable70; - _shadDrawX = destX - _vm->_picWindowX; - _shadDrawY = destY - _vm->_picWindowY; + heroData->_shadDrawX = drawNode->posX - heroData->_vm->_picWindowX; + heroData->_shadDrawY = drawNode->posY - heroData->_vm->_picWindowY; - int shadPosX = _shadDrawX; - int shadPosY = _shadDrawY; - int shadBitAddr = destY * _vm->kMaxPicWidth / 8 + destX / 8; - int shadBitMask = 128 >> (destX % 8); + int shadPosX = heroData->_shadDrawX; + int shadPosY = heroData->_shadDrawY; + int shadBitAddr = drawNode->posY * PrinceEngine::kMaxPicWidth / 8 + drawNode->posX / 8; + int shadBitMask = 128 >> (drawNode->posX % 8); - int shadZoomY2 = _shadScaleValue; - int shadZoomY = _scaleValue; + int shadZoomY2 = heroData->_shadScaleValue; + int shadZoomY = heroData->_scaleValue; int diffX = 0; int diffY = 0; int shadowHeroX = 0; - int shadowHeroY = _frameYSize - 1; + int shadowHeroY = heroSurfaceHeight - 1; int shadLastY = 0; byte *shadowHero = (byte *)makeShadow->getBasePtr(shadowHeroX, shadowHeroY); // first pixel from last row of shadow hero - byte *background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX, _shadDrawY); // pixel of background where shadow sprite starts + byte *background = (byte *)screen->getBasePtr(heroData->_shadDrawX, heroData->_shadDrawY); // pixel of background where shadow sprite starts // banked2 - byte *shadowLineStart = _shadowLine + 8; + byte *shadowLineStart = heroData->_shadowLine + 8; int shadWallDown = 0; int shadWallBitAddr = 0; @@ -307,17 +308,17 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { int shadWallModulo = 0; // linear_loop - for (int i = 0; i < _frameYSize; i++) { + for (int i = 0; i < heroSurfaceHeight; i++) { int shadSkipX = 0; int ct_loop = 0; int sprModulo = 0; int j; //retry_line: - for (j = _frameYSize - i; j > 0; j--) { + for (j = heroSurfaceHeight - i; j > 0; j--) { shadZoomY -= 100; - if (shadZoomY < 0 && _scaleValue != 10000) { - shadZoomY += _scaleValue; + if (shadZoomY < 0 && heroData->_scaleValue != 10000) { + shadZoomY += heroData->_scaleValue; shadowHeroY--; if (shadowHeroY < 0) { break; @@ -339,7 +340,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { if (shadPosX < 0) { shadSkipX = -1 * shadPosX; background += shadSkipX; - if (_frameXSize > shadSkipX) { + if (heroSurfaceWidth > shadSkipX) { shadowHero += shadSkipX; shadBitAddr += shadSkipX / 8; if ((shadSkipX % 8) != 0) { @@ -359,12 +360,12 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { } } else { //x1_ok - if (shadPosX + _frameXSize > 640) { + if (shadPosX + heroSurfaceWidth > 640) { ct_loop = 640 - shadPosX; // test it - sprModulo = shadPosX + _frameXSize - 640; + sprModulo = shadPosX + heroSurfaceWidth - 640; } else { //draw_line - ct_loop = _frameXSize; + ct_loop = heroSurfaceWidth; } } //draw_line1 @@ -372,8 +373,8 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { int k; for (k = j; k > 0; k--) { shadZoomY2 -= 100; - if (shadZoomY2 < 0 && _shadScaleValue != 10000) { - shadZoomY2 += _shadScaleValue; + if (shadZoomY2 < 0 && heroData->_shadScaleValue != 10000) { + shadZoomY2 += heroData->_shadScaleValue; shadowHeroY--; if (shadowHeroY < 0) { break; @@ -392,20 +393,20 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { //line_y_ok_2: //copy_trans bool shadWDFlag = false; - int shadZoomX = _scaleValue; + int shadZoomX = heroData->_scaleValue; int backgroundDiff = 0; int shadBitMaskCopyTrans = shadBitMask; int shadBitAddrCopyTrans = shadBitAddr; //ct_loop: for (int l = 0; l < ct_loop; l++) { shadZoomX -= 100; - if (shadZoomX < 0 && _scaleValue != 10000) { - shadZoomX += _scaleValue; + if (shadZoomX < 0 && heroData->_scaleValue != 10000) { + shadZoomX += heroData->_scaleValue; } else { - if (*shadowHero == _graph->kShadowColor) { - if ((shadBitMaskCopyTrans & _vm->_shadowBitmap[shadBitAddrCopyTrans]) != 0) { + if (*shadowHero == GraphicsMan::kShadowColor) { + if ((shadBitMaskCopyTrans & heroData->_vm->_shadowBitmap[shadBitAddrCopyTrans]) != 0) { if (shadWallDown == 0) { - if ((shadBitMaskCopyTrans & _vm->_shadowBitmap[shadBitAddrCopyTrans + _vm->kShadowBitmapSize]) != 0) { + if ((shadBitMaskCopyTrans & heroData->_vm->_shadowBitmap[shadBitAddrCopyTrans + heroData->_vm->kShadowBitmapSize]) != 0) { shadWDFlag = true; //shadow *background = *(sprShadow + *background); @@ -425,7 +426,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { } //okok backgroundDiff++; - background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX + backgroundDiff, _shadDrawY + diffY); + background = (byte *)screen->getBasePtr(heroData->_shadDrawX + diffX + backgroundDiff, heroData->_shadDrawY + diffY); } shadowHeroX++; shadowHero = (byte *)makeShadow->getBasePtr(shadowHeroX, shadowHeroY); @@ -434,7 +435,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { if (!shadWallDown && shadWDFlag) { shadWallDown = shadPosX; shadWallBitAddr = shadBitAddr; - shadWallDestAddr = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX, _shadDrawY + diffY); + shadWallDestAddr = (byte *)screen->getBasePtr(heroData->_shadDrawX + diffX, heroData->_shadDrawY + diffY); shadWallBitMask = shadBitMask; shadWallPosY = shadPosY; shadWallSkipX = shadSkipX; @@ -450,18 +451,18 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { if (ct_loop > shadWallSkipX && ct_loop - shadWallSkipX > shadWallModulo) { //WALL_copy_trans shadWDFlag = false; - int shadZoomXWall = _scaleValue; + int shadZoomXWall = heroData->_scaleValue; int backgroundDiffWall = 0; int shadowHeroXWall = 0; //ct_loop: for (int m = 0; m < ct_loop; m++) { shadZoomXWall -= 100; - if (shadZoomXWall < 0 && _scaleValue != 10000) { - shadZoomXWall += _scaleValue; + if (shadZoomXWall < 0 && heroData->_scaleValue != 10000) { + shadZoomXWall += heroData->_scaleValue; } else { //point_ok: - if (*shadowHero == _graph->kShadowColor) { - if ((shadBitMaskWallCopyTrans & _vm->_shadowBitmap[shadBitAddrWallCopyTrans + _vm->kShadowBitmapSize]) != 0) { + if (*shadowHero == GraphicsMan::kShadowColor) { + if ((shadBitMaskWallCopyTrans & heroData->_vm->_shadowBitmap[shadBitAddrWallCopyTrans + heroData->_vm->kShadowBitmapSize]) != 0) { *background = *(sprShadow + *background); } } @@ -481,8 +482,8 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { } } //krap2 - shadWallDestAddr -= _vm->kNormalWidth; - shadWallBitAddr -= _vm->kMaxPicWidth / 8; + shadWallDestAddr -= PrinceEngine::kNormalWidth; + shadWallBitAddr -= PrinceEngine::kMaxPicWidth / 8; shadWallPosY--; } } @@ -490,11 +491,11 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { //next_line if (*(shadowLineStart + 2) < *(shadowLineStart - 2)) { //minus_y - shadBitAddr -= _vm->kMaxPicWidth / 8; + shadBitAddr -= PrinceEngine::kMaxPicWidth / 8; shadPosY--; diffY--; } else if (*(shadowLineStart + 2) > *(shadowLineStart - 2)) { - shadBitAddr += _vm->kMaxPicWidth / 8; + shadBitAddr += PrinceEngine::kMaxPicWidth / 8; shadPosY++; diffY++; } @@ -528,7 +529,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) { break; } shadowHeroX = 0; - background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX, _shadDrawY + diffY); + background = (byte *)screen->getBasePtr(heroData->_shadDrawX + diffX, heroData->_shadDrawY + diffY); shadowHero = (byte *)makeShadow->getBasePtr(shadowHeroX, shadowHeroY); } //koniec_bajki - end_of_a_story @@ -890,7 +891,6 @@ void Hero::drawHero() { freeZoomedSurface(); Graphics::Surface *mainHeroSurface = getSurface(); if (mainHeroSurface) { - //showHeroShadow(mainHeroSurface); DrawNode newDrawNode; newDrawNode.posX = _drawX; newDrawNode.posY = _drawY; @@ -908,10 +908,27 @@ void Hero::drawHero() { newDrawNode.s = mainHeroSurface; } _vm->_drawNodeList.push_back(newDrawNode); + + drawHeroShadow(mainHeroSurface); + } } } +void Hero::drawHeroShadow(Graphics::Surface *heroFrame) { + DrawNode newDrawNode; + newDrawNode.posX = _middleX - _scaledFrameXSize / 2; + newDrawNode.posY = _middleY - _shadMinus - 1; + newDrawNode.posZ = kHeroShadowZ; + newDrawNode.width = 0; + newDrawNode.height = 0; + newDrawNode.originalRoomSurface = nullptr; + newDrawNode.data = this; + newDrawNode.drawFunction = &showHeroShadow; + newDrawNode.s = heroFrame; + _vm->_drawNodeList.push_back(newDrawNode); +} + void Hero::heroMoveGotIt(int x, int y, int dir) { _middleX = x; _middleY = y; diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 00c47e1dc4b4..2e838cc9b348 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -36,6 +36,7 @@ class Animation; class PrinceEngine; class GraphicsMan; struct InventoryItem; +struct DrawNode; class Hero { public: @@ -43,6 +44,7 @@ class Hero { static const int16 kShadowLineArraySize = 2 * 1280 * 4; static const int16 kStepLeftRight = 8; static const int16 kStepUpDown = 4; + static const int16 kHeroShadowZ = 2; enum State { kHeroStateStay, @@ -124,14 +126,11 @@ class Hero { Graphics::Surface *zoomSprite(Graphics::Surface *heroFrame); void line(int x1, int y1, int x2, int y2); void plotPoint(int x, int y); - void showHeroShadow(Graphics::Surface *heroFrame); + static void showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode); + void drawHeroShadow(Graphics::Surface *heroFrame); void setShadowScale(int32 shadowScale); void freeOldMove(); void freeHeroAnim(); - -//private: - PrinceEngine *_vm; - GraphicsMan *_graph; uint16 _number; uint16 _visible; @@ -186,6 +185,10 @@ class Hero { uint32 _moveDelay; uint32 _shadMinus; + +private: + PrinceEngine *_vm; + GraphicsMan *_graph; }; } // End of namespace Prince diff --git a/engines/prince/prince.h b/engines/prince/prince.h index fbd71a23163d..fe9379180d9b 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -231,7 +231,7 @@ struct DrawNode { int32 height; Graphics::Surface *s; Graphics::Surface *originalRoomSurface; - byte *data; + void *data; void (*drawFunction)(Graphics::Surface *, DrawNode *); }; From c3a3bdebd729be66210e7099fa696676139188e0 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 4 Aug 2014 12:02:00 +0200 Subject: [PATCH 322/374] PRINCE: showHero() update --- engines/prince/hero.cpp | 33 ++++++++++++--------------------- engines/prince/hero.h | 1 - 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 993665d833d7..e3493c496623 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -42,7 +42,7 @@ Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph), _shadZoomFactor(0), _shadScaleValue(0), _shadLineLen(0), _shadDrawX(0), _shadDrawY(0), _frameXSize(0), _frameYSize(0), _scaledFrameXSize(0), _scaledFrameYSize(0), _color(0), _coords(nullptr), _dirTab(nullptr), _currCoords(nullptr), _currDirTab(nullptr), _step(0), - _maxBoredom(200), _turnAnim(0), _leftRightMainDir(0), _upDownMainDir(0), _animSetNr(0) + _maxBoredom(200), _leftRightMainDir(0), _upDownMainDir(0), _animSetNr(0) { _shadowLine = (byte *)malloc(kShadowLineArraySize); } @@ -737,7 +737,7 @@ void Hero::showHero() { int rotateDir = rotateHero(_lastDirection, _destDirection); _lastDirection = _destDirection; if (rotateDir) { - _turnAnim = rotateDir; + _moveSetType = rotateDir; _state = kHeroStateTran; } else { _state = kHeroStateStay; @@ -750,9 +750,8 @@ void Hero::showHero() { } if (_state == kHeroStateTran) { - if (_moveSet[_turnAnim] != nullptr) { + if (_moveSet[_moveSetType] != nullptr) { // only in bear form - _moveSetType = _turnAnim; if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 2) { _phase += 2; } else { @@ -766,9 +765,8 @@ void Hero::showHero() { } if (_state == kHeroStateMvan) { - if (_moveSet[_turnAnim] != nullptr) { + if (_moveSet[_moveSetType] != nullptr) { // only in bear form - _moveSetType = _turnAnim; if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 2) { _phase += 2; } else { @@ -802,26 +800,19 @@ void Hero::showHero() { _phase = 0; int rotateDir = rotateHero(_lastDirection, dir); _lastDirection = dir; - if (!rotateDir) { - continue; - } else { - _turnAnim = rotateDir; + if (_moveSet[rotateDir] != nullptr) { + // only in bear form _state = kHeroStateMvan; - if (_moveSet[_turnAnim] != nullptr) { - // only in bear form - _moveSetType = _turnAnim; - if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 2) { - _phase += 2; - break; - } else { - _turnAnim = 0; - _state = kHeroStateMove; - continue; - } + _moveSetType = rotateDir; + if (_phase < _moveSet[_moveSetType]->getPhaseCount() - 2) { + _phase += 2; + break; } else { _state = kHeroStateMove; continue; } + } else { + continue; } } //no_need_direction_change diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 2e838cc9b348..743e09ac8d3a 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -180,7 +180,6 @@ class Hero { int _color; // subtitles color uint32 _animSetNr; // number of animation set Common::Array _moveSet; // MoveAnims MoveSet - int16 _turnAnim; byte *_shadowLine; uint32 _moveDelay; From f36fbcb97fb012ae4baf99b2de1c9d8ce9ae048f Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 4 Aug 2014 12:55:03 +0200 Subject: [PATCH 323/374] PRINCE: loadLocation() - freeAllNormAnims --- engines/prince/prince.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index a6a664cac61b..250f1fb9b543 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -151,8 +151,10 @@ PrinceEngine::~PrinceEngine() { _drawNodeList.clear(); clearBackAnimList(); + _backAnimList.clear(); freeAllNormAnims(); + _normAnimList.clear(); for (uint i = 0; i < _allInvList.size(); i++) { _allInvList[i]._surface->free(); @@ -470,6 +472,8 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _script->installObjects(_room->_obj); + freeAllNormAnims(); + clearBackAnimList(); _script->installBackAnims(_backAnimList, _room->_backAnim); @@ -2826,14 +2830,16 @@ void PrinceEngine::doTalkAnim(int animNumber, int slot, AnimType animType) { } void PrinceEngine::freeNormAnim(int slot) { - _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; + 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; + } } } @@ -2841,7 +2847,6 @@ void PrinceEngine::freeAllNormAnims() { for (int i = 0; i < kMaxNormAnims; i++) { freeNormAnim(i); } - _normAnimList.clear(); } // Modified version of Graphics::drawLine() to allow breaking the loop and return value From 2bed872498c22fc21b2a993656802f0c81da2936 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 4 Aug 2014 21:31:19 +0200 Subject: [PATCH 324/374] PRINCE: showHero() - special animations fix --- engines/prince/hero.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index e3493c496623..7bbd6c659960 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -200,6 +200,7 @@ void Hero::countDrawPosition() { } int phaseFrameIndex = heroAnim->getPhaseFrameIndex(_phase); Graphics::Surface *heroSurface = heroAnim->getFrame(phaseFrameIndex); + _frameXSize = heroSurface->w; _frameYSize = heroSurface->h; _scaledFrameXSize = getScaledValue(_frameXSize); @@ -647,17 +648,18 @@ void Hero::showHero() { if (_phase < _specAnim->getPhaseCount() - 1) { _phase++; } else { - _phase = 0; - freeHeroAnim(); if (!_talkTime) { _state = kHeroStateStay; } else { _state = kHeroStateTalk; } + return; } } else { _state = kHeroStateStay; } + } else { + freeHeroAnim(); } if (_state == kHeroStateTalk) { From d100597ce939239f8d3fddc6d327c3a7468d739d Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 4 Aug 2014 21:56:36 +0200 Subject: [PATCH 325/374] PRINCE: Inventory after swaping and loading fix --- engines/prince/prince.cpp | 2 ++ engines/prince/saveload.cpp | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 250f1fb9b543..9ede877d0e40 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1895,9 +1895,11 @@ void PrinceEngine::swapInv(int heroId) { 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]); } diff --git a/engines/prince/saveload.cpp b/engines/prince/saveload.cpp index 55435f168913..39a4002b4066 100644 --- a/engines/prince/saveload.cpp +++ b/engines/prince/saveload.cpp @@ -420,7 +420,7 @@ void PrinceEngine::syncGame(Common::SeekableReadStream *readStream, Common::Writ if (invId == endInv) { break; } - _mainHero->_inventory.push_back(invId); + _mainHero->_inventory2.push_back(invId); } // Second hero @@ -450,7 +450,7 @@ void PrinceEngine::syncGame(Common::SeekableReadStream *readStream, Common::Writ if (invId == endInv) { break; } - _secondHero->_inventory.push_back(invId); + _secondHero->_inventory2.push_back(invId); } // Script From 5791d48c4687ebf6c87160728a9ee629b6821032 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 4 Aug 2014 22:07:00 +0200 Subject: [PATCH 326/374] PRINCE: showHero - special animations drawing position fix --- engines/prince/hero.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 7bbd6c659960..282d86557472 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -653,6 +653,7 @@ void Hero::showHero() { } else { _state = kHeroStateTalk; } + countDrawPosition(); return; } } else { From 49337549d9959ec9858fb0e497c27b27febfc277 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 5 Aug 2014 04:30:07 +0200 Subject: [PATCH 327/374] PRINCE: makeCurve(), getCurve(), mouseWeirdo(), O_KRZYWA, O_GETKRZYWA, O_GETMOB --- engines/prince/curve_values.h | 45 +++++++++++++ engines/prince/prince.cpp | 117 +++++++++++++++++++++++++++------- engines/prince/prince.h | 11 ++++ engines/prince/script.cpp | 17 ++--- 4 files changed, 157 insertions(+), 33 deletions(-) create mode 100644 engines/prince/curve_values.h diff --git a/engines/prince/curve_values.h b/engines/prince/curve_values.h new file mode 100644 index 000000000000..d72f11fd3642 --- /dev/null +++ b/engines/prince/curve_values.h @@ -0,0 +1,45 @@ +/* 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. + * + */ + +namespace Prince { + +const int curveValues[17][4] = { + { 32768, 0, 0, 0 }, + { 25200, 7200, 480, -112 }, + { 18816, 12544, 1792, -384 }, + { 13520, 16224, 3744, -720 }, + { 9216, 18432, 6144, -1024 }, + { 5808, 19360, 8800, -1200 }, + { 3200, 19200, 11520, -1152 }, + { 1296, 18144, 14112, -784 }, + { 0, 16384, 16384, 0 }, + { -784, 14112, 18144, 1296 }, + { -1152, 11520, 19200, 3200 }, + { -1200, 8800, 19360, 5808 }, + { -1024, 6144, 18432, 9216 }, + { -720, 3744, 16224, 13520 }, + { -384, 1792, 12544, 18816 }, + { -112, 480, 7200, 25200 }, + { 0, 0, 0, 32768 } +}; + +} // End of namespace Prince diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 9ede877d0e40..9e1903350768 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -60,6 +60,7 @@ #include "prince/resource.h" #include "prince/animation.h" #include "prince/option_text.h" +#include "prince/curve_values.h" namespace Prince { @@ -92,7 +93,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _traceLineLen(0), _rembBitmapTemp(nullptr), _rembBitmap(nullptr), _rembMask(0), _rembX(0), _rembY(0), _fpX(0), _fpY(0), _checkBitmapTemp(nullptr), _checkBitmap(nullptr), _checkMask(0), _checkX(0), _checkY(0), _traceLineFirstPointFlag(false), _tracePointFirstPointFlag(false), _coordsBuf2(nullptr), _coords2(nullptr), _coordsBuf3(nullptr), _coords3(nullptr), - _shanLen(0), _directionTable(nullptr), _currentMidi(0), _lightX(0), _lightY(0) { + _shanLen(0), _directionTable(nullptr), _currentMidi(0), _lightX(0), _lightY(0), _curveData(nullptr), _curvPos(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -189,6 +190,8 @@ PrinceEngine::~PrinceEngine() { free(_zoomBitmap); free(_shadowBitmap); + + free(_curveData); } GUI::Debugger *PrinceEngine::getDebugger() { @@ -333,6 +336,8 @@ void PrinceEngine::init() { _zoomBitmap = (byte *)malloc(kZoomBitmapLen); _shadowBitmap = (byte *)malloc(2 * kShadowBitmapSize); + + _curveData = (int16 *)malloc(2 * kCurveLen * sizeof(int16)); } void PrinceEngine::showLogo() { @@ -889,13 +894,9 @@ void PrinceEngine::keyHandler(Common::Event event) { } } -int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobList, bool usePriorityList) { - Common::Point mousepos = _system->getEventManager()->getMousePos(); - Common::Point mousePosCamera(mousepos.x + _picWindowX, mousepos.y); +int PrinceEngine::getMob(Common::Array &mobList, bool usePriorityList, int posX, int posY) { - if (_mouseFlag == 0 || _mouseFlag == 3) { - return -1; - } + Common::Point pointPos(posX, posY); int mobListSize; if (usePriorityList) { @@ -921,7 +922,7 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis case 0: case 1: //normal_mob - if (!mob->_rect.contains(mousePosCamera)) { + if (!mob->_rect.contains(pointPos)) { continue; } break; @@ -932,9 +933,9 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis 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(mousePosCamera)) { + if (objectRect.contains(pointPos)) { Graphics::Surface *objSurface = obj.getSurface(); - byte *pixel = (byte *)objSurface->getBasePtr(mousePosCamera.x - obj._x, mousePosCamera.y - obj._y); + byte *pixel = (byte *)objSurface->getBasePtr(posX - obj._x, posY - obj._y); if (*pixel != 255) { break; } @@ -952,14 +953,14 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis 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(mousePosCamera)) { + 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(mousePosCamera.x - backAnim._currX, mousePosCamera.y - backAnim._currY); + byte pixel = *(byte *)backAnimSurface->getBasePtr(posX - backAnim._currX, posY - backAnim._currY); if (pixel != 255) { if (type == 5) { - if (mob->_rect.contains(mousePosCamera)) { + if (mob->_rect.contains(pointPos)) { break; } } else { @@ -978,7 +979,24 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis break; } - Common::String mobName = mob->_name; + if (usePriorityList) { + return _mobPriorityList[mobNumber]; + } else { + return mobNumber; + } + } + return -1; +} + +int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &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++) { @@ -1010,7 +1028,7 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis uint16 textW = getTextWidth(mobName.c_str()); - uint16 x = mousepos.x - textW / 2; + uint16 x = mousePos.x - textW / 2; if (x > screen->w) { x = 0; } @@ -1019,20 +1037,15 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array &mobLis x = screen->w - textW; } - uint16 y = mousepos.y - _font->getFontHeight(); + uint16 y = mousePos.y - _font->getFontHeight(); if (y > screen->h) { y = _font->getFontHeight() - 2; } _font->drawString(screen, mobName, x, y, screen->w, 216); - - if (usePriorityList) { - return _mobPriorityList[mobNumber]; - } else { - return mobNumber; - } } - return -1; + + return mobNumber; } void PrinceEngine::printAt(uint32 slot, uint8 color, char *s, uint16 x, uint16 y) { @@ -2851,6 +2864,61 @@ void PrinceEngine::freeAllNormAnims() { } } +void PrinceEngine::getCurve() { + _flags->setFlagValue(Flags::TORX1, _curveData[_curvPos]); + _flags->setFlagValue(Flags::TORY1, _curveData[_curvPos + 1]); + _curvPos += 2; +} + +void PrinceEngine::makeCurve() { + _curvPos = 0; + int x1 = _flags->getFlagValue(Flags::TORX1); + int y1 = _flags->getFlagValue(Flags::TORY1); + int x2 = _flags->getFlagValue(Flags::TORX2); + int y2 = _flags->getFlagValue(Flags::TORY2); + + for (int i = 0; i < kCurveLen; i++) { + int sum1 = x1 * curveValues[i][0]; + sum1 += (x2 + (x1 - x2) / 2) * curveValues[i][1]; + sum1 += x2 * curveValues[i][2]; + sum1 += x2 * curveValues[i][3]; + + int sum2 = y1 * curveValues[i][0]; + sum2 += (y2 - 20) * curveValues[i][1]; + sum2 += (y2 - 10) * curveValues[i][2]; + sum2 += y2 * curveValues[i][3]; + + _curveData[i * 2] = (sum1 >> 15); + _curveData[i * 2 + 1] = (sum2 >> 15); + } +} + +void PrinceEngine::mouseWeirdo() { + if (_mouseFlag == 3) { + int weirdDir = _randomSource.getRandomNumber(3); + Common::Point mousePos = _system->getEventManager()->getMousePos(); + switch (weirdDir) { + case 0: + mousePos.x += kCelStep; + break; + case 1: + mousePos.x -= kCelStep; + break; + case 2: + mousePos.y += kCelStep; + break; + case 3: + mousePos.y -= kCelStep; + break; + } + mousePos.x = CLIP(mousePos.x, (int16) 0, (int16) 639); + _flags->setFlagValue(Flags::MXFLAG, mousePos.x); + mousePos.y = CLIP(mousePos.y, (int16) 0, (int16) 479); + _flags->setFlagValue(Flags::MYFLAG, mousePos.y); + _system->warpMouse(mousePos.x, mousePos.y); + } +} + // 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 @@ -4424,6 +4492,9 @@ void PrinceEngine::mainLoop() { return; } + // for "throw a rock" mini-game + mouseWeirdo(); + _interpreter->stepBg(); _interpreter->stepFg(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index fe9379180d9b..0c7e68c08107 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -481,6 +481,17 @@ class PrinceEngine : public Engine { void blackPalette(); void setPalette(); + int getMob(Common::Array &mobList, bool usePriorityList, int posX, int posY); + + // 'Throw a rock' mini-game: + static const int16 kCurveLen = 17; + static const int kCelStep = 4; + int16 *_curveData; + int _curvPos; + void makeCurve(); + void getCurve(); + void mouseWeirdo(); + // Pathfinding static const int16 kPathGridStep = 2; static const int32 kPathBitmapLen = (kMaxPicHeight / kPathGridStep * kMaxPicWidth / kPathGridStep) / 8; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index e0fdff1e31ca..91b8e50ea6d6 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1844,26 +1844,23 @@ void Interpreter::O_OPENINVENTORY() { debugInterpreter("O_OPENINVENTORY"); } -// TODO void Interpreter::O_KRZYWA() { + _vm->makeCurve(); debugInterpreter("O_KRZYWA"); } -// TODO void Interpreter::O_GETKRZYWA() { + _vm->getCurve(); debugInterpreter("O_GETKRZYWA"); - // _flags->setFlagValue(Flags::TORX1, krzywa[_krzywaIndex++]) - // _flags->setFlagValue(Flags::TORY1, krzywa[_krzywaIndex++]) - // Check _krzywaIndex } -// TODO void Interpreter::O_GETMOB() { Flags::Id flagId = readScriptFlagId(); - uint16 mx = readScriptFlagValue(); - uint16 my = readScriptFlagValue(); - debugInterpreter("O_GETMOB flagId %d, mx %d, my %d", flagId, mx, my); - // check if current mob pos = (mx, my) + uint16 posX = readScriptFlagValue(); + uint16 posY = readScriptFlagValue(); + int mobNumber = _vm->getMob(_vm->_mobList, true, posX, posY); + _flags->setFlagValue(flagId, mobNumber + 1); + debugInterpreter("O_GETMOB flagId %d, posX %d, posY %d", flagId, posX, posY); } // Not used in game From a3c829a7741630cf2aca1c142c782a111402902e Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 5 Aug 2014 18:11:33 +0200 Subject: [PATCH 328/374] PRINCE: Background animations - update --- engines/prince/script.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 91b8e50ea6d6..061d86c848c3 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -250,6 +250,8 @@ int Script::scanMobEventsWithItem(int mobMask, int dataEventOffset, int itemMask void Script::installSingleBackAnim(Common::Array &backAnimList, int slot, int roomBackAnimOffset) { + _vm->removeSingleBackAnim(slot); + int offset = roomBackAnimOffset + slot * 4; BackgroundAnim newBackgroundAnim; @@ -788,15 +790,19 @@ void Interpreter::O_GO() { void Interpreter::O_BACKANIMUPDATEOFF() { uint16 slotId = readScriptFlagValue(); int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; - _vm->_backAnimList[slotId].backAnims[currAnim]._state = 1; + if (!_vm->_backAnimList[slotId].backAnims.empty()) { + _vm->_backAnimList[slotId].backAnims[currAnim]._state = 1; + } debugInterpreter("O_BACKANIMUPDATEOFF slotId %d", slotId); } void Interpreter::O_BACKANIMUPDATEON() { uint16 slotId = readScriptFlagValue(); int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; - _vm->_backAnimList[slotId].backAnims[currAnim]._state = 0; - debugInterpreter("O_BACKANIMUPDATEON %d", slotId); + if (!_vm->_backAnimList[slotId].backAnims.empty()) { + _vm->_backAnimList[slotId].backAnims[currAnim]._state = 0; + } + debugInterpreter("O_BACKANIMUPDATEON slotId %d", slotId); } void Interpreter::O_CHANGECURSOR() { From c47a8799b2fe4cc3381f337352a759a02296c636 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 6 Aug 2014 17:35:08 +0200 Subject: [PATCH 329/374] PRINCE: Second hero movement - moveShandria(), moveRunHero() fix --- engines/prince/prince.cpp | 16 ++++++---------- engines/prince/prince.h | 1 + 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 9e1903350768..905862998eea 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2191,6 +2191,9 @@ void PrinceEngine::moveRunHero(int heroId, int x, int y, int dir, bool runHeroFl } else { hero->_state = Hero::kHeroStateMove; } + if (heroId == kMainHero && _mouseFlag) { + moveShandria(); + } } } else { hero->freeOldMove(); @@ -2198,9 +2201,6 @@ void PrinceEngine::moveRunHero(int heroId, int x, int y, int dir, bool runHeroFl } hero->freeHeroAnim(); hero->_visible = 1; - if (heroId == 1 && _mouseFlag) { - moveShandria(); - } } } @@ -4190,8 +4190,6 @@ void PrinceEngine::scanDirections() { void PrinceEngine::moveShandria() { int shanLen1 = _shanLen; - static const int kMinDistance = 2500; - if (_flags->getFlagValue(Flags::SHANDOG)) { _secondHero->freeHeroAnim(); _secondHero->freeOldMove(); @@ -4211,7 +4209,6 @@ void PrinceEngine::moveShandria() { yDiff *= 1.5; int shanDis = xDiff * xDiff + yDiff * yDiff; if (shanDis >= kMinDistance) { - //scangoodpoint: while (1) { shanCoords -= 4; if (shanCoords == _mainHero->_currCoords) { @@ -4233,15 +4230,14 @@ void PrinceEngine::moveShandria() { break; } } - //bye2 int pathSizeDiff = (shanCoords - _mainHero->_currCoords) / 4; - int destDir = *_mainHero->_currDirTab + pathSizeDiff; + int destDir = *(_mainHero->_currDirTab + pathSizeDiff); _secondHero->_destDirection = destDir; int destX = READ_UINT16(shanCoords); int destY = READ_UINT16(shanCoords + 2); _secondHero->_coords = makePath(kSecondHero, _secondHero->_middleX, _secondHero->_middleY, destX, destY); if (_secondHero->_coords != nullptr) { - _secondHero->_currCoords = _mainHero->_coords; + _secondHero->_currCoords = _secondHero->_coords; int delay = shanLen1 - _shanLen; if (delay < 6) { delay = 6; @@ -4396,7 +4392,7 @@ byte *PrinceEngine::makePath(int heroId, int currX, int currY, int destX, int de WRITE_UINT32(newCoords, 0xFFFFFFFF); newCoords += 4; _shanLen = (newCoords - newCoordsBegin); - //_shanLen /= 4 ? + _shanLen /= 4; return newCoordsBegin; } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 0c7e68c08107..cb4e41fb7989 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -497,6 +497,7 @@ class PrinceEngine : public Engine { static const int32 kPathBitmapLen = (kMaxPicHeight / kPathGridStep * kMaxPicWidth / kPathGridStep) / 8; static const int32 kTracePts = 8000; static const int32 kPBW = kMaxPicWidth / 16; // PathBitmapWidth + static const int kMinDistance = 2500; byte *_roomPathBitmap; // PL - Sala byte *_roomPathBitmapTemp; // PL - SSala From a85a93f8886ef750e704302eabf1bfafc068206e Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 6 Aug 2014 18:05:32 +0200 Subject: [PATCH 330/374] PRINCE: getAnimData() update --- engines/prince/prince.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/engines/prince/prince.h b/engines/prince/prince.h index cb4e41fb7989..c8600e78284a 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -152,9 +152,7 @@ struct Anim { case kAnimState: return _state; case kAnimFrame: - return _frame; - case kAnimLastFrame: - return _lastFrame; + return _frame + 1; // fix for location 30 - man with a dog animation case kAnimX: return _x; default: From 4dbcdd19ec40b8b3d6ed416421eaff11a74181cf Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 7 Aug 2014 02:20:52 +0200 Subject: [PATCH 331/374] PRINCE: showNormAnims() fix --- engines/prince/prince.cpp | 5 +++-- engines/prince/script.cpp | 8 ++++++++ engines/prince/script.h | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 905862998eea..9026e53c5bad 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1390,8 +1390,9 @@ void PrinceEngine::showNormAnims() { } else { anim._frame++; } - if (anim._frame < phaseCount - 1) { - anim._showFrame = anim._frame; + anim._showFrame = anim._frame; + if (anim._showFrame >= phaseCount) { + anim._showFrame = phaseCount - 1; } showAnim(anim); } diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 061d86c848c3..dc8bb9167440 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -643,6 +643,14 @@ void Interpreter::O_SHOWANIM() { delete anim._shadowData; anim._shadowData = nullptr; } + + // WALKAROUND: fix for turning off bard's wife background animation + // in front of bard's house (location 7) after giving her poem (item 33) + // in script: GiveLetter (line 11082) + if (_currentInstruction == kGiveLetterScriptFix) { + _vm->_backAnimList[1].backAnims[0]._state = 1; + } + debugInterpreter("O_SHOWANIM slot %d, animId %d", slot, animId); } diff --git a/engines/prince/script.h b/engines/prince/script.h index 9c397b0d1f65..196a19512d85 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -252,6 +252,8 @@ class Interpreter { typedef void (Interpreter::*OpcodeFunc)(); static OpcodeFunc _opcodes[]; + static const int kGiveLetterScriptFix = 79002; + // Keep opcode handlers names as they are in original code // it easier to switch back and forth void O_WAITFOREVER(); From b0dd6db58ce46e809a4add71bc6cccacf79c4685 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 8 Aug 2014 17:09:26 +0200 Subject: [PATCH 332/374] PRINCE: Script update - readScriptFlagValue fix --- engines/prince/prince.cpp | 2 +- engines/prince/script.cpp | 278 +++++++++++++++++++------------------- engines/prince/script.h | 2 +- 3 files changed, 141 insertions(+), 141 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 9026e53c5bad..bac261e56f57 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2559,7 +2559,7 @@ void PrinceEngine::displayInventory() { _mainHero->freeOldMove(); _secondHero->freeOldMove(); - _interpreter->storeNewPC(0); + _interpreter->setFgOpcodePC(0); stopAllSamples(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index dc8bb9167440..4d00018a02b4 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -530,7 +530,7 @@ T Interpreter::readScript() { return data; } -int16 Interpreter::readScriptFlagValue() { +int32 Interpreter::readScriptFlagValue() { uint16 value = readScript(); if (value & InterpreterFlags::kFlagMask) { return _flags->getFlagValue((Flags::Id)value); @@ -560,14 +560,14 @@ void Interpreter::O_SETUPPALETTE() { } void Interpreter::O_INITROOM() { - uint16 roomId = readScriptFlagValue(); + int32 roomId = readScriptFlagValue(); _vm->loadLocation(roomId); _opcodeNF = 1; debugInterpreter("O_INITROOM %d", roomId); } void Interpreter::O_SETSAMPLE() { - uint16 sampleId = readScriptFlagValue(); + int32 sampleId = readScriptFlagValue(); int32 sampleNameOffset = readScript(); const char *sampleName = _script->getString(_currentInstruction + sampleNameOffset - 4); _vm->loadSample(sampleId, sampleName); @@ -575,22 +575,22 @@ void Interpreter::O_SETSAMPLE() { } void Interpreter::O_FREESAMPLE() { - uint16 sampleId = readScriptFlagValue(); + int32 sampleId = readScriptFlagValue(); _vm->freeSample(sampleId); debugInterpreter("O_FREESAMPLE sampleId: %d", sampleId); } void Interpreter::O_PLAYSAMPLE() { - uint16 sampleId = readScriptFlagValue(); + int32 sampleId = readScriptFlagValue(); uint16 loopType = readScript(); _vm->playSample(sampleId, loopType); debugInterpreter("O_PLAYSAMPLE sampleId %d loopType %d", sampleId, loopType); } void Interpreter::O_PUTOBJECT() { - uint16 roomId = readScriptFlagValue(); - uint16 slot = readScriptFlagValue(); - uint16 objectId = readScriptFlagValue(); + int32 roomId = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); + int32 objectId = readScriptFlagValue(); Room *room = new Room(); room->loadRoom(_script->getRoomOffset(roomId)); _vm->_script->setObjId(room->_obj, slot, objectId); @@ -602,8 +602,8 @@ void Interpreter::O_PUTOBJECT() { } void Interpreter::O_REMOBJECT() { - uint16 roomId = readScriptFlagValue(); - uint16 slot = readScriptFlagValue(); + int32 roomId = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); Room *room = new Room(); room->loadRoom(_script->getRoomOffset(roomId)); _vm->_script->setObjId(room->_obj, slot, 0xFF); @@ -615,8 +615,8 @@ void Interpreter::O_REMOBJECT() { } void Interpreter::O_SHOWANIM() { - uint16 slot = readScriptFlagValue(); - uint16 animId = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); + int32 animId = readScriptFlagValue(); _vm->freeNormAnim(slot); Anim &anim = _vm->_normAnimList[slot]; AnimListItem &animList = _vm->_animList[animId]; @@ -655,7 +655,7 @@ void Interpreter::O_SHOWANIM() { } void Interpreter::O_CHECKANIMEND() { - uint16 slot = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); if (_vm->_normAnimList[slot]._frame != _vm->_normAnimList[slot]._lastFrame - 1) { _currentInstruction -= 4; _opcodeNF = 1; @@ -664,14 +664,14 @@ void Interpreter::O_CHECKANIMEND() { } void Interpreter::O_FREEANIM() { - uint16 slot = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); _vm->freeNormAnim(slot); debugInterpreter("O_FREEANIM slot %d", slot); } void Interpreter::O_CHECKANIMFRAME() { - uint16 slot = readScriptFlagValue(); - uint16 frameNumber = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); + int32 frameNumber = readScriptFlagValue(); if (_vm->_normAnimList[slot]._frame != frameNumber - 1) { _currentInstruction -= 6; _opcodeNF = 1; @@ -680,8 +680,8 @@ void Interpreter::O_CHECKANIMFRAME() { } void Interpreter::O_PUTBACKANIM() { - uint16 roomId = readScriptFlagValue(); - uint16 slot = readScriptFlagValue(); + int32 roomId = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); int32 animId = readScript(); Room *room = new Room(); room->loadRoom(_script->getRoomOffset(roomId)); @@ -694,8 +694,8 @@ void Interpreter::O_PUTBACKANIM() { } void Interpreter::O_REMBACKANIM() { - uint16 roomId = readScriptFlagValue(); - uint16 slot = readScriptFlagValue(); + int32 roomId = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); if (_vm->_locationNr == roomId) { _vm->removeSingleBackAnim(slot); } @@ -707,8 +707,8 @@ void Interpreter::O_REMBACKANIM() { } void Interpreter::O_CHECKBACKANIMFRAME() { - uint16 slotId = readScriptFlagValue(); - uint16 frameId = readScriptFlagValue(); + int32 slotId = readScriptFlagValue(); + int32 frameId = readScriptFlagValue(); int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; if (_vm->_backAnimList[slotId].backAnims[currAnim]._frame != frameId - 1) { _currentInstruction -= 6; @@ -734,7 +734,7 @@ void Interpreter::O_STOPMUSIC() { } void Interpreter::O__WAIT() { - uint16 pause = readScriptFlagValue(); + int32 pause = readScriptFlagValue(); debugInterpreter("O__WAIT pause %d", pause); if (!_waitFlag) { // set new wait flag value and continue @@ -796,7 +796,7 @@ void Interpreter::O_GO() { } void Interpreter::O_BACKANIMUPDATEOFF() { - uint16 slotId = readScriptFlagValue(); + int32 slotId = readScriptFlagValue(); int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; if (!_vm->_backAnimList[slotId].backAnims.empty()) { _vm->_backAnimList[slotId].backAnims[currAnim]._state = 1; @@ -805,7 +805,7 @@ void Interpreter::O_BACKANIMUPDATEOFF() { } void Interpreter::O_BACKANIMUPDATEON() { - uint16 slotId = readScriptFlagValue(); + int32 slotId = readScriptFlagValue(); int currAnim = _vm->_backAnimList[slotId]._seq._currRelative; if (!_vm->_backAnimList[slotId].backAnims.empty()) { _vm->_backAnimList[slotId].backAnims[currAnim]._state = 0; @@ -814,7 +814,7 @@ void Interpreter::O_BACKANIMUPDATEON() { } void Interpreter::O_CHANGECURSOR() { - uint16 cursorId = readScriptFlagValue(); + int32 cursorId = readScriptFlagValue(); _vm->changeCursor(cursorId); debugInterpreter("O_CHANGECURSOR %x", cursorId); } @@ -826,14 +826,14 @@ void Interpreter::O_CHANGEANIMTYPE() { void Interpreter::O__SETFLAG() { Flags::Id flagId = readScriptFlagId(); - int16 value = readScriptFlagValue(); + int32 value = readScriptFlagValue(); _flags->setFlagValue((Flags::Id)(flagId), value); debugInterpreter("O__SETFLAG 0x%04X (%s) = %d", flagId, Flags::getFlagName(flagId), value); } void Interpreter::O_COMPARE() { Flags::Id flagId = readScriptFlagId(); - uint16 value = readScriptFlagValue(); + int32 value = readScriptFlagValue(); _result = _flags->getFlagValue(flagId) != value; debugInterpreter("O_COMPARE flagId 0x%04X (%s), value %d == %d (%d)", flagId, Flags::getFlagName(flagId), value, _flags->getFlagValue(flagId), _result); } @@ -856,7 +856,7 @@ void Interpreter::O_JUMPNZ() { // TODO void Interpreter::O_EXIT() { - uint16 exitCode = readScriptFlagValue(); + int32 exitCode = readScriptFlagValue(); debugInterpreter("O_EXIT exitCode %d", exitCode); // Set exit code and shows credits // if exit code == 0x02EAD @@ -864,7 +864,7 @@ void Interpreter::O_EXIT() { void Interpreter::O_ADDFLAG() { Flags::Id flagId = readScriptFlagId(); - int16 value = readScriptFlagValue(); + int32 value = readScriptFlagValue(); _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) + value); if (_flags->getFlagValue(flagId)) { _result = 1; @@ -876,15 +876,15 @@ void Interpreter::O_ADDFLAG() { } void Interpreter::O_TALKANIM() { - uint16 animNumber = readScriptFlagValue(); - uint16 slot = readScriptFlagValue(); + int32 animNumber = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); _vm->doTalkAnim(animNumber, slot, kNormalAnimation); debugInterpreter("O_TALKANIM animNumber %d, slot %d", animNumber, slot); } void Interpreter::O_SUBFLAG() { Flags::Id flagId = readScriptFlagId(); - int16 value = readScriptFlagValue(); + int32 value = readScriptFlagValue(); _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) - value); if (_flags->getFlagValue(flagId)) { _result = 1; @@ -914,7 +914,7 @@ void Interpreter::O_SETSTRING() { void Interpreter::O_ANDFLAG() { Flags::Id flagId = readScriptFlagId(); - int16 value = readScriptFlagValue(); + int32 value = readScriptFlagValue(); _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) & value); if (_flags->getFlagValue(flagId)) { _result = 1; @@ -926,8 +926,8 @@ void Interpreter::O_ANDFLAG() { void Interpreter::O_GETMOBDATA() { Flags::Id flagId = readScriptFlagId(); - uint16 mobId = readScriptFlagValue(); - uint16 mobOffset = readScriptFlagValue(); + int32 mobId = readScriptFlagValue(); + int32 mobOffset = readScriptFlagValue(); int16 value = _vm->_mobList[mobId].getData((Mob::AttrId)mobOffset); _flags->setFlagValue(flagId, value); debugInterpreter("O_GETMOBDATA flagId %d, modId %d, mobOffset %d", flagId, mobId, mobOffset); @@ -935,7 +935,7 @@ void Interpreter::O_GETMOBDATA() { void Interpreter::O_ORFLAG() { Flags::Id flagId = readScriptFlagId(); - int16 value = readScriptFlagValue(); + int32 value = readScriptFlagValue(); _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) | value); if (_flags->getFlagValue(flagId)) { _result = 1; @@ -946,16 +946,16 @@ void Interpreter::O_ORFLAG() { } void Interpreter::O_SETMOBDATA() { - uint16 mobId = readScriptFlagValue(); - uint16 mobOffset = readScriptFlagValue(); - uint16 value = readScriptFlagValue(); + int32 mobId = readScriptFlagValue(); + int32 mobOffset = readScriptFlagValue(); + int32 value = readScriptFlagValue(); _vm->_mobList[mobId].setData((Mob::AttrId)mobOffset, value); debugInterpreter("O_SETMOBDATA mobId %d, mobOffset %d, value %d", mobId, mobOffset, value); } void Interpreter::O_XORFLAG() { Flags::Id flagId = readScriptFlagId(); - int16 value = readScriptFlagValue(); + int32 value = readScriptFlagValue(); _flags->setFlagValue(flagId, _flags->getFlagValue(flagId) ^ value); if (_flags->getFlagValue(flagId)) { _result = 1; @@ -966,23 +966,23 @@ void Interpreter::O_XORFLAG() { } void Interpreter::O_GETMOBTEXT() { - uint16 mob = readScriptFlagValue(); + int32 mob = readScriptFlagValue(); _currentString = _vm->_locationNr * 100 + mob + 60001; _string = (byte *)_vm->_mobList[mob]._examText.c_str(); debugInterpreter("O_GETMOBTEXT mob %d", mob); } void Interpreter::O_MOVEHERO() { - uint16 heroId = readScriptFlagValue(); - uint16 x = readScriptFlagValue(); - uint16 y = readScriptFlagValue(); - uint16 dir = readScriptFlagValue(); + int32 heroId = readScriptFlagValue(); + int32 x = readScriptFlagValue(); + int32 y = readScriptFlagValue(); + int32 dir = readScriptFlagValue(); _vm->moveRunHero(heroId, x, y, dir, false); debugInterpreter("O_MOVEHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); } void Interpreter::O_WALKHERO() { - uint16 heroId = readScriptFlagValue(); + int32 heroId = readScriptFlagValue(); Hero *hero = nullptr; if (!heroId) { hero = _vm->_mainHero; @@ -999,10 +999,10 @@ void Interpreter::O_WALKHERO() { } void Interpreter::O_SETHERO() { - uint16 heroId = readScriptFlagValue(); - int16 x = readScriptFlagValue(); - int16 y = readScriptFlagValue(); - uint16 dir = readScriptFlagValue(); + int32 heroId = readScriptFlagValue(); + int32 x = readScriptFlagValue(); + int32 y = readScriptFlagValue(); + int32 dir = readScriptFlagValue(); Hero *hero = nullptr; if (!heroId) { hero = _vm->_mainHero; @@ -1019,7 +1019,7 @@ void Interpreter::O_SETHERO() { } void Interpreter::O_HEROOFF() { - uint16 heroId = readScriptFlagValue(); + int32 heroId = readScriptFlagValue(); Hero *hero = nullptr; if (!heroId) { hero = _vm->_mainHero; @@ -1033,7 +1033,7 @@ void Interpreter::O_HEROOFF() { } void Interpreter::O_HEROON() { - uint16 heroId = readScriptFlagValue(); + int32 heroId = readScriptFlagValue(); Hero *hero = nullptr; if (!heroId) { hero = _vm->_mainHero; @@ -1047,7 +1047,7 @@ void Interpreter::O_HEROON() { } void Interpreter::O_CLSTEXT() { - uint16 slot = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); _vm->_textSlots[slot]._str = nullptr; _vm->_textSlots[slot]._time = 0; debugInterpreter("O_CLSTEXT slot %d", slot); @@ -1067,8 +1067,8 @@ void Interpreter::O_CALLTABLE() { } void Interpreter::O_CHANGEMOB() { - uint16 mob = readScriptFlagValue(); - uint16 value = readScriptFlagValue(); + int32 mob = readScriptFlagValue(); + int32 value = readScriptFlagValue(); value ^= 1; _vm->_script->setMobVisible(_vm->_room->_mobs, mob, value); _vm->_mobList[mob]._visible = value; @@ -1076,15 +1076,15 @@ void Interpreter::O_CHANGEMOB() { } void Interpreter::O_ADDINV() { - uint16 hero = readScriptFlagValue(); - uint16 item = readScriptFlagValue(); + int32 hero = readScriptFlagValue(); + int32 item = readScriptFlagValue(); _vm->addInv(hero, item, false); debugInterpreter("O_ADDINV hero %d, item %d", hero, item); } void Interpreter::O_REMINV() { - uint16 hero = readScriptFlagValue(); - uint16 item = readScriptFlagValue(); + int32 hero = readScriptFlagValue(); + int32 item = readScriptFlagValue(); _vm->remInv(hero, item); debugInterpreter("O_REMINV hero %d, item %d", hero, item); } @@ -1120,8 +1120,8 @@ void Interpreter::O_WAITFRAME() { } void Interpreter::O_SETFRAME() { - uint16 anim = readScriptFlagValue(); - uint16 frame = readScriptFlagValue(); + int32 anim = readScriptFlagValue(); + int32 frame = readScriptFlagValue(); _vm->_normAnimList[anim]._frame = frame; debugInterpreter("O_SETFRAME anim %d, frame %d", anim, frame); } @@ -1133,8 +1133,8 @@ void Interpreter::O_RUNACTION() { void Interpreter::O_COMPAREHI() { Flags::Id flag = readScriptFlagId(); - int16 value = readScriptFlagValue(); - int16 flagValue = _flags->getFlagValue(flag); + int32 value = readScriptFlagValue(); + int32 flagValue = _flags->getFlagValue(flag); if (flagValue > value) { _result = 0; } else { @@ -1145,8 +1145,8 @@ void Interpreter::O_COMPAREHI() { void Interpreter::O_COMPARELO() { Flags::Id flag = readScriptFlagId(); - int16 value = readScriptFlagValue(); - int16 flagValue = _flags->getFlagValue(flag); + int32 value = readScriptFlagValue(); + int32 flagValue = _flags->getFlagValue(flag); if (flagValue < value) { _result = 0; } else { @@ -1171,13 +1171,13 @@ void Interpreter::O_CHECKINV() { } void Interpreter::O_TALKHERO() { - uint16 hero = readScriptFlagValue(); + int32 hero = readScriptFlagValue(); _vm->talkHero(hero); debugInterpreter("O_TALKHERO hero %d", hero); } void Interpreter::O_WAITTEXT() { - uint16 slot = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); Text &text = _vm->_textSlots[slot]; if (text._time && text._str) { if (_flags->getFlagValue(Flags::ESCAPED)) { @@ -1196,7 +1196,7 @@ void Interpreter::O_WAITTEXT() { } void Interpreter::O_SETHEROANIM() { - uint16 heroId = readScriptFlagValue(); + int32 heroId = readScriptFlagValue(); int32 offset = readScript(); Hero *hero = nullptr; if (!heroId) { @@ -1224,7 +1224,7 @@ void Interpreter::O_SETHEROANIM() { } void Interpreter::O_WAITHEROANIM() { - uint16 heroId = readScriptFlagValue(); + int32 heroId = readScriptFlagValue(); Hero *hero = nullptr; if (!heroId) { hero = _vm->_mainHero; @@ -1242,8 +1242,8 @@ void Interpreter::O_WAITHEROANIM() { void Interpreter::O_GETHERODATA() { Flags::Id flagId = readScriptFlagId(); - uint16 heroId = readScriptFlagValue(); - uint16 heroOffset = readScriptFlagValue(); + int32 heroId = readScriptFlagValue(); + int32 heroOffset = readScriptFlagValue(); Hero *hero = nullptr; if (!heroId) { hero = _vm->_mainHero; @@ -1262,10 +1262,10 @@ void Interpreter::O_GETMOUSEBUTTON() { } void Interpreter::O_CHANGEFRAMES() { - uint16 anim = readScriptFlagValue(); - uint16 frame = readScriptFlagValue(); - uint16 lastFrame = readScriptFlagValue(); - uint16 loopFrame = readScriptFlagValue(); + int32 anim = readScriptFlagValue(); + int32 frame = readScriptFlagValue(); + int32 lastFrame = readScriptFlagValue(); + int32 loopFrame = readScriptFlagValue(); _vm->_normAnimList[anim]._frame = frame; _vm->_normAnimList[anim]._lastFrame = lastFrame; _vm->_normAnimList[anim]._loopFrame = loopFrame; @@ -1273,10 +1273,10 @@ void Interpreter::O_CHANGEFRAMES() { } void Interpreter::O_CHANGEBACKFRAMES() { - uint16 anim = readScriptFlagValue(); - uint16 frame = readScriptFlagValue(); - uint16 lastFrame = readScriptFlagValue(); - uint16 loopFrame = readScriptFlagValue(); + int32 anim = readScriptFlagValue(); + int32 frame = readScriptFlagValue(); + int32 lastFrame = readScriptFlagValue(); + int32 loopFrame = readScriptFlagValue(); int currAnim = _vm->_backAnimList[anim]._seq._currRelative; Anim &backAnim = _vm->_backAnimList[anim].backAnims[currAnim]; backAnim._frame = frame; @@ -1287,8 +1287,8 @@ void Interpreter::O_CHANGEBACKFRAMES() { void Interpreter::O_GETBACKANIMDATA() { Flags::Id flagId = readScriptFlagId(); - uint16 animNumber = readScriptFlagValue(); - uint16 animDataOffset = readScriptFlagValue(); + int32 animNumber = readScriptFlagValue(); + int32 animDataOffset = readScriptFlagValue(); int currAnim = _vm->_backAnimList[animNumber]._seq._currRelative; int16 value = _vm->_backAnimList[animNumber].backAnims[currAnim].getAnimData((Anim::AnimOffsets)(animDataOffset)); _flags->setFlagValue((Flags::Id)(flagId), value); @@ -1297,8 +1297,8 @@ void Interpreter::O_GETBACKANIMDATA() { void Interpreter::O_GETANIMDATA() { Flags::Id flagId = readScriptFlagId(); - uint16 anim = readScriptFlagValue(); - uint16 animOffset = readScriptFlagValue(); + int32 anim = readScriptFlagValue(); + int32 animOffset = readScriptFlagValue(); if (_vm->_normAnimList[anim]._animData != nullptr) { _flags->setFlagValue(flagId, _vm->_normAnimList[anim].getAnimData((Anim::AnimOffsets)(animOffset))); } @@ -1312,8 +1312,8 @@ void Interpreter::O_SETBGCODE() { } void Interpreter::O_SETBACKFRAME() { - uint16 anim = readScriptFlagValue(); - uint16 frame = readScriptFlagValue(); + int32 anim = readScriptFlagValue(); + int32 frame = readScriptFlagValue(); int currAnim = _vm->_backAnimList[anim]._seq._currRelative; if (_vm->_backAnimList[anim].backAnims[currAnim]._animData != nullptr) { _vm->_backAnimList[anim].backAnims[currAnim]._frame = frame; @@ -1330,8 +1330,8 @@ void Interpreter::O_GETRND() { } void Interpreter::O_TALKBACKANIM() { - uint16 animNumber = readScriptFlagValue(); - uint16 slot = readScriptFlagValue(); + int32 animNumber = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); _vm->doTalkAnim(animNumber, slot, kBackgroundAnimation); debugInterpreter("O_TALKBACKANIM animNumber %d, slot %d", animNumber, slot); } @@ -1366,23 +1366,23 @@ void Interpreter::O_CALLDFLAG() { } void Interpreter::O_PRINTAT() { - uint16 slot = readScriptFlagValue(); - uint16 x = readScriptFlagValue(); - uint16 y = readScriptFlagValue(); - uint8 color = _flags->getFlagValue(Flags::KOLOR); + int32 slot = readScriptFlagValue(); + int32 x = readScriptFlagValue(); + int32 y = readScriptFlagValue(); + int32 color = _flags->getFlagValue(Flags::KOLOR); _vm->printAt(slot, color, (char *)_string, x, y); increaseString(); debugInterpreter("O_PRINTAT slot %d, x %d, y %d", slot, x, y); } void Interpreter::O_ZOOMIN() { - uint16 slot = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); _vm->initZoomIn(slot); debugInterpreter("O_ZOOMIN slot %04d", slot); } void Interpreter::O_ZOOMOUT() { - uint16 slot = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); _vm->initZoomOut(slot); debugInterpreter("O_ZOOMOUT slot %d", slot); } @@ -1394,8 +1394,8 @@ void Interpreter::O_SETSTRINGOFFSET() { void Interpreter::O_GETOBJDATA() { Flags::Id flag = readScriptFlagId(); - uint16 slot = readScriptFlagValue(); - uint16 objOffset = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); + int32 objOffset = readScriptFlagValue(); int nr = _vm->_objSlot[slot]; if (nr != 0xFF) { int16 value = _vm->_objList[nr]->getData((Object::AttrId)objOffset); @@ -1405,9 +1405,9 @@ void Interpreter::O_GETOBJDATA() { } void Interpreter::O_SETOBJDATA() { - uint16 slot = readScriptFlagValue(); - uint16 objOffset = readScriptFlagValue(); - int16 value = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); + int32 objOffset = readScriptFlagValue(); + int32 value = readScriptFlagValue(); int nr = _vm->_objSlot[slot]; if (nr != 0xFF) { _vm->_objList[nr]->setData((Object::AttrId)objOffset, value); @@ -1421,8 +1421,8 @@ void Interpreter::O_SWAPOBJECTS() { } void Interpreter::O_CHANGEHEROSET() { - uint16 heroId = readScriptFlagValue(); - uint16 heroSet = readScriptFlagValue(); + int32 heroId = readScriptFlagValue(); + int32 heroSet = readScriptFlagValue(); if (!heroId) { _vm->_mainHero->loadAnimSet(heroSet); } else if (heroId == 1) { @@ -1437,7 +1437,7 @@ void Interpreter::O_ADDSTRING() { } void Interpreter::O_SUBSTRING() { - uint16 value = readScriptFlagValue(); + int32 value = readScriptFlagValue(); _string -= value; debugInterpreter("O_SUBSTRING value %d", value); } @@ -1530,7 +1530,7 @@ void Interpreter::O_INITDIALOG() { } void Interpreter::O_ENABLEDIALOGOPT() { - uint16 opt = readScriptFlagValue(); + int32 opt = readScriptFlagValue(); int dialogDataValue = (int)READ_UINT32(_vm->_dialogData); dialogDataValue &= ~(1u << opt); WRITE_UINT32(_vm->_dialogData, dialogDataValue); @@ -1538,7 +1538,7 @@ void Interpreter::O_ENABLEDIALOGOPT() { } void Interpreter::O_DISABLEDIALOGOPT() { - uint16 opt = readScriptFlagValue(); + int32 opt = readScriptFlagValue(); int dialogDataValue = (int)READ_UINT32(_vm->_dialogData); dialogDataValue |= (1u << opt); WRITE_UINT32(_vm->_dialogData, dialogDataValue); @@ -1546,7 +1546,7 @@ void Interpreter::O_DISABLEDIALOGOPT() { } void Interpreter::O_SHOWDIALOGBOX() { - uint16 box = readScriptFlagValue(); + int32 box = readScriptFlagValue(); uint32 currInstr = _currentInstruction; _vm->createDialogBox(box); _flags->setFlagValue(Flags::DIALINES, _vm->_dialogLines); @@ -1560,16 +1560,16 @@ void Interpreter::O_SHOWDIALOGBOX() { } void Interpreter::O_STOPSAMPLE() { - uint16 slot = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); _vm->stopSample(slot); debugInterpreter("O_STOPSAMPLE slot %d", slot); } void Interpreter::O_BACKANIMRANGE() { - uint16 slotId = readScriptFlagValue(); + int32 slotId = readScriptFlagValue(); uint16 animId = readScript(); - uint16 low = readScriptFlagValue(); - uint16 high = readScriptFlagValue(); + int32 low = readScriptFlagValue(); + int32 high = readScriptFlagValue(); if (animId != 0xFFFF) { if (animId & InterpreterFlags::kFlagMask) { animId = _flags->getFlagValue((Flags::Id)animId); @@ -1608,7 +1608,7 @@ void Interpreter::O_SETPATH() { } void Interpreter::O_GETHEROX() { - uint16 heroId = readScriptFlagValue(); + int32 heroId = readScriptFlagValue(); Flags::Id flagId = readScriptFlagId(); if (!heroId) { _flags->setFlagValue(flagId, _vm->_mainHero->_middleX); @@ -1619,7 +1619,7 @@ void Interpreter::O_GETHEROX() { } void Interpreter::O_GETHEROY() { - uint16 heroId = readScriptFlagValue(); + int32 heroId = readScriptFlagValue(); Flags::Id flagId = readScriptFlagId(); if (!heroId) { _flags->setFlagValue(flagId, _vm->_mainHero->_middleY); @@ -1630,7 +1630,7 @@ void Interpreter::O_GETHEROY() { } void Interpreter::O_GETHEROD() { - uint16 heroId = readScriptFlagValue(); + int32 heroId = readScriptFlagValue(); Flags::Id flagId = readScriptFlagId(); if (!heroId) { _flags->setFlagValue(flagId, _vm->_mainHero->_lastDirection); @@ -1661,7 +1661,7 @@ void Interpreter::O_SETFGCODE() { } void Interpreter::O_STOPHERO() { - uint16 heroId = readScriptFlagValue(); + int32 heroId = readScriptFlagValue(); if (!heroId) { _vm->_mainHero->freeOldMove(); } else if (heroId == 1) { @@ -1671,13 +1671,13 @@ void Interpreter::O_STOPHERO() { } void Interpreter::O_ANIMUPDATEOFF() { - uint16 slotId = readScriptFlagValue(); + int32 slotId = readScriptFlagValue(); _vm->_normAnimList[slotId]._state = 1; debugInterpreter("O_ANIMUPDATEOFF slotId %d", slotId); } void Interpreter::O_ANIMUPDATEON() { - uint16 slotId = readScriptFlagValue(); + int32 slotId = readScriptFlagValue(); _vm->_normAnimList[slotId]._state = 0; debugInterpreter("O_ANIMUPDATEON slotId %d", slotId); } @@ -1690,17 +1690,17 @@ void Interpreter::O_FREECURSOR() { } void Interpreter::O_ADDINVQUIET() { - uint16 hero = readScriptFlagValue(); - uint16 item = readScriptFlagValue(); + int32 hero = readScriptFlagValue(); + int32 item = readScriptFlagValue(); _vm->addInv(hero, item, true); debugInterpreter("O_ADDINVQUIET hero %d, item %d", hero, item); } void Interpreter::O_RUNHERO() { - uint16 heroId = readScriptFlagValue(); - uint16 x = readScriptFlagValue(); - uint16 y = readScriptFlagValue(); - uint16 dir = readScriptFlagValue(); + int32 heroId = readScriptFlagValue(); + int32 x = readScriptFlagValue(); + int32 y = readScriptFlagValue(); + int32 dir = readScriptFlagValue(); _vm->moveRunHero(heroId, x, y, dir, true); debugInterpreter("O_RUNHERO heroId %d, x %d, y %d, dir %d", heroId, x, y, dir); } @@ -1716,13 +1716,13 @@ void Interpreter::O_SETBACKANIMDATA() { } void Interpreter::O_VIEWFLC() { - uint16 animNr = readScriptFlagValue(); + int32 animNr = readScriptFlagValue(); _vm->loadAnim(animNr, false); debugInterpreter("O_VIEWFLC animNr %d", animNr); } void Interpreter::O_CHECKFLCFRAME() { - uint16 frameNr = readScriptFlagValue(); + int32 frameNr = readScriptFlagValue(); debugInterpreter("O_CHECKFLCFRAME frame number %d", frameNr); if (_vm->_flicPlayer.getCurFrame() != frameNr) { _currentInstruction -= 4; @@ -1745,7 +1745,7 @@ void Interpreter::O_FREEFLC() { } void Interpreter::O_TALKHEROSTOP() { - uint16 heroId = readScriptFlagValue(); + int32 heroId = readScriptFlagValue(); if (!heroId) { _vm->_mainHero->_state = Hero::kHeroStateStay; } else if (heroId == 1) { @@ -1756,8 +1756,8 @@ void Interpreter::O_TALKHEROSTOP() { // TODO - check this void Interpreter::O_HEROCOLOR() { - uint16 heroId = readScriptFlagValue(); - uint16 color = readScriptFlagValue(); + int32 heroId = readScriptFlagValue(); + int32 color = readScriptFlagValue(); if (!heroId) { _vm->_mainHero->_color = color; } else if (heroId == 1) { @@ -1772,31 +1772,31 @@ void Interpreter::O_GRABMAPA() { } void Interpreter::O_ENABLENAK() { - uint16 nakId = readScriptFlagValue(); + int32 nakId = readScriptFlagValue(); _vm->_maskList[nakId]._flags = 0; debugInterpreter("O_ENABLENAK nakId %d", nakId); } void Interpreter::O_DISABLENAK() { - uint16 nakId = readScriptFlagValue(); + int32 nakId = readScriptFlagValue(); _vm->_maskList[nakId]._flags = 1; debugInterpreter("O_DISABLENAK nakId %d", nakId); } void Interpreter::O_GETMOBNAME() { - uint16 modId = readScriptFlagValue(); + int32 modId = readScriptFlagValue(); _string = (byte *)_vm->_mobList[modId]._name.c_str(); debugInterpreter("O_GETMOBNAME modId %d", modId); } void Interpreter::O_SWAPINVENTORY() { - uint16 hero = readScriptFlagValue(); + int32 hero = readScriptFlagValue(); _vm->swapInv(hero); debugInterpreter("O_SWAPINVENTORY hero %d", hero); } void Interpreter::O_CLEARINVENTORY() { - uint16 hero = readScriptFlagValue(); + int32 hero = readScriptFlagValue(); _vm->clearInv(hero); debugInterpreter("O_CLEARINVENTORY hero %d", hero); } @@ -1807,42 +1807,42 @@ void Interpreter::O_SKIPTEXT() { } void Interpreter::O_SETVOICEH() { - uint16 slot = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); static const uint32 VOICE_H_SLOT = 28; uint16 voiceLineH = _flags->getFlagValue(Flags::VOICE_H_LINE); _vm->setVoice(slot, VOICE_H_SLOT, voiceLineH); } void Interpreter::O_SETVOICEA() { - uint16 slot = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); static const uint32 VOICE_A_SLOT = 29; uint16 voiceLineH = _flags->getFlagValue(Flags::VOICE_H_LINE); _vm->setVoice(slot, VOICE_A_SLOT, voiceLineH); } void Interpreter::O_SETVOICEB() { - uint16 slot = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); static const uint32 VOICE_B_SLOT = 30; uint16 voiceLineH = _flags->getFlagValue(Flags::VOICE_H_LINE); _vm->setVoice(slot, VOICE_B_SLOT, voiceLineH); } void Interpreter::O_SETVOICEC() { - uint16 slot = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); static const uint32 VOICE_C_SLOT = 31; uint16 voiceLineH = _flags->getFlagValue(Flags::VOICE_H_LINE); _vm->setVoice(slot, VOICE_C_SLOT, voiceLineH); } void Interpreter::O_SETVOICED() { - uint16 slot = readScriptFlagValue(); + int32 slot = readScriptFlagValue(); static const uint32 VOICE_D_SLOT = 32; uint16 voiceLineH = _flags->getFlagValue(Flags::VOICE_H_LINE); _vm->setVoice(slot, VOICE_D_SLOT, voiceLineH); } void Interpreter::O_VIEWFLCLOOP() { - uint16 animId = readScriptFlagValue(); + int32 animId = readScriptFlagValue(); _vm->loadAnim(animId, true); debugInterpreter("O_VIEWFLCLOOP animId %d", animId); } @@ -1870,8 +1870,8 @@ void Interpreter::O_GETKRZYWA() { void Interpreter::O_GETMOB() { Flags::Id flagId = readScriptFlagId(); - uint16 posX = readScriptFlagValue(); - uint16 posY = readScriptFlagValue(); + int32 posX = readScriptFlagValue(); + int32 posY = readScriptFlagValue(); int mobNumber = _vm->getMob(_vm->_mobList, true, posX, posY); _flags->setFlagValue(flagId, mobNumber + 1); debugInterpreter("O_GETMOB flagId %d, posX %d, posY %d", flagId, posX, posY); diff --git a/engines/prince/script.h b/engines/prince/script.h index 196a19512d85..98f5000004d5 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -240,7 +240,7 @@ class Interpreter { // Helper functions uint32 step(uint32 opcodePC); - int16 readScriptFlagValue(); + int32 readScriptFlagValue(); Flags::Id readScriptFlagId(); int checkSeq(byte *string); From 886cf189c66a9fa59f0317a25ccc5db9d75bf59a Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 8 Aug 2014 22:58:38 +0200 Subject: [PATCH 333/374] PRINCE: showPower(), O_EXIT - last mini-game and game ending --- engines/prince/prince.cpp | 54 +++++++++++++++++++++++++++++++++++++++ engines/prince/prince.h | 12 +++++++++ engines/prince/script.cpp | 16 ++++++++---- engines/prince/script.h | 1 + 4 files changed, 78 insertions(+), 5 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index bac261e56f57..d5796e203f7f 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -888,6 +888,16 @@ void PrinceEngine::keyHandler(Common::Event event) { getDebugger()->attach(); } break; + case Common::KEYCODE_z: + if (_flags->getFlagValue(Flags::POWERENABLED)) { + _flags->setFlagValue(Flags::MBFLAG, 1); + } + break; + case Common::KEYCODE_x: + if (_flags->getFlagValue(Flags::POWERENABLED)) { + _flags->setFlagValue(Flags::MBFLAG, 2); + } + break; case Common::KEYCODE_ESCAPE: _flags->setFlagValue(Flags::ESCAPED2, 1); break; @@ -1768,6 +1778,8 @@ void PrinceEngine::drawScreen() { _inventoryBackgroundRemember = false; } + showPower(); + getDebugger()->onFrame(); } else { @@ -2207,6 +2219,9 @@ void PrinceEngine::moveRunHero(int heroId, int x, int y, int dir, bool runHeroFl void PrinceEngine::leftMouseButton() { _flags->setFlagValue(Flags::LMOUSE, 1); + if (_flags->getFlagValue(Flags::POWERENABLED)) { + _flags->setFlagValue(Flags::MBFLAG, 1); + } if (_mouseFlag) { int option = 0; int optionEvent = -1; @@ -2285,6 +2300,9 @@ void PrinceEngine::leftMouseButton() { } void PrinceEngine::rightMouseButton() { + if (_flags->getFlagValue(Flags::POWERENABLED)) { + _flags->setFlagValue(Flags::MBFLAG, 2); + } if (_mouseFlag) { _mainHero->freeOldMove(); _secondHero->freeOldMove(); @@ -2920,6 +2938,42 @@ void PrinceEngine::mouseWeirdo() { } } +void PrinceEngine::showPower() { + if (_flags->getFlagValue(Flags::POWERENABLED)) { + int power = _flags->getFlagValue(Flags::POWER); + + byte *dst = (byte *)_graph->_frontScreen->getBasePtr(kPowerBarPosX, kPowerBarPosY); + for (int y = 0; y < kPowerBarHeight; y++) { + byte *dst2 = dst; + for (int x = 0; x < kPowerBarWidth; x++, dst2++) { + *dst2 = kPowerBarBackgroundColor; + } + dst += _graph->_frontScreen->pitch; + } + + if (power) { + byte *dst = (byte *)_graph->_frontScreen->getBasePtr(kPowerBarPosX, kPowerBarGreenPosY); + for (int y = 0; y < kPowerBarGreenHeight; y++) { + byte *dst2 = dst; + for (int x = 0; x < power + 1; x++, dst2++) { + if (x < 58) { + *dst2 = kPowerBarGreenColor1; + } else { + *dst2 = kPowerBarGreenColor2; + } + } + dst += _graph->_frontScreen->pitch; + } + } + + _graph->change(); + } +} + +// TODO +void PrinceEngine::showCredits() { +} + // 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 diff --git a/engines/prince/prince.h b/engines/prince/prince.h index c8600e78284a..4aeb4f99f446 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -262,6 +262,7 @@ class PrinceEngine : public Engine { void syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream); bool loadGame(int slotNumber); void resetGame(); + void showCredits(); int getGameType() const; const char *getGameId() const; @@ -490,6 +491,17 @@ class PrinceEngine : public Engine { void getCurve(); void mouseWeirdo(); + static const uint16 kPowerBarPosX = 288; + static const uint16 kPowerBarPosY = 430; + static const uint8 kPowerBarWidth = 64; + static const uint8 kPowerBarHeight = 16; + static const uint8 kPowerBarBackgroundColor = 0; + static const uint16 kPowerBarGreenPosY = 434; + static const uint8 kPowerBarGreenColor1 = 202; + static const uint8 kPowerBarGreenColor2 = 235; + static const uint8 kPowerBarGreenHeight = 8; + void showPower(); + // Pathfinding static const int16 kPathGridStep = 2; static const int32 kPathBitmapLen = (kMaxPicHeight / kPathGridStep * kMaxPicWidth / kPathGridStep) / 8; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 4d00018a02b4..e6423144a73a 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -406,7 +406,7 @@ int32 InterpreterFlags::getFlagValue(Flags::Id flagId) { Interpreter::Interpreter(PrinceEngine *vm, Script *script, InterpreterFlags *flags) : _vm(vm), _script(script), _flags(flags), - _stacktop(0), _opcodeNF(false), + _stacktop(0), _opcodeNF(false), _opcodeEnd(false), _waitFlag(0), _result(true) { // Initialize the script @@ -469,6 +469,10 @@ uint32 Interpreter::step(uint32 opcodePC) { } } + if (_opcodeEnd) { + _vm->quitGame(); + } + return _currentInstruction; } @@ -854,12 +858,14 @@ void Interpreter::O_JUMPNZ() { debugInterpreter("O_JUMPNZ result = %d, next %08x, offset 0x%08X", _result, _currentInstruction, offset); } -// TODO void Interpreter::O_EXIT() { int32 exitCode = readScriptFlagValue(); + _opcodeEnd = true; + _opcodeNF = 1; + if (exitCode == 0x2EAD) { + _vm->showCredits(); + } debugInterpreter("O_EXIT exitCode %d", exitCode); - // Set exit code and shows credits - // if exit code == 0x02EAD } void Interpreter::O_ADDFLAG() { @@ -1256,7 +1262,7 @@ void Interpreter::O_GETHERODATA() { debugInterpreter("O_GETHERODATA flag %04x - (%s), heroId %d, heroOffset %d", flagId, Flags::getFlagName(flagId), heroId, heroOffset); } -// TODO - for location 41 (prison in hell) +// No need of implementation here void Interpreter::O_GETMOUSEBUTTON() { debugInterpreter("O_GETMOUSEBUTTON"); } diff --git a/engines/prince/script.h b/engines/prince/script.h index 98f5000004d5..1c87fb3b2309 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -222,6 +222,7 @@ class Interpreter { byte _result; bool _opcodeNF; // break interpreter loop + bool _opcodeEnd; // end of a game flag static const uint32 _STACK_SIZE = 500; uint32 _stack[_STACK_SIZE]; From b97f726a3e79d11ca243ef48a8a6173d47366c7e Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 9 Aug 2014 05:37:57 +0200 Subject: [PATCH 334/374] PRINCE: scrollCredits() implementation, showLogo() update --- engines/prince/font.cpp | 6 +- engines/prince/font.h | 1 + engines/prince/graphics.cpp | 6 -- engines/prince/graphics.h | 2 - engines/prince/prince.cpp | 131 +++++++++++++++++++++++++++++++----- engines/prince/prince.h | 9 ++- engines/prince/script.cpp | 2 +- 7 files changed, 130 insertions(+), 27 deletions(-) diff --git a/engines/prince/font.cpp b/engines/prince/font.cpp index 0ac61f29beda..42329d26065e 100644 --- a/engines/prince/font.cpp +++ b/engines/prince/font.cpp @@ -25,6 +25,7 @@ #include "common/stream.h" #include "prince/font.h" +#include "prince/prince.h" namespace Prince { @@ -72,6 +73,7 @@ int Font::getCharWidth(uint32 chr) const { void Font::drawChar(Graphics::Surface *dst, uint32 chr, int posX, int posY, uint32 color) const { const ChrData chrData = getChrData(chr); + Common::Rect screenRect(0, 0, PrinceEngine::kNormalWidth, PrinceEngine::kNormalHeight); for (int y = 0; y < chrData._height; y++) { for (int x = 0; x < chrData._width; x++) { @@ -81,7 +83,9 @@ void Font::drawChar(Graphics::Surface *dst, uint32 chr, int posX, int posY, uint else if (d == 2) d = color; else if (d == 3) d = 0; if (d != 255) { - *(byte *)dst->getBasePtr(posX + x, posY + y) = d; + if (screenRect.contains(posX + x, posY + y)) { + *(byte *)dst->getBasePtr(posX + x, posY + y) = d; + } } } } diff --git a/engines/prince/font.h b/engines/prince/font.h index 001e9f7668d4..3b50994e2c6a 100644 --- a/engines/prince/font.h +++ b/engines/prince/font.h @@ -26,6 +26,7 @@ #include "graphics/surface.h" #include "common/str.h" +#include "common/rect.h" namespace Prince { diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index e161ddd1967b..bc8c86e65d7f 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -259,12 +259,6 @@ void GraphicsMan::drawBackSpriteDrawNode(Graphics::Surface *screen, DrawNode *dr } } -void GraphicsMan::drawPixel(Graphics::Surface *screen, int32 posX, int32 posY) { - byte *dst = (byte *)screen->getBasePtr(posX, posY); - *dst = 255; - change(); -} - byte GraphicsMan::getBlendTableColor(byte pixelColor, byte backgroundPixelColor, byte *blendTable) { int32 redFirstOrg, greenFirstOrg, blueFirstOrg; int32 redFirstBack, greenFirstBack, blueFirstBack; diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index 95c10ec790a3..83a4aec55c61 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -65,8 +65,6 @@ class GraphicsMan { static const byte kShadowColor = 191; - void drawPixel(Graphics::Surface *screen, int32 posX, int32 posY); - private: PrinceEngine *_vm; bool _changed; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index d5796e203f7f..7ecdae5fa6ee 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -93,7 +93,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _traceLineLen(0), _rembBitmapTemp(nullptr), _rembBitmap(nullptr), _rembMask(0), _rembX(0), _rembY(0), _fpX(0), _fpY(0), _checkBitmapTemp(nullptr), _checkBitmap(nullptr), _checkMask(0), _checkX(0), _checkY(0), _traceLineFirstPointFlag(false), _tracePointFirstPointFlag(false), _coordsBuf2(nullptr), _coords2(nullptr), _coordsBuf3(nullptr), _coords3(nullptr), - _shanLen(0), _directionTable(nullptr), _currentMidi(0), _lightX(0), _lightY(0), _curveData(nullptr), _curvPos(0) { + _shanLen(0), _directionTable(nullptr), _currentMidi(0), _lightX(0), _lightY(0), _curveData(nullptr), _curvPos(0), + _creditsData(nullptr), _creditsDataSize(0), _currentTime(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -192,6 +193,8 @@ PrinceEngine::~PrinceEngine() { free(_shadowBitmap); free(_curveData); + + free(_creditsData); } GUI::Debugger *PrinceEngine::getDebugger() { @@ -338,15 +341,29 @@ void PrinceEngine::init() { _shadowBitmap = (byte *)malloc(2 * kShadowBitmapSize); _curveData = (int16 *)malloc(2 * kCurveLen * sizeof(int16)); + + Common::SeekableReadStream *creditsDataStream = SearchMan.createReadStreamForMember("credits.dat"); + if (!creditsDataStream) { + error("Can't load creditsDataStream"); + return; + } + _creditsDataSize = creditsDataStream->size(); + _creditsData = (byte *)malloc(_creditsDataSize); + creditsDataStream->read(_creditsData, _creditsDataSize); } void PrinceEngine::showLogo() { MhwanhDecoder logo; + _system->delayMillis(1000 / kFPS * 20); if (Resource::loadResource(&logo, "logo.raw", true)) { + loadSample(0, "LOGO.WAV"); + playSample(0, 0); _graph->setPalette(logo.getPalette()); + //TODO - setPalette(); _graph->draw(_graph->_frontScreen, logo.getSurface()); _graph->update(_graph->_frontScreen); - _system->delayMillis(700); + _graph->change(); + _system->delayMillis(1000 / kFPS * 70); } } @@ -1069,7 +1086,7 @@ void PrinceEngine::printAt(uint32 slot, uint8 color, char *s, uint16 x, uint16 y text._y = y; text._color = color; int lines = calcTextLines(s); - text._time = calcTextTime(lines); + text._time = calcTextTime(lines); } int PrinceEngine::calcTextLines(const char *s) { @@ -1848,10 +1865,17 @@ void PrinceEngine::setPalette() { } void PrinceEngine::pause() { - uint32 currentTime = _system->getMillis(); - int delay = 1000 / 15 - int32(_system->getMillis() - currentTime); + int delay = 1000 / kFPS - int32(_system->getMillis() - _currentTime); + delay = delay < 0 ? 0 : delay; + _system->delayMillis(delay); + _currentTime = _system->getMillis(); +} + +void PrinceEngine::pause2() { + int delay = 1000 / (kFPS * 2) - int32(_system->getMillis() - _currentTime); delay = delay < 0 ? 0 : delay; _system->delayMillis(delay); + _currentTime = _system->getMillis(); } void PrinceEngine::addInv(int heroId, int item, bool addItemQuiet) { @@ -2970,8 +2994,90 @@ void PrinceEngine::showPower() { } } -// TODO -void PrinceEngine::showCredits() { +void PrinceEngine::scrollCredits() { + byte *scrollAdress = _creditsData; + while (!shouldQuit()) { + for (int scrollPos = 0; scrollPos > -23; scrollPos--) { + const Graphics::Surface *roomSurface = _roomBmp->getSurface(); + if (roomSurface) { + _graph->draw(_graph->_frontScreen, roomSurface); + } + char *s = (char *)scrollAdress; + int drawY = scrollPos; + for (int i = 0; i < 22; i++) { + Common::String line; + char *linePos = s; + while ((*linePos != 13)) { + line += *linePos; + linePos++; + } + if (!line.empty()) { + int drawX = (kNormalWidth - getTextWidth(line.c_str())) / 2; + _font->drawString(_graph->_frontScreen, line, drawX, drawY, _graph->_frontScreen->w, 217); + } + + char letter1; + bool gotIt1 = false; + do { + letter1 = *s; + s++; + if (letter1 == 13) { + if (*s == 10) { + s++; + } + if (*s != 35) { + gotIt1 = true; + } + break; + } + } while (letter1 != 35); + + if (gotIt1) { + drawY += 23; + } else { + break; + } + } + Common::Event event; + Common::EventManager *eventMan = _system->getEventManager(); + while (eventMan->pollEvent(event)) { + if (event.type == Common::EVENT_KEYDOWN) { + if (event.kbd.keycode == Common::KEYCODE_ESCAPE) { + blackPalette(); + return; + } + } + } + if (shouldQuit()) { + return; + } + _graph->change(); + _graph->update(_graph->_frontScreen); + pause2(); + } + char letter2; + byte *scan2 = scrollAdress; + bool gotIt2 = false; + do { + letter2 = *scan2; + scan2++; + if (letter2 == 13) { + if (*scan2 == 10) { + scan2++; + } + if (*scan2 != 35) { + gotIt2 = true; + } + break; + } + } while (letter2 != 35); + if (gotIt2) { + scrollAdress = scan2; + } else { + break; + } + } + blackPalette(); } // Modified version of Graphics::drawLine() to allow breaking the loop and return value @@ -4515,12 +4621,10 @@ void PrinceEngine::openInventoryCheck() { } void PrinceEngine::mainLoop() { - changeCursor(0); + _currentTime = _system->getMillis(); while (!shouldQuit()) { - uint32 currentTime = _system->getMillis(); - Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); while (eventMan->pollEvent(event)) { @@ -4555,12 +4659,7 @@ void PrinceEngine::mainLoop() { openInventoryCheck(); - // Calculate the frame delay based off a desired frame time - int delay = 1000 / 15 - int32(_system->getMillis() - currentTime); - // Ensure non-negative - delay = delay < 0 ? 0 : delay; - _system->delayMillis(delay); - + pause(); } } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 4aeb4f99f446..2a9fe8666b11 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -262,7 +262,10 @@ class PrinceEngine : public Engine { void syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream); bool loadGame(int slotNumber); void resetGame(); - void showCredits(); + + int32 _creditsDataSize; + byte *_creditsData; + void scrollCredits(); int getGameType() const; const char *getGameId() const; @@ -315,6 +318,7 @@ class PrinceEngine : public Engine { }; int _mouseFlag; + uint32 _currentTime; uint16 _locationNr; uint16 _sceneWidth; int32 _picWindowX; @@ -331,6 +335,8 @@ class PrinceEngine : public Engine { byte *_zoomBitmap; byte *_shadowBitmap; + static const int16 kFPS = 15; + static const int16 kMaxPicWidth = 1280; static const int16 kMaxPicHeight = 480; static const int16 kZoomStep = 4; @@ -608,6 +614,7 @@ class PrinceEngine : public Engine { void runDrawNodes(); void makeShadowTable(int brightness); void pause(); + void pause2(); uint32 getTextWidth(const char *s); void debugEngine(const char *s, ...); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index e6423144a73a..8fa24a4afc43 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -863,7 +863,7 @@ void Interpreter::O_EXIT() { _opcodeEnd = true; _opcodeNF = 1; if (exitCode == 0x2EAD) { - _vm->showCredits(); + _vm->scrollCredits(); } debugInterpreter("O_EXIT exitCode %d", exitCode); } From 425132faf9ca3eec69a087a65321bae5c8c7a1ab Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 9 Aug 2014 21:44:38 +0200 Subject: [PATCH 335/374] PRINCE: showPalette(), showLogo() - update --- engines/prince/prince.cpp | 56 ++++++++++++++++++--------------------- engines/prince/prince.h | 2 +- engines/prince/script.cpp | 2 +- 3 files changed, 28 insertions(+), 32 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 7ecdae5fa6ee..2894831386a8 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -358,11 +358,10 @@ void PrinceEngine::showLogo() { if (Resource::loadResource(&logo, "logo.raw", true)) { loadSample(0, "LOGO.WAV"); playSample(0, 0); - _graph->setPalette(logo.getPalette()); - //TODO - setPalette(); _graph->draw(_graph->_frontScreen, logo.getSurface()); - _graph->update(_graph->_frontScreen); _graph->change(); + _graph->update(_graph->_frontScreen); + setPalette(logo.getPalette()); _system->delayMillis(1000 / kFPS * 70); } } @@ -1833,35 +1832,32 @@ void PrinceEngine::blackPalette() { free(blackPalette); } -void PrinceEngine::setPalette() { - byte *paletteBackup = nullptr; - byte *blackPalette = (byte *)malloc(256 * 3); - - int fadeStep = 0; - for (int i = 0; i <= kFadeStep; i++) { - paletteBackup = (byte *)_roomBmp->getPalette(); - for (int j = 0; j < 256; j++) { - blackPalette[3 * j] = paletteBackup[3 * j] * fadeStep / 4; - blackPalette[3 * j + 1] = paletteBackup[3 * j + 1] * fadeStep / 4; - blackPalette[3 * j + 2] = paletteBackup[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(paletteBackup); - free(blackPalette); - return; +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; + } + pause(); } - pause(); - } - if (paletteBackup != nullptr) { - _graph->setPalette(paletteBackup); + _graph->setPalette(palette); + free(blackPalette); } - free(blackPalette); } void PrinceEngine::pause() { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 2a9fe8666b11..a1e59cc9ae69 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -484,7 +484,7 @@ class PrinceEngine : public Engine { static const uint8 kFadeStep = 4; void blackPalette(); - void setPalette(); + void setPalette(const byte *palette); int getMob(Common::Array &mobList, bool usePriorityList, int posX, int posY); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 8fa24a4afc43..872da2e82deb 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -559,7 +559,7 @@ void Interpreter::O_BLACKPALETTE() { } void Interpreter::O_SETUPPALETTE() { - _vm->setPalette(); + _vm->setPalette(_vm->_roomBmp->getPalette()); debugInterpreter("O_SETUPPALETTE"); } From 01b243d996f476b2feff1a43df2ef4d6a02bcdff Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 9 Aug 2014 22:11:52 +0200 Subject: [PATCH 336/374] PRINCE: Hero::getData() - fix --- engines/prince/hero.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 282d86557472..5b630ae3b673 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -107,7 +107,7 @@ uint16 Hero::getData(AttrId dataId) { case kHeroLastDir: return _lastDirection; case kHeroAnimSet: - return _moveSetType; + return _animSetNr; default: assert(false); return 0; From 70a94908d3ddab949cd0755c148d87e0c59d420b Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 10 Aug 2014 16:08:45 +0200 Subject: [PATCH 337/374] PRINCE: Throw a rock mini-game - cursor update --- engines/prince/prince.cpp | 19 +++++++++---------- engines/prince/script.cpp | 1 - 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 2894831386a8..060c1ca23333 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -516,10 +516,7 @@ void PrinceEngine::changeCursor(uint16 curId) { const Graphics::Surface *curSurface = nullptr; - uint16 hotspotX = 0; - uint16 hotspotY = 0; - - switch(curId) { + switch (curId) { case 0: CursorMan.showMouse(false); _optionsFlag = 0; @@ -533,8 +530,10 @@ void PrinceEngine::changeCursor(uint16 curId) { break; case 3: curSurface = _cursor3->getSurface(); - hotspotX = curSurface->w >> 1; - hotspotY = curSurface->h >> 1; + 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; } @@ -542,7 +541,7 @@ void PrinceEngine::changeCursor(uint16 curId) { CursorMan.replaceCursor( curSurface->getBasePtr(0, 0), curSurface->w, curSurface->h, - hotspotX, hotspotY, + 0, 0, 255, false, &curSurface->format ); @@ -2323,7 +2322,7 @@ void PrinceEngine::rightMouseButton() { if (_flags->getFlagValue(Flags::POWERENABLED)) { _flags->setFlagValue(Flags::MBFLAG, 2); } - if (_mouseFlag) { + if (_mouseFlag && _mouseFlag != 3) { _mainHero->freeOldMove(); _secondHero->freeOldMove(); _interpreter->storeNewPC(0); @@ -2950,9 +2949,9 @@ void PrinceEngine::mouseWeirdo() { mousePos.y -= kCelStep; break; } - mousePos.x = CLIP(mousePos.x, (int16) 0, (int16) 639); + mousePos.x = CLIP(mousePos.x, (int16) 315, (int16) 639); _flags->setFlagValue(Flags::MXFLAG, mousePos.x); - mousePos.y = CLIP(mousePos.y, (int16) 0, (int16) 479); + mousePos.y = CLIP(mousePos.y, (int16) 0, (int16) 170); _flags->setFlagValue(Flags::MYFLAG, mousePos.y); _system->warpMouse(mousePos.x, mousePos.y); } diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 872da2e82deb..9dabebfb5eae 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1760,7 +1760,6 @@ void Interpreter::O_TALKHEROSTOP() { debugInterpreter("O_TALKHEROSTOP %d", heroId); } -// TODO - check this void Interpreter::O_HEROCOLOR() { int32 heroId = readScriptFlagValue(); int32 color = readScriptFlagValue(); From 075ea1a0e01cb8f6f2bf672e9cc88399355d12c5 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 10 Aug 2014 16:56:33 +0200 Subject: [PATCH 338/374] PRINCE: makePath() - fix --- engines/prince/prince.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 060c1ca23333..bdf33e55a937 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -4422,12 +4422,18 @@ byte *PrinceEngine::makePath(int heroId, int currX, int currY, int destX, int de if ((x1 != x2) || (y1 != y2)) { findPoint(x1, y1); - if (x1 != _fpX || y1 != _fpY) { + if (!getPixelAddr(_roomPathBitmap, _fpX, _fpY)) { + return nullptr; + } + if ((x1 != _fpX) || (y1 != _fpY)) { x1 = _fpX; y1 = _fpY; } findPoint(x2, y2); - if (x2 != _fpX || y2 != _fpY) { + if (!getPixelAddr(_roomPathBitmap, _fpX, _fpY)) { + return nullptr; + } + if ((x2 != _fpX) || (y2 != _fpY)) { x2 = _fpX; y2 = _fpY; if (!_flags->getFlagValue(Flags::EXACTMOVE)) { From 7026f687ffea18832cab06b27ea18680afe7435a Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 10 Aug 2014 21:47:35 +0200 Subject: [PATCH 339/374] PRINCE: loadTrans(), drawTransparentWithTransDrawNode() - implementation --- engines/prince/graphics.cpp | 65 ++++++++++++++++++++++++++++++++----- engines/prince/graphics.h | 1 + engines/prince/hero.cpp | 4 +-- engines/prince/prince.cpp | 38 ++++++++++++++++++---- engines/prince/prince.h | 3 ++ 5 files changed, 94 insertions(+), 17 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index bc8c86e65d7f..ab91a550d4d3 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -164,15 +164,62 @@ void GraphicsMan::drawTransparentDrawNode(Graphics::Surface *screen, DrawNode *d byte *dst1 = (byte *)screen->getBasePtr(drawNode->posX, drawNode->posY); for (int y = 0; y < drawNode->s->h; y++) { - byte *src2 = src1; - byte *dst2 = dst1; - for (int x = 0; x < drawNode->s->w; x++, src2++, dst2++) { - if (*src2 != 255) { - if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { - if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { - *dst2 = *src2; - } - } + if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { + byte *src2 = src1; + byte *dst2 = dst1; + for (int x = 0; x < drawNode->s->w; x++, src2++, dst2++) { + if (*src2 != 255) { + if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { + *dst2 = *src2; + } + } + } + } + src1 += drawNode->s->pitch; + dst1 += screen->pitch; + } +} + +void GraphicsMan::drawTransparentWithTransDrawNode(Graphics::Surface *screen, DrawNode *drawNode) { + byte *src1 = (byte *)drawNode->s->getBasePtr(0, 0); + byte *dst1 = (byte *)screen->getBasePtr(drawNode->posX, drawNode->posY); + byte *transTableData = (byte *)drawNode->data; + + for (int y = 0; y < drawNode->s->h; y++) { + if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { + byte *src2 = src1; + byte *dst2 = dst1; + for (int x = 0; x < drawNode->s->w; x++, src2++, dst2++) { + if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { + if (*src2 != 255) { + *dst2 = *src2; + } else if (x) { + if (*(src2 - 1) == 255) { + if (x != drawNode->s->w - 1) { + if (*(src2 + 1) == 255) { + continue; + } + } + } + } else if (*(src2 + 1) == 255) { + continue; + } + byte value = 0; + if (y != drawNode->s->h - 1) { + value = *(src1 + drawNode->s->pitch + x); + if (value == 255) { + if (y) { + value = *(src1 + x); + if (value == 255) { + continue; + } + } else { + continue; + } + } + *dst2 = transTableData[*dst2 * 256 + value]; + } + } } } src1 += drawNode->s->pitch; diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index 83a4aec55c61..d83a43dcd16f 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -49,6 +49,7 @@ class GraphicsMan { void drawTransparentWithBlendSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, int transColor); static void drawTransparentDrawNode(Graphics::Surface *screen, DrawNode *drawNode); + static void drawTransparentWithTransDrawNode(Graphics::Surface *screen, DrawNode *drawNode); static void drawAsShadowDrawNode(Graphics::Surface *screen, DrawNode *drawNode); static void drawMaskDrawNode(Graphics::Surface *screen, DrawNode *drawNode); static void drawBackSpriteDrawNode(Graphics::Surface *screen, DrawNode *drawNode); diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 5b630ae3b673..47aff052d46e 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -892,8 +892,8 @@ void Hero::drawHero() { newDrawNode.width = 0; newDrawNode.height = 0; newDrawNode.originalRoomSurface = nullptr; - newDrawNode.data = nullptr; - newDrawNode.drawFunction = &_graph->drawTransparentDrawNode; + newDrawNode.data = _vm->_transTable; + newDrawNode.drawFunction = &_graph->drawTransparentWithTransDrawNode; if (_zoomFactor) { _zoomedHeroSurface = zoomSprite(mainHeroSurface); diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index bdf33e55a937..2e695d122d98 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -94,7 +94,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _checkBitmapTemp(nullptr), _checkBitmap(nullptr), _checkMask(0), _checkX(0), _checkY(0), _traceLineFirstPointFlag(false), _tracePointFirstPointFlag(false), _coordsBuf2(nullptr), _coords2(nullptr), _coordsBuf3(nullptr), _coords3(nullptr), _shanLen(0), _directionTable(nullptr), _currentMidi(0), _lightX(0), _lightY(0), _curveData(nullptr), _curvPos(0), - _creditsData(nullptr), _creditsDataSize(0), _currentTime(0) { + _creditsData(nullptr), _creditsDataSize(0), _currentTime(0), _zoomBitmap(nullptr), _shadowBitmap(nullptr), _transTable(nullptr) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -191,6 +191,7 @@ PrinceEngine::~PrinceEngine() { free(_zoomBitmap); free(_shadowBitmap); + free(_transTable); free(_curveData); @@ -339,6 +340,7 @@ void PrinceEngine::init() { _zoomBitmap = (byte *)malloc(kZoomBitmapLen); _shadowBitmap = (byte *)malloc(2 * kShadowBitmapSize); + _transTable = (byte *)malloc(kTransTableSize); _curveData = (int16 *)malloc(2 * kCurveLen * sizeof(int16)); @@ -444,6 +446,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { loadZoom(_zoomBitmap, kZoomBitmapLen, "zoom"); loadShadow(_shadowBitmap, kShadowBitmapSize, "shadow", "shadow2"); + loadTrans(_transTable, "trans"); loadPath("path"); for (uint32 i = 0; i < _pscrList.size(); i++) { @@ -832,6 +835,25 @@ bool PrinceEngine::loadShadow(byte *shadowBitmap, uint32 dataSize, const char *r 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) { @@ -1305,8 +1327,8 @@ void PrinceEngine::showSprite(Graphics::Surface *spriteSurface, int destX, int d newDrawNode.height = 0; newDrawNode.s = spriteSurface; newDrawNode.originalRoomSurface = nullptr; - newDrawNode.data = nullptr; - newDrawNode.drawFunction = &_graph->drawTransparentDrawNode; + newDrawNode.data = _transTable; + newDrawNode.drawFunction = &_graph->drawTransparentWithTransDrawNode; _drawNodeList.push_back(newDrawNode); } } @@ -1690,12 +1712,16 @@ void PrinceEngine::showObjects() { newDrawNode.height = 0; newDrawNode.s = objSurface; newDrawNode.originalRoomSurface = nullptr; - newDrawNode.data = nullptr; - if ((_objList[nr]->_flags & 0x2000)) { + newDrawNode.data = nullptr; newDrawNode.drawFunction = &_graph->drawBackSpriteDrawNode; } else { - newDrawNode.drawFunction = &_graph->drawTransparentDrawNode; + newDrawNode.data = _transTable; + if (_flags->getFlagValue(Flags::NOANTIALIAS)) { + newDrawNode.drawFunction = &_graph->drawTransparentDrawNode; + } else { + newDrawNode.drawFunction = &_graph->drawTransparentWithTransDrawNode; + } } _drawNodeList.push_back(newDrawNode); } diff --git a/engines/prince/prince.h b/engines/prince/prince.h index a1e59cc9ae69..d9f86bc91231 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -285,6 +285,7 @@ class PrinceEngine : public Engine { bool loadSample(uint32 sampleSlot, const Common::String &name); bool loadZoom(byte *zoomBitmap, uint32 dataSize, const char *resourceName); bool loadShadow(byte *shadowBitmap, uint32 dataSize, const char *resourceName1, const char *resourceName2); + bool loadTrans(byte *transTable, const char *resourceName); bool loadMobPriority(const char *resourceName); bool loadMusic(int musNumber); @@ -334,6 +335,7 @@ class PrinceEngine : public Engine { uint8 _currentMidi; byte *_zoomBitmap; byte *_shadowBitmap; + byte *_transTable; static const int16 kFPS = 15; @@ -346,6 +348,7 @@ class PrinceEngine : public Engine { static const int16 kZoomBitmapHeight = kMaxPicHeight / kZoomStep; static const int16 kNormalWidth = 640; static const int16 kNormalHeight = 480; + static const int32 kTransTableSize = 256 * 256; static const int kMaxNormAnims = 64; static const int kMaxBackAnims = 64; From c941c5e2fdcc137a72d142261c1ad5df1f0291de Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sun, 10 Aug 2014 22:07:45 +0200 Subject: [PATCH 340/374] PRINCE: Graphics - drawing functions update --- engines/prince/graphics.cpp | 99 +++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 53 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index ab91a550d4d3..f200949ec2b6 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -95,12 +95,12 @@ void GraphicsMan::drawTransparentSurface(Graphics::Surface *screen, int32 posX, byte *src1 = (byte *)s->getBasePtr(0, 0); byte *dst1 = (byte *)screen->getBasePtr(posX, posY); for (int y = 0; y < s->h; y++) { - byte *src2 = src1; - byte *dst2 = dst1; - for (int x = 0; x < s->w; x++, src2++, dst2++) { - if (*src2 != transColor) { - if (x + posX < screen->w && x + posX >= 0) { - if (y + posY < screen->h && y + posY >= 0) { + if (y + posY < screen->h && y + posY >= 0) { + byte *src2 = src1; + byte *dst2 = dst1; + for (int x = 0; x < s->w; x++, src2++, dst2++) { + if (*src2 != transColor) { + if (x + posX < screen->w && x + posX >= 0) { *dst2 = *src2; } } @@ -115,14 +115,13 @@ void GraphicsMan::drawTransparentSurface(Graphics::Surface *screen, int32 posX, void GraphicsMan::drawAsShadowSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, byte *shadowTable) { byte *src1 = (byte *)s->getBasePtr(0, 0); byte *dst1 = (byte *)screen->getBasePtr(posX, posY); - for (int y = 0; y < s->h; y++) { - byte *src2 = src1; - byte *dst2 = dst1; - for (int x = 0; x < s->w; x++, src2++, dst2++) { - if (*src2 == kShadowColor) { - if (x + posX < screen->w && x + posX >= 0) { - if (y + posY < screen->h && y + posY >= 0) { + if (y + posY < screen->h && y + posY >= 0) { + byte *src2 = src1; + byte *dst2 = dst1; + for (int x = 0; x < s->w; x++, src2++, dst2++) { + if (*src2 == kShadowColor) { + if (x + posX < screen->w && x + posX >= 0) { *dst2 = *(shadowTable + *dst2); } } @@ -141,12 +140,12 @@ void GraphicsMan::drawTransparentWithBlendSurface(Graphics::Surface *screen, int blendTable[i] = 255; } for (int y = 0; y < s->h; y++) { - byte *src2 = src1; - byte *dst2 = dst1; - for (int x = 0; x < s->w; x++, src2++, dst2++) { - if (*src2 != transColor) { - if (x + posX < screen->w && x + posX >= 0) { - if (y + posY < screen->h && y + posY >= 0) { + if (y + posY < screen->h && y + posY >= 0) { + byte *src2 = src1; + byte *dst2 = dst1; + for (int x = 0; x < s->w; x++, src2++, dst2++) { + if (*src2 != transColor) { + if (x + posX < screen->w && x + posX >= 0) { *dst2 = getBlendTableColor(*src2, *dst2, blendTable); } } @@ -162,7 +161,6 @@ void GraphicsMan::drawTransparentWithBlendSurface(Graphics::Surface *screen, int void GraphicsMan::drawTransparentDrawNode(Graphics::Surface *screen, DrawNode *drawNode) { byte *src1 = (byte *)drawNode->s->getBasePtr(0, 0); byte *dst1 = (byte *)screen->getBasePtr(drawNode->posX, drawNode->posY); - for (int y = 0; y < drawNode->s->h; y++) { if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { byte *src2 = src1; @@ -184,7 +182,6 @@ void GraphicsMan::drawTransparentWithTransDrawNode(Graphics::Surface *screen, Dr byte *src1 = (byte *)drawNode->s->getBasePtr(0, 0); byte *dst1 = (byte *)screen->getBasePtr(drawNode->posX, drawNode->posY); byte *transTableData = (byte *)drawNode->data; - for (int y = 0; y < drawNode->s->h; y++) { if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { byte *src2 = src1; @@ -234,24 +231,22 @@ void GraphicsMan::drawMaskDrawNode(Graphics::Surface *screen, DrawNode *drawNode int maskWidth = drawNode->width >> 3; int maskPostion = 0; int maskCounter = 128; - for (int y = 0; y < drawNode->height; y++) { - byte *src2 = src1; - byte *dst2 = dst1; - int tempMaskPostion = maskPostion; - for (int x = 0; x < drawNode->width; x++, src2++, dst2++) { - if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { - if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { + if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { + byte *src2 = src1; + byte *dst2 = dst1; + int tempMaskPostion = maskPostion; + for (int x = 0; x < drawNode->width; x++, src2++, dst2++) { + if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { if ((maskData[tempMaskPostion] & maskCounter) != 0) { *dst2 = *src2; - //*dst2 = 0; // for debugging } } - } - maskCounter >>= 1; - if (maskCounter == 0) { - maskCounter = 128; - tempMaskPostion++; + maskCounter >>= 1; + if (maskCounter == 0) { + maskCounter = 128; + tempMaskPostion++; + } } } src1 += drawNode->originalRoomSurface->pitch; @@ -265,14 +260,13 @@ void GraphicsMan::drawAsShadowDrawNode(Graphics::Surface *screen, DrawNode *draw byte *shadowData = (byte *)drawNode->data; byte *src1 = (byte *)drawNode->s->getBasePtr(0, 0); byte *dst1 = (byte *)screen->getBasePtr(drawNode->posX, drawNode->posY); - for (int y = 0; y < drawNode->s->h; y++) { - byte *src2 = src1; - byte *dst2 = dst1; - for (int x = 0; x < drawNode->s->w; x++, src2++, dst2++) { - if (*src2 == kShadowColor) { - if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { - if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { + if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { + byte *src2 = src1; + byte *dst2 = dst1; + for (int x = 0; x < drawNode->s->w; x++, src2++, dst2++) { + if (*src2 == kShadowColor) { + if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { *dst2 = *(shadowData + *dst2); } } @@ -286,19 +280,18 @@ void GraphicsMan::drawAsShadowDrawNode(Graphics::Surface *screen, DrawNode *draw void GraphicsMan::drawBackSpriteDrawNode(Graphics::Surface *screen, DrawNode *drawNode) { byte *src1 = (byte *)drawNode->s->getBasePtr(0, 0); byte *dst1 = (byte *)screen->getBasePtr(drawNode->posX, drawNode->posY); - for (int y = 0; y < drawNode->s->h; y++) { - byte *src2 = src1; - byte *dst2 = dst1; - for (int x = 0; x < drawNode->s->w; x++, src2++, dst2++) { - if (*src2 != 255) { - if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { - if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { - if (*dst2 == 255) { - *dst2 = *src2; - } - } - } + if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { + byte *src2 = src1; + byte *dst2 = dst1; + for (int x = 0; x < drawNode->s->w; x++, src2++, dst2++) { + if (*src2 != 255) { + if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { + if (*dst2 == 255) { + *dst2 = *src2; + } + } + } } } src1 += drawNode->s->pitch; From 6471a354f4f8a42876f9f9b7d44de50dca31a9f6 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 11 Aug 2014 00:40:32 +0200 Subject: [PATCH 341/374] PRINCE: drawTransparent functions - update --- engines/prince/graphics.cpp | 9 +++++---- engines/prince/graphics.h | 4 ++-- engines/prince/prince.cpp | 16 ++++++++-------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index f200949ec2b6..bb6d7f72921b 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -91,7 +91,8 @@ void GraphicsMan::draw(Graphics::Surface *screen, const Graphics::Surface *s) { change(); } -void GraphicsMan::drawTransparentSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, int transColor) { +// Black (value = 0) as a primary transparent color, fix for FLC animations +void GraphicsMan::drawTransparentSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, int secondTransColor) { byte *src1 = (byte *)s->getBasePtr(0, 0); byte *dst1 = (byte *)screen->getBasePtr(posX, posY); for (int y = 0; y < s->h; y++) { @@ -99,7 +100,7 @@ void GraphicsMan::drawTransparentSurface(Graphics::Surface *screen, int32 posX, byte *src2 = src1; byte *dst2 = dst1; for (int x = 0; x < s->w; x++, src2++, dst2++) { - if (*src2 != transColor) { + if (*src2 && *src2 != secondTransColor) { if (x + posX < screen->w && x + posX >= 0) { *dst2 = *src2; } @@ -132,7 +133,7 @@ void GraphicsMan::drawAsShadowSurface(Graphics::Surface *screen, int32 posX, int } } -void GraphicsMan::drawTransparentWithBlendSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, int transColor) { +void GraphicsMan::drawTransparentWithBlendSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s) { byte *src1 = (byte *)s->getBasePtr(0, 0); byte *dst1 = (byte *)screen->getBasePtr(posX, posY); byte *blendTable = (byte *)malloc(256); @@ -144,7 +145,7 @@ void GraphicsMan::drawTransparentWithBlendSurface(Graphics::Surface *screen, int byte *src2 = src1; byte *dst2 = dst1; for (int x = 0; x < s->w; x++, src2++, dst2++) { - if (*src2 != transColor) { + if (*src2) { if (x + posX < screen->w && x + posX >= 0) { *dst2 = getBlendTableColor(*src2, *dst2, blendTable); } diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index d83a43dcd16f..b6f002b7da56 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -44,9 +44,9 @@ class GraphicsMan { void makeShadowTable(int brightness, byte *shadowTable); void draw(Graphics::Surface *screen, const Graphics::Surface *s); - void drawTransparentSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, int transColor); + void drawTransparentSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, int secondTransColor = 0); void drawAsShadowSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, byte *shadowTable); - void drawTransparentWithBlendSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, int transColor); + void drawTransparentWithBlendSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s); static void drawTransparentDrawNode(Graphics::Surface *screen, DrawNode *drawNode); static void drawTransparentWithTransDrawNode(Graphics::Surface *screen, DrawNode *drawNode); diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 2e695d122d98..6659ec743e56 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1996,7 +1996,7 @@ void PrinceEngine::addInvObj() { while (_mst_shadow2 < 512) { rememberScreenInv(); - _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase, 0); + _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase); drawInvItems(); _graph->update(_graph->_screenForInventory); _mst_shadow2 += 50; @@ -2010,7 +2010,7 @@ void PrinceEngine::addInvObj() { } while (_mst_shadow2 > 256) { rememberScreenInv(); - _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase, 0); + _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase); drawInvItems(); _graph->update(_graph->_screenForInventory); _mst_shadow2 -= 42; @@ -2028,7 +2028,7 @@ void PrinceEngine::addInvObj() { _mst_shadow2 = 256; while (_mst_shadow2 < 512) { rememberScreenInv(); - _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase, 0); + _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase); drawInvItems(); _graph->update(_graph->_screenForInventory); _mst_shadow2 += 50; @@ -2042,7 +2042,7 @@ void PrinceEngine::addInvObj() { } while (_mst_shadow2 > 256) { rememberScreenInv(); - _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase, 0); + _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase); drawInvItems(); _graph->update(_graph->_screenForInventory); _mst_shadow2 -= 50; @@ -2059,7 +2059,7 @@ void PrinceEngine::addInvObj() { _mst_shadow2 = 0; for (int i = 0; i < 20; i++) { rememberScreenInv(); - _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase, 0); + _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase); drawInvItems(); _graph->update(_graph->_screenForInventory); Common::Event event; @@ -2182,10 +2182,10 @@ void PrinceEngine::drawInvItems() { drawX += (_maxInvW - itemSurface->w) / 2; } if (!_mst_shadow) { - _graph->drawTransparentSurface(_graph->_screenForInventory, drawX, drawY, itemSurface, 0); + _graph->drawTransparentSurface(_graph->_screenForInventory, drawX, drawY, itemSurface); } else { _mst_shadow = _mst_shadow2; - _graph->drawTransparentWithBlendSurface(_graph->_screenForInventory, drawX, drawY, itemSurface, 0); + _graph->drawTransparentWithBlendSurface(_graph->_screenForInventory, drawX, drawY, itemSurface); } } currInvX += _invLineW + _invLineSkipX; @@ -2652,7 +2652,7 @@ void PrinceEngine::displayInventory() { rememberScreenInv(); Graphics::Surface *suitcase = _suitcaseBmp->getSurface(); - _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase, 0); + _graph->drawTransparentSurface(_graph->_screenForInventory, 0, 0, suitcase); drawInvItems(); From b31500343962a1b8b0d79db566fa08419db1bb2d Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 12 Aug 2014 20:26:03 +0200 Subject: [PATCH 342/374] PRINCE: Graphics::drawTransparentWithTrans fix --- engines/prince/graphics.cpp | 39 ++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index bb6d7f72921b..d70591d2ccaf 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -191,27 +191,34 @@ void GraphicsMan::drawTransparentWithTransDrawNode(Graphics::Surface *screen, Dr if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { if (*src2 != 255) { *dst2 = *src2; - } else if (x) { - if (*(src2 - 1) == 255) { - if (x != drawNode->s->w - 1) { - if (*(src2 + 1) == 255) { - continue; + } else { + if (x) { + if (*(src2 - 1) == 255) { + if (x != drawNode->s->w - 1) { + if (*(src2 + 1) == 255) { + continue; + } } } + } else if (*(src2 + 1) == 255) { + continue; } - } else if (*(src2 + 1) == 255) { - continue; - } - byte value = 0; - if (y != drawNode->s->h - 1) { - value = *(src1 + drawNode->s->pitch + x); - if (value == 255) { - if (y) { - value = *(src1 + x); - if (value == 255) { + byte value = 0; + if (y != drawNode->s->h - 1) { + value = *(src2 + drawNode->s->pitch); + if (value == 255) { + if (y) { + value = *(src2 - drawNode->s->pitch); + if (value == 255) { + continue; + } + } else { continue; } - } else { + } + } else { + value = *(src2 - drawNode->s->pitch); + if (value == 255) { continue; } } From 13541465482612387e789d84c4e3d96a2ee0fbdd Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 14 Aug 2014 04:41:58 +0200 Subject: [PATCH 343/374] PRINCE: showHeroShadow - left side clipping fix --- engines/prince/hero.cpp | 251 ++++++++++++++++++++------------------ engines/prince/prince.cpp | 2 +- 2 files changed, 131 insertions(+), 122 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 47aff052d46e..496099251f27 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -240,8 +240,7 @@ static void plot(int x, int y, int color, void *data) { shadowLine->_shadLineLen++; } -// FIXME - shadows are badly cutted off in left down corner of locations 7, 12 -// and horizontal line with wrong colors in the middle of shadow appears in loc. 12, 23 +// FIXME - horizontal line with wrong colors in the middle of shadow appears in loc. 12, 23 void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { Hero *heroData = (Hero *)drawNode->data; int16 heroSurfaceWidth = drawNode->s->w; @@ -324,7 +323,6 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { if (shadowHeroY < 0) { break; } - shadowHero = (byte *)makeShadow->getBasePtr(shadowHeroX, shadowHeroY); } else { break; } @@ -335,157 +333,169 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { if (shadowHeroY < 0) { break; } + + bool skipLineFlag = false; //line_y_ok if (shadLastY != shadPosY && shadPosY >= 0 && shadPosY < 480 && shadPosX < 640) { shadLastY = shadPosY; if (shadPosX < 0) { shadSkipX = -1 * shadPosX; - background += shadSkipX; if (heroSurfaceWidth > shadSkipX) { - shadowHero += shadSkipX; - shadBitAddr += shadSkipX / 8; - if ((shadSkipX % 8) != 0) { - //loop_rotate: - for (int a = 0; a < (shadSkipX % 8); a++) { - if (shadBitMask == 1) { - shadBitMask = 128; - shadBitAddr++; - } else { - shadBitMask >>= 1; - } - } - } + ct_loop = heroSurfaceWidth - shadSkipX; + shadowHeroX = shadSkipX; } else { //skip_line - //test it + skipLineFlag = true; } } else { //x1_ok if (shadPosX + heroSurfaceWidth > 640) { - ct_loop = 640 - shadPosX; // test it + ct_loop = 640 - shadPosX; sprModulo = shadPosX + heroSurfaceWidth - 640; } else { //draw_line ct_loop = heroSurfaceWidth; } } - //draw_line1 - //retry_line2 - int k; - for (k = j; k > 0; k--) { - shadZoomY2 -= 100; - if (shadZoomY2 < 0 && heroData->_shadScaleValue != 10000) { - shadZoomY2 += heroData->_shadScaleValue; - shadowHeroY--; - if (shadowHeroY < 0) { + + if (!skipLineFlag) { + //draw_line1 + //retry_line2 + int k; + for (k = j; k > 0; k--) { + shadZoomY2 -= 100; + if (shadZoomY2 < 0 && heroData->_shadScaleValue != 10000) { + shadZoomY2 += heroData->_shadScaleValue; + shadowHeroY--; + if (shadowHeroY < 0) { + break; + } + } else { break; } - shadowHero = (byte *)makeShadow->getBasePtr(shadowHeroX, shadowHeroY); - } else { + } + if (shadowHeroY < 0) { break; } - } - if (shadowHeroY < 0) { - break; - } - if (k == 0) { - break; - } - //line_y_ok_2: - //copy_trans - bool shadWDFlag = false; - int shadZoomX = heroData->_scaleValue; - int backgroundDiff = 0; - int shadBitMaskCopyTrans = shadBitMask; - int shadBitAddrCopyTrans = shadBitAddr; - //ct_loop: - for (int l = 0; l < ct_loop; l++) { - shadZoomX -= 100; - if (shadZoomX < 0 && heroData->_scaleValue != 10000) { - shadZoomX += heroData->_scaleValue; - } else { - if (*shadowHero == GraphicsMan::kShadowColor) { - if ((shadBitMaskCopyTrans & heroData->_vm->_shadowBitmap[shadBitAddrCopyTrans]) != 0) { - if (shadWallDown == 0) { - if ((shadBitMaskCopyTrans & heroData->_vm->_shadowBitmap[shadBitAddrCopyTrans + heroData->_vm->kShadowBitmapSize]) != 0) { - shadWDFlag = true; - //shadow - *background = *(sprShadow + *background); + if (k == 0) { + break; + } + //line_y_ok_2: + //copy_trans + bool shadWDFlag = false; + int shadZoomX = heroData->_scaleValue; + int backgroundDiff = shadSkipX; + int shadBitMaskCopyTrans = shadBitMask; + int shadBitAddrCopyTrans = shadBitAddr; + shadowHero = (byte *)makeShadow->getBasePtr(shadowHeroX, shadowHeroY); + background = (byte *)screen->getBasePtr(heroData->_shadDrawX + diffX + backgroundDiff, heroData->_shadDrawY + diffY); + + if (shadPosX < 0) { + if (heroSurfaceWidth > shadSkipX) { + shadBitAddrCopyTrans += shadSkipX / 8; + if ((shadSkipX % 8)) { + //loop_rotate: + for (int a = 0; a < (shadSkipX % 8); a++) { + if (shadBitMaskCopyTrans == 1) { + shadBitMaskCopyTrans = 128; + shadBitAddrCopyTrans++; + } else { + shadBitMaskCopyTrans >>= 1; } } - } else { - //shadow - *background = *(sprShadow + *background); } } - //ct_next - if (shadBitMaskCopyTrans == 1) { - shadBitMaskCopyTrans = 128; - shadBitAddrCopyTrans++; - } else { - shadBitMaskCopyTrans >>= 1; - } - //okok - backgroundDiff++; - background = (byte *)screen->getBasePtr(heroData->_shadDrawX + diffX + backgroundDiff, heroData->_shadDrawY + diffY); } - shadowHeroX++; - shadowHero = (byte *)makeShadow->getBasePtr(shadowHeroX, shadowHeroY); - } - //byebyebye - if (!shadWallDown && shadWDFlag) { - shadWallDown = shadPosX; - shadWallBitAddr = shadBitAddr; - shadWallDestAddr = (byte *)screen->getBasePtr(heroData->_shadDrawX + diffX, heroData->_shadDrawY + diffY); - shadWallBitMask = shadBitMask; - shadWallPosY = shadPosY; - shadWallSkipX = shadSkipX; - shadWallModulo = sprModulo; - } - //byebye - if (shadDirection != 0 && shadWallDown != 0) { - int shadBitMaskWallCopyTrans = shadWallBitMask; - int shadBitAddrWallCopyTrans = shadWallBitAddr; - background = shadWallDestAddr; - shadowHero = (byte *)makeShadow->getBasePtr(shadWallSkipX, shadowHeroY); - - if (ct_loop > shadWallSkipX && ct_loop - shadWallSkipX > shadWallModulo) { - //WALL_copy_trans - shadWDFlag = false; - int shadZoomXWall = heroData->_scaleValue; - int backgroundDiffWall = 0; - int shadowHeroXWall = 0; - //ct_loop: - for (int m = 0; m < ct_loop; m++) { - shadZoomXWall -= 100; - if (shadZoomXWall < 0 && heroData->_scaleValue != 10000) { - shadZoomXWall += heroData->_scaleValue; - } else { - //point_ok: - if (*shadowHero == GraphicsMan::kShadowColor) { - if ((shadBitMaskWallCopyTrans & heroData->_vm->_shadowBitmap[shadBitAddrWallCopyTrans + heroData->_vm->kShadowBitmapSize]) != 0) { - *background = *(sprShadow + *background); + + //ct_loop: + for (int l = 0; l < ct_loop; l++) { + shadZoomX -= 100; + if (shadZoomX < 0 && heroData->_scaleValue != 10000) { + shadZoomX += heroData->_scaleValue; + } else { + if (*shadowHero == GraphicsMan::kShadowColor) { + if ((shadBitMaskCopyTrans & heroData->_vm->_shadowBitmap[shadBitAddrCopyTrans]) != 0) { + if (shadWallDown == 0) { + if ((shadBitMaskCopyTrans & heroData->_vm->_shadowBitmap[shadBitAddrCopyTrans + heroData->_vm->kShadowBitmapSize]) != 0) { + shadWDFlag = true; + //shadow + *background = *(sprShadow + *background); + } } + } else { + //shadow + *background = *(sprShadow + *background); } - //ct_next - if (shadBitMaskWallCopyTrans == 1) { - shadBitMaskWallCopyTrans = 128; - shadBitAddrWallCopyTrans++; + } + //ct_next + if (shadBitMaskCopyTrans == 1) { + shadBitMaskCopyTrans = 128; + shadBitAddrCopyTrans++; + } else { + shadBitMaskCopyTrans >>= 1; + } + //okok + backgroundDiff++; + background = (byte *)screen->getBasePtr(heroData->_shadDrawX + diffX + backgroundDiff, heroData->_shadDrawY + diffY); + } + shadowHeroX++; + shadowHero = (byte *)makeShadow->getBasePtr(shadowHeroX, shadowHeroY); + } + //byebyebye + if (!shadWallDown && shadWDFlag) { + shadWallDown = shadPosX; + shadWallBitAddr = shadBitAddr; + shadWallDestAddr = (byte *)screen->getBasePtr(heroData->_shadDrawX + diffX, heroData->_shadDrawY + diffY); + shadWallBitMask = shadBitMask; + shadWallPosY = shadPosY; + shadWallSkipX = shadSkipX; + shadWallModulo = sprModulo; + } + //byebye + if (shadDirection != 0 && shadWallDown != 0) { + int shadBitMaskWallCopyTrans = shadWallBitMask; + int shadBitAddrWallCopyTrans = shadWallBitAddr; + background = shadWallDestAddr; + shadowHero = (byte *)makeShadow->getBasePtr(shadWallSkipX, shadowHeroY); + + if (ct_loop > shadWallSkipX && ct_loop - shadWallSkipX > shadWallModulo) { + //WALL_copy_trans + shadWDFlag = false; + int shadZoomXWall = heroData->_scaleValue; + int backgroundDiffWall = 0; + int shadowHeroXWall = 0; + //ct_loop: + for (int m = 0; m < ct_loop; m++) { + shadZoomXWall -= 100; + if (shadZoomXWall < 0 && heroData->_scaleValue != 10000) { + shadZoomXWall += heroData->_scaleValue; } else { - shadBitMaskWallCopyTrans >>= 1; + //point_ok: + if (*shadowHero == GraphicsMan::kShadowColor) { + if ((shadBitMaskWallCopyTrans & heroData->_vm->_shadowBitmap[shadBitAddrWallCopyTrans + heroData->_vm->kShadowBitmapSize]) != 0) { + *background = *(sprShadow + *background); + } + } + //ct_next + if (shadBitMaskWallCopyTrans == 1) { + shadBitMaskWallCopyTrans = 128; + shadBitAddrWallCopyTrans++; + } else { + shadBitMaskWallCopyTrans >>= 1; + } + //okok + backgroundDiffWall++; + background = shadWallDestAddr + backgroundDiffWall; } - //okok - backgroundDiffWall++; - background = shadWallDestAddr + backgroundDiffWall; + shadowHeroXWall++; + shadowHero = (byte *)makeShadow->getBasePtr(shadWallSkipX + shadowHeroXWall, shadowHeroY); } - shadowHeroXWall++; - shadowHero = (byte *)makeShadow->getBasePtr(shadWallSkipX + shadowHeroXWall, shadowHeroY); } + //krap2 + shadWallDestAddr -= PrinceEngine::kNormalWidth; + shadWallBitAddr -= PrinceEngine::kMaxPicWidth / 8; + shadWallPosY--; } - //krap2 - shadWallDestAddr -= PrinceEngine::kNormalWidth; - shadWallBitAddr -= PrinceEngine::kMaxPicWidth / 8; - shadWallPosY--; } } //skip_line @@ -968,7 +978,6 @@ void Hero::heroMoveGotIt(int x, int y, int dir) { } } -//TODO - test this void Hero::scrollHero() { int scrollType = _vm->_flags->getFlagValue(Flags::SCROLLTYPE); int position = _middleX; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 6659ec743e56..9517b02691f8 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -318,7 +318,7 @@ void PrinceEngine::init() { _roomPathBitmapTemp = (byte *)malloc(kPathBitmapLen); _coordsBuf = (byte *)malloc(kTracePts * 4); _coords = _coordsBuf; - _coordsBufEnd = _coordsBuf + kTracePts * 4 - 4; // TODO - test this + _coordsBufEnd = _coordsBuf + kTracePts * 4 - 4; BackgroundAnim tempBackAnim; tempBackAnim._seq._currRelative = 0; From 89bda02eb111d0aefb8a81115b0986eff07321ed Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 15 Aug 2014 20:32:32 +0200 Subject: [PATCH 344/374] PRINCE: showHeroShadow - shadowLine data reading fix --- engines/prince/hero.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 496099251f27..e2d63c5e5d96 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -240,7 +240,6 @@ static void plot(int x, int y, int color, void *data) { shadowLine->_shadLineLen++; } -// FIXME - horizontal line with wrong colors in the middle of shadow appears in loc. 12, 23 void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { Hero *heroData = (Hero *)drawNode->data; int16 heroSurfaceWidth = drawNode->s->w; @@ -500,18 +499,18 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { } //skip_line //next_line - if (*(shadowLineStart + 2) < *(shadowLineStart - 2)) { + if (READ_UINT16(shadowLineStart + 2) < READ_UINT16(shadowLineStart - 2)) { //minus_y shadBitAddr -= PrinceEngine::kMaxPicWidth / 8; shadPosY--; diffY--; - } else if (*(shadowLineStart + 2) > *(shadowLineStart - 2)) { + } else if (READ_UINT16(shadowLineStart + 2) > READ_UINT16(shadowLineStart - 2)) { shadBitAddr += PrinceEngine::kMaxPicWidth / 8; shadPosY++; diffY++; } //no_change_y - if (*shadowLineStart < *(shadowLineStart - 4)) { + if (READ_UINT16(shadowLineStart) < READ_UINT16(shadowLineStart - 4)) { //minus_x shadPosX--; //rol @@ -522,7 +521,7 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { shadBitMask <<= 1; } diffX--; - } else if (*shadowLineStart > *(shadowLineStart - 4)) { + } else if (READ_UINT16(shadowLineStart) > READ_UINT16(shadowLineStart - 4)) { shadPosX++; //ror if (shadBitMask == 1) { From 40ac742169db49e16756092f6e9bd28b23b8d7e3 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 15 Aug 2014 21:04:55 +0200 Subject: [PATCH 345/374] PRINCE: initZoomIn() update --- engines/prince/prince.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 9517b02691f8..cfd1e7762882 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -1576,6 +1576,7 @@ void PrinceEngine::initZoomIn(int slot) { 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; } } From 9ef705ebb46c93dea4da42ea63d42b34b395ae89 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 15 Aug 2014 21:57:26 +0200 Subject: [PATCH 346/374] PRINCE: playNextFLCFrame() update --- engines/prince/prince.cpp | 15 ++++++++++----- engines/prince/prince.h | 3 ++- engines/prince/script.cpp | 3 ++- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index cfd1e7762882..634ac2ccf69d 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -94,7 +94,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _checkBitmapTemp(nullptr), _checkBitmap(nullptr), _checkMask(0), _checkX(0), _checkY(0), _traceLineFirstPointFlag(false), _tracePointFirstPointFlag(false), _coordsBuf2(nullptr), _coords2(nullptr), _coordsBuf3(nullptr), _coords3(nullptr), _shanLen(0), _directionTable(nullptr), _currentMidi(0), _lightX(0), _lightY(0), _curveData(nullptr), _curvPos(0), - _creditsData(nullptr), _creditsDataSize(0), _currentTime(0), _zoomBitmap(nullptr), _shadowBitmap(nullptr), _transTable(nullptr) { + _creditsData(nullptr), _creditsDataSize(0), _currentTime(0), _zoomBitmap(nullptr), _shadowBitmap(nullptr), _transTable(nullptr), + _flcFrameSurface(nullptr) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -626,7 +627,7 @@ void PrinceEngine::stopMusic() { } } -bool PrinceEngine::playNextFrame() { +bool PrinceEngine::playNextFLCFrame() { if (!_flicPlayer.isVideoLoaded()) return false; @@ -634,9 +635,13 @@ bool PrinceEngine::playNextFrame() { if (s) { _graph->drawTransparentSurface(_graph->_frontScreen, 0, 0, s, 255); _graph->change(); + _flcFrameSurface = s; } else if (_flicLooped) { _flicPlayer.rewind(); - playNextFrame(); + playNextFLCFrame(); + } else if (_flcFrameSurface) { + _graph->drawTransparentSurface(_graph->_frontScreen, 0, 0, _flcFrameSurface, 255); + _graph->change(); } return true; @@ -783,7 +788,7 @@ bool PrinceEngine::loadAnim(uint16 animNr, bool loop) { debugEngine("%s loaded", streamName.c_str()); _flicLooped = loop; _flicPlayer.start(); - playNextFrame(); + playNextFLCFrame(); return true; } @@ -1796,7 +1801,7 @@ void PrinceEngine::drawScreen() { showNormAnims(); - playNextFrame(); + playNextFLCFrame(); showObjects(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index d9f86bc91231..7e4592ad5414 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -274,6 +274,7 @@ class PrinceEngine : public Engine { const PrinceGameDescription *_gameDescription; Video::FlicDecoder _flicPlayer; + const Graphics::Surface *_flcFrameSurface; VariaTxt *_variaTxt; uint32 _talkTxtSize; @@ -596,7 +597,7 @@ class PrinceEngine : public Engine { int checkRightUpDir(); private: - bool playNextFrame(); + bool playNextFLCFrame(); void keyHandler(Common::Event event); int checkMob(Graphics::Surface *screen, Common::Array &mobList, bool usePriorityList); void drawScreen(); diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 9dabebfb5eae..582864d0c384 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -1723,6 +1723,7 @@ void Interpreter::O_SETBACKANIMDATA() { void Interpreter::O_VIEWFLC() { int32 animNr = readScriptFlagValue(); + _vm->_flcFrameSurface = nullptr; _vm->loadAnim(animNr, false); debugInterpreter("O_VIEWFLC animNr %d", animNr); } @@ -1745,8 +1746,8 @@ void Interpreter::O_CHECKFLCEND() { } } -// TODO void Interpreter::O_FREEFLC() { + _vm->_flcFrameSurface = nullptr; debugInterpreter("O_FREEFLC"); } From 422054f81cdcdd3f962afd8f777e83458b3f4588 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 15 Aug 2014 21:59:24 +0200 Subject: [PATCH 347/374] PRINCE: init() - delete creditsDataStream --- engines/prince/prince.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 634ac2ccf69d..080085b3235a 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -353,6 +353,7 @@ void PrinceEngine::init() { _creditsDataSize = creditsDataStream->size(); _creditsData = (byte *)malloc(_creditsDataSize); creditsDataStream->read(_creditsData, _creditsDataSize); + delete creditsDataStream; } void PrinceEngine::showLogo() { From 9bda7c37c376a7c925a4b44184dddc952813c2d5 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 16 Aug 2014 22:54:38 +0200 Subject: [PATCH 348/374] PRINCE: Shadows drawing - update --- engines/prince/hero.cpp | 131 +++++++++++++++----------------------- engines/prince/hero.h | 13 +--- engines/prince/prince.cpp | 95 +++++++++++++++++---------- engines/prince/prince.h | 16 ++++- 4 files changed, 128 insertions(+), 127 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index e2d63c5e5d96..ff4be1aefcda 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -38,20 +38,14 @@ Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph), _number(0), _visible(false), _state(kHeroStateStay), _middleX(0), _middleY(0), _boreNum(1), _currHeight(0), _moveDelay(0), _shadMinus(0), _moveSetType(0), _zoomedHeroSurface(nullptr), _lastDirection(kHeroDirDown), _destDirection(kHeroDirDown), _talkTime(0), _boredomTime(0), _phase(0), - _specAnim(nullptr), _drawX(0), _drawY(0), _drawZ(0), _zoomFactor(0), _scaleValue(0), - _shadZoomFactor(0), _shadScaleValue(0), _shadLineLen(0), _shadDrawX(0), _shadDrawY(0), + _specAnim(nullptr), _drawX(0), _drawY(0), _drawZ(0), _frameXSize(0), _frameYSize(0), _scaledFrameXSize(0), _scaledFrameYSize(0), _color(0), _coords(nullptr), _dirTab(nullptr), _currCoords(nullptr), _currDirTab(nullptr), _step(0), _maxBoredom(200), _leftRightMainDir(0), _upDownMainDir(0), _animSetNr(0) { - _shadowLine = (byte *)malloc(kShadowLineArraySize); } Hero::~Hero() { - if (_shadowLine != nullptr) { - free(_shadowLine); - _shadowLine = nullptr; - } freeHeroAnim(); freeOldMove(); freeZoomedSurface(); @@ -116,14 +110,14 @@ uint16 Hero::getData(AttrId dataId) { int Hero::getScaledValue(int size) { int newSize = 0; - int16 initScaleValue = _scaleValue; - if (_scaleValue != 10000) { - for(int i = 0; i < size; i++) { + int16 initScaleValue = _vm->_scaleValue; + if (_vm->_scaleValue != 10000) { + for (int i = 0; i < size; i++) { initScaleValue -= 100; - if(initScaleValue >= 0) { + if (initScaleValue >= 0) { newSize++; } else { - initScaleValue += _scaleValue; + initScaleValue += _vm->_scaleValue; } } return newSize; @@ -137,7 +131,7 @@ Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) { zoomedFrame->create(_scaledFrameXSize, _scaledFrameYSize, Graphics::PixelFormat::createFormatCLUT8()); int sprZoomX; - int sprZoomY = _scaleValue; + int sprZoomY = _vm->_scaleValue; uint xSource = 0; uint ySource = 0; uint xDest = 0; @@ -147,12 +141,12 @@ Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) { // linear_loop: while (1) { sprZoomY -= 100; - if (sprZoomY >= 0 || _scaleValue == 10000) { + if (sprZoomY >= 0 || _vm->_scaleValue == 10000) { // all_r_y - sprZoomX = _scaleValue; + sprZoomX = _vm->_scaleValue; break; // to loop_lin } else { - sprZoomY += _scaleValue; + sprZoomY += _vm->_scaleValue; xSource = 0; ySource++; } @@ -165,7 +159,7 @@ Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) { memcpy(zoomedFrame->getBasePtr(xDest, yDest), heroFrame->getBasePtr(xSource, ySource), 1); xDest++; } else { - sprZoomX += _scaleValue; + sprZoomX += _vm->_scaleValue; j--; } xSource++; @@ -213,7 +207,7 @@ void Hero::countDrawPosition() { //int diffY = heroAnim->getIdYDiff(); } - if (_zoomFactor != 0) { + if (_vm->_scaleValue != 10000) { //notfullSize _drawX = _middleX - _scaledFrameXSize / 2; _drawY = tempMiddleY + 1 - _scaledFrameYSize; @@ -229,19 +223,8 @@ void Hero::countDrawPosition() { } } -void Hero::plotPoint(int x, int y) { - WRITE_UINT16(&_shadowLine[_shadLineLen * 4], x); - WRITE_UINT16(&_shadowLine[_shadLineLen * 4 + 2], y); -} - -static void plot(int x, int y, int color, void *data) { - Hero *shadowLine = (Hero *)data; - shadowLine->plotPoint(x, y); - shadowLine->_shadLineLen++; -} - void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { - Hero *heroData = (Hero *)drawNode->data; + PrinceEngine *vm = (PrinceEngine *)drawNode->data; int16 heroSurfaceWidth = drawNode->s->w; int16 heroSurfaceHeight = drawNode->s->h; @@ -262,27 +245,27 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { if (drawNode->posY > 1 && drawNode->posY < PrinceEngine::kMaxPicHeight) { int shadDirection; - if (heroData->_vm->_lightY > drawNode->posY) { + if (vm->_lightY > drawNode->posY) { shadDirection = 1; } else { shadDirection = 0; } - heroData->_shadLineLen = 0; - Graphics::drawLine(heroData->_vm->_lightX, heroData->_vm->_lightY, drawNode->posX, drawNode->posY, 0, &plot, heroData); + vm->_shadLineLen = 0; + Graphics::drawLine(vm->_lightX, vm->_lightY, drawNode->posX, drawNode->posY, 0, &vm->plotShadowLinePoint, vm); - byte *sprShadow = (byte *)heroData->_graph->_shadowTable70; + byte *sprShadow = vm->_graph->_shadowTable70; - heroData->_shadDrawX = drawNode->posX - heroData->_vm->_picWindowX; - heroData->_shadDrawY = drawNode->posY - heroData->_vm->_picWindowY; + int shadDrawX = drawNode->posX - vm->_picWindowX; + int shadDrawY = drawNode->posY - vm->_picWindowY; - int shadPosX = heroData->_shadDrawX; - int shadPosY = heroData->_shadDrawY; + int shadPosX = shadDrawX; + int shadPosY = shadDrawY; int shadBitAddr = drawNode->posY * PrinceEngine::kMaxPicWidth / 8 + drawNode->posX / 8; int shadBitMask = 128 >> (drawNode->posX % 8); - int shadZoomY2 = heroData->_shadScaleValue; - int shadZoomY = heroData->_scaleValue; + int shadZoomY2 = vm->_shadScaleValue; + int shadZoomY = drawNode->scaleValue; int diffX = 0; int diffY = 0; @@ -293,10 +276,10 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { int shadLastY = 0; byte *shadowHero = (byte *)makeShadow->getBasePtr(shadowHeroX, shadowHeroY); // first pixel from last row of shadow hero - byte *background = (byte *)screen->getBasePtr(heroData->_shadDrawX, heroData->_shadDrawY); // pixel of background where shadow sprite starts + byte *background = (byte *)screen->getBasePtr(shadDrawX, shadDrawY); // pixel of background where shadow sprite starts // banked2 - byte *shadowLineStart = heroData->_shadowLine + 8; + byte *shadowLineStart = vm->_shadowLine + 8; int shadWallDown = 0; int shadWallBitAddr = 0; @@ -316,8 +299,8 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { //retry_line: for (j = heroSurfaceHeight - i; j > 0; j--) { shadZoomY -= 100; - if (shadZoomY < 0 && heroData->_scaleValue != 10000) { - shadZoomY += heroData->_scaleValue; + if (shadZoomY < 0 && drawNode->scaleValue != 10000) { + shadZoomY += drawNode->scaleValue; shadowHeroY--; if (shadowHeroY < 0) { break; @@ -326,7 +309,7 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { break; } } - if (j == 0) { + if (!j) { break; } if (shadowHeroY < 0) { @@ -363,8 +346,8 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { int k; for (k = j; k > 0; k--) { shadZoomY2 -= 100; - if (shadZoomY2 < 0 && heroData->_shadScaleValue != 10000) { - shadZoomY2 += heroData->_shadScaleValue; + if (shadZoomY2 < 0 && vm->_shadScaleValue != 10000) { + shadZoomY2 += vm->_shadScaleValue; shadowHeroY--; if (shadowHeroY < 0) { break; @@ -376,18 +359,18 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { if (shadowHeroY < 0) { break; } - if (k == 0) { + if (!k) { break; } //line_y_ok_2: //copy_trans bool shadWDFlag = false; - int shadZoomX = heroData->_scaleValue; + int shadZoomX = drawNode->scaleValue; int backgroundDiff = shadSkipX; int shadBitMaskCopyTrans = shadBitMask; int shadBitAddrCopyTrans = shadBitAddr; shadowHero = (byte *)makeShadow->getBasePtr(shadowHeroX, shadowHeroY); - background = (byte *)screen->getBasePtr(heroData->_shadDrawX + diffX + backgroundDiff, heroData->_shadDrawY + diffY); + background = (byte *)screen->getBasePtr(shadDrawX + diffX + backgroundDiff, shadDrawY + diffY); if (shadPosX < 0) { if (heroSurfaceWidth > shadSkipX) { @@ -409,13 +392,13 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { //ct_loop: for (int l = 0; l < ct_loop; l++) { shadZoomX -= 100; - if (shadZoomX < 0 && heroData->_scaleValue != 10000) { - shadZoomX += heroData->_scaleValue; + if (shadZoomX < 0 && drawNode->scaleValue != 10000) { + shadZoomX += drawNode->scaleValue; } else { if (*shadowHero == GraphicsMan::kShadowColor) { - if ((shadBitMaskCopyTrans & heroData->_vm->_shadowBitmap[shadBitAddrCopyTrans]) != 0) { + if ((shadBitMaskCopyTrans & vm->_shadowBitmap[shadBitAddrCopyTrans])) { if (shadWallDown == 0) { - if ((shadBitMaskCopyTrans & heroData->_vm->_shadowBitmap[shadBitAddrCopyTrans + heroData->_vm->kShadowBitmapSize]) != 0) { + if ((shadBitMaskCopyTrans & vm->_shadowBitmap[shadBitAddrCopyTrans + PrinceEngine::kShadowBitmapSize])) { shadWDFlag = true; //shadow *background = *(sprShadow + *background); @@ -435,7 +418,7 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { } //okok backgroundDiff++; - background = (byte *)screen->getBasePtr(heroData->_shadDrawX + diffX + backgroundDiff, heroData->_shadDrawY + diffY); + background = (byte *)screen->getBasePtr(shadDrawX + diffX + backgroundDiff, shadDrawY + diffY); } shadowHeroX++; shadowHero = (byte *)makeShadow->getBasePtr(shadowHeroX, shadowHeroY); @@ -444,14 +427,14 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { if (!shadWallDown && shadWDFlag) { shadWallDown = shadPosX; shadWallBitAddr = shadBitAddr; - shadWallDestAddr = (byte *)screen->getBasePtr(heroData->_shadDrawX + diffX, heroData->_shadDrawY + diffY); + shadWallDestAddr = (byte *)screen->getBasePtr(shadDrawX + diffX, shadDrawY + diffY); shadWallBitMask = shadBitMask; shadWallPosY = shadPosY; shadWallSkipX = shadSkipX; shadWallModulo = sprModulo; } //byebye - if (shadDirection != 0 && shadWallDown != 0) { + if (shadDirection && shadWallDown) { int shadBitMaskWallCopyTrans = shadWallBitMask; int shadBitAddrWallCopyTrans = shadWallBitAddr; background = shadWallDestAddr; @@ -460,18 +443,18 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { if (ct_loop > shadWallSkipX && ct_loop - shadWallSkipX > shadWallModulo) { //WALL_copy_trans shadWDFlag = false; - int shadZoomXWall = heroData->_scaleValue; + int shadZoomXWall = drawNode->scaleValue; int backgroundDiffWall = 0; int shadowHeroXWall = 0; //ct_loop: for (int m = 0; m < ct_loop; m++) { shadZoomXWall -= 100; - if (shadZoomXWall < 0 && heroData->_scaleValue != 10000) { - shadZoomXWall += heroData->_scaleValue; + if (shadZoomXWall < 0 && drawNode->scaleValue != 10000) { + shadZoomXWall += drawNode->scaleValue; } else { //point_ok: if (*shadowHero == GraphicsMan::kShadowColor) { - if ((shadBitMaskWallCopyTrans & heroData->_vm->_shadowBitmap[shadBitAddrWallCopyTrans + heroData->_vm->kShadowBitmapSize]) != 0) { + if ((shadBitMaskWallCopyTrans & vm->_shadowBitmap[shadBitAddrWallCopyTrans + PrinceEngine::kShadowBitmapSize])) { *background = *(sprShadow + *background); } } @@ -539,7 +522,7 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { break; } shadowHeroX = 0; - background = (byte *)screen->getBasePtr(heroData->_shadDrawX + diffX, heroData->_shadDrawY + diffY); + background = (byte *)screen->getBasePtr(shadDrawX + diffX, shadDrawY + diffY); shadowHero = (byte *)makeShadow->getBasePtr(shadowHeroX, shadowHeroY); } //koniec_bajki - end_of_a_story @@ -549,12 +532,10 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { } void Hero::setScale(int8 zoomBitmapValue) { - if (zoomBitmapValue == 0) { - _zoomFactor = 0; - _scaleValue = 10000; + if (!zoomBitmapValue) { + _vm->_scaleValue = 10000; } else { - _zoomFactor = zoomBitmapValue; - _scaleValue = 10000 / _zoomFactor; + _vm->_scaleValue = 10000 / zoomBitmapValue; } } @@ -563,17 +544,6 @@ void Hero::selectZoom() { setScale(zoomBitmapValue); } -void Hero::setShadowScale(int32 shadowScale) { - shadowScale = 100 - shadowScale; - if (shadowScale == 0) { - _shadZoomFactor = 0; - _shadScaleValue = 10000; - } else { - _shadZoomFactor = shadowScale; - _shadScaleValue = 10000 / _shadZoomFactor; - } -} - int Hero::rotateHero(int oldDirection, int newDirection) { switch (oldDirection) { case kHeroDirLeft: @@ -904,7 +874,7 @@ void Hero::drawHero() { newDrawNode.data = _vm->_transTable; newDrawNode.drawFunction = &_graph->drawTransparentWithTransDrawNode; - if (_zoomFactor) { + if (_vm->_scaleValue != 10000) { _zoomedHeroSurface = zoomSprite(mainHeroSurface); newDrawNode.s = _zoomedHeroSurface; } else { @@ -925,8 +895,9 @@ void Hero::drawHeroShadow(Graphics::Surface *heroFrame) { newDrawNode.posZ = kHeroShadowZ; newDrawNode.width = 0; newDrawNode.height = 0; + newDrawNode.scaleValue = _vm->_scaleValue; newDrawNode.originalRoomSurface = nullptr; - newDrawNode.data = this; + newDrawNode.data = _vm; newDrawNode.drawFunction = &showHeroShadow; newDrawNode.s = heroFrame; _vm->_drawNodeList.push_back(newDrawNode); diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 743e09ac8d3a..d5f7d8cc7a68 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -41,7 +41,6 @@ struct DrawNode; class Hero { public: static const uint32 kMoveSetSize = 26; - static const int16 kShadowLineArraySize = 2 * 1280 * 4; static const int16 kStepLeftRight = 8; static const int16 kStepUpDown = 4; static const int16 kHeroShadowZ = 2; @@ -128,7 +127,6 @@ class Hero { void plotPoint(int x, int y); static void showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode); void drawHeroShadow(Graphics::Surface *heroFrame); - void setShadowScale(int32 shadowScale); void freeOldMove(); void freeHeroAnim(); @@ -138,9 +136,7 @@ class Hero { int16 _middleX; // middle of X int16 _middleY; // lower part of hero int16 _moveSetType; - - int8 _zoomFactor; - int16 _scaleValue; + int16 _frameXSize; int16 _frameYSize; int16 _scaledFrameXSize; @@ -149,12 +145,6 @@ class Hero { int16 _drawY; int16 _drawZ; - int32 _shadZoomFactor; - int32 _shadScaleValue; - int32 _shadLineLen; - int16 _shadDrawX; - int16 _shadDrawY; - byte *_coords; // array of coordinates byte *_dirTab; // array of directions byte *_currCoords; // current coordinations @@ -180,7 +170,6 @@ class Hero { int _color; // subtitles color uint32 _animSetNr; // number of animation set Common::Array _moveSet; // MoveAnims MoveSet - byte *_shadowLine; uint32 _moveDelay; uint32 _shadMinus; diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 080085b3235a..4b1147626a56 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -95,7 +95,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _tracePointFirstPointFlag(false), _coordsBuf2(nullptr), _coords2(nullptr), _coordsBuf3(nullptr), _coords3(nullptr), _shanLen(0), _directionTable(nullptr), _currentMidi(0), _lightX(0), _lightY(0), _curveData(nullptr), _curvPos(0), _creditsData(nullptr), _creditsDataSize(0), _currentTime(0), _zoomBitmap(nullptr), _shadowBitmap(nullptr), _transTable(nullptr), - _flcFrameSurface(nullptr) { + _flcFrameSurface(nullptr), _shadScaleValue(0), _shadLineLen(0), _scaleValue(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -196,6 +196,8 @@ PrinceEngine::~PrinceEngine() { free(_curveData); + free(_shadowLine); + free(_creditsData); } @@ -345,6 +347,8 @@ void PrinceEngine::init() { _curveData = (int16 *)malloc(2 * kCurveLen * sizeof(int16)); + _shadowLine = (byte *)malloc(kShadowLineArraySize); + Common::SeekableReadStream *creditsDataStream = SearchMan.createReadStreamForMember("credits.dat"); if (!creditsDataStream) { error("Can't load creditsDataStream"); @@ -489,8 +493,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _lightX = _script->getLightX(_locationNr); _lightY = _script->getLightY(_locationNr); - _mainHero->setShadowScale(_script->getShadowScale(_locationNr)); - _secondHero->setShadowScale(_script->getShadowScale(_locationNr)); + setShadowScale(_script->getShadowScale(_locationNr)); for (uint i = 0; i < _mobList.size(); i++) { _mobList[i]._visible = _script->getMobVisible(_room->_mobs, i); @@ -514,6 +517,22 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { return true; } +void PrinceEngine::setShadowScale(int32 shadowScale) { + shadowScale = 100 - shadowScale; + if (!shadowScale) { + _shadScaleValue = 10000; + } else { + _shadScaleValue = 10000 / shadowScale; + } +} + +void PrinceEngine::plotShadowLinePoint(int x, int y, int color, void *data) { + PrinceEngine *vm = (PrinceEngine *)data; + WRITE_UINT16(&vm->_shadowLine[vm->_shadLineLen * 4], x); + WRITE_UINT16(&vm->_shadowLine[vm->_shadLineLen * 4 + 2], y); + vm->_shadLineLen++; +} + void PrinceEngine::changeCursor(uint16 curId) { _debugger->_cursorNr = curId; _mouseFlag = curId; @@ -1360,8 +1379,6 @@ void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX, void PrinceEngine::showAnim(Anim &anim) { //ShowFrameCode //ShowAnimFrame - int phaseCount = anim._animData->getPhaseCount(); - int frameCount = anim._animData->getFrameCount(); int phase = anim._showFrame; int phaseFrameIndex = anim._animData->getPhaseFrameIndex(phase); int x = anim._x + anim._animData->getPhaseOffsetX(phase); @@ -1371,34 +1388,49 @@ void PrinceEngine::showAnim(Anim &anim) { int maxFrontFlag = (animFlag & 2); int specialZFlag = anim._nextAnim; int z = anim._nextAnim; - Graphics::Surface *backAnimSurface = anim._animData->getFrame(phaseFrameIndex); - int frameWidth = backAnimSurface->w; - int frameHeight = backAnimSurface->h; + Graphics::Surface *animSurface = anim._animData->getFrame(phaseFrameIndex); + int frameWidth = animSurface->w; + int frameHeight = animSurface->h; int shadowZ = 0; - if (x != 0 || y != 0 || phaseCount != 1 || frameCount != 1) { // TODO - check if this needed - - 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 { + if (checkMaskFlag) { + if (!anim._nextAnim) { z = y + frameHeight - 1; } - shadowZ = z; + checkMasks(x, y, frameWidth, frameHeight, z); + } - anim._currX = x; - anim._currY = y; - anim._currW = frameWidth; - anim._currH = frameHeight; - showSprite(backAnimSurface, x, y, 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)) { + if (animSurface) { + 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 @@ -1778,12 +1810,11 @@ void PrinceEngine::drawScreen() { clsMasks(); _mainHero->showHero(); - _secondHero->showHero(); - _mainHero->scrollHero(); - _secondHero->_drawX -= _picWindowX; - _mainHero->drawHero(); + + _secondHero->showHero(); + _secondHero->_drawX -= _picWindowX; _secondHero->drawHero(); const Graphics::Surface *roomSurface; diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 7e4592ad5414..3c7b381cafe1 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -227,6 +227,7 @@ struct DrawNode { int posZ; int32 width; int32 height; + int32 scaleValue; Graphics::Surface *s; Graphics::Surface *originalRoomSurface; void *data; @@ -325,19 +326,28 @@ class PrinceEngine : public Engine { uint16 _sceneWidth; int32 _picWindowX; int32 _picWindowY; - int16 _lightX; // for hero shadow - int16 _lightY; + Image::BitmapDecoder *_roomBmp; MhwanhDecoder *_suitcaseBmp; Room *_room; Script *_script; InterpreterFlags *_flags; Interpreter *_interpreter; + GraphicsMan *_graph; uint8 _currentMidi; byte *_zoomBitmap; byte *_shadowBitmap; byte *_transTable; + int16 _scaleValue; // scale for hero or special shadow animation + int16 _lightX; // for hero shadow + int16 _lightY; + int32 _shadScaleValue; + int32 _shadLineLen; + byte *_shadowLine; + void setShadowScale(int32 shadowScale); + static void plotShadowLinePoint(int x, int y, int color, void *data); + static const int16 kFPS = 15; static const int16 kMaxPicWidth = 1280; @@ -345,6 +355,7 @@ class PrinceEngine : public Engine { static const int16 kZoomStep = 4; static const int32 kZoomBitmapLen = kMaxPicHeight / kZoomStep * kMaxPicWidth / kZoomStep; static const int32 kShadowBitmapSize = kMaxPicWidth * kMaxPicHeight / 8; + static const int16 kShadowLineArraySize = 2 * 1280 * 4; static const int16 kZoomBitmapWidth = kMaxPicWidth / kZoomStep; static const int16 kZoomBitmapHeight = kMaxPicHeight / kZoomStep; static const int16 kNormalWidth = 640; @@ -630,7 +641,6 @@ class PrinceEngine : public Engine { Graphics::Surface *_cursor2; Cursor *_cursor3; Debugger *_debugger; - GraphicsMan *_graph; Font *_font; MusicPlayer *_midiPlayer; From 35c3d362b27c4e23d754e4c0fb9155b0640fc1b5 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Sat, 16 Aug 2014 23:01:08 +0200 Subject: [PATCH 349/374] PRINCE: dialogImage - memory leak fix --- engines/prince/prince.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 4b1147626a56..e5e78139cf21 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -199,6 +199,11 @@ PrinceEngine::~PrinceEngine() { free(_shadowLine); free(_creditsData); + + if (_dialogImage != nullptr) { + _dialogImage->free(); + delete _dialogImage; + } } GUI::Debugger *PrinceEngine::getDebugger() { From 01bf821e176ade6d74270450cbdcd3eea51686a8 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 18 Aug 2014 20:53:36 +0200 Subject: [PATCH 350/374] PRINCE: dialogImage - second memory leak fix --- engines/prince/prince.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index e5e78139cf21..0267cf58bbf7 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -75,7 +75,7 @@ void PrinceEngine::debugEngine(const char *s, ...) { debug("Prince::Engine %s", buf); } -PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : +PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _graph(nullptr), _script(nullptr), _interpreter(nullptr), _flags(nullptr), _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), _room(nullptr), _cursor1(nullptr), _cursor2(nullptr), _cursor3(nullptr), _font(nullptr), @@ -95,7 +95,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _tracePointFirstPointFlag(false), _coordsBuf2(nullptr), _coords2(nullptr), _coordsBuf3(nullptr), _coords3(nullptr), _shanLen(0), _directionTable(nullptr), _currentMidi(0), _lightX(0), _lightY(0), _curveData(nullptr), _curvPos(0), _creditsData(nullptr), _creditsDataSize(0), _currentTime(0), _zoomBitmap(nullptr), _shadowBitmap(nullptr), _transTable(nullptr), - _flcFrameSurface(nullptr), _shadScaleValue(0), _shadLineLen(0), _scaleValue(0) { + _flcFrameSurface(nullptr), _shadScaleValue(0), _shadLineLen(0), _scaleValue(0), _dialogImage(nullptr) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -2863,6 +2863,7 @@ void PrinceEngine::runDialog() { } _dialogImage->free(); delete _dialogImage; + _dialogImage = nullptr; _dialogFlag = false; } From afe47b014a0538171e826c780f198a19df60bd69 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 18 Aug 2014 22:03:50 +0200 Subject: [PATCH 351/374] PRINCE: drawTransparentWithTrans - memory leak fix --- engines/prince/graphics.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index d70591d2ccaf..2f021fe2231d 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -200,7 +200,11 @@ void GraphicsMan::drawTransparentWithTransDrawNode(Graphics::Surface *screen, Dr } } } - } else if (*(src2 + 1) == 255) { + } else if (x != drawNode->s->w - 1) { + if (*(src2 + 1) == 255) { + continue; + } + } else { continue; } byte value = 0; @@ -216,11 +220,13 @@ void GraphicsMan::drawTransparentWithTransDrawNode(Graphics::Surface *screen, Dr continue; } } - } else { + } else if (y) { value = *(src2 - drawNode->s->pitch); if (value == 255) { continue; } + } else { + continue; } *dst2 = transTableData[*dst2 * 256 + value]; } From e1774dc4462332b8345c44c7ebc5d5f7ff722efa Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 30 Sep 2014 15:43:16 +0200 Subject: [PATCH 352/374] PRINCE: countDrawPosition() - clean up --- engines/prince/animation.cpp | 20 ++------------------ engines/prince/animation.h | 5 ----- engines/prince/hero.cpp | 26 +++----------------------- 3 files changed, 5 insertions(+), 46 deletions(-) diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index db16adacbc29..b594ff47d1f6 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -28,7 +28,7 @@ namespace Prince { -Animation::Animation() : _idXDiff(0), _idYDiff(0), _loopCount(0), _phaseCount(0), _frameCount(0), _baseX(0), _baseY(0) +Animation::Animation() : _loopCount(0), _phaseCount(0), _frameCount(0), _baseX(0), _baseY(0) { } @@ -50,8 +50,7 @@ void Animation::clear() { } bool Animation::loadFromStream(Common::SeekableReadStream &stream) { - _idXDiff = stream.readByte(); - _idYDiff = stream.readByte(); + stream.skip(2); // skip not used x and y coord diff _loopCount = stream.readUint16LE(); _phaseCount = stream.readUint16LE(); stream.skip(2); // skip _frameCount here @@ -109,21 +108,6 @@ bool Animation::loadFromStream(Common::SeekableReadStream &stream) { return true; } -bool Animation::testId() const { - if (_idXDiff == 'A' && _idYDiff == 'N') { - return true; - } - return false; -} - -int8 Animation::getIdXDiff() const { - return _idXDiff; -} - -int8 Animation::getIdYDiff() const { - return _idYDiff; -} - int16 Animation::getLoopCount() const { return _loopCount; } diff --git a/engines/prince/animation.h b/engines/prince/animation.h index 87d21f5dbc89..c4df3a197061 100644 --- a/engines/prince/animation.h +++ b/engines/prince/animation.h @@ -36,9 +36,6 @@ class Animation { ~Animation(); bool loadFromStream(Common::SeekableReadStream &stream); - bool testId() const; - int8 getIdXDiff() const; - int8 getIdYDiff() const; int16 getLoopCount() const; int32 getPhaseCount() const; int32 getFrameCount() const; @@ -64,8 +61,6 @@ class Animation { }; Common::Array _frameList; Common::Array _phaseList; - int8 _idXDiff; - int8 _idYDiff; int16 _loopCount; int16 _phaseCount; int32 _frameCount; diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index ff4be1aefcda..bc127b398b55 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -180,18 +180,6 @@ void Hero::countDrawPosition() { heroAnim = _moveSet[_moveSetType]; } if (heroAnim != nullptr) { - int16 tempMiddleY; - int16 baseX = heroAnim->getBaseX(); - int16 baseY = heroAnim->getBaseY(); - // any chance? - if (baseX == 320) { - tempMiddleY = _middleY - (baseY - 240); - if (baseY != 240) { - error("Hero::countDrawPosition() - tempMiddleY"); - } - } else { - tempMiddleY = _middleY; - } int phaseFrameIndex = heroAnim->getPhaseFrameIndex(_phase); Graphics::Surface *heroSurface = heroAnim->getFrame(phaseFrameIndex); @@ -200,26 +188,18 @@ void Hero::countDrawPosition() { _scaledFrameXSize = getScaledValue(_frameXSize); _scaledFrameYSize = getScaledValue(_frameYSize); - // any use of this? - if (!heroAnim->testId()) { - error("countDrawPosition - !heroAnim->testId()"); - //int diffX = heroAnim->getIdXDiff(); - //int diffY = heroAnim->getIdYDiff(); - } - if (_vm->_scaleValue != 10000) { //notfullSize _drawX = _middleX - _scaledFrameXSize / 2; - _drawY = tempMiddleY + 1 - _scaledFrameYSize; + _drawY = _middleY + 1 - _scaledFrameYSize; _vm->checkMasks(_drawX, _drawY - 1, _scaledFrameXSize, _scaledFrameYSize, _middleY); } else { //fullSize _drawX = _middleX - _frameXSize / 2; - _drawY = tempMiddleY + 1 - _frameYSize; + _drawY = _middleY + 1 - _frameYSize; _vm->checkMasks(_drawX, _drawY - 1, _frameXSize, _frameYSize, _middleY); } - - _drawZ = tempMiddleY; + _drawZ = _middleY; } } From 543ddc3e90e26c806cb284235128b580f804e337 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 30 Sep 2014 22:34:06 +0200 Subject: [PATCH 353/374] PRINCE: Original copyright - update --- engines/prince/detection.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/prince/detection.h b/engines/prince/detection.h index 6137730bd0fd..be08a71ea901 100644 --- a/engines/prince/detection.h +++ b/engines/prince/detection.h @@ -85,7 +85,7 @@ class PrinceMetaEngine : public AdvancedMetaEngine { } virtual const char *getOriginalCopyright() const { - return "Copyright (C)"; + return "The Prince and the Coward (C) 1996-97 Metropolis"; } virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; From a9d9696d217f43732e3594f5f862c4a8b97b9328 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Fri, 3 Oct 2014 17:12:11 +0200 Subject: [PATCH 354/374] PRINCE: Animation class - indentation fix --- engines/prince/animation.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/prince/animation.h b/engines/prince/animation.h index c4df3a197061..838836d818da 100644 --- a/engines/prince/animation.h +++ b/engines/prince/animation.h @@ -34,8 +34,8 @@ class Animation { public: Animation(); ~Animation(); - bool loadFromStream(Common::SeekableReadStream &stream); - + bool loadFromStream(Common::SeekableReadStream &stream); + int16 getLoopCount() const; int32 getPhaseCount() const; int32 getFrameCount() const; From 4ef22e3a196705097cb4ffd4992d1666e4519537 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 6 Oct 2014 22:54:24 +0200 Subject: [PATCH 355/374] PRINCE: PtcArchive::createReadStreamFromMember - add MKTAG --- engines/prince/archive.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/engines/prince/archive.cpp b/engines/prince/archive.cpp index 11be0b224a47..28f77cb4c42c 100644 --- a/engines/prince/archive.cpp +++ b/engines/prince/archive.cpp @@ -123,13 +123,13 @@ Common::SeekableReadStream *PtcArchive::createReadStreamForMember(const Common:: _stream->seek(entryHeader._offset); // This *HAS* to be malloc (not new[]) because MemoryReadStream uses free() to free the memory - byte* buffer = (byte *)malloc(size); + byte *buffer = (byte *)malloc(size); _stream->read(buffer, size); - if (READ_BE_UINT32(buffer) == 0x4D41534D) { + if (READ_BE_UINT32(buffer) == MKTAG('M', 'A', 'S', 'M')) { Decompressor dec; uint32 decompLen = READ_BE_UINT32(buffer + 14); - byte *decompData = (byte*)malloc(decompLen); + byte *decompData = (byte *)malloc(decompLen); dec.decompress(buffer + 18, decompData, decompLen); free(buffer); size = decompLen; From 6d228fe3f9e4e4717b04dd3211513be37ce9468e Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 6 Oct 2014 23:06:25 +0200 Subject: [PATCH 356/374] PRINCE: Mob::AttrId - enum names update --- engines/prince/mob.cpp | 14 +++++++------- engines/prince/mob.h | 19 ++++--------------- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/engines/prince/mob.cpp b/engines/prince/mob.cpp index 9f3ff5d7b838..de825ef8b209 100644 --- a/engines/prince/mob.cpp +++ b/engines/prince/mob.cpp @@ -75,13 +75,13 @@ bool Mob::loadFromStream(Common::SeekableReadStream &stream) { void Mob::setData(AttrId dataId, uint16 value) { switch (dataId) { - case ExamDir: + case kMobExamDir: _examDirection = (Direction)value; break; - case ExamX: + case kMobExamX: _examPosition.x = value; break; - case ExamY: + case kMobExamY: _examPosition.y = value; break; default: @@ -91,13 +91,13 @@ void Mob::setData(AttrId dataId, uint16 value) { uint16 Mob::getData(AttrId dataId) { switch (dataId) { - case Visible: + case kMobVisible: return _visible; - case ExamDir: + case kMobExamDir: return _examDirection; - case ExamX: + case kMobExamX: return _examPosition.x; - case ExamY: + case kMobExamY: return _examPosition.y; default: assert(false); diff --git a/engines/prince/mob.h b/engines/prince/mob.h index aaa51988b202..ecf0eb4c3a0b 100644 --- a/engines/prince/mob.h +++ b/engines/prince/mob.h @@ -41,21 +41,10 @@ class Mob { // Used instead of offset in setData and getData enum AttrId { - Visible = 0, - Type = 2, - X1 = 4, - Y1 = 6, - X2 = 8, - Y2 = 10, - Mask = 12, - ExamX = 14, - ExamY = 16, - ExamDir = 18, - UseX = 20, - UseY = 21, - UseDir = 22, - Name = 24, - ExamText = 28 + kMobVisible = 0, + kMobExamX = 14, + kMobExamY = 16, + kMobExamDir = 18, }; void setData(AttrId dataId, uint16 value); From f3965bbe5a6900d324d0602fd16085deec2f9579 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Mon, 6 Oct 2014 23:52:35 +0200 Subject: [PATCH 357/374] PRINCE: detection.h - remove unnecessary comment --- engines/prince/detection.h | 1 - 1 file changed, 1 deletion(-) diff --git a/engines/prince/detection.h b/engines/prince/detection.h index be08a71ea901..e8f225690e09 100644 --- a/engines/prince/detection.h +++ b/engines/prince/detection.h @@ -66,7 +66,6 @@ static const PrinceGameDescription gameDescriptions[] = { { AD_TABLE_END_MARKER, 0 } }; -// we match from data too, to stop detection from a non-top-level directory const static char *directoryGlobs[] = { "all", 0 From 115340bc874c0a79d64db93e1ed3d914b27fceb5 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 7 Oct 2014 02:14:12 +0200 Subject: [PATCH 358/374] PRINCE: Resource loading - renaming --- engines/prince/animation.cpp | 2 +- engines/prince/animation.h | 2 +- engines/prince/cursor.cpp | 2 +- engines/prince/cursor.h | 2 +- engines/prince/font.cpp | 2 +- engines/prince/font.h | 2 +- engines/prince/mhwanh.h | 12 ------------ engines/prince/resource.h | 2 +- engines/prince/script.cpp | 2 +- engines/prince/script.h | 4 ++-- engines/prince/variatxt.cpp | 2 +- engines/prince/variatxt.h | 2 +- 12 files changed, 12 insertions(+), 24 deletions(-) diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index b594ff47d1f6..b4bde27f69eb 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -49,7 +49,7 @@ void Animation::clear() { } } -bool Animation::loadFromStream(Common::SeekableReadStream &stream) { +bool Animation::loadStream(Common::SeekableReadStream &stream) { stream.skip(2); // skip not used x and y coord diff _loopCount = stream.readUint16LE(); _phaseCount = stream.readUint16LE(); diff --git a/engines/prince/animation.h b/engines/prince/animation.h index 838836d818da..733acb399c59 100644 --- a/engines/prince/animation.h +++ b/engines/prince/animation.h @@ -34,7 +34,7 @@ class Animation { public: Animation(); ~Animation(); - bool loadFromStream(Common::SeekableReadStream &stream); + bool loadStream(Common::SeekableReadStream &stream); int16 getLoopCount() const; int32 getPhaseCount() const; diff --git a/engines/prince/cursor.cpp b/engines/prince/cursor.cpp index 38b5be3bca40..ddcabbd28f94 100644 --- a/engines/prince/cursor.cpp +++ b/engines/prince/cursor.cpp @@ -37,7 +37,7 @@ Cursor::~Cursor() { } } -bool Cursor::loadFromStream(Common::SeekableReadStream &stream) { +bool Cursor::loadStream(Common::SeekableReadStream &stream) { stream.skip(4); uint16 width = stream.readUint16LE(); uint16 height = stream.readUint16LE(); diff --git a/engines/prince/cursor.h b/engines/prince/cursor.h index 683a158ba8a4..9387f344dc8d 100644 --- a/engines/prince/cursor.h +++ b/engines/prince/cursor.h @@ -34,7 +34,7 @@ class Cursor { Cursor(); ~Cursor(); - bool loadFromStream(Common::SeekableReadStream &stream); + bool loadStream(Common::SeekableReadStream &stream); const Graphics::Surface *getSurface() const { return _surface; } private: diff --git a/engines/prince/font.cpp b/engines/prince/font.cpp index 42329d26065e..e81a93d1a183 100644 --- a/engines/prince/font.cpp +++ b/engines/prince/font.cpp @@ -39,7 +39,7 @@ Font::~Font() { } } -bool Font::loadFromStream(Common::SeekableReadStream &stream) { +bool Font::loadStream(Common::SeekableReadStream &stream) { stream.seek(0); uint32 dataSize = stream.size(); _fontData = (byte *)malloc(dataSize); diff --git a/engines/prince/font.h b/engines/prince/font.h index 3b50994e2c6a..b03849a4aab8 100644 --- a/engines/prince/font.h +++ b/engines/prince/font.h @@ -35,7 +35,7 @@ class Font : public Graphics::Font { Font(); virtual ~Font(); - bool loadFromStream(Common::SeekableReadStream &stream); + bool loadStream(Common::SeekableReadStream &stream); virtual int getFontHeight() const override; diff --git a/engines/prince/mhwanh.h b/engines/prince/mhwanh.h index cfa14630b7fd..f8165a76662a 100644 --- a/engines/prince/mhwanh.h +++ b/engines/prince/mhwanh.h @@ -50,18 +50,6 @@ class MhwanhDecoder : public Image::ImageDecoder { byte *_palette; }; -namespace Resource { - template <> inline - bool loadFromStream(MhwanhDecoder &image, Common::SeekableReadStream &stream) { - return image.loadStream(stream); - } - - template <> inline - bool loadFromStream(Image::BitmapDecoder &image, Common::SeekableReadStream &stream) { - return image.loadStream(stream); - } -} - } // End of namespace Prince #endif diff --git a/engines/prince/resource.h b/engines/prince/resource.h index 76ac5b0505b5..b1fbd9c4f03d 100644 --- a/engines/prince/resource.h +++ b/engines/prince/resource.h @@ -34,7 +34,7 @@ namespace Resource { template bool loadFromStream(T &resource, Common::SeekableReadStream &stream) { - return resource.loadFromStream(stream); + return resource.loadStream(stream); } template diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 582864d0c384..5f178d96d2b1 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -96,7 +96,7 @@ Script::~Script() { } } -bool Script::loadFromStream(Common::SeekableReadStream &stream) { +bool Script::loadStream(Common::SeekableReadStream &stream) { _dataSize = stream.size(); if (!_dataSize) { return false; diff --git a/engines/prince/script.h b/engines/prince/script.h index 1c87fb3b2309..473163ed9ad2 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -64,7 +64,7 @@ class Room { int _talk; int _give; - bool loadFromStream(Common::SeekableReadStream &stream); + bool loadStream(Common::SeekableReadStream &stream); bool loadRoom(byte *roomData); int getOptionOffset(int option); @@ -123,7 +123,7 @@ class Script { ScriptInfo _scriptInfo; - bool loadFromStream(Common::SeekableReadStream &stream); + bool loadStream(Common::SeekableReadStream &stream); template T read(uint32 address) { diff --git a/engines/prince/variatxt.cpp b/engines/prince/variatxt.cpp index 839ed5e66226..c38c65ce5d31 100644 --- a/engines/prince/variatxt.cpp +++ b/engines/prince/variatxt.cpp @@ -37,7 +37,7 @@ VariaTxt::~VariaTxt() { } -bool VariaTxt::loadFromStream(Common::SeekableReadStream &stream) { +bool VariaTxt::loadStream(Common::SeekableReadStream &stream) { _dataSize = stream.size(); _data = (byte *)malloc(_dataSize); stream.read(_data, _dataSize); diff --git a/engines/prince/variatxt.h b/engines/prince/variatxt.h index 99b225f362a9..04c34bc0effc 100644 --- a/engines/prince/variatxt.h +++ b/engines/prince/variatxt.h @@ -29,7 +29,7 @@ class VariaTxt { VariaTxt(); ~VariaTxt(); - bool loadFromStream(Common::SeekableReadStream &stream); + bool loadStream(Common::SeekableReadStream &stream); byte *getString(uint32 stringId); private: From 80cf4bae8bb8fd11b7eef90f243c4ceade3cfb4c Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 7 Oct 2014 02:56:34 +0200 Subject: [PATCH 359/374] PRINCE: Script::loadAllMasks - fix --- engines/prince/script.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 5f178d96d2b1..38c0d3a345dd 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -347,17 +347,19 @@ void Script::installObjects(int offset) { bool Script::loadAllMasks(Common::Array &maskList, int offset) { Mask tempMask; while (1) { - tempMask._state = READ_UINT32(&_data[offset]); + Common::MemoryReadStream maskStream(_data, _dataSize); + maskStream.seek(offset); + tempMask._state = maskStream.readUint16LE(); if (tempMask._state == -1) { break; } - tempMask._flags = READ_UINT32(&_data[offset + 2]); - tempMask._x1 = READ_UINT32(&_data[offset + 4]); - tempMask._y1 = READ_UINT32(&_data[offset + 6]); - tempMask._x2 = READ_UINT32(&_data[offset + 8]); - tempMask._y2 = READ_UINT32(&_data[offset + 10]); - tempMask._z = READ_UINT32(&_data[offset + 12]); - tempMask._number = READ_UINT32(&_data[offset + 14]); + tempMask._flags = maskStream.readUint16LE(); + tempMask._x1 = maskStream.readUint16LE(); + tempMask._y1 = maskStream.readUint16LE(); + tempMask._x2 = maskStream.readUint16LE(); + tempMask._y2 = maskStream.readUint16LE(); + tempMask._z = maskStream.readUint16LE(); + tempMask._number = maskStream.readUint16LE(); const Common::String msStreamName = Common::String::format("MS%02d", tempMask._number); Common::SeekableReadStream *msStream = SearchMan.createReadStreamForMember(msStreamName); From e894a18b08a524faa9392ee193fe96f4f2b3c3dd Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 7 Oct 2014 16:05:37 +0200 Subject: [PATCH 360/374] PRINCE: Script::installSingleBackAnim - update --- engines/prince/prince.h | 6 +++++- engines/prince/script.cpp | 39 ++++++++++++++++++++++++--------------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 3c7b381cafe1..d7519e2414e7 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -104,13 +104,17 @@ struct BAS { int32 _data2; // additional data for measurements }; +const int kStructSizeBAS = 28; + struct BASA { int16 _num; // animation number int16 _start; // initial frame int16 _end; // final frame - int16 _pad; // fulfilment to 8 bytes + //int16 _pad; // fulfilment to 8 bytes }; +const int kStructSizeBASA = 8; + // background and normal animation struct Anim { BASA _basaData; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 38c0d3a345dd..09f45af2e4ad 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -250,25 +250,30 @@ int Script::scanMobEventsWithItem(int mobMask, int dataEventOffset, int itemMask void Script::installSingleBackAnim(Common::Array &backAnimList, int slot, int roomBackAnimOffset) { - _vm->removeSingleBackAnim(slot); + _vm->removeSingleBackAnim(slot); // free slot before loading - int offset = roomBackAnimOffset + slot * 4; + int offset = roomBackAnimOffset + slot * 4; // BackgroundAnim offset for selected slot number - BackgroundAnim newBackgroundAnim; + BackgroundAnim newBackgroundAnim; // BackgroundAnim seq data and its array of Anim - int animOffset = READ_UINT32(&_data[offset]); - int anims = READ_UINT32(&_data[animOffset + 8]); + int animOffset = READ_UINT32(&_data[offset]); // pos of BackgroundAnim data in script + int anims = READ_UINT32(&_data[animOffset + 8]); // amount of Anim in BackgroundAnim if (anims == 0) { - anims = 1; + anims = 1; // anims with 0 as amount in game data has just 1 animation } if (animOffset != 0) { + Common::MemoryReadStream stream(_data, _dataSize); // stream from script data for (int i = 0; i < anims; i++) { Anim newAnim; - newAnim._basaData._num = READ_UINT16(&_data[animOffset + 28 + i * 8]); - newAnim._basaData._start = READ_UINT16(&_data[animOffset + 28 + i * 8 + 2]); - newAnim._basaData._end = READ_UINT16(&_data[animOffset + 28 + i * 8 + 4]); + stream.seek(animOffset + kStructSizeBAS + kStructSizeBASA * i); + // Anim BASA data + newAnim._basaData._num = stream.readUint16LE(); + newAnim._basaData._start = stream.readUint16LE(); + newAnim._basaData._end = stream.readUint16LE(); + + // Anim number in game files int animNumber = newAnim._basaData._num; const Common::String animName = Common::String::format("AN%02d", animNumber); const Common::String shadowName = Common::String::format("AN%02dS", animNumber); @@ -279,9 +284,10 @@ void Script::installSingleBackAnim(Common::Array &backAnimList, delete newAnim._shadowData; newAnim._shadowData = nullptr; } + newAnim._usage = 0; newAnim._state = 0; // enabled - if ((_vm->_animList[animNumber]._flags & 4) != 0) { + if ((_vm->_animList[animNumber]._flags & 4)) { newAnim._state = 1; newAnim._frame = _vm->_animList[animNumber]._endPhase; newAnim._showFrame = _vm->_animList[animNumber]._endPhase; @@ -306,16 +312,19 @@ void Script::installSingleBackAnim(Common::Array &backAnimList, newBackgroundAnim.backAnims.push_back(newAnim); } - newBackgroundAnim._seq._type = READ_UINT32(&_data[animOffset]); - newBackgroundAnim._seq._data = READ_UINT32(&_data[animOffset + 4]); - newBackgroundAnim._seq._anims = READ_UINT32(&_data[animOffset + 8]); + // Anim BAS data + stream.seek(animOffset); + newBackgroundAnim._seq._type = stream.readUint32LE(); + newBackgroundAnim._seq._data = stream.readUint32LE(); + newBackgroundAnim._seq._anims = stream.readUint32LE(); + stream.skip(12); newBackgroundAnim._seq._current = newBackgroundAnim.backAnims[0]._basaData._num; newBackgroundAnim._seq._counter = 0; newBackgroundAnim._seq._currRelative = 0; - newBackgroundAnim._seq._data2 = READ_UINT32(&_data[animOffset + 24]); + newBackgroundAnim._seq._data2 = stream.readUint32LE(); int start = newBackgroundAnim.backAnims[0]._basaData._start; // BASA_Start of first frame - int end = newBackgroundAnim.backAnims[0]._basaData._end; //BASA_End of first frame + int end = newBackgroundAnim.backAnims[0]._basaData._end; // BASA_End of first frame if (start != -1) { newBackgroundAnim.backAnims[0]._frame = start; From dcb85739fffbfcb9b1da72ecbfcb048875f93d62 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Tue, 7 Oct 2014 16:17:19 +0200 Subject: [PATCH 361/374] PRINCE: MusicPlayer - remove unnecessary comments --- engines/prince/sound.cpp | 9 --------- engines/prince/sound.h | 7 +------ 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/engines/prince/sound.cpp b/engines/prince/sound.cpp index 0f536973b69d..e58e89d8f9e2 100644 --- a/engines/prince/sound.cpp +++ b/engines/prince/sound.cpp @@ -20,11 +20,6 @@ * */ -/* - * This code is based on original Soltys source code - * Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon - */ - #include "prince/prince.h" #include "prince/sound.h" #include "prince/musNum.h" @@ -136,10 +131,6 @@ MusicPlayer::MusicPlayer(PrinceEngine *vm) : _vm(vm) { else _driver->sendGMReset(); - // TODO: Load cmf.ins with the instrument table. It seems that an - // interface for such an operation is supported for AdLib. Maybe for - // this card, setting instruments is necessary. - _driver->setTimerCallback(this, &timerCallback); } } diff --git a/engines/prince/sound.h b/engines/prince/sound.h index b1711bd682eb..cc44b0a1103a 100644 --- a/engines/prince/sound.h +++ b/engines/prince/sound.h @@ -20,11 +20,6 @@ * */ -/* - * This code is based on original Soltys source code - * Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon - */ - #ifndef PRINCE_SOUND_H #define PRINCE_SOUND_H @@ -63,7 +58,7 @@ class MusicPlayer: public Audio::MidiPlayer { virtual void send(uint32 b); virtual void sendToChannel(byte channel, uint32 b); - static const char * _musTable[]; + static const char *_musTable[]; static const uint8 _musRoomTable[]; }; From 0e70ffaf59044402973eb88ec32f338c522491e3 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 8 Oct 2014 17:39:10 +0200 Subject: [PATCH 362/374] PRINCE: Flags::getFlagName - debugging function Faster searching by changing switch to bsearch and array --- engines/prince/flags.cpp | 759 ++++++++++++++++++++------------------- engines/prince/flags.h | 15 +- 2 files changed, 399 insertions(+), 375 deletions(-) diff --git a/engines/prince/flags.cpp b/engines/prince/flags.cpp index 3b0d1d95dca3..f1a05bd4df3b 100644 --- a/engines/prince/flags.cpp +++ b/engines/prince/flags.cpp @@ -21,383 +21,400 @@ */ #include "prince/flags.h" +#include "prince/script.h" namespace Prince { const char *Flags::getFlagName(uint16 flagId) { - switch (flagId) { - default: return "unknown_flag"; - case FLAGA1: return "FLAGA1"; - case FLAGA2: return "FLAGA2"; - case FLAGA3: return "FLAGA3"; - case DESTX: return "DESTX"; - case DESTY: return "DESTY"; - case DESTD: return "DESTD"; - case DwarfDone: return "DwarfDone"; - case GRABARZCOUNTER: return "GRABARZCOUNTER"; - case KIERUNEK: return "KIERUNEK"; - case BACKFLAG1: return "BACKFLAG1"; - case BACKFLAG2: return "BACKFLAG2"; - case BACKFLAG3: return "BACKFLAG3"; - case BACKFLAG4: return "BACKFLAG4"; - case MACROFLAG1: return "MACROFLAG1"; - case MACROFLAG2: return "MACROFLAG2"; - case MACROFLAG3: return "MACROFLAG3"; - case HEROLDDONE: return "HEROLDDONE"; - case BRIDGESET: return "BRIDGESET"; - case U_BT_1: return "U_BT_1"; - case U_BT_2: return "U_BT_2"; - case U_BT_3: return "U_BT_3"; - case U_BT_4: return "U_BT_4"; - case U_BT_5: return "U_BT_5"; - case U_BT_6: return "U_BT_6"; - case U_BT_7: return "U_BT_7"; - case U_BT_8: return "U_BT_8"; - case U_BT_9: return "U_BT_9"; - case U_BT_COUNTER: return "U_BT_COUNTER"; - case ARIVALDALIVE: return "ARIVALDALIVE"; - case TALKCHAR1: return "TALKCHAR1"; - case TalkType1: return "TalkType1"; - case TALKROUT1: return "TALKROUT1"; - case TALKROUT2: return "TALKROUT2"; - case TALKROUT3: return "TALKROUT3"; - case TALKROUT4: return "TALKROUT4"; - case TALKANIM1: return "TALKANIM1"; - case TALKANIM2: return "TALKANIM2"; - case TALKCOLOR1: return "TALKCOLOR1"; - case TALKCOLOR2: return "TALKCOLOR2"; - case KapciuchTaken: return "KapciuchTaken"; - case CurrentBeggarA: return "CurrentBeggarA"; - case TempKapc: return "TempKapc"; - case HomTaken: return "HomTaken"; - case WizardTalk: return "WizardTalk"; - case SunlordTalk: return "SunlordTalk"; - case HermitTalk: return "HermitTalk"; - case RunyMode: return "RunyMode"; - case FatMerchantTalk: return "FatMerchantTalk"; - case HotDogTalk: return "HotDogTalk"; - case ThiefTalk: return "ThiefTalk"; - case BeggarTalk: return "BeggarTalk"; - case MonkTalk: return "MonkTalk"; - case BardTalk: return "BardTalk"; - case BarmanTalk: return "BarmanTalk"; - case LeftPlayerTalk: return "LeftPlayerTalk"; - case OczySowy: return "OczySowy"; - case CzachySpeed1: return "CzachySpeed1"; - case CzachySpeed2: return "CzachySpeed2"; - case CzachySpeed3: return "CzachySpeed3"; - case CzachySlowDown1: return "CzachySlowDown1"; - case CzachySlowDown2: return "CzachySlowDown2"; - case CzachySlowDown3: return "CzachySlowDown3"; - case FjordDane: return "FjordDane"; - case GKopany1: return "GKopany1"; - case GKopany2: return "GKopany2"; - case GKopany3: return "GKopany3"; - case GKopany4: return "GKopany4"; - case KnowGodWord: return "KnowGodWord"; - case TALKROUT21: return "TALKROUT21"; - case TALKROUT22: return "TALKROUT22"; - case TALKROUT23: return "TALKROUT23"; - case TALKROUT24: return "TALKROUT24"; - case TalkType2: return "TalkType2"; - case GrabarzTalk: return "GrabarzTalk"; - case LastTalker: return "LastTalker"; - case MapaPustelniaEnabled: return "MapaPustelniaEnabled"; - case MapaTempleEnabled: return "MapaTempleEnabled"; - case MapaFjordEnabled: return "MapaFjordEnabled"; - case MapaSilmanionaEnabled: return "MapaSilmanionaEnabled"; - case MapaKurhanEnabled: return "MapaKurhanEnabled"; - case MapaDragonEnabled: return "MapaDragonEnabled"; - case MapaMillEnabled: return "MapaMillEnabled"; - case DwarfRunning: return "DwarfRunning"; - case DwarfTalk: return "DwarfTalk"; - case CurseLift: return "CurseLift"; - case KosciSwapped: return "KosciSwapped"; - case BookStolen: return "BookStolen"; - case MapaUsable: return "MapaUsable"; - case FjordBoss: return "FjordBoss"; - case FjordHotDog: return "FjordHotDog"; - case FjordLewy: return "FjordLewy"; - case FjordPrawy: return "FjordPrawy"; - case TalkArivald: return "TalkArivald"; - case ShootDone: return "ShootDone"; - case ShootRunning: return "ShootRunning"; - case ShootKnow: return "ShootKnow"; - case MirrorKnow: return "MirrorKnow"; - case Gar1stTime: return "Gar1stTime"; - case KosciTaken: return "KosciTaken"; - case ArivGotSpell: return "ArivGotSpell"; - case BookGiven: return "BookGiven"; - case Wywieszka: return "Wywieszka"; - case TalkSheila: return "TalkSheila"; - case TalkSheila2: return "TalkSheila2"; - case BackHuman: return "BackHuman"; - case SkarbiecOpen: return "SkarbiecOpen"; - case LustroTaken: return "LustroTaken"; - case GargoyleHom: return "GargoyleHom"; - case GargoyleBroken: return "GargoyleBroken"; - case FjordDzien: return "FjordDzien"; - case GargoyleHom2: return "GargoyleHom2"; - case RunMonstersRunning: return "RunMonstersRunning"; - case FoundPaperInCoffin: return "FoundPaperInCoffin"; - case KnowSunlord: return "KnowSunlord"; - case KnowSunlordTalk: return "KnowSunlordTalk"; - case ArivaldCzyta: return "ArivaldCzyta"; - case TelepX: return "TelepX"; - case TelepY: return "TelepY"; - case TelepDir: return "TelepDir"; - case TelepRoom: return "TelepRoom"; - case ListStolen: return "ListStolen"; - case WifeInDoor: return "WifeInDoor"; - case TalkWifeFlag: return "TalkWifeFlag"; - case LetterGiven: return "LetterGiven"; - case LutniaTaken: return "LutniaTaken"; - case BardHomeOpen: return "BardHomeOpen"; - case FjordNoMonsters: return "FjordNoMonsters"; - case ShandriaWallTalking: return "ShandriaWallTalking"; - case ShandriaWallCounter: return "ShandriaWallCounter"; - case ShandriaWallDone: return "ShandriaWallDone"; - case FutureDone: return "FutureDone"; - case TalkButch: return "TalkButch"; - case GotSzalik: return "GotSzalik"; - case GotCzosnek: return "GotCzosnek"; - case BearDone: return "BearDone"; - case NekrVisited: return "NekrVisited"; - case SunRiddle: return "SunRiddle"; - case PtaszekAway: return "PtaszekAway"; - case KotGadanie: return "KotGadanie"; - case SzlafmycaTaken: return "SzlafmycaTaken"; - case BabkaTalk: return "BabkaTalk"; - case SellerTalk: return "SellerTalk"; - case CzosnekDone: return "CzosnekDone"; - case PriestCounter: return "PriestCounter"; - case PriestGest1: return "PriestGest1"; - case PriestGest2: return "PriestGest2"; - case PriestGest3: return "PriestGest3"; - case PriestGest4: return "PriestGest4"; - case PriestAnim: return "PriestAnim"; - case HolyWaterTaken: return "HolyWaterTaken"; - case AxeTaken: return "AxeTaken"; - case BadylTaken1: return "BadylTaken1"; - case BadylTaken2: return "BadylTaken2"; - case BadylSharpened: return "BadylSharpened"; - case PorwanieSmoka: return "PorwanieSmoka"; - case ShopReOpen: return "ShopReOpen"; - case LuskaShown: return "LuskaShown"; - case CudKnow: return "CudKnow"; - case VampireDead: return "VampireDead"; - case MapaVisible1: return "MapaVisible1"; - case MapaVisible2: return "MapaVisible2"; - case MapaVisible3: return "MapaVisible3"; - case MapaVisible4: return "MapaVisible4"; - case MapaVisible5: return "MapaVisible5"; - case MapaVisible6: return "MapaVisible6"; - case MapaVisible7: return "MapaVisible7"; - case MapaVisible8: return "MapaVisible8"; - case MapaVisible9: return "MapaVisible9"; - case MapaX: return "MapaX"; - case MapaY: return "MapaY"; - case MapaD: return "MapaD"; - case OldMapaX: return "OldMapaX"; - case OldMapaY: return "OldMapaY"; - case OldMapaD: return "OldMapaD"; - case MovingBack: return "MovingBack"; - case MapaCount: return "MapaCount"; - case Pustelnia1st: return "Pustelnia1st"; - case CzarnePole1st: return "CzarnePole1st"; - case TalkArivNum: return "TalkArivNum"; - case Pfui: return "Pfui"; - case MapaSunlordEnabled:return "MapaSunlordEnabled"; - case WebDone: return "WebDone"; - case DragonDone: return "DragonDone"; - case KanPlay: return "KanPlay"; - case OldKanPlay: return "OldKanPlay"; - case LapkiWait: return "LapkiWait"; - case WebNoCheck: return "WebNoCheck"; - case Perfumeria: return "Perfumeria"; - case SmokNoCheck: return "SmokNoCheck"; - case IluzjaBroken: return "IluzjaBroken"; - case IluzjaWorking: return "IluzjaWorking"; - case IluzjaCounter: return "IluzjaCounter"; - case KurhanOpen1: return "KurhanOpen1"; - case KastetTaken: return "KastetTaken"; - case KastetDown: return "KastetDown"; - case KurhanDone: return "KurhanDone"; - case SkelCounter: return "SkelCounter"; - case SkelDial1: return "SkelDial1"; - case SkelDial2: return "SkelDial2"; - case SkelDial3: return "SkelDial3"; - case SkelDial4: return "SkelDial4"; - case SameTalker: return "SameTalker"; - case RunMonstersText: return "RunMonstersText"; - case PiwnicaChecked: return "PiwnicaChecked"; - case DragonTalked: return "DragonTalked"; - case ToldAboutBook: return "ToldAboutBook"; - case SilmanionaDone: return "SilmanionaDone"; - case ToldBookCount: return "ToldBookCount"; - case SmrodNoCheck: return "SmrodNoCheck"; - case RopeTaken: return "RopeTaken"; - case RopeTime: return "RopeTime"; - case LaskaFree: return "LaskaFree"; - case ShanSmokTalked: return "ShanSmokTalked"; - case SwordTaken: return "SwordTaken"; - case Mill1st: return "Mill1st"; - case SawRat: return "SawRat"; - case KnowRat: return "KnowRat"; - case DziuraTimer: return "DziuraTimer"; - case LaskaInside: return "LaskaInside"; - case HoleBig: return "HoleBig"; - case EnableWiedzmin: return "EnableWiedzmin"; - case EnableTrucizna: return "EnableTrucizna"; - case KnowPoison: return "KnowPoison"; - case KufelTaken: return "KufelTaken"; - case BojkaEnabled: return "BojkaEnabled"; - case BitwaNot1st: return "BitwaNot1st"; - case BojkaTimer: return "BojkaTimer"; - case BojkaGirl: return "BojkaGirl"; - case Look1st: return "Look1st"; - case RatTaken: return "RatTaken"; - case LaskaTalkedGr: return "LaskaTalkedGr"; - case RatusGivus: return "RatusGivus"; - case MamObole: return "MamObole"; - case Speed1st: return "Speed1st"; - case SpeedTimer: return "SpeedTimer"; - case ProveIt: return "ProveIt"; - case Proven: return "Proven"; - case ShowWoalka: return "ShowWoalka"; - case PoisonTaken: return "PoisonTaken"; - case HellOpened: return "HellOpened"; - case HellNoCheck: return "HellNoCheck"; - case TalAn1: return "TalAn1"; - case TalAn2: return "TalAn2"; - case TalAn3: return "TalAn3"; - case TalkDevilGuard: return "TalkDevilGuard"; - case Sword1st: return "Sword1st"; - case IluzjaNoCheck: return "IluzjaNoCheck"; - case RozdzielniaNumber: return "RozdzielniaNumber"; - case JailChecked: return "JailChecked"; - case JailTalked: return "JailTalked"; - case TrickFailed: return "TrickFailed"; - case WegielVisible: return "WegielVisible"; - case WegielTimer1: return "WegielTimer1"; - case RandomSample: return "RandomSample"; - case RandomSampleTimer: return "RandomSampleTimer"; - case SampleTimer: return "SampleTimer"; - case ZonaSample: return "ZonaSample"; - case HoleTryAgain: return "HoleTryAgain"; - case TeleportTimer: return "TeleportTimer"; - case RozLezy: return "RozLezy"; - case UdkoTimer: return "UdkoTimer"; - case ZaworZatkany: return "ZaworZatkany"; - case ZaworOpened: return "ZaworOpened"; - case DoorExploded: return "DoorExploded"; - case SkoraTaken: return "SkoraTaken"; - case CiezkieByl: return "CiezkieByl"; - case MamWegiel: return "MamWegiel"; - case SwiecaAway: return "SwiecaAway"; - case ITSAVE: return "ITSAVE"; - case RozpadlSie: return "RozpadlSie"; - case WegielFullTimer: return "WegielFullTimer"; - case WegielDown: return "WegielDown"; - case WegielDownTimer: return "WegielDownTimer"; - case PaliSie: return "PaliSie"; - case DiabGuardTalked: return "DiabGuardTalked"; - case GuardsNoCheck: return "GuardsNoCheck"; - case TalkedPowloka: return "TalkedPowloka"; - case JailOpen: return "JailOpen"; - case PrzytulTimer: return "PrzytulTimer"; - case JailDone: return "JailDone"; - case MamMonety: return "MamMonety"; - case LotTimer: return "LotTimer"; - case LotObj: return "LotObj"; - case PtakTimer: return "PtakTimer"; - case BookTimer: return "BookTimer"; - case BookGiba: return "BookGiba"; - case PtakLata: return "PtakLata"; - case Podej: return "Podej"; - case GotHint: return "GotHint"; - case LawaLeci: return "LawaLeci"; - case PowerKlik: return "PowerKlik"; - case LucekBad: return "LucekBad"; - case LucekBad1st: return "LucekBad1st"; - case IntroDial1: return "IntroDial1"; - case IntroDial2: return "IntroDial2"; - case ItsOutro: return "ItsOutro"; - case KamienComment: return "KamienComment"; - case KamienSkip: return "KamienSkip"; - case TesterFlag: return "TesterFlag"; - case RememberLine: return "RememberLine"; - case OpisLapek: return "OpisLapek"; - case TalWait: return "TalWait"; - case OpisKamienia: return "OpisKamienia"; - case JumpBox: return "JumpBox"; - case JumpBox1: return "JumpBox1"; - case JumpBox2: return "JumpBox2"; - case JumpBox3: return "JumpBox3"; - case SpecPiesek: return "SpecPiesek"; - case SpecPiesekCount: return "SpecPiesekCount"; - case SpecPiesekGadanie: return "SpecPiesekGadanie"; - case ZnikaFlag: return "ZnikaFlag"; - case ZnikaTimer: return "ZnikaTimer"; - case SowaTimer: return "SowaTimer"; - case MamrotanieOff: return "MamrotanieOff"; - - case CURRMOB: return "CURRMOB"; - case KOLOR: return "KOLOR"; - case MBFLAG: return "MBFLAG"; - case MXFLAG: return "MXFLAG"; - case MYFLAG: return "MYFLAG"; - case SCROLLTYPE: return "SCROLLTYPE"; - case SCROLLVALUE: return "SCROLLVALUE"; - case SCROLLVALUE2: return "SCROLLVALUE2"; - case TALKEXITCODE: return "TALKEXITCODE"; - case SPECROUTFLAG1: return "SPECROUTFLAG1"; - case SPECROUTFLAG2: return "SPECROUTFLAG2"; - case SPECROUTFLAG3: return "SPECROUTFLAG3"; - case TALKFLAGCODE: return "TALKFLAGCODE"; - case CURRROOM: return "CURRROOM"; - case Talker1Init: return "Talker1Init"; - case Talker2Init: return "Talker2Init"; - case RESTOREROOM: return "RESTOREROOM"; - case INVALLOWED: return "INVALLOWED"; - case BOXSEL: return "BOXSEL"; - case CURSEBLINK: return "CURSEBLINK"; - case EXACTMOVE: return "EXACTMOVE"; - case MOVEDESTX: return "MOVEDESTX"; - case MOVEDESTY: return "MOVEDESTY"; - case NOANTIALIAS: return "NOANTIALIAS"; - case ESCAPED: return "ESCAPED"; - case ALLOW1OPTION: return "ALLOW1OPTION"; - case VOICE_H_LINE: return "VOICE_H_LINE"; - case VOICE_A_LINE: return "VOICE_A_LINE"; - case VOICE_B_LINE: return "VOICE_B_LINE"; - case VOICE_C_LINE: return "VOICE_C_LINE"; - case NOHEROATALL: return "NOHEROATALL"; - case MOUSEENABLED: return "MOUSEENABLED"; - case DIALINES: return "DIALINES"; + FlagDebug *flagd = nullptr; + flagd = (FlagDebug *)bsearch(&flagId, _flagNames, kFlagDebugAmount, sizeof(FlagDebug), Flags::compareFlagDebug); + if (flagd != nullptr) { + return flagd->flagName; + } else { + return "unknown_flag"; + } +} - case SHANWALK: return "SHANWALK"; - case SHANDOG: return "SHANDOG"; - case GETACTIONBACK: return "GETACTIONBACK"; - case GETACTIONDATA: return "GETACTIONDATA"; - case GETACTION: return "GETACTION"; - case HEROFAST: return "HEROFAST"; - case SELITEM: return "SELITEM"; - case LMOUSE: return "LMOUSE"; - case MINMX: return "MINMX"; - case MAXMX: return "MAXMX"; - case MINMY: return "MINMY"; - case MAXMY: return "MAXMY"; - case TORX1: return "TORX1"; - case TORY1: return "TORY1"; - case TORX2: return "TORX2"; - case TORY2: return "TORY2"; - case POWER: return "POWER"; - case POWERENABLED: return "POWERENABLED"; - case FLCRESTORE: return "FLCRESTORE"; - case NOCLSTEXT: return "NOCLSTEXT"; - case ESCAPED2: return "ESCAPED2"; +int Flags::compareFlagDebug(const void *a, const void *b) { + const uint32 *flagId = (const uint32 *)a; + const FlagDebug *entry = (const FlagDebug *)b; + if (*flagId < (uint32)entry->id) { + return -1; + } else if (*flagId > (uint32)entry->id) { + return 1; } + return 0; } +const Flags::FlagDebug Flags::_flagNames[Flags::kFlagDebugAmount] = { + { Flags::FLAGA1, "FLAGA1" }, + { Flags::FLAGA2, "FLAGA2" }, + { Flags::FLAGA3, "FLAGA3" }, + { Flags::DESTX, "DESTX" }, + { Flags::DESTY, "DESTY" }, + { Flags::DESTD, "DESTD" }, + { Flags::DwarfDone, "DwarfDone" }, + { Flags::GRABARZCOUNTER, "GRABARZCOUNTER" }, + { Flags::KIERUNEK, "KIERUNEK" }, + { Flags::BACKFLAG1, "BACKFLAG1" }, + { Flags::BACKFLAG2, "BACKFLAG2" }, + { Flags::BACKFLAG3, "BACKFLAG3" }, + { Flags::BACKFLAG4, "BACKFLAG4" }, + { Flags::MACROFLAG1, "MACROFLAG1" }, + { Flags::MACROFLAG2, "MACROFLAG2" }, + { Flags::MACROFLAG3, "MACROFLAG3" }, + { Flags::HEROLDDONE, "HEROLDDONE" }, + { Flags::BRIDGESET, "BRIDGESET" }, + { Flags::U_BT_1, "U_BT_1" }, + { Flags::U_BT_2, "U_BT_2" }, + { Flags::U_BT_3, "U_BT_3" }, + { Flags::U_BT_4, "U_BT_4" }, + { Flags::U_BT_5, "U_BT_5" }, + { Flags::U_BT_6, "U_BT_6" }, + { Flags::U_BT_7, "U_BT_7" }, + { Flags::U_BT_8, "U_BT_8" }, + { Flags::U_BT_9, "U_BT_9" }, + { Flags::U_BT_COUNTER, "U_BT_COUNTER" }, + { Flags::ARIVALDALIVE, "ARIVALDALIVE" }, + { Flags::TALKCHAR1, "TALKCHAR1" }, + { Flags::TalkType1, "TalkType1" }, + { Flags::TALKROUT1, "TALKROUT1" }, + { Flags::TALKROUT2, "TALKROUT2" }, + { Flags::TALKROUT3, "TALKROUT3" }, + { Flags::TALKROUT4, "TALKROUT4" }, + { Flags::TALKANIM1, "TALKANIM1" }, + { Flags::TALKANIM2, "TALKANIM2" }, + { Flags::TALKCOLOR1, "TALKCOLOR1" }, + { Flags::TALKCOLOR2, "TALKCOLOR2" }, + { Flags::KapciuchTaken, "KapciuchTaken" }, + { Flags::CurrentBeggarA, "CurrentBeggarA" }, + { Flags::TempKapc, "TempKapc" }, + { Flags::HomTaken, "HomTaken" }, + { Flags::WizardTalk, "WizardTalk" }, + { Flags::SunlordTalk, "SunlordTalk" }, + { Flags::HermitTalk, "HermitTalk" }, + { Flags::RunyMode, "RunyMode" }, + { Flags::FatMerchantTalk, "FatMerchantTalk" }, + { Flags::HotDogTalk, "HotDogTalk" }, + { Flags::ThiefTalk, "ThiefTalk" }, + { Flags::BeggarTalk, "BeggarTalk" }, + { Flags::MonkTalk, "MonkTalk" }, + { Flags::BardTalk, "BardTalk" }, + { Flags::BarmanTalk, "BarmanTalk" }, + { Flags::LeftPlayerTalk, "LeftPlayerTalk" }, + { Flags::OczySowy, "OczySowy" }, + { Flags::CzachySpeed1, "CzachySpeed1" }, + { Flags::CzachySpeed2, "CzachySpeed2" }, + { Flags::CzachySpeed3, "CzachySpeed3" }, + { Flags::CzachySlowDown1, "CzachySlowDown1" }, + { Flags::CzachySlowDown2, "CzachySlowDown2" }, + { Flags::CzachySlowDown3, "CzachySlowDown3" }, + { Flags::FjordDane, "FjordDane" }, + { Flags::GKopany1, "GKopany1" }, + { Flags::GKopany2, "GKopany2" }, + { Flags::GKopany3, "GKopany3" }, + { Flags::GKopany4, "GKopany4" }, + { Flags::KnowGodWord, "KnowGodWord" }, + { Flags::TALKROUT21, "TALKROUT21" }, + { Flags::TALKROUT22, "TALKROUT22" }, + { Flags::TALKROUT23, "TALKROUT23" }, + { Flags::TALKROUT24, "TALKROUT24" }, + { Flags::TalkType2, "TalkType2" }, + { Flags::GrabarzTalk, "GrabarzTalk" }, + { Flags::LastTalker, "LastTalker" }, + { Flags::MapaPustelniaEnabled, "MapaPustelniaEnabled" }, + { Flags::MapaTempleEnabled, "MapaTempleEnabled" }, + { Flags::MapaFjordEnabled, "MapaFjordEnabled" }, + { Flags::MapaSilmanionaEnabled, "MapaSilmanionaEnabled" }, + { Flags::MapaKurhanEnabled, "MapaKurhanEnabled" }, + { Flags::MapaDragonEnabled, "MapaDragonEnabled" }, + { Flags::MapaMillEnabled, "MapaMillEnabled" }, + { Flags::DwarfRunning, "DwarfRunning" }, + { Flags::DwarfTalk, "DwarfTalk" }, + { Flags::CurseLift, "CurseLift" }, + { Flags::KosciSwapped, "KosciSwapped" }, + { Flags::BookStolen, "BookStolen" }, + { Flags::MapaUsable, "MapaUsable" }, + { Flags::FjordBoss, "FjordBoss" }, + { Flags::FjordHotDog, "FjordHotDog" }, + { Flags::FjordLewy, "FjordLewy" }, + { Flags::FjordPrawy, "FjordPrawy" }, + { Flags::TalkArivald, "TalkArivald" }, + { Flags::ShootDone, "ShootDone" }, + { Flags::ShootRunning, "ShootRunning" }, + { Flags::ShootKnow, "ShootKnow" }, + { Flags::MirrorKnow, "MirrorKnow" }, + { Flags::Gar1stTime, "Gar1stTime" }, + { Flags::KosciTaken, "KosciTaken" }, + { Flags::ArivGotSpell, "ArivGotSpell" }, + { Flags::BookGiven, "BookGiven" }, + { Flags::Wywieszka, "Wywieszka" }, + { Flags::TalkSheila, "TalkSheila" }, + { Flags::TalkSheila2, "TalkSheila2" }, + { Flags::BackHuman, "BackHuman" }, + { Flags::SkarbiecOpen, "SkarbiecOpen" }, + { Flags::LustroTaken, "LustroTaken" }, + { Flags::GargoyleHom, "GargoyleHom" }, + { Flags::GargoyleBroken, "GargoyleBroken" }, + { Flags::FjordDzien, "FjordDzien" }, + { Flags::GargoyleHom2, "GargoyleHom2" }, + { Flags::RunMonstersRunning, "RunMonstersRunning" }, + { Flags::FoundPaperInCoffin, "FoundPaperInCoffin" }, + { Flags::KnowSunlord, "KnowSunlord" }, + { Flags::KnowSunlordTalk, "KnowSunlordTalk" }, + { Flags::ArivaldCzyta, "ArivaldCzyta" }, + { Flags::TelepX, "TelepX" }, + { Flags::TelepY, "TelepY" }, + { Flags::TelepDir, "TelepDir" }, + { Flags::TelepRoom, "TelepRoom" }, + { Flags::ListStolen, "ListStolen" }, + { Flags::WifeInDoor, "WifeInDoor" }, + { Flags::TalkWifeFlag, "TalkWifeFlag" }, + { Flags::LetterGiven, "LetterGiven" }, + { Flags::LutniaTaken, "LutniaTaken" }, + { Flags::BardHomeOpen, "BardHomeOpen" }, + { Flags::FjordNoMonsters, "FjordNoMonsters" }, + { Flags::ShandriaWallTalking, "ShandriaWallTalking" }, + { Flags::ShandriaWallCounter, "ShandriaWallCounter" }, + { Flags::ShandriaWallDone, "ShandriaWallDone" }, + { Flags::FutureDone, "FutureDone" }, + { Flags::TalkButch, "TalkButch" }, + { Flags::GotSzalik, "GotSzalik" }, + { Flags::GotCzosnek, "GotCzosnek" }, + { Flags::BearDone, "BearDone" }, + { Flags::NekrVisited, "NekrVisited" }, + { Flags::SunRiddle, "SunRiddle" }, + { Flags::PtaszekAway, "PtaszekAway" }, + { Flags::KotGadanie, "KotGadanie" }, + { Flags::SzlafmycaTaken, "SzlafmycaTaken" }, + { Flags::BabkaTalk, "BabkaTalk" }, + { Flags::SellerTalk, "SellerTalk" }, + { Flags::CzosnekDone, "CzosnekDone" }, + { Flags::PriestCounter, "PriestCounter" }, + { Flags::PriestGest1, "PriestGest1" }, + { Flags::PriestGest2, "PriestGest2" }, + { Flags::PriestGest3, "PriestGest3" }, + { Flags::PriestGest4, "PriestGest4" }, + { Flags::PriestAnim, "PriestAnim" }, + { Flags::HolyWaterTaken, "HolyWaterTaken" }, + { Flags::AxeTaken, "AxeTaken" }, + { Flags::BadylTaken1, "BadylTaken1" }, + { Flags::BadylTaken2, "BadylTaken2" }, + { Flags::BadylSharpened, "BadylSharpened" }, + { Flags::PorwanieSmoka, "PorwanieSmoka" }, + { Flags::ShopReOpen, "ShopReOpen" }, + { Flags::LuskaShown, "LuskaShown" }, + { Flags::CudKnow, "CudKnow" }, + { Flags::VampireDead, "VampireDead" }, + { Flags::MapaVisible1, "MapaVisible1" }, + { Flags::MapaVisible2, "MapaVisible2" }, + { Flags::MapaVisible3, "MapaVisible3" }, + { Flags::MapaVisible4, "MapaVisible4" }, + { Flags::MapaVisible5, "MapaVisible5" }, + { Flags::MapaVisible6, "MapaVisible6" }, + { Flags::MapaVisible7, "MapaVisible7" }, + { Flags::MapaVisible8, "MapaVisible8" }, + { Flags::MapaVisible9, "MapaVisible9" }, + { Flags::MapaX, "MapaX" }, + { Flags::MapaY, "MapaY" }, + { Flags::MapaD, "MapaD" }, + { Flags::OldMapaX, "OldMapaX" }, + { Flags::OldMapaY, "OldMapaY" }, + { Flags::OldMapaD, "OldMapaD" }, + { Flags::MovingBack, "MovingBack" }, + { Flags::MapaCount, "MapaCount" }, + { Flags::Pustelnia1st, "Pustelnia1st" }, + { Flags::CzarnePole1st, "CzarnePole1st" }, + { Flags::TalkArivNum, "TalkArivNum" }, + { Flags::Pfui, "Pfui" }, + { Flags::MapaSunlordEnabled, "MapaSunlordEnabled" }, + { Flags::WebDone, "WebDone" }, + { Flags::DragonDone, "DragonDone" }, + { Flags::KanPlay, "KanPlay" }, + { Flags::OldKanPlay, "OldKanPlay" }, + { Flags::LapkiWait, "LapkiWait" }, + { Flags::WebNoCheck, "WebNoCheck" }, + { Flags::Perfumeria, "Perfumeria" }, + { Flags::SmokNoCheck, "SmokNoCheck" }, + { Flags::IluzjaBroken, "IluzjaBroken" }, + { Flags::IluzjaWorking, "IluzjaWorking" }, + { Flags::IluzjaCounter, "IluzjaCounter" }, + { Flags::KurhanOpen1, "KurhanOpen1" }, + { Flags::KastetTaken, "KastetTaken" }, + { Flags::KastetDown, "KastetDown" }, + { Flags::KurhanDone, "KurhanDone" }, + { Flags::SkelCounter, "SkelCounter" }, + { Flags::SkelDial1, "SkelDial1" }, + { Flags::SkelDial2, "SkelDial2" }, + { Flags::SkelDial3, "SkelDial3" }, + { Flags::SkelDial4, "SkelDial4" }, + { Flags::SameTalker, "SameTalker" }, + { Flags::RunMonstersText, "RunMonstersText" }, + { Flags::PiwnicaChecked, "PiwnicaChecked" }, + { Flags::DragonTalked, "DragonTalked" }, + { Flags::ToldAboutBook, "ToldAboutBook" }, + { Flags::SilmanionaDone, "SilmanionaDone" }, + { Flags::ToldBookCount, "ToldBookCount" }, + { Flags::SmrodNoCheck, "SmrodNoCheck" }, + { Flags::RopeTaken, "RopeTaken" }, + { Flags::RopeTime, "RopeTime" }, + { Flags::LaskaFree, "LaskaFree" }, + { Flags::ShanSmokTalked, "ShanSmokTalked" }, + { Flags::SwordTaken, "SwordTaken" }, + { Flags::Mill1st, "Mill1st" }, + { Flags::SawRat, "SawRat" }, + { Flags::KnowRat, "KnowRat" }, + { Flags::DziuraTimer, "DziuraTimer" }, + { Flags::LaskaInside, "LaskaInside" }, + { Flags::HoleBig, "HoleBig" }, + { Flags::EnableWiedzmin, "EnableWiedzmin" }, + { Flags::EnableTrucizna, "EnableTrucizna" }, + { Flags::KnowPoison, "KnowPoison" }, + { Flags::KufelTaken, "KufelTaken" }, + { Flags::BojkaEnabled, "BojkaEnabled" }, + { Flags::BitwaNot1st, "BitwaNot1st" }, + { Flags::BojkaTimer, "BojkaTimer" }, + { Flags::BojkaGirl, "BojkaGirl" }, + { Flags::Look1st, "Look1st" }, + { Flags::RatTaken, "RatTaken" }, + { Flags::LaskaTalkedGr, "LaskaTalkedGr" }, + { Flags::RatusGivus, "RatusGivus" }, + { Flags::MamObole, "MamObole" }, + { Flags::Speed1st, "Speed1st" }, + { Flags::SpeedTimer, "SpeedTimer" }, + { Flags::ProveIt, "ProveIt" }, + { Flags::Proven, "Proven" }, + { Flags::ShowWoalka, "ShowWoalka" }, + { Flags::PoisonTaken, "PoisonTaken" }, + { Flags::HellOpened, "HellOpened" }, + { Flags::HellNoCheck, "HellNoCheck" }, + { Flags::TalAn1, "TalAn1" }, + { Flags::TalAn2, "TalAn2" }, + { Flags::TalAn3, "TalAn3" }, + { Flags::TalkDevilGuard, "TalkDevilGuard" }, + { Flags::Sword1st, "Sword1st" }, + { Flags::IluzjaNoCheck, "IluzjaNoCheck" }, + { Flags::RozdzielniaNumber, "RozdzielniaNumber" }, + { Flags::JailChecked, "JailChecked" }, + { Flags::JailTalked, "JailTalked" }, + { Flags::TrickFailed, "TrickFailed" }, + { Flags::WegielVisible, "WegielVisible" }, + { Flags::WegielTimer1, "WegielTimer1" }, + { Flags::RandomSample, "RandomSample" }, + { Flags::RandomSampleTimer, "RandomSampleTimer" }, + { Flags::SampleTimer, "SampleTimer" }, + { Flags::ZonaSample, "ZonaSample" }, + { Flags::HoleTryAgain, "HoleTryAgain" }, + { Flags::TeleportTimer, "TeleportTimer" }, + { Flags::RozLezy, "RozLezy" }, + { Flags::UdkoTimer, "UdkoTimer" }, + { Flags::ZaworZatkany, "ZaworZatkany" }, + { Flags::ZaworOpened, "ZaworOpened" }, + { Flags::DoorExploded, "DoorExploded" }, + { Flags::SkoraTaken, "SkoraTaken" }, + { Flags::CiezkieByl, "CiezkieByl" }, + { Flags::MamWegiel, "MamWegiel" }, + { Flags::SwiecaAway, "SwiecaAway" }, + { Flags::ITSAVE, "ITSAVE" }, + { Flags::RozpadlSie, "RozpadlSie" }, + { Flags::WegielFullTimer, "WegielFullTimer" }, + { Flags::WegielDown, "WegielDown" }, + { Flags::WegielDownTimer, "WegielDownTimer" }, + { Flags::PaliSie, "PaliSie" }, + { Flags::DiabGuardTalked, "DiabGuardTalked" }, + { Flags::GuardsNoCheck, "GuardsNoCheck" }, + { Flags::TalkedPowloka, "TalkedPowloka" }, + { Flags::JailOpen, "JailOpen" }, + { Flags::PrzytulTimer, "PrzytulTimer" }, + { Flags::JailDone, "JailDone" }, + { Flags::MamMonety, "MamMonety" }, + { Flags::LotTimer, "LotTimer" }, + { Flags::LotObj, "LotObj" }, + { Flags::PtakTimer, "PtakTimer" }, + { Flags::BookTimer, "BookTimer" }, + { Flags::BookGiba, "BookGiba" }, + { Flags::PtakLata, "PtakLata" }, + { Flags::Podej, "Podej" }, + { Flags::GotHint, "GotHint" }, + { Flags::LawaLeci, "LawaLeci" }, + { Flags::PowerKlik, "PowerKlik" }, + { Flags::LucekBad, "LucekBad" }, + { Flags::LucekBad1st, "LucekBad1st" }, + { Flags::IntroDial1, "IntroDial1" }, + { Flags::IntroDial2, "IntroDial2" }, + { Flags::ItsOutro, "ItsOutro" }, + { Flags::KamienComment, "KamienComment" }, + { Flags::KamienSkip, "KamienSkip" }, + { Flags::TesterFlag, "TesterFlag" }, + { Flags::RememberLine, "RememberLine" }, + { Flags::OpisLapek, "OpisLapek" }, + { Flags::TalWait, "TalWait" }, + { Flags::OpisKamienia, "OpisKamienia" }, + { Flags::JumpBox, "JumpBox" }, + { Flags::JumpBox1, "JumpBox1" }, + { Flags::JumpBox2, "JumpBox2" }, + { Flags::JumpBox3, "JumpBox3" }, + { Flags::SpecPiesek, "SpecPiesek" }, + { Flags::SpecPiesekCount, "SpecPiesekCount" }, + { Flags::SpecPiesekGadanie, "SpecPiesekGadanie" }, + { Flags::ZnikaFlag, "ZnikaFlag" }, + { Flags::ZnikaTimer, "ZnikaTimer" }, + { Flags::SowaTimer, "SowaTimer" }, + { Flags::MamrotanieOff, "MamrotanieOff" }, + { Flags::CURRMOB, "CURRMOB" }, + { Flags::KOLOR, "KOLOR" }, + { Flags::MBFLAG, "MBFLAG" }, + { Flags::MXFLAG, "MXFLAG" }, + { Flags::MYFLAG, "MYFLAG" }, + { Flags::SCROLLTYPE, "SCROLLTYPE" }, + { Flags::SCROLLVALUE, "SCROLLVALUE" }, + { Flags::SCROLLVALUE2, "SCROLLVALUE2" }, + { Flags::TALKEXITCODE, "TALKEXITCODE" }, + { Flags::SPECROUTFLAG1, "SPECROUTFLAG1" }, + { Flags::SPECROUTFLAG2, "SPECROUTFLAG2" }, + { Flags::SPECROUTFLAG3, "SPECROUTFLAG3" }, + { Flags::TALKFLAGCODE, "TALKFLAGCODE" }, + { Flags::CURRROOM, "CURRROOM" }, + { Flags::Talker1Init, "Talker1Init" }, + { Flags::Talker2Init, "Talker2Init" }, + { Flags::RESTOREROOM, "RESTOREROOM" }, + { Flags::INVALLOWED, "INVALLOWED" }, + { Flags::BOXSEL, "BOXSEL" }, + { Flags::CURSEBLINK, "CURSEBLINK" }, + { Flags::EXACTMOVE, "EXACTMOVE" }, + { Flags::MOVEDESTX, "MOVEDESTX" }, + { Flags::MOVEDESTY, "MOVEDESTY" }, + { Flags::NOANTIALIAS, "NOANTIALIAS" }, + { Flags::ESCAPED, "ESCAPED" }, + { Flags::ALLOW1OPTION, "ALLOW1OPTION" }, + { Flags::VOICE_H_LINE, "VOICE_H_LINE" }, + { Flags::VOICE_A_LINE, "VOICE_A_LINE" }, + { Flags::VOICE_B_LINE, "VOICE_B_LINE" }, + { Flags::VOICE_C_LINE, "VOICE_C_LINE" }, + { Flags::NOHEROATALL, "NOHEROATALL" }, + { Flags::MOUSEENABLED, "MOUSEENABLED" }, + { Flags::DIALINES, "DIALINES" }, + { Flags::SHANWALK, "SHANWALK" }, + { Flags::SHANDOG, "SHANDOG" }, + { Flags::GETACTIONBACK, "GETACTIONBACK" }, + { Flags::GETACTIONDATA, "GETACTIONDATA" }, + { Flags::GETACTION, "GETACTION" }, + { Flags::HEROFAST, "HEROFAST" }, + { Flags::SELITEM, "SELITEM" }, + { Flags::LMOUSE, "LMOUSE" }, + { Flags::MINMX, "MINMX" }, + { Flags::MAXMX, "MAXMX" }, + { Flags::MINMY, "MINMY" }, + { Flags::MAXMY, "MAXMY" }, + { Flags::TORX1, "TORX1" }, + { Flags::TORY1, "TORY1" }, + { Flags::TORX2, "TORX2" }, + { Flags::TORY2, "TORY2" }, + { Flags::POWER, "POWER" }, + { Flags::POWERENABLED, "POWERENABLED" }, + { Flags::FLCRESTORE, "FLCRESTORE" }, + { Flags::NOCLSTEXT, "NOCLSTEXT" }, + { Flags::ESCAPED2, "ESCAPED2" }, +}; + } // End of namespace Prince diff --git a/engines/prince/flags.h b/engines/prince/flags.h index efa97eb5eda0..706f72826add 100644 --- a/engines/prince/flags.h +++ b/engines/prince/flags.h @@ -27,10 +27,9 @@ namespace Prince { -struct Flags { - - // TODO: Remove from release build - // useful just for debugging +class Flags { +public: + static int compareFlagDebug(const void *a, const void *b); static const char *getFlagName(uint16 flagId); enum Id { @@ -408,6 +407,14 @@ struct Flags { NOCLSTEXT = 0x846E, ESCAPED2 = 0x8470 }; + + struct FlagDebug { + Id id; + char flagName[30]; + }; + + static const int kFlagDebugAmount = 368; + static const FlagDebug _flagNames[kFlagDebugAmount]; }; } // End of namespace Prince From 78684333478cd567c820b930d0ba6663a0cecdd0 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 8 Oct 2014 17:51:32 +0200 Subject: [PATCH 363/374] PRINCE: Flags::Id - remove non-english comment --- engines/prince/flags.h | 1 - 1 file changed, 1 deletion(-) diff --git a/engines/prince/flags.h b/engines/prince/flags.h index 706f72826add..8337f82a953a 100644 --- a/engines/prince/flags.h +++ b/engines/prince/flags.h @@ -349,7 +349,6 @@ class Flags { ZnikaTimer = 0x8286, SowaTimer = 0x8288, MamrotanieOff = 0x828A, - // Flagi systemowe do kontroli przez skrypt // System flags controlled by script CURRMOB = 0x8400, KOLOR = 0x8402, From a554fa9f7d35679c36cb9149a080d9f8a1e5cbe4 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 8 Oct 2014 18:09:18 +0200 Subject: [PATCH 364/374] PRINCE: Changing all occurrences of NULL to nullptr To beconsistent and to keep just one of them --- engines/prince/archive.cpp | 4 +- engines/prince/hero.cpp | 6 +- engines/prince/hero_set.h | 162 ++++++++++++++++++------------------- engines/prince/prince.cpp | 2 +- engines/prince/prince.h | 2 +- engines/prince/sound.cpp | 4 +- 6 files changed, 90 insertions(+), 90 deletions(-) diff --git a/engines/prince/archive.cpp b/engines/prince/archive.cpp index 28f77cb4c42c..bc5d5d3818b8 100644 --- a/engines/prince/archive.cpp +++ b/engines/prince/archive.cpp @@ -29,7 +29,7 @@ namespace Prince { -PtcArchive::PtcArchive() : _stream(NULL) { +PtcArchive::PtcArchive() : _stream(nullptr) { } PtcArchive::~PtcArchive() { @@ -81,7 +81,7 @@ bool PtcArchive::open(const Common::String &filename) { void PtcArchive::close() { delete _stream; - _stream = NULL; + _stream = nullptr; _items.clear(); } diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index bc127b398b55..15dd7eb0544c 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -69,8 +69,8 @@ bool Hero::loadAnimSet(uint32 animSetNr) { _moveSet.resize(kMoveSetSize); for (uint32 i = 0; i < kMoveSetSize; i++) { debug("Anim set item %d %s", i, animSet[i]); - Animation *anim = NULL; - if (animSet[i] != NULL) { + Animation *anim = nullptr; + if (animSet[i] != nullptr) { anim = new Animation(); Resource::loadResource(anim, animSet[i], false); } @@ -93,7 +93,7 @@ Graphics::Surface *Hero::getSurface() { Graphics::Surface *heroFrame = heroAnim->getFrame(phaseFrameIndex); return heroFrame; } - return NULL; + return nullptr; } uint16 Hero::getData(AttrId dataId) { diff --git a/engines/prince/hero_set.h b/engines/prince/hero_set.h index 1674f67503ff..dfe7e502685a 100644 --- a/engines/prince/hero_set.h +++ b/engines/prince/hero_set.h @@ -33,28 +33,28 @@ static HeroSetAnimNames heroSet5 = { "SR_DIAB.ANI", "SU_DIAB.ANI", "SD_DIAB.ANI", - NULL, - NULL, + nullptr, + nullptr, "MU_DIAB.ANI", "MD_DIAB.ANI", "TL_DIAB.ANI", "TR_DIAB.ANI", "TU_DIAB.ANI", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr }; static HeroSetAnimNames heroSet1 = { @@ -70,18 +70,18 @@ static HeroSetAnimNames heroSet1 = { "TR_HERO1.ANI", "TU_HERO1.ANI", "TD_HERO1.ANI", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, "KSI_KURZ.ANI", "KS_WLOSY.ANI" }; @@ -99,18 +99,18 @@ static HeroSetAnimNames heroSet2 = { "TR_HERO2.ANI", "TU_HERO2.ANI", "TD_HERO2.ANI", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, "KSI_KU_S.ANI", "KS_WLO_S.ANI" }; @@ -140,8 +140,8 @@ static HeroSetAnimNames heroSet3 = { "N_PRZ-LW.ANI", "N_PRZ-PR.ANI", "N_PRZ-TL.ANI", - NULL, - NULL, + nullptr, + nullptr, }; static HeroSetAnimNames shanSet1 = { @@ -157,18 +157,18 @@ static HeroSetAnimNames shanSet1 = { "TR_SHAN.ANI", "TU_SHAN.ANI", "TD_SHAN.ANI", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, "B1_SHAN.ANI", "B2_SHAN.ANI", }; @@ -186,18 +186,18 @@ static HeroSetAnimNames shanSet2 = { "TR_SHAN2.ANI", "TU_SHAN.ANI", "TD_SHAN2.ANI", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, "B1_SHAN2.ANI", "B2_SHAN2.ANI" }; @@ -215,20 +215,20 @@ static HeroSetAnimNames arivSet1 = { "TR_ARIV.ANI", "TU_ARIV.ANI", "TD_ARIV.ANI", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr }; const HeroSetAnimNames *heroSetTable[7] = { diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 0267cf58bbf7..a0cb863dc25e 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2203,7 +2203,7 @@ void PrinceEngine::drawInvItems() { int drawX = currInvX; int drawY = currInvY; - Graphics::Surface *itemSurface = NULL; + Graphics::Surface *itemSurface = nullptr; if (itemNr != 68) { itemSurface = _allInvList[itemNr].getSurface(); if (itemSurface->h < _maxInvH) { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index d7519e2414e7..e6d56b283e6e 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -76,7 +76,7 @@ struct Text { uint16 _time; uint32 _color; - Text() : _str(NULL), _x(0), _y(0), _time(0), _color(255){ + Text() : _str(nullptr), _x(0), _y(0), _time(0), _color(255){ } }; diff --git a/engines/prince/sound.cpp b/engines/prince/sound.cpp index e58e89d8f9e2..032297ee4328 100644 --- a/engines/prince/sound.cpp +++ b/engines/prince/sound.cpp @@ -119,7 +119,7 @@ const uint8 MusicPlayer::_musRoomTable[] = { MusicPlayer::MusicPlayer(PrinceEngine *vm) : _vm(vm) { - _data = NULL; + _data = nullptr; _isGM = false; MidiPlayer::createDriver(); @@ -143,7 +143,7 @@ void MusicPlayer::killMidi() { Audio::MidiPlayer::stop(); free(_data); - _data = NULL; + _data = nullptr; } void MusicPlayer::loadMidi(const char *name) { From 4270a1a23ab54a3cb7efe7143725fcd64ba4cc8b Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 8 Oct 2014 20:56:59 +0200 Subject: [PATCH 365/374] PRINCE: GraphicsMan::drawTransparentWithTransDrawNode - add comments Add skipping anti-alias check for last pixel in row --- engines/prince/graphics.cpp | 42 +++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 2f021fe2231d..f54327fbf8c0 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -179,60 +179,102 @@ void GraphicsMan::drawTransparentDrawNode(Graphics::Surface *screen, DrawNode *d } } +/** + * Similar to drawTransparentDrawNode but with additional anti-aliasing code for sprite drawing. + * Edge smoothing is based on 256 x 256 table of colors transition. + * Algorithm is checking if currently drawing pixel is located next to the edge of sprite and if it makes jagged line. + * If it does then this pixel is set with color from transition table calculated of original background pixel color + * and sprite's edge pixel color. + */ void GraphicsMan::drawTransparentWithTransDrawNode(Graphics::Surface *screen, DrawNode *drawNode) { + // pos of first pixel for each row of source sprite byte *src1 = (byte *)drawNode->s->getBasePtr(0, 0); + // pos of drawing first pixel for each row on screen surface byte *dst1 = (byte *)screen->getBasePtr(drawNode->posX, drawNode->posY); + // trasition table for calculating new color value byte *transTableData = (byte *)drawNode->data; for (int y = 0; y < drawNode->s->h; y++) { if (y + drawNode->posY < screen->h && y + drawNode->posY >= 0) { + // current pixel in row of source sprite byte *src2 = src1; + // current pixel in row of screen surface byte *dst2 = dst1; for (int x = 0; x < drawNode->s->w; x++, src2++, dst2++) { if (x + drawNode->posX < screen->w && x + drawNode->posX >= 0) { if (*src2 != 255) { + // if source sprite pixel is not mask color than draw it normally *dst2 = *src2; } else { + // check for making jagged line if (x) { + // not first pixel in row if (*(src2 - 1) == 255) { + // if it has mask color to the left - check right if (x != drawNode->s->w - 1) { + // not last pixel in row if (*(src2 + 1) == 255) { + // pixel to the right with mask color - no anti-alias continue; } + // it's not mask color to the right - we continue checking + } else { + // last pixel in row, no right check - no anti-alias + continue; } } + // it's not mask color to the left - we continue checking } else if (x != drawNode->s->w - 1) { + // first pixel in row but not last - just right pixel checking if (*(src2 + 1) == 255) { + // pixel to the right with mask color - no anti-alias continue; } + // it's not mask color to the right - we continue checking } else { + // it's first and last pixel in row at the same time (width = 1) - no anti-alias continue; } byte value = 0; if (y != drawNode->s->h - 1) { + // not last row + // check pixel below of current src2 pixel value = *(src2 + drawNode->s->pitch); if (value == 255) { + // pixel below with mask color - check above if (y) { + // not first row value = *(src2 - drawNode->s->pitch); if (value == 255) { + // pixel above with mask color - no anti-alias continue; } + // it's not mask color above - we draw as transition color } else { + // first row - no anti-alias continue; } } + // it's not mask color below - we draw as transition color } else if (y) { + // last row - just check above value = *(src2 - drawNode->s->pitch); if (value == 255) { + // pixel above with mask color - no anti-alias continue; } + // it's not mask color above - we draw as transition color } else { + // first and last row at the same time (height = 1) - no anti-alias + // just for bugged animations continue; } + // new color value based on orginal screen surface color and sprite's edge pixel color *dst2 = transTableData[*dst2 * 256 + value]; } } } } + // adding pitch to jump to next row of pixels src1 += drawNode->s->pitch; dst1 += screen->pitch; } From f10ea31e3b07082fcfc659511a82521463cfd15f Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 8 Oct 2014 23:59:20 +0200 Subject: [PATCH 366/374] PRINCE: GraphicsMan - add some new comments --- engines/prince/graphics.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index f54327fbf8c0..40ecaf5d0b10 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -113,6 +113,10 @@ void GraphicsMan::drawTransparentSurface(Graphics::Surface *screen, int32 posX, change(); } +/** + * Similar to drawTransparentSurface but with use of shadowTable for color recalculation + * and kShadowColor (191) as a transparent color. + */ void GraphicsMan::drawAsShadowSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s, byte *shadowTable) { byte *src1 = (byte *)s->getBasePtr(0, 0); byte *dst1 = (byte *)screen->getBasePtr(posX, posY); @@ -133,6 +137,10 @@ void GraphicsMan::drawAsShadowSurface(Graphics::Surface *screen, int32 posX, int } } +/** + * Used in glowing animation for inventory items. Creates special blendTable array of colors, + * use black (0) as a transparent color. + */ void GraphicsMan::drawTransparentWithBlendSurface(Graphics::Surface *screen, int32 posX, int32 posY, const Graphics::Surface *s) { byte *src1 = (byte *)s->getBasePtr(0, 0); byte *dst1 = (byte *)screen->getBasePtr(posX, posY); @@ -159,6 +167,10 @@ void GraphicsMan::drawTransparentWithBlendSurface(Graphics::Surface *screen, int change(); } +/** + * Similar to drawTransparentSurface but with with use of DrawNode as argument for Z axis sorting + * and white (255) as transparent color. + */ void GraphicsMan::drawTransparentDrawNode(Graphics::Surface *screen, DrawNode *drawNode) { byte *src1 = (byte *)drawNode->s->getBasePtr(0, 0); byte *dst1 = (byte *)screen->getBasePtr(drawNode->posX, drawNode->posY); @@ -265,7 +277,6 @@ void GraphicsMan::drawTransparentWithTransDrawNode(Graphics::Surface *screen, Dr // it's not mask color above - we draw as transition color } else { // first and last row at the same time (height = 1) - no anti-alias - // just for bugged animations continue; } // new color value based on orginal screen surface color and sprite's edge pixel color From 257fd35f5a8c3df9820cc02bc607e8e372ff2309 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 9 Oct 2014 00:04:55 +0200 Subject: [PATCH 367/374] PRINCE: Hero::showHeroShadow - ct_loop variable rename to ctLoop --- engines/prince/hero.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 15dd7eb0544c..69afb06ea204 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -272,7 +272,7 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { // linear_loop for (int i = 0; i < heroSurfaceHeight; i++) { int shadSkipX = 0; - int ct_loop = 0; + int ctLoop = 0; int sprModulo = 0; int j; @@ -303,7 +303,7 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { if (shadPosX < 0) { shadSkipX = -1 * shadPosX; if (heroSurfaceWidth > shadSkipX) { - ct_loop = heroSurfaceWidth - shadSkipX; + ctLoop = heroSurfaceWidth - shadSkipX; shadowHeroX = shadSkipX; } else { //skip_line @@ -312,11 +312,11 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { } else { //x1_ok if (shadPosX + heroSurfaceWidth > 640) { - ct_loop = 640 - shadPosX; + ctLoop = 640 - shadPosX; sprModulo = shadPosX + heroSurfaceWidth - 640; } else { //draw_line - ct_loop = heroSurfaceWidth; + ctLoop = heroSurfaceWidth; } } @@ -370,7 +370,7 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { } //ct_loop: - for (int l = 0; l < ct_loop; l++) { + for (int l = 0; l < ctLoop; l++) { shadZoomX -= 100; if (shadZoomX < 0 && drawNode->scaleValue != 10000) { shadZoomX += drawNode->scaleValue; @@ -420,14 +420,14 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { background = shadWallDestAddr; shadowHero = (byte *)makeShadow->getBasePtr(shadWallSkipX, shadowHeroY); - if (ct_loop > shadWallSkipX && ct_loop - shadWallSkipX > shadWallModulo) { + if (ctLoop > shadWallSkipX && ctLoop - shadWallSkipX > shadWallModulo) { //WALL_copy_trans shadWDFlag = false; int shadZoomXWall = drawNode->scaleValue; int backgroundDiffWall = 0; int shadowHeroXWall = 0; //ct_loop: - for (int m = 0; m < ct_loop; m++) { + for (int m = 0; m < ctLoop; m++) { shadZoomXWall -= 100; if (shadZoomXWall < 0 && drawNode->scaleValue != 10000) { shadZoomXWall += drawNode->scaleValue; From ebd417fef4b56a2d1e0c8fa39e0d9766a4c2ed2d Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 9 Oct 2014 00:12:09 +0200 Subject: [PATCH 368/374] PRINCE: GraphicsMan::getBlendTableColor - change big number to INT_MAX --- engines/prince/graphics.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 40ecaf5d0b10..36760874c1dd 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -409,7 +409,7 @@ byte GraphicsMan::getBlendTableColor(byte pixelColor, byte backgroundPixelColor, } currColor = 0; - bigValue = 999999999; // infinity + bigValue = INT_MAX; // infinity for (int j = 0; j < 256; j++) { redSecondOrg = originalPalette[3 * j]; redNew = redFirstOrg - redSecondOrg; From f80d72d10ae78c29b21a4ca0533a2f1b05e729ac Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 9 Oct 2014 00:34:21 +0200 Subject: [PATCH 369/374] PRINCE: script.h - small comment correction --- engines/prince/script.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/prince/script.h b/engines/prince/script.h index 473163ed9ad2..fa7f9b74697e 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -255,8 +255,8 @@ class Interpreter { static const int kGiveLetterScriptFix = 79002; - // Keep opcode handlers names as they are in original code - // it easier to switch back and forth + // Keep opcode handlers names as they are in original code + // making it easier to switch back and forth void O_WAITFOREVER(); void O_BLACKPALETTE(); void O_SETUPPALETTE(); From 9db1d77d478fafe1ecd2d2723d4374a80bfba90e Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 9 Oct 2014 17:54:46 +0200 Subject: [PATCH 370/374] PRINCE: Remove readScript and LittleEndianReader templates from Script Change all of READ_UINT16 to READ_LE_UINT16 and all READ_UINT32 to READ_LE_UINT32 for endian-safety --- engines/prince/hero.cpp | 18 +++---- engines/prince/prince.cpp | 76 ++++++++++++++-------------- engines/prince/script.cpp | 103 ++++++++++++++++++++++---------------- engines/prince/script.h | 20 ++------ 4 files changed, 111 insertions(+), 106 deletions(-) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 69afb06ea204..8c13c6d1f992 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -462,18 +462,18 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { } //skip_line //next_line - if (READ_UINT16(shadowLineStart + 2) < READ_UINT16(shadowLineStart - 2)) { + if (READ_LE_UINT16(shadowLineStart + 2) < READ_LE_UINT16(shadowLineStart - 2)) { //minus_y shadBitAddr -= PrinceEngine::kMaxPicWidth / 8; shadPosY--; diffY--; - } else if (READ_UINT16(shadowLineStart + 2) > READ_UINT16(shadowLineStart - 2)) { + } else if (READ_LE_UINT16(shadowLineStart + 2) > READ_LE_UINT16(shadowLineStart - 2)) { shadBitAddr += PrinceEngine::kMaxPicWidth / 8; shadPosY++; diffY++; } //no_change_y - if (READ_UINT16(shadowLineStart) < READ_UINT16(shadowLineStart - 4)) { + if (READ_LE_UINT16(shadowLineStart) < READ_LE_UINT16(shadowLineStart - 4)) { //minus_x shadPosX--; //rol @@ -484,7 +484,7 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) { shadBitMask <<= 1; } diffX--; - } else if (READ_UINT16(shadowLineStart) > READ_UINT16(shadowLineStart - 4)) { + } else if (READ_LE_UINT16(shadowLineStart) > READ_LE_UINT16(shadowLineStart - 4)) { shadPosX++; //ror if (shadBitMask == 1) { @@ -752,9 +752,9 @@ void Hero::showHero() { //go_for_it: while (1) { if (_currCoords != nullptr) { - if (READ_UINT32(_currCoords) != 0xFFFFFFFF) { - x = READ_UINT16(_currCoords); - y = READ_UINT16(_currCoords + 2); + if (READ_LE_UINT32(_currCoords) != 0xFFFFFFFF) { + x = READ_LE_UINT16(_currCoords); + y = READ_LE_UINT16(_currCoords + 2); _currCoords += 4; dir = *_currDirTab; _currDirTab++; @@ -801,8 +801,8 @@ void Hero::showHero() { } } else { //finito - _middleX = READ_UINT16(_currCoords - 4); - _middleY = READ_UINT16(_currCoords - 2); + _middleX = READ_LE_UINT16(_currCoords - 4); + _middleY = READ_LE_UINT16(_currCoords - 2); selectZoom(); if (_coords != nullptr) { diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index a0cb863dc25e..98398e8d4e93 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -2160,8 +2160,8 @@ void PrinceEngine::prepareInventoryToView() { tempMobItem._name = ""; tempMobItem._examText = ""; - int txtOffset = READ_UINT32(&_invTxt[itemNr * 8]); - int examTxtOffset = READ_UINT32(&_invTxt[itemNr * 8 + 4]); + int txtOffset = READ_LE_UINT32(&_invTxt[itemNr * 8]); + int examTxtOffset = READ_LE_UINT32(&_invTxt[itemNr * 8 + 4]); stream.seek(txtOffset); while ((c = stream.readByte())) { @@ -2747,7 +2747,7 @@ void PrinceEngine::displayInventory() { void PrinceEngine::createDialogBox(int dialogBoxNr) { _dialogLines = 0; int amountOfDialogOptions = 0; - int dialogDataValue = (int)READ_UINT32(_dialogData); + int dialogDataValue = (int)READ_LE_UINT32(_dialogData); byte c; int sentenceNumber; @@ -2799,7 +2799,7 @@ void PrinceEngine::runDialog() { byte *dialogText = _dialogText; byte *dialogCurrentText = nullptr; int dialogSelected = -1; - int dialogDataValue = (int)READ_UINT32(_dialogData); + int dialogDataValue = (int)READ_LE_UINT32(_dialogData); while ((sentenceNumber = *dialogText) != 0xFF) { dialogText++; @@ -2871,7 +2871,7 @@ void PrinceEngine::dialogLeftMouseButton(byte *string, int dialogSelected) { _interpreter->setString(string); talkHero(0); - int dialogDataValue = (int)READ_UINT32(_dialogData); + int dialogDataValue = (int)READ_LE_UINT32(_dialogData); dialogDataValue |= (1u << dialogSelected); WRITE_UINT32(_dialogData, dialogDataValue); @@ -3776,7 +3776,7 @@ int PrinceEngine::cpe() { if ((*(_checkBitmap + kPBW) & _checkMask)) { switch (_checkMask) { case 128: - value = READ_UINT16(_checkBitmap - 1); + value = READ_LE_UINT16(_checkBitmap - 1); value &= 0x4001; if (value != 0x4001) { return 0; @@ -3825,7 +3825,7 @@ int PrinceEngine::cpe() { } break; case 1: - value = READ_UINT16(_checkBitmap); + value = READ_LE_UINT16(_checkBitmap); value &= 0x8002; if (value != 0x8002) { return 0; @@ -4130,8 +4130,8 @@ bool PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { } else if (drawLineFlag == -1 && _traceLineLen >= 2) { byte *tempCorrds = bcad; while (tempCorrds != _coords) { - x = READ_UINT16(tempCorrds); - y = READ_UINT16(tempCorrds + 2); + x = READ_LE_UINT16(tempCorrds); + y = READ_LE_UINT16(tempCorrds + 2); tempCorrds += 4; specialPlot2(x, y); } @@ -4203,13 +4203,13 @@ bool PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { byte *tempCoords = _coords; tempCoords -= 4; if (tempCoords > _coordsBuf) { - int tempX = READ_UINT16(tempCoords); - int tempY = READ_UINT16(tempCoords + 2); + int tempX = READ_LE_UINT16(tempCoords); + int tempY = READ_LE_UINT16(tempCoords + 2); if (_checkX == tempX && _checkY == tempY) { _coords = tempCoords; } - x = READ_UINT16(tempCoords); - y = READ_UINT16(tempCoords + 2); + x = READ_LE_UINT16(tempCoords); + y = READ_LE_UINT16(tempCoords + 2); } else { return false; } @@ -4261,10 +4261,10 @@ void PrinceEngine::approxPath() { if (tempCoordsBuf != tempCoords) { tempCoords -= 4; // last point on path while (tempCoordsBuf != tempCoords) { - x1 = READ_UINT16(tempCoords); - y1 = READ_UINT16(tempCoords + 2); - x2 = READ_UINT16(tempCoordsBuf); - y2 = READ_UINT16(tempCoordsBuf + 2); + x1 = READ_LE_UINT16(tempCoords); + y1 = READ_LE_UINT16(tempCoords + 2); + x2 = READ_LE_UINT16(tempCoordsBuf); + y2 = READ_LE_UINT16(tempCoordsBuf + 2); tempCoordsBuf += 4; //TracePoint oldCoords = _coords2; @@ -4273,8 +4273,8 @@ void PrinceEngine::approxPath() { WRITE_UINT16(_coords2 + 2, y1); _coords2 += 4; } else { - int testX = READ_UINT16(_coords2 - 4); - int testY = READ_UINT16(_coords2 - 2); + int testX = READ_LE_UINT16(_coords2 - 4); + int testY = READ_LE_UINT16(_coords2 - 2); if (testX != x1 || testY != y1) { WRITE_UINT16(_coords2, x1); WRITE_UINT16(_coords2 + 2, y1); @@ -4315,8 +4315,8 @@ int PrinceEngine::scanDirectionsFindNext(byte *tempCoordsBuf, int xDiff, int yDi } while (1) { - againPointX1 = READ_UINT16(tempCoordsBuf); - againPointY1 = READ_UINT16(tempCoordsBuf + 2); + againPointX1 = READ_LE_UINT16(tempCoordsBuf); + againPointY1 = READ_LE_UINT16(tempCoordsBuf + 2); tempCoordsBuf += 4; if (tempCoordsBuf == _coords) { @@ -4324,8 +4324,8 @@ int PrinceEngine::scanDirectionsFindNext(byte *tempCoordsBuf, int xDiff, int yDi break; } - dX = againPointX1 - READ_UINT16(tempCoordsBuf); - dY = againPointY1 - READ_UINT16(tempCoordsBuf + 2); + dX = againPointX1 - READ_LE_UINT16(tempCoordsBuf); + dY = againPointY1 - READ_LE_UINT16(tempCoordsBuf + 2); if (dX != xDiff) { direction = tempY; @@ -4352,14 +4352,14 @@ void PrinceEngine::scanDirections() { int x1, y1, x2, y2, xDiff, yDiff; while (1) { - x1 = READ_UINT16(tempCoordsBuf); - y1 = READ_UINT16(tempCoordsBuf + 2); + x1 = READ_LE_UINT16(tempCoordsBuf); + y1 = READ_LE_UINT16(tempCoordsBuf + 2); tempCoordsBuf += 4; if (tempCoordsBuf == _coords) { break; } - x2 = READ_UINT16(tempCoordsBuf); - y2 = READ_UINT16(tempCoordsBuf + 2); + x2 = READ_LE_UINT16(tempCoordsBuf); + y2 = READ_LE_UINT16(tempCoordsBuf + 2); xDiff = x1 - x2; yDiff = y1 - y2; @@ -4420,8 +4420,8 @@ void PrinceEngine::moveShandria() { _secondHero->freeHeroAnim(); _secondHero->freeOldMove(); byte *shanCoords = _mainHero->_currCoords + shanLen1 * 4 - 4; - int shanX = READ_UINT16(shanCoords - 4); - int shanY = READ_UINT16(shanCoords - 2); + int shanX = READ_LE_UINT16(shanCoords - 4); + int shanY = READ_LE_UINT16(shanCoords - 2); int xDiff = shanX - _secondHero->_middleX; if (xDiff < 0) { xDiff *= -1; @@ -4440,8 +4440,8 @@ void PrinceEngine::moveShandria() { if (shanCoords == _mainHero->_currCoords) { break; } - int x = READ_UINT16(shanCoords); - int y = READ_UINT16(shanCoords + 2); + int x = READ_LE_UINT16(shanCoords); + int y = READ_LE_UINT16(shanCoords + 2); int pointDiffX = x - shanX; if (pointDiffX < 0) { pointDiffX *= -1; @@ -4459,8 +4459,8 @@ void PrinceEngine::moveShandria() { int pathSizeDiff = (shanCoords - _mainHero->_currCoords) / 4; int destDir = *(_mainHero->_currDirTab + pathSizeDiff); _secondHero->_destDirection = destDir; - int destX = READ_UINT16(shanCoords); - int destY = READ_UINT16(shanCoords + 2); + 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; @@ -4571,15 +4571,15 @@ byte *PrinceEngine::makePath(int heroId, int currX, int currY, int destX, int de if (choosenLength) { if (chosenCoordsBuf != nullptr) { - int tempXBegin = READ_UINT16(chosenCoordsBuf); - int tempYBegin = READ_UINT16(chosenCoordsBuf + 2); + int tempXBegin = READ_LE_UINT16(chosenCoordsBuf); + int tempYBegin = READ_LE_UINT16(chosenCoordsBuf + 2); if (stX != tempXBegin || stY != tempYBegin) { SWAP(chosenCoordsBuf, choosenCoords); chosenCoordsBuf -= 4; int cord; byte *tempCoordsBuf = _coordsBuf; while (1) { - cord = READ_UINT32(chosenCoordsBuf); + cord = READ_LE_UINT32(chosenCoordsBuf); WRITE_UINT32(tempCoordsBuf, cord); tempCoordsBuf += 4; if (chosenCoordsBuf == choosenCoords) { @@ -4611,10 +4611,10 @@ byte *PrinceEngine::makePath(int heroId, int currX, int currY, int destX, int de newCoords = (byte *)malloc(normCoordsSize); newCoordsBegin = newCoords; while (tempCoordsBuf != tempCoords) { - newValueX = READ_UINT16(tempCoordsBuf); + newValueX = READ_LE_UINT16(tempCoordsBuf); WRITE_UINT16(newCoords, newValueX * 2); newCoords += 2; - newValueY = READ_UINT16(tempCoordsBuf + 2); + newValueY = READ_LE_UINT16(tempCoordsBuf + 2); WRITE_UINT16(newCoords, newValueY * 2); newCoords += 2; tempCoordsBuf += 4; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 09f45af2e4ad..0181f6912ddf 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -135,16 +135,28 @@ bool Script::loadStream(Common::SeekableReadStream &stream) { return true; } +uint16 Script::readScript16(uint32 address) { + assert((_data + address + sizeof(uint16)) <= (_data + _dataSize)); + uint16 data = READ_LE_UINT16(&_data[address]); + return data; +} + +uint32 Script::readScript32(uint32 address) { + assert((_data + address + sizeof(uint32)) <= (_data + _dataSize)); + uint32 data = READ_LE_UINT32(&_data[address]); + return data; +} + int16 Script::getLightX(int locationNr) { - return (int)READ_UINT16(&_data[_scriptInfo.lightSources + locationNr * 8]); + return (int)READ_LE_UINT16(&_data[_scriptInfo.lightSources + locationNr * 8]); } int16 Script::getLightY(int locationNr) { - return (int)READ_UINT16(&_data[_scriptInfo.lightSources + locationNr * 8 + 2]); + return (int)READ_LE_UINT16(&_data[_scriptInfo.lightSources + locationNr * 8 + 2]); } int32 Script::getShadowScale(int locationNr) { - return (int)READ_UINT16(&_data[_scriptInfo.lightSources + locationNr * 8 + 4]); + return (int)READ_LE_UINT16(&_data[_scriptInfo.lightSources + locationNr * 8 + 4]); } uint32 Script::getStartGameOffset() { @@ -152,7 +164,7 @@ uint32 Script::getStartGameOffset() { } uint32 Script::getLocationInitScript(int initRoomTableOffset, int roomNr) { - return (uint32)READ_UINT32(&_data[initRoomTableOffset + roomNr * 4]); + return (uint32)READ_LE_UINT32(&_data[initRoomTableOffset + roomNr * 4]); } byte Script::getMobVisible(int roomMobOffset, uint16 mob) { @@ -193,7 +205,7 @@ uint8 *Script::getHeroAnimName(int offset) { } uint32 Script::getBackAnimId(int roomBackAnimOffset, int slot) { - uint32 animId = READ_UINT32(&_data[roomBackAnimOffset + slot * 4]); + uint32 animId = READ_LE_UINT32(&_data[roomBackAnimOffset + slot * 4]); return animId; } @@ -215,9 +227,9 @@ int Script::scanMobEvents(int mobMask, int dataEventOffset) { int16 mob; int32 code; do { - mob = (int)READ_UINT16(&_data[dataEventOffset + i * 6]); + mob = (int)READ_LE_UINT16(&_data[dataEventOffset + i * 6]); if (mob == mobMask) { - code = (int)READ_UINT32(&_data[dataEventOffset + i * 6 + 2]); + code = (int)READ_LE_UINT32(&_data[dataEventOffset + i * 6 + 2]); debug("code: %d", code); return code; } @@ -233,11 +245,11 @@ int Script::scanMobEventsWithItem(int mobMask, int dataEventOffset, int itemMask int16 item; int32 code; do { - mob = (int)READ_UINT16(&_data[dataEventOffset + i * 8]); + mob = (int)READ_LE_UINT16(&_data[dataEventOffset + i * 8]); if (mob == mobMask) { - item = (int)READ_UINT16(&_data[dataEventOffset + i * 8 + 2]); + item = (int)READ_LE_UINT16(&_data[dataEventOffset + i * 8 + 2]); if (item == itemMask) { - code = (int)READ_UINT32(&_data[dataEventOffset + i * 8 + 4]); + code = (int)READ_LE_UINT32(&_data[dataEventOffset + i * 8 + 4]); debug("itemMask: %d", item); debug("code: %d", code); return code; @@ -256,8 +268,8 @@ void Script::installSingleBackAnim(Common::Array &backAnimList, BackgroundAnim newBackgroundAnim; // BackgroundAnim seq data and its array of Anim - int animOffset = READ_UINT32(&_data[offset]); // pos of BackgroundAnim data in script - int anims = READ_UINT32(&_data[animOffset + 8]); // amount of Anim in BackgroundAnim + int animOffset = READ_LE_UINT32(&_data[offset]); // pos of BackgroundAnim data in script + int anims = READ_LE_UINT32(&_data[animOffset + 8]); // amount of Anim in BackgroundAnim if (anims == 0) { anims = 1; // anims with 0 as amount in game data has just 1 animation @@ -463,7 +475,7 @@ uint32 Interpreter::step(uint32 opcodePC) { _lastInstruction = _currentInstruction; // Get the current opcode - _lastOpcode = readScript(); + _lastOpcode = readScript16(); if (_lastOpcode > kNumOpcodes) error( @@ -538,15 +550,20 @@ void Interpreter::setFgOpcodePC(uint32 value) { _fgOpcodePC = value; } -template -T Interpreter::readScript() { - T data = _script->read(_currentInstruction); - _currentInstruction += sizeof(data); +uint16 Interpreter::readScript16() { + uint16 data = _script->readScript16(_currentInstruction); + _currentInstruction += sizeof(uint16); + return data; +} + +uint32 Interpreter::readScript32() { + uint32 data = _script->readScript32(_currentInstruction); + _currentInstruction += sizeof(uint32); return data; } int32 Interpreter::readScriptFlagValue() { - uint16 value = readScript(); + uint16 value = readScript16(); if (value & InterpreterFlags::kFlagMask) { return _flags->getFlagValue((Flags::Id)value); } @@ -554,7 +571,7 @@ int32 Interpreter::readScriptFlagValue() { } Flags::Id Interpreter::readScriptFlagId() { - return (Flags::Id)readScript(); + return (Flags::Id)readScript16(); } void Interpreter::O_WAITFOREVER() { @@ -583,7 +600,7 @@ void Interpreter::O_INITROOM() { void Interpreter::O_SETSAMPLE() { int32 sampleId = readScriptFlagValue(); - int32 sampleNameOffset = readScript(); + int32 sampleNameOffset = readScript32(); const char *sampleName = _script->getString(_currentInstruction + sampleNameOffset - 4); _vm->loadSample(sampleId, sampleName); debugInterpreter("O_SETSAMPLE %d %s", sampleId, sampleName); @@ -597,7 +614,7 @@ void Interpreter::O_FREESAMPLE() { void Interpreter::O_PLAYSAMPLE() { int32 sampleId = readScriptFlagValue(); - uint16 loopType = readScript(); + uint16 loopType = readScript16(); _vm->playSample(sampleId, loopType); debugInterpreter("O_PLAYSAMPLE sampleId %d loopType %d", sampleId, loopType); } @@ -697,7 +714,7 @@ void Interpreter::O_CHECKANIMFRAME() { void Interpreter::O_PUTBACKANIM() { int32 roomId = readScriptFlagValue(); int32 slot = readScriptFlagValue(); - int32 animId = readScript(); + int32 animId = readScript32(); Room *room = new Room(); room->loadRoom(_script->getRoomOffset(roomId)); _vm->_script->setBackAnimId(room->_backAnim, slot, animId); @@ -738,7 +755,7 @@ void Interpreter::O_FREEALLSAMPLES() { } void Interpreter::O_SETMUSIC() { - uint16 musicId = readScript(); + uint16 musicId = readScript16(); _vm->loadMusic(musicId); debugInterpreter("O_SETMUSIC musicId %d", musicId); } @@ -787,7 +804,7 @@ void Interpreter::O_CLS() { } void Interpreter::O__CALL() { - int32 address = readScript(); + int32 address = readScript32(); _stack[_stacktop] = _currentInstruction; _stacktop++; _currentInstruction += address - 4; @@ -805,7 +822,7 @@ void Interpreter::O_RETURN() { } void Interpreter::O_GO() { - int32 opPC = readScript(); + int32 opPC = readScript32(); _currentInstruction += opPC - 4; debugInterpreter("O_GO 0x%04X", opPC); } @@ -854,7 +871,7 @@ void Interpreter::O_COMPARE() { } void Interpreter::O_JUMPZ() { - int32 offset = readScript(); + int32 offset = readScript32(); if (!_result) { _currentInstruction += offset - 4; } @@ -862,7 +879,7 @@ void Interpreter::O_JUMPZ() { } void Interpreter::O_JUMPNZ() { - int32 offset = readScript(); + int32 offset = readScript32(); if (_result) { _currentInstruction += offset - 4; } @@ -913,7 +930,7 @@ void Interpreter::O_SUBFLAG() { } void Interpreter::O_SETSTRING() { - int32 offset = readScript(); + int32 offset = readScript32(); _currentString = offset; if (offset >= 80000) { _string = _vm->_variaTxt->getString(offset - 80000); @@ -1073,7 +1090,7 @@ void Interpreter::O_CLSTEXT() { void Interpreter::O_CALLTABLE() { Flags::Id flagId = readScriptFlagId(); int roomNr = _flags->getFlagValue(flagId); - int32 tableOffset = readScript(); + int32 tableOffset = readScript32(); int initLocationScript = _script->getLocationInitScript(tableOffset, roomNr); if (initLocationScript) { _stack[_stacktop] = _currentInstruction; @@ -1214,7 +1231,7 @@ void Interpreter::O_WAITTEXT() { void Interpreter::O_SETHEROANIM() { int32 heroId = readScriptFlagValue(); - int32 offset = readScript(); + int32 offset = readScript32(); Hero *hero = nullptr; if (!heroId) { hero = _vm->_mainHero; @@ -1323,7 +1340,7 @@ void Interpreter::O_GETANIMDATA() { } void Interpreter::O_SETBGCODE() { - int32 offset = readScript(); + int32 offset = readScript32(); _bgOpcodePC = _currentInstruction + offset - 4; debugInterpreter("O_SETBGCODE next %08x, offset %08x", _bgOpcodePC, offset); } @@ -1340,7 +1357,7 @@ void Interpreter::O_SETBACKFRAME() { void Interpreter::O_GETRND() { Flags::Id flag = readScriptFlagId(); - uint16 rndSeed = readScript(); + uint16 rndSeed = readScript16(); int value = _vm->_randomSource.getRandomNumber(rndSeed - 1); _flags->setFlagValue(flag, value); debugInterpreter("O_GETRND flag %d, rndSeed %d, value %d", flag, rndSeed, value); @@ -1355,7 +1372,7 @@ void Interpreter::O_TALKBACKANIM() { // Simplifying, because used only once in Location 20 void Interpreter::O_LOADPATH() { - readScript(); + readScript32(); _vm->loadPath("path2"); debugInterpreter("O_LOADPATH - path2"); } @@ -1369,7 +1386,7 @@ void Interpreter::O_GETCHAR() { void Interpreter::O_SETDFLAG() { Flags::Id flagId = readScriptFlagId(); - int32 address = readScript(); + int32 address = readScript32(); _flags->setFlagValue((Flags::Id)(flagId), _currentInstruction + address - 4); debugInterpreter("O_SETDFLAG 0x%04X (%s) = 0x%04X", flagId, Flags::getFlagName(flagId), _currentInstruction + address - 4); } @@ -1482,7 +1499,7 @@ void Interpreter::O_INITDIALOG() { byte *stringCurrOff = _string; byte *string = _string; stringCurrOff++; - int32 adressOfFirstSequence = (int)READ_UINT16(stringCurrOff); + int32 adressOfFirstSequence = (int)READ_LE_UINT16(stringCurrOff); stringCurrOff += 2; _string = string + adressOfFirstSequence; @@ -1499,7 +1516,7 @@ void Interpreter::O_INITDIALOG() { byte *line = nullptr; int dialogBox = 0; - while ((off = (int)READ_UINT16(stringCurrOff)) != -1) { + while ((off = (int)READ_LE_UINT16(stringCurrOff)) != -1) { stringCurrOff += 2; if (off) { line = string + off; @@ -1510,7 +1527,7 @@ void Interpreter::O_INITDIALOG() { stringCurrOff += 2; int dialogOpt = 0; - while ((off = (int)READ_UINT16(stringCurrOff)) != -1) { + while ((off = (int)READ_LE_UINT16(stringCurrOff)) != -1) { stringCurrOff += 2; if (off) { line = string + off; @@ -1548,7 +1565,7 @@ void Interpreter::O_INITDIALOG() { void Interpreter::O_ENABLEDIALOGOPT() { int32 opt = readScriptFlagValue(); - int dialogDataValue = (int)READ_UINT32(_vm->_dialogData); + int dialogDataValue = (int)READ_LE_UINT32(_vm->_dialogData); dialogDataValue &= ~(1u << opt); WRITE_UINT32(_vm->_dialogData, dialogDataValue); debugInterpreter("O_ENABLEDIALOGOPT opt %d", opt); @@ -1556,7 +1573,7 @@ void Interpreter::O_ENABLEDIALOGOPT() { void Interpreter::O_DISABLEDIALOGOPT() { int32 opt = readScriptFlagValue(); - int dialogDataValue = (int)READ_UINT32(_vm->_dialogData); + int dialogDataValue = (int)READ_LE_UINT32(_vm->_dialogData); dialogDataValue |= (1u << opt); WRITE_UINT32(_vm->_dialogData, dialogDataValue); debugInterpreter("O_DISABLEDIALOGOPT opt %d", opt); @@ -1584,7 +1601,7 @@ void Interpreter::O_STOPSAMPLE() { void Interpreter::O_BACKANIMRANGE() { int32 slotId = readScriptFlagValue(); - uint16 animId = readScript(); + uint16 animId = readScript16(); int32 low = readScriptFlagValue(); int32 high = readScriptFlagValue(); if (animId != 0xFFFF) { @@ -1672,7 +1689,7 @@ void Interpreter::O_POPSTRING() { } void Interpreter::O_SETFGCODE() { - int32 offset = readScript(); + int32 offset = readScript32(); _fgOpcodePC = _currentInstruction + offset - 4; debugInterpreter("O_SETFGCODE next %08x, offset %08x", _fgOpcodePC, offset); } @@ -1723,8 +1740,8 @@ void Interpreter::O_RUNHERO() { } void Interpreter::O_SETBACKANIMDATA() { - uint16 animNumber = readScript(); - uint16 animDataOffset = readScript(); + uint16 animNumber = readScript16(); + uint16 animDataOffset = readScript16(); Flags::Id flagId = readScriptFlagId(); uint16 value = _flags->getFlagValue((Flags::Id)(flagId)); int currAnim = _vm->_backAnimList[animNumber]._seq._currRelative; diff --git a/engines/prince/script.h b/engines/prince/script.h index fa7f9b74697e..4799e849447b 100644 --- a/engines/prince/script.h +++ b/engines/prince/script.h @@ -39,13 +39,6 @@ struct Anim; struct BackgroundAnim; struct Mask; -// TODO - change this to sth else? -namespace Detail { - template T LittleEndianReader(void *data); - template <> inline uint16 LittleEndianReader(void *data) { return READ_LE_UINT16(data); } - template <> inline uint32 LittleEndianReader(void *data) { return READ_LE_UINT32(data); } -} - class Room { public: Room(); @@ -125,11 +118,8 @@ class Script { bool loadStream(Common::SeekableReadStream &stream); - template - T read(uint32 address) { - assert((_data + address + sizeof(T)) <= (_data + _dataSize)); - return Detail::LittleEndianReader(&_data[address]); - } + uint16 readScript16(uint32 address); + uint32 readScript32(uint32 address); uint32 getStartGameOffset(); uint32 getLocationInitScript(int initRoomTableOffset, int roomNr); @@ -240,14 +230,12 @@ class Interpreter { // Helper functions uint32 step(uint32 opcodePC); - + uint16 readScript16(); + uint32 readScript32(); int32 readScriptFlagValue(); Flags::Id readScriptFlagId(); int checkSeq(byte *string); - // instantiation not needed here - template T readScript(); - void debugInterpreter(const char *s, ...); typedef void (Interpreter::*OpcodeFunc)(); From 081ad221d553349203336a6623e93358b30697d1 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 9 Oct 2014 18:28:30 +0200 Subject: [PATCH 371/374] PRINCE: Change ADGameFlag in gameDescriptions to ADGF_TESTING --- engines/prince/detection.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/prince/detection.h b/engines/prince/detection.h index e8f225690e09..5cc0d32be48a 100644 --- a/engines/prince/detection.h +++ b/engines/prince/detection.h @@ -46,7 +46,7 @@ static const PrinceGameDescription gameDescriptions[] = { AD_ENTRY1s("databank.ptc", "5fa03833177331214ec1354761b1d2ee", 3565031), Common::DE_DEU, Common::kPlatformWindows, - ADGF_NO_FLAGS, + ADGF_TESTING, GUIO1(GUIO_NONE) }, 0 @@ -58,7 +58,7 @@ static const PrinceGameDescription gameDescriptions[] = { AD_ENTRY1s("databank.ptc", "48ec9806bda9d152acbea8ce31c93c49", 3435298), Common::PL_POL, Common::kPlatformWindows, - ADGF_NO_FLAGS, + ADGF_TESTING, GUIO1(GUIO_NONE) }, 1 From 0e6ae70d9b94ace8665faeca5666c08c8b7ecf2b Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 9 Oct 2014 18:43:17 +0200 Subject: [PATCH 372/374] PRINCE: Fix INT_MAX error - change it to kIntMax constant --- engines/prince/graphics.cpp | 2 +- engines/prince/prince.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 36760874c1dd..cd4b62f7a5ab 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -409,7 +409,7 @@ byte GraphicsMan::getBlendTableColor(byte pixelColor, byte backgroundPixelColor, } currColor = 0; - bigValue = INT_MAX; // infinity + bigValue = PrinceEngine::kIntMax; // infinity for (int j = 0; j < 256; j++) { redSecondOrg = originalPalette[3 * j]; redNew = redFirstOrg - redSecondOrg; diff --git a/engines/prince/prince.h b/engines/prince/prince.h index e6d56b283e6e..3d10c671f085 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -353,6 +353,7 @@ class PrinceEngine : public Engine { static void plotShadowLinePoint(int x, int y, int color, void *data); static const int16 kFPS = 15; + static const int32 kIntMax = 2147483647; static const int16 kMaxPicWidth = 1280; static const int16 kMaxPicHeight = 480; From c9c93b4b4dd20c094da57729a96abb0b978de40f Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 9 Oct 2014 21:01:31 +0200 Subject: [PATCH 373/374] PRINCE: Change all WRITE_UINT16 to WRITE_LE_UINT16 and all WRITE_UINT32 to WRITE_LE_UINT32 for endian-safety fix --- engines/prince/prince.cpp | 40 +++++++++++++++++++-------------------- engines/prince/script.cpp | 6 +++--- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 98398e8d4e93..51748b30d9eb 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -533,8 +533,8 @@ void PrinceEngine::setShadowScale(int32 shadowScale) { void PrinceEngine::plotShadowLinePoint(int x, int y, int color, void *data) { PrinceEngine *vm = (PrinceEngine *)data; - WRITE_UINT16(&vm->_shadowLine[vm->_shadLineLen * 4], x); - WRITE_UINT16(&vm->_shadowLine[vm->_shadLineLen * 4 + 2], y); + WRITE_LE_UINT16(&vm->_shadowLine[vm->_shadLineLen * 4], x); + WRITE_LE_UINT16(&vm->_shadowLine[vm->_shadLineLen * 4 + 2], y); vm->_shadLineLen++; } @@ -2873,7 +2873,7 @@ void PrinceEngine::dialogLeftMouseButton(byte *string, int dialogSelected) { int dialogDataValue = (int)READ_LE_UINT32(_dialogData); dialogDataValue |= (1u << dialogSelected); - WRITE_UINT32(_dialogData, dialogDataValue); + WRITE_LE_UINT32(_dialogData, dialogDataValue); _flags->setFlagValue(Flags::BOXSEL, dialogSelected + 1); setVoice(0, 28, dialogSelected + 1); @@ -3296,9 +3296,9 @@ Direction PrinceEngine::makeDirection(int x1, int y1, int x2, int y2) { void PrinceEngine::specialPlot(int x, int y) { if (_coords < _coordsBufEnd) { - WRITE_UINT16(_coords, x); + WRITE_LE_UINT16(_coords, x); _coords += 2; - WRITE_UINT16(_coords, y); + WRITE_LE_UINT16(_coords, y); _coords += 2; specialPlot2(x, y); } @@ -3311,9 +3311,9 @@ void PrinceEngine::specialPlot2(int x, int y) { void PrinceEngine::specialPlotInside(int x, int y) { if (_coords < _coordsBufEnd) { - WRITE_UINT16(_coords, x); + WRITE_LE_UINT16(_coords, x); _coords += 2; - WRITE_UINT16(_coords, y); + WRITE_LE_UINT16(_coords, y); _coords += 2; } } @@ -4231,9 +4231,9 @@ bool PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { } void PrinceEngine::specialPlotInside2(int x, int y) { - WRITE_UINT16(_coords2, x); + WRITE_LE_UINT16(_coords2, x); _coords2 += 2; - WRITE_UINT16(_coords2, y); + WRITE_LE_UINT16(_coords2, y); _coords2 += 2; } @@ -4269,15 +4269,15 @@ void PrinceEngine::approxPath() { //TracePoint oldCoords = _coords2; if (_coords2 == _coordsBuf2) { - WRITE_UINT16(_coords2, x1); - WRITE_UINT16(_coords2 + 2, y1); + 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_UINT16(_coords2, x1); - WRITE_UINT16(_coords2 + 2, y1); + WRITE_LE_UINT16(_coords2, x1); + WRITE_LE_UINT16(_coords2 + 2, y1); _coords2 += 4; } } @@ -4580,7 +4580,7 @@ byte *PrinceEngine::makePath(int heroId, int currX, int currY, int destX, int de byte *tempCoordsBuf = _coordsBuf; while (1) { cord = READ_LE_UINT32(chosenCoordsBuf); - WRITE_UINT32(tempCoordsBuf, cord); + WRITE_LE_UINT32(tempCoordsBuf, cord); tempCoordsBuf += 4; if (chosenCoordsBuf == choosenCoords) { break; @@ -4595,7 +4595,7 @@ byte *PrinceEngine::makePath(int heroId, int currX, int currY, int destX, int de } _coords = _coordsBuf + sizeChoosen; } - WRITE_UINT32(_coords, 0xFFFFFFFF); + WRITE_LE_UINT32(_coords, 0xFFFFFFFF); freeCoords2(); freeCoords3(); scanDirections(); @@ -4612,16 +4612,16 @@ byte *PrinceEngine::makePath(int heroId, int currX, int currY, int destX, int de newCoordsBegin = newCoords; while (tempCoordsBuf != tempCoords) { newValueX = READ_LE_UINT16(tempCoordsBuf); - WRITE_UINT16(newCoords, newValueX * 2); + WRITE_LE_UINT16(newCoords, newValueX * 2); newCoords += 2; newValueY = READ_LE_UINT16(tempCoordsBuf + 2); - WRITE_UINT16(newCoords, newValueY * 2); + WRITE_LE_UINT16(newCoords, newValueY * 2); newCoords += 2; tempCoordsBuf += 4; } - WRITE_UINT16(newCoords - 4, realDestX); - WRITE_UINT16(newCoords - 2, realDestY); - WRITE_UINT32(newCoords, 0xFFFFFFFF); + WRITE_LE_UINT16(newCoords - 4, realDestX); + WRITE_LE_UINT16(newCoords - 2, realDestY); + WRITE_LE_UINT32(newCoords, 0xFFFFFFFF); newCoords += 4; _shanLen = (newCoords - newCoordsBegin); _shanLen /= 4; diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 0181f6912ddf..75d084f63986 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -210,7 +210,7 @@ uint32 Script::getBackAnimId(int roomBackAnimOffset, int slot) { } void Script::setBackAnimId(int roomBackAnimOffset, int slot, int animId) { - WRITE_UINT32(&_data[roomBackAnimOffset + slot * 4], animId); + WRITE_LE_UINT32(&_data[roomBackAnimOffset + slot * 4], animId); } byte Script::getObjId(int roomObjOffset, int slot) { @@ -1567,7 +1567,7 @@ void Interpreter::O_ENABLEDIALOGOPT() { int32 opt = readScriptFlagValue(); int dialogDataValue = (int)READ_LE_UINT32(_vm->_dialogData); dialogDataValue &= ~(1u << opt); - WRITE_UINT32(_vm->_dialogData, dialogDataValue); + WRITE_LE_UINT32(_vm->_dialogData, dialogDataValue); debugInterpreter("O_ENABLEDIALOGOPT opt %d", opt); } @@ -1575,7 +1575,7 @@ void Interpreter::O_DISABLEDIALOGOPT() { int32 opt = readScriptFlagValue(); int dialogDataValue = (int)READ_LE_UINT32(_vm->_dialogData); dialogDataValue |= (1u << opt); - WRITE_UINT32(_vm->_dialogData, dialogDataValue); + WRITE_LE_UINT32(_vm->_dialogData, dialogDataValue); debugInterpreter("O_DISABLEDIALOGOPT opt %d", opt); } From c769c3b8855820122e6a7a6712cb7139445d8a0b Mon Sep 17 00:00:00 2001 From: lukaslw Date: Thu, 9 Oct 2014 21:05:55 +0200 Subject: [PATCH 374/374] PRINCE: Add MKTAG - BLAH in decrypt function --- engines/prince/archive.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/prince/archive.cpp b/engines/prince/archive.cpp index bc5d5d3818b8..ae6a2b75468d 100644 --- a/engines/prince/archive.cpp +++ b/engines/prince/archive.cpp @@ -41,7 +41,7 @@ static void decrypt(byte *buffer, uint32 size) { while (size--) { *buffer++ += key & 0xFF; key ^= 0x2E84299A; - key += 0x424C4148; + key += MKTAG('B', 'L', 'A', 'H'); key = ((key & 1) << 31) | (key >> 1); } }