diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp index 35dfbde0be..130f0f357a 100644 --- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp @@ -257,6 +257,21 @@ void ControllerInterface::UpdateInput() } } +void ControllerInterface::SetAspectRatioAdjustment(float value) +{ + m_aspect_ratio_adjustment = value; +} + +Common::Vec2 ControllerInterface::GetWindowInputScale() const +{ + const auto ar = m_aspect_ratio_adjustment.load(); + + if (ar > 1) + return {1.f, ar}; + else + return {1 / ar, 1.f}; +} + // Register a callback to be called when a device is added or removed (as from the input backends' // hotplug thread), or when devices are refreshed // Returns a handle for later removing the callback. diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h index 359bd8f0c3..4f1651f361 100644 --- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h +++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h @@ -10,6 +10,7 @@ #include #include +#include "Common/Matrix.h" #include "Common/WindowSystemInfo.h" #include "InputCommon/ControllerInterface/Device.h" @@ -52,6 +53,14 @@ public: bool IsInit() const { return m_is_init; } void UpdateInput(); + // Set adjustment from the full render window aspect-ratio to the drawn aspect-ratio. + // Used to fit mouse cursor inputs to the relevant region of the render window. + void SetAspectRatioAdjustment(float); + + // Calculated from the aspect-ratio adjustment. + // Inputs based on window coordinates should be multiplied by this. + Common::Vec2 GetWindowInputScale() const; + HotplugCallbackHandle RegisterDevicesChangedCallback(std::function callback); void UnregisterDevicesChangedCallback(const HotplugCallbackHandle& handle); void InvokeDevicesChangedCallbacks() const; @@ -62,6 +71,7 @@ private: std::atomic m_is_init; std::atomic m_is_populating_devices{false}; WindowSystemInfo m_wsi; + std::atomic m_aspect_ratio_adjustment = 1; }; extern ControllerInterface g_controller_interface; diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp index 24edc4386c..1e617d6c24 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp @@ -125,9 +125,11 @@ void KeyboardMouse::UpdateCursorInput() const auto win_width = rect.right - rect.left; const auto win_height = rect.bottom - rect.top; + const auto window_scale = g_controller_interface.GetWindowInputScale(); + // Convert the cursor position to a range from -1 to 1. - m_state_in.cursor.x = ControlState(point.x) / win_width * 2 - 1; - m_state_in.cursor.y = ControlState(point.y) / win_height * 2 - 1; + m_state_in.cursor.x = (ControlState(point.x) / win_width * 2 - 1) * window_scale.x; + m_state_in.cursor.y = (ControlState(point.y) / win_height * 2 - 1) * window_scale.y; } void KeyboardMouse::UpdateInput() diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h index e1d2500b15..711c9461e6 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h @@ -6,6 +6,7 @@ #include +#include "Common/Matrix.h" #include "InputCommon/ControllerInterface/DInput/DInput8.h" #include "InputCommon/ControllerInterface/Device.h" @@ -20,10 +21,7 @@ private: { BYTE keyboard[256]; DIMOUSESTATE2 mouse; - struct - { - ControlState x, y; - } cursor; + Common::TVec2 cursor; }; class Key : public Input diff --git a/Source/Core/InputCommon/ControllerInterface/Quartz/QuartzKeyboardAndMouse.h b/Source/Core/InputCommon/ControllerInterface/Quartz/QuartzKeyboardAndMouse.h index 902621cddc..5d3ea86f3e 100644 --- a/Source/Core/InputCommon/ControllerInterface/Quartz/QuartzKeyboardAndMouse.h +++ b/Source/Core/InputCommon/ControllerInterface/Quartz/QuartzKeyboardAndMouse.h @@ -6,6 +6,7 @@ #include +#include "Common/Matrix.h" #include "InputCommon/ControllerInterface/Device.h" namespace ciface::Quartz @@ -64,10 +65,7 @@ public: std::string GetSource() const override; private: - struct - { - float x, y; - } m_cursor; + Common::Vec2 m_cursor; uint32_t m_windowid; }; diff --git a/Source/Core/InputCommon/ControllerInterface/Quartz/QuartzKeyboardAndMouse.mm b/Source/Core/InputCommon/ControllerInterface/Quartz/QuartzKeyboardAndMouse.mm index 6cbc0a3f11..7c4673acd7 100644 --- a/Source/Core/InputCommon/ControllerInterface/Quartz/QuartzKeyboardAndMouse.mm +++ b/Source/Core/InputCommon/ControllerInterface/Quartz/QuartzKeyboardAndMouse.mm @@ -9,6 +9,8 @@ #include #include +#include "InputCommon/ControllerInterface/ControllerInterface.h" + namespace ciface::Quartz { std::string KeycodeToName(const CGKeyCode keycode) @@ -177,10 +179,12 @@ void KeyboardAndMouse::UpdateInput() CGPoint loc = CGEventGetLocation(event); CFRelease(event); + const auto window_scale = g_controller_interface.GetWindowInputScale(); + loc.x -= bounds.origin.x; loc.y -= bounds.origin.y; - m_cursor.x = loc.x / bounds.size.width * 2 - 1.0; - m_cursor.y = loc.y / bounds.size.height * 2 - 1.0; + m_cursor.x = (loc.x / bounds.size.width * 2 - 1.0) * window_scale.x; + m_cursor.y = (loc.y / bounds.size.height * 2 - 1.0) * window_scale.y; } std::string KeyboardAndMouse::GetName() const diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp index d9642c6264..540a2ec9a8 100644 --- a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp @@ -212,9 +212,11 @@ void KeyboardMouse::UpdateCursor() XWindowAttributes win_attribs; XGetWindowAttributes(m_display, m_window, &win_attribs); + const auto window_scale = g_controller_interface.GetWindowInputScale(); + // the mouse position as a range from -1 to 1 - m_state.cursor.x = win_x / (float)win_attribs.width * 2 - 1; - m_state.cursor.y = win_y / (float)win_attribs.height * 2 - 1; + m_state.cursor.x = (win_x / win_attribs.width * 2 - 1) * window_scale.x; + m_state.cursor.y = (win_y / win_attribs.height * 2 - 1) * window_scale.y; } void KeyboardMouse::UpdateInput() diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h index e657f8b8df..52c424a3e6 100644 --- a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h +++ b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h @@ -12,6 +12,7 @@ extern "C" { #include } +#include "Common/Matrix.h" #include "InputCommon/ControllerInterface/ControllerInterface.h" namespace ciface::XInput2 @@ -25,10 +26,8 @@ private: { char keyboard[32]; unsigned int buttons; - struct - { - float x, y; - } cursor, axis; + Common::Vec2 cursor; + Common::Vec2 axis; }; class Key : public Input diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 71281defdf..03e277d563 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -50,6 +50,8 @@ #include "Core/Host.h" #include "Core/Movie.h" +#include "InputCommon/ControllerInterface/ControllerInterface.h" + #include "VideoCommon/AbstractFramebuffer.h" #include "VideoCommon/AbstractStagingTexture.h" #include "VideoCommon/AbstractTexture.h" @@ -119,6 +121,9 @@ bool Renderer::Initialize() void Renderer::Shutdown() { + // Disable ControllerInterface's aspect ratio adjustments so mapping dialog behaves normally. + g_controller_interface.SetAspectRatioAdjustment(1); + // First stop any framedumping, which might need to dump the last xfb frame. This process // can require additional graphics sub-systems so it needs to be done first ShutdownFrameDumping(); @@ -775,10 +780,15 @@ void Renderer::UpdateDrawRectangle() g_Config.fAspectRatioHackH = 1; } - float draw_width, draw_height, crop_width, crop_height; - // get the picture aspect ratio - draw_width = crop_width = CalculateDrawAspectRatio(); + const float draw_aspect_ratio = CalculateDrawAspectRatio(); + + // Make ControllerInterface aware of the render window region actually being used + // to adjust mouse cursor inputs. + g_controller_interface.SetAspectRatioAdjustment(draw_aspect_ratio / (win_width / win_height)); + + float draw_width, draw_height, crop_width, crop_height; + draw_width = crop_width = draw_aspect_ratio; draw_height = crop_height = 1; // crop the picture to a standard aspect ratio