Skip to content

[GEN] Backport various crash and memory fixes from Zero Hour #692

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 17, 2025
Merged
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
2 changes: 2 additions & 0 deletions Generals/Code/GameEngine/Include/Common/Science.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ class ScienceStore : public SubsystemInterface
friend class ScienceInfo;

public:
virtual ~ScienceStore();

void init();
void reset();
void update() { }
Expand Down
12 changes: 9 additions & 3 deletions Generals/Code/GameEngine/Include/Common/SparseMatchFinder.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,16 +176,22 @@ class SparseMatchFinder
const MATCHABLE* findBestInfo(const std::vector<MATCHABLE>& v, const BITSET& bits) const
{
typename MatchMap::const_iterator it = m_bestMatches.find(bits);

const MATCHABLE *first = NULL;
if (it != m_bestMatches.end())
{
return (*it).second;
first = (*it).second;
}

if (first != NULL) {
return first;
}

const MATCHABLE* info = findBestInfoSlow(v, bits);

DEBUG_ASSERTCRASH(info != NULL, ("no suitable match for criteria was found!\n"));
if (info != NULL)
if (info != NULL) {
m_bestMatches[bits] = info;
}

return info;
}
Expand Down
4 changes: 3 additions & 1 deletion Generals/Code/GameEngine/Include/GameLogic/RankInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,13 @@ class RankInfo : public Overridable
Int m_sciencePurchasePointsGranted;
ScienceVec m_sciencesGranted;
};
EMPTY_DTOR(RankInfo)
//EMPTY_DTOR(RankInfo)

//-------------------------------------------------------------------------------------------------
class RankInfoStore : public SubsystemInterface
{
public:
virtual ~RankInfoStore();

public:
void init();
Expand Down
4 changes: 3 additions & 1 deletion Generals/Code/GameEngine/Source/Common/GlobalData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1055,8 +1055,10 @@ GlobalData::~GlobalData( void )
if (m_weaponBonusSet)
m_weaponBonusSet->deleteInstance();

if( m_theOriginal == this )
if( m_theOriginal == this ) {
m_theOriginal = NULL;
TheWritableGlobalData = NULL;
}

} // end ~GlobalData

Expand Down
2 changes: 2 additions & 0 deletions Generals/Code/GameEngine/Source/Common/MiniLog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ LogClass::~LogClass()

void LogClass::log(const char *fmt, ...)
{
if (!m_fp)
return;
static char buf[1024];
static Int lastFrame = 0;
static Int lastIndex = 0;
Expand Down
17 changes: 17 additions & 0 deletions Generals/Code/GameEngine/Source/Common/RTS/Science.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,23 @@ void ScienceStore::init()
m_sciences.clear();
}

//-----------------------------------------------------------------------------
ScienceStore::~ScienceStore()
{
// nope.
//m_sciences.clear();

// go through all sciences and delete any overrides
for (ScienceInfoVec::iterator it = m_sciences.begin(); it != m_sciences.end(); /*++it*/)
{
ScienceInfo* si = *it;
++it;
if (si) {
si->deleteInstance();
}
}
}

//-----------------------------------------------------------------------------
void ScienceStore::reset()
{
Expand Down
8 changes: 6 additions & 2 deletions Generals/Code/GameEngine/Source/Common/System/Debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ static void doStackDump();
inline Bool ignoringAsserts()
{
#ifdef DEBUG_CRASHING
return !DX8Wrapper_IsWindowed || TheGlobalData->m_debugIgnoreAsserts;
return !DX8Wrapper_IsWindowed || (TheGlobalData&&TheGlobalData->m_debugIgnoreAsserts);
#else
return !DX8Wrapper_IsWindowed;
#endif
Expand Down Expand Up @@ -468,7 +468,7 @@ void DebugCrash(const char *format, ...)
doLogOutput(theCrashBuffer);
#endif
#ifdef DEBUG_STACKTRACE
if (!TheGlobalData->m_debugIgnoreStackTrace)
if (!(TheGlobalData && TheGlobalData->m_debugIgnoreStackTrace))
{
doStackDump();
}
Expand Down Expand Up @@ -663,6 +663,10 @@ void ReleaseCrash(const char *reason)
char prevbuf[ _MAX_PATH ];
char curbuf[ _MAX_PATH ];

if (TheGlobalData==NULL) {
return; // We are shutting down, and TheGlobalData has been freed. jba. [4/15/2003]
}

strcpy(prevbuf, TheGlobalData->getPath_UserData().str());
strcat(prevbuf, RELEASECRASH_FILE_NAME_PREV);
strcpy(curbuf, TheGlobalData->getPath_UserData().str());
Expand Down
10 changes: 7 additions & 3 deletions Generals/Code/GameEngine/Source/Common/System/Xfer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ void Xfer::xferScienceType( ScienceType *science )
else
{

DEBUG_CRASH(( "xferScienceVec - Unknown xfer mode '%d'\n", getXferMode() ));
DEBUG_CRASH(( "xferScienceType - Unknown xfer mode '%d'\n", getXferMode() ));
throw XFER_MODE_UNKNOWN;

} // end else
Expand Down Expand Up @@ -577,8 +577,12 @@ void Xfer::xferScienceVec( ScienceVec *scienceVec )
// vector should be empty at this point
if( scienceVec->empty() == FALSE )
{
DEBUG_CRASH(( "xferScienceVec - vector is not empty, but should be\n" ));
throw XFER_LIST_NOT_EMPTY;
// Not worth an assert, since things can give you Sciences on creation. Just handle it and load.
scienceVec->clear();

// Homework for today. Write 2000 words reconciling "Your code must never crash" with "Intentionally putting crashes in the code". Fucktard.
// DEBUG_CRASH(( "xferScienceVec - vector is not empty, but should be\n" ));
// throw XFER_LIST_NOT_EMPTY;
}

for( UnsignedShort i = 0; i < count; ++i )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,11 @@ void ControlBar::populatePurchaseScience( Player* player )

setControlCommand( m_sciencePurchaseWindowsRank3[ i ], commandButton );
ScienceType st = SCIENCE_INVALID;
st = commandButton->getScienceVec()[ 0 ];
ScienceVec sv = commandButton->getScienceVec();
if (! sv.empty())
{
st = sv[ 0 ];
}

if( player->isScienceDisabled( st ) )
{
Expand Down Expand Up @@ -940,6 +944,10 @@ ControlBar::~ControlBar( void )
}

m_radarAttackGlowWindow = NULL;

if (m_rightHUDCameoWindow && m_rightHUDCameoWindow->winGetUserData())
delete m_rightHUDCameoWindow->winGetUserData();

} // end ~ControlBar
void ControlBarPopupDescriptionUpdateFunc( WindowLayout *layout, void *param );

Expand Down Expand Up @@ -1017,9 +1025,12 @@ void ControlBar::init( void )
id = TheNameKeyGenerator->nameToKey( windowName.str() );
m_commandWindows[ i ] =
TheWindowManager->winGetWindowFromId( m_contextParent[ CP_COMMAND ], id );
m_commandWindows[ i ]->winGetPosition(&commandPos.x, &commandPos.y);
m_commandWindows[ i ]->winGetSize(&commandSize.x, &commandSize.y);
m_commandWindows[ i ]->winSetStatus( WIN_STATUS_USE_OVERLAY_STATES );
if (m_commandWindows[ i ])
{
m_commandWindows[ i ]->winGetPosition(&commandPos.x, &commandPos.y);
m_commandWindows[ i ]->winGetSize(&commandSize.x, &commandSize.y);
m_commandWindows[ i ]->winSetStatus( WIN_STATUS_USE_OVERLAY_STATES );
}

// removed from multiplayer branch
// windowName.format( "ControlBar.wnd:CommandMarker%02d", i + 1 );
Expand Down Expand Up @@ -1052,7 +1063,7 @@ void ControlBar::init( void )
m_sciencePurchaseWindowsRank3[ i ]->winSetStatus( WIN_STATUS_USE_OVERLAY_STATES );
} // end for i

for( i = 0; i < MAX_PURCHASE_SCIENCE_RANK_8; i++ )
for( i = 0; i < MAX_PURCHASE_SCIENCE_RANK_8; i++ )
{
windowName.format( "GeneralsExpPoints.wnd:ButtonRank8Number%d", i );
id = TheNameKeyGenerator->nameToKey( windowName.str() );
Expand Down Expand Up @@ -1933,7 +1944,10 @@ CommandSet* ControlBar::findNonConstCommandSet( const AsciiString& name )
const CommandButton *ControlBar::findCommandButton( const AsciiString& name )
{
CommandButton *btn = findNonConstCommandButton(name);
btn = (CommandButton *)btn->friend_getFinalOverride();
if( btn )
{
btn = (CommandButton *)btn->friend_getFinalOverride();
}
return btn;
}

Expand Down Expand Up @@ -2059,7 +2073,11 @@ void ControlBar::switchToContext( ControlBarContext context, Drawable *draw )
//Clear any potentially flashing buttons!
for( int i = 0; i < MAX_COMMANDS_PER_SET; i++ )
{
m_commandWindows[ i ]->winClearStatus( WIN_STATUS_FLASHING );
// the implementation won't necessarily use the max number of windows possible
if (m_commandWindows[ i ])
{
m_commandWindows[ i ]->winClearStatus( WIN_STATUS_FLASHING );
}
}
// if there is a current selected drawable then we wil display a selection portrait if present
if( draw )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ void ControlBar::doTransportInventoryUI( Object *transport, const CommandSet *co
const CommandButton *commandButton;
for( Int i = 0; i < MAX_COMMANDS_PER_SET; i++ )
{
// our implementation doesn't necessarily make use of the max possible command buttons
if (! m_commandWindows[ i ]) continue;

// get command button
commandButton = commandSet->getCommandButton(i);
Expand Down Expand Up @@ -213,6 +215,9 @@ void ControlBar::doTransportInventoryUI( Object *transport, const CommandSet *co
m_commandWindows[ i ]->winHide( TRUE );
}


// is this where we set the cameos disabled when container is subdued?

// if we've counted more UI spots than the transport can hold, hide this command window
if( inventoryCommandCount > transportMax )
m_commandWindows[ i ]->winHide( TRUE );
Expand Down Expand Up @@ -279,7 +284,10 @@ void ControlBar::populateCommand( Object *obj )

// hide all the buttons
for( i = 0; i < MAX_COMMANDS_PER_SET; i++ )
m_commandWindows[ i ]->winHide( TRUE );
if (m_commandWindows[ i ])
{
m_commandWindows[ i ]->winHide( TRUE );
}

// nothing left to do
return;
Expand All @@ -294,6 +302,8 @@ void ControlBar::populateCommand( Object *obj )
const CommandButton *commandButton;
for( i = 0; i < MAX_COMMANDS_PER_SET; i++ )
{
// our implementation doesn't necessarily make use of the max possible command buttons
if (! m_commandWindows[ i ]) continue;

// get command button
commandButton = commandSet->getCommandButton(i);
Expand Down Expand Up @@ -377,7 +387,7 @@ void ControlBar::populateCommand( Object *obj )
//Now we have to search through the command buttons to find a matching purchase science button.
for( const CommandButton *command = m_commandButtons; command; command = command->getNext() )
{
if( command->getCommandType() == GUI_COMMAND_PURCHASE_SCIENCE )
if( command && command->getCommandType() == GUI_COMMAND_PURCHASE_SCIENCE )
{
//All purchase sciences specify a single science.
if( command->getScienceVec().empty() )
Expand Down Expand Up @@ -732,6 +742,9 @@ void ControlBar::updateContextCommand( void )
GameWindow *win;
const CommandButton *command;

// our implementation doesn't necessarily make use of the max possible command buttons
if (! m_commandWindows[ i ]) continue;

// get the window
win = m_commandWindows[ i ];

Expand Down Expand Up @@ -1277,7 +1290,7 @@ CommandAvailability ControlBar::getCommandAvailability( const CommandButton *com
}
else if( SpecialAbilityUpdate *spUpdate = obj->findSpecialAbilityUpdate( command->getSpecialPowerTemplate()->getSpecialPowerType() ) )
{
if( spUpdate->isPowerCurrentlyInUse( command ) )
if( spUpdate && spUpdate->isPowerCurrentlyInUse( command ) )
{
return COMMAND_RESTRICTED;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ CBCommandStatus ControlBar::processCommandUI( GameWindow *control,
{
// get the command pointer from the control user data we put in the button
const CommandButton *commandButton = (const CommandButton *)GadgetButtonGetData(control);
if( !commandButton )
{
DEBUG_CRASH( ("ControlBar::processCommandUI() -- Button activated has no data. Ignoring...") );
return CBC_COMMAND_NOT_USED;
}

// sanity, we won't process messages if we have no source object,
// unless we're CB_CONTEXT_PURCHASE_SCIENCE or GUI_COMMAND_SPECIAL_POWER_FROM_COMMAND_CENTER
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ void ControlBar::addCommonCommands( Drawable *draw, Bool firstDrawable )
{

m_commonCommands[ i ] = NULL;
m_commandWindows[ i ]->winHide( TRUE );
if (m_commandWindows[ i ])
{
m_commandWindows[ i ]->winHide( TRUE );
}
// After Every change to the m_commandWIndows, we need to show fill in the missing blanks with the images
// removed from multiplayer branch
//showCommandMarkers();
Expand All @@ -118,6 +121,8 @@ void ControlBar::addCommonCommands( Drawable *draw, Bool firstDrawable )
// just add each command that is classified as a common command
for( i = 0; i < MAX_COMMANDS_PER_SET; i++ )
{
// our implementation doesn't necessarily make use of the max possible command buttons
if (! m_commandWindows[ i ]) continue;

// get command
command = commandSet->getCommandButton(i);
Expand Down Expand Up @@ -148,6 +153,9 @@ void ControlBar::addCommonCommands( Drawable *draw, Bool firstDrawable )
for( i = 0; i < MAX_COMMANDS_PER_SET; i++ )
{

// our implementation doesn't necessarily make use of the max possible command buttons
if (! m_commandWindows[ i ]) continue;

// get the command
command = commandSet->getCommandButton(i);

Expand Down Expand Up @@ -213,7 +221,12 @@ void ControlBar::populateMultiSelect( void )

// by default, hide all the controls in the command section
for( Int i = 0; i < MAX_COMMANDS_PER_SET; i++ )
m_commandWindows[ i ]->winHide( TRUE );
{
if (m_commandWindows[ i ])
{
m_commandWindows[ i ]->winHide( TRUE );
}
}

// sanity
DEBUG_ASSERTCRASH( TheInGameUI->getSelectCount() > 1,
Expand Down Expand Up @@ -333,6 +346,9 @@ void ControlBar::updateContextMultiSelect( void )
// get the control window
win = m_commandWindows[ i ];

// our implementation doesn't necessarily make use of the max possible command buttons
if (!win) continue;

// don't consider hidden windows
if( win->winIsHidden() == TRUE )
continue;
Expand Down Expand Up @@ -389,6 +405,8 @@ void ControlBar::updateContextMultiSelect( void )
//
for( i = 0; i < MAX_COMMANDS_PER_SET; i++ )
{
// our implementation doesn't necessarily make use of the max possible command buttons
if (! m_commandWindows[ i ]) continue;

// don't consider hidden commands
if( m_commandWindows[ i ]->winIsHidden() == TRUE )
Expand Down
Loading