rain in wasm
The raining ascii on my homepage was inspired by: soohoonchoi.com.
rules first
No libc, no libm, no allocation, no globals. The caller hands over a single block of memory, and a macro sizes it at compile time.
#define FIELD_BYTES(w, h) \
((size_t)(w) * (size_t)(h) * sizeof(float) \
+ (size_t)(w) * sizeof(float) \
+ (size_t)(w) * sizeof(uint32_t) \
+ (size_t)(w) * (size_t)(h))
the field
Each column is an independent stream of characters. I took a 32-bit hash
of each column index to give it a permanent speed of 2.5-11 rows per second.
A per-column accumulator collects speed * dt, and each time we
cross 1, the column shifts down a single cell. Each cell gets multiplied by a
decay factor so it fades as it falls.
The char entering at the top of the screen comes from hashing the column
and its shift count in blocks of eight. The rain is a pure function of
(seed, column, shift count).
freestanding wasm
No emscripten (because why not). The custom allocator is just a bump pointer starting at the address the linker marks as the end of static data:
extern unsigned char __heap_base;
static void *balloc(size_t n)
{
uintptr_t p = (next + 15u) & ~(uintptr_t)15u;
uintptr_t end = p + n;
size_t have = __builtin_wasm_memory_size(0) * PAGE;
if (end > have) {
size_t pages = (end - have + PAGE - 1) / PAGE;
if (__builtin_wasm_memory_grow(0, pages) == (size_t)-1)
return 0;
}
next = end;
return (void *)p;
}