| Start | Super Packer | Atari Graphics Studio / AGS | Graph2Font / G2F | Mads |   http://madteam.atari8.info  
SKŁAD GRUPY
PRODUKCJE
scena
gry
użytki
vbxe
SPRZĘT
Sio2SD/Pajero
Sio2SD/Rocky
Stereo/Pajero
GTIA/Psychol
ARTYKUŁY
DEMO EFFECTS
LINKI
   

Bewesoft
Szybkie piksele
Syzygy #8

tłumaczył: Lizard/Aids

Tak, zgadza się, artykuł ten zawiera trochę informacji o szybkich procedurach graficznych trybu wysokiej rozdzielczości. Lecz tym razem nie będzie mowy o jednej tylko procedurze, a o całym ich zestawie niezbędnym do zrobienia dema: CLS, PLOT, DRAW i CIRCLE! Jednym słowem, coś dla was koderzy!

Przed ujawnieniem szczegółów, pokażę wam, że opisane tu procedury naprawdę działają i są bardzo szybkie. Wyjdźcie na chwilę z magazynu i uruchomcie program GREXAMPL.COM, poźniej wróćcie do tego tekstu.

Zróbcie to teraz, a ja zaczekam!



Czekam........

Ok, już jesteście z powrotem? No to kontynuujemy...

Jeśli naprawdę obejrzeliście przykładowy program, to zobaczyliście okrąg, linię i punkt, a wszystko to w jednej ramce! Nawet duże obiekty (okrąg o średnicy 200 pikseli, linia długości 256 pikseli) są na tyle szybko rysowane, że można ich wyświetlić 50 w ciągu sekundy! (Demo nie używa procedury CLS - wykorzystałem do pokazu tylko jeden ekran, gdyż przy czyszczeniu ekranu zobaczylibyście nieprzyjemne miganie...)

W archiwum dołączonym do magazynu znajdują się źródła (w formacie ATMAS II) przykładowego programu, który właśnie przed chwilą zobaczyliście. Każdy plik źródłowy zawiera po jednej procedurze do rysowania okręgu, linii oraz w głównym dwie procedury: CLS i PLOT oraz wszystkie inne rzeczy takie jak Display List, inicjowanie tablic, pętla główna, itd... Zauważyć należy, że wszystkie procedury korzystają z tych samych tablic, tak więc, aby użyć np. CIRCLE należy też skopiować podprogram inicjujący z pliku MAIN.

Wszystkie procedury są całkiem szybkie, lecz jeśli ktoś uważa, że nie są dość szybkie, to może je jeszcze przyspieszyć. Jak? Należy tak rozlokować procedury, tablice, zmienne, itp. w pamięci, by skoki warunkowe nie odbywały się pomiędzy różnymi stronami, gdyż jak wiadomo, wykonują się wtedy o cykl dłużej z powodu zmiany starszego bajtu PC... (Co, nie wiedzieliście, że małe Atari ma w sobie PeCeta?)

Teraz trochę informacji na temat omawianych procedur...

Po pierwsze DRAW. Działa w pełnym zakresie od 0-255 na obydwu współrzędnych. Współrzędne początku i końca linii muszą być podane w zmiennych X0, X1, Y0 i Y1.

Jeśli chcielibyście wiedzieć jak działa procka DRAW, to zerknijcie do "Quick draw routine" w MegaZine #6. Opublikowałem tam procedurę, która nie była jednak najszybsza i używała całego dostępnego obszaru na stronie zerowej... Później WosFilm przedstawił ulepszoną wersję. W końcu, kilka miesięcy temu (teraz już lat - przyp. tł.) dostałem jeszcze jedną wersję od Konopa z S.C.G. (dzięki!). Ta procka była całkiem szybka, jednak mnie udało się napisać jeszcze szybszą, zawierającą najlepsze pomysły ze wszystkich podprogramów. Ta (najszybsza) wersja jest zamieszczona w przykładzie na dysku.

Główne zmiany to: oddzielne procedury dla różnych kierunków rysowania, pętla główna skopiowana jest osiem razy (niektóre zmienne zmieniono na stałe, które są różne w zależności od kopii procedury), a sprawdzenie, czy nastąpił koniec linii umieszczony jest tylko w jednej kopii (w pozostałych przypadek ten nie występuje). Oczywiście procedura zmodyfikowana w ten sposób jest trochę długa (12 KB kodu źródłowego), lecz kto by się tym przejmował...

Procedura PLOT powinna być wywoływana z pozycją X i Y w odpowiednich rejestrach. Prawdopodobnie jest to najszybsza procedura; złożona z kilku innych. Pomysły do niej zaczerpnąłem m.in. z Barymaga i od Konopa/S.C.G.
Ponieważ procedura jest bardzo krótka, to nie ma potrzeby używania czasochłonnych rozkazów JSR, RTS. Dlatego też, PLOT napisany został jako makro.
Kolej na CLS. Procedura wzorowana jest na artykule Detail'a "Fast graphics operations for the 6502" z MegaZine'u #7. Celem jest przyspieszenie czyszczenia pamięci ekranu poprzez wpisanie do pamięci większej ilości rozkazów STA (oszczędność czasu poprzez wyeliminowanie pętli). Problem w tym, że chcąc wyczyścić 7kB (tyle ma pamięć ekranu) tylko przez samo STA, potrzeba 21 KB na tę "procedurę"! To zbyt wiele. Postanowiłem więc połączyć tę metodę z tradycyjną pętlą - 2.5 KB STA wykonane osiem razy. Czas zużywany przez pętle jest znikomy, a wymagania pamięciowe nie zmuszają do kupna PeCeta. Główna procedura (2.5 B długości) tworzona jest przez mały generator...

OKRĘGI

Ostatnia procedua - CIRCLE - napisana jest całkowicie przeze mnie. Nie wiem, czy ktoś inny też ją napisał; przynajmniej nic mi o tym nie wiadomo...

Parametry dla tej procy należy przekazać w rejestrach (X, Y, R odpowiednio w X, Y, A). Współrzędne X, Y mogą mieć dowolny zakres (0-255), a promień ograniczony jest w zakresie od 0 do 127 (pamiętać należy, że średnica jest dwa razy dłuższa).

Wyjaśnię teraz jak działa ten podprogram. Zazwyczaj rysując okrąg, stosuje się funkcje trygonometryczne. Od razu wam radzę: zapomnijcie o nich - są zbyt wolne!!!

Cudowną rzeczą czyniącą mój okrąg szybkim jest to (twierdzenie Pitagorasa):

              /|
            c/ |b
            /  |
           -----
             a     c^2=a^2+b^2

Zacznijmy od początku... Podczas rysowania okręgu określonego przez (X, Y, R), dodajemy do siebie współrzędne X, Y przed zapaleniem każdego pi- ksela. Pozwala to tylko na rysowanie okręgu o parametrach (0, 0, R). Dzielimy też okrąg na osiem części:

                          ...
                       . " | " .
                     : \ 3 | 2 / :
                    :   \  |  /   :
                   .'  4 \ | / 1  '.
                   :-------+-------:
                   '. 5  / | \  8 .'
                    :   /  |  \   :
                     : / 6 | 7 \ :
                      '.   |   .'
                         """"""

(sorry za ten paskudny rysunek, lecz w proporcji ciężko jest zrobić dobre ASCII, jakby ktoś nie wiedzał, to jest to kółko podzielone na osiem równych części - przyp. tł.)

Można rysować wszystkie osiem części w tym samym czasie. Wykonując obliczenia dla pierwszej części zapalamy piksele o współrzędnych: (X,Y) (Y,X) (-Y,X) (-X,Y) (-X,-Y) (-Y,-X) (Y,-X) (X,-Y)

Teraz pozostało już wyjaśnić jak obliczyć tę pieprzoną "pierwszą część" okręgu. Ok... Wiadomo, że każdy punkt na okręgu jest równo oddalony od środka - to jest promień. Jeśli środkiem jest punkt (0, 0), to prawdą jest, że: X^2 + Y^2 = R^2. Teraz definiujemy funkcję F(X,Y) = X^2+Y^2-R^2. Wartością tejże funkcji jest pewien rodzaj wskazania, gdzie położony jest piksel: wartość dodatnia - poza okręgiem, ujemna - wewnątrz okręgu.

Reszta jest już dość podobna do procedury DRAW opisanej w MegaZine #6. Zaczynamy od X=R i Y=0. Ponieważ będziemy rysować tylko pierwszą część (0-45 stopni), wystarczy, że będziemy wykonywać tylko pionowe (w górę) lub ukośne (w górę i lewo) kroki. Obliczamy wartość F(X-0.5,Y+1) - brzeg pomiędzy dwoma możliwym pikselami - i sprawdzamy znak wyniku. Ujemny - pionowy krok, dodatni - ukośny.

A jak wyglądają obliczenia? Na szczęście wszystkie "^2" zniknęły, więc można użyć prostych rozkazów assemblera. Na początek obliczamy:

F(R-0.5,0) = 0.25-R

A może myślicie, że powinno być F(R-0.5,1)... Oczywiście macie rację, lecz to nie pomyłka. Program (zajrzyjcie do archiwum) rozpoczyna się w środku procedury dla pionowego kroku, umieszczając piksel na pozycji (R, 0), czyli krok ten wykonywany jest przed pierwszym "prawdziwym" krokiem...

Ponieważ dodawane i odejmowane są tylko wartości całkowite, można zrobić to prościej - wszystkie znaki (+/-) podczas obliczeń będą identyczne. Tak więc, w programie znajduje się:

F(R-0.5,0) = -R

Następne wartości będą obliczone na podstawie poprzednich w następujący sposób (używając nowych współrzędnych X, Y): Po pionowym kroku:

F(X-0.5,Y+1) = F(X-0.5,Y) + 2*Y+1

I po skośnym kroku:

F(X-0.5,Y+1) = F(X+0.5,Y) + 2*Y-2*X+1

I to wszystko. Jeśli chcecie, możecie używać moich procedur we własnych demach i innych produkcjach, lecz, proszę, nie zapomnijcie wspomnieć, kto jest ich autorem. Jeśli ktoś przyspieszy moje procedury, niech da mi znać!

Udanego kodowania!!!!

Bewesoft

 

madteam.atari8.info © MadTeam, hosted: www.atari8.info