From 4cf10e8ecd46666520835371fa55c8a467856704 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Sun, 12 Apr 2026 12:37:42 -0400 Subject: [PATCH] misc: move usb lifecycle into new IOConfigurator --- CMakeLists.txt | 1 + include/DOF/DOF.h | 2 +- src/DOF.cpp | 13 ++----- src/cab/out/dudescab/DudesCab.cpp | 10 +++--- src/cab/out/pac/PacDriveSingleton.cpp | 33 ++++++++--------- src/cab/out/pac/PacDriveSingleton.h | 2 +- src/general/IOConfigurator.cpp | 51 +++++++++++++++++++++++++++ src/general/IOConfigurator.h | 30 ++++++++++++++++ src/general/bitmap/Image.cpp | 2 +- 9 files changed, 109 insertions(+), 35 deletions(-) create mode 100644 src/general/IOConfigurator.cpp create mode 100644 src/general/IOConfigurator.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a6c137..ef723ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,6 +99,7 @@ set(LIBDOF_SOURCES src/general/FilePattern.cpp src/general/FilePatternList.cpp src/general/FileReader.cpp + src/general/IOConfigurator.cpp src/general/MathExtensions.cpp src/general/StringExtensions.cpp src/general/analog/AnalogAlpha.cpp diff --git a/include/DOF/DOF.h b/include/DOF/DOF.h index 16ba028..271d89d 100644 --- a/include/DOF/DOF.h +++ b/include/DOF/DOF.h @@ -2,7 +2,7 @@ #define LIBDOF_VERSION_MAJOR 0 // X Digits #define LIBDOF_VERSION_MINOR 4 // Max 2 Digits -#define LIBDOF_VERSION_PATCH 6 // Max 2 Digits +#define LIBDOF_VERSION_PATCH 7 // Max 2 Digits #define _LIBDOF_STR(x) #x #define LIBDOF_STR(x) _LIBDOF_STR(x) diff --git a/src/DOF.cpp b/src/DOF.cpp index 8c3e422..3ddb223 100644 --- a/src/DOF.cpp +++ b/src/DOF.cpp @@ -9,29 +9,22 @@ #include "Log.h" #include "Logger.h" #include "Pinball.h" +#include "general/IOConfigurator.h" #include "general/StringExtensions.h" -#ifdef __HIDAPI__ -#include -#endif - namespace DOF { DOF::DOF() { -#ifdef __HIDAPI__ - hid_init(); -#endif + IOConfigurator::Initialize(); m_pinball = new Pinball(); } DOF::~DOF() { delete m_pinball; -#ifdef __HIDAPI__ - hid_exit(); -#endif + IOConfigurator::Shutdown(); } void DOF::Init(const char* tableFilename, const char* romName) diff --git a/src/cab/out/dudescab/DudesCab.cpp b/src/cab/out/dudescab/DudesCab.cpp index 099f207..63e0c3c 100644 --- a/src/cab/out/dudescab/DudesCab.cpp +++ b/src/cab/out/dudescab/DudesCab.cpp @@ -232,8 +232,9 @@ std::vector DudesCab::FindDevices() else productName = ""; #else - std::wstring wstr(cur_dev->product_string); - productName = std::string(wstr.begin(), wstr.end()); + wchar_t* wstr = cur_dev->product_string; + while (*wstr) + productName += static_cast(*wstr++); #endif } @@ -250,8 +251,9 @@ std::vector DudesCab::FindDevices() else serialNumber = ""; #else - std::wstring wserial(cur_dev->serial_number); - serialNumber = std::string(wserial.begin(), wserial.end()); + wchar_t* wserial = cur_dev->serial_number; + while (*wserial) + serialNumber += static_cast(*wserial++); #endif } else diff --git a/src/cab/out/pac/PacDriveSingleton.cpp b/src/cab/out/pac/PacDriveSingleton.cpp index 341a9f1..f2c6eee 100644 --- a/src/cab/out/pac/PacDriveSingleton.cpp +++ b/src/cab/out/pac/PacDriveSingleton.cpp @@ -1,8 +1,7 @@ #include "PacDriveSingleton.h" -#include "../../../Log.h" +#include "../../../general/IOConfigurator.h" #include "../../../general/StringExtensions.h" #include -#include namespace DOF { @@ -15,7 +14,7 @@ PacDriveSingleton& PacDriveSingleton::GetInstance() PacDriveSingleton::PacDriveSingleton() : m_numDevices(0) - , m_libusbContext(nullptr) + , m_usbContext(nullptr) { Initialize(); } @@ -24,13 +23,7 @@ PacDriveSingleton::~PacDriveSingleton() { Shutdown(); } void PacDriveSingleton::Initialize() { - int result = libusb_init(&m_libusbContext); - if (result < 0) - { - Log::Exception(StringExtensions::Build("Failed to initialize libusb: {0}", std::to_string(result))); - return; - } - + m_usbContext = IOConfigurator::GetUSBContext(); EnumerateDevices(); } @@ -56,12 +49,7 @@ void PacDriveSingleton::Shutdown() } } m_usbDevices.clear(); - - if (m_libusbContext) - { - libusb_exit(m_libusbContext); - m_libusbContext = nullptr; - } + m_usbContext = nullptr; } } @@ -151,8 +139,14 @@ void PacDriveSingleton::EnumerateDevices() hid_free_enumeration(devices); + if (!m_usbContext) + { + m_numDevices = static_cast(m_devices.size()); + return; + } + libusb_device** usbDevices; - ssize_t deviceCount = libusb_get_device_list(m_libusbContext, &usbDevices); + ssize_t deviceCount = libusb_get_device_list(m_usbContext, &usbDevices); if (deviceCount > 0) { @@ -577,7 +571,10 @@ void PacDriveSingleton::OpenUsbDevice(int index) if (m_usbDevices.find(index) != m_usbDevices.end()) return; - libusb_device_handle* handle = libusb_open_device_with_vid_pid(m_libusbContext, device.vendorId, device.productId); + if (!m_usbContext) + return; + + libusb_device_handle* handle = libusb_open_device_with_vid_pid(m_usbContext, device.vendorId, device.productId); if (handle) { if (libusb_kernel_driver_active(handle, 0) == 1) diff --git a/src/cab/out/pac/PacDriveSingleton.h b/src/cab/out/pac/PacDriveSingleton.h index 84f1ded..3b96a44 100644 --- a/src/cab/out/pac/PacDriveSingleton.h +++ b/src/cab/out/pac/PacDriveSingleton.h @@ -79,7 +79,7 @@ class PacDriveSingleton std::mutex m_hidDevicesMutex; int m_numDevices; - libusb_context* m_libusbContext; + libusb_context* m_usbContext; std::map m_usbDevices; std::mutex m_usbDevicesMutex; diff --git a/src/general/IOConfigurator.cpp b/src/general/IOConfigurator.cpp new file mode 100644 index 0000000..32e9e04 --- /dev/null +++ b/src/general/IOConfigurator.cpp @@ -0,0 +1,51 @@ +#include "IOConfigurator.h" + +#include "../Log.h" +#include "StringExtensions.h" + +#ifdef __HIDAPI__ +#include +#endif + +#include + +namespace DOF +{ + +#ifdef __LIBUSB__ +libusb_context* IOConfigurator::s_libusbContext = nullptr; +#endif + +void IOConfigurator::Initialize() +{ +#ifdef __HIDAPI__ + hid_init(); +#endif +#ifdef __LIBUSB__ + if (s_libusbContext == nullptr) + { + int result = libusb_init(&s_libusbContext); + if (result < 0) + { + Log::Exception(StringExtensions::Build("Failed to initialize libusb: {0}", std::to_string(result))); + s_libusbContext = nullptr; + } + } +#endif +} + +void IOConfigurator::Shutdown() +{ +#ifdef __LIBUSB__ + if (s_libusbContext != nullptr) + { + libusb_exit(s_libusbContext); + s_libusbContext = nullptr; + } +#endif +#ifdef __HIDAPI__ + hid_exit(); +#endif +} + +} diff --git a/src/general/IOConfigurator.h b/src/general/IOConfigurator.h new file mode 100644 index 0000000..a56c258 --- /dev/null +++ b/src/general/IOConfigurator.h @@ -0,0 +1,30 @@ +#pragma once + +#include "DOF/DOF.h" + +#ifdef __LIBUSB__ +#include +#endif + +namespace DOF +{ + +class IOConfigurator +{ +public: + static void Initialize(); + static void Shutdown(); + +#ifdef __LIBUSB__ + static libusb_context* GetUSBContext() { return s_libusbContext; } +#endif + +private: + IOConfigurator() = delete; + +#ifdef __LIBUSB__ + static libusb_context* s_libusbContext; +#endif +}; + +} diff --git a/src/general/bitmap/Image.cpp b/src/general/bitmap/Image.cpp index e8c1642..023ce64 100644 --- a/src/general/bitmap/Image.cpp +++ b/src/general/bitmap/Image.cpp @@ -67,7 +67,7 @@ void Image::LoadFromFile(const std::string& filename) int channels; unsigned char* gifData = stbi_load_gif_from_memory(buffer.data(), static_cast(fileSize), &delays, &m_width, &m_height, &frameCount, &channels, 4); - if (gifData != nullptr && frameCount > 1) + if (gifData != nullptr && frameCount > 0) { m_channels = 4; m_frameCount = frameCount;