From d61b26b79f889603a084e148626bba3c267cf75f Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 9 Mar 2015 00:14:59 -0400 Subject: HID: Complete refactor of pad/touch input to fix threading issues. --- src/core/hle/service/hid/hid.cpp | 104 +++++++++------------------------------ 1 file changed, 23 insertions(+), 81 deletions(-) (limited to 'src/core/hle/service/hid/hid.cpp') diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 703a765b..baff9271 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -12,6 +12,8 @@ #include "core/hle/kernel/shared_memory.h" #include "core/hle/hle.h" +#include "video_core/video_core.h" + namespace Service { namespace HID { @@ -23,15 +25,8 @@ Kernel::SharedPtr g_event_accelerometer; Kernel::SharedPtr g_event_gyroscope; Kernel::SharedPtr g_event_debug_pad; -// Next Pad state update information -static PadState next_state = {{0}}; static u32 next_pad_index = 0; -static s16 next_pad_circle_x = 0; -static s16 next_pad_circle_y = 0; - static u32 next_touch_index = 0; -static u16 next_touch_x = 0; -static u16 next_touch_y = 0; /** * Gets a pointer to the PadData structure inside HID shared memory @@ -55,38 +50,15 @@ static inline SharedMem* GetSharedMem() { // * Set PadData.current_state.circle_left = 1 if current PadEntry.circle_pad_x <= -41 // * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_y <= -41 -/** - * Circle Pad from keys. - * - * This is implemented as "pushed all the way to an edge (max) or centered (0)". - * - * Indicate the circle pad is pushed completely to the edge in 1 of 8 directions. - */ -static void UpdateNextCirclePadState() { - static const s16 max_value = 0x9C; - next_pad_circle_x = next_state.circle_left ? -max_value : 0x0; - next_pad_circle_x += next_state.circle_right ? max_value : 0x0; - next_pad_circle_y = next_state.circle_down ? -max_value : 0x0; - next_pad_circle_y += next_state.circle_up ? max_value : 0x0; -} - -void PadButtonPress(const PadState& pad_state) { - next_state.hex |= pad_state.hex; - UpdateNextCirclePadState(); -} - -void PadButtonRelease(const PadState& pad_state) { - next_state.hex &= ~pad_state.hex; - UpdateNextCirclePadState(); -} - -void PadUpdateComplete() { +void HIDUpdate() { SharedMem* shared_mem = GetSharedMem(); if (shared_mem == nullptr) return; - shared_mem->pad.current_state.hex = next_state.hex; + const PadState& state = VideoCore::g_emu_window->GetPadState(); + + shared_mem->pad.current_state.hex = state.hex; shared_mem->pad.index = next_pad_index; ++next_touch_index %= shared_mem->pad.entries.size(); @@ -95,28 +67,19 @@ void PadUpdateComplete() { PadState old_state = shared_mem->pad.entries[last_entry_index].current_state; // Compute bitmask with 1s for bits different from the old state - PadState changed; - changed.hex = (next_state.hex ^ old_state.hex); - - // Compute what was added - PadState additions; - additions.hex = changed.hex & next_state.hex; - - // Compute what was removed - PadState removals; - removals.hex = changed.hex & old_state.hex; + PadState changed = { { (state.hex ^ old_state.hex) } }; // Get the current Pad entry - PadDataEntry* current_pad_entry = &shared_mem->pad.entries[shared_mem->pad.index]; + PadDataEntry* pad_entry = &shared_mem->pad.entries[shared_mem->pad.index]; // Update entry properties - current_pad_entry->current_state.hex = next_state.hex; - current_pad_entry->delta_additions.hex = additions.hex; - current_pad_entry->delta_removals.hex = removals.hex; + pad_entry->current_state.hex = state.hex; + pad_entry->delta_additions.hex = changed.hex & state.hex; + pad_entry->delta_removals.hex = changed.hex & old_state.hex;; // Set circle Pad - current_pad_entry->circle_pad_x = next_pad_circle_x; - current_pad_entry->circle_pad_y = next_pad_circle_y; + pad_entry->circle_pad_x = state.circle_left ? -0x9C : state.circle_right ? 0x9C : 0x0; + pad_entry->circle_pad_y = state.circle_down ? -0x9C : state.circle_up ? 0x9C : 0x0; // If we just updated index 0, provide a new timestamp if (shared_mem->pad.index == 0) { @@ -124,39 +87,15 @@ void PadUpdateComplete() { shared_mem->pad.index_reset_ticks = (s64)Core::g_app_core->GetTicks(); } - // Signal both handles when there's an update to Pad or touch - g_event_pad_or_touch_1->Signal(); - g_event_pad_or_touch_2->Signal(); -} - -void TouchPress(u16 x, u16 y) { - next_touch_x = x; - next_touch_y = y; -} - -void TouchRelease() { - next_touch_x = 0; - next_touch_y = 0; -} - -void TouchUpdateComplete() { - SharedMem* shared_mem = GetSharedMem(); - - if (shared_mem == nullptr) - return; - shared_mem->touch.index = next_touch_index; ++next_touch_index %= shared_mem->touch.entries.size(); // Get the current touch entry - TouchDataEntry* current_touch_entry = &shared_mem->touch.entries[shared_mem->touch.index]; + TouchDataEntry* touch_entry = &shared_mem->touch.entries[shared_mem->touch.index]; + bool pressed = false; - // Set touchpad position - current_touch_entry->x = next_touch_x; - current_touch_entry->y = next_touch_y; - - // TODO(bunnei): Verify this behavior on real hardware - current_touch_entry->valid = (next_touch_x || next_touch_y) ? 1 : 0; + std::tie(touch_entry->x, touch_entry->y, pressed) = VideoCore::g_emu_window->GetTouchState(); + touch_entry->valid = pressed ? 1 : 0; // TODO(bunnei): We're not doing anything with offset 0xA8 + 0x18 of HID SharedMemory, which // supposedly is "Touch-screen entry, which contains the raw coordinate data prior to being @@ -194,6 +133,9 @@ void HIDInit() { g_shared_mem = SharedMemory::Create("HID:SharedMem"); + next_pad_index = 0; + next_touch_index = 0; + // Create event handles g_event_pad_or_touch_1 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch1"); g_event_pad_or_touch_2 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch2"); @@ -203,8 +145,8 @@ void HIDInit() { } void HIDShutdown() { - } -} -} +} // namespace HID + +} // namespace Service -- cgit v1.2.3