Jump to:

- Core Functionality
- Game Engine
- Music Language
- Tutorial

# BooBoo Game Engine

There are 3 optional functions taking/returning no parameters called from the app:

- draw - called at refresh rate
- run - called at logic rate (default 60 times per second)
- end - called when the program is exiting

Before draw, the backbuffer is cleared to black, the depth buffer is cleared to 1.0 and the stencil buffer is cleared to 0.

There are also GUI callbacks for events and drawing, and a callback for generic input events, which are described in the GUI and events sections.

There is another global callback you can define, draw_letterbox

    	function draw_letterbox type x y w h

x, y are the top left coordinate of where to draw, w/h are the width and height in pixels. See LETTERBOX_* in constants for the bar types. This is used to draw a custom letterbox when the window size and aspect ratio you requested don't match. A default letterbox will be drawn in case you don't draw anything.

At startup, global code is run. Then the above mentioned callbacks get called at intervals or shutdown.

The screen is 640x360 by default, stretched to the window size appropriately. F11 toggles between fullscreen/windowed mode. F12 exits. F10 takes a screenshot saved in your home directory and automatically numbered.

There are loads of command line switches you can use which come from Shim. A switch starting with + enables and a - disables things, but here are a few of them:

- +fullscreen
- +width x
- +height x
- -vsync
- +fps
- +volume [0-255]
- +multisampling
- +aa-samples 16
- +linear-filtering
- +freq hq ; audio frequency
- +float-samples ; use floating point (audio) samples
- +ops ; show ops/sec

Lots of the demos and examples use a simple Z/X key to A/B button mapping, so the keys are Z/X and arrows if you're using a keyboard. Most but not all included examples support the keyboard as well as joysticks.

The file shim5.json can be put in your data/ directory to supply some extra parameters and info such as window title and other things. You can also override game-supplied shim5.json files by placing one in you Windows Saved Games\BooBoo folder.

All colours use premultiplied alpha.

Most load function can take an optional boolean parameter at the end, which Tells BooBoo to load it from the filesystem rather than from the data/ directory or data.cpa. For example image_load, mml_load, font_load etc. It is called lffs below.

For no particular reason, I'm marking OPTIONAL PARAMETERS with a ^

This is the directory structure for data/ or data.cpa. For example image_load loads from gfx/images, mml_load loads from audio/mml etc.

    data/ or data.cpa:
    	gfx
    		images
    			misc
    			tiles
    		textures
    		models
    		sprites
    		palettes
    		shaders
    			glsl
    	audio
    		mml
    		samples
    	misc
    		maps
    	scripts

The following sections describe the API:

- Miscellaneous Functions
- Graphics Functions
- Primitives Functions
- Image Functions
- Sprite Functions
- Font Functions
- Tilemap Functions
- Shader Functions
- 3D Functions
- GUI Functions
- Collision Detection Functions
- Audio Functions
- Input Functions
- JSON Functions
- Constants
- Events

## Miscellaneous Functions

### inspect

    	print a value in a popup for debugging
    	e.g. inspect x

### delay

    	delay an amount of milliseconds
    	e.g. delay 1000

### (get_ticks)

    	Get milliseconds since BooBoo interpreter launch
    	e.g. = ticks (get_ticks)

### (get_logic_rate)

    	Query the logic rate (default 60)
    	e.g. = r (get_logic_rate)

### set_logic_rate

    	Change the logic rate. Values between 1 and 1000 inclusive are
    	supported.
    	e.g. set_logic_rate 144

### (file_list)

    	Get a list of files in the data/ directory or data.cpa
    	e.g. = vec (file_list)

### screenshot

    	Save a screenshot of the backbuffer. TGA and PNG are supported.
    	The optional boolean toggles whether or not the letterbox is saved
    	(default TRUE)
    	e.g. screenshot "screenshot.png" FALSE

### add_notification

    	Add a popup notification in the top right of the screen that goes
    	away after a few seconds. This uses the default font named font.ttf.
    	e.g. add_notification "You won!"

### screen_shake

    	Apply a screen shake effect
    	Currently only works with 2d projection, not after set_3d
    	e.g. screen_shake amount_in_pixels duration_in_millis

## Graphics Functions

### clear

    	clear the screen
    	The screen is cleared to black (RGB 0, 0, 0) before draw is called.
    	e.g. clear r g b

### flip

    	flip the backbuffer to the screen
    	Normally you don't need this, as a flip is done after draw returns,
    	but there are some situations where it's useful.
    	e.g. flip

### resize

    	resize the drawing area projection
    	Letterboxing will be applied if the window aspect ratio is
    	different from what you supply here
    	e.g. resize 240 160 ; make a GBA game!

### (get_screen_size)

    	Get the size of the window in pixels. This
    	includes "black bars" and scaling, this is
    	the raw pixel-for-pixel size of the window
    	(or fullscreen window)
    	e.g. explode (get_screen_size) scr_w scr_h

### (get_buffer_size)

    	Get the size of the drawing area projection.
    	This is what "resize" changes and it starts at 640x360.
    	e.g. explode (get_buffer_size) bw bh

### (get_screen_offset)

    	The BooBoo window is managed in a way that resizing the screen in
    	any way produces a scaled version of the game at the maximum size
    	the window will fit. Sometimes this requires "black bars".
    	screen_offset gives you the position of	the top left of the drawing
    	given any black bars. This is mainly useful for some shaders (for
    	example shaders that use gl_FragCoord.)
    	e.g. explode (get_screen_offset) ox oy

### (get_scale)

    	Retrieve the scale of the projection. BooBoo starts in a 1280x720
    	window with a 640x360 buffer, so e.g. the scale would be 2 to start
    	and would change based on window size and buffer size.
    	e.g. = s (get_scale)

### toggle_fullscreen

    	Change from fullscreen to windowed or vice versa depending on the
    	current windowed/fullscreen state.
    	e.g. toggle_fullscreen

### (is_fullscreen)

    	Find out if the screen is currently fullscreen
    	e.g. = onoff (is_fullscreen)

### (get_refresh_rate)

    	Query the refresh rate of the monitor
    	e.g. = r (get_refresh_rate)

### set_scissor

    	Set a scissor rectangle. Anything drawn outside of this will not be drawn.
    	This is based on the projection (buffer size) you're using, not actual
    	window size/coordinates/black bars to make it easier.
    	e.g. set_scissor x y w h

### unset_scissor

    	Undo a set_scissor, reverting the scissor rectangle to fullscreen.
    	e.g. unset_scissor

### (get_scissor)

    	Get the scissor rectangle
    	e.g. explode (get_scissor) x y w h

### set_viewport

    	Set a custom viewport
    	This is based on the projection (buffer size) you're using, not actual
    	window size/coordinates/black bars to make it easier.
    	e.g. set_viewport x y w h

### unset_viewport

    	Reset the viewport after custom setting
    	e.g. unset_viewport

### (get_viewport)

    	Get the viewport
    	e.g. explode (get_viewport) x y w h

### set_blend_mode

    	Set the colour blending mode. Default is ONE/INVSRCALPHA. See constants.
    	e.g. set_blend_mode BLEND_ONE BLEND_ONE ; additive blending

### (get_blend_mode)

    	Returns the blend mode
    	e.g. explode (get_blend_mode) src dst

### clear_depth_buffer

    	Clear the depth buffer. Expects a double
    	e.g. clear_depth_buffer 1.0

### clear_stencil_buffer

    	Clear the stencil buffer. Expects an int
    	e.g. clear_stencil_buffer #FFFFFFFF

### enable_depth_test

    	Enable/disable depth test
    	e.g. enable_depth_test onoff

### (is_depth_test_enabled)

    	Returns whether or not depth test is enabled
    	e.g. = onoff (is_depth_test_enabled)

### enable_depth_write

    	Enable/disable writing into the depth buffer
    	e.g. enable_depth_write onoff

### (is_depth_write_enabled)

    	Returns whether or not depth write is enabled
    	e.g. = onoff (is_depth_write_enabled)

### set_depth_mode

    	Set the depth buffer mode, one of the COMPARE_ functions listed in constants.
    	e.g. set_depth_mode COMPARE_LESSEQUAL

### (get_depth_mode)

    	Returns the depth mode
    	e.g. = mode (get_depth_mode)

### enable_stencil

    	Enable/disable stencil buffer
    	e.g. enable_stencil onoff

### (is_stencil_enabled)

    	Returns whether or not stencil is enabled
    	e.g. = onoff (is_stencil_enabled)

### enable_two_sided_stencil

    	Enable/disable two sided stencil
    	e.g. enable_two_sided_stencil onoff

### (is_two_sided_stencil_enabled)

    	Returns whether or not two sided stencil is enabled
    	e.g. = onoff (is_two_sided_stencil_enabled)

### set_stencil_mode

    	Set the stencil mode for frontfaces
    	e.g. set_stencil_mode COMPARE_LESS STENCILOP_REPALCE STENCILOP_REPLACE STENCILOP_KEEP #FF #00

### (get_stencil_mode)

    	Returns the stencil mode (front faces)
    	e.g. explode (get_stencil_mode) func fail zfail pass ref mask

### set_stencil_mode_backfaces

    	Set the stencil mode for backfaces
    	e.g. set_stencil_mode_backfaces COMPARE_LESS STENCILOP_REPALCE STENCILOP_REPLACE STENCILOP_KEEP #FF #00

### (get_stencil_mode_backfaces)

    	Returns the stencil mode (back faces)
    	e.g. explode (get_stencil_mode_backfaces) func fail zfail pass ref mask

### set_front_face

    	Set the winding order for front faces (see constants)
    	e.g. set_front_face FACE_CCW

### (get_front_face)

    	Returns the front face
    	e.g. = f (get_front_face)

### set_cull_mode

    	Set which faces are culled
    	e.g. set_cull_mode FRONT_FACE

### (get_cull_mode)

    	Returns the cull mode
    	e.g. = mode (get_cull_mode)

### enable_colour_write

    	Enable/disable writing into the colour buffer
    	e.g. enable_colour_write onoff

### (is_colour_write_enabled)

    	Returns whether or not colour write is enabled
    	e.g. = onoff (is_colour_write_enabled)

### set_projection

    	Set custom projection
    	e.g. set_projection mv proj

### set_default_projection

    	Restore the default projection
    	e.g. set_default_projection

### (get_projection)

    	Get the current projection matices
    	e.g. explode (get_projection) mv proj

### resize_vertex_cache

    	Normally not needed, but if you draw a tonne of geometry between
    	image_start/image_end or start_primitives/end_primitives, the vertex
    	cache could need to be resized frequently on first frame, so you can
    	use this to reserve a larger amount. This is in addition to whatever
    	has already been reserved.
    	e.g. resize_vertex_cache (* 1024 256)

### (create_vertex_buffer)

    	Draw arbitrary 3d geometry
    	All vectors are vectors of numbers
    	e.g., one vertex is 3 numbers, one face is 3 numbers, one colour is 4
    	faces are vertex indices
    	colours are per-face-vertex
    	empty colour vector = white
    	empty normal vector = 0.0
    	Pass vectors as pointers to avoid array copies
    	e.g. = vb (create_vertex_buffer (@ vert_vec) (@ face_vec) (@ colour_vec) (@ normal_vec) (@ texcoord_vec) num_triangles ^ create_fbo)

### destroy_vertex_buffer

    	Destroy a vertex buffer
    	e.g. destroy_vertex_buffer vb

### draw_vertex_buffer

    	Draw arbitrary geometry
    	e.g. draw_vertex_buffer vertex_buf

### draw_vertex_buffer_textured

    	Draw arbitrary textured geometry
    	e.g. draw_vertex_buffer_textured tex vertex_buf texture

## Primitive Functions

### start_primitives

    	batch primitives for speed
    	e.g. start_primitives

### end_primitives

    	batch primitives for speed
    	When this is called, anything between this and
    	the previous start_primitives gets drawn at once
    	e.g. end_primitives

### line

    	draw a line
    	e.g. line r g b a x1 y1 x2 y2 ^ thickness

### triangle

    	Draw an outline triangle
    	e.g. triangle r g b a x1 y1 x2 y2 x3 y3 ^ thickness

### filled_triangle

    	draw a filled triangle with 3 colours
    	e.g. filled_triangle r1 g1 b1 a1 r2 g2 b2 a2 r3 g3 b3 a3 x1 y1 x2 y2 x3 y3

### rectangle

    	draw a outline rectangle
    	e.g. rectangle r g b a x y w h ^ thickness

### filled_rectangle

    	draw a filled rectangle
    	e.g. filled_rectangle r1 g1 b1 a1 r2 g2 b2 a2 r2 g3 b3 a3 r4 g4 b4 a4 x y w h

### ellipse

    	draw a outline ellipse with given number of pie slices making up the circle
    	(4 is the minimum, -1 for auto)
    	e.g. ellipse r g b a x y radius_x radius_y ^ thickness sections

### filled_ellipse

    	draw a filled ellipse with given number of pie slices (-1 for auto)
    	e.g. filled_ellipse r g b a x y radius_x radius_y ^ sections

### circle

    	draw a outline circle with given number of pie slices (-1 for auto)
    	e.g. circle r g b a x y radius ^ thickness sections

### filled_circle

    	draw a filled circle with give number of pie slices (-1 for auto)
    	e.g. filled_circle r g b a x y radius ^ sections

## Image Functions

### set_target

    	Set the render target. This only works with images created with
    	image_create.
    	e.g. set_target img

### set_target_backbuffer

    	Set the render target to the backbuffer
    	e.g. set_target_backbuffer

### (image_create)

    	create a render target
    	e.g. = dest (image_create w h)
    	Returns -1 on fail

### (image_load)

    	load an image
    	e.g. = dest (image_load filename ^ lffs)
    	Returns -1 on fail

### image_save

    	Save an image. TGA and PNG are supported.
    	e.g. image_save img "c:/foo.tga"

### (image_read_texture)

    	Read a texture into a vector of colour components
    	e.g. = v (image_read_texture img)
    	e.g. = green [v y x 1]

### (image_to_texture)

    	Convert a vector of colour components to a image
    	This uses the same format returned by image_read_texture
    	e.g. image_read_texture img v
    	e.g. = [v y x 3] 255 ; change alpha of a pixel
    	e.g. image_destroy img
    	e.g. = img (image_to_texture v)

### image_update

    	Update the pixels of an existing texture, rather than creating a
    	new one. It's faster.
    	e.g. image_update img v /* v is in the same format as
    	image_read_texture describes */

### image_draw

    	draw an image
    	e.g. image_draw img tint_r tint_g tint_b tint_a x y ^ flip_h flip_v

### image_stretch_region

    	draw a region of an image and maybe stretch it
    	e.g. image_stretch_region image r g b a source_x source_y source_w source_h dest_x dest_y dest_w dest_h ^ flip_h flip_v

### image_draw_rotated_scaled

    	draw an image with rotation and scale
    	e.g. image_draw_rotated_scaled img tint_r tint_g tint_b tint_a pivot_x pivot_y x y angle scale_x scale_y ^ flip_h flip_v

### image_draw_9patch

    	Draw an image as a 9patch (9 equal chunks, 3x3 with the edges
    	outlining and the centre filled with the centre chunk)
    	e.g. image_draw_9patch img tint_r tint_g tint_b tint_a x y w h

### image_start

    	start a batch of images for speed (must be same image)
    	e.g. image_start img

### image_end

    	end a batch of images
    	e.g. image_end img

### (image_size)

    	get image width/height
    	e.g. explode (image_size img) w h

### image_destroy

    	Free an image
    	e.g. image_destroy img

## Sprite Functions

### (sprite_load)

    	Load a sprite. Please see the example for the format of a sprite.
    	Basically, each animation in a sprite is a sprite sheet exported
    	from Aseprite. Then there is a sprite.json which has a list of
    	animation names.
    	e.g. = sprite (sprite_load "my_sprite" ^ lffs)
    	Returns -1 on fail

### sprite_draw

    	Draw the current frame of a sprite
    	e.g. sprite_draw sprite tint_r g b a dx dy ^ flip_h flip_v

### sprite_set_animation

    	Set the current animation. You can optionally add a callback which
    	will be called when the animation is finished. The callback takes
    	1 parameter which will be the sprite (number) that set_animation
    	was called on.
    	e.g. sprite_set_animation sprite "punch" my_function

### sprite_set_animation_lazy

    	Like sprite_set_animation but forces nothing if the same animation has
    	already been set. Cannot take callbacks
    	e.g. sprite_set_animation_lazy sprite "run"

### (sprite_get_animation)

    	Returns the name of the current animation
    	e.g. = anim_name (sprite_get_animation sprite)

### (sprite_get_previous_animation)

    	Returns the name of the previous animation
    	e.g. = anim_name (sprite_get_previous_animation sprite)

### (sprite_length)

    	Returns the total length in milliseconds of the current animation
    	e.g. = l (sprite_length sprite)

### (sprite_current_frame)

    	Returns the current frame number
    	e.g. = n (sprite_current_frame sprite)

### (sprite_num_frames)

    	Gets the number of frames in the current animation
    	e.g. = nf (sprite_num_frames sprite)

### (sprite_current_frame_size)

    	Returns the size of the current frame's image
    	e.g. explode (sprite_current_frame_size sprite) w h

### sprite_start

    	Start a sprite's animation (if stopped)
    	e.g. sprite_start sprite

### sprite_stop

    	Stop a sprite's animation
    	e.g. sprite_stop sprite

### sprite_reset

    	Reset a sprite's animation to the beginning
    	e.g. sprite_reset sprite

### (sprite_bounds)

    	Returns the top left/bottom rightmost opaque pixels in the sprite
    	e.g. explode (sprite_bounds sprite) x1 y1 x2 y2

### (sprite_elapsed)

    	Get the number of milliseconds of elapsed time of the current
    	animation
    	e.g. = n (sprite_elapsed sprite)

### (sprite_frame_times)

    	Get a vector of numbers which are the duration of each frame in the
    	sprite in milliseconds
    	e.g. = v (sprite_frame_times sprite)

### (sprite_is_started)

    	Check if a sprite is started or not
    	e.g. = onoff (sprite_is_started sprite)

### sprite_destroy

    	Free a sprite
    	e.g. sprite_destroy s

## Font Functions

### (font_load)

    	load a TTF font
    	All of the font functions support UTF8
    	e.g. = font (font_load "DejaVuSans.ttf" px_size smooth_flag ^ lffs)
    	Returns -1 on fail

### font_draw

    	draw text. Colour codes can be used if you supply a
    	data/gfx/palettes/palette.gpl with a GIMP palette. Colour codes
    	use |## where ## is a hex number referencing a palette entry.
    	Up to 256 extra glyphs can be added with font_add_extra_glyph.
    	Those use @##.
    	e.g.
    	font_draw font r g b a "HELLO" x y ^ rtl
    	The rtl flag turns on right to left drawing

### (font_width)

    	get width of a string given a font
    	e.g. = dest (font_width font "FOOBARBAZ")

### (font_height)

    	get the height of a font
    	e.g. = dest (font_height font)

### font_add_extra_glyph

    	You can add up to 256 extra glyphs (0 to 255.) The can be used
    	with @## with font_draw.
    	e.g. font_add_extra_glyph font #00 my_image

### font_destroy

    	Free a font
    	e.g. font_destroy f

## Tilemap Functions

### set_tile_size

    	You should call this to set a (square) tile size before tilemap_load
    	unless your tiles are the default, 16 pixels in size.
    	e.g. set_tile_size 32

### (tilemap_load)

    	Load a tilemap from data/misc/maps. Tiles should be located in
    	data/gfx/images/tiles and named tiles0.png, tiles1.png and so on
    	(.tga is also supported.) See AshEdit for more details on maps
    	and creating them.
    	e.g. = t (tilemap_load "map.wm2" ^ lffs)
    	Returns -1 on fail

### tilemap_draw

    	Draw a selection of tilemap layers
    	This automatically crops (doesn't draw) tiles outside the screen
    	e.g. tilemap_draw tilemap start_layer_inclusive end_layer_inclusive x y

### (tilemap_num_layers)

    	Get the number of layers in a tilemap
    	e.g. = nl (tilemap_num_layers tilemap)

### (tilemap_size)

    	Get the size of a tilemap in tiles
    	e.g. explode (tilemap_size tilemap) w h

### (tilemap_is_solid)

    	Check if a tile is walkable
    	e.g. = solid (tilemap_is_solid tilemap x y)

### (tilemap_get_groups)

    	Get group info about groups in a tilemap
    	e.g. = vec (tilemap_get_groups tilemap)
    	The vector will be stuffed with type/x/y/w/h vectors
    	See AshEdit for the meaning of groups. They're basically
    	arbitrary integers/bitmasks that rectangles of a tilemap
    	can be defined as. For example you could define a group
    	with number 74 to be a question block in your platformer.

### tilemap_set_animated_tiles

    	Tiles can be animated. The delay is in milliseconds. Width
    	and height are the width and height of the area to animate. Then
    	the vector contains the topleft tile position of each frame of
    	animation (should be width by height) as a vector of vectors of
    	2 numbers each (x/y)
    	e.g. tilemap_set_animated_tiles tilemap delay w h anim_data

### (tilemap_find_path)

    	A* pathfinding using the tilemap solids and your own supplied points.
    	The path returned is a vector of vectors of x/y values
    	extra is a 2d vector of x/y values to use as extra solids
    	e.g. = path (tilemap_find_path tilemap extra start_x start_y end_x end_y)
    	path will be empty if there is no path

### tilemap_set_solid

    	Set the solid flag of a tile
    	e.g. tilemap_set_solid tilemap x y onoff

### tilemap_set_tile

    	Change a tile in the tilemap to the tile x/y given
    	e.g. tilemap_set_tile tilemap layer posx posy tile_x tile_y solid

### (tilemap_get_tile)

    	Get tile x/y and solid flag of layer/position in tilemap
    	e.g. explode (tilemap_get_tile tilemap layer x y) out_tx out_ty out_solid
    	out_tx/ty refers to x/y position within the tile sheet.

### tilemap_destroy

    	Free a tilemap
    	e.g. tilemap_destroy tilemap

## Shader Functions

### (shader_load)

    	Load a shader
    	e.g. = shader (shader_load "my_vert" "my_frag" ^ lffs)
    	This will load from
    	data/gfx/shaders/glsl/my_vert.txt
    	Returns -1 on fail
    	Shaders should be written in GLSL 1.2

### shader_use

    	Start using a shader
    	e.g. shader_use shader

### shader_use_default

    	Use the default shader
    	e.g. shader_use_default

### shader_set_bool

    	Set a boolean value in a shader
    	e.g. shader_set_bool shader "b" 0

### shader_set_int

    	Set an integer value in a shader
    	e.g. shader_set_int shader "i" 1298

### shader_set_float

    	Set a float value in a shader
    	e.g. shader_set_float shader "f" 10.1

### shader_set_colour

    	Set a colour value in a shader
    	e.g. shader_set_colour shader "c" r g b a

### shader_set_texture

    	Set a texture value in a shader
    	e.g. shader_set_texture shader "tex" my_img

### shader_set_matrix

    	Set a matrix uniform value in a shader
    	Matrices here are 2d vectors of numbers
    	e.g. shader_set_matrix shader "mymat" m

### shader_set_matrix_array

    	Set an array of matrices in a shader
    	e.g. shader_set_matrix_array shader "mats" my_vec_of_mats

### shader_set_float_vector

    	Set a float vector uniform in a shader
    	e.g. shader_set_float_vector shader "myvec" vec

### shader_destroy

    	Free a shader
    	e.g. shader_destroy shader

## 3D Functions

### set_2d

    	Revert to the default 2d projection
    	e.g. set_2d

### set_3d

    	Enable the default 3d projection
    	e.g. set_3d

### (model_load)

    	Load a model with an optional armature an animations from .x file
    	Each model has its own transform set with model_* transform functions
    	e.g. = model (model_load "filename.x" ^ lffs)
    	Returns -1 on fail

### (model_clone)

    	Clone a model
    	This is a clone of an existing model with its own transform. Any
    	animations will repeat over clones
    	e.g. = clone (model_clone model)

### model_draw

    	Draw a model with its transforms applied
    	e.g. model_draw model r_tint g_tint b_tint a_tint

### model_identity

    	Set model transform to identity
    	e.g. model_identity model

### model_scale

    	Alter the scale of a model
    	e.g. model_scale model add_sx add_sy add_sz

### model_rotate

    	Rotate a model.
    	e.g. model_rotate model angle axisx axisy axisz

### model_translate

    	Translate (move) a model
    	e.g. model_translate model add_x add_y add_z

### model_set_animation

    	Set the animation to the one named. You can optionally pass a BooBoo
    	function that takes a number as parameter (model id) that will be
    	called when the animation finishes.
    	e.g. model_set_animation model "attack" done_attack

### model_stop

    	Stop a models animation
    	e.g. model_stop model

### model_reset

    	Reset a models animation to the beginning
    	e.g. model_reset model

### (model_size)

    	Get the dimensions of a model
    	e.g. explode (model_size model) szx szy szz

### model_destroy

    	Free a model
    	e.g. model_destroy model

### identity_3d

    	Set the modelview matrix to the identity matrix
    	e.g. identity_3d

### scale_3d

    	Scale the modelview matrix
    	e.g. scale_3d sx sy sz

### rotate_3d

    	Rotate the modelview matrix
    	e.g. rotate_3d rx ry rz

### translate_3d

    	Translate the modelview matrix
    	e.g. translate_3d x y z

### (billboard_create)

    	Create a billboard
    	e.g. = result (billboard_create image x y z w h)
    	Returns -1 on fail

### (billboard_from_sprite)

    	Create a billboard backed by a sprite
    	unit is the number of pixels that spans 1 3D unit
    	e.g. = result (billboard_from_sprite sprite x y z w h unit)
    	Returns -1 on fail

### billboard_draw

    	Draw a tinted billboard
    	e.g. billboard_draw billboard r g b a

### billboard_translate

    	Move a billboard
    	e.g. billboard_translate b x y z

### billboard_scale

    	Scale a billboard
    	e.g. billboard_scale b sx sy

### billboard_destroy

    	Free a billboard
    	e.g. billboard_destroy b

## GUI Functions

Widgets are generic rectangles with a userdata attached to them to supply their properties.

Two callbacks get called for every GUI event/drawing operation:

    gui_event widget_id type a b c d x y w h focussed ~userdata

    gui_draw widget_id x y w h focussed ~userdata

(note the ~, which is quite handy if you want to store state info in userdata)

type, a, b, c and d are the same as for the global 'event' callback, described in Events. x, y, w and h are the calculated position and size of the widget in pixels.

### (widget_create)

    	Create a widget
    	Sizes less than equal to 1 are taken as a percentage
    	of the container size
    	e.g. = result (widget_create w h userdata)
    	Returns -1 on fail

### widget_set_parent

    	Widget hierarchy is important. You want to have one root widget
    	and add everything (perhaps in multiple containers) to it
    	e.g. widget_set_parent child parent

### widget_set_float_left

    	Similar to float left in CSS
    	e.g. widget_set_float_left widget onoff

### widget_set_float_right

    	Similar to float right in CSS
    	e.g. widget_set_float_right widget onoff

### widget_set_float_bottom

    	Similar to float bottom in CSS
    	e.g. widget_set_float_bottom widget onoff

### widget_set_centre_x

    	Centre a widget horizontally
    	e.g. widget_set_centre_x widget onoff

### widget_set_centre_y

    	Centre a widget vertically
    	e.g. widget_set_centre_y widget onoff

### widget_set_clear_float_x

    	Tell a widget to clear past widgets floating horizontally
    	e.g. widget_set_clear_float_x widget onoff

### widget_set_clear_float_y

    	Tell a widget to clear past widgets floating vertically
    	e.g. widget_set_clear_float_y widget onoff

### widget_set_break_line

    	Start a new row for this widget
    	e.g. widget_set_break_line widget onoff

### widget_set_accepts_focus

    	Allow a widget to accept the input focus or not
    	e.g. widget_set_accepts_focus widget onoff

### widget_set_padding_left

    	Set left padding
    	e.g. widget_set_padding_left widget px

### widget_set_padding_right

    	Set right padding
    	e.g. widget_set_padding_right widget px

### widget_set_padding_top

    	Set top padding
    	e.g. widget_set_padding_top widget px

### widget_set_padding_bottom

    	Set bottom padding
    	e.g. widget_set_padding_bottom widget px

### (widget_get_padding_left)

    	Get left padding of a widget
    	e.g. = pad (widget_get_padding_left widget)

### (widget_get_padding_right)

    	Get right padding of a widget
    	e.g. = pad (widget_get_padding_right widget)

### (widget_get_padding_top)

    	Get top padding of a widget
    	e.g. = pad (widget_get_padding_top widget)

### (widget_get_padding_bottom)

    	Get bottom padding of a widget
    	e.g. = pad (widget_get_padding_bottom widget)

### widget_set_left_widget

    	Hint at the widget to the left of this one for focus changes
    	with keyboard/gamepad
    	This isn't usually necessary if a widget can be found in-line
    	in the direction of the focus change
    	e.g. widget_set_left_widget widget left_widget

### widget_set_right_widget

    	Hint at the widget to the right of this one for focus changes
    	with keyboard/gamepad
    	This isn't usually necessary if a widget can be found in-line
    	in the direction of the focus change
    	e.g. widget_set_right_widget widget right_widget

### widget_set_up_widget

    	Hint at the widget to the up of this one for focus changes
    	with keyboard/gamepad
    	This isn't usually necessary if a widget can be found in-line
    	in the direction of the focus change
    	e.g. widget_set_up_widget widget up_widget

### widget_set_down_widget

    	Hint at the widget to the down of this one for focus changes
    	with keyboard/gamepad
    	This isn't usually necessary if a widget can be found in-line
    	in the direction of the focus change
    	e.g. widget_set_down_widget widget down_widget

### gui_start

    	Start executing a gui
    	e.g. gui_start root_widget

### gui_exit

    	Close the toplevel GUI and destroy widgets
    	e.g. gui_exit

### gui_set_focus

    	Set focus to a widget
    	e.g. gui_set_focus my_button

### gui_set_transition_types

    	Set the in/out transition types for GUI start/end
    	transitions. See constants.
    	e.g. gui_set_transition_types TRANSITION_ENLARGE TRANSITION_SHRINK
    	; this is the default

## Collision Detection Functions

### (cd_model_point)

    	Check if a point is inside a model
    	The model must be closed for this to work properly
    	e.g. = onoff (cd_model_point model x y z)

### (cd_model_line_segment)

    	Check if a line segment intersects or is contained in a model
    	If result is TRUE, outx/outy/outz will have the intersection point
    	e.g. explode (cd_model_line_segment model x y z x2 y2 z2) result outx outy outz

### (cd_sphere_sphere)

    	Check if two sphere intersect
    	e.g. = onoff (cd_sphere_sphere x y z r x2 y2 z2 r2)

## Audio Functions

### (mml_create)

    	create an MML from a string. See the Music documentation section.
    	e.g. = dest (mml_create "A @TYPE3 abcdefg")
    	; this plays a b c d e f g 16th notes with a sine wave generator
    	Returns -1 on fail

### (mml_load)

    	load an MML from file
    	e.g. = dest (mml_load "sfx/blast.mml" ^ lffs)
    	Returns -1 on fail

### mml_play

    	play a sound
    	e.g. mml_play blast ^ volume loop

### mml_stop

    	stop a looping sound
    	e.g. mml_stop blast

### (sample_load)

    	load a sample
    	e.g. = s (sample_load "example.wav" ^ lffs)
    	Returns -1 on fail

### sample_play

    	play a sample
    	e.g. sample_play s ^ volume loop

### sample_stop

    	Stop a looping sample
    	e.g. sample_stop s

### mml_destroy

    	Free an MML
    	e.g. mml_destroy mml

### sample_destroy

    	Destroy a sample
    	e.g. sample_destroy sample

## Input Functions

### (joy_count)

    	get number of connected joysticks
    	e.g. = num_joysticks (joy_count)

### rumble

    	Rumble all or one joystick
    	e.g. rumble duration_in_ms ^ index

### (joy_get_button)

    	Get the state of a joystick button listed in constants
    	Result is 0 or 1
    	e.g. = result (joy_get_button joy_num JOY_A)

### (joy_get_axis)

    	Get the state of a joystick axis listed in constants
    	Results or -1 to 1 except for triggers which are 0 to 1
    	e.g. = result (joy_get_axis joy_num JOY_LEFTX)

### (mouse_get_position)

    	Get the mouse position scaled relative to the projection
    	e.g. explode (mouse_get_position) mx my

### (mouse_get_buttons)

    	Get the mouse button state
    	Wheel will be 1 (forward) 0 (not moved) or -1 (backward)
    	e.g. explode (mouse_get_buttons) left middle right wheel

### (mouse_get_delta)

    	Get the mouse delta movement since last call
    	The first time this is called, the values will be set to 0 and
    	return 0
    	e.g. explode (mouse_get_delta) dx dy

### mouse_set_relative

    	Keep the mouse in the window and use relative coordinates
    	e.g. mouse_set_relative bonoff

### (key_get)

    	Read if a key is pressed or not.
    	See constants for key names
    	e.g. = dest (key_get KEY_SPACE)

## JSON Functions

### (json_load)

    	Load a JSON file
    	e.g. = j (json_load "file.json" ^ lffs)
    	Returns -1 on fail

### (json_create)

    	Create a blank JSON file. Takes a boolean that creates the root
    	as either an array (TRUE) or hash (FALSE)
    	e.g. = j (json_create FALSE)
    	Returns -1 on fail

### (json_exists)

    	Check if a key exists in a JSON object
    	You can dig down into the file by separating keys with ">"
    	"[0]" "[1]" etc can be used to access arrays.
    	e.g. = yesno (json_exists json "foo>bar>baz")

### (json_typeof)

    	Return a string representation of JSON key type
    	e.g. = val (json_typeof json "foo>bar>baz"

### (json_size)

    	Return the number of children of a JSON key
    	e.g. = n (json_size json "foo>bar>baz"

### (json_get_string)

    	Read a string from JSON
    	You can dig down into the file by separating keys with ">"
    	"[0]" "[1]" etc can be used to access arrays.
    	e.g. = s (json_get_string json "settings>profile>name")

### (json_get_number)

    	Read a number from JSON
    	You can dig down into the file by separating keys with ">"
    	"[0]" "[1]" etc can be used to access arrays.
    	e.g. = n (json_get_number json "settings>mouse>sensitivity")

### (json_get_bool)

    	Read a boolean from JSON
    	You can dig down into the file by separating keys with ">"
    	"[0]" "[1]" etc can be used to access arrays.
    	e.g. = n (json_get_boolean json "settings>gfx>crt_filter")

### json_set_string

    	Set a string in a JSON object
    	You can dig down into the file by separating keys with ">"
    	"[0]" "[1]" etc can be used to access arrays.
    	e.g. json_set_string json "foo>bar>baz" "TURNIPS"

### json_set_number

    	Set a number in a JSON object
    	You can dig down into the file by separating keys with ">"
    	"[0]" "[1]" etc can be used to access arrays.
    	e.g. json_set_number json "foo>bar>baz" 762.4

### json_set_bool

    	Set a boolean in a JSON object
    	You can dig down into the file by separating keys with ">"
    	"[0]" "[1]" etc can be used to access arrays.
    	e.g. json_set_bool json "foo>bar>baz" TRUE

### json_add_array

    	Add an array element to a json object.
    	You can dig down into the file by separating keys with ">"
    	"[0]" "[1]" etc can be used to access arrays.
    	e.g. json_add_array json "foo>bar>baz"

### json_add_hash

    	Add a hash element to a json object.
    	You can dig down into the file by separating keys with ">"
    	"[0]" "[1]" etc can be used to access arrays.
    	e.g. json_add_array json "foo>bar>baz"

### json_remove

    	Remove a child from JSON tree
    	You can dig down into the file by separating keys with ">"
    	"[0]" "[1]" etc can be used to access arrays.
    	e.g. json_remove json "foo>bar>baz"

### (json_save)

    	Save a json object to json file
    	e.g. = succeeded (json_save json "foo.json")

### json_destroy

    	Free a JSON object
    	e.g. json_destroy json

## Constants

The following keyboard constants are used with key_get:

- KEY_UNKNOWN
- KEY_RETURN
- KEY_ESCAPE
- KEY_BACKSPACE
- KEY_TAB
- KEY_SPACE
- KEY_EXCLAIM
- KEY_DBLAPOSTROPHE
- KEY_HASH
- KEY_DOLLAR
- KEY_PERCENT
- KEY_AMPERSAND
- KEY_APOSTROPHE
- KEY_LEFTPAREN
- KEY_RIGHTPAREN
- KEY_ASTERISK
- KEY_PLUS
- KEY_COMMA
- KEY_MINUS
- KEY_PERIOD
- KEY_SLASH
- KEY_0
- KEY_1
- KEY_2
- KEY_3
- KEY_4
- KEY_5
- KEY_6
- KEY_7
- KEY_8
- KEY_9
- KEY_COLON
- KEY_SEMICOLON
- KEY_LESS
- KEY_EQUALS
- KEY_GREATER
- KEY_QUESTION
- KEY_AT
- KEY_LEFTBRACKET
- KEY_BACKSLASH
- KEY_RIGHTBRACKET
- KEY_CARET
- KEY_UNDERSCORE
- KEY_GRAVE
- KEY_A
- KEY_B
- KEY_C
- KEY_D
- KEY_E
- KEY_F
- KEY_G
- KEY_H
- KEY_I
- KEY_J
- KEY_K
- KEY_L
- KEY_M
- KEY_N
- KEY_O
- KEY_P
- KEY_Q
- KEY_R
- KEY_S
- KEY_T
- KEY_U
- KEY_V
- KEY_W
- KEY_X
- KEY_Y
- KEY_Z
- KEY_LEFTBRACE
- KEY_PIPE
- KEY_RIGHTBRACE
- KEY_TILDE
- KEY_DELETE
- KEY_PLUSMINUS
- KEY_CAPSLOCK
- KEY_F1
- KEY_F2
- KEY_F3
- KEY_F4
- KEY_F5
- KEY_F6
- KEY_F7
- KEY_F8
- KEY_F9
- KEY_F10
- KEY_F11
- KEY_F12
- KEY_PRINTSCREEN
- KEY_SCROLLLOCK
- KEY_PAUSE
- KEY_INSERT
- KEY_HOME
- KEY_PAGEUP
- KEY_END
- KEY_PAGEDOWN
- KEY_RIGHT
- KEY_LEFT
- KEY_DOWN
- KEY_UP
- KEY_NUMLOCKCLEAR
- KEY_KP_DIVIDE
- KEY_KP_MULTIPLY
- KEY_KP_MINUS
- KEY_KP_PLUS
- KEY_KP_ENTER
- KEY_KP_1
- KEY_KP_2
- KEY_KP_3
- KEY_KP_4
- KEY_KP_5
- KEY_KP_6
- KEY_KP_7
- KEY_KP_8
- KEY_KP_9
- KEY_KP_0
- KEY_KP_PERIOD
- KEY_APPLICATION
- KEY_POWER
- KEY_KP_EQUALS
- KEY_F13
- KEY_F14
- KEY_F15
- KEY_F16
- KEY_F17
- KEY_F18
- KEY_F19
- KEY_F20
- KEY_F21
- KEY_F22
- KEY_F23
- KEY_F24
- KEY_EXECUTE
- KEY_HELP
- KEY_MENU
- KEY_SELECT
- KEY_STOP
- KEY_AGAIN
- KEY_UNDO
- KEY_CUT
- KEY_COPY
- KEY_PASTE
- KEY_FIND
- KEY_MUTE
- KEY_VOLUMEUP
- KEY_VOLUMEDOWN
- KEY_KP_COMMA
- KEY_KP_EQUALSAS400
- KEY_ALTERASE
- KEY_SYSREQ
- KEY_CANCEL
- KEY_CLEAR
- KEY_PRIOR
- KEY_RETURN2
- KEY_SEPARATOR
- KEY_OUT
- KEY_OPER
- KEY_CLEARAGAIN
- KEY_CRSEL
- KEY_EXSEL
- KEY_KP_00
- KEY_KP_000
- KEY_THOUSANDSSEPARATOR
- KEY_DECIMALSEPARATOR
- KEY_CURRENCYUNIT
- KEY_CURRENCYSUBUNIT
- KEY_KP_LEFTPAREN
- KEY_KP_RIGHTPAREN
- KEY_KP_LEFTBRACE
- KEY_KP_RIGHTBRACE
- KEY_KP_TAB
- KEY_KP_BACKSPACE
- KEY_KP_A
- KEY_KP_B
- KEY_KP_C
- KEY_KP_D
- KEY_KP_E
- KEY_KP_F
- KEY_KP_XOR
- KEY_KP_POWER
- KEY_KP_PERCENT
- KEY_KP_LESS
- KEY_KP_GREATER
- KEY_KP_AMPERSAND
- KEY_KP_DBLAMPERSAND
- KEY_KP_VERTICALBAR
- KEY_KP_DBLVERTICALBAR
- KEY_KP_COLON
- KEY_KP_HASH
- KEY_KP_SPACE
- KEY_KP_AT
- KEY_KP_EXCLAM
- KEY_KP_MEMSTORE
- KEY_KP_MEMRECALL
- KEY_KP_MEMCLEAR
- KEY_KP_MEMADD
- KEY_KP_MEMSUBTRACT
- KEY_KP_MEMMULTIPLY
- KEY_KP_MEMDIVIDE
- KEY_KP_PLUSMINUS
- KEY_KP_CLEAR
- KEY_KP_CLEARENTRY
- KEY_KP_BINARY
- KEY_KP_OCTAL
- KEY_KP_DECIMAL
- KEY_KP_HEXADECIMAL
- KEY_LCTRL
- KEY_LSHIFT
- KEY_LALT
- KEY_LGUI
- KEY_RCTRL
- KEY_RSHIFT
- KEY_RALT
- KEY_RGUI
- KEY_MODE
- KEY_SLEEP
- KEY_WAKE
- KEY_CHANNEL_INCREMENT
- KEY_CHANNEL_DECREMENT
- KEY_MEDIA_PLAY
- KEY_MEDIA_PAUSE
- KEY_MEDIA_RECORD
- KEY_MEDIA_FAST_FORWARD
- KEY_MEDIA_REWIND
- KEY_MEDIA_NEXT_TRACK
- KEY_MEDIA_PREVIOUS_TRACK
- KEY_MEDIA_STOP
- KEY_MEDIA_EJECT
- KEY_MEDIA_PLAY_PAUSE
- KEY_MEDIA_SELECT
- KEY_AC_NEW
- KEY_AC_OPEN
- KEY_AC_CLOSE
- KEY_AC_EXIT
- KEY_AC_SAVE
- KEY_AC_PRINT
- KEY_AC_PROPERTIES
- KEY_AC_SEARCH
- KEY_AC_HOME
- KEY_AC_BACK
- KEY_AC_FORWARD
- KEY_AC_STOP
- KEY_AC_REFRESH
- KEY_AC_BOOKMARKS
- KEY_SOFTLEFT
- KEY_SOFTRIGHT
- KEY_CALL
- KEY_ENDCALL
- KEY_LEFT_TAB
- KEY_LEVEL5_SHIFT
- KEY_MULTI_KEY_COMPOSE
- KEY_LMETA
- KEY_RMETA
- KEY_LHYPER
- KEY_RHYPER

Event types:

- EVENT_KEY_DOWN
- EVENT_KEY_UP
- EVENT_JOY_DOWN
- EVENT_JOY_UP
- EVENT_JOY_AXIS
- EVENT_MOUSE_DOWN
- EVENT_MOUSE_UP
- EVENT_MOUSE_AXIS
- EVENT_MOUSE_WHEEL

Joystick buttons:

- JOY_A
- JOY_B
- JOY_X
- JOY_Y
- JOY_BACK
- JOY_GUIDE
- JOY_START
- JOY_LS
- JOY_RS
- JOY_LB
- JOY_RB
- JOY_U
- JOY_D
- JOY_L
- JOY_R

Joystick axes:

- JOY_LEFTX
- JOY_LEFTY
- JOY_RIGHTX
- JOY_RIGHTY
- JOY_TRIGGERLEFT
- JOY_TRIGGERRIGHT

GUI constants:

- TRANSITION_NONE
- TRANSITION_ENLARGE
- TRANSITION_SHRINK
- TRANSITION_SLIDE
- TRANSITION_SLIDE_VERTICAL
- TRANSITION_FADE

For drawing custom letterbox:

- LETTERBOX_TOP
- LETTERBOX_BOTTOM
- LETTERBOX_LEFT
- LETTERBOX_RIGHT

For set_blend_mode:

- BLEND_ZERO
- BLEND_ONE
- BLEND_SRCCOLOR
- BLEND_INVSRCCOLOR
- BLEND_SRCALPHA
- BLEND_INVSRCALPHA

Compare functions for depth/stencil buffers

- COMPARE_NEVER
- COMPARE_LESS
- COMPARE_EQUAL
- COMPARE_LESSEQUAL
- COMPARE_GREATER
- COMPARE_NOTEQUAL
- COMPARE_GREATEREQUAL
- COMPARE_ALWAYS

Stencil operations

- STENCILOP_KEEP
- STENCILOP_ZERO
- STENCILOP_REPLACE
- STENCILOP_INCRSAT
- STENCILOP_DECRSAT
- STENCILOP_INVERT
- STENCILOP_INCR
- STENCILOP_DECR

Triangle faces

- NO_FACE
- FRONT_FACE
- BACK_FACE

Front faces

- FACE_CW
- FACE_CCW

## Events

You can receive events so you're sure you don't miss anything. Mouse and joystick button down events automatically generate repeat events, which are marked specially so you can know the difference.

To receive events, define a function called event with 5 arguments:

    function event type a b c d { ... }

type will be one of the EVENT_* constants listed in the Constants section. The parameters depend on the event type. Unused parameters are undefined for an event that doesn't supply them. The parameters for each event type are:

### EVENT_KEY_DOWN

    	a - the key constant
    	b - TRUE if this is a repeat event

### EVENT_KEY_UP

    	a - the key constant

### EVENT_JOY_DOWN

    	a - the joystick index (0=first, 1=second, ...)
    	b - the button constant in constants
    	c - TRUE if it is a repeat event

### EVENT_JOY_UP

    	a - the joystick index (0=first, 1=second, ...)
    	b - the joystick button constant

### EVENT_JOY_AXIS

    	a - the joystick index (0=first, 1=second, ...)
    	b - the axis index
    	c - the value from -1 to 1

### EVENT_MOUSE_DOWN

    	a - the button
    	b - TRUE if it is a repeat event
    	c - mouse x
    	d - mouse y

### EVENT_MOUSE_UP

    	a - the button

### EVENT_MOUSE_AXIS

    	a - the x window coordinate
    	b - the y window coordinate
    	c - the delta x movement
    	d - the delta y movement

### EVENT_MOUSE_WHEEL

    	a - the horizontal wheel movement
    	b - the vertical wheel movement