From aa3c6d79c6b70c873e4e8c2db713fe43fc6c1de4 Mon Sep 17 00:00:00 2001 From: Jan Date: Mon, 30 Aug 2021 19:30:06 +0200 Subject: [PATCH] Implement holding use button for activating for controllers --- src/Components/Modules/Gamepad.cpp | 44 ++++++++++++++++++++++++++++++ src/Components/Modules/Gamepad.hpp | 4 +++ 2 files changed, 48 insertions(+) diff --git a/src/Components/Modules/Gamepad.cpp b/src/Components/Modules/Gamepad.cpp index a51839f2..df3b12cc 100644 --- a/src/Components/Modules/Gamepad.cpp +++ b/src/Components/Modules/Gamepad.cpp @@ -138,6 +138,7 @@ namespace Game keyname_t combinedLocalizedKeyNames[VANILLA_KEY_NAME_COUNT + std::extent_v + 1]; PlayerKeyState* playerKeys = reinterpret_cast(0xA1B7D0); + kbutton_t* playersKb = reinterpret_cast(0xA1A9A8); AimAssistGlobals* aaGlobArray = reinterpret_cast(0x7A2110); keyname_t* vanillaKeyNames = reinterpret_cast(0x798580); keyname_t* vanillaLocalizedKeyNames = reinterpret_cast(0x798880); @@ -168,6 +169,7 @@ namespace Components Dvar::Var Gamepad::gpad_button_deadzone; Dvar::Var Gamepad::gpad_button_rstick_deflect_max; Dvar::Var Gamepad::gpad_button_lstick_deflect_max; + Dvar::Var Gamepad::gpad_use_hold_time; Dvar::Var Gamepad::input_viewSensitivity; Dvar::Var Gamepad::input_invertPitch; Dvar::Var Gamepad::aim_turnrate_pitch; @@ -876,6 +878,44 @@ namespace Components } } + bool Gamepad::Gamepad_ShouldUse(const unsigned useTime) + { + // Only apply hold time to +usereload keybind + return !Game::playersKb[Game::KB_USE_RELOAD].active || useTime >= static_cast(gpad_use_hold_time.get()); + } + + __declspec(naked) void Gamepad::Player_UseEntity_Stub() + { + __asm + { + // Execute overwritten instructions + cmp eax, [ecx + 0x10] + jl skipUse + + // Call our custom check + push eax + pushad + push eax + call Gamepad_ShouldUse + add esp,4 + mov [esp + 0x20],eax + popad + pop eax + + // Skip use if custom check returns false + test al,al + jz skipUse + + // perform use + push 0x5FE39B + ret + + skipUse: + push 0x5FE3AF + ret + } + } + bool Gamepad::Key_IsValidGamePadChar(const int key) { return key >= Game::K_FIRSTGAMEPADBUTTON_RANGE_1 && key <= Game::K_LASTGAMEPADBUTTON_RANGE_1 @@ -1608,6 +1648,7 @@ namespace Components gpad_button_deadzone = Dvar::Register("gpad_button_deadzone", 0.13f, 0.0f, 1.0f, 0, "Game pad button deadzone threshhold"); gpad_button_lstick_deflect_max = Dvar::Register("gpad_button_lstick_deflect_max", 1.0f, 0.0f, 1.0f, 0, "Game pad maximum pad stick pressed value"); gpad_button_rstick_deflect_max = Dvar::Register("gpad_button_rstick_deflect_max", 1.0f, 0.0f, 1.0f, 0, "Game pad maximum pad stick pressed value"); + gpad_use_hold_time = Dvar::Register("gpad_use_hold_time", 250, 0, INT32_MAX, 0, "Time to hold the 'use' button on gamepads to activate use"); input_viewSensitivity = Dvar::Register("input_viewSensitivity", 1.0f, 0.0001f, 5.0f, Game::DVAR_FLAG_SAVED, "View Sensitivity"); input_invertPitch = Dvar::Register("input_invertPitch", false, Game::DVAR_FLAG_SAVED, "Invert gamepad pitch"); @@ -1791,6 +1832,9 @@ namespace Components // Only return gamepad keys when gamepad enabled and only non gamepad keys when not Utils::Hook(0x5A7A23, Key_GetCommandAssignmentInternal_Hk, HOOK_CALL).install()->quick(); + // Add hold time to gamepad usereload on hold prompts + Utils::Hook(0x5FE396, Player_UseEntity_Stub, HOOK_JUMP).install()->quick(); + // Add gamepad inputs to remote control (eg predator) handling Utils::Hook(0x5A6D4E, CL_RemoteControlMove_Stub, HOOK_CALL).install()->quick(); diff --git a/src/Components/Modules/Gamepad.hpp b/src/Components/Modules/Gamepad.hpp index 75c7a099..d0e20d82 100644 --- a/src/Components/Modules/Gamepad.hpp +++ b/src/Components/Modules/Gamepad.hpp @@ -298,6 +298,7 @@ namespace Components static Dvar::Var gpad_button_deadzone; static Dvar::Var gpad_button_rstick_deflect_max; static Dvar::Var gpad_button_lstick_deflect_max; + static Dvar::Var gpad_use_hold_time; static Dvar::Var input_viewSensitivity; static Dvar::Var input_invertPitch; static Dvar::Var aim_turnrate_pitch; @@ -353,6 +354,9 @@ namespace Components static char ClampChar(int value); static void CL_GamepadMove(int gamePadIndex, Game::usercmd_s* cmd, float frameTimeBase); static void CL_MouseMove_Stub(); + + static bool Gamepad_ShouldUse(unsigned useTime); + static void Player_UseEntity_Stub(); static bool Key_IsValidGamePadChar(int key); static void CL_GamepadResetMenuScrollTime(int gamePadIndex, int key, bool down, unsigned int time);