aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/prince/prince.cpp131
-rw-r--r--engines/prince/prince.h8
-rw-r--r--engines/prince/script.cpp30
3 files changed, 167 insertions, 2 deletions
diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp
index 0df1f778c6..ddf64b7b52 100644
--- a/engines/prince/prince.cpp
+++ b/engines/prince/prince.cpp
@@ -144,6 +144,8 @@ PrinceEngine::~PrinceEngine() {
clearBackAnimList();
+ freeAllNormAnims();
+
for (uint i = 0; i < _allInvList.size(); i++) {
_allInvList[i]._surface->free();
delete _allInvList[i]._surface;
@@ -272,6 +274,13 @@ void PrinceEngine::init() {
_mainHero->loadAnimSet(1);
_secondHero->loadAnimSet(3);
+
+ Anim tempAnim;
+ tempAnim._animData = nullptr;
+ tempAnim._shadowData = nullptr;
+ for (int i = 0; i < kMaxNormAnims; i++) {
+ _normAnimList.push_back(tempAnim);
+ }
}
void PrinceEngine::showLogo() {
@@ -1172,6 +1181,105 @@ void PrinceEngine::showSpriteShadow(Graphics::Surface *shadowSurface, int destX,
}
}
+void PrinceEngine::showAnim(Anim &anim) {
+ //ShowFrameCode
+ //ShowAnimFrame
+ int phaseCount = anim._animData->getPhaseCount();
+ int frameCount = anim._animData->getFrameCount();
+ int phase = anim._showFrame;
+ int phaseFrameIndex = anim._animData->getPhaseFrameIndex(phase);
+ int x = anim._x + anim._animData->getPhaseOffsetX(phase);
+ int y = anim._y + anim._animData->getPhaseOffsetY(phase);
+ int animFlag = anim._flags;
+ int checkMaskFlag = (animFlag & 1);
+ int maxFrontFlag = (animFlag & 2);
+ int specialZFlag = anim._nextAnim;
+ int z = anim._nextAnim;
+ int frameWidth = anim._animData->getFrameWidth(phaseFrameIndex);
+ int frameHeight = anim._animData->getFrameHeight(phaseFrameIndex);
+ int shadowZ = 0;
+
+ if (x != 0 || y != 0 || phaseCount != 1 || frameCount != 1) { // TODO - check if this needed
+
+ if (checkMaskFlag != 0) {
+ if (anim._nextAnim == 0) {
+ z = y + frameHeight - 1;
+ }
+ checkMasks(x, y, frameWidth, frameHeight, z);
+ }
+
+ if (specialZFlag != 0) {
+ z = specialZFlag;
+ } else if (maxFrontFlag != 0) {
+ z = kMaxPicHeight + 1;
+ } else {
+ z = y + frameHeight - 1;
+ }
+ shadowZ = z;
+
+ anim._currX = x;
+ anim._currY = y;
+ anim._currW = frameWidth;
+ anim._currH = frameHeight;
+ Graphics::Surface *backAnimSurface = anim._animData->getFrame(phaseFrameIndex); // TODO - check for memory leak
+ showSprite(backAnimSurface, x, y, z, true);
+ }
+
+ //ShowFrameCodeShadow
+ //ShowAnimFrameShadow
+ if (anim._shadowData != nullptr) {
+ int shadowPhaseFrameIndex = anim._shadowData->getPhaseFrameIndex(phase);
+ int shadowX = anim._shadowData->getBaseX() + anim._shadowData->getPhaseOffsetX(phase);
+ int shadowY = anim._shadowData->getBaseY() + anim._shadowData->getPhaseOffsetY(phase);
+ int shadowFrameWidth = anim._shadowData->getFrameWidth(shadowPhaseFrameIndex);
+ int shadowFrameHeight = anim._shadowData->getFrameHeight(shadowPhaseFrameIndex);
+
+ if (checkMaskFlag != 0) {
+ checkMasks(shadowX, shadowY, shadowFrameWidth, shadowFrameHeight, shadowY + shadowFrameWidth - 1);
+ }
+
+ if (shadowZ == 0) {
+ if (maxFrontFlag != 0) {
+ shadowZ = kMaxPicHeight + 1;
+ } else {
+ shadowZ = shadowY + shadowFrameWidth - 1;
+ }
+ }
+
+ Graphics::Surface *shadowSurface = anim._shadowData->getFrame(shadowPhaseFrameIndex); // TODO - check for memory leak
+ showSpriteShadow(shadowSurface, shadowX, shadowY, shadowZ, true);
+ }
+}
+
+void PrinceEngine::showNormAnims() {
+ for (int i = 0; i < kMaxNormAnims; i++) {
+ Anim &anim = _normAnimList[i];
+ if (anim._animData != nullptr) {
+ if (!anim._state) {
+ if (anim._frame == anim._lastFrame) {
+ if (anim._loopType) {
+ if (anim._loopType == 1) {
+ anim._frame = anim._loopFrame;
+ } else {
+ continue;
+ }
+ } else {
+ if (anim._frame >= 1) {
+ anim._frame--;
+ } else {
+ anim._frame = 0;
+ }
+ }
+ } else {
+ anim._frame++;
+ }
+ anim._showFrame = anim._frame;
+ showAnim(anim);
+ }
+ }
+ }
+}
+
void PrinceEngine::showBackAnims() {
for (uint i = 0; i < _backAnimList.size(); i++) {
int activeSubAnim = _backAnimList[i]._seq._currRelative;
@@ -1507,6 +1615,8 @@ void PrinceEngine::drawScreen() {
}
}
+ showNormAnims();
+
showBackAnims();
showObjects();
@@ -2387,6 +2497,27 @@ void PrinceEngine::testDialog() {
}
}
+void PrinceEngine::freeNormAnim(int slot) {
+ _normAnimList[slot]._state = 1;
+ delete _normAnimList[slot]._animData;
+ _normAnimList[slot]._animData = nullptr;
+ delete _normAnimList[slot]._shadowData;
+ _normAnimList[slot]._shadowData = nullptr;
+ _normAnimList[slot]._currFrame = 0;
+}
+
+void PrinceEngine::freeAllNormAnims() {
+ for (int i = 0; i < kMaxNormAnims; i++) {
+ if (_normAnimList[i]._animData != nullptr) {
+ delete _normAnimList[i]._animData;
+ }
+ if (_normAnimList[i]._shadowData != nullptr) {
+ delete _normAnimList[i]._shadowData;
+ }
+ }
+ _normAnimList.clear();
+}
+
void PrinceEngine::mainLoop() {
changeCursor(0);
diff --git a/engines/prince/prince.h b/engines/prince/prince.h
index d6bdad376f..fdf5aa15b8 100644
--- a/engines/prince/prince.h
+++ b/engines/prince/prince.h
@@ -299,11 +299,17 @@ public:
Room *_room;
Script *_script;
+ static const int kMaxNormAnims = 64;
+
Common::Array<AnimListItem> _animList;
Common::Array<BackgroundAnim> _backAnimList;
+ Common::Array<Anim> _normAnimList;
Common::Array<Common::Array<DialogLine>> _dialogBoxList;
Common::Array<Mob> _mobList;
+ void freeNormAnim(int slot);
+ void freeAllNormAnims();
+
Common::RandomSource _randomSource;
static const int16 kNormalWidth = 640;
@@ -411,6 +417,8 @@ private:
void showTexts(Graphics::Surface *screen);
void init();
void showLogo();
+ void showAnim(Anim &anim);
+ void showNormAnims();
void showBackAnims();
void clearBackAnimList();
bool spriteCheck(int sprWidth, int sprHeight, int destX, int destY);
diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp
index 5d8ba5d996..37f6724b36 100644
--- a/engines/prince/script.cpp
+++ b/engines/prince/script.cpp
@@ -606,7 +606,32 @@ void Interpreter::O_REMOBJECT() {
void Interpreter::O_SHOWANIM() {
uint16 slot = readScriptFlagValue();
uint16 animId = readScriptFlagValue();
-
+ _vm->freeNormAnim(slot);
+ Anim &anim = _vm->_normAnimList[slot];
+ AnimListItem &animList = _vm->_animList[animId];
+ anim._currFrame = 0;
+ anim._packFlag = 0;
+ anim._state = 0;
+ anim._frame = animList._startPhase;
+ anim._showFrame = animList._startPhase;
+ anim._lastFrame = animList._endPhase;
+ anim._loopFrame = animList._loopPhase;
+ anim._x = animList._x;
+ anim._y = animList._y;
+ anim._loopType = animList._loopType;
+ anim._shadowBack = animList._type;
+ anim._flags = animList._flags;
+ anim._nextAnim = animList._nextAnim;
+ int fileNumber = animList._fileNumber;
+ const Common::String animName = Common::String::format("AN%02d", fileNumber);
+ const Common::String shadowName = Common::String::format("AN%02dS", fileNumber);
+ anim._animData = new Animation();
+ anim._shadowData = new Animation();
+ Resource::loadResource(anim._animData, animName.c_str(), true);
+ if (!Resource::loadResource(anim._shadowData, shadowName.c_str(), false)) {
+ delete anim._shadowData;
+ anim._shadowData = nullptr;
+ }
debugInterpreter("O_SHOWANIM slot %d, animId %d", slot, animId);
}
@@ -620,6 +645,7 @@ void Interpreter::O_CHECKANIMEND() {
void Interpreter::O_FREEANIM() {
uint16 slot = readScriptFlagValue();
+ _vm->freeNormAnim(slot);
debugInterpreter("O_FREEANIM slot %d", slot);
}
@@ -650,10 +676,10 @@ void Interpreter::O_CHECKBACKANIMFRAME() {
uint16 frameId = readScriptFlagValue();
int currAnim = _vm->_backAnimList[slotId]._seq._currRelative;
if (_vm->_backAnimList[slotId].backAnims[currAnim]._frame != frameId) {
- debugInterpreter("O_CHECKBACKANIMFRAME slotId %d, frameId %d", slotId, frameId);
//esi -= 6; loop of this OP?
_opcodeNF = 1;
}
+ debugInterpreter("O_CHECKBACKANIMFRAME slotId %d, frameId %d", slotId, frameId);
}
void Interpreter::O_FREEALLSAMPLES() {