diff --git a/src/core/gpu.cpp b/src/core/gpu.cpp
index 56ac5dc9d..c7d21f5d6 100644
--- a/src/core/gpu.cpp
+++ b/src/core/gpu.cpp
@@ -927,15 +927,15 @@ bool GPU::ConvertScreenCoordinatesToBeamTicksAndLines(s32 window_x, s32 window_y
   if (x_scale != 1.0f)
   {
     const float dw = static_cast<float>(m_crtc_state.display_width);
-    float scaled_x = ((static_cast<float>(display_x) / dw) * 2.0f) - 1.0f; // 0..1 -> -1..1
+    float scaled_x = ((display_x / dw) * 2.0f) - 1.0f; // 0..1 -> -1..1
     scaled_x *= x_scale;
-    display_x = static_cast<s32>(((scaled_x + 1.0f) * 0.5f) * dw); // -1..1 -> 0..1
+    display_x = (((scaled_x + 1.0f) * 0.5f) * dw); // -1..1 -> 0..1
   }
 
-  Log_DebugPrintf("win %d,%d -> disp %d,%d (size %u,%u frac %f,%f)", window_x, window_y, display_x, display_y,
+  Log_DebugPrintf("win %d,%d -> disp %.2f,%.2f (size %u,%u frac %f,%f)", window_x, window_y, display_x, display_y,
                   m_crtc_state.display_width, m_crtc_state.display_height,
-                  static_cast<float>(display_x) / static_cast<float>(m_crtc_state.display_width),
-                  static_cast<float>(display_y) / static_cast<float>(m_crtc_state.display_height));
+                  display_x / static_cast<float>(m_crtc_state.display_width),
+                  display_y / static_cast<float>(m_crtc_state.display_height));
 
   if (display_x < 0 || static_cast<u32>(display_x) >= m_crtc_state.display_width || display_y < 0 ||
       static_cast<u32>(display_y) >= m_crtc_state.display_height)
@@ -943,9 +943,10 @@ bool GPU::ConvertScreenCoordinatesToBeamTicksAndLines(s32 window_x, s32 window_y
     return false;
   }
 
-  *out_line =
-    (static_cast<u32>(display_y) >> BoolToUInt8(m_GPUSTAT.vertical_interlace)) + m_crtc_state.vertical_visible_start;
-  *out_tick = (static_cast<u32>(display_x) * m_crtc_state.dot_clock_divider) + m_crtc_state.horizontal_visible_start;
+  *out_line = (static_cast<u32>(std::round(display_y)) >> BoolToUInt8(m_GPUSTAT.vertical_interlace)) +
+              m_crtc_state.vertical_visible_start;
+  *out_tick = static_cast<u32>(std::round(display_x * static_cast<float>(m_crtc_state.dot_clock_divider))) +
+              m_crtc_state.horizontal_visible_start;
   return true;
 }
 
diff --git a/src/core/host_display.cpp b/src/core/host_display.cpp
index c285b1525..740f33add 100644
--- a/src/core/host_display.cpp
+++ b/src/core/host_display.cpp
@@ -257,9 +257,9 @@ std::tuple<s32, s32, s32, s32> HostDisplay::CalculateSoftwareCursorDrawRect(s32
   return std::tie(out_left, out_top, out_width, out_height);
 }
 
-std::tuple<s32, s32> HostDisplay::ConvertWindowCoordinatesToDisplayCoordinates(s32 window_x, s32 window_y,
-                                                                               s32 window_width, s32 window_height,
-                                                                               s32 top_margin) const
+std::tuple<float, float> HostDisplay::ConvertWindowCoordinatesToDisplayCoordinates(s32 window_x, s32 window_y,
+                                                                                   s32 window_width, s32 window_height,
+                                                                                   s32 top_margin) const
 {
   s32 left, top, width, height, left_padding, top_padding;
   float scale, y_scale;
@@ -274,7 +274,7 @@ std::tuple<s32, s32> HostDisplay::ConvertWindowCoordinatesToDisplayCoordinates(s
   const float display_x = scaled_display_x / scale;
   const float display_y = scaled_display_y / scale / y_scale;
 
-  return std::make_tuple(static_cast<s32>(display_x), static_cast<s32>(display_y));
+  return std::make_tuple(display_x, display_y);
 }
 
 static bool CompressAndWriteTextureToFile(u32 width, u32 height, std::string filename, FileSystem::ManagedCFilePtr fp,
diff --git a/src/core/host_display.h b/src/core/host_display.h
index 34e073111..47b8ad372 100644
--- a/src/core/host_display.h
+++ b/src/core/host_display.h
@@ -190,8 +190,8 @@ public:
                                                    bool apply_aspect_ratio = true) const;
 
   /// Helper function for converting window coordinates to display coordinates.
-  std::tuple<s32, s32> ConvertWindowCoordinatesToDisplayCoordinates(s32 window_x, s32 window_y, s32 window_width,
-                                                                    s32 window_height, s32 top_margin) const;
+  std::tuple<float, float> ConvertWindowCoordinatesToDisplayCoordinates(s32 window_x, s32 window_y, s32 window_width,
+                                                                        s32 window_height, s32 top_margin) const;
 
   /// Helper function to save texture data to a PNG. If flip_y is set, the image will be flipped aka OpenGL.
   bool WriteTextureToFile(const void* texture_handle, u32 x, u32 y, u32 width, u32 height, std::string filename,