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 XEEN_SPRITES_H
24 #define XEEN_SPRITES_H
25 
26 #include "common/scummsys.h"
27 #include "common/array.h"
28 #include "common/file.h"
29 #include "graphics/surface.h"
30 #include "xeen/files.h"
31 #include "xeen/xsurface.h"
32 
33 namespace Xeen {
34 
35 class XeenEngine;
36 class Window;
37 
38 enum {
39 	SCALE_MASK = 0x7FFF, SCALE_ENLARGE = 0x8000
40 };
41 
42 enum SpriteFlags {
43 	SPRFLAG_MODE_MASK = 0xF00, SPRFLAG_DRAWER1 = 0x100, SPRFLAG_DRAWER2 = 0x200,
44 	SPRFLAG_DRAWER3 = 0x300, SPRFLAG_DRAWER4 = 0x400, SPRFLAG_DRAWER5 = 0x500, SPRFLAG_DRAWER6 = 0x600,
45 	SPRFLAG_DRAWER7 = 0x700, SPRFLAG_800 = 0x800, SPRFLAG_SCENE_CLIPPED = 0x2000,
46 	SPRFLAG_BOTTOM_CLIPPED = 0x4000, SPRFLAG_HORIZ_FLIPPED = 0x8000, SPRFLAG_RESIZE = 0x10000
47 };
48 
49 class SpriteResource {
50 private:
51 	struct IndexEntry {
52 		uint16 _offset1, _offset2;
53 	};
54 	Common::Array<IndexEntry> _index;
55 	size_t _filesize;
56 	byte *_data;
57 	Common::String _filename;
58 	static int _clippedBottom;
59 
60 	/**
61 	 * Load a sprite resource from a stream
62 	 */
63 	void load(Common::SeekableReadStream &f);
64 
65 	/**
66 	 * Draw the sprite onto the given surface
67 	 */
68 	void draw(XSurface &dest, int frame, const Common::Point &destPos,
69 		const Common::Rect &bounds, uint flags = 0, int scale = 0);
70 
71 	/**
72 	 * Draw the sprite onto a given window
73 	 */
74 	void draw(int windowNum, int frame, const Common::Point &destPos,
75 		const Common::Rect &bounds, uint flags = 0, int scale = 0);
76 
77 	/**
78 	 * Deep copy assuming that the current instance is clean
79 	 */
80 	void copy(const SpriteResource &src);
81 public:
82 	SpriteResource();
83 	SpriteResource(const Common::String &filename);
84 	SpriteResource(const Common::String &filename, int ccMode);
85 	SpriteResource(const SpriteResource &src);
86 
87 	virtual ~SpriteResource();
88 
89 	/**
90 	 * Copy operator for duplicating a sprite resource
91 	 */
92 	SpriteResource &operator=(const SpriteResource &src);
93 
94 	/**
95 	 * Load a sprite resource from a given file
96 	 */
97 	void load(const Common::String &filename);
98 
99 	/**
100 	 * Load a sprite resource from a given file and archive
101 	 */
102 	void load(const Common::String &filename, int ccMode);
103 
104 	/**
105 	 * Clears the sprite resource
106 	 */
107 	void clear();
108 
109 	/**
110 	 * Draw a sprite onto a surface
111 	 * @param dest		Destination surface
112 	 * @param frame		Frame number
113 	 * @param destPos	Destination position
114 	 * @param flags		Flags
115 	 * @param scale		Scale: 0=No scale, SCALE_ENLARGE=Enlarge it
116 	 *					1..15   -> reduces the sprite: the higher, the smaller it'll be
117 	 */
118 	void draw(XSurface &dest, int frame, const Common::Point &destPos,
119 		uint flags = 0, int scale = 0);
120 
121 	/**
122 	 * Draw a sprite onto a specific window
123 	 * @param dest		Destination window
124 	 * @param frame		Frame number
125 	 * @param destPos	Destination position
126 	 * @param flags		Flags
127 	 * @param scale		Scale: 0=No scale, SCALE_ENLARGE=Enlarge it
128 	 *					1..15   -> reduces the sprite: the higher, the smaller it'll be
129 	 */
130 	void draw(Window &dest, int frame, const Common::Point &destPos,
131 		uint flags = 0, int scale = 0);
132 
133 	/**
134 	 * Draw a sprite onto a given window
135 	 * @param windowIndex	Destination window number
136 	 * @param frame		Frame number
137 	 * @param destPos	Destination position
138 	 * @param flags		Flags
139 	 * @param scale		Scale: 0=No scale, SCALE_ENLARGE=Enlarge it
140 	 *					1..15   -> reduces the sprite: the higher, the smaller it'll be
141 	 */
142 	void draw(int windowIndex, int frame, const Common::Point &destPos,
143 		uint flags = 0, int scale = 0);
144 
145 	/**
146 	 * Draw the sprite onto the given surface
147 	 * @param dest		Destination surface
148 	 * @param frame		Frame number
149 	 */
150 	void draw(XSurface &dest, int frame);
151 
152 	/**
153 	 * Draw the sprite onto the given window
154 	 * @param windowIndex	Destination window number
155 	 * @param frame			Frame number
156 	 */
157 	void draw(int windowIndex, int frame);
158 
159 	/**
160 	 * Gets the size of a sprite
161 	 */
162 	Common::Point getFrameSize(int frame) const;
163 
164 	/**
165 	 * Returns the number of frames the sprite resource has
166 	 */
size()167 	size_t size() const { return _index.size(); }
168 
169 	/**
170 	 * Returns true if the sprite resource is empty (ie. nothing is loaded)
171 	 */
empty()172 	bool empty() const { return _index.size() == 0; }
173 
174 	/**
175 	 * Set the bottom Y position where sprites are clipped if SPRFLAG_BOTTOM_CLIPPED
176 	 * is applied
177 	 */
setClippedBottom(int y)178 	static void setClippedBottom(int y) { _clippedBottom = y; }
179 };
180 
181 /**
182  * Basic sprite drawer
183  */
184 class SpriteDrawer {
185 private:
186 	byte *_data;
187 	size_t _filesize;
188 protected:
189 	byte *_destTop, *_destBottom;
190 	byte *_destLeft, *_destRight;
191 	int _pitch;
192 private:
193 	/**
194 	 * Scale a co-ordinate value based on the passed scaling mask
195 	 */
196 	static uint getScaledVal(int xy, uint16 &scaleMask);
197 protected:
198 	/**
199 	 * Roll carry right opcode emulation
200 	 */
201 	void rcr(uint16 &val, bool &cf);
202 
203 	/**
204 	 * Output a pixel
205 	 */
206 	virtual void drawPixel(byte *dest, byte pixel);
207 public:
208 	/**
209 	 * Constructor
210 	 */
SpriteDrawer(byte * data,size_t filesize)211 	SpriteDrawer(byte *data, size_t filesize) : _data(data), _filesize(filesize) {}
212 
213 	/**
214 	 * Destructor
215 	 */
~SpriteDrawer()216 	virtual ~SpriteDrawer() {}
217 
218 	/**
219 	 * Draw a sprite frame based on a passed offset into the data stream
220 	 */
221 	void draw(XSurface &dest, uint16 offset, const Common::Point &pt,
222 		const Common::Rect &clipRect, uint flags, int scale);
223 };
224 
225 class SpriteDrawer1 : public SpriteDrawer {
226 private:
227 	byte _offset, _mask;
228 protected:
229 	/**
230 	 * Output a pixel
231 	 */
232 	void drawPixel(byte *dest, byte pixel) override;
233 public:
234 	/**
235 	 * Constructor
236 	 */
237 	SpriteDrawer1(byte *data, size_t filesize, int index);
238 };
239 
240 /**
241  * Scrambles up the sprite by drawing many of the pixels randomly
242  * at a horizontal or vertical offset
243  */
244 class SpriteDrawer2 : public SpriteDrawer {
245 private:
246 	uint16 _mask1, _mask2;
247 	uint16 _random1, _random2;
248 private:
249 	/**
250 	 * Output a pixel
251 	 */
252 	void drawPixel(byte *dest, byte pixel) override;
253 public:
254 	/**
255 	 * Constructor
256 	 */
257 	SpriteDrawer2(byte *data, size_t filesize, int index);
258 };
259 
260 /**
261  * Draws the sprite as faint ghostly, see-through.
262  */
263 class SpriteDrawer3 : public SpriteDrawer {
264 private:
265 	uint16 _offset, _mask;
266 	byte _palette[256 * 3];
267 	bool _hasPalette;
268 private:
269 	/**
270 	 * Output a pixel
271 	 */
272 	void drawPixel(byte *dest, byte pixel) override;
273 public:
274 	/**
275 	 * Constructor
276 	 */
277 	SpriteDrawer3(byte *data, size_t filesize, int index);
278 };
279 
280 class SpriteDrawer4 : public SpriteDrawer {
281 private:
282 	byte _threshold;
283 protected:
284 	/**
285 	 * Output a pixel
286 	 */
287 	void drawPixel(byte *dest, byte pixel) override;
288 public:
289 	/**
290 	 * Constructor
291 	 */
292 	SpriteDrawer4(byte *data, size_t filesize, int index);
293 };
294 
295 /**
296  * Draws a sprite with a fuzziness effect where only some pixels of the sprite are randomly drawn
297  */
298 class SpriteDrawer5 : public SpriteDrawer {
299 private:
300 	uint16 _threshold, _random1, _random2;
301 protected:
302 	/**
303 	 * Output a pixel
304 	 */
305 	void drawPixel(byte *dest, byte pixel) override;
306 public:
307 	/**
308 	 * Constructor
309 	 */
310 	SpriteDrawer5(byte *data, size_t filesize, int index);
311 };
312 
313 class SpriteDrawer6 : public SpriteDrawer {
314 private:
315 	byte _mask;
316 protected:
317 	/**
318 	 * Output a pixel
319 	 */
320 	void drawPixel(byte *dest, byte pixel) override;
321 public:
322 	/**
323 	 * Constructor
324 	 */
325 	SpriteDrawer6(byte *data, size_t filesize, int index);
326 };
327 
328 } // End of namespace Xeen
329 
330 #endif /* MADS_SPRITES_H */
331