1 /* GemRB - Infinity Engine Emulator 2 * Copyright (C) 2003 The GemRB Project 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 * 18 * 19 */ 20 21 /** 22 * @file Video.h 23 * Declares Video, base class for video output plugins. 24 * @author The GemRB Project 25 */ 26 27 #ifndef VIDEO_H 28 #define VIDEO_H 29 30 #include "globals.h" 31 32 #include "EnumFlags.h" 33 #include "Plugin.h" 34 #include "Polygon.h" 35 #include "Sprite2D.h" 36 37 #include <deque> 38 #include <algorithm> 39 40 namespace GemRB { 41 42 class EventMgr; 43 class Palette; 44 using PaletteHolder = Holder<Palette>; 45 46 // Note: not all these flags make sense together. 47 // Specifically: BlitFlags::GREY overrides BlitFlags::SEPIA 48 enum BlitFlags : uint32_t { 49 NONE = 0, 50 HALFTRANS = 2, // IE_VVC_TRANSPARENT 51 BLENDED = 8, // IE_VVC_BLENDED, not implemented in SDLVideo yet 52 MIRRORX = 0x10, // IE_VVC_MIRRORX 53 MIRRORY = 0x20, // IE_VVC_MIRRORY 54 // IE_VVC_TINT = 0x00030000. which is (BlitFlags::COLOR_MOD | BlitFlags::ALPHA_MOD) 55 COLOR_MOD = 0x00010000, // srcC = srcC * (color / 255) 56 ALPHA_MOD = 0x00020000, // srcA = srcA * (alpha / 255) 57 GREY = 0x80000, // IE_VVC_GREYSCALE, timestop palette 58 SEPIA = 0x02000000, // IE_VVC_SEPIA, dream scene palette 59 MULTIPLY = 0x00100000, // IE_VVC_DARKEN, not implemented in SDLVideo yet 60 GLOW = 0x00200000, // IE_VVC_GLOWING, not implemented in SDLVideo yet 61 ADD = 0x00400000, 62 STENCIL_ALPHA = 0x00800000, // blend with the stencil buffer using the stencil's alpha channel as the stencil 63 STENCIL_RED = 0x01000000, // blend with the stencil buffer using the stencil's r channel as the stencil 64 STENCIL_GREEN = 0x08000000, // blend with the stencil buffer using the stencil's g channel as the stencil 65 STENCIL_BLUE = 0x20000000, // blend with the stencil buffer using the stencil's b channel as the stencil 66 STENCIL_DITHER = 0x10000000 // use dithering instead of transpanency. only affects stencil values of 128. 67 }; 68 69 #define BLIT_STENCIL_MASK (BlitFlags::STENCIL_ALPHA|BlitFlags::STENCIL_RED|BlitFlags::STENCIL_GREEN|BlitFlags::STENCIL_BLUE|BlitFlags::STENCIL_DITHER) 70 71 class GEM_EXPORT VideoBuffer { 72 protected: 73 Region rect; 74 75 public: VideoBuffer(const Region & r)76 VideoBuffer(const Region& r) : rect(r) {} ~VideoBuffer()77 virtual ~VideoBuffer() {} 78 Size()79 ::GemRB::Size Size() const { return rect.Dimensions(); } Origin()80 Point Origin() const { return rect.Origin(); } Rect()81 Region Rect() const { return rect; } 82 SetOrigin(const Point & p)83 void SetOrigin(const Point& p) { rect.x = p.x; rect.y = p.y; } 84 Clear()85 virtual void Clear() { Clear({0, 0, rect.w, rect.h}); }; 86 virtual void Clear(const Region& rgn) = 0; 87 // CopyPixels takes at least one void* buffer with implied pitch of Region.w, otherwise alternating pairs of buffers and their coresponding pitches 88 virtual void CopyPixels(const Region& bufDest, const void* pixelBuf, const int* pitch = NULL, ...) = 0; 89 90 virtual bool RenderOnDisplay(void* display) const = 0; 91 }; 92 93 using VideoBufferPtr = std::shared_ptr<VideoBuffer>; 94 95 /** 96 * @class Video 97 * Base class for video output plugins. 98 */ 99 100 class GEM_EXPORT Video : public Plugin { 101 public: 102 static const TypeID ID; 103 104 enum class BufferFormat { 105 DISPLAY, // whatever format the video driver thinks is best for the display 106 DISPLAY_ALPHA, // the same RGB format as DISPLAY, but forces an alpha if DISPLAY doesn't provide one 107 RGBPAL8, // 8 bit palettized 108 RGB555, // 16 bit RGB (truecolor) 109 RGBA8888, // Standard 8 bits per channel with alpha 110 YV12 // YUV format for BIK videos 111 }; 112 113 protected: 114 unsigned long lastTime; 115 EventMgr* EvntManager; 116 Region screenClip; 117 Size screenSize; 118 int bpp; 119 bool fullscreen; 120 121 unsigned char Gamma10toGamma22[256]; 122 unsigned char Gamma22toGamma10[256]; 123 124 using VideoBuffers = std::deque<VideoBuffer*>; 125 126 // collection of all existing video buffers 127 VideoBuffers buffers; 128 // collection built by calls to PushDrawingBuffer() and cleared after SwapBuffers() 129 // the collection is iterated and drawn in order during SwapBuffers() 130 // Note: we can add the same buffer more than once to drawingBuffers! 131 VideoBuffers drawingBuffers; 132 // the current top of drawingBuffers that draw operations occur on 133 VideoBuffer* drawingBuffer; 134 VideoBufferPtr stencilBuffer = nullptr; 135 136 Region ClippedDrawingRect(const Region& target, const Region* clip = NULL) const; 137 virtual void Wait(unsigned long) = 0; 138 void DestroyBuffer(VideoBuffer*); 139 void DestroyBuffers(); 140 141 private: 142 virtual VideoBuffer* NewVideoBuffer(const Region&, BufferFormat)=0; 143 virtual void SwapBuffers(VideoBuffers&)=0; 144 virtual int PollEvents() = 0; 145 virtual int CreateDriverDisplay(const char* title) = 0; 146 147 // the actual drawing implementations 148 virtual void DrawRectImp(const Region& rgn, const Color& color, bool fill, BlitFlags flags) = 0; 149 virtual void DrawPointImp(const Point&, const Color& color, BlitFlags flags) = 0; 150 virtual void DrawPointsImp(const std::vector<Point>& points, const Color& color, BlitFlags flags) = 0; 151 virtual void DrawCircleImp(const Point& origin, unsigned short r, const Color& color, BlitFlags flags) = 0; 152 virtual void DrawEllipseSegmentImp(const Point& origin, unsigned short xr, unsigned short yr, const Color& color, 153 double anglefrom, double angleto, bool drawlines, BlitFlags flags) = 0; 154 virtual void DrawEllipseImp(const Point& origin, unsigned short xr, unsigned short yr, const Color& color, BlitFlags flags) = 0; 155 virtual void DrawPolygonImp(const Gem_Polygon* poly, const Point& origin, const Color& color, bool fill, BlitFlags flags) = 0; 156 virtual void DrawLineImp(const Point& p1, const Point& p2, const Color& color, BlitFlags flags) = 0; 157 virtual void DrawLinesImp(const std::vector<Point>& points, const Color& color, BlitFlags flags)=0; 158 159 public: 160 Video(void); 161 ~Video(void) override; 162 163 virtual int Init(void) = 0; 164 165 int CreateDisplay(const Size&, int bpp, bool fullscreen, const char* title); 166 virtual void SetWindowTitle(const char *title) = 0; 167 168 /** Toggles GemRB between fullscreen and windowed mode. */ 169 bool ToggleFullscreenMode(); 170 virtual bool SetFullscreenMode(bool set) = 0; 171 bool GetFullscreenMode() const; 172 /** Swaps displayed and back buffers */ 173 int SwapBuffers(unsigned int fpscap = 30); 174 VideoBufferPtr CreateBuffer(const Region&, BufferFormat = BufferFormat::DISPLAY); 175 void PushDrawingBuffer(const VideoBufferPtr&); 176 void PopDrawingBuffer(); 177 void SetStencilBuffer(const VideoBufferPtr&); 178 /** Grabs and releases mouse cursor within GemRB window */ 179 virtual bool ToggleGrabInput() = 0; 180 virtual void CaptureMouse(bool enabled) = 0; GetScreenSize()181 const Size& GetScreenSize() { return screenSize; } 182 183 virtual void StartTextInput() = 0; 184 virtual void StopTextInput() = 0; 185 virtual bool InTextInput() = 0; 186 187 virtual bool TouchInputEnabled() = 0; 188 189 virtual Holder<Sprite2D> CreateSprite(const Region&, int bpp, ieDword rMask, 190 ieDword gMask, ieDword bMask, ieDword aMask, void* pixels, 191 bool cK = false, int index = 0) = 0; 192 virtual Holder<Sprite2D> CreateSprite8(const Region&, void* pixels, 193 PaletteHolder palette, bool cK = false, int index = 0) = 0; 194 virtual Holder<Sprite2D> CreatePalettedSprite(const Region&, int bpp, void* pixels, 195 Color* palette, bool cK = false, int index = 0) = 0; SupportsBAMSprites()196 virtual bool SupportsBAMSprites() { return false; } 197 198 void BlitSprite(const Holder<Sprite2D> spr, Point p, 199 const Region* clip = NULL); 200 201 virtual void BlitSprite(const Holder<Sprite2D> spr, const Region& src, Region dst, 202 BlitFlags flags, Color tint = Color()) = 0; 203 204 virtual void BlitGameSprite(const Holder<Sprite2D> spr, const Point& p, 205 BlitFlags flags, Color tint = Color()) = 0; 206 207 void BlitGameSpriteWithPalette(Holder<Sprite2D> spr, PaletteHolder pal, const Point& p, 208 BlitFlags flags, Color tint); 209 210 virtual void BlitVideoBuffer(const VideoBufferPtr& buf, const Point& p, BlitFlags flags, 211 const Color* tint = nullptr) = 0; 212 213 /** Return GemRB window screenshot. 214 * It's generated from the momentary back buffer */ 215 virtual Holder<Sprite2D> GetScreenshot(Region r, const VideoBufferPtr& buf = nullptr) = 0; 216 /** This function Draws the Border of a Rectangle as described by the Region parameter. The Color used to draw the rectangle is passes via the Color parameter. */ 217 void DrawRect(const Region& rgn, const Color& color, bool fill = true, BlitFlags flags = BlitFlags::NONE); 218 219 void DrawPoint(const Point&, const Color& color, BlitFlags flags = BlitFlags::NONE); 220 void DrawPoints(const std::vector<Point>& points, const Color& color, BlitFlags flags = BlitFlags::NONE); 221 222 /** Draws a circle */ 223 void DrawCircle(const Point& origin, unsigned short r, const Color& color, BlitFlags flags = BlitFlags::NONE); 224 /** Draws an Ellipse Segment */ 225 void DrawEllipseSegment(const Point& origin, unsigned short xr, unsigned short yr, const Color& color, 226 double anglefrom, double angleto, bool drawlines = true, BlitFlags flags = BlitFlags::NONE); 227 /** Draws an ellipse */ 228 void DrawEllipse(const Point& origin, unsigned short xr, unsigned short yr, const Color& color, BlitFlags flags = BlitFlags::NONE); 229 /** Draws a polygon on the screen */ 230 void DrawPolygon(const Gem_Polygon* poly, const Point& origin, const Color& color, bool fill = false, BlitFlags flags = BlitFlags::NONE); 231 /** Draws a line segment */ 232 void DrawLine(const Point& p1, const Point& p2, const Color& color, BlitFlags flags = BlitFlags::NONE); 233 void DrawLines(const std::vector<Point>& points, const Color& color, BlitFlags flags = BlitFlags::NONE); 234 /** Sets Event Manager */ 235 void SetEventMgr(EventMgr* evnt); 236 /** Flips sprite, returns new sprite */ 237 Holder<Sprite2D> MirrorSprite(const Holder<Sprite2D> sprite, BlitFlags flags, bool MirrorAnchor); 238 239 /** Sets Clip Rectangle */ 240 void SetScreenClip(const Region* clip); 241 /** Gets Clip Rectangle */ GetScreenClip()242 const Region& GetScreenClip() { return screenClip; } 243 virtual void SetGamma(int brightness, int contrast) = 0; 244 245 /** Scales down a sprite by a ratio */ 246 Holder<Sprite2D> SpriteScaleDown(const Holder<Sprite2D> sprite, unsigned int ratio); 247 /** Creates an ellipse or circle shaped sprite with various intensity 248 * for projectile light spots */ 249 Holder<Sprite2D> CreateLight(int radius, int intensity); 250 251 Color SpriteGetPixelSum(const Holder<Sprite2D> sprite, unsigned short xbase, unsigned short ybase, unsigned int ratio); 252 }; 253 254 } 255 256 #endif 257