/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef DRACI_ANIMATION_H #define DRACI_ANIMATION_H #include "common/array.h" #include "common/list.h" #include "common/rect.h" #include "draci/sprite.h" namespace Draci { /** * Animation IDs for those animations that don't have their IDs * specified in the data files. */ enum { kOverlayImage = -1, kWalkingMapOverlay = -2, kWalkingShortestPathOverlay = -3, kWalkingObliquePathOverlay = -4, kTitleText = -5, kSpeechText = -6, kInventorySprite = -7, kDialogueLinesID = -8, kUnused = -12, kInventoryItemsID = -13 }; /** * Used by overlays as a neutral index that won't get * released with the GPL Release command. */ enum { kIgnoreIndex = -2 }; class DraciEngine; class Surface; struct SoundSample; class Animation { typedef void (Animation::* AnimationCallback)(); public: Animation(DraciEngine *v, int id, uint z, bool playing); ~Animation(); uint getZ() const { return _z; } void setZ(uint z) { _z = z; } void setID(int id) { _id = id; } int getID() const { return _id; } void nextFrame(bool force); void drawFrame(Surface *surface); void addFrame(Drawable *frame, const SoundSample *sample); void replaceFrame(int i, Drawable *frame, const SoundSample *sample); const Drawable *getConstCurrentFrame() const; Drawable *getCurrentFrame(); Drawable *getFrame(int frameNum); void setCurrentFrame(uint frame); uint currentFrameNum() const { return _currentFrame; } uint getFrameCount() const { return _frames.size(); } void makeLastFrameRelative(int x, int y); void clearShift(); bool isPlaying() const { return _playing; } void setPlaying(bool playing); bool isPaused() const { return _paused; } void setPaused(bool paused) { _paused = paused; } bool isLooping() const { return _looping; } void setLooping(bool looping); void setIsRelative(bool value) { _isRelative = value; } bool isRelative() const { return _isRelative; } void setRelative(int relx, int rely); int getRelativeX() const { return _displacement.relX; } int getRelativeY() const { return _displacement.relY; } const Displacement &getDisplacement() const { return _displacement; } // displacement of the whole animation Displacement getCurrentFrameDisplacement() const; // displacement of the current frame (includes _shift) Common::Point getCurrentFramePosition() const; // with displacement and shift applied void supportsQuickAnimation(bool val) { _canBeQuick = val; } int getIndex() const { return _index; } void setIndex(int index) { _index = index; } void setScaleFactors(double scaleX, double scaleY); double getScaleX() const { return _displacement.extraScaleX; } double getScaleY() const { return _displacement.extraScaleY; } void markDirtyRect(Surface *surface) const; // Animation callbacks. They can only do simple things, such as // setting the value of some variable or stopping an animation. In // particular, they cannot run sub-loops or anything like that, because // the callback is called at an arbitrary time without much control // over what the state of the rest of the program is. void registerCallback(AnimationCallback callback) { _callback = callback; } void doNothing() {} void exitGameLoop(); void tellWalkingState(); void play(); void stop(); void del(); private: uint nextFrameNum() const; void deleteFrames(); /** Internal animation ID * (as specified in the data files and the bytecode) */ int _id; /** The recency index of an animation, i.e. the most recently added animation has * the highest index. Some script commands need this. */ int _index; uint _currentFrame; uint _z; Common::Point _shift; // partial sum of _relativeShifts from the beginning of the animation until the current frame bool _hasChangedFrame; Displacement _displacement; bool _isRelative; uint _tick; bool _playing; bool _looping; bool _paused; bool _canBeQuick; /** Array of frames of the animation. The animation object owns these pointers. */ Common::Array _frames; Common::Array _relativeShifts; /** Array of samples played during the animation. The animation * object doesn't own these pointers, but they are stored in the * cache. */ Common::Array _samples; AnimationCallback _callback; DraciEngine *_vm; }; class AnimationManager { public: AnimationManager(DraciEngine *vm) : _vm(vm), _lastIndex(-1), _animationPauseCounter(0) {} ~AnimationManager() { deleteAll(); } void insert(Animation *anim, bool allocateIndex); Animation *load(uint animNum); void pauseAnimations(); void unpauseAnimations(); void deleteAnimation(Animation *anim); void deleteOverlays(); void deleteAll(); void drawScene(Surface *surf); Animation *getAnimation(int id); int getLastIndex() const { return _lastIndex; } void deleteAfterIndex(int index); const Animation *getTopAnimation(int x, int y) const; private: void sortAnimations(); DraciEngine *_vm; /** List of animation objects, maintained sorted by decreasing Z-coordinates. * The animation manager owns the pointers. */ Common::List _animations; /** The index of the most recently added animation. * See Animation::_index for details. */ int _lastIndex; /** How many times the animations are paused. * Needed because the animations can be paused once by entering the * inventory and then again by entering the game menu. When they are * unpaused the first time, they should be kept paused. */ int _animationPauseCounter; }; } // End of namespace Draci #endif // DRACI_ANIMATION_H