aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/prince/draw.cpp705
-rw-r--r--engines/prince/mob.cpp158
-rw-r--r--engines/prince/module.mk1
-rw-r--r--engines/prince/prince.cpp828
4 files changed, 864 insertions, 828 deletions
diff --git a/engines/prince/draw.cpp b/engines/prince/draw.cpp
new file mode 100644
index 0000000000..6d330f61cb
--- /dev/null
+++ b/engines/prince/draw.cpp
@@ -0,0 +1,705 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "graphics/palette.h"
+
+#include "prince/prince.h"
+
+#include "prince/animation.h"
+#include "prince/graphics.h"
+#include "prince/hero.h"
+#include "prince/script.h"
+
+namespace Prince {
+
+bool PrinceEngine::spriteCheck(int sprWidth, int sprHeight, int destX, int destY) {
+ destX -= _picWindowX;
+ destY -= _picWindowY;
+
+ // if x1 is on visible part of screen
+ if (destX < 0) {
+ if (destX + sprWidth < 1) {
+ //x2 is negative - out of window
+ return false;
+ }
+ }
+ // if x1 is outside of screen on right side
+ if (destX >= kNormalWidth) {
+ return false;
+ }
+
+ if (destY < 0) {
+ if (destY + sprHeight < 1) {
+ //y2 is negative - out of window
+ return false;
+ }
+ }
+ if (destY >= kNormalHeight) {
+ return false;
+ }
+
+ return true;
+}
+
+// CheckNak
+void PrinceEngine::checkMasks(int x1, int y1, int sprWidth, int sprHeight, int z) {
+ int x2 = x1 + sprWidth - 1;
+ int y2 = y1 + sprHeight - 1;
+ if (x1 < 0) {
+ x1 = 0;
+ }
+ for (uint i = 0; i < _maskList.size(); i++) {
+ if (!_maskList[i]._state && !_maskList[i]._flags) {
+ if (_maskList[i]._z > z) {
+ if (_maskList[i]._x1 <= x2 && _maskList[i]._x2 >= x1) {
+ if (_maskList[i]._y1 <= y2 && _maskList[i]._y2 >= y1) {
+ _maskList[i]._state = 1;
+ }
+ }
+ }
+ }
+ }
+}
+
+// ClsNak
+void PrinceEngine::clsMasks() {
+ for (uint i = 0; i < _maskList.size(); i++) {
+ if (_maskList[i]._state) {
+ _maskList[i]._state = 0;
+ }
+ }
+}
+
+// InsertNakladki
+void PrinceEngine::insertMasks(Graphics::Surface *originalRoomSurface) {
+ for (uint i = 0; i < _maskList.size(); i++) {
+ if (_maskList[i]._state) {
+ if (_maskList[i]._data != nullptr) {
+ showMask(i, originalRoomSurface);
+ } else {
+ error("insertMasks() - Wrong mask data- nr %d", i);
+ }
+ }
+ }
+}
+
+// ShowNak
+void PrinceEngine::showMask(int maskNr, Graphics::Surface *originalRoomSurface) {
+ if (!_maskList[maskNr]._flags) {
+ if (spriteCheck(_maskList[maskNr]._width, _maskList[maskNr]._height, _maskList[maskNr]._x1, _maskList[maskNr]._y1)) {
+ int destX = _maskList[maskNr]._x1 - _picWindowX;
+ int destY = _maskList[maskNr]._y1 - _picWindowY;
+ DrawNode newDrawNode;
+ newDrawNode.posX = destX;
+ newDrawNode.posY = destY;
+ newDrawNode.posZ = _maskList[maskNr]._z;
+ newDrawNode.width = _maskList[maskNr]._width;
+ newDrawNode.height = _maskList[maskNr]._height;
+ newDrawNode.s = nullptr;
+ newDrawNode.originalRoomSurface = originalRoomSurface;
+ newDrawNode.data = _maskList[maskNr].getMask();
+ newDrawNode.drawFunction = &_graph->drawMaskDrawNode;
+ _drawNodeList.push_back(newDrawNode);
+ }
+ }
+}
+
+void PrinceEngine::showSprite(Graphics::Surface *spriteSurface, int destX, int destY, int destZ) {
+ if (spriteCheck(spriteSurface->w, spriteSurface->h, destX, destY)) {
+ destX -= _picWindowX;
+ destY -= _picWindowY;
+ DrawNode newDrawNode;
+ newDrawNode.posX = destX;
+ newDrawNode.posY = destY;
+ newDrawNode.posZ = destZ;
+ newDrawNode.width = 0;
+ newDrawNode.height = 0;
+ newDrawNode.s = spriteSurface;
+ newDrawNode.originalRoomSurface = nullptr;
+ newDrawNode.data = _transTable;
+ newDrawNode.drawFunction = &_graph->drawTransparentWithTransDrawNode;
+ _drawNodeList.push_back(newDrawNode);
+ }
+}
+
+void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY, int destZ) {
+ if (spriteCheck(shadowSurface->w, shadowSurface->h, destX, destY)) {
+ destX -= _picWindowX;
+ destY -= _picWindowY;
+ DrawNode newDrawNode;
+ newDrawNode.posX = destX;
+ newDrawNode.posY = destY;
+ newDrawNode.posZ = destZ;
+ newDrawNode.width = 0;
+ newDrawNode.height = 0;
+ newDrawNode.s = shadowSurface;
+ newDrawNode.originalRoomSurface = nullptr;
+ newDrawNode.data = _graph->_shadowTable70;
+ newDrawNode.drawFunction = &_graph->drawAsShadowDrawNode;
+ _drawNodeList.push_back(newDrawNode);
+ }
+}
+
+void PrinceEngine::showAnim(Anim &anim) {
+ //ShowFrameCode
+ //ShowAnimFrame
+ int phase = anim._showFrame;
+ int phaseFrameIndex = anim._animData->getPhaseFrameIndex(phase);
+ int x = anim._x + anim._animData->getPhaseOffsetX(phase);
+ int y = anim._y + anim._animData->getPhaseOffsetY(phase);
+ int animFlag = anim._flags;
+ int checkMaskFlag = (animFlag & 1);
+ int maxFrontFlag = (animFlag & 2);
+ int specialZFlag = anim._nextAnim;
+ int z = anim._nextAnim;
+ Graphics::Surface *animSurface = anim._animData->getFrame(phaseFrameIndex);
+ int frameWidth = animSurface->w;
+ int frameHeight = animSurface->h;
+ int shadowZ = 0;
+
+ if (checkMaskFlag) {
+ if (!anim._nextAnim) {
+ z = y + frameHeight - 1;
+ }
+ checkMasks(x, y, frameWidth, frameHeight, z);
+ }
+
+ if (specialZFlag) {
+ z = specialZFlag;
+ } else if (maxFrontFlag) {
+ z = kMaxPicHeight + 1;
+ } else {
+ z = y + frameHeight - 1;
+ }
+ shadowZ = z;
+
+ anim._currX = x;
+ anim._currY = y;
+ anim._currW = frameWidth;
+ anim._currH = frameHeight;
+ showSprite(animSurface, x, y, z);
+
+ // make_special_shadow
+ if ((anim._flags & 0x80)) {
+ DrawNode newDrawNode;
+ newDrawNode.posX = x;
+ newDrawNode.posY = y + animSurface->h - anim._shadowBack;
+ newDrawNode.posZ = Hero::kHeroShadowZ;
+ newDrawNode.width = 0;
+ newDrawNode.height = 0;
+ newDrawNode.scaleValue = _scaleValue;
+ newDrawNode.originalRoomSurface = nullptr;
+ newDrawNode.data = this;
+ newDrawNode.drawFunction = &Hero::showHeroShadow;
+ newDrawNode.s = animSurface;
+ _drawNodeList.push_back(newDrawNode);
+ }
+
+ //ShowFrameCodeShadow
+ //ShowAnimFrameShadow
+ if (anim._shadowData != nullptr) {
+ int shadowPhaseFrameIndex = anim._shadowData->getPhaseFrameIndex(phase);
+ int shadowX = anim._shadowData->getBaseX() + anim._shadowData->getPhaseOffsetX(phase);
+ int shadowY = anim._shadowData->getBaseY() + anim._shadowData->getPhaseOffsetY(phase);
+ Graphics::Surface *shadowSurface = anim._shadowData->getFrame(shadowPhaseFrameIndex);
+ int shadowFrameWidth = shadowSurface->w;
+ int shadowFrameHeight = shadowSurface->h;
+
+ if (checkMaskFlag) {
+ checkMasks(shadowX, shadowY, shadowFrameWidth, shadowFrameHeight, shadowY + shadowFrameWidth - 1);
+ }
+
+ if (!shadowZ) {
+ if (maxFrontFlag) {
+ shadowZ = kMaxPicHeight + 1;
+ } else {
+ shadowZ = shadowY + shadowFrameWidth - 1;
+ }
+ }
+ showSpriteShadow(shadowSurface, shadowX, shadowY, shadowZ);
+ }
+}
+
+void PrinceEngine::showNormAnims() {
+ for (int i = 0; i < kMaxNormAnims; i++) {
+ Anim &anim = _normAnimList[i];
+ if (anim._animData != nullptr) {
+ int phaseCount = anim._animData->getPhaseCount();
+ if (!anim._state) {
+ if (anim._frame == anim._lastFrame - 1) {
+ if (anim._loopType) {
+ if (anim._loopType == 1) {
+ anim._frame = anim._loopFrame;
+ } else {
+ continue;
+ }
+ }
+ } else {
+ anim._frame++;
+ }
+ anim._showFrame = anim._frame;
+ if (anim._showFrame >= phaseCount) {
+ anim._showFrame = phaseCount - 1;
+ }
+ showAnim(anim);
+ }
+ }
+ }
+}
+
+void PrinceEngine::setBackAnim(Anim &backAnim) {
+ int start = backAnim._basaData._start;
+ if (start != -1) {
+ backAnim._frame = start;
+ backAnim._showFrame = start;
+ backAnim._loopFrame = start;
+ }
+ int end = backAnim._basaData._end;
+ if (end != -1) {
+ backAnim._lastFrame = end;
+ }
+ backAnim._state = 0;
+}
+
+void PrinceEngine::showBackAnims() {
+ for (int i = 0; i < kMaxBackAnims; i++) {
+ BAS &seq = _backAnimList[i]._seq;
+ int activeSubAnim = seq._currRelative;
+ if (!_backAnimList[i].backAnims.empty()) {
+ if (_backAnimList[i].backAnims[activeSubAnim]._animData != nullptr) {
+ if (!_backAnimList[i].backAnims[activeSubAnim]._state) {
+ seq._counter++;
+ if (seq._type == 2) {
+ if (!seq._currRelative) {
+ if (seq._counter >= seq._data) {
+ if (seq._anims > 2) {
+ seq._currRelative = _randomSource.getRandomNumber(seq._anims - 2) + 1;
+ activeSubAnim = seq._currRelative;
+ seq._current = _backAnimList[i].backAnims[activeSubAnim]._basaData._num;
+ }
+ setBackAnim(_backAnimList[i].backAnims[activeSubAnim]);
+ seq._counter = 0;
+ }
+ }
+ }
+
+ if (seq._type == 3) {
+ if (!seq._currRelative) {
+ if (seq._counter < seq._data2) {
+ continue;
+ } else {
+ setBackAnim(_backAnimList[i].backAnims[activeSubAnim]);
+ }
+ }
+ }
+
+ if (_backAnimList[i].backAnims[activeSubAnim]._frame == _backAnimList[i].backAnims[activeSubAnim]._lastFrame - 1) {
+ _backAnimList[i].backAnims[activeSubAnim]._frame = _backAnimList[i].backAnims[activeSubAnim]._loopFrame;
+ switch (seq._type) {
+ case 1:
+ if (seq._anims > 1) {
+ int rnd;
+ do {
+ rnd = _randomSource.getRandomNumber(seq._anims - 1);
+ } while (rnd == seq._currRelative);
+ seq._currRelative = rnd;
+ seq._current = _backAnimList[i].backAnims[rnd]._basaData._num;
+ activeSubAnim = rnd;
+ setBackAnim(_backAnimList[i].backAnims[activeSubAnim]);
+ seq._counter = 0;
+ }
+ break;
+ case 2:
+ if (seq._currRelative) {
+ seq._currRelative = 0;
+ seq._current = _backAnimList[i].backAnims[0]._basaData._num;
+ activeSubAnim = 0;
+ setBackAnim(_backAnimList[i].backAnims[activeSubAnim]);
+ seq._counter = 0;
+ }
+ break;
+ case 3:
+ seq._currRelative = 0;
+ seq._current = _backAnimList[i].backAnims[0]._basaData._num;
+ seq._counter = 0;
+ seq._data2 = _randomSource.getRandomNumber(seq._data - 1);
+ continue; // for bug in original game
+ break;
+ }
+ } else {
+ _backAnimList[i].backAnims[activeSubAnim]._frame++;
+ }
+ _backAnimList[i].backAnims[activeSubAnim]._showFrame = _backAnimList[i].backAnims[activeSubAnim]._frame;
+ showAnim(_backAnimList[i].backAnims[activeSubAnim]);
+ }
+ }
+ }
+ }
+}
+
+void PrinceEngine::removeSingleBackAnim(int slot) {
+ if (!_backAnimList[slot].backAnims.empty()) {
+ for (uint j = 0; j < _backAnimList[slot].backAnims.size(); j++) {
+ if (_backAnimList[slot].backAnims[j]._animData != nullptr) {
+ delete _backAnimList[slot].backAnims[j]._animData;
+ _backAnimList[slot].backAnims[j]._animData = nullptr;
+ }
+ if (_backAnimList[slot].backAnims[j]._shadowData != nullptr) {
+ delete _backAnimList[slot].backAnims[j]._shadowData;
+ _backAnimList[slot].backAnims[j]._shadowData = nullptr;
+ }
+ }
+ _backAnimList[slot].backAnims.clear();
+ _backAnimList[slot]._seq._currRelative = 0;
+ }
+}
+
+void PrinceEngine::clearBackAnimList() {
+ for (int i = 0; i < kMaxBackAnims; i++) {
+ removeSingleBackAnim(i);
+ }
+}
+
+void PrinceEngine::grabMap() {
+ _graph->_frontScreen->copyFrom(*_roomBmp->getSurface());
+ showObjects();
+ runDrawNodes();
+ _graph->_mapScreen->copyFrom(*_graph->_frontScreen);
+}
+
+void PrinceEngine::initZoomIn(int slot) {
+ freeZoomObject(slot);
+ Object *object = _objList[slot];
+ if (object != nullptr) {
+ Graphics::Surface *zoomSource = object->getSurface();
+ if (zoomSource != nullptr) {
+ object->_flags |= 0x8000;
+ object->_zoomSurface = new Graphics::Surface();
+ object->_zoomSurface->create(zoomSource->w, zoomSource->h, Graphics::PixelFormat::createFormatCLUT8());
+ object->_zoomSurface->fillRect(Common::Rect(zoomSource->w, zoomSource->h), 0xFF);
+ object->_zoomTime = 20;
+ }
+ }
+}
+
+void PrinceEngine::initZoomOut(int slot) {
+ freeZoomObject(slot);
+ Object *object = _objList[slot];
+ if (object != nullptr) {
+ Graphics::Surface *zoomSource = object->getSurface();
+ if (zoomSource != nullptr) {
+ object->_flags |= 0x4000;
+ object->_zoomSurface = new Graphics::Surface();
+ object->_zoomSurface->copyFrom(*zoomSource);
+ object->_zoomTime = 10;
+ }
+ }
+}
+
+void PrinceEngine::doZoomIn(int slot) {
+ Object *object = _objList[slot];
+ if (object != nullptr) {
+ Graphics::Surface *orgSurface = object->getSurface();
+ if (orgSurface != nullptr) {
+ byte *src1 = (byte *)orgSurface->getBasePtr(0, 0);
+ byte *dst1 = (byte *)object->_zoomSurface->getBasePtr(0, 0);
+ int x = 0;
+ int surfaceHeight = orgSurface->h;
+ for (int y = 0; y < surfaceHeight; y++) {
+ byte *src2 = src1;
+ byte *dst2 = dst1;
+ int w = orgSurface->w - x;
+ src2 += x;
+ dst2 += x;
+ while (w > 0) {
+ int randVal = _randomSource.getRandomNumber(zoomInStep - 1);
+ if (randVal < w) {
+ *(dst2 + randVal) = *(src2 + randVal);
+ src2 += zoomInStep;
+ dst2 += zoomInStep;
+ } else if (y + 1 != surfaceHeight) {
+ *(dst1 + orgSurface->pitch + randVal - w) = *(src1 + orgSurface->pitch + randVal - w);
+ }
+ w -= zoomInStep;
+ }
+ x = -1 * w;
+ src1 += orgSurface->pitch;
+ dst1 += orgSurface->pitch;
+ }
+ }
+ }
+}
+
+void PrinceEngine::doZoomOut(int slot) {
+ Object *object = _objList[slot];
+ if (object != nullptr) {
+ Graphics::Surface *orgSurface = object->getSurface();
+ if (orgSurface != nullptr) {
+ byte *dst1 = (byte *)object->_zoomSurface->getBasePtr(0, 0);
+ int x = 0;
+ int surfaceHeight = orgSurface->h;
+ for (int y = 0; y < surfaceHeight; y++) {
+ byte *dst2 = dst1;
+ int w = orgSurface->w - x;
+ dst2 += x;
+ while (w > 0) {
+ int randVal = _randomSource.getRandomNumber(zoomInStep - 1);
+ if (randVal < w) {
+ *(dst2 + randVal) = 255;
+ dst2 += zoomInStep;
+ } else if (y + 1 != surfaceHeight) {
+ *(dst1 + orgSurface->pitch + randVal - w) = 255;
+ }
+ w -= zoomInStep;
+ }
+ x = -1 * w;
+ dst1 += orgSurface->pitch;
+ }
+ }
+ }
+}
+
+void PrinceEngine::freeZoomObject(int slot) {
+ Object *object = _objList[slot];
+ if (object != nullptr) {
+ if (object->_zoomSurface != nullptr) {
+ object->_zoomSurface->free();
+ delete object->_zoomSurface;
+ object->_zoomSurface = nullptr;
+ }
+ }
+}
+
+void PrinceEngine::showObjects() {
+ for (int i = 0; i < kMaxObjects; i++) {
+ int nr = _objSlot[i];
+ if (nr != 0xFF) {
+ Graphics::Surface *objSurface = nullptr;
+ if ((_objList[nr]->_flags & 0x8000)) {
+ _objList[nr]->_zoomTime--;
+ if (!_objList[nr]->_zoomTime) {
+ freeZoomObject(nr);
+ _objList[nr]->_flags &= 0x7FFF;
+ objSurface = _objList[nr]->getSurface();
+ } else {
+ doZoomIn(nr);
+ objSurface = _objList[nr]->_zoomSurface;
+ }
+ } else if ((_objList[nr]->_flags & 0x4000)) {
+ _objList[nr]->_zoomTime--;
+ if (!_objList[nr]->_zoomTime) {
+ freeZoomObject(nr);
+ _objList[nr]->_flags &= 0xBFFF;
+ objSurface = _objList[nr]->getSurface();
+ } else {
+ doZoomOut(nr);
+ objSurface = _objList[nr]->_zoomSurface;
+ }
+ } else {
+ objSurface = _objList[nr]->getSurface();
+ }
+
+ if (objSurface != nullptr) {
+ if (spriteCheck(objSurface->w, objSurface->h, _objList[nr]->_x, _objList[nr]->_y)) {
+ int destX = _objList[nr]->_x - _picWindowX;
+ int destY = _objList[nr]->_y - _picWindowY;
+ DrawNode newDrawNode;
+ newDrawNode.posX = destX;
+ newDrawNode.posY = destY;
+ newDrawNode.posZ = _objList[nr]->_z;
+ newDrawNode.width = 0;
+ newDrawNode.height = 0;
+ newDrawNode.s = objSurface;
+ newDrawNode.originalRoomSurface = nullptr;
+ if ((_objList[nr]->_flags & 0x2000)) {
+ newDrawNode.data = nullptr;
+ newDrawNode.drawFunction = &_graph->drawBackSpriteDrawNode;
+ } else {
+ newDrawNode.data = _transTable;
+ if (_flags->getFlagValue(Flags::NOANTIALIAS)) {
+ newDrawNode.drawFunction = &_graph->drawTransparentDrawNode;
+ } else {
+ newDrawNode.drawFunction = &_graph->drawTransparentWithTransDrawNode;
+ }
+ }
+ _drawNodeList.push_back(newDrawNode);
+ }
+
+ if ((_objList[nr]->_flags & 1)) {
+ checkMasks(_objList[nr]->_x, _objList[nr]->_y, objSurface->w, objSurface->h, _objList[nr]->_z);
+ }
+ }
+ }
+ }
+}
+
+void PrinceEngine::showParallax() {
+ if (!_pscrList.empty()) {
+ for (uint i = 0; i < _pscrList.size(); i++) {
+ Graphics::Surface *pscrSurface = _pscrList[i]->getSurface();
+ if (pscrSurface != nullptr) {
+ int x = _pscrList[i]->_x - (_pscrList[i]->_step * _picWindowX / 4);
+ int y = _pscrList[i]->_y;
+ int z = PScr::kPScrZ;
+ if (spriteCheck(pscrSurface->w, pscrSurface->h, x, y)) {
+ showSprite(pscrSurface, x, y, z);
+ }
+ }
+ }
+ }
+}
+
+bool PrinceEngine::compareDrawNodes(DrawNode d1, DrawNode d2) {
+ if (d1.posZ < d2.posZ) {
+ return true;
+ }
+ return false;
+}
+
+void PrinceEngine::runDrawNodes() {
+ Common::sort(_drawNodeList.begin(), _drawNodeList.end(), compareDrawNodes);
+
+ for (uint i = 0; i < _drawNodeList.size(); i++) {
+ (*_drawNodeList[i].drawFunction)(_graph->_frontScreen, &_drawNodeList[i]);
+ }
+ _graph->change();
+}
+
+void PrinceEngine::drawScreen() {
+ if (!_showInventoryFlag || _inventoryBackgroundRemember) {
+ clsMasks();
+
+ _mainHero->showHero();
+ _mainHero->scrollHero();
+ _mainHero->drawHero();
+
+ _secondHero->showHero();
+ _secondHero->_drawX -= _picWindowX;
+ _secondHero->drawHero();
+
+ const Graphics::Surface *roomSurface;
+ if (_locationNr != 50) {
+ roomSurface = _roomBmp->getSurface();
+ } else {
+ roomSurface = _graph->_mapScreen;
+ }
+ Graphics::Surface visiblePart;
+ if (roomSurface) {
+ visiblePart = roomSurface->getSubArea(Common::Rect(_picWindowX, 0, roomSurface->w, roomSurface->h));
+ _graph->draw(_graph->_frontScreen, &visiblePart);
+ }
+
+ showBackAnims();
+
+ showNormAnims();
+
+ playNextFLCFrame();
+
+ showObjects();
+
+ if (roomSurface) {
+ insertMasks(&visiblePart);
+ }
+
+ showParallax();
+
+ runDrawNodes();
+
+ _drawNodeList.clear();
+
+ if (!_inventoryBackgroundRemember && !_dialogFlag) {
+ if (!_optionsFlag) {
+ _selectedMob = checkMob(_graph->_frontScreen, _mobList, true);
+ }
+ showTexts(_graph->_frontScreen);
+ checkOptions();
+ } else {
+ _inventoryBackgroundRemember = false;
+ }
+
+ showPower();
+
+ getDebugger()->onFrame();
+
+ } else {
+ displayInventory();
+ }
+}
+
+void PrinceEngine::blackPalette() {
+ byte *paletteBackup = (byte *)malloc(256 * 3);
+ byte *blackPalette1 = (byte *)malloc(256 * 3);
+
+ int fadeStep = kFadeStep - 1;
+ for (int i = 0; i < kFadeStep; i++) {
+ _system->getPaletteManager()->grabPalette(paletteBackup, 0, 256);
+ for (int j = 0; j < 256; j++) {
+ blackPalette1[3 * j] = paletteBackup[3 * j] * fadeStep / 4;
+ blackPalette1[3 * j + 1] = paletteBackup[3 * j + 1] * fadeStep / 4;
+ blackPalette1[3 * j + 2] = paletteBackup[3 * j + 2] * fadeStep / 4;
+ }
+ fadeStep--;
+ _graph->setPalette(blackPalette1);
+ _system->updateScreen();
+ Common::Event event;
+ Common::EventManager *eventMan = _system->getEventManager();
+ eventMan->pollEvent(event);
+ if (shouldQuit()) {
+ free(paletteBackup);
+ free(blackPalette1);
+ return;
+ }
+ pausePrinceEngine();
+ }
+ free(paletteBackup);
+ free(blackPalette1);
+}
+
+void PrinceEngine::setPalette(const byte *palette) {
+ if (palette != nullptr) {
+ byte *blackPalette_ = (byte *)malloc(256 * 3);
+ int fadeStep = 0;
+ for (int i = 0; i <= kFadeStep; i++) {
+ for (int j = 0; j < 256; j++) {
+ blackPalette_[3 * j] = palette[3 * j] * fadeStep / 4;
+ blackPalette_[3 * j + 1] = palette[3 * j + 1] * fadeStep / 4;
+ blackPalette_[3 * j + 2] = palette[3 * j + 2] * fadeStep / 4;
+ }
+ fadeStep++;
+ _graph->setPalette(blackPalette_);
+ _system->updateScreen();
+ Common::Event event;
+ Common::EventManager *eventMan = _system->getEventManager();
+ eventMan->pollEvent(event);
+ if (shouldQuit()) {
+ _graph->setPalette(palette);
+ free(blackPalette_);
+ return;
+ }
+ pausePrinceEngine();
+ }
+ _graph->setPalette(palette);
+ free(blackPalette_);
+ }
+}
+
+} // End of namespace Prince
diff --git a/engines/prince/mob.cpp b/engines/prince/mob.cpp
index b170ba324b..de15991dba 100644
--- a/engines/prince/mob.cpp
+++ b/engines/prince/mob.cpp
@@ -20,7 +20,11 @@
*
*/
+#include "prince/prince.h"
+
#include "prince/mob.h"
+#include "prince/animation.h"
+#include "prince/font.h"
namespace Prince {
@@ -105,4 +109,158 @@ uint16 Mob::getData(AttrId dataId) {
}
}
+int PrinceEngine::getMob(Common::Array<Mob> &mobList, bool usePriorityList, int posX, int posY) {
+
+ Common::Point pointPos(posX, posY);
+
+ int mobListSize;
+ if (usePriorityList) {
+ mobListSize = _mobPriorityList.size();
+ } else {
+ mobListSize = mobList.size();
+ }
+
+ for (int mobNumber = 0; mobNumber < mobListSize; mobNumber++) {
+ Mob *mob = nullptr;
+ if (usePriorityList) {
+ mob = &mobList[_mobPriorityList[mobNumber]];
+ } else {
+ mob = &mobList[mobNumber];
+ }
+
+ if (mob->_visible) {
+ continue;
+ }
+
+ int type = mob->_type & 7;
+ switch (type) {
+ case 0:
+ case 1:
+ //normal_mob
+ if (!mob->_rect.contains(pointPos)) {
+ continue;
+ }
+ break;
+ case 3:
+ //mob_obj
+ if (mob->_mask < kMaxObjects) {
+ int nr = _objSlot[mob->_mask];
+ if (nr != 0xFF) {
+ Object &obj = *_objList[nr];
+ Common::Rect objectRect(obj._x, obj._y, obj._x + obj._width, obj._y + obj._height);
+ if (objectRect.contains(pointPos)) {
+ Graphics::Surface *objSurface = obj.getSurface();
+ byte *pixel = (byte *)objSurface->getBasePtr(posX - obj._x, posY - obj._y);
+ if (*pixel != 255) {
+ break;
+ }
+ }
+ }
+ }
+ continue;
+ break;
+ case 2:
+ case 5:
+ //check_ba_mob
+ if (!_backAnimList[mob->_mask].backAnims.empty()) {
+ int currentAnim = _backAnimList[mob->_mask]._seq._currRelative;
+ Anim &backAnim = _backAnimList[mob->_mask].backAnims[currentAnim];
+ if (backAnim._animData != nullptr) {
+ if (!backAnim._state) {
+ Common::Rect backAnimRect(backAnim._currX, backAnim._currY, backAnim._currX + backAnim._currW, backAnim._currY + backAnim._currH);
+ if (backAnimRect.contains(pointPos)) {
+ int phase = backAnim._showFrame;
+ int phaseFrameIndex = backAnim._animData->getPhaseFrameIndex(phase);
+ Graphics::Surface *backAnimSurface = backAnim._animData->getFrame(phaseFrameIndex);
+ byte pixel = *(byte *)backAnimSurface->getBasePtr(posX - backAnim._currX, posY - backAnim._currY);
+ if (pixel != 255) {
+ if (type == 5) {
+ if (mob->_rect.contains(pointPos)) {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ continue;
+ break;
+ default:
+ //not_part_ba
+ continue;
+ break;
+ }
+
+ if (usePriorityList) {
+ return _mobPriorityList[mobNumber];
+ } else {
+ return mobNumber;
+ }
+ }
+ return -1;
+}
+
+int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array<Mob> &mobList, bool usePriorityList) {
+ if (_mouseFlag == 0 || _mouseFlag == 3) {
+ return -1;
+ }
+ Common::Point mousePos = _system->getEventManager()->getMousePos();
+ int mobNumber = getMob(mobList, usePriorityList, mousePos.x + _picWindowX, mousePos.y);
+
+ if (mobNumber != -1) {
+ Common::String mobName = mobList[mobNumber]._name;
+
+ if (getLanguage() == Common::DE_DEU) {
+ for (uint i = 0; i < mobName.size(); i++) {
+ switch (mobName[i]) {
+ case '\xc4':
+ mobName.setChar('\x83', i);
+ break;
+ case '\xd6':
+ mobName.setChar('\x84', i);
+ break;
+ case '\xdc':
+ mobName.setChar('\x85', i);
+ break;
+ case '\xdf':
+ mobName.setChar('\x7f', i);
+ break;
+ case '\xe4':
+ mobName.setChar('\x80', i);
+ break;
+ case '\xf6':
+ mobName.setChar('\x81', i);
+ break;
+ case '\xfc':
+ mobName.setChar('\x82', i);
+ break;
+ }
+ }
+ }
+
+ uint16 textW = getTextWidth(mobName.c_str());
+
+ uint16 x = mousePos.x - textW / 2;
+ if (x > screen->w) {
+ x = 0;
+ }
+
+ if (x + textW > screen->w) {
+ x = screen->w - textW;
+ }
+
+ uint16 y = mousePos.y - _font->getFontHeight();
+ if (y > screen->h) {
+ y = _font->getFontHeight() - 2;
+ }
+
+ _font->drawString(screen, mobName, x, y, screen->w, 216);
+ }
+
+ return mobNumber;
+}
+
} // End of namespace Prince
diff --git a/engines/prince/module.mk b/engines/prince/module.mk
index d045c1feda..8446d07a12 100644
--- a/engines/prince/module.mk
+++ b/engines/prince/module.mk
@@ -7,6 +7,7 @@ MODULE_OBJS = \
debugger.o \
decompress.o \
detection.o \
+ draw.o \
flags.o \
font.o \
graphics.o \
diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp
index 321c4f1b2a..654b87ea26 100644
--- a/engines/prince/prince.cpp
+++ b/engines/prince/prince.cpp
@@ -33,13 +33,11 @@
#include "common/str.h"
#include "graphics/surface.h"
-#include "graphics/palette.h"
#include "graphics/pixelformat.h"
#include "engines/util.h"
#include "prince/prince.h"
-#include "prince/font.h"
#include "prince/graphics.h"
#include "prince/script.h"
#include "prince/debugger.h"
@@ -47,7 +45,6 @@
#include "prince/mob.h"
#include "prince/music.h"
#include "prince/variatxt.h"
-#include "prince/flags.h"
#include "prince/font.h"
#include "prince/mhwanh.h"
#include "prince/cursor.h"
@@ -563,160 +560,6 @@ void PrinceEngine::keyHandler(Common::Event event) {
}
}
-int PrinceEngine::getMob(Common::Array<Mob> &mobList, bool usePriorityList, int posX, int posY) {
-
- Common::Point pointPos(posX, posY);
-
- int mobListSize;
- if (usePriorityList) {
- mobListSize = _mobPriorityList.size();
- } else {
- mobListSize = mobList.size();
- }
-
- for (int mobNumber = 0; mobNumber < mobListSize; mobNumber++) {
- Mob *mob = nullptr;
- if (usePriorityList) {
- mob = &mobList[_mobPriorityList[mobNumber]];
- } else {
- mob = &mobList[mobNumber];
- }
-
- if (mob->_visible) {
- continue;
- }
-
- int type = mob->_type & 7;
- switch (type) {
- case 0:
- case 1:
- //normal_mob
- if (!mob->_rect.contains(pointPos)) {
- continue;
- }
- break;
- case 3:
- //mob_obj
- if (mob->_mask < kMaxObjects) {
- int nr = _objSlot[mob->_mask];
- if (nr != 0xFF) {
- Object &obj = *_objList[nr];
- Common::Rect objectRect(obj._x, obj._y, obj._x + obj._width, obj._y + obj._height);
- if (objectRect.contains(pointPos)) {
- Graphics::Surface *objSurface = obj.getSurface();
- byte *pixel = (byte *)objSurface->getBasePtr(posX - obj._x, posY - obj._y);
- if (*pixel != 255) {
- break;
- }
- }
- }
- }
- continue;
- break;
- case 2:
- case 5:
- //check_ba_mob
- if (!_backAnimList[mob->_mask].backAnims.empty()) {
- int currentAnim = _backAnimList[mob->_mask]._seq._currRelative;
- Anim &backAnim = _backAnimList[mob->_mask].backAnims[currentAnim];
- if (backAnim._animData != nullptr) {
- if (!backAnim._state) {
- Common::Rect backAnimRect(backAnim._currX, backAnim._currY, backAnim._currX + backAnim._currW, backAnim._currY + backAnim._currH);
- if (backAnimRect.contains(pointPos)) {
- int phase = backAnim._showFrame;
- int phaseFrameIndex = backAnim._animData->getPhaseFrameIndex(phase);
- Graphics::Surface *backAnimSurface = backAnim._animData->getFrame(phaseFrameIndex);
- byte pixel = *(byte *)backAnimSurface->getBasePtr(posX - backAnim._currX, posY - backAnim._currY);
- if (pixel != 255) {
- if (type == 5) {
- if (mob->_rect.contains(pointPos)) {
- break;
- }
- } else {
- break;
- }
- }
- }
- }
- }
- }
- continue;
- break;
- default:
- //not_part_ba
- continue;
- break;
- }
-
- if (usePriorityList) {
- return _mobPriorityList[mobNumber];
- } else {
- return mobNumber;
- }
- }
- return -1;
-}
-
-int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array<Mob> &mobList, bool usePriorityList) {
- if (_mouseFlag == 0 || _mouseFlag == 3) {
- return -1;
- }
- Common::Point mousePos = _system->getEventManager()->getMousePos();
- int mobNumber = getMob(mobList, usePriorityList, mousePos.x + _picWindowX, mousePos.y);
-
- if (mobNumber != -1) {
- Common::String mobName = mobList[mobNumber]._name;
-
- if (getLanguage() == Common::DE_DEU) {
- for (uint i = 0; i < mobName.size(); i++) {
- switch (mobName[i]) {
- case '\xc4':
- mobName.setChar('\x83', i);
- break;
- case '\xd6':
- mobName.setChar('\x84', i);
- break;
- case '\xdc':
- mobName.setChar('\x85', i);
- break;
- case '\xdf':
- mobName.setChar('\x7f', i);
- break;
- case '\xe4':
- mobName.setChar('\x80', i);
- break;
- case '\xf6':
- mobName.setChar('\x81', i);
- break;
- case '\xfc':
- mobName.setChar('\x82', i);
- break;
- }
- }
- }
-
- uint16 textW = getTextWidth(mobName.c_str());
-
- uint16 x = mousePos.x - textW / 2;
- if (x > screen->w) {
- x = 0;
- }
-
- if (x + textW > screen->w) {
- x = screen->w - textW;
- }
-
- uint16 y = mousePos.y - _font->getFontHeight();
- if (y > screen->h) {
- y = _font->getFontHeight() - 2;
- }
-
- _font->drawString(screen, mobName, x, y, screen->w, 216);
- }
-
- return mobNumber;
-}
-
void PrinceEngine::printAt(uint32 slot, uint8 color, char *s, uint16 x, uint16 y) {
debugC(1, DebugChannel::kEngine, "PrinceEngine::printAt slot %d, color %d, x %02d, y %02d, str %s", slot, color, x, y, s);
@@ -846,677 +689,6 @@ void PrinceEngine::showTexts(Graphics::Surface *screen) {
}
}
-bool PrinceEngine::spriteCheck(int sprWidth, int sprHeight, int destX, int destY) {
- destX -= _picWindowX;
- destY -= _picWindowY;
-
- // if x1 is on visible part of screen
- if (destX < 0) {
- if (destX + sprWidth < 1) {
- //x2 is negative - out of window
- return false;
- }
- }
- // if x1 is outside of screen on right side
- if (destX >= kNormalWidth) {
- return false;
- }
-
- if (destY < 0) {
- if (destY + sprHeight < 1) {
- //y2 is negative - out of window
- return false;
- }
- }
- if (destY >= kNormalHeight) {
- return false;
- }
-
- return true;
-}
-
-// CheckNak
-void PrinceEngine::checkMasks(int x1, int y1, int sprWidth, int sprHeight, int z) {
- int x2 = x1 + sprWidth - 1;
- int y2 = y1 + sprHeight - 1;
- if (x1 < 0) {
- x1 = 0;
- }
- for (uint i = 0; i < _maskList.size(); i++) {
- if (!_maskList[i]._state && !_maskList[i]._flags) {
- if (_maskList[i]._z > z) {
- if (_maskList[i]._x1 <= x2 && _maskList[i]._x2 >= x1) {
- if (_maskList[i]._y1 <= y2 && _maskList[i]._y2 >= y1) {
- _maskList[i]._state = 1;
- }
- }
- }
- }
- }
-}
-
-// ClsNak
-void PrinceEngine::clsMasks() {
- for (uint i = 0; i < _maskList.size(); i++) {
- if (_maskList[i]._state) {
- _maskList[i]._state = 0;
- }
- }
-}
-
-// InsertNakladki
-void PrinceEngine::insertMasks(Graphics::Surface *originalRoomSurface) {
- for (uint i = 0; i < _maskList.size(); i++) {
- if (_maskList[i]._state) {
- if (_maskList[i]._data != nullptr) {
- showMask(i, originalRoomSurface);
- } else {
- error("insertMasks() - Wrong mask data- nr %d", i);
- }
- }
- }
-}
-
-// ShowNak
-void PrinceEngine::showMask(int maskNr, Graphics::Surface *originalRoomSurface) {
- if (!_maskList[maskNr]._flags) {
- if (spriteCheck(_maskList[maskNr]._width, _maskList[maskNr]._height, _maskList[maskNr]._x1, _maskList[maskNr]._y1)) {
- int destX = _maskList[maskNr]._x1 - _picWindowX;
- int destY = _maskList[maskNr]._y1 - _picWindowY;
- DrawNode newDrawNode;
- newDrawNode.posX = destX;
- newDrawNode.posY = destY;
- newDrawNode.posZ = _maskList[maskNr]._z;
- newDrawNode.width = _maskList[maskNr]._width;
- newDrawNode.height = _maskList[maskNr]._height;
- newDrawNode.s = nullptr;
- newDrawNode.originalRoomSurface = originalRoomSurface;
- newDrawNode.data = _maskList[maskNr].getMask();
- newDrawNode.drawFunction = &_graph->drawMaskDrawNode;
- _drawNodeList.push_back(newDrawNode);
- }
- }
-}
-
-void PrinceEngine::showSprite(Graphics::Surface *spriteSurface, int destX, int destY, int destZ) {
- if (spriteCheck(spriteSurface->w, spriteSurface->h, destX, destY)) {
- destX -= _picWindowX;
- destY -= _picWindowY;
- DrawNode newDrawNode;
- newDrawNode.posX = destX;
- newDrawNode.posY = destY;
- newDrawNode.posZ = destZ;
- newDrawNode.width = 0;
- newDrawNode.height = 0;
- newDrawNode.s = spriteSurface;
- newDrawNode.originalRoomSurface = nullptr;
- newDrawNode.data = _transTable;
- newDrawNode.drawFunction = &_graph->drawTransparentWithTransDrawNode;
- _drawNodeList.push_back(newDrawNode);
- }
-}
-
-void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY, int destZ) {
- if (spriteCheck(shadowSurface->w, shadowSurface->h, destX, destY)) {
- destX -= _picWindowX;
- destY -= _picWindowY;
- DrawNode newDrawNode;
- newDrawNode.posX = destX;
- newDrawNode.posY = destY;
- newDrawNode.posZ = destZ;
- newDrawNode.width = 0;
- newDrawNode.height = 0;
- newDrawNode.s = shadowSurface;
- newDrawNode.originalRoomSurface = nullptr;
- newDrawNode.data = _graph->_shadowTable70;
- newDrawNode.drawFunction = &_graph->drawAsShadowDrawNode;
- _drawNodeList.push_back(newDrawNode);
- }
-}
-
-void PrinceEngine::showAnim(Anim &anim) {
- //ShowFrameCode
- //ShowAnimFrame
- int phase = anim._showFrame;
- int phaseFrameIndex = anim._animData->getPhaseFrameIndex(phase);
- int x = anim._x + anim._animData->getPhaseOffsetX(phase);
- int y = anim._y + anim._animData->getPhaseOffsetY(phase);
- int animFlag = anim._flags;
- int checkMaskFlag = (animFlag & 1);
- int maxFrontFlag = (animFlag & 2);
- int specialZFlag = anim._nextAnim;
- int z = anim._nextAnim;
- Graphics::Surface *animSurface = anim._animData->getFrame(phaseFrameIndex);
- int frameWidth = animSurface->w;
- int frameHeight = animSurface->h;
- int shadowZ = 0;
-
- if (checkMaskFlag) {
- if (!anim._nextAnim) {
- z = y + frameHeight - 1;
- }
- checkMasks(x, y, frameWidth, frameHeight, z);
- }
-
- if (specialZFlag) {
- z = specialZFlag;
- } else if (maxFrontFlag) {
- z = kMaxPicHeight + 1;
- } else {
- z = y + frameHeight - 1;
- }
- shadowZ = z;
-
- anim._currX = x;
- anim._currY = y;
- anim._currW = frameWidth;
- anim._currH = frameHeight;
- showSprite(animSurface, x, y, z);
-
- // make_special_shadow
- if ((anim._flags & 0x80)) {
- DrawNode newDrawNode;
- newDrawNode.posX = x;
- newDrawNode.posY = y + animSurface->h - anim._shadowBack;
- newDrawNode.posZ = Hero::kHeroShadowZ;
- newDrawNode.width = 0;
- newDrawNode.height = 0;
- newDrawNode.scaleValue = _scaleValue;
- newDrawNode.originalRoomSurface = nullptr;
- newDrawNode.data = this;
- newDrawNode.drawFunction = &Hero::showHeroShadow;
- newDrawNode.s = animSurface;
- _drawNodeList.push_back(newDrawNode);
- }
-
- //ShowFrameCodeShadow
- //ShowAnimFrameShadow
- if (anim._shadowData != nullptr) {
- int shadowPhaseFrameIndex = anim._shadowData->getPhaseFrameIndex(phase);
- int shadowX = anim._shadowData->getBaseX() + anim._shadowData->getPhaseOffsetX(phase);
- int shadowY = anim._shadowData->getBaseY() + anim._shadowData->getPhaseOffsetY(phase);
- Graphics::Surface *shadowSurface = anim._shadowData->getFrame(shadowPhaseFrameIndex);
- int shadowFrameWidth = shadowSurface->w;
- int shadowFrameHeight = shadowSurface->h;
-
- if (checkMaskFlag) {
- checkMasks(shadowX, shadowY, shadowFrameWidth, shadowFrameHeight, shadowY + shadowFrameWidth - 1);
- }
-
- if (!shadowZ) {
- if (maxFrontFlag) {
- shadowZ = kMaxPicHeight + 1;
- } else {
- shadowZ = shadowY + shadowFrameWidth - 1;
- }
- }
- showSpriteShadow(shadowSurface, shadowX, shadowY, shadowZ);
- }
-}
-
-void PrinceEngine::showNormAnims() {
- for (int i = 0; i < kMaxNormAnims; i++) {
- Anim &anim = _normAnimList[i];
- if (anim._animData != nullptr) {
- int phaseCount = anim._animData->getPhaseCount();
- if (!anim._state) {
- if (anim._frame == anim._lastFrame - 1) {
- if (anim._loopType) {
- if (anim._loopType == 1) {
- anim._frame = anim._loopFrame;
- } else {
- continue;
- }
- }
- } else {
- anim._frame++;
- }
- anim._showFrame = anim._frame;
- if (anim._showFrame >= phaseCount) {
- anim._showFrame = phaseCount - 1;
- }
- showAnim(anim);
- }
- }
- }
-}
-
-void PrinceEngine::setBackAnim(Anim &backAnim) {
- int start = backAnim._basaData._start;
- if (start != -1) {
- backAnim._frame = start;
- backAnim._showFrame = start;
- backAnim._loopFrame = start;
- }
- int end = backAnim._basaData._end;
- if (end != -1) {
- backAnim._lastFrame = end;
- }
- backAnim._state = 0;
-}
-
-void PrinceEngine::showBackAnims() {
- for (int i = 0; i < kMaxBackAnims; i++) {
- BAS &seq = _backAnimList[i]._seq;
- int activeSubAnim = seq._currRelative;
- if (!_backAnimList[i].backAnims.empty()) {
- if (_backAnimList[i].backAnims[activeSubAnim]._animData != nullptr) {
- if (!_backAnimList[i].backAnims[activeSubAnim]._state) {
- seq._counter++;
- if (seq._type == 2) {
- if (!seq._currRelative) {
- if (seq._counter >= seq._data) {
- if (seq._anims > 2) {
- seq._currRelative = _randomSource.getRandomNumber(seq._anims - 2) + 1;
- activeSubAnim = seq._currRelative;
- seq._current = _backAnimList[i].backAnims[activeSubAnim]._basaData._num;
- }
- setBackAnim(_backAnimList[i].backAnims[activeSubAnim]);
- seq._counter = 0;
- }
- }
- }
-
- if (seq._type == 3) {
- if (!seq._currRelative) {
- if (seq._counter < seq._data2) {
- continue;
- } else {
- setBackAnim(_backAnimList[i].backAnims[activeSubAnim]);
- }
- }
- }
-
- if (_backAnimList[i].backAnims[activeSubAnim]._frame == _backAnimList[i].backAnims[activeSubAnim]._lastFrame - 1) {
- _backAnimList[i].backAnims[activeSubAnim]._frame = _backAnimList[i].backAnims[activeSubAnim]._loopFrame;
- switch (seq._type) {
- case 1:
- if (seq._anims > 1) {
- int rnd;
- do {
- rnd = _randomSource.getRandomNumber(seq._anims - 1);
- } while (rnd == seq._currRelative);
- seq._currRelative = rnd;
- seq._current = _backAnimList[i].backAnims[rnd]._basaData._num;
- activeSubAnim = rnd;
- setBackAnim(_backAnimList[i].backAnims[activeSubAnim]);
- seq._counter = 0;
- }
- break;
- case 2:
- if (seq._currRelative) {
- seq._currRelative = 0;
- seq._current = _backAnimList[i].backAnims[0]._basaData._num;
- activeSubAnim = 0;
- setBackAnim(_backAnimList[i].backAnims[activeSubAnim]);
- seq._counter = 0;
- }
- break;
- case 3:
- seq._currRelative = 0;
- seq._current = _backAnimList[i].backAnims[0]._basaData._num;
- seq._counter = 0;
- seq._data2 = _randomSource.getRandomNumber(seq._data - 1);
- continue; // for bug in original game
- break;
- }
- } else {
- _backAnimList[i].backAnims[activeSubAnim]._frame++;
- }
- _backAnimList[i].backAnims[activeSubAnim]._showFrame = _backAnimList[i].backAnims[activeSubAnim]._frame;
- showAnim(_backAnimList[i].backAnims[activeSubAnim]);
- }
- }
- }
- }
-}
-
-void PrinceEngine::removeSingleBackAnim(int slot) {
- if (!_backAnimList[slot].backAnims.empty()) {
- for (uint j = 0; j < _backAnimList[slot].backAnims.size(); j++) {
- if (_backAnimList[slot].backAnims[j]._animData != nullptr) {
- delete _backAnimList[slot].backAnims[j]._animData;
- _backAnimList[slot].backAnims[j]._animData = nullptr;
- }
- if (_backAnimList[slot].backAnims[j]._shadowData != nullptr) {
- delete _backAnimList[slot].backAnims[j]._shadowData;
- _backAnimList[slot].backAnims[j]._shadowData = nullptr;
- }
- }
- _backAnimList[slot].backAnims.clear();
- _backAnimList[slot]._seq._currRelative = 0;
- }
-}
-
-void PrinceEngine::clearBackAnimList() {
- for (int i = 0; i < kMaxBackAnims; i++) {
- removeSingleBackAnim(i);
- }
-}
-
-void PrinceEngine::grabMap() {
- _graph->_frontScreen->copyFrom(*_roomBmp->getSurface());
- showObjects();
- runDrawNodes();
- _graph->_mapScreen->copyFrom(*_graph->_frontScreen);
-}
-
-void PrinceEngine::initZoomIn(int slot) {
- freeZoomObject(slot);
- Object *object = _objList[slot];
- if (object != nullptr) {
- Graphics::Surface *zoomSource = object->getSurface();
- if (zoomSource != nullptr) {
- object->_flags |= 0x8000;
- object->_zoomSurface = new Graphics::Surface();
- object->_zoomSurface->create(zoomSource->w, zoomSource->h, Graphics::PixelFormat::createFormatCLUT8());
- object->_zoomSurface->fillRect(Common::Rect(zoomSource->w, zoomSource->h), 0xFF);
- object->_zoomTime = 20;
- }
- }
-}
-
-void PrinceEngine::initZoomOut(int slot) {
- freeZoomObject(slot);
- Object *object = _objList[slot];
- if (object != nullptr) {
- Graphics::Surface *zoomSource = object->getSurface();
- if (zoomSource != nullptr) {
- object->_flags |= 0x4000;
- object->_zoomSurface = new Graphics::Surface();
- object->_zoomSurface->copyFrom(*zoomSource);
- object->_zoomTime = 10;
- }
- }
-}
-
-void PrinceEngine::doZoomIn(int slot) {
- Object *object = _objList[slot];
- if (object != nullptr) {
- Graphics::Surface *orgSurface = object->getSurface();
- if (orgSurface != nullptr) {
- byte *src1 = (byte *)orgSurface->getBasePtr(0, 0);
- byte *dst1 = (byte *)object->_zoomSurface->getBasePtr(0, 0);
- int x = 0;
- int surfaceHeight = orgSurface->h;
- for (int y = 0; y < surfaceHeight; y++) {
- byte *src2 = src1;
- byte *dst2 = dst1;
- int w = orgSurface->w - x;
- src2 += x;
- dst2 += x;
- while (w > 0) {
- int randVal = _randomSource.getRandomNumber(zoomInStep - 1);
- if (randVal < w) {
- *(dst2 + randVal) = *(src2 + randVal);
- src2 += zoomInStep;
- dst2 += zoomInStep;
- } else if (y + 1 != surfaceHeight) {
- *(dst1 + orgSurface->pitch + randVal - w) = *(src1 + orgSurface->pitch + randVal - w);
- }
- w -= zoomInStep;
- }
- x = -1 * w;
- src1 += orgSurface->pitch;
- dst1 += orgSurface->pitch;
- }
- }
- }
-}
-
-void PrinceEngine::doZoomOut(int slot) {
- Object *object = _objList[slot];
- if (object != nullptr) {
- Graphics::Surface *orgSurface = object->getSurface();
- if (orgSurface != nullptr) {
- byte *dst1 = (byte *)object->_zoomSurface->getBasePtr(0, 0);
- int x = 0;
- int surfaceHeight = orgSurface->h;
- for (int y = 0; y < surfaceHeight; y++) {
- byte *dst2 = dst1;
- int w = orgSurface->w - x;
- dst2 += x;
- while (w > 0) {
- int randVal = _randomSource.getRandomNumber(zoomInStep - 1);
- if (randVal < w) {
- *(dst2 + randVal) = 255;
- dst2 += zoomInStep;
- } else if (y + 1 != surfaceHeight) {
- *(dst1 + orgSurface->pitch + randVal - w) = 255;
- }
- w -= zoomInStep;
- }
- x = -1 * w;
- dst1 += orgSurface->pitch;
- }
- }
- }
-}
-
-void PrinceEngine::freeZoomObject(int slot) {
- Object *object = _objList[slot];
- if (object != nullptr) {
- if (object->_zoomSurface != nullptr) {
- object->_zoomSurface->free();
- delete object->_zoomSurface;
- object->_zoomSurface = nullptr;
- }
- }
-}
-
-void PrinceEngine::showObjects() {
- for (int i = 0; i < kMaxObjects; i++) {
- int nr = _objSlot[i];
- if (nr != 0xFF) {
- Graphics::Surface *objSurface = nullptr;
- if ((_objList[nr]->_flags & 0x8000)) {
- _objList[nr]->_zoomTime--;
- if (!_objList[nr]->_zoomTime) {
- freeZoomObject(nr);
- _objList[nr]->_flags &= 0x7FFF;
- objSurface = _objList[nr]->getSurface();
- } else {
- doZoomIn(nr);
- objSurface = _objList[nr]->_zoomSurface;
- }
- } else if ((_objList[nr]->_flags & 0x4000)) {
- _objList[nr]->_zoomTime--;
- if (!_objList[nr]->_zoomTime) {
- freeZoomObject(nr);
- _objList[nr]->_flags &= 0xBFFF;
- objSurface = _objList[nr]->getSurface();
- } else {
- doZoomOut(nr);
- objSurface = _objList[nr]->_zoomSurface;
- }
- } else {
- objSurface = _objList[nr]->getSurface();
- }
-
- if (objSurface != nullptr) {
- if (spriteCheck(objSurface->w, objSurface->h, _objList[nr]->_x, _objList[nr]->_y)) {
- int destX = _objList[nr]->_x - _picWindowX;
- int destY = _objList[nr]->_y - _picWindowY;
- DrawNode newDrawNode;
- newDrawNode.posX = destX;
- newDrawNode.posY = destY;
- newDrawNode.posZ = _objList[nr]->_z;
- newDrawNode.width = 0;
- newDrawNode.height = 0;
- newDrawNode.s = objSurface;
- newDrawNode.originalRoomSurface = nullptr;
- if ((_objList[nr]->_flags & 0x2000)) {
- newDrawNode.data = nullptr;
- newDrawNode.drawFunction = &_graph->drawBackSpriteDrawNode;
- } else {
- newDrawNode.data = _transTable;
- if (_flags->getFlagValue(Flags::NOANTIALIAS)) {
- newDrawNode.drawFunction = &_graph->drawTransparentDrawNode;
- } else {
- newDrawNode.drawFunction = &_graph->drawTransparentWithTransDrawNode;
- }
- }
- _drawNodeList.push_back(newDrawNode);
- }
-
- if ((_objList[nr]->_flags & 1)) {
- checkMasks(_objList[nr]->_x, _objList[nr]->_y, objSurface->w, objSurface->h, _objList[nr]->_z);
- }
- }
- }
- }
-}
-
-void PrinceEngine::showParallax() {
- if (!_pscrList.empty()) {
- for (uint i = 0; i < _pscrList.size(); i++) {
- Graphics::Surface *pscrSurface = _pscrList[i]->getSurface();
- if (pscrSurface != nullptr) {
- int x = _pscrList[i]->_x - (_pscrList[i]->_step * _picWindowX / 4);
- int y = _pscrList[i]->_y;
- int z = PScr::kPScrZ;
- if (spriteCheck(pscrSurface->w, pscrSurface->h, x, y)) {
- showSprite(pscrSurface, x, y, z);
- }
- }
- }
- }
-}
-
-bool PrinceEngine::compareDrawNodes(DrawNode d1, DrawNode d2) {
- if (d1.posZ < d2.posZ) {
- return true;
- }
- return false;
-}
-
-void PrinceEngine::runDrawNodes() {
- Common::sort(_drawNodeList.begin(), _drawNodeList.end(), compareDrawNodes);
-
- for (uint i = 0; i < _drawNodeList.size(); i++) {
- (*_drawNodeList[i].drawFunction)(_graph->_frontScreen, &_drawNodeList[i]);
- }
- _graph->change();
-}
-
-void PrinceEngine::drawScreen() {
- if (!_showInventoryFlag || _inventoryBackgroundRemember) {
- clsMasks();
-
- _mainHero->showHero();
- _mainHero->scrollHero();
- _mainHero->drawHero();
-
- _secondHero->showHero();
- _secondHero->_drawX -= _picWindowX;
- _secondHero->drawHero();
-
- const Graphics::Surface *roomSurface;
- if (_locationNr != 50) {
- roomSurface = _roomBmp->getSurface();
- } else {
- roomSurface = _graph->_mapScreen;
- }
- Graphics::Surface visiblePart;
- if (roomSurface) {
- visiblePart = roomSurface->getSubArea(Common::Rect(_picWindowX, 0, roomSurface->w, roomSurface->h));
- _graph->draw(_graph->_frontScreen, &visiblePart);
- }
-
- showBackAnims();
-
- showNormAnims();
-
- playNextFLCFrame();
-
- showObjects();
-
- if (roomSurface) {
- insertMasks(&visiblePart);
- }
-
- showParallax();
-
- runDrawNodes();
-
- _drawNodeList.clear();
-
- if (!_inventoryBackgroundRemember && !_dialogFlag) {
- if (!_optionsFlag) {
- _selectedMob = checkMob(_graph->_frontScreen, _mobList, true);
- }
- showTexts(_graph->_frontScreen);
- checkOptions();
- } else {
- _inventoryBackgroundRemember = false;
- }
-
- showPower();
-
- getDebugger()->onFrame();
-
- } else {
- displayInventory();
- }
-}
-
-void PrinceEngine::blackPalette() {
- byte *paletteBackup = (byte *)malloc(256 * 3);
- byte *blackPalette1 = (byte *)malloc(256 * 3);
-
- int fadeStep = kFadeStep - 1;
- for (int i = 0; i < kFadeStep; i++) {
- _system->getPaletteManager()->grabPalette(paletteBackup, 0, 256);
- for (int j = 0; j < 256; j++) {
- blackPalette1[3 * j] = paletteBackup[3 * j] * fadeStep / 4;
- blackPalette1[3 * j + 1] = paletteBackup[3 * j + 1] * fadeStep / 4;
- blackPalette1[3 * j + 2] = paletteBackup[3 * j + 2] * fadeStep / 4;
- }
- fadeStep--;
- _graph->setPalette(blackPalette1);
- _system->updateScreen();
- Common::Event event;
- Common::EventManager *eventMan = _system->getEventManager();
- eventMan->pollEvent(event);
- if (shouldQuit()) {
- free(paletteBackup);
- free(blackPalette1);
- return;
- }
- pausePrinceEngine();
- }
- free(paletteBackup);
- free(blackPalette1);
-}
-
-void PrinceEngine::setPalette(const byte *palette) {
- if (palette != nullptr) {
- byte *blackPalette_ = (byte *)malloc(256 * 3);
- int fadeStep = 0;
- for (int i = 0; i <= kFadeStep; i++) {
- for (int j = 0; j < 256; j++) {
- blackPalette_[3 * j] = palette[3 * j] * fadeStep / 4;
- blackPalette_[3 * j + 1] = palette[3 * j + 1] * fadeStep / 4;
- blackPalette_[3 * j + 2] = palette[3 * j + 2] * fadeStep / 4;
- }
- fadeStep++;
- _graph->setPalette(blackPalette_);
- _system->updateScreen();
- Common::Event event;
- Common::EventManager *eventMan = _system->getEventManager();
- eventMan->pollEvent(event);
- if (shouldQuit()) {
- _graph->setPalette(palette);
- free(blackPalette_);
- return;
- }
- pausePrinceEngine();
- }
- _graph->setPalette(palette);
- free(blackPalette_);
- }
-}
-
void PrinceEngine::pausePrinceEngine(int fps) {
int delay = 1000 / fps - int32(_system->getMillis() - _currentTime);
delay = delay < 0 ? 0 : delay;