go back

util [source code]


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