mirror of
https://github.com/SFML/SFML.git
synced 2024-11-28 22:31:09 +08:00
Add EnumArray to implement enum-indexed arrays
This commit is contained in:
parent
92826e1c1f
commit
a474654ea7
@ -30,6 +30,8 @@
|
|||||||
#include <SFML/Window/EglContext.hpp>
|
#include <SFML/Window/EglContext.hpp>
|
||||||
#include <SFML/Window/Event.hpp>
|
#include <SFML/Window/Event.hpp>
|
||||||
|
|
||||||
|
#include <SFML/System/EnumArray.hpp>
|
||||||
|
|
||||||
#include <android/configuration.h>
|
#include <android/configuration.h>
|
||||||
#include <android/native_activity.h>
|
#include <android/native_activity.h>
|
||||||
|
|
||||||
@ -73,9 +75,9 @@ struct ActivityStates
|
|||||||
void (*forwardEvent)(const Event& event){};
|
void (*forwardEvent)(const Event& event){};
|
||||||
int (*processEvent)(int fd, int events, void* data){};
|
int (*processEvent)(int fd, int events, void* data){};
|
||||||
|
|
||||||
std::unordered_map<int, Vector2i> touchEvents;
|
std::unordered_map<int, Vector2i> touchEvents;
|
||||||
Vector2i mousePosition;
|
Vector2i mousePosition;
|
||||||
bool isButtonPressed[Mouse::ButtonCount]{};
|
EnumArray<Mouse::Button, bool, Mouse::ButtonCount> isButtonPressed{};
|
||||||
|
|
||||||
bool mainOver{};
|
bool mainOver{};
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ set(SRC
|
|||||||
${INCROOT}/Angle.inl
|
${INCROOT}/Angle.inl
|
||||||
${SRCROOT}/Clock.cpp
|
${SRCROOT}/Clock.cpp
|
||||||
${INCROOT}/Clock.hpp
|
${INCROOT}/Clock.hpp
|
||||||
|
${SRCROOT}/EnumArray.hpp
|
||||||
${SRCROOT}/Err.cpp
|
${SRCROOT}/Err.cpp
|
||||||
${INCROOT}/Err.hpp
|
${INCROOT}/Err.hpp
|
||||||
${INCROOT}/Export.hpp
|
${INCROOT}/Export.hpp
|
||||||
|
75
src/SFML/System/EnumArray.hpp
Normal file
75
src/SFML/System/EnumArray.hpp
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SFML - Simple and Fast Multimedia Library
|
||||||
|
// Copyright (C) 2007-2023 Laurent Gomila (laurent@sfml-dev.org)
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it freely,
|
||||||
|
// subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented;
|
||||||
|
// you must not claim that you wrote the original software.
|
||||||
|
// If you use this software in a product, an acknowledgment
|
||||||
|
// in the product documentation would be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such,
|
||||||
|
// and must not be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Headers
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
#include <array>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
|
||||||
|
namespace sf::priv
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Fixed-size array container indexed by an enumeration
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
template <typename Enum, typename Value, std::size_t Count>
|
||||||
|
struct EnumArray : public std::array<Value, Count>
|
||||||
|
{
|
||||||
|
static_assert(std::is_enum_v<Enum>, "Enum type parameter must be an enumeration");
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Returns a reference to the element associated to specified \a key
|
||||||
|
///
|
||||||
|
/// No bounds checking is performed in release builds.
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
constexpr Value& operator[](Enum key)
|
||||||
|
{
|
||||||
|
const auto index = static_cast<std::size_t>(key);
|
||||||
|
assert(index < Count && "Index is out of bounds");
|
||||||
|
return std::array<Value, Count>::operator[](index);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Returns a reference to the element associated to specified \a key
|
||||||
|
///
|
||||||
|
/// No bounds checking is performed in release builds.
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
constexpr const Value& operator[](Enum key) const
|
||||||
|
{
|
||||||
|
const auto index = static_cast<std::size_t>(key);
|
||||||
|
assert(index < Count && "Index is out of bounds");
|
||||||
|
return std::array<Value, Count>::operator[](index);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace sf::priv
|
@ -171,7 +171,7 @@ bool isMouseButtonPressed(Mouse::Button button)
|
|||||||
ActivityStates& states = getActivity();
|
ActivityStates& states = getActivity();
|
||||||
const std::lock_guard lock(states.mutex);
|
const std::lock_guard lock(states.mutex);
|
||||||
|
|
||||||
return states.isButtonPressed[static_cast<int>(button)];
|
return states.isButtonPressed[button];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Window/SensorImpl.hpp>
|
#include <SFML/Window/SensorImpl.hpp>
|
||||||
|
|
||||||
|
#include <SFML/System/EnumArray.hpp>
|
||||||
#include <SFML/System/Time.hpp>
|
#include <SFML/System/Time.hpp>
|
||||||
|
|
||||||
#include <android/looper.h>
|
#include <android/looper.h>
|
||||||
@ -44,10 +45,10 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
ALooper* looper;
|
ALooper* looper;
|
||||||
ASensorManager* sensorManager;
|
ASensorManager* sensorManager;
|
||||||
ASensorEventQueue* sensorEventQueue;
|
ASensorEventQueue* sensorEventQueue;
|
||||||
sf::Vector3f sensorData[sf::Sensor::Count];
|
sf::priv::EnumArray<sf::Sensor::Type, sf::Vector3f, sf::Sensor::Count> sensorData;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
@ -104,8 +105,8 @@ bool SensorImpl::open(Sensor::Type sensor)
|
|||||||
// Set the event rate (not to consume too much battery)
|
// Set the event rate (not to consume too much battery)
|
||||||
ASensorEventQueue_setEventRate(sensorEventQueue, m_sensor, static_cast<std::int32_t>(minimumDelay.asMicroseconds()));
|
ASensorEventQueue_setEventRate(sensorEventQueue, m_sensor, static_cast<std::int32_t>(minimumDelay.asMicroseconds()));
|
||||||
|
|
||||||
// Save the index of the sensor
|
// Save the type of the sensor
|
||||||
m_index = static_cast<unsigned int>(sensor);
|
m_type = sensor;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -124,7 +125,7 @@ Vector3f SensorImpl::update() const
|
|||||||
// Update our sensor data list
|
// Update our sensor data list
|
||||||
ALooper_pollAll(0, nullptr, nullptr, nullptr);
|
ALooper_pollAll(0, nullptr, nullptr, nullptr);
|
||||||
|
|
||||||
return sensorData[m_index];
|
return sensorData[m_type];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -142,14 +143,15 @@ void SensorImpl::setEnabled(bool enabled)
|
|||||||
const ASensor* SensorImpl::getDefaultSensor(Sensor::Type sensor)
|
const ASensor* SensorImpl::getDefaultSensor(Sensor::Type sensor)
|
||||||
{
|
{
|
||||||
// Find the Android sensor type
|
// Find the Android sensor type
|
||||||
static int types[] = {ASENSOR_TYPE_ACCELEROMETER,
|
static EnumArray<Sensor::Type, int, Sensor::Count> types =
|
||||||
ASENSOR_TYPE_GYROSCOPE,
|
{ASENSOR_TYPE_ACCELEROMETER,
|
||||||
ASENSOR_TYPE_MAGNETIC_FIELD,
|
ASENSOR_TYPE_GYROSCOPE,
|
||||||
ASENSOR_TYPE_GRAVITY,
|
ASENSOR_TYPE_MAGNETIC_FIELD,
|
||||||
ASENSOR_TYPE_LINEAR_ACCELERATION,
|
ASENSOR_TYPE_GRAVITY,
|
||||||
ASENSOR_TYPE_ORIENTATION};
|
ASENSOR_TYPE_LINEAR_ACCELERATION,
|
||||||
|
ASENSOR_TYPE_ORIENTATION};
|
||||||
|
|
||||||
int type = types[static_cast<int>(sensor)];
|
int type = types[sensor];
|
||||||
|
|
||||||
// Retrieve the default sensor matching this type
|
// Retrieve the default sensor matching this type
|
||||||
return ASensorManager_getDefaultSensor(sensorManager, type);
|
return ASensorManager_getDefaultSensor(sensorManager, type);
|
||||||
@ -215,7 +217,7 @@ int SensorImpl::processSensorEvents(int /* fd */, int /* events */, void* /* sen
|
|||||||
if (!type)
|
if (!type)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
sensorData[static_cast<int>(*type)] = data;
|
sensorData[*type] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -122,7 +122,7 @@ private:
|
|||||||
// Member data
|
// Member data
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
const ASensor* m_sensor; ///< Android sensor structure
|
const ASensor* m_sensor; ///< Android sensor structure
|
||||||
unsigned int m_index; ///< Index of the sensor
|
Sensor::Type m_type; ///< Type of the sensor
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf::priv
|
||||||
|
@ -524,6 +524,7 @@ int WindowImplAndroid::processPointerEvent(bool isDown, AInputEvent* inputEvent,
|
|||||||
|
|
||||||
std::size_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
|
std::size_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
|
||||||
std::int32_t id = AMotionEvent_getPointerId(inputEvent, index);
|
std::int32_t id = AMotionEvent_getPointerId(inputEvent, index);
|
||||||
|
const auto button = static_cast<Mouse::Button>(id);
|
||||||
|
|
||||||
int x = static_cast<int>(AMotionEvent_getX(inputEvent, index));
|
int x = static_cast<int>(AMotionEvent_getX(inputEvent, index));
|
||||||
int y = static_cast<int>(AMotionEvent_getY(inputEvent, index));
|
int y = static_cast<int>(AMotionEvent_getY(inputEvent, index));
|
||||||
@ -535,12 +536,12 @@ int WindowImplAndroid::processPointerEvent(bool isDown, AInputEvent* inputEvent,
|
|||||||
if (device == AINPUT_SOURCE_MOUSE)
|
if (device == AINPUT_SOURCE_MOUSE)
|
||||||
{
|
{
|
||||||
event.type = Event::MouseButtonPressed;
|
event.type = Event::MouseButtonPressed;
|
||||||
event.mouseButton.button = static_cast<Mouse::Button>(id);
|
event.mouseButton.button = button;
|
||||||
event.mouseButton.x = x;
|
event.mouseButton.x = x;
|
||||||
event.mouseButton.y = y;
|
event.mouseButton.y = y;
|
||||||
|
|
||||||
if (id >= 0 && id < static_cast<int>(Mouse::ButtonCount))
|
if (id >= 0 && id < static_cast<int>(Mouse::ButtonCount))
|
||||||
states.isButtonPressed[id] = true;
|
states.isButtonPressed[button] = true;
|
||||||
}
|
}
|
||||||
else if (static_cast<unsigned int>(device) & AINPUT_SOURCE_TOUCHSCREEN)
|
else if (static_cast<unsigned int>(device) & AINPUT_SOURCE_TOUCHSCREEN)
|
||||||
{
|
{
|
||||||
@ -557,12 +558,12 @@ int WindowImplAndroid::processPointerEvent(bool isDown, AInputEvent* inputEvent,
|
|||||||
if (device == AINPUT_SOURCE_MOUSE)
|
if (device == AINPUT_SOURCE_MOUSE)
|
||||||
{
|
{
|
||||||
event.type = Event::MouseButtonReleased;
|
event.type = Event::MouseButtonReleased;
|
||||||
event.mouseButton.button = static_cast<Mouse::Button>(id);
|
event.mouseButton.button = button;
|
||||||
event.mouseButton.x = x;
|
event.mouseButton.x = x;
|
||||||
event.mouseButton.y = y;
|
event.mouseButton.y = y;
|
||||||
|
|
||||||
if (id >= 0 && id < static_cast<int>(Mouse::ButtonCount))
|
if (id >= 0 && id < static_cast<int>(Mouse::ButtonCount))
|
||||||
states.isButtonPressed[id] = false;
|
states.isButtonPressed[button] = false;
|
||||||
}
|
}
|
||||||
else if (static_cast<std::uint32_t>(device) & AINPUT_SOURCE_TOUCHSCREEN)
|
else if (static_cast<std::uint32_t>(device) & AINPUT_SOURCE_TOUCHSCREEN)
|
||||||
{
|
{
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <SFML/Window/Event.hpp>
|
#include <SFML/Window/Event.hpp>
|
||||||
#include <SFML/Window/InputImpl.hpp>
|
#include <SFML/Window/InputImpl.hpp>
|
||||||
|
|
||||||
|
#include <SFML/System/EnumArray.hpp>
|
||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -60,9 +61,9 @@ struct TouchSlot
|
|||||||
std::recursive_mutex inputMutex; // threadsafe? maybe...
|
std::recursive_mutex inputMutex; // threadsafe? maybe...
|
||||||
sf::Vector2i mousePos; // current mouse position
|
sf::Vector2i mousePos; // current mouse position
|
||||||
|
|
||||||
std::vector<int> fileDescriptors; // list of open file descriptors for /dev/input
|
std::vector<int> fileDescriptors; // list of open file descriptors for /dev/input
|
||||||
std::vector<bool> mouseMap(sf::Mouse::ButtonCount, false); // track whether keys are down
|
sf::priv::EnumArray<sf::Mouse::Button, bool, sf::Mouse::ButtonCount> mouseMap{}; // track whether mouse buttons are down
|
||||||
std::vector<bool> keyMap(sf::Keyboard::KeyCount, false); // track whether mouse buttons are down
|
std::vector<bool> keyMap(sf::Keyboard::KeyCount, false); // track whether keys are down
|
||||||
|
|
||||||
int touchFd = -1; // file descriptor we have seen MT events on; assumes only 1
|
int touchFd = -1; // file descriptor we have seen MT events on; assumes only 1
|
||||||
std::vector<TouchSlot> touchSlots; // track the state of each touch "slot"
|
std::vector<TouchSlot> touchSlots; // track the state of each touch "slot"
|
||||||
@ -392,7 +393,7 @@ bool eventProcess(sf::Event& event)
|
|||||||
event.mouseButton.x = mousePos.x;
|
event.mouseButton.x = mousePos.x;
|
||||||
event.mouseButton.y = mousePos.y;
|
event.mouseButton.y = mousePos.y;
|
||||||
|
|
||||||
mouseMap[static_cast<std::size_t>(*mb)] = inputEvent.value;
|
mouseMap[*mb] = inputEvent.value;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -632,7 +633,7 @@ bool isMouseButtonPressed(Mouse::Button button)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
update();
|
update();
|
||||||
return mouseMap[static_cast<std::size_t>(button)];
|
return mouseMap[button];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -159,8 +159,8 @@ std::optional<sf::Joystick::Axis> usageToAxis(int usage)
|
|||||||
|
|
||||||
void hatValueToSfml(int value, sf::priv::JoystickState& state)
|
void hatValueToSfml(int value, sf::priv::JoystickState& state)
|
||||||
{
|
{
|
||||||
state.axes[static_cast<int>(sf::Joystick::Axis::PovX)] = static_cast<float>(hatValueMap[value].first);
|
state.axes[sf::Joystick::Axis::PovX] = static_cast<float>(hatValueMap[value].first);
|
||||||
state.axes[static_cast<int>(sf::Joystick::Axis::PovY)] = static_cast<float>(hatValueMap[value].second);
|
state.axes[sf::Joystick::Axis::PovY] = static_cast<float>(hatValueMap[value].second);
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@ -271,12 +271,12 @@ JoystickCaps JoystickImpl::getCapabilities() const
|
|||||||
{
|
{
|
||||||
if (usage == HUG_HAT_SWITCH)
|
if (usage == HUG_HAT_SWITCH)
|
||||||
{
|
{
|
||||||
caps.axes[static_cast<int>(Joystick::Axis::PovX)] = true;
|
caps.axes[Joystick::Axis::PovX] = true;
|
||||||
caps.axes[static_cast<int>(Joystick::Axis::PovY)] = true;
|
caps.axes[Joystick::Axis::PovY] = true;
|
||||||
}
|
}
|
||||||
else if (const std::optional<Joystick::Axis> axis = usageToAxis(usage))
|
else if (const std::optional<Joystick::Axis> axis = usageToAxis(usage))
|
||||||
{
|
{
|
||||||
caps.axes[static_cast<int>(*axis)] = true;
|
caps.axes[*axis] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -332,8 +332,8 @@ JoystickState JoystickImpl::JoystickImpl::update()
|
|||||||
int minimum = item.logical_minimum;
|
int minimum = item.logical_minimum;
|
||||||
int maximum = item.logical_maximum;
|
int maximum = item.logical_maximum;
|
||||||
|
|
||||||
value = (value - minimum) * 200 / (maximum - minimum) - 100;
|
value = (value - minimum) * 200 / (maximum - minimum) - 100;
|
||||||
m_state.axes[static_cast<int>(*axis)] = static_cast<float>(value);
|
m_state.axes[*axis] = static_cast<float>(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ unsigned int Joystick::getButtonCount(unsigned int joystick)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool Joystick::hasAxis(unsigned int joystick, Axis axis)
|
bool Joystick::hasAxis(unsigned int joystick, Axis axis)
|
||||||
{
|
{
|
||||||
return priv::JoystickManager::getInstance().getCapabilities(joystick).axes[static_cast<int>(axis)];
|
return priv::JoystickManager::getInstance().getCapabilities(joystick).axes[axis];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ bool Joystick::isButtonPressed(unsigned int joystick, unsigned int button)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
float Joystick::getAxisPosition(unsigned int joystick, Axis axis)
|
float Joystick::getAxisPosition(unsigned int joystick, Axis axis)
|
||||||
{
|
{
|
||||||
return priv::JoystickManager::getInstance().getState(joystick).axes[static_cast<int>(axis)];
|
return priv::JoystickManager::getInstance().getState(joystick).axes[axis];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
|
|
||||||
#include <SFML/Window/Joystick.hpp>
|
#include <SFML/Window/Joystick.hpp>
|
||||||
|
|
||||||
|
#include <SFML/System/EnumArray.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace sf::priv
|
namespace sf::priv
|
||||||
{
|
{
|
||||||
@ -40,8 +42,8 @@ namespace sf::priv
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
struct JoystickCaps
|
struct JoystickCaps
|
||||||
{
|
{
|
||||||
unsigned int buttonCount{}; //!< Number of buttons supported by the joystick
|
unsigned int buttonCount{}; //!< Number of buttons supported by the joystick
|
||||||
bool axes[Joystick::AxisCount]{}; //!< Support for each axis
|
EnumArray<Joystick::Axis, bool, Joystick::AxisCount> axes{}; //!< Support for each axis
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -51,9 +53,9 @@ struct JoystickCaps
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
struct JoystickState
|
struct JoystickState
|
||||||
{
|
{
|
||||||
bool connected{}; //!< Is the joystick currently connected?
|
bool connected{}; //!< Is the joystick currently connected?
|
||||||
float axes[Joystick::AxisCount]{}; //!< Position of each axis, in range [-100, 100]
|
EnumArray<Joystick::Axis, float, Joystick::AxisCount> axes{}; //!< Position of each axis, in range [-100, 100]
|
||||||
bool buttons[Joystick::ButtonCount]{}; //!< Status of each button (true = pressed)
|
bool buttons[Joystick::ButtonCount]{}; //!< Status of each button (true = pressed)
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf::priv
|
||||||
|
@ -160,8 +160,8 @@ std::optional<sf::Joystick::Axis> usageToAxis(int usage)
|
|||||||
|
|
||||||
void hatValueToSfml(int value, sf::priv::JoystickState& state)
|
void hatValueToSfml(int value, sf::priv::JoystickState& state)
|
||||||
{
|
{
|
||||||
state.axes[static_cast<int>(sf::Joystick::Axis::PovX)] = static_cast<float>(hatValueMap[value].first);
|
state.axes[sf::Joystick::Axis::PovX] = static_cast<float>(hatValueMap[value].first);
|
||||||
state.axes[static_cast<int>(sf::Joystick::Axis::PovY)] = static_cast<float>(hatValueMap[value].second);
|
state.axes[sf::Joystick::Axis::PovY] = static_cast<float>(hatValueMap[value].second);
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@ -276,12 +276,12 @@ JoystickCaps JoystickImpl::getCapabilities() const
|
|||||||
{
|
{
|
||||||
if (usage == HUG_HAT_SWITCH)
|
if (usage == HUG_HAT_SWITCH)
|
||||||
{
|
{
|
||||||
caps.axes[static_cast<int>(Joystick::Axis::PovX)] = true;
|
caps.axes[Joystick::Axis::PovX] = true;
|
||||||
caps.axes[static_cast<int>(Joystick::Axis::PovY)] = true;
|
caps.axes[Joystick::Axis::PovY] = true;
|
||||||
}
|
}
|
||||||
else if (const std::optional<Joystick::Axis> axis = usageToAxis(usage))
|
else if (const std::optional<Joystick::Axis> axis = usageToAxis(usage))
|
||||||
{
|
{
|
||||||
caps.axes[static_cast<int>(*axis)] = true;
|
caps.axes[*axis] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -337,8 +337,8 @@ JoystickState JoystickImpl::JoystickImpl::update()
|
|||||||
int minimum = item.logical_minimum;
|
int minimum = item.logical_minimum;
|
||||||
int maximum = item.logical_maximum;
|
int maximum = item.logical_maximum;
|
||||||
|
|
||||||
value = (value - minimum) * 200 / (maximum - minimum) - 100;
|
value = (value - minimum) * 200 / (maximum - minimum) - 100;
|
||||||
m_state.axes[static_cast<int>(*axis)] = value;
|
m_state.axes[*axis] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,17 +45,17 @@ SensorManager& SensorManager::getInstance()
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool SensorManager::isAvailable(Sensor::Type sensor)
|
bool SensorManager::isAvailable(Sensor::Type sensor)
|
||||||
{
|
{
|
||||||
return m_sensors[static_cast<int>(sensor)].available;
|
return m_sensors[sensor].available;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void SensorManager::setEnabled(Sensor::Type sensor, bool enabled)
|
void SensorManager::setEnabled(Sensor::Type sensor, bool enabled)
|
||||||
{
|
{
|
||||||
if (m_sensors[static_cast<int>(sensor)].available)
|
if (m_sensors[sensor].available)
|
||||||
{
|
{
|
||||||
m_sensors[static_cast<int>(sensor)].enabled = enabled;
|
m_sensors[sensor].enabled = enabled;
|
||||||
m_sensors[static_cast<int>(sensor)].sensor.setEnabled(enabled);
|
m_sensors[sensor].sensor.setEnabled(enabled);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -68,14 +68,14 @@ void SensorManager::setEnabled(Sensor::Type sensor, bool enabled)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool SensorManager::isEnabled(Sensor::Type sensor) const
|
bool SensorManager::isEnabled(Sensor::Type sensor) const
|
||||||
{
|
{
|
||||||
return m_sensors[static_cast<int>(sensor)].enabled;
|
return m_sensors[sensor].enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Vector3f SensorManager::getValue(Sensor::Type sensor) const
|
Vector3f SensorManager::getValue(Sensor::Type sensor) const
|
||||||
{
|
{
|
||||||
return m_sensors[static_cast<int>(sensor)].value;
|
return m_sensors[sensor].value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -100,19 +100,21 @@ SensorManager::SensorManager()
|
|||||||
// Per sensor initialization
|
// Per sensor initialization
|
||||||
for (unsigned int i = 0; i < Sensor::Count; ++i)
|
for (unsigned int i = 0; i < Sensor::Count; ++i)
|
||||||
{
|
{
|
||||||
|
const auto sensor = static_cast<Sensor::Type>(i);
|
||||||
|
|
||||||
// Check which sensors are available
|
// Check which sensors are available
|
||||||
m_sensors[i].available = SensorImpl::isAvailable(static_cast<Sensor::Type>(i));
|
m_sensors[sensor].available = SensorImpl::isAvailable(sensor);
|
||||||
|
|
||||||
// Open the available sensors
|
// Open the available sensors
|
||||||
if (m_sensors[i].available)
|
if (m_sensors[sensor].available)
|
||||||
{
|
{
|
||||||
if (m_sensors[i].sensor.open(static_cast<Sensor::Type>(i)))
|
if (m_sensors[sensor].sensor.open(sensor))
|
||||||
{
|
{
|
||||||
m_sensors[i].sensor.setEnabled(false);
|
m_sensors[sensor].sensor.setEnabled(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_sensors[i].available = false;
|
m_sensors[sensor].available = false;
|
||||||
err() << "Warning: sensor " << i << " failed to open, will not be available" << std::endl;
|
err() << "Warning: sensor " << i << " failed to open, will not be available" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
#include <SFML/Window/Sensor.hpp>
|
#include <SFML/Window/Sensor.hpp>
|
||||||
#include <SFML/Window/SensorImpl.hpp>
|
#include <SFML/Window/SensorImpl.hpp>
|
||||||
|
|
||||||
|
#include <SFML/System/EnumArray.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace sf::priv
|
namespace sf::priv
|
||||||
{
|
{
|
||||||
@ -133,7 +135,7 @@ private:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Member data
|
// Member data
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Item m_sensors[Sensor::Count]; //!< Sensors information and state
|
EnumArray<Sensor::Type, Item, Sensor::Count> m_sensors; //!< Sensors information and state
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf::priv
|
||||||
|
@ -603,17 +603,17 @@ JoystickCaps JoystickImpl::getCapabilities() const
|
|||||||
switch (m_mapping[i])
|
switch (m_mapping[i])
|
||||||
{
|
{
|
||||||
// clang-format off
|
// clang-format off
|
||||||
case ABS_X: caps.axes[static_cast<int>(Joystick::Axis::X)] = true; break;
|
case ABS_X: caps.axes[Joystick::Axis::X] = true; break;
|
||||||
case ABS_Y: caps.axes[static_cast<int>(Joystick::Axis::Y)] = true; break;
|
case ABS_Y: caps.axes[Joystick::Axis::Y] = true; break;
|
||||||
case ABS_Z:
|
case ABS_Z:
|
||||||
case ABS_THROTTLE: caps.axes[static_cast<int>(Joystick::Axis::Z)] = true; break;
|
case ABS_THROTTLE: caps.axes[Joystick::Axis::Z] = true; break;
|
||||||
case ABS_RZ:
|
case ABS_RZ:
|
||||||
case ABS_RUDDER: caps.axes[static_cast<int>(Joystick::Axis::R)] = true; break;
|
case ABS_RUDDER: caps.axes[Joystick::Axis::R] = true; break;
|
||||||
case ABS_RX: caps.axes[static_cast<int>(Joystick::Axis::U)] = true; break;
|
case ABS_RX: caps.axes[Joystick::Axis::U] = true; break;
|
||||||
case ABS_RY: caps.axes[static_cast<int>(Joystick::Axis::V)] = true; break;
|
case ABS_RY: caps.axes[Joystick::Axis::V] = true; break;
|
||||||
case ABS_HAT0X: caps.axes[static_cast<int>(Joystick::Axis::PovX)] = true; break;
|
case ABS_HAT0X: caps.axes[Joystick::Axis::PovX] = true; break;
|
||||||
case ABS_HAT0Y: caps.axes[static_cast<int>(Joystick::Axis::PovY)] = true; break;
|
case ABS_HAT0Y: caps.axes[Joystick::Axis::PovY] = true; break;
|
||||||
default: break;
|
default: break;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -655,30 +655,30 @@ JoystickState JoystickImpl::JoystickImpl::update()
|
|||||||
switch (m_mapping[joyState.number])
|
switch (m_mapping[joyState.number])
|
||||||
{
|
{
|
||||||
case ABS_X:
|
case ABS_X:
|
||||||
m_state.axes[static_cast<int>(Joystick::Axis::X)] = value;
|
m_state.axes[Joystick::Axis::X] = value;
|
||||||
break;
|
break;
|
||||||
case ABS_Y:
|
case ABS_Y:
|
||||||
m_state.axes[static_cast<int>(Joystick::Axis::Y)] = value;
|
m_state.axes[Joystick::Axis::Y] = value;
|
||||||
break;
|
break;
|
||||||
case ABS_Z:
|
case ABS_Z:
|
||||||
case ABS_THROTTLE:
|
case ABS_THROTTLE:
|
||||||
m_state.axes[static_cast<int>(Joystick::Axis::Z)] = value;
|
m_state.axes[Joystick::Axis::Z] = value;
|
||||||
break;
|
break;
|
||||||
case ABS_RZ:
|
case ABS_RZ:
|
||||||
case ABS_RUDDER:
|
case ABS_RUDDER:
|
||||||
m_state.axes[static_cast<int>(Joystick::Axis::R)] = value;
|
m_state.axes[Joystick::Axis::R] = value;
|
||||||
break;
|
break;
|
||||||
case ABS_RX:
|
case ABS_RX:
|
||||||
m_state.axes[static_cast<int>(Joystick::Axis::U)] = value;
|
m_state.axes[Joystick::Axis::U] = value;
|
||||||
break;
|
break;
|
||||||
case ABS_RY:
|
case ABS_RY:
|
||||||
m_state.axes[static_cast<int>(Joystick::Axis::V)] = value;
|
m_state.axes[Joystick::Axis::V] = value;
|
||||||
break;
|
break;
|
||||||
case ABS_HAT0X:
|
case ABS_HAT0X:
|
||||||
m_state.axes[static_cast<int>(Joystick::Axis::PovX)] = value;
|
m_state.axes[Joystick::Axis::PovX] = value;
|
||||||
break;
|
break;
|
||||||
case ABS_HAT0Y:
|
case ABS_HAT0Y:
|
||||||
m_state.axes[static_cast<int>(Joystick::Axis::PovY)] = value;
|
m_state.axes[Joystick::Axis::PovY] = value;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -331,14 +331,14 @@ JoystickCaps JoystickImpl::getCapabilities() const
|
|||||||
if (caps.buttonCount > Joystick::ButtonCount)
|
if (caps.buttonCount > Joystick::ButtonCount)
|
||||||
caps.buttonCount = Joystick::ButtonCount;
|
caps.buttonCount = Joystick::ButtonCount;
|
||||||
|
|
||||||
caps.axes[static_cast<int>(Joystick::Axis::X)] = true;
|
caps.axes[Joystick::Axis::X] = true;
|
||||||
caps.axes[static_cast<int>(Joystick::Axis::Y)] = true;
|
caps.axes[Joystick::Axis::Y] = true;
|
||||||
caps.axes[static_cast<int>(Joystick::Axis::Z)] = (m_caps.wCaps & JOYCAPS_HASZ) != 0;
|
caps.axes[Joystick::Axis::Z] = (m_caps.wCaps & JOYCAPS_HASZ) != 0;
|
||||||
caps.axes[static_cast<int>(Joystick::Axis::R)] = (m_caps.wCaps & JOYCAPS_HASR) != 0;
|
caps.axes[Joystick::Axis::R] = (m_caps.wCaps & JOYCAPS_HASR) != 0;
|
||||||
caps.axes[static_cast<int>(Joystick::Axis::U)] = (m_caps.wCaps & JOYCAPS_HASU) != 0;
|
caps.axes[Joystick::Axis::U] = (m_caps.wCaps & JOYCAPS_HASU) != 0;
|
||||||
caps.axes[static_cast<int>(Joystick::Axis::V)] = (m_caps.wCaps & JOYCAPS_HASV) != 0;
|
caps.axes[Joystick::Axis::V] = (m_caps.wCaps & JOYCAPS_HASV) != 0;
|
||||||
caps.axes[static_cast<int>(Joystick::Axis::PovX)] = (m_caps.wCaps & JOYCAPS_HASPOV) != 0;
|
caps.axes[Joystick::Axis::PovX] = (m_caps.wCaps & JOYCAPS_HASPOV) != 0;
|
||||||
caps.axes[static_cast<int>(Joystick::Axis::PovY)] = (m_caps.wCaps & JOYCAPS_HASPOV) != 0;
|
caps.axes[Joystick::Axis::PovY] = (m_caps.wCaps & JOYCAPS_HASPOV) != 0;
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
@ -379,36 +379,36 @@ JoystickState JoystickImpl::update()
|
|||||||
state.connected = true;
|
state.connected = true;
|
||||||
|
|
||||||
// Axes
|
// Axes
|
||||||
state.axes[static_cast<int>(Joystick::Axis::X)] = (static_cast<float>(pos.dwXpos) -
|
state.axes[Joystick::Axis::X] = (static_cast<float>(pos.dwXpos) -
|
||||||
static_cast<float>(m_caps.wXmax + m_caps.wXmin) / 2.f) *
|
static_cast<float>(m_caps.wXmax + m_caps.wXmin) / 2.f) *
|
||||||
200.f / static_cast<float>(m_caps.wXmax - m_caps.wXmin);
|
200.f / static_cast<float>(m_caps.wXmax - m_caps.wXmin);
|
||||||
state.axes[static_cast<int>(Joystick::Axis::Y)] = (static_cast<float>(pos.dwYpos) -
|
state.axes[Joystick::Axis::Y] = (static_cast<float>(pos.dwYpos) -
|
||||||
static_cast<float>(m_caps.wYmax + m_caps.wYmin) / 2.f) *
|
static_cast<float>(m_caps.wYmax + m_caps.wYmin) / 2.f) *
|
||||||
200.f / static_cast<float>(m_caps.wYmax - m_caps.wYmin);
|
200.f / static_cast<float>(m_caps.wYmax - m_caps.wYmin);
|
||||||
state.axes[static_cast<int>(Joystick::Axis::Z)] = (static_cast<float>(pos.dwZpos) -
|
state.axes[Joystick::Axis::Z] = (static_cast<float>(pos.dwZpos) -
|
||||||
static_cast<float>(m_caps.wZmax + m_caps.wZmin) / 2.f) *
|
static_cast<float>(m_caps.wZmax + m_caps.wZmin) / 2.f) *
|
||||||
200.f / static_cast<float>(m_caps.wZmax - m_caps.wZmin);
|
200.f / static_cast<float>(m_caps.wZmax - m_caps.wZmin);
|
||||||
state.axes[static_cast<int>(Joystick::Axis::R)] = (static_cast<float>(pos.dwRpos) -
|
state.axes[Joystick::Axis::R] = (static_cast<float>(pos.dwRpos) -
|
||||||
static_cast<float>(m_caps.wRmax + m_caps.wRmin) / 2.f) *
|
static_cast<float>(m_caps.wRmax + m_caps.wRmin) / 2.f) *
|
||||||
200.f / static_cast<float>(m_caps.wRmax - m_caps.wRmin);
|
200.f / static_cast<float>(m_caps.wRmax - m_caps.wRmin);
|
||||||
state.axes[static_cast<int>(Joystick::Axis::U)] = (static_cast<float>(pos.dwUpos) -
|
state.axes[Joystick::Axis::U] = (static_cast<float>(pos.dwUpos) -
|
||||||
static_cast<float>(m_caps.wUmax + m_caps.wUmin) / 2.f) *
|
static_cast<float>(m_caps.wUmax + m_caps.wUmin) / 2.f) *
|
||||||
200.f / static_cast<float>(m_caps.wUmax - m_caps.wUmin);
|
200.f / static_cast<float>(m_caps.wUmax - m_caps.wUmin);
|
||||||
state.axes[static_cast<int>(Joystick::Axis::V)] = (static_cast<float>(pos.dwVpos) -
|
state.axes[Joystick::Axis::V] = (static_cast<float>(pos.dwVpos) -
|
||||||
static_cast<float>(m_caps.wVmax + m_caps.wVmin) / 2.f) *
|
static_cast<float>(m_caps.wVmax + m_caps.wVmin) / 2.f) *
|
||||||
200.f / static_cast<float>(m_caps.wVmax - m_caps.wVmin);
|
200.f / static_cast<float>(m_caps.wVmax - m_caps.wVmin);
|
||||||
|
|
||||||
// Special case for POV, it is given as an angle
|
// Special case for POV, it is given as an angle
|
||||||
if (pos.dwPOV != 0xFFFF)
|
if (pos.dwPOV != 0xFFFF)
|
||||||
{
|
{
|
||||||
const float angle = static_cast<float>(pos.dwPOV) / 18000.f * 3.141592654f;
|
const float angle = static_cast<float>(pos.dwPOV) / 18000.f * 3.141592654f;
|
||||||
state.axes[static_cast<int>(Joystick::Axis::PovX)] = std::sin(angle) * 100;
|
state.axes[Joystick::Axis::PovX] = std::sin(angle) * 100;
|
||||||
state.axes[static_cast<int>(Joystick::Axis::PovY)] = std::cos(angle) * 100;
|
state.axes[Joystick::Axis::PovY] = std::cos(angle) * 100;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state.axes[static_cast<int>(Joystick::Axis::PovX)] = 0;
|
state.axes[Joystick::Axis::PovX] = 0;
|
||||||
state.axes[static_cast<int>(Joystick::Axis::PovY)] = 0;
|
state.axes[Joystick::Axis::PovY] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buttons
|
// Buttons
|
||||||
@ -877,7 +877,10 @@ JoystickCaps JoystickImpl::getCapabilitiesDInput() const
|
|||||||
|
|
||||||
// Check which axes have valid offsets
|
// Check which axes have valid offsets
|
||||||
for (unsigned int i = 0; i < Joystick::AxisCount; ++i)
|
for (unsigned int i = 0; i < Joystick::AxisCount; ++i)
|
||||||
caps.axes[i] = (m_axes[i] != -1);
|
{
|
||||||
|
const auto axis = static_cast<Joystick::Axis>(i);
|
||||||
|
caps.axes[axis] = (m_axes[axis] != -1);
|
||||||
|
}
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
@ -929,9 +932,10 @@ JoystickState JoystickImpl::updateDInputBuffered()
|
|||||||
// Get the current state of each axis
|
// Get the current state of each axis
|
||||||
for (unsigned int j = 0; j < Joystick::AxisCount; ++j)
|
for (unsigned int j = 0; j < Joystick::AxisCount; ++j)
|
||||||
{
|
{
|
||||||
if (m_axes[j] == static_cast<int>(events[i].dwOfs))
|
const auto axis = static_cast<Joystick::Axis>(j);
|
||||||
|
if (m_axes[axis] == static_cast<int>(events[i].dwOfs))
|
||||||
{
|
{
|
||||||
if ((j == static_cast<int>(Joystick::Axis::PovX)) || (j == static_cast<int>(Joystick::Axis::PovY)))
|
if ((axis == Joystick::Axis::PovX) || (axis == Joystick::Axis::PovY))
|
||||||
{
|
{
|
||||||
const unsigned short value = LOWORD(events[i].dwData);
|
const unsigned short value = LOWORD(events[i].dwData);
|
||||||
|
|
||||||
@ -939,18 +943,18 @@ JoystickState JoystickImpl::updateDInputBuffered()
|
|||||||
{
|
{
|
||||||
const float angle = (static_cast<float>(value)) * 3.141592654f / DI_DEGREES / 180.f;
|
const float angle = (static_cast<float>(value)) * 3.141592654f / DI_DEGREES / 180.f;
|
||||||
|
|
||||||
m_state.axes[static_cast<int>(Joystick::Axis::PovX)] = std::sin(angle) * 100.f;
|
m_state.axes[Joystick::Axis::PovX] = std::sin(angle) * 100.f;
|
||||||
m_state.axes[static_cast<int>(Joystick::Axis::PovY)] = std::cos(angle) * 100.f;
|
m_state.axes[Joystick::Axis::PovY] = std::cos(angle) * 100.f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_state.axes[static_cast<int>(Joystick::Axis::PovX)] = 0.f;
|
m_state.axes[Joystick::Axis::PovX] = 0.f;
|
||||||
m_state.axes[static_cast<int>(Joystick::Axis::PovY)] = 0.f;
|
m_state.axes[Joystick::Axis::PovY] = 0.f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_state.axes[j] = (static_cast<float>(static_cast<short>(events[i].dwData)) + 0.5f) * 100.f / 32767.5f;
|
m_state.axes[axis] = (static_cast<float>(static_cast<short>(events[i].dwData)) + 0.5f) * 100.f / 32767.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
eventHandled = true;
|
eventHandled = true;
|
||||||
@ -1018,37 +1022,38 @@ JoystickState JoystickImpl::updateDInputPolled()
|
|||||||
// Get the current state of each axis
|
// Get the current state of each axis
|
||||||
for (unsigned int i = 0; i < Joystick::AxisCount; ++i)
|
for (unsigned int i = 0; i < Joystick::AxisCount; ++i)
|
||||||
{
|
{
|
||||||
if (m_axes[i] != -1)
|
const auto axis = static_cast<Joystick::Axis>(i);
|
||||||
|
if (m_axes[axis] != -1)
|
||||||
{
|
{
|
||||||
if ((i == static_cast<int>(Joystick::Axis::PovX)) || (i == static_cast<int>(Joystick::Axis::PovY)))
|
if ((axis == Joystick::Axis::PovX) || (axis == Joystick::Axis::PovY))
|
||||||
{
|
{
|
||||||
const unsigned short value = LOWORD(
|
const unsigned short value = LOWORD(
|
||||||
*reinterpret_cast<const DWORD*>(reinterpret_cast<const char*>(&joystate) + m_axes[i]));
|
*reinterpret_cast<const DWORD*>(reinterpret_cast<const char*>(&joystate) + m_axes[axis]));
|
||||||
|
|
||||||
if (value != 0xFFFF)
|
if (value != 0xFFFF)
|
||||||
{
|
{
|
||||||
const float angle = (static_cast<float>(value)) * 3.141592654f / DI_DEGREES / 180.f;
|
const float angle = (static_cast<float>(value)) * 3.141592654f / DI_DEGREES / 180.f;
|
||||||
|
|
||||||
state.axes[static_cast<int>(Joystick::Axis::PovX)] = std::sin(angle) * 100.f;
|
state.axes[Joystick::Axis::PovX] = std::sin(angle) * 100.f;
|
||||||
state.axes[static_cast<int>(Joystick::Axis::PovY)] = std::cos(angle) * 100.f;
|
state.axes[Joystick::Axis::PovY] = std::cos(angle) * 100.f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state.axes[static_cast<int>(Joystick::Axis::PovX)] = 0.f;
|
state.axes[Joystick::Axis::PovX] = 0.f;
|
||||||
state.axes[static_cast<int>(Joystick::Axis::PovY)] = 0.f;
|
state.axes[Joystick::Axis::PovY] = 0.f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state.axes[i] = (static_cast<float>(*reinterpret_cast<const LONG*>(
|
state.axes[axis] = (static_cast<float>(*reinterpret_cast<const LONG*>(
|
||||||
reinterpret_cast<const char*>(&joystate) + m_axes[i])) +
|
reinterpret_cast<const char*>(&joystate) + m_axes[axis])) +
|
||||||
0.5f) *
|
0.5f) *
|
||||||
100.f / 32767.5f;
|
100.f / 32767.5f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state.axes[i] = 0.f;
|
state.axes[axis] = 0.f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1103,23 +1108,23 @@ BOOL CALLBACK JoystickImpl::deviceObjectEnumerationCallback(const DIDEVICEOBJECT
|
|||||||
{
|
{
|
||||||
// Axes
|
// Axes
|
||||||
if (deviceObjectInstance->guidType == guids::GUID_XAxis)
|
if (deviceObjectInstance->guidType == guids::GUID_XAxis)
|
||||||
joystick.m_axes[static_cast<int>(Joystick::Axis::X)] = DIJOFS_X;
|
joystick.m_axes[Joystick::Axis::X] = DIJOFS_X;
|
||||||
else if (deviceObjectInstance->guidType == guids::GUID_YAxis)
|
else if (deviceObjectInstance->guidType == guids::GUID_YAxis)
|
||||||
joystick.m_axes[static_cast<int>(Joystick::Axis::Y)] = DIJOFS_Y;
|
joystick.m_axes[Joystick::Axis::Y] = DIJOFS_Y;
|
||||||
else if (deviceObjectInstance->guidType == guids::GUID_ZAxis)
|
else if (deviceObjectInstance->guidType == guids::GUID_ZAxis)
|
||||||
joystick.m_axes[static_cast<int>(Joystick::Axis::Z)] = DIJOFS_Z;
|
joystick.m_axes[Joystick::Axis::Z] = DIJOFS_Z;
|
||||||
else if (deviceObjectInstance->guidType == guids::GUID_RzAxis)
|
else if (deviceObjectInstance->guidType == guids::GUID_RzAxis)
|
||||||
joystick.m_axes[static_cast<int>(Joystick::Axis::R)] = DIJOFS_RZ;
|
joystick.m_axes[Joystick::Axis::R] = DIJOFS_RZ;
|
||||||
else if (deviceObjectInstance->guidType == guids::GUID_RxAxis)
|
else if (deviceObjectInstance->guidType == guids::GUID_RxAxis)
|
||||||
joystick.m_axes[static_cast<int>(Joystick::Axis::U)] = DIJOFS_RX;
|
joystick.m_axes[Joystick::Axis::U] = DIJOFS_RX;
|
||||||
else if (deviceObjectInstance->guidType == guids::GUID_RyAxis)
|
else if (deviceObjectInstance->guidType == guids::GUID_RyAxis)
|
||||||
joystick.m_axes[static_cast<int>(Joystick::Axis::V)] = DIJOFS_RY;
|
joystick.m_axes[Joystick::Axis::V] = DIJOFS_RY;
|
||||||
else if (deviceObjectInstance->guidType == guids::GUID_Slider)
|
else if (deviceObjectInstance->guidType == guids::GUID_Slider)
|
||||||
{
|
{
|
||||||
if (joystick.m_axes[static_cast<int>(Joystick::Axis::U)] == -1)
|
if (joystick.m_axes[Joystick::Axis::U] == -1)
|
||||||
joystick.m_axes[static_cast<int>(Joystick::Axis::U)] = DIJOFS_SLIDER(0);
|
joystick.m_axes[Joystick::Axis::U] = DIJOFS_SLIDER(0);
|
||||||
else
|
else
|
||||||
joystick.m_axes[static_cast<int>(Joystick::Axis::V)] = DIJOFS_SLIDER(1);
|
joystick.m_axes[Joystick::Axis::V] = DIJOFS_SLIDER(1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return DIENUM_CONTINUE;
|
return DIENUM_CONTINUE;
|
||||||
@ -1145,10 +1150,10 @@ BOOL CALLBACK JoystickImpl::deviceObjectEnumerationCallback(const DIDEVICEOBJECT
|
|||||||
// POVs
|
// POVs
|
||||||
if (deviceObjectInstance->guidType == guids::GUID_POV)
|
if (deviceObjectInstance->guidType == guids::GUID_POV)
|
||||||
{
|
{
|
||||||
if (joystick.m_axes[static_cast<int>(Joystick::Axis::PovX)] == -1)
|
if (joystick.m_axes[Joystick::Axis::PovX] == -1)
|
||||||
{
|
{
|
||||||
joystick.m_axes[static_cast<int>(Joystick::Axis::PovX)] = DIJOFS_POV(0);
|
joystick.m_axes[Joystick::Axis::PovX] = DIJOFS_POV(0);
|
||||||
joystick.m_axes[static_cast<int>(Joystick::Axis::PovY)] = DIJOFS_POV(0);
|
joystick.m_axes[Joystick::Axis::PovY] = DIJOFS_POV(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
#include <SFML/System/EnumArray.hpp>
|
||||||
#include <SFML/System/Win32/WindowsHeader.hpp>
|
#include <SFML/System/Win32/WindowsHeader.hpp>
|
||||||
|
|
||||||
#include <dinput.h>
|
#include <dinput.h>
|
||||||
@ -212,11 +213,11 @@ private:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Member data
|
// Member data
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
unsigned int m_index{}; //!< Index of the joystick
|
unsigned int m_index{}; //!< Index of the joystick
|
||||||
JOYCAPS m_caps{}; //!< Joystick capabilities
|
JOYCAPS m_caps{}; //!< Joystick capabilities
|
||||||
IDirectInputDevice8W* m_device{}; //!< DirectInput 8.x device
|
IDirectInputDevice8W* m_device{}; //!< DirectInput 8.x device
|
||||||
DIDEVCAPS m_deviceCaps{}; //!< DirectInput device capabilities
|
DIDEVCAPS m_deviceCaps{}; //!< DirectInput device capabilities
|
||||||
int m_axes[Joystick::AxisCount]{}; //!< Offsets to the bytes containing the axes states, -1 if not available
|
EnumArray<Joystick::Axis, int, Joystick::AxisCount> m_axes{}; //!< Offsets to the bytes containing the axes states, -1 if not available
|
||||||
int m_buttons[Joystick::ButtonCount]{}; //!< Offsets to the bytes containing the button states, -1 if not available
|
int m_buttons[Joystick::ButtonCount]{}; //!< Offsets to the bytes containing the button states, -1 if not available
|
||||||
Joystick::Identification m_identification; //!< Joystick identification
|
Joystick::Identification m_identification; //!< Joystick identification
|
||||||
JoystickState m_state; //!< Buffered joystick state
|
JoystickState m_state; //!< Buffered joystick state
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
#include <SFML/System/Sleep.hpp>
|
#include <SFML/System/Sleep.hpp>
|
||||||
#include <SFML/System/Time.hpp>
|
#include <SFML/System/Time.hpp>
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@ -122,7 +121,7 @@ WindowImpl::WindowImpl() : m_joystickStatesImpl(std::make_unique<JoystickStatesI
|
|||||||
for (unsigned int i = 0; i < Joystick::Count; ++i)
|
for (unsigned int i = 0; i < Joystick::Count; ++i)
|
||||||
{
|
{
|
||||||
m_joystickStatesImpl->states[i] = JoystickManager::getInstance().getState(i);
|
m_joystickStatesImpl->states[i] = JoystickManager::getInstance().getState(i);
|
||||||
std::fill_n(m_previousAxes[i], static_cast<std::size_t>(Joystick::AxisCount), 0.f);
|
m_previousAxes[i].fill(0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the initial sensor states
|
// Get the initial sensor states
|
||||||
@ -240,7 +239,7 @@ void WindowImpl::processJoystickEvents()
|
|||||||
|
|
||||||
// Clear previous axes positions
|
// Clear previous axes positions
|
||||||
if (connected)
|
if (connected)
|
||||||
std::fill_n(m_previousAxes[i], static_cast<std::size_t>(Joystick::AxisCount), 0.f);
|
m_previousAxes[i].fill(0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connected)
|
if (connected)
|
||||||
@ -250,20 +249,21 @@ void WindowImpl::processJoystickEvents()
|
|||||||
// Axes
|
// Axes
|
||||||
for (unsigned int j = 0; j < Joystick::AxisCount; ++j)
|
for (unsigned int j = 0; j < Joystick::AxisCount; ++j)
|
||||||
{
|
{
|
||||||
if (caps.axes[j])
|
const auto axis = static_cast<Joystick::Axis>(j);
|
||||||
|
if (caps.axes[axis])
|
||||||
{
|
{
|
||||||
const float prevPos = m_previousAxes[i][j];
|
const float prevPos = m_previousAxes[i][axis];
|
||||||
const float currPos = m_joystickStatesImpl->states[i].axes[j];
|
const float currPos = m_joystickStatesImpl->states[i].axes[axis];
|
||||||
if (std::abs(currPos - prevPos) >= m_joystickThreshold)
|
if (std::abs(currPos - prevPos) >= m_joystickThreshold)
|
||||||
{
|
{
|
||||||
Event event;
|
Event event;
|
||||||
event.type = Event::JoystickMoved;
|
event.type = Event::JoystickMoved;
|
||||||
event.joystickMove.joystickId = i;
|
event.joystickMove.joystickId = i;
|
||||||
event.joystickMove.axis = static_cast<Joystick::Axis>(j);
|
event.joystickMove.axis = axis;
|
||||||
event.joystickMove.position = currPos;
|
event.joystickMove.position = currPos;
|
||||||
pushEvent(event);
|
pushEvent(event);
|
||||||
|
|
||||||
m_previousAxes[i][j] = currPos;
|
m_previousAxes[i][axis] = currPos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -302,18 +302,18 @@ void WindowImpl::processSensorEvents()
|
|||||||
if (SensorManager::getInstance().isEnabled(sensor))
|
if (SensorManager::getInstance().isEnabled(sensor))
|
||||||
{
|
{
|
||||||
// Copy the previous value of the sensor and get the new one
|
// Copy the previous value of the sensor and get the new one
|
||||||
const Vector3f previousValue = m_sensorValue[i];
|
const Vector3f previousValue = m_sensorValue[sensor];
|
||||||
m_sensorValue[i] = SensorManager::getInstance().getValue(sensor);
|
m_sensorValue[sensor] = SensorManager::getInstance().getValue(sensor);
|
||||||
|
|
||||||
// If the value has changed, trigger an event
|
// If the value has changed, trigger an event
|
||||||
if (m_sensorValue[i] != previousValue) // TODO use a threshold?
|
if (m_sensorValue[sensor] != previousValue) // TODO use a threshold?
|
||||||
{
|
{
|
||||||
Event event;
|
Event event;
|
||||||
event.type = Event::SensorChanged;
|
event.type = Event::SensorChanged;
|
||||||
event.sensor.type = sensor;
|
event.sensor.type = sensor;
|
||||||
event.sensor.x = m_sensorValue[i].x;
|
event.sensor.x = m_sensorValue[sensor].x;
|
||||||
event.sensor.y = m_sensorValue[i].y;
|
event.sensor.y = m_sensorValue[sensor].y;
|
||||||
event.sensor.z = m_sensorValue[i].z;
|
event.sensor.z = m_sensorValue[sensor].z;
|
||||||
pushEvent(event);
|
pushEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,9 @@
|
|||||||
#include <SFML/Window/Vulkan.hpp>
|
#include <SFML/Window/Vulkan.hpp>
|
||||||
#include <SFML/Window/WindowHandle.hpp>
|
#include <SFML/Window/WindowHandle.hpp>
|
||||||
|
|
||||||
|
#include <SFML/System/EnumArray.hpp>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
@ -329,11 +332,12 @@ private:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Member data
|
// Member data
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::queue<Event> m_events; //!< Queue of available events
|
std::queue<Event> m_events; //!< Queue of available events
|
||||||
std::unique_ptr<JoystickStatesImpl> m_joystickStatesImpl; //!< Previous state of the joysticks (PImpl)
|
std::unique_ptr<JoystickStatesImpl> m_joystickStatesImpl; //!< Previous state of the joysticks (PImpl)
|
||||||
Vector3f m_sensorValue[Sensor::Count]; //!< Previous value of the sensors
|
EnumArray<Sensor::Type, Vector3f, Sensor::Count> m_sensorValue; //!< Previous value of the sensors
|
||||||
float m_joystickThreshold{0.1f}; //!< Joystick threshold (minimum motion for "move" event to be generated)
|
float m_joystickThreshold{0.1f}; //!< Joystick threshold (minimum motion for "move" event to be generated)
|
||||||
float m_previousAxes[Joystick::Count][Joystick::AxisCount]{}; //!< Position of each axis last time a move event triggered, in range [-100, 100]
|
std::array<EnumArray<Joystick::Axis, float, Joystick::AxisCount>, Joystick::Count>
|
||||||
|
m_previousAxes{}; //!< Position of each axis last time a move event triggered, in range [-100, 100]
|
||||||
std::optional<Vector2u> m_minimumSize; //!< Minimum window size
|
std::optional<Vector2u> m_minimumSize; //!< Minimum window size
|
||||||
std::optional<Vector2u> m_maximumSize; //!< Maximum window size
|
std::optional<Vector2u> m_maximumSize; //!< Maximum window size
|
||||||
};
|
};
|
||||||
|
@ -377,10 +377,10 @@ JoystickCaps JoystickImpl::getCapabilities() const
|
|||||||
|
|
||||||
// Axis:
|
// Axis:
|
||||||
for (const auto& [axis, iohidElementRef] : m_axis)
|
for (const auto& [axis, iohidElementRef] : m_axis)
|
||||||
caps.axes[static_cast<int>(axis)] = true;
|
caps.axes[axis] = true;
|
||||||
|
|
||||||
if (m_hat != nullptr)
|
if (m_hat != nullptr)
|
||||||
caps.axes[static_cast<int>(Joystick::Axis::PovX)] = caps.axes[static_cast<int>(Joystick::Axis::PovY)] = true;
|
caps.axes[Joystick::Axis::PovX] = caps.axes[Joystick::Axis::PovY] = true;
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
@ -480,7 +480,7 @@ JoystickState JoystickImpl::update()
|
|||||||
const double physicalValue = IOHIDValueGetScaledValue(value, kIOHIDValueScaleTypePhysical);
|
const double physicalValue = IOHIDValueGetScaledValue(value, kIOHIDValueScaleTypePhysical);
|
||||||
const auto scaledValue = static_cast<float>(
|
const auto scaledValue = static_cast<float>(
|
||||||
(((physicalValue - physicalMin) * (scaledMax - scaledMin)) / (physicalMax - physicalMin)) + scaledMin);
|
(((physicalValue - physicalMin) * (scaledMax - scaledMin)) / (physicalMax - physicalMin)) + scaledMin);
|
||||||
state.axes[static_cast<int>(axis)] = scaledValue;
|
state.axes[axis] = scaledValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update POV/Hat state. Assuming model described in `open`, values are:
|
// Update POV/Hat state. Assuming model described in `open`, values are:
|
||||||
@ -508,17 +508,17 @@ JoystickState JoystickImpl::update()
|
|||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
case 3:
|
case 3:
|
||||||
state.axes[static_cast<int>(Joystick::Axis::PovX)] = +100;
|
state.axes[Joystick::Axis::PovX] = +100;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
case 6:
|
case 6:
|
||||||
case 7:
|
case 7:
|
||||||
state.axes[static_cast<int>(Joystick::Axis::PovX)] = -100;
|
state.axes[Joystick::Axis::PovX] = -100;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
state.axes[static_cast<int>(Joystick::Axis::PovX)] = 0;
|
state.axes[Joystick::Axis::PovX] = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,17 +528,17 @@ JoystickState JoystickImpl::update()
|
|||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
case 7:
|
case 7:
|
||||||
state.axes[static_cast<int>(Joystick::Axis::PovY)] = +100;
|
state.axes[Joystick::Axis::PovY] = +100;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
case 5:
|
case 5:
|
||||||
state.axes[static_cast<int>(Joystick::Axis::PovY)] = -100;
|
state.axes[Joystick::Axis::PovY] = -100;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
state.axes[static_cast<int>(Joystick::Axis::PovY)] = 0;
|
state.axes[Joystick::Axis::PovY] = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user