5.1 KiB
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)
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 <string.h> / <ctype.h> functions:
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)
#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.
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.
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)
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.
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:
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.
// 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.