ScummVM API documentation
gamerate.h
1/* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * aint32 with this program; if not, write to the Free Software
19 *
20 *
21 * Based on the original sources
22 * Faery Tale II -- The Halls of the Dead
23 * (c) 1993-1996 The Wyrmkeep Entertainment Co.
24 */
25
26#ifndef SAGA2_GAMERATE_H
27#define SAGA2_GAMERATE_H
28
29namespace Saga2 {
30
31enum {
32 kGRFramesPerSecond = 0
33};
34
36 uint32 _ticksPerSecond;
37 uint32 _lastTime;
38
39protected:
40 uint32 _frames;
41 float _instantFrameCount;
42
43public:
44 frameCounter(uint32 perSec, uint32 now) {
45 _ticksPerSecond = perSec;
46 _frames = 0;
47 _lastTime = now;
48 _instantFrameCount = 0;
49 }
50
51 virtual ~frameCounter() {}
52
53 virtual void updateFrameCount() {
54 int32 frameTime = gameTime - _lastTime;
55 _lastTime = gameTime;
56 _frames++;
57 _instantFrameCount = frameTime ? _ticksPerSecond / frameTime : 100;
58 }
59
60 virtual float frameStat(int statID = kGRFramesPerSecond) {
61 return _instantFrameCount;
62 }
63};
64
65
66enum {
67 kGRFramesPerKilosecond = 1,
68 kGRFPKS1SecAvgNewest = 2,
69 kGRFPKS1SecAvgNew = 3,
70 kGRFPKS1SecAvg = 4,
71 kGRFPKS1SecAvgOld = 5,
72 kGRFPKS1SecAvgOldest = 6,
73 kGRFPKS5SecAvg = 7,
74 kGRFPKSAvg1SecAvg = 8,
75 kGRFPKS1SecVarNewest = 9,
76 kGRFPKS1SecVarNew = 10,
77 kGRFPKS1SecVar = 11,
78 kGRFPKS1SecVarOld = 12,
79 kGRFPKS1SecVarOldest = 13,
80 kGRFPKS5SecVar = 14,
81 kGRFPKSVar1SecAvg = 15
82};
83
85 float _desiredFPS;
86
87 uint32 _historySize;
88 float *_frameHistory;
89
90 float _avg1Sec[5];
91 float _avg5Sec;
92 float _secAvg;
93 float _dif1Sec[5];
94 float _dif5Sec;
95 float _secDif;
96
97 float ksHistory(int32 i) {
98 return 1000.0 * _frameHistory[i];
99 }
100
101 void calculateAverages() {
102 // clear averages
103 for (int i = 0; i < 5; i++)
104 _avg1Sec[i] = 0;
105
106 _avg5Sec = 0;
107
108 // get totals
109 for (uint i = 0; i < _historySize; i++)
110 _avg1Sec[i / int(_desiredFPS)] += ksHistory(i);
111
112 // get averages
113 for (uint i = 0; i < 5; i++) {
114 _avg5Sec += _avg1Sec[i];
115 _avg1Sec[i] /= _desiredFPS;
116 }
117
118 // get broad averages
119 _secAvg = _avg5Sec / 5;
120 _avg5Sec /= (5 * _desiredFPS);
121 }
122
123 void calculateVariance() {
124 // clear variances
125 for (int i = 0; i < 5; i++)
126 _dif1Sec[i] = 0;
127
128 _dif5Sec = 0;
129
130 // get variance totals
131 for (uint i = 0; i < _historySize; i++) {
132 _dif1Sec[i / int(_desiredFPS)] += ABS(ksHistory(i) - _avg1Sec[i / int(_desiredFPS)]);
133 _dif5Sec += ABS(ksHistory(i) - _avg5Sec);
134 }
135
136 // get average variances
137 for (uint i = 0; i < 5; i++) {
138 _secDif += _avg1Sec[i] - _secAvg;
139 _dif1Sec[i] /= _desiredFPS;
140 }
141
142 // get broad variance
143 _dif5Sec /= (5 * _desiredFPS);
144 }
145
146
147public:
148 frameSmoother(int32 fps, uint32 perSec, uint32 now);
149
150
151 virtual ~frameSmoother() {
152 if (_frameHistory)
153 delete[] _frameHistory;
154
155 _frameHistory = nullptr;
156 }
157
158 virtual void updateFrameCount() {
159 frameCounter::updateFrameCount();
160 _frameHistory[_frames % _historySize] = _instantFrameCount;
161 if (0 == (_frames % int(_desiredFPS))) {
162 calculateAverages();
163 calculateVariance();
164 }
165 }
166
167 virtual float frameStat(int statID = kGRFramesPerSecond) {
168 int oldestOffset = (_frames % _historySize) / _desiredFPS;
169 switch (statID) {
170 case kGRFramesPerKilosecond :
171 return 1000 * _instantFrameCount;
172 case kGRFPKS1SecAvgNewest :
173 return _avg1Sec[4 + oldestOffset];
174 case kGRFPKS1SecAvgNew :
175 return _avg1Sec[3 + oldestOffset];
176 case kGRFPKS1SecAvg :
177 return _avg1Sec[2 + oldestOffset];
178 case kGRFPKS1SecAvgOld :
179 return _avg1Sec[1 + oldestOffset];
180 case kGRFPKS1SecAvgOldest :
181 return _avg1Sec[0 + oldestOffset];
182 case kGRFPKS5SecAvg :
183 return _avg5Sec;
184 case kGRFPKSAvg1SecAvg :
185 return _secAvg;
186 case kGRFPKS1SecVarNewest :
187 return _dif1Sec[4 + oldestOffset];
188 case kGRFPKS1SecVarNew :
189 return _dif1Sec[3 + oldestOffset];
190 case kGRFPKS1SecVar :
191 return _dif1Sec[2 + oldestOffset];
192 case kGRFPKS1SecVarOld :
193 return _dif1Sec[1 + oldestOffset];
194 case kGRFPKS1SecVarOldest :
195 return _dif1Sec[0 + oldestOffset];
196 case kGRFPKS5SecVar :
197 return _dif5Sec;
198 case kGRFPKSVar1SecAvg :
199 return _secDif;
200 default:
201 return frameCounter::frameStat(statID);
202 }
203 }
204};
205
206frameSmoother::frameSmoother(int32 fps, uint32 perSec, uint32 now)
207 : frameCounter(perSec, now) {
208 assert(fps);
209 _desiredFPS = fps;
210 _historySize = fps * 5;
211 _frameHistory = new float[_historySize];
212
213 for (uint32 i = 0; i < _historySize; i++)
214 _frameHistory[i] = 0;
215
216 for (int i = 0; i < 5; i++)
217 _dif1Sec[i] = _avg1Sec[i] = 0;
218
219 _dif5Sec = 0;
220 _avg5Sec = 0;
221 _secDif = 0;
222 _secAvg = 0;
223}
224
225} // end of namespace Saga2
226
227#endif
Definition: gamerate.h:35
Definition: gamerate.h:84
T ABS(T x)
Definition: util.h:60