Skip to content

feat(intro): Add short Intro Logo for The Super Hackers team#2267

Open
xezon wants to merge 5 commits intoTheSuperHackers:mainfrom
xezon:xezon/add-new-intro
Open

feat(intro): Add short Intro Logo for The Super Hackers team#2267
xezon wants to merge 5 commits intoTheSuperHackers:mainfrom
xezon:xezon/add-new-intro

Conversation

@xezon
Copy link

@xezon xezon commented Feb 7, 2026

Merge with Rebase

This change has 5 commits:

  1. Move intro related code to new file and class
  2. Simplify the intro state machine to make it easier to modify and extend
  3. Remove the non functional copyright string and simplify the EA logo movie code. This also shortens the effective EA logo duration by 3 to 5 seconds.
  4. Remove the superfluous legal page from intro sequence, which would have lasted 4 seconds after Sizzle video but was practically never visible except if the mem pass would have failed (relevant for 2000 era computers). I think the condition was actually meant to be the inverse...
  5. Add new intro screen for The Super Hacker team

Old Intro Sequence

  1. EA Logo, 3 seconds, non skippable
  2. Black Screen, 3-5 seconds (*1), non skippable
  3. Sizzle Video, skippable
  4. Legal Page, 4 seconds, practically never shown
  5. Shell Map load screen

(*1) I did not measure how long the black screen was. According to code somewhere between 3 to 5 seconds.

New Intro Sequence

  1. EA Logo, 3 seconds, non skippable
  2. Black Screen, 800 milliseconds, non skippable
  3. The Super Hackers Logo, 3 seconds, non skippable
  4. Black Screen, 1 second, non skippable
  5. Sizzle Video, skippable
  6. Shell Map load screen
image

TODO

  • Replicate in Generals
  • Add pull id to commit titles
  • Verify each commit compiles individually

@xezon xezon added Art Is art related Enhancement Is new feature or request Minor Severity: Minor < Major < Critical < Blocker Gen Relates to Generals ZH Relates to Zero Hour Refactor Edits the code with insignificant behavior changes, is never user facing labels Feb 7, 2026
@greptile-apps
Copy link

greptile-apps bot commented Feb 7, 2026

Greptile Summary

This PR refactors the game's intro sequence into a clean, self-contained Intro class with a proper bitmask-driven state machine, replacing a fragile inline implementation in GameClient::update() that relied on a static local variable and a blocking Sleep() loop for the legal page. It also removes the now-dead playLogoMovie/copyright-hold machinery from Display, drops the global m_afterIntro flag in favour of isDone(), and adds a new 3-second The Super Hackers team logo screen (with fade-in/fade-out) between the EA logo and the Sizzle video.

Key changes:

  • New Intro class (Core/GameEngine) encapsulates all intro state transitions; state advancement uses a bitfield so individual steps can be toggled by the m_playIntro/m_playSizzle flags without branching scattered across GameClient
  • Display::playLogoMovie and all copyright hold-time fields removed; Display::update() is significantly simplified
  • m_afterIntro global removed from GlobalData; all twelve call sites cleaned up across CommandLine.cpp, GameEngine.cpp, and GlobalData.cpp
  • TheGameClient->DRAW() is now called from the W3D render pipeline (replacing a stale comment), wiring Intro::draw() into the frame loop for the fade effect
  • The effective black-screen gap between EA logo and Sizzle shrinks from 3–5 s to 800 ms + 1 s (split around the new logo screen)

Confidence Score: 5/5

  • Safe to merge — logic is sound across all intro flag combinations and the single unused include is trivial cleanup.
  • All previously raised concerns have been resolved (overflow fix, enterNextState loop correctness, enterNextState visibility). freeDisplayString(nullptr) is safe per the W3DDisplayStringManager implementation. The only remaining finding is an unused GameWindowManager.h include in Intro.cpp — a one-line cleanup with no runtime impact.
  • No files require special attention.

Important Files Changed

Filename Overview
Core/GameEngine/Include/GameClient/Intro.h New header introducing the Intro state machine class. Uses #pragma once, nullptr, private members, and forward declarations correctly. IntroState enum and DisplayEntity struct are private to the class.
Core/GameEngine/Source/GameClient/Intro.cpp New implementation of the Intro state machine. Contains one unused include (GameWindowManager.h). State transitions are correct — enterNextState() loops to Done when no states are enabled, doPostIntro() is called exactly once, and freeDisplayString safely handles null pointers.
GeneralsMD/Code/GameEngine/Source/GameClient/GameClient.cpp Replaces the old spaghetti inline intro logic (static local variable, legal page blocking loop) with clean Intro object lifecycle management. m_intro is null-checked before and after update(), correctly handling the transition frame.
GeneralsMD/Code/GameEngine/Source/GameClient/Display.cpp Removes the playLogoMovie function and all copyright hold-time machinery. The simplified update() correctly advances to stopMovie() when the last frame is reached.
GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp Replaces the stale "end of video example code" comment with a real call to TheGameClient->DRAW(), wiring the Intro draw path into the render pipeline. Copyright display string rendering removed cleanly.
GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h Removes the now-obsolete m_afterIntro flag, which was made redundant by the Intro object's isDone() mechanism.
GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp Removes two duplicate m_afterIntro = TRUE assignments that were defensive copies of the same flag logic, now handled by the Intro class.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    Start([IntroState_Start]) --> EN1{enterNextState}
    EN1 -->|m_playIntro=true| EALogo[IntroState_EALogoMovie\ndoEALogoMovie\nplays movie]
    EN1 -->|m_playIntro=false\nm_playSizzle=true| SizzleMovie
    EN1 -->|both false| Done

    EALogo -->|isMoviePlaying=false| EN2{enterNextState}
    EN2 -->|m_playIntro=true| TSHWait[IntroState_TheSuperHackersWait\ndoAsyncWait 800ms]
    TSHWait -->|wait elapsed| EN3{enterNextState}
    EN3 --> TSH[IntroState_TheSuperHackers\ndoTheSuperHackers\ndraw fade-in/out\n3000ms wait]
    TSH -->|wait elapsed| EN4{enterNextState}
    EN4 -->|m_playSizzle=true\nm_playIntro=true| SizzleWait[IntroState_SizzleMovieWait\ndoAsyncWait 1000ms]
    EN4 -->|m_playSizzle=false| Done
    SizzleWait -->|wait elapsed| EN5{enterNextState}
    EN5 -->|m_playSizzle=true| SizzleMovie[IntroState_SizzleMovie\ndoSizzleMovie\nplays movie]
    SizzleMovie -->|isMoviePlaying=false| EN6{enterNextState}
    EN6 --> Done[IntroState_Done\ndoPostIntro\nm_breakTheMovie=TRUE]
    Done --> Shell([GameClient deletes Intro\nshowShellMap + showShell])
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: Core/GameEngine/Source/GameClient/Intro.cpp
Line: 28

Comment:
**Unused include**

`GameWindowManager.h` is included here but `TheWindowManager` (or any other symbol from that header) is never referenced in this file. It appears to be a leftover from the `GameClient.cpp` rewrite, where the old code used `TheWindowManager` to display the legal page.

```suggestion
#include "GameClient/GameText.h"
```
Remove the `GameWindowManager.h` include entirely.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (10): Last reviewed commit: "feat(intro): Add short Intro Logo for Th..." | Re-trigger Greptile

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

9 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

@greptile-apps
Copy link

greptile-apps bot commented Feb 7, 2026

Additional Comments (1)

GeneralsMD/Code/GameEngine/Source/GameClient/GameClient.cpp
Intro can block startup

GameClient::update() only shows the shell (TheShell->showShellMap/showShell) after m_intro->isDone(). With the new Intro implementation, if the global flags disable both intro and sizzle (m_playIntro==false and m_playSizzle==false) and m_afterIntro is not pre-set, Intro never reaches Done (see IntroState_Start handling), so the game can get stuck in the intro phase and never show the shell. This previously worked because GameEngine::init() forced m_afterIntro = TRUE when m_playIntro was false.

Fix by making Intro immediately become done when there are no enabled states, or by preserving the old m_afterIntro initialization behavior.

Prompt To Fix With AI
This is a comment left during a code review.
Path: GeneralsMD/Code/GameEngine/Source/GameClient/GameClient.cpp
Line: 514:531

Comment:
**Intro can block startup**

`GameClient::update()` only shows the shell (`TheShell->showShellMap/showShell`) after `m_intro->isDone()`. With the new `Intro` implementation, if the global flags disable both intro and sizzle (`m_playIntro==false` and `m_playSizzle==false`) and `m_afterIntro` is not pre-set, `Intro` never reaches `Done` (see `IntroState_Start` handling), so the game can get stuck in the intro phase and never show the shell. This previously worked because `GameEngine::init()` forced `m_afterIntro = TRUE` when `m_playIntro` was false.

Fix by making `Intro` immediately become done when there are no enabled states, or by preserving the old `m_afterIntro` initialization behavior.

How can I resolve this? If you propose a fix, please make it concise.

@xezon xezon force-pushed the xezon/add-new-intro branch from 999721b to 0f278e6 Compare February 7, 2026 14:15
@xezon xezon force-pushed the xezon/add-new-intro branch from 0f278e6 to 1a738f7 Compare February 7, 2026 16:19
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

@helmutbuhler
Copy link

Wouldn't it be more appropriate to show the Superhackers stuff in the credits menu? As is this would imply that the whole game is made by us. I don't think it would be fair to show our names more prominently than the original developers.

@xezon
Copy link
Author

xezon commented Feb 7, 2026

Wouldn't it be more appropriate to show the Superhackers stuff in the credits menu? As is this would imply that the whole game is made by us. I don't think it would be fair to show our names more prominently than the original developers.

Maybe remove all user names from this Intro and just show the Team name + url?

We can also clarify "Edited by ..."

@helmutbuhler
Copy link

Wouldn't it be more appropriate to show the Superhackers stuff in the credits menu? As is this would imply that the whole game is made by us. I don't think it would be fair to show our names more prominently than the original developers.

Maybe remove all user names from this Intro and just show the Team name + url?

We can also clarify "Edited by ..."

I wouldn't add anything to the intro. I don't think it's necessary to remind the player every time the game starts who made the patch. Maybe just add a tiny note on the shellmap screen below the gamename "patched by Superhackers" or something like that.

It's nice though that the 3-5 seconds black screen is removed here!

@Caball009
Copy link

Caball009 commented Feb 8, 2026

I didn't even know what the 'black screen' was when I saw this PR, because I have renamed the files for the EA logo and sizzle and I don't see it. This makes the game launch faster, and saves me 5+ seconds every time I launch the game. I strongly dislike changing anything that would unnecessarily increase the launch time for me as developer. I'm ok with it if I can skip it with some command line.

That said, I like the new intro.

@LegionnaireG
Copy link

LegionnaireG commented Feb 8, 2026

I don't think people will understand what it means if the intro screen is this plain. On the intro, maybe add 3 to 5 sentences with the key achievements of TheSuperHackers. Maybe something like:

  We've patched up the game to bring you:
  - Improving game stability
  - Unlocked 60+ FPS for single player
  - Significant reduction in mismatches for multiplayer
  - Higher graphics preset
  - Vulnerability fixes

@tintinhamans
Copy link

I don't think people will understand what it means if the intro screen is this plain. On the intro, maybe add 3 to 5 sentences with the key achievements of TheSuperHackers. Maybe something like:

  We've patched up the game to bring you:
  - Improving game stability
  - Unlocked 60+ FPS for single player
  - Significant reduction in mismatches for multiplayer
  - Higher graphics preset
  - Vulnerability fixes

I feel like adding too much text won't really be very useful given the fact that it's only shown for 3 seconds.

@xezon
Copy link
Author

xezon commented Feb 8, 2026

I feel like adding too much text won't really be very useful given the fact that it's only shown for 3 seconds.

I agree with this sentiment.

What we can add is a "Improved by" on top, to clarify that this Author has improved the game. This is very simple and broad.

@xezon
Copy link
Author

xezon commented Feb 9, 2026

When this is merged I will make a follow up to skip the entire intro sequence with a single ESC press. This will alleviate any waiting pains for impatient users.

@xezon xezon force-pushed the xezon/add-new-intro branch from 1a738f7 to 29b1ce7 Compare February 11, 2026 19:46
@xezon
Copy link
Author

xezon commented Feb 11, 2026

Improvements applied according to feedbacks:

  • Removed all individual contributor names (to be shown in Credits Menu instead)
  • Replaced github url with domain name
  • Added pretext to clarify that we did not built the game, but improved it
image

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

12 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@greptile-apps
Copy link

greptile-apps bot commented Feb 11, 2026

Additional Comments (1)

GeneralsMD/Code/GameEngine/Source/GameClient/GameClient.cpp
Missing cleanup of m_intro in destructor - potential memory leak if GameClient is destroyed before intro completes.

	delete m_intro;
	m_intro = nullptr;
Prompt To Fix With AI
This is a comment left during a code review.
Path: GeneralsMD/Code/GameEngine/Source/GameClient/GameClient.cpp
Line: 119:119

Comment:
Missing cleanup of `m_intro` in destructor - potential memory leak if `GameClient` is destroyed before intro completes.

```suggestion
	delete m_intro;
	m_intro = nullptr;
```

How can I resolve this? If you propose a fix, please make it concise.

@xezon xezon force-pushed the xezon/add-new-intro branch from 29b1ce7 to 9c82551 Compare February 11, 2026 19:55
@xezon xezon requested a review from tintinhamans February 11, 2026 19:58
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

12 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@xezon
Copy link
Author

xezon commented Feb 11, 2026

Maybe text can be made a bit bigger.

@fbraz3
Copy link

fbraz3 commented Feb 13, 2026

A suggestion: the credits screen would display all contributors names.

Something like:

# TheSuperHackers Team

Name 1 - Role
Name 2 - Role
Name 3 - Role
......

# Individual Contributors

Name 4 - 100 commits
Name 5 - 95 commits
.....

# EA games
......
......
......

The git summary command from Git Extras can be used to generate the individual contributors report and add it dinamically on build time.
https://github.com/tj/git-extras/blob/main/Commands.md#git-summary

@xezon xezon force-pushed the xezon/add-new-intro branch from dc44ab3 to 0f958d9 Compare February 22, 2026 09:45
@xezon
Copy link
Author

xezon commented Feb 22, 2026

Text was made bigger. And font scaling was made strict with factor 1.0. It will always look the same on any resolution, independent of Language.ini setups.

image

@xezon xezon force-pushed the xezon/add-new-intro branch from 0f958d9 to 12e53a2 Compare February 24, 2026 21:50
@xezon xezon force-pushed the xezon/add-new-intro branch from 12e53a2 to 832f3d8 Compare March 9, 2026 19:59
@Mauller
Copy link

Mauller commented Mar 10, 2026

How about some old school ASCII text? Like the Atari days.

  _______ _             _____                       _    _            _                 
 |__   __| |           / ____|                     | |  | |          | |                
    | |  | |__   ___  | (___  _   _ _ __   ___ _ __| |__| | __ _  ___| | _____ _ __ ___ 
    | |  | '_ \ / _ \  \___ \| | | | '_ \ / _ \ '__|  __  |/ _` |/ __| |/ / _ \ '__/ __|
    | |  | | | |  __/  ____) | |_| | |_) |  __/ |  | |  | | (_| | (__|   <  __/ |  \__ \
    |_|  |_| |_|\___| |_____/ \__,_| .__/ \___|_|  |_|  |_|\__,_|\___|_|\_\___|_|  |___/
                                   | |                                                  
                                   |_|                                                  

@xezon xezon force-pushed the xezon/add-new-intro branch from 832f3d8 to f3a985c Compare March 22, 2026 10:14
@xezon
Copy link
Author

xezon commented Mar 22, 2026

How about some old school ASCII text?

Maybe is a bit difficult to read. Also makes it look like hackware.

Rebased.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Art Is art related Enhancement Is new feature or request Gen Relates to Generals Minor Severity: Minor < Major < Critical < Blocker Refactor Edits the code with insignificant behavior changes, is never user facing ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants