1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
|
/*
* 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;
enum class EImageBlitMode : uint8_t;
// Image class
class CPicture : public CIntObject
{
std::shared_ptr<IImage> bg;
std::function<void()> rCallback;
public:
/// if set, only specified section of internal image will be rendered
std::optional<Rect> srcRect;
/// If set to true, image will be redrawn on each frame
bool needRefresh;
std::shared_ptr<IImage> getSurface()
{
return bg;
}
/// wrap existing image
CPicture(std::shared_ptr<IImage> image, const Point & position);
/// wrap section of an existing Image
CPicture(std::shared_ptr<IImage> 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, EImageBlitMode mode);
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<void()> & 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<IImage> 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:
FilledTexturePlayerColored(Rect position);
void setPlayerColor(PlayerColor player);
};
/// Class for displaying one image from animation
class CAnimImage: public CIntObject
{
private:
std::shared_ptr<CAnimation> 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<PlayerColor> 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<CAnimation> 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<void()> 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<ECreatureAnimType> 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);
};
|