# Utility Library Source: `src/dusk/util/` All C code in the project must use these utilities instead of their standard library equivalents. Do not use `malloc`, `free`, `strcmp`, `strcpy`, `memcpy`, `memset`, etc. directly. --- ## Memory (`memory.h`) ```c void *memoryAllocate(size_t size); void *memoryAlign(size_t alignment, size_t size); // aligned alloc void memoryFree(void *ptr); void memoryCopy(void *dest, const void *src, size_t size); void memoryZero(void *dest, size_t size); errorret_t memoryCompare(const void *a, const void *b, size_t size); size_t memoryGetAllocatedCount(void); // Returns the number of live allocations. Must be 0 at test teardown. void memoryTrack(void *ptr); // Register a pointer that was malloc'd outside the engine (e.g. by a // third-party library) so it counts toward the allocation tracker. ``` `MEMORY_POINTERS_IN_USE` is a file-scope static tracking the live count. It is incremented by `memoryAllocate` / `memoryTrack` and decremented by `memoryFree`. Tests assert this is 0 at teardown to catch leaks. --- ## String (`string.h`) Use these instead of `` / `` functions: ```c void stringCopy(char_t *dest, const char_t *src, size_t destSize); int stringCompare(const char_t *a, const char_t *b); bool_t stringEquals(const char_t *a, const char_t *b); int stringCompareInsensitive(const char_t *a, const char_t *b); size_t stringLength(const char_t *str); void stringTrim(char_t *str); bool_t stringIsWhitespace(char_t c); bool_t stringStartsWith(const char_t *str, const char_t *prefix); bool_t stringEndsWith(const char_t *str, const char_t *suffix); bool_t stringContains(const char_t *haystack, const char_t *needle); char_t *stringFind(const char_t *haystack, const char_t *needle); void stringFormat(char_t *dest, size_t destSize, const char_t *fmt, ...); int32_t stringToInt(const char_t *str); float_t stringToFloat(const char_t *str); void stringFromInt(char_t *dest, size_t destSize, int32_t value); void stringFromFloat(char_t *dest, size_t destSize, float_t value); ``` `destSize` in `stringCopy` / `stringFormat` is the buffer capacity **excluding** the null terminator. --- ## Math (`math.h`) ```c #define MATH_PI M_PI #define mathMax(a, b) #define mathMin(a, b) #define mathClamp(x, lower, upper) #define mathAbs(amt) uint32_t mathNextPowTwo(uint32_t value); float_t mathModFloat(float_t x, float_t y); // always non-negative float_t mathLerp(float_t a, float_t b, float_t t); // plus additional trig / remap helpers ``` The project uses **cglm** for vector and matrix math (`vec3`, `mat4`, `glm_vec3_*`, `glm_mat4_*`, etc.). `math.h` provides scalar helpers that complement cglm. --- ## Endian (`endian.h`) GameCube and Wii are big-endian. Any binary data format (asset files, network packets) must use the endian utilities when reading multi-byte values. ```c bool_t isHostLittleEndian(void); uint16_t endianLittleToHost16(uint16_t value); uint32_t endianLittleToHost32(uint32_t value); uint64_t endianLittleToHost64(uint64_t value); float_t endianLittleToHostFloat(float_t value); ``` If neither `DUSK_PLATFORM_ENDIAN_LITTLE` nor `DUSK_PLATFORM_ENDIAN_BIG` is defined, the implementation falls back to a runtime check (`ENDIAN_MAGIC` probe). Prefer setting the compile-time macro for new platform targets. --- ## Reference counting (`ref.h`) `ref_t` is a generic reference-counted handle with optional lock / unlock / all-unlocked callbacks. ```c void refInit( ref_t *ref, void *data, refcallback_t onLock, refcallback_t onUnlock, refcallback_t onAllUnlocked // called when count -> 0; do cleanup here ); void refLock(ref_t *ref); // increment count bool_t refUnlock(ref_t *ref); // decrement; returns true if count == 0 ``` The asset entry system uses `ref_t` internally to track how many subsystems have locked a loaded asset. --- ## Array (`array.h`) ```c void arrayReverse(void *array, size_t count, size_t elementSize); ``` Generic in-place reverse using the element stride. --- ## Sort (`sort.h`) Use these instead of `qsort` for portability across all platforms. ```c typedef int_t (*sortcompare_t)(const void *, const void *); void sortBubble( void *array, const size_t count, const size_t size, const sortcompare_t compare ); void sortQuick( void *array, const size_t count, const size_t size, const sortcompare_t compare ); #define sort sortQuick // preferred; use this in new code ``` Typed convenience helpers for `uint8_t` arrays: ```c int sortArrayU8Compare(const void *a, const void *b); void sortArrayU8(uint8_t *array, const size_t count); ``` --- ## Crypt (`crypt.h`) CRC32 checksum for save file integrity. Not cryptographically secure -- do not use for security purposes. ```c // One-shot checksum: uint32_t cryptCRC32(const void *data, const size_t size); // Streaming (incremental) CRC32: uint32_t cryptCRC32Begin(void); void cryptCRC32Update( uint32_t *crc, const void *data, const size_t size ); uint32_t cryptCRC32End(const uint32_t crc); ``` The streaming API allows computing a checksum across multiple buffers or while interleaving other reads -- the save system uses this to verify the whole save slot in a single pass.