From 3ec96b84add67921a2a2ca552b0bbd400d14d70a Mon Sep 17 00:00:00 2001 From: Muzychenko Andrey <33288308+k4zmu2a@users.noreply.github.com> Date: Mon, 25 Oct 2021 08:03:30 +0300 Subject: [PATCH] PresentVScreen: fixed sub pixel offset. SDL<2.0.10 uses crude approximation. --- SpaceCadetPinball/pch.h | 6 +++++ SpaceCadetPinball/render.cpp | 47 +++++++++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/SpaceCadetPinball/pch.h b/SpaceCadetPinball/pch.h index 9a49af3..40e2849 100644 --- a/SpaceCadetPinball/pch.h +++ b/SpaceCadetPinball/pch.h @@ -77,4 +77,10 @@ inline float RandFloat() return static_cast(std::rand() / static_cast(RAND_MAX)); } +template constexpr +int Sign(T val) +{ + return (T(0) < val) - (val < T(0)); +} + #endif //PCH_H diff --git a/SpaceCadetPinball/render.cpp b/SpaceCadetPinball/render.cpp index ee0cc5b..cd9bae6 100644 --- a/SpaceCadetPinball/render.cpp +++ b/SpaceCadetPinball/render.cpp @@ -563,29 +563,53 @@ void render::PresentVScreen() } else { - int32_t srcSeparationX = static_cast(vscreen->Width * 0.625f); - - SDL_Rect srcBoardRect = SDL_Rect + auto tableWidthCoef = static_cast(pb::MainTable->Width) / vscreen->Width; + auto srcSeparationX = static_cast(round(vscreen->Width * tableWidthCoef)); + auto srcBoardRect = SDL_Rect { 0, 0, srcSeparationX, vscreen->Height }; - - SDL_Rect srcSidebarRect = SDL_Rect + auto srcSidebarRect = SDL_Rect { srcSeparationX, 0, vscreen->Width - srcSeparationX, vscreen->Height }; - int32_t dstSeparationX = static_cast(DestinationRect.w * 0.625f); - - SDL_Rect dstBoardRect = SDL_Rect +#if SDL_VERSION_ATLEAST(2, 0, 10) + // SDL_RenderCopyF was added in 2.0.10 + auto dstSeparationX = DestinationRect.w * tableWidthCoef; + auto dstBoardRect = SDL_FRect { - DestinationRect.x + static_cast(offset_x * fullscrn::ScaleX), DestinationRect.y + static_cast(offset_y * fullscrn::ScaleY), - dstSeparationX, DestinationRect.h + DestinationRect.x + offset_x * fullscrn::ScaleX, + DestinationRect.y + offset_y * fullscrn::ScaleY, + dstSeparationX, static_cast(DestinationRect.h) + }; + auto dstSidebarRect = SDL_FRect + { + DestinationRect.x + dstSeparationX, static_cast(DestinationRect.y), + DestinationRect.w - dstSeparationX, static_cast(DestinationRect.h) }; - SDL_Rect dstSidebarRect = SDL_Rect + SDL_RenderCopyF(winmain::Renderer, vScreenTex, &srcBoardRect, &dstBoardRect); + SDL_RenderCopyF(winmain::Renderer, vScreenTex, &srcSidebarRect, &dstSidebarRect); +#else + // SDL_RenderCopy cannot express sub pixel offset. + // Vscreen shift is required for that. + auto dstSeparationX = static_cast(DestinationRect.w * tableWidthCoef); + auto scaledOffX = static_cast(round(offset_x * fullscrn::ScaleX)); + if (offset_x != 0 && scaledOffX == 0) + scaledOffX = Sign(offset_x); + auto scaledOffY = static_cast(round(offset_y * fullscrn::ScaleY)); + if (offset_y != 0 && scaledOffX == 0) + scaledOffY = Sign(offset_y); + + auto dstBoardRect = SDL_Rect + { + DestinationRect.x + scaledOffX, DestinationRect.y + scaledOffY, + dstSeparationX, DestinationRect.h + }; + auto dstSidebarRect = SDL_Rect { DestinationRect.x + dstSeparationX, DestinationRect.y, DestinationRect.w - dstSeparationX, DestinationRect.h @@ -593,5 +617,6 @@ void render::PresentVScreen() SDL_RenderCopy(winmain::Renderer, vScreenTex, &srcBoardRect, &dstBoardRect); SDL_RenderCopy(winmain::Renderer, vScreenTex, &srcSidebarRect, &dstSidebarRect); +#endif } }