From fac7ab2616aadeb4a8a884d44e0f7064db76435c Mon Sep 17 00:00:00 2001 From: mchughalex <25671999+mchughalex@users.noreply.github.com> Date: Tue, 30 Jun 2026 23:44:10 +0100 Subject: [PATCH] fix Windows startup and rumble filtering --- src/core/filesystem_win.cpp | 19 ++++++++++++++++--- src/input/input_system.cpp | 23 ++++++++++++++++++++++- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/core/filesystem_win.cpp b/src/core/filesystem_win.cpp index 8cc3036..b30d4a6 100644 --- a/src/core/filesystem_win.cpp +++ b/src/core/filesystem_win.cpp @@ -43,9 +43,22 @@ std::filesystem::path to_path(const std::u16string_view source) { namespace filesystem { std::filesystem::path GetExecutablePath() { - wchar_t* path; - auto error = _get_wpgmptr(&path); - return !error ? std::filesystem::path(path) : std::filesystem::path(); + std::wstring path(MAX_PATH, L'\0'); + for (;;) { + const DWORD length = + GetModuleFileNameW(nullptr, path.data(), static_cast(path.size())); + if (length == 0) { + return {}; + } + if (length < path.size()) { + path.resize(length); + return std::filesystem::path(path); + } + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER || path.size() >= 32768) { + return {}; + } + path.resize(path.size() * 2); + } } std::filesystem::path GetExecutableFolder() { diff --git a/src/input/input_system.cpp b/src/input/input_system.cpp index 15513a7..0c436c1 100644 --- a/src/input/input_system.cpp +++ b/src/input/input_system.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -41,6 +42,10 @@ REXCVAR_DEFINE_STRING(input_backend, kDefaultInputBackend, "Input", "Input backe .allowed({"sdl", "xinput"}); REXCVAR_DEFINE_BOOL(guide_button, false, "Input", "Enable guide button pass-through"); +REXCVAR_DEFINE_BOOL(hid_rumble_enabled, true, "Input", "Enable controller vibration"); +REXCVAR_DEFINE_UINT32(hid_rumble_min_motor_speed, 0x1000, "Input", + "Minimum XInput motor speed forwarded to host controllers") + .range(0, 0xFFFF); namespace rex::input { InputSystem::InputSystem(rex::ui::Window* window) : window_(window) {} @@ -170,9 +175,25 @@ X_RESULT InputSystem::GetState(uint32_t user_index, X_INPUT_STATE* out_state) { X_RESULT InputSystem::SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration) { SCOPE_profile_cpu_f("hid"); + if (!vibration) { + return X_ERROR_BAD_ARGUMENTS; + } + + X_INPUT_VIBRATION filtered_vibration = {}; + if (REXCVAR_GET(hid_rumble_enabled)) { + const uint32_t min_motor_speed = REXCVAR_GET(hid_rumble_min_motor_speed); + const auto filter_motor = [min_motor_speed](uint16_t speed) -> uint16_t { + return speed >= min_motor_speed ? speed : 0; + }; + filtered_vibration.left_motor_speed = + filter_motor(static_cast(vibration->left_motor_speed)); + filtered_vibration.right_motor_speed = + filter_motor(static_cast(vibration->right_motor_speed)); + } + bool any_connected = false; for (auto& driver : drivers_) { - X_RESULT result = driver->SetState(user_index, vibration); + X_RESULT result = driver->SetState(user_index, &filtered_vibration); if (result != X_ERROR_DEVICE_NOT_CONNECTED) { any_connected = true; }