refactor(loadscreen): Refactor the single player load screen to use TheDisplay for intro video playback#2273
Conversation
…lay for video playback (#)
| } | ||
|
|
||
| // if the display has a movie playing then we need to draw the displays video buffer | ||
| if (TheDisplay->isMoviePlaying()) |
There was a problem hiding this comment.
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 Overview
|
| Filename | Overview |
|---|---|
| GeneralsMD/Code/GameEngine/Source/GameClient/Display.cpp | Implemented getMovieProgress() to calculate video progress percentage; potential null pointer dereference if called outside of movie playback |
| GeneralsMD/Code/GameEngine/Source/GameClient/GUI/LoadScreen.cpp | Refactored video playback to use TheDisplay's internal buffers; simplified loop logic; progress bar now updates based on movie progress; background window handling improved |
| GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameWindow.cpp | Added automatic rendering of TheDisplay's internal video buffer when a movie is playing |
Sequence Diagram
sequenceDiagram
participant LoadScreen as SinglePlayerLoadScreen
participant Display as TheDisplay
participant VideoPlayer as TheVideoPlayer
participant WindowMgr as TheWindowManager
participant GameWindow as W3DGameWindow
LoadScreen->>LoadScreen: Hide background window
LoadScreen->>LoadScreen: Enable progress bar
LoadScreen->>Display: playMovie(movieLabel)
Display->>VideoPlayer: open(movieLabel)
VideoPlayer-->>Display: videoStream
Display->>Display: createVideoBuffer()
Display->>Display: Set m_videoStream & m_videoBuffer
loop while isMoviePlaying()
LoadScreen->>Display: getMovieProgress()
Display-->>LoadScreen: progress percentage
LoadScreen->>LoadScreen: Update progress bar
LoadScreen->>WindowMgr: update()
LoadScreen->>Display: update()
LoadScreen->>Display: draw()
Display->>GameWindow: drawVideoBuffer()
GameWindow->>Display: drawVideoBuffer(coords)
Display->>Display: Render video frame
end
LoadScreen->>Display: stopMovie()
Display->>Display: Clean up m_videoStream & m_videoBuffer
LoadScreen->>LoadScreen: Re-enable background window
Last reviewed commit: a71ec34
| @@ -548,51 +515,23 @@ void SinglePlayerLoadScreen::init( GameInfo *game ) | |||
|
|
|||
| TheGameEngine->serviceWindowsOS(); | |||
|
|
|||
| if(!m_videoStream->isFrameReady()) | |||
| { | |||
| Sleep(1); | |||
| continue; | |||
| } | |||
|
|
|||
| m_videoStream->frameDecompress(); | |||
| m_videoStream->frameRender(m_videoBuffer); | |||
|
|
|||
| // PULLED FROM THE MISSION DISK | |||
| // moveWindows( m_videoStream->frameIndex()); | |||
|
|
|||
| m_videoStream->frameNext(); | |||
|
|
|||
| if(m_videoBuffer) | |||
| m_loadScreen->winGetInstanceData()->setVideoBuffer(m_videoBuffer); | |||
| if(m_videoStream->frameIndex() % progressUpdateCount == 0) | |||
| { | |||
| shiftedPercent++; | |||
| if(shiftedPercent >0) | |||
| shiftedPercent = 0; | |||
| Int percent = (shiftedPercent + FRAME_FUDGE_ADD)/1.3; | |||
| UnicodeString per; | |||
| per.format(L"%d%%",percent); | |||
| TheMouse->setCursorTooltip(UnicodeString::TheEmptyString); | |||
| GadgetProgressBarSetProgress(m_progressBar, percent); | |||
| GadgetStaticTextSetText(m_percent, per); | |||
|
|
|||
| } | |||
| TheWindowManager->update(); | |||
|
|
|||
| // redraw all views, update the GUI | |||
| TheWindowManager->update(); | |||
| TheDisplay->update(); | |||
| TheDisplay->draw(); | |||
| } | |||
There was a problem hiding this comment.
Progress bar update logic was removed during video playback. The old implementation updated the progress bar based on video frame count, but now the loop only checks isMoviePlaying() without updating any visual progress indicator. Check whether this removal was intentional.
Prompt To Fix With AI
This is a comment left during a code review.
Path: GeneralsMD/Code/GameEngine/Source/GameClient/GUI/LoadScreen.cpp
Line: 502:522
Comment:
Progress bar update logic was removed during video playback. The old implementation updated the progress bar based on video frame count, but now the loop only checks `isMoviePlaying()` without updating any visual progress indicator. Check whether this removal was intentional.
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
The removal was intentional as the progress bar handling was already considered a hack and added nothing to the video playback
There was a problem hiding this comment.
It actually does show a loading bar at the bottom. Seen in USA 01 Mission Load Screen:
![]()
i know, i removed the loading bar since it doesn't really add anything and the code behind it functioning for showing the video playback is hacky. The portion of the bar that progresses while the video plays back is a small 1/20 th of the bars overall length. So seems better to just use it to report loading progress.
The window it is part of also has to be hidden when rescaled videos are played otherwise it shows behind the video.
There was a problem hiding this comment.
I think the purpose of the loading bar is to show how long the video will play? Would be good to keep it.
There was a problem hiding this comment.
I think the purpose of the loading bar is to show how long the video will play? Would be good to keep it.
I can check it again but i am sure the video doesn't fill the bar during playback, it only fills a tiny portion at the beginning and the rest is filled when the rest of the game data is loading.
There was a problem hiding this comment.
If that is the case, maybe we fix the loading bar. It should be possible to calculate the loading progress because the video length is known.
There was a problem hiding this comment.
Managed to implement the video bar, while making it progress with the video playback, in an easier way than i initially expected.
xezon
left a comment
There was a problem hiding this comment.
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. |
54be1bc to
a71ec34
Compare
|
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. |
| Real Display::getMovieProgress() | ||
| { | ||
| return (Real)m_videoStream->frameIndex() / (Real)m_videoStream->frameCount() * 100.0f; | ||
| } |
There was a problem hiding this comment.
Potential null pointer dereference if m_videoStream is null. Should check m_videoStream before dereferencing.
| Real Display::getMovieProgress() | |
| { | |
| return (Real)m_videoStream->frameIndex() / (Real)m_videoStream->frameCount() * 100.0f; | |
| } | |
| Real Display::getMovieProgress() | |
| { | |
| if (m_videoStream == nullptr) | |
| return 0.0f; | |
| return (Real)m_videoStream->frameIndex() / (Real)m_videoStream->frameCount() * 100.0f; | |
| } |
Prompt To Fix With AI
This is a comment left during a code review.
Path: GeneralsMD/Code/GameEngine/Source/GameClient/Display.cpp
Line: 367:370
Comment:
Potential null pointer dereference if `m_videoStream` is null. Should check `m_videoStream` before dereferencing.
```suggestion
Real Display::getMovieProgress()
{
if (m_videoStream == nullptr)
return 0.0f;
return (Real)m_videoStream->frameIndex() / (Real)m_videoStream->frameCount() * 100.0f;
}
```
How can I resolve this? If you propose a fix, please make it concise.

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.