Re: keyboard help
- Posted by Jacques Deschenes <desja at QUEBECTEL.COM> Dec 08, 1996
- 608 views
--=====================_850082487==_ At 00:52 8-12-96 -0800, you wrote: >---------------------- Information from the mail header ----------------------- >Sender: Euphoria Programming for MS-DOS <EUPHORIA at >MIAMIU.ACS.MUOHIO.EDU> >Poster: Michael Packard <lgp at EXO.COM> >Subject: keyboard help >------------------------------------------------------------------------------- > >hi. Anybody know how to (easliy) ready the keyboard directly? I need to >know what keys are currenly being help down, not just the last one >pressed. If I'm holding down the "turn" key and then press and hold the >"fire" I want to continue turning while firing too, until I release the >"turn" key. > >How do I do it? > >Michael Packard >Lord Generic Productions >lgp at exo.com http://exo.com/~lgp >A Crash Course in Game Design and Production >http://exo.com/~lgp/euphoria > Hi Michael, Unless you're ready for system programming in assembler, just forget it. The actual keyboard interrupt service routine only track one key at a time. The keyboard send 2 codes for each key. One when the key is pushed down and one when the key is released. If you push a second key while a first one is down the ISR doesn`t remember the first one is still down. >>>> BUT there is a way around it if you are ready to change your game keys. There is 9 keys on the keyboards that are track down. You can push many of them without interfering with each other. I include gamepad.e and tstgampd.ex to show you how to transform the special keys of the keyboard in game pad. With gamepad.e you can still use alpha key but only once at a time and it's simpler to use the scan codes by calling GetScanCode() instead of get_key(). For more informaiton see note at beginning of gamepad.e file. --=====================_850082487==_ -- NAME: GAMEPAD.E -- OBJECT: use keyboard special keys as a game pad. -- CREATION DATE: Dec. 8th, 1996 -- BY: Jacques Deschenes, Baie-Comeau, Canada, e-mail:Desja at quebectel.com -- RATIONALE: the problem with using the keyboard as a game pad is that one -- can't press 2 keys at the same time, because the keyboard service routine -- only track one key. If the player hold down a key and then push a second -- key the Interrupt service routine doesn't see the first key any more. The -- player have to release it and push it again for the ISR to detect it. -- Possible solutions: -- 1) rewrite keyboard ISR. Best solution if you are system programmer. -- 2) on the keyboard there is special keys that the service routine process -- differently. Those keys are flagged has long as they are holded down. -- The player can hold down 2 or 3 of those keys without loosing tracking. -- The 9 flagged keys are: -- RIGHT SHIFT -- LEFT SHIFT -- RIGHT CONTROL -- LEFT CONTROL -- RIGHT ALT -- LEFT ALT -- CAPS LOCK -- NUM LOCK -- SCROLL LOCK -- For their position on the keyboard the first 6 are the best to use for game. -- -- This include file implement solution 2. -- Another problem arise from that solution: The key code returned by normal -- key is modified by the control and alt keys. So if the game use normal key -- like spacebar the get_key() will return different value depending if the -- player is holding down control, alt or control-alt at the same time he press -- spacebar. -- A partial solution to that problem is to read the scan code instead of the -- key code as scan codes of alpha keys are not modified by the specials keys. -- (but arrows and functions keys scan codes are modified) -- -- This include file export only 3 functions: -- GetKeyPad() which return a sequence containing the state of all specials -- keys. -- KeyPressed() return 1 if a key is pressed. -- GetScanCode() which return the scan code or normal key if one is pressed. include machine.e -- index constants to access keypad sequence returned by GetKeyPad() constant siR_SHIFT = 1, siL_SHIFT = 2, siL_CTRL = 3, siL_ALT = 4, siR_CTRL = 5, siR_ALT = 6, siSCR_LOCK = 7, siNUM_LOCK = 8, siCAP_LOCK = 9 global function GetKeyPad() -- return keyboard flags -- output register AH containt AT flags and AL containt XT flags sequence r, at, xt r = repeat(0,10) r[REG_AX] = #1200 r = dos_interrupt(#16,r) at = int_to_bits(floor(r[REG_AX]/256),8) xt = int_to_bits(remainder(r[REG_AX],256),8) return xt[1..2]&at[1..7] end function -- GetKeyPad() global function KeyPressed() -- check if a key is present in keyboard buffer sequence r r = repeat(0,10) r[REG_AX] = #1100 r = dos_interrupt(#16,r) return remainder(r[REG_FLAGS],8) < 4 -- key present if zero flag = 0 end function --KeyPressed() global function GetScanCode() sequence r if KeyPressed() then r = repeat(0,10) r[REG_AX] = #1000 r = dos_interrupt(#16,r) return floor(r[REG_AX]/256) end if return 0 end function -- GetScanCode() --=====================_850082487==_ include gamepad.e integer code,PrevCode sequence flags code = 0 PrevCode = 0 constant PadStr={"RIGHT SHIFT","LEFT SHIFT","LEFT CONTROL","LEFT ALT", "RIGHT CONTROL", "RIGHT ALT", "SCROLL LOCK", "NUM LOCK", "CAPS LOCK"} procedure ShowPad(sequence pad) position(2,1) for i = 1 to length(pad) do if pad[i] = 1 then puts(1,PadStr[i]&'\n') else puts(1," \n") end if end for end procedure clear_screen() while code != 1 do code = GetScanCode() if code and code != PrevCode then position(1,1) printf(1,"Scan code = %3d\n",{code}) PrevCode = code end if flags = GetKeyPad() ShowPad(flags) end while --=====================_850082487==_ Jacques Deschenes Baie-Comeau, Quebec Canada desja at quebectel.com --=====================_850082487==_--