1:1 source port of the engine and game code; Windows build and system layer; docs. No game files or SDK headers.
This commit is contained in:
parent
c3b032a45a
commit
0ecb47e9cb
3871 changed files with 91080 additions and 1640063 deletions
30
port/game/sseconv.h
Normal file
30
port/game/sseconv.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
// Port helper (no game counterpart): float -> integer conversions exactly as gcc 4.0 codes them for i386 with SSE
|
||||
// in the game's objects, where a plain C++ cast on the 64-bit host can give a different result outside the
|
||||
// target type's range.
|
||||
#ifndef GAME_SSECONV_H
|
||||
#define GAME_SSECONV_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// (uint32_t)double: minsd/maxsd clamp to [0, 4294967295] (a NaN takes the upper bound), 2^31 subtracted when the
|
||||
// unclamped value is >= 2^31 (cmplesd mask), cvttpd2dq, bit 31 restored. Constants in the game's __const, e.g.
|
||||
// @0x00192700 = {2147483648.0, 0.0, 4294967295.0, 0.0}. So < 0 -> 0, > 4294967295 -> 0xFFFFFFFF, NaN -> 0x80000000
|
||||
// (cvttpd2dq of 4294967295.0 is the integer indefinite).
|
||||
inline uint32_t SseDoubleToUInt32(double d)
|
||||
{
|
||||
bool big = (2147483648.0 <= d); // cmplesd
|
||||
double x = d;
|
||||
if (!(x < 4294967295.0)) x = 4294967295.0; // minsd x, 4294967295.0
|
||||
if (!(x > 0.0)) x = 0.0; // maxsd x, 0.0
|
||||
if (big) x -= 2147483648.0; // subsd (mask & 2^31)
|
||||
int32_t t = (x > -2147483649.0 && x < 2147483648.0) ? (int32_t)x : (int32_t)0x80000000u; // cvttpd2dq
|
||||
return (uint32_t)t ^ (big ? 0x80000000u : 0u);
|
||||
}
|
||||
|
||||
// (int32_t)double / (int32_t)float: cvttsd2si / cvttss2si; out of range and NaN give the integer indefinite.
|
||||
inline int32_t SseDoubleToInt32(double d)
|
||||
{
|
||||
return (d > -2147483649.0 && d < 2147483648.0) ? (int32_t)d : (int32_t)0x80000000u;
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue