Use Q16.16 fixed point for player horiz

git-svn-id: https://svn.eduke32.com/eduke32@6724 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
terminx 2018-03-07 04:21:05 +00:00
parent 7fa0abda26
commit 4d8bb170a3
25 changed files with 1140 additions and 96 deletions

View file

@ -201,6 +201,8 @@ engine_objs := \
mhk.cpp \ mhk.cpp \
pngwrite.cpp \ pngwrite.cpp \
miniz.c \ miniz.c \
fix16.c \
fix16_str.c \
engine_editor_objs := \ engine_editor_objs := \
build.cpp \ build.cpp \

View file

@ -103,6 +103,8 @@
<ClInclude Include="..\..\source\build\include\dxtfilter.h" /> <ClInclude Include="..\..\source\build\include\dxtfilter.h" />
<ClInclude Include="..\..\source\build\include\dynamicgtk.h" /> <ClInclude Include="..\..\source\build\include\dynamicgtk.h" />
<ClInclude Include="..\..\source\build\include\editor.h" /> <ClInclude Include="..\..\source\build\include\editor.h" />
<ClInclude Include="..\..\source\build\include\fix16.h" />
<ClInclude Include="..\..\source\build\include\fix16.hpp" />
<ClInclude Include="..\..\source\build\include\glbuild.h" /> <ClInclude Include="..\..\source\build\include\glbuild.h" />
<ClInclude Include="..\..\source\build\include\glext.h" /> <ClInclude Include="..\..\source\build\include\glext.h" />
<ClInclude Include="..\..\source\build\include\gtkbits.h" /> <ClInclude Include="..\..\source\build\include\gtkbits.h" />
@ -263,6 +265,8 @@
<ClCompile Include="..\..\source\build\src\dxtfilter.cpp" /> <ClCompile Include="..\..\source\build\src\dxtfilter.cpp" />
<ClCompile Include="..\..\source\build\src\dynamicgtk.cpp" /> <ClCompile Include="..\..\source\build\src\dynamicgtk.cpp" />
<ClCompile Include="..\..\source\build\src\engine.cpp" /> <ClCompile Include="..\..\source\build\src\engine.cpp" />
<ClCompile Include="..\..\source\build\src\fix16.c" />
<ClCompile Include="..\..\source\build\src\fix16_str.c" />
<ClCompile Include="..\..\source\build\src\glbuild.cpp" /> <ClCompile Include="..\..\source\build\src\glbuild.cpp" />
<ClCompile Include="..\..\source\build\src\gtkbits.cpp" /> <ClCompile Include="..\..\source\build\src\gtkbits.cpp" />
<ClCompile Include="..\..\source\build\src\hash.cpp" /> <ClCompile Include="..\..\source\build\src\hash.cpp" />

View file

@ -567,6 +567,12 @@
<ClInclude Include="..\..\source\glad\include\glad\glad_wgl.h"> <ClInclude Include="..\..\source\glad\include\glad\glad_wgl.h">
<Filter>glad\headers\glad</Filter> <Filter>glad\headers\glad</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\source\build\include\fix16.h">
<Filter>build\headers</Filter>
</ClInclude>
<ClInclude Include="..\..\source\build\include\fix16.hpp">
<Filter>build\headers</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\source\build\src\a-c.cpp"> <ClCompile Include="..\..\source\build\src\a-c.cpp">
@ -989,6 +995,12 @@
<ClCompile Include="..\..\source\glad\src\glad_wgl.c"> <ClCompile Include="..\..\source\glad\src\glad_wgl.c">
<Filter>glad\source</Filter> <Filter>glad\source</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\source\build\src\fix16.c">
<Filter>build\source</Filter>
</ClCompile>
<ClCompile Include="..\..\source\build\src\fix16_str.c">
<Filter>build\source</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="msvc.mak"> <None Include="msvc.mak">

View file

@ -184,7 +184,9 @@ ENGINE_OBJS= \
$(ENGINE_OBJ)\screenshot.$o \ $(ENGINE_OBJ)\screenshot.$o \
$(ENGINE_OBJ)\mhk.$o \ $(ENGINE_OBJ)\mhk.$o \
$(ENGINE_OBJ)\pngwrite.$o \ $(ENGINE_OBJ)\pngwrite.$o \
$(ENGINE_OBJ)\miniz.$o $(ENGINE_OBJ)\miniz.$o \
$(ENGINE_OBJ)\fix16.$o \
$(ENGINE_OBJ)\fix16_str.$o
ENGINE_EDITOR_OBJS=$(ENGINE_OBJ)\build.$o \ ENGINE_EDITOR_OBJS=$(ENGINE_OBJ)\build.$o \

View file

@ -29,8 +29,8 @@ $(ENGINE_OBJ)/textfont.$o: $(ENGINE_SRC)/textfont.cpp
$(ENGINE_OBJ)/smalltextfont.$o: $(ENGINE_SRC)/smalltextfont.cpp $(ENGINE_OBJ)/smalltextfont.$o: $(ENGINE_SRC)/smalltextfont.cpp
$(ENGINE_OBJ)/glbuild.$o: $(ENGINE_SRC)/glbuild.cpp $(ENGINE_INC)/glbuild.h $(ENGINE_INC)/baselayer.h $(GLAD_INC)/glad/glad.h $(ENGINE_OBJ)/glbuild.$o: $(ENGINE_SRC)/glbuild.cpp $(ENGINE_INC)/glbuild.h $(ENGINE_INC)/baselayer.h $(GLAD_INC)/glad/glad.h
$(ENGINE_OBJ)/kplib.$o: $(ENGINE_SRC)/kplib.cpp $(ENGINE_INC)/compat.h $(ENGINE_INC)/kplib.h $(ENGINE_OBJ)/kplib.$o: $(ENGINE_SRC)/kplib.cpp $(ENGINE_INC)/compat.h $(ENGINE_INC)/kplib.h
$(ENGINE_OBJ)/lz4.$o: $(ENGINE_SRC)/lz4.c $(ENGINE_INC)/lz4.h
$(ENGINE_OBJ)/md4.$o: $(ENGINE_SRC)/md4.cpp $(ENGINE_INC)/md4.h $(ENGINE_OBJ)/md4.$o: $(ENGINE_SRC)/md4.cpp $(ENGINE_INC)/md4.h
$(ENGINE_OBJ)/lz4.$o: $(ENGINE_SRC)/lz4.c $(ENGINE_INC)/lz4.h
$(ENGINE_OBJ)/osd.$o: $(ENGINE_SRC)/osd.cpp $(ENGINE_INC)/build.h $(ENGINE_INC)/buildtypes.h $(ENGINE_INC)/osd.h $(ENGINE_INC)/compat.h $(ENGINE_INC)/baselayer.h $(ENGINE_OBJ)/osd.$o: $(ENGINE_SRC)/osd.cpp $(ENGINE_INC)/build.h $(ENGINE_INC)/buildtypes.h $(ENGINE_INC)/osd.h $(ENGINE_INC)/compat.h $(ENGINE_INC)/baselayer.h
$(ENGINE_OBJ)/pragmas.$o: $(ENGINE_SRC)/pragmas.cpp $(ENGINE_INC)/compat.h $(ENGINE_OBJ)/pragmas.$o: $(ENGINE_SRC)/pragmas.cpp $(ENGINE_INC)/compat.h
$(ENGINE_OBJ)/scriptfile.$o: $(ENGINE_SRC)/scriptfile.cpp $(ENGINE_INC)/scriptfile.h $(ENGINE_INC)/cache1d.h $(ENGINE_INC)/compat.h $(ENGINE_OBJ)/scriptfile.$o: $(ENGINE_SRC)/scriptfile.cpp $(ENGINE_INC)/scriptfile.h $(ENGINE_INC)/cache1d.h $(ENGINE_INC)/compat.h
@ -46,6 +46,8 @@ $(ENGINE_OBJ)/winbits.$o: $(ENGINE_SRC)/winbits.cpp $(ENGINE_INC)/winbits.h
$(ENGINE_OBJ)/xxhash.$o: $(ENGINE_SRC)/xxhash.c $(ENGINE_INC)/xxhash.h $(ENGINE_OBJ)/xxhash.$o: $(ENGINE_SRC)/xxhash.c $(ENGINE_INC)/xxhash.h
$(ENGINE_OBJ)/pngwrite.$o: $(ENGINE_SRC)/pngwrite.cpp $(ENGINE_INC)/pngwrite.h $(ENGINE_OBJ)/pngwrite.$o: $(ENGINE_SRC)/pngwrite.cpp $(ENGINE_INC)/pngwrite.h
$(ENGINE_OBJ)/miniz.$o: $(ENGINE_SRC)/miniz.c $(ENGINE_INC)/miniz.h $(ENGINE_OBJ)/miniz.$o: $(ENGINE_SRC)/miniz.c $(ENGINE_INC)/miniz.h
$(ENGINE_OBJ)/fix16.$o: $(ENGINE_SRC)/fix16.c $(ENGINE_INC)/fix16.h
$(ENGINE_OBJ)/fix16_str.$o: $(ENGINE_SRC)/fix16_str.c $(ENGINE_INC)/fix16.h
$(ENGINE_OBJ)/lunatic.$o: $(ENGINE_SRC)/lunatic.cpp $(ENGINE_INC)/lunatic.h $(ENGINE_INC)/cache1d.h $(ENGINE_INC)/osd.h $(ENGINE_OBJ)/lunatic.$o: $(ENGINE_SRC)/lunatic.cpp $(ENGINE_INC)/lunatic.h $(ENGINE_INC)/cache1d.h $(ENGINE_INC)/osd.h

View file

@ -1241,6 +1241,7 @@ static inline void maybe_grow_buffer(char ** const buffer, int32_t * const buffe
#define LIBDIVIDE_NONAMESPACE #define LIBDIVIDE_NONAMESPACE
#define LIBDIVIDE_NOINLINE #define LIBDIVIDE_NOINLINE
#include "libdivide.h" #include "libdivide.h"
#include "fix16.h"
/* End dependence on compat.o object. */ /* End dependence on compat.o object. */

View file

@ -0,0 +1,318 @@
#ifndef __libfixmath_fix16_h__
#define __libfixmath_fix16_h__
#ifdef __cplusplus
extern "C"
{
#endif
/* These options may let the optimizer to remove some calls to the functions.
* Refer to http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
*/
#ifndef FIXMATH_FUNC_ATTRS
# ifdef __GNUC__
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)
# define FIXMATH_FUNC_ATTRS __attribute__((leaf, nothrow, const))
# else
# define FIXMATH_FUNC_ATTRS __attribute__((nothrow, const))
# endif
# else
# define FIXMATH_FUNC_ATTRS
# endif
#endif
#include <stdint.h>
typedef int32_t fix16_t;
static const fix16_t FOUR_DIV_PI = 0x145F3; /*!< Fix16 value of 4/PI */
static const fix16_t _FOUR_DIV_PI2 = 0xFFFF9840; /*!< Fix16 value of -4/PI² */
static const fix16_t X4_CORRECTION_COMPONENT = 0x399A; /*!< Fix16 value of 0.225 */
static const fix16_t PI_DIV_4 = 0x0000C90F; /*!< Fix16 value of PI/4 */
static const fix16_t THREE_PI_DIV_4 = 0x00025B2F; /*!< Fix16 value of 3PI/4 */
static const fix16_t fix16_maximum = 0x7FFFFFFF; /*!< the maximum value of fix16_t */
static const fix16_t fix16_minimum = 0x80000000; /*!< the minimum value of fix16_t */
static const fix16_t fix16_overflow = 0x80000000; /*!< the value used to indicate overflows when FIXMATH_NO_OVERFLOW is not specified */
static const fix16_t fix16_pi = 205887; /*!< fix16_t value of pi */
static const fix16_t fix16_e = 178145; /*!< fix16_t value of e */
static const fix16_t fix16_one = 0x00010000; /*!< fix16_t value of 1 */
/* Conversion functions between fix16_t and float/integer.
* These are inlined to allow compiler to optimize away constant numbers
*/
static inline fix16_t fix16_from_int(int a) { return a * fix16_one; }
static inline float fix16_to_float(fix16_t a) { return (float)a / fix16_one; }
static inline double fix16_to_dbl(fix16_t a) { return (double)a / fix16_one; }
static inline int fix16_to_int(fix16_t a)
{
#ifdef FIXMATH_NO_ROUNDING
return (a >> 16);
#else
if (a >= 0)
return (a + (fix16_one >> 1)) / fix16_one;
return (a - (fix16_one >> 1)) / fix16_one;
#endif
}
static inline fix16_t fix16_from_float(float a)
{
float temp = a * fix16_one;
#ifndef FIXMATH_NO_ROUNDING
temp += (temp >= 0) ? 0.5f : -0.5f;
#endif
return (fix16_t)temp;
}
static inline fix16_t fix16_from_dbl(double a)
{
double temp = a * fix16_one;
#ifndef FIXMATH_NO_ROUNDING
temp += (temp >= 0) ? 0.5f : -0.5f;
#endif
return (fix16_t)temp;
}
/* Macro for defining fix16_t constant values.
The functions above can't be used from e.g. global variable initializers,
and their names are quite long also. This macro is useful for constants
springled alongside code, e.g. F16(1.234).
Note that the argument is evaluated multiple times, and also otherwise
you should only use this for constant values. For runtime-conversions,
use the functions above.
*/
#define F16(x) ((fix16_t)(((x) >= 0) ? ((x) * 65536.0 + 0.5) : ((x) * 65536.0 - 0.5)))
static inline fix16_t fix16_abs(fix16_t x)
{ return (x < 0 ? -x : x); }
static inline fix16_t fix16_floor(fix16_t x)
{ return (x & 0xFFFF0000UL); }
static inline fix16_t fix16_ceil(fix16_t x)
{ return (x & 0xFFFF0000UL) + (x & 0x0000FFFFUL ? fix16_one : 0); }
static inline fix16_t fix16_min(fix16_t x, fix16_t y)
{ return (x < y ? x : y); }
static inline fix16_t fix16_max(fix16_t x, fix16_t y)
{ return (x > y ? x : y); }
static inline fix16_t fix16_clamp(fix16_t x, fix16_t lo, fix16_t hi)
{ return fix16_min(fix16_max(x, lo), hi); }
/* Subtraction and addition with (optional) overflow detection. */
#ifdef FIXMATH_NO_OVERFLOW
static inline fix16_t fix16_add(fix16_t inArg0, fix16_t inArg1) { return (inArg0 + inArg1); }
static inline fix16_t fix16_sub(fix16_t inArg0, fix16_t inArg1) { return (inArg0 - inArg1); }
#else
extern fix16_t fix16_add(fix16_t a, fix16_t b) FIXMATH_FUNC_ATTRS;
extern fix16_t fix16_sub(fix16_t a, fix16_t b) FIXMATH_FUNC_ATTRS;
/* Saturating arithmetic */
extern fix16_t fix16_sadd(fix16_t a, fix16_t b) FIXMATH_FUNC_ATTRS;
extern fix16_t fix16_ssub(fix16_t a, fix16_t b) FIXMATH_FUNC_ATTRS;
#endif
/*! Multiplies the two given fix16_t's and returns the result.
*/
extern fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1) FIXMATH_FUNC_ATTRS;
/*! Divides the first given fix16_t by the second and returns the result.
*/
extern fix16_t fix16_div(fix16_t inArg0, fix16_t inArg1) FIXMATH_FUNC_ATTRS;
#ifndef FIXMATH_NO_OVERFLOW
/*! Performs a saturated multiplication (overflow-protected) of the two given fix16_t's and returns the result.
*/
extern fix16_t fix16_smul(fix16_t inArg0, fix16_t inArg1) FIXMATH_FUNC_ATTRS;
/*! Performs a saturated division (overflow-protected) of the first fix16_t by the second and returns the result.
*/
extern fix16_t fix16_sdiv(fix16_t inArg0, fix16_t inArg1) FIXMATH_FUNC_ATTRS;
#endif
/*! Divides the first given fix16_t by the second and returns the result.
*/
extern fix16_t fix16_mod(fix16_t x, fix16_t y) FIXMATH_FUNC_ATTRS;
/*! Returns the linear interpolation: (inArg0 * (1 - inFract)) + (inArg1 * inFract)
*/
extern fix16_t fix16_lerp8(fix16_t inArg0, fix16_t inArg1, uint8_t inFract) FIXMATH_FUNC_ATTRS;
extern fix16_t fix16_lerp16(fix16_t inArg0, fix16_t inArg1, uint16_t inFract) FIXMATH_FUNC_ATTRS;
extern fix16_t fix16_lerp32(fix16_t inArg0, fix16_t inArg1, uint32_t inFract) FIXMATH_FUNC_ATTRS;
/*! Returns the sine of the given fix16_t.
*/
extern fix16_t fix16_sin_parabola(fix16_t inAngle) FIXMATH_FUNC_ATTRS;
/*! Returns the sine of the given fix16_t.
*/
extern fix16_t fix16_sin(fix16_t inAngle) FIXMATH_FUNC_ATTRS;
/*! Returns the cosine of the given fix16_t.
*/
extern fix16_t fix16_cos(fix16_t inAngle) FIXMATH_FUNC_ATTRS;
/*! Returns the tangent of the given fix16_t.
*/
extern fix16_t fix16_tan(fix16_t inAngle) FIXMATH_FUNC_ATTRS;
/*! Returns the arcsine of the given fix16_t.
*/
extern fix16_t fix16_asin(fix16_t inValue) FIXMATH_FUNC_ATTRS;
/*! Returns the arccosine of the given fix16_t.
*/
extern fix16_t fix16_acos(fix16_t inValue) FIXMATH_FUNC_ATTRS;
/*! Returns the arctangent of the given fix16_t.
*/
extern fix16_t fix16_atan(fix16_t inValue) FIXMATH_FUNC_ATTRS;
/*! Returns the arctangent of inY/inX.
*/
extern fix16_t fix16_atan2(fix16_t inY, fix16_t inX) FIXMATH_FUNC_ATTRS;
static const fix16_t fix16_rad_to_deg_mult = 3754936;
static inline fix16_t fix16_rad_to_deg(fix16_t radians)
{ return fix16_mul(radians, fix16_rad_to_deg_mult); }
static const fix16_t fix16_deg_to_rad_mult = 1144;
static inline fix16_t fix16_deg_to_rad(fix16_t degrees)
{ return fix16_mul(degrees, fix16_deg_to_rad_mult); }
/*! Returns the square root of the given fix16_t.
*/
extern fix16_t fix16_sqrt(fix16_t inValue) FIXMATH_FUNC_ATTRS;
/*! Returns the square of the given fix16_t.
*/
static inline fix16_t fix16_sq(fix16_t x)
{ return fix16_mul(x, x); }
/*! Returns the exponent (e^) of the given fix16_t.
*/
extern fix16_t fix16_exp(fix16_t inValue) FIXMATH_FUNC_ATTRS;
/*! Returns the natural logarithm of the given fix16_t.
*/
extern fix16_t fix16_log(fix16_t inValue) FIXMATH_FUNC_ATTRS;
/*! Returns the base 2 logarithm of the given fix16_t.
*/
extern fix16_t fix16_log2(fix16_t x) FIXMATH_FUNC_ATTRS;
/*! Returns the saturated base 2 logarithm of the given fix16_t.
*/
extern fix16_t fix16_slog2(fix16_t x) FIXMATH_FUNC_ATTRS;
/*! Convert fix16_t value to a string.
* Required buffer length for largest values is 13 bytes.
*/
extern void fix16_to_str(fix16_t value, char *buf, int decimals);
/*! Convert string to a fix16_t value
* Ignores spaces at beginning and end. Returns fix16_overflow if
* value is too large or there were garbage characters.
*/
extern fix16_t fix16_from_str(const char *buf);
/** Helper macro for F16C. Replace token with its number of characters/digits. */
#define FIXMATH_TOKLEN(token) ( sizeof( #token ) - 1 )
/** Helper macro for F16C. Handles pow(10, n) for n from 0 to 8. */
#define FIXMATH_CONSTANT_POW10(times) ( \
(times == 0) ? 1ULL \
: (times == 1) ? 10ULL \
: (times == 2) ? 100ULL \
: (times == 3) ? 1000ULL \
: (times == 4) ? 10000ULL \
: (times == 5) ? 100000ULL \
: (times == 6) ? 1000000ULL \
: (times == 7) ? 10000000ULL \
: 100000000ULL \
)
/** Helper macro for F16C, the type uint64_t is only used at compile time and
* shouldn't be visible in the generated code.
*
* @note We do not use fix16_one instead of 65536ULL, because the
* "use of a const variable in a constant expression is nonstandard in C".
*/
#define FIXMATH_CONVERT_MANTISSA(m) \
( (unsigned) \
( \
( \
( \
(uint64_t)( ( ( 1 ## m ## ULL ) - FIXMATH_CONSTANT_POW10(FIXMATH_TOKLEN(m)) ) * FIXMATH_CONSTANT_POW10(5 - FIXMATH_TOKLEN(m)) ) \
* 100000ULL * 65536ULL \
) \
+ 5000000000ULL /* rounding: + 0.5 */ \
) \
/ \
10000000000LL \
) \
)
#define FIXMATH_COMBINE_I_M(i, m) \
( \
( \
( i ) \
<< 16 \
) \
| \
( \
FIXMATH_CONVERT_MANTISSA(m) \
& 0xFFFF \
) \
)
/** Create int16_t (Q16.16) constant from separate integer and mantissa part.
*
* Only tested on 32-bit ARM Cortex-M0 / x86 Intel.
*
* This macro is needed when compiling with options like "--fpu=none",
* which forbid all and every use of float and related types and
* would thus make it impossible to have fix16_t constants.
*
* Just replace uses of F16() with F16C() like this:
* F16(123.1234) becomes F16C(123,1234)
*
* @warning Specification of any value outside the mentioned intervals
* WILL result in undefined behavior!
*
* @note Regardless of the specified minimum and maximum values for i and m below,
* the total value of the number represented by i and m MUST be in the interval
* ]-32768.00000:32767.99999[ else usage with this macro will yield undefined behavior.
*
* @param i Signed integer constant with a value in the interval ]-32768:32767[.
* @param m Positive integer constant in the interval ]0:99999[ (fractional part/mantissa).
*/
#define F16C(i, m) \
( (fix16_t) \
( \
(( #i[0] ) == '-') \
? -FIXMATH_COMBINE_I_M((unsigned)( ( (i) * -1) ), m) \
: FIXMATH_COMBINE_I_M((unsigned)i, m) \
) \
)
#ifdef __cplusplus
}
#include "fix16.hpp"
#endif
#endif

View file

@ -0,0 +1,154 @@
#ifndef __libfixmath_fix16_hpp__
#define __libfixmath_fix16_hpp__
#include "fix16.h"
class Fix16 {
public:
fix16_t value;
Fix16() { value = 0; }
Fix16(const Fix16 &inValue) { value = inValue.value; }
Fix16(const fix16_t inValue) { value = inValue; }
Fix16(const float inValue) { value = fix16_from_float(inValue); }
Fix16(const double inValue) { value = fix16_from_dbl(inValue); }
Fix16(const int16_t inValue) { value = fix16_from_int(inValue); }
operator fix16_t() const { return value; }
operator double() const { return fix16_to_dbl(value); }
operator float() const { return fix16_to_float(value); }
operator int16_t() const { return fix16_to_int(value); }
Fix16 & operator=(const Fix16 &rhs) { value = rhs.value; return *this; }
Fix16 & operator=(const fix16_t rhs) { value = rhs; return *this; }
Fix16 & operator=(const double rhs) { value = fix16_from_dbl(rhs); return *this; }
Fix16 & operator=(const float rhs) { value = fix16_from_float(rhs); return *this; }
Fix16 & operator=(const int16_t rhs) { value = fix16_from_int(rhs); return *this; }
Fix16 & operator+=(const Fix16 &rhs) { value += rhs.value; return *this; }
Fix16 & operator+=(const fix16_t rhs) { value += rhs; return *this; }
Fix16 & operator+=(const double rhs) { value += fix16_from_dbl(rhs); return *this; }
Fix16 & operator+=(const float rhs) { value += fix16_from_float(rhs); return *this; }
Fix16 & operator+=(const int16_t rhs) { value += fix16_from_int(rhs); return *this; }
Fix16 & operator-=(const Fix16 &rhs) { value -= rhs.value; return *this; }
Fix16 & operator-=(const fix16_t rhs) { value -= rhs; return *this; }
Fix16 & operator-=(const double rhs) { value -= fix16_from_dbl(rhs); return *this; }
Fix16 & operator-=(const float rhs) { value -= fix16_from_float(rhs); return *this; }
Fix16 & operator-=(const int16_t rhs) { value -= fix16_from_int(rhs); return *this; }
Fix16 & operator*=(const Fix16 &rhs) { value = fix16_mul(value, rhs.value); return *this; }
Fix16 & operator*=(const fix16_t rhs) { value = fix16_mul(value, rhs); return *this; }
Fix16 & operator*=(const double rhs) { value = fix16_mul(value, fix16_from_dbl(rhs)); return *this; }
Fix16 & operator*=(const float rhs) { value = fix16_mul(value, fix16_from_float(rhs)); return *this; }
Fix16 & operator*=(const int16_t rhs) { value *= rhs; return *this; }
Fix16 & operator/=(const Fix16 &rhs) { value = fix16_div(value, rhs.value); return *this; }
Fix16 & operator/=(const fix16_t rhs) { value = fix16_div(value, rhs); return *this; }
Fix16 & operator/=(const double rhs) { value = fix16_div(value, fix16_from_dbl(rhs)); return *this; }
Fix16 & operator/=(const float rhs) { value = fix16_div(value, fix16_from_float(rhs)); return *this; }
Fix16 & operator/=(const int16_t rhs) { value /= rhs; return *this; }
const Fix16 operator+(const Fix16 &other) const { Fix16 ret = *this; ret += other; return ret; }
const Fix16 operator+(const fix16_t other) const { Fix16 ret = *this; ret += other; return ret; }
const Fix16 operator+(const double other) const { Fix16 ret = *this; ret += other; return ret; }
const Fix16 operator+(const float other) const { Fix16 ret = *this; ret += other; return ret; }
const Fix16 operator+(const int16_t other) const { Fix16 ret = *this; ret += other; return ret; }
#ifndef FIXMATH_NO_OVERFLOW
const Fix16 sadd(const Fix16 &other) const { Fix16 ret = fix16_sadd(value, other.value); return ret; }
const Fix16 sadd(const fix16_t other) const { Fix16 ret = fix16_sadd(value, other); return ret; }
const Fix16 sadd(const double other) const { Fix16 ret = fix16_sadd(value, fix16_from_dbl(other)); return ret; }
const Fix16 sadd(const float other) const { Fix16 ret = fix16_sadd(value, fix16_from_float(other)); return ret; }
const Fix16 sadd(const int16_t other) const { Fix16 ret = fix16_sadd(value, fix16_from_int(other)); return ret; }
#endif
const Fix16 operator-(const Fix16 &other) const { Fix16 ret = *this; ret -= other; return ret; }
const Fix16 operator-(const fix16_t other) const { Fix16 ret = *this; ret -= other; return ret; }
const Fix16 operator-(const double other) const { Fix16 ret = *this; ret -= other; return ret; }
const Fix16 operator-(const float other) const { Fix16 ret = *this; ret -= other; return ret; }
const Fix16 operator-(const int16_t other) const { Fix16 ret = *this; ret -= other; return ret; }
#ifndef FIXMATH_NO_OVERFLOW
const Fix16 ssub(const Fix16 &other) const { Fix16 ret = fix16_sadd(value, -other.value); return ret; }
const Fix16 ssub(const fix16_t other) const { Fix16 ret = fix16_sadd(value, -other); return ret; }
const Fix16 ssub(const double other) const { Fix16 ret = fix16_sadd(value, -fix16_from_dbl(other)); return ret; }
const Fix16 ssub(const float other) const { Fix16 ret = fix16_sadd(value, -fix16_from_float(other)); return ret; }
const Fix16 ssub(const int16_t other) const { Fix16 ret = fix16_sadd(value, -fix16_from_int(other)); return ret; }
#endif
const Fix16 operator*(const Fix16 &other) const { Fix16 ret = *this; ret *= other; return ret; }
const Fix16 operator*(const fix16_t other) const { Fix16 ret = *this; ret *= other; return ret; }
const Fix16 operator*(const double other) const { Fix16 ret = *this; ret *= other; return ret; }
const Fix16 operator*(const float other) const { Fix16 ret = *this; ret *= other; return ret; }
const Fix16 operator*(const int16_t other) const { Fix16 ret = *this; ret *= other; return ret; }
#ifndef FIXMATH_NO_OVERFLOW
const Fix16 smul(const Fix16 &other) const { Fix16 ret = fix16_smul(value, other.value); return ret; }
const Fix16 smul(const fix16_t other) const { Fix16 ret = fix16_smul(value, other); return ret; }
const Fix16 smul(const double other) const { Fix16 ret = fix16_smul(value, fix16_from_dbl(other)); return ret; }
const Fix16 smul(const float other) const { Fix16 ret = fix16_smul(value, fix16_from_float(other)); return ret; }
const Fix16 smul(const int16_t other) const { Fix16 ret = fix16_smul(value, fix16_from_int(other)); return ret; }
#endif
const Fix16 operator/(const Fix16 &other) const { Fix16 ret = *this; ret /= other; return ret; }
const Fix16 operator/(const fix16_t other) const { Fix16 ret = *this; ret /= other; return ret; }
const Fix16 operator/(const double other) const { Fix16 ret = *this; ret /= other; return ret; }
const Fix16 operator/(const float other) const { Fix16 ret = *this; ret /= other; return ret; }
const Fix16 operator/(const int16_t other) const { Fix16 ret = *this; ret /= other; return ret; }
#ifndef FIXMATH_NO_OVERFLOW
const Fix16 sdiv(const Fix16 &other) const { Fix16 ret = fix16_sdiv(value, other.value); return ret; }
const Fix16 sdiv(const fix16_t other) const { Fix16 ret = fix16_sdiv(value, other); return ret; }
const Fix16 sdiv(const double other) const { Fix16 ret = fix16_sdiv(value, fix16_from_dbl(other)); return ret; }
const Fix16 sdiv(const float other) const { Fix16 ret = fix16_sdiv(value, fix16_from_float(other)); return ret; }
const Fix16 sdiv(const int16_t other) const { Fix16 ret = fix16_sdiv(value, fix16_from_int(other)); return ret; }
#endif
int operator==(const Fix16 &other) const { return (value == other.value); }
int operator==(const fix16_t other) const { return (value == other); }
int operator==(const double other) const { return (value == fix16_from_dbl(other)); }
int operator==(const float other) const { return (value == fix16_from_float(other)); }
int operator==(const int16_t other) const { return (value == fix16_from_int(other)); }
int operator!=(const Fix16 &other) const { return (value != other.value); }
int operator!=(const fix16_t other) const { return (value != other); }
int operator!=(const double other) const { return (value != fix16_from_dbl(other)); }
int operator!=(const float other) const { return (value != fix16_from_float(other)); }
int operator!=(const int16_t other) const { return (value != fix16_from_int(other)); }
int operator<=(const Fix16 &other) const { return (value <= other.value); }
int operator<=(const fix16_t other) const { return (value <= other); }
int operator<=(const double other) const { return (value <= fix16_from_dbl(other)); }
int operator<=(const float other) const { return (value <= fix16_from_float(other)); }
int operator<=(const int16_t other) const { return (value <= fix16_from_int(other)); }
int operator>=(const Fix16 &other) const { return (value >= other.value); }
int operator>=(const fix16_t other) const { return (value >= other); }
int operator>=(const double other) const { return (value >= fix16_from_dbl(other)); }
int operator>=(const float other) const { return (value >= fix16_from_float(other)); }
int operator>=(const int16_t other) const { return (value >= fix16_from_int(other)); }
int operator< (const Fix16 &other) const { return (value < other.value); }
int operator< (const fix16_t other) const { return (value < other); }
int operator< (const double other) const { return (value < fix16_from_dbl(other)); }
int operator< (const float other) const { return (value < fix16_from_float(other)); }
int operator< (const int16_t other) const { return (value < fix16_from_int(other)); }
int operator> (const Fix16 &other) const { return (value > other.value); }
int operator> (const fix16_t other) const { return (value > other); }
int operator> (const double other) const { return (value > fix16_from_dbl(other)); }
int operator> (const float other) const { return (value > fix16_from_float(other)); }
int operator> (const int16_t other) const { return (value > fix16_from_int(other)); }
Fix16 sin() const { return Fix16(fix16_sin(value)); }
Fix16 cos() const { return Fix16(fix16_cos(value)); }
Fix16 tan() const { return Fix16(fix16_tan(value)); }
Fix16 asin() const { return Fix16(fix16_asin(value)); }
Fix16 acos() const { return Fix16(fix16_acos(value)); }
Fix16 atan() const { return Fix16(fix16_atan(value)); }
Fix16 atan2(const Fix16 &inY) const { return Fix16(fix16_atan2(value, inY.value)); }
Fix16 sqrt() const { return Fix16(fix16_sqrt(value)); }
};
#endif

View file

@ -0,0 +1,162 @@
#ifndef __libfixmath_int64_h__
#define __libfixmath_int64_h__
#ifdef __cplusplus
extern "C"
{
#endif
#ifndef FIXMATH_NO_64BIT
static inline int64_t int64_const(int32_t hi, uint32_t lo) { return (((int64_t)hi << 32) | lo); }
static inline int64_t int64_from_int32(int32_t x) { return (int64_t)x; }
static inline int32_t int64_hi(int64_t x) { return (x >> 32); }
static inline uint32_t int64_lo(int64_t x) { return (x & ((1ULL << 32) - 1)); }
static inline int64_t int64_add(int64_t x, int64_t y) { return (x + y); }
static inline int64_t int64_neg(int64_t x) { return (-x); }
static inline int64_t int64_sub(int64_t x, int64_t y) { return (x - y); }
static inline int64_t int64_shift(int64_t x, int8_t y) { return (y < 0 ? (x >> -y) : (x << y)); }
static inline int64_t int64_mul_i32_i32(int32_t x, int32_t y) { return (x * y); }
static inline int64_t int64_mul_i64_i32(int64_t x, int32_t y) { return (x * y); }
static inline int64_t int64_div_i64_i32(int64_t x, int32_t y) { return (x / y); }
static inline int int64_cmp_eq(int64_t x, int64_t y) { return (x == y); }
static inline int int64_cmp_ne(int64_t x, int64_t y) { return (x != y); }
static inline int int64_cmp_gt(int64_t x, int64_t y) { return (x > y); }
static inline int int64_cmp_ge(int64_t x, int64_t y) { return (x >= y); }
static inline int int64_cmp_lt(int64_t x, int64_t y) { return (x < y); }
static inline int int64_cmp_le(int64_t x, int64_t y) { return (x <= y); }
#else
typedef struct {
int32_t hi;
uint32_t lo;
} __int64_t;
static inline __int64_t int64_const(int32_t hi, uint32_t lo) { return (__int64_t){ hi, lo }; }
static inline __int64_t int64_from_int32(int32_t x) { return (__int64_t){ (x < 0 ? -1 : 0), x }; }
static inline int32_t int64_hi(__int64_t x) { return x.hi; }
static inline uint32_t int64_lo(__int64_t x) { return x.lo; }
static inline int int64_cmp_eq(__int64_t x, __int64_t y) { return ((x.hi == y.hi) && (x.lo == y.lo)); }
static inline int int64_cmp_ne(__int64_t x, __int64_t y) { return ((x.hi != y.hi) || (x.lo != y.lo)); }
static inline int int64_cmp_gt(__int64_t x, __int64_t y) { return ((x.hi > y.hi) || ((x.hi == y.hi) && (x.lo > y.lo))); }
static inline int int64_cmp_ge(__int64_t x, __int64_t y) { return ((x.hi > y.hi) || ((x.hi == y.hi) && (x.lo >= y.lo))); }
static inline int int64_cmp_lt(__int64_t x, __int64_t y) { return ((x.hi < y.hi) || ((x.hi == y.hi) && (x.lo < y.lo))); }
static inline int int64_cmp_le(__int64_t x, __int64_t y) { return ((x.hi < y.hi) || ((x.hi == y.hi) && (x.lo <= y.lo))); }
static inline __int64_t int64_add(__int64_t x, __int64_t y) {
__int64_t ret;
ret.hi = x.hi + y.hi;
ret.lo = x.lo + y.lo;
if((ret.lo < x.lo) || (ret.hi < y.hi))
ret.hi++;
return ret;
}
static inline __int64_t int64_neg(__int64_t x) {
__int64_t ret;
ret.hi = ~x.hi;
ret.lo = ~x.lo + 1;
if(ret.lo == 0)
ret.hi++;
return ret;
}
static inline __int64_t int64_sub(__int64_t x, __int64_t y) {
return int64_add(x, int64_neg(y));
}
static inline __int64_t int64_shift(__int64_t x, int8_t y) {
__int64_t ret;
if(y > 0) {
if(y >= 32)
return (__int64_t){ 0, 0 };
ret.hi = (x.hi << y) | (x.lo >> (32 - y));
ret.lo = (x.lo << y);
} else {
y = -y;
if(y >= 32)
return (__int64_t){ 0, 0 };
ret.lo = (x.lo >> y) | (x.hi << (32 - y));
ret.hi = (x.hi >> y);
}
return ret;
}
static inline __int64_t int64_mul_i32_i32(int32_t x, int32_t y) {
int16_t hi[2] = { (x >> 16), (y >> 16) };
uint16_t lo[2] = { (x & 0xFFFF), (y & 0xFFFF) };
int32_t r_hi = hi[0] * hi[1];
int32_t r_md = (hi[0] * lo[1]) + (hi[1] * lo[0]);
uint32_t r_lo = lo[0] * lo[1];
r_hi += (r_md >> 16);
r_lo += (r_md << 16);
return (__int64_t){ r_hi, r_lo };
}
static inline __int64_t int64_mul_i64_i32(__int64_t x, int32_t y) {
int neg = ((x.hi ^ y) < 0);
if(x.hi < 0)
x = int64_neg(x);
if(y < 0)
y = -y;
uint32_t _x[4] = { (x.hi >> 16), (x.hi & 0xFFFF), (x.lo >> 16), (x.lo & 0xFFFF) };
uint32_t _y[2] = { (y >> 16), (y & 0xFFFF) };
uint32_t r[4];
r[0] = (_x[0] * _y[0]);
r[1] = (_x[1] * _y[0]) + (_x[0] * _y[1]);
r[2] = (_x[1] * _y[1]) + (_x[2] * _y[0]);
r[3] = (_x[2] * _y[0]) + (_x[1] * _y[1]);
__int64_t ret;
ret.lo = r[0] + (r[1] << 16);
ret.hi = (r[3] << 16) + r[2] + (r[1] >> 16);
return (neg ? int64_neg(ret) : ret);
}
static inline __int64_t int64_div_i64_i32(__int64_t x, int32_t y) {
int neg = ((x.hi ^ y) < 0);
if(x.hi < 0)
x = int64_neg(x);
if(y < 0)
y = -y;
__int64_t ret = { (x.hi / y) , (x.lo / y) };
x.hi = x.hi % y;
x.lo = x.lo % y;
__int64_t _y = int64_from_int32(y);
__int64_t i;
for(i = int64_from_int32(1); int64_cmp_lt(_y, x); _y = int64_shift(_y, 1), i = int64_shift(i, 1));
while(x.hi) {
_y = int64_shift(_y, -1);
i = int64_shift(i, -1);
if(int64_cmp_ge(x, _y)) {
x = int64_sub(x, _y);
ret = int64_add(ret, i);
}
}
ret = int64_add(ret, int64_from_int32(x.lo / y));
return (neg ? int64_neg(ret) : ret);
}
#define int64_t __int64_t
#endif
#ifdef __cplusplus
}
#endif
#endif

View file

@ -214,7 +214,7 @@ static void scansector(int16_t startsectnum);
static void draw_rainbow_background(void); static void draw_rainbow_background(void);
int16_t editstatus = 0; int16_t editstatus = 0;
static int32_t global100horiz; // (-100..300)-scale horiz (the one passed to drawrooms) static fix16_t global100horiz; // (-100..300)-scale horiz (the one passed to drawrooms)
////////// YAX ////////// ////////// YAX //////////
@ -874,7 +874,7 @@ void yax_drawrooms(void (*SpriteAnimFunc)(int32_t,int32_t,int32_t,int32_t),
{ {
static uint8_t havebunch[YAX_MAXBUNCHES>>3]; static uint8_t havebunch[YAX_MAXBUNCHES>>3];
const int32_t horiz = global100horiz; const fix16_t horiz = global100horiz;
int32_t i, j, k, lev, cf, nmp; int32_t i, j, k, lev, cf, nmp;
int32_t bnchcnt, bnchnum[2] = {0,0}, maxlev[2]; int32_t bnchcnt, bnchnum[2] = {0,0}, maxlev[2];
@ -1386,6 +1386,7 @@ static int32_t xsi[8], ysi[8], horizycent;
static int32_t *horizlookup=0, *horizlookup2=0; static int32_t *horizlookup=0, *horizlookup2=0;
int32_t globalposx, globalposy, globalposz, globalhoriz; int32_t globalposx, globalposy, globalposz, globalhoriz;
fix16_t qglobalhoriz;
float fglobalposx, fglobalposy, fglobalposz; float fglobalposx, fglobalposy, fglobalposz;
int16_t globalang, globalcursectnum; int16_t globalang, globalcursectnum;
int32_t globalpal, cosglobalang, singlobalang; int32_t globalpal, cosglobalang, singlobalang;
@ -7911,7 +7912,7 @@ void set_globalang(int16_t ang)
// drawrooms // drawrooms
// //
int32_t drawrooms(int32_t daposx, int32_t daposy, int32_t daposz, int32_t drawrooms(int32_t daposx, int32_t daposy, int32_t daposz,
int16_t daang, int32_t dahoriz, int16_t dacursectnum) int16_t daang, fix16_t dahoriz, int16_t dacursectnum)
{ {
int32_t i, j, /*cz, fz,*/ closest; int32_t i, j, /*cz, fz,*/ closest;
int16_t *shortptr1, *shortptr2; int16_t *shortptr1, *shortptr2;
@ -7927,7 +7928,8 @@ int32_t drawrooms(int32_t daposx, int32_t daposy, int32_t daposz,
// xdimenscale is scale(xdimen,yxaspect,320); // xdimenscale is scale(xdimen,yxaspect,320);
// normalization by viewingrange so that center-of-aim doesn't depend on it // normalization by viewingrange so that center-of-aim doesn't depend on it
globalhoriz = mulscale16(dahoriz-100,divscale16(xdimenscale,viewingrange))+(ydimen>>1); globalhoriz = mulscale16(fix16_to_int(dahoriz)-100,divscale16(xdimenscale,viewingrange))+(ydimen>>1);
qglobalhoriz = mulscale16(dahoriz-F16(100), divscale16(xdimenscale, viewingrange))+fix16_from_int(ydimen>>1);
globaluclip = (0-globalhoriz)*xdimscale; globaluclip = (0-globalhoriz)*xdimscale;
globaldclip = (ydimen-globalhoriz)*xdimscale; globaldclip = (ydimen-globalhoriz)*xdimscale;

View file

@ -205,6 +205,7 @@ extern int32_t xdimen, xdimenrecip, halfxdimen, xdimenscale, xdimscale, ydimen;
extern float fxdimen; extern float fxdimen;
extern intptr_t frameoffset; extern intptr_t frameoffset;
extern int32_t globalposx, globalposy, globalposz, globalhoriz; extern int32_t globalposx, globalposy, globalposz, globalhoriz;
extern fix16_t qglobalhoriz;
extern float fglobalposx, fglobalposy, fglobalposz; extern float fglobalposx, fglobalposy, fglobalposz;
extern int16_t globalang, globalcursectnum; extern int16_t globalang, globalcursectnum;
extern int32_t globalpal, cosglobalang, singlobalang; extern int32_t globalpal, cosglobalang, singlobalang;

260
source/build/src/fix16.c Normal file
View file

@ -0,0 +1,260 @@
#include "fix16.h"
#include "int64.h"
/* Subtraction and addition with overflow detection.
* The versions without overflow detection are inlined in the header.
*/
#ifndef FIXMATH_NO_OVERFLOW
fix16_t fix16_add(fix16_t a, fix16_t b)
{
// Use unsigned integers because overflow with signed integers is
// an undefined operation (http://www.airs.com/blog/archives/120).
uint32_t _a = a, _b = b;
uint32_t sum = _a + _b;
// Overflow can only happen if sign of a == sign of b, and then
// it causes sign of sum != sign of a.
if (!((_a ^ _b) & 0x80000000) && ((_a ^ sum) & 0x80000000))
return fix16_overflow;
return sum;
}
fix16_t fix16_sub(fix16_t a, fix16_t b)
{
uint32_t _a = a, _b = b;
uint32_t diff = _a - _b;
// Overflow can only happen if sign of a != sign of b, and then
// it causes sign of diff != sign of a.
if (((_a ^ _b) & 0x80000000) && ((_a ^ diff) & 0x80000000))
return fix16_overflow;
return diff;
}
/* Saturating arithmetic */
fix16_t fix16_sadd(fix16_t a, fix16_t b)
{
fix16_t result = fix16_add(a, b);
if (result == fix16_overflow)
return (a >= 0) ? fix16_maximum : fix16_minimum;
return result;
}
fix16_t fix16_ssub(fix16_t a, fix16_t b)
{
fix16_t result = fix16_sub(a, b);
if (result == fix16_overflow)
return (a >= 0) ? fix16_maximum : fix16_minimum;
return result;
}
#endif
/* 64-bit implementation for fix16_mul. Fastest version for e.g. ARM Cortex M3.
* Performs a 32*32 -> 64bit multiplication. The middle 32 bits are the result,
* bottom 16 bits are used for rounding, and upper 16 bits are used for overflow
* detection.
*/
fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1)
{
int64_t product = (int64_t)inArg0 * inArg1;
#ifndef FIXMATH_NO_OVERFLOW
// The upper 17 bits should all be the same (the sign).
uint32_t upper = (product >> 47);
#endif
if (product < 0)
{
#ifndef FIXMATH_NO_OVERFLOW
if (~upper)
return fix16_overflow;
#endif
#ifndef FIXMATH_NO_ROUNDING
// This adjustment is required in order to round -1/2 correctly
product--;
#endif
}
else
{
#ifndef FIXMATH_NO_OVERFLOW
if (upper)
return fix16_overflow;
#endif
}
#ifdef FIXMATH_NO_ROUNDING
return product >> 16;
#else
fix16_t result = product >> 16;
result += (product & 0x8000) >> 15;
return result;
#endif
}
#ifndef FIXMATH_NO_OVERFLOW
/* Wrapper around fix16_mul to add saturating arithmetic. */
fix16_t fix16_smul(fix16_t inArg0, fix16_t inArg1)
{
fix16_t result = fix16_mul(inArg0, inArg1);
if (result == fix16_overflow)
{
if ((inArg0 >= 0) == (inArg1 >= 0))
return fix16_maximum;
else
return fix16_minimum;
}
return result;
}
#endif
/* 32-bit implementation of fix16_div. Fastest version for e.g. ARM Cortex M3.
* Performs 32-bit divisions repeatedly to reduce the remainder. For this to
* be efficient, the processor has to have 32-bit hardware division.
*/
#ifdef __GNUC__
// Count leading zeros, using processor-specific instruction if available.
#define clz(x) (__builtin_clzl(x) - (8 * sizeof(long) - 32))
#else
static uint8_t clz(uint32_t x)
{
uint8_t result = 0;
if (x == 0) return 32;
while (!(x & 0xF0000000)) { result += 4; x <<= 4; }
while (!(x & 0x80000000)) { result += 1; x <<= 1; }
return result;
}
#endif
fix16_t fix16_div(fix16_t a, fix16_t b)
{
// This uses a hardware 32/32 bit division multiple times, until we have
// computed all the bits in (a<<17)/b. Usually this takes 1-3 iterations.
if (b == 0)
return fix16_minimum;
uint32_t remainder = (a >= 0) ? a : (-a);
uint32_t divider = (b >= 0) ? b : (-b);
uint32_t quotient = 0;
int bit_pos = 17;
// Kick-start the division a bit.
// This improves speed in the worst-case scenarios where N and D are large
// It gets a lower estimate for the result by N/(D >> 17 + 1).
if (divider & 0xFFF00000)
{
uint32_t shifted_div = ((divider >> 17) + 1);
quotient = remainder / shifted_div;
remainder -= ((uint64_t)quotient * divider) >> 17;
}
// If the divider is divisible by 2^n, take advantage of it.
while (!(divider & 0xF) && bit_pos >= 4)
{
divider >>= 4;
bit_pos -= 4;
}
while (remainder && bit_pos >= 0)
{
// Shift remainder as much as we can without overflowing
int shift = clz(remainder);
if (shift > bit_pos) shift = bit_pos;
remainder <<= shift;
bit_pos -= shift;
uint32_t div = remainder / divider;
remainder = remainder % divider;
quotient += div << bit_pos;
#ifndef FIXMATH_NO_OVERFLOW
if (div & ~(0xFFFFFFFF >> bit_pos))
return fix16_overflow;
#endif
remainder <<= 1;
bit_pos--;
}
#ifndef FIXMATH_NO_ROUNDING
// Quotient is always positive so rounding is easy
quotient++;
#endif
fix16_t result = quotient >> 1;
// Figure out the sign of the result
if ((a ^ b) & 0x80000000)
{
#ifndef FIXMATH_NO_OVERFLOW
if (result == fix16_minimum)
return fix16_overflow;
#endif
result = -result;
}
return result;
}
#ifndef FIXMATH_NO_OVERFLOW
/* Wrapper around fix16_div to add saturating arithmetic. */
fix16_t fix16_sdiv(fix16_t inArg0, fix16_t inArg1)
{
fix16_t result = fix16_div(inArg0, inArg1);
if (result == fix16_overflow)
{
if ((inArg0 >= 0) == (inArg1 >= 0))
return fix16_maximum;
else
return fix16_minimum;
}
return result;
}
#endif
fix16_t fix16_mod(fix16_t x, fix16_t y) { return x %= y; }
#ifndef FIXMATH_NO_64BIT
fix16_t fix16_lerp8(fix16_t inArg0, fix16_t inArg1, uint8_t inFract)
{
int64_t tempOut = int64_mul_i32_i32(inArg0, ((1 << 8) - inFract));
tempOut = int64_add(tempOut, int64_mul_i32_i32(inArg1, inFract));
tempOut = int64_shift(tempOut, -8);
return (fix16_t)int64_lo(tempOut);
}
fix16_t fix16_lerp16(fix16_t inArg0, fix16_t inArg1, uint16_t inFract)
{
int64_t tempOut = int64_mul_i32_i32(inArg0, (((int32_t)1 << 16) - inFract));
tempOut = int64_add(tempOut, int64_mul_i32_i32(inArg1, inFract));
tempOut = int64_shift(tempOut, -16);
return (fix16_t)int64_lo(tempOut);
}
fix16_t fix16_lerp32(fix16_t inArg0, fix16_t inArg1, uint32_t inFract)
{
int64_t tempOut;
tempOut = ((int64_t)inArg0 * (0 - inFract));
tempOut += ((int64_t)inArg1 * inFract);
tempOut >>= 32;
return (fix16_t)tempOut;
}
#endif

View file

@ -0,0 +1,114 @@
#include "fix16.h"
#include <stdbool.h>
#include <ctype.h>
static const uint32_t scales[8] = {
/* 5 decimals is enough for full fix16_t precision */
1, 10, 100, 1000, 10000, 100000, 100000, 100000
};
static char *itoa_loop(char *buf, uint32_t scale, uint32_t value, bool skip)
{
while (scale)
{
unsigned digit = (value / scale);
if (!skip || digit || scale == 1)
{
skip = false;
*buf++ = '0' + digit;
value %= scale;
}
scale /= 10;
}
return buf;
}
void fix16_to_str(fix16_t value, char *buf, int decimals)
{
uint32_t uvalue = (value >= 0) ? value : -value;
if (value < 0)
*buf++ = '-';
/* Separate the integer and decimal parts of the value */
unsigned intpart = uvalue >> 16;
uint32_t fracpart = uvalue & 0xFFFF;
uint32_t scale = scales[decimals & 7];
fracpart = fix16_mul(fracpart, scale);
if (fracpart >= scale)
{
/* Handle carry from decimal part */
intpart++;
fracpart -= scale;
}
/* Format integer part */
buf = itoa_loop(buf, 10000, intpart, true);
/* Format decimal part (if any) */
if (scale != 1)
{
*buf++ = '.';
buf = itoa_loop(buf, scale / 10, fracpart, false);
}
*buf = '\0';
}
fix16_t fix16_from_str(const char *buf)
{
while (isspace(*buf))
buf++;
/* Decode the sign */
bool negative = (*buf == '-');
if (*buf == '+' || *buf == '-')
buf++;
/* Decode the integer part */
uint32_t intpart = 0;
int count = 0;
while (isdigit(*buf))
{
intpart *= 10;
intpart += *buf++ - '0';
count++;
}
if (count == 0 || count > 5
|| intpart > 32768 || (!negative && intpart > 32767))
return fix16_overflow;
fix16_t value = intpart << 16;
/* Decode the decimal part */
if (*buf == '.' || *buf == ',')
{
buf++;
uint32_t fracpart = 0;
uint32_t scale = 1;
while (isdigit(*buf) && scale < 100000)
{
scale *= 10;
fracpart *= 10;
fracpart += *buf++ - '0';
}
value += fix16_div(fracpart, scale);
}
/* Verify that there is no garbage left over */
while (*buf != '\0')
{
if (!isdigit(*buf) && !isspace(*buf))
return fix16_overflow;
buf++;
}
return negative ? -value : value;
}

View file

@ -4630,7 +4630,7 @@ void polymost_drawrooms()
gsinang2 = gsinang * (fviewingrange * (1.0f/65536.f)); gsinang2 = gsinang * (fviewingrange * (1.0f/65536.f));
ghalfx = (float)(xdimen>>1); ghalfx = (float)(xdimen>>1);
grhalfxdown10 = 1.f/(ghalfx*1024.f); grhalfxdown10 = 1.f/(ghalfx*1024.f);
ghoriz = (float)globalhoriz; ghoriz = fix16_to_float(qglobalhoriz);
gvisibility = ((float)globalvisibility)*FOGSCALE; gvisibility = ((float)globalvisibility)*FOGSCALE;

View file

@ -2611,7 +2611,7 @@ ACTOR_STATIC void A_DoProjectileBounce(int const spriteNum)
ACTOR_STATIC void P_HandleBeingSpitOn(DukePlayer_t * const ps) ACTOR_STATIC void P_HandleBeingSpitOn(DukePlayer_t * const ps)
{ {
ps->horiz += 32; ps->qhoriz += F16(32);
ps->return_to_center = 8; ps->return_to_center = 8;
if (ps->loogcnt) if (ps->loogcnt)
@ -4303,7 +4303,7 @@ ACTOR_STATIC void G_MoveActors(void)
DELETE_SPRITE_AND_CONTINUE(spriteNum); DELETE_SPRITE_AND_CONTINUE(spriteNum);
} }
pSprite->z = pPlayer->pos.z + pPlayer->pyoff - pData[2] + ZOFFSET3 + ((100 - pPlayer->horiz) << 4); pSprite->z = pPlayer->pos.z + pPlayer->pyoff - pData[2] + ZOFFSET3 + (fix16_to_int(F16(100) - pPlayer->qhoriz) << 4);
if (pData[2] > 512) if (pData[2] > 512)
pData[2] -= 128; pData[2] -= 128;

View file

@ -334,7 +334,7 @@ static void M32_drawdebug(void)
#endif #endif
static int32_t G_DoThirdPerson(const DukePlayer_t *pp, vec3_t *vect, int16_t *vsectnum, int32_t ang, int32_t horiz) static int32_t G_DoThirdPerson(const DukePlayer_t *pp, vec3_t *vect, int16_t *vsectnum, int32_t ang, fix16_t qhoriz)
{ {
spritetype *sp = &sprite[pp->i]; spritetype *sp = &sprite[pp->i];
int32_t i, hx, hy; int32_t i, hx, hy;
@ -344,7 +344,7 @@ static int32_t G_DoThirdPerson(const DukePlayer_t *pp, vec3_t *vect, int16_t *vs
vec3_t n = { vec3_t n = {
sintable[(ang+1536)&2047]>>4, sintable[(ang+1536)&2047]>>4,
sintable[(ang+1024)&2047]>>4, sintable[(ang+1024)&2047]>>4,
(horiz-100)*128 fix16_mul(qhoriz-F16(100), F16(128))
}; };
updatesectorz(vect->x,vect->y,vect->z,vsectnum); updatesectorz(vect->x,vect->y,vect->z,vsectnum);
@ -522,7 +522,7 @@ static void G_SE40(int32_t smoothratio)
polymer_setanimatesprites(G_DoSpriteAnimations, CAMERA(pos.x), CAMERA(pos.y), CAMERA(ang), smoothratio); polymer_setanimatesprites(G_DoSpriteAnimations, CAMERA(pos.x), CAMERA(pos.y), CAMERA(ang), smoothratio);
#endif #endif
drawrooms(sprite[sprite2].x + x, sprite[sprite2].y + y, drawrooms(sprite[sprite2].x + x, sprite[sprite2].y + y,
z + renderz, CAMERA(ang), CAMERA(horiz), sect); z + renderz, CAMERA(ang), CAMERA(qhoriz), sect);
drawing_ror = 1 + level; drawing_ror = 1 + level;
if (drawing_ror == 2) // viewing from top if (drawing_ror == 2) // viewing from top
@ -555,7 +555,7 @@ static void G_SE40(int32_t smoothratio)
} }
#endif #endif
void G_HandleMirror(int32_t x, int32_t y, int32_t z, int32_t a, int32_t horiz, int32_t smoothratio) void G_HandleMirror(int32_t x, int32_t y, int32_t z, int32_t a, fix16_t qhoriz, int32_t smoothratio)
{ {
if ((gotpic[MIRROR>>3]&(1<<(MIRROR&7))) if ((gotpic[MIRROR>>3]&(1<<(MIRROR&7)))
#ifdef POLYMER #ifdef POLYMER
@ -616,12 +616,12 @@ void G_HandleMirror(int32_t x, int32_t y, int32_t z, int32_t a, int32_t horiz, i
int32_t didmirror; int32_t didmirror;
yax_preparedrawrooms(); yax_preparedrawrooms();
didmirror = drawrooms(tposx,tposy,z,tang,horiz,g_mirrorSector[i]+MAXSECTORS); didmirror = drawrooms(tposx,tposy,z,tang,qhoriz,g_mirrorSector[i]+MAXSECTORS);
yax_drawrooms(G_DoSpriteAnimations, g_mirrorSector[i], didmirror, smoothratio); yax_drawrooms(G_DoSpriteAnimations, g_mirrorSector[i], didmirror, smoothratio);
} }
#ifdef USE_OPENGL #ifdef USE_OPENGL
else else
drawrooms(tposx,tposy,z,tang,horiz,g_mirrorSector[i]+MAXSECTORS); drawrooms(tposx,tposy,z,tang,qhoriz,g_mirrorSector[i]+MAXSECTORS);
// XXX: Sprites don't get drawn with TROR/Polymost // XXX: Sprites don't get drawn with TROR/Polymost
#endif #endif
display_mirror = 1; display_mirror = 1;
@ -910,8 +910,8 @@ void G_DrawRooms(int32_t playerNum, int32_t smoothRatio)
CAMERA(pos) = camVect; CAMERA(pos) = camVect;
CAMERA(ang) = pPlayer->oang + mulscale16(((pPlayer->ang + 1024 - pPlayer->oang) & 2047) - 1024, smoothRatio); CAMERA(ang) = pPlayer->oang + mulscale16(((pPlayer->ang + 1024 - pPlayer->oang) & 2047) - 1024, smoothRatio);
CAMERA(ang) += pPlayer->look_ang; CAMERA(ang) += pPlayer->look_ang;
CAMERA(horiz) = pPlayer->ohoriz + pPlayer->ohorizoff CAMERA(qhoriz) = pPlayer->oqhoriz + pPlayer->oqhorizoff
+ mulscale16((pPlayer->horiz + pPlayer->horizoff - pPlayer->ohoriz - pPlayer->ohorizoff), smoothRatio); + mulscale16((pPlayer->qhoriz + pPlayer->qhorizoff - pPlayer->oqhoriz - pPlayer->oqhorizoff), smoothRatio);
if (ud.viewbob) if (ud.viewbob)
{ {
@ -927,10 +927,10 @@ void G_DrawRooms(int32_t playerNum, int32_t smoothRatio)
{ {
CAMERA(pos.z) -= 3072; CAMERA(pos.z) -= 3072;
if (G_DoThirdPerson(pPlayer, &CAMERA(pos), &CAMERA(sect), CAMERA(ang), CAMERA(horiz)) < 0) if (G_DoThirdPerson(pPlayer, &CAMERA(pos), &CAMERA(sect), CAMERA(ang), CAMERA(qhoriz)) < 0)
{ {
CAMERA(pos.z) += 3072; CAMERA(pos.z) += 3072;
G_DoThirdPerson(pPlayer, &CAMERA(pos), &CAMERA(sect), CAMERA(ang), CAMERA(horiz)); G_DoThirdPerson(pPlayer, &CAMERA(pos), &CAMERA(sect), CAMERA(ang), CAMERA(qhoriz));
} }
} }
} }
@ -941,7 +941,7 @@ void G_DrawRooms(int32_t playerNum, int32_t smoothRatio)
// looking through viewscreen // looking through viewscreen
CAMERA(pos) = camVect; CAMERA(pos) = camVect;
CAMERA(ang) = pPlayer->ang + pPlayer->look_ang; CAMERA(ang) = pPlayer->ang + pPlayer->look_ang;
CAMERA(horiz) = 100 + sprite[pPlayer->newowner].shade; CAMERA(qhoriz) = fix16_from_int(100 + sprite[pPlayer->newowner].shade);
CAMERA(sect) = sprite[pPlayer->newowner].sectnum; CAMERA(sect) = sprite[pPlayer->newowner].sectnum;
} }
@ -1005,7 +1005,7 @@ void G_DrawRooms(int32_t playerNum, int32_t smoothRatio)
// like showview must cope with that situation or bail out! // like showview must cope with that situation or bail out!
int const noDraw = VM_OnEventWithReturn(EVENT_DISPLAYROOMS, pPlayer->i, playerNum, 0); int const noDraw = VM_OnEventWithReturn(EVENT_DISPLAYROOMS, pPlayer->i, playerNum, 0);
CAMERA(horiz) = clamp(CAMERA(horiz), HORIZ_MIN, HORIZ_MAX); CAMERA(qhoriz) = fix16_clamp(CAMERA(qhoriz), F16(HORIZ_MIN), F16(HORIZ_MAX));
if (noDraw != 1) // event return values other than 0 and 1 are reserved if (noDraw != 1) // event return values other than 0 and 1 are reserved
{ {
@ -1015,7 +1015,7 @@ void G_DrawRooms(int32_t playerNum, int32_t smoothRatio)
"other values are reserved.\n"); "other values are reserved.\n");
*/ */
G_HandleMirror(CAMERA(pos.x), CAMERA(pos.y), CAMERA(pos.z), CAMERA(ang), CAMERA(horiz), smoothRatio); G_HandleMirror(CAMERA(pos.x), CAMERA(pos.y), CAMERA(pos.z), CAMERA(ang), CAMERA(qhoriz), smoothRatio);
#ifdef LEGACY_ROR #ifdef LEGACY_ROR
G_SE40(smoothRatio); G_SE40(smoothRatio);
#endif #endif
@ -1030,7 +1030,7 @@ void G_DrawRooms(int32_t playerNum, int32_t smoothRatio)
gotpic[MIRROR>>3] |= (1<<(MIRROR&7)); gotpic[MIRROR>>3] |= (1<<(MIRROR&7));
#else #else
yax_preparedrawrooms(); yax_preparedrawrooms();
drawrooms(CAMERA(pos.x),CAMERA(pos.y),CAMERA(pos.z),CAMERA(ang),CAMERA(horiz),CAMERA(sect)); drawrooms(CAMERA(pos.x),CAMERA(pos.y),CAMERA(pos.z),CAMERA(ang),CAMERA(qhoriz),CAMERA(sect));
yax_drawrooms(G_DoSpriteAnimations, CAMERA(sect), 0, smoothRatio); yax_drawrooms(G_DoSpriteAnimations, CAMERA(sect), 0, smoothRatio);
#ifdef LEGACY_ROR #ifdef LEGACY_ROR
if ((unsigned)ror_sprite < MAXSPRITES && drawing_ror == 1) // viewing from bottom if ((unsigned)ror_sprite < MAXSPRITES && drawing_ror == 1) // viewing from bottom
@ -2118,7 +2118,7 @@ int A_Spawn(int spriteNum, int tileNum)
T1(newSprite) = krand() & 1; T1(newSprite) = krand() & 1;
pSprite->z = (3 << 8) + pPlayer->pyoff + pPlayer->pos.z - ((pPlayer->horizoff + pPlayer->horiz - 100) << 4); pSprite->z = (3 << 8) + pPlayer->pyoff + pPlayer->pos.z - (fix16_to_int((pPlayer->qhorizoff + pPlayer->qhoriz - F16(100))) << 4);
if (pSprite->picnum == SHOTGUNSHELL) if (pSprite->picnum == SHOTGUNSHELL)
pSprite->z += (3 << 8); pSprite->z += (3 << 8);
@ -6858,7 +6858,7 @@ int G_DoMoveThings(void)
sprite[g_player[i].ps->holoduke_on].cstat ^= 256; sprite[g_player[i].ps->holoduke_on].cstat ^= 256;
hitscan((vec3_t *)pPlayer, pPlayer->cursectnum, sintable[(pPlayer->ang + 512) & 2047], sintable[pPlayer->ang & 2047], hitscan((vec3_t *)pPlayer, pPlayer->cursectnum, sintable[(pPlayer->ang + 512) & 2047], sintable[pPlayer->ang & 2047],
(100 - pPlayer->horiz - pPlayer->horizoff) << 11, &hitData, 0xffff0030); fix16_to_int(F16(100) - pPlayer->qhoriz - pPlayer->qhorizoff) << 11, &hitData, 0xffff0030);
for (bssize_t TRAVERSE_CONNECT(i)) for (bssize_t TRAVERSE_CONNECT(i))
if (g_player[i].ps->holoduke_on != -1) if (g_player[i].ps->holoduke_on != -1)

View file

@ -29,6 +29,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "premap.h" // XXX #include "premap.h" // XXX
#endif #endif
#include "fix16.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -127,7 +129,8 @@ static inline int32_t G_GetLogoFlags(void)
typedef struct { typedef struct {
vec3_t pos; vec3_t pos;
int32_t dist, clock; int32_t dist, clock;
int16_t ang, horiz, sect; fix16_t qhoriz;
int16_t ang, sect;
} camera_t; } camera_t;
extern camera_t g_camera; extern camera_t g_camera;
@ -189,7 +192,8 @@ typedef struct {
int32_t returnvar[MAX_RETURN_VALUES-1]; int32_t returnvar[MAX_RETURN_VALUES-1];
#if !defined LUNATIC #if !defined LUNATIC
int16_t cameraang, camerasect, camerahoriz; int16_t cameraang, camerasect;
fix16_t cameraqhoriz;
#endif #endif
int16_t pause_on,from_bonus; int16_t pause_on,from_bonus;
int16_t camerasprite,last_camsprite; int16_t camerasprite,last_camsprite;
@ -367,7 +371,7 @@ void G_DisplayRest(int32_t smoothratio);
void G_DoSpriteAnimations(int32_t ourx, int32_t oury, int32_t oura, int32_t smoothratio); void G_DoSpriteAnimations(int32_t ourx, int32_t oury, int32_t oura, int32_t smoothratio);
void G_DrawBackground(void); void G_DrawBackground(void);
void G_DrawFrags(void); void G_DrawFrags(void);
void G_HandleMirror(int32_t x, int32_t y, int32_t z, int32_t a, int32_t horiz, int32_t smoothratio); void G_HandleMirror(int32_t x, int32_t y, int32_t z, int32_t a, fix16_t horiz, int32_t smoothratio);
void G_DrawRooms(int32_t snum,int32_t smoothratio); void G_DrawRooms(int32_t snum,int32_t smoothratio);
void G_DrawTXDigiNumZ(int32_t starttile,int32_t x,int32_t y,int32_t n,int32_t s,int32_t pal,int32_t cs,int32_t x1,int32_t y1,int32_t x2,int32_t y2,int32_t z); void G_DrawTXDigiNumZ(int32_t starttile,int32_t x,int32_t y,int32_t n,int32_t s,int32_t pal,int32_t cs,int32_t x1,int32_t y1,int32_t x2,int32_t y2,int32_t z);
int G_FPSLimit(void); int G_FPSLimit(void);

View file

@ -285,7 +285,7 @@ GAMEEXEC_STATIC GAMEEXEC_INLINE void P_ForceAngle(DukePlayer_t *pPlayer)
{ {
int const nAngle = 128-(krand()&255); int const nAngle = 128-(krand()&255);
pPlayer->horiz += 64; pPlayer->qhoriz += F16(64);
pPlayer->return_to_center = 9; pPlayer->return_to_center = 9;
pPlayer->rotscrnang = nAngle >> 1; pPlayer->rotscrnang = nAngle >> 1;
pPlayer->look_ang = pPlayer->rotscrnang; pPlayer->look_ang = pPlayer->rotscrnang;

View file

@ -539,9 +539,9 @@ int32_t __fastcall VM_GetPlayer(int32_t const playerNum, int32_t labelNum, int32
case PLAYER_POSX: labelNum = ps->pos.x; break; case PLAYER_POSX: labelNum = ps->pos.x; break;
case PLAYER_POSY: labelNum = ps->pos.y; break; case PLAYER_POSY: labelNum = ps->pos.y; break;
case PLAYER_POSZ: labelNum = ps->pos.z; break; case PLAYER_POSZ: labelNum = ps->pos.z; break;
case PLAYER_HORIZ: labelNum = ps->horiz; break; case PLAYER_HORIZ: labelNum = fix16_to_int(ps->qhoriz); break;
case PLAYER_OHORIZ: labelNum = ps->ohoriz; break; case PLAYER_OHORIZ: labelNum = fix16_to_int(ps->oqhoriz); break;
case PLAYER_OHORIZOFF: labelNum = ps->ohorizoff; break; case PLAYER_OHORIZOFF: labelNum = fix16_to_int(ps->oqhorizoff); break;
case PLAYER_INVDISPTIME: labelNum = ps->invdisptime; break; case PLAYER_INVDISPTIME: labelNum = ps->invdisptime; break;
case PLAYER_BOBPOSX: labelNum = ps->bobpos.x; break; case PLAYER_BOBPOSX: labelNum = ps->bobpos.x; break;
case PLAYER_BOBPOSY: labelNum = ps->bobpos.y; break; case PLAYER_BOBPOSY: labelNum = ps->bobpos.y; break;
@ -578,7 +578,7 @@ int32_t __fastcall VM_GetPlayer(int32_t const playerNum, int32_t labelNum, int32
case PLAYER_CURR_WEAPON: labelNum = ps->curr_weapon; break; case PLAYER_CURR_WEAPON: labelNum = ps->curr_weapon; break;
case PLAYER_LAST_WEAPON: labelNum = ps->last_weapon; break; case PLAYER_LAST_WEAPON: labelNum = ps->last_weapon; break;
case PLAYER_TIPINCS: labelNum = ps->tipincs; break; case PLAYER_TIPINCS: labelNum = ps->tipincs; break;
case PLAYER_HORIZOFF: labelNum = ps->horizoff; break; case PLAYER_HORIZOFF: labelNum = fix16_to_int(ps->qhorizoff); break;
case PLAYER_WANTWEAPONFIRE: labelNum = ps->wantweaponfire; break; case PLAYER_WANTWEAPONFIRE: labelNum = ps->wantweaponfire; break;
case PLAYER_HOLODUKE_AMOUNT: labelNum = ps->inv_amount[GET_HOLODUKE]; break; case PLAYER_HOLODUKE_AMOUNT: labelNum = ps->inv_amount[GET_HOLODUKE]; break;
case PLAYER_NEWOWNER: labelNum = ps->newowner; break; case PLAYER_NEWOWNER: labelNum = ps->newowner; break;
@ -723,9 +723,9 @@ void __fastcall VM_SetPlayer(int32_t const playerNum, int32_t const labelNum, in
case PLAYER_POSX: ps->pos.x = iSet; break; case PLAYER_POSX: ps->pos.x = iSet; break;
case PLAYER_POSY: ps->pos.y = iSet; break; case PLAYER_POSY: ps->pos.y = iSet; break;
case PLAYER_POSZ: ps->pos.z = iSet; break; case PLAYER_POSZ: ps->pos.z = iSet; break;
case PLAYER_HORIZ: ps->horiz = iSet; break; case PLAYER_HORIZ: ps->qhoriz = fix16_from_int(iSet); break;
case PLAYER_OHORIZ: ps->ohoriz = iSet; break; case PLAYER_OHORIZ: ps->oqhoriz = fix16_from_int(iSet); break;
case PLAYER_OHORIZOFF: ps->ohorizoff = iSet; break; case PLAYER_OHORIZOFF: ps->oqhorizoff = fix16_from_int(iSet); break;
case PLAYER_INVDISPTIME: ps->invdisptime = iSet; break; case PLAYER_INVDISPTIME: ps->invdisptime = iSet; break;
case PLAYER_BOBPOSX: ps->bobpos.x = iSet; break; case PLAYER_BOBPOSX: ps->bobpos.x = iSet; break;
case PLAYER_BOBPOSY: ps->bobpos.y = iSet; break; case PLAYER_BOBPOSY: ps->bobpos.y = iSet; break;
@ -762,7 +762,7 @@ void __fastcall VM_SetPlayer(int32_t const playerNum, int32_t const labelNum, in
case PLAYER_CURR_WEAPON: ps->curr_weapon = iSet; break; case PLAYER_CURR_WEAPON: ps->curr_weapon = iSet; break;
case PLAYER_LAST_WEAPON: ps->last_weapon = iSet; break; case PLAYER_LAST_WEAPON: ps->last_weapon = iSet; break;
case PLAYER_TIPINCS: ps->tipincs = iSet; break; case PLAYER_TIPINCS: ps->tipincs = iSet; break;
case PLAYER_HORIZOFF: ps->horizoff = iSet; break; case PLAYER_HORIZOFF: ps->qhorizoff = fix16_from_int(iSet); break;
case PLAYER_WANTWEAPONFIRE: ps->wantweaponfire = iSet; break; case PLAYER_WANTWEAPONFIRE: ps->wantweaponfire = iSet; break;
case PLAYER_HOLODUKE_AMOUNT: ps->inv_amount[GET_HOLODUKE] = iSet; break; case PLAYER_HOLODUKE_AMOUNT: ps->inv_amount[GET_HOLODUKE] = iSet; break;
case PLAYER_NEWOWNER: ps->newowner = iSet; break; case PLAYER_NEWOWNER: ps->newowner = iSet; break;
@ -907,7 +907,7 @@ int32_t __fastcall VM_GetPlayerInput(int32_t const playerNum, int32_t labelNum)
switch (labelNum) switch (labelNum)
{ {
case INPUT_AVEL: labelNum = i->avel; break; case INPUT_AVEL: labelNum = i->avel; break;
case INPUT_HORZ: labelNum = i->horz; break; case INPUT_HORZ: labelNum = fix16_to_int(i->qhorz); break;
case INPUT_FVEL: labelNum = i->fvel; break; case INPUT_FVEL: labelNum = i->fvel; break;
case INPUT_SVEL: labelNum = i->svel; break; case INPUT_SVEL: labelNum = i->svel; break;
case INPUT_BITS: labelNum = i->bits; break; case INPUT_BITS: labelNum = i->bits; break;
@ -931,7 +931,7 @@ void __fastcall VM_SetPlayerInput(int32_t const playerNum, int32_t const labelNu
switch (labelNum) switch (labelNum)
{ {
case INPUT_AVEL: i->avel = iSet; break; case INPUT_AVEL: i->avel = iSet; break;
case INPUT_HORZ: i->horz = iSet; break; case INPUT_HORZ: i->qhorz = fix16_from_int(iSet); break;
case INPUT_FVEL: i->fvel = iSet; break; case INPUT_FVEL: i->fvel = iSet; break;
case INPUT_SVEL: i->svel = iSet; break; case INPUT_SVEL: i->svel = iSet; break;
case INPUT_BITS: i->bits = iSet; break; case INPUT_BITS: i->bits = iSet; break;

View file

@ -1544,7 +1544,7 @@ static void Gv_AddSystemVars(void)
Gv_NewVar("cameray",(intptr_t)&ud.camerapos.y, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR); Gv_NewVar("cameray",(intptr_t)&ud.camerapos.y, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
Gv_NewVar("cameraz",(intptr_t)&ud.camerapos.z, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR); Gv_NewVar("cameraz",(intptr_t)&ud.camerapos.z, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
Gv_NewVar("cameraang",(intptr_t)&ud.cameraang, GAMEVAR_SYSTEM | GAMEVAR_INT16PTR); Gv_NewVar("cameraang",(intptr_t)&ud.cameraang, GAMEVAR_SYSTEM | GAMEVAR_INT16PTR);
Gv_NewVar("camerahoriz",(intptr_t)&ud.camerahoriz, GAMEVAR_SYSTEM | GAMEVAR_INT16PTR); Gv_NewVar("camerahoriz",(intptr_t)&ud.cameraqhoriz, GAMEVAR_SYSTEM | GAMEVAR_INT16PTR); // XXX FIXME
Gv_NewVar("camerasect",(intptr_t)&ud.camerasect, GAMEVAR_SYSTEM | GAMEVAR_INT16PTR); Gv_NewVar("camerasect",(intptr_t)&ud.camerasect, GAMEVAR_SYSTEM | GAMEVAR_INT16PTR);
Gv_NewVar("cameradist",(intptr_t)&g_cameraDistance, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR); Gv_NewVar("cameradist",(intptr_t)&g_cameraDistance, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
Gv_NewVar("cameraclock",(intptr_t)&g_cameraClock, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR); Gv_NewVar("cameraclock",(intptr_t)&g_cameraClock, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
@ -1701,7 +1701,7 @@ void Gv_RefreshPointers(void)
aGameVars[Gv_GetVarIndex("cameray")].global = (intptr_t)&ud.camerapos.y; aGameVars[Gv_GetVarIndex("cameray")].global = (intptr_t)&ud.camerapos.y;
aGameVars[Gv_GetVarIndex("cameraz")].global = (intptr_t)&ud.camerapos.z; aGameVars[Gv_GetVarIndex("cameraz")].global = (intptr_t)&ud.camerapos.z;
aGameVars[Gv_GetVarIndex("cameraang")].global = (intptr_t)&ud.cameraang; aGameVars[Gv_GetVarIndex("cameraang")].global = (intptr_t)&ud.cameraang;
aGameVars[Gv_GetVarIndex("camerahoriz")].global = (intptr_t)&ud.camerahoriz; aGameVars[Gv_GetVarIndex("camerahoriz")].global = (intptr_t)&ud.cameraqhoriz; // XXX FIXME
aGameVars[Gv_GetVarIndex("camerasect")].global = (intptr_t)&ud.camerasect; aGameVars[Gv_GetVarIndex("camerasect")].global = (intptr_t)&ud.camerasect;
aGameVars[Gv_GetVarIndex("cameradist")].global = (intptr_t)&g_cameraDistance; aGameVars[Gv_GetVarIndex("cameradist")].global = (intptr_t)&g_cameraDistance;
aGameVars[Gv_GetVarIndex("cameraclock")].global = (intptr_t)&g_cameraClock; aGameVars[Gv_GetVarIndex("cameraclock")].global = (intptr_t)&g_cameraClock;

View file

@ -1442,8 +1442,8 @@ void Net_FillPlayerUpdate(playerupdate_t *update, int32_t player)
update->opos = g_player[player].ps->opos; update->opos = g_player[player].ps->opos;
update->vel = g_player[player].ps->vel; update->vel = g_player[player].ps->vel;
update->ang = g_player[player].ps->ang; update->ang = g_player[player].ps->ang;
update->horiz = g_player[player].ps->horiz; update->horiz = g_player[player].ps->qhoriz;
update->horizoff = g_player[player].ps->horizoff; update->horizoff = g_player[player].ps->qhorizoff;
update->ping = g_player[player].ping; update->ping = g_player[player].ping;
update->deadflag = g_player[player].ps->dead_flag; update->deadflag = g_player[player].ps->dead_flag;
update->playerquitflag = g_player[player].playerquitflag; update->playerquitflag = g_player[player].playerquitflag;
@ -1459,8 +1459,8 @@ void Net_ExtractPlayerUpdate(playerupdate_t *update, int32_t type)
g_player[playerindex].ps->opos = update->opos; g_player[playerindex].ps->opos = update->opos;
g_player[playerindex].ps->vel = update->vel; g_player[playerindex].ps->vel = update->vel;
g_player[playerindex].ps->ang = update->ang; g_player[playerindex].ps->ang = update->ang;
g_player[playerindex].ps->horiz = update->horiz; g_player[playerindex].ps->qhoriz = update->horiz;
g_player[playerindex].ps->horizoff = update->horizoff; g_player[playerindex].ps->qhorizoff = update->horizoff;
} }
if (type == PACKET_MASTER_TO_SLAVE) if (type == PACKET_MASTER_TO_SLAVE)

View file

@ -289,7 +289,7 @@ static int A_FindTargetSprite(const spritetype *pSprite, int projAng, int projec
if (pSprite->picnum == APLAYER) if (pSprite->picnum == APLAYER)
{ {
const DukePlayer_t *const ps = g_player[P_GetP(pSprite)].ps; const DukePlayer_t *const ps = g_player[P_GetP(pSprite)].ps;
onScreen = (klabs(scale(SZ(spriteNum)-pSprite->z,10,spriteDist)-(ps->horiz+ps->horizoff-100)) < 100); onScreen = (klabs(scale(SZ(spriteNum)-pSprite->z,10,spriteDist)-fix16_to_int(ps->qhoriz+ps->qhorizoff-F16(100))) < 100);
} }
int const canSee = (PN(spriteNum) == ORGANTIC || PN(spriteNum) == ROTATEGUN) int const canSee = (PN(spriteNum) == ORGANTIC || PN(spriteNum) == ROTATEGUN)
@ -480,7 +480,7 @@ static void P_PreFireHitscan(int spriteNum, int playerNum, int projecTile, vec3_
{ {
hitdata_t hitData; hitdata_t hitData;
*zvel = A_GetShootZvel((100-pPlayer->horiz-pPlayer->horizoff)<<5); *zvel = A_GetShootZvel(fix16_to_int(F16(100)-pPlayer->qhoriz-pPlayer->qhorizoff)<<5);
hitscan(srcVect, sprite[spriteNum].sectnum, sintable[(*shootAng + 512) & 2047], hitscan(srcVect, sprite[spriteNum].sectnum, sintable[(*shootAng + 512) & 2047],
sintable[*shootAng & 2047], *zvel << 6, &hitData, CLIPMASK1); sintable[*shootAng & 2047], *zvel << 6, &hitData, CLIPMASK1);
@ -503,7 +503,7 @@ static void P_PreFireHitscan(int spriteNum, int playerNum, int projecTile, vec3_
if (aimSprite == -1) // no target if (aimSprite == -1) // no target
{ {
notarget: notarget:
*zvel = (100-pPlayer->horiz-pPlayer->horizoff)<<5; *zvel = fix16_to_int(F16(100)-pPlayer->qhoriz-pPlayer->qhorizoff)<<5;
} }
Proj_MaybeAddSpread(doSpread, zvel, shootAng, zRange, angRange); Proj_MaybeAddSpread(doSpread, zvel, shootAng, zRange, angRange);
@ -917,7 +917,7 @@ static int A_ShootCustom(int const spriteNum, int const projecTile, int shootAng
otherSprite = GetAutoAimAng(spriteNum, playerNum, projecTile, 8<<8, 0+2, startPos, pProj->vel, &zvel, &shootAng); otherSprite = GetAutoAimAng(spriteNum, playerNum, projecTile, 8<<8, 0+2, startPos, pProj->vel, &zvel, &shootAng);
if (otherSprite < 0) if (otherSprite < 0)
zvel = (100-pPlayer->horiz-pPlayer->horizoff)*(pProj->vel/8); zvel = fix16_to_int(F16(100)-pPlayer->qhoriz-pPlayer->qhorizoff)*(pProj->vel/8);
if (pProj->sound >= 0) if (pProj->sound >= 0)
A_PlaySound(pProj->sound, spriteNum); A_PlaySound(pProj->sound, spriteNum);
@ -976,7 +976,7 @@ static int A_ShootCustom(int const spriteNum, int const projecTile, int shootAng
case PROJECTILE_KNEE: case PROJECTILE_KNEE:
if (playerNum >= 0) if (playerNum >= 0)
{ {
zvel = (100 - pPlayer->horiz - pPlayer->horizoff) << 5; zvel = fix16_to_int(F16(100) - pPlayer->qhoriz - pPlayer->qhorizoff) << 5;
startPos->z += (6 << 8); startPos->z += (6 << 8);
shootAng += 15; shootAng += 15;
} }
@ -1095,7 +1095,7 @@ static int32_t A_ShootHardcoded(int spriteNum, int projecTile, int shootAng, vec
{ {
if (playerNum >= 0) if (playerNum >= 0)
{ {
Zvel = (100 - pPlayer->horiz - pPlayer->horizoff) << 5; Zvel = fix16_to_int(F16(100) - pPlayer->qhoriz - pPlayer->qhorizoff) << 5;
startPos.z += (6 << 8); startPos.z += (6 << 8);
shootAng += 15; shootAng += 15;
} }
@ -1239,7 +1239,7 @@ static int32_t A_ShootHardcoded(int spriteNum, int projecTile, int shootAng, vec
if (playerNum >= 0) if (playerNum >= 0)
{ {
if (GetAutoAimAng(spriteNum, playerNum, projecTile, -ZOFFSET4, 0, &startPos, vel, &Zvel, &shootAng) < 0) if (GetAutoAimAng(spriteNum, playerNum, projecTile, -ZOFFSET4, 0, &startPos, vel, &Zvel, &shootAng) < 0)
Zvel = (100 - pPlayer->horiz - pPlayer->horizoff) * 98; Zvel = fix16_to_int(F16(100) - pPlayer->qhoriz - pPlayer->qhorizoff) * 98;
} }
else else
{ {
@ -1306,7 +1306,7 @@ static int32_t A_ShootHardcoded(int spriteNum, int projecTile, int shootAng, vec
j = GetAutoAimAng(spriteNum, playerNum, projecTile, 8 << 8, 0 + 2, &startPos, vel, &Zvel, &shootAng); j = GetAutoAimAng(spriteNum, playerNum, projecTile, 8 << 8, 0 + 2, &startPos, vel, &Zvel, &shootAng);
if (j < 0) if (j < 0)
Zvel = (100 - pPlayer->horiz - pPlayer->horizoff) * 81; Zvel = fix16_to_int(F16(100) - pPlayer->qhoriz - pPlayer->qhorizoff) * 81;
if (projecTile == RPG) if (projecTile == RPG)
A_PlaySound(RPG_SHOOT, spriteNum); A_PlaySound(RPG_SHOOT, spriteNum);
@ -1413,7 +1413,7 @@ static int32_t A_ShootHardcoded(int spriteNum, int projecTile, int shootAng, vec
case HANDHOLDINGLASER__STATIC: case HANDHOLDINGLASER__STATIC:
{ {
int const zOffset = (playerNum >= 0) ? g_player[playerNum].ps->pyoff : 0; int const zOffset = (playerNum >= 0) ? g_player[playerNum].ps->pyoff : 0;
Zvel = (playerNum >= 0) ? (100 - pPlayer->horiz - pPlayer->horizoff) * 32 : 0; Zvel = (playerNum >= 0) ? fix16_to_int(F16(100) - pPlayer->qhoriz - pPlayer->qhorizoff) * 32 : 0;
startPos.z -= zOffset; startPos.z -= zOffset;
Proj_DoHitscan(spriteNum, 0, &startPos, Zvel, shootAng, &hitData); Proj_DoHitscan(spriteNum, 0, &startPos, Zvel, shootAng, &hitData);
@ -1513,7 +1513,7 @@ static int32_t A_ShootHardcoded(int spriteNum, int projecTile, int shootAng, vec
if (playerNum >= 0) if (playerNum >= 0)
{ {
if (GetAutoAimAng(spriteNum, playerNum, projecTile, ZOFFSET6, 0, &startPos, 768, &Zvel, &shootAng) < 0) if (GetAutoAimAng(spriteNum, playerNum, projecTile, ZOFFSET6, 0, &startPos, 768, &Zvel, &shootAng) < 0)
Zvel = (100 - pPlayer->horiz - pPlayer->horizoff) * 98; Zvel = fix16_to_int(F16(100) - pPlayer->qhoriz - pPlayer->qhorizoff) * 98;
} }
else if (pSprite->statnum != STAT_EFFECTOR) else if (pSprite->statnum != STAT_EFFECTOR)
{ {
@ -1831,7 +1831,7 @@ static int P_DisplayKnee(int kneeShade)
kneePal = ps->palookup; kneePal = ps->palookup;
G_DrawTileScaled(105+(g_player[screenpeek].inputBits->avel>>5)-(ps->look_ang>>1)+(knee_y[ps->knee_incs]>>2), G_DrawTileScaled(105+(g_player[screenpeek].inputBits->avel>>5)-(ps->look_ang>>1)+(knee_y[ps->knee_incs]>>2),
kneeY+280-((ps->horiz-ps->horizoff)>>4),KNEE,kneeShade,4+DRAWEAP_CENTER,kneePal); kneeY+280-(fix16_to_int(ps->qhoriz-ps->qhorizoff)>>4),KNEE,kneeShade,4+DRAWEAP_CENTER,kneePal);
return 1; return 1;
} }
@ -1861,7 +1861,7 @@ static int P_DisplayKnuckles(int knuckleShade)
int const knucklePal = P_GetHudPal(pPlayer); int const knucklePal = P_GetHudPal(pPlayer);
G_DrawTileScaled(160 + (g_player[screenpeek].inputBits->avel >> 5) - (pPlayer->look_ang >> 1), G_DrawTileScaled(160 + (g_player[screenpeek].inputBits->avel >> 5) - (pPlayer->look_ang >> 1),
knuckleY + 180 - ((pPlayer->horiz - pPlayer->horizoff) >> 4), knuckleY + 180 - (fix16_to_int(pPlayer->qhoriz - pPlayer->qhorizoff) >> 4),
CRACKKNUCKLES + knuckleFrames[pPlayer->knuckle_incs >> 1], knuckleShade, 4 + DRAWEAP_CENTER, CRACKKNUCKLES + knuckleFrames[pPlayer->knuckle_incs >> 1], knuckleShade, 4 + DRAWEAP_CENTER,
knucklePal); knucklePal);
@ -2016,7 +2016,7 @@ static int P_DisplayTip(int tipShade)
guniqhudid = 201; guniqhudid = 201;
G_DrawTileScaled(170 + (g_player[screenpeek].inputBits->avel >> 5) - (pPlayer->look_ang >> 1), G_DrawTileScaled(170 + (g_player[screenpeek].inputBits->avel >> 5) - (pPlayer->look_ang >> 1),
tipYOffset + tipY + 240 - ((pPlayer->horiz - pPlayer->horizoff) >> 4), tipYOffset + tipY + 240 - (fix16_to_int(pPlayer->qhoriz - pPlayer->qhorizoff) >> 4),
TIP + ((26 - pPlayer->tipincs) >> 4), tipShade, DRAWEAP_CENTER, tipPal); TIP + ((26 - pPlayer->tipincs) >> 4), tipShade, DRAWEAP_CENTER, tipPal);
guniqhudid = 0; guniqhudid = 0;
@ -2049,13 +2049,13 @@ static int P_DisplayAccess(int accessShade)
if ((pSprite->access_incs - 3) > 0 && (pSprite->access_incs - 3) >> 3) if ((pSprite->access_incs - 3) > 0 && (pSprite->access_incs - 3) >> 3)
{ {
G_DrawTileScaled(170 + (g_player[screenpeek].inputBits->avel >> 5) - (pSprite->look_ang >> 1) + accessX, G_DrawTileScaled(170 + (g_player[screenpeek].inputBits->avel >> 5) - (pSprite->look_ang >> 1) + accessX,
accessY + 266 - ((pSprite->horiz - pSprite->horizoff) >> 4), accessY + 266 - (fix16_to_int(pSprite->qhoriz - pSprite->qhorizoff) >> 4),
HANDHOLDINGLASER + (pSprite->access_incs >> 3), accessShade, DRAWEAP_CENTER, accessPal); HANDHOLDINGLASER + (pSprite->access_incs >> 3), accessShade, DRAWEAP_CENTER, accessPal);
} }
else else
{ {
G_DrawTileScaled(170 + (g_player[screenpeek].inputBits->avel >> 5) - (pSprite->look_ang >> 1) + accessX, G_DrawTileScaled(170 + (g_player[screenpeek].inputBits->avel >> 5) - (pSprite->look_ang >> 1) + accessX,
accessY + 266 - ((pSprite->horiz - pSprite->horizoff) >> 4), HANDHOLDINGACCESS, accessShade, accessY + 266 - (fix16_to_int(pSprite->qhoriz - pSprite->qhorizoff) >> 4), HANDHOLDINGACCESS, accessShade,
4 + DRAWEAP_CENTER, accessPal); 4 + DRAWEAP_CENTER, accessPal);
} }
@ -2886,7 +2886,7 @@ void P_GetInput(int playerNum)
// JBF: Run key behaviour is selectable // JBF: Run key behaviour is selectable
int const playerRunning = (ud.runkey_mode) ? (BUTTON(gamefunc_Run) | ud.auto_run) : (ud.auto_run ^ BUTTON(gamefunc_Run)); int const playerRunning = (ud.runkey_mode) ? (BUTTON(gamefunc_Run) | ud.auto_run) : (ud.auto_run ^ BUTTON(gamefunc_Run));
staticInput.svel = staticInput.fvel = staticInput.avel = staticInput.horz = 0; staticInput.svel = staticInput.fvel = staticInput.avel = staticInput.qhorz = 0;
if (BUTTON(gamefunc_Strafe)) if (BUTTON(gamefunc_Strafe))
{ {
@ -2900,9 +2900,10 @@ void P_GetInput(int playerNum)
info[1].dyaw = (info[1].dyaw + info[0].dyaw) % 32; info[1].dyaw = (info[1].dyaw + info[0].dyaw) % 32;
} }
staticInput.horz = (ud.mouseflip) ? -(info[0].dpitch + info[1].dpitch) / (314 - 128) : (info[0].dpitch + info[1].dpitch) / (314 - 128); staticInput.qhorz = fix16_div(fix16_from_int(info[0].dpitch), F16(512));
if (ud.mouseflip) staticInput.qhorz = -staticInput.qhorz;
info[1].dpitch = (info[1].dpitch + info[0].dpitch) % (314 - 128);
staticInput.svel -= info[0].dx; staticInput.svel -= info[0].dx;
info[1].dz = info[0].dz % (1 << 6); info[1].dz = info[0].dz % (1 << 6);
staticInput.fvel = -info[0].dz >> 6; staticInput.fvel = -info[0].dz >> 6;
@ -2950,7 +2951,7 @@ void P_GetInput(int playerNum)
staticInput.fvel = clamp(staticInput.fvel, -MAXVEL, MAXVEL); staticInput.fvel = clamp(staticInput.fvel, -MAXVEL, MAXVEL);
staticInput.svel = clamp(staticInput.svel, -MAXSVEL, MAXSVEL); staticInput.svel = clamp(staticInput.svel, -MAXSVEL, MAXSVEL);
staticInput.avel = clamp(staticInput.avel, -MAXANGVEL, MAXANGVEL); staticInput.avel = clamp(staticInput.avel, -MAXANGVEL, MAXANGVEL);
staticInput.horz = clamp(staticInput.horz, -MAXHORIZ, MAXHORIZ); staticInput.qhorz = fix16_clamp(staticInput.qhorz, F16(-MAXHORIZ), F16(MAXHORIZ));
int weaponSelection; int weaponSelection;
@ -3050,7 +3051,7 @@ void P_GetInput(int playerNum)
localInput.fvel = 0; localInput.fvel = 0;
localInput.svel = 0; localInput.svel = 0;
localInput.avel = 0; localInput.avel = 0;
localInput.horz = 0; localInput.qhorz = 0;
return; return;
} }
@ -3063,7 +3064,7 @@ void P_GetInput(int playerNum)
pPlayer->fric.y; pPlayer->fric.y;
localInput.avel = staticInput.avel; localInput.avel = staticInput.avel;
localInput.horz = staticInput.horz; localInput.qhorz = staticInput.qhorz;
} }
static int32_t P_DoCounters(int playerNum) static int32_t P_DoCounters(int playerNum)
@ -3917,7 +3918,7 @@ static void P_ProcessWeapon(int playerNum)
hitdata_t hitData; hitdata_t hitData;
hitscan((const vec3_t *)pPlayer, pPlayer->cursectnum, sintable[(pPlayer->ang + 512) & 2047], hitscan((const vec3_t *)pPlayer, pPlayer->cursectnum, sintable[(pPlayer->ang + 512) & 2047],
sintable[pPlayer->ang & 2047], (100 - pPlayer->horiz - pPlayer->horizoff) * 32, &hitData, sintable[pPlayer->ang & 2047], fix16_to_int(F16(100) - pPlayer->qhoriz - pPlayer->qhorizoff) * 32, &hitData,
CLIPMASK1); CLIPMASK1);
if ((hitData.sect < 0 || hitData.sprite >= 0) || if ((hitData.sect < 0 || hitData.sprite >= 0) ||
@ -4015,12 +4016,12 @@ static void P_ProcessWeapon(int playerNum)
if (pPlayer->on_ground && TEST_SYNC_KEY(playerBits, SK_CROUCH)) if (pPlayer->on_ground && TEST_SYNC_KEY(playerBits, SK_CROUCH))
{ {
pipeBombFwdVel = 15; pipeBombFwdVel = 15;
pipeBombZvel = ((pPlayer->horiz + pPlayer->horizoff - 100) * 20); pipeBombZvel = (fix16_to_int(pPlayer->qhoriz + pPlayer->qhorizoff - F16(100)) * 20);
} }
else else
{ {
pipeBombFwdVel = 140; pipeBombFwdVel = 140;
pipeBombZvel = -512 - ((pPlayer->horiz + pPlayer->horizoff - 100) * 20); pipeBombZvel = -512 - (fix16_to_int(pPlayer->qhoriz + pPlayer->qhorizoff - F16(100)) * 20);
} }
int pipeSpriteNum = A_InsertSprite(pPlayer->cursectnum, int pipeSpriteNum = A_InsertSprite(pPlayer->cursectnum,
@ -4513,8 +4514,8 @@ static void P_Dead(int const playerNum, int const sectorLotag, int const floorZ,
pPlayer->oang = pPlayer->ang; pPlayer->oang = pPlayer->ang;
pPlayer->opyoff = pPlayer->pyoff; pPlayer->opyoff = pPlayer->pyoff;
pPlayer->horiz = 100; pPlayer->qhoriz = F16(100);
pPlayer->horizoff = 0; pPlayer->qhorizoff = 0;
updatesector(pPlayer->pos.x, pPlayer->pos.y, &pPlayer->cursectnum); updatesector(pPlayer->pos.x, pPlayer->pos.y, &pPlayer->cursectnum);
@ -4605,8 +4606,8 @@ void P_ProcessInput(int playerNum)
actor[pPlayer->i].floorz = floorZ; actor[pPlayer->i].floorz = floorZ;
actor[pPlayer->i].ceilingz = ceilZ; actor[pPlayer->i].ceilingz = ceilZ;
pPlayer->ohoriz = pPlayer->horiz; pPlayer->oqhoriz = pPlayer->qhoriz;
pPlayer->ohorizoff = pPlayer->horizoff; pPlayer->oqhorizoff = pPlayer->qhorizoff;
// calculates automatic view angle for playing without a mouse // calculates automatic view angle for playing without a mouse
if (pPlayer->aim_mode == 0 && pPlayer->on_ground && sectorLotag != ST_2_UNDERWATER if (pPlayer->aim_mode == 0 && pPlayer->on_ground && sectorLotag != ST_2_UNDERWATER
@ -4623,14 +4624,14 @@ void P_ProcessInput(int playerNum)
int const slopeZ = getflorzofslope(pPlayer->cursectnum, adjustedPlayer.x, adjustedPlayer.y); int const slopeZ = getflorzofslope(pPlayer->cursectnum, adjustedPlayer.x, adjustedPlayer.y);
if ((pPlayer->cursectnum == curSectNum) || if ((pPlayer->cursectnum == curSectNum) ||
(klabs(getflorzofslope(curSectNum, adjustedPlayer.x, adjustedPlayer.y) - slopeZ) <= ZOFFSET6)) (klabs(getflorzofslope(curSectNum, adjustedPlayer.x, adjustedPlayer.y) - slopeZ) <= ZOFFSET6))
pPlayer->horizoff += mulscale16(trueFloorZ - slopeZ, 160); pPlayer->qhorizoff += fix16_from_int(mulscale16(trueFloorZ - slopeZ, 160));
} }
} }
if (pPlayer->horizoff > 0) if (pPlayer->qhorizoff > 0)
pPlayer->horizoff -= ((pPlayer->horizoff >> 3) + 1); pPlayer->qhorizoff -= ((pPlayer->qhorizoff >> 3) + fix16_one);
else if (pPlayer->horizoff < 0) else if (pPlayer->qhorizoff < 0)
pPlayer->horizoff += (((-pPlayer->horizoff) >> 3) + 1); pPlayer->qhorizoff += (((-pPlayer->qhorizoff) >> 3) + fix16_one);
if (highZhit >= 0 && (highZhit&49152) == 49152) if (highZhit >= 0 && (highZhit&49152) == 49152)
{ {
@ -5317,7 +5318,7 @@ HORIZONLY:;
if (VM_OnEvent(EVENT_LOOKUP,pPlayer->i,playerNum) == 0) if (VM_OnEvent(EVENT_LOOKUP,pPlayer->i,playerNum) == 0)
{ {
pPlayer->return_to_center = 9; pPlayer->return_to_center = 9;
pPlayer->horiz += 12<<(int)(TEST_SYNC_KEY(playerBits, SK_RUN)); pPlayer->qhoriz += fix16_from_int(12<<(int)(TEST_SYNC_KEY(playerBits, SK_RUN)));
centerHoriz++; centerHoriz++;
} }
} }
@ -5327,7 +5328,7 @@ HORIZONLY:;
if (VM_OnEvent(EVENT_LOOKDOWN,pPlayer->i,playerNum) == 0) if (VM_OnEvent(EVENT_LOOKDOWN,pPlayer->i,playerNum) == 0)
{ {
pPlayer->return_to_center = 9; pPlayer->return_to_center = 9;
pPlayer->horiz -= 12<<(int)(TEST_SYNC_KEY(playerBits, SK_RUN)); pPlayer->qhoriz -= fix16_from_int(12<<(int)(TEST_SYNC_KEY(playerBits, SK_RUN)));
centerHoriz++; centerHoriz++;
} }
} }
@ -5336,7 +5337,7 @@ HORIZONLY:;
{ {
if (VM_OnEvent(EVENT_AIMUP,pPlayer->i,playerNum) == 0) if (VM_OnEvent(EVENT_AIMUP,pPlayer->i,playerNum) == 0)
{ {
pPlayer->horiz += 6<<(int)(TEST_SYNC_KEY(playerBits, SK_RUN)); pPlayer->qhoriz += fix16_from_int(6<<(int)(TEST_SYNC_KEY(playerBits, SK_RUN)));
centerHoriz++; centerHoriz++;
} }
} }
@ -5345,7 +5346,7 @@ HORIZONLY:;
{ {
if (VM_OnEvent(EVENT_AIMDOWN,pPlayer->i,playerNum) == 0) if (VM_OnEvent(EVENT_AIMDOWN,pPlayer->i,playerNum) == 0)
{ {
pPlayer->horiz -= 6<<(int)(TEST_SYNC_KEY(playerBits, SK_RUN)); pPlayer->qhoriz -= fix16_from_int(6<<(int)(TEST_SYNC_KEY(playerBits, SK_RUN)));
centerHoriz++; centerHoriz++;
} }
} }
@ -5353,23 +5354,23 @@ HORIZONLY:;
if (pPlayer->return_to_center > 0 && !TEST_SYNC_KEY(playerBits, SK_LOOK_UP) && !TEST_SYNC_KEY(playerBits, SK_LOOK_DOWN)) if (pPlayer->return_to_center > 0 && !TEST_SYNC_KEY(playerBits, SK_LOOK_UP) && !TEST_SYNC_KEY(playerBits, SK_LOOK_DOWN))
{ {
pPlayer->return_to_center--; pPlayer->return_to_center--;
pPlayer->horiz += 33-(pPlayer->horiz/3); pPlayer->qhoriz += F16(33)-fix16_div(pPlayer->qhoriz, F16(3));
centerHoriz++; centerHoriz++;
} }
if (pPlayer->hard_landing > 0) if (pPlayer->hard_landing > 0)
{ {
pPlayer->hard_landing--; pPlayer->hard_landing--;
pPlayer->horiz -= (pPlayer->hard_landing<<4); pPlayer->qhoriz -= fix16_from_int(pPlayer->hard_landing<<4);
} }
if (centerHoriz) if (centerHoriz)
{ {
if (pPlayer->horiz > 95 && pPlayer->horiz < 105) pPlayer->horiz = 100; if (pPlayer->qhoriz > F16(95) && pPlayer->qhoriz < F16(105)) pPlayer->qhoriz = F16(100);
if (pPlayer->horizoff > -5 && pPlayer->horizoff < 5) pPlayer->horizoff = 0; if (pPlayer->qhorizoff > F16(-5) && pPlayer->qhorizoff < F16(5)) pPlayer->qhorizoff = 0;
} }
pPlayer->horiz = clamp(pPlayer->horiz + g_player[playerNum].inputBits->horz, HORIZ_MIN, HORIZ_MAX); pPlayer->qhoriz = fix16_clamp(pPlayer->qhoriz + g_player[playerNum].inputBits->qhorz, F16(HORIZ_MIN), F16(HORIZ_MAX));
//Shooting code/changes //Shooting code/changes
@ -5391,7 +5392,7 @@ HORIZONLY:;
if (pPlayer->knee_incs > 0) if (pPlayer->knee_incs > 0)
{ {
pPlayer->horiz -= 48; pPlayer->qhoriz -= F16(48);
pPlayer->return_to_center = 9; pPlayer->return_to_center = 9;
if (++pPlayer->knee_incs > 15) if (++pPlayer->knee_incs > 15)

View file

@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define player_h_ #define player_h_
#include "inv.h" #include "inv.h"
#include "fix16.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -119,7 +120,8 @@ typedef struct {
typedef struct { typedef struct {
uint32_t bits; uint32_t bits;
int16_t fvel, svel, avel; int16_t fvel, svel, avel;
int8_t horz, extbits; fix16_t qhorz;
int8_t extbits;
} input_t; } input_t;
#pragma pack(push,1) #pragma pack(push,1)
@ -155,7 +157,7 @@ typedef struct {
int16_t max_ammo_amount[MAX_WEAPONS], ammo_amount[MAX_WEAPONS], inv_amount[GET_MAX]; int16_t max_ammo_amount[MAX_WEAPONS], ammo_amount[MAX_WEAPONS], inv_amount[GET_MAX];
int16_t wackedbyactor, pyoff, opyoff; int16_t wackedbyactor, pyoff, opyoff;
int16_t horiz, horizoff, ohoriz, ohorizoff; fix16_t qhoriz, qhorizoff, oqhoriz, oqhorizoff;
int16_t newowner, jumping_counter, airleft; int16_t newowner, jumping_counter, airleft;
int16_t fta, ftq, access_wallnum, access_spritenum; int16_t fta, ftq, access_wallnum, access_spritenum;
int16_t got_access, weapon_ang, visibility; int16_t got_access, weapon_ang, visibility;

View file

@ -712,10 +712,10 @@ void P_ResetPlayer(int playerNum)
pPlayer->last_extra = pSprite->extra = pPlayer->max_player_health; pPlayer->last_extra = pSprite->extra = pPlayer->max_player_health;
pPlayer->wantweaponfire = -1; pPlayer->wantweaponfire = -1;
pPlayer->horiz = 100; pPlayer->qhoriz = F16(100);
pPlayer->on_crane = -1; pPlayer->on_crane = -1;
pPlayer->frag_ps = playerNum; pPlayer->frag_ps = playerNum;
pPlayer->horizoff = 0; pPlayer->qhorizoff = 0;
pPlayer->opyoff = 0; pPlayer->opyoff = 0;
pPlayer->wackedbyactor = -1; pPlayer->wackedbyactor = -1;
pPlayer->inv_amount[GET_SHIELD] = g_startArmorAmount; pPlayer->inv_amount[GET_SHIELD] = g_startArmorAmount;
@ -790,9 +790,9 @@ void P_ResetStatus(int playerNum)
pPlayer->footprintpal = 0; pPlayer->footprintpal = 0;
pPlayer->footprintshade = 0; pPlayer->footprintshade = 0;
pPlayer->jumping_toggle = 0; pPlayer->jumping_toggle = 0;
pPlayer->ohoriz = 140; pPlayer->oqhoriz = F16(140);
pPlayer->horiz = 140; pPlayer->qhoriz = F16(140);
pPlayer->horizoff = 0; pPlayer->qhorizoff = 0;
pPlayer->bobcounter = 0; pPlayer->bobcounter = 0;
pPlayer->on_ground = 0; pPlayer->on_ground = 0;
pPlayer->player_par = 0; pPlayer->player_par = 0;

View file

@ -639,7 +639,10 @@ static void G_PrintCoords(int32_t snum)
} }
Bsprintf(tempbuf, "XYZ= (%d, %d, %d)", ps->pos.x, ps->pos.y, ps->pos.z); Bsprintf(tempbuf, "XYZ= (%d, %d, %d)", ps->pos.x, ps->pos.y, ps->pos.z);
printext256(x, y, COLOR_WHITE, -1, tempbuf, 0); printext256(x, y, COLOR_WHITE, -1, tempbuf, 0);
Bsprintf(tempbuf, "A/H/HO= %d, %d, %d", ps->ang, ps->horiz, ps->horizoff); char horiz[16], horizoff[16];
fix16_to_str(ps->qhoriz, horiz, 2);
fix16_to_str(ps->qhorizoff, horizoff, 2);
Bsprintf(tempbuf, "A/H/HO= %d, %s, %s", ps->ang, horiz, horizoff);
printext256(x, y+9, COLOR_WHITE, -1, tempbuf, 0); printext256(x, y+9, COLOR_WHITE, -1, tempbuf, 0);
Bsprintf(tempbuf, "VEL= (%d, %d, %d) + (%d, %d, 0)", Bsprintf(tempbuf, "VEL= (%d, %d, %d) + (%d, %d, 0)",
ps->vel.x>>14, ps->vel.y>>14, ps->vel.z, ps->fric.x>>5, ps->fric.y>>5); ps->vel.x>>14, ps->vel.y>>14, ps->vel.z, ps->fric.x>>5, ps->fric.y>>5);