summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hid/emulated_devices.cpp10
-rw-r--r--src/core/hid/emulated_devices.h4
-rw-r--r--src/core/hid/hid_types.h35
-rw-r--r--src/core/hid/input_converter.cpp4
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.cpp3
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.h1
-rw-r--r--src/core/hle/service/hid/controllers/mouse.cpp7
-rw-r--r--src/core/hle/service/hid/controllers/mouse.h2
-rw-r--r--src/core/hle/service/hid/hid.cpp29
-rw-r--r--src/core/hle/service/hid/hid.h4
-rw-r--r--src/input_common/drivers/mouse.cpp21
-rw-r--r--src/input_common/drivers/mouse.h1
-rw-r--r--src/yuzu/bootmanager.cpp4
-rw-r--r--src/yuzu/configuration/configure_input_advanced.cpp2
14 files changed, 79 insertions, 48 deletions
diff --git a/src/core/hid/emulated_devices.cpp b/src/core/hid/emulated_devices.cpp
index 70a494097..874780ec2 100644
--- a/src/core/hid/emulated_devices.cpp
+++ b/src/core/hid/emulated_devices.cpp
@@ -376,9 +376,9 @@ void EmulatedDevices::SetMouseAnalog(Common::Input::CallbackStatus callback, std
376 376
377void EmulatedDevices::SetMouseStick(Common::Input::CallbackStatus callback) { 377void EmulatedDevices::SetMouseStick(Common::Input::CallbackStatus callback) {
378 std::lock_guard lock{mutex}; 378 std::lock_guard lock{mutex};
379 const auto stick_value = TransformToStick(callback); 379 const auto touch_value = TransformToTouch(callback);
380 380
381 device_status.mouse_stick_value = stick_value; 381 device_status.mouse_stick_value = touch_value;
382 382
383 if (is_configuring) { 383 if (is_configuring) {
384 device_status.mouse_position_state = {}; 384 device_status.mouse_position_state = {};
@@ -386,8 +386,8 @@ void EmulatedDevices::SetMouseStick(Common::Input::CallbackStatus callback) {
386 return; 386 return;
387 } 387 }
388 388
389 device_status.mouse_position_state.x = stick_value.x.value; 389 device_status.mouse_position_state.x = touch_value.x.value;
390 device_status.mouse_position_state.y = stick_value.y.value; 390 device_status.mouse_position_state.y = touch_value.y.value;
391 391
392 TriggerOnChange(DeviceTriggerType::Mouse); 392 TriggerOnChange(DeviceTriggerType::Mouse);
393} 393}
@@ -420,7 +420,7 @@ MousePosition EmulatedDevices::GetMousePosition() const {
420 return device_status.mouse_position_state; 420 return device_status.mouse_position_state;
421} 421}
422 422
423AnalogStickState EmulatedDevices::GetMouseDeltaWheel() const { 423AnalogStickState EmulatedDevices::GetMouseWheel() const {
424 return device_status.mouse_wheel_state; 424 return device_status.mouse_wheel_state;
425} 425}
426 426
diff --git a/src/core/hid/emulated_devices.h b/src/core/hid/emulated_devices.h
index 49edfd255..05a945d08 100644
--- a/src/core/hid/emulated_devices.h
+++ b/src/core/hid/emulated_devices.h
@@ -38,7 +38,7 @@ using MouseButtonValues =
38 std::array<Common::Input::ButtonStatus, Settings::NativeMouseButton::NumMouseButtons>; 38 std::array<Common::Input::ButtonStatus, Settings::NativeMouseButton::NumMouseButtons>;
39using MouseAnalogValues = 39using MouseAnalogValues =
40 std::array<Common::Input::AnalogStatus, Settings::NativeMouseWheel::NumMouseWheels>; 40 std::array<Common::Input::AnalogStatus, Settings::NativeMouseWheel::NumMouseWheels>;
41using MouseStickValue = Common::Input::StickStatus; 41using MouseStickValue = Common::Input::TouchStatus;
42 42
43struct MousePosition { 43struct MousePosition {
44 f32 x; 44 f32 x;
@@ -130,7 +130,7 @@ public:
130 MousePosition GetMousePosition() const; 130 MousePosition GetMousePosition() const;
131 131
132 /// Returns the latest mouse wheel change 132 /// Returns the latest mouse wheel change
133 AnalogStickState GetMouseDeltaWheel() const; 133 AnalogStickState GetMouseWheel() const;
134 134
135 /** 135 /**
136 * Adds a callback to the list of events 136 * Adds a callback to the list of events
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h
index af95f3aff..8b12f63ad 100644
--- a/src/core/hid/hid_types.h
+++ b/src/core/hid/hid_types.h
@@ -502,21 +502,30 @@ static_assert(sizeof(VibrationDeviceInfo) == 0x8, "VibrationDeviceInfo has incor
502// This is nn::hid::KeyboardModifier 502// This is nn::hid::KeyboardModifier
503struct KeyboardModifier { 503struct KeyboardModifier {
504 union { 504 union {
505 u64 raw{}; 505 u32 raw{};
506 BitField<0, 1, u64> control; 506 BitField<0, 1, u32> control;
507 BitField<1, 1, u64> shift; 507 BitField<1, 1, u32> shift;
508 BitField<2, 1, u64> left_alt; 508 BitField<2, 1, u32> left_alt;
509 BitField<3, 1, u64> right_alt; 509 BitField<3, 1, u32> right_alt;
510 BitField<4, 1, u64> gui; 510 BitField<4, 1, u32> gui;
511 BitField<8, 1, u64> caps_lock; 511 BitField<8, 1, u32> caps_lock;
512 BitField<9, 1, u64> scroll_lock; 512 BitField<9, 1, u32> scroll_lock;
513 BitField<10, 1, u64> num_lock; 513 BitField<10, 1, u32> num_lock;
514 BitField<11, 1, u64> katakana; 514 BitField<11, 1, u32> katakana;
515 BitField<12, 1, u64> hiragana; 515 BitField<12, 1, u32> hiragana;
516 BitField<32, 1, u64> unknown; 516 };
517};
518
519static_assert(sizeof(KeyboardModifier) == 0x4, "KeyboardModifier is an invalid size");
520
521// This is nn::hid::KeyboardAttribute
522struct KeyboardAttribute {
523 union {
524 u32 raw{};
525 BitField<0, 1, u32> is_connected;
517 }; 526 };
518}; 527};
519static_assert(sizeof(KeyboardModifier) == 0x8, "KeyboardModifier is an invalid size"); 528static_assert(sizeof(KeyboardAttribute) == 0x4, "KeyboardAttribute is an invalid size");
520 529
521// This is nn::hid::KeyboardKey 530// This is nn::hid::KeyboardKey
522struct KeyboardKey { 531struct KeyboardKey {
diff --git a/src/core/hid/input_converter.cpp b/src/core/hid/input_converter.cpp
index c4e653956..f5acff6e0 100644
--- a/src/core/hid/input_converter.cpp
+++ b/src/core/hid/input_converter.cpp
@@ -175,6 +175,10 @@ Common::Input::TouchStatus TransformToTouch(const Common::Input::CallbackStatus&
175 case Common::Input::InputType::Touch: 175 case Common::Input::InputType::Touch:
176 status = callback.touch_status; 176 status = callback.touch_status;
177 break; 177 break;
178 case Common::Input::InputType::Stick:
179 status.x = callback.stick_status.x;
180 status.y = callback.stick_status.y;
181 break;
178 default: 182 default:
179 LOG_ERROR(Input, "Conversion from type {} to touch not implemented", callback.type); 183 LOG_ERROR(Input, "Conversion from type {} to touch not implemented", callback.type);
180 break; 184 break;
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp
index 0ef8af0e6..9588a6910 100644
--- a/src/core/hle/service/hid/controllers/keyboard.cpp
+++ b/src/core/hle/service/hid/controllers/keyboard.cpp
@@ -42,8 +42,7 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing,
42 42
43 next_state.key = keyboard_state; 43 next_state.key = keyboard_state;
44 next_state.modifier = keyboard_modifier_state; 44 next_state.modifier = keyboard_modifier_state;
45 // This is always enabled on HW. Check what it actually does 45 next_state.attribute.is_connected.Assign(1);
46 next_state.modifier.unknown.Assign(1);
47 } 46 }
48 47
49 keyboard_lifo.WriteNextEntry(next_state); 48 keyboard_lifo.WriteNextEntry(next_state);
diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h
index ec5dd607c..0d61cb470 100644
--- a/src/core/hle/service/hid/controllers/keyboard.h
+++ b/src/core/hle/service/hid/controllers/keyboard.h
@@ -38,6 +38,7 @@ private:
38 struct KeyboardState { 38 struct KeyboardState {
39 s64 sampling_number; 39 s64 sampling_number;
40 Core::HID::KeyboardModifier modifier; 40 Core::HID::KeyboardModifier modifier;
41 Core::HID::KeyboardAttribute attribute;
41 Core::HID::KeyboardKey key; 42 Core::HID::KeyboardKey key;
42 }; 43 };
43 static_assert(sizeof(KeyboardState) == 0x30, "KeyboardState is an invalid size"); 44 static_assert(sizeof(KeyboardState) == 0x30, "KeyboardState is an invalid size");
diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp
index 9c408e7f4..ba79888ae 100644
--- a/src/core/hle/service/hid/controllers/mouse.cpp
+++ b/src/core/hle/service/hid/controllers/mouse.cpp
@@ -38,15 +38,16 @@ void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
38 if (Settings::values.mouse_enabled) { 38 if (Settings::values.mouse_enabled) {
39 const auto& mouse_button_state = emulated_devices->GetMouseButtons(); 39 const auto& mouse_button_state = emulated_devices->GetMouseButtons();
40 const auto& mouse_position_state = emulated_devices->GetMousePosition(); 40 const auto& mouse_position_state = emulated_devices->GetMousePosition();
41 const auto& mouse_wheel_state = emulated_devices->GetMouseDeltaWheel(); 41 const auto& mouse_wheel_state = emulated_devices->GetMouseWheel();
42 next_state.attribute.is_connected.Assign(1); 42 next_state.attribute.is_connected.Assign(1);
43 next_state.x = static_cast<s32>(mouse_position_state.x * Layout::ScreenUndocked::Width); 43 next_state.x = static_cast<s32>(mouse_position_state.x * Layout::ScreenUndocked::Width);
44 next_state.y = static_cast<s32>(mouse_position_state.y * Layout::ScreenUndocked::Height); 44 next_state.y = static_cast<s32>(mouse_position_state.y * Layout::ScreenUndocked::Height);
45 next_state.delta_x = next_state.x - last_entry.x; 45 next_state.delta_x = next_state.x - last_entry.x;
46 next_state.delta_y = next_state.y - last_entry.y; 46 next_state.delta_y = next_state.y - last_entry.y;
47 next_state.delta_wheel_x = mouse_wheel_state.x; 47 next_state.delta_wheel_x = mouse_wheel_state.x - last_mouse_wheel_state.x;
48 next_state.delta_wheel_y = mouse_wheel_state.y; 48 next_state.delta_wheel_y = mouse_wheel_state.y - last_mouse_wheel_state.y;
49 49
50 last_mouse_wheel_state = mouse_wheel_state;
50 next_state.button = mouse_button_state; 51 next_state.button = mouse_button_state;
51 } 52 }
52 53
diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h
index 25017f117..1ac69aa6f 100644
--- a/src/core/hle/service/hid/controllers/mouse.h
+++ b/src/core/hle/service/hid/controllers/mouse.h
@@ -14,6 +14,7 @@
14namespace Core::HID { 14namespace Core::HID {
15class EmulatedDevices; 15class EmulatedDevices;
16struct MouseState; 16struct MouseState;
17struct AnalogStickState;
17} // namespace Core::HID 18} // namespace Core::HID
18 19
19namespace Service::HID { 20namespace Service::HID {
@@ -37,6 +38,7 @@ private:
37 static_assert(sizeof(mouse_lifo) == 0x350, "mouse_lifo is an invalid size"); 38 static_assert(sizeof(mouse_lifo) == 0x350, "mouse_lifo is an invalid size");
38 Core::HID::MouseState next_state{}; 39 Core::HID::MouseState next_state{};
39 40
41 Core::HID::AnalogStickState last_mouse_wheel_state;
40 Core::HID::EmulatedDevices* emulated_devices; 42 Core::HID::EmulatedDevices* emulated_devices;
41}; 43};
42} // namespace Service::HID 44} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index e740b4331..95fc07325 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -35,9 +35,9 @@ namespace Service::HID {
35 35
36// Updating period for each HID device. 36// Updating period for each HID device.
37// Period time is obtained by measuring the number of samples in a second on HW using a homebrew 37// Period time is obtained by measuring the number of samples in a second on HW using a homebrew
38constexpr auto pad_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 250Hz) 38constexpr auto pad_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 250Hz)
39constexpr auto keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz) 39constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz)
40constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz) 40constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz)
41constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; 41constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
42 42
43IAppletResource::IAppletResource(Core::System& system_, 43IAppletResource::IAppletResource(Core::System& system_,
@@ -79,11 +79,11 @@ IAppletResource::IAppletResource(Core::System& system_,
79 const auto guard = LockService(); 79 const auto guard = LockService();
80 UpdateControllers(user_data, ns_late); 80 UpdateControllers(user_data, ns_late);
81 }); 81 });
82 keyboard_update_event = Core::Timing::CreateEvent( 82 mouse_keyboard_update_event = Core::Timing::CreateEvent(
83 "HID::UpdatekeyboardCallback", 83 "HID::UpdateMouseKeyboardCallback",
84 [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { 84 [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
85 const auto guard = LockService(); 85 const auto guard = LockService();
86 UpdateKeyboard(user_data, ns_late); 86 UpdateMouseKeyboard(user_data, ns_late);
87 }); 87 });
88 motion_update_event = Core::Timing::CreateEvent( 88 motion_update_event = Core::Timing::CreateEvent(
89 "HID::UpdateMotionCallback", 89 "HID::UpdateMotionCallback",
@@ -93,7 +93,7 @@ IAppletResource::IAppletResource(Core::System& system_,
93 }); 93 });
94 94
95 system.CoreTiming().ScheduleEvent(pad_update_ns, pad_update_event); 95 system.CoreTiming().ScheduleEvent(pad_update_ns, pad_update_event);
96 system.CoreTiming().ScheduleEvent(keyboard_update_ns, keyboard_update_event); 96 system.CoreTiming().ScheduleEvent(mouse_keyboard_update_ns, mouse_keyboard_update_event);
97 system.CoreTiming().ScheduleEvent(motion_update_ns, motion_update_event); 97 system.CoreTiming().ScheduleEvent(motion_update_ns, motion_update_event);
98 98
99 system.HIDCore().ReloadInputDevices(); 99 system.HIDCore().ReloadInputDevices();
@@ -109,7 +109,7 @@ void IAppletResource::DeactivateController(HidController controller) {
109 109
110IAppletResource::~IAppletResource() { 110IAppletResource::~IAppletResource() {
111 system.CoreTiming().UnscheduleEvent(pad_update_event, 0); 111 system.CoreTiming().UnscheduleEvent(pad_update_event, 0);
112 system.CoreTiming().UnscheduleEvent(keyboard_update_event, 0); 112 system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event, 0);
113 system.CoreTiming().UnscheduleEvent(motion_update_event, 0); 113 system.CoreTiming().UnscheduleEvent(motion_update_event, 0);
114} 114}
115 115
@@ -130,6 +130,10 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data,
130 if (controller == controllers[static_cast<size_t>(HidController::Keyboard)]) { 130 if (controller == controllers[static_cast<size_t>(HidController::Keyboard)]) {
131 continue; 131 continue;
132 } 132 }
133 // Mouse has it's own update event
134 if (controller == controllers[static_cast<size_t>(HidController::Mouse)]) {
135 continue;
136 }
133 controller->OnUpdate(core_timing, system.Kernel().GetHidSharedMem().GetPointer(), 137 controller->OnUpdate(core_timing, system.Kernel().GetHidSharedMem().GetPointer(),
134 SHARED_MEMORY_SIZE); 138 SHARED_MEMORY_SIZE);
135 } 139 }
@@ -142,18 +146,21 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data,
142 core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event); 146 core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event);
143} 147}
144 148
145void IAppletResource::UpdateKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { 149void IAppletResource::UpdateMouseKeyboard(std::uintptr_t user_data,
150 std::chrono::nanoseconds ns_late) {
146 auto& core_timing = system.CoreTiming(); 151 auto& core_timing = system.CoreTiming();
147 152
153 controllers[static_cast<size_t>(HidController::Mouse)]->OnUpdate(
154 core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE);
148 controllers[static_cast<size_t>(HidController::Keyboard)]->OnUpdate( 155 controllers[static_cast<size_t>(HidController::Keyboard)]->OnUpdate(
149 core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE); 156 core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE);
150 157
151 // If ns_late is higher than the update rate ignore the delay 158 // If ns_late is higher than the update rate ignore the delay
152 if (ns_late > keyboard_update_ns) { 159 if (ns_late > mouse_keyboard_update_ns) {
153 ns_late = {}; 160 ns_late = {};
154 } 161 }
155 162
156 core_timing.ScheduleEvent(keyboard_update_ns - ns_late, keyboard_update_event); 163 core_timing.ScheduleEvent(mouse_keyboard_update_ns - ns_late, mouse_keyboard_update_event);
157} 164}
158 165
159void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { 166void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index bbad165f8..ab0084118 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -70,13 +70,13 @@ private:
70 70
71 void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); 71 void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
72 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 72 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
73 void UpdateKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 73 void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
74 void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 74 void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
75 75
76 KernelHelpers::ServiceContext& service_context; 76 KernelHelpers::ServiceContext& service_context;
77 77
78 std::shared_ptr<Core::Timing::EventType> pad_update_event; 78 std::shared_ptr<Core::Timing::EventType> pad_update_event;
79 std::shared_ptr<Core::Timing::EventType> keyboard_update_event; 79 std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event;
80 std::shared_ptr<Core::Timing::EventType> motion_update_event; 80 std::shared_ptr<Core::Timing::EventType> motion_update_event;
81 81
82 std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)> 82 std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>
diff --git a/src/input_common/drivers/mouse.cpp b/src/input_common/drivers/mouse.cpp
index 478737db2..05fd7f9c0 100644
--- a/src/input_common/drivers/mouse.cpp
+++ b/src/input_common/drivers/mouse.cpp
@@ -39,7 +39,7 @@ void Mouse::UpdateThread(std::stop_token stop_token) {
39 Common::SetCurrentThreadName("yuzu:input:Mouse"); 39 Common::SetCurrentThreadName("yuzu:input:Mouse");
40 constexpr int update_time = 10; 40 constexpr int update_time = 10;
41 while (!stop_token.stop_requested()) { 41 while (!stop_token.stop_requested()) {
42 if (Settings::values.mouse_panning) { 42 if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) {
43 // Slow movement by 4% 43 // Slow movement by 4%
44 last_mouse_change *= 0.96f; 44 last_mouse_change *= 0.96f;
45 const float sensitivity = 45 const float sensitivity =
@@ -52,14 +52,17 @@ void Mouse::UpdateThread(std::stop_token stop_token) {
52 StopPanning(); 52 StopPanning();
53 } 53 }
54 std::this_thread::sleep_for(std::chrono::milliseconds(update_time)); 54 std::this_thread::sleep_for(std::chrono::milliseconds(update_time));
55
56 // Reset wheel position
57 SetAxis(identifier, wheel_axis_x, 0);
58 SetAxis(identifier, wheel_axis_y, 0);
59 } 55 }
60} 56}
61 57
62void Mouse::MouseMove(int x, int y, f32 touch_x, f32 touch_y, int center_x, int center_y) { 58void Mouse::MouseMove(int x, int y, f32 touch_x, f32 touch_y, int center_x, int center_y) {
59 // If native mouse is enabled just set the screen coordinates
60 if (Settings::values.mouse_enabled) {
61 SetAxis(identifier, mouse_axis_x, touch_x);
62 SetAxis(identifier, mouse_axis_y, touch_y);
63 return;
64 }
65
63 SetAxis(identifier, touch_axis_x, touch_x); 66 SetAxis(identifier, touch_axis_x, touch_x);
64 SetAxis(identifier, touch_axis_y, touch_y); 67 SetAxis(identifier, touch_axis_y, touch_y);
65 68
@@ -121,7 +124,7 @@ void Mouse::PressButton(int x, int y, f32 touch_x, f32 touch_y, MouseButton butt
121void Mouse::ReleaseButton(MouseButton button) { 124void Mouse::ReleaseButton(MouseButton button) {
122 SetButton(identifier, static_cast<int>(button), false); 125 SetButton(identifier, static_cast<int>(button), false);
123 126
124 if (!Settings::values.mouse_panning) { 127 if (!Settings::values.mouse_panning && !Settings::values.mouse_enabled) {
125 SetAxis(identifier, mouse_axis_x, 0); 128 SetAxis(identifier, mouse_axis_x, 0);
126 SetAxis(identifier, mouse_axis_y, 0); 129 SetAxis(identifier, mouse_axis_y, 0);
127 } 130 }
@@ -129,8 +132,10 @@ void Mouse::ReleaseButton(MouseButton button) {
129} 132}
130 133
131void Mouse::MouseWheelChange(int x, int y) { 134void Mouse::MouseWheelChange(int x, int y) {
132 SetAxis(identifier, wheel_axis_x, static_cast<f32>(x)); 135 wheel_position.x += x;
133 SetAxis(identifier, wheel_axis_y, static_cast<f32>(y)); 136 wheel_position.y += y;
137 SetAxis(identifier, wheel_axis_x, static_cast<f32>(wheel_position.x));
138 SetAxis(identifier, wheel_axis_y, static_cast<f32>(wheel_position.y));
134} 139}
135 140
136void Mouse::ReleaseAllButtons() { 141void Mouse::ReleaseAllButtons() {
diff --git a/src/input_common/drivers/mouse.h b/src/input_common/drivers/mouse.h
index 429502af9..f7e6db0b5 100644
--- a/src/input_common/drivers/mouse.h
+++ b/src/input_common/drivers/mouse.h
@@ -72,6 +72,7 @@ private:
72 Common::Vec2<int> mouse_origin; 72 Common::Vec2<int> mouse_origin;
73 Common::Vec2<int> last_mouse_position; 73 Common::Vec2<int> last_mouse_position;
74 Common::Vec2<float> last_mouse_change; 74 Common::Vec2<float> last_mouse_change;
75 Common::Vec2<int> wheel_position;
75 bool button_pressed; 76 bool button_pressed;
76 int mouse_panning_timout{}; 77 int mouse_panning_timout{};
77 std::jthread update_thread; 78 std::jthread update_thread;
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index 1015e51b5..2313a4189 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -729,7 +729,7 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
729 const int center_y = height() / 2; 729 const int center_y = height() / 2;
730 input_subsystem->GetMouse()->MouseMove(x, y, touch_x, touch_y, center_x, center_y); 730 input_subsystem->GetMouse()->MouseMove(x, y, touch_x, touch_y, center_x, center_y);
731 731
732 if (Settings::values.mouse_panning) { 732 if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) {
733 QCursor::setPos(mapToGlobal({center_x, center_y})); 733 QCursor::setPos(mapToGlobal({center_x, center_y}));
734 } 734 }
735 735
@@ -1044,7 +1044,7 @@ void GRenderWindow::showEvent(QShowEvent* event) {
1044 1044
1045bool GRenderWindow::eventFilter(QObject* object, QEvent* event) { 1045bool GRenderWindow::eventFilter(QObject* object, QEvent* event) {
1046 if (event->type() == QEvent::HoverMove) { 1046 if (event->type() == QEvent::HoverMove) {
1047 if (Settings::values.mouse_panning) { 1047 if (Settings::values.mouse_panning || Settings::values.mouse_enabled) {
1048 auto* hover_event = static_cast<QMouseEvent*>(event); 1048 auto* hover_event = static_cast<QMouseEvent*>(event);
1049 mouseMoveEvent(hover_event); 1049 mouseMoveEvent(hover_event);
1050 return false; 1050 return false;
diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp
index cf8aad4ab..e6127f9e6 100644
--- a/src/yuzu/configuration/configure_input_advanced.cpp
+++ b/src/yuzu/configuration/configure_input_advanced.cpp
@@ -179,4 +179,6 @@ void ConfigureInputAdvanced::RetranslateUI() {
179void ConfigureInputAdvanced::UpdateUIEnabled() { 179void ConfigureInputAdvanced::UpdateUIEnabled() {
180 ui->debug_configure->setEnabled(ui->debug_enabled->isChecked()); 180 ui->debug_configure->setEnabled(ui->debug_enabled->isChecked());
181 ui->touchscreen_advanced->setEnabled(ui->touchscreen_enabled->isChecked()); 181 ui->touchscreen_advanced->setEnabled(ui->touchscreen_enabled->isChecked());
182 ui->mouse_panning->setEnabled(!ui->mouse_enabled->isChecked());
183 ui->mouse_panning_sensitivity->setEnabled(!ui->mouse_enabled->isChecked());
182} 184}