Skip to content

Fix #2834: Frame-rate-independent general promotion star blink#2844

Closed
secprentice wants to merge 1 commit into
TheSuperHackers:mainfrom
secprentice:fix/2834-promotion-star-blink-framerate
Closed

Fix #2834: Frame-rate-independent general promotion star blink#2844
secprentice wants to merge 1 commit into
TheSuperHackers:mainfrom
secprentice:fix/2834-promotion-star-blink-framerate

Conversation

@secprentice

Copy link
Copy Markdown

Summary

Fixes #2834.

The general promotion star button used TheGameLogic->getFrame() % LOGICFRAMES_PER_SECOND > LOGICFRAMES_PER_SECOND / 2 to drive its blink animation. At high FPS (e.g. uncapped or 144 Hz), logic frames advance faster than real time, causing the button to blink far too rapidly and become visually distracting.

Change: Replaced the frame-based blink condition with timeGetTime() % 1000 > 500 in both Generals and GeneralsMD ControlBar.cpp. This gives a steady, wall-clock 1 Hz blink (500 ms on / 500 ms off) that is completely independent of game speed or frame rate.

Files changed

  • Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp
  • GeneralsMD/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp

Test plan

  • Earn a general promotion at high FPS (uncapped or 144 Hz+) — star button should blink at ~1 Hz, not rapidly
  • Confirm the star still blinks (not permanently on or off)
  • Confirm behaviour is identical in both the base game and Zero Hour builds

Replace getFrame() % LOGICFRAMES_PER_SECOND with timeGetTime() % 1000
so the general promotion button blinks at a steady ~1 Hz regardless of
the game's logic frame rate or display FPS.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jun 29, 2026

Copy link
Copy Markdown

Greptile Summary

Replaces the frame-count-based blink condition in getStarImage() with a timeGetTime() % 1000 > 500 wall-clock check, making the general promotion star blink at a steady 1 Hz regardless of game speed or frame rate. The identical fix is applied consistently to both the base game (Generals/) and Zero Hour (GeneralsMD/) builds.

  • timeGetTime is already pulled in through PreRTS.h<mmsystem.h> and used pervasively across the engine, so no new dependency or include is needed.
  • The behavioural difference (blink continues while the game is paused) is intentional and desirable for a UI element that should draw the player's attention.

Confidence Score: 5/5

Safe to merge — two-line change swapping a frame-count blink for a wall-clock blink, with no new dependencies or side-effects.

The fix is minimal and self-contained: timeGetTime is already declared through PreRTS.h and used widely across the engine, the modulo arithmetic is correct for a DWORD, and the change is applied symmetrically in both the base-game and Zero Hour files. No logic outside of getStarImage is touched.

No files require special attention.

Important Files Changed

Filename Overview
Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp Single-line fix in getStarImage(): frame-based blink replaced with timeGetTime() % 1000 > 500; no new dependencies needed.
GeneralsMD/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp Identical fix mirrored for Zero Hour build; change is consistent and correct.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[getStarImage called] --> B{sciencePurchasePoints\nchanged or <= 0?}
    B -- Yes --> C[m_genStarFlash = FALSE]
    B -- No --> D[update m_lastFlashedAtPointValue]
    C --> E{win exists?}
    D --> E
    E -- No --> F[return nullptr]
    E -- Yes --> G{m_genStarFlash?}
    G -- No --> H[set enabled image\nreturn nullptr]
    G -- Yes --> I{timeGetTime % 1000 > 500\nwall-clock blink}
    I -- True / ON half --> J[set highlight image\nreturn nullptr]
    I -- False / OFF half --> K[set enabled image\nreturn nullptr]

    style I fill:#d4edda,stroke:#28a745
Loading
%%{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"}}}%%
flowchart TD
    A[getStarImage called] --> B{sciencePurchasePoints\nchanged or <= 0?}
    B -- Yes --> C[m_genStarFlash = FALSE]
    B -- No --> D[update m_lastFlashedAtPointValue]
    C --> E{win exists?}
    D --> E
    E -- No --> F[return nullptr]
    E -- Yes --> G{m_genStarFlash?}
    G -- No --> H[set enabled image\nreturn nullptr]
    G -- Yes --> I{timeGetTime % 1000 > 500\nwall-clock blink}
    I -- True / ON half --> J[set highlight image\nreturn nullptr]
    I -- False / OFF half --> K[set enabled image\nreturn nullptr]

    style I fill:#d4edda,stroke:#28a745
Loading

Reviews (1): Last reviewed commit: "Fix #2834: Frame-rate-independent promot..." | Re-trigger Greptile

@bobtista

Copy link
Copy Markdown

Duplicate of #2835

@bobtista bobtista marked this as a duplicate of #2835 Jun 29, 2026
@Skyaero42

Copy link
Copy Markdown

#2835 is the better implementation. Closing this one.

Please search for existing PR's before opening a new one to prevent duplicates.

@Skyaero42 Skyaero42 closed this Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

General promotion star button blink speed changes with framerate

3 participants