Pre-computed floating point numbers can be safely used in the comparison
function, whereas recomputation every time the sort function is called might
lead to a crash when the computed number is slightly differently every time,
because the sort function would return different results for the same faces.
The new type C4TimeMilliseconds behaves for the most part like a uint32_t but is overflow-proof in comparisons.
In some places, a 0-value (or uint_max) of the variable storing the time had the special meaning "not set yet". This has been resolved by having it as a pointer to C4TimeMilliseconds with NULL meaning that it has not been set yet.
I believe a possible cause for this is a object's model with a very low completion. However, I am not sure where the right place is to make sure everything goes alright in that case.
ResTable (the main system string table) was a home-grown hashmap that
did not cope with collisions at all. Since we already have a proper
dictionary in C4LangStringTable, use that instead.
The movement code relies on itofix(a + 1) == itofix(a) + 1, which requires
always rounding in the same direction. Since negative numbers are rounded
less often (Objects rarely are outside the landscape), change the behavior
for them.
This might make the rendering a bit quicker, since the whole texture
environment setup that we do every frame is no longer required --
instead only the shader is bound and a few variables uploaded. However,
this was not the main motivation behind this change.
It also simplifies the code a bit. The texture environment setup is
replaced by GLSL code generation. Another small benefit is that for
texture units in material scripts that do not use an actual texture
image no hardware TIU is being used. This reduces the number of hardware
TIUs required for rendering the Clonk from 3 to 2.
The main benefit of this change, however, is that material specific
and clonk specific color variations can be applied correctly. This mainly
concerns ClrModulation and MOD2 drawing. Before, the ClrModulation was
mixed with the material color, which could lead to incorrect results
depending on what the texture units were doing. Now it is being applied
by the shader after all texture units in the material scripts have been
processed.
Another motivation of this change is to implement support for custom
shaders, which is already foreseen by OGRE material scripts. The
specification has only to be implemented. With this change in place,
both custom shaders and "fixed" processing can share the same code in
the engine, since both end up using a shader for the mesh rendering.
The shader currently works only for directional lights, but should be
easy to extend to also support point lights.
This mostly simplifies things, since most other places use an 32 bit
integer to store colors, but might even improve performance through better
cache locality.
Since U+003F QUESTION MARK is a potentially valid character in a unicode string,
have the text iterator return U+FFFD if it can't decode its input instead. This
way the caller can be certain that the input isn't a proper question mark and
doesn't accidentally use it, e.g. as a wildcard.
gcc 4.6 generates better code for FIXED_EMULATE_64BIT disablen for both
32 and 64 bit. It properly recognizes that the 32,32->64 multiplication
instruction of the x86 is the right choice for the job whereas the more
complicated FIXED_EMULATE_64BIT version requires multiple multiplications
Thanks Günther for checking this! :)
This would happen when the product of the lower significant part, which is
between 0 and 65535 (even though C4Fixed is a signed data type!) exceeds
2^31, for example for val=36864, fVal2=61440.
These are the ones that the blender 2.6 exporter sets automatically. We don't
support them yet but we want to be able to load the material script
nevertheless. Many of the additional options are set to their default values
anyway.
The usage of timsort instead of std::sort at this point is twofold. First,
it's faster in our case where the array is already sorted in many cases
(remember this is called at least once a frame). And it's not just a bit
faster either but a lot. I have measured a factor of 7 on my system.
Second, in our Windows autobuilds there is a crash within std::sort which is
very hard to debug because it's hardly reproducible with anything other than
the autobuilds (I tried hard). If the crash goes away with timsort then
great, if not then maybe it's easier to debug since the code is in our tree.
The various small utilities do not use the engine Log implementation but
one that simply prints to stdout. Instead of duplicating that one, link a
common one into the utilities.
Although the code already uses boost, boost/uuid hides the sha1
implementation in a deeply nested namespace, which is just too bizarre to
use. Also the name of that namespace suggests that it is just an
implementation detail that could go away without notice.
The base64 decoding lookup table uses '\xff' to denote an invalid
value. On compilers where char is signed, this results in a value of
-1, which cannot be converted to an unsigned char in an aggregate
initializer [dcl.init.aggr p2].
Otherwise loading a savegame with an attached def mesh fails if the mesh
has neither attached meshes or animation nodes since the [ChildInstance]
section ends up empty in which case StdCompilerIniWrite does not write the
section at all.
This fixes a bug where sequences were incorrectly accepted when they ended with
a multibyte sequence, the end of which was beyond the passed string length.
MultiByteToWideChar doesn't do anything when it gets a buffer length of 0,
so it doesn't nullterminate the memory, so EnumerateDisplayModes fails because
of an invalid monitor id.