sdlinput.pas 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. unit sdlinput;
  2. {
  3. $Id: sdlinput.pas,v 1.7 2004/09/30 22:32:04 savage Exp $
  4. }
  5. {******************************************************************************}
  6. { }
  7. { JEDI-SDL : Pascal units for SDL - Simple DirectMedia Layer }
  8. { SDL Input Wrapper }
  9. { }
  10. { }
  11. { The initial developer of this Pascal code was : }
  12. { Dominique Louis <[email protected]> }
  13. { }
  14. { Portions created by Dominique Louis are }
  15. { Copyright (C) 2003 - 2100 Dominique Louis. }
  16. { }
  17. { }
  18. { Contributor(s) }
  19. { -------------- }
  20. { Dominique Louis <[email protected]> }
  21. { }
  22. { Obtained through: }
  23. { Joint Endeavour of Delphi Innovators ( Project JEDI ) }
  24. { }
  25. { You may retrieve the latest version of this file at the Project }
  26. { JEDI home page, located at http://delphi-jedi.org }
  27. { }
  28. { The contents of this file are used with permission, subject to }
  29. { the Mozilla Public License Version 1.1 (the "License"); you may }
  30. { not use this file except in compliance with the License. You may }
  31. { obtain a copy of the License at }
  32. { http://www.mozilla.org/MPL/MPL-1.1.html }
  33. { }
  34. { Software distributed under the License is distributed on an }
  35. { "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
  36. { implied. See the License for the specific language governing }
  37. { rights and limitations under the License. }
  38. { }
  39. { Description }
  40. { ----------- }
  41. { SDL Mouse, Keyboard and Joystick wrapper }
  42. { }
  43. { }
  44. { Requires }
  45. { -------- }
  46. { SDL.dll on Windows platforms }
  47. { libSDL-1.1.so.0 on Linux platform }
  48. { }
  49. { Programming Notes }
  50. { ----------------- }
  51. { }
  52. { }
  53. { }
  54. { }
  55. { Revision History }
  56. { ---------------- }
  57. { March 12 2003 - DL : Initial creation }
  58. { }
  59. { February 02 2004 - DL : Added Custom Cursor Support to the Mouse class }
  60. {
  61. $Log: sdlinput.pas,v $
  62. Revision 1.7 2004/09/30 22:32:04 savage
  63. Updated with slightly different header comments
  64. Revision 1.6 2004/09/12 21:52:58 savage
  65. Slight changes to fix some issues with the sdl classes.
  66. Revision 1.5 2004/05/10 21:11:49 savage
  67. changes required to help get SoAoS off the ground.
  68. Revision 1.4 2004/05/03 22:38:40 savage
  69. Added the ability to enable or disable certain inputs @ runtime. Basically it just does not call UpdateInput if Enabled = false.
  70. Can also disable and enable input devices via the InputManager.
  71. Revision 1.3 2004/04/28 21:27:01 savage
  72. Updated Joystick code and event handlers. Needs testing...
  73. Revision 1.2 2004/02/14 22:36:29 savage
  74. Fixed inconsistencies of using LoadLibrary and LoadModule.
  75. Now all units make use of LoadModule rather than LoadLibrary and other dynamic proc procedures.
  76. Revision 1.1 2004/02/05 00:08:20 savage
  77. Module 1.0 release
  78. }
  79. {******************************************************************************}
  80. interface
  81. {$i jedi-sdl.inc}
  82. uses
  83. Classes,
  84. sdl;
  85. type
  86. TSDLInputType = ( itJoystick , itKeyBoard, itMouse );
  87. TSDLInputTypes = set of TSDLInputType;
  88. TSDLCustomInput = class( TObject )
  89. private
  90. FEnabled: Boolean;
  91. public
  92. constructor Create;
  93. function UpdateInput( event: TSDL_EVENT ) : Boolean; virtual; abstract;
  94. property Enabled : Boolean read FEnabled write FEnabled;
  95. end;
  96. TSDLJoyAxisMoveEvent = procedure ( Which: UInt8; Axis: UInt8; Value: SInt16 ) {$IFNDEF NOT_OO}of object{$ENDIF};
  97. TSDLJoyBallMoveEvent = procedure ( Which: UInt8; Ball: UInt8; RelativePos: TPoint ) {$IFNDEF NOT_OO}of object{$ENDIF};
  98. TSDLJoyHatMoveEvent = procedure ( Which: UInt8; Hat: UInt8; Value: SInt16 ) {$IFNDEF NOT_OO}of object{$ENDIF};
  99. TSDLJoyButtonEvent = procedure ( Which: UInt8; Button: UInt8; State: SInt16 ) {$IFNDEF NOT_OO}of object{$ENDIF};
  100. TSDLJoyStick = class( TSDLCustomInput )
  101. private
  102. FJoystick : PSDL_Joystick;
  103. FJoystickIndex : Integer;
  104. FJoyAxisMoveEvent : TSDLJoyAxisMoveEvent;
  105. FJoyBallMoveEvent : TSDLJoyBallMoveEvent;
  106. FJoyHatMoveEvent : TSDLJoyHatMoveEvent;
  107. FJoyButtonDownEvent : TSDLJoyButtonEvent;
  108. FJoyButtonUpEvent : TSDLJoyButtonEvent;
  109. procedure DoAxisMove( Event : TSDL_Event );
  110. procedure DoBallMove( Event : TSDL_Event );
  111. procedure DoHatMove( Event : TSDL_Event );
  112. procedure DoButtonDown( Event : TSDL_Event );
  113. procedure DoButtonUp( Event : TSDL_Event );
  114. function GetName: PChar;
  115. function GetNumAxes: integer;
  116. function GetNumBalls: integer;
  117. function GetNumButtons: integer;
  118. function GetNumHats: integer;
  119. public
  120. constructor Create( Index : Integer );
  121. destructor Destroy; override;
  122. procedure Open;
  123. procedure Close;
  124. function UpdateInput( Event: TSDL_EVENT ) : Boolean; override;
  125. property Name : PChar read GetName;
  126. property NumAxes : integer read GetNumAxes;
  127. property NumBalls : integer read GetNumBalls;
  128. property NumButtons : integer read GetNumButtons;
  129. property NumHats : integer read GetNumHats;
  130. property OnAxisMove : TSDLJoyAxisMoveEvent read FJoyAxisMoveEvent write FJoyAxisMoveEvent;
  131. property OnBallMove : TSDLJoyBallMoveEvent read FJoyBallMoveEvent write FJoyBallMoveEvent;
  132. property OnHatMove : TSDLJoyHatMoveEvent read FJoyHatMoveEvent write FJoyHatMoveEvent;
  133. property OnButtonDown : TSDLJoyButtonEvent read FJoyButtonDownEvent write FJoyButtonDownEvent;
  134. property OnButtonUp : TSDLJoyButtonEvent read FJoyButtonUpEvent write FJoyButtonUpEvent;
  135. end;
  136. TSDLJoySticks = class( TObject )
  137. private
  138. FNumOfJoySticks: Integer;
  139. FJoyStickList : TList;
  140. function GetJoyStick(Index: integer): TSDLJoyStick;
  141. procedure SetJoyStick(Index: integer; const Value: TSDLJoyStick);
  142. public
  143. constructor Create;
  144. destructor Destroy; override;
  145. function UpdateInput( event: TSDL_EVENT ) : Boolean;
  146. property NumOfJoySticks : Integer read FNumOfJoySticks write FNumOfJoySticks;
  147. property JoySticks[ Index : integer ] : TSDLJoyStick read GetJoyStick write SetJoyStick;
  148. end;
  149. TSDLKeyBoardEvent = procedure ( var Key: TSDLKey; Shift: TSDLMod; unicode : UInt16 ) {$IFNDEF NOT_OO}of object{$ENDIF};
  150. TSDLKeyBoard = class( TSDLCustomInput )
  151. private
  152. FKeys : PKeyStateArr;
  153. FOnKeyUp: TSDLKeyBoardEvent;
  154. FOnKeyDown: TSDLKeyBoardEvent;
  155. procedure DoKeyDown( keysym : PSDL_keysym );
  156. procedure DoKeyUp( keysym : PSDL_keysym );
  157. public
  158. function IsKeyDown( Key : TSDLKey ) : Boolean;
  159. function IsKeyUp( Key : TSDLKey ) : Boolean;
  160. function UpdateInput( event: TSDL_EVENT ) : Boolean; override;
  161. property Keys : PKeyStateArr read FKeys write FKeys;
  162. property OnKeyDown : TSDLKeyBoardEvent read FOnKeyDown write FOnKeyDown;
  163. property OnKeyUp : TSDLKeyBoardEvent read FOnKeyUp write FOnKeyUp;
  164. end;
  165. TSDLMouseButtonEvent = procedure ( Button : Integer; Shift: TSDLMod; MousePos : TPoint ) {$IFNDEF NOT_OO}of object{$ENDIF};
  166. TSDLMouseMoveEvent = procedure ( Shift: TSDLMod; CurrentPos : TPoint; RelativePos : TPoint ) {$IFNDEF NOT_OO}of object{$ENDIF};
  167. TSDLMouseWheelEvent = procedure ( WheelDelta : Integer; Shift: TSDLMod; MousePos : TPoint ) {$IFNDEF NOT_OO}of object{$ENDIF};
  168. TSDLMouse = class( TSDLCustomInput )
  169. private
  170. FDragging : Boolean;
  171. FMousePos : TPoint;
  172. FOnMouseUp: TSDLMouseButtonEvent;
  173. FOnMouseDown: TSDLMouseButtonEvent;
  174. FOnMouseMove: TSDLMouseMoveEvent;
  175. FOnMouseWheel: TSDLMouseWheelEvent;
  176. FCursor : PSDL_Cursor; // Cursor Pointer
  177. procedure DoMouseMove( Event: TSDL_Event );
  178. procedure DoMouseDown( Event: TSDL_Event );
  179. procedure DoMouseUp( Event: TSDL_Event );
  180. procedure DoMouseWheelScroll( Event: TSDL_Event );
  181. function GetMousePosition: TPoint;
  182. procedure SetMousePosition(const Value: TPoint);
  183. public
  184. destructor Destroy; override;
  185. function UpdateInput( event: TSDL_EVENT ) : Boolean; override;
  186. function MouseIsDown( Button : Integer ) : Boolean;
  187. function MouseIsUp( Button : Integer ) : Boolean;
  188. procedure SetCursor(data, mask: PUInt8; w, h, hot_x, hot_y: Integer);
  189. procedure ShowCursor;
  190. procedure HideCursor;
  191. property OnMouseDown : TSDLMouseButtonEvent read FOnMouseDown write FOnMouseDown;
  192. property OnMouseUp : TSDLMouseButtonEvent read FOnMouseUp write FOnMouseUp;
  193. property OnMouseMove : TSDLMouseMoveEvent read FOnMouseMove write FOnMouseMove;
  194. property OnMouseWheel : TSDLMouseWheelEvent read FOnMouseWheel write FOnMouseWheel;
  195. property MousePosition : TPoint read GetMousePosition write SetMousePosition;
  196. end;
  197. TSDLInputManager = class( TObject )
  198. private
  199. FKeyBoard : TSDLKeyBoard;
  200. FMouse : TSDLMouse;
  201. FJoystick : TSDLJoysticks;
  202. public
  203. constructor Create( InitInputs : TSDLInputTypes );
  204. destructor Destroy; override;
  205. procedure Disable( InitInputs : TSDLInputTypes; JoyStickNumber : Integer = 0 );
  206. procedure Enable( InitInputs : TSDLInputTypes; JoyStickNumber : Integer = 0 );
  207. function UpdateInputs( event: TSDL_EVENT ) : Boolean;
  208. property KeyBoard : TSDLKeyBoard read FKeyBoard write FKeyBoard;
  209. property Mouse : TSDLMouse read FMouse write FMouse;
  210. property JoyStick : TSDLJoysticks read FJoyStick write FJoyStick;
  211. end;
  212. implementation
  213. { TSDLCustomInput }
  214. constructor TSDLCustomInput.Create;
  215. begin
  216. inherited;
  217. FEnabled := true;
  218. end;
  219. { TSDLJoysticks }
  220. constructor TSDLJoysticks.Create;
  221. var
  222. i : integer;
  223. begin
  224. inherited;
  225. if ( SDL_WasInit( SDL_INIT_JOYSTICK ) = 0 ) then
  226. SDL_InitSubSystem( SDL_INIT_JOYSTICK );
  227. FNumOfJoySticks := SDL_NumJoysticks;
  228. FJoyStickList := TList.Create;
  229. for i := 0 to FNumOfJoySticks - 1 do
  230. begin
  231. FJoyStickList.Add( TSDLJoyStick.Create( i ) );
  232. end;
  233. end;
  234. destructor TSDLJoysticks.Destroy;
  235. var
  236. i : integer;
  237. begin
  238. if FJoyStickList.Count > 0 then
  239. begin
  240. for i := 0 to FJoyStickList.Count - 1 do
  241. begin
  242. TSDLJoyStick( FJoyStickList.Items[i] ).Free;
  243. end;
  244. end;
  245. SDL_QuitSubSystem( SDL_INIT_JOYSTICK );
  246. inherited;
  247. end;
  248. function TSDLJoySticks.GetJoyStick(Index: integer): TSDLJoyStick;
  249. begin
  250. Result := TSDLJoyStick( FJoyStickList[ Index ] );
  251. end;
  252. procedure TSDLJoySticks.SetJoyStick(Index: integer;
  253. const Value: TSDLJoyStick);
  254. begin
  255. FJoyStickList[ Index ] := @Value;
  256. end;
  257. function TSDLJoysticks.UpdateInput(event: TSDL_EVENT): Boolean;
  258. var
  259. i : integer;
  260. begin
  261. result := false;
  262. if FJoyStickList.Count > 0 then
  263. begin
  264. for i := 0 to FJoyStickList.Count - 1 do
  265. begin
  266. TSDLJoyStick( FJoyStickList.Items[i] ).UpdateInput( event );
  267. end;
  268. end;
  269. end;
  270. { TSDLKeyBoard }
  271. procedure TSDLKeyBoard.DoKeyDown(keysym: PSDL_keysym);
  272. begin
  273. if Assigned( FOnKeyDown ) then
  274. FOnKeyDown( keysym.sym , keysym.modifier, keysym.unicode );
  275. end;
  276. procedure TSDLKeyBoard.DoKeyUp(keysym: PSDL_keysym);
  277. begin
  278. if Assigned( FOnKeyUp ) then
  279. FOnKeyUp( keysym.sym , keysym.modifier, keysym.unicode );
  280. end;
  281. function TSDLKeyBoard.IsKeyDown( Key: TSDLKey ): Boolean;
  282. begin
  283. SDL_PumpEvents;
  284. // Populate Keys array
  285. FKeys := PKeyStateArr( SDL_GetKeyState( nil ) );
  286. Result := ( FKeys[Key] = SDL_PRESSED );
  287. end;
  288. function TSDLKeyBoard.IsKeyUp( Key: TSDLKey ): Boolean;
  289. begin
  290. SDL_PumpEvents;
  291. // Populate Keys array
  292. FKeys := PKeyStateArr( SDL_GetKeyState( nil ) );
  293. Result := ( FKeys[Key] = SDL_RELEASED );
  294. end;
  295. function TSDLKeyBoard.UpdateInput(event: TSDL_EVENT): Boolean;
  296. begin
  297. result := false;
  298. if ( FEnabled ) then
  299. begin
  300. case event.type_ of
  301. SDL_KEYDOWN :
  302. begin
  303. // handle key presses
  304. DoKeyDown( @event.key.keysym );
  305. result := true;
  306. end;
  307. SDL_KEYUP :
  308. begin
  309. // handle key releases
  310. DoKeyUp( @event.key.keysym );
  311. result := true;
  312. end;
  313. end;
  314. end;
  315. end;
  316. { TSDLMouse }
  317. destructor TSDLMouse.Destroy;
  318. begin
  319. if FCursor <> nil then
  320. SDL_FreeCursor( FCursor );
  321. inherited;
  322. end;
  323. procedure TSDLMouse.DoMouseDown( Event: TSDL_Event );
  324. var
  325. CurrentPos : TPoint;
  326. begin
  327. FDragging := true;
  328. if Assigned( FOnMouseDown ) then
  329. begin
  330. CurrentPos.x := event.button.x;
  331. CurrentPos.y := event.button.y;
  332. FOnMouseDown( event.button.button, SDL_GetModState, CurrentPos );
  333. end;
  334. end;
  335. procedure TSDLMouse.DoMouseMove( Event: TSDL_Event );
  336. var
  337. CurrentPos, RelativePos : TPoint;
  338. begin
  339. if Assigned( FOnMouseMove ) then
  340. begin
  341. CurrentPos.x := event.motion.x;
  342. CurrentPos.y := event.motion.y;
  343. RelativePos.x := event.motion.xrel;
  344. RelativePos.y := event.motion.yrel;
  345. FOnMouseMove( SDL_GetModState, CurrentPos, RelativePos );
  346. end;
  347. end;
  348. procedure TSDLMouse.DoMouseUp( event: TSDL_EVENT );
  349. var
  350. Point : TPoint;
  351. begin
  352. FDragging := false;
  353. if Assigned( FOnMouseUp ) then
  354. begin
  355. Point.x := event.button.x;
  356. Point.y := event.button.y;
  357. FOnMouseUp( event.button.button, SDL_GetModState, Point );
  358. end;
  359. end;
  360. procedure TSDLMouse.DoMouseWheelScroll( event: TSDL_EVENT );
  361. var
  362. Point : TPoint;
  363. begin
  364. if Assigned( FOnMouseWheel ) then
  365. begin
  366. Point.x := event.button.x;
  367. Point.y := event.button.y;
  368. if ( event.button.button = SDL_BUTTON_WHEELUP ) then
  369. FOnMouseWheel( SDL_BUTTON_WHEELUP, SDL_GetModState, Point )
  370. else
  371. FOnMouseWheel( SDL_BUTTON_WHEELDOWN, SDL_GetModState, Point );
  372. end;
  373. end;
  374. function TSDLMouse.GetMousePosition: TPoint;
  375. begin
  376. SDL_PumpEvents;
  377. SDL_GetMouseState( FMousePos.X, FMousePos.Y );
  378. Result := FMousePos;
  379. end;
  380. procedure TSDLMouse.HideCursor;
  381. begin
  382. SDL_ShowCursor( SDL_DISABLE );
  383. end;
  384. function TSDLMouse.MouseIsDown(Button: Integer): Boolean;
  385. begin
  386. SDL_PumpEvents;
  387. Result := ( SDL_GetMouseState( FMousePos.X, FMousePos.Y ) and SDL_BUTTON( Button ) = 0 );
  388. end;
  389. function TSDLMouse.MouseIsUp(Button: Integer): Boolean;
  390. begin
  391. SDL_PumpEvents;
  392. Result := not ( SDL_GetMouseState( FMousePos.X, FMousePos.Y ) and SDL_BUTTON( Button ) = 0 );
  393. end;
  394. procedure TSDLMouse.SetCursor(data, mask: PUInt8; w, h, hot_x, hot_y: Integer);
  395. begin
  396. if FCursor <> nil then
  397. SDL_FreeCursor( FCursor );
  398. // create the cursor
  399. FCursor := SDL_CreateCursor( data, mask, w, h, hot_x, hot_y );
  400. // set the cursor
  401. SDL_SetCursor( FCursor );
  402. end;
  403. procedure TSDLMouse.SetMousePosition(const Value: TPoint);
  404. begin
  405. SDL_WarpMouse( Value.x, Value.y );
  406. end;
  407. procedure TSDLMouse.ShowCursor;
  408. begin
  409. SDL_ShowCursor( SDL_ENABLE );
  410. end;
  411. function TSDLMouse.UpdateInput(event: TSDL_EVENT): Boolean;
  412. begin
  413. result := false;
  414. if ( FEnabled ) then
  415. begin
  416. case event.type_ of
  417. SDL_MOUSEMOTION :
  418. begin
  419. // handle Mouse Move
  420. DoMouseMove( event );
  421. end;
  422. SDL_MOUSEBUTTONDOWN :
  423. begin
  424. // handle Mouse Down
  425. if ( event.button.button = SDL_BUTTON_WHEELUP )
  426. or ( event.button.button = SDL_BUTTON_WHEELDOWN ) then
  427. DoMouseWheelScroll( event )
  428. else
  429. DoMouseDown( event );
  430. end;
  431. SDL_MOUSEBUTTONUP :
  432. begin
  433. // handle Mouse Up
  434. if ( event.button.button = SDL_BUTTON_WHEELUP )
  435. or ( event.button.button = SDL_BUTTON_WHEELDOWN ) then
  436. DoMouseWheelScroll( event )
  437. else
  438. DoMouseUp( event );
  439. end;
  440. end;
  441. end;
  442. end;
  443. { TSDLInputManager }
  444. constructor TSDLInputManager.Create(InitInputs: TSDLInputTypes);
  445. begin
  446. inherited Create;
  447. if itJoystick in InitInputs then
  448. FJoystick := TSDLJoysticks.Create;
  449. if itKeyBoard in InitInputs then
  450. FKeyBoard := TSDLKeyBoard.Create;
  451. if itMouse in InitInputs then
  452. FMouse := TSDLMouse.Create;
  453. end;
  454. destructor TSDLInputManager.Destroy;
  455. begin
  456. if FJoystick <> nil then
  457. FreeAndNil( FJoystick );
  458. if FKeyBoard <> nil then
  459. FreeAndNil( FKeyBoard );
  460. if FMouse <> nil then
  461. FreeAndNil( FMouse );
  462. inherited;
  463. end;
  464. procedure TSDLInputManager.Disable( InitInputs : TSDLInputTypes; JoyStickNumber : Integer );
  465. begin
  466. if itJoystick in InitInputs then
  467. FJoystick.JoySticks[ JoyStickNumber ].Enabled := false;
  468. if itKeyBoard in InitInputs then
  469. FKeyBoard.Enabled := false;
  470. if itMouse in InitInputs then
  471. FMouse.Enabled := false;
  472. end;
  473. procedure TSDLInputManager.Enable( InitInputs: TSDLInputTypes; JoyStickNumber: Integer );
  474. begin
  475. if itJoystick in InitInputs then
  476. FJoystick.JoySticks[ JoyStickNumber ].Enabled := true;
  477. if itKeyBoard in InitInputs then
  478. FKeyBoard.Enabled := true;
  479. if itMouse in InitInputs then
  480. FMouse.Enabled := true;
  481. end;
  482. function TSDLInputManager.UpdateInputs( event: TSDL_EVENT ): Boolean;
  483. begin
  484. Result := false;
  485. if ( FJoystick <> nil ) then
  486. Result := FJoystick.UpdateInput( event );
  487. if ( FKeyBoard <> nil ) then
  488. Result := FKeyBoard.UpdateInput( event );
  489. if ( FMouse <> nil ) then
  490. Result := FMouse.UpdateInput( event );
  491. end;
  492. { TSDLJoyStick }
  493. procedure TSDLJoyStick.Close;
  494. begin
  495. SDL_JoystickClose( @FJoystick );
  496. end;
  497. constructor TSDLJoyStick.Create( Index : Integer );
  498. begin
  499. inherited Create;
  500. FJoystick := nil;
  501. FJoystickIndex := Index;
  502. end;
  503. destructor TSDLJoyStick.Destroy;
  504. begin
  505. if FJoystick <> nil then
  506. Close;
  507. inherited;
  508. end;
  509. procedure TSDLJoyStick.DoAxisMove(Event: TSDL_Event);
  510. begin
  511. if Assigned( FJoyAxisMoveEvent ) then
  512. begin
  513. FJoyAxisMoveEvent( Event.jaxis.which, Event.jaxis.axis, Event.jaxis.value );
  514. end
  515. end;
  516. procedure TSDLJoyStick.DoBallMove(Event: TSDL_Event);
  517. var
  518. BallPoint : TPoint;
  519. begin
  520. if Assigned( FJoyBallMoveEvent ) then
  521. begin
  522. BallPoint.x := Event.jball.xrel;
  523. BallPoint.y := Event.jball.yrel;
  524. FJoyBallMoveEvent( Event.jball.which, Event.jball.ball, BallPoint );
  525. end;
  526. end;
  527. procedure TSDLJoyStick.DoButtonDown(Event: TSDL_Event);
  528. begin
  529. if Assigned( FJoyButtonDownEvent ) then
  530. begin
  531. if ( Event.jbutton.state = SDL_PRESSED ) then
  532. FJoyButtonDownEvent( Event.jbutton.which, Event.jbutton.button, Event.jbutton.state );
  533. end;
  534. end;
  535. procedure TSDLJoyStick.DoButtonUp(Event: TSDL_Event);
  536. begin
  537. if Assigned( FJoyButtonUpEvent ) then
  538. begin
  539. if ( Event.jbutton.state = SDL_RELEASED ) then
  540. FJoyButtonUpEvent( Event.jbutton.which, Event.jbutton.button, Event.jbutton.state );
  541. end
  542. end;
  543. procedure TSDLJoyStick.DoHatMove(Event: TSDL_Event);
  544. begin
  545. if Assigned( FJoyHatMoveEvent ) then
  546. begin
  547. FJoyHatMoveEvent( Event.jhat.which, Event.jhat.hat, Event.jhat.value );
  548. end;
  549. end;
  550. function TSDLJoyStick.GetName: PChar;
  551. begin
  552. result := FJoystick.name;
  553. end;
  554. function TSDLJoyStick.GetNumAxes: integer;
  555. begin
  556. result := FJoystick.naxes;
  557. end;
  558. function TSDLJoyStick.GetNumBalls: integer;
  559. begin
  560. result := FJoystick.nballs;
  561. end;
  562. function TSDLJoyStick.GetNumButtons: integer;
  563. begin
  564. result := FJoystick.nbuttons;
  565. end;
  566. function TSDLJoyStick.GetNumHats: integer;
  567. begin
  568. result := FJoystick.nhats;
  569. end;
  570. procedure TSDLJoyStick.Open;
  571. begin
  572. FJoystick := SDL_JoyStickOpen( FJoystickIndex );
  573. end;
  574. function TSDLJoyStick.UpdateInput(Event: TSDL_EVENT): Boolean;
  575. begin
  576. Result := false;
  577. if ( FEnabled ) then
  578. begin
  579. case event.type_ of
  580. SDL_JOYAXISMOTION :
  581. begin
  582. DoAxisMove( Event );
  583. end;
  584. SDL_JOYBALLMOTION :
  585. begin
  586. DoBallMove( Event );
  587. end;
  588. SDL_JOYHATMOTION :
  589. begin
  590. DoHatMove( Event );
  591. end;
  592. SDL_JOYBUTTONDOWN :
  593. begin
  594. DoButtonDown( Event );
  595. end;
  596. SDL_JOYBUTTONUP :
  597. begin
  598. DoButtonUp( Event );
  599. end;
  600. end;
  601. end;
  602. end;
  603. end.