From 5a94adcf2692b6d02d929d62823123d33c4f4bfd Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 22 Mar 2026 15:54:29 +0300 Subject: [PATCH] overlays: Implement SDF config transforms --- rpcs3/Emu/RSX/Overlays/overlay_controls.cpp | 34 +++++++++++++++++++++ rpcs3/Emu/RSX/Overlays/overlay_controls.h | 5 +++ rpcs3/Emu/RSX/VK/VKOverlays.cpp | 1 + 3 files changed, 40 insertions(+) diff --git a/rpcs3/Emu/RSX/Overlays/overlay_controls.cpp b/rpcs3/Emu/RSX/Overlays/overlay_controls.cpp index 0a1af3c6c5..67c9fdf36f 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_controls.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_controls.cpp @@ -54,6 +54,40 @@ namespace rsx return result; } + void compiled_resource::sdf_config_t::transform(const areaf& target_viewport, const sizef& virtual_viewport) + { + const f32 scale_x = target_viewport.width() / virtual_viewport.width; + const f32 scale_y = target_viewport.height() / virtual_viewport.height; + + // Ideally the average should match the x and y scaling but arithmetic drift shifts the values around a bit. + // Also we need a way to define perfect circles when the aspect ratio is not respected. + const f32 scale_av = (scale_x + scale_y) / 2; + + hx *= scale_x; + hy *= scale_y; + br *= scale_av; + bw *= scale_av; + + // Account for flipped viewport + if (target_viewport.x2 < target_viewport.x1) + { + cx = target_viewport.width() - (cx * scale_x) + target_viewport.x2; + } + else + { + cx = cx * scale_x + target_viewport.x1; + } + + if (target_viewport.y2 < target_viewport.y1) + { + cy = target_viewport.height() - (cy * scale_y) + target_viewport.y2; + } + else + { + cy = cy * scale_y + target_viewport.y1; + } + } + image_info::image_info(const std::string& filename, bool grayscaled) { fs::file f(filename, fs::read + fs::isfile); diff --git a/rpcs3/Emu/RSX/Overlays/overlay_controls.h b/rpcs3/Emu/RSX/Overlays/overlay_controls.h index 0932eaa9ed..7b88af2e12 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_controls.h +++ b/rpcs3/Emu/RSX/Overlays/overlay_controls.h @@ -115,6 +115,11 @@ namespace rsx f32 bw; // Border width color4f border_color; + + // Transform a SDF definition from one reference frame to another + // Target viewport - your actual render area + // Virtual viewport - the internal design viewport + void transform(const areaf& target_viewport, const sizef& virtual_viewport); }; struct command_config diff --git a/rpcs3/Emu/RSX/VK/VKOverlays.cpp b/rpcs3/Emu/RSX/VK/VKOverlays.cpp index c555e7a341..0436ab527d 100644 --- a/rpcs3/Emu/RSX/VK/VKOverlays.cpp +++ b/rpcs3/Emu/RSX/VK/VKOverlays.cpp @@ -660,6 +660,7 @@ namespace vk m_disable_vertex_snap = command.config.disable_vertex_snap; m_sdf_config = command.config.sdf_config; + m_sdf_config.transform(static_cast(viewport), { m_scale_offset.x, m_scale_offset.y }); vk::image_view* src = nullptr; switch (command.config.texture_ref)