From c3902e3a29ef5e0c64347a25735f8d840aed1d34 Mon Sep 17 00:00:00 2001 From: doyle Date: Sun, 16 Jul 2023 17:52:18 +1000 Subject: [PATCH] dqn: Move vector math to impl, add new macros --- dqn.rdbg | Bin 1121 -> 1195 bytes dqn_core.h | 39 ++- dqn_math.cpp | 629 +++++++++++++++++++++++++++++++++++++++++------ dqn_math.h | 309 ++++++++++++----------- dqn_memory.cpp | 21 ++ dqn_memory.h | 3 +- dqn_misc.cpp | 2 +- dqn_platform.cpp | 6 +- dqn_platform.h | 8 + dqn_print.cpp | 10 +- 10 files changed, 774 insertions(+), 253 deletions(-) diff --git a/dqn.rdbg b/dqn.rdbg index 6977235d8ef449b2184c7e5b537c345c7c212381..a09c161564dcc1b93aa5b45ee387001dcc52c205 100644 GIT binary patch delta 214 zcmaFJv6^#&oih^y1A`S1J6pwgLrU!tQBY0%V3$fcIh)a+QIrK} w((E`PYuC`Tj+{}G61uz}zh;@7$Sg7WK2s4dNEU<{fk1fjL+0$sCzxjf05yU{KL7v# delta 104 zcmZ3@`H*9R9V;^f1B1-OMsbe#(vsBT61|Lx4N{ECKmmdH(!9))c#vSRUUESJ^TgRF zH?L##WfTNynH?u&?HYR4kuz#i0`p`+W|7Gn%tbsP84zY operator+(Lambda lambda) { return Dqn_Defer(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) \ diff --git a/dqn_math.cpp b/dqn_math.cpp index 51dd0a9..eedebbe 100644 --- a/dqn_math.cpp +++ b/dqn_math.cpp @@ -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) diff --git a/dqn_math.h b/dqn_math.h index e37bdf6..a0d00dc 100644 --- a/dqn_math.h +++ b/dqn_math.h @@ -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; } + struct { Dqn_f32 x, y, z, w; }; + struct { Dqn_f32 r, g, b, a; }; + Dqn_V3 rgb; + 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 Dqn_V2 Dqn_Rect_Center(Dqn_Rect rect); +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); +DQN_API bool Dqn_Rect_ContainsRect (Dqn_Rect a, Dqn_Rect b); +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); #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 diff --git a/dqn_memory.cpp b/dqn_memory.cpp index fc06679..83ac763 100644 --- a/dqn_memory.cpp +++ b/dqn_memory.cpp @@ -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); diff --git a/dqn_memory.h b/dqn_memory.h index fd589f2..86816ce 100644 --- a/dqn_memory.h +++ b/dqn_memory.h @@ -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 diff --git a/dqn_misc.cpp b/dqn_misc.cpp index c25240f..3d7811a 100644 --- a/dqn_misc.cpp +++ b/dqn_misc.cpp @@ -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)"); diff --git a/dqn_platform.cpp b/dqn_platform.cpp index 2392924..3de79eb 100644 --- a/dqn_platform.cpp +++ b/dqn_platform.cpp @@ -3,9 +3,9 @@ #pragma comment(lib, "bcrypt") #pragma comment(lib, "wininet") - #if defined(DQN_NO_WIN32_MINIMAL_HEADER) || defined(_INC_WINDOWS) - #include // Dqn_OS_SecureRNGBytes -> BCryptOpenAlgorithmProvider ... etc - #include // Dqn_Win_MakeProcessDPIAware -> SetProcessDpiAwareProc + #if defined(DQN_NO_WIN32_MIN_HEADER) + #include // Dqn_OS_SecureRNGBytes -> BCryptOpenAlgorithmProvider ... etc + #include // Dqn_Win_MakeProcessDPIAware -> SetProcessDpiAwareProc #if !defined(DQN_NO_WINNET) #include // Dqn_Win_Net -> InternetConnect ... etc #endif // DQN_NO_WINNET diff --git a/dqn_platform.h b/dqn_platform.h index fcf3d65..a74bbc0 100644 --- a/dqn_platform.h +++ b/dqn_platform.h @@ -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 =========================================================================== diff --git a/dqn_print.cpp b/dqn_print.cpp index fe9d7f7..997a936 100644 --- a/dqn_print.cpp +++ b/dqn_print.cpp @@ -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,