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
|
/*
* 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 "../gui/SDL_Extensions.h"
struct SDL_Surface;
struct Rect;
class CAnimImage;
class CLabel;
class CAnimation;
// Image class
class CPicture : public CIntObject
{
void setSurface(SDL_Surface *to);
public:
SDL_Surface * bg;
Rect * srcRect; //if nullptr then whole surface will be used
bool freeSurf; //whether surface will be freed upon CPicture destruction
bool needRefresh;//Surface needs to be displayed each frame
bool visible;
operator SDL_Surface*()
{
return bg;
}
CPicture(const Rect & r, const SDL_Color & color, bool screenFormat = false); //rect filled with given color
CPicture(const Rect & r, ui32 color, bool screenFormat = false); //rect filled with given color
CPicture(SDL_Surface * BG, int x = 0, int y=0, bool Free = true); //wrap existing SDL_Surface
CPicture(const std::string &bmpname, int x=0, int y=0);
CPicture(SDL_Surface *BG, const Rect &SrcRext, int x = 0, int y = 0, bool free = false); //wrap subrect of given surface
~CPicture();
void init();
//set alpha value for whole surface. Note: may be messed up if surface is shared
// 0=transparent, 255=opaque
void setAlpha(int value);
void scaleTo(Point size);
void createSimpleRect(const Rect &r, bool screenFormat, ui32 color);
void show(SDL_Surface * to) override;
void showAll(SDL_Surface * to) override;
void convertToScreenBPP();
void colorize(PlayerColor player);
};
/// area filled with specific texture
class CFilledTexture : CIntObject
{
SDL_Surface * texture;
public:
CFilledTexture(std::string imageName, Rect position);
~CFilledTexture();
void showAll(SDL_Surface *to) override;
};
/// 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;
PlayerColor player;
ui8 flags;
void init();
public:
bool visible;
CAnimImage(const std::string & name, size_t Frame, size_t Group=0, int x=0, int y=0, ui8 Flags=0);
CAnimImage(std::shared_ptr<CAnimation> Anim, size_t Frame, size_t Group=0, int x=0, int y=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
void playerColored(PlayerColor player);
void showAll(SDL_Surface * to) override;
};
/// 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
PLAYER_COLORED=16, //TODO: all loaded images will be player-colored
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
//TODO: replace with time delay(needed for battles)
ui32 frameDelay;//delay in frames of each image
ui32 value;//how many times current frame was showed
ui8 flags;//Flags from EFlags enum
//blit image with optional rotation, fitting into rect, etc
void blitImage(size_t frame, size_t group, SDL_Surface *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, std::string name, ui8 flags=0, ui32 Delay=4, size_t Group=0);
~CShowableAnim();
//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();
//show current frame and increase counter
void show(SDL_Surface * to) override;
void showAll(SDL_Surface * to) override;
};
/// Creature-dependend animations like attacking, moving,...
class CCreatureAnim: public CShowableAnim
{
public:
enum EHeroAnimType
{
HERO_HOLDING = 0,
HERO_IDLE = 1, // idling movement that happens from time to time
HERO_DEFEAT = 2, // played when army loses stack or on friendly fire
HERO_VICTORY = 3, // when enemy stack killed or huge damage is dealt
HERO_CAST_SPELL = 4 // spellcasting
};
enum EAnimType // list of creature animations, numbers were taken from def files
{
MOVING=0,
MOUSEON=1,
HOLDING=2,
HITTED=3,
DEFENCE=4,
DEATH=5,
DEATH_RANGED=6,
TURN_L=7,
TURN_R=8, //same
//TURN_L2=9, //identical to previous?
//TURN_R2=10,
ATTACK_UP=11,
ATTACK_FRONT=12,
ATTACK_DOWN=13,
SHOOT_UP=14,
SHOOT_FRONT=15,
SHOOT_DOWN=16,
CAST_UP=17,
CAST_FRONT=18,
CAST_DOWN=19,
MOVE_START=20,
MOVE_END=21,
DEAD = 22, // new group, used to show dead stacks. If empty - last frame from "DEATH" will be copied here
DEAD_RANGED = 23, // new group, used to show dead stacks (if DEATH_RANGED was used). If empty - last frame from "DEATH_RANGED" will be copied here
VCMI_CAST_UP = 30,
VCMI_CAST_FRONT = 31,
VCMI_CAST_DOWN = 32,
VCMI_2HEX_UP = 40,
VCMI_2HEX_FRONT = 41,
VCMI_2HEX_DOWN = 42
};
private:
//queue of animations waiting to be displayed
std::queue<EAnimType> 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(EAnimType newType);
void startPreview(bool warMachine);
//clear queue and set animation to this sequence
void clearAndSet(EAnimType type);
CCreatureAnim(int x, int y, std::string name, ui8 flags = 0, EAnimType = HOLDING);
};
|