keyboard.monkey2 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. Namespace mojo.input
  2. #Import "native/keyinfo.h"
  3. #Import "native/keyinfo.cpp"
  4. Extern Private
  5. Struct bbKeyInfo
  6. Field name:Void Ptr
  7. Field scanCode:Int
  8. Field keyCode:Int
  9. End
  10. Global bbKeyInfos:bbKeyInfo Ptr
  11. Public
  12. #rem monkeydoc Global instance of the KeyboardDevice class.
  13. #end
  14. Const Keyboard:=New KeyboardDevice
  15. #rem monkeydoc The KeyboardDevice class.
  16. All method that take a `key` parameter can also be used with 'raw' keys.
  17. A raw key represents the physical location of a key on US keyboards. For example, `Key.Q|Key.Raw` indicates the key at the top left of the
  18. 'qwerty' keys regardless of the current keyboard layout.
  19. Please see the [[Key]] enum for more information on raw keys.
  20. To access the keyboard device, use the global [[Keyboard]] constant.
  21. The keyboard device should only used after a new [[app.AppInstance]] is created.
  22. #end
  23. Class KeyboardDevice Extends InputDevice
  24. #rem monkeydoc The current state of the modifier keys.
  25. #end
  26. Property Modifiers:Modifier()
  27. Return _modifiers
  28. End
  29. #rem monkeydoc Gets the name of a key.
  30. If `key` is a raw key, returns the name 'printed' on that key.
  31. if `key` is a virtual key
  32. #end
  33. Method KeyName:String( key:Key )
  34. If key & key.Raw key=TranslateKey( key )
  35. Return _names[key]
  36. End
  37. #rem monkeydoc Translates a key to/from a raw key.
  38. If `key` is a raw key, returns the corresponding virual key.
  39. If `key` is a virtual key, returns the corresponding raw key.
  40. #end
  41. Method TranslateKey:Key( key:Key )
  42. If key & Key.Raw
  43. #If __TARGET__="emscripten"
  44. Return key & ~Key.Raw
  45. #Else
  46. Local keyCode:=SDL_GetKeyFromScancode( Cast<SDL_Scancode>( _raw2scan[ key & ~Key.Raw ] ) )
  47. Return KeyCodeToKey( keyCode )
  48. #Endif
  49. Else
  50. Local scanCode:=_key2scan[key]
  51. Return _scan2raw[scanCode]
  52. Endif
  53. Return Key.None
  54. End
  55. #rem monkeydoc Checks the current up/down state of a key.
  56. Returns true if `key` is currently held down.
  57. If `key` is a raw key, the state of the key as it is physically positioned on US keyboards is returned.
  58. @param key Key to check.
  59. #end
  60. Method KeyDown:Bool( key:Key )
  61. Local scode:=ScanCode( key )
  62. Return _down[scode]
  63. End
  64. #rem monkeydoc Checks if a key was pressed.
  65. Returns true if `key` was pressed since the last call to KeyPressed with the same key.
  66. If `key` is a raw key, the state of the key as it is physically positioned on US keyboards is returned.
  67. @param key Key to check.
  68. #end
  69. Method KeyPressed:Bool( key:Key )
  70. Local scode:=ScanCode( key )
  71. Return _pressed[scode]
  72. End
  73. #rem monkeydoc Checks if a key was released.
  74. Returns true if `key` was released since the last call to KeyReleased with the same key.
  75. If `key` is a raw key, the state of the key as it is physically positioned on US keyboards is returned.
  76. @param key Key to check.
  77. #end
  78. Method KeyReleased:Bool( key:Key )
  79. Local scode:=ScanCode( key )
  80. Return _released[scode]
  81. End
  82. #rem monkeydoc @hidden
  83. #end
  84. Method KeyHit:Bool( key:Key )
  85. Return KeyPressed( key )
  86. End
  87. '***** Internal *****
  88. #rem monkeydoc @hidden
  89. #end
  90. Method ScanCode:Int( key:Key )
  91. If key & Key.Raw Return _raw2scan[ key & ~Key.Raw ]
  92. Return _key2scan[ key ]
  93. End
  94. #rem monkeydoc @hidden
  95. #end
  96. Method KeyCodeToKey:Key( keyCode:Int )
  97. If (keyCode & $40000000) keyCode=(keyCode & ~$40000000)+$80
  98. Return Cast<Key>( keyCode )
  99. End
  100. #rem monkeydoc @hidden
  101. #end
  102. Method ScanCodeToRawKey:Key( scanCode:Int )
  103. Return _scan2raw[ scanCode ]
  104. End
  105. #rem monkeydoc @hidden
  106. #end
  107. Method Init()
  108. Local p:=bbKeyInfos
  109. While p->name
  110. Local name:=String.FromCString( p->name )
  111. Local scanCode:=p->scanCode
  112. Local keyCode:=p->keyCode
  113. Local key:=KeyCodeToKey( keyCode )
  114. _names[key]=name
  115. _raw2scan[key]=scanCode
  116. _scan2raw[scanCode]=key | Key.Raw
  117. #If __TARGET__="emscripten"
  118. _key2scan[key]=scanCode
  119. #Else
  120. _key2scan[key]=SDL_GetScancodeFromKey( Cast<SDL_Keycode>( keyCode ) )
  121. #Endif
  122. _scan2key[_key2scan[key]]=scanCode
  123. p=p+1
  124. Wend
  125. End
  126. #rem monkeydoc @hidden
  127. #end
  128. Method Update()
  129. For Local key:=Eachin _pressedKeys
  130. _pressed[key]=False
  131. Next
  132. _pressedKeys.Clear()
  133. For Local key:=Eachin _releasedKeys
  134. _released[key]=False
  135. Next
  136. _releasedKeys.Clear()
  137. End
  138. #rem monkeydoc @hidden
  139. #end
  140. Method SendEvent( event:SDL_Event Ptr )
  141. Select event->type
  142. Case SDL_KEYDOWN
  143. Local kevent:=Cast<SDL_KeyboardEvent Ptr>( event )
  144. Local scode:=kevent->keysym.scancode
  145. If _down[scode] Return
  146. _down[scode]=True
  147. _pressed[scode]=True
  148. _pressedKeys.Push( scode )
  149. Select kevent->keysym.sym
  150. Case $400000e0 _modifiers|=Modifier.LeftControl
  151. Case $400000e1 _modifiers|=Modifier.LeftShift
  152. Case $400000e2 _modifiers|=Modifier.LeftAlt
  153. Case $400000e3 _modifiers|=Modifier.LeftGui
  154. Case $400000e4 _modifiers|=Modifier.RightControl
  155. Case $400000e5 _modifiers|=Modifier.RightShift
  156. Case $400000e6 _modifiers|=Modifier.RightAlt
  157. Case $400000e7 _modifiers|=Modifier.RightGui
  158. End
  159. Case SDL_KEYUP
  160. Local kevent:=Cast<SDL_KeyboardEvent Ptr>( event )
  161. Local scode:=kevent->keysym.scancode
  162. If Not _down[scode] Return
  163. _down[scode]=False
  164. _released[scode]=True
  165. _releasedKeys.Push( scode )
  166. Select kevent->keysym.sym
  167. Case $400000e0 _modifiers&=~Modifier.LeftControl
  168. Case $400000e1 _modifiers&=~Modifier.LeftShift
  169. Case $400000e2 _modifiers&=~Modifier.LeftAlt
  170. Case $400000e3 _modifiers&=~Modifier.LeftGui
  171. Case $400000e4 _modifiers&=~Modifier.RightControl
  172. Case $400000e5 _modifiers&=~Modifier.RightShift
  173. Case $400000e6 _modifiers&=~Modifier.RightAlt
  174. Case $400000e7 _modifiers&=~Modifier.RightGui
  175. End
  176. End
  177. End
  178. Private
  179. Field _modifiers:Modifier
  180. Field _down:=New Bool[512]
  181. Field _pressed:=New Bool[512]
  182. Field _released:=New Bool[512]
  183. Field _pressedKeys:=New IntStack
  184. Field _releasedKeys:=New IntStack
  185. Field _names:=New String[512]
  186. Field _raw2scan:=New Int[512] 'no translate
  187. Field _scan2raw:=New Key[512] 'no translate
  188. Field _key2scan:=New Int[512] 'translate
  189. Field _scan2key:=New Int[512] 'translate
  190. Method New()
  191. End
  192. End