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