sigildocs

Graphics and Audio

Sigil provides cross-platform graphics, audio, and windowing for building games and creative applications. It's built on Sokol, a collection of lightweight C libraries.

Modules

  • (sigil app) — Application lifecycle, windowing, input events
  • (sigil graphics) — 2D rendering, textures, transforms
  • (sigil graphics font) — Text rendering with TrueType fonts
  • (sigil graphics image) — Image loading
  • (sigil audio) — Sound effects and music playback

Quick Start

A minimal graphical application:

(import (sigil app)
        (sigil graphics))

(define (init) #f)

(define (frame dt)
  (with-frame
    (clear-screen 0.1 0.1 0.2)
    (set-color 1.0 0.5 0.0)
    (fill-rect 100 100 64 64)))

(define (cleanup) #f)

(app-run init frame cleanup)

Application Lifecycle

app-run

The main entry point for graphical applications:

(app-run init-proc frame-proc cleanup-proc
         [title: "Sigil App"]
         [width: 800]
         [height: 600])
  • init-proc — Called once at startup
  • frame-proc — Called every frame with delta time (seconds)
  • cleanup-proc — Called before exit

Input

;; Keyboard
(key-down? 'space)      ; Currently held
(key-pressed? 'return)  ; Just pressed this frame
(key-released? 'escape) ; Just released this frame

;; Mouse
(mouse-x)               ; X position in pixels
(mouse-y)               ; Y position in pixels
(mouse-down? 'left)     ; Button held
(mouse-pressed? 'right) ; Button just clicked

;; Lifecycle
(quit-requested?)       ; User tried to close window
(request-quit)          ; Trigger application exit

Key symbols: 'a through 'z, '0 through '9, 'space, 'return, 'escape, 'left, 'right, 'up, 'down, 'tab, 'backspace, etc.

Frame Info

(frame-time)    ; Seconds since last frame (delta time)
(time-elapsed)  ; Seconds since app started
(frame-width)   ; Frame buffer width in pixels
(frame-height)  ; Frame buffer height in pixels

Graphics

Frame Structure

All drawing happens between begin-frame and end-frame:

(with-frame
  (clear-screen 0 0 0)
  ;; drawing commands here
  )

The with-frame macro handles begin-frame and end-frame automatically.

Viewport and Coordinates

Set up a virtual coordinate system with automatic letterboxing:

(set-viewport 320 240)  ; Virtual 320x240 resolution
(set-letterbox-color 0 0 0)  ; Black bars

This maintains aspect ratio regardless of window size.

Colors

(set-color 1.0 0.0 0.0)       ; Red (RGB, 0.0-1.0)
(set-color 1.0 1.0 1.0 0.5)   ; White, 50% transparent (RGBA)

Shape Primitives

;; Rectangles
(fill-rect x y width height)
(draw-rect x y width height)

;; Lines and points
(draw-line x1 y1 x2 y2)
(draw-point x y)

;; Triangles
(fill-triangle x1 y1 x2 y2 x3 y3)
(draw-triangle x1 y1 x2 y2 x3 y3)

Textures

Load and draw images:

(import (sigil graphics image))

;; Load image from file
(define img (load-image "sprite.png"))

;; Create GPU texture
(define tex (load-texture img))

;; Draw at position
(draw-texture tex 100 100)

;; Draw scaled
(draw-texture tex 100 100 width: 64 height: 64)

;; Draw sprite sheet region
(draw-texture-region tex x y sx sy sw sh)

Supported formats: PNG, JPEG, BMP, TGA, GIF.

Transforms

Apply transformations to subsequent drawing:

(push-transform)
  (translate 100 100)
  (rotate 0.5)  ; radians
  (scale 2.0 2.0)
  (fill-rect -16 -16 32 32)  ; Drawn transformed
(pop-transform)

;; Rotate around a point
(rotate-at angle center-x center-y)
(scale-at sx sy center-x center-y)

;; Reset to identity
(reset-transform)

Text Rendering

(import (sigil graphics font))

;; Load TrueType font at pixel size
(define font (load-font "DejaVuSans.ttf" 24))

;; Draw text
(draw-text font "Hello, World!" 100 100)

;; Measure text width
(text-width font "Hello")  ; => pixels

;; Draw centered
(draw-text-centered font "Centered" 400 300)

Audio

Setup

Audio is initialized automatically when using app-run. For manual control:

(import (sigil audio))

(audio-setup)
;; ... use audio ...
(audio-shutdown)

Sound Effects

Short sounds loaded entirely into memory:

(define explosion (load-sound "explosion.ogg"))

;; Play sound
(play-sound explosion)
(play-sound explosion volume: 0.5)  ; 50% volume

;; Stop all sounds
(stop-all-sounds)

Music

Streamed from disk for longer audio:

(define bgm (load-music "background.ogg"))

;; Playback control
(play-music bgm)
(play-music bgm loop: #t)  ; Loop forever
(pause-music)
(resume-music)
(stop-music)

;; Check state
(music-playing?)  ; => #t or #f

;; Volume
(set-music-volume 0.8)  ; 0.0 to 1.0

Supported format: OGG Vorbis.

Global Audio Control

(set-master-volume 0.5)  ; Affects all audio
(mute-audio)
(unmute-audio)
(audio-muted?)  ; => #t or #f

Example: Simple Game

(import (sigil app)
        (sigil graphics)
        (sigil graphics font)
        (sigil audio))

(define player-x 400)
(define player-y 300)
(define speed 200)
(define font #f)
(define jump-sound #f)

(define (init)
  (set-viewport 800 600)
  (set! font (load-font "game-font.ttf" 16))
  (set! jump-sound (load-sound "jump.ogg")))

(define (frame dt)
  ;; Input
  (when (key-down? 'left)
    (set! player-x (- player-x (* speed dt))))
  (when (key-down? 'right)
    (set! player-x (+ player-x (* speed dt))))
  (when (key-pressed? 'space)
    (play-sound jump-sound))
  (when (key-pressed? 'escape)
    (request-quit))

  ;; Render
  (with-frame
    (clear-screen 0.2 0.3 0.4)

    ;; Player
    (set-color 1.0 0.8 0.0)
    (fill-rect (- player-x 16) (- player-y 16) 32 32)

    ;; UI
    (set-color 1.0 1.0 1.0)
    (draw-text font "Arrow keys to move, Space to jump" 10 10)))

(define (cleanup) #f)

(app-run init frame cleanup
         title: "My Game"
         width: 800
         height: 600)

Building a Game

Add the graphics and audio packages to your dependencies:

;; package.sgl
(package
  name: "my-game"
  version: "0.1.0"

  dependencies:
  (list
    (from-workspace name: "sigil-app")
    (from-workspace name: "sigil-graphics")
    (from-workspace name: "sigil-audio"))

  entry: '(my-game main))

Build and run:

sigil run

Create a standalone executable:

sigil build --config release

Cross-Platform Notes

The graphics and audio libraries work on:

  • Linux (OpenGL)
  • macOS (Metal)
  • Windows (D3D11)
  • WebAssembly (WebGL)

The same code runs on all platforms — Sokol handles the graphics backend abstraction.