File: Images.h

package info (click to toggle)
vcmi 0.99%2Bdfsg%2Bgit20190113.f06c8a87-1
  • links: PTS, VCS
  • area: contrib
  • in suites: buster
  • size: 11,096 kB
  • sloc: cpp: 142,605; sh: 315; objc: 248; makefile: 32; ansic: 28; python: 13
file content (231 lines) | stat: -rw-r--r-- 6,267 bytes parent folder | download | duplicates (2)
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);

};