From 8ccdc415bc692c726c92937ee7fde13cdcd5a1a8 Mon Sep 17 00:00:00 2001 From: Rosalie Wanders Date: Sat, 4 Feb 2023 22:10:06 +0100 Subject: [PATCH] RMG-Input: implement support for mapping multiple inputs --- Source/RMG-Input/CMakeLists.txt | 4 +- .../UserInterface/Widget/AddMappingButton.cpp | 33 + .../UserInterface/Widget/AddMappingButton.hpp | 43 + .../UserInterface/Widget/ControllerWidget.cpp | 287 +++--- .../UserInterface/Widget/ControllerWidget.hpp | 30 +- .../UserInterface/Widget/ControllerWidget.ui | 827 ++++++++++++------ .../UserInterface/Widget/CustomButton.cpp | 113 --- .../UserInterface/Widget/CustomButton.hpp | 67 -- .../UserInterface/Widget/MappingButton.cpp | 248 ++++++ .../UserInterface/Widget/MappingButton.hpp | 83 ++ .../Widget/RemoveMappingButton.cpp | 33 + .../Widget/RemoveMappingButton.hpp | 43 + Source/RMG-Input/main.cpp | 166 ++-- .../Resource/icons/black/svg/add-line.svg | 1 + .../icons/black/svg/delete-back-line.svg | 1 + .../Resource/icons/white/svg/add-line.svg | 1 + .../icons/white/svg/delete-back-line.svg | 1 + Source/RMG/UserInterface/UIResources.qrc | 4 + 18 files changed, 1353 insertions(+), 632 deletions(-) create mode 100644 Source/RMG-Input/UserInterface/Widget/AddMappingButton.cpp create mode 100644 Source/RMG-Input/UserInterface/Widget/AddMappingButton.hpp delete mode 100644 Source/RMG-Input/UserInterface/Widget/CustomButton.cpp delete mode 100644 Source/RMG-Input/UserInterface/Widget/CustomButton.hpp create mode 100644 Source/RMG-Input/UserInterface/Widget/MappingButton.cpp create mode 100644 Source/RMG-Input/UserInterface/Widget/MappingButton.hpp create mode 100644 Source/RMG-Input/UserInterface/Widget/RemoveMappingButton.cpp create mode 100644 Source/RMG-Input/UserInterface/Widget/RemoveMappingButton.hpp create mode 100644 Source/RMG/UserInterface/Resource/icons/black/svg/add-line.svg create mode 100644 Source/RMG/UserInterface/Resource/icons/black/svg/delete-back-line.svg create mode 100644 Source/RMG/UserInterface/Resource/icons/white/svg/add-line.svg create mode 100644 Source/RMG/UserInterface/Resource/icons/white/svg/delete-back-line.svg diff --git a/Source/RMG-Input/CMakeLists.txt b/Source/RMG-Input/CMakeLists.txt index 96de9968..cd330d24 100644 --- a/Source/RMG-Input/CMakeLists.txt +++ b/Source/RMG-Input/CMakeLists.txt @@ -17,7 +17,9 @@ set(RMG_INPUT_SOURCES UserInterface/Widget/ControllerWidget.ui UserInterface/Widget/ControllerWidget.cpp UserInterface/Widget/ControllerImageWidget.cpp - UserInterface/Widget/CustomButton.cpp + UserInterface/Widget/MappingButton.cpp + UserInterface/Widget/AddMappingButton.cpp + UserInterface/Widget/RemoveMappingButton.cpp UserInterface/EventFilter.cpp UserInterface/OptionsDialog.ui UserInterface/OptionsDialog.cpp diff --git a/Source/RMG-Input/UserInterface/Widget/AddMappingButton.cpp b/Source/RMG-Input/UserInterface/Widget/AddMappingButton.cpp new file mode 100644 index 00000000..c828f3ff --- /dev/null +++ b/Source/RMG-Input/UserInterface/Widget/AddMappingButton.cpp @@ -0,0 +1,33 @@ +/* + * Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG + * Copyright (C) 2020 Rosalie Wanders + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "AddMappingButton.hpp" +#include "ControllerWidget.hpp" +#include "MappingButton.hpp" + +using namespace UserInterface::Widget; + +AddMappingButton::AddMappingButton(QWidget* parent) : QPushButton(parent) +{ +} + +AddMappingButton::~AddMappingButton() +{ +} + +void AddMappingButton::Initialize(ControllerWidget* widget, MappingButton* button) +{ + this->controllerWidget = widget; + this->mappingButton = button; + + connect(this, &QPushButton::released, [=] + { + emit this->controllerWidget->on_AddMappingButton_Released(this->mappingButton); + }); +} diff --git a/Source/RMG-Input/UserInterface/Widget/AddMappingButton.hpp b/Source/RMG-Input/UserInterface/Widget/AddMappingButton.hpp new file mode 100644 index 00000000..2d25d4c3 --- /dev/null +++ b/Source/RMG-Input/UserInterface/Widget/AddMappingButton.hpp @@ -0,0 +1,43 @@ +/* + * Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG + * Copyright (C) 2020 Rosalie Wanders + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef ADDMAPPINGBUTTON_HPP +#define ADDMAPPINGBUTTON_HPP + +#include + +#include "common.hpp" + +namespace UserInterface +{ +namespace Widget +{ + +// we can't include ControllerWidget.hpp +// because that header includes this header, +// so forward-declare it to prevent issues +class ControllerWidget; +class MappingButton; + +class AddMappingButton : public QPushButton +{ +private: + ControllerWidget* controllerWidget = nullptr; + MappingButton* mappingButton = nullptr; + +public: + AddMappingButton(QWidget* parent); + ~AddMappingButton(); + + void Initialize(ControllerWidget* widget, MappingButton* button); +}; +} +} + +#endif // ADDMAPPINGBUTTON_HPP diff --git a/Source/RMG-Input/UserInterface/Widget/ControllerWidget.cpp b/Source/RMG-Input/UserInterface/Widget/ControllerWidget.cpp index c6357f7a..71f1747d 100644 --- a/Source/RMG-Input/UserInterface/Widget/ControllerWidget.cpp +++ b/Source/RMG-Input/UserInterface/Widget/ControllerWidget.cpp @@ -91,7 +91,7 @@ ControllerWidget::ControllerWidget(QWidget* parent, EventFilter* eventFilter) : { this->analogStickRightButton, SettingsID::Input_AnalogStickRight_InputType, SettingsID::Input_AnalogStickRight_Name, SettingsID::Input_AnalogStickRight_Data, SettingsID::Input_AnalogStickRight_ExtraData }, }); - CustomButton* buttonList[] = + MappingButton* buttonList[] = { // dpad this->dpadUpButton, @@ -133,37 +133,50 @@ ControllerWidget::~ControllerWidget() void ControllerWidget::initializeButtons() { - CustomButton* buttonList[] = + struct + { + MappingButton* mappingButton; + AddMappingButton* addMappingButton; + RemoveMappingButton* removeMappingButton; + } mappingList[] = { // dpad - this->dpadUpButton, - this->dpadDownButton, - this->dpadLeftButton, - this->dpadRightButton, + { this->dpadUpButton, this->dpadUpAddButton, this->dpadUpRemoveButton }, + { this->dpadDownButton, this->dpadDownAddButton, this->dpadDownRemoveButton }, + { this->dpadLeftButton, this->dpadLeftAddButton, this->dpadLeftRemoveButton }, + { this->dpadRightButton, this->dpadRightAddButton, this->dpadRightRemoveButton }, // analog stick - this->analogStickUpButton, - this->analogStickDownButton, - this->analogStickLeftButton, - this->analogStickRightButton, + { this->analogStickUpButton, this->analogStickUpAddButton, this->analogStickUpRemoveButton }, + { this->analogStickDownButton, this->analogStickDownAddButton, this->analogStickDownRemoveButton }, + { this->analogStickLeftButton, this->analogStickLeftAddButton, this->analogStickLeftRemoveButton }, + { this->analogStickRightButton, this->analogStickRightAddButton, this->analogStickRightRemoveButton }, // cbuttons - this->cbuttonUpButton, - this->cbuttonDownButton, - this->cbuttonLeftButton, - this->cbuttonRightButton, + { this->cbuttonUpButton, this->cbuttonUpAddButton, this->cbuttonUpRemoveButton }, + { this->cbuttonDownButton, this->cbuttonDownAddButton, this->cbuttonDownRemoveButton }, + { this->cbuttonLeftButton, this->cbuttonLeftAddButton, this->cbuttonLeftRemoveButton }, + { this->cbuttonRightButton, this->cbuttonRightAddButton, this->cbuttonRightRemoveButton }, // triggers - this->leftTriggerButton, - this->rightTriggerButton, - this->zTriggerButton, + { this->leftTriggerButton, this->leftTriggerAddButton, this->leftTriggerRemoveButton }, + { this->rightTriggerButton, this->rightTriggerAddButton, this->rightTriggerRemoveButton }, + { this->zTriggerButton, this->zTriggerAddButton, this->zTriggerRemoveButton }, // buttons - this->aButton, - this->bButton, - this->startButton, + { this->aButton, this->aAddButton, this->aRemoveButton }, + { this->bButton, this->bAddButton, this->bRemoveButton }, + { this->startButton, this->startAddButton, this->startRemoveButton }, }; - for (auto& button : buttonList) + for (auto& mapping : mappingList) { - button->Initialize(this); - button->setText(" "); + // initialize buttons + mapping.mappingButton->Initialize(this); + mapping.addMappingButton->Initialize(this, mapping.mappingButton); + mapping.removeMappingButton->Initialize(this, mapping.mappingButton); + + // clear text & set icon + mapping.addMappingButton->setText(""); + mapping.removeMappingButton->setText(""); + mapping.addMappingButton->setIcon(QIcon::fromTheme("add-line")); + mapping.removeMappingButton->setIcon(QIcon::fromTheme("delete-back-line")); } } @@ -212,7 +225,7 @@ void ControllerWidget::enableAllChildren() } } -void ControllerWidget::removeDuplicates(CustomButton* button) +void ControllerWidget::removeDuplicates(MappingButton* button) { std::string section = this->getCurrentSettingsSection().toStdString(); @@ -229,11 +242,20 @@ void ControllerWidget::removeDuplicates(CustomButton* button) continue; } - if ((buttonWidget->GetInputType() == button->GetInputType()) && - (buttonWidget->GetInputData() == button->GetInputData()) && - (buttonWidget->GetExtraInputData() == button->GetExtraInputData())) + std::vector inputType; + std::vector inputData; + std::vector extraInputData; + + inputType = button->GetInputType(); + inputData = button->GetInputData(); + extraInputData = button->GetExtraInputData(); + + for (int i = 0; i < inputType.size(); i++) { - buttonWidget->Clear(); + if (buttonWidget->HasInputData((InputType)inputType.at(i), inputData.at(i), extraInputData.at(i))) + { + buttonWidget->RemoveInputData((InputType)inputType.at(i), inputData.at(i), extraInputData.at(i)); + } } } } @@ -406,34 +428,37 @@ void ControllerWidget::on_controllerPluggedCheckBox_toggled(bool value) QWidget* widgetList[] = { // dpad - this->dpadUpButton, - this->dpadDownButton, - this->dpadLeftButton, - this->dpadRightButton, + this->groupBox, + this->dpadUpButton, this->dpadUpAddButton, this->dpadUpRemoveButton, + this->dpadDownButton, this->dpadDownAddButton, this->dpadDownRemoveButton, + this->dpadLeftButton, this->dpadLeftAddButton, this->dpadLeftRemoveButton, + this->dpadRightButton, this->dpadRightAddButton, this->dpadRightRemoveButton, // analog stick - this->analogStickUpButton, - this->analogStickDownButton, - this->analogStickLeftButton, - this->analogStickRightButton, + this->groupBox_2, + this->analogStickUpButton, this->analogStickUpAddButton, this->analogStickUpRemoveButton, + this->analogStickDownButton, this->analogStickDownAddButton, this->analogStickDownRemoveButton, + this->analogStickLeftButton, this->analogStickLeftAddButton, this->analogStickLeftRemoveButton, + this->analogStickRightButton, this->analogStickRightAddButton, this->analogStickRightRemoveButton, // cbuttons - this->cbuttonUpButton, - this->cbuttonDownButton, - this->cbuttonLeftButton, - this->cbuttonRightButton, + this->groupBox_3, + this->cbuttonUpButton, this->cbuttonUpAddButton, this->cbuttonUpRemoveButton, + this->cbuttonDownButton, this->cbuttonDownAddButton, this->cbuttonDownRemoveButton, + this->cbuttonLeftButton, this->cbuttonLeftAddButton, this->cbuttonLeftRemoveButton, + this->cbuttonRightButton, this->cbuttonRightAddButton, this->cbuttonRightRemoveButton, // triggers - this->leftTriggerButton, - this->rightTriggerButton, - this->zTriggerButton, + this->leftTriggerButton, this->leftTriggerAddButton, this->leftTriggerRemoveButton, + this->rightTriggerButton, this->rightTriggerAddButton, this->rightTriggerRemoveButton, + this->zTriggerButton, this->zTriggerAddButton, this->zTriggerRemoveButton, // buttons - this->aButton, - this->bButton, - this->startButton, + this->groupBox_6, + this->aButton, this->aAddButton, this->aRemoveButton, + this->bButton, this->bAddButton, this->bRemoveButton, + this->startButton, this->startAddButton, this->startRemoveButton, // misc UI elements this->deadZoneSlider, this->optionsButton, this->profileComboBox, this->removeProfileButton, - //this->setupButton, this->resetButton, this->inputDeviceComboBox, this->inputDeviceRefreshButton @@ -483,15 +508,6 @@ void ControllerWidget::on_removeProfileButton_clicked() this->profileComboBox->setCurrentIndex(0); } -void ControllerWidget::on_setupButton_clicked() -{ - this->currentInSetup = true; - this->currentSetupButtonWidgetIndex = 0; - - this->setupButtonWidgets.at(0)->setFocus(Qt::OtherFocusReason); - this->setupButtonWidgets.at(0)->click(); -} - void ControllerWidget::on_resetButton_clicked() { this->LoadSettings(); @@ -509,7 +525,7 @@ void ControllerWidget::on_optionsButton_clicked() } } -void ControllerWidget::on_CustomButton_released(CustomButton* button) +void ControllerWidget::on_MappingButton_Released(MappingButton* button) { if (this->currentButton != nullptr) { @@ -524,11 +540,23 @@ void ControllerWidget::on_CustomButton_released(CustomButton* button) this->disableAllChildren(); } -void ControllerWidget::on_CustomButton_TimerFinished(CustomButton* button) +void ControllerWidget::on_AddMappingButton_Released(MappingButton* button) +{ + this->addMappingToButton = true; + button->click(); +} + +void ControllerWidget::on_RemoveMappingButton_Released(MappingButton* button) +{ + button->RemoveLastInputData(); +} + +void ControllerWidget::on_MappingButton_TimerFinished(MappingButton* button) { if (this->currentButton == button) { - this->currentButton = nullptr; + this->currentButton = nullptr; + this->addMappingToButton = false; } button->RestoreState(); @@ -536,11 +564,12 @@ void ControllerWidget::on_CustomButton_TimerFinished(CustomButton* button) this->enableAllChildren(); } -void ControllerWidget::on_CustomButton_DataSet(CustomButton* button) +void ControllerWidget::on_MappingButton_DataSet(MappingButton* button) { this->enableAllChildren(); this->removeDuplicates(button); - this->currentButton = nullptr; + this->currentButton = nullptr; + this->addMappingToButton = false; } void ControllerWidget::on_MainDialog_SdlEvent(SDL_Event* event) @@ -587,12 +616,24 @@ void ControllerWidget::on_MainDialog_SdlEvent(SDL_Event* event) { if (sdlButtonPressed) { - this->currentButton->SetInputData( - inputType, - sdlButton, - 0, - sdlButtonName - ); + if (this->addMappingToButton) + { + this->currentButton->AddInputData( + inputType, + sdlButton, + 0, + sdlButtonName + ); + } + else + { + this->currentButton->SetInputData( + inputType, + sdlButton, + 0, + sdlButtonName + ); + } } break; } @@ -600,8 +641,7 @@ void ControllerWidget::on_MainDialog_SdlEvent(SDL_Event* event) // update controller button state for (auto& button : this->buttonWidgetMappings) { - if (button.buttonWidget->GetInputType() == inputType && - button.buttonWidget->GetInputData() == sdlButton) + if (button.buttonWidget->HasInputData(inputType, sdlButton)) { this->controllerImageWidget->SetButtonState(button.button, sdlButtonPressed); } @@ -610,8 +650,7 @@ void ControllerWidget::on_MainDialog_SdlEvent(SDL_Event* event) // update controller analog stick state for (auto& joystick : this->joystickWidgetMappings) { - if (joystick.buttonWidget->GetInputType() == inputType && - joystick.buttonWidget->GetInputData() == sdlButton) + if (joystick.buttonWidget->HasInputData(inputType, sdlButton)) { switch (joystick.direction) { @@ -701,12 +740,25 @@ void ControllerWidget::on_MainDialog_SdlEvent(SDL_Event* event) sdlAxisName += sdlAxisDirection > 0 ? "+" : "-"; } } - this->currentButton->SetInputData( - inputType, - sdlAxis, - sdlAxisDirection, - sdlAxisName - ); + + if (this->addMappingToButton) + { + this->currentButton->AddInputData( + inputType, + sdlAxis, + sdlAxisDirection, + sdlAxisName + ); + } + else + { + this->currentButton->SetInputData( + inputType, + sdlAxis, + sdlAxisDirection, + sdlAxisName + ); + } } break; } @@ -714,9 +766,7 @@ void ControllerWidget::on_MainDialog_SdlEvent(SDL_Event* event) // update controller button state for (auto& button : this->buttonWidgetMappings) { - if (button.buttonWidget->GetInputType() == inputType && - button.buttonWidget->GetInputData() == sdlAxis && - button.buttonWidget->GetExtraInputData() == sdlAxisDirection) + if (button.buttonWidget->HasInputData(inputType, sdlAxis, sdlAxisDirection)) { this->controllerImageWidget->SetButtonState(button.button, sdlAxisButtonPressed); } @@ -725,9 +775,7 @@ void ControllerWidget::on_MainDialog_SdlEvent(SDL_Event* event) // update controller analog stick state for (auto& joystick : this->joystickWidgetMappings) { - if (joystick.buttonWidget->GetInputType() == inputType && - joystick.buttonWidget->GetInputData() == sdlAxis && - joystick.buttonWidget->GetExtraInputData() == sdlAxisDirection) + if (joystick.buttonWidget->HasInputData(inputType, sdlAxis, sdlAxisDirection)) { const int value = -(double)((double)sdlAxisValue / SDL_AXIS_PEAK * 100); @@ -770,12 +818,24 @@ void ControllerWidget::on_MainDialog_SdlEvent(SDL_Event* event) { if (sdlButtonPressed) { - this->currentButton->SetInputData( - InputType::Keyboard, - sdlButton, - 0, - SDL_GetScancodeName(sdlButton) - ); + if (this->addMappingToButton) + { + this->currentButton->AddInputData( + InputType::Keyboard, + sdlButton, + 0, + SDL_GetScancodeName(sdlButton) + ); + } + else + { + this->currentButton->SetInputData( + InputType::Keyboard, + sdlButton, + 0, + SDL_GetScancodeName(sdlButton) + ); + } } break; } @@ -783,8 +843,7 @@ void ControllerWidget::on_MainDialog_SdlEvent(SDL_Event* event) // update controller button state for (auto& button : this->buttonWidgetMappings) { - if (button.buttonWidget->GetInputType() == InputType::Keyboard && - button.buttonWidget->GetInputData() == sdlButton) + if (button.buttonWidget->HasInputData(InputType::Keyboard, sdlButton)) { this->controllerImageWidget->SetButtonState(button.button, sdlButtonPressed); } @@ -793,8 +852,7 @@ void ControllerWidget::on_MainDialog_SdlEvent(SDL_Event* event) // update controller analog stick state for (auto& joystick : this->joystickWidgetMappings) { - if (joystick.buttonWidget->GetInputType() == InputType::Keyboard && - joystick.buttonWidget->GetInputData() == sdlButton) + if (joystick.buttonWidget->HasInputData(InputType::Keyboard, sdlButton)) { switch (joystick.direction) { @@ -916,12 +974,29 @@ void ControllerWidget::LoadSettings(QString sectionQString) for (auto& buttonSetting : this->buttonSettingMappings) { - enum InputType type = (InputType)CoreSettingsGetIntValue(buttonSetting.inputTypeSettingsId, section); - std::string name = CoreSettingsGetStringValue(buttonSetting.nameSettingsId, section); - int data = CoreSettingsGetIntValue(buttonSetting.dataSettingsId, section); - int extraData = CoreSettingsGetIntValue(buttonSetting.extraDataSettingsId, section); + buttonSetting.button->Clear(); - buttonSetting.button->SetInputData(type, data, extraData, QString::fromStdString(name)); + std::vector types = CoreSettingsGetIntListValue(buttonSetting.inputTypeSettingsId, section); + std::vector names = CoreSettingsGetStringListValue(buttonSetting.nameSettingsId, section); + std::vector data = CoreSettingsGetIntListValue(buttonSetting.dataSettingsId, section); + std::vector extraData = CoreSettingsGetIntListValue(buttonSetting.extraDataSettingsId, section); + + int count = std::min(extraData.size(), std::min(types.size(), std::min(names.size(), data.size()))); + + if (count == 0) + { // attempt to load old profile type + types.push_back(CoreSettingsGetIntValue(buttonSetting.inputTypeSettingsId, section)); + names.push_back(CoreSettingsGetStringValue(buttonSetting.nameSettingsId, section)); + data.push_back(CoreSettingsGetIntValue(buttonSetting.dataSettingsId, section)); + extraData.push_back(CoreSettingsGetIntValue(buttonSetting.extraDataSettingsId, section)); + count = 1; + } + + // add all input data + for (int i = 0; i < count; i++) + { + buttonSetting.button->AddInputData((InputType)types[i], data[i], extraData[i], QString::fromStdString(names.at(i))); + } } // force refresh some UI elements @@ -943,19 +1018,15 @@ void ControllerWidget::SaveDefaultSettings() CoreSettingsSetValue(SettingsID::Input_DeviceNum, section, -1); CoreSettingsSetValue(SettingsID::Input_Deadzone, section, 9); CoreSettingsSetValue(SettingsID::Input_Pak, section, 0); -#ifdef _WIN32 CoreSettingsSetValue(SettingsID::Input_RemoveDuplicateMappings, section, true); -#else - CoreSettingsSetValue(SettingsID::Input_RemoveDuplicateMappings, section, false); -#endif // _WIN32 CoreSettingsSetValue(SettingsID::Input_InvertAxis, section, true); for (auto& buttonSetting : this->buttonSettingMappings) { - CoreSettingsSetValue(buttonSetting.inputTypeSettingsId, section, (int)InputType::Invalid); - CoreSettingsSetValue(buttonSetting.nameSettingsId, section, std::string(" ")); - CoreSettingsSetValue(buttonSetting.dataSettingsId, section, 0); - CoreSettingsSetValue(buttonSetting.extraDataSettingsId, section, 0); + CoreSettingsSetValue(buttonSetting.inputTypeSettingsId, section, std::vector({ (int)InputType::Invalid })); + CoreSettingsSetValue(buttonSetting.nameSettingsId, section, std::vector({ std::string() })); + CoreSettingsSetValue(buttonSetting.dataSettingsId, section, std::vector({ 0 })); + CoreSettingsSetValue(buttonSetting.extraDataSettingsId, section, std::vector({ 0 })); } CoreSettingsSave(); @@ -986,8 +1057,8 @@ void ControllerWidget::SaveSettings() for (auto& buttonSetting : this->buttonSettingMappings) { - CoreSettingsSetValue(buttonSetting.inputTypeSettingsId, section, (int)buttonSetting.button->GetInputType()); - CoreSettingsSetValue(buttonSetting.nameSettingsId, section, buttonSetting.button->text().toStdString()); + CoreSettingsSetValue(buttonSetting.inputTypeSettingsId, section, buttonSetting.button->GetInputType()); + CoreSettingsSetValue(buttonSetting.nameSettingsId, section, buttonSetting.button->GetInputText()); CoreSettingsSetValue(buttonSetting.dataSettingsId, section, buttonSetting.button->GetInputData()); CoreSettingsSetValue(buttonSetting.extraDataSettingsId, section, buttonSetting.button->GetExtraInputData()); } diff --git a/Source/RMG-Input/UserInterface/Widget/ControllerWidget.hpp b/Source/RMG-Input/UserInterface/Widget/ControllerWidget.hpp index e38a93cc..cc61e156 100644 --- a/Source/RMG-Input/UserInterface/Widget/ControllerWidget.hpp +++ b/Source/RMG-Input/UserInterface/Widget/ControllerWidget.hpp @@ -10,7 +10,7 @@ #ifndef CONTROLLERWIDGET_H #define CONTROLLERWIDGET_H -#include "CustomButton.hpp" +#include "MappingButton.hpp" #include "ControllerImageWidget.hpp" #include "UserInterface/EventFilter.hpp" @@ -39,23 +39,24 @@ private: OptionsDialogSettings optionsDialogSettings; QList inputDeviceNameList; - CustomButton* currentButton = nullptr; - + MappingButton* currentButton = nullptr; + bool addMappingToButton = false; + struct buttonWidgetMapping { enum N64ControllerButton button; - CustomButton* buttonWidget; + MappingButton* buttonWidget; }; struct axisWidgetMapping { enum InputAxisDirection direction; - CustomButton* buttonWidget; + MappingButton* buttonWidget; }; struct buttonSettingMapping { - CustomButton* button; + MappingButton* button; SettingsID inputTypeSettingsId; SettingsID nameSettingsId; SettingsID dataSettingsId; @@ -65,9 +66,7 @@ private: QList buttonWidgetMappings; QList joystickWidgetMappings; QList buttonSettingMappings; - QList setupButtonWidgets; - int currentSetupButtonWidgetIndex = 0; - bool currentInSetup = false; + QList setupButtonWidgets; void initializeButtons(); @@ -77,7 +76,7 @@ private: void disableAllChildren(); void enableAllChildren(); - void removeDuplicates(CustomButton* button); + void removeDuplicates(MappingButton* button); QString getCurrentSettingsSection(); @@ -117,15 +116,18 @@ private slots: void on_controllerPluggedCheckBox_toggled(bool value); void on_removeProfileButton_clicked(); - void on_setupButton_clicked(); + void on_resetButton_clicked(); void on_optionsButton_clicked(); public slots: - void on_CustomButton_released(CustomButton* button); - void on_CustomButton_TimerFinished(CustomButton* button); - void on_CustomButton_DataSet(CustomButton* button); + void on_MappingButton_Released(MappingButton* button); + void on_MappingButton_TimerFinished(MappingButton* button); + void on_MappingButton_DataSet(MappingButton* button); + void on_AddMappingButton_Released(MappingButton* button); + void on_RemoveMappingButton_Released(MappingButton* button); + void on_MainDialog_SdlEvent(SDL_Event* event); void on_MainDialog_SdlEventPollFinished(); signals: diff --git a/Source/RMG-Input/UserInterface/Widget/ControllerWidget.ui b/Source/RMG-Input/UserInterface/Widget/ControllerWidget.ui index 7aaa0092..85cb8082 100644 --- a/Source/RMG-Input/UserInterface/Widget/ControllerWidget.ui +++ b/Source/RMG-Input/UserInterface/Widget/ControllerWidget.ui @@ -6,8 +6,8 @@ 0 0 - 811 - 554 + 1239 + 562 @@ -144,7 +144,7 @@ - + Qt::Vertical @@ -173,9 +173,9 @@ false - + - + @@ -189,23 +189,6 @@ - - - - - 0 - 0 - - - - - - - - - - - @@ -217,25 +200,14 @@ Down: - - - - - - - 0 - 0 - + + false - - + + true - - - - @@ -249,23 +221,6 @@ - - - - - 0 - 0 - - - - - - - - - - - @@ -279,18 +234,133 @@ + + + + - - - - 0 - 0 - - - - - - + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + + + - + + + + @@ -314,9 +384,9 @@ false - + - + @@ -330,17 +400,6 @@ - - - - - - - - - - - @@ -354,17 +413,6 @@ - - - - - - - - - - - @@ -378,17 +426,6 @@ - - - - - - - - - - - @@ -402,12 +439,115 @@ + + + + - - - - - + + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + @@ -459,12 +599,26 @@ - + + + + + + + + + + + + + - + + + @@ -490,12 +644,26 @@ - + + + + + + + + + + + + + - + + + @@ -531,21 +699,24 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + - - - - Qt::Horizontal - - - - 40 - 20 - - - - + + 0 + @@ -554,61 +725,89 @@ - + - - - 0 + + + + - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Z-Trigger: - - - - - - - - - - - + - - - Qt::Horizontal + + + - - - - 40 - 20 - - - + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 0 + + + + + Z-Trigger: + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -616,7 +815,7 @@ - + Qt::Vertical @@ -645,9 +844,9 @@ false - + - + @@ -661,23 +860,6 @@ - - - - - 0 - 0 - - - - - - - - - - - @@ -691,23 +873,6 @@ - - - - - 0 - 0 - - - - - - - - - - - @@ -721,23 +886,6 @@ - - - - - 0 - 0 - - - - - - - - - - - @@ -751,18 +899,133 @@ + + + + - - - - 0 - 0 - - - - - - + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + + + - + + + + @@ -780,9 +1043,9 @@ - + - + @@ -796,23 +1059,6 @@ - - - - - 0 - 0 - - - - - - - - - - - @@ -826,18 +1072,71 @@ + + + + - - - - 0 - 0 - - - - - - + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + + + - + + + + @@ -892,9 +1191,9 @@ - CustomButton + MappingButton QPushButton -
UserInterface/Widget/CustomButton.hpp
+
UserInterface/Widget/MappingButton.hpp
ControllerImageWidget @@ -902,6 +1201,16 @@
UserInterface/Widget/ControllerImageWidget.hpp
1
+ + AddMappingButton + QPushButton +
UserInterface/Widget/AddMappingButton.hpp
+
+ + RemoveMappingButton + QPushButton +
UserInterface/Widget/RemoveMappingButton.hpp
+
diff --git a/Source/RMG-Input/UserInterface/Widget/CustomButton.cpp b/Source/RMG-Input/UserInterface/Widget/CustomButton.cpp deleted file mode 100644 index 03fb0919..00000000 --- a/Source/RMG-Input/UserInterface/Widget/CustomButton.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG - * Copyright (C) 2020 Rosalie Wanders - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3. - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#include "CustomButton.hpp" -#include "ControllerWidget.hpp" - -using namespace UserInterface::Widget; - -CustomButton::CustomButton(QWidget* parent) : QPushButton(parent) -{ - this->countDownTimer = new QTimer(this); - connect(this->countDownTimer, &QTimer::timeout, this, &CustomButton::on_countDownTimer_triggered); -} - -CustomButton::~CustomButton() -{ - -} - -void CustomButton::Initialize(QWidget* widget) -{ - this->controllerWidget = (ControllerWidget*)widget; - - connect(this, &QPushButton::released, - [=] - { - emit this->controllerWidget->on_CustomButton_released(this); - }); -} - -void CustomButton::Clear() -{ - this->inputType = InputType::Invalid; - this->inputData = 0; - this->extraInputData = 0; - this->savedInputData = 0; - this->savedExtraInputData = 0; - this->setText(" "); -} - -void CustomButton::StartTimer() -{ - this->currentCountDownNum = 5; - this->on_countDownTimer_triggered(); - this->countDownTimer->start(1000); -} - -void CustomButton::StopTimer() -{ - this->countDownTimer->stop(); -} - -void CustomButton::SetInputData(enum InputType type, int value, int extraValue, QString name) -{ - this->inputType = type; - this->inputData = value; - this->extraInputData = extraValue; - this->setText(name); - this->StopTimer(); - emit this->controllerWidget->on_CustomButton_DataSet(this); -} - -enum InputType CustomButton::GetInputType() -{ - return this->inputType; -} - -int CustomButton::GetInputData() -{ - return this->inputData; -} - -int CustomButton::GetExtraInputData() -{ - return this->extraInputData; -} - -void CustomButton::SaveState() -{ - this->savedInputType = this->inputType; - this->savedInputData = this->inputData; - this->savedExtraInputData = this->extraInputData; - this->savedText = this->text(); -} - -void CustomButton::RestoreState() -{ - this->inputType = this->savedInputType; - this->inputData = this->savedInputData; - this->extraInputData = this->savedExtraInputData; - this->setText(this->savedText); -} - -void CustomButton::on_countDownTimer_triggered() -{ - this->setText(QString::number(this->currentCountDownNum)); - - if (this->currentCountDownNum == 0) - { - this->setText(""); - this->currentCountDownNum = 5; - this->countDownTimer->stop(); - emit this->controllerWidget->on_CustomButton_TimerFinished(this); - } - - this->currentCountDownNum--; -} diff --git a/Source/RMG-Input/UserInterface/Widget/CustomButton.hpp b/Source/RMG-Input/UserInterface/Widget/CustomButton.hpp deleted file mode 100644 index 9ad6cac4..00000000 --- a/Source/RMG-Input/UserInterface/Widget/CustomButton.hpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG - * Copyright (C) 2020 Rosalie Wanders - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3. - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef CUSTOMBUTTON_HPP -#define CUSTOMBUTTON_HPP - -#include -#include - -#include "common.hpp" - -namespace UserInterface -{ -namespace Widget -{ - -// we can't include ControllerWidget.hpp -// because that header includes this header, -// so forward-declare it to prevent issues -class ControllerWidget; - -class CustomButton : public QPushButton -{ -private: - QTimer* countDownTimer = nullptr; - ControllerWidget* controllerWidget = nullptr; - int currentCountDownNum = 0; - enum InputType inputType = InputType::Invalid; - int inputData = 0; - int extraInputData = 0; - - enum InputType savedInputType = InputType::Invalid; - int savedInputData = 0; - int savedExtraInputData = 0; - QString savedText; -public: - CustomButton(QWidget* parent); - ~CustomButton(); - void Initialize(QWidget* widget); - void Clear(); - - void StartTimer(); - void StopTimer(); - - - void SetInputData(enum InputType type, int value, int extraValue, QString name); - enum InputType GetInputType(); - int GetInputData(); - int GetExtraInputData(); - - void SaveState(); - void RestoreState(); - -private slots: - void on_countDownTimer_triggered(); -}; -} -} - - -#endif // CUSTOMBUTTON_HPP diff --git a/Source/RMG-Input/UserInterface/Widget/MappingButton.cpp b/Source/RMG-Input/UserInterface/Widget/MappingButton.cpp new file mode 100644 index 00000000..98d19565 --- /dev/null +++ b/Source/RMG-Input/UserInterface/Widget/MappingButton.cpp @@ -0,0 +1,248 @@ +/* + * Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG + * Copyright (C) 2020 Rosalie Wanders + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "MappingButton.hpp" +#include "ControllerWidget.hpp" + +using namespace UserInterface::Widget; + +MappingButton::MappingButton(QWidget* parent) : QPushButton(parent) +{ + this->countDownTimer = new QTimer(this); + connect(this->countDownTimer, &QTimer::timeout, this, &MappingButton::on_countDownTimer_triggered); +} + +MappingButton::~MappingButton() +{ + +} + +void MappingButton::Initialize(ControllerWidget* widget) +{ + this->controllerWidget = widget; + + connect(this, &QPushButton::released, [=] + { + emit this->controllerWidget->on_MappingButton_Released(this); + }); + + this->setText(" "); +} + +void MappingButton::Clear() +{ + this->inputData.clear(); + this->savedInputData.clear(); + this->setText(" "); +} + +void MappingButton::StartTimer() +{ + this->currentCountDownNum = 5; + this->on_countDownTimer_triggered(); + this->countDownTimer->start(1000); +} + +void MappingButton::StopTimer() +{ + this->countDownTimer->stop(); +} + +void MappingButton::SetInputData(enum InputType type, int value, int extraValue, QString name) +{ + // don't add stub + if (name.simplified().isEmpty()) + { + return; + } + + this->inputData.clear(); + this->inputData.push_back( + { + type, + value, + extraValue, + name + } + ); + + this->reloadText(); + this->StopTimer(); + + emit this->controllerWidget->on_MappingButton_DataSet(this); +} + +void MappingButton::AddInputData(enum InputType type, int value, int extraValue, QString name) +{ + // don't add stub + if (name.simplified().isEmpty()) + { + return; + } + + if (!this->HasInputData(type, value, extraValue)) + { + this->inputData.push_back( + { + type, + value, + extraValue, + name + } + ); + } + + this->reloadText(); + this->StopTimer(); + + emit this->controllerWidget->on_MappingButton_DataSet(this); +} + +void MappingButton::RemoveLastInputData(void) +{ + if (!this->inputData.empty()) + { + this->inputData.pop_back(); + } + + this->reloadText(); +} + +void MappingButton::RemoveInputData(InputType type, int value, int extraValue) +{ + auto iter = this->getInputDataIter(type, value, extraValue); + if (iter == this->inputData.end()) + { + return; + } + + this->inputData.erase(iter); + this->reloadText(); +} + +bool MappingButton::HasInputData(enum InputType type, int value, int extraValue) +{ + return this->getInputDataIter(type, value, extraValue) != this->inputData.end(); +} + +std::vector MappingButton::GetInputType() +{ + std::vector inputTypeList; + + for (const auto& data : this->inputData) + { + inputTypeList.push_back((int)data.Type); + } + + return inputTypeList; +} + +std::vector MappingButton::GetInputData() +{ + std::vector inputDataList; + + for (const auto& data : this->inputData) + { + inputDataList.push_back(data.Data); + } + + return inputDataList; +} + +std::vector MappingButton::GetExtraInputData() +{ + std::vector extraInputDataList; + + for (const auto& data : this->inputData) + { + extraInputDataList.push_back(data.ExtraData); + } + + return extraInputDataList; +} + +std::vector MappingButton::GetInputText() +{ + std::vector inputTextList; + + for (const auto& data : this->inputData) + { + inputTextList.push_back(data.Text.toStdString()); + } + + return inputTextList; +} + +void MappingButton::SaveState() +{ + this->savedInputData = this->inputData; +} + +void MappingButton::RestoreState() +{ + this->inputData = this->savedInputData; + this->reloadText(); +} + +void MappingButton::on_countDownTimer_triggered() +{ + this->setText(QString::number(this->currentCountDownNum)); + + if (this->currentCountDownNum == 0) + { + this->setText(""); + this->currentCountDownNum = 5; + this->countDownTimer->stop(); + emit this->controllerWidget->on_MappingButton_TimerFinished(this); + } + + this->currentCountDownNum--; +} + +void MappingButton::reloadText() +{ + QString text; + QFontMetrics fontMetrics(this->font()); + + int size = this->inputData.size(); + for (int i = 0; i < size; i++) + { + text += this->inputData.at(i).Text; + + // only add comma when + // not at the last item + if (i < (size - 1)) + { + text += ", "; + } + } + + QString elidedText = fontMetrics.elidedText(text, Qt::ElideRight, this->width()); + + // needed for spacing + if (elidedText.isEmpty()) + { + elidedText = " "; + } + + this->setToolTip(text); + this->setText(elidedText); +} + +std::vector::iterator MappingButton::getInputDataIter(InputType type, int value, int extraValue) +{ + auto predicate = [type, value, extraValue](const auto& entry) + { + return entry.Type == type && + (value == -1 || entry.Data == value) && + (extraValue == -1 || entry.ExtraData == extraValue); + }; + + return std::find_if(this->inputData.begin(), this->inputData.end(), predicate); +} diff --git a/Source/RMG-Input/UserInterface/Widget/MappingButton.hpp b/Source/RMG-Input/UserInterface/Widget/MappingButton.hpp new file mode 100644 index 00000000..f0f98310 --- /dev/null +++ b/Source/RMG-Input/UserInterface/Widget/MappingButton.hpp @@ -0,0 +1,83 @@ +/* + * Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG + * Copyright (C) 2020 Rosalie Wanders + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef MAPPINGBUTTON_HPP +#define MAPPINGBUTTON_HPP + +#include +#include + +#include "common.hpp" + +namespace UserInterface +{ +namespace Widget +{ + +// we can't include ControllerWidget.hpp +// because that header includes this header, +// so forward-declare it to prevent issues +class ControllerWidget; + +struct MappingButtonInputDataType +{ + InputType Type; + int Data; + int ExtraData; + QString Text; +}; + +class MappingButton : public QPushButton +{ +private: + QTimer* countDownTimer = nullptr; + ControllerWidget* controllerWidget = nullptr; + int currentCountDownNum = 0; + + std::vector inputData; + + std::vector savedInputData; + + void reloadText(); + + std::vector::iterator getInputDataIter(InputType type, int value, int extraValue); + +public: + MappingButton(QWidget* parent); + ~MappingButton(); + + void Initialize(ControllerWidget* widget); + void Clear(); + + void StartTimer(); + void StopTimer(); + + void SetInputData(InputType type, int value, int extraValue, QString name); + void AddInputData(InputType type, int value, int extraValue, QString name); + + void RemoveLastInputData(void); + void RemoveInputData(InputType type, int value, int extraValue); + + bool HasInputData(InputType type, int value = -1, int extraValue = -1); + + std::vector GetInputType(); + std::vector GetInputData(); + std::vector GetExtraInputData(); + std::vector GetInputText(); + + void SaveState(); + void RestoreState(); + +private slots: + void on_countDownTimer_triggered(); +}; +} +} + +#endif // MAPPINGBUTTON_HPP diff --git a/Source/RMG-Input/UserInterface/Widget/RemoveMappingButton.cpp b/Source/RMG-Input/UserInterface/Widget/RemoveMappingButton.cpp new file mode 100644 index 00000000..2d2e47dc --- /dev/null +++ b/Source/RMG-Input/UserInterface/Widget/RemoveMappingButton.cpp @@ -0,0 +1,33 @@ +/* + * Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG + * Copyright (C) 2020 Rosalie Wanders + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "RemoveMappingButton.hpp" +#include "ControllerWidget.hpp" +#include "MappingButton.hpp" + +using namespace UserInterface::Widget; + +RemoveMappingButton::RemoveMappingButton(QWidget* parent) : QPushButton(parent) +{ +} + +RemoveMappingButton::~RemoveMappingButton() +{ +} + +void RemoveMappingButton::Initialize(ControllerWidget* widget, MappingButton* button) +{ + this->controllerWidget = widget; + this->mappingButton = button; + + connect(this, &QPushButton::released, [=] + { + emit this->controllerWidget->on_RemoveMappingButton_Released(this->mappingButton); + }); +} diff --git a/Source/RMG-Input/UserInterface/Widget/RemoveMappingButton.hpp b/Source/RMG-Input/UserInterface/Widget/RemoveMappingButton.hpp new file mode 100644 index 00000000..4886d2c8 --- /dev/null +++ b/Source/RMG-Input/UserInterface/Widget/RemoveMappingButton.hpp @@ -0,0 +1,43 @@ +/* + * Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG + * Copyright (C) 2020 Rosalie Wanders + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef REMOVEMAPPINGBUTTON_HPP +#define REMOVEMAPPINGBUTTON_HPP + +#include + +#include "common.hpp" + +namespace UserInterface +{ +namespace Widget +{ + +// we can't include ControllerWidget.hpp +// because that header includes this header, +// so forward-declare it to prevent issues +class ControllerWidget; +class MappingButton; + +class RemoveMappingButton : public QPushButton +{ +private: + ControllerWidget* controllerWidget = nullptr; + MappingButton* mappingButton = nullptr; + +public: + RemoveMappingButton(QWidget* parent); + ~RemoveMappingButton(); + + void Initialize(ControllerWidget* widget, MappingButton* button); +}; +} +} + +#endif // REMOVEMAPPINGBUTTON_HPP diff --git a/Source/RMG-Input/main.cpp b/Source/RMG-Input/main.cpp index 37aa2a5a..768523fe 100644 --- a/Source/RMG-Input/main.cpp +++ b/Source/RMG-Input/main.cpp @@ -49,9 +49,10 @@ struct InputMapping { - InputType Type = InputType::Invalid; - int Data = 0; - int ExtraData = 0; + std::vector Type; + std::vector Data; + std::vector ExtraData; + int Count = 0; }; struct InputProfile @@ -122,9 +123,18 @@ static bool l_KeyboardState[SDL_NUM_SCANCODES]; static void load_inputmapping_settings(InputMapping* mapping, std::string section, SettingsID inputTypeSettingsId, SettingsID dataSettingsId, SettingsID extraDataSettingsId) { - mapping->Type = (InputType)CoreSettingsGetIntValue(inputTypeSettingsId, section); - mapping->Data = CoreSettingsGetIntValue(dataSettingsId, section); - mapping->ExtraData = CoreSettingsGetIntValue(extraDataSettingsId, section); + mapping->Type = CoreSettingsGetIntListValue(inputTypeSettingsId, section); + mapping->Data = CoreSettingsGetIntListValue(dataSettingsId, section); + mapping->ExtraData = CoreSettingsGetIntListValue(extraDataSettingsId, section); + mapping->Count = std::min(mapping->Type.size(), std::min(mapping->Data.size(), mapping->ExtraData.size())); + + if (mapping->Count == 0) + { // try to load old profile type + mapping->Type.push_back(CoreSettingsGetIntValue(inputTypeSettingsId, section)); + mapping->Data.push_back(CoreSettingsGetIntValue(dataSettingsId, section)); + mapping->ExtraData.push_back(CoreSettingsGetIntValue(extraDataSettingsId, section)); + mapping->Count = 1; + } } static void load_settings(void) @@ -286,81 +296,97 @@ static void close_controllers(void) static int get_button_state(InputProfile* profile, InputMapping* inputMapping) { - switch (inputMapping->Type) + int state = 0; + + for (int i = 0; i < inputMapping->Count; i++) { - case InputType::GamepadButton: + const int data = inputMapping->Data.at(i); + const int extraData = inputMapping->ExtraData.at(i); + + switch ((InputType)inputMapping->Type[i]) { - return SDL_GameControllerGetButton(profile->InputDevice.GetGameControllerHandle(), (SDL_GameControllerButton)inputMapping->Data); - }; - case InputType::GamepadAxis: - { - int axis_value = SDL_GameControllerGetAxis(profile->InputDevice.GetGameControllerHandle(), (SDL_GameControllerAxis)inputMapping->Data); - return (abs(axis_value) >= (SDL_AXIS_PEAK / 2) && (inputMapping->ExtraData ? axis_value > 0 : axis_value < 0)) ? 1 : 0; - }; - case InputType::JoystickButton: - { - return SDL_JoystickGetButton(profile->InputDevice.GetJoystickHandle(), inputMapping->Data); - }; - case InputType::JoystickAxis: - { - int axis_value = SDL_JoystickGetAxis(profile->InputDevice.GetJoystickHandle(), inputMapping->Data); - return (abs(axis_value) >= (SDL_AXIS_PEAK / 2) && (inputMapping->ExtraData ? axis_value > 0 : axis_value < 0)) ? 1 : 0; + case InputType::GamepadButton: + { + state |= SDL_GameControllerGetButton(profile->InputDevice.GetGameControllerHandle(), (SDL_GameControllerButton)data); + } break; + case InputType::GamepadAxis: + { + int axis_value = SDL_GameControllerGetAxis(profile->InputDevice.GetGameControllerHandle(), (SDL_GameControllerAxis)data); + state |= (abs(axis_value) >= (SDL_AXIS_PEAK / 2) && (extraData ? axis_value > 0 : axis_value < 0)) ? 1 : 0; + } break; + case InputType::JoystickButton: + { + state |= SDL_JoystickGetButton(profile->InputDevice.GetJoystickHandle(), data); + } break; + case InputType::JoystickAxis: + { + int axis_value = SDL_JoystickGetAxis(profile->InputDevice.GetJoystickHandle(), data); + state |= (abs(axis_value) >= (SDL_AXIS_PEAK / 2) && (extraData ? axis_value > 0 : axis_value < 0)) ? 1 : 0; + } break; + case InputType::Keyboard: + { + state |= l_KeyboardState[data] ? 1 : 0; + } break; + default: + break; } - case InputType::Keyboard: - { - return l_KeyboardState[inputMapping->Data] ? 1 : 0; - }; - default: - break; } - return 0; + return state; } // returns axis input scaled to the range [-1, 1] static double get_axis_state(InputProfile* profile, InputMapping* inputMapping, int direction, double value) { - switch (inputMapping->Type) - { - case InputType::GamepadButton: - { - int buttonState = SDL_GameControllerGetButton(profile->InputDevice.GetGameControllerHandle(), (SDL_GameControllerButton)inputMapping->Data); - return buttonState ? direction : value; - } break; - case InputType::GamepadAxis: - { - double axis_value = SDL_GameControllerGetAxis(profile->InputDevice.GetGameControllerHandle(), (SDL_GameControllerAxis)inputMapping->Data); - if (inputMapping->ExtraData ? axis_value > 0 : axis_value < 0) - { - axis_value = (axis_value / SDL_AXIS_PEAK); - axis_value = abs(axis_value) * direction; - return axis_value; - } - } break; - case InputType::JoystickButton: - { - int buttonState = SDL_JoystickGetButton(profile->InputDevice.GetJoystickHandle(), inputMapping->Data); - return buttonState ? direction : value; - } break; - case InputType::JoystickAxis: - { - double axis_value = SDL_JoystickGetAxis(profile->InputDevice.GetJoystickHandle(), inputMapping->Data); - if (inputMapping->ExtraData ? axis_value > 0 : axis_value < 0) - { - axis_value = (axis_value / SDL_AXIS_PEAK); - axis_value = abs(axis_value) * direction; - return axis_value; - } - } break; - case InputType::Keyboard: - { - return l_KeyboardState[inputMapping->Data] ? direction : value; - } break; - default: - break; - } + int state = 0; - return value; + for (int i = 0; i < inputMapping->Count; i++) + { + const int data = inputMapping->Data.at(i); + const int extraData = inputMapping->ExtraData.at(i); + + switch ((InputType)inputMapping->Type[i]) + { + case InputType::GamepadButton: + { + int buttonState = SDL_GameControllerGetButton(profile->InputDevice.GetGameControllerHandle(), (SDL_GameControllerButton)data); + state |= buttonState; + } break; + case InputType::GamepadAxis: + { + double axis_value = SDL_GameControllerGetAxis(profile->InputDevice.GetGameControllerHandle(), (SDL_GameControllerAxis)data); + if (extraData ? axis_value > 0 : axis_value < 0) + { + axis_value = (axis_value / SDL_AXIS_PEAK); + axis_value = abs(axis_value) * direction; + return axis_value; + } + } break; + case InputType::JoystickButton: + { + int buttonState = SDL_JoystickGetButton(profile->InputDevice.GetJoystickHandle(), data); + state |= buttonState; + } break; + case InputType::JoystickAxis: + { + double axis_value = SDL_JoystickGetAxis(profile->InputDevice.GetJoystickHandle(), data); + if (extraData ? axis_value > 0 : axis_value < 0) + { + axis_value = (axis_value / SDL_AXIS_PEAK); + axis_value = abs(axis_value) * direction; + return axis_value; + } + } break; + case InputType::Keyboard: + { + state |= l_KeyboardState[data]; + } break; + default: + break; + } + } + + return state ? direction : value; } static double simulate_deadzone(double n64InputAxis, double maxAxis, int deadzone, double axisRange) diff --git a/Source/RMG/UserInterface/Resource/icons/black/svg/add-line.svg b/Source/RMG/UserInterface/Resource/icons/black/svg/add-line.svg new file mode 100644 index 00000000..3069852f --- /dev/null +++ b/Source/RMG/UserInterface/Resource/icons/black/svg/add-line.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Source/RMG/UserInterface/Resource/icons/black/svg/delete-back-line.svg b/Source/RMG/UserInterface/Resource/icons/black/svg/delete-back-line.svg new file mode 100644 index 00000000..b8009500 --- /dev/null +++ b/Source/RMG/UserInterface/Resource/icons/black/svg/delete-back-line.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Source/RMG/UserInterface/Resource/icons/white/svg/add-line.svg b/Source/RMG/UserInterface/Resource/icons/white/svg/add-line.svg new file mode 100644 index 00000000..24ce0d25 --- /dev/null +++ b/Source/RMG/UserInterface/Resource/icons/white/svg/add-line.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Source/RMG/UserInterface/Resource/icons/white/svg/delete-back-line.svg b/Source/RMG/UserInterface/Resource/icons/white/svg/delete-back-line.svg new file mode 100644 index 00000000..3d32244d --- /dev/null +++ b/Source/RMG/UserInterface/Resource/icons/white/svg/delete-back-line.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Source/RMG/UserInterface/UIResources.qrc b/Source/RMG/UserInterface/UIResources.qrc index 2201980c..eb69a794 100644 --- a/Source/RMG/UserInterface/UIResources.qrc +++ b/Source/RMG/UserInterface/UIResources.qrc @@ -4,9 +4,11 @@ Resource/CoverFallback.png Resource/icons/black/index.theme + Resource/icons/black/svg/add-line.svg Resource/icons/black/svg/brush-line.svg Resource/icons/black/svg/checkbox-blank-circle-line.svg Resource/icons/black/svg/code-box-line.svg + Resource/icons/black/svg/delete-back-line.svg Resource/icons/black/svg/delete-bin-line.svg Resource/icons/black/svg/door-open-line.svg Resource/icons/black/svg/file-line.svg @@ -31,9 +33,11 @@ Resource/icons/black/svg/volume-up-line.svg Resource/icons/white/index.theme + Resource/icons/white/svg/add-line.svg Resource/icons/white/svg/brush-line.svg Resource/icons/white/svg/checkbox-blank-circle-line.svg Resource/icons/white/svg/code-box-line.svg + Resource/icons/white/svg/delete-back-line.svg Resource/icons/white/svg/delete-bin-line.svg Resource/icons/white/svg/door-open-line.svg Resource/icons/white/svg/file-line.svg