Fixing text buffer texture/font corruption (#479) #534
Reference in New Issue
Block a user
No description provided.
Delete Branch "fix-479"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Debugging #479 has become a meandering process, with some other bugs needing to be fixed along the way. Might as well keep them in 1 PR.
<change_fps>to your replay to achieve that.I still am quite stumped on the real error for #479. I asked for help in the SFML Discord channel, here's a link to that thread (you'll need a discord account and to join the SFML group to see it). But anyway, this link makes it easy for me to consult back to what people suggested.
EDIT: Changed the title to clarify one thing I do know about this bug: the text buffer array still contains the correct text. This is a case of the
sf::Textthat's rendered onto text_area_gworld being corrupt somehow. Maybe the font gets corrupted.Fix #479
Fix #532
Fix #533
@CelticMinstrel This bug was caused by this line:
62ddf3d0b3 (diff-0352715fc63f00d5823113f53777233ac00d70eb82df14dc28b2e9366710ee86L961)When creating a new PC, the empty slot was being filled by this cPlayer constructor which set the player name to "\n". Then, pick_pc_name() would be called, putting the "\n" in as the text field's default value.
Now, I don't know why, but it appears that the larger issue here is that if we accidentally try to render a newline character, the font object becomes borked. This probably explains #454 (one instance of which this PR also fixes) and maybe #417 as well. We need to find all the ways we might end up trying to do that... And maybe add an assertion that there are no newlines in strings being drawn.
In this case, setting the default player name to empty string, fixes #479 as reproduced by the log in that thread.
Was there any reason to set the player's default name to a newline and not an empty string?
According to the blame, it looks like the "\n" default name has been in place since 16 years ago when Mac and Windows code were separate. I'm thinking its purpose is obsolete and an empty string is fine?
I found the
"\n"in the original source code released by Spiderweb Software - at party.c:528. I have no idea why it was there, but it used to be ansprintfcall. If you used blame I'm guessing you saw this as well.This strikes me as kind of weird. Are we doing something strange in our rendering? I don't think this happens in other projects where I use SFML – rendering a newline should just be a no-op. Though admittedly, other projects probably only render a newline as part of a run of text and not alone… or it's possible I had logic to split on newline so the newline actually isn't being rendered.
I’ll dig into the nitty gritty of why it happens—we should probably know
exactly why.
On Fri, Jan 17, 2025 at 8:43 AM Celtic Minstrel @.***>
wrote:
I've modified draw_startup() to just directly do some tests.
This first version, just putting "\n" in an sf::Text, doesn't break anything.

A newline in the middle of a string also doesn't break anything. Actually, SFML handles the newline.
sf::Text text("text\nwith a newline in it", *ResMgr::fonts.get("plain"), 12);Now, using our cboe library functions:
Still good.
win_draw_string with a newline in the middle:

Now I'm getting surprised this all still works.
#479 was caused by the newline being in the string for a cTextField, and those use draw_string_hilite so I tried that next:
both give the same result:

And still not reproducing the bug.
Still getting to the bottom of this.
No more messing around, I tried just launching a text field with "\n" in it:
But this still didn't break anything!
I still honestly don't know how to reproduce this bug without running the very long replay that entails printing to the buffer hundreds of times and doing all kinds of weird state changes. But even then it doesn't feel like it comes from a random memory leak, because Windows and Mac both share the problem (albeit presented differently visually).
Could the newline in the default name have been put there to avoid a segfault/out-of-bounds here?
3daf1d55e4/src/game/boe.party.cpp (L2225)Seems plausible, but that wouldn't be a segfault even on an empty string, since strings need to be null-terminated (even
std::stringneeds that so thatc_str()works), and also because a short string doesn't allocate any memory (there's no heap pointer to dereference). It would probably be an out-of-bounds assertion in some debug C++ runtimes though.