initial commit
This commit is contained in:
+92
@@ -0,0 +1,92 @@
|
||||
#ifndef GAMEPAD_H
|
||||
#define GAMEPAD_H
|
||||
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
#include "gamepad_keys.h"
|
||||
#include <iostream>
|
||||
|
||||
/**
|
||||
* @brief A template class for a generic Gamepad.
|
||||
*
|
||||
* This class serves as a generic gamepad template. It can be specialized for specific gamepad types.
|
||||
*
|
||||
* @tparam KeysType The type of keys for the gamepad (e.g., XboxKeys, PlayStationKeys).
|
||||
*/
|
||||
template <typename KeysType>
|
||||
class Gamepad {
|
||||
public:
|
||||
std::vector<std::string> button_status_;
|
||||
/**
|
||||
* @brief Constructor for the Gamepad class.
|
||||
*
|
||||
* Initializes the gamepad with the specified UDP port for data reception.
|
||||
*
|
||||
* @param port The UDP port to use for receiving gamepad data.
|
||||
*/
|
||||
Gamepad(int port = kDefaultPort);
|
||||
|
||||
/**
|
||||
* @brief Destructor for the Gamepad class.
|
||||
*
|
||||
* This destructor stops the data thread to clean up resources when the gamepad instance is destroyed.
|
||||
*/
|
||||
virtual ~Gamepad(){
|
||||
StopDataThread();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the data thread for simulating gamepad data.
|
||||
*/
|
||||
void StartDataThread();
|
||||
|
||||
/**
|
||||
* @brief Stops the data thread.
|
||||
*/
|
||||
void StopDataThread();
|
||||
|
||||
/**
|
||||
* @brief Gets the gamepad keys.
|
||||
* @return The current gamepad keys.
|
||||
*/
|
||||
KeysType& GetKeys();
|
||||
|
||||
/**
|
||||
* @brief Sets a callback function to be called on each data update.
|
||||
* @param callback The callback function that takes an update count as an argument.
|
||||
*/
|
||||
void SetUpdateCallback(const std::function<void(uint32_t)>& callback);
|
||||
|
||||
/**
|
||||
* @brief Calculate the CRC-16 checksum for a given data buffer.
|
||||
*
|
||||
* @param data Pointer to the data buffer.
|
||||
* @param length Length of the data buffer.
|
||||
* @return The CRC-16 checksum of the data.
|
||||
*/
|
||||
uint16_t CalculateCrc16(const uint8_t* data, size_t length);
|
||||
|
||||
std::function<void(uint32_t)> updateCallback_; ///< Callback function for data updates.
|
||||
|
||||
protected:
|
||||
std::thread data_thread_; ///< Thread for generating simulated data.
|
||||
std::atomic<bool> stop_thread_; ///< Flag to signal the data thread to stop.
|
||||
mutable std::mutex mutex_; ///< Mutex for data access synchronization.
|
||||
KeysType keys_; ///< Gamepad keys.
|
||||
int port_; ///< The UDP port for data reception.
|
||||
timespec start_time_; //receive timestamp start time
|
||||
|
||||
/**
|
||||
* @brief Updates the gamepad data buffer and keys.
|
||||
*
|
||||
* @param buffer The data buffer to be updated.
|
||||
* @param keys The keys to be updated.
|
||||
* @return True if the data is valid and updated, false otherwise.
|
||||
*/
|
||||
virtual bool UpdateData(std::vector<uint8_t>& buffer, KeysType& keys) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
#ifndef GAMEPAD_KEYS_H
|
||||
#define GAMEPAD_KEYS_H
|
||||
|
||||
/**
|
||||
* @file gamepad_keys.h
|
||||
* @brief Defines structures and constants related to gamepad keys and data.
|
||||
*/
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cmath>
|
||||
#include <array>
|
||||
|
||||
/** @brief Size of the header in bytes. */
|
||||
const size_t kHeaderSize = 2;
|
||||
|
||||
/** @brief Total number of channels for gamepad keys. */
|
||||
const size_t kChannlSize = 16;
|
||||
|
||||
/** @brief Number of channels dedicated to axis values in the gamepad data. */
|
||||
const size_t kAxisChannlSize = 4;
|
||||
|
||||
/** @brief Number of channels dedicated to axis buttons in the gamepad data. */
|
||||
const size_t kAxisButtonSize = 2;
|
||||
|
||||
const size_t kSwitchKeysSize = 4;
|
||||
|
||||
/** @brief Maximum range of the joystick axis values. */
|
||||
const uint16_t kJoystickRange = 1000;
|
||||
|
||||
/** @brief Default UDP port for gamepad data reception. */
|
||||
const uint16_t kDefaultPort = 12121;
|
||||
|
||||
/** @brief Header bytes for identifying gamepad data. */
|
||||
const unsigned char kHeader[kHeaderSize] = {0x55, 0x66};
|
||||
|
||||
const size_t kRetroidButtonSize = 10;
|
||||
const size_t kSkydroidButtonSize = 8;
|
||||
|
||||
/** @brief Enumerates different types of gamepads. */
|
||||
enum class GamepadType {
|
||||
kRetroid = 1, /**< RETROID gamepad type. */
|
||||
kSkydroid = 2,
|
||||
};
|
||||
|
||||
/** @brief Enumerates the status of keys, whether pressed or released. */
|
||||
enum class KeyStatus {
|
||||
kReleased = 0, /**< Key is released. */
|
||||
kPressed = 1, /**< Key is pressed. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Structure representing the keys of a Retroid gamepad.
|
||||
*/
|
||||
struct RetroidKeys {
|
||||
double time_stamp;
|
||||
union {
|
||||
uint16_t value; /**< Union to represent the keys as a single value. */
|
||||
struct {
|
||||
uint8_t R1 : 1; /**< R1 button. */
|
||||
uint8_t L1 : 1; /**< L1 button. */
|
||||
uint8_t start : 1; /**< Start button. */
|
||||
uint8_t select : 1; /**< Select button. */
|
||||
|
||||
uint8_t R2 : 1; /**< R2 button. */
|
||||
uint8_t L2 : 1; /**< L2 button. */
|
||||
|
||||
uint8_t A : 1; /**< A button. */
|
||||
uint8_t B : 1; /**< B button. */
|
||||
uint8_t X : 1; /**< X button. */
|
||||
uint8_t Y : 1; /**< Y button. */
|
||||
|
||||
uint8_t left : 1; /**< Left button on the directional pad. */
|
||||
uint8_t right : 1; /**< Right button on the directional pad. */
|
||||
uint8_t up : 1; /**< Up button on the directional pad. */
|
||||
uint8_t down : 1; /**< Down button on the directional pad. */
|
||||
|
||||
uint8_t left_axis_button : 1; /**< Left analog stick button. */
|
||||
uint8_t right_axis_button : 1; /**< Right analog stick button. */
|
||||
};
|
||||
};
|
||||
union {
|
||||
float axis_values[kAxisChannlSize]; /**< Array representing axis values. */
|
||||
struct {
|
||||
float left_axis_x; /**< X-axis value of the left analog stick. */
|
||||
float left_axis_y; /**< Y-axis value of the left analog stick. */
|
||||
float right_axis_x; /**< X-axis value of the right analog stick. */
|
||||
float right_axis_y; /**< Y-axis value of the right analog stick. */
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Structure representing the keys of a Skydroid Gamepad.
|
||||
*/
|
||||
struct SkydroidKeys {
|
||||
double time_stamp;
|
||||
union {
|
||||
uint8_t keys_value; /**< Union to represent the button as a single value. */
|
||||
struct {
|
||||
uint8_t C : 1; /**< C button. */
|
||||
uint8_t right : 1; /**< right button. */
|
||||
uint8_t D : 1; /**< D button. */
|
||||
uint8_t E : 1; /**< E button. */
|
||||
uint8_t F : 1; /**< F button. */
|
||||
uint8_t reserved : 1; /**< reserved. */
|
||||
uint8_t A : 1; /**< A button. */
|
||||
uint8_t B : 1; /**< B button. */
|
||||
};
|
||||
};
|
||||
|
||||
union {
|
||||
uint8_t switch_keys[kSwitchKeysSize]; /**< Array representing switch_keys values. */
|
||||
struct {
|
||||
|
||||
uint8_t sw1 ; /**< switch_key1 */
|
||||
uint8_t sw2 ; /**< switch_key2 */
|
||||
uint8_t sw3 ; /**< switch_key3 */
|
||||
uint8_t sw4 ; /**< switch_key4 */
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
union {
|
||||
float axis_values[kAxisChannlSize]; /**< Array representing axis values. */
|
||||
struct {
|
||||
float left_axis_x; /**< X-axis value of the left analog stick. */
|
||||
float left_axis_y; /**< Y-axis value of the left analog stick. */
|
||||
float right_axis_x; /**< X-axis value of the right analog stick. */
|
||||
float right_axis_y; /**< Y-axis value of the right analog stick. */
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
/**
|
||||
* @brief Structure representing the complete gamepad data packet.
|
||||
*/
|
||||
struct RetroidGamepadData {
|
||||
uint8_t stx[kHeaderSize]; /**< Start-of-text bytes for identifying the start of data. */
|
||||
uint8_t ctrl; /**< Control byte for additional flags or information. */
|
||||
uint16_t data_len; /**< Length of the data in the packet. */
|
||||
uint16_t seq; /**< Sequence number for tracking packet order or identifying duplicates. */
|
||||
uint8_t id; /**< Identifier for the type of gamepad. */
|
||||
uint16_t crc16; /**< CRC-16 checksum for data integrity verification. */
|
||||
union {
|
||||
uint8_t data[kChannlSize * sizeof(uint16_t)]; /**< Array representing raw data channels. */
|
||||
struct {
|
||||
uint16_t buttons[kRetroidButtonSize]; /**< Array representing button values. */
|
||||
int16_t left_axis_x; /**< X-axis value of the left analog stick. */
|
||||
int16_t left_axis_y; /**< Y-axis value of the left analog stick. */
|
||||
int16_t right_axis_x; /**< X-axis value of the right analog stick. */
|
||||
int16_t right_axis_y; /**< Y-axis value of the right analog stick. */
|
||||
uint16_t axis_buttons[kAxisButtonSize]; /**< Array representing axis button values. */
|
||||
};
|
||||
};
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
/**
|
||||
* @brief Structure representing the complete Gamepad data packet.
|
||||
*/
|
||||
struct SkydroidGamepadData {
|
||||
uint8_t stx[kHeaderSize]; /**< Start-of-text bytes for identifying the start of data. */
|
||||
uint8_t ctrl; /**< Control byte for additional flags or information. */
|
||||
uint16_t data_len; /**< Length of the data in the packet. */
|
||||
uint16_t seq; /**< Sequence number for tracking packet order or identifying duplicates. */
|
||||
uint8_t id; /**< Identifier for the type of Gamepad. */
|
||||
uint16_t crc16; /**< CRC-16 checksum for data integrity verification. */
|
||||
union {
|
||||
uint8_t data[kChannlSize * sizeof(uint16_t)]; /**< Array representing raw data channels. */
|
||||
struct {
|
||||
int16_t right_axis_x; /**< X-axis value of the right analog stick. */
|
||||
int16_t right_axis_y; /**< Y-axis value of the right analog stick. */
|
||||
int16_t left_axis_y; /**< Y-axis value of the left analog stick. */
|
||||
int16_t left_axis_x; /**< X-axis value of the left analog stick. */
|
||||
uint16_t switch_keys[kSwitchKeysSize]; /**< Array representing switch_keys values. */
|
||||
uint16_t buttons[kSkydroidButtonSize]; /**< Array representing button values. */
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
#ifndef RETROID_GAMEPAD_H
|
||||
#define RETROID_GAMEPAD_H
|
||||
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
#include "gamepad.h"
|
||||
|
||||
/**
|
||||
* @brief A specialized class for RETROID gamepad.
|
||||
*
|
||||
* This class specializes the generic Gamepad class for RETROID gamepad.
|
||||
*/
|
||||
class RetroidGamepad : public Gamepad<RetroidKeys> {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor for the RetroidGamepad class.
|
||||
*
|
||||
* Initializes the Retroid gamepad with the specified UDP port for data reception.
|
||||
*
|
||||
* @param port The UDP port to use for receiving gamepad data.
|
||||
*/
|
||||
RetroidGamepad(int port = kDefaultPort);
|
||||
|
||||
// /**
|
||||
// * @brief Overloaded output stream operator for RetroidGamepad.
|
||||
// *
|
||||
// * Allows printing RetroidGamepad information to an output stream.
|
||||
// *
|
||||
// * @param o The output stream.
|
||||
// * @param is The RetroidGamepad object.
|
||||
// * @return Reference to the output stream.
|
||||
// */
|
||||
// friend std::ostream& operator<<(std::ostream& o, RetroidGamepad& is);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Updates the RETROID gamepad data buffer and keys.
|
||||
*
|
||||
* @param buffer The data buffer to be updated.
|
||||
* @param keys The RETROID gamepad keys to be updated.
|
||||
* @return True if the data is valid and updated, false otherwise.
|
||||
*/
|
||||
bool UpdateData(std::vector<uint8_t>& buffer, RetroidKeys& keys) override;
|
||||
|
||||
/**
|
||||
* @brief Checks if the received data from the RETROID gamepad is valid.
|
||||
*
|
||||
* @param data The gamepad data to be validated.
|
||||
* @return True if the data is valid, false otherwise.
|
||||
*/
|
||||
bool DataIsValid(const RetroidGamepadData& data);
|
||||
};
|
||||
|
||||
#endif // RETROID_GAMEPAD_H
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
#ifndef SKYDROID_GAMEPAD_H
|
||||
#define SKYDROID_GAMEPAD_H
|
||||
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
#include "gamepad.h"
|
||||
|
||||
/**
|
||||
* @brief A specialized class for Skydroid gamepad.
|
||||
*
|
||||
* This class specializes the generic Gamepad class for Skydroid gamepad.
|
||||
*/
|
||||
class SkydroidGamepad : public Gamepad<SkydroidKeys> {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor for the SkydroidGamepad class.
|
||||
*
|
||||
* Initializes the Skydroid gamepad with the specified UDP port for data reception.
|
||||
*
|
||||
* @param port The UDP port to use for receiving gamepad data.
|
||||
*/
|
||||
SkydroidGamepad(int port = kDefaultPort);
|
||||
|
||||
// /**
|
||||
// * @brief Overloaded output stream operator for SkydroidGamepad.
|
||||
// *
|
||||
// * Allows printing SkydroidGamepad information to an output stream.
|
||||
// *
|
||||
// * @param o The output stream.
|
||||
// * @param is The SkydroidGamepad object.
|
||||
// * @return Reference to the output stream.
|
||||
// */
|
||||
// friend std::ostream& operator<<(std::ostream& o, SkydroidGamepad& is);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Updates the Skydroid gamepad data buffer and keys.
|
||||
*
|
||||
* @param buffer The data buffer to be updated.
|
||||
* @param keys The Skydroid gamepad keys to be updated.
|
||||
* @return True if the data is valid and updated, false otherwise.
|
||||
*/
|
||||
bool UpdateData(std::vector<uint8_t>& buffer, SkydroidKeys& keys) override;
|
||||
|
||||
/**
|
||||
* @brief Checks if the received data from the Skydroid gamepad is valid.
|
||||
*
|
||||
* @param data The gamepad data to be validated.
|
||||
* @return True if the data is valid, false otherwise.
|
||||
*/
|
||||
bool DataIsValid(const SkydroidGamepadData& data);
|
||||
};
|
||||
|
||||
#endif // SKYDROID_GAMEPAD_H
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
#ifndef UDP_RECEIVER_H
|
||||
#define UDP_RECEIVER_H
|
||||
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
/**
|
||||
* @brief The UdpReceiver class for receiving UDP data.
|
||||
*/
|
||||
class UdpReceiver {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor for UdpReceiver.
|
||||
* @param port The port to listen for UDP data.
|
||||
*/
|
||||
UdpReceiver(int port);
|
||||
|
||||
/**
|
||||
* @brief Receive UDP data.
|
||||
* @return A vector containing received data as uint8_t.
|
||||
*/
|
||||
std::vector<uint8_t> ReceiveData();
|
||||
|
||||
/**
|
||||
* @brief Destructor for UdpReceiver.
|
||||
*/
|
||||
~UdpReceiver();
|
||||
|
||||
private:
|
||||
int socket_fd_;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user