Предисловие
В этом уроке мы создадим красивый переход Fade-in и Fade-out в SGDK.
Сначала, скачайте картинку с MEGA.
И импортируйте её в качестве ресурса, с названием img. Про импорт картинок, я говорил в уроке SGDK. Создание изображения.
Перед тем как писать код, поговорим о CRAM.
Что такое CRAM.
- CRAM — это память, способная хранить 4 палитры по 16 цветов, итого 64 цвета. На практике, доступно меньше, т.к. 4 цвета задают прозрачность (по 1-му цвету в каждой палитре).
- Каждый элемент палитры занимает 2 байта, из них, 9 бит отводится под цвет, итого, на выбор дается 512 цветов (2^9 = 512)
Подробно про CRAM (на английском)
Пишем код.
Перепишите данный код к себе в main.c
#include <genesis.h>
#include "resources.h"
int main()
{
u16 palette_full[64];
memcpy(&palette_full[0], img.palette->data, 16 * 2);
PAL_setColors(0, palette_black, 64, DMA);
VDP_drawImage(BG_A, &img, 0, 0);
PAL_fadeIn(0, 63, palette_full, 100, FALSE);
waitMs(3000);
PAL_fadeOut(0, 63, 100, FALSE);
while(1)
{
SYS_doVBlankProcess();
}
return (0);
}
Разберем его.
u16 palette_full[64];
Сначала, создадим массив, в котором будем хранить все палитры. В качестве типа используется u16, 16-ти битное или 2-х байтовое число, ровно столько нужно на 1 элемент палитры. Количество элементов равно 64, этого хватит, что-бы уместить все 4 палитры.
memcpy(&palette_full[0], img.palette->data, 16 * 2);
Функция memcpy — копирует блок данных из одной переменной в другую. Синтаксис у неё следующий.
memcpy(куда_копируем, откуда_копируем, сколько_копируем_в_байтах);
Таким образом, здесь.
memcpy(&palette_full[0], img.palette->data, 16 * 2);
Мы скопировали палитру img.pallette->data в массив palette_full. Палитра состоит из 16-ти элементов, 1 элемент занимает 2 байта, поэтому перемещаем 16*2 байтов.
Данную палитру мы скопировали, что-бы потом восстановить, потому-что в следующей строке, мы перезапишем палитру, и сделаем её черной.
PAL_setColors(0, palette_black, 64, DMA);
PAL_setColors — функция, которая записываем палитру в CRAM. Синтаксис у неё следующий.
PAL_setPaletteColors(начальный_индекс, палитра, конечный_индекс, способ_передачи);
- начальный_ндекс — номер элемента, начиная с которого идет запись палитры (число от 0 до 63)
- палитра — сама палитра.
- конечный_индекс — номер конечного элемента палитры, (число от 0 до 63)
pallete_black — это палитра состоящая из черных цветов. Она подгружается из pal.h которая находится внутри genesis.h.
Приготовления окончены. Теперь, сделаем переход Fade-in(осветление).
PAL_fadeIn(0, 63, palette_full, 100, FALSE);
Синтаксис у функции PAL_fadeIn следующий.
PAL_fadeIn(начальный_цвет, конечный_цвет, палитра, время_перехода_в_фреймах, выполнять_асинхронно);
- начальный_цвет — задает индекс начального цвета (число от 0 до 63)
- конечный_цвет — задает индекс конечного цвета (число от 0 до 63)
- палитра — это палитра, в которую осуществляется переход.
- время_перехода_в_фреймах — указывает, сколько кадров будет длится переход.
- выполнять_асинхронно — если FALSE, программа не будет выполнять следующие комманды, пока не завершится переход, в противном случае — будет.
Таким образом, за 100 кадров, изображение перейдет от черной палитры (pallete_balck), к палитре изображения (pallete_full).
waitMs(3000);
Ждем 3000 мс или 3 секунды.
PAL_fadeOut(0, 63, 100, FALSE);
И затемняем экран, с помощью функции PAL_fadeOut, у которой следующий синтаксис.
PAL_fadeOut(начальный_цвет, конечный_цвет, время_перехода_в_фреймах, выполнять_асинхронно);
Теперь, скомпилируйте и запустите, должно получится следующее.
Итоговый результат.
В гифке, анимация повторяется. У вас такого не будет.