diff --git a/Source/RMG-Input/UserInterface/MainDialog.cpp b/Source/RMG-Input/UserInterface/MainDialog.cpp index a7557a55..4ea450fd 100644 --- a/Source/RMG-Input/UserInterface/MainDialog.cpp +++ b/Source/RMG-Input/UserInterface/MainDialog.cpp @@ -54,7 +54,8 @@ MainDialog::MainDialog(QWidget* parent, Thread::SDLThread* sdlThread) : QDialog( // always add keyboard device for (auto& controllerWidget : this->controllerWidgets) { - controllerWidget->AddInputDevice("Keyboard", -1); + controllerWidget->AddInputDevice("Automatic", -2); + controllerWidget->AddInputDevice("Keyboard", -1); } // fill device list at least once @@ -90,29 +91,45 @@ void MainDialog::openInputDevice(QString deviceName, int deviceNum) { SDL_JoystickID joystickId; Widget::ControllerWidget* controllerWidget; - controllerWidget = controllerWidgets.at(this->tabWidget->currentIndex()); + controllerWidget = this->controllerWidgets.at(this->tabWidget->currentIndex()); // we don't need to open a keyboard if (deviceNum == -1) { - currentDeviceName = ""; - currentDeviceNum = -1; + this->currentDeviceName = ""; + this->currentDeviceNum = -1; controllerWidget->SetCurrentJoystickID(-1); return; } + // handle automatic mode + if (deviceNum == -2) + { + int currentIndex = this->tabWidget->currentIndex(); + if (currentIndex < this->inputDeviceList.size()) + { // use device when there's one + deviceNum = this->inputDeviceList.at(currentIndex).deviceNum; + } + else + { // no device found, fallback to keyboard + this->currentDeviceName = ""; + this->currentDeviceNum = -1; + return; + } + } + if (SDL_IsGameController(deviceNum) == SDL_TRUE) { - currentJoystick = nullptr; - currentController = SDL_GameControllerOpen(deviceNum); + this->currentJoystick = nullptr; + this->currentController = SDL_GameControllerOpen(deviceNum); } else { - currentJoystick = SDL_JoystickOpen(deviceNum); - currentController = nullptr; + this->currentJoystick = SDL_JoystickOpen(deviceNum); + this->currentController = nullptr; } - currentDeviceNum = deviceNum; + this->currentDeviceNum = deviceNum; joystickId = SDL_JoystickGetDeviceInstanceID(deviceNum); controllerWidget->SetCurrentJoystickID(joystickId); controllerWidget->SetIsCurrentJoystickGameController(currentController != nullptr); diff --git a/Source/RMG-Input/UserInterface/MainDialog.hpp b/Source/RMG-Input/UserInterface/MainDialog.hpp index 56403f4a..5d2402b0 100644 --- a/Source/RMG-Input/UserInterface/MainDialog.hpp +++ b/Source/RMG-Input/UserInterface/MainDialog.hpp @@ -43,7 +43,7 @@ private: bool updatingDeviceList = false; QList controllerWidgets; - SDL_Joystick* currentJoystick = nullptr; + SDL_Joystick* currentJoystick = nullptr; SDL_GameController* currentController = nullptr; QString currentDeviceName; int currentDeviceNum = 0; diff --git a/Source/RMG-Input/UserInterface/Widget/ControllerWidget.cpp b/Source/RMG-Input/UserInterface/Widget/ControllerWidget.cpp index 94121b64..5d3e70f0 100644 --- a/Source/RMG-Input/UserInterface/Widget/ControllerWidget.cpp +++ b/Source/RMG-Input/UserInterface/Widget/ControllerWidget.cpp @@ -269,7 +269,7 @@ void ControllerWidget::AddInputDevice(QString deviceName, int deviceNum) { QString name = deviceName; - if (deviceNum != -1) + if (deviceNum >= 0) { name += " ("; name += QString::number(deviceNum); @@ -337,6 +337,10 @@ void ControllerWidget::CheckInputDeviceSettings() (this->inputDeviceComboBox->itemText(deviceNumIndex).startsWith(QString::fromStdString(deviceName)))) { // full match this->inputDeviceComboBox->setCurrentIndex(deviceNumIndex); + if (deviceNum == -2) + { // need to force-refresh when set to automatic + this->on_inputDeviceComboBox_currentIndexChanged(0); + } } else if (deviceNameIndex != -1) { // name only match @@ -1020,8 +1024,8 @@ void ControllerWidget::SaveDefaultSettings() std::string section = this->settingsSection.toStdString(); CoreSettingsSetValue(SettingsID::Input_PluggedIn, section, false); - CoreSettingsSetValue(SettingsID::Input_DeviceName, section, std::string("Keyboard")); - CoreSettingsSetValue(SettingsID::Input_DeviceNum, section, -1); + CoreSettingsSetValue(SettingsID::Input_DeviceName, section, std::string("Automatic")); + CoreSettingsSetValue(SettingsID::Input_DeviceNum, section, -2); CoreSettingsSetValue(SettingsID::Input_Deadzone, section, 9); CoreSettingsSetValue(SettingsID::Input_Pak, section, 0); CoreSettingsSetValue(SettingsID::Input_RemoveDuplicateMappings, section, true); diff --git a/Source/RMG-Input/main.cpp b/Source/RMG-Input/main.cpp index 74b9b354..036bc819 100644 --- a/Source/RMG-Input/main.cpp +++ b/Source/RMG-Input/main.cpp @@ -269,15 +269,76 @@ static void apply_gameboy_settings(void) CoreSettingsSave(); } +static void open_controller_automatic(int num, InputProfile* profile) +{ + static int previousSdlDeviceNum = -1; + + // reset variable when needed + if (num == 0) + { + previousSdlDeviceNum = -1; + } + + bool foundSdlDevice = false; + SDL_GameController* sdlGameController = nullptr; + SDL_Joystick* sdlJoystick = nullptr; + std::string sdlDeviceName; + + for (int i = (previousSdlDeviceNum + 1); i < SDL_NumJoysticks(); i++) + { + if (SDL_IsGameController(i)) + { + sdlGameController = SDL_GameControllerOpen(i); + if (sdlGameController != nullptr) + { + sdlDeviceName = SDL_GameControllerName(sdlGameController); + SDL_GameControllerClose(sdlGameController); + profile->DeviceNum = i; + profile->DeviceName = sdlDeviceName; + previousSdlDeviceNum = i; + foundSdlDevice = true; + break; + } + } + else + { + sdlJoystick = SDL_JoystickOpen(i); + if (sdlJoystick != nullptr) + { + sdlDeviceName = SDL_JoystickName(sdlJoystick); + SDL_JoystickClose(sdlJoystick); + profile->DeviceNum = i; + profile->DeviceName = sdlDeviceName; + previousSdlDeviceNum = i; + foundSdlDevice = true; + break; + } + } + } + + if (!foundSdlDevice) + { // fallback to keyboard + profile->DeviceNum = -1; + } +} + static void open_controllers(void) { + // force SDL to re-load joysticks + SDL_PumpEvents(); + for (int i = 0; i < NUM_CONTROLLERS; i++) { InputProfile* profile = &l_InputProfiles[i]; profile->InputDevice.CloseDevice(); - if (profile->DeviceNum != -1) + // handle automatic mode + if (profile->DeviceNum == -2) + { + open_controller_automatic(i, profile); + } + else if (profile->DeviceNum != -1) { profile->InputDevice.OpenDevice(profile->DeviceName, profile->DeviceNum); } @@ -710,7 +771,6 @@ EXPORT void CALL GetKeys(int Control, BUTTONS* Keys) if (!profile->InputDevice.HasOpenDevice() || !profile->InputDevice.IsAttached()) { profile->InputDevice.OpenDevice(profile->DeviceName, profile->DeviceNum); - return; } } } @@ -756,7 +816,7 @@ EXPORT void CALL InitiateControllers(CONTROL_INFO ControlInfo) l_KeyboardState[i] = 0; } - l_ControlInfo = ControlInfo; + l_ControlInfo = ControlInfo; l_HasControlInfo = true; // load settings