Давно что-то не было обновления… Просто местами призадумался, местами был занят другими файлами…
Сперва наверное нужно об ошибках.
Первая в прошлой версии, но далеко не первая за период моего общения с Arduino IDE. Вносишь изменения, компилируешь, все отлично. Пытаешься всё то же самое завести на другом компе, начинают сыпаться предупреждения. Не фатально, но неприятно.
Другая ошибка, довольно простая, и в то же время весьма досадная. Выбирая размер переменной, в условиях ограниченного количества ОЗУ, всегда стараешься не переборщить. Но это на ранних стадиях. Но этим я переболел уже давно. Сидеть и перебирать код, выясняя где я там, вместо 16 битной переменной, выбрал 8 битную… Это я уже проходил. Я всё же стараюсь экономить, но если есть хоть сумрачное подозрение что 8 бит при каких-то условиях будет мало, я не задумываясь меняю на 16.
Достаточно простая формула
window_seg = ((X2-X1)*(Y2-Y1) ) / ((memory_size * color_depth_mult);
Мне заведомо известно, что количество сегментов будет не более 50-80. Рабочий вариант 10-20. Но всё же предполагаю, еcли да кабы… И выделяю 16 бит. И этого оказывается мало!
Фикус в том, что промежуточные расчеты, внутри строки (формулы), могут вывалится далеко за 16 бит.
Не потребуется выделять 32 бита, с этим хорошо справится приведение типа.
window_seg = ((unsigned long) (X2-X1)*(Y2-Y1) ) / ((unsigned long) memory_size * color_depth_mult);
Точно так же, когда компилятор ругается на сравнение знаковых и без знаковых переменных, чтобы ничего не менять, можно в if ( ) произвести приведение типа, к знаковой переменной.
Это довольно очевидно, если хоть немного знаешь ассемблер, и то как всё это происходит на более низком уровне. Каких-то великих преимуществ это не дает, но многие ошибки начинаешь выкупать намного быстрее. А если учесть, что скорость написания кода напрямую зависит от скорости исправления ошибок, то тут современному программисту стоит кумекать да смекать, а нужен ему ассемблер или нет.
Ладно.. Всё это лирика… и обучение. Ошибки в процессе обучения нужно собрать все.
Что о библиотечке.
Библиотечка выехала на оперативный простор.
Теперь, для отрисовки в окне не требуется создавать объект.
Выделяем память: unsigned char window_memory[1400]={0,};
Создаем окно: Display_Window window (20, 20, 120, 120, window_memory, 1400, 2);
Рисуем фигуру: window.Fill_Rectangle (5,5, 40,35);
Отправляем художества на отрисовку: window.Render_Content();
Можно в цикле, можно в функции, передавая например в функцию ссылку на окно. Примеры есть в наличии.
Условие тут всего одно. Выделенной памяти должно хватать на одно окно целиком. Иначе нужно создавать объект и бить окно на сегменты.
Но если брать для сравнения Ардуино Нано с 2Кб ОЗУ то это окшко 100х100, может чуть больше. При этом требуется все не используемое повырезать… (закомментить)
По началу, я сильно разочаровался в 2х цветном режиме, там преимуществ не то что не было, порой он уступал 4х цветному режиму. Я даже табличку накидал с количеством fps…
Но при ближайшем рассмотрении оказалось, что там слишком много лишних движений, некоторые операции оказались попросту не нужны. И 2х цветный режим довольно серьезно отыграл время. И что теперь делать? Табличку переписывать? А в следующей версии все обернется обратно?
Функция которая выводила текст на экран, была написана самой первой, после того как был написан элементарный прямоугольник. И я не мог нарадоваться, насколько быстро выводился текст на экран. Буквы рисуются поэлементно, а не попиксельно, как в большинстве библиотек. Буквы не подтирают фон под собой…
А теперь, в окне, текст не человечески сильно просаживает fps, когда это не счетчик, а символов с два десятка. И оно всё в таком переобувании!
«Становится не важным, что вчера казалось главнее всего»
Ладно, над текстом я думаю можно будет еще поразмыслить…
Есть вопросы и более глобальные.
Подойдя к объекту всплывающего окна, я прикинул, что было бы не плохо, если бы оно оказывалось всегда выше всех объектов, вне зависимости от того когда он был создан. Всплывающее окно должно перекрыть всё что под ним, все логично. Дельце плевое, сместить элемент, даже не на самый край массива, а на край заполненых значений. А освободившееся место замкнуть. Чтобы метод Render_Content(); обыграл данный объект в самую последнюю очередь. Весьма простое ТЗ.
Односвязные списки? Двухсвязные списки? Не, не слышал! :) Вручную потрошить массивы, это уже стало моей слабостью. Сдвгаем вправо, как » чтобы значения упираясь в край исчезали, а не выходили за пределы массива? Да легко! Двигаем с любого места, да легко! Си мне кажется про это! Указатели, циклы и вывернутые наизнанку массивы :)
Все было готово, удачно протестировано. Но я довольно неожиданно въехал в пня! Void массив указателей, сложно подвинуть, даже поменять местами, даже тупо удалить. Беглые попытки его движения советам из тырнета, не привели к успеху.
А void массив указателей, в ключе данной библиотеки ультра экономичен и архи удобен. Иначе пришлось бы подводить под общий знаменатель очень разносторонние объекты. В треугольнике 6 координат и все int. В окружности две int остальные без знаков. В тексте присутствует указатель на массив. Много полей класса просто пустовали бы. Один объект 20 байт, это точно не про ATMega.
Конечно, ситуацию эту я объеду. Я могу оставить void на месте. Сместить данные в остальных массивах, но изменить их нумерацию. Но хотелось бы как минимум их удалять… Но надо будет посмотреть и разобраться.
Пока что, у меня возникает подозрение, что те кто утверждал, что указатель просто хранит аддресс переменной и на этом всё заканчивается, нас мягко говоря вводил в заблуждение.
Новые версии доступны на сайте : http://ямал-спец-альтернатива.рф/Main_menu/Other_works/Arduino_projects/Display_library.html