CAnimation.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. #ifndef __CANIMATION_H__
  2. #define __CANIMATION_H__
  3. #include <boost/function.hpp>
  4. #include <vector>
  5. #include <string>
  6. #include <queue>
  7. #include <set>
  8. #include "../global.h"
  9. #include "GUIBase.h"
  10. /*
  11. * CAnimation.h, part of VCMI engine
  12. *
  13. * Authors: listed in file AUTHORS in main folder
  14. *
  15. * License: GNU General Public License v2.0 or later
  16. * Full text of license available in license.txt file, in main folder
  17. *
  18. */
  19. struct SDL_Surface;
  20. struct BMPPalette;
  21. //class for def loading, methods are based on CDefHandler
  22. //after loading will store general info (palette and frame offsets) and pointer to file itself
  23. class CDefFile
  24. {
  25. private:
  26. struct SSpriteDef
  27. {
  28. ui32 prSize;
  29. ui32 defType2;
  30. ui32 FullWidth;
  31. ui32 FullHeight;
  32. ui32 SpriteWidth;
  33. ui32 SpriteHeight;
  34. ui32 LeftMargin;
  35. ui32 TopMargin;
  36. };
  37. //offset[group][frame] - offset of frame data in file
  38. std::vector< std::vector <size_t> > offset;
  39. //sorted list of offsets used to determine size
  40. std::set <size_t> offList;
  41. unsigned char * data;
  42. BMPPalette * colors;
  43. int datasize;
  44. unsigned int type;
  45. public:
  46. CDefFile(std::string Name);
  47. ~CDefFile();
  48. //true if file was opened correctly
  49. bool loaded() const;
  50. //get copy of palette to unpack compressed animation
  51. BMPPalette * getPalette();
  52. //true if frame is present in it
  53. bool haveFrame(size_t frame, size_t group) const;
  54. //get copy of binary data
  55. unsigned char * getFrame(size_t frame, size_t group) const;
  56. //load frame as SDL_Surface
  57. SDL_Surface * loadFrame(size_t frame, size_t group) const ;
  58. //static version of previous one for calling from compressed anim
  59. static SDL_Surface * loadFrame(const unsigned char * FDef, const BMPPalette * palette);
  60. };
  61. // Class for handling animation.
  62. class CAnimation
  63. {
  64. private:
  65. //internal structure to hold all data of specific frame
  66. struct AnimEntry
  67. {
  68. //surface for this entry
  69. SDL_Surface * surf;
  70. //data for CompressedAnim
  71. unsigned char * data;
  72. //reference count, changed by loadFrame \ unloadFrame
  73. size_t refCount;
  74. //size of compressed data, unused for def files
  75. size_t dataSize;
  76. //bitfield, location of image data: 1 - def, 2 - file#9.*, 4 - file#9#2.*
  77. unsigned char source;
  78. AnimEntry();
  79. };
  80. //palette from def file, used only for compressed anim
  81. BMPPalette * defPalette;
  82. //entries[group][position], store all info regarding frames
  83. std::vector< std::vector <AnimEntry> > entries;
  84. //animation file name
  85. std::string name;
  86. //if true all frames will be stored in compressed state
  87. const bool compressed;
  88. //loader, will be called by load(), require opened def file for loading from it. Returns true if image is loaded
  89. bool loadFrame(CDefFile * file, size_t frame, size_t group);
  90. //unloadFrame, returns true if image has been unloaded ( either deleted or decreased refCount)
  91. bool unloadFrame(size_t frame, size_t group);
  92. //decompress entry data
  93. void decompress(AnimEntry &entry);
  94. //initialize animation from file
  95. void init(CDefFile * file);
  96. //try to open def file
  97. CDefFile * getFile() const;
  98. //to get rid of copy-pasting error message :]
  99. void printError(size_t frame, size_t group, std::string type) const;
  100. public:
  101. CAnimation(std::string Name, bool Compressed = false);
  102. CAnimation();
  103. ~CAnimation();
  104. //add custom surface to the end of specific group. If shared==true surface needs to be deleted
  105. //somewhere outside of CAnim as well (SDL_Surface::refcount will be increased)
  106. void add(SDL_Surface * surf, bool shared=false, size_t group=0);
  107. //removes all surfaces which have compressed data
  108. void removeDecompressed(size_t frame, size_t group);
  109. //get pointer to surface, this function ignores groups (like ourImages in DefHandler)
  110. SDL_Surface * image (size_t frame);
  111. //get pointer to surface, from specific group
  112. SDL_Surface * image(size_t frame, size_t group);
  113. //removes all frames as well as their entries
  114. void clear();
  115. //all available frames
  116. void load ();
  117. void unload();
  118. //all frames from group
  119. void loadGroup (size_t group);
  120. void unloadGroup(size_t group);
  121. //single image
  122. void load (size_t frame, size_t group=0);
  123. void unload(size_t frame, size_t group=0);
  124. //list of frames (first = group ID, second = frame ID)
  125. void load (std::vector <std::pair <size_t, size_t> > frames);
  126. void unload(std::vector <std::pair <size_t, size_t> > frames);
  127. //helper to fix frame order on some buttons
  128. void fixButtonPos();
  129. //size of specific group, 0 if not present
  130. size_t groupSize(size_t group) const;
  131. //total count of frames in whole anim
  132. size_t size() const;
  133. };
  134. /*
  135. //Class for displaying one image from animation
  136. class CAnimImage: public CIntObject
  137. {
  138. private:
  139. CAnimation anim;
  140. size_t frame;//displayed frame/group
  141. size_t group;
  142. public:
  143. CAnimImage(int x, int y, std::string name, size_t Frame, size_t Group=0);//c-tor
  144. ~CAnimImage();//d-tor
  145. //change displayed frame on this one
  146. void setFrame(size_t Frame, size_t Group=0);
  147. void show(SDL_Surface *to);
  148. //TODO: showAll();
  149. };
  150. */
  151. //Base class for displaying animation, used as superclass for different animations
  152. class CShowableAnim: public CIntObject
  153. {
  154. public:
  155. enum EFlags
  156. {
  157. FLAG_BASE=1, //base frame will be blitted before current one
  158. FLAG_COMPRESSED=2, //animations will be loaded in compressed state
  159. FLAG_ROTATED=4, //will be displayed rotated
  160. FLAG_ALPHA=8, //if image is 8bbp it will be printed with transparency (0=opaque, 255=transparent)
  161. FLAG_USERLE=16, //not used for now, enable RLE compression from SDL
  162. FLAG_PREVIEW=32 //for creatures only: several animation (move, attack, defence...) will be randomly selected
  163. };
  164. protected:
  165. CAnimation anim;
  166. size_t group, frame;//current frame
  167. size_t first, last; //animation range
  168. unsigned char flags;//flags from EFlags enum
  169. unsigned int frameDelay;//delay in frames of each image
  170. unsigned int value;//how many times current frame was showed
  171. //blit image with optional rotation, fitting into rect, etc
  172. void blitImage(SDL_Surface *what, SDL_Surface *to);
  173. //For clipping in rect, offsets of picture coordinates
  174. int xOffset, yOffset;
  175. public:
  176. //called when next animation sequence is required
  177. boost::function<void()> callback;
  178. CShowableAnim(int x, int y, std::string name, unsigned char flags, unsigned int Delay=4, size_t Group=0);
  179. ~CShowableAnim();
  180. //set animation to group or part of group
  181. bool set(size_t Group);
  182. bool set(size_t Group, size_t from, size_t to=-1);
  183. //set rotation flag
  184. void rotate(bool on);
  185. //move displayed part of picture (if picture is clipped to rect)
  186. void movePic( int byX, int byY);
  187. //set frame to first, call callback
  188. virtual void reset();
  189. //show current frame and increase counter
  190. void show(SDL_Surface *to);
  191. void showAll(SDL_Surface *to);
  192. };
  193. class CCreatureAnim: public CShowableAnim
  194. {
  195. public:
  196. enum EAnimType // list of creature animations, numbers were taken from def files
  197. {
  198. ANIM_MOVING=0, //will automatically add MOVE_START and MOVE_END to queue
  199. ANIM_MOUSEON=1,
  200. ANIM_HOLDING=2,
  201. ANIM_HITTED=3,
  202. ANIM_DEFENCE=4,
  203. ANIM_DEATH=5,
  204. //ANIM_DEATH2=6, //unused?
  205. ANIM_TURN_L=7, //will automatically play second part of anim and rotate creature
  206. ANIM_TURN_R=8, //same
  207. //ANIM_TURN_L2=9, //identical to previous?
  208. //ANIM_TURN_R2=10,
  209. ANIM_ATTACK_UP=11,
  210. ANIM_ATTACK_FRONT=12,
  211. ANIM_ATTACK_DOWN=13,
  212. ANIM_SHOOT_UP=14,
  213. ANIM_SHOOT_FRONT=15,
  214. ANIM_SHOOT_DOWN=16,
  215. ANIM_CAST_UP=17,
  216. ANIM_CAST_FRONT=18,
  217. ANIM_CAST_DOWN=19,
  218. ANIM_2HEX_ATTACK_UP=17,
  219. ANIM_2HEX_ATTACK_FRONT=18,
  220. ANIM_2HEX_ATTACK_DOWN=19,
  221. ANIM_MOVE_START=20, //no need to use this two directly - ANIM_MOVING will be enought
  222. ANIM_MOVE_END=21
  223. };
  224. private:
  225. // queue of animations waiting to be displayed
  226. std::queue<EAnimType> queue;
  227. //this funcction is used as callback if preview flag was set during construction
  228. void loopPreview();
  229. public:
  230. //change anim to next if queue is not empty, call callback othervice
  231. void reset();
  232. //add sequence to the end of queue
  233. void addLast(EAnimType newType);
  234. //clear queue and set animation to this sequence
  235. void clearAndSet(EAnimType type);
  236. CCreatureAnim(int x, int y, std::string name, unsigned char flags=FLAG_COMPRESSED | FLAG_ALPHA | FLAG_PREVIEW,
  237. EAnimType type=ANIM_HOLDING);
  238. };
  239. #endif // __CANIMATIONHANDLER_H__