Erinäköisiä näppäinhandlereita olen nähnyt täällä putkassa vasta QB:n puolella, joten eiköhän laiteta tänne kaksi omaa kehittämääni/käyttämääni :)
Ylempi on käytössä saippurasian kilpailuun tekemässäni pelissä.
Normaali getch()-komento palauttaa erikoisnäppäimet (nuolet, home, end jne) kahden sarjoissa, ja silloin tällöin on todella ärsyttävää kun pelissä painaa nuolta/tms kohdassa, jossa on odottamassa vain yksi getch()-komento, jonka jälkeen seuraava getch palauttaa scankoodin. Funktio palauttaa joka näppäimelle yhden uniikin koodin (myös erikoisnapeille), erottaa toisistaan myös alt+ctrl-yhdistelmät. Käyttää inline asm:ia (hieman), joten ulkomuotoa pitänee hieman muokata muille kääntäjille (toimii borlandc:ssä).
Alempi taas vielä nimeltä mainitsemattomassa luolastoräiskinnässä. Perinteinen näppäin-pohjassa-systeemi. Siitä tuskin kykenee kertomaan mitään uutta.
En liitä vinkkiin mitään vakioita, ne on hauskaa löytää itse :) (Vaikkain kaikkien pitäisi tosin tuntea näppäistön scankoodit jo ulkoa)
//Über unicue näppäinhandleri
//Tähän pyydettiin kommentiia... sitä te myös saatte...
int LueNappi(){
int x;
asm{
push ax //varmistetaan ax = pinoon piiloon
xor ax,ax //tyhjätään mokoma
int 16H //keskeytys 16H = odotetaan painallusta
mov x, ax //Siirretään scankoodi+kirjain muuttujaan x
pop ax //palautetaan ax pinosta
}
return x;
}
/*
Keskeytys 16H
Kun kerran on kutsuttu, niin kone odottaa kunnes
näppäintä painetaan. Painalluksen jälkeen AX-rekisterissä
on näppäimen koodi: AH:ssa on ascii-koodi ja AL:ssä scankoodi.
Täten siis esim. nuoli ylös on asc=0, scan=72. Yhdistelmä voidaan ilmaista
myös seuraavasti: (asc<<8)+(scan&0XFF). Eli nuoli ylöspäin olisi
tunnistettavissa esim. näin:
if(LueNappi() == (0<<8)+(72&0XFF))printf("painoit ylös-nuolta!");
*///Über näppäin pohjassa
#include <stdio.h>
#include <stdlib.h>
volatile signed char napit[128]={0};
//Tähän funktiopointteriin tallennetaan vanha handleri
void interrupt (*vanha_i9)(...);
//Uusi, asennettava handleri
void interrupt uusi_i9(...){
unsigned char register ch=inportb(0x60);
if(ch<80){
napit[ch]=1;
}else{
napit[ch^0x80]=0;
}
outportb(0x20,0x20);
}
//asettaa handlerin käyttöön
void koukuta_i9(){
vanha_i9=getvect(0x9);
setvect(0x9,uusi_i9);
}
//Palauttaa vanhan
void vapauta_i9(){
setvect(0x9,vanha_i9);
}
//apufunktio
schar keydown(char key){return napit[key];}//Käyttö...
int main(){
int a;
a = LueNappi();
printf("Palautettu lukema: %i", a);
printf("\n\rPaina ESC");
koukuta_i9();
while(1){
if(keydown(1))break;
}
vapauta_i9();
return 0;
}Miksei tämä koodi toimi Windowsissa?
"Access violation reading location 0xffffffff."
Onneksi Windowsiin löytyy tällainen:
#define KeyDown(VK_CODE) ((GetAsyncKeyState(VK_CODE) & 0x8000) ? true : false)
Näppäimistön lukeminen suoraan keskeytyksen koukuttamalla ei ole mahdollista kuin DOS-ohjelmassa. Windowsissa tosiaan kannattaa käyttää esimerkiksi tuota mainitsemaasi GetAsyncKeyState-funktiota.
Aihe on jo aika vanha, joten et voi enää vastata siihen.