Skip to content

Comments

refactor(loadscreen): Refactor the single player load screen to use TheDisplay for intro video playback#2273

Open
Mauller wants to merge 2 commits intoTheSuperHackers:mainfrom
Mauller:Mauller/refactor-loadscreen-video-playback
Open

refactor(loadscreen): Refactor the single player load screen to use TheDisplay for intro video playback#2273
Mauller wants to merge 2 commits intoTheSuperHackers:mainfrom
Mauller:Mauller/refactor-loadscreen-video-playback

Conversation

@Mauller
Copy link

@Mauller Mauller commented Feb 8, 2026

Merge with rebase

This breaks out changes from #2053 that involve the refactoring of the video playback.

I split this into two commits, one with the changes to TheDisplay for adding extra functionality, the second is the load screen refactor changes.

The other changes will come along after for video scaling options and for disabling the custom overlay during video playback.

This also fixes how the video playback is displayed in the progress bar.
Now the video progress filles the entire bar before resetting the bar for the normal data loading portion of the intro screen.


  • Replicate in generals

@Mauller Mauller self-assigned this Feb 8, 2026
@Mauller Mauller added 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 8, 2026
}

// if the display has a movie playing then we need to draw the displays video buffer
if (TheDisplay->isMoviePlaying())
Copy link
Author

@Mauller Mauller Feb 8, 2026

Choose a reason for hiding this comment

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

This is added in addition to the original drawing functionality as some screens still use the original method, such as the challenge load screen.

The challenge load screen does something more complex with it's video handling and needs looking at seperate from this change.

@greptile-apps
Copy link

greptile-apps bot commented Feb 8, 2026

Greptile Summary

This PR successfully refactors video playback in the single player load screen by centralizing video management in TheDisplay object instead of managing video buffers and streams directly in LoadScreen.

Key Changes:

  • Removed video buffer/stream management from SinglePlayerLoadScreen class
  • Added getMovieProgress() method to Display class to expose video playback progress (0.0 to 1.0)
  • Added parameterless overloads of drawVideoBuffer() and drawScaledVideoBuffer() that use Display's internal video buffer
  • Updated W3DGameWindow to draw Display's video buffer when isMoviePlaying() is true
  • Simplified load screen logic - now calls playMovie(), polls progress in loop, then calls stopMovie()
  • Fixed video progress bar to properly fill during playback and reset before data loading phase
  • Changes are mirrored identically across Generals and GeneralsMD codebases

Benefits:

  • Cleaner separation of concerns - Display owns video playback infrastructure
  • Eliminates duplicate video management code
  • Simpler and more maintainable load screen implementation
  • More accurate progress tracking for video playback

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The refactoring is well-structured with proper encapsulation, existing null checks in isMoviePlaying() protect against null pointer dereferences, the changes maintain backward compatibility by keeping original method signatures, and identical implementations across Generals/GeneralsMD reduce platform-specific bugs. Previous review concerns about null checks and progress bar handling have been addressed.
  • No files require special attention

Important Files Changed

Filename Overview
Core/GameEngine/Source/GameClient/GUI/LoadScreen.cpp Refactored to use TheDisplay's video playback methods, simplified progress tracking, and improved video progress bar logic
Generals/Code/GameEngine/Source/GameClient/Display.cpp Implemented getMovieProgress() to calculate video playback progress with proper null checks
Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp Implemented parameterless video buffer drawing methods that use internal m_videoBuffer and m_videoStream members
Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameWindow.cpp Added logic to draw TheDisplay's video buffer when isMoviePlaying() is true and no local video buffer exists
GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp Identical implementation to Generals version with parameterless video buffer drawing methods

Sequence Diagram

sequenceDiagram
    participant LoadScreen as SinglePlayerLoadScreen
    participant Display as TheDisplay
    participant VideoPlayer as TheVideoPlayer
    participant WindowManager as TheWindowManager
    participant GameWindow as W3DGameWindow
    
    LoadScreen->>Display: playMovie(movieLabel)
    Display->>VideoPlayer: open(movieName)
    VideoPlayer-->>Display: VideoStream
    Display->>Display: createVideoBuffer()
    Note over Display: Store m_videoStream & m_videoBuffer
    
    loop While movie is playing
        LoadScreen->>Display: isMoviePlaying()
        Display-->>LoadScreen: true
        LoadScreen->>Display: getMovieProgress()
        Display-->>LoadScreen: progress (0.0-1.0)
        LoadScreen->>LoadScreen: Update progress bar
        LoadScreen->>WindowManager: update()
        LoadScreen->>Display: update()
        Display->>Display: frameDecompress() & frameRender()
        LoadScreen->>Display: draw()
        Display->>GameWindow: draw window
        GameWindow->>Display: isMoviePlaying()
        Display-->>GameWindow: true
        GameWindow->>Display: drawVideoBuffer(coords)
        Display->>Display: Render video to screen
    end
    
    LoadScreen->>Display: stopMovie()
    Display->>Display: Delete buffer & close stream
Loading

Last reviewed commit: 097b484

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.

3 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Copy link

@xezon xezon left a comment

Choose a reason for hiding this comment

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

Does the loading bar in videos still work?

@Mauller
Copy link
Author

Mauller commented Feb 13, 2026

Does the loading bar in videos still work?

No i removed the video playback being part of the loading bar since the code behind it is hacky and it didn't add anything to the playback.
The window the bar is part of also needs hiding when rescaled videos are played otherwise the stretched background image shows behind the video.

@Mauller Mauller force-pushed the Mauller/refactor-loadscreen-video-playback branch from 54be1bc to a71ec34 Compare February 14, 2026 16:25
@Mauller
Copy link
Author

Mauller commented Feb 14, 2026

Tweaked to now show and properly update the progress bar during the video playback.

The bar now correctly displays where the video is during its playback, the bar then gets reset for the normal loading portion of the intro screen.

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.

8 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@Mauller Mauller force-pushed the Mauller/refactor-loadscreen-video-playback branch from a71ec34 to 03e38b6 Compare February 15, 2026 10:05
@Mauller
Copy link
Author

Mauller commented Feb 15, 2026

This should be good to go

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.

8 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

@xezon
Copy link

xezon commented Feb 15, 2026

So is this still a pure refactor or now a bugfix?

Copy link

@xezon xezon left a comment

Choose a reason for hiding this comment

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

Greptile still has comments

@Mauller
Copy link
Author

Mauller commented Feb 15, 2026

So is this still a pure refactor or now a bugfix?

it's prob a mix of both with the change of the load bar behaviour

@Mauller Mauller force-pushed the Mauller/refactor-loadscreen-video-playback branch from 03e38b6 to 53ae2e5 Compare February 15, 2026 10:46
@Mauller
Copy link
Author

Mauller commented Feb 15, 2026

Tweaked

@Mauller Mauller force-pushed the Mauller/refactor-loadscreen-video-playback branch from 53ae2e5 to ebb01a2 Compare February 19, 2026 20:40
xezon
xezon previously approved these changes Feb 19, 2026
Copy link

@xezon xezon left a comment

Choose a reason for hiding this comment

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

OK

@Mauller Mauller force-pushed the Mauller/refactor-loadscreen-video-playback branch 2 times, most recently from 39c7788 to 14332fd Compare February 19, 2026 21:19
@Mauller
Copy link
Author

Mauller commented Feb 19, 2026

Manually merged to generals, there are some differences in the loadscreen.cpp which made it a little more difficult to determine how to merge.

@xezon
Copy link

xezon commented Feb 19, 2026

Perhaps a unify is better before this?

@Mauller
Copy link
Author

Mauller commented Feb 20, 2026

Perhaps a unify is better before this?

Zero hour changes quite a bit of the load screen behaviour, including adding the challenge load screen.
The changed behaviour is also dependent on data being present for the factional theming of the load screen.

@xezon
Copy link

xezon commented Feb 20, 2026

Zero hour changes quite a bit of the load screen behaviour, including adding the challenge load screen. The changed behaviour is also dependent on data being present for the factional theming of the load screen.

I went ahead and made a merge of them with #2332

@xezon
Copy link

xezon commented Feb 21, 2026

#2332 is merged. This change can now advance.

@Mauller
Copy link
Author

Mauller commented Feb 21, 2026

#2332 is merged. This change can now advance.

Will take a look soon

@Mauller Mauller force-pushed the Mauller/refactor-loadscreen-video-playback branch from 14332fd to 097b484 Compare February 21, 2026 14:34
@Mauller
Copy link
Author

Mauller commented Feb 21, 2026

Rebased and tweaked this based on the merge

Copy link

@xezon xezon left a comment

Choose a reason for hiding this comment

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

My expectation is that this breaks Generals Campaign videos in its current form.

UnicodeString m_unicodeObjectiveLines[MAX_OBJECTIVE_LINES];

VideoBuffer *m_videoBuffer;
VideoStreamInterface *m_videoStream;
Copy link

Choose a reason for hiding this comment

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

There also is video buffer in ChallengeLoadScreen

Copy link
Author

Choose a reason for hiding this comment

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

Challenge load screen is still using the old method due to extra complexities that need handling seperately.

Copy link

Choose a reason for hiding this comment

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

So there will be another refactor?

Copy link
Author

@Mauller Mauller Feb 21, 2026

Choose a reason for hiding this comment

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

That needs handling on it's own for now, it uses a seperate video player handling object and it's not just a single video being played. The challenge screen is composed of multiple different videos.

{
#if RTS_GENERALS
// if we're min speced
m_videoStream->frameGoto(m_videoStream->frameCount()); // zero based
Copy link

Choose a reason for hiding this comment

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

What is the replacement for this? The intent here is to show the last frame of the video as a static image.

Copy link
Author

Choose a reason for hiding this comment

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

The load screen background shows instead like in zero hour.

Copy link

Choose a reason for hiding this comment

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

Why? Better preserve the original behavior.

m_videoStream->frameRender(m_videoBuffer);

#if RTS_GENERALS
moveWindows( m_videoStream->frameIndex());
Copy link

Choose a reason for hiding this comment

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

What is the replacement for this? As I understand, this is necessary to show the moving pictures and texts during Generals Campaign Videos?

Copy link
Author

Choose a reason for hiding this comment

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

i will double check this, might need to add a method to get the current frame from the video playing in TheDisplay

Copy link
Author

Choose a reason for hiding this comment

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

i need to look at this a bit more because the refactor to display the movie using TheDisplay causes the output to also show in all nested GameWindows.

@xezon xezon dismissed their stale review February 22, 2026 09:33

Outstanding questions

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

Labels

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.

2 participants