diff --git a/src/arch/Lights/LightsDriver_snek.cpp b/src/arch/Lights/LightsDriver_snek.cpp index cb8bb37f55..6c04eaf960 100644 --- a/src/arch/Lights/LightsDriver_snek.cpp +++ b/src/arch/Lights/LightsDriver_snek.cpp @@ -6,50 +6,14 @@ REGISTER_LIGHTS_DRIVER_CLASS(snek); -LightsDriver_snek::LightsDriver_snek() +LightsDriver_snek::LightsDriver_snek() : dev{ SNEK_VID , SNEK_PID , SNEK_LIGHTING_INTERFACENUM } { - struct hid_device_info *devs, *cur_dev; - memset(outputBuffer, 0x00, SNEK_HIDREPORT_SIZE); - - // Enumerate through the snek device to find the lighting interface. - devs = hid_enumerate(SNEK_VID, SNEK_PID); - cur_dev = devs; - - if (devs && cur_dev) - { - // Look for the desired interface number for lighting. - while (cur_dev) - { - if (cur_dev->vendor_id == SNEK_VID && - cur_dev->product_id == SNEK_PID && - cur_dev->interface_number == SNEK_LIGHTING_INTERFACENUM) - { - // Open the device via its path (only way to get interface) - handle = hid_open_path(cur_dev->path); - - break; - } - - cur_dev = cur_dev->next; - } - } - - if (!handle) - { - LOG->Warn("snek board lighting not found."); - } } LightsDriver_snek::~LightsDriver_snek() { - if (handle) - { - hid_close(handle); - } - // Finalize the hidapi library - hid_exit(); } void LightsDriver_snek::SetBuffer(int index, bool lightState) @@ -76,12 +40,6 @@ void LightsDriver_snek::SetBuffer(int index, bool lightState) void LightsDriver_snek::Set(const LightsState *ls) { - // do not make a message for a non-connected device. - if (!handle) - { - return; - } - SetBuffer(SNEK_INDEX_DANCE_M_UL, ls->m_bCabinetLights[LIGHT_MARQUEE_UP_LEFT]); SetBuffer(SNEK_INDEX_DANCE_M_UR, ls->m_bCabinetLights[LIGHT_MARQUEE_UP_RIGHT]); SetBuffer(SNEK_INDEX_DANCE_M_LL, ls->m_bCabinetLights[LIGHT_MARQUEE_LR_LEFT]); @@ -106,7 +64,7 @@ void LightsDriver_snek::Set(const LightsState *ls) if (stateChanged) { // TODO: Check for error/reconnect. - hid_write(handle, (unsigned char *)&outputBuffer, SNEK_HIDREPORT_SIZE); + dev.Write((unsigned char *)&outputBuffer, SNEK_HIDREPORT_SIZE); stateChanged = false; } } diff --git a/src/arch/Lights/LightsDriver_snek.h b/src/arch/Lights/LightsDriver_snek.h index 55eccbd53a..79229229ec 100644 --- a/src/arch/Lights/LightsDriver_snek.h +++ b/src/arch/Lights/LightsDriver_snek.h @@ -19,7 +19,7 @@ #include "arch/Lights/LightsDriver.h" #include -#include "hidapi.h" +#include "archutils/Common/HidDevice.h" // static information about the device in question. #define SNEK_VID 0x2e8a @@ -98,7 +98,7 @@ enum SnekLightIndex class LightsDriver_snek : public LightsDriver { private: - hid_device *handle = nullptr; + HidDevice dev; bool stateChanged = false; uint8_t outputBuffer[SNEK_HIDREPORT_SIZE] = {0}; diff --git a/src/arch/Lights/LightsDriver_stac.cpp b/src/arch/Lights/LightsDriver_stac.cpp index 80e7deb3b6..f09f77d662 100644 --- a/src/arch/Lights/LightsDriver_stac.cpp +++ b/src/arch/Lights/LightsDriver_stac.cpp @@ -6,61 +6,14 @@ REGISTER_LIGHTS_DRIVER_CLASS(stac); -LightsDriver_stac::LightsDriver_stac() +LightsDriver_stac::LightsDriver_stac() : devs{{STAC_VID , STAC_PID_P1, STAC_LIGHTING_INTERFACE}, {STAC_VID , STAC_PID_P2, STAC_LIGHTING_INTERFACE }} { - struct hid_device_info *devs, *cur_dev; - memset(outputBuffer[GameController_1], 0x00, STAC_HIDREPORT_SIZE); memset(outputBuffer[GameController_2], 0x00, STAC_HIDREPORT_SIZE); - - // Enumerate through to find the lighting interface. - devs = hid_enumerate(STAC_VID, 0); - cur_dev = devs; - - if (devs && cur_dev) - { - while (cur_dev) - { - if (cur_dev->vendor_id == STAC_VID && - cur_dev->interface_number == STAC_LIGHTING_INTERFACE) - { - if (cur_dev->product_id == STAC_PID_P1) - { - handle[0] = hid_open_path(cur_dev->path); - } - else if (cur_dev->product_id == STAC_PID_P2) - { - handle[1] = hid_open_path(cur_dev->path); - } - } - - cur_dev = cur_dev->next; - } - } - - if (!handle[0]) - { - LOG->Warn("stac P1 device not found."); - } - - if (!handle[1]) - { - LOG->Warn("stac P2 device not found."); - } } LightsDriver_stac::~LightsDriver_stac() { - for (int i = 0; i < STAC_MAX_NUMBER; i++) - { - if (handle[i]) - { - hid_close(handle[i]); - } - } - - // Finalize the hidapi library - hid_exit(); } void LightsDriver_stac::SetBuffer(int index, bool lightState, GameController ctrlNum) @@ -88,7 +41,7 @@ void LightsDriver_stac::SetBuffer(int index, bool lightState, GameController ctr void LightsDriver_stac::HandleState(const LightsState *ls, GameController ctrlNum) { // do not create a message for an disconnected device. - if (!handle[ctrlNum]) + if (!devs[ctrlNum].IsConnected()) return; // check to see which game we are running as it can change during gameplay. @@ -114,8 +67,7 @@ void LightsDriver_stac::HandleState(const LightsState *ls, GameController ctrlNu // only push changes. if (stateChanged[ctrlNum]) { - // TODO: Check for error/reconnect. - hid_write(handle[ctrlNum], (unsigned char *)&outputBuffer[ctrlNum], STAC_HIDREPORT_SIZE); + devs[ctrlNum].Write((unsigned char *)&outputBuffer[ctrlNum], STAC_HIDREPORT_SIZE); stateChanged[ctrlNum] = false; } } diff --git a/src/arch/Lights/LightsDriver_stac.h b/src/arch/Lights/LightsDriver_stac.h index a9ab4e12dc..de38a4a082 100644 --- a/src/arch/Lights/LightsDriver_stac.h +++ b/src/arch/Lights/LightsDriver_stac.h @@ -21,7 +21,7 @@ #include "arch/Lights/LightsDriver.h" #include -#include "hidapi.h" +#include "archutils/Common/HidDevice.h" // static information about the device(s) in question. #define STAC_VID 0x04d8 @@ -50,7 +50,7 @@ enum StacLightIndex class LightsDriver_stac : public LightsDriver { private: - hid_device *handle[STAC_MAX_NUMBER] = {nullptr}; + HidDevice devs[STAC_MAX_NUMBER]; bool stateChanged[STAC_MAX_NUMBER] = {false}; uint8_t outputBuffer[STAC_MAX_NUMBER][STAC_HIDREPORT_SIZE] = {0}; diff --git a/src/archutils/Common/HidDevice.cpp b/src/archutils/Common/HidDevice.cpp index e9d6b8c711..5c98cb4826 100644 --- a/src/archutils/Common/HidDevice.cpp +++ b/src/archutils/Common/HidDevice.cpp @@ -2,7 +2,7 @@ #include "HidDevice.h" #include "RageLog.h" -HidDevice::HidDevice(int vid, int pid) :vid(vid), pid(pid) +HidDevice::HidDevice(int vid, int pid, int interfaceNum) : path{ GetPath(vid, pid, interfaceNum) } { bool result = TryConnect(); @@ -14,31 +14,78 @@ HidDevice::HidDevice(int vid, int pid) :vid(vid), pid(pid) } else { + path = path; hid_set_nonblocking(handle, 1); - foundOnce = true; } } HidDevice::~HidDevice() { - if (handle) + if (handle != nullptr) hid_close(handle); hid_exit(); } +void HidDevice::Close() +{ + hid_close(handle); + handle = nullptr; +} + +bool HidDevice::Open() +{ + handle = hid_open_path(path); + + return handle != nullptr; +} + bool HidDevice::TryConnect() { - handle = hid_open(vid, pid, NULL); + if (path == nullptr) + return false; - return handle != NULL; + return Open(); } bool HidDevice::IsConnected() { - if (!handle && foundOnce) + if (handle == nullptr) return TryConnect(); - return handle != NULL; + return handle != nullptr; +} + +char* HidDevice::GetPath(int vid, int pid, int interfaceNumber) +{ + struct hid_device_info* devs, * cur_dev; + + devs = hid_enumerate(vid, pid); + cur_dev = devs; + + if (devs && cur_dev) + { + // Look for the desired devices by iterating connected ones + while (cur_dev) + { + if (cur_dev->vendor_id == vid && + cur_dev->product_id == pid) + { + if (interfaceNumber == -1) + { + return cur_dev->path; + } + else + { + if(cur_dev->interface_number == interfaceNumber) + return cur_dev->path; + } + } + + cur_dev = cur_dev->next; + } + } + + return nullptr; } void HidDevice::Read(unsigned char* data, size_t length) @@ -54,5 +101,8 @@ void HidDevice::Write(const unsigned char* data, size_t length) if (!IsConnected()) return; - hid_write(handle, data, length); + int result = hid_write(handle, data, length); + + if (result != length) + Close(); } diff --git a/src/archutils/Common/HidDevice.h b/src/archutils/Common/HidDevice.h index 2e1ddf4cb3..d975b2bd31 100644 --- a/src/archutils/Common/HidDevice.h +++ b/src/archutils/Common/HidDevice.h @@ -6,18 +6,20 @@ class HidDevice { private: - hid_device* handle; - bool foundOnce = false; - int vid; - int pid; - + hid_device* handle{nullptr}; + char* path = nullptr; + void Close(); + bool Open(); bool TryConnect(); - bool IsConnected(); public: - HidDevice(int vid, int pid); + static char* GetPath(int vid, int pid, int interfaceNum = -1); + + HidDevice(int vid, int pid, int interfaceNum = -1); virtual ~HidDevice(); + bool IsConnected(); + void Read(unsigned char* data, size_t length); void Write(const unsigned char* data, size_t length); };