pc: fix certain controller bindings not working (#368)

## Link to GitHub Issue, if one exists
Fixes #364 

## Description of change
The game attempts to hook raw input, but raw input API can only be used
by one window per process. Hook `RegisterRawInputDevices` and prevent
the game from registration for raw input notifications.

## Testing
Tested that HID keyboard works with `Bind` option.
This commit is contained in:
bicarus-dev
2025-09-17 03:55:02 -07:00
committed by GitHub
parent 164592b16d
commit 6592191624
2 changed files with 27 additions and 1 deletions
+25
View File
@@ -3,12 +3,15 @@
#include <format> #include <format>
#include "bi2x_hook.h" #include "bi2x_hook.h"
#include "util/detour.h"
#include "util/logging.h"
#include "util/fileutils.h" #include "util/fileutils.h"
#include "util/unity_player.h" #include "util/unity_player.h"
#include "util/execexe.h" #include "util/execexe.h"
#include "acioemu/handle.h" #include "acioemu/handle.h"
#include "misc/wintouchemu.h" #include "misc/wintouchemu.h"
#include "hooks/graphics/graphics.h" #include "hooks/graphics/graphics.h"
#include "rawinput/rawinput.h"
namespace games::pc { namespace games::pc {
std::string PC_INJECT_ARGS = ""; std::string PC_INJECT_ARGS = "";
@@ -17,6 +20,24 @@ namespace games::pc {
static acioemu::ACIOHandle *acioHandle = nullptr; static acioemu::ACIOHandle *acioHandle = nullptr;
static std::wstring portName = L"COM1"; static std::wstring portName = L"COM1";
static decltype(RegisterRawInputDevices) *RegisterRawInputDevices_orig = nullptr;
static BOOL WINAPI RegisterRawInputDevices_hook(PCRAWINPUTDEVICE pRawInputDevices, UINT uiNumDevices, UINT cbSize) {
// if the caller is spice itself, then pass through.
if (pRawInputDevices &&
(uiNumDevices > 0) &&
(pRawInputDevices[0].hwndTarget == RI_MGR->input_hwnd)) {
return RegisterRawInputDevices_orig(pRawInputDevices, uiNumDevices, cbSize);
}
// otherwise, it must be the game; prevent the game from registering for raw input
// and hijacking WM_INPUT messages.
SetLastError(0xDEADBEEF);
return FALSE;
}
void PCGame::attach() { void PCGame::attach() {
Game::attach(); Game::attach();
@@ -39,6 +60,10 @@ namespace games::pc {
} }
}); });
const auto user32Dll = "user32.dll";
detour::trampoline_try(user32Dll, "RegisterRawInputDevices",
RegisterRawInputDevices_hook, &RegisterRawInputDevices_orig);
if (GRAPHICS_SHOW_CURSOR) { if (GRAPHICS_SHOW_CURSOR) {
unity_utils::force_show_cursor(true); unity_utils::force_show_cursor(true);
+2 -1
View File
@@ -54,7 +54,6 @@ namespace rawinput {
HotplugManager *hotplug; HotplugManager *hotplug;
std::vector<Device> devices; std::vector<Device> devices;
HWND input_hwnd = nullptr;
WNDCLASSEX input_hwnd_class {}; WNDCLASSEX input_hwnd_class {};
std::thread *input_thread = nullptr; std::thread *input_thread = nullptr;
std::thread *flush_thread = nullptr; std::thread *flush_thread = nullptr;
@@ -91,6 +90,8 @@ namespace rawinput {
public: public:
HWND input_hwnd = nullptr;
RawInputManager(); RawInputManager();
~RawInputManager(); ~RawInputManager();