Newsgroup: it.comp.lang.c
Titolo: Rallentamento della gestione della keyboard

Ho installoto un mio keyboard handler, che va a sostituire quello di 
default.
L'handler di per se funziona bene, ma ho un problema, se tengo premuto un 
tasto per piu di 2/3 secondi mi si rallenta la gestione della tastiera. (vi 
faccio un esempio: se tengo premuto, SENZA MAI STACCARE IL DITO, la 
freccetta destra, l'omino si muove senza problemi verso destra, dopo i primi 
2/3 secondi però l'omino inizia a muoversi a sctti verso destra. SE STACCO 
PER 1 ISTANTE IL DITO, omino inizia a muoversi correttamente, e così via...)
Io credo che il problema sia dovuto al fatto che il buffer della tastiera si 
riempie.
Girando per il newsgroup ho notato che esistono principalemente 2 metodi per 
svuotare il buffer:
1) Utilizzo di fflush, ma da quanto ho capito tale funzione funziona 
correttamente solo per buffer di output. (non è quindi il mio caso)
2) while (getchar()!='\n');
Nonstante dopo l'installazione del mio handler di tastiera non possa usare 
funzioni tipo getch, getchar, scanf, ecc... questa soluzione la potrei anche 
utilizzare, installando e disinstallando l'handler prima di fare il while. 
C'è però un problema, che non è detto (anzi sicuramente) che alla fine del 
buffer ci sia uno \n, poiche i tasti che prevalentemente utilizzo sono le 
freccette.
Ne ho notato poi anche un terzo, ma è abbastanza artigianale..., fa uso 
della scanf.
Vi chiedo quindi se conoscete altri metodi per svuotare il buffer di 
tastiera, preferibilmente (ma non è un problema) senza uso di getch, 
getchar, scanf ...(e tutte quelle funzioni che leggono dallo stdin).
Grazie
CIAO 

 svuotare il buffer:
...
Secondo me devi passare a funzioni piu' adatte. Su win32, per puro
esempio potresti utilizzare GetAsyncKeyState, o altro. Se volessi un
programma portabile potresti usare SDL.
Putroppo tutte queste funzioni sono OT su questo NG.
Tommaso
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 Putroppo tutte queste funzioni sono OT su questo NG.
Il fatto è che io sto progammando sotto DOS, come compilatore sto 
utilizzando DJGPP. 

 wrote 

Il mio messaggio non voleva essere specifico di win32. Per questo ho
detto "per puro esempio". Anche sotto "DOS" con DJGPP esistono modi
speficici per accedere alla tastiera.


  
ha scritto:


 timer...
Allora ti riscivo il mio problema, ed in più inserisco anche del codice, 
così forse si capisce
meglio.
Ho installoto un mio keyboard handler, che va a sostituire quello di
default.
L'handler di per se funziona bene, ma ho un problema, se tengo premuto un
tasto per piu di 1/2 secondi mi si rallenta la gestione della tastiera. (vi
faccio un esempio: se tengo premuto, SENZA MAI STACCARE IL DITO, la
freccetta destra, l'omino si muove senza problemi verso destra, dopo i primi
2/3 secondi però l'omino inizia a muoversi a sctti verso destra. SE STACCO
PER 1 ISTANTE IL DITO, omino inizia a muoversi correttamente, e così via...)
Io credo che il problema sia dovuto al fatto che il buffer della tastiera si
riempie.
Girando per il newsgroup ho notato che esistono principalemente 2 metodi per
svuotare il buffer:
1) Utilizzo di fflush, ma da quanto ho capito tale funzione funziona
correttamente solo per buffer di output. (non è quindi il mio caso)
2) while (getchar()!='\n');
Nonstante dopo l'installazione del mio handler di tastiera non possa usare
funzioni tipo getch, getchar, scanf, ecc... questa soluzione la potrei anche
utilizzare, installando e disinstallando l'handler prima di fare il while.
C'è però un problema, che non è detto (anzi sicuramente) che alla fine del
buffer ci sia uno \n, poiche i tasti che prevalentemente utilizzo sono le
freccette.
Ne ho notato poi anche un terzo, ma è abbastanza artigianale..., fa uso
della scanf.
Vi chiedo quindi se conoscete altri metodi per svuotare il buffer di
tastiera, preferibilmente (ma non è un problema) senza uso di getch,
getchar, scanf ...(e tutte quelle funzioni che leggono dallo stdin).
______________________________________________
//Questo è il codice per l'handler di tastiera
volatile int keyboard[128];
static void keyboarHandler();
void installKeyboardHandler();
void deinstallKeyboardHandler();
/*
        Funzione che crea il nuovo handler della keyboard.
*/
static void KeyboardHandler() {
        //legge dalla porta
        scancode = inp(KEYPORT);
        //setta a vero il flag per aggiornare il vettore dei tasti
        update = 1;
        switch (scancode) {
                case EXTENDED:
                case EXTENDED+1:
                        update = 0;             //non updato perch¦ il tasto 
¦ esteso
                        lastscan = scancode;    //lastscan mi serve per 
sapere il tipo di tasto
esteso.
                break;
                default:
                        if ((lastscan==EXTENDED)||(lastscan==EXTENDED+1))
                                update =  0;
                        if (update) {
                                //updato key_status
                                key_status[lastscan&127]=(lastscan&PRESSED)?0:1;
                                lastscan=0;
                        }
                break;
        }
        //Dico alla tastiera che il tasto ¦ stato letto
        __asm__("inb    $0x61,%al");
        __asm__("orb    $0x80,%al");
        __asm__("outb   %al,$0x61");
        __asm__("andb   $0x7F,%al");
        __asm__("outb   %al,$0x61");
        //dico al pic che la daisy chain pu. continuare perchè ho finito.
        outp(0x20,0x20);
}
/*
        Funzione che installa il nuovo handler della keyboard
*/
void installKeyboardHandler() {
        kb.pm_offset = (unsigned int)KeyboardHandler;
        kb.pm_selector = _my_cs();
        _go32_dpmi_allocate_iret_wrapper(&kb);
        _go32_dpmi_get_protected_mode_interrupt_vector(KEYBOARD, 
&oldkbhandler);
        _go32_dpmi_set_protected_mode_interrupt_vector(KEYBOARD, &kb);
}
/*
        Funzione che reinstalla l'handler di default della keyboard.
*/
void deinstallKeyboardHandler() {
        _go32_dpmi_set_protected_mode_interrupt_vector(KEYBOARD, 
&oldkbhandler);
}
/*Questo è un esempio di come utilizzo il nuovo handler nel main. Lo 
installo, quindi faccio un
  while che viene esguito fino a quando uscita non diventa == 0, quindi 
installo l'handler di
  tastiera precedente.
*/
 .
 .
 .
installKeyboardHandler();
uscita=1;
while (uscita) {
 tasto=inportb(0x60);
        switch (tasto) {
                       case 0x4d:
                                x+=2;
                                verso=1;
                                break;
                       case 0x4b:
                                x-=2;
                                verso=0;
                                break;
                        case 0x50:
                                y+=2;
                                break;
                        case 0x48:
                                y-=2;
                                break;
                        case 0x01:
                                uscita=0;
                                break;
                        default: ;
 }
 .
 .  //stampo l'omino a schermo utilizzando le variabili x,y come coordinate
 .  //(x,y) ove stampare l'omino.
 .
}
deinstallKeyboardHandler();
 .
 .
 .

 /*Questo č un esempio di come utilizzo il nuovo handler nel main. Lo

Ho avuto lo stesso problema qualche tempo fa. Devi disattivare l' int 09h.
Ti riporto un pezzo del file interrup.a:
"INT 09 C - IRQ1 - KEYBOARD DATA READY
Desc: this interrupt is generated when data is received from the keyboard.
	  This is normally a scan code (from either a keypress *or* a key
	  release), but may also be an ACK or NAK of a command on AT-class
	  keyboards.
Notes: this IRQ may be masked by setting bit 1 on I/O port 21h"
Io ho risolto il probelma scrivendo qualcosa del tipo outp(0x21, 2).
Se vuoi lasciare inalterato lo stato degli altri bit puoi fare un OR
bit-a-bit tra il contenuto della porta 0x21 e il valore 2. Per ripristinare
fai l'AND bit-a-bit tra il contenuto modificato e il vecchio contenuto (che
hai magari precedentemente salvato in un altra variabile). Naturalmente č
importante ripristinare il tutto se, al termine del tuo programma, vuoi
continuare ad usare la tastiera... :-)
Ti lascio anche l'URL della lista degli interrupt di Ralph Brown.
http://www.cs.cmu.edu/~ralf/files.html
In particolare nel file interrup.d trovi la descrizione dei servizi dell'
int 16h che č l'interruzione dedicata ai servizi per la gestione della
tastiera.
Fammi sapere se risolvi.
Ciao
{scheme}
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 int 16h che è l'interruzione dedicata ai servizi per la gestione della


 Ho avuto lo stesso problema qualche tempo fa. Devi disattivare l' int 09h.
Ma io l'interrupt 09h (che č quello della tastiera) lo riprogrammo!
Tu quando hai risolto cosě avevi anche riprogrammato l'handler della 
keyboard o avevi usato quello di default?
Nel caso lo avevi riprogrammato mi spiegheresti un pň piů dettagliatamente 
la procedura da seguire? (ad esempio dove metto oupt(0x21,2), nel mio 
handler o nel main???)
Ciao


Evidentemente non lo hai riprogrammato nel modo corretto se il buffer si
riempie comunque. Ti posto l'URL di un forum dove recentemente c'è stata una
discussione del genere. In quella discussione non si parlava però di inibire
l' int 09h.
Tu devi, in pratica:
+ scaricare il file keyb.h indicato nel forum
+ aggiungere all'inizio del tuo programma l'outp(0x21, 2)
+ gestire la tastiera in un ciclo
    do
     {
      myInt(0);
     }
     while(...);
Se guardi il codice di keyb.h ti sarà tutto più chiaro. L'unica cosa, che mi
ha fatto dannare, era che la funzione myInt è definita come interrupt e
DOVREBBE essere eseguita quando è lanciata l' int 09h. Io uso questo codice
nel Borland Turbo C++ 3.0 e in realtà non viene per niente eseguita quando
premo un tasto. Per cui uso l'artificio del ciclo do-while descritto sopra
per richiamare la procedura continuamente, una volta interdetto l'int 09h,
sia chiaro.
Vedi tu come adattare il tutto nel tuo caso.
Ciao.



OK ti ringrazio però hai dimenticato di postarmi l'URL :) 

 Sul link che ti ho dato trovi un esempio (solo per il timer).
Ho appena provato ad installare l'handler in RM però il risultato non 
cambia!
Oro tengo installati entrambi i gestori.
Comincio a pensare che siano gli handler che siano programmati male. 
Purtroppo io li ho presi dalla rete, sul sito 
www.gameprog.it
, e se dovessi 
farne uno io non saprei dove mettere le mani.
Sullo stesso sito ho trovato un'altro handler di tastiera, questa volta 
programmato in assembler, solo che contiene degli errori e dovrei farmelo 
correggere, perchè io di assembly ci capisco poco e niente!
Tu come sei messo? :)    (magari te lo posto :)))))))
CIAO! 


Hai ragione... :-) Ma penso che sia lo stesso file che hai scaricato tu.
http://www.gameprog.it/index.php?action=forum&forumaction=view&rid=10814&msgid=1
Ciao.


 
http://www.gameprog.it/index.php?action=forum&forumaction=view&rid=10814&msgid=1
Azz in quel post non ci ero mai cascato!
Io gli handler li ho presi nella sezione programmazione->interfaccie 
Hardware (ci sono anche spiegati i gestori per mouse e joystick)
Dimmi un pň scheme ma tu sei interessato alla programmazione di videogame? 
Nel caso si potrebbe fare qualche cosa insieme! Cmq ti avverto che io ho 
iniziato da poco sono ancora al 2D LOL.
Fammi sapere!!!
Se vuoi anche via e-mail (
carmine.m...@libero.it
 togli il NOSPAM)
CIAO