diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/prince/draw.cpp | 705 | ||||
-rw-r--r-- | engines/prince/mob.cpp | 158 | ||||
-rw-r--r-- | engines/prince/module.mk | 1 | ||||
-rw-r--r-- | engines/prince/prince.cpp | 828 |
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; |