mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-25 11:56:18 +00:00
KBM Input Bug Fixes / Added Binds v2 (#3109)
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / linux-sdl-gcc (push) Blocked by required conditions
Build and Release / linux-qt-gcc (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / linux-sdl-gcc (push) Blocked by required conditions
Build and Release / linux-qt-gcc (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions
* fixed nonload issues with background music (#3094)
* Fixing my pull request branch
* Pull request change part 2
* Continued changes to project and altered kbm_help_dialog.h text to QStringLiterals
* Finalized commit and changed kbm_help_dialog.h
* KBM Input Bug Fixes / Added Binds
Fixed input issues where some inputs would not bind when pressing (side mouse buttons, some symbols, etc). Also, fixed up code formatting in altered files (removed C-style casts and replaced with C++ <static_casts>, added a few macros and one member functions).
This is v2 of my commit, addressing all issues brought up by @kalaposfos
* Updated C-style casts in kbm_gui.cpp
* Fixed formatting from clang-format
* Updated expendable sections location and changed order of appearance
* Merged PR #3098 into kbm_gui.cpp
* Updates from running clang-format
* Potential MacOS error fix
Changes std::string to std::string_view, which prevented MacOS from building
* Undid MacOS commit for new PR
* Revert "Undid MacOS commit for new PR"
This reverts commit fc376c5e1f
.
* Updated SDL_INVALID_ID=UINT32_MAX macro to SDL_UNMAPPED=UINT32_MAX-1
* Update from merge conflicts
Updated SDL_INVALID_ID=UINT32_MAX macro to SDL_UNMAPPED=UINT32_MAX-1
* FIxed memory.cpp errors from testing PR #3117 (MacOS fixes)
* Removed "kp;"
* Fixed help dialogue from kalaposfos' changes
Fixed 3 edits made by kalaposfos from a recent commit.
---------
Co-authored-by: georgemoralis <giorgosmrls@gmail.com>
This commit is contained in:
parent
7b0249d9ca
commit
8dcd9cc0f9
6 changed files with 585 additions and 630 deletions
|
@ -185,7 +185,7 @@ InputBinding GetBindingFromString(std::string& line) {
|
|||
if (string_to_keyboard_key_map.find(t) != string_to_keyboard_key_map.end()) {
|
||||
input = InputID(InputType::KeyboardMouse, string_to_keyboard_key_map.at(t));
|
||||
} else if (string_to_axis_map.find(t) != string_to_axis_map.end()) {
|
||||
input = InputID(InputType::Axis, (u32)string_to_axis_map.at(t).axis);
|
||||
input = InputID(InputType::Axis, string_to_axis_map.at(t).axis);
|
||||
} else if (string_to_cbutton_map.find(t) != string_to_cbutton_map.end()) {
|
||||
input = InputID(InputType::Controller, string_to_cbutton_map.at(t));
|
||||
} else {
|
||||
|
@ -236,19 +236,15 @@ void ParseInputConfig(const std::string game_id = "") {
|
|||
line.erase(std::remove_if(line.begin(), line.end(),
|
||||
[](unsigned char c) { return std::isspace(c); }),
|
||||
line.end());
|
||||
|
||||
if (line.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Truncate lines starting at #
|
||||
std::size_t comment_pos = line.find('#');
|
||||
if (comment_pos != std::string::npos) {
|
||||
line = line.substr(0, comment_pos);
|
||||
}
|
||||
// Remove trailing semicolon
|
||||
if (!line.empty() && line[line.length() - 1] == ';') {
|
||||
line = line.substr(0, line.length() - 1);
|
||||
}
|
||||
if (line.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
@ -263,8 +259,13 @@ void ParseInputConfig(const std::string game_id = "") {
|
|||
|
||||
std::string output_string = line.substr(0, equal_pos);
|
||||
std::string input_string = line.substr(equal_pos + 1);
|
||||
std::size_t comma_pos = input_string.find(',');
|
||||
// Remove trailing semicolon from input_string
|
||||
if (!input_string.empty() && input_string[input_string.length() - 1] == ';' &&
|
||||
input_string != ";") {
|
||||
line = line.substr(0, line.length() - 1);
|
||||
}
|
||||
|
||||
std::size_t comma_pos = input_string.find(',');
|
||||
auto parseInt = [](const std::string& s) -> std::optional<int> {
|
||||
try {
|
||||
return std::stoi(s);
|
||||
|
@ -382,7 +383,6 @@ void ParseInputConfig(const std::string game_id = "") {
|
|||
BindingConnection connection(InputID(), nullptr);
|
||||
auto button_it = string_to_cbutton_map.find(output_string);
|
||||
auto axis_it = string_to_axis_map.find(output_string);
|
||||
|
||||
if (binding.IsEmpty()) {
|
||||
LOG_WARNING(Input, "Invalid format at line: {}, data: \"{}\", skipping line.",
|
||||
lineCount, line);
|
||||
|
@ -420,7 +420,7 @@ void ParseInputConfig(const std::string game_id = "") {
|
|||
u32 GetMouseWheelEvent(const SDL_Event& event) {
|
||||
if (event.type != SDL_EVENT_MOUSE_WHEEL && event.type != SDL_EVENT_MOUSE_WHEEL_OFF) {
|
||||
LOG_WARNING(Input, "Something went wrong with wheel input parsing!");
|
||||
return (u32)-1;
|
||||
return SDL_UNMAPPED;
|
||||
}
|
||||
if (event.wheel.y > 0) {
|
||||
return SDL_MOUSE_WHEEL_UP;
|
||||
|
@ -431,7 +431,7 @@ u32 GetMouseWheelEvent(const SDL_Event& event) {
|
|||
} else if (event.wheel.x < 0) {
|
||||
return SDL_MOUSE_WHEEL_LEFT;
|
||||
}
|
||||
return (u32)-1;
|
||||
return SDL_UNMAPPED;
|
||||
}
|
||||
|
||||
InputEvent InputBinding::GetInputEventFromSDLEvent(const SDL_Event& e) {
|
||||
|
@ -441,16 +441,19 @@ InputEvent InputBinding::GetInputEventFromSDLEvent(const SDL_Event& e) {
|
|||
return InputEvent(InputType::KeyboardMouse, e.key.key, e.key.down, 0);
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||
return InputEvent(InputType::KeyboardMouse, (u32)e.button.button, e.button.down, 0);
|
||||
return InputEvent(InputType::KeyboardMouse, static_cast<u32>(e.button.button),
|
||||
e.button.down, 0);
|
||||
case SDL_EVENT_MOUSE_WHEEL:
|
||||
case SDL_EVENT_MOUSE_WHEEL_OFF:
|
||||
return InputEvent(InputType::KeyboardMouse, GetMouseWheelEvent(e),
|
||||
e.type == SDL_EVENT_MOUSE_WHEEL, 0);
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_UP:
|
||||
return InputEvent(InputType::Controller, (u32)e.gbutton.button, e.gbutton.down, 0);
|
||||
return InputEvent(InputType::Controller, static_cast<u32>(e.gbutton.button), e.gbutton.down,
|
||||
0); // clang made me do it
|
||||
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
|
||||
return InputEvent(InputType::Axis, (u32)e.gaxis.axis, true, e.gaxis.value / 256);
|
||||
return InputEvent(InputType::Axis, static_cast<u32>(e.gaxis.axis), true,
|
||||
e.gaxis.value / 256); // this too
|
||||
default:
|
||||
return InputEvent();
|
||||
}
|
||||
|
@ -589,7 +592,7 @@ void ControllerOutput::FinalizeUpdate() {
|
|||
bool UpdatePressedKeys(InputEvent event) {
|
||||
// Skip invalid inputs
|
||||
InputID input = event.input;
|
||||
if (input.sdl_id == (u32)-1) {
|
||||
if (input.sdl_id == SDL_UNMAPPED) {
|
||||
return false;
|
||||
}
|
||||
if (input.type == InputType::Axis) {
|
||||
|
|
|
@ -56,7 +56,7 @@ class InputID {
|
|||
public:
|
||||
InputType type;
|
||||
u32 sdl_id;
|
||||
InputID(InputType d = InputType::Count, u32 i = (u32)-1) : type(d), sdl_id(i) {}
|
||||
InputID(InputType d = InputType::Count, u32 i = SDL_UNMAPPED) : type(d), sdl_id(i) {}
|
||||
bool operator==(const InputID& o) const {
|
||||
return type == o.type && sdl_id == o.sdl_id;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ public:
|
|||
return *this != InputID();
|
||||
}
|
||||
std::string ToString() {
|
||||
return fmt::format("({}: {:x})", input_type_names[(u8)type], sdl_id);
|
||||
return fmt::format("({}: {:x})", input_type_names[static_cast<u8>(type)], sdl_id);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -138,6 +138,7 @@ const std::map<std::string, AxisMapping> string_to_axis_map = {
|
|||
{"axis_right_y", {SDL_GAMEPAD_AXIS_RIGHTY, 127}},
|
||||
};
|
||||
const std::map<std::string, u32> string_to_keyboard_key_map = {
|
||||
// alphanumeric
|
||||
{"a", SDLK_A},
|
||||
{"b", SDLK_B},
|
||||
{"c", SDLK_C},
|
||||
|
@ -174,6 +175,73 @@ const std::map<std::string, u32> string_to_keyboard_key_map = {
|
|||
{"7", SDLK_7},
|
||||
{"8", SDLK_8},
|
||||
{"9", SDLK_9},
|
||||
|
||||
// symbols
|
||||
{"`", SDLK_GRAVE},
|
||||
{"~", SDLK_TILDE},
|
||||
{"!", SDLK_EXCLAIM},
|
||||
{"@", SDLK_AT},
|
||||
{"#", SDLK_HASH},
|
||||
{"$", SDLK_DOLLAR},
|
||||
{"%", SDLK_PERCENT},
|
||||
{"^", SDLK_CARET},
|
||||
{"&", SDLK_AMPERSAND},
|
||||
{"*", SDLK_ASTERISK},
|
||||
{"(", SDLK_LEFTPAREN},
|
||||
{")", SDLK_RIGHTPAREN},
|
||||
{"-", SDLK_MINUS},
|
||||
{"_", SDLK_UNDERSCORE},
|
||||
{"=", SDLK_EQUALS},
|
||||
{"+", SDLK_PLUS},
|
||||
{"[", SDLK_LEFTBRACKET},
|
||||
{"]", SDLK_RIGHTBRACKET},
|
||||
{"{", SDLK_LEFTBRACE},
|
||||
{"}", SDLK_RIGHTBRACE},
|
||||
{"\\", SDLK_BACKSLASH},
|
||||
{"|", SDLK_PIPE},
|
||||
{";", SDLK_SEMICOLON},
|
||||
{":", SDLK_COLON},
|
||||
{"'", SDLK_APOSTROPHE},
|
||||
{"\"", SDLK_DBLAPOSTROPHE},
|
||||
{",", SDLK_COMMA},
|
||||
{"<", SDLK_LESS},
|
||||
{".", SDLK_PERIOD},
|
||||
{">", SDLK_GREATER},
|
||||
{"/", SDLK_SLASH},
|
||||
{"?", SDLK_QUESTION},
|
||||
|
||||
// special keys
|
||||
{"escape", SDLK_ESCAPE},
|
||||
{"printscreen", SDLK_PRINTSCREEN},
|
||||
{"scrolllock", SDLK_SCROLLLOCK},
|
||||
{"pausebreak", SDLK_PAUSE},
|
||||
{"backspace", SDLK_BACKSPACE},
|
||||
{"delete", SDLK_DELETE},
|
||||
{"insert", SDLK_INSERT},
|
||||
{"home", SDLK_HOME},
|
||||
{"end", SDLK_END},
|
||||
{"pgup", SDLK_PAGEUP},
|
||||
{"pgdown", SDLK_PAGEDOWN},
|
||||
{"tab", SDLK_TAB},
|
||||
{"capslock", SDLK_CAPSLOCK},
|
||||
{"enter", SDLK_RETURN},
|
||||
{"lshift", SDLK_LSHIFT},
|
||||
{"rshift", SDLK_RSHIFT},
|
||||
{"lctrl", SDLK_LCTRL},
|
||||
{"rctrl", SDLK_RCTRL},
|
||||
{"lalt", SDLK_LALT},
|
||||
{"ralt", SDLK_RALT},
|
||||
{"lmeta", SDLK_LGUI},
|
||||
{"rmeta", SDLK_RGUI},
|
||||
{"lwin", SDLK_LGUI},
|
||||
{"rwin", SDLK_RGUI},
|
||||
{"space", SDLK_SPACE},
|
||||
{"up", SDLK_UP},
|
||||
{"down", SDLK_DOWN},
|
||||
{"left", SDLK_LEFT},
|
||||
{"right", SDLK_RIGHT},
|
||||
|
||||
// keypad
|
||||
{"kp0", SDLK_KP_0},
|
||||
{"kp1", SDLK_KP_1},
|
||||
{"kp2", SDLK_KP_2},
|
||||
|
@ -184,43 +252,16 @@ const std::map<std::string, u32> string_to_keyboard_key_map = {
|
|||
{"kp7", SDLK_KP_7},
|
||||
{"kp8", SDLK_KP_8},
|
||||
{"kp9", SDLK_KP_9},
|
||||
{"comma", SDLK_COMMA},
|
||||
{"period", SDLK_PERIOD},
|
||||
{"question", SDLK_QUESTION},
|
||||
{"semicolon", SDLK_SEMICOLON},
|
||||
{"minus", SDLK_MINUS},
|
||||
{"underscore", SDLK_UNDERSCORE},
|
||||
{"lparenthesis", SDLK_LEFTPAREN},
|
||||
{"rparenthesis", SDLK_RIGHTPAREN},
|
||||
{"lbracket", SDLK_LEFTBRACKET},
|
||||
{"rbracket", SDLK_RIGHTBRACKET},
|
||||
{"lbrace", SDLK_LEFTBRACE},
|
||||
{"rbrace", SDLK_RIGHTBRACE},
|
||||
{"backslash", SDLK_BACKSLASH},
|
||||
{"dash", SDLK_SLASH},
|
||||
{"enter", SDLK_RETURN},
|
||||
{"space", SDLK_SPACE},
|
||||
{"tab", SDLK_TAB},
|
||||
{"backspace", SDLK_BACKSPACE},
|
||||
{"escape", SDLK_ESCAPE},
|
||||
{"left", SDLK_LEFT},
|
||||
{"right", SDLK_RIGHT},
|
||||
{"up", SDLK_UP},
|
||||
{"down", SDLK_DOWN},
|
||||
{"lctrl", SDLK_LCTRL},
|
||||
{"rctrl", SDLK_RCTRL},
|
||||
{"lshift", SDLK_LSHIFT},
|
||||
{"rshift", SDLK_RSHIFT},
|
||||
{"lalt", SDLK_LALT},
|
||||
{"ralt", SDLK_RALT},
|
||||
{"lmeta", SDLK_LGUI},
|
||||
{"rmeta", SDLK_RGUI},
|
||||
{"lwin", SDLK_LGUI},
|
||||
{"rwin", SDLK_RGUI},
|
||||
{"home", SDLK_HOME},
|
||||
{"end", SDLK_END},
|
||||
{"pgup", SDLK_PAGEUP},
|
||||
{"pgdown", SDLK_PAGEDOWN},
|
||||
{"kp.", SDLK_KP_PERIOD},
|
||||
{"kp,", SDLK_KP_COMMA},
|
||||
{"kp/", SDLK_KP_DIVIDE},
|
||||
{"kp*", SDLK_KP_MULTIPLY},
|
||||
{"kp-", SDLK_KP_MINUS},
|
||||
{"kp+", SDLK_KP_PLUS},
|
||||
{"kp=", SDLK_KP_EQUALS},
|
||||
{"kpenter", SDLK_KP_ENTER},
|
||||
|
||||
// mouse
|
||||
{"leftbutton", SDL_BUTTON_LEFT},
|
||||
{"rightbutton", SDL_BUTTON_RIGHT},
|
||||
{"middlebutton", SDL_BUTTON_MIDDLE},
|
||||
|
@ -230,15 +271,8 @@ const std::map<std::string, u32> string_to_keyboard_key_map = {
|
|||
{"mousewheeldown", SDL_MOUSE_WHEEL_DOWN},
|
||||
{"mousewheelleft", SDL_MOUSE_WHEEL_LEFT},
|
||||
{"mousewheelright", SDL_MOUSE_WHEEL_RIGHT},
|
||||
{"kpperiod", SDLK_KP_PERIOD},
|
||||
{"kpcomma", SDLK_KP_COMMA},
|
||||
{"kpdivide", SDLK_KP_DIVIDE},
|
||||
{"kpmultiply", SDLK_KP_MULTIPLY},
|
||||
{"kpminus", SDLK_KP_MINUS},
|
||||
{"kpplus", SDLK_KP_PLUS},
|
||||
{"kpenter", SDLK_KP_ENTER},
|
||||
{"kpequals", SDLK_KP_EQUALS},
|
||||
{"capslock", SDLK_CAPSLOCK},
|
||||
|
||||
// no binding
|
||||
{"unmapped", SDL_UNMAPPED},
|
||||
};
|
||||
|
||||
|
@ -335,6 +369,7 @@ public:
|
|||
// returns an InputEvent based on the event type (keyboard, mouse buttons/wheel, or controller)
|
||||
static InputEvent GetInputEventFromSDLEvent(const SDL_Event& e);
|
||||
};
|
||||
|
||||
class ControllerOutput {
|
||||
static GameController* controller;
|
||||
|
||||
|
|
|
@ -164,198 +164,73 @@ void KBMSettings::EnableMappingButtons() {
|
|||
}
|
||||
}
|
||||
|
||||
void KBMSettings::SaveKBMConfig(bool CloseOnSave) {
|
||||
void KBMSettings::SaveKBMConfig(bool close_on_save) {
|
||||
std::string output_string = "", input_string = "";
|
||||
std::vector<std::string> lines, inputs;
|
||||
|
||||
// Comment lines for config file
|
||||
lines.push_back("#Feeling lost? Check out the Help section!");
|
||||
lines.push_back("");
|
||||
lines.push_back("#Keyboard bindings");
|
||||
lines.push_back("");
|
||||
|
||||
input_string = ui->CrossButton->text().toStdString();
|
||||
output_string = "cross";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->CircleButton->text().toStdString();
|
||||
output_string = "circle";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->TriangleButton->text().toStdString();
|
||||
output_string = "triangle";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->SquareButton->text().toStdString();
|
||||
output_string = "square";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
lines.push_back("");
|
||||
|
||||
input_string = ui->DpadUpButton->text().toStdString();
|
||||
output_string = "pad_up";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->DpadDownButton->text().toStdString();
|
||||
output_string = "pad_down";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->DpadLeftButton->text().toStdString();
|
||||
output_string = "pad_left";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->DpadRightButton->text().toStdString();
|
||||
output_string = "pad_right";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
lines.push_back("");
|
||||
|
||||
input_string = ui->L1Button->text().toStdString();
|
||||
output_string = "l1";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->R1Button->text().toStdString();
|
||||
output_string = "r1";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->L2Button->text().toStdString();
|
||||
output_string = "l2";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->R2Button->text().toStdString();
|
||||
output_string = "r2";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->L3Button->text().toStdString();
|
||||
output_string = "l3";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->R3Button->text().toStdString();
|
||||
output_string = "r3";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
lines.push_back("");
|
||||
|
||||
input_string = ui->OptionsButton->text().toStdString();
|
||||
output_string = "options";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->TouchpadLeftButton->text().toStdString();
|
||||
output_string = "touchpad_left";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->TouchpadCenterButton->text().toStdString();
|
||||
output_string = "touchpad_center";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->TouchpadRightButton->text().toStdString();
|
||||
output_string = "touchpad_right";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
lines.push_back("");
|
||||
|
||||
input_string = ui->LStickUpButton->text().toStdString();
|
||||
output_string = "axis_left_y_minus";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->LStickDownButton->text().toStdString();
|
||||
output_string = "axis_left_y_plus";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->LStickLeftButton->text().toStdString();
|
||||
output_string = "axis_left_x_minus";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->LStickRightButton->text().toStdString();
|
||||
output_string = "axis_left_x_plus";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
lines.push_back("");
|
||||
|
||||
input_string = ui->RStickUpButton->text().toStdString();
|
||||
output_string = "axis_right_y_minus";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->RStickDownButton->text().toStdString();
|
||||
output_string = "axis_right_y_plus";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->RStickLeftButton->text().toStdString();
|
||||
output_string = "axis_right_x_minus";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
input_string = ui->RStickRightButton->text().toStdString();
|
||||
output_string = "axis_right_x_plus";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
|
||||
lines.push_back("");
|
||||
|
||||
input_string = ui->MouseJoystickBox->currentText().toStdString();
|
||||
output_string = "mouse_to_joystick";
|
||||
if (input_string != "unmapped")
|
||||
// Lambda to reduce repetitive code for mapping buttons to config lines
|
||||
auto add_mapping = [&](const QString& buttonText, const std::string& output_name) {
|
||||
input_string = buttonText.toStdString();
|
||||
output_string = output_name;
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped") {
|
||||
inputs.push_back(input_string);
|
||||
}
|
||||
};
|
||||
|
||||
input_string = ui->LHalfButton->text().toStdString();
|
||||
output_string = "leftjoystick_halfmode";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
add_mapping(ui->CrossButton->text(), "cross");
|
||||
add_mapping(ui->CircleButton->text(), "circle");
|
||||
add_mapping(ui->TriangleButton->text(), "triangle");
|
||||
add_mapping(ui->SquareButton->text(), "square");
|
||||
|
||||
input_string = ui->RHalfButton->text().toStdString();
|
||||
output_string = "rightjoystick_halfmode";
|
||||
lines.push_back(output_string + " = " + input_string);
|
||||
if (input_string != "unmapped")
|
||||
inputs.push_back(input_string);
|
||||
lines.push_back("");
|
||||
|
||||
add_mapping(ui->DpadUpButton->text(), "pad_up");
|
||||
add_mapping(ui->DpadDownButton->text(), "pad_down");
|
||||
add_mapping(ui->DpadLeftButton->text(), "pad_left");
|
||||
add_mapping(ui->DpadRightButton->text(), "pad_right");
|
||||
|
||||
lines.push_back("");
|
||||
|
||||
add_mapping(ui->L1Button->text(), "l1");
|
||||
add_mapping(ui->R1Button->text(), "r1");
|
||||
add_mapping(ui->L2Button->text(), "l2");
|
||||
add_mapping(ui->R2Button->text(), "r2");
|
||||
add_mapping(ui->L3Button->text(), "l3");
|
||||
add_mapping(ui->R3Button->text(), "r3");
|
||||
|
||||
lines.push_back("");
|
||||
|
||||
add_mapping(ui->TouchpadLeftButton->text(), "touchpad_left");
|
||||
add_mapping(ui->TouchpadCenterButton->text(), "touchpad_center");
|
||||
add_mapping(ui->TouchpadRightButton->text(), "touchpad_right");
|
||||
add_mapping(ui->OptionsButton->text(), "options");
|
||||
|
||||
lines.push_back("");
|
||||
|
||||
add_mapping(ui->LStickUpButton->text(), "axis_left_y_minus");
|
||||
add_mapping(ui->LStickDownButton->text(), "axis_left_y_plus");
|
||||
add_mapping(ui->LStickLeftButton->text(), "axis_left_x_minus");
|
||||
add_mapping(ui->LStickRightButton->text(), "axis_left_x_plus");
|
||||
|
||||
lines.push_back("");
|
||||
|
||||
add_mapping(ui->RStickUpButton->text(), "axis_right_y_minus");
|
||||
add_mapping(ui->RStickDownButton->text(), "axis_right_y_plus");
|
||||
add_mapping(ui->RStickLeftButton->text(), "axis_right_x_minus");
|
||||
add_mapping(ui->RStickRightButton->text(), "axis_right_x_plus");
|
||||
|
||||
lines.push_back("");
|
||||
|
||||
add_mapping(ui->MouseJoystickBox->currentText(), "mouse_to_joystick");
|
||||
add_mapping(ui->LHalfButton->text(), "leftjoystick_halfmode");
|
||||
add_mapping(ui->RHalfButton->text(), "rightjoystick_halfmode");
|
||||
|
||||
std::string DOString = std::format("{:.2f}", (ui->DeadzoneOffsetSlider->value() / 100.f));
|
||||
std::string SMString = std::format("{:.1f}", (ui->SpeedMultiplierSlider->value() / 10.f));
|
||||
|
@ -405,6 +280,7 @@ void KBMSettings::SaveKBMConfig(bool CloseOnSave) {
|
|||
// Prevent duplicate inputs for KBM as this breaks the 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;
|
||||
|
@ -446,7 +322,7 @@ QString(tr("Cannot bind any unique input more than once. Duplicate inputs mapped
|
|||
Config::SetUseUnifiedInputConfig(!ui->PerGameCheckBox->isChecked());
|
||||
Config::save(Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "config.toml");
|
||||
|
||||
if (CloseOnSave)
|
||||
if (close_on_save)
|
||||
QWidget::close();
|
||||
}
|
||||
|
||||
|
@ -514,7 +390,6 @@ void KBMSettings::SetUIValuestoMappings(std::string config_id) {
|
|||
|
||||
if (std::find(ControllerInputs.begin(), ControllerInputs.end(), input_string) ==
|
||||
ControllerInputs.end()) {
|
||||
|
||||
if (output_string == "cross") {
|
||||
ui->CrossButton->setText(QString::fromStdString(input_string));
|
||||
} else if (output_string == "circle") {
|
||||
|
@ -578,7 +453,7 @@ void KBMSettings::SetUIValuestoMappings(std::string config_id) {
|
|||
if (comma_pos != std::string::npos) {
|
||||
std::string DOstring = line.substr(equal_pos + 1, comma_pos);
|
||||
float DOffsetValue = std::stof(DOstring) * 100.0;
|
||||
int DOffsetInt = int(DOffsetValue);
|
||||
int DOffsetInt = static_cast<int>(DOffsetValue);
|
||||
ui->DeadzoneOffsetSlider->setValue(DOffsetInt);
|
||||
QString LabelValue = QString::number(DOffsetInt / 100.0, 'f', 2);
|
||||
QString LabelString = tr("Deadzone Offset (def 0.50):") + " " + LabelValue;
|
||||
|
@ -588,12 +463,8 @@ void KBMSettings::SetUIValuestoMappings(std::string config_id) {
|
|||
std::size_t comma_pos2 = SMSOstring.find(',');
|
||||
if (comma_pos2 != std::string::npos) {
|
||||
std::string SMstring = SMSOstring.substr(0, comma_pos2);
|
||||
float SpeedMultValue = std::stof(SMstring) * 10.0;
|
||||
int SpeedMultInt = int(SpeedMultValue);
|
||||
if (SpeedMultInt < 1)
|
||||
SpeedMultInt = 1;
|
||||
if (SpeedMultInt > 50)
|
||||
SpeedMultInt = 50;
|
||||
float SpeedMultValue = std::clamp(std::stof(SMstring) * 10.0f, 1.0f, 50.0f);
|
||||
int SpeedMultInt = static_cast<int>(SpeedMultValue);
|
||||
ui->SpeedMultiplierSlider->setValue(SpeedMultInt);
|
||||
LabelValue = QString::number(SpeedMultInt / 10.0, 'f', 1);
|
||||
LabelString = tr("Speed Multiplier (def 1.0):") + " " + LabelValue;
|
||||
|
@ -601,7 +472,7 @@ void KBMSettings::SetUIValuestoMappings(std::string config_id) {
|
|||
|
||||
std::string SOstring = SMSOstring.substr(comma_pos2 + 1);
|
||||
float SOffsetValue = std::stof(SOstring) * 1000.0;
|
||||
int SOffsetInt = int(SOffsetValue);
|
||||
int SOffsetInt = static_cast<int>(SOffsetValue);
|
||||
ui->SpeedOffsetSlider->setValue(SOffsetInt);
|
||||
LabelValue = QString::number(SOffsetInt / 1000.0, 'f', 3);
|
||||
LabelString = tr("Speed Offset (def 0.125):") + " " + LabelValue;
|
||||
|
@ -699,6 +570,16 @@ void KBMSettings::SetMapping(QString input) {
|
|||
MappingCompleted = true;
|
||||
}
|
||||
|
||||
// Helper lambda to get the modified button text based on the current keyboard modifiers
|
||||
auto GetModifiedButton = [](Qt::KeyboardModifiers modifier, const std::string& m_button,
|
||||
const std::string& n_button) -> QString {
|
||||
if (QApplication::keyboardModifiers() & modifier) {
|
||||
return QString::fromStdString(m_button);
|
||||
} else {
|
||||
return QString::fromStdString(n_button);
|
||||
}
|
||||
};
|
||||
|
||||
bool KBMSettings::eventFilter(QObject* obj, QEvent* event) {
|
||||
if (event->type() == QEvent::Close) {
|
||||
if (HelpWindowOpen) {
|
||||
|
@ -719,213 +600,7 @@ bool KBMSettings::eventFilter(QObject* obj, QEvent* event) {
|
|||
}
|
||||
|
||||
switch (keyEvent->key()) {
|
||||
case Qt::Key_Space:
|
||||
pressedKeys.insert("space");
|
||||
break;
|
||||
case Qt::Key_Comma:
|
||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||
pressedKeys.insert("kpcomma");
|
||||
} else {
|
||||
pressedKeys.insert("comma");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Period:
|
||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||
pressedKeys.insert("kpperiod");
|
||||
} else {
|
||||
pressedKeys.insert("period");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Slash:
|
||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers())
|
||||
pressedKeys.insert("kpdivide");
|
||||
break;
|
||||
case Qt::Key_Asterisk:
|
||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers())
|
||||
pressedKeys.insert("kpmultiply");
|
||||
break;
|
||||
case Qt::Key_Question:
|
||||
pressedKeys.insert("question");
|
||||
break;
|
||||
case Qt::Key_Semicolon:
|
||||
pressedKeys.insert("semicolon");
|
||||
break;
|
||||
case Qt::Key_Minus:
|
||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||
pressedKeys.insert("kpminus");
|
||||
} else {
|
||||
pressedKeys.insert("minus");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Plus:
|
||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||
pressedKeys.insert("kpplus");
|
||||
} else {
|
||||
pressedKeys.insert("plus");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_ParenLeft:
|
||||
pressedKeys.insert("lparenthesis");
|
||||
break;
|
||||
case Qt::Key_ParenRight:
|
||||
pressedKeys.insert("rparenthesis");
|
||||
break;
|
||||
case Qt::Key_BracketLeft:
|
||||
pressedKeys.insert("lbracket");
|
||||
break;
|
||||
case Qt::Key_BracketRight:
|
||||
pressedKeys.insert("rbracket");
|
||||
break;
|
||||
case Qt::Key_BraceLeft:
|
||||
pressedKeys.insert("lbrace");
|
||||
break;
|
||||
case Qt::Key_BraceRight:
|
||||
pressedKeys.insert("rbrace");
|
||||
break;
|
||||
case Qt::Key_Backslash:
|
||||
pressedKeys.insert("backslash");
|
||||
break;
|
||||
case Qt::Key_Tab:
|
||||
pressedKeys.insert("tab");
|
||||
break;
|
||||
case Qt::Key_Backspace:
|
||||
pressedKeys.insert("backspace");
|
||||
break;
|
||||
case Qt::Key_Return:
|
||||
pressedKeys.insert("enter");
|
||||
break;
|
||||
case Qt::Key_Enter:
|
||||
pressedKeys.insert("kpenter");
|
||||
break;
|
||||
case Qt::Key_Home:
|
||||
pressedKeys.insert("home");
|
||||
break;
|
||||
case Qt::Key_End:
|
||||
pressedKeys.insert("end");
|
||||
break;
|
||||
case Qt::Key_PageDown:
|
||||
pressedKeys.insert("pgdown");
|
||||
break;
|
||||
case Qt::Key_PageUp:
|
||||
pressedKeys.insert("pgup");
|
||||
break;
|
||||
case Qt::Key_CapsLock:
|
||||
pressedKeys.insert("capslock");
|
||||
break;
|
||||
case Qt::Key_Escape:
|
||||
pressedKeys.insert("unmapped");
|
||||
break;
|
||||
case Qt::Key_Shift:
|
||||
if (keyEvent->nativeScanCode() == rshift) {
|
||||
pressedKeys.insert("rshift");
|
||||
} else {
|
||||
pressedKeys.insert("lshift");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Alt:
|
||||
if (keyEvent->nativeScanCode() == ralt) {
|
||||
pressedKeys.insert("ralt");
|
||||
} else {
|
||||
pressedKeys.insert("lalt");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Control:
|
||||
if (keyEvent->nativeScanCode() == rctrl) {
|
||||
pressedKeys.insert("rctrl");
|
||||
} else {
|
||||
pressedKeys.insert("lctrl");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Meta:
|
||||
activateWindow();
|
||||
#ifdef _WIN32
|
||||
pressedKeys.insert("lwin");
|
||||
#else
|
||||
pressedKeys.insert("lmeta");
|
||||
#endif
|
||||
case Qt::Key_1:
|
||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||
pressedKeys.insert("kp1");
|
||||
} else {
|
||||
pressedKeys.insert("1");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_2:
|
||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||
pressedKeys.insert("kp2");
|
||||
} else {
|
||||
pressedKeys.insert("2");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_3:
|
||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||
pressedKeys.insert("kp3");
|
||||
} else {
|
||||
pressedKeys.insert("3");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_4:
|
||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||
pressedKeys.insert("kp4");
|
||||
} else {
|
||||
pressedKeys.insert("4");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_5:
|
||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||
pressedKeys.insert("kp5");
|
||||
} else {
|
||||
pressedKeys.insert("5");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_6:
|
||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||
pressedKeys.insert("kp6");
|
||||
} else {
|
||||
pressedKeys.insert("6");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_7:
|
||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||
pressedKeys.insert("kp7");
|
||||
} else {
|
||||
pressedKeys.insert("7");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_8:
|
||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||
pressedKeys.insert("kp8");
|
||||
} else {
|
||||
pressedKeys.insert("8");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_9:
|
||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||
pressedKeys.insert("kp9");
|
||||
} else {
|
||||
pressedKeys.insert("9");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_0:
|
||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||
pressedKeys.insert("kp0");
|
||||
} else {
|
||||
pressedKeys.insert("0");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Up:
|
||||
activateWindow();
|
||||
pressedKeys.insert("up");
|
||||
break;
|
||||
case Qt::Key_Down:
|
||||
pressedKeys.insert("down");
|
||||
break;
|
||||
case Qt::Key_Left:
|
||||
pressedKeys.insert("left");
|
||||
break;
|
||||
case Qt::Key_Right:
|
||||
pressedKeys.insert("right");
|
||||
break;
|
||||
// alphanumeric
|
||||
case Qt::Key_A:
|
||||
pressedKeys.insert("a");
|
||||
break;
|
||||
|
@ -999,13 +674,232 @@ bool KBMSettings::eventFilter(QObject* obj, QEvent* event) {
|
|||
pressedKeys.insert("x");
|
||||
break;
|
||||
case Qt::Key_Y:
|
||||
pressedKeys.insert("Y");
|
||||
pressedKeys.insert("y");
|
||||
break;
|
||||
case Qt::Key_Z:
|
||||
pressedKeys.insert("z");
|
||||
break;
|
||||
case Qt::Key_0:
|
||||
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp0", "0"));
|
||||
break;
|
||||
case Qt::Key_1:
|
||||
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp1", "1"));
|
||||
break;
|
||||
case Qt::Key_2:
|
||||
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp2", "2"));
|
||||
break;
|
||||
case Qt::Key_3:
|
||||
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp3", "3"));
|
||||
break;
|
||||
case Qt::Key_4:
|
||||
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp4", "4"));
|
||||
break;
|
||||
case Qt::Key_5:
|
||||
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp5", "5"));
|
||||
break;
|
||||
case Qt::Key_6:
|
||||
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp6", "6"));
|
||||
break;
|
||||
case Qt::Key_7:
|
||||
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp7", "7"));
|
||||
break;
|
||||
case Qt::Key_8:
|
||||
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp8", "8"));
|
||||
break;
|
||||
case Qt::Key_9:
|
||||
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp9", "9"));
|
||||
break;
|
||||
|
||||
// symbols
|
||||
case Qt::Key_Exclam:
|
||||
pressedKeys.insert("!");
|
||||
break;
|
||||
case Qt::Key_At:
|
||||
pressedKeys.insert("@");
|
||||
break;
|
||||
case Qt::Key_NumberSign:
|
||||
pressedKeys.insert("#");
|
||||
break;
|
||||
case Qt::Key_Dollar:
|
||||
pressedKeys.insert("$");
|
||||
break;
|
||||
case Qt::Key_Percent:
|
||||
pressedKeys.insert("%");
|
||||
break;
|
||||
case Qt::Key_AsciiCircum:
|
||||
pressedKeys.insert("^");
|
||||
break;
|
||||
case Qt::Key_Ampersand:
|
||||
pressedKeys.insert("&");
|
||||
break;
|
||||
case Qt::Key_Asterisk:
|
||||
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp*", "*"));
|
||||
break;
|
||||
case Qt::Key_ParenLeft:
|
||||
pressedKeys.insert("(");
|
||||
break;
|
||||
case Qt::Key_ParenRight:
|
||||
pressedKeys.insert(")");
|
||||
break;
|
||||
case Qt::Key_Minus:
|
||||
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp-", "-"));
|
||||
break;
|
||||
case Qt::Key_Underscore:
|
||||
pressedKeys.insert("_");
|
||||
break;
|
||||
case Qt::Key_Equal:
|
||||
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp=", "="));
|
||||
break;
|
||||
case Qt::Key_Plus:
|
||||
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp+", "+"));
|
||||
break;
|
||||
case Qt::Key_BracketLeft:
|
||||
pressedKeys.insert("[");
|
||||
break;
|
||||
case Qt::Key_BracketRight:
|
||||
pressedKeys.insert("]");
|
||||
break;
|
||||
case Qt::Key_BraceLeft:
|
||||
pressedKeys.insert("{");
|
||||
break;
|
||||
case Qt::Key_BraceRight:
|
||||
pressedKeys.insert("}");
|
||||
break;
|
||||
case Qt::Key_Backslash:
|
||||
pressedKeys.insert("\\");
|
||||
break;
|
||||
case Qt::Key_Bar:
|
||||
pressedKeys.insert("|");
|
||||
break;
|
||||
case Qt::Key_Semicolon:
|
||||
pressedKeys.insert(";");
|
||||
break;
|
||||
case Qt::Key_Colon:
|
||||
pressedKeys.insert(":");
|
||||
break;
|
||||
case Qt::Key_Apostrophe:
|
||||
pressedKeys.insert("'");
|
||||
break;
|
||||
case Qt::Key_QuoteDbl:
|
||||
pressedKeys.insert("\"");
|
||||
break;
|
||||
case Qt::Key_Comma:
|
||||
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp,", ","));
|
||||
break;
|
||||
case Qt::Key_Less:
|
||||
pressedKeys.insert("<");
|
||||
break;
|
||||
case Qt::Key_Period:
|
||||
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp.", "."));
|
||||
break;
|
||||
case Qt::Key_Greater:
|
||||
pressedKeys.insert(">");
|
||||
break;
|
||||
case Qt::Key_Slash:
|
||||
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp/", "/"));
|
||||
break;
|
||||
case Qt::Key_Question:
|
||||
pressedKeys.insert("question");
|
||||
break;
|
||||
|
||||
// special keys
|
||||
case Qt::Key_Print:
|
||||
pressedKeys.insert("printscreen");
|
||||
break;
|
||||
case Qt::Key_ScrollLock:
|
||||
pressedKeys.insert("scrolllock");
|
||||
break;
|
||||
case Qt::Key_Pause:
|
||||
pressedKeys.insert("pausebreak");
|
||||
break;
|
||||
case Qt::Key_Backspace:
|
||||
pressedKeys.insert("backspace");
|
||||
break;
|
||||
case Qt::Key_Insert:
|
||||
pressedKeys.insert("insert");
|
||||
break;
|
||||
case Qt::Key_Delete:
|
||||
pressedKeys.insert("delete");
|
||||
break;
|
||||
case Qt::Key_Home:
|
||||
pressedKeys.insert("home");
|
||||
break;
|
||||
case Qt::Key_End:
|
||||
pressedKeys.insert("end");
|
||||
break;
|
||||
case Qt::Key_PageUp:
|
||||
pressedKeys.insert("pgup");
|
||||
break;
|
||||
case Qt::Key_PageDown:
|
||||
pressedKeys.insert("pgdown");
|
||||
break;
|
||||
case Qt::Key_Tab:
|
||||
pressedKeys.insert("tab");
|
||||
break;
|
||||
case Qt::Key_CapsLock:
|
||||
pressedKeys.insert("capslock");
|
||||
break;
|
||||
case Qt::Key_Return:
|
||||
pressedKeys.insert("enter");
|
||||
break;
|
||||
case Qt::Key_Enter:
|
||||
pressedKeys.insert(GetModifiedButton(Qt::ShiftModifier, "kpenter", "enter"));
|
||||
break;
|
||||
case Qt::Key_Shift:
|
||||
if (keyEvent->nativeScanCode() == LSHIFT_KEY) {
|
||||
pressedKeys.insert("lshift");
|
||||
} else {
|
||||
pressedKeys.insert("rshift");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Alt:
|
||||
if (keyEvent->nativeScanCode() == LALT_KEY) {
|
||||
pressedKeys.insert("lalt");
|
||||
} else {
|
||||
pressedKeys.insert("ralt");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Control:
|
||||
if (keyEvent->nativeScanCode() == LCTRL_KEY) {
|
||||
pressedKeys.insert("lctrl");
|
||||
} else {
|
||||
pressedKeys.insert("rctrl");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Meta:
|
||||
activateWindow();
|
||||
#ifdef _WIN32
|
||||
pressedKeys.insert("lwin");
|
||||
#else
|
||||
pressedKeys.insert("lmeta");
|
||||
#endif
|
||||
break;
|
||||
case Qt::Key_Space:
|
||||
pressedKeys.insert("space");
|
||||
break;
|
||||
case Qt::Key_Up:
|
||||
activateWindow();
|
||||
pressedKeys.insert("up");
|
||||
break;
|
||||
case Qt::Key_Down:
|
||||
pressedKeys.insert("down");
|
||||
break;
|
||||
case Qt::Key_Left:
|
||||
pressedKeys.insert("left");
|
||||
break;
|
||||
case Qt::Key_Right:
|
||||
pressedKeys.insert("right");
|
||||
break;
|
||||
|
||||
// cancel mapping
|
||||
case Qt::Key_Escape:
|
||||
pressedKeys.insert("unmapped");
|
||||
break;
|
||||
|
||||
// default case
|
||||
default:
|
||||
break;
|
||||
// bottom text
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1024,8 +918,17 @@ bool KBMSettings::eventFilter(QObject* obj, QEvent* event) {
|
|||
case Qt::MiddleButton:
|
||||
pressedKeys.insert("middlebutton");
|
||||
break;
|
||||
case Qt::XButton1:
|
||||
pressedKeys.insert("sidebuttonback");
|
||||
break;
|
||||
case Qt::XButton2:
|
||||
pressedKeys.insert("sidebuttonforward");
|
||||
break;
|
||||
|
||||
// default case
|
||||
default:
|
||||
break;
|
||||
// bottom text
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1056,22 +959,16 @@ bool KBMSettings::eventFilter(QObject* obj, QEvent* event) {
|
|||
if (wheelEvent->angleDelta().x() > 5) {
|
||||
if (std::find(AxisList.begin(), AxisList.end(), MappingButton) == AxisList.end()) {
|
||||
// QT changes scrolling to horizontal for all widgets with the alt modifier
|
||||
if (Qt::AltModifier & QApplication::keyboardModifiers()) {
|
||||
pressedKeys.insert("mousewheelup");
|
||||
} else {
|
||||
pressedKeys.insert("mousewheelright");
|
||||
}
|
||||
pressedKeys.insert(
|
||||
GetModifiedButton(Qt::AltModifier, "mousewheelup", "mousewheelright"));
|
||||
} else {
|
||||
QMessageBox::information(this, tr("Cannot set mapping"),
|
||||
tr("Mousewheel cannot be mapped to stick outputs"));
|
||||
}
|
||||
} else if (wheelEvent->angleDelta().x() < -5) {
|
||||
if (std::find(AxisList.begin(), AxisList.end(), MappingButton) == AxisList.end()) {
|
||||
if (Qt::AltModifier & QApplication::keyboardModifiers()) {
|
||||
pressedKeys.insert("mousewheeldown");
|
||||
} else {
|
||||
pressedKeys.insert("mousewheelleft");
|
||||
}
|
||||
pressedKeys.insert(
|
||||
GetModifiedButton(Qt::AltModifier, "mousewheeldown", "mousewheelleft"));
|
||||
} else {
|
||||
QMessageBox::information(this, tr("Cannot set mapping"),
|
||||
tr("Mousewheel cannot be mapped to stick outputs"));
|
||||
|
@ -1083,4 +980,4 @@ bool KBMSettings::eventFilter(QObject* obj, QEvent* event) {
|
|||
return QDialog::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
KBMSettings::~KBMSettings() {}
|
||||
KBMSettings::~KBMSettings() {}
|
|
@ -4,6 +4,18 @@
|
|||
#include <QDialog>
|
||||
#include "game_info.h"
|
||||
|
||||
// macros > declaring constants
|
||||
// also, we were only using one counterpart
|
||||
#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 KBMSettings;
|
||||
}
|
||||
|
@ -25,22 +37,6 @@ private:
|
|||
std::unique_ptr<Ui::KBMSettings> ui;
|
||||
std::shared_ptr<GameInfoClass> m_game_info;
|
||||
|
||||
#ifdef _WIN32
|
||||
const int lctrl = 29;
|
||||
const int rctrl = 57373;
|
||||
const int lalt = 56;
|
||||
const int ralt = 57400;
|
||||
const int lshift = 42;
|
||||
const int rshift = 54;
|
||||
#else
|
||||
const int lctrl = 37;
|
||||
const int rctrl = 105;
|
||||
const int lalt = 64;
|
||||
const int ralt = 108;
|
||||
const int lshift = 50;
|
||||
const int rshift = 62;
|
||||
#endif
|
||||
|
||||
bool eventFilter(QObject* obj, QEvent* event) override;
|
||||
void ButtonConnects();
|
||||
void SetUIValuestoMappings(std::string config_id);
|
||||
|
|
|
@ -78,16 +78,16 @@ HelpDialog::HelpDialog(bool* open_flag, QWidget* parent) : QDialog(parent) {
|
|||
|
||||
// Add expandable sections to container layout
|
||||
auto* quickstartSection = new ExpandableSection(tr("Quickstart"), quickstart());
|
||||
auto* faqSection = new ExpandableSection(tr("FAQ"), faq());
|
||||
auto* syntaxSection = new ExpandableSection(tr("Syntax"), syntax());
|
||||
auto* specialSection = new ExpandableSection(tr("Special Bindings"), special());
|
||||
auto* bindingsSection = new ExpandableSection(tr("Keybindings"), bindings());
|
||||
auto* specialSection = new ExpandableSection(tr("Special Bindings"), special());
|
||||
auto* faqSection = new ExpandableSection(tr("FAQ"), faq());
|
||||
|
||||
containerLayout->addWidget(quickstartSection);
|
||||
containerLayout->addWidget(faqSection);
|
||||
containerLayout->addWidget(syntaxSection);
|
||||
containerLayout->addWidget(specialSection);
|
||||
containerLayout->addWidget(bindingsSection);
|
||||
containerLayout->addWidget(specialSection);
|
||||
containerLayout->addWidget(faqSection);
|
||||
containerLayout->addStretch(1);
|
||||
|
||||
// Scroll area wrapping the container
|
||||
|
@ -110,3 +110,160 @@ HelpDialog::HelpDialog(bool* open_flag, QWidget* parent) : QDialog(parent) {
|
|||
connect(specialSection, &ExpandableSection::expandedChanged, this, &HelpDialog::adjustSize);
|
||||
connect(bindingsSection, &ExpandableSection::expandedChanged, this, &HelpDialog::adjustSize);
|
||||
}
|
||||
|
||||
// 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::faq() {
|
||||
return R"(
|
||||
Q: What are the emulator-wide keybinds?
|
||||
A:
|
||||
-F12: Triggers Renderdoc capture
|
||||
-F11: Toggles fullscreen
|
||||
-F10: Toggles FPS counter
|
||||
-Ctrl+F10: Open the debug menu
|
||||
-F9: Pauses the emulator if the debug menu is open
|
||||
-F8: Reparses the config file while in-game
|
||||
-F7: Toggles mouse capture and mouse input
|
||||
-F6: Toggles mouse-to-gyro emulation
|
||||
|
||||
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.
|
||||
|
||||
Q: What happens if I accidentally make a typo in the config?
|
||||
A: The code recognises the line as wrong and skips it, so the rest of the file will get parsed, but that line in question will be treated like a comment line. You can find these lines in the log if you search for 'input_handler'.
|
||||
|
||||
Q: I want to bind <input> to <output>, but your code doesn't support <input>!
|
||||
A: Some keys are intentionally omitted, but if you read the bindings through, and you're sure it is not there and isn't one of the intentionally disabled ones, open an issue on https://github.com/shadps4-emu/shadPS4.
|
||||
|
||||
Q: What does default.ini do?
|
||||
A: If you're using per-game configs, it's the base from which all new games generate their config file. If you use the unified config, then default.ini is used for every game directly instead.
|
||||
|
||||
Q: What does the use Per-game Config checkbox do?
|
||||
A: It controls whether the config is loaded from CUSAXXXXX.ini for a game or from default.ini. This way, if you only want to manage one set of bindings, you can do so, but if you want to use a different setup for every game, that's possible as well.)";
|
||||
}
|
||||
|
||||
QString HelpDialog::syntax() {
|
||||
return R"(
|
||||
Below is the file format for mouse, keyboard, and controller inputs:
|
||||
|
||||
Rules:
|
||||
- You can bind up to 3 inputs to one button.
|
||||
- Adding '#' at the beginning of a line creates a comment.
|
||||
- Extra whitespace doesn't affect input.
|
||||
<output>=<input>; is just as valid as <output> = <input>;
|
||||
- ';' at the end of a line is also optional.
|
||||
|
||||
Syntax (aka how a line can look like):
|
||||
#Comment line
|
||||
<controller_button> = <input>, <input>, <input>;
|
||||
<controller_button> = <input>, <input>;
|
||||
<controller_button> = <input>;
|
||||
|
||||
Examples:
|
||||
#Interact
|
||||
cross = e;
|
||||
#Heavy attack (in BB)
|
||||
r2 = leftbutton, lshift;
|
||||
#Move forward
|
||||
axis_left_y_minus = w;)";
|
||||
}
|
||||
|
||||
QString HelpDialog::bindings() {
|
||||
return R"(
|
||||
The following names should be interpreted without the '' around them. For inputs that have left and right versions, only the left one is shown, but the right version also works.
|
||||
(Example: 'lshift', 'rshift')
|
||||
|
||||
Keyboard:
|
||||
Alphabet:
|
||||
'a', 'b', ..., 'z'
|
||||
Numbers:
|
||||
'0', '1', ..., '9'
|
||||
Keypad:
|
||||
'kp 0', 'kp 1', ..., 'kp 9',
|
||||
'kp .', 'kp ,', 'kp /', 'kp *', 'kp -', 'kp +', 'kp =', 'kp enter'
|
||||
Symbols:
|
||||
'`', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '_', '=', '+', '{', '}', '[', ']', '\', '|',
|
||||
';', ':', ''', '"', ',', '<', '.', '>', '/', '?'
|
||||
Special keys:
|
||||
'escape (text editor only)', 'printscreen', 'scrolllock', 'pausebreak',
|
||||
'backspace', 'insert', 'delete', 'home', 'end', 'pgup', 'pgdown', 'tab',
|
||||
'capslock', 'enter', 'space'
|
||||
Arrow keys:
|
||||
'up', 'down', 'left', 'right'
|
||||
Modifier keys:
|
||||
'lctrl', 'lshift', 'lalt', 'lwin' = 'lmeta' (same input, different names, so if you are not on Windows and don't like calling this the Windows key, there is an alternative)
|
||||
|
||||
Mouse:
|
||||
'leftbutton', 'rightbutton', 'middlebutton', 'sidebuttonforward',
|
||||
'sidebuttonback'
|
||||
The following wheel inputs cannot be bound to axis input, only button:
|
||||
'mousewheelup', 'mousewheeldown', 'mousewheelleft',
|
||||
'mousewheelright'
|
||||
|
||||
Controller:
|
||||
The touchpad currently can't be rebound to anything else, but you can bind buttons to it.
|
||||
If you have a controller that has different names for buttons, it will still work. Just look up the equivalent names for that controller.
|
||||
The same left-right rule still applies here.
|
||||
Buttons:
|
||||
'triangle', 'circle', 'cross', 'square', 'l1', 'l3',
|
||||
'options', touchpad', 'up', 'down', 'left', 'right'
|
||||
Input-only:
|
||||
'lpaddle_low', 'lpaddle_high'
|
||||
Output-only:
|
||||
'touchpad_left', 'touchpad_center', 'touchpad_right'
|
||||
Axes if you bind them to a button input:
|
||||
'axis_left_x_plus', 'axis_left_x_minus', 'axis_left_y_plus', 'axis_left_y_minus',
|
||||
'axis_right_x_plus', ..., 'axis_right_y_minus',
|
||||
'l2'
|
||||
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.)";
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
'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.
|
||||
|
||||
'mouse_to_joystick' = 'none', 'left' or 'right';
|
||||
This binds the mouse movement to either joystick. If it receives a value that is not 'left' or 'right', it defaults to 'none'.
|
||||
|
||||
'mouse_movement_params' = float, float, float;
|
||||
(If you don't know what a float is, it is a data type that stores decimal numbers.)
|
||||
Default values: 0.5, 1, 0.125
|
||||
Let's break each parameter down:
|
||||
1st: 'mouse_deadzone_offset' should have a value between 0 and 1 (it gets clamped to that range anyway), with 0 being no offset and 1 being pushing the joystick to the max in the direction the mouse moved.
|
||||
This controls the minimum distance the joystick gets moved when moving the mouse. If set to 0, it will emulate raw mouse input, which doesn't work very well due to deadzones preventing input if the movement is not large enough.
|
||||
2nd: 'mouse_speed' is just a standard multiplier to the mouse input speed.
|
||||
If you input a negative number, the axis directions get reversed. Keep in mind that the offset can still push it back to positive if it's big enough.
|
||||
3rd: 'mouse_speed_offset' should be in the 0 to 1 range, with 0 being no offset and 1 being offsetting to the max possible value.
|
||||
Let's set 'mouse_deadzone_offset' to 0.5, and 'mouse_speed_offset' to 0: This means that if we move the mouse very slowly, it still inputs a half-strength joystick input, and if we increase the speed, it would stay that way until we move faster than half the max speed. If we instead set this to 0.25, we now only need to move the mouse faster than the 0.5-0.25=0.25=quarter of the max speed, to get an increase in joystick speed. If we set it to 0.5, then even moving the mouse at 1 pixel per frame will result in a faster-than-minimum speed.
|
||||
|
||||
'key_toggle' = <key>, <key_to_toggle>;
|
||||
This assigns a key to another key, and if pressed, toggles that key's virtual value. If it's on, then it doesn't matter if the key is pressed or not, the input handler will treat it as if it's pressed.
|
||||
Let's say we want to be able to toggle 'l1' with 't'. You can then bind 'l1' to a key you won't use, like 'kpenter'. Then bind 't' to toggle that. You will end up with this:
|
||||
l1 = kpenter;
|
||||
key_toggle = t, kpenter;
|
||||
|
||||
'analog_deadzone' = <device>, <value>, <value>;
|
||||
This sets the deadzone range for various inputs. The first value is the minimum deadzone while the second is the maximum. Values go from 1 to 127 (no deadzone to max deadzone).
|
||||
If you only want a minimum or maximum deadzone, set the other value to 1 or 127 respectively.
|
||||
Valid devices: 'leftjoystick', 'rightjoystick', 'l2', 'r2'
|
||||
|
||||
'mouse_gyro_roll_mode':
|
||||
Controls whether moving the mouse sideways causes a panning or a rolling motion while mouse-to-gyro emulation is active.)";
|
||||
}
|
||||
|
|
|
@ -42,142 +42,9 @@ protected:
|
|||
private:
|
||||
bool* help_open_ptr;
|
||||
|
||||
QString 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, its features and help on 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 started out because I didn't like the original unchangeable keybinds, but 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 ovbiously you can make adjustments however you like.
|
||||
)";
|
||||
}
|
||||
QString faq() {
|
||||
return
|
||||
R"(Q: What are the emulator-wide keybinds?
|
||||
A: -F12: Triggers Renderdoc capture
|
||||
-F11: Toggles fullscreen
|
||||
-F10: Toggles FPS counter
|
||||
-Ctrl F10: Open the debug menu
|
||||
-F9: Pauses emultor, if the debug menu is open
|
||||
-F8: Reparses the config file while in-game
|
||||
-F7: Toggles mouse-to-joystick emulation
|
||||
-F6: Toggles mouse-to-gyro emulation
|
||||
|
||||
Q: How do I change between mouse and controller joystick input, and why is it even required?
|
||||
A: You can switch between them with F7, and it is required, because mouse input is done with polling, which means mouse movement is checked every frame, and if it didn't move, the code manually sets the emulator's virtual controller to 0 (back to the center), even if other input devices would update it.
|
||||
|
||||
Q: What happens if I accidentally make a typo in the config?
|
||||
A: The code recognises the line as wrong, and skip it, so the rest of the file will get parsed, but that line in question will be treated like a comment line. You can find these lines in the log, if you search for 'input_handler'.
|
||||
|
||||
Q: I want to bind <input> to <output>, but your code doesn't support <input>!
|
||||
A: Some keys are intentionally omitted, but if you read the bindings through, and you're sure it is not there and isn't one of the intentionally disabled ones, open an issue on https://github.com/shadps4-emu/shadPS4.
|
||||
|
||||
Q: What does default.ini do?
|
||||
A: If you're using per-game configs, it's the base from which all new games generate their config file. If you use the unified config, then this is used for every game directly instead.
|
||||
|
||||
Q: What does the use Per-game Config checkbox do?
|
||||
A: It controls whether the config is loaded from CUSAXXXXX.ini for a game, or from default.ini. This way, if you only want to manage one set of bindings, you can do so, but if you want to use a different setup for every game, that's possible as well.
|
||||
)";
|
||||
}
|
||||
QString syntax() {
|
||||
return
|
||||
R"(This is the full list of currently supported mouse, keyboard and controller inputs, and how to use them.
|
||||
Emulator-reserved keys: F1 through F12
|
||||
|
||||
Syntax (aka how a line can look like):
|
||||
#Comment line
|
||||
<controller_button> = <input>, <input>, <input>;
|
||||
<controller_button> = <input>, <input>;
|
||||
<controller_button> = <input>;
|
||||
|
||||
Examples:
|
||||
#Interact
|
||||
cross = e;
|
||||
#Heavy attack (in BB)
|
||||
r2 = leftbutton, lshift;
|
||||
#Move forward
|
||||
axis_left_y_minus = w;
|
||||
|
||||
You can make a comment line by putting # as the first character.
|
||||
Whitespace doesn't matter, <output>=<input>; is just as valid as <output> = <input>;
|
||||
';' at the ends of lines is also optional.
|
||||
)";
|
||||
}
|
||||
QString bindings() {
|
||||
return
|
||||
R"(The following names should be interpreted without the '' around them, and for inputs that have left and right versions, only the left one is shown, but the right can be inferred from that.
|
||||
Example: 'lshift', 'rshift'
|
||||
|
||||
Keyboard:
|
||||
Alphabet: 'a', 'b', ..., 'z'
|
||||
Numbers: '0', '1', ..., '9'
|
||||
Keypad: 'kp0', kp1', ..., 'kp9', 'kpperiod', 'kpcomma',
|
||||
'kpdivide', 'kpmultiply', 'kpdivide', 'kpplus', 'kpminus', 'kpenter'
|
||||
Punctuation and misc:
|
||||
'space', 'comma', 'period', 'question', 'semicolon', 'minus', 'plus', 'lparenthesis', 'lbracket', 'lbrace', 'backslash', 'dash',
|
||||
'enter', 'tab', backspace', 'escape'
|
||||
Arrow keys: 'up', 'down', 'left', 'right'
|
||||
Modifier keys:
|
||||
'lctrl', 'lshift', 'lalt', 'lwin' = 'lmeta' (same input, different names, so if you are not on Windows and don't like calling this the Windows key, there is an alternative)
|
||||
|
||||
Mouse:
|
||||
'leftbutton', 'rightbutton', 'middlebutton', 'sidebuttonforward', 'sidebuttonback'
|
||||
The following wheel inputs cannot be bound to axis input, only button:
|
||||
'mousewheelup', 'mousewheeldown', 'mousewheelleft', 'mousewheelright'
|
||||
|
||||
Controller:
|
||||
The touchpad currently can't be rebound to anything else, but you can bind buttons to it.
|
||||
If you have a controller that has different names for buttons, it will still work, just look up what are the equivalent names for that controller
|
||||
The same left-right rule still applies here.
|
||||
Buttons:
|
||||
'triangle', 'circle', 'cross', 'square', 'l1', 'l3',
|
||||
'options', touchpad', 'up', 'down', 'left', 'right'
|
||||
Input-only:
|
||||
'lpaddle_low', 'lpaddle_high'
|
||||
Output-only:
|
||||
'touchpad_left', 'touchpad_center', 'touchpad_right'
|
||||
Axes if you bind them to a button input:
|
||||
'axis_left_x_plus', 'axis_left_x_minus', 'axis_left_y_plus', 'axis_left_y_minus',
|
||||
'axis_right_x_plus', ..., 'axis_right_y_minus',
|
||||
'l2'
|
||||
Axes if you bind them to another axis input:
|
||||
'axis_left_x' 'axis_left_y' 'axis_right_x' 'axis_right_y',
|
||||
'l2'
|
||||
)";
|
||||
}
|
||||
QString special() {
|
||||
return
|
||||
R"(There are some extra bindings you can put into the config file, that don't correspond to a controller input, but rather something else.
|
||||
You can find these here, with detailed comments, examples and suggestions for most of them.
|
||||
|
||||
'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.
|
||||
|
||||
'mouse_to_joystick' = 'none', 'left' or 'right';
|
||||
This binds the mouse movement to either joystick. If it recieves a value that is not 'left' or 'right', it defaults to 'none'.
|
||||
|
||||
'mouse_movement_params' = float, float, float;
|
||||
(If you don't know what a float is, it is a data type that stores non-whole numbers.)
|
||||
Default values: 0.5, 1, 0.125
|
||||
Let's break each parameter down:
|
||||
1st: mouse_deadzone_offset: this value should have a value between 0 and 1 (It gets clamped to that range anyway), with 0 being no offset and 1 being pushing the joystick to the max in the direction the mouse moved.
|
||||
This controls the minimum distance the joystick gets moved, when moving the mouse. If set to 0, it will emulate raw mouse input, which doesn't work very well due to deadzones preventing input if the movement is not large enough.
|
||||
2nd: mouse_speed: It's just a standard multiplier to the mouse input speed.
|
||||
If you input a negative number, the axis directions get reversed (Keep in mind that the offset can still push it back to positive, if it's big enough)
|
||||
3rd: mouse_speed_offset: This also should be in the 0 to 1 range, with 0 being no offset and 1 being offsetting to the max possible value.
|
||||
This is best explained through an example: Let's set mouse_deadzone to 0.5, and this to 0: This means that if we move the mousevery slowly, it still inputs a half-strength joystick input, and if we increase the speed, it would stay that way until we move faster than half the max speed. If we instead set this to 0.25, we now only need to move the mouse faster than the 0.5-0.25=0.25=quarter of the max speed, to get an increase in joystick speed. If we set it to 0.5, then even moving the mouse at 1 pixel per frame will result in a faster-than-minimum speed.
|
||||
|
||||
'key_toggle' = <key>, <key_to_toggle>;
|
||||
This assigns a key to another key, and if pressed, toggles that key's virtual value. If it's on, then it doesn't matter if the key is pressed or not, the input handler will treat it as if it's pressed.
|
||||
You can make an input toggleable with this, for example: Let's say we want to be able to toggle l1 with t. You can then bind l1 to a key you won't use, like kpenter, then bind t to toggle that, so you will end up with this:
|
||||
l1 = kpenter;
|
||||
key_toggle = t, kpenter;
|
||||
'analog_deadzone' = <device>, <value>, <value>;
|
||||
Values go from 1 to 127 (no deadzone to max deadzone), first is the inner, second is the outer deadzone
|
||||
If you only want inner or outer deadzone, set the other to 1 or 127, respectively
|
||||
Devices: leftjoystick, rightjoystick, l2, r2
|
||||
'mouse_gyro_roll_mode':
|
||||
Controls whether moving the mouse sideways causes a panning or a rolling motion while mouse-to-gyro emulation is active.
|
||||
)";
|
||||
}
|
||||
QString quickstart();
|
||||
QString faq();
|
||||
QString syntax();
|
||||
QString bindings();
|
||||
QString special();
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue