aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/prince/animation.cpp179
-rw-r--r--engines/prince/animation.h35
-rw-r--r--engines/prince/graphics.cpp2
-rw-r--r--engines/prince/graphics.h1
-rw-r--r--engines/prince/hero.cpp8
-rw-r--r--engines/prince/prince.cpp71
-rw-r--r--engines/prince/prince.h6
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();