Autor: | Wojciech Muła |
---|---|
Dodany: | 9.03.2002 |
W artykule pokażę jak zminimalizować ilość przesyłanych danych przy przesuwanych w pionie napisach. Oczywiście można analogicznie postąpić przy scollach w poziomie.
Poniżej zostały zdefiniowane wszystkie stałe i zmienne które będą wykorzystywane w przykładach.
const unsigned int img_width; // rozmiar const unsigned int img_height; // obrazka const unsigned int text_height;// wysokość tekstu typedef pixel scanline[img_width]; // pojedyncza linia obrazu scanline image[img_height]; // bufor obraz scanline text [text_height]; // bufor dla 1 linii tekstu // funkcja wyświetla generuje napis w buforze 'text' void render_text(const char* string);
W poniższym pseudokodzie obraz jest przesuwany do góry.
int text_scanline = text_height; ... while (stop == 0) { for (int i=0; i<img_height-1; i++) // przesuń obraz o 1 linię do góry image[i] = image[i+1]; // czasochłonne if (text_scanline == text_height) // "wysunięto" już całą linię tekstu { // należy wygenerować nowy tekst render_text(...); text_scanline = 0; } image[img_height-1] = text[text_scanline++]; // przepisz do ostatniej linii // obrazu jedną z linii tekstu screen = image; // wyświetl obraz }
Przesunięcie image o 1 linię wymaga przesłania (img_height-1)* img_width pikseli i tego należy się pozbyć.
Proponuję potraktować image jako bufor okrężny scanlinów.
int text_scanline = text_height; // licznik wyświetlonych linii tekstu int top_line = 0; // wskaźnik początku bufora okrężnego while (stop == 0) { if (text_scanline == text_height) // "wysunięto" już całą linię tekstu { // należy wygenerować nowy tekst render_text(...); text_scanline = 0; } // przepisanie do ostatniej linii obrazu jednej z linii tekstu // ostatnia w buforze okrężnym nie tablicy! image[top_line] = text[text_scanline++]; / należy kopiować scanliny z bufora ekranu w trochę innej kolejności n = 0; for (i=top_line; i<img_height; i++) // najpierw kopiujemy górną część screen[n++] = image[i]; for (i=0; i<top_line; i++) // a następnie dolną screen[n++] = image[i]; // zwiększamy top_line top_line += (top_line+1) % img_height; }
W przypadku gdy obliczenie reszty z dzielenia będzie kłopotliwe (np. pisząc w asemblerze) można użyć prostszego kodu:
if (++top_line == img_height) top_line=0;
Przyrost prędkości będzie znaczny, zostało wyeliminowane praktycznie jedno przesyłanie bufora bardzo niewielkim kosztem.
Poniżej zestawienie liczby przesłań scanlinów w obu metodach:
Teoretycznie można więc liczyć na około 200% wzrost prędkości.