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