this was so broken, I think if anyone ever tried to use __DATE__ or
__TIME__ it must've crashed, either from free(curtime) (which was the
return value of ctime()) or from things like token[7] = NULL when token
was a pointer (to a single element!).
I think it could work now.
Also fixed potential memory leaks in cases that don't "return" anything
These are now used by idStr::(v)snPrintf(), and in the future can
be used if a (v)snprintf() that's guaranteed not to call
common->Warning() or similar is needed (e.g. used during early startup)
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
It corrupted the stack when called with buffers allocated on the stack
and numSamples that are not a multiple of four, apparently, by writing
4 floats too many, at least in the 22KHz Stereo case..
This caused the crash described in
https://github.com/dhewm/dhewm3/issues/303#issuecomment-678809662
Now it just uses the generic C code, like all platforms besides MSVC/x86
already do.
idStr::StripFileExtension() (and SetFileExtension() which uses it) and
others didn't work correctly if there was a dot in a directory name,
because they just searched from last to first char for '.', so if the
current filename didn't have an extension to cut off, they'd just cut
off at any other '.' they found.
So D:\dev\doom3.data\base\maps\bla could turn into D:\dev\doom3
(or, for SetFileExtension(), D:\dev\doom3.map)
While at it, I made most of the idStr code that explicitly checked for
'\\' and '/' (and maybe ':' for AROS) use a little
"bool isDirSeparator(int c)" function so we don't have the #ifdefs
for different platforms all over the place.
On Windows, ID_INLINE does __forceinline, which is bad if the function
calls alloca() and is called in a loop..
So use just __inline there so the compiler can choose not to inline
(if called in a loop).
This didn't cause actual stack overflows as far as I know, but it could
(and MSVC warns about it).
(This includes "Fix ID_MAYBE_INLINE on non-Windows platforms")
Somehow I must have added that
savefile->WriteFloat( spreadCrouchFactor );
twice when merging the Ruiner/Rivensin changes into the SDK.. damn.
(As it's only read once, all data read from the savegame after it
will be garbage)
I had a crash when creating a Savegame in idAnimState::Save(),
because animator was NULL - so I added a check for that.
The rest has been found with GCC address sanitizer (ASan)
the game code asserts all the time, but seems to work when disabling
assertions..
so make sure assertions are really disabled with NDEBUG, even if _DEBUG
is set (like it is in debug builds).
this way I can at least get an unoptimized debug build that can actually
be tested.
I created this repo from the original dhewm3 repo, but I used
git filter-branch to kill all the files that are not needed to just
build base.dll and d3xp.dll (or .so or .dylib or whatever).
So this is basically just the files the original Doom3 SDK had, but
taken from dhewm3 instead (and thus GPL licensed and patched for
64bit-support etc) + some dhewm3 specific stuff + CMakeLists.txt
to build them.
The git filter-branch details:
filter-branch -f --prune-empty --tree-filter /tmp/killkill.sh @
## /tmp/killkill.sh:
#!/bin/sh
find . -exec /tmp/removeothers.sh {} \;
exit 0
## /tmp/removeothers.sh:
#!/bin/bash
FNAME="$1"
if [[ $FNAME == \./\.git* ]] || [[ $FNAME == \./d3xp/* ]] || [[ $FNAME == \./game/* ]]
then
#echo "ignoring $FNAME"
exit 0
fi
if ! grep -Fxq "$FNAME" /tmp/d3sdklist.txt
then
#echo "REMOVING $FNAME"
rm -rf "$FNAME"
fi
exit 0
## /tmp/d3sdklist.txt was is just a textfile with one path per line with
all the files (and directories!) I wanted to keep, like:
.
..
./sys/platform.h
./framework/Game.h
./config.h.in
./CMakeLists.txt
## ... and all the relevant files from the SDK
Sometimes memory was allocated with new[] but freed with delete instead
of delete[], which is wrong.
And there were some small memory leaks, too.
Furtunately clang's AddressSanitizer detected all that so I could easily
fix it.
(There seem to be some more small memory leaks which are harder to fix,
though)
__builtin_trap() causes an illegal instruction and thus the process
can't resume afterwards.
raise(SIGTRAP) only breaks into the debugger and thus allows to
"ignore" the assertion while debugging.
Everytime List.h is included in a new file (and sys/platform.h isn't)
there are confusing compiler-errors..
So just #include sys/platform.h in List.h directly, because it uses
ID_INLINE which is defined there
GCC had shitloads of superfluous warnings wherever List.h and Str.h were
included.. get rid of them by using #pragma GCC diagnostic at some places
in List.h and Str.h.
Also add some casts, initialize some variables for other warnings
Apart from some minor stuff, this changes the signature of some methods
of Parser and Token classes and of the (unused) Random2 class.
That no problem though, because the calling code uses normal ints
anyway.
The original implementation was pretty broken (but not used anyway),
it is now fixed and improved a bit (got rid of one inner loop).
This (at least part of the problem) was detected by PVS-Studio,
see http://www.viva64.com/en/b/0120/ Fragment 3
Bug introduced with e97d3288. This doesn't work with MinGW, since
the struct members might not be aligned to the native pointer
size (in this case idSampleDecoderLocal was aligned to a 8 byte
boundary on win32).
Just switch the two members to avoid ugly code.
We want to use the SIMD functions of the base class if the
deriving class does not implement every overloaded variant.
Added missing idLight::SetColor(idVec3) which is declared in
idEntity.