Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
2ab923e
DrawCursorFix V2: added scan for symmetric cursors + Corrected mousew…
Messenils Nov 4, 2025
800dc8c
Rearranged tunell and put it first in order on inject. Added option T…
Messenils Jan 27, 2026
eb00cc0
Option TranslateXtoMKB
Messenils Jan 27, 2026
7072f58
Removed debug message. Fixed correct Xinput ID for TranslateXinput op…
Messenils Jan 27, 2026
d88d253
Erased TranslateXtoMKB and started over again. now all of protoinputs…
Messenils Feb 6, 2026
35c8d01
mapping for TranslateXinputtoMKB in UI + fixed some button problems
Messenils Feb 8, 2026
08c58fa
Integrated coordinate scanning in the XinputtoMKB option
Messenils Feb 9, 2026
876b31b
important. reverted something in inputlock i shouldnt touch
Messenils Feb 9, 2026
7d4fef1
fixed coordinate redraw on window move. added some of the scanning op…
Messenils Feb 10, 2026
b7dcfeb
disabled coordinate search completely when scanoption is disabled
Messenils Feb 10, 2026
aa42036
repaired stick axis buttons, added GetCursorInfoHook
Messenils Feb 11, 2026
b2bd6bf
near complete. just some render problem. already fixed for pointA
Messenils Feb 14, 2026
3c25075
Render now okay. dont know of any other problems
Messenils Feb 15, 2026
834d0b9
New option: ProtoInput.ScaleInput. handles mouse scaling if any game …
Messenils Feb 25, 2026
60b3a06
made the scaling manual, with 2 new lines
Messenils Feb 28, 2026
0bd05c7
gui thread startup moved to hotkey press. repaired a tunell error
Messenils Mar 3, 2026
d977768
i forget to delete the guithread in dllmain. now fixed, now the threa…
Messenils Mar 4, 2026
7721f97
Added sens adjust hotkey for TranslateX. Start button + Up/Down -> br…
Messenils Mar 22, 2026
5c2f885
added suboption TranslateKBMtoXinput within Xinputhook
Messenils Mar 27, 2026
16a31dd
translate option playable now
Messenils Mar 29, 2026
5c2c2fb
fixed imgui unique ids/text
Messenils Mar 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions src/ProtoInput/ProtoInputHooks/BlockXinputHook.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#include "BlockXinputHook.h"
#include <imgui.h>
#include <Xinput.h>

namespace Proto
{

DWORD WINAPI Hook_XInputGetState(DWORD dwUserIndex, XINPUT_STATE* pState)
{
return ERROR_SUCCESS;
}
DWORD WINAPI Hook_XInputGetStateEx(DWORD dwUserIndex, XINPUT_STATE* pState)
{
return ERROR_SUCCESS;
}

DWORD WINAPI Hook_XInputSetState(DWORD dwUserIndex, XINPUT_VIBRATION* pVibration)
{
return ERROR_SUCCESS;
}


void BlockXinputHook::ShowGuiStatus()
{

ImGui::Separator();
ImGui::Text("This hook blocks Xinput Controllers from being discovered by game.");
}

void BlockXinputHook::InstallImpl()
{
// Some games (e.g. Terraria) haven't loaded the dlls when we inject hooks. So load all XInput dlls.
const wchar_t* xinputNames[] = {
L"xinput1_3.dll", L"xinput1_4.dll", L"xinput1_2.dll", L"xinput1_1.dll", L"xinput9_1_0.dll"
};
for (const auto xinputName : xinputNames)
{
if (LoadLibraryW(xinputName) == nullptr)
{
fprintf(stderr, "Not hooking %ws as failed to load dll\n", xinputName);
continue;
}

if (GetModuleHandleW(xinputName) == nullptr)
{
fprintf(stderr, "Not hooking %ws as failed get module\n", xinputName);
continue;
}

hookInfos.push_back(std::get<1>(InstallNamedHook(xinputName, "XInputGetState", Hook_XInputGetState)));
hookInfos.push_back(std::get<1>(InstallNamedHook(xinputName, "XInputSetState", Hook_XInputSetState)));
}
//XinputGetStateEx (hidden call, ordinal 100). Only present in xinput1_4.dll and xinput1_3.dll. Used by EtG and DoS2
//DWORD as 1st param and similar structure pointer for 2nd param (with an extra DWORD at the end). Can be treated as a normal XINPUT_STATE.
if (nullptr != LoadLibraryW(L"xinput1_4.dll"))
{
hookInfos.push_back(std::get<1>(InstallNamedHook(L"xinput1_4.dll", (LPCSTR)(100), Hook_XInputGetStateEx, true)));
}
if (nullptr != LoadLibraryW(L"xinput1_3.dll"))
{
hookInfos.push_back(std::get<1>(InstallNamedHook(L"xinput1_3.dll", (LPCSTR)(100), Hook_XInputGetStateEx, true)));

XInputGetStateExPtr = t_XInputGetStateEx(GetProcAddress(GetModuleHandleW(L"xinput1_3.dll"), (LPCSTR)(100)));
XInputGetStatePtr = t_XInputGetState(GetProcAddress(GetModuleHandleW(L"xinput1_3.dll"), "XInputGetState"));
XInputSetStatePtr = t_XInputSetState(GetProcAddress(GetModuleHandleW(L"xinput1_3.dll"), "XInputSetState"));

if (XInputGetStateExPtr == nullptr)
MessageBoxA(NULL, "XInputGetStateExPtr is null", "Error", MB_OK);

if (XInputGetStatePtr == nullptr)
MessageBoxA(NULL, "XInputGetStatePtr is null", "Error", MB_OK);

if (XInputSetStatePtr == nullptr)
MessageBoxA(NULL, "XInputSetStatePtr is null", "Error", MB_OK);

if (XInputGetCapabilitiesPtr == nullptr)
MessageBoxA(NULL, "XInputGetCapabilitiesPtr is null", "Error", MB_OK);
}

void BlockXinputHook::UninstallImpl()
{
UninstallHook(&hookInfoBlockXinput);
}

}
29 changes: 29 additions & 0 deletions src/ProtoInput/ProtoInputHooks/BlockXinputHook.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once
#include "Hook.h"
#include "InstallHooks.h"

namespace Proto
{


class BlockXinputHook final : public Hook
{
private:
std::vector<HookInfo> hookInfos{};

public:
const char* GetHookName() const override { return "Cursor Visibility"; }
const char* GetHookDescription() const override
{
return "Whenever the game calls for the cursor to be shown/hidden, the 'fake' cursor is shown/hidden instead. "
"Also detects when the game tries to set a custom cursor image, so the fake cursor can copy it. ";
}
bool HasGuiStatus() const override { return true; }
void ShowGuiStatus() override;
void InstallImpl() override;
void UninstallImpl() override;

static bool ShowCursorWhenImageUpdated;
};

}
Loading