Skip to content
Permalink
Browse files

InputCommon/DualShockUDPClient: Make use of std::array where applicable

Provides the same semantics of a C array, but is much nicer to work
with.

Notably, it makes all cases of performing comparisons with said arrays
significantly less reading-involved.
  • Loading branch information
lioncash committed Nov 22, 2019
1 parent 67097b4 commit 278d03f737fe3bf1e4ca2b9b1ea33bbd7e94aa8f
@@ -4,8 +4,11 @@

#include "InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPClient.h"

#include <algorithm>
#include <array>
#include <chrono>
#include <cstring>
#include <mutex>
#include <tuple>

#include <SFML/Network/SocketSelector.hpp>
#include <SFML/Network/UdpSocket.hpp>
@@ -18,7 +21,6 @@
#include "Common/Random.h"
#include "Common/Thread.h"
#include "Core/CoreTiming.h"
#include "Core/HW/SystemTimers.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h"
#include "InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPProto.h"

@@ -136,16 +138,15 @@ static std::chrono::steady_clock::time_point s_next_listports;
static std::thread s_hotplug_thread;
static Common::Flag s_hotplug_thread_running;
static std::mutex s_port_info_mutex;
static Proto::MessageType::PortInfo s_port_info[Proto::PORT_COUNT];
static std::array<Proto::MessageType::PortInfo, Proto::PORT_COUNT> s_port_info;
static sf::UdpSocket s_socket;

static bool IsSameController(const Proto::MessageType::PortInfo& a,
const Proto::MessageType::PortInfo& b)
{
// compare everything but battery_status
return a.pad_id == b.pad_id && a.pad_state == b.pad_state && a.model == b.model &&
a.connection_type == b.connection_type &&
memcmp(a.pad_mac_address, b.pad_mac_address, sizeof a.pad_mac_address) == 0;
return std::tie(a.pad_id, a.pad_state, a.model, a.connection_type, a.pad_mac_address) ==
std::tie(b.pad_id, b.pad_state, b.model, b.connection_type, b.pad_mac_address);
}

static sf::Socket::Status ReceiveWithTimeout(sf::UdpSocket& socket, void* data, std::size_t size,
@@ -176,10 +177,7 @@ static void HotplugThreadFunc()
Proto::Message<Proto::MessageType::ListPorts> msg(s_client_uid);
auto& list_ports = msg.m_message;
list_ports.pad_request_count = 4;
list_ports.pad_id[0] = 0;
list_ports.pad_id[1] = 1;
list_ports.pad_id[2] = 2;
list_ports.pad_id[3] = 3;
list_ports.pad_id = {0, 1, 2, 3};
msg.Finish();
if (s_socket.send(&list_ports, sizeof list_ports, s_server_address, s_server_port) !=
sf::Socket::Status::Done)
@@ -246,10 +244,10 @@ static void Restart()

s_client_uid = Common::Random::GenerateValue<u32>();
s_next_listports = std::chrono::steady_clock::time_point::min();
for (int port_index = 0; port_index < Proto::PORT_COUNT; port_index++)
for (size_t port_index = 0; port_index < s_port_info.size(); port_index++)
{
s_port_info[port_index] = {};
s_port_info[port_index].pad_id = port_index;
s_port_info[port_index].pad_id = static_cast<u8>(port_index);
}

PopulateDevices(); // remove devices
@@ -286,11 +284,14 @@ void PopulateDevices()
[](const auto* dev) { return dev->GetSource() == "DSUClient"; });

std::lock_guard<std::mutex> lock(s_port_info_mutex);
for (int port_index = 0; port_index < Proto::PORT_COUNT; port_index++)
for (size_t port_index = 0; port_index < s_port_info.size(); port_index++)
{
Proto::MessageType::PortInfo port_info = s_port_info[port_index];
if (port_info.pad_state == Proto::DsState::Connected)
g_controller_interface.AddDevice(std::make_shared<Device>(port_info.model, port_index));
const Proto::MessageType::PortInfo& port_info = s_port_info[port_index];
if (port_info.pad_state != Proto::DsState::Connected)
continue;

g_controller_interface.AddDevice(
std::make_shared<Device>(port_info.model, static_cast<int>(port_index)));
}
}

@@ -4,6 +4,8 @@

#pragma once

#include <array>
#include <cstring>
#include <optional>

#include <zlib.h>
@@ -17,12 +19,12 @@ namespace ciface::DualShockUDPClient::Proto
//
// WARNING: Little endian host assumed

static constexpr u16 CEMUHOOK_PROTOCOL_VERSION = 1001;
constexpr u16 CEMUHOOK_PROTOCOL_VERSION = 1001;

static constexpr int PORT_COUNT = 4;
constexpr int PORT_COUNT = 4;

static constexpr char CLIENT[] = "DSUC";
static constexpr char SERVER[] = "DSUS";
constexpr std::array<u8, 4> CLIENT{'D', 'S', 'U', 'C'};
constexpr std::array<u8, 4> SERVER{'D', 'S', 'U', 'S'};

#pragma pack(push, 1)

@@ -69,7 +71,7 @@ enum RegisterFlags : u8

struct MessageHeader
{
u8 source[4];
std::array<u8, 4> source;
u16 protocol_version;
u16 message_length; // actually message size minus header size
u32 crc32;
@@ -101,7 +103,7 @@ struct VersionResponse
MessageHeader header;
u32 message_type;
u16 max_protocol_version;
u8 padding[2];
std::array<u8, 2> padding;
};

struct ListPorts
@@ -111,7 +113,7 @@ struct ListPorts
MessageHeader header;
u32 message_type;
u32 pad_request_count;
u8 pad_id[4];
std::array<u8, 4> pad_id;
};

struct PortInfo
@@ -124,7 +126,7 @@ struct PortInfo
DsState pad_state;
DsModel model;
DsConnection connection_type;
u8 pad_mac_address[6];
std::array<u8, 6> pad_mac_address;
DsBattery battery_status;
u8 padding;
};
@@ -137,7 +139,7 @@ struct PadDataRequest
u32 message_type;
RegisterFlags register_flags;
u8 pad_id_to_register;
u8 mac_address_to_register[6];
std::array<u8, 6> mac_address_to_register;
};

struct PadDataResponse
@@ -150,7 +152,7 @@ struct PadDataResponse
DsState pad_state;
DsModel model;
DsConnection connection_type;
u8 pad_mac_address[6];
std::array<u8, 6> pad_mac_address;
DsBattery battery_status;
u8 active;
u32 hid_packet_counter;
@@ -224,11 +226,11 @@ static inline u32 CRC32(const void* buffer, unsigned length)
template <typename MsgType>
struct Message
{
Message() : m_message{} {}
Message() = default;

explicit Message(u32 source_uid) : m_message{}
explicit Message(u32 source_uid)
{
memcpy((char*)m_message.header.source, MsgType::FROM, sizeof(m_message.header.source));
m_message.header.source = MsgType::FROM;
m_message.header.protocol_version = CEMUHOOK_PROTOCOL_VERSION;
m_message.header.message_length = sizeof(*this) - sizeof(m_message.header);
m_message.header.source_uid = source_uid;
@@ -253,7 +255,7 @@ struct Message
}
if (m_message.header.protocol_version > CEMUHOOK_PROTOCOL_VERSION)
return std::nullopt;
if (memcmp(m_message.header.source, ToMsgType::FROM, sizeof(m_message.header.source)))
if (m_message.header.source != ToMsgType::FROM)
return std::nullopt;
if (m_message.message_type != ToMsgType::TYPE)
return std::nullopt;
@@ -265,7 +267,7 @@ struct Message
return tomsg;
}

MsgType m_message;
MsgType m_message{};
};

#pragma pack(pop)

0 comments on commit 278d03f

Please sign in to comment.
You can’t perform that action at this time.