1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef ULTIMA4_GFX_IMAGE_H
24 #define ULTIMA4_GFX_IMAGE_H
25 
26 #include "ultima/ultima4/core/types.h"
27 #include "ultima/ultima4/gfx/textcolor.h"
28 #include "graphics/managed_surface.h"
29 
30 namespace Ultima {
31 namespace Ultima4 {
32 
33 typedef Graphics::ManagedSurface *BackendSurface;
34 
35 #define DARK_GRAY_HALO RGBA(14,15,16,255)
36 
37 struct RGBA {
RGBARGBA38 	RGBA(int red, int green, int blue, int alpha) : r(red), g(green), b(blue), a(alpha) {}
RGBARGBA39 	RGBA() : r(0), g(0), b(0), a(255) {}
40 	uint r, g, b, a;
41 
uint32RGBA42 	operator uint32() const {
43 		return r | (g << 8) | (b << 16) | (0xff << 24);
44 	}
45 };
46 bool operator==(const RGBA &lhs, const RGBA &rhs);
47 
48 class Image;
49 
50 struct SubImage : public Common::Rect {
51 	Common::String _name;
52 	Common::String _srcImageName;
53 };
54 
55 #define IM_OPAQUE (uint) 255
56 #define IM_TRANSPARENT 0
57 
58 /**
59  * A simple image object that can be drawn and read/written to at the
60  * pixel level.
61  * @todo
62  *  <ul>
63  *      <li>drawing methods should be pushed to Drawable subclass</li>
64  *  </ul>
65  */
66 class Image {
67 private:
68 	Graphics::ManagedSurface *_surface;
69 	DisposeAfterUse::Flag _disposeAfterUse;
70 	bool _paletted;
71 	RGBA _backgroundColor;
72 	Image();                    /* use create method to construct images */
73 
74 	// disallow assignments, copy contruction
75 	Image(const Image &);
76 	const Image &operator=(const Image &);
77 
78 	Graphics::ManagedSurface *getSurface(Image *d) const;
79 
80 	uint getColor(byte r, byte g, byte b, byte a);
81 public:
82 	enum Type {
83 		HARDWARE,
84 		SOFTWARE
85 	};
86 
87 	/**
88 	 * Creates a new image.  Scale is stored to allow drawing using U4
89 	 * (320x200) coordinates, regardless of the actual image scale.
90 	 * Indexed is true for palette based images, or false for RGB images.
91 	 * Image type determines whether to create a hardware (i.e. video ram)
92 	 * or software (i.e. normal ram) image.
93 	 */
94 	static Image *create(int w, int h, bool paletted, Type type);
95 
96 	/**
97 	 * Create a special purpose image the represents the whole screen.
98 	 */
99 	static Image *createScreenImage();
100 
101 	/**
102 	 * Creates a duplicate of another image
103 	 */
104 	static Image *duplicate(Image *image);
105 
106 	/**
107 	 * Frees the image.
108 	 */
109 	~Image();
110 
111 	void create(int w, int h, bool paletted);
112 
113 	/* palette handling */
114 	/**
115 	 * Sets the palette
116 	 */
117 	void setPalette(const RGBA *colors, unsigned n_colors);
118 
119 	/**
120 	 * Copies the palette from another image.
121 	 */
122 	void setPaletteFromImage(const Image *src);
123 	bool getTransparentIndex(uint &index) const;
124 	void performTransparencyHack(uint colorValue, uint numFrames, uint currentFrameIndex, uint haloWidth, uint haloOpacityIncrementByPixelDistance);
125 	void setTransparentIndex(uint index);
126 
127 	/**
128 	 * Sets the specified font colors
129 	 */
130 	bool setFontColor(ColorFG fg, ColorBG bg);
131 
132 	/**
133 	 * Sets the specified font colors
134 	 */
135 	bool setFontColorFG(ColorFG fg);
136 
137 	/**
138 	 * Sets the specified font colors
139 	 */
140 	bool setFontColorBG(ColorBG bg);
141 
142 	/**
143 	 * Returns the color of the specified palette index
144 	 */
145 	RGBA getPaletteColor(int index);       // returns the color of the specified palette index
146 
147 	/**
148 	 * Sets the specified palette index to the specified RGB color
149 	 */
150 	bool setPaletteIndex(uint index, RGBA color);
151 
152 	/**
153 	 * Returns the palette index of the specified RGB color
154 	 */
155 	int getPaletteIndex(RGBA color);
156 	RGBA setColor(uint8 r, uint8 g, uint8 b, uint8 a = IM_OPAQUE);
157 
158 
159 	/* alpha handling */
160 	bool isAlphaOn() const;
161 	void alphaOn();
162 	void alphaOff();
163 
164 
165 	/* Will clear the image to the background color, and set the internal backgroundColor variable */
166 	void initializeToBackgroundColor(RGBA backgroundColor = DARK_GRAY_HALO);
167 	/* Will make the pixels that match the background color disappear, with a blur halo */
168 	void makeBackgroundColorTransparent(int haloSize = 0,  int shadowOpacity = 255);
169 
170 
171 	//void finalizeAlphaSurface(RGBA * key = nullptr);
172 
173 	/* writing to image */
174 
175 	/**
176 	 * Sets the color of a single pixel.
177 	 */
178 	void putPixel(int x, int y, int r, int g, int b, int a); //TODO Consider using &
179 
180 	/**
181 	 * Sets the palette index of a single pixel.  If the image is in
182 	 * indexed mode, then the index is simply the palette entry number.
183 	 * If the image is RGB, it is a packed RGB triplet.
184 	 */
185 	void putPixelIndex(int x, int y, uint index);
186 
187 	/**
188 	 * Fills a rectangle in the image with a given color.
189 	 */
190 	void fillRect(int x, int y, int w, int h, int r, int g, int b, int a = IM_OPAQUE);
191 
192 	void blitFrom(const Graphics::Surface &src);
193 
194 	/* reading from image */
195 	/**
196 	 * Gets the color of a single pixel.
197 	 */
198 	void getPixel(int x, int y, uint &r, uint &g, uint &b, uint &a) const;
199 
200 	/**
201 	 * Gets the palette index of a single pixel.  If the image is in
202 	 * indexed mode, then the index is simply the palette entry number.
203 	 * If the image is RGB, it is a packed RGB triplet.
204 	 */
205 	void getPixelIndex(int x, int y, uint &index) const;
206 
207 	/* image drawing methods */
208 	/**
209 	 * Draws the entire image onto the screen at the given offset.
210 	 */
draw(int x,int y)211 	void draw(int x, int y) const {
212 		drawOn(nullptr, x, y);
213 	}
214 
215 	/**
216 	 * Draws a piece of the image onto the screen at the given offset.
217 	 * The area of the image to draw is defined by the rectangle rx, ry,
218 	 * rw, rh.
219 	 */
drawSubRect(int x,int y,int rx,int ry,int rw,int rh)220 	void drawSubRect(int x, int y, int rx, int ry, int rw, int rh) const {
221 		drawSubRectOn(nullptr, x, y, rx, ry, rw, rh);
222 	}
223 
224 	/**
225 	 * Draws a piece of the image onto the screen at the given offset, inverted.
226 	 * The area of the image to draw is defined by the rectangle rx, ry,
227 	 * rw, rh.
228 	 */
drawSubRectInverted(int x,int y,int rx,int ry,int rw,int rh)229 	void drawSubRectInverted(int x, int y, int rx, int ry, int rw, int rh) const {
230 		drawSubRectInvertedOn(nullptr, x, y, rx, ry, rw, rh);
231 	}
232 
233 	/* image drawing methods for drawing onto another image instead of the screen */
234 	/**
235 	 * Draws the image onto another image.
236 	 */
237 	void drawOn(Image *d, int x, int y) const;
238 
239 	/**
240 	 * Draws a piece of the image onto another image.
241 	 */
242 	void drawSubRectOn(Image *d, int x, int y, int rx, int ry, int rw, int rh) const;
243 
244 	/**
245 	 * Draws a piece of the image onto another image, inverted.
246 	 */
247 	void drawSubRectInvertedOn(Image *d, int x, int y, int rx, int ry, int rw, int rh) const;
248 
width()249 	int width() const {
250 		return _surface->w;
251 	}
height()252 	int height() const {
253 		return _surface->h;
254 	}
isIndexed()255 	bool isIndexed() const {
256 		return _paletted;
257 	}
getSurface()258 	BackendSurface getSurface() {
259 		return _surface;
260 	}
261 
262 	void drawHighlighted();
263 
264 	/**
265 	 * Debug method that dumps a given image directly to the screen
266 	 * and does a screen update. Useful for validating images are correct
267 	 */
268 	void dump();
269 };
270 
271 } // End of namespace Ultima4
272 } // End of namespace Ultima
273 
274 #endif
275