From 2624cca9f0ae9a69ba1b32ecb264b5a5d7cb7cb4 Mon Sep 17 00:00:00 2001 From: Krzyhau Date: Sat, 25 Apr 2020 19:26:18 +0200 Subject: [PATCH 01/14] committing old files --- src/Features.hpp | 1 + src/Games/Windows/Portal2.cpp | 6 + src/Modules/Client.cpp | 9 ++ src/Modules/Client.hpp | 3 + src/Modules/Engine.cpp | 19 ++- src/Modules/Engine.hpp | 7 + src/Modules/EngineDemoPlayer.cpp | 4 + src/Modules/InputSystem.cpp | 18 +++ src/Modules/InputSystem.hpp | 214 +++++++++++++++++++++++++++++++ src/Offsets.cpp | 6 + src/Offsets.hpp | 6 + src/SAR.cpp | 1 + 12 files changed, 291 insertions(+), 3 deletions(-) diff --git a/src/Features.hpp b/src/Features.hpp index 527d337c..a6e1be8a 100644 --- a/src/Features.hpp +++ b/src/Features.hpp @@ -26,3 +26,4 @@ #include "Features/Timer/PauseTimer.hpp" #include "Features/Timer/Timer.hpp" #include "Features/WorkshopList.hpp" +#include "Features/DemoCamera.hpp" diff --git a/src/Games/Windows/Portal2.cpp b/src/Games/Windows/Portal2.cpp index 4f8adc66..ade9c850 100644 --- a/src/Games/Windows/Portal2.cpp +++ b/src/Games/Windows/Portal2.cpp @@ -36,6 +36,9 @@ void Portal2::LoadOffsets() GetSteamAPIContext = 177; // CEngineClient StringToButtonCode = 31; // CInputSystem SleepUntilInput = 33; // CInputSystem + IsButtonDown = 14; //CInputSystem + GetCursorPosition = 45; //CInputSystem + SetCursorPosition = 38; //CInputSystem GetRecordingTick = 1; // CDemoRecorder net_time = 19; // CDemoRecorder::GetRecordingTick SetSignonState = 3; // CDemoRecorder @@ -57,6 +60,8 @@ void Portal2::LoadOffsets() demoplayer = 74; // CClientState::Disconnect demorecorder = 87; // CClientState::Disconnect GetCurrentMap = 25; // CEngineTool + HostFrameTime = 39; //CEngineTool + ClientTime = 47; //CEngineTool m_szLevelName = 36; // CEngineTool::GetCurrentMap AddListener = 3; // CGameEventManager RemoveListener = 5; // CGameEventManager @@ -145,6 +150,7 @@ void Portal2::LoadOffsets() JoyStickApplyMovement = 64; // CInput KeyDown = 398; // CInput::JoyStickApplyMovement KeyUp = 377; // CInput::JoyStickApplyMovement + OverrideView = 18; // ClientModeShared // vguimatsurface.dll diff --git a/src/Modules/Client.cpp b/src/Modules/Client.cpp index 0c8efbc0..2ebcac63 100644 --- a/src/Modules/Client.cpp +++ b/src/Modules/Client.cpp @@ -12,6 +12,7 @@ #include "Features/Session.hpp" #include "Features/Tas/AutoStrafer.hpp" #include "Features/Tas/CommandQueuer.hpp" +#include "Features/DemoCamera.hpp" #include "Console.hpp" #include "Engine.hpp" @@ -38,6 +39,7 @@ REDECL(Client::DecodeUserCmdFromBuffer2); REDECL(Client::CInput_CreateMove); REDECL(Client::GetButtonBits); REDECL(Client::playvideo_end_level_transition_callback); +REDECL(Client::OverrideView); MDECL(Client::GetAbsOrigin, Vector, C_m_vecAbsOrigin); MDECL(Client::GetAbsAngles, QAngle, C_m_angAbsRotation); @@ -211,6 +213,12 @@ DETOUR_COMMAND(Client::playvideo_end_level_transition) return Client::playvideo_end_level_transition_callback(args); } +DETOUR(Client::OverrideView, void* m_View) +{ + demoCamera->OverrideView(m_View); + return Client::OverrideView(thisptr, m_View); +} + bool Client::Init() { bool readJmp = false; @@ -291,6 +299,7 @@ bool Client::Init() if (this->g_pClientMode = Interface::Create(clientMode)) { this->g_pClientMode->Hook(Client::CreateMove_Hook, Client::CreateMove, Offsets::CreateMove); + this->g_pClientMode->Hook(Client::OverrideView_Hook, Client::OverrideView, Offsets::OverrideView); } if (this->g_pClientMode2 = Interface::Create(clientMode2)) { diff --git a/src/Modules/Client.hpp b/src/Modules/Client.hpp index 27b662d9..842a8442 100644 --- a/src/Modules/Client.hpp +++ b/src/Modules/Client.hpp @@ -60,6 +60,9 @@ class Client : public Module { // CInput::GetButtonBits DECL_DETOUR(GetButtonBits, bool bResetState); + // ClientModeShared::OverrideView + DECL_DETOUR(OverrideView, void* m_View); + DECL_DETOUR_COMMAND(playvideo_end_level_transition); bool Init() override; diff --git a/src/Modules/Engine.cpp b/src/Modules/Engine.cpp index 1ecc4eee..cd43eb4e 100644 --- a/src/Modules/Engine.cpp +++ b/src/Modules/Engine.cpp @@ -128,6 +128,16 @@ void Engine::SafeUnload(const char* postCommand) } } +float Engine::GetHostFrameTime() +{ + return this->HostFrameTime(this->engineTool->ThisPtr()); +} + +float Engine::GetClientTime() +{ + return this->ClientTime(this->engineTool->ThisPtr()); +} + // CClientState::Disconnect DETOUR(Engine::Disconnect, bool bShowMainMenu) { @@ -356,8 +366,8 @@ bool Engine::Init() } } - if (auto tool = Interface::Create(this->Name(), "VENGINETOOL0", false)) { - auto GetCurrentMap = tool->Original(Offsets::GetCurrentMap); + if (this->engineTool = Interface::Create(this->Name(), "VENGINETOOL0", false)) { + auto GetCurrentMap = this->engineTool->Original(Offsets::GetCurrentMap); this->m_szLevelName = Memory::Deref(GetCurrentMap + Offsets::m_szLevelName); if (sar.game->Is(SourceGame_HalfLife2Engine) && std::strlen(this->m_szLevelName) != 0) { @@ -366,7 +376,9 @@ bool Engine::Init() } this->m_bLoadgame = reinterpret_cast((uintptr_t)this->m_szLevelName + Offsets::m_bLoadGame); - Interface::Delete(tool); + + this->HostFrameTime = this->engineTool->Original<_HostFrameTime>(Offsets::HostFrameTime); + this->ClientTime = this->engineTool->Original<_ClientTime>(Offsets::ClientTime); } if (auto s_EngineAPI = Interface::Create(this->Name(), "VENGINE_LAUNCHER_API_VERSION0", false)) { @@ -448,6 +460,7 @@ void Engine::Shutdown() Interface::Delete(this->cl); Interface::Delete(this->eng); Interface::Delete(this->s_GameEventManager); + Interface::Delete(this->engineTool); #ifdef _WIN32 Command::Unhook("connect", Engine::connect_callback); diff --git a/src/Modules/Engine.hpp b/src/Modules/Engine.hpp index 1e182613..440388f9 100644 --- a/src/Modules/Engine.hpp +++ b/src/Modules/Engine.hpp @@ -21,6 +21,7 @@ class Engine : public Module { Interface* eng = nullptr; Interface* debugoverlay = nullptr; Interface* s_ServerPlugin = nullptr; + Interface* engineTool = nullptr; using _ClientCmd = int(__rescall*)(void* thisptr, const char* szCmdString); using _GetLocalPlayer = int(__rescall*)(void* thisptr); @@ -34,6 +35,8 @@ class Engine : public Module { using _AddText = void(__rescall*)(void* thisptr, const char* pText, int nTickDelay); using _ClientCommand = int (*)(void* thisptr, void* pEdict, const char* szFmt, ...); using _GetLocalClient = int (*)(int index); + using _HostFrameTime = float (*)(void* thisptr); + using _ClientTime = float (*)(void* thisptr); #ifdef _WIN32 using _GetScreenSize = int(__stdcall*)(int& width, int& height); using _GetActiveSplitScreenPlayerSlot = int (*)(); @@ -62,6 +65,8 @@ class Engine : public Module { _ConPrintEvent ConPrintEvent = nullptr; _ClientCommand ClientCommand = nullptr; _GetLocalClient GetLocalClient = nullptr; + _HostFrameTime HostFrameTime = nullptr; + _ClientTime ClientTime = nullptr; EngineDemoPlayer* demoplayer = nullptr; EngineDemoRecorder* demorecorder = nullptr; @@ -89,6 +94,8 @@ class Engine : public Module { void SendToCommandBuffer(const char* text, int delay); int PointToScreen(const Vector& point, Vector& screen); void SafeUnload(const char* postCommand = nullptr); + float GetHostFrameTime(); + float GetClientTime(); // CClientState::Disconnect DECL_DETOUR(Disconnect, bool bShowMainMenu); diff --git a/src/Modules/EngineDemoPlayer.cpp b/src/Modules/EngineDemoPlayer.cpp index b411675c..f5eb23c8 100644 --- a/src/Modules/EngineDemoPlayer.cpp +++ b/src/Modules/EngineDemoPlayer.cpp @@ -2,6 +2,7 @@ #include "Features/Demo/Demo.hpp" #include "Features/Demo/DemoParser.hpp" +#include "Features/DemoCamera.hpp" #include "Console.hpp" #include "Engine.hpp" @@ -43,6 +44,9 @@ DETOUR(EngineDemoPlayer::StartPlayback, const char* filename, bool bAsTimeDemo) console->Print("Could not parse \"%s\"!\n", engine->demoplayer->DemoName); } } + + demoCamera->RequestTimeOffsetRefresh(); + return result; } diff --git a/src/Modules/InputSystem.cpp b/src/Modules/InputSystem.cpp index 5a820ec5..6af303f7 100644 --- a/src/Modules/InputSystem.cpp +++ b/src/Modules/InputSystem.cpp @@ -15,6 +15,21 @@ int InputSystem::GetButton(const char* pString) return this->StringToButtonCode(this->g_InputSystem->ThisPtr(), pString); } +bool InputSystem::IsKeyDown(ButtonCode_t key) +{ + return this->IsButtonDown(this->g_InputSystem->ThisPtr(), key); +} + +void InputSystem::GetCursorPos(int& x, int& y) +{ + return this->GetCursorPosition(this->g_InputSystem->ThisPtr(), x, y); +} + +void InputSystem::SetCursorPos(int x, int y) +{ + return this->SetCursorPosition(this->g_InputSystem->ThisPtr(), x, y); +} + // CInputSystem::SleepUntilInput DETOUR(InputSystem::SleepUntilInput, int nMaxSleepTimeMS) { @@ -33,6 +48,9 @@ bool InputSystem::Init() if (sar.game->Is(SourceGame_Portal2Engine)) { this->g_InputSystem->Hook(InputSystem::SleepUntilInput_Hook, InputSystem::SleepUntilInput, Offsets::SleepUntilInput); + 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 f83bff1c..291f4a7a 100644 --- a/src/Modules/InputSystem.hpp +++ b/src/Modules/InputSystem.hpp @@ -6,6 +6,211 @@ #include "Offsets.hpp" #include "Utils.hpp" +enum { + JOYSTICK_MAX_BUTTON_COUNT = 32, + JOYSTICK_POV_BUTTON_COUNT = 4, + JOYSTICK_AXIS_BUTTON_COUNT = MAX_JOYSTICK_AXES * 2, +}; + +#define MAX_JOYSTICKS 1 +#define JOYSTICK_BUTTON_INTERNAL(_joystick, _button) (JOYSTICK_FIRST_BUTTON + ((_joystick)*JOYSTICK_MAX_BUTTON_COUNT) + (_button)) +#define JOYSTICK_POV_BUTTON_INTERNAL(_joystick, _button) (JOYSTICK_FIRST_POV_BUTTON + ((_joystick)*JOYSTICK_POV_BUTTON_COUNT) + (_button)) +#define JOYSTICK_AXIS_BUTTON_INTERNAL(_joystick, _button) (JOYSTICK_FIRST_AXIS_BUTTON + ((_joystick)*JOYSTICK_AXIS_BUTTON_COUNT) + (_button)) + +#define JOYSTICK_BUTTON(_joystick, _button) ((ButtonCode_t)JOYSTICK_BUTTON_INTERNAL(_joystick, _button)) +#define JOYSTICK_POV_BUTTON(_joystick, _button) ((ButtonCode_t)JOYSTICK_POV_BUTTON_INTERNAL(_joystick, _button)) +#define JOYSTICK_AXIS_BUTTON(_joystick, _button) ((ButtonCode_t)JOYSTICK_AXIS_BUTTON_INTERNAL(_joystick, _button)) + +enum ButtonCode_t { + BUTTON_CODE_INVALID = -1, + BUTTON_CODE_NONE = 0, + + KEY_FIRST = 0, + + KEY_NONE = KEY_FIRST, + KEY_0, + KEY_1, + KEY_2, + KEY_3, + KEY_4, + KEY_5, + KEY_6, + KEY_7, + KEY_8, + KEY_9, + KEY_A, + KEY_B, + KEY_C, + KEY_D, + KEY_E, + KEY_F, + KEY_G, + KEY_H, + KEY_I, + KEY_J, + KEY_K, + KEY_L, + KEY_M, + KEY_N, + KEY_O, + KEY_P, + KEY_Q, + KEY_R, + KEY_S, + KEY_T, + KEY_U, + KEY_V, + KEY_W, + KEY_X, + KEY_Y, + KEY_Z, + KEY_PAD_0, + KEY_PAD_1, + KEY_PAD_2, + KEY_PAD_3, + KEY_PAD_4, + KEY_PAD_5, + KEY_PAD_6, + KEY_PAD_7, + KEY_PAD_8, + KEY_PAD_9, + KEY_PAD_DIVIDE, + KEY_PAD_MULTIPLY, + KEY_PAD_MINUS, + KEY_PAD_PLUS, + KEY_PAD_ENTER, + KEY_PAD_DECIMAL, + KEY_LBRACKET, + KEY_RBRACKET, + KEY_SEMICOLON, + KEY_APOSTROPHE, + KEY_BACKQUOTE, + KEY_COMMA, + KEY_PERIOD, + KEY_SLASH, + KEY_BACKSLASH, + KEY_MINUS, + KEY_EQUAL, + KEY_ENTER, + KEY_SPACE, + KEY_BACKSPACE, + KEY_TAB, + KEY_CAPSLOCK, + KEY_NUMLOCK, + KEY_ESCAPE, + KEY_SCROLLLOCK, + KEY_INSERT, + KEY_DELETE, + KEY_HOME, + KEY_END, + KEY_PAGEUP, + KEY_PAGEDOWN, + KEY_BREAK, + KEY_LSHIFT, + KEY_RSHIFT, + KEY_LALT, + KEY_RALT, + KEY_LCONTROL, + KEY_RCONTROL, + KEY_LWIN, + KEY_RWIN, + KEY_APP, + KEY_UP, + KEY_LEFT, + KEY_DOWN, + KEY_RIGHT, + KEY_F1, + KEY_F2, + KEY_F3, + KEY_F4, + KEY_F5, + KEY_F6, + KEY_F7, + KEY_F8, + KEY_F9, + KEY_F10, + KEY_F11, + KEY_F12, + KEY_CAPSLOCKTOGGLE, + KEY_NUMLOCKTOGGLE, + KEY_SCROLLLOCKTOGGLE, + + KEY_LAST = KEY_SCROLLLOCKTOGGLE, + KEY_COUNT = KEY_LAST - KEY_FIRST + 1, + + // Mouse + MOUSE_FIRST = KEY_LAST + 1, + + MOUSE_LEFT = MOUSE_FIRST, + MOUSE_RIGHT, + MOUSE_MIDDLE, + MOUSE_4, + MOUSE_5, + MOUSE_WHEEL_UP, // A fake button which is 'pressed' and 'released' when the wheel is moved up + MOUSE_WHEEL_DOWN, // A fake button which is 'pressed' and 'released' when the wheel is moved down + + MOUSE_LAST = MOUSE_WHEEL_DOWN, + MOUSE_COUNT = MOUSE_LAST - MOUSE_FIRST + 1, + + // Joystick + JOYSTICK_FIRST = MOUSE_LAST + 1, + + JOYSTICK_FIRST_BUTTON = JOYSTICK_FIRST, + JOYSTICK_LAST_BUTTON = JOYSTICK_BUTTON_INTERNAL(MAX_JOYSTICKS - 1, JOYSTICK_MAX_BUTTON_COUNT - 1), + JOYSTICK_FIRST_POV_BUTTON, + JOYSTICK_LAST_POV_BUTTON = JOYSTICK_POV_BUTTON_INTERNAL(MAX_JOYSTICKS - 1, JOYSTICK_POV_BUTTON_COUNT - 1), + JOYSTICK_FIRST_AXIS_BUTTON, + JOYSTICK_LAST_AXIS_BUTTON = JOYSTICK_AXIS_BUTTON_INTERNAL(MAX_JOYSTICKS - 1, JOYSTICK_AXIS_BUTTON_COUNT - 1), + + JOYSTICK_LAST = JOYSTICK_LAST_AXIS_BUTTON, + +#if !defined(_X360) + NOVINT_FIRST = JOYSTICK_LAST + 2, // plus 1 missing key. +1 seems to cause issues on the first button. + + NOVINT_LOGO_0 = NOVINT_FIRST, + NOVINT_TRIANGLE_0, + NOVINT_BOLT_0, + NOVINT_PLUS_0, + NOVINT_LOGO_1, + NOVINT_TRIANGLE_1, + NOVINT_BOLT_1, + NOVINT_PLUS_1, + + NOVINT_LAST = NOVINT_PLUS_1, +#endif + + BUTTON_CODE_LAST, + BUTTON_CODE_COUNT = BUTTON_CODE_LAST - KEY_FIRST + 1, + + // Helpers for XBox 360 + KEY_XBUTTON_UP = JOYSTICK_FIRST_POV_BUTTON, // POV buttons + KEY_XBUTTON_RIGHT, + KEY_XBUTTON_DOWN, + KEY_XBUTTON_LEFT, + + KEY_XBUTTON_A = JOYSTICK_FIRST_BUTTON, // Buttons + KEY_XBUTTON_B, + KEY_XBUTTON_X, + KEY_XBUTTON_Y, + KEY_XBUTTON_LEFT_SHOULDER, + KEY_XBUTTON_RIGHT_SHOULDER, + KEY_XBUTTON_BACK, + KEY_XBUTTON_START, + KEY_XBUTTON_STICK1, + KEY_XBUTTON_STICK2, + + KEY_XSTICK1_RIGHT = JOYSTICK_FIRST_AXIS_BUTTON, // XAXIS POSITIVE + KEY_XSTICK1_LEFT, // XAXIS NEGATIVE + KEY_XSTICK1_DOWN, // YAXIS POSITIVE + KEY_XSTICK1_UP, // YAXIS NEGATIVE + KEY_XBUTTON_LTRIGGER, // ZAXIS POSITIVE + KEY_XBUTTON_RTRIGGER, // ZAXIS NEGATIVE + KEY_XSTICK2_RIGHT, // UAXIS POSITIVE + KEY_XSTICK2_LEFT, // UAXIS NEGATIVE + KEY_XSTICK2_DOWN, // VAXIS POSITIVE + KEY_XSTICK2_UP, // VAXIS NEGATIVE +}; + #define BUTTON_CODE_INVALID -1 #define KEY_ESCAPE 70 @@ -14,13 +219,22 @@ class InputSystem : public Module { Interface* g_InputSystem = nullptr; using _StringToButtonCode = int(__rescall*)(void* thisptr, const char* pString); + using _IsButtonDown = bool(__rescall*)(void* thisptr, ButtonCode_t key); + using _GetCursorPosition = void(__rescall*)(void* thisptr, int& x, int& y); + using _SetCursorPosition = void(__rescall*)(void* thisptr, int x, int y); using _KeySetBinding = void(__cdecl*)(int keynum, const char* pBinding); _StringToButtonCode StringToButtonCode = nullptr; + _IsButtonDown IsButtonDown = nullptr; + _GetCursorPosition GetCursorPosition = nullptr; + _SetCursorPosition SetCursorPosition = nullptr; _KeySetBinding KeySetBinding = nullptr; public: int GetButton(const char* pString); + bool IsKeyDown(ButtonCode_t); + void GetCursorPos(int& x, int& y); + void SetCursorPos(int x, int y); // CInputSystem::SleepUntilInput DECL_DETOUR(SleepUntilInput, int nMaxSleepTimeMS); diff --git a/src/Offsets.cpp b/src/Offsets.cpp index fb583fc0..1fb41f4e 100644 --- a/src/Offsets.cpp +++ b/src/Offsets.cpp @@ -34,6 +34,7 @@ int JoyStickApplyMovement; // ClientModeShared int CreateMove; +int OverrideView; // ConVar int Dtor; @@ -56,6 +57,9 @@ int DrawTextLen; // CInputSystem int StringToButtonCode; int SleepUntilInput; +int IsButtonDown; +int GetCursorPosition; +int SetCursorPosition; // CInput int GetButtonBits; @@ -123,6 +127,8 @@ int Paint; // CEngineTool int GetCurrentMap; +int HostFrameTime; +int ClientTime; // CSchemeManager int GetIScheme; diff --git a/src/Offsets.hpp b/src/Offsets.hpp index fc84558d..8793601b 100644 --- a/src/Offsets.hpp +++ b/src/Offsets.hpp @@ -34,6 +34,7 @@ extern int JoyStickApplyMovement; // ClientModeShared extern int CreateMove; +extern int OverrideView; // ConVar extern int Dtor; @@ -56,6 +57,9 @@ extern int DrawTextLen; // CInputSystem extern int StringToButtonCode; extern int SleepUntilInput; +extern int IsButtonDown; +extern int GetCursorPosition; +extern int SetCursorPosition; // CInput extern int GetButtonBits; @@ -123,6 +127,8 @@ extern int Paint; // CEngineTool extern int GetCurrentMap; +extern int HostFrameTime; +extern int ClientTime; // CSchemeManager extern int GetIScheme; diff --git a/src/SAR.cpp b/src/SAR.cpp index cb3e40c0..71b549fc 100644 --- a/src/SAR.cpp +++ b/src/SAR.cpp @@ -61,6 +61,7 @@ bool SAR::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerF this->features->AddFeature(&pauseTimer); this->features->AddFeature(&dataMapDumper); this->features->AddFeature(&fovChanger); + this->features->AddFeature(&demoCamera); this->modules->AddModule(&inputSystem); this->modules->AddModule(&scheme); From b81889f889903ae25006494ac3cfe89a019a6c75 Mon Sep 17 00:00:00 2001 From: Krzyhau Date: Sun, 26 Apr 2020 01:14:44 +0200 Subject: [PATCH 02/14] democam->cam conversion + cleanup --- src/Features.hpp | 2 +- src/Modules/Client.cpp | 9 +++++++-- src/Modules/EngineDemoPlayer.cpp | 4 ++-- src/SAR.cpp | 2 +- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/Features.hpp b/src/Features.hpp index a6e1be8a..b88c4701 100644 --- a/src/Features.hpp +++ b/src/Features.hpp @@ -26,4 +26,4 @@ #include "Features/Timer/PauseTimer.hpp" #include "Features/Timer/Timer.hpp" #include "Features/WorkshopList.hpp" -#include "Features/DemoCamera.hpp" +#include "Features/Camera.hpp" diff --git a/src/Modules/Client.cpp b/src/Modules/Client.cpp index 2ebcac63..b6085376 100644 --- a/src/Modules/Client.cpp +++ b/src/Modules/Client.cpp @@ -12,7 +12,7 @@ #include "Features/Session.hpp" #include "Features/Tas/AutoStrafer.hpp" #include "Features/Tas/CommandQueuer.hpp" -#include "Features/DemoCamera.hpp" +#include "Features/Camera.hpp" #include "Console.hpp" #include "Engine.hpp" @@ -120,6 +120,11 @@ DETOUR(Client::CreateMove, float flInputSampleTime, CUserCmd* cmd) inputHud.SetButtonBits(0, cmd->buttons); } + if (sv_cheats.GetBool() && engine->hoststate->m_activeGame) { + camera->OverrideMovement(cmd); + } + + return Client::CreateMove(thisptr, flInputSampleTime, cmd); } DETOUR(Client::CreateMove2, float flInputSampleTime, CUserCmd* cmd) @@ -215,7 +220,7 @@ DETOUR_COMMAND(Client::playvideo_end_level_transition) DETOUR(Client::OverrideView, void* m_View) { - demoCamera->OverrideView(m_View); + camera->OverrideView(m_View); return Client::OverrideView(thisptr, m_View); } diff --git a/src/Modules/EngineDemoPlayer.cpp b/src/Modules/EngineDemoPlayer.cpp index f5eb23c8..cd3a5d00 100644 --- a/src/Modules/EngineDemoPlayer.cpp +++ b/src/Modules/EngineDemoPlayer.cpp @@ -2,7 +2,7 @@ #include "Features/Demo/Demo.hpp" #include "Features/Demo/DemoParser.hpp" -#include "Features/DemoCamera.hpp" +#include "Features/Camera.hpp" #include "Console.hpp" #include "Engine.hpp" @@ -45,7 +45,7 @@ DETOUR(EngineDemoPlayer::StartPlayback, const char* filename, bool bAsTimeDemo) } } - demoCamera->RequestTimeOffsetRefresh(); + camera->RequestTimeOffsetRefresh(); return result; } diff --git a/src/SAR.cpp b/src/SAR.cpp index 71b549fc..dd40322d 100644 --- a/src/SAR.cpp +++ b/src/SAR.cpp @@ -61,7 +61,7 @@ bool SAR::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerF this->features->AddFeature(&pauseTimer); this->features->AddFeature(&dataMapDumper); this->features->AddFeature(&fovChanger); - this->features->AddFeature(&demoCamera); + this->features->AddFeature(&camera); this->modules->AddModule(&inputSystem); this->modules->AddModule(&scheme); From 79d77e521320b424d868914566b4c4b75bb13fe3 Mon Sep 17 00:00:00 2001 From: Krzyhau Date: Sun, 26 Apr 2020 01:18:13 +0200 Subject: [PATCH 03/14] bruh it literally didn't add these files to commit --- src/Features/Camera.cpp | 504 ++++++++++++++++++++++++++++++++++++++++ src/Features/Camera.hpp | 71 ++++++ 2 files changed, 575 insertions(+) create mode 100644 src/Features/Camera.cpp create mode 100644 src/Features/Camera.hpp diff --git a/src/Features/Camera.cpp b/src/Features/Camera.cpp new file mode 100644 index 00000000..7c10eba8 --- /dev/null +++ b/src/Features/Camera.cpp @@ -0,0 +1,504 @@ +#include "Camera.hpp" + +#include "Modules/Client.hpp" +#include "Modules/Console.hpp" +#include "Modules/Engine.hpp" +#include "Modules/InputSystem.hpp" +#include "Modules/Server.hpp" + +#include "Features/EntityList.hpp" + +#include "Command.hpp" +#include "Offsets.hpp" +#include "Utils.hpp" + +Camera* camera; + +Variable sar_cam_control("sar_cam_control", "0", 0, 2, + "sar_cam_control : Change type of camera control.\n" + "0 = Default (camera is controlled by game engine),\n" + "1 = Drive mode (camera is separated and can be controlled by user input),\n" + "2 = Cinematic mode (camera is controlled by predefined path).\n"); + +Variable sar_cam_drive("sar_cam_drive", "0", 0, 1, + "Enables or disables camera drive mode in-game " + "(turning it on is not required for demo player)\n"); + +Variable cl_skip_player_render_in_main_view; +Variable r_drawviewmodel; +Variable ss_force_primary_fullscreen; +Variable crosshair; + +Camera::Camera() +{ + controlType = Disabled; + + //a bunch of console variables later used in a janky hack + cl_skip_player_render_in_main_view = Variable("cl_skip_player_render_in_main_view"); + r_drawviewmodel = Variable("r_drawviewmodel"); + ss_force_primary_fullscreen = Variable("ss_force_primary_fullscreen"); + crosshair = Variable("crosshair"); +} + +Camera::~Camera() +{ + camera->states.clear(); + + //if (sar_democam_cvar_autochange.GetBool()) { + // cl_skip_player_render_in_main_view.SetValue(1); + // r_drawviewmodel.SetValue(1); + //} +} + +//if in drive mode, checks if player wants to control the camera +//for now it requires LMB input (as in demo drive mode) +bool Camera::IsDriving() { + bool drivingInGame = sar_cam_drive.GetBool() && sv_cheats.GetBool() && engine->hoststate->m_activeGame; + bool drivingInDemo = engine->demoplayer->IsPlaying(); + bool wantingToDrive = inputSystem->IsKeyDown(ButtonCode_t::MOUSE_LEFT); + + return camera->controlType == Manual && wantingToDrive && (drivingInGame || drivingInDemo); +} + +//Calculates demo camera parameter value based on time and predefined path +float Camera::InterpolateStateParam(CameraStateParameter param, float time) +{ + enum { FIRST, + PREV, + NEXT, + LAST }; + + //reading closest 4 frames + float frameTime = time * 60.0f; + int frames[4] = { INT_MIN, INT_MIN, INT_MAX, INT_MAX }; + for (auto const& state : camera->states) { + int stateTime = state.first; + if (frameTime - stateTime >= 0 && frameTime - stateTime < frameTime - frames[PREV]) { + frames[FIRST] = frames[PREV]; + frames[PREV] = stateTime; + } + if (stateTime - frameTime >= 0 && stateTime - frameTime < frames[NEXT] - frameTime) { + frames[LAST] = frames[NEXT]; + frames[NEXT] = stateTime; + } + if (stateTime > frames[FIRST] && stateTime < frames[PREV]) { + frames[FIRST] = stateTime; + } + if (stateTime > frames[NEXT] && stateTime < frames[LAST]) { + frames[LAST] = stateTime; + } + } + + //points for interpolation + Vector points[4]; + + //filling X values + for (int i = 0; i < 4; i++) { + points[i].x = (float)frames[i]; + } + + //making sure all X values are correct before reading Y values, + //"frames" fixed for read, "points" fixed for interpolation. + //if there's at least one cam state in the map, none of these should be MIN or MAX after this. + if (frames[PREV] == INT_MIN) { + points[PREV].x = (float)frames[NEXT]; + frames[PREV] = frames[NEXT]; + } + if (frames[NEXT] == INT_MAX) { + points[NEXT].x = (float)frames[PREV]; + frames[NEXT] = frames[PREV]; + } + if (frames[FIRST] == INT_MIN) { + points[FIRST].x = (float)(2 * frames[PREV] - frames[NEXT]); + frames[FIRST] = frames[PREV]; + } + if (frames[LAST] == INT_MAX) { + points[LAST].x = (float)(2 * frames[NEXT] - frames[PREV]); + frames[LAST] = frames[NEXT]; + } + + bool workWithAngles = param == ANGLES_X || param == ANGLES_Y || param == ANGLES_Z; + + //filling Y values + float oldY = 0; + for (int i = 0; i < 4; i++) { + CameraState state = camera->states[frames[i]]; + switch (param) { + case ANGLES_X: + points[i].y = state.angles.x; + break; + case ANGLES_Y: + points[i].y = state.angles.y; + break; + case ANGLES_Z: + points[i].y = state.angles.z; + break; + case ORIGIN_X: + points[i].y = state.origin.x; + break; + case ORIGIN_Y: + points[i].y = state.origin.y; + break; + case ORIGIN_Z: + points[i].y = state.origin.z; + break; + case FOV: + points[i].y = state.fov; + break; + } + if (workWithAngles) { + float angDif = points[i].y - oldY; + angDif += (angDif > 180) ? -360 : (angDif < -180) ? 360 : 0; + points[i].y = oldY += angDif; + oldY = points[i].y; + } + } + + if (frameTime <= points[PREV].x) + return points[PREV].y; + if (frameTime >= points[NEXT].x) + return points[NEXT].y; + + float t = (frameTime - points[PREV].x) / (points[NEXT].x - points[PREV].x); + //linear interp. + + //return points[PREV].y + (points[NEXT].y - points[PREV].y) * t; + + //cubic hermite spline... kind of? maybe? no fucking clue, just leave me alone + float t2 = t * t, t3 = t * t * t; + float x0 = (points[FIRST].x - points[PREV].x) / (points[NEXT].x - points[PREV].x); + float x1 = 0, x2 = 1; + float x3 = (points[LAST].x - points[PREV].x) / (points[NEXT].x - points[PREV].x); + float m1 = ((points[NEXT].y - points[PREV].y) / (x2 - x1) + (points[PREV].y - points[FIRST].y) / (x1 - x0)) / 2; + float m2 = ((points[LAST].y - points[NEXT].y) / (x3 - x2) + (points[NEXT].y - points[PREV].y) / (x2 - x1)) / 2; + + return (2 * t3 - 3 * t2 + 1) * points[PREV].y + (t3 - 2 * t2 + t) * m1 + (-2 * t3 + 3 * t2) * points[NEXT].y + (t3 - t2) * m2; +} + +//Overrides view. +void Camera::OverrideView(void* m_View) +{ + if (timeOffsetRefresh) { + timeOffset = engine->GetClientTime() - engine->demoplayer->GetTick() / 60.0f; + timeOffsetRefresh = false; + } + + auto newControlType = static_cast(sar_cam_control.GetInt()); + + //don't allow cinematic mode outside of demo player + if (!engine->demoplayer->IsPlaying() && newControlType == Path) { + if (controlType != Path) { + CAMERA_REQUIRE_DEMO_PLAYER_ERROR(); + } else { + controlType = Disabled; + } + newControlType = controlType; + sar_cam_control.SetValue(controlType); + } + + //don't allow drive mode when not using sv_cheats + if (newControlType == Manual && !sv_cheats.GetBool() && !engine->demoplayer->IsPlaying()) { + if (controlType != Manual) { + console->Print("Drive mode requires sv_cheats 1 or demo player.\n"); + } else { + controlType = Disabled; + } + newControlType = controlType; + sar_cam_control.SetValue(controlType); + } + + //janky hack mate + //overriding cvar values, boolean (int) values only. + //this way the cvar themselves are unchanged + if (newControlType != Disabled) { + cl_skip_player_render_in_main_view.ThisPtr()->m_nValue = 0; + r_drawviewmodel.ThisPtr()->m_nValue = 0; + ss_force_primary_fullscreen.ThisPtr()->m_nValue = 1; + crosshair.ThisPtr()->m_nValue = 0; + } + + //handling camera control type switching + if (newControlType != controlType) { + if (controlType == Disabled && newControlType != Disabled) { + //enabling + //sorry nothing + } else if (controlType != Disabled && newControlType == Disabled) { + //disabling + //resetting cvars to their actual values when swithing control off + cl_skip_player_render_in_main_view.SetValue(cl_skip_player_render_in_main_view.GetString()); + r_drawviewmodel.SetValue(r_drawviewmodel.GetString()); + ss_force_primary_fullscreen.SetValue(ss_force_primary_fullscreen.GetString()); + in_forceuser.SetValue(in_forceuser.GetString()); + crosshair.SetValue(crosshair.GetString()); + this->manualActive = false; + } + controlType = newControlType; + } + + //don't do anything if not in game or demo player + if (engine->hoststate->m_activeGame || engine->demoplayer->IsPlaying()) { + //TODO: make CViewSetup struct instead of getting stuff with offsets + Vector* origin = reinterpret_cast(static_cast(m_View) + 28); + QAngle* angles = reinterpret_cast(static_cast(m_View) + 31); + float* fov = reinterpret_cast(static_cast(m_View) + 20); + if (controlType == Disabled) { + currentState.origin = (*origin); + currentState.angles = (*angles); + currentState.fov = (*fov); + } else { + + //manual camera view control + if (controlType == Manual) { + if (IsDriving()) { + if (!manualActive) { + inputSystem->GetCursorPos(mouseHoldPos[0], mouseHoldPos[1]); + manualActive = true; + } + } else { + if (manualActive) { + in_forceuser.SetValue(in_forceuser.GetString()); + manualActive = false; + } + } + if (manualActive) { + //even junkier hack. lock mouse movement using fake in_forceuser 2 LMAO + if(engine->hoststate->m_activeGame)in_forceuser.ThisPtr()->m_nValue = 2; + + //getting mouse movement and resetting the cursor position + int mX, mY; + inputSystem->GetCursorPos(mX, mY); + mX -= mouseHoldPos[0]; + mY -= mouseHoldPos[1]; + inputSystem->SetCursorPos(mouseHoldPos[0], mouseHoldPos[1]); + + currentState.angles.x += (float)mY * 0.22f; + currentState.angles.y -= (float)mX * 0.22f; + + //limit both values between -180 and 180 + currentState.angles.x = remainderf(currentState.angles.x, 360.0f); + currentState.angles.y = remainderf(currentState.angles.y, 360.0f); + + //calculating vectors out of angles for movement + Vector forward, right; + float cp, sp, cy, sy, cr, sr; + cp = cosf(DEG2RAD(currentState.angles.x)); + sp = sinf(DEG2RAD(currentState.angles.x)); + cy = cosf(DEG2RAD(currentState.angles.y)); + sy = sinf(DEG2RAD(currentState.angles.y)); + cr = cosf(DEG2RAD(currentState.angles.z)); + sr = sinf(DEG2RAD(currentState.angles.z)); + + forward.x = cp * cy; + forward.y = cp * sy; + forward.z = -sp; + + right.x = (-1 * sr * sp * cy + -1 * cr * -sy); + right.y = (-1 * sr * sp * sy + -1 * cr * cy); + right.z = -1 * sr * cp; + + //applying movement + bool shiftdown = inputSystem->IsKeyDown(KEY_LSHIFT) || inputSystem->IsKeyDown(KEY_RSHIFT); + bool controldown = inputSystem->IsKeyDown(KEY_LCONTROL) || inputSystem->IsKeyDown(KEY_RCONTROL); + float speed = shiftdown ? 525.0f : (controldown ? 60.0f : 175.0f); + speed *= engine->GetHostFrameTime(); + + if (inputSystem->IsKeyDown(ButtonCode_t::KEY_W)) { + currentState.origin = currentState.origin + (forward * speed); + } + if (inputSystem->IsKeyDown(ButtonCode_t::KEY_S)) { + currentState.origin = currentState.origin + (forward * -speed); + } + if (inputSystem->IsKeyDown(ButtonCode_t::KEY_A)) { + currentState.origin = currentState.origin + (right * -speed); + } + if (inputSystem->IsKeyDown(ButtonCode_t::KEY_D)) { + currentState.origin = currentState.origin + (right * speed); + } + } + } + if (controlType == Path) { + //don't do interpolation when there are no points + if (states.size() > 0) { + float currentTime = engine->GetClientTime() - timeOffset; + currentState.origin.x = InterpolateStateParam(ORIGIN_X, currentTime); + currentState.origin.y = InterpolateStateParam(ORIGIN_Y, currentTime); + currentState.origin.z = InterpolateStateParam(ORIGIN_Z, currentTime); + currentState.angles.x = InterpolateStateParam(ANGLES_X, currentTime); + currentState.angles.y = InterpolateStateParam(ANGLES_Y, currentTime); + currentState.angles.z = InterpolateStateParam(ANGLES_Z, currentTime); + //currentState.fov = InterpolateStateParam(FOV, currentFrameTime); + } + } + //applying custom view + *origin = currentState.origin; + *angles = currentState.angles; + *fov = currentState.fov; //fov is currently not working, not sure why + //console->Print("%f\n", engine->GetClientTime() - timeOffset); + } + } +} + +void Camera::RequestTimeOffsetRefresh() +{ + timeOffsetRefresh = true; +} + +void Camera::OverrideMovement(CUserCmd* cmd) +{ + //blocking keyboard inputs on manual mode + if (IsDriving()) { + cmd->buttons = 0; + cmd->forwardmove = 0; + cmd->sidemove = 0; + cmd->upmove = 0; + } +} + +//COMMANDS + +CON_COMMAND(sar_cam_path_setkf, "sar_cam_path_setkf [frame] [x] [y] [z] [yaw] [pitch] [roll] [fov]: Sets the camera path keyframe.\n") +{ + CAMERA_REQUIRE_DEMO_PLAYER(); + + if (args.ArgC() >= 1 && args.ArgC() <= 9) { + CameraState campos = camera->currentState; + int curFrame = engine->demoplayer->GetTick(); + if (args.ArgC() > 1) { + curFrame = std::atoi(args[1]); + } + if (args.ArgC() > 2) { + float nums[7] = { + campos.origin.x, campos.origin.x, campos.origin.x, + campos.angles.x, campos.angles.x, campos.angles.x, + campos.fov + }; + for (int i = 0; i < args.ArgC() - 2; i++) { + nums[i] = std::stof(args[i + 2]); + } + campos.origin.x = nums[0]; + campos.origin.y = nums[1]; + campos.origin.z = nums[2]; + campos.angles.x = nums[3]; + campos.angles.y = nums[4]; + campos.angles.z = nums[5]; + campos.fov = nums[6]; + } + camera->states[curFrame] = campos; + console->Print("Camera key frame %d created: ", curFrame); + console->Print(std::string(campos).c_str()); + console->Print("\n"); + } else { + return console->Print(sar_cam_path_setkf.ThisPtr()->m_pszHelpString); + } +} + +CON_COMMAND(sar_cam_path_showkf, "sar_cam_path_showkf [frame] : Display information about camera path keyframe at specified frame.\n") +{ + CAMERA_REQUIRE_DEMO_PLAYER(); + + if (args.ArgC() == 2) { + int i = std::atoi(args[1]); + if (camera->states.count(i)) { + console->Print(std::string(camera->states[i]).c_str()); + console->Print("\n"); + } else { + console->Print("This keyframe does not exist.\n"); + } + } else { + return console->Print(sar_cam_path_showkf.ThisPtr()->m_pszHelpString); + } +} + +CON_COMMAND(sar_cam_path_showkfs, "sar_cam_path_showkfs : Display information about all camera path keyframes.\n") +{ + CAMERA_REQUIRE_DEMO_PLAYER(); + + if (args.ArgC() == 1) { + for (auto const& state : camera->states) { + console->Print("%d: ", state.first); + console->Print(std::string(state.second).c_str()); + console->Print("\n"); + } + } else { + return console->Print(sar_cam_path_showkfs.ThisPtr()->m_pszHelpString); + } +} + +CON_COMMAND(sar_cam_path_getkfs, "sar_cam_path_getkfs : Exports commands for recreating currently made camera path.\n") +{ + CAMERA_REQUIRE_DEMO_PLAYER(); + + if (args.ArgC() == 1) { + for (auto const& state : camera->states) { + CameraState cam = state.second; + console->Print("sar_democam_setkf %d %f %f %f %f %f %f;\n", state.first, cam.origin.x, cam.origin.y, cam.origin.z, cam.angles.x, cam.angles.y, cam.angles.z); + } + } else { + return console->Print(sar_cam_path_getkfs.ThisPtr()->m_pszHelpString); + } +} + +CON_COMMAND(sar_cam_path_remkf, "sar_cam_path_remkf [frame] : Removes camera path keyframe at specified frame.\n") +{ + CAMERA_REQUIRE_DEMO_PLAYER(); + + if (args.ArgC() == 1) { + int i = std::atoi(args[1]); + camera->states.erase(i); + console->Print("Camera path keyframe at frame %f removed.\n", args[1]); + } else { + return console->Print(sar_cam_path_remkf.ThisPtr()->m_pszHelpString); + } +} + +CON_COMMAND(sar_cam_path_remkfs, "sar_cam_path_remkfs : Removes all camera path keyframes.\n") +{ + CAMERA_REQUIRE_DEMO_PLAYER(); + + if (args.ArgC() == 1) { + camera->states.clear(); + console->Print("All camera path keyframes have been removed.\n"); + } else { + return console->Print(sar_cam_path_remkfs.ThisPtr()->m_pszHelpString); + } +} + +CON_COMMAND(sar_cam_setang, "sar_cam_setang [roll] : Sets camera angle.\n") +{ + if (camera->controlType != Manual) { + console->Print("Camera not in drive mode! Switching.\n"); + sar_cam_control.SetValue(CameraControlType::Manual); + } + + if (args.ArgC() == 3 || args.ArgC() == 4) { + float angles[3] = { 0, 0, 0 }; + for (int i = 0; i < args.ArgC() - 1; i++) { + angles[i] = std::stof(args[i + 1]); + } + camera->currentState.angles.x = angles[0]; + camera->currentState.angles.y = angles[1]; + camera->currentState.angles.z = angles[2]; + } else { + return console->Print(sar_cam_setang.ThisPtr()->m_pszHelpString); + } +} + +CON_COMMAND(sar_cam_setpos, "sar_cam_setpos : Sets camera position.\n") +{ + if (camera->controlType != Manual) { + console->Print("Camera not in drive mode! Switching.\n"); + sar_cam_control.SetValue(CameraControlType::Manual); + } + + if (args.ArgC() == 4) { + float pos[3] = { 0, 0, 0 }; + for (int i = 0; i < args.ArgC() - 1; i++) { + pos[i] = std::stof(args[i + 1]); + } + camera->currentState.origin.x = pos[0]; + camera->currentState.origin.y = pos[1]; + camera->currentState.origin.z = pos[2]; + } else { + return console->Print(sar_cam_setpos.ThisPtr()->m_pszHelpString); + } +} \ No newline at end of file diff --git a/src/Features/Camera.hpp b/src/Features/Camera.hpp new file mode 100644 index 00000000..fbdce094 --- /dev/null +++ b/src/Features/Camera.hpp @@ -0,0 +1,71 @@ +#pragma once +#include +#include + +#include "Feature.hpp" + +#include "Utils/SDK.hpp" +#include "Variable.hpp" +#include "Modules/Engine.hpp" + + +#define CAMERA_REQUIRE_DEMO_PLAYER_ERROR() console->Print("Cinematic mode cannot be used outside of demo player.\n") +#define CAMERA_REQUIRE_DEMO_PLAYER() if (!engine->demoplayer->IsPlaying()) return CAMERA_REQUIRE_DEMO_PLAYER_ERROR() + +extern Variable sar_cam_control; +extern Variable sar_cam_drive; + +extern Variable cl_skip_player_render_in_main_view; +extern Variable r_drawviewmodel; +extern Variable ss_force_primary_fullscreen; +extern Variable crosshair; + +struct CameraState { + Vector origin = Vector(); + QAngle angles = QAngle(); + float fov = 90; + operator std::string() const{ + std::ostringstream s; + s << "pos: " << origin.x << " " << origin.y << " " << origin.z << "; "; + s << "rot: " << angles.x << " " << angles.y << " " << angles.z << "; "; + s << "fov: " << fov; + return s.str(); + } +}; + +enum CameraStateParameter { + ORIGIN_X, + ORIGIN_Y, + ORIGIN_Z, + ANGLES_X, + ANGLES_Y, + ANGLES_Z, + FOV +}; + +enum CameraControlType { + Disabled, + Manual, + Path, +}; + +class Camera : public Feature { +private: + bool manualActive = false; + bool timeOffsetRefresh = true; + int mouseHoldPos[2] = {0,0}; + float timeOffset = 0.0; +public: + CameraControlType controlType = Disabled; + CameraState currentState; + std::map states; + Camera(); + ~Camera(); + bool IsDriving(); + void OverrideView(void* m_View); + float InterpolateStateParam(CameraStateParameter param, float time); + void RequestTimeOffsetRefresh(); + void OverrideMovement(CUserCmd* cmd); +}; + +extern Camera* camera; \ No newline at end of file From 88c6d7f74b1683078f1b55e7ccc76b12e89ecdc2 Mon Sep 17 00:00:00 2001 From: Krzyhau Date: Sun, 26 Apr 2020 14:56:38 +0200 Subject: [PATCH 04/14] refactoring + fov added --- src/Cheats.cpp | 2 +- src/Features/Camera.cpp | 319 +++++++++++++++++++------------ src/Features/Camera.hpp | 14 +- src/Features/FovChanger.cpp | 2 +- src/Features/Tas/AutoStrafer.cpp | 2 +- src/Features/Tas/AutoStrafer.hpp | 2 +- src/Features/WorkshopList.hpp | 2 +- 7 files changed, 212 insertions(+), 131 deletions(-) diff --git a/src/Cheats.cpp b/src/Cheats.cpp index b0c01012..40fc3cc1 100644 --- a/src/Cheats.cpp +++ b/src/Cheats.cpp @@ -66,7 +66,7 @@ CON_COMMAND(sar_togglewait, "Enables or disables \"wait\" for the command buffer { auto state = !*engine->m_bWaitEnabled; *engine->m_bWaitEnabled = *engine->m_bWaitEnabled2 = state; - console->Print("%s wait!\n", (state) ? "Enabled" : "Disabled"); + console->Print("%s wait!\n", (state) ? "Enabled" : "Default"); } // P2, INFRA and HL2 only diff --git a/src/Features/Camera.cpp b/src/Features/Camera.cpp index 7c10eba8..af3d427e 100644 --- a/src/Features/Camera.cpp +++ b/src/Features/Camera.cpp @@ -7,6 +7,7 @@ #include "Modules/Server.hpp" #include "Features/EntityList.hpp" +#include "Features/Timer/PauseTimer.hpp" #include "Command.hpp" #include "Offsets.hpp" @@ -20,55 +21,139 @@ Variable sar_cam_control("sar_cam_control", "0", 0, 2, "1 = Drive mode (camera is separated and can be controlled by user input),\n" "2 = Cinematic mode (camera is controlled by predefined path).\n"); -Variable sar_cam_drive("sar_cam_drive", "0", 0, 1, +Variable sar_cam_drive("sar_cam_drive", "0", 0, 1, "Enables or disables camera drive mode in-game " "(turning it on is not required for demo player)\n"); Variable cl_skip_player_render_in_main_view; Variable r_drawviewmodel; Variable ss_force_primary_fullscreen; -Variable crosshair; + +void ResetCameraRelatedCvars() +{ + cl_skip_player_render_in_main_view.SetValue(cl_skip_player_render_in_main_view.GetString()); + r_drawviewmodel.SetValue(r_drawviewmodel.GetString()); + ss_force_primary_fullscreen.SetValue(ss_force_primary_fullscreen.GetString()); + in_forceuser.SetValue(in_forceuser.GetString()); +} Camera::Camera() { - controlType = Disabled; + controlType = Default; //a bunch of console variables later used in a janky hack cl_skip_player_render_in_main_view = Variable("cl_skip_player_render_in_main_view"); r_drawviewmodel = Variable("r_drawviewmodel"); ss_force_primary_fullscreen = Variable("ss_force_primary_fullscreen"); - crosshair = Variable("crosshair"); } Camera::~Camera() { camera->states.clear(); - - //if (sar_democam_cvar_autochange.GetBool()) { - // cl_skip_player_render_in_main_view.SetValue(1); - // r_drawviewmodel.SetValue(1); - //} + ResetCameraRelatedCvars(); } + + //if in drive mode, checks if player wants to control the camera //for now it requires LMB input (as in demo drive mode) -bool Camera::IsDriving() { +bool Camera::IsDriving() +{ bool drivingInGame = sar_cam_drive.GetBool() && sv_cheats.GetBool() && engine->hoststate->m_activeGame; bool drivingInDemo = engine->demoplayer->IsPlaying(); bool wantingToDrive = inputSystem->IsKeyDown(ButtonCode_t::MOUSE_LEFT); - - return camera->controlType == Manual && wantingToDrive && (drivingInGame || drivingInDemo); + + return camera->controlType == Drive && wantingToDrive && (drivingInGame || drivingInDemo); } -//Calculates demo camera parameter value based on time and predefined path -float Camera::InterpolateStateParam(CameraStateParameter param, float time) + +//used by camera state interpolation function. all the math is here. +float InterpolateCurve(std::vector points, float x, bool dealingWithAngles=false) { enum { FIRST, PREV, NEXT, LAST }; - //reading closest 4 frames + //fixing Y values in case they're angles, for proper interpolation + if (dealingWithAngles) { + float oldY = 0; + for (int i = 0; i < 4; i++) { + float angDif = points[i].y - oldY; + angDif += (angDif > 180) ? -360 : (angDif < -180) ? 360 : 0; + points[i].y = oldY += angDif; + oldY = points[i].y; + } + } + + if (x <= points[PREV].x) + return points[PREV].y; + if (x >= points[NEXT].x) + return points[NEXT].y; + + float t = (x - points[PREV].x) / (points[NEXT].x - points[PREV].x); + + //linear interp. in case you dont want anything cool + //return points[PREV].y + (points[NEXT].y - points[PREV].y) * t; + + //cubic hermite spline... kind of? maybe? no fucking clue, just leave me alone + float t2 = t * t, t3 = t * t * t; + float x0 = (points[FIRST].x - points[PREV].x) / (points[NEXT].x - points[PREV].x); + float x1 = 0, x2 = 1; + float x3 = (points[LAST].x - points[PREV].x) / (points[NEXT].x - points[PREV].x); + float m1 = ((points[NEXT].y - points[PREV].y) / (x2 - x1) + (points[PREV].y - points[FIRST].y) / (x1 - x0)) / 2; + float m2 = ((points[LAST].y - points[NEXT].y) / (x3 - x2) + (points[NEXT].y - points[PREV].y) / (x2 - x1)) / 2; + + return (2 * t3 - 3 * t2 + 1) * points[PREV].y + (t3 - 2 * t2 + t) * m1 + (-2 * t3 + 3 * t2) * points[NEXT].y + (t3 - t2) * m2; +} + + +//creates vector array for specified parameter. it can probably be done in much more elegant way +std::vector CameraStatesToInterpolationPoints(float* x, CameraState* y, CameraStateParameter param) +{ + std::vector points; + for (int i = 0; i < 4; i++) { + Vector v; + v.x = x[i]; + CameraState cs = y[i]; + switch (param) { + case ORIGIN_X: + v.y = cs.origin.x; + break; + case ORIGIN_Y: + v.y = cs.origin.y; + break; + case ORIGIN_Z: + v.y = cs.origin.z; + break; + case ANGLES_X: + v.y = cs.angles.x; + break; + case ANGLES_Y: + v.y = cs.angles.y; + break; + case ANGLES_Z: + v.y = cs.angles.z; + break; + case FOV: + v.y = cs.fov; + break; + } + points.push_back(v); + } + return points; +} + +//Creates interpolated camera state based on states array and given time. +//This is the closest I could get to valve's demo spline camera path +CameraState Camera::InterpolateStates(float time) +{ + enum { FIRST, + PREV, + NEXT, + LAST }; + + //reading 4 frames closest to time float frameTime = time * 60.0f; int frames[4] = { INT_MIN, INT_MIN, INT_MAX, INT_MAX }; for (auto const& state : camera->states) { @@ -89,119 +174,80 @@ float Camera::InterpolateStateParam(CameraStateParameter param, float time) } } - //points for interpolation - Vector points[4]; - - //filling X values + //x values for interpolation + float x[4]; for (int i = 0; i < 4; i++) { - points[i].x = (float)frames[i]; + x[i] = (float)frames[i]; } //making sure all X values are correct before reading Y values, - //"frames" fixed for read, "points" fixed for interpolation. + //"frames" fixed for read, "x" fixed for interpolation. //if there's at least one cam state in the map, none of these should be MIN or MAX after this. if (frames[PREV] == INT_MIN) { - points[PREV].x = (float)frames[NEXT]; + x[PREV] = (float)frames[NEXT]; frames[PREV] = frames[NEXT]; } if (frames[NEXT] == INT_MAX) { - points[NEXT].x = (float)frames[PREV]; + x[NEXT] = (float)frames[PREV]; frames[NEXT] = frames[PREV]; } if (frames[FIRST] == INT_MIN) { - points[FIRST].x = (float)(2 * frames[PREV] - frames[NEXT]); + x[FIRST] = (float)(2 * frames[PREV] - frames[NEXT]); frames[FIRST] = frames[PREV]; } if (frames[LAST] == INT_MAX) { - points[LAST].x = (float)(2 * frames[NEXT] - frames[PREV]); + x[LAST] = (float)(2 * frames[NEXT] - frames[PREV]); frames[LAST] = frames[NEXT]; } - bool workWithAngles = param == ANGLES_X || param == ANGLES_Y || param == ANGLES_Z; - //filling Y values - float oldY = 0; + CameraState y[4]; for (int i = 0; i < 4; i++) { - CameraState state = camera->states[frames[i]]; - switch (param) { - case ANGLES_X: - points[i].y = state.angles.x; - break; - case ANGLES_Y: - points[i].y = state.angles.y; - break; - case ANGLES_Z: - points[i].y = state.angles.z; - break; - case ORIGIN_X: - points[i].y = state.origin.x; - break; - case ORIGIN_Y: - points[i].y = state.origin.y; - break; - case ORIGIN_Z: - points[i].y = state.origin.z; - break; - case FOV: - points[i].y = state.fov; - break; - } - if (workWithAngles) { - float angDif = points[i].y - oldY; - angDif += (angDif > 180) ? -360 : (angDif < -180) ? 360 : 0; - points[i].y = oldY += angDif; - oldY = points[i].y; - } + y[i] = camera->states[frames[i]]; } - if (frameTime <= points[PREV].x) - return points[PREV].y; - if (frameTime >= points[NEXT].x) - return points[NEXT].y; - - float t = (frameTime - points[PREV].x) / (points[NEXT].x - points[PREV].x); - //linear interp. + //interpolating each parameter + CameraState interp; + interp.origin.x = InterpolateCurve(CameraStatesToInterpolationPoints(x, y, ORIGIN_X), frameTime); + interp.origin.y = InterpolateCurve(CameraStatesToInterpolationPoints(x, y, ORIGIN_Y), frameTime); + interp.origin.z = InterpolateCurve(CameraStatesToInterpolationPoints(x, y, ORIGIN_Z), frameTime); + interp.angles.x = InterpolateCurve(CameraStatesToInterpolationPoints(x, y, ANGLES_X), frameTime, true); + interp.angles.y = InterpolateCurve(CameraStatesToInterpolationPoints(x, y, ANGLES_Y), frameTime, true); + interp.angles.z = InterpolateCurve(CameraStatesToInterpolationPoints(x, y, ANGLES_Z), frameTime, true); + interp.fov = InterpolateCurve(CameraStatesToInterpolationPoints(x, y, FOV), frameTime); + + return interp; +} - //return points[PREV].y + (points[NEXT].y - points[PREV].y) * t; - //cubic hermite spline... kind of? maybe? no fucking clue, just leave me alone - float t2 = t * t, t3 = t * t * t; - float x0 = (points[FIRST].x - points[PREV].x) / (points[NEXT].x - points[PREV].x); - float x1 = 0, x2 = 1; - float x3 = (points[LAST].x - points[PREV].x) / (points[NEXT].x - points[PREV].x); - float m1 = ((points[NEXT].y - points[PREV].y) / (x2 - x1) + (points[PREV].y - points[FIRST].y) / (x1 - x0)) / 2; - float m2 = ((points[LAST].y - points[NEXT].y) / (x3 - x2) + (points[NEXT].y - points[PREV].y) / (x2 - x1)) / 2; - - return (2 * t3 - 3 * t2 + 1) * points[PREV].y + (t3 - 2 * t2 + t) * m1 + (-2 * t3 + 3 * t2) * points[NEXT].y + (t3 - t2) * m2; -} //Overrides view. void Camera::OverrideView(void* m_View) { - if (timeOffsetRefresh) { + if (timeOffsetRefreshRequested) { timeOffset = engine->GetClientTime() - engine->demoplayer->GetTick() / 60.0f; - timeOffsetRefresh = false; + timeOffsetRefreshRequested = false; } auto newControlType = static_cast(sar_cam_control.GetInt()); //don't allow cinematic mode outside of demo player - if (!engine->demoplayer->IsPlaying() && newControlType == Path) { - if (controlType != Path) { + if (!engine->demoplayer->IsPlaying() && newControlType == Cinematic) { + if (controlType != Cinematic) { CAMERA_REQUIRE_DEMO_PLAYER_ERROR(); } else { - controlType = Disabled; + controlType = Default; } newControlType = controlType; sar_cam_control.SetValue(controlType); } //don't allow drive mode when not using sv_cheats - if (newControlType == Manual && !sv_cheats.GetBool() && !engine->demoplayer->IsPlaying()) { - if (controlType != Manual) { + if (newControlType == Drive && !sv_cheats.GetBool() && !engine->demoplayer->IsPlaying()) { + if (controlType != Drive) { console->Print("Drive mode requires sv_cheats 1 or demo player.\n"); } else { - controlType = Disabled; + controlType = Default; } newControlType = controlType; sar_cam_control.SetValue(controlType); @@ -210,26 +256,21 @@ void Camera::OverrideView(void* m_View) //janky hack mate //overriding cvar values, boolean (int) values only. //this way the cvar themselves are unchanged - if (newControlType != Disabled) { + if (newControlType != Default) { cl_skip_player_render_in_main_view.ThisPtr()->m_nValue = 0; r_drawviewmodel.ThisPtr()->m_nValue = 0; ss_force_primary_fullscreen.ThisPtr()->m_nValue = 1; - crosshair.ThisPtr()->m_nValue = 0; } //handling camera control type switching if (newControlType != controlType) { - if (controlType == Disabled && newControlType != Disabled) { + if (controlType == Default && newControlType != Default) { //enabling //sorry nothing - } else if (controlType != Disabled && newControlType == Disabled) { + } else if (controlType != Default && newControlType == Default) { //disabling //resetting cvars to their actual values when swithing control off - cl_skip_player_render_in_main_view.SetValue(cl_skip_player_render_in_main_view.GetString()); - r_drawviewmodel.SetValue(r_drawviewmodel.GetString()); - ss_force_primary_fullscreen.SetValue(ss_force_primary_fullscreen.GetString()); - in_forceuser.SetValue(in_forceuser.GetString()); - crosshair.SetValue(crosshair.GetString()); + ResetCameraRelatedCvars(); this->manualActive = false; } controlType = newControlType; @@ -240,15 +281,17 @@ void Camera::OverrideView(void* m_View) //TODO: make CViewSetup struct instead of getting stuff with offsets Vector* origin = reinterpret_cast(static_cast(m_View) + 28); QAngle* angles = reinterpret_cast(static_cast(m_View) + 31); - float* fov = reinterpret_cast(static_cast(m_View) + 20); - if (controlType == Disabled) { + float* fov = reinterpret_cast(static_cast(m_View) + 26); + if (controlType == Default || cameraRefreshRequested) { currentState.origin = (*origin); currentState.angles = (*angles); currentState.fov = (*fov); - } else { - + if (cameraRefreshRequested) + cameraRefreshRequested = false; + } + if (controlType != Default) { //manual camera view control - if (controlType == Manual) { + if (controlType == Drive) { if (IsDriving()) { if (!manualActive) { inputSystem->GetCursorPos(mouseHoldPos[0], mouseHoldPos[1]); @@ -262,7 +305,8 @@ void Camera::OverrideView(void* m_View) } if (manualActive) { //even junkier hack. lock mouse movement using fake in_forceuser 2 LMAO - if(engine->hoststate->m_activeGame)in_forceuser.ThisPtr()->m_nValue = 2; + if (engine->hoststate->m_activeGame) + in_forceuser.ThisPtr()->m_nValue = 2; //getting mouse movement and resetting the cursor position int mX, mY; @@ -271,8 +315,14 @@ void Camera::OverrideView(void* m_View) mY -= mouseHoldPos[1]; inputSystem->SetCursorPos(mouseHoldPos[0], mouseHoldPos[1]); - currentState.angles.x += (float)mY * 0.22f; - currentState.angles.y -= (float)mX * 0.22f; + if (inputSystem->IsKeyDown(ButtonCode_t::MOUSE_RIGHT)) { + //allow fov manipulation + currentState.fov = fminf(fmaxf(currentState.fov + mY * 0.22f, 0.1f), 179.0f); + currentState.angles.z += (float)mX * 0.22f; + } else { + currentState.angles.x += (float)mY * 0.22f; + currentState.angles.y -= (float)mX * 0.22f; + } //limit both values between -180 and 180 currentState.angles.x = remainderf(currentState.angles.x, 360.0f); @@ -316,17 +366,11 @@ void Camera::OverrideView(void* m_View) } } } - if (controlType == Path) { + if (controlType == Cinematic) { //don't do interpolation when there are no points if (states.size() > 0) { float currentTime = engine->GetClientTime() - timeOffset; - currentState.origin.x = InterpolateStateParam(ORIGIN_X, currentTime); - currentState.origin.y = InterpolateStateParam(ORIGIN_Y, currentTime); - currentState.origin.z = InterpolateStateParam(ORIGIN_Z, currentTime); - currentState.angles.x = InterpolateStateParam(ANGLES_X, currentTime); - currentState.angles.y = InterpolateStateParam(ANGLES_Y, currentTime); - currentState.angles.z = InterpolateStateParam(ANGLES_Z, currentTime); - //currentState.fov = InterpolateStateParam(FOV, currentFrameTime); + currentState = InterpolateStates(currentTime); } } //applying custom view @@ -340,7 +384,12 @@ void Camera::OverrideView(void* m_View) void Camera::RequestTimeOffsetRefresh() { - timeOffsetRefresh = true; + timeOffsetRefreshRequested = true; +} + +void Camera::RequestCameraRefresh() +{ + cameraRefreshRequested = true; } void Camera::OverrideMovement(CUserCmd* cmd) @@ -431,7 +480,7 @@ CON_COMMAND(sar_cam_path_getkfs, "sar_cam_path_getkfs : Exports commands for rec if (args.ArgC() == 1) { for (auto const& state : camera->states) { CameraState cam = state.second; - console->Print("sar_democam_setkf %d %f %f %f %f %f %f;\n", state.first, cam.origin.x, cam.origin.y, cam.origin.z, cam.angles.x, cam.angles.y, cam.angles.z); + console->Print("sar_cam_path_setkf %d %f %f %f %f %f %f %f;\n", state.first, cam.origin.x, cam.origin.y, cam.origin.z, cam.angles.x, cam.angles.y, cam.angles.z, cam.fov); } } else { return console->Print(sar_cam_path_getkfs.ThisPtr()->m_pszHelpString); @@ -442,10 +491,14 @@ CON_COMMAND(sar_cam_path_remkf, "sar_cam_path_remkf [frame] : Removes camera pat { CAMERA_REQUIRE_DEMO_PLAYER(); - if (args.ArgC() == 1) { + if (args.ArgC() == 2) { int i = std::atoi(args[1]); - camera->states.erase(i); - console->Print("Camera path keyframe at frame %f removed.\n", args[1]); + if (camera->states.count(i)) { + camera->states.erase(i); + console->Print("Camera path keyframe at frame %d removed.\n", args[1]); + } else { + console->Print("This keyframe does not exist.\n"); + } } else { return console->Print(sar_cam_path_remkf.ThisPtr()->m_pszHelpString); } @@ -463,11 +516,11 @@ CON_COMMAND(sar_cam_path_remkfs, "sar_cam_path_remkfs : Removes all camera path } } -CON_COMMAND(sar_cam_setang, "sar_cam_setang [roll] : Sets camera angle.\n") +CON_COMMAND(sar_cam_setang, "sar_cam_setang [roll] : Sets camera angle (requires camera Drive Mode).\n") { - if (camera->controlType != Manual) { + if (camera->controlType != Drive) { console->Print("Camera not in drive mode! Switching.\n"); - sar_cam_control.SetValue(CameraControlType::Manual); + sar_cam_control.SetValue(CameraControlType::Drive); } if (args.ArgC() == 3 || args.ArgC() == 4) { @@ -483,11 +536,11 @@ CON_COMMAND(sar_cam_setang, "sar_cam_setang [roll] : Sets camera a } } -CON_COMMAND(sar_cam_setpos, "sar_cam_setpos : Sets camera position.\n") +CON_COMMAND(sar_cam_setpos, "sar_cam_setpos : Sets camera position (requires camera Drive Mode).\n") { - if (camera->controlType != Manual) { + if (camera->controlType != Drive) { console->Print("Camera not in drive mode! Switching.\n"); - sar_cam_control.SetValue(CameraControlType::Manual); + sar_cam_control.SetValue(CameraControlType::Drive); } if (args.ArgC() == 4) { @@ -501,4 +554,30 @@ CON_COMMAND(sar_cam_setpos, "sar_cam_setpos : Sets camera position.\ } else { return console->Print(sar_cam_setpos.ThisPtr()->m_pszHelpString); } +} + +CON_COMMAND(sar_cam_setfov, "sar_cam_setfov : Sets camera field of view (requires camera Drive Mode).\n") +{ + if (camera->controlType != Drive) { + console->Print("Camera not in drive mode! Switching.\n"); + sar_cam_control.SetValue(CameraControlType::Drive); + } + + if (args.ArgC() == 2) { + float fov = std::atof(args[1]); + camera->currentState.fov = fov; + } else { + return console->Print(sar_cam_setfov.ThisPtr()->m_pszHelpString); + } +} + +CON_COMMAND(sar_cam_reset, "sar_cam_reset: Resets camera to its default position.\n") +{ + if (args.ArgC() == 1) { + if (camera->controlType == Drive) { + camera->RequestCameraRefresh(); + } + } else { + return console->Print(sar_cam_reset.ThisPtr()->m_pszHelpString); + } } \ No newline at end of file diff --git a/src/Features/Camera.hpp b/src/Features/Camera.hpp index fbdce094..5189c59d 100644 --- a/src/Features/Camera.hpp +++ b/src/Features/Camera.hpp @@ -44,27 +44,29 @@ enum CameraStateParameter { }; enum CameraControlType { - Disabled, - Manual, - Path, + Default, + Drive, + Cinematic, }; class Camera : public Feature { private: bool manualActive = false; - bool timeOffsetRefresh = true; + bool cameraRefreshRequested = false; + bool timeOffsetRefreshRequested = true; int mouseHoldPos[2] = {0,0}; float timeOffset = 0.0; public: - CameraControlType controlType = Disabled; + CameraControlType controlType = Default; CameraState currentState; std::map states; Camera(); ~Camera(); bool IsDriving(); void OverrideView(void* m_View); - float InterpolateStateParam(CameraStateParameter param, float time); + CameraState InterpolateStates(float time); void RequestTimeOffsetRefresh(); + void RequestCameraRefresh(); void OverrideMovement(CUserCmd* cmd); }; diff --git a/src/Features/FovChanger.cpp b/src/Features/FovChanger.cpp index cd608556..422793c9 100644 --- a/src/Features/FovChanger.cpp +++ b/src/Features/FovChanger.cpp @@ -36,7 +36,7 @@ CON_COMMAND_COMPLETION(sar_force_fov, "Forces player FOV. Usage: sar_force_fov < auto fov = std::atoi(args[1]); if (fov == 0) { fovChanger->SetFov(fov); - return console->Print("Disabled forcing FOV!\n"); + return console->Print("Default forcing FOV!\n"); } if (fov < 75 || fov > 150) { diff --git a/src/Features/Tas/AutoStrafer.cpp b/src/Features/Tas/AutoStrafer.cpp index 59f8febc..0357803e 100644 --- a/src/Features/Tas/AutoStrafer.cpp +++ b/src/Features/Tas/AutoStrafer.cpp @@ -188,7 +188,7 @@ CON_COMMAND(sar_tas_strafe_vectorial, "sar_tas_strafe_vectorial : Change t { IGNORE_DEMO_PLAYER(); - auto type = VecStrafeType::Disabled; + auto type = VecStrafeType::Default; if (args.ArgC() == 2) { type = static_cast(std::atoi(args[1])); diff --git a/src/Features/Tas/AutoStrafer.hpp b/src/Features/Tas/AutoStrafer.hpp index 53f032ec..cc118037 100644 --- a/src/Features/Tas/AutoStrafer.hpp +++ b/src/Features/Tas/AutoStrafer.hpp @@ -17,7 +17,7 @@ enum class StrafingType { }; enum class VecStrafeType { - Disabled, + Default, Normal, Visual }; diff --git a/src/Features/WorkshopList.hpp b/src/Features/WorkshopList.hpp index 281a7773..fec27df8 100644 --- a/src/Features/WorkshopList.hpp +++ b/src/Features/WorkshopList.hpp @@ -13,7 +13,7 @@ class WorkshopList : public Feature { public: WorkshopList(); - std::string Path(); + std::string Cinematic(); int Update(); }; From b8a9e59f810713d4c902e0f3358990cfa7717550 Mon Sep 17 00:00:00 2001 From: Krzyhau Date: Sun, 26 Apr 2020 15:02:10 +0200 Subject: [PATCH 05/14] reverting accidental replace --- src/Features/FovChanger.cpp | 2 +- src/Features/Tas/AutoStrafer.cpp | 2 +- src/Features/Tas/AutoStrafer.hpp | 2 +- src/Features/WorkshopList.hpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Features/FovChanger.cpp b/src/Features/FovChanger.cpp index 422793c9..cd608556 100644 --- a/src/Features/FovChanger.cpp +++ b/src/Features/FovChanger.cpp @@ -36,7 +36,7 @@ CON_COMMAND_COMPLETION(sar_force_fov, "Forces player FOV. Usage: sar_force_fov < auto fov = std::atoi(args[1]); if (fov == 0) { fovChanger->SetFov(fov); - return console->Print("Default forcing FOV!\n"); + return console->Print("Disabled forcing FOV!\n"); } if (fov < 75 || fov > 150) { diff --git a/src/Features/Tas/AutoStrafer.cpp b/src/Features/Tas/AutoStrafer.cpp index 0357803e..59f8febc 100644 --- a/src/Features/Tas/AutoStrafer.cpp +++ b/src/Features/Tas/AutoStrafer.cpp @@ -188,7 +188,7 @@ CON_COMMAND(sar_tas_strafe_vectorial, "sar_tas_strafe_vectorial : Change t { IGNORE_DEMO_PLAYER(); - auto type = VecStrafeType::Default; + auto type = VecStrafeType::Disabled; if (args.ArgC() == 2) { type = static_cast(std::atoi(args[1])); diff --git a/src/Features/Tas/AutoStrafer.hpp b/src/Features/Tas/AutoStrafer.hpp index cc118037..53f032ec 100644 --- a/src/Features/Tas/AutoStrafer.hpp +++ b/src/Features/Tas/AutoStrafer.hpp @@ -17,7 +17,7 @@ enum class StrafingType { }; enum class VecStrafeType { - Default, + Disabled, Normal, Visual }; diff --git a/src/Features/WorkshopList.hpp b/src/Features/WorkshopList.hpp index fec27df8..281a7773 100644 --- a/src/Features/WorkshopList.hpp +++ b/src/Features/WorkshopList.hpp @@ -13,7 +13,7 @@ class WorkshopList : public Feature { public: WorkshopList(); - std::string Cinematic(); + std::string Path(); int Update(); }; From eb4352d42f00b7abb707a1c1a48be46784114834 Mon Sep 17 00:00:00 2001 From: Krzyhau Date: Sun, 26 Apr 2020 19:42:09 +0200 Subject: [PATCH 06/14] small changes --- src/Features/Camera.cpp | 28 +++++++++++++++++----------- src/Features/Camera.hpp | 3 --- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/Features/Camera.cpp b/src/Features/Camera.cpp index af3d427e..f5d1037e 100644 --- a/src/Features/Camera.cpp +++ b/src/Features/Camera.cpp @@ -234,7 +234,7 @@ void Camera::OverrideView(void* m_View) //don't allow cinematic mode outside of demo player if (!engine->demoplayer->IsPlaying() && newControlType == Cinematic) { if (controlType != Cinematic) { - CAMERA_REQUIRE_DEMO_PLAYER_ERROR(); + console->Print("Cinematic mode cannot be used outside of demo player.\n"); } else { controlType = Default; } @@ -366,6 +366,7 @@ void Camera::OverrideView(void* m_View) } } } + //cinematic camera - move it along predefined path if (controlType == Cinematic) { //don't do interpolation when there are no points if (states.size() > 0) { @@ -376,8 +377,7 @@ void Camera::OverrideView(void* m_View) //applying custom view *origin = currentState.origin; *angles = currentState.angles; - *fov = currentState.fov; //fov is currently not working, not sure why - //console->Print("%f\n", engine->GetClientTime() - timeOffset); + *fov = currentState.fov; } } } @@ -407,7 +407,8 @@ void Camera::OverrideMovement(CUserCmd* cmd) CON_COMMAND(sar_cam_path_setkf, "sar_cam_path_setkf [frame] [x] [y] [z] [yaw] [pitch] [roll] [fov]: Sets the camera path keyframe.\n") { - CAMERA_REQUIRE_DEMO_PLAYER(); + if (!engine->demoplayer->IsPlaying()) + return console->Print("Cinematic mode cannot be used outside of demo player.\n"); if (args.ArgC() >= 1 && args.ArgC() <= 9) { CameraState campos = camera->currentState; @@ -443,7 +444,8 @@ CON_COMMAND(sar_cam_path_setkf, "sar_cam_path_setkf [frame] [x] [y] [z] [yaw] [p CON_COMMAND(sar_cam_path_showkf, "sar_cam_path_showkf [frame] : Display information about camera path keyframe at specified frame.\n") { - CAMERA_REQUIRE_DEMO_PLAYER(); + if (!engine->demoplayer->IsPlaying()) + return console->Print("Cinematic mode cannot be used outside of demo player.\n"); if (args.ArgC() == 2) { int i = std::atoi(args[1]); @@ -460,7 +462,8 @@ CON_COMMAND(sar_cam_path_showkf, "sar_cam_path_showkf [frame] : Display informat CON_COMMAND(sar_cam_path_showkfs, "sar_cam_path_showkfs : Display information about all camera path keyframes.\n") { - CAMERA_REQUIRE_DEMO_PLAYER(); + if (!engine->demoplayer->IsPlaying()) + return console->Print("Cinematic mode cannot be used outside of demo player.\n"); if (args.ArgC() == 1) { for (auto const& state : camera->states) { @@ -475,7 +478,8 @@ CON_COMMAND(sar_cam_path_showkfs, "sar_cam_path_showkfs : Display information ab CON_COMMAND(sar_cam_path_getkfs, "sar_cam_path_getkfs : Exports commands for recreating currently made camera path.\n") { - CAMERA_REQUIRE_DEMO_PLAYER(); + if (!engine->demoplayer->IsPlaying()) + return console->Print("Cinematic mode cannot be used outside of demo player.\n"); if (args.ArgC() == 1) { for (auto const& state : camera->states) { @@ -489,13 +493,14 @@ CON_COMMAND(sar_cam_path_getkfs, "sar_cam_path_getkfs : Exports commands for rec CON_COMMAND(sar_cam_path_remkf, "sar_cam_path_remkf [frame] : Removes camera path keyframe at specified frame.\n") { - CAMERA_REQUIRE_DEMO_PLAYER(); + if (!engine->demoplayer->IsPlaying()) + return console->Print("Cinematic mode cannot be used outside of demo player.\n"); if (args.ArgC() == 2) { int i = std::atoi(args[1]); if (camera->states.count(i)) { camera->states.erase(i); - console->Print("Camera path keyframe at frame %d removed.\n", args[1]); + console->Print("Camera path keyframe at frame %d removed.\n", i); } else { console->Print("This keyframe does not exist.\n"); } @@ -506,7 +511,8 @@ CON_COMMAND(sar_cam_path_remkf, "sar_cam_path_remkf [frame] : Removes camera pat CON_COMMAND(sar_cam_path_remkfs, "sar_cam_path_remkfs : Removes all camera path keyframes.\n") { - CAMERA_REQUIRE_DEMO_PLAYER(); + if (!engine->demoplayer->IsPlaying()) + return console->Print("Cinematic mode cannot be used outside of demo player.\n"); if (args.ArgC() == 1) { camera->states.clear(); @@ -564,7 +570,7 @@ CON_COMMAND(sar_cam_setfov, "sar_cam_setfov : Sets camera field of view (re } if (args.ArgC() == 2) { - float fov = std::atof(args[1]); + float fov = (float)std::atof(args[1]); camera->currentState.fov = fov; } else { return console->Print(sar_cam_setfov.ThisPtr()->m_pszHelpString); diff --git a/src/Features/Camera.hpp b/src/Features/Camera.hpp index 5189c59d..2c05a683 100644 --- a/src/Features/Camera.hpp +++ b/src/Features/Camera.hpp @@ -9,9 +9,6 @@ #include "Modules/Engine.hpp" -#define CAMERA_REQUIRE_DEMO_PLAYER_ERROR() console->Print("Cinematic mode cannot be used outside of demo player.\n") -#define CAMERA_REQUIRE_DEMO_PLAYER() if (!engine->demoplayer->IsPlaying()) return CAMERA_REQUIRE_DEMO_PLAYER_ERROR() - extern Variable sar_cam_control; extern Variable sar_cam_drive; From 32700a7ddcec1a5c6bb49cfda892990b0b9e8bfb Mon Sep 17 00:00:00 2001 From: Krzyhau Date: Sun, 26 Apr 2020 20:01:49 +0200 Subject: [PATCH 07/14] more bugfixing --- src/Features/Camera.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Features/Camera.cpp b/src/Features/Camera.cpp index f5d1037e..86b6660f 100644 --- a/src/Features/Camera.cpp +++ b/src/Features/Camera.cpp @@ -21,7 +21,7 @@ Variable sar_cam_control("sar_cam_control", "0", 0, 2, "1 = Drive mode (camera is separated and can be controlled by user input),\n" "2 = Cinematic mode (camera is controlled by predefined path).\n"); -Variable sar_cam_drive("sar_cam_drive", "0", 0, 1, +Variable sar_cam_drive("sar_cam_drive", "1", 0, 1, "Enables or disables camera drive mode in-game " "(turning it on is not required for demo player)\n"); @@ -237,6 +237,7 @@ void Camera::OverrideView(void* m_View) console->Print("Cinematic mode cannot be used outside of demo player.\n"); } else { controlType = Default; + ResetCameraRelatedCvars(); } newControlType = controlType; sar_cam_control.SetValue(controlType); @@ -248,6 +249,7 @@ void Camera::OverrideView(void* m_View) console->Print("Drive mode requires sv_cheats 1 or demo player.\n"); } else { controlType = Default; + ResetCameraRelatedCvars(); } newControlType = controlType; sar_cam_control.SetValue(controlType); From b6fc30c4f7712f726f2a6f8edb09934f8585b2b2 Mon Sep 17 00:00:00 2001 From: Krzyhau Date: Sun, 26 Apr 2020 20:05:13 +0200 Subject: [PATCH 08/14] uh oh big whoops --- src/Cheats.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cheats.cpp b/src/Cheats.cpp index 40fc3cc1..b0c01012 100644 --- a/src/Cheats.cpp +++ b/src/Cheats.cpp @@ -66,7 +66,7 @@ CON_COMMAND(sar_togglewait, "Enables or disables \"wait\" for the command buffer { auto state = !*engine->m_bWaitEnabled; *engine->m_bWaitEnabled = *engine->m_bWaitEnabled2 = state; - console->Print("%s wait!\n", (state) ? "Enabled" : "Default"); + console->Print("%s wait!\n", (state) ? "Enabled" : "Disabled"); } // P2, INFRA and HL2 only From 5b1dadd8c4940c717094abd4c88015f15225b9ab Mon Sep 17 00:00:00 2001 From: Krzyhau Date: Mon, 27 Apr 2020 14:57:04 +0200 Subject: [PATCH 09/14] forgot to commit project files lmao --- src/SourceAutoRecord.vcxproj | 2 ++ src/SourceAutoRecord.vcxproj.filters | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/SourceAutoRecord.vcxproj b/src/SourceAutoRecord.vcxproj index f6944ec0..ffff8a0e 100644 --- a/src/SourceAutoRecord.vcxproj +++ b/src/SourceAutoRecord.vcxproj @@ -124,6 +124,7 @@ + @@ -265,6 +266,7 @@ + diff --git a/src/SourceAutoRecord.vcxproj.filters b/src/SourceAutoRecord.vcxproj.filters index 8099f56d..7dbf163a 100644 --- a/src/SourceAutoRecord.vcxproj.filters +++ b/src/SourceAutoRecord.vcxproj.filters @@ -319,6 +319,9 @@ SourceAutoRecord\Features + + SourceAutoRecord\Features + @@ -666,6 +669,9 @@ SourceAutoRecord\Features + + SourceAutoRecord\Features + From 170879a3b8d12a6c40d2a8743ca625d61f950f1a Mon Sep 17 00:00:00 2001 From: Krzyhau Date: Fri, 1 May 2020 18:36:20 +0200 Subject: [PATCH 10/14] IsGamePaused function --- src/Features/Camera.cpp | 3 ++- src/Games/Windows/Portal2.cpp | 1 + src/Modules/Engine.cpp | 6 ++++++ src/Modules/Engine.hpp | 3 +++ src/Offsets.cpp | 1 + src/Offsets.hpp | 1 + 6 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Features/Camera.cpp b/src/Features/Camera.cpp index 86b6660f..d9967e0c 100644 --- a/src/Features/Camera.cpp +++ b/src/Features/Camera.cpp @@ -60,10 +60,11 @@ Camera::~Camera() bool Camera::IsDriving() { bool drivingInGame = sar_cam_drive.GetBool() && sv_cheats.GetBool() && engine->hoststate->m_activeGame; + bool isPaused = engine->IsGamePaused(); bool drivingInDemo = engine->demoplayer->IsPlaying(); bool wantingToDrive = inputSystem->IsKeyDown(ButtonCode_t::MOUSE_LEFT); - return camera->controlType == Drive && wantingToDrive && (drivingInGame || drivingInDemo); + return camera->controlType == Drive && wantingToDrive && (drivingInGame || drivingInDemo) && !isPaused; } diff --git a/src/Games/Windows/Portal2.cpp b/src/Games/Windows/Portal2.cpp index ade9c850..da4ce43d 100644 --- a/src/Games/Windows/Portal2.cpp +++ b/src/Games/Windows/Portal2.cpp @@ -32,6 +32,7 @@ void Portal2::LoadOffsets() viewangles = 19040; // CEngineClient::SetViewAngles GetMaxClients = 20; // CEngineClient GetGameDirectory = 35; // CEngineClient + IsPaused = 86; // CEngineClient GetActiveSplitScreenPlayerSlot = 127; // CEngineClient GetSteamAPIContext = 177; // CEngineClient StringToButtonCode = 31; // CInputSystem diff --git a/src/Modules/Engine.cpp b/src/Modules/Engine.cpp index cd43eb4e..6760ddad 100644 --- a/src/Modules/Engine.cpp +++ b/src/Modules/Engine.cpp @@ -138,6 +138,11 @@ float Engine::GetClientTime() return this->ClientTime(this->engineTool->ThisPtr()); } +bool Engine::IsGamePaused() +{ + return this->IsPaused(this->engineClient->ThisPtr()); +} + // CClientState::Disconnect DETOUR(Engine::Disconnect, bool bShowMainMenu) { @@ -293,6 +298,7 @@ bool Engine::Init() this->SetViewAngles = this->engineClient->Original<_SetViewAngles>(Offsets::SetViewAngles); this->GetMaxClients = this->engineClient->Original<_GetMaxClients>(Offsets::GetMaxClients); this->GetGameDirectory = this->engineClient->Original<_GetGameDirectory>(Offsets::GetGameDirectory); + this->IsPaused = this->engineClient->Original<_IsPaused>(Offsets::IsPaused); Memory::Read<_Cbuf_AddText>((uintptr_t)this->ClientCmd + Offsets::Cbuf_AddText, &this->Cbuf_AddText); Memory::Deref((uintptr_t)this->Cbuf_AddText + Offsets::s_CommandBuffer, &this->s_CommandBuffer); diff --git a/src/Modules/Engine.hpp b/src/Modules/Engine.hpp index 440388f9..94c21d9f 100644 --- a/src/Modules/Engine.hpp +++ b/src/Modules/Engine.hpp @@ -37,6 +37,7 @@ class Engine : public Module { using _GetLocalClient = int (*)(int index); using _HostFrameTime = float (*)(void* thisptr); using _ClientTime = float (*)(void* thisptr); + using _IsPaused = bool (*)(void* thisptr); #ifdef _WIN32 using _GetScreenSize = int(__stdcall*)(int& width, int& height); using _GetActiveSplitScreenPlayerSlot = int (*)(); @@ -67,6 +68,7 @@ class Engine : public Module { _GetLocalClient GetLocalClient = nullptr; _HostFrameTime HostFrameTime = nullptr; _ClientTime ClientTime = nullptr; + _IsPaused IsPaused = nullptr; EngineDemoPlayer* demoplayer = nullptr; EngineDemoRecorder* demorecorder = nullptr; @@ -96,6 +98,7 @@ class Engine : public Module { void SafeUnload(const char* postCommand = nullptr); float GetHostFrameTime(); float GetClientTime(); + bool IsGamePaused(); // CClientState::Disconnect DECL_DETOUR(Disconnect, bool bShowMainMenu); diff --git a/src/Offsets.cpp b/src/Offsets.cpp index 1fb41f4e..370490f8 100644 --- a/src/Offsets.cpp +++ b/src/Offsets.cpp @@ -22,6 +22,7 @@ int GetViewAngles; int SetViewAngles; int GetMaxClients; int ServerCmdKeyValues; +int IsPaused; int GetActiveSplitScreenPlayerSlot; int GetSteamAPIContext; diff --git a/src/Offsets.hpp b/src/Offsets.hpp index 8793601b..4bd63cf5 100644 --- a/src/Offsets.hpp +++ b/src/Offsets.hpp @@ -22,6 +22,7 @@ extern int GetViewAngles; extern int SetViewAngles; extern int GetMaxClients; extern int ServerCmdKeyValues; +extern int IsPaused; extern int GetActiveSplitScreenPlayerSlot; extern int GetSteamAPIContext; From a1b797f7d714098ee5f511445f5cbf8203f93e71 Mon Sep 17 00:00:00 2001 From: Krzyhau Date: Sat, 2 May 2020 15:13:24 +0200 Subject: [PATCH 11/14] autocompletion --- src/Features/Camera.cpp | 85 +++++++++++++++++++++++++++++++++++++---- src/Features/Camera.hpp | 4 +- 2 files changed, 81 insertions(+), 8 deletions(-) diff --git a/src/Features/Camera.cpp b/src/Features/Camera.cpp index d9967e0c..709fde6e 100644 --- a/src/Features/Camera.cpp +++ b/src/Features/Camera.cpp @@ -59,12 +59,11 @@ Camera::~Camera() //for now it requires LMB input (as in demo drive mode) bool Camera::IsDriving() { - bool drivingInGame = sar_cam_drive.GetBool() && sv_cheats.GetBool() && engine->hoststate->m_activeGame; - bool isPaused = engine->IsGamePaused(); + bool drivingInGame = sar_cam_drive.GetBool() && sv_cheats.GetBool() && !engine->IsGamePaused() && engine->hoststate->m_activeGame; bool drivingInDemo = engine->demoplayer->IsPlaying(); bool wantingToDrive = inputSystem->IsKeyDown(ButtonCode_t::MOUSE_LEFT); - return camera->controlType == Drive && wantingToDrive && (drivingInGame || drivingInDemo) && !isPaused; + return camera->controlType == Drive && wantingToDrive && (drivingInGame || drivingInDemo); } @@ -408,7 +407,40 @@ void Camera::OverrideMovement(CUserCmd* cmd) //COMMANDS -CON_COMMAND(sar_cam_path_setkf, "sar_cam_path_setkf [frame] [x] [y] [z] [yaw] [pitch] [roll] [fov]: Sets the camera path keyframe.\n") +DECL_COMMAND_COMPLETION(sar_cam_path_setkf) +{ + for (auto const& state : camera->states) { + if (items.size() == COMMAND_COMPLETION_MAXITEMS) { + break; + } + + char camString[512] = {}; + CameraState cam = state.second; + sprintf(camString, "%d %.0f %.0f %.0f %.0f %.0f %.0f %.0f", + state.first, cam.origin.x, cam.origin.y, cam.origin.z, + cam.angles.x, cam.angles.y, cam.angles.z, cam.fov + ); + + camString[COMMAND_COMPLETION_ITEM_LENGTH - 1 - 19] = '\0'; + std::string camStringString(&camString[0], COMMAND_COMPLETION_ITEM_LENGTH - 19); + + if (std::strlen(match) != std::strlen(cmd)) { + if (std::strstr(camStringString.c_str(), match)) { + items.push_back(camStringString); + } + } else { + items.push_back(camStringString); + } + } + + FINISH_COMMAND_COMPLETION(); +} + +CON_COMMAND_F_COMPLETION( + sar_cam_path_setkf, + "sar_cam_path_setkf [frame] [x] [y] [z] [yaw] [pitch] [roll] [fov]: Sets the camera path keyframe.\n", + 0, AUTOCOMPLETION_FUNCTION(sar_cam_path_setkf) +) { if (!engine->demoplayer->IsPlaying()) return console->Print("Cinematic mode cannot be used outside of demo player.\n"); @@ -445,7 +477,36 @@ CON_COMMAND(sar_cam_path_setkf, "sar_cam_path_setkf [frame] [x] [y] [z] [yaw] [p } } -CON_COMMAND(sar_cam_path_showkf, "sar_cam_path_showkf [frame] : Display information about camera path keyframe at specified frame.\n") +DECL_COMMAND_COMPLETION(sar_cam_path_showkf) +{ + for (auto const& state : camera->states) { + if (items.size() == COMMAND_COMPLETION_MAXITEMS) { + break; + } + + char camString[64] = {}; + CameraState cam = state.second; + sprintf(camString, "%d", state.first); + + std::string camStringString = camString; + + if (std::strlen(match) != std::strlen(cmd)) { + if (std::strstr(camStringString.c_str(), match)) { + items.push_back(camStringString); + } + } else { + items.push_back(camString); + } + } + + FINISH_COMMAND_COMPLETION(); +} + +CON_COMMAND_F_COMPLETION( + sar_cam_path_showkf, + "sar_cam_path_showkf [frame] : Display information about camera path keyframe at specified frame.\n", + 0, AUTOCOMPLETION_FUNCTION(sar_cam_path_showkf) +) { if (!engine->demoplayer->IsPlaying()) return console->Print("Cinematic mode cannot be used outside of demo player.\n"); @@ -487,14 +548,21 @@ CON_COMMAND(sar_cam_path_getkfs, "sar_cam_path_getkfs : Exports commands for rec if (args.ArgC() == 1) { for (auto const& state : camera->states) { CameraState cam = state.second; - console->Print("sar_cam_path_setkf %d %f %f %f %f %f %f %f;\n", state.first, cam.origin.x, cam.origin.y, cam.origin.z, cam.angles.x, cam.angles.y, cam.angles.z, cam.fov); + console->Print("sar_cam_path_setkf %d %f %f %f %f %f %f %f;\n", + state.first, cam.origin.x, cam.origin.y, cam.origin.z, + cam.angles.x, cam.angles.y, cam.angles.z, cam.fov + ); } } else { return console->Print(sar_cam_path_getkfs.ThisPtr()->m_pszHelpString); } } -CON_COMMAND(sar_cam_path_remkf, "sar_cam_path_remkf [frame] : Removes camera path keyframe at specified frame.\n") +CON_COMMAND_F_COMPLETION( + sar_cam_path_remkf, + "sar_cam_path_remkf [frame] : Removes camera path keyframe at specified frame.\n", + 0, AUTOCOMPLETION_FUNCTION(sar_cam_path_showkf) +) { if (!engine->demoplayer->IsPlaying()) return console->Print("Cinematic mode cannot be used outside of demo player.\n"); @@ -525,6 +593,9 @@ CON_COMMAND(sar_cam_path_remkfs, "sar_cam_path_remkfs : Removes all camera path } } + + + CON_COMMAND(sar_cam_setang, "sar_cam_setang [roll] : Sets camera angle (requires camera Drive Mode).\n") { if (camera->controlType != Drive) { diff --git a/src/Features/Camera.hpp b/src/Features/Camera.hpp index 2c05a683..aec4502b 100644 --- a/src/Features/Camera.hpp +++ b/src/Features/Camera.hpp @@ -67,4 +67,6 @@ class Camera : public Feature { void OverrideMovement(CUserCmd* cmd); }; -extern Camera* camera; \ No newline at end of file +extern Camera* camera; + +extern DECL_DECLARE_AUTOCOMPLETION_FUNCTION(sar_cam_path_setkf); \ No newline at end of file From 166a48a9f5b25eb76a32fb74956f2e7503a3fff2 Mon Sep 17 00:00:00 2001 From: Krzyhau Date: Sat, 2 May 2020 19:54:21 +0200 Subject: [PATCH 12/14] pausing and cviewsetup struct (and other stuff i accidentally broke) --- src/Features/Camera.cpp | 74 ++++++++++++++--------------------- src/Features/Camera.hpp | 2 +- src/Games/Windows/Portal2.cpp | 2 +- src/Modules/Client.cpp | 29 ++++++++------ src/Modules/Client.hpp | 2 +- src/Modules/Engine.cpp | 6 --- src/Modules/Engine.hpp | 3 -- src/Modules/VGui.cpp | 6 +++ src/Modules/VGui.hpp | 7 ++++ src/Offsets.cpp | 2 +- src/Offsets.hpp | 2 +- src/Utils/SDK.hpp | 55 ++++++++++++++++++++++++++ 12 files changed, 118 insertions(+), 72 deletions(-) diff --git a/src/Features/Camera.cpp b/src/Features/Camera.cpp index 709fde6e..9b1daa47 100644 --- a/src/Features/Camera.cpp +++ b/src/Features/Camera.cpp @@ -5,6 +5,7 @@ #include "Modules/Engine.hpp" #include "Modules/InputSystem.hpp" #include "Modules/Server.hpp" +#include "Modules/VGui.hpp" #include "Features/EntityList.hpp" #include "Features/Timer/PauseTimer.hpp" @@ -53,22 +54,20 @@ Camera::~Camera() ResetCameraRelatedCvars(); } - - //if in drive mode, checks if player wants to control the camera //for now it requires LMB input (as in demo drive mode) bool Camera::IsDriving() { - bool drivingInGame = sar_cam_drive.GetBool() && sv_cheats.GetBool() && !engine->IsGamePaused() && engine->hoststate->m_activeGame; + bool drivingInGame = sar_cam_drive.GetBool() && sv_cheats.GetBool() && engine->hoststate->m_activeGame; bool drivingInDemo = engine->demoplayer->IsPlaying(); bool wantingToDrive = inputSystem->IsKeyDown(ButtonCode_t::MOUSE_LEFT); + bool isUI = vgui->IsUIVisible(); - return camera->controlType == Drive && wantingToDrive && (drivingInGame || drivingInDemo); + return camera->controlType == Drive && wantingToDrive && (drivingInGame || drivingInDemo) && !isUI; } - //used by camera state interpolation function. all the math is here. -float InterpolateCurve(std::vector points, float x, bool dealingWithAngles=false) +float InterpolateCurve(std::vector points, float x, bool dealingWithAngles = false) { enum { FIRST, PREV, @@ -107,8 +106,7 @@ float InterpolateCurve(std::vector points, float x, bool dealingWithAngl return (2 * t3 - 3 * t2 + 1) * points[PREV].y + (t3 - 2 * t2 + t) * m1 + (-2 * t3 + 3 * t2) * points[NEXT].y + (t3 - t2) * m2; } - -//creates vector array for specified parameter. it can probably be done in much more elegant way +//creates vector array for specified parameter. it can probably be done in much more elegant way std::vector CameraStatesToInterpolationPoints(float* x, CameraState* y, CameraStateParameter param) { std::vector points; @@ -215,14 +213,12 @@ CameraState Camera::InterpolateStates(float time) interp.angles.y = InterpolateCurve(CameraStatesToInterpolationPoints(x, y, ANGLES_Y), frameTime, true); interp.angles.z = InterpolateCurve(CameraStatesToInterpolationPoints(x, y, ANGLES_Z), frameTime, true); interp.fov = InterpolateCurve(CameraStatesToInterpolationPoints(x, y, FOV), frameTime); - + return interp; } - - //Overrides view. -void Camera::OverrideView(void* m_View) +void Camera::OverrideView(CPortalViewSetup1* m_View) { if (timeOffsetRefreshRequested) { timeOffset = engine->GetClientTime() - engine->demoplayer->GetTick() / 60.0f; @@ -280,14 +276,10 @@ void Camera::OverrideView(void* m_View) //don't do anything if not in game or demo player if (engine->hoststate->m_activeGame || engine->demoplayer->IsPlaying()) { - //TODO: make CViewSetup struct instead of getting stuff with offsets - Vector* origin = reinterpret_cast(static_cast(m_View) + 28); - QAngle* angles = reinterpret_cast(static_cast(m_View) + 31); - float* fov = reinterpret_cast(static_cast(m_View) + 26); if (controlType == Default || cameraRefreshRequested) { - currentState.origin = (*origin); - currentState.angles = (*angles); - currentState.fov = (*fov); + currentState.origin = m_View->origin; + currentState.angles = m_View->angles; + currentState.fov = m_View->fov; if (cameraRefreshRequested) cameraRefreshRequested = false; } @@ -377,9 +369,9 @@ void Camera::OverrideView(void* m_View) } } //applying custom view - *origin = currentState.origin; - *angles = currentState.angles; - *fov = currentState.fov; + m_View->origin = currentState.origin; + m_View->angles = currentState.angles; + m_View->fov = currentState.fov; } } } @@ -416,10 +408,9 @@ DECL_COMMAND_COMPLETION(sar_cam_path_setkf) char camString[512] = {}; CameraState cam = state.second; - sprintf(camString, "%d %.0f %.0f %.0f %.0f %.0f %.0f %.0f", - state.first, cam.origin.x, cam.origin.y, cam.origin.z, - cam.angles.x, cam.angles.y, cam.angles.z, cam.fov - ); + sprintf(camString, "%d %.0f %.0f %.0f %.0f %.0f %.0f %.0f", + state.first, cam.origin.x, cam.origin.y, cam.origin.z, + cam.angles.x, cam.angles.y, cam.angles.z, cam.fov); camString[COMMAND_COMPLETION_ITEM_LENGTH - 1 - 19] = '\0'; std::string camStringString(&camString[0], COMMAND_COMPLETION_ITEM_LENGTH - 19); @@ -437,10 +428,9 @@ DECL_COMMAND_COMPLETION(sar_cam_path_setkf) } CON_COMMAND_F_COMPLETION( - sar_cam_path_setkf, - "sar_cam_path_setkf [frame] [x] [y] [z] [yaw] [pitch] [roll] [fov]: Sets the camera path keyframe.\n", - 0, AUTOCOMPLETION_FUNCTION(sar_cam_path_setkf) -) + sar_cam_path_setkf, + "sar_cam_path_setkf [frame] [x] [y] [z] [yaw] [pitch] [roll] [fov]: Sets the camera path keyframe.\n", + 0, AUTOCOMPLETION_FUNCTION(sar_cam_path_setkf)) { if (!engine->demoplayer->IsPlaying()) return console->Print("Cinematic mode cannot be used outside of demo player.\n"); @@ -503,10 +493,9 @@ DECL_COMMAND_COMPLETION(sar_cam_path_showkf) } CON_COMMAND_F_COMPLETION( - sar_cam_path_showkf, - "sar_cam_path_showkf [frame] : Display information about camera path keyframe at specified frame.\n", - 0, AUTOCOMPLETION_FUNCTION(sar_cam_path_showkf) -) + sar_cam_path_showkf, + "sar_cam_path_showkf [frame] : Display information about camera path keyframe at specified frame.\n", + 0, AUTOCOMPLETION_FUNCTION(sar_cam_path_showkf)) { if (!engine->demoplayer->IsPlaying()) return console->Print("Cinematic mode cannot be used outside of demo player.\n"); @@ -548,10 +537,9 @@ CON_COMMAND(sar_cam_path_getkfs, "sar_cam_path_getkfs : Exports commands for rec if (args.ArgC() == 1) { for (auto const& state : camera->states) { CameraState cam = state.second; - console->Print("sar_cam_path_setkf %d %f %f %f %f %f %f %f;\n", - state.first, cam.origin.x, cam.origin.y, cam.origin.z, - cam.angles.x, cam.angles.y, cam.angles.z, cam.fov - ); + console->Print("sar_cam_path_setkf %d %f %f %f %f %f %f %f;\n", + state.first, cam.origin.x, cam.origin.y, cam.origin.z, + cam.angles.x, cam.angles.y, cam.angles.z, cam.fov); } } else { return console->Print(sar_cam_path_getkfs.ThisPtr()->m_pszHelpString); @@ -559,10 +547,9 @@ CON_COMMAND(sar_cam_path_getkfs, "sar_cam_path_getkfs : Exports commands for rec } CON_COMMAND_F_COMPLETION( - sar_cam_path_remkf, - "sar_cam_path_remkf [frame] : Removes camera path keyframe at specified frame.\n", - 0, AUTOCOMPLETION_FUNCTION(sar_cam_path_showkf) -) + sar_cam_path_remkf, + "sar_cam_path_remkf [frame] : Removes camera path keyframe at specified frame.\n", + 0, AUTOCOMPLETION_FUNCTION(sar_cam_path_showkf)) { if (!engine->demoplayer->IsPlaying()) return console->Print("Cinematic mode cannot be used outside of demo player.\n"); @@ -593,9 +580,6 @@ CON_COMMAND(sar_cam_path_remkfs, "sar_cam_path_remkfs : Removes all camera path } } - - - CON_COMMAND(sar_cam_setang, "sar_cam_setang [roll] : Sets camera angle (requires camera Drive Mode).\n") { if (camera->controlType != Drive) { diff --git a/src/Features/Camera.hpp b/src/Features/Camera.hpp index aec4502b..830b0db3 100644 --- a/src/Features/Camera.hpp +++ b/src/Features/Camera.hpp @@ -60,7 +60,7 @@ class Camera : public Feature { Camera(); ~Camera(); bool IsDriving(); - void OverrideView(void* m_View); + void OverrideView(CPortalViewSetup1* m_View); CameraState InterpolateStates(float time); void RequestTimeOffsetRefresh(); void RequestCameraRefresh(); diff --git a/src/Games/Windows/Portal2.cpp b/src/Games/Windows/Portal2.cpp index da4ce43d..472d1d1b 100644 --- a/src/Games/Windows/Portal2.cpp +++ b/src/Games/Windows/Portal2.cpp @@ -32,7 +32,6 @@ void Portal2::LoadOffsets() viewangles = 19040; // CEngineClient::SetViewAngles GetMaxClients = 20; // CEngineClient GetGameDirectory = 35; // CEngineClient - IsPaused = 86; // CEngineClient GetActiveSplitScreenPlayerSlot = 127; // CEngineClient GetSteamAPIContext = 177; // CEngineClient StringToButtonCode = 31; // CInputSystem @@ -51,6 +50,7 @@ void Portal2::LoadOffsets() m_szDemoBaseName = 1344; // CDemoRecorder::StartupDemoFile m_nDemoNumber = 1608; // CDemoRecorder::StartupDemoFile m_bRecording = 1606; // CDemoRecorder::SetSignonState + IsGameUIVisible = 2; //IEngineGui Paint = 14; // CEngineVGui ProcessTick = 1; // CClientState/IServerMessageHandler tickcount = 95; // CClientState::ProcessTick diff --git a/src/Modules/Client.cpp b/src/Modules/Client.cpp index b6085376..12b0202c 100644 --- a/src/Modules/Client.cpp +++ b/src/Modules/Client.cpp @@ -210,22 +210,19 @@ DETOUR(Client::GetButtonBits, bool bResetState) return bits; } -DETOUR_COMMAND(Client::playvideo_end_level_transition) -{ +DETOUR_COMMAND(Client::playvideo_end_level_transition) { console->DevMsg("%s\n", args.m_pArgSBuffer); session->Ended(); return Client::playvideo_end_level_transition_callback(args); } -DETOUR(Client::OverrideView, void* m_View) -{ +DETOUR(Client::OverrideView, CPortalViewSetup1* m_View) { camera->OverrideView(m_View); return Client::OverrideView(thisptr, m_View); } -bool Client::Init() -{ +bool Client::Init() { bool readJmp = false; #ifdef _WIN32 readJmp = sar.game->Is(SourceGame_TheStanleyParable | SourceGame_TheBeginnersGuide); @@ -242,8 +239,8 @@ bool Client::Init() if (sar.game->Is(SourceGame_Portal2)) { auto leaderboard = Command("+leaderboard"); if (!!leaderboard) { - using _GetHud = void*(__cdecl*)(int unk); - using _FindElement = void*(__rescall*)(void* thisptr, const char* pName); + using _GetHud = void* (__cdecl*)(int unk); + using _FindElement = void* (__rescall*)(void* thisptr, const char* pName); auto cc_leaderboard_enable = (uintptr_t)leaderboard.ThisPtr()->m_pCommandCallback; auto GetHud = Memory::Read<_GetHud>(cc_leaderboard_enable + Offsets::GetHud); @@ -271,7 +268,8 @@ bool Client::Init() if (sar.game->Is(SourceGame_TheStanleyParable)) { auto GetButtonBits = g_Input->Original(Offsets::GetButtonBits, readJmp); Memory::Deref(GetButtonBits + Offsets::in_jump, &this->in_jump); - } else if (sar.game->Is(SourceGame_Portal2 | SourceGame_ApertureTag)) { + } + else if (sar.game->Is(SourceGame_Portal2 | SourceGame_ApertureTag)) { in_forceuser = Variable("in_forceuser"); if (!!in_forceuser && this->g_Input) { this->g_Input->Hook(CInput_CreateMove_Hook, CInput_CreateMove, Offsets::GetButtonBits + 1); @@ -279,7 +277,8 @@ bool Client::Init() Command::Hook("playvideo_end_level_transition", Client::playvideo_end_level_transition_callback_hook, Client::playvideo_end_level_transition_callback); } - } else { + } + else { g_Input->Hook(Client::DecodeUserCmdFromBuffer2_Hook, Client::DecodeUserCmdFromBuffer2, Offsets::DecodeUserCmdFromBuffer); } } @@ -293,18 +292,22 @@ bool Client::Init() auto g_pClientMode = Memory::Deref(GetClientMode + Offsets::g_pClientMode); clientMode = Memory::Deref(g_pClientMode); clientMode2 = Memory::Deref(g_pClientMode + sizeof(void*)); - } else { + } + else { typedef void* (*_GetClientMode)(); auto GetClientMode = Memory::Read<_GetClientMode>(HudProcessInput + Offsets::GetClientMode); clientMode = GetClientMode(); } - } else if (sar.game->Is(SourceGame_HalfLife2Engine)) { + } + else if (sar.game->Is(SourceGame_HalfLife2Engine)) { clientMode = Memory::DerefDeref(HudProcessInput + Offsets::GetClientMode); } if (this->g_pClientMode = Interface::Create(clientMode)) { this->g_pClientMode->Hook(Client::CreateMove_Hook, Client::CreateMove, Offsets::CreateMove); - this->g_pClientMode->Hook(Client::OverrideView_Hook, Client::OverrideView, Offsets::OverrideView); + if (sar.game->Is(SourceGame_Portal2Engine)) { + this->g_pClientMode->Hook(Client::OverrideView_Hook, Client::OverrideView, Offsets::OverrideView); + } } if (this->g_pClientMode2 = Interface::Create(clientMode2)) { diff --git a/src/Modules/Client.hpp b/src/Modules/Client.hpp index 842a8442..74ab077e 100644 --- a/src/Modules/Client.hpp +++ b/src/Modules/Client.hpp @@ -61,7 +61,7 @@ class Client : public Module { DECL_DETOUR(GetButtonBits, bool bResetState); // ClientModeShared::OverrideView - DECL_DETOUR(OverrideView, void* m_View); + DECL_DETOUR(OverrideView, CPortalViewSetup1* m_View); DECL_DETOUR_COMMAND(playvideo_end_level_transition); diff --git a/src/Modules/Engine.cpp b/src/Modules/Engine.cpp index 6760ddad..cd43eb4e 100644 --- a/src/Modules/Engine.cpp +++ b/src/Modules/Engine.cpp @@ -138,11 +138,6 @@ float Engine::GetClientTime() return this->ClientTime(this->engineTool->ThisPtr()); } -bool Engine::IsGamePaused() -{ - return this->IsPaused(this->engineClient->ThisPtr()); -} - // CClientState::Disconnect DETOUR(Engine::Disconnect, bool bShowMainMenu) { @@ -298,7 +293,6 @@ bool Engine::Init() this->SetViewAngles = this->engineClient->Original<_SetViewAngles>(Offsets::SetViewAngles); this->GetMaxClients = this->engineClient->Original<_GetMaxClients>(Offsets::GetMaxClients); this->GetGameDirectory = this->engineClient->Original<_GetGameDirectory>(Offsets::GetGameDirectory); - this->IsPaused = this->engineClient->Original<_IsPaused>(Offsets::IsPaused); Memory::Read<_Cbuf_AddText>((uintptr_t)this->ClientCmd + Offsets::Cbuf_AddText, &this->Cbuf_AddText); Memory::Deref((uintptr_t)this->Cbuf_AddText + Offsets::s_CommandBuffer, &this->s_CommandBuffer); diff --git a/src/Modules/Engine.hpp b/src/Modules/Engine.hpp index 94c21d9f..440388f9 100644 --- a/src/Modules/Engine.hpp +++ b/src/Modules/Engine.hpp @@ -37,7 +37,6 @@ class Engine : public Module { using _GetLocalClient = int (*)(int index); using _HostFrameTime = float (*)(void* thisptr); using _ClientTime = float (*)(void* thisptr); - using _IsPaused = bool (*)(void* thisptr); #ifdef _WIN32 using _GetScreenSize = int(__stdcall*)(int& width, int& height); using _GetActiveSplitScreenPlayerSlot = int (*)(); @@ -68,7 +67,6 @@ class Engine : public Module { _GetLocalClient GetLocalClient = nullptr; _HostFrameTime HostFrameTime = nullptr; _ClientTime ClientTime = nullptr; - _IsPaused IsPaused = nullptr; EngineDemoPlayer* demoplayer = nullptr; EngineDemoRecorder* demorecorder = nullptr; @@ -98,7 +96,6 @@ class Engine : public Module { void SafeUnload(const char* postCommand = nullptr); float GetHostFrameTime(); float GetClientTime(); - bool IsGamePaused(); // CClientState::Disconnect DECL_DETOUR(Disconnect, bool bShowMainMenu); diff --git a/src/Modules/VGui.cpp b/src/Modules/VGui.cpp index a3d6a1bf..1ba0aef2 100644 --- a/src/Modules/VGui.cpp +++ b/src/Modules/VGui.cpp @@ -66,10 +66,16 @@ DETOUR(VGui::Paint, PaintMode_t mode) return result; } +bool VGui::IsUIVisible(){ + return this->IsGameUIVisible(this->enginevgui->ThisPtr()); +} + bool VGui::Init() { this->enginevgui = Interface::Create(this->Name(), "VEngineVGui0"); if (this->enginevgui) { + this->IsGameUIVisible = this->enginevgui->Original<_IsGameUIVisible>(Offsets::IsGameUIVisible); + this->enginevgui->Hook(VGui::Paint_Hook, VGui::Paint, Offsets::Paint); for (auto& hud : Hud::GetList()) { diff --git a/src/Modules/VGui.hpp b/src/Modules/VGui.hpp index 6342c00e..82cde36d 100644 --- a/src/Modules/VGui.hpp +++ b/src/Modules/VGui.hpp @@ -24,6 +24,13 @@ class VGui : public Module { void Draw(HudElement* const& element); public: + + using _IsGameUIVisible = bool(__rescall*)(void* thisptr); + + _IsGameUIVisible IsGameUIVisible = nullptr; + + bool IsUIVisible(); + // CEngineVGui::Paint DECL_DETOUR(Paint, PaintMode_t mode); diff --git a/src/Offsets.cpp b/src/Offsets.cpp index 370490f8..d8787e82 100644 --- a/src/Offsets.cpp +++ b/src/Offsets.cpp @@ -22,7 +22,6 @@ int GetViewAngles; int SetViewAngles; int GetMaxClients; int ServerCmdKeyValues; -int IsPaused; int GetActiveSplitScreenPlayerSlot; int GetSteamAPIContext; @@ -124,6 +123,7 @@ int m_pSurfaceData; int iNumPortalsPlaced; // IEngineVGuiInternal +int IsGameUIVisible; int Paint; // CEngineTool diff --git a/src/Offsets.hpp b/src/Offsets.hpp index 4bd63cf5..1c605d98 100644 --- a/src/Offsets.hpp +++ b/src/Offsets.hpp @@ -22,7 +22,6 @@ extern int GetViewAngles; extern int SetViewAngles; extern int GetMaxClients; extern int ServerCmdKeyValues; -extern int IsPaused; extern int GetActiveSplitScreenPlayerSlot; extern int GetSteamAPIContext; @@ -124,6 +123,7 @@ extern int m_pSurfaceData; extern int iNumPortalsPlaced; // IEngineVGuiInternal +extern int IsGameUIVisible; extern int Paint; // CEngineTool diff --git a/src/Utils/SDK.hpp b/src/Utils/SDK.hpp index b5d84bda..71dc0c6b 100644 --- a/src/Utils/SDK.hpp +++ b/src/Utils/SDK.hpp @@ -918,3 +918,58 @@ enum PaintMode_t { PAINT_UIPANELS = (1 << 0), PAINT_INGAMEPANELS = (1 << 1), }; + +struct CPortalViewSetup1 { + int x; + int m_nUnscaledX; + int y; + int m_nUnscaledY; + int width; + int m_nUnscaledWidth; + int height; + int m_nUnscaledHeight; + bool m_bOrtho; + float m_OrthoLeft; + float m_OrthoTop; + float m_OrthoRight; + float m_OrthoBottom; + bool m_bCustomViewMatrix; + float m_matCustomViewMatrix[3][4]; + float fov; + float fovViewmodel; + Vector origin; + QAngle angles; + + //TODO: stuff below not tested - verify + float zNear; + float zFar; + float zNearViewmodel; + float zFarViewmodel; + float m_flAspectRatio; + float m_flNearBlurDepth; + float m_flNearFocusDepth; + float m_flFarFocusDepth; + float m_flFarBlurDepth; + float m_flNearBlurRadius; + float m_flFarBlurRadius; + int m_nDoFQuality; + int m_nMotionBlurMode; + float m_flShutterTime; + Vector m_vShutterOpenPosition; + QAngle m_shutterOpenAngles; + Vector m_vShutterClosePosition; + QAngle m_shutterCloseAngles; + float m_flOffCenterTop; + float m_flOffCenterBottom; + float m_flOffCenterLeft; + float m_flOffCenterRight; + bool m_bOffCenter : 1; + bool m_bRenderToSubrectOfLargerScreen : 1; + bool m_bDoBloomAndToneMapping : 1; + bool m_bDoDepthOfField : 1; + bool m_bHDRTarget : 1; + bool m_bDrawWorldNormal : 1; + bool m_bCullFrontFaces : 1; + bool m_bCacheFullSceneState : 1; + bool m_bCSMView : 1; +}; From ae0c4431c5d628a8f493bc769bd3bb1da9b35287 Mon Sep 17 00:00:00 2001 From: Krzyhau Date: Tue, 10 Nov 2020 23:31:20 +0100 Subject: [PATCH 13/14] linux support --- src/Games/Linux/Portal2.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Games/Linux/Portal2.cpp b/src/Games/Linux/Portal2.cpp index 11a30db2..4e619c8c 100644 --- a/src/Games/Linux/Portal2.cpp +++ b/src/Games/Linux/Portal2.cpp @@ -36,6 +36,9 @@ void Portal2::LoadOffsets() GetSteamAPIContext = 178; // CEngineClient StringToButtonCode = 31; // CInputSystem SleepUntilInput = 33; // CInputSystem + IsButtonDown = 14; //CInputSystem + GetCursorPosition = 45; //CInputSystem + SetCursorPosition = 38; //CInputSystem GetRecordingTick = 1; // CDemoRecorder net_time = 28; // CDemoRecorder::GetRecordingTick SetSignonState = 3; // CDemoRecorder @@ -47,6 +50,7 @@ void Portal2::LoadOffsets() m_szDemoBaseName = 1344; // CDemoRecorder::StartupDemoFile m_nDemoNumber = 1608; // CDemoRecorder::StartupDemoFile m_bRecording = 1606; // CDemoRecorder::SetSignonState + IsGameUIVisible = 2; // IEngineGui Paint = 15; // CEngineVGui ProcessTick = 12; // CClientState tickcount = 73; // CClientState::ProcessTick @@ -57,6 +61,8 @@ void Portal2::LoadOffsets() demoplayer = 93; // CClientState::Disconnect demorecorder = 106; // CClientState::Disconnect GetCurrentMap = 26; // CEngineTool + HostFrameTime = 40; //CEngineTool + ClientTime = 48; //CEngineTool m_szLevelName = 72; // CEngineTool::GetCurrentMap AddListener = 4; // CGameEventManager RemoveListener = 6; // CGameEventManager @@ -146,6 +152,7 @@ void Portal2::LoadOffsets() JoyStickApplyMovement = 64; // CInput KeyDown = 295; // CInput::JoyStickApplyMovement KeyUp = 341; // CInput::JoyStickApplyMovement + OverrideView = 19; // ClientModeShared // vguimatsurface.so From 1685366a2d4a248c47276d511858e9df4f59f979 Mon Sep 17 00:00:00 2001 From: Krzyhau Date: Tue, 10 Nov 2020 23:35:58 +0100 Subject: [PATCH 14/14] reverting weird white chars changes --- src/Modules/Client.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/Modules/Client.cpp b/src/Modules/Client.cpp index 12b0202c..9b0f0c00 100644 --- a/src/Modules/Client.cpp +++ b/src/Modules/Client.cpp @@ -210,19 +210,22 @@ DETOUR(Client::GetButtonBits, bool bResetState) return bits; } -DETOUR_COMMAND(Client::playvideo_end_level_transition) { +DETOUR_COMMAND(Client::playvideo_end_level_transition) +{ console->DevMsg("%s\n", args.m_pArgSBuffer); session->Ended(); return Client::playvideo_end_level_transition_callback(args); } -DETOUR(Client::OverrideView, CPortalViewSetup1* m_View) { +DETOUR(Client::OverrideView, CPortalViewSetup1* m_View) +{ camera->OverrideView(m_View); return Client::OverrideView(thisptr, m_View); } -bool Client::Init() { +bool Client::Init() +{ bool readJmp = false; #ifdef _WIN32 readJmp = sar.game->Is(SourceGame_TheStanleyParable | SourceGame_TheBeginnersGuide); @@ -239,8 +242,8 @@ bool Client::Init() { if (sar.game->Is(SourceGame_Portal2)) { auto leaderboard = Command("+leaderboard"); if (!!leaderboard) { - using _GetHud = void* (__cdecl*)(int unk); - using _FindElement = void* (__rescall*)(void* thisptr, const char* pName); + using _GetHud = void*(__cdecl*)(int unk); + using _FindElement = void*(__rescall*)(void* thisptr, const char* pName); auto cc_leaderboard_enable = (uintptr_t)leaderboard.ThisPtr()->m_pCommandCallback; auto GetHud = Memory::Read<_GetHud>(cc_leaderboard_enable + Offsets::GetHud); @@ -268,8 +271,7 @@ bool Client::Init() { if (sar.game->Is(SourceGame_TheStanleyParable)) { auto GetButtonBits = g_Input->Original(Offsets::GetButtonBits, readJmp); Memory::Deref(GetButtonBits + Offsets::in_jump, &this->in_jump); - } - else if (sar.game->Is(SourceGame_Portal2 | SourceGame_ApertureTag)) { + } else if (sar.game->Is(SourceGame_Portal2 | SourceGame_ApertureTag)) { in_forceuser = Variable("in_forceuser"); if (!!in_forceuser && this->g_Input) { this->g_Input->Hook(CInput_CreateMove_Hook, CInput_CreateMove, Offsets::GetButtonBits + 1); @@ -277,8 +279,7 @@ bool Client::Init() { Command::Hook("playvideo_end_level_transition", Client::playvideo_end_level_transition_callback_hook, Client::playvideo_end_level_transition_callback); } - } - else { + } else { g_Input->Hook(Client::DecodeUserCmdFromBuffer2_Hook, Client::DecodeUserCmdFromBuffer2, Offsets::DecodeUserCmdFromBuffer); } } @@ -292,14 +293,12 @@ bool Client::Init() { auto g_pClientMode = Memory::Deref(GetClientMode + Offsets::g_pClientMode); clientMode = Memory::Deref(g_pClientMode); clientMode2 = Memory::Deref(g_pClientMode + sizeof(void*)); - } - else { + } else { typedef void* (*_GetClientMode)(); auto GetClientMode = Memory::Read<_GetClientMode>(HudProcessInput + Offsets::GetClientMode); clientMode = GetClientMode(); } - } - else if (sar.game->Is(SourceGame_HalfLife2Engine)) { + } else if (sar.game->Is(SourceGame_HalfLife2Engine)) { clientMode = Memory::DerefDeref(HudProcessInput + Offsets::GetClientMode); }