diff options
author | Cameron Cawley | 2019-07-27 14:40:50 +0100 |
---|---|---|
committer | Filippos Karapetis | 2019-08-15 02:01:21 +0300 |
commit | 1feb86ee97eaaaf326918d4945cdaa0a2f61d33f (patch) | |
tree | ee051b4732b9d65bb57940af07e3d4cf91aba7f5 | |
parent | 0bf74e590d6da396ae10793191fad92f4424ae6d (diff) | |
download | scummvm-rg350-1feb86ee97eaaaf326918d4945cdaa0a2f61d33f.tar.gz scummvm-rg350-1feb86ee97eaaaf326918d4945cdaa0a2f61d33f.tar.bz2 scummvm-rg350-1feb86ee97eaaaf326918d4945cdaa0a2f61d33f.zip |
BACKENDS: Handle screen shaking in WindowedGraphicsManager
-rw-r--r-- | backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp | 8 | ||||
-rw-r--r-- | backends/graphics/gph/gph-graphics.cpp | 10 | ||||
-rw-r--r-- | backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp | 9 | ||||
-rw-r--r-- | backends/graphics/opengl/opengl-graphics.cpp | 19 | ||||
-rw-r--r-- | backends/graphics/opengl/opengl-graphics.h | 7 | ||||
-rw-r--r-- | backends/graphics/surfacesdl/surfacesdl-graphics.cpp | 20 | ||||
-rw-r--r-- | backends/graphics/surfacesdl/surfacesdl-graphics.h | 3 | ||||
-rw-r--r-- | backends/graphics/wincesdl/wincesdl-graphics.cpp | 11 | ||||
-rw-r--r-- | backends/graphics/windowed.h | 19 |
9 files changed, 55 insertions, 51 deletions
diff --git a/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp b/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp index 0b0d9a3a7a..a7dbed18c8 100644 --- a/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp +++ b/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp @@ -86,6 +86,8 @@ ScalerProc *DINGUXSdlGraphicsManager::getGraphicsScalerProc(int mode) const { void DINGUXSdlGraphicsManager::initSize(uint w, uint h, const Graphics::PixelFormat *format) { assert(_transactionMode == kTransactionActive); + _gameScreenShakeOffset = 0; + #ifdef USE_RGB_COLOR // Avoid redundant format changes Graphics::PixelFormat newFormat; @@ -216,16 +218,16 @@ void DINGUXSdlGraphicsManager::internUpdateScreen() { #endif // If the shake position changed, fill the dirty area with blackness - if (_currentShakePos != _newShakePos || + if (_currentShakePos != _gameScreenShakeOffset || (_cursorNeedsRedraw && _mouseBackup.y <= _currentShakePos)) { - SDL_Rect blackrect = {0, 0, (Uint16)(_videoMode.screenWidth * _videoMode.scaleFactor), (Uint16)(_newShakePos * _videoMode.scaleFactor)}; + SDL_Rect blackrect = {0, 0, (Uint16)(_videoMode.screenWidth * _videoMode.scaleFactor), (Uint16)(_gameScreenShakeOffset * _videoMode.scaleFactor)}; if (_videoMode.aspectRatioCorrection && !_overlayVisible) blackrect.h = real2Aspect(blackrect.h - 1) + 1; SDL_FillRect(_hwScreen, &blackrect, 0); - _currentShakePos = _newShakePos; + _currentShakePos = _gameScreenShakeOffset; _forceRedraw = true; } diff --git a/backends/graphics/gph/gph-graphics.cpp b/backends/graphics/gph/gph-graphics.cpp index a55a8869bb..cb3e09ac49 100644 --- a/backends/graphics/gph/gph-graphics.cpp +++ b/backends/graphics/gph/gph-graphics.cpp @@ -78,6 +78,8 @@ ScalerProc *GPHGraphicsManager::getGraphicsScalerProc(int mode) const { void GPHGraphicsManager::initSize(uint w, uint h, const Graphics::PixelFormat *format) { assert(_transactionMode == kTransactionActive); + _gameScreenShakeOffset = 0; + #ifdef USE_RGB_COLOR // Avoid redundant format changes Graphics::PixelFormat newFormat; @@ -216,16 +218,16 @@ void GPHGraphicsManager::internUpdateScreen() { #endif // If the shake position changed, fill the dirty area with blackness - if (_currentShakePos != _newShakePos || - (_cursorNeedsRedraw && _mouseBackup.y <= _currentShakePos)) { - SDL_Rect blackrect = {0, 0, _videoMode.screenWidth *_videoMode.scaleFactor, _newShakePos *_videoMode.scaleFactor}; + if (_currentShakePos != _gameScreenShakeOffset || + (_cursorNeedsRedraw && _mouseBackup.y <= _currentShakePos)) { + SDL_Rect blackrect = {0, 0, (Uint16)(_videoMode.screenWidth * _videoMode.scaleFactor), (Uint16)(_gameScreenShakeOffset * _videoMode.scaleFactor)}; if (_videoMode.aspectRatioCorrection && !_overlayVisible) blackrect.h = real2Aspect(blackrect.h - 1) + 1; SDL_FillRect(_hwScreen, &blackrect, 0); - _currentShakePos = _newShakePos; + _currentShakePos = _gameScreenShakeOffset; _forceRedraw = true; } diff --git a/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp b/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp index 45546c10e7..2105bd84d8 100644 --- a/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp +++ b/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp @@ -88,6 +88,8 @@ ScalerProc *LinuxmotoSdlGraphicsManager::getGraphicsScalerProc(int mode) const { void LinuxmotoSdlGraphicsManager::initSize(uint w, uint h, const Graphics::PixelFormat *format) { assert(_transactionMode == kTransactionActive); + _gameScreenShakeOffset = 0; + #ifdef USE_RGB_COLOR // Avoid redundant format changes Graphics::PixelFormat newFormat; @@ -247,15 +249,16 @@ void LinuxmotoSdlGraphicsManager::internUpdateScreen() { #endif // If the shake position changed, fill the dirty area with blackness - if (_currentShakePos != _newShakePos) { - SDL_Rect blackrect = {0, 0, _videoMode.screenWidth * _videoMode.scaleFactor, _newShakePos * _videoMode.scaleFactor}; + if (_currentShakePos != _gameScreenShakeOffset || + (_cursorNeedsRedraw && _mouseBackup.y <= _currentShakePos)) { + SDL_Rect blackrect = {0, 0, (Uint16)(_videoMode.screenWidth * _videoMode.scaleFactor), (Uint16)(_gameScreenShakeOffset * _videoMode.scaleFactor)}; if (_videoMode.aspectRatioCorrection && !_overlayVisible) blackrect.h = real2Aspect(blackrect.h - 1) + 1; SDL_FillRect(_hwscreen, &blackrect, 0); - _currentShakePos = _newShakePos; + _currentShakePos = _gameScreenShakeOffset; _forceFull = true; } diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp index 3ee374eaab..a6f31e64fb 100644 --- a/backends/graphics/opengl/opengl-graphics.cpp +++ b/backends/graphics/opengl/opengl-graphics.cpp @@ -56,7 +56,7 @@ OpenGLGraphicsManager::OpenGLGraphicsManager() : _currentState(), _oldState(), _transactionMode(kTransactionNone), _screenChangeID(1 << (sizeof(int) * 8 - 2)), _pipeline(nullptr), _stretchMode(STRETCH_FIT), _defaultFormat(), _defaultFormatAlpha(), - _gameScreen(nullptr), _gameScreenShakeOffset(0), _overlay(nullptr), + _gameScreen(nullptr), _overlay(nullptr), _cursor(nullptr), _cursorHotspotX(0), _cursorHotspotY(0), _cursorHotspotXScaled(0), _cursorHotspotYScaled(0), _cursorWidthScaled(0), _cursorHeightScaled(0), @@ -456,13 +456,6 @@ void OpenGLGraphicsManager::fillScreen(uint32 col) { _gameScreen->fill(col); } -void OpenGLGraphicsManager::setShakePos(int shakeOffset) { - if (_gameScreenShakeOffset != shakeOffset) { - _gameScreenShakeOffset = shakeOffset; - _forceRedraw = true; - } -} - void OpenGLGraphicsManager::updateScreen() { if (!_gameScreen) { return; @@ -508,13 +501,11 @@ void OpenGLGraphicsManager::updateScreen() { _backBuffer.enableScissorTest(true); } - const GLfloat shakeOffset = _gameScreenShakeOffset * (GLfloat)_gameDrawRect.height() / _gameScreen->getHeight(); - // Alpha blending is disabled when drawing the screen _backBuffer.enableBlend(Framebuffer::kBlendModeDisabled); // First step: Draw the (virtual) game screen. - g_context.getActivePipeline()->drawTexture(_gameScreen->getGLTexture(), _gameDrawRect.left, _gameDrawRect.top + shakeOffset, _gameDrawRect.width(), _gameDrawRect.height()); + g_context.getActivePipeline()->drawTexture(_gameScreen->getGLTexture(), _gameDrawRect.left, _gameDrawRect.top, _gameDrawRect.width(), _gameDrawRect.height()); // Second step: Draw the overlay if visible. if (_overlayVisible) { @@ -526,13 +517,9 @@ void OpenGLGraphicsManager::updateScreen() { if (_cursorVisible && _cursor) { _backBuffer.enableBlend(Framebuffer::kBlendModePremultipliedTransparency); - // Adjust game screen shake position, but only when the overlay is not - // visible. - const GLfloat cursorOffset = _overlayVisible ? 0 : shakeOffset; - g_context.getActivePipeline()->drawTexture(_cursor->getGLTexture(), _cursorX - _cursorHotspotXScaled, - _cursorY - _cursorHotspotYScaled + cursorOffset, + _cursorY - _cursorHotspotYScaled, _cursorWidthScaled, _cursorHeightScaled); } diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h index 0cf85ddfd6..f88315bf30 100644 --- a/backends/graphics/opengl/opengl-graphics.h +++ b/backends/graphics/opengl/opengl-graphics.h @@ -93,8 +93,6 @@ public: virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) override; virtual void fillScreen(uint32 col) override; - virtual void setShakePos(int shakeOffset) override; - virtual void updateScreen() override; virtual Graphics::Surface *lockScreen() override; @@ -333,11 +331,6 @@ protected: */ byte _gamePalette[3 * 256]; - /** - * The offset by which the screen is moved vertically. - */ - int _gameScreenShakeOffset; - // // Overlay // diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp index f71aa20865..bd430e8171 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp @@ -155,7 +155,7 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou _scalerProc(0), _screenChangeCount(0), _mouseData(nullptr), _mouseSurface(nullptr), _mouseOrigSurface(nullptr), _cursorDontScale(false), _cursorPaletteDisabled(true), - _currentShakePos(0), _newShakePos(0), + _currentShakePos(0), _paletteDirtyStart(0), _paletteDirtyEnd(0), _screenIsLocked(false), _graphicsMutex(0), @@ -825,7 +825,7 @@ int SurfaceSdlGraphicsManager::getStretchMode() const { void SurfaceSdlGraphicsManager::initSize(uint w, uint h, const Graphics::PixelFormat *format) { assert(_transactionMode == kTransactionActive); - _newShakePos = 0; + _gameScreenShakeOffset = 0; #ifdef USE_RGB_COLOR //avoid redundant format changes @@ -1205,20 +1205,24 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() { ScalerProc *scalerProc; int scale1; +#if !SDL_VERSION_ATLEAST(2, 0, 0) // If the shake position changed, fill the dirty area with blackness - if (_currentShakePos != _newShakePos || + // When building with SDL2, the shake offset is added to the active rect instead, + // so this isn't needed there. + if (_currentShakePos != _gameScreenShakeOffset || (_cursorNeedsRedraw && _mouseBackup.y <= _currentShakePos)) { - SDL_Rect blackrect = {0, 0, (Uint16)(_videoMode.screenWidth * _videoMode.scaleFactor), (Uint16)(_newShakePos * _videoMode.scaleFactor)}; + SDL_Rect blackrect = {0, 0, (Uint16)(_videoMode.screenWidth * _videoMode.scaleFactor), (Uint16)(_gameScreenShakeOffset * _videoMode.scaleFactor)}; if (_videoMode.aspectRatioCorrection && !_overlayVisible) blackrect.h = real2Aspect(blackrect.h - 1) + 1; SDL_FillRect(_hwScreen, &blackrect, 0); - _currentShakePos = _newShakePos; + _currentShakePos = _gameScreenShakeOffset; _forceRedraw = true; } +#endif // Check whether the palette was changed in the meantime and update the // screen surface accordingly. @@ -1754,12 +1758,6 @@ void SurfaceSdlGraphicsManager::setCursorPalette(const byte *colors, uint start, blitCursor(); } -void SurfaceSdlGraphicsManager::setShakePos(int shake_pos) { - assert(_transactionMode == kTransactionNone); - - _newShakePos = shake_pos; -} - void SurfaceSdlGraphicsManager::setFocusRectangle(const Common::Rect &rect) { #ifdef USE_SDL_DEBUG_FOCUSRECT // Only enable focus rectangle debug code, when the user wants it diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h index 10054605a7..3bf0dd516f 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.h +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h @@ -126,7 +126,6 @@ public: virtual void unlockScreen() override; virtual void fillScreen(uint32 col) override; virtual void updateScreen() override; - virtual void setShakePos(int shakeOffset) override; virtual void setFocusRectangle(const Common::Rect& rect) override; virtual void clearFocusRectangle() override; @@ -348,8 +347,8 @@ protected: }; // Shake mode + // This is always set to 0 when building with SDL2. int _currentShakePos; - int _newShakePos; // Palette data SDL_Color *_currentPalette; diff --git a/backends/graphics/wincesdl/wincesdl-graphics.cpp b/backends/graphics/wincesdl/wincesdl-graphics.cpp index 80792d439c..9bfcd64079 100644 --- a/backends/graphics/wincesdl/wincesdl-graphics.cpp +++ b/backends/graphics/wincesdl/wincesdl-graphics.cpp @@ -498,12 +498,17 @@ void WINCESdlGraphicsManager::internUpdateScreen() { } // If the shake position changed, fill the dirty area with blackness - if (_currentShakePos != _newShakePos) { - SDL_Rect blackrect = {0, 0, _videoMode.screenWidth *_scaleFactorXm / _scaleFactorXd, _newShakePos *_scaleFactorYm / _scaleFactorYd}; + if (_currentShakePos != _gameScreenShakeOffset || + (_cursorNeedsRedraw && _mouseBackup.y <= _currentShakePos)) { + SDL_Rect blackrect = {0, 0, (Uint16)(_videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd), (Uint16)(_gameScreenShakeOffset * _scaleFactorYm / _scaleFactorYd)}; + if (_videoMode.aspectRatioCorrection) blackrect.h = real2Aspect(blackrect.h - 1) + 1; + SDL_FillRect(_hwScreen, &blackrect, 0); - _currentShakePos = _newShakePos; + + _currentShakePos = _gameScreenShakeOffset; + _forceRedraw = true; } diff --git a/backends/graphics/windowed.h b/backends/graphics/windowed.h index 66b1476d22..74933a1727 100644 --- a/backends/graphics/windowed.h +++ b/backends/graphics/windowed.h @@ -44,6 +44,7 @@ public: _windowWidth(0), _windowHeight(0), _overlayVisible(false), + _gameScreenShakeOffset(0), _forceRedraw(false), _cursorVisible(false), _cursorX(0), @@ -73,6 +74,14 @@ public: _forceRedraw = true; } + virtual void setShakePos(int shakeOffset) override { + if (_gameScreenShakeOffset != shakeOffset) { + _gameScreenShakeOffset = shakeOffset; + recalculateDisplayAreas(); + _cursorNeedsRedraw = true; + } + } + protected: /** * @returns whether or not the game screen must have aspect ratio correction @@ -195,6 +204,7 @@ protected: _activeArea.height = getHeight(); } } + /** * Sets the position of the hardware mouse cursor in the host system, * relative to the window. @@ -272,6 +282,11 @@ protected: bool _overlayVisible; /** + * The offset by which the screen is moved vertically. + */ + int _gameScreenShakeOffset; + + /** * The scaled draw rectangle for the game surface within the window. */ Common::Rect _gameDrawRect; @@ -375,8 +390,8 @@ private: } } - drawRect.left = (_windowWidth - width) / 2; - drawRect.top = (_windowHeight - height) / 2; + drawRect.left = ((_windowWidth - width) / 2); + drawRect.top = ((_windowHeight - height) / 2) + _gameScreenShakeOffset; drawRect.setWidth(width); drawRect.setHeight(height); } |