1/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
2/* If you are missing that file, acquire a complete release at teeworlds.com. */
3
4#include "smooth_time.h"
5
6#include "graph.h"
7
8#include <base/math.h>
9#include <base/system.h>
10
11void CSmoothTime::Init(int64_t Target)
12{
13 m_Snap = time_get();
14 m_Current = Target;
15 m_Target = Target;
16 m_Margin = 0;
17 m_SpikeCounter = 0;
18 m_aAdjustSpeed[ADJUSTDIRECTION_DOWN] = 0.3f;
19 m_aAdjustSpeed[ADJUSTDIRECTION_UP] = 0.3f;
20}
21
22void CSmoothTime::SetAdjustSpeed(EAdjustDirection Direction, float Value)
23{
24 m_aAdjustSpeed[Direction] = Value;
25}
26
27int64_t CSmoothTime::Get(int64_t Now) const
28{
29 int64_t c = m_Current + (Now - m_Snap);
30 int64_t t = m_Target + (Now - m_Snap);
31
32 // it's faster to adjust upward instead of downward
33 // we might need to adjust these abit
34
35 float AdjustSpeed = m_aAdjustSpeed[ADJUSTDIRECTION_DOWN];
36 if(t > c)
37 AdjustSpeed = m_aAdjustSpeed[ADJUSTDIRECTION_UP];
38
39 float a = ((Now - m_Snap) / (float)time_freq()) * AdjustSpeed;
40 if(a > 1.0f)
41 a = 1.0f;
42
43 int64_t r = c + (int64_t)((t - c) * a);
44 return r + m_Margin;
45}
46
47void CSmoothTime::UpdateInt(int64_t Target)
48{
49 int64_t Now = time_get();
50 m_Current = Get(Now) - m_Margin;
51 m_Snap = Now;
52 m_Target = Target;
53}
54
55void CSmoothTime::Update(CGraph *pGraph, int64_t Target, int TimeLeft, EAdjustDirection AdjustDirection)
56{
57 bool UpdateTimer = true;
58
59 if(TimeLeft < 0)
60 {
61 bool IsSpike = false;
62 if(TimeLeft < -50)
63 {
64 IsSpike = true;
65
66 m_SpikeCounter += 5;
67 if(m_SpikeCounter > 50)
68 m_SpikeCounter = 50;
69 }
70
71 if(IsSpike && m_SpikeCounter < 15)
72 {
73 // ignore this ping spike
74 UpdateTimer = false;
75 pGraph->Add(Value: TimeLeft, Color: ColorRGBA(1.0f, 1.0f, 0.0f, 0.75f));
76 }
77 else
78 {
79 pGraph->Add(Value: TimeLeft, Color: ColorRGBA(1.0f, 0.0f, 0.0f, 0.75f));
80 if(m_aAdjustSpeed[AdjustDirection] < 30.0f)
81 m_aAdjustSpeed[AdjustDirection] *= 2.0f;
82 }
83 }
84 else
85 {
86 if(m_SpikeCounter)
87 m_SpikeCounter--;
88
89 pGraph->Add(Value: TimeLeft, Color: ColorRGBA(0.0f, 1.0f, 0.0f, 0.75f));
90
91 m_aAdjustSpeed[AdjustDirection] *= 0.95f;
92 if(m_aAdjustSpeed[AdjustDirection] < 2.0f)
93 m_aAdjustSpeed[AdjustDirection] = 2.0f;
94 }
95
96 if(UpdateTimer)
97 UpdateInt(Target);
98}
99
100void CSmoothTime::UpdateMargin(int64_t Margin)
101{
102 m_Margin = Margin;
103}
104