BearLibTerminal

Материал из Клуб любителей рогаликов
Перейти к: навигация, поиск

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

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

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

  • Высокая скорость вывода (в основе лежит OpenGL).
  • Возможность использования тайловых (в виде картинки) и векторных (TrueType) шрифтов.
  • Легкость использования Unicode.
  • Полная TrueColor палитра.
  • Возможность комбинации нескольких символов в одном знакоместе.
  • Поддержка ввода с клавиатуры и мыши.

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

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

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

Интерфейс библиотеки

BearLibTerminal оформлен в виде динамически подключаемой библиотеки (.dll), интерфейс которой насчитывает 19 функций. Используемое соглашение вызова — cdecl.

terminal_open

<syntaxhighlight lang="cpp"> int terminal_open(int codepage); </syntaxhighlight> Для начала работы с библиотекой необходимо вызвать функцию terminal_open. Эта функция принимает один параметр -- номер кодировки, которую использует приложение. Подробно о кодировках и их использовании в BearLibTerminal [будет] рассказано в отдельном параграфе. В большинстве случаев подойдет значение по умолчанию, CODEPAGE_DEFAULT. До вызова terminal_open все остальные функции библиотеки мгновенно завершаются, не выполняя никаких действий. Вызов terminal_open не приводит к немедленному выводу окна терминала на экран, окно отображается в момент первого вызова функции #terminal_refresh.

terminal_close

<syntaxhighlight lang="cpp"> void terminal_close(); </syntaxhighlight> Симметричный terminal_open вызов, закрывающий терминал и освобождающий используемые библиотекой ресурсы. Поведение программы, не вызвавшей terminal_open перед своим завершением, неопределено.

terminal_options

<syntaxhighlight lang="cpp"> int terminal_options(const char* options, ...); int terminal_options_noformat(const char* options); </syntaxhighlight> Данная функция представляет собой универсальный способ задания разнообразных настроек библиотеки. Опции задаются в виде строки с парами параметр-значение, разделенными точкой с запятой:
option1=value1; option2=value2; ...

В библиотеке имеются два варианта функции, с суффиксом "noformat" и без. Вариант без суффикса (с переменным числом аргументов) позволяет использовать в С/С++ привычное форматирование передаваемой строки: <syntaxhighlight lang="cpp"> terminal_options("size=%dx%d", width, height); </syntaxhighlight> Вариант с суффиксом "noformat" не производит подобного форматирования и может быть использован при вызове функций из программы, написанной на других языках программирования, предоставляющих собственные механизмы форматирования строк.

Перечень доступных параметров

Наименование Значение по умолчанию Описание
Настройки окна
size 80x25 Размер окна терминала в знакоместах, в формате ШИРИНАxВЫСОТА.
title BearLibTerminal Заголовок окна терминала.
icon app.ico Имя .ico-файла с иконкой, которая будет использована для окна.
Настройки шрифта
font.name default Имя файла шрифта, векторного .ttf или тайлового .bmp/.png
font.size 10 Размер шрифта: высота символа для векторного шрифта, размер одного тайла для тайлового шрифта.
font.mode normal Режим растеризации при использовании векторного шрифта: monochrome, normal или lcd.
font.codepage utf-8 Кодовая страница тайлового шрифта.
Настройки ввода
input.events keypress Фильтр событий ввода, комбинация из флагов none, keypress, keyrelease, mousemove, mousescroll, all.
input.timeout infinite Таймаут ожидания события ввода: infinite, immediate или численное значение в миллисекундах.
input.precise_mousemove false Флаг, указывающий, будет ли считаться движением мыши попиксельное (true) или познакоместное (false) перемещение указателя.
Настройки вывода
output.postformat true Флаг, включающий или выключающий постформатирование при выводе текста.
Настройки логгирования
log.file bearlibterminal.log Имя файла, куда в библиотека будет писать свой лог. Файл не ротируется, логгирование попросту производится в конец указанного файла.
log.level error Уровень важности логгирования: none, fatal, error, warning, info, debug, trace

Настройки окна

<подробно про настройки окна>

Настройки шрифта

<подробно про настройки шрифта>

Настройки ввода

<подробно про настройки ввода>

terminal_put

<syntaxhighlight lang="cpp"> void terminal_put(int x, int y, int code); </syntaxhighlight> Одна из основных функций библиотеки, позволяет вывести символ в знакоместо с указанными координатами.

Диапазон возможных для вывода кодов символов не ограничен выбранной при вызове terminal_open кодировкой (см. #Кодировки).

В зависимости от выбранного режима смешения, выводимый символ может заменить собой все содержимое указанного знакоместа или быть добавленным поверх уже имеющихся (см. #terminal_blending).

terminal_color

<syntaxhighlight lang="cpp"> void terminal_color(color_t color); </syntaxhighlight> Устанавливает основной цвет выводимого текста. Параметром функции является целое беззнаковое 32-битное число, представляющее цвет в формате ARGB, например 0xFFFF0000 -- сплошной красный, 0x800000FF -- полупрозрачный синий.

См. #color_from_argb, #color_from_name, #Постформатирование.

terminal_bkcolor

<syntaxhighlight lang="cpp"> void terminal_bkcolor(color_t color); </syntaxhighlight> Аналогичная terminal_color функция, но устанавливающая цвет фона выводимых символов.

В зависимости от режима смешения, цвет фона может применяется к знакоместу только в случае, если символ является первым в знакоместе (см. #terminal_blending).

terminal_blending

<syntaxhighlight lang="cpp"> void terminal_blending(int mode); </syntaxhighlight> Функция устанавливает режим смешения для вывода символов: BLENDING_NONE или BLENDING_ADDITIVE.

В режиме BLENDING_NONE выводимый символ полностью замещает содержимое соответствующего знакоместа, цвет фона устанавливается в выбранный посредством #terminal_bkcolor цвет. Это обычное поведение терминал-подобных приложений.

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

BearLibTerminal Blending 01.png

terminal_printf

<syntaxhighlight lang="cpp"> size_t terminal_printf(int x, int y, const char* format, ...); size_t terminal_printf_noformat(int x, int y, const char* s); </syntaxhighlight> ...

terminal_clear

<syntaxhighlight lang="cpp"> void terminal_clear(); </syntaxhighlight> Функция очистки экрана. Содержимое всех ячеек-знакомест удаляется, цвет фона устанавливается в выбранный посредством #terminal_bkcolor цвет.

terminal_clear_area

<syntaxhighlight lang="cpp"> void terminal_clear_area(int x, int y, int w, int h); </syntaxhighlight> Функция частичной очистки экрана. Содержимое ячеек-знакомест в указанной области экрана удаляется, цвет фона устанавливается в выбранный посредством #terminal_bkcolor цвет.

terminal_refresh

<syntaxhighlight lang="cpp"> void terminal_refresh(); </syntaxhighlight> Функция обновления экрана. Эта функция должна быть вызвана, чтобы изменения содержимого терминала на самом деле отобразились на экране.

Окно терминала инициализируется и выводится на экран при первом вызове terminal_refresh.

terminal_has_input

<syntaxhighlight lang="cpp"> int terminal_has_input(); </syntaxhighlight> Позволяет узнать, есть ли события в очереди ввода. Возвращает 0, если очередь пуста или 1, если есть непрочитанные события.

См. #Ввод

terminal_get

<syntaxhighlight lang="cpp"> int terminal_get(); </syntaxhighlight> Возвращает код следующего событие из очереди ввода.

Если очередь ввода пуста, поведение зависит от параметра input.timeout:

  • infinite: выполнение программы блокируется до поступления следующего события ввода.
  • N (где N -- некоторое неотрицательное значение): выполнение программы блокируется до поступления события ввода, но не более чем на N миллисекунд, по истечении которых возвращается -1.

Если input.timeout равен нулю, блокирования выполнения программы не производится, в случае пустой очереди ввода функция немедленно возвращает -1.

См. #Ввод

terminal_getstr

<syntaxhighlight lang="cpp"> int terminal_getstr(int x, int y, char* buffer, int max); </syntaxhighlight> На момент версии beta6 функция не дописана и в собранной библиотеке отключена.

Функция чтения текста с клавиатуры с учетом локалей и раскладок пользователя.

В процессе работы функции ввод полностью обрабатывается терминалом. Набираемые пользователем символы добавляются к строке в буфере buffer, при этом максимальный размер получаемой строки ограничивается max символами. В это время содержимое строки и курсор ввода отображается в терминале начиная с позиции (x, y).

TODO: картинка-иллюстрация

Чтение очереди ввода функцией terminal_getstr производится до:

  • Подтверждения ввода (поступления события VK_RETURN), функция возвращает количество введенных символов.
  • Отмены ввода (поступления события VK_ESCAPE или VK_CLOSE), функция возвращает -2.
  • Истечения отведенного промежутка времени (таймаута), функция возвращает -1.

Величина таймаута, в течении которого производится ввод и в течении которого вводимая строка отображается на экране зависит от значения параметра input.timeout:

  • infinite: неограниченно, до поступления событий VK_RETURN, VK_ESCAPE или VK_CLOSE.
  • N (где N -- некоторое неотрицательное значение): N миллисекунд.

Если input.timeout равен нулю, блокирования ввода и отображения вводимой строки на экране не производится, функция обрабатывает доступные сообщения в очереди ввода и немедленно завершается, возвращая одно из перечисленных выше значений.

По завершении, terminal_getstr убирает введенную строку и курсор ввода с экрана, восстанавливая предыдущее содержимое использованных ячеек-знакомест.

Иначе говоря, при значении input.timeout = infinite (значение по умолчанию), функция terminal_getstr производит чтение строки "до победного конца": до подтверждения или отмены ввода, полностью забирая на себя ответственность по отображению вводимого текста на экране. Пользователю библиотеки остается лишь проверить возвращенное значение и, в случае успешного завершения, использовать готовую строку в буфере buffer.

Значение input.timeout, равное или большее нуля, позволяет организовать "неблокирующий" ввод строки. Результат выполнения terminal_getstr появляется на экране на N миллисекунд, по истечении которых можно быстро обновить анимацию и продожить ввод дальше -- и так до тех пор, пока функция не вернет неотрицатильное значение (пользователь завершил ввод) или -2 (пользователь отменил ввод).

См. #Ввод

terminal_state

<syntaxhighlight lang="cpp"> int terminal_state(int code); </syntaxhighlight> ...

color_from_argb

<syntaxhighlight lang="cpp"> color_t color_from_argb(int a, int r, int g, int b); </syntaxhighlight> ...

color_from_name

<syntaxhighlight lang="cpp"> color_t color_from_name(const char* name); </syntaxhighlight> ...

terminal_custom_render_func

<syntaxhighlight lang="cpp"> void terminal_custom_render_func(custom_render_func_cb f); </syntaxhighlight> Автор библиотеки сам в легком замешательстве, но пазл вроде бы складывается.

Кодировки

...

Ввод

...

Примеры

<syntaxhighlight lang="cpp">

  1. include <bearlibterminal.h>
  2. include <Windows.h>

int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { terminal_open(CODEPAGE_DEFAULT);

// Выводим текст terminal_printf(1, 1, "Hello, world!"); terminal_refresh();

// Ждем, пока пользователь не закроет окно while ( terminal_get() != VK_CLOSE );

terminal_close(); } </syntaxhighlight> BTW, зависимость от Windows.h будет исправлена со временем.

<syntaxhighlight lang="pascal"> uses

 BeaRLibTerminal.pas;

begin

 terminal_open(CODEPAGE_DEFAULT);

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

 terminal_close();

end. </syntaxhighlight>