summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar bunnei2015-03-08 00:12:47 -0500
committerGravatar bunnei2015-03-10 18:05:16 -0400
commit83a66dd701789761c118c7e105327a1b6166ed13 (patch)
tree48c3feab4d36116b25990c4dc18429cfb674fd29 /src/core
parentMerge pull request #649 from lioncash/clean (diff)
downloadyuzu-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.cpp51
-rw-r--r--src/core/hle/service/hid/hid.h46
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
27static PadState next_state = {{0}}; 27static PadState next_state = {{0}};
28static u32 next_index = 0; 28static u32 next_pad_index = 0;
29static s16 next_circle_x = 0; 29static s16 next_pad_circle_x = 0;
30static s16 next_circle_y = 0; 30static 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 */
35static inline PadData* GetPadData() { 35static 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 */
61static void UpdateNextCirclePadState() { 61static 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 */
89void PadUpdateComplete() { 89void 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 */
70struct PadDataEntry { 70struct 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 */
82struct PadData { 82struct 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 */
91struct 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