Merged all the joystick fixes from trunk

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1343 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
LaurentGom 2010-01-11 09:04:59 +00:00
commit 7b83fbc544
13 changed files with 220 additions and 123 deletions

View File

@ -162,7 +162,7 @@ namespace Mouse
XButton1, ///< The first extra mouse button
XButton2, ///< The second extra mouse button
Count ///< Keep last -- the total number of mouse buttons
ButtonCount ///< Keep last -- the total number of mouse buttons
};
}
@ -183,7 +183,13 @@ namespace Joy
AxisV, ///< The V axis
AxisPOV, ///< The Point-Of-View axis (hat)
Count ///< Keep last -- the total number of joystick axis
AxisCount // Keep last -- total number of joystick axis
};
enum
{
Count = 4, ///< Total number of supported joysticks
ButtonCount = 32 ///< Total number of supported joystick buttons
};
}

View File

@ -128,15 +128,21 @@ private :
////////////////////////////////////////////////////////////
virtual void OnEvent(const Event& event);
////////////////////////////////////////////////////////////
/// Reset all the states
///
////////////////////////////////////////////////////////////
void ResetStates();
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
bool myKeys[Key::Count]; ///< Array containing the state of all keyboard keys
bool myMouseButtons[Mouse::Count]; ///< Array containing the state of all mouse buttons
bool myJoystickButtons[2][32]; ///< Array containing the state of all joysticks buttons
int myMouseX; ///< Mouse position on X
int myMouseY; ///< Mouse position on Y
float myJoystickAxis[2][Joy::Count]; ///< Joysticks position on each axis
bool myKeys[Key::Count]; ///< Array containing the state of all keyboard keys
bool myMouseButtons[Mouse::ButtonCount]; ///< Array containing the state of all mouse buttons
int myMouseX; ///< Mouse position on X
int myMouseY; ///< Mouse position on Y
bool myJoystickButtons[Joy::Count][Joy::ButtonCount]; ///< Array containing the state of all joysticks buttons
float myJoystickAxis[Joy::Count][Joy::AxisCount]; ///< Joysticks position on each axis
};
} // namespace sf

View File

@ -151,7 +151,9 @@ PySfWindow_init(PySfWindow *self, PyObject *args, PyObject *kwds)
PySfContextSettings *Params;
if (args != NULL)
{
{
if (PyTuple_Size(args) == 0)
return 0;
if (PyArg_ParseTuple(args, "l|O!:Window.__new__", &Handle, &PySfContextSettingsType, &Params))
return 0;
PyErr_Clear();

View File

@ -55,12 +55,11 @@ JoystickState Joystick::UpdateState()
////////////////////////////////////////////////////////////
/// Get the number of axes supported by the joystick
/// Check if the joystick supports the given axis
////////////////////////////////////////////////////////////
unsigned int Joystick::GetAxesCount() const
bool Joystick::HasAxis(Joy::Axis Axis) const
{
// Return number of supported axes
return 0;
return false;
}

View File

@ -58,13 +58,15 @@ public :
JoystickState UpdateState();
////////////////////////////////////////////////////////////
/// Get the number of axes supported by the joystick
/// Check if the joystick supports the given axis
///
/// \return Number of axis
/// \param Axis : Axis to check
///
/// \return True of the axis is supported, false otherwise
///
////////////////////////////////////////////////////////////
unsigned int GetAxesCount() const;
bool HasAxis(Joy::Axis Axis) const;
////////////////////////////////////////////////////////////
/// Get the number of buttons supported by the joystick
///

View File

@ -35,23 +35,7 @@ Input::Input() :
myMouseX(0),
myMouseY(0)
{
for (int i = 0; i < Key::Count; ++i)
myKeys[i] = false;
for (int i = 0; i < Mouse::Count; ++i)
myMouseButtons[i] = false;
for (int i = 0; i < 32; ++i)
{
myJoystickButtons[0][i] = false;
myJoystickButtons[1][i] = false;
}
for (int i = 0; i < Joy::Count; ++i)
{
myJoystickAxis[0][i] = 0.f;
myJoystickAxis[1][i] = 0.f;
}
ResetStates();
}
@ -72,7 +56,7 @@ bool Input::IsMouseButtonDown(Mouse::Button button) const
////////////////////////////////////////////////////////////
bool Input::IsJoystickButtonDown(unsigned int joystick, unsigned int button) const
{
if ((joystick < 4) && (button < 32))
if ((joystick < Joy::Count) && (button < Joy::ButtonCount))
return myJoystickButtons[joystick][button];
else
return false;
@ -96,7 +80,10 @@ int Input::GetMouseY() const
////////////////////////////////////////////////////////////
float Input::GetJoystickAxis(unsigned int joystick, Joy::Axis axis) const
{
return myJoystickAxis[joystick][axis];
if (joystick < Joy::Count)
return myJoystickAxis[joystick][axis];
else
return 0.f;
}
@ -130,24 +117,33 @@ void Input::OnEvent(const Event& event)
// Lost focus event : we must reset all persistent states
case Event::LostFocus :
{
for (int i = 0; i < Key::Count; ++i)
myKeys[i] = false;
for (int i = 0; i < Mouse::Count; ++i)
myMouseButtons[i] = false;
for (int i = 0; i < 32; ++i)
{
myJoystickButtons[0][i] = false;
myJoystickButtons[1][i] = false;
}
ResetStates();
break;
}
default :
break;
}
}
////////////////////////////////////////////////////////////
void Input::ResetStates()
{
for (int i = 0; i < Key::Count; ++i)
myKeys[i] = false;
for (int i = 0; i < Mouse::ButtonCount; ++i)
myMouseButtons[i] = false;
for (int i = 0; i < Joy::Count; ++i)
{
for (int j = 0; j < Joy::ButtonCount; ++j)
myJoystickButtons[i][j] = false;
for (int j = 0; j < Joy::AxisCount; ++j)
myJoystickAxis[i][j] = 0.f;
myJoystickAxis[i][Joy::AxisPOV] = -1.f;
}
}
} // namespace sf

View File

@ -42,10 +42,20 @@ namespace priv
////////////////////////////////////////////////////////////
struct JoystickState
{
enum {MaxButtons = 32};
JoystickState()
{
// Default value for axes
for (int i = 0; i < Joy::AxisCount; ++i)
Axis[i] = 0.f;
Axis[Joy::AxisPOV] = -1.f;
float Axis[Joy::Count]; ///< Position on each axis in range [-100, 100] (except POV which is [0, 360])
bool Buttons[MaxButtons]; ///< Status of each button (true = pressed)
// Default value for buttons
for (int i = 0; i < Joy::ButtonCount; ++i)
Buttons[i] = false;
}
float Axis[Joy::AxisCount]; ///< Position on each axis in range [-100, 100] (except POV which is [0, 360])
bool Buttons[Joy::ButtonCount]; ///< Status of each button (true = pressed)
};
} // namespace priv

View File

@ -28,13 +28,6 @@
#include <SFML/Window/Joystick.hpp>
#include <sstream>
#if defined(SFML_SYSTEM_LINUX)
#include <linux/joystick.h>
#include <fcntl.h>
#elif defined(SFML_SYSTEM_FREEBSD)
// #include <sys/joystick.h> ?
#endif
namespace sf
{
@ -46,12 +39,18 @@ namespace priv
void Joystick::Initialize(unsigned int index)
{
// Initial state
myNbAxes = 0;
myNbButtons = 0;
for (int i = 0; i < Joy::Count; ++i)
myState.Axis[i] = 0.f;
for (int i = 0; i < JoystickState::MaxButtons; ++i)
myPovX = 0;
myPovY = 0;
for (int i = 0; i < Joy::ButtonCount; ++i)
{
myState.Buttons[i] = false;
}
for (int i = 0; i < Joy::AxisCount; ++i)
{
myState.Axis[i] = 0.f;
myAxes[i] = false;
}
// Open the joystick handle
std::ostringstream oss;
@ -61,13 +60,32 @@ void Joystick::Initialize(unsigned int index)
{
// Use non-blocking mode
fcntl(myDescriptor, F_SETFL, O_NONBLOCK);
// Get number of axes and buttons
char nbAxes, nbButtons;
ioctl(myDescriptor, JSIOCGAXES, &nbAxes);
// Get number of buttons
char nbButtons;
ioctl(myDescriptor, JSIOCGBUTTONS, &nbButtons);
myNbAxes = nbAxes;
myNbButtons = nbButtons;
if (myNbButtons > Joy::ButtonCount)
myNbButtons = Joy::ButtonCount;
// Get the supported axes
char nbAxes;
ioctl(myDescriptor, JSIOCGAXES, &nbAxes);
ioctl(myDescriptor, JSIOCGAXMAP, myAxesMapping);
for (int i = 0; i < nbAxes; ++i)
{
switch (myAxesMapping[i])
{
case ABS_X : myAxes[Joy::AxisX] = true; break;
case ABS_Y : myAxes[Joy::AxisY] = true; break;
case ABS_Z : case ABS_THROTTLE : myAxes[Joy::AxisZ] = true; break;
case ABS_RZ: case ABS_RUDDER: myAxes[Joy::AxisR] = true; break;
case ABS_RX : myAxes[Joy::AxisU] = true; break;
case ABS_RY : myAxes[Joy::AxisV] = true; break;
case ABS_HAT0X : case ABS_HAT0Y : myAxes[Joy::AxisPOV] = true; break;
default : break;
}
}
}
}
@ -85,11 +103,42 @@ JoystickState Joystick::UpdateState()
// An axis has been moved
case JS_EVENT_AXIS :
{
if (joyState.number < Joy::Count)
myState.Axis[joyState.number] = joyState.value * 100.f / 32767.f;
switch (myAxesMapping[joyState.number])
{
case ABS_X : myState.Axis[Joy::AxisX] = joyState.value * 100.f / 32767.f; break;
case ABS_Y : myState.Axis[Joy::AxisY] = joyState.value * 100.f / 32767.f; break;
case ABS_Z : case ABS_THROTTLE : myState.Axis[Joy::AxisZ] = joyState.value * 100.f / 32767.f; break;
case ABS_RZ: case ABS_RUDDER: myState.Axis[Joy::AxisR] = joyState.value * 100.f / 32767.f; break;
case ABS_RX : myState.Axis[Joy::AxisU] = joyState.value * 100.f / 32767.f; break;
case ABS_RY : myState.Axis[Joy::AxisV] = joyState.value * 100.f / 32767.f; break;
case ABS_HAT0X : myPovX = joyState.value; break;
case ABS_HAT0Y : myPovY = joyState.value; break;
default : break;
}
// Compute the new POV angle
if (myPovX > 0)
{
if (myPovY > 0) myState.Axis[Joy::AxisPOV] = 135.f;
else if (myPovY < 0) myState.Axis[Joy::AxisPOV] = 45.f;
else myState.Axis[Joy::AxisPOV] = 90.f;
}
else if (myPovX < 0)
{
if (myPovY > 0) myState.Axis[Joy::AxisPOV] = 225.f;
else if (myPovY < 0) myState.Axis[Joy::AxisPOV] = 315.f;
else myState.Axis[Joy::AxisPOV] = 270.f;
}
else
{
if (myPovY > 0) myState.Axis[Joy::AxisPOV] = 180.f;
else if (myPovY < 0) myState.Axis[Joy::AxisPOV] = 0.f;
else myState.Axis[Joy::AxisPOV] = -1.f;
}
break;
}
// A button has been pressed
case JS_EVENT_BUTTON :
{
@ -106,9 +155,9 @@ JoystickState Joystick::UpdateState()
////////////////////////////////////////////////////////////
unsigned int Joystick::GetAxesCount() const
bool Joystick::HasAxis(Joy::Axis Axis) const
{
return myNbAxes;
return myAxes[Axis];
}
@ -136,9 +185,9 @@ JoystickState Joystick::UpdateState()
////////////////////////////////////////////////////////////
unsigned int Joystick::GetAxesCount() const
bool Joystick::HasAxis(Joy::Axis Axis) const
{
return 0;
return false;
}

View File

@ -28,6 +28,12 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#if defined(SFML_SYSTEM_LINUX)
#include <linux/joystick.h>
#include <fcntl.h>
#elif defined(SFML_SYSTEM_FREEBSD)
// #include <sys/joystick.h> ?
#endif
namespace sf
@ -59,12 +65,14 @@ public :
JoystickState UpdateState();
////////////////////////////////////////////////////////////
/// \brief Get the number of axes supported by the joystick
/// \brief Check if the joystick supports the given axis
///
/// \return Number of axis
/// \param axis Axis to check
///
/// \return True of the axis is supported, false otherwise
///
////////////////////////////////////////////////////////////
unsigned int GetAxesCount() const;
bool HasAxis(Joy::Axis Axis) const;
////////////////////////////////////////////////////////////
/// \brief Get the number of buttons supported by the joystick
@ -79,10 +87,13 @@ private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
int myDescriptor; ///< Linux descriptor of the joystick
unsigned int myNbAxes; ///< Number of axis supported by the joystick
unsigned int myNbButtons; ///< Number of buttons supported by the joystick
JoystickState myState; ///< Current state of the joystick
int myDescriptor; ///< Linux descriptor of the joystick
unsigned int myNbButtons; ///< Number of buttons supported by the joystick
bool myAxes[Joy::AxisCount]; ///< Supported axes
JoystickState myState; ///< Current state of the joystick
int myPovX; ///< Last X position of the POV
int myPovY; ///< Last Y position of the POV
char myAxesMapping[ABS_MAX + 1]; ///< Axes mapping (index --> axis id)
};
} // namespace priv

View File

@ -40,10 +40,12 @@ namespace priv
void Joystick::Initialize(unsigned int index)
{
// Reset state
myIndex = JOYSTICKID1;
myNbAxes = 0;
myNbButtons = 0;
myIsConnected = false;
myIndex = JOYSTICKID1;
myNbButtons = 0;
myIsConnected = false;
myHasContinuousPOV = false;
for (int i = 0; i < Joy::AxisCount; ++i)
myAxes[i] = false;
// Get the Index-th connected joystick
MMRESULT error;
@ -62,10 +64,18 @@ void Joystick::Initialize(unsigned int index)
myIsConnected = true;
JOYCAPS caps;
joyGetDevCaps(myIndex, &caps, sizeof(caps));
myNbAxes = caps.wNumAxes;
myNbButtons = caps.wNumButtons;
if (myNbButtons > JoystickState::MaxButtons)
myNbButtons = JoystickState::MaxButtons;
if (myNbButtons > Joy::ButtonCount)
myNbButtons = Joy::ButtonCount;
myAxes[Joy::AxisX] = true;
myAxes[Joy::AxisY] = true;
myAxes[Joy::AxisZ] = (caps.wCaps & JOYCAPS_HASZ) != 0;
myAxes[Joy::AxisR] = (caps.wCaps & JOYCAPS_HASR) != 0;
myAxes[Joy::AxisU] = (caps.wCaps & JOYCAPS_HASU) != 0;
myAxes[Joy::AxisV] = (caps.wCaps & JOYCAPS_HASV) != 0;
myAxes[Joy::AxisPOV] = (caps.wCaps & JOYCAPS_HASPOV) != 0;
myHasContinuousPOV = (caps.wCaps & JOYCAPS_POVCTS) != 0;
return;
}
@ -80,7 +90,7 @@ void Joystick::Initialize(unsigned int index)
////////////////////////////////////////////////////////////
JoystickState Joystick::UpdateState()
{
JoystickState state = {0};
JoystickState state;
if (myIsConnected)
{
@ -90,8 +100,9 @@ JoystickState Joystick::UpdateState()
{
// Get the current joystick state
JOYINFOEX pos;
pos.dwFlags = JOY_RETURNALL;
pos.dwSize = sizeof(JOYINFOEX);
pos.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | JOY_RETURNR | JOY_RETURNU | JOY_RETURNV | JOY_RETURNBUTTONS;
pos.dwFlags |= myHasContinuousPOV ? JOY_RETURNPOVCTS : JOY_RETURNPOV;
pos.dwSize = sizeof(JOYINFOEX);
if (joyGetPosEx(myIndex, &pos) == JOYERR_NOERROR)
{
// Axes
@ -103,7 +114,10 @@ JoystickState Joystick::UpdateState()
state.Axis[Joy::AxisV] = (pos.dwVpos - (caps.wVmax + caps.wVmin) / 2.f) * 200.f / (caps.wVmax - caps.wVmin);
// POV
state.Axis[Joy::AxisPOV] = pos.dwPOV / 100.f;
if (pos.dwPOV != 0xFFFF)
state.Axis[Joy::AxisPOV] = pos.dwPOV / 100.f;
else
state.Axis[Joy::AxisPOV] = -1.f;
// Buttons
for (unsigned int i = 0; i < GetButtonsCount(); ++i)
@ -117,9 +131,9 @@ JoystickState Joystick::UpdateState()
////////////////////////////////////////////////////////////
unsigned int Joystick::GetAxesCount() const
bool Joystick::HasAxis(Joy::Axis Axis) const
{
return myNbAxes;
return myAxes[Axis];
}

View File

@ -59,12 +59,14 @@ public :
JoystickState UpdateState();
////////////////////////////////////////////////////////////
/// \brief Get the number of axes supported by the joystick
/// \brief Check if the joystick supports the given axis
///
/// \return Number of axis
/// \param Axis : Axis to check
///
/// \return True of the axis is supported, false otherwise
///
////////////////////////////////////////////////////////////
unsigned int GetAxesCount() const;
bool HasAxis(Joy::Axis Axis) const;
////////////////////////////////////////////////////////////
/// \brief Get the number of buttons supported by the joystick
@ -79,10 +81,11 @@ private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
bool myIsConnected; ///< Is there a joystick connected?
unsigned int myIndex; ///< Windows ID of the joystick
unsigned int myNbAxes; ///< Number of axis supported by the joystick
unsigned int myNbButtons; ///< Number of buttons supported by the joystick
bool myIsConnected; ///< Is there a joystick connected?
unsigned int myIndex; ///< Windows ID of the joystick
unsigned int myNbButtons; ///< Number of buttons supported by the joystick
bool myAxes[Joy::AxisCount]; ///< Supported axes
bool myHasContinuousPOV; ///< True if the driver supports continuous values for the POV
};
} // namespace priv

View File

@ -74,7 +74,7 @@ myHeight (0),
myJoyThreshold(0.1f)
{
// Initialize the joysticks
for (unsigned int i = 0; i < JoysticksCount; ++i)
for (unsigned int i = 0; i < Joy::Count; ++i)
{
myJoysticks[i].Initialize(i);
myJoyStates[i] = myJoysticks[i].UpdateState();
@ -149,25 +149,29 @@ void WindowImpl::SendEvent(const Event& event)
////////////////////////////////////////////////////////////
void WindowImpl::ProcessJoystickEvents()
{
for (unsigned int i = 0; i < JoysticksCount; ++i)
for (unsigned int i = 0; i < Joy::Count; ++i)
{
// Copy the previous state of the joystick and get the new one
JoystickState previousState = myJoyStates[i];
myJoyStates[i] = myJoysticks[i].UpdateState();
// Axis
for (unsigned int j = 0; j < myJoysticks[i].GetAxesCount(); ++j)
for (unsigned int j = 0; j < Joy::AxisCount; ++j)
{
float prevPos = previousState.Axis[j];
float currPos = myJoyStates[i].Axis[j];
if (fabs(currPos - prevPos) >= myJoyThreshold)
Joy::Axis axis = static_cast<Joy::Axis>(j);
if (myJoysticks[i].HasAxis(axis))
{
Event event;
event.Type = Event::JoyMoved;
event.JoyMove.JoystickId = i;
event.JoyMove.Axis = static_cast<Joy::Axis>(j);
event.JoyMove.Position = currPos;
SendEvent(event);
float prevPos = previousState.Axis[axis];
float currPos = myJoyStates[i].Axis[axis];
if (fabs(currPos - prevPos) >= myJoyThreshold)
{
Event event;
event.Type = Event::JoyMoved;
event.JoyMove.JoystickId = i;
event.JoyMove.Axis = axis;
event.JoyMove.Position = currPos;
SendEvent(event);
}
}
}

View File

@ -238,18 +238,13 @@ private :
////////////////////////////////////////////////////////////
virtual void ProcessEvents(bool block) = 0;
////////////////////////////////////////////////////////////
// Total number of joysticks supported
////////////////////////////////////////////////////////////
enum {JoysticksCount = 2};
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
std::set<WindowListener*> myListeners; ///< Array of listeners connected to the window
Joystick myJoysticks[JoysticksCount]; ///< Joysticks to observe
JoystickState myJoyStates[JoysticksCount]; ///< Current states of the joysticks
float myJoyThreshold; ///< Joystick threshold (minimum motion for MOVE event to be generated)
std::set<WindowListener*> myListeners; ///< Array of listeners connected to the window
Joystick myJoysticks[Joy::Count]; ///< Joysticks to observe
JoystickState myJoyStates[Joy::Count]; ///< Current states of the joysticks
float myJoyThreshold; ///< Joystick threshold (minimum motion for MOVE event to be generated)
};
} // namespace priv