Myszka i C

Patkoss

Pewien czas temu, gdy umieściłem w dziale Turbo Pascal artykuł o programowaniu myszki w tym języku, opatrzony on został komentarzem, że powinien być on także przeredagowany dla języka C/C++. Język C/C++, oczywiście dysponuje także możliwością wywoływania kodu assemblerowego, więc można bezpośrednio wywoływać podane instrukcje. Jednak język C/C++ posiada także w pliku nagłówkowym dos.h bardzo elegancką moim zdaniem unię, która pozwala w prosty i przyjemny sposób odwoływać się do rejestrów procesora, oraz współdziałającą z tą unią funkcję wywołującą żądane przerwanie. Mowa tutaj o unii REGS oraz funkcji int86(). REGS jest unią więc pozwala nam przechowywać dane w strukturze dostosowanej do rozmiaru danych. Posiada ona struktury x oraz h. Różnią się one, oczywiście rozmiarem: x pozwala na przechowywanie wartości całych rejestrów (słowa), a h na przechowywanie polówek rejestrów (bajtów). Nazwy pól struktur są identyczne z nazwami rzeczywistych rejestrów i ich połówek. Funkcja int86() pobiera 3 argumenty: nr. Wywoływanego przerwania, oraz referencję do struktury wejściowej (przechowującej dane potrzebne do prawidłowej obsługi przerwania) oraz referencję do struktury wyjściowej (zawierającej wynik działania przerwania, czyli dane wygenerowane w wyniku działania przerwania). Wszystko powinno stać się jasne po przeglądnięciu przykładowego kodu:

#include "conio.h"
#include "stdio.h"
#include "dos.h"

int main() 
{
  unsigned int x, y;
  //deklaracja unii rejestrów
  REGS rej;
  rej.x.ax=0;
  //wywołanie przerwania: test na obecność myszy
  int86 (0x33, &rej, &rej);
  //jeśli błąd to kończymy program, nie obsługujemy błędu
  if (!rej.x.ax) return 0;
  rej.x.ax=1;
  //wyświetlamy kursor
  int86 (0x33, &rej, &rej);
  int c;
  //wyczyszczenie bufora klawiatury, tak na wszelki wypadek
  while (kbhit()) c=getch();
  clrscr();
  //pobieranie informacji o położeniu kursora i jeśli klawisz lewy wciśnięty to wyświetlenie *
  while (!kbhit()) {
    rej.x.ax=3;
    int86 (0x33, &rej, &rej);
    if (rej.x.bx & 1) {
      gotoxy (rej.x.cx/8, rej.x.dx/8);
      cprintf ("*");
    }
  }
  return 0;
}

Po uruchomieniu powyższego programu ekran zostanie wyczyszczony, pojawi się kursor myszy i w miejscu gdzie klikniemy myszką pojawi się gwiazdka. Dowolny klawisz kończy pracę programu. Prawda, że proste? Nawet bardzo. Jedyne o czym musimy pamiętać to aby dzielić wynik działania przerwania (punkty położenia kursora myszy) przez 8, oczywiście w trybie tekstowym. Kursora oczywiście nie musimy jawnie wyświetlać, gdy pracujemy w oknie graficznego systemu operacyjnego (obsługiwanego myszą oczywiście).

Uwaga! Ta metoda działa tylko w Turbo C, nie zadziała jeśli korzystamy np. z GCC i Dev-C++ na nowszych wersjach Windows, chyba że zainstalujemy jakieś biblioteki emulujące int86.

4 komentarzy

Kompilator: Default compiler

Wykonywanie  g++.exe...
g++.exe "C:\Users\Piotrek\Documents\dev c++\myszka.cpp" -o "C:\Users\Piotrek\Documents\dev c++\myszka.exe"   -g3  -I"C:\Dev-Cpp\lib\gcc\mingw32\3.4.2\include"  -I"C:\Dev-Cpp\include\c++\3.4.2\backward"  -I"C:\Dev-Cpp\include\c++\3.4.2\mingw32"  -I"C:\Dev-Cpp\include\c++\3.4.2"  -I"C:\Dev-Cpp\include"   -L"C:\Dev-Cpp\lib" -g3 
C:\Users\Piotrek\Documents\dev c++\myszka.cpp: In function `int main()':
C:\Users\Piotrek\Documents\dev c++\myszka.cpp:9: error: `REGS' undeclared (first use this function)
C:\Users\Piotrek\Documents\dev c++\myszka.cpp:9: error: (Each undeclared identifier is reported only once for each function it appears in.)
C:\Users\Piotrek\Documents\dev c++\myszka.cpp:9: error: expected `;' before "rej"
C:\Users\Piotrek\Documents\dev c++\myszka.cpp:10: error: `rej' undeclared (first use this function)
C:\Users\Piotrek\Documents\dev c++\myszka.cpp:12: error: `int86' undeclared (first use this function)

C:\Users\Piotrek\Documents\dev c++\myszka.cpp:21: error: `clrscr' undeclared (first use this function)
C:\Users\Piotrek\Documents\dev c++\myszka.cpp:27: error: `gotoxy' undeclared (first use this function)

C:\Users\Piotrek\Documents\dev c++\myszka.cpp:28: error: `cprintf' undeclared (first use this function)

Wykonanie zakończone

Skopiowałem dokładnie kod.

9 C:\Users\Piotrek\Documents\dev c++\myszka.cpp `REGS' undeclared (first use this function)

u mnie nie chodzi... pluje sie do :

[quote]int86 (0x33, ®s, ®s); [/quote]

popraw ten tekst bo nie wyswitle znakow