Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: C: DOS-Näppäinhandlerit

sqwiik [11.06.2004 23:24:15]

#

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;
}

Metabolix [12.06.2004 19:33:15]

#

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)

Antti Laaksonen [12.06.2004 21:22:23]

#

Näppäimistön lukeminen suoraan keskeytyksen koukuttamalla ei ole mahdollista kuin DOS-ohjelmassa. Windowsissa tosiaan kannattaa käyttää esimerkiksi tuota mainitsemaasi GetAsyncKeyState-funktiota.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta