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
42enum {
43 GFX_SURFACESDL = 0
44};
45
46
51public:
52 SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
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
87protected:
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#if SDL_VERSION_ATLEAST(3, 0, 0)
99 Graphics::PixelFormat convertSDLPixelFormat(SDL_PixelFormat in) const;
100#else
102#endif
103public:
104 void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) override;
105 Graphics::Surface *lockScreen() override;
106 void unlockScreen() override;
107 void fillScreen(uint32 col) override;
108 void fillScreen(const Common::Rect &r, uint32 col) override;
109 void updateScreen() override;
110 void setFocusRectangle(const Common::Rect& rect) override;
111 void clearFocusRectangle() override;
112
113 Graphics::PixelFormat getOverlayFormat() const override { return _overlayFormat; }
114 void clearOverlay() override;
115 void grabOverlay(Graphics::Surface &surface) const override;
116 void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override;
117 int16 getOverlayHeight() const override { return _videoMode.overlayHeight; }
118 int16 getOverlayWidth() const override { return _videoMode.overlayWidth; }
119
120 void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, const Graphics::PixelFormat *format, const byte *mask, frac_t scaleX, frac_t scaleY) override;
121 void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, const Graphics::PixelFormat *format, const byte *mask, frac_t scaleX, frac_t scaleY, bool disableKeyColor);
122 void setCursorPalette(const byte *colors, uint start, uint num) override;
123
124#ifdef USE_OSD
125 void displayMessageOnOSD(const Common::U32String &msg) override;
126 void displayActivityIconOnOSD(const Graphics::Surface *icon) override;
127#endif
128
129 // Override from Common::EventObserver
130 bool notifyEvent(const Common::Event &event) override;
131
132 // SdlGraphicsManager interface
133 void notifyVideoExpose() override;
134 void notifyResize(const int width, const int height) override;
135
136#if defined(USE_IMGUI) && (defined(USE_IMGUI_SDLRENDERER2) || defined(USE_IMGUI_SDLRENDERER3))
137 void *getImGuiTexture(const Graphics::Surface &image, const byte *palette, int palCount) override;
138 void freeImGuiTexture(void *texture) override;
139#endif
140
141protected:
142#ifdef USE_OSD
144 SDL_Surface *_osdMessageSurface;
146 uint8 _osdMessageAlpha;
148 uint32 _osdMessageFadeStartTime;
150 enum {
151 kOSDFadeOutDelay = 2 * 1000,
152 kOSDFadeOutDuration = 500,
153 kOSDInitialAlpha = 80
154 };
156 SDL_Rect getOSDMessageRect() const;
158 void removeOSDMessage();
160 SDL_Surface *_osdIconSurface;
162 SDL_Rect getOSDIconRect() const;
163
164 void updateOSD();
165 void drawOSD();
166#endif
167
169 int _kw, _kh;
170 public:
171 AspectRatio() { _kw = _kh = 0; }
172 AspectRatio(int w, int h);
173
174 bool isAuto() const { return (_kw | _kh) == 0; }
175
176 int kw() const { return _kw; }
177 int kh() const { return _kh; }
178 };
179
180 static AspectRatio getDesiredAspectRatio();
181
182 bool gameNeedsAspectRatioCorrection() const override {
183 return _videoMode.aspectRatioCorrection;
184 }
185 int getGameRenderScale() const override {
186 return _videoMode.scaleFactor;
187 }
188
189 void handleResizeImpl(const int width, const int height) override;
190
191 virtual void setupHardwareSize();
192
193 void fixupResolutionForAspectRatio(AspectRatio desiredAspectRatio, int &width, int &height) const;
194
195#if SDL_VERSION_ATLEAST(2, 0, 0)
196 /* SDL2 features a different API for 2D graphics. We create a wrapper
197 * around this API to keep the code paths as close as possible. */
198 SDL_Renderer *_renderer;
199 SDL_Texture *_screenTexture;
200 void deinitializeRenderer();
201 void recreateScreenTexture();
202
203 virtual SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
204 virtual void SDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects);
205 int SDL_SetColors(SDL_Surface *surface, SDL_Color *colors, int firstcolor, int ncolors);
206#endif
207
209 SDL_Surface *_screen;
210 Graphics::PixelFormat _screenFormat;
211 Graphics::PixelFormat _cursorFormat;
212#ifdef USE_RGB_COLOR
213 Common::List<Graphics::PixelFormat> _supportedFormats;
214
219 void detectSupportedFormats();
220#endif
221
223 SDL_Surface *_tmpscreen;
225 SDL_Surface *_tmpscreen2;
226
227 SDL_Surface *_overlayscreen;
228 bool _useOldSrc;
229 Graphics::PixelFormat _overlayFormat;
230 bool _isDoubleBuf, _isHwPalette;
231
232 enum {
233 kTransactionNone = 0,
234 kTransactionActive = 1,
235 kTransactionRollback = 2
236 };
237
239 bool sizeChanged;
240 bool needHotswap;
241 bool needUpdatescreen;
242#if SDL_VERSION_ATLEAST(2, 0, 0)
243 bool needTextureUpdate;
244 bool needDisplayResize;
245#endif
246 bool formatChanged;
247
249 sizeChanged = false;
250 needHotswap = false;
251 needUpdatescreen = false;
252
253#if SDL_VERSION_ATLEAST(2, 0, 0)
254 needTextureUpdate = false;
255 needDisplayResize = false;
256#endif
257 formatChanged = false;
258 }
259 };
260 TransactionDetails _transactionDetails;
261
262 struct VideoState {
263 bool setup;
264
265 bool fullscreen;
266 bool aspectRatioCorrection;
267 AspectRatio desiredAspectRatio;
268 bool filtering;
269
270 int mode;
271#if SDL_VERSION_ATLEAST(2, 0, 0)
272 int stretchMode;
273#endif
274 bool vsync;
275
276 uint scalerIndex;
277 int scaleFactor;
278
279 int screenWidth, screenHeight;
280 int overlayWidth, overlayHeight;
281 int hardwareWidth, hardwareHeight;
283
284 VideoState() {
285 setup = false;
286 fullscreen = false;
287 aspectRatioCorrection = false;
288 // desiredAspectRatio set to (0, 0) by AspectRatio constructor
289 filtering = false;
290
291 mode = GFX_SURFACESDL;
292#if SDL_VERSION_ATLEAST(2, 0, 0)
293 stretchMode = 0;
294#endif
295 vsync = false;
296
297 scalerIndex = 0;
298 scaleFactor = 0;
299
300 screenWidth = 0;
301 screenHeight = 0;
302 overlayWidth = 0;
303 overlayHeight = 0;
304 hardwareWidth = 0;
305 hardwareHeight = 0;
306 // format set to 0 values by Graphics::PixelFormat constructor
307 }
308 };
309 VideoState _videoMode, _oldVideoMode;
310
311#if defined(WIN32) && !SDL_VERSION_ATLEAST(2, 0, 0)
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 uint32 _mouseKeyColor;
383 bool _disableMouseKeyColor;
384 byte _mappedMouseKeyColor;
385 frac_t _cursorScaleX;
386 frac_t _cursorScaleY;
387 bool _cursorPaletteDisabled;
388 SDL_Surface *_mouseOrigSurface;
389 SDL_Surface *_mouseSurface;
390
391 // Shake mode
392 // This is always set to 0 when building with SDL2.
393 int _currentShakeXOffset;
394 int _currentShakeYOffset;
395
396 // Palette data
397 SDL_Color *_currentPalette;
398 uint _paletteDirtyStart, _paletteDirtyEnd;
399
400 SDL_Color *_overlayPalette;
401 bool _isInOverlayPalette;
402
403 // Cursor palette data
404 SDL_Color *_cursorPalette;
405
411
412#ifdef USE_SDL_DEBUG_FOCUSRECT
413 bool _enableFocusRectDebugCode;
414 bool _enableFocusRect;
415 Common::Rect _focusRect;
416#endif
417
418 virtual void addDirtyRect(int x, int y, int w, int h, bool inOverlay, bool realCoordinates = false);
419
420 virtual void drawMouse();
421 virtual void undrawMouse();
422 virtual void blitCursor();
423
424 virtual void internUpdateScreen();
425 virtual void updateScreen(SDL_Rect *dirtyRectList, int actualDirtyRects);
426
427 virtual bool loadGFXMode();
428 virtual void unloadGFXMode();
429 virtual bool hotswapGFXMode();
430
431 virtual void setAspectRatioCorrection(bool enable);
432 void setFilteringMode(bool enable);
433 void setVSync(bool enable);
434
435 bool saveScreenshot(const Common::Path &filename) const override;
436 virtual void setGraphicsModeIntern();
437 virtual void getDefaultResolution(uint &w, uint &h);
438
439 // In SurfaceSDL mode we never render in 3D and can always switch the fullscreen state
440 bool canSwitchFullscreen() const override { return true; }
441
442private:
443 void setFullscreenMode(bool enable);
444 void handleScalerHotkeys(uint mode, int factor);
445
450 Common::Point convertOverlayToGame(const int x, const int y) const {
451 if (getOverlayWidth() == 0 || getOverlayHeight() == 0) {
452 error("convertOverlayToGame called without a valid overlay");
453 }
454
455 return Common::Point(x * getWidth() / getOverlayWidth(),
456 y * getHeight() / getOverlayHeight());
457 }
458
463 Common::Point convertGameToOverlay(const int x, const int y) const {
464 if (getWidth() == 0 || getHeight() == 0) {
465 error("convertGameToOverlay called without a valid overlay");
466 }
467
468 return Common::Point(x * getOverlayWidth() / getWidth(),
469 y * getOverlayHeight() / getHeight());
470 }
471
478 bool _needRestoreAfterOverlay;
479 bool _prevForceRedraw;
480 bool _prevCursorNeedsRedraw;
481};
482
483#endif
Definition: list.h:44
Definition: mutex.h:67
Definition: path.h:52
Definition: ustr.h:57
Definition: scalerplugin.h:28
Definition: scalerplugin.h:150
Definition: sdl-events.h:40
Definition: sdl-graphics.h:38
Definition: sdl-window.h:30
Definition: surfacesdl-graphics.h:168
Definition: surfacesdl-graphics.h:50
bool gameNeedsAspectRatioCorrection() const override
Definition: surfacesdl-graphics.h:182
bool canSwitchFullscreen() const override
Definition: surfacesdl-graphics.h:440
void notifyResize(const int width, const int height) override
SDL_Surface * _tmpscreen2
Definition: surfacesdl-graphics.h:225
void notifyVideoExpose() override
void grabPalette(byte *colors, uint start, uint num) const override
bool notifyEvent(const Common::Event &event) override
Graphics::PixelFormat convertSDLPixelFormat(SDL_PixelFormat *in) const
int getGameRenderScale() const override
Definition: surfacesdl-graphics.h:185
Common::Mutex _graphicsMutex
Definition: surfacesdl-graphics.h:410
void handleResizeImpl(const int width, const int height) override
SDL_Surface * _screen
Definition: surfacesdl-graphics.h:209
SDL_Surface * _tmpscreen
Definition: surfacesdl-graphics.h:223
void setPalette(const byte *colors, uint start, uint num) override
int32 frac_t
Definition: frac.h:52
Feature
Definition: system.h:415
TransactionError
Definition: system.h:1188
@ kGfxModeNoFlags
Definition: system.h:790
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: events.h:218
Definition: rect.h:144
Definition: rect.h:536
Definition: pixelformat.h:138
Definition: surface.h:67
Definition: system.h:741
Definition: surfacesdl-graphics.h:359
Definition: surfacesdl-graphics.h:238
Definition: surfacesdl-graphics.h:262