From 36224bad4b3cfc54d081a6e97e75f7abf088eb37 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 7 Dec 2012 04:31:41 +0000 Subject: [PATCH] - Set the name of the generated VC++ solution to "ZDBSP" instead of "project". - Use xs_Float.h for loading UDMF vertex data so that they will be bit-exact with ZDoom's loader. SVN r3979 (trunk) --- CMakeLists.txt | 6 +- processor_udmf.cpp | 11 ++- xs_Float.h | 224 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 236 insertions(+), 5 deletions(-) create mode 100644 xs_Float.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 61723bb..d6f3777 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,10 +3,11 @@ if( COMMAND cmake_policy ) cmake_policy( SET CMP0003 NEW ) endif( COMMAND cmake_policy ) - include( CheckFunctionExists ) include( CheckCXXCompilerFlag ) +project( ZDBSP ) + IF( NOT CMAKE_BUILD_TYPE ) SET( CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." @@ -157,7 +158,8 @@ set( HEADERS templates.h wad.h workdata.h - zdbsp.h ) + zdbsp.h + xs_Float.h ) if( SSE_MATTERS ) if( FULL_SSE2 ) diff --git a/processor_udmf.cpp b/processor_udmf.cpp index 2e4f44c..fa00164 100644 --- a/processor_udmf.cpp +++ b/processor_udmf.cpp @@ -23,6 +23,11 @@ #include "processor.h" #include "sc_man.h" +typedef double real64; +typedef unsigned int uint32; +typedef signed int int32; +#include "xs_Float.h" + class StringBuffer { @@ -119,12 +124,12 @@ double CheckFloat(const char *key) fixed_t CheckFixed(const char *key) { - double val = CheckFloat(key) * 65536; - if (val < double(INT_MIN) || val > double(INT_MAX)) + double val = CheckFloat(key); + if (val < -32768 || val > 32767) { SC_ScriptError("Fixed point value is out of range for key '%s'\n\t%.2f should be within [-32768,32767]", key, val / 65536); } - return fixed_t(val); + return xs_Fix<16>::ToFix(val); } //=========================================================================== diff --git a/xs_Float.h b/xs_Float.h new file mode 100644 index 0000000..19300b2 --- /dev/null +++ b/xs_Float.h @@ -0,0 +1,224 @@ +// ==================================================================================================================== +// ==================================================================================================================== +// xs_Float.h +// +// Source: "Know Your FPU: Fixing Floating Fast" +// http://www.stereopsis.com/sree/fpu2006.html +// +// xs_CRoundToInt: Round toward nearest, but ties round toward even (just like FISTP) +// xs_ToInt: Round toward zero, just like the C (int) cast +// xs_FloorToInt: Round down +// xs_CeilToInt: Round up +// xs_RoundToInt: Round toward nearest, but ties round up +// ==================================================================================================================== +// ==================================================================================================================== +#ifndef _xs_FLOAT_H_ +#define _xs_FLOAT_H_ + +// ==================================================================================================================== +// Defines +// ==================================================================================================================== +#ifndef _xs_DEFAULT_CONVERSION +#define _xs_DEFAULT_CONVERSION 0 +#endif //_xs_DEFAULT_CONVERSION + + +#if __BIG_ENDIAN__ + #define _xs_iexp_ 0 + #define _xs_iman_ 1 +#else + #define _xs_iexp_ 1 //intel is little endian + #define _xs_iman_ 0 +#endif //BigEndian_ + +#ifdef __GNUC__ +#define finline inline +#else +#define finline __forceinline +#endif + +union _xs_doubleints +{ + real64 val; + uint32 ival[2]; +}; + +#if 0 +#define _xs_doublecopysgn(a,b) ((int32*)&a)[_xs_iexp_]&=~(((int32*)&b)[_xs_iexp_]&0x80000000) +#define _xs_doubleisnegative(a) ((((int32*)&a)[_xs_iexp_])|0x80000000) +#endif + +// ==================================================================================================================== +// Constants +// ==================================================================================================================== +const real64 _xs_doublemagic = real64 (6755399441055744.0); //2^52 * 1.5, uses limited precisicion to floor +const real64 _xs_doublemagicdelta = (1.5e-8); //almost .5f = .5f + 1e^(number of exp bit) +const real64 _xs_doublemagicroundeps = (.5f-_xs_doublemagicdelta); //almost .5f = .5f - 1e^(number of exp bit) + + +// ==================================================================================================================== +// Prototypes +// ==================================================================================================================== +static int32 xs_CRoundToInt (real64 val, real64 dmr = _xs_doublemagic); +static int32 xs_ToInt (real64 val, real64 dme = -_xs_doublemagicroundeps); +static int32 xs_FloorToInt (real64 val, real64 dme = _xs_doublemagicroundeps); +static int32 xs_CeilToInt (real64 val, real64 dme = _xs_doublemagicroundeps); +static int32 xs_RoundToInt (real64 val); + +//int32 versions +finline static int32 xs_CRoundToInt (int32 val) {return val;} +finline static int32 xs_ToInt (int32 val) {return val;} + + + +// ==================================================================================================================== +// Fix Class +// ==================================================================================================================== +template class xs_Fix +{ +public: + typedef int32 Fix; + + // ==================================================================================================================== + // Basic Conversion from Numbers + // ==================================================================================================================== + finline static Fix ToFix (int32 val) {return val<>N;} + + + +protected: + // ==================================================================================================================== + // Helper function - mainly to preserve _xs_DEFAULT_CONVERSION + // ==================================================================================================================== + finline static int32 xs_ConvertToFixed (real64 val) + { + #if _xs_DEFAULT_CONVERSION==0 + return xs_CRoundToInt(val, _xs_doublemagic/(1<= 1400 + // VC++ 2005's standard cast is a little bit faster than this + // magic number code. (Which is pretty amazing!) SSE has the + // fastest C-style float->int conversion, but unfortunately, + // checking for SSE support every time you need to do a + // conversion completely negates its performance advantage. + return int32(val); +#else +#if _xs_DEFAULT_CONVERSION==0 + return (val<0) ? xs_CRoundToInt(val-dme) : + xs_CRoundToInt(val+dme); +#else + return int32(val); +#endif +#endif +} + + +// ==================================================================================================================== +finline static int32 xs_FloorToInt(real64 val, real64 dme) +{ +#if _xs_DEFAULT_CONVERSION==0 + return xs_CRoundToInt (val - dme); +#else + return floor(val); +#endif +} + + +// ==================================================================================================================== +finline static int32 xs_CeilToInt(real64 val, real64 dme) +{ +#if _xs_DEFAULT_CONVERSION==0 + return xs_CRoundToInt (val + dme); +#else + return ceil(val); +#endif +} + + +// ==================================================================================================================== +finline static int32 xs_RoundToInt(real64 val) +{ +#if _xs_DEFAULT_CONVERSION==0 + // Yes, it is important that two fadds be generated, so you cannot override the dmr + // passed to xs_CRoundToInt with _xs_doublemagic + _xs_doublemagicdelta. If you do, + // you'll end up with Banker's Rounding again. + return xs_CRoundToInt (val + _xs_doublemagicdelta); +#else + return floor(val+.5); +#endif +} + + + +// ==================================================================================================================== +// ==================================================================================================================== +// Unsigned variants +// ==================================================================================================================== +// ==================================================================================================================== +finline static uint32 xs_CRoundToUInt(real64 val) +{ + return (uint32)xs_CRoundToInt(val); +} + +finline static uint32 xs_FloorToUInt(real64 val) +{ + return (uint32)xs_FloorToInt(val); +} + +finline static uint32 xs_CeilToUInt(real64 val) +{ + return (uint32)xs_CeilToUInt(val); +} + +finline static uint32 xs_RoundToUInt(real64 val) +{ + return (uint32)xs_RoundToInt(val); +} + + + +// ==================================================================================================================== +// ==================================================================================================================== +#endif // _xs_FLOAT_H_ \ No newline at end of file