@@ -197,6 +197,10 @@ void setGeneralCampaign( Int buttonIndex )
197197// -------------------------------------------------------------------------------------------------
198198void 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