mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Merge pull request #5851 from flibitijibibo/master
Add support for SDL controller accelerometer/gyro events
This commit is contained in:
		
						commit
						28039d39a1
					
				
					 6 changed files with 187 additions and 4 deletions
				
			
		|  | @ -144,7 +144,7 @@ if (ENABLE_SDL2) | ||||||
|     if (CITRA_USE_BUNDLED_SDL2) |     if (CITRA_USE_BUNDLED_SDL2) | ||||||
|         # Detect toolchain and platform |         # Detect toolchain and platform | ||||||
|         if ((MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1930) AND ARCHITECTURE_x86_64) |         if ((MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1930) AND ARCHITECTURE_x86_64) | ||||||
|             set(SDL2_VER "SDL2-2.0.12") |             set(SDL2_VER "SDL2-2.0.16") | ||||||
|         else() |         else() | ||||||
|             message(FATAL_ERROR "No bundled SDL2 binaries for your toolchain. Disable CITRA_USE_BUNDLED_SDL2 and provide your own.") |             message(FATAL_ERROR "No bundled SDL2 binaries for your toolchain. Disable CITRA_USE_BUNDLED_SDL2 and provide your own.") | ||||||
|         endif() |         endif() | ||||||
|  |  | ||||||
|  | @ -7,6 +7,7 @@ | ||||||
| #include <QLabel> | #include <QLabel> | ||||||
| #include <QMessageBox> | #include <QMessageBox> | ||||||
| #include <QPushButton> | #include <QPushButton> | ||||||
|  | #include <QTimer> | ||||||
| #include <QVBoxLayout> | #include <QVBoxLayout> | ||||||
| #include "citra_qt/configuration/configure_motion_touch.h" | #include "citra_qt/configuration/configure_motion_touch.h" | ||||||
| #include "citra_qt/configuration/configure_touch_from_button.h" | #include "citra_qt/configuration/configure_touch_from_button.h" | ||||||
|  | @ -70,16 +71,18 @@ void CalibrationConfigurationDialog::UpdateButtonText(QString text) { | ||||||
|     cancel_button->setText(text); |     cancel_button->setText(text); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const std::array<std::pair<const char*, const char*>, 2> MotionProviders = { | const std::array<std::pair<const char*, const char*>, 3> MotionProviders = { | ||||||
|     {{"motion_emu", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "Mouse (Right Click)")}, |     {{"motion_emu", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "Mouse (Right Click)")}, | ||||||
|      {"cemuhookudp", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "CemuhookUDP")}}}; |      {"cemuhookudp", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "CemuhookUDP")}, | ||||||
|  |      {"sdl", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "SDL")}}}; | ||||||
| 
 | 
 | ||||||
| const std::array<std::pair<const char*, const char*>, 2> TouchProviders = { | const std::array<std::pair<const char*, const char*>, 2> TouchProviders = { | ||||||
|     {{"emu_window", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "Emulator Window")}, |     {{"emu_window", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "Emulator Window")}, | ||||||
|      {"cemuhookudp", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "CemuhookUDP")}}}; |      {"cemuhookudp", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "CemuhookUDP")}}}; | ||||||
| 
 | 
 | ||||||
| ConfigureMotionTouch::ConfigureMotionTouch(QWidget* parent) | ConfigureMotionTouch::ConfigureMotionTouch(QWidget* parent) | ||||||
|     : QDialog(parent), ui(std::make_unique<Ui::ConfigureMotionTouch>()) { |     : QDialog(parent), ui(std::make_unique<Ui::ConfigureMotionTouch>()), | ||||||
|  |       timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()) { | ||||||
|     ui->setupUi(this); |     ui->setupUi(this); | ||||||
|     for (auto [provider, name] : MotionProviders) { |     for (auto [provider, name] : MotionProviders) { | ||||||
|         ui->motion_provider->addItem(tr(name), QString::fromUtf8(provider)); |         ui->motion_provider->addItem(tr(name), QString::fromUtf8(provider)); | ||||||
|  | @ -95,6 +98,22 @@ ConfigureMotionTouch::ConfigureMotionTouch(QWidget* parent) | ||||||
|            "using-a-controller-or-android-phone-for-motion-or-touch-input'><span " |            "using-a-controller-or-android-phone-for-motion-or-touch-input'><span " | ||||||
|            "style=\"text-decoration: underline; color:#039be5;\">Learn More</span></a>")); |            "style=\"text-decoration: underline; color:#039be5;\">Learn More</span></a>")); | ||||||
| 
 | 
 | ||||||
|  |     timeout_timer->setSingleShot(true); | ||||||
|  |     connect(timeout_timer.get(), &QTimer::timeout, [this]() { SetPollingResult({}, true); }); | ||||||
|  | 
 | ||||||
|  |     connect(poll_timer.get(), &QTimer::timeout, [this]() { | ||||||
|  |         Common::ParamPackage params; | ||||||
|  |         for (auto& poller : device_pollers) { | ||||||
|  |             params = poller->GetNextInput(); | ||||||
|  |             // We want all the input systems to be in a "polling" state, but we only care about the
 | ||||||
|  |             // input from SDL.
 | ||||||
|  |             if (params.Has("engine") && params.Get("engine", "") == "sdl") { | ||||||
|  |                 SetPollingResult(params, false); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|     SetConfiguration(); |     SetConfiguration(); | ||||||
|     UpdateUiDisplay(); |     UpdateUiDisplay(); | ||||||
|     ConnectEvents(); |     ConnectEvents(); | ||||||
|  | @ -122,6 +141,9 @@ void ConfigureMotionTouch::SetConfiguration() { | ||||||
|         Settings::values.current_input_profile.touch_from_button_map_index); |         Settings::values.current_input_profile.touch_from_button_map_index); | ||||||
|     ui->motion_sensitivity->setValue(motion_param.Get("sensitivity", 0.01f)); |     ui->motion_sensitivity->setValue(motion_param.Get("sensitivity", 0.01f)); | ||||||
| 
 | 
 | ||||||
|  |     guid = motion_param.Get("guid", "0"); | ||||||
|  |     port = motion_param.Get("port", 0); | ||||||
|  | 
 | ||||||
|     min_x = touch_param.Get("min_x", 100); |     min_x = touch_param.Get("min_x", 100); | ||||||
|     min_y = touch_param.Get("min_y", 50); |     min_y = touch_param.Get("min_y", 50); | ||||||
|     max_x = touch_param.Get("max_x", 1800); |     max_x = touch_param.Get("max_x", 1800); | ||||||
|  | @ -145,6 +167,14 @@ void ConfigureMotionTouch::UpdateUiDisplay() { | ||||||
|         ui->motion_sensitivity->setVisible(false); |         ui->motion_sensitivity->setVisible(false); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if (motion_engine == "sdl") { | ||||||
|  |         ui->motion_controller_label->setVisible(true); | ||||||
|  |         ui->motion_controller_button->setVisible(true); | ||||||
|  |     } else { | ||||||
|  |         ui->motion_controller_label->setVisible(false); | ||||||
|  |         ui->motion_controller_button->setVisible(false); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if (touch_engine == "cemuhookudp") { |     if (touch_engine == "cemuhookudp") { | ||||||
|         ui->touch_calibration->setVisible(true); |         ui->touch_calibration->setVisible(true); | ||||||
|         ui->touch_calibration_config->setVisible(true); |         ui->touch_calibration_config->setVisible(true); | ||||||
|  | @ -172,6 +202,30 @@ void ConfigureMotionTouch::ConnectEvents() { | ||||||
|     connect(ui->touch_provider, |     connect(ui->touch_provider, | ||||||
|             static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, |             static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, | ||||||
|             [this]([[maybe_unused]] int index) { UpdateUiDisplay(); }); |             [this]([[maybe_unused]] int index) { UpdateUiDisplay(); }); | ||||||
|  |     connect(ui->motion_controller_button, &QPushButton::clicked, [=]() { | ||||||
|  |         if (QMessageBox::information(this, tr("Information"), | ||||||
|  |                                      tr("After pressing OK, press a button on the controller whose " | ||||||
|  |                                         "motion you want to track."), | ||||||
|  |                                      QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) { | ||||||
|  |             ui->motion_controller_button->setText(tr("[press button]")); | ||||||
|  |             ui->motion_controller_button->setFocus(); | ||||||
|  | 
 | ||||||
|  |             input_setter = [=](const Common::ParamPackage& params) { | ||||||
|  |                 guid = params.Get("guid", "0"); | ||||||
|  |                 port = params.Get("port", 0); | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             device_pollers = | ||||||
|  |                 InputCommon::Polling::GetPollers(InputCommon::Polling::DeviceType::Button); | ||||||
|  | 
 | ||||||
|  |             for (auto& poller : device_pollers) { | ||||||
|  |                 poller->Start(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             timeout_timer->start(5000); // Cancel after 5 seconds
 | ||||||
|  |             poll_timer->start(200);     // Check for new inputs every 200ms
 | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|     connect(ui->udp_test, &QPushButton::clicked, this, &ConfigureMotionTouch::OnCemuhookUDPTest); |     connect(ui->udp_test, &QPushButton::clicked, this, &ConfigureMotionTouch::OnCemuhookUDPTest); | ||||||
|     connect(ui->touch_calibration_config, &QPushButton::clicked, this, |     connect(ui->touch_calibration_config, &QPushButton::clicked, this, | ||||||
|             &ConfigureMotionTouch::OnConfigureTouchCalibration); |             &ConfigureMotionTouch::OnConfigureTouchCalibration); | ||||||
|  | @ -183,6 +237,21 @@ void ConfigureMotionTouch::ConnectEvents() { | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void ConfigureMotionTouch::SetPollingResult(const Common::ParamPackage& params, bool abort) { | ||||||
|  |     timeout_timer->stop(); | ||||||
|  |     poll_timer->stop(); | ||||||
|  |     for (auto& poller : device_pollers) { | ||||||
|  |         poller->Stop(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!abort && input_setter) { | ||||||
|  |         (*input_setter)(params); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ui->motion_controller_button->setText(tr("Configure")); | ||||||
|  |     input_setter.reset(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void ConfigureMotionTouch::OnCemuhookUDPTest() { | void ConfigureMotionTouch::OnCemuhookUDPTest() { | ||||||
|     ui->udp_test->setEnabled(false); |     ui->udp_test->setEnabled(false); | ||||||
|     ui->udp_test->setText(tr("Testing")); |     ui->udp_test->setText(tr("Testing")); | ||||||
|  | @ -285,6 +354,9 @@ void ConfigureMotionTouch::ApplyConfiguration() { | ||||||
| 
 | 
 | ||||||
|     if (motion_engine == "motion_emu") { |     if (motion_engine == "motion_emu") { | ||||||
|         motion_param.Set("sensitivity", static_cast<float>(ui->motion_sensitivity->value())); |         motion_param.Set("sensitivity", static_cast<float>(ui->motion_sensitivity->value())); | ||||||
|  |     } else if (motion_engine == "sdl") { | ||||||
|  |         motion_param.Set("guid", guid); | ||||||
|  |         motion_param.Set("port", port); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (touch_engine == "cemuhookudp") { |     if (touch_engine == "cemuhookudp") { | ||||||
|  |  | ||||||
|  | @ -8,11 +8,13 @@ | ||||||
| #include <QDialog> | #include <QDialog> | ||||||
| #include "common/param_package.h" | #include "common/param_package.h" | ||||||
| #include "core/settings.h" | #include "core/settings.h" | ||||||
|  | #include "input_common/main.h" | ||||||
| #include "input_common/udp/udp.h" | #include "input_common/udp/udp.h" | ||||||
| 
 | 
 | ||||||
| class QVBoxLayout; | class QVBoxLayout; | ||||||
| class QLabel; | class QLabel; | ||||||
| class QPushButton; | class QPushButton; | ||||||
|  | class QTimer; | ||||||
| 
 | 
 | ||||||
| namespace Ui { | namespace Ui { | ||||||
| class ConfigureMotionTouch; | class ConfigureMotionTouch; | ||||||
|  | @ -63,10 +65,21 @@ private: | ||||||
|     void SetConfiguration(); |     void SetConfiguration(); | ||||||
|     void UpdateUiDisplay(); |     void UpdateUiDisplay(); | ||||||
|     void ConnectEvents(); |     void ConnectEvents(); | ||||||
|  |     void SetPollingResult(const Common::ParamPackage& params, bool abort); | ||||||
|     bool CanCloseDialog(); |     bool CanCloseDialog(); | ||||||
| 
 | 
 | ||||||
|     std::unique_ptr<Ui::ConfigureMotionTouch> ui; |     std::unique_ptr<Ui::ConfigureMotionTouch> ui; | ||||||
| 
 | 
 | ||||||
|  |     // Used for SDL input polling
 | ||||||
|  |     std::string guid; | ||||||
|  |     int port; | ||||||
|  |     std::unique_ptr<QTimer> timeout_timer; | ||||||
|  |     std::unique_ptr<QTimer> poll_timer; | ||||||
|  |     std::vector<std::unique_ptr<InputCommon::Polling::DevicePoller>> device_pollers; | ||||||
|  | 
 | ||||||
|  |     /// This will be the the setting function when an input is awaiting configuration.
 | ||||||
|  |     std::optional<std::function<void(const Common::ParamPackage&)>> input_setter; | ||||||
|  | 
 | ||||||
|     // Coordinate system of the CemuhookUDP touch provider
 |     // Coordinate system of the CemuhookUDP touch provider
 | ||||||
|     int min_x, min_y, max_x, max_y; |     int min_x, min_y, max_x, max_y; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -67,6 +67,24 @@ | ||||||
|         </item> |         </item> | ||||||
|        </layout> |        </layout> | ||||||
|       </item> |       </item> | ||||||
|  |       <item> | ||||||
|  |        <layout class="QHBoxLayout"> | ||||||
|  |         <item> | ||||||
|  |          <widget class="QLabel" name="motion_controller_label"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>Controller:</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item> | ||||||
|  |          <widget class="QPushButton" name="motion_controller_button"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>Configure</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |        </layout> | ||||||
|  |       </item> | ||||||
|      </layout> |      </layout> | ||||||
|     </widget> |     </widget> | ||||||
|    </item> |    </item> | ||||||
|  |  | ||||||
|  | @ -173,6 +173,24 @@ public: | ||||||
|         std::lock_guard lock{mutex}; |         std::lock_guard lock{mutex}; | ||||||
|         return (state.hats.at(hat) & direction) != 0; |         return (state.hats.at(hat) & direction) != 0; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     void SetAccel(const float x, const float y, const float z) { | ||||||
|  |         std::lock_guard lock{mutex}; | ||||||
|  |         state.accel.x = x; | ||||||
|  |         state.accel.y = y; | ||||||
|  |         state.accel.z = z; | ||||||
|  |     } | ||||||
|  |     void SetGyro(const float pitch, const float yaw, const float roll) { | ||||||
|  |         std::lock_guard lock{mutex}; | ||||||
|  |         state.gyro.x = pitch; | ||||||
|  |         state.gyro.y = yaw; | ||||||
|  |         state.gyro.z = roll; | ||||||
|  |     } | ||||||
|  |     std::tuple<Common::Vec3<float>, Common::Vec3<float>> GetMotion() const { | ||||||
|  |         std::lock_guard lock{mutex}; | ||||||
|  |         return std::make_tuple(state.accel, state.gyro); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * The guid of the joystick |      * The guid of the joystick | ||||||
|      */ |      */ | ||||||
|  | @ -204,6 +222,8 @@ private: | ||||||
|         std::unordered_map<int, bool> buttons; |         std::unordered_map<int, bool> buttons; | ||||||
|         std::unordered_map<int, Sint16> axes; |         std::unordered_map<int, Sint16> axes; | ||||||
|         std::unordered_map<int, Uint8> hats; |         std::unordered_map<int, Uint8> hats; | ||||||
|  |         Common::Vec3<float> accel; | ||||||
|  |         Common::Vec3<float> gyro; | ||||||
|     } state; |     } state; | ||||||
|     std::string guid; |     std::string guid; | ||||||
|     int port; |     int port; | ||||||
|  | @ -473,6 +493,14 @@ void SDLState::InitGameController(int controller_index) { | ||||||
|         LOG_WARNING(Input, "failed to open joystick {} as controller", controller_index); |         LOG_WARNING(Input, "failed to open joystick {} as controller", controller_index); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  | #if SDL_VERSION_ATLEAST(2, 0, 14) | ||||||
|  |     if (SDL_GameControllerHasSensor(sdl_controller, SDL_SENSOR_ACCEL)) { | ||||||
|  |         SDL_GameControllerSetSensorEnabled(sdl_controller, SDL_SENSOR_ACCEL, SDL_TRUE); | ||||||
|  |     } | ||||||
|  |     if (SDL_GameControllerHasSensor(sdl_controller, SDL_SENSOR_GYRO)) { | ||||||
|  |         SDL_GameControllerSetSensorEnabled(sdl_controller, SDL_SENSOR_GYRO, SDL_TRUE); | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|     const std::string guid = GetGUID(SDL_GameControllerGetJoystick(sdl_controller)); |     const std::string guid = GetGUID(SDL_GameControllerGetJoystick(sdl_controller)); | ||||||
| 
 | 
 | ||||||
|     LOG_INFO(Input, "opened joystick {} as controller", controller_index); |     LOG_INFO(Input, "opened joystick {} as controller", controller_index); | ||||||
|  | @ -557,6 +585,25 @@ void SDLState::HandleGameControllerEvent(const SDL_Event& event) { | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|  | #if SDL_VERSION_ATLEAST(2, 0, 14) | ||||||
|  |     case SDL_CONTROLLERSENSORUPDATE: { | ||||||
|  |         if (auto joystick = GetSDLJoystickBySDLID(event.csensor.which)) { | ||||||
|  |             switch (event.csensor.sensor) { | ||||||
|  |             case SDL_SENSOR_ACCEL: | ||||||
|  |                 joystick->SetAccel(event.csensor.data[0] / SDL_STANDARD_GRAVITY, | ||||||
|  |                                    -event.csensor.data[1] / SDL_STANDARD_GRAVITY, | ||||||
|  |                                    event.csensor.data[2] / SDL_STANDARD_GRAVITY); | ||||||
|  |                 break; | ||||||
|  |             case SDL_SENSOR_GYRO: | ||||||
|  |                 joystick->SetGyro(-event.csensor.data[0] * (180.0f / Common::PI), | ||||||
|  |                                   event.csensor.data[1] * (180.0f / Common::PI), | ||||||
|  |                                   -event.csensor.data[2] * (180.0f / Common::PI)); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|     case SDL_JOYDEVICEREMOVED: |     case SDL_JOYDEVICEREMOVED: | ||||||
|         LOG_DEBUG(Input, "Joystick removed with Instance_ID {}", event.jdevice.which); |         LOG_DEBUG(Input, "Joystick removed with Instance_ID {}", event.jdevice.which); | ||||||
|         CloseJoystick(SDL_JoystickFromInstanceID(event.jdevice.which)); |         CloseJoystick(SDL_JoystickFromInstanceID(event.jdevice.which)); | ||||||
|  | @ -658,6 +705,18 @@ private: | ||||||
|     const float deadzone; |     const float deadzone; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | class SDLMotion final : public Input::MotionDevice { | ||||||
|  | public: | ||||||
|  |     explicit SDLMotion(std::shared_ptr<SDLJoystick> joystick_) : joystick(std::move(joystick_)) {} | ||||||
|  | 
 | ||||||
|  |     std::tuple<Common::Vec3<float>, Common::Vec3<float>> GetStatus() const override { | ||||||
|  |         return joystick->GetMotion(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     std::shared_ptr<SDLJoystick> joystick; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| /// A button device factory that creates button devices from SDL joystick
 | /// A button device factory that creates button devices from SDL joystick
 | ||||||
| class SDLButtonFactory final : public Input::Factory<Input::ButtonDevice> { | class SDLButtonFactory final : public Input::Factory<Input::ButtonDevice> { | ||||||
| public: | public: | ||||||
|  | @ -764,10 +823,28 @@ private: | ||||||
|     SDLState& state; |     SDLState& state; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | class SDLMotionFactory final : public Input::Factory<Input::MotionDevice> { | ||||||
|  | public: | ||||||
|  |     explicit SDLMotionFactory(SDLState& state_) : state(state_) {} | ||||||
|  | 
 | ||||||
|  |     std::unique_ptr<Input::MotionDevice> Create(const Common::ParamPackage& params) override { | ||||||
|  |         const std::string guid = params.Get("guid", "0"); | ||||||
|  |         const int port = params.Get("port", 0); | ||||||
|  | 
 | ||||||
|  |         auto joystick = state.GetSDLJoystickByGUID(guid, port); | ||||||
|  | 
 | ||||||
|  |         return std::make_unique<SDLMotion>(joystick); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     SDLState& state; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| SDLState::SDLState() { | SDLState::SDLState() { | ||||||
|     using namespace Input; |     using namespace Input; | ||||||
|     RegisterFactory<ButtonDevice>("sdl", std::make_shared<SDLButtonFactory>(*this)); |     RegisterFactory<ButtonDevice>("sdl", std::make_shared<SDLButtonFactory>(*this)); | ||||||
|     RegisterFactory<AnalogDevice>("sdl", std::make_shared<SDLAnalogFactory>(*this)); |     RegisterFactory<AnalogDevice>("sdl", std::make_shared<SDLAnalogFactory>(*this)); | ||||||
|  |     RegisterFactory<MotionDevice>("sdl", std::make_shared<SDLMotionFactory>(*this)); | ||||||
| 
 | 
 | ||||||
|     // If the frontend is going to manage the event loop, then we dont start one here
 |     // If the frontend is going to manage the event loop, then we dont start one here
 | ||||||
|     start_thread = !SDL_WasInit(SDL_INIT_GAMECONTROLLER); |     start_thread = !SDL_WasInit(SDL_INIT_GAMECONTROLLER); | ||||||
|  | @ -812,6 +889,7 @@ SDLState::~SDLState() { | ||||||
|     using namespace Input; |     using namespace Input; | ||||||
|     UnregisterFactory<ButtonDevice>("sdl"); |     UnregisterFactory<ButtonDevice>("sdl"); | ||||||
|     UnregisterFactory<AnalogDevice>("sdl"); |     UnregisterFactory<AnalogDevice>("sdl"); | ||||||
|  |     UnregisterFactory<MotionDevice>("sdl"); | ||||||
| 
 | 
 | ||||||
|     CloseJoysticks(); |     CloseJoysticks(); | ||||||
|     CloseGameControllers(); |     CloseGameControllers(); | ||||||
|  |  | ||||||
|  | @ -22,6 +22,7 @@ class SDLJoystick; | ||||||
| class SDLGameController; | class SDLGameController; | ||||||
| class SDLButtonFactory; | class SDLButtonFactory; | ||||||
| class SDLAnalogFactory; | class SDLAnalogFactory; | ||||||
|  | class SDLMotionFactory; | ||||||
| 
 | 
 | ||||||
| class SDLState : public State { | class SDLState : public State { | ||||||
| public: | public: | ||||||
|  | @ -73,6 +74,7 @@ private: | ||||||
| 
 | 
 | ||||||
|     std::shared_ptr<SDLButtonFactory> button_factory; |     std::shared_ptr<SDLButtonFactory> button_factory; | ||||||
|     std::shared_ptr<SDLAnalogFactory> analog_factory; |     std::shared_ptr<SDLAnalogFactory> analog_factory; | ||||||
|  |     std::shared_ptr<SDLMotionFactory> motion_factory; | ||||||
| 
 | 
 | ||||||
|     bool start_thread = false; |     bool start_thread = false; | ||||||
|     std::atomic<bool> initialized = false; |     std::atomic<bool> initialized = false; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue