Предисловие.
В этом уроке мы разберем кручение палитры. Данная техника позволит вам создать красивые градиентные анимации, с минимальной нагрузкой на процессор.
Разбираем код.
Скачайте SGDK проект с github и откройте main.c. Сначала разберем вспомогательные функции.
void leftRotatebyOne(u16 arr[], u16 n)
{
u16 temp = arr[0], i;
for (i = 0; i < n - 1; i++)
arr[i] = arr[i + 1];
arr[n-1] = temp;
}
Функция leftRotatebyOne — крутит палитру на 1 шаг. Она принимает:
- Массив — arr
- Количество элементов в нем — n
Еще, данная комманда может вас смутить:
u16 temp = arr[0], i;
Но это лишь короткая запись этого:
u16 temp = arr[0];
u16 i;
Далее, функция leftRotate вызывает функцию leftRotatebyOne нужное количество раз.
void leftRotate(u16 arr[], u16 d, u16 n)
{
u16 i;
for (i = 0; i < d; i++)
leftRotatebyOne(arr, n);
}
Она принимает:
- Массив — arr
- Количество шагов поворота — d
- Размер массива — n
Ок, теперь разберем главную функцию paletteRotationScene.
void paletteRotationScene(){
u16 my_pal0[16]; //Создаем массив под палитру
PAL_setPalette(PAL0, img.palette->data, CPU); //Записываем палитру изображения в PAL0
curTileInd = 16;
PAL_getPalette(PAL0, my_pal0); //Из PAL0 достаем палитру, и записываем в my_pal0 массив
SYS_doVBlankProcess();
VDP_drawImageEx(BG_B, &img, TILE_ATTR_FULL(PAL0, 0, FALSE, FALSE, curTileInd), 0, 0, FALSE, TRUE); //рисуем картинку на BG_B слое
curTileInd += img.tileset->numTile;
while(1){
leftRotatebyOne(my_pal0, 16); //Крутим массив my_pal0 на 1 шаг
PAL_setPalette(PAL0, my_pal0, DMA); //Меняем палитру PAL0 на палитру my_pal0
SYS_doVBlankProcess();
}
}
Весь код я объяснил в комментариях.
По итогу, получили красивую градиентную анимацию.

Крутим часть палитры.
Если же вам нужно крутить не всю палитру, а только часть — делаем так.
leftRotatebyOne(&my_pal0[начало_индекс], количество_цветов);
где,
- начало_индекс — задает номер цвета, с которого начинаем кручение палитры
- количество_цветов — задает количество цветов для кручения.
Вот пример:
leftRotatebyOne(&my_pal0[2], 8);
Итоговый результат.
