From 329bf692e668e5c3d0a9b24c5e53415021b2064a Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Thu, 23 Apr 2026 11:58:58 +0200 Subject: [PATCH] =?UTF-8?q?feat(editor):=20Screen::windowToCanvas()=20per?= =?UTF-8?q?=20a=20input=20de=20rat=C3=B2li?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/core/rendering/screen.cpp | 29 +++++++++++++++++++++++++++++ source/core/rendering/screen.hpp | 10 ++++++++++ 2 files changed, 39 insertions(+) diff --git a/source/core/rendering/screen.cpp b/source/core/rendering/screen.cpp index 69248fb..6953fd1 100644 --- a/source/core/rendering/screen.cpp +++ b/source/core/rendering/screen.cpp @@ -11,6 +11,7 @@ #include #include "core/rendering/canvas.hpp" +#include "core/rendering/sdl3gpu/viewport.hpp" #include "utils/defines.hpp" namespace { @@ -265,6 +266,34 @@ void Screen::blendRect(int x, int y, int w, int h, std::uint32_t argb, std::uint } } +auto Screen::windowToCanvas(float window_x, float window_y) const -> SDL_FPoint { + // Path fallback: SDL ja porta un helper que desfà el + // logical_presentation automàticament. Evita que haguem de replicar + // les regles de letterbox/integer/etc. + if (renderer_ != nullptr) { + float cx = 0.0F; + float cy = 0.0F; + SDL_RenderCoordinatesFromWindow(renderer_, window_x, window_y, &cx, &cy); + return {cx, cy}; + } + // Path GPU: el canvas es pinta al viewport que calcula + // `computeViewport` a partir del mode d'escalat i la mida del + // swapchain. Fem el mateix càlcul aquí per trobar la inversa. + int win_w = 0; + int win_h = 0; + SDL_GetWindowSize(window_, &win_w, &win_h); + if (win_w <= 0 || win_h <= 0) { return {-1.0F, -1.0F}; } + const auto VP = Rendering::computeViewport(config_.scaling_mode, + static_cast(win_w), + static_cast(win_h), + canvas_width_, + canvas_height_); + if (VP.w <= 0.0F || VP.h <= 0.0F) { return {-1.0F, -1.0F}; } + const float NX = (window_x - VP.x) / VP.w; + const float NY = (window_y - VP.y) / VP.h; + return {NX * static_cast(canvas_width_), NY * static_cast(canvas_height_)}; +} + void Screen::setOverlayRenderer(std::function callback) { overlay_renderer_ = std::move(callback); } diff --git a/source/core/rendering/screen.hpp b/source/core/rendering/screen.hpp index 763460a..2bb8726 100644 --- a/source/core/rendering/screen.hpp +++ b/source/core/rendering/screen.hpp @@ -86,6 +86,16 @@ class Screen { [[nodiscard]] auto getCanvasWidth() const -> int { return canvas_width_; } [[nodiscard]] auto getCanvasHeight() const -> int { return canvas_height_; } + // Transforma una coordenada en espai finestra (tal com venen als + // esdeveniments SDL de ratolí) a espai canvas (0..canvas_w, 0..canvas_h). + // Reverteix el zoom de la finestra i el mode d'escalat actiu: al path + // fallback SDL_Renderer es delega a `SDL_RenderCoordinatesFromWindow`; + // al path GPU es recalcula a partir del viewport actual. Si el punt + // cau fora de la zona del canvas (letterbox/integer), els valors + // retornats queden fora del rang `[0, canvas_w/h)` — el caller ha de + // fer el bounds-check i ignorar el clic en eixe cas. + [[nodiscard]] auto windowToCanvas(float window_x, float window_y) const -> SDL_FPoint; + // Mètriques per a overlays de debug (RenderInfo). [[nodiscard]] auto getLastFPS() const -> int { return fps_.last_value; } [[nodiscard]] auto getGPUDriver() const -> const std::string& { return gpu_driver_; }