From 6c3e9f5151fac4906c2fabc2e26ee39bc7043664 Mon Sep 17 00:00:00 2001 From: Denis Kasak Date: Sun, 5 Jul 2009 03:24:46 +0000 Subject: * API change for Animation and AnimObj; AnimObj is now a proper class and each instance handles its own animation. Animation handles adding, fetching and deleting of AnimObjs (probably needs a namechange). * Implemented actual animation (previously only the first frame was display) * Implemented animation starting, stoping, looping * Loaded looping dragon animation as a test svn-id: r42114 --- engines/draci/animation.cpp | 215 +++++++++++++++++++++++++++++++++----------- 1 file changed, 164 insertions(+), 51 deletions(-) (limited to 'engines/draci/animation.cpp') diff --git a/engines/draci/animation.cpp b/engines/draci/animation.cpp index 5e6578de57..a29281d510 100644 --- a/engines/draci/animation.cpp +++ b/engines/draci/animation.cpp @@ -28,111 +28,224 @@ namespace Draci { -void Animation::addAnimation(uint id, uint z, bool playing) { +AnimObj::AnimObj(DraciEngine *vm) : _vm(vm) { + _id = kUnused; + _z = 0; + _playing = false; + _looping = false; + _delay = 0; + _tick = _vm->_system->getMillis(); + _currentFrame = 0; +} + +AnimObj::~AnimObj() { + deleteFrames(); +} + +bool AnimObj::isLooping() { + return _looping; +} + +void AnimObj::setLooping(bool looping) { + _looping = looping; +} + +void AnimObj::setDelay(uint delay) { + _delay = delay; +} + +void AnimObj::nextFrame(bool force) { + + // If there's only one or no frames, return + if (getFramesNum() < 2) + return; + + Common::Rect frameRect = _frames[_currentFrame]->getRect(); + + // If we are at the last frame and not looping, stop the animation + // The animation is also restarted to frame zero + if ((_currentFrame == nextFrameNum() - 1) && !_looping) { + _currentFrame = 0; + _playing = false; + return; + } + + if (force || (_tick + _delay <= _vm->_system->getMillis())) { + _vm->_screen->getSurface()->markDirtyRect(frameRect); + _currentFrame = nextFrameNum(); + _tick = _vm->_system->getMillis(); + } + + debugC(6, kDraciAnimationDebugLevel, + "tick=%d delay=%d tick+delay=%d currenttime=%d frame=%d framenum=%d", + _tick, _delay, _tick + _delay, _vm->_system->getMillis(), _currentFrame, _frames.size()); +} + +uint AnimObj::nextFrameNum() { + + if ((_currentFrame == getFramesNum() - 1) && _looping) + return 0; + else + return _currentFrame + 1; +} + +void AnimObj::drawFrame(Surface *surface) { - AnimObj *obj = new AnimObj(); - obj->_id = id; - obj->_z = z; - obj->_currentFrame = 0; - obj->_playing = playing; + if (_frames.size() == 0) + return; + + if (_id == kOverlayImage) { + _frames[_currentFrame]->draw(surface, false); + } + else { + _frames[_currentFrame]->draw(surface, true); + } +} - insertAnimation(*obj); +void AnimObj::setID(int id) { + + _id = id; } -void Animation::play(uint id) { +int AnimObj::getID() { + + return _id; +} - AnimObj &obj = *getAnimation(id); +void AnimObj::setZ(uint z) { - obj._playing = true; + _z = z; } -void Animation::stop(uint id) { +uint AnimObj::getZ() { + + return _z; +} - AnimObj &obj = *getAnimation(id); +bool AnimObj::isPlaying() { - obj._playing = false; + return _playing; } -Common::List::iterator Animation::getAnimation(uint id) { +void AnimObj::setPlaying(bool playing) { - Common::List::iterator it; + _playing = playing; +} - for (it = _animObjects.begin(); it != _animObjects.end(); ++it) { - if (it->_id == id) { - return it; - } +void AnimObj::addFrame(Drawable *frame) { + + _frames.push_back(frame); +} + +uint AnimObj::getFramesNum() { + + return _frames.size(); +} + +void AnimObj::deleteFrames() { + + for (uint i = 0; i < getFramesNum(); ++i) { + delete _frames[i]; + _frames.pop_back(); } +} + +AnimObj *Animation::addAnimation(int id, uint z, bool playing) { + + AnimObj *obj = new AnimObj(_vm); + obj->setID(id); + obj->setZ(z); + obj->setPlaying(playing); + obj->setLooping(false); + + insertAnimation(obj); + + return obj; +} + +void Animation::play(int id) { + + AnimObj *obj = getAnimation(id); + + obj->setPlaying(true); +} - return _animObjects.end(); +void Animation::stop(int id) { + + AnimObj *obj = getAnimation(id); + + obj->setPlaying(false); } -void Animation::insertAnimation(AnimObj &animObj) { +AnimObj *Animation::getAnimation(int id) { - Common::List::iterator it; + Common::List::iterator it; for (it = _animObjects.begin(); it != _animObjects.end(); ++it) { - if (animObj._z < it->_z) - break; + if ((*it)->getID() == id) { + return *it; + } } - _animObjects.insert(it, animObj); + return *_animObjects.end(); } -void Animation::addFrame(uint id, Drawable *frame) { +void Animation::insertAnimation(AnimObj *animObj) { - Common::List::iterator it = getAnimation(id); + Common::List::iterator it; + + for (it = _animObjects.begin(); it != _animObjects.end(); ++it) { + if (animObj->getZ() < (*it)->getZ()) + break; + } - it->_frames.push_back(frame); + _animObjects.insert(it, animObj); } void Animation::addOverlay(Drawable *overlay, uint z) { - AnimObj *obj = new AnimObj(); - obj->_id = kOverlayImage; - obj->_z = z; - obj->_currentFrame = 0; - obj->_playing = true; - obj->_frames.push_back(overlay); + AnimObj *obj = new AnimObj(_vm); + obj->setID(kOverlayImage); + obj->setZ(z); + obj->setPlaying(true); + obj->addFrame(overlay); - insertAnimation(*obj); + insertAnimation(obj); } void Animation::drawScene(Surface *surf) { - Common::List::iterator it; + Common::List::iterator it; for (it = _animObjects.begin(); it != _animObjects.end(); ++it) { - if (!it->_playing) { + if (! ((*it)->isPlaying()) ) { continue; } - if (it->_id == kOverlayImage) { - it->_frames[it->_currentFrame]->draw(surf, false); - } - else { - it->_frames[it->_currentFrame]->draw(surf, true); - } + (*it)->nextFrame(); + (*it)->drawFrame(surf); } } -void Animation::deleteAnimation(uint id) { +void Animation::deleteAnimation(int id) { - Common::List::iterator it = getAnimation(id); + Common::List::iterator it; - for (uint i = 0; i < it->_frames.size(); ++i) { - delete it->_frames[i]; + for (it = _animObjects.begin(); it != _animObjects.end(); ++it) { + if ((*it)->getID() == id) + break; } + + (*it)->deleteFrames(); _animObjects.erase(it); } void Animation::deleteAll() { - Common::List::iterator it; + Common::List::iterator it; for (it = _animObjects.begin(); it != _animObjects.end(); ++it) { - for (uint i = 0; i < it->_frames.size(); ++i) { - delete it->_frames[i]; - } + (*it)->deleteFrames(); } _animObjects.clear(); -- cgit v1.2.3