BearLibTerminal - псевдоконсольное окно для рогалика

Форум библиотеки BeaRLib

Модератор: Apromix

Аватара пользователя
Apromix
Мастер
Сообщения: 1236
Зарегистрирован: 04 июл 2011, 10:44
Откуда: Украина, Черновцы
Контактная информация:

Re: BeaRLibTerminal - псевдоконсольное окно для рогалика

Сообщение Apromix » 27 янв 2013, 20:32

Хм, и еще вопрос по хелсбару. Из чего он рисуется? Можно как-то в демке увидеть, как меняется его размер, цвет? Можно нарисовать 2 бара вверху, верхний красный, тот что пониже его - синий (запас маны)? Можно нарисовать такую же цветную полоску под буквой - это как бы аура? :)

Аватара пользователя
Cfyz
Сообщения: 776
Зарегистрирован: 30 ноя 2006, 10:03
Откуда: Санкт-Петербург
Контактная информация:

Re: BeaRLibTerminal - псевдоконсольное окно для рогалика

Сообщение Cfyz » 27 янв 2013, 20:58

Apromix писал(а):А как с шрифтом-картинкой обстоят дела? Вроде стены какие-то там видел в ресах
Со шрифтами-картинками (тайловыми шрифтами) все хорошо =) Они были реализованы первым делом, раньше TrueType.

Стены в ресурсах, как можно заметить, располагаются на местах символов рисования рамок. Этот шрифт взят из репозитория Dwarf Fortress, где подобным методом превращают рамочки в полноценные объемные стены. Ну и как результат, при использовании в BearLibTerminal юникодным кодам рамок ставятся в соответствие именно эти тайлы. Например, в демке шрифтов для шрифта Nobbins прокрути диапазон символов до предпоследнего (Box Drawing) — все тайлы на месте + обычные остальные рамки, для которых в тайловом шрифте соответствия не нашлось.

В плане символов/тайлов рамок тайловые и TrueType шрифты несколько отличаются. Для TrueType шрифтов ВСЕГДА используются автоматически сгенерированные библиотекой тайлы. Потому что я еще не видел ни одного честного TrueType шрифта (фактически растровый Fixedsys не в счет), в котором родными символами можно было бы пользоваться. И наоборот, для кастомных по самой своей сути тайловых шрифтов считается, что если уж автор сделал картинку для этого символа, то наверное он знает что делает и сгенерированные библиотекой используются только если в шрифте нет.
Apromix писал(а):Хм, и еще вопрос по хелсбару. Из чего он рисуется? Можно как-то в демке увидеть, как меняется его размер, цвет? Можно нарисовать 2 бара вверху, верхний красный, тот что пониже его - синий (запас маны)? Можно нарисовать такую же цветную полоску под буквой - это как бы аура?
Библиотека предоставляет возможность положить в одну ячейку "стопку" символов/тайлов, каждый со своим собственным цветом. Что из этого можно сотворить — зависит исключительно от изобретательности использующего.

Поменять цвет полоски здоровья? Разумеется. Как уже было сказано, второй тайл с полоской поверх первого можно уложить любого цвета.
Поменять размер? В юникоде строго оговоренный список линий, рамок и блочных элементов, но идея та же: кладем поверх тайл желаемого цвета и "размера".
Две полоски? Снизу буквы? Аналогично, имея необходимые (заготовленные) тайлы — хоть десять и хоть крест-накрест.

Такие изыски начинают конфликтовать с идеей использования векторного TrueType шрифта (где нельзя точно сказать, кроме как растеризовать и померять линейкой, размеры и пропорции символа и знакоместа), но в случае использования тайлового шрифта простор для творчества огого. Тайловый шрифт не ограничен 256 символами, просто первые 256 сопоставляются кодам символов согласно указанной кодировке для эффективного вывода текста. Однако, тайлы с индексами 256 и выше или тайлы символов, которые не будут использоваться при выводе (например, первые 32), могут быть заменены на что угодно и использованы при комбинации в один сложный тайл.

Если есть идеи, какие еще геометрические фигуры по типу блоков или рамок могут быть универсально полезны, я могу внести их в список автоматически генерируемых библиотекой (с кодами из Unicode Private Use диапазона) и тогда их можно будет использовать и вместе с векторными шрифтами.
Пытается раскуклиться

Аватара пользователя
Apromix
Мастер
Сообщения: 1236
Зарегистрирован: 04 июл 2011, 10:44
Откуда: Украина, Черновцы
Контактная информация:

Re: BeaRLibTerminal - псевдоконсольное окно для рогалика

Сообщение Apromix » 27 янв 2013, 21:04

В демке было бы неплохо еще один добавить пункт: динамическое изменение размеров шрифта и окна терминала соответственно :)

Аватара пользователя
Cfyz
Сообщения: 776
Зарегистрирован: 30 ноя 2006, 10:03
Откуда: Санкт-Петербург
Контактная информация:

Re: BeaRLibTerminal - псевдоконсольное окно для рогалика

Сообщение Cfyz » 27 янв 2013, 21:09

Apromix писал(а):В демке было бы неплохо еще один добавить пункт: динамическое изменение размеров шрифта и окна терминала соответственно
Второй пункт в демке шрифтов и есть размер. Для тайловых его, разумеется, менять нельзя, но для векторных — от 8 до 15 пунктов. Или ты не заметил, что все четыре пункта (шрифт, размер, режим растеризации, отображаемый диапазон символов) можно менять? =)

Впрочем, даже если размер тайлового шрифта менять нельзя (на то он и тайловый), все равно при смене default → Nobbins размер тайла и, соответственно, окна меняется весьма заметно.
Пытается раскуклиться

Аватара пользователя
Apromix
Мастер
Сообщения: 1236
Зарегистрирован: 04 июл 2011, 10:44
Откуда: Украина, Черновцы
Контактная информация:

Re: BeaRLibTerminal - псевдоконсольное окно для рогалика

Сообщение Apromix » 27 янв 2013, 21:17

Cfyz писал(а):
Apromix писал(а):В демке было бы неплохо еще один добавить пункт: динамическое изменение размеров шрифта и окна терминала соответственно
Второй пункт в демке шрифтов и есть размер. Для тайловых его, разумеется, менять нельзя, но для векторных — от 8 до 15 пунктов. Или ты не заметил, что все четыре пункта (шрифт, размер, режим растеризации, отображаемый диапазон символов) можно менять? =)
Действительно не заметил. Работает на ура! :) Наверное нужно побольше подсказочек написать. Или мне побольше поюзать демку :)

Аватара пользователя
hexMer
Сообщения: 150
Зарегистрирован: 12 сен 2009, 09:48

Re: BeaRLibTerminal - псевдоконсольное окно для рогалика

Сообщение hexMer » 30 янв 2013, 12:13

Cfyz писал(а):демка
Красотища! Вангую великое будущее этому терминалу.
При некоторой сноровке, кстати говоря, можно сделать тайловый рогалик (с квадратными буквами размером 1/4 тайла) :wink:

Аватара пользователя
Cfyz
Сообщения: 776
Зарегистрирован: 30 ноя 2006, 10:03
Откуда: Санкт-Петербург
Контактная информация:

Re: BeaRLibTerminal - псевдоконсольное окно для рогалика

Сообщение Cfyz » 30 янв 2013, 16:13

hexMer писал(а):Красотища! Вангую великое будущее этому терминалу.
И это вы еще моего правильного освещения не видели! Не ну на самом деле, не знаю насчет великого, но считаю вполне реальным сделать терминал более-менее известным инструментом в данной предметной области.
hexMer писал(а):При некоторой сноровке, кстати говоря, можно сделать тайловый рогалик (с квадратными буквами размером 1/4 тайла)
Ха, мне нравится ваш ход мыслей =) Действительно, если взять шрифт, скажем, 8x12, то кроме самих символов можно нарисовать в картинке тайлового шрифта и полноценные тайлы размером 16x24. Думаю, надо будет пример такого использования добавить в демо =)
Пытается раскуклиться

Аватара пользователя
Cfyz
Сообщения: 776
Зарегистрирован: 30 ноя 2006, 10:03
Откуда: Санкт-Петербург
Контактная информация:

Re: BeaRLibTerminal - псевдоконсольное окно для рогалика

Сообщение Cfyz » 03 фев 2013, 12:39

Воскресное обновление BearLibTerminal. На этот раз на повестке дня — мышь!

Несколько переделан ввод. Список возможных опций terminal_options дополнен следующей: input.events — фильтр событий ввода в виде набора флагов: none, all, keypress, keyrelease, mousemove, mousescroll. Несколько флагов указываются через '+' или '-': input.events=keypress+keyrelease+mousescroll. И наоборот: input.events=all-mousemove.

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

Введен новый метод terminal_state. Он позволяет получить состояние некоторой переменной (счетчика, флага, etc.). На данный момент — это состояние клавиатуры и мыши в произвольный момент времени:

Код: Выделить всё

int code = terminal_get();
if ( code == 'A' )
{
    if ( terminal_state(VK_CONTROL) ) // Ctrl+A
    {
        ShowGenericA();
    }
    else
    {
        int mx = terminal_state(VK_MOUSE_X);
        int my = terminal_state(VK_MOUSE_Y);
        ShowPointA(mx, my);
    }
}
Пример, разумеется, совершенно надуманный, но скорее всего достаточно наглядно иллюстрирует сам механизм.

Для клавиш клавиатуры и мыши используется их обычный код (VK_ESCAPE, VK_LBUTTON или 'A'), плюс для "непрерывных" состояний введены три дополнительных кода:
VK_MOUSE_X
VK_MOUSE_Y
VK_MOUSE_WHEEL

А также два виртуальных кода соответствующих событий:
VK_MOUSE_MOVE
VK_MOUSE_SCROLL

Поначалу хотел разделить названия клавиш, виртуальных событий и состояний, но оказалось, что эти множества пересекаются, а названия с разными префиксами только путают, поэтому будет одно большое перечисление VK_xxx, где слово "key" в аббревиатуре VK — уже не "клавиша", но скорее "ключ" таблицы.

Теперь немного поподробнее о фильтрации событий ввода:
1. keypress — нажатие клавиши, самое привычное событие, генерируется VK_xxx.
2. keyrelease — отпуск клавиши, генерируется VK_xxx|VK_FLAG_RELEASED.
3. mousemove — перемещения мыши; генерируется VK_MOUSE_MOVE, если мышь сдвинулась на другое знакоместо.
4. mousescroll — поворот колесика мыши, генерируется VK_MOUSE_SCROLL.
5. all — все вышеперечисленные.
6. none — никаких событий.

При фильтрации событий соблюдается их очередность. Например, предположим, что пока программа была занята расчетами, пользователь успел нажать клавишу 'A', подвинуть мышь из центра в левый верхний угол, отпустить 'A', нажать 'B' и повернуть колесико мыши. Также допустим, что фильтр событий установлен в keypress+mousescroll. Внутренняя очередь событий будет иметь примерно такой вид:
{ 'A', VK_MOUSE_MOVE, VK_MOUSE_MOVE, VK_MOUSE_MOVE, 'A'|VK_FLAG_RELEASED, 'B', VK_MOUSE_SCROLL, 'B'|VK_FLAG_RELEASED, ... }

Тогда, при обработке описанной очереди событий будет происходить следующее:
0. До первого вызова terminal_get(), состояния terminal_state(VK_MOUSE_X/Y) → центр терминала; terminal_state(VS_MOUSE_WHEEL) → 0.
1. Первый вызов terminal_get() вернет 'A'; VK_MOUSE_X/Y → верхний левый угол; VK_MOUSE_WHEEL → 0.
2. Второй вызов terminal_get() вернет 'B'; VK_MOUSE_X/Y → верхний левый угол; VK_MOUSE_WHEEL → 0.
3. Третий вызов terminal_get() возвращает VK_MOUSE_SCROLL; VK_MOUSE_X/Y → верхний левый угол; VK_MOUSE_WHEEL → 5.
4. ?????
5. PROFIT

Обратите внимание, что в отсутствие флагов keyrelease и mousemove в фильтре input.events соответствующие события не были считаны terminal_get.

В случае, если фильтр выставляется в none, поведение несколько отличается:
1. terminal_get всегда будет возвращать 0 вместо того, чтобы навечно заблокировать выполнение программы (своеобразная защита от неаккуратного вызова).
2. В вызове terminal_get нет необходимости: все события "прокручиваются" автоматически, поэтому terminal_state всегда возвращает самые последние значения.

Феникс, тебе не нравились события отпуска клавиш? Теперь они выключаются;
kipar, тебе хотелось immediate-mode ввод? Выставляй input.events=none и пользуйся terminal_state(VK_xxx);

По умолчанию фильтр выставлен в keypress: докладывается только факт нажатия клавиши (как на клавиатуре, так и клавиши мыши).


Ну и как обычно, чуточку обновленная демо с пунктом про мышь.
Вложения
beta4.zip
(1.11 МБ) 107 скачиваний
Пытается раскуклиться

Аватара пользователя
kipar
Сообщения: 2120
Зарегистрирован: 10 мар 2010, 13:16
Откуда: Москва

Re: BeaRLibTerminal - псевдоконсольное окно для рогалика

Сообщение kipar » 03 фев 2013, 14:54

Класс, счас заценим!

Аватара пользователя
kipar
Сообщения: 2120
Зарегистрирован: 10 мар 2010, 13:16
Откуда: Москва

Re: BeaRLibTerminal - псевдоконсольное окно для рогалика

Сообщение kipar » 04 фев 2013, 12:33

Что-то у меня задание шрифта (font.name) не работает - terminal_options возвращает -1 для всего что ни попробую кроме font.name=default.
Где должны лежать файлы шрифта чтобы работало? Нужно ли указывать полный путь? Брать в кавычки?
---
Хм, хотя в твоей демке все работает. Буду дальше разбираться.

Аватара пользователя
Cfyz
Сообщения: 776
Зарегистрирован: 30 ноя 2006, 10:03
Откуда: Санкт-Петербург
Контактная информация:

Re: BeaRLibTerminal - псевдоконсольное окно для рогалика

Сообщение Cfyz » 04 фев 2013, 12:58

kipar писал(а):Что-то у меня задание шрифта (font.name) не работает - terminal_options возвращает -1 для всего что ни попробую кроме font.name=default.
Где должны лежать файлы шрифта чтобы работало? Нужно ли указывать полный путь? Брать в кавычки?
Это вина в том числе и отсутствующей документации. Как-то я не решался ее делать пока интерфейс библиотеки менялся каждый день. Но, вроде пришли к определенному общему знаменателю, а значит не за горами RC и нормальный мануал >_<

Шрифт описывается не одним именем. Там целых четыре параметра: font.name, font.size, font.codepage и font.mode.

Для тайлового шрифта (картинкой) необходимо задать:
font.name=filename.png
font.size=WxH (W и H — размеры одного тайла)
font.codepage=C (С — кодовая страница, 1251 например).

Для TrueType шрифта необходимо задать:
font.name=filename.ttf
font.size=H (H — высота символа)
font.mode=M (M — режим растеризации, monochrome, default normal или lcd).

С одной стороны, их в принципе можно задавать поодиночке (например, вполне нормально взять и сменить размер векторного шрифта или его режим растеризации). С другой стороны, если указать лишь часть параметров, остальные берутся какие остались с предыдущих вызовов или вовсе что там по умолчанию. Не факт, что пазл сложится. Так что правильный, надежный вариант -- это в первый раз задать все релевантные выбранному типу шрифта опции (по три штуки), а уже впоследствии, если вообще потребуется, менять уже точно зная что будет использовано в качестве остальных параметров.

Надо еще какой-нибудь метод в интерфейсе, чтоб возвращал текстовое описание ошибки, а то вообще черный ящик.

Касаемо имен файлов и путей, то там пока просто, кавычек не предусмотрено, а путь как обычно отсчитывается от текущего каталога (ну кроме как указан абсолютный, тут тоже все ясно). Что может быть проблемой, если приложение запускается, например, из-под Visual Studio, которая кладет собранный экзешник в один каталог (Debug или Release), а запускает его из каталога проекта, что поначалу совсем неочевидно.
Последний раз редактировалось Cfyz 04 фев 2013, 13:48, всего редактировалось 1 раз.
Пытается раскуклиться

Аватара пользователя
kipar
Сообщения: 2120
Зарегистрирован: 10 мар 2010, 13:16
Откуда: Москва

Re: BeaRLibTerminal - псевдоконсольное окно для рогалика

Сообщение kipar » 04 фев 2013, 13:09

Cfyz писал(а):font.mode=M (M — режим растеризации, monochrome, default или lcd).
Тока не default, а normal :lol:
Теперь заработало.

Аватара пользователя
Cfyz
Сообщения: 776
Зарегистрирован: 30 ноя 2006, 10:03
Откуда: Санкт-Петербург
Контактная информация:

Re: BeaRLibTerminal - псевдоконсольное окно для рогалика

Сообщение Cfyz » 04 фев 2013, 13:47

kipar писал(а):Тока не default, а normal :lol:
Действительно >_<

Еще касаемо immediate-mode ввода пришел в голову нюанс. Есть по меньшей мере одна кнопка, которая не имеет события "отпустили" -- это кнопка закрытия окна, крестик этот в верхнем правом углу. Для потокового ввода это не является проблемой, ибо можно просто в момент фиксации нажатия сразу, одновременно сгенерировать и нажатие, и отпуск виртуальной клавиши. В immediate-mode поймать такое нажатие оказывается попросту невозможно.
Пытается раскуклиться

Аватара пользователя
Apromix
Мастер
Сообщения: 1236
Зарегистрирован: 04 июл 2011, 10:44
Откуда: Украина, Черновцы
Контактная информация:

Re: BeaRLibTerminal - псевдоконсольное окно для рогалика

Сообщение Apromix » 06 фев 2013, 08:33

Скачал. Посмотрел. Суперово :D Я в восторге от терминала :)

Аватара пользователя
kipar
Сообщения: 2120
Зарегистрирован: 10 мар 2010, 13:16
Откуда: Москва

Re: BeaRLibTerminal - псевдоконсольное окно для рогалика

Сообщение kipar » 06 фев 2013, 09:01

Cfyz писал(а):Еще касаемо immediate-mode ввода пришел в голову нюанс. Есть по меньшей мере одна кнопка, которая не имеет события "отпустили" -- это кнопка закрытия окна, крестик этот в верхнем правом углу. Для потокового ввода это не является проблемой, ибо можно просто в момент фиксации нажатия сразу, одновременно сгенерировать и нажатие, и отпуск виртуальной клавиши. В immediate-mode поймать такое нажатие оказывается попросту невозможно.
Тогда, может его отдельно обрабатывать? Т.е. в immediate mode считать, что если ее раз нажали, то она уже не отпускается. Все-таки это не обычная кнопка. Хотя на закрытие может нужно не просто выходить, а сначала спросить подтверждение... Тогда какой-нибудь отдельный флаг "закрытие было кликнуто" сделать, сбрасываемый при считывании.

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

---
Кстати, если в твоей демке в пункте "Speed" начать перетаскивать окно мышкой, то fps увеличивается в 10 раз - с 91 до 900 :shock:

Ответить

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 21 гость