mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-12-10 05:38:49 +00:00
Hotkey config changes (#3391)
* This works, but it's missing some hotkeys and the GUI isn't hooked up to anything now * More hotkeys * Remove debug log * clang * accidentally used the wrong value here * gui changes for new backend (#10) * gui changes for new backend * fix lmeta * don't erase non-hotkey lines * do not erase hotkey configs in kbm or controller guis * Fix repeated inputs * Documentation --------- Co-authored-by: rainmakerv2 <30595646+rainmakerv3@users.noreply.github.com>
This commit is contained in:
@@ -9,7 +9,6 @@
|
||||
#include "common/path_util.h"
|
||||
#include "control_settings.h"
|
||||
#include "input/input_handler.h"
|
||||
#include "sdl_window.h"
|
||||
#include "ui_control_settings.h"
|
||||
|
||||
ControlSettings::ControlSettings(std::shared_ptr<GameInfoClass> game_info_get, bool isGameRunning,
|
||||
@@ -181,7 +180,7 @@ void ControlSettings::SaveControllerConfig(bool CloseOnSave) {
|
||||
config_id = (ui->ProfileComboBox->currentText() == tr("Common Config"))
|
||||
? "default"
|
||||
: ui->ProfileComboBox->currentText().toStdString();
|
||||
const auto config_file = Config::GetFoolproofKbmConfigFile(config_id);
|
||||
const auto config_file = Config::GetFoolproofInputConfigFile(config_id);
|
||||
|
||||
int lineCount = 0;
|
||||
std::string line;
|
||||
@@ -208,6 +207,11 @@ void ControlSettings::SaveControllerConfig(bool CloseOnSave) {
|
||||
output_string = line.substr(0, equal_pos - 1);
|
||||
input_string = line.substr(equal_pos + 2);
|
||||
|
||||
if (output_string.contains("hotkey")) {
|
||||
lines.push_back(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool controllerInputdetected = false;
|
||||
for (std::string input : ControllerInputs) {
|
||||
// Needed to avoid detecting backspace while detecting back
|
||||
@@ -411,7 +415,7 @@ void ControlSettings::SetUIValuestoMappings() {
|
||||
? "default"
|
||||
: ui->ProfileComboBox->currentText().toStdString();
|
||||
|
||||
const auto config_file = Config::GetFoolproofKbmConfigFile(config_id);
|
||||
const auto config_file = Config::GetFoolproofInputConfigFile(config_id);
|
||||
std::ifstream file(config_file);
|
||||
|
||||
bool CrossExists = false, CircleExists = false, SquareExists = false, TriangleExists = false,
|
||||
|
||||
@@ -3,21 +3,23 @@
|
||||
|
||||
#include <fstream>
|
||||
#include <QKeyEvent>
|
||||
#include <QtConcurrent>
|
||||
#include <QMessageBox>
|
||||
#include <QtConcurrent/qtconcurrentrun.h>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include "common/config.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/path_util.h"
|
||||
#include "hotkeys.h"
|
||||
#include "input/controller.h"
|
||||
#include "input/input_handler.h"
|
||||
#include "sdl_event_wrapper.h"
|
||||
#include "ui_hotkeys.h"
|
||||
|
||||
hotkeys::hotkeys(bool isGameRunning, QWidget* parent)
|
||||
: QDialog(parent), GameRunning(isGameRunning), ui(new Ui::hotkeys) {
|
||||
Hotkeys::Hotkeys(bool isGameRunning, QWidget* parent)
|
||||
: QDialog(parent), GameRunning(isGameRunning), ui(new Ui::Hotkeys) {
|
||||
|
||||
ui->setupUi(this);
|
||||
installEventFilter(this);
|
||||
|
||||
if (!GameRunning) {
|
||||
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
|
||||
@@ -28,46 +30,59 @@ hotkeys::hotkeys(bool isGameRunning, QWidget* parent)
|
||||
|
||||
LoadHotkeys();
|
||||
CheckGamePad();
|
||||
installEventFilter(this);
|
||||
|
||||
ButtonsList = {
|
||||
ui->fpsButtonPad,
|
||||
ui->quitButtonPad,
|
||||
ui->fullscreenButtonPad,
|
||||
ui->pauseButtonPad,
|
||||
};
|
||||
PadButtonsList = {ui->fpsButtonPad, ui->quitButtonPad, ui->fullscreenButtonPad,
|
||||
ui->pauseButtonPad, ui->reloadButtonPad};
|
||||
|
||||
ui->buttonBox->button(QDialogButtonBox::Save)->setText(tr("Save"));
|
||||
ui->buttonBox->button(QDialogButtonBox::Apply)->setText(tr("Apply"));
|
||||
ui->buttonBox->button(QDialogButtonBox::Cancel)->setText(tr("Cancel"));
|
||||
KBButtonsList = {ui->fpsButtonKB, ui->quitButtonKB, ui->fullscreenButtonKB,
|
||||
ui->pauseButtonKB, ui->reloadButtonKB, ui->renderdocButton,
|
||||
ui->mouseJoystickButton, ui->mouseGyroButton};
|
||||
|
||||
connect(ui->buttonBox, &QDialogButtonBox::clicked, this, [this](QAbstractButton* button) {
|
||||
if (button == ui->buttonBox->button(QDialogButtonBox::Save)) {
|
||||
SaveHotkeys(true);
|
||||
} else if (button == ui->buttonBox->button(QDialogButtonBox::Apply)) {
|
||||
SaveHotkeys(false);
|
||||
} else if (button == ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)) {
|
||||
SetDefault();
|
||||
} else if (button == ui->buttonBox->button(QDialogButtonBox::Cancel)) {
|
||||
QWidget::close();
|
||||
}
|
||||
});
|
||||
|
||||
for (auto& button : ButtonsList) {
|
||||
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QWidget::close);
|
||||
|
||||
ui->buttonBox->button(QDialogButtonBox::Save)->setText(tr("Save"));
|
||||
ui->buttonBox->button(QDialogButtonBox::Apply)->setText(tr("Apply"));
|
||||
ui->buttonBox->button(QDialogButtonBox::Cancel)->setText(tr("Cancel"));
|
||||
ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)->setText(tr("Restore Defaults"));
|
||||
|
||||
for (auto& button : PadButtonsList) {
|
||||
connect(button, &QPushButton::clicked, this,
|
||||
[this, &button]() { StartTimer(button, true); });
|
||||
}
|
||||
|
||||
connect(this, &hotkeys::PushGamepadEvent, this, [this]() { CheckMapping(MappingButton); });
|
||||
for (auto& button : KBButtonsList) {
|
||||
connect(button, &QPushButton::clicked, this,
|
||||
[this, &button]() { StartTimer(button, false); });
|
||||
}
|
||||
|
||||
SdlEventWrapper::Wrapper::wrapperActive = true;
|
||||
QObject::connect(SdlEventWrapper::Wrapper::GetInstance(), &SdlEventWrapper::Wrapper::SDLEvent,
|
||||
this, &hotkeys::processSDLEvents);
|
||||
this, &Hotkeys::processSDLEvents);
|
||||
|
||||
if (!GameRunning) {
|
||||
Polling = QtConcurrent::run(&hotkeys::pollSDLEvents, this);
|
||||
Polling = QtConcurrent::run(&Hotkeys::pollSDLEvents, this);
|
||||
}
|
||||
}
|
||||
|
||||
void hotkeys::DisableMappingButtons() {
|
||||
for (const auto& i : ButtonsList) {
|
||||
void Hotkeys::DisableMappingButtons() {
|
||||
for (auto& i : PadButtonsList) {
|
||||
i->setEnabled(false);
|
||||
}
|
||||
|
||||
for (auto& i : KBButtonsList) {
|
||||
i->setEnabled(false);
|
||||
}
|
||||
|
||||
@@ -75,8 +90,12 @@ void hotkeys::DisableMappingButtons() {
|
||||
ui->buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
|
||||
}
|
||||
|
||||
void hotkeys::EnableMappingButtons() {
|
||||
for (const auto& i : ButtonsList) {
|
||||
void Hotkeys::EnableMappingButtons() {
|
||||
for (auto& i : PadButtonsList) {
|
||||
i->setEnabled(true);
|
||||
}
|
||||
|
||||
for (auto& i : KBButtonsList) {
|
||||
i->setEnabled(true);
|
||||
}
|
||||
|
||||
@@ -84,63 +103,154 @@ void hotkeys::EnableMappingButtons() {
|
||||
ui->buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true);
|
||||
}
|
||||
|
||||
void hotkeys::SaveHotkeys(bool CloseOnSave) {
|
||||
const auto hotkey_file = Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "hotkeys.ini";
|
||||
if (!std::filesystem::exists(hotkey_file)) {
|
||||
Input::createHotkeyFile(hotkey_file);
|
||||
}
|
||||
void Hotkeys::SetDefault() {
|
||||
|
||||
QString controllerFullscreenString, controllerPauseString, controllerFpsString,
|
||||
controllerQuitString = "";
|
||||
std::ifstream file(hotkey_file);
|
||||
PadButtonsList = {ui->fpsButtonPad, ui->quitButtonPad, ui->fullscreenButtonPad,
|
||||
ui->pauseButtonPad, ui->reloadButtonPad};
|
||||
|
||||
KBButtonsList = {ui->fpsButtonKB, ui->quitButtonKB, ui->fullscreenButtonKB,
|
||||
ui->pauseButtonKB, ui->reloadButtonKB, ui->renderdocButton,
|
||||
ui->mouseJoystickButton, ui->mouseGyroButton};
|
||||
|
||||
ui->fpsButtonPad->setText("unmapped");
|
||||
ui->quitButtonPad->setText("unmapped");
|
||||
ui->fullscreenButtonPad->setText("unmapped");
|
||||
ui->pauseButtonPad->setText("unmapped");
|
||||
ui->reloadButtonPad->setText("unmapped");
|
||||
|
||||
ui->fpsButtonKB->setText("f10");
|
||||
ui->quitButtonKB->setText("lctrl, lshift, end");
|
||||
ui->fullscreenButtonKB->setText("f11");
|
||||
ui->pauseButtonKB->setText("f9");
|
||||
ui->reloadButtonKB->setText("f8");
|
||||
|
||||
ui->renderdocButton->setText("f12");
|
||||
ui->mouseJoystickButton->setText("f7");
|
||||
ui->mouseGyroButton->setText("f6");
|
||||
}
|
||||
|
||||
void Hotkeys::SaveHotkeys(bool CloseOnSave) {
|
||||
std::vector<std::string> lines, inputs;
|
||||
|
||||
auto add_mapping = [&](const QString& buttonText, const std::string& output_name) {
|
||||
if (buttonText.toStdString() != "unmapped") {
|
||||
lines.push_back(output_name + " = " + buttonText.toStdString());
|
||||
inputs.push_back(buttonText.toStdString());
|
||||
}
|
||||
};
|
||||
|
||||
lines.push_back("# Anything put here will be loaded for all games,");
|
||||
lines.push_back("# alongside the game's config or default.ini depending on your preference.");
|
||||
lines.push_back("");
|
||||
|
||||
add_mapping(ui->fullscreenButtonPad->text(), "hotkey_fullscreen");
|
||||
add_mapping(ui->fullscreenButtonKB->text(), "hotkey_fullscreen");
|
||||
lines.push_back("");
|
||||
|
||||
add_mapping(ui->pauseButtonPad->text(), "hotkey_pause");
|
||||
add_mapping(ui->pauseButtonKB->text(), "hotkey_pause");
|
||||
lines.push_back("");
|
||||
|
||||
add_mapping(ui->fpsButtonPad->text(), "hotkey_show_fps");
|
||||
add_mapping(ui->fpsButtonKB->text(), "hotkey_show_fps");
|
||||
lines.push_back("");
|
||||
|
||||
add_mapping(ui->quitButtonPad->text(), "hotkey_quit");
|
||||
add_mapping(ui->quitButtonKB->text(), "hotkey_quit");
|
||||
lines.push_back("");
|
||||
|
||||
add_mapping(ui->reloadButtonPad->text(), "hotkey_reload_inputs");
|
||||
add_mapping(ui->reloadButtonKB->text(), "hotkey_reload_inputs");
|
||||
lines.push_back("");
|
||||
|
||||
add_mapping(ui->renderdocButton->text(), "hotkey_renderdoc_capture");
|
||||
add_mapping(ui->mouseJoystickButton->text(), "hotkey_toggle_mouse_to_joystick");
|
||||
add_mapping(ui->mouseGyroButton->text(), "hotkey_toggle_mouse_to_gyro");
|
||||
|
||||
auto hotkey_file = Config::GetFoolproofInputConfigFile("global");
|
||||
std::fstream file(hotkey_file);
|
||||
int lineCount = 0;
|
||||
std::string line = "";
|
||||
std::vector<std::string> lines;
|
||||
|
||||
std::string line;
|
||||
while (std::getline(file, line)) {
|
||||
lineCount++;
|
||||
|
||||
std::size_t comment_pos = line.find('#');
|
||||
if (comment_pos != std::string::npos) {
|
||||
if (!line.contains("Anything put here will be loaded for all games") &&
|
||||
!line.contains("alongside the game's config or default.ini depending on your"))
|
||||
lines.push_back(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::size_t equal_pos = line.find('=');
|
||||
if (equal_pos == std::string::npos) {
|
||||
lines.push_back(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line.contains("controllerFullscreen")) {
|
||||
line = "controllerFullscreen = " + ui->fullscreenButtonPad->text().toStdString();
|
||||
} else if (line.contains("controllerStop")) {
|
||||
line = "controllerStop = " + ui->quitButtonPad->text().toStdString();
|
||||
} else if (line.contains("controllerFps")) {
|
||||
line = "controllerFps = " + ui->fpsButtonPad->text().toStdString();
|
||||
} else if (line.contains("controllerPause")) {
|
||||
line = "controllerPause = " + ui->pauseButtonPad->text().toStdString();
|
||||
if (!line.contains("hotkey")) {
|
||||
lines.push_back(line);
|
||||
}
|
||||
|
||||
lines.push_back(line);
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
std::ofstream output_file(hotkey_file);
|
||||
// Prevent duplicate inputs that break the input engine
|
||||
bool duplicateFound = false;
|
||||
QSet<QString> duplicateMappings;
|
||||
|
||||
for (auto it = inputs.begin(); it != inputs.end(); ++it) {
|
||||
if (std::find(it + 1, inputs.end(), *it) != inputs.end()) {
|
||||
duplicateFound = true;
|
||||
duplicateMappings.insert(QString::fromStdString(*it));
|
||||
}
|
||||
}
|
||||
|
||||
if (duplicateFound) {
|
||||
QStringList duplicatesList;
|
||||
for (const QString& mapping : duplicateMappings) {
|
||||
for (auto& button : PadButtonsList) {
|
||||
if (button->text() == mapping)
|
||||
duplicatesList.append(button->objectName() + " - " + mapping);
|
||||
}
|
||||
|
||||
for (auto& button : KBButtonsList) {
|
||||
if (button->text() == mapping)
|
||||
duplicatesList.append(button->objectName() + " - " + mapping);
|
||||
}
|
||||
}
|
||||
QMessageBox::information(
|
||||
this, tr("Unable to Save"),
|
||||
// clang-format off
|
||||
QString(tr("Cannot bind any unique input more than once. Duplicate inputs mapped to the following buttons:\n\n%1").arg(duplicatesList.join("\n"))));
|
||||
// clang-format on
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> save;
|
||||
bool CurrentLineEmpty = false, LastLineEmpty = false;
|
||||
for (auto const& line : lines) {
|
||||
LastLineEmpty = CurrentLineEmpty ? true : false;
|
||||
CurrentLineEmpty = line.empty() ? true : false;
|
||||
if (!CurrentLineEmpty || !LastLineEmpty)
|
||||
save.push_back(line);
|
||||
}
|
||||
|
||||
std::ofstream output_file(hotkey_file);
|
||||
for (auto const& line : save) {
|
||||
output_file << line << '\n';
|
||||
}
|
||||
output_file.close();
|
||||
|
||||
Input::LoadHotkeyInputs();
|
||||
// this also parses global hotkeys
|
||||
if (GameRunning)
|
||||
Input::ParseInputConfig("default");
|
||||
|
||||
if (CloseOnSave)
|
||||
QWidget::close();
|
||||
}
|
||||
|
||||
void hotkeys::LoadHotkeys() {
|
||||
const auto hotkey_file = Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "hotkeys.ini";
|
||||
if (!std::filesystem::exists(hotkey_file)) {
|
||||
Input::createHotkeyFile(hotkey_file);
|
||||
}
|
||||
|
||||
QString controllerFullscreenString, controllerPauseString, controllerFpsString,
|
||||
controllerQuitString = "";
|
||||
void Hotkeys::LoadHotkeys() {
|
||||
auto hotkey_file = Config::GetFoolproofInputConfigFile("global");
|
||||
std::ifstream file(hotkey_file);
|
||||
int lineCount = 0;
|
||||
std::string line = "";
|
||||
@@ -152,26 +262,51 @@ void hotkeys::LoadHotkeys() {
|
||||
if (equal_pos == std::string::npos)
|
||||
continue;
|
||||
|
||||
if (line.contains("controllerFullscreen")) {
|
||||
controllerFullscreenString = QString::fromStdString(line.substr(equal_pos + 2));
|
||||
} else if (line.contains("controllerStop")) {
|
||||
controllerQuitString = QString::fromStdString(line.substr(equal_pos + 2));
|
||||
} else if (line.contains("controllerFps")) {
|
||||
controllerFpsString = QString::fromStdString(line.substr(equal_pos + 2));
|
||||
} else if (line.contains("controllerPause")) {
|
||||
controllerPauseString = QString::fromStdString(line.substr(equal_pos + 2));
|
||||
std::string output_string = line.substr(0, equal_pos);
|
||||
std::string input_string = line.substr(equal_pos + 2);
|
||||
|
||||
bool controllerInputDetected = false;
|
||||
for (const 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 (output_string.contains("hotkey_fullscreen")) {
|
||||
controllerInputDetected
|
||||
? ui->fullscreenButtonPad->setText(QString::fromStdString(input_string))
|
||||
: ui->fullscreenButtonKB->setText(QString::fromStdString(input_string));
|
||||
} else if (output_string.contains("hotkey_show_fps")) {
|
||||
controllerInputDetected
|
||||
? ui->fpsButtonPad->setText(QString::fromStdString(input_string))
|
||||
: ui->fpsButtonKB->setText(QString::fromStdString(input_string));
|
||||
} else if (output_string.contains("hotkey_pause")) {
|
||||
controllerInputDetected
|
||||
? ui->pauseButtonPad->setText(QString::fromStdString(input_string))
|
||||
: ui->pauseButtonKB->setText(QString::fromStdString(input_string));
|
||||
} else if (output_string.contains("hotkey_quit")) {
|
||||
controllerInputDetected
|
||||
? ui->quitButtonPad->setText(QString::fromStdString(input_string))
|
||||
: ui->quitButtonKB->setText(QString::fromStdString(input_string));
|
||||
} else if (output_string.contains("hotkey_reload_inputs")) {
|
||||
controllerInputDetected
|
||||
? ui->reloadButtonPad->setText(QString::fromStdString(input_string))
|
||||
: ui->reloadButtonKB->setText(QString::fromStdString(input_string));
|
||||
} else if (output_string.contains("hotkey_renderdoc_capture")) {
|
||||
ui->renderdocButton->setText(QString::fromStdString(input_string));
|
||||
} else if (output_string.contains("hotkey_toggle_mouse_to_joystick")) {
|
||||
ui->mouseJoystickButton->setText(QString::fromStdString(input_string));
|
||||
} else if (output_string.contains("hotkey_toggle_mouse_to_gyro")) {
|
||||
ui->mouseGyroButton->setText(QString::fromStdString(input_string));
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
ui->fpsButtonPad->setText(controllerFpsString);
|
||||
ui->quitButtonPad->setText(controllerQuitString);
|
||||
ui->fullscreenButtonPad->setText(controllerFullscreenString);
|
||||
ui->pauseButtonPad->setText(controllerPauseString);
|
||||
}
|
||||
|
||||
void hotkeys::CheckGamePad() {
|
||||
void Hotkeys::CheckGamePad() {
|
||||
if (h_gamepad) {
|
||||
SDL_CloseGamepad(h_gamepad);
|
||||
h_gamepad = nullptr;
|
||||
@@ -181,6 +316,7 @@ void hotkeys::CheckGamePad() {
|
||||
|
||||
if (!h_gamepads) {
|
||||
LOG_ERROR(Input, "Cannot get gamepad list: {}", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
int defaultIndex = GamepadSelect::GetIndexfromGUID(h_gamepads, gamepad_count,
|
||||
@@ -204,16 +340,14 @@ void hotkeys::CheckGamePad() {
|
||||
}
|
||||
}
|
||||
|
||||
void hotkeys::StartTimer(QPushButton*& button, bool isButton) {
|
||||
void Hotkeys::StartTimer(QPushButton*& button, bool isButton) {
|
||||
MappingTimer = 3;
|
||||
EnableButtonMapping = true;
|
||||
MappingCompleted = false;
|
||||
L2Pressed = false;
|
||||
R2Pressed = false;
|
||||
mapping = button->text();
|
||||
DisableMappingButtons();
|
||||
|
||||
button->setText(tr("Press a button") + " [" + QString::number(MappingTimer) + "]");
|
||||
isButton ? EnablePadMapping = true : EnableKBMapping = true;
|
||||
button->setText(tr("Waiting for inputs") + " [" + QString::number(MappingTimer) + "]");
|
||||
|
||||
timer = new QTimer(this);
|
||||
MappingButton = button;
|
||||
@@ -221,18 +355,18 @@ void hotkeys::StartTimer(QPushButton*& button, bool isButton) {
|
||||
connect(timer, &QTimer::timeout, this, [this]() { CheckMapping(MappingButton); });
|
||||
}
|
||||
|
||||
void hotkeys::CheckMapping(QPushButton*& button) {
|
||||
void Hotkeys::CheckMapping(QPushButton*& button) {
|
||||
MappingTimer -= 1;
|
||||
button->setText(tr("Press a button") + " [" + QString::number(MappingTimer) + "]");
|
||||
button->setText(tr("Waiting for inputs") + " [" + QString::number(MappingTimer) + "]");
|
||||
|
||||
if (pressedButtons.size() > 0) {
|
||||
QStringList keyStrings;
|
||||
|
||||
for (const QString& buttonAction : pressedButtons) {
|
||||
for (QString& buttonAction : pressedButtons) {
|
||||
keyStrings << buttonAction;
|
||||
}
|
||||
|
||||
QString combo = keyStrings.join(",");
|
||||
QString combo = keyStrings.join(", ");
|
||||
SetMapping(combo);
|
||||
MappingButton->setText(combo);
|
||||
pressedButtons.clear();
|
||||
@@ -240,32 +374,427 @@ void hotkeys::CheckMapping(QPushButton*& button) {
|
||||
|
||||
if (MappingCompleted || MappingTimer <= 0) {
|
||||
button->setText(mapping);
|
||||
EnableButtonMapping = false;
|
||||
EnablePadMapping = false;
|
||||
EnableKBMapping = false;
|
||||
L2Pressed = false;
|
||||
R2Pressed = false;
|
||||
EnableMappingButtons();
|
||||
timer->stop();
|
||||
}
|
||||
}
|
||||
|
||||
void hotkeys::SetMapping(QString input) {
|
||||
void Hotkeys::SetMapping(QString input) {
|
||||
mapping = input;
|
||||
MappingCompleted = true;
|
||||
}
|
||||
|
||||
// use QT events instead of SDL to override default event closing the window with escape
|
||||
bool hotkeys::eventFilter(QObject* obj, QEvent* event) {
|
||||
if (event->type() == QEvent::KeyPress && EnableButtonMapping) {
|
||||
// use QT events instead of SDL for KB since SDL doesn't allow background KB events
|
||||
bool Hotkeys::eventFilter(QObject* obj, QEvent* event) {
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
if (keyEvent->key() == Qt::Key_Escape) {
|
||||
SetMapping("unmapped");
|
||||
PushGamepadEvent();
|
||||
if (EnableKBMapping || EnablePadMapping) {
|
||||
SetMapping("unmapped");
|
||||
CheckMapping(MappingButton);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if (EnableKBMapping) {
|
||||
|
||||
if (pressedButtons.size() >= 3) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (keyEvent->key()) {
|
||||
// modifiers
|
||||
case Qt::Key_Shift:
|
||||
if (keyEvent->nativeScanCode() == LSHIFT_KEY) {
|
||||
pressedButtons.insert(1, "lshift");
|
||||
} else {
|
||||
pressedButtons.insert(2, "rshift");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Alt:
|
||||
if (keyEvent->nativeScanCode() == LALT_KEY) {
|
||||
pressedButtons.insert(3, "lalt");
|
||||
} else {
|
||||
pressedButtons.insert(4, "ralt");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Control:
|
||||
if (keyEvent->nativeScanCode() == LCTRL_KEY) {
|
||||
pressedButtons.insert(5, "lctrl");
|
||||
} else {
|
||||
pressedButtons.insert(6, "rctrl");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Meta:
|
||||
#ifdef _WIN32
|
||||
pressedButtons.insert(7, "lwin");
|
||||
#else
|
||||
pressedButtons.insert(7, "lmeta");
|
||||
#endif
|
||||
break;
|
||||
|
||||
// f keys
|
||||
|
||||
case Qt::Key_F1:
|
||||
pressedButtons.insert(8, "f1");
|
||||
break;
|
||||
case Qt::Key_F2:
|
||||
pressedButtons.insert(9, "f2");
|
||||
break;
|
||||
case Qt::Key_F3:
|
||||
pressedButtons.insert(10, "f3");
|
||||
break;
|
||||
case Qt::Key_F4:
|
||||
pressedButtons.insert(11, "f4");
|
||||
break;
|
||||
case Qt::Key_F5:
|
||||
pressedButtons.insert(12, "f5");
|
||||
break;
|
||||
case Qt::Key_F6:
|
||||
pressedButtons.insert(13, "f6");
|
||||
break;
|
||||
case Qt::Key_F7:
|
||||
pressedButtons.insert(14, "f7");
|
||||
break;
|
||||
case Qt::Key_F8:
|
||||
pressedButtons.insert(15, "f8");
|
||||
break;
|
||||
case Qt::Key_F9:
|
||||
pressedButtons.insert(16, "f9");
|
||||
break;
|
||||
case Qt::Key_F10:
|
||||
pressedButtons.insert(17, "f10");
|
||||
break;
|
||||
case Qt::Key_F11:
|
||||
pressedButtons.insert(18, "f11");
|
||||
break;
|
||||
case Qt::Key_F12:
|
||||
pressedButtons.insert(19, "f12");
|
||||
break;
|
||||
|
||||
// alphanumeric
|
||||
case Qt::Key_A:
|
||||
pressedButtons.insert(20, "a");
|
||||
break;
|
||||
case Qt::Key_B:
|
||||
pressedButtons.insert(21, "b");
|
||||
break;
|
||||
case Qt::Key_C:
|
||||
pressedButtons.insert(22, "c");
|
||||
break;
|
||||
case Qt::Key_D:
|
||||
pressedButtons.insert(23, "d");
|
||||
break;
|
||||
case Qt::Key_E:
|
||||
pressedButtons.insert(24, "e");
|
||||
break;
|
||||
case Qt::Key_F:
|
||||
pressedButtons.insert(25, "f");
|
||||
break;
|
||||
case Qt::Key_G:
|
||||
pressedButtons.insert(26, "g");
|
||||
break;
|
||||
case Qt::Key_H:
|
||||
pressedButtons.insert(27, "h");
|
||||
break;
|
||||
case Qt::Key_I:
|
||||
pressedButtons.insert(28, "i");
|
||||
break;
|
||||
case Qt::Key_J:
|
||||
pressedButtons.insert(29, "j");
|
||||
break;
|
||||
case Qt::Key_K:
|
||||
pressedButtons.insert(30, "k");
|
||||
break;
|
||||
case Qt::Key_L:
|
||||
pressedButtons.insert(31, "l");
|
||||
break;
|
||||
case Qt::Key_M:
|
||||
pressedButtons.insert(32, "m");
|
||||
break;
|
||||
case Qt::Key_N:
|
||||
pressedButtons.insert(33, "n");
|
||||
break;
|
||||
case Qt::Key_O:
|
||||
pressedButtons.insert(34, "o");
|
||||
break;
|
||||
case Qt::Key_P:
|
||||
pressedButtons.insert(35, "p");
|
||||
break;
|
||||
case Qt::Key_Q:
|
||||
pressedButtons.insert(36, "q");
|
||||
break;
|
||||
case Qt::Key_R:
|
||||
pressedButtons.insert(37, "r");
|
||||
break;
|
||||
case Qt::Key_S:
|
||||
pressedButtons.insert(38, "s");
|
||||
break;
|
||||
case Qt::Key_T:
|
||||
pressedButtons.insert(39, "t");
|
||||
break;
|
||||
case Qt::Key_U:
|
||||
pressedButtons.insert(40, "u");
|
||||
break;
|
||||
case Qt::Key_V:
|
||||
pressedButtons.insert(41, "v");
|
||||
break;
|
||||
case Qt::Key_W:
|
||||
pressedButtons.insert(42, "w");
|
||||
break;
|
||||
case Qt::Key_X:
|
||||
pressedButtons.insert(43, "x");
|
||||
break;
|
||||
case Qt::Key_Y:
|
||||
pressedButtons.insert(44, "y");
|
||||
break;
|
||||
case Qt::Key_Z:
|
||||
pressedButtons.insert(45, "z");
|
||||
break;
|
||||
case Qt::Key_0:
|
||||
QApplication::keyboardModifiers() & Qt::KeypadModifier
|
||||
? pressedButtons.insert(46, "kp0")
|
||||
: pressedButtons.insert(56, "0");
|
||||
break;
|
||||
case Qt::Key_1:
|
||||
QApplication::keyboardModifiers() & Qt::KeypadModifier
|
||||
? pressedButtons.insert(47, "kp1")
|
||||
: pressedButtons.insert(57, "1");
|
||||
break;
|
||||
case Qt::Key_2:
|
||||
QApplication::keyboardModifiers() & Qt::KeypadModifier
|
||||
? pressedButtons.insert(48, "kp2")
|
||||
: pressedButtons.insert(58, "2");
|
||||
break;
|
||||
case Qt::Key_3:
|
||||
QApplication::keyboardModifiers() & Qt::KeypadModifier
|
||||
? pressedButtons.insert(49, "kp3")
|
||||
: pressedButtons.insert(59, "3");
|
||||
break;
|
||||
case Qt::Key_4:
|
||||
QApplication::keyboardModifiers() & Qt::KeypadModifier
|
||||
? pressedButtons.insert(50, "kp4")
|
||||
: pressedButtons.insert(60, "4");
|
||||
break;
|
||||
case Qt::Key_5:
|
||||
QApplication::keyboardModifiers() & Qt::KeypadModifier
|
||||
? pressedButtons.insert(51, "kp5")
|
||||
: pressedButtons.insert(61, "5");
|
||||
break;
|
||||
case Qt::Key_6:
|
||||
QApplication::keyboardModifiers() & Qt::KeypadModifier
|
||||
? pressedButtons.insert(52, "kp6")
|
||||
: pressedButtons.insert(62, "6");
|
||||
break;
|
||||
case Qt::Key_7:
|
||||
QApplication::keyboardModifiers() & Qt::KeypadModifier
|
||||
? pressedButtons.insert(53, "kp7")
|
||||
: pressedButtons.insert(63, "7");
|
||||
break;
|
||||
case Qt::Key_8:
|
||||
QApplication::keyboardModifiers() & Qt::KeypadModifier
|
||||
? pressedButtons.insert(54, "kp8")
|
||||
: pressedButtons.insert(64, "8");
|
||||
break;
|
||||
case Qt::Key_9:
|
||||
QApplication::keyboardModifiers() & Qt::KeypadModifier
|
||||
? pressedButtons.insert(55, "kp9")
|
||||
: pressedButtons.insert(65, "9");
|
||||
break;
|
||||
|
||||
// symbols
|
||||
case Qt::Key_Asterisk:
|
||||
QApplication::keyboardModifiers() & Qt::KeypadModifier
|
||||
? pressedButtons.insert(66, "kpasterisk")
|
||||
: pressedButtons.insert(74, "asterisk");
|
||||
break;
|
||||
case Qt::Key_Minus:
|
||||
QApplication::keyboardModifiers() & Qt::KeypadModifier
|
||||
? pressedButtons.insert(67, "kpminus")
|
||||
: pressedButtons.insert(75, "minus");
|
||||
break;
|
||||
case Qt::Key_Equal:
|
||||
QApplication::keyboardModifiers() & Qt::KeypadModifier
|
||||
? pressedButtons.insert(68, "kpequals")
|
||||
: pressedButtons.insert(76, "equals");
|
||||
break;
|
||||
case Qt::Key_Plus:
|
||||
QApplication::keyboardModifiers() & Qt::KeypadModifier
|
||||
? pressedButtons.insert(69, "kpplus")
|
||||
: pressedButtons.insert(77, "plus");
|
||||
break;
|
||||
case Qt::Key_Slash:
|
||||
QApplication::keyboardModifiers() & Qt::KeypadModifier
|
||||
? pressedButtons.insert(70, "kpslash")
|
||||
: pressedButtons.insert(78, "slash");
|
||||
break;
|
||||
case Qt::Key_Comma:
|
||||
QApplication::keyboardModifiers() & Qt::KeypadModifier
|
||||
? pressedButtons.insert(71, "kpcomma")
|
||||
: pressedButtons.insert(79, "comma");
|
||||
break;
|
||||
case Qt::Key_Period:
|
||||
QApplication::keyboardModifiers() & Qt::KeypadModifier
|
||||
? pressedButtons.insert(72, "kpperiod")
|
||||
: pressedButtons.insert(80, "period");
|
||||
break;
|
||||
case Qt::Key_Enter:
|
||||
QApplication::keyboardModifiers() & Qt::KeypadModifier
|
||||
? pressedButtons.insert(73, "kpenter")
|
||||
: pressedButtons.insert(81, "enter");
|
||||
break;
|
||||
case Qt::Key_QuoteLeft:
|
||||
pressedButtons.insert(82, "grave");
|
||||
break;
|
||||
case Qt::Key_AsciiTilde:
|
||||
pressedButtons.insert(83, "tilde");
|
||||
break;
|
||||
case Qt::Key_Exclam:
|
||||
pressedButtons.insert(84, "exclamation");
|
||||
break;
|
||||
case Qt::Key_At:
|
||||
pressedButtons.insert(85, "at");
|
||||
break;
|
||||
case Qt::Key_NumberSign:
|
||||
pressedButtons.insert(86, "hash");
|
||||
break;
|
||||
case Qt::Key_Dollar:
|
||||
pressedButtons.insert(87, "dollar");
|
||||
break;
|
||||
case Qt::Key_Percent:
|
||||
pressedButtons.insert(88, "percent");
|
||||
break;
|
||||
case Qt::Key_AsciiCircum:
|
||||
pressedButtons.insert(89, "caret");
|
||||
break;
|
||||
case Qt::Key_Ampersand:
|
||||
pressedButtons.insert(90, "ampersand");
|
||||
break;
|
||||
case Qt::Key_ParenLeft:
|
||||
pressedButtons.insert(91, "lparen");
|
||||
break;
|
||||
case Qt::Key_ParenRight:
|
||||
pressedButtons.insert(92, "rparen");
|
||||
break;
|
||||
case Qt::Key_BracketLeft:
|
||||
pressedButtons.insert(93, "lbracket");
|
||||
break;
|
||||
case Qt::Key_BracketRight:
|
||||
pressedButtons.insert(94, "rbracket");
|
||||
break;
|
||||
case Qt::Key_BraceLeft:
|
||||
pressedButtons.insert(95, "lbrace");
|
||||
break;
|
||||
case Qt::Key_BraceRight:
|
||||
pressedButtons.insert(96, "rbrace");
|
||||
break;
|
||||
case Qt::Key_Underscore:
|
||||
pressedButtons.insert(97, "underscore");
|
||||
break;
|
||||
case Qt::Key_Backslash:
|
||||
pressedButtons.insert(98, "backslash");
|
||||
break;
|
||||
case Qt::Key_Bar:
|
||||
pressedButtons.insert(99, "pipe");
|
||||
break;
|
||||
case Qt::Key_Semicolon:
|
||||
pressedButtons.insert(100, "semicolon");
|
||||
break;
|
||||
case Qt::Key_Colon:
|
||||
pressedButtons.insert(101, "colon");
|
||||
break;
|
||||
case Qt::Key_Apostrophe:
|
||||
pressedButtons.insert(102, "apostrophe");
|
||||
break;
|
||||
case Qt::Key_QuoteDbl:
|
||||
pressedButtons.insert(103, "quote");
|
||||
break;
|
||||
case Qt::Key_Less:
|
||||
pressedButtons.insert(104, "less");
|
||||
break;
|
||||
case Qt::Key_Greater:
|
||||
pressedButtons.insert(105, "greater");
|
||||
break;
|
||||
case Qt::Key_Question:
|
||||
pressedButtons.insert(106, "question");
|
||||
break;
|
||||
|
||||
// special keys
|
||||
case Qt::Key_Print:
|
||||
pressedButtons.insert(107, "printscreen");
|
||||
break;
|
||||
case Qt::Key_ScrollLock:
|
||||
pressedButtons.insert(108, "scrolllock");
|
||||
break;
|
||||
case Qt::Key_Pause:
|
||||
pressedButtons.insert(109, "pausebreak");
|
||||
break;
|
||||
case Qt::Key_Backspace:
|
||||
pressedButtons.insert(110, "backspace");
|
||||
break;
|
||||
case Qt::Key_Insert:
|
||||
pressedButtons.insert(111, "insert");
|
||||
break;
|
||||
case Qt::Key_Delete:
|
||||
pressedButtons.insert(112, "delete");
|
||||
break;
|
||||
case Qt::Key_Home:
|
||||
pressedButtons.insert(113, "home");
|
||||
break;
|
||||
case Qt::Key_End:
|
||||
pressedButtons.insert(114, "end");
|
||||
break;
|
||||
case Qt::Key_PageUp:
|
||||
pressedButtons.insert(115, "pgup");
|
||||
break;
|
||||
case Qt::Key_PageDown:
|
||||
pressedButtons.insert(116, "pgdown");
|
||||
break;
|
||||
case Qt::Key_Tab:
|
||||
pressedButtons.insert(117, "tab");
|
||||
break;
|
||||
case Qt::Key_CapsLock:
|
||||
pressedButtons.insert(118, "capslock");
|
||||
break;
|
||||
case Qt::Key_Return:
|
||||
pressedButtons.insert(119, "enter");
|
||||
break;
|
||||
case Qt::Key_Space:
|
||||
pressedButtons.insert(120, "space");
|
||||
break;
|
||||
case Qt::Key_Up:
|
||||
pressedButtons.insert(121, "up");
|
||||
break;
|
||||
case Qt::Key_Down:
|
||||
pressedButtons.insert(122, "down");
|
||||
break;
|
||||
case Qt::Key_Left:
|
||||
pressedButtons.insert(123, "left");
|
||||
break;
|
||||
case Qt::Key_Right:
|
||||
pressedButtons.insert(124, "right");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event->type() == QEvent::KeyPress && EnableKBMapping) {
|
||||
CheckMapping(MappingButton);
|
||||
return true;
|
||||
}
|
||||
|
||||
return QDialog::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
void hotkeys::processSDLEvents(int Type, int Input, int Value) {
|
||||
if (EnableButtonMapping) {
|
||||
void Hotkeys::processSDLEvents(int Type, int Input, int Value) {
|
||||
if (EnablePadMapping) {
|
||||
|
||||
if (pressedButtons.size() >= 3) {
|
||||
return;
|
||||
@@ -330,7 +859,7 @@ void hotkeys::processSDLEvents(int Type, int Input, int Value) {
|
||||
L2Pressed = true;
|
||||
} else if (Value < 5000) {
|
||||
if (L2Pressed && !R2Pressed)
|
||||
emit PushGamepadEvent();
|
||||
CheckMapping(MappingButton);
|
||||
}
|
||||
break;
|
||||
case SDL_GAMEPAD_AXIS_RIGHT_TRIGGER:
|
||||
@@ -339,7 +868,7 @@ void hotkeys::processSDLEvents(int Type, int Input, int Value) {
|
||||
R2Pressed = true;
|
||||
} else if (Value < 5000) {
|
||||
if (R2Pressed && !L2Pressed)
|
||||
emit PushGamepadEvent();
|
||||
CheckMapping(MappingButton);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -348,7 +877,7 @@ void hotkeys::processSDLEvents(int Type, int Input, int Value) {
|
||||
}
|
||||
|
||||
if (Type == SDL_EVENT_GAMEPAD_BUTTON_UP)
|
||||
emit PushGamepadEvent();
|
||||
CheckMapping(MappingButton);
|
||||
}
|
||||
|
||||
if (Type == SDL_EVENT_GAMEPAD_ADDED || SDL_EVENT_GAMEPAD_REMOVED) {
|
||||
@@ -356,7 +885,7 @@ void hotkeys::processSDLEvents(int Type, int Input, int Value) {
|
||||
}
|
||||
}
|
||||
|
||||
void hotkeys::pollSDLEvents() {
|
||||
void Hotkeys::pollSDLEvents() {
|
||||
SDL_Event event;
|
||||
while (SdlEventWrapper::Wrapper::wrapperActive) {
|
||||
|
||||
@@ -372,14 +901,15 @@ void hotkeys::pollSDLEvents() {
|
||||
}
|
||||
}
|
||||
|
||||
void hotkeys::Cleanup() {
|
||||
void Hotkeys::Cleanup() {
|
||||
SdlEventWrapper::Wrapper::wrapperActive = false;
|
||||
if (h_gamepad) {
|
||||
SDL_CloseGamepad(h_gamepad);
|
||||
h_gamepad = nullptr;
|
||||
}
|
||||
|
||||
SDL_free(h_gamepads);
|
||||
if (h_gamepads)
|
||||
SDL_free(h_gamepads);
|
||||
|
||||
if (!GameRunning) {
|
||||
SDL_Event quitLoop{};
|
||||
@@ -397,4 +927,4 @@ void hotkeys::Cleanup() {
|
||||
}
|
||||
}
|
||||
|
||||
hotkeys::~hotkeys() {}
|
||||
Hotkeys::~Hotkeys() {}
|
||||
|
||||
@@ -3,40 +3,50 @@
|
||||
|
||||
#include <QDialog>
|
||||
#include <QFuture>
|
||||
#include <QTimer>
|
||||
#include <SDL3/SDL_gamepad.h>
|
||||
|
||||
#include "sdl_event_wrapper.h"
|
||||
#ifdef _WIN32
|
||||
#define LCTRL_KEY 29
|
||||
#define LALT_KEY 56
|
||||
#define LSHIFT_KEY 42
|
||||
#else
|
||||
#define LCTRL_KEY 37
|
||||
#define LALT_KEY 64
|
||||
#define LSHIFT_KEY 50
|
||||
#endif
|
||||
|
||||
namespace Ui {
|
||||
class hotkeys;
|
||||
class Hotkeys;
|
||||
}
|
||||
|
||||
class hotkeys : public QDialog {
|
||||
class Hotkeys : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit hotkeys(bool GameRunning, QWidget* parent = nullptr);
|
||||
~hotkeys();
|
||||
explicit Hotkeys(bool GameRunning, QWidget* parent = nullptr);
|
||||
~Hotkeys();
|
||||
|
||||
signals:
|
||||
void PushGamepadEvent();
|
||||
private Q_SLOTS:
|
||||
void processSDLEvents(int Type, int Input, int Value);
|
||||
void StartTimer(QPushButton*& button, bool isPad);
|
||||
void SaveHotkeys(bool CloseOnSave);
|
||||
void SetDefault();
|
||||
|
||||
private:
|
||||
bool eventFilter(QObject* obj, QEvent* event) override;
|
||||
void CheckMapping(QPushButton*& button);
|
||||
void StartTimer(QPushButton*& button, bool isButton);
|
||||
void DisableMappingButtons();
|
||||
void EnableMappingButtons();
|
||||
void SaveHotkeys(bool CloseOnSave);
|
||||
void LoadHotkeys();
|
||||
void processSDLEvents(int Type, int Input, int Value);
|
||||
void pollSDLEvents();
|
||||
void CheckGamePad();
|
||||
void SetMapping(QString input);
|
||||
void Cleanup();
|
||||
|
||||
bool GameRunning;
|
||||
bool EnableButtonMapping = false;
|
||||
bool EnablePadMapping = false;
|
||||
bool EnableKBMapping = false;
|
||||
bool MappingCompleted = false;
|
||||
bool L2Pressed = false;
|
||||
bool R2Pressed = false;
|
||||
@@ -50,13 +60,29 @@ private:
|
||||
|
||||
// use QMap instead of QSet to maintain order of inserted strings
|
||||
QMap<int, QString> pressedButtons;
|
||||
QList<QPushButton*> ButtonsList;
|
||||
QList<QPushButton*> PadButtonsList;
|
||||
QList<QPushButton*> KBButtonsList;
|
||||
QFuture<void> Polling;
|
||||
|
||||
Ui::hotkeys* ui;
|
||||
Ui::Hotkeys* ui;
|
||||
|
||||
const std::vector<std::string> ControllerInputs = {
|
||||
"cross", "circle", "square", "triangle", "l1",
|
||||
"r1", "l2", "r2", "l3",
|
||||
|
||||
"r3", "options", "pad_up",
|
||||
|
||||
"pad_down",
|
||||
|
||||
"pad_left", "pad_right", "axis_left_x", "axis_left_y", "axis_right_x",
|
||||
"axis_right_y", "back"};
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent* event) override {
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
void accept() override {
|
||||
// Blank override to prevent quitting when save button pressed
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,217 +2,315 @@
|
||||
<!-- SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
SPDX-License-Identifier: GPL-2.0-or-later -->
|
||||
<ui version="4.0">
|
||||
<class>hotkeys</class>
|
||||
<widget class="QDialog" name="hotkeys">
|
||||
<class>Hotkeys</class>
|
||||
<widget class="QDialog" name="Hotkeys">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::WindowModality::WindowModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>849</width>
|
||||
<height>496</height>
|
||||
<width>987</width>
|
||||
<height>549</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Customize Hotkeys</string>
|
||||
</property>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>750</x>
|
||||
<y>200</y>
|
||||
<width>81</width>
|
||||
<height>81</height>
|
||||
<x>3</x>
|
||||
<y>2</y>
|
||||
<width>981</width>
|
||||
<height>541</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::StandardButton::Apply|QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Save</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QWidget" name="verticalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>10</y>
|
||||
<width>681</width>
|
||||
<height>231</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="controllerLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="controllerLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>19</pointsize>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Controller Hotkeys</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutPad1">
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>979</width>
|
||||
<height>539</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QWidget" name="verticalLayoutWidget_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>3</x>
|
||||
<y>7</y>
|
||||
<width>971</width>
|
||||
<height>532</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="HotkeysLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="fpsGroupbox">
|
||||
<property name="title">
|
||||
<string>Show FPS Counter</string>
|
||||
<widget class="QLabel" name="controllerLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>19</pointsize>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Controller Hotkeys</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="fpsButtonPad">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::FocusPolicy::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>unmapped</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="stopGroupbox">
|
||||
<property name="title">
|
||||
<string>Stop Emulator</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QPushButton" name="quitButtonPad">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::FocusPolicy::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>unmapped</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutPad2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="fullscreenGroupbox">
|
||||
<property name="title">
|
||||
<string>Toggle Fullscreen</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="fullscreenButtonPad">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::FocusPolicy::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>unmapped</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="pauseGroupbox">
|
||||
<property name="title">
|
||||
<string>Toggle Pause</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pauseButtonPad">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::FocusPolicy::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>unmapped</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="verticalLayoutWidget_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>250</y>
|
||||
<width>681</width>
|
||||
<height>191</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="keyboardLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="keyboardLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>19</pointsize>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Keyboard Hotkeys</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="KBLabelsLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutKB1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutPad1">
|
||||
<item>
|
||||
<widget class="QLabel" name="fpsLabelKB">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
<widget class="QGroupBox" name="fpsGroupboxPad">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Shape::Box</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show Fps Counter: F10</string>
|
||||
<property name="title">
|
||||
<string>Show FPS Counter</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="fpsButtonPad">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::FocusPolicy::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>unmapped</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="stopLabelKB">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
<widget class="QGroupBox" name="quitGroupboxKB_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Shape::Box</enum>
|
||||
<property name="title">
|
||||
<string>Quit Emulation</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Stop Emulator: n/a</string>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QPushButton" name="quitButtonPad">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::FocusPolicy::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>unmapped</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="reloadMappingsBoxPad">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Reload Button Mappings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QPushButton" name="reloadButtonPad">
|
||||
<property name="text">
|
||||
<string>unmapped</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutPad2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="fullscreenGroupboxPad">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Toggle Fullscreen</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="fullscreenButtonPad">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::FocusPolicy::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>unmapped</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="pauseGroupboxPad">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Toggle Pause</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pauseButtonPad">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::FocusPolicy::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>unmapped</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="keyboardLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>19</pointsize>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Keyboard Hotkeys</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutKB1">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="fpsGroupboxKB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Show FPS Counter</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<item>
|
||||
<widget class="QPushButton" name="fpsButtonKB">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::FocusPolicy::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>unmapped</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="quitGroupboxKB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Quit Emulation</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||
<item>
|
||||
<widget class="QPushButton" name="quitButtonKB">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::FocusPolicy::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>unmapped</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="reloadMappingsBoxKB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Reload Button Mappings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||
<item>
|
||||
<widget class="QPushButton" name="reloadButtonKB">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::FocusPolicy::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>unmapped</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@@ -220,59 +318,197 @@
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutKB2">
|
||||
<item>
|
||||
<widget class="QLabel" name="fullscreenLabelKB">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
<widget class="QGroupBox" name="fullscreenGroupboxKB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Shape::Box</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Toggle Fullscreen: F11</string>
|
||||
<property name="title">
|
||||
<string>Toggle Fullscreen</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||
<item>
|
||||
<widget class="QPushButton" name="fullscreenButtonKB">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::FocusPolicy::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>unmapped</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="pauseLabelKB">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
<widget class="QGroupBox" name="pauseGroupboxKB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Shape::Box</enum>
|
||||
<property name="title">
|
||||
<string>Toggle Pause</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Toggle Pause: F9</string>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_10">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pauseButtonKB">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::FocusPolicy::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>unmapped</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="renderdocGroupbox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Renderdoc Capture (for debugging only)</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_12">
|
||||
<item>
|
||||
<widget class="QPushButton" name="renderdocButton">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::FocusPolicy::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>unmapped</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="mouseJoystickGroupbox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Toggle Mouse to Joystick Emulation</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||
<item>
|
||||
<widget class="QPushButton" name="mouseJoystickButton">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::FocusPolicy::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>unmapped</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="mouseGyroGroupbox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Toggle Mouse to Gyro Emulation</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_14">
|
||||
<item>
|
||||
<widget class="QPushButton" name="mouseGyroButton">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::FocusPolicy::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>unmapped</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="tipLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Tip: Up to three simultaneous inputs can be assigned for each hotkey</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::StandardButton::Apply|QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::RestoreDefaults|QDialogButtonBox::StandardButton::Save</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QLabel" name="tipLabel">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>50</x>
|
||||
<y>450</y>
|
||||
<width>631</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Tip: Up to three inputs can be assigned for each function</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
@@ -280,7 +516,7 @@
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>hotkeys</receiver>
|
||||
<receiver>Hotkeys</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
@@ -296,7 +532,7 @@
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>hotkeys</receiver>
|
||||
<receiver>Hotkeys</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
|
||||
@@ -85,7 +85,7 @@ EditorDialog::EditorDialog(QWidget* parent) : QDialog(parent) {
|
||||
|
||||
void EditorDialog::loadFile(QString game) {
|
||||
|
||||
const auto config_file = Config::GetFoolproofKbmConfigFile(game.toStdString());
|
||||
const auto config_file = Config::GetFoolproofInputConfigFile(game.toStdString());
|
||||
QFile file(config_file);
|
||||
|
||||
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
@@ -100,7 +100,7 @@ void EditorDialog::loadFile(QString game) {
|
||||
|
||||
void EditorDialog::saveFile(QString game) {
|
||||
|
||||
const auto config_file = Config::GetFoolproofKbmConfigFile(game.toStdString());
|
||||
const auto config_file = Config::GetFoolproofInputConfigFile(game.toStdString());
|
||||
QFile file(config_file);
|
||||
|
||||
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
@@ -195,10 +195,10 @@ void EditorDialog::onResetToDefaultClicked() {
|
||||
|
||||
if (reply == QMessageBox::Yes) {
|
||||
if (default_default) {
|
||||
const auto default_file = Config::GetFoolproofKbmConfigFile("default");
|
||||
const auto default_file = Config::GetFoolproofInputConfigFile("default");
|
||||
std::filesystem::remove(default_file);
|
||||
}
|
||||
const auto config_file = Config::GetFoolproofKbmConfigFile("default");
|
||||
const auto config_file = Config::GetFoolproofInputConfigFile("default");
|
||||
QFile file(config_file);
|
||||
|
||||
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
|
||||
@@ -254,7 +254,7 @@ void KBMSettings::SaveKBMConfig(bool close_on_save) {
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
|
||||
lines.push_back("");
|
||||
const auto config_file = Config::GetFoolproofKbmConfigFile(config_id);
|
||||
const auto config_file = Config::GetFoolproofInputConfigFile(config_id);
|
||||
std::fstream file(config_file);
|
||||
int lineCount = 0;
|
||||
std::string line;
|
||||
@@ -293,7 +293,7 @@ void KBMSettings::SaveKBMConfig(bool close_on_save) {
|
||||
}
|
||||
|
||||
if (controllerInputdetected || output_string == "analog_deadzone" ||
|
||||
output_string == "override_controller_color") {
|
||||
output_string == "override_controller_color" || output_string.contains("hotkey")) {
|
||||
lines.push_back(line);
|
||||
}
|
||||
}
|
||||
@@ -396,7 +396,7 @@ void KBMSettings::SetDefault() {
|
||||
}
|
||||
|
||||
void KBMSettings::SetUIValuestoMappings(std::string config_id) {
|
||||
const auto config_file = Config::GetFoolproofKbmConfigFile(config_id);
|
||||
const auto config_file = Config::GetFoolproofInputConfigFile(config_id);
|
||||
std::ifstream file(config_file);
|
||||
|
||||
int lineCount = 0;
|
||||
|
||||
@@ -114,11 +114,9 @@ HelpDialog::HelpDialog(bool* open_flag, QWidget* parent) : QDialog(parent) {
|
||||
// Helper functions that store the text contents for each tab inb the HelpDialog menu
|
||||
QString HelpDialog::quickstart() {
|
||||
return R"(
|
||||
The keyboard and controller remapping backend, GUI, and documentation have been written by kalaposfos.
|
||||
|
||||
In this section, you will find information about the project and its features, as well as help setting up your ideal setup.
|
||||
To view the config file's syntax, check out the Syntax tab, for keybind names, visit Normal Keybinds and Special Bindings, and if you are here to view emulator-wide keybinds, you can find it in the FAQ section.
|
||||
This project began because I disliked the original, unchangeable keybinds. Rather than waiting for someone else to do it, I implemented this myself. From the default keybinds, you can clearly tell this was a project built for Bloodborne, but obviously, you can make adjustments however you like.)";
|
||||
)";
|
||||
}
|
||||
|
||||
QString HelpDialog::syntax() {
|
||||
@@ -157,6 +155,8 @@ Keyboard:
|
||||
'a', 'b', ..., 'z'
|
||||
Numbers:
|
||||
'0', '1', ..., '9'
|
||||
F keys:
|
||||
'f1', 'f2', ..., 'f12'
|
||||
Keypad:
|
||||
'kp0', 'kp1', ..., 'kp9',
|
||||
'kpperiod', 'kpcomma', 'kpslash', 'kpasterisk', 'kpminus', 'kpplus', 'kpequals', 'kpenter'
|
||||
@@ -186,7 +186,7 @@ Controller:
|
||||
'triangle', 'circle', 'cross', 'square', 'l1', 'l3',
|
||||
'options', touchpad', 'up', 'down', 'left', 'right'
|
||||
Input-only:
|
||||
'lpaddle_low', 'lpaddle_high'
|
||||
'lpaddle_low', 'lpaddle_high', 'back' = 'share' (Xbox and PS4 names)
|
||||
Output-only:
|
||||
'touchpad_left', 'touchpad_center', 'touchpad_right'
|
||||
Axes if you bind them to a button input:
|
||||
@@ -196,9 +196,6 @@ Controller:
|
||||
Axes if you bind them to another axis input:
|
||||
'axis_left_x', 'axis_left_y', 'axis_right_x', 'axis_right_y',
|
||||
'l2'
|
||||
|
||||
Invalid Inputs:
|
||||
'F1-F12' are reserved for emulator-wide keybinds, and cannot be bound to controller inputs.
|
||||
|
||||
Symbols (expanded):
|
||||
` 'grave'
|
||||
@@ -235,7 +232,13 @@ Symbols (expanded):
|
||||
QString HelpDialog::special() {
|
||||
return R"(
|
||||
There are some extra bindings you can put in the config file that don't correspond to a controller input but something else.
|
||||
You can find these here, with detailed comments, examples, and suggestions for most of them.
|
||||
You can find these here, with comments, examples, and suggestions for most of them.
|
||||
|
||||
Emulator hotkeys:
|
||||
These are regarded as normal bindings, but they are put in a special config named global.ini by default, which is a config that is always loaded alongside the main config (If you want to, you can use this to set some common bindings that'll be in effect for every game, then put only the game specific bindings in their respective files). This doesn't mean you can't add them to the normal configs, you can absolutely make game specific emulator hokeys as well.
|
||||
'hotkey_pause', 'hotkey_fullscreen', 'hotkey_show_fps',
|
||||
'hotkey_quit', 'hotkey_reload_inputs', 'hotkey_toggle_mouse_to_joystick',
|
||||
'hotkey_toggle_mouse_to_gyro', 'hotkey_renderdoc_capture'
|
||||
|
||||
'leftjoystick_halfmode' and 'rightjoystick_halfmode' = <key>;
|
||||
These are a pair of input modifiers that change the way keyboard button-bound axes work. By default, those push the joystick to the max in their respective direction, but if their respective 'joystick_halfmode' modifier value is true, they only push it... halfway. With this, you can change from run to walk in games like Bloodborne.
|
||||
@@ -272,7 +275,7 @@ You can find these here, with detailed comments, examples, and suggestions for m
|
||||
QString HelpDialog::faq() {
|
||||
return R"(
|
||||
Q: What are the emulator-wide keybinds?
|
||||
A:
|
||||
A: By default, they're the following:
|
||||
-F12: Triggers Renderdoc capture
|
||||
-F11: Toggles fullscreen
|
||||
-F10: Toggles FPS counter
|
||||
@@ -281,6 +284,7 @@ A:
|
||||
-F8: Reparses the config file while in-game
|
||||
-F7: Toggles mouse capture and mouse input
|
||||
-F6: Toggles mouse-to-gyro emulation
|
||||
More info on these can be found in the Special keybinds tab.
|
||||
|
||||
Q: How do I switch between mouse and controller joystick input? Why is it even required?
|
||||
A: Pressing F7 toggles between mouse and controller joystick input. It is required because the program polls the mouse input, which means it checks mouse movement every frame. If it didn't move, the code would manually set the emulator's virtual controller to 0 (to the center), even if other input devices would update it.
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "control_settings.h"
|
||||
#include "game_install_dialog.h"
|
||||
#include "hotkeys.h"
|
||||
#include "input/input_handler.h"
|
||||
#include "kbm_gui.h"
|
||||
#include "main_window.h"
|
||||
#include "settings_dialog.h"
|
||||
@@ -497,7 +498,7 @@ void MainWindow::CreateConnects() {
|
||||
});
|
||||
|
||||
connect(ui->configureHotkeys, &QAction::triggered, this, [this]() {
|
||||
auto hotkeyDialog = new hotkeys(isGameRunning, this);
|
||||
auto hotkeyDialog = new Hotkeys(isGameRunning, this);
|
||||
hotkeyDialog->exec();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user