Zanim zaczniemy, znajdziesz w systemie mieszankę SNES-a i Game Boy'a, a rdzeniem graficznym nadal jest dobrze znany silnik 2D o nazwie PPU. Zalecam przeczytanie tych artykułów przed kontynuowaniem, ponieważ powrócę do wielu wcześniej wyjaśnionych koncepcji.
W porównaniu z poprzednimi Game Boy'ami mamy teraz ekran LCD, który może wyświetlać do 32 768 kolorów (15 bitów). Ma rozdzielczość 240 x 160 pikseli i częstotliwość odświeżania ~60Hz.
Organizowanie treści
Grafika jest rozproszona w następujących obszarach pamięci:
- 96 KB 16-bitowego VRAM-u (RAM-u Wideo): Gdzie 64 KB przechowuje tła i 32 KB przechowuje sprite'y.
- 1 KB 32-bitowego OAM-u (Pamięci Atrybutów Obiektów): Przechowuje do 128 wpisów sprite (nie grafiki, tylko indeksy i atrybuty). Jego magistrala jest zoptymalizowana pod kątem szybkiego renderowania.
- 1 KB 16-bitowego PAL RAM-u (RAM-u Palety): Przechowuje dwie palety, jedną dla tła, a drugą dla sprite'ów. Każda paleta zawiera 256 wpisów 15-bitowych kolorów, przy czym kolor
0jest przezroczysty.
Konstruowanie klatki
Jeśli czytałeś poprzednie artykuły, GBA będzie Ci znajomy, chociaż istnieją dodatkowe funkcje, które mogą Cię zaskoczyć, i nie zapominaj, że ta konsola działa na dwóch bateriach AA.
Wypożyczę grafikę z Sonic Advance 3 firmy Sega, aby pokazać, jak składa się klatka.
Kafelki

Te dwa bloki są wykonane z Kafelków 4 bpp.

Możesz zauważyć tutaj dziwne pionowe wzory, nie są to grafiki, ale 'Mapy Kafelków' (patrz następna sekcja).

Te dwa bloki są zarezerwowane dla sprite'ów.
Kafelki GBA są ściśle bitmapami 8x8 pikseli, mogą używać 16 kolorów (4 bpp) lub 256 kolorów (8 bpp). Kafelki 4 bpp zajmują 32 bajty, a 8 bpp zajmują 64 bajty.
Kafelki mogą być przechowywane w dowolnym miejscu w pamięci VRAM, jednak PPU chce je pogrupować w charblock'i: Regiony 16 KB. Każdy blok jest zarezerwowany dla określonego typu warstwy (tła i sprite'ów), a programiści decydują, gdzie zaczyna się każdy charblock. Może to spowodować pewne nakładanie się, co w konsekwencji umożliwia dwóm charblock'om współdzielenie tych samych kafelków.
Ze względu na rozmiar charblock'a, w jednym bloku można przechowywać do 256 płytek 8 bpp lub 512 płytek 4 bpp. Dozwolonych jest do sześciu charblock'ów, które łącznie wymagają 96 KB pamięci: dokładnej ilości pamięci VRAM, jaką ma ta konsola.
Tylko cztery charblock'i mogą być użyte jako tła, a dwa mogą być użyte jako sprite'y.
Tła

Warstwa Tła 3 (BG3).
Ta konkretna warstwa będzie przesuwana poziomo na pewnych liniach skanowania, aby zasymulować efekty wody.
Warstwa tła tego systemu znacznie się poprawiła od czasu Game Boy Color. W końcu zawiera niektóre funkcje znalezione w Super Nintendo (pamiętasz przekształcenia afiniczne?).
PPU może narysować do czterech warstw tła. Możliwości każdego z nich będą zależeć od wybranego trybu działania :
- Tryb 0: Zapewnia cztery warstwy statyczne.
- Tryb 1: Dostępne są tylko trzy warstwy, chociaż jedna z nich jest afiniczna (można ją obracać i/lub skalować).
- Tryb 2: Dostarcza dwie warstwy afiniczne.
Każda warstwa ma wymiar do 512x512 pikseli. Jeśli jest afiniczna, to będzie miała rozmiar do 1024x1024 pikseli.
Fragment danych definiujący warstwę tła to Mapa Kafelków. Aby wdrożyć ją w sposób zrozumiały dla PPU, programiści używają screenblock'ów, konstrukcji definiującej części warstwy tła (32x32 kafelki). Screenblock zajmuje tylko 2 KB, ale do zbudowania całej warstwy będzie potrzebny więcej niż jeden. Programiści mogą umieścić je gdziekolwiek wewnątrz charblocków tła, co oznacza, że nie wszystkie wpisy kafelków będą zawierały grafikę!
Sprite'y
Rozmiar sprite może mieć szerokość do 64x64 pikseli, jak na tak mały ekran będą okupywać jego dużą część.
Jeśli to nie było wystarczające, PPU może teraz zastosować transformacje afiniczne do sprite'ów!
Wpisy sprtie mają szerokość 32 bitów, a ich wartości można podzielić na dwie grupy:
- Atrybuty: Zawiera pozycję x/y, przesunięcie h/v, rozmiar, kształt (kwadratowy lub prostokątny), typ sprite'u (afiniczny lub regularny) i położenie pierwszego kafelka.
- Dane afiniczne: Używany tylko wtedy, gdy sprite jest afiniczny, określają skalowanie i obrót.
Rezultat

Wszystkie warstwy scalone (Tada!).
Jak zawsze, PPU automatycznie połączy wszystkie warstwy, ale to jeszcze nie koniec! System może również zastosować kilka efektów na tych warstwach:
- Mozaika: sprawia, że kafelki wyglądają bardziej kwadratowo.
- Mieszanie alfa: Łączy kolory nakładających się warstw, aby uzyskać efekty przezroczystości.
- Okienkowanie: Dzieli ekran na dwa różne okna, gdzie każde może mieć własne oddzielne grafiki i efekty, zewnętrzna strefa obu okien może być również renderowana za pomocą kafelków.
Z drugiej strony, aby zaktualizować klatkę, dostępne jest wiele opcji:
- Wydaj polecenie CPU: Procesor ma teraz pełny dostęp do pamięci VRAM, kiedy tylko chce. Może jednak powodować niechciane artefakty, jeżeli zmieni niektóre dane w połowie klatki, więc oczekiwanie na VBlank/HBlank (tradycyjny sposób) pozostaje w większości przypadków najbezpieczniejszą opcją.
- Użyj Kontrolera DMA: DMA zapewnia ~10-cio krotnie szybszy transfer i może być zaplanowany podczas VBlank i HBlank. Ta konsola zapewnia 4 kanały DMA (dwa przeznaczone na dźwięk, jeden do operacji krytycznych, a ostatni do celów ogólnych). Miej na uwadzę, że kontroler zatrzyma procesor podczas operacji (chociaż praktycznie tego nie zauważy!).
Poza Kafelkami
Czasami możemy chcieć utworzyć tło, z którego tile engine nie będzie w stanie narysować wszystkich wymaganych grafiki. Nowoczesne konsole rozwiązały ten problem, implementując architekturę bufora-klatek, ale nie jest to możliwe, gdy jest bardzo mało RAM... Cóż, tak się składa, że GBA ma 96 KB pamięci VRAM, co wystarcza do przydzielenia bitmapy o wymiarach naszego ekranu LCD.
Dobrą wiadomością jest to, że PPU faktycznie implementuje tę funkcjonalność, uwzględniając trzy dodatkowe tryby, zwane trybami bitmapy :
- Tryb 3: Przydziela pojedynczą w pełni kolorową klatkę (16 bpp, 32,768 kolorów).
- Tryb 4: Zapewnia dwie klatki z połową kolorów (8 bpp, 256 kolorów) każda.
- Tryb 5: Dwie w pełni kolorowe klatki, każda o połowę mniejsza (160x128 pikseli).
Powodem posiadania dwóch bitmap jest włączenie przewracania-stron: Rysowanie na wyświetlanej bitmapie może ujawnić pewne dziwne artefakty podczas procesu. Jeśli zamiast tego manipulujemy inną, żaden z błędów nie zostanie pokazany użytkownikowi. Po zakończeniu drugiej bitmapy, PPU można zaktualizować, aby wskazywał na drugą, skutecznie zamieniając wyświetlaną klatkę.

Super Monkey Ball Jr. (2002).
Tryb bitmapowy umożliwił procesorowi dostarczenie podstawowej grafiki 3D do scenerii.
Obiekty pierwszego planu to sprite'y (oddzielna warstwa).

Demo Tonc'a.
Renderowana bitmapa z kilkoma prymitywami.
Zauważ, że ekran nie pokazuje znaczących wzorów generowanych przez silniki kafelków.

SpongeBob Kanciastoporty Nickelodeon'a.
Odcinek rozpowszechniany jako kartridż Gba Video (oczywiście był mocno skompresowany).
Ogólnie rzecz biorąc, brzmi to jak najnowocześniejsza funkcja, jednak większość gier trzymała się silnika kafelków. Czemu? Ponieważ w praktyce kosztuje dużo zasobów procesora.
Widzisz, podczas korzystania z silnika kafelków procesor może delegować większość obliczeń do układu graficznego. W przeciwieństwie do tego, system buforowania klatki, który zapewnia PPU, ogranicza się tylko do wyświetlania tego segmentu pamięci jako pojedynczej warstwy tła, co oznacza brak indywidualnych transformacji afinicznych, warstw lub efektów, chyba że procesor je obliczy. Ponadto, bufor-klatki zajmuje 80 KB pamięci, więc tylko 16 KB (połowa) jest dostępnych do przechowywania kafelków sprite'ów.
Z tego powodu te tryby są używane oszczędnie, na przykład do odtwarzania wideo (Game Boy Advance Video całkowicie na tym polegał) lub renderowania Geometrii 3D za pomocą procesora. W każdym razie wyniki były co najmniej imponujące.


