Path: utzoo!utgpu!news-server.csri.toronto.edu!bonnie.concordia.ca!uunet!mcsun!cernvax!chx400!ugun2b!ugsc2a!fisher From: fisher@sc2a.unige.ch Newsgroups: comp.sys.ibm.pc.misc Subject: Re: letting keypress always gen interrupt Message-ID: <1991May3.144917.415@sc2a.unige.ch> Date: 3 May 91 12:49:17 GMT References: <9819@star.cs.vu.nl> Organization: University of Geneva, Switzerland Lines: 97 In article <9819@star.cs.vu.nl>, mgvalen@cs.vu.nl (Valent MG) writes: > > Hello everybody out there, > > Here I have a problem handling the keyboard the way I want > it. [...] > Hold down a key. You will see it's scancode being printed > continuously. Now, while holding the key, press another and kee > it pressed also. This latter keypress will take over and > it's scancode will be printed. Till so far, ok. Now release > the key you have pressed down last. It's (release) scancode > will be printed as expected, but after this, NO MORE printing > (even though you're still holding down the key you pressed > first !). [...] Well, this is not a software problem. You see, it's the keyboard that generates the repeat, if you hold it down long enough. The programs that let you set the repeat factor (or that have an increasing speed of repeat) usualy drop the hardware repeat, and simulate their own. One example of this can be found in WordPerfect (version 3.12 and 4.2, at least) : when you hold down the UpArrow to scroll the screen, the scrolling stops imediately after you release it, even if there should still be a dozen "Ups" in the buffer. This means either that the repeat is done internally, or that the buffer is purged of any remaining "Ups" whenever the "key release" code is recieved. > PS1: I know there must be an efficient way, because check out (almost) > any action game. In such a game, it is > possible for the player to move to left/right, in between firing by > pressing the firekey (while keeping the 'move to the left/right' > pressed). This gives the effect as if moving to the left/right and > firing happen simultaneous.) What you would like is a keybord that sends simultaneously repeat codes for every key that is pressed... wou'd have to buil your own. This is what I would do (it can be quite fast, too): Have your keyboard driver read the scan-code, and update an array of chars: #define key_release(code) ((code) & 0x80) #define clean(code) ((code) & 0x7F) if (key_release(code)) { state[clean(code)] = NO; } else { if (key_state[clean(code)]==NO) { key_state[clean(code)] = YES; waiting_keys[clean(code)]++; } /* else drop keyboard's repeat... */ } The information in "key_state" and in "waiting_keys" must be public. They should probably be combined into a single char... Your main game loop will have to do the following: char *fire = waiting_keys[SCAN_CODE_FOR_SPACEBAR]; char *fire_state = key_state[SCAN_CODE_FOR_SPACEBAR]; char *left = waiting_keys[SCAN_CODE_FOR_LEFT]; char *left_state = key_state[SCAN_CODE_FOR_LEFT]; char *sing_a_song = ... do { if (*fire) { *fire--; shoot_the_gun(); } else if (*fire_state==YES) { shoot_the_gun(); } if (*left) { *left--; move_to_the_(LEFT); } else if (*left_state==YES) { move_to_the_(LEFT); } if (*sing_a_song) { ... (Hmm, I got carried away...) Anyways, you have now a system in which at every game loop, you will react according to the current key status, and what's more, the user will be guaranteed to fire at least three times if he stuck the spacebar three times... And don't tell me this is slower than the standard keyboard interrupt driver in MS-DOS... Hope this helps, Markus G. Fischer, Dept of Anthropology, Geneva CH