feat(gui): Implement user option to scale the game window transition speed#2840
Conversation
|
| Filename | Overview |
|---|---|
| Core/GameEngine/Include/Common/OptionPreferences.h | Adds getGameWindowTransitionSpeedMultiplier() declaration; clean addition consistent with surrounding interface. |
| Core/GameEngine/Source/Common/OptionPreferences.cpp | Implements getGameWindowTransitionSpeedMultiplier(): reads from INI via atof, clamps to [1.0, 1000.0], returns default 1.0f if key absent — follows the same pattern as neighboring prefs. |
| Core/GameEngine/Source/GameClient/GUI/GameWindowTransitions.cpp | Scales timeScale by m_gameWindowTransitionSpeedMultiplier; the existing isFinished guard in the frame-stepping loop bounds iteration count to animation length even at max multiplier. |
| Generals/Code/GameEngine/Include/Common/GlobalData.h | Adds m_gameWindowTransitionSpeedMultiplier field to GlobalData; correctly placed alongside other per-user display preferences. |
| Generals/Code/GameEngine/Source/Common/GlobalData.cpp | Initializes field to 1.0f in constructor and loads it from optionPref in parseGameDataDefinition, consistent with neighboring settings. |
| Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp | Adds a saveOptions block that reads the existing INI value and writes it back unchanged (INI-only configuration, no UI control), matching the established pattern for ResolutionFontAdjustment. |
| GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h | Same field addition as in Generals/; correctly replicated to the Zero Hour expansion. |
| GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp | Same init and load pattern as in Generals/; correctly replicated. |
| GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp | Same saveOptions block as in Generals/; correctly replicated. |
Sequence Diagram
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant INI as Options.ini
participant OptPref as OptionPreferences
participant GD as GlobalData
participant TG as TransitionGroup::update()
Note over INI,GD: At startup (parseGameDataDefinition)
INI->>OptPref: "GameWindowTransitionSpeedMultiplier=N"
OptPref->>OptPref: clamp(1.0, N, 1000.0)
OptPref->>GD: "m_gameWindowTransitionSpeedMultiplier = N"
Note over TG: Each render update
TG->>TG: "timeScale = FramePacer.getBaseOverUpdateFpsRatio()"
TG->>GD: read m_gameWindowTransitionSpeedMultiplier
TG->>TG: "timeScale *= multiplier"
TG->>TG: step frames (bounded by isFinished)
Note over INI,GD: On saveOptions()
GD->>OptPref: getGameWindowTransitionSpeedMultiplier()
OptPref->>INI: write clamped value back
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant INI as Options.ini
participant OptPref as OptionPreferences
participant GD as GlobalData
participant TG as TransitionGroup::update()
Note over INI,GD: At startup (parseGameDataDefinition)
INI->>OptPref: "GameWindowTransitionSpeedMultiplier=N"
OptPref->>OptPref: clamp(1.0, N, 1000.0)
OptPref->>GD: "m_gameWindowTransitionSpeedMultiplier = N"
Note over TG: Each render update
TG->>TG: "timeScale = FramePacer.getBaseOverUpdateFpsRatio()"
TG->>GD: read m_gameWindowTransitionSpeedMultiplier
TG->>TG: "timeScale *= multiplier"
TG->>TG: step frames (bounded by isFinished)
Note over INI,GD: On saveOptions()
GD->>OptPref: getGameWindowTransitionSpeedMultiplier()
OptPref->>INI: write clamped value back
Reviews (5): Last reviewed commit: "feat(gui): Replicate GameWindowTransitio..." | Re-trigger Greptile
| // transitions cannot skip a state when the render frame rate dips below the base rate. | ||
| const Real timeScale = TheFramePacer->getBaseOverUpdateFpsRatio(); | ||
| // TheSuperHackers @feature bobtista 28/06/2026 Scale by the user menu transition speed preference. | ||
| const Real timeScale = TheFramePacer->getBaseOverUpdateFpsRatio() * TheGlobalData->m_menuTransitionSpeed; |
There was a problem hiding this comment.
Maybe also apply this to the movement speed of Control Bar, Diplomacy Screen? Or does that need to be a separate setting?
There was a problem hiding this comment.
Those don't go through TransitionGroup they use the sliding/animate-window path. Could make another PR for those - would you want it to be a separate setting or controlled by this one?
There was a problem hiding this comment.
Maybe make it a separate setting GameWindowMovementSpeedMultiplier
It's iteration-bound (frame-pacer frozen in that loop), so lowering Sleep speeds the fade up rather than smoothing it, is that what you want? It would be like 30x faster right? Maybe the proper change is to route the loop through the frame pacer, which would presumably be in its own PR. |
Right, perhaps
I don't think that's necessary. |
Let's handle this in another PR. If we use that formula it will double count the denominator, duration becomes 1/speed². That 33 msec delay just makes the whole fade loop have 30fps pacing. We could do something like |
…nd enforce 1-1000 range
Would you mind doing a follow-up PR for this, then? |
|
Any major issues keeping this from being merged? |
xezon
left a comment
There was a problem hiding this comment.
I think there needs to be an addition to Options Menu so that this gets saved in the Options.INI
|
Pull description says 1.0 means 1x slower. But it is not slower. |
should that be its own PR? Or here? |
|
I tested it and it works great. (I added the setting to the options.ini file myself). |
It requires 5 or so lines in Options Menu. We typically add this in one commit, because it belongs together and is thereofre not necessary to split to more than one commit. We perhaps also have several other Options that have been forgotten to be added there and are therefore never default written to Options.ini. |
… via Options Menu
…persistence to Generals
Closes #2839
This change adds a
GameWindowTransitionSpeedMultiplieroption (inOptions.ini) that scales the speed of menu/window transition animations, as requested following #2056. Defaults to1.0(unchanged behavior); values range from1.0(1×) to1000.0(1000× faster).The multiplier is applied to the existing frame-rate-decoupled time step from #2056, so transitions still step through every state and never skip.
Todo