summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Kevin Hartman2014-09-08 21:46:02 -0700
committerGravatar Kevin Hartman2014-09-12 01:15:14 -0700
commit02fd19b2f60f4db8a683734e4300d7498c861309 (patch)
treec9c95671835d73b5ca7e52029de5bb27832e11a3 /src/core
parentInitial HID PAD work, with GLFW only. (diff)
downloadyuzu-02fd19b2f60f4db8a683734e4300d7498c861309.tar.gz
yuzu-02fd19b2f60f4db8a683734e4300d7498c861309.tar.xz
yuzu-02fd19b2f60f4db8a683734e4300d7498c861309.zip
Added support for multiple input device types for KeyMap and connected Qt.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/service/hid.cpp160
-rw-r--r--src/core/hle/service/hid.h80
2 files changed, 127 insertions, 113 deletions
diff --git a/src/core/hle/service/hid.cpp b/src/core/hle/service/hid.cpp
index 1ef39fced..b6ec1b8ff 100644
--- a/src/core/hle/service/hid.cpp
+++ b/src/core/hle/service/hid.cpp
@@ -14,96 +14,102 @@
14 14
15namespace HID_User { 15namespace HID_User {
16 16
17Handle g_shared_mem = 0; ///< Handle to shared memory region designated to HID_User service 17// Handle to shared memory region designated to HID_User service
18static Handle shared_mem = 0;
18 19
19// Event handles 20// Event handles
20Handle g_event_pad_or_touch_1 = 0; 21static Handle event_pad_or_touch_1 = 0;
21Handle g_event_pad_or_touch_2 = 0; 22static Handle event_pad_or_touch_2 = 0;
22Handle g_event_accelerometer = 0; 23static Handle event_accelerometer = 0;
23Handle g_event_gyroscope = 0; 24static Handle event_gyroscope = 0;
24Handle g_event_debug_pad = 0; 25static Handle event_debug_pad = 0;
25 26
26// Next PAD state update information 27// Next Pad state update information
27PADState g_next_state = {{0}}; 28static PadState next_state = {{0}};
28u32 g_next_index = 0; 29static u32 next_index = 0;
29s16 g_next_circle_x = 0; 30static s16 next_circle_x = 0;
30s16 g_next_circle_y = 0; 31static s16 next_circle_y = 0;
31 32
32/** Gets a pointer to the PADData structure inside HID shared memory 33/**
34 * Gets a pointer to the PadData structure inside HID shared memory
33 */ 35 */
34static inline PADData* GetPADData() { 36static inline PadData* GetPadData() {
35 if (0 == g_shared_mem) 37 if (0 == shared_mem)
36 return nullptr; 38 return nullptr;
37 39
38 return reinterpret_cast<PADData*>(Kernel::GetSharedMemoryPointer(g_shared_mem, 0)); 40 return reinterpret_cast<PadData*>(Kernel::GetSharedMemoryPointer(shared_mem, 0));
39} 41}
40 42
41/** Circle PAD from keys. 43/**
44 * Circle Pad from keys.
42 * 45 *
43 * This is implemented as "pushed all the way to an edge (max) or centered (0)". 46 * This is implemented as "pushed all the way to an edge (max) or centered (0)".
44 * 47 *
45 * Indicate the circle pad is pushed completely to the edge in 1 of 8 directions. 48 * Indicate the circle pad is pushed completely to the edge in 1 of 8 directions.
46 */ 49 */
47void UpdateNextCirclePADState() { 50void UpdateNextCirclePadState() {
48 static const s16 max_value = 0x9C; 51 static const s16 max_value = 0x9C;
49 g_next_circle_x = g_next_state.circle_left ? -max_value : 0x0; 52 next_circle_x = next_state.circle_left ? -max_value : 0x0;
50 g_next_circle_x += g_next_state.circle_right ? max_value : 0x0; 53 next_circle_x += next_state.circle_right ? max_value : 0x0;
51 g_next_circle_y = g_next_state.circle_down ? -max_value : 0x0; 54 next_circle_y = next_state.circle_down ? -max_value : 0x0;
52 g_next_circle_y += g_next_state.circle_up ? max_value : 0x0; 55 next_circle_y += next_state.circle_up ? max_value : 0x0;
53} 56}
54 57
55/** Sets a PAD state (button or button combo) as pressed 58/**
59 * Sets a Pad state (button or button combo) as pressed
56 */ 60 */
57void PADButtonPress(PADState pad_state) { 61void PadButtonPress(PadState pad_state) {
58 g_next_state.hex |= pad_state.hex; 62 next_state.hex |= pad_state.hex;
59 UpdateNextCirclePADState(); 63 UpdateNextCirclePadState();
60} 64}
61 65
62/** Sets a PAD state (button or button combo) as released 66/**
67 * Sets a Pad state (button or button combo) as released
63 */ 68 */
64void PADButtonRelease(PADState pad_state) { 69void PadButtonRelease(PadState pad_state) {
65 g_next_state.hex &= ~pad_state.hex; 70 next_state.hex &= ~pad_state.hex;
66 UpdateNextCirclePADState(); 71 UpdateNextCirclePadState();
67} 72}
68 73
69/** Called after all PAD changes to be included in this update have been made, 74/**
70 * including both PAD key changes and analog circle PAD changes. 75 * Called after all Pad changes to be included in this update have been made,
76 * including both Pad key changes and analog circle Pad changes.
71 */ 77 */
72void PADUpdateComplete() { 78void PadUpdateComplete() {
73 PADData* pad_data = GetPADData(); 79 PadData* pad_data = GetPadData();
74 80
75 // Update PADData struct 81 // Update PadData struct
76 pad_data->current_state.hex = g_next_state.hex; 82 pad_data->current_state.hex = next_state.hex;
77 pad_data->index = g_next_index; 83 pad_data->index = next_index;
78 g_next_index = (g_next_index + 1) % pad_data->entries.size(); 84 next_index = (next_index + 1) % pad_data->entries.size();
79 85
80 // Get the previous PAD state 86 // Get the previous Pad state
81 u32 last_entry_index = (pad_data->index - 1) % pad_data->entries.size(); 87 u32 last_entry_index = (pad_data->index - 1) % pad_data->entries.size();
82 PADState old_state = pad_data->entries[last_entry_index].current_state; 88 PadState old_state = pad_data->entries[last_entry_index].current_state;
83 89
84 // Compute bitmask with 1s for bits different from the old state 90 // Compute bitmask with 1s for bits different from the old state
85 PADState changed; 91 PadState changed;
86 changed.hex = (g_next_state.hex ^ old_state.hex); 92 changed.hex = (next_state.hex ^ old_state.hex);
87 93
88 // Compute what was added 94 // Compute what was added
89 PADState additions; 95 PadState additions;
90 additions.hex = changed.hex & g_next_state.hex; 96 additions.hex = changed.hex & next_state.hex;
91 97
92 // Compute what was removed 98 // Compute what was removed
93 PADState removals; 99 PadState removals;
94 removals.hex = changed.hex & old_state.hex; 100 removals.hex = changed.hex & old_state.hex;
95 101
96 // Get the current PAD entry 102 // Get the current Pad entry
97 PADDataEntry* current_pad_entry = &pad_data->entries[pad_data->index]; 103 PadDataEntry* current_pad_entry = &pad_data->entries[pad_data->index];
98 104
99 // Update entry properties 105 // Update entry properties
100 current_pad_entry->current_state.hex = g_next_state.hex; 106 current_pad_entry->current_state.hex = next_state.hex;
101 current_pad_entry->delta_additions.hex = additions.hex; 107 current_pad_entry->delta_additions.hex = additions.hex;
102 current_pad_entry->delta_removals.hex = removals.hex; 108 current_pad_entry->delta_removals.hex = removals.hex;
103 109
104 // Set circle PAD 110 // Set circle Pad
105 current_pad_entry->circle_pad_x = g_next_circle_x; 111 current_pad_entry->circle_pad_x = next_circle_x;
106 current_pad_entry->circle_pad_y = g_next_circle_y; 112 current_pad_entry->circle_pad_y = next_circle_y;
107 113
108 // If we just updated index 0, provide a new timestamp 114 // If we just updated index 0, provide a new timestamp
109 if (pad_data->index == 0) { 115 if (pad_data->index == 0) {
@@ -111,24 +117,24 @@ void PADUpdateComplete() {
111 pad_data->index_reset_ticks = (s64)Core::g_app_core->GetTicks(); 117 pad_data->index_reset_ticks = (s64)Core::g_app_core->GetTicks();
112 } 118 }
113 119
114 // Signal both handles when there's an update to PAD or touch 120 // Signal both handles when there's an update to Pad or touch
115 Kernel::SignalEvent(g_event_pad_or_touch_1); 121 Kernel::SignalEvent(event_pad_or_touch_1);
116 Kernel::SignalEvent(g_event_pad_or_touch_2); 122 Kernel::SignalEvent(event_pad_or_touch_2);
117} 123}
118 124
119 125
120// TODO(peachum): 126// TODO(peachum):
121// Add a method for setting analog input from joystick device for the circle PAD. 127// Add a method for setting analog input from joystick device for the circle Pad.
122// 128//
123// This method should: 129// This method should:
124// * Be called after both PADButton<Press, Release>(). 130// * Be called after both PadButton<Press, Release>().
125// * Be called before PADUpdateComplete() 131// * Be called before PadUpdateComplete()
126// * Set current PADEntry.circle_pad_<axis> using analog data 132// * Set current PadEntry.circle_pad_<axis> using analog data
127// * Set PadData.raw_circle_pad_data 133// * Set PadData.raw_circle_pad_data
128// * Set PadData.current_state.circle_right = 1 if current PADEntry.circle_pad_x >= 41 134// * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_x >= 41
129// * Set PadData.current_state.circle_up = 1 if current PADEntry.circle_pad_y >= 41 135// * Set PadData.current_state.circle_up = 1 if current PadEntry.circle_pad_y >= 41
130// * Set PadData.current_state.circle_left = 1 if current PADEntry.circle_pad_x <= -41 136// * Set PadData.current_state.circle_left = 1 if current PadEntry.circle_pad_x <= -41
131// * Set PadData.current_state.circle_right = 1 if current PADEntry.circle_pad_y <= -41 137// * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_y <= -41
132 138
133 139
134/** 140/**
@@ -149,12 +155,12 @@ void GetIPCHandles(Service::Interface* self) {
149 u32* cmd_buff = Service::GetCommandBuffer(); 155 u32* cmd_buff = Service::GetCommandBuffer();
150 156
151 cmd_buff[1] = 0; // No error 157 cmd_buff[1] = 0; // No error
152 cmd_buff[3] = g_shared_mem; 158 cmd_buff[3] = shared_mem;
153 cmd_buff[4] = g_event_pad_or_touch_1; 159 cmd_buff[4] = event_pad_or_touch_1;
154 cmd_buff[5] = g_event_pad_or_touch_2; 160 cmd_buff[5] = event_pad_or_touch_2;
155 cmd_buff[6] = g_event_accelerometer; 161 cmd_buff[6] = event_accelerometer;
156 cmd_buff[7] = g_event_gyroscope; 162 cmd_buff[7] = event_gyroscope;
157 cmd_buff[8] = g_event_debug_pad; 163 cmd_buff[8] = event_debug_pad;
158 164
159 DEBUG_LOG(KERNEL, "called"); 165 DEBUG_LOG(KERNEL, "called");
160} 166}
@@ -177,14 +183,14 @@ const Interface::FunctionInfo FunctionTable[] = {
177// Interface class 183// Interface class
178 184
179Interface::Interface() { 185Interface::Interface() {
180 g_shared_mem = Kernel::CreateSharedMemory("HID_User:SharedMem"); // Create shared memory object 186 shared_mem = Kernel::CreateSharedMemory("HID_User:SharedMem"); // Create shared memory object
181 187
182 // Create event handles 188 // Create event handles
183 g_event_pad_or_touch_1 = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventPADOrTouch1"); 189 event_pad_or_touch_1 = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventPadOrTouch1");
184 g_event_pad_or_touch_2 = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventPADOrTouch2"); 190 event_pad_or_touch_2 = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventPadOrTouch2");
185 g_event_accelerometer = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventAccelerometer"); 191 event_accelerometer = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventAccelerometer");
186 g_event_gyroscope = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventGyroscope"); 192 event_gyroscope = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventGyroscope");
187 g_event_debug_pad = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventDebugPAD"); 193 event_debug_pad = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID_User:EventDebugPad");
188 194
189 Register(FunctionTable, ARRAY_SIZE(FunctionTable)); 195 Register(FunctionTable, ARRAY_SIZE(FunctionTable));
190} 196}
diff --git a/src/core/hle/service/hid.h b/src/core/hle/service/hid.h
index f5f76f0fc..a077e25cd 100644
--- a/src/core/hle/service/hid.h
+++ b/src/core/hle/service/hid.h
@@ -10,13 +10,15 @@
10//////////////////////////////////////////////////////////////////////////////////////////////////// 10////////////////////////////////////////////////////////////////////////////////////////////////////
11// Namespace HID_User 11// Namespace HID_User
12 12
13// This service is used for interfacing to physical user controls... perhaps "Human Interface 13// This service is used for interfacing to physical user controls.
14// Devices"? Uses include game pad controls, accelerometers, gyroscopes, etc. 14// Uses include game pad controls, touchscreen, accelerometers, gyroscopes, and debug pad.
15 15
16namespace HID_User { 16namespace HID_User {
17 17
18/// Structure of a PAD controller state 18/**
19struct PADState { 19 * Structure of a Pad controller state.
20 */
21struct PadState {
20 union { 22 union {
21 u32 hex; 23 u32 hex;
22 24
@@ -40,58 +42,64 @@ struct PADState {
40 }; 42 };
41}; 43};
42 44
43/// Structure of a single entry in the PADData's PAD state history array 45/**
44struct PADDataEntry { 46 * Structure of a single entry in the PadData's Pad state history array.
45 PADState current_state; 47 */
46 PADState delta_additions; 48struct PadDataEntry {
47 PADState delta_removals; 49 PadState current_state;
50 PadState delta_additions;
51 PadState delta_removals;
48 52
49 s16 circle_pad_x; 53 s16 circle_pad_x;
50 s16 circle_pad_y; 54 s16 circle_pad_y;
51}; 55};
52 56
53/// Structure of all data related to the 3DS Pad 57/**
54struct PADData { 58 * Structure of all data related to the 3DS Pad.
59 */
60struct PadData {
55 s64 index_reset_ticks; 61 s64 index_reset_ticks;
56 s64 index_reset_ticks_previous; 62 s64 index_reset_ticks_previous;
57 u32 index; // the index of the last updated PAD state history element 63 u32 index; // the index of the last updated Pad state history element
58 64
59 u32 pad1; 65 u32 pad1;
60 u32 pad2; 66 u32 pad2;
61 67
62 PADState current_state; // same as entries[index].current_state 68 PadState current_state; // same as entries[index].current_state
63 u32 raw_circle_pad_data; 69 u32 raw_circle_pad_data;
64 70
65 u32 pad3; 71 u32 pad3;
66 72
67 std::array<PADDataEntry, 8> entries; // PAD state history 73 std::array<PadDataEntry, 8> entries; // Pad state history
68}; 74};
69 75
70// Pre-defined PADStates for single button presses 76// Pre-defined PadStates for single button presses
71const PADState PAD_NONE = {{0}}; 77const PadState PAD_NONE = {{0}};
72const PADState PAD_A = {{1u << 0}}; 78const PadState PAD_A = {{1u << 0}};
73const PADState PAD_B = {{1u << 1}}; 79const PadState PAD_B = {{1u << 1}};
74const PADState PAD_SELECT = {{1u << 2}}; 80const PadState PAD_SELECT = {{1u << 2}};
75const PADState PAD_START = {{1u << 3}}; 81const PadState PAD_START = {{1u << 3}};
76const PADState PAD_RIGHT = {{1u << 4}}; 82const PadState PAD_RIGHT = {{1u << 4}};
77const PADState PAD_LEFT = {{1u << 5}}; 83const PadState PAD_LEFT = {{1u << 5}};
78const PADState PAD_UP = {{1u << 6}}; 84const PadState PAD_UP = {{1u << 6}};
79const PADState PAD_DOWN = {{1u << 7}}; 85const PadState PAD_DOWN = {{1u << 7}};
80const PADState PAD_R = {{1u << 8}}; 86const PadState PAD_R = {{1u << 8}};
81const PADState PAD_L = {{1u << 9}}; 87const PadState PAD_L = {{1u << 9}};
82const PADState PAD_X = {{1u << 10}}; 88const PadState PAD_X = {{1u << 10}};
83const PADState PAD_Y = {{1u << 11}}; 89const PadState PAD_Y = {{1u << 11}};
84const PADState PAD_CIRCLE_RIGHT = {{1u << 28}}; 90const PadState PAD_CIRCLE_RIGHT = {{1u << 28}};
85const PADState PAD_CIRCLE_LEFT = {{1u << 29}}; 91const PadState PAD_CIRCLE_LEFT = {{1u << 29}};
86const PADState PAD_CIRCLE_UP = {{1u << 30}}; 92const PadState PAD_CIRCLE_UP = {{1u << 30}};
87const PADState PAD_CIRCLE_DOWN = {{1u << 31}}; 93const PadState PAD_CIRCLE_DOWN = {{1u << 31}};
88 94
89// Methods for updating the HID module's state 95// Methods for updating the HID module's state
90void PADButtonPress(PADState pad_state); 96void PadButtonPress(PadState pad_state);
91void PADButtonRelease(PADState pad_state); 97void PadButtonRelease(PadState pad_state);
92void PADUpdateComplete(); 98void PadUpdateComplete();
93 99
94/// HID service interface 100/**
101 * HID service interface.
102 */
95class Interface : public Service::Interface { 103class Interface : public Service::Interface {
96public: 104public:
97 105