From b748de12c323427716ed1ff3d657e3291bf627e6 Mon Sep 17 00:00:00 2001 From: mlugg Date: Sat, 9 Jul 2022 13:08:26 +0100 Subject: [PATCH] feat: add sar_dpi_scale --- src/Modules/Engine.cpp | 18 +++++++++++++++++- src/Modules/Engine.hpp | 5 +++++ src/Modules/InputSystem.cpp | 32 ++++++++++++++++++++++++++++++++ src/Modules/InputSystem.hpp | 7 +++++++ src/OffsetsData.hpp | 2 ++ 5 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/Modules/Engine.cpp b/src/Modules/Engine.cpp index be4ee2332..9f0778954 100644 --- a/src/Modules/Engine.cpp +++ b/src/Modules/Engine.cpp @@ -5,6 +5,7 @@ #include "EngineDemoPlayer.hpp" #include "EngineDemoRecorder.hpp" #include "Event.hpp" +#include "InputSystem.hpp" #include "Features/Camera.hpp" #include "Features/Cvars.hpp" #include "Features/Demo/DemoParser.hpp" @@ -57,6 +58,9 @@ Variable sar_cm_rightwarp("sar_cm_rightwarp", "0", "Fix CM wrongwarp.\n"); REDECL(Engine::Disconnect); REDECL(Engine::SetSignonState); REDECL(Engine::ChangeLevel); +#ifndef _WIN32 +REDECL(Engine::GetMouseDelta); +#endif REDECL(Engine::Frame); REDECL(Engine::PurgeUnusedModels); REDECL(Engine::OnGameOverlayActivated); @@ -305,6 +309,14 @@ DETOUR(Engine::ChangeLevel, const char *s1, const char *s2) { return Engine::ChangeLevel(thisptr, s1, s2); } +#ifndef _WIN32 +// CVEngineClient::GetMouseDelta +DETOUR_T(void, Engine::GetMouseDelta, int &x, int &y, bool ignore_next) { + Engine::GetMouseDelta(thisptr, x, y, ignore_next); + inputSystem->DPIScaleDeltas(x, y); +} +#endif + void Engine::GetTicks(int &host, int &server, int &client) { auto &et = this->engineTool; using _Fn = int(__rescall *)(void *thisptr); @@ -773,7 +785,7 @@ DETOUR(Engine::DestroyDebugMesh, int vertCount, Vector *verts) { } bool Engine::Init() { - this->engineClient = Interface::Create(this->Name(), "VEngineClient015", false); + this->engineClient = Interface::Create(this->Name(), "VEngineClient015"); this->s_ServerPlugin = Interface::Create(this->Name(), "ISERVERPLUGINHELPERS001", false); if (this->engineClient) { @@ -792,6 +804,10 @@ bool Engine::Init() { this->GetLevelNameShort = this->engineClient->Original<_GetLevelNameShort>(Offsets::GetLevelNameShort); this->GetLightForPoint = this->engineClient->Original<_GetLightForPoint>(Offsets::GetLightForPoint); +#ifndef _WIN32 + this->engineClient->Hook(Engine::GetMouseDelta_Hook, Engine::GetMouseDelta, Offsets::GetMouseDelta); +#endif + Memory::Read<_Cbuf_AddText>((uintptr_t)this->ClientCmd + Offsets::Cbuf_AddText, &this->Cbuf_AddText); #ifndef _WIN32 if (sar.game->Is(SourceGame_EIPRelPIC)) { diff --git a/src/Modules/Engine.hpp b/src/Modules/Engine.hpp index f515f38aa..d9333e8cd 100644 --- a/src/Modules/Engine.hpp +++ b/src/Modules/Engine.hpp @@ -161,6 +161,11 @@ class Engine : public Module { // CVEngineServer::ChangeLevel DECL_DETOUR(ChangeLevel, const char *s1, const char *s2); +#ifndef _WIN32 + // CVEngineClient::GetMouseDelta + DECL_DETOUR_T(void, GetMouseDelta, int &x, int &y, bool ignore_next); +#endif + // CEngine::Frame DECL_DETOUR(Frame); diff --git a/src/Modules/InputSystem.cpp b/src/Modules/InputSystem.cpp index 1c3c1fe69..0f432d4e3 100644 --- a/src/Modules/InputSystem.cpp +++ b/src/Modules/InputSystem.cpp @@ -9,6 +9,9 @@ #include "Utils.hpp" REDECL(InputSystem::SleepUntilInput); +#ifdef _WIN32 +REDECL(InputSystem::GetRawMouseAccumulators); +#endif int InputSystem::GetButton(const char *pString) { return this->StringToButtonCode(this->g_InputSystem->ThisPtr(), pString); @@ -26,6 +29,24 @@ void InputSystem::SetCursorPos(int x, int y) { return this->SetCursorPosition(this->g_InputSystem->ThisPtr(), x, y); } +Variable sar_dpi_scale("sar_dpi_scale", "1", 1, "Fraction to scale mouse DPI down by.\n"); +void InputSystem::DPIScaleDeltas(int &x, int &y) { + static int saved_x = 0; + static int saved_y = 0; + + int scale = sar_dpi_scale.GetInt(); + if (scale < 1) scale = 1; + + saved_x += x; + saved_y += y; + + x = saved_x / scale; + y = saved_y / scale; + + saved_x %= scale; + saved_y %= scale; +} + // CInputSystem::SleepUntilInput DETOUR(InputSystem::SleepUntilInput, int nMaxSleepTimeMS) { if (sar_disable_no_focus_sleep.GetBool()) { @@ -35,12 +56,23 @@ DETOUR(InputSystem::SleepUntilInput, int nMaxSleepTimeMS) { return InputSystem::SleepUntilInput(thisptr, nMaxSleepTimeMS); } +#ifdef _WIN32 +// CInputSystem::GetRawMouseAccumulators +DETOUR_T(void, InputSystem::GetRawMouseAccumulators, int &x, int &y) { + InputSystem::GetRawMouseAccumulators(thisptr, x, y); + inputSystem->DPIScaleDeltas(x, y); +} +#endif + bool InputSystem::Init() { this->g_InputSystem = Interface::Create(this->Name(), "InputSystemVersion001"); if (this->g_InputSystem) { this->StringToButtonCode = this->g_InputSystem->Original<_StringToButtonCode>(Offsets::StringToButtonCode); this->g_InputSystem->Hook(InputSystem::SleepUntilInput_Hook, InputSystem::SleepUntilInput, Offsets::SleepUntilInput); +#ifdef _WIN32 + this->g_InputSystem->Hook(InputSystem::GetRawMouseAccumulators_Hook, InputSystem::GetRawMouseAccumulators, Offsets::GetRawMouseAccumulators); +#endif this->IsButtonDown = this->g_InputSystem->Original<_IsButtonDown>(Offsets::IsButtonDown); this->GetCursorPosition = this->g_InputSystem->Original<_GetCursorPosition>(Offsets::GetCursorPosition); this->SetCursorPosition = this->g_InputSystem->Original<_SetCursorPosition>(Offsets::SetCursorPosition); diff --git a/src/Modules/InputSystem.hpp b/src/Modules/InputSystem.hpp index e241ccd53..a79440982 100644 --- a/src/Modules/InputSystem.hpp +++ b/src/Modules/InputSystem.hpp @@ -235,9 +235,16 @@ class InputSystem : public Module { void GetCursorPos(int &x, int &y); void SetCursorPos(int x, int y); + void DPIScaleDeltas(int &x, int &y); + // CInputSystem::SleepUntilInput DECL_DETOUR(SleepUntilInput, int nMaxSleepTimeMS); +#ifdef _WIN32 + // CInputSystem::GetRawMouseAccumulators + DECL_DETOUR_T(void, GetRawMouseAccumulators, int &x, int &y); +#endif + bool Init() override; void Shutdown() override; const char *Name() override { return MODULE("inputsystem"); } diff --git a/src/OffsetsData.hpp b/src/OffsetsData.hpp index 831b4c56f..1a1e8c53b 100644 --- a/src/OffsetsData.hpp +++ b/src/OffsetsData.hpp @@ -24,6 +24,7 @@ OFFSET_DEFAULT(GetSaveDirName, 124, 124) OFFSET_DEFAULT(ExecuteClientCmd, 104, 104) OFFSET_DEFAULT(GetActiveSplitScreenPlayerSlot, 127, 127) OFFSET_DEFAULT(GetSteamAPIContext, 177, 178) +OFFSET_DEFAULT(GetMouseDelta, -1, 161) // This method only exists on Linux OFFSET_DEFAULT(IsPaused, 86, 86) OFFSET_DEFAULT(DebugDrawPhysCollide, 75, 75) OFFSET_DEFAULT(Con_IsVisible, 11, 11) @@ -75,6 +76,7 @@ OFFSET_DEFAULT(CreateNewTextureID, 41, 41) // CInputSystem OFFSET_DEFAULT(StringToButtonCode, 31, 31) OFFSET_DEFAULT(SleepUntilInput, 33, 33) +OFFSET_DEFAULT(GetRawMouseAccumulators, 50, 52) OFFSET_DEFAULT(IsButtonDown, 14, 14) OFFSET_DEFAULT(GetCursorPosition, 45, 45) OFFSET_DEFAULT(SetCursorPosition, 38, 38)