Files
dusk/.claude/util.md
T
2026-06-16 10:15:59 -05:00

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.