Player/Missile Graphics
From Atariki
Spis treści |
Charakterystyka
Player and Missile Graphics - "grafika graczy i pocisków". Właściwość układu GTIA polegająca na nakładaniu na ekran obiektów niezależnych od zwykłej zawartości ("tła" oraz "ramek"). Generowane w ten sposób ruchome obiekty znane są na innych platformach sprzętowych pod nazwą "duszków" (ang. sprites).
W 8-bitowych komputerach Atari możliwe jest uzyskanie czterech niezależnych graczy i czterech pocisków (lub pięciu graczy - piątego uzyskujemy przez połączenie czterech pocisków).
Kształt
Każdy gracz ma szerokość 8 pikseli. Ich kształty definiuje się w osobnych obszarach pamięci określonych przez zawartość PMBASE ($D407). Każdemu bitowi w bajcie odpowiada jeden piksel gracza.
Kolejne bajty definiowane w obszarze dowolnego gracza:
0 7 - piksel n ........ ..oooo.. .o....o. o.o..o.o o......o o.oooo.o .o....o. ..oooo.. n+8 ........ : 7 0 - bit bajt
Szerokość pocisku wynosi 2 piksele. Ponieważ wszystkich dostępnych pocisków jest dokładnie 4, to definiuje się je razem poprzez wypełnienie odpowiednich par bitów w obszarze pocisków określanym również przez zawartość PMBASE ($D407):
Kolejne bajty definiowane w obszarze pocisków:
3 2 1 0 - pocisk : : : : 01 01 01 01 - piksel n .. .. .. .. .. oo oo .. .o .. .o o. o. .. oo .o o. .o o. .o o. oo .. .o .o o. .. o. .. oo oo .. n+8 .. .. .. .. : 76 54 32 10 - bit bajt
Każdemu bitowi, podobnie jak w przypadku graczy, odpowiada dokładnie jeden piksel pocisku.
Wysokość sprajta odpowiada wysokości ekranu, czyli 240 pikseli w rozdzielczości jednoliniowej (piksel ma wysokość jednej linii ekranowej), lub 120 w rozdzielczości dwuliniowej (piksel ma wtedy wysokość dwóch linii ekranowych). Wynika to z faktu, że ANTIC rozpoczyna pobieranie danych dla kształtu sprajtów z pamięci RAM w 8 linii skanningowej, a kończy w 247. O tym czy pobierane są dane dla graczy, czy dla pocisków, czy dla wszystkich sprajtów decydują bity 2 i 3 rejestru DMACTL ($D400) kontrolujące DMA.
Można jednakże definiować kształty sprajtów bez pośrednictwa ANTIC-a wpisując odpowiednie dane bezpośrednio do rejestrów GRAFP0-3 i GRAFM. Dane te są wykorzystywane każdorazowo kiedy plamka rysująca obraz osiąga poziomą pozycję na ekranie równą wartościom zapisanym w rejestrach HPOSP0-3 i HPOSM0-3. Modyfikując więc co jakiś czas (przykładowo co okres trwania linii skaningowej) zawartość wspomnianych rejestrów można własnoręcznie definiować kształty sprajtów nawet wtedy, kiedy ANTIC nie rysuje obrazu (bity 0 i 1 rejestru DMACTL ($D400) są zgaszone). Stwarza to pole do realizacji przeróżnych programowych technik generowania obrazu jak na przykład:
- replikacja sprajtów w linii (przez zmianę rejestrów pozycji poziomej HPOSP0-3 i HPOSM0-3),
- multiplikacja sprajtów w linii i na ekranie (przez zmianę rejestrów pozycji poziomej HPOSP0-3 i HPOSM0-3, kształtu GRAFP0-3 i GRAFM i kolorów COLPM0-3 ewentualnie COLPF3 czy szerokości SIZEP0-3 i SIZEM),
- rozciąganie sprajta (przez modyfikację rejestru szerokości SIZEP0-3 i SIZEM),
- zmiany priorytetów sprajtów (przez modyfikację rejestru PRIOR).
Kolory
Jeden gracz może mieć dowolny wybrany z palety kolor - pocisk ma ten sam kolor co odpowiadający mu gracz (np. jeśli gracz nr 3 ma kolor $0A, wtedy pocisk nr 3 ma również kolor $0A). Wyjątkiem jest sytuacja, kiedy łączymy pociski w celu otrzymania piątego gracza - w tym przypadku gracz ten otrzymuje kolor z rejestru COLPF3 ($D019). Przez ingerencję w rejestr GTIACTL ($D01B) można też spowodować, że nakładające się piksele obiektów będą miały trzeci kolor uzyskiwany przez wykonanie bitowego OR na wartościach rejestrów kolorów nakładających się obiektów (tzw. gracze wielokolorowi). Nakładanie kolorów zachodzi wyłącznie w parach:
- PM0 + PM1 : gracz 0 lub pocisk 0 + gracz 1 lub pocisk 1
- PM2 + PM3 : gracz 2 lub pocisk 2 + gracz 3 lub pocisk 3
Możliwe jest również uzyskanie dodatkowych kolorów na ekranie przez ustalenie priorytetu 0 dla graczy i pocisków.
Kolory ustalamy wpisując odpowiednie wartości do rejestrów COLPM0-COLPM3 ($D012-$D015).
Priorytety
W rejestrze GTIACTL ($D01B) można określić priorytety wyświetlania poszczególnych sprajtów i elementów grafiki. Do tego celu konstruktorzy przeznaczyli aż 4 bity.
Wyboru priorytetu dokonuje się poprzez ustawienie dokładnie jednego bitu.
bit | 3210 | kolejność | ||||||||
znaczenie | 0001 | PM0 | PM1 | PM2 | PM3 | PF0 | PF1 | PF2 | PF3 | BAK |
0010 | PM0 | PM1 | PF3 | PF2 | PF1 | PF0 | PM2 | PM3 | BAK | |
0100 | PF3 | PF2 | PF1 | PF0 | PM0 | PM1 | PM2 | PM3 | BAK | |
1000 | PF0 | PF1 | PM0 | PM1 | PM2 | PM3 | PF2 | PF3 | BAK |
UWAGA! Pierwszeństwo COLPF3 ($D019) przed innymi kolorami można zaobserwować kiedy połączy się wszystkie pociski w piątego gracza, gdyż wtedy właśnie ten rejestr definiuje ich kolor.
Ustawienie priorytetu 0 powoduje, prócz uzyskania dodatkowych kombinacji kolorów, następujące ustalenie priorytetów:
bit | 3210 | kolejność | ||||||||
znaczenie | 0000 | PM0 | PM1 | PF0 | PF1 | PM2 | PM3 | PF2 | PF3 | BAK |
Analogicznie ustawienie kilku bitów równocześnie powoduje, poza wyświetleniem koloru czarnego, ustalenie następujących priorytetów:
bit | 3210 | kolejność | ||||||||
znaczenie | 0011 | PM0 | PM1 | PF2 | PF3 | PM2 | PM3 | PF0 | PF1 | BAK |
0101 | PF3 | PF2 | PM0 | PM1 | PM2 | PM3 | PF0 | PF1 | BAK | |
0110 | PF3 | PF2 | PF1 | PF0 | PM0 | PM1 | PM2 | PM3 | BAK | |
0111 | PF3 | PF2 | PM0 | PM1 | PM2 | PM3 | PF0 | PF1 | BAK | |
1001 | PM0 | PM1 | PM2 | PM3 | PF0 | PF1 | PF2 | PF3 | BAK | |
1010 | PF0 | PF1 | PM0 | PM1 | PM2 | PM3 | PF2 | PF3 | BAK | |
1011 | PM0 | PM1 | PF2 | PF3 | PM2 | PM3 | PF0 | PF1 | BAK | |
1100 | PF3 | PF2 | PF1 | PF0 | PM0 | PM1 | PM2 | PM3 | BAK | |
1101 | PF3 | PF2 | PM0 | PM1 | PM2 | PM3 | PF0 | PF1 | BAK | |
1110 | PF3 | PF2 | PF1 | PF0 | PM0 | PM1 | PM2 | PM3 | BAK | |
1111 | PF3 | PF2 | PM0 | PM1 | PM2 | PM3 | PF0 | PF1 | BAK |
Kolor ramki COLBAK ($D01A) ma zawsze najniższy priorytet, tak więc niemożliwe jest przykrywanie sprajtów przez ramkę ekranu.
Dodatkowe kolory
Ustawienie priorytetu 0 powoduje, że kolory sprajtów zaczynają interferować z kolorami pola gry pozwalając na uzyskanie dodatkowych barw. Odbywa się to analogicznie, jak w przypadku wyświetlania sprajtów wielokolorowych przez dokonanie operacji bitowego OR na wartościach odpowiednich rejestrów kolorów, lecz kolory sprajtów - poza nakładaniem się w parach PM0+PM1 i PM2+PM3 - interferują dodatkowo z kolorami pola gry (PFx):
- PF0 + PM0
- PF0 + PM1
- PF0 + PM0 + PM1
- PF1 + PM0
- PF1 + PM1
- PF1 + PM0 + PM1
- PF2 + PM2
- PF2 + PM3
- PF2 + PM2 + PM3
- PF3 + PM2
- PF3 + PM3
- PF3 + PM2 + PM3
W ten sposób umiejętnie manipulując kształtem, szerokością i położeniami sprajtów można w wierszu uzyskać 23 różne kolory.
Niestety łącząc pociski w piątego gracza nie uzyskamy nakładania PF2 z PF3.
Hi-Res
W trybach wysokiej rozdzielczości nałożenie sprajta na pole gry powoduje zmianę koloru tła wszędzie tam gdzie piksel sprajta jest zapalony. W konsekwencji wszystkie piksele grafiki mają kolor pobrany z rejestru sprajta, przy czym jasność piksela zgaszonego (0) brana jest z rejestru koloru sprajta, natomiast jasność piksela zapalonego (1) brana jest z rejestru COLPF1 ($D017).
Ponieważ zarówno kolor tła, jak i piksela pobierany jest z rejestru COLPF2 ($D018), to nieco inaczej wygląda również nakładanie kolorów sprajtów kiedy włączony jest priorytet 0 i zachodzi wyłącznie w przypadkach:
- PF2 + PM2
- PF2 + PM3
- PF2 + PM2 + PM3
- PF3 + PM2
- PF3 + PM3
- PF3 + PM2 + PM3
Ponieważ połączenie pocisków w piątego gracza powoduje, że kolor pocisków brany jest z rejestru COLPF3 ($D019), to w miejscach gdzie piksele pocisków są zapalone kolor PF2 jest zastępowany przez PF3. Nakładanie kolorów zaś odbywa się w tym przypadku tylko między pociskami (które traktowane są jak pole gry PF3) a graczami.
Pierwsza para sprajtów PM0 i PM1 reaguje wyłącznie między sobą, ponieważ żaden piksel pola gry nigdy nie przybiera koloru pobranego z COLPF0 ($D016) lub COLPF1 ($D017).
Z kolei druga para zawsze interferuje z kolorem COLPF2 ($D018) lub COLPF3 ($D019), a więc kombinacje
- PM2
- PM3
- PM2 + PM3
możliwe są wyłącznie na ramce, gdzie wyświetlany jest COLBAK ($D01A) (co, nawiasem mówiąc, zwiększa pulę kolorów możliwych do uzyskania w linii z 23 do 26).
Kolor czarny
Jednoczesne ustawienie kilku bitów odpowiadających priorytetom sprajtów w rejestrze GTIACTL ($D01B) skutkuje wyświetleniem koloru czarnego w miejscach nakładania sprajtów na pole gry, niezależnie od tego jakie wartości ustawione są w rejestrach kolorów.
I tak dla priorytetów:
- %0110
- %1001
kolor czarny uzyskuje się kombinacjami:
- PF0 + PM0
- PF0 + PM1
- PF0 + PM0 + PM1
- PF1 + PM0
- PF1 + PM1
- PF1 + PM0 + PM1
Analogicznie dla priorytetów:
- %0011
- %1100
działają kombinacje:
- PF2 + PM2
- PF2 + PM3
- PF2 + PM2 + PM3
- PF3 + PM2
- PF3 + PM3
- PF3 + PM2 + PM3
oraz dla priorytetów:
- %0101
- %0111
- %1010
- %1011
- %1101
- %1110
- %1111
wszystkie kombinacje czyli:
- PF0 + PM0
- PF0 + PM1
- PF0 + PM0 + PM1
- PF1 + PM0
- PF1 + PM1
- PF1 + PM0 + PM1
- PF2 + PM2
- PF2 + PM3
- PF2 + PM2 + PM3
- PF3 + PM2
- PF3 + PM3
- PF3 + PM2 + PM3
UWAGA! Warto pamiętać, że przy włączeniu piątego gracza kolor pocisków pobierany jest z COLPF3, a więc w takim przypadku gracz 2 lub 3 nałożony na dowolny pocisk będzie generował kolor czarny.
Pozycjonowanie
Pozycję poziomą graczy kontroluje się wpisując ich położenie do rejestrów HPOSP0-HPOSP3 ($D000-$D003). Podobnie zmienia się pozycję poziomą pocisków - należy wpisywać pożądane wartości do rejestrów HPOSM0-HPOSM3 ($D004-$D007). Są to rejestry tylko do zapisu.
ANTIC wyświetla 228 cykli koloru w linii, co przekłada się na maksymalną widoczną pozycję poziomą sprajta. Poniżej znajdują się pozycje sprajta odpowiadające położeniom krawędzi ekranu zależnie od jego szerokości konfigurowanej za pomocą bitów 0 i 1 w rejestrze DMACTL ($D400):
wartość | lewa krawędź | prawa krawędź | opis |
%00 | - | - | pusty ekran |
%01 | $40 | $C0 | wąski ekran |
%10 | $30 | $D0 | normalny ekran |
%11 | $20 | $E0 | szeroki ekran |
Środek ekranu znajduje się w pozycji $80. Lewa krawędź widocznego obrazu znajduje się w pozycji $2C, prawa - w $D4 - i są to ograniczenia dla obrazu generowanego przez ANTIC. GTIA potrafi wyświetlić obraz w nieco szerszym zakresie $22-$DE.
W przypadku gdy ANTIC wyświetla obraz szeroki, wtedy w obszarze $DC-$DD wyświetlają się tzw. "śmieci", czyli przypadkowe dane pobierane z szyny danych, które można przykryć sprajtami.
Niestety nie ma rejestrów określających pozycję pionową - kontroluje się ją zmieniając położenie graczy oraz pocisków w obszarze pamięci wskazywanym przez PMBASE ($D407).
Obiekt | Obszar względem PMBASE w rozdzielczości | |
dwuliniowej | jednoliniowej | |
pociski | $0184-$01FB | $0308-$03F7 |
gracz 0 | $0204-$027B | $0408-$04F7 |
gracz 1 | $0284-$02FB | $0508-$05F7 |
gracz 2 | $0304-$037B | $0608-$06F7 |
gracz 3 | $0384-$03FB | $0708-$07F7 |
ANTIC rysuje na ekranie telewizyjnym 240 linii począwszy od linii 8, a skończywszy na 247. Z tego względu w rozdzielczości jednoliniowej na ekranie widoczna jest treść duszka zdefiniowana bajtami 8..247, a w rozdzielczości dwuliniowej bajtami 4..123 obszaru wskazywanego przez PMBASE ($D407). Pozostałe bajty znajdują się "poza ekranem" i nie są nigdy widoczne.
Ustawienie bitu w rejestrze VDELAY ($D01C) powoduje obniżenie rysowania odpowiedniego sprajta o jedną linię skanningową, ale tylko kiedy ustawiona jest rozdzielczość dwuliniowa w DMACTL ($D400).
Wykrywanie kolizji
Istnieje również możliwość sprzętowego wykrywania wzajemnych kolizji duszków z polem gry (ale nie z kolorem tła), jak i z innymi duszkami. Służą do tego rejestry tylko do odczytu:
- KOLM0PF-KOLM3PF ($D000-$D003) Kolizja pocisku z polem gry. Wartości odczytujemy z poniższego schematu:
Bit 7 6 5 4 3 2 1 0 Rejestr koloru ...nieużywane.... 3 2 1 0
- KOLP0PF-KOLP3PF ($D004-$D007) Kolizja gracza z polem gry:
Bit 7 6 5 4 3 2 1 0 Rejestr koloru ....nieużywane... 3 2 1 0
- KOLM0P-KOLM3P ($D008-$D00B) Kolizja pocisku z graczem (nie ma rejestrów służących do wykrywania kolizji pocisku z pociskiem):
Bit 7 6 5 4 3 2 1 0 Duszek ...nieużywane.... 3 2 1 0
- KOLP0P-KOLP3P ($D00C-$D00F) Kolizja gracza z graczem:
Bit 7 6 5 4 3 2 1 0 Duszek ...nieużywane.... 3 2 1 0
Zresetowanie wszystkich rejestrów kolizji następuje po zapisaniu dowolnej wartości do HITCLR ($D01E).
Rozmiar
Matryca graczy ma 8 punktów szerokości, pocisków - 2 punkty. Gracze oraz pociski mogą być sprzętowo rozszerzane za pomocą przeznaczonych do tego celu rejestrów. Możliwe są: szerokość pojedyncza, podwójna i poczwórna. Uzyskuje się je ustawiając odpowiednie kombinacje bitów w rejestrach SIZEP0-SIZEP3:
Bit 7 6 5 4 3 2 1 0 Szerokość: ...nieużywane... 0 0 pojedyncza (8 cykli koloru) 0 1 podwójna (16 cykli koloru) 1 0 pojedyncza 1 1 poczwórna (32 cykle koloru)
Dla ustalenia szerokości dla pocisków używa się rejestru SIZEM ($D00C):
Bity Szerokość: pojedyncza podwójna poczwórna 7 i 6: pocisk 3 0,128 64 192 5 i 4: pocisk 2 0, 32 16 48 3 i 2: pocisk 1 0, 8 4 12 1 i 0: pocisk 0 0, 2 1 3
Co do wysokości, zarówno gracze jak i pociski mają zawsze wysokość całego ekranu (łącznie z ewentualnymi ramkami) - oczywiście widać przy tym tylko te ich części, które zostały "narysowane" w obszarze pamięci wskazywanym przez rejestr PMBASE $D407. Bit skasowany oznacza tu piksel przezroczysty, bit ustawiony - piksel w kolorze wybranym dla danego duszka.
Linki
- Altirra Hardware Reference Manual ze szczegółowym opisem możliwości sprzętowych układu GTIA
- Wątek na forum Atari Age z opisem priorytetu 0
- Wątek na forum Atari Online z dyskusją nad 22 kolorami w linii
- Artykuł na Atari Online opisujący mechanizmy nakładania kolorów
- Opis na forum AtariArea jak rozciągać sprajty
- Wyjaśnienia Foxa na forach AtariAge i AtariOnline o tym jak działa rysowanie sprajtów
- Ankieta Pavrosa odnośnie wysokości ekranu