Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/cvars.md
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@
|sar_time_demo|cmd|sar_time_demo \<demo_name> - parses a demo and prints some information about it|
|sar_time_demo_dev|0|Printing mode when using sar_time_demo.<br>0 = Default,<br>1 = Console commands,<br>2 = Console commands & packets.|
|sar_time_demos|cmd|sar_time_demos \<demo_name> [demo_name2]... - parses multiple demos and prints the total sum of them|
|sar_timeline_show_completed|0|Only show speedrun starts and splits with matching finishes.|
|sar_timeline_show_completed|0|Only show speedrun starts and splits with matching finishes. Set to 2 to only show Personal Bests.|
|sar_timeline_splits|1|Add split markers to the Steam Timeline.|
|sar_timer_always_running|1|Timer will save current value when disconnecting.|
|sar_timer_result|cmd|sar_timer_result - prints result of timer|
Expand Down
49 changes: 47 additions & 2 deletions src/Features/SteamTimeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

/* Timeline can get cluttered up (especially at long recording lengths), nice to have an option to disable adding splits. */
Variable sar_timeline_splits("sar_timeline_splits", "1", "Add split markers to the Steam Timeline.\n");
Variable sar_timeline_show_completed("sar_timeline_show_completed", "0", "Only show speedrun starts and splits with matching finishes.\n");
Variable sar_timeline_show_completed("sar_timeline_show_completed", "0", "Only show speedrun starts and splits with matching finishes. Set to 2 to only show Personal Bests.\n");

Timeline *timeline;

Expand All @@ -17,6 +17,11 @@ Timeline::Timeline() {

static std::chrono::time_point<std::chrono::system_clock> g_speedrunStart;
static std::vector<std::tuple<std::string, std::string, float>> g_pendingSplits;
static float g_pendingPbFinishOffset;
static std::string g_pendingPbFinishTime;
static std::chrono::time_point<std::chrono::system_clock> g_pendingPbSpeedrunStart;
static std::vector<std::tuple<std::string, std::string, float>> g_pendingPbSplits;
static bool g_hasPendingPbRun = false;

void Timeline::StartSpeedrun() {
if (!steam->hasLoaded) return;
Expand Down Expand Up @@ -57,6 +62,16 @@ ON_EVENT(SPEEDRUN_FINISH) {
auto fl_time = SpeedrunTimer::GetTotalTicks() * engine->GetIPT();
auto time = SpeedrunTimer::Format(fl_time);

if (sar_timeline_show_completed.GetInt() >= 2) {
g_pendingPbFinishOffset = offset.count();
g_pendingPbFinishTime = time;
g_pendingPbSpeedrunStart = g_speedrunStart;
g_pendingPbSplits = g_pendingSplits;
g_hasPendingPbRun = true;
g_pendingSplits.clear();
return;
}

if (sar_timeline_show_completed.GetBool()) {
steam->g_timeline->AddTimelineEvent("steam_timer", "Speedrun Start", "", 1, -offset.count(), 0.0f, k_ETimelineEventClipPriority_Standard);

Expand All @@ -80,8 +95,38 @@ ON_EVENT(SPEEDRUN_FINISH) {

ON_EVENT(MAYBE_AUTOSUBMIT) {
if (!steam->hasLoaded) return;
if (!event.pb)
if (!event.pb) {
g_pendingPbSplits.clear();
g_hasPendingPbRun = false;
return;
}

if (sar_timeline_show_completed.GetInt() >= 2 && g_hasPendingPbRun) {
std::chrono::duration<float> offset = std::chrono::system_clock::now() - g_pendingPbSpeedrunStart;
float finishOffset = g_pendingPbFinishOffset - offset.count();

steam->g_timeline->AddTimelineEvent("steam_timer", "Speedrun Start", "", 1, -offset.count(), 0.0f, k_ETimelineEventClipPriority_Standard);

for (const auto &[splitName, splitTime, splitOffset] : g_pendingPbSplits) {
steam->g_timeline->AddTimelineEvent(
"steam_bolt",
splitName.c_str(),
splitTime.c_str(),
0,
splitOffset - offset.count(),
0.0f,
k_ETimelineEventClipPriority_None);
}
g_pendingPbSplits.clear();

steam->g_timeline->SetTimelineStateDescription(("Speedrun " + g_pendingPbFinishTime).c_str(), -offset.count());
steam->g_timeline->ClearTimelineStateDescription(finishOffset);
steam->g_timeline->AddTimelineEvent("steam_crown", "Personal Best", SpeedrunTimer::Format(event.score / 100.0f).c_str(), 2, finishOffset, 0.0f, k_ETimelineEventClipPriority_Featured);
g_hasPendingPbRun = false;
return;
}
g_pendingPbSplits.clear();
g_hasPendingPbRun = false;

steam->g_timeline->AddTimelineEvent("steam_crown", "Personal Best", SpeedrunTimer::Format(event.score / 100.0f).c_str(), 2, 0.0f, 0.0f, k_ETimelineEventClipPriority_Featured);
}
Loading