1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef DRACI_ANIMATION_H 24 #define DRACI_ANIMATION_H 25 26 #include "common/array.h" 27 #include "common/list.h" 28 #include "common/rect.h" 29 #include "draci/sprite.h" 30 31 namespace Draci { 32 33 /** 34 * Animation IDs for those animations that don't have their IDs 35 * specified in the data files. 36 */ 37 enum { 38 kOverlayImage = -1, 39 kWalkingMapOverlay = -2, 40 kWalkingShortestPathOverlay = -3, 41 kWalkingObliquePathOverlay = -4, 42 kTitleText = -5, 43 kSpeechText = -6, 44 kInventorySprite = -7, 45 kDialogueLinesID = -8, 46 kUnused = -12, 47 kInventoryItemsID = -13 48 }; 49 50 /** 51 * Used by overlays as a neutral index that won't get 52 * released with the GPL Release command. 53 */ 54 enum { kIgnoreIndex = -2 }; 55 56 class DraciEngine; 57 class Surface; 58 struct SoundSample; 59 60 class Animation { 61 62 typedef void (Animation::* AnimationCallback)(); 63 64 public: 65 Animation(DraciEngine *v, int id, uint z, bool playing); 66 ~Animation(); 67 getZ()68 uint getZ() const { return _z; } setZ(uint z)69 void setZ(uint z) { _z = z; } 70 setID(int id)71 void setID(int id) { _id = id; } getID()72 int getID() const { return _id; } 73 74 void nextFrame(bool force); 75 void drawFrame(Surface *surface); 76 77 void addFrame(Drawable *frame, const SoundSample *sample); 78 void replaceFrame(int i, Drawable *frame, const SoundSample *sample); 79 const Drawable *getConstCurrentFrame() const; 80 Drawable *getCurrentFrame(); 81 Drawable *getFrame(int frameNum); 82 void setCurrentFrame(uint frame); currentFrameNum()83 uint currentFrameNum() const { return _currentFrame; } getFrameCount()84 uint getFrameCount() const { return _frames.size(); } 85 void makeLastFrameRelative(int x, int y); 86 void clearShift(); 87 isPlaying()88 bool isPlaying() const { return _playing; } 89 void setPlaying(bool playing); 90 isPaused()91 bool isPaused() const { return _paused; } setPaused(bool paused)92 void setPaused(bool paused) { _paused = paused; } 93 isLooping()94 bool isLooping() const { return _looping; } 95 void setLooping(bool looping); 96 setIsRelative(bool value)97 void setIsRelative(bool value) { _isRelative = value; } isRelative()98 bool isRelative() const { return _isRelative; } 99 void setRelative(int relx, int rely); getRelativeX()100 int getRelativeX() const { return _displacement.relX; } getRelativeY()101 int getRelativeY() const { return _displacement.relY; } getDisplacement()102 const Displacement &getDisplacement() const { return _displacement; } // displacement of the whole animation 103 Displacement getCurrentFrameDisplacement() const; // displacement of the current frame (includes _shift) 104 Common::Point getCurrentFramePosition() const; // with displacement and shift applied 105 supportsQuickAnimation(bool val)106 void supportsQuickAnimation(bool val) { _canBeQuick = val; } 107 getIndex()108 int getIndex() const { return _index; } setIndex(int index)109 void setIndex(int index) { _index = index; } 110 111 void setScaleFactors(double scaleX, double scaleY); getScaleX()112 double getScaleX() const { return _displacement.extraScaleX; } getScaleY()113 double getScaleY() const { return _displacement.extraScaleY; } 114 115 void markDirtyRect(Surface *surface) const; 116 117 // Animation callbacks. They can only do simple things, such as 118 // setting the value of some variable or stopping an animation. In 119 // particular, they cannot run sub-loops or anything like that, because 120 // the callback is called at an arbitrary time without much control 121 // over what the state of the rest of the program is. registerCallback(AnimationCallback callback)122 void registerCallback(AnimationCallback callback) { _callback = callback; } 123 doNothing()124 void doNothing() {} 125 void exitGameLoop(); 126 void tellWalkingState(); 127 128 void play(); 129 void stop(); 130 void del(); 131 132 private: 133 uint nextFrameNum() const; 134 void deleteFrames(); 135 136 /** Internal animation ID 137 * (as specified in the data files and the bytecode) 138 */ 139 int _id; 140 141 /** The recency index of an animation, i.e. the most recently added animation has 142 * the highest index. Some script commands need this. 143 */ 144 int _index; 145 146 uint _currentFrame; 147 uint _z; 148 Common::Point _shift; // partial sum of _relativeShifts from the beginning of the animation until the current frame 149 bool _hasChangedFrame; 150 151 Displacement _displacement; 152 bool _isRelative; 153 154 uint _tick; 155 bool _playing; 156 bool _looping; 157 bool _paused; 158 159 bool _canBeQuick; 160 161 /** Array of frames of the animation. The animation object owns these pointers. 162 */ 163 Common::Array<Drawable *> _frames; 164 Common::Array<Common::Point> _relativeShifts; 165 /** Array of samples played during the animation. The animation 166 * object doesn't own these pointers, but they are stored in the 167 * cache. 168 */ 169 Common::Array<const SoundSample *> _samples; 170 171 AnimationCallback _callback; 172 173 DraciEngine *_vm; 174 }; 175 176 177 class AnimationManager { 178 179 public: AnimationManager(DraciEngine * vm)180 AnimationManager(DraciEngine *vm) : _vm(vm), _lastIndex(-1), _animationPauseCounter(0) {} ~AnimationManager()181 ~AnimationManager() { deleteAll(); } 182 183 void insert(Animation *anim, bool allocateIndex); 184 Animation *load(uint animNum); 185 186 void pauseAnimations(); 187 void unpauseAnimations(); 188 189 void deleteAnimation(Animation *anim); 190 void deleteOverlays(); 191 void deleteAll(); 192 193 void drawScene(Surface *surf); 194 195 Animation *getAnimation(int id); 196 getLastIndex()197 int getLastIndex() const { return _lastIndex; } 198 void deleteAfterIndex(int index); 199 200 const Animation *getTopAnimation(int x, int y) const; 201 202 private: 203 void sortAnimations(); 204 205 DraciEngine *_vm; 206 207 /** List of animation objects, maintained sorted by decreasing Z-coordinates. 208 * The animation manager owns the pointers. 209 */ 210 Common::List<Animation *> _animations; 211 212 /** The index of the most recently added animation. 213 * See Animation::_index for details. 214 */ 215 int _lastIndex; 216 217 /** How many times the animations are paused. 218 * Needed because the animations can be paused once by entering the 219 * inventory and then again by entering the game menu. When they are 220 * unpaused the first time, they should be kept paused. */ 221 int _animationPauseCounter; 222 }; 223 224 } // End of namespace Draci 225 226 #endif // DRACI_ANIMATION_H 227