Skip to content

Commit 29dff58

Browse files
committed
tweak(fps): Decouple non-network logic update from render update (#1451)
1 parent 1d49449 commit 29dff58

File tree

9 files changed

+496
-47
lines changed

9 files changed

+496
-47
lines changed

Core/GameEngine/Include/Common/FrameRateLimit.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,42 @@ class FrameRateLimit
2929
LARGE_INTEGER m_freq;
3030
LARGE_INTEGER m_start;
3131
};
32+
33+
34+
enum FpsValueChange
35+
{
36+
FpsValueChange_Increase,
37+
FpsValueChange_Decrease,
38+
};
39+
40+
41+
class RenderFpsPreset
42+
{
43+
public:
44+
enum CPP_11(: UnsignedInt)
45+
{
46+
UncappedFpsValue = 1000,
47+
};
48+
49+
static UnsignedInt getNextFpsValue(UnsignedInt value);
50+
static UnsignedInt getPrevFpsValue(UnsignedInt value);
51+
static UnsignedInt changeFpsValue(UnsignedInt value, FpsValueChange change);
52+
53+
private:
54+
static const UnsignedInt s_fpsValues[];
55+
};
56+
57+
58+
class LogicTimeScaleFpsPreset
59+
{
60+
public:
61+
enum CPP_11(: UnsignedInt)
62+
{
63+
StepFpsValue = 5,
64+
};
65+
66+
static UnsignedInt getNextFpsValue(UnsignedInt value);
67+
static UnsignedInt getPrevFpsValue(UnsignedInt value);
68+
static UnsignedInt changeFpsValue(UnsignedInt value, FpsValueChange change);
69+
};
70+

Core/GameEngine/Source/Common/FrameRateLimit.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,75 @@ Real FrameRateLimit::wait(UnsignedInt maxFps)
5252
m_start = tick;
5353
return (Real)elapsedSeconds;
5454
}
55+
56+
57+
const UnsignedInt RenderFpsPreset::s_fpsValues[] = {
58+
30, 50, 56, 60, 65, 70, 72, 75, 80, 85, 90, 100, 110, 120, 144, 240, 480, UncappedFpsValue };
59+
60+
static_assert(LOGICFRAMES_PER_SECOND <= 30, "Min FPS values need to be revisited!");
61+
62+
UnsignedInt RenderFpsPreset::getNextFpsValue(UnsignedInt value)
63+
{
64+
const Int first = 0;
65+
const Int last = ARRAY_SIZE(s_fpsValues) - 1;
66+
for (Int i = first; i < last; ++i)
67+
{
68+
if (value >= s_fpsValues[i] && value < s_fpsValues[i + 1])
69+
{
70+
return s_fpsValues[i + 1];
71+
}
72+
}
73+
return s_fpsValues[last];
74+
}
75+
76+
UnsignedInt RenderFpsPreset::getPrevFpsValue(UnsignedInt value)
77+
{
78+
const Int first = 0;
79+
const Int last = ARRAY_SIZE(s_fpsValues) - 1;
80+
for (Int i = last; i > first; --i)
81+
{
82+
if (value <= s_fpsValues[i] && value > s_fpsValues[i - 1])
83+
{
84+
return s_fpsValues[i - 1];
85+
}
86+
}
87+
return s_fpsValues[first];
88+
}
89+
90+
UnsignedInt RenderFpsPreset::changeFpsValue(UnsignedInt value, FpsValueChange change)
91+
{
92+
switch (change)
93+
{
94+
default:
95+
case FpsValueChange_Increase: return getNextFpsValue(value);
96+
case FpsValueChange_Decrease: return getPrevFpsValue(value);
97+
}
98+
}
99+
100+
101+
UnsignedInt LogicTimeScaleFpsPreset::getNextFpsValue(UnsignedInt value)
102+
{
103+
return value + StepFpsValue;
104+
}
105+
106+
UnsignedInt LogicTimeScaleFpsPreset::getPrevFpsValue(UnsignedInt value)
107+
{
108+
if (value - StepFpsValue < LOGICFRAMES_PER_SECOND)
109+
{
110+
return LOGICFRAMES_PER_SECOND;
111+
}
112+
else
113+
{
114+
return value - StepFpsValue;
115+
}
116+
}
117+
118+
UnsignedInt LogicTimeScaleFpsPreset::changeFpsValue(UnsignedInt value, FpsValueChange change)
119+
{
120+
switch (change)
121+
{
122+
default:
123+
case FpsValueChange_Increase: return getNextFpsValue(value);
124+
case FpsValueChange_Decrease: return getPrevFpsValue(value);
125+
}
126+
}

GeneralsMD/Code/GameEngine/Include/Common/GameEngine.h

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@
3434
#include "Common/SubsystemInterface.h"
3535
#include "Common/GameType.h"
3636

37-
#define DEFAULT_MAX_FPS 45
38-
3937
// forward declarations
4038
class AudioManager;
4139
class GameLogic;
@@ -72,8 +70,20 @@ class GameEngine : public SubsystemInterface
7270

7371
virtual void execute( void ); /**< The "main loop" of the game engine.
7472
It will not return until the game exits. */
75-
virtual void setFramesPerSecondLimit( Int fps ); ///< Set the maximum rate engine updates are allowed to occur
76-
virtual Int getFramesPerSecondLimit( void ); ///< Get maxFPS. Not inline since it is called from another lib.
73+
74+
virtual void setFramesPerSecondLimit( Int fps ); ///< Set the max render and engine update fps.
75+
virtual Int getFramesPerSecondLimit( void ); ///< Get the max render and engine update fps.
76+
Real getUpdateTime(); ///< Get the last engine update delta time.
77+
Real getUpdateFps(); ///< Get the last engine update fps.
78+
79+
virtual void setLogicTimeScaleFps( Int fps ); ///< Set the logic time scale fps and therefore scale the simulation time. Is capped by the max render fps and does not apply to network matches.
80+
virtual Int getLogicTimeScaleFps(); ///< Get the raw logic time scale fps value.
81+
virtual void enableLogicTimeScale( Bool enable ); ///< Enable the logic time scale setup. If disabled, the simulation time scale is bound to the render frame time or network update time.
82+
virtual Bool isLogicTimeScaleEnabled(); ///< Check whether the logic time scale setup is enabled.
83+
Int getActualLogicTimeScaleFps(); ///< Get the real logic time scale fps, depending on the max render fps, network state and enabled state.
84+
Real getActualLogicTimeScaleRatio(); ///< Get the real logic time scale ratio, depending on the max render fps, network state and enabled state.
85+
Real getActualLogicTimeScaleOverFpsRatio(); ///< Get the real logic time scale over render fps ratio, used to scale down steps in render updates to match logic updates.
86+
7787
virtual void setQuitting( Bool quitting ); ///< set quitting status
7888
virtual Bool getQuitting(void); ///< is app getting ready to quit.
7989

@@ -100,9 +110,15 @@ class GameEngine : public SubsystemInterface
100110
virtual ParticleSystemManager* createParticleSystemManager( void ) = 0;
101111
virtual AudioManager *createAudioManager( void ) = 0; ///< Factory for Audio Manager
102112

103-
Int m_maxFPS; ///< Maximum frames per second allowed
113+
Int m_maxFPS; ///< Maximum frames per second for rendering
114+
Int m_logicTimeScaleFPS; ///< Maximum frames per second for logic time scale
115+
116+
Real m_updateTime; ///< Last engine update delta time
117+
Real m_logicTimeAccumulator; ///< Frame time accumulated towards submitting a new logic frame
118+
104119
Bool m_quitting; ///< true when we need to quit the game
105120
Bool m_isActive; ///< app has OS focus.
121+
Bool m_enableLogicTimeScale;
106122

107123
};
108124
inline void GameEngine::setQuitting( Bool quitting ) { m_quitting = quitting; }

GeneralsMD/Code/GameEngine/Include/Common/MessageStream.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,10 @@ class GameMessage : public MemoryPoolObject
241241
MSG_META_HELP, ///< bring up help screen
242242
#endif
243243

244+
MSG_META_INCREASE_MAX_RENDER_FPS, ///< TheSuperHackers @feature Increase the max render fps
245+
MSG_META_DECREASE_MAX_RENDER_FPS, ///< TheSuperHackers @feature Decrease the max render fps
246+
MSG_META_INCREASE_LOGIC_TIME_SCALE, ///< TheSuperHackers @feature Increase the logic time scale
247+
MSG_META_DECREASE_LOGIC_TIME_SCALE, ///< TheSuperHackers @feature Decrease the logic time scale
244248
MSG_META_TOGGLE_LOWER_DETAILS, ///< toggles graphics options to crappy mode instantly
245249
MSG_META_TOGGLE_CONTROL_BAR, ///< show/hide controlbar
246250

GeneralsMD/Code/GameEngine/Include/GameClient/MetaEvent.h

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,24 @@ static const LookupListRec CategoryListName[] =
6969
// KeyDefType; this is extremely important to maintain!
7070
enum MappableKeyType CPP_11(: Int)
7171
{
72+
// keypad keys ----------------------------------------------------------------
73+
MK_KP0 = KEY_KP0,
74+
MK_KP1 = KEY_KP1,
75+
MK_KP2 = KEY_KP2,
76+
MK_KP3 = KEY_KP3,
77+
MK_KP4 = KEY_KP4,
78+
MK_KP5 = KEY_KP5,
79+
MK_KP6 = KEY_KP6,
80+
MK_KP7 = KEY_KP7,
81+
MK_KP8 = KEY_KP8,
82+
MK_KP9 = KEY_KP9,
83+
MK_KPDEL = KEY_KPDEL,
84+
MK_KPSTAR = KEY_KPSTAR,
85+
MK_KPMINUS = KEY_KPMINUS,
86+
MK_KPPLUS = KEY_KPPLUS,
87+
MK_KPENTER = KEY_KPENTER,
88+
MK_KPSLASH = KEY_KPSLASH,
89+
7290
MK_ESC = KEY_ESC,
7391
MK_BACKSPACE = KEY_BACKSPACE,
7492
MK_ENTER = KEY_ENTER,
@@ -122,16 +140,6 @@ enum MappableKeyType CPP_11(: Int)
122140
MK_8 = KEY_8,
123141
MK_9 = KEY_9,
124142
MK_0 = KEY_0,
125-
MK_KP1 = KEY_KP1,
126-
MK_KP2 = KEY_KP2,
127-
MK_KP3 = KEY_KP3,
128-
MK_KP4 = KEY_KP4,
129-
MK_KP5 = KEY_KP5,
130-
MK_KP6 = KEY_KP6,
131-
MK_KP7 = KEY_KP7,
132-
MK_KP8 = KEY_KP8,
133-
MK_KP9 = KEY_KP9,
134-
MK_KP0 = KEY_KP0,
135143
MK_MINUS = KEY_MINUS,
136144
MK_EQUAL = KEY_EQUAL,
137145
MK_LBRACKET = KEY_LBRACKET,
@@ -153,13 +161,30 @@ enum MappableKeyType CPP_11(: Int)
153161
MK_PGDN = KEY_PGDN,
154162
MK_INS = KEY_INS,
155163
MK_DEL = KEY_DEL,
156-
MK_KPSLASH = KEY_KPSLASH,
157164
MK_NONE = KEY_NONE
158165

159166
};
160167

161168
static const LookupListRec KeyNames[] =
162169
{
170+
// keypad keys ----------------------------------------------------------------
171+
{ "KEY_KP0", MK_KP0 },
172+
{ "KEY_KP1", MK_KP1 },
173+
{ "KEY_KP2", MK_KP2 },
174+
{ "KEY_KP3", MK_KP3 },
175+
{ "KEY_KP4", MK_KP4 },
176+
{ "KEY_KP5", MK_KP5 },
177+
{ "KEY_KP6", MK_KP6 },
178+
{ "KEY_KP7", MK_KP7 },
179+
{ "KEY_KP8", MK_KP8 },
180+
{ "KEY_KP9", MK_KP9 },
181+
{ "KEY_KPDEL", MK_KPDEL },
182+
{ "KEY_KPSTAR", MK_KPSTAR },
183+
{ "KEY_KPMINUS", MK_KPMINUS },
184+
{ "KEY_KPPLUS", MK_KPPLUS },
185+
{ "KEY_KPENTER", MK_KPENTER },
186+
{ "KEY_KPSLASH", MK_KPSLASH },
187+
163188
{ "KEY_ESC", MK_ESC },
164189
{ "KEY_BACKSPACE", MK_BACKSPACE },
165190
{ "KEY_ENTER", MK_ENTER },
@@ -213,16 +238,6 @@ static const LookupListRec KeyNames[] =
213238
{ "KEY_8", MK_8 },
214239
{ "KEY_9", MK_9 },
215240
{ "KEY_0", MK_0 },
216-
{ "KEY_KP1", MK_KP1 },
217-
{ "KEY_KP2", MK_KP2 },
218-
{ "KEY_KP3", MK_KP3 },
219-
{ "KEY_KP4", MK_KP4 },
220-
{ "KEY_KP5", MK_KP5 },
221-
{ "KEY_KP6", MK_KP6 },
222-
{ "KEY_KP7", MK_KP7 },
223-
{ "KEY_KP8", MK_KP8 },
224-
{ "KEY_KP9", MK_KP9 },
225-
{ "KEY_KP0", MK_KP0 },
226241
{ "KEY_MINUS", MK_MINUS },
227242
{ "KEY_EQUAL", MK_EQUAL },
228243
{ "KEY_LBRACKET", MK_LBRACKET },
@@ -244,7 +259,6 @@ static const LookupListRec KeyNames[] =
244259
{ "KEY_PGDN", MK_PGDN },
245260
{ "KEY_INS", MK_INS },
246261
{ "KEY_DEL", MK_DEL },
247-
{ "KEY_KPSLASH", MK_KPSLASH },
248262
{ "KEY_NONE", MK_NONE },
249263
{ NULL, 0 } // keep this last!
250264
};
@@ -301,7 +315,9 @@ enum CommandUsableInType CPP_11(: Int)
301315
COMMANDUSABLE_NONE = 0,
302316

303317
COMMANDUSABLE_SHELL = (1 << 0),
304-
COMMANDUSABLE_GAME = (1 << 1)
318+
COMMANDUSABLE_GAME = (1 << 1),
319+
320+
COMMANDUSABLE_EVERYWHERE = COMMANDUSABLE_SHELL | COMMANDUSABLE_GAME,
305321
};
306322

307323
static const char* TheCommandUsableInNames[] =

0 commit comments

Comments
 (0)