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.
|
| Filename | Overview |
|---|---|
| GeneralsMD/Code/GameEngine/Source/GameClient/Display.cpp | Implemented getMovieProgress() to calculate video progress as frame ratio (0.0 to 1.0) with null check |
| GeneralsMD/Code/GameEngine/Source/GameClient/GUI/LoadScreen.cpp | Refactored to use TheDisplay for video playback instead of local video management, simplified the loop, improved progress bar to fill during video playback, added explicit reset of progress bar after video completes |
| GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp | Implemented parameterless overloads that delegate to existing methods using internal m_videoBuffer and m_videoStream |
| GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameWindow.cpp | Added rendering logic to draw Display's video buffer when isMoviePlaying() is true, enabling centralized video playback |
Sequence Diagram
sequenceDiagram
participant LoadScreen as SinglePlayerLoadScreen
participant Display as TheDisplay
participant VideoPlayer as TheVideoPlayer
participant GameWindow as W3DGameWindow
participant WindowManager as TheWindowManager
Note over LoadScreen: Video Playback Refactoring
LoadScreen->>Display: playMovie(movieLabel)
Display->>VideoPlayer: open(movieLabel)
VideoPlayer-->>Display: VideoStream
Display->>Display: createVideoBuffer()
Display->>Display: allocate buffer
Note over Display: Stores m_videoStream & m_videoBuffer
loop While isMoviePlaying()
LoadScreen->>Display: isMoviePlaying()
Display-->>LoadScreen: true
LoadScreen->>Display: getMovieProgress()
Display-->>LoadScreen: frameIndex/frameCount
LoadScreen->>LoadScreen: Update progress bar
LoadScreen->>WindowManager: update()
LoadScreen->>Display: update()
Note over Display: frameDecompress() & frameRender()
Display->>Display: Process video frame
LoadScreen->>Display: draw()
Display->>GameWindow: drawVideoBuffer(coords)
GameWindow->>Display: isMoviePlaying()
Display-->>GameWindow: true
GameWindow->>Display: drawVideoBuffer(x, y, x+w, y+h)
Note over GameWindow: Renders video to screen
end
LoadScreen->>Display: stopMovie()
Display->>Display: Close stream & free buffer
LoadScreen->>LoadScreen: Reset progress bar to 0
Last reviewed commit: 53ae2e5
| @@ -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. |
a71ec34 to
03e38b6
Compare
|
This should be good to go |
| void W3DDisplay::drawScaledVideoBuffer() | ||
| { | ||
| drawScaledVideoBuffer(m_videoBuffer, m_videoStream); | ||
| } |
There was a problem hiding this comment.
Missing null check before dereferencing m_videoBuffer and m_videoStream. The original method at line 2813 doesn't check either, but since this is being called from W3DGameWindow.cpp:398 which already checks isMoviePlaying(), it should be safe. However, defensive programming suggests adding a check here as well.
| void W3DDisplay::drawScaledVideoBuffer() | |
| { | |
| drawScaledVideoBuffer(m_videoBuffer, m_videoStream); | |
| } | |
| void W3DDisplay::drawScaledVideoBuffer() | |
| { | |
| if (m_videoBuffer && m_videoStream) | |
| drawScaledVideoBuffer(m_videoBuffer, m_videoStream); | |
| } |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Prompt To Fix With AI
This is a comment left during a code review.
Path: GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp
Line: 2847:2850
Comment:
Missing null check before dereferencing `m_videoBuffer` and `m_videoStream`. The original method at line 2813 doesn't check either, but since this is being called from `W3DGameWindow.cpp:398` which already checks `isMoviePlaying()`, it should be safe. However, defensive programming suggests adding a check here as well.
```suggestion
void W3DDisplay::drawScaledVideoBuffer()
{
if (m_videoBuffer && m_videoStream)
drawScaledVideoBuffer(m_videoBuffer, m_videoStream);
}
```
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise.| void W3DDisplay::drawVideoBuffer( Int startX, Int startY, Int endX, Int endY ) | ||
| { | ||
| drawVideoBuffer(m_videoBuffer, startX, startY, endX, endY); | ||
| } |
There was a problem hiding this comment.
Missing null check for m_videoBuffer before dereferencing. While isMoviePlaying() checks both pointers, adding a guard here provides an extra safety layer.
| void W3DDisplay::drawVideoBuffer( Int startX, Int startY, Int endX, Int endY ) | |
| { | |
| drawVideoBuffer(m_videoBuffer, startX, startY, endX, endY); | |
| } | |
| void W3DDisplay::drawVideoBuffer( Int startX, Int startY, Int endX, Int endY ) | |
| { | |
| if (m_videoBuffer) | |
| drawVideoBuffer(m_videoBuffer, startX, startY, endX, endY); | |
| } |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Prompt To Fix With AI
This is a comment left during a code review.
Path: GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp
Line: 2869:2872
Comment:
Missing null check for `m_videoBuffer` before dereferencing. While `isMoviePlaying()` checks both pointers, adding a guard here provides an extra safety layer.
```suggestion
void W3DDisplay::drawVideoBuffer( Int startX, Int startY, Int endX, Int endY )
{
if (m_videoBuffer)
drawVideoBuffer(m_videoBuffer, startX, startY, endX, endY);
}
```
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise.|
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 |
03e38b6 to
53ae2e5
Compare
|
Tweaked |


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.