SGDK. Крутим палитру.

Предисловие.

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

Разбираем код.

Скачайте 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);

Итоговый результат.