1 /*
2  * Copyright 2010-2014 OpenXcom Developers.
3  *
4  * This file is part of OpenXcom.
5  *
6  * OpenXcom is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * OpenXcom is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with OpenXcom.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 #ifndef OPENXCOM_SURFACE_H
20 #define OPENXCOM_SURFACE_H
21 
22 #include <SDL.h>
23 #include <SDL_image.h>
24 #include <string>
25 
26 namespace OpenXcom
27 {
28 
29 class Font;
30 class Language;
31 
32 /**
33  * Element that is blit (rendered) onto the screen.
34  * Mainly an encapsulation for SDL's SDL_Surface struct, so it
35  * borrows a lot of its terminology. Takes care of all the common
36  * rendering tasks and color effects, while serving as the base
37  * class for more specialized screen elements.
38  */
39 class Surface
40 {
41 protected:
42 	SDL_Surface *_surface;
43 	int _x, _y;
44 	SDL_Rect _crop, _clear;
45 	bool _visible, _hidden, _redraw;
46 	void *_alignedBuffer;
47 	std::string _tooltip;
48 
49 	void resize(int width, int height);
50 public:
51 	/// Creates a new surface with the specified size and position.
52 	Surface(int width, int height, int x = 0, int y = 0, int bpp = 8);
53 	/// Creates a new surface from an existing one.
54 	Surface(const Surface& other);
55 	/// Cleans up the surface.
56 	virtual ~Surface();
57 	/// Loads an X-Com SCR graphic.
58 	void loadScr(const std::string &filename);
59 	/// Loads an X-Com SPK graphic.
60 	void loadSpk(const std::string &filename);
61 	/// Loads a TFTD BDY graphic.
62 	void loadBdy(const std::string &filename);
63 	/// Loads a general image file.
64 	void loadImage(const std::string &filename);
65 	/// Clears the surface's contents.
66 	void clear();
67 	/// Offsets the surface's colors by a set amount.
68 	void offset(int off, int min = -1, int max = -1, int mul = 1);
69 	/// Inverts the surface's colors.
70 	void invert(Uint8 mid);
71 	/// Runs surface functionality every cycle
72 	virtual void think();
73 	/// Draws the surface's graphic.
74 	virtual void draw();
75 	/// Blits this surface onto another one.
76 	virtual void blit(Surface *surface);
77 	/// Initializes the surface's various text resources.
initText(Font *,Font *,Language *)78 	virtual void initText(Font *, Font *, Language *) {};
79 	/// Copies a portion of another surface into this one.
80 	void copy(Surface *surface);
81     /// Draws a filled rectangle on the surface.
82     void drawRect(SDL_Rect *rect, Uint8 color);
83 	/// Draws a filled rectangle on the surface.
84 	void drawRect(Sint16 x, Sint16 y, Sint16 w, Sint16 h, Uint8 color);
85     /// Draws a line on the surface.
86     void drawLine(Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 color);
87     /// Draws a filled circle on the surface.
88     void drawCircle(Sint16 x, Sint16 y, Sint16 r, Uint8 color);
89     /// Draws a filled polygon on the surface.
90     void drawPolygon(Sint16 *x, Sint16 *y, int n, Uint8 color);
91     /// Draws a textured polygon on the surface.
92     void drawTexturedPolygon(Sint16 *x, Sint16 *y, int n, Surface *texture, int dx, int dy);
93     /// Draws a string on the surface.
94     void drawString(Sint16 x, Sint16 y, const char *s, Uint8 color);
95 	/// Sets the surface's palette.
96 	virtual void setPalette(SDL_Color *colors, int firstcolor = 0, int ncolors = 256);
97 	/**
98 	 * Returns the surface's 8bpp palette.
99 	 * @return Pointer to the palette's colors.
100 	 */
getPalette()101 	SDL_Color *getPalette() const
102 	{
103 		return _surface->format->palette->colors;
104 	}
105 	/// Sets the X position of the surface.
106 	virtual void setX(int x);
107 	/**
108 	 * Returns the position of the surface in the X axis.
109 	 * @return X position in pixels.
110 	 */
getX()111 	int getX() const
112 	{
113 		return _x;
114 	}
115 	/// Sets the Y position of the surface.
116 	virtual void setY(int y);
117 	/**
118 	 * Returns the position of the surface in the Y axis.
119 	 * @return Y position in pixels.
120 	 */
getY()121 	int getY() const
122 	{
123 		return _y;
124 	}
125 	/// Sets the surface's visibility.
126 	void setVisible(bool visible);
127 	/// Gets the surface's visibility.
128 	bool getVisible() const;
129 	/// Resets the cropping rectangle for the surface.
130 	void resetCrop();
131 	/// Gets the cropping rectangle for the surface.
132 	SDL_Rect *getCrop();
133 	/**
134 	 * Changes the color of a pixel in the surface, relative to
135 	 * the top-left corner of the surface.
136 	 * @param x X position of the pixel.
137 	 * @param y Y position of the pixel.
138 	 * @param pixel New color for the pixel.
139 	 */
setPixel(int x,int y,Uint8 pixel)140 	void setPixel(int x, int y, Uint8 pixel)
141 	{
142 		if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight())
143 		{
144 			return;
145 		}
146 		((Uint8 *)_surface->pixels)[y * _surface->pitch + x * _surface->format->BytesPerPixel] = pixel;
147 	}
148 	/**
149 	 * Changes the color of a pixel in the surface and returns the
150 	 * next pixel position. Useful when changing a lot of pixels in
151 	 * a row, eg. loading images.
152 	 * @param x Pointer to the X position of the pixel. Changed to the next X position in the sequence.
153 	 * @param y Pointer to the Y position of the pixel. Changed to the next Y position in the sequence.
154 	 * @param pixel New color for the pixel.
155 	 */
setPixelIterative(int * x,int * y,Uint8 pixel)156 	void setPixelIterative(int *x, int *y, Uint8 pixel)
157 	{
158 		setPixel(*x, *y, pixel);
159 		(*x)++;
160 		if (*x == getWidth())
161 		{
162 			(*y)++;
163 			*x = 0;
164 		}
165 	}
166 	/**
167 	 * Returns the color of a specified pixel in the surface.
168 	 * @param x X position of the pixel.
169 	 * @param y Y position of the pixel.
170 	 * @return Color of the pixel.
171 	 */
getPixel(int x,int y)172 	Uint8 getPixel(int x, int y) const
173 	{
174 		if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight())
175 		{
176 			return 0;
177 		}
178 		return ((Uint8 *)_surface->pixels)[y * _surface->pitch + x * _surface->format->BytesPerPixel];
179 	}
180 	/**
181 	 * Returns the internal SDL_Surface for SDL calls.
182 	 * @return Pointer to the surface.
183 	 */
getSurface()184 	SDL_Surface *getSurface() const
185 	{
186 		return _surface;
187 	}
188 	/**
189 	 * Returns the width of the surface.
190 	 * @return Width in pixels.
191 	 */
getWidth()192 	int getWidth() const
193 	{
194 		return _surface->w;
195 	}
196 	/// Sets the width of the surface.
197 	virtual void setWidth(int width);
198 	/**
199 	 * Returns the height of the surface.
200 	 * @return Height in pixels
201 	 */
getHeight()202 	int getHeight() const
203 	{
204 		return _surface->h;
205 	}
206 	/// Sets the height of the surface.
207 	virtual void setHeight(int height);
208 	/// Sets the surface's special hidden flag.
209 	void setHidden(bool hidden);
210 	/// Locks the surface.
211 	void lock();
212 	/// Unlocks the surface.
213 	void unlock();
214 	/// Specific blit function to blit battlescape terrain data in different shades in a fast way.
215 	void blitNShade(Surface *surface, int x, int y, int off, bool half = false, int newBaseColor = 0);
216 	/// Invalidate the surface: force it to be redrawn
217 	void invalidate();
218 	/// Gets the tooltip of the surface.
219 	std::string getTooltip() const;
220 	/// Sets the tooltip of the surface.
221 	void setTooltip(const std::string &tooltip);
222 
223 };
224 
225 }
226 
227 #endif
228