Initial re-upload of spice2x-24-08-24
This commit is contained in:
131
external/stepmaniax-sdk/sdk/Windows/SMXDeviceConnection.h
vendored
Normal file
131
external/stepmaniax-sdk/sdk/Windows/SMXDeviceConnection.h
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
#ifndef SMXDevice_H
|
||||
#define SMXDevice_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <functional>
|
||||
using namespace std;
|
||||
|
||||
#include "Helpers.h"
|
||||
|
||||
namespace SMX
|
||||
{
|
||||
|
||||
struct SMXDeviceInfo
|
||||
{
|
||||
// If true, this controller is set to player 2.
|
||||
bool m_bP2 = false;
|
||||
|
||||
// This device's serial number.
|
||||
char m_Serial[33];
|
||||
|
||||
// This device's firmware version (normally 1).
|
||||
uint16_t m_iFirmwareVersion;
|
||||
};
|
||||
|
||||
// Low-level SMX device handling.
|
||||
class SMXDeviceConnection
|
||||
{
|
||||
public:
|
||||
static shared_ptr<SMXDeviceConnection> Create();
|
||||
SMXDeviceConnection(shared_ptr<SMXDeviceConnection> &pSelf);
|
||||
~SMXDeviceConnection();
|
||||
|
||||
bool Open(shared_ptr<AutoCloseHandle> DeviceHandle, wstring &error);
|
||||
|
||||
void Close();
|
||||
|
||||
// Get the device handle opened by Open(), or NULL if we're not open.
|
||||
shared_ptr<AutoCloseHandle> GetDeviceHandle() const { return m_hDevice; }
|
||||
|
||||
void Update(wstring &sError);
|
||||
|
||||
// Devices are inactive by default, and will just read device info and then idle. We'll
|
||||
// process input state packets, but we won't send any commands to the device or process
|
||||
// any commands from it. It's safe to have a device open but inactive if it's being used
|
||||
// by another application.
|
||||
void SetActive(bool bActive);
|
||||
bool GetActive() const { return m_bActive; }
|
||||
|
||||
bool IsConnected() const { return m_hDevice != nullptr; }
|
||||
bool IsConnectedWithDeviceInfo() const { return m_hDevice != nullptr && m_bGotInfo; }
|
||||
SMXDeviceInfo GetDeviceInfo() const { return m_DeviceInfo; }
|
||||
|
||||
// Read from the read buffer. This only returns data that we've already read, so there aren't
|
||||
// any errors to report here.
|
||||
bool ReadPacket(string &out);
|
||||
|
||||
// Send a command. This must be a single complete command: partial writes and multiple
|
||||
// commands in a call aren't allowed.
|
||||
void SendCommand(const string &cmd, function<void(string response)> pComplete=nullptr);
|
||||
|
||||
uint16_t GetInputState() const { return m_iInputState; }
|
||||
|
||||
private:
|
||||
void RequestDeviceInfo(function<void(string response)> pComplete = nullptr);
|
||||
|
||||
void CheckReads(wstring &error);
|
||||
void BeginAsyncRead(wstring &error);
|
||||
void CheckWrites(wstring &error);
|
||||
void HandleUsbPacket(const string &buf);
|
||||
|
||||
weak_ptr<SMXDeviceConnection> m_pSelf;
|
||||
shared_ptr<AutoCloseHandle> m_hDevice;
|
||||
|
||||
bool m_bActive = false;
|
||||
|
||||
// After we open a device, we request basic info. Once we get it, this is set to true.
|
||||
bool m_bGotInfo = false;
|
||||
|
||||
list<string> m_sReadBuffers;
|
||||
string m_sCurrentReadBuffer;
|
||||
|
||||
struct PendingCommandPacket {
|
||||
PendingCommandPacket();
|
||||
|
||||
string sData;
|
||||
};
|
||||
|
||||
// Commands that are waiting to be sent:
|
||||
struct PendingCommand {
|
||||
PendingCommand();
|
||||
|
||||
list<shared_ptr<PendingCommandPacket>> m_Packets;
|
||||
|
||||
// The overlapped struct for writing this command's packets. m_bWriting is true
|
||||
// if we're waiting for the write to complete.
|
||||
OVERLAPPED m_Overlapped;
|
||||
bool m_bWriting = false;
|
||||
|
||||
// This is only called if m_bWaitForResponse if true. Otherwise, we send the command
|
||||
// and forget about it. If the command has a response, it'll be in buf.
|
||||
function<void(string response)> m_pComplete;
|
||||
|
||||
// If true, once we send this command we won't send any other commands until we get
|
||||
// a response.
|
||||
bool m_bIsDeviceInfoCommand = false;
|
||||
|
||||
// The SMX::GetMonotonicTime when we started sending this command.
|
||||
double m_fSentAt = 0;
|
||||
};
|
||||
list<shared_ptr<PendingCommand>> m_aPendingCommands;
|
||||
|
||||
// If set, we've sent a command out of m_aPendingCommands and we're waiting for a response. We
|
||||
// can't send another command until the previous one has completed.
|
||||
shared_ptr<PendingCommand> m_pCurrentCommand = nullptr;
|
||||
|
||||
// We always have a read in progress.
|
||||
OVERLAPPED overlapped_read;
|
||||
char overlapped_read_buffer[64];
|
||||
|
||||
uint16_t m_iInputState = 0;
|
||||
|
||||
// The current device info. We retrieve this when we connect.
|
||||
SMXDeviceInfo m_DeviceInfo;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user