aboutsummaryrefslogtreecommitdiffstats
path: root/src/base/UJoystick.pas
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/UJoystick.pas')
-rw-r--r--src/base/UJoystick.pas312
1 files changed, 312 insertions, 0 deletions
diff --git a/src/base/UJoystick.pas b/src/base/UJoystick.pas
new file mode 100644
index 00000000..30808812
--- /dev/null
+++ b/src/base/UJoystick.pas
@@ -0,0 +1,312 @@
+{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *}
+
+unit UJoystick;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ SDL;
+
+type
+ TJoyButton = record
+ State: integer;
+ Enabled: boolean;
+ Type_: byte;
+ Sym: cardinal;
+ end;
+
+ TJoyHatState = record
+ State: Boolean;
+ LastTick: Cardinal;
+ Enabled: boolean;
+ Type_: byte;
+ Sym: cardinal;
+ end;
+
+ TJoyUnit = record
+ Button: array[0..15] of TJoyButton;
+ HatState: Array[0..3] of TJoyHatState;
+ end;
+
+ TJoy = class
+ constructor Create;
+ procedure Update;
+ end;
+
+var
+ Joy: TJoy;
+ JoyUnit: TJoyUnit;
+ SDL_Joy: PSDL_Joystick;
+ JoyEvent: TSDL_Event;
+
+implementation
+
+uses SysUtils,
+ ULog;
+
+constructor TJoy.Create;
+var
+ B: integer;
+ //N: integer;
+begin
+ inherited;
+
+ //Old Corvus5 Method
+ {// joystick support
+ SDL_JoystickEventState(SDL_IGNORE);
+ SDL_InitSubSystem(SDL_INIT_JOYSTICK);
+ if SDL_NumJoysticks <> 1 then
+ Log.LogStatus('Joystick count <> 1', 'TJoy.Create');
+
+ SDL_Joy := SDL_JoystickOpen(0);
+ if SDL_Joy = nil then
+ Log.LogError('SDL_JoystickOpen failed', 'TJoy.Create');
+
+ if SDL_JoystickNumButtons(SDL_Joy) <> 16 then
+ Log.LogStatus('Joystick button count <> 16', 'TJoy.Create');
+
+// SDL_JoystickEventState(SDL_ENABLE);
+ // Events don't work - thay hang the whole application with SDL_JoystickEventState(SDL_ENABLE)
+
+ // clear states
+ for B := 0 to 15 do
+ JoyUnit.Button[B].State := 1;
+
+ // mapping
+ JoyUnit.Button[1].Enabled := true;
+ JoyUnit.Button[1].Type_ := SDL_KEYDOWN;
+ JoyUnit.Button[1].Sym := SDLK_RETURN;
+ JoyUnit.Button[2].Enabled := true;
+ JoyUnit.Button[2].Type_ := SDL_KEYDOWN;
+ JoyUnit.Button[2].Sym := SDLK_ESCAPE;
+
+ JoyUnit.Button[12].Enabled := true;
+ JoyUnit.Button[12].Type_ := SDL_KEYDOWN;
+ JoyUnit.Button[12].Sym := SDLK_LEFT;
+ JoyUnit.Button[13].Enabled := true;
+ JoyUnit.Button[13].Type_ := SDL_KEYDOWN;
+ JoyUnit.Button[13].Sym := SDLK_DOWN;
+ JoyUnit.Button[14].Enabled := true;
+ JoyUnit.Button[14].Type_ := SDL_KEYDOWN;
+ JoyUnit.Button[14].Sym := SDLK_RIGHT;
+ JoyUnit.Button[15].Enabled := true;
+ JoyUnit.Button[15].Type_ := SDL_KEYDOWN;
+ JoyUnit.Button[15].Sym := SDLK_UP;
+ }
+ //New Sarutas method
+ SDL_JoystickEventState(SDL_IGNORE);
+ SDL_InitSubSystem(SDL_INIT_JOYSTICK);
+ if SDL_NumJoysticks < 1 then
+ begin
+ Log.LogError('No Joystick found');
+ exit;
+ end;
+
+
+ SDL_Joy := SDL_JoystickOpen(0);
+ if SDL_Joy = nil then
+ begin
+ Log.LogError('Could not Init Joystick');
+ exit;
+ end;
+ //N := SDL_JoystickNumButtons(SDL_Joy);
+ //if N < 6 then Log.LogStatus('Joystick button count < 6', 'TJoy.Create');
+
+ for B := 0 to 5 do begin
+ JoyUnit.Button[B].Enabled := true;
+ JoyUnit.Button[B].State := 1;
+ JoyUnit.Button[B].Type_ := SDL_KEYDOWN;
+ end;
+
+ JoyUnit.Button[0].Sym := SDLK_Return;
+ JoyUnit.Button[1].Sym := SDLK_Escape;
+ JoyUnit.Button[2].Sym := SDLK_M;
+ JoyUnit.Button[3].Sym := SDLK_R;
+
+ JoyUnit.Button[4].Sym := SDLK_RETURN;
+ JoyUnit.Button[5].Sym := SDLK_ESCAPE;
+
+ //Set HatState
+ for B := 0 to 3 do begin
+ JoyUnit.HatState[B].Enabled := true;
+ JoyUnit.HatState[B].State := False;
+ JoyUnit.HatState[B].Type_ := SDL_KEYDOWN;
+ end;
+
+ JoyUnit.HatState[0].Sym := SDLK_UP;
+ JoyUnit.HatState[1].Sym := SDLK_RIGHT;
+ JoyUnit.HatState[2].Sym := SDLK_DOWN;
+ JoyUnit.HatState[3].Sym := SDLK_LEFT;
+end;
+
+procedure TJoy.Update;
+var
+ B: integer;
+ State: UInt8;
+ Tick: Cardinal;
+ Axes: Smallint;
+begin
+ SDL_JoystickUpdate;
+
+ //Manage Buttons
+ for B := 0 to 15 do begin
+ if (JoyUnit.Button[B].Enabled) and (JoyUnit.Button[B].State <> SDL_JoystickGetButton(SDL_Joy, B)) and (JoyUnit.Button[B].State = 0) then begin
+ JoyEvent.type_ := JoyUnit.Button[B].Type_;
+ JoyEvent.key.keysym.sym := JoyUnit.Button[B].Sym;
+ SDL_PushEvent(@JoyEvent);
+ end;
+ end;
+
+
+ for B := 0 to 15 do begin
+ JoyUnit.Button[B].State := SDL_JoystickGetButton(SDL_Joy, B);
+ end;
+
+ //Get Tick
+ Tick := SDL_GetTicks();
+
+ //Get CoolieHat
+ if (SDL_JoystickNumHats(SDL_Joy)>=1) then
+ State := SDL_JoystickGetHat(SDL_Joy, 0)
+ else
+ State := 0;
+
+ //Get Axis
+ if (SDL_JoystickNumAxes(SDL_Joy)>=2) then
+ begin
+ //Down - Up (X- Axis)
+ Axes := SDL_JoystickGetAxis(SDL_Joy, 1);
+ If Axes >= 15000 then
+ State := State or SDL_HAT_Down
+ Else If Axes <= -15000 then
+ State := State or SDL_HAT_UP;
+
+ //Left - Right (Y- Axis)
+ Axes := SDL_JoystickGetAxis(SDL_Joy, 0);
+ If Axes >= 15000 then
+ State := State or SDL_HAT_Right
+ Else If Axes <= -15000 then
+ State := State or SDL_HAT_Left;
+ end;
+
+ //Manage Hat and joystick Events
+ if (SDL_JoystickNumHats(SDL_Joy)>=1) OR (SDL_JoystickNumAxes(SDL_Joy)>=2) then
+ begin
+
+ //Up Button
+ If (JoyUnit.HatState[0].Enabled) and ((SDL_HAT_UP AND State) = SDL_HAT_UP) then
+ begin //IF Button is newly Pressed or if he is Pressed longer than 500 msecs
+ if (JoyUnit.HatState[0].State = False) OR (JoyUnit.HatState[0].Lasttick < Tick) then
+ begin
+ //Set Tick and State
+ if JoyUnit.HatState[0].State then
+ JoyUnit.HatState[0].Lasttick := Tick + 200
+ else
+ JoyUnit.HatState[0].Lasttick := Tick + 500;
+
+ JoyUnit.HatState[0].State := True;
+
+ JoyEvent.type_ := JoyUnit.HatState[0].Type_;
+ JoyEvent.key.keysym.sym := JoyUnit.HatState[0].Sym;
+ SDL_PushEvent(@JoyEvent);
+ end;
+ end
+ else
+ JoyUnit.HatState[0].State := False;
+
+ //Right Button
+ If (JoyUnit.HatState[1].Enabled) and ((SDL_HAT_RIGHT AND State) = SDL_HAT_RIGHT) then
+ begin //IF Button is newly Pressed or if he is Pressed longer than 500 msecs
+ if (JoyUnit.HatState[1].State = False) OR (JoyUnit.HatState[1].Lasttick < Tick) then
+ begin
+ //Set Tick and State
+ if JoyUnit.HatState[1].State then
+ JoyUnit.HatState[1].Lasttick := Tick + 200
+ else
+ JoyUnit.HatState[1].Lasttick := Tick + 500;
+
+ JoyUnit.HatState[1].State := True;
+
+ JoyEvent.type_ := JoyUnit.HatState[1].Type_;
+ JoyEvent.key.keysym.sym := JoyUnit.HatState[1].Sym;
+ SDL_PushEvent(@JoyEvent);
+ end;
+ end
+ else
+ JoyUnit.HatState[1].State := False;
+
+ //Down button
+ If (JoyUnit.HatState[2].Enabled) and ((SDL_HAT_DOWN AND State) = SDL_HAT_DOWN) then
+ begin //IF Button is newly Pressed or if he is Pressed longer than 230 msecs
+ if (JoyUnit.HatState[2].State = False) OR (JoyUnit.HatState[2].Lasttick < Tick) then
+ begin
+ //Set Tick and State
+ if JoyUnit.HatState[2].State then
+ JoyUnit.HatState[2].Lasttick := Tick + 200
+ else
+ JoyUnit.HatState[2].Lasttick := Tick + 500;
+
+ JoyUnit.HatState[2].State := True;
+
+ JoyEvent.type_ := JoyUnit.HatState[2].Type_;
+ JoyEvent.key.keysym.sym := JoyUnit.HatState[2].Sym;
+ SDL_PushEvent(@JoyEvent);
+ end;
+ end
+ else
+ JoyUnit.HatState[2].State := False;
+
+ //Left Button
+ If (JoyUnit.HatState[3].Enabled) and ((SDL_HAT_LEFT AND State) = SDL_HAT_LEFT) then
+ begin //IF Button is newly Pressed or if he is Pressed longer than 230 msecs
+ if (JoyUnit.HatState[3].State = False) OR (JoyUnit.HatState[3].Lasttick < Tick) then
+ begin
+ //Set Tick and State
+ if JoyUnit.HatState[3].State then
+ JoyUnit.HatState[3].Lasttick := Tick + 200
+ else
+ JoyUnit.HatState[3].Lasttick := Tick + 500;
+
+ JoyUnit.HatState[3].State := True;
+
+ JoyEvent.type_ := JoyUnit.HatState[3].Type_;
+ JoyEvent.key.keysym.sym := JoyUnit.HatState[3].Sym;
+ SDL_PushEvent(@JoyEvent);
+ end;
+ end
+ else
+ JoyUnit.HatState[3].State := False;
+ end;
+
+end;
+
+end.