From 3b542cea53b94bc10592a618f60c4f813e518b60 Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Sun, 21 Oct 2018 18:35:40 +0100 Subject: SURFACESDL: Respect filtering setting when performing aspect ratio correction --- backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp | 2 +- backends/graphics/gph/gph-graphics.cpp | 2 +- .../linuxmotosdl/linuxmotosdl-graphics.cpp | 2 +- .../graphics/surfacesdl/surfacesdl-graphics.cpp | 33 ++++++-------- backends/graphics/surfacesdl/surfacesdl-graphics.h | 6 +-- graphics/scaler/aspect.cpp | 50 ++++++++++++++++------ graphics/scaler/aspect.h | 6 ++- 7 files changed, 58 insertions(+), 43 deletions(-) diff --git a/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp b/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp index fa2217dfd8..6a935ea75b 100644 --- a/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp +++ b/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp @@ -372,7 +372,7 @@ void DINGUXSdlGraphicsManager::internUpdateScreen() { #ifdef USE_SCALERS if (_videoMode.aspectRatioCorrection && orig_dst_y < height && !_overlayVisible) - r->h = stretch200To240((uint8 *) _hwScreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1); + r->h = stretch200To240((uint8 *) _hwScreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1, _videoMode.filtering); #endif } SDL_UnlockSurface(srcSurf); diff --git a/backends/graphics/gph/gph-graphics.cpp b/backends/graphics/gph/gph-graphics.cpp index 910dab9140..5ec36c25c6 100644 --- a/backends/graphics/gph/gph-graphics.cpp +++ b/backends/graphics/gph/gph-graphics.cpp @@ -395,7 +395,7 @@ void GPHGraphicsManager::internUpdateScreen() { #ifdef USE_SCALERS if (_videoMode.aspectRatioCorrection && orig_dst_y < height && !_overlayVisible) - r->h = stretch200To240((uint8 *) _hwScreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1); + r->h = stretch200To240((uint8 *) _hwScreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1, _videoMode.filtering); #endif } SDL_UnlockSurface(srcSurf); diff --git a/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp b/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp index 57b7f8136b..bb78435797 100644 --- a/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp +++ b/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp @@ -406,7 +406,7 @@ void LinuxmotoSdlGraphicsManager::internUpdateScreen() { #ifdef USE_SCALERS if (_videoMode.aspectRatioCorrection && orig_dst_y < height && !_overlayVisible) - r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1); + r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1, _videoMode.filtering); #endif } SDL_UnlockSurface(srcSurf); diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp index ac758e4424..3e9aa9faab 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp @@ -204,8 +204,8 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou _videoMode.fullscreen = true; #endif -#if SDL_VERSION_ATLEAST(2, 0, 0) _videoMode.filtering = ConfMan.getBool("filtering"); +#if SDL_VERSION_ATLEAST(2, 0, 0) _videoMode.stretchMode = STRETCH_FIT; #endif @@ -254,8 +254,8 @@ bool SurfaceSdlGraphicsManager::hasFeature(OSystem::Feature f) const { return (f == OSystem::kFeatureFullscreenMode) || (f == OSystem::kFeatureAspectRatioCorrection) || -#if SDL_VERSION_ATLEAST(2, 0, 0) (f == OSystem::kFeatureFilteringMode) || +#if SDL_VERSION_ATLEAST(2, 0, 0) (f == OSystem::kFeatureStretchMode) || #endif (f == OSystem::kFeatureCursorPalette) || @@ -270,11 +270,9 @@ void SurfaceSdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) case OSystem::kFeatureAspectRatioCorrection: setAspectRatioCorrection(enable); break; -#if SDL_VERSION_ATLEAST(2, 0, 0) case OSystem::kFeatureFilteringMode: setFilteringMode(enable); break; -#endif case OSystem::kFeatureCursorPalette: _cursorPaletteDisabled = !enable; blitCursor(); @@ -299,10 +297,8 @@ bool SurfaceSdlGraphicsManager::getFeatureState(OSystem::Feature f) const { return _videoMode.fullscreen; case OSystem::kFeatureAspectRatioCorrection: return _videoMode.aspectRatioCorrection; -#if SDL_VERSION_ATLEAST(2, 0, 0) case OSystem::kFeatureFilteringMode: return _videoMode.filtering; -#endif case OSystem::kFeatureCursorPalette: return !_cursorPaletteDisabled; default: @@ -371,11 +367,11 @@ OSystem::TransactionError SurfaceSdlGraphicsManager::endGFXTransaction() { errors |= OSystem::kTransactionStretchModeSwitchFailed; _videoMode.stretchMode = _oldVideoMode.stretchMode; +#endif } else if (_videoMode.filtering != _oldVideoMode.filtering) { errors |= OSystem::kTransactionFilteringFailed; _videoMode.filtering = _oldVideoMode.filtering; -#endif #ifdef USE_RGB_COLOR } else if (_videoMode.format != _oldVideoMode.format) { errors |= OSystem::kTransactionFormatNotSupported; @@ -395,9 +391,7 @@ OSystem::TransactionError SurfaceSdlGraphicsManager::endGFXTransaction() { if (_videoMode.fullscreen == _oldVideoMode.fullscreen && _videoMode.aspectRatioCorrection == _oldVideoMode.aspectRatioCorrection && _videoMode.mode == _oldVideoMode.mode && -#if SDL_VERSION_ATLEAST(2, 0, 0) _videoMode.filtering == _oldVideoMode.filtering && -#endif _videoMode.screenWidth == _oldVideoMode.screenWidth && _videoMode.screenHeight == _oldVideoMode.screenHeight) { @@ -1329,7 +1323,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() { #ifdef USE_SCALERS if (_videoMode.aspectRatioCorrection && orig_dst_y < height && !_overlayVisible) - r->h = stretch200To240((uint8 *) _hwScreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1); + r->h = stretch200To240((uint8 *) _hwScreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1, _videoMode.filtering); #endif } SDL_UnlockSurface(srcSurf); @@ -1520,7 +1514,6 @@ void SurfaceSdlGraphicsManager::setAspectRatioCorrection(bool enable) { } } -#if SDL_VERSION_ATLEAST(2, 0, 0) void SurfaceSdlGraphicsManager::setFilteringMode(bool enable) { Common::StackLock lock(_graphicsMutex); @@ -1529,10 +1522,11 @@ void SurfaceSdlGraphicsManager::setFilteringMode(bool enable) { if (_transactionMode == kTransactionActive) { _videoMode.filtering = enable; +#if SDL_VERSION_ATLEAST(2, 0, 0) _transactionDetails.needTextureUpdate = true; +#endif } } -#endif void SurfaceSdlGraphicsManager::copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) { assert(_transactionMode == kTransactionNone); @@ -1663,9 +1657,8 @@ void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool re } #ifdef USE_SCALERS - if (_videoMode.aspectRatioCorrection && !_overlayVisible && !realCoordinates) { - makeRectStretchable(x, y, w, h); - } + if (_videoMode.aspectRatioCorrection && !_overlayVisible && !realCoordinates) + makeRectStretchable(x, y, w, h, _videoMode.filtering); #endif if (w == width && h == height) { @@ -1825,7 +1818,8 @@ void SurfaceSdlGraphicsManager::clearOverlay() { #ifdef USE_SCALERS if (_videoMode.aspectRatioCorrection) stretch200To240((uint8 *)_overlayscreen->pixels, _overlayscreen->pitch, - _videoMode.overlayWidth, _videoMode.screenHeight * _videoMode.scaleFactor, 0, 0, 0); + _videoMode.overlayWidth, _videoMode.screenHeight * _videoMode.scaleFactor, 0, 0, 0, + _videoMode.filtering); #endif SDL_UnlockSurface(_tmpscreen); SDL_UnlockSurface(_overlayscreen); @@ -2209,8 +2203,7 @@ void SurfaceSdlGraphicsManager::blitCursor() { } #ifdef USE_SCALERS -// Basically it is kVeryFastAndUglyAspectMode of stretch200To240 from -// common/scale/aspect.cpp +// Basically it is stretch200To240Nearest from common/scale/aspect.cpp static int cursorStretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY) { int maxDstY = real2Aspect(origSrcY + height - 1); int y; @@ -2538,7 +2531,6 @@ bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) { return true; } -#if SDL_VERSION_ATLEAST(2, 0, 0) // Ctrl-Alt-f toggles filtering if (key == 'f') { beginGFXTransaction(); @@ -2555,7 +2547,6 @@ bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) { internUpdateScreen(); return true; } -#endif #if SDL_VERSION_ATLEAST(2, 0, 0) // Ctrl+Alt+s cycles through scaling mode (0 to 3) @@ -2676,9 +2667,9 @@ bool SurfaceSdlGraphicsManager::isScalerHotkey(const Common::Event &event) { if (keyValue >= ARRAYSIZE(s_gfxModeSwitchTable)) return false; } -#if SDL_VERSION_ATLEAST(2, 0, 0) if (event.kbd.keycode == 'f') return true; +#if SDL_VERSION_ATLEAST(2, 0, 0) if (event.kbd.keycode == 's') return true; #endif diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h index 6e7fec4823..3866bc3810 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.h +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h @@ -248,9 +248,9 @@ protected: bool fullscreen; bool aspectRatioCorrection; AspectRatio desiredAspectRatio; - -#if SDL_VERSION_ATLEAST(2, 0, 0) bool filtering; + +#if SDL_VERSION_ATLEAST(2, 0, 0) int stretchMode; #endif @@ -381,9 +381,7 @@ protected: virtual bool hotswapGFXMode(); virtual void setAspectRatioCorrection(bool enable); -#if SDL_VERSION_ATLEAST(2, 0, 0) void setFilteringMode(bool enable); -#endif virtual bool saveScreenshot(const char *filename); virtual void setGraphicsModeIntern(); diff --git a/graphics/scaler/aspect.cpp b/graphics/scaler/aspect.cpp index b923442163..f85d043a83 100644 --- a/graphics/scaler/aspect.cpp +++ b/graphics/scaler/aspect.cpp @@ -158,8 +158,10 @@ static inline void interpolate5Line(uint16 *dst, const uint16 *srcA, const uint1 } #endif -void makeRectStretchable(int &x, int &y, int &w, int &h) { +void makeRectStretchable(int &x, int &y, int &w, int &h, bool interpolate) { #if ASPECT_MODE != kSuperFastAndUglyAspectMode + if (!interpolate) + return; int m = real2Aspect(y) % 6; // Ensure that the rect will start on a line that won't have its @@ -203,8 +205,9 @@ void makeRectStretchable(int &x, int &y, int &w, int &h) { * srcY + height - 1, and it should be stretched to Y coordinates srcY * through real2Aspect(srcY + height - 1). */ + template -int stretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY) { +int stretch200To240Nearest(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY) { int maxDstY = real2Aspect(origSrcY + height - 1); int y; const uint8 *startSrcPtr = buf + srcX * 2 + (srcY - origSrcY) * pitch; @@ -212,13 +215,25 @@ int stretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, i for (y = maxDstY; y >= srcY; y--) { const uint8 *srcPtr = startSrcPtr + aspect2Real(y) * pitch; - -#if ASPECT_MODE == kSuperFastAndUglyAspectMode if (srcPtr == dstPtr) break; memcpy(dstPtr, srcPtr, sizeof(uint16) * width); -#else - // Bilinear filter + dstPtr -= pitch; + } + + return 1 + maxDstY - srcY; +} + + +template +int stretch200To240Interpolated(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY) { + int maxDstY = real2Aspect(origSrcY + height - 1); + int y; + const uint8 *startSrcPtr = buf + srcX * 2 + (srcY - origSrcY) * pitch; + uint8 *dstPtr = buf + srcX * 2 + maxDstY * pitch; + + for (y = maxDstY; y >= srcY; y--) { + const uint8 *srcPtr = startSrcPtr + aspect2Real(y) * pitch; switch (y % 6) { case 0: case 5: @@ -238,22 +253,31 @@ int stretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, i interpolate5Line((uint16 *)dstPtr, (const uint16 *)srcPtr, (const uint16 *)(srcPtr - pitch), width); break; } -#endif dstPtr -= pitch; } return 1 + maxDstY - srcY; } -int stretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY) { +int stretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY, bool interpolate) { extern int gBitFormat; - if (gBitFormat == 565) - return stretch200To240 >(buf, pitch, width, height, srcX, srcY, origSrcY); - else // gBitFormat == 555 - return stretch200To240 >(buf, pitch, width, height, srcX, srcY, origSrcY); +#if ASPECT_MODE != kSuperFastAndUglyAspectMode + if (interpolate) { + if (gBitFormat == 565) + return stretch200To240Interpolated >(buf, pitch, width, height, srcX, srcY, origSrcY); + else // gBitFormat == 555 + return stretch200To240Interpolated >(buf, pitch, width, height, srcX, srcY, origSrcY); + } else { +#endif + if (gBitFormat == 565) + return stretch200To240Nearest >(buf, pitch, width, height, srcX, srcY, origSrcY); + else // gBitFormat == 555 + return stretch200To240Nearest >(buf, pitch, width, height, srcX, srcY, origSrcY); +#if ASPECT_MODE != kSuperFastAndUglyAspectMode + } +#endif } - template void Normal1xAspectTemplate(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { diff --git a/graphics/scaler/aspect.h b/graphics/scaler/aspect.h index 30e13c93cd..bb082ebba0 100644 --- a/graphics/scaler/aspect.h +++ b/graphics/scaler/aspect.h @@ -43,18 +43,20 @@ FORCEINLINE int aspect2Real(int y) { /** * TODO: explain */ -void makeRectStretchable(int &x, int &y, int &w, int &h); +void makeRectStretchable(int &x, int &y, int &w, int &h, bool interpolate); /** * TODO: explain */ + int stretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, - int origSrcY); + int origSrcY, + bool interpolate); /** -- cgit v1.2.3