Use optionals to represent empty states

This commit is contained in:
Chris Thrasher 2024-10-16 18:12:09 -06:00
parent 18eb48b13e
commit fe5456ee78
No known key found for this signature in database
GPG Key ID: 56FB686C9DFC8E2C
2 changed files with 30 additions and 33 deletions

View File

@ -519,8 +519,8 @@ bool JoystickImpl::openDInput(unsigned int index)
// Initialize DirectInput members // Initialize DirectInput members
m_device = nullptr; m_device = nullptr;
m_axes.fill(-1); m_axes.fill(std::nullopt);
m_buttons.fill(-1); m_buttons.fill(std::nullopt);
m_deviceCaps = {}; m_deviceCaps = {};
m_deviceCaps.dwSize = sizeof(DIDEVCAPS); m_deviceCaps.dwSize = sizeof(DIDEVCAPS);
@ -711,9 +711,9 @@ bool JoystickImpl::openDInput(unsigned int index)
} }
// Set device's axis mode to absolute if the device reports having at least one axis // Set device's axis mode to absolute if the device reports having at least one axis
for (const int axis : m_axes) for (const std::optional axis : m_axes)
{ {
if (axis != -1) if (axis.has_value())
{ {
property = {}; property = {};
property.diph.dwSize = sizeof(property); property.diph.dwSize = sizeof(property);
@ -847,17 +847,15 @@ JoystickCaps JoystickImpl::getCapabilitiesDInput() const
// Count how many buttons have valid offsets // Count how many buttons have valid offsets
caps.buttonCount = 0; caps.buttonCount = 0;
for (const int button : m_buttons) for (const std::optional button : m_buttons)
{ if (button.has_value())
if (button != -1)
++caps.buttonCount; ++caps.buttonCount;
}
// 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)
{ {
const auto axis = static_cast<Joystick::Axis>(i); const auto axis = static_cast<Joystick::Axis>(i);
caps.axes[axis] = (m_axes[axis] != -1); caps.axes[axis] = m_axes[axis].has_value();
} }
return caps; return caps;
@ -911,7 +909,7 @@ JoystickState JoystickImpl::updateDInputBuffered()
for (unsigned int j = 0; j < Joystick::AxisCount; ++j) for (unsigned int j = 0; j < Joystick::AxisCount; ++j)
{ {
const auto axis = static_cast<Joystick::Axis>(j); const auto axis = static_cast<Joystick::Axis>(j);
if (m_axes[axis] == static_cast<int>(events[i].dwOfs)) if (m_axes[axis] == events[i].dwOfs)
{ {
if ((axis == Joystick::Axis::PovX) || (axis == Joystick::Axis::PovY)) if ((axis == Joystick::Axis::PovX) || (axis == Joystick::Axis::PovY))
{ {
@ -945,12 +943,10 @@ JoystickState JoystickImpl::updateDInputBuffered()
continue; continue;
// Get the current state of each button // Get the current state of each button
for (unsigned int j = 0; j < Joystick::ButtonCount; ++j) for (std::size_t j = 0; j < m_buttons.size(); ++j)
{ if (m_buttons[j] == events[i].dwOfs)
if (m_buttons[j] == static_cast<int>(events[i].dwOfs))
m_state.buttons[j] = (events[i].dwData != 0); m_state.buttons[j] = (events[i].dwData != 0);
} }
}
m_state.connected = true; m_state.connected = true;
@ -1001,12 +997,12 @@ JoystickState JoystickImpl::updateDInputPolled()
for (unsigned int i = 0; i < Joystick::AxisCount; ++i) for (unsigned int i = 0; i < Joystick::AxisCount; ++i)
{ {
const auto axis = static_cast<Joystick::Axis>(i); const auto axis = static_cast<Joystick::Axis>(i);
if (m_axes[axis] != -1) if (m_axes[axis].has_value())
{ {
if ((axis == Joystick::Axis::PovX) || (axis == 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[axis])); *reinterpret_cast<const DWORD*>(reinterpret_cast<const char*>(&joystate) + *m_axes[axis]));
if (value != 0xFFFF) if (value != 0xFFFF)
{ {
@ -1024,7 +1020,7 @@ JoystickState JoystickImpl::updateDInputPolled()
else else
{ {
state.axes[axis] = (static_cast<float>(*reinterpret_cast<const LONG*>( state.axes[axis] = (static_cast<float>(*reinterpret_cast<const LONG*>(
reinterpret_cast<const char*>(&joystate) + m_axes[axis])) + reinterpret_cast<const char*>(&joystate) + *m_axes[axis])) +
0.5f) * 0.5f) *
100.f / 32767.5f; 100.f / 32767.5f;
} }
@ -1038,9 +1034,9 @@ JoystickState JoystickImpl::updateDInputPolled()
// Get the current state of each button // Get the current state of each button
for (unsigned int i = 0; i < Joystick::ButtonCount; ++i) for (unsigned int i = 0; i < Joystick::ButtonCount; ++i)
{ {
if (m_buttons[i] != -1) if (m_buttons[i].has_value())
{ {
const BYTE value = *reinterpret_cast<const BYTE*>(reinterpret_cast<const char*>(&joystate) + m_buttons[i]); const BYTE value = *reinterpret_cast<const BYTE*>(reinterpret_cast<const char*>(&joystate) + *m_buttons[i]);
state.buttons[i] = ((value & 0x80) != 0); state.buttons[i] = ((value & 0x80) != 0);
} }
@ -1099,10 +1095,10 @@ BOOL CALLBACK JoystickImpl::deviceObjectEnumerationCallback(const DIDEVICEOBJECT
joystick.m_axes[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[Joystick::Axis::U] == -1) if (!joystick.m_axes[Joystick::Axis::U].has_value())
joystick.m_axes[Joystick::Axis::U] = DIJOFS_SLIDER(0); joystick.m_axes[Joystick::Axis::U] = static_cast<unsigned int>(DIJOFS_SLIDER(0));
else else
joystick.m_axes[Joystick::Axis::V] = DIJOFS_SLIDER(1); joystick.m_axes[Joystick::Axis::V] = static_cast<unsigned int>(DIJOFS_SLIDER(1));
} }
else else
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
@ -1128,7 +1124,7 @@ BOOL CALLBACK JoystickImpl::deviceObjectEnumerationCallback(const DIDEVICEOBJECT
// POVs // POVs
if (deviceObjectInstance->guidType == guids::GUID_POV) if (deviceObjectInstance->guidType == guids::GUID_POV)
{ {
if (joystick.m_axes[Joystick::Axis::PovX] == -1) if (!joystick.m_axes[Joystick::Axis::PovX].has_value())
{ {
joystick.m_axes[Joystick::Axis::PovX] = DIJOFS_POV(0); joystick.m_axes[Joystick::Axis::PovX] = DIJOFS_POV(0);
joystick.m_axes[Joystick::Axis::PovY] = DIJOFS_POV(0); joystick.m_axes[Joystick::Axis::PovY] = DIJOFS_POV(0);
@ -1142,9 +1138,9 @@ BOOL CALLBACK JoystickImpl::deviceObjectEnumerationCallback(const DIDEVICEOBJECT
// Buttons // Buttons
for (unsigned int i = 0; i < Joystick::ButtonCount; ++i) for (unsigned int i = 0; i < Joystick::ButtonCount; ++i)
{ {
if (joystick.m_buttons[i] == -1) if (!joystick.m_buttons[i].has_value())
{ {
joystick.m_buttons[i] = DIJOFS_BUTTON(static_cast<int>(i)); *joystick.m_buttons[i] = DIJOFS_BUTTON(static_cast<int>(i));
break; break;
} }
} }

View File

@ -32,6 +32,7 @@
#include <dinput.h> #include <dinput.h>
#include <mmsystem.h> #include <mmsystem.h>
#include <optional>
namespace sf::priv namespace sf::priv
@ -217,8 +218,8 @@ private:
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
EnumArray<Joystick::Axis, int, Joystick::AxisCount> m_axes{}; //!< Offsets to the bytes containing the axes states, -1 if not available EnumArray<Joystick::Axis, std::optional<unsigned int>, Joystick::AxisCount> m_axes{}; //!< Offsets to the bytes containing the axes states
std::array<int, Joystick::ButtonCount> m_buttons{}; //!< Offsets to the bytes containing the button states, -1 if not available std::array<std::optional<unsigned int>, Joystick::ButtonCount> m_buttons{}; //!< Offsets to the bytes containing the button states
Joystick::Identification m_identification; //!< Joystick identification Joystick::Identification m_identification; //!< Joystick identification
JoystickState m_state; //!< Buffered joystick state JoystickState m_state; //!< Buffered joystick state
bool m_buffered{}; //!< `true` if the device uses buffering, `false` if the device uses polling bool m_buffered{}; //!< `true` if the device uses buffering, `false` if the device uses polling