Originally sound updates only happened about every 100ms and
`sampleTime` (or `newSoundTime`) was a multiple of 4096
(`MIXBUFFER_SAMPLES`).
After I changed this to updates every 16ms and made the calculation of
`sampleTime` a lot simpler, it could be any value (as it's current
amount of milliseconds multiplied by 44.1).
It generally seemed to work, but it seems advisable to make it a
multiple of 8 (see also "Fix endless loop when decoding OGGs" commit).
So I round it to the nearest multiple of 8 now. Furthermore I increased
the accuracy when the game has been running for a long time by using
double instead of float, and tried to make sure that `sampleTime` is
always positive (or at least as long as `inTime` is positive).
idStr is used in both the main thread and the async sound thread, so
it should better be thread-safe.. idDynamicBlockAlloc is not.
Use realloc() and free() instead.
For some reason this caused a lot more crashes (due to inconsistencies
in the allocator's heap) with newer Linux distros (like XUbuntu 20.04)
and when using GCC9, while they rarely reproduced with GCC7 or on
XUbuntu 18.04
fixes#391
In idSampleDecoderLocal::DecodeOGG() `totalSamples` was 1 and
`reqSamples` was 0, which caused an endless loop.. this was caused by
idSoundWorldLocal::ReadFromSaveGame() setting
`chan->openalStreamingOffset` to an odd number, I think due to
`currentSoundTime` being an odd number.
To fix that, I round up `chan->openalStreamingOffset` to a (very) even
number, and to be double-sure I also added a check in DecodeOgg() to
make sure it exits the loop if `reqSamples` is 0.
If those functions (e.g. called by common->Printf(), common->Error())
weren't called from the mainthread and win_outputEditString was set to 1,
a deadlock could occur.
Specifically, the async thread (handling sound) was calling
common->Warning() -> Sys_Printf() -> Conbuf_AppendText() which called
SendMessageA() which blocks until the main thread handles the message.
The main thread however was in idSampleDecoderLocal::Decode() trying to
enter CRITICAL_SECTION_ONE, which was held by the async thread
(it's used to synchronize sound handling between main and async thread).
So now if Sys_Printf() (or Sys_Error() which should have the same problem)
is not called by the main thread, the text is buffered and
Conbuf_AppendText() is called for the buffered lines in the next frame
in Win_Frame().
In idSampleDecoderLocal::DecodeOGG() sometimes (esp. in The Lost Mission
mod) it happens that stb_vorbis_get_samples_float() decodes one sample
less than expected so one is left and when trying to decode that,
stb_vorbis_get_samples_float() returns 0, which we interpreted as an error.
This case is now handled more gracefully: No warning is printed (except
if developer 1) and failed is not set (setting it would prevent the sound
from being played again, I think).
the script paths were wrong, on Linux they were like
"pak000.pk4/script/doom_util.script" while on Windows it's only
"script/doom_util.script".
Fixed idFileSystemLocal::OSPathToRelativePath() to skip ...pk4/
also fixed GCC compile error in Common.cpp
only override cmd->viewDef in RB_DrawView() if we're drawing the
primary view (which for several calculations before actual drawing
was set to the saved/locked render view)
Note that r_lockSurfaces is more useful with r_useScissor 0 (otherwise
there's black bars over the screen when moving) and r_shadows 0 (otherwise
areas that weren't visible when locking are black because the lights
there are skipped)
remaining bug: gui surfaces move around the screen when looking around
set(CMAKE_REQUIRED_LIBRARIES backtrace) tells our custom libbacktrace
availability check that it needs to link against libbacktrace.
Seems like it also tells other unrelated compiler-checks like for
-fvisibility=hidden to link against libbacktrace, so if it's not
available they fail as well.
Fixed by unsetting CMAKE_REQUIRED_LIBRARIES after the backtrace check.
While debian-based distros ship libbacktrace as part of libgcc,
apparently in Arch Linux and openSUSE (and possibly others) it's a
separate package, so I mantion it in the README as an (optional)
dependency now and made CMake print a warning if it's not found.
according to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100839
the real compiler flag enabling this bullshit isn't
-fexpensive-optimizations but -ffp-contract=fast which for some(*)
reason is default in optimized builds.
I think it's best to disabled that optimization globally in case it
also breaks other code (I really don't want to spend several days to
hunt such an idiot bug again). I really doubt it makes any measurable
performance difference.
As https://twitter.com/stephentyrone/status/1399424911328874499 says
that clang might also enable this in the future (though to =on instead
of =fast which should be a bit saner but would still break our code),
just set this option for all GCC-ish compilers incl. clang.
(*) the reason of course is that GCC developers don't develop GCC for
their users but to win idiotic SPEC benchmarks
Only happend if `ONATIVE` was enabled (or some other flag was set
that enables the FMA extension), the root cause was that the cross
product didn't return 0 when it should, but a small value < 0.
Caused some faces to be missing in maps compiled with dmap.
https://github.com/RobertBeckebans/RBDOOM-3-BFG/issues/436#issuecomment-851061826
has lots of explanation.
I think this is a compiler bug, this commit works around it.
fixes#147
because of https://github.com/microsoft/vcpkg/issues/18098 people shouldn't use vcpkg (at least until they fix that)
libjpeg, libogg and libvorbis(file) aren't needed anymore, so mention that it's only needed for 1.5.1 and older
I'm gonna use it with libbacktrace - I'll need the path of the
executable before I can use idStr (and thus before I could call
Sys_GetPath(PATH_EXE, str)).