Allow combination inputs

This commit is contained in:
rainmakerv3 2025-06-23 06:51:15 +08:00 committed by rainmakerv3
parent 71bca8be8b
commit 5430ca00fe
3 changed files with 232 additions and 168 deletions

View File

@ -109,7 +109,7 @@ ControlSettings::ControlSettings(std::shared_ptr<GameInfoClass> game_info_get, Q
UpdateLightbarColor(); UpdateLightbarColor();
}); });
connect(this, &ControlSettings::gamepadInputEvent, this, connect(this, &ControlSettings::PushGamepadEvent, this,
[this]() { CheckMapping(MappingButton); }); [this]() { CheckMapping(MappingButton); });
connect(this, &ControlSettings::AxisChanged, this, connect(this, &ControlSettings::AxisChanged, this,
[this]() { ConnectAxisInputs(MappingButton); }); [this]() { ConnectAxisInputs(MappingButton); });
@ -171,9 +171,17 @@ void ControlSettings::SaveControllerConfig(bool CloseOnSave) {
output_string = line.substr(0, equal_pos - 1); output_string = line.substr(0, equal_pos - 1);
input_string = line.substr(equal_pos + 2); input_string = line.substr(equal_pos + 2);
if (std::find(ControllerInputs.begin(), ControllerInputs.end(), input_string) != bool controllerInputdetected = false;
ControllerInputs.end() || for (std::string input : ControllerInputs) {
output_string == "analog_deadzone" || output_string == "override_controller_color") { // Needed to avoid detecting backspace while detecting back
if (input_string.contains(input) && !input_string.contains("backspace")) {
controllerInputdetected = true;
break;
}
}
if (controllerInputdetected || output_string == "analog_deadzone" ||
output_string == "override_controller_color") {
line.erase(); line.erase();
continue; continue;
} }
@ -356,7 +364,6 @@ void ControlSettings::AddBoxItems() {
} }
void ControlSettings::SetUIValuestoMappings() { void ControlSettings::SetUIValuestoMappings() {
std::string config_id; std::string config_id;
config_id = (ui->ProfileComboBox->currentText() == "Common Config") config_id = (ui->ProfileComboBox->currentText() == "Common Config")
? "default" ? "default"
@ -391,9 +398,16 @@ void ControlSettings::SetUIValuestoMappings() {
std::string output_string = line.substr(0, equal_pos); std::string output_string = line.substr(0, equal_pos);
std::string input_string = line.substr(equal_pos + 1); std::string input_string = line.substr(equal_pos + 1);
if (std::find(ControllerInputs.begin(), ControllerInputs.end(), input_string) != bool controllerInputdetected = false;
ControllerInputs.end() || for (std::string input : ControllerInputs) {
output_string == "analog_deadzone" || output_string == "override_controller_color") { // Needed to avoid detecting backspace while detecting back
if (input_string.contains(input) && !input_string.contains("backspace")) {
controllerInputdetected = true;
break;
}
}
if (controllerInputdetected) {
if (output_string == "cross") { if (output_string == "cross") {
ui->CrossButton->setText(QString::fromStdString(input_string)); ui->CrossButton->setText(QString::fromStdString(input_string));
CrossExists = true; CrossExists = true;
@ -464,7 +478,10 @@ void ControlSettings::SetUIValuestoMappings() {
ui->RStickUpButton->setText(QString::fromStdString(input_string)); ui->RStickUpButton->setText(QString::fromStdString(input_string));
ui->RStickDownButton->setText(QString::fromStdString(input_string)); ui->RStickDownButton->setText(QString::fromStdString(input_string));
RStickYExists = true; RStickYExists = true;
} else if (input_string.contains("leftjoystick")) { }
}
if (input_string.contains("leftjoystick")) {
std::size_t comma_pos = line.find(','); std::size_t comma_pos = line.find(',');
if (comma_pos != std::string::npos) { if (comma_pos != std::string::npos) {
int deadzonevalue = std::stoi(line.substr(comma_pos + 1)); int deadzonevalue = std::stoi(line.substr(comma_pos + 1));
@ -474,7 +491,9 @@ void ControlSettings::SetUIValuestoMappings() {
ui->LeftDeadzoneSlider->setValue(2); ui->LeftDeadzoneSlider->setValue(2);
ui->LeftDeadzoneValue->setText("2"); ui->LeftDeadzoneValue->setText("2");
} }
} else if (input_string.contains("rightjoystick")) { }
if (input_string.contains("rightjoystick")) {
std::size_t comma_pos = line.find(','); std::size_t comma_pos = line.find(',');
if (comma_pos != std::string::npos) { if (comma_pos != std::string::npos) {
int deadzonevalue = std::stoi(line.substr(comma_pos + 1)); int deadzonevalue = std::stoi(line.substr(comma_pos + 1));
@ -484,7 +503,9 @@ void ControlSettings::SetUIValuestoMappings() {
ui->RightDeadzoneSlider->setValue(2); ui->RightDeadzoneSlider->setValue(2);
ui->RightDeadzoneValue->setText("2"); ui->RightDeadzoneValue->setText("2");
} }
} else if (output_string == "override_controller_color") { }
if (output_string == "override_controller_color") {
std::size_t comma_pos = line.find(','); std::size_t comma_pos = line.find(',');
if (comma_pos != std::string::npos) { if (comma_pos != std::string::npos) {
std::string overridestring = line.substr(equal_pos + 1, comma_pos); std::string overridestring = line.substr(equal_pos + 1, comma_pos);
@ -506,22 +527,19 @@ void ControlSettings::SetUIValuestoMappings() {
if (comma_pos3 != std::string::npos) { if (comma_pos3 != std::string::npos) {
std::string Gstring = GBstring.substr(0, comma_pos3); std::string Gstring = GBstring.substr(0, comma_pos3);
ui->GSlider->setValue(std::stoi(Gstring)); ui->GSlider->setValue(std::stoi(Gstring));
QString GreenValue = QString GreenValue = QString("%1").arg(std::stoi(Gstring), 3, 10, QChar('0'));
QString("%1").arg(std::stoi(Gstring), 3, 10, QChar('0'));
QString GValue = tr("G:") + " " + GreenValue; QString GValue = tr("G:") + " " + GreenValue;
ui->GLabel->setText(GValue); ui->GLabel->setText(GValue);
std::string Bstring = GBstring.substr(comma_pos3 + 1); std::string Bstring = GBstring.substr(comma_pos3 + 1);
ui->BSlider->setValue(std::stoi(Bstring)); ui->BSlider->setValue(std::stoi(Bstring));
QString BlueValue = QString BlueValue = QString("%1").arg(std::stoi(Bstring), 3, 10, QChar('0'));
QString("%1").arg(std::stoi(Bstring), 3, 10, QChar('0'));
QString BValue = tr("B:") + " " + BlueValue; QString BValue = tr("B:") + " " + BlueValue;
ui->BLabel->setText(BValue); ui->BLabel->setText(BValue);
} }
} }
} }
} }
}
file.close(); file.close();
// If an entry does not exist in the config file, we assume the user wants it unmapped // If an entry does not exist in the config file, we assume the user wants it unmapped
@ -679,6 +697,7 @@ void ControlSettings::StartTimer(QPushButton*& button, bool isButton) {
MappingTimer = 3; MappingTimer = 3;
isButton ? EnableButtonMapping = true : EnableAxisMapping = true; isButton ? EnableButtonMapping = true : EnableAxisMapping = true;
MappingCompleted = false; MappingCompleted = false;
triggerWasPressed = false;
mapping = button->text(); mapping = button->text();
DisableMappingButtons(); DisableMappingButtons();
@ -698,6 +717,19 @@ void ControlSettings::CheckMapping(QPushButton*& button) {
? button->setText(tr("Press a button") + " [" + QString::number(MappingTimer) + "]") ? button->setText(tr("Press a button") + " [" + QString::number(MappingTimer) + "]")
: button->setText(tr("Move analog stick") + " [" + QString::number(MappingTimer) + "]"); : button->setText(tr("Move analog stick") + " [" + QString::number(MappingTimer) + "]");
if (pressedButtons.size() > 0) {
QStringList keyStrings;
for (const QString& buttonAction : pressedButtons) {
keyStrings << buttonAction;
}
QString combo = keyStrings.join(",");
SetMapping(combo);
MappingButton->setText(combo);
pressedButtons.clear();
}
if (MappingCompleted || MappingTimer <= 0) { if (MappingCompleted || MappingTimer <= 0) {
button->setText(mapping); button->setText(mapping);
EnableButtonMapping = false; EnableButtonMapping = false;
@ -710,11 +742,13 @@ void ControlSettings::CheckMapping(QPushButton*& button) {
void ControlSettings::SetMapping(QString input) { void ControlSettings::SetMapping(QString input) {
mapping = input; mapping = input;
MappingCompleted = true; MappingCompleted = true;
emit gamepadInputEvent(); if (EnableAxisMapping) {
if (EnableAxisMapping)
emit AxisChanged(); emit AxisChanged();
emit PushGamepadEvent();
}
} }
// use QT events instead of SDL to override default event closing the window with escape
bool ControlSettings::eventFilter(QObject* obj, QEvent* event) { bool ControlSettings::eventFilter(QObject* obj, QEvent* event) {
if (event->type() == QEvent::KeyPress && EnableButtonMapping) { if (event->type() == QEvent::KeyPress && EnableButtonMapping) {
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event); QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
@ -734,7 +768,6 @@ void ControlSettings::pollSDLEvents() {
return; return;
} }
while (SDL_WaitEvent(&event)) {
if (event.type == SDL_EVENT_QUIT) { if (event.type == SDL_EVENT_QUIT) {
isRunning = false; isRunning = false;
SDL_QuitSubSystem(SDL_INIT_GAMEPAD); SDL_QuitSubSystem(SDL_INIT_GAMEPAD);
@ -748,85 +781,99 @@ void ControlSettings::pollSDLEvents() {
if (EnableButtonMapping) { if (EnableButtonMapping) {
if (event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN) { if (event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN) {
switch (event.gbutton.button) { switch (event.gbutton.button) {
case SDL_GAMEPAD_BUTTON_SOUTH: case SDL_GAMEPAD_BUTTON_SOUTH:
SetMapping("cross"); pressedButtons.insert("cross");
break; break;
case SDL_GAMEPAD_BUTTON_EAST: case SDL_GAMEPAD_BUTTON_EAST:
SetMapping("circle"); pressedButtons.insert("circle");
break; break;
case SDL_GAMEPAD_BUTTON_NORTH: case SDL_GAMEPAD_BUTTON_NORTH:
SetMapping("triangle"); pressedButtons.insert("triangle");
break; break;
case SDL_GAMEPAD_BUTTON_WEST: case SDL_GAMEPAD_BUTTON_WEST:
SetMapping("square"); pressedButtons.insert("square");
break; break;
case SDL_GAMEPAD_BUTTON_LEFT_SHOULDER: case SDL_GAMEPAD_BUTTON_LEFT_SHOULDER:
SetMapping("l1"); pressedButtons.insert("l1");
break; break;
case SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER: case SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER:
SetMapping("r1"); pressedButtons.insert("r1");
break; break;
case SDL_GAMEPAD_BUTTON_LEFT_STICK: case SDL_GAMEPAD_BUTTON_LEFT_STICK:
SetMapping("l3"); pressedButtons.insert("l3");
break; break;
case SDL_GAMEPAD_BUTTON_RIGHT_STICK: case SDL_GAMEPAD_BUTTON_RIGHT_STICK:
SetMapping("r3"); pressedButtons.insert("r3");
break; break;
case SDL_GAMEPAD_BUTTON_DPAD_UP: case SDL_GAMEPAD_BUTTON_DPAD_UP:
SetMapping("pad_up"); pressedButtons.insert("pad_up");
break; break;
case SDL_GAMEPAD_BUTTON_DPAD_DOWN: case SDL_GAMEPAD_BUTTON_DPAD_DOWN:
SetMapping("pad_down"); pressedButtons.insert("pad_down");
break; break;
case SDL_GAMEPAD_BUTTON_DPAD_LEFT: case SDL_GAMEPAD_BUTTON_DPAD_LEFT:
SetMapping("pad_left"); pressedButtons.insert("pad_left");
break; break;
case SDL_GAMEPAD_BUTTON_DPAD_RIGHT: case SDL_GAMEPAD_BUTTON_DPAD_RIGHT:
SetMapping("pad_right"); pressedButtons.insert("pad_right");
break; break;
case SDL_GAMEPAD_BUTTON_BACK: case SDL_GAMEPAD_BUTTON_BACK:
SetMapping("back"); pressedButtons.insert("back");
break; break;
case SDL_GAMEPAD_BUTTON_LEFT_PADDLE1: case SDL_GAMEPAD_BUTTON_LEFT_PADDLE1:
SetMapping("lpaddle_high"); pressedButtons.insert("lpaddle_high");
break; break;
case SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1: case SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1:
SetMapping("rpaddle_high"); pressedButtons.insert("rpaddle_high");
break; break;
case SDL_GAMEPAD_BUTTON_LEFT_PADDLE2: case SDL_GAMEPAD_BUTTON_LEFT_PADDLE2:
SetMapping("lpaddle_low"); pressedButtons.insert("lpaddle_low");
break; break;
case SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2: case SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2:
SetMapping("rpaddle_low"); pressedButtons.insert("rpaddle_low");
break; break;
case SDL_GAMEPAD_BUTTON_START: case SDL_GAMEPAD_BUTTON_START:
SetMapping("options"); pressedButtons.insert("options");
break; break;
default: default:
break; break;
} }
} }
if (event.type == SDL_EVENT_GAMEPAD_BUTTON_UP) {
emit PushGamepadEvent();
}
if (event.type == SDL_EVENT_GAMEPAD_AXIS_MOTION) { if (event.type == SDL_EVENT_GAMEPAD_AXIS_MOTION) {
// SDL trigger axis values range from 0-32000, set mapping on half movement // SDL trigger axis values range from 0 to 32000, set mapping on half movement
if (event.gaxis.value > 16000) { // Set zone for trigger release signal arbitrarily at 5000
switch (event.gaxis.axis) { switch (event.gaxis.axis) {
case SDL_GAMEPAD_AXIS_LEFT_TRIGGER: case SDL_GAMEPAD_AXIS_LEFT_TRIGGER:
SetMapping("l2"); if (event.gaxis.value > 16000) {
pressedButtons.insert("l2");
triggerWasPressed = true;
} else if (event.gaxis.value < 5000) {
if (triggerWasPressed)
emit PushGamepadEvent();
}
break; break;
case SDL_GAMEPAD_AXIS_RIGHT_TRIGGER: case SDL_GAMEPAD_AXIS_RIGHT_TRIGGER:
SetMapping("r2"); if (event.gaxis.value > 16000) {
pressedButtons.insert("r2");
triggerWasPressed = true;
} else if (event.gaxis.value < 5000) {
if (triggerWasPressed)
emit PushGamepadEvent();
}
break; break;
default: default:
break; break;
} }
} }
}
} else if (EnableAxisMapping) { } else if (EnableAxisMapping) {
if (event.type == SDL_EVENT_GAMEPAD_AXIS_MOTION) { if (event.type == SDL_EVENT_GAMEPAD_AXIS_MOTION) {
// SDL stick axis values range from -32000-32000, set mapping on half movement // SDL stick axis values range from -32000 to 32000, set mapping on half movement
if (event.gaxis.value > 16000 || event.gaxis.value < -16000) { if (event.gaxis.value > 16000 || event.gaxis.value < -16000) {
switch (event.gaxis.axis) { switch (event.gaxis.axis) {
case SDL_GAMEPAD_AXIS_LEFTX: case SDL_GAMEPAD_AXIS_LEFTX:
@ -849,6 +896,5 @@ void ControlSettings::pollSDLEvents() {
} }
} }
} }
}
ControlSettings::~ControlSettings() {} ControlSettings::~ControlSettings() {}

View File

@ -19,7 +19,7 @@ public:
~ControlSettings(); ~ControlSettings();
signals: signals:
void gamepadInputEvent(); void PushGamepadEvent();
void AxisChanged(); void AxisChanged();
private Q_SLOTS: private Q_SLOTS:
@ -46,8 +46,10 @@ private:
QList<QPushButton*> ButtonsList; QList<QPushButton*> ButtonsList;
QList<QPushButton*> AxisList; QList<QPushButton*> AxisList;
QSet<QString> pressedButtons;
bool isRunning = true; bool isRunning = true;
bool triggerWasPressed = false;
bool EnableButtonMapping = false; bool EnableButtonMapping = false;
bool EnableAxisMapping = false; bool EnableAxisMapping = false;
bool MappingCompleted = false; bool MappingCompleted = false;

View File

@ -269,9 +269,17 @@ void KBMSettings::SaveKBMConfig(bool close_on_save) {
output_string = line.substr(0, equal_pos - 1); output_string = line.substr(0, equal_pos - 1);
input_string = line.substr(equal_pos + 2); input_string = line.substr(equal_pos + 2);
if (std::find(ControllerInputs.begin(), ControllerInputs.end(), input_string) != bool controllerInputdetected = false;
ControllerInputs.end() || for (std::string input : ControllerInputs) {
output_string == "analog_deadzone" || output_string == "override_controller_color") { // Needed to avoid detecting backspace while detecting back
if (input_string.contains(input) && !input_string.contains("backspace")) {
controllerInputdetected = true;
break;
}
}
if (controllerInputdetected || output_string == "analog_deadzone" ||
output_string == "override_controller_color") {
lines.push_back(line); lines.push_back(line);
} }
} }
@ -388,8 +396,16 @@ void KBMSettings::SetUIValuestoMappings(std::string config_id) {
std::string output_string = line.substr(0, equal_pos - 1); std::string output_string = line.substr(0, equal_pos - 1);
std::string input_string = line.substr(equal_pos + 2); std::string input_string = line.substr(equal_pos + 2);
if (std::find(ControllerInputs.begin(), ControllerInputs.end(), input_string) == bool controllerInputdetected = false;
ControllerInputs.end()) { for (std::string input : ControllerInputs) {
// Needed to avoid detecting backspace while detecting back
if (input_string.contains(input) && !input_string.contains("backspace")) {
controllerInputdetected = true;
break;
}
}
if (!controllerInputdetected) {
if (output_string == "cross") { if (output_string == "cross") {
ui->CrossButton->setText(QString::fromStdString(input_string)); ui->CrossButton->setText(QString::fromStdString(input_string));
} else if (output_string == "circle") { } else if (output_string == "circle") {