SGDK. Меняем тайлы в спрайте.

Введение.

При создании HUD в игре на Sega Genesis, у вас есть 2 пути:

  • Использовать WINDOW слой
  • Использовать спрайты

WINDOW слой откусывает кусок BG_A, это значит что HUD не получится сделать прозрачным. Тогда как, спрайтовый HUD лишен этих недостатков.

Спрайтовый HUD из Sonic The Hedgehog

Что мы знаем о спрайтах:

  • Sega Genesis поддерживает спрайты от 8×8 px до 32×32 px (реальные спрайты).
  • Спрайты побольше, достигаются за счет одновременного использования нескольких спрайтов (программные спрайты).
  • У спрайтов есть лимит на скан-линию в 20 спрайтов. Т.е. 20 спрайтов могут пересекать горизонтальную линию поперек экрана, иначе они багуют.
  • Максимальное количество спрайтов — 80.

Так вот, почему-бы не использовать доступное пространство внутри спрайта — эффективно. Т.е. редактировать тайлы внутри спрайта, что-бы уменьшить вероятность влезть в лимиты на скан-линию.

Сперва, скачайте проект с github, затем откройте main.c в папке src. Разберем его.

Меняем тайл спрайта.

TileSet tempTileset;
tempTileset.tiles = MEM_alloc(sizeof(u32)*img_1.tileset->numTile);

unpackTileSet(img_1.tileset, &tempTileset);
VDP_loadTileSet(&tempTileset, sonic_obj->attribut & TILE_INDEX_MASK, CPU); 

Этими строками, я создал тайлсет и аллоцировал под массив тайлов нужное количество байтов.

TileSet tempTileset;
tempTileset.tiles = MEM_alloc(sizeof(u32)*img_1.tileset->numTile);

img_1 — является Image ресурсом, внутри которого есть указатель на tileset, из которого, я достал количество тайлов.

Далее, с помощью функции unpackTileset, я распаковал тайлсет img_1 и записал в переменную tempTileset.

unpackTileSet(img_1.tileset, &tempTileset);

При распаковке, выделилась память под тайлсет, не забудьте очистить её (MEM_free) когда уже не будет нужна (при смене уровня например).

Тайлсет получен, осталось записать его в VDP, для этого используется VDP_loadTileSet. У которого следующий синтаксис:

VDP_loadTileSet(откуда_брать_тайлсет, куда_в_VDP_писать, способ_передачи); 

где:

  • откуда_брать_тайлсет — это указатель на переменную типа Tileset
  • куда_в_VDP_писать — номер тайла в VDP, куда будем писать.
  • способ_передачи — может быть CPU, DMA, DMA_QUEUE, DMA_QUEUE_COPY, самый стабильный CPU, а также, самый медленный.
VDP_loadTileSet(&tempTileset, sonic_obj->attribut & TILE_INDEX_MASK, CPU); 

Данная строка:

sonic_obj->attribut & TILE_INDEX_MASK

Возвращает номер начального тайла в VDP, который использует спрайт.

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

А еще, вы можете отредактировать тайл под себя, вот так:

unpackTileSet(img_1.tileset, &tempTileset);
tempTileset.tiles[0] = 0xFFFFFFFF;
tempTileset.tiles[1] = 0xFFFFFFFF;

Каждый символ после 0x, отвечает за индекс цвета в палитре. Таким образом, вы можете менять пиксели тайла.

Генерируем свой тайл, и подставляем в спрайт.

Вы также, можете заменить тайл спрайта сгенерированным тайлом, примерно так:

const u32 sprite_tileset[16] =
{
0x000FF000,
0x00FFFF00,
0x0FFFFFF0,
0xFFFFFFFF,
0xFFFFFFFF,
0x0FFFFFF0,
0x00FFFF00,
0x000FF000,

0x000EE000, 0x00EEEE00, 0x0EEEEEE0, 0xEEEEEEEE, 0xEEEEEEEE, 0x0EEEEEE0, 0x00EEEE00, 0x000EE000
};

PAL_setPalette(PAL3, spr_sonic.palette->data, DMA);
sonic_obj = SPR_addSprite(&spr_sonic, x,  y, TILE_ATTR(PAL3, 0, FALSE, FALSE));
SPR_update();
SYS_doVBlankProcess();
	
VDP_loadTileData(sprite_tileset, sonic_obj->attribut & TILE_INDEX_MASK, 2, СPU);

Здесь, sprite_tileset представляет из себя данные тайлов спрайта. В примере видно, что каждое число после 0x, задает цвет (от 0 до F, или от 0 до 15).

И, функцией VDP_loadTileData, записываем тайл в VRAM по такому синтаксису.

VDP_loadTileData(тайлсет, номер_тайла_в_VDP, количество_загруженных_тайлов, способ_передачи);

В итоге, получили следующее:

Конвертируем тайлсет в код.

Можно сконвертировать картинку в код, подобного типа:

const u32 sprite_tileset[16] =
{
0x000FF000,
0x00FFFF00,
0x0FFFFFF0,
0xFFFFFFFF,
0xFFFFFFFF,
0x0FFFFFF0,
0x00FFFF00,
0x000FF000,
};

Делается это с помощью Python скрипта написанного Greg Gallardo, скачайте его в отдельную папку.

В папке со скриптом, добавьте картинку с вашими тайлами, и переименуйте в ground_tiles.png, и запустите скрипт. Код, отобразится в консоли.

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

Пожалуйста отключи блокировщик рекламы, или внеси сайт в белый список!

Please disable your adblocker or whitelist this site!