Skip to content

Instantly share code, notes, and snippets.

@peterhellberg
Created November 6, 2023 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peterhellberg/db9abfdbb87c4d7705efe7ea0366fa08 to your computer and use it in GitHub Desktop.
Save peterhellberg/db9abfdbb87c4d7705efe7ea0366fa08 to your computer and use it in GitHub Desktop.
MicroW8 API for Zig ⚡
//
// MicroW8: https://exoticorn.github.io/microw8/docs/
// ┌───────────────────────────────────────────────────────────────────────────┐
// │ │
// │ Platform Constants │
// │ │
// └───────────────────────────────────────────────────────────────────────────┘
pub const SCREEN_WIDTH: u32 = 320;
pub const SCREEN_HEIGHT: u32 = 240;
// ┌───────────────────────────────────────────────────────────────────────────┐
// │ │
// │ Memory Addresses │
// │ │
// └───────────────────────────────────────────────────────────────────────────┘
pub const TIME_MS: *i32 = @ptrFromInt(0x40); // time since module start in ms
pub const FRAMEBUFFER: *[320 * 240]u8 = @ptrFromInt(0x78); // frame buffer
pub const PALETTE: *[256]u32 = @ptrFromInt(0x13000);
pub const FONT: *[256]u32 = @ptrFromInt(0x13400);
pub const BUTTON_UP: i32 = 0;
pub const BUTTON_DOWN: i32 = 1;
pub const BUTTON_LEFT: i32 = 2;
pub const BUTTON_RIGHT: i32 = 3;
pub const BUTTON_A: i32 = 4;
pub const BUTTON_B: i32 = 5;
pub const BUTTON_X: i32 = 6;
pub const BUTTON_Y: i32 = 7;
// ┌───────────────────────────────────────────────────────────────────────────┐
// │ │
// │ Math Functions │
// │ │
// └───────────────────────────────────────────────────────────────────────────┘
// These all do what you'd expect them to. All angles are in radians.
pub extern fn asin(x: f32) f32; // Returns the arcsine of x.
pub extern fn acos(x: f32) f32; // Returns the arccosine of x.
pub extern fn atan(f32) f32; // Returns the arctangent of x.
pub extern fn atan2(y: f32, x: f32) f32; // Returns the angle between the point (x, y) and the positive x-axis.
pub extern fn sin(angle: f32) f32; // Returns the sine of angle.
pub extern fn tan(angle: f32) f32; // Returns the tangent of angle.
pub extern fn cos(angle: f32) f32; // Returns the cosine of angle.
pub extern fn exp(x: f32) f32; // Returns e^x.
pub extern fn log(x: f32) f32; // Returns the natural logarithmus of x. Ie. e^log(x) == x.
pub extern fn pow(x: f32, y: f32) f32; // Returns x^y.
pub extern fn fmod(x: f32, y: f32) f32; // Returns x modulo y, ie. x - floor(x / y) * y. This means the sign of the result of fmod is the same as y.
// ┌───────────────────────────────────────────────────────────────────────────┐
// │ │
// │ Random Functions │
// │ │
// └───────────────────────────────────────────────────────────────────────────┘
// MicroW8 provides a pretty good PRNG, namely xorshift64*.
// It is initialized to a constant seed at each startup, so if you want to
// vary the random sequence you'll need to provide a seed yourself.
pub extern fn random() i32; // Returns a (pseudo-)random 32bit integer.
pub extern fn randomf() f32; // Returns a (pseudo-)random float equally distributed in [0,1).
pub extern fn randomSeed(seed: i32) void; // Seeds the PRNG with the given seed.
// ┌───────────────────────────────────────────────────────────────────────────┐
// │ │
// │ Graphics Functions │
// │ │
// └───────────────────────────────────────────────────────────────────────────┘
pub extern fn cls(color: i32) void; // Clears the screen to the given color index.
pub extern fn setPixel(x: i32, y: i32, color: i32) void; // Sets the pixel at x, y to the given color index.
pub extern fn getPixel(x: i32, y: i32) i32; // Returns the color index at x, y. Returns 0 if the given coordinates are outside the screen.
//TODO: Currently broken in uw8: pub extern fn hline(left: i32, right: i32, y: i32, color: i32) void; // Fills the horizontal line [left, right), y with the given color index.
pub extern fn rectangle(x: f32, y: f32, w: f32, h: f32, color: i32) void; // Fills the rectangle x,y - x+w,y+h with the given color index. (Sets all pixels where the pixel center lies inside the rectangle.)
pub extern fn circle(cx: f32, cy: f32, radius: f32, color: i32) void; // Fills the circle at cx, cy and with radius with the given color index. (Sets all pixels where the pixel center lies inside the circle.)
pub extern fn rectangle_outline(x: f32, y: f32, w: f32, h: f32, color: i32) void; // Draws a one pixel outline on the inside of the given rectangle. (Draws the outermost pixels that are still inside the rectangle area.)
pub extern fn circle_outline(cx: f32, cy: f32, radius: f32, color: i32) void; // Draws a one pixel outline on the inside of the given circle. (Draws the outermost pixels that are still inside the circle area.)
pub extern fn line(x1: f32, y1: f32, x2: f32, y2: f32, color: i32) void; // Draws a line from x1,y1 to x2,y2 in the given color index.
// ┌───────────────────────────────────────────────────────────────────────────┐
// │ │
// │ Input Functions │
// │ │
// └───────────────────────────────────────────────────────────────────────────┘
pub extern fn isButtonPressed(btn: i32) bool; // Returns whether the buttons with the given index is pressed this frame.
pub extern fn isButtonTriggered(btn: i32) bool; // Returns whether the given button is newly pressed this frame.
pub extern fn time() f32; // Returns the time in seconds since the start of the cart. The integer time in milliseconds can also be read at address 0x40.
// ┌───────────────────────────────────────────────────────────────────────────┐
// │ │
// │ Text Functions │
// │ │
// └───────────────────────────────────────────────────────────────────────────┘
pub extern fn printChar(char: i32) void; // Prints the character in the lower 8 bits of char. If the upper 24 bits are non-zero, right-shifts char by 8 bits and loops back to the beginning.
pub extern fn printString(str: [*]const u8) void; // Prints the zero-terminated string at the given memory address.
pub extern fn printInt(num: i32) void; // Prints num as a signed decimal number.
pub extern fn setTextColor(color: i32) void; // Sets the text color.
pub extern fn setBackgroundColor(color: i32) void; // Sets the background color.
pub extern fn setCursorPosition(x: i32, y: i32) void; // Sets the cursor position. In normal mode x and y are multiplied by 8 to get the pixel position, in graphics mode they are used as is.
// ┌───────────────────────────────────────────────────────────────────────────┐
// │ │
// │ Sound Functions │
// │ │
// └───────────────────────────────────────────────────────────────────────────┘
pub extern fn playNote(channel: i32, note: i32) void; // Triggers a note (1-127) on the given channel (0-3).
pub extern fn sndGes(sampleIndex: i32) f32; // This implements a sound chip, generating sound based on 32 bytes of sound registers.
@peterhellberg
Copy link
Author

peterhellberg commented Nov 6, 2023

Docs: https://exoticorn.github.io/microw8/docs/

About

MicroW8 is a WebAssembly based fantasy console inspired by the likes of TIC-80, WASM-4 and PICO-8.

The initial motivation behind MicroW8 was to explore whether there was a way to make WebAssembly viable for size-coding. (Size coding being the art of creating tiny (often <= 256 bytes) graphical effects and games.) The available examples so far are all in this space, however, I very carefully made sure that all design decisions make sense from the point of view of bigger projects as well.

Specs

  • Screen: 320x240, 256 colors, 60Hz
  • Modules: Up to 256KB (WASM)
  • Memory: 256KB
  • Gamepad input (D-Pad + 4 Buttons)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment