From 83a66dd701789761c118c7e105327a1b6166ed13 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 8 Mar 2015 00:12:47 -0500 Subject: HID: Refactored shared memory decoding for touchpad support. --- src/core/hle/service/hid/hid.cpp | 51 +++++++++++++++++++++++----------------- src/core/hle/service/hid/hid.h | 46 ++++++++++++++++++++++++++---------- 2 files changed, 64 insertions(+), 33 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index e0689be2e..c21799db6 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -25,17 +25,17 @@ Kernel::SharedPtr g_event_debug_pad; // Next Pad state update information static PadState next_state = {{0}}; -static u32 next_index = 0; -static s16 next_circle_x = 0; -static s16 next_circle_y = 0; +static u32 next_pad_index = 0; +static s16 next_pad_circle_x = 0; +static s16 next_pad_circle_y = 0; /** * Gets a pointer to the PadData structure inside HID shared memory */ -static inline PadData* GetPadData() { +static inline SharedMem* GetPadData() { if (g_shared_mem == nullptr) return nullptr; - return reinterpret_cast(g_shared_mem->GetPointer().ValueOr(nullptr)); + return reinterpret_cast(g_shared_mem->GetPointer().ValueOr(nullptr)); } // TODO(peachum): @@ -60,10 +60,10 @@ static inline PadData* GetPadData() { */ static void UpdateNextCirclePadState() { static const s16 max_value = 0x9C; - next_circle_x = next_state.circle_left ? -max_value : 0x0; - next_circle_x += next_state.circle_right ? max_value : 0x0; - next_circle_y = next_state.circle_down ? -max_value : 0x0; - next_circle_y += next_state.circle_up ? max_value : 0x0; + 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; } /** @@ -87,20 +87,18 @@ void PadButtonRelease(const PadState& pad_state) { * including both Pad key changes and analog circle Pad changes. */ void PadUpdateComplete() { - PadData* pad_data = GetPadData(); + SharedMem* shared_mem = GetPadData(); - if (pad_data == nullptr) { + if (shared_mem == nullptr) return; - } - // Update PadData struct - pad_data->current_state.hex = next_state.hex; - pad_data->index = next_index; - next_index = (next_index + 1) % pad_data->entries.size(); + shared_mem->pad.current_state.hex = next_state.hex; + shared_mem->pad.index = next_pad_index; + next_pad_index = (next_pad_index + 1) % shared_mem->pad.entries.size(); // Get the previous Pad state - u32 last_entry_index = (pad_data->index - 1) % pad_data->entries.size(); - PadState old_state = pad_data->entries[last_entry_index].current_state; + u32 last_entry_index = (shared_mem->pad.index - 1) % shared_mem->pad.entries.size(); + 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; @@ -115,7 +113,7 @@ void PadUpdateComplete() { removals.hex = changed.hex & old_state.hex; // Get the current Pad entry - PadDataEntry* current_pad_entry = &pad_data->entries[pad_data->index]; + PadDataEntry* current_pad_entry = &shared_mem->pad.entries[shared_mem->pad.index]; // Update entry properties current_pad_entry->current_state.hex = next_state.hex; @@ -123,8 +121,19 @@ void PadUpdateComplete() { current_pad_entry->delta_removals.hex = removals.hex; // Set circle Pad - current_pad_entry->circle_pad_x = next_circle_x; - current_pad_entry->circle_pad_y = next_circle_y; + current_pad_entry->circle_pad_x = next_pad_circle_x; + current_pad_entry->circle_pad_y = next_pad_circle_y; + + // If we just updated index 0, provide a new timestamp + if (shared_mem->pad.index == 0) { + shared_mem->pad.index_reset_ticks_previous = shared_mem->pad.index_reset_ticks; + 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(); +} // If we just updated index 0, provide a new timestamp if (pad_data->index == 0) { diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 9c6e86f77..6318d1d53 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -65,7 +65,7 @@ struct PadState { }; /** - * Structure of a single entry in the PadData's Pad state history array. + * Structure of a single entry of Pad state history within HID shared memory */ struct PadDataEntry { PadState current_state; @@ -77,22 +77,44 @@ struct PadDataEntry { }; /** - * Structure of all data related to the 3DS Pad. + * Structure of a single entry of touch state history within HID shared memory */ -struct PadData { - s64 index_reset_ticks; - s64 index_reset_ticks_previous; - u32 index; // the index of the last updated Pad state history element +struct TouchDataEntry { + u16 x; + u16 y; + u32 data_valid; +}; + +/** + * Structure of data stored in HID shared memory + */ +struct SharedMem { + // Offset 0x0 : "PAD" data, this is used for buttons and the circle pad + struct { + s64 index_reset_ticks; + s64 index_reset_ticks_previous; + u32 index; // Index of the last updated pad state history element + + INSERT_PADDING_BYTES(0x8); + + PadState current_state; // Same as entries[index].current_state + u32 raw_circle_pad_data; + + INSERT_PADDING_BYTES(0x4); - u32 pad1; - u32 pad2; + std::array entries; // Pad state history + } pad; - PadState current_state; // same as entries[index].current_state - u32 raw_circle_pad_data; + // Offset 0xA8 : Touchpad data, this is used for touchpad input + struct { + s64 index_reset_ticks; + s64 index_reset_ticks_previous; + u32 index; // Index of the last updated touch state history element - u32 pad3; + INSERT_PADDING_BYTES(0xC); - std::array entries; // Pad state history + std::array entries; + } touch; }; // Pre-defined PadStates for single button presses -- cgit v1.2.3 From 3229b048d9b4f16433fb1c5d623e6b79bc1a2d93 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 8 Mar 2015 00:13:49 -0500 Subject: HID: Moved some docstrings to the header. --- src/core/hle/service/hid/hid.cpp | 25 ++----------------------- src/core/hle/service/hid/hid.h | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 24 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index c21799db6..5812724d2 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -32,7 +32,7 @@ static s16 next_pad_circle_y = 0; /** * Gets a pointer to the PadData structure inside HID shared memory */ -static inline SharedMem* GetPadData() { +static inline SharedMem* GetSharedMem() { if (g_shared_mem == nullptr) return nullptr; return reinterpret_cast(g_shared_mem->GetPointer().ValueOr(nullptr)); @@ -66,28 +66,18 @@ static void UpdateNextCirclePadState() { next_pad_circle_y += next_state.circle_up ? max_value : 0x0; } -/** - * Sets a Pad state (button or button combo) as pressed - */ void PadButtonPress(const PadState& pad_state) { next_state.hex |= pad_state.hex; UpdateNextCirclePadState(); } -/** - * Sets a Pad state (button or button combo) as released - */ void PadButtonRelease(const PadState& pad_state) { next_state.hex &= ~pad_state.hex; UpdateNextCirclePadState(); } -/** - * Called after all Pad changes to be included in this update have been made, - * including both Pad key changes and analog circle Pad changes. - */ void PadUpdateComplete() { - SharedMem* shared_mem = GetPadData(); + SharedMem* shared_mem = GetSharedMem(); if (shared_mem == nullptr) return; @@ -135,17 +125,6 @@ void PadUpdateComplete() { g_event_pad_or_touch_2->Signal(); } - // If we just updated index 0, provide a new timestamp - if (pad_data->index == 0) { - pad_data->index_reset_ticks_previous = pad_data->index_reset_ticks; - pad_data->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 GetIPCHandles(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 6318d1d53..cd6263243 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -162,9 +162,22 @@ const PadState PAD_CIRCLE_DOWN = {{1u << 31}}; */ void GetIPCHandles(Interface* self); -// Methods for updating the HID module's state +/** + * Sets a Pad state (button or button combo) as pressed + * @param pad_state PadState data indicating which buttons have been pressed + */ void PadButtonPress(const PadState& pad_state); + +/** + * Sets a Pad state (button or button combo) as released + * @param pad_state PadState data indicating which buttons have been released + */ void PadButtonRelease(const PadState& pad_state); + +/** + * Called after all Pad changes to be included in this update have been made, including both Pad + * key changes and analog circle Pad changes. + */ void PadUpdateComplete(); void HIDInit(); -- cgit v1.2.3 From 1a904ded40c87c41c404cfe5e74722c0a6554926 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 8 Mar 2015 03:05:56 -0400 Subject: HID: Added functions to emulate the touchpad. --- src/core/hle/service/hid/hid.cpp | 48 ++++++++++++++++++++++++++++++++++++++++ src/core/hle/service/hid/hid.h | 13 +++++++++++ 2 files changed, 61 insertions(+) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 5812724d2..29213e0fe 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -29,6 +29,10 @@ 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 */ @@ -125,6 +129,50 @@ void PadUpdateComplete() { 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 = (next_touch_index + 1) % shared_mem->touch.entries.size(); + + // Get the current touch entry + TouchDataEntry* current_touch_entry = &shared_mem->touch.entries[shared_mem->touch.index]; + + // 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->data_valid = (next_touch_x || next_touch_y) ? 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 + // converted to pixel coordinates." (http://3dbrew.org/wiki/HID_Shared_Memory#Offset_0xA8). + + // If we just updated index 0, provide a new timestamp + if (shared_mem->touch.index == 0) { + shared_mem->touch.index_reset_ticks_previous = shared_mem->touch.index_reset_ticks; + shared_mem->touch.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 GetIPCHandles(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index cd6263243..f2affb5c5 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -180,6 +180,19 @@ void PadButtonRelease(const PadState& pad_state); */ void PadUpdateComplete(); +/** + * Signal that the touchpad has been pressed + * @param x Touchpad x-coordinate in bottom screen pixels (between 0 and 320) + * @param y Touchpad y-coordinate in bottom screen pixels (between 0 and 240) + */ +void TouchPress(u16 x, u16 y); + +/// Signal that touchpad has been released +void TouchRelease(); + +/// Signal that touchpad updates have been completed +void TouchUpdateComplete(); + void HIDInit(); void HIDShutdown(); -- cgit v1.2.3 From e9b9f1842be5afa794f03e2a0fa29d49cfca2601 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 8 Mar 2015 21:21:25 -0400 Subject: HID: Added static asserts to check register position in shared memory. --- src/core/hle/service/hid/hid.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index f2affb5c5..e4665a43c 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -89,7 +89,7 @@ struct TouchDataEntry { * Structure of data stored in HID shared memory */ struct SharedMem { - // Offset 0x0 : "PAD" data, this is used for buttons and the circle pad + // "Pad data, this is used for buttons and the circle pad struct { s64 index_reset_ticks; s64 index_reset_ticks_previous; @@ -105,7 +105,7 @@ struct SharedMem { std::array entries; // Pad state history } pad; - // Offset 0xA8 : Touchpad data, this is used for touchpad input + // Touchpad data, this is used for touchpad input struct { s64 index_reset_ticks; s64 index_reset_ticks_previous; @@ -117,6 +117,20 @@ struct SharedMem { } touch; }; +// TODO: MSVC does not support using offsetof() on non-static data members even though this +// is technically allowed since C++11. This macro should be enabled once MSVC adds +// support for that. +#ifndef _MSC_VER +#define ASSERT_REG_POSITION(field_name, position) \ + static_assert(offsetof(SharedMem, field_name) == position * 4, \ + "Field "#field_name" has invalid position") + +ASSERT_REG_POSITION(pad.index_reset_ticks, 0x0); +ASSERT_REG_POSITION(touch.index_reset_ticks, 0x2A); + +#undef ASSERT_REG_POSITION +#endif // !defined(_MSC_VER) + // Pre-defined PadStates for single button presses const PadState PAD_NONE = {{0}}; const PadState PAD_A = {{1u << 0}}; -- cgit v1.2.3 From 432aa1044c12b9b2ac9815c6ab41917ac971a616 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 8 Mar 2015 21:28:23 -0400 Subject: HID: Changed TouchDataEntry `valid` to a BitField and added some doc strings. --- src/core/hle/service/hid/hid.cpp | 2 +- src/core/hle/service/hid/hid.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 29213e0fe..72e2d63e3 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -156,7 +156,7 @@ void TouchUpdateComplete() { current_touch_entry->y = next_touch_y; // TODO(bunnei): Verify this behavior on real hardware - current_touch_entry->data_valid = (next_touch_x || next_touch_y) ? 1 : 0; + current_touch_entry->valid = (next_touch_x || next_touch_y) ? 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 diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index e4665a43c..7fdf5828a 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -80,9 +80,9 @@ struct PadDataEntry { * Structure of a single entry of touch state history within HID shared memory */ struct TouchDataEntry { - u16 x; - u16 y; - u32 data_valid; + u16 x; ///< Y-coordinate of a touchpad press on the lower screen + u16 y; ///< X-coordinate of a touchpad press on the lower screen + BitField<0,7,u32> valid; ///< Set to 1 when this entry contains actual X/Y data, otherwise 0 }; /** -- cgit v1.2.3 From a1a1a5c6c537fa35f914e3bb5deaae48ada95c99 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 8 Mar 2015 21:32:13 -0400 Subject: HID: Cleanup how `next_touch_index` is calculated for Pad and touch. --- src/core/hle/service/hid/hid.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 72e2d63e3..703a765b5 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -88,7 +88,7 @@ void PadUpdateComplete() { shared_mem->pad.current_state.hex = next_state.hex; shared_mem->pad.index = next_pad_index; - next_pad_index = (next_pad_index + 1) % shared_mem->pad.entries.size(); + ++next_touch_index %= shared_mem->pad.entries.size(); // Get the previous Pad state u32 last_entry_index = (shared_mem->pad.index - 1) % shared_mem->pad.entries.size(); @@ -146,7 +146,7 @@ void TouchUpdateComplete() { return; shared_mem->touch.index = next_touch_index; - next_touch_index = (next_touch_index + 1) % shared_mem->touch.entries.size(); + ++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]; -- cgit v1.2.3 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 +++++++++------------------------------ src/core/hle/service/hid/hid.h | 35 ++----------- 2 files changed, 28 insertions(+), 111 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 703a765b5..baff92716 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 diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 7fdf5828a..063f06858 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -176,38 +176,13 @@ const PadState PAD_CIRCLE_DOWN = {{1u << 31}}; */ void GetIPCHandles(Interface* self); -/** - * Sets a Pad state (button or button combo) as pressed - * @param pad_state PadState data indicating which buttons have been pressed - */ -void PadButtonPress(const PadState& pad_state); - -/** - * Sets a Pad state (button or button combo) as released - * @param pad_state PadState data indicating which buttons have been released - */ -void PadButtonRelease(const PadState& pad_state); - -/** - * Called after all Pad changes to be included in this update have been made, including both Pad - * key changes and analog circle Pad changes. - */ -void PadUpdateComplete(); - -/** - * Signal that the touchpad has been pressed - * @param x Touchpad x-coordinate in bottom screen pixels (between 0 and 320) - * @param y Touchpad y-coordinate in bottom screen pixels (between 0 and 240) - */ -void TouchPress(u16 x, u16 y); - -/// Signal that touchpad has been released -void TouchRelease(); - -/// Signal that touchpad updates have been completed -void TouchUpdateComplete(); +/// Checks for user input updates +void HIDUpdate(); +/// Initialize HID service void HIDInit(); + +/// Shutdown HID service void HIDShutdown(); } -- cgit v1.2.3 From 85cbccb1d3110c934ccf0edddf86a03fa692f27b Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 9 Mar 2015 23:03:24 -0400 Subject: HID: Added additional variable comments and some code cleanups. --- src/core/hle/service/hid/hid.cpp | 8 ++++++-- src/core/hle/service/hid/hid.h | 41 ++++++++++++++++++++++------------------ 2 files changed, 29 insertions(+), 20 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index baff92716..6aa8bfd1f 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -17,6 +17,8 @@ namespace Service { namespace HID { +static const int MAX_CIRCLEPAD_POS = 0x9C; ///< Max value for a circle pad position + Kernel::SharedPtr g_shared_mem = nullptr; Kernel::SharedPtr g_event_pad_or_touch_1; @@ -78,8 +80,10 @@ void HIDUpdate() { pad_entry->delta_removals.hex = changed.hex & old_state.hex;; // Set circle Pad - 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; + pad_entry->circle_pad_x = state.circle_left ? -MAX_CIRCLEPAD_POS : + state.circle_right ? MAX_CIRCLEPAD_POS : 0x0; + pad_entry->circle_pad_y = state.circle_down ? -MAX_CIRCLEPAD_POS : + state.circle_up ? MAX_CIRCLEPAD_POS : 0x0; // If we just updated index 0, provide a new timestamp if (shared_mem->pad.index == 0) { diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 063f06858..03971d3c7 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -80,40 +80,45 @@ struct PadDataEntry { * Structure of a single entry of touch state history within HID shared memory */ struct TouchDataEntry { - u16 x; ///< Y-coordinate of a touchpad press on the lower screen - u16 y; ///< X-coordinate of a touchpad press on the lower screen - BitField<0,7,u32> valid; ///< Set to 1 when this entry contains actual X/Y data, otherwise 0 + u16 x; ///< Y-coordinate of a touchpad press on the lower screen + u16 y; ///< X-coordinate of a touchpad press on the lower screen + BitField<0, 7, u32> valid; ///< Set to 1 when this entry contains actual X/Y data, otherwise 0 }; /** * Structure of data stored in HID shared memory */ struct SharedMem { - // "Pad data, this is used for buttons and the circle pad + /// Pad data, this is used for buttons and the circle pad struct { - s64 index_reset_ticks; - s64 index_reset_ticks_previous; - u32 index; // Index of the last updated pad state history element + s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0 + s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks` + u32 index; ///< Index of the last updated pad state entry - INSERT_PADDING_BYTES(0x8); + INSERT_PADDING_WORDS(0x2); - PadState current_state; // Same as entries[index].current_state - u32 raw_circle_pad_data; + PadState current_state; ///< Current state of the pad buttons - INSERT_PADDING_BYTES(0x4); + // TODO(bunnei): Implement `raw_circle_pad_data` field + u32 raw_circle_pad_data; ///< Raw (analog) circle pad data, before being converted - std::array entries; // Pad state history + INSERT_PADDING_WORDS(0x1); + + std::array entries; ///< Last 8 pad entries } pad; - // Touchpad data, this is used for touchpad input + /// Touchpad data, this is used for touchpad input struct { - s64 index_reset_ticks; - s64 index_reset_ticks_previous; - u32 index; // Index of the last updated touch state history element + s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0 + s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks` + u32 index; ///< Index of the last updated touch entry + + INSERT_PADDING_WORDS(0x1); - INSERT_PADDING_BYTES(0xC); + // TODO(bunnei): Implement `raw_entry` field + TouchDataEntry raw_entry; ///< Raw (analog) touch data, before being converted - std::array entries; + std::array entries; ///< Last 8 touch entries, in pixel coordinates } touch; }; -- cgit v1.2.3 From e79c27f1e04031e08a14db9517fe6b06647c65b1 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 9 Mar 2015 23:38:52 -0400 Subject: HID: Removed unnecessary global variables. --- src/core/hle/service/hid/hid.cpp | 90 +++++++++++++++++++--------------------- src/core/hle/service/hid/hid.h | 10 ----- 2 files changed, 42 insertions(+), 58 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 6aa8bfd1f..e7f9bec7e 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -19,26 +19,19 @@ namespace HID { static const int MAX_CIRCLEPAD_POS = 0x9C; ///< Max value for a circle pad position -Kernel::SharedPtr g_shared_mem = nullptr; +// Handle to shared memory region designated to HID_User service +static Kernel::SharedPtr shared_mem = nullptr; -Kernel::SharedPtr g_event_pad_or_touch_1; -Kernel::SharedPtr g_event_pad_or_touch_2; -Kernel::SharedPtr g_event_accelerometer; -Kernel::SharedPtr g_event_gyroscope; -Kernel::SharedPtr g_event_debug_pad; +// Event handles +static Kernel::SharedPtr event_pad_or_touch_1 = nullptr; +static Kernel::SharedPtr event_pad_or_touch_2 = nullptr; +static Kernel::SharedPtr event_accelerometer = nullptr; +static Kernel::SharedPtr event_gyroscope = nullptr; +static Kernel::SharedPtr event_debug_pad = nullptr; static u32 next_pad_index = 0; static u32 next_touch_index = 0; -/** - * Gets a pointer to the PadData structure inside HID shared memory - */ -static inline SharedMem* GetSharedMem() { - if (g_shared_mem == nullptr) - return nullptr; - return reinterpret_cast(g_shared_mem->GetPointer().ValueOr(nullptr)); -} - // TODO(peachum): // Add a method for setting analog input from joystick device for the circle Pad. // @@ -53,26 +46,27 @@ static inline SharedMem* GetSharedMem() { // * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_y <= -41 void HIDUpdate() { - SharedMem* shared_mem = GetSharedMem(); + SharedMem* mem = reinterpret_cast(shared_mem->GetPointer().ValueOr(nullptr)); + const PadState state = VideoCore::g_emu_window->GetPadState(); - if (shared_mem == nullptr) + if (mem == nullptr) { + LOG_DEBUG(Service_HID, "Cannot update HID prior to mapping shared memory!"); return; + } - 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(); + mem->pad.current_state.hex = state.hex; + mem->pad.index = next_pad_index; + ++next_touch_index %= mem->pad.entries.size(); // Get the previous Pad state - u32 last_entry_index = (shared_mem->pad.index - 1) % shared_mem->pad.entries.size(); - PadState old_state = shared_mem->pad.entries[last_entry_index].current_state; + u32 last_entry_index = (mem->pad.index - 1) % mem->pad.entries.size(); + PadState old_state = mem->pad.entries[last_entry_index].current_state; // Compute bitmask with 1s for bits different from the old state PadState changed = { { (state.hex ^ old_state.hex) } }; // Get the current Pad entry - PadDataEntry* pad_entry = &shared_mem->pad.entries[shared_mem->pad.index]; + PadDataEntry* pad_entry = &mem->pad.entries[mem->pad.index]; // Update entry properties pad_entry->current_state.hex = state.hex; @@ -86,16 +80,16 @@ void HIDUpdate() { state.circle_up ? MAX_CIRCLEPAD_POS : 0x0; // If we just updated index 0, provide a new timestamp - if (shared_mem->pad.index == 0) { - shared_mem->pad.index_reset_ticks_previous = shared_mem->pad.index_reset_ticks; - shared_mem->pad.index_reset_ticks = (s64)Core::g_app_core->GetTicks(); + if (mem->pad.index == 0) { + mem->pad.index_reset_ticks_previous = mem->pad.index_reset_ticks; + mem->pad.index_reset_ticks = (s64)Core::g_app_core->GetTicks(); } - shared_mem->touch.index = next_touch_index; - ++next_touch_index %= shared_mem->touch.entries.size(); + mem->touch.index = next_touch_index; + ++next_touch_index %= mem->touch.entries.size(); // Get the current touch entry - TouchDataEntry* touch_entry = &shared_mem->touch.entries[shared_mem->touch.index]; + TouchDataEntry* touch_entry = &mem->touch.entries[mem->touch.index]; bool pressed = false; std::tie(touch_entry->x, touch_entry->y, pressed) = VideoCore::g_emu_window->GetTouchState(); @@ -106,14 +100,14 @@ void HIDUpdate() { // converted to pixel coordinates." (http://3dbrew.org/wiki/HID_Shared_Memory#Offset_0xA8). // If we just updated index 0, provide a new timestamp - if (shared_mem->touch.index == 0) { - shared_mem->touch.index_reset_ticks_previous = shared_mem->touch.index_reset_ticks; - shared_mem->touch.index_reset_ticks = (s64)Core::g_app_core->GetTicks(); + if (mem->touch.index == 0) { + mem->touch.index_reset_ticks_previous = mem->touch.index_reset_ticks; + mem->touch.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(); + event_pad_or_touch_1->Signal(); + event_pad_or_touch_2->Signal(); } void GetIPCHandles(Service::Interface* self) { @@ -121,12 +115,12 @@ void GetIPCHandles(Service::Interface* self) { cmd_buff[1] = 0; // No error // TODO(yuriks): Return error from SendSyncRequest is this fails (part of IPC marshalling) - cmd_buff[3] = Kernel::g_handle_table.Create(Service::HID::g_shared_mem).MoveFrom(); - cmd_buff[4] = Kernel::g_handle_table.Create(Service::HID::g_event_pad_or_touch_1).MoveFrom(); - cmd_buff[5] = Kernel::g_handle_table.Create(Service::HID::g_event_pad_or_touch_2).MoveFrom(); - cmd_buff[6] = Kernel::g_handle_table.Create(Service::HID::g_event_accelerometer).MoveFrom(); - cmd_buff[7] = Kernel::g_handle_table.Create(Service::HID::g_event_gyroscope).MoveFrom(); - cmd_buff[8] = Kernel::g_handle_table.Create(Service::HID::g_event_debug_pad).MoveFrom(); + cmd_buff[3] = Kernel::g_handle_table.Create(Service::HID::shared_mem).MoveFrom(); + cmd_buff[4] = Kernel::g_handle_table.Create(Service::HID::event_pad_or_touch_1).MoveFrom(); + cmd_buff[5] = Kernel::g_handle_table.Create(Service::HID::event_pad_or_touch_2).MoveFrom(); + cmd_buff[6] = Kernel::g_handle_table.Create(Service::HID::event_accelerometer).MoveFrom(); + cmd_buff[7] = Kernel::g_handle_table.Create(Service::HID::event_gyroscope).MoveFrom(); + cmd_buff[8] = Kernel::g_handle_table.Create(Service::HID::event_debug_pad).MoveFrom(); } void HIDInit() { @@ -135,17 +129,17 @@ void HIDInit() { AddService(new HID_U_Interface); AddService(new HID_SPVR_Interface); - g_shared_mem = SharedMemory::Create("HID:SharedMem"); + 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"); - g_event_accelerometer = Event::Create(RESETTYPE_ONESHOT, "HID:EventAccelerometer"); - g_event_gyroscope = Event::Create(RESETTYPE_ONESHOT, "HID:EventGyroscope"); - g_event_debug_pad = Event::Create(RESETTYPE_ONESHOT, "HID:EventDebugPad"); + event_pad_or_touch_1 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch1"); + event_pad_or_touch_2 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch2"); + event_accelerometer = Event::Create(RESETTYPE_ONESHOT, "HID:EventAccelerometer"); + event_gyroscope = Event::Create(RESETTYPE_ONESHOT, "HID:EventGyroscope"); + event_debug_pad = Event::Create(RESETTYPE_ONESHOT, "HID:EventDebugPad"); } void HIDShutdown() { diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 03971d3c7..0946cf660 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -18,16 +18,6 @@ namespace Kernel { namespace Service { namespace HID { -// Handle to shared memory region designated to HID_User service -extern Kernel::SharedPtr g_shared_mem; - -// Event handles -extern Kernel::SharedPtr g_event_pad_or_touch_1; -extern Kernel::SharedPtr g_event_pad_or_touch_2; -extern Kernel::SharedPtr g_event_accelerometer; -extern Kernel::SharedPtr g_event_gyroscope; -extern Kernel::SharedPtr g_event_debug_pad; - /** * Structure of a Pad controller state. */ -- cgit v1.2.3 From 4bbddda377625332635aa2a2687816435eb574a2 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 9 Mar 2015 23:47:57 -0400 Subject: hid_user: Removed unnecessary includes. --- src/core/hle/service/hid/hid_user.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/hid/hid_user.cpp b/src/core/hle/service/hid/hid_user.cpp index 1d0accefe..c2d5758fb 100644 --- a/src/core/hle/service/hid/hid_user.cpp +++ b/src/core/hle/service/hid/hid_user.cpp @@ -3,8 +3,6 @@ // Refer to the license.txt file included. #include "core/hle/hle.h" -#include "core/hle/kernel/event.h" -#include "core/hle/kernel/shared_memory.h" #include "core/hle/service/hid/hid.h" #include "core/hle/service/hid/hid_user.h" -- cgit v1.2.3