diff --git a/include/SFML/Window/Event.hpp b/include/SFML/Window/Event.hpp index f241b282a..47748789d 100644 --- a/include/SFML/Window/Event.hpp +++ b/include/SFML/Window/Event.hpp @@ -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 }; } diff --git a/include/SFML/Window/Input.hpp b/include/SFML/Window/Input.hpp index 1e8f5c6ce..246aa7b8c 100644 --- a/include/SFML/Window/Input.hpp +++ b/include/SFML/Window/Input.hpp @@ -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 diff --git a/python/src/Window.cpp b/python/src/Window.cpp index 221f382e4..542b86681 100644 --- a/python/src/Window.cpp +++ b/python/src/Window.cpp @@ -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(); diff --git a/src/SFML/Window/Cocoa/Joystick.cpp b/src/SFML/Window/Cocoa/Joystick.cpp index 4ade09c4d..ff2a353aa 100644 --- a/src/SFML/Window/Cocoa/Joystick.cpp +++ b/src/SFML/Window/Cocoa/Joystick.cpp @@ -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; } diff --git a/src/SFML/Window/Cocoa/Joystick.hpp b/src/SFML/Window/Cocoa/Joystick.hpp index 425907517..60c5db243 100644 --- a/src/SFML/Window/Cocoa/Joystick.hpp +++ b/src/SFML/Window/Cocoa/Joystick.hpp @@ -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 /// diff --git a/src/SFML/Window/Input.cpp b/src/SFML/Window/Input.cpp index 6e1e02b98..289ec7060 100644 --- a/src/SFML/Window/Input.cpp +++ b/src/SFML/Window/Input.cpp @@ -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 diff --git a/src/SFML/Window/Joystick.hpp b/src/SFML/Window/Joystick.hpp index 135bae6ef..5a54a283f 100644 --- a/src/SFML/Window/Joystick.hpp +++ b/src/SFML/Window/Joystick.hpp @@ -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 diff --git a/src/SFML/Window/Linux/Joystick.cpp b/src/SFML/Window/Linux/Joystick.cpp index 77ae4bcf7..2ad46b49c 100644 --- a/src/SFML/Window/Linux/Joystick.cpp +++ b/src/SFML/Window/Linux/Joystick.cpp @@ -28,13 +28,6 @@ #include #include -#if defined(SFML_SYSTEM_LINUX) - #include - #include -#elif defined(SFML_SYSTEM_FREEBSD) - // #include ? -#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; } diff --git a/src/SFML/Window/Linux/Joystick.hpp b/src/SFML/Window/Linux/Joystick.hpp index b444ecdb3..17acfbaf7 100644 --- a/src/SFML/Window/Linux/Joystick.hpp +++ b/src/SFML/Window/Linux/Joystick.hpp @@ -28,6 +28,12 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// +#if defined(SFML_SYSTEM_LINUX) + #include + #include +#elif defined(SFML_SYSTEM_FREEBSD) + // #include ? +#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 diff --git a/src/SFML/Window/Win32/Joystick.cpp b/src/SFML/Window/Win32/Joystick.cpp index ed4b9bbef..e14552f75 100644 --- a/src/SFML/Window/Win32/Joystick.cpp +++ b/src/SFML/Window/Win32/Joystick.cpp @@ -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]; } diff --git a/src/SFML/Window/Win32/Joystick.hpp b/src/SFML/Window/Win32/Joystick.hpp index 0b6599274..6b3c3874c 100644 --- a/src/SFML/Window/Win32/Joystick.hpp +++ b/src/SFML/Window/Win32/Joystick.hpp @@ -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 diff --git a/src/SFML/Window/WindowImpl.cpp b/src/SFML/Window/WindowImpl.cpp index 7e411905e..0ed6cb354 100644 --- a/src/SFML/Window/WindowImpl.cpp +++ b/src/SFML/Window/WindowImpl.cpp @@ -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(j); + if (myJoysticks[i].HasAxis(axis)) { - Event event; - event.Type = Event::JoyMoved; - event.JoyMove.JoystickId = i; - event.JoyMove.Axis = static_cast(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); + } } } diff --git a/src/SFML/Window/WindowImpl.hpp b/src/SFML/Window/WindowImpl.hpp index 82272bd11..393faf312 100644 --- a/src/SFML/Window/WindowImpl.hpp +++ b/src/SFML/Window/WindowImpl.hpp @@ -238,18 +238,13 @@ private : //////////////////////////////////////////////////////////// virtual void ProcessEvents(bool block) = 0; - //////////////////////////////////////////////////////////// - // Total number of joysticks supported - //////////////////////////////////////////////////////////// - enum {JoysticksCount = 2}; - //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - std::set 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 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