Programming
C++
Turbo Pascal
Delphi
Ver. 1.0 Beta, Don't have a compiler? Now you can write simple scripts ONLINE! This is a basic version -does not include all the Pascal statements. Only to learn basics
Obsługa klawiatury w Pascalu, Zaawansowane badanie za pomocą przerwań do tworzenia gier
Klawiatura standardowo
Aby obsługiwać odczyt wciśniętych klawiszy standardową metodą można skorzystać z ReadKey z modułu Crt lub skorzystać z funkcji PORT[$60] dostępnej w każdym programie bez dodatkowych modułów.
ReadKey wczytuje stan ostatnio wciśniętego klawisza. W połączeniu z keypressed można obsłużyć obsługę klawiatury bez zatrzymywania programu. repeat if keypressed then ch:=ReadKey; until ch=#27; W przypadku PORT[$60], podobnie, jednak warto byłoby wyczyścić bufor klawiatury aby zapobiec jego przepełnieniu. repeat until PORT[$60]<>1; Obydwa przypadki wczytują stan wciśniętego, pojedynczego klawisza z klawiatury. Pierwsza metoda jest częściej spotykana, druga czyta bezpośrednio z portu. Kody klawiszy w pierwszej funkcji to kody ASCII. W przypadku drugiej -kody są kolejnymi liczbami, poczynając od Escape, przez F1, F2, F3 itd... Czyszczenie bufora klawiatury można wykonać korzystając z poniższej funkcji PROCEDURE Keyb_Clear;Assembler; ASM mov ax, 0c00h int 21h END; Obsługa klawiatury w Turbo pascalu
Problem z klawiaturą zaczyna się gdy chcemy zbudować coś naprawdę zaawansowanego. Ciężko jest nam przechwytywać informacje o wciśniętych altach, controlach i shiftach. Największy problem pojawia się gdy wciskamy wiele klawiszy na raz. Wtedy zaczyna się jeden duży pisk -oznaczający przepełnienie bufora. Jak tego uniknąć Potrzebne zaawansowane obsługiwanie przerwańCo wcale nie znaczy że trudne. Kiedy wciskamy klawisz komputer wywołuje pewne przerwanie. Kiedy opuszczamy dzieje się to samo. W takim razie wystarczy podczas każdego przerwania wpisać do tablicy czy dany klawisz jest wciśnięty czy nie. Należy także pamiętać o wyczyszczeniu bufora, żebyśmy nie musieli słuchać pisków przepełnienia bufora. Ponieważ nie dysponuję zbyt duża ilością czasu wkleję moduł, którym sam się posługiwałem do obsługi klawiatury. Na jego przykładzie możesz napisać coś swojego, albo wykoprzystać go w swoich projektach. Użycie modułu: przed pętlą główną zainicjuj klawiaturę za pomocą keyb_Init; Teraz stan klawiatury badasz z tablicy key[x] Są podstawione pewne stałe, np. Vk_Up, Vk_Down - to są strzałki, resztę zobacz w kodzie użycie np. if key[Vk_Up] then y:=y-1; w pętli czyść za każdym razem bufor przez keyb_Clear; Na końcu przywróć stare przerwanie przez keyb_End; UWAGA! to nie jest kolejność Ascii! Kolejność musisz samemu zbadać np. w tablicy z kodu źródłowego {$g+} unit keyb_x; interface TYPE TKeyboard_Event = PROCEDURE; VAR key : array[1..127] of boolean; { to store the key-presses } AnyPressed : Boolean; KeyDelay : Word; KEYBOARD_EVENT : TKeyboard_Event; Const KeyName : array[1..83] of string[10] = ( 'Esc','1','2','3','4','5','6', '7','8','9','0','_','=','BckSpace', 'Tab','Q','W','E','R','T','Y', 'U','I','O','P','[',']','Return', 'Ctrl','A','S','D','F','G','H', 'J','K','L',';','"','`','Lewy Shift', '','Z','X','C','V','B','N','M', ',','.','/','Prw. Shift','*', 'AlT','Spacja','Caps Lock','F1', 'F2','F3','F4','F5','F6','F7','F8', 'F9','F10','Num Lock','Scroll Lock', 'Home','G˘ra','Pg Up','-','Lewo', '5','Prawo','+','End','D˘�','Pg Down', 'Ins','Del'); Const KeyNorm : array[1..55] of CHAR = ( { 1 2 3 4 5 6 7 8 9 10} ' ', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', ' ', ' ', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', ' ', ' ', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '"', '`', ' ', '', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', ' ', '*'); KeyAlt : array[1..55] of CHAR = ( { 1 2 3 4 5 6 7 8 9 10} ' ', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', ' ', ' ', 'q', 'w', ' ©', 'r', 't', 'y', 'u', 'i', '˘', 'p', '[', ']', ' ', ' ', 'Ą', '�', 'd', 'f', 'g', 'h', 'j', 'k', '�', ';', '"', '`', ' ', '', 'ľ', ' «', ' †', 'v', 'b', 'ä', 'm', ',', '.', '/', ' ', '*'); KeyShift : array[1..55] of CHAR = ( { 1 2 3 4 5 6 7 8 9 10} '~', '!', '@', '#', '$', '%', '^', ' &', '*', '(', ')', '_', '+', ' ', ' ', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', ' ', ' ', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '`', ' ', '', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', ' ', '*'); VK_ESC = 1; { these are just some constants... } VK_Down = 80; { the most important keys in games } VK_Up = 72; { are the arrow keys, and the } VK_Left = 75; { control+alt keys... } VK_Right = 77; VK_CTRL = 29; VK_ALT = 56; VK_RETURN = 28; VK_SPACE = 57; VK_SHIFT = 42; PROCEDURE Keyb_Init; PROCEDURE Keyb_End; PROCEDURE Keyb_Clear; Function Keyb_KeyRetrace:Boolean; implementation uses dos; VAR OldInt09 : pointer; { old keyboard interupt } Const KeyWait:Integer=0; PROCEDURE Keyb_End ; BEGIN SetIntVec( $09, OldInt09 ) ; END; {$f+} PROCEDURE Keyb_NewInt09; INTERRUPT; Begin IF Assigned(KEYBOARD_EVENT) THEN Keyboard_Event; ASM STI xor ch,ch { set CH to 0, we're using bytes here! } mov dx,$60 { set DX to port $60 (keyboard port) } in al,dx { get byte from keyboard } mov cl,al { put it in CL for usage } and cl,$7f { and CL with 127 (MOD 128) } mov bx,offset key { get offset of the KEY array of booleans } dec bx add bx,cx { add keyfound to BX } mov si,bx { put calculated offset in DS:[SI] } shr al,7 { divide AL with 128 } xor al,1 mov [si],al { put TRUE or FALSE in array position of keyfound } mov anypressed,al { set ANYPRESSED to TRUE or FALSE } mov dx,$61 in al,dx { get byte from the port } mov cl,al or al,$80 out dx,al mov al,cl out dx,al cli mov ax,$20 mov dx,$20 out dx,ax END; End; {$f-} PROCEDURE Keyb_Init; VAR n : byte; BEGIN AnyPressed:=False; ExitProc := addr( Keyb_End) ; GetIntVec( $09, OldInt09 ) ; SetIntVec( $09, addr( Keyb_NewInt09 ) ) ; For N := 1 to 127 do Key[ N ] := False ; END; PROCEDURE Keyb_Clear;Assembler; ASM mov ax, 0c00h int 21h END; Function Keyb_KeyRetrace:Boolean; begin Keyb_KeyRetrace:=False; if keywait>0 then begin dec(keydelay);exit; End; keywait:=KeyDelay; Keyb_KeyRetrace:=True; end; begin KeyDelay:=1;FillChar(key,sizeof(key),0); KEYBOARD_EVENT:=NIL; end. |
ON-LINE scripts!