From b673857d7dfc72f38d9242b315cd590b859795ff Mon Sep 17 00:00:00 2001 From: german77 Date: Sat, 13 Nov 2021 23:25:45 -0600 Subject: core/hid: Improve accuracy of the keyboard implementation --- src/core/hle/service/hid/controllers/keyboard.cpp | 1 + src/core/hle/service/hid/hid.cpp | 35 ++++++++++++++++++++--- src/core/hle/service/hid/hid.h | 2 ++ 3 files changed, 34 insertions(+), 4 deletions(-) (limited to 'src/core/hle/service/hid') diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp index d6505dbc5..0ef8af0e6 100644 --- a/src/core/hle/service/hid/controllers/keyboard.cpp +++ b/src/core/hle/service/hid/controllers/keyboard.cpp @@ -42,6 +42,7 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing, next_state.key = keyboard_state; next_state.modifier = keyboard_modifier_state; + // This is always enabled on HW. Check what it actually does next_state.modifier.unknown.Assign(1); } diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 496b55d0e..e740b4331 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -35,8 +35,9 @@ namespace Service::HID { // Updating period for each HID device. // Period time is obtained by measuring the number of samples in a second on HW using a homebrew -constexpr auto pad_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 250Hz) -constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz) +constexpr auto pad_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 250Hz) +constexpr auto keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz) +constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz) constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; IAppletResource::IAppletResource(Core::System& system_, @@ -78,14 +79,21 @@ IAppletResource::IAppletResource(Core::System& system_, const auto guard = LockService(); UpdateControllers(user_data, ns_late); }); + keyboard_update_event = Core::Timing::CreateEvent( + "HID::UpdatekeyboardCallback", + [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { + const auto guard = LockService(); + UpdateKeyboard(user_data, ns_late); + }); motion_update_event = Core::Timing::CreateEvent( - "HID::MotionPadCallback", + "HID::UpdateMotionCallback", [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { const auto guard = LockService(); UpdateMotion(user_data, ns_late); }); system.CoreTiming().ScheduleEvent(pad_update_ns, pad_update_event); + system.CoreTiming().ScheduleEvent(keyboard_update_ns, keyboard_update_event); system.CoreTiming().ScheduleEvent(motion_update_ns, motion_update_event); system.HIDCore().ReloadInputDevices(); @@ -101,6 +109,7 @@ void IAppletResource::DeactivateController(HidController controller) { IAppletResource::~IAppletResource() { system.CoreTiming().UnscheduleEvent(pad_update_event, 0); + system.CoreTiming().UnscheduleEvent(keyboard_update_event, 0); system.CoreTiming().UnscheduleEvent(motion_update_event, 0); } @@ -117,18 +126,36 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data, auto& core_timing = system.CoreTiming(); for (const auto& controller : controllers) { + // Keyboard has it's own update event + if (controller == controllers[static_cast(HidController::Keyboard)]) { + continue; + } controller->OnUpdate(core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE); } // If ns_late is higher than the update rate ignore the delay - if (ns_late > motion_update_ns) { + if (ns_late > pad_update_ns) { ns_late = {}; } core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event); } +void IAppletResource::UpdateKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { + auto& core_timing = system.CoreTiming(); + + controllers[static_cast(HidController::Keyboard)]->OnUpdate( + core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE); + + // If ns_late is higher than the update rate ignore the delay + if (ns_late > keyboard_update_ns) { + ns_late = {}; + } + + core_timing.ScheduleEvent(keyboard_update_ns - ns_late, keyboard_update_event); +} + void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { auto& core_timing = system.CoreTiming(); diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 973e6a8ac..bbad165f8 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -70,11 +70,13 @@ private: void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); + void UpdateKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); KernelHelpers::ServiceContext& service_context; std::shared_ptr pad_update_event; + std::shared_ptr keyboard_update_event; std::shared_ptr motion_update_event; std::array, static_cast(HidController::MaxControllers)> -- cgit v1.2.3