BearLibTerminal — различия между версиями

Материал из Клуб любителей рогаликов
Перейти к: навигация, поиск
(Nim)
 
(не показано 16 промежуточных версий 3 участников)
Строка 1: Строка 1:
 +
__NOTOC__
 
BearLibTerminal — это небольшая (в интерфейсном плане) библиотека для организации терминал-подобного окна, вывода текста, обработки простого ввода.  
 
BearLibTerminal — это небольшая (в интерфейсном плане) библиотека для организации терминал-подобного окна, вывода текста, обработки простого ввода.  
  
Строка 4: Строка 5:
  
 
Достойными внимания особенностями терминала являются:
 
Достойными внимания особенностями терминала являются:
 +
* Легкость использования Unicode.
 +
* Использование тайловых (в виде картинки) и векторных (TrueType) шрифтов.
 +
* Расширенный вывод символов: композиция, центрирование, смещение.
 
* Высокая скорость вывода (в основе лежит OpenGL).
 
* Высокая скорость вывода (в основе лежит OpenGL).
* Возможность использования тайловых (в виде картинки) и векторных (TrueType) шрифтов.
+
* Поддержка как клавиатуры, так и мыши.
* Легкость использования Unicode.
+
* Сборки под Windows, Linux и OS X.
* Полная TrueColor палитра.
+
* Привязки к нескольким языкам: С/С++, C#, Lua, Pascal, Python, Ruby.
* Возможность комбинации нескольких символов в одном знакоместе.
 
* Поддержка ввода с клавиатуры и мыши.
 
  
 
BearLibTerminal не является:
 
BearLibTerminal не является:
Строка 15: Строка 17:
 
* Графическим движком общего назначения: функциональность библиотеки сознательно ограничивается функциональностью псевдотерминала ''(спорное утверждение для версий 0.9+)''.
 
* Графическим движком общего назначения: функциональность библиотеки сознательно ограничивается функциональностью псевдотерминала ''(спорное утверждение для версий 0.9+)''.
  
Похожие инструменты: [[Tinycurses]], [[libtcod]].
+
Похожие инструменты: [[Tinycurses]], [[libtcod]].  
  
Найти библиотеку можно в соответствующей [http://rlgclub.ru/forum/viewtopic.php?f=26&t=851 теме форума] (см. первое сообщение).
+
== Документация ==
<div style="margin-top: 0.5em;">__TOC__</div>
+
Наиболее актуальная документация размещена на сайте библиотеки:
 +
* [http://foo.wyrd.name/ru:bearlibterminal:reference Описание API]
  
== Элементарный пример использования ==
+
== Установка ==
 +
В большинстве случаев нужно взять заголовочный файл/враппер и бинарник динамической библиотеки из архива, который можно скачать [http://foo.wyrd.name/ru:bearlibterminal#скачать на сайте] библиотеки или [http://rlgclub.ru/forum/viewtopic.php?f=26&t=851 по ссылкам] в первом сообщении форума.
  
'''C/C++'''<source lang="cpp">
+
==== C/C++ ====
#include <BearLibTerminal.h>
+
Используется заголовочный файл BearLibTerminal.h
  
TERMINAL_TAKE_CARE_OF_WINMAIN // Но можно и самостоятельно определить WinMain
+
При использовании MSVC приложение линкуется с "интерфейсной библиотекой" BearLibTerminal.lib
  
int main()
+
При использовании MinGW приложение нужно линковать непосредственно с BearLibTerminal.dll (файл .lib содержит лишь перечень функций для MSVC).
{
 
    terminal_open();
 
  
    // Выводим текст
+
При использовании GCC под Linux приложение линкуется с libBearLibTerminal.so
    terminal_printf(1, 1, "Hello, world!");
 
    terminal_refresh();
 
  
    // Ждем, пока пользователь не закроет окно
+
==== C# ====
    while (terminal_read() != VK_CLOSE);
+
Используется враппер BearLibTerminal.cs, который должен быть включен в состав проекта.
  
    terminal_close();
+
==== Nim ====
}
+
Используется враппер [https://github.com/bearlib/terminal-nim BearLibTerminal.nim], который должен быть включен в состав проекта.
</source>
 
== Справка по интерфейсу библиотеки ==
 
BearLibTerminal оформлен в виде динамически подключаемой библиотеки (.dll). Используемое [http://ru.wikipedia.org/wiki/%D0%A1%D0%BE%D0%B3%D0%BB%D0%B0%D1%88%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B2%D1%8B%D0%B7%D0%BE%D0%B2%D0%B0 соглашение вызова] — cdecl.
 
=== terminal_open ===
 
<source lang="cpp">
 
int terminal_open();
 
</source>
 
Для начала работы с библиотекой необходимо вызвать функцию terminal_open. До вызова <code>terminal_open</code> все остальные функции библиотеки мгновенно завершаются, не выполняя никаких действий.
 
<code>terminal_open</code> производит инициализацию терминала со "стандартными" параметрами: размер рабочей области 80x25 ячеек, шрифт Fixedsys Excelsior. Вызов <code>terminal_open</code> не приводит к немедленному выводу окна терминала на экран, окно отображается в момент первого вызова функции <code>[[#terminal_refresh]]</code>.
 
=== terminal_close ===
 
<source lang="cpp">
 
void terminal_close();
 
</source>
 
Симметричный <code>terminal_open</code> вызов, закрывающий терминал и освобождающий используемые библиотекой ресурсы. Поведение программы, не вызвавшей terminal_open перед своим завершением, неопределено.
 
=== terminal_set ===
 
Данная функция представляет собой универсальный способ задания разнообразных настроек библиотеки и описания используемых тайлсетов. Опции задаются в виде строки с группами значений в следующем формате: <code>group1.option1=value1; group1.option2=value2; ...</code> Эта запись может быть сокращена до: <code>group1: [option1=]value1, option2=value2; ...</code> Например:
 
<source lang="cpp">
 
terminal_set("window.size=80x25; window.title='Заголовок'");
 
// То же самое, что и:
 
terminal_set("window: size=80x25, title='Заголовок'");
 
</source>
 
  
Динамическая библиотека предоставляет три варианта для строки из 8, 16 и 32-битных символов: terminal_set8, terminal_set16 и terminal_set32. Детали о разрядности символов должны быть скрыты хедером для конкретного языка программирования с учетом разрядности исрользуемых в языке строк. Например, для С/С++ этот вызов доступен в виде следующих функций:
+
==== Lua ====
<source lang="cpp">
+
Интерфейс для Lua включен непосредственно в библиотеку.
int terminal_set(const char* s);
 
int terminal_wset(const wchar_t* s);
 
</source>
 
Кроме того, хедер для C/C++ предоставляет варианты с printf-подобным форматированием строки: <code>terminal_[w]set[f](...);</code>
 
==== Перечень доступных параметров ====
 
{| class="wikitable"
 
|-
 
|Наименование
 
|Значение по умолчанию
 
|Описание
 
|-
 
|colspan="3" style="background-color: #dddddd;"|''Настройки окна, группа атрибутов '''window'''''
 
|-
 
|size
 
|80x25
 
|Размер окна терминала в знакоместах в формате <ширина>x<высота>.
 
|-
 
|cellsize
 
|auto
 
|Размер ячейки знакоместа, в пикселях в формате <ширина>x<высота> или auto
 
|-
 
|title
 
|BearLibTerminal
 
|Заголовок окна терминала.
 
|-
 
|icon
 
|app.ico
 
|Имя <tt>.ico</tt>-файла с иконкой, которая будет использована для окна.
 
|-
 
|colspan="3" style="background-color: #dddddd;"|''Настройки ввода, группа атрибутов '''input'''''
 
|-
 
|events
 
|keypress
 
|Фильтр событий ввода, комбинация из флагов <tt>none</tt>, <tt>keypress</tt>, <tt>keyrelease</tt>, <tt>mousemove</tt>, <tt>mousescroll</tt>, <tt>all</tt>.
 
|-
 
|nonblocking
 
|false
 
|Если выставлен в true, вызовы terminal_read[_xxx] не приостанавливают выполнение программы, если очередь ввода пуста.
 
|-
 
|precise-mousemove
 
|false
 
|Флаг, указывающий, будет ли считаться движением мыши попиксельное (true) или познакоместное (false) перемещение указателя.
 
|-
 
|sticky-close
 
|true
 
|Если выставлен в false, то по закрытию окна событие VK_CLOSE генерируется однократно. Если выставлен в true, то по закрытию окна terminal_read будет постоянно возвращать VK_CLOSE.
 
|-
 
|cursor-symbol
 
|95 (ASCII 0x5F, подчеркивание)
 
|Код символа, используемого в качестве курсора в terminal_read_str.
 
|-
 
|cursor-blink-rate
 
|500
 
|Скорость мерцания курсора в terminal_read_str, в миллисекундах.
 
|-
 
|colspan="3" style="background-color: #dddddd;"|''Настройки вывода, группа атрибутов '''output'''''
 
|-
 
|postformatting
 
|true
 
|Флаг, включающий или выключающий постформатирование при выводе текста.
 
|-
 
|vsync
 
|true
 
|Флаг, включающий или выключающий вертикальную синхронизацию при отрисовке.
 
|-
 
|colspan="3" style="background-color: #dddddd;"|''Настройки растрового тайлсета, группа атрибутов '''font''' или '''U+xxxx'''''
 
|-
 
|name
 
|
 
|Описательное имя растрового ресурса: имя файла или адрес памяти.
 
|-
 
|size
 
|
 
|Размер одиночного тайла в пикселях в формате <ширина>x<высота>. Необязательный атрибут, если он не указан, считается что все изображение это один тайл.
 
|-
 
|resize
 
|
 
|Размер, до которого нужно переразмерить растровое изображение. Необязательный атрибут.
 
|-
 
|resize-filter
 
|bilinear
 
|Фильтр, который будет использован при переразмерении изображения. Возможные варианты: nearest, bilinear, bicubic.
 
|-
 
|resize-mode
 
|stretch
 
|Режим переразмерения. Возможные варианты: stretch (растянуть), fit (вписать по большей стороне), crop (вписать по меньшей стороне).
 
|-
 
|raw-size
 
|
 
|Размер исходного изображения в случае загрузки из памяти. Если этот атрибут не указан, используется значение атрибута ''size'' (и считается, что все изображение это один тайл).
 
|-
 
|codepage
 
|ascii
 
|Кодовая таблица соответствия отдельных тайлов в тайлсете кодам Unicode. Возможные варианты: ascii, utf8, 437, 866, 1250, 1251 или имя файла с таблицей.
 
|-
 
|align
 
|
 
|Точка отсчета координат для центрирования тайла в ячейке. Возможные значения: center, top-left, top-right, bottom-left, bottom-right. Необязательный атрибут, для тайлсетов из одного тайла (спрайтов) используется top-left, для тайлсетов из нескольких тайлов (шрифтов) используется center.
 
|-
 
|bbox
 
|1x1
 
|Размер логической ячейки, в которой выполняется центрирование тайла, в знакоместах.
 
|-
 
|transparent
 
|
 
|Цвет прозрачного фона для изображений без альфа-канала. Необязательный атрибут (и вообще используйте PNG).
 
|-
 
|colspan="3" style="background-color: #dddddd;"|''Настройки TrueType тайлсета, группа атрибутов '''font''' или '''U+xxxx'''''
 
|-
 
|name
 
|
 
|Имя .ttf-файла шрифта
 
|-
 
|size
 
|
 
|Размер шрифта: либо средняя высота строчного символа в пикселях, либо размер ячейки в пикселях для автоматического подбора размера шрифта.
 
|-
 
|size-reference
 
|@
 
|Необязательный атрибут. Код символа, используемого для оценки/подбора размера шрифта.
 
|-
 
|mode
 
|normal
 
|Режим растеризации. Возможные варианты: <tt>monochrome</tt>, <tt>normal</tt> или <tt>lcd</tt>.
 
|-
 
|codepage
 
|utf-8
 
|Кодовая таблица нестандартного соответствия кодов Юникода и символов шрифта.
 
|-
 
|align
 
|center
 
|Точка отсчета координат для центрирования символа в ячейке. Возможные значения: center, top-left, top-right, bottom-left, bottom-right.
 
|-
 
|bbox
 
|1x1
 
|Размер логической ячейки, в которой выполняется центрирование тайла, в знакоместах.
 
|-
 
|colspan="3" style="background-color: #dddddd;"|''Настройки логгирования, группа атрибутов '''log'''''
 
|-
 
|file
 
|bearlibterminal.log
 
|Имя файла, куда в библиотека будет писать свой лог.
 
|-
 
|level
 
|error
 
|Уровень важности логгирования: <tt>none</tt>, <tt>fatal</tt>, <tt>error</tt>, <tt>warning</tt>, <tt>info</tt>, <tt>debug</tt>, <tt>trace</tt>
 
|-
 
|mode
 
|truncate
 
|Режим ведения лога. Возможные варианты: truncate (начинать файл заново при каждом новом старте) и append (дописывать в конец файла).
 
|}
 
=== terminal_put ===
 
<source lang="cpp">
 
void terminal_put(int x, int y, int code);
 
</source>
 
Одна из основных функций библиотеки, позволяет вывести символ в знакоместо с указанными координатами. В зависимости от выбранного режима смешения, выводимый символ может заменить собой все содержимое указанного знакоместа или быть добавленным поверх уже имеющихся (см. <tt>[[#terminal_composition]]</tt>). Для ячеек первого слоя <tt>terminal_put</tt> применяет цвет фона.
 
=== terminal_put_ext ===
 
<source lang="cpp">
 
void terminal_put_ext(int x, int y, int dx, int dy, int code, color_t* corners);
 
</source>
 
Расширенный вывод символа в ячейку. Позволяет задать смещение в пикселях относительно обычного положения тайла (dx, dy) и индивидуальные цвета углов тайла (corners). Если цвета не заданы (последним аргументом передано 0), то используется текущий цвет, установленный [[#terminal_color]].
 
=== terminal_color ===
 
<source lang="cpp">
 
void terminal_color(color_t color);
 
</source>
 
Устанавливает основной цвет выводимого текста (тайлов). Функция принимает целое беззнаковое 32-битное число, представляющее цвет в формате 0xAARRGGBB. В хедере для C++ имеется перегруженный вариант, принимающий строку с именем цвета.
 
  
См. [[#color_from_argb]], [[#color_from_name]], [[#Постформатирование]].
+
Под Windows достаточно использовать любой динамически собранный интерпретатор Lua, например [https://github.com/rjpcomputing/luaforwindows Lua for Windows]. Вызов <code>require "BearLibTerminal"</code> подгрузит файл BearLibTerminal.dll как бинарный модуль.
=== terminal_bkcolor ===
 
<source lang="cpp">
 
void terminal_bkcolor(color_t color);
 
</source>
 
Аналогичная <code>terminal_color</code> функция, но устанавливающая цвет фона выводимых символов.
 
  
Цвет фона применяется к знакоместам только в первом слое (см. <tt>[[#terminal_layer]]</tt>).
+
Под Linux файл библиотеки имеет имя libBearLibTerminal.so, но так как бинарные модули Lua не имеют префикса lib, придется переименовать его в BearLibTerminal.so
=== terminal_composition ===
 
<source lang="cpp">
 
void terminal_composition(int mode);
 
</source>
 
Функция устанавливает режим наложения тайлов в одной ячейке: <code>TK_COMPOSITION_ON</code> или <code>TK_COMPOSITION_OFF</code>.
 
  
В режиме <code>TK_COMPOSITION_OFF</code> выводимый символ полностью замещает содержимое соответствующего знакоместа, цвет фона устанавливается в выбранный посредством <tt>[[#terminal_bkcolor]]</tt> цвет. Это обычное поведение терминал-подобных приложений.
+
==== FreePascal/Delphi ====
 +
Используется враппер BearLibTerminal.pas, который должен быть включен в состав проекта.
  
В режиме TK_COMPOSITION_ON выводимый символ "накладывается" на уже имеющиеся в ячейке символы, причем каждый отдельный символ в получившейся "стопке" может иметь индивидуальный цвет (и даже индивидуальное смещение и цвета углов, см. [[#terminal_put_ext]]. Таким образом можно комбинировать глифы и/или тайлы для получения более сложных фигур.
+
==== Python ====
=== terminal_layer ===
+
Для Python есть пакеты библиотеки для Windows, Linux и OS X (включающие в себя соответствующий бинарный файл: .dll/.so/.dylib). Поэтому для установки достаточно просто выполнить:
<source lang="cpp">
 
void terminal_layer(int layer);
 
</source>
 
Функция устанавливает текущим слой с указанным номером. Доступны слои с номерами от 0 до 255. Цвет фона у ячеек имеется только у первого слоя, ячейки остальных слоев имеют прозрачный фон. Функция [[#terminal_clear_area]] работает только с текущим слоем, в то время как [[#terminal_clear]] очищает все содержимое сцены, все слои.
 
=== terminal_print ===
 
<source lang="cpp">
 
int terminal_print(int x, int y, const char* s);
 
</source>
 
Аналогично [[#terminal_set]], библиотека предоставляет несколько вариантов функции для строк различной разрядности, но хедер к С/С++ скрывает это и вызов доступен для char* и wchar_t* строк с форматированием и без: <code>terminal_[w]print[f]</code>. В строке, передаваемой в функцию terminal_print могуть присутствовать теги постформатирования, модифицирующие производимый вывод:
 
  
Цвет текста и фона:<br />
+
<code>pip install bearlibterminal</code>
<code>terminal_print(2, 1, "[color=amber]Amber[/color] letters, [bkcolor=darkest gray]gray background[/bkcolor].");</code>
 
  
Произвольный символ:<br />
+
Команда установки может отличаться: для Python3 утилита pip обычно называется pip3, также может быть полезно добавить флаг --user (установка только для текущего пользователя).
<code>terminal_print(2, 1, "Earth rune: [U+E001]");</code>
 
  
Комбинация символов:<br />
+
==== Ruby ====
<code>terminal_print(2, 1, "a[+]^");</code><br />
+
Используется враппер BearLibTerminal.rb, который должен быть включен в состав проекта.
Такой тег комбинирует два тайла как будто бы они были положены в одну ячейку с включенным наложением (TK_COMPOSITION_ON).
 
  
Межсимвольный интервал:<br />
+
== Примеры использования ==
<code>terminal_print(2, 1, "[spacing=2x2]sparse text");</code><br />
+
"Hello, world" на нескольких языках:
Межсимвольный/межстрочный интервал необходим для вывода текста тайлами размером более одного знакоместа.
 
  
Сдвиг кодовой страницы:<br />
+
==== C/C++ ====
<code>terminal_print(2, 1, "[base=0xE000:1251]Русский текст");</code><br />
 
Сдвиг страницы позволяет выводить текст тайлсетом в произвольной кодировке и загруженным по произвольному коду.
 
=== terminal_clear ===
 
 
<source lang="cpp">
 
<source lang="cpp">
void terminal_clear();
+
#include <BearLibTerminal.h>
</source>
+
 
Функция очистки экрана. Содержимое всех ячеек-знакомест во всех слоях удаляется, цвет фона устанавливается в выбранный посредством <tt>[[#terminal_bkcolor]]</tt> цвет.
+
TERMINAL_TAKE_CARE_OF_WINMAIN // Но можно и самостоятельно определить WinMain
=== terminal_clear_area ===
+
 
<source lang="cpp">
+
int main()
void terminal_clear_area(int x, int y, int w, int h);
+
{
</source>
+
  terminal_open();
Функция частичной очистки экрана. Удаляется содержимое ячеек-знакомест в указанной области экрана текущего слоя.
+
 
=== terminal_refresh ===
+
  // Выводим текст
<source lang="cpp">
+
  terminal_printf(1, 1, "Hello, world!");
void terminal_refresh();
+
  terminal_refresh();
</source>
 
Функция обновления экрана. Эта функция должна быть вызвана, чтобы изменения содержимого терминала на самом деле отобразились на экране. Окно терминала выводится на экран при первом вызове <code>terminal_refresh</code>.
 
=== terminal_has_input ===
 
<source lang="cpp">
 
int terminal_has_input();
 
</source>
 
Позволяет узнать, есть ли события в очереди ввода. Возвращает 0, если очередь пуста или 1, если есть непрочитанные события.
 
=== terminal_read ===
 
<source lang="cpp">
 
int terminal_read();
 
</source>
 
Возвращает код следующего событие из очереди ввода.
 
  
Если очередь ввода пуста, поведение зависит от параметра ''input.nonblocking'':
+
  // Ждем, пока пользователь не закроет окно
* ''false'': выполнение программы блокируется до поступления следующего события ввода.
+
  while (terminal_read() != VK_CLOSE);
* ''true'': блокирования выполнения программы не производится, в случае пустой очереди ввода функция немедленно возвращает TK_INPUT_NONE.
 
  
См. [[#Ввод]]
+
  terminal_close();
=== terminal_read_ext ===
+
}
<source lang="cpp">
 
int terminal_read_ext(int flags);
 
 
</source>
 
</source>
Расширенная версия чтения очереди ввода. Параметр ''flags'' может включать в себя следующие флаги:
 
* TK_READ_CHAR: функция пытается выбрать из очереди текстовый символ. В случае, если следующее событие в очереди ввода не порождает текcтовый ввод, возвращается TK_INPUT_CALL_AGAIN, не убирая событие из очереди.
 
* TK_READ_NOREMOVE: функция не убирает прочитанное событие из очереди. Следующий вызов вернет такое же значение.
 
=== terminal_read_str ===
 
<source lang="cpp">
 
int terminal_read_str(int x, int y, char* buffer, int max);
 
int terminal_read_wstr(int x, int y, wchar_t* buffer, int max);
 
</source>
 
Функция чтения текста с клавиатуры с учетом локалей и раскладок пользователя. Набираемые пользователем символы добавляются к строке в буфере <code>buffer</code>, при этом максимальный размер получаемой строки ограничивается <code>max</code> символами.
 
  
Поведение функции сильно зависит от параметра ''input.nonblocking''. Если он равен ''false'' (по умолчанию), то в процессе работы функции ввод полностью обрабатывается терминалом. В это время содержимое строки и курсор ввода отображается в терминале начиная с позиции (<code>x</code>, <code>y</code>). Чтение ввода функцией <code>terminal_read_str</code> в блокирующем режиме производится до:
+
==== Python ====
* Подтверждения ввода (поступления события TK_RETURN). Функция возвращает количество введенных символов (значение больше либо равное нулю).
+
<source lang="python">
* Отмены ввода (поступления события TK_ESCAPE или TK_CLOSE). Функция возвращает TK_INPUT_CANCELLED.
+
from bearlibterminal import terminal
По завершении, <code>terminal_read_str</code> убирает введенную строку и курсор ввода с экрана, восстанавливая предыдущее содержимое использованных ячеек-знакомест.
+
 
 +
terminal.open()
  
Если ''input.nonblocking'' равен ''true'' (неблокирующее чтение), функция <code>terminal_read_str</code> не трогает экран, а только производит чтение доступной очереди ввода. В неблокирующем режиме:
+
# Выводим текст
* По подтверждению ввода (TK_RETURN) функция возвращает количество введенных символов.
+
terminal.printf(2, 1, 'Hello, world!')
* По отмене ввода (TK_ESCAPE или TK_CLOSE) функция возвращает TK_INPUT_CANCELLED.
+
terminal.refresh()
* Если очередь ввода пуста, функция возвращает TK_INPUT_CALL_AGAIN.
 
Задача отрисовки процесса ввода (текст, курсор) ложится на пользователя библиотеки.
 
  
Размер передаваемого в функцию буфера должен быть достаточно большим, чтобы вместить максимально возможную вводимую строку. Так как параметр max указывается в символах, без учета нуль-терминатора, это означает, что для вызова в кодировке UTF-8 (<code>terminal_read_str</code>) буфер должен быть размером не менее max*3+1 (каждый символ может занять до трех байт + нуль-терминатор), а для UTF-16/32 вызова (<code>terminal_read_wstr</code>) -- не менее max+1.
+
# Ждем, пока пользователь не закроет окно
 +
while terminal.read() != terminal.TK_CLOSE:
 +
  pass
  
См. [[#Ввод]]
+
terminal.close()
=== terminal_state ===
 
<source lang="cpp">
 
int terminal_state(int code);
 
 
</source>
 
</source>
Данная функция позволяет получить текущее состояние некоторых переменных терминала. Код переменной берется из перечисления TK_xxx.
 
* Состояние клавиш: коды TK_ESCAPE, TK_0, TK_NUMPAD0, TK_A и т. д. Функция возвращает 1, если клавиша нажата или 0, если отпущена.
 
* Состояние мыши: TK_MOUSE_X и TK_MOUSE_Y (в знакоместах), TK_MOUSE_PIXEL_X, TK_MOUSE_PIXEL_Y (в пикселях), TK_MOUSE_WHEEL (в шагах колесика).
 
* Размеры экрана в знакоместах: TK_WIDTH, TK_HEIGHT.
 
* Размеры знакоместа в пикселях: TK_CELL_WIDTH, TK_CELL_HEIGHT.
 
* Текущие параметры сцены: TK_COMPOSITION, TK_COLOR, TK_BKCOLOR, TK_LAYER.
 
В зависимости от выбранного фильтра событий ввода (''input.events''), состояние клавиш и мыши возвращается не на момент вызова, а соответствующее текущему состоянию очереди ввода. Обновление значений, возвращаемых функцией <code>terminal_state</code>, производится по мере выбора соответствующих событий из очереди ввода посредством <code>terminal_read</code>.
 
 
Например, если пользователь нажмет сочетание клавиш Shift+Z, в очереди ввода оно будет представлено как Shift(нажато), Z(нажато), Z(отпущено), Shift(отпущено). На момент выбора из очереди ввода события о нажатии клавиши Z, состояние клавиши Shift будет точно "нажато", даже если обработка ввода будет произведена несвоевременно и на самом деле клавиша Shift к тому моменту будет уже отпущена. Это позволяет производить проверку нажатия сочетаний клавиш элементарным образом:
 
<source lang="cpp">
 
int code = terminal_read();
 
  
if (code == TK_Z)
+
==== FreePascal/Delphi ====
{
+
<source lang="delphi">
    if (terminal_state(TK_SHIFT))
 
    {
 
        // Нажато Shift+Z
 
    }
 
    else if (terminal_state(TK_CTRL))
 
    {
 
        // Нажато Ctrl+Z
 
    }
 
    else
 
    {
 
        // Нажата просто Z
 
    }
 
}
 
</source>
 
Однако, если событие не попадает под фильтр событий ввода (''input.events''), оно не может быть выбрано из очереди посредством <code>terminal_read</code> и будет обработано автоматически. В пределе, если фильтр равен ''none'', то все события обрабатываются автоматически и <code>terminal_state</code> всегда возвращает текущее (последнее) состояние.
 
=== color_from_argb ===
 
<source lang="cpp">
 
color_t color_from_argb(int a, int r, int g, int b);
 
</source>
 
Простая вспомогательная функция, собирающая из отдельных R, G, B и A компонент одно 32-битное число, которым представляется цвет в библиотеке (0xAARRGGBB).
 
=== color_from_name ===
 
<source lang="cpp">
 
color_t color_from_name(const char* name);
 
</source>
 
Данная функция возвращает цвет (его числовое представление) по имени из встроенной в библиотеку палитры. Эта палитра практически полностью повторяет [http://doryen.eptalys.net/data/libtcod/doc/1.5.2/html2/color.html палитру] из libtcod. Имя указывается в виде "оттенок" или "яркость оттенок", где возможными значениями являются:
 
{| class="wikitable"
 
|-
 
|Яркость
 
|lightest, lighter, light, dark, darker, darkest
 
|-
 
|Оттенок
 
|grey или gray, red, flame, orange, amber, yellow, lime, chartreuse, green, sea, turquoise, cyan, sky, azure, blue, han, violet, purple, fuchsia, magenta, pink, crimson
 
|}
 
Также, по имени цвет можно использовать в тегах ''color'' и ''bkcolor'' функции <code>terminal_printf</code>:
 
<source lang="cpp">
 
terminal_color("lighter gray"); // Основным цветом выбран светло-серый
 
terminal_printf(1, 1, "You see a [color=dark red]glowing[/color] stone."); // Слово glowing будет темно-красным
 
</source>
 
== Ввод ==
 
...
 
== Примеры ==
 
'''FreePascal'''<source lang="pascal">
 
 
uses
 
uses
   BeaRLibTerminal,
+
   BeaRLibTerminal;
  Windows;
 
  
 
begin
 
begin
Строка 407: Строка 115:
  
 
   // Ждем, пока пользователь не закроет окно
 
   // Ждем, пока пользователь не закроет окно
   while (terminal_get() <> TK_CLOSE) do;  
+
   while (terminal_read() <> TK_CLOSE) do;  
 
   
 
   
 
   terminal_close();
 
   terminal_close();
Строка 413: Строка 121:
 
</source>
 
</source>
  
 
+
==== C# ====
'''C#'''<source lang="csharp">
+
<source lang="csharp">
 
using System;
 
using System;
 
using BearLib;
 
using BearLib;
Строка 420: Строка 128:
 
namespace HelloWorld
 
namespace HelloWorld
 
{
 
{
    static class Program
+
  static class Program
 +
  {
 +
    static void Main()
 
     {
 
     {
        static void Main()
+
      Terminal.Open();
        {
 
            Terminal.Open();
 
  
            // Выводим текст
+
      // Выводим текст
            Terminal.Print(1, 1, "Hello, world!");
+
      Terminal.Print(1, 1, "Hello, world!");
            Terminal.Refresh();
+
      Terminal.Refresh();
  
            // Ждем, пока пользователь не закроет окно
+
      // Ждем, пока пользователь не закроет окно
            while (Terminal.Read() != Terminal.Keys.Close);
+
      while (Terminal.Read() != Terminal.Keys.Close);
  
            Terminal.Close();
+
      Terminal.Close();
        }
 
 
     }
 
     }
 +
  }
 
}
 
}
 +
</source>
 +
 +
==== Nim ====
 +
<source lang="nimrod">
 +
import BearLibTerminal
 +
 +
terminal_open()
 +
 +
# Выводим текст
 +
discard terminal_print(1, 1, "Hello, world!")
 +
terminal_refresh()
 +
 +
var key = terminal_read()
 +
 +
# Ждем, пока пользователь не закроет окно
 +
while key != TK_CLOSE and key != TK_ESCAPE:
 +
  key = terminal_read()
 +
 +
terminal_close()
 +
</source>
 +
 +
==== Lua ====
 +
<source lang="lua">
 +
local T = require "BearLibTerminal"
 +
 +
T.open()
 +
-- Выводим текст
 +
T.print(1, 1, "Hello, World!")
 +
T.refresh()
 +
repeat
 +
key = T.read()
 +
-- Ждем, пока пользователь не закроет окно
 +
until key == T.TK_CLOSE or key == T.TK_ESCAPE
 +
T.close()
 
</source>
 
</source>
  
 
[[Category:BeaRLib]]
 
[[Category:BeaRLib]]

Текущая версия на 20:21, 11 сентября 2017

BearLibTerminal — это небольшая (в интерфейсном плане) библиотека для организации терминал-подобного окна, вывода текста, обработки простого ввода.

Большое количество roguelike совершенно осознанно используют аскетичное символьное/псевдографическое оформление. Однако, использование стандартных средств вывода (командной строки ОС) сопряжено с досадными ограничениями скорости вывода, цветовой гаммы, используемого шрифта. Нетривиальной задачей оказывается и применение расширенного набора символов, например нескольких языков и псевдографики. BearLibTerminal позволяет обойти упомянутые ограничения оставаясь в рамках простой концепции "терминала": пользователю предоставляется прямоугольная сетка ячеек-знакомест, средства для вывода текста и чтения ввода с клавиатуры.

Достойными внимания особенностями терминала являются:

  • Легкость использования Unicode.
  • Использование тайловых (в виде картинки) и векторных (TrueType) шрифтов.
  • Расширенный вывод символов: композиция, центрирование, смещение.
  • Высокая скорость вывода (в основе лежит OpenGL).
  • Поддержка как клавиатуры, так и мыши.
  • Сборки под Windows, Linux и OS X.
  • Привязки к нескольким языкам: С/С++, C#, Lua, Pascal, Python, Ruby.

BearLibTerminal не является:

  • Фреймворком roguelike: в библиотеке нет и никогда не будет генераторов случайных чисел, уровней или имен персонажей, механизмов расчета FOV/LOS и освещения, средств для работы с файлами или сетью.
  • Графическим движком общего назначения: функциональность библиотеки сознательно ограничивается функциональностью псевдотерминала (спорное утверждение для версий 0.9+).

Похожие инструменты: Tinycurses, libtcod.

Документация

Наиболее актуальная документация размещена на сайте библиотеки:

Установка

В большинстве случаев нужно взять заголовочный файл/враппер и бинарник динамической библиотеки из архива, который можно скачать на сайте библиотеки или по ссылкам в первом сообщении форума.

C/C++

Используется заголовочный файл BearLibTerminal.h

При использовании MSVC приложение линкуется с "интерфейсной библиотекой" BearLibTerminal.lib

При использовании MinGW приложение нужно линковать непосредственно с BearLibTerminal.dll (файл .lib содержит лишь перечень функций для MSVC).

При использовании GCC под Linux приложение линкуется с libBearLibTerminal.so

C#

Используется враппер BearLibTerminal.cs, который должен быть включен в состав проекта.

Nim

Используется враппер BearLibTerminal.nim, который должен быть включен в состав проекта.

Lua

Интерфейс для Lua включен непосредственно в библиотеку.

Под Windows достаточно использовать любой динамически собранный интерпретатор Lua, например Lua for Windows. Вызов require "BearLibTerminal" подгрузит файл BearLibTerminal.dll как бинарный модуль.

Под Linux файл библиотеки имеет имя libBearLibTerminal.so, но так как бинарные модули Lua не имеют префикса lib, придется переименовать его в BearLibTerminal.so

FreePascal/Delphi

Используется враппер BearLibTerminal.pas, который должен быть включен в состав проекта.

Python

Для Python есть пакеты библиотеки для Windows, Linux и OS X (включающие в себя соответствующий бинарный файл: .dll/.so/.dylib). Поэтому для установки достаточно просто выполнить:

pip install bearlibterminal

Команда установки может отличаться: для Python3 утилита pip обычно называется pip3, также может быть полезно добавить флаг --user (установка только для текущего пользователя).

Ruby

Используется враппер BearLibTerminal.rb, который должен быть включен в состав проекта.

Примеры использования

"Hello, world" на нескольких языках:

C/C++

<source lang="cpp">

  1. include <BearLibTerminal.h>

TERMINAL_TAKE_CARE_OF_WINMAIN // Но можно и самостоятельно определить WinMain

int main() {

 terminal_open();
 // Выводим текст
 terminal_printf(1, 1, "Hello, world!");
 terminal_refresh();
 // Ждем, пока пользователь не закроет окно
 while (terminal_read() != VK_CLOSE); 
 terminal_close();

} </source>

Python

<source lang="python"> from bearlibterminal import terminal

terminal.open()

  1. Выводим текст

terminal.printf(2, 1, 'Hello, world!') terminal.refresh()

  1. Ждем, пока пользователь не закроет окно

while terminal.read() != terminal.TK_CLOSE:

 pass

terminal.close() </source>

FreePascal/Delphi

<source lang="delphi"> uses

 BeaRLibTerminal;

begin

 terminal_open();

 // Выводим текст
 terminal_print(1, 1, 'Hello, world!');
 terminal_refresh();
 // Ждем, пока пользователь не закроет окно
 while (terminal_read() <> TK_CLOSE) do; 

 terminal_close();

end. </source>

C#

<source lang="csharp"> using System; using BearLib;

namespace HelloWorld {

 static class Program
 {
   static void Main()
   {
     Terminal.Open();
     // Выводим текст
     Terminal.Print(1, 1, "Hello, world!");
     Terminal.Refresh();
     // Ждем, пока пользователь не закроет окно
     while (Terminal.Read() != Terminal.Keys.Close);
     Terminal.Close();
   }
 }

} </source>

Nim

<source lang="nimrod"> import BearLibTerminal

terminal_open()

  1. Выводим текст

discard terminal_print(1, 1, "Hello, world!") terminal_refresh()

var key = terminal_read()

  1. Ждем, пока пользователь не закроет окно

while key != TK_CLOSE and key != TK_ESCAPE:

 key = terminal_read()

terminal_close() </source>

Lua

<source lang="lua"> local T = require "BearLibTerminal"

T.open() -- Выводим текст T.print(1, 1, "Hello, World!") T.refresh() repeat key = T.read() -- Ждем, пока пользователь не закроет окно until key == T.TK_CLOSE or key == T.TK_ESCAPE T.close() </source>