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

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

Модератор: Apromix

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

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

Сообщение Apromix » 11 окт 2016, 13:34

Cfyz писал(а):... с безымянным параметром неудобно эти значения читать обратно или составлять на лету механически. Справдливее будет дать им какое-то опциональное имя, например чтобы "font: foo.ttf, size=11" и "font: source=foo.ttf, size=11" были равнозначны...
Это позволит и так писать: font.source=resources\UbuntuMono-R.ttf?

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

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

Сообщение Cfyz » 11 окт 2016, 14:29

По идее да. Вообще-то даже сейчас так можно, просто именем "безымянного" значения является _ (подчеркивание). "font._=foo.ttf". А еще можно "font: foo.ttf; font.size=11;" писать, все равно оно в список key=value превращается.

Замена имени безымянного значения на что-то индивидуальное заметно усложнит работу в некоторых местах (всмысле куда больше переписывать; а там не переписывать, там рефакторить надо). Существенно проще заменить подчеркивание на более обычное, но столь же безликое слово, например "font.value=/path/to/file.ttf; font.size=11" -- терпимо выглядит? Просто по-моему если строчка руками пишется, то можно и сокращенно записать, а если она генерируется, то не без разницы ли название параметра?

С тайлсетами еще такой нюанс: для первоначальной инициализации надо несколько параметров, "font.value=file.ext" будет мало. В одном set() надо передать хотя бы минимально необходимый набор, хотя и неважно в каком виде и порядке описанный. А вот сделать так, чтобы потом уже можно было устанавливать "font.size=12" -- это имеет смысл.
Пытается раскуклиться

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

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

Сообщение Apromix » 12 окт 2016, 07:55

По уровням логирования мало информации. Добавь больше информации в табличку :)

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

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

Сообщение Cfyz » 18 окт 2016, 14:07

Багфикс-релиз 0.14.10:
  • Окно все-таки центрируется теперь на экране при первом отображении (во всех ОС).
  • Несколько правок для OS X: пункт меню Cmd+Q, фикс первой отрисовки, универсальный пакет для Python.
  • Окончательно поправлен флуд событиями мыши (можно читать-рисовать по одному событию за раз и все равно не тормозить).
  • Оптимизации и исправления во враппере для Python.
Windows / Linux / OS X / PyPI

Одновременно поломал работу под Wine, будет починено после некоторого расследования.
Пытается раскуклиться

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

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

Сообщение Apromix » 21 окт 2016, 07:59

Замечательно! Обновлюсь и я)
Скрытый текст: ПОКАЗАТЬ
Версия как у убунты))

Аватара пользователя
Loinon
Сообщения: 43
Зарегистрирован: 19 июл 2016, 18:20

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

Сообщение Loinon » 23 окт 2016, 16:26

Приветствую :)
Наверное, вопрос тупой: каким образом можно scale'ить тайлы? Хочу добавить возможность изменять размер cellsize, растягивая или сжимая изображение тайла (как от alt + [+/-]), а не обрезывая его. Или нужно как-то через resize в конфиг. строке при назначении тайлсета это указывать? При ресайзе он назначает весь тайлсет для одного символа.
upd: думаю, было бы здорово иметь функцию, для управления скейлом окна терминала, а alt+ [+/-] убрать.
upd2: пока программно делю весь тайлсет на тайлы и назначаю его через Terminal.set (). Мой говнокод на c# под спойлером
Скрытый текст: ПОКАЗАТЬ

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

struct Tileset
		{
			public string Path { get; set; }
			public int NumbOfTilesVer { get; set; }
			public int NumbOfTilesHor { get; set; }
			public int TilesetCode { get; set; }

			public Tileset (string path, int numbHor, int numbVer, int code)
			{
				Path = path;
				NumbOfTilesHor = numbHor;
				NumbOfTilesVer = numbVer;
				TileSetCode = code;
			}

			public bool Set ()
			{
				bool result = true;
				Bitmap tileset = new Bitmap (Path);
				Bitmap tile = new Bitmap (tileset.Width / NumbOfTilesHor, tileset.Height / NumbOfTilesVer);
				int i = 0;

				using (var g = Graphics.FromImage (tile))
					for (int y = 0; y < tileset.Height; y += tile.Height)
						for (int x = 0; x < tileset.Width; x += tile.Width)
							if (result)
							{
								g.DrawImage (tileset, new Rectangle (0, 0, tile.Width, tile.Height), new Rectangle (x, y, tile.Width, tile.Height), GraphicsUnit.Pixel);
								result = Terminal.Set ("{0}: {1}, raw-size = {2}", TilesetCode + i, new Bitmap (tile, Settings.Default.CellSize), Settings.Default.CellSize);
								i++;
							}
				tileset.Dispose ();
				tile.Dispose ();
				return result;
			}
		}
Стоит только захотеть...

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

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

Сообщение Cfyz » 24 окт 2016, 00:30

Вот ведь багодел Т_Т.

1. Падение в wine потому, что одна опциональная функция подгружается динамически; загрузили библиотеку, взяли адрес функции в ней, выгрузили библиотеку. Ммм, что это оно вдруг падает? В Windows это работает лишь потому, что где такая библиотека есть (Windows Vista+) она все равно уже загружена в память хотя бы для нужд самой ОС. В wine она нужна только приложению и честно выгружается.
2. Сломался полноэкранный режим в Linux, потому что каноничный способ центрирования окна -- это сделать его DIALOG, а окна такого типа не разворачиваются на весь экран.
3. Параметр resize сломан =(. Вообще доках записано, что resize переразмеряет исходное изображение, но вот свежим взглядом мне кажется будет более логично если этот параметр будет указывать целевой размер именно тайла (ну или всего изображения, если это не тайлсет и тайл как бы один).

Скейл окна терминала определенно будет управляться из приложения. Только не отдельной функцией, а стандартно для опций окна, через Set("window.scale=1.5"). Там есть один нюанс, так что это не войдет в ближайшее обновление с исправлениями, но точно будет. Alt-команды по умолчанию впрочем убираться не будут. Их идея в том, что некоторое управление доступно пользователю независимо от поддержки в самом приложении (и тем не менее, их можно отключить опцией "input.alt-functions=false").

Когда я поправлю resize (в ближайшее время, день? два?) нарезка руками станет не нужна, но все равно отмечу, что создание копии new Bitmap(tile, CellSize) излишне, так как содержимое Bitmap копируется внутри Set. И надо что-то придумать по поводу raw-size в этом случае, потому что странно все-таки выглядит руками указывать размер передаваемого Bitmap.
Пытается раскуклиться

Аватара пользователя
Loinon
Сообщения: 43
Зарегистрирован: 19 июл 2016, 18:20

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

Сообщение Loinon » 25 окт 2016, 13:57

Т.е. resize будет указывать размер одного тайла в тайлсете?
Например, Set("0xE000: size = 16x16, resize = 32x32") будет означать, что тайлсет будет поделен на тайлы размером 16х16, которые потом будут растянуты на 32х32? Еще по будущему скейлу вопрос: будет ли скейл работать в полноэкранном режиме?
Стоит только захотеть...

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

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

Сообщение Cfyz » 26 окт 2016, 13:13

Loinon писал(а):Т.е. resize будет указывать размер одного тайла в тайлсете? <...> тайлсет будет поделен на тайлы размером 16х16, которые потом будут растянуты на 32х32?
Да. Мне такое поведение кажется более наглядным, ведь при использовании resize интерес представляет в первую очередь результирующий размер тайла, в то время как size описывает загружаемое изображение, а конкретно какого размера кусочки в изображении-тайлсете (и по умолчанию тайлы делаются такого же). Кроме того, это не даст нечаянно сделать исходное изображение такого размера, что потом не получится порезать нацело (например было 64x64, тайл 16x16, переразмерили до 75x75 и теперь размер тайла 18.75 пикселя?).
Loinon писал(а):Еще по будущему скейлу вопрос: будет ли скейл работать в полноэкранном режиме?
А в полноэкранном режиме скейл не видно. Полноэкранный режим это в общем-то скейл "в край" монитора. Неважно насколько было растянуто окно раньше -- 150% ли, 200% ли -- в полноэкранном режиме оно растянуто на весь экран по построению.

Обращаю внимание, что гипотетический window.scale и resize у тайлсета это не синонимы. Параметр resize изменяет размер тайлов, этот размер не обязан соответсвовать размеру ячейки (и, как следствие, окна). Например, можно представить такой (немного нетривиальный) сценарий, когда используется шрифт 10x20, а квадратные картинки монстров вписываются в 20x20 (2x1 ячееек) будучи подгружены из 8x8 пиксель-арт тайлсета и увеличены вдвое:

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

font: Readable.ttf, size=10x20;
0xE000: monsters.png, size=8x8, resize=16x16, resize-filter=nearest, spacing=2x1;
* resize-filter нужен затем, чтобы пиксель-арт остался пиксель-артом, а не был заблюрен билинейной фильтрацией.
* spacing нужен затем, чтобы при Put(x, y, 0xE005) тайл был отцентрирован в квадратном блоке из 2x1 ячеек:
resize.png
resize.png (5.31 КБ) 4952 просмотра
А вот window.scale -- это параметр терминала целиком, все окно будет отмасштабировано со всем своим содержимым. Полноэкранный режим это как бы частный случай скейла.
Пытается раскуклиться

Аватара пользователя
Loinon
Сообщения: 43
Зарегистрирован: 19 июл 2016, 18:20

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

Сообщение Loinon » 26 окт 2016, 18:16

Cпасибо большое за разъяснение :) А возможен ли скейл для тайлов? Чтобы менять cellsize и подгонять под него scale тайлов (или наоборот) во время выполнения приложения? Например, как в Dwarf fortress при прокрутки колеса мыши (скрины под спойлером). Я так понял, во время выполнения конфигурирование тайлсетами не поддерживается. Тогда, придется через set("Ex000=none") обнулять тайлсет и назначать его заново, но уже с необходимым resize? И шрифты также перенастраивать. И еще вопрос: можно ли настроить встроенный шрифт (размер. центрирование и т.д.)?
Скрытый текст: ПОКАЗАТЬ
Изображение
Изображение
Стоит только захотеть...

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

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

Сообщение Cfyz » 27 окт 2016, 15:00

Loinon писал(а):А возможен ли скейл для тайлов? Чтобы менять cellsize и подгонять под него scale тайлов (или наоборот) во время выполнения приложения? Например, как в Dwarf fortress при прокрутки колеса мыши
Это вообще довольно интересный момент, зум содержимого. Логика в этом определенная есть, эдакая противоположность масштабированию окна. Но нет, поддержки такого в терминале сейчас нет.

А вот какую задачу это решает? Если мы хотим, чтобы игра могла использовать все доступное место на экране, то надо выставить window.resizeable=true, после чего окошко можно будет обычным образом переразмерить мышкой и появится кнопка "развернуть на весь экран". При изменении размеров окна приложение получит TK_RESIZED и должно будет перестроить вывод под новое количество ячеек. См. пример "j. window resizing" в SampleOmni.

Если же мы хотим сделать зум внутриигрового содержимого (карты), то наверное стоит отделять его масштаб от общего масштаба приложения. На скриншотах Dwarf Fortress выше видно, что интерфейс игры масштабируется вместе со всем и превращается в кашу. В идеале приложение может отмасштабировать только карту, оставив количество ячеек и интерфейс неизменными. Нюанс здесь правда в том, что в псевдотерминальной сцене будет непросто рисовать карту адресуя расположение тайлов меньше одной ячейки. Это идея для нового примера использования.

Тем не менее, я наверное добавлю и такой зум -- при котором размер окна остается неизменным, а меняется количество ячеек в нем. Просто для полноты картины. Работать это будет, конечно, только при window.resizeable=true, так как бессмысленно пытаться менять размер сцены, если приложение к этому не готово. Вообще все вышесказанное возможно только в том случае, если приложение может обработать смену количества ячеек в сцене.
Loinon писал(а):И еще вопрос: можно ли настроить встроенный шрифт (размер. центрирование и т.д.)?
Встроенный шрифт -- он обычный растровый, просто упоминание "default" вместо имени файла приводит к подстановке нескольких параметров: исходной картинки, размера тайла в ней и кодовой страницы =). Так как он растровый, размер можно поменять только через resize (который сломанный), остальные параметры (spacing, align) можно указать как обычно.
Пытается раскуклиться

Аватара пользователя
Loinon
Сообщения: 43
Зарегистрирован: 19 июл 2016, 18:20

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

Сообщение Loinon » 27 окт 2016, 18:42

Scale определенных тайлов идеальный вариант, но, наверное, это будет сложно реализовать. Вам, во всяком случае, виднее. Если будет "общий" скейл всех тайлов, то и этого будет достаточно для меня. Как вариант, сделать уникальный скейл для каждого слоя, располагая карту в одном слое (или нескольких), который (которые?) и скейлиться, а интерфейс располагать слоями выше, он будет оставаться неизменным. При этом тогда и cellsize придется делать уникальным для слоев, чтобы адресация происходила на каждом слое, как надо...

Хотелось бы в приложении реализовать как возможность изменять размер окна в знакоместах через Set("window.resize=true"), так и менять размер содержимого отдельного тайла, изменяя их scale через гипотетический Set("window.cellsizeScale=someValue"). Я как раз делаю приложение с гибким интерфейсом... При скейле содержимого тогда придется менять cellsize, чтобы не было черных полос между тайлами и они не накладывались друг на друга, если, конечно, Вы не решите менять cellsize параллельно со scale'ом внутри библиотеки. При этом, чтобы само окно не меняло размер, нужно будет менять его размер программно убирая или создавая новые тайлы. И после всех этих манипуляций подгонять интерфейс и вырисовывать получившуюся картину.

Щас пойдут мысли вслух. К примеру, окно 20х20 клеток, у каждого cellsize = 10x10, размер окна приложения тогда 200x200 в пикселях. Делаем scale тайлов, например, на 1.75, тогда новый cellsize = 10*1.75 = 17.5. Придется что-то делать с лишними 0.5. Оптимально будет делать дельту между ближайшими возможными значениями scale тайлов таким, чтобы при умножении на cellsize получалось целое число, но это уже будет на совести программиста. Ну пусть scale тогда будет 1.5, => cellsize = 1.5*10 = 15. При этом окно приложения увеличится также в полтора раза, поэтому, чтобы размер окна не менялся, увеличиваем его до 200 px по высоте и ширине. И вот еще проблема, 200 не делится нацело на 15. Тогда округлять до 13 или 14, в зависимости от значения после запятой, но тогда будет "поддергиваться" рамки окна от незначительных изменений скейла. Самое лучшее решение тогда делать дельту между возможными значениями scale'a таким, чтобы новый cellsize получался и целым числом, и окно в пикселях делилось на него.
Стоит только захотеть...

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

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

Сообщение Cfyz » 30 окт 2016, 22:32

Так, несколько запоздалый обещанный фикс простых огрех 0.14.11: задающий размер тайла параметр resize у тайлсетов и исправление ряда технических багов.
Windows / Linux / OS X / PyPI
Loinon писал(а):Scale определенных тайлов идеальный вариант, но, наверное, это будет сложно реализовать. Вам, во всяком случае, виднее.
Вообще-то что я там подразумевал -- это как раз целиком ложится на плечи разработчика игры =).

Есть масштабирование окна, оно может быть в двух вариантах. Один вариант это как в Caves of Qud или в Dwarf Fortress при переразмерении окна мышкой: меняется размер окна, а его содержимое растягивается (примерно так сейчас в BearLibTerminal). Другой вариант это как в Dwarf Fortress при вращении колесика мыши: размер окна остается неизменным, меняется количество ячеек (в этом случае приложение должно уметь обрабатывать изменение размера сцены). Грубо говоря оба варианта это одно и то же, просто в формуле (window_size = cell_size * scene_size) подкручиваются разные переменные. Плюс в том, что от приложения практически ничего не надо и при этом можно переразмерить что угодно. Минус в том, что выполняющая скейл часть понятия не имеет о том, что собственно она скейлит. Получаются размытые тайлы, уменьшенный до состояния нечитаемости UI и т. д.

Эти два варианта "механического" переразмерения в BearLibTerminal будут. Один есть сейчас (Alt+плюс/минус), второй будет (скажем, Alt+Shift+плюс/минус). Для того, чтобы можно было повесить это на свои комбинации (например на колесико мыши), управление масштабом будет доступно и через window.scale. Только надо с формой записи определиться: скажем, window.scale=0.75 это переразмерить окно оставив количество ячеек прежним, а window.scale=-0.75 это вписать новое количество ячеек в прежний размер окна (или у кого-нибудь есть вариант нотации получше?). Там довольно нюансов в реализации (в основном как раз таки с округлениями), но в целом универсальный механизм пойдет на пользу библиотеке.

А вот о чем я говорил про масштабирование только части ячеек, так это идеализированный вариант с осмысленным, "интеллектуальным" переразмерением сцены самим приложением, которое уж точно знает что, как и зачем оно скейлит. По команде пользователя переразмеряются только тайлы уровня/монстров, в то время как размер базовой ячейки (он же -- размер текста) и размер окна остаются неизменны. При увеличении размера тайлов карты их в отведенное место влазит меньше, но зато на них появляются полоски здоровья и прочие штуки. При уменьшении тайлы сначала становятся меньше, теряют детали, а потом и вовсе заменяются на что-то типа миникарты, потому что скейлить картинки до 4x4 и меньше бессмысленно. Плюсы -- это должно неплохо выглядеть. Минусы -- это многого требует со стороны приложения и нужен аккуратный подгон размеров, универсального решения в общем виде нет.
Loinon писал(а):Как вариант, сделать уникальный скейл для каждого слоя <...> При этом тогда и cellsize придется делать уникальным для слоев <...>
Это на самом деле разведет чудовищный бардак. Если очень хочется рисовать тайлы не по сетке, то есть довольно простой и понятный хак: количество тайлов в ячейке искуственно не ограничено, и при этом каждый тайл может иметь свое смещение, так что остается помещать их на сцену как PutExt(0, 0, x, y, code) для любых пиксельных координат (x, y). См. "Extended 2: Smooth scroll" в SampleOmni.
Пытается раскуклиться

Аватара пользователя
Loinon
Сообщения: 43
Зарегистрирован: 19 июл 2016, 18:20

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

Сообщение Loinon » 02 ноя 2016, 17:43

Cпасибо, resize теперь стабильно работает :)
Появился такой вопрос, в связи с изменением значения input.filter'a по умолчанию: можно ли обойтись без конфиг файла при установки фильтра обрабатываемых кодов? Set("input.filter = [keyboard, mouse+] не работает :( Только если через конфиг. файл.
Стоит только захотеть...

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

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

Сообщение Cfyz » 03 ноя 2016, 12:07

Точно не работает? В SampleOmni пункт "g. input: mouse" выставляет то же самое и вроде бы работает. Разве что там использованы фигурные скобки вместо квадратных, но и так, и так правильно (по крайней мере пока). Попробуй включить логгирование (log: file=bt.log, level=trace) и посмотреть что приходит внутрь библиотеки.
Пытается раскуклиться

Ответить

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

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