Compare commits

...

2 Commits

Author SHA1 Message Date
5fdb1aa1a4 dqn: Update readme 2023-07-16 17:59:07 +10:00
c3902e3a29 dqn: Move vector math to impl, add new macros 2023-07-16 17:52:18 +10:00
11 changed files with 794 additions and 259 deletions

BIN
dqn.rdbg

Binary file not shown.

View File

@ -24,11 +24,30 @@
#define DQN_COMPILER_GCC
#endif
// Declare struct literals that work in both C and C++ because the syntax is
// different between languages.
#if 0
struct Foo { int a; }
struct Foo foo = DQN_LITERAL(Foo){32}; // Works on both C and C++
#endif
#if defined(__cplusplus)
#define DQN_LITERAL(T) T
#else
#define DQN_LITERAL(T) (T)
#endif
#if defined(__cplusplus)
#define DQN_THREAD_LOCAL thread_local
#else
#define DQN_THREAD_LOCAL _Thread_local
#endif
#if defined(_WIN32)
#define DQN_OS_WIN32
#elif defined(__aarch64__) || defined(_M_ARM64)
#define DQN_OS_ARM64
#else
#elif defined(__linux__)
#define DQN_OS_UNIX
#endif
@ -121,7 +140,6 @@
// NOTE: Preprocessor Token Tricks =================================================================
#define DQN_TOKEN_COMBINE2(x, y) x ## y
#define DQN_TOKEN_COMBINE(x, y) DQN_TOKEN_COMBINE2(x, y)
#define DQN_UNIQUE_NAME(prefix) DQN_TOKEN_COMBINE(prefix, __LINE__)
#define DQN_SWAP(a, b) \
do \
@ -194,19 +212,17 @@
#define DQN_INVALID_CODE_PATH DQN_INVALID_CODE_PATHF("Invalid code path triggered")
// NOTE: Check macro ===============================================================================
// Assert the expression given in debug, whilst in release- assertion is
// removed and the expression is evaluated and returned.
//
// This function provides dual logic which allows handling of the condition
// gracefully in release mode, but asserting in debug mode. This is an internal
// function, prefer the @see DQN_CHECK macros.
//
// Returns true if the expression evaluated to true, false otherwise.
// Check the expression trapping in debug, whilst in release- trapping is
// removed and the expression is evaluated as if it were a normal 'if' branch.
//
// This allows handling of the condition gracefully when compiled out but traps
// to notify the developer in builds when it's compiled in.
#if 0
bool flag = true;
if (!DQN_CHECKF(flag, "Flag was false!")) {
if (DQN_CHECKF(flag, "Flag was false!")) {
// This branch will execute!
} else {
// Prints "Flag was false!"
}
#endif
#define DQN_CHECK(expr) DQN_CHECKF(expr, "")
@ -255,6 +271,7 @@ struct Dqn_DeferHelper
Dqn_Defer<Lambda> operator+(Lambda lambda) { return Dqn_Defer<Lambda>(lambda); };
};
#define DQN_UNIQUE_NAME(prefix) DQN_TOKEN_COMBINE(prefix, __LINE__)
#define DQN_DEFER const auto DQN_UNIQUE_NAME(defer_lambda_) = Dqn_DeferHelper() + [&]()
#define DQN_DEFER_LOOP(begin, end) \

View File

@ -1,36 +1,295 @@
#if !defined(DQN_NO_V2)
// NOTE: [$VEC2] Vector2 ===========================================================================
DQN_API Dqn_V2I Dqn_V2ToV2I(Dqn_V2 a)
DQN_API bool operator!=(Dqn_V2I lhs, Dqn_V2I rhs)
{
Dqn_V2I result = Dqn_V2I(DQN_CAST(int32_t)a.x, DQN_CAST(int32_t)a.y);
bool result = !(lhs == rhs);
return result;
}
DQN_API Dqn_V2 Dqn_V2Min(Dqn_V2 a, Dqn_V2 b)
DQN_API bool operator==(Dqn_V2I lhs, Dqn_V2I rhs)
{
Dqn_V2 result = Dqn_V2(DQN_MIN(a.x, b.x), DQN_MIN(a.y, b.y));
bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y);
return result;
}
DQN_API Dqn_V2 Dqn_V2Max(Dqn_V2 a, Dqn_V2 b)
DQN_API bool operator>=(Dqn_V2I lhs, Dqn_V2I rhs)
{
Dqn_V2 result = Dqn_V2(DQN_MAX(a.x, b.x), DQN_MAX(a.y, b.y));
bool result = (lhs.x >= rhs.x) && (lhs.y >= rhs.y);
return result;
}
DQN_API Dqn_V2 Dqn_V2Abs(Dqn_V2 a)
DQN_API bool operator<=(Dqn_V2I lhs, Dqn_V2I rhs)
{
Dqn_V2 result = Dqn_V2(DQN_ABS(a.x), DQN_ABS(a.y));
bool result = (lhs.x <= rhs.x) && (lhs.y <= rhs.y);
return result;
}
DQN_API Dqn_f32 Dqn_V2Dot(Dqn_V2 a, Dqn_V2 b)
DQN_API bool operator<(Dqn_V2I lhs, Dqn_V2I rhs)
{
bool result = (lhs.x < rhs.x) && (lhs.y < rhs.y);
return result;
}
DQN_API bool operator>(Dqn_V2I lhs, Dqn_V2I rhs)
{
bool result = (lhs.x > rhs.x) && (lhs.y > rhs.y);
return result;
}
DQN_API Dqn_V2I operator-(Dqn_V2I lhs, Dqn_V2I rhs)
{
Dqn_V2I result = Dqn_V2I_InitNx2(lhs.x - rhs.x, lhs.y - rhs.y);
return result;
}
DQN_API Dqn_V2I operator+(Dqn_V2I lhs, Dqn_V2I rhs)
{
Dqn_V2I result = Dqn_V2I_InitNx2(lhs.x + rhs.x, lhs.y + rhs.y);
return result;
}
DQN_API Dqn_V2I operator*(Dqn_V2I lhs, Dqn_V2I rhs)
{
Dqn_V2I result = Dqn_V2I_InitNx2(lhs.x * rhs.x, lhs.y * rhs.y);
return result;
}
DQN_API Dqn_V2I operator*(Dqn_V2I lhs, Dqn_f32 rhs)
{
Dqn_V2I result = Dqn_V2I_InitNx2(lhs.x * rhs, lhs.y * rhs);
return result;
}
DQN_API Dqn_V2I operator*(Dqn_V2I lhs, int32_t rhs)
{
Dqn_V2I result = Dqn_V2I_InitNx2(lhs.x * rhs, lhs.y * rhs);
return result;
}
DQN_API Dqn_V2I operator/(Dqn_V2I lhs, Dqn_V2I rhs)
{
Dqn_V2I result = Dqn_V2I_InitNx2(lhs.x / rhs.x, lhs.y / rhs.y);
return result;
}
DQN_API Dqn_V2I operator/(Dqn_V2I lhs, Dqn_f32 rhs)
{
Dqn_V2I result = Dqn_V2I_InitNx2(lhs.x / rhs, lhs.y / rhs);
return result;
}
DQN_API Dqn_V2I operator/(Dqn_V2I lhs, int32_t rhs)
{
Dqn_V2I result = Dqn_V2I_InitNx2(lhs.x / rhs, lhs.y / rhs);
return result;
}
DQN_API Dqn_V2I &operator*=(Dqn_V2I &lhs, Dqn_V2I rhs)
{
lhs = lhs * rhs;
return lhs;
}
DQN_API Dqn_V2I &operator*=(Dqn_V2I &lhs, Dqn_f32 rhs)
{
lhs = lhs * rhs;
return lhs;
}
DQN_API Dqn_V2I &operator*=(Dqn_V2I &lhs, int32_t rhs)
{
lhs = lhs * rhs;
return lhs;
}
DQN_API Dqn_V2I &operator/=(Dqn_V2I &lhs, Dqn_V2I rhs)
{
lhs = lhs / rhs;
return lhs;
}
DQN_API Dqn_V2I &operator/=(Dqn_V2I &lhs, Dqn_f32 rhs)
{
lhs = lhs / rhs;
return lhs;
}
DQN_API Dqn_V2I &operator/=(Dqn_V2I &lhs, int32_t rhs)
{
lhs = lhs / rhs;
return lhs;
}
DQN_API Dqn_V2I &operator-=(Dqn_V2I &lhs, Dqn_V2I rhs)
{
lhs = lhs - rhs;
return lhs;
}
DQN_API Dqn_V2I &operator+=(Dqn_V2I &lhs, Dqn_V2I rhs)
{
lhs = lhs + rhs;
return lhs;
}
// NOTE: Vector2
DQN_API bool operator!=(Dqn_V2 lhs, Dqn_V2 rhs)
{
bool result = !(lhs == rhs);
return result;
}
DQN_API bool operator==(Dqn_V2 lhs, Dqn_V2 rhs)
{
bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y);
return result;
}
DQN_API bool operator>=(Dqn_V2 lhs, Dqn_V2 rhs)
{
bool result = (lhs.x >= rhs.x) && (lhs.y >= rhs.y);
return result;
}
DQN_API bool operator<=(Dqn_V2 lhs, Dqn_V2 rhs)
{
bool result = (lhs.x <= rhs.x) && (lhs.y <= rhs.y);
return result;
}
DQN_API bool operator<(Dqn_V2 lhs, Dqn_V2 rhs)
{
bool result = (lhs.x < rhs.x) && (lhs.y < rhs.y);
return result;
}
DQN_API bool operator>(Dqn_V2 lhs, Dqn_V2 rhs)
{
bool result = (lhs.x > rhs.x) && (lhs.y > rhs.y);
return result;
}
DQN_API Dqn_V2 operator-(Dqn_V2 lhs, Dqn_V2 rhs)
{
Dqn_V2 result = Dqn_V2_InitNx2(lhs.x - rhs.x, lhs.y - rhs.y);
return result;
}
DQN_API Dqn_V2 operator+(Dqn_V2 lhs, Dqn_V2 rhs)
{
Dqn_V2 result = Dqn_V2_InitNx2(lhs.x + rhs.x, lhs.y + rhs.y);
return result;
}
DQN_API Dqn_V2 operator*(Dqn_V2 lhs, Dqn_V2 rhs)
{
Dqn_V2 result = Dqn_V2_InitNx2(lhs.x * rhs.x, lhs.y * rhs.y);
return result;
}
DQN_API Dqn_V2 operator*(Dqn_V2 lhs, Dqn_f32 rhs)
{
Dqn_V2 result = Dqn_V2_InitNx2(lhs.x * rhs, lhs.y * rhs);
return result;
}
DQN_API Dqn_V2 operator*(Dqn_V2 lhs, int32_t rhs)
{
Dqn_V2 result = Dqn_V2_InitNx2(lhs.x * rhs, lhs.y * rhs);
return result;
}
DQN_API Dqn_V2 operator/(Dqn_V2 lhs, Dqn_V2 rhs)
{
Dqn_V2 result = Dqn_V2_InitNx2(lhs.x / rhs.x, lhs.y / rhs.y);
return result;
}
DQN_API Dqn_V2 operator/(Dqn_V2 lhs, Dqn_f32 rhs)
{
Dqn_V2 result = Dqn_V2_InitNx2(lhs.x / rhs, lhs.y / rhs);
return result;
}
DQN_API Dqn_V2 operator/(Dqn_V2 lhs, int32_t rhs)
{
Dqn_V2 result = Dqn_V2_InitNx2(lhs.x / rhs, lhs.y / rhs);
return result;
}
DQN_API Dqn_V2 &operator*=(Dqn_V2 &lhs, Dqn_V2 rhs)
{
lhs = lhs * rhs;
return lhs;
}
DQN_API Dqn_V2 &operator*=(Dqn_V2 &lhs, Dqn_f32 rhs)
{
lhs = lhs * rhs;
return lhs;
}
DQN_API Dqn_V2 &operator*=(Dqn_V2 &lhs, int32_t rhs)
{
lhs = lhs * rhs;
return lhs;
}
DQN_API Dqn_V2 &operator/=(Dqn_V2 &lhs, Dqn_V2 rhs)
{
lhs = lhs / rhs;
return lhs;
}
DQN_API Dqn_V2 &operator/=(Dqn_V2 &lhs, Dqn_f32 rhs)
{
lhs = lhs / rhs;
return lhs;
}
DQN_API Dqn_V2 &operator/=(Dqn_V2 &lhs, int32_t rhs)
{
lhs = lhs / rhs;
return lhs;
}
DQN_API Dqn_V2 &operator-=(Dqn_V2 &lhs, Dqn_V2 rhs)
{
lhs = lhs - rhs;
return lhs;
}
DQN_API Dqn_V2 &operator+=(Dqn_V2 &lhs, Dqn_V2 rhs)
{
lhs = lhs + rhs;
return lhs;
}
DQN_API Dqn_V2 Dqn_V2_Min(Dqn_V2 a, Dqn_V2 b)
{
Dqn_V2 result = Dqn_V2_InitNx2(DQN_MIN(a.x, b.x), DQN_MIN(a.y, b.y));
return result;
}
DQN_API Dqn_V2 Dqn_V2_Max(Dqn_V2 a, Dqn_V2 b)
{
Dqn_V2 result = Dqn_V2_InitNx2(DQN_MAX(a.x, b.x), DQN_MAX(a.y, b.y));
return result;
}
DQN_API Dqn_V2 Dqn_V2_Abs(Dqn_V2 a)
{
Dqn_V2 result = Dqn_V2_InitNx2(DQN_ABS(a.x), DQN_ABS(a.y));
return result;
}
DQN_API Dqn_f32 Dqn_V2_Dot(Dqn_V2 a, Dqn_V2 b)
{
Dqn_f32 result = (a.x * b.x) + (a.y * b.y);
return result;
}
DQN_API Dqn_f32 Dqn_V2LengthSq(Dqn_V2 a, Dqn_V2 b)
DQN_API Dqn_f32 Dqn_V2_LengthSq(Dqn_V2 a, Dqn_V2 b)
{
Dqn_f32 x_side = b.x - a.x;
Dqn_f32 y_side = b.y - a.y;
@ -38,7 +297,7 @@ DQN_API Dqn_f32 Dqn_V2LengthSq(Dqn_V2 a, Dqn_V2 b)
return result;
}
DQN_API Dqn_V2 Dqn_V2Normalise(Dqn_V2 a)
DQN_API Dqn_V2 Dqn_V2_Normalise(Dqn_V2 a)
{
Dqn_f32 length_sq = DQN_SQUARED(a.x) + DQN_SQUARED(a.y);
Dqn_f32 length = DQN_SQRTF(length_sq);
@ -46,31 +305,163 @@ DQN_API Dqn_V2 Dqn_V2Normalise(Dqn_V2 a)
return result;
}
DQN_API Dqn_V2 Dqn_V2Perpendicular(Dqn_V2 a)
DQN_API Dqn_V2 Dqn_V2_Perpendicular(Dqn_V2 a)
{
Dqn_V2 result = Dqn_V2(-a.y, a.x);
Dqn_V2 result = Dqn_V2_InitNx2(-a.y, a.x);
return result;
}
#endif // !defined(DQN_NO_V2)
#if !defined(DQN_NO_V3)
// NOTE: [$VEC3] Vector3 ===========================================================================
DQN_API Dqn_f32 Dqn_V3LengthSq(Dqn_V3 a)
DQN_API bool operator!=(Dqn_V3 lhs, Dqn_V3 rhs)
{
bool result = !(lhs == rhs);
return result;
}
DQN_API bool operator==(Dqn_V3 lhs, Dqn_V3 rhs)
{
bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y) && (lhs.z == rhs.z);
return result;
}
DQN_API bool operator>=(Dqn_V3 lhs, Dqn_V3 rhs)
{
bool result = (lhs.x >= rhs.x) && (lhs.y >= rhs.y) && (lhs.z >= rhs.z);
return result;
}
DQN_API bool operator<=(Dqn_V3 lhs, Dqn_V3 rhs)
{
bool result = (lhs.x <= rhs.x) && (lhs.y <= rhs.y) && (lhs.z <= rhs.z);
return result;
}
DQN_API bool operator< (Dqn_V3 lhs, Dqn_V3 rhs)
{
bool result = (lhs.x < rhs.x) && (lhs.y < rhs.y) && (lhs.z < rhs.z);
return result;
}
DQN_API bool operator>(Dqn_V3 lhs, Dqn_V3 rhs)
{
bool result = (lhs.x > rhs.x) && (lhs.y > rhs.y) && (lhs.z > rhs.z);
return result;
}
DQN_API Dqn_V3 operator-(Dqn_V3 lhs, Dqn_V3 rhs)
{
Dqn_V3 result = Dqn_V3_InitNx3(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z);
return result;
}
DQN_API Dqn_V3 operator+(Dqn_V3 lhs, Dqn_V3 rhs)
{
Dqn_V3 result = Dqn_V3_InitNx3(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z);
return result;
}
DQN_API Dqn_V3 operator*(Dqn_V3 lhs, Dqn_V3 rhs)
{
Dqn_V3 result = Dqn_V3_InitNx3(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z);
return result;
}
DQN_API Dqn_V3 operator*(Dqn_V3 lhs, Dqn_f32 rhs)
{
Dqn_V3 result = Dqn_V3_InitNx3(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs);
return result;
}
DQN_API Dqn_V3 operator*(Dqn_V3 lhs, int32_t rhs)
{
Dqn_V3 result = Dqn_V3_InitNx3(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs);
return result;
}
DQN_API Dqn_V3 operator/(Dqn_V3 lhs, Dqn_V3 rhs)
{
Dqn_V3 result = Dqn_V3_InitNx3(lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z);
return result;
}
DQN_API Dqn_V3 operator/(Dqn_V3 lhs, Dqn_f32 rhs)
{
Dqn_V3 result = Dqn_V3_InitNx3(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs);
return result;
}
DQN_API Dqn_V3 operator/(Dqn_V3 lhs, int32_t rhs)
{
Dqn_V3 result = Dqn_V3_InitNx3(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs);
return result;
}
DQN_API Dqn_V3 &operator*=(Dqn_V3 &lhs, Dqn_V3 rhs)
{
lhs = lhs * rhs;
return lhs;
}
DQN_API Dqn_V3 &operator*=(Dqn_V3 &lhs, Dqn_f32 rhs)
{
lhs = lhs * rhs;
return lhs;
}
DQN_API Dqn_V3 &operator*=(Dqn_V3 &lhs, int32_t rhs)
{
lhs = lhs * rhs;
return lhs;
}
DQN_API Dqn_V3 &operator/=(Dqn_V3 &lhs, Dqn_V3 rhs)
{
lhs = lhs / rhs;
return lhs;
}
DQN_API Dqn_V3 &operator/=(Dqn_V3 &lhs, Dqn_f32 rhs)
{
lhs = lhs / rhs;
return lhs;
}
DQN_API Dqn_V3 &operator/=(Dqn_V3 &lhs, int32_t rhs)
{
lhs = lhs / rhs;
return lhs;
}
DQN_API Dqn_V3 &operator-=(Dqn_V3 &lhs, Dqn_V3 rhs)
{
lhs = lhs - rhs;
return lhs;
}
DQN_API Dqn_V3 &operator+=(Dqn_V3 &lhs, Dqn_V3 rhs)
{
lhs = lhs + rhs;
return lhs;
}
DQN_API Dqn_f32 Dqn_V3_LengthSq(Dqn_V3 a)
{
Dqn_f32 result = DQN_SQUARED(a.x) + DQN_SQUARED(a.y) + DQN_SQUARED(a.z);
return result;
}
DQN_API Dqn_f32 Dqn_V3Length(Dqn_V3 a)
DQN_API Dqn_f32 Dqn_V3_Length(Dqn_V3 a)
{
Dqn_f32 length_sq = DQN_SQUARED(a.x) + DQN_SQUARED(a.y) + DQN_SQUARED(a.z);
Dqn_f32 result = DQN_SQRTF(length_sq);
return result;
}
DQN_API Dqn_V3 Dqn_V3Normalise(Dqn_V3 a)
DQN_API Dqn_V3 Dqn_V3_Normalise(Dqn_V3 a)
{
Dqn_f32 length = Dqn_V3Length(a);
Dqn_f32 length = Dqn_V3_Length(a);
Dqn_V3 result = a / length;
return result;
}
@ -78,6 +469,108 @@ DQN_API Dqn_V3 Dqn_V3Normalise(Dqn_V3 a)
#if !defined(DQN_NO_V4)
// NOTE: [$VEC4] Vector4 ===========================================================================
DQN_API bool operator!=(Dqn_V4 lhs, Dqn_V4 rhs)
{
bool result = !(lhs == rhs);
return result;
}
DQN_API bool operator==(Dqn_V4 lhs, Dqn_V4 rhs)
{
bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y) && (lhs.z == rhs.z) && (lhs.w == rhs.w);
return result;
}
DQN_API bool operator>=(Dqn_V4 lhs, Dqn_V4 rhs)
{
bool result = (lhs.x >= rhs.x) && (lhs.y >= rhs.y) && (lhs.z >= rhs.z) && (lhs.w >= rhs.w);
return result;
}
DQN_API bool operator<=(Dqn_V4 lhs, Dqn_V4 rhs)
{
bool result = (lhs.x <= rhs.x) && (lhs.y <= rhs.y) && (lhs.z <= rhs.z) && (lhs.w <= rhs.w);
return result;
}
DQN_API bool operator< (Dqn_V4 lhs, Dqn_V4 rhs)
{
bool result = (lhs.x < rhs.x) && (lhs.y < rhs.y) && (lhs.z < rhs.z) && (lhs.w < rhs.w);
return result;
}
DQN_API bool operator>(Dqn_V4 lhs, Dqn_V4 rhs)
{
bool result = (lhs.x > rhs.x) && (lhs.y > rhs.y) && (lhs.z > rhs.z) && (lhs.w > rhs.w);
return result;
}
DQN_API Dqn_V4 operator-(Dqn_V4 lhs, Dqn_V4 rhs)
{
Dqn_V4 result = Dqn_V4_InitNx4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w);
return result;
}
DQN_API Dqn_V4 operator+(Dqn_V4 lhs, Dqn_V4 rhs)
{
Dqn_V4 result = Dqn_V4_InitNx4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w);
return result;
}
DQN_API Dqn_V4 operator* (Dqn_V4 lhs, Dqn_V4 rhs)
{
Dqn_V4 result = Dqn_V4_InitNx4(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w);
return result;
}
DQN_API Dqn_V4 operator*(Dqn_V4 lhs, Dqn_f32 rhs)
{
Dqn_V4 result = Dqn_V4_InitNx4(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs);
return result;
}
DQN_API Dqn_V4 operator*(Dqn_V4 lhs, int32_t rhs)
{
Dqn_V4 result = Dqn_V4_InitNx4(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs);
return result;
}
DQN_API Dqn_V4 operator/(Dqn_V4 lhs, Dqn_f32 rhs)
{
Dqn_V4 result = Dqn_V4_InitNx4(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs, lhs.w / rhs);
return result;
}
DQN_API Dqn_V4 &operator*=(Dqn_V4 &lhs, Dqn_V4 rhs)
{
lhs = lhs * rhs;
return lhs;
}
DQN_API Dqn_V4 &operator*=(Dqn_V4 &lhs, Dqn_f32 rhs)
{
lhs = lhs * rhs;
return lhs;
}
DQN_API Dqn_V4 &operator*=(Dqn_V4 &lhs, int32_t rhs)
{
lhs = lhs * rhs;
return lhs;
}
DQN_API Dqn_V4 &operator-=(Dqn_V4 &lhs, Dqn_V4 rhs)
{
lhs = lhs - rhs;
return lhs;
}
DQN_API Dqn_V4 &operator+=(Dqn_V4 &lhs, Dqn_V4 rhs)
{
lhs = lhs + rhs;
return lhs;
}
DQN_API Dqn_f32 Dqn_V4Dot(Dqn_V4 a, Dqn_V4 b)
{
Dqn_f32 result = (a.x * b.x) + (a.y * b.y) + (a.z * b.z) + (a.w * b.w);
@ -163,9 +656,9 @@ DQN_API Dqn_M4 Dqn_M4_Transpose(Dqn_M4 mat)
DQN_API Dqn_M4 Dqn_M4_Rotate(Dqn_V3 axis01, Dqn_f32 radians)
{
DQN_ASSERTF(DQN_ABS(Dqn_V3Length(axis01) - 1.f) <= 0.01f,
DQN_ASSERTF(DQN_ABS(Dqn_V3_Length(axis01) - 1.f) <= 0.01f,
"Rotation axis must be normalised, length = %f",
Dqn_V3Length(axis01));
Dqn_V3_Length(axis01));
Dqn_f32 sin = DQN_SINF(radians);
Dqn_f32 cos = DQN_COSF(radians);
@ -338,98 +831,80 @@ DQN_API Dqn_FString8<256> Dqn_M4_ColumnMajorString(Dqn_M4 mat)
#if !defined(DQN_NO_RECT)
// NOTE: [$RECT] Dqn_Rect ==========================================================================
DQN_API Dqn_Rect Dqn_Rect_InitFromPosAndSize(Dqn_V2 pos, Dqn_V2 size)
DQN_API bool operator==(const Dqn_Rect& lhs, const Dqn_Rect& rhs)
{
Dqn_Rect result = {};
result.min = pos;
if (size.x < 0) result.min.x -= size.x;
if (size.y < 0) result.min.y -= size.y;
result.max = result.min + Dqn_V2Abs(size);
bool result = (lhs.pos == rhs.pos) && (lhs.size == rhs.size);
return result;
}
DQN_API Dqn_V2 Dqn_Rect_Center(Dqn_Rect rect)
{
Dqn_V2 size = rect.max - rect.min;
Dqn_V2 result = rect.min + (size * 0.5f);
Dqn_V2 result = rect.pos + (rect.size * .5f);
return result;
}
DQN_API bool Dqn_Rect_ContainsPoint(Dqn_Rect rect, Dqn_V2 p)
{
bool result = (p.x >= rect.min.x && p.x <= rect.max.x && p.y >= rect.min.y && p.y <= rect.max.y);
Dqn_V2 min = rect.pos;
Dqn_V2 max = rect.pos + rect.size;
bool result = (p.x >= min.x && p.x <= max.x && p.y >= min.y && p.y <= max.y);
return result;
}
DQN_API bool Dqn_Rect_ContainsRect(Dqn_Rect a, Dqn_Rect b)
{
bool result = (b.min >= a.min && b.max <= a.max);
return result;
}
DQN_API Dqn_V2 Dqn_Rect_Size(Dqn_Rect rect)
{
Dqn_V2 result = rect.max - rect.min;
return result;
}
DQN_API Dqn_Rect Dqn_Rect_Move(Dqn_Rect src, Dqn_V2 move_amount)
{
Dqn_Rect result = src;
result.min += move_amount;
result.max += move_amount;
return result;
}
DQN_API Dqn_Rect Dqn_Rect_MoveTo(Dqn_Rect src, Dqn_V2 dest)
{
Dqn_V2 move_amount = dest - src.min;
Dqn_Rect result = src;
result.min += move_amount;
result.max += move_amount;
Dqn_V2 a_min = a.pos;
Dqn_V2 a_max = a.pos + a.size;
Dqn_V2 b_min = b.pos;
Dqn_V2 b_max = b.pos + b.size;
bool result = (b_min >= a_min && b_max <= a_max);
return result;
}
DQN_API bool Dqn_Rect_Intersects(Dqn_Rect a, Dqn_Rect b)
{
bool result = (a.min.x <= b.max.x && a.max.x >= b.min.x) &&
(a.min.y <= b.max.y && a.max.y >= b.min.y);
Dqn_V2 a_min = a.pos;
Dqn_V2 a_max = a.pos + a.size;
Dqn_V2 b_min = b.pos;
Dqn_V2 b_max = b.pos + b.size;
bool result = (a_min.x <= b_max.x && a_max.x >= b_min.x) &&
(a_min.y <= b_max.y && a_max.y >= b_min.y);
return result;
}
DQN_API Dqn_Rect Dqn_Rect_Intersection(Dqn_Rect a, Dqn_Rect b)
{
Dqn_Rect result = {};
if (Dqn_Rect_Intersects(a, b))
{
result.min.x = DQN_MAX(a.min.x, b.min.x);
result.min.y = DQN_MAX(a.min.y, b.min.y);
result.max.x = DQN_MIN(a.max.x, b.max.x);
result.max.y = DQN_MIN(a.max.y, b.max.y);
}
if (Dqn_Rect_Intersects(a, b)) {
Dqn_V2 a_min = a.pos;
Dqn_V2 a_max = a.pos + a.size;
Dqn_V2 b_min = b.pos;
Dqn_V2 b_max = b.pos + b.size;
Dqn_V2 min = {};
Dqn_V2 max = {};
min.x = DQN_MAX(a_min.x, b_min.x);
min.y = DQN_MAX(a_min.y, b_min.y);
max.x = DQN_MIN(a_max.x, b_max.x);
max.y = DQN_MIN(a_max.y, b_max.y);
result = Dqn_Rect_InitV2x2(min, max - min);
}
return result;
}
DQN_API Dqn_Rect Dqn_Rect_Union(Dqn_Rect a, Dqn_Rect b)
{
Dqn_Rect result = {};
result.min.x = DQN_MIN(a.min.x, b.min.x);
result.min.y = DQN_MIN(a.min.y, b.min.y);
result.max.x = DQN_MAX(a.max.x, b.max.x);
result.max.y = DQN_MAX(a.max.y, b.max.y);
return result;
}
Dqn_V2 a_min = a.pos;
Dqn_V2 a_max = a.pos + a.size;
Dqn_V2 b_min = b.pos;
Dqn_V2 b_max = b.pos + b.size;
DQN_API Dqn_Rect Dqn_Rect_FromRectI32(Dqn_RectI32 a)
{
Dqn_Rect result = Dqn_Rect(a.min, a.max);
return result;
}
DQN_API Dqn_V2I Dqn_RectI32_Size(Dqn_RectI32 rect)
{
Dqn_V2I result = rect.max - rect.min;
Dqn_V2 min, max;
min.x = DQN_MIN(a_min.x, b_min.x);
min.y = DQN_MIN(a_min.y, b_min.y);
max.x = DQN_MAX(a_max.x, b_max.x);
max.y = DQN_MAX(a_max.y, b_max.y);
Dqn_Rect result = Dqn_Rect_InitV2x2(min, max - min);
return result;
}
#endif // !defined(DQN_NO_RECT)

View File

@ -8,124 +8,128 @@
// [$RECT] Dqn_Rect | DQN_NO_RECT |
// [$MATH] Other | |
// =================================================================================================
#if defined(DQN_COMPILER_W32_MSVC)
#pragma warning(push)
#pragma warning(disable: 4201) // warning C4201: nonstandard extension used: nameless struct/union
#endif
#if !defined(DQN_NO_V2)
// NOTE: [$VEC2] Vector2 ===========================================================================
struct Dqn_V2I
union Dqn_V2I
{
int32_t x, y;
Dqn_V2I() = default;
Dqn_V2I(Dqn_f32 x_, Dqn_f32 y_): x((int32_t)x_), y((int32_t)y_) {}
Dqn_V2I(int32_t x_, int32_t y_): x(x_), y(y_) {}
Dqn_V2I(int32_t xy): x(xy), y(xy) {}
bool operator!=(Dqn_V2I other) const { return !(*this == other); }
bool operator==(Dqn_V2I other) const { return (x == other.x) && (y == other.y); }
bool operator>=(Dqn_V2I other) const { return (x >= other.x) && (y >= other.y); }
bool operator<=(Dqn_V2I other) const { return (x <= other.x) && (y <= other.y); }
bool operator< (Dqn_V2I other) const { return (x < other.x) && (y < other.y); }
bool operator> (Dqn_V2I other) const { return (x > other.x) && (y > other.y); }
Dqn_V2I operator- (Dqn_V2I other) const { Dqn_V2I result(x - other.x, y - other.y); return result; }
Dqn_V2I operator+ (Dqn_V2I other) const { Dqn_V2I result(x + other.x, y + other.y); return result; }
Dqn_V2I operator* (Dqn_V2I other) const { Dqn_V2I result(x * other.x, y * other.y); return result; }
Dqn_V2I operator* (Dqn_f32 other) const { Dqn_V2I result(x * other, y * other); return result; }
Dqn_V2I operator* (int32_t other) const { Dqn_V2I result(x * other, y * other); return result; }
Dqn_V2I operator/ (Dqn_V2I other) const { Dqn_V2I result(x / other.x, y / other.y); return result; }
Dqn_V2I operator/ (Dqn_f32 other) const { Dqn_V2I result(x / other, y / other); return result; }
Dqn_V2I operator/ (int32_t other) const { Dqn_V2I result(x / other, y / other); return result; }
Dqn_V2I &operator*=(Dqn_V2I other) { *this = *this * other; return *this; }
Dqn_V2I &operator*=(Dqn_f32 other) { *this = *this * other; return *this; }
Dqn_V2I &operator*=(int32_t other) { *this = *this * other; return *this; }
Dqn_V2I &operator-=(Dqn_V2I other) { *this = *this - other; return *this; }
Dqn_V2I &operator+=(Dqn_V2I other) { *this = *this + other; return *this; }
struct { int32_t x, y; };
struct { int32_t w, h; };
int32_t data[2];
};
struct Dqn_V2
#define Dqn_V2I_InitNx1(x) DQN_LITERAL(Dqn_V2I){(int32_t)(x), (int32_t)(x)}
#define Dqn_V2I_InitNx2(x, y) DQN_LITERAL(Dqn_V2I){(int32_t)(x), (int32_t)(y)}
DQN_API bool operator!=(Dqn_V2I lhs, Dqn_V2I rhs);
DQN_API bool operator==(Dqn_V2I lhs, Dqn_V2I rhs);
DQN_API bool operator>=(Dqn_V2I lhs, Dqn_V2I rhs);
DQN_API bool operator<=(Dqn_V2I lhs, Dqn_V2I rhs);
DQN_API bool operator< (Dqn_V2I lhs, Dqn_V2I rhs);
DQN_API bool operator> (Dqn_V2I lhs, Dqn_V2I rhs);
DQN_API Dqn_V2I operator- (Dqn_V2I lhs, Dqn_V2I rhs);
DQN_API Dqn_V2I operator+ (Dqn_V2I lhs, Dqn_V2I rhs);
DQN_API Dqn_V2I operator* (Dqn_V2I lhs, Dqn_V2I rhs);
DQN_API Dqn_V2I operator* (Dqn_V2I lhs, Dqn_f32 rhs);
DQN_API Dqn_V2I operator* (Dqn_V2I lhs, int32_t rhs);
DQN_API Dqn_V2I operator/ (Dqn_V2I lhs, Dqn_V2I rhs);
DQN_API Dqn_V2I operator/ (Dqn_V2I lhs, Dqn_f32 rhs);
DQN_API Dqn_V2I operator/ (Dqn_V2I lhs, int32_t rhs);
DQN_API Dqn_V2I &operator*=(Dqn_V2I& lhs, Dqn_V2I rhs);
DQN_API Dqn_V2I &operator*=(Dqn_V2I& lhs, Dqn_f32 rhs);
DQN_API Dqn_V2I &operator*=(Dqn_V2I& lhs, int32_t rhs);
DQN_API Dqn_V2I &operator/=(Dqn_V2I& lhs, Dqn_V2I rhs);
DQN_API Dqn_V2I &operator/=(Dqn_V2I& lhs, Dqn_f32 rhs);
DQN_API Dqn_V2I &operator/=(Dqn_V2I& lhs, int32_t rhs);
DQN_API Dqn_V2I &operator-=(Dqn_V2I& lhs, Dqn_V2I rhs);
DQN_API Dqn_V2I &operator+=(Dqn_V2I& lhs, Dqn_V2I rhs);
union Dqn_V2
{
Dqn_f32 x, y;
Dqn_V2() = default;
Dqn_V2(Dqn_f32 a) : x(a), y(a) {}
Dqn_V2(int32_t a) : x((Dqn_f32)a), y((Dqn_f32)a) {}
Dqn_V2(Dqn_f32 x, Dqn_f32 y): x(x), y(y) {}
Dqn_V2(int32_t x, int32_t y): x((Dqn_f32)x), y((Dqn_f32)y) {}
Dqn_V2(Dqn_V2I a) : x((Dqn_f32)a.x),y((Dqn_f32)a.y){}
bool operator!=(Dqn_V2 other) const { return !(*this == other); }
bool operator==(Dqn_V2 other) const { return (x == other.x) && (y == other.y); }
bool operator>=(Dqn_V2 other) const { return (x >= other.x) && (y >= other.y); }
bool operator<=(Dqn_V2 other) const { return (x <= other.x) && (y <= other.y); }
bool operator< (Dqn_V2 other) const { return (x < other.x) && (y < other.y); }
bool operator> (Dqn_V2 other) const { return (x > other.x) && (y > other.y); }
Dqn_V2 operator- (Dqn_V2 other) const { Dqn_V2 result(x - other.x, y - other.y); return result; }
Dqn_V2 operator+ (Dqn_V2 other) const { Dqn_V2 result(x + other.x, y + other.y); return result; }
Dqn_V2 operator* (Dqn_V2 other) const { Dqn_V2 result(x * other.x, y * other.y); return result; }
Dqn_V2 operator* (Dqn_f32 other) const { Dqn_V2 result(x * other, y * other); return result; }
Dqn_V2 operator* (int32_t other) const { Dqn_V2 result(x * other, y * other); return result; }
Dqn_V2 operator/ (Dqn_V2 other) const { Dqn_V2 result(x / other.x, y / other.y); return result; }
Dqn_V2 operator/ (Dqn_f32 other) const { Dqn_V2 result(x / other, y / other); return result; }
Dqn_V2 operator/ (int32_t other) const { Dqn_V2 result(x / other, y / other); return result; }
Dqn_V2 &operator*=(Dqn_V2 other) { *this = *this * other; return *this; }
Dqn_V2 &operator*=(Dqn_f32 other) { *this = *this * other; return *this; }
Dqn_V2 &operator*=(int32_t other) { *this = *this * other; return *this; }
Dqn_V2 &operator/=(Dqn_V2 other) { *this = *this / other; return *this; }
Dqn_V2 &operator/=(Dqn_f32 other) { *this = *this / other; return *this; }
Dqn_V2 &operator/=(int32_t other) { *this = *this / other; return *this; }
Dqn_V2 &operator-=(Dqn_V2 other) { *this = *this - other; return *this; }
Dqn_V2 &operator+=(Dqn_V2 other) { *this = *this + other; return *this; }
struct { Dqn_f32 x, y; };
struct { Dqn_f32 w, h; };
Dqn_f32 data[2];
};
DQN_API Dqn_V2I Dqn_V2ToV2I(Dqn_V2 a);
DQN_API Dqn_V2 Dqn_V2Min(Dqn_V2 a, Dqn_V2 b);
DQN_API Dqn_V2 Dqn_V2Max(Dqn_V2 a, Dqn_V2 b);
DQN_API Dqn_V2 Dqn_V2Abs(Dqn_V2 a);
DQN_API Dqn_f32 Dqn_V2Dot(Dqn_V2 a, Dqn_V2 b);
DQN_API Dqn_f32 Dqn_V2LengthSq(Dqn_V2 a, Dqn_V2 b);
DQN_API Dqn_V2 Dqn_V2Normalise(Dqn_V2 a);
DQN_API Dqn_V2 Dqn_V2Perpendicular(Dqn_V2 a);
#define Dqn_V2_InitNx1(x) DQN_LITERAL(Dqn_V2){(Dqn_f32)(x), (Dqn_f32)(x)}
#define Dqn_V2_InitNx2(x, y) DQN_LITERAL(Dqn_V2){(Dqn_f32)(x), (Dqn_f32)(y)}
DQN_API bool operator!=(Dqn_V2 lhs, Dqn_V2 rhs);
DQN_API bool operator==(Dqn_V2 lhs, Dqn_V2 rhs);
DQN_API bool operator>=(Dqn_V2 lhs, Dqn_V2 rhs);
DQN_API bool operator<=(Dqn_V2 lhs, Dqn_V2 rhs);
DQN_API bool operator< (Dqn_V2 lhs, Dqn_V2 rhs);
DQN_API bool operator> (Dqn_V2 lhs, Dqn_V2 rhs);
DQN_API Dqn_V2 operator- (Dqn_V2 lhs, Dqn_V2 rhs);
DQN_API Dqn_V2 operator+ (Dqn_V2 lhs, Dqn_V2 rhs);
DQN_API Dqn_V2 operator* (Dqn_V2 lhs, Dqn_V2 rhs);
DQN_API Dqn_V2 operator* (Dqn_V2 lhs, Dqn_f32 rhs);
DQN_API Dqn_V2 operator* (Dqn_V2 lhs, int32_t rhs);
DQN_API Dqn_V2 operator/ (Dqn_V2 lhs, Dqn_V2 rhs);
DQN_API Dqn_V2 operator/ (Dqn_V2 lhs, Dqn_f32 rhs);
DQN_API Dqn_V2 operator/ (Dqn_V2 lhs, int32_t rhs);
DQN_API Dqn_V2 &operator*=(Dqn_V2& lhs, Dqn_V2 rhs);
DQN_API Dqn_V2 &operator*=(Dqn_V2& lhs, Dqn_f32 rhs);
DQN_API Dqn_V2 &operator*=(Dqn_V2& lhs, int32_t rhs);
DQN_API Dqn_V2 &operator/=(Dqn_V2& lhs, Dqn_V2 rhs);
DQN_API Dqn_V2 &operator/=(Dqn_V2& lhs, Dqn_f32 rhs);
DQN_API Dqn_V2 &operator/=(Dqn_V2& lhs, int32_t rhs);
DQN_API Dqn_V2 &operator-=(Dqn_V2& lhs, Dqn_V2 rhs);
DQN_API Dqn_V2 &operator+=(Dqn_V2& lhs, Dqn_V2 rhs);
DQN_API Dqn_V2I Dqn_V2_ToV2I(Dqn_V2 a);
DQN_API Dqn_V2 Dqn_V2_Min(Dqn_V2 a, Dqn_V2 b);
DQN_API Dqn_V2 Dqn_V2_Max(Dqn_V2 a, Dqn_V2 b);
DQN_API Dqn_V2 Dqn_V2_Abs(Dqn_V2 a);
DQN_API Dqn_f32 Dqn_V2_Dot(Dqn_V2 a, Dqn_V2 b);
DQN_API Dqn_f32 Dqn_V2_LengthSq(Dqn_V2 a, Dqn_V2 b);
DQN_API Dqn_V2 Dqn_V2_Normalise(Dqn_V2 a);
DQN_API Dqn_V2 Dqn_V2_Perpendicular(Dqn_V2 a);
#endif // !defined(DQN_NO_V2)
#if !defined(DQN_NO_V3)
// NOTE: [$VEC3] Vector3 ===========================================================================
struct Dqn_V3
union Dqn_V3
{
Dqn_f32 x, y, z;
Dqn_V3() = default;
Dqn_V3(Dqn_f32 a) : x(a), y(a), z(a) {}
Dqn_V3(int32_t a) : x(DQN_CAST(Dqn_f32)a), y(DQN_CAST(Dqn_f32)a), z(DQN_CAST(Dqn_f32)a) {}
Dqn_V3(Dqn_f32 x, Dqn_f32 y, Dqn_f32 z): x(x), y(y), z(z) {}
Dqn_V3(int32_t x, int32_t y, Dqn_f32 z): x(DQN_CAST(Dqn_f32)x), y(DQN_CAST(Dqn_f32)y), z(DQN_CAST(Dqn_f32)z) {}
Dqn_V3(Dqn_V2 xy, Dqn_f32 z) : x(xy.x), y(xy.y), z(z) {}
bool operator!= (Dqn_V3 other) const { return !(*this == other); }
bool operator== (Dqn_V3 other) const { return (x == other.x) && (y == other.y) && (z == other.z); }
bool operator>= (Dqn_V3 other) const { return (x >= other.x) && (y >= other.y) && (z >= other.z); }
bool operator<= (Dqn_V3 other) const { return (x <= other.x) && (y <= other.y) && (z <= other.z); }
bool operator< (Dqn_V3 other) const { return (x < other.x) && (y < other.y) && (z < other.z); }
bool operator> (Dqn_V3 other) const { return (x > other.x) && (y > other.y) && (z > other.z); }
Dqn_V3 operator- (Dqn_V3 other) const { Dqn_V3 result(x - other.x, y - other.y, z - other.z); return result; }
Dqn_V3 operator+ (Dqn_V3 other) const { Dqn_V3 result(x + other.x, y + other.y, z + other.z); return result; }
Dqn_V3 operator* (Dqn_V3 other) const { Dqn_V3 result(x * other.x, y * other.y, z * other.z); return result; }
Dqn_V3 operator* (Dqn_f32 other) const { Dqn_V3 result(x * other, y * other, z * other); return result; }
Dqn_V3 operator* (int32_t other) const { Dqn_V3 result(x * other, y * other, z * other); return result; }
Dqn_V3 operator/ (Dqn_V3 other) const { Dqn_V3 result(x / other.x, y / other.y, z / other.z); return result; }
Dqn_V3 operator/ (Dqn_f32 other) const { Dqn_V3 result(x / other, y / other, z / other); return result; }
Dqn_V3 operator/ (int32_t other) const { Dqn_V3 result(x / other, y / other, z / other); return result; }
Dqn_V3 &operator*=(Dqn_V3 other) { *this = *this * other; return *this; }
Dqn_V3 &operator*=(Dqn_f32 other) { *this = *this * other; return *this; }
Dqn_V3 &operator*=(int32_t other) { *this = *this * other; return *this; }
Dqn_V3 &operator/=(Dqn_V3 other) { *this = *this / other; return *this; }
Dqn_V3 &operator/=(Dqn_f32 other) { *this = *this / other; return *this; }
Dqn_V3 &operator/=(int32_t other) { *this = *this / other; return *this; }
Dqn_V3 &operator-=(Dqn_V3 other) { *this = *this - other; return *this; }
Dqn_V3 &operator+=(Dqn_V3 other) { *this = *this + other; return *this; }
struct { Dqn_f32 x, y, z; };
struct { Dqn_f32 r, g, b; };
Dqn_f32 data[3];
};
DQN_API Dqn_f32 Dqn_V3LengthSq(Dqn_V3 a);
DQN_API Dqn_f32 Dqn_V3Length(Dqn_V3 a);
DQN_API Dqn_V3 Dqn_V3Normalise(Dqn_V3 a);
#define Dqn_V3_InitNx1(x) DQN_LITERAL(Dqn_V3){(Dqn_f32)(x), (Dqn_f32)(x), (Dqn_f32)(x)}
#define Dqn_V3_InitNx3(x, y, z) DQN_LITERAL(Dqn_V3){(Dqn_f32)(x), (Dqn_f32)(y), (Dqn_f32)(z)}
#define Dqn_V3_InitV2x1_Nx1(xy, z) DQN_LITERAL(Dqn_V3){(Dqn_f32)(xy.x), (Dqn_f32)(xy.y), (Dqn_f32)(z)}
DQN_API bool operator!=(Dqn_V3 lhs, Dqn_V3 rhs);
DQN_API bool operator==(Dqn_V3 lhs, Dqn_V3 rhs);
DQN_API bool operator>=(Dqn_V3 lhs, Dqn_V3 rhs);
DQN_API bool operator<=(Dqn_V3 lhs, Dqn_V3 rhs);
DQN_API bool operator< (Dqn_V3 lhs, Dqn_V3 rhs);
DQN_API bool operator> (Dqn_V3 lhs, Dqn_V3 rhs);
DQN_API Dqn_V3 operator- (Dqn_V3 lhs, Dqn_V3 rhs);
DQN_API Dqn_V3 operator+ (Dqn_V3 lhs, Dqn_V3 rhs);
DQN_API Dqn_V3 operator* (Dqn_V3 lhs, Dqn_V3 rhs);
DQN_API Dqn_V3 operator* (Dqn_V3 lhs, Dqn_f32 rhs);
DQN_API Dqn_V3 operator* (Dqn_V3 lhs, int32_t rhs);
DQN_API Dqn_V3 operator/ (Dqn_V3 lhs, Dqn_V3 rhs);
DQN_API Dqn_V3 operator/ (Dqn_V3 lhs, Dqn_f32 rhs);
DQN_API Dqn_V3 operator/ (Dqn_V3 lhs, int32_t rhs);
DQN_API Dqn_V3 &operator*=(Dqn_V3 &lhs, Dqn_V3 rhs);
DQN_API Dqn_V3 &operator*=(Dqn_V3 &lhs, Dqn_f32 rhs);
DQN_API Dqn_V3 &operator*=(Dqn_V3 &lhs, int32_t rhs);
DQN_API Dqn_V3 &operator/=(Dqn_V3 &lhs, Dqn_V3 rhs);
DQN_API Dqn_V3 &operator/=(Dqn_V3 &lhs, Dqn_f32 rhs);
DQN_API Dqn_V3 &operator/=(Dqn_V3 &lhs, int32_t rhs);
DQN_API Dqn_V3 &operator-=(Dqn_V3 &lhs, Dqn_V3 rhs);
DQN_API Dqn_V3 &operator+=(Dqn_V3 &lhs, Dqn_V3 rhs);
DQN_API Dqn_f32 Dqn_V3_LengthSq(Dqn_V3 a);
DQN_API Dqn_f32 Dqn_V3_Length(Dqn_V3 a);
DQN_API Dqn_V3 Dqn_V3_Normalise(Dqn_V3 a);
#endif // !defined(DQN_NO_V3)
#if !defined(DQN_NO_V4)
@ -135,39 +139,42 @@ DQN_API Dqn_V3 Dqn_V3Normalise(Dqn_V3 a);
#error "Dqn_Rect requires Dqn_V3 hence DQN_NO_V3 must *not* be defined"
#endif
#if defined(DQN_COMPILER_W32_MSVC)
#pragma warning(push)
#pragma warning(disable: 4201) // warning C4201: nonstandard extension used: nameless struct/union
#endif
union Dqn_V4
{
struct { Dqn_f32 x, y, z, w; };
struct { Dqn_f32 r, g, b, a; };
struct { Dqn_V2 min; Dqn_V2 max; } v2;
Dqn_V3 rgb;
Dqn_f32 e[4];
Dqn_V4() = default;
Dqn_V4(Dqn_f32 xyzw) : x(xyzw), y(xyzw), z(xyzw), w(xyzw) {}
Dqn_V4(Dqn_f32 x, Dqn_f32 y, Dqn_f32 z, Dqn_f32 w): x(x), y(y), z(z), w(w) {}
Dqn_V4(int32_t x, int32_t y, int32_t z, int32_t w): x(DQN_CAST(Dqn_f32)x), y(DQN_CAST(Dqn_f32)y), z(DQN_CAST(Dqn_f32)z), w(DQN_CAST(Dqn_f32)w) {}
Dqn_V4(Dqn_V3 xyz, Dqn_f32 w) : x(xyz.x), y(xyz.y), z(xyz.z), w(w) {}
Dqn_V4(Dqn_V2 v2) : x(v2.x), y(v2.y), z(v2.x), w(v2.y) {}
bool operator!=(Dqn_V4 other) const { return !(*this == other); }
bool operator==(Dqn_V4 other) const { return (x == other.x) && (y == other.y) && (z == other.z) && (w == other.w); }
bool operator>=(Dqn_V4 other) const { return (x >= other.x) && (y >= other.y) && (z >= other.z) && (w >= other.w); }
bool operator<=(Dqn_V4 other) const { return (x <= other.x) && (y <= other.y) && (z <= other.z) && (w <= other.w); }
bool operator< (Dqn_V4 other) const { return (x < other.x) && (y < other.y) && (z < other.z) && (w < other.w); }
bool operator> (Dqn_V4 other) const { return (x > other.x) && (y > other.y) && (z > other.z) && (w > other.w); }
Dqn_V4 operator- (Dqn_V4 other) const { Dqn_V4 result(x - other.x, y - other.y, z - other.z, w - other.w); return result; }
Dqn_V4 operator+ (Dqn_V4 other) const { Dqn_V4 result(x + other.x, y + other.y, z + other.z, w + other.w); return result; }
Dqn_V4 operator* (Dqn_V4 other) const { Dqn_V4 result(x * other.x, y * other.y, z * other.z, w * other.w); return result; }
Dqn_V4 operator* (Dqn_f32 other) const { Dqn_V4 result(x * other, y * other, z * other, w * other); return result; }
Dqn_V4 operator* (int32_t other) const { Dqn_V4 result(x * other, y * other, z * other, w * other); return result; }
Dqn_V4 operator/ (Dqn_f32 other) const { Dqn_V4 result(x / other, y / other, z / other, w / other); return result; }
Dqn_V4 &operator*=(Dqn_V4 other) { *this = *this * other; return *this; }
Dqn_V4 &operator*=(Dqn_f32 other) { *this = *this * other; return *this; }
Dqn_V4 &operator*=(int32_t other) { *this = *this * other; return *this; }
Dqn_V4 &operator-=(Dqn_V4 other) { *this = *this - other; return *this; }
Dqn_V4 &operator+=(Dqn_V4 other) { *this = *this + other; return *this; }
Dqn_f32 data[4];
};
#define Dqn_V4_InitNx1(x) DQN_LITERAL(Dqn_V4){(Dqn_f32)(x), (Dqn_f32)(x), (Dqn_f32)(x), (Dqn_f32)(x)}
#define Dqn_V4_InitNx4(x, y, z, w) DQN_LITERAL(Dqn_V4){(Dqn_f32)(x), (Dqn_f32)(y), (Dqn_f32)(z), (Dqn_f32)(w)}
bool operator!=(Dqn_V4 lhs, Dqn_V4 rhs);
bool operator==(Dqn_V4 lhs, Dqn_V4 rhs);
bool operator>=(Dqn_V4 lhs, Dqn_V4 rhs);
bool operator<=(Dqn_V4 lhs, Dqn_V4 rhs);
bool operator< (Dqn_V4 lhs, Dqn_V4 rhs);
bool operator> (Dqn_V4 lhs, Dqn_V4 rhs);
Dqn_V4 operator- (Dqn_V4 lhs, Dqn_V4 rhs);
Dqn_V4 operator+ (Dqn_V4 lhs, Dqn_V4 rhs);
Dqn_V4 operator* (Dqn_V4 lhs, Dqn_V4 rhs);
Dqn_V4 operator* (Dqn_V4 lhs, Dqn_f32 rhs);
Dqn_V4 operator* (Dqn_V4 lhs, int32_t rhs);
Dqn_V4 operator/ (Dqn_V4 lhs, Dqn_f32 rhs);
Dqn_V4 &operator*=(Dqn_V4 &lhs, Dqn_V4 rhs);
Dqn_V4 &operator*=(Dqn_V4 &lhs, Dqn_f32 rhs);
Dqn_V4 &operator*=(Dqn_V4 &lhs, int32_t rhs);
Dqn_V4 &operator-=(Dqn_V4 &lhs, Dqn_V4 rhs);
Dqn_V4 &operator+=(Dqn_V4 &lhs, Dqn_V4 rhs);
#if defined(DQN_COMPILER_W32_MSVC)
#pragma warning(pop)
#endif
#endif // !defined(DQN_NO_V4)
#if !defined(DQN_NO_M4)
@ -211,36 +218,28 @@ DQN_API Dqn_FString8<256> Dqn_M4_ColumnMajorString(Dqn_M4 mat);
struct Dqn_Rect
{
Dqn_V2 min, max;
Dqn_Rect() = default;
Dqn_Rect(Dqn_V2 min, Dqn_V2 max) : min(min), max(max) {}
Dqn_Rect(Dqn_V2I min, Dqn_V2I max) : min(min), max(max) {}
Dqn_Rect(Dqn_f32 x, Dqn_f32 y, Dqn_f32 max_x, Dqn_f32 max_y) : min(x, y), max(max_x, max_y) {}
bool operator==(Dqn_Rect other) const { return (min == other.min) && (max == other.max); }
Dqn_V2 pos, size;
};
struct Dqn_RectI32
{
Dqn_V2I min, max;
Dqn_RectI32() = default;
Dqn_RectI32(Dqn_V2I min, Dqn_V2I max) : min(min), max(max) {}
};
#if defined(__cplusplus)
#define Dqn_Rect_InitV2x2(pos, size) Dqn_Rect{pos, size}
#else
#define Dqn_Rect_InitV2x2(pos, size) (Dqn_Rect){pos, size}
#endif
DQN_API Dqn_Rect Dqn_Rect_InitFromPosAndSize(Dqn_V2 pos, Dqn_V2 size);
DQN_API bool operator== (const Dqn_Rect& lhs, const Dqn_Rect& rhs);
DQN_API Dqn_V2 Dqn_Rect_Center (Dqn_Rect rect);
DQN_API bool Dqn_Rect_ContainsPoint(Dqn_Rect rect, Dqn_V2 p);
DQN_API bool Dqn_Rect_ContainsRect (Dqn_Rect a, Dqn_Rect b);
DQN_API Dqn_V2 Dqn_Rect_Size(Dqn_Rect rect);
DQN_API Dqn_Rect Dqn_Rect_Move(Dqn_Rect src, Dqn_V2 move_amount);
DQN_API Dqn_Rect Dqn_Rect_MoveTo(Dqn_Rect src, Dqn_V2 dest);
DQN_API bool Dqn_Rect_Intersects (Dqn_Rect a, Dqn_Rect b);
DQN_API Dqn_Rect Dqn_Rect_Intersection (Dqn_Rect a, Dqn_Rect b);
DQN_API Dqn_Rect Dqn_Rect_Union (Dqn_Rect a, Dqn_Rect b);
DQN_API Dqn_Rect Dqn_Rect_FromRectI32(Dqn_RectI32 a);
DQN_API Dqn_V2I Dqn_RectI32_Size(Dqn_RectI32 rect);
#endif // !defined(DQN_NO_RECT)
// NOTE: [$MATH] Other =============================================================================
DQN_API Dqn_V2 Dqn_Lerp_V2(Dqn_V2 a, Dqn_f32 t, Dqn_V2 b);
DQN_API Dqn_f32 Dqn_Lerp_F32(Dqn_f32 a, Dqn_f32 t, Dqn_f32 b);
#if defined(DQN_COMPILER_W32_MSVC)
#pragma warning(pop)
#endif

View File

@ -289,6 +289,24 @@ DQN_API void Dqn_Arena_BlockReset_(DQN_LEAK_TRACE_FUNCTION Dqn_ArenaBlock *block
Dqn_VMem_Release(block, block_metadata_size + block->size);
Dqn_Library_LeakTraceMarkFree(DQN_LEAK_TRACE_ARG block);
} else {
if (block->arena->use_after_free_guard) {
DQN_ASSERTF(
block->flags & Dqn_ArenaBlockFlags_UseAfterFreeGuard,
"Arena has set use-after-free guard but the memory it uses was not initialised "
"with use-after-free semantics. You might have set the arena use-after-free "
"flag after it has already done an allocation which is not valid. Make sure "
"you set the flag first before the arena is used.");
} else {
DQN_ASSERTF(
(block->flags & Dqn_ArenaBlockFlags_UseAfterFreeGuard) == 0,
"The arena's memory block has the use-after-free guard set but the arena does "
"not have the use-after-free flag set. This is not valid, a block that has "
"use-after-free semantics was allocated from an arena with the equivalent flag set "
"and for the lifetime of the block the owning arena must also have the same flag "
"set for correct behaviour. Make sure you do not unset the flag on the arena "
"whilst it still has memory blocks that it owns.");
}
block->used = reset_info.used_value;
// NOTE: Guard all the committed pages again
if (block->arena->use_after_free_guard)
@ -473,6 +491,9 @@ DQN_API Dqn_ArenaBlock *Dqn_Arena_Grow_(DQN_LEAK_TRACE_FUNCTION Dqn_Arena *arena
result->flags = flags;
result->arena = arena;
if (arena->use_after_free_guard)
result->flags |= Dqn_ArenaBlockFlags_UseAfterFreeGuard;
// NOTE: Reset the block (this will guard the memory pages if required, otherwise no-op).
Dqn_ArenaBlockResetInfo_ reset_info = {};
Dqn_Arena_BlockReset_(DQN_LEAK_TRACE_ARG result, Dqn_ZeroMem_No, reset_info);

View File

@ -189,7 +189,8 @@ DQN_API int Dqn_VMem_Protect (void *ptr, Dqn_usize size, uint32_t page_flags);
enum Dqn_ArenaBlockFlags
{
Dqn_ArenaBlockFlags_Private = 1 << 0, ///< Private blocks can only allocate its memory when used in the 'FromBlock' API variants
Dqn_ArenaBlockFlags_Private = 1 << 0, // Private blocks can only allocate its memory when used in the 'FromBlock' API variants
Dqn_ArenaBlockFlags_UseAfterFreeGuard = 1 << 1, // Block was allocated with use-after-free guard semantics
};
struct Dqn_ArenaStat

View File

@ -538,7 +538,7 @@ DQN_API uint32_t Dqn_Thread_GetID()
DQN_API Dqn_ThreadContext *Dqn_Thread_GetContext_(DQN_LEAK_TRACE_FUNCTION_NO_COMMA)
{
thread_local Dqn_ThreadContext result = {};
DQN_THREAD_LOCAL Dqn_ThreadContext result = {};
if (!result.init) {
result.init = true;
DQN_ASSERTF(dqn_library.lib_init, "Library must be initialised by calling Dqn_Library_Init(nullptr)");

View File

@ -3,9 +3,9 @@
#pragma comment(lib, "bcrypt")
#pragma comment(lib, "wininet")
#if defined(DQN_NO_WIN32_MINIMAL_HEADER) || defined(_INC_WINDOWS)
#if defined(DQN_NO_WIN32_MIN_HEADER)
#include <bcrypt.h> // Dqn_OS_SecureRNGBytes -> BCryptOpenAlgorithmProvider ... etc
#include <shellscalingapi.h> // Dqn_Win_MakeProcessDPIAware -> SetProcessDpiAwareProc
#include <shellapi.h> // Dqn_Win_MakeProcessDPIAware -> SetProcessDpiAwareProc
#if !defined(DQN_NO_WINNET)
#include <wininet.h> // Dqn_Win_Net -> InternetConnect ... etc
#endif // DQN_NO_WINNET

View File

@ -199,7 +199,12 @@ DQN_API uint64_t Dqn_Date_EpochTime ();
// NOTE: [$W32H] Win32 Min Header ==================================================================
#if defined(DQN_OS_WIN32)
#if !defined(DQN_NO_WIN32_MIN_HEADER) && !defined(_INC_WINDOWS)
#if defined(DQN_COMPILER_W32_MSVC)
#pragma warning(push)
#pragma warning(disable: 4201) // warning C4201: nonstandard extension used: nameless struct/union
#endif
// Taken from Windows.h
// typedef unsigned long DWORD;
// typedef unsigned short WORD;
@ -220,6 +225,9 @@ DQN_API uint64_t Dqn_Date_EpochTime ();
} u;
uint64_t QuadPart;
} LARGE_INTEGER;
#if defined(DQN_COMPILER_W32_MSVC)
#pragma warning(pop)
#endif
#endif // !defined(DQN_NO_WIN32_MIN_HEADER) && !defined(_INC_WINDOWS)
// NOTE: [$WIND] Dqn_Win ===========================================================================

View File

@ -33,10 +33,10 @@ DQN_API void Dqn_Print_Std(Dqn_PrintStd std_handle, Dqn_String8 string)
#if defined(DQN_OS_WIN32)
// NOTE: Get the output handles from kernel
// =========================================================================
thread_local void *std_out_print_handle = nullptr;
thread_local void *std_err_print_handle = nullptr;
thread_local bool std_out_print_to_console = false;
thread_local bool std_err_print_to_console = false;
DQN_THREAD_LOCAL void *std_out_print_handle = nullptr;
DQN_THREAD_LOCAL void *std_err_print_handle = nullptr;
DQN_THREAD_LOCAL bool std_out_print_to_console = false;
DQN_THREAD_LOCAL bool std_err_print_to_console = false;
if (!std_out_print_handle) {
unsigned long mode = 0; (void)mode;
@ -171,7 +171,7 @@ DQN_API void Dqn_Print_StdLnFVStyle(Dqn_PrintStd std_handle, Dqn_PrintStyle styl
DQN_API Dqn_String8 Dqn_Print_ESCColourString(Dqn_PrintESCColour colour, uint8_t r, uint8_t g, uint8_t b)
{
thread_local char buffer[32];
DQN_THREAD_LOCAL char buffer[32];
buffer[0] = 0;
Dqn_String8 result = {};
result.size = STB_SPRINTF_DECORATE(snprintf)(buffer,

View File

@ -9,20 +9,34 @@ amalgamates all the files into one translation unit.
## Build
To build with this library, copy all the `*.[h|cpp]` files at the root of the
repository and in one header file,
repository to your desired location, accessible by your project and in one
header file include the header.
```cpp
#include "dqn.h"
```
Which includes all other files and their declaration into your header. In one
`.cpp` file defined the implementation macro to enable the implementation of the
header in that translation unit,
`dqn.h` includes all other files and their declaration into your header. In
*one* `.cpp` file define the macro to enable the implementation of the header in
the translation unit.
```cpp
#define DQN_IMPLEMENTATION
#include "dqn.h"
```
Ensure that the folder containing the files is part of the include search path
for the compiler for the amalgamated `dqn.h` to successfully locate the files.
Finally ensure that the compiler has in its search paths for the include
directory where headers are located, e.g. `-I <path/to/dqn/headers>`.
## Customisation
The headers provide macros to compile out sections that are not needed. This can
be useful to speed up compile times if you want a particular part of the
library. Each header contains a table-of-contents that denotes the macro to
define to disable that section that should be defined before the header include.
```cpp
#define DQN_NO_VARRAY // Disable virtual array container
#define DQN_NO_JSON_BUILDER // Disable the JSON string builder
#include "dqn.h"
```