Drawing

Previously, I decided to try and draw directly onto the display instead of using the existing calendar application. Drawing on the display is fairly easy in Inferno, and is something I like to do in many of my init scripts so that I can check that I am using the correct pixel formats.

A Limbo program

A version of the code I use is shown below. It draws four horizontal stripes at the top-left of the screen: three for the primary colours and one for white, using gradients starting from black and increasing in brightness until the full intensity of each colour is shown. The first half of the code includes definitions from module files and defines the Test module that the program implements.

implement Test;

include "sys.m";
include "draw.m";
Context, Display, Image, Point, Rect: import draw;

draw: Draw;

Test: module
{
    init: fn(nil: ref Context, nil: list of string);
};

init(context: ref Context, nil: list of string)
{
    # Use the Draw module to draw on the screen.
    draw = load Draw Draw->PATH;
    display := Display.allocate(nil);
    for (b := 0; b < 256; b++) {
        display.image.draw(Rect(Point(b, 0), Point(b + 1, 4)), display.rgb(b, 0, 0), display.opaque, Point(0, 0));
        display.image.draw(Rect(Point(b, 4), Point(b + 1, 8)), display.rgb(0, b, 0), display.opaque, Point(0, 0));
        display.image.draw(Rect(Point(b, 8), Point(b + 1, 12)), display.rgb(0, 0, b), display.opaque, Point(0, 0));
        display.image.draw(Rect(Point(b, 12), Point(b + 1, 16)), display.rgb(b, b, b), display.opaque, Point(0, 0));
    }
}

In the init function, an instance of the Draw module is loaded and assigned to the global draw variable, which is then used to allocate a display. The display allows access to the image that represents its framebuffer, so we can draw the rectangles that make up the gradient.

Running the code

If you want to run the code (test.b) in the emulator, you will need to run the emulator with the -g option, like this:

emu -g 320x240

In the emulator, find the directory where you placed the test.b file and compile it before running it:

limbo test.b
./test

This causes a 320×240 sized window to open that should show something like the image below.


Drawing a gradient at the top-left of the display

Normally, when running emu, having to choose the size of the window is inconvenient, especially if you decide you need more space to do things. In this case it's helpful that the window size is chosen in advance because it lets me prototype the user interface for a small-screen device.


David Boddie
17 December 2021