Девятая версия дома!
В 8.5 были допущена крайне досадная ошибка, вызванная работой над ошибками и исправлением ошибок. Это тот случай, когда запилил обновление, толком не протестив, даже в уже специально подготовленных для этих целей примерах. Но ошибка как минимум интересная, разберу её чуть позже.
В девятой версии мне удалось реализовать отрисовку графических элементов через условно "экранную память". Все логически к этому шло, так как это во всех смыслах корректный режим и для динамического изображения и самое главное написания кода для анимации.
Изначально я настраивался на 4 цвета. Прикинул, что именно для анимированных элементов 3 цвета + фон, вполне себе. 4 цвета, это значит я смогу уместить пиксель в одной паре бит. В данной схеме нет ничего хитрого, так же например хранятся спрайты на Денди. Ну плюс палитра, разумеется палитра есть и у меня.
Но как оказалось хитрость в хранении тайлов и спрайтов на денди все же есть и о ней стоит упомянуть.
Если открыть любой редактор для ромхакинга, мы можем убедиться что любой тайл или спрайт состоит из 4х цветов, один из которых зачастую фон.
Если 1 пара бит будет хранить состояние одного пикселя, то для хранения 1 тайла, размером 8х8, потребуется (8х8)/4=16 байт адресуемой памяти. И это так и есть, только хранятся со смещением. Первый бит пары в первом байте, следующий. Следующий из пары уже в следующем или со сдвигом на 8 байт, точно не припомню. Сложно сказать с чем связана была такая форма записи. Возможно для двухцветных режимов...
Но хитрость тут в другом. Все элементы закодированы лишь 4мя цветами, но на экране присутствует гораздо больше цветов.
Я связываю это с тем, что спрайты и тайлы в ROM-ах хранятся в разных местах катриджной памяти, зачастую между ними бывают пустые промежутки. И в случае если подгружается тайл из диапазона с ... по ..., то используем палитру А, из следующего диапазона - Палитра Б и т.д.
Вот например, почти все спрайты принадлежат одной палитре. И расположены они в ROM-е в одном месте.
Но тут уж утверждать 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 не проверял, но точно знаю что ругаться будет. Эти правки я оставлю на потом. Непонятно в каком виде будет Си часть библиотеки... Так как по сути они используют разные методы и функции и при использовании обоих будут занимать уж очень много места... Нужно было некоторую точку сохранения пройти, чтобы уже выдохнуть.