* avoid undefined behavior from UNREACHABLE on reachable code paths
UNREACHABLE expands to __assume(false) / __builtin_unreachable() in
release builds, which is undefined behavior if the code is ever actually
reached. Many UNREACHABLE sites only guard against unexpected-but-
possible runtime states (values from tables, mission/save files, network
packets, scripting, or user input), so reaching them should degrade
gracefully rather than invoke UB.
Replace UNREACHABLE with Assertion(false, ...) at all such sites. It
still pops an error in debug builds, but in release it is a harmless
no-op that simply falls through to the following code. Sites that are
genuinely unreachable by local invariants (e.g. a switch over a bounded
random number) are left as UNREACHABLE.
A few converted sites had no safe fall-through -- an uninitialized read,
null dereference, or null call would have followed -- so they also get a
minimal recovery: initialize the value, guard the dereference, return
early, or skip the offending item.
Where the converted site was a simple guard of the form
if (x) { Assertion(false, ...); return; }
hoist the check onto the invariant instead:
Assertion(!x, ...);
if (x) { return; }
This states the expectation directly and shows the offending value in
the debug popup, while keeping the same graceful runtime degradation.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
* addendum
After consultation with Lafiel, use UNREACHABLE in situations that are effectively impossible even if not provably impossible. UNREACHABLE = "this shouldn't ever happen"; Assertion = "if this ever happens, it's a coding error". Also fix a few other sites and change a couple to Warnings.
---------
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
* add wing display names
Adds display name capability for wings, matching the pattern and infrastructure of display names for ships. As in #7234, wing display names take precedence over ship display names, if both are provided; because if ship display names took precedence, a ship would have the same display name in every wave.
All the relevant display locations are handled, including the HUD, escort list, message box, and mission log. Lua API support is provided as well.
Adds full support for both FRED and QtFRED, including the always-save-display-names setting.
Addresses #7189 and the last request from #1730.
* add help text from #7234
Rewrite `force_fit_string` to be more robust and to remove the potential for memory access violations. Also audit all of the length parameters in the calling functions - some of them were the buffer size, not the length. This should fix the mysterious crash in the mission log screen.
At some point the mission log became unable to display entries that wrapped around to subsequent lines. Fix that by keeping track of how many lines each entry occupies and adjusting the display accordingly.
This will correctly display mission log segments on multiple lines, but it uses the current string splitting technique which does not split properly in all cases. The splitting will work properly once the `split_str_once` refactor is merged.
* make mission log dynamic
Change the mission log from a static array to a dynamic vector. This removes any chance of the mission log running into a limit (as regularly happened with the last mission of Shepherds before the limit bump) and also prevents strange mission bugs caused by culling obsolete entries.
This also unifies the API a bit by renaming the public `message_log_` function prefixes to `mission_log_`, removing the redundant `Num_log_lines` variable, and removing `Log_scrollback_vec` from the header.
Implements #5878.
* feedback
* refactor to reference rather than pointer
This limit has not been bumped since the original public source release. The final mission in Shepherds has been experiencing mysterious bugs which were finally tracked down to the mission log overflowing its limit and discarding log entries. Ideally the mission log should be made dynamic and the pruning mechanisms removed, but for the 24.0 release, it suffices to bump the limit.
This advances the versions for Clang to 16 and GCC to 13 along with
fixing any warnings these new versions are detecting now.
The new image versions also include Vulkan so the additional workflow
step for installing that is not necessary anymore.
`gr_get_string_size` takes a length parameter, but `split_str_once` was calling it with the position instead. This led to incorrect results occasionally. If the incorrect pixel width had the bad luck to be exactly equal to the remaining space, this would cause an infinite loop. This fixes the bug and adds a bunch of safeguards to prevent a similar situation in the future.
Several things going on here:
1) refactor `get_display_string()` to `get_display_name()` to be more precise
2) likewise, refactor `alt_name` to `display_name`
3) automatically generate display names when parsing the ship, ship class, and weapon class for the first time
4) remove the on-the-fly truncation of names with hash symbols
Basically this subsumes the `end_string_at_first_hash_symbol` logic into the display name. Rather than truncate the name every time it's displayed, truncate it once when it's parsed. This takes advantage of the previous display name infrastructure, since display names are a superset of the case of truncating the hash symbol.
This also has the benefit of now allowing hash symbols within display names. When updating Destiny of Peace, I noticed that "Lockheed Shuttle #4" would no longer display properly; and it was not previously possible to fix this even with display names.
I could pull out the `get_display_string()` and `alt_name` renaming into a separate PR if desired.
This is a minor follow-up to PR #2390. There are a few minor differences between untranslated strings and the internal strings in strings.tbl; this PR fixes them.
This adds a mission file option for ships which allows specifying a
different string which should be used for displaying the name of the
ship to the user. This name will not be used in SEXPs or other ship
lookup functions so it can be freely translated and two ships can also
have the same display name.
The new feature can be used by adding $Display name: <string> after $Name
for a ship in a mission file. I think I added proper support for FRED
(and qtFRED) so that this new value is properly saved but it would be
great if someone could test that.
This implements one of the features requested in #1730.
Time-undocked will cause FSO to freeze unless you know what you're doing, so this PR fixes some gotcha areas. Inspired by The E's rant on Discord which, while not 100% correct, did indicate some areas for improvement.
1) Set the default "number of times docked" argument to 1 when the sexp is created in FRED, same as with the has-[un]docked-delay sexps
2) Catch any <= 0 counts when the sexp is called in FRED and set them to 1. (This was done for other sexps which used mission_log_get_time_indexed, but was not done for time-[un]docked for some reason.)
3) Add an assertion to mission_log_get_time_indexed as a last resort to guard against invalid counts.
This introduces a new mechanism for handling bit flags. Instead of using an int (or two, or three) to write bits into, this uses the std::bitset in a wrapper class that accepts an enum class as input. This means that certain classes of errors we've had a few of in the engine, where a coder used the wrong set of flags or checked them against the wrong variable (SF_STEALTH vs SIF_STEALTH, for example) can now be detected at a compiler level rather than not at all.
This allows to use standard TrueType Fonts for text rendering in FSO. It uses the NanoVG library which provides the ability of drawing 2D shapes. This library is used for most 2D operations now and can also be used directly by using the PathRenderer class.
--also, remove the restriction on capship cargo where ships must have the "scannable" flag
--because of the above constraints, "nothing" cannot be a meaningful subsys cargo, but then again, scanning a subsystem with "nothing" didn't do anything in the old code, so this doesn't change anything