Skip to content

Commit c8bbad1

Browse files
bugfix(challenge): Prevent general bio text animation issues and crashes
1 parent 6266009 commit c8bbad1

1 file changed

Lines changed: 26 additions & 9 deletions

File tree

GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/ChallengeMenu.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,10 @@ void setGeneralCampaign( Int buttonIndex )
197197
//-------------------------------------------------------------------------------------------------
198198
void setGeneralBio( Int buttonIndex )
199199
{
200+
// Always reset the animation position so that a stale bioTextPosition from a previous
201+
// bio can never be used against newly-assigned (possibly shorter) bioLine strings.
202+
bioTextPosition = 0;
203+
200204
if (buttonIndex < 0 || buttonIndex >= NUM_GENERALS)
201205
return;
202206

@@ -208,8 +212,6 @@ void setGeneralBio( Int buttonIndex )
208212
const Image *image = generals[buttonIndex].getBioPortraitSmall();
209213
bioPortrait->winSetEnabledImage( 0, image );
210214
bioPortrait->winSetStatus( WIN_STATUS_IMAGE );
211-
212-
bioTextPosition = 0;
213215
bioLine1 = TheGameText->fetch(generals[buttonIndex].getBioName());
214216
bioLine2 = TheGameText->fetch(generals[buttonIndex].getBioRank());
215217
bioLine3 = TheGameText->fetch(generals[buttonIndex].getBioBranch());
@@ -278,35 +280,50 @@ Bool updateBio(Int frames)
278280
{
279281
Bool ret = FALSE;
280282

283+
// Recompute the actual total length from the current strings to ensure bioTotalLength
284+
// is never stale if the bio strings were replaced (e.g. via a rapid mouse-leave event)
285+
// before bioTextPosition could be validated against the new strings.
286+
Int actualTotalLength = bioLine1.getLength() + bioLine2.getLength() + bioLine3.getLength() + bioLine4.getLength();
287+
281288
for (Int i = 0; i < frames; i++)
282289
{
283-
if (bioTextPosition < bioTotalLength)
290+
if (bioTextPosition < actualTotalLength)
284291
{
285292
UnicodeString text;
286293
WideChar wChar;
287294
GameWindow *window;
288-
if (bioTextPosition < bioLine1.getLength())
295+
Int line1Len = bioLine1.getLength();
296+
Int line2Len = bioLine2.getLength();
297+
Int line3Len = bioLine3.getLength();
298+
Int line4Len = bioLine4.getLength();
299+
if (bioTextPosition < line1Len)
289300
{
290301
text = GadgetStaticTextGetText(bioLine1Entry);
291302
wChar = bioLine1.getCharAt(bioTextPosition);
292303
window = bioLine1Entry;
293304
}
294-
else if (bioTextPosition < bioLine1.getLength() + bioLine2.getLength())
305+
else if (bioTextPosition < line1Len + line2Len)
295306
{
307+
Int idx = bioTextPosition - line1Len;
308+
if (idx < 0 || idx >= line2Len) break;
296309
text = GadgetStaticTextGetText(bioLine2Entry);
297-
wChar = bioLine2.getCharAt(bioTextPosition - bioLine1.getLength());
310+
wChar = bioLine2.getCharAt(idx);
298311
window = bioLine2Entry;
299312
}
300-
else if (bioTextPosition < bioLine1.getLength() + bioLine2.getLength() + bioLine3.getLength())
313+
else if (bioTextPosition < line1Len + line2Len + line3Len)
301314
{
315+
Int idx = bioTextPosition - line1Len - line2Len;
316+
if (idx < 0 || idx >= line3Len) break;
302317
text = GadgetStaticTextGetText(bioLine3Entry);
303-
wChar = bioLine3.getCharAt(bioTextPosition - bioLine1.getLength() - bioLine2.getLength());
318+
wChar = bioLine3.getCharAt(idx);
304319
window = bioLine3Entry;
305320
}
306321
else
307322
{
323+
Int idx = bioTextPosition - line1Len - line2Len - line3Len;
324+
if (idx < 0 || idx >= line4Len) break;
308325
text = GadgetStaticTextGetText(bioLine4Entry);
309-
wChar = bioLine4.getCharAt(bioTextPosition - bioLine1.getLength() - bioLine2.getLength() - bioLine3.getLength());
326+
wChar = bioLine4.getCharAt(idx);
310327
window = bioLine4Entry;
311328
}
312329

0 commit comments

Comments
 (0)