Abstract

Lights, camera, action!

Making use of Lys requires hooking into (or duplicating) its custom Makefile rules, so you should also read the usage section of the README.

On the Futhark side, you need to define a module called lys that implements the module type lys. You can do this directly, or use some of the various conveniences defined in this file. For example, if you do not care about showing any text, you can use lys_no_text.

Synopsis

open import "lib/github.com/athas/matte/colour"
type string [n] = [n]u8
type event = #keydown {key: i32} | #keyup {key: i32} | #mouse {buttons: i32, x: i32, y: i32} | #step f32 | #wheel {dx: i32, dy: i32}
module type lys_core = {
type~ state
val event: event -> state -> state
val resize: (h: i64) -> (w: i64) -> state -> state
val render: state -> [][]argb.colour
}
module type lys = {
include lys_core
val init: (seed: u32) -> (h: i64) -> (w: i64) -> state
val grab_mouse: bool
val text_format: () -> string []
type text_content
val text_content: (fps: f32) -> state -> text_content
val text_colour: state -> argb.colour
}
module type lys_no_text = lys with text_content = ()
module lys_no_text: {
type text_content = ()
val text_format: () -> *[0]u8
val text_content '^t₀ '^t₁: t₀ -> t₁ -> ()
val text_colour '^t₀: t₀ -> u32
}
module lys: lys_no_text
val SDLK_UNKNOWN : i32
val SDLK_BACKSPACE : i32
val SDLK_TAB : i32
val SDLK_RETURN : i32
val SDLK_ESCAPE : i32
val SDLK_SPACE : i32
val SDLK_EXCLAIM : i32
val SDLK_QUOTEDBL : i32
val SDLK_HASH : i32
val SDLK_DOLLAR : i32
val SDLK_PERCENT : i32
val SDLK_AMPERSAND : i32
val SDLK_QUOTE : i32
val SDLK_LEFTPAREN : i32
val SDLK_RIGHTPAREN : i32
val SDLK_ASTERISK : i32
val SDLK_PLUS : i32
val SDLK_COMMA : i32
val SDLK_MINUS : i32
val SDLK_PERIOD : i32
val SDLK_SLASH : i32
val SDLK_0 : i32
val SDLK_1 : i32
val SDLK_2 : i32
val SDLK_3 : i32
val SDLK_4 : i32
val SDLK_5 : i32
val SDLK_6 : i32
val SDLK_7 : i32
val SDLK_8 : i32
val SDLK_9 : i32
val SDLK_COLON : i32
val SDLK_SEMICOLON : i32
val SDLK_LESS : i32
val SDLK_EQUALS : i32
val SDLK_GREATER : i32
val SDLK_QUESTION : i32
val SDLK_AT : i32
val SDLK_LEFTBRACKET : i32
val SDLK_BACKSLASH : i32
val SDLK_RIGHTBRACKET : i32
val SDLK_CARET : i32
val SDLK_UNDERSCORE : i32
val SDLK_BACKQUOTE : i32
val SDLK_a : i32
val SDLK_b : i32
val SDLK_c : i32
val SDLK_d : i32
val SDLK_e : i32
val SDLK_f : i32
val SDLK_g : i32
val SDLK_h : i32
val SDLK_i : i32
val SDLK_j : i32
val SDLK_k : i32
val SDLK_l : i32
val SDLK_m : i32
val SDLK_n : i32
val SDLK_o : i32
val SDLK_p : i32
val SDLK_q : i32
val SDLK_r : i32
val SDLK_s : i32
val SDLK_t : i32
val SDLK_u : i32
val SDLK_v : i32
val SDLK_w : i32
val SDLK_x : i32
val SDLK_y : i32
val SDLK_z : i32
val SDLK_DELETE : i32
val SDLK_CAPSLOCK : i32
val SDLK_F1 : i32
val SDLK_F2 : i32
val SDLK_F3 : i32
val SDLK_F4 : i32
val SDLK_F5 : i32
val SDLK_F6 : i32
val SDLK_F7 : i32
val SDLK_F8 : i32
val SDLK_F9 : i32
val SDLK_F10 : i32
val SDLK_F11 : i32
val SDLK_F12 : i32
val SDLK_PRINTSCREEN : i32
val SDLK_SCROLLLOCK : i32
val SDLK_PAUSE : i32
val SDLK_INSERT : i32
val SDLK_HOME : i32
val SDLK_PAGEUP : i32
val SDLK_END : i32
val SDLK_PAGEDOWN : i32
val SDLK_RIGHT : i32
val SDLK_LEFT : i32
val SDLK_DOWN : i32
val SDLK_UP : i32
val SDLK_NUMLOCKCLEAR : i32
val SDLK_KP_DIVIDE : i32
val SDLK_KP_MULTIPLY : i32
val SDLK_KP_MINUS : i32
val SDLK_KP_PLUS : i32
val SDLK_KP_ENTER : i32
val SDLK_KP_1 : i32
val SDLK_KP_2 : i32
val SDLK_KP_3 : i32
val SDLK_KP_4 : i32
val SDLK_KP_5 : i32
val SDLK_KP_6 : i32
val SDLK_KP_7 : i32
val SDLK_KP_8 : i32
val SDLK_KP_9 : i32
val SDLK_KP_0 : i32
val SDLK_KP_PERIOD : i32
val SDLK_APPLICATION : i32
val SDLK_POWER : i32
val SDLK_KP_EQUALS : i32
val SDLK_F13 : i32
val SDLK_F14 : i32
val SDLK_F15 : i32
val SDLK_F16 : i32
val SDLK_F17 : i32
val SDLK_F18 : i32
val SDLK_F19 : i32
val SDLK_F20 : i32
val SDLK_F21 : i32
val SDLK_F22 : i32
val SDLK_F23 : i32
val SDLK_F24 : i32
val SDLK_EXECUTE : i32
val SDLK_HELP : i32
val SDLK_MENU : i32
val SDLK_SELECT : i32
val SDLK_STOP : i32
val SDLK_AGAIN : i32
val SDLK_UNDO : i32
val SDLK_CUT : i32
val SDLK_COPY : i32
val SDLK_PASTE : i32
val SDLK_FIND : i32
val SDLK_MUTE : i32
val SDLK_VOLUMEUP : i32
val SDLK_VOLUMEDOWN : i32
val SDLK_KP_COMMA : i32
val SDLK_KP_EQUALSAS400 : i32
val SDLK_ALTERASE : i32
val SDLK_SYSREQ : i32
val SDLK_CANCEL : i32
val SDLK_CLEAR : i32
val SDLK_PRIOR : i32
val SDLK_RETURN2 : i32
val SDLK_SEPARATOR : i32
val SDLK_OUT : i32
val SDLK_OPER : i32
val SDLK_CLEARAGAIN : i32
val SDLK_CRSEL : i32
val SDLK_EXSEL : i32
val SDLK_KP_00 : i32
val SDLK_KP_000 : i32
val SDLK_THOUSANDSSEPARATOR : i32
val SDLK_DECIMALSEPARATOR : i32
val SDLK_CURRENCYUNIT : i32
val SDLK_CURRENCYSUBUNIT : i32
val SDLK_KP_LEFTPAREN : i32
val SDLK_KP_RIGHTPAREN : i32
val SDLK_KP_LEFTBRACE : i32
val SDLK_KP_RIGHTBRACE : i32
val SDLK_KP_TAB : i32
val SDLK_KP_BACKSPACE : i32
val SDLK_KP_A : i32
val SDLK_KP_B : i32
val SDLK_KP_C : i32
val SDLK_KP_D : i32
val SDLK_KP_E : i32
val SDLK_KP_F : i32
val SDLK_KP_XOR : i32
val SDLK_KP_POWER : i32
val SDLK_KP_PERCENT : i32
val SDLK_KP_LESS : i32
val SDLK_KP_GREATER : i32
val SDLK_KP_AMPERSAND : i32
val SDLK_KP_DBLAMPERSAND : i32
val SDLK_KP_VERTICALBAR : i32
val SDLK_KP_DBLVERTICALBAR : i32
val SDLK_KP_COLON : i32
val SDLK_KP_HASH : i32
val SDLK_KP_SPACE : i32
val SDLK_KP_AT : i32
val SDLK_KP_EXCLAM : i32
val SDLK_KP_MEMSTORE : i32
val SDLK_KP_MEMRECALL : i32
val SDLK_KP_MEMCLEAR : i32
val SDLK_KP_MEMADD : i32
val SDLK_KP_MEMSUBTRACT : i32
val SDLK_KP_MEMMULTIPLY : i32
val SDLK_KP_MEMDIVIDE : i32
val SDLK_KP_PLUSMINUS : i32
val SDLK_KP_CLEAR : i32
val SDLK_KP_CLEARENTRY : i32
val SDLK_KP_BINARY : i32
val SDLK_KP_OCTAL : i32
val SDLK_KP_DECIMAL : i32
val SDLK_KP_HEXADECIMAL : i32
val SDLK_LCTRL : i32
val SDLK_LSHIFT : i32
val SDLK_LALT : i32
val SDLK_LGUI : i32
val SDLK_RCTRL : i32
val SDLK_RSHIFT : i32
val SDLK_RALT : i32
val SDLK_RGUI : i32
val SDLK_MODE : i32
val SDLK_AUDIONEXT : i32
val SDLK_AUDIOPREV : i32
val SDLK_AUDIOSTOP : i32
val SDLK_AUDIOPLAY : i32
val SDLK_AUDIOMUTE : i32
val SDLK_MEDIASELECT : i32
val SDLK_WWW : i32
val SDLK_MAIL : i32
val SDLK_CALCULATOR : i32
val SDLK_COMPUTER : i32
val SDLK_AC_SEARCH : i32
val SDLK_AC_HOME : i32
val SDLK_AC_BACK : i32
val SDLK_AC_FORWARD : i32
val SDLK_AC_STOP : i32
val SDLK_AC_REFRESH : i32
val SDLK_AC_BOOKMARKS : i32
val SDLK_BRIGHTNESSDOWN : i32
val SDLK_BRIGHTNESSUP : i32
val SDLK_DISPLAYSWITCH : i32
val SDLK_KBDILLUMTOGGLE : i32
val SDLK_KBDILLUMDOWN : i32
val SDLK_KBDILLUMUP : i32
val SDLK_EJECT : i32
val SDLK_SLEEP : i32

Description

type string [n] = [n]u8

UTF-8 encoded string. This is what is produced by string literals in Futhark code.

type event = #keydown {key: i32} | #keyup {key: i32} | #mouse {buttons: i32, x: i32, y: i32} | #step f32 | #wheel {dx: i32, dy: i32}

An event is sent when something has happened that might cause the state of the program to change, or just when some time has passed. It is permissible to ignore all of these events. Things that must not be ignored are separate functions in lys.

  • #step x: x seconds have passed since init or the last time this event was received.

  • #keydown {key}: key has pressed.

  • #keyup {key}: key has been released.

  • #mouse {buttons, x, y}: The mouse has been moved or clicked. buttons is a bit mask indicating which button(s) are held down, and the x/y the new position of the mouse.

  • #wheel {dx, dy}: The mouse wheel has been used. Note that there can be multiple wheels; this is why the dy direction also makes sense. In most cases, however, only the dy will be non-zero.

module type lys_core

The core subset of the module type of Lys applications. This is useful if you need a Lys application with custom initialisation or without text rendering.

type~ state

The state maintained by this Lys application. Most functions will take the current state and return a new state.

val event: event -> state -> state

An event occured. It is permissible to ignore any of these events by returning the same state unchanged.

val resize: (h: i64) -> (w: i64) -> state -> state

The window was resized.

val render: state -> [][]argb.colour

The function for rendering a screen image in row-major order (height by width). The size of the array returned must match the last dimensions provided to the state (via init or resize).

module type lys

The module type of Lys applications. If you define a module called lys that has this module type, then the autogenerated Lys wrapper application can automatically define the entry point functions that allows Lys to communicate with the C program that actually implements the user interaction.

include lys_core
val init: (seed: u32) -> (h: i64) -> (w: i64) -> state

Initial state for a given window size. A random seed is passed in. Don't treat this as a true random number (it's currently just a timestamp), but use it for initialising a proper RNG.

val grab_mouse: bool

If true, the program will grab the mouse, and all positions reported via the mouse function will be relative to the last time mouse was called. If in doubt, leave this false.

val text_format: () -> string []

Show helpful text in the upper-left corner. Specify in printf format with extensions: '%[string1|string2|...]' prints a string but takes an index into the given list of strings, separated by '|'. For example, '%[circle|square]' prints 'circle' if passed the i32 value 0, and 'square' if passed 1.

type text_content

The content must be a scalar or a tuple of scalars.

val text_content: (fps: f32) -> state -> text_content
val text_colour: state -> argb.colour

The colour can vary based on the state.

module type lys_no_text

A module type for the simple case where we don't want any text. You can define the lys module to have this module type instead of lys. For maximal convenience, you can open lys_no_text inside your module definition.

module lys_no_text

A convenience module that can be opened to give dummy definitions for the text-related functionality.

module lys

A dummy lys module that just produces a black rectangle and does nothing in response to events.

val SDLK_TAB: i32
val SDLK_SPACE: i32
val SDLK_HASH: i32
val SDLK_QUOTE: i32
val SDLK_PLUS: i32
val SDLK_COMMA: i32
val SDLK_MINUS: i32
val SDLK_SLASH: i32
val SDLK_0: i32
val SDLK_1: i32
val SDLK_2: i32
val SDLK_3: i32
val SDLK_4: i32
val SDLK_5: i32
val SDLK_6: i32
val SDLK_7: i32
val SDLK_8: i32
val SDLK_9: i32
val SDLK_COLON: i32
val SDLK_LESS: i32
val SDLK_AT: i32
val SDLK_CARET: i32
val SDLK_a: i32
val SDLK_b: i32
val SDLK_c: i32
val SDLK_d: i32
val SDLK_e: i32
val SDLK_f: i32
val SDLK_g: i32
val SDLK_h: i32
val SDLK_i: i32
val SDLK_j: i32
val SDLK_k: i32
val SDLK_l: i32
val SDLK_m: i32
val SDLK_n: i32
val SDLK_o: i32
val SDLK_p: i32
val SDLK_q: i32
val SDLK_r: i32
val SDLK_s: i32
val SDLK_t: i32
val SDLK_u: i32
val SDLK_v: i32
val SDLK_w: i32
val SDLK_x: i32
val SDLK_y: i32
val SDLK_z: i32
val SDLK_F1: i32
val SDLK_F2: i32
val SDLK_F3: i32
val SDLK_F4: i32
val SDLK_F5: i32
val SDLK_F6: i32
val SDLK_F7: i32
val SDLK_F8: i32
val SDLK_F9: i32
val SDLK_F10: i32
val SDLK_F11: i32
val SDLK_F12: i32
val SDLK_PAUSE: i32
val SDLK_HOME: i32
val SDLK_END: i32
val SDLK_RIGHT: i32
val SDLK_LEFT: i32
val SDLK_DOWN: i32
val SDLK_UP: i32
val SDLK_KP_1: i32
val SDLK_KP_2: i32
val SDLK_KP_3: i32
val SDLK_KP_4: i32
val SDLK_KP_5: i32
val SDLK_KP_6: i32
val SDLK_KP_7: i32
val SDLK_KP_8: i32
val SDLK_KP_9: i32
val SDLK_KP_0: i32
val SDLK_POWER: i32
val SDLK_F13: i32
val SDLK_F14: i32
val SDLK_F15: i32
val SDLK_F16: i32
val SDLK_F17: i32
val SDLK_F18: i32
val SDLK_F19: i32
val SDLK_F20: i32
val SDLK_F21: i32
val SDLK_F22: i32
val SDLK_F23: i32
val SDLK_F24: i32
val SDLK_HELP: i32
val SDLK_MENU: i32
val SDLK_STOP: i32
val SDLK_AGAIN: i32
val SDLK_UNDO: i32
val SDLK_CUT: i32
val SDLK_COPY: i32
val SDLK_PASTE: i32
val SDLK_FIND: i32
val SDLK_MUTE: i32
val SDLK_CLEAR: i32
val SDLK_PRIOR: i32
val SDLK_OUT: i32
val SDLK_OPER: i32
val SDLK_CRSEL: i32
val SDLK_EXSEL: i32
val SDLK_KP_00: i32
val SDLK_KP_A: i32
val SDLK_KP_B: i32
val SDLK_KP_C: i32
val SDLK_KP_D: i32
val SDLK_KP_E: i32
val SDLK_KP_F: i32
val SDLK_KP_AT: i32
val SDLK_LCTRL: i32
val SDLK_LALT: i32
val SDLK_LGUI: i32
val SDLK_RCTRL: i32
val SDLK_RALT: i32
val SDLK_RGUI: i32
val SDLK_MODE: i32
val SDLK_WWW: i32
val SDLK_MAIL: i32
val SDLK_EJECT: i32
val SDLK_SLEEP: i32