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.