summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorAdmiral H. Curtiss <pikachu025@gmail.com>2022-10-13 02:18:58 +0200
committerGitHub <noreply@github.com>2022-10-13 02:18:58 +0200
commit06f74bd7d1d13de41e46c7a86bb12a8f21f8395d (patch)
tree3dcb794b67189e520942dacd893512884a2a9e15 /Source/Core
parent304e1e5b9fb6fe839d04a58cafe3e26df412f32d (diff)
parent3939b32ed6158b700cbbb79d0bad7ef62f563c8b (diff)
Merge pull request #11152 from jordan-woyak/wm-emu-ir-point-size
WiimoteEmu: Improve simulated IR point size accuracy.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/HW/WiimoteEmu/Camera.cpp25
1 files changed, 15 insertions, 10 deletions
diff --git a/Source/Core/Core/HW/WiimoteEmu/Camera.cpp b/Source/Core/Core/HW/WiimoteEmu/Camera.cpp
index 854c9e8577..fb79f12702 100644
--- a/Source/Core/Core/HW/WiimoteEmu/Camera.cpp
+++ b/Source/Core/Core/HW/WiimoteEmu/Camera.cpp
@@ -75,19 +75,24 @@ CameraLogic::GetCameraPoints(const Common::Matrix44& transform, Common::Vec2 fie
const auto point = camera_view * Vec4(v, 1.0);
// Check if LED is behind camera.
- if (point.z > 0)
- {
- // FYI: Casting down vs. rounding seems to produce more symmetrical output.
- const auto x = s32((1 - point.x / point.w) * CAMERA_RES_X / 2);
- const auto y = s32((1 - point.y / point.w) * CAMERA_RES_Y / 2);
+ if (point.z < 0)
+ return CameraPoint();
- const auto point_size = std::lround(MAX_POINT_SIZE / point.w / 2);
+ // FYI: truncating vs. rounding seems to produce more symmetrical cursor positioning.
+ const auto x = s32((1 - point.x / point.w) * CAMERA_RES_X / 2);
+ const auto y = s32((1 - point.y / point.w) * CAMERA_RES_Y / 2);
- if (x >= 0 && y >= 0 && x < CAMERA_RES_X && y < CAMERA_RES_Y)
- return CameraPoint({u16(x), u16(y)}, u8(point_size));
- }
+ // Check if LED is outside of view.
+ if (x < 0 || y < 0 || x >= CAMERA_RES_X || y >= CAMERA_RES_Y)
+ return CameraPoint();
+
+ // Curve fit from data using an official WM+ and sensor bar at middle "sensitivity".
+ // Point sizes at minimum and maximum sensitivity differ by around 0.5 (not implemented).
+ const auto point_size = 2.37f * std::pow(point.z, -0.778f);
+
+ const auto clamped_point_size = std::clamp<s32>(std::lround(point_size), 1, MAX_POINT_SIZE);
- return CameraPoint();
+ return CameraPoint({u16(x), u16(y)}, u8(clamped_point_size));
});
return camera_points;