summaryrefslogtreecommitdiff
path: root/src/input_common/sdl/sdl_impl.cpp
diff options
context:
space:
mode:
authorGravatar Zach Hilman2019-06-05 15:51:03 -0400
committerGravatar GitHub2019-06-05 15:51:03 -0400
commit6aff1005efc98cd7d1ddab705f041bd60d40f51a (patch)
treecc3207d49e7a6d4dbefa8f3bcbe638143b29f44c /src/input_common/sdl/sdl_impl.cpp
parentMerge pull request #2510 from SciresM/desired_language (diff)
parentinput_common/sdl/sdl_impl: Correct logging string in SDLState constructor (diff)
downloadyuzu-6aff1005efc98cd7d1ddab705f041bd60d40f51a.tar.gz
yuzu-6aff1005efc98cd7d1ddab705f041bd60d40f51a.tar.xz
yuzu-6aff1005efc98cd7d1ddab705f041bd60d40f51a.zip
Merge pull request #2541 from lioncash/input
input_common/sdl/sdl_impl: Minor cleanup
Diffstat (limited to 'src/input_common/sdl/sdl_impl.cpp')
-rw-r--r--src/input_common/sdl/sdl_impl.cpp134
1 files changed, 65 insertions, 69 deletions
diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp
index 0b69bfede..d2e9d278f 100644
--- a/src/input_common/sdl/sdl_impl.cpp
+++ b/src/input_common/sdl/sdl_impl.cpp
@@ -6,7 +6,6 @@
6#include <atomic> 6#include <atomic>
7#include <cmath> 7#include <cmath>
8#include <functional> 8#include <functional>
9#include <iterator>
10#include <mutex> 9#include <mutex>
11#include <string> 10#include <string>
12#include <thread> 11#include <thread>
@@ -15,7 +14,6 @@
15#include <utility> 14#include <utility>
16#include <vector> 15#include <vector>
17#include <SDL.h> 16#include <SDL.h>
18#include "common/assert.h"
19#include "common/logging/log.h" 17#include "common/logging/log.h"
20#include "common/math_util.h" 18#include "common/math_util.h"
21#include "common/param_package.h" 19#include "common/param_package.h"
@@ -23,12 +21,10 @@
23#include "core/frontend/input.h" 21#include "core/frontend/input.h"
24#include "input_common/sdl/sdl_impl.h" 22#include "input_common/sdl/sdl_impl.h"
25 23
26namespace InputCommon { 24namespace InputCommon::SDL {
27
28namespace SDL {
29 25
30static std::string GetGUID(SDL_Joystick* joystick) { 26static std::string GetGUID(SDL_Joystick* joystick) {
31 SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); 27 const SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick);
32 char guid_str[33]; 28 char guid_str[33];
33 SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str)); 29 SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str));
34 return guid_str; 30 return guid_str;
@@ -37,26 +33,27 @@ static std::string GetGUID(SDL_Joystick* joystick) {
37/// Creates a ParamPackage from an SDL_Event that can directly be used to create a ButtonDevice 33/// Creates a ParamPackage from an SDL_Event that can directly be used to create a ButtonDevice
38static Common::ParamPackage SDLEventToButtonParamPackage(SDLState& state, const SDL_Event& event); 34static Common::ParamPackage SDLEventToButtonParamPackage(SDLState& state, const SDL_Event& event);
39 35
40static int SDLEventWatcher(void* userdata, SDL_Event* event) { 36static int SDLEventWatcher(void* user_data, SDL_Event* event) {
41 SDLState* sdl_state = reinterpret_cast<SDLState*>(userdata); 37 auto* const sdl_state = static_cast<SDLState*>(user_data);
38
42 // Don't handle the event if we are configuring 39 // Don't handle the event if we are configuring
43 if (sdl_state->polling) { 40 if (sdl_state->polling) {
44 sdl_state->event_queue.Push(*event); 41 sdl_state->event_queue.Push(*event);
45 } else { 42 } else {
46 sdl_state->HandleGameControllerEvent(*event); 43 sdl_state->HandleGameControllerEvent(*event);
47 } 44 }
45
48 return 0; 46 return 0;
49} 47}
50 48
51class SDLJoystick { 49class SDLJoystick {
52public: 50public:
53 SDLJoystick(std::string guid_, int port_, SDL_Joystick* joystick, 51 SDLJoystick(std::string guid_, int port_, SDL_Joystick* joystick)
54 decltype(&SDL_JoystickClose) deleter = &SDL_JoystickClose) 52 : guid{std::move(guid_)}, port{port_}, sdl_joystick{joystick, &SDL_JoystickClose} {}
55 : guid{std::move(guid_)}, port{port_}, sdl_joystick{joystick, deleter} {}
56 53
57 void SetButton(int button, bool value) { 54 void SetButton(int button, bool value) {
58 std::lock_guard lock{mutex}; 55 std::lock_guard lock{mutex};
59 state.buttons[button] = value; 56 state.buttons.insert_or_assign(button, value);
60 } 57 }
61 58
62 bool GetButton(int button) const { 59 bool GetButton(int button) const {
@@ -66,7 +63,7 @@ public:
66 63
67 void SetAxis(int axis, Sint16 value) { 64 void SetAxis(int axis, Sint16 value) {
68 std::lock_guard lock{mutex}; 65 std::lock_guard lock{mutex};
69 state.axes[axis] = value; 66 state.axes.insert_or_assign(axis, value);
70 } 67 }
71 68
72 float GetAxis(int axis) const { 69 float GetAxis(int axis) const {
@@ -93,7 +90,7 @@ public:
93 90
94 void SetHat(int hat, Uint8 direction) { 91 void SetHat(int hat, Uint8 direction) {
95 std::lock_guard lock{mutex}; 92 std::lock_guard lock{mutex};
96 state.hats[hat] = direction; 93 state.hats.insert_or_assign(hat, direction);
97 } 94 }
98 95
99 bool GetHatDirection(int hat, Uint8 direction) const { 96 bool GetHatDirection(int hat, Uint8 direction) const {
@@ -118,10 +115,8 @@ public:
118 return sdl_joystick.get(); 115 return sdl_joystick.get();
119 } 116 }
120 117
121 void SetSDLJoystick(SDL_Joystick* joystick, 118 void SetSDLJoystick(SDL_Joystick* joystick) {
122 decltype(&SDL_JoystickClose) deleter = &SDL_JoystickClose) { 119 sdl_joystick.reset(joystick);
123 sdl_joystick =
124 std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)>(joystick, deleter);
125 } 120 }
126 121
127private: 122private:
@@ -136,59 +131,57 @@ private:
136 mutable std::mutex mutex; 131 mutable std::mutex mutex;
137}; 132};
138 133
139/**
140 * Get the nth joystick with the corresponding GUID
141 */
142std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickByGUID(const std::string& guid, int port) { 134std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickByGUID(const std::string& guid, int port) {
143 std::lock_guard lock{joystick_map_mutex}; 135 std::lock_guard lock{joystick_map_mutex};
144 const auto it = joystick_map.find(guid); 136 const auto it = joystick_map.find(guid);
145 if (it != joystick_map.end()) { 137 if (it != joystick_map.end()) {
146 while (it->second.size() <= static_cast<std::size_t>(port)) { 138 while (it->second.size() <= static_cast<std::size_t>(port)) {
147 auto joystick = std::make_shared<SDLJoystick>(guid, static_cast<int>(it->second.size()), 139 auto joystick =
148 nullptr, [](SDL_Joystick*) {}); 140 std::make_shared<SDLJoystick>(guid, static_cast<int>(it->second.size()), nullptr);
149 it->second.emplace_back(std::move(joystick)); 141 it->second.emplace_back(std::move(joystick));
150 } 142 }
151 return it->second[port]; 143 return it->second[port];
152 } 144 }
153 auto joystick = std::make_shared<SDLJoystick>(guid, 0, nullptr, [](SDL_Joystick*) {}); 145 auto joystick = std::make_shared<SDLJoystick>(guid, 0, nullptr);
154 return joystick_map[guid].emplace_back(std::move(joystick)); 146 return joystick_map[guid].emplace_back(std::move(joystick));
155} 147}
156 148
157/**
158 * Check how many identical joysticks (by guid) were connected before the one with sdl_id and so tie
159 * it to a SDLJoystick with the same guid and that port
160 */
161std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickBySDLID(SDL_JoystickID sdl_id) { 149std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickBySDLID(SDL_JoystickID sdl_id) {
162 auto sdl_joystick = SDL_JoystickFromInstanceID(sdl_id); 150 auto sdl_joystick = SDL_JoystickFromInstanceID(sdl_id);
163 const std::string guid = GetGUID(sdl_joystick); 151 const std::string guid = GetGUID(sdl_joystick);
164 152
165 std::lock_guard lock{joystick_map_mutex}; 153 std::lock_guard lock{joystick_map_mutex};
166 auto map_it = joystick_map.find(guid); 154 const auto map_it = joystick_map.find(guid);
167 if (map_it != joystick_map.end()) { 155 if (map_it != joystick_map.end()) {
168 auto vec_it = std::find_if(map_it->second.begin(), map_it->second.end(), 156 const auto vec_it =
169 [&sdl_joystick](const std::shared_ptr<SDLJoystick>& joystick) { 157 std::find_if(map_it->second.begin(), map_it->second.end(),
170 return sdl_joystick == joystick->GetSDLJoystick(); 158 [&sdl_joystick](const std::shared_ptr<SDLJoystick>& joystick) {
171 }); 159 return sdl_joystick == joystick->GetSDLJoystick();
160 });
172 if (vec_it != map_it->second.end()) { 161 if (vec_it != map_it->second.end()) {
173 // This is the common case: There is already an existing SDL_Joystick maped to a 162 // This is the common case: There is already an existing SDL_Joystick maped to a
174 // SDLJoystick. return the SDLJoystick 163 // SDLJoystick. return the SDLJoystick
175 return *vec_it; 164 return *vec_it;
176 } 165 }
166
177 // Search for a SDLJoystick without a mapped SDL_Joystick... 167 // Search for a SDLJoystick without a mapped SDL_Joystick...
178 auto nullptr_it = std::find_if(map_it->second.begin(), map_it->second.end(), 168 const auto nullptr_it = std::find_if(map_it->second.begin(), map_it->second.end(),
179 [](const std::shared_ptr<SDLJoystick>& joystick) { 169 [](const std::shared_ptr<SDLJoystick>& joystick) {
180 return !joystick->GetSDLJoystick(); 170 return !joystick->GetSDLJoystick();
181 }); 171 });
182 if (nullptr_it != map_it->second.end()) { 172 if (nullptr_it != map_it->second.end()) {
183 // ... and map it 173 // ... and map it
184 (*nullptr_it)->SetSDLJoystick(sdl_joystick); 174 (*nullptr_it)->SetSDLJoystick(sdl_joystick);
185 return *nullptr_it; 175 return *nullptr_it;
186 } 176 }
177
187 // There is no SDLJoystick without a mapped SDL_Joystick 178 // There is no SDLJoystick without a mapped SDL_Joystick
188 // Create a new SDLJoystick 179 // Create a new SDLJoystick
189 auto joystick = std::make_shared<SDLJoystick>(guid, map_it->second.size(), sdl_joystick); 180 const int port = static_cast<int>(map_it->second.size());
181 auto joystick = std::make_shared<SDLJoystick>(guid, port, sdl_joystick);
190 return map_it->second.emplace_back(std::move(joystick)); 182 return map_it->second.emplace_back(std::move(joystick));
191 } 183 }
184
192 auto joystick = std::make_shared<SDLJoystick>(guid, 0, sdl_joystick); 185 auto joystick = std::make_shared<SDLJoystick>(guid, 0, sdl_joystick);
193 return joystick_map[guid].emplace_back(std::move(joystick)); 186 return joystick_map[guid].emplace_back(std::move(joystick));
194} 187}
@@ -215,17 +208,19 @@ void SDLState::InitJoystick(int joystick_index) {
215 (*it)->SetSDLJoystick(sdl_joystick); 208 (*it)->SetSDLJoystick(sdl_joystick);
216 return; 209 return;
217 } 210 }
218 auto joystick = std::make_shared<SDLJoystick>(guid, joystick_guid_list.size(), sdl_joystick); 211 const int port = static_cast<int>(joystick_guid_list.size());
212 auto joystick = std::make_shared<SDLJoystick>(guid, port, sdl_joystick);
219 joystick_guid_list.emplace_back(std::move(joystick)); 213 joystick_guid_list.emplace_back(std::move(joystick));
220} 214}
221 215
222void SDLState::CloseJoystick(SDL_Joystick* sdl_joystick) { 216void SDLState::CloseJoystick(SDL_Joystick* sdl_joystick) {
223 std::string guid = GetGUID(sdl_joystick); 217 const std::string guid = GetGUID(sdl_joystick);
218
224 std::shared_ptr<SDLJoystick> joystick; 219 std::shared_ptr<SDLJoystick> joystick;
225 { 220 {
226 std::lock_guard lock{joystick_map_mutex}; 221 std::lock_guard lock{joystick_map_mutex};
227 // This call to guid is safe since the joystick is guaranteed to be in the map 222 // This call to guid is safe since the joystick is guaranteed to be in the map
228 auto& joystick_guid_list = joystick_map[guid]; 223 const auto& joystick_guid_list = joystick_map[guid];
229 const auto joystick_it = 224 const auto joystick_it =
230 std::find_if(joystick_guid_list.begin(), joystick_guid_list.end(), 225 std::find_if(joystick_guid_list.begin(), joystick_guid_list.end(),
231 [&sdl_joystick](const std::shared_ptr<SDLJoystick>& joystick) { 226 [&sdl_joystick](const std::shared_ptr<SDLJoystick>& joystick) {
@@ -233,9 +228,10 @@ void SDLState::CloseJoystick(SDL_Joystick* sdl_joystick) {
233 }); 228 });
234 joystick = *joystick_it; 229 joystick = *joystick_it;
235 } 230 }
236 // Destruct SDL_Joystick outside the lock guard because SDL can internally call event calback 231
237 // which locks the mutex again 232 // Destruct SDL_Joystick outside the lock guard because SDL can internally call the
238 joystick->SetSDLJoystick(nullptr, [](SDL_Joystick*) {}); 233 // event callback which locks the mutex again.
234 joystick->SetSDLJoystick(nullptr);
239} 235}
240 236
241void SDLState::HandleGameControllerEvent(const SDL_Event& event) { 237void SDLState::HandleGameControllerEvent(const SDL_Event& event) {
@@ -317,9 +313,10 @@ public:
317 trigger_if_greater(trigger_if_greater_) {} 313 trigger_if_greater(trigger_if_greater_) {}
318 314
319 bool GetStatus() const override { 315 bool GetStatus() const override {
320 float axis_value = joystick->GetAxis(axis); 316 const float axis_value = joystick->GetAxis(axis);
321 if (trigger_if_greater) 317 if (trigger_if_greater) {
322 return axis_value > threshold; 318 return axis_value > threshold;
319 }
323 return axis_value < threshold; 320 return axis_value < threshold;
324 } 321 }
325 322
@@ -444,7 +441,7 @@ public:
444 const int port = params.Get("port", 0); 441 const int port = params.Get("port", 0);
445 const int axis_x = params.Get("axis_x", 0); 442 const int axis_x = params.Get("axis_x", 0);
446 const int axis_y = params.Get("axis_y", 1); 443 const int axis_y = params.Get("axis_y", 1);
447 float deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, .99f); 444 const float deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, .99f);
448 445
449 auto joystick = state.GetSDLJoystickByGUID(guid, port); 446 auto joystick = state.GetSDLJoystickByGUID(guid, port);
450 447
@@ -470,7 +467,7 @@ SDLState::SDLState() {
470 return; 467 return;
471 } 468 }
472 if (SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1") == SDL_FALSE) { 469 if (SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1") == SDL_FALSE) {
473 LOG_ERROR(Input, "Failed to set Hint for background events", SDL_GetError()); 470 LOG_ERROR(Input, "Failed to set hint for background events with: {}", SDL_GetError());
474 } 471 }
475 472
476 SDL_AddEventWatch(&SDLEventWatcher, this); 473 SDL_AddEventWatch(&SDLEventWatcher, this);
@@ -507,12 +504,12 @@ SDLState::~SDLState() {
507 } 504 }
508} 505}
509 506
510Common::ParamPackage SDLEventToButtonParamPackage(SDLState& state, const SDL_Event& event) { 507static Common::ParamPackage SDLEventToButtonParamPackage(SDLState& state, const SDL_Event& event) {
511 Common::ParamPackage params({{"engine", "sdl"}}); 508 Common::ParamPackage params({{"engine", "sdl"}});
512 509
513 switch (event.type) { 510 switch (event.type) {
514 case SDL_JOYAXISMOTION: { 511 case SDL_JOYAXISMOTION: {
515 auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); 512 const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which);
516 params.Set("port", joystick->GetPort()); 513 params.Set("port", joystick->GetPort());
517 params.Set("guid", joystick->GetGUID()); 514 params.Set("guid", joystick->GetGUID());
518 params.Set("axis", event.jaxis.axis); 515 params.Set("axis", event.jaxis.axis);
@@ -526,14 +523,14 @@ Common::ParamPackage SDLEventToButtonParamPackage(SDLState& state, const SDL_Eve
526 break; 523 break;
527 } 524 }
528 case SDL_JOYBUTTONUP: { 525 case SDL_JOYBUTTONUP: {
529 auto joystick = state.GetSDLJoystickBySDLID(event.jbutton.which); 526 const auto joystick = state.GetSDLJoystickBySDLID(event.jbutton.which);
530 params.Set("port", joystick->GetPort()); 527 params.Set("port", joystick->GetPort());
531 params.Set("guid", joystick->GetGUID()); 528 params.Set("guid", joystick->GetGUID());
532 params.Set("button", event.jbutton.button); 529 params.Set("button", event.jbutton.button);
533 break; 530 break;
534 } 531 }
535 case SDL_JOYHATMOTION: { 532 case SDL_JOYHATMOTION: {
536 auto joystick = state.GetSDLJoystickBySDLID(event.jhat.which); 533 const auto joystick = state.GetSDLJoystickBySDLID(event.jhat.which);
537 params.Set("port", joystick->GetPort()); 534 params.Set("port", joystick->GetPort());
538 params.Set("guid", joystick->GetGUID()); 535 params.Set("guid", joystick->GetGUID());
539 params.Set("hat", event.jhat.hat); 536 params.Set("hat", event.jhat.hat);
@@ -607,8 +604,8 @@ public:
607 SDLPoller::Start(); 604 SDLPoller::Start();
608 605
609 // Reset stored axes 606 // Reset stored axes
610 analog_xaxis = -1; 607 analog_x_axis = -1;
611 analog_yaxis = -1; 608 analog_y_axis = -1;
612 analog_axes_joystick = -1; 609 analog_axes_joystick = -1;
613 } 610 }
614 611
@@ -620,25 +617,25 @@ public:
620 } 617 }
621 // An analog device needs two axes, so we need to store the axis for later and wait for 618 // An analog device needs two axes, so we need to store the axis for later and wait for
622 // a second SDL event. The axes also must be from the same joystick. 619 // a second SDL event. The axes also must be from the same joystick.
623 int axis = event.jaxis.axis; 620 const int axis = event.jaxis.axis;
624 if (analog_xaxis == -1) { 621 if (analog_x_axis == -1) {
625 analog_xaxis = axis; 622 analog_x_axis = axis;
626 analog_axes_joystick = event.jaxis.which; 623 analog_axes_joystick = event.jaxis.which;
627 } else if (analog_yaxis == -1 && analog_xaxis != axis && 624 } else if (analog_y_axis == -1 && analog_x_axis != axis &&
628 analog_axes_joystick == event.jaxis.which) { 625 analog_axes_joystick == event.jaxis.which) {
629 analog_yaxis = axis; 626 analog_y_axis = axis;
630 } 627 }
631 } 628 }
632 Common::ParamPackage params; 629 Common::ParamPackage params;
633 if (analog_xaxis != -1 && analog_yaxis != -1) { 630 if (analog_x_axis != -1 && analog_y_axis != -1) {
634 auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); 631 const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which);
635 params.Set("engine", "sdl"); 632 params.Set("engine", "sdl");
636 params.Set("port", joystick->GetPort()); 633 params.Set("port", joystick->GetPort());
637 params.Set("guid", joystick->GetGUID()); 634 params.Set("guid", joystick->GetGUID());
638 params.Set("axis_x", analog_xaxis); 635 params.Set("axis_x", analog_x_axis);
639 params.Set("axis_y", analog_yaxis); 636 params.Set("axis_y", analog_y_axis);
640 analog_xaxis = -1; 637 analog_x_axis = -1;
641 analog_yaxis = -1; 638 analog_y_axis = -1;
642 analog_axes_joystick = -1; 639 analog_axes_joystick = -1;
643 return params; 640 return params;
644 } 641 }
@@ -646,8 +643,8 @@ public:
646 } 643 }
647 644
648private: 645private:
649 int analog_xaxis = -1; 646 int analog_x_axis = -1;
650 int analog_yaxis = -1; 647 int analog_y_axis = -1;
651 SDL_JoystickID analog_axes_joystick = -1; 648 SDL_JoystickID analog_axes_joystick = -1;
652}; 649};
653} // namespace Polling 650} // namespace Polling
@@ -667,5 +664,4 @@ SDLState::Pollers SDLState::GetPollers(InputCommon::Polling::DeviceType type) {
667 return pollers; 664 return pollers;
668} 665}
669 666
670} // namespace SDL 667} // namespace InputCommon::SDL
671} // namespace InputCommon