feat(input): add host input remapping

Add compact keyboard and mouse mapping with analog-stick defaults and integrate a global remapping editor into the Qt launcher.

Based on the host input remapping work from PR #109.

Co-authored-by: DistantMyth <thetarun3@gmail.com>
This commit is contained in:
nmzik
2026-08-04 03:24:24 +02:00
parent a3a00464bc
commit 6396dc9a85
21 changed files with 756 additions and 41 deletions
+23 -31
View File
@@ -32,6 +32,7 @@
#include "graphics/host_gpu/vma.h"
#include "graphics/host_gpu/vulkanCommon.h"
#include "graphics/presentation/renderDoc.h"
#include "graphics/presentation/window/hostInput.h"
#include "graphics/presentation/window/windowInternal.h"
#include "kytyGitVersion.h"
#include "libs/controller.h"
@@ -59,8 +60,6 @@
namespace Libs::Graphics {
constexpr int KEYBOARD_CONTROLLER_ID = -1000;
struct EventKeyboard {
bool down;
bool up;
@@ -73,26 +72,6 @@ struct EventKeyboard {
double timestamp_seconds;
};
static uint32_t KeyboardKeyToPadButton(int key_code) {
switch (key_code) {
case SDLK_w: return Controller::PAD_BUTTON_UP;
case SDLK_a: return Controller::PAD_BUTTON_LEFT;
case SDLK_s: return Controller::PAD_BUTTON_DOWN;
case SDLK_d: return Controller::PAD_BUTTON_RIGHT;
case SDLK_j: return Controller::PAD_BUTTON_CROSS;
case SDLK_i: return Controller::PAD_BUTTON_TRIANGLE;
case SDLK_k: return Controller::PAD_BUTTON_SQUARE;
case SDLK_l: return Controller::PAD_BUTTON_CIRCLE;
case SDLK_q: return Controller::PAD_BUTTON_L1;
case SDLK_e: return Controller::PAD_BUTTON_R1;
case SDLK_RETURN:
case SDLK_RETURN2: return Controller::PAD_BUTTON_OPTIONS;
case SDLK_BACKSPACE:
case SDLK_TAB: return Controller::PAD_BUTTON_TOUCH_PAD;
default: return 0;
}
}
static uint32_t ControllerButtonToPadButton(int button) {
switch (button) {
case SDL_CONTROLLER_BUTTON_A: return Controller::PAD_BUTTON_CROSS;
@@ -261,16 +240,11 @@ static void GameEventKeyboard(WindowLoopState& game, const EventKeyboard& key) {
}
}
const auto button = KeyboardKeyToPadButton(key.key_code);
if (button != 0 && (key.down || key.up) && !key.repeat) {
static bool keyboard_connected = false;
if (!keyboard_connected) {
Controller::ControllerConnect(KEYBOARD_CONTROLLER_ID);
keyboard_connected = true;
}
Controller::ControllerButton(KEYBOARD_CONTROLLER_ID, button, key.down);
}
#endif
if ((key.down || key.up) && !key.repeat) {
HostInputKey(key.key_code, key.down);
}
}
static void GameEventMouse([[maybe_unused]] const EventMouse& mb) {
@@ -292,6 +266,23 @@ static void GameEventMouse([[maybe_unused]] const EventMouse& mb) {
mb.x, mb.y);
}
#endif
if (mb.down || mb.up) {
uint8_t mouse_button = 0;
if (mb.left) {
mouse_button = SDL_BUTTON_LEFT;
} else if (mb.middle) {
mouse_button = SDL_BUTTON_MIDDLE;
} else if (mb.right) {
mouse_button = SDL_BUTTON_RIGHT;
} else if (mb.x1) {
mouse_button = SDL_BUTTON_X1;
} else if (mb.x2) {
mouse_button = SDL_BUTTON_X2;
}
HostInputMouseButton(mouse_button, mb.down);
}
}
static void GameEventFinger([[maybe_unused]] const EventFinger& f) {
@@ -795,6 +786,7 @@ static void WindowCreate(WindowContext& context) {
if (SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) < 0) {
EXIT("%s\n", SDL_GetError());
}
HostInputInit();
LOGF("WindowCreate(): width = %d, height = %d\n", width, height);