Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions fix/fix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,24 +69,24 @@
#include "fix.h"

// Tables for trig functions
float sincos_table[321]; // 256 entries + 64 sin-only + 1 for interpolation
scalar sincos_table[321]; // 256 entries + 64 sin-only + 1 for interpolation
angle asin_table[257]; // 1 quadrants worth, +1 for interpolation
angle acos_table[257];

// Generate the data for the trig tables
void InitMathTables() {
int i;
float rad, s, c;
scalar rad, s, c;

for (i = 0; i < 321; i++) {
rad = (float)((double)i / 256.0 * 2 * PI);
rad = (scalar)((double)i / 256.0 * 2 * PI);
sincos_table[i] = std::sin(rad);
}

for (i = 0; i < 256; i++) {

s = std::asin((float)i / 256.0f);
c = std::acos((float)i / 256.0f);
s = std::asin((scalar)i / 256.0f);
c = std::acos((scalar)i / 256.0f);

s = (s / (PI * 2));
c = (c / (PI * 2));
Expand All @@ -100,36 +100,36 @@
}

// Returns the sine of the given angle. Linearly interpolates between two entries in a 256-entry table
float FixSin(angle a) {
scalar FixSin(angle a) {
int i, f;
float s0, s1;
scalar s0, s1;

i = (a >> 8) & 0xff;
f = a & 0xff;

s0 = sincos_table[i];
s1 = sincos_table[i + 1];
return (float)(s0 + ((s1 - s0) * (double)f / 256.0));
return (scalar)(s0 + ((s1 - s0) * (double)f / 256.0));
}

// Returns the cosine of the given angle. Linearly interpolates between two entries in a 256-entry table
float FixCos(angle a) {
scalar FixCos(angle a) {
int i, f;
float c0, c1;
scalar c0, c1;

i = (a >> 8) & 0xff;
f = a & 0xff;

c0 = sincos_table[i + 64];
c1 = sincos_table[i + 64 + 1];
return (float)(c0 + ((c1 - c0) * (double)f / 256.0));
return (scalar)(c0 + ((c1 - c0) * (double)f / 256.0));
}

// Get rid of the "no return value" warnings in the next three functions
#pragma warning(disable : 4035)

Check warning on line 129 in fix/fix.cpp

View workflow job for this annotation

GitHub Actions / Build for PR / macOS, Debug

unknown pragma ignored [-Wunknown-pragmas]

Check warning on line 129 in fix/fix.cpp

View workflow job for this annotation

GitHub Actions / Build for PR / macOS, Debug

unknown pragma ignored [-Wunknown-pragmas]

Check warning on line 129 in fix/fix.cpp

View workflow job for this annotation

GitHub Actions / Build for PR / Linux-x64-clang, Debug

unknown pragma ignored [-Wunknown-pragmas]

// compute inverse sine
angle FixAsin(float v) {
angle FixAsin(scalar v) {
fix vv;
int i, f, aa;

Expand All @@ -151,7 +151,7 @@
}

// compute inverse cosine
angle FixAcos(float v) {
angle FixAcos(scalar v) {
fix vv;
int i, f, aa;

Expand All @@ -177,8 +177,8 @@
// equal the ratio of the actual cos & sin for the result angle, but the parms
// need not be the actual cos & sin.
// NOTE: this is different from the standard C atan2, since it is left-handed.
angle FixAtan2(float cos, float sin) {
float q, m;
angle FixAtan2(scalar cos, scalar sin) {
scalar q, m;
angle t;

// find smaller of two
Expand Down
21 changes: 13 additions & 8 deletions fix/fix.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,17 @@

#include <cmath>
#include <cstdint>
#include <type_traits>

typedef std::make_signed<size_t>::type ssize_t;
// the basic floating-point type
using scalar = float;

// Angles are unsigned shorts
typedef uint16_t angle;
using angle = uint16_t;

// The basic fixed-point type
typedef int32_t fix;
using fix = int32_t;

#define PI 3.141592654f
#define PIOVER2 1.570796327 // DAJ
Expand All @@ -84,10 +89,10 @@ typedef int32_t fix;
void InitMathTables();

// Returns the sine of the given angle. Linearly interpolates between two entries in a 256-entry table
float FixSin(angle a);
scalar FixSin(angle a);

// Returns the cosine of the given angle. Linearly interpolates between two entries in a 256-entry table
float FixCos(angle a);
scalar FixCos(angle a);

#define Round(x) ((int)(x + 0.5))

Expand All @@ -96,11 +101,11 @@ float FixCos(angle a);
#define FloatToFix(num) ((fix)((num) * FLOAT_SCALER))
#define IntToFix(num) ((num) << FIX_SHIFT)
#define ShortToFix(num) (((int32_t)(num)) << FIX_SHIFT)
#define FixToFloat(num) (((float)(num)) / FLOAT_SCALER)
#define FixToFloat(num) (((scalar)(num)) / FLOAT_SCALER)
#define FixToInt(num) ((num) >> FIX_SHIFT)

angle FixAtan2(float cos, float sin);
angle FixAsin(float v);
angle FixAcos(float v);
angle FixAtan2(scalar cos, scalar sin);
angle FixAsin(scalar v);
angle FixAcos(scalar v);

#endif
2 changes: 0 additions & 2 deletions lib/vecmat.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,6 @@

#include <cmath>

#include "fix.h"

// All structs, defines and inline functions are located in vecmat_external.h
// vecmat_external.h is where anything that can be used by DLLs should be.
#include "vecmat_external.h"
Expand Down
173 changes: 150 additions & 23 deletions lib/vecmat_external.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,48 +40,176 @@
* $NoKeywords: $
*/

#ifndef VECMAT_EXTERNAL_H
#define VECMAT_EXTERNAL_H
#pragma once

#include <cstdint>

// Angles are unsigned shorts
typedef uint16_t angle; // make sure this matches up with fix.h
#include "fix.h"

struct angvec {
angle p, h, b;
using T = angle;
constexpr static const size_t N = 3;
constexpr static const size_t PITCH = 0;
constexpr static const size_t HEADING = 1;
constexpr static const size_t BANK = 2;
union {
T phb[N];
struct { T p, h, b; };
};
constexpr static inline angvec id(ssize_t i = -1)
{
return angvec{
((i % N) == PITCH) ? (T)1 : (T)0,
((i % N) == HEADING) ? (T)1 : (T)0,
((i % N) == BANK) ? (T)1 : (T)0
};
}
constexpr static inline angvec ne()
{
return angvec{ (T)0, (T)0, (T)0 };
}
};

#define IDENTITY_MATRIX \
{ \
{1.0, 0, 0}, {0, 1.0, 0}, { 0, 0, 1.0 } \
}

struct vector {
float x, y, z;
using T = scalar;
constexpr static const size_t N = 3;
constexpr static const size_t X = 0;
constexpr static const size_t Y = 1;
constexpr static const size_t Z = 2;
union {
T xyz[N];
struct { T x, y, z; };
struct { T r, g, b; };
};
constexpr static inline const vector id(ssize_t i = -1)
{
return vector{
((i % N) == X) ? (T)1 : (T)0,
((i % N) == Y) ? (T)1 : (T)0,
((i % N) == Z) ? (T)1 : (T)0
};
}
constexpr static inline const vector ne()
{
return vector{ (T)0, (T)0, (T)0 };
}
};

using vector_array = vector;

struct alignas(sizeof(scalar) * 4) aligned_vector {
using T = scalar;
constexpr static const size_t N = 3;
constexpr static const size_t X = 0;
constexpr static const size_t Y = 1;
constexpr static const size_t Z = 2;
union {
T xyz[N];
struct { T x, y, z; };
struct { T r, g, b; };
};
constexpr static inline const aligned_vector id(ssize_t i = -1)
{
return aligned_vector{
((i % N) == X) ? (T)1 : (T)0,
((i % N) == Y) ? (T)1 : (T)0,
((i % N) == Z) ? (T)1 : (T)0,
};
}
constexpr static inline const aligned_vector ne()
{
return aligned_vector{ (scalar)0, (scalar)0, (scalar)0 };
}
};

struct vector4 {
float x, y, z, kat_pad;
using aligned_vector_array = aligned_vector;

struct alignas(sizeof(scalar) * 4) vector4 {
using T = scalar;
constexpr static const size_t N = 4;
constexpr static const size_t X = 0;
constexpr static const size_t Y = 1;
constexpr static const size_t Z = 2;
constexpr static const size_t W = 3;
union {
T xyzw[N];
struct { T x, y, z; union { T w; T kat_pad; }; };
struct { union { T r; T l; }; T g, b, a; };
struct { T u,v; union { T u2; T s; }; union { T v2; T t; }; };
};

struct vector_array {
float xyz[3];
constexpr static inline const vector4 id(ssize_t i = -1)
{
return vector4{
((i % N) == X) ? (T)1 : (T)0,
((i % N) == Y) ? (T)1 : (T)0,
((i % N) == Z) ? (T)1 : (T)0,
((i % N) == W) ? (T)1 : (T)0
};
}
constexpr static inline const vector4 ne()
{
return vector4{ (T)0, (T)0, (T)0, (T)0 };
}
};

using vector4_array = vector4;
using aligned_vector4 = vector4;
using aligned_vector4_array = aligned_vector4;

struct matrix {
vector rvec, uvec, fvec;
constexpr static const size_t RIGHT_HAND = 0;
constexpr static const size_t UP = 1;
constexpr static const size_t FORWARD = 2;
union {
struct {
vector rvec;
vector uvec;
vector fvec;
};
scalar a2d[3][3];
scalar a1d[9];
};
constexpr static inline const matrix id()
{
return matrix{ vector::id(0), vector::id(1), vector::id(2) };
}
constexpr static inline const matrix ne()
{
return matrix{ vector::ne(), vector::ne(), vector::ne() };
}
};

struct matrix4 {
vector4 rvec, uvec, fvec;
constexpr matrix IDENTITY_MATRIX = matrix::id();

struct alignas(alignof(vector4) * 4) matrix4 {
constexpr static const size_t RIGHT_HAND = 0;
constexpr static const size_t UP = 1;
constexpr static const size_t FORWARD = 2;
constexpr static const size_t POSITION = 3;
union {
struct {
vector4 rvec;
vector4 uvec;
vector4 fvec;
vector4 pos;
};
scalar a2d[4][4];
scalar a1d[16];
};
constexpr static inline const matrix4 id()
{
return matrix4{ vector4::id(0), vector4::id(1), vector4::id(2), vector4::id(3) };
}
constexpr static inline const matrix4 ne()
{
return matrix4{ vector4::ne(), vector4::ne(), vector4::ne(), vector4::ne() };
}
};

// Zero's out a vector
static inline void vm_MakeZero(vector *v) { v->x = v->y = v->z = 0; }
static inline void vm_MakeZero(vector *v) { *v = vector::ne(); }

// Set an angvec to {0,0,0}
static inline void vm_MakeZero(angvec *a) { a->p = a->h = a->b = 0; }
static inline void vm_MakeZero(angvec *a) { *a = angvec::ne(); }

// Checks for equality
static inline bool operator==(vector a, vector b) {
Expand Down Expand Up @@ -271,4 +399,3 @@ static inline float vm_Dot3Vector(float x, float y, float z, vector *v) { return

#define vm_GetSurfaceNormal vm_GetNormal

#endif
Loading
Loading