From 6043dabc3c8e1e585cfa0693e464c4a74e3522d4 Mon Sep 17 00:00:00 2001 From: Jan Date: Mon, 23 Aug 2021 13:25:14 +0200 Subject: [PATCH] Apply gamepad axis rotation to usercmds --- src/Components/Modules/Gamepad.cpp | 443 +++++++++-------------------- src/Components/Modules/Gamepad.hpp | 126 +++++--- src/Game/Functions.cpp | 2 + src/Game/Functions.hpp | 2 + 4 files changed, 233 insertions(+), 340 deletions(-) diff --git a/src/Components/Modules/Gamepad.cpp b/src/Components/Modules/Gamepad.cpp index d8abc2c1..45a251e1 100644 --- a/src/Components/Modules/Gamepad.cpp +++ b/src/Components/Modules/Gamepad.cpp @@ -2,9 +2,6 @@ #include -#define XINPUT_SENSITIVITY_MULTIPLIER 4 // Arbitrary value I multiply the xinput senstivity dvar with to get nicer values (0-10 range or something) -#define SIGN(d) ((d > 0) - (d < 0)) - namespace Game { ButtonToCodeMap_t buttonList[] @@ -45,6 +42,16 @@ namespace Game GPAD_INVALID }; + GamepadPhysicalAxis axisSameStick[GPAD_PHYSAXIS_COUNT] + { + GPAD_PHYSAXIS_RSTICK_Y, + GPAD_PHYSAXIS_RSTICK_X, + GPAD_PHYSAXIS_LSTICK_Y, + GPAD_PHYSAXIS_LSTICK_X, + GPAD_PHYSAXIS_NONE, + GPAD_PHYSAXIS_NONE + }; + const char* physicalAxisNames[GPAD_PHYSAXIS_COUNT] { "A_RSTICK_X", @@ -130,6 +137,7 @@ namespace Game keyname_t combinedLocalizedKeyNames[VANILLA_KEY_NAME_COUNT + std::extent_v + 1]; PlayerKeyState* playerKeys = reinterpret_cast(0xA1B7D0); + AimAssistGlobals* aaGlobArray = reinterpret_cast(0x7A2110); keyname_t* vanillaKeyNames = reinterpret_cast(0x798580); keyname_t* vanillaLocalizedKeyNames = reinterpret_cast(0x798880); } @@ -159,6 +167,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::input_viewSensitivity; Dvar::Var Gamepad::xpadSensitivity; Dvar::Var Gamepad::xpadEarlyTime; @@ -193,25 +202,6 @@ namespace Components {Game::K_APAD_RIGHT, Game::K_RIGHTARROW}, }; - - // This should be read from a text file in the players/ folder, most probably / or from config_mp.cfg - std::vector mappings = { - Gamepad::ActionMapping(XINPUT_GAMEPAD_A, "gostand"), - Gamepad::ActionMapping(XINPUT_GAMEPAD_B, "stance"), - Gamepad::ActionMapping(XINPUT_GAMEPAD_X, "usereload"), - Gamepad::ActionMapping(XINPUT_GAMEPAD_Y, "weapnext", false), - Gamepad::ActionMapping(XINPUT_GAMEPAD_LEFT_SHOULDER, "smoke"), - Gamepad::ActionMapping(XINPUT_GAMEPAD_RIGHT_SHOULDER, "frag"), - Gamepad::ActionMapping(XINPUT_GAMEPAD_LEFT_THUMB, "breath_sprint"), - Gamepad::ActionMapping(XINPUT_GAMEPAD_RIGHT_THUMB, "melee"), - Gamepad::ActionMapping(XINPUT_GAMEPAD_START, "togglemenu", false), - Gamepad::ActionMapping(XINPUT_GAMEPAD_BACK, "scores"), - Gamepad::ActionMapping(XINPUT_GAMEPAD_DPAD_LEFT, "actionslot 3"), - Gamepad::ActionMapping(XINPUT_GAMEPAD_DPAD_RIGHT, "actionslot 2"), - Gamepad::ActionMapping(XINPUT_GAMEPAD_DPAD_DOWN, "actionslot 1"), - Gamepad::ActionMapping(XINPUT_GAMEPAD_DPAD_UP, "actionslot 4"), - }; - Gamepad::GamePadGlobals::GamePadGlobals() : axes{}, nextScrollTime(0) @@ -223,132 +213,6 @@ namespace Components } } - - // Same thing - - // void Gamepad::Vibrate(int leftVal, int rightVal) - // { - // // Create a Vibraton State - // XINPUT_VIBRATION Vibration; - // - // // Zeroise the Vibration - // ZeroMemory(&Vibration, sizeof(XINPUT_VIBRATION)); - // - // // Set the Vibration Values - // Vibration.wLeftMotorSpeed = leftVal; - // Vibration.wRightMotorSpeed = rightVal; - // - // // Vibrate the controller - // XInputSetState(xiPlayerNum, &Vibration); - // } - - void Gamepad::CL_GamepadMove(int, Game::usercmd_s* cmd) - { - auto& gamePad = gamePads[0]; - - if (gamePad.enabled) - { - if (std::fabs(gamePad.sticks[0]) > 0.0f || std::fabs(gamePad.sticks[1]) > 0.0f) - { - // We check for 0:0 again so we don't overwrite keyboard input in case the user doesn't feel like using their gamepad, even though its plugged in - cmd->rightmove = static_cast(gamePad.sticks[0] * static_cast(std::numeric_limits().max())); - cmd->forwardmove = static_cast(gamePad.sticks[1] * static_cast(std::numeric_limits().max())); - } - - const bool pressingLeftTrigger = gamePad.analogs[0] > TRIGGER_THRESHOLD_F; - const bool previouslyPressingLeftTrigger = gamePad.lastAnalogs[0] > TRIGGER_THRESHOLD_F; - if (pressingLeftTrigger != previouslyPressingLeftTrigger) - { - if (pressingLeftTrigger) - { - Command::Execute("+speed_throw"); - isADS = true; - } - else - { - Command::Execute("-speed_throw"); - isADS = false; - } - } - - const bool pressingRightTrigger = gamePad.analogs[1] > TRIGGER_THRESHOLD_F; - const bool previouslyPressingRightTrigger = gamePad.lastAnalogs[1] > TRIGGER_THRESHOLD_F; - if (pressingRightTrigger != previouslyPressingRightTrigger) - { - if (pressingRightTrigger) - { - Command::Execute("+attack"); - } - else - { - Command::Execute("-attack"); - } - } - - // Buttons (on/off) mappings - for (auto& i : mappings) - { - auto mapping = i; - auto action = mapping.action; - auto antiAction = mapping.action; - - if (mapping.isReversible) - { - action = "+" + mapping.action; - antiAction = "-" + mapping.action; - } - else if (mapping.wasPressed) - { - if (gamePad.digitals & mapping.input) - { - // Button still pressed, do not send info - } - else - { - i.wasPressed = false; - } - - continue; - } - - if (gamePad.digitals & mapping.input) - { - if (mapping.spamWhenHeld || !i.wasPressed) - { - Command::Execute(action); - } - i.wasPressed = true; - } - else if (mapping.isReversible && mapping.wasPressed) - { - i.wasPressed = false; - Command::Execute(antiAction); - } - } - } - } - - __declspec(naked) void Gamepad::CL_CreateCmdStub() - { - __asm - { - // do xinput! - push esi - push ebp - call CL_GamepadMove - add esp, 8h - - // execute code we patched over - add esp, 4 - fld st - pop ebx - - // return back - push 0x5A6DBF - retn - } - } - __declspec(naked) void Gamepad::MSG_WriteDeltaUsercmdKeyStub() { __asm @@ -431,151 +295,6 @@ namespace Components } } - int Gamepad::unk_CheckKeyHook(int localClientNum, Game::keyNum_t keyCode) - { - const auto& gamePad = gamePads[0]; - - if (gamePad.enabled) - { - if (keyCode == Game::keyNum_t::K_MOUSE2) - { - const bool pressingLeftTrigger = gamePad.analogs[0] > TRIGGER_THRESHOLD_F; - const bool previouslyPressingLeftTrigger = gamePad.lastAnalogs[0] > TRIGGER_THRESHOLD_F; - if (pressingLeftTrigger != previouslyPressingLeftTrigger) - { - if (pressingLeftTrigger) - { - return 1; - } - else - { - return 0; - } - } - } - } - - return Utils::Hook::Call(0x48B2D0)(localClientNum, keyCode); - } - - void Gamepad::MouseOverride(Game::clientActive_t* clientActive, float* mx, float* my) - { - CL_GetMouseMovementCl(clientActive, mx, my); - - const auto& gamePad = gamePads[0]; - - if (gamePad.enabled) - { - float viewSensitivityMultiplier = xpadSensitivity.get() * XINPUT_SENSITIVITY_MULTIPLIER; - - float lockedSensitivityMultiplier = xpadEarlyMultiplier.get(); - float generalXSensitivityMultiplier = xpadHorizontalMultiplier.get(); - float generalYSensitivityMultiplier = xpadVerticalMultiplier.get(); - std::chrono::milliseconds msBeforeUnlockingSensitivity = std::chrono::milliseconds(xpadEarlyTime.get()); - - float viewStickX = gamePad.sticks[2]; - float viewStickY = gamePad.sticks[3]; - - // Gamepad horizontal acceleration on view - if (abs(viewStickX) > 0.80f) - { - if (!isHoldingMaxLookX) - { - isHoldingMaxLookX = true; - timeAtFirstHeldMaxLookX = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); - } - else - { - std::chrono::milliseconds hasBeenHoldingLeftXForMs = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()) - - timeAtFirstHeldMaxLookX; -#ifdef STEP_SENSITIVITY - if (hasBeenHoldingLeftXForMs < msBeforeUnlockingSensitivity) { - viewStickX *= lockedSensitivityMultiplier; - } -#else - float coeff = std::clamp(hasBeenHoldingLeftXForMs.count() / (float)msBeforeUnlockingSensitivity.count(), 0.0F, 1.0F); - viewStickX *= lockedSensitivityMultiplier + coeff * (1.0f - lockedSensitivityMultiplier); -#endif - } - } - else - { - isHoldingMaxLookX = false; - timeAtFirstHeldMaxLookX = 0ms; - viewStickX *= lockedSensitivityMultiplier; - } - - float adsMultiplier = 1.0f; - - auto ps = &clientActive->snap.ps; - - // DO NOT use clientActive->usingAds ! It only works for toggle ADS - if (PM_IsAdsAllowed(ps) && isADS) - { - adsMultiplier = xpadAdsMultiplier.get(); - } - - if (viewStickX != 0 || viewStickY != 0) - { - *(my) = viewStickX * viewSensitivityMultiplier * generalXSensitivityMultiplier * adsMultiplier; - *(mx) = -viewStickY * viewSensitivityMultiplier * generalYSensitivityMultiplier * adsMultiplier; - } - - // Handling killstreaks - const bool pressingRightTrigger = gamePad.analogs[1] > TRIGGER_THRESHOLD_F; - const bool previouslyPressingRightTrigger = gamePad.lastAnalogs[1] > TRIGGER_THRESHOLD_F; - if (pressingRightTrigger != previouslyPressingRightTrigger) - { - bool* isInPredator = reinterpret_cast(0x8EE3B8); - - if (pressingRightTrigger) - { - Utils::Hook::Set(0xA1C4F4, Game::LOC_SEL_INPUT_CONFIRM); - if (*isInPredator) - { - // Yea, that's how we boost - // Command::execute is sync by default so the predator event gets fired properly - Command::Execute("+attack"); - Command::Execute("-attack"); - } - } - } - } - } - - // Game -> Client DLL - __declspec(naked) void CL_GetMouseMovementStub() - { - __asm - { - push edx; - push ecx; - push eax; - call Gamepad::MouseOverride; - add esp, 0xC; - ret; - } - } - - // Client DLL -> Game - void Gamepad::CL_GetMouseMovementCl(Game::clientActive_t* result, float* mx, float* my) - { - __asm - { - push ebx; - push ecx; - push edx; - mov eax, result; - mov ecx, mx; - mov edx, my; - mov ebx, 5A60E0h; - call ebx; - pop edx; - pop ecx; - pop ebx; - } - } - bool Gamepad::GPad_Check(const int gamePadIndex, const int portIndex) { assert(gamePadIndex < Game::MAX_GAMEPADS); @@ -610,6 +329,111 @@ namespace Components || key >= Game::K_FIRSTGAMEPADBUTTON_RANGE_3 && key <= Game::K_LASTGAMEPADBUTTON_RANGE_3; } + float Gamepad::CL_GamepadAxisValue(const int gamePadIndex, const Game::GamepadVirtualAxis virtualAxis) + { + assert(gamePadIndex < Game::MAX_GAMEPADS); + assert(virtualAxis > Game::GPAD_VIRTAXIS_NONE && virtualAxis < Game::GPAD_VIRTAXIS_COUNT); + const auto& gamePadGlobal = gamePadGlobals[gamePadIndex]; + + const auto& [physicalAxis, mapType] = gamePadGlobal.axes.virtualAxes[virtualAxis]; + + if (physicalAxis <= Game::GPAD_PHYSAXIS_NONE || physicalAxis >= Game::GPAD_PHYSAXIS_COUNT) + return 0.0f; + + auto axisDeflection = gamePadGlobal.axes.axesValues[physicalAxis]; + + if (mapType == Game::GPAD_MAP_SQUARED) + { + const auto otherAxisSameStick = Game::axisSameStick[physicalAxis]; + + float otherAxisDeflection; + if (otherAxisSameStick <= Game::GPAD_PHYSAXIS_NONE || otherAxisSameStick >= Game::GPAD_PHYSAXIS_COUNT) + otherAxisDeflection = 0.0f; + else + otherAxisDeflection = gamePadGlobal.axes.axesValues[otherAxisSameStick]; + + axisDeflection = std::sqrt(axisDeflection * axisDeflection + otherAxisDeflection * otherAxisDeflection) * axisDeflection; + } + + return axisDeflection; + } + + char Gamepad::ClampChar(const int value) + { + return static_cast(std::clamp(value, std::numeric_limits::min(), std::numeric_limits::max())); + } + + void Gamepad::CL_GamepadMove(const int gamePadIndex, Game::usercmd_s* cmd, const float frame_time_base) + { + assert(gamePadIndex < Game::MAX_GAMEPADS); + auto& gamePad = gamePads[gamePadIndex]; + auto& gamePadGlobal = gamePadGlobals[gamePadIndex]; + + if (!gpad_enabled.get() || !gamePad.enabled) + return; + + auto pitch = CL_GamepadAxisValue(gamePadIndex, Game::GPAD_VIRTAXIS_PITCH); + if (!Dvar::Var("input_invertPitch").get()) + pitch *= -1; + + auto yaw = -CL_GamepadAxisValue(gamePadIndex, Game::GPAD_VIRTAXIS_YAW); + auto forward = CL_GamepadAxisValue(gamePadIndex, Game::GPAD_VIRTAXIS_FORWARD); + auto side = CL_GamepadAxisValue(gamePadIndex, Game::GPAD_VIRTAXIS_SIDE); + auto attack = CL_GamepadAxisValue(gamePadIndex, Game::GPAD_VIRTAXIS_ATTACK); + auto moveScale = static_cast(std::numeric_limits::max()); + + if (std::fabs(side) > 0.0f || std::fabs(forward) > 0.0f) + { + const auto length = std::fabs(side) <= std::fabs(forward) + ? side / forward + : forward / side; + moveScale = std::sqrt((length * length) + 1.0f) * moveScale; + } + + const auto forwardMove = static_cast(std::floor(forward * moveScale)); + const auto rightMove = static_cast(std::floor(side * moveScale)); + + const auto sensitivity = input_viewSensitivity.get(); + pitch *= sensitivity; + yaw *= sensitivity; + + if (Game::clients[0].cgameMaxPitchSpeed > 0 && Game::clients[0].cgameMaxPitchSpeed < std::fabs(pitch)) + pitch = std::signbit(pitch) ? -Game::clients[0].cgameMaxPitchSpeed : Game::clients[0].cgameMaxPitchSpeed; + if (Game::clients[0].cgameMaxYawSpeed > 0 && Game::clients[0].cgameMaxYawSpeed < std::fabs(yaw)) + yaw = std::signbit(yaw) ? -Game::clients[0].cgameMaxYawSpeed : Game::clients[0].cgameMaxYawSpeed; + + + Game::clients[0].clViewangles[0] += pitch; + Game::clients[0].clViewangles[1] += yaw; + + cmd->rightmove = ClampChar(cmd->rightmove + rightMove); + cmd->forwardmove = ClampChar(cmd->forwardmove + forwardMove); + } + + constexpr auto CL_MouseMove = 0x5A6240; + + __declspec(naked) void Gamepad::CL_MouseMove_Stub() + { + __asm + { + // Prepare args for our function call + push [esp+0x4] // frametime_base + push ebx // cmd + push eax // localClientNum + + push [esp+0x8] // restore frametime_base on the stack + call CL_MouseMove + add esp,4 + + // Call our function, the args were already prepared earlier + call CL_GamepadMove + add esp,0xC + + ret + } + } + + void Gamepad::CL_GamepadResetMenuScrollTime(const int gamePadIndex, const int key, const bool down, const unsigned time) { assert(gamePadIndex < Game::MAX_GAMEPADS); @@ -1171,7 +995,7 @@ namespace Components Game::FS_Printf(handle, "unbindallaxis\n"); - for(auto virtualAxisIndex = 0u; virtualAxisIndex < Game::GPAD_VIRTAXIS_COUNT; virtualAxisIndex++) + for (auto virtualAxisIndex = 0u; virtualAxisIndex < Game::GPAD_VIRTAXIS_COUNT; virtualAxisIndex++) { const auto& axisMapping = gamePadGlobal.axes.virtualAxes[virtualAxisIndex]; if (axisMapping.physicalAxis <= Game::GPAD_PHYSAXIS_NONE || axisMapping.physicalAxis >= Game::GPAD_PHYSAXIS_COUNT @@ -1199,7 +1023,7 @@ namespace Components void __declspec(naked) Gamepad::Com_WriteConfiguration_Modified_Stub() { __asm - { + { mov eax, [ecx + 0x18] or eax, gamePadBindingsModifiedFlags // Also check for gamePadBindingsModifiedFlags test al, 1 @@ -1210,10 +1034,10 @@ namespace Components push 0x60B26E retn - endMethod: + endMethod: push 0x60B298 retn - } + } } @@ -1343,6 +1167,8 @@ 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"); + + input_viewSensitivity = Dvar::Register("input_viewSensitivity", 1.0f, 0.0001f, 5.0f, Game::DVAR_FLAG_SAVED, "View Sensitivity"); } void Gamepad::IN_Init_Hk() @@ -1361,10 +1187,10 @@ namespace Components { for (auto keyNum = 0; keyNum < Game::K_LAST_KEY; keyNum++) { - if(!Key_IsValidGamePadChar(keyNum)) + if (!Key_IsValidGamePadChar(keyNum)) continue; - if(Game::playerKeys[0].keys[keyNum].binding && strcmp(Game::playerKeys[0].keys[keyNum].binding, cmd) == 0) + if (Game::playerKeys[0].keys[keyNum].binding && strcmp(Game::playerKeys[0].keys[keyNum].binding, cmd) == 0) { (*keys)[keyCount++] = keyNum; @@ -1411,11 +1237,11 @@ namespace Components __declspec(naked) void Gamepad::CL_MouseEvent_Stub() { __asm - { + { pushad cmp eax, 6 jz hideCursor - + call IsGamePadInUse test al, al jnz hideCursor @@ -1425,11 +1251,11 @@ namespace Components push 0x4D7C68 retn; - hideCursor: + hideCursor: popad push 0x4D7C8A retn - } + } } bool Gamepad::UI_RefreshViewport_Hk() @@ -1441,11 +1267,12 @@ namespace Components { memcpy(Game::combinedKeyNames, Game::vanillaKeyNames, sizeof(Game::keyname_t) * Game::VANILLA_KEY_NAME_COUNT); memcpy(&Game::combinedKeyNames[Game::VANILLA_KEY_NAME_COUNT], Game::extendedKeyNames, sizeof(Game::keyname_t) * std::extent_v); - Game::combinedKeyNames[std::extent_v -1] = { nullptr, 0 }; + Game::combinedKeyNames[std::extent_v - 1] = {nullptr, 0}; memcpy(Game::combinedLocalizedKeyNames, Game::vanillaLocalizedKeyNames, sizeof(Game::keyname_t) * Game::VANILLA_LOCALIZED_KEY_NAME_COUNT); - memcpy(&Game::combinedLocalizedKeyNames[Game::VANILLA_LOCALIZED_KEY_NAME_COUNT], Game::extendedLocalizedKeyNames, sizeof(Game::keyname_t) * std::extent_v); - Game::combinedLocalizedKeyNames[std::extent_v -1] = { nullptr, 0 }; + memcpy(&Game::combinedLocalizedKeyNames[Game::VANILLA_LOCALIZED_KEY_NAME_COUNT], Game::extendedLocalizedKeyNames, + sizeof(Game::keyname_t) * std::extent_v); + Game::combinedLocalizedKeyNames[std::extent_v - 1] = {nullptr, 0}; Utils::Hook::Set(0x4A780A, Game::combinedKeyNames); Utils::Hook::Set(0x4A7810, Game::combinedKeyNames); @@ -1474,7 +1301,6 @@ namespace Components // Also rewrite configuration when gamepad config is dirty Utils::Hook(0x60B264, Com_WriteConfiguration_Modified_Stub, HOOK_JUMP).install()->quick(); - Utils::Hook(0x60B223, Key_WriteBindings_Hk, HOOK_CALL).install()->quick(); CreateKeyNameMap(); @@ -1505,6 +1331,9 @@ namespace Components //Utils::Hook(0x5A6816, CL_GetMouseMovementStub, HOOK_CALL).install()->quick(); //Utils::Hook(0x5A6829, unk_CheckKeyHook, HOOK_CALL).install()->quick(); + // Add gamepad inputs to usercmds + Utils::Hook(0x5A6DAE, CL_MouseMove_Stub, HOOK_CALL).install()->quick(); + xpadSensitivity = Dvar::Register("xpad_sensitivity", 1.9f, 0.1f, 10.0f, Game::DVAR_FLAG_SAVED, "View sensitivity for XInput-compatible gamepads"); xpadEarlyTime = Dvar::Register("xpad_early_time", 130, 0, 1000, Game::DVAR_FLAG_SAVED, "Time (in milliseconds) of reduced view sensitivity"); xpadEarlyMultiplier = Dvar::Register("xpad_early_multiplier", 0.25f, 0.01f, 1.0f, Game::DVAR_FLAG_SAVED, diff --git a/src/Components/Modules/Gamepad.hpp b/src/Components/Modules/Gamepad.hpp index 469e8958..86f579c4 100644 --- a/src/Components/Modules/Gamepad.hpp +++ b/src/Components/Modules/Gamepad.hpp @@ -114,6 +114,89 @@ namespace Game float axesValues[GPAD_PHYSAXIS_COUNT]; GamepadVirtualAxisMapping virtualAxes[GPAD_VIRTAXIS_COUNT]; }; + + struct AimAssistPlayerState + { + float velocity[3]; + int eFlags; + int linkFlags; + int pm_flags; + int weapFlags; + int weaponState; + float fWeaponPosFrac; + int weapIndex; + bool hasAmmo; + bool isDualWielding; + bool isThirdPerson; + bool isExtendedMelee; + }; + + struct AimTweakables + { + float slowdownRegionWidth; + float slowdownRegionHeight; + float autoAimRegionWidth; + float autoAimRegionHeight; + float autoMeleeRegionWidth; + float autoMeleeRegionHeight; + float lockOnRegionWidth; + float lockOnRegionHeight; + }; + + struct AimScreenTarget + { + int entIndex; + float clipMins[2]; + float clipMaxs[2]; + float aimPos[3]; + float velocity[3]; + float distSqr; + float crosshairDistSqr; + }; + + enum AutoMeleeState + { + AIM_MELEE_STATE_OFF = 0x0, + AIM_MELEE_STATE_TARGETED = 0x1, + AIM_MELEE_STATE_UPDATING = 0x2, + }; + + struct __declspec(align(16)) AimAssistGlobals + { + AimAssistPlayerState ps; + __declspec(align(8)) float screenMtx[4][4]; + float invScreenMtx[4][4]; + bool initialized; + int prevButtons; + AimTweakables tweakables; + float eyeOrigin[3]; + float viewOrigin[3]; + float viewAngles[3]; + float viewAxis[3][3]; + float fovTurnRateScale; + float fovScaleInv; + float adsLerp; + float pitchDelta; + float yawDelta; + float screenWidth; + float screenHeight; + AimScreenTarget screenTargets[64]; + int screenTargetCount; + int autoAimTargetEnt; + bool autoAimPressed; + bool autoAimActive; + float autoAimPitch; + float autoAimPitchTarget; + float autoAimYaw; + float autoAimYawTarget; + AutoMeleeState autoMeleeState; + int autoMeleeTargetEnt; + float autoMeleePitch; + float autoMeleePitchTarget; + float autoMeleeYaw; + float autoMeleeYawTarget; + int lockOnTargetEnt; + }; } namespace Components @@ -153,23 +236,6 @@ namespace Components GamePadGlobals(); }; - struct ActionMapping - { - int input; - std::string action; - bool isReversible; - bool wasPressed = false; - bool spamWhenHeld = false; - - ActionMapping(int input, std::string action, bool isReversible = true, bool spamWhenHeld = false) - { - this->action = action; - this->isReversible = isReversible; - this->input = input; - this->spamWhenHeld = spamWhenHeld; - } - }; - private: static GamePad gamePads[Game::MAX_GAMEPADS]; static GamePadGlobals gamePadGlobals[Game::MAX_GAMEPADS]; @@ -200,6 +266,11 @@ 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 input_viewSensitivity; + static Dvar::Var aim_turnrate_pitch; + static Dvar::Var aim_turnrate_pitch_ads; + static Dvar::Var aim_turnrate_yaw; + static Dvar::Var aim_turnrate_yaw_ads; static Dvar::Var xpadSensitivity; static Dvar::Var xpadEarlyTime; @@ -208,18 +279,6 @@ namespace Components static Dvar::Var xpadVerticalMultiplier; static Dvar::Var xpadAdsMultiplier; - static void CL_GetMouseMovementCl(Game::clientActive_t* result, float* mx, float* my); - static int unk_CheckKeyHook(int localClientNum, Game::keyNum_t keyCode); - - static void MouseOverride(Game::clientActive_t* clientActive, float* my, float* mx); - static void Vibrate(int leftVal = 0, int rightVal = 0); - - static void CL_FrameStub(); - static void PollXInputDevices(); - - static void CL_CreateCmdStub(); - static void CL_GamepadMove(int, Game::usercmd_s*); - static void MSG_WriteDeltaUsercmdKeyStub(); static void ApplyMovement(Game::msg_t* msg, int key, Game::usercmd_s* from, Game::usercmd_s* to); @@ -227,11 +286,12 @@ namespace Components static void MSG_ReadDeltaUsercmdKeyStub(); static void MSG_ReadDeltaUsercmdKeyStub2(); - static void GetLeftStick01Value(XINPUT_STATE* xiState, float& x, float& y); - static void GetRightStick01Value(XINPUT_STATE* xiState, float& x, float& y); - static void GamepadStickTo01(SHORT value, SHORT deadzone, float& output01); + static bool Key_IsValidGamePadChar(int key); - static bool Key_IsValidGamePadChar(const int key); + static float CL_GamepadAxisValue(int gamePadIndex, Game::GamepadVirtualAxis virtualAxis); + static char ClampChar(int value); + static void CL_GamepadMove(int gamePadIndex, Game::usercmd_s* cmd, float frame_time_base); + static void CL_MouseMove_Stub(); static void CL_GamepadResetMenuScrollTime(int gamePadIndex, int key, bool down, unsigned int time); static bool CL_CheckForIgnoreDueToRepeat(int gamePadIndex, int key, int repeatCount, unsigned int time); diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 75180c63..72f2e9f7 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -1274,4 +1274,6 @@ namespace Game } } #pragma optimize("", on) + + clientActive_t* clients = reinterpret_cast(0xB2C698); } diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index d9b1cbcd..c8950f1b 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -956,4 +956,6 @@ namespace Game void R_AddDebugBounds(float* color, Bounds* b, const float(*quat)[4]); Glyph* R_GetCharacterGlyph(Font_s* font, unsigned int letter); + + extern clientActive_t* clients; }