diff options
-rw-r--r-- | engines/prince/animation.cpp | 179 | ||||
-rw-r--r-- | engines/prince/animation.h | 35 | ||||
-rw-r--r-- | engines/prince/graphics.cpp | 2 | ||||
-rw-r--r-- | engines/prince/graphics.h | 1 | ||||
-rw-r--r-- | engines/prince/hero.cpp | 8 | ||||
-rw-r--r-- | engines/prince/prince.cpp | 71 | ||||
-rw-r--r-- | engines/prince/prince.h | 6 |
7 files changed, 155 insertions, 147 deletions
diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index ac0d0585e1..f5beb8674f 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -29,132 +29,155 @@ namespace Prince { bool Animation::loadFromStream(Common::SeekableReadStream &stream) { - _dataSize = stream.size(); - _data = (byte *)malloc(_dataSize); - - if (stream.read(_data, _dataSize) != _dataSize) { - free(_data); - return false; + _idXDiff = stream.readByte(); + _idYDiff = stream.readByte(); + _loopCount = stream.readUint16LE(); + _phaseCount = stream.readUint16LE(); + stream.skip(2); // skip _frameCount here + _baseX = stream.readUint16LE(); + _baseY = stream.readUint16LE(); + uint32 phaseTableOffset = stream.readUint32LE(); + uint32 tableOfFrameOffsets = stream.pos(); + + stream.seek(phaseTableOffset); + Phase tempPhase; + _frameCount = 0; + for (int phase = 0; phase < _phaseCount; phase++) { + tempPhase._phaseOffsetX = stream.readSint16LE(); + tempPhase._phaseOffsetY = stream.readSint16LE(); + tempPhase._phaseToFrameIndex = stream.readUint16LE(); + if (tempPhase._phaseToFrameIndex > _frameCount) { + _frameCount = tempPhase._phaseToFrameIndex; + } + _phaseList.push_back(tempPhase); + stream.skip(2); + } + if (_phaseCount) { + _frameCount++; } - return true; -} -Animation::Animation(): _data(NULL) { + for (int frame = 0; frame < _frameCount; frame++) { + stream.seek(tableOfFrameOffsets + frame * 4); + uint32 frameInfoOffset = stream.readUint32LE(); + stream.seek(frameInfoOffset); + uint16 frameWidth = stream.readUint16LE(); + uint16 frameHeight = stream.readUint16LE(); + uint32 frameDataPos = stream.pos(); + uint32 frameDataOffset = stream.readUint32BE(); + + Graphics::Surface *surf = new Graphics::Surface(); + surf->create(frameWidth, frameHeight, Graphics::PixelFormat::createFormatCLUT8()); + if (frameDataOffset == MKTAG('m', 'a', 's', 'm')) { + // Compressed + Decompressor dec; + uint32 ddataSize = stream.readUint32LE(); + byte *data = (byte *)malloc(ddataSize); + byte *ddata = (byte *)malloc(ddataSize); + + stream.read(data, ddataSize); + dec.decompress(data, ddata, ddataSize); + for (uint16 i = 0; i < frameHeight; i++) { + memcpy(surf->getBasePtr(0, i), ddata + frameWidth * i, frameWidth); + } + free(ddata); + free(data); + } else { + stream.seek(frameDataPos); + // Uncompressed + for (uint16 i = 0; i < frameHeight; i++) { + stream.read(surf->getBasePtr(0, i), frameWidth); + } + } + _frameList.push_back(surf); + } + return true; } -Animation::Animation(byte *data, uint32 dataSize) - : _data(data), _dataSize(dataSize) { +Animation::Animation() : _idXDiff(0), _idYDiff(0), _loopCount(0), _phaseCount(0), _frameCount(0), _baseX(0), _baseY(0) +{ } Animation::~Animation() { - free(_data); + clear(); } void Animation::clear() { - if (_data != NULL) { - free(_data); + _phaseList.clear(); + for (int i = 0; i < _frameCount; i++) { + _frameList[i]->free(); + delete _frameList[i]; + _frameList[i] = nullptr; } } -// AH_ID - TODO - if need this fix endianess bool Animation::testId() const { - char id[2]; - id[0] = (char)READ_LE_UINT16(_data); - id[1] = (char)READ_LE_UINT16(_data + 1); - if (id[0] == 'A' && id[1] == 'N') { - return true; // normal animation + if (_idXDiff == 'A' && _idYDiff == 'N') { + return true; } return false; } -// AH_ID - x diff int8 Animation::getIdXDiff() const { - return (int8)READ_LE_UINT16(_data); + return _idXDiff; } -// AH_ID - y diff int8 Animation::getIdYDiff() const { - return (int8)READ_LE_UINT16(_data + 1); + return _idYDiff; } -// AH_Loop int16 Animation::getLoopCount() const { - return READ_LE_UINT16(_data + 2); + return _loopCount; } -// AH_Fazy int32 Animation::getPhaseCount() const { - return READ_LE_UINT16(_data + 4); + return _phaseCount; } -// AH_Ramki int32 Animation::getFrameCount() const { - return READ_LE_UINT16(_data + 6); + return _frameCount; } -// AH_X int16 Animation::getBaseX() const { - return READ_LE_UINT16(_data + 8); + return _baseX; } -// AH_Y int16 Animation::getBaseY() const { - return READ_LE_UINT16(_data + 10); -} - -byte *Animation::getPhaseEntry(uint phaseIndex) const { - return _data + READ_LE_UINT32(_data + 12) + phaseIndex * 8; -} - -int16 Animation::getPhaseOffsetX(uint phaseIndex) const { - return READ_LE_UINT16(getPhaseEntry(phaseIndex) + 0); + return _baseY; } -int16 Animation::getPhaseOffsetY(uint phaseIndex) const { - return READ_LE_UINT16(getPhaseEntry(phaseIndex) + 2); -} - -int16 Animation::getPhaseFrameIndex(uint phaseIndex) const { - return READ_LE_UINT16(getPhaseEntry(phaseIndex) + 4); +int16 Animation::getPhaseOffsetX(int phaseIndex) const { + if (phaseIndex < _phaseCount) { + return _phaseList[phaseIndex]._phaseOffsetX; + } else { + error("getPhaseOffsetX() phaseIndex: %d, phaseCount: %d", phaseIndex, _phaseCount); + } } -int16 Animation::getFrameWidth(uint frameIndex) const { - byte *frameData = _data + READ_LE_UINT32(_data + 16 + frameIndex * 4); - return READ_LE_UINT16(frameData + 0); +int16 Animation::getPhaseOffsetY(int phaseIndex) const { + if (phaseIndex < _phaseCount) { + return _phaseList[phaseIndex]._phaseOffsetY; + } else { + error("getPhaseOffsetY() phaseIndex: %d, phaseCount: %d", phaseIndex, _phaseCount); + } } -int16 Animation::getFrameHeight(uint frameIndex) const { - byte *frameData = _data + READ_LE_UINT32(_data + 16 + frameIndex * 4); - return READ_LE_UINT16(frameData + 2); +int16 Animation::getPhaseFrameIndex(int phaseIndex) const { + if (phaseIndex < _phaseCount) { + return _phaseList[phaseIndex]._phaseToFrameIndex; + } else { + error("getPhaseFrameIndex() phaseIndex: %d, phaseCount: %d", phaseIndex, _phaseCount); + } } -Graphics::Surface *Animation::getFrame(uint frameIndex) { - byte *frameData = _data + READ_LE_UINT32(_data + 16 + frameIndex * 4); - int16 width = READ_LE_UINT16(frameData + 0); - int16 height = READ_LE_UINT16(frameData + 2); - //debug("width = %d; height = %d", width, height); - Graphics::Surface *surf = new Graphics::Surface(); - surf->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); - //debug("frameData %p", frameData); - if (READ_BE_UINT32(frameData + 4) == MKTAG('m', 'a', 's', 'm')) { - // Compressed - Decompressor dec; - uint32 ddataSize = READ_LE_UINT32(frameData + 8); - byte *ddata = (byte *)malloc(ddataSize); - dec.decompress(frameData + 12, ddata, ddataSize); - for (uint16 i = 0; i < height; i++) { - memcpy(surf->getBasePtr(0, i), ddata + width * i, width); - } - free(ddata); +Graphics::Surface *Animation::getFrame(int frameIndex) { + if (frameIndex < _frameCount) { + return _frameList[frameIndex]; } else { - // Uncompressed - for (uint16 i = 0; i < height; i++) { - memcpy(surf->getBasePtr(0, i), frameData + 4 + width * i, width); - } + error("getFrame() frameIndex: %d, frameCount: %d", frameIndex, _frameCount); } - return surf; -} } +} // End of namespace Prince + /* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/animation.h b/engines/prince/animation.h index 09ebf7d8b9..23a1b5808a 100644 --- a/engines/prince/animation.h +++ b/engines/prince/animation.h @@ -32,32 +32,39 @@ namespace Prince { class Animation { public: - bool loadFromStream(Common::SeekableReadStream &stream); - Animation(); - Animation(byte *data, uint32 dataSize); ~Animation(); + bool loadFromStream(Common::SeekableReadStream &stream); + bool testId() const; int8 getIdXDiff() const; int8 getIdYDiff() const; int16 getLoopCount() const; - int16 getBaseX() const; - int16 getBaseY() const; int32 getPhaseCount() const; int32 getFrameCount() const; - int16 getPhaseOffsetX(uint phaseIndex) const; - int16 getPhaseOffsetY(uint phaseIndex) const; - int16 getPhaseFrameIndex(uint phaseIndex) const; - Graphics::Surface *getFrame(uint frameIndex); - int16 getFrameWidth(uint frameIndex) const; - int16 getFrameHeight(uint frameIndex) const; + int16 getBaseX() const; + int16 getBaseY() const; + int16 getPhaseOffsetX(int phaseIndex) const; + int16 getPhaseOffsetY(int phaseIndex) const; + int16 getPhaseFrameIndex(int phaseIndex) const; + Graphics::Surface *getFrame(int frameIndex); void clear(); private: + struct Phase { + int16 _phaseOffsetX; + int16 _phaseOffsetY; + uint16 _phaseToFrameIndex; + }; Common::Array<Graphics::Surface *> _frameList; - byte *_data; - uint32 _dataSize; - byte *getPhaseEntry(uint phaseIndex) const; + Common::Array<Phase> _phaseList; + int8 _idXDiff; + int8 _idYDiff; + int16 _loopCount; + int16 _phaseCount; + int32 _frameCount; + int16 _baseX; + int16 _baseY; }; } diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 195c61b5f0..58ab7b0f21 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -381,6 +381,6 @@ void GraphicsMan::makeShadowTable(int brightness, byte *shadowPalette) { } } -} +} // End of namespace Prince /* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index f4e7f37d89..57e28fdae5 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -25,7 +25,6 @@ #include "graphics/surface.h" - namespace Prince { class PrinceEngine; diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 3b5403532c..bb6d07e524 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -191,12 +191,16 @@ void Hero::countDrawPosition() { // any chance? if (baseX == 320) { tempMiddleY = _middleY - (baseY - 240); + if (baseY != 240) { + error("Hero::countDrawPosition() - tempMiddleY"); + } } else { tempMiddleY = _middleY; } int phaseFrameIndex = heroAnim->getPhaseFrameIndex(_phase); - _frameXSize = heroAnim->getFrameWidth(phaseFrameIndex); - _frameYSize = heroAnim->getFrameHeight(phaseFrameIndex); + Graphics::Surface *heroSurface = heroAnim->getFrame(phaseFrameIndex); + _frameXSize = heroSurface->w; + _frameYSize = heroSurface->h; _scaledFrameXSize = getScaledValue(_frameXSize); _scaledFrameYSize = getScaledValue(_frameYSize); diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 3fe43e6ed9..34af04b7d2 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -149,7 +149,7 @@ PrinceEngine::~PrinceEngine() { } _maskList.clear(); - freeDrawNodes(); + _drawNodeList.clear(); clearBackAnimList(); @@ -461,8 +461,6 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _mobList[i]._visible = _script->getMobVisible(_room->_mobs, i); } - freeDrawNodes(); - _script->installObjects(_room->_obj); clearBackAnimList(); @@ -1020,8 +1018,6 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array<Mob> &mobLis int phaseFrameIndex = backAnim._animData->getPhaseFrameIndex(phase); Graphics::Surface *backAnimSurface = backAnim._animData->getFrame(phaseFrameIndex); byte pixel = *(byte *)backAnimSurface->getBasePtr(mousePosCamera.x - backAnim._currX, mousePosCamera.y - backAnim._currY); - backAnimSurface->free(); - delete backAnimSurface; if (pixel != 255) { if (type == 5) { if (mob->_rect.contains(mousePosCamera)) { @@ -1311,14 +1307,13 @@ void PrinceEngine::showMask(int maskNr, Graphics::Surface *originalRoomSurface) newDrawNode.s = nullptr; newDrawNode.originalRoomSurface = originalRoomSurface; newDrawNode.data = _maskList[maskNr].getMask(); - newDrawNode.freeSurfaceSMemory = false; newDrawNode.drawFunction = &_graph->drawMaskDrawNode; _drawNodeList.push_back(newDrawNode); } } } -void PrinceEngine::showSprite(Graphics::Surface *spriteSurface, int destX, int destY, int destZ, bool freeSurfaceMemory) { +void PrinceEngine::showSprite(Graphics::Surface *spriteSurface, int destX, int destY, int destZ) { if (spriteCheck(spriteSurface->w, spriteSurface->h, destX, destY)) { destX -= _picWindowX; destY -= _picWindowY; @@ -1331,16 +1326,12 @@ void PrinceEngine::showSprite(Graphics::Surface *spriteSurface, int destX, int d newDrawNode.s = spriteSurface; newDrawNode.originalRoomSurface = nullptr; newDrawNode.data = nullptr; - newDrawNode.freeSurfaceSMemory = freeSurfaceMemory; newDrawNode.drawFunction = &_graph->drawTransparentDrawNode; _drawNodeList.push_back(newDrawNode); - } else if (freeSurfaceMemory) { - spriteSurface->free(); - delete spriteSurface; } } -void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY, int destZ, bool freeSurfaceMemory) { +void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY, int destZ) { if (spriteCheck(shadowSurface->w, shadowSurface->h, destX, destY)) { destX -= _picWindowX; destY -= _picWindowY; @@ -1353,12 +1344,8 @@ void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX, newDrawNode.s = shadowSurface; newDrawNode.originalRoomSurface = nullptr; newDrawNode.data = _graph->_shadowTable70; - newDrawNode.freeSurfaceSMemory = freeSurfaceMemory; newDrawNode.drawFunction = &_graph->drawAsShadowDrawNode; _drawNodeList.push_back(newDrawNode); - } else if (freeSurfaceMemory) { - shadowSurface->free(); - delete shadowSurface; } } @@ -1376,8 +1363,9 @@ void PrinceEngine::showAnim(Anim &anim) { int maxFrontFlag = (animFlag & 2); int specialZFlag = anim._nextAnim; int z = anim._nextAnim; - int frameWidth = anim._animData->getFrameWidth(phaseFrameIndex); - int frameHeight = anim._animData->getFrameHeight(phaseFrameIndex); + Graphics::Surface *backAnimSurface = anim._animData->getFrame(phaseFrameIndex); + int frameWidth = backAnimSurface->w; + int frameHeight = backAnimSurface->h; int shadowZ = 0; if (x != 0 || y != 0 || phaseCount != 1 || frameCount != 1) { // TODO - check if this needed @@ -1402,8 +1390,7 @@ void PrinceEngine::showAnim(Anim &anim) { anim._currY = y; anim._currW = frameWidth; anim._currH = frameHeight; - Graphics::Surface *backAnimSurface = anim._animData->getFrame(phaseFrameIndex); // TODO - check for memory leak - showSprite(backAnimSurface, x, y, z, true); + showSprite(backAnimSurface, x, y, z); } //ShowFrameCodeShadow @@ -1412,8 +1399,9 @@ void PrinceEngine::showAnim(Anim &anim) { int shadowPhaseFrameIndex = anim._shadowData->getPhaseFrameIndex(phase); int shadowX = anim._shadowData->getBaseX() + anim._shadowData->getPhaseOffsetX(phase); int shadowY = anim._shadowData->getBaseY() + anim._shadowData->getPhaseOffsetY(phase); - int shadowFrameWidth = anim._shadowData->getFrameWidth(shadowPhaseFrameIndex); - int shadowFrameHeight = anim._shadowData->getFrameHeight(shadowPhaseFrameIndex); + Graphics::Surface *shadowSurface = anim._shadowData->getFrame(shadowPhaseFrameIndex); + int shadowFrameWidth = shadowSurface->w; + int shadowFrameHeight = shadowSurface->h; if (checkMaskFlag) { checkMasks(shadowX, shadowY, shadowFrameWidth, shadowFrameHeight, shadowY + shadowFrameWidth - 1); @@ -1426,9 +1414,7 @@ void PrinceEngine::showAnim(Anim &anim) { shadowZ = shadowY + shadowFrameWidth - 1; } } - - Graphics::Surface *shadowSurface = anim._shadowData->getFrame(shadowPhaseFrameIndex); // TODO - check for memory leak - showSpriteShadow(shadowSurface, shadowX, shadowY, shadowZ, true); + showSpriteShadow(shadowSurface, shadowX, shadowY, shadowZ); } } @@ -1436,6 +1422,7 @@ void PrinceEngine::showNormAnims() { for (int i = 0; i < kMaxNormAnims; i++) { Anim &anim = _normAnimList[i]; if (anim._animData != nullptr) { + int phaseCount = anim._animData->getPhaseCount(); if (!anim._state) { if (anim._frame == anim._lastFrame - 1) { if (anim._loopType) { @@ -1448,7 +1435,9 @@ void PrinceEngine::showNormAnims() { } else { anim._frame++; } - anim._showFrame = anim._frame; + if (anim._frame < phaseCount - 1) { + anim._showFrame = anim._frame; + } showAnim(anim); } } @@ -1721,7 +1710,6 @@ void PrinceEngine::showObjects() { newDrawNode.s = objSurface; newDrawNode.originalRoomSurface = nullptr; newDrawNode.data = nullptr; - newDrawNode.freeSurfaceSMemory = false; if ((_objList[nr]->_flags & 0x2000)) { newDrawNode.drawFunction = &_graph->drawBackSpriteDrawNode; @@ -1747,7 +1735,7 @@ void PrinceEngine::showParallax() { int y = _pscrList[i]->_y; int z = 1000; if (spriteCheck(pscrSurface->w, pscrSurface->h, x, y)) { - showSprite(pscrSurface, x, y, z, false); + showSprite(pscrSurface, x, y, z); } } } @@ -1769,17 +1757,6 @@ void PrinceEngine::runDrawNodes() { _graph->change(); } - -void PrinceEngine::freeDrawNodes() { - for (uint i = 0; i < _drawNodeList.size(); i++) { - if (_drawNodeList[i].freeSurfaceSMemory) { - _drawNodeList[i].s->free(); - delete _drawNodeList[i].s; - } - } - _drawNodeList.clear(); -} - void PrinceEngine::drawScreen() { clsMasks(); @@ -1802,7 +1779,8 @@ void PrinceEngine::drawScreen() { _graph->draw(_graph->_frontScreen, &visiblePart); } - Graphics::Surface *mainHeroSurface = NULL; + Graphics::Surface *mainHeroSurface = nullptr; + Graphics::Surface *zoomedHeroSurface = nullptr; if (_mainHero->_visible) { mainHeroSurface = _mainHero->getSurface(); if (mainHeroSurface) { @@ -1819,12 +1797,10 @@ void PrinceEngine::drawScreen() { newDrawNode.drawFunction = &_graph->drawTransparentDrawNode; if (_mainHero->_zoomFactor) { - Graphics::Surface *zoomedHeroSurface = _mainHero->zoomSprite(mainHeroSurface); + zoomedHeroSurface = _mainHero->zoomSprite(mainHeroSurface); newDrawNode.s = zoomedHeroSurface; - newDrawNode.freeSurfaceSMemory = true; } else { newDrawNode.s = mainHeroSurface; - newDrawNode.freeSurfaceSMemory = false; } _drawNodeList.push_back(newDrawNode); } @@ -1846,11 +1822,12 @@ void PrinceEngine::drawScreen() { runDrawNodes(); - freeDrawNodes(); + _drawNodeList.clear(); - if (_mainHero->_visible) { - mainHeroSurface->free(); - delete mainHeroSurface; + if (zoomedHeroSurface != nullptr) { + zoomedHeroSurface->free(); + delete zoomedHeroSurface; + zoomedHeroSurface = nullptr; } if (!_inventoryBackgroundRemember && !_dialogFlag) { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index eef583222f..ac898aaf57 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -233,7 +233,6 @@ struct DrawNode { Graphics::Surface *s; Graphics::Surface *originalRoomSurface; byte *data; - bool freeSurfaceSMemory; void (*drawFunction)(Graphics::Surface *, DrawNode *); }; @@ -566,13 +565,12 @@ private: void showBackAnims(); void clearBackAnimList(); bool spriteCheck(int sprWidth, int sprHeight, int destX, int destY); - void showSprite(Graphics::Surface *spriteSurface, int destX, int destY, int destZ, bool freeSurfaceMemory); - void showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY, int destZ, bool freeSurfaceMemory); + void showSprite(Graphics::Surface *spriteSurface, int destX, int destY, int destZ); + void showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY, int destZ); void showObjects(); void showParallax(); static bool compareDrawNodes(DrawNode d1, DrawNode d2); void runDrawNodes(); - void freeDrawNodes(); void makeShadowTable(int brightness); void pause(); |