Obsługa myszki w Pascalu

Patkoss

Pobaw się z myszką!

W czasach, kiedy świat systemów operacyjnych (domowych coraz częściej i korporacyjnych) jest zdominowany przez systemy o graficznym obliczu, zabawa z myszką wydaje się być archaizmem. Należy jednak pamiętać, że istnieją także systemy gdzie większość roboty wykonuje się i tak w konsoli. Systemem takim jest z pewnością Linux. Kod ten może być stosowany zarówno w systemach wywodzących się z DOS'a (Windows'y) jak i Unix'a (Linux'y). Umiejętność niskopoziomowego programowania myszy może być nadal użyteczna, a z pewnością jest to ciekawe. Zatem odpal swój ulubiony edytor i zaprzęgnij swój ulubiony kompilator do roboty.

Pierwszą rzecz jaką musimy posiadać (oprócz myszy oczywiście), jest to jej sterownik. Jeżeli masz mysz masz także sterownik - systemy najczęściej mają wbudowany sterownik (biedny DOS nie miał). Myszka jest obsługiwana pod przerwaniem 33h. Najpierw więc sprawdźmy czy myszka istnieje (jest poprawnie podłączona, sterownik w pamięci, kot nakarmiony):

var mouse_present: word;
asm
  mov ax, 0;
  int 33h;
  mov mouse_present, ax;
end;
if mouse_present<>0 then writeln ('Mouse isn''t present or driver not loaded!');

Jeśli w rejestrze AX pojawi się wartość różna od 0, znaczy to że wystąpił błąd w teście obecności myszy. W Windows błąd taki nie może wystąpić, chyba że faktycznie nie posiadasz myszki lub pracujesz w trybie DOS'a. Następna rzecz jaką zrobimy to wyświetlenie kursora:

asm
  mov ax, 1;
  int 33h;
end;

Jeśli chcielibyśmy ukryć kursor, zmieńmy numer funkcji na 2:

asm
  mov ax, 2;
  int 33h;
end;

Kolejną przydatną rzeczą (chyba najbardziej) jest umiejętność odczytania położenia kursora i stanu przycisków myszy. Nie ma problemu. Assembler wespół ze sterownikiem myszy zapewniają to jedną funkcją o nr. 3. Kodujmy więc:

var x, y, keys: word;
asm
  mov ax, 3;
  int 33h;
  mov x, cx; {położenie poziome kursora znajduje się w rejestrze CX}
  mov y, dx; {położenie pionowe kursora znajduje się w rejestrze DX}
  mov keys, bx; {w rejetrze BX zawarta jest informacja o klawiszach}
end;

Po wykonaniu powyższych instrukcji w zmiennych x oraz y otrzymamy aktualne położenie kursora (jeżeli chcemy ciągle odczytywać te wartości powinniśmy umieścić je w pętli), natomiast zmienna keys zawierać będzie informacje o klawiszach. Jak odczytać te wartości? Trzeba przeprowadzić test bitów. Jeżeli najmłodszy bit (pierwszy) jest ustawiony oznacza to, że lewy przycisk był przyciśnięty w momencie wywoływania przerwania 33h. Jeżeli drugi bit jest ustawiony oznacza to, że prawy przycisk był wciśnięty:

if keys and 1 then writeln ("Left key's pushed.");
if keys and 2 then writeln ("Right key's pushed.");

I to wszystko co potrzebne jest do poprawnej obsługi myszy. Istnieje jeszcze wiele różnych funkcji do obsługi myszy, powiedzmy sobie teraz o dwóch, limitujących obszar poruszania się kursora:

var horiz_min, horiz_max, vert_min, vert_max: word;
{limity położeń poziomych i pionowych}
begin
  horiz_min:=10; horiz_max:=20;
  vert_min:=10; vert_max:=20;
  asm
    mov ax, 7; {ustal limity poziome}
    mov cx, horiz_min;
    mov dx, horiz_max;
    int 33h;
    mov ax, 8; {ustal limity pionowe}
    mov cx, vert_min;
    mov dx, vert_max;
    int 33h;
  end;
end;

I to wszystko już, oczywiście nie jest to limit wszystkich funkcji dostępnych dla myszy, lecz te są z pewnością najbardziej użyteczne. Sam pracuję w obydwu środowiskach, więc życzę miłej zabawy w Windows i w Linux.

16 komentarzy

hmm coś mi się widzi że musze pokombinować w fpc z winApi(czy tam z byle innym shi**m.).. bo Dos w fpc to raczej.... eee... nie działa?

int 33h działa pod Linuksem? Aż za chwilę przetestuje..

EDIT: Przetestowałem i dostaje caly czas:
"Naruszenie ochrony pamięci"

IMHO int 33h to interfejs do sterownika myszy od MS

"...if mouse_present<>0 then writeln ('Mouse isn''t present or driver not loaded!');
</delphi>

Jeśli w rejestrze AX pojawi się wartość różna od 0" -ludzie widzicie błąd to poprawcie...

Czy nie lepiej dołączyć moduł drivers.tpu
Jak wygląda obsługa myszy z uzyciem modułu drivers.tpu
Gdzie jest plik pomocy do modułu drivers.tpu

"Czy Twoja myszka jest podłączona do portu COM1, COM2, czy też PS/2?"

Pod USB.

Można też mychę ogsługiwać bez kota ;) (sterownika), lecz wtedy trzeba kombinować z portami. Ale dla cierpliwych, to dobre zajęcie. Tylko wtedy wymagane byłoby od użytkownika programu:
Czy Twoja myszka jest podłączona do portu COM1, COM2, czy też PS/2?

sqli: Jest dobrze tylko komentarz był nie poprawny .
Jeżeli wyrzuci 0 do Ax to znaczy że niepodłonczono / zainstalowano ...
natomiast jeśli FFFFh to znaczy że podłączono ... itd ;P

A jak to wygląda w trybie graficznym? Bo u mnie jak użyłem myszy to w momencie gdy ruszyłem myszą w czasie odświeżania ekranu to pół obrazu miałem czarno-białe pasy (były też inne jaja). W końcu wkurzyłem się i wywaliłem obsługę myszy i poobsadzałem wszystko na klawiaturę :-)

Czy nie można tego zrobić bez asma? Od czego jest biblioteka "Dos" i jej polecenia?

A co będziesz asembler przekładał na C??

A może gdyby autor pisał komunikaty po polsku, to wiedziałby co komputer nadaje, bo trochę się pogubił.

musio : oczywiscie, można. ale po co ?

(dla niekumatych : rejestry + przerwania są obsługiwane w TP bez potrzeby wpisywania wstawek asmowych, tylko że dużo wolniej...)

Mi się wydaje że można to zrobić nie wykorzystując assemblera.

Jednak działa, komunikat się wyświetla, ale mysz działa. Nie znam się na assemblerze, ale czy tam nie powinno być
if mouse_present=0 then writeln ("Mouse isn't present or driver not loaded!");
czyli =0 a nie <>0. ?

Mam windows xp i mi wyswietla "Mouse isn't present or driver not loaded!" , czy to działa na winxp??

a moglby ktos ten jezyk zamienic na C ? ;P