Найти тему

Библиотека переходит в оконный режим.

Девятая версия дома!
В 8.5 были допущена крайне досадная ошибка, вызванная работой над ошибками и исправлением ошибок. Это тот случай, когда запилил обновление, толком не протестив, даже в уже специально подготовленных для этих целей примерах. Но ошибка как минимум интересная, разберу её чуть позже.

Оконный режим библиотеки Display Library режим SPI ATMega328p Display 320x240
Оконный режим библиотеки Display Library режим SPI ATMega328p Display 320x240

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

Изначально я настраивался на 4 цвета. Прикинул, что именно для анимированных элементов 3 цвета + фон, вполне себе. 4 цвета, это значит я смогу уместить пиксель в одной паре бит. В данной схеме нет ничего хитрого, так же например хранятся спрайты на Денди. Ну плюс палитра, разумеется палитра есть и у меня.

Но как оказалось хитрость в хранении тайлов и спрайтов на денди все же есть и о ней стоит упомянуть.

Если открыть любой редактор для ромхакинга, мы можем убедиться что любой тайл или спрайт состоит из 4х цветов, один из которых зачастую фон.

ROM первой части игры Megamen
ROM первой части игры Megamen

Если 1 пара бит будет хранить состояние одного пикселя, то для хранения 1 тайла, размером 8х8, потребуется (8х8)/4=16 байт адресуемой памяти. И это так и есть, только хранятся со смещением. Первый бит пары в первом байте, следующий. Следующий из пары уже в следующем или со сдвигом на 8 байт, точно не припомню. Сложно сказать с чем связана была такая форма записи. Возможно для двухцветных режимов...

Но хитрость тут в другом. Все элементы закодированы лишь 4мя цветами, но на экране присутствует гораздо больше цветов.

-3

Я связываю это с тем, что спрайты и тайлы в ROM-ах хранятся в разных местах катриджной памяти, зачастую между ними бывают пустые промежутки. И в случае если подгружается тайл из диапазона с ... по ..., то используем палитру А, из следующего диапазона - Палитра Б и т.д.

Вот например, почти все спрайты принадлежат одной палитре. И расположены они в ROM-е в одном месте.

-4

Но тут уж утверждать 100% точно я не могу. Но могу 100% утверждать, что заморачиваться до такой степени, что иметь несколько палитр на один кадр, я точно не буду. Режим 16 цветов, как оказалось не сильно отстает от 4х.


Всё это хорошо, но не все так хорошо с оперативной памятью.
Путем не сложных подсчетов, мы можем прикинуть, что для некоторой, скажем прямо, весьма скудной, области размером 144 на 144 пикселя, далее именуемой окном, для 4х цветного режима необходимо: 144х144=20736/4 = 5184(байт). То есть в 1 байт, по 2 пары на место у нас влезает 4 пикселя. Но даже для такого микроскопического окна, требуется более 5 килобайт оперативной памяти, которой в 328-й Атмеге попросту неоткуда взять.
Заранее скажу что всё крутиться расходуя всего 1 килобайт ОЗУ. На первый взгляд может показаться, что из воздуха ОЗУ берется, а нет алгоритм рационально подходит к потреблению драгоценной памяти. Т
Ну и стандартная задача. Место есть только под 1 килобайт, а вместить нужно 5. А если речь про 16 цветов. То есть под цвет необходимо выделить одну тетраду байта... Это на размер 144х144 потребуется уже 10 килобайт ОЗУ. Заранее скажу что, ну уже с небольшими тормозами но 328-ая Атмега потянет и это!

В чем же алгоритм? По сути своей алгоритм прост. Окно по горизонтали бьется на сегменты, в зависимости от количества выделенной памяти. Сегмент представляет собой окно поменьше, по высоте, но с той же шириной как и основное.
Некоторый объект, если он попадает в текущий сегмент, отправляется на отрисовку. Сперва он заносится в выделенное для этого ОЗУ. Потому туда попадают второй, третий объект.. Когда будут внесены все созданные объекты, память можно отправляется на отрисовку, то есть отправлять в память дисплея. Далее переходим к следующему сегменту...

Данный режим создавался для создания максимально простой анимации. Режим работает по класической схеме. Чем меньше выделенного ОЗУ и чем выше разрешение экрана, тем сильнее тормоза.

Теперь, нет мерцания объекта из-за его постоянного подтирания. Анимация смотрится достойно. Код максимально простой. Создаем окно, создаем объекты, которые по координатам находятся уже в отсчете окна (в локальных координатах окна), далее двигаем объекты, изменяем. И отправляем "экранную память" в память дисплея.

Из самых первых минусов, это то что я пробую С++. И всё это весит как windo... как конь! И это я пока еще не вписал в библу цифры и буквы. Так как пока еще не понял в каком именно виде стоит их туда инкрустировать. Да и по сути это нова ветка библиотеки. Как будет расти старая ветка, я пока еще не решил.

Но более примечательным оказались иные моменты...
Изначально я планировал, что библа будет работать в режиме 2х и 4х цветов. Прикинув что 16 цветов, будет для 1кб ОЗУ (и даже для 6Кб атмеги 2560) слишком тяжело. Предварительная практика показала, что для записи в память объекта в 2х цветном режиме, требуется значительно больше движений, чем при записи в 4х и 16-ти цетном режиме. Сегментов окна становится меньше, а времени на запись объектов тратится больше.
Изначально казалось, что между режимами 4 и 16 цветов будет гигантская, квадратичная разница. А на практике, различаются они порой не сильно.

Другая интересная особенность заключается в общем размере прошивки.
Особенность работы данного режима библиотеки, что все методы отрисовки всех существующих объектов прибывают в игре, вне зависимости был создан объект или нет. Поэтому решил их выпиливать условной компиляцией. И я оказался весьма удивлен, когда время прохождения демки с фигурками сократилось. Решил не останавливаться и в условную компиляцию завел еще и режимы работы библиотеки (2, 4 и 16 цветов) И был приятно удивлен, что помимо размера прошивки, возросла скорость прорисовки демки. Прирост составил 15-20%.

Хорошая получилась работа, приятный результат, но я несколько озадачен... Есть что необходимо оптимизировать. Большие надежды были на 2х цветный режим, а вот на 16ти цветный надежды не было. Да и с цветами я опять намудрил, нужен подготовить тест для сведения цветов.

Все в очень тестовом виде. Все настройки библиотеки находятся в заголовочном файле Display_Lib_Window.h Пока нет описания методов, потому как пока нет четкого понимания с их работой. В Atmel Studio не проверял, но точно знаю что ругаться будет. Эти правки я оставлю на потом. Непонятно в каком виде будет Си часть библиотеки... Так как по сути они используют разные методы и функции и при использовании обоих будут занимать уж очень много места... Нужно было некоторую точку сохранения пройти, чтобы уже выдохнуть.