/* * Images.h, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * * License: GNU General Public License v2.0 or later * Full text of license available in license.txt file, in main folder * */ #pragma once #include "../gui/CIntObject.h" #include "../battle/BattleConstants.h" #include "../../lib/filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN class Rect; VCMI_LIB_NAMESPACE_END class CAnimImage; class CLabel; class CAnimation; class IImage; // Image class class CPicture : public CIntObject { std::shared_ptr bg; std::function rCallback; public: /// if set, only specified section of internal image will be rendered std::optional srcRect; /// If set to true, image will be redrawn on each frame bool needRefresh; std::shared_ptr getSurface() { return bg; } /// wrap existing image CPicture(std::shared_ptr image, const Point & position); /// wrap section of an existing Image CPicture(std::shared_ptr image, const Rect &SrcRext, int x = 0, int y = 0); //wrap subrect of given surface CPicture(const ImagePath & bmpname, const Rect &SrcRext, int x = 0, int y = 0); //wrap subrect of given surface /// Loads image from specified file name CPicture(const ImagePath & bmpname); CPicture(const ImagePath & bmpname, const Point & position); CPicture(const ImagePath & bmpname, int x, int y); /// set alpha value for whole surface. Note: may be messed up if surface is shared /// 0=transparent, 255=opaque void setAlpha(uint8_t value); void scaleTo(Point size); void setPlayerColor(PlayerColor player); void addRClickCallback(const std::function & callback); void show(Canvas & to) override; void showAll(Canvas & to) override; void showPopupWindow(const Point & cursorPosition) override; }; /// area filled with specific texture class CFilledTexture : public CIntObject { protected: std::shared_ptr texture; Rect imageArea; public: CFilledTexture(const ImagePath & imageName, Rect position, Rect imageArea); CFilledTexture(const ImagePath & imageName, Rect position); void showAll(Canvas & to) override; }; /// area filled with specific texture, colorized to player color if image is indexed class FilledTexturePlayerIndexed : public CFilledTexture { public: using CFilledTexture::CFilledTexture; void setPlayerColor(PlayerColor player); }; /// area filled with specific texture, with applied color filter to colorize it to specific player class FilledTexturePlayerColored : public CFilledTexture { public: using CFilledTexture::CFilledTexture; void setPlayerColor(PlayerColor player); }; /// Class for displaying one image from animation class CAnimImage: public CIntObject { private: std::shared_ptr anim; //displayed frame/group size_t frame; size_t group; ui8 flags; Point scaledSize; /// If set, then image is colored using player-specific palette std::optional player; bool isScaled() const; void setSizeFromImage(const IImage &img); void init(); public: bool visible; CAnimImage(const AnimationPath & name, size_t Frame, size_t Group=0, int x=0, int y=0, ui8 Flags=0); CAnimImage(const AnimationPath & name, size_t Frame, Rect targetPos, size_t Group=0, ui8 Flags=0); ~CAnimImage(); /// size of animation size_t size(); /// change displayed frame on this one void setFrame(size_t Frame, size_t Group=0); /// makes image player-colored to specific player void setPlayerColor(PlayerColor player); /// returns true if image has player-colored effect applied bool isPlayerColored() const; void showAll(Canvas & to) override; void setAnimationPath(const AnimationPath & name, size_t frame); void setScale(Point scale); }; /// Base class for displaying animation, used as superclass for different animations class CShowableAnim: public CIntObject { public: enum EFlags { BASE=1, //base frame will be blitted before current one HORIZONTAL_FLIP=2, //TODO: will be displayed rotated VERTICAL_FLIP=4, //TODO: will be displayed rotated CREATURE_MODE=8, // use alpha channel for images with palette. Required for creatures in battle and map objects PLAY_ONCE=32 //play animation only once and stop at last frame }; protected: std::shared_ptr anim; size_t group, frame;//current frame size_t first, last; //animation range /// total time on scren for each frame in animation ui32 frameTimeTotal; /// how long was current frame visible on screen ui32 frameTimePassed; ui8 flags;//Flags from EFlags enum //blit image with optional rotation, fitting into rect, etc void blitImage(size_t frame, size_t group, Canvas & to); //For clipping in rect, offsets of picture coordinates int xOffset, yOffset; ui8 alpha; public: //called when next animation sequence is required std::function callback; //Set per-surface alpha, 0 = transparent, 255 = opaque void setAlpha(ui32 alphaValue); CShowableAnim(int x, int y, const AnimationPath & name, ui8 flags, ui32 frameTime, size_t Group=0, uint8_t alpha = UINT8_MAX); //set animation to group or part of group bool set(size_t Group); bool set(size_t Group, size_t from, size_t to=-1); //set rotation flags void rotate(bool on, bool vertical=false); //move displayed part of picture (if picture is clipped to rect) void clipRect(int posX, int posY, int width, int height); //set frame to first, call callback virtual void reset(); //set animation duration void setDuration(int durationMs); //show current frame and increase counter void show(Canvas & to) override; void showAll(Canvas & to) override; void tick(uint32_t msPassed) override; }; /// Creature-dependend animations like attacking, moving,... class CCreatureAnim: public CShowableAnim { private: //queue of animations waiting to be displayed std::queue queue; //this function is used as callback if preview flag was set during construction void loopPreview(bool warMachine); public: //change anim to next if queue is not empty, call callback othervice void reset() override; //add sequence to the end of queue void addLast(ECreatureAnimType newType); void startPreview(bool warMachine); //clear queue and set animation to this sequence void clearAndSet(ECreatureAnimType type); CCreatureAnim(int x, int y, const AnimationPath & name, ui8 flags = 0, ECreatureAnimType = ECreatureAnimType::HOLDING); };