1024 is excessive. 128 leaves 25 bytes unused on Trainee (the longest
difficulty string, tied with Hotshot) at time 0:00:00. A player who
reached double-digit hours for both time on level and time in game would
need 2 bytes more. A player who rescued 100 hostages would need another
2 bytes.
The existing code checks that w.m_ptr is not nullptr before using it.
clang's flow analysis is unable to prove that w.m_ptr does not become
nullptr after it was first checked, even though `w` is const. This
causes clang to include calls to null_pointer_exception::report, which
is not instantiated for wall. That in turn causes a link error.
Rewrite the code to let clang see that the value tested is the value
used, and that no nullptr dereference can happen here.
Push the computation up, so that invocations that differ only in the
length of their expression strings will resolve to the same template.
Rework unchecked_partial_range not to take expression strings if they
will not be used.
- Inline add_computed_color into gr_find_closest_color, and then only
one function will need access to Computed_colors.
- Allow the recent-choice bubble-up logic to apply to all elements
- If all entries are in use, always overwrite the last element in
Computed_colors instead of picking one randomly.
gr_find_closest_color did not need it. Remove it. For the others,
resetting the count is sufficient. There is no need to reset the
individual elements.
Add a helper to deduce the enum type of a value, and use an appropriate
std::underlying_type<T> expression for that enum type. This avoids the
need to repeat the type of the enum at the site of each cast, and moves
the casts into the helper to make the callers easier to read.
- Use std::iota to initialize the translation array
- Switch from conditionally using either a linear count or the array to
always using the array. In non-random mode, the array is initialized
and never shuffled, so it should produce the same effect as using the
linear count, but avoids a branch in the loop.
- Switch to using std::shuffle driven by std::minstd_rand, rather than
an inline swap loop using d_rand() to pick indices.
- Reorder the shuffle logic to have exactly one invocation in each game,
so that the shuffle call itself can be eligible for inlining.
- Use std::uniform_int_distribution to decide whether to reshuffle in
Descent 2. Maintain the original logic that reshuffling happens 25%
of the time.
clang-12 warns when the format string checking logic indexes off the end
of a very short format string to PHYSFSX_printf. In each case, the call
had no variadic arguments, so it can be switched to PHYSFSX_puts_literal
to make the code simpler and eliminate the warning.
A robot that is rendered may be woken later, subject to some conditions.
Move the easily checked conditions into the renderer, so that robots
which will not be woken are never recorded.
Checking the glow special case should be cheaper than computing and
checking the normal, so check the glow case first. Also, when the glow
values are defined, cache the result of reading from it to avoid
repeating the indexing logic farther down.
Commit d0d7545ec1 ("Unload robot movies on exit") intended to shorten
the lifetime of the loaded data, but failed to save the unique_ptr, so
the lifetime was shortened more than intended. Save the unique_ptr so
that the movies remain loaded.
Also, add a [[nodiscard]] annotation so that the compiler can warn if
this mistake is repeated.
Reported-by: Q3BFG10K <https://github.com/dxx-rebirth/dxx-rebirth/issues/599>
Fixes: d0d7545ec1 ("Unload robot movies on exit")
The previous commit removed an incorrect double scaling of the player's
weapon sounds, which will make all such sounds louder. Players with
their FX volume set to maximum will now have twice as loud a sound.
Halve the intensity in the source to return to the volume such players
would have had before. Players with an FX volume less than maximum will
still get a somewhat louder sound than before.