Files
st/include/math.hpp
T
Yanis 5ca3eeb61e Sync nitro headers with nitro decomp (#156)
* sync headers with nitro decomp

* fix most build issues

* fix symbols

* fix regressions
2026-10-07 04:12:55 +02:00

538 lines
12 KiB
C++

#pragma once
#include <nitro/math.h>
// some kind of angle conversion? only used for angle values so far
#define MUL_FX32_FX64(a, b) (fx32)(((((a) * (b)) + 0x80000000000LL) >> 32))
#define UNK_FX_OPERATION_1(a) (MUL_FX32_FX64((u64) (a), 0xB60B60B60BLL) >> FX32_SHIFT)
#define MUL_FX32_U(a, b) (fx32)((((u64) (a)) * ((u64) (b)) + 0x800) >> FX32_SHIFT)
#define UNK_FX_OPERATION_2(a) MUL_FX32_U((u64) (a), FX_F32_TO_FX32(1.2f))
#define DEG_TO_ANG(n) ((n) * 0x10000 / 360)
#define DEG_TO_ANG_ALT(n) DEG_TO_ANG((u64) (n))
#define ABS(x) ((x) < 0 ? -(x) : (x))
#define ABS2(x) ((x) >= 0 ? (x) : -(x))
#define CLAMP(x, min, max) ((x) > (max) ? (max) : (x) < (min) ? (min) : (x))
#define CLAMP2(x, min, max) ((x) > (max) ? (max) : (x) >= (min) ? (x) : (min))
#define CLAMP3(x, min, max) ((x) >= (max) ? (max) : (x) <= (min) ? (min) : (x))
#define POW_2(x) (x * x)
static inline const s32 ClampValue(s32 value, const s32 min, const s32 max) {
if (value > max) {
value = max;
} else if (value < min) {
value = min;
}
return value;
}
static inline void ClampValue16(s16 *value, const s32 min, const s32 max) {
if (*value > max) {
*value = max;
} else if (*value < min) {
*value = min;
}
}
// C++ wrapper for VecFx32
struct VecFx32Cpp {
VecFx32 vec;
VecFx32Cpp() {}
VecFx32Cpp(fx32 X, fx32 Y, fx32 Z) {
vec.x = X;
vec.y = Y;
vec.z = Z;
}
};
// C++ wrapper for VecFx16
struct VecFx16Cpp {
VecFx16 vec;
VecFx16Cpp() {}
VecFx16Cpp(fx16 X, fx16 Y, fx16 Z) {
vec.x = X;
vec.y = Y;
vec.z = Z;
}
};
union Vec2p {
struct {
/* 0 */ fx32 x;
/* 4 */ fx32 y;
/* 8 */
};
fx32 coords[2];
};
#define Vec2p_Add(a, b, dst) Vec2_Add(Vec2p, a, b, dst)
#define Vec2p_Sub(a, b, dst) Vec2_Sub(Vec2p, a, b, dst)
#define Vec2p_Set(a, dst) Vec2_Set(Vec2p, a, dst)
#define Vec2p_Clear(dst) Vec2_Clear(fx32, dst)
static inline void Vec2p_Copy(const Vec2p *src, Vec2p *dst) {
#if __MWERKS__
dst->coords = src->coords;
#else
dst->x = src->x;
dst->y = src->y;
#endif
}
#if __MWERKS__
#define Vec2_Set(a, dst) \
{ \
(dst)->coords = (a)->coords; \
} \
((void) 0)
#else
#define Vec2_Set(a, dst) \
{ \
(dst)->x = (a)->x; \
(dst)->y = (a)->y; \
} \
((void) 0)
#endif
#define Vec2_CopyAdd(type, a, b, dst) \
{ \
type temp; \
temp.x = (a)->x + (b)->x; \
temp.y = (a)->y + (b)->y; \
Vec2_Set(&temp, dst); \
} \
((void) 0)
#define Vec2_CopySub(type, a, b, dst) \
{ \
type temp; \
temp.x = (a)->x - (b)->x; \
temp.y = (a)->y - (b)->y; \
Vec2_Set(&temp, dst); \
} \
((void) 0)
extern "C" {
//! TODO: find a way to remove that
typedef union Vec2sC {
struct {
/* 0 */ s16 x;
/* 2 */ s16 y;
/* 4 */
};
s16 coords[2];
} Vec2sC;
}
union Vec2s {
struct {
/* 0 */ s16 x;
/* 2 */ s16 y;
/* 4 */
};
s16 coords[2];
void operator=(const Vec2s &from) {
this->x = from.x;
this->y = from.y;
}
Vec2s() {}
Vec2s(Vec2s *from) {
#if __MWERKS__
this->coords = from->coords;
#else
this->x = from->x;
this->y = from->y;
#endif
}
Vec2s(s16 X, s16 Y) {
x = X;
y = Y;
}
};
#define Vec2s_CopyAdd(a, b, dst) Vec2_CopyAdd(Vec2s, a, b, dst)
#define Vec2s_CopySub(a, b, dst) Vec2_CopySub(Vec2s, a, b, dst)
#define Vec2s_Set(a, dst) Vec2_Set(a, dst)
static inline void Vec2s_Clear(Vec2s *dst) {
Vec2s empty;
empty.x = 0;
empty.y = 0;
#if __MWERKS__
dst->coords = empty.coords;
#else
dst->x = empty.x;
dst->y = empty.y;
#endif
}
static inline void Vec2s_Add(const Vec2s *a, const Vec2s *b, Vec2s *dst) {
s16 x = a->x + b->x;
s16 y = a->y + b->y;
dst->x = x;
dst->y = y;
}
//! TODO: probably fake
static inline void Vec2s_Add2(const Vec2s *a, Vec2s *dst) {
s16 x1, y1, x2, y2;
x1 = a->x;
x2 = dst->x;
y2 = dst->y;
y1 = a->y;
x2 += x1;
dst->x = x2;
dst->y = (s16) dst->y;
dst->y += y1;
}
static inline void Vec2s_Sub(const Vec2s *a, const Vec2s *b, Vec2s *dst) {
s16 x = a->x - b->x;
s16 y = a->y - b->y;
dst->x = x;
dst->y = y;
}
//! TODO: Vec2s_OffsetAdd and Vec2s_OffsetAdd2 are probably fake?
static inline void Vec2s_OffsetAdd(Vec2s *a, Vec2s *b, Vec2s *c, Vec2s *dst) {
s16 y;
s16 x;
y = a->y + b->y;
x = a->x + b->x;
x += c->x;
y += c->y;
dst->x = x;
dst->y = y;
}
static inline void Vec2s_OffsetAdd2(Vec2s *a, Vec2s *b, Vec2s *c, Vec2s *dst) {
s16 y;
s16 x;
y = a->y + b->y;
x = a->x + b->x;
y += c->y;
x += c->x;
dst->x = x;
dst->y = y;
}
static inline void Vec2s_Copy(const Vec2s *a, Vec2s *dst) {
#if __MWERKS__
dst->coords = a->coords;
#else
dst->x = a->x;
dst->y = a->y;
#endif
}
union Vec2us {
struct {
/* 0 */ u16 x;
/* 2 */ u16 y;
/* 4 */
};
u16 coords[2];
void operator=(const Vec2us &from) {
this->x = from.x;
this->y = from.y;
}
Vec2us() {}
Vec2us(u16 X, u16 Y) {
x = X;
y = Y;
}
Vec2us(Vec2us *pFrom) {
x = pFrom->x;
y = pFrom->y;
}
};
#define Vec2us_CopyAdd(a, b, dst) Vec2_CopyAdd(Vec2us, a, b, dst)
#define Vec2us_CopySub(a, b, dst) Vec2_CopySub(Vec2us, a, b, dst)
#define Vec2us_Set(a, dst) Vec2_Set(a, dst)
static inline void Vec2us_Clear(Vec2us *dst) {
Vec2us empty;
empty.x = 0;
empty.y = 0;
#if __MWERKS__
dst->coords = empty.coords;
#else
dst->x = empty.x;
dst->y = empty.y;
#endif
}
static inline void Vec2us_Add(const Vec2us *a, const Vec2us *b, Vec2us *dst) {
u16 x = a->x + b->x;
u16 y = a->y + b->y;
dst->x = x;
dst->y = y;
}
static inline void Vec2us_Sub(const Vec2us *a, const Vec2us *b, Vec2us *dst) {
u16 x = a->x - b->x;
u16 y = a->y - b->y;
dst->x = x;
dst->y = y;
}
static inline void Vec2us_Copy(const Vec2us *a, Vec2us *dst) {
#if __MWERKS__
dst->coords = a->coords;
#else
dst->x = a->x;
dst->y = a->y;
#endif
}
union Vec2bCpp {
struct {
/* 0 */ u8 x;
/* 1 */ u8 y;
/* 2 */
};
u8 coords[2];
u16 data[1];
void operator=(const Vec2bCpp &from) {
this->x = from.x;
this->y = from.y;
}
Vec2bCpp() {}
Vec2bCpp(u8 X, u8 Y) {
x = X;
y = Y;
}
};
#define Vec2b_CopyAdd(a, b, dst) Vec2_CopyAdd(Vec2bCpp, a, b, dst)
#define Vec2b_CopySub(a, b, dst) Vec2_CopySub(Vec2bCpp, a, b, dst)
#define Vec2b_Set(a, dst) Vec2_Set(a, dst)
static inline void Vec2b_Clear(Vec2bCpp *dst) {
Vec2bCpp empty;
empty.x = 0;
empty.y = 0;
#if __MWERKS__
dst->coords = empty.coords;
#else
dst->x = empty.x;
dst->y = empty.y;
#endif
}
static inline void Vec2b_Add(const Vec2bCpp *a, const Vec2bCpp *b, Vec2bCpp *dst) {
u8 x = a->x + b->x;
u8 y = a->y + b->y;
dst->x = x;
dst->y = y;
}
static inline void Vec2b_Sub(const Vec2bCpp *a, const Vec2bCpp *b, Vec2bCpp *dst) {
u8 x = a->x - b->x;
u8 y = a->y - b->y;
dst->x = x;
dst->y = y;
}
static inline void Vec2b_Copy(const Vec2bCpp *a, Vec2bCpp *dst) {
#if __MWERKS__
dst->coords = a->coords;
#else
dst->x = a->x;
dst->y = a->y;
#endif
}
union Vec2pCpp {
struct {
/* 0 */ fx32 x;
/* 4 */ fx32 y;
/* 8 */
};
fx32 coords[2];
void operator=(const Vec2pCpp &from) {
this->x = from.x;
this->y = from.y;
}
Vec2pCpp() {}
Vec2pCpp(fx32 X, fx32 Y) {
x = X;
y = Y;
}
};
#define Vec2pCpp_CopyAdd(a, b, dst) Vec2_CopyAdd(Vec2pCpp, a, b, dst)
#define Vec2pCpp_CopySub(a, b, dst) Vec2_CopySub(Vec2pCpp, a, b, dst)
#define Vec2pCpp_Set(a, dst) Vec2_Set(a, dst)
static inline void Vec2pCpp_Clear(Vec2pCpp *dst) {
Vec2pCpp empty;
empty.x = 0;
empty.y = 0;
#if __MWERKS__
dst->coords = empty.coords;
#else
dst->x = empty.x;
dst->y = empty.y;
#endif
}
static inline void Vec2pCpp_Add(const Vec2pCpp *a, const Vec2pCpp *b, Vec2pCpp *dst) {
fx32 x = a->x + b->x;
fx32 y = a->y + b->y;
dst->x = x;
dst->y = y;
}
static inline void Vec2pCpp_Sub(const Vec2pCpp *a, const Vec2pCpp *b, Vec2pCpp *dst) {
fx32 x = a->x - b->x;
fx32 y = a->y - b->y;
dst->x = x;
dst->y = y;
}
static inline void Vec2pCpp_Copy(const Vec2pCpp *a, Vec2pCpp *dst) {
#if __MWERKS__
dst->coords = a->coords;
#else
dst->x = a->x;
dst->y = a->y;
#endif
}
//! TODO: remove
extern "C" inline Vec2s *Vec2s_New(s16 x, s16 y) {
Vec2s vec;
vec.x = x;
vec.y = y;
return &vec;
}
//! TODO: remove
extern "C" inline Vec2s *Vec2s_GetCopy(Vec2s *src) {
Vec2s vec;
vec.x = src->x;
vec.y = src->y;
return &vec;
}
union Vec2sb {
struct {
/* 0 */ s8 x;
/* 2 */ s8 y;
/* 4 */
};
s8 coords[2];
void operator=(const Vec2sb &from) {
this->x = from.x;
this->y = from.y;
}
Vec2sb() {}
Vec2sb(u8 X, u8 Y) {
x = X;
y = Y;
}
};
union Vec3s {
struct {
/* 0 */ s16 x;
/* 2 */ s16 y;
/* 4 */ s16 z;
/* 6 */
};
s16 coords[3];
void operator=(const Vec3s &from) {
this->x = from.x;
this->y = from.y;
this->z = from.z;
}
Vec3s() {}
Vec3s(Vec3s *from) {
#if __MWERKS__
this->coords = from->coords;
#else
this->x = from->x;
this->y = from->y;
this->z = from->z;
#endif
}
Vec3s(s16 X, s16 Y, s16 Z) {
x = X;
y = Y;
y = Z;
}
};
struct UnkAngleStruct {
union {
u16 angle_u;
s16 angle_s;
};
UnkAngleStruct() {}
UnkAngleStruct(s16 angle) :
angle_s(angle) {}
// clang-format off
UnkAngleStruct& operator+=(const u16 value) { this->angle_u += value; return *this; }
UnkAngleStruct& operator+=(const unsigned int value) { this->angle_u += value; return *this; }
UnkAngleStruct& operator+=(const s16 value) { this->angle_s += value; return *this; }
UnkAngleStruct& operator+=(const int value) { this->angle_s += value; return *this; }
UnkAngleStruct& operator++() { this->angle_s += 1; return *this; }
UnkAngleStruct& operator++(int) { this->angle_s += 1; return *this; }
UnkAngleStruct& operator-=(const u16 value) { this->angle_u -= value; return *this; }
UnkAngleStruct& operator-=(const unsigned int value) { this->angle_u -= value; return *this; }
UnkAngleStruct& operator-=(const s16 value) { this->angle_s -= value; return *this; }
UnkAngleStruct& operator-=(const int value) { this->angle_s -= value; return *this; }
UnkAngleStruct& operator--() { this->angle_s -= 1; return *this; }
UnkAngleStruct& operator--(int) { this->angle_s -= 1; return *this; }
UnkAngleStruct& operator=(const u16 value) { this->angle_u = value; return *this; }
UnkAngleStruct& operator=(const unsigned int value) { this->angle_u += value; return *this; }
UnkAngleStruct& operator=(const s16 value) { this->angle_s = value; return *this; }
UnkAngleStruct& operator=(const int value) { this->angle_s = value; return *this; }
// clang-format on
};