Skip to content

Commit 94adda6

Browse files
committed
feat: make tas raw interpolation less invasive
in order to avoid potential playback issues, since this feature is purely for presentational purposes, it has been modified to override client-side behaviour to take those extra mouse samples into account, without affecting server simulation at all. ...also the previous implementation was straight up bugged lmao
1 parent 99f1d31 commit 94adda6

5 files changed

Lines changed: 36 additions & 29 deletions

File tree

docs/cvars.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@
633633
|sar_tas_stop|cmd|sar_tas_stop - stop TAS playing|
634634
|sar_tas_tools_enabled|1|Enables tool processing for TAS script making.|
635635
|sar_tas_tools_force|0|Force tool playback for TAS scripts; primarily for debugging.|
636-
|sar_tas_use_raw_interpolation|0|Allows TAS controller to perform extra mouse samples to make camera movement more smooth. Can affect raw playback outcome!|
636+
|sar_tas_use_raw_interpolation|1|Overrides camera and viewmodel to use offset based on extra mouse samples during raw TAS playback.|
637637
|sar_teleport|cmd|sar_teleport [noportals] - teleports the player to the last saved location|
638638
|sar_teleport_setpos|cmd|sar_teleport_setpos - saves current location for teleportation|
639639
|sar_tick_debug|0|Output debugging information to the console related to ticks and frames.|

src/Features/Camera.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,12 @@ void Camera::OverrideView(ViewSetup *m_View) {
405405
float real_frame_time = std::chrono::duration_cast<std::chrono::duration<float>>(now - last_frame).count();
406406
last_frame = now;
407407

408+
if (tasPlayer->IsRunning() && !tasPlayer->IsUsingTools() && sar_tas_use_raw_interpolation.GetBool()) {
409+
auto offset = tasControllers[GET_SLOT()]->GetExtraMouseSamplesAngles();
410+
m_View->angles.x += offset.x;
411+
m_View->angles.y += offset.y;
412+
}
413+
408414
if (sar_cam_force_eye_pos.GetBool() && sv_cheats.GetBool()) {
409415
Vector eyePos;
410416
QAngle eyeAng;

src/Features/Tas/TasController.cpp

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const int g_TasControllerInGameButtons[] = {
1919
};
2020

2121
Variable sar_tas_real_controller_debug("sar_tas_real_controller_debug", "0", 0, 4, "Debugs controller.\n");
22-
Variable sar_tas_use_raw_interpolation("sar_tas_use_raw_interpolation", "0", "Allows TAS controller to perform extra mouse samples to make camera movement more smooth. Can affect raw playback outcome!\n");
22+
Variable sar_tas_use_raw_interpolation("sar_tas_use_raw_interpolation", "1", "Overrides camera and viewmodel to use offset based on extra mouse samples during raw TAS playback.\n");
2323

2424
TasController *tasControllers[2];
2525

@@ -108,12 +108,18 @@ void TasController::SetButtonState(TasControllerInput i, bool state) {
108108
btn->state = state;
109109
}
110110

111+
QAngle TasController::GetExtraMouseSamplesAngles() {
112+
// setting those to set angles is tricky and breaks compability, we can thank
113+
// altticks and floating point arithmetics for that. Instead, we're overriding
114+
// client-side behaviour only to simply make raw present better.
115+
return extraMouseSamplesAngles;
116+
}
117+
111118
std::chrono::time_point<std::chrono::high_resolution_clock> g_lastControllerMove;
112119

113120
void TasController::ControllerMove(int nSlot, float flFrametime, CUserCmd *cmd) {
114121
// ControllerMove is executed several times for one tick. Most of them
115122
// are called from ExtraMouseSamples with 0 tick count. We want to filter them out.
116-
bool wasInExtraMouseSamples = inExtraMouseSamples;
117123
inExtraMouseSamples = cmd->tick_count == 0;
118124

119125
// doing some debugs to test the behaviour of the real controller
@@ -142,29 +148,19 @@ void TasController::ControllerMove(int nSlot, float flFrametime, CUserCmd *cmd)
142148

143149
//console->Print("TasController::ControllerMove (%d, ", cmd->tick_count);
144150

145-
if (!sar_tas_use_raw_interpolation.GetBool()) {
146-
// without raw interpolation, treat is as if extra mouse samples never happened
147-
wasInExtraMouseSamples = false;
148-
if (inExtraMouseSamples) {
149-
return;
150-
}
151-
}
152-
153-
if (inExtraMouseSamples && !tasPlayer->IsUsingTools()) {
154-
if (!wasInExtraMouseSamples) {
155-
viewanglesPreExtraMouseSamples = engine->GetAngles(nSlot);
156-
}
157-
151+
if (!inExtraMouseSamples) {
152+
extraMouseSamplesAccumulatedTime = 0.0f;
153+
extraMouseSamplesAngles = QAngle();
154+
} else if (sar_tas_use_raw_interpolation.GetBool()) {
158155
extraMouseSamplesAccumulatedTime += flFrametime;
159156

160157
auto extraViewAnalog = tasPlayer->FetchRawExtraViewAnalog(nSlot, extraMouseSamplesAccumulatedTime);
161-
ApplyViewAnalog(nSlot, nullptr, extraViewAnalog, true);
162-
163-
return;
158+
extraMouseSamplesAngles.x = -extraViewAnalog.y;
159+
extraMouseSamplesAngles.y = -extraViewAnalog.x;
164160
}
165161

166-
if (wasInExtraMouseSamples) {
167-
extraMouseSamplesAccumulatedTime = 0.0f;
162+
if (inExtraMouseSamples) {
163+
return; // further controller logic should happen only during ticks, not extra mouse samples
168164
}
169165

170166
tasPlayer->FetchInputs(nSlot, this, cmd);
@@ -224,7 +220,7 @@ void TasController::ControllerMove(int nSlot, float flFrametime, CUserCmd *cmd)
224220
// don't do this part if tools are enabled.
225221
// tools processing will do it instead
226222
if (!tasPlayer->IsUsingTools()) {
227-
ApplyViewAnalog(nSlot, cmd, viewAnalog, wasInExtraMouseSamples);
223+
ApplyViewAnalog(nSlot, cmd, viewAnalog);
228224
}
229225

230226
{
@@ -237,14 +233,10 @@ void TasController::ControllerMove(int nSlot, float flFrametime, CUserCmd *cmd)
237233
}
238234
}
239235

240-
void TasController::ApplyViewAnalog(int nSlot, CUserCmd *cmd, Vector analog, bool usePreExtraMouseSampleAngles) {
236+
void TasController::ApplyViewAnalog(int nSlot, CUserCmd *cmd, Vector analog) {
241237
QAngle viewangles;
242238
viewangles = engine->GetAngles(nSlot);
243239

244-
if (usePreExtraMouseSampleAngles) {
245-
viewangles = viewanglesPreExtraMouseSamples;
246-
}
247-
248240
viewangles.y -= analog.x; // positive values should rotate right.
249241
viewangles.x -= analog.y; // positive values should rotate up.
250242
viewangles.x = std::min(std::max(viewangles.x, -cl_pitchdown.GetFloat()), cl_pitchup.GetFloat());

src/Features/Tas/TasController.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class TasController : public Feature {
4040

4141
bool inExtraMouseSamples;
4242
float extraMouseSamplesAccumulatedTime;
43-
QAngle viewanglesPreExtraMouseSamples;
43+
QAngle extraMouseSamplesAngles;
4444

4545
public:
4646
TasController();
@@ -63,15 +63,18 @@ class TasController : public Feature {
6363
bool GetButtonState(TasControllerInput i);
6464
void SetButtonState(TasControllerInput i, bool state);
6565

66+
QAngle GetExtraMouseSamplesAngles();
67+
6668
void ControllerMove(int nSlot, float flFrametime, CUserCmd *cmd);
6769

6870
private:
69-
void ApplyViewAnalog(int nSlot, CUserCmd *cmd, Vector analog, bool usePreExtraMouseSampleAngles);
71+
void ApplyViewAnalog(int nSlot, CUserCmd *cmd, Vector analog);
7072
};
7173

7274
extern TasController *tasControllers[2];
7375

7476
extern Variable sar_tas_real_controller_debug;
77+
extern Variable sar_tas_use_raw_interpolation;
7578

7679
extern Variable cl_pitchdown;
7780
extern Variable cl_pitchup;

src/Modules/Client.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,12 @@ Hook g_DrawOpaqueRenderablesHook(&Client::DrawOpaqueRenderables_Hook);
842842

843843
extern Hook g_CalcViewModelLagHook;
844844
DETOUR_T(void, Client::CalcViewModelLag, Vector &origin, QAngle &angles, QAngle &original_angles) {
845+
if (tasPlayer->IsRunning() && !tasPlayer->IsUsingTools() && sar_tas_use_raw_interpolation.GetBool()) {
846+
auto offset = tasControllers[GET_SLOT()]->GetExtraMouseSamplesAngles();
847+
angles.x += offset.x;
848+
angles.y += offset.y;
849+
}
850+
845851
if (sar_disable_weapon_sway.GetBool()) {
846852
return;
847853
}

0 commit comments

Comments
 (0)