mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 08:22:32 +00:00
added support for loading keyboard config from file
This commit is contained in:
parent
b412cb4cca
commit
81e0f143cc
@ -20,8 +20,328 @@
|
|||||||
|
|
||||||
namespace Frontend {
|
namespace Frontend {
|
||||||
|
|
||||||
WindowSDL::WindowSDL(s32 width_, s32 height_, Input::GameController* controller_,
|
bool KeyBinding::operator<(const KeyBinding& other) const {
|
||||||
std::string_view window_title)
|
return std::tie(key, modifier) < std::tie(other.key, other.modifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
// modifiers are bitwise or-d together, so we need to check if ours is in that
|
||||||
|
template<typename T>
|
||||||
|
typename std::map<KeyBinding, T>::const_iterator FindKeyAllowingPartialModifiers(const std::map<KeyBinding, T>& map, KeyBinding binding) {
|
||||||
|
for (typename std::map<KeyBinding, T>::const_iterator it = map.cbegin(); it != map.cend(); it++) {
|
||||||
|
if ((it->first.key == binding.key) && (it->first.modifier & binding.modifier) != 0) {
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map.end(); // Return end if no match is found
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
typename std::map<KeyBinding, T>::const_iterator FindKeyAllowingOnlyNoModifiers(const std::map<KeyBinding, T>& map, KeyBinding binding) {
|
||||||
|
for (typename std::map<KeyBinding, T>::const_iterator it = map.cbegin(); it != map.cend(); it++) {
|
||||||
|
if (it->first.key == binding.key && it->first.modifier == SDL_KMOD_NONE) {
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map.end(); // Return end if no match is found
|
||||||
|
}
|
||||||
|
|
||||||
|
// Axis map: maps key+modifier to controller axis and axis value
|
||||||
|
struct AxisMapping {
|
||||||
|
Input::Axis axis;
|
||||||
|
int value; // Value to set for key press (+127 or -127 for movement)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// i strongly suggest you collapse these maps
|
||||||
|
std::map<std::string, u32> string_to_cbutton_map = {
|
||||||
|
{"triangle", OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TRIANGLE},
|
||||||
|
{"circle", OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_CIRCLE},
|
||||||
|
{"cross", OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_CROSS},
|
||||||
|
{"square", OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_SQUARE},
|
||||||
|
{"l1", OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L1},
|
||||||
|
{"l2", OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L2},
|
||||||
|
{"r1", OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R1},
|
||||||
|
{"r2", OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R2},
|
||||||
|
{"l3", OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L3},
|
||||||
|
{"r3", OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R3},
|
||||||
|
{"options", OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_OPTIONS},
|
||||||
|
{"touchpad", OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TOUCH_PAD},
|
||||||
|
{"up", OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_UP},
|
||||||
|
{"down", OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_DOWN},
|
||||||
|
{"left", OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_LEFT},
|
||||||
|
{"right", OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_RIGHT}
|
||||||
|
};
|
||||||
|
std::map<std::string, AxisMapping> string_to_axis_map = {
|
||||||
|
{"axis_left_x_plus", {Input::Axis::LeftX, 127}},
|
||||||
|
{"axis_left_x_minus", {Input::Axis::LeftX, -127}},
|
||||||
|
{"axis_left_y_plus", {Input::Axis::LeftY, 127}},
|
||||||
|
{"axis_left_y_minus", {Input::Axis::LeftY, -127}},
|
||||||
|
{"axis_right_x_plus", {Input::Axis::RightX, 127}},
|
||||||
|
{"axis_right_x_minus", {Input::Axis::RightX, -127}},
|
||||||
|
{"axis_right_y_plus", {Input::Axis::RightY, 127}},
|
||||||
|
{"axis_right_y_minus", {Input::Axis::RightY, -127}},
|
||||||
|
};
|
||||||
|
std::map<std::string, u32> string_to_keyboard_key_map = {
|
||||||
|
{"a", SDLK_A},
|
||||||
|
{"b", SDLK_B},
|
||||||
|
{"c", SDLK_C},
|
||||||
|
{"d", SDLK_D},
|
||||||
|
{"e", SDLK_E},
|
||||||
|
{"f", SDLK_F},
|
||||||
|
{"g", SDLK_G},
|
||||||
|
{"h", SDLK_H},
|
||||||
|
{"i", SDLK_I},
|
||||||
|
{"j", SDLK_J},
|
||||||
|
{"k", SDLK_K},
|
||||||
|
{"l", SDLK_L},
|
||||||
|
{"m", SDLK_M},
|
||||||
|
{"n", SDLK_N},
|
||||||
|
{"o", SDLK_O},
|
||||||
|
{"p", SDLK_P},
|
||||||
|
{"q", SDLK_Q},
|
||||||
|
{"r", SDLK_R},
|
||||||
|
{"s", SDLK_S},
|
||||||
|
{"t", SDLK_T},
|
||||||
|
{"u", SDLK_U},
|
||||||
|
{"v", SDLK_V},
|
||||||
|
{"w", SDLK_W},
|
||||||
|
{"x", SDLK_X},
|
||||||
|
{"y", SDLK_Y},
|
||||||
|
{"z", SDLK_Z},
|
||||||
|
{"0", SDLK_0},
|
||||||
|
{"1", SDLK_1},
|
||||||
|
{"2", SDLK_2},
|
||||||
|
{"3", SDLK_3},
|
||||||
|
{"4", SDLK_4},
|
||||||
|
{"5", SDLK_5},
|
||||||
|
{"6", SDLK_6},
|
||||||
|
{"7", SDLK_7},
|
||||||
|
{"8", SDLK_8},
|
||||||
|
{"9", SDLK_9},
|
||||||
|
{",", SDLK_COMMA},
|
||||||
|
{".", SDLK_PERIOD},
|
||||||
|
{"?", SDLK_QUESTION},
|
||||||
|
{";", SDLK_SEMICOLON},
|
||||||
|
{"-", SDLK_MINUS},
|
||||||
|
{"_", SDLK_UNDERSCORE},
|
||||||
|
{"(", SDLK_LEFTPAREN},
|
||||||
|
{")", SDLK_RIGHTPAREN},
|
||||||
|
{"[", SDLK_LEFTBRACKET},
|
||||||
|
{"]", SDLK_RIGHTBRACKET},
|
||||||
|
{"{", SDLK_LEFTBRACE},
|
||||||
|
{"}", SDLK_RIGHTBRACE},
|
||||||
|
{"\\", SDLK_BACKSLASH},
|
||||||
|
{"/", 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},
|
||||||
|
{"leftbutton", SDL_BUTTON_LEFT},
|
||||||
|
{"rightbutton", SDL_BUTTON_RIGHT},
|
||||||
|
{"middlebutton", SDL_BUTTON_MIDDLE},
|
||||||
|
};
|
||||||
|
std::map<std::string, u32> string_to_keyboard_mod_key_map = {
|
||||||
|
{"lshift", SDL_KMOD_LSHIFT},
|
||||||
|
{"rshift", SDL_KMOD_RSHIFT},
|
||||||
|
{"lctrl", SDL_KMOD_LCTRL},
|
||||||
|
{"rctrl", SDL_KMOD_RCTRL},
|
||||||
|
{"lalt", SDL_KMOD_LALT},
|
||||||
|
{"ralt", SDL_KMOD_RALT},
|
||||||
|
{"shift", SDL_KMOD_SHIFT},
|
||||||
|
{"ctrl", SDL_KMOD_CTRL},
|
||||||
|
{"alt", SDL_KMOD_ALT},
|
||||||
|
{"l_meta", SDL_KMOD_LGUI},
|
||||||
|
{"r_meta", SDL_KMOD_RGUI},
|
||||||
|
{"meta", SDL_KMOD_GUI},
|
||||||
|
{"lwin", SDL_KMOD_LGUI},
|
||||||
|
{"rwin", SDL_KMOD_RGUI},
|
||||||
|
{"win", SDL_KMOD_GUI},
|
||||||
|
{"none", SDL_KMOD_NONE}, // if you want to be fancy
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Button map: maps key+modifier to controller button
|
||||||
|
std::map<KeyBinding, u32> button_map = {
|
||||||
|
/*
|
||||||
|
//Taken keys:
|
||||||
|
//F11: fullscreen
|
||||||
|
//F10: Fps counter
|
||||||
|
//F9: toggle mouse capture
|
||||||
|
// use an other item (healing), change status in inv
|
||||||
|
{{SDLK_F, SDL_KMOD_NONE}, OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TRIANGLE},
|
||||||
|
// dodge, back in inv
|
||||||
|
{{SDLK_SPACE, SDL_KMOD_NONE}, OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_CIRCLE},
|
||||||
|
// interact, select item in inv
|
||||||
|
{{SDLK_E, SDL_KMOD_NONE}, OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_CROSS},
|
||||||
|
// use quick item, remove equipped item of change item desc in inv
|
||||||
|
{{SDLK_R, SDL_KMOD_NONE}, OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_SQUARE},
|
||||||
|
|
||||||
|
// arrow keys, but triggers normal wasd too (pls fix)
|
||||||
|
// emergency extra bullets
|
||||||
|
{{SDLK_W, SDL_KMOD_LALT}, OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_UP},
|
||||||
|
// change quick item
|
||||||
|
{{SDLK_S, SDL_KMOD_LALT}, OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_DOWN},
|
||||||
|
// change weapon in left
|
||||||
|
{{SDLK_a, SDL_KMOD_LALT}, OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_LEFT},
|
||||||
|
// change weapon in right
|
||||||
|
{{SDLK_D, SDL_KMOD_LALT}, OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_RIGHT},
|
||||||
|
|
||||||
|
// menu
|
||||||
|
{{SDLK_ESCAPE, SDL_KMOD_NONE}, OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_OPTIONS},
|
||||||
|
// gestures
|
||||||
|
{{SDLK_G, SDL_KMOD_NONE}, OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TOUCH_PAD},
|
||||||
|
|
||||||
|
// transform
|
||||||
|
{{SDL_BUTTON_RIGHT, SDL_KMOD_LSHIFT}, OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L1},
|
||||||
|
// light attack
|
||||||
|
{{SDL_BUTTON_LEFT, SDL_KMOD_NONE}, OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R1},
|
||||||
|
// shoot
|
||||||
|
{{SDL_BUTTON_RIGHT, SDL_KMOD_NONE}, OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L2},
|
||||||
|
// heavy attack
|
||||||
|
{{SDL_BUTTON_LEFT, SDL_KMOD_LSHIFT}, OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R2},
|
||||||
|
|
||||||
|
// does nothing
|
||||||
|
{{SDLK_X, SDL_KMOD_NONE}, OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L3},
|
||||||
|
// center cam, lock on enemy
|
||||||
|
{{SDLK_Q, SDL_KMOD_NONE}, OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R3},
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
std::map<KeyBinding, AxisMapping> axis_map = {
|
||||||
|
/*
|
||||||
|
// move
|
||||||
|
{{SDLK_A, SDL_KMOD_NONE}, {Input::Axis::LeftX, -127}},
|
||||||
|
{{SDLK_D, SDL_KMOD_NONE}, {Input::Axis::LeftX, 127}},
|
||||||
|
{{SDLK_W, SDL_KMOD_NONE}, {Input::Axis::LeftY, -127}},
|
||||||
|
{{SDLK_S, SDL_KMOD_NONE}, {Input::Axis::LeftY, 127}},
|
||||||
|
|
||||||
|
//this is now using the mouse
|
||||||
|
{{SDLK_J, SDL_KMOD_NONE}, {Input::Axis::RightX, -127}},
|
||||||
|
{{SDLK_L, SDL_KMOD_NONE}, {Input::Axis::RightX, 127}},
|
||||||
|
{{SDLK_I, SDL_KMOD_NONE}, {Input::Axis::RightY, -127}},
|
||||||
|
{{SDLK_K, SDL_KMOD_NONE}, {Input::Axis::RightY, 127}},
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
void WindowSDL::parseInputConfig(const std::string& filename) {
|
||||||
|
std::ifstream file(filename);
|
||||||
|
if (!file.is_open()) {
|
||||||
|
std::cerr << "Error opening file: " << filename << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
button_map.clear();
|
||||||
|
axis_map.clear();
|
||||||
|
int lineCount = 0;
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(file, line)) {
|
||||||
|
lineCount++;
|
||||||
|
// Ignore comment lines
|
||||||
|
if (line.empty() || line[0] == '#') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Split the line by '='
|
||||||
|
std::size_t equal_pos = line.find('=');
|
||||||
|
if (equal_pos == std::string::npos) {
|
||||||
|
std::cerr << "Invalid line format: " << line << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string controller_input = line.substr(0, equal_pos);
|
||||||
|
std::string kbm_input = line.substr(equal_pos + 1);
|
||||||
|
KeyBinding binding = {0, SDL_KMOD_NONE}; // Initialize KeyBinding
|
||||||
|
|
||||||
|
// first we parse the binding, and if its wrong, we skip to the next line
|
||||||
|
std::size_t comma_pos = kbm_input.find(',');
|
||||||
|
if (comma_pos != std::string::npos) {
|
||||||
|
// Handle key + modifier
|
||||||
|
std::string key = kbm_input.substr(0, comma_pos);
|
||||||
|
std::string mod = kbm_input.substr(comma_pos + 1);
|
||||||
|
|
||||||
|
auto key_it = string_to_keyboard_key_map.find(key);
|
||||||
|
auto mod_it = string_to_keyboard_mod_key_map.find(mod);
|
||||||
|
|
||||||
|
if (key_it != string_to_keyboard_key_map.end() && mod_it != string_to_keyboard_mod_key_map.end()) {
|
||||||
|
binding.key = key_it->second;
|
||||||
|
binding.modifier = mod_it->second;
|
||||||
|
} else {
|
||||||
|
std::cerr << "Syntax error while parsing kbm inputs at line " << lineCount << "\n";
|
||||||
|
continue; // skip
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Just a key without modifier
|
||||||
|
auto key_it = string_to_keyboard_key_map.find(kbm_input);
|
||||||
|
if (key_it != string_to_keyboard_key_map.end()) {
|
||||||
|
binding.key = key_it->second;
|
||||||
|
} else {
|
||||||
|
std::cerr << "Syntax error while parsing kbm inputs at line " << lineCount << "\n";
|
||||||
|
continue; // skip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for axis mapping (example: axis_left_x_plus)
|
||||||
|
auto axis_it = string_to_axis_map.find(controller_input);
|
||||||
|
auto button_it = string_to_cbutton_map.find(controller_input);
|
||||||
|
if (axis_it != string_to_axis_map.end()) {
|
||||||
|
axis_map[binding] = axis_it->second;
|
||||||
|
} else if(button_it != string_to_cbutton_map.end()) {
|
||||||
|
button_map[binding] = button_it->second;
|
||||||
|
} else {
|
||||||
|
std::cerr << "Syntax error while parsing controller inputs at line " << lineCount << "\n";
|
||||||
|
continue; // skip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint32 WindowSDL::keyRepeatCallback(void* param, Uint32 id, Uint32 interval) {
|
||||||
|
auto* data = (std::pair<WindowSDL*, SDL_Event*>*)param;
|
||||||
|
KeyBinding binding = { data->second->key.key, SDL_GetModState() };
|
||||||
|
data->first->updateModKeyedInputsManually(binding);
|
||||||
|
//data->first->onKeyPress(data->second);
|
||||||
|
delete data->second;
|
||||||
|
delete data;
|
||||||
|
return 0; // Return 0 to stop the timer after firing once
|
||||||
|
}
|
||||||
|
Uint32 WindowSDL::mousePolling(void* param, Uint32 id, Uint32 interval) {
|
||||||
|
auto* data = (WindowSDL*)param;
|
||||||
|
data->updateMouse();
|
||||||
|
return 33; // Return 0 to stop the timer after firing once
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowSDL::updateMouse() {
|
||||||
|
float d_x = 0, d_y = 0;
|
||||||
|
SDL_GetRelativeMouseState(&d_x, &d_y);
|
||||||
|
//std::cout << "mouse polling yay!\n" << d_x << " " << d_y <<"\n";
|
||||||
|
|
||||||
|
float angle = atan2(d_y, d_x);
|
||||||
|
float a_x = cos(angle) * 128.0, a_y = sin(angle) * 128.0;
|
||||||
|
|
||||||
|
if (d_x != 0 && d_y != 0) {
|
||||||
|
controller->Axis(0, Input::Axis::RightX, Input::GetAxis(-0x80, 0x80, a_x));
|
||||||
|
controller->Axis(0, Input::Axis::RightY, Input::GetAxis(-0x80, 0x80, a_y));
|
||||||
|
} else {
|
||||||
|
controller->Axis(0, Input::Axis::RightX, Input::GetAxis(-0x80, 0x80, 0));
|
||||||
|
controller->Axis(0, Input::Axis::RightY, Input::GetAxis(-0x80, 0x80, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WindowSDL::WindowSDL(s32 width_, s32 height_, Input::GameController* controller_, std::string_view window_title)
|
||||||
: width{width_}, height{height_}, controller{controller_} {
|
: width{width_}, height{height_}, controller{controller_} {
|
||||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||||
UNREACHABLE_MSG("Failed to initialize SDL video subsystem: {}", SDL_GetError());
|
UNREACHABLE_MSG("Failed to initialize SDL video subsystem: {}", SDL_GetError());
|
||||||
@ -70,6 +390,11 @@ WindowSDL::WindowSDL(s32 width_, s32 height_, Input::GameController* controller_
|
|||||||
window_info.type = WindowSystemType::Metal;
|
window_info.type = WindowSystemType::Metal;
|
||||||
window_info.render_surface = SDL_Metal_GetLayer(SDL_Metal_CreateView(window));
|
window_info.render_surface = SDL_Metal_GetLayer(SDL_Metal_CreateView(window));
|
||||||
#endif
|
#endif
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
// initialize kbm controls
|
||||||
|
parseInputConfig("user/keyboardInputConfig.ini");
|
||||||
|
>>>>>>> f031c7e1 (added support for loading keyboard config from file)
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowSDL::~WindowSDL() = default;
|
WindowSDL::~WindowSDL() = default;
|
||||||
@ -143,6 +468,7 @@ void WindowSDL::onKeyPress(const SDL_Event* event) {
|
|||||||
|
|
||||||
u32 button = 0;
|
u32 button = 0;
|
||||||
Input::Axis axis = Input::Axis::AxisMax;
|
Input::Axis axis = Input::Axis::AxisMax;
|
||||||
|
<<<<<<< HEAD
|
||||||
int axisvalue = 0;
|
int axisvalue = 0;
|
||||||
int ax = 0;
|
int ax = 0;
|
||||||
std::string backButtonBehavior = Config::getBackButtonBehavior();
|
std::string backButtonBehavior = Config::getBackButtonBehavior();
|
||||||
@ -313,6 +639,98 @@ void WindowSDL::onKeyPress(const SDL_Event* event) {
|
|||||||
if (axis != Input::Axis::AxisMax) {
|
if (axis != Input::Axis::AxisMax) {
|
||||||
controller->Axis(0, axis, ax);
|
controller->Axis(0, axis, ax);
|
||||||
}
|
}
|
||||||
|
=======
|
||||||
|
int axis_value = 0;
|
||||||
|
|
||||||
|
// Handle window controls outside of the input maps
|
||||||
|
if (event->type == SDL_EVENT_KEY_DOWN) {
|
||||||
|
// Toggle capture of the mouse
|
||||||
|
if (binding.key == SDLK_F9) {
|
||||||
|
SDL_SetWindowRelativeMouseMode(this->GetSdlWindow(), !SDL_GetWindowRelativeMouseMode(this->GetSdlWindow()));
|
||||||
|
}
|
||||||
|
// Reparse kbm inputs
|
||||||
|
if (binding.key == SDLK_F8) {
|
||||||
|
parseInputConfig("user/keyboardInputConfig.ini");
|
||||||
|
}
|
||||||
|
// Toggle fullscreen
|
||||||
|
if (binding.key == SDLK_F11) {
|
||||||
|
SDL_WindowFlags flag = SDL_GetWindowFlags(window);
|
||||||
|
bool is_fullscreen = flag & SDL_WINDOW_FULLSCREEN;
|
||||||
|
SDL_SetWindowFullscreen(window, !is_fullscreen);
|
||||||
|
}
|
||||||
|
// Trigger rdoc capture
|
||||||
|
if (binding.key == SDLK_F12) {
|
||||||
|
VideoCore::TriggerCapture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check if the current key+modifier is a button mapping
|
||||||
|
bool button_found = false;
|
||||||
|
auto button_it = FindKeyAllowingPartialModifiers(button_map, binding);
|
||||||
|
if (button_it == button_map.end()) {
|
||||||
|
button_it = FindKeyAllowingOnlyNoModifiers(button_map, binding);
|
||||||
|
}
|
||||||
|
if (button_it != button_map.end()) {
|
||||||
|
button_found = true;
|
||||||
|
button = button_it->second;
|
||||||
|
WindowSDL::updateButton(binding, button, event->type == SDL_EVENT_KEY_DOWN || event->type == SDL_EVENT_MOUSE_BUTTON_DOWN);
|
||||||
|
}
|
||||||
|
// Check if the current key+modifier is an axis mapping
|
||||||
|
auto axis_it = FindKeyAllowingPartialModifiers(axis_map, binding);
|
||||||
|
if (axis_it == axis_map.end() && !button_found) {
|
||||||
|
axis_it = FindKeyAllowingOnlyNoModifiers(axis_map, binding);
|
||||||
|
}
|
||||||
|
if (axis_it != axis_map.end()) {
|
||||||
|
axis = axis_it->second.axis;
|
||||||
|
axis_value = (event->type == SDL_EVENT_KEY_DOWN || event->type == SDL_EVENT_MOUSE_BUTTON_DOWN) ? axis_it->second.value : 0;
|
||||||
|
int ax = Input::GetAxis(-0x80, 0x80, axis_value);
|
||||||
|
controller->Axis(0, axis, ax);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we don't do this, then if we activate a mod keyed input and let go of the mod key first,
|
||||||
|
// the button will be stuck on the "on" state becuse the "turn off" signal would only come from
|
||||||
|
// the other key being unpressed
|
||||||
|
void WindowSDL::updateModKeyedInputsManually(Frontend::KeyBinding& binding) {
|
||||||
|
bool mod_keyed_input_found = false;
|
||||||
|
for (auto input : button_map) {
|
||||||
|
if (input.first.modifier != SDL_KMOD_NONE) {
|
||||||
|
if ((input.first.modifier & binding.modifier) == 0) {
|
||||||
|
WindowSDL::updateButton(binding, input.second, false);
|
||||||
|
} else {
|
||||||
|
mod_keyed_input_found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto input : axis_map) {
|
||||||
|
if (input.first.modifier != SDL_KMOD_NONE) {
|
||||||
|
if((input.first.modifier & binding.modifier) == 0) {
|
||||||
|
controller->Axis(0, input.second.axis, Input::GetAxis(-0x80, 0x80, 0));
|
||||||
|
} else {
|
||||||
|
mod_keyed_input_found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if both non mod keyed and mod keyed inputs are used and you press the key and then the mod key in a single frame,
|
||||||
|
// both will activate but the simple one will not deactivate, unless i use this stupid looking workaround
|
||||||
|
//return;
|
||||||
|
if(!mod_keyed_input_found) return; // in this case the fix for the fix for the wrong update order is not needed
|
||||||
|
for(auto input : button_map) {
|
||||||
|
if(input.first.modifier == SDL_KMOD_NONE) {
|
||||||
|
WindowSDL::updateButton(binding, input.second, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(auto input : axis_map) {
|
||||||
|
if(input.first.modifier == SDL_KMOD_NONE) {
|
||||||
|
controller->Axis(0, input.second.axis, Input::GetAxis(-0x80, 0x80, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// also this sometimes leads to janky inputs but whoever decides to intentionally create a state where this is needed
|
||||||
|
// should not deserve a smooth experience anyway
|
||||||
|
>>>>>>> f031c7e1 (added support for loading keyboard config from file)
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowSDL::onGamepadEvent(const SDL_Event* event) {
|
void WindowSDL::onGamepadEvent(const SDL_Event* event) {
|
||||||
|
@ -75,6 +75,8 @@ private:
|
|||||||
|
|
||||||
int sdlGamepadToOrbisButton(u8 button);
|
int sdlGamepadToOrbisButton(u8 button);
|
||||||
|
|
||||||
|
void parseInputConfig(const std::string& filename);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
s32 width;
|
s32 width;
|
||||||
s32 height;
|
s32 height;
|
||||||
|
57
user/keyboardInputConfig.ini
Normal file
57
user/keyboardInputConfig.ini
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# controller button mappings
|
||||||
|
|
||||||
|
# taken keys:
|
||||||
|
# f11: fullscreen
|
||||||
|
# f10: fps counter
|
||||||
|
# f9: toggle mouse capture
|
||||||
|
# f8: reparse keyboard input (this)
|
||||||
|
|
||||||
|
# use another item (healing), change status in inventory
|
||||||
|
triangle=f
|
||||||
|
# dodge, back in inv
|
||||||
|
circle=space
|
||||||
|
# interact, select item in inv
|
||||||
|
cross=e
|
||||||
|
# use quick item, remove item in inv
|
||||||
|
square=r
|
||||||
|
|
||||||
|
# arrow keys, but triggers normal wasd too (please fix)
|
||||||
|
# emergency extra bullets
|
||||||
|
up=w,lalt
|
||||||
|
# change quick item
|
||||||
|
down=s,lalt
|
||||||
|
# change weapon in left hand
|
||||||
|
left=a,lalt
|
||||||
|
# change weapon in right hand
|
||||||
|
right=d,lalt
|
||||||
|
|
||||||
|
# menu
|
||||||
|
options=escape
|
||||||
|
# gestures
|
||||||
|
touchpad=g
|
||||||
|
|
||||||
|
# transform
|
||||||
|
l1=rightbutton,lshift
|
||||||
|
# shoot
|
||||||
|
r1=leftbutton
|
||||||
|
# light attack
|
||||||
|
l2=rightbutton
|
||||||
|
# heavy attack
|
||||||
|
r2=leftbutton,lshift
|
||||||
|
|
||||||
|
# does nothing
|
||||||
|
l3=x
|
||||||
|
# center cam, lock on
|
||||||
|
r3=q
|
||||||
|
|
||||||
|
# axis mappings
|
||||||
|
# move
|
||||||
|
axis_left_x_minus=a
|
||||||
|
axis_left_x_plus=d
|
||||||
|
axis_left_y_minus=w
|
||||||
|
axis_left_y_plus=s
|
||||||
|
# og cam input
|
||||||
|
# axis_right_x_minus=j
|
||||||
|
# axis_right_x_plus=l
|
||||||
|
# axis_right_y_minus=i
|
||||||
|
# axis_right_y_plus=k
|
Loading…
Reference in New Issue
Block a user