BearLibTerminal — различия между версиями
Apromix (обсуждение | вклад) (→Примеры) |
Apromix (обсуждение | вклад) (→Примеры) |
||
Строка 275: | Строка 275: | ||
<syntaxhighlight lang="pascal"> | <syntaxhighlight lang="pascal"> | ||
uses | uses | ||
+ | Windows, | ||
BeaRLibTerminal.pas; | BeaRLibTerminal.pas; | ||
Строка 285: | Строка 286: | ||
// Ждем, пока пользователь не закроет окно | // Ждем, пока пользователь не закроет окно | ||
− | while ( terminal_get() <> VK_CLOSE ) do ; | + | while ( terminal_get() <> VK_CLOSE ) do Sleep(1); |
terminal_close(); | terminal_close(); |
Версия 11:32, 11 июля 2013
BearLibTerminal — это небольшая (в интерфейсном плане) библиотека для организации терминал-подобного окна, вывода текста, обработки простого ввода.
Большое количество roguelike совершенно осознанно используют аскетичное символьное/псевдографическое оформление. Однако, использование стандартных средств вывода (командной строки ОС) сопряжено с досадными ограничениями скорости вывода, цветовой гаммы, используемого шрифта. Нетривиальной задачей оказывается и применение расширенного набора символов, например нескольких языков и псевдографики. BearLibTerminal позволяет обойти упомянутые ограничения оставаясь в рамках простой концепции "терминала": пользователю предоставляется прямоугольная сетка ячеек-знакомест, средства для вывода текста и чтения ввода с клавиатуры.
Достойными внимания особенностями терминала являются:
- Высокая скорость вывода (в основе лежит OpenGL).
- Возможность использования тайловых (в виде картинки) и векторных (TrueType) шрифтов.
- Легкость использования Unicode.
- Полная TrueColor палитра.
- Возможность комбинации нескольких символов в одном знакоместе.
- Поддержка ввода с клавиатуры и мыши.
BearLibTerminal не является:
- Фреймворком roguelike: в библиотеке нет и никогда не будет генераторов случайных чисел, уровней или имен персонажей, механизмов расчета FOV/LOS и освещения, средств для работы с файлами или сетью.
- Графическим движком общего назначения: функциональность библиотеки сознательно ограничивается функциональностью псевдотерминала. Несколько шрифтов, летающие по окну буквы, системы частиц и пр. могут быть реализованы посредством захвата нижележащего контекста OpenGL, но это никогда не будет целью самой библиотеки.
Похожие инструменты: Tinycurses, libtcod.
Содержание
- 1 Интерфейс библиотеки
- 1.1 terminal_open
- 1.2 terminal_close
- 1.3 terminal_options
- 1.4 terminal_put
- 1.5 terminal_color
- 1.6 terminal_bkcolor
- 1.7 terminal_blending
- 1.8 terminal_printf
- 1.9 terminal_clear
- 1.10 terminal_clear_area
- 1.11 terminal_refresh
- 1.12 terminal_has_input
- 1.13 terminal_get
- 1.14 terminal_getstr
- 1.15 terminal_state
- 1.16 color_from_argb
- 1.17 color_from_name
- 1.18 terminal_custom_render_func
- 2 Кодировки
- 3 Ввод
- 4 Примеры
Интерфейс библиотеки
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
выводимый символ "накладывается" на уже имеющиеся в ячейке символы, причем каждый отдельный символ в получившейся "стопке" может иметь индивидуальный цвет. Таким образом можно комбинировать глифы и/или тайлы для получения более сложных фигур. Цвет фона знакоместа обновляется только при выводе самого первого символа.
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">
- include <bearlibterminal.h>
- 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
Windows, BeaRLibTerminal.pas;
begin
terminal_open(CODEPAGE_DEFAULT); // Выводим текст terminal_printf(1, 1, 'Hello, world!'); terminal_refresh();
// Ждем, пока пользователь не закроет окно while ( terminal_get() <> VK_CLOSE ) do Sleep(1); terminal_close();
end. </syntaxhighlight>