<!-- Generated by bin2h, DO NOT edit -->
# Memory Map

## Misc

All values are little endian, so the smaller digit is stored on the smaller address.

| Offset | Size       | Description                                                        |
|--------|-----------:|--------------------------------------------------------------------|
|  00000 |          1 | MEG-4 firmware version major                                       |
|  00001 |          1 | MEG-4 firmware version minor                                       |
|  00002 |          1 | MEG-4 firmware version bugfix                                      |
|  00003 |          1 | performance counter, last frame's unspent time in 1/1000th secs    |
|  00004 |          4 | number of 1/1000th second ticks since power on                     |
|  00008 |          8 | UTC unix timestamp                                                 |
|  00010 |          2 | current locale                                                     |

The performance counter shows the time unspent when the last frame was generated. If this is zero or negative, then it means
how much your loop() function has overstepped its available timeframe.

## Pointer

| Offset | Size       | Description                                                        |
|--------|-----------:|--------------------------------------------------------------------|
|  00012 |          2 | pointer buttons state (see [getbtn] and [getclk])                  |
|  00014 |          2 | pointer sprite index                                               |
|  00016 |          2 | pointer X coordinate                                               |
|  00018 |          2 | pointer Y coordinate                                               |

The pointer buttons are as follows:

| Define  | Bitmask   | Description                                                        |
|---------|----------:|--------------------------------------------------------------------|
| `BTN_L` |         1 | Left mouse button                                                  |
| `BTN_M` |         2 | Middle mouse button                                                |
| `BTN_R` |         4 | Right mouse button                                                 |
| `SCR_U` |         8 | Scroll up                                                          |
| `SCR_D` |        16 | Scroll down                                                        |
| `SCR_L` |        32 | Scroll left                                                        |
| `SCR_R` |        64 | Scroll right                                                       |

The upper bits of the pointer sprite index are used for hotspots: bit 13-15 hotspot Y, bit 10-12 hotspot X, bit 0-9 sprite.
There are some predefined built-in cursors:

| Define       | Value     | Description                                                   |
|--------------|----------:|---------------------------------------------------------------|
| `PTR_NORM`   |      03fb | Normal (arrow) pointer                                        |
| `PTR_TEXT`   |      03fc | Text pointer                                                  |
| `PTR_HAND`   |      0bfd | Link pointer                                                  |
| `PTR_ERR`    |      93fe | Error pointer                                                 |
| `PTR_NONE`   |      ffff | The pointer is hidden                                         |

## Keyboard

| Offset | Size       | Description                                                        |
|--------|-----------:|--------------------------------------------------------------------|
|  0001A |          1 | keyboard queue tail                                                |
|  0001B |          1 | keyboard queue head                                                |
|  0001C |         64 | keyboard queue, 16 elements, each 4 bytes (see [popkey])           |
|  0005C |         18 | keyboard keys pressed state by scancodes (see [getkey])            |

The keys popped from the queue are represented in UTF-8. Some invalid UTF-8 sequences represent special (non-printable)
keys, for example:

| Keycode | Description                                     |
|---------|-------------------------------------------------|
| `\x8`   | The character 8, <kbd>←Backspace</kbd> key      |
| `\x9`   | The character 9, <kbd>Tab</kbd> key             |
| `\n`    | The character 10, <kbd>⏎Enter</kbd> key         |
| `\x1b`  | The character 27, <kbd>Esc</kbd> key            |
| `Del`   | The <kbd>Del</kbd> key                          |
| `Up`    | The cursor arrow <kbd>▴</kbd> key               |
| `Down`  | The cursor arrow <kbd>▾</kbd> key               |
| `Left`  | The cursor arrow <kbd>◂</kbd> key               |
| `Rght`  | The cursor arrow <kbd>▸</kbd> key               |
| `Cut`   | The Cut key (or <kbd>Ctrl</kbd>+<kbd>X</kbd>)   |
| `Cpy`   | The Copy key (or <kbd>Ctrl</kbd>+<kbd>C</kbd>)  |
| `Pst`   | The Paste key (or <kbd>Ctrl</kbd>+<kbd>V</kbd>) |

The scancodes are as follows:

| ScanCode | Address | Bitmask | Define            |
|---------:|---------|--------:|-------------------|
|        0 |   0005C |       1 | `KEY_CHEAT`       |
|        1 |   0005C |       2 | `KEY_F1`          |
|        2 |   0005C |       4 | `KEY_F2`          |
|        3 |   0005C |       8 | `KEY_F3`          |
|        4 |   0005C |      16 | `KEY_F4`          |
|        5 |   0005C |      32 | `KEY_F5`          |
|        6 |   0005C |      64 | `KEY_F6`          |
|        7 |   0005C |     128 | `KEY_F7`          |
|        8 |   0005D |       1 | `KEY_F8`          |
|        9 |   0005D |       2 | `KEY_F9`          |
|       10 |   0005D |       4 | `KEY_F10`         |
|       11 |   0005D |       8 | `KEY_F11`         |
|       12 |   0005D |      16 | `KEY_F12`         |
|       13 |   0005D |      32 | `KEY_PRSCR`       |
|       14 |   0005D |      64 | `KEY_SCRLOCK`     |
|       15 |   0005D |     128 | `KEY_PAUSE`       |
|       16 |   0005E |       1 | `KEY_BACKQUOTE`   |
|       17 |   0005E |       2 | `KEY_1`           |
|       18 |   0005E |       4 | `KEY_2`           |
|       19 |   0005E |       8 | `KEY_3`           |
|       20 |   0005E |      16 | `KEY_4`           |
|       21 |   0005E |      32 | `KEY_5`           |
|       22 |   0005E |      64 | `KEY_6`           |
|       23 |   0005E |     128 | `KEY_7`           |
|       24 |   0005F |       1 | `KEY_8`           |
|       25 |   0005F |       2 | `KEY_9`           |
|       26 |   0005F |       4 | `KEY_0`           |
|       27 |   0005F |       8 | `KEY_MINUS`       |
|       28 |   0005F |      16 | `KEY_EQUAL`       |
|       29 |   0005F |      32 | `KEY_BACKSPACE`   |
|       30 |   0005F |      64 | `KEY_TAB`         |
|       31 |   0005F |     128 | `KEY_Q`           |
|       32 |   00060 |       1 | `KEY_W`           |
|       33 |   00060 |       2 | `KEY_E`           |
|       34 |   00060 |       4 | `KEY_R`           |
|       35 |   00060 |       8 | `KEY_T`           |
|       36 |   00060 |      16 | `KEY_Y`           |
|       37 |   00060 |      32 | `KEY_U`           |
|       38 |   00060 |      64 | `KEY_I`           |
|       39 |   00060 |     128 | `KEY_O`           |
|       40 |   00061 |       1 | `KEY_P`           |
|       41 |   00061 |       2 | `KEY_LBRACKET`    |
|       42 |   00061 |       4 | `KEY_RBRACKET`    |
|       43 |   00061 |       8 | `KEY_ENTER`       |
|       44 |   00061 |      16 | `KEY_CAPSLOCK`    |
|       45 |   00061 |      32 | `KEY_A`           |
|       46 |   00061 |      64 | `KEY_S`           |
|       47 |   00061 |     128 | `KEY_D`           |
|       48 |   00062 |       1 | `KEY_F`           |
|       49 |   00062 |       2 | `KEY_G`           |
|       50 |   00062 |       4 | `KEY_H`           |
|       51 |   00062 |       8 | `KEY_J`           |
|       52 |   00062 |      16 | `KEY_K`           |
|       53 |   00062 |      32 | `KEY_L`           |
|       54 |   00062 |      64 | `KEY_SEMICOLON`   |
|       55 |   00062 |     128 | `KEY_APOSTROPHE`  |
|       56 |   00063 |       1 | `KEY_BACKSLASH`   |
|       57 |   00063 |       2 | `KEY_LSHIFT`      |
|       58 |   00063 |       4 | `KEY_LESS`        |
|       59 |   00063 |       8 | `KEY_Z`           |
|       60 |   00063 |      16 | `KEY_X`           |
|       61 |   00063 |      32 | `KEY_C`           |
|       62 |   00063 |      64 | `KEY_V`           |
|       63 |   00063 |     128 | `KEY_B`           |
|       64 |   00064 |       1 | `KEY_N`           |
|       65 |   00064 |       2 | `KEY_M`           |
|       66 |   00064 |       4 | `KEY_COMMA`       |
|       67 |   00064 |       8 | `KEY_PERIOD`      |
|       68 |   00064 |      16 | `KEY_SLASH`       |
|       69 |   00064 |      32 | `KEY_RSHIFT`      |
|       70 |   00064 |      64 | `KEY_LCTRL`       |
|       71 |   00064 |     128 | `KEY_LSUPER`      |
|       72 |   00065 |       1 | `KEY_LALT`        |
|       73 |   00065 |       2 | `KEY_SPACE`       |
|       74 |   00065 |       4 | `KEY_RALT`        |
|       75 |   00065 |       8 | `KEY_RSUPER`      |
|       76 |   00065 |      16 | `KEY_MENU`        |
|       77 |   00065 |      32 | `KEY_RCTRL`       |
|       78 |   00065 |      64 | `KEY_INS`         |
|       79 |   00065 |     128 | `KEY_HOME`        |
|       80 |   00066 |       1 | `KEY_PGUP`        |
|       81 |   00066 |       2 | `KEY_DEL`         |
|       82 |   00066 |       4 | `KEY_END`         |
|       83 |   00066 |       8 | `KEY_PGDN`        |
|       84 |   00066 |      16 | `KEY_UP`          |
|       85 |   00066 |      32 | `KEY_LEFT`        |
|       86 |   00066 |      64 | `KEY_DOWN`        |
|       87 |   00066 |     128 | `KEY_RIGHT`       |
|       88 |   00067 |       1 | `KEY_NUMLOCK`     |
|       89 |   00067 |       2 | `KEY_KP_DIV`      |
|       90 |   00067 |       4 | `KEY_KP_MUL`      |
|       91 |   00067 |       8 | `KEY_KP_SUB`      |
|       92 |   00067 |      16 | `KEY_KP_7`        |
|       93 |   00067 |      32 | `KEY_KP_8`        |
|       94 |   00067 |      64 | `KEY_KP_9`        |
|       95 |   00067 |     128 | `KEY_KP_ADD`      |
|       96 |   00068 |       1 | `KEY_KP_4`        |
|       97 |   00068 |       2 | `KEY_KP_5`        |
|       98 |   00068 |       4 | `KEY_KP_6`        |
|       99 |   00068 |       8 | `KEY_KP_1`        |
|      100 |   00068 |      16 | `KEY_KP_2`        |
|      101 |   00068 |      32 | `KEY_KP_3`        |
|      102 |   00068 |      64 | `KEY_KP_ENTER`    |
|      103 |   00068 |     128 | `KEY_KP_0`        |
|      104 |   00069 |       1 | `KEY_KP_DEC`      |
|      105 |   00069 |       2 | `KEY_INT1`        |
|      106 |   00069 |       4 | `KEY_INT2`        |
|      107 |   00069 |       8 | `KEY_INT3`        |
|      108 |   00069 |      16 | `KEY_INT4`        |
|      109 |   00069 |      32 | `KEY_INT5`        |
|      110 |   00069 |      64 | `KEY_INT6`        |
|      111 |   00069 |     128 | `KEY_INT7`        |
|      112 |   0006A |       1 | `KEY_INT8`        |
|      113 |   0006A |       2 | `KEY_LNG1`        |
|      114 |   0006A |       4 | `KEY_LNG2`        |
|      115 |   0006A |       8 | `KEY_LNG3`        |
|      116 |   0006A |      16 | `KEY_LNG4`        |
|      117 |   0006A |      32 | `KEY_LNG5`        |
|      118 |   0006A |      64 | `KEY_LNG6`        |
|      119 |   0006A |     128 | `KEY_LNG7`        |
|      120 |   0006B |       1 | `KEY_LNG8`        |
|      121 |   0006B |       2 | `KEY_APP`         |
|      122 |   0006B |       4 | `KEY_POWER`       |
|      123 |   0006B |       8 | `KEY_KP_EQUAL`    |
|      124 |   0006B |      16 | `KEY_EXEC`        |
|      125 |   0006B |      32 | `KEY_HELP`        |
|      126 |   0006B |      64 | `KEY_SELECT`      |
|      127 |   0006B |     128 | `KEY_STOP`        |
|      128 |   0006C |       1 | `KEY_AGAIN`       |
|      129 |   0006C |       2 | `KEY_UNDO`        |
|      130 |   0006C |       4 | `KEY_CUT`         |
|      131 |   0006C |       8 | `KEY_COPY`        |
|      132 |   0006C |      16 | `KEY_PASTE`       |
|      133 |   0006C |      32 | `KEY_FIND`        |
|      134 |   0006C |      64 | `KEY_MUTE`        |
|      135 |   0006C |     128 | `KEY_VOLUP`       |
|      136 |   0006D |       1 | `KEY_VOLDN`       |


## Gamepad

| Offset | Size       | Description                                                        |
|--------|-----------:|--------------------------------------------------------------------|
|  0006E |          2 | gamepad joystick threshold (defaults to 8000)                      |
|  00070 |          8 | primary gamepad - keyboard scancode mappings (see [keyboard])      |
|  00078 |          4 | 4 gamepads button pressed state (see [getpad])                     |

The gamepad buttons are as follows:

| Define  | Bitmask   | Description                                                        |
|---------|----------:|--------------------------------------------------------------------|
| `BTN_L` |         1 | The `◁` button or joystick left                                   |
| `BTN_U` |         2 | The `△` button or joystick up                                     |
| `BTN_R` |         4 | The `▷` button or joystick right                                  |
| `BTN_D` |         8 | The `▽` button or joystick down                                   |
| `BTN_A` |        16 | The `Ⓐ` button                                                     |
| `BTN_B` |        32 | The `Ⓑ` button                                                     |
| `BTN_X` |        64 | The `Ⓧ` button                                                     |
| `BTN_Y` |       128 | The `Ⓨ` button                                                     |

The `△△▽▽◁▷◁▷ⒷⒶ` sequence makes the `KEY_CHEAT` "key" pressed.

## Graphics Processing Unit

| Offset | Size       | Description                                                        |
|--------|-----------:|--------------------------------------------------------------------|
|  0007E |          1 | UNICODE code point upper bits for font glyph mapping               |
|  0007F |          1 | sprite bank selector for the map                                   |
|  00080 |       1024 | palette, 256 colors, each entry 4 bytes, RGBA                      |
|  00480 |          2 | x0, crop area X start in pixels (for all drawing functions)        |
|  00482 |          2 | x1, crop area X end in pixels                                      |
|  00484 |          2 | y0, crop area Y start in pixels                                    |
|  00486 |          2 | y1, crop area Y end in pixels                                      |
|  00488 |          2 | displayed vram X offset in pixels or 0xffff                        |
|  0048A |          2 | displayed vram Y offset in pixels or 0xffff                        |
|  0048C |          1 | turtle pen down flag (see [up], [down])                            |
|  0048D |          1 | turtle pen color, palette index 0 to 255 (see [color])             |
|  0048E |          2 | turtle direction in degrees, 0 to 359 (see [left], [right])        |
|  00490 |          2 | turtle X offset in pixels (see [move])                             |
|  00492 |          2 | turtle Y offset in pixels                                          |
|  00494 |          2 | maze walking speed in 1/128 tiles (see [maze])                     |
|  00496 |          2 | maze rotating speed in degrees (1 to 90)                           |
|  00498 |          1 | console foreground color, palette index 0 to 255 (see [printf])    |
|  00499 |          1 | console background color, palette index 0 to 255                   |
|  0049A |          2 | console X offset in pixels                                         |
|  0049C |          2 | console Y offset in pixels                                         |
|  0049E |          2 | camera X offset in [3D space] (see [tri3d], [tritx], [mesh])       |
|  004A0 |          2 | camera Y offset                                                    |
|  004A2 |          2 | camera Z offset                                                    |
|  004A4 |          2 | camera direction, pitch (0 up, 90 forward)                         |
|  004A6 |          2 | camera direction, yaw (0 left, 90 forward)                         |
|  004A8 |          1 | camera field of view in angles (45, negative gives orthographic)   |
|  004AA |          2 | light source position X offset (see [tri3d], [tritx], [mesh])      |
|  004AC |          2 | light source position Y offset                                     |
|  004AE |          2 | light source position Z offset                                     |
|  00600 |      64000 | map, 320 x 200 sprite indices (see [map] and [maze])               |
|  10000 |      65536 | sprites, 256 x 256 palette indices, 1024 8 x 8 pixels (see [spr])  |
|  28000 |      32768 | window for 4096 font glyphs (see 0007E, [width] and [text])        |

## Digital Signal Processor

| Offset | Size       | Description                                                        |
|--------|-----------:|--------------------------------------------------------------------|
|  0007C |          1 | waveform bank selector (1 to 31)                                   |
|  0007D |          1 | music track bank selector (0 to 7)                                 |
|  004BA |          1 | current tempo (in ticks per row, read-only)                        |
|  004BB |          1 | current track being played (read-only)                             |
|  004BC |          2 | current row being played (read-only)                               |
|  004BE |          2 | number of total rows in current track (read-only)                  |
|  004C0 |         64 | 16 channel status registers, each 4 bytes (read-only)              |
|  00500 |        256 | 64 sound effects, each 4 bytes                                     |
|  20000 |      16384 | window for waveform samples (see 0007C)                            |
|  24000 |      16384 | window for music patterns (see 0007D)                              |

The DSP status registers are all read-only, and for each channel they look like:

| Offset | Size       | Description                                                        |
|--------|-----------:|--------------------------------------------------------------------|
|      0 |          2 | current position in the waveform being played                      |
|      2 |          1 | current waveform (1 to 31, 0 if the channel is silent)             |
|      3 |          1 | current volume (0 means channel is turned off)                     |

The first 4 channels are for the music, the rest for the sound effects.

Note that the waveform index 0 means "use the previous waveform", so index 0 cannot be used in the selector.
The format of every other waveform:

| Offset | Size       | Description                                                        |
|--------|-----------:|--------------------------------------------------------------------|
|      0 |          2 | number of samples                                                  |
|      2 |          2 | loop start                                                         |
|      4 |          2 | loop length                                                        |
|      6 |          1 | finetune value, -8 to 7                                            |
|      7 |          1 | volume, 0 to 64                                                    |
|      8 |      16376 | signed 8-bit mono samples                                          |

The format of the sound effects and the music tracks are the same, the only difference is, music tracks have 4 notes per row,
one for each channel, and there are 1024 rows; while for sound effects there's only one note and 64 rows.

| Offset | Size       | Description                                                        |
|--------|-----------:|--------------------------------------------------------------------|
|      0 |          1 | note number, see `NOTE_x` defines, 0 to 96                         |
|      1 |          1 | waveform index, 0 to 31                                            |
|      2 |          1 | effect type, 0 to 255 (see [note effects])                         |
|      3 |          1 | effect parameter                                                   |

The counting of notes goes as follows: 0 means no note set. Followed by 8 octaves, each with 12 notes, so 1 equals to C-0,
12 is B-0 (on the lowest octave), 13 is C-1 (one octave higher) and 14 is C#1 (C sharp, semitone higher). For example the
D note on the 4th octave would be 1 + 4\*12 + 2 = 51. The B-7 is 96, the highest note on the highest octave. You also have
built-in defines, for example C-1 is `NOTE_C_1` and C#1 is `NOTE_Cs1`, if you don't want to count then you can use these as well
in your program.

## Note Effects

For simplicity, MEG-4 uses the same codes as the Amiga MOD file (this way you'll see the same in the built-in editor as well
as in a third party music tracker), but it does not support all of them. As said earlier, these codes are represented by three
hex numbers, the first being the type `t`, and the last two the parameter, `xy` (or `xx`). The types `E1` to `ED` are all stored
in the type byte, although it looks like one of their nibble might belong to the parameter, but it's not.

| Effect | Code | Description                                                |
|--------|------|------------------------------------------------------------|
| ...    | 000  | No effect                                                  |
| Arp    | 0xy  | Arpeggio, play note, note+x semitone and note+y semitone   |
| Po/    | 1xx  | Portamento up, slide period by x up                        |
| Po\\   | 2xx  | Portamento down, slide period by x down                    |
| Ptn    | 3xx  | Tone portamento, slide period to period x                  |
| Vib    | 4xy  | Vibrato, oscillate the pitch by y semitones at x freq      |
| Ctv    | 5xy  | Continue Tone portamento + volume slide by x up or y down  |
| Cvv    | 6xy  | Continue Vibrato + volume slide by x up or by y down       |
| Trm    | 7xy  | Tremolo, oscillate the volume by y amplitude at x freq     |
| Ofs    | 9xx  | Set sample offset to x \* 256                              |
| Vls    | Axy  | Slide volume by x up or by y down                          |
| Jmp    | Bxx  | Position jump, set row to x \* 64                          |
| Vol    | Cxx  | Set volume to x                                            |
| Fp/    | E1x  | Fine portamento up, increase period by x                   |
| Fp\\   | E2x  | Fine portamento down, decrease period by x                 |
| Svw    | E4x  | Set vibrato waveform, 0 sine, 1 saw, 2 square, 3 noise     |
| Ftn    | E5x  | Set finetune, change tuning by x (-8 to 7)                 |
| Stw    | E7x  | Set tremolo waveform, 0 sine, 1 saw, 2 square, 3 noise     |
| Rtg    | E9x  | Retrigger note, trigger current sample every x ticks       |
| Fv/    | EAx  | Fine volume slide up, increase by x                        |
| Fv\\   | EBx  | Fine volume slide down, decrease by x                      |
| Cut    | ECx  | Cut note in x ticks                                        |
| Dly    | EDx  | Delay note in x ticks                                      |
| Tpr    | Fxx  | Set number of ticks per row to x (tick defalts to 6)       |

## User Memory

Memory addresses from 00000 to 2FFFF belong to the MMIO, everything above (starting from 30000 or `MEM_USER`) is freely usable
user memory.

| Offset | Size       | Description                                                        |
|--------|-----------:|--------------------------------------------------------------------|
|  30000 |          4 | (BASIC only) offset of DATA                                        |
|  30004 |          4 | (BASIC only) current READ counter                                  |
|  30008 |          4 | (BASIC only) maximum READ, number of DATA                          |

This is followed by the global variables that you have declared in your program, followed by the constants, like string literals.
In case of BASIC, then this is followed by the actual DATA records.

Memory addresses above the initialized data can be dynamically allocated and freed in your program via the [malloc] and [free] calls.

Lastly the stack, which is at the top (starting from C0000 or `MEM_LIMIT`) and growing *downwards*. Your program's local variables
(that you declared inside a function) go here. The size of the stack always changes depending on which function calls which other
function in your program.

If by any chance the top of the dynamically allocated data and the bottom of the stack would overlap, then MEG-4 throws an
"Out of memory" error.

## Format String

Some functions, [printf], [sprintf] and [trace] use a format string that may contain special characters to reference arguments
and to describe how to display them. These are:

| Code | Description                                                |
|------|------------------------------------------------------------|
| `%%` | The `%` character                                          |
| `%d` | Next parameter as a decimal number                         |
| `%u` | Next parameter as an unsigned decimal number               |
| `%x` | Next parameter as a hexadecimal number                     |
| `%o` | Next parameter as an octal number                          |
| `%b` | Next parameter as a binary number                          |
| `%f` | Next parameter as a floating point number                  |
| `%s` | Next parameter as a string                                 |
| `%c` | Next parameter as an UTF-8 character                       |
| `%p` | Next parameter as an address (pointer)                     |
| `\t` | Tab, fix vertical position before continue                 |
| `\n` | Start a new line                                           |

You can add padding by specifying the length between `%` and the code. If that starts with `0`, then value will be padded
with zeros, otherwise with spaces. For example `%4d` will pad the value to the right with spaces, and `%04x` with zeros.
The `f` accepts a number after a dot, which tells the number of digits in the fractional part (up to 8), eg. `%.6f`.

## 3D Space

In MEG-4, the 3 dimensional space is handled according to the right-hand rule: +X is on the right, +Y is up, and +Z is towards the
viewer.

```
  +Y
   |
   |__ +X
  /
+Z
```

Each point must be placed in the range -32767 to +32767. How this 3D world is projected to your 2D screen depends on how you
configure the camera (see [Graphics Processing Unit] address 0049E). Of course, you have to place the camera in the world, with
X, Y, Z coordinates. Then you have to tell where the camera is looking at, using pitch and yaw. Finally you also have to tell what
kind of lens the camera has, by specifying the field of view angle. That latter normally should be between 30 (very narrow) and
180 degrees (like fish and birds). MEG-4 supports up to 127 degrees, but there's a trick. Positive FOV values will be projected as
perspective (the farther the object is, the smaller it is), but negative values also handled, just with orthographic projection
(no matter the distance, the object's size will be the same). Perspective is used in FPS games, while the orthographic projection
is mostly preferred by strategy games.

You can display a set of triangles (a complete 3D model) using the [mesh] function efficiently. Because models probably have local
coordinates, that would draw all models one on top of another around the origo. So if you want to dispay multiple models in the
world, first you should translate them (place them) into world coordinates using [trns], and then use the translated vertex cloud
with [mesh] (moving and rotating the model around won't change the triangles, just their vertex coordinates).

## Code Editor Shortcuts

Additional [keyboard] shortcuts you can use when editing the source:

| Key                          | Description                                                                          |
|------------------------------|--------------------------------------------------------------------------------------|
| <kbd>Ctrl</kbd>+<kbd>F</kbd> | Find string                                                                          |
| <kbd>Ctrl</kbd>+<kbd>G</kbd> | Find again                                                                           |
| <kbd>Ctrl</kbd>+<kbd>H</kbd> | Search and replace (in the selected text, or in lack of that, in the entire source)  |
| <kbd>Ctrl</kbd>+<kbd>J</kbd> | Go to line                                                                           |
| <kbd>Ctrl</kbd>+<kbd>D</kbd> | Go to function definition                                                            |
| <kbd>Ctrl</kbd>+<kbd>N</kbd> | List bookmarks                                                                       |
| <kbd>Ctrl</kbd>+<kbd>B</kbd> | Toggle bookmark on current line                                                      |
| <kbd>Ctrl</kbd>+<kbd>▴</kbd> | Go to previous bookmark                                                              |
| <kbd>Ctrl</kbd>+<kbd>▾</kbd> | Go to next bookmark                                                                  |
| <kbd>Ctrl</kbd>+<kbd>◂</kbd> | Go to the beginning of the previous word                                             |
| <kbd>Ctrl</kbd>+<kbd>▸</kbd> | Go to the end of the next word                                                       |
| <kbd>Ctrl</kbd>+<kbd>,</kbd> | Decrease indentation of selection                                                    |
| <kbd>Ctrl</kbd>+<kbd>.</kbd> | Increase indentation of selection                                                    |
| <kbd>Home</kbd>              | Move cursor to the beginning of the line                                             |
| <kbd>End</kbd>               | Move cursor to the end of the line                                                   |
| <kbd>PgUp</kbd>              | Move cursor 42 lines (one page) up                                                   |
| <kbd>PgDown</kbd>            | Move cursor 42 lines (one page) down                                                 |
| <kbd>F1</kbd>                | If the cursor is in an API's argument list, then go to function's built-in help page |

Regardless to platform's keyboard layout, all characters required for programing (and some more) can always be accessed:

| Left <kbd>Alt</kbd> + |
|-----------------------|
| <kbd> </kbd> <kbd>(</kbd> <kbd>)</kbd> <kbd>{</kbd> <kbd>}</kbd> <kbd>〈</kbd> <kbd>〉</kbd> <kbd>!</kbd> <kbd>^</kbd> <kbd>_</kbd> <kbd>-</kbd> <kbd>=</kbd> |
| <kbd>⇥</kbd> <kbd> </kbd> <kbd> </kbd> <kbd>€</kbd> <kbd>₹</kbd> <kbd>~</kbd> <kbd>¥</kbd> <kbd> </kbd> <kbd> </kbd> <kbd>°</kbd> <kbd>"</kbd> <kbd>\[</kbd> <kbd>\]</kbd> |
| <kbd>↨</kbd> <kbd>&</kbd> <kbd>$</kbd> <kbd>@</kbd> <kbd>¦</kbd> <kbd> </kbd> <kbd>#</kbd> <kbd> </kbd> <kbd> </kbd> <kbd>£</kbd> <kbd>;</kbd> <kbd>'</kbd> <kbd>\\</kbd> |
| <kbd>⇮</kbd> <kbd>:</kbd> <kbd>?</kbd> <kbd> </kbd> <kbd>元</kbd> <kbd>%</kbd> <kbd>+</kbd> <kbd>✶</kbd> <kbd>,</kbd> <kbd>.</kbd> <kbd>/</kbd> |

See also the menu for alternative input methods and their keyboard shortcuts.

# Console

## putc

```c
void putc(uint32_t chr)
```
<dl>
<dt>Description</dt><dd>
Prints a character to console.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| chr | UTF-8 character |
</dd>
</dl>
<hr>
## printf

```c
void printf(str_t fmt, ...)
```
<dl>
<dt>Description</dt><dd>
Prints text to console.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| fmt | string to display, a [format string] |
| ... | optional arguments |
</dd>
</dl>
<hr>
## getc

```c
uint32_t getc(void)
```
<dl>
<dt>Description</dt><dd>
Reads a character from console, blocks program when there's no input.
</dd>
<dt>Return Value</dt><dd>
An UTF-8 character the user entered.
</dd>
<dt>See Also</dt><dd>
[popkey]
</dd>
</dl>
<hr>
## gets

```c
str_t gets(void)
```
<dl>
<dt>Description</dt><dd>
Reads in a newline terminated string from user (does not return the newline).
</dd>
<dt>Return Value</dt><dd>
The bytes read in a string.
</dd>
</dl>
<hr>
## trace

```c
void trace(str_t fmt, ...)
```
<dl>
<dt>Description</dt><dd>
Trace execution by printing to stdout. Only works if `meg4` was started with the `-v` verbose flag.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| fmt | [format string] |
| ... | optional arguments |
</dd>
</dl>
<hr>
## delay

```c
void delay(uint16_t msec)
```
<dl>
<dt>Description</dt><dd>
Delays program execution.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| msec | delay in milliseconds |
</dd>
</dl>
<hr>
## exit

```c
void exit(void)
```
<dl>
<dt>Description</dt><dd>
Exits program.
</dd>
</dl>

# Audio

## sfx

```c
void sfx(uint8_t sfx, uint8_t channel, uint8_t volume)
```
<dl>
<dt>Description</dt><dd>
Plays a sound effect.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| sfx | the index of the sound effect, 0 to 63 |
| channel | channel to be used, 0 to 11 |
| volume | volume to be used, 0 to 255, 0 turns off channel |
</dd>
</dl>
<hr>
## music

```c
void music(uint8_t track, uint16_t row, uint8_t volume)
```
<dl>
<dt>Description</dt><dd>
Plays a music track.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| track | the index of the music track, 0 to 7 |
| row | row to start playing from, 0 to 1023 (max song length) |
| volume | volume to be used, 0 to 255, 0 turns off music |
</dd>
</dl>

# GPIO

## gpio_rev

```c
uint32_t gpio_rev(void)
```
<dl>
<dt>Description</dt><dd>
Query the GPIO board's revision number. Returns 0 if the platform isn't GPIO capable.
</dd>
<dt>Return Value</dt><dd>
Board's revision number or 0 if not supported.
</dd>
</dl>
<hr>
## gpio_get

```c
int gpio_get(uint8_t pin)
```
<dl>
<dt>Description</dt><dd>
Read the value of a GPIO pin.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| pin | physical pin number, 1 to 40 |
</dd>
<dt>Return Value</dt><dd>
Returns 1 if the pin is high, 0 if it's low, -1 on error (GPIO pin not supported).
</dd>
<dt>See Also</dt><dd>
[gpio_set]
</dd>
</dl>
<hr>
## gpio_set

```c
int gpio_set(uint8_t pin, int value)
```
<dl>
<dt>Description</dt><dd>
Write the value to a GPIO pin.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| pin | physical pin number, 1 to 40 |
| value | 1 to set the pin high, 0 for low |
</dd>
<dt>Return Value</dt><dd>
Returns 0 on success, -1 on error (GPIO pin not supported).
</dd>
<dt>See Also</dt><dd>
[gpio_get]
</dd>
</dl>

# Graphics

## cls

```c
void cls(uint8_t palidx)
```
<dl>
<dt>Description</dt><dd>
Clears the entire screen and resets display offsets, also sets the console's background color.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| palidx | color, palette index 0 to 255 |
</dd>
<dt>See Also</dt><dd>
[pget], [pset]
</dd>
</dl>
<hr>
## cget

```c
uint32_t cget(uint16_t x, uint16_t y)
```
<dl>
<dt>Description</dt><dd>
Get pixel at a coordinate and return color RGBA.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| x | X coordinate in pixels |
| y | Y coordinate in pixels |
</dd>
<dt>Return Value</dt><dd>
A packed color, with RGBA channels (red is in the least significant byte).
</dd>
<dt>See Also</dt><dd>
[cls], [pget], [pset]
</dd>
</dl>
<hr>
## pget

```c
uint8_t pget(uint16_t x, uint16_t y)
```
<dl>
<dt>Description</dt><dd>
Get pixel at a coordinate and return its palette index.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| x | X coordinate in pixels |
| y | Y coordinate in pixels |
</dd>
<dt>Return Value</dt><dd>
Color in palette index, 0 to 255.
</dd>
<dt>See Also</dt><dd>
[cls], [pset], [cget]
</dd>
</dl>
<hr>
## pset

```c
void pset(uint8_t palidx, uint16_t x, uint16_t y)
```
<dl>
<dt>Description</dt><dd>
Plots a pixel at a coordinate.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| palidx | color, palette index 0 to 255 |
| x | X coordinate in pixels |
| y | Y coordinate in pixels |
</dd>
<dt>See Also</dt><dd>
[cls], [pget]
</dd>
</dl>
<hr>
## width

```c
uint16_t width(int8_t type, str_t str)
```
<dl>
<dt>Description</dt><dd>
Returns displayed text's width in pixels.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| type | font type, -4 to 4 |
| str | string to measure |
</dd>
<dt>Return Value</dt><dd>
Number of pixels required to display text.
</dd>
<dt>See Also</dt><dd>
[text]
</dd>
</dl>
<hr>
## text

```c
void text(uint8_t palidx, int16_t x, int16_t y, int8_t type, uint8_t shidx, uint8_t sha, str_t str)
```
<dl>
<dt>Description</dt><dd>
Prints text on screen.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| palidx | color, palette index 0 to 255 |
| x | X coordinate in pixels |
| y | Y coordinate in pixels |
| type | font type, -4 to -1 monospace, 1 to 4 proportional |
| shidx | shadow's color, palette index 0 to 255 |
| sha | shadow's alpha, 0 (fully transparent) to 255 (fully opaque) |
| str | string to display |
</dd>
<dt>See Also</dt><dd>
[width]
</dd>
</dl>
<hr>
## line

```c
void line(uint8_t palidx, int16_t x0, int16_t y0, int16_t x1, int16_t y1)
```
<dl>
<dt>Description</dt><dd>
Draws an anti-aliased line.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| palidx | color, palette index 0 to 255 |
| x0 | starting X coordinate in pixels |
| y0 | starting Y coordinate in pixels |
| x1 | ending X coordinate in pixels |
| y1 | ending Y coordinate in pixels |
</dd>
<dt>See Also</dt><dd>
[qbez], [cbez]
</dd>
</dl>
<hr>
## qbez

```c
void qbez(uint8_t palidx, int16_t x0, int16_t y0, int16_t x1, int16_t y1,
    int16_t cx, int16_t cy)
```
<dl>
<dt>Description</dt><dd>
Draws a quadratic Bezier curve.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| palidx | color, palette index 0 to 255 |
| x0 | starting X coordinate in pixels |
| y0 | starting Y coordinate in pixels |
| x1 | ending X coordinate in pixels |
| y1 | ending Y coordinate in pixels |
| cx | control point X coordinate in pixels |
| cy | control point Y coordinate in pixels |
</dd>
<dt>See Also</dt><dd>
[line], [cbez]
</dd>
</dl>
<hr>
## cbez

```c
void cbez(uint8_t palidx, int16_t x0, int16_t y0, int16_t x1, int16_t y1,
    int16_t cx0, int16_t cy0, int16_t cx1, int16_t cy1)
```
<dl>
<dt>Description</dt><dd>
Draws a cubic Bezier curve.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| palidx | color, palette index 0 to 255 |
| x0 | starting X coordinate in pixels |
| y0 | starting Y coordinate in pixels |
| x1 | ending X coordinate in pixels |
| y1 | ending Y coordinate in pixels |
| cx0 | first control point X coordinate in pixels |
| cy0 | first control point Y coordinate in pixels |
| cx1 | second control point X coordinate in pixels |
| cy1 | second control point Y coordinate in pixels |
</dd>
<dt>See Also</dt><dd>
[line], [qbez]
</dd>
</dl>
<hr>
## tri

```c
void tri(uint8_t palidx, int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2)
```
<dl>
<dt>Description</dt><dd>
Draws a triangle.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| palidx | color, palette index 0 to 255 |
| x0 | first edge X coordinate in pixels |
| y0 | first edge Y coordinate in pixels |
| x1 | second edge X coordinate in pixels |
| y1 | second edge Y coordinate in pixels |
| x2 | third edge X coordinate in pixels |
| y2 | third edge Y coordinate in pixels |
</dd>
<dt>See Also</dt><dd>
[ftri], [tri2d], [tri3d], [tritx], [mesh], [trns]
</dd>
</dl>
<hr>
## ftri

```c
void ftri(uint8_t palidx, int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2)
```
<dl>
<dt>Description</dt><dd>
Draws a filled triangle.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| palidx | color, palette index 0 to 255 |
| x0 | first edge X coordinate in pixels |
| y0 | first edge Y coordinate in pixels |
| x1 | second edge X coordinate in pixels |
| y1 | second edge Y coordinate in pixels |
| x2 | third edge X coordinate in pixels |
| y2 | third edge Y coordinate in pixels |
</dd>
<dt>See Also</dt><dd>
[tri], [tri2d], [tri3d], [tritx], [mesh], [trns]
</dd>
</dl>
<hr>
## tri2d

```c
void tri2d(uint8_t pi0, int16_t x0, int16_t y0,
    uint8_t pi1, int16_t x1, int16_t y1,
    uint8_t pi2, int16_t x2, int16_t y2)
```
<dl>
<dt>Description</dt><dd>
Draws a filled triangle with color gradients.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| pi0 | first edge color, palette index 0 to 255 |
| x0 | first edge X coordinate in pixels |
| y0 | first edge Y coordinate in pixels |
| pi1 | second edge color, palette index 0 to 255 |
| x1 | second edge X coordinate in pixels |
| y1 | second edge Y coordinate in pixels |
| pi2 | third edge color, palette index 0 to 255 |
| x2 | third edge X coordinate in pixels |
| y2 | third edge Y coordinate in pixels |
</dd>
<dt>See Also</dt><dd>
[tri], [ftri], [tri3d], [tritx], [mesh], [trns]
</dd>
</dl>
<hr>
## tri3d

```c
void tri3d(uint8_t pi0, int16_t x0, int16_t y0, int16_t z0,
    uint8_t pi1, int16_t x1, int16_t y1, int16_t z1,
    uint8_t pi2, int16_t x2, int16_t y2, int16_t z2)
```
<dl>
<dt>Description</dt><dd>
Draws a filled triangle with color gradients in [3D space].
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| pi0 | first edge color, palette index 0 to 255 |
| x0 | first edge X coordinate in space |
| y0 | first edge Y coordinate in space |
| z0 | first edge Z coordinate in space |
| pi1 | second edge color, palette index 0 to 255 |
| x1 | second edge X coordinate in space |
| y1 | second edge Y coordinate in space |
| z1 | second edge Z coordinate in space |
| pi2 | third edge color, palette index 0 to 255 |
| x2 | third edge X coordinate in space |
| y2 | third edge Y coordinate in space |
| z2 | third edge Z coordinate in space |
</dd>
<dt>See Also</dt><dd>
[tri], [ftri], [tri2d], [tritx], [mesh], [trns]
</dd>
</dl>
<hr>
## tritx

```c
void tritx(uint8_t u0, uint8_t v0, int16_t x0, int16_t y0, int16_t z0,
    uint8_t u1, uint8_t v1, int16_t x1, int16_t y1, int16_t z1,
    uint8_t u2, uint8_t v2, int16_t x2, int16_t y2, int16_t z2)
```
<dl>
<dt>Description</dt><dd>
Draws a textured triangle in [3D space].
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| u0 | first edge texture X coordinate 0 to 255 |
| v0 | first edge texture Y coordinate 0 to 255 |
| x0 | first edge X coordinate in space |
| y0 | first edge Y coordinate in space |
| z0 | first edge Z coordinate in space |
| u1 | second edge texture X coordinate 0 to 255 |
| v1 | second edge texture Y coordinate 0 to 255 |
| x1 | second edge X coordinate in space |
| y1 | second edge Y coordinate in space |
| z1 | second edge Z coordinate in space |
| u2 | third edge texture X coordinate 0 to 255 |
| v2 | third edge texture Y coordinate 0 to 255 |
| x2 | third edge X coordinate in space |
| y2 | third edge Y coordinate in space |
| z2 | third edge Z coordinate in space |
</dd>
<dt>See Also</dt><dd>
[tri], [ftri], [tri2d], [tri3d], [mesh], [trns]
</dd>
</dl>
<hr>
## mesh

```c
void mesh(addr_t verts, addr_t uvs, uint16_t numtri, addr_t tris)
```
<dl>
<dt>Description</dt><dd>
Draws a mesh made of triangles in [3D space], using indices to vertices and texture coordinates (or palette).
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| verts | address of vertices array, 3 x 2 bytes each, X, Y, Z |
| uvs | address of UVs array (if 0, then palette is used), 2 x 1 bytes each, texture X, Y |
| numtri | number of triangles |
| tris | address of triangles array with indices, 6 x 1 bytes each, vi1, ui1/pi1, vi2, ui2/pi2, vi3, ui3/pi3 |
</dd>
<dt>See Also</dt><dd>
[tri], [ftri], [tri2d], [tri3d], [tritx], [trns]
</dd>
</dl>
<hr>
## rect

```c
void rect(uint8_t palidx, int16_t x0, int16_t y0, int16_t x1, int16_t y1)
```
<dl>
<dt>Description</dt><dd>
Draws a rectangle.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| palidx | color, palette index 0 to 255 |
| x0 | top left corner X coordinate in pixels |
| y0 | top left corner Y coordinate in pixels |
| x1 | bottom right X coordinate in pixels |
| y1 | bottom right Y coordinate in pixels |
</dd>
<dt>See Also</dt><dd>
[frect]
</dd>
</dl>
<hr>
## frect

```c
void frect(uint8_t palidx, int16_t x0, int16_t y0, int16_t x1, int16_t y1)
```
<dl>
<dt>Description</dt><dd>
Draws a filled rectangle.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| palidx | color, palette index 0 to 255 |
| x0 | top left corner X coordinate in pixels |
| y0 | top left corner Y coordinate in pixels |
| x1 | bottom right X coordinate in pixels |
| y1 | bottom right Y coordinate in pixels |
</dd>
<dt>See Also</dt><dd>
[rect]
</dd>
</dl>
<hr>
## circ

```c
void circ(uint8_t palidx, int16_t x, int16_t y, uint16_t r)
```
<dl>
<dt>Description</dt><dd>
Draws a circle.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| palidx | color, palette index 0 to 255 |
| x | center X coordinate in pixels |
| y | center Y coordinate in pixels |
| r | radius in pixels |
</dd>
<dt>See Also</dt><dd>
[fcirc], [ellip], [fellip]
</dd>
</dl>
<hr>
## fcirc

```c
void fcirc(uint8_t palidx, int16_t x, int16_t y, uint16_t r)
```
<dl>
<dt>Description</dt><dd>
Draws a filled circle.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| palidx | color, palette index 0 to 255 |
| x | center X coordinate in pixels |
| y | center Y coordinate in pixels |
| r | radius in pixels |
</dd>
<dt>See Also</dt><dd>
[circ], [ellip], [fellip]
</dd>
</dl>
<hr>
## ellip

```c
void ellip(uint8_t palidx, int16_t x0, int16_t y0, int16_t x1, int16_t y1)
```
<dl>
<dt>Description</dt><dd>
Draws an ellipse.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| palidx | color, palette index 0 to 255 |
| x0 | top left corner X coordinate in pixels |
| y0 | top left corner Y coordinate in pixels |
| x1 | bottom right X coordinate in pixels |
| y1 | bottom right Y coordinate in pixels |
</dd>
<dt>See Also</dt><dd>
[circ], [fcirc], [fellip]
</dd>
</dl>
<hr>
## fellip

```c
void fellip(uint8_t palidx, int16_t x0, int16_t y0, int16_t x1, int16_t y1)
```
<dl>
<dt>Description</dt><dd>
Draws a filled ellipse.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| palidx | color, palette index 0 to 255 |
| x0 | top left corner X coordinate in pixels |
| y0 | top left corner Y coordinate in pixels |
| x1 | bottom right X coordinate in pixels |
| y1 | bottom right Y coordinate in pixels |
</dd>
<dt>See Also</dt><dd>
[circ], [fcirc], [ellip]
</dd>
</dl>
<hr>
## move

```c
void move(int16_t x, int16_t y, uint16_t deg)
```
<dl>
<dt>Description</dt><dd>
Moves turtle to the given position on screen or in the maze.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| x | X coordinate in pixels (or 1/128 tiles with [maze]) |
| y | Y coordinate in pixels |
| deg | direction in degrees, 0 to 359, 0 is upwards on screen, 90 is to the right |
</dd>
<dt>See Also</dt><dd>
[left], [right], [up], [down], [color], [forw], [back]
</dd>
</dl>
<hr>
## left

```c
void left(uint16_t deg)
```
<dl>
<dt>Description</dt><dd>
Turns turtle left.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| deg | change in degrees, 0 to 359 |
</dd>
<dt>See Also</dt><dd>
[move], [right], [up], [down], [color], [forw], [back]
</dd>
</dl>
<hr>
## right

```c
void right(uint16_t deg)
```
<dl>
<dt>Description</dt><dd>
Turns turtle right.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| deg | change in degrees, 0 to 359 |
</dd>
<dt>See Also</dt><dd>
[move], [left], [up], [down], [color], [forw], [back]
</dd>
</dl>
<hr>
## up

```c
void up(void)
```
<dl>
<dt>Description</dt><dd>
Lifts turtle's tail up. The turtle will move without drawing a line.
</dd>
<dt>See Also</dt><dd>
[move], [left], [right], [down], [color], [forw], [back]
</dd>
</dl>
<hr>
## down

```c
void down(void)
```
<dl>
<dt>Description</dt><dd>
Puts turtle's tail down. The turtle will move drawing a line (see [color]).
</dd>
<dt>See Also</dt><dd>
[move], [left], [right], [up], [color], [forw], [back]
</dd>
</dl>
<hr>
## color

```c
void color(uint8_t palidx)
```
<dl>
<dt>Description</dt><dd>
Sets turtle paint color.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| palidx | color, palette index 0 to 255 |
</dd>
<dt>See Also</dt><dd>
[move], [left], [right], [up], [down], [forw], [back]
</dd>
</dl>
<hr>
## forw

```c
void forw(uint16_t cnt)
```
<dl>
<dt>Description</dt><dd>
Moves turtle forward.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| cnt | amount in pixels (or 1/128 tiles with [maze]) |
</dd>
<dt>See Also</dt><dd>
[move], [left], [right], [up], [down], [color], [back]
</dd>
</dl>
<hr>
## back

```c
void back(uint16_t cnt)
```
<dl>
<dt>Description</dt><dd>
Moves turtle backward.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| cnt | amount in pixels (or 1/128 tiles with [maze]) |
</dd>
<dt>See Also</dt><dd>
[move], [left], [right], [up], [down], [color], [forw]
</dd>
</dl>
<hr>
## spr

```c
void spr(int16_t x, int16_t y, uint16_t sprite, uint8_t sw, uint8_t sh, int8_t scale, uint8_t type)
```
<dl>
<dt>Description</dt><dd>
Displays a sprite, or multiple adjacent sprites.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| x | X coordinate in pixels |
| y | Y coordinate in pixels |
| sprite | sprite id, 0 to 1023 |
| sw | number of horizontal sprites |
| sh | number of vertical sprites |
| scale | scale, -3 to 4 |
| type | transform, 0=normal, 1=rotate 90, 2=rotate 180, 3=rotate 270, 4=flip vertically, 5=flip+90, 6=flip horizontally, 7=flip+270 |
</dd>
<dt>See Also</dt><dd>
[dlg], [stext]
</dd>
</dl>
<hr>
## dlg

```c
void dlg(int16_t x, int16_t y, uint16_t w, uint16_t h, int8_t scale,
    uint16_t tl, uint16_t tm, uint16_t tr,
    uint16_t ml, uint16_t bg, uint16_t mr,
    uint16_t bl, uint16_t bm, uint16_t br)
```
<dl>
<dt>Description</dt><dd>
Displays a dialog window using sprites.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| x | X coordinate in pixels |
| y | Y coordinate in pixels |
| w | dialog width in pixels |
| h | dialog height in pixels |
| scale | scale, -3 to 4 |
| tl | top left corner sprite id |
| tm | top middle sprite id |
| tr | top right corner sprite id |
| ml | middle left side sprite id |
| bg | background sprite id |
| mr | middle right side sprite id |
| bl | bottom left corner sprite id |
| bm | bottom middle sprite id |
| br | bottom right corner sprite id |
</dd>
<dt>See Also</dt><dd>
[spr], [stext]
</dd>
</dl>
<hr>
## stext

```c
void stext(int16_t x, int16_t y, uint16_t fs, uint16_t fu, uint8_t sw, uint8_t sh, int8_t scale, str_t str)
```
<dl>
<dt>Description</dt><dd>
Displays text on screen using sprites.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| x | X coordinate in pixels |
| y | Y coordinate in pixels |
| fs | first sprite id to be used for displaying |
| fu | first UNICODE (smallest character) in string |
| sw | number of horizontal sprites |
| sh | number of vertical sprites |
| scale | scale, -3 to 4 |
| str | zero terminated UTF-8 string |
</dd>
<dt>See Also</dt><dd>
[spr], [dlg]
</dd>
</dl>
<hr>
## remap

```c
void remap(addr_t replace)
```
<dl>
<dt>Description</dt><dd>
Replaces tiles on map. Can be used to animate tiles on the map.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| replace | an array of 256 sprite ids |
</dd>
<dt>See Also</dt><dd>
[mget], [mset], [map], [maze]
</dd>
</dl>
<hr>
## mget

```c
uint16_t mget(uint16_t mx, uint16_t my)
```
<dl>
<dt>Description</dt><dd>
Returns one tile on map.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| mx | X coordinate on map in tiles |
| my | Y coordinate on map in tiles |
</dd>
<dt>Return Value</dt><dd>
The sprite id of the tile at the given coordinate.
</dd>
<dt>See Also</dt><dd>
[remap], [mset], [map], [maze]
</dd>
</dl>
<hr>
## mset

```c
void mset(uint16_t mx, uint16_t my, uint16_t sprite)
```
<dl>
<dt>Description</dt><dd>
Sets one tile on map.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| mx | X coordinate on map in tiles |
| my | Y coordinate on map in tiles |
| sprite | sprite id, 0 to 1023 |
</dd>
<dt>See Also</dt><dd>
[remap], [mget], [map], [maze]
</dd>
</dl>
<hr>
## map

```c
void map(int16_t x, int16_t y, uint16_t mx, uint16_t my, uint16_t mw, uint16_t mh, int8_t scale)
```
<dl>
<dt>Description</dt><dd>
Draws (part of) the map.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| x | X coordinate in pixels |
| y | Y coordinate in pixels |
| mx | X coordinate on map in tiles |
| my | Y coordinate on map in tiles |
| mw | number of horizontal tiles |
| mh | number of vertical tiles |
| scale | scale, -3 to 4 |
</dd>
<dt>See Also</dt><dd>
[remap], [mget], [mset], [maze]
</dd>
</dl>
<hr>
## maze

```c
void maze(uint16_t mx, uint16_t my, uint16_t mw, uint16_t mh, uint8_t scale,
    uint16_t sky, uint16_t grd, uint16_t door, uint16_t wall, uint16_t obj, uint8_t numnpc, addr_t npc)
```
<dl>
<dt>Description</dt><dd>
Displays map as a 3D maze, using turtle's position.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| mx | X coordinate on map in tiles |
| my | Y coordinate on map in tiles |
| mw | number of horizontal tiles |
| mh | number of vertical tiles |
| scale | number of sprites per tiles in power of two, 0 to 3 |
| sky | sky tile index |
| grd | ground tile index |
| door | first door tile index |
| wall | first wall tile index |
| obj | first object tile index |
| numnpc | number of NPC records |
| npc | an uint32_t array of numnpc times x,y,tile index triplets |
</dd>
<dt>See Also</dt><dd>
[remap], [mget], [mset], [map]
</dd>
</dl>

# Input

## getpad

```c
int getpad(int pad, int btn)
```
<dl>
<dt>Description</dt><dd>
Gets the current state of a gamepad button.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| pad | gamepad index, 0 to 3 |
| btn | one of the [gamepad] buttons, `BTN_` |
</dd>
<dt>Return Value</dt><dd>
Zero if not pressed, non-zero if pressed.
</dd>
<dt>See Also</dt><dd>
[prspad], [relpad], [getbtn], [getclk], [getkey]
</dd>
</dl>
<hr>
## prspad

```c
int prspad(int pad, int btn)
```
<dl>
<dt>Description</dt><dd>
Returns true if gamepad button was pressed since last call.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| pad | gamepad index, 0 to 3 |
| btn | one of the [gamepad] buttons, `BTN_` |
</dd>
<dt>Return Value</dt><dd>
Zero if not pressed, non-zero if pressed.
</dd>
<dt>See Also</dt><dd>
[relpad], [getpad], [getbtn], [getclk], [getkey]
</dd>
</dl>
<hr>
## relpad

```c
int relpad(int pad, int btn)
```
<dl>
<dt>Description</dt><dd>
Returns true if gamepad button was released since last call.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| pad | gamepad index, 0 to 3 |
| btn | one of the [gamepad] buttons, `BTN_` |
</dd>
<dt>Return Value</dt><dd>
Zero if wasn't released, non-zero if released.
</dd>
<dt>See Also</dt><dd>
[prspad], [getpad], [getbtn], [getclk], [getkey]
</dd>
</dl>
<hr>
## getbtn

```c
int getbtn(int btn)
```
<dl>
<dt>Description</dt><dd>
Gets the mouse buttons state.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| btn | one of the [pointer] buttons, `BTN_` or `SCR_` |
</dd>
<dt>Return Value</dt><dd>
Zero if not pressed, non-zero if pressed.
</dd>
<dt>See Also</dt><dd>
[prspad], [relpad], [getpad], [getclk], [getkey]
</dd>
</dl>
<hr>
## getclk

```c
int getclk(int btn)
```
<dl>
<dt>Description</dt><dd>
Gets mouse button clicking.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| btn | one of the [pointer] buttons, `BTN_` |
</dd>
<dt>Return Value</dt><dd>
Zero if not clicked, non-zero if clicked.
</dd>
<dt>See Also</dt><dd>
[prspad], [relpad], [getpad], [getbtn], [getkey]
</dd>
</dl>
<hr>
## getkey

```c
int getkey(int sc)
```
<dl>
<dt>Description</dt><dd>
Gets the current state of a key.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| sc | scancode, 1 to 144, see [keyboard] |
</dd>
<dt>Return Value</dt><dd>
Zero if not pressed, non-zero if pressed.
</dd>
<dt>See Also</dt><dd>
[prspad], [relpad], [getpad], [getbtn], [getclk]
</dd>
</dl>
<hr>
## popkey

```c
uint32_t popkey(void)
```
<dl>
<dt>Description</dt><dd>
Pop an UTF-8 key from the keyboard queue. See [keyboard], and for the blocking version [getc].
</dd>
<dt>Return Value</dt><dd>
The UTF-8 representation of the key, or 0 if the queue was empty (no blocking).
</dd>
<dt>See Also</dt><dd>
[pendkey], [lenkey], [speckey], [getc]
</dd>
</dl>
<hr>
## pendkey

```c
int pendkey(void)
```
<dl>
<dt>Description</dt><dd>
Returns true if there's a key pending in the queue (but leaves the key in the queue, does not pop it).
</dd>
<dt>Return Value</dt><dd>
Returns 1 if there are keys in the queue pending.
</dd>
<dt>See Also</dt><dd>
[popkey], [lenkey], [speckey]
</dd>
</dl>
<hr>
## lenkey

```c
int lenkey(uint32_t key)
```
<dl>
<dt>Description</dt><dd>
Returns the length of a UTF-8 key in bytes.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| key | the key, popped from the queue |
</dd>
<dt>Return Value</dt><dd>
UTF-8 representation's length in bytes.
</dd>
<dt>See Also</dt><dd>
[popkey], [pendkey], [speckey]
</dd>
</dl>
<hr>
## speckey

```c
int speckey(uint32_t key)
```
<dl>
<dt>Description</dt><dd>
Returns true if key is a special key.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| key | the key, popped from the queue |
</dd>
<dt>Return Value</dt><dd>
Returns 1 if it's a special key, and 0 if it's a printable one.
</dd>
<dt>See Also</dt><dd>
[popkey], [pendkey], [lenkey]
</dd>
</dl>

# Mathematics

## rand

```c
uint32_t rand(void)
```
<dl>
<dt>Description</dt><dd>
Get random. Use `%` modulo to make it smaller, for example `1 + rand() % 6` returns random between 1 and 6, like a dice.
</dd>
<dt>Return Value</dt><dd>
A random number between 0 and 2^^32^^-1 (4294967295).
</dd>
<dt>See Also</dt><dd>
[rnd]
</dd>
</dl>
<hr>
## rnd

```c
float rnd(void)
```
<dl>
<dt>Description</dt><dd>
Get random. Same as [rand], but returns a floating point number.
</dd>
<dt>Return Value</dt><dd>
A random number between 0.0 and 1.0.
</dd>
<dt>See Also</dt><dd>
[rand]
</dd>
</dl>
<hr>
## float

```c
float float(int val)
```
<dl>
<dt>Description</dt><dd>
Returns the floating point equivalent of an integer number.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| val | value |
</dd>
<dt>Return Value</dt><dd>
The floating point of value.
</dd>
<dt>See Also</dt><dd>
[int]
</dd>
</dl>
<hr>
## int

```c
int int(float val)
```
<dl>
<dt>Description</dt><dd>
Returns the integer equivalent of a floating point number.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| val | value |
</dd>
<dt>Return Value</dt><dd>
The integer of value.
</dd>
<dt>See Also</dt><dd>
[float]
</dd>
</dl>
<hr>
## floor

```c
float floor(float val)
```
<dl>
<dt>Description</dt><dd>
Returns the largest integral number that's not greater than value.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| val | value |
</dd>
<dt>Return Value</dt><dd>
The floor of value.
</dd>
<dt>See Also</dt><dd>
[ceil]
</dd>
</dl>
<hr>
## ceil

```c
float ceil(float val)
```
<dl>
<dt>Description</dt><dd>
Returns the smallest integral number that's not less than value.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| val | value |
</dd>
<dt>Return Value</dt><dd>
The ceiling of value.
</dd>
<dt>See Also</dt><dd>
[floor]
</dd>
</dl>
<hr>
## sgn

```c
float sgn(float val)
```
<dl>
<dt>Description</dt><dd>
Returns the sign of the value.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| val | value |
</dd>
<dt>Return Value</dt><dd>
Either 1.0 or -1.0.
</dd>
<dt>See Also</dt><dd>
[abs]
</dd>
</dl>
<hr>
## abs

```c
float abs(float val)
```
<dl>
<dt>Description</dt><dd>
Returns the absolute of the value.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| val | value |
</dd>
<dt>Return Value</dt><dd>
Either value or -value, always positive.
</dd>
<dt>See Also</dt><dd>
[sgn]
</dd>
</dl>
<hr>
## exp

```c
float exp(float val)
```
<dl>
<dt>Description</dt><dd>
Returns the exponential of the value, i.e. base of natural logarithms raised to power of the value.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| val | value |
</dd>
<dt>Return Value</dt><dd>
Returns e^^val^^.
</dd>
<dt>See Also</dt><dd>
[log], [pow]
</dd>
</dl>
<hr>
## log

```c
float log(float val)
```
<dl>
<dt>Description</dt><dd>
Returns the natural logarithm of the value.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| val | value |
</dd>
<dt>Return Value</dt><dd>
Returns natural logarithm of value.
</dd>
<dt>See Also</dt><dd>
[exp]
</dd>
</dl>
<hr>
## pow

```c
float pow(float val, float exp)
```
<dl>
<dt>Description</dt><dd>
Returns the value raised to the power of exponent. This is a slow operation, try to avoid.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| val | value |
| exp | exponent |
</dd>
<dt>Return Value</dt><dd>
Returns val^^exp^^.
</dd>
<dt>See Also</dt><dd>
[exp], [sqrt], [rsqrt]
</dd>
</dl>
<hr>
## sqrt

```c
float sqrt(float val)
```
<dl>
<dt>Description</dt><dd>
Returns the square root of the value. This is a slow operation, try to avoid.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| val | value |
</dd>
<dt>Return Value</dt><dd>
Square root of the value.
</dd>
<dt>See Also</dt><dd>
[pow], [rsqrt]
</dd>
</dl>
<hr>
## rsqrt

```c
float rsqrt(float val)
```
<dl>
<dt>Description</dt><dd>
Returns the reciprocal of the square root of the value (`1 / sqrt(val)`). Uses John Carmack's fast method.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| val | value |
</dd>
<dt>Return Value</dt><dd>
Reciprocal of the square root of the value.
</dd>
<dt>See Also</dt><dd>
[pow], [sqrt]
</dd>
</dl>
<hr>
## clamp

```c
float clamp(float val, float minv, float maxv)
```
<dl>
<dt>Description</dt><dd>
Clamps a value between the limits.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| val | value |
| minv | minimum value |
| maxv | maximum value |
</dd>
<dt>Return Value</dt><dd>
Clamped value.
</dd>
<dt>See Also</dt><dd>
[clampv2], [clampv3], [clampv4]
</dd>
</dl>
<hr>
## lerp

```c
float lerp(float a, float b, float t)
```
<dl>
<dt>Description</dt><dd>
Linear interpolates two numbers.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | first float number |
| b | second float number |
| t | interpolation value between 0.0 and 1.0 |
</dd>
<dt>See Also</dt><dd>
[lerpv2], [lerpv3], [lerpv4], [lerpq], [slerpq]
</dd>
</dl>
<hr>
## pi

```c
float pi(void)
```
<dl>
<dt>Description</dt><dd>
Returns π as a floating point number.
</dd>
<dt>Return Value</dt><dd>
The value 3.14159265358979323846.
</dd>
</dl>
<hr>
## cos

```c
float cos(uint16_t deg)
```
<dl>
<dt>Description</dt><dd>
Returns cosine.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| deg | degree, 0 to 359, 0 is up, 90 on the right |
</dd>
<dt>Return Value</dt><dd>
Cosine of the degree, between -1.0 to 1.0.
</dd>
<dt>See Also</dt><dd>
[sin], [tan], [acos], [asin], [atan], [atan2]
</dd>
</dl>
<hr>
## sin

```c
float sin(uint16_t deg)
```
<dl>
<dt>Description</dt><dd>
Returns sine.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| deg | degree, 0 to 359, 0 is up, 90 to the right |
</dd>
<dt>Return Value</dt><dd>
Sine of the degree, between -1.0 to 1.0.
</dd>
<dt>See Also</dt><dd>
[cos], [tan], [acos], [asin], [atan], [atan2]
</dd>
</dl>
<hr>
## tan

```c
float tan(uint16_t deg)
```
<dl>
<dt>Description</dt><dd>
Returns tangent.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| deg | degree, 0 to 359, 0 is up, 90 to the right |
</dd>
<dt>Return Value</dt><dd>
Tangent of the degree, between -1.0 to 1.0.
</dd>
<dt>See Also</dt><dd>
[cos], [sin], [acos], [asin], [atan], [atan2]
</dd>
</dl>
<hr>
## acos

```c
uint16_t acos(float val)
```
<dl>
<dt>Description</dt><dd>
Returns arcus cosine.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| val | value, -1.0 to 1.0 |
</dd>
<dt>Return Value</dt><dd>
Arcus cosine in degree, 0 to 359, 0 is up, 90 to the right.
</dd>
<dt>See Also</dt><dd>
[cos], [sin], [tan], [asin], [atan], [atan2]
</dd>
</dl>
<hr>
## asin

```c
uint16_t asin(float val)
```
<dl>
<dt>Description</dt><dd>
Returns arcus sine.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| val | value, -1.0 to 1.0 |
</dd>
<dt>Return Value</dt><dd>
Arcus sine in degree, 0 to 359, 0 is up, 90 to the right.
</dd>
<dt>See Also</dt><dd>
[cos], [sin], [tan], [acos], [atan], [atan2]
</dd>
</dl>
<hr>
## atan

```c
uint16_t atan(float val)
```
<dl>
<dt>Description</dt><dd>
Returns arcus tangent.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| val | value, -1.0 to 1.0 |
</dd>
<dt>Return Value</dt><dd>
Arcus tangent in degree, 0 to 359, 0 is up, 90 to the right.
</dd>
<dt>See Also</dt><dd>
[cos], [sin], [tan], [acos], [asin], [atan2]
</dd>
</dl>
<hr>
## atan2

```c
uint16_t atan2(float y, float x)
```
<dl>
<dt>Description</dt><dd>
Returns arcus tangent for y/x, using the signs of y and x to determine the quadrant.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| y | Y coordinate |
| x | X coordinate |
</dd>
<dt>Return Value</dt><dd>
Arcus tangent in degree, 0 to 359, 0 is up, 90 to the right.
</dd>
<dt>See Also</dt><dd>
[cos], [sin], [tan], [acos], [asin]
</dd>
</dl>
<hr>
## dotv2

```c
float dotv2(addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Calculates dot product of two vectors with two elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of two floats |
| b | address of two floats |
</dd>
<dt>Return Value</dt><dd>
Dot product of the vectors.
</dd>
<dt>See Also</dt><dd>
[lenv2], [scalev2], [negv2], [addv2], [subv2], [mulv2], [divv2], [clampv2], [lerpv2], [normv2]
</dd>
</dl>
<hr>
## lenv2

```c
float lenv2(addr_t a)
```
<dl>
<dt>Description</dt><dd>
Calculates the length of a vector with two elements. This is slow, try to avoid (see [normv2]).
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of two floats |
</dd>
<dt>Return Value</dt><dd>
Length of the vector.
</dd>
<dt>See Also</dt><dd>
[dotv2], [scalev2], [negv2], [addv2], [subv2], [mulv2], [divv2], [clampv2], [lerpv2], [normv2]
</dd>
</dl>
<hr>
## scalev2

```c
void scalev2(addr_t a, float s)
```
<dl>
<dt>Description</dt><dd>
Scales a vector with two elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of two floats |
| s | scaler value |
</dd>
<dt>See Also</dt><dd>
[dotv2], [lenv2], [negv2], [addv2], [subv2], [mulv2], [divv2], [clampv2], [lerpv2], [normv2]
</dd>
</dl>
<hr>
## negv2

```c
void negv2(addr_t a)
```
<dl>
<dt>Description</dt><dd>
Negates a vector with two elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of two floats |
</dd>
<dt>See Also</dt><dd>
[dotv2], [lenv2], [scalev2], [addv2], [subv2], [mulv2], [divv2], [clampv2], [lerpv2], [normv2]
</dd>
</dl>
<hr>
## addv2

```c
void addv2(addr_t dst, addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Adds together vectors with two elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of two floats |
| a | address of two floats |
| b | address of two floats |
</dd>
<dt>See Also</dt><dd>
[dotv2], [lenv2], [scalev2], [negv2], [subv2], [mulv2], [divv2], [clampv2], [lerpv2], [normv2]
</dd>
</dl>
<hr>
## subv2

```c
void subv2(addr_t dst, addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Subtracts vectors with two elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of two floats |
| a | address of two floats |
| b | address of two floats |
</dd>
<dt>See Also</dt><dd>
[dotv2], [lenv2], [scalev2], [negv2], [addv2], [mulv2], [divv2], [clampv2], [lerpv2], [normv2]
</dd>
</dl>
<hr>
## mulv2

```c
void mulv2(addr_t dst, addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Multiplies vectors with two elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of two floats |
| a | address of two floats |
| b | address of two floats |
</dd>
<dt>See Also</dt><dd>
[dotv2], [lenv2], [scalev2], [negv2], [addv2], [subv2], [divv2], [clampv2], [lerpv2], [normv2]
</dd>
</dl>
<hr>
## divv2

```c
void divv2(addr_t dst, addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Divides vectors with two elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of two floats |
| a | address of two floats |
| b | address of two floats |
</dd>
<dt>See Also</dt><dd>
[dotv2], [lenv2], [scalev2], [negv2], [addv2], [subv2], [mulv2], [clampv2], [lerpv2], [normv2]
</dd>
</dl>
<hr>
## clampv2

```c
void clampv2(addr_t dst, addr_t v, addr_t minv, addr_t maxv)
```
<dl>
<dt>Description</dt><dd>
Clamps vectors with two elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of two floats |
| v | address of two floats, input |
| minv | address of two floats, minimum |
| maxv | address of two floats, maximum |
</dd>
<dt>See Also</dt><dd>
[dotv2], [lenv2], [scalev2], [negv2], [addv2], [subv2], [mulv2], [divv2], [lerpv2], [normv2]
</dd>
</dl>
<hr>
## lerpv2

```c
void lerpv2(addr_t dst, addr_t a, addr_t b, float t)
```
<dl>
<dt>Description</dt><dd>
Linear interpolates vectors with two elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of two floats |
| a | address of two floats |
| b | address of two floats |
| t | interpolation value between 0.0 and 1.0 |
</dd>
<dt>See Also</dt><dd>
[dotv2], [lenv2], [scalev2], [negv2], [addv2], [subv2], [mulv2], [divv2], [clampv2], [normv2]
</dd>
</dl>
<hr>
## normv2

```c
void normv2(addr_t a)
```
<dl>
<dt>Description</dt><dd>
Normalizes a vector with two elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of two floats |
</dd>
<dt>See Also</dt><dd>
[dotv2], [lenv2], [scalev2], [negv2], [addv2], [subv2], [mulv2], [divv2], [clampv2], [lerpv2]
</dd>
</dl>
<hr>
## dotv3

```c
float dotv3(addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Calculates dot product of two vectors with three elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of three floats |
| b | address of three floats |
</dd>
<dt>Return Value</dt><dd>
Dot product of the vectors.
</dd>
<dt>See Also</dt><dd>
[lenv3], [scalev3], [negv3], [addv3], [subv3], [mulv3], [divv3], [crossv3], [clampv3], [lerpv3], [normv3]
</dd>
</dl>
<hr>
## lenv3

```c
float lenv3(addr_t a)
```
<dl>
<dt>Description</dt><dd>
Calculates the length of a vector with three elements. This is slow, try to avoid (see [normv3]).
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of three floats |
</dd>
<dt>Return Value</dt><dd>
Length of the vector.
</dd>
<dt>See Also</dt><dd>
[dotv3], [scalev3], [negv3], [addv3], [subv3], [mulv3], [divv3], [crossv3], [clampv3], [lerpv3], [normv3]
</dd>
</dl>
<hr>
## scalev3

```c
void scalev3(addr_t a, float s)
```
<dl>
<dt>Description</dt><dd>
Scales a vector with three elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of three floats |
| s | scaler value |
</dd>
<dt>See Also</dt><dd>
[dotv3], [lenv3], [negv3], [addv3], [subv3], [mulv3], [divv3], [crossv3], [clampv3], [lerpv3], [normv3]
</dd>
</dl>
<hr>
## negv3

```c
void negv3(addr_t a)
```
<dl>
<dt>Description</dt><dd>
Negates a vector with three elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of three floats |
</dd>
<dt>See Also</dt><dd>
[dotv3], [lenv3], [scalev3], [addv3], [subv3], [mulv3], [divv3], [crossv3], [clampv3], [lerpv3], [normv3]
</dd>
</dl>
<hr>
## addv3

```c
void addv3(addr_t dst, addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Adds together vectors with three elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of three floats |
| a | address of three floats |
| b | address of three floats |
</dd>
<dt>See Also</dt><dd>
[dotv3], [lenv3], [scalev3], [negv3], [subv3], [mulv3], [divv3], [crossv3], [clampv3], [lerpv3], [normv3]
</dd>
</dl>
<hr>
## subv3

```c
void subv3(addr_t dst, addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Subtracts vectors with three elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of three floats |
| a | address of three floats |
| b | address of three floats |
</dd>
<dt>See Also</dt><dd>
[dotv3], [lenv3], [scalev3], [negv3], [addv3], [mulv3], [divv3], [crossv3], [clampv3], [lerpv3], [normv3]
</dd>
</dl>
<hr>
## mulv3

```c
void mulv3(addr_t dst, addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Multiplies vectors with three elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of three floats |
| a | address of three floats |
| b | address of three floats |
</dd>
<dt>See Also</dt><dd>
[dotv3], [lenv3], [scalev3], [negv3], [addv3], [subv3], [divv3], [crossv3], [clampv3], [lerpv3], [normv3]
</dd>
</dl>
<hr>
## divv3

```c
void divv3(addr_t dst, addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Divides vectors with three elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of three floats |
| a | address of three floats |
| b | address of three floats |
</dd>
<dt>See Also</dt><dd>
[dotv3], [lenv3], [scalev3], [negv3], [addv3], [subv3], [mulv3], [crossv3], [clampv3], [lerpv3], [normv3]
</dd>
</dl>
<hr>
## crossv3

```c
void crossv3(addr_t dst, addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Calculates cross product of vectors with three elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of three floats |
| a | address of three floats |
| b | address of three floats |
</dd>
<dt>See Also</dt><dd>
[dotv3], [lenv3], [scalev3], [negv3], [addv3], [subv3], [mulv3], [divv3], [clampv3], [lerpv3], [normv3]
</dd>
</dl>
<hr>
## clampv3

```c
void clampv3(addr_t dst, addr_t v, addr_t minv, addr_t maxv)
```
<dl>
<dt>Description</dt><dd>
Clamps vectors with three elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of three floats |
| v | address of three floats, input |
| minv | address of three floats, minimum |
| maxv | address of three floats, maximum |
</dd>
<dt>See Also</dt><dd>
[dotv3], [lenv3], [scalev3], [negv3], [addv3], [subv3], [mulv3], [divv3], [crossv3], [lerpv3], [normv3]
</dd>
</dl>
<hr>
## lerpv3

```c
void lerpv3(addr_t dst, addr_t a, addr_t b, float t)
```
<dl>
<dt>Description</dt><dd>
Linear interpolates vectors with three elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of three floats |
| a | address of three floats |
| b | address of three floats |
| t | interpolation value between 0.0 and 1.0 |
</dd>
<dt>See Also</dt><dd>
[dotv3], [lenv3], [scalev3], [negv3], [addv3], [subv3], [mulv3], [divv3], [crossv3], [clampv3], [normv3]
</dd>
</dl>
<hr>
## normv3

```c
void normv3(addr_t a)
```
<dl>
<dt>Description</dt><dd>
Normalizes a vector with three elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of three floats |
</dd>
<dt>See Also</dt><dd>
[dotv3], [lenv3], [scalev3], [negv3], [addv3], [subv3], [mulv3], [divv3], [crossv3], [clampv3], [lerpv3]
</dd>
</dl>
<hr>
## dotv4

```c
float dotv4(addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Calculates dot product of two vectors with four elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of four floats |
| b | address of four floats |
</dd>
<dt>Return Value</dt><dd>
Dot product of the vectors.
</dd>
<dt>See Also</dt><dd>
[lenv4], [scalev4], [negv4], [addv4], [subv4], [mulv4], [divv4], [clampv4], [lerpv4], [normv4]
</dd>
</dl>
<hr>
## lenv4

```c
float lenv4(addr_t a)
```
<dl>
<dt>Description</dt><dd>
Calculates the length of a vector with four elements. This is slow, try to avoid (see [normv4]).
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of four floats |
</dd>
<dt>Return Value</dt><dd>
Length of the vector.
</dd>
<dt>See Also</dt><dd>
[dotv4], [scalev4], [negv4], [addv4], [subv4], [mulv4], [divv4], [clampv4], [lerpv4], [normv4]
</dd>
</dl>
<hr>
## scalev4

```c
void scalev4(addr_t a, float s)
```
<dl>
<dt>Description</dt><dd>
Scales a vector with four elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of four floats |
| s | scaler value |
</dd>
<dt>See Also</dt><dd>
[dotv4], [lenv4], [negv4], [addv4], [subv4], [mulv4], [divv4], [clampv4], [lerpv4], [normv4]
</dd>
</dl>
<hr>
## negv4

```c
void negv4(addr_t a)
```
<dl>
<dt>Description</dt><dd>
Negates a vector with four elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of four floats |
</dd>
<dt>See Also</dt><dd>
[dotv4], [lenv4], [scalev4], [addv4], [subv4], [mulv4], [divv4], [clampv4], [lerpv4], [normv4]
</dd>
</dl>
<hr>
## addv4

```c
void addv4(addr_t dst, addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Adds together vectors with four elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of four floats |
| a | address of four floats |
| b | address of four floats |
</dd>
<dt>See Also</dt><dd>
[dotv4], [lenv4], [negv4], [scalev4], [subv4], [mulv4], [divv4], [clampv4], [lerpv4], [normv4]
</dd>
</dl>
<hr>
## subv4

```c
void subv4(addr_t dst, addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Subtracts vectors with four elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of four floats |
| a | address of four floats |
| b | address of four floats |
</dd>
<dt>See Also</dt><dd>
[dotv4], [lenv4], [scalev4], [negv4], [addv4], [mulv4], [divv4], [clampv4], [lerpv4], [normv4]
</dd>
</dl>
<hr>
## mulv4

```c
void mulv4(addr_t dst, addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Multiplies vectors with four elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of four floats |
| a | address of four floats |
| b | address of four floats |
</dd>
<dt>See Also</dt><dd>
[dotv4], [lenv4], [scalev4], [negv4], [addv4], [subv4], [divv4], [clampv4], [lerpv4], [normv4]
</dd>
</dl>
<hr>
## divv4

```c
void divv4(addr_t dst, addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Divides vectors with four elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of four floats |
| a | address of four floats |
| b | address of four floats |
</dd>
<dt>See Also</dt><dd>
[dotv4], [lenv4], [scalev4], [negv4], [addv4], [subv4], [mulv4], [clampv4], [lerpv4], [normv4]
</dd>
</dl>
<hr>
## clampv4

```c
void clampv4(addr_t dst, addr_t v, addr_t minv, addr_t maxv)
```
<dl>
<dt>Description</dt><dd>
Clamps vectors with four elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of four floats |
| v | address of four floats, input |
| minv | address of four floats, minimum |
| maxv | address of four floats, maximum |
</dd>
<dt>See Also</dt><dd>
[dotv4], [lenv4], [scalev4], [negv4], [addv4], [subv4], [mulv4], [divv4], [lerpv4], [normv4]
</dd>
</dl>
<hr>
## lerpv4

```c
void lerpv4(addr_t dst, addr_t a, addr_t b, float t)
```
<dl>
<dt>Description</dt><dd>
Linear interpolates vectors with four elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of four floats |
| a | address of four floats |
| b | address of four floats |
| t | interpolation value between 0.0 and 1.0 |
</dd>
<dt>See Also</dt><dd>
[dotv4], [lenv4], [scalev4], [negv4], [addv4], [subv4], [mulv4], [divv4], [clampv4], [normv4]
</dd>
</dl>
<hr>
## normv4

```c
void normv4(addr_t a)
```
<dl>
<dt>Description</dt><dd>
Normalizes a vector with four elements.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of four floats |
</dd>
<dt>See Also</dt><dd>
[dotv4], [lenv4], [scalev4], [negv4], [addv4], [subv4], [mulv4], [divv4], [clampv4], [lerpv4]
</dd>
</dl>
<hr>
## idq

```c
void idq(addr_t a)
```
<dl>
<dt>Description</dt><dd>
Loads the identity quaternion.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of four floats |
</dd>
<dt>See Also</dt><dd>
[eulerq], [dotq], [lenq], [scaleq], [negq], [addq], [subq], [mulq], [rotq], [lerpq], [slerpq], [normq]
</dd>
</dl>
<hr>
## eulerq

```c
void eulerq(addr_t dst, uint16_t pitch, uint16_t yaw, uint16_t roll)
```
<dl>
<dt>Description</dt><dd>
Loads a quaternion using Euler angles.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of four floats |
| pitch | rotation around X axis in degrees, 0 to 359 |
| yaw | rotation around Y axis in degrees, 0 to 359 |
| roll | rotation around Z axis in degrees, 0 to 359 |
</dd>
<dt>See Also</dt><dd>
[idq], [dotq], [lenq], [scaleq], [negq], [addq], [subq], [mulq], [rotq], [lerpq], [slerpq], [normq]
</dd>
</dl>
<hr>
## dotq

```c
float dotq(addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Calculates dot product of a quaternion.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of four floats |
| b | address of four floats |
</dd>
<dt>Return Value</dt><dd>
Dot product of the quaternion.
</dd>
<dt>See Also</dt><dd>
[idq], [eulerq], [lenq], [scaleq], [negq], [addq], [subq], [mulq], [rotq], [lerpq], [slerpq], [normq]
</dd>
</dl>
<hr>
## lenq

```c
float lenq(addr_t a)
```
<dl>
<dt>Description</dt><dd>
Calculates the length of a quaternion.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of four floats |
</dd>
<dt>Return Value</dt><dd>
Length of the quaternion.
</dd>
<dt>See Also</dt><dd>
[idq], [eulerq], [dotq], [scaleq], [negq], [addq], [subq], [mulq], [rotq], [lerpq], [slerpq], [normq]
</dd>
</dl>
<hr>
## scaleq

```c
void scaleq(addr_t a, float s)
```
<dl>
<dt>Description</dt><dd>
Scales a quaternion.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of four floats |
| s | scaler value |
</dd>
<dt>See Also</dt><dd>
[idq], [eulerq], [dotq], [lenq], [negq], [addq], [subq], [mulq], [rotq], [lerpq], [slerpq], [normq]
</dd>
</dl>
<hr>
## negq

```c
void negq(addr_t a)
```
<dl>
<dt>Description</dt><dd>
Negates a quaternion.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of four floats |
</dd>
<dt>See Also</dt><dd>
[idq], [eulerq], [dotq], [lenq], [scaleq], [addq], [subq], [mulq], [rotq], [lerpq], [slerpq], [normq]
</dd>
</dl>
<hr>
## addq

```c
void addq(addr_t dst, addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Adds together quaternions.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of four floats |
| a | address of four floats |
| b | address of four floats |
</dd>
<dt>See Also</dt><dd>
[idq], [eulerq], [dotq], [lenq], [scaleq], [negq], [subq], [mulq], [rotq], [lerpq], [slerpq], [normq]
</dd>
</dl>
<hr>
## subq

```c
void subq(addr_t dst, addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Subtracts quaternions.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of four floats |
| a | address of four floats |
| b | address of four floats |
</dd>
<dt>See Also</dt><dd>
[idq], [eulerq], [dotq], [lenq], [scaleq], [negq], [addq], [mulq], [rotq], [lerpq], [slerpq], [normq]
</dd>
</dl>
<hr>
## mulq

```c
void mulq(addr_t dst, addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Multiplies quaternions.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of four floats |
| a | address of four floats |
| b | address of four floats |
</dd>
<dt>See Also</dt><dd>
[idq], [eulerq], [dotq], [lenq], [scaleq], [negq], [addq], [subq], [rotq], [lerpq], [slerpq], [normq]
</dd>
</dl>
<hr>
## rotq

```c
void rotq(addr_t dst, addr_t q, addr_t v)
```
<dl>
<dt>Description</dt><dd>
Rotates a vector with three elements by a quaternion.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of three floats |
| q | address of four floats |
| v | address of three floats |
</dd>
<dt>See Also</dt><dd>
[idq], [eulerq], [dotq], [lenq], [scaleq], [negq], [addq], [subq], [mulq], [lerpq], [slerpq], [normq]
</dd>
</dl>
<hr>
## lerpq

```c
void lerpq(addr_t dst, addr_t a, addr_t b, float t)
```
<dl>
<dt>Description</dt><dd>
Linear interpolates two quaternions.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of four floats |
| a | address of four floats |
| b | address of four floats |
| t | interpolation value between 0.0 and 1.0 |
</dd>
<dt>See Also</dt><dd>
[idq], [eulerq], [dotq], [lenq], [scaleq], [negq], [addq], [subq], [mulq], [rotq], [slerpq], [normq]
</dd>
</dl>
<hr>
## slerpq

```c
void slerpq(addr_t dst, addr_t a, addr_t b, float t)
```
<dl>
<dt>Description</dt><dd>
Spherical interpolates a quaternion.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of four floats |
| a | address of four floats |
| b | address of four floats |
| t | interpolation value between 0.0 and 1.0 |
</dd>
<dt>See Also</dt><dd>
[idq], [eulerq], [dotq], [lenq], [scaleq], [negq], [addq], [subq], [mulq], [rotq], [lerpq], [normq]
</dd>
</dl>
<hr>
## normq

```c
void normq(addr_t a)
```
<dl>
<dt>Description</dt><dd>
Normalizes a quaternion.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of four floats |
</dd>
<dt>See Also</dt><dd>
[idq], [eulerq], [dotq], [lenq], [scaleq], [negq], [addq], [subq], [mulq], [rotq], [lerpq], [slerpq]
</dd>
</dl>
<hr>
## idm4

```c
void idm4(addr_t a)
```
<dl>
<dt>Description</dt><dd>
Loads a 4 x 4 identity matrix.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of 16 floats |
</dd>
<dt>See Also</dt><dd>
[trsm4], [detm4], [addm4], [subm4], [mulm4], [mulm4v3], [mulm4v4], [invm4], [trpm4]
</dd>
</dl>
<hr>
## trsm4

```c
void trsm4(addr_t dst, addr_t t, addr_t r, addr_t s)
```
<dl>
<dt>Description</dt><dd>
Creates a 4 x 4 matrix with translation, rotation and scaling.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of 16 floats, destination matrix |
| t | address of three floats, translation vector |
| r | address of four floats, rotation quaternion |
| s | address of three floats, scaling vector |
</dd>
<dt>See Also</dt><dd>
[idm4], [detm4], [addm4], [subm4], [mulm4], [mulm4v3], [mulm4v4], [invm4], [trpm4]
</dd>
</dl>
<hr>
## detm4

```c
float detm4(addr_t a)
```
<dl>
<dt>Description</dt><dd>
Returns the matrix's determinant.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| a | address of 16 floats |
</dd>
<dt>Return Value</dt><dd>
The matrix's determinant.
</dd>
<dt>See Also</dt><dd>
[idm4], [trsm4], [addm4], [subm4], [mulm4], [mulm4v3], [mulm4v4], [invm4], [trpm4]
</dd>
</dl>
<hr>
## addm4

```c
void addm4(addr_t dst, addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Adds matrices together.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of 16 floats |
| a | address of 16 floats |
| b | address of 16 floats |
</dd>
<dt>See Also</dt><dd>
[idm4], [trsm4], [detm4], [subm4], [mulm4], [mulm4v3], [mulm4v4], [invm4], [trpm4]
</dd>
</dl>
<hr>
## subm4

```c
void subm4(addr_t dst, addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Subtracts matrices.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of 16 floats |
| a | address of 16 floats |
| b | address of 16 floats |
</dd>
<dt>See Also</dt><dd>
[idm4], [trsm4], [detm4], [addm4], [mulm4], [mulm4v3], [mulm4v4], [invm4], [trpm4]
</dd>
</dl>
<hr>
## mulm4

```c
void mulm4(addr_t dst, addr_t a, addr_t b)
```
<dl>
<dt>Description</dt><dd>
Multiplies matrices.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of 16 floats |
| a | address of 16 floats |
| b | address of 16 floats |
</dd>
<dt>See Also</dt><dd>
[idm4], [trsm4], [detm4], [addm4], [subm4], [mulm4v3], [mulm4v4], [invm4], [trpm4]
</dd>
</dl>
<hr>
## mulm4v3

```c
void mulm4v3(addr_t dst, addr_t m, addr_t v)
```
<dl>
<dt>Description</dt><dd>
Multiplies a vector with three elements by a matrix.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of three floats |
| m | address of 16 floats |
| v | address of three floats |
</dd>
<dt>See Also</dt><dd>
[idm4], [trsm4], [detm4], [addm4], [subm4], [mulm4], [mulm4v4], [invm4], [trpm4]
</dd>
</dl>
<hr>
## mulm4v4

```c
void mulm4v4(addr_t dst, addr_t m, addr_t v)
```
<dl>
<dt>Description</dt><dd>
Multiplies a vector with four elements by a matrix.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of four floats |
| m | address of 16 floats |
| v | address of four floats |
</dd>
<dt>See Also</dt><dd>
[idm4], [trsm4], [detm4], [addm4], [subm4], [mulm4], [mulm4v3], [invm4], [trpm4]
</dd>
</dl>
<hr>
## invm4

```c
void invm4(addr_t dst, addr_t a)
```
<dl>
<dt>Description</dt><dd>
Calculates inverse matrix.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of 16 floats |
| a | address of 16 floats |
</dd>
<dt>See Also</dt><dd>
[idm4], [trsm4], [detm4], [addm4], [subm4], [mulm4], [mulm4v3], [mulm4v4], [trpm4]
</dd>
</dl>
<hr>
## trpm4

```c
void trpm4(addr_t dst, addr_t a)
```
<dl>
<dt>Description</dt><dd>
Transpose matrix.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address of 16 floats |
| a | address of 16 floats |
</dd>
<dt>See Also</dt><dd>
[idm4], [trsm4], [detm4], [addm4], [subm4], [mulm4], [mulm4v3], [mulm4v4], [invm4]
</dd>
</dl>
<hr>
## trns

```c
void trns(addr_t dst, addr_t src, uint8_t num,
    int16_t x, int16_t y, int16_t z,
    uint16_t pitch, uint16_t yaw, uint16_t roll,
    float scale)
```
<dl>
<dt>Description</dt><dd>
Translate a vertex cloud, aka. place a 3D model in [3D space].
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | destination vertices array, 3 x 2 bytes each, X, Y, Z |
| src | source vertices array, 3 x 2 bytes each, X, Y, Z |
| num | number of vertex coordinate triplets in the array |
| x | world X coordinate, -32767 to 32767 |
| y | world Y coordinate, -32767 to 32767 |
| z | world Z coordinate, -32767 to 32767 |
| pitch | rotation around X axis in degrees, 0 to 359 |
| yaw | rotation around Y axis in degrees, 0 to 359 |
| roll | rotation around Z axis in degrees, 0 to 359 |
| scale | scale, use 1.0 to keep original size |
</dd>
<dt>See Also</dt><dd>
[mesh]
</dd>
</dl>

# Memory

## inb

```c
uint8_t inb(addr_t src)
```
<dl>
<dt>Description</dt><dd>
Read in one byte from memory.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| src | address, 0x00000 to 0xBFFFF |
</dd>
<dt>Return Value</dt><dd>
Returns the value at that address.
</dd>
</dl>
<hr>
## inw

```c
uint16_t inw(addr_t src)
```
<dl>
<dt>Description</dt><dd>
Read in a word (two bytes) from memory.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| src | address, 0x00000 to 0xBFFFE |
</dd>
<dt>Return Value</dt><dd>
Returns the value at that address.
</dd>
</dl>
<hr>
## ini

```c
uint32_t ini(addr_t src)
```
<dl>
<dt>Description</dt><dd>
Read in an integer (four bytes) from memory.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| src | address, 0x00000 to 0xBFFFC |
</dd>
<dt>Return Value</dt><dd>
Returns the value at that address.
</dd>
</dl>
<hr>
## outb

```c
void outb(addr_t dst, uint8_t value)
```
<dl>
<dt>Description</dt><dd>
Write out one byte to memory.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address, 0x00000 to 0xBFFFF |
| value | value to set, 0 to 255 |
</dd>
</dl>
<hr>
## outw

```c
void outw(addr_t dst, uint16_t value)
```
<dl>
<dt>Description</dt><dd>
Write out a word (two bytes) to memory.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address, 0x00000 to 0xBFFFE |
| value | value to set, 0 to 65535 |
</dd>
</dl>
<hr>
## outi

```c
void outi(addr_t dst, uint32_t value)
```
<dl>
<dt>Description</dt><dd>
Write out an integer (four bytes) to memory.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | address, 0x00000 to 0xBFFFC |
| value | value to set, 0 to 4294967295 |
</dd>
</dl>
<hr>
## memsave

```c
int memsave(uint8_t overlay, addr_t src, uint32_t size)
```
<dl>
<dt>Description</dt><dd>
Saves memory area to overlay.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| overlay | index of overlay to write to, 0 to 255 |
| src | memory offset to save from, 0x00000 to 0xBFFFF |
| size | number of bytes to save |
</dd>
<dt>Return Value</dt><dd>
Returns 1 on success, 0 on error.
</dd>
<dt>See Also</dt><dd>
[memload]
</dd>
</dl>
<hr>
## memload

```c
int memload(addr_t dst, uint8_t overlay, uint32_t maxsize)
```
<dl>
<dt>Description</dt><dd>
Loads an overlay into the specified memory area.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | memory offset to load to, 0x00000 to 0xBFFFF |
| overlay | index of overlay to read from, 0 to 255 |
| maxsize | maximum number of bytes to load |
</dd>
<dt>Return Value</dt><dd>
Returns the number of bytes actually loaded.
</dd>
<dt>See Also</dt><dd>
[memsave]
</dd>
</dl>
<hr>
## memcpy

```c
void memcpy(addr_t dst, addr_t src, uint32_t len)
```
<dl>
<dt>Description</dt><dd>
Copy memory regions.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | destination address, 0x00000 to 0xBFFFF |
| src | source address, 0x00000 to 0xBFFFF |
| len | number of bytes to copy |
</dd>
</dl>
<hr>
## memset

```c
void memset(addr_t dst, uint8_t value, uint32_t len)
```
<dl>
<dt>Description</dt><dd>
Set memory region to a given value.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | destination address, 0x00000 to 0xBFFFF |
| value | value to set, 0 to 255 |
| len | number of bytes to set |
</dd>
</dl>
<hr>
## memcmp

```c
int memcmp(addr_t addr0, addr_t addr1, uint32_t len)
```
<dl>
<dt>Description</dt><dd>
Compare memory regions.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| addr0 | first address, 0x00000 to 0xBFFFF |
| addr1 | second address, 0x00000 to 0xBFFFF |
| len | number of bytes to compare |
</dd>
<dt>Return Value</dt><dd>
Returns difference, 0 if the two memory region matches.
</dd>
</dl>
<hr>
## deflate

```c
int deflate(addr_t dst, addr_t src, uint32_t len)
```
<dl>
<dt>Description</dt><dd>
Compress a buffer using RFC1950 deflate (zlib).
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | destination address, 0x30000 to 0xBFFFF |
| src | source address, 0x30000 to 0xBFFFF |
| len | number of bytes to compress |
</dd>
<dt>Return Value</dt><dd>
0 or negative on error, otherwise the length of the compressed buffer and compressed data in dst.
</dd>
<dt>See Also</dt><dd>
[inflate]
</dd>
</dl>
<hr>
## inflate

```c
int inflate(addr_t dst, addr_t src, uint32_t len)
```
<dl>
<dt>Description</dt><dd>
Uncompress a buffer with RFC1950 deflate (zlib) compressed data.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| dst | destination address, 0x30000 to 0xBFFFF |
| src | source address, 0x30000 to 0xBFFFF |
| len | number of compressed bytes |
</dd>
<dt>Return Value</dt><dd>
0 or negative on error, otherwise the length of the uncompressed buffer and uncompressed data in dst.
</dd>
<dt>See Also</dt><dd>
[deflate]
</dd>
</dl>
<hr>
## time

```c
float time(void)
```
<dl>
<dt>Description</dt><dd>
Returns the number of ticks since power on.
</dd>
<dt>Return Value</dt><dd>
The elapsed time in milliseconds since power on.
</dd>
<dt>See Also</dt><dd>
[now]
</dd>
</dl>
<hr>
## now

```c
uint32_t now(void)
```
<dl>
<dt>Description</dt><dd>
Returns the UNIX timestamp. Check the byte at offset 0000C to see if it overflows.
</dd>
<dt>Return Value</dt><dd>
The elapsed time in seconds since 1 Jan 1970 midnight, Greenwich Mean Time.
</dd>
<dt>See Also</dt><dd>
[time]
</dd>
</dl>
<hr>
## atoi

```c
int atoi(str_t src)
```
<dl>
<dt>Description</dt><dd>
Converts an ASCII decimal string into an integer number.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| src | string address, 0x00000 to 0xBFFFF |
</dd>
<dt>Return Value</dt><dd>
The number value of the string.
</dd>
<dt>See Also</dt><dd>
[itoa], [str], [val]
</dd>
</dl>
<hr>
## itoa

```c
str_t itoa(int value)
```
<dl>
<dt>Description</dt><dd>
Converts an integer number into an ASCII decimal string.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| value | the value, -2147483648 to 2147483647 |
</dd>
<dt>Return Value</dt><dd>
The converted string.
</dd>
<dt>See Also</dt><dd>
[atoi], [str], [val]
</dd>
</dl>
<hr>
## val

```c
float val(str_t src)
```
<dl>
<dt>Description</dt><dd>
Converts an ASCII decimal string into a floating point number.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| src | string address, 0x00000 to 0xBFFFF |
</dd>
<dt>Return Value</dt><dd>
The number value of the string.
</dd>
<dt>See Also</dt><dd>
[itoa], [atoi], [str]
</dd>
</dl>
<hr>
## str

```c
str_t str(float value)
```
<dl>
<dt>Description</dt><dd>
Converts a floating point number into an ASCII decimal string.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| value | the value |
</dd>
<dt>Return Value</dt><dd>
The converted string.
</dd>
<dt>See Also</dt><dd>
[atoi], [itoa], [val]
</dd>
</dl>
<hr>
## sprintf

```c
str_t sprintf(str_t fmt, ...)
```
<dl>
<dt>Description</dt><dd>
Returns a zero terminated UTF-8 string created using format and arguments.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| fmt | [format string] |
| ... | optional arguments |
</dd>
<dt>Return Value</dt><dd>
Constructed string.
</dd>
</dl>
<hr>
## strlen

```c
int strlen(str_t src)
```
<dl>
<dt>Description</dt><dd>
Return the number of bytes in a string (without the terminating zero).
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| src | string address, 0x00000 to 0xBFFFF |
</dd>
<dt>Return Value</dt><dd>
The number of bytes in the string.
</dd>
<dt>See Also</dt><dd>
[mblen]
</dd>
</dl>
<hr>
## mblen

```c
int mblen(str_t src)
```
<dl>
<dt>Description</dt><dd>
Return the number of UTF-8 multi-byte characters in a string (without the terminating zero).
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| src | string address, 0x00000 to 0xBFFFF |
</dd>
<dt>Return Value</dt><dd>
The number of characters in the string.
</dd>
<dt>See Also</dt><dd>
[strlen]
</dd>
</dl>
<hr>
## malloc

```c
addr_t malloc(uint32_t size)
```
<dl>
<dt>Description</dt><dd>
Allocates user memory dynamically.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| size | number of bytes to allocate |
</dd>
<dt>Return Value</dt><dd>
Address of the new allocated buffer or NULL on error.
</dd>
<dt>See Also</dt><dd>
[realloc], [free]
</dd>
</dl>
<hr>
## realloc

```c
addr_t realloc(addr_t addr, uint32_t size)
```
<dl>
<dt>Description</dt><dd>
Resize a previously allocated buffer.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| addr | address of the allocated buffer |
| size | number of bytes to resize to |
</dd>
<dt>Return Value</dt><dd>
Address of the new allocated buffer or NULL on error.
</dd>
<dt>See Also</dt><dd>
[malloc], [free]
</dd>
</dl>
<hr>
## free

```c
int free(addr_t addr)
```
<dl>
<dt>Description</dt><dd>
Frees dynamically allocated user memory.
</dd>
<dt>Parameters</dt><dd>
| Argument | Description |
| addr | address of the allocated buffer |
</dd>
<dt>Return Value</dt><dd>
1 on success, 0 on error.
</dd>
<dt>See Also</dt><dd>
[malloc], [realloc]
</dd>
</dl>
