Skip to main content Link Menu Expand (external link) Document Search Copy Copied
WIA2 Lab 8

Paint - funkcje, przerwania myszy

Ho ho ho, wesołych świąt!


Dziś i w następnym tygodniu zajęcia bardzo przyjemne, ponieważ pracować będziemy razem. Celem Tego bloku zajęć jest stworzenie aplikacji do rysowania, tak abyście mogli na koniec przedświątecznych zajęć narysować w własnoręcznie napisanym paincie kartkę świąteczną. Wszystkie nadające się kartki umieszczę w galerii na stronie, jak tylko wyczaję, jak tu zrobić galerię.

Założenia podstawowe

  • Aplikacja ma działać w trybie graficznym Int 10/AH=00h
  • Rysujemy za pomocą myszy Int 33
  • Kolory zmieniamy wybranym klawiszem Int 16
  • Rozmiar pędzla zmieniamy innym klawiszem

Ten materiał traktować należy jako podstawowy skrypt, bardziej szczegółowy kod stworzymy na zajęciach

Zaczynamy

Pierwszą rzeczą, którą musimy zrobić, to włączenie kursora. Int 33/AX=0001h.

org 100h
mov AX, 0001h
int 33h


mov AH, 4Ch
int 21h

Następnie proponuję napisać pętlę nieskończoną, tak, aby program nie zamykał się od razu po uruchomieniu.

main_loop:

jmp main_loop

Ta pętla ma jeden zasadniczy problem - nie da się z niej wyjść. Proponuję użyć klawisza q.

main_loop:
        mov AH, 00h
        int 16h
        cmp AL, 'q'
je koniec  
jmp main_loop

Tryb graficzny

Na początek, odrobinę teorii i historii (ale mało, obiecuję). W czasach komputera łupanego kluczowym elementem, który pozwalał na wyświetlanie obrazu była karta VGA (Video Graphics Array). To fizyczne urządzenie generowało na podstawie przerwań sygnał wideo, który wyświetlany był na ekranie. Standardowe karty VGA obsługiwały kilka trybów graficznych i tekstowych, zależnych od modelu, z których każde oferowało inną rozdzielczość, paletę kolorów i co najważniejsze: tryb wyświetlania.

Tryb Rozdzielczość Kolory T/G CharBlock AlphaRes
0,1 360x400 16 T 9x16 40x25
2,3 720x400 16 T 9x16 80x25
4,5 320x200 4 G 8x8 40x25
6 640x200 2 G 8x8 80x25
7 720x400 mono T 9x16 80x25
D 320x200 16 G 8x8 40x25
E 640x200 16 G 8x8 80x25
F 640x350 mono G 8x14 80x25
10 640x350 16 G 8x14 80x25
11 640x480 2 G 8x16 80x30
12 640x480 16 G 8x16 80x30
13 320x200 256 G 8x8 40x25

Źródło

Nas interesuje tryb graficzny, myślę że 16 kolorów w zupełnośći nam wystarczy, aby stworzyć piękną kartkę, dlatego też proponuję tryb 0x0E, najwyżej potem zmienimy. Skorzystamy z przerwania Int 10/AH=00h

Na początku programu umieszczam:

mov AH, 00h
mov AL, 0Eh
int 10h

Przydałoby się również wrócić na koniec programu do domyślnego trybu tekstowego. Oczywiście możemy po prostu odpalić polecenie cls po zakończeniu rysowania, ale wtedy nie tworzylibyśmy profesjonalnego oprogramowania. A przecież tworzymy tutaj poważny program.

Przechwytywanie kursora

Potrzebne przerwanie to Int 33/AX=0003h. Zwróci ono status przycisków i aktualną pozycję kursora - bieżąca kolumna zwracana jest w rejestrze CX, wiersz natomiast w rejestrze DX.

W pętli głównej programu umieścić musimy instrukcję, która sprawdzać nam będzie, gdzie dokładnie znajduje się kursor:

mov AX, 0003h
int 33h

Przerwanie to w rejestrach CX i DX zwraca kolumnę i wiersz, w których znajduje się kursor. Narysujemy teraz w tym miejscu piksel przerwaniem Int 10/AH=0Ch. Fartownie, kolumna i wiersz, w których narysowane mają być piksele pobierane są z tych samych rejestrów, w których przed chwilą zostawiło nam je przerwanie 33h.

mov AX, 0003h   ;|
        int 33h         ;|Przechwycenie poz. kursora

        mov AH, 0Ch     ;|
        mov AL, 0Ch     ;|
        mov BH, 0h      ;|
        int 10h         ;|Wydruk piksela na pozycji kursora
Bitfields for mouse button status:

Bit(s)  Description     (Table 03168)
0      left button pressed if 1
1      right button pressed if 1
2      middle button pressed if 1 (Mouse Systems/Logitech/Genius)