diff --git a/src/citron/bootmanager.cpp b/src/citron/bootmanager.cpp index b02b8f663..5cdedfb8a 100644 --- a/src/citron/bootmanager.cpp +++ b/src/citron/bootmanager.cpp @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: 2014 Citra Emulator Project +// SPDX-FileCopyrightText: 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include @@ -732,6 +733,7 @@ void GRenderWindow::ConstrainMouse() { void GRenderWindow::wheelEvent(QWheelEvent* event) { const int x = event->angleDelta().x(); const int y = event->angleDelta().y(); + LOG_DEBUG(Frontend, "GRenderWindow wheel event: x={}, y={}", x, y); input_subsystem->GetMouse()->MouseWheelChange(x, y); } diff --git a/src/citron_cmd/emu_window/emu_window_sdl2.cpp b/src/citron_cmd/emu_window/emu_window_sdl2.cpp index 9163d5707..24d371285 100644 --- a/src/citron_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/citron_cmd/emu_window/emu_window_sdl2.cpp @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: 2016 Citra Emulator Project +// SPDX-FileCopyrightText: 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include @@ -77,6 +78,11 @@ void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { input_subsystem->GetMouse()->TouchMove(touch_x, touch_y); } +void EmuWindow_SDL2::OnMouseWheel(s32 x, s32 y) { + input_subsystem->GetMouse()->MouseWheelChange(x, y); + LOG_DEBUG(Frontend, "SDL2 Mouse wheel event: x={}, y={}", x, y); +} + void EmuWindow_SDL2::OnFingerDown(float x, float y, std::size_t id) { input_subsystem->GetTouchScreen()->TouchPressed(x, y, id); } @@ -202,6 +208,9 @@ void EmuWindow_SDL2::WaitEvent() { OnMouseButton(event.button.button, event.button.state, event.button.x, event.button.y); } break; + case SDL_MOUSEWHEEL: + OnMouseWheel(event.wheel.x, event.wheel.y); + break; case SDL_FINGERDOWN: OnFingerDown(event.tfinger.x, event.tfinger.y, static_cast(event.tfinger.touchId)); diff --git a/src/citron_cmd/emu_window/emu_window_sdl2.h b/src/citron_cmd/emu_window/emu_window_sdl2.h index 71cfdc991..6362d3971 100644 --- a/src/citron_cmd/emu_window/emu_window_sdl2.h +++ b/src/citron_cmd/emu_window/emu_window_sdl2.h @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: 2016 Citra Emulator Project +// SPDX-FileCopyrightText: 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -52,6 +53,9 @@ protected: /// Called by WaitEvent when the mouse moves. void OnMouseMotion(s32 x, s32 y); + /// Called by WaitEvent when the mouse wheel is scrolled + void OnMouseWheel(s32 x, s32 y); + /// Called by WaitEvent when a finger starts touching the touchscreen void OnFingerDown(float x, float y, std::size_t id); diff --git a/src/hid_core/frontend/emulated_devices.cpp b/src/hid_core/frontend/emulated_devices.cpp index a827aa9b7..ffed9a277 100644 --- a/src/hid_core/frontend/emulated_devices.cpp +++ b/src/hid_core/frontend/emulated_devices.cpp @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include @@ -374,6 +375,7 @@ void EmulatedDevices::SetMouseWheel(const Common::Input::CallbackStatus& callbac const auto analog_value = TransformToAnalog(callback); device_status.mouse_wheel_values[index] = analog_value; + LOG_DEBUG(Input, "EmulatedDevices::SetMouseWheel: index={}, value={}", index, analog_value.value); if (is_configuring) { device_status.mouse_wheel_state = {}; @@ -455,6 +457,11 @@ AnalogStickState EmulatedDevices::GetMouseWheel() const { return device_status.mouse_wheel_state; } +void EmulatedDevices::ResetMouseWheel() { + std::scoped_lock lock{mutex}; + device_status.mouse_wheel_state = {}; +} + void EmulatedDevices::TriggerOnChange(DeviceTriggerType type) { std::scoped_lock lock{callback_mutex}; for (const auto& poller_pair : callback_list) { diff --git a/src/hid_core/frontend/emulated_devices.h b/src/hid_core/frontend/emulated_devices.h index a77558c56..08c077370 100644 --- a/src/hid_core/frontend/emulated_devices.h +++ b/src/hid_core/frontend/emulated_devices.h @@ -135,6 +135,9 @@ public: /// Returns the latest mouse wheel change AnalogStickState GetMouseWheel() const; + /// Resets the mouse wheel state (should be called each frame) + void ResetMouseWheel(); + /** * Adds a callback to the list of events * @param update_callback InterfaceUpdateCallback that will be triggered diff --git a/src/hid_core/resources/mouse/debug_mouse.cpp b/src/hid_core/resources/mouse/debug_mouse.cpp index 5f6f6e8e1..d6e4cab58 100644 --- a/src/hid_core/resources/mouse/debug_mouse.cpp +++ b/src/hid_core/resources/mouse/debug_mouse.cpp @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "core/core_timing.h" @@ -55,6 +56,9 @@ void DebugMouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) { next_state.delta_wheel_y = mouse_wheel_state.y - last_mouse_wheel_state.y; last_mouse_wheel_state = mouse_wheel_state; + + // Reset mouse wheel state after reading to ensure delta values work correctly + emulated_devices->ResetMouseWheel(); next_state.button = mouse_button_state; } diff --git a/src/hid_core/resources/mouse/mouse.cpp b/src/hid_core/resources/mouse/mouse.cpp index 53a8938a1..ac00f457e 100644 --- a/src/hid_core/resources/mouse/mouse.cpp +++ b/src/hid_core/resources/mouse/mouse.cpp @@ -55,6 +55,9 @@ void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) { next_state.delta_wheel_y = mouse_wheel_state.y - last_mouse_wheel_state.y; last_mouse_wheel_state = mouse_wheel_state; + + // Reset mouse wheel state after reading to ensure delta values work correctly + emulated_devices->ResetMouseWheel(); next_state.button = mouse_button_state; } diff --git a/src/input_common/drivers/mouse.cpp b/src/input_common/drivers/mouse.cpp index 9fb824baf..eb4bd4ef4 100644 --- a/src/input_common/drivers/mouse.cpp +++ b/src/input_common/drivers/mouse.cpp @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include @@ -235,6 +236,7 @@ void Mouse::MouseWheelChange(int x, int y) { wheel_position.x += x; wheel_position.y += y; last_motion_change.z += static_cast(y); + LOG_DEBUG(Input, "Mouse wheel change: x={}, y={}, wheel_pos=({}, {})", x, y, wheel_position.x, wheel_position.y); SetAxis(identifier, wheel_axis_x, static_cast(wheel_position.x)); SetAxis(identifier, wheel_axis_y, static_cast(wheel_position.y)); }