Skip to main content

Drawing Text

To draw some text at position (10, 10):

text("Hello world!", 10, 10);

DRAW_COLORS color 1 is used as the text color, DRAW_COLORS color 2 is used as the background color.

Special Characters#

The WASM-4 font contains 224 characters total.

Aside from text and symbols, many slots are empty. This is because in ASCII, the text format used for the text() function, doesn't have any character indexed to it. Moreover, some of them are mapped, but as control characters.

The \n, for example, is technically a character, but it's mapped to mark a line break.

If we look closely at the font, we'll find four arrows and two buttons, highlighted by a circle. It's possible to print one of these characters by escaping it's charcode.

KeyEscape Character
X button\x80
Z button\x81
Left arrow\x84
Right arrow\x85
Up arrow\x86
Down arrow\x87

We could use those as instructions for our games!

text("Press \x86 to jump!", 10, 10);

Custom Fonts#

Since WASM-4 doesn't have a custom font, we have to figure a way to implement our own. One way to approach this is treating a font like a tilemap, except we're indexing characters instead of numbers!

The example below will print a text using the BitScript sprite font:

import "wasm4.pn";
const FONT_WIDTH: u32 = 208;const CHAR_WIDTH: u32 = 8;const CHAR_HEIGHT: u32 = 8;const CHARSET: [26]u8 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";const FONT: [208]u8 = [  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x08, 0x1c, 0x1c, 0x3c, 0x18, 0x3e,  0x1c, 0x26, 0x10, 0x2c, 0x12, 0x08, 0x24, 0x26,  0x1c, 0x3c, 0x1c, 0x78, 0x1c, 0x3c, 0x62, 0x42,  0x82, 0xc4, 0x42, 0x66, 0x08, 0x32, 0x22, 0x52,  0x24, 0x51, 0x22, 0x25, 0x28, 0x14, 0x14, 0x08,  0x24, 0x26, 0x22, 0x52, 0x22, 0xa4, 0x22, 0x52,  0x22, 0xa5, 0x44, 0x2a, 0x24, 0x1c, 0x14, 0x52,  0x20, 0x12, 0x20, 0x10, 0x20, 0x26, 0x28, 0x04,  0x14, 0x08, 0x2c, 0x24, 0x22, 0x52, 0x22, 0xa4,  0x20, 0x10, 0x22, 0x24, 0x54, 0x10, 0x24, 0x04,  0x14, 0x5c, 0x40, 0x22, 0x38, 0x38, 0x4e, 0x7c,  0x28, 0x08, 0x28, 0x10, 0x54, 0x58, 0x42, 0x14,  0x44, 0x78, 0x18, 0x10, 0x24, 0x28, 0x54, 0x10,  0x14, 0x08, 0x24, 0xa4, 0x40, 0x62, 0x40, 0x20,  0x44, 0x48, 0x10, 0x08, 0x34, 0x30, 0x54, 0x48,  0x44, 0x20, 0x54, 0x48, 0x04, 0x20, 0x44, 0x28,  0x2c, 0x28, 0x08, 0x10, 0x3c, 0xa4, 0x42, 0xa4,  0x44, 0xa0, 0x44, 0xc9, 0x10, 0x48, 0x24, 0x52,  0x44, 0x4a, 0x44, 0xa0, 0x3a, 0x48, 0x44, 0xa0,  0x44, 0x10, 0x28, 0xa8, 0x48, 0x38, 0x42, 0x5b,  0x3c, 0x58, 0x38, 0x40, 0x38, 0x46, 0x68, 0x34,  0x42, 0x2c, 0x82, 0x84, 0x3a, 0x40, 0x08, 0x86,  0x38, 0x40, 0x3a, 0x10, 0x48, 0x46, 0x30, 0x66];
fn draw_space(x: i32, y: i32, column: u32, line: u32, colors: u16){    DRAW_COLORS = DRAW_COLORS & 0x0F;    rect(        x + (column * CHAR_WIDTH) as i32,        y + (line * CHAR_HEIGHT) as i32,        CHAR_WIDTH,        CHAR_HEIGHT    );    DRAW_COLORS = colors;}
fn draw_char(char_index: u32, x: i32, y: i32, column: u32, line: u32){    blitSub(        FONT,        x + (column * CHAR_WIDTH) as i32,        y + (line * CHAR_HEIGHT) as i32,        CHAR_WIDTH,        CHAR_HEIGHT,        char_index * CHAR_WIDTH,        0,        FONT_WIDTH,        BLIT_1BPP,    );}
fn write_with_custom_font(text: []u8, x: i32, y: i32, colors: u16){    // Set draw colors...    DRAW_COLORS = colors;
    // Line and column counters.    var line: u32 = 0;    var column: u32 = 0;
    // Iterate through each character...    var i = 0;    {        if i == |text|            goto end;
        var char_code: u8 = text[i];
        // Break into next line when encounter a "\n" (newline)...        if char_code == 10        {            line = line + 1;            column = 0;            goto next;        }
        // Character index on charset.        var char_index = 0;        {            if char_index == |CHARSET|                goto not_found;            if CHARSET[char_index] == char_code            {                draw_char(char_index as u32, x, y, column, line);                goto drawn;            }            char_index = char_index + 1;            loop;        }
        not_found:        // Skip invalid characters, spaces, etc.        draw_space(x, y, column, line, colors);
        drawn:        // Advance to next column...        column = column + 1;
        next:        i = i + 1;        loop;    }    end:}
pub extern fn update(){    write_with_custom_font("HELLO WORLD WITH\nOUR CUSTOM FONT", 4, 4, 0x30);}