main.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. // Copyright 2017 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <memory>
  5. #include <thread>
  6. #include "common/param_package.h"
  7. #include "input_common/analog_from_button.h"
  8. #include "input_common/gcadapter/gc_adapter.h"
  9. #include "input_common/gcadapter/gc_poller.h"
  10. #include "input_common/keyboard.h"
  11. #include "input_common/main.h"
  12. #include "input_common/motion_emu.h"
  13. #include "input_common/udp/udp.h"
  14. #ifdef HAVE_SDL2
  15. #include "input_common/sdl/sdl.h"
  16. #endif
  17. namespace InputCommon {
  18. struct InputSubsystem::Impl {
  19. void Initialize() {
  20. auto gcadapter = std::make_shared<GCAdapter::Adapter>();
  21. gcbuttons = std::make_shared<GCButtonFactory>(gcadapter);
  22. Input::RegisterFactory<Input::ButtonDevice>("gcpad", gcbuttons);
  23. gcanalog = std::make_shared<GCAnalogFactory>(gcadapter);
  24. Input::RegisterFactory<Input::AnalogDevice>("gcpad", gcanalog);
  25. keyboard = std::make_shared<Keyboard>();
  26. Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard);
  27. Input::RegisterFactory<Input::AnalogDevice>("analog_from_button",
  28. std::make_shared<AnalogFromButton>());
  29. motion_emu = std::make_shared<MotionEmu>();
  30. Input::RegisterFactory<Input::MotionDevice>("motion_emu", motion_emu);
  31. #ifdef HAVE_SDL2
  32. sdl = SDL::Init();
  33. #endif
  34. udp = CemuhookUDP::Init();
  35. }
  36. void Shutdown() {
  37. Input::UnregisterFactory<Input::ButtonDevice>("keyboard");
  38. keyboard.reset();
  39. Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button");
  40. Input::UnregisterFactory<Input::MotionDevice>("motion_emu");
  41. motion_emu.reset();
  42. #ifdef HAVE_SDL2
  43. sdl.reset();
  44. #endif
  45. udp.reset();
  46. Input::UnregisterFactory<Input::ButtonDevice>("gcpad");
  47. Input::UnregisterFactory<Input::AnalogDevice>("gcpad");
  48. gcbuttons.reset();
  49. gcanalog.reset();
  50. }
  51. [[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const {
  52. std::vector<Common::ParamPackage> devices = {
  53. Common::ParamPackage{{"display", "Any"}, {"class", "any"}},
  54. Common::ParamPackage{{"display", "Keyboard/Mouse"}, {"class", "key"}},
  55. };
  56. #ifdef HAVE_SDL2
  57. auto sdl_devices = sdl->GetInputDevices();
  58. devices.insert(devices.end(), sdl_devices.begin(), sdl_devices.end());
  59. #endif
  60. auto udp_devices = udp->GetInputDevices();
  61. devices.insert(devices.end(), udp_devices.begin(), udp_devices.end());
  62. return devices;
  63. }
  64. [[nodiscard]] AnalogMapping GetAnalogMappingForDevice(
  65. const Common::ParamPackage& params) const {
  66. if (!params.Has("class") || params.Get("class", "") == "any") {
  67. return {};
  68. }
  69. if (params.Get("class", "") == "key") {
  70. // TODO consider returning the SDL key codes for the default keybindings
  71. return {};
  72. }
  73. #ifdef HAVE_SDL2
  74. if (params.Get("class", "") == "sdl") {
  75. return sdl->GetAnalogMappingForDevice(params);
  76. }
  77. #endif
  78. return {};
  79. }
  80. [[nodiscard]] ButtonMapping GetButtonMappingForDevice(
  81. const Common::ParamPackage& params) const {
  82. if (!params.Has("class") || params.Get("class", "") == "any") {
  83. return {};
  84. }
  85. if (params.Get("class", "") == "key") {
  86. // TODO consider returning the SDL key codes for the default keybindings
  87. return {};
  88. }
  89. #ifdef HAVE_SDL2
  90. if (params.Get("class", "") == "sdl") {
  91. return sdl->GetButtonMappingForDevice(params);
  92. }
  93. #endif
  94. return {};
  95. }
  96. std::shared_ptr<Keyboard> keyboard;
  97. std::shared_ptr<MotionEmu> motion_emu;
  98. #ifdef HAVE_SDL2
  99. std::unique_ptr<SDL::State> sdl;
  100. #endif
  101. std::unique_ptr<CemuhookUDP::State> udp;
  102. std::shared_ptr<GCButtonFactory> gcbuttons;
  103. std::shared_ptr<GCAnalogFactory> gcanalog;
  104. };
  105. InputSubsystem::InputSubsystem() : impl{std::make_unique<Impl>()} {}
  106. InputSubsystem::~InputSubsystem() = default;
  107. void InputSubsystem::Initialize() {
  108. impl->Initialize();
  109. }
  110. void InputSubsystem::Shutdown() {
  111. impl->Shutdown();
  112. }
  113. Keyboard* InputSubsystem::GetKeyboard() {
  114. return impl->keyboard.get();
  115. }
  116. const Keyboard* InputSubsystem::GetKeyboard() const {
  117. return impl->keyboard.get();
  118. }
  119. MotionEmu* InputSubsystem::GetMotionEmu() {
  120. return impl->motion_emu.get();
  121. }
  122. const MotionEmu* InputSubsystem::GetMotionEmu() const {
  123. return impl->motion_emu.get();
  124. }
  125. std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const {
  126. return impl->GetInputDevices();
  127. }
  128. AnalogMapping InputSubsystem::GetAnalogMappingForDevice(const Common::ParamPackage& device) const {
  129. return impl->GetAnalogMappingForDevice(device);
  130. }
  131. ButtonMapping InputSubsystem::GetButtonMappingForDevice(const Common::ParamPackage& device) const {
  132. return impl->GetButtonMappingForDevice(device);
  133. }
  134. GCAnalogFactory* InputSubsystem::GetGCAnalogs() {
  135. return impl->gcanalog.get();
  136. }
  137. const GCAnalogFactory* InputSubsystem::GetGCAnalogs() const {
  138. return impl->gcanalog.get();
  139. }
  140. GCButtonFactory* InputSubsystem::GetGCButtons() {
  141. return impl->gcbuttons.get();
  142. }
  143. const GCButtonFactory* InputSubsystem::GetGCButtons() const {
  144. return impl->gcbuttons.get();
  145. }
  146. std::vector<std::unique_ptr<Polling::DevicePoller>> InputSubsystem::GetPollers(
  147. Polling::DeviceType type) const {
  148. #ifdef HAVE_SDL2
  149. return impl->sdl->GetPollers(type);
  150. #else
  151. return {};
  152. #endif
  153. }
  154. std::string GenerateKeyboardParam(int key_code) {
  155. Common::ParamPackage param{
  156. {"engine", "keyboard"},
  157. {"code", std::to_string(key_code)},
  158. };
  159. return param.Serialize();
  160. }
  161. std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left, int key_right,
  162. int key_modifier, float modifier_scale) {
  163. Common::ParamPackage circle_pad_param{
  164. {"engine", "analog_from_button"},
  165. {"up", GenerateKeyboardParam(key_up)},
  166. {"down", GenerateKeyboardParam(key_down)},
  167. {"left", GenerateKeyboardParam(key_left)},
  168. {"right", GenerateKeyboardParam(key_right)},
  169. {"modifier", GenerateKeyboardParam(key_modifier)},
  170. {"modifier_scale", std::to_string(modifier_scale)},
  171. };
  172. return circle_pad_param.Serialize();
  173. }
  174. } // namespace InputCommon