diff options
author | sluicebox | 2019-11-16 23:41:07 -0800 |
---|---|---|
committer | Eugene Sandulenko | 2019-11-19 00:20:40 +0100 |
commit | 8057cfa38f247c8a46bf563da706b541837e5ded (patch) | |
tree | dea1dc34c07e909070fc03079cf4331656909d57 /backends | |
parent | 40415a5c4a3dc78c495a89589e4590b71c0dbe77 (diff) | |
download | scummvm-rg350-8057cfa38f247c8a46bf563da706b541837e5ded.tar.gz scummvm-rg350-8057cfa38f247c8a46bf563da706b541837e5ded.tar.bz2 scummvm-rg350-8057cfa38f247c8a46bf563da706b541837e5ded.zip |
SDL: Implement horizontal shake
Diffstat (limited to 'backends')
-rw-r--r-- | backends/graphics/surfacesdl/surfacesdl-graphics.cpp | 49 | ||||
-rw-r--r-- | backends/graphics/windowed.h | 2 |
2 files changed, 39 insertions, 12 deletions
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp index 95c7ddc918..c43dee78ef 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp @@ -1207,6 +1207,19 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() { // If the shake position changed, fill the dirty area with blackness // When building with SDL2, the shake offset is added to the active rect instead, // so this isn't needed there. + if (_currentShakeXOffset != _gameScreenShakeXOffset || + (_cursorNeedsRedraw && _mouseBackup.x <= _currentShakeXOffset)) { + SDL_Rect blackrect = {0, 0, (Uint16)(_gameScreenShakeXOffset * _videoMode.scaleFactor), (Uint16)(_videoMode.screenHeight * _videoMode.scaleFactor)}; + + if (_videoMode.aspectRatioCorrection && !_overlayVisible) + blackrect.h = real2Aspect(blackrect.h - 1) + 1; + + SDL_FillRect(_hwScreen, &blackrect, 0); + + _currentShakeXOffset = _gameScreenShakeXOffset; + + _forceRedraw = true; + } if (_currentShakeYOffset != _gameScreenShakeYOffset || (_cursorNeedsRedraw && _mouseBackup.y <= _currentShakeYOffset)) { SDL_Rect blackrect = {0, 0, (Uint16)(_videoMode.screenWidth * _videoMode.scaleFactor), (Uint16)(_gameScreenShakeYOffset * _videoMode.scaleFactor)}; @@ -1294,14 +1307,19 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() { dstPitch = _hwScreen->pitch; for (r = _dirtyRectList; r != lastRect; ++r) { + int dst_x = r->x + _currentShakeXOffset; int dst_y = r->y + _currentShakeYOffset; + int dst_w = 0; int dst_h = 0; #ifdef USE_SCALERS int orig_dst_y = 0; #endif - int rx1 = r->x * scale1; - if (dst_y < height) { + if (dst_x < width && dst_y < height) { + dst_w = r->w; + if (dst_w > width - dst_x) + dst_w = width - dst_x; + dst_h = r->h; if (dst_h > height - dst_y) dst_h = height - dst_y; @@ -1309,19 +1327,20 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() { #ifdef USE_SCALERS orig_dst_y = dst_y; #endif - dst_y = dst_y * scale1; + dst_x *= scale1; + dst_y *= scale1; if (_videoMode.aspectRatioCorrection && !_overlayVisible) dst_y = real2Aspect(dst_y); assert(scalerProc != NULL); scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch, - (byte *)_hwScreen->pixels + rx1 * 2 + dst_y * dstPitch, dstPitch, r->w, dst_h); + (byte *)_hwScreen->pixels + dst_x * 2 + dst_y * dstPitch, dstPitch, dst_w, dst_h); } - r->x = rx1; + r->x = dst_x; r->y = dst_y; - r->w = r->w * scale1; + r->w = dst_w * scale1; r->h = dst_h * scale1; #ifdef USE_SCALERS @@ -1335,7 +1354,9 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() { // Readjust the dirty rect list in case we are doing a full update. // This is necessary if shaking is active. if (_forceRedraw) { + _dirtyRectList[0].x = 0; _dirtyRectList[0].y = 0; + _dirtyRectList[0].w = _videoMode.hardwareWidth; _dirtyRectList[0].h = _videoMode.hardwareHeight; } @@ -1350,17 +1371,22 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() { // Of course when the overlay is visible we do not show it, since it is only for game // specific focus. if (_enableFocusRect && !_overlayVisible) { + int x = _focusRect.left + _currentShakeXOffset; int y = _focusRect.top + _currentShakeYOffset; - int h = 0; - int x = _focusRect.left * scale1; - int w = _focusRect.width() * scale1; - if (y < height) { - h = _focusRect.height(); + if (x < width && y < height) { + int w = _focusRect.width(); + if (w > width - x) + w = width - x; + + int h = _focusRect.height(); if (h > height - y) h = height - y; + x *= scale1; y *= scale1; + w *= scale1; + h *= scale1; if (_videoMode.aspectRatioCorrection && !_overlayVisible) y = real2Aspect(y); @@ -2277,6 +2303,7 @@ void SurfaceSdlGraphicsManager::drawMouse() { // We draw the pre-scaled cursor image, so now we need to adjust for // scaling, shake position and aspect ratio correction manually. + dst.x += _currentShakeXOffset; dst.y += _currentShakeYOffset; if (_videoMode.aspectRatioCorrection && !_overlayVisible) diff --git a/backends/graphics/windowed.h b/backends/graphics/windowed.h index 7d9198d6b8..40fbe8baf7 100644 --- a/backends/graphics/windowed.h +++ b/backends/graphics/windowed.h @@ -406,7 +406,7 @@ private: } } - drawRect.left = ((_windowWidth - width) / 2); + drawRect.left = ((_windowWidth - width) / 2) + _gameScreenShakeXOffset; drawRect.top = ((_windowHeight - height) / 2) + _gameScreenShakeYOffset; drawRect.setWidth(width); drawRect.setHeight(height); |