aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Kasak2009-07-05 03:24:46 +0000
committerDenis Kasak2009-07-05 03:24:46 +0000
commit6c3e9f5151fac4906c2fabc2e26ee39bc7043664 (patch)
tree3b27df90db22f61f7b6b6d2c05b8e7717f05146f
parent960740fe83ee1d1e4cea33f732df4b698d22c479 (diff)
downloadscummvm-rg350-6c3e9f5151fac4906c2fabc2e26ee39bc7043664.tar.gz
scummvm-rg350-6c3e9f5151fac4906c2fabc2e26ee39bc7043664.tar.bz2
scummvm-rg350-6c3e9f5151fac4906c2fabc2e26ee39bc7043664.zip
* 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
-rw-r--r--engines/draci/animation.cpp215
-rw-r--r--engines/draci/animation.h61
-rw-r--r--engines/draci/game.cpp10
3 files changed, 219 insertions, 67 deletions
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<AnimObj>::iterator Animation::getAnimation(uint id) {
+void AnimObj::setPlaying(bool playing) {
- Common::List<AnimObj>::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<AnimObj>::iterator it;
+ Common::List<AnimObj *>::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<AnimObj>::iterator it = getAnimation(id);
+ Common::List<AnimObj *>::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<AnimObj>::iterator it;
+ Common::List<AnimObj *>::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<AnimObj>::iterator it = getAnimation(id);
+ Common::List<AnimObj *>::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<AnimObj>::iterator it;
+ Common::List<AnimObj *>::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();
diff --git a/engines/draci/animation.h b/engines/draci/animation.h
index c69947ea28..d4be8b5ba3 100644
--- a/engines/draci/animation.h
+++ b/engines/draci/animation.h
@@ -30,44 +30,81 @@
namespace Draci {
-enum { kOverlayImage = -1 };
+enum { kOverlayImage = -1, kUnused = -2 };
class DraciEngine;
-struct AnimObj {
- uint _id;
+class AnimObj {
+public:
+ AnimObj(DraciEngine *vm);
+ ~AnimObj();
+
+ uint getZ();
+ void setZ(uint z);
+
+ void setID(int id);
+ int getID();
+
+ void setDelay(uint delay);
+
+ void nextFrame(bool force = false);
+ void drawFrame(Surface *surface);
+
+ void addFrame(Drawable *frame);
+ uint getFramesNum();
+ void deleteFrames();
+
+ bool isPlaying();
+ void setPlaying(bool playing);
+
+ bool isLooping();
+ void setLooping(bool looping);
+
+
+private:
+
+ uint nextFrameNum();
+
+ int _id;
uint _currentFrame;
uint _z;
- bool _playing;
+ uint _delay;
+ uint _tick;
+ bool _playing;
+ bool _looping;
Common::Array<Drawable*> _frames;
+
+ DraciEngine *_vm;
};
+// TODO: Probably needs a namechange to AnimationManager or similar since AnimObj now
+// acts as an animation object
+
class Animation {
public:
Animation(DraciEngine *vm) : _vm(vm) {};
~Animation() { deleteAll(); }
- void addAnimation(uint id, uint z, bool playing = false);
- void addFrame(uint id, Drawable *frame);
+ AnimObj *addAnimation(int id, uint z, bool playing = false);
void addOverlay(Drawable *overlay, uint z);
- void play(uint id);
- void stop(uint id);
+ void play(int id);
+ void stop(int id);
- void deleteAnimation(uint id);
+ void deleteAnimation(int id);
void deleteAll();
void drawScene(Surface *surf);
- Common::List<AnimObj>::iterator getAnimation(uint id);
+ AnimObj *getAnimation(int id);
private:
- void insertAnimation(AnimObj &animObj);
+ void insertAnimation(AnimObj *animObj);
DraciEngine *_vm;
- Common::List<AnimObj> _animObjects;
+ Common::List<AnimObj *> _animObjects;
};
}
diff --git a/engines/draci/game.cpp b/engines/draci/game.cpp
index b24d62d36d..a843a8267e 100644
--- a/engines/draci/game.cpp
+++ b/engines/draci/game.cpp
@@ -189,7 +189,7 @@ int Game::loadAnimation(uint animNum) {
animationReader.readByte(); // Cyclic field, not used
animationReader.readByte(); // Relative field, not used
- _vm->_anims->addAnimation(animNum, 254, false);
+ AnimObj *obj = _vm->_anims->addAnimation(animNum, 254, false);
for (uint i = 0; i < numFrames; ++i) {
uint spriteNum = animationReader.readUint16LE() - 1;
@@ -202,8 +202,7 @@ int Game::loadAnimation(uint animNum) {
uint freq = animationReader.readUint16LE();
uint delay = animationReader.readUint16LE();
- // TODO: implement Animation::setDelay()
- //_vm->_anims->setDelay(animNum, delay*10);
+ obj->setDelay(delay * 10);
BAFile *spriteFile = _vm->_spritesArchive->getFile(spriteNum);
@@ -212,7 +211,10 @@ int Game::loadAnimation(uint animNum) {
if (mirror)
sp->setMirrorOn();
- _vm->_anims->addFrame(animNum, sp);
+ // HACK: This is only for testing
+ obj->setLooping(true);
+
+ obj->addFrame(sp);
}
return animNum;