From 3b25426bd95423f74bca25145c67e350d3745d5a Mon Sep 17 00:00:00 2001
From: Zach Hilman <zachhilman@gmail.com>
Date: Thu, 1 Nov 2018 22:01:59 -0400
Subject: [PATCH] hid: Add controller bindings for Mouse controller

---
 .../hle/service/hid/controllers/mouse.cpp     | 25 ++++++++++++++++---
 src/core/hle/service/hid/controllers/mouse.h  |  9 ++++++-
 2 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp
index 4e246a57d..63391dbe9 100644
--- a/src/core/hle/service/hid/controllers/mouse.cpp
+++ b/src/core/hle/service/hid/controllers/mouse.cpp
@@ -5,6 +5,7 @@
 #include <cstring>
 #include "common/common_types.h"
 #include "core/core_timing.h"
+#include "core/frontend/emu_window.h"
 #include "core/hle/service/hid/controllers/mouse.h"
 
 namespace Service::HID {
@@ -14,7 +15,6 @@ Controller_Mouse::Controller_Mouse() = default;
 Controller_Mouse::~Controller_Mouse() = default;
 
 void Controller_Mouse::OnInit() {}
-
 void Controller_Mouse::OnRelease() {}
 
 void Controller_Mouse::OnUpdate(u8* data, std::size_t size) {
@@ -34,10 +34,29 @@ void Controller_Mouse::OnUpdate(u8* data, std::size_t size) {
 
     cur_entry.sampling_number = last_entry.sampling_number + 1;
     cur_entry.sampling_number2 = cur_entry.sampling_number;
-    // TODO(ogniK): Update mouse states
+
+    if (Settings::values.mouse_enabled) {
+        const auto [px, py, sx, sy] = mouse_device->GetStatus();
+        const auto x = static_cast<s32>(px * Layout::ScreenUndocked::Width);
+        const auto y = static_cast<s32>(py * Layout::ScreenUndocked::Height);
+        cur_entry.x = x;
+        cur_entry.y = y;
+        cur_entry.delta_x = x - last_entry.x;
+        cur_entry.delta_y = y - last_entry.y;
+        cur_entry.mouse_wheel_x = sx;
+        cur_entry.mouse_wheel_y = sy;
+
+        for (std::size_t i = 0; i < mouse_button_devices.size(); ++i) {
+            cur_entry.button |= (mouse_button_devices[i]->GetStatus() << i);
+        }
+    }
 
     std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory));
 }
 
-void Controller_Mouse::OnLoadInputDevices() {}
+void Controller_Mouse::OnLoadInputDevices() {
+    mouse_device = Input::CreateDevice<Input::MouseDevice>(Settings::values.mouse_device);
+    std::transform(Settings::values.mouse_buttons.begin(), Settings::values.mouse_buttons.end(),
+                   mouse_button_devices.begin(), Input::CreateDevice<Input::ButtonDevice>);
+}
 } // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h
index 543b0b71f..70b654d07 100644
--- a/src/core/hle/service/hid/controllers/mouse.h
+++ b/src/core/hle/service/hid/controllers/mouse.h
@@ -7,7 +7,9 @@
 #include <array>
 #include "common/common_types.h"
 #include "common/swap.h"
+#include "core/frontend/input.h"
 #include "core/hle/service/hid/controllers/controller_base.h"
+#include "core/settings.h"
 
 namespace Service::HID {
 class Controller_Mouse final : public ControllerBase {
@@ -35,7 +37,8 @@ private:
         s32_le y;
         s32_le delta_x;
         s32_le delta_y;
-        s32_le mouse_wheel;
+        s32_le mouse_wheel_x;
+        s32_le mouse_wheel_y;
         s32_le button;
         s32_le attribute;
     };
@@ -46,5 +49,9 @@ private:
         std::array<MouseState, 17> mouse_states;
     };
     SharedMemory shared_memory{};
+
+    std::unique_ptr<Input::MouseDevice> mouse_device;
+    std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeMouseButton::NumMouseButtons>
+        mouse_button_devices;
 };
 } // namespace Service::HID