sdlgamecontroller.bmx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. ' Copyright (c) 2015-2022 Bruce A Henderson
  2. '
  3. ' This software is provided 'as-is', without any express or implied
  4. ' warranty. In no event will the authors be held liable for any damages
  5. ' arising from the use of this software.
  6. '
  7. ' Permission is granted to anyone to use this software for any purpose,
  8. ' including commercial applications, and to alter it and redistribute it
  9. ' freely, subject to the following restrictions:
  10. '
  11. ' 1. The origin of this software must not be misrepresented; you must not
  12. ' claim that you wrote the original software. If you use this software
  13. ' in a product, an acknowledgment in the product documentation would be
  14. ' appreciated but is not required.
  15. '
  16. ' 2. Altered source versions must be plainly marked as such, and must not be
  17. ' misrepresented as being the original software.
  18. '
  19. ' 3. This notice may not be removed or altered from any source
  20. ' distribution.
  21. '
  22. SuperStrict
  23. Rem
  24. bbdoc: GameController and Joystick Mapping
  25. End Rem
  26. Module SDL.SDLGameController
  27. Import "common.bmx"
  28. Rem
  29. bbdoc: Checks if the given joystick is supported by the game controller interface.
  30. returns: #True if the given joystick is supported by the game controller interface, #False if it isn't or it's an invalid index.
  31. about: @port is joystick port, up to #JoyCount.
  32. End Rem
  33. Function SDLIsGameController:Int(port:Int)
  34. Return SDL_IsGameController(port)
  35. End Function
  36. Rem
  37. bbdoc: A game controller or mapped joystick.
  38. End Rem
  39. Type TSDLGameController
  40. Field controllerPtr:Byte Ptr
  41. Rem
  42. bbdoc: Opens a game controller to use.
  43. returns: A #TSDLGameController instance or #Null if an error occurred; call #SDLGetError() for more information.
  44. about: The @port passed as an argument refers to the N'th game controller on the system.
  45. A call to #Close should be made when you have finished with this game controller.
  46. End Rem
  47. Function Open:TSDLGameController(port:Int)
  48. Local this:TSDLGameController = New TSDLGameController
  49. this.controllerPtr = SDL_GameControllerOpen(port)
  50. If this.controllerPtr Then
  51. Return this
  52. End If
  53. End Function
  54. Rem
  55. bbdoc: Closes the game controller.
  56. End Rem
  57. Method Close()
  58. If controllerPtr Then
  59. SDL_GameControllerClose(controllerPtr)
  60. controllerPtr = Null
  61. End If
  62. End Method
  63. Rem
  64. bbdoc: Checks if a controller has been opened and is currently connected.
  65. returns: #True if the controller has been opened and currently connected, or #False if it has not.
  66. End Rem
  67. Method GetAttached:Int()
  68. Return SDL_GameControllerGetAttached(controllerPtr)
  69. End Method
  70. Rem
  71. bbdoc: Gets the current state of an axis control on a game controller.
  72. returns: Axis state (including 0) on success or 0 (also) on failure; call #SDLGetError for more information.
  73. about: The axis indices start at index 0.
  74. The state is a value ranging from -32768 to 32767. Triggers, however, range from 0 to 32767 (they never return a negative value).
  75. End Rem
  76. Method GetAxis:Int(axis:ESDLGameControllerAxis)
  77. Return SDL_GameControllerGetAxis(controllerPtr, axis)
  78. End Method
  79. Rem
  80. bbdoc: Gets the current state of a button on a game controller.
  81. returns: 1 for pressed state or 0 for not pressed state or error; call #SDLGetError for more information.
  82. about: The button indices start at index 0.
  83. End Rem
  84. Method GetButton:Int(button:ESDLGameControllerButton)
  85. Return SDL_GameControllerGetButton(controllerPtr, button)
  86. End Method
  87. Rem
  88. bbdoc: Gets the implementation dependent name for the game controller.
  89. returns: The implementation dependent name for the game controller, or #Null if there is no name or the controller is invalid.
  90. End Rem
  91. Method GetName:String()
  92. Local n:Byte Ptr = SDL_GameControllerName(controllerPtr)
  93. If n Then
  94. Return String.FromUTF8String(n)
  95. End If
  96. End Method
  97. Rem
  98. bbdoc: Gets the current mapping of the Game Controller.
  99. returns: A #String that has the controller's mapping or #Null if no mapping is available; call #SDLGetError for more information.
  100. about: More information about the mapping can be found at #AddMapping.
  101. End Rem
  102. Method GetMapping:String()
  103. Local n:Byte Ptr = SDL_GameControllerMapping(controllerPtr)
  104. If n Then
  105. Local s:String = String.FromUTF8String(n)
  106. SDL_free(n)
  107. Return s
  108. End If
  109. End Method
  110. Rem
  111. bbdoc: Returns the type of this currently opened controller.
  112. End Rem
  113. Method GetType:ESDLGameControllerType()
  114. Return SDL_GameControllerGetType(controllerPtr)
  115. End Method
  116. Rem
  117. bbdoc: Returns whether the game controller has a given axis.
  118. End Rem
  119. Method HasAxis:Int(axis:ESDLGameControllerAxis)
  120. Return SDL_GameControllerHasAxis(controllerPtr, axis)
  121. End Method
  122. Rem
  123. bbdoc: Returns whether the game controller has a given button.
  124. End Rem
  125. Method HasButton:Int(button:ESDLGameControllerButton)
  126. Return SDL_GameControllerHasButton(controllerPtr, button)
  127. End Method
  128. Rem
  129. bbdoc: Gets the number of touchpads on the game controller.
  130. End Rem
  131. Method GetNumTouchpads:Int()
  132. Return SDL_GameControllerGetNumTouchpads(controllerPtr)
  133. End Method
  134. Rem
  135. bbdoc: Gets the number of supported simultaneous fingers on a touchpad on the game controller.
  136. End Rem
  137. Method GetNumTouchpadFingers:Int(touchpad:Int)
  138. Return SDL_GameControllerGetNumTouchpadFingers(controllerPtr, touchpad)
  139. End Method
  140. Rem
  141. bbdoc: Gets the current state of a finger on a touchpad on the game controller.
  142. End Rem
  143. Method GetTouchpadFinger:Int(touchpad:Int, finger:Int, state:Byte Var, x:Float Var, y:Float Var, pressure:Float Var)
  144. Return SDL_GameControllerGetTouchpadFinger(controllerPtr, touchpad, finger, Varptr state, Varptr x, Varptr y, Varptr pressure)
  145. End Method
  146. Rem
  147. bbdoc: Returns whether the game controller has a particular sensor.
  148. returns: #True if the sensor exists, #False otherwise.
  149. End Rem
  150. Method HasSensor:Int(sensorType:ESDLSensorType)
  151. Return SDL_GameControllerHasSensor(controllerPtr, sensorType)
  152. End Method
  153. Rem
  154. bbdoc: Sets whether data reporting for the game controller sensor is enabled.
  155. returns: 0, or -1 if an error occurred.
  156. End Rem
  157. Method SetSensorEnabled:Int(sensorType:ESDLSensorType, enabled:Int)
  158. Return SDL_GameControllerSetSensorEnabled(controllerPtr, sensorType, enabled)
  159. End Method
  160. Rem
  161. bbdoc: Queries whether sensor data reporting is enabled for the game controller.
  162. returns: #True if the sensor is enabled, #False otherwise.
  163. End Rem
  164. Method IsSensorEnabled:Int(sensorType:ESDLSensorType)
  165. Return SDL_GameControllerIsSensorEnabled(controllerPtr, sensorType)
  166. End Method
  167. Rem
  168. bbdoc: Gets the current state of a game controller sensor.
  169. returns: 0, or -1 if an error occurred.
  170. about: The number of values and interpretation of the data is sensor dependent.
  171. End Rem
  172. Method SDL_GameControllerGetSensorData:Int(sensorType:ESDLSensorType, data:Float Ptr, numValues:Int)
  173. Return SDL_GameControllerGetSensorData(controllerPtr, sensorType, data, numValues)
  174. End Method
  175. Rem
  176. bbdoc: Starts a rumble effect.
  177. returns: 0, or -1 if rumble isn't supported on this controller.
  178. about: Each call to this method cancels any previous rumble effect, and calling it with 0 intensity stops any rumbling.
  179. End Rem
  180. Method Rumble:Int(lowFrequencyRumble:Short, highFrequencyRumble:Short, durationMs:UInt)
  181. Return SDL_GameControllerRumble(controllerPtr, lowFrequencyRumble, highFrequencyRumble, durationMs)
  182. End Method
  183. Rem
  184. bbdoc: Starts a rumble effect in the game controller's triggers
  185. returns: 0, or -1 if rumble isn't supported on this controller.
  186. about: Each call to this function cancels any previous trigger rumble effect, and calling it with 0 intensity stops any rumbling.
  187. End Rem
  188. Method RumbleTriggers:Int(leftRumble:Short, rightRumble:Short, durationMs:UInt)
  189. Return SDL_GameControllerRumbleTriggers(controllerPtr, leftRumble, rightRumble, durationMs)
  190. End Method
  191. Rem
  192. bbdoc: Returns whether the controller has an LED.
  193. returns: #True, or #False if this controller does not have a modifiable LED.
  194. End Rem
  195. Method HasLED:Int()
  196. Return SDL_GameControllerHasLED(controllerPtr)
  197. End Method
  198. Rem
  199. bbdoc: Updates a controller's LED color.
  200. returns: 0, or -1 if this controller does not have a modifiable LED.
  201. End Rem
  202. Method SDL_GameControllerSetLED:Int(red:Byte, green:Byte, blue:Byte)
  203. Return SDL_GameControllerSetLED(controllerPtr, red, green, blue)
  204. End Method
  205. Rem
  206. bbdoc: Queries whether the game controller has rumble support.
  207. returns: #True, or #False if this controller does not have rumble support.
  208. End Rem
  209. Method HasRumble:Int()
  210. Return SDL_GameControllerHasRumble(controllerPtr)
  211. End Method
  212. Rem
  213. bbdoc: Queries whether the game controller has rumble support on triggers.
  214. returns: #True, or #False if this controller does not have trigger rumble support.
  215. End Rem
  216. Method HasRumbleTriggers:Int()
  217. Return SDL_GameControllerHasRumbleTriggers(controllerPtr)
  218. End Method
  219. Rem
  220. bbdoc: Gets the player index of an opened game controller.
  221. returns: The player index for the controller, or -1 if it's not available.
  222. about: For XInput controllers this returns the XInput user index.
  223. End Rem
  224. Method GetPlayerIndex:Int(handle:Byte Ptr)
  225. Return SDL_GameControllerGetPlayerIndex(controllerPtr)
  226. End Method
  227. Rem
  228. bbdoc: Sets the player index of an opened game controller.
  229. End Rem
  230. Method SetPlayerIndex(index:Int)
  231. SDL_GameControllerSetPlayerIndex(controllerPtr, index)
  232. End Method
  233. Rem
  234. bbdoc: Adds support for controllers that SDL is unaware of or to cause an existing controller to have a different binding.
  235. returns: 1 if a new mapping is added, 0 if an existing mapping is updated, -1 on error; call #SDLGetError for more information.
  236. about: The mapping string has the format "GUID,name,mapping", where GUID is the string value from #GetGUIDString, name is the human
  237. readable string for the device and mappings are controller mappings to joystick ones. Under Windows there is a
  238. reserved GUID of "xinput" that covers all XInput devices. The mapping format for joystick is:
  239. | Mapping | Description |
  240. |---|---|
  241. | bX | a joystick button, index X |
  242. | hX.Y | hat X with value Y |
  243. | aX | axis X of the joystick |
  244. Buttons can be used as a controller axes and vice versa.
  245. This string shows an example of a valid mapping for a controller: `"341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7"`
  246. End Rem
  247. Function AddMapping:Int(mapping:String)
  248. Local m:Byte Ptr = mapping.ToUTF8String()
  249. Local res:Int = SDL_GameControllerAddMapping(m)
  250. MemFree(m)
  251. Return res
  252. End Function
  253. Rem
  254. bbdoc: Converts a string into an enum representation for an #ESDLGameControllerAxis.
  255. returns: The #ESDLGameControllerAxis enum corresponding to the input string, or ESDLGameControllerAxis.INVALID if no match was found.
  256. End Rem
  257. Function GetAxisFromString:ESDLGameControllerAxis(txt:String)
  258. Local t:Byte Ptr = txt.ToUTF8String()
  259. Local axis:ESDLGameControllerAxis = SDL_GameControllerGetAxisFromString(t)
  260. MemFree(t)
  261. Return axis
  262. End Function
  263. Rem
  264. bbdoc: Turns a string into a button mapping.
  265. returns: A button mapping (#ESDLGameControllerButton) on success or ESDLGameControllerButton.INVALID on failure.
  266. End Rem
  267. Function GetButtonFromString:ESDLGameControllerButton(txt:String)
  268. Local t:Byte Ptr = txt.ToUTF8String()
  269. Local button:ESDLGameControllerButton = SDL_GameControllerGetButtonFromString(t)
  270. MemFree(t)
  271. Return button
  272. End Function
  273. Rem
  274. bbdoc: Turns an axis enum into a string mapping.
  275. End Rem
  276. Function GetStringForAxis:String(axis:ESDLGameControllerAxis)
  277. Return String.FromUTF8String(SDL_GameControllerGetStringForAxis(axis))
  278. End Function
  279. Rem
  280. bbdoc: Turns a button enum into a string mapping.
  281. End Rem
  282. Function GetStringForButton:String(button:ESDLGameControllerButton)
  283. Return String.FromUTF8String(SDL_GameControllerGetStringForButton(button))
  284. End Function
  285. Rem
  286. bbdoc: Gets the implementation dependent name for the game controller.
  287. returns: The implementation dependent name for the game controller, or #Null if there is no name or the index is invalid.
  288. End Rem
  289. Function NameForIndex:String(port:Int)
  290. Local n:Byte Ptr = SDL_GameControllerNameForIndex(port)
  291. If n Then
  292. Return String.FromUTF8String(n)
  293. End If
  294. End Function
  295. Rem
  296. bbdoc: Gets the type of a game controller.
  297. about: This can be called before any controllers are opened.
  298. End Rem
  299. Function TypeForIndex:ESDLGameControllerType(port:Int)
  300. Return SDL_GameControllerTypeForIndex(port)
  301. End Function
  302. End Type