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

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

Модератор: Apromix

Аватара пользователя
Феникc
Сообщения: 679
Зарегистрирован: 27 ноя 2010, 15:01
Откуда: Челябинск

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

Сообщение Феникc » 12 янв 2013, 21:28

Держи.
Премного благодарен, то что нужно. Отпишусь в случае проблем, если что - прошу считать меня коммунистом бета-тестером.
Всё вышесказанное - ИМХО, если не указано обратное.

Аватара пользователя
Феникc
Сообщения: 679
Зарегистрирован: 27 ноя 2010, 15:01
Откуда: Челябинск

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

Сообщение Феникc » 13 янв 2013, 19:58

Вроде всё работает. Правда моя студия не умеет Юникод без БОМ, но пока я использую Notepad++ для перевода, благо что текста почти нет.
Непонятно только как менять размер шрифта. Вот такой код

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

terminal_open(nullptr);
terminal_font("size=20");//как и terminal_font("size=20x20");
не работает. Или требуется указывать все параметры? В таком случае необходимо знать название стандартного шрифта (который, как я понял, зашит в ресурсы дллки).
Всё вышесказанное - ИМХО, если не указано обратное.

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

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

Сообщение Cfyz » 13 янв 2013, 22:23

Феникс писал(а):Правда моя студия не умеет Юникод без БОМ
То есть как это 2012 (вроде бы ты говорил такая) студия не умеет юникод без маркера? О_о В списке кодировок (при сохранении с указанием оной) UTF-8 с маркером и UTF-8 без маркера находятся в разных концах списка, легко не заметить.
Феникс писал(а): Вот такой код <...> не работает. Или требуется указывать все параметры?
Да, надо все параметры. Так как получается вот такая ерунда и из-за потихоньку растущего количества разных, не всегда нужных на виду параметров, я думаю вообще сделать настройки через одну функцию

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

terminal_options("param1=value1; param2=value2");
Тогда и возможность задать один конкретный параметр станет логичной. Хотя все равно есть нюанс, что некоторые вещи надо бы задавать вместе разом, но это можно просто задокументировать.
Феникс писал(а):В таком случае необходимо знать название стандартного шрифта (который, как я понял, зашит в ресурсы дллки).
Имя его -- Fixedsys Excelsior, см. интернеты, это public domain. Но вложенный -- это на самом деле шрифт-картинка, куда вошли несколько диапазонов юникода, так что размер все равно не поменять (256x320 PNG заметно меньше полного шрифта, а вложенный "шрифт по умолчанию" это все равно в основном на быстро что-нибудь попробовать и еще чтоб было куда откатиться в случае ошибки с кастомным). Впрочем, даже если там бы был .ttf, тебе бы это не помогло, так как это практически растровый шрифт. Нормально он смотрится только в одном размере -- 12pt/16px.

Вернуть обратно вложенный шрифт после использования кастомного можно с помощью

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

terminal_font("default");
Пытается раскуклиться

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

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

Сообщение Cfyz » 14 янв 2013, 00:12

Я все-таки прокомментирую использование кодировок.

В BearLibTerminal (на данный момент, возможны изменения) есть ряд вызовов, оперирующих символами или строками и затрагиваемых вопросом кодировки текста:
terminal_title
terminal_font
terminal_put
terminal_puts/printf
terminal_gets

Очень часто (поведение по умолчанию многих компиляторов) исходный код программы в указанной кодировке после компиляции порождает строки в той же кодировке. Можно выделить две основные группы часто используемых кодировок: это Unicode (UTF-8, UTF-16, UCS, ...) и однобайтные "ANSI/OEM-кодировки" (Windows-1251, DOS-Latin-US, ...).

BearLibTerminal (на данный момент) поддерживает один вариант Unicode-кодировки: UTF-8. Работа упомянутых выше функций с UTF-8 совершенно прозрачна.

Однако, есть ряд случаев, когда желательно использовать строки в однобайтной кодировке: компилятор/IDE может поддерживать только конкретную кодировку; или хочется упростить работу с текстом, а полный Unicode не нужен. В этом случае можно указать используемую программой кодировку в вызове terminal_open:

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

terminal_open("codepage=windows-1251");
В данный момент поддерживаются следующие кодировки:
Windows-1250 (Windows Latin Central Europe)
Windows-1251 (Windows Cyrilic)
Windows-1252 (Windows Latin Western Europe)
Windows-1253 (Windows Greek)
Windows-1257 (Windows Latin Baltic)
DOS-437 (DOS Latin US)
DOS-737 (DOS Greek)
DOS-852 (DOS Latin Central Europe)
DOS-858 (DOS Latin Western Europe)
DOS-866 (DOS Cyrillic)
Относительно странный перечень объясняется тем, что это также и список кодировок, доступных для шрифтов-изображений (параметр codepage при вызове terminal_font с type=bitmap).

При указании кодировки в terminal_open включается режим трансляции кодировок во всех текстовых вызовах библиотеки. При выводе все строки в однобайтной кодировке внутри BearLibTerminal будут приведены к Unicode и использованы в дальнейших операциях. Текст "Dark spell «Ragna Blade»" шрифтом от Dward Fortress буден выведен верно автоматически, несмотря на разницу в кодах символов '«' и '»' в кодировках Windows-1251 (программа) и DOS Latin US (шрифт). Текст в заголовке окна также будет отображен верно независимо от кодировки программы (если только пользователь не поигрался с кастомными системными шрифтами).

Аналогично, единственная на данный момент функция ввода terminal_gets изначально оперирует юникодом, позволяя вводить текст независимо от локали/раскладки конкретной машины, но при возврате результата он будет сконвертирован в используемую программой кодировку.

Определенный нюанс имеется в работе terminal_put. Эта функция кладет символ с указанным кодом в ячейку. Так как весьма интуитивным является вызов вида:

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

terminal_put(x, y, 'Ю');
внутри terminal_put также производится трансляция кодировки. Однако, использование ANSI-кодировки может быть искусственным/вынужденным ограничением. Кроме того, шрифт-изображение (тайловая карта) может включать и более 256 тайлов. Использование отдельных символов с кодами, выходящими за пределы однобайтной кодировки (256 и далее) в terminal_put никогда не попадает под конвертацию. Это позволяет использовать, к примеру, символы рисования рамок (которые в наличии всегда) или разные тайлы предметов даже в программе с однобайтной кодировкой строк.
Пытается раскуклиться

Аватара пользователя
Феникc
Сообщения: 679
Зарегистрирован: 27 ноя 2010, 15:01
Откуда: Челябинск

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

Сообщение Феникc » 14 янв 2013, 00:24

Да, сглупил, пытался выставить кодировку в настройках проекта :)
Впрочем, теперь не лучше.
Скрытый текст: ПОКАЗАТЬ
Безымянный.jpg
Безымянный.jpg (42.35 КБ) 10964 просмотра
В настройках проекта стоит Юникод. put и puts выдают вот такой результат, при этом terminal_title работает нормально, выводя кириллицу.
И да, нажатия клавиш берутся как-то уж слишком часто - явно чаще чем выставлено в настройках ОСи. На одно, самое кратковременное нажатие, терминал генерирует как минимум два события. Клавиши опрашиваются в обычном while-цикле.
Всё вышесказанное - ИМХО, если не указано обратное.

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

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

Сообщение Cfyz » 14 янв 2013, 00:50

Феникс писал(а):Впрочем, теперь не лучше.
Теперь у тебя все верно с кодировкой. Неверный вывод, оказывается, мой косяк в обратном преобразовании юникод --> индекс глифа в картинке дефолтного шрифта. Если подключишь .ttf: terminal_font("type=truetype; filename=G:\\FSEX300.ttf; size=12");, то все будет ок. Дефолтный же сломан, поправить несложно, но это будет не ранее завтрашнего (уже сегодняшнего) позднего вечера.

Также, на всякий случай, глянь мой пост чуть выше про кодировки.
Феникс писал(а):нажатия клавиш берутся как-то уж слишком часто - явно чаще чем выставлено в настройках ОСи. На одно, самое кратковременное нажатие, терминал генерирует как минимум два события.
Два -- это подозрительное число. На каждое "нажатие" генерируются два события -- на само нажатие и на отпуск клавиши. Различаются девятым битом (VK_FLAG_RELEASED). И ввод не может отличаться от ввода ОСи, это и есть ввод ОСи :D включая все настройки. Вот если приходит два идентичных числа, то да, там что-то сломано.

Очередь схожа с WndProc из WinAPI. Тяжело логично задать что тебе надо, а что нет. Очередь должна всегда выбираться целиком, а уж на что реагировать, а что игнорировать это дело разработчика. Логически, событие с кодом ('A' | VK_FLAG_RELEASED) ничем не отличается от нежданного события с кодом ('P'), если никакого действия на P не запланировано. И то, и то -- событие, которое придется проигнорировать.

В принципе, можно сделать опции "не генерировать события отпуска клавиши", "не генерировать события перемещения мыши", если таких опций будет единицы (пока вон две). Иначе проще оставить весь поток, чем путаться во флагах. Решение откладываю до подготовки следующей беты.
Пытается раскуклиться

Аватара пользователя
Феникc
Сообщения: 679
Зарегистрирован: 27 ноя 2010, 15:01
Откуда: Челябинск

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

Сообщение Феникc » 14 янв 2013, 10:24

Теперь у тебя все верно с кодировкой. Неверный вывод, оказывается, мой косяк в обратном преобразовании юникод --> индекс глифа в картинке дефолтного шрифта. Если подключишь .ttf: terminal_font("type=truetype; filename=G:\\FSEX300.ttf; size=12");, то все будет ок. Дефолтный же сломан, поправить несложно, но это будет не ранее завтрашнего (уже сегодняшнего) позднего вечера.
Я подозревал что-то подобное. Окей, возьму .ttf, мне не сложно.
Также, на всякий случай, глянь мой пост чуть выше про кодировки.
Видел.
Два -- это подозрительное число. На каждое "нажатие" генерируются два события -- на само нажатие и на отпуск клавиши. Различаются девятым битом (VK_FLAG_RELEASED). И ввод не может отличаться от ввода ОСи, это и есть ввод ОСи включая все настройки. Вот если приходит два идентичных числа, то да, там что-то сломано.
#-o В общем, ясно. Если найду ещё какие-то непонятности, смахивающие на баги, скажу.
Всё вышесказанное - ИМХО, если не указано обратное.

Аватара пользователя
Феникc
Сообщения: 679
Зарегистрирован: 27 ноя 2010, 15:01
Откуда: Челябинск

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

Сообщение Феникc » 14 янв 2013, 12:11

Забавная деталь - при слишком большом окне терминала верхняя его граница опускается так, чтобы окно влезло в монитор.
Вторая забавная деталь - @ в моноширинных шрифтах выглядит не очень :) В итоге взял Lucida Console Regular, если кому интересно.
Вообще, вроде больше ничего не заметно, так что немного порассуждаю.
Хорошо бы сделать отключение событий на отпускаемые клавиши, это да. Иначе приходится вставлять в цикл обработки конструкцию вида

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

if ((key & VK_FLAG_RELEASED) == VK_FLAG_RELEASED) continue; 
Тут можно сделать как в HGE - там это всё задаётся в начале, используя функцию вида setState(stateName, stateValue). Эту же конструкцию можно приспособить и к заданию всех остальных параметров терминала, включая шрифты, размеры и заголовок окна. Всё-таки задание через строку немного муторней, хотя со стороны терминала это может и удобней, не знаю.
Всё вышесказанное - ИМХО, если не указано обратное.

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

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

Сообщение Cfyz » 14 янв 2013, 12:57

Феникс писал(а):Забавная деталь - при слишком большом окне терминала верхняя его граница опускается так, чтобы окно влезло в монитор.
Не понял как это, но моей заслуги там нет =) Окно создается в выбираемых ОС координатах.
Феникс писал(а):Вторая забавная деталь - @ в моноширинных шрифтах выглядит не очень :) В итоге взял Lucida Console Regular, если кому интересно.
Lucida Console Regular это тоже моноширинный =) Вообще в терминал нужно только моноширинный, но я кажется понял, что ты имеешь в виду. Попробуй еще Consolas из Windows Vista+, мне он даже больше Lucida нравится.
Феникс писал(а):Хорошо бы сделать отключение событий на отпускаемые клавиши, это да. Иначе приходится вставлять в цикл обработки конструкцию вида <...>
Тут смотри какая ситуация. Помимо (key & VK_FLAG_RELEASED) может запросто прийти VK_F7. Или VK_NUMPAD4. Или любая другая клавиша, реакция на которую не предусмотрена. Тут надо от обратного, не игнорировать конкретные, а выбирать все, но вот реагировать только на определенные.
Феникс писал(а):Тут можно сделать как в HGE - там это всё задаётся в начале, используя функцию вида setState(stateName, stateValue). Эту же конструкцию можно приспособить и к заданию всех остальных параметров терминала, включая шрифты, размеры и заголовок окна. Всё-таки задание через строку немного муторней, хотя со стороны терминала это может и удобней, не знаю.
Перегрузка функций есть не в каждом языке. Делать set_state_int, set_state_string, set_state_size и т. д. -- пыжня, имхо. Типы тоже не всегда хорошо совпадают между языками.

Задание через строку ни разу не муторнее:

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

terminal_options("font.size=12"); // вообще думать не надо

fgets(buffer, 80, options_file);
terminal_options(buffer); // быстренько приляпать настройку шрифта в файлике

terminal_options("font.name=%s; font.size=%d", font_name, font_size); // С
terminal_options(Format("font.name=%0:s; font.size=%1:d", font_name, font_size)); // Pascal
terminal_options("font.name={0}; font.size={1}", font_name, font_size); // C# LOL
И вообще. Проблемы быстро и просто перевести что-то в строку нет. Обратно либа уж как-нибудь сама разберется.
Последний раз редактировалось Cfyz 14 янв 2013, 13:51, всего редактировалось 1 раз.
Пытается раскуклиться

Аватара пользователя
Феникc
Сообщения: 679
Зарегистрирован: 27 ноя 2010, 15:01
Откуда: Челябинск

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

Сообщение Феникc » 14 янв 2013, 13:20

Не понял как это, но моей заслуги там нет =) Окно создается в выбираемых ОС координатах.
Попробуй создать окно 80*40 с 30 размером, заполнив его разноцветными блоками, сам увидишь.
Lucida Console Regular это тоже моноширинный =) Вообще в терминал нужно только моноширинный, но я кажется понял, что ты имеешь в виду. Попробуй еще Consolas из Windows Vista+, мне он даже больше Lucida нравится.
Знаю, да. Имел в виду, что он мне понравился больше других. Consolas тоже надо будет попробовать.
Тут смотри какая ситуация. Помимо (key & VK_FLAG_RELEASED) может запросто прийти VK_F7. Или VK_NUMPAD4. Или любая другая клавиша, реакция на которую не предусмотрена. Тут надо от обратного, не игнорировать конкретные, а выбирать все, но вот реагировать только на определенные.
Немного не понял. Очевидно что та конструкция должна отсекать события, генерирующиеся при отпускании клавиши, и вот хорошо бы как раз иметь возможность вообще отключить их генерацию. С непредусмотренными клавишами всё просто, обычный switch/case для тех, на которые реакция должна быть.
Тьфу, понял. Очевидно что этот switch отсечёт сразу и те, которые released. Тогда их отключение обычно и не требуется, разве что если нужно ожидать одного нажатия (а не отпускания) клавиши, приходится вставлять цикл, который промотает все released события.

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

do
{
	key = terminal_get();
} while ((key & VK_FLAG_RELEASED) == VK_FLAG_RELEASED);
<code>
И вообще. Проблемы быстро и просто перевести что-то в строку нет. Обратно либа уж как-нибудь сама разберется.
Действительно. Ну ладно, всё равно это были досужие размышления :)
Всё вышесказанное - ИМХО, если не указано обратное.

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

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

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

Феникс писал(а):приходится вставлять цикл, который промотает все released события
Чисто алгоритмически, можно записать даже еще немного проще:

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

do { terminal_get(); } while ( terminal_kbhit() );
Впрочем, это все софистика, подобный цикл не имеет смысла: так как отпускание клавиши всегда будет позже ее нажатия, к моменту когда могло бы быть отфильтровано "лишнее" событие, основное условие уже будет выполнено (а цикл, соответственно, прерван). Вот тут и кроется неочевидная деталь: машины нынче быстрые и программа скорее всего успеет выполнить обработку нажатия раньше, чем придет событие об отпукании клавиши. Поэтому правильный способ одновременно и самый простой: игнорировать вообще все, что не нужно:

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

void ShowSmthA()
{
    /* ... */
    terminal_get(); // Press any key here
}

void Menu()
{
    while ( true )
    {
        /* Redraw */
        int key = terminal_get();
        switch ( key )
        {
            case 'A': ShowSmthA(); break;
            /* ... */
        }
    }
}
Посмотри, что сломается, если не обработать (VK_ESC | VK_FLAG_RELEASED) в конце ShowSmthA? Да ничего. Это событие будет прочитано в очередном цикле в Menu и проигнорировано.
Пытается раскуклиться

Аватара пользователя
Феникc
Сообщения: 679
Зарегистрирован: 27 ноя 2010, 15:01
Откуда: Челябинск

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

Сообщение Феникc » 15 янв 2013, 18:29

Посмотри, что сломается, если не обработать (VK_ESC | VK_FLAG_RELEASED) в конце ShowSmthA? Да ничего. Это событие будет прочитано в очередном цикле в Menu и проигнорировано.
Может я и ошибаюсь, но первым в ShowSmthA() придёт таки 'A'|VK_FLAG_RELEASED, что неприятно, особенно если это ожидание нужно чтобы игрок прочитал некий текст. Именно поэтому там придётся вставить тот цикл. Кстати, разве do { terminal_get(); } while ( terminal_kbhit() ); не промотает вообще все события? Порой это может быть вредным.
Всё вышесказанное - ИМХО, если не указано обратное.

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

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

Сообщение Cfyz » 15 янв 2013, 20:09

Феникс писал(а):Может я и ошибаюсь, но первым в ShowSmthA() придёт таки 'A'|VK_FLAG_RELEASED, что неприятно, особенно если это ожидание нужно чтобы игрок прочитал некий текст. Именно поэтому там придётся вставить тот цикл. Кстати, разве do { terminal_get(); } while ( terminal_kbhit() ); не промотает вообще все события? Порой это может быть вредным.
Да, внутри ShowSmthAпервым прочитается 'A'|VK_FLAG_RELEASED, как я и отмечал: первое, простое событие 'A' обработается быстрее появления второго. Теперь должно быть очевидно почему бесполезно фильтровать отпуск клавиши в том же цикле, в котором отрабатывается нажатие.

Тем не менее, логика "press any key" везде и всегда опиралась на предположение, что буфер ввода (та же самая очередь) чист. Если внутри ShowSmthA нет своего цикла обработки, который в качестве побочного эффекта сбросит очередь до вызова финального terminal_get, значит очередь надо очистить самостоятельно:

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

// Clear input queue
while ( terminal_kbhit() ) terminal_get();

// Press any key
terminal_get();
Этот цикл уже имеет вполне определенный смысл.

Теперь вернемся к

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

do { terminal_get(); } while ( terminal_kbhit() );
Это весьма сокращенный вариант цикла обработки со совершенно иным смыслом: обработать все события в очереди, но -- не менее одного, даже подождав при необходимости. Такой цикл применим, если к моменту обработки ввода игрок мог уже сделать выбор, а мог и не сделать. Например, если обсчет мира занимает заметное время (полсекунды?) то после обсчета в качестве очередного ожидания стрелочек логично поставить именно такой. Разумеется, вместо просто terminal_get должно быть get со switch со всеми деталями. Соответственно это полностью нормально, что цикл проматывает все события (он задуман для этого).

Вообще ситуации подобного плана -- это даже не проблемы, а обычный процесс разработки. Нужно подождать нажатия клавиши -- ждем. Не устраивают устаревшие нажатия -- убираем их. Прокрутка всех может быть вредной -- не прокручиваем =) Программа -- она такая, делает что приказано, а не то, что ты хочешь >_<.
Пытается раскуклиться

Аватара пользователя
warchief
Сообщения: 300
Зарегистрирован: 11 янв 2008, 09:55
Откуда: Озеро снов

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

Сообщение warchief » 17 янв 2013, 03:49

Да, надо все параметры. Так как получается вот такая ерунда и из-за потихоньку растущего количества разных, не всегда нужных на виду параметров, я думаю вообще сделать настройки через одну функцию
Я бы сделал структуру описатель и передавал ее:

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

typedef struct sDesc
{
    int width;
    int height;
    char *caption;
} Desc;

Desc CostructDesc()
{
   Desc d;
   width = 80;
   hieght = 60;
   d.caption="Hell";
   return d;  
}

sDesc desc = CostructDesc();
terminal_open(desc);
Тогда бы не было проблем - когда параметров много для одной функции (все таки функция принимающая 10-20 параметров - тот еще ад), а куча разных функций усложняют жизнь программиста. Плюс CostructDesc обеспечивает параметры значениями по умолчанию.

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

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

Сообщение Cfyz » 17 янв 2013, 15:09

warchief писал(а):Я бы сделал структуру описатель и передавал ее: <...> Тогда бы не было проблем - когда параметров много для одной функции (все таки функция принимающая 10-20 параметров - тот еще ад), а куча разных функций усложняют жизнь программиста. Плюс CostructDesc обеспечивает параметры значениями по умолчанию.
Все верно, в серьезных проектах со сложной структурой именно так и делается, конструктор по структуре со всеми возможными полями. И компактно записывается, и упрощает поддержку (сериалицация, подмена контекста и пр.). Но тут немного другой случай.

1. Это библиотека, которая предполагается к использованию из максимально возможного количества языков (+версий компиляторов). Мне бы не хотелось делать лишние структуры с кучей полей, у которых надо следить за выравниванием и верным маршалингом типов. Я отчаянно держусь за интерфейс с минимальным связыванием, пока что это оперирующий скалярами всего трех типов.
2. Это библиотека со предположительно минимально необходимым интерфейсом. Создать объект, заполнить одно поле, другое, уже сколько строк. Если надо поменять только один параметр из десяти, придется хранить исходную структуру или вводить метод возврата текущей, что пересекается со следующим пунктом:
3. Структура со всеми настраиваемыми полями жестко фиксирует набор. Банально хотелось бы скрыть с глаз долой, но оставить физически доступными различные экспериментальные и дебажные опции. Кроме того, добавление или изменение поля порушит бинарную совместимость, см. п. 1.
4. Ну и косметически это не очень опрятно. Чтобы задать размеры окна, нужно указать отдельно Desc.width и отдельно Desc.height. Для перечислений и флагов надо вводить константы и маски и т. д. Заводить новые типы и лишние структуры нежелательно по п. 1.

В общем, надежное стабильное решение, но когда имеем дело непосредственно с конкретным кодом. Будет работать, но в сумме не вызывает восторга.

Чуть выше была ма-аленькая дискуссия (в один вопрос-ответ длиной) где я выдумал задание опций в текстовом виде через одну функцию:

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

int terminal_options(const char* options, ...);

...
terminal_options("size=80x25");
terminal_options("font=whatever.png; font.size=8x14; font.codepage=dos-latin-us");
terminal_options("title=Hello, %s", name);
Итого, по упомянутым пунктам:
1. Туда -- C-строка, оттуда -- целое со знаком. Все.
2. Одна функция, с помощью которой можно задать и всю релевантную конфигурацию разом, и поменять один параметр по месту.
3. terminal_options("debug.timings=true; debug.log.level=trace");
4. Задание размера как "80x25", перечисления в человеко-читаемом виде, флаги как "flag1+flag2+flag3";

В общем, я пока не вижу существенных недостатков у этого подхода, а плюсы у него вполне очевидные.

Единственным задаваемым иным способом остается "кодировка программы", которую необходимо знать, чтобы работать со строками далее. Может показаться, что ее не обязательно знать, в конце-концов практически все параметры укладываются в ASCII, которому плевать на кодировки, но есть параметры необязательно из латиницы типа title или font.name. Смене в процессе работы кодировка не подлежит, она вообще зависит от IDE-компилятора-проекта и смене не подлежит в пределах целой жизни этого проекта. При этом, это единственная опция, которая влияет на возможность задания других опций. Поэтому кодировка программы будет задаваться в terminal_open. Это потребует введения в интерфейс перечисления, фактически дублирующего задаваемое иным способом (font.codepage), что мне не нравится, но тут, похоже, ничего не поделаешь.
Пытается раскуклиться

Ответить

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

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