Back to index

libsfml  1.6+dfsg2
Joystick.cpp
Go to the documentation of this file.
00001 
00002 //
00003 // SFML - Simple and Fast Multimedia Library
00004 // Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
00005 //
00006 // This software is provided 'as-is', without any express or implied warranty.
00007 // In no event will the authors be held liable for any damages arising from the use of this software.
00008 //
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it freely,
00011 // subject to the following restrictions:
00012 //
00013 // 1. The origin of this software must not be misrepresented;
00014 //    you must not claim that you wrote the original software.
00015 //    If you use this software in a product, an acknowledgment
00016 //    in the product documentation would be appreciated but is not required.
00017 //
00018 // 2. Altered source versions must be plainly marked as such,
00019 //    and must not be misrepresented as being the original software.
00020 //
00021 // 3. This notice may not be removed or altered from any source distribution.
00022 //
00024 
00026 // Headers
00028 #include <SFML/Window/Joystick.hpp>
00029 #include <sstream>
00030 
00031 
00032 namespace sf
00033 {
00034 namespace priv
00035 {
00036 #if defined(SFML_SYSTEM_LINUX)
00037 
00041 void Joystick::Initialize(unsigned int Index)
00042 {
00043     // Initial state
00044     myNbButtons = 0;
00045     myPovX = 0;
00046     myPovY = 0;
00047     for (int i = 0; i < Joy::ButtonCount; ++i)
00048     {
00049         myState.Buttons[i] = false;
00050     }
00051     for (int i = 0; i < Joy::AxisCount; ++i)
00052     {
00053         myState.Axis[i] = 0.f;
00054         myAxes[i] = false;
00055     }
00056 
00057     // Open the joystick handle
00058     std::ostringstream oss;
00059     oss << "/dev/input/js" << Index;
00060     myDescriptor = open(oss.str().c_str(), O_RDONLY);
00061     if (myDescriptor > 0)
00062     {
00063         // Use non-blocking mode
00064         fcntl(myDescriptor, F_SETFL, O_NONBLOCK);
00065 
00066         // Get number of buttons
00067         char NbButtons;
00068         ioctl(myDescriptor, JSIOCGBUTTONS, &NbButtons);
00069         myNbButtons = NbButtons;
00070         if (myNbButtons > Joy::ButtonCount)
00071             myNbButtons = Joy::ButtonCount;
00072 
00073         // Get the supported axes
00074         char NbAxes;
00075         ioctl(myDescriptor, JSIOCGAXES, &NbAxes);
00076         ioctl(myDescriptor, JSIOCGAXMAP, myAxesMapping);
00077         for (int i = 0; i < NbAxes; ++i)
00078         {
00079             switch (myAxesMapping[i])
00080             {
00081                 case ABS_X :                      myAxes[Joy::AxisX]   = true; break;
00082                 case ABS_Y :                      myAxes[Joy::AxisY]   = true; break;
00083                 case ABS_Z : case ABS_THROTTLE :  myAxes[Joy::AxisZ]   = true; break;
00084                 case ABS_RZ: case ABS_RUDDER:     myAxes[Joy::AxisR]   = true; break;
00085                 case ABS_RX :                     myAxes[Joy::AxisU]   = true; break;
00086                 case ABS_RY :                     myAxes[Joy::AxisV]   = true; break;
00087                 case ABS_HAT0X : case ABS_HAT0Y : myAxes[Joy::AxisPOV] = true; break;
00088                 default : break;
00089             }
00090         }
00091     }
00092 }
00093 
00094 
00098 JoystickState Joystick::UpdateState()
00099 {
00100     if (myDescriptor > 0)
00101     {
00102         js_event JoyState;
00103         while (read(myDescriptor, &JoyState, sizeof(JoyState)) > 0)
00104         {
00105             switch (JoyState.type & ~JS_EVENT_INIT)
00106             {
00107                 // An axis has been moved
00108                 case JS_EVENT_AXIS :
00109                 {
00110                     switch (myAxesMapping[JoyState.number])
00111                     {
00112                         case ABS_X :                      myState.Axis[Joy::AxisX] = JoyState.value * 100.f / 32767.f; break;
00113                         case ABS_Y :                      myState.Axis[Joy::AxisY] = JoyState.value * 100.f / 32767.f; break;
00114                         case ABS_Z : case ABS_THROTTLE :  myState.Axis[Joy::AxisZ] = JoyState.value * 100.f / 32767.f; break;
00115                         case ABS_RZ: case ABS_RUDDER:     myState.Axis[Joy::AxisR] = JoyState.value * 100.f / 32767.f; break;
00116                         case ABS_RX :                     myState.Axis[Joy::AxisU] = JoyState.value * 100.f / 32767.f; break;
00117                         case ABS_RY :                     myState.Axis[Joy::AxisV] = JoyState.value * 100.f / 32767.f; break;
00118                         case ABS_HAT0X :                  myPovX = JoyState.value;                                     break;
00119                         case ABS_HAT0Y :                  myPovY = JoyState.value;                                     break;
00120                         default : break;
00121                     }
00122 
00123                     // Compute the new POV angle
00124                     if (myPovX > 0)
00125                     {
00126                         if      (myPovY > 0) myState.Axis[Joy::AxisPOV] = 135.f;
00127                         else if (myPovY < 0) myState.Axis[Joy::AxisPOV] = 45.f;
00128                         else                 myState.Axis[Joy::AxisPOV] = 90.f;
00129                     }
00130                     else if (myPovX < 0)
00131                     {
00132                         if      (myPovY > 0) myState.Axis[Joy::AxisPOV] = 225.f;
00133                         else if (myPovY < 0) myState.Axis[Joy::AxisPOV] = 315.f;
00134                         else                 myState.Axis[Joy::AxisPOV] = 270.f;
00135                     }
00136                     else
00137                     {
00138                         if      (myPovY > 0) myState.Axis[Joy::AxisPOV] = 180.f;
00139                         else if (myPovY < 0) myState.Axis[Joy::AxisPOV] = 0.f;
00140                         else                 myState.Axis[Joy::AxisPOV] = -1.f;
00141                     }
00142                     break;
00143                 }
00144 
00145                 // A button has been pressed
00146                 case JS_EVENT_BUTTON :
00147                 {
00148                     if (JoyState.number < GetButtonsCount())
00149                         myState.Buttons[JoyState.number] = (JoyState.value != 0);
00150                     break;
00151                 }
00152             }
00153         }
00154     }
00155 
00156     return myState;
00157 }
00158 
00159 
00163 bool Joystick::HasAxis(Joy::Axis Axis) const
00164 {
00165     return myAxes[Axis];
00166 }
00167 
00168 
00172 unsigned int Joystick::GetButtonsCount() const
00173 {
00174     return myNbButtons;
00175 }
00176 
00177 
00178 #elif defined(SFML_SYSTEM_FREEBSD)
00179 
00180 
00184 void Joystick::Initialize(unsigned int Index)
00185 {
00186 }
00187 
00188 
00192 JoystickState Joystick::UpdateState()
00193 {
00194     return JoystickState();
00195 }
00196 
00197 
00201 bool Joystick::HasAxis(Joy::Axis Axis) const
00202 {
00203     return false;
00204 }
00205 
00206 
00210 unsigned int Joystick::GetButtonsCount() const
00211 {
00212     return 0;
00213 }
00214 
00215 #endif // defined(SFML_SYSTEM_FREEBSD)
00216 
00217 } // namespace priv
00218 
00219 } // namespace sf