diff options
| author | 2015-03-08 00:12:47 -0500 | |
|---|---|---|
| committer | 2015-03-10 18:05:16 -0400 | |
| commit | 83a66dd701789761c118c7e105327a1b6166ed13 (patch) | |
| tree | 48c3feab4d36116b25990c4dc18429cfb674fd29 /src/core | |
| parent | Merge pull request #649 from lioncash/clean (diff) | |
| download | yuzu-83a66dd701789761c118c7e105327a1b6166ed13.tar.gz yuzu-83a66dd701789761c118c7e105327a1b6166ed13.tar.xz yuzu-83a66dd701789761c118c7e105327a1b6166ed13.zip | |
HID: Refactored shared memory decoding for touchpad support.
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/service/hid/hid.cpp | 51 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.h | 46 |
2 files changed, 64 insertions, 33 deletions
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<Kernel::Event> g_event_debug_pad; | |||
| 25 | 25 | ||
| 26 | // Next Pad state update information | 26 | // Next Pad state update information |
| 27 | static PadState next_state = {{0}}; | 27 | static PadState next_state = {{0}}; |
| 28 | static u32 next_index = 0; | 28 | static u32 next_pad_index = 0; |
| 29 | static s16 next_circle_x = 0; | 29 | static s16 next_pad_circle_x = 0; |
| 30 | static s16 next_circle_y = 0; | 30 | static s16 next_pad_circle_y = 0; |
| 31 | 31 | ||
| 32 | /** | 32 | /** |
| 33 | * Gets a pointer to the PadData structure inside HID shared memory | 33 | * Gets a pointer to the PadData structure inside HID shared memory |
| 34 | */ | 34 | */ |
| 35 | static inline PadData* GetPadData() { | 35 | static inline SharedMem* GetPadData() { |
| 36 | if (g_shared_mem == nullptr) | 36 | if (g_shared_mem == nullptr) |
| 37 | return nullptr; | 37 | return nullptr; |
| 38 | return reinterpret_cast<PadData*>(g_shared_mem->GetPointer().ValueOr(nullptr)); | 38 | return reinterpret_cast<SharedMem*>(g_shared_mem->GetPointer().ValueOr(nullptr)); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | // TODO(peachum): | 41 | // TODO(peachum): |
| @@ -60,10 +60,10 @@ static inline PadData* GetPadData() { | |||
| 60 | */ | 60 | */ |
| 61 | static void UpdateNextCirclePadState() { | 61 | static void UpdateNextCirclePadState() { |
| 62 | static const s16 max_value = 0x9C; | 62 | static const s16 max_value = 0x9C; |
| 63 | next_circle_x = next_state.circle_left ? -max_value : 0x0; | 63 | next_pad_circle_x = next_state.circle_left ? -max_value : 0x0; |
| 64 | next_circle_x += next_state.circle_right ? max_value : 0x0; | 64 | next_pad_circle_x += next_state.circle_right ? max_value : 0x0; |
| 65 | next_circle_y = next_state.circle_down ? -max_value : 0x0; | 65 | next_pad_circle_y = next_state.circle_down ? -max_value : 0x0; |
| 66 | next_circle_y += next_state.circle_up ? max_value : 0x0; | 66 | next_pad_circle_y += next_state.circle_up ? max_value : 0x0; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | /** | 69 | /** |
| @@ -87,20 +87,18 @@ void PadButtonRelease(const PadState& pad_state) { | |||
| 87 | * including both Pad key changes and analog circle Pad changes. | 87 | * including both Pad key changes and analog circle Pad changes. |
| 88 | */ | 88 | */ |
| 89 | void PadUpdateComplete() { | 89 | void PadUpdateComplete() { |
| 90 | PadData* pad_data = GetPadData(); | 90 | SharedMem* shared_mem = GetPadData(); |
| 91 | 91 | ||
| 92 | if (pad_data == nullptr) { | 92 | if (shared_mem == nullptr) |
| 93 | return; | 93 | return; |
| 94 | } | ||
| 95 | 94 | ||
| 96 | // Update PadData struct | 95 | shared_mem->pad.current_state.hex = next_state.hex; |
| 97 | pad_data->current_state.hex = next_state.hex; | 96 | shared_mem->pad.index = next_pad_index; |
| 98 | pad_data->index = next_index; | 97 | next_pad_index = (next_pad_index + 1) % shared_mem->pad.entries.size(); |
| 99 | next_index = (next_index + 1) % pad_data->entries.size(); | ||
| 100 | 98 | ||
| 101 | // Get the previous Pad state | 99 | // Get the previous Pad state |
| 102 | u32 last_entry_index = (pad_data->index - 1) % pad_data->entries.size(); | 100 | u32 last_entry_index = (shared_mem->pad.index - 1) % shared_mem->pad.entries.size(); |
| 103 | PadState old_state = pad_data->entries[last_entry_index].current_state; | 101 | PadState old_state = shared_mem->pad.entries[last_entry_index].current_state; |
| 104 | 102 | ||
| 105 | // Compute bitmask with 1s for bits different from the old state | 103 | // Compute bitmask with 1s for bits different from the old state |
| 106 | PadState changed; | 104 | PadState changed; |
| @@ -115,7 +113,7 @@ void PadUpdateComplete() { | |||
| 115 | removals.hex = changed.hex & old_state.hex; | 113 | removals.hex = changed.hex & old_state.hex; |
| 116 | 114 | ||
| 117 | // Get the current Pad entry | 115 | // Get the current Pad entry |
| 118 | PadDataEntry* current_pad_entry = &pad_data->entries[pad_data->index]; | 116 | PadDataEntry* current_pad_entry = &shared_mem->pad.entries[shared_mem->pad.index]; |
| 119 | 117 | ||
| 120 | // Update entry properties | 118 | // Update entry properties |
| 121 | current_pad_entry->current_state.hex = next_state.hex; | 119 | current_pad_entry->current_state.hex = next_state.hex; |
| @@ -123,8 +121,19 @@ void PadUpdateComplete() { | |||
| 123 | current_pad_entry->delta_removals.hex = removals.hex; | 121 | current_pad_entry->delta_removals.hex = removals.hex; |
| 124 | 122 | ||
| 125 | // Set circle Pad | 123 | // Set circle Pad |
| 126 | current_pad_entry->circle_pad_x = next_circle_x; | 124 | current_pad_entry->circle_pad_x = next_pad_circle_x; |
| 127 | current_pad_entry->circle_pad_y = next_circle_y; | 125 | current_pad_entry->circle_pad_y = next_pad_circle_y; |
| 126 | |||
| 127 | // If we just updated index 0, provide a new timestamp | ||
| 128 | if (shared_mem->pad.index == 0) { | ||
| 129 | shared_mem->pad.index_reset_ticks_previous = shared_mem->pad.index_reset_ticks; | ||
| 130 | shared_mem->pad.index_reset_ticks = (s64)Core::g_app_core->GetTicks(); | ||
| 131 | } | ||
| 132 | |||
| 133 | // Signal both handles when there's an update to Pad or touch | ||
| 134 | g_event_pad_or_touch_1->Signal(); | ||
| 135 | g_event_pad_or_touch_2->Signal(); | ||
| 136 | } | ||
| 128 | 137 | ||
| 129 | // If we just updated index 0, provide a new timestamp | 138 | // If we just updated index 0, provide a new timestamp |
| 130 | if (pad_data->index == 0) { | 139 | 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 { | |||
| 65 | }; | 65 | }; |
| 66 | 66 | ||
| 67 | /** | 67 | /** |
| 68 | * Structure of a single entry in the PadData's Pad state history array. | 68 | * Structure of a single entry of Pad state history within HID shared memory |
| 69 | */ | 69 | */ |
| 70 | struct PadDataEntry { | 70 | struct PadDataEntry { |
| 71 | PadState current_state; | 71 | PadState current_state; |
| @@ -77,22 +77,44 @@ struct PadDataEntry { | |||
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | /** | 79 | /** |
| 80 | * Structure of all data related to the 3DS Pad. | 80 | * Structure of a single entry of touch state history within HID shared memory |
| 81 | */ | 81 | */ |
| 82 | struct PadData { | 82 | struct TouchDataEntry { |
| 83 | s64 index_reset_ticks; | 83 | u16 x; |
| 84 | s64 index_reset_ticks_previous; | 84 | u16 y; |
| 85 | u32 index; // the index of the last updated Pad state history element | 85 | u32 data_valid; |
| 86 | }; | ||
| 87 | |||
| 88 | /** | ||
| 89 | * Structure of data stored in HID shared memory | ||
| 90 | */ | ||
| 91 | struct SharedMem { | ||
| 92 | // Offset 0x0 : "PAD" data, this is used for buttons and the circle pad | ||
| 93 | struct { | ||
| 94 | s64 index_reset_ticks; | ||
| 95 | s64 index_reset_ticks_previous; | ||
| 96 | u32 index; // Index of the last updated pad state history element | ||
| 97 | |||
| 98 | INSERT_PADDING_BYTES(0x8); | ||
| 99 | |||
| 100 | PadState current_state; // Same as entries[index].current_state | ||
| 101 | u32 raw_circle_pad_data; | ||
| 102 | |||
| 103 | INSERT_PADDING_BYTES(0x4); | ||
| 86 | 104 | ||
| 87 | u32 pad1; | 105 | std::array<PadDataEntry, 8> entries; // Pad state history |
| 88 | u32 pad2; | 106 | } pad; |
| 89 | 107 | ||
| 90 | PadState current_state; // same as entries[index].current_state | 108 | // Offset 0xA8 : Touchpad data, this is used for touchpad input |
| 91 | u32 raw_circle_pad_data; | 109 | struct { |
| 110 | s64 index_reset_ticks; | ||
| 111 | s64 index_reset_ticks_previous; | ||
| 112 | u32 index; // Index of the last updated touch state history element | ||
| 92 | 113 | ||
| 93 | u32 pad3; | 114 | INSERT_PADDING_BYTES(0xC); |
| 94 | 115 | ||
| 95 | std::array<PadDataEntry, 8> entries; // Pad state history | 116 | std::array<TouchDataEntry, 8> entries; |
| 117 | } touch; | ||
| 96 | }; | 118 | }; |
| 97 | 119 | ||
| 98 | // Pre-defined PadStates for single button presses | 120 | // Pre-defined PadStates for single button presses |