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 SHERLOCK_IMAGE_FILE_H
24 #define SHERLOCK_IMAGE_FILE_H
25 
26 #include "common/array.h"
27 #include "common/file.h"
28 #include "common/hashmap.h"
29 #include "common/hash-str.h"
30 #include "common/rect.h"
31 #include "common/str.h"
32 #include "common/stream.h"
33 #include "graphics/surface.h"
34 
35 namespace Sherlock {
36 
37 class SherlockEngine;
38 
39 struct ImageFrame {
40 	uint32 _pos;
41 	byte _decoded;
42 	uint32 _size;
43 	uint16 _width, _height;
44 	int _paletteBase;
45 	bool _rleEncoded;
46 	Common::Point _offset;
47 	byte _rleMarker;
48 	Graphics::Surface _frame;
49 
50 	/**
51 	 * Converts an ImageFrame record to a surface for convenience in passing to drawing methods
52 	 */
53 	operator const Graphics::Surface &() { return _frame; }
54 
55 	/**
56 	 * Decompress a single frame for the sprite
57 	 */
58 	void decompressFrame(const byte *src, bool isRoseTattoo);
59 
60 	/**
61 	 * Return the frame width adjusted by a specified scale amount
62 	 */
63 	int sDrawXSize(int scaleVal) const;
64 
65 	/**
66 	 * Return the frame height adjusted by a specified scale amount
67 	 */
68 	int sDrawYSize(int scaleVal) const;
69 
70 	/**
71 	 * Return the frame offset x adjusted by a specified scale amount
72 	 */
73 	int sDrawXOffset(int scaleVal) const;
74 
75 	/**
76 	 * Return the frame offset y adjusted by a specified scale amount
77 	 */
78 	int sDrawYOffset(int scaleVal) const;
79 };
80 
81 class ImageFile {
82 private:
83 	static SherlockEngine *_vm;
84 	Common::Array<ImageFrame> _frames;
85 	Common::String _name;
86 
87 	/**
88 	 * Load the data of the sprite
89 	 */
90 	void load(Common::SeekableReadStream &stream, bool skipPalette, bool animImages);
91 
92 	/**
93 	 * Gets the palette at the start of the sprite file
94 	 */
95 	void loadPalette(Common::SeekableReadStream &stream);
96 protected:
97 	virtual void decodeFrame(ImageFrame &frame);
98 public:
99 	ImageFrame& operator[](uint index);
100 	uint size();
101 	void push_back(const ImageFrame &frame);
102 
103 	byte _palette[256 * 3];
104 public:
105 	ImageFile();
106 	ImageFile(const Common::String &name, bool skipPal = false, bool animImages = false);
107 	ImageFile(Common::SeekableReadStream &stream, bool skipPal = false);
108 	virtual ~ImageFile();
109 	static void setVm(SherlockEngine *vm);
110 };
111 
112 enum ImageFile3DOType {
113 	kImageFile3DOType_Animation    = 0,
114 	kImageFile3DOType_Cel          = 1,
115 	kImageFile3DOType_CelAnimation = 2,
116 	kImageFile3DOType_RoomFormat   = 3,
117 	kImageFile3DOType_Font         = 4
118 };
119 
120 struct ImageFile3DOPixelLookupTable {
121 	uint16 pixelColor[256];
122 };
123 
124 class ImageFile3DO : public ImageFile { // Common::Array<ImageFrame> {
125 private:
126 	static SherlockEngine *_vm;
127 
128 	/**
129 	 * Load the data of the sprite
130 	 */
131 	void load(Common::SeekableReadStream &stream, bool isRoomData);
132 
133 	/**
134 	 * convert pixel RGB values from RGB555 to RGB565
135 	 */
136 	inline uint16 convertPixel(uint16 pixel3DO);
137 
138 	/**
139 	 * Load 3DO cel file
140 	 */
141 	void load3DOCelFile(Common::SeekableReadStream &stream);
142 
143 	/**
144 	 * Load 3DO cel data (room file format)
145 	 */
146 	void load3DOCelRoomData(Common::SeekableReadStream &stream);
147 
148 	inline uint16 celGetBits(const byte *&dataPtr, byte bitCount, byte &dataBitsLeft);
149 
150 	/**
151 	 * Decompress a single frame of a 3DO cel file
152 	 */
153 	void decompress3DOCelFrame(ImageFrame &frame, const byte *dataPtr, uint32 dataSize, byte bitsPerPixel, ImageFile3DOPixelLookupTable *pixelLookupTable);
154 
155 	/**
156 	 * Load animation graphics file
157 	 */
158 	void loadAnimationFile(Common::SeekableReadStream &stream);
159 
160 	/**
161 	 * Load Sherlock Holmes 3DO font file
162 	 */
163 	void loadFont(Common::SeekableReadStream &stream);
164 
165 protected:
166 	void decodeFrame(ImageFrame &frame);
167 
168 public:
169 	ImageFile3DO(const Common::String &name, ImageFile3DOType imageFile3DOType);
170 	ImageFile3DO(Common::SeekableReadStream &stream, bool isRoomData = false);
171 	static void setVm(SherlockEngine *vm);
172 };
173 
174 #define STREAMING_BUFFER_SIZE 65536
175 
176 class StreamingImageFile {
177 private:
178 	int _frameNumber;
179 	Common::SeekableReadStream *_stream;
180 	byte _buffer[STREAMING_BUFFER_SIZE];
181 	bool _compressed;
182 	bool _active;
183 public:
184 	ImageFrame _imageFrame;
185 
186 	Common::Point _position;		// Animation position
187 	Common::Rect _oldBounds;		// Bounds of previous frame
188 	Common::Rect _removeBounds;		// Remove area for just drawn frame
189 
190 	int _flags;						// Flags
191 	int _scaleVal;					// Specifies the scale amount
192 	int _zPlacement;				// Used by doBgAnim for determining Z order
193 public:
194 	StreamingImageFile();
195 	~StreamingImageFile();
196 
197 	/**
198 	 * Initialize reading of the specified stream
199 	 */
200 	void load(Common::SeekableReadStream *stream, bool compressed);
201 
202 	/**
203 	 * Close the streamining image file
204 	 */
205 	void close();
206 
207 	/**
208 	 * Get the next frame of the file
209 	 */
210 	bool getNextFrame();
211 
212 	/**
213 	 * Returns whether there are any remaining frames or not
214 	 */
active()215 	bool active() const { return _active; }
216 
217 	/**
218 	 * Return the current frame number
219 	 */
frameNumber()220 	int frameNumber() const { return _frameNumber; }
221 };
222 
223 } // End of namespace Sherlock
224 
225 #endif
226