CAnimation.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. #pragma once
  2. #include "../../lib/vcmi_endian.h"
  3. #include "gui/Geometries.h"
  4. #include "../../lib/GameConstants.h"
  5. /*
  6. * CAnimation.h, part of VCMI engine
  7. *
  8. * Authors: listed in file AUTHORS in main folder
  9. *
  10. * License: GNU General Public License v2.0 or later
  11. * Full text of license available in license.txt file, in main folder
  12. *
  13. */
  14. struct SDL_Surface;
  15. class SDLImageLoader;
  16. class CompImageLoader;
  17. class JsonNode;
  18. /// Class for def loading, methods are based on CDefHandler
  19. /// After loading will store general info (palette and frame offsets) and pointer to file itself
  20. class CDefFile
  21. {
  22. private:
  23. struct SSpriteDef
  24. {
  25. ui32 size;
  26. ui32 format; /// format in which pixel data is stored
  27. ui32 fullWidth; /// full width and height of frame, including borders
  28. ui32 fullHeight;
  29. ui32 width; /// width and height of pixel data, borders excluded
  30. ui32 height;
  31. si32 leftMargin;
  32. si32 topMargin;
  33. } PACKED_STRUCT;
  34. //offset[group][frame] - offset of frame data in file
  35. std::map<size_t, std::vector <size_t> > offset;
  36. std::unique_ptr<ui8[]> data;
  37. std::unique_ptr<SDL_Color[]> palette;
  38. public:
  39. CDefFile(std::string Name);
  40. ~CDefFile();
  41. //load frame as SDL_Surface
  42. template<class ImageLoader>
  43. void loadFrame(size_t frame, size_t group, ImageLoader &loader) const;
  44. const std::map<size_t, size_t> getEntries() const;
  45. };
  46. /*
  47. * Base class for images, can be used for non-animation pictures as well
  48. */
  49. class IImage
  50. {
  51. int refCount;
  52. public:
  53. //draws image on surface "where" at position
  54. virtual void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=nullptr, ui8 alpha=255) const=0;
  55. //decrease ref count, returns true if image can be deleted (refCount <= 0)
  56. bool decreaseRef();
  57. void increaseRef();
  58. //Change palette to specific player
  59. virtual void playerColored(PlayerColor player)=0;
  60. virtual int width() const=0;
  61. virtual int height() const=0;
  62. IImage();
  63. virtual ~IImage() {};
  64. };
  65. /*
  66. * Wrapper around SDL_Surface
  67. */
  68. class SDLImage : public IImage
  69. {
  70. public:
  71. //Surface without empty borders
  72. SDL_Surface * surf;
  73. //size of left and top borders
  74. Point margins;
  75. //total size including borders
  76. Point fullSize;
  77. public:
  78. //Load image from def file
  79. SDLImage(CDefFile *data, size_t frame, size_t group=0, bool compressed=false);
  80. //Load from bitmap file
  81. SDLImage(std::string filename, bool compressed=false);
  82. //Create using existing surface, extraRef will increase refcount on SDL_Surface
  83. SDLImage(SDL_Surface * from, bool extraRef);
  84. ~SDLImage();
  85. void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=nullptr, ui8 alpha=255) const override;
  86. void playerColored(PlayerColor player) override;
  87. int width() const override;
  88. int height() const override;
  89. friend class SDLImageLoader;
  90. };
  91. /*
  92. * RLE-compressed image data for 8-bit images with alpha-channel, currently far from finished
  93. * primary purpose is not high compression ratio but fast drawing.
  94. * Consist of repeatable segments with format similar to H3 def compression:
  95. * 1st byte:
  96. * if (byte == 0xff)
  97. * raw data, opaque and semi-transparent data always in separate blocks
  98. * else
  99. * RLE-compressed image data with this color
  100. * 2nd byte = size of segment
  101. * raw data (if any)
  102. */
  103. class CompImage : public IImage
  104. {
  105. //x,y - margins, w,h - sprite size
  106. Rect sprite;
  107. //total size including borders
  108. Point fullSize;
  109. //RLE-d data
  110. ui8 * surf;
  111. //array of offsets for each line
  112. ui32 * line;
  113. //palette
  114. SDL_Color *palette;
  115. //Used internally to blit one block of data
  116. template<int bpp, int dir>
  117. void BlitBlock(ui8 type, ui8 size, ui8 *&data, ui8 *&dest, ui8 alpha) const;
  118. void BlitBlockWithBpp(ui8 bpp, ui8 type, ui8 size, ui8 *&data, ui8 *&dest, ui8 alpha, bool rotated) const;
  119. public:
  120. //Load image from def file
  121. CompImage(const CDefFile *data, size_t frame, size_t group=0);
  122. //TODO: load image from SDL_Surface
  123. CompImage(SDL_Surface * surf);
  124. ~CompImage();
  125. void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=nullptr, ui8 alpha=255) const override;
  126. void playerColored(PlayerColor player) override;
  127. int width() const override;
  128. int height() const override;
  129. friend class CompImageLoader;
  130. };
  131. /// Class for handling animation
  132. class CAnimation
  133. {
  134. private:
  135. //source[group][position] - file with this frame, if string is empty - image located in def file
  136. std::map<size_t, std::vector <JsonNode> > source;
  137. //bitmap[group][position], store objects with loaded bitmaps
  138. std::map<size_t, std::map<size_t, IImage* > > images;
  139. //animation file name
  140. std::string name;
  141. //if true all frames will be stored in compressed (RLE) state
  142. const bool compressed;
  143. //loader, will be called by load(), require opened def file for loading from it. Returns true if image is loaded
  144. bool loadFrame(CDefFile * file, size_t frame, size_t group);
  145. //unloadFrame, returns true if image has been unloaded ( either deleted or decreased refCount)
  146. bool unloadFrame(size_t frame, size_t group);
  147. //initialize animation from file
  148. void initFromJson(const JsonNode & input);
  149. void init(CDefFile * file);
  150. //try to open def file
  151. CDefFile * getFile() const;
  152. //to get rid of copy-pasting error message :]
  153. void printError(size_t frame, size_t group, std::string type) const;
  154. //not a very nice method to get image from another def file
  155. //TODO: remove after implementing resource manager
  156. IImage * getFromExtraDef(std::string filename);
  157. public:
  158. CAnimation(std::string Name, bool Compressed = false);
  159. CAnimation();
  160. ~CAnimation();
  161. //static method for debugging - print info about loaded animations
  162. static void getAnimInfo();
  163. static std::set<CAnimation*> loadedAnims;
  164. //add custom surface to the selected position.
  165. void setCustom(std::string filename, size_t frame, size_t group=0);
  166. //get pointer to image from specific group, nullptr if not found
  167. IImage * getImage(size_t frame, size_t group=0, bool verbose=true) const;
  168. //all available frames
  169. void load ();
  170. void unload();
  171. //all frames from group
  172. void loadGroup (size_t group);
  173. void unloadGroup(size_t group);
  174. //single image
  175. void load (size_t frame, size_t group=0);
  176. void unload(size_t frame, size_t group=0);
  177. //total count of frames in group (including not loaded)
  178. size_t size(size_t group=0) const;
  179. };
  180. const float DEFAULT_DELTA = 0.05f;
  181. class CFadeAnimation
  182. {
  183. public:
  184. enum class EMode
  185. {
  186. NONE, IN, OUT
  187. };
  188. private:
  189. float delta;
  190. SDL_Surface * fadingSurface;
  191. bool fading;
  192. float fadingCounter;
  193. bool shouldFreeSurface;
  194. float initialCounter() const;
  195. bool isFinished() const;
  196. public:
  197. EMode fadingMode;
  198. CFadeAnimation();
  199. ~CFadeAnimation();
  200. void init(EMode mode, SDL_Surface * sourceSurface, bool freeSurfaceAtEnd = false, float animDelta = DEFAULT_DELTA);
  201. void update();
  202. void draw(SDL_Surface * targetSurface, const SDL_Rect * sourceRect, SDL_Rect * destRect);
  203. bool isFading() const { return fading; }
  204. };