# Utilities Source: `src/dusk/util/` --- ## String (`util/string.h`) **Always use these instead of stdlib equivalents** (`strcmp`, `strcpy`, `sprintf`, etc.). ```c stringCopy(dest, src, destSize); // safe strncpy; always null-terminates stringCompare(a, b); // -1 / 0 / 1 stringEquals(a, b); // bool_t stringCompareInsensitive(a, b); // case-insensitive -1 / 0 / 1 stringTrim(str); // in-place strip leading/trailing whitespace stringFindLastChar(str, c); // last occurrence pointer or NULL stringFormat(dest, destSize, fmt, ...); // snprintf wrapper; pass NULL dest to get length stringFormatVA(dest, destSize, fmt, args); // va_list version stringIsWhitespace(c); // bool_t // Parse: stringToI32(str, &out) → bool_t stringToI64(str, &out) → bool_t stringToI16(str, &out) → bool_t stringToU16(str, &out) → bool_t stringToF32(str, &out) → bool_t // Suffix checks: stringEndsWith(str, suffix) → bool_t stringEndsWithCaseInsensitive(str, suffix) → bool_t stringIncludesString(haystack, needle) → bool_t ``` --- ## Memory (`util/memory.h`) **Always use these instead of `malloc`/`free`/`memcpy`/`memset` directly.** ```c memoryAllocate(size) → void * // malloc + tracks pointer count memoryAlign(alignment, size) → void * // aligned malloc memoryFree(ptr) // free + decrements count memoryReallocate(&ptr, size) // realloc memoryResize(&ptr, oldSize, newSize) // realloc + copy (safe reshape) memoryTrack(ptr) // track externally-malloc'd pointer memoryCopy(dest, src, size) // memcpy memoryMove(dest, src, size) // memmove memorySet(dest, value, size) // memset memoryZero(dest, size) // memset 0 memoryCompare(a, b, size) → int_t // memcmp // Useful for uploading vertex data with different source/dest layouts: memoryCopyInterleaved(dest, destStride, src, srcStride, elementSize, count); memoryCopyRangeSafe(dest, start, end, sizeMax); // copy with bounds check memoryGetAllocatedCount() → size_t // current malloc'd block count ``` --- ## Math (`util/math.h`) ```c mathNextPowTwo(value) → uint32_t // next power of two >= value mathMax(a, b) // macro mathMin(a, b) // macro mathClamp(x, lower, upper) // macro mathAbs(amt) // macro mathModFloat(x, y) → float_t // always non-negative modulo mathLerp(a, b, t) → float_t // linear interpolation (floats) ``` For fixed-point lerp use `fixedLerp(a, b, t)` from `util/fixed.h`. `MATH_PI` is defined as `M_PI`. --- ## Fixed-point (`util/fixed.h`) Q24.8 format: 24-bit integer part, 8-bit fractional part (`int32_t`). See [architecture.md](architecture.md#fixed-point-math) for the full API. Quick reference: ```c FIXED(1.5f) // compile-time literal fixedFromI32(3) // runtime int → fixed fixedToFloat(f) // fixed → float (only for GL/platform APIs) fixedMul(a, b) // multiplication (not just addition) fixedDiv(a, b) // division fixedLerp(a, b, t) // lerp where t ∈ [0, FIXED_ONE] ``` --- ## Array (`util/array.h`) ```c arrayReverse(array, count, size); // in-place reverse; size = sizeof(element) ``` --- ## Sort (`util/sort.h`) ```c sortQuick(array, count, size, compare); // quicksort sortBubble(array, count, size, compare); // bubble sort (small arrays) sort(array, count, size, compare); // macro alias for sortQuick // Convenience uint8_t sorter: sortArrayU8(array, count); int sortArrayU8Compare(const void *a, const void *b); // comparator ``` `sortcompare_t` matches `qsort` comparator signature: `int (*)(const void *, const void *)`. --- ## Reference counting (`util/ref.h`) ```c refInit(&ref, dataPtr, onLock, onUnlock, onAllUnlocked); refLock(&ref); // increments count, calls onLock bool_t hit_zero = refUnlock(&ref); // decrements; calls onAllUnlocked when 0 ``` Used internally by the asset entry system to track how many callers hold a reference to a loaded asset entry. --- ## CRC32 (`util/crypt.h`) ```c // One-shot: uint32_t crc = cryptCRC32(data, size); // Streaming: uint32_t acc = cryptCRC32Begin(); cryptCRC32Update(&acc, chunk1, len1); cryptCRC32Update(&acc, chunk2, len2); uint32_t final = cryptCRC32End(acc); ``` Used by the save stream to checksum save files. --- ## Endian (`util/endian.h`) All serialized data (save files, asset headers) is little-endian. Convert to/from host byte order: ```c uint32_t val = endianLittleToHost32(rawU32); uint16_t val = endianLittleToHost16(rawU16); float_t val = endianLittleToHostFloat(rawFloat); ``` `isHostLittleEndian()` returns a bool at runtime. The compile-time defines `DUSK_PLATFORM_ENDIAN_LITTLE` / `DUSK_PLATFORM_ENDIAN_BIG` are set by `cmake/targets/.cmake`.