It's been a while since I've been around. Thought about working to contribute something. I didn't see any KB input handlers, though I'm sure they are out there. I always ran into headaches getting the right inputs for mulitple key presses, timing, combos for fighting games etc... So I figured other people may have similar problems. I just got done on my rough draft and have more features and functions/routines to code. Not the greatest work, but something.
When it's finished I'll upload it to the codebase or code snippet forum (whichever is more appropriate). I could use some input from other coders on what things should be added.
remstart Keyboard Input Handler
Version 1.0 DBPro
by ~Zenassem 4/15/07
Description:
This code snippet is an attempt to provide the programmer with a means
to interpret keyboard input for games in DBPro. While the language
autmatically provides useful functions such as Inkey$(), Entry$(),
Scancode(), Keystate(), and other core kb handling commands; They don't
always meet the need of arcade games by themselves.
Version 1.0 will scan for the majority of keys and keep track of a key's
state + multiple keys at the same time (sort of lol), whether it IsPressed, IsReleased, IsHeld, the Keysname & Scancode,
as well as a keyboard buffer similar to the entryBuffer, that can be
Parsed to search for combos of keys, similar to that in fighting style
games.
I plan to enhance the core of the code, to improve speed, accuracy, and
efficiency in future versions. For instance, removing searching for unecessary
or No assigned scan codes. At current the code just searches from 0 to MAX_NUM_KEYS(255)
which isn't necessary. Additionally I'd like to break up some of the scancodes
into zones, so that if many keys aren't being used there would be no need to
search, and the programmer could have choice over what to enable.
The following code, uses a sample main loop, that covers most of the KBIH functions.
remend
sync on
sync rate 0
backdrop off
`%%% CONSTANTS
`KB_Key Abbreviations and Scancodes
#Constant KB_ESC 1 `Escape
#Constant KB_1 2 `1
#Constant KB_2 3 `2
#Constant KB_3 4 `3
#Constant KB_4 5 `4
#Constant KB_5 6 `5
#Constant KB_6 7 `6
#Constant KB_7 8 `7
#Constant KB_8 9 `8
#Constant KB_9 10 `10
#Constant KB_0 11 `0
#Constant KB_HYP 12 `-
#Constant KB_EQU 13 `=
#Constant KB_BKS 14 `Back Space
#Constant KB_TAB 15 `TAB
#Constant KB_Q 16 `Q
#Constant KB_W 17 `W
#Constant KB_E 18 `E
#Constant KB_R 19 `R
#Constant KB_T 20 `T
#Constant KB_Y 21 `Y
#Constant KB_U 22 `U
#Constant KB_I 23 `I
#Constant KB_O 24 `O
#Constant KB_P 25 `P
#Constant KB_LBR 26 `[
#Constant KB_RBR 27 `]
#Constant KB_RTN 28 `Return
#Constant KB_LCTRL 29 `Left Control
#Constant KB_A 30 `A
#Constant KB_S 31 `S
#Constant KB_D 32 `D
#Constant KB_F 33 `F
#Constant KB_G 34 `G
#Constant KB_H 35 `H
#Constant KB_J 36 `J
#Constant KB_K 37 `K
#Constant KB_L 38 `L
#Constant KB_SCOL 39 `;
#Constant KB_APOS 40 `'
#Constant KB_TIL 41 `~
#Constant KB_LSHFT 42 `Left Shift
#Constant KB_BSLSH 43 `\
#Constant KB_Z 44 `Z
#Constant KB_X 45 `X
#Constant KB_C 46 `C
#Constant KB_V 47 `V
#Constant KB_B 48 `B
#Constant KB_N 49 `N
#Constant KB_M 50 `M
#Constant KB_COM 51 `,
#Constant KB_PER 52 `.
#Constant KB_FSLSH 53 `/
#Constant KB_RSHFT 54 `Right Shift
#Constant KB_NP_MUL 55 `*
#Constant KB_LALT 56 `Left Alt
#Constant KB_SPC 57 `Space Bar
#Constant KB_CAPSL 58 `Caps Lock
#Constant KB_F1 59 `F1
#Constant KB_F2 60 `F2
#Constant KB_F3 61 `F3
#Constant KB_F4 62 `F4
#Constant KB_F5 63 `F5
#Constant KB_F6 64 `F6
#Constant KB_F7 65 `F7
#Constant KB_F8 66 `F8
#Constant KB_F9 67 `F9
#Constant KB_F10 68 `F10
#Constant KB_F11 69 `F11
#Constant KB_F12 70 `F12
#Constant KB_NP_7 71 `Num Pad 7
#Constant KB_NP_8 72 `Num Pad 8
#Constant KB_NP_9 73 `Num Pad 9
#Constant KB_NP_SUB 74 `Num Pad -
#Constant KB_NP_4 75 `Num Pad 4
#Constant KB_NP_5 76 `Num Pad 5
#Constant KB_NP_6 77 `Num Pad 6
#Constant KB_NP_ADD 78 `Num Pad +
#Constant KB_NP_1 79 `Num Pad 1
#Constant KB_NP_2 80 `Num Pad 2
#Constant KB_NP_3 81 `Num Pad 3
#Constant KB_NP_0 82 `Num Pad 0
#Constant KB_NP_DEC 83 `Num Pad .
#Constant KB_NP_ENT 156 `Num Pad Enter
#Constant KB_RCTRL 157 `Right CTL
#Constant KB_RALT 184 `Right Alt
#Constant KB_HOM 199 `Home
#Constant KB_UP 200 `Up Arrow
#Constant KB_PGUP 201 `PgUp
#Constant KB_LEFT 203 `Left Arrow
#Constant KB_RIGHT 205 `Right Arrow
#Constant KB_END 207 `END
#Constant KB_DOWN 208 `Down Arrow
#Constant KB_PGDN 209 `PgDn
#Constant KB_INS 210 `Insert
#Constant KB_DEL 211 `Delete
#Constant KB_LWIN 219 `Left Windows
#Constant KB_RWIN 220 `Right Windows
#Constant KB_SPEC 221 `Special
` Special keys - may be diff't on other KB's
#Constant KB_BRK 197 `Pause/Break
#Constant KB_MEN 221 `Menu
#Constant MAX_NUM_KEYS 255
#Constant MAX_SC_BUFFER_SIZE 60
#Constant MAX_COMBO_TIME 1000 `= to 1 second
#Constant MAX_NUM_COMBOS 3
`%%% User Defined Types (UDT) Definitions
type KeyType
ScnCode AS INTEGER
KeyName AS STRING
IsPressed AS INTEGER
IsReleased AS INTEGER
IsHeld As INTEGER
endtype
`Initialize UDT
DIM kb_KeyInfo(MAX_NUM_KEYS) AS KeyType
`Intialize kb_KeyInfo Array
for index=0 to MAX_NUM_KEYS
kb_KeyInfo(index).ScnCode=0
kb_KeyInfo(index).KeyName="NULL"
kb_KeyInfo(index).IsPressed=0
kb_KeyInfo(index).IsReleased=3
kb_KeyInfo(index).IsHeld=0
next index
`Read data fromm keyinfo.txt into kb_KeyInfo fields
open to read 1, "keyinfo.txt"
while file end(1)=0
read string 1, scncode$
`convert string to integer
`** find out why can't read byte, word, long
scncode=val(scncode$)
read string 1, keyname$
kb_KeyInfo(scncode).ScnCode=scncode
kb_KeyInfo(scncode).KeyName=keyname$
endwhile
close file 1
`Globals
kb_ScBuffer$=""
dim ComboList$(MAX_NUM_COMBOS)
ComboList$(0)="205205205" `right, right, right
ComboList$(1)="200200200" `up, up, up
ComboList$(2)="203203203" `Left, Left, Left
GameDone=0
kb_Init_Timer=Timer()
`***** MAIN TEST KEYBOARD INPUT HANDLER APPLICATION *****
`Main Loop
while GameDone=0
kb_Time_Passed = Timer()- Kb_Init_Timer
gosub RecAllKeyStates `Record Important Key State Changes
gosub DispAllKeyStates`Print Key State Changes to screnn
if kb_No_Entry=1 and kb_Time_Passed>= MAX_COMBO_TIME or Len(ScBuffer$)>=MAX_SC_BUFFER_SIZE
`Parse multiple Key History buffer
gosub ParseSCBuffer
endif
sync
`Make sure to reset the kb_timers if necessary
if kb_Time_Passed >= MAX_COMBO_TIME
kb_Time_Passed = 0
kb_Init_Timer=Timer()
endif
endwhile
`***** END OF MAIN TEST APLLICATION *****
`%%% Subroutines & Functions
RecAllKeyStates:
`if no keys are pressed than there kb_No_Entry is true/1
if scancode()=0
kb_No_Entry=1
else
kb_No_Entry=0
endif
`search through all the scancodes
`!!!reminder - this needs to be optimized. No use looking for codes
` that don't exist. Based on programmer choice an new array or multiple
`arrays will be created for zones to shorten how many scancodes are actually
`searched.
for index=0 to MAX_NUM_KEYS
sc=keystate(index)
`if the key was released (which was already rec) set it to some
`arbitrary number other than 0 or 1
if kb_KeyInfo(index).IsReleased=1
kb_KeyInfo(index).IsReleased=3
endif
`if the key was in a pressed state but now is not - set isReleased to
`1 and is pressed to 0
if sc=0 and kb_KeyInfo(index).IsPressed=1
kb_KeyInfo(index).IsPressed=0
kb_keyInfo(index).IsHeld=0
kb_KeyInfo(index).IsReleased=1
endif
`if the key is being pressed and was being pressed last check - now set it to held
if sc=1 and kb_KeyInfo(index).IsPressed=1
kb_KeyInfo(index).IsHeld=1
endif
`if the key is pressed but not being held - set pressed to 1 and add the scancode to the buffer
if sc=1 and kb_KeyInfo(index).IsHeld=0
kb_KeyInfo(index).IsPressed=1
kb_KeyInfo(index).IsReleased=0
kb_ScBuffer$=kb_ScBuffer$+"/"+str$(kb_KeyInfo(index).ScnCode)
`I am adding "/'s" to the the buffer only to parse them out later
`Reason, I didn't want to leave the chance that scancodes could
`converge to form a different code for combos. I'll have to implement
`that in the parser later. For example scancode 20 and scancode 5
`should not be confused with scancode 205
endif
next index
return
DispAllKeyStates:
for index=0 to MAX_NUM_KEYS
if kb_KeyInfo(index).IsPressed=1
print kb_KeyInfo(Index).KeyName; "Is Pressed"
sync
endif
if kb_KeyInfo(index).IsReleased=1
print kb_KeyInfo(index).KeyName; " Is released"
sync
endif
if kb_KeyInfo(index).IsHeld=1
print kb_KeyInfo(index).KeyName; " Is Held"
sync
endif
next index
return
ParseSCBuffer:
`If the Buffer is empty do nothing
`!!!reminder to implement accidental scancode convergence (noted above)
` And to also look for for shorter combos in a longer string
if kb_ScBuffer$<>""
Print "Parsing Buffer"
print "kb_ScBuffer$ = ";kb_ScBuffer$
sync
charcounter=0
kb_ScBuffer_Len=len(kb_ScBuffer$)
for index=0 to kb_ScBuffer_Len
if mid$(kb_ScBuffer$,index)="/" or index=kb_ScBuffer_Len
`if we reached the last scancode - don't take off the last character
if index=kb_SCBuffer_Len
inc index
endif
for index2=charcounter to index-1
kb_Combo$=kb_Combo$+mid$(kb_ScBuffer$, index2)
next index2
charcounter=index+1
endif
next index
print "kb_Combo$ = "; kb_Combo$
sync
wait key
for index=0 to MAX_NUM_COMBOS
if kb_Combo$=ComboList$(index)
print "Combo Detected - Against ComboList(";index;")"
sync
endif
next index
`Reset Kb_Combo$
kb_Combo$=""
`Reset kb_ScBuffer$
kb_ScBuffer$=""
endif
return
attached is a textfile that I plan to use later on, right now it just fills the array, and gives a longer desc of keys