START:
At start of program call
StartKeyTapCheck()
ENGINE FUNCTIONS:
For each key you're interested in monitoring call
KeyTapCheck() with the scancode, or
KeyTapValueUpdate() which will do the lot. The advantage of KeyTapCheck is it returns if a key has been pressed (not held).
UTILITY FUNCTIONS:
Counters/Toggles:
Call
KeyTapValueToggle() for the toggle status of a key, or
KeyTapValueCount() for a count of that keys keypresses.
Combos:
It's possible to detect combos, including "combos" of a single key. This is handy for detecting specific keytaps after a KeyTapValueUpdate() has been called.
There are two groups of combo detector functions.
The first is
KeyTapCheckCombo(0,0,0,0,0,0)
The 0s are input paramters, between one and six scancodes. It returns 1 if those scancodes are being tapped. The difference between this and other functions is some of the later scancodes of this function can be zero.
There is a keystate variant:
KeyScanCheckCombo(), again taking the same format as above including ending paramters can be zero.
The second group are for fixed numbers of scancodes, where each parameter is expected to be filled.
KeyTapCheckCombo1(0)
KeyTapCheckCombo2(0,0)
..
KeyTapCheckCombo6(0,0,0,0,0,0)
There are keystate variants.
KeyScanCheckCombo1(0)
KeyScanCheckCombo2(0,0)
..
KeyScanCheckCombo6(0,0,0,0,0,0)
There are also some handy constant definitions typed out.
The example code clarifies that all, I hope.
REMSTART
***** DOCUMENTATION
KEY TAP CHECK
by viberunner
Public Domain.
Use as your own. Enjoy.
This is an enhancement of a function found on the DBP forums.
A key-tap function, that is while a key is being pressed
the first return from the function is 1 (key is pressed)
and second and subsequent calls to the function are zero.
The calls to the function will also be zero as the key
is released. The function returns 1 the first time that
key is pressed again.
Keyboard-wide.
REMEND
` Required to initialise the function.
StartKeyTapCheck()
Set Text Opaque
DO
` Clear Screen
center text screen width()/2,0,"PRESS ANY KEY, HOLD IF IF YOU DESIRE."
center text screen width()/2,20,"ASD TO COMBO. SPACE TO CLEAR."
` Scan all the Keys
FOR i = 1 TO 255
TEST = KeyTapCheck(i)
IF TEST = 1
TEXT RND(SCREEN WIDTH()-30), RND(SCREEN HEIGHT()-30)+15, STR$(i)
TEXT 0,0,STR$(I) + " "
ENDIF
` Method of saving first-keypress of interesting type
IF i = 57 : KEY_Space_Tapped = TEST : ENDIF
NEXT i
` Example of testing for a specific keypress
IF KEY_Space_Tapped = 1
CLS
StartKeyTapCheck()
ENDIF
` General Checker - generic, fill with parameters
` ASD
IF KeyTapCheckCombo(30,31,32,0,0,0) = 1
TEXT ((SCREEN WIDTH()/2)-100)+RND(200), ((SCREEN HEIGHT()/2)-100)+RND(200), "** combo asd **"
ENDIF
` ASD
IF KeyScanCheckCombo(30,31,32,0,0,0) = 1
TEXT SCREEN WIDTH()/2, SCREEN HEIGHT()/2+40, "** scan asd **"
ELSE
TEXT SCREEN WIDTH()/2, SCREEN HEIGHT()/2+40, " "
ENDIF
` Specific Checker - Faster Function
` ASD
IF KeyTapCheckCombo3(30,31,32) = 1
TEXT ((SCREEN WIDTH()/2)-300)+RND(200), ((SCREEN HEIGHT()/2)-100)+RND(200), "** fast combo asd **"
ENDIF
` ASD
IF KeyScanCheckCombo3(30,31,32) = 1
TEXT SCREEN WIDTH()/2-200, SCREEN HEIGHT()/2+40, "** fast scan asd **"
ELSE
TEXT SCREEN WIDTH()/2-200, SCREEN HEIGHT()/2+40, " "
ENDIF
` See toggle and counts for A
i = KeyTapValueToggle(30)
TEXT 0,40,"a toggle " + STR$(i) + " "
i = KeyTapValueCount(30)
TEXT 0,60,"a count " + STR$(i) + " "
LOOP
END
` ********************************************
` FUNCTIONS
` ********************************************
` Main function, call with a SCANCODE each cycle.
FUNCTION KeyTapCheck(KTC AS DWORD)
KTC_KeyTapNew(KTC) = 0
IF KeyState(KTC) > KTC_KeyTapCheck(KTC)
KTC_KeyTapNew(KTC) = 1
INC KTC_KeyTapCount(KTC),1
IF KTC_KeyTapToggle(KTC) = 0
KTC_KeyTapToggle(KTC) = 1
ELSE
KTC_KeyTapToggle(KTC) = 0
ENDIF
ENDIF
KTC_KeyTapCheck(KTC) = 0
IF KeyState(KTC) = 1 : KTC_KeyTapCheck(KTC) = 1 : ENDIF
KTC_Return = KTC_KeyTapNew(KTC)
ENDFUNCTION KTC_Return
` This function used instead of several
` KeyTapCheck() - it won't return keys
` being tapped but it does keep all counters
` and toggles updated; and keys can be returned
` with the Combo checkers (including single-presses).
FUNCTION KeyTapValueUpdate()
LOCAL KTC_Local_Counter AS DWORD = 0
LOCAL KTC_Local_Count_TO AS DWORD = 0
LOCAL KTC_Local_NULL AS DWORD = 0
KTC_Local_Count_TO = ARRAY COUNT(KTC_KeyTapNew(0))
FOR KTC_Local_Counter = 0 TO KTC_Local_Count_TO
KTC_Local_NULL = KeyTapCheck(KTC_Local_Counter)
NEXT KTC_Local_Counter
ENDFUNCTION
` This will return a toggle based on the key code
FUNCTION KeyTapValueToggle(KTC AS DWORD)
LOCAL KTC_Return AS BOOLEAN
KTC_Return = KTC_KeyTapToggle(KTC)
ENDFUNCTION KTC_Return
` This will return a count of the keypresses of a key code
FUNCTION KeyTapValueCount(KTC AS DWORD)
LOCAL KTC_Return AS BOOLEAN
KTC_Return = KTC_KeyTapCount(KTC)
ENDFUNCTION KTC_Return
` Use: parameters p1 to p6 contain key scancodes,
` if all the keys check out as a new keypress
` then 1 is returned. To use less than six
` paramters put 0 for end parameters,
` e.g KeyTapCheckCombo(23,24,0,0,0,0)
` or KeyTapCheckCombo(76,75,190,4,88,0)
FUNCTION KeyTapCheckCombo(p1,p2,p3,p4,p5,p6)
` Sanity Check
IF p1 = 0 : EXITFUNCTION 0 : ENDIF
` First Key Found
IF (KTC_KeyTapNew(p1) = 1) AND _
(p2 = 0)
EXITFUNCTION 1
ENDIF
` First Two
IF (KTC_KeyTapNew(p1) = 1) AND _
(KTC_KeyTapNew(p2) = 1) AND _
(p3 = 0)
EXITFUNCTION 1
ENDIF
` Three
IF (KTC_KeyTapNew(p1) = 1) AND _
(KTC_KeyTapNew(p2) = 1) AND _
(KTC_KeyTapNew(p3) = 1) AND _
(p4 = 0)
EXITFUNCTION 1
ENDIF
` Four
IF (KTC_KeyTapNew(p1) = 1) AND _
(KTC_KeyTapNew(p2) = 1) AND _
(KTC_KeyTapNew(p3) = 1) AND _
(KTC_KeyTapNew(p4) = 1) AND _
(p5 = 0)
EXITFUNCTION 1
ENDIF
` Five
IF (KTC_KeyTapNew(p1) = 1) AND _
(KTC_KeyTapNew(p2) = 1) AND _
(KTC_KeyTapNew(p3) = 1) AND _
(KTC_KeyTapNew(p4) = 1) AND _
(KTC_KeyTapNew(p5) = 1) AND _
(p6 = 0)
EXITFUNCTION 1
ENDIF
` Six
IF (KTC_KeyTapNew(p1) = 1) AND _
(KTC_KeyTapNew(p2) = 1) AND _
(KTC_KeyTapNew(p3) = 1) AND _
(KTC_KeyTapNew(p4) = 1) AND _
(KTC_KeyTapNew(p5) = 1) AND _
(KTC_KeyTapNew(p6) = 1)
EXITFUNCTION 1
ENDIF
` Should be obvious by now how to extend it,
` if you want to check for more than six keys.
ENDFUNCTION 0
` Same as above but returns if keys are
` CURRENTLY being held down, not new keypresses
FUNCTION KeyScanCheckCombo(p1,p2,p3,p4,p5,p6)
` Sanity Check
IF p1 = 0 : EXITFUNCTION 0 : ENDIF
` First Key Found
IF (KeyState(p1) = 1) AND _
(p2 = 0)
EXITFUNCTION 1
ENDIF
` First Two
IF (KeyState(p1) = 1) AND _
(KeyState(p2) = 1) AND _
(p3 = 0)
EXITFUNCTION 1
ENDIF
` Three
IF (KeyState(p1) = 1) AND _
(KeyState(p2) = 1) AND _
(KeyState(p3) = 1) AND _
(p4 = 0)
EXITFUNCTION 1
ENDIF
` Four
IF (KeyState(p1) = 1) AND _
(KeyState(p2) = 1) AND _
(KeyState(p3) = 1) AND _
(KeyState(p4) = 1) AND _
(p5 = 0)
EXITFUNCTION 1
ENDIF
` Five
IF (KeyState(p1) = 1) AND _
(KeyState(p2) = 1) AND _
(KeyState(p3) = 1) AND _
(KeyState(p4) = 1) AND _
(KeyState(p5) = 1) AND _
(p6 = 0)
EXITFUNCTION 1
ENDIF
` Six
IF (KeyState(p1) = 1) AND _
(KeyState(p2) = 1) AND _
(KeyState(p3) = 1) AND _
(KeyState(p4) = 1) AND _
(KeyState(p5) = 1) AND _
(KeyState(p6) = 1)
EXITFUNCTION 1
ENDIF
` Should be obvious by now how to extend it,
` if you want to check for more than six keys.
ENDFUNCTION 0
FUNCTION KeyTapCheckCombo1(p1)
IF (KTC_KeyTapNew(p1) = 1)
EXITFUNCTION 1
ENDIF
ENDFUNCTION 0
FUNCTION KeyTapCheckCombo2(p1,p2)
IF (KTC_KeyTapNew(p1) = 1) AND _
(KTC_KeyTapNew(p2) = 1)
EXITFUNCTION 1
ENDIF
ENDFUNCTION 0
FUNCTION KeyTapCheckCombo3(p1,p2,p3)
IF (KTC_KeyTapNew(p1) = 1) AND _
(KTC_KeyTapNew(p2) = 1) AND _
(KTC_KeyTapNew(p3) = 1)
EXITFUNCTION 1
ENDIF
ENDFUNCTION 0
FUNCTION KeyTapCheckCombo4(p1,p2,p3,p4)
IF (KTC_KeyTapNew(p1) = 1) AND _
(KTC_KeyTapNew(p2) = 1) AND _
(KTC_KeyTapNew(p3) = 1) AND _
(KTC_KeyTapNew(p4) = 1)
EXITFUNCTION 1
ENDIF
ENDFUNCTION 0
FUNCTION KeyTapCheckCombo5(p1,p2,p3,p4,p5)
IF (KTC_KeyTapNew(p1) = 1) AND _
(KTC_KeyTapNew(p2) = 1) AND _
(KTC_KeyTapNew(p3) = 1) AND _
(KTC_KeyTapNew(p4) = 1) AND _
(KTC_KeyTapNew(p5) = 1)
EXITFUNCTION 1
ENDIF
ENDFUNCTION 0
FUNCTION KeyTapCheckCombo6(p1,p2,p3,p4,p5,p6)
IF (KTC_KeyTapNew(p1) = 1) AND _
(KTC_KeyTapNew(p2) = 1) AND _
(KTC_KeyTapNew(p3) = 1) AND _
(KTC_KeyTapNew(p4) = 1) AND _
(KTC_KeyTapNew(p5) = 1) AND _
(KTC_KeyTapNew(p6) = 1)
EXITFUNCTION 1
ENDIF
ENDFUNCTION 0
FUNCTION KeyScanCheckCombo1(p1)
IF (KeyState(p1) = 1)
EXITFUNCTION 1
ENDIF
ENDFUNCTION 0
FUNCTION KeyScanCheckCombo2(p1,p2)
IF (KeyState(p1) = 1) AND _
(KeyState(p2) = 1)
EXITFUNCTION 1
ENDIF
ENDFUNCTION 0
FUNCTION KeyScanCheckCombo3(p1,p2,p3)
IF (KeyState(p1) = 1) AND _
(KeyState(p2) = 1) AND _
(KeyState(p3) = 1)
EXITFUNCTION 1
ENDIF
ENDFUNCTION 0
FUNCTION KeyScanCheckCombo4(p1,p2,p3,p4)
IF (KeyState(p1) = 1) AND _
(KeyState(p2) = 1) AND _
(KeyState(p3) = 1) AND _
(KeyState(p4) = 1)
EXITFUNCTION 1
ENDIF
ENDFUNCTION 0
FUNCTION KeyScanCheckCombo5(p1,p2,p3,p4,p5)
IF (KeyState(p1) = 1) AND _
(KeyState(p2) = 1) AND _
(KeyState(p3) = 1) AND _
(KeyState(p4) = 1) AND _
(KeyState(p5) = 1)
EXITFUNCTION 1
ENDIF
ENDFUNCTION 0
FUNCTION KeyScanCheckCombo6(p1,p2,p3,p4,p5,p6)
IF (KeyState(p1) = 1) AND _
(KeyState(p2) = 1) AND _
(KeyState(p3) = 1) AND _
(KeyState(p4) = 1) AND _
(KeyState(p5) = 1) AND _
(KeyState(p6) = 1)
EXITFUNCTION 1
ENDIF
ENDFUNCTION 0
` Required. Initialises the arrays. Can be re-used to re-intialise.
FUNCTION StartKeyTapCheck()
LOCAL ga AS DWORD = 256
GLOBAL DIM KTC_KeyTapCheck(ga) AS BOOLEAN
GLOBAL DIM KTC_KeyTapNew(ga) AS BOOLEAN
GLOBAL DIM KTC_KeyTapToggle(ga) AS BOOLEAN
GLOBAL DIM KTC_KeyTapCount(ga) AS DWORD
FOR ci = 0 TO ga
KTC_KeyTapCheck(ci) = 0
KTC_KeyTapNew(ci) = 0
KTC_KeyTapToggle(ci) = 0
KTC_KeyTapCount(ci) = 0
NEXT ci
ENDFUNCTION
REMSTART
` You can use these at the top of your program.
` Or you can code the values directly in, e.g.
` test_esc = KeyTapNew(1)
` You might well want to rename some of these.
` These based on UK keyboard, non-UK keyboards
` will have keys missing from this list.
#CONSTANT KEY_ESC 1
#CONSTANT KEY_1 2
#CONSTANT KEY_2 3
#CONSTANT KEY_3 4
#CONSTANT KEY_4 5
#CONSTANT KEY_5 6
#CONSTANT KEY_6 7
#CONSTANT KEY_7 8
#CONSTANT KEY_8 9
#CONSTANT KEY_9 10
#CONSTANT KEY_0 11
#CONSTANT KEY_MINUS 12
#CONSTANT KEY_PLUS 13
#CONSTANT KEY_BACK 14
#CONSTANT KEY_TAB 15
#CONSTANT KEY_Q 16
#CONSTANT KEY_W 17
#CONSTANT KEY_E 18
#CONSTANT KEY_R 19
#CONSTANT KEY_T 20
#CONSTANT KEY_Y 21
#CONSTANT KEY_U 22
#CONSTANT KEY_I 23
#CONSTANT KEY_O 24
#CONSTANT KEY_P 25
#CONSTANT KEY_SQBR_L 26
#CONSTANT KEY_SQBR_R 27
#CONSTANT KEY_RETURN 28
#CONSTANT KEY_CTRL_L 29
#CONSTANT KEY_A 30
#CONSTANT KEY_S 31
#CONSTANT KEY_D 32
#CONSTANT KEY_F 33
#CONSTANT KEY_G 34
#CONSTANT KEY_H 35
#CONSTANT KEY_J 35
#CONSTANT KEY_K 37
#CONSTANT KEY_L 38
#CONSTANT KEY_COLON 39
#CONSTANT KEY_QUOTE 40
#CONSTANT KEY_TILDE 41
#CONSTANT KEY_SHIFT_L 42
#CONSTANT KEY_HASH 43
#CONSTANT KEY_Z 44
#CONSTANT KEY_X 45
#CONSTANT KEY_C 46
#CONSTANT KEY_V 47
#CONSTANT KEY_B 48
#CONSTANT KEY_N 49
#CONSTANT KEY_M 50
#CONSTANT KEY_COMMA 51
#CONSTANT KEY_DOT 52
#CONSTANT KEY_SLASH 53
#CONSTANT KEY_SHIFT_R 54
#CONSTANT KEY_NUM_MULT 55
#CONSTANT KEY_ALT_L 56
#CONSTANT KEY_SPACE 57
#CONSTANT KEY_CAPS 58
#CONSTANT KEY_F1 59
#CONSTANT KEY_F2 60
#CONSTANT KEY_F3 61
#CONSTANT KEY_F4 62
#CONSTANT KEY_F5 63
#CONSTANT KEY_F6 64
#CONSTANT KEY_F7 65
#CONSTANT KEY_F8 66
#CONSTANT KEY_F9 67
#CONSTANT KEY_F10 68
#CONSTANT KEY_NUM_LOCK 69
#CONSTANT KEY_SCROLL 70
#CONSTANT KEY_NUM_7 71
#CONSTANT KEY_NUM_8 72
#CONSTANT KEY_NUM_9 73
#CONSTANT KEY_NUM_MINUS 74
#CONSTANT KEY_NUM_4 75
#CONSTANT KEY_NUM_5 76
#CONSTANT KEY_NUM_6 77
#CONSTANT KEY_NUM_ADD 78
#CONSTANT KEY_NUM_1 79
#CONSTANT KEY_NUM_2 80
#CONSTANT KEY_NUM_3 81
#CONSTANT KEY_NUM_0 82
#CONSTANT KEY_NUM_DOT 83
`
#CONSTANT KEY_BACKSLASH 86
#CONSTANT KEY_F11 87
#CONSTANT KEY_F12 88
#CONSTANT KEY_ENTER 156
#CONSTANT KEY_CTRL_R 157
#CONSTANT KEY_NUM_DIV 181
#CONSTANT KEY_PRINT 183
#CONSTANT KEY_ALT_GR 184
#CONSTANT KEY_PAUSE 197
#CONSTANT KEY_HOME 199
#CONSTANT KEY_ARROW_UP 200
#CONSTANT KEY_PAGE_UP 201
#CONSTANT KEY_ARROW_LEFT 203
#CONSTANT KEY_ARROW_RIGHT 205
#CONSTANT KEY_END 207
#CONSTANT KEY_ARROW_DOWN 208
#CONSTANT KEY_PAGE_DOWN 209
#CONSTANT KEY_INSERT 210
#CONSTANT KEY_DELETE 211
#CONSTANT KEY_WIN_L 219
#CONSTANT KEY_WIN_R 220
#CONSTANT KEY_MENU_R 221
REMEND