diff --git a/Source/Base/dn_base.cpp b/Source/Base/dn_base.cpp index 280b7d0..dbe1dd5 100644 --- a/Source/Base/dn_base.cpp +++ b/Source/Base/dn_base.cpp @@ -1473,7 +1473,7 @@ DN_API bool DN_ErrSinkEndLogError_(DN_ErrSink *err, DN_CallSite call_site, DN_St // NOTE: Log the error DN_Str8 log = DN_Str8BuilderBuild(&builder, err->arena); - DN_LogPrint(DN_LogMakeU32LogTypeParam(DN_LogType_Error), call_site, "%.*s", DN_Str8PrintFmt(log)); + DN_LogPrint(DN_LogTypeParamFromType(DN_LogType_Error), call_site, "%.*s", DN_Str8PrintFmt(log)); if (node->mode == DN_ErrSinkMode_DebugBreakOnErrorLog) DN_DebugBreak; @@ -1552,7 +1552,6 @@ DN_API void DN_TCInit(DN_TCCore *tc, DN_U64 thread_id, DN_Arena *main_arena, DN_ tc->temp_a_arena = temp_a_arena; tc->temp_b_arena = temp_b_arena; tc->err_sink.arena = err_sink_arena; - tc->lane.count = 1; } DN_API void DN_TCInitFromMemFuncs(DN_TCCore *tc, DN_U64 thread_id, DN_TCInitArgs *args, DN_ArenaMemFuncs mem_funcs) @@ -1672,21 +1671,6 @@ DN_API DN_ErrSink *DN_TCErrSink() return result; } -DN_API DN_TCLane *DN_TCLaneGet() -{ - DN_TCCore *tc = DN_TCGet(); - DN_TCLane *result = &tc->lane; - return result; -} - -DN_API DN_TCLane DN_TCLaneEquip(DN_TCLane lane) -{ - DN_TCLane *curr = DN_TCLaneGet(); - DN_TCLane result = *curr; - *curr = lane; - return result; -} - DN_API void *DN_PoolCopy(DN_Pool *pool, void const *data, DN_U64 size, uint8_t align) { if (!pool || !data || size == 0) @@ -1989,14 +1973,7 @@ DN_API bool DN_Str16Eq(DN_Str16 lhs, DN_Str16 rhs) return result; } -DN_API DN_Str8 DN_Str8FromCStr8(char const *src) -{ - DN_USize size = DN_CStr8Size(src); - DN_Str8 result = DN_Str8FromPtr(src, size); - return result; -} - -DN_API DN_Str8 DN_Str8FromArena(DN_Arena *arena, DN_USize size, DN_ZMem z_mem) +DN_API DN_Str8 DN_Str8AllocArena(DN_Arena *arena, DN_USize size, DN_ZMem z_mem) { DN_Str8 result = {}; result.data = DN_ArenaNewArray(arena, char, size + 1, z_mem); @@ -2006,7 +1983,7 @@ DN_API DN_Str8 DN_Str8FromArena(DN_Arena *arena, DN_USize size, DN_ZMem z_mem) return result; } -DN_API DN_Str8 DN_Str8FromPool(DN_Pool *pool, DN_USize size) +DN_API DN_Str8 DN_Str8AllocPool(DN_Pool *pool, DN_USize size) { DN_Str8 result = {}; result.data = DN_PoolNewArray(pool, char, size + 1); @@ -2016,9 +1993,16 @@ DN_API DN_Str8 DN_Str8FromPool(DN_Pool *pool, DN_USize size) return result; } +DN_API DN_Str8 DN_Str8FromCStr8(char const *src) +{ + DN_USize size = DN_CStr8Size(src); + DN_Str8 result = DN_Str8FromPtr(src, size); + return result; +} + DN_API DN_Str8 DN_Str8FromPtrArena(DN_Arena *arena, void const *data, DN_USize size) { - DN_Str8 result = DN_Str8FromArena(arena, size, DN_ZMem_No); + DN_Str8 result = DN_Str8AllocArena(arena, size, DN_ZMem_No); if (result.size) DN_Memcpy(result.data, data, size); return result; @@ -2026,7 +2010,7 @@ DN_API DN_Str8 DN_Str8FromPtrArena(DN_Arena *arena, void const *data, DN_USize s DN_API DN_Str8 DN_Str8FromPtrPool(DN_Pool *pool, void const *data, DN_USize size) { - DN_Str8 result = DN_Str8FromPool(pool, size); + DN_Str8 result = DN_Str8AllocPool(pool, size); if (result.size) DN_Memcpy(result.data, data, size); return result; @@ -2068,7 +2052,7 @@ DN_API DN_Str8 DN_Str8FromFmtArena(DN_Arena *arena, DN_FMT_ATTRIB char const *fm DN_API DN_Str8 DN_Str8FromFmtVArena(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args) { DN_USize size = DN_FmtVSize(fmt, args); - DN_Str8 result = DN_Str8FromArena(arena, size, DN_ZMem_No); + DN_Str8 result = DN_Str8AllocArena(arena, size, DN_ZMem_No); if (result.data) { DN_USize written = 0; DN_FmtVAppend(result.data, &written, result.size + 1, fmt, args); @@ -2082,7 +2066,7 @@ DN_API DN_Str8 DN_Str8FromFmtPool(DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, va_list args; va_start(args, fmt); DN_USize size = DN_FmtVSize(fmt, args); - DN_Str8 result = DN_Str8FromPool(pool, size); + DN_Str8 result = DN_Str8AllocPool(pool, size); if (result.data) { DN_USize written = 0; DN_FmtVAppend(result.data, &written, result.size + 1, fmt, args); @@ -2437,7 +2421,7 @@ DN_API DN_Str8FindResult DN_Str8FindStr8(DN_Str8 string, DN_Str8 find, DN_Str8Eq return result; } -DN_API DN_Str8FindResult DN_Str8Find(DN_Str8 string, uint32_t flags) +DN_API DN_Str8FindResult DN_Str8Find(DN_Str8 string, DN_Str8FindFlag flags) { DN_Str8FindResult result = {}; for (size_t index = 0; !result.found && index < string.size; index++) { @@ -2468,7 +2452,7 @@ DN_API DN_Str8 DN_Str8Segment(DN_Arena *arena, DN_Str8 src, DN_USize segment_siz segments--; DN_USize segment_counter = 0; - DN_Str8 result = DN_Str8FromArena(arena, src.size + segments, DN_ZMem_Yes); + DN_Str8 result = DN_Str8AllocArena(arena, src.size + segments, DN_ZMem_Yes); DN_USize write_index = 0; for (DN_ForIndexU(src_index, src.size)) { result.data[write_index++] = src.data[src_index]; @@ -2496,7 +2480,7 @@ DN_API DN_Str8 DN_Str8ReverseSegment(DN_Arena *arena, DN_Str8 src, DN_USize segm DN_USize write_counter = 0; DN_USize segment_counter = 0; - DN_Str8 result = DN_Str8FromArena(arena, src.size + segments, DN_ZMem_Yes); + DN_Str8 result = DN_Str8AllocArena(arena, src.size + segments, DN_ZMem_Yes); DN_USize write_index = result.size - 1; DN_MSVC_WARNING_PUSH @@ -2711,7 +2695,7 @@ DN_API DN_Str8 DN_Str8AppendFV(DN_Arena *arena, DN_Str8 string, char const *fmt, { // TODO: Calculate size and write into one buffer instead of 2 appends DN_Str8 append = DN_Str8FromFmtVArena(arena, fmt, args); - DN_Str8 result = DN_Str8FromArena(arena, string.size + append.size, DN_ZMem_No); + DN_Str8 result = DN_Str8AllocArena(arena, string.size + append.size, DN_ZMem_No); DN_Memcpy(result.data, string.data, string.size); DN_Memcpy(result.data + string.size, append.data, append.size); return result; @@ -2729,7 +2713,7 @@ DN_API DN_Str8 DN_Str8FillF(DN_Arena *arena, DN_USize count, char const *fmt, .. DN_API DN_Str8 DN_Str8FillFV(DN_Arena *arena, DN_USize count, char const *fmt, va_list args) { DN_Str8 fill = DN_Str8FromFmtVArena(arena, fmt, args); - DN_Str8 result = DN_Str8FromArena(arena, count * fill.size, DN_ZMem_No); + DN_Str8 result = DN_Str8AllocArena(arena, count * fill.size, DN_ZMem_No); for (DN_USize index = 0; index < count; index++) { void *dest = result.data + (index * fill.size); DN_Memcpy(dest, fill.data, fill.size); @@ -2848,6 +2832,81 @@ DN_API DN_Str8 DN_Str8ReplaceInsensitive(DN_Str8 string, DN_Str8 find, DN_Str8 r return result; } +DN_API DN_Str8 DN_Str8SliceRender(DN_Str8Slice slice, DN_Str8 separator, DN_Arena *arena) +{ + DN_Str8 result = {}; + if (!arena) + return result; + + DN_USize total_size = 0; + for (DN_USize index = 0; index < slice.count; index++) { + if (index) + total_size += separator.size; + DN_Str8 item = slice.data[index]; + total_size += item.size; + } + + result = DN_Str8AllocArena(arena, total_size, DN_ZMem_No); + if (result.data) { + DN_USize write_index = 0; + for (DN_USize index = 0; index < slice.count; index++) { + if (index) { + DN_Memcpy(result.data + write_index, separator.data, separator.size); + write_index += separator.size; + } + DN_Str8 item = slice.data[index]; + DN_Memcpy(result.data + write_index, item.data, item.size); + write_index += item.size; + } + } + + return result; +} + +DN_API DN_Str8 DN_Str8RenderSpaceSep(DN_Str8Slice slice, DN_Arena *arena) +{ + DN_Str8 result = DN_Str8SliceRender(slice, DN_Str8Lit(" "), arena); + return result; +} + +DN_API DN_Str16 DN_Str16SliceRender(DN_Str16Slice slice, DN_Str16 separator, DN_Arena *arena) +{ + DN_Str16 result = {}; + if (!arena) + return result; + + DN_USize total_size = 0; + for (DN_USize index = 0; index < slice.count; index++) { + if (index) + total_size += separator.size; + DN_Str16 item = slice.data[index]; + total_size += item.size; + } + + result = {DN_ArenaNewArray(arena, wchar_t, total_size + 1, DN_ZMem_No), total_size}; + if (result.data) { + DN_USize write_index = 0; + for (DN_USize index = 0; index < slice.count; index++) { + if (index) { + DN_Memcpy(result.data + write_index, separator.data, separator.size * sizeof(result.data[0])); + write_index += separator.size; + } + DN_Str16 item = slice.data[index]; + DN_Memcpy(result.data + write_index, item.data, item.size * sizeof(result.data[0])); + write_index += item.size; + } + } + + result.data[total_size] = 0; + return result; +} + +DN_API DN_Str16 DN_Str16RenderSpaceSep(DN_Str16Slice slice, DN_Arena *arena) +{ + DN_Str16 result = DN_Str16SliceRender(slice, DN_Str16Lit(L" "), arena); + return result; +} + DN_API DN_Str8Builder DN_Str8BuilderFromArena(DN_Arena *arena) { DN_Str8Builder result = {}; @@ -3144,7 +3203,7 @@ DN_API DN_Str8Slice DN_Str8BuilderBuildSlice(DN_Str8Builder const *builder, DN_A } // NOTE: DN_UTF -DN_API int DN_UTF8EncodeCodepoint(uint8_t utf8[4], uint32_t codepoint) +DN_API int DN_UTF8EncodeCodepoint(DN_U8 utf8[4], DN_U32 codepoint) { // NOTE: Table from https://www.reedbeta.com/blog/programmers-intro-to-unicode/ // ----------------------------------------+----------------------------+--------------------+ @@ -3185,7 +3244,7 @@ DN_API int DN_UTF8EncodeCodepoint(uint8_t utf8[4], uint32_t codepoint) return 0; } -DN_API int DN_UTF16EncodeCodepoint(uint16_t utf16[2], uint32_t codepoint) +DN_API int DN_UTF16EncodeCodepoint(DN_U16 utf16[2], DN_U32 codepoint) { // NOTE: Table from https://www.reedbeta.com/blog/programmers-intro-to-unicode/ // ----------------------------------------+------------------------------------+------------------+ @@ -3196,14 +3255,14 @@ DN_API int DN_UTF16EncodeCodepoint(uint16_t utf16[2], uint32_t codepoint) // ----------------------------------------+------------------------------------+------------------+ if (codepoint <= 0b1111'1111'1111'1111) { - utf16[0] = DN_Cast(uint16_t) codepoint; + utf16[0] = DN_Cast(DN_U16) codepoint; return 1; } if (codepoint <= 0b1111'1111'1111'1111'1111) { - uint32_t surrogate_codepoint = codepoint + 0x10000; - utf16[0] = 0b1101'1000'0000'0000 | ((surrogate_codepoint >> 10) & 0b11'1111'1111); // x - utf16[1] = 0b1101'1100'0000'0000 | ((surrogate_codepoint >> 0) & 0b11'1111'1111); // y + DN_U32 surrogate_codepoint = codepoint + 0x10000; + utf16[0] = 0b1101'1000'0000'0000 | ((surrogate_codepoint >> 10) & 0b11'1111'1111); // x + utf16[1] = 0b1101'1100'0000'0000 | ((surrogate_codepoint >> 0) & 0b11'1111'1111); // y return 2; } @@ -3791,7 +3850,7 @@ DN_API DN_U64 DN_PCG32Next64(DN_PCG32 *rng) DN_API DN_U32 DN_PCG32Range(DN_PCG32 *rng, DN_U32 low, DN_U32 high) { DN_U32 bound = high - low; - DN_U32 threshold = -(int32_t)bound % bound; + DN_U32 threshold = -(DN_I32)bound % bound; for (;;) { DN_U32 r = DN_PCG32Next(rng); @@ -3803,7 +3862,7 @@ DN_API DN_U32 DN_PCG32Range(DN_PCG32 *rng, DN_U32 low, DN_U32 high) DN_API DN_F32 DN_PCG32NextF32(DN_PCG32 *rng) { DN_U32 x = DN_PCG32Next(rng); - return (DN_F32)(int32_t)(x >> 8) * 0x1.0p-24f; + return (DN_F32)(DN_I32)(x >> 8) * 0x1.0p-24f; } DN_API DN_F64 DN_PCG32NextF64(DN_PCG32 *rng) @@ -4192,10 +4251,1590 @@ DN_API void DN_LogPrint(DN_LogTypeParam type, DN_CallSite call_site, DN_FMT_ATTR } } -DN_API DN_LogTypeParam DN_LogMakeU32LogTypeParam(DN_LogType type) +DN_API DN_LogTypeParam DN_LogTypeParamFromType(DN_LogType type) { DN_LogTypeParam result = {}; result.is_u32_enum = true; result.u32 = type; return result; } + +DN_API bool operator==(DN_V2I32 lhs, DN_V2I32 rhs) +{ + bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y); + return result; +} + +DN_API bool operator!=(DN_V2I32 lhs, DN_V2I32 rhs) +{ + bool result = !(lhs == rhs); + return result; +} + +DN_API bool operator>=(DN_V2I32 lhs, DN_V2I32 rhs) +{ + bool result = (lhs.x >= rhs.x) && (lhs.y >= rhs.y); + return result; +} + +DN_API bool operator<=(DN_V2I32 lhs, DN_V2I32 rhs) +{ + bool result = (lhs.x <= rhs.x) && (lhs.y <= rhs.y); + return result; +} + +DN_API bool operator<(DN_V2I32 lhs, DN_V2I32 rhs) +{ + bool result = (lhs.x < rhs.x) && (lhs.y < rhs.y); + return result; +} + +DN_API bool operator>(DN_V2I32 lhs, DN_V2I32 rhs) +{ + bool result = (lhs.x > rhs.x) && (lhs.y > rhs.y); + return result; +} + +DN_API DN_V2I32 operator-(DN_V2I32 lhs, DN_V2I32 rhs) +{ + DN_V2I32 result = DN_V2I32From2N(lhs.x - rhs.x, lhs.y - rhs.y); + return result; +} + +DN_API DN_V2I32 operator-(DN_V2I32 lhs) +{ + DN_V2I32 result = DN_V2I32From2N(-lhs.x, -lhs.y); + return result; +} + +DN_API DN_V2I32 operator+(DN_V2I32 lhs, DN_V2I32 rhs) +{ + DN_V2I32 result = DN_V2I32From2N(lhs.x + rhs.x, lhs.y + rhs.y); + return result; +} + +DN_API DN_V2I32 operator*(DN_V2I32 lhs, DN_V2I32 rhs) +{ + DN_V2I32 result = DN_V2I32From2N(lhs.x * rhs.x, lhs.y * rhs.y); + return result; +} + +DN_API DN_V2I32 operator*(DN_V2I32 lhs, DN_F32 rhs) +{ + DN_V2I32 result = DN_V2I32From2N(lhs.x * rhs, lhs.y * rhs); + return result; +} + +DN_API DN_V2I32 operator*(DN_V2I32 lhs, DN_I32 rhs) +{ + DN_V2I32 result = DN_V2I32From2N(lhs.x * rhs, lhs.y * rhs); + return result; +} + +DN_API DN_V2I32 operator/(DN_V2I32 lhs, DN_V2I32 rhs) +{ + DN_V2I32 result = DN_V2I32From2N(lhs.x / rhs.x, lhs.y / rhs.y); + return result; +} + +DN_API DN_V2I32 operator/(DN_V2I32 lhs, DN_F32 rhs) +{ + DN_V2I32 result = DN_V2I32From2N(lhs.x / rhs, lhs.y / rhs); + return result; +} + +DN_API DN_V2I32 operator/(DN_V2I32 lhs, DN_I32 rhs) +{ + DN_V2I32 result = DN_V2I32From2N(lhs.x / rhs, lhs.y / rhs); + return result; +} + +DN_API DN_V2I32 &operator*=(DN_V2I32 &lhs, DN_V2I32 rhs) +{ + lhs = lhs * rhs; + return lhs; +} + +DN_API DN_V2I32 &operator*=(DN_V2I32 &lhs, DN_F32 rhs) +{ + lhs = lhs * rhs; + return lhs; +} + +DN_API DN_V2I32 &operator*=(DN_V2I32 &lhs, DN_I32 rhs) +{ + lhs = lhs * rhs; + return lhs; +} + +DN_API DN_V2I32 &operator/=(DN_V2I32 &lhs, DN_V2I32 rhs) +{ + lhs = lhs / rhs; + return lhs; +} + +DN_API DN_V2I32 &operator/=(DN_V2I32 &lhs, DN_F32 rhs) +{ + lhs = lhs / rhs; + return lhs; +} + +DN_API DN_V2I32 &operator/=(DN_V2I32 &lhs, DN_I32 rhs) +{ + lhs = lhs / rhs; + return lhs; +} + +DN_API DN_V2I32 &operator-=(DN_V2I32 &lhs, DN_V2I32 rhs) +{ + lhs = lhs - rhs; + return lhs; +} + +DN_API DN_V2I32 &operator+=(DN_V2I32 &lhs, DN_V2I32 rhs) +{ + lhs = lhs + rhs; + return lhs; +} + +DN_API DN_V2I32 DN_V2I32Min(DN_V2I32 a, DN_V2I32 b) +{ + DN_V2I32 result = DN_V2I32From2N(DN_Min(a.x, b.x), DN_Min(a.y, b.y)); + return result; +} + +DN_API DN_V2I32 DN_V2I32Max(DN_V2I32 a, DN_V2I32 b) +{ + DN_V2I32 result = DN_V2I32From2N(DN_Max(a.x, b.x), DN_Max(a.y, b.y)); + return result; +} + +DN_API DN_V2I32 DN_V2I32Abs(DN_V2I32 a) +{ + DN_V2I32 result = DN_V2I32From2N(DN_Abs(a.x), DN_Abs(a.y)); + return result; +} + +DN_API bool operator!=(DN_V2U16 lhs, DN_V2U16 rhs) +{ + bool result = !(lhs == rhs); + return result; +} + +DN_API bool operator==(DN_V2U16 lhs, DN_V2U16 rhs) +{ + bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y); + return result; +} + +DN_API bool operator>=(DN_V2U16 lhs, DN_V2U16 rhs) +{ + bool result = (lhs.x >= rhs.x) && (lhs.y >= rhs.y); + return result; +} + +DN_API bool operator<=(DN_V2U16 lhs, DN_V2U16 rhs) +{ + bool result = (lhs.x <= rhs.x) && (lhs.y <= rhs.y); + return result; +} + +DN_API bool operator<(DN_V2U16 lhs, DN_V2U16 rhs) +{ + bool result = (lhs.x < rhs.x) && (lhs.y < rhs.y); + return result; +} + +DN_API bool operator>(DN_V2U16 lhs, DN_V2U16 rhs) +{ + bool result = (lhs.x > rhs.x) && (lhs.y > rhs.y); + return result; +} + +DN_API DN_V2U16 operator-(DN_V2U16 lhs, DN_V2U16 rhs) +{ + DN_V2U16 result = DN_V2U16From2N(lhs.x - rhs.x, lhs.y - rhs.y); + return result; +} + +DN_API DN_V2U16 operator+(DN_V2U16 lhs, DN_V2U16 rhs) +{ + DN_V2U16 result = DN_V2U16From2N(lhs.x + rhs.x, lhs.y + rhs.y); + return result; +} + +DN_API DN_V2U16 operator*(DN_V2U16 lhs, DN_V2U16 rhs) +{ + DN_V2U16 result = DN_V2U16From2N(lhs.x * rhs.x, lhs.y * rhs.y); + return result; +} + +DN_API DN_V2U16 operator*(DN_V2U16 lhs, DN_F32 rhs) +{ + DN_V2U16 result = DN_V2U16From2N(lhs.x * rhs, lhs.y * rhs); + return result; +} + +DN_API DN_V2U16 operator*(DN_V2U16 lhs, DN_I32 rhs) +{ + DN_V2U16 result = DN_V2U16From2N(lhs.x * rhs, lhs.y * rhs); + return result; +} + +DN_API DN_V2U16 operator/(DN_V2U16 lhs, DN_V2U16 rhs) +{ + DN_V2U16 result = DN_V2U16From2N(lhs.x / rhs.x, lhs.y / rhs.y); + return result; +} + +DN_API DN_V2U16 operator/(DN_V2U16 lhs, DN_F32 rhs) +{ + DN_V2U16 result = DN_V2U16From2N(lhs.x / rhs, lhs.y / rhs); + return result; +} + +DN_API DN_V2U16 operator/(DN_V2U16 lhs, DN_I32 rhs) +{ + DN_V2U16 result = DN_V2U16From2N(lhs.x / rhs, lhs.y / rhs); + return result; +} + +DN_API DN_V2U16 &operator*=(DN_V2U16 &lhs, DN_V2U16 rhs) +{ + lhs = lhs * rhs; + return lhs; +} + +DN_API DN_V2U16 &operator*=(DN_V2U16 &lhs, DN_F32 rhs) +{ + lhs = lhs * rhs; + return lhs; +} + +DN_API DN_V2U16 &operator*=(DN_V2U16 &lhs, DN_I32 rhs) +{ + lhs = lhs * rhs; + return lhs; +} + +DN_API DN_V2U16 &operator/=(DN_V2U16 &lhs, DN_V2U16 rhs) +{ + lhs = lhs / rhs; + return lhs; +} + +DN_API DN_V2U16 &operator/=(DN_V2U16 &lhs, DN_F32 rhs) +{ + lhs = lhs / rhs; + return lhs; +} + +DN_API DN_V2U16 &operator/=(DN_V2U16 &lhs, DN_I32 rhs) +{ + lhs = lhs / rhs; + return lhs; +} + +DN_API DN_V2U16 &operator-=(DN_V2U16 &lhs, DN_V2U16 rhs) +{ + lhs = lhs - rhs; + return lhs; +} + +DN_API DN_V2U16 &operator+=(DN_V2U16 &lhs, DN_V2U16 rhs) +{ + lhs = lhs + rhs; + return lhs; +} + +DN_API bool operator!=(DN_V2F32 lhs, DN_V2F32 rhs) +{ + bool result = !(lhs == rhs); + return result; +} + +DN_API bool operator==(DN_V2F32 lhs, DN_V2F32 rhs) +{ + bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y); + return result; +} + +DN_API bool operator>=(DN_V2F32 lhs, DN_V2F32 rhs) +{ + bool result = (lhs.x >= rhs.x) && (lhs.y >= rhs.y); + return result; +} + +DN_API bool operator<=(DN_V2F32 lhs, DN_V2F32 rhs) +{ + bool result = (lhs.x <= rhs.x) && (lhs.y <= rhs.y); + return result; +} + +DN_API bool operator<(DN_V2F32 lhs, DN_V2F32 rhs) +{ + bool result = (lhs.x < rhs.x) && (lhs.y < rhs.y); + return result; +} + +DN_API bool operator>(DN_V2F32 lhs, DN_V2F32 rhs) +{ + bool result = (lhs.x > rhs.x) && (lhs.y > rhs.y); + return result; +} + +DN_API DN_V2F32 operator-(DN_V2F32 lhs) +{ + DN_V2F32 result = DN_V2F32From2N(-lhs.x, -lhs.y); + return result; +} + +DN_API DN_V2F32 operator-(DN_V2F32 lhs, DN_V2F32 rhs) +{ + DN_V2F32 result = DN_V2F32From2N(lhs.x - rhs.x, lhs.y - rhs.y); + return result; +} + +DN_API DN_V2F32 operator-(DN_V2F32 lhs, DN_V2I32 rhs) +{ + DN_V2F32 result = DN_V2F32From2N(lhs.x - rhs.x, lhs.y - rhs.y); + return result; +} + +DN_API DN_V2F32 operator-(DN_V2F32 lhs, DN_F32 rhs) +{ + DN_V2F32 result = DN_V2F32From2N(lhs.x - rhs, lhs.y - rhs); + return result; +} + +DN_API DN_V2F32 operator-(DN_V2F32 lhs, DN_I32 rhs) +{ + DN_V2F32 result = DN_V2F32From2N(lhs.x - rhs, lhs.y - rhs); + return result; +} + +DN_API DN_V2F32 operator+(DN_V2F32 lhs, DN_V2F32 rhs) +{ + DN_V2F32 result = DN_V2F32From2N(lhs.x + rhs.x, lhs.y + rhs.y); + return result; +} + +DN_API DN_V2F32 operator+(DN_V2F32 lhs, DN_V2I32 rhs) +{ + DN_V2F32 result = DN_V2F32From2N(lhs.x + rhs.x, lhs.y + rhs.y); + return result; +} + +DN_API DN_V2F32 operator+(DN_V2F32 lhs, DN_F32 rhs) +{ + DN_V2F32 result = DN_V2F32From2N(lhs.x + rhs, lhs.y + rhs); + return result; +} + +DN_API DN_V2F32 operator+(DN_V2F32 lhs, DN_I32 rhs) +{ + DN_V2F32 result = DN_V2F32From2N(lhs.x + rhs, lhs.y + rhs); + return result; +} + +DN_API DN_V2F32 operator*(DN_V2F32 lhs, DN_V2F32 rhs) +{ + DN_V2F32 result = DN_V2F32From2N(lhs.x * rhs.x, lhs.y * rhs.y); + return result; +} + +DN_API DN_V2F32 operator*(DN_V2F32 lhs, DN_V2I32 rhs) +{ + DN_V2F32 result = DN_V2F32From2N(lhs.x * rhs.x, lhs.y * rhs.y); + return result; +} + +DN_API DN_V2F32 operator*(DN_V2F32 lhs, DN_F32 rhs) +{ + DN_V2F32 result = DN_V2F32From2N(lhs.x * rhs, lhs.y * rhs); + return result; +} + +DN_API DN_V2F32 operator*(DN_V2F32 lhs, DN_I32 rhs) +{ + DN_V2F32 result = DN_V2F32From2N(lhs.x * rhs, lhs.y * rhs); + return result; +} + +DN_API DN_V2F32 operator/(DN_V2F32 lhs, DN_V2F32 rhs) +{ + DN_V2F32 result = DN_V2F32From2N(lhs.x / rhs.x, lhs.y / rhs.y); + return result; +} + +DN_API DN_V2F32 operator/(DN_V2F32 lhs, DN_V2I32 rhs) +{ + DN_V2F32 result = DN_V2F32From2N(lhs.x / rhs.x, lhs.y / rhs.y); + return result; +} + +DN_API DN_V2F32 operator/(DN_V2F32 lhs, DN_F32 rhs) +{ + DN_V2F32 result = DN_V2F32From2N(lhs.x / rhs, lhs.y / rhs); + return result; +} + +DN_API DN_V2F32 operator/(DN_V2F32 lhs, DN_I32 rhs) +{ + DN_V2F32 result = DN_V2F32From2N(lhs.x / rhs, lhs.y / rhs); + return result; +} + +DN_API DN_V2F32 &operator*=(DN_V2F32 &lhs, DN_V2F32 rhs) +{ + lhs = lhs * rhs; + return lhs; +} + +DN_API DN_V2F32 &operator*=(DN_V2F32 &lhs, DN_V2I32 rhs) +{ + lhs = lhs * rhs; + return lhs; +} + +DN_API DN_V2F32 &operator*=(DN_V2F32 &lhs, DN_F32 rhs) +{ + lhs = lhs * rhs; + return lhs; +} + +DN_API DN_V2F32 &operator*=(DN_V2F32 &lhs, DN_I32 rhs) +{ + lhs = lhs * rhs; + return lhs; +} + +DN_API DN_V2F32 &operator/=(DN_V2F32 &lhs, DN_V2F32 rhs) +{ + lhs = lhs / rhs; + return lhs; +} + +DN_API DN_V2F32 &operator/=(DN_V2F32 &lhs, DN_V2I32 rhs) +{ + lhs = lhs / rhs; + return lhs; +} + +DN_API DN_V2F32 &operator/=(DN_V2F32 &lhs, DN_F32 rhs) +{ + lhs = lhs / rhs; + return lhs; +} + +DN_API DN_V2F32 &operator/=(DN_V2F32 &lhs, DN_I32 rhs) +{ + lhs = lhs / rhs; + return lhs; +} + +DN_API DN_V2F32 &operator-=(DN_V2F32 &lhs, DN_V2F32 rhs) +{ + lhs = lhs - rhs; + return lhs; +} + +DN_API DN_V2F32 &operator-=(DN_V2F32 &lhs, DN_V2I32 rhs) +{ + lhs = lhs - rhs; + return lhs; +} + +DN_API DN_V2F32 &operator-=(DN_V2F32 &lhs, DN_F32 rhs) +{ + lhs = lhs - rhs; + return lhs; +} + +DN_API DN_V2F32 &operator-=(DN_V2F32 &lhs, DN_I32 rhs) +{ + lhs = lhs - rhs; + return lhs; +} + +DN_API DN_V2F32 &operator+=(DN_V2F32 &lhs, DN_V2F32 rhs) +{ + lhs = lhs + rhs; + return lhs; +} + +DN_API DN_V2F32 &operator+=(DN_V2F32 &lhs, DN_V2I32 rhs) +{ + lhs = lhs + rhs; + return lhs; +} + +DN_API DN_V2F32 &operator+=(DN_V2F32 &lhs, DN_F32 rhs) +{ + lhs = lhs + rhs; + return lhs; +} + +DN_API DN_V2F32 &operator+=(DN_V2F32 &lhs, DN_I32 rhs) +{ + lhs = lhs + rhs; + return lhs; +} + +DN_API DN_V2F32 DN_V2F32Min(DN_V2F32 a, DN_V2F32 b) +{ + DN_V2F32 result = DN_V2F32From2N(DN_Min(a.x, b.x), DN_Min(a.y, b.y)); + return result; +} + +DN_API DN_V2F32 DN_V2F32Max(DN_V2F32 a, DN_V2F32 b) +{ + DN_V2F32 result = DN_V2F32From2N(DN_Max(a.x, b.x), DN_Max(a.y, b.y)); + return result; +} + +DN_API DN_V2F32 DN_V2F32Abs(DN_V2F32 a) +{ + DN_V2F32 result = DN_V2F32From2N(DN_Abs(a.x), DN_Abs(a.y)); + return result; +} + +DN_API DN_F32 DN_V2F32Dot(DN_V2F32 a, DN_V2F32 b) +{ + // NOTE: Scalar projection of B onto A ///////////////////////////////////////////////////////// + // + // Scalar projection calculates the signed distance between `b` and `a` + // where `a` is a unit vector then, the dot product calculates the projection + // of `b` onto the infinite line that the direction of `a` represents. This + // calculation is the signed distance. + // + // signed_distance = dot_product(a, b) = (a.x * b.x) + (a.y * b.y) + // + // Y + // ^ b + // | /| + // | / | + // | / | + // | / | Projection + // | / | + // |/ V + // +--->--------> X + // . a . + // . . + // |------| <- Calculated signed distance + // + // The signed-ness of the result indicates the relationship: + // + // Distance <0 means `b` is behind `a` + // Distance >0 means `b` is in-front of `a` + // Distance ==0 means `b` is perpendicular to `a` + // + // If `a` is not normalized then the signed-ness of the result still holds + // however result no longer represents the actual distance between the + // 2 objects. One of the vectors must be normalised (e.g. turned into a unit + // vector). + // + // NOTE: DN_V projection ///////////////////////////////////////////////////////////////////// + // + // DN_V projection calculates the exact X,Y coordinates of where `b` meets + // `a` when it was projected. This is calculated by multipying the + // 'scalar projection' result by the unit vector of `a` + // + // vector_projection = a * signed_distance = a * dot_product(a, b) + + DN_F32 result = (a.x * b.x) + (a.y * b.y); + return result; +} + +DN_API DN_F32 DN_V2F32LengthSq2V2(DN_V2F32 lhs, DN_V2F32 rhs) +{ + // NOTE: Pythagoras's theorem (a^2 + b^2 = c^2) without the square root + DN_F32 a = rhs.x - lhs.x; + DN_F32 b = rhs.y - lhs.y; + DN_F32 c_squared = DN_Squared(a) + DN_Squared(b); + DN_F32 result = c_squared; + return result; +} + +DN_API bool DN_V2F32LengthSqIsWithin2V2(DN_V2F32 lhs, DN_V2F32 rhs, DN_F32 within_amount_sq) +{ + DN_F32 dist = DN_V2F32LengthSq2V2(lhs, rhs); + bool result = dist <= within_amount_sq; + return result; +} + +DN_API DN_F32 DN_V2F32Length2V2(DN_V2F32 lhs, DN_V2F32 rhs) +{ + DN_F32 result_squared = DN_V2F32LengthSq2V2(lhs, rhs); + DN_F32 result = DN_SqrtF32(result_squared); + return result; +} + +DN_API DN_F32 DN_V2F32LengthSq(DN_V2F32 lhs) +{ + // NOTE: Pythagoras's theorem without the square root + DN_F32 c_squared = DN_Squared(lhs.x) + DN_Squared(lhs.y); + DN_F32 result = c_squared; + return result; +} + +DN_API DN_F32 DN_V2F32Length(DN_V2F32 lhs) +{ + DN_F32 c_squared = DN_V2F32LengthSq(lhs); + DN_F32 result = DN_SqrtF32(c_squared); + return result; +} + +DN_API DN_V2F32 DN_V2F32Normalise(DN_V2F32 a) +{ + DN_F32 length = DN_V2F32Length(a); + DN_V2F32 result = a / length; + return result; +} + +DN_API DN_V2F32 DN_V2F32Perpendicular(DN_V2F32 a) +{ + // NOTE: Matrix form of a 2D vector can be defined as + // + // x' = x cos(t) - y sin(t) + // y' = x sin(t) + y cos(t) + // + // Calculate a line perpendicular to a vector means rotating the vector by + // 90 degrees + // + // x' = x cos(90) - y sin(90) + // y' = x sin(90) + y cos(90) + // + // Where `cos(90) = 0` and `sin(90) = 1` then, + // + // x' = -y + // y' = +x + + DN_V2F32 result = DN_V2F32From2N(-a.y, a.x); + return result; +} + +DN_API DN_V2F32 DN_V2F32Reflect(DN_V2F32 in, DN_V2F32 surface) +{ + DN_V2F32 normal = DN_V2F32Perpendicular(surface); + DN_V2F32 normal_norm = DN_V2F32Normalise(normal); + DN_F32 signed_dist = DN_V2F32Dot(in, normal_norm); + DN_V2F32 result = DN_V2F32From2N(in.x, in.y + (-signed_dist * 2.f)); + return result; +} + +DN_API DN_F32 DN_V2F32Area(DN_V2F32 a) +{ + DN_F32 result = a.w * a.h; + return result; +} + +DN_API bool operator!=(DN_V3F32 lhs, DN_V3F32 rhs) +{ + bool result = !(lhs == rhs); + return result; +} + +DN_API bool operator==(DN_V3F32 lhs, DN_V3F32 rhs) +{ + bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y) && (lhs.z == rhs.z); + return result; +} + +DN_API bool operator>=(DN_V3F32 lhs, DN_V3F32 rhs) +{ + bool result = (lhs.x >= rhs.x) && (lhs.y >= rhs.y) && (lhs.z >= rhs.z); + return result; +} + +DN_API bool operator<=(DN_V3F32 lhs, DN_V3F32 rhs) +{ + bool result = (lhs.x <= rhs.x) && (lhs.y <= rhs.y) && (lhs.z <= rhs.z); + return result; +} + +DN_API bool operator<(DN_V3F32 lhs, DN_V3F32 rhs) +{ + bool result = (lhs.x < rhs.x) && (lhs.y < rhs.y) && (lhs.z < rhs.z); + return result; +} + +DN_API bool operator>(DN_V3F32 lhs, DN_V3F32 rhs) +{ + bool result = (lhs.x > rhs.x) && (lhs.y > rhs.y) && (lhs.z > rhs.z); + return result; +} + +DN_API DN_V3F32 operator-(DN_V3F32 lhs, DN_V3F32 rhs) +{ + DN_V3F32 result = DN_V3F32From3N(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z); + return result; +} + +DN_API DN_V3F32 operator-(DN_V3F32 lhs) +{ + DN_V3F32 result = DN_V3F32From3N(-lhs.x, -lhs.y, -lhs.z); + return result; +} + +DN_API DN_V3F32 operator+(DN_V3F32 lhs, DN_V3F32 rhs) +{ + DN_V3F32 result = DN_V3F32From3N(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z); + return result; +} + +DN_API DN_V3F32 operator*(DN_V3F32 lhs, DN_V3F32 rhs) +{ + DN_V3F32 result = DN_V3F32From3N(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z); + return result; +} + +DN_API DN_V3F32 operator*(DN_V3F32 lhs, DN_F32 rhs) +{ + DN_V3F32 result = DN_V3F32From3N(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs); + return result; +} + +DN_API DN_V3F32 operator*(DN_V3F32 lhs, DN_I32 rhs) +{ + DN_V3F32 result = DN_V3F32From3N(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs); + return result; +} + +DN_API DN_V3F32 operator/(DN_V3F32 lhs, DN_V3F32 rhs) +{ + DN_V3F32 result = DN_V3F32From3N(lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z); + return result; +} + +DN_API DN_V3F32 operator/(DN_V3F32 lhs, DN_F32 rhs) +{ + DN_V3F32 result = DN_V3F32From3N(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs); + return result; +} + +DN_API DN_V3F32 operator/(DN_V3F32 lhs, DN_I32 rhs) +{ + DN_V3F32 result = DN_V3F32From3N(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs); + return result; +} + +DN_API DN_V3F32 &operator*=(DN_V3F32 &lhs, DN_V3F32 rhs) +{ + lhs = lhs * rhs; + return lhs; +} + +DN_API DN_V3F32 &operator*=(DN_V3F32 &lhs, DN_F32 rhs) +{ + lhs = lhs * rhs; + return lhs; +} + +DN_API DN_V3F32 &operator*=(DN_V3F32 &lhs, DN_I32 rhs) +{ + lhs = lhs * rhs; + return lhs; +} + +DN_API DN_V3F32 &operator/=(DN_V3F32 &lhs, DN_V3F32 rhs) +{ + lhs = lhs / rhs; + return lhs; +} + +DN_API DN_V3F32 &operator/=(DN_V3F32 &lhs, DN_F32 rhs) +{ + lhs = lhs / rhs; + return lhs; +} + +DN_API DN_V3F32 &operator/=(DN_V3F32 &lhs, DN_I32 rhs) +{ + lhs = lhs / rhs; + return lhs; +} + +DN_API DN_V3F32 &operator-=(DN_V3F32 &lhs, DN_V3F32 rhs) +{ + lhs = lhs - rhs; + return lhs; +} + +DN_API DN_V3F32 &operator+=(DN_V3F32 &lhs, DN_V3F32 rhs) +{ + lhs = lhs + rhs; + return lhs; +} + +DN_API DN_F32 DN_V3_LengthSq(DN_V3F32 a) +{ + DN_F32 result = DN_Squared(a.x) + DN_Squared(a.y) + DN_Squared(a.z); + return result; +} + +DN_API DN_F32 DN_V3_Length(DN_V3F32 a) +{ + DN_F32 length_sq = DN_Squared(a.x) + DN_Squared(a.y) + DN_Squared(a.z); + DN_F32 result = DN_SqrtF32(length_sq); + return result; +} + +DN_API DN_V3F32 DN_V3_Normalise(DN_V3F32 a) +{ + DN_F32 length = DN_V3_Length(a); + DN_V3F32 result = a / length; + return result; +} + +DN_API DN_V4F32 DN_V4F32FromRGBU32(DN_U32 u32) +{ + DN_U8 r = (DN_U8)((u32 & 0x00FF0000) >> 16); + DN_U8 g = (DN_U8)((u32 & 0x0000FF00) >> 8); + DN_U8 b = (DN_U8)((u32 & 0x000000FF) >> 0); + DN_V4F32 result = DN_V4F32FromRGBU8(r, g, b); + return result; +} + +DN_API DN_V4F32 DN_V4F32FromRGBAU32(DN_U32 u32) +{ + DN_U8 r = (DN_U8)((u32 & 0xFF000000) >> 24); + DN_U8 g = (DN_U8)((u32 & 0x00FF0000) >> 16); + DN_U8 b = (DN_U8)((u32 & 0x0000FF00) >> 8); + DN_U8 a = (DN_U8)((u32 & 0x000000FF) >> 0); + DN_V4F32 result = DN_V4F32FromRGBAU8(r, g, b, a); + return result; +} + +DN_API bool operator==(DN_V4F32 lhs, DN_V4F32 rhs) +{ + bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y) && (lhs.z == rhs.z) && (lhs.w == rhs.w); + return result; +} + +DN_API bool operator!=(DN_V4F32 lhs, DN_V4F32 rhs) +{ + bool result = !(lhs == rhs); + return result; +} + +DN_API bool operator>=(DN_V4F32 lhs, DN_V4F32 rhs) +{ + bool result = (lhs.x >= rhs.x) && (lhs.y >= rhs.y) && (lhs.z >= rhs.z) && (lhs.w >= rhs.w); + return result; +} + +DN_API bool operator<=(DN_V4F32 lhs, DN_V4F32 rhs) +{ + bool result = (lhs.x <= rhs.x) && (lhs.y <= rhs.y) && (lhs.z <= rhs.z) && (lhs.w <= rhs.w); + return result; +} + +DN_API bool operator<(DN_V4F32 lhs, DN_V4F32 rhs) +{ + bool result = (lhs.x < rhs.x) && (lhs.y < rhs.y) && (lhs.z < rhs.z) && (lhs.w < rhs.w); + return result; +} + +DN_API bool operator>(DN_V4F32 lhs, DN_V4F32 rhs) +{ + bool result = (lhs.x > rhs.x) && (lhs.y > rhs.y) && (lhs.z > rhs.z) && (lhs.w > rhs.w); + return result; +} + +DN_API DN_V4F32 operator-(DN_V4F32 lhs, DN_V4F32 rhs) +{ + DN_V4F32 result = DN_V4F32From4N(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w); + return result; +} + +DN_API DN_V4F32 operator-(DN_V4F32 lhs) +{ + DN_V4F32 result = DN_V4F32From4N(-lhs.x, -lhs.y, -lhs.z, -lhs.w); + return result; +} + +DN_API DN_V4F32 operator+(DN_V4F32 lhs, DN_V4F32 rhs) +{ + DN_V4F32 result = DN_V4F32From4N(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w); + return result; +} + +DN_API DN_V4F32 operator*(DN_V4F32 lhs, DN_V4F32 rhs) +{ + DN_V4F32 result = DN_V4F32From4N(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w); + return result; +} + +DN_API DN_V4F32 operator*(DN_V4F32 lhs, DN_F32 rhs) +{ + DN_V4F32 result = DN_V4F32From4N(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs); + return result; +} + +DN_API DN_V4F32 operator*(DN_V4F32 lhs, DN_I32 rhs) +{ + DN_V4F32 result = DN_V4F32From4N(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs); + return result; +} + +DN_API DN_V4F32 operator/(DN_V4F32 lhs, DN_F32 rhs) +{ + DN_V4F32 result = DN_V4F32From4N(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs, lhs.w / rhs); + return result; +} + +DN_API DN_V4F32 &operator*=(DN_V4F32 &lhs, DN_V4F32 rhs) +{ + lhs = lhs * rhs; + return lhs; +} + +DN_API DN_V4F32 &operator*=(DN_V4F32 &lhs, DN_F32 rhs) +{ + lhs = lhs * rhs; + return lhs; +} + +DN_API DN_V4F32 &operator*=(DN_V4F32 &lhs, DN_I32 rhs) +{ + lhs = lhs * rhs; + return lhs; +} + +DN_API DN_V4F32 &operator-=(DN_V4F32 &lhs, DN_V4F32 rhs) +{ + lhs = lhs - rhs; + return lhs; +} + +DN_API DN_V4F32 &operator+=(DN_V4F32 &lhs, DN_V4F32 rhs) +{ + lhs = lhs + rhs; + return lhs; +} + +DN_API DN_F32 DN_V4F32Dot(DN_V4F32 a, DN_V4F32 b) +{ + DN_F32 result = (a.x * b.x) + (a.y * b.y) + (a.z * b.z) + (a.w * b.w); + return result; +} + +DN_API DN_M4 DN_M4Identity() +{ + DN_M4 result = + { + { + {1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {0, 0, 0, 1}, + } + }; + + return result; +} + +DN_API DN_M4 DN_M4ScaleF(DN_F32 x, DN_F32 y, DN_F32 z) +{ + DN_M4 result = + { + { + {x, 0, 0, 0}, + {0, y, 0, 0}, + {0, 0, z, 0}, + {0, 0, 0, 1}, + } + }; + + return result; +} + +DN_API DN_M4 DN_M4Scale(DN_V3F32 xyz) +{ + DN_M4 result = + { + { + {xyz.x, 0, 0, 0}, + {0, xyz.y, 0, 0}, + {0, 0, xyz.z, 0}, + {0, 0, 0, 1}, + } + }; + + return result; +} + +DN_API DN_M4 DN_M4TranslateF(DN_F32 x, DN_F32 y, DN_F32 z) +{ + DN_M4 result = + { + { + {1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {x, y, z, 1}, + } + }; + + return result; +} + +DN_API DN_M4 DN_M4Translate(DN_V3F32 xyz) +{ + DN_M4 result = + { + { + {1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {xyz.x, xyz.y, xyz.z, 1}, + } + }; + + return result; +} + +DN_API DN_M4 DN_M4Transpose(DN_M4 mat) +{ + DN_M4 result = {}; + for (int col = 0; col < 4; col++) + for (int row = 0; row < 4; row++) + result.columns[col][row] = mat.columns[row][col]; + return result; +} + +DN_API DN_M4 DN_M4Rotate(DN_V3F32 axis01, DN_F32 radians) +{ + DN_AssertF(DN_Abs(DN_V3_Length(axis01) - 1.f) <= 0.01f, + "Rotation axis must be normalised, length = %f", + DN_V3_Length(axis01)); + + DN_F32 sin = DN_SinF32(radians); + DN_F32 cos = DN_CosF32(radians); + DN_F32 one_minus_cos = 1.f - cos; + + DN_F32 x = axis01.x; + DN_F32 y = axis01.y; + DN_F32 z = axis01.z; + DN_F32 x2 = DN_Squared(x); + DN_F32 y2 = DN_Squared(y); + DN_F32 z2 = DN_Squared(z); + + DN_M4 result = + { + { + {cos + x2 * one_minus_cos, y * x * one_minus_cos + z * sin, z * x * one_minus_cos - y * sin, 0}, // Col 1 + {x * y * one_minus_cos - z * sin, cos + y2 * one_minus_cos, z * y * one_minus_cos + x * sin, 0}, // Col 2 + {x * z * one_minus_cos + y * sin, y * z * one_minus_cos - x * sin, cos + z2 * one_minus_cos, 0}, // Col 3 + {0, 0, 0, 1}, // Col 4 + } + }; + + return result; +} + +DN_API DN_M4 DN_M4Orthographic(DN_F32 left, DN_F32 right, DN_F32 bottom, DN_F32 top, DN_F32 z_near, DN_F32 z_far) +{ + // NOTE: Here is the matrix in column major for readability. Below it's + // transposed due to how you have to declare column major matrices in C/C++. + // + // m = [2/r-l, 0, 0, -1*(r+l)/(r-l)] + // [0, 2/t-b, 0, 1*(t+b)/(t-b)] + // [0, 0, -2/f-n, -1*(f+n)/(f-n)] + // [0, 0, 0, 1 ] + + DN_M4 result = + { + { + {2.f / (right - left), 0.f, 0.f, 0.f}, + {0.f, 2.f / (top - bottom), 0.f, 0.f}, + {0.f, 0.f, -2.f / (z_far - z_near), 0.f}, + {(-1.f * (right + left)) / (right - left), (-1.f * (top + bottom)) / (top - bottom), (-1.f * (z_far + z_near)) / (z_far - z_near), 1.f}, + } + }; + + return result; +} + +DN_API DN_M4 DN_M4Perspective(DN_F32 fov /*radians*/, DN_F32 aspect, DN_F32 z_near, DN_F32 z_far) +{ + DN_F32 tan_fov = DN_TanF32(fov / 2.f); + DN_M4 result = + { + { + {1.f / (aspect * tan_fov), 0.f, 0.f, 0.f}, + {0, 1.f / tan_fov, 0.f, 0.f}, + {0.f, 0.f, (z_near + z_far) / (z_near - z_far), -1.f}, + {0.f, 0.f, (2.f * z_near * z_far) / (z_near - z_far), 0.f}, + } + }; + + return result; +} + +DN_API DN_M4 DN_M4Add(DN_M4 lhs, DN_M4 rhs) +{ + DN_M4 result; + for (int col = 0; col < 4; col++) + for (int it = 0; it < 4; it++) + result.columns[col][it] = lhs.columns[col][it] + rhs.columns[col][it]; + return result; +} + +DN_API DN_M4 DN_M4Sub(DN_M4 lhs, DN_M4 rhs) +{ + DN_M4 result; + for (int col = 0; col < 4; col++) + for (int it = 0; it < 4; it++) + result.columns[col][it] = lhs.columns[col][it] - rhs.columns[col][it]; + return result; +} + +DN_API DN_M4 DN_M4Mul(DN_M4 lhs, DN_M4 rhs) +{ + DN_M4 result; + for (int col = 0; col < 4; col++) { + for (int row = 0; row < 4; row++) { + DN_F32 sum = 0; + for (int f32_it = 0; f32_it < 4; f32_it++) + sum += lhs.columns[f32_it][row] * rhs.columns[col][f32_it]; + + result.columns[col][row] = sum; + } + } + return result; +} + +DN_API DN_M4 DN_M4Div(DN_M4 lhs, DN_M4 rhs) +{ + DN_M4 result; + for (int col = 0; col < 4; col++) + for (int it = 0; it < 4; it++) + result.columns[col][it] = lhs.columns[col][it] / rhs.columns[col][it]; + return result; +} + +DN_API DN_M4 DN_M4AddF(DN_M4 lhs, DN_F32 rhs) +{ + DN_M4 result; + for (int col = 0; col < 4; col++) + for (int it = 0; it < 4; it++) + result.columns[col][it] = lhs.columns[col][it] + rhs; + return result; +} + +DN_API DN_M4 DN_M4SubF(DN_M4 lhs, DN_F32 rhs) +{ + DN_M4 result; + for (int col = 0; col < 4; col++) + for (int it = 0; it < 4; it++) + result.columns[col][it] = lhs.columns[col][it] - rhs; + return result; +} + +DN_API DN_M4 DN_M4MulF(DN_M4 lhs, DN_F32 rhs) +{ + DN_M4 result; + for (int col = 0; col < 4; col++) + for (int it = 0; it < 4; it++) + result.columns[col][it] = lhs.columns[col][it] * rhs; + return result; +} + +DN_API DN_M4 DN_M4DivF(DN_M4 lhs, DN_F32 rhs) +{ + DN_M4 result; + for (int col = 0; col < 4; col++) + for (int it = 0; it < 4; it++) + result.columns[col][it] = lhs.columns[col][it] / rhs; + return result; +} + +DN_API DN_Str8x256 DN_M4ColumnMajorString(DN_M4 mat) +{ + DN_Str8x256 result = {}; + for (int row = 0; row < 4; row++) { + for (int it = 0; it < 4; it++) { + if (it == 0) + DN_FmtAppend(result.data, &result.size, sizeof(result.data), "|"); + DN_FmtAppend(result.data, &result.size, sizeof(result.data), "%.5f", mat.columns[it][row]); + if (it != 3) + DN_FmtAppend(result.data, &result.size, sizeof(result.data), ", "); + else + DN_FmtAppend(result.data, &result.size, sizeof(result.data), "|\n"); + } + } + return result; +} + +DN_API bool operator==(DN_M2x3 const &lhs, DN_M2x3 const &rhs) +{ + bool result = DN_Memcmp(lhs.e, rhs.e, sizeof(lhs.e[0]) * DN_ArrayCountU(lhs.e)) == 0; + return result; +} + +DN_API bool operator!=(DN_M2x3 const &lhs, DN_M2x3 const &rhs) +{ + bool result = !(lhs == rhs); + return result; +} + +DN_API DN_M2x3 DN_M2x3Identity() +{ + DN_M2x3 result = { + { + 1, + 0, + 0, + 0, + 1, + 0, + } + }; + return result; +} + +DN_API DN_M2x3 DN_M2x3Translate(DN_V2F32 offset) +{ + DN_M2x3 result = { + { + 1, + 0, + offset.x, + 0, + 1, + offset.y, + } + }; + return result; +} + +DN_API DN_V2F32 DN_M2x3ScaleGet(DN_M2x3 m2x3) +{ + DN_V2F32 result = DN_V2F32From2N(m2x3.row[0][0], m2x3.row[1][1]); + return result; +} + +DN_API DN_M2x3 DN_M2x3Scale(DN_V2F32 scale) +{ + DN_M2x3 result = {{ + scale.x, 0, 0, + 0, scale.y, 0, + }}; + return result; +} + +DN_API DN_M2x3 DN_M2x3Rotate(DN_F32 radians) +{ + DN_M2x3 result = { + { + DN_CosF32(radians), + DN_SinF32(radians), + 0, + -DN_SinF32(radians), + DN_CosF32(radians), + 0, + } + }; + return result; +} + +DN_API DN_M2x3 DN_M2x3Mul(DN_M2x3 m1, DN_M2x3 m2) +{ + // NOTE: Ordinarily you can't multiply M2x3 with M2x3 because column count + // (3) != row count (2). We pretend we have two 3x3 matrices with the last + // row set to [0 0 1] and perform a 3x3 matrix multiply. + // + // | (0)a (1)b (2)c | | (0)g (1)h (2)i | + // | (3)d (4)e (5)f | x | (3)j (4)k (5)l | + // | (6)0 (7)0 (8)1 | | (6)0 (7)0 (8)1 | + + DN_M2x3 result = { + { + m1.e[0] * m2.e[0] + m1.e[1] * m2.e[3], // a*g + b*j + c*0[omitted], + m1.e[0] * m2.e[1] + m1.e[1] * m2.e[4], // a*h + b*k + c*0[omitted], + m1.e[0] * m2.e[2] + m1.e[1] * m2.e[5] + m1.e[2], // a*i + b*l + c*1, + + m1.e[3] * m2.e[0] + m1.e[4] * m2.e[3], // d*g + e*j + f*0[omitted], + m1.e[3] * m2.e[1] + m1.e[4] * m2.e[4], // d*h + e*k + f*0[omitted], + m1.e[3] * m2.e[2] + m1.e[4] * m2.e[5] + m1.e[5], // d*i + e*l + f*1, + } + }; + + return result; +} + +DN_API DN_V2F32 DN_M2x3Mul2F32(DN_M2x3 m1, DN_F32 x, DN_F32 y) +{ + // NOTE: Ordinarily you can't multiply M2x3 with V2 because column count (3) + // != row count (2). We pretend we have a V3 with `z` set to `1`. + // + // | (0)a (1)b (2)c | | x | + // | (3)d (4)e (5)f | x | y | + // | 1 | + + DN_V2F32 result = { + { + m1.e[0] * x + m1.e[1] * y + m1.e[2], // a*x + b*y + c*1 + m1.e[3] * x + m1.e[4] * y + m1.e[5], // d*x + e*y + f*1 + } + }; + return result; +} + +DN_API DN_V2F32 DN_M2x3MulV2F32(DN_M2x3 m1, DN_V2F32 v2) +{ + DN_V2F32 result = DN_M2x3Mul2F32(m1, v2.x, v2.y); + return result; +} + +DN_API bool operator==(const DN_Rect &lhs, const DN_Rect &rhs) +{ + bool result = (lhs.pos == rhs.pos) && (lhs.size == rhs.size); + return result; +} + +DN_API DN_V2F32 DN_RectCenter(DN_Rect rect) +{ + DN_V2F32 result = rect.pos + (rect.size * .5f); + return result; +} + +DN_API bool DN_RectContainsPoint(DN_Rect rect, DN_V2F32 p) +{ + DN_V2F32 min = rect.pos; + DN_V2F32 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; +} + +DN_API bool DN_RectContainsRect(DN_Rect a, DN_Rect b) +{ + DN_V2F32 a_min = a.pos; + DN_V2F32 a_max = a.pos + a.size; + DN_V2F32 b_min = b.pos; + DN_V2F32 b_max = b.pos + b.size; + bool result = (b_min >= a_min && b_max <= a_max); + return result; +} + +DN_API DN_Rect DN_RectExpand(DN_Rect a, DN_F32 amount) +{ + DN_Rect result = a; + result.pos -= amount; + result.size += (amount * 2.f); + return result; +} + +DN_API DN_Rect DN_RectExpandV2(DN_Rect a, DN_V2F32 amount) +{ + DN_Rect result = a; + result.pos -= amount; + result.size += (amount * 2.f); + return result; +} + +DN_API bool DN_RectIntersects(DN_Rect a, DN_Rect b) +{ + DN_V2F32 a_min = a.pos; + DN_V2F32 a_max = a.pos + a.size; + DN_V2F32 b_min = b.pos; + DN_V2F32 b_max = b.pos + b.size; + bool has_size = a.size.x && a.size.y && b.size.x && b.size.y; + bool result = false; + if (has_size) + 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; +} + +DN_API DN_Rect DN_RectIntersection(DN_Rect a, DN_Rect b) +{ + DN_Rect result = DN_RectFrom2V2(a.pos, DN_V2F32From1N(0)); + if (DN_RectIntersects(a, b)) { + DN_V2F32 a_min = a.pos; + DN_V2F32 a_max = a.pos + a.size; + DN_V2F32 b_min = b.pos; + DN_V2F32 b_max = b.pos + b.size; + + DN_V2F32 min = {}; + DN_V2F32 max = {}; + min.x = DN_Max(a_min.x, b_min.x); + min.y = DN_Max(a_min.y, b_min.y); + max.x = DN_Min(a_max.x, b_max.x); + max.y = DN_Min(a_max.y, b_max.y); + result = DN_RectFrom2V2(min, max - min); + } + return result; +} + +DN_API DN_Rect DN_RectUnion(DN_Rect a, DN_Rect b) +{ + DN_V2F32 a_min = a.pos; + DN_V2F32 a_max = a.pos + a.size; + DN_V2F32 b_min = b.pos; + DN_V2F32 b_max = b.pos + b.size; + + DN_V2F32 min, max; + min.x = DN_Min(a_min.x, b_min.x); + min.y = DN_Min(a_min.y, b_min.y); + max.x = DN_Max(a_max.x, b_max.x); + max.y = DN_Max(a_max.y, b_max.y); + DN_Rect result = DN_RectFrom2V2(min, max - min); + return result; +} + +DN_API DN_RectMinMax DN_RectGetMinMax(DN_Rect a) +{ + DN_RectMinMax result = {}; + result.min = a.pos; + result.max = a.pos + a.size; + return result; +} + +DN_API DN_F32 DN_RectArea(DN_Rect a) +{ + DN_F32 result = a.size.w * a.size.h; + return result; +} + +DN_API DN_Rect DN_RectCutLeftClip(DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip) +{ + DN_F32 min_x = rect->pos.x; + DN_F32 max_x = rect->pos.x + rect->size.w; + DN_F32 result_max_x = min_x + amount; + if (clip) + result_max_x = DN_Min(result_max_x, max_x); + DN_Rect result = DN_RectFrom4N(min_x, rect->pos.y, result_max_x - min_x, rect->size.h); + rect->pos.x = result_max_x; + rect->size.w = max_x - result_max_x; + return result; +} + +DN_API DN_Rect DN_RectCutRightClip(DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip) +{ + DN_F32 min_x = rect->pos.x; + DN_F32 max_x = rect->pos.x + rect->size.w; + DN_F32 result_min_x = max_x - amount; + if (clip) + result_min_x = DN_Max(result_min_x, 0); + DN_Rect result = DN_RectFrom4N(result_min_x, rect->pos.y, max_x - result_min_x, rect->size.h); + rect->size.w = result_min_x - min_x; + return result; +} + +DN_API DN_Rect DN_RectCutTopClip(DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip) +{ + DN_F32 min_y = rect->pos.y; + DN_F32 max_y = rect->pos.y + rect->size.h; + DN_F32 result_max_y = min_y + amount; + if (clip) + result_max_y = DN_Min(result_max_y, max_y); + DN_Rect result = DN_RectFrom4N(rect->pos.x, min_y, rect->size.w, result_max_y - min_y); + rect->pos.y = result_max_y; + rect->size.h = max_y - result_max_y; + return result; +} + +DN_API DN_Rect DN_RectCutBottomClip(DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip) +{ + DN_F32 min_y = rect->pos.y; + DN_F32 max_y = rect->pos.y + rect->size.h; + DN_F32 result_min_y = max_y - amount; + if (clip) + result_min_y = DN_Max(result_min_y, 0); + DN_Rect result = DN_RectFrom4N(rect->pos.x, result_min_y, rect->size.w, max_y - result_min_y); + rect->size.h = result_min_y - min_y; + return result; +} + +DN_API DN_Rect DN_RectCutCut(DN_RectCut rect_cut, DN_V2F32 size, DN_RectCutClip clip) +{ + DN_Rect result = {}; + if (rect_cut.rect) { + switch (rect_cut.side) { + case DN_RectCutSide_Left: result = DN_RectCutLeftClip(rect_cut.rect, size.w, clip); break; + case DN_RectCutSide_Right: result = DN_RectCutRightClip(rect_cut.rect, size.w, clip); break; + case DN_RectCutSide_Top: result = DN_RectCutTopClip(rect_cut.rect, size.h, clip); break; + case DN_RectCutSide_Bottom: result = DN_RectCutBottomClip(rect_cut.rect, size.h, clip); break; + } + } + return result; +} + +DN_API DN_V2F32 DN_RectInterpV2F32(DN_Rect rect, DN_V2F32 t01) +{ + DN_V2F32 result = DN_V2F32From2N(rect.pos.w + (rect.size.w * t01.x), + rect.pos.h + (rect.size.h * t01.y)); + return result; +} + +DN_API DN_V2F32 DN_RectTopLeft(DN_Rect rect) +{ + DN_V2F32 result = DN_RectInterpV2F32(rect, DN_V2F32From2N(0, 0)); + return result; +} + +DN_API DN_V2F32 DN_RectTopRight(DN_Rect rect) +{ + DN_V2F32 result = DN_RectInterpV2F32(rect, DN_V2F32From2N(1, 0)); + return result; +} + +DN_API DN_V2F32 DN_RectBottomLeft(DN_Rect rect) +{ + DN_V2F32 result = DN_RectInterpV2F32(rect, DN_V2F32From2N(0, 1)); + return result; +} + +DN_API DN_V2F32 DN_RectBottomRight(DN_Rect rect) +{ + DN_V2F32 result = DN_RectInterpV2F32(rect, DN_V2F32From2N(1, 1)); + return result; +} + +DN_API DN_RaycastV2 DN_RaycastLineIntersectV2(DN_V2F32 origin_a, DN_V2F32 dir_a, DN_V2F32 origin_b, DN_V2F32 dir_b) +{ + // NOTE: Parametric equation of a line + // + // p = o + (t*d) + // + // - o is the starting 2d point + // - d is the direction of the line + // - t is a scalar that scales along the direction of the point + // + // To determine if a ray intersections a ray, we want to solve + // + // (o_a + (t_a * d_a)) = (o_b + (t_b * d_b)) + // + // Where '_a' and '_b' represent the 1st and 2nd point's origin, direction + // and 't' components respectively. This is 2 equations with 2 unknowns + // (`t_a` and `t_b`) which we can solve for by expressing the equation in + // terms of `t_a` and `t_b`. + // + // Working that math out produces the formula below for 't'. + + DN_RaycastV2 result = {}; + DN_F32 denominator = ((dir_b.y * dir_a.x) - (dir_b.x * dir_a.y)); + if (denominator != 0.0f) { + result.t_a = (((origin_a.y - origin_b.y) * dir_b.x) + ((origin_b.x - origin_a.x) * dir_b.y)) / denominator; + result.t_b = (((origin_a.y - origin_b.y) * dir_a.x) + ((origin_b.x - origin_a.x) * dir_a.y)) / denominator; + result.hit = true; + } + return result; +} + +DN_API DN_V2F32 DN_LerpV2F32(DN_V2F32 a, DN_F32 t, DN_V2F32 b) +{ + DN_V2F32 result = {}; + result.x = a.x + ((b.x - a.x) * t); + result.y = a.y + ((b.y - a.y) * t); + return result; +} + +DN_API DN_F32 DN_LerpF32(DN_F32 a, DN_F32 t, DN_F32 b) +{ + DN_F32 result = a + ((b - a) * t); + return result; +} diff --git a/Source/Base/dn_base.h b/Source/Base/dn_base.h index 2b26742..6590239 100644 --- a/Source/Base/dn_base.h +++ b/Source/Base/dn_base.h @@ -346,103 +346,6 @@ typedef DN_I32 DN_B32; #define DN_ISIZE_MAX INTPTR_MAX #define DN_ISIZE_MIN INTPTR_MIN -enum DN_ZMem -{ - DN_ZMem_No, // Memory can be handed out without zero-ing it out - DN_ZMem_Yes, // Memory should be zero-ed out before giving to the callee -}; - -struct DN_Str8 -{ - char *data; // The bytes of the string - DN_USize size; // The number of bytes in the string -}; - -struct DN_Str8Slice -{ - DN_Str8 *data; - DN_USize count; -}; - -struct DN_Str8x16 { char data[16]; DN_USize size; }; -struct DN_Str8x32 { char data[32]; DN_USize size; }; -struct DN_Str8x64 { char data[64]; DN_USize size; }; -struct DN_Str8x128 { char data[128]; DN_USize size; }; -struct DN_Str8x256 { char data[256]; DN_USize size; }; - -struct DN_Hex32 { char data[32]; }; -struct DN_Hex64 { char data[64]; }; -struct DN_Hex128 { char data[128]; }; - -struct DN_HexU64Str8 -{ - char data[(sizeof(DN_U64) * 2) + 1 /*null-terminator*/]; - DN_U8 size; -}; - -enum DN_HexFromU64Type -{ - DN_HexFromU64Type_Nil, - DN_HexFromU64Type_Uppercase, -}; - -struct DN_Str16 // A pointer and length style string that holds slices to UTF16 bytes. -{ - wchar_t *data; // The UTF16 bytes of the string - DN_USize size; // The number of characters in the string -}; - -struct DN_U8x16 { DN_U8 data[16]; }; -struct DN_U8x32 { DN_U8 data[32]; }; -struct DN_U8x64 { DN_U8 data[64]; }; - -template -struct DN_Slice // A pointer and length container of data -{ - T *data; - DN_USize size; - - T *begin() { return data; } - T *end() { return data + size; } - T const *begin() const { return data; } - T const *end() const { return data + size; } -}; - -struct DN_CallSite -{ - DN_Str8 file; - DN_Str8 function; - DN_U32 line; -}; - -#define DN_CALL_SITE DN_CallSite { DN_Str8Lit(__FILE__), DN_Str8Lit(__func__), __LINE__ } - -// NOTE: Defer Macro -#if defined(__cplusplus) -template -struct DN_Defer -{ - Procedure proc; - DN_Defer(Procedure p) : proc(p) {} - ~DN_Defer() { proc(); } -}; - -struct DN_DeferHelper -{ - template - DN_Defer operator+(Lambda lambda) { return DN_Defer(lambda); }; -}; - -#define DN_UniqueName(prefix) DN_TokenCombine(prefix, __LINE__) -#define DN_DEFER const auto DN_UniqueName(defer_lambda_) = DN_DeferHelper() + [&]() -#endif // defined(__cplusplus) - -#define DN_DeferLoop(begin, end) \ - bool DN_UniqueName(once) = (begin, true); \ - DN_UniqueName(once); \ - end, DN_UniqueName(once) = false - - // NOTE: Intrinsics // NOTE: DN_AtomicAdd/Exchange return the previous value store in the target #if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL) @@ -506,6 +409,42 @@ struct DN_DeferHelper #define DN_CountLeadingZerosUSize(value) DN_CountLeadingZerosU32(value) #endif +enum DN_ZMem +{ + DN_ZMem_No, // Memory can be handed out without zero-ing it out + DN_ZMem_Yes, // Memory should be zero-ed out before giving to the callee +}; + +struct DN_Str8 +{ + char *data; // The bytes of the string + DN_USize size; // The number of bytes in the string +}; + +struct DN_Str8Slice +{ + DN_Str8 *data; + DN_USize count; +}; + +struct DN_Str8x16 { char data[16]; DN_USize size; }; +struct DN_Str8x32 { char data[32]; DN_USize size; }; +struct DN_Str8x64 { char data[64]; DN_USize size; }; +struct DN_Str8x128 { char data[128]; DN_USize size; }; +struct DN_Str8x256 { char data[256]; DN_USize size; }; + +struct DN_Str16 // A pointer and length style string that holds slices to UTF16 bytes. +{ + wchar_t *data; // The UTF16 bytes of the string + DN_USize size; // The number of characters in the string +}; + +struct DN_Str16Slice +{ + DN_Str16 *data; + DN_USize count; +}; + struct DN_CPURegisters { int eax; @@ -611,6 +550,73 @@ struct DN_TicketMutex unsigned int volatile serving; // The ticket ID to block the mutex on until it is returned }; + +struct DN_Hex32 { char data[32]; }; +struct DN_Hex64 { char data[64]; }; +struct DN_Hex128 { char data[128]; }; + +struct DN_HexU64Str8 +{ + char data[(sizeof(DN_U64) * 2) + 1 /*null-terminator*/]; + DN_U8 size; +}; + +enum DN_HexFromU64Type +{ + DN_HexFromU64Type_Nil, + DN_HexFromU64Type_Uppercase, +}; + + +struct DN_U8x16 { DN_U8 data[16]; }; +struct DN_U8x32 { DN_U8 data[32]; }; +struct DN_U8x64 { DN_U8 data[64]; }; + +DN_MSVC_WARNING_PUSH +DN_MSVC_WARNING_DISABLE(4201) // warning C4201: nonstandard extension used: nameless struct/union +union DN_V2USize +{ + struct { DN_USize x, y; }; + struct { DN_USize w, h; }; + struct { DN_USize min, max; }; + struct { DN_USize begin, end; }; + DN_USize data[2]; +}; +DN_MSVC_WARNING_POP + +struct DN_CallSite +{ + DN_Str8 file; + DN_Str8 function; + DN_U32 line; +}; + +#define DN_CALL_SITE DN_CallSite { DN_Str8Lit(__FILE__), DN_Str8Lit(__func__), __LINE__ } + +#if defined(__cplusplus) +template +struct DN_Defer +{ + Procedure proc; + DN_Defer(Procedure p) : proc(p) {} + ~DN_Defer() { proc(); } +}; + +struct DN_DeferHelper +{ + template + DN_Defer operator+(Lambda lambda) { return DN_Defer(lambda); }; +}; + +#define DN_UniqueName(prefix) DN_TokenCombine(prefix, __LINE__) +#define DN_DEFER const auto DN_UniqueName(defer_lambda_) = DN_DeferHelper() + [&]() +#endif // defined(__cplusplus) + +#define DN_DeferLoop(begin, end) \ + bool DN_UniqueName(once) = (begin, true); \ + DN_UniqueName(once); \ + end, DN_UniqueName(once) = false + struct DN_U64FromResult { bool success; @@ -865,7 +871,8 @@ struct DN_Str8FindResult DN_Str8 start_to_before_match; // Substring from the start of the buffer up until the found string, not including it }; -enum DN_Str8FindFlag +typedef DN_USize DN_Str8FindFlag; +enum DN_Str8FindFlag_ { DN_Str8FindFlag_Digit = 1 << 0, // 0-9 DN_Str8FindFlag_Whitespace = 1 << 1, // '\r', '\t', '\n', ' ' @@ -1041,14 +1048,6 @@ struct DN_ErrSink DN_USize stack_size; }; -struct DN_TCLane -{ - DN_USize index; - DN_USize count; - DN_U64 barrier_handle; - void* shared_mem; -}; - struct DN_TCScratch { DN_Arena* arena; @@ -1080,7 +1079,7 @@ struct DN_TCCore // (T)hread (C)ontext sitting in thread-local storage DN_Str8x64 name; DN_U64 thread_id; DN_CallSite call_site; - DN_TCLane lane; + char lane_opaque[sizeof(DN_U64) * 4]; DN_Arena main_arena_; DN_Arena temp_a_arena_; @@ -1185,6 +1184,105 @@ struct DN_StackTraceWalkResultIterator typedef void DN_LogPrintFunc(DN_LogTypeParam type, void *user_data, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, va_list args); +DN_MSVC_WARNING_PUSH +DN_MSVC_WARNING_DISABLE(4201) // warning C4201: nonstandard extension used: nameless struct/union +union DN_V2I32 +{ + struct { DN_I32 x, y; }; + struct { DN_I32 w, h; }; + DN_I32 data[2]; +}; + +union DN_V2U16 +{ + struct { DN_U16 x, y; }; + struct { DN_U16 w, h; }; + DN_U16 data[2]; +}; + +union DN_V2U32 +{ + struct { DN_U32 x, y; }; + struct { DN_U32 w, h; }; + struct { DN_U32 min, max; }; + DN_U32 data[2]; +}; + +union DN_V2F32 +{ + struct { DN_F32 x, y; }; + struct { DN_F32 w, h; }; + DN_F32 data[2]; +}; +DN_DArrayStructDecl(DN_V2F32); + +union DN_V3F32 +{ + struct { DN_F32 x, y, z; }; + struct { DN_F32 r, g, b; }; + DN_V2F32 xy; + DN_F32 data[3]; +}; + +union DN_V4F32 +{ + struct { DN_F32 x, y, z, w; }; + struct { DN_F32 r, g, b, a; }; + DN_V3F32 rgb; + DN_V3F32 xyz; + DN_F32 data[4]; +}; +DN_DArrayStructDecl(DN_V4F32); +DN_MSVC_WARNING_POP + +struct DN_M4 +{ + DN_F32 columns[4][4]; // Column major matrix +}; + +union DN_M2x3 +{ + DN_F32 e[6]; + DN_F32 row[2][3]; +}; + +struct DN_Rect +{ + DN_V2F32 pos, size; +}; + +struct DN_RectMinMax +{ + DN_V2F32 min, max; +}; + +enum DN_RectCutClip +{ + DN_RectCutClip_No, + DN_RectCutClip_Yes, +}; + +enum DN_RectCutSide +{ + DN_RectCutSide_Left, + DN_RectCutSide_Right, + DN_RectCutSide_Top, + DN_RectCutSide_Bottom, +}; + +struct DN_RectCut +{ + DN_Rect* rect; + DN_RectCutSide side; +}; + +struct DN_RaycastV2 +{ + bool hit; // True if there was an intersection, false if the lines are parallel + DN_F32 t_a; // Distance along `dir_a` that the intersection occurred, e.g. `origin_a + (dir_a * t_a)` + DN_F32 t_b; // Distance along `dir_b` that the intersection occurred, e.g. `origin_b + (dir_b * t_b)` +}; + #if !defined(DN_STB_SPRINTF_HEADER_ONLY) #define STB_SPRINTF_IMPLEMENTATION #define STB_SPRINTF_STATIC @@ -1325,8 +1423,8 @@ DN_API void DN_ArenaTempMemEnd #define DN_ArenaNewArray(arena, T, count, zmem) (T *)DN_ArenaAlloc(arena, sizeof(T) * (count), alignof(T), zmem) #define DN_ArenaNewArrayZ(arena, T, count) (T *)DN_ArenaAlloc(arena, sizeof(T) * (count), alignof(T), DN_ZMem_Yes) -#define DN_ArenaNewCopy(arena, T, src) (T *)DN_ArenaCopy (arena, (src), sizeof(T), alignof(T)) -#define DN_ArenaNewArrayCopy(arena, T, src, count) (T *)DN_ArenaCopy (arena, (src), sizeof(T) * (count), alignof(T)) +#define DN_ArenaNewCopy(arena, T, src) (T *)DN_ArenaCopy(arena, (src), sizeof(T), alignof(T)) +#define DN_ArenaNewArrayCopy(arena, T, src, count) (T *)DN_ArenaCopy(arena, (src), sizeof(T) * (count), alignof(T)) DN_API DN_Pool DN_PoolFromArena (DN_Arena *arena, DN_U8 align); DN_API bool DN_PoolIsValid (DN_Pool const *pool); @@ -1374,7 +1472,6 @@ DN_API DN_Arena* DN_TCFrameArena DN_API DN_ErrSink* DN_TCErrSink (); #define DN_TCErrSinkBegin(mode) DN_ErrSinkBegin(DN_TCErrSink(), mode) #define DN_TCErrSinkBeginDefault() DN_ErrSinkBeginDefault(DN_TCErrSink()) -DN_API DN_TCLane DN_TCLaneEquip (DN_TCLane lane); DN_API bool DN_CharIsAlphabet (char ch); DN_API bool DN_CharIsDigit (char ch); @@ -1410,9 +1507,9 @@ DN_API DN_USize DN_CStr16Size #define DN_Str8PrintFmt(string) (int)((string).size), (string).data #define DN_Str8FromPtr(data, size) DN_Literal(DN_Str8){(char *)(data), (DN_USize)(size)} #define DN_Str8FromStruct(ptr) DN_Str8FromPtr((ptr)->data, (ptr)->size) +DN_API DN_Str8 DN_Str8AllocArena (DN_Arena *arena, DN_USize size, DN_ZMem z_mem); +DN_API DN_Str8 DN_Str8AllocPool (DN_Pool *pool, DN_USize size); DN_API DN_Str8 DN_Str8FromCStr8 (char const *src); -DN_API DN_Str8 DN_Str8FromArena (DN_Arena *arena, DN_USize size, DN_ZMem z_mem); -DN_API DN_Str8 DN_Str8FromPool (DN_Pool *pool, DN_USize size); DN_API DN_Str8 DN_Str8FromPtrArena (DN_Arena *arena, void const *data, DN_USize size); DN_API DN_Str8 DN_Str8FromPtrPool (DN_Pool *pool, void const *data, DN_USize size); DN_API DN_Str8 DN_Str8FromStr8Arena (DN_Arena *arena, DN_Str8 string); @@ -1455,7 +1552,7 @@ DN_API DN_USize DN_Str8Split DN_API DN_Str8SplitResult DN_Str8SplitArena (DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode); DN_API DN_Str8FindResult DN_Str8FindStr8Array (DN_Str8 string, DN_Str8 const *find, DN_USize find_size, DN_Str8EqCase eq_case); DN_API DN_Str8FindResult DN_Str8FindStr8 (DN_Str8 string, DN_Str8 find, DN_Str8EqCase eq_case); -DN_API DN_Str8FindResult DN_Str8Find (DN_Str8 string, uint32_t flags); +DN_API DN_Str8FindResult DN_Str8Find (DN_Str8 string, DN_Str8FindFlag flags); DN_API DN_Str8 DN_Str8Segment (DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char); DN_API DN_Str8 DN_Str8ReverseSegment (DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char); DN_API bool DN_Str8Eq (DN_Str8 lhs, DN_Str8 rhs, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive); @@ -1491,6 +1588,12 @@ DN_API DN_Str8 DN_Str8Replace DN_API DN_Str8 DN_Str8ReplaceSensitive (DN_Str8 string, DN_Str8 find, DN_Str8 replace, DN_USize start_index, DN_Arena *arena); DN_API DN_Str8 DN_Str8ReplaceInsensitive (DN_Str8 string, DN_Str8 find, DN_Str8 replace, DN_USize start_index, DN_Arena *arena); +DN_API DN_Str8 DN_Str8SliceRender (DN_Str8Slice array, DN_Str8 separator, DN_Arena *arena); +DN_API DN_Str8 DN_Str8RenderSpaceSep (DN_Str8Slice array, DN_Arena *arena); + +DN_API DN_Str16 DN_Str16SliceRender (DN_Str16Slice array, DN_Str16 separator, DN_Arena *arena); +DN_API DN_Str16 DN_Str16RenderSpaceSep (DN_Str16Slice array, DN_Arena *arena); + DN_API DN_Str8Builder DN_Str8BuilderFromArena (DN_Arena *arena); DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrRef (DN_Arena *arena, DN_Str8 const *strings, DN_USize size); DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrCopy (DN_Arena *arena, DN_Str8 const *strings, DN_USize size); @@ -1523,8 +1626,8 @@ DN_API DN_Str8 DN_Str8BuilderBuild DN_API DN_Str8 DN_Str8BuilderBuildDelimited (DN_Str8Builder const *builder, DN_Str8 delimiter, DN_Arena *arena); DN_API DN_Str8Slice DN_Str8BuilderBuildSlice (DN_Str8Builder const *builder, DN_Arena *arena); -DN_API int DN_EncodeUTF8Codepoint (uint8_t utf8[4], uint32_t codepoint); -DN_API int DN_EncodeUTF16Codepoint (uint16_t utf16[2], uint32_t codepoint); +DN_API int DN_EncodeUTF8Codepoint (DN_U8 utf8[4], DN_U32 codepoint); +DN_API int DN_EncodeUTF16Codepoint (DN_U16 utf16[2], DN_U32 codepoint); DN_API DN_U8 DN_U8FromHexNibble (char hex); DN_API DN_NibbleFromU8Result DN_NibbleFromU8 (DN_U8 u8); @@ -1612,7 +1715,7 @@ DN_API DN_Str8 DN_LogColourEscapeCodeStr8FromU32 DN_API DN_LogPrefixSize DN_LogMakePrefix (DN_LogStyle style, DN_LogTypeParam type, DN_CallSite call_site, DN_LogDate date, char *dest, DN_USize dest_size); DN_API void DN_LogSetPrintFunc (DN_LogPrintFunc *print_func, void *user_data); DN_API void DN_LogPrint (DN_LogTypeParam type, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, ...); -DN_API DN_LogTypeParam DN_LogMakeU32LogTypeParam (DN_LogType type); +DN_API DN_LogTypeParam DN_LogTypeParamFromType (DN_LogType type); #define DN_LogDebugF(fmt, ...) DN_LogPrint(DN_LogMakeU32LogTypeParam(DN_LogType_Debug), DN_CALL_SITE, fmt, ##__VA_ARGS__) #define DN_LogInfoF(fmt, ...) DN_LogPrint(DN_LogMakeU32LogTypeParam(DN_LogType_Info), DN_CALL_SITE, fmt, ##__VA_ARGS__) #define DN_LogWarningF(fmt, ...) DN_LogPrint(DN_LogMakeU32LogTypeParam(DN_LogType_Warning), DN_CALL_SITE, fmt, ##__VA_ARGS__) @@ -1620,7 +1723,6 @@ DN_API DN_LogTypeParam DN_LogMakeU32LogTypeParam // NOTE: OS primitives that the OS layer can provide for the base layer but is optional. #if defined(DN_FREESTANDING) -#define DN_StackTraceWalkStr8FromHeap(...) DN_Str8Lit("N/A") #define DN_StackTraceWalk(...) #define DN_StackTraceWalkResultIterate(...) #define DN_StackTraceWalkResultToStr8(...) DN_Str8Lit("N/A") @@ -1631,14 +1733,281 @@ DN_API DN_LogTypeParam DN_LogMakeU32LogTypeParam #define DN_StackTracePrint(...) #define DN_StackTraceReloadSymbols(...) #else -DN_API DN_StackTraceWalkResult DN_StackTraceWalk (DN_Arena *arena, DN_U16 limit); -DN_API bool DN_StackTraceWalkResultIterate(DN_StackTraceWalkResultIterator *it, DN_StackTraceWalkResult const *walk); -DN_API DN_Str8 DN_StackTraceWalkResultToStr8 (DN_Arena *arena, DN_StackTraceWalkResult const *walk, DN_U16 skip); -DN_API DN_Str8 DN_StackTraceWalkStr8 (DN_Arena *arena, DN_U16 limit, DN_U16 skip); -DN_API DN_Str8 DN_StackTraceWalkStr8FromHeap (DN_U16 limit, DN_U16 skip); -DN_API DN_StackTraceFrameSlice DN_StackTraceGetFrames (DN_Arena *arena, DN_U16 limit); -DN_API DN_StackTraceFrame DN_StackTraceRawFrameToFrame (DN_Arena *arena, DN_StackTraceRawFrame raw_frame); -DN_API void DN_StackTracePrint (DN_U16 limit); -DN_API void DN_StackTraceReloadSymbols (); +DN_API DN_StackTraceWalkResult DN_StackTraceWalk (DN_Arena *arena, DN_U16 limit); +DN_API bool DN_StackTraceWalkResultIterate (DN_StackTraceWalkResultIterator *it, DN_StackTraceWalkResult const *walk); +DN_API DN_Str8 DN_StackTraceWalkResultToStr8 (DN_Arena *arena, DN_StackTraceWalkResult const *walk, DN_U16 skip); +DN_API DN_Str8 DN_StackTraceWalkStr8 (DN_Arena *arena, DN_U16 limit, DN_U16 skip); +DN_API DN_Str8 DN_StackTraceWalkStr8FromHeap (DN_U16 limit, DN_U16 skip); +DN_API DN_StackTraceFrameSlice DN_StackTraceGetFrames (DN_Arena *arena, DN_U16 limit); +DN_API DN_StackTraceFrame DN_StackTraceRawFrameToFrame (DN_Arena *arena, DN_StackTraceRawFrame raw_frame); +DN_API void DN_StackTracePrint (DN_U16 limit); +DN_API void DN_StackTraceReloadSymbols (); #endif + +#define DN_V2I32Zero DN_Literal(DN_V2I32){{(DN_I32)(0), (DN_I32)(0)}} +#define DN_V2I32One DN_Literal(DN_V2I32){{(DN_I32)(1), (DN_I32)(1)}} +#define DN_V2I32From1N(x) DN_Literal(DN_V2I32){{(DN_I32)(x), (DN_I32)(x)}} +#define DN_V2I32From2N(x, y) DN_Literal(DN_V2I32){{(DN_I32)(x), (DN_I32)(y)}} +#define DN_V2I32InitV2(xy) DN_Literal(DN_V2I32){{(DN_I32)(xy).x, (DN_I32)(xy).y}} + +DN_API bool operator!= (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API bool operator== (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API bool operator>= (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API bool operator<= (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API bool operator< (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API bool operator> (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API DN_V2I32 operator- (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API DN_V2I32 operator- (DN_V2I32 lhs); +DN_API DN_V2I32 operator+ (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API DN_V2I32 operator* (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API DN_V2I32 operator* (DN_V2I32 lhs, DN_F32 rhs); +DN_API DN_V2I32 operator* (DN_V2I32 lhs, DN_I32 rhs); +DN_API DN_V2I32 operator/ (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API DN_V2I32 operator/ (DN_V2I32 lhs, DN_F32 rhs); +DN_API DN_V2I32 operator/ (DN_V2I32 lhs, DN_I32 rhs); +DN_API DN_V2I32& operator*= (DN_V2I32& lhs, DN_V2I32 rhs); +DN_API DN_V2I32& operator*= (DN_V2I32& lhs, DN_F32 rhs); +DN_API DN_V2I32& operator*= (DN_V2I32& lhs, DN_I32 rhs); +DN_API DN_V2I32& operator/= (DN_V2I32& lhs, DN_V2I32 rhs); +DN_API DN_V2I32& operator/= (DN_V2I32& lhs, DN_F32 rhs); +DN_API DN_V2I32& operator/= (DN_V2I32& lhs, DN_I32 rhs); +DN_API DN_V2I32& operator-= (DN_V2I32& lhs, DN_V2I32 rhs); +DN_API DN_V2I32& operator+= (DN_V2I32& lhs, DN_V2I32 rhs); + +DN_API DN_V2I32 DN_V2I32Min (DN_V2I32 a, DN_V2I32 b); +DN_API DN_V2I32 DN_V2I32Max (DN_V2I32 a, DN_V2I32 b); +DN_API DN_V2I32 DN_V2I32Abs (DN_V2I32 a); + +#define DN_V2U16Zero DN_Literal(DN_V2U16){{(DN_U16)(0), (DN_U16)(0)}} +#define DN_V2U16One DN_Literal(DN_V2U16){{(DN_U16)(1), (DN_U16)(1)}} +#define DN_V2U16From1N(x) DN_Literal(DN_V2U16){{(DN_U16)(x), (DN_U16)(x)}} +#define DN_V2U16From2N(x, y) DN_Literal(DN_V2U16){{(DN_U16)(x), (DN_U16)(y)}} + +DN_API bool operator!= (DN_V2U16 lhs, DN_V2U16 rhs); +DN_API bool operator== (DN_V2U16 lhs, DN_V2U16 rhs); +DN_API bool operator>= (DN_V2U16 lhs, DN_V2U16 rhs); +DN_API bool operator<= (DN_V2U16 lhs, DN_V2U16 rhs); +DN_API bool operator< (DN_V2U16 lhs, DN_V2U16 rhs); +DN_API bool operator> (DN_V2U16 lhs, DN_V2U16 rhs); +DN_API DN_V2U16 operator- (DN_V2U16 lhs, DN_V2U16 rhs); +DN_API DN_V2U16 operator+ (DN_V2U16 lhs, DN_V2U16 rhs); +DN_API DN_V2U16 operator* (DN_V2U16 lhs, DN_V2U16 rhs); +DN_API DN_V2U16 operator* (DN_V2U16 lhs, DN_F32 rhs); +DN_API DN_V2U16 operator* (DN_V2U16 lhs, DN_I32 rhs); +DN_API DN_V2U16 operator/ (DN_V2U16 lhs, DN_V2U16 rhs); +DN_API DN_V2U16 operator/ (DN_V2U16 lhs, DN_F32 rhs); +DN_API DN_V2U16 operator/ (DN_V2U16 lhs, DN_I32 rhs); +DN_API DN_V2U16& operator*= (DN_V2U16& lhs, DN_V2U16 rhs); +DN_API DN_V2U16& operator*= (DN_V2U16& lhs, DN_F32 rhs); +DN_API DN_V2U16& operator*= (DN_V2U16& lhs, DN_I32 rhs); +DN_API DN_V2U16& operator/= (DN_V2U16& lhs, DN_V2U16 rhs); +DN_API DN_V2U16& operator/= (DN_V2U16& lhs, DN_F32 rhs); +DN_API DN_V2U16& operator/= (DN_V2U16& lhs, DN_I32 rhs); +DN_API DN_V2U16& operator-= (DN_V2U16& lhs, DN_V2U16 rhs); +DN_API DN_V2U16& operator+= (DN_V2U16& lhs, DN_V2U16 rhs); + +#define DN_V2U32Zero DN_Literal(DN_V2U32){{(DN_U32)(0), (DN_U32)(0)}} +#define DN_V2U32One DN_Literal(DN_V2U32){{(DN_U32)(1), (DN_U32)(1)}} +#define DN_V2U32From1N(x) DN_Literal(DN_V2U32){{(DN_U32)(x), (DN_U32)(x)}} +#define DN_V2U32From2N(x, y) DN_Literal(DN_V2U32){{(DN_U32)(x), (DN_U32)(y)}} + +#define DN_V2F32Zero DN_Literal(DN_V2F32){{(DN_F32)(0), (DN_F32)(0)}} +#define DN_V2F32One DN_Literal(DN_V2F32){{(DN_F32)(1), (DN_F32)(1)}} +#define DN_V2F32From1N(x) DN_Literal(DN_V2F32){{(DN_F32)(x), (DN_F32)(x)}} +#define DN_V2F32From2N(x, y) DN_Literal(DN_V2F32){{(DN_F32)(x), (DN_F32)(y)}} +#define DN_V2F32FromV2I32(xy) DN_Literal(DN_V2F32){{(DN_F32)(xy).x, (DN_F32)(xy).y}} +#define DN_V2F32FromV2U32(xy) DN_Literal(DN_V2F32){{(DN_F32)(xy).x, (DN_F32)(xy).y}} + +DN_API bool operator!= (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API bool operator== (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API bool operator>= (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API bool operator<= (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API bool operator< (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API bool operator> (DN_V2F32 lhs, DN_V2F32 rhs); + +DN_API DN_V2F32 operator- (DN_V2F32 lhs); +DN_API DN_V2F32 operator- (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API DN_V2F32 operator- (DN_V2F32 lhs, DN_V2I32 rhs); +DN_API DN_V2F32 operator- (DN_V2F32 lhs, DN_F32 rhs); +DN_API DN_V2F32 operator- (DN_V2F32 lhs, DN_I32 rhs); + +DN_API DN_V2F32 operator+ (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API DN_V2F32 operator+ (DN_V2F32 lhs, DN_V2I32 rhs); +DN_API DN_V2F32 operator+ (DN_V2F32 lhs, DN_F32 rhs); +DN_API DN_V2F32 operator+ (DN_V2F32 lhs, DN_I32 rhs); + +DN_API DN_V2F32 operator* (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API DN_V2F32 operator* (DN_V2F32 lhs, DN_V2I32 rhs); +DN_API DN_V2F32 operator* (DN_V2F32 lhs, DN_F32 rhs); +DN_API DN_V2F32 operator* (DN_V2F32 lhs, DN_I32 rhs); + +DN_API DN_V2F32 operator/ (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API DN_V2F32 operator/ (DN_V2F32 lhs, DN_V2I32 rhs); +DN_API DN_V2F32 operator/ (DN_V2F32 lhs, DN_F32 rhs); +DN_API DN_V2F32 operator/ (DN_V2F32 lhs, DN_I32 rhs); + +DN_API DN_V2F32& operator*= (DN_V2F32& lhs, DN_V2F32 rhs); +DN_API DN_V2F32& operator*= (DN_V2F32& lhs, DN_V2I32 rhs); +DN_API DN_V2F32& operator*= (DN_V2F32& lhs, DN_F32 rhs); +DN_API DN_V2F32& operator*= (DN_V2F32& lhs, DN_I32 rhs); + +DN_API DN_V2F32& operator/= (DN_V2F32& lhs, DN_V2F32 rhs); +DN_API DN_V2F32& operator/= (DN_V2F32& lhs, DN_V2I32 rhs); +DN_API DN_V2F32& operator/= (DN_V2F32& lhs, DN_F32 rhs); +DN_API DN_V2F32& operator/= (DN_V2F32& lhs, DN_I32 rhs); + +DN_API DN_V2F32& operator-= (DN_V2F32& lhs, DN_V2F32 rhs); +DN_API DN_V2F32& operator-= (DN_V2F32& lhs, DN_V2I32 rhs); +DN_API DN_V2F32& operator-= (DN_V2F32& lhs, DN_F32 rhs); +DN_API DN_V2F32& operator-= (DN_V2F32& lhs, DN_I32 rhs); + +DN_API DN_V2F32& operator+= (DN_V2F32& lhs, DN_V2F32 rhs); +DN_API DN_V2F32& operator+= (DN_V2F32& lhs, DN_V2I32 rhs); +DN_API DN_V2F32& operator+= (DN_V2F32& lhs, DN_F32 rhs); +DN_API DN_V2F32& operator+= (DN_V2F32& lhs, DN_I32 rhs); + +DN_API DN_V2F32 DN_V2F32Min (DN_V2F32 a, DN_V2F32 b); +DN_API DN_V2F32 DN_V2F32Max (DN_V2F32 a, DN_V2F32 b); +DN_API DN_V2F32 DN_V2F32Abs (DN_V2F32 a); +DN_API DN_F32 DN_V2F32Dot (DN_V2F32 a, DN_V2F32 b); +DN_API DN_F32 DN_V2F32LengthSq2V2 (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API bool DN_V2F32LengthSqIsWithin2V2 (DN_V2F32 lhs, DN_V2F32 rhs, DN_F32 within_amount_sq); +DN_API DN_F32 DN_V2F32Length2V2 (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API DN_F32 DN_V2F32LengthSq (DN_V2F32 lhs); +DN_API DN_F32 DN_V2F32Length (DN_V2F32 lhs); +DN_API DN_V2F32 DN_V2F32Normalise (DN_V2F32 a); +DN_API DN_V2F32 DN_V2F32Perpendicular (DN_V2F32 a); +DN_API DN_V2F32 DN_V2F32Reflect (DN_V2F32 in, DN_V2F32 surface); +DN_API DN_F32 DN_V2F32Area (DN_V2F32 a); + +#define DN_V3F32From1N(x) DN_Literal(DN_V3F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}} +#define DN_V3F32From3N(x, y, z) DN_Literal(DN_V3F32){{(DN_F32)(x), (DN_F32)(y), (DN_F32)(z)}} +#define DN_V3F32FromV2F32And1N(xy, z) DN_Literal(DN_V3F32){{(DN_F32)(xy.x), (DN_F32)(xy.y), (DN_F32)(z)}} + +DN_API bool operator== (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API bool operator!= (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API bool operator>= (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API bool operator<= (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API bool operator< (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API bool operator> (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API DN_V3F32 operator- (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API DN_V3F32 operator- (DN_V3F32 lhs); +DN_API DN_V3F32 operator+ (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API DN_V3F32 operator* (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API DN_V3F32 operator* (DN_V3F32 lhs, DN_F32 rhs); +DN_API DN_V3F32 operator* (DN_V3F32 lhs, DN_I32 rhs); +DN_API DN_V3F32 operator/ (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API DN_V3F32 operator/ (DN_V3F32 lhs, DN_F32 rhs); +DN_API DN_V3F32 operator/ (DN_V3F32 lhs, DN_I32 rhs); +DN_API DN_V3F32& operator*= (DN_V3F32 &lhs, DN_V3F32 rhs); +DN_API DN_V3F32& operator*= (DN_V3F32 &lhs, DN_F32 rhs); +DN_API DN_V3F32& operator*= (DN_V3F32 &lhs, DN_I32 rhs); +DN_API DN_V3F32& operator/= (DN_V3F32 &lhs, DN_V3F32 rhs); +DN_API DN_V3F32& operator/= (DN_V3F32 &lhs, DN_F32 rhs); +DN_API DN_V3F32& operator/= (DN_V3F32 &lhs, DN_I32 rhs); +DN_API DN_V3F32& operator-= (DN_V3F32 &lhs, DN_V3F32 rhs); +DN_API DN_V3F32& operator+= (DN_V3F32 &lhs, DN_V3F32 rhs); +DN_API DN_F32 DN_V3F32LengthSq (DN_V3F32 a); +DN_API DN_F32 DN_V3F32Length (DN_V3F32 a); +DN_API DN_V3F32 DN_V3F32Normalise (DN_V3F32 a); + +#define DN_V4F32From1N(x) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}} +#define DN_V4F32From4N(x, y, z, w) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(y), (DN_F32)(z), (DN_F32)(w)}} +#define DN_V4F32FromV3And1N(xyz, w) DN_Literal(DN_V4F32){{xyz.x, xyz.y, xyz.z, w}} +#define DN_V4F32FromRGBAU8(r, g, b, a) DN_Literal(DN_V4F32){{r / 255.f, g / 255.f, b / 255.f, a / 255.f}} +#define DN_V4F32FromRGBU8(r, g, b) DN_Literal(DN_V4F32){{r / 255.f, g / 255.f, b / 255.f, 1.f}} +DN_API DN_V4F32 DN_V4F32FromRGBU32 (DN_U32 u32); +DN_API DN_V4F32 DN_V4F32FromRGBAU32 (DN_U32 u32); +#define DN_V4F32FromV4Alpha(v4, alpha) DN_V4F32FromV3And1N(v4.xyz, alpha) +DN_API bool operator== (DN_V4F32 lhs, DN_V4F32 rhs); +DN_API bool operator!= (DN_V4F32 lhs, DN_V4F32 rhs); +DN_API bool operator<= (DN_V4F32 lhs, DN_V4F32 rhs); +DN_API bool operator< (DN_V4F32 lhs, DN_V4F32 rhs); +DN_API bool operator> (DN_V4F32 lhs, DN_V4F32 rhs); +DN_API DN_V4F32 operator- (DN_V4F32 lhs, DN_V4F32 rhs); +DN_API DN_V4F32 operator- (DN_V4F32 lhs); +DN_API DN_V4F32 operator+ (DN_V4F32 lhs, DN_V4F32 rhs); +DN_API DN_V4F32 operator* (DN_V4F32 lhs, DN_V4F32 rhs); +DN_API DN_V4F32 operator* (DN_V4F32 lhs, DN_F32 rhs); +DN_API DN_V4F32 operator* (DN_V4F32 lhs, DN_I32 rhs); +DN_API DN_V4F32 operator/ (DN_V4F32 lhs, DN_F32 rhs); +DN_API DN_V4F32& operator*= (DN_V4F32 &lhs, DN_V4F32 rhs); +DN_API DN_V4F32& operator*= (DN_V4F32 &lhs, DN_F32 rhs); +DN_API DN_V4F32& operator*= (DN_V4F32 &lhs, DN_I32 rhs); +DN_API DN_V4F32& operator-= (DN_V4F32 &lhs, DN_V4F32 rhs); +DN_API DN_V4F32& operator+= (DN_V4F32 &lhs, DN_V4F32 rhs); +DN_API DN_F32 DN_V4F32Dot (DN_V4F32 a, DN_V4F32 b); + +DN_API DN_M4 DN_M4Identity (); +DN_API DN_M4 DN_M4ScaleF (DN_F32 x, DN_F32 y, DN_F32 z); +DN_API DN_M4 DN_M4Scale (DN_V3F32 xyz); +DN_API DN_M4 DN_M4TranslateF (DN_F32 x, DN_F32 y, DN_F32 z); +DN_API DN_M4 DN_M4Translate (DN_V3F32 xyz); +DN_API DN_M4 DN_M4Transpose (DN_M4 mat); +DN_API DN_M4 DN_M4Rotate (DN_V3F32 axis, DN_F32 radians); +DN_API DN_M4 DN_M4Orthographic (DN_F32 left, DN_F32 right, DN_F32 bottom, DN_F32 top, DN_F32 z_near, DN_F32 z_far); +DN_API DN_M4 DN_M4Perspective (DN_F32 fov /*radians*/, DN_F32 aspect, DN_F32 z_near, DN_F32 z_far); +DN_API DN_M4 DN_M4Add (DN_M4 lhs, DN_M4 rhs); +DN_API DN_M4 DN_M4Sub (DN_M4 lhs, DN_M4 rhs); +DN_API DN_M4 DN_M4Mul (DN_M4 lhs, DN_M4 rhs); +DN_API DN_M4 DN_M4Div (DN_M4 lhs, DN_M4 rhs); +DN_API DN_M4 DN_M4AddF (DN_M4 lhs, DN_F32 rhs); +DN_API DN_M4 DN_M4SubF (DN_M4 lhs, DN_F32 rhs); +DN_API DN_M4 DN_M4MulF (DN_M4 lhs, DN_F32 rhs); +DN_API DN_M4 DN_M4DivF (DN_M4 lhs, DN_F32 rhs); +DN_API DN_Str8x256 DN_M4ColumnMajorString (DN_M4 mat); + +DN_API bool operator== (DN_M2x3 const &lhs, DN_M2x3 const &rhs); +DN_API bool operator!= (DN_M2x3 const &lhs, DN_M2x3 const &rhs); +DN_API DN_M2x3 DN_M2x3Identity (); +DN_API DN_M2x3 DN_M2x3Translate (DN_V2F32 offset); +DN_API DN_V2F32 DN_M2x3ScaleGet (DN_M2x3 m2x3); +DN_API DN_M2x3 DN_M2x3Scale (DN_V2F32 scale); +DN_API DN_M2x3 DN_M2x3Rotate (DN_F32 radians); +DN_API DN_M2x3 DN_M2x3Mul (DN_M2x3 m1, DN_M2x3 m2); +DN_API DN_V2F32 DN_M2x3Mul2F32 (DN_M2x3 m1, DN_F32 x, DN_F32 y); +DN_API DN_V2F32 DN_M2x3MulV2F32 (DN_M2x3 m1, DN_V2F32 v2); + +#define DN_RectFrom2V2(pos, size) DN_Literal(DN_Rect){(pos), (size)} +#define DN_RectFrom4N(x, y, w, h) DN_Literal(DN_Rect){DN_Literal(DN_V2F32){{x, y}}, DN_Literal(DN_V2F32){{w, h}}} +#define DN_RectZero DN_RectFrom4N(0, 0, 0, 0) + +DN_API bool operator== (const DN_Rect& lhs, const DN_Rect& rhs); +DN_API DN_V2F32 DN_RectCenter (DN_Rect rect); +DN_API bool DN_RectContainsPoint (DN_Rect rect, DN_V2F32 p); +DN_API bool DN_RectContainsRect (DN_Rect a, DN_Rect b); +DN_API DN_Rect DN_RectExpand (DN_Rect a, DN_F32 amount); +DN_API DN_Rect DN_RectExpandV2 (DN_Rect a, DN_V2F32 amount); +DN_API bool DN_RectIntersects (DN_Rect a, DN_Rect b); +DN_API DN_Rect DN_RectIntersection (DN_Rect a, DN_Rect b); +DN_API DN_Rect DN_RectUnion (DN_Rect a, DN_Rect b); +DN_API DN_RectMinMax DN_RectGetMinMax (DN_Rect a); +DN_API DN_F32 DN_RectArea (DN_Rect a); +DN_API DN_V2F32 DN_RectInterpV2F32 (DN_Rect rect, DN_V2F32 t01); +DN_API DN_V2F32 DN_RectTopLeft (DN_Rect rect); +DN_API DN_V2F32 DN_RectTopRight (DN_Rect rect); +DN_API DN_V2F32 DN_RectBottomLeft (DN_Rect rect); +DN_API DN_V2F32 DN_RectBottomRight (DN_Rect rect); + +DN_API DN_Rect DN_RectCutLeftClip (DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip); +DN_API DN_Rect DN_RectCutRightClip (DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip); +DN_API DN_Rect DN_RectCutTopClip (DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip); +DN_API DN_Rect DN_RectCutBottomClip (DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip); + +#define DN_RectCutLeft(rect, amount) DN_RectCutLeftClip(rect, amount, DN_RectCutClip_Yes) +#define DN_RectCutRight(rect, amount) DN_RectCutRightClip(rect, amount, DN_RectCutClip_Yes) +#define DN_RectCutTop(rect, amount) DN_RectCutTopClip(rect, amount, DN_RectCutClip_Yes) +#define DN_RectCutBottom(rect, amount) DN_RectCutBottomClip(rect, amount, DN_RectCutClip_Yes) + +#define DN_RectCutLeftNoClip(rect, amount) DN_RectCutLeftClip(rect, amount, DN_RectCutClip_No) +#define DN_RectCutRightNoClip(rect, amount) DN_RectCutRightClip(rect, amount, DN_RectCutClip_No) +#define DN_RectCutTopNoClip(rect, amount) DN_RectCutTopClip(rect, amount, DN_RectCutClip_No) +#define DN_RectCutBottomNoClip(rect, amount) DN_RectCutBottomClip(rect, amount, DN_RectCutClip_No) + +DN_API DN_Rect DN_RectCutCut (DN_RectCut rect_cut, DN_V2F32 size, DN_RectCutClip clip); +#define DN_RectCutInit(rect, side) DN_Literal(DN_RectCut){rect, side} + +DN_API DN_RaycastV2 DN_RaycastLineIntersectV2 (DN_V2F32 origin_a, DN_V2F32 dir_a, DN_V2F32 origin_b, DN_V2F32 dir_b); +DN_API DN_V2F32 DN_LerpV2F32 (DN_V2F32 a, DN_F32 t, DN_V2F32 b); +DN_API DN_F32 DN_LerpF32 (DN_F32 a, DN_F32 t, DN_F32 b); #endif // !defined(DN_BASE_H) diff --git a/Source/Base/dn_base_containers.cpp b/Source/Base/dn_base_containers.cpp index 3efeb4b..c440979 100644 --- a/Source/Base/dn_base_containers.cpp +++ b/Source/Base/dn_base_containers.cpp @@ -662,81 +662,6 @@ DN_DSMapKey DN_DSMapKeyStr8(DN_DSMap const *map, DN_Str8 string) return result; } -DN_API DN_Str8 DN_Slice_Str8Render(DN_Arena *arena, DN_Slice array, DN_Str8 separator) -{ - DN_Str8 result = {}; - if (!arena) - return result; - - DN_USize total_size = 0; - for (DN_USize index = 0; index < array.size; index++) { - if (index) - total_size += separator.size; - DN_Str8 item = array.data[index]; - total_size += item.size; - } - - result = DN_Str8FromArena(arena, total_size, DN_ZMem_No); - if (result.data) { - DN_USize write_index = 0; - for (DN_USize index = 0; index < array.size; index++) { - if (index) { - DN_Memcpy(result.data + write_index, separator.data, separator.size); - write_index += separator.size; - } - DN_Str8 item = array.data[index]; - DN_Memcpy(result.data + write_index, item.data, item.size); - write_index += item.size; - } - } - - return result; -} - -DN_API DN_Str8 DN_Slice_Str8RenderSpaceSeparated(DN_Arena *arena, DN_Slice array) -{ - DN_Str8 result = DN_Slice_Str8Render(arena, array, DN_Str8Lit(" ")); - return result; -} - -DN_API DN_Str16 DN_Slice_Str16Render(DN_Arena *arena, DN_Slice array, DN_Str16 separator) -{ - DN_Str16 result = {}; - if (!arena) - return result; - - DN_USize total_size = 0; - for (DN_USize index = 0; index < array.size; index++) { - if (index) - total_size += separator.size; - DN_Str16 item = array.data[index]; - total_size += item.size; - } - - result = {DN_ArenaNewArray(arena, wchar_t, total_size + 1, DN_ZMem_No), total_size}; - if (result.data) { - DN_USize write_index = 0; - for (DN_USize index = 0; index < array.size; index++) { - if (index) { - DN_Memcpy(result.data + write_index, separator.data, separator.size * sizeof(result.data[0])); - write_index += separator.size; - } - DN_Str16 item = array.data[index]; - DN_Memcpy(result.data + write_index, item.data, item.size * sizeof(result.data[0])); - write_index += item.size; - } - } - - result.data[total_size] = 0; - return result; -} - -DN_API DN_Str16 DN_Slice_Str16RenderSpaceSeparated(DN_Arena *arena, DN_Slice array) -{ - DN_Str16 result = DN_Slice_Str16Render(arena, array, DN_Str16Lit(L" ")); - return result; -} - // NOTE: DN_DSMap DN_API DN_DSMapKey DN_DSMapKeyU64NoHash(DN_U64 u64) { diff --git a/Source/Extra/dn_math.cpp b/Source/Extra/dn_math.cpp deleted file mode 100644 index efee942..0000000 --- a/Source/Extra/dn_math.cpp +++ /dev/null @@ -1,1585 +0,0 @@ -#define DN_MATH_CPP - -#if defined(_CLANGD) - #include "dn_math.h" -#endif - -DN_API bool operator==(DN_V2I32 lhs, DN_V2I32 rhs) -{ - bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y); - return result; -} - -DN_API bool operator!=(DN_V2I32 lhs, DN_V2I32 rhs) -{ - bool result = !(lhs == rhs); - return result; -} - -DN_API bool operator>=(DN_V2I32 lhs, DN_V2I32 rhs) -{ - bool result = (lhs.x >= rhs.x) && (lhs.y >= rhs.y); - return result; -} - -DN_API bool operator<=(DN_V2I32 lhs, DN_V2I32 rhs) -{ - bool result = (lhs.x <= rhs.x) && (lhs.y <= rhs.y); - return result; -} - -DN_API bool operator<(DN_V2I32 lhs, DN_V2I32 rhs) -{ - bool result = (lhs.x < rhs.x) && (lhs.y < rhs.y); - return result; -} - -DN_API bool operator>(DN_V2I32 lhs, DN_V2I32 rhs) -{ - bool result = (lhs.x > rhs.x) && (lhs.y > rhs.y); - return result; -} - -DN_API DN_V2I32 operator-(DN_V2I32 lhs, DN_V2I32 rhs) -{ - DN_V2I32 result = DN_V2I32_From2N(lhs.x - rhs.x, lhs.y - rhs.y); - return result; -} - -DN_API DN_V2I32 operator-(DN_V2I32 lhs) -{ - DN_V2I32 result = DN_V2I32_From2N(-lhs.x, -lhs.y); - return result; -} - -DN_API DN_V2I32 operator+(DN_V2I32 lhs, DN_V2I32 rhs) -{ - DN_V2I32 result = DN_V2I32_From2N(lhs.x + rhs.x, lhs.y + rhs.y); - return result; -} - -DN_API DN_V2I32 operator*(DN_V2I32 lhs, DN_V2I32 rhs) -{ - DN_V2I32 result = DN_V2I32_From2N(lhs.x * rhs.x, lhs.y * rhs.y); - return result; -} - -DN_API DN_V2I32 operator*(DN_V2I32 lhs, DN_F32 rhs) -{ - DN_V2I32 result = DN_V2I32_From2N(lhs.x * rhs, lhs.y * rhs); - return result; -} - -DN_API DN_V2I32 operator*(DN_V2I32 lhs, int32_t rhs) -{ - DN_V2I32 result = DN_V2I32_From2N(lhs.x * rhs, lhs.y * rhs); - return result; -} - -DN_API DN_V2I32 operator/(DN_V2I32 lhs, DN_V2I32 rhs) -{ - DN_V2I32 result = DN_V2I32_From2N(lhs.x / rhs.x, lhs.y / rhs.y); - return result; -} - -DN_API DN_V2I32 operator/(DN_V2I32 lhs, DN_F32 rhs) -{ - DN_V2I32 result = DN_V2I32_From2N(lhs.x / rhs, lhs.y / rhs); - return result; -} - -DN_API DN_V2I32 operator/(DN_V2I32 lhs, int32_t rhs) -{ - DN_V2I32 result = DN_V2I32_From2N(lhs.x / rhs, lhs.y / rhs); - return result; -} - -DN_API DN_V2I32 &operator*=(DN_V2I32 &lhs, DN_V2I32 rhs) -{ - lhs = lhs * rhs; - return lhs; -} - -DN_API DN_V2I32 &operator*=(DN_V2I32 &lhs, DN_F32 rhs) -{ - lhs = lhs * rhs; - return lhs; -} - -DN_API DN_V2I32 &operator*=(DN_V2I32 &lhs, int32_t rhs) -{ - lhs = lhs * rhs; - return lhs; -} - -DN_API DN_V2I32 &operator/=(DN_V2I32 &lhs, DN_V2I32 rhs) -{ - lhs = lhs / rhs; - return lhs; -} - -DN_API DN_V2I32 &operator/=(DN_V2I32 &lhs, DN_F32 rhs) -{ - lhs = lhs / rhs; - return lhs; -} - -DN_API DN_V2I32 &operator/=(DN_V2I32 &lhs, int32_t rhs) -{ - lhs = lhs / rhs; - return lhs; -} - -DN_API DN_V2I32 &operator-=(DN_V2I32 &lhs, DN_V2I32 rhs) -{ - lhs = lhs - rhs; - return lhs; -} - -DN_API DN_V2I32 &operator+=(DN_V2I32 &lhs, DN_V2I32 rhs) -{ - lhs = lhs + rhs; - return lhs; -} - -DN_API DN_V2I32 DN_V2I32_Min(DN_V2I32 a, DN_V2I32 b) -{ - DN_V2I32 result = DN_V2I32_From2N(DN_Min(a.x, b.x), DN_Min(a.y, b.y)); - return result; -} - -DN_API DN_V2I32 DN_V2I32_Max(DN_V2I32 a, DN_V2I32 b) -{ - DN_V2I32 result = DN_V2I32_From2N(DN_Max(a.x, b.x), DN_Max(a.y, b.y)); - return result; -} - -DN_API DN_V2I32 DN_V2I32_Abs(DN_V2I32 a) -{ - DN_V2I32 result = DN_V2I32_From2N(DN_Abs(a.x), DN_Abs(a.y)); - return result; -} - -DN_API bool operator!=(DN_V2U16 lhs, DN_V2U16 rhs) -{ - bool result = !(lhs == rhs); - return result; -} - -DN_API bool operator==(DN_V2U16 lhs, DN_V2U16 rhs) -{ - bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y); - return result; -} - -DN_API bool operator>=(DN_V2U16 lhs, DN_V2U16 rhs) -{ - bool result = (lhs.x >= rhs.x) && (lhs.y >= rhs.y); - return result; -} - -DN_API bool operator<=(DN_V2U16 lhs, DN_V2U16 rhs) -{ - bool result = (lhs.x <= rhs.x) && (lhs.y <= rhs.y); - return result; -} - -DN_API bool operator<(DN_V2U16 lhs, DN_V2U16 rhs) -{ - bool result = (lhs.x < rhs.x) && (lhs.y < rhs.y); - return result; -} - -DN_API bool operator>(DN_V2U16 lhs, DN_V2U16 rhs) -{ - bool result = (lhs.x > rhs.x) && (lhs.y > rhs.y); - return result; -} - -DN_API DN_V2U16 operator-(DN_V2U16 lhs, DN_V2U16 rhs) -{ - DN_V2U16 result = DN_V2U16_From2N(lhs.x - rhs.x, lhs.y - rhs.y); - return result; -} - -DN_API DN_V2U16 operator+(DN_V2U16 lhs, DN_V2U16 rhs) -{ - DN_V2U16 result = DN_V2U16_From2N(lhs.x + rhs.x, lhs.y + rhs.y); - return result; -} - -DN_API DN_V2U16 operator*(DN_V2U16 lhs, DN_V2U16 rhs) -{ - DN_V2U16 result = DN_V2U16_From2N(lhs.x * rhs.x, lhs.y * rhs.y); - return result; -} - -DN_API DN_V2U16 operator*(DN_V2U16 lhs, DN_F32 rhs) -{ - DN_V2U16 result = DN_V2U16_From2N(lhs.x * rhs, lhs.y * rhs); - return result; -} - -DN_API DN_V2U16 operator*(DN_V2U16 lhs, int32_t rhs) -{ - DN_V2U16 result = DN_V2U16_From2N(lhs.x * rhs, lhs.y * rhs); - return result; -} - -DN_API DN_V2U16 operator/(DN_V2U16 lhs, DN_V2U16 rhs) -{ - DN_V2U16 result = DN_V2U16_From2N(lhs.x / rhs.x, lhs.y / rhs.y); - return result; -} - -DN_API DN_V2U16 operator/(DN_V2U16 lhs, DN_F32 rhs) -{ - DN_V2U16 result = DN_V2U16_From2N(lhs.x / rhs, lhs.y / rhs); - return result; -} - -DN_API DN_V2U16 operator/(DN_V2U16 lhs, int32_t rhs) -{ - DN_V2U16 result = DN_V2U16_From2N(lhs.x / rhs, lhs.y / rhs); - return result; -} - -DN_API DN_V2U16 &operator*=(DN_V2U16 &lhs, DN_V2U16 rhs) -{ - lhs = lhs * rhs; - return lhs; -} - -DN_API DN_V2U16 &operator*=(DN_V2U16 &lhs, DN_F32 rhs) -{ - lhs = lhs * rhs; - return lhs; -} - -DN_API DN_V2U16 &operator*=(DN_V2U16 &lhs, int32_t rhs) -{ - lhs = lhs * rhs; - return lhs; -} - -DN_API DN_V2U16 &operator/=(DN_V2U16 &lhs, DN_V2U16 rhs) -{ - lhs = lhs / rhs; - return lhs; -} - -DN_API DN_V2U16 &operator/=(DN_V2U16 &lhs, DN_F32 rhs) -{ - lhs = lhs / rhs; - return lhs; -} - -DN_API DN_V2U16 &operator/=(DN_V2U16 &lhs, int32_t rhs) -{ - lhs = lhs / rhs; - return lhs; -} - -DN_API DN_V2U16 &operator-=(DN_V2U16 &lhs, DN_V2U16 rhs) -{ - lhs = lhs - rhs; - return lhs; -} - -DN_API DN_V2U16 &operator+=(DN_V2U16 &lhs, DN_V2U16 rhs) -{ - lhs = lhs + rhs; - return lhs; -} - -DN_API bool operator!=(DN_V2F32 lhs, DN_V2F32 rhs) -{ - bool result = !(lhs == rhs); - return result; -} - -DN_API bool operator==(DN_V2F32 lhs, DN_V2F32 rhs) -{ - bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y); - return result; -} - -DN_API bool operator>=(DN_V2F32 lhs, DN_V2F32 rhs) -{ - bool result = (lhs.x >= rhs.x) && (lhs.y >= rhs.y); - return result; -} - -DN_API bool operator<=(DN_V2F32 lhs, DN_V2F32 rhs) -{ - bool result = (lhs.x <= rhs.x) && (lhs.y <= rhs.y); - return result; -} - -DN_API bool operator<(DN_V2F32 lhs, DN_V2F32 rhs) -{ - bool result = (lhs.x < rhs.x) && (lhs.y < rhs.y); - return result; -} - -DN_API bool operator>(DN_V2F32 lhs, DN_V2F32 rhs) -{ - bool result = (lhs.x > rhs.x) && (lhs.y > rhs.y); - return result; -} - -DN_API DN_V2F32 operator-(DN_V2F32 lhs) -{ - DN_V2F32 result = DN_V2F32_From2N(-lhs.x, -lhs.y); - return result; -} - -DN_API DN_V2F32 operator-(DN_V2F32 lhs, DN_V2F32 rhs) -{ - DN_V2F32 result = DN_V2F32_From2N(lhs.x - rhs.x, lhs.y - rhs.y); - return result; -} - -DN_API DN_V2F32 operator-(DN_V2F32 lhs, DN_V2I32 rhs) -{ - DN_V2F32 result = DN_V2F32_From2N(lhs.x - rhs.x, lhs.y - rhs.y); - return result; -} - -DN_API DN_V2F32 operator-(DN_V2F32 lhs, DN_F32 rhs) -{ - DN_V2F32 result = DN_V2F32_From2N(lhs.x - rhs, lhs.y - rhs); - return result; -} - -DN_API DN_V2F32 operator-(DN_V2F32 lhs, int32_t rhs) -{ - DN_V2F32 result = DN_V2F32_From2N(lhs.x - rhs, lhs.y - rhs); - return result; -} - -DN_API DN_V2F32 operator+(DN_V2F32 lhs, DN_V2F32 rhs) -{ - DN_V2F32 result = DN_V2F32_From2N(lhs.x + rhs.x, lhs.y + rhs.y); - return result; -} - -DN_API DN_V2F32 operator+(DN_V2F32 lhs, DN_V2I32 rhs) -{ - DN_V2F32 result = DN_V2F32_From2N(lhs.x + rhs.x, lhs.y + rhs.y); - return result; -} - -DN_API DN_V2F32 operator+(DN_V2F32 lhs, DN_F32 rhs) -{ - DN_V2F32 result = DN_V2F32_From2N(lhs.x + rhs, lhs.y + rhs); - return result; -} - -DN_API DN_V2F32 operator+(DN_V2F32 lhs, int32_t rhs) -{ - DN_V2F32 result = DN_V2F32_From2N(lhs.x + rhs, lhs.y + rhs); - return result; -} - -DN_API DN_V2F32 operator*(DN_V2F32 lhs, DN_V2F32 rhs) -{ - DN_V2F32 result = DN_V2F32_From2N(lhs.x * rhs.x, lhs.y * rhs.y); - return result; -} - -DN_API DN_V2F32 operator*(DN_V2F32 lhs, DN_V2I32 rhs) -{ - DN_V2F32 result = DN_V2F32_From2N(lhs.x * rhs.x, lhs.y * rhs.y); - return result; -} - -DN_API DN_V2F32 operator*(DN_V2F32 lhs, DN_F32 rhs) -{ - DN_V2F32 result = DN_V2F32_From2N(lhs.x * rhs, lhs.y * rhs); - return result; -} - -DN_API DN_V2F32 operator*(DN_V2F32 lhs, int32_t rhs) -{ - DN_V2F32 result = DN_V2F32_From2N(lhs.x * rhs, lhs.y * rhs); - return result; -} - -DN_API DN_V2F32 operator/(DN_V2F32 lhs, DN_V2F32 rhs) -{ - DN_V2F32 result = DN_V2F32_From2N(lhs.x / rhs.x, lhs.y / rhs.y); - return result; -} - -DN_API DN_V2F32 operator/(DN_V2F32 lhs, DN_V2I32 rhs) -{ - DN_V2F32 result = DN_V2F32_From2N(lhs.x / rhs.x, lhs.y / rhs.y); - return result; -} - -DN_API DN_V2F32 operator/(DN_V2F32 lhs, DN_F32 rhs) -{ - DN_V2F32 result = DN_V2F32_From2N(lhs.x / rhs, lhs.y / rhs); - return result; -} - -DN_API DN_V2F32 operator/(DN_V2F32 lhs, int32_t rhs) -{ - DN_V2F32 result = DN_V2F32_From2N(lhs.x / rhs, lhs.y / rhs); - return result; -} - -DN_API DN_V2F32 &operator*=(DN_V2F32 &lhs, DN_V2F32 rhs) -{ - lhs = lhs * rhs; - return lhs; -} - -DN_API DN_V2F32 &operator*=(DN_V2F32 &lhs, DN_V2I32 rhs) -{ - lhs = lhs * rhs; - return lhs; -} - -DN_API DN_V2F32 &operator*=(DN_V2F32 &lhs, DN_F32 rhs) -{ - lhs = lhs * rhs; - return lhs; -} - -DN_API DN_V2F32 &operator*=(DN_V2F32 &lhs, int32_t rhs) -{ - lhs = lhs * rhs; - return lhs; -} - -DN_API DN_V2F32 &operator/=(DN_V2F32 &lhs, DN_V2F32 rhs) -{ - lhs = lhs / rhs; - return lhs; -} - -DN_API DN_V2F32 &operator/=(DN_V2F32 &lhs, DN_V2I32 rhs) -{ - lhs = lhs / rhs; - return lhs; -} - -DN_API DN_V2F32 &operator/=(DN_V2F32 &lhs, DN_F32 rhs) -{ - lhs = lhs / rhs; - return lhs; -} - -DN_API DN_V2F32 &operator/=(DN_V2F32 &lhs, int32_t rhs) -{ - lhs = lhs / rhs; - return lhs; -} - -DN_API DN_V2F32 &operator-=(DN_V2F32 &lhs, DN_V2F32 rhs) -{ - lhs = lhs - rhs; - return lhs; -} - -DN_API DN_V2F32 &operator-=(DN_V2F32 &lhs, DN_V2I32 rhs) -{ - lhs = lhs - rhs; - return lhs; -} - -DN_API DN_V2F32 &operator-=(DN_V2F32 &lhs, DN_F32 rhs) -{ - lhs = lhs - rhs; - return lhs; -} - -DN_API DN_V2F32 &operator-=(DN_V2F32 &lhs, int32_t rhs) -{ - lhs = lhs - rhs; - return lhs; -} - -DN_API DN_V2F32 &operator+=(DN_V2F32 &lhs, DN_V2F32 rhs) -{ - lhs = lhs + rhs; - return lhs; -} - -DN_API DN_V2F32 &operator+=(DN_V2F32 &lhs, DN_V2I32 rhs) -{ - lhs = lhs + rhs; - return lhs; -} - -DN_API DN_V2F32 &operator+=(DN_V2F32 &lhs, DN_F32 rhs) -{ - lhs = lhs + rhs; - return lhs; -} - -DN_API DN_V2F32 &operator+=(DN_V2F32 &lhs, int32_t rhs) -{ - lhs = lhs + rhs; - return lhs; -} - -DN_API DN_V2F32 DN_V2F32_Min(DN_V2F32 a, DN_V2F32 b) -{ - DN_V2F32 result = DN_V2F32_From2N(DN_Min(a.x, b.x), DN_Min(a.y, b.y)); - return result; -} - -DN_API DN_V2F32 DN_V2F32_Max(DN_V2F32 a, DN_V2F32 b) -{ - DN_V2F32 result = DN_V2F32_From2N(DN_Max(a.x, b.x), DN_Max(a.y, b.y)); - return result; -} - -DN_API DN_V2F32 DN_V2F32_Abs(DN_V2F32 a) -{ - DN_V2F32 result = DN_V2F32_From2N(DN_Abs(a.x), DN_Abs(a.y)); - return result; -} - -DN_API DN_F32 DN_V2F32_Dot(DN_V2F32 a, DN_V2F32 b) -{ - // NOTE: Scalar projection of B onto A ///////////////////////////////////////////////////////// - // - // Scalar projection calculates the signed distance between `b` and `a` - // where `a` is a unit vector then, the dot product calculates the projection - // of `b` onto the infinite line that the direction of `a` represents. This - // calculation is the signed distance. - // - // signed_distance = dot_product(a, b) = (a.x * b.x) + (a.y * b.y) - // - // Y - // ^ b - // | /| - // | / | - // | / | - // | / | Projection - // | / | - // |/ V - // +--->--------> X - // . a . - // . . - // |------| <- Calculated signed distance - // - // The signed-ness of the result indicates the relationship: - // - // Distance <0 means `b` is behind `a` - // Distance >0 means `b` is in-front of `a` - // Distance ==0 means `b` is perpendicular to `a` - // - // If `a` is not normalized then the signed-ness of the result still holds - // however result no longer represents the actual distance between the - // 2 objects. One of the vectors must be normalised (e.g. turned into a unit - // vector). - // - // NOTE: DN_V projection ///////////////////////////////////////////////////////////////////// - // - // DN_V projection calculates the exact X,Y coordinates of where `b` meets - // `a` when it was projected. This is calculated by multipying the - // 'scalar projection' result by the unit vector of `a` - // - // vector_projection = a * signed_distance = a * dot_product(a, b) - - DN_F32 result = (a.x * b.x) + (a.y * b.y); - return result; -} - -DN_API DN_F32 DN_V2F32_LengthSq2V2(DN_V2F32 lhs, DN_V2F32 rhs) -{ - // NOTE: Pythagoras's theorem (a^2 + b^2 = c^2) without the square root - DN_F32 a = rhs.x - lhs.x; - DN_F32 b = rhs.y - lhs.y; - DN_F32 c_squared = DN_Squared(a) + DN_Squared(b); - DN_F32 result = c_squared; - return result; -} - -DN_API bool DN_V2F32_LengthSqIsWithin2V2(DN_V2F32 lhs, DN_V2F32 rhs, DN_F32 within_amount_sq) -{ - DN_F32 dist = DN_V2F32_LengthSq2V2(lhs, rhs); - bool result = dist <= within_amount_sq; - return result; -} - -DN_API DN_F32 DN_V2F32_Length2V2(DN_V2F32 lhs, DN_V2F32 rhs) -{ - DN_F32 result_squared = DN_V2F32_LengthSq2V2(lhs, rhs); - DN_F32 result = DN_SqrtF32(result_squared); - return result; -} - -DN_API DN_F32 DN_V2F32_LengthSq(DN_V2F32 lhs) -{ - // NOTE: Pythagoras's theorem without the square root - DN_F32 c_squared = DN_Squared(lhs.x) + DN_Squared(lhs.y); - DN_F32 result = c_squared; - return result; -} - -DN_API DN_F32 DN_V2F32_Length(DN_V2F32 lhs) -{ - DN_F32 c_squared = DN_V2F32_LengthSq(lhs); - DN_F32 result = DN_SqrtF32(c_squared); - return result; -} - -DN_API DN_V2F32 DN_V2F32_Normalise(DN_V2F32 a) -{ - DN_F32 length = DN_V2F32_Length(a); - DN_V2F32 result = a / length; - return result; -} - -DN_API DN_V2F32 DN_V2F32_Perpendicular(DN_V2F32 a) -{ - // NOTE: Matrix form of a 2D vector can be defined as - // - // x' = x cos(t) - y sin(t) - // y' = x sin(t) + y cos(t) - // - // Calculate a line perpendicular to a vector means rotating the vector by - // 90 degrees - // - // x' = x cos(90) - y sin(90) - // y' = x sin(90) + y cos(90) - // - // Where `cos(90) = 0` and `sin(90) = 1` then, - // - // x' = -y - // y' = +x - - DN_V2F32 result = DN_V2F32_From2N(-a.y, a.x); - return result; -} - -DN_API DN_V2F32 DN_V2F32_Reflect(DN_V2F32 in, DN_V2F32 surface) -{ - DN_V2F32 normal = DN_V2F32_Perpendicular(surface); - DN_V2F32 normal_norm = DN_V2F32_Normalise(normal); - DN_F32 signed_dist = DN_V2F32_Dot(in, normal_norm); - DN_V2F32 result = DN_V2F32_From2N(in.x, in.y + (-signed_dist * 2.f)); - return result; -} - -DN_API DN_F32 DN_V2F32_Area(DN_V2F32 a) -{ - DN_F32 result = a.w * a.h; - return result; -} - -DN_API bool operator!=(DN_V3F32 lhs, DN_V3F32 rhs) -{ - bool result = !(lhs == rhs); - return result; -} - -DN_API bool operator==(DN_V3F32 lhs, DN_V3F32 rhs) -{ - bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y) && (lhs.z == rhs.z); - return result; -} - -DN_API bool operator>=(DN_V3F32 lhs, DN_V3F32 rhs) -{ - bool result = (lhs.x >= rhs.x) && (lhs.y >= rhs.y) && (lhs.z >= rhs.z); - return result; -} - -DN_API bool operator<=(DN_V3F32 lhs, DN_V3F32 rhs) -{ - bool result = (lhs.x <= rhs.x) && (lhs.y <= rhs.y) && (lhs.z <= rhs.z); - return result; -} - -DN_API bool operator<(DN_V3F32 lhs, DN_V3F32 rhs) -{ - bool result = (lhs.x < rhs.x) && (lhs.y < rhs.y) && (lhs.z < rhs.z); - return result; -} - -DN_API bool operator>(DN_V3F32 lhs, DN_V3F32 rhs) -{ - bool result = (lhs.x > rhs.x) && (lhs.y > rhs.y) && (lhs.z > rhs.z); - return result; -} - -DN_API DN_V3F32 operator-(DN_V3F32 lhs, DN_V3F32 rhs) -{ - DN_V3F32 result = DN_V3F32_From3N(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z); - return result; -} - -DN_API DN_V3F32 operator-(DN_V3F32 lhs) -{ - DN_V3F32 result = DN_V3F32_From3N(-lhs.x, -lhs.y, -lhs.z); - return result; -} - -DN_API DN_V3F32 operator+(DN_V3F32 lhs, DN_V3F32 rhs) -{ - DN_V3F32 result = DN_V3F32_From3N(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z); - return result; -} - -DN_API DN_V3F32 operator*(DN_V3F32 lhs, DN_V3F32 rhs) -{ - DN_V3F32 result = DN_V3F32_From3N(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z); - return result; -} - -DN_API DN_V3F32 operator*(DN_V3F32 lhs, DN_F32 rhs) -{ - DN_V3F32 result = DN_V3F32_From3N(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs); - return result; -} - -DN_API DN_V3F32 operator*(DN_V3F32 lhs, int32_t rhs) -{ - DN_V3F32 result = DN_V3F32_From3N(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs); - return result; -} - -DN_API DN_V3F32 operator/(DN_V3F32 lhs, DN_V3F32 rhs) -{ - DN_V3F32 result = DN_V3F32_From3N(lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z); - return result; -} - -DN_API DN_V3F32 operator/(DN_V3F32 lhs, DN_F32 rhs) -{ - DN_V3F32 result = DN_V3F32_From3N(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs); - return result; -} - -DN_API DN_V3F32 operator/(DN_V3F32 lhs, int32_t rhs) -{ - DN_V3F32 result = DN_V3F32_From3N(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs); - return result; -} - -DN_API DN_V3F32 &operator*=(DN_V3F32 &lhs, DN_V3F32 rhs) -{ - lhs = lhs * rhs; - return lhs; -} - -DN_API DN_V3F32 &operator*=(DN_V3F32 &lhs, DN_F32 rhs) -{ - lhs = lhs * rhs; - return lhs; -} - -DN_API DN_V3F32 &operator*=(DN_V3F32 &lhs, int32_t rhs) -{ - lhs = lhs * rhs; - return lhs; -} - -DN_API DN_V3F32 &operator/=(DN_V3F32 &lhs, DN_V3F32 rhs) -{ - lhs = lhs / rhs; - return lhs; -} - -DN_API DN_V3F32 &operator/=(DN_V3F32 &lhs, DN_F32 rhs) -{ - lhs = lhs / rhs; - return lhs; -} - -DN_API DN_V3F32 &operator/=(DN_V3F32 &lhs, int32_t rhs) -{ - lhs = lhs / rhs; - return lhs; -} - -DN_API DN_V3F32 &operator-=(DN_V3F32 &lhs, DN_V3F32 rhs) -{ - lhs = lhs - rhs; - return lhs; -} - -DN_API DN_V3F32 &operator+=(DN_V3F32 &lhs, DN_V3F32 rhs) -{ - lhs = lhs + rhs; - return lhs; -} - -DN_API DN_F32 DN_V3_LengthSq(DN_V3F32 a) -{ - DN_F32 result = DN_Squared(a.x) + DN_Squared(a.y) + DN_Squared(a.z); - return result; -} - -DN_API DN_F32 DN_V3_Length(DN_V3F32 a) -{ - DN_F32 length_sq = DN_Squared(a.x) + DN_Squared(a.y) + DN_Squared(a.z); - DN_F32 result = DN_SqrtF32(length_sq); - return result; -} - -DN_API DN_V3F32 DN_V3_Normalise(DN_V3F32 a) -{ - DN_F32 length = DN_V3_Length(a); - DN_V3F32 result = a / length; - return result; -} - -DN_API DN_V4F32 DN_V4F32_FromRGBU32(DN_U32 u32) -{ - DN_U8 r = (DN_U8)((u32 & 0x00FF0000) >> 16); - DN_U8 g = (DN_U8)((u32 & 0x0000FF00) >> 8); - DN_U8 b = (DN_U8)((u32 & 0x000000FF) >> 0); - DN_V4F32 result = DN_V4F32_FromRGBU8(r, g, b); - return result; -} - -DN_API DN_V4F32 DN_V4F32_FromRGBAU32(DN_U32 u32) -{ - DN_U8 r = (DN_U8)((u32 & 0xFF000000) >> 24); - DN_U8 g = (DN_U8)((u32 & 0x00FF0000) >> 16); - DN_U8 b = (DN_U8)((u32 & 0x0000FF00) >> 8); - DN_U8 a = (DN_U8)((u32 & 0x000000FF) >> 0); - DN_V4F32 result = DN_V4F32_FromRGBAU8(r, g, b, a); - return result; -} - -DN_API bool operator==(DN_V4F32 lhs, DN_V4F32 rhs) -{ - bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y) && (lhs.z == rhs.z) && (lhs.w == rhs.w); - return result; -} - -DN_API bool operator!=(DN_V4F32 lhs, DN_V4F32 rhs) -{ - bool result = !(lhs == rhs); - return result; -} - -DN_API bool operator>=(DN_V4F32 lhs, DN_V4F32 rhs) -{ - bool result = (lhs.x >= rhs.x) && (lhs.y >= rhs.y) && (lhs.z >= rhs.z) && (lhs.w >= rhs.w); - return result; -} - -DN_API bool operator<=(DN_V4F32 lhs, DN_V4F32 rhs) -{ - bool result = (lhs.x <= rhs.x) && (lhs.y <= rhs.y) && (lhs.z <= rhs.z) && (lhs.w <= rhs.w); - return result; -} - -DN_API bool operator<(DN_V4F32 lhs, DN_V4F32 rhs) -{ - bool result = (lhs.x < rhs.x) && (lhs.y < rhs.y) && (lhs.z < rhs.z) && (lhs.w < rhs.w); - return result; -} - -DN_API bool operator>(DN_V4F32 lhs, DN_V4F32 rhs) -{ - bool result = (lhs.x > rhs.x) && (lhs.y > rhs.y) && (lhs.z > rhs.z) && (lhs.w > rhs.w); - return result; -} - -DN_API DN_V4F32 operator-(DN_V4F32 lhs, DN_V4F32 rhs) -{ - DN_V4F32 result = DN_V4F32_From4N(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w); - return result; -} - -DN_API DN_V4F32 operator-(DN_V4F32 lhs) -{ - DN_V4F32 result = DN_V4F32_From4N(-lhs.x, -lhs.y, -lhs.z, -lhs.w); - return result; -} - -DN_API DN_V4F32 operator+(DN_V4F32 lhs, DN_V4F32 rhs) -{ - DN_V4F32 result = DN_V4F32_From4N(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w); - return result; -} - -DN_API DN_V4F32 operator*(DN_V4F32 lhs, DN_V4F32 rhs) -{ - DN_V4F32 result = DN_V4F32_From4N(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w); - return result; -} - -DN_API DN_V4F32 operator*(DN_V4F32 lhs, DN_F32 rhs) -{ - DN_V4F32 result = DN_V4F32_From4N(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs); - return result; -} - -DN_API DN_V4F32 operator*(DN_V4F32 lhs, int32_t rhs) -{ - DN_V4F32 result = DN_V4F32_From4N(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs); - return result; -} - -DN_API DN_V4F32 operator/(DN_V4F32 lhs, DN_F32 rhs) -{ - DN_V4F32 result = DN_V4F32_From4N(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs, lhs.w / rhs); - return result; -} - -DN_API DN_V4F32 &operator*=(DN_V4F32 &lhs, DN_V4F32 rhs) -{ - lhs = lhs * rhs; - return lhs; -} - -DN_API DN_V4F32 &operator*=(DN_V4F32 &lhs, DN_F32 rhs) -{ - lhs = lhs * rhs; - return lhs; -} - -DN_API DN_V4F32 &operator*=(DN_V4F32 &lhs, int32_t rhs) -{ - lhs = lhs * rhs; - return lhs; -} - -DN_API DN_V4F32 &operator-=(DN_V4F32 &lhs, DN_V4F32 rhs) -{ - lhs = lhs - rhs; - return lhs; -} - -DN_API DN_V4F32 &operator+=(DN_V4F32 &lhs, DN_V4F32 rhs) -{ - lhs = lhs + rhs; - return lhs; -} - -DN_API DN_F32 DN_V4F32Dot(DN_V4F32 a, DN_V4F32 b) -{ - DN_F32 result = (a.x * b.x) + (a.y * b.y) + (a.z * b.z) + (a.w * b.w); - return result; -} - -DN_API DN_M4 DN_M4_Identity() -{ - DN_M4 result = - { - { - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {0, 0, 1, 0}, - {0, 0, 0, 1}, - } - }; - - return result; -} - -DN_API DN_M4 DN_M4_ScaleF(DN_F32 x, DN_F32 y, DN_F32 z) -{ - DN_M4 result = - { - { - {x, 0, 0, 0}, - {0, y, 0, 0}, - {0, 0, z, 0}, - {0, 0, 0, 1}, - } - }; - - return result; -} - -DN_API DN_M4 DN_M4_Scale(DN_V3F32 xyz) -{ - DN_M4 result = - { - { - {xyz.x, 0, 0, 0}, - {0, xyz.y, 0, 0}, - {0, 0, xyz.z, 0}, - {0, 0, 0, 1}, - } - }; - - return result; -} - -DN_API DN_M4 DN_M4_TranslateF(DN_F32 x, DN_F32 y, DN_F32 z) -{ - DN_M4 result = - { - { - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {0, 0, 1, 0}, - {x, y, z, 1}, - } - }; - - return result; -} - -DN_API DN_M4 DN_M4_Translate(DN_V3F32 xyz) -{ - DN_M4 result = - { - { - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {0, 0, 1, 0}, - {xyz.x, xyz.y, xyz.z, 1}, - } - }; - - return result; -} - -DN_API DN_M4 DN_M4_Transpose(DN_M4 mat) -{ - DN_M4 result = {}; - for (int col = 0; col < 4; col++) - for (int row = 0; row < 4; row++) - result.columns[col][row] = mat.columns[row][col]; - return result; -} - -DN_API DN_M4 DN_M4_Rotate(DN_V3F32 axis01, DN_F32 radians) -{ - DN_AssertF(DN_Abs(DN_V3_Length(axis01) - 1.f) <= 0.01f, - "Rotation axis must be normalised, length = %f", - DN_V3_Length(axis01)); - - DN_F32 sin = DN_SinF32(radians); - DN_F32 cos = DN_CosF32(radians); - DN_F32 one_minus_cos = 1.f - cos; - - DN_F32 x = axis01.x; - DN_F32 y = axis01.y; - DN_F32 z = axis01.z; - DN_F32 x2 = DN_Squared(x); - DN_F32 y2 = DN_Squared(y); - DN_F32 z2 = DN_Squared(z); - - DN_M4 result = - { - { - {cos + x2 * one_minus_cos, y * x * one_minus_cos + z * sin, z * x * one_minus_cos - y * sin, 0}, // Col 1 - {x * y * one_minus_cos - z * sin, cos + y2 * one_minus_cos, z * y * one_minus_cos + x * sin, 0}, // Col 2 - {x * z * one_minus_cos + y * sin, y * z * one_minus_cos - x * sin, cos + z2 * one_minus_cos, 0}, // Col 3 - {0, 0, 0, 1}, // Col 4 - } - }; - - return result; -} - -DN_API DN_M4 DN_M4_Orthographic(DN_F32 left, DN_F32 right, DN_F32 bottom, DN_F32 top, DN_F32 z_near, DN_F32 z_far) -{ - // NOTE: Here is the matrix in column major for readability. Below it's - // transposed due to how you have to declare column major matrices in C/C++. - // - // m = [2/r-l, 0, 0, -1*(r+l)/(r-l)] - // [0, 2/t-b, 0, 1*(t+b)/(t-b)] - // [0, 0, -2/f-n, -1*(f+n)/(f-n)] - // [0, 0, 0, 1 ] - - DN_M4 result = - { - { - {2.f / (right - left), 0.f, 0.f, 0.f}, - {0.f, 2.f / (top - bottom), 0.f, 0.f}, - {0.f, 0.f, -2.f / (z_far - z_near), 0.f}, - {(-1.f * (right + left)) / (right - left), (-1.f * (top + bottom)) / (top - bottom), (-1.f * (z_far + z_near)) / (z_far - z_near), 1.f}, - } - }; - - return result; -} - -DN_API DN_M4 DN_M4_Perspective(DN_F32 fov /*radians*/, DN_F32 aspect, DN_F32 z_near, DN_F32 z_far) -{ - DN_F32 tan_fov = DN_TanF32(fov / 2.f); - DN_M4 result = - { - { - {1.f / (aspect * tan_fov), 0.f, 0.f, 0.f}, - {0, 1.f / tan_fov, 0.f, 0.f}, - {0.f, 0.f, (z_near + z_far) / (z_near - z_far), -1.f}, - {0.f, 0.f, (2.f * z_near * z_far) / (z_near - z_far), 0.f}, - } - }; - - return result; -} - -DN_API DN_M4 DN_M4_Add(DN_M4 lhs, DN_M4 rhs) -{ - DN_M4 result; - for (int col = 0; col < 4; col++) - for (int it = 0; it < 4; it++) - result.columns[col][it] = lhs.columns[col][it] + rhs.columns[col][it]; - return result; -} - -DN_API DN_M4 DN_M4_Sub(DN_M4 lhs, DN_M4 rhs) -{ - DN_M4 result; - for (int col = 0; col < 4; col++) - for (int it = 0; it < 4; it++) - result.columns[col][it] = lhs.columns[col][it] - rhs.columns[col][it]; - return result; -} - -DN_API DN_M4 DN_M4_Mul(DN_M4 lhs, DN_M4 rhs) -{ - DN_M4 result; - for (int col = 0; col < 4; col++) { - for (int row = 0; row < 4; row++) { - DN_F32 sum = 0; - for (int f32_it = 0; f32_it < 4; f32_it++) - sum += lhs.columns[f32_it][row] * rhs.columns[col][f32_it]; - - result.columns[col][row] = sum; - } - } - return result; -} - -DN_API DN_M4 DN_M4_Div(DN_M4 lhs, DN_M4 rhs) -{ - DN_M4 result; - for (int col = 0; col < 4; col++) - for (int it = 0; it < 4; it++) - result.columns[col][it] = lhs.columns[col][it] / rhs.columns[col][it]; - return result; -} - -DN_API DN_M4 DN_M4_AddF(DN_M4 lhs, DN_F32 rhs) -{ - DN_M4 result; - for (int col = 0; col < 4; col++) - for (int it = 0; it < 4; it++) - result.columns[col][it] = lhs.columns[col][it] + rhs; - return result; -} - -DN_API DN_M4 DN_M4_SubF(DN_M4 lhs, DN_F32 rhs) -{ - DN_M4 result; - for (int col = 0; col < 4; col++) - for (int it = 0; it < 4; it++) - result.columns[col][it] = lhs.columns[col][it] - rhs; - return result; -} - -DN_API DN_M4 DN_M4_MulF(DN_M4 lhs, DN_F32 rhs) -{ - DN_M4 result; - for (int col = 0; col < 4; col++) - for (int it = 0; it < 4; it++) - result.columns[col][it] = lhs.columns[col][it] * rhs; - return result; -} - -DN_API DN_M4 DN_M4_DivF(DN_M4 lhs, DN_F32 rhs) -{ - DN_M4 result; - for (int col = 0; col < 4; col++) - for (int it = 0; it < 4; it++) - result.columns[col][it] = lhs.columns[col][it] / rhs; - return result; -} - -DN_API DN_Str8x256 DN_M4_ColumnMajorString(DN_M4 mat) -{ - DN_Str8x256 result = {}; - for (int row = 0; row < 4; row++) { - for (int it = 0; it < 4; it++) { - if (it == 0) - DN_FmtAppend(result.data, &result.size, sizeof(result.data), "|"); - DN_FmtAppend(result.data, &result.size, sizeof(result.data), "%.5f", mat.columns[it][row]); - if (it != 3) - DN_FmtAppend(result.data, &result.size, sizeof(result.data), ", "); - else - DN_FmtAppend(result.data, &result.size, sizeof(result.data), "|\n"); - } - } - return result; -} - -DN_API bool operator==(DN_M2x3 const &lhs, DN_M2x3 const &rhs) -{ - bool result = DN_Memcmp(lhs.e, rhs.e, sizeof(lhs.e[0]) * DN_ArrayCountU(lhs.e)) == 0; - return result; -} - -DN_API bool operator!=(DN_M2x3 const &lhs, DN_M2x3 const &rhs) -{ - bool result = !(lhs == rhs); - return result; -} - -DN_API DN_M2x3 DN_M2x3_Identity() -{ - DN_M2x3 result = { - { - 1, - 0, - 0, - 0, - 1, - 0, - } - }; - return result; -} - -DN_API DN_M2x3 DN_M2x3_Translate(DN_V2F32 offset) -{ - DN_M2x3 result = { - { - 1, - 0, - offset.x, - 0, - 1, - offset.y, - } - }; - return result; -} - -DN_API DN_V2F32 DN_M2x3_ScaleGet(DN_M2x3 m2x3) -{ - DN_V2F32 result = DN_V2F32_From2N(m2x3.row[0][0], m2x3.row[1][1]); - return result; -} - -DN_API DN_M2x3 DN_M2x3_Scale(DN_V2F32 scale) -{ - DN_M2x3 result = {{ - scale.x, 0, 0, - 0, scale.y, 0, - }}; - return result; -} - -DN_API DN_M2x3 DN_M2x3_Rotate(DN_F32 radians) -{ - DN_M2x3 result = { - { - DN_CosF32(radians), - DN_SinF32(radians), - 0, - -DN_SinF32(radians), - DN_CosF32(radians), - 0, - } - }; - return result; -} - -DN_API DN_M2x3 DN_M2x3_Mul(DN_M2x3 m1, DN_M2x3 m2) -{ - // NOTE: Ordinarily you can't multiply M2x3 with M2x3 because column count - // (3) != row count (2). We pretend we have two 3x3 matrices with the last - // row set to [0 0 1] and perform a 3x3 matrix multiply. - // - // | (0)a (1)b (2)c | | (0)g (1)h (2)i | - // | (3)d (4)e (5)f | x | (3)j (4)k (5)l | - // | (6)0 (7)0 (8)1 | | (6)0 (7)0 (8)1 | - - DN_M2x3 result = { - { - m1.e[0] * m2.e[0] + m1.e[1] * m2.e[3], // a*g + b*j + c*0[omitted], - m1.e[0] * m2.e[1] + m1.e[1] * m2.e[4], // a*h + b*k + c*0[omitted], - m1.e[0] * m2.e[2] + m1.e[1] * m2.e[5] + m1.e[2], // a*i + b*l + c*1, - - m1.e[3] * m2.e[0] + m1.e[4] * m2.e[3], // d*g + e*j + f*0[omitted], - m1.e[3] * m2.e[1] + m1.e[4] * m2.e[4], // d*h + e*k + f*0[omitted], - m1.e[3] * m2.e[2] + m1.e[4] * m2.e[5] + m1.e[5], // d*i + e*l + f*1, - } - }; - - return result; -} - -DN_API DN_V2F32 DN_M2x3_Mul2F32(DN_M2x3 m1, DN_F32 x, DN_F32 y) -{ - // NOTE: Ordinarily you can't multiply M2x3 with V2 because column count (3) - // != row count (2). We pretend we have a V3 with `z` set to `1`. - // - // | (0)a (1)b (2)c | | x | - // | (3)d (4)e (5)f | x | y | - // | 1 | - - DN_V2F32 result = { - { - m1.e[0] * x + m1.e[1] * y + m1.e[2], // a*x + b*y + c*1 - m1.e[3] * x + m1.e[4] * y + m1.e[5], // d*x + e*y + f*1 - } - }; - return result; -} - -DN_API DN_V2F32 DN_M2x3_MulV2(DN_M2x3 m1, DN_V2F32 v2) -{ - DN_V2F32 result = DN_M2x3_Mul2F32(m1, v2.x, v2.y); - return result; -} - -DN_API bool operator==(const DN_Rect &lhs, const DN_Rect &rhs) -{ - bool result = (lhs.pos == rhs.pos) && (lhs.size == rhs.size); - return result; -} - -DN_API DN_V2F32 DN_Rect_Center(DN_Rect rect) -{ - DN_V2F32 result = rect.pos + (rect.size * .5f); - return result; -} - -DN_API bool DN_Rect_ContainsPoint(DN_Rect rect, DN_V2F32 p) -{ - DN_V2F32 min = rect.pos; - DN_V2F32 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; -} - -DN_API bool DN_Rect_ContainsRect(DN_Rect a, DN_Rect b) -{ - DN_V2F32 a_min = a.pos; - DN_V2F32 a_max = a.pos + a.size; - DN_V2F32 b_min = b.pos; - DN_V2F32 b_max = b.pos + b.size; - bool result = (b_min >= a_min && b_max <= a_max); - return result; -} - -DN_API DN_Rect DN_Rect_Expand(DN_Rect a, DN_F32 amount) -{ - DN_Rect result = a; - result.pos -= amount; - result.size += (amount * 2.f); - return result; -} - -DN_API DN_Rect DN_Rect_ExpandV2(DN_Rect a, DN_V2F32 amount) -{ - DN_Rect result = a; - result.pos -= amount; - result.size += (amount * 2.f); - return result; -} - -DN_API bool DN_Rect_Intersects(DN_Rect a, DN_Rect b) -{ - DN_V2F32 a_min = a.pos; - DN_V2F32 a_max = a.pos + a.size; - DN_V2F32 b_min = b.pos; - DN_V2F32 b_max = b.pos + b.size; - bool has_size = a.size.x && a.size.y && b.size.x && b.size.y; - bool result = false; - if (has_size) - 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; -} - -DN_API DN_Rect DN_Rect_Intersection(DN_Rect a, DN_Rect b) -{ - DN_Rect result = DN_Rect_From2V2(a.pos, DN_V2F32_From1N(0)); - if (DN_Rect_Intersects(a, b)) { - DN_V2F32 a_min = a.pos; - DN_V2F32 a_max = a.pos + a.size; - DN_V2F32 b_min = b.pos; - DN_V2F32 b_max = b.pos + b.size; - - DN_V2F32 min = {}; - DN_V2F32 max = {}; - min.x = DN_Max(a_min.x, b_min.x); - min.y = DN_Max(a_min.y, b_min.y); - max.x = DN_Min(a_max.x, b_max.x); - max.y = DN_Min(a_max.y, b_max.y); - result = DN_Rect_From2V2(min, max - min); - } - return result; -} - -DN_API DN_Rect DN_Rect_Union(DN_Rect a, DN_Rect b) -{ - DN_V2F32 a_min = a.pos; - DN_V2F32 a_max = a.pos + a.size; - DN_V2F32 b_min = b.pos; - DN_V2F32 b_max = b.pos + b.size; - - DN_V2F32 min, max; - min.x = DN_Min(a_min.x, b_min.x); - min.y = DN_Min(a_min.y, b_min.y); - max.x = DN_Max(a_max.x, b_max.x); - max.y = DN_Max(a_max.y, b_max.y); - DN_Rect result = DN_Rect_From2V2(min, max - min); - return result; -} - -DN_API DN_RectMinMax DN_Rect_MinMax(DN_Rect a) -{ - DN_RectMinMax result = {}; - result.min = a.pos; - result.max = a.pos + a.size; - return result; -} - -DN_API DN_F32 DN_Rect_Area(DN_Rect a) -{ - DN_F32 result = a.size.w * a.size.h; - return result; -} - -DN_API DN_Rect DN_Rect_CutLeftClip(DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip) -{ - DN_F32 min_x = rect->pos.x; - DN_F32 max_x = rect->pos.x + rect->size.w; - DN_F32 result_max_x = min_x + amount; - if (clip) - result_max_x = DN_Min(result_max_x, max_x); - DN_Rect result = DN_Rect_From4N(min_x, rect->pos.y, result_max_x - min_x, rect->size.h); - rect->pos.x = result_max_x; - rect->size.w = max_x - result_max_x; - return result; -} - -DN_API DN_Rect DN_Rect_CutRightClip(DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip) -{ - DN_F32 min_x = rect->pos.x; - DN_F32 max_x = rect->pos.x + rect->size.w; - DN_F32 result_min_x = max_x - amount; - if (clip) - result_min_x = DN_Max(result_min_x, 0); - DN_Rect result = DN_Rect_From4N(result_min_x, rect->pos.y, max_x - result_min_x, rect->size.h); - rect->size.w = result_min_x - min_x; - return result; -} - -DN_API DN_Rect DN_Rect_CutTopClip(DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip) -{ - DN_F32 min_y = rect->pos.y; - DN_F32 max_y = rect->pos.y + rect->size.h; - DN_F32 result_max_y = min_y + amount; - if (clip) - result_max_y = DN_Min(result_max_y, max_y); - DN_Rect result = DN_Rect_From4N(rect->pos.x, min_y, rect->size.w, result_max_y - min_y); - rect->pos.y = result_max_y; - rect->size.h = max_y - result_max_y; - return result; -} - -DN_API DN_Rect DN_Rect_CutBottomClip(DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip) -{ - DN_F32 min_y = rect->pos.y; - DN_F32 max_y = rect->pos.y + rect->size.h; - DN_F32 result_min_y = max_y - amount; - if (clip) - result_min_y = DN_Max(result_min_y, 0); - DN_Rect result = DN_Rect_From4N(rect->pos.x, result_min_y, rect->size.w, max_y - result_min_y); - rect->size.h = result_min_y - min_y; - return result; -} - -DN_API DN_Rect DN_RectCut_Cut(DN_RectCut rect_cut, DN_V2F32 size, DN_RectCutClip clip) -{ - DN_Rect result = {}; - if (rect_cut.rect) { - switch (rect_cut.side) { - case DN_RectCutSide_Left: result = DN_Rect_CutLeftClip(rect_cut.rect, size.w, clip); break; - case DN_RectCutSide_Right: result = DN_Rect_CutRightClip(rect_cut.rect, size.w, clip); break; - case DN_RectCutSide_Top: result = DN_Rect_CutTopClip(rect_cut.rect, size.h, clip); break; - case DN_RectCutSide_Bottom: result = DN_Rect_CutBottomClip(rect_cut.rect, size.h, clip); break; - } - } - return result; -} - -DN_API DN_V2F32 DN_Rect_InterpolatedPoint(DN_Rect rect, DN_V2F32 t01) -{ - DN_V2F32 result = DN_V2F32_From2N(rect.pos.w + (rect.size.w * t01.x), - rect.pos.h + (rect.size.h * t01.y)); - return result; -} - -DN_API DN_V2F32 DN_Rect_TopLeft(DN_Rect rect) -{ - DN_V2F32 result = DN_Rect_InterpolatedPoint(rect, DN_V2F32_From2N(0, 0)); - return result; -} - -DN_API DN_V2F32 DN_Rect_TopRight(DN_Rect rect) -{ - DN_V2F32 result = DN_Rect_InterpolatedPoint(rect, DN_V2F32_From2N(1, 0)); - return result; -} - -DN_API DN_V2F32 DN_Rect_BottomLeft(DN_Rect rect) -{ - DN_V2F32 result = DN_Rect_InterpolatedPoint(rect, DN_V2F32_From2N(0, 1)); - return result; -} - -DN_API DN_V2F32 DN_Rect_BottomRight(DN_Rect rect) -{ - DN_V2F32 result = DN_Rect_InterpolatedPoint(rect, DN_V2F32_From2N(1, 1)); - return result; -} - -DN_API DN_RaycastLineIntersectV2Result DN_Raycast_LineIntersectV2(DN_V2F32 origin_a, DN_V2F32 dir_a, DN_V2F32 origin_b, DN_V2F32 dir_b) -{ - // NOTE: Parametric equation of a line - // - // p = o + (t*d) - // - // - o is the starting 2d point - // - d is the direction of the line - // - t is a scalar that scales along the direction of the point - // - // To determine if a ray intersections a ray, we want to solve - // - // (o_a + (t_a * d_a)) = (o_b + (t_b * d_b)) - // - // Where '_a' and '_b' represent the 1st and 2nd point's origin, direction - // and 't' components respectively. This is 2 equations with 2 unknowns - // (`t_a` and `t_b`) which we can solve for by expressing the equation in - // terms of `t_a` and `t_b`. - // - // Working that math out produces the formula below for 't'. - - DN_RaycastLineIntersectV2Result result = {}; - DN_F32 denominator = ((dir_b.y * dir_a.x) - (dir_b.x * dir_a.y)); - if (denominator != 0.0f) { - result.t_a = (((origin_a.y - origin_b.y) * dir_b.x) + ((origin_b.x - origin_a.x) * dir_b.y)) / denominator; - result.t_b = (((origin_a.y - origin_b.y) * dir_a.x) + ((origin_b.x - origin_a.x) * dir_a.y)) / denominator; - result.hit = true; - } - return result; -} - -DN_API DN_V2F32 DN_Lerp_V2F32(DN_V2F32 a, DN_F32 t, DN_V2F32 b) -{ - DN_V2F32 result = {}; - result.x = a.x + ((b.x - a.x) * t); - result.y = a.y + ((b.y - a.y) * t); - return result; -} - -DN_API DN_F32 DN_Lerp_F32(DN_F32 a, DN_F32 t, DN_F32 b) -{ - DN_F32 result = a + ((b - a) * t); - return result; -} diff --git a/Source/Extra/dn_math.h b/Source/Extra/dn_math.h deleted file mode 100644 index 03bce9c..0000000 --- a/Source/Extra/dn_math.h +++ /dev/null @@ -1,376 +0,0 @@ -#if !defined(DN_MATH_H) -#define DN_MATH_H - -#if defined(_CLANGD) - #include "../dn.h" -#endif - -DN_MSVC_WARNING_PUSH -DN_MSVC_WARNING_DISABLE(4201) // warning C4201: nonstandard extension used: nameless struct/union -union DN_V2I32 -{ - struct { DN_I32 x, y; }; - struct { DN_I32 w, h; }; - DN_I32 data[2]; -}; - -union DN_V2U16 -{ - struct { DN_U16 x, y; }; - struct { DN_U16 w, h; }; - DN_U16 data[2]; -}; - -union DN_V2U32 -{ - struct { DN_U32 x, y; }; - struct { DN_U32 w, h; }; - DN_U32 data[2]; -}; - -union DN_V2F32 -{ - struct { DN_F32 x, y; }; - struct { DN_F32 w, h; }; - DN_F32 data[2]; -}; -DN_DArrayStructDecl(DN_V2F32); - -union DN_V3F32 -{ - struct { DN_F32 x, y, z; }; - struct { DN_F32 r, g, b; }; - DN_V2F32 xy; - DN_F32 data[3]; -}; - -union DN_V4F32 -{ - struct { DN_F32 x, y, z, w; }; - struct { DN_F32 r, g, b, a; }; - DN_V3F32 rgb; - DN_V3F32 xyz; - DN_F32 data[4]; -}; -DN_DArrayStructDecl(DN_V4F32); -DN_MSVC_WARNING_POP - -struct DN_M4 -{ - DN_F32 columns[4][4]; // Column major matrix -}; - -union DN_M2x3 -{ - DN_F32 e[6]; - DN_F32 row[2][3]; -}; - -struct DN_Rect -{ - DN_V2F32 pos, size; -}; - -struct DN_RectMinMax -{ - DN_V2F32 min, max; -}; - -enum DN_RectCutClip -{ - DN_RectCutClip_No, - DN_RectCutClip_Yes, -}; - -enum DN_RectCutSide -{ - DN_RectCutSide_Left, - DN_RectCutSide_Right, - DN_RectCutSide_Top, - DN_RectCutSide_Bottom, -}; - -struct DN_RectCut -{ - DN_Rect* rect; - DN_RectCutSide side; -}; - -struct DN_RaycastLineIntersectV2Result -{ - bool hit; // True if there was an intersection, false if the lines are parallel - DN_F32 t_a; // Distance along `dir_a` that the intersection occurred, e.g. `origin_a + (dir_a * t_a)` - DN_F32 t_b; // Distance along `dir_b` that the intersection occurred, e.g. `origin_b + (dir_b * t_b)` -}; - -#define DN_V2I32_Zero DN_Literal(DN_V2I32){{(int32_t)(0), (int32_t)(0)}} -#define DN_V2I32_One DN_Literal(DN_V2I32){{(int32_t)(1), (int32_t)(1)}} -#define DN_V2I32_From1N(x) DN_Literal(DN_V2I32){{(int32_t)(x), (int32_t)(x)}} -#define DN_V2I32_From2N(x, y) DN_Literal(DN_V2I32){{(int32_t)(x), (int32_t)(y)}} -#define DN_V2I32_InitV2(xy) DN_Literal(DN_V2I32){{(int32_t)(xy).x, (int32_t)(xy).y}} - -DN_API bool operator!= (DN_V2I32 lhs, DN_V2I32 rhs); -DN_API bool operator== (DN_V2I32 lhs, DN_V2I32 rhs); -DN_API bool operator>= (DN_V2I32 lhs, DN_V2I32 rhs); -DN_API bool operator<= (DN_V2I32 lhs, DN_V2I32 rhs); -DN_API bool operator< (DN_V2I32 lhs, DN_V2I32 rhs); -DN_API bool operator> (DN_V2I32 lhs, DN_V2I32 rhs); -DN_API DN_V2I32 operator- (DN_V2I32 lhs, DN_V2I32 rhs); -DN_API DN_V2I32 operator- (DN_V2I32 lhs); -DN_API DN_V2I32 operator+ (DN_V2I32 lhs, DN_V2I32 rhs); -DN_API DN_V2I32 operator* (DN_V2I32 lhs, DN_V2I32 rhs); -DN_API DN_V2I32 operator* (DN_V2I32 lhs, DN_F32 rhs); -DN_API DN_V2I32 operator* (DN_V2I32 lhs, int32_t rhs); -DN_API DN_V2I32 operator/ (DN_V2I32 lhs, DN_V2I32 rhs); -DN_API DN_V2I32 operator/ (DN_V2I32 lhs, DN_F32 rhs); -DN_API DN_V2I32 operator/ (DN_V2I32 lhs, int32_t rhs); -DN_API DN_V2I32 & operator*= (DN_V2I32& lhs, DN_V2I32 rhs); -DN_API DN_V2I32 & operator*= (DN_V2I32& lhs, DN_F32 rhs); -DN_API DN_V2I32 & operator*= (DN_V2I32& lhs, int32_t rhs); -DN_API DN_V2I32 & operator/= (DN_V2I32& lhs, DN_V2I32 rhs); -DN_API DN_V2I32 & operator/= (DN_V2I32& lhs, DN_F32 rhs); -DN_API DN_V2I32 & operator/= (DN_V2I32& lhs, int32_t rhs); -DN_API DN_V2I32 & operator-= (DN_V2I32& lhs, DN_V2I32 rhs); -DN_API DN_V2I32 & operator+= (DN_V2I32& lhs, DN_V2I32 rhs); - -DN_API DN_V2I32 DN_V2I32_Min (DN_V2I32 a, DN_V2I32 b); -DN_API DN_V2I32 DN_V2I32_Max (DN_V2I32 a, DN_V2I32 b); -DN_API DN_V2I32 DN_V2I32_Abs (DN_V2I32 a); - -#define DN_V2U16_Zero DN_Literal(DN_V2U16){{(DN_U16)(0), (DN_U16)(0)}} -#define DN_V2U16_One DN_Literal(DN_V2U16){{(DN_U16)(1), (DN_U16)(1)}} -#define DN_V2U16_From1N(x) DN_Literal(DN_V2U16){{(DN_U16)(x), (DN_U16)(x)}} -#define DN_V2U16_From2N(x, y) DN_Literal(DN_V2U16){{(DN_U16)(x), (DN_U16)(y)}} - -DN_API bool operator!= (DN_V2U16 lhs, DN_V2U16 rhs); -DN_API bool operator== (DN_V2U16 lhs, DN_V2U16 rhs); -DN_API bool operator>= (DN_V2U16 lhs, DN_V2U16 rhs); -DN_API bool operator<= (DN_V2U16 lhs, DN_V2U16 rhs); -DN_API bool operator< (DN_V2U16 lhs, DN_V2U16 rhs); -DN_API bool operator> (DN_V2U16 lhs, DN_V2U16 rhs); -DN_API DN_V2U16 operator- (DN_V2U16 lhs, DN_V2U16 rhs); -DN_API DN_V2U16 operator+ (DN_V2U16 lhs, DN_V2U16 rhs); -DN_API DN_V2U16 operator* (DN_V2U16 lhs, DN_V2U16 rhs); -DN_API DN_V2U16 operator* (DN_V2U16 lhs, DN_F32 rhs); -DN_API DN_V2U16 operator* (DN_V2U16 lhs, int32_t rhs); -DN_API DN_V2U16 operator/ (DN_V2U16 lhs, DN_V2U16 rhs); -DN_API DN_V2U16 operator/ (DN_V2U16 lhs, DN_F32 rhs); -DN_API DN_V2U16 operator/ (DN_V2U16 lhs, int32_t rhs); -DN_API DN_V2U16 & operator*= (DN_V2U16& lhs, DN_V2U16 rhs); -DN_API DN_V2U16 & operator*= (DN_V2U16& lhs, DN_F32 rhs); -DN_API DN_V2U16 & operator*= (DN_V2U16& lhs, int32_t rhs); -DN_API DN_V2U16 & operator/= (DN_V2U16& lhs, DN_V2U16 rhs); -DN_API DN_V2U16 & operator/= (DN_V2U16& lhs, DN_F32 rhs); -DN_API DN_V2U16 & operator/= (DN_V2U16& lhs, int32_t rhs); -DN_API DN_V2U16 & operator-= (DN_V2U16& lhs, DN_V2U16 rhs); -DN_API DN_V2U16 & operator+= (DN_V2U16& lhs, DN_V2U16 rhs); - -#define DN_V2U32_Zero DN_Literal(DN_V2U32){{(DN_U32)(0), (DN_U32)(0)}} -#define DN_V2U32_One DN_Literal(DN_V2U32){{(DN_U32)(1), (DN_U32)(1)}} -#define DN_V2U32_From1N(x) DN_Literal(DN_V2U32){{(DN_U32)(x), (DN_U32)(x)}} -#define DN_V2U32_From2N(x, y) DN_Literal(DN_V2U32){{(DN_U32)(x), (DN_U32)(y)}} - -#define DN_V2F32_Zero DN_Literal(DN_V2F32){{(DN_F32)(0), (DN_F32)(0)}} -#define DN_V2F32_One DN_Literal(DN_V2F32){{(DN_F32)(1), (DN_F32)(1)}} -#define DN_V2F32_From1N(x) DN_Literal(DN_V2F32){{(DN_F32)(x), (DN_F32)(x)}} -#define DN_V2F32_From2N(x, y) DN_Literal(DN_V2F32){{(DN_F32)(x), (DN_F32)(y)}} -#define DN_V2F32_FromV2I32(xy) DN_Literal(DN_V2F32){{(DN_F32)(xy).x, (DN_F32)(xy).y}} -#define DN_V2F32_FromV2U32(xy) DN_Literal(DN_V2F32){{(DN_F32)(xy).x, (DN_F32)(xy).y}} - -DN_API bool operator!= (DN_V2F32 lhs, DN_V2F32 rhs); -DN_API bool operator== (DN_V2F32 lhs, DN_V2F32 rhs); -DN_API bool operator>= (DN_V2F32 lhs, DN_V2F32 rhs); -DN_API bool operator<= (DN_V2F32 lhs, DN_V2F32 rhs); -DN_API bool operator< (DN_V2F32 lhs, DN_V2F32 rhs); -DN_API bool operator> (DN_V2F32 lhs, DN_V2F32 rhs); - -DN_API DN_V2F32 operator- (DN_V2F32 lhs); -DN_API DN_V2F32 operator- (DN_V2F32 lhs, DN_V2F32 rhs); -DN_API DN_V2F32 operator- (DN_V2F32 lhs, DN_V2I32 rhs); -DN_API DN_V2F32 operator- (DN_V2F32 lhs, DN_F32 rhs); -DN_API DN_V2F32 operator- (DN_V2F32 lhs, int32_t rhs); - -DN_API DN_V2F32 operator+ (DN_V2F32 lhs, DN_V2F32 rhs); -DN_API DN_V2F32 operator+ (DN_V2F32 lhs, DN_V2I32 rhs); -DN_API DN_V2F32 operator+ (DN_V2F32 lhs, DN_F32 rhs); -DN_API DN_V2F32 operator+ (DN_V2F32 lhs, int32_t rhs); - -DN_API DN_V2F32 operator* (DN_V2F32 lhs, DN_V2F32 rhs); -DN_API DN_V2F32 operator* (DN_V2F32 lhs, DN_V2I32 rhs); -DN_API DN_V2F32 operator* (DN_V2F32 lhs, DN_F32 rhs); -DN_API DN_V2F32 operator* (DN_V2F32 lhs, int32_t rhs); - -DN_API DN_V2F32 operator/ (DN_V2F32 lhs, DN_V2F32 rhs); -DN_API DN_V2F32 operator/ (DN_V2F32 lhs, DN_V2I32 rhs); -DN_API DN_V2F32 operator/ (DN_V2F32 lhs, DN_F32 rhs); -DN_API DN_V2F32 operator/ (DN_V2F32 lhs, int32_t rhs); - -DN_API DN_V2F32 & operator*= (DN_V2F32& lhs, DN_V2F32 rhs); -DN_API DN_V2F32 & operator*= (DN_V2F32& lhs, DN_V2I32 rhs); -DN_API DN_V2F32 & operator*= (DN_V2F32& lhs, DN_F32 rhs); -DN_API DN_V2F32 & operator*= (DN_V2F32& lhs, int32_t rhs); - -DN_API DN_V2F32 & operator/= (DN_V2F32& lhs, DN_V2F32 rhs); -DN_API DN_V2F32 & operator/= (DN_V2F32& lhs, DN_V2I32 rhs); -DN_API DN_V2F32 & operator/= (DN_V2F32& lhs, DN_F32 rhs); -DN_API DN_V2F32 & operator/= (DN_V2F32& lhs, int32_t rhs); - -DN_API DN_V2F32 & operator-= (DN_V2F32& lhs, DN_V2F32 rhs); -DN_API DN_V2F32 & operator-= (DN_V2F32& lhs, DN_V2I32 rhs); -DN_API DN_V2F32 & operator-= (DN_V2F32& lhs, DN_F32 rhs); -DN_API DN_V2F32 & operator-= (DN_V2F32& lhs, int32_t rhs); - -DN_API DN_V2F32 & operator+= (DN_V2F32& lhs, DN_V2F32 rhs); -DN_API DN_V2F32 & operator+= (DN_V2F32& lhs, DN_V2I32 rhs); -DN_API DN_V2F32 & operator+= (DN_V2F32& lhs, DN_F32 rhs); -DN_API DN_V2F32 & operator+= (DN_V2F32& lhs, int32_t rhs); - -DN_API DN_V2F32 DN_V2F32_Min (DN_V2F32 a, DN_V2F32 b); -DN_API DN_V2F32 DN_V2F32_Max (DN_V2F32 a, DN_V2F32 b); -DN_API DN_V2F32 DN_V2F32_Abs (DN_V2F32 a); -DN_API DN_F32 DN_V2F32_Dot (DN_V2F32 a, DN_V2F32 b); -DN_API DN_F32 DN_V2F32_LengthSq2V2 (DN_V2F32 lhs, DN_V2F32 rhs); -DN_API bool DN_V2F32_LengthSqIsWithin2V2 (DN_V2F32 lhs, DN_V2F32 rhs, DN_F32 within_amount_sq); -DN_API DN_F32 DN_V2F32_Length2V2 (DN_V2F32 lhs, DN_V2F32 rhs); -DN_API DN_F32 DN_V2F32_LengthSq (DN_V2F32 lhs); -DN_API DN_F32 DN_V2F32_Length (DN_V2F32 lhs); -DN_API DN_V2F32 DN_V2F32_Normalise (DN_V2F32 a); -DN_API DN_V2F32 DN_V2F32_Perpendicular (DN_V2F32 a); -DN_API DN_V2F32 DN_V2F32_Reflect (DN_V2F32 in, DN_V2F32 surface); -DN_API DN_F32 DN_V2F32_Area (DN_V2F32 a); - -#define DN_V3F32_From1N(x) DN_Literal(DN_V3F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}} -#define DN_V3F32_From3N(x, y, z) DN_Literal(DN_V3F32){{(DN_F32)(x), (DN_F32)(y), (DN_F32)(z)}} -#define DN_V3F32_FromV2F32And1N(xy, z) DN_Literal(DN_V3F32){{(DN_F32)(xy.x), (DN_F32)(xy.y), (DN_F32)(z)}} - -DN_API bool operator== (DN_V3F32 lhs, DN_V3F32 rhs); -DN_API bool operator!= (DN_V3F32 lhs, DN_V3F32 rhs); -DN_API bool operator>= (DN_V3F32 lhs, DN_V3F32 rhs); -DN_API bool operator<= (DN_V3F32 lhs, DN_V3F32 rhs); -DN_API bool operator< (DN_V3F32 lhs, DN_V3F32 rhs); -DN_API bool operator> (DN_V3F32 lhs, DN_V3F32 rhs); -DN_API DN_V3F32 operator- (DN_V3F32 lhs, DN_V3F32 rhs); -DN_API DN_V3F32 operator- (DN_V3F32 lhs); -DN_API DN_V3F32 operator+ (DN_V3F32 lhs, DN_V3F32 rhs); -DN_API DN_V3F32 operator* (DN_V3F32 lhs, DN_V3F32 rhs); -DN_API DN_V3F32 operator* (DN_V3F32 lhs, DN_F32 rhs); -DN_API DN_V3F32 operator* (DN_V3F32 lhs, int32_t rhs); -DN_API DN_V3F32 operator/ (DN_V3F32 lhs, DN_V3F32 rhs); -DN_API DN_V3F32 operator/ (DN_V3F32 lhs, DN_F32 rhs); -DN_API DN_V3F32 operator/ (DN_V3F32 lhs, int32_t rhs); -DN_API DN_V3F32 & operator*= (DN_V3F32 &lhs, DN_V3F32 rhs); -DN_API DN_V3F32 & operator*= (DN_V3F32 &lhs, DN_F32 rhs); -DN_API DN_V3F32 & operator*= (DN_V3F32 &lhs, int32_t rhs); -DN_API DN_V3F32 & operator/= (DN_V3F32 &lhs, DN_V3F32 rhs); -DN_API DN_V3F32 & operator/= (DN_V3F32 &lhs, DN_F32 rhs); -DN_API DN_V3F32 & operator/= (DN_V3F32 &lhs, int32_t rhs); -DN_API DN_V3F32 & operator-= (DN_V3F32 &lhs, DN_V3F32 rhs); -DN_API DN_V3F32 & operator+= (DN_V3F32 &lhs, DN_V3F32 rhs); -DN_API DN_F32 DN_V3F32_LengthSq (DN_V3F32 a); -DN_API DN_F32 DN_V3F32_Length (DN_V3F32 a); -DN_API DN_V3F32 DN_V3F32_Normalise (DN_V3F32 a); - -#define DN_V4F32_From1N(x) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}} -#define DN_V4F32_From4N(x, y, z, w) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(y), (DN_F32)(z), (DN_F32)(w)}} -#define DN_V4F32_FromV3And1N(xyz, w) DN_Literal(DN_V4F32){{xyz.x, xyz.y, xyz.z, w}} -#define DN_V4F32_FromRGBAU8(r, g, b, a) DN_Literal(DN_V4F32){{r / 255.f, g / 255.f, b / 255.f, a / 255.f}} -#define DN_V4F32_FromRGBU8(r, g, b) DN_Literal(DN_V4F32){{r / 255.f, g / 255.f, b / 255.f, 1.f}} -DN_API DN_V4F32 DN_V4F32_FromRGBU32(DN_U32 u32); -DN_API DN_V4F32 DN_V4F32_FromRGBAU32(DN_U32 u32); -#define DN_V4F32_FromV4Alpha(v4, alpha) DN_V4F32_FromV3And1N(v4.xyz, alpha) -DN_API bool operator== (DN_V4F32 lhs, DN_V4F32 rhs); -DN_API bool operator!= (DN_V4F32 lhs, DN_V4F32 rhs); -DN_API bool operator<= (DN_V4F32 lhs, DN_V4F32 rhs); -DN_API bool operator< (DN_V4F32 lhs, DN_V4F32 rhs); -DN_API bool operator> (DN_V4F32 lhs, DN_V4F32 rhs); -DN_API DN_V4F32 operator- (DN_V4F32 lhs, DN_V4F32 rhs); -DN_API DN_V4F32 operator- (DN_V4F32 lhs); -DN_API DN_V4F32 operator+ (DN_V4F32 lhs, DN_V4F32 rhs); -DN_API DN_V4F32 operator* (DN_V4F32 lhs, DN_V4F32 rhs); -DN_API DN_V4F32 operator* (DN_V4F32 lhs, DN_F32 rhs); -DN_API DN_V4F32 operator* (DN_V4F32 lhs, int32_t rhs); -DN_API DN_V4F32 operator/ (DN_V4F32 lhs, DN_F32 rhs); -DN_API DN_V4F32 & operator*= (DN_V4F32 &lhs, DN_V4F32 rhs); -DN_API DN_V4F32 & operator*= (DN_V4F32 &lhs, DN_F32 rhs); -DN_API DN_V4F32 & operator*= (DN_V4F32 &lhs, int32_t rhs); -DN_API DN_V4F32 & operator-= (DN_V4F32 &lhs, DN_V4F32 rhs); -DN_API DN_V4F32 & operator+= (DN_V4F32 &lhs, DN_V4F32 rhs); -DN_API DN_F32 DN_V4F32_Dot (DN_V4F32 a, DN_V4F32 b); - -DN_API DN_M4 DN_M4_Identity (); -DN_API DN_M4 DN_M4_ScaleF (DN_F32 x, DN_F32 y, DN_F32 z); -DN_API DN_M4 DN_M4_Scale (DN_V3F32 xyz); -DN_API DN_M4 DN_M4_TranslateF (DN_F32 x, DN_F32 y, DN_F32 z); -DN_API DN_M4 DN_M4_Translate (DN_V3F32 xyz); -DN_API DN_M4 DN_M4_Transpose (DN_M4 mat); -DN_API DN_M4 DN_M4_Rotate (DN_V3F32 axis, DN_F32 radians); -DN_API DN_M4 DN_M4_Orthographic (DN_F32 left, DN_F32 right, DN_F32 bottom, DN_F32 top, DN_F32 z_near, DN_F32 z_far); -DN_API DN_M4 DN_M4_Perspective (DN_F32 fov /*radians*/, DN_F32 aspect, DN_F32 z_near, DN_F32 z_far); -DN_API DN_M4 DN_M4_Add (DN_M4 lhs, DN_M4 rhs); -DN_API DN_M4 DN_M4_Sub (DN_M4 lhs, DN_M4 rhs); -DN_API DN_M4 DN_M4_Mul (DN_M4 lhs, DN_M4 rhs); -DN_API DN_M4 DN_M4_Div (DN_M4 lhs, DN_M4 rhs); -DN_API DN_M4 DN_M4_AddF (DN_M4 lhs, DN_F32 rhs); -DN_API DN_M4 DN_M4_SubF (DN_M4 lhs, DN_F32 rhs); -DN_API DN_M4 DN_M4_MulF (DN_M4 lhs, DN_F32 rhs); -DN_API DN_M4 DN_M4_DivF (DN_M4 lhs, DN_F32 rhs); -DN_API DN_Str8x256 DN_M4_ColumnMajorString (DN_M4 mat); - -DN_API bool operator== (DN_M2x3 const &lhs, DN_M2x3 const &rhs); -DN_API bool operator!= (DN_M2x3 const &lhs, DN_M2x3 const &rhs); -DN_API DN_M2x3 DN_M2x3_Identity (); -DN_API DN_M2x3 DN_M2x3_Translate (DN_V2F32 offset); -DN_API DN_V2F32 DN_M2x3_ScaleGet (DN_M2x3 m2x3); -DN_API DN_M2x3 DN_M2x3_Scale (DN_V2F32 scale); -DN_API DN_M2x3 DN_M2x3_Rotate (DN_F32 radians); -DN_API DN_M2x3 DN_M2x3_Mul (DN_M2x3 m1, DN_M2x3 m2); -DN_API DN_V2F32 DN_M2x3_Mul2F32 (DN_M2x3 m1, DN_F32 x, DN_F32 y); -DN_API DN_V2F32 DN_M2x3_MulV2 (DN_M2x3 m1, DN_V2F32 v2); - -#define DN_Rect_From2V2(pos, size) DN_Literal(DN_Rect){(pos), (size)} -#define DN_Rect_From4N(x, y, w, h) DN_Literal(DN_Rect){DN_Literal(DN_V2F32){{x, y}}, DN_Literal(DN_V2F32){{w, h}}} -#define DN_Rect_Zero DN_Rect_From4N(0, 0, 0, 0) - -DN_API bool operator== (const DN_Rect& lhs, const DN_Rect& rhs); -DN_API DN_V2F32 DN_Rect_Center (DN_Rect rect); -DN_API bool DN_Rect_ContainsPoint (DN_Rect rect, DN_V2F32 p); -DN_API bool DN_Rect_ContainsRect (DN_Rect a, DN_Rect b); -DN_API DN_Rect DN_Rect_Expand (DN_Rect a, DN_F32 amount); -DN_API DN_Rect DN_Rect_ExpandV2 (DN_Rect a, DN_V2F32 amount); -DN_API bool DN_Rect_Intersects (DN_Rect a, DN_Rect b); -DN_API DN_Rect DN_Rect_Intersection (DN_Rect a, DN_Rect b); -DN_API DN_Rect DN_Rect_Union (DN_Rect a, DN_Rect b); -DN_API DN_RectMinMax DN_Rect_MinMax (DN_Rect a); -DN_API DN_F32 DN_Rect_Area (DN_Rect a); -DN_API DN_V2F32 DN_Rect_InterpolatedPoint (DN_Rect rect, DN_V2F32 t01); -DN_API DN_V2F32 DN_Rect_TopLeft (DN_Rect rect); -DN_API DN_V2F32 DN_Rect_TopRight (DN_Rect rect); -DN_API DN_V2F32 DN_Rect_BottomLeft (DN_Rect rect); -DN_API DN_V2F32 DN_Rect_BottomRight (DN_Rect rect); - -DN_API DN_Rect DN_Rect_CutLeftClip (DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip); -DN_API DN_Rect DN_Rect_CutRightClip (DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip); -DN_API DN_Rect DN_Rect_CutTopClip (DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip); -DN_API DN_Rect DN_Rect_CutBottomClip (DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip); - -#define DN_Rect_CutLeft(rect, amount) DN_Rect_CutLeftClip(rect, amount, DN_RectCutClip_Yes) -#define DN_Rect_CutRight(rect, amount) DN_Rect_CutRightClip(rect, amount, DN_RectCutClip_Yes) -#define DN_Rect_CutTop(rect, amount) DN_Rect_CutTopClip(rect, amount, DN_RectCutClip_Yes) -#define DN_Rect_CutBottom(rect, amount) DN_Rect_CutBottomClip(rect, amount, DN_RectCutClip_Yes) - -#define DN_Rect_CutLeftNoClip(rect, amount) DN_Rect_CutLeftClip(rect, amount, DN_RectCutClip_No) -#define DN_Rect_CutRightNoClip(rect, amount) DN_Rect_CutRightClip(rect, amount, DN_RectCutClip_No) -#define DN_Rect_CutTopNoClip(rect, amount) DN_Rect_CutTopClip(rect, amount, DN_RectCutClip_No) -#define DN_Rect_CutBottomNoClip(rect, amount) DN_Rect_CutBottomClip(rect, amount, DN_RectCutClip_No) - -DN_API DN_Rect DN_RectCut_Cut (DN_RectCut rect_cut, DN_V2F32 size, DN_RectCutClip clip); -#define DN_RectCut_Init(rect, side) DN_Literal(DN_RectCut){rect, side} -#define DN_RectCut_Left(rect) DN_Literal(DN_RectCut){rect, DN_RectCutSide_Left} -#define DN_RectCut_Right(rect) DN_Literal(DN_RectCut){rect, DN_RectCutSide_Right} -#define DN_RectCut_Top(rect) DN_Literal(DN_RectCut){rect, DN_RectCutSide_Top} -#define DN_RectCut_Bottom(rect) DN_Literal(DN_RectCut){rect, DN_RectCutSide_Bottom} - -DN_API DN_RaycastLineIntersectV2Result DN_Raycast_LineIntersectV2(DN_V2F32 origin_a, DN_V2F32 dir_a, DN_V2F32 origin_b, DN_V2F32 dir_b); -DN_API DN_V2F32 DN_Lerp_V2F32 (DN_V2F32 a, DN_F32 t, DN_V2F32 b); -DN_API DN_F32 DN_Lerp_F32 (DN_F32 a, DN_F32 t, DN_F32 b); -#endif // !defined(DN_MATH_H) diff --git a/Source/OS/dn_os.cpp b/Source/OS/dn_os.cpp index 3ee385c..e0bef14 100644 --- a/Source/OS/dn_os.cpp +++ b/Source/OS/dn_os.cpp @@ -408,10 +408,10 @@ DN_API DN_Str8 DN_OS_FileReadAll(DN_Allocator alloc_type, void *allocator, DN_St if (alloc_type == DN_Allocator_Arena) { DN_Arena *arena = DN_Cast(DN_Arena *) allocator; arena_tmp = DN_ArenaTempMemBegin(arena); - result = DN_Str8FromArena(arena, path_info.size, DN_ZMem_No); + result = DN_Str8AllocArena(arena, path_info.size, DN_ZMem_No); } else { DN_Pool *pool = DN_Cast(DN_Pool *) allocator; - result = DN_Str8FromPool(pool, path_info.size); + result = DN_Str8AllocPool(pool, path_info.size); } if (!result.data) { @@ -639,7 +639,7 @@ DN_API DN_Str8 DN_OS_PathBuildWithSeparator(DN_Arena *arena, DN_OSPath const *fs // NOTE: Each link except the last one needs the path separator appended to it, '/' or '\\' DN_USize string_size = (fs_path->has_prefix_path_separator ? path_separator.size : 0) + fs_path->string_size + ((fs_path->links_size - 1) * path_separator.size); - result = DN_Str8FromArena(arena, string_size, DN_ZMem_No); + result = DN_Str8AllocArena(arena, string_size, DN_ZMem_No); if (result.data) { char *dest = result.data; if (fs_path->has_prefix_path_separator) { @@ -664,17 +664,14 @@ DN_API DN_Str8 DN_OS_PathBuildWithSeparator(DN_Arena *arena, DN_OSPath const *fs } // NOTE: DN_OSExec -DN_API DN_OSExecResult DN_OS_Exec(DN_Slice cmd_line, - DN_OSExecArgs *args, - DN_Arena *arena, - DN_ErrSink *error) +DN_API DN_OSExecResult DN_OS_Exec(DN_Str8Slice cmd_line, DN_OSExecArgs *args, DN_Arena *arena, DN_ErrSink *error) { DN_OSExecAsyncHandle async_handle = DN_OS_ExecAsync(cmd_line, args, error); DN_OSExecResult result = DN_OS_ExecWait(async_handle, arena, error); return result; } -DN_API DN_OSExecResult DN_OS_ExecOrAbort(DN_Slice cmd_line, DN_OSExecArgs *args, DN_Arena *arena) +DN_API DN_OSExecResult DN_OS_ExecOrAbort(DN_Str8Slice cmd_line, DN_OSExecArgs *args, DN_Arena *arena) { DN_ErrSink *error = DN_TCErrSinkBegin(DN_ErrSinkMode_Nil); DN_OSExecResult result = DN_OS_Exec(cmd_line, args, arena, error); @@ -694,8 +691,12 @@ static void DN_OS_ThreadExecute_(void *user_context) DN_ArenaMemFuncs mem_funcs = DN_ArenaMemFuncsGetDefaults(); DN_TCInitFromMemFuncs(&thread->context, thread->thread_id, /*args=*/nullptr, mem_funcs); DN_TCEquip(&thread->context); - if (thread->is_lane_set) - DN_TCLaneEquip(thread->lane); + if (thread->is_lane_set) { + DN_OS_TCThreadLaneEquip(thread->lane); + DN_OS_ThreadSetNameFmt("L%02zu/%02zu T%zu", thread->lane.index, thread->lane.count, thread->thread_id); + } else { + DN_OS_ThreadSetNameFmt("T%zu", thread->lane.index, thread->lane.count, thread->thread_id); + } DN_OS_SemaphoreWait(&thread->init_semaphore, DN_OS_SEMAPHORE_INFINITE_TIMEOUT); thread->func(thread); } @@ -716,7 +717,85 @@ DN_API void DN_OS_ThreadSetNameFmt(char const *fmt, ...) #endif } -// NOTE: DN_OSHttp ///////////////////////////////////////////////////////////////////////////////// +DN_API DN_OSThreadLane DN_OS_ThreadLaneInit(DN_USize index, DN_USize thread_count, DN_OSBarrier barrier, DN_UPtr *shared_mem) +{ + DN_OSThreadLane result = {}; + result.index = index; + result.count = thread_count; + result.barrier = barrier; + result.shared_mem = shared_mem; + return result; +} + +DN_API void DN_OS_ThreadLaneSync(DN_OSThreadLane *lane, void **ptr_to_share) +{ + if (!lane) + return; + + // NOTE: Write the pointer into shared memory (if we're the lane producing the data) + bool sharing = false; + if (ptr_to_share && *ptr_to_share) { + DN_Memcpy(lane->shared_mem, ptr_to_share, sizeof(*ptr_to_share)); + sharing = true; + } + + DN_OS_BarrierWait(&lane->barrier); // NOTE: Ensure sharing lane has completed the write + + // NOTE: Read pointer from shared memory (if we're the other lanes that read the data) + if (ptr_to_share && !(*ptr_to_share)) { + sharing = true; + DN_Memcpy(ptr_to_share, lane->shared_mem, sizeof(*ptr_to_share)); + } + + if (sharing) + DN_OS_BarrierWait(&lane->barrier); // NOTE: Ensure the reading lanes have completed the read +} + +DN_API DN_V2USize DN_OS_ThreadLaneRange(DN_OSThreadLane *lane, DN_USize values_count) +{ + DN_USize values_per_thread = values_count / lane->count; + DN_USize rem_values = values_count % lane->count; + bool thread_has_leftovers = lane->index < rem_values; + DN_USize leftovers_before_this_thread_index = 0; + + if (thread_has_leftovers) + leftovers_before_this_thread_index = lane->index; + else + leftovers_before_this_thread_index = leftovers_before_this_thread_index; + + DN_USize thread_start_index = (values_per_thread * lane->index) + leftovers_before_this_thread_index; + DN_USize thread_values_count = values_per_thread + (thread_has_leftovers ? 1 : 0); + + DN_V2USize result = {}; + result.begin = thread_start_index; + result.end = result.begin + thread_values_count; + return result; +} + +DN_API DN_OSThreadLane *DN_OS_TCThreadLane() +{ + DN_TCCore *tc = DN_TCGet(); + DN_OSThreadLane *result = tc ? DN_Cast(DN_OSThreadLane *) tc->lane_opaque : nullptr; + return result; +} + +DN_API void DN_OS_TCThreadLaneSync(void **ptr_to_share) +{ + DN_OSThreadLane *lane = DN_OS_TCThreadLane(); + DN_OS_ThreadLaneSync(lane, ptr_to_share); +} + +DN_API DN_OSThreadLane DN_OS_TCThreadLaneEquip(DN_OSThreadLane lane) +{ + DN_TCCore *tc = DN_TCGet(); + DN_OSThreadLane *curr = DN_Cast(DN_OSThreadLane *) tc->lane_opaque; + DN_StaticAssert(sizeof(tc->lane_opaque) >= sizeof(DN_OSThreadLane)); + DN_OSThreadLane result = *curr; + *curr = lane; + return result; +} + +// NOTE: DN_OSHttp DN_API void DN_OS_HttpRequestWait(DN_OSHttpResponse *response) { if (response && response->on_complete_semaphore.handle != 0) @@ -925,21 +1004,13 @@ DN_VArray DN_OS_VArrayInit(DN_USize max) return result; } -template -DN_VArray DN_OS_VArrayInitSlice(DN_Slice slice, DN_USize max) -{ - DN_USize real_max = DN_Max(slice.size, max); - DN_VArray result = DN_OS_VArrayInit(real_max); - if (DN_OS_VArrayIsValid(&result)) - DN_OS_VArrayAddArray(&result, slice.data, slice.size); - return result; -} - template DN_VArray DN_OS_VArrayInitCArray(T const (&items)[N], DN_USize max) { DN_USize real_max = DN_Max(N, max); - DN_VArray result = DN_OS_VArrayInitSlice(DN_Slice_Init(items, N), real_max); + DN_VArray result = DN_OS_VArrayInit(real_max); + if (DN_OS_VArrayIsValid(&result)) + DN_OS_VArrayAddArray(&result, items, N); return result; } diff --git a/Source/OS/dn_os.h b/Source/OS/dn_os.h index fd197f1..ba63f5a 100644 --- a/Source/OS/dn_os.h +++ b/Source/OS/dn_os.h @@ -161,9 +161,9 @@ struct DN_OSExecResult struct DN_OSExecArgs { - DN_OSExecFlags flags; - DN_Str8 working_dir; - DN_Slice environment; + DN_OSExecFlags flags; + DN_Str8 working_dir; + DN_Str8Slice environment; }; // NOTE: DN_OSSemaphore @@ -199,11 +199,19 @@ struct DN_OSConditionVariable // NOTE: DN_OSThread typedef DN_I32(DN_OSThreadFunc)(struct DN_OSThread *); +struct DN_OSThreadLane +{ + DN_USize index; + DN_USize count; + DN_OSBarrier barrier; + void* shared_mem; +}; + struct DN_OSThread { DN_Str8x64 name; DN_TCCore context; - DN_TCLane lane; + DN_OSThreadLane lane; bool is_lane_set; void *handle; DN_U64 thread_id; @@ -295,7 +303,6 @@ DN_API DN_Str8 DN_Str8BuilderBuildFromHeap (D DN_API void DN_OS_LogPrint (DN_LogTypeParam type, void *user_data, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, va_list args); DN_API void DN_OS_SetLogPrintFuncToOS (); -DN_API void DN_OS_DumpThreadContextArenaStat (DN_Str8 file_path); DN_API void * DN_OS_MemReserve (DN_USize size, DN_MemCommit commit, DN_MemPage page_flags); DN_API bool DN_OS_MemCommit (void *ptr, DN_USize size, DN_U32 page_flags); @@ -385,9 +392,9 @@ DN_API DN_Str8 DN_OS_PathF (D DN_API void DN_OS_Exit (int32_t exit_code); DN_API DN_OSExecResult DN_OS_ExecPump (DN_OSExecAsyncHandle handle, char *stdout_buffer, size_t *stdout_size, char *stderr_buffer, size_t *stderr_size, DN_U32 timeout_ms, DN_ErrSink *err); DN_API DN_OSExecResult DN_OS_ExecWait (DN_OSExecAsyncHandle handle, DN_Arena *arena, DN_ErrSink *err); -DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync (DN_Slice cmd_line, DN_OSExecArgs *args, DN_ErrSink *err); -DN_API DN_OSExecResult DN_OS_Exec (DN_Slice cmd_line, DN_OSExecArgs *args, DN_Arena *arena, DN_ErrSink *err); -DN_API DN_OSExecResult DN_OS_ExecOrAbort (DN_Slice cmd_line, DN_OSExecArgs *args, DN_Arena *arena); +DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync (DN_Str8Slice cmd_line, DN_OSExecArgs *args, DN_ErrSink *err); +DN_API DN_OSExecResult DN_OS_Exec (DN_Str8Slice cmd_line, DN_OSExecArgs *args, DN_Arena *arena, DN_ErrSink *err); +DN_API DN_OSExecResult DN_OS_ExecOrAbort (DN_Str8Slice cmd_line, DN_OSExecArgs *args, DN_Arena *arena); DN_API DN_OSSemaphore DN_OS_SemaphoreInit (DN_U32 initial_count); DN_API void DN_OS_SemaphoreDeinit (DN_OSSemaphore *semaphore); @@ -411,11 +418,19 @@ DN_API bool DN_OS_ConditionVariableWaitUntil (D DN_API void DN_OS_ConditionVariableSignal (DN_OSConditionVariable *cv); DN_API void DN_OS_ConditionVariableBroadcast (DN_OSConditionVariable *cv); -DN_API bool DN_OS_ThreadInit (DN_OSThread *thread, DN_OSThreadFunc *func, DN_TCLane *lane, void *user_context); +DN_API bool DN_OS_ThreadInit (DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, void *user_context); DN_API bool DN_OS_ThreadJoin (DN_OSThread *thread); DN_API DN_U32 DN_OS_ThreadID (); DN_API void DN_OS_ThreadSetNameFmt (char const *fmt, ...); +DN_API DN_OSThreadLane DN_OS_ThreadLaneInit (DN_USize index, DN_USize thread_count, DN_OSBarrier barrier, DN_UPtr *share_mem); +DN_API void DN_OS_ThreadLaneSync (DN_OSThreadLane *lane, void **ptr_to_share); +DN_API DN_V2USize DN_OS_ThreadLaneRange (DN_OSThreadLane *lane, DN_USize values_count); + +DN_API DN_OSThreadLane* DN_OS_TCThreadLane (); +DN_API void DN_OS_TCThreadLaneSync (void **ptr_to_share); +DN_API DN_OSThreadLane DN_OS_TCThreadLaneEquip (DN_OSThreadLane lane); + DN_API void DN_OS_HttpRequestAsync (DN_OSHttpResponse *response, DN_Arena *arena, DN_Str8 host, DN_Str8 path, DN_OSHttpRequestSecure secure, DN_Str8 method, DN_Str8 body, DN_Str8 headers); DN_API void DN_OS_HttpRequestWait (DN_OSHttpResponse *response); DN_API void DN_OS_HttpRequestFree (DN_OSHttpResponse *response); @@ -495,7 +510,6 @@ template struct DN_VArray template DN_VArray DN_OS_VArrayInitByteSize (DN_USize byte_size); template DN_VArray DN_OS_VArrayInit (DN_USize max); -template DN_VArray DN_OS_VArrayInitSlice (DN_Slice slice, DN_USize max); template DN_VArray DN_OS_VArrayInitCArray (T const (&items)[N], DN_USize max); template void DN_OS_VArrayDeinit (DN_VArray *array); template bool DN_OS_VArrayIsValid (DN_VArray const *array); diff --git a/Source/OS/dn_os_w32.cpp b/Source/OS/dn_os_w32.cpp index d9e8bdd..cfdd0c9 100644 --- a/Source/OS/dn_os_w32.cpp +++ b/Source/OS/dn_os_w32.cpp @@ -856,20 +856,20 @@ DN_API DN_OSExecResult DN_OS_ExecWait(DN_OSExecAsyncHandle handle, DN_Arena *are return result; } -DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, DN_OSExecArgs *args, DN_ErrSink *err) +DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Str8Slice cmd_line, DN_OSExecArgs *args, DN_ErrSink *err) { // NOTE: Pre-amble DN_OSExecAsyncHandle result = {}; - if (cmd_line.size == 0) + if (cmd_line.count == 0) return result; DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); - DN_Str8 cmd_rendered = DN_Slice_Str8Render(scratch.arena, cmd_line, DN_Str8Lit(" ")); -DN_Str16 cmd16 = DN_OS_W32Str8ToStr16(scratch.arena, cmd_rendered); + DN_Str8 cmd_rendered = DN_Str8SliceRender(cmd_line, DN_Str8Lit(" "), scratch.arena); + DN_Str16 cmd16 = DN_OS_W32Str8ToStr16(scratch.arena, cmd_rendered); DN_Str16 working_dir16 = DN_OS_W32Str8ToStr16(scratch.arena, args->working_dir); DN_Str8Builder env_builder = DN_Str8BuilderFromArena(scratch.arena); - DN_Str8BuilderAppendArrayRef(&env_builder, args->environment.data, args->environment.size); + DN_Str8BuilderAppendArrayRef(&env_builder, args->environment.data, args->environment.count); if (env_builder.string_size) DN_Str8BuilderAppendRef(&env_builder, DN_Str8Lit("\0")); @@ -1243,7 +1243,7 @@ static DWORD __stdcall DN_OS_ThreadFunc_(void *user_context) return 0; } -DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_TCLane *lane, void *user_context) +DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, void *user_context) { bool result = false; if (!thread) @@ -1704,7 +1704,7 @@ DN_API DN_Str8 DN_OS_W32Str16ToStr8(DN_Arena *arena, DN_Str16 src) // NOTE: Str8 allocate ensures there's one extra byte for // null-termination already so no-need to +1 the required size DN_ArenaTempMemScope temp_mem = DN_ArenaTempMemScope(arena); - DN_Str8 buffer = DN_Str8FromArena(arena, required_size, DN_ZMem_No); + DN_Str8 buffer = DN_Str8AllocArena(arena, required_size, DN_ZMem_No); if (buffer.size == 0) return result; diff --git a/Source/dn.cpp b/Source/dn.cpp index 00cc26d..004cc60 100644 --- a/Source/dn.cpp +++ b/Source/dn.cpp @@ -29,7 +29,7 @@ DN_API void DN_Init(DN_Core *dn, DN_InitFlags flags, DN_InitArgs *args) #if DN_H_WITH_OS DN_OSCore *os = &dn->os; dn->os_init = true; - DN_OS_SetLogPrintFuncToOS(os); + DN_OS_SetLogPrintFuncToOS(); // NOTE: Query OS information { @@ -223,10 +223,6 @@ DN_API void DN_BeginFrame() #endif } -#if DN_H_WITH_MATH -#include "Extra/dn_math.cpp" -#endif - #if DN_H_WITH_HELPERS #include "Extra/dn_helpers.cpp" #endif diff --git a/Source/dn.h b/Source/dn.h index a3a2a39..0ea5576 100644 --- a/Source/dn.h +++ b/Source/dn.h @@ -14,7 +14,6 @@ /* #define DN_H_WITH_OS 1 #define DN_H_WITH_CORE 1 - #define DN_H_WITH_MATH 1 #define DN_H_WITH_HELPERS 1 #define DN_H_WITH_ASYNC 1 #define DN_H_WITH_NET 1 @@ -140,10 +139,6 @@ extern DN_Core *g_dn_; DN_API void DN_Init (DN_Core *dn, DN_InitFlags flags, DN_InitArgs *args); DN_API void DN_BeginFrame(); -#if DN_H_WITH_MATH -#include "Extra/dn_math.h" -#endif - #if DN_H_WITH_HELPERS #include "Extra/dn_helpers.h" #endif