TRECISION: Fix drawing frames from disabled animations - bugs #12624, #12626

Fixes the chain shown incorrectly when entering the platforms and the
shopkeeper's wife appearing frozen after she's left the storeroom
This commit is contained in:
Filippos Karapetis
2021-06-14 03:56:13 +03:00
parent a40a796b9e
commit 039cf08f4f
+29 -13
View File
@@ -436,14 +436,16 @@ void AnimManager::refreshSmkAnim(uint16 animation) {
handleEndOfVideo(animation, kSmackerAction);
}
for (int32 a = 0; a < MAXCHILD; a++) {
if (!(_animTab[animation]._flag & (SMKANIM_OFF1 << a)) && (_animTab[animation]._lim[a].bottom != 0)) {
_vm->_graphicsMgr->addDirtyRect(_animTab[animation]._lim[a], true);
for (int32 i = 0; i < MAXCHILD; i++) {
if (!(_animTab[animation]._flag & (SMKANIM_OFF1 << i)) && _animTab[animation]._lim[i].bottom != 0) {
_vm->_graphicsMgr->addDirtyRect(_animTab[animation]._lim[i], true);
}
}
}
void AnimManager::handleEndOfVideo(int animation, int slot) {
const bool isLoopingOrBackground = (_animTab[animation]._flag & SMKANIM_LOOP) || (_animTab[animation]._flag & SMKANIM_BKG);
if (_smkAnims[slot] == nullptr) {
smkStop(slot);
return;
@@ -451,7 +453,7 @@ void AnimManager::handleEndOfVideo(int animation, int slot) {
if (!_smkAnims[slot]->endOfFrames())
return;
if (!(_animTab[animation]._flag & SMKANIM_LOOP) && !(_animTab[animation]._flag & SMKANIM_BKG)) {
if (!isLoopingOrBackground) {
smkStop(slot);
_vm->_flagPaintCharacter = true;
} else {
@@ -461,6 +463,10 @@ void AnimManager::handleEndOfVideo(int animation, int slot) {
}
}
static bool rectsIntersect(Common::Rect r1, Common::Rect r2) {
return (r1.left <= r2.right) && (r1.right >= r2.left) && (r1.top <= r2.bottom) && (r1.bottom >= r2.top);
}
void AnimManager::drawSmkBackgroundFrame(int animation) {
NightlongSmackerDecoder *smkDecoder = _smkAnims[kSmackerBackground];
if (smkDecoder == nullptr)
@@ -473,20 +479,30 @@ void AnimManager::drawSmkBackgroundFrame(int animation) {
const byte *palette = smkDecoder->getPalette();
if (smkDecoder->getCurFrame() == 0 && !_bgAnimRestarted) {
_vm->_graphicsMgr->blitToScreenBuffer(frame, 0, TOP, palette, true);
bool drawFrame = true;
for (int32 i = 0; i < MAXCHILD; i++) {
if ((_animTab[animation]._flag & (SMKANIM_OFF1 << i))) {
drawFrame = false;
break;
}
}
if (drawFrame)
_vm->_graphicsMgr->blitToScreenBuffer(frame, 0, TOP, palette, true);
} else {
while (lastRect) {
bool intersects = false;
for (int32 a = 0; a < MAXCHILD; a++) {
if (_animTab[animation]._flag & (SMKANIM_OFF1 << a)) {
if (_animTab[animation]._lim[a].intersects(*lastRect)) {
intersects = true;
break;
}
bool drawDirtyRect = true;
for (int32 i = 0; i < MAXCHILD; i++) {
const bool intersect = rectsIntersect(_animTab[animation]._lim[i], *lastRect);
if ((_animTab[animation]._flag & (SMKANIM_OFF1 << i)) && intersect) {
drawDirtyRect = false;
break;
}
}
if (smkDecoder->getCurFrame() > 0 && !intersects) {
if (smkDecoder->getCurFrame() > 0 && drawDirtyRect) {
Graphics::Surface anim = frame->getSubArea(*lastRect);
_vm->_graphicsMgr->blitToScreenBuffer(&anim, lastRect->left, lastRect->top + TOP, palette, true);
}