plik


Wyświetlanie obrazków BMP Wyświetlanie obrazków BMP Jeśli przejrzeliście mój poprzedni kurs związany z grafiką, to umiecie już coś samodzielnie narysować. Ale przecież w Internecie (i nie tylko) jest tyle ciekawych rysunków, nie mówiąc już o tych, które moglibyście stworzyć dla jakiegoś specjalnego celu, np. swojej własnej gry. Dlatego teraz pokażę, jak takie rysunki wyświetlać. Ze względu na prostotę formatu, wybrałem pliki typu BMP. Plik, który chcecie wyświetlić powinien mieć rozmiar 320x200 pikseli w 256 kolorach (jak pamiętamy, taki rysunek pasuje jak ulał do trybu graficznego 13h). Wszystkie operacje na pliku zostały już przez mnie szczegółowo opisane w jednej z części mojego kursu, więc tutaj nie będziemy poświęcać im zbyt wiele uwagi. Ale przejdźmy wreszcie do interesujących nas szczegółów. Powinniście zaopatrzyć się w cokolwiek, co opisuje format BMP. Informacje, z których będę tutaj korzystał, znalazłem w Internecie (niestety, nie pamiętam już gdzie, ale możecie poszukać na http://www.wotsit.org/). A oto nagłówek pliku BMP (składnia języka Pascal niestety): Autor tekstu: Piotr Sokolowski, 6 maja 1998r -------------------------------------------- Budowa naglowka pliku BMP: Type TBitMapHeader = Record bfType : Word; (dwa bajty) bfSize : LongInt; (cztery bajty) bfReserved : LongInt; bfOffBits : LongInt; biSize : LongInt; biWidth : LongInt; biHeight : LongInt; biPlanes : Word; biBitCount : Word; biCompression : LongInt; biSizeImage : LongInt; biXPelsPerMeter : LongInt; biYPelsPerMeter : LongInt; biClrUsed : LongInt; biClrImportant : LongInt; End; Gdzie: bftype - jest to dwubajtowa sygnatura "BM" bfsize - czterobajtowy rozmiar pliku bfreserved - pole zarezerwowane(0) bfoffbits - przesuniecie poczatku danych graficznych bisize - podaje rozmiar naglowka biwidth - wysokosc bitmapy w pikselach biheight - szerokosc bitmapy w pikselach biplanes - liczba pitplanow(prawie zawsze ma wartosc 1) bibitcound - ilosc bitow na piksel. Przyjmuje wartosc 1,4,8 lub 24. bicompression - sposob kompresji bisizeimag - rozmiar obrazka w bajtach. W przypadku bitmapy nie skompresowanej rowne 0. bixpelspermeter, biypelspermeter - ilosc pikseli na metr biclrused - ˙ilosc ˙kolorow ˙istniejacej ˙palety, ˙a ˙uzywanych wlasnie przez bitmape biclrimporant - okresla ktory kolor bitmapy jest najwazniejszy, gdy rowny 0 to wszystkie sa tak samo istotne. Ale spokojnie - nie musicie znać ich wszystkich, bo my nie będziemy wszystkich używać. Ściśle mówiąc, nie będziemy używać ani jednego z tych pól! No to po co to wszystko? Po to, aby znać długość nagłowka pliku (54 bajty), który ominiemy przy analizie pliku. Po nagłówku idzie paleta 256 kolorów * 4 bajty/kolor = kolejny 1kB. Jeśli macie jakieś wątpliwości co do tego 1 kilobajta, to słusznie. Oczywiście, do opisu koloru wystarczą 3 bajty (odpowiadające kolorom czerwonemu, zielonemu i niebieskiemu - RGB), co daje razem 768 bajtów. Co czwarty bajt nie zawiera żadnej istotnej informacji i będziemy go pomijać (zmienna "z"). Zaraz po palecie idzie obraz, piksel po pikselu. Niestety, nie jest to tak "logiczne" ustawienie, jak byśmy sobie tego życzyli. Otóż, pierwsze 320 bajtów to ostatni wiersz obrazka, drugie 320 - przedostatni, itd. Dlatego trzeba będzie troszkę pokombinować. Zanim jeszcze zaczniemy, należy się przyjrzeć, których portów (choć to samo można uzyskać wywołując odpowiednie przerwanie) i dlaczego będziemy używać (patrzymy do pliku "ports.lst" w Spisie Przerwań Ralfa Brown'a): 03C8 RW (VGA,MCGA) PEL address register (write mode) Sets DAC in write mode and assign start of color register index (0..255) for following write accesses to 3C9h. Don't read from 3C9h while in write mode. Next access to 03C8h will stop pending mode immediatly. 03C9 RW (VGA,MCGA) PEL data register Three consequtive reads (in read mode) or writes (in write mode) in the order: red, green, blue. The internal DAC index is incremented each 3rd access. bit7-6: HiColor VGA DACs only: color-value bit7-6 bit5-0: color-value bit5-0 Czyli, najpierw na 3C8h idzie numer rejestru dla danego koloru (rejestrów jest 256 i kolorów też), a potem na 3C9h idą trzy wartości kolorów: czerwonego, zielonego i niebieskiego, których połączenie daje nam żądany kolor. Ale dobierzmy się wreszcie do kodu: ; Program wyswietla na ekranie kolorowy rysunek o rozmiarze ; 320x200 w 256 kolorach, umieszczony w pliku. ; ; nasm -O999 -o bmp1.com -f bin bmp1.asm ; ; Autor: Bogdan D., bogdandr (at) op (kropka) pl ; ; na podstawie kodu podpisanego "Piotr Sokolowski", napisanego w jezyku Pascal org 100h ; ================================================================= start: mov ax, 13h int 10h ; uruchamiamy tryb graficzny 13h - 320x200x256 mov ax, 3d00h ; otwieramy plik tylko do odczytu mov dx, nazwa_pliku int 21h jnc otw_ok mov ah, 9 mov dx, blad_plik ; wyswietlane, gdy wystapil blad int 21h err: mov ax, 4c01h ; wyjscie z kodem bledu=1 int 21h otw_ok: mov bx, ax ; bx = uchwyt do pliku mov ah, 3fh ; czytanie z pliku mov cx, 54 ; wyrzucamy 54 bajty naglowka mov dx, smieci int 21h jc err ; ================================================= ; wczytywanie palety z pliku: ; ================================================= xor si, si ; wskaznik do tablicy "paleta" czytaj_pal: mov ah, 3fh ; czytanie z pliku mov cx, 4 ; czytam po 4 bajty - do b,g,r i "z". "z" odrzucamy mov dx, b int 21h jc err ; ustawiamy palete: mov al, [r] shr al, 2 mov [paleta+si], al ; paleta[si] = [r] / 4 mov al, [g] shr al, 2 mov [paleta+si+1], al ; paleta[si] = [g] / 4 mov al, [b] shr al, 2 mov [paleta+si+2], al ; paleta[si] = [b] / 4 add si, 3 ; przejdz o 3 miejsca dalej - na kolejne wartosci RGB cmp si, 256*3 ; sprawdz, czy nie zapisalismy juz wszystkich kolorow jb czytaj_pal ; ================================================= ; wysylanie palety do karty graficznej: ; ================================================= xor ax, ax xor si, si ; SI = wskaznik do palety mov dx, 3c8h ; port karty graficznej wyslij_palete: out dx, al ; wysylamy numer rejestru, wszystkie od 0 do 255 inc dx ; DX = port 3C9h push ax ; zapisujemy kolorki: czerowny, zielony, niebieski. mov al, [paleta+si] ; AL = czerwony (patrz petla "czytaj_pal") out dx, al mov al, [paleta+si+1] ; AL = zielony out dx, al mov al, [paleta+si+2] ; AL = niebieski out dx, al pop ax add si, 3 ; przejdz do nastepnych wartosci kolorow dec dx ; DX z powrotem 3C8h inc ax ; wybierzemy kolejny rejestr koloru w karcie graficznej cmp ax, 256 ; sprawdz, czy juz koniec pracy jb wyslij_palete ; ================================================= ; wczytywanie obrazka: ; ================================================= mov ax, 0a000h mov ds, ax ; czytaj bezposrednio do pamieci ekranu mov dx, 64000-320 ; DX = adres ostatniego wiersza mov cx, 320 ; z pliku czytamy po 1 bajcie obrazek: mov ah, 3fh int 21h ; czytaj 320 pikseli prosto na ekran jc err sub dx, 320 ; przejdz do wczesniejszego wiersza jnc obrazek ; dopoki nie musimy "pozyczac" do odejmowania. ; pozyczymy dopiero wtedy, gdy DX < 320 - a to sie ; zdarzy dopiero, gdy DX = 0, czyli przerobilismy ; caly obrazek i ekran ; ================================================= ; koniec programu: ; ================================================= mov ah, 3eh int 21h ; zamknij plik jc err xor ah, ah int 16h ; czekamy na klawisz mov ax, 3 int 10h ; powrot do trybu tekstowego mov ax, 4c00h int 21h ; ================================================= ; dane: ; ================================================= nazwa_pliku db 'rys1.bmp',0 blad_plik db 'Blad operacji na pliku!$' smieci times 54 db 0 paleta times 768 db 0 b db 0 g db 0 r db 0 z db 0 kolor db 0 Mam nadzieję, że kod jest dość jasny. Nawet jeśli znacie assemblera tylko w takim stopniu, w jakim to jest możliwe po przeczytaniu mojego kursu, zrozumienie tego programu nie powinno sprawić Wam więcej kłopotów niż mnie sprawiło przetłumaczenie go z Pascala.

Wyszukiwarka

Podobne podstrony:
BMP TUT
BMP TUT
DOS BMP TUT
ART121 tut 2
phys tut 08
bmp metadata
BMP 2 dentystyka
phys tut 12
DOS DIOD TUT
SYS TUT
ART121 tut 3
MYSZ TUT
PWR TUT
GRAF TUT
tut?2 sdram vhdl

więcej podobnych podstron