Pascal assembler 13h, bufor ekranu, własne fonty.

0

Witam,
Ostatnio wziąłem się za pisanie programu w trybie 13h. Aby szybko działał, użyłem wstawek asseblerowych, a całość składana jest właśnie w pascalu.(Program nie używa żadnych bibliotek typu CRT czy Graph, ani pamięci rozszerzonej)
Mój problem polega na szybkości jego działania, otóż używając typowych pascalowskich poleceń program wyświetla bitmapę z dysku w sekundę (DOSBox przy 3000 cyklach).
Odbywa się to w taki sposób:
0. (Plik z obrazem to zmodyfikowana mapa bitowa - bez nagłówka, palety i odwrócona do góry nogami);

  1. Ładuje plik amorficzny(była jakaś inna tego nazwa) do bufora ekranu bufor:array[0..319,0..119 ] of byte; za pomocą dwóch pętli for na x,y;
  2. Wrzucam bufor na ekran piksel po pikselu pętlą for (x,y) i poleceniem PutPixel (asm, pobiera x,y i color).
  3. Czy możliwe jest użycie monochromatycznej mapy bitowej zamiast 256-cio kolorowej celem oszczędności pamięci?

I teraz moje pytanie brzmi: Jak zrobić to szybciej?
Jak w asmie szybko wysłać bufor na ekran? Musi to być szybciej niż czas powrotu plamki, czyli poniżej 1/25 sekundy.

Problem drugi: Własne fonty.
Otóż przykładowo posiadam bitmapę w 256 kolorach 8x2048 pikseli, i chcę za pomocą procedury wysłać na ekran dowolny tekst, w dodatku przewijający się. Potrzebuję wczytać go do bufora, odczytać id znaku ASCII i użyć tego ID jako offsetu do bitmapy. Następnie wysłać tekst na ekran i zanimować go.
Problemem okazuje się też przycięcie scrolla tekstowego, aby nie zapętlił się gdzieś z drugiej strony ekranu.
I teraz tak:
1.Jak odczytać ID znaku w standardzie ASCII, to znaczy otrzymać z tego liczbę 0-255?
2.Jak szybko przyciąć animowany tekst do szerokości ekranu?

Mam nadzieję, iż ktoś rozpatrzy ten temat i udzieli mi pomocy.
Pozdrowienia,
Sinsky

0

Nie kopiuj bitmapy w ten sposób, tylko za pomocą move kopiuj cały obszar od razu, bądź ładuj bitmapę bezpośrednio pod adres pamięci ekranu. Jeśli będziesz wywoływał jakąkolwiej procedurę dla ustawiania KAŻDEGO piksela z osobna, będzie to BARDZO powolne (co zresztą widzisz).

0

Tak. Czytanie pliku napiszę w asmie, porcjami wielkości rejestru 16-bitowego, do bufora, a następnie na ekran, bo chcę wykorzystać obrazek wielokrotnie, w animacji.
Kod już mam, później go wstawię, ale teraz nasuwa się problem kolejny:
Czytanie monochromatycznych bitmap.
Otóż taka bitmapa jak ulał nadaje się do czcionek, a nie wiem jak zduplikować bity:

Mam w jednym bajcie 4D zapisane 8 pikseli: 0 1 0 0 1 1 0 1 i muszę zrobić z tego 00 FF 00 00 FF FF 00 FF, aby wysłać na ekran(ew. zamiast FF-01).
Wydobyć piksla można za pomocą shr, shl i or, ale dużo to motania, matryca do przekształceń też odpada..
Z tym 01 to można by co drugi bit wstawić zero, ale czy jest to możliwe?

Albo z samym or, może mi się uda..;]

0

Czytania pliku nie musisz robić w assemblerze. Dysk jest na tyle poowoolnyy w stosunku do procesora, że nic tym nie zyskasz. Napisz czytanie z dysku do bufora normalnie, a w asemblerze napisz owo kopiowanie z bufora na ekran, i inne tego typu operacje.

Jeśli chodzi o drugie pytanie, możesz posłużyć się taką tablicą

type tosiem=array[1..8] of byte;
const piksele:array[0..255] of tosiem=(($00,$00,$00,$00,$00,$00,$00,$00),
                                       ($FF,$00,$00,$00,$00,$00,$00,$00),
                                       ($00,$FF,$00,$00,$00,$00,$00,$00),
                                       ($FF,$FF,$00,$00,$00,$00,$00,$00),
                                       ($00,$00,$FF,$00,$00,$00,$00,$00),
                                       ... // zapewne lepiej taką tablicę wygenerować w locie
                                       ($FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF),
                                      );

i adresując pisele[bajt_zrodlowy] dostajesz 8 bajtów wynikowych.
Dwa kilobajty na tablicę nie zabolą, jednak czy to faktycznie będzie szybsze od operacji bitowych - musisz sprawdzić.

0
sinsky napisał(a)

1.Jak odczytać ID znaku w standardzie ASCII, to znaczy otrzymać z tego liczbę 0-255?

var

c: char;
v: byte;
...
c:='a';
v:=ord(c);

Proste ;)

0
sinsky napisał(a)

1.Jak odczytać ID znaku w standardzie ASCII, to znaczy otrzymać z tego liczbę 0-255?
Ale ASCII obejmuje tylko zakres 0-127.

0

3000 cyklach??? 3kHz? Czy ja czegoś nie rozumiem?
W takim przypadku dodaj do tego cztery zera...

0

Przy moich 3000 cyklach na DOSBox'ie chodzą płynnie stare gierki. Sam się dziwie, że WipeOut potrzebuje tylko 10000 cykli do wyświetlenia grafy 3D. Tak więc są to inne cykle niż cykle procesora i mam problem w odniesieniu ich do rzeczywistej szybkości.

Fanael:Połowę roboty mniej;]

Kombinowałem i kombinowałem, ale na razie wróciłem do punktu wyjścia. Obrazek rysuje się powoli i chyba zdecyduje się na ustępstwo co do wymagań - niech działa dobrze na celeronie 1000 i wzwyż. Poza tym problem pamięci rozszerzonej - w borlandowskim TP7.0 domyślnie jest te 600k podstawowej, a na przykład w DevPascalu domyślnie włączona rozszerzona. A i niech będzie pod windę, pod core duo, jako że się uczę pierwsze programiki mogą dużo zżerać.

Dzięki temu będę mógł rysować obraz do bufora wygodnie piksel po pikselu bez obawy, że nastąpi zamulenie.

W tym miejscu chciałbym podziękować wszystkim tym, którzy mi pomogli - że mieli choć trochę czasu w świecie rosnącej konsumpcji i spadających notowań giełdowych, cokolwiek to znaczy.

//Hmm.. Zna ktoś jakąś stronę z wzorami matematycznymi na rotozoomery, kefrens bary czy inne efekty?

0

Wznawiam temat, ostatnio posiedziałem przy moim kodzie i mam już spreparowany elegancko bufor ekranu.

buf:array[0..63999] of byte;

Próbowałem go wysłać przez asma, ale wychodzi nadal na jedno, bierze piksel po pikselu i ma to porównywalną prędkość do paszczala.
Jak szybko wysłać go na ekran?

1 użytkowników online, w tym zalogowanych: 0, gości: 1