Blog/content/posts/2022/tic80/learn.md

592 lines
29 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "Learn"
date: 2022-12-23T22:30:44+03:00
draft: false
tags: [gamedev, hardware, tic80]
---
# TIC-80 tiny computer
1.0.2164 (b09c50c)
https://tic80.com (C) 2017-2022
## Добро пожаловать
Это мой вольный перевод страницы https://tic80.com/learn с официального сайта.
Так сказать «для себя».
TIC-80 — это [фэнтезийный](https://en.wikipedia.org/wiki/Fantasy_video_game_console)
компьютер (игровая консоль), с помощью которой можно создавать, играть и делиться маленькими играми.
Она имеет встроенные инструменты для разработки:
* редактор кода
* редактор спрайтов
* редактор карт
* звуковой редактор
* командную строку
Используя эти инструменты в конечном счёте ты получишь файл картриджа,
который можно сохранить и даже воспроизвести на сайте.
Картридж можно запаковать в плеер, который будет работать на всех популярных платформах.
Чтобы игра была в стиле ретро, мощности компьютера были искуственно ограничены.
## Спецификация
```text
ДИСПЛЕЙ 240x136 пикселей, цветовая палитра из 16 цветов.
ВВОД 4 геймпада с 8 кнопками / мышь / клавиатура.
СПРАЙТЫ 256 тайлов размером 8x8 и 256 спрайтов размером 8x8.
КАРТЫ 240x136 клеток, размер 1920x1088 пикселей.
ЗВУК 4 канала с настраиваемыми сигналами.
КОД 64KB на lua, ruby, js, moon, fennel, squirrel, wren or wasm.
```
```text
+-----------------------------------+
| 96KB RAM LAYOUT |
+-------+-------------------+-------+
| ADDR | INFO | BYTES |
+-------+-------------------+-------+
| 00000 | <VRAM> | 16384 |
| 04000 | TILES | 8192 |
| 06000 | SPRITES | 8192 |
| 08000 | MAP | 32640 |
| 0FF80 | GAMEPADS | 4 |
| 0FF84 | MOUSE | 4 |
| 0FF88 | KEYBOARD | 4 |
| 0FF8C | SFX STATE | 16 |
| 0FF9C | SOUND REGISTERS | 72 |
| 0FFE4 | WAVEFORMS | 256 |
| 100E4 | SFX | 4224 |
| 11164 | MUSIC PATTERNS | 11520 |
| 13E64 | MUSIC TRACKS | 408 |
| 13FFC | MUSIC STATE | 4 |
| 14000 | STEREO VOLUME | 4 |
| 14004 | PERSISTENT MEMORY | 1024 |
| 14404 | SPRITE FLAGS | 512 |
| 14604 | FONT | 1016 |
| 149FC | FONT PARAMS | 8 |
| 14A04 | ALT FONT | 1016 |
| 14DFC | ALT FONT PARAMS | 8 |
| 14E04 | BUTTONS MAPPING | 32 |
| 14E24 | ... (free) | 12764 |
+-------+-------------------+-------+
```
```text
+-----------------------------------+
| 16KB VRAM LAYOUT |
+-------+-------------------+-------+
| ADDR | INFO | BYTES |
+-------+-------------------+-------+
| 00000 | SCREEN | 16320 |
| 03FC0 | PALETTE | 48 |
| 03FF0 | PALETTE MAP | 8 |
| 03FF8 | BORDER COLOR | 1 |
| 03FF9 | SCREEN OFFSET | 2 |
| 03FFB | MOUSE CURSOR | 1 |
| 03FFC | BLIT SEGMENT | 1 |
| 03FFD | ... (reserved) | 3 |
+-------+-------------------+-------+
```
## Консольные команды
### `cd` — изменение директории
Использование:
```text
cd <path>
cd /
cd ..
```
### `cls` — оичстить экран консоли
Использование: `cls`
### `config` — изменение системных настроек картриджа
используй параметр `reset` для сброса текущей конфигурации,
используй параметр `default` для редактирования стандартного шаблока картриджа.
Использование: `config [reset|default]`
### `del` — удалить из файловой системы
Использование: `del <file|folder>`
### `demo` — Установить демонстрационный картридж в текущую директорию
Использование: `demo`
### `dir` — показать список файлов
Использование: `dir`
### `edit` — открыть редактор картриджа
Использование: `edit`
### `eval` — запустить код
Использование: `eval`
### `exit` — выйти из приложения
Использование: `exit`
### `export` — экспортировать ...
картридж в HTML, создать нативную сборку для Windows/Linux/Mac/RPI,
экстпортиротвать спрайты/карту/... в .png файл
или эскпортировать звуки и музыку в .wav файл.
Использование:
```text
export [win|winxp|linux|rpi|mac|html|binary|tiles|sprites|map|mapimg|sfx|music|screen|help|...]
<file> [bank=0 vbank=0 id=0 ...]
```
### `folder` — открыть кабочий каталог в ОС
Использование: `folder`
### `help` — показать справочную информацию о командах, API, etc
Использование:
```text
help [<text>|version|welcome|spec|ram|vram|commands|api|keys|buttons|startup|terms|license]
```
### `import` — импортировать код/спрайты/карту/... из внешего файла
Использование:
```text
import [binary|tiles|sprites|map|code|screen|...]
<file> [bank=0 x=0 y=0 w=0 h=0 vbank=0 ...]
```
### `load` — загрузить картридж из локального файла
Расширение `.tic` указывать не нужно.
Ты можешь также загружать отдельные секции из картриджа,
например спрайты, карты.
Использование:
```text
load <cart> [code|tiles|sprites|map|sfx|music|palette|flags|screen]
```
### `menu` — показать игровое меню...
где можно настроить параметры видео, звука и ввода.
Использование: `menu`
### `mkdir` — создать директорию
Использование: `mkdir <name>`
### `new` — создать новый `Hello World` картридж
Использование:
```text
new <lua|ruby|js|moon|fennel|squirrel|wren|wasm>
```
### `resume` — вернуться к последнему картриджу или проекту
Использование: `resume`
### `run` — запустить текущий картридж или проект
Использование: `run`
### `save` — сохранить картридж на локальном диске
Используй `.lua` `.rb` `.js` `.moon` `.fnl` `.nut` `.wren` `.wasmp`
расширения, для сохранения картиджа в текстовом формате **(PRO feature)**.
Использование: `save <cart>`
### `surf` — открыть каталог картриджей
Использование: `surf`
## Функции API
### `BDR(row)`
Позволяет выполнять код между рисованием каждой строки полноэкранного сканирования,
например, для управления палитрой.
### `BOOT`
Стартоая функция.
### `MENU(index)`
Обработчик игрового меню.
### `SCN(row)`
Позволяет выполнять код между отрисовкой каждой строки развертки,
например, для управления палитрой.
### `TIC()`
Основная функция. Она вызывается со скоростью 60 кадров в секунду (60 раз в секунду).
### `btn(id) -> pressed`
Эта функция позволяет прочитать состояние одной из кнопок, прикрепленных к TIC.
Функция возвращает `true`, если клавиша с указаным `id`
в данный момент находится в нажатом состоянии.
Функция будет возвращать `true` до тех пор, пока клавиша удерживается нажатой.
Если необходимо проверить, была ли только что нажата клавиша,
используй вместо этого `btnp()`.
### `btnp(id hold=-1 period=-1) -> pressed`
Эта функция позволяет прочитать состояние одной из кнопок TIC.
Функция возвращает `true`, только если клавиша была нажата с момента последнего кадра.
Можете использовать дополнительные параметры `hold` (удержания)
и `period` (периода), которые позволяют проверить, удерживается ли кнопка.
По истечении времени, указанного для удержания,
`btnp` будет возвращать значение `true` каждый раз,
когда проходит период времени, если клавиша все ещё нажата.
Например, чтобы повторно проверять через 2 секунды состояние кнопки `0`
и продолжать проверять её состояние каждую 1/10 секунды,
нужно использовать `btnp(0, 120, 6)`.
Поскольку время выражается в тиках, а TIC-80 работает со скоростью 60 кадров в секунду,
то используем значение 120 для ожидания 2 секунд и 6 тиков (т.е. 60/10)
в качестве интервала повторной проверки.
### `circ(x y radius color)`
Эта функция рисует закрашенный круг нужного радиуса и цвета с центром в точках `x`, `y`.
Для отрисовки используется алгоритм Брезенхэма.
### `circb(x y radius color)`
Рисует окружность круга с центром в точках `x`, `y`, используя указанные радиус и цвет.
Для отрисовки используется алгоритм Брезенхэма.
### `clip(x y width height)` | `clip()`
Эта функция ограничивает отрисовку областью отсечения
или областью `viewport`, определяемой параметрами `x`, `y`, `w`, `h`.
Вещи, нарисованные за пределами этой области, не будут видны.
Вызов `clip()` без параметров сбросит область рисования на весь экран.
### `cls(color=0)`
Очистка экрана.
При вызове этой функции очищается весь экран, используя цвет, указанный в качестве аргумента.
Если параметр не передается, используется первый цвет (0).
### `elli(x y a b color)`
Эта функция рисует заполненный эллипс радиусом, указанным в аргументах `a` и `b`,
цветом (`color`) с центром в точках `x`, `y`.
Для отрисовки используется алгоритм Брезенхэма.
### ellib
`ellib(x y a b color)`
Эта функция рисует границу эллипса радиусом, указанным в аргументах `a` и `b`,
цветом (`color`) с центром в точках `x`, `y`.
Для отрисовки используется алгоритм Брезенхэма.
### `exit()`
Прерывает выполнение программы и возвращает к консоли, когда функция завершается.
### `fget(sprite_id flag) -> bool`
Возвращает `true`, если установлен указанный флаг спрайта.
Смотри `fset()` для более подробной информации.
### `font(text x y chromakey char_width char_height fixed=false scale=1) -> width`
Печатает строку со шрифтом, определенным в спрайтах переднего плана (_foreground sprites_).
Чтобы просто распечатать на экране, проверьте `print()`.
Чтобы вывести на консоль, проверьте `trace()`.
### `fset(sprite_id flag bool)`
У каждого спрайта есть восемь флагов,
которые можно использовать для хранения информации
или сигнализации о различных условиях.
Например, флаг `0` может использоваться для указания того,
что спрайт невидим, а флаг `6` может указывать на то,
что флаг должен масштабироваться и т. д.
Смотри алгоритм `fget()`.
### `key(code=-1) -> pressed`
Функция возвращает `true`, если нажата клавиша, указанная аргументов `code`.
### `keyp(code=-1 hold=-1 period=-1) -> pressed`
Эта функция возвращает `true`, если клавиша нажата,
но не была нажата в предыдущем кадре.
Смотри `btnp()` для объяснения необязательных параметров удержания и периода.
### `line(x0 y0 x1 y1 color)`
Рисует прямую линию от точки `x0:y0` до точки `x1:y1` указанного цвета.
### `map(x=0 y=0 w=30 h=17 sx=0 sy=0 colorkey=-1 scale=1 remap=nil)`
Карта состоит из ячеек 8х8 пикселей, каждую из которых можно заполнить спрайтом с помощью редактора карт.
Карта может иметь до 240 ячеек в ширину и 136 в глубину.
Эта функция отрисовывает нужную область карты в указанную позицию на экране.
Например, `map(5, 5, 12, 10, 0, 0)` отобразит участок карты размером 12x10 ячеек,
начиная с координат карты `(5, 5)` и заканчивая положением на экране `(0, 0)`.
Последний аргумент функции `map()` — это мощная callback функция
для изменения способа отображения ячеек карты (спрайтов) при вызове карты.
Его можно использовать для вращения, отражения и замены спрайтов во время игры.
В отличие от `mset`, который сохраняет изменения на карте,
эту специальную функцию можно использовать для создания анимированных тайлов
или полной их замены.
Некоторые примеры включают изменение спрайтов для открытия дверных проемов,
скрытие спрайтов, используемых для создания объектов в вашей игре,
и даже для спавна самих объектов.
Тайловая карта размещается последовательно в ОЗУ — запись 1 в `0x08000` приведет к тому,
что тайл (спрайт) #1 появится вверху слева при вызове `map()`.
Чтобы установить тайл сразу под ним, нам нужно написать `0x08000 + 240`, т.е. `0x080F0`.
### `memcpy(dest source size)`
Эта функция позволяет копировать непрерывный блок ОЗУ TIC-80
объемом 96 КБ с одного адреса на другой.
Адреса указываются в шестнадцатеричном формате, значения в десятичном.
### `memset(dest value size)`
Эта функция позволяет вам установить непрерывный блок любой части ОЗУ
TIC-80 на одно и то же значение.
Адреса указываются в шестнадцатеричном формате, значения в десятичном.
### `mget(x y) -> tile_id`
Получает идентификатор спрайта по заданным координатам карты `x` и `y`.
### `mouse() -> x y left middle right scrollx scrolly`
Функция возвращает координаты мыши и логическое значение
для состояния каждой кнопки мыши.
`true` указывает, что кнопка нажата.
### `mset(x y tile_id)`
Функция изменит тайл по указанным координатам карты.
По умолчанию внесенные изменения сохраняются только во время работы текущей игры.
Чтобы внести постоянные изменения в карту, смотри `sync()`.
Связаные функции: `map()` `mget()` `sync()`.
### `music(track=-1 frame=-1 row=-1 loop=true sustain=false tempo=-1 speed=-1)`
Функция запускает воспроизведение трека, созданного в музыкальном редакторе.
Вызов функции без аргументов остановить музыку.
### `peek(addr bits=8) -> value`
Функция позволяет читать память из TIC-80.
Полезно ли получать доступ к ресурсам, созданным с помощью встроенных инструментов,
таких как спрайты, карты, звуки, данные картриджей?
Никогда не мечтали озвучить спрайт?
Адрес указывается в шестнадцатеричном формате, но значение в десятиричном.
Для записи в адрес памяти используй `poke()`.
`bits` могут быть `1`, `2`, `4`, `8`.
### `peek1(addr) -> value`
Эта функция позволяет считывать однобитовые значения из ОЗУ TIC-80.
Адрес указывается в шестнадцатеричном формате.
### `peek2(addr) -> value`
Эта функция позволяет считывать двухбитовые значения из ОЗУ TIC-80.
Адрес указывается в шестнадцатеричном формате.
### `peek4(addr) -> value`
Эта функция позволяет считывать значения из ОЗУ TIC-80.
Адрес указывается в шестнадцатеричном формате.
Смотри `poke4()` для получения подробной информации о том,
как адресация полубайтов сравнивается с адресацией байтов.
### `pix(x y color)` | `pix(x y) -> color`
This function can read or write pixel color values.
When called with a color parameter, the pixel at the specified coordinates is set to that color.
Calling the function without a color parameter returns the color of the pixel at the specified position.
### pmem
`pmem(index value)
pmem(index) -> value`
This function allows you to save and retrieve data in one of the 256 individual 32-bit slots available in the cartridge's persistent memory.
This is useful for saving high-scores, level advancement or achievements.
The data is stored as unsigned 32-bit integers (from 0 to 4294967295).
Tips:
- pmem depends on the cartridge hash (md5), so don't change your lua script if you want to keep the data.
- Use `saveid:` with a personalized string in the header metadata to override the default MD5 calculation.
This allows the user to update a cart without losing their saved data.
### poke
`poke(addr value bits=8)`
This function allows you to write a single byte to any address in TIC's RAM.
The address should be specified in hexadecimal format, the value in decimal.
`bits` allowed to be 1,2,4,8.
### poke1
`poke1(addr value)`
This function allows you to write single bit values directly to RAM.
The address is often specified in hexadecimal format.
### poke2
`poke2(addr value)`
This function allows you to write two bits values directly to RAM.
The address is often specified in hexadecimal format.
### poke4
`poke4(addr value)`
This function allows you to write directly to RAM.
The address is often specified in hexadecimal format.
For both peek4 and poke4 RAM is addressed in 4 bit segments (nibbles).
Therefore, to access the the RAM at byte address 0x4000
you would need to access both the 0x8000 and 0x8001 nibble addresses.
### print
`print(text x=0 y=0 color=15 fixed=false scale=1 smallfont=false) -> width`
This will simply print text to the screen using the font defined in config.
When set to true, the fixed width option ensures that each character will be printed in a `box` of the same size, so the character `i` will occupy the same width as the character `w` for example.
When fixed width is false, there will be a single space between each character.
Tips:
- To use a custom rastered font, check out `font()`.
- To print to the console, check out `trace()`.
### rect
`rect(x y w h color)`
This function draws a filled rectangle of the desired size and color at the specified position.
If you only need to draw the the border or outline of a rectangle (ie not filled) see `rectb()`.
### rectb
`rectb(x y w h color)`
This function draws a one pixel thick rectangle border at the position requested.
If you need to fill the rectangle with a color, see `rect()` instead.
### reset
`reset()`
Resets the cartridge. To return to the console, see the `exit()`.
### sfx
`sfx(id note=-1 duration=-1 channel=0 volume=15 speed=0)`
This function will play the sound with `id` created in the sfx editor.
Calling the function with id set to -1 will stop playing the channel.
The note can be supplied as an integer between 0 and 95 (representing 8 octaves of 12 notes each) or as a string giving the note name and octave.
For example, a note value of `14` will play the note `D` in the second octave.
The same note could be specified by the string `D-2`.
Note names consist of two characters, the note itself (in upper case) followed by `-` to represent the natural note or `#` to represent a sharp.
There is no option to indicate flat values.
The available note names are therefore: C-, C#, D-, D#, E-, F-, F#, G-, G#, A-, A#, B-.
The `octave` is specified using a single digit in the range 0 to 8.
The `duration` specifies how many ticks to play the sound for since TIC-80 runs at 60 frames per second, a value of 30 represents half a second.
A value of -1 will play the sound continuously.
The `channel` parameter indicates which of the four channels to use. Allowed values are 0 to 3.
The `volume` can be between 0 and 15.
The `speed` in the range -4 to 3 can be specified and means how many `ticks+1` to play each step, so speed==0 means 1 tick per step.
### spr
`spr(id x y colorkey=-1 scale=1 flip=0 rotate=0 w=1 h=1)`
Draws the sprite number index at the x and y coordinate.
You can specify a colorkey in the palette which will be used as the transparent color or use a value of -1 for an opaque sprite.
The sprite can be scaled up by a desired factor. For example, a scale factor of 2 means an 8x8 pixel sprite is drawn to a 16x16 area of the screen.
You can flip the sprite where:
- 0 = No Flip
- 1 = Flip horizontally
- 2 = Flip vertically
- 3 = Flip both vertically and horizontally
When you rotate the sprite, it's rotated clockwise in 90 steps:
- 0 = No rotation
- 1 = 90 rotation
- 2 = 180 rotation
- 3 = 270 rotation
You can draw a composite sprite (consisting of a rectangular region of sprites from the sprite sheet) by specifying the `w` and `h` parameters (which default to 1).
### sync
`sync(mask=0 bank=0 tocart=false)`
The pro version of TIC-80 contains 8 memory banks.
To switch between these banks, sync can be used to either load contents from a memory bank to runtime, or save contents from the active runtime to a bank.
The function can only be called once per frame.If you have manipulated the runtime memory (e.g. by using mset), you can reset the active state by calling sync(0,0,false).
This resets the whole runtime memory to the contents of bank 0.Note that sync is not used to load code from banks; this is done automatically.
### time
`time() -> ticks`
This function returns the number of milliseconds elapsed since the cartridge began execution.
Useful for keeping track of time, animating items and triggering events.
### trace
`trace(message color=15)`
This is a service function, useful for debugging your code.
It prints the message parameter to the console in the (optional) color specified.
Tips:
- The Lua concatenator for strings is .. (two points).
- Use console cls command to clear the output from trace.
### tri
`tri(x1 y1 x2 y2 x3 y3 color)`
This function draws a triangle filled with color, using the supplied vertices.
### trib
`trib(x1 y1 x2 y2 x3 y3 color)`
This function draws a triangle border with color, using the supplied vertices.
### tstamp
`tstamp() -> timestamp`
This function returns the number of seconds elapsed since January 1st, 1970.
Useful for creating persistent games which evolve over time between plays.
### ttri
`ttri(x1 y1 x2 y2 x3 y3 u1 v1 u2 v2 u3 v3 texsrc=0 chromakey=-1 z1=0 z2=0 z3=0)`
It renders a triangle filled with texture from image ram, map ram or vbank.
Use in 3D graphics.
In particular, if the vertices in the triangle have different 3D depth, you may see some distortion.
These can be thought of as the window inside image ram (sprite sheet), map ram or another vbank.
Note that the sprite sheet or map in this case is treated as a single large image, with U and V addressing its pixels directly, rather than by sprite ID.
So for example the top left corner of sprite #2 would be located at u=16, v=0.
### vbank
`vbank(bank) -> prev
vbank() -> prev`
VRAM contains 2x16K memory chips, use vbank(0) or vbank(1) to switch between them.
## Button IDs
```text
+--------+----+----+----+----+
| ACTION | P1 | P2 | P3 | P4 |
+--------+----+----+----+----+
| UP | 0 | 8 | 16 | 24 |
| DOWN | 1 | 9 | 17 | 25 |
| LEFT | 2 | 10 | 18 | 26 |
| RIGHT | 3 | 11 | 19 | 27 |
| A | 4 | 12 | 20 | 28 |
| B | 5 | 13 | 21 | 29 |
| X | 6 | 14 | 22 | 30 |
| Y | 7 | 15 | 23 | 31 |
+--------+----+----+----+----+
```
## Key IDs
```text
+------+-----+ +------+--------------+
| CODE | KEY | | CODE | KEY |
+------+-----+ +------+--------------+
| 1 | A | | 37 | MINUS |
| 2 | B | | 38 | EQUALS |
| 3 | C | | 39 | LEFTBRACKET |
| 4 | D | | 40 | RIGHTBRACKET |
| 5 | E | | 41 | BACKSLASH |
| 6 | F | | 42 | SEMICOLON |
| 7 | G | | 43 | APOSTROPHE |
| 8 | H | | 44 | GRAVE |
| 9 | I | | 45 | COMMA |
| 10 | J | | 46 | PERIOD |
| 11 | K | | 47 | SLASH |
| 12 | L | | 48 | SPACE |
| 13 | M | | 49 | TAB |
| 14 | N | | 50 | RETURN |
| 15 | O | | 51 | BACKSPACE |
| 16 | P | | 52 | DELETE |
| 17 | Q | | 53 | INSERT |
| 18 | R | | 54 | PAGEUP |
| 19 | S | | 55 | PAGEDOWN |
| 20 | T | | 56 | HOME |
| 21 | U | | 57 | END |
| 22 | V | | 58 | UP |
| 23 | W | | 59 | DOWN |
| 24 | X | | 60 | LEFT |
| 25 | Y | | 61 | RIGHT |
| 26 | Z | | 62 | CAPSLOCK |
| 27 | 0 | | 63 | CTRL |
| 28 | 1 | | 64 | SHIFT |
| 29 | 2 | | 65 | ALT |
| 30 | 3 | | | |
| 31 | 4 | | | |
| 32 | 5 | | | |
| 33 | 6 | | | |
| 34 | 7 | | | |
| 35 | 8 | | | |
| 36 | 9 | | | |
+------+-----+ +------+--------------+
```
## Параметры запуска
```text
--skip skip startup animation
--volume=<int> global volume value [0-15]
--cli console only output
--fullscreen enable fullscreen mode
--vsync enable VSYNC
--soft use software rendering
--fs=<str> path to the file system folder
--scale=<int> main window scale
--cmd=<str> run commands in the console
--keepcmd re-execute commands on every run
--version print program version
--crt enable CRT monitor effect
```