Change it from the level number on which the path was created to a
true/false flag. The previous logic only tested whether the number was
equal to the current level number.
This also fixes a bug where the action was not available on the first
secret level, since that level is `-1`, and the value was set to `-1` to
indicate that it should be enabled.
cockpit_decode_alpha::deccpt has static scope and is retained to support
the data in WinBoxOverlay. Change WinBoxOverlay into a structure that
stores deccpt (and rename it to the more descriptive
`decoded_full_cockpit_image`) to keep the pieces together.
Switch from formatting the strings each time they are drawn to format
them once and save them in scores_menu. Change the drawing logic to
draw from those saved strings. Change the reset logic to reinitialize
those strings instead of recreating the entire menu.
Most callers do not need it, and it is only vaguely related to the
purpose of measuring a particular string. For those callers that need
it, lift it out.
Some targets only ever use GUI warn functions. On those targets:
- initialize `warn_func` to `msgbox_warning` at compile time
- remove the runtime initialize of warn_func in main
On targets which do not call `clear_warn_func`, preprocess out its
declaration and definition.
Taken together, these changes allow some targets not to define
`warn_printf`.
On x86_64-w64-mingw32, `uint_fast32_t` is `unsigned int`. Use the
appropriate format macro for it, instead of writing `lu` and expecting
that `uint_fast32_t` will be `unsigned long`.
gcc-7 warns if a structured binding defines a variable, and then does
not use it. Suppress the warning, since the binding is needed in the
non-editor build.
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.
The SDL_mixer library has already been instructed, via Mix_Volume, to
scale the volume of sounds on all channels, by an amount based on
digi_volume. There is no need to manipulate the effective distance of a
particular sound to further scale it by digi_volume. Even if this
second scale was needed, it was done incorrectly, because it was only
applied when the sound was started, but not re-applied when the sound's
volume was updated due to positional changes. As a result, any sound
which was updated would switch to an unscaled version. Sounds which
were never updated, such as those attached to the viewer object, would
retain their original scaled volume.
Update the implementation of digi_mixer_set_channel_volume to call
Mix_SetDistance in the same way as digi_mixer_start_sound, for
readability and consistency.
Some callers need to update an existing sound_object. Other callers
need a temporary copy of the data for external use. Rearrange the code
so that the latter type of caller can obtain the data without a pointer
indirection.
gcc treats the intervening lines since the last `if` as sufficient to
recognize this as not misleading. clang does not. Change the indent to
calm clang.
The latter more clearly shows that the code flow will not proceed past
this point while the menu is open. This conversion sets the stage for
later changes to make these menus asynchronous.
Add RAII wrappers for unmounting PHYSFS paths. Use them in places that
previously handled unmounting explicitly. Also, use it for descent.hog
/ descent2.hog, which previously were left mounted indefinitely.
Some callers will need access to the computed path. Change the callers
to pass in a buffer for this path, and have PHYSFSX_addRelToSearchPath
fill that buffer directly.
lastsize was never updated from 0, so every pass would reallocate the
buffer. Switch to a std::vector and rely on it to remember the size.
Manually tracking the size would be slightly more efficient, but this is
not a hot path and the vector approach is easier to review.
Avoids switching cockpit views to CM_LETTERBOX when player dies or
level ends which stereo viewport is active, as well as other calls
to select_cockpit().
When player gets killed, the screen inexplicably switches to
another viewport format to show explosion POV and then switches
to cockpit viewport, which is not compatible with stereo formats.
Unable to locate where exactly cockpit gets switched on player
dead state, so hack is in place to keep stereo formats fullscreen.
Commit 6ad87cf78ab3 removed support for char[] as an input to
nm_item_input and fixed all sites that used it in the cross-platform
build. The Windows build has one use that no other platform does, and
this use was not fixed. Fix it now.
Fixes: 6ad87cf78ab369cdc26080ac579fb2ab3f592de6 ("Remove nm_set_item_input overload for char[]")
As discussed in pull #582, there are some rough edges to this feature.
Hide the option, but not the functionality, from users until these can
be corrected. Users who want to experiment with the feature can access
it through the command-line or the in-game hotkeys in any build. This
change only hides the help text, to prevent users from finding it and
expecting it to be fully finished.
The fallthrough appears to be intentional. Add an annotation to allow
it.
Fixes: 6bc0e822d2 ("Handle HUD overlays in separate screen rects for stereo renderings.")
Used 1x VR_eye_offset to track image shift adjustments via OGL frustum planes
instead of 2x VR_eye_offset used in Descent 1.5 image shift adjustments.
Without any HUD rect offset, HUD overlays would appear to match the zero-parallax
view plane instead of appearing in an out-of-screen parallax view plane.
Note since ogl_stereo_frame() is only ever called once per ogl_start_frame()..
ogl_end_frame() instance, only the active stereo eye view needs to be handled.
Implies that separate left/right viewport/transform caches are redundant.
Equivalent to legacy Descent 1.5 pixel shift methods for stereo formats.
Since Descent is rendering viewpoint differences for left/right eyes,
pixel shifting via display viewport is sufficient adjustment.
Since OGL layer here is essentially handling display output surfaces,
the OGL projection transform is not useful for stereo parallax effects
as when used for 3D scenes.
Enable stereo mode when launched via -gl_stereo option.
GL_STEREO quad buffering may not be available unless OGL layer
supports stereo pixel format descriptors.
Half-height viewport rendering for above/below format.
Half-width viewport rendering for side/by/side formats.
HUD & cockpit elements disabled when stereo views active.
OGL layer used for rendering surfaces, so using left/right viewports absent stereo quad buffers.
Using legacy Descent +/- eye offset method for left/right stereo perspective rendering passes.
fbd05a1592 dropped an include of "jukebox.h" as unnecessary. jukebox
was almost unnecessary, but jukebox includes physfsx, and physfsx
includes stdexcept. stdexcept is necessary. Include stdexcept
directly.
Fixes: fbd05a1592 ("optimize include files (include what you use)")
Commit e6875641c9 moved allowed_chars from global scope into
individual newmenu_item entries. However, it did not enforce that this
field be initialized, and some callers failed to do so. The save game
menu was such a caller, and crashed when using an uninitialized value as
the allowed_chars pointer. There is no character restriction here, so
explicitly set the pointer to nullptr.
Reported-by: kitelessd <https://github.com/dxx-rebirth/dxx-rebirth/issues/571>
Fixes: e6875641c9 ("Move Newmenu_allowed_chars into individual newmenu_item")
clang warns for an unused constexpr global variable. gcc does not.
Move the affected variable into the same #if that guards the use of the
variable.
Fixes: 4a8d7c7574 ("Default to 1024x768 for new users, not 640x480")
640x480 is too small to render some dialogs correctly, and is much
smaller than even a small laptop screen. Smaller resolutions are still
supported, if the user chooses to switch.
When the user opens the menu via the mouse, grd_curcanv points to a
canvas other than the top level canvas. When the user opens the menu
via the keyboard, grd_curcanv points to the top level canvas. For this
menu, the top level canvas must be used in order to get correct
alignment. Switch the constructor to always use the top level canvas.
Reported-by: dimag0g <https://github.com/dxx-rebirth/dxx-rebirth/issues/564>
Fixes: e45ba0b4a9 ("Make new game menu inherit from newmenu")
Callers only ever test for whether the movie was skipped, and never
distinguish between a movie that ran to completion versus a movie that
the user interrupted. Combine these two statuses into one value, and
eliminate the logic in RunMovie that picked which of the two to return.
Previously, rendering the preferred bomb type could also change it if
the active type was exhausted. This is undesirable, since it depends on
the user to have a HUD mode which causes the bomb type to render.
Switch to only change the active type if the user tries to drop a bomb
while the active type is unavailable. Some call sites already switch
bomb types automatically on depletion. Those sites will still do so.
v0.58.1 did this, but the functionality was accidentally removed in
859b399d20. Restore it.
Fixes: 859b399d20 ("Use mask for Secondary_last_was_super")
gcc computes a potential value range for game times as [0, 1092] instead
of the [0, 50] that the game uses. This could be reasonable as the code
was before, but even adding an explicit range check before the usage
does not eliminate the warning. Avoid the warning by increasing the
size of the buffer to avoid truncation even if the value were 1092.
After the previous commit, its only purpose is to automatically dismiss
the window after 3 seconds. Users may be surprised by this, and the
automatic dismissal has limited value. Remove it and let the user
remain at the cancel dialog until a decision is made.
The menu operated by kmatrix_poll2 exists only when the containing
kmatrix menu is also open. kmatrix has its own call to
do_protocol_frame, so there is no need for another one here.
Closing the kmatrix window while it is not in the foreground may cause a
use-after-free when it is closed again later, since the event loop can
reenter kmatrix_window::event_handler. Skip the exit logic if the
window is not in the foreground, so that it remains open until it times
out while in the foreground.
Previously, callers chose whether to use a fullscreen background image,
and the newmenu code inferred that callers without a background image
wanted a background box, while those with a background image wanted no
box. Change newmenu_layout to take a parameter specifying the caller's
intent, so that a caller can choose to have any combination of a
background image and a background box.
Calling gr_set_mode invalidates loaded fonts. Avoid a use-after-free by
forcing a cockpit reset, which will reinitialize canvases that reference
the unloaded fonts.
Commit 8a437a759c changed the logic to
always set show_all to 1. This renders the short-circuit logic in
info_display_object_placement irrelevant, as show_all will always force
the information to draw. Remove the variables that were used to decide
whether a redraw was required.
A prior conversion changed the actual rendering to use the argument
cv_font, but still picked which render function to use based on the
flags for the active font. Switch to use only the supplied font.
PHYSFSX_isNewPath retrieves from PhysFS a list of all paths, then
searches them, and frees them at the end. PhysFS can search its own
list without needing the allocations, so delegate the work to it.
->when_selected is always get_absolute_path. Remove the pointer and
replace the indirect calls with a direct reference.
->userdata is always a pointer to the buffer for get_absolute_path to
fill. Change the type from `void *` to an appropriate reference.
The last PhysFS 1 release was in March 2009. The last PhysFS 2 release
was in August 2017, shortly before the release of PhysFS 3 in September
2017. Most distributions have moved to PhysFS 3. Drop support for
PhysFS 1 and PhysFS 2. PhysFS 2 support could be restored if there is
interest.
Remove the use of qsort, since PhysFS sorts the result. The PhysFS sort
is case-sensitive rather than insensitive as the qsort was, but this is
unlikely to matter for most users.
Avoid an unnecessary strlen. The required data can be obtained from the
strchr.
Suppress player files that do not end in `.plr`. PhysFS should not
return such a file, and if it did, later code would likely become
confused. Hide such files from the user.
Previously, if the background failed to load, the kmatrix window was
immediately aborted. Change the logic so that a failure to load uses a
blank black background, but still shows the kmatrix window.
This reduces the chance of players hitting a difficult-to-fix
double-free bug, by preventing the free from occurring when the window
times out while not in focus. A proper fix requires not freeing the
window in a recursive call path.
Some group functionality was disabled in 2665869c24, but the globals
to support the disabled code were not removed. Move them into a
corresponding #if 0, since they have no value with the group code
disabled.
Fixes: 2665869c24 ("Mark editor groups broken")
It has never worked correctly. It compares real vertex numbers (as used
to index in Vertices[]) to abstract vertex numbers (always in the range
of [0, 7], as used on a theoretical segment.
Once the loop has determined a vertex is used at least twice, there is
no need to count how many more times it is used. Return immediately
after detecting the second use.
- Make it static
- Remove the update of Num_vertices, since the caller reverses that
update.
- Remove the reversal, since it is no longer needed.
- Remove the test and update of Vertices.count, because the caller
always passes a vertex number that makes the test false.
These refer to the Miner levels, which were removed in the preceding
commit since support for them has been marked as broken for an extended
period, and no one has reported an issue.
The Miner LVL files are not present in retail Descent 2 data. I know of
no way to obtain them. The code for loading them has been marked as
broken since 2018, and no one reported it. Remove this support to
simplify future work.
This reduces the call depth by one, and eliminates a load of a global
variable that always has the value MULTI_PROTO_UDP. It adds a load of
the address of the empty dispatch object. Overall, this should be an
improvement.
Every user now uses inheritance and a virtual function override. Make
callback_handler pure virtual, delete its body, and then delete the
member variables that existed only for use in that body. Remove the
constructor parameters that initialized those variables, and update all
derived classes accordingly.
The requirement to call send_creation_events from outside the
constructor makes the presence of a helper function convenient. Rename
ui_create_dialog to window_create, and move it to window.h.
This reverts commit 2bed74b056. The host
authority functionality, though important, is less important than basic
stability. Exposing the game window during this period causes various
problems, since drawing the window runs game logic:
- On escape from the final level of a mission, the player escapes the mine
twice.
- The game window is freed prematurely during the cleanup after finishing the
mission. This later leads to a use-after-free while trying to return to the
main menu.
- Game sounds continue to play in the background while the kmatrix window is
open.
- There is a brief flash of a game after exiting the kmatrix window, before the
next level initializes completely and the player warps to the correct start
spot.
Remove the logic to expose the game window during this fragile time. If this
breaks the host authority code, that will need to be fixed differently.
Fixes: 2bed74b056 ("During kmatrix bring up Game_wind againso the host can still follow the game - becomes necessary later with host-authority functions")
`const auto &&` deduces a type that is always const, which breaks the
SDL-only build. Use cg3s_point explicitly, so that the type is const
for OpenGL and mutable for SDL-only.
Fixes: ec6a78c481 ("Use enum class for marker index types")
Commit 6d3dce4e16 and commit
61f186bc18 tightened type checking for
texture values, and fixed all affected sites in the OpenGL build. The
SDL-only build had additional code paths that were not noticed or fixed.
This commit fixes those paths.
Commit cb2b844 and subsequent commits changed load_exit_models to only
call bm_free_extra_objbitmaps if EMULATING_D1. The variable
extra_bitmap_num is initialized as a side effect of
bm_free_extra_objbitmaps, so it wasn't initialized anymore if
not EMULATING_D1. This broke the exit sequence with the
D2 Mac Demo data and add-on missions with custom exit sequences.
This commit adds initialization of extra_bitmap_num if not EMULATING_D1
to fix the exit handling.
Kreeblah reports that clang now warns for powerup.cpp due to a missing
__attribute_format_printf. This was incorrectly dropped in
ffb653c0b8. gcc did not warn, but clang
now warns. Add back the attribute.
Fixes: ffb653c0b8 ("Pass control_info & to various functions")
Reported-by: Kreeblah <https://github.com/dxx-rebirth/dxx-rebirth/pull/547>
If a menu was all text except for the last element, the menu would
incorrectly be classifed as all text, and citem would be pinned to the
first element.
Fixes: 14a9657136 ("Use partial_range to store newmenu_item pointer/length")