Dynawa Lua API

The following functions are defined in main.bin's Lua compiler / interpreter. Your boot.lua script can use them as soon as it is called for the first time.

All of these functions are fully blocking, i.e. the Lua execution always halts until the function returns.

Bitmaps and Display

The graphic system is based on bitmaps. A bitmap is a rectangle of pixels. Each pixel has R, G an B values (1 byte each) and an alpha channel value (1 byte). Bitmaps can be larger than physical screen size. Bitmaps are represented as full Lua userdata and thus can be analyzed using dynawa.peek() function (described later) and are properly garbage-collected. Also note that Lua's full userdata are passed as references which means that modifying a bitmap results in modification of all existing "instances" of this bitmap (which are in fact just different pointers to a single bitmap).

bitmap = dynawa.bitmap.new(width, height, [[R,G,B],A])

This function returns a new bitmap with size width * height in which each all pixels have the specified R,G,B and A values. If R,G,B and A are omitted, they default to 0,0,0 and 255 respectively.

bitmap = dynawa.bitmap.from_png(string)

New bitmap is parsed from the binary data given in "string". TODO errors.

bitmap = dynawa.bitmap.from_png(filename)

New bitmap is parsed from the file on microSD card. TODO errors.

dynawa.bitmap.show (bitmap, [rotate])

The given bitmap is displayed on device's display. If "rotate" is true, the bitmap is rotated 180 degrees.

Bitmap's dimensions must be 160x128 pixels. Transparency values are ignored.

Note: Copying the bitmap to video memory is significantly slower than manipulating bitmap in RAM.

dynawa.bitmap.show_partial (bitmap, bmp_x, bmp_y, width, height, scr_x, scr_y, [rotate])

The rectangular sub-region of "bitmap", defined by bmp_x, bmp_y, width and height is displayed on the device's screen. Arguments scr_x and scr_y specify the position of bitmap's top left corner on the screen.

If the "rotate" argument is true, it's assumed the screen is physically rotated 180 degrees and all values are automatically adjusted to accomodate this fact and display the bitmap "correctly". 

There is no intelligent clipping. Your application must guarantee that all the values are valid and don't lie outside the screen.

If bmp_x, bmp_y, width and height are all nil, the the whole bitmap is used (not just its sub-region).

bitmap = dynawa.bitmap.copy (source_bmp, x, y, width, height)

This function creates the new bitmap as a partial copy of original bitmap. The new bitmap has the size of width * height pixels and its top-left pixel is taken from x,y cordinates in the original bitmap.

This function performs intelligent clipping and can work with "illegal values", i.e. the new bitmap does not have to be fully enclosed by the original bitmap. Optional new "blank pixels" in the new bitmap are created as fully transparent.

Function returns the new bitmap. The original bitmap is not modified.

bitmap = dynawa.bitmap.combine (background_bitmap, overlay_bitmap, x, y, [new_bitmap])

The "overlay_bitmap" is "overlaid" on top of "background_bitmap" with overlay's top-left pixel being put at background's x,y coordinates. The modified bitmap is returned.

If optional "new_bitmap" argument is true, background_bitmap is not modified in any way and new bitmap is returned as function's result.

In any case, the clipping is always handled correctly.

bitmap = dynawa.bitmap.mask (source_bitmap, mask_bitmap, x, y)

This is a special function, a hybrid of bitmap.copy and bitmap.combine. The mask_bitmap is (hypothetically) overlaid onto source_bitmap with mask_bitmap's top-left pixel being located at source_bitmap's x,y coordinates. Then, a new bitmap is created, whose size is the same as mask_bitmap's size. For each pixel of this new bitmap, the R, G and B values are taken from source_bitmap, however the transparency values are taken from mask_bitmap. The new bitmap is the function's return value.

For example, if source_bitmap is a large rectangle filled with color gradient and mask_bitmap is small blue star, the result of dynawa.bitmap.mask will be small star with color gradient.

The clipping is handled correctly. The original bitmaps are not modified. The new bitmap always has the same dimensions as mask_bitmap.


userdata = dynawa.timer.start(delta, [repeat])

This function creates new timer which fires after "delta" milliseconds. If "repeat" is true, the timer fires every "delta" ms repeatedly, until stopped.

This function returns a timer handle (light userdata).

Note that timers are not clocked using the high-precision hardware clock and, as such, are not very precise. Generally, you should expect deviation of about 1% (i.e. loss or gain of about 1 second per 100 seconds).


Explicitly cancels the timer with specified handle. If this handle does not exist, no error is raised. 

Note that at the instant you are calling the dynawa.timer.cancel() function, it's possible the timer has actually already fired and you will receive its "timer_fired" event in one of the following handle_event() iterations, i.e. after the succesful cancellation!

Time and Date

ticks = dynawa.ticks()

This function returns a number (integer) of milliseconds since the watch was last switched on or reset.

Note that this function uses the same counter as dynawa.timer.start() and as such cannot be relied on for exact time values.

seconds, milliseconds = dynawa.time.get()

This function returns the same integer value as Lua's default os.time() function - the number of seconds that have passed since the beginning of year 1970. The only difference is that dynawa.time.get() also returns a second value. This second value represents number of milliseconds since the last whole second. Its value is always between 0 and 990 inclusive and its resolution is 10 milliseconds (i.e. it's always divisible by 10). Example:

local secs, msecs = dynawa.time.get()
print("Exactly "..secs + msecs/1000..." seconds have passed since 1970")

This function (as well as os.time() function) uses the precise hardware clock but is more processor-expensive than dynawa.ticks().


Sets the precise hardware clock to new value. Milliseconds are set to 0.


table = dynawa.file.dir_stat(fname)

Returns info about files in the microSD card directory. "fname" is full pathname of directory. If fname does not exist or is not directory, the function raises an error. If succesfull, it returns a table whose keys are filenames (without full pathnames) and values are file sizes (non-negative integers) or "dir" (string) for subdirectories. For example, dynawa.file.dir_stat("/_sys/") could return the following table: {["boot.lua"] = 5678, ["wristos.lua"] = 23456, ["apps"] = "dir"}

boolean = dynawa.file.mkdir(name)

Creates directory on microSD card. "name" is full pathname. Returns true when succesful. Returns false when directory (or file with same name) already exists.


byte = dynawa.peek (address [,userdata])

Returns the value of byte at address "address" in RAM. If "userdata" is present, instead returns value of byte at index "address" in this userdata (indexing is zero-based).