Создание графики для nes/dendy

Предыдущие мои статьи рассказывают о том как начать программировать под денди на ассемблере. Мы научились отрисовывать спрайты и background, так же мельком обсудили что такое таблица атрибутов и таблица имен, так же мы разобрались как прочитать контроллер. В тех статьях Я использовал chr от игры super mario bros 2 потому как не художник, но все же для создания игры мне пришлось искать инструменты какое мне помогут в создание своей графики для игры. Под катом этапы разработки графики.

Довольно много времени ушло на то что бы найти инструмент под linux для создания таблицы имен, через какое то время я даже начал писать своё на php. Идея была проста, и уже был близок к завершению. Возможно конвертировать изображение bmp или png пройдя попиксельно. С лева на право 128 пикселей, и с верху в низ 256 строк. Далее определяем цвет каждого пикселя, а таких может быть всего 4-ре и в зависимости от цвета ставим соответствующие биты, каждый пиксель в файле chr описывается 2 битами, по следующему принципу:

  • цвет 0 = 00 = 00000000

  • цвет 1 = 01 = 00000001

  • цвет 2 = 10 = 00000010

  • цвет 3 = 11 = 00000011

То есть эти 2 бита всего лишь последние 2 бита порядкового номера цвета. При этом в спрайтах цвет 0 — прозрачный цвет. В background’e это цвет фона.

В chr буквально храниться 2 банка, 128 на 128 пикселей. Часто 1-банк используется для спрайтов (и называется левым), 2-й банк в свою очередь используется для спрайтов фона (ну или тайлов, Я могу ошибаться в терминологии). С этим разобрались, и вот как только Я заканчивал свой скрипт, то нашел уже готовый на node.js img2chr

Скрипт устанавливается довольно просто

$ npm install -g img2chr

У данного скрипта есть 2-ва параметра 1-й это файл картинки (я использую png), 2-й это файл куда надо сохранить chr

img2chr test.png test.chr

После этого мы можем подключать chr в коде и использовать его.

Немного об эмуляторе FCEUX

Попробовал несколько эмуляторов к моменту написания этой статьи, оказалось что более всего удобен FCEUX под Windows, запущенный из под wine. Он предоставляет дебагер, и может дампить nametable и attribute table что довольно удобно для правильного рендера уровней.

Как я сказал выше Я не художник, и тем более не умею красиво рисовать. Первым делом я создал изображение 128×256 пикселей расчертил по 8 пикселей ячейку, ошибся в первой ячейки, но оказалось не критично.

Картинка с линиями
308ed3beabdaf74783829731ef911846.png

Зеленой линией я разделил картинку на две страницы. Далее я нарисовал грубые контуры будущих спрайтов.

Грубый набросок
f6f2e5f804c7bba17c346a5469e9d676.png

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

Кулаки и удаленные спрайты
2eebe37c131e4f984db8e24ae0728f29.png

Далее я начал работу над сглаживанием контуров, приводя контуры к более геометрически правильному виду, удалив лишние пиксели, и там где не хватало добавил. Часть изображения начал раскрашивать уже в оттенке серого.

Контуры и цвета
e91a8ab3e3df673bae1fb79e3731c841.png

Далее я продолжил раскраску спрайтов в соответствующие цвета

Цвета промежуточный вариант
7ba5fb8d97e10eccce90ad1cf3fbebf9.png

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

Окончательный вариант
d928cf4f96888f7e6907f75a6719298c.png

После этого мне оставалось одно запустить команду

img2png test.png t.chr

Импортировать себе в код и нарисовать фон и спрайты. Напомню что спрайты рисуются довольно просто последовательной записью в порт PPU $2004

  1. Y — координаты

  2. Номер спрайта

  3. Маска отображения

  4. X — координата

Типичный код отрисовки спрайта выглядит так

LDA #100 ; загружаем в акумулятор A значение 100
STA $2004 ; сохраняенм значение координаты Y в порт $2004
LDA #$01 ; спрайт под номером 1 (0-я строка, 1-й спрайт) 
STA $2004 ; записываем спрайт в порт
LDA #%00010110 ; маска 
STA $2004
LDA #100 ; x координата 
STA $2004

И на экране был выведен мой спрайт. Что не могло не радовать. После этого я вывел все спрайты для отрисовки героя их вышло 10, конечно это очень большое количество спрайтов, так как мы можем достичь ограничений приставки например 64 спрайта одновременно на экране, но об этом мы поговорим в следующих статьях.

Предыдущие статьи:

  1. Программирование NES

  2. Считывание контроллера

© Habrahabr.ru