From e4fd85d110e4a15f31c3cd92acfff35c6001a728 Mon Sep 17 00:00:00 2001 From: evanlin96069 <72735402+evanlin96069@users.noreply.github.com> Date: Sat, 25 Apr 2026 14:48:35 -0400 Subject: [PATCH 1/2] Fix GetPlayerMins/Maxs signature --- spt/features/tracing.cpp | 12 ++++++------ spt/features/tracing.hpp | 6 ++++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/spt/features/tracing.cpp b/spt/features/tracing.cpp index d014449c0..ba0a06f8c 100644 --- a/spt/features/tracing.cpp +++ b/spt/features/tracing.cpp @@ -482,24 +482,24 @@ bool Tracing::ShouldLoadFeature() void Tracing::UnloadFeature() {} #if defined(SSDK2013) -IMPL_HOOK_THISCALL(Tracing, void, CGameMovement__GetPlayerMins, IGameMovement*, Vector* out) +IMPL_HOOK_THISCALL(Tracing, Vector*, CGameMovement__GetPlayerMins, IGameMovement*, Vector* out) { if (spt_tracing.overrideMinMax) { *out = spt_tracing._mins; + return out; } - else - spt_tracing.ORIG_CGameMovement__GetPlayerMins(thisptr, out); + return spt_tracing.ORIG_CGameMovement__GetPlayerMins(thisptr, out); } -IMPL_HOOK_THISCALL(Tracing, void, CGameMovement__GetPlayerMaxs, IGameMovement*, Vector* out) +IMPL_HOOK_THISCALL(Tracing, Vector*, CGameMovement__GetPlayerMaxs, IGameMovement*, Vector* out) { if (spt_tracing.overrideMinMax) { *out = spt_tracing._maxs; + return out; } - else - spt_tracing.ORIG_CGameMovement__GetPlayerMaxs(thisptr, out); + return spt_tracing.ORIG_CGameMovement__GetPlayerMaxs(thisptr, out); } #else IMPL_HOOK_THISCALL(Tracing, const Vector&, CGameMovement__GetPlayerMins, IGameMovement*) diff --git a/spt/features/tracing.hpp b/spt/features/tracing.hpp index f615e49c5..1716e8013 100644 --- a/spt/features/tracing.hpp +++ b/spt/features/tracing.hpp @@ -175,8 +175,10 @@ class Tracing : public FeatureWrapper trace_t& pm); #if defined(SSDK2013) - DECL_HOOK_THISCALL(void, CGameMovement__GetPlayerMins, IGameMovement*, Vector*); - DECL_HOOK_THISCALL(void, CGameMovement__GetPlayerMaxs, IGameMovement*, Vector*); + // virtual Vector GetPlayerMins( void ) const; + DECL_HOOK_THISCALL(Vector*, CGameMovement__GetPlayerMins, IGameMovement*, Vector*); + // virtual Vector GetPlayerMaxs( void ) const; + DECL_HOOK_THISCALL(Vector*, CGameMovement__GetPlayerMaxs, IGameMovement*, Vector*); #else DECL_HOOK_THISCALL(const Vector&, CGameMovement__GetPlayerMins, IGameMovement*); DECL_HOOK_THISCALL(const Vector&, CGameMovement__GetPlayerMaxs, IGameMovement*); From 37f75e6249a4d8a38edb8cd9de99186c0ddf6e81 Mon Sep 17 00:00:00 2001 From: evanlin96069 <72735402+evanlin96069@users.noreply.github.com> Date: Sat, 25 Apr 2026 14:48:46 -0400 Subject: [PATCH 2/2] Add spt_disable_portal_roll_offset --- spt/features/game_fixes/visual_fixes.cpp | 32 ++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/spt/features/game_fixes/visual_fixes.cpp b/spt/features/game_fixes/visual_fixes.cpp index 7aad510c2..f92dccf23 100644 --- a/spt/features/game_fixes/visual_fixes.cpp +++ b/spt/features/game_fixes/visual_fixes.cpp @@ -3,6 +3,7 @@ #include "..\feature.hpp" #include "convar.hpp" #include "ent_utils.hpp" +#include "game_detection.hpp" #include "signals.hpp" #include "..\visualizations\imgui\imgui_interface.hpp" #include "spt\utils\ent_list.hpp" @@ -44,6 +45,10 @@ ConVar spt_disable_render_delay("spt_disable_render_delay", 0, "Removes the 0.25s render delay after load.", RenderDelayCVarCallback); +ConVar spt_disable_portal_roll_offset("spt_disable_portal_roll_offset", + "0", + 0, + "Removes the roll offset applied to the camera in Portal."); // Misc visual fixes class VisualFixes : public FeatureWrapper @@ -92,6 +97,9 @@ class VisualFixes : public FeatureWrapper const Vector& eyePosition, const QAngle& eyeAngles); + // Vector EyeFootPosition( const QAngle &qEyeAngles ); + DECL_HOOK_THISCALL(Vector*, C_Portal_Player__EyeFootPosition, void*, Vector* out, QAngle* qEyeAngles); + void OnFinishRestore(void* thisptr); }; @@ -169,6 +177,8 @@ namespace patterns "83 3D ?? ?? ?? ?? 01 75 ?? 8B 0D ?? ?? ?? ?? 8B 11", "7122284", "83 3D ?? ?? ?? ?? 01 75 ?? 8B 0D ?? ?? ?? ?? 8B 01 8B 40 ?? FF D0 84 C0 75 ?? F3 0F 10 05 ?? ?? ?? ??"); + // TODO: Steampipe support. This function is inlined in 7122284. + PATTERNS(C_Portal_Player__EyeFootPosition, "5135", "83 EC 18 8B 44 24 ?? D9 40 ?? 8D 54 24 ?? D9 E1 52"); } // namespace patterns void VisualFixes::InitHooks() @@ -183,6 +193,11 @@ void VisualFixes::InitHooks() FIND_PATTERN(client, CAM_ToThirdPerson); HOOK_FUNCTION(client, C_BaseViewModel__CalcViewModelView); FIND_PATTERN(engine, MiddleOfCL_FullyConnected); + + if (utils::DoesGameLookLikePortal()) + { + HOOK_FUNCTION(client, C_Portal_Player__EyeFootPosition); + } } bool VisualFixes::ShouldLoadFeature() @@ -272,6 +287,11 @@ void VisualFixes::LoadFeature() InitConcommandBase(spt_disable_render_delay); } + if (ORIG_C_Portal_Player__EyeFootPosition) + { + InitConcommandBase(spt_disable_portal_roll_offset); + } + SptImGuiGroup::QoL_Visual.RegisterUserCallback( []() { @@ -279,6 +299,7 @@ void VisualFixes::LoadFeature() SptImGui::CvarCheckbox(y_spt_disable_shake, "##checkbox_shake"); SptImGui::CvarCheckbox(y_spt_disable_tone_map_reset, "##checkbox_tone_map"); SptImGui::CvarCheckbox(spt_disable_render_delay, "##checkbox_render_delay"); + SptImGui::CvarCheckbox(spt_disable_portal_roll_offset, "##checkbox_portal_roll_offset"); SptImGui::CvarInputTextInteger(y_spt_override_tpose, "T-pose sequence override", ""); ConVar* cvars[] = {&spt_viewmodel_offset_x, &spt_viewmodel_offset_y, &spt_viewmodel_offset_z}; @@ -373,6 +394,17 @@ IMPL_HOOK_THISCALL(VisualFixes, spt_visual_fixes.ORIG_C_BaseViewModel__CalcViewModelView(thisptr, owner, vmorigin, eyeAngles); } +IMPL_HOOK_THISCALL(VisualFixes, Vector*, C_Portal_Player__EyeFootPosition, void*, Vector* out, QAngle* qEyeAngles) +{ + if (spt_disable_portal_roll_offset.GetBool()) + { + *out = utils::GetPlayerEyePosition(); + return out; + } + + return spt_visual_fixes.ORIG_C_Portal_Player__EyeFootPosition(thisptr, out, qEyeAngles); +} + void VisualFixes::OnFinishRestore(void* thisptr) { // I have no idea what this flag is, but setting it unconditionally seems to