[Scummvm-git-logs] scummvm master -> 750e2060bf35b44b344d9cabc20d5f23cfa8b87e
phcoder
noreply at scummvm.org
Sun Jan 29 06:21:17 UTC 2023
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
750e2060bf NEVERHOOD: Fix crash on expiring animated sprite backref
Commit: 750e2060bf35b44b344d9cabc20d5f23cfa8b87e
https://github.com/scummvm/scummvm/commit/750e2060bf35b44b344d9cabc20d5f23cfa8b87e
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-01-29T07:19:36+01:00
Commit Message:
NEVERHOOD: Fix crash on expiring animated sprite backref
Thanks a lot to -=CHE at TER=- for discovering this and excellent debugging
work.
Changed paths:
engines/neverhood/sprite.cpp
engines/neverhood/sprite.h
diff --git a/engines/neverhood/sprite.cpp b/engines/neverhood/sprite.cpp
index 8cc058c47be..c79e2a87a83 100644
--- a/engines/neverhood/sprite.cpp
+++ b/engines/neverhood/sprite.cpp
@@ -183,13 +183,13 @@ void StaticSprite::updatePosition() {
// AnimatedSprite
AnimatedSprite::AnimatedSprite(NeverhoodEngine *vm, int objectPriority)
- : Sprite(vm, objectPriority), _animResource(vm), _subtitleSurface(new AnimatedSpriteSubtitles(vm, this)) {
+ : Sprite(vm, objectPriority), _animResource(vm), _subtitleSurface(new AnimatedSpriteSubtitles(vm)) {
init();
}
AnimatedSprite::AnimatedSprite(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority, int16 x, int16 y)
- : Sprite(vm, 1100), _animResource(vm), _subtitleSurface(new AnimatedSpriteSubtitles(vm, this)) {
+ : Sprite(vm, 1100), _animResource(vm), _subtitleSurface(new AnimatedSpriteSubtitles(vm)) {
init();
SetUpdateHandler(&AnimatedSprite::update);
@@ -224,6 +224,8 @@ void AnimatedSprite::init() {
_plFirstFrameHash = 0;
_plLastFrameHash = 0;
_animStatus = 0;
+ if (_subtitleSurface)
+ _subtitleSurface->setFrameIndex(-1, 0);
}
void AnimatedSprite::update() {
@@ -309,7 +311,8 @@ void AnimatedSprite::updateAnim() {
if (_animStatus == 1) {
if (_animResource.load(_newAnimFileHash)) {
_currAnimFileHash = _newAnimFileHash;
- _subtitles.reset(new SubtitlePlayer(_vm, _newAnimFileHash, kSubtitleWidth));
+ if (_subtitleSurface)
+ _subtitleSurface->setHash(_newAnimFileHash);
} else {
_animResource.load(calcHash("sqDefault"));
_currAnimFileHash = 0;
@@ -323,7 +326,8 @@ void AnimatedSprite::updateAnim() {
} else {
if (_animResource.load(_newAnimFileHash)) {
_currAnimFileHash = _newAnimFileHash;
- _subtitles.reset(new SubtitlePlayer(_vm, _newAnimFileHash, kSubtitleWidth));
+ if (_subtitleSurface)
+ _subtitleSurface->setHash(_newAnimFileHash);
} else {
_animResource.load(calcHash("sqDefault"));
_currAnimFileHash = 0;
@@ -348,6 +352,8 @@ void AnimatedSprite::updateAnim() {
}
+ if (_subtitleSurface)
+ _subtitleSurface->setFrameIndex(_currFrameIndex, _lastFrameIndex);
}
void AnimatedSprite::updatePosition() {
@@ -367,11 +373,7 @@ void AnimatedSprite::updatePosition() {
_surface->getDrawRect().y = filterY(_y + _drawOffset.y);
}
- int subCenterX = _surface->getDrawRect().x + _surface->getDrawRect().width / 2;
- _subtitleSurface->getDrawRect().x = MAX(subCenterX - kSubtitleWidth / 2, 0);
- _subtitleSurface->getDrawRect().width = kSubtitleWidth;
- _subtitleSurface->getDrawRect().y = MIN(_surface->getDrawRect().y + _surface->getDrawRect().height + 1, 480 - (SubtitlePlayer::kSubtitleCharHeight - 1));
- _subtitleSurface->getDrawRect().height = SubtitlePlayer::kSubtitleCharHeight;
+ _subtitleSurface->updatePosition(_surface->getDrawRect());
if (_needRefresh) {
_surface->drawAnimResource(_animResource, _currFrameIndex, _doDeltaX, _doDeltaY, _drawOffset.width, _drawOffset.height);
@@ -400,23 +402,42 @@ void AnimatedSprite::updateFrameIndex() {
_currFrameIndex = _lastFrameIndex;
}
}
+
+ if (_subtitleSurface)
+ _subtitleSurface->setFrameIndex(_currFrameIndex, _lastFrameIndex);
+}
+
+AnimatedSprite::AnimatedSpriteSubtitles::AnimatedSpriteSubtitles(NeverhoodEngine *vm) :
+ BaseSurface(vm, 0xffff, kSubtitleWidth, SubtitlePlayer::kSubtitleCharHeight, "animated sprite subtitles"), _currFrameIndex(-1), _subCenterX(320) {
+}
+
+void AnimatedSprite::AnimatedSpriteSubtitles::setHash(uint32 fileHash) {
+ _subtitles.reset(new SubtitlePlayer(_vm, fileHash, kSubtitleWidth));
+}
+
+void AnimatedSprite::AnimatedSpriteSubtitles::setFrameIndex(int currFrameIndex, int lastFrameIndex) {
+ if (currFrameIndex > 0 && currFrameIndex < lastFrameIndex)
+ _currFrameIndex = currFrameIndex;
+ else
+ _currFrameIndex = -1;
}
-AnimatedSprite::AnimatedSpriteSubtitles::AnimatedSpriteSubtitles(NeverhoodEngine *vm, AnimatedSprite *backref) :
- _backref(backref), BaseSurface(vm, 0xffff, kSubtitleWidth, SubtitlePlayer::kSubtitleCharHeight, "animated sprite subtitles") {
+void AnimatedSprite::AnimatedSpriteSubtitles::updatePosition(const NDrawRect &parentDrawRect) {
+ _subCenterX = parentDrawRect.x + parentDrawRect.width / 2;
+ getDrawRect().x = MAX(_subCenterX - kSubtitleWidth / 2, 0);
+ getDrawRect().width = kSubtitleWidth;
+ getDrawRect().y = MIN(parentDrawRect.y + parentDrawRect.height + 1, 480 - (SubtitlePlayer::kSubtitleCharHeight - 1));
+ getDrawRect().height = SubtitlePlayer::kSubtitleCharHeight;
}
void AnimatedSprite::AnimatedSpriteSubtitles::draw() {
- if (_backref->_subtitles && _backref->_subtitles->isValid() &&
- _backref->_currFrameIndex != 0 &&
- _backref->_currFrameIndex < _backref->_lastFrameIndex) {
- int subCenterX = _backref->_surface->getDrawRect().x + _backref->_surface->getDrawRect().width / 2;
- _backref->_subtitles->renderFrame(_backref->_currFrameIndex, subCenterX - getDrawRect().x);
- const Graphics::Surface *bottom = _backref->_subtitles->getBottomSubs();
+ if (_subtitles && _subtitles->isValid() && _currFrameIndex > 0) {
+ _subtitles->renderFrame(_currFrameIndex, _subCenterX - getDrawRect().x);
+ const Graphics::Surface *bottom = _subtitles->getBottomSubs();
if (bottom) {
- _vm->_screen->drawSurface2(bottom, _drawRect, _clipRect, true, ++_version, nullptr, _backref->_subtitles->getSubtitleAlpha());
+ _vm->_screen->drawSurface2(bottom, _drawRect, _clipRect, true, ++_version, nullptr, _subtitles->getSubtitleAlpha());
}
- if (_backref->_subtitles->getTopSubs())
+ if (_subtitles->getTopSubs())
warning("Top subs are unsupported");
}
}
diff --git a/engines/neverhood/sprite.h b/engines/neverhood/sprite.h
index b19a7a7c3b7..9265382d531 100644
--- a/engines/neverhood/sprite.h
+++ b/engines/neverhood/sprite.h
@@ -155,15 +155,19 @@ protected:
class AnimatedSpriteSubtitles : public BaseSurface {
public:
void draw() override;
- AnimatedSpriteSubtitles(NeverhoodEngine *vm, AnimatedSprite *backRef);
+ AnimatedSpriteSubtitles(NeverhoodEngine *vm);
+ void setFrameIndex(int currFrameIndex, int lastFrameIndex);
+ void setHash(uint32 fileHash);
+ void updatePosition(const NDrawRect &parentDrawRect);
private:
- AnimatedSprite *_backref;
+ Common::ScopedPtr<SubtitlePlayer> _subtitles;
+ int _currFrameIndex;
+ int _subCenterX;
};
static const int kSubtitleWidth = 320;
Common::SharedPtr<AnimatedSpriteSubtitles> _subtitleSurface;
typedef void (AnimatedSprite::*AnimationCb)();
- Common::ScopedPtr<SubtitlePlayer> _subtitles;
AnimResource _animResource;
uint32 _currAnimFileHash, _newAnimFileHash, _nextAnimFileHash;
int16 _currFrameIndex, _lastFrameIndex;
More information about the Scummvm-git-logs
mailing list