Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

2D Drawing Functions

Screen-space sprites, rectangles, and text rendering.

Color: Use set_color(0xRRGGBBAA) before drawing to set the tint color. Default is white (0xFFFFFFFF).

Screen Coordinate System

All 2D drawing uses screen-space coordinates with the following conventions:

PropertyValue
Resolution960×540 pixels (fixed)
OriginTop-left corner (0, 0)
X-axisIncreases rightward (0 to 960)
Y-axisIncreases downward (0 to 540)
Anchor pointTop-left corner of sprite/rect
(0,0) ───────────────────────────► X (960)
  │
  │   ┌────────┐
  │   │ sprite │  x,y is top-left corner
  │   │  w×h   │
  │   └────────┘
  ▼
  Y (540)

The screen is always rendered at 960×540 internally and scaled to fit the window. This ensures pixel-perfect positioning regardless of window size.

Sprites

draw_sprite

Draws a textured quad at screen coordinates.

Signature:

#![allow(unused)]
fn main() {
fn draw_sprite(x: f32, y: f32, w: f32, h: f32)
}

Parameters:

NameTypeDescription
x, yf32Screen position (top-left corner)
w, hf32Size in pixels

Example:

#![allow(unused)]
fn main() {
fn render() {
    // Draw full texture
    texture_bind(player_sprite);
    draw_sprite(100.0, 100.0, 64.0, 64.0);

    // Tinted sprite
    set_color(0xFF8080FF);
    draw_sprite(200.0, 100.0, 64.0, 64.0);
}
}

draw_sprite_region

Draws a region of a texture (sprite sheet).

Signature:

#![allow(unused)]
fn main() {
fn draw_sprite_region(
    x: f32, y: f32, w: f32, h: f32,
    src_x: f32, src_y: f32, src_w: f32, src_h: f32
)
}

Parameters:

NameTypeDescription
x, yf32Screen position
w, hf32Destination size in pixels
src_x, src_yf32Source UV position (0.0-1.0)
src_w, src_hf32Source UV size (0.0-1.0)

Example:

#![allow(unused)]
fn main() {
// Sprite sheet: 4x4 grid of 32x32 sprites (128x128 texture)
fn draw_frame(frame: u32) {
    let col = frame % 4;
    let row = frame / 4;
    // UV coordinates: frame size / texture size
    let uv_size = 32.0 / 128.0;  // = 0.25
    draw_sprite_region(
        100.0, 100.0, 64.0, 64.0,           // Destination (scaled 2x)
        col as f32 * uv_size, row as f32 * uv_size, uv_size, uv_size  // Source UV
    );
}
}

draw_sprite_ex

Draws a sprite with rotation and custom origin.

Signature:

#![allow(unused)]
fn main() {
fn draw_sprite_ex(
    x: f32, y: f32, w: f32, h: f32,
    src_x: f32, src_y: f32, src_w: f32, src_h: f32,
    origin_x: f32, origin_y: f32,
    angle_deg: f32
)
}

Parameters:

NameTypeDescription
x, yf32Screen position
w, hf32Destination size
src_x, src_y, src_w, src_hf32Source UV region (0.0-1.0)
origin_x, origin_yf32Rotation origin (0-1 normalized)
angle_degf32Rotation angle in degrees

Example:

#![allow(unused)]
fn main() {
fn render() {
    // Rotating sprite around center
    draw_sprite_ex(
        200.0, 200.0, 64.0, 64.0,    // Position and size
        0.0, 0.0, 1.0, 1.0,          // Full texture UV
        0.5, 0.5,                     // Center origin
        elapsed_time() * 90.0         // Rotation (90 deg/sec)
    );

    // Rotating around bottom-center (like a pendulum)
    draw_sprite_ex(
        300.0, 200.0, 64.0, 64.0,
        0.0, 0.0, 1.0, 1.0,
        0.5, 1.0,                     // Bottom-center origin
        (elapsed_time() * 2.0).sin() * 30.0
    );
}
}

Rectangles

draw_rect

Draws a solid color rectangle.

Signature:

#![allow(unused)]
fn main() {
fn draw_rect(x: f32, y: f32, w: f32, h: f32)
}

Parameters:

NameTypeDescription
x, yf32Screen position (top-left)
w, hf32Size in pixels

Example:

#![allow(unused)]
fn main() {
fn render() {
    // Health bar background
    set_color(0x333333FF);
    draw_rect(10.0, 10.0, 100.0, 20.0);

    // Health bar fill
    set_color(0x00FF00FF);
    let health_width = (health / max_health) * 96.0;
    draw_rect(12.0, 12.0, health_width, 16.0);

    // Semi-transparent overlay
    set_color(0x00000080);
    draw_rect(0.0, 0.0, 960.0, 540.0);
}
}

Lines & Circles

draw_line

Draws a line between two points.

Signature:

#![allow(unused)]
fn main() {
fn draw_line(x1: f32, y1: f32, x2: f32, y2: f32, thickness: f32)
}

Parameters:

NameTypeDescription
x1, y1f32Start point in screen pixels
x2, y2f32End point in screen pixels
thicknessf32Line thickness in pixels

Example:

#![allow(unused)]
fn main() {
fn render() {
    // Diagonal line
    set_color(0xFFFFFFFF);
    draw_line(100.0, 100.0, 300.0, 200.0, 2.0);

    // Box outline
    set_color(0x00FF00FF);
    draw_line(50.0, 50.0, 150.0, 50.0, 1.0);
    draw_line(150.0, 50.0, 150.0, 150.0, 1.0);
    draw_line(150.0, 150.0, 50.0, 150.0, 1.0);
    draw_line(50.0, 150.0, 50.0, 50.0, 1.0);
}
}

draw_circle

Draws a filled circle.

Signature:

#![allow(unused)]
fn main() {
fn draw_circle(x: f32, y: f32, radius: f32)
}

Parameters:

NameTypeDescription
x, yf32Center position in screen pixels
radiusf32Circle radius in pixels

Notes: Rendered as a 16-segment approximation.

Example:

#![allow(unused)]
fn main() {
fn render() {
    // Player indicator
    set_color(0x00FF00FF);
    draw_circle(player_x, player_y, 10.0);

    // Semi-transparent area effect
    set_color(0xFF000040);
    draw_circle(500.0, 300.0, 50.0);
}
}

draw_circle_outline

Draws a circle outline.

Signature:

#![allow(unused)]
fn main() {
fn draw_circle_outline(x: f32, y: f32, radius: f32, thickness: f32)
}

Parameters:

NameTypeDescription
x, yf32Center position in screen pixels
radiusf32Circle radius in pixels
thicknessf32Line thickness in pixels

Notes: Rendered as 16 line segments.

Example:

#![allow(unused)]
fn main() {
fn render() {
    // Selection ring
    set_color(0xFFFF00FF);
    draw_circle_outline(selected_x, selected_y, 20.0, 2.0);

    // Range indicator
    set_color(0x00FF0080);
    draw_circle_outline(tower_x, tower_y, attack_range, 1.0);
}
}

Text

draw_text

Draws text using the bound font.

Signature:

#![allow(unused)]
fn main() {
fn draw_text(ptr: *const u8, len: u32, x: f32, y: f32, size: f32)
}

Parameters:

NameTypeDescription
ptr*const u8Pointer to UTF-8 string
lenu32String length in bytes
x, yf32Screen position
sizef32Font size in pixels

Note: Use set_color(0xRRGGBBAA) before calling draw_text() to set the text color.

Example:

#![allow(unused)]
fn main() {
fn render() {
    let text = b"SCORE: 12345";
    set_color(0xFFFFFFFF);
    draw_text(text.as_ptr(), text.len() as u32, 10.0, 10.0, 16.0);

    let title = b"GAME OVER";
    set_color(0xFF0000FF);
    draw_text(title.as_ptr(), title.len() as u32, 400.0, 270.0, 48.0);
}
}

text_width

Measures the width of text when rendered.

Signature:

#![allow(unused)]
fn main() {
fn text_width(ptr: *const u8, len: u32, size: f32) -> f32
}

Parameters:

NameTypeDescription
ptr*const u8Pointer to UTF-8 string
lenu32String length in bytes
sizef32Font size in pixels

Returns: Width in pixels that the text would occupy when rendered.

Example:

#![allow(unused)]
fn main() {
fn render() {
    let text = b"CENTERED";
    let width = text_width(text.as_ptr(), text.len() as u32, 32.0);

    // Center text on screen
    let x = (screen::WIDTH as f32 - width) / 2.0;
    set_color(0xFFFFFFFF);
    draw_text(text.as_ptr(), text.len() as u32, x, 270.0, 32.0);
}
}

See Also: draw_text


Custom Fonts

load_font

Loads a fixed-width bitmap font.

Signature:

#![allow(unused)]
fn main() {
fn load_font(
    texture: u32,
    char_width: u32,
    char_height: u32,
    first_codepoint: u32,
    char_count: u32
) -> u32
}

Parameters:

NameTypeDescription
textureu32Font texture atlas handle
char_widthu32Width of each character in pixels
char_heightu32Height of each character in pixels
first_codepointu32First character code (usually 32 for space)
char_countu32Number of characters in atlas

Returns: Font handle

Constraints: Init-only.

Example:

#![allow(unused)]
fn main() {
fn init() {
    unsafe {
        FONT_TEXTURE = load_texture(128, 64, FONT_PIXELS.as_ptr());
        // 8x8 font starting at space (32), 96 characters
        MY_FONT = load_font(FONT_TEXTURE, 8, 8, 32, 96);
    }
}
}

load_font_ex

Loads a variable-width bitmap font.

Signature:

#![allow(unused)]
fn main() {
fn load_font_ex(
    texture: u32,
    widths_ptr: *const u8,
    char_height: u32,
    first_codepoint: u32,
    char_count: u32
) -> u32
}

Parameters:

NameTypeDescription
textureu32Font texture atlas handle
widths_ptr*const u8Pointer to array of character widths
char_heightu32Height of each character
first_codepointu32First character code
char_countu32Number of characters

Returns: Font handle

Constraints: Init-only.

Example:

#![allow(unused)]
fn main() {
// Width table for characters ' ' through '~'
static CHAR_WIDTHS: [u8; 96] = [
    4, 2, 4, 6, 6, 6, 6, 2, 3, 3, 4, 6, 2, 4, 2, 4, // space to /
    6, 4, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 4, 6, 4, 6, // 0 to ?
    // ... etc
];

fn init() {
    unsafe {
        PROP_FONT = load_font_ex(FONT_TEX, CHAR_WIDTHS.as_ptr(), 12, 32, 96);
    }
}
}

font_bind

Binds a font for subsequent draw_text() calls.

Signature:

#![allow(unused)]
fn main() {
fn font_bind(font_handle: u32)
}

Example:

#![allow(unused)]
fn main() {
fn render() {
    // Use custom font
    font_bind(MY_FONT);
    set_color(0xFFFFFFFF);
    draw_text(b"Custom Text".as_ptr(), 11, 10.0, 10.0, 16.0);

    // Switch to different font
    font_bind(TITLE_FONT);
    set_color(0xFFD700FF);
    draw_text(b"Title".as_ptr(), 5, 100.0, 50.0, 32.0);
}
}

Complete Example

#![allow(unused)]
fn main() {
static mut UI_FONT: u32 = 0;
static mut ICON_SHEET: u32 = 0;

// Icon sheet is 64x32 pixels with 16x16 icons
const ICON_SIZE: f32 = 16.0;
const SHEET_W: f32 = 64.0;
const SHEET_H: f32 = 32.0;
const ICON_UV_W: f32 = ICON_SIZE / SHEET_W;  // 0.25
const ICON_UV_H: f32 = ICON_SIZE / SHEET_H;  // 0.5

fn init() {
    unsafe {
        UI_FONT = rom_font(b"ui_font".as_ptr(), 7);
        ICON_SHEET = rom_texture(b"icons".as_ptr(), 5);
    }
}

fn render() {
    unsafe {
        // Disable depth for 2D overlay
        depth_test(0);
        blend_mode(1);

        // Background panel
        set_color(0x00000099);
        draw_rect(5.0, 5.0, 200.0, 80.0);

        // Health bar background
        set_color(0x333333FF);
        draw_rect(10.0, 10.0, 102.0, 12.0);

        // Health bar fill
        set_color(0x00FF00FF);
        draw_rect(11.0, 11.0, health as f32, 10.0);

        // Health icon (first icon in sheet)
        texture_bind(ICON_SHEET);
        set_color(0xFFFFFFFF);
        draw_sprite_region(
            10.0, 25.0, 16.0, 16.0,      // Position and size
            0.0, 0.0, ICON_UV_W, ICON_UV_H  // UV region (0.0-1.0)
        );

        // Score text
        font_bind(UI_FONT);
        set_color(0xFFFFFFFF);
        let score_text = b"SCORE: 12345";
        draw_text(score_text.as_ptr(), score_text.len() as u32,
                  30.0, 25.0, 12.0);

        // Animated coin icon (4 frames in bottom row)
        let frame = ((elapsed_time() * 8.0) as u32) % 4;
        set_color(0xFFD700FF);
        draw_sprite_region(
            10.0, 45.0, 16.0, 16.0,
            frame as f32 * ICON_UV_W, 0.5, ICON_UV_W, ICON_UV_H  // UV coords
        );

        // Re-enable depth for 3D
        depth_test(1);
        blend_mode(0);
    }
}
}

See Also: rom_font, Textures