util [source code]
- these functions don't allocate memory.
- these functions are provided as is, use it at your own risk.
api
types [source code]
typedef uint8_t byte;
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t s8;
typedef int8_t i8;
typedef int16_t s16;
typedef int16_t i16;
typedef int32_t s32;
typedef int32_t i32;
typedef int64_t s64;
typedef int64_t i64;
struct coroutine {
    u64 state;
    float sleep;
};
        
#define countof(x) [source code]
calculate length of fixed array. alias: count_of.
int test[8] = {0};
countof(test); // -> 8
count_of(test); // -> 8
#define countargs(...) [source code]
counts given arguments (up to 10) alias: count_args.
countargs(1, 2, 5); // -> 3 count_args(1, 2, 5); // -> 3
#define abs(x) [source code]
calculate absolute value from x.
abs(-2); // -> 2 abs(8); // -> 8
#define min(a, b) [source code]
get minimum value between a and b.
min(2, 4); // -> 2
#define max(a, b) [source code]
calculate maximum value between a and b.
max(2, 4); // -> 4
#define clamp(x, a, b) [source code]
limit x to be between a and b.
clamp(2, 1, 8); // -> 2 clamp(2, 3, 8); // -> 3 clamp(10, 3, 8); // -> 8
#define lerp(start, end, t) [source code]
linear interpolation between start and end using t as weight. t being a normalized value ([0, 1])
lerp(1, 10, 0.5f); // -> 5.5f
#define sqr(x) [source code]
x ^ 2
sqr(5); // -> 25
#define coroutine(ctx) [source code]
begin a coroutine block. check this example. this is a faked coroutine block by using a technique that abuses the behavior of a switch statement. read more about it.
struct coroutine ctx = {0};
void test_coroutine()
{
    coroutine(&ctx) {
        fprintf(stderr, "this block will execute first\n");
        yield();
        
        fprintf(stderr, "and when this block runs again, this line will be executed skipping the previous yield.\n");
        yield();
        // reset coroutine state.
        reset;
    }
}
test_coroutine();
test_coroutine();
// would print:
// "this block will execute first"
// "and when this block runs again, this line will be executed skipping the previous yield."
// notice that one message gets print first, and then the next one instead of
// a regular function call which would print this instead:
// "this block will execute first"
// "and when this block runs again, this line will be executed skipping the previous yield."
// "this block will execute first"
// "and when this block runs again, this line will be executed skipping the previous yield."
#define yield_to(id) [source code]
yield from a coroutine specifying an id. unless you need to specify an id, use yield.
// ...
#define yield() [source code]
yield from a coroutine using __COUNTER__ + 1 as id.
// ...
#define syield_to(id, sleep_for, dt) [source code]
yield and sleep for sleep_for from a coroutine specifying an id. unless you need to specify the id, use syield.
// ...
#define syield(sleep_for, dt) [source code]
yield and sleep for sleep_for seconds using __COUNTER__ + 1 as id. dt represents how much time has past (for instance, in a game context, this would be the frame time)
// ...
#define reset [source code]
reset the state of the running coroutine, the next time the coroutine block runs, it will start from the beginning.
// ...
u32 random_int(u32 *seed); [source code]
generate a random int. seed can be null in which case, a debug test seed will be used.
random_int(0); // -> random int random_int(0); // -> random int
u32 random_int_between(u32 *seed, u32 lower, u32 upper); [source code]
generate a random int between lower and upper. seed can be null in which case, a debug test seed will be used.
random_int_between(0, 10, 100); // -> random int between 10 and 100