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 /*
24  * This code is based on Broken Sword 2.5 engine
25  *
26  * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
27  *
28  * Licensed under GNU GPL v2
29  *
30  */
31 
32 /*
33  * GraphicEngine
34  * ----------------
35  * This the graphics engine interface.
36  *
37  * Autor: Malte Thiesen
38  */
39 
40 #ifndef SWORD25_GRAPHICENGINE_H
41 #define SWORD25_GRAPHICENGINE_H
42 
43 // Includes
44 #include "common/array.h"
45 #include "common/rect.h"
46 #include "common/ptr.h"
47 #include "common/str.h"
48 #include "graphics/surface.h"
49 #include "sword25/kernel/common.h"
50 #include "sword25/kernel/resservice.h"
51 #include "sword25/kernel/persistable.h"
52 #include "sword25/gfx/renderobjectptr.h"
53 #include "sword25/math/vertex.h"
54 
55 namespace Sword25 {
56 
57 class Kernel;
58 class Image;
59 class Panel;
60 class Screenshot;
61 class RenderObjectManager;
62 
63 typedef uint BS_COLOR;
64 
65 #define BS_RGB(R,G,B)       (0xFF000000 | ((R) << 16) | ((G) << 8) | (B))
66 #define BS_ARGB(A,R,G,B)    (((A) << 24) | ((R) << 16) | ((G) << 8) | (B))
67 
68 /**
69  * This is the graphics engine. Unlike the original code, this is not
70  * an interface that needs to be subclassed, but rather already contains
71  * all required functionality.
72  */
73 class GraphicEngine : public ResourceService, public Persistable {
74 public:
75 	// Enums
76 	// -----
77 
78 	// Color formats
79 	//
80 	/**
81 	 * The color format used by the engine
82 	 */
83 	enum COLOR_FORMATS {
84 		/// Undefined/unknown color format
85 		CF_UNKNOWN = 0,
86 		/**
87 		 * 24-bit color format (R8G8B8)
88 		 */
89 		CF_RGB24,
90 		/**
91 		 * 32-bit color format (A8R8G8B8) (little endian)
92 		*/
93 		CF_ARGB32,
94 		/**
95 		    32-bit color format (A8B8G8R8) (little endian)
96 		*/
97 		CF_ABGR32
98 	};
99 
100 	// Constructor
101 	// -----------
102 	GraphicEngine(Kernel *pKernel);
103 	~GraphicEngine();
104 
105 	// Interface
106 	// ---------
107 
108 	/**
109 	 * Initializes the graphics engine and sets the screen mode. Returns
110 	 * true if initialisation failed.
111 	 * @note This method should be called immediately after the
112 	 * initialisation of all services.
113 	 *
114 	 * @param Height            The height of the output buffer in pixels. The default value is 600
115 	 * @param BitDepth          The bit depth of the desired output buffer in bits. The default value is 16
116 	 * @param BackbufferCount   The number of back buffers to be created. The default value is 2
117 	 */
118 	bool init(int width = 800, int height = 600, int bitDepth = 16, int backbufferCount = 2);
119 
120 	/**
121 	 * Begins rendering a new frame.
122 	 * Notes: This method must be called at the beginning of the main loop, before any rendering methods are used.
123 	 * Notes: Implementations of this method must call _UpdateLastFrameDuration()
124 	 * @param UpdateAll         Specifies whether the renderer should redraw everything on the next frame.
125 	 * This feature can be useful if the renderer with Dirty Rectangles works, but sometimes the client may
126 	*/
127 	bool startFrame(bool updateAll = false);
128 
129 	/**
130 	 * Ends the rendering of a frame and draws it on the screen.
131 	 *
132 	 * This method must be at the end of the main loop. After this call, no further Render method may be called.
133 	 * This should only be called once for a given previous call to #StartFrame.
134 	*/
135 	bool endFrame();
136 
137 	/**
138 	 * Creates a thumbnail with the dimensions of 200x125. This will not include the top and bottom of the screen..
139 	 * the interface boards the the image as a 16th of it's original size.
140 	 * Notes: This method should only be called after a call to EndFrame(), and before the next call to StartFrame().
141 	 * The frame buffer must have a resolution of 800x600.
142 	 * @param Filename  The filename for the screenshot
143 	 */
144 	bool saveThumbnailScreenshot(const Common::String &filename);
145 
146 	RenderObjectPtr<Panel> getMainPanel();
147 
148 	/**
149 	 * Specifies the time (in microseconds) since the last frame has passed
150 	 */
getLastFrameDurationMicro()151 	int getLastFrameDurationMicro() const {
152 		if (!_timerActive)
153 			return 0;
154 		return _lastFrameDuration;
155 	}
156 
157 	/**
158 	 * Specifies the time (in microseconds) the previous frame took
159 	*/
getLastFrameDuration()160 	float getLastFrameDuration() const {
161 		if (!_timerActive)
162 			return 0;
163 		return static_cast<float>(_lastFrameDuration) / 1000000.0f;
164 	}
165 
stopMainTimer()166 	void stopMainTimer() {
167 		_timerActive = false;
168 	}
169 
resumeMainTimer()170 	void resumeMainTimer() {
171 		_timerActive = true;
172 	}
173 
getSecondaryFrameDuration()174 	float getSecondaryFrameDuration() const {
175 		return static_cast<float>(_lastFrameDuration) / 1000000.0f;
176 	}
177 
178 	// Accessor methods
179 
180 	/**
181 	 * Returns the width of the output buffer in pixels
182 	 */
getDisplayWidth()183 	int getDisplayWidth() const {
184 		return _width;
185 	}
186 
187 	/**
188 	 * Returns the height of the output buffer in pixels
189 	 */
getDisplayHeight()190 	int getDisplayHeight() const {
191 		return _height;
192 	}
193 
194 	/**
195 	 * Returns the bounding box of the output buffer: (0, 0, Width, Height)
196 	 */
getDisplayRect()197 	Common::Rect &getDisplayRect() {
198 		return _screenRect;
199 	}
200 
201 	/**
202 	 * Returns the bit depth of the output buffer
203 	 */
getBitDepth()204 	int getBitDepth() {
205 		return _bitDepth;
206 	}
207 
208 	/**
209 	 * Determines whether the frame buffer change is to be synchronised with Vsync. This is turned on by default.
210 	 * Notes: In windowed mode, this setting has no effect.
211 	 * @param Vsync     Indicates whether the frame buffer changes are to be synchronised with Vsync.
212 	 */
213 	void setVsync(bool vsync);
214 
215 	/**
216 	 * Returns true if V-Sync is on.
217 	 * Notes: In windowed mode, this setting has no effect.
218 	 */
219 	bool getVsync() const;
220 
221 	/**
222 	 * Fills a rectangular area of the frame buffer with a color.
223 	 * Notes: It is possible to create transparent rectangles by passing a color with an Alpha value of 255.
224 	 * @param FillRectPtr   Pointer to a Common::Rect, which specifies the section of the frame buffer to be filled.
225 	 * If the rectangle falls partly off-screen, then it is automatically trimmed.
226 	 * If a NULL value is passed, then the entire image is to be filled.
227 	 * @param Color         The 32-bit color with which the area is to be filled. The default is BS_RGB(0, 0, 0) (black)
228 	 * @note FIf the rectangle is not completely inside the screen, it is automatically clipped.
229 	 */
230 	bool fill(const Common::Rect *fillRectPtr = 0, uint color = BS_RGB(0, 0, 0));
231 
232 	Graphics::Surface _backSurface;
getSurface()233 	Graphics::Surface *getSurface() { return &_backSurface; }
234 
235 	Common::SeekableReadStream *_thumbnail;
getThumbnail()236 	Common::SeekableReadStream *getThumbnail() { return _thumbnail; }
237 
238 	// Access methods
239 
240 	/**
241 	 * Returns the size of a pixel entry in bytes for a particular color format
242 	 * @param ColorFormat   The desired color format. The parameter must be of type COLOR_FORMATS
243 	 * @return              Returns the size of a pixel in bytes. If the color format is unknown, -1 is returned.
244 	 */
getPixelSize(GraphicEngine::COLOR_FORMATS colorFormat)245 	static int getPixelSize(GraphicEngine::COLOR_FORMATS colorFormat) {
246 		switch (colorFormat) {
247 		case GraphicEngine::CF_ARGB32:
248 			return 4;
249 		default:
250 			return -1;
251 		}
252 	}
253 
254 	/**
255 	 * Calculates the length of an image line in bytes, depending on a given color format.
256 	 * @param ColorFormat   The color format
257 	 * @param Width         The width of the line in pixels
258 	 * @return              Reflects the length of the line in bytes. If the color format is
259 	 * unknown, -1 is returned
260 	 */
calcPitch(GraphicEngine::COLOR_FORMATS colorFormat,int width)261 	static int calcPitch(GraphicEngine::COLOR_FORMATS colorFormat, int width) {
262 		switch (colorFormat) {
263 		case GraphicEngine::CF_ARGB32:
264 			return width * 4;
265 
266 		default:
267 			assert(false);
268 		}
269 
270 		return -1;
271 	}
272 
273 	// Resource-Managing Methods
274 	// --------------------------
275 	virtual Resource *loadResource(const Common::String &fileName);
276 	virtual bool canLoadResource(const Common::String &fileName);
277 
278 	// Persistence Methods
279 	// -------------------
280 	virtual bool persist(OutputPersistenceBlock &writer);
281 	virtual bool unpersist(InputPersistenceBlock &reader);
282 
283 	static void ARGBColorToLuaColor(lua_State *L, uint color);
284 	static uint luaColorToARGBColor(lua_State *L, int stackIndex);
285 
286 protected:
287 
288 	// Display Variables
289 	// -----------------
290 	int _width;
291 	int _height;
292 	Common::Rect _screenRect;
293 	int _bitDepth;
294 
295 	/**
296 	 * Calculates the time since the last frame beginning has passed.
297 	 */
298 	void updateLastFrameDuration();
299 
300 private:
301 	bool registerScriptBindings();
302 	void unregisterScriptBindings();
303 
304 	// LastFrameDuration Variables
305 	// ---------------------------
306 	uint _lastTimeStamp;
307 	uint _lastFrameDuration;
308 	bool _timerActive;
309 	Common::Array<uint> _frameTimeSamples;
310 	uint _frameTimeSampleSlot;
311 
312 private:
313 	RenderObjectPtr<Panel> _mainPanelPtr;
314 
315 	Common::ScopedPtr<RenderObjectManager> _renderObjectManagerPtr;
316 
317 	struct DebugLine {
DebugLineDebugLine318 		DebugLine(const Vertex &start, const Vertex &end, uint color) :
319 			_start(start),
320 			_end(end),
321 			_color(color) {}
DebugLineDebugLine322 		DebugLine() {}
323 
324 		Vertex _start;
325 		Vertex _end;
326 		uint _color;
327 	};
328 };
329 
330 } // End of namespace Sword25
331 
332 #endif
333