ScummVM API documentation
surfacesdl-graphics.h
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 modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (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, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef BACKENDS_GRAPHICS_SURFACESDL_GRAPHICS_H
23 #define BACKENDS_GRAPHICS_SURFACESDL_GRAPHICS_H
24 
25 #include "backends/graphics/graphics.h"
26 #include "backends/graphics/sdl/sdl-graphics.h"
27 #include "graphics/pixelformat.h"
28 #include "graphics/scaler.h"
29 #include "graphics/scalerplugin.h"
30 #include "common/events.h"
31 #include "common/mutex.h"
32 
33 #include "backends/events/sdl/sdl-events.h"
34 
35 #include "backends/platform/sdl/sdl-sys.h"
36 
37 #ifndef RELEASE_BUILD
38 // Define this to allow for focus rectangle debugging
39 #define USE_SDL_DEBUG_FOCUSRECT
40 #endif
41 
42 enum {
43  GFX_SURFACESDL = 0
44 };
45 
46 
51 public:
52  SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
53  virtual ~SurfaceSdlGraphicsManager();
54 
55  bool hasFeature(OSystem::Feature f) const override;
56  void setFeatureState(OSystem::Feature f, bool enable) override;
57  bool getFeatureState(OSystem::Feature f) const override;
58 
59  const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
60  int getDefaultGraphicsMode() const override;
61  bool setGraphicsMode(int mode, uint flags = OSystem::kGfxModeNoFlags) override;
62  int getGraphicsMode() const override;
63  uint getDefaultScaler() const override;
64  uint getDefaultScaleFactor() const override;
65  bool setScaler(uint mode, int factor) override;
66  uint getScaler() const override;
67  uint getScaleFactor() const override;
68 #ifdef USE_RGB_COLOR
69  Graphics::PixelFormat getScreenFormat() const override { return _screenFormat; }
70  Common::List<Graphics::PixelFormat> getSupportedFormats() const override;
71 #endif
72 #if SDL_VERSION_ATLEAST(2, 0, 0)
73  const OSystem::GraphicsMode *getSupportedStretchModes() const override;
74  int getDefaultStretchMode() const override;
75  bool setStretchMode(int mode) override;
76  int getStretchMode() const override;
77 #endif
78  void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL) override;
79  int getScreenChangeID() const override { return _screenChangeCount; }
80 
81  void beginGFXTransaction() override;
82  OSystem::TransactionError endGFXTransaction() override;
83 
84  int16 getHeight() const override;
85  int16 getWidth() const override;
86 
87 protected:
88  // PaletteManager API
89  void setPalette(const byte *colors, uint start, uint num) override;
90  void grabPalette(byte *colors, uint start, uint num) const override;
91  virtual void initGraphicsSurface();
92 
98  Graphics::PixelFormat convertSDLPixelFormat(SDL_PixelFormat *in) const;
99 public:
100  void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) override;
101  Graphics::Surface *lockScreen() override;
102  void unlockScreen() override;
103  void fillScreen(uint32 col) override;
104  void fillScreen(const Common::Rect &r, uint32 col) override;
105  void updateScreen() override;
106  void setFocusRectangle(const Common::Rect& rect) override;
107  void clearFocusRectangle() override;
108 
109  Graphics::PixelFormat getOverlayFormat() const override { return _overlayFormat; }
110  void clearOverlay() override;
111  void grabOverlay(Graphics::Surface &surface) const override;
112  void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override;
113  int16 getOverlayHeight() const override { return _videoMode.overlayHeight; }
114  int16 getOverlayWidth() const override { return _videoMode.overlayWidth; }
115 
116  void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL, const byte *mask = NULL) override;
117  void setCursorPalette(const byte *colors, uint start, uint num) override;
118 
119 #ifdef USE_OSD
120  void displayMessageOnOSD(const Common::U32String &msg) override;
121  void displayActivityIconOnOSD(const Graphics::Surface *icon) override;
122 #endif
123 
124  // Override from Common::EventObserver
125  bool notifyEvent(const Common::Event &event) override;
126 
127  // SdlGraphicsManager interface
128  void notifyVideoExpose() override;
129  void notifyResize(const int width, const int height) override;
130 
131 protected:
132 #ifdef USE_OSD
133 
134  SDL_Surface *_osdMessageSurface;
136  uint8 _osdMessageAlpha;
138  uint32 _osdMessageFadeStartTime;
140  enum {
141  kOSDFadeOutDelay = 2 * 1000,
142  kOSDFadeOutDuration = 500,
143  kOSDInitialAlpha = 80
144  };
146  SDL_Rect getOSDMessageRect() const;
148  void removeOSDMessage();
150  SDL_Surface *_osdIconSurface;
152  SDL_Rect getOSDIconRect() const;
153 
154  void updateOSD();
155  void drawOSD();
156 #endif
157 
158  class AspectRatio {
159  int _kw, _kh;
160  public:
161  AspectRatio() { _kw = _kh = 0; }
162  AspectRatio(int w, int h);
163 
164  bool isAuto() const { return (_kw | _kh) == 0; }
165 
166  int kw() const { return _kw; }
167  int kh() const { return _kh; }
168  };
169 
170  static AspectRatio getDesiredAspectRatio();
171 
172  bool gameNeedsAspectRatioCorrection() const override {
173  return _videoMode.aspectRatioCorrection;
174  }
175  int getGameRenderScale() const override {
176  return _videoMode.scaleFactor;
177  }
178 
179  void handleResizeImpl(const int width, const int height) override;
180 
181  virtual void setupHardwareSize();
182 
183  void fixupResolutionForAspectRatio(AspectRatio desiredAspectRatio, int &width, int &height) const;
184 
185 #if SDL_VERSION_ATLEAST(2, 0, 0)
186  /* SDL2 features a different API for 2D graphics. We create a wrapper
187  * around this API to keep the code paths as close as possible. */
188  SDL_Renderer *_renderer;
189  SDL_Texture *_screenTexture;
190  void deinitializeRenderer();
191  void recreateScreenTexture();
192 
193  virtual SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
194  virtual void SDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects);
195  int SDL_SetColors(SDL_Surface *surface, SDL_Color *colors, int firstcolor, int ncolors);
196  int SDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha);
197  int SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key);
198 #endif
199 
201  SDL_Surface *_screen;
202  Graphics::PixelFormat _screenFormat;
203  Graphics::PixelFormat _cursorFormat;
204 #ifdef USE_RGB_COLOR
205  Common::List<Graphics::PixelFormat> _supportedFormats;
206 
211  void detectSupportedFormats();
212 #endif
213 
215  SDL_Surface *_tmpscreen;
217  SDL_Surface *_tmpscreen2;
218 
219  SDL_Surface *_overlayscreen;
220  bool _useOldSrc;
221  Graphics::PixelFormat _overlayFormat;
222  bool _isDoubleBuf, _isHwPalette;
223 
224  enum {
225  kTransactionNone = 0,
226  kTransactionActive = 1,
227  kTransactionRollback = 2
228  };
229 
231  bool sizeChanged;
232  bool needHotswap;
233  bool needUpdatescreen;
234 #if SDL_VERSION_ATLEAST(2, 0, 0)
235  bool needTextureUpdate;
236  bool needDisplayResize;
237 #endif
238 #ifdef USE_RGB_COLOR
239  bool formatChanged;
240 #endif
241 
243  sizeChanged = false;
244  needHotswap = false;
245  needUpdatescreen = false;
246 
247 #if SDL_VERSION_ATLEAST(2, 0, 0)
248  needTextureUpdate = false;
249  needDisplayResize = false;
250 #endif
251 #ifdef USE_RGB_COLOR
252  formatChanged = false;
253 #endif
254  }
255  };
256  TransactionDetails _transactionDetails;
257 
258  struct VideoState {
259  bool setup;
260 
261  bool fullscreen;
262  bool aspectRatioCorrection;
263  AspectRatio desiredAspectRatio;
264  bool filtering;
265 
266  int mode;
267 #if SDL_VERSION_ATLEAST(2, 0, 0)
268  int stretchMode;
269 #endif
270  bool vsync;
271 
272  uint scalerIndex;
273  int scaleFactor;
274 
275  int screenWidth, screenHeight;
276  int overlayWidth, overlayHeight;
277  int hardwareWidth, hardwareHeight;
278 #ifdef USE_RGB_COLOR
279  Graphics::PixelFormat format;
280 #endif
281 
282  VideoState() {
283  setup = false;
284  fullscreen = false;
285  aspectRatioCorrection = false;
286  // desiredAspectRatio set to (0, 0) by AspectRatio constructor
287  filtering = false;
288 
289  mode = GFX_SURFACESDL;
290 #if SDL_VERSION_ATLEAST(2, 0, 0)
291  stretchMode = 0;
292 #endif
293  vsync = false;
294 
295  scalerIndex = 0;
296  scaleFactor = 0;
297 
298  screenWidth = 0;
299  screenHeight = 0;
300  overlayWidth = 0;
301  overlayHeight = 0;
302  hardwareWidth = 0;
303  hardwareHeight = 0;
304 #ifdef USE_RGB_COLOR
305  // format set to 0 values by Graphics::PixelFormat constructor
306 #endif
307  }
308  };
309  VideoState _videoMode, _oldVideoMode;
310 
311 #if defined(WIN32) && !SDL_VERSION_ATLEAST(2, 0, 0)
312 
325  uint8 _originalBitsPerPixel;
326 #endif
327 
328  int _transactionMode;
329 
330  // Indicates whether it is needed to free _hwSurface in destructor
331  bool _displayDisabled;
332 
333  const PluginList &_scalerPlugins;
334  ScalerPluginObject *_scalerPlugin;
335  Scaler *_scaler, *_mouseScaler;
336  uint _maxExtraPixels;
337  uint _extraPixels;
338 
339  bool _screenIsLocked;
340  Graphics::Surface _framebuffer;
341 
342  int _screenChangeCount;
343 
344  enum {
345  NUM_DIRTY_RECT = 100,
346  MAX_SCALING = 3
347  };
348 
349  // Dirty rect management
350  // When double-buffering we need to redraw both updates from
351  // current frame and previous frame. For convenience we copy
352  // them here before traversing the list.
353  SDL_Rect _dirtyRectList[2 * NUM_DIRTY_RECT];
354  int _numDirtyRects;
355 
356  SDL_Rect _prevDirtyRectList[NUM_DIRTY_RECT];
357  int _numPrevDirtyRects;
358 
359  struct MousePos {
360  // The size and hotspot of the original cursor image.
361  int16 w, h;
362  int16 hotX, hotY;
363 
364  // The size and hotspot of the pre-scaled cursor image, in real
365  // coordinates.
366  int16 rW, rH;
367  int16 rHotX, rHotY;
368 
369  // The size and hotspot of the pre-scaled cursor image, in game
370  // coordinates.
371  int16 vW, vH;
372  int16 vHotX, vHotY;
373 
374  MousePos() : w(0), h(0), hotX(0), hotY(0),
375  rW(0), rH(0), rHotX(0), rHotY(0), vW(0), vH(0),
376  vHotX(0), vHotY(0)
377  { }
378  };
379 
380  SDL_Rect _mouseLastRect, _mouseNextRect;
381  MousePos _mouseCurState;
382 #ifdef USE_RGB_COLOR
383  uint32 _mouseKeyColor;
384 #else
385  byte _mouseKeyColor;
386 #endif
387  byte _mappedMouseKeyColor;
388  bool _cursorDontScale;
389  bool _cursorPaletteDisabled;
390  SDL_Surface *_mouseOrigSurface;
391  SDL_Surface *_mouseSurface;
392 
393  // Shake mode
394  // This is always set to 0 when building with SDL2.
395  int _currentShakeXOffset;
396  int _currentShakeYOffset;
397 
398  // Palette data
399  SDL_Color *_currentPalette;
400  uint _paletteDirtyStart, _paletteDirtyEnd;
401 
402  SDL_Color *_overlayPalette;
403  bool _isInOverlayPalette;
404 
405  // Cursor palette data
406  SDL_Color *_cursorPalette;
407 
413 
414 #ifdef USE_SDL_DEBUG_FOCUSRECT
415  bool _enableFocusRectDebugCode;
416  bool _enableFocusRect;
417  Common::Rect _focusRect;
418 #endif
419 
420  virtual void addDirtyRect(int x, int y, int w, int h, bool inOverlay, bool realCoordinates = false);
421 
422  virtual void drawMouse();
423  virtual void undrawMouse();
424  virtual void blitCursor();
425 
426  virtual void internUpdateScreen();
427  virtual void updateScreen(SDL_Rect *dirtyRectList, int actualDirtyRects);
428 
429  virtual bool loadGFXMode();
430  virtual void unloadGFXMode();
431  virtual bool hotswapGFXMode();
432 
433  virtual void setAspectRatioCorrection(bool enable);
434  void setFilteringMode(bool enable);
435  void setVSync(bool enable);
436 
437  bool saveScreenshot(const Common::Path &filename) const override;
438  virtual void setGraphicsModeIntern();
439  virtual void getDefaultResolution(uint &w, uint &h);
440 
441 private:
442  void setFullscreenMode(bool enable);
443  void handleScalerHotkeys(uint mode, int factor);
444 
449  Common::Point convertOverlayToGame(const int x, const int y) const {
450  if (getOverlayWidth() == 0 || getOverlayHeight() == 0) {
451  error("convertOverlayToGame called without a valid overlay");
452  }
453 
454  return Common::Point(x * getWidth() / getOverlayWidth(),
455  y * getHeight() / getOverlayHeight());
456  }
457 
462  Common::Point convertGameToOverlay(const int x, const int y) const {
463  if (getWidth() == 0 || getHeight() == 0) {
464  error("convertGameToOverlay called without a valid overlay");
465  }
466 
467  return Common::Point(x * getOverlayWidth() / getWidth(),
468  y * getOverlayHeight() / getHeight());
469  }
470 
477  bool _needRestoreAfterOverlay;
478  bool _prevForceRedraw;
479  bool _prevCursorNeedsRedraw;
480 };
481 
482 #endif
Definition: surfacesdl-graphics.h:359
bool notifyEvent(const Common::Event &event) override
int getGameRenderScale() const override
Definition: surfacesdl-graphics.h:175
Definition: surfacesdl-graphics.h:258
Definition: surface.h:66
Definition: system.h:788
Definition: sdl-events.h:40
Definition: sdl-graphics.h:38
void handleResizeImpl(const int width, const int height) override
Definition: array.h:52
Definition: pixelformat.h:138
Definition: system.h:739
Feature
Definition: system.h:417
Definition: list.h:44
Definition: rect.h:144
Definition: path.h:52
void notifyVideoExpose() override
void notifyResize(const int width, const int height) override
Common::Mutex _graphicsMutex
Definition: surfacesdl-graphics.h:412
bool gameNeedsAspectRatioCorrection() const override
Definition: surfacesdl-graphics.h:172
Definition: ustr.h:57
TransactionError
Definition: system.h:1148
Definition: scalerplugin.h:150
Definition: events.h:198
Definition: mutex.h:67
Definition: rect.h:45
SDL_Surface * _screen
Definition: surfacesdl-graphics.h:201
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: surfacesdl-graphics.h:230
SDL_Surface * _tmpscreen
Definition: surfacesdl-graphics.h:215
Definition: surfacesdl-graphics.h:158
Definition: surfacesdl-graphics.h:50
void grabPalette(byte *colors, uint start, uint num) const override
SDL_Surface * _tmpscreen2
Definition: surfacesdl-graphics.h:217
void setPalette(const byte *colors, uint start, uint num) override
Definition: scalerplugin.h:28
Graphics::PixelFormat convertSDLPixelFormat(SDL_PixelFormat *in) const
Definition: sdl-window.h:30