From 11bee5527d5ce8db44626597a9c415b5cda3eb9b Mon Sep 17 00:00:00 2001 From: boykopovar Date: Fri, 25 Sep 2026 11:07:51 +0300 Subject: [PATCH] fix(video): preserve client aspect ratio when resizing --- .../libSceVideoOut/include/DisplayWindow.hpp | 2 +- .../prx/libSceVideoOut/src/DisplayWindow.cpp | 30 ++++++++++++------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/core/libs/prx/libSceVideoOut/include/DisplayWindow.hpp b/core/libs/prx/libSceVideoOut/include/DisplayWindow.hpp index fbc4283e8..fbc4d960a 100644 --- a/core/libs/prx/libSceVideoOut/include/DisplayWindow.hpp +++ b/core/libs/prx/libSceVideoOut/include/DisplayWindow.hpp @@ -25,7 +25,7 @@ private: void updateAspectRatio(std::uint32_t sourceWidth, std::uint32_t sourceHeight); void installSubclass(); void removeSubclass() noexcept; - void applyAspectRatio(std::uintptr_t edge, void* rect) const; + void applyAspectRatio(void* hwnd, std::uintptr_t edge, void* rect) const; static std::intptr_t __stdcall windowProc(void* hwnd, unsigned int message, std::uintptr_t wParam, std::intptr_t lParam, std::uintptr_t subclassId, std::uintptr_t referenceData); diff --git a/core/libs/prx/libSceVideoOut/src/DisplayWindow.cpp b/core/libs/prx/libSceVideoOut/src/DisplayWindow.cpp index f861a8e14..7c7f5ac23 100644 --- a/core/libs/prx/libSceVideoOut/src/DisplayWindow.cpp +++ b/core/libs/prx/libSceVideoOut/src/DisplayWindow.cpp @@ -124,21 +124,30 @@ void DisplayWindow::removeSubclass() noexcept { #endif } -void DisplayWindow::applyAspectRatio(std::uintptr_t edge, void* rect) const { +void DisplayWindow::applyAspectRatio(void* hwnd, std::uintptr_t edge, void* rect) const { #ifdef _WIN32 - if (aspectWidth == 0 || aspectHeight == 0) return; + require(aspectWidth != 0 && aspectHeight != 0, "source extent must be non-zero during resize"); + RECT windowBounds{}; + RECT clientBounds{}; + require(GetWindowRect(static_cast(hwnd), &windowBounds) != FALSE, "GetWindowRect failed"); + require(GetClientRect(static_cast(hwnd), &clientBounds) != FALSE, "GetClientRect failed"); + const auto frameWidth = (windowBounds.right - windowBounds.left) - (clientBounds.right - clientBounds.left); + const auto frameHeight = (windowBounds.bottom - windowBounds.top) - (clientBounds.bottom - clientBounds.top); + require(frameWidth >= 0 && frameHeight >= 0, "invalid window frame extent"); auto* bounds = static_cast(rect); - const auto currentWidth = static_cast(bounds->right - bounds->left); - const auto currentHeight = static_cast(bounds->bottom - bounds->top); + const auto clientWidth = bounds->right - bounds->left - frameWidth; + const auto clientHeight = bounds->bottom - bounds->top - frameHeight; + require(clientWidth > 0 && clientHeight > 0, "resized client extent must be positive"); if (edge == WMSZ_TOP || edge == WMSZ_BOTTOM) { - const auto width = AgcDriver::ComputeWidthForHeight_nid_postfix(aspectWidth, aspectHeight, currentHeight); - bounds->right = bounds->left + static_cast(width); + const auto width = AgcDriver::ComputeWidthForHeight_nid_postfix(aspectWidth, aspectHeight, static_cast(clientHeight)); + bounds->right = bounds->left + static_cast(width) + frameWidth; return; } - const auto height = AgcDriver::ComputeHeightForWidth_nid_postfix(aspectWidth, aspectHeight, currentWidth); - if (edge == WMSZ_TOPLEFT || edge == WMSZ_TOPRIGHT) bounds->top = bounds->bottom - static_cast(height); - else bounds->bottom = bounds->top + static_cast(height); + const auto height = AgcDriver::ComputeHeightForWidth_nid_postfix(aspectWidth, aspectHeight, static_cast(clientWidth)); + if (edge == WMSZ_TOPLEFT || edge == WMSZ_TOPRIGHT) bounds->top = bounds->bottom - static_cast(height) - frameHeight; + else bounds->bottom = bounds->top + static_cast(height) + frameHeight; #else + static_cast(hwnd); static_cast(edge); static_cast(rect); #endif @@ -148,7 +157,8 @@ std::intptr_t __stdcall DisplayWindow::windowProc(void* hwnd, unsigned int messa #ifdef _WIN32 static_cast(subclassId); if (message == WM_SIZING) { - reinterpret_cast(referenceData)->applyAspectRatio(wParam, reinterpret_cast(lParam)); + reinterpret_cast(referenceData)->applyAspectRatio(hwnd, wParam, reinterpret_cast(lParam)); + return TRUE; } return DefSubclassProc(static_cast(hwnd), message, static_cast(wParam), static_cast(lParam)); #else