Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3567,6 +3567,12 @@ void InGameUI::postWindowDraw( void )
Int hudOffsetX = 0;
Int hudOffsetY = 0;

// TheSuperHackers @info During video playback we don't want custom overlay elements showing
if (TheDisplay->isMoviePlaying())
Copy link

Choose a reason for hiding this comment

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

Should this test perhaps be higher up the call chain? Because it seems oddly specific to just return this call and none of the other window draw functions. Why are the other window draw functions not necessary to exclude from video playback?

Copy link
Author

Choose a reason for hiding this comment

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

The custom overlay we added as a post post draw is the only one that really interferes with video playback, the majority of the other draw functions don't enter the code within themselves since there is no text or other objects to display.

{
return;
}

if (m_networkLatencyPointSize > 0 && TheGameLogic->isInMultiplayerGame())
{
drawNetworkLatency(hudOffsetX, hudOffsetY);
Expand Down
1 change: 1 addition & 0 deletions GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ class GlobalData : public SubsystemInterface
Bool m_sounds3DOn;
Bool m_speechOn;
Bool m_videoOn;
Bool m_maintainVideoAspect;
Bool m_disableCameraMovement;

Bool m_useFX; ///< If false, don't render effects
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ class OptionPreferences : public UserPreferences
Real getResolutionFontAdjustment(void);

Bool getShowMoneyPerMinute(void) const;
Bool getMaintainVideoAspect(void) const;
};

//-----------------------------------------------------------------------------
Expand Down
11 changes: 9 additions & 2 deletions GeneralsMD/Code/GameEngine/Include/GameClient/Display.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,15 +143,18 @@ class Display : public SubsystemInterface

/// draw a video buffer fit within the screen coordinates
virtual void drawScaledVideoBuffer( VideoBuffer *buffer, VideoStreamInterface *stream ) = 0;
virtual void drawVideoBuffer( VideoBuffer *buffer, Int startX, Int startY,
Int endX, Int endY ) = 0;
virtual void drawScaledVideoBuffer() = 0;
virtual void drawVideoBuffer( VideoBuffer *buffer, Int startX, Int startY, Int endX, Int endY ) = 0;
virtual void drawVideoBuffer(Int startX, Int startY, Int endX, Int endY) = 0;

/// FullScreen video playback
virtual void playLogoMovie( AsciiString movieName, Int minMovieLength, Int minCopyrightLength );
virtual void playMovie( AsciiString movieName );
virtual void stopMovie( void );
virtual Bool isMoviePlaying(void);

virtual VideoBuffer* getVideoBuffer() { return m_videoBuffer; }

/// Register debug display callback
virtual void setDebugDisplayCallback( DebugDisplayCallback *callback, void *userData = NULL );
virtual DebugDisplayCallback *getDebugDisplayCallback();
Expand All @@ -173,6 +176,9 @@ class Display : public SubsystemInterface
virtual Bool isLetterBoxFading( void ) { return FALSE; } ///< returns true while letterbox fades in/out
virtual Bool isLetterBoxed( void ) { return FALSE; } //WST 10/2/2002. Added query interface

virtual void setMaintainVideoAspect(Bool maintainAspect) { m_maintainVideoAspect = maintainAspect; }
virtual Bool isVideoAspectMaintained() { return m_maintainVideoAspect; }

virtual void setCinematicText( AsciiString string ) { m_cinematicText = string; }
virtual void setCinematicFont( GameFont *font ) { m_cinematicFont = font; }
virtual void setCinematicTextFrames( Int frames ) { m_cinematicTextFrames = frames; }
Expand Down Expand Up @@ -205,6 +211,7 @@ class Display : public SubsystemInterface
void *m_debugDisplayUserData; ///< Data for debug display update handler
Real m_letterBoxFadeLevel; ///<tracks the current alpha level for fading letter-boxed mode in/out.
Bool m_letterBoxEnabled; ///<current state of letterbox
Bool m_maintainVideoAspect;
UnsignedInt m_letterBoxFadeStartTime; ///< time of letterbox fade start
Int m_movieHoldTime; ///< time that we hold on the last frame of the movie
Int m_copyrightHoldTime; ///< time that the copyright must be on the screen
Expand Down
3 changes: 3 additions & 0 deletions GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ GlobalData* GlobalData::m_theOriginal = NULL;
{ "Sounds3DOn", INI::parseBool, NULL, offsetof( GlobalData, m_sounds3DOn ) },
{ "SpeechOn", INI::parseBool, NULL, offsetof( GlobalData, m_speechOn ) },
{ "VideoOn", INI::parseBool, NULL, offsetof( GlobalData, m_videoOn ) },
{ "MaintainVideoAspect", INI::parseBool, NULL, offsetof(GlobalData, m_maintainVideoAspect) },
{ "DisableCameraMovements", INI::parseBool, NULL, offsetof( GlobalData, m_disableCameraMovement ) },

/* These are internal use only, they do not need file definitons
Expand Down Expand Up @@ -784,6 +785,7 @@ GlobalData::GlobalData()
m_sounds3DOn = TRUE;
m_speechOn = TRUE;
m_videoOn = TRUE;
m_maintainVideoAspect = TRUE;
m_disableCameraMovement = FALSE;
m_maxVisibleTranslucentObjects = 512;
m_maxVisibleOccluderObjects = 512;
Expand Down Expand Up @@ -1226,6 +1228,7 @@ void GlobalData::parseGameDataDefinition( INI* ini )
TheWritableGlobalData->m_systemTimeFontSize = optionPref.getSystemTimeFontSize();
TheWritableGlobalData->m_gameTimeFontSize = optionPref.getGameTimeFontSize();
TheWritableGlobalData->m_showMoneyPerMinute = optionPref.getShowMoneyPerMinute();
TheWritableGlobalData->m_maintainVideoAspect = optionPref.getMaintainVideoAspect();

Int val=optionPref.getGammaValue();
//generate a value between 0.6 and 2.0.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -995,6 +995,19 @@ Bool OptionPreferences::getShowMoneyPerMinute(void) const
return FALSE;
}

Bool OptionPreferences::getMaintainVideoAspect(void) const
{
OptionPreferences::const_iterator it = find("MaintainVideoAspect");
if (it == end())
return TheGlobalData->m_maintainVideoAspect;

if (stricmp(it->second.str(), "yes") == 0)
{
return TRUE;
}
return FALSE;
}

static OptionPreferences *pref = NULL;

static void setDefaults( void )
Expand Down Expand Up @@ -1574,6 +1587,16 @@ static void saveOptions( void )
TheWritableGlobalData->m_showMoneyPerMinute = show;
}

//-------------------------------------------------------------------------------------------------
// Set Video Scaling
{
Bool maintainAspect = pref->getMaintainVideoAspect();
AsciiString prefString;
prefString = maintainAspect ? "yes" : "no";
(*pref)["MaintainVideoAspect"] = prefString;
TheWritableGlobalData->m_maintainVideoAspect = maintainAspect;
}

//-------------------------------------------------------------------------------------------------
// Resolution
//
Expand Down
76 changes: 13 additions & 63 deletions GeneralsMD/Code/GameEngine/Source/GameClient/GUI/LoadScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,32 +476,6 @@ void SinglePlayerLoadScreen::init( GameInfo *game )

*/
m_ambientLoop.setEventName("LoadScreenAmbient");
// create the new stream
m_videoStream = TheVideoPlayer->open( TheCampaignManager->getCurrentMission()->m_movieLabel );
Copy link

Choose a reason for hiding this comment

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

Are m_videoStream, m_videoBuffer still required to exist then?

Would it make sense to first make a single refactor change that merges all the video playbacks into the same code before doing any of the other changes?

Because it looks to me that this change does multiple different but related things right now.

Copy link
Author

@Mauller Mauller Jan 4, 2026

Choose a reason for hiding this comment

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

they are no longer required because i am making use of the video handling within TheDisplay instead.
This has it's own m_videoStream and m_videoBuffer handling within itself.

The majority of the changes within this PR just handle the moving of the video handling out of LoadScreen.cpp and into TheDisplay instead. All of the tweaks to handle hiding the custom overlay and adding the user option are minor in comparisson.

I don't think it's entirely worth it's own PR for that, but i could move them into their own commits?

Copy link

Choose a reason for hiding this comment

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

I think m_videoStream, m_videoBuffer were not removed. They are now unused.

Separate Pull or Commit makes sense, because the video change is a refactor, nothing user facing, whereas the clock visuals change is user facing.

if ( m_videoStream == NULL )
{
m_percent->winHide(TRUE);
return;
}

// Create the new buffer
m_videoBuffer = TheDisplay->createVideoBuffer();
if ( m_videoBuffer == NULL ||
!m_videoBuffer->allocate( m_videoStream->width(),
m_videoStream->height())
)
{
delete m_videoBuffer;
m_videoBuffer = NULL;

if ( m_videoStream )
{
m_videoStream->close();
m_videoStream = NULL;
}

return;
}

// format the progress bar: USA to blue, GLA to green, China to red
// and set the background image
Expand Down Expand Up @@ -530,9 +504,13 @@ void SinglePlayerLoadScreen::init( GameInfo *game )
// TheSuperHackers @bugfix Originally this movie render loop stopped rendering when the game window was inactive.
// This either skipped the movie or caused decompression artifacts. Now the video just keeps playing until it done.

Int progressUpdateCount = m_videoStream->frameCount() / FRAME_FUDGE_ADD;
Int shiftedPercent = -FRAME_FUDGE_ADD + 1;
while (m_videoStream->frameIndex() < m_videoStream->frameCount() - 1 )
// Hide the background window while the movie is playing
backgroundWin->winEnable(false);

// TheSuperHackers @info We now make use of movie playback within the display object
TheDisplay->playMovie(TheCampaignManager->getCurrentMission()->m_movieLabel);

while(TheDisplay->isMoviePlaying())
{
// TheSuperHackers @feature User can now skip video by pressing ESC
if (TheKeyboard)
Expand All @@ -548,51 +526,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();
}

// let the background image show through
m_videoStream->close();
m_videoStream = NULL;
m_loadScreen->winGetInstanceData()->setVideoBuffer( NULL );
TheDisplay->stopMovie();
backgroundWin->winEnable(true);
TheDisplay->draw();
}
else
{
// if we're min spec'ed don't play a movie

backgroundWin->winEnable(true);

Int delay = mission->m_voiceLength * 1000;
Int begin = timeGetTime();
Int currTime = begin;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ void GameClient::init( void )
if( TheDisplay ) {
TheDisplay->init();
TheDisplay->setName("TheDisplay");
TheDisplay->setMaintainVideoAspect(TheGlobalData->m_maintainVideoAspect);
}

TheHeaderTemplateManager = MSGNEW("GameClientSubsystem") HeaderTemplateManager;
Expand Down
6 changes: 6 additions & 0 deletions GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3658,6 +3658,12 @@ void InGameUI::postWindowDraw( void )
Int hudOffsetX = 0;
Int hudOffsetY = 0;

// TheSuperHackers @info During video playback we don't want custom overlay elements showing
if (TheDisplay->isMoviePlaying())
{
return;
}

if (m_networkLatencyPointSize > 0 && TheGameLogic->isInMultiplayerGame())
{
drawNetworkLatency(hudOffsetX, hudOffsetY);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,9 @@ class W3DDisplay : public Display

/// draw a video buffer fit within the screen coordinates
virtual void drawScaledVideoBuffer( VideoBuffer *buffer, VideoStreamInterface *stream );
virtual void drawVideoBuffer( VideoBuffer *buffer, Int startX, Int startY,
Int endX, Int endY );
virtual void drawScaledVideoBuffer();
virtual void drawVideoBuffer( VideoBuffer *buffer, Int startX, Int startY, Int endX, Int endY );
virtual void drawVideoBuffer( Int startX, Int startY, Int endX, Int endY );

virtual VideoBuffer* createVideoBuffer( void ) ; ///< Create a video buffer that can be used for this display

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,14 +378,21 @@ void W3DGameWinDefaultDraw( GameWindow *window, WinInstanceData *instData )

}

// if we have a video buffer, draw the video buffer
if ( instData->m_videoBuffer )
// if the display has a movie playing then we need to draw the video buffer
if( TheDisplay->isMoviePlaying() )
{
ICoord2D pos, size;
window->winGetScreenPosition( &pos.x, &pos.y );
window->winGetSize( &size.x, &size.y );

TheDisplay->drawVideoBuffer( instData->m_videoBuffer, pos.x, pos.y, pos.x + size.x, pos.y + size.y );
if (TheDisplay->isVideoAspectMaintained()) {
TheDisplay->drawScaledVideoBuffer();
}
else {
ICoord2D pos, size;
window->winGetScreenPosition( &pos.x, &pos.y );
window->winGetSize( &size.x, &size.y );

TheDisplay->drawVideoBuffer( pos.x, pos.y, pos.x + size.x, pos.y + size.y );
}

}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2850,6 +2850,11 @@ void W3DDisplay::drawScaledVideoBuffer( VideoBuffer *buffer, VideoStreamInterfac
drawVideoBuffer( buffer, startX, startY, endX, endY );
}

void W3DDisplay::drawScaledVideoBuffer()
{
drawScaledVideoBuffer(m_videoBuffer, m_videoStream);
}

//============================================================================
// W3DDisplay::drawVideoBuffer
//============================================================================
Expand All @@ -2867,6 +2872,11 @@ void W3DDisplay::drawVideoBuffer( VideoBuffer *buffer, Int startX, Int startY, I

}

void W3DDisplay::drawVideoBuffer( Int startX, Int startY, Int endX, Int endY )
{
TheDisplay->drawVideoBuffer(m_videoBuffer, startX, startY, endX, endY);
}

// W3DDisplay::setClipRegion ============================================
/** Set the clipping region for images.
@todo: Make this work for all primitives, not just drawImage. */
Expand Down
8 changes: 5 additions & 3 deletions GeneralsMD/Code/Tools/GUIEdit/Include/GUIEditDisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,11 @@ class GUIEditDisplay : public Display
virtual VideoBuffer* createVideoBuffer( void ) { return NULL; }

/// draw a video buffer fit within the screen coordinates
virtual void drawScaledVideoBuffer( VideoBuffer *buffer, VideoStreamInterface *stream ) { }
virtual void drawVideoBuffer( VideoBuffer *buffer, Int startX, Int startY,
Int endX, Int endY ) { }
virtual void drawScaledVideoBuffer(VideoBuffer* buffer, VideoStreamInterface* stream) { }
virtual void drawScaledVideoBuffer() { }
virtual void drawVideoBuffer(VideoBuffer* buffer, Int startX, Int startY, Int endX, Int endY) { }
virtual void drawVideoBuffer(Int startX, Int startY, Int endX, Int endY) { }

virtual void takeScreenShot(void){ }
virtual void toggleMovieCapture(void) {}

Expand Down
Loading