Old-School Wasm Demo Environment

WebAssembly, out of the box, has no notion of graphics. There are many ways to connect it to browser graphics support. This is one.

This environment provides a linear framebuffer and not much else. It's very similar to the environment provided by late 80s and early 90s computers, and it makes it very simple to write small demos.

Basic Environment

A program consists of a single WebAssembly module with particular exports and imports. The framebuffer resides in its linear memory, but not at a predefined address: one of the exports tells the wrapper where to find it.

The following exports are recognized:

symbol Type Required? Purpose
step func () -> () Required Called before displaying each frame. Should prepare the framebuffer.
BG global i32 Required Address of framebuffer in linear memory.
memory memory Required The instance's memory.
init func () -> () Optional Called once after module instantiation to set up memory.
DIM global i32 Optional Address of dimensions in linear memory.

The wrapper program will:

  1. Instantiate the module.
  2. Call init.
  3. Call step.
  4. Display the framebuffer image located at FB in memory.
  5. Go to step 3.

The framebuffer is a raster image in row-major order. Each pixel consists of four bytes, in the order R, G, B, and A (where A is alpha, or opacity). Thus, it's exactly 1MiB in size.

The framebuffer defaults to 512x512 pixels. If the program exports the DIM address, it should be the address of a four-byte section of linear memory which contains two u16 values in little-endian byte order: first width, then height. (The size is in memory, instead of in the global, because compilers don't currently provide a good way to put initialized values into globals... other than memory addresses.)