input_mapping.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. // Copyright 2021 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included
  4. #include "common/common_types.h"
  5. #include "input_common/input_engine.h"
  6. #include "input_common/input_mapping.h"
  7. namespace InputCommon {
  8. MappingFactory::MappingFactory() {}
  9. void MappingFactory::BeginMapping(Polling::InputType type) {
  10. is_enabled = true;
  11. input_type = type;
  12. input_queue.Clear();
  13. first_axis = -1;
  14. second_axis = -1;
  15. }
  16. [[nodiscard]] const Common::ParamPackage MappingFactory::GetNextInput() {
  17. Common::ParamPackage input;
  18. input_queue.Pop(input);
  19. return input;
  20. }
  21. void MappingFactory::RegisterInput(const MappingData& data) {
  22. if (!is_enabled) {
  23. return;
  24. }
  25. if (!IsDriverValid(data)) {
  26. return;
  27. }
  28. switch (input_type) {
  29. case Polling::InputType::Button:
  30. RegisterButton(data);
  31. return;
  32. case Polling::InputType::Stick:
  33. RegisterStick(data);
  34. return;
  35. case Polling::InputType::Motion:
  36. RegisterMotion(data);
  37. return;
  38. default:
  39. return;
  40. }
  41. }
  42. void MappingFactory::StopMapping() {
  43. is_enabled = false;
  44. input_type = Polling::InputType::None;
  45. input_queue.Clear();
  46. }
  47. void MappingFactory::RegisterButton(const MappingData& data) {
  48. Common::ParamPackage new_input;
  49. new_input.Set("engine", data.engine);
  50. if (data.pad.guid != Common::UUID{}) {
  51. new_input.Set("guid", data.pad.guid.Format());
  52. }
  53. new_input.Set("port", static_cast<int>(data.pad.port));
  54. new_input.Set("pad", static_cast<int>(data.pad.pad));
  55. switch (data.type) {
  56. case EngineInputType::Button:
  57. // Workaround for old compatibility
  58. if (data.engine == "keyboard") {
  59. new_input.Set("code", data.index);
  60. break;
  61. }
  62. new_input.Set("button", data.index);
  63. break;
  64. case EngineInputType::HatButton:
  65. new_input.Set("hat", data.index);
  66. new_input.Set("direction", data.hat_name);
  67. break;
  68. case EngineInputType::Analog:
  69. new_input.Set("axis", data.index);
  70. new_input.Set("threshold", 0.5f);
  71. break;
  72. default:
  73. return;
  74. }
  75. input_queue.Push(new_input);
  76. }
  77. void MappingFactory::RegisterStick(const MappingData& data) {
  78. Common::ParamPackage new_input;
  79. new_input.Set("engine", data.engine);
  80. if (data.pad.guid != Common::UUID{}) {
  81. new_input.Set("guid", data.pad.guid.Format());
  82. }
  83. new_input.Set("port", static_cast<int>(data.pad.port));
  84. new_input.Set("pad", static_cast<int>(data.pad.pad));
  85. // If engine is mouse map the mouse position as a joystick
  86. if (data.engine == "mouse") {
  87. new_input.Set("axis_x", 0);
  88. new_input.Set("axis_y", 1);
  89. new_input.Set("threshold", 0.5f);
  90. new_input.Set("range", 1.0f);
  91. new_input.Set("deadzone", 0.0f);
  92. input_queue.Push(new_input);
  93. return;
  94. }
  95. switch (data.type) {
  96. case EngineInputType::Button:
  97. case EngineInputType::HatButton:
  98. RegisterButton(data);
  99. return;
  100. case EngineInputType::Analog:
  101. if (first_axis == data.index) {
  102. return;
  103. }
  104. if (first_axis == -1) {
  105. first_axis = data.index;
  106. return;
  107. }
  108. new_input.Set("axis_x", first_axis);
  109. new_input.Set("axis_y", data.index);
  110. new_input.Set("threshold", 0.5f);
  111. new_input.Set("range", 0.95f);
  112. new_input.Set("deadzone", 0.15f);
  113. break;
  114. default:
  115. return;
  116. }
  117. input_queue.Push(new_input);
  118. }
  119. void MappingFactory::RegisterMotion(const MappingData& data) {
  120. Common::ParamPackage new_input;
  121. new_input.Set("engine", data.engine);
  122. if (data.pad.guid != Common::UUID{}) {
  123. new_input.Set("guid", data.pad.guid.Format());
  124. }
  125. new_input.Set("port", static_cast<int>(data.pad.port));
  126. new_input.Set("pad", static_cast<int>(data.pad.pad));
  127. switch (data.type) {
  128. case EngineInputType::Button:
  129. case EngineInputType::HatButton:
  130. RegisterButton(data);
  131. return;
  132. case EngineInputType::Analog:
  133. if (first_axis == data.index) {
  134. return;
  135. }
  136. if (second_axis == data.index) {
  137. return;
  138. }
  139. if (first_axis == -1) {
  140. first_axis = data.index;
  141. return;
  142. }
  143. if (second_axis == -1) {
  144. second_axis = data.index;
  145. return;
  146. }
  147. new_input.Set("axis_x", first_axis);
  148. new_input.Set("axis_y", second_axis);
  149. new_input.Set("axis_z", data.index);
  150. new_input.Set("range", 1.0f);
  151. new_input.Set("deadzone", 0.20f);
  152. break;
  153. case EngineInputType::Motion:
  154. new_input.Set("motion", data.index);
  155. break;
  156. default:
  157. return;
  158. }
  159. input_queue.Push(new_input);
  160. }
  161. bool MappingFactory::IsDriverValid(const MappingData& data) const {
  162. // Only port 0 can be mapped on the keyboard
  163. if (data.engine == "keyboard" && data.pad.port != 0) {
  164. return false;
  165. }
  166. // The following drivers don't need to be mapped
  167. if (data.engine == "tas") {
  168. return false;
  169. }
  170. if (data.engine == "touch") {
  171. return false;
  172. }
  173. if (data.engine == "touch_from_button") {
  174. return false;
  175. }
  176. if (data.engine == "analog_from_button") {
  177. return false;
  178. }
  179. return true;
  180. }
  181. } // namespace InputCommon