full IOKit support for smash adapter

This commit is contained in:
Jack Andersen
2015-04-23 14:24:15 -10:00
parent 92e7c3fb04
commit 4377109346
13 changed files with 627 additions and 71 deletions

View File

@@ -1,20 +1,35 @@
#ifndef CDEVICEBASE
#define CDEVICEBASE
class CDeviceToken;
class IHIDDevice;
#include <stdint.h>
#include <stdlib.h>
class CDeviceBase
{
CDeviceToken* m_token;
IHIDDevice* m_hidDev;
friend CDeviceToken;
friend class CDeviceToken;
friend class CHIDDeviceIOKit;
friend class CHIDDeviceUdev;
friend class CHIDDeviceWin32;
class CDeviceToken* m_token;
class IHIDDevice* m_hidDev;
void _deviceDisconnected();
public:
CDeviceBase(CDeviceToken* token, IHIDDevice* hidDev);
CDeviceBase(CDeviceToken* token);
virtual ~CDeviceBase();
void closeDevice();
virtual void deviceDisconnected()=0;
/* Low-Level API */
bool sendInterruptTransfer(uint8_t pipe, const uint8_t* data, size_t length);
size_t receiveInterruptTransfer(uint8_t pipe, uint8_t* data, size_t length);
virtual void transferCycle() {};
/* High-Level API */
bool sendReport(const uint8_t* data, size_t length);
virtual size_t receiveReport(uint8_t* data, size_t length) {};
};
#endif // CDEVICEBASE

View File

@@ -33,9 +33,9 @@ private:
/* Friend methods for platform-listener to find/insert/remove
* tokens with type-filtering */
inline bool _hasToken(TDeviceHandle handle)
inline bool _hasToken(const std::string& path)
{
auto preCheck = m_tokens.find(handle);
auto preCheck = m_tokens.find(path);
if (preCheck != m_tokens.end())
return true;
return false;
@@ -44,14 +44,14 @@ private:
{
if (BooDeviceMatchToken(token, m_types)) {
m_tokensLock.lock();
TInsertedDeviceToken inseredTok = m_tokens.insert(std::make_pair(token.getDeviceHandle(), std::move(token)));
TInsertedDeviceToken inseredTok = m_tokens.insert(std::make_pair(token.getDevicePath(), std::move(token)));
m_tokensLock.unlock();
deviceConnected(inseredTok.first->second);
}
}
inline void _removeToken(TDeviceHandle handle)
inline void _removeToken(const std::string& path)
{
auto preCheck = m_tokens.find(handle);
auto preCheck = m_tokens.find(path);
if (preCheck != m_tokens.end())
{
CDeviceToken& tok = preCheck->second;

View File

@@ -5,20 +5,13 @@
#include "CDeviceBase.hpp"
#include "DeviceClasses.hpp"
#if __APPLE__
#include <IOKit/hid/IOHIDLib.h>
typedef IOHIDDeviceRef TDeviceHandle;
#elif _WIN32
#elif __linux__
#endif
class CDeviceToken
{
unsigned m_vendorId;
unsigned m_productId;
std::string m_vendorName;
std::string m_productName;
TDeviceHandle m_devHandle;
std::string m_devPath;
friend class CDeviceBase;
CDeviceBase* m_connectedDev;
@@ -34,8 +27,8 @@ class CDeviceToken
public:
CDeviceToken(const CDeviceToken&) = delete;
CDeviceToken(CDeviceToken&&) = default;
inline CDeviceToken(unsigned vid, unsigned pid, const char* vname, const char* pname, TDeviceHandle handle)
: m_vendorId(vid), m_productId(pid), m_devHandle(handle), m_connectedDev(NULL)
inline CDeviceToken(unsigned vid, unsigned pid, const char* vname, const char* pname, const char* path)
: m_vendorId(vid), m_productId(pid), m_devPath(path), m_connectedDev(NULL)
{
if (vname)
m_vendorName = vname;
@@ -47,19 +40,19 @@ public:
inline unsigned getProductId() const {return m_productId;}
inline const std::string& getVendorName() const {return m_vendorName;}
inline const std::string& getProductName() const {return m_productName;}
inline TDeviceHandle getDeviceHandle() const {return m_devHandle;}
inline const std::string& getDevicePath() const {return m_devPath;}
inline bool isDeviceOpen() const {return m_connectedDev;}
inline CDeviceBase* openAndGetDevice()
{
if (!m_connectedDev)
m_connectedDev = BooDeviceNew(this);
m_connectedDev = BooDeviceNew(*this);
return m_connectedDev;
}
inline bool operator ==(const CDeviceToken& rhs) const
{return m_devHandle == rhs.m_devHandle;}
{return m_devPath == rhs.m_devPath;}
inline bool operator <(const CDeviceToken& rhs) const
{return m_devHandle < rhs.m_devHandle;}
{return m_devPath < rhs.m_devPath;}
};
#endif // CDEVICETOKEN

View File

@@ -1,14 +1,63 @@
#ifndef CDOLPHINSMASHADAPTER_HPP
#define CDOLPHINSMASHADAPTER_HPP
#include <stdint.h>
#include "CDeviceBase.hpp"
struct IDolphinSmashAdapterCallback
{
enum EDolphinControllerType
{
DOL_TYPE_NONE = 0,
DOL_TYPE_NORMAL = 0x10,
DOL_TYPE_WAVEBIRD = 0x20,
DOL_TYPE_RUMBLE = 0xF0
};
enum EDolphinControllerButtons
{
DOL_START = 1<<0,
DOL_Z = 1<<1,
DOL_L = 1<<2,
DOL_R = 1<<3,
DOL_A = 1<<8,
DOL_B = 1<<9,
DOL_X = 1<<10,
DOL_Y = 1<<11,
DOL_LEFT = 1<<12,
DOL_RIGHT = 1<<13,
DOL_DOWN = 1<<14,
DOL_UP = 1<<15
};
struct SDolphinControllerState
{
uint8_t m_leftStick[2];
uint8_t m_rightStick[2];
uint8_t m_analogTriggers[2];
uint16_t m_btns;
};
virtual void controllerConnected(unsigned idx, EDolphinControllerType type) {}
virtual void controllerDisconnected(unsigned idx, EDolphinControllerType type) {}
virtual void controllerUpdate(unsigned idx, EDolphinControllerType type,
const SDolphinControllerState& state) {}
};
class CDolphinSmashAdapter final : public CDeviceBase
{
IDolphinSmashAdapterCallback* m_callback;
uint8_t m_knownControllers;
uint8_t m_rumbleRequest;
uint8_t m_rumbleState;
bool m_didHandshake;
void deviceDisconnected();
void transferCycle();
public:
CDolphinSmashAdapter(CDeviceToken* token, IHIDDevice* hidDev);
CDolphinSmashAdapter(CDeviceToken* token);
~CDolphinSmashAdapter();
inline void setCallback(IDolphinSmashAdapterCallback* cb)
{m_callback = cb; m_knownControllers = 0;}
inline void startRumble(unsigned idx) {if (idx >= 4) return; m_rumbleRequest |= 1<<idx;}
inline void stopRumble(unsigned idx) {if (idx >= 4) return; m_rumbleRequest &= ~(1<<idx);}
};
#endif // CDOLPHINSMASHADAPTER_HPP

View File

@@ -22,6 +22,6 @@ enum EDeviceMask
};
bool BooDeviceMatchToken(const CDeviceToken& token, EDeviceMask mask);
CDeviceBase* BooDeviceNew(CDeviceToken* token);
CDeviceBase* BooDeviceNew(CDeviceToken& token);
#endif // CDEVICECLASSES_HPP