1 /*
2 DSFML - The Simple and Fast Multimedia Library for D
3 
4 Copyright (c) 2013 - 2015 Jeremy DeHaan (dehaan.jeremiah@gmail.com)
5 
6 This software is provided 'as-is', without any express or implied warranty.
7 In no event will the authors be held liable for any damages arising from the use of this software.
8 
9 Permission is granted to anyone to use this software for any purpose, including commercial applications,
10 and to alter it and redistribute it freely, subject to the following restrictions:
11 
12 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
13 If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
14 
15 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
16 
17 3. This notice may not be removed or altered from any source distribution
18 */
19 
20 ///A module containing the Joystick class.
21 module dsfml.window.joystick;
22 
23 /**
24  *Give access to the real-time state of the joysticks.
25  *
26  *Joystick provides an interface to the state of the joysticks.
27  *
28  *It only contains static functions, so it's not meant to be instanciated. Instead, each joystick is identified
29   *by an index that is passed to the functions of this class.
30  *
31  *This class allows users to query the state of joysticks at any time and directly, without having to deal with
32  *a window and its events. Compared to the JoystickMoved, JoystickButtonPressed and JoystickButtonReleased events, 
33  *Joystick can retrieve the state of axes and buttons of joysticks at any time (you don't need to store and update 
34  *a boolean on your side in order to know if a button is pressed or released), and you always get the real state of 
35  *joysticks, even if they are moved, pressed or released when your window is out of focus and no event is triggered.
36 */
37 final abstract class Joystick
38 {
39 	//Constants related to joysticks capabilities.
40 	enum
41 	{
42 		///Maximum number of supported joysticks.
43 		JoystickCount = 8,
44 		///Maximum number of supported buttons.
45 		JoystickButtonCount = 32,
46 		///Maximum number of supported axes.
47 		JoystickAxisCount = 8
48 	}
49 	
50 	///Axes supported by SFML joysticks.
51 	enum Axis
52 	{
53 		///The X axis.
54 		X,
55 		///The Y axis.
56 		Y,
57 		///The Z axis.
58 		Z,
59 		///The R axis.
60 		R,
61 		///The U axis.
62 		U,
63 		///The V axis.
64 		V,
65 		///The X axis of the point-of-view hat.
66 		PovX,
67 		///The Y axis of the point-of-view hat.
68 		PovY
69 	}
70 
71 	///Return the number of buttons supported by a joystick.
72 	///
73 	///If the joystick is not connected, this function returns 0.
74 	///
75 	//////Params:
76 	///		joystick = Index of the joystick.
77 	///
78 	///Returns: Number of buttons supported by the joystick.
79 	static uint getButtonCount(uint joystick)
80 	{
81 		return sfJoystick_getButtonCount(joystick);
82 	}
83 	
84 	///Get the current position of a joystick axis.
85 	///
86 	///If the joystick is not connected, this function returns 0.
87 	///
88 	///Params:
89 	///		joystick = 	Index of the joystick.
90 	///		axis = Axis to check.
91 	///
92 	///Returns: Current position of the axis, in range [-100 .. 100].
93 	static float getAxisPosition(uint joystick, Axis axis)
94 	{
95 		return sfJoystick_getAxisPosition(joystick, axis);
96 	}
97 	
98 	///Check if a joystick supports a given axis.
99 	///
100 	///If the joystick is not connected, this function returns false.
101 	///
102 	///Params:
103 	///		joystick = 	Index of the joystick.
104 	///		axis = Axis to check.
105 	///
106 	///Returns: True if the joystick supports the axis, false otherwise.
107 	static bool hasAxis(uint joystick, Axis axis)
108 	{
109 		return (sfJoystick_hasAxis(joystick, axis));
110 	}
111 	
112 	///Check if a joystick button is pressed.
113 	///
114 	///If the joystick is not connected, this function returns false.
115 	///
116 	///Params:
117 	///		joystick = 	Index of the joystick.
118 	///		button = Button to check.
119 	///
120 	///Returns: True if the button is pressed, false otherwise.
121 	static bool isButtonPressed(uint joystick, uint button)
122 	{
123 		return sfJoystick_isButtonPressed(joystick, button);
124 	}
125 
126 	///Check if a joystick is connected.
127 	///
128 	///Params:
129 	///		joystick = 	Index of the joystick.
130 	///
131 	///Returns: True if the joystick is connected, false otherwise.
132 	static bool isConnected(uint joystick)
133 	{
134 		return (sfJoystick_isConnected(joystick));
135 	}
136 
137 	///Update the states of all joysticks.
138 	///
139 	///This function is used internally by SFML, so you normally don't have to call it explicitely.
140 	///However, you may need to call it if you have no window yet (or no window at all): in this case the joysticks states are not updated automatically.
141 	static void update()
142 	{
143 		sfJoystick_update();
144 	}
145 	
146 }
147 
148 unittest
149 {
150 	version(DSFML_Unittest_Window)
151 	{
152 
153 		import std.stdio;
154 	
155 		Joystick.update();
156 	
157 		bool[] joysticks = [false,false,false,false,false,false,false,false]; 
158 	
159 		for(uint i; i < Joystick.JoystickCount; ++i)
160 		{
161 			if(Joystick.isConnected(i))
162 			{
163 				joysticks[i] = true;
164 				writeln("Joystick number ",i," is connected!");
165 			}
166 		}
167 	
168 		foreach(uint i,bool joystick;joysticks)
169 		{
170 			if(joystick)
171 			{
172 				//Check buttons
173 				uint buttonCounts = Joystick.getButtonCount(i);
174 			
175 				for(uint j = 0; j<buttonCounts; ++j)
176 				{
177 					if(Joystick.isButtonPressed(i,j))
178 					{
179 						writeln("Button ", j, " was pressed on joystick ", i);
180 					}
181 				}
182 			
183 				//check axis
184 				for(int j = 0; j<Joystick.JoystickAxisCount;++j)
185 				{
186 					Joystick.Axis axis = cast(Joystick.Axis)j;
187 					
188 					if(Joystick.hasAxis(i,axis))
189 					{
190 						writeln("Axis ", axis, " has a position of ", Joystick.getAxisPosition(i,axis), "for joystick", i);
191 					
192 					
193 					}
194 				}
195 			
196 			}
197 		}
198 	}
199 }
200 
201 private extern(C):
202 //Check if a joystick is connected
203 bool sfJoystick_isConnected(uint joystick);
204 
205 //Return the number of buttons supported by a joystick
206 uint sfJoystick_getButtonCount(uint joystick);
207 
208 //Check if a joystick supports a given axis
209 bool sfJoystick_hasAxis(uint joystick, int axis);
210 
211 //Check if a joystick button is pressed
212 bool sfJoystick_isButtonPressed(uint joystick, uint button);
213 
214 //Get the current position of a joystick axis
215 float sfJoystick_getAxisPosition(uint joystick, int axis);
216 
217 //Update the states of all joysticks
218 void sfJoystick_update();
219 
220