Prefer memcpy with a predetermined length, rather than strncpy, which
could leave the buffer without a terminator. No current callers could
cause the lack of a terminator, but gcc-13 warns about it, so rearrange
the code to fix the warning.
Testing for `object_none` is insufficient. Games saved before the fix
for 14cdf1b352 may have a `last_hitobj` of
`0x1ff`, which triggers an exception when constructing `icobjidx_t`.
Treat any invalid object index as `object_none`.
Reported-by: Quix0r <https://github.com/dxx-rebirth/dxx-rebirth/issues/716>
The index of the guidebot is set by loading the level data, and this is
usually sufficient. However, if the user kills the guidebot, then uses
cheats to create a new one, the new guidebot will often have a different
index than the original guidebot. If such a game is saved and then
reloaded, then after the reload, the computed guidebot index will be
reverted to the index of the original dead guidebot. This causes
various problems, including potentially a crash. Recompute the guidebot
index after loading the objects from the save file, so that it matches
the live guidebot.
Reported-by: GitInMotion <https://github.com/dxx-rebirth/dxx-rebirth/issues/713>
Various code assumes that Buddy_objnum maintains the invariants:
- If the guidebot exists, Buddy_objnum must refer to it.
- If no guidebot exists, Buddy_objnum must be object_none.
This was not enforced, so if the guidebot is killed, Buddy_objnum can
continue to refer to its last index. That can cause spurious errors
later. For example, when the player enters an energy center, if the
guidebot is dead and the guidebot's last goal was "Find energy center",
then the console reports:
```
BUG: buddy is object 28, but that object is type 255.
```
Fix that by clearing the guidebot index when the guidebot is killed.
Prefer non-static data member initializers over leaving the member
undefined in the constructor and relying on the caller to zero the
member afterward.
The pointer is only used by the constructor, so there is no need to
store it in the object.
Rework the allocation of the trailing storage to avoid the use of
placement new on a uint8_t[].
Pass a mutable buffer from the caller, and allow
PHYSFSX_addRelToSearchPath to adjust the capitalization in that buffer,
rather than creating a copy in a stack local. This can slightly affect
status messages that use the name, but otherwise should have no effect
on the game.
Store an owned pointer in MVEFILE instead of storing an unowned pointer
there and requiring the caller to keep the owned pointer alive for the
lifetime of the MVEFILE.
This has been broken since b1c5307eb1
changed the type of gr_palette from `uint8_t[256*3]` to
`array<rgb_t, 256>`. Remove it, since no one has reported it in 10
years.
Due to original game bugs, which Rebirth intentionally replicates in
order to match the balance of the original game, the logic looks odd.
Add comments explaining that the oddity is intentional.
clang-15 warns for a write-only parameter. The parameter is only used
in a debug print, which has been commented out since the code was
originally imported. Remove the parameter and the commented print.
SDL2_mixer changed how it upsamples sounds, and some users complained
about the difference. Add an internal resampler that emulates how
SDL_mixer upsamples sounds. Since all Rebirth upsampling is an integer
upsample (11Khz -> 44KHz, 22KHz -> 44Khz), this internal emulation is
considerably simpler than a general purpose resampler.
With this commit, the builder can choose which resamplers to enable.
The available resamplers are chosen by preprocessor directive, and
presently do not have an SConstruct flag. For each resampler, if no
choice is made, then the resampler will be enabled if it is reasonable.
At least one of the resamplers must be enabled, or the build will fail
with a `#error` message.
The user may choose at program start time which of the available
resamplers to use for that execution of the program, through passing one
of the command line arguments:
- `-sdlmixer-resampler=sdl-native`
- `-sdlmixer-resampler=emulate-sdl1`
- `-sdlmixer-resampler=emulate-soundblaster16`
Runtime switching is not supported. If the user does not choose, then
the first enabled resampler from the list below will be used. The
available resamplers are:
- sdl_native (DXX_FEATURE_EXTERNAL_RESAMPLER_SDL_NATIVE) - delegates to
SDL_mixer / SDL2_mixer, the way Rebirth has historically done.
- emulate_sdl1 (DXX_FEATURE_INTERNAL_RESAMPLER_EMULATE_SDL1) - an
internal resampler that emulates how SDL_mixer worked. This should be
equivalent to sdl_native when using SDL_mixer, so by default it is
enabled when Rebirth is built to use SDL2_mixer and disabled when
Rebirth is built to use SDL_mixer. It can still be enabled manually
even when building for SDL_mixer, but this does not seem likely to be
useful.
- emulate_soundblaster16
(DXX_FEATURE_INTERNAL_RESAMPLER_EMULATE_SOUNDBLASTER16) - an internal
resampler submitted by @raptor in
5165efbc46. Some users reported audio
quality issues with this resampler, so it is not presently the
default.