Embed libusb 1.0 into project
This commit is contained in:
committed by
teejusb
parent
1c46342a95
commit
59e6e94cf3
@@ -32,7 +32,6 @@ jobs:
|
|||||||
libmad0-dev
|
libmad0-dev
|
||||||
libpulse-dev
|
libpulse-dev
|
||||||
libudev-dev
|
libudev-dev
|
||||||
libusb-dev
|
|
||||||
libxinerama-dev
|
libxinerama-dev
|
||||||
libx11-dev
|
libx11-dev
|
||||||
libxrandr-dev
|
libxrandr-dev
|
||||||
|
|||||||
@@ -37,3 +37,7 @@
|
|||||||
path = extern/libtomcrypt
|
path = extern/libtomcrypt
|
||||||
url = https://github.com/libtom/libtomcrypt.git
|
url = https://github.com/libtom/libtomcrypt.git
|
||||||
shallow = true
|
shallow = true
|
||||||
|
[submodule "extern/libusb"]
|
||||||
|
path = extern/libusb
|
||||||
|
url = https://github.com/libusb/libusb-cmake.git
|
||||||
|
shallow = true
|
||||||
|
|||||||
@@ -1,105 +0,0 @@
|
|||||||
# - Find libusb for portable USB support
|
|
||||||
# This module will find libusb as published by
|
|
||||||
# http://libusb.sf.net and
|
|
||||||
# http://libusb-win32.sf.net
|
|
||||||
#
|
|
||||||
# It will use PkgConfig if present and supported, else search
|
|
||||||
# it on its own. If the LibUSB_ROOT_DIR environment variable
|
|
||||||
# is defined, it will be used as base path.
|
|
||||||
# The following standard variables get defined:
|
|
||||||
# LIBUSB_FOUND: true if LibUSB was found
|
|
||||||
# LIBUSB_INCLUDE_DIRS: the directory that contains the include file
|
|
||||||
# LIBUSB_LIBRARIES: the library
|
|
||||||
if( WIN32 )
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include ( CheckLibraryExists )
|
|
||||||
include ( CheckIncludeFile )
|
|
||||||
|
|
||||||
find_package ( PkgConfig )
|
|
||||||
if ( PKG_CONFIG_FOUND )
|
|
||||||
pkg_check_modules ( PKGCONFIG_LIBUSB libusb )
|
|
||||||
endif ( PKG_CONFIG_FOUND )
|
|
||||||
|
|
||||||
if ( PKGCONFIG_LIBUSB_FOUND )
|
|
||||||
set ( LIBUSB_FOUND ${PKGCONFIG_LIBUSB_FOUND} )
|
|
||||||
set ( LIBUSB_INCLUDE_DIRS ${PKGCONFIG_LIBUSB_INCLUDE_DIRS} )
|
|
||||||
foreach ( i ${PKGCONFIG_LIBUSB_LIBRARIES} )
|
|
||||||
find_library ( ${i}_LIBRARY
|
|
||||||
NAMES ${i}
|
|
||||||
PATHS ${PKGCONFIG_LIBUSB_LIBRARY_DIRS}
|
|
||||||
)
|
|
||||||
if ( ${i}_LIBRARY )
|
|
||||||
list ( APPEND LIBUSB_LIBRARIES ${${i}_LIBRARY} )
|
|
||||||
endif ( ${i}_LIBRARY )
|
|
||||||
mark_as_advanced ( ${i}_LIBRARY )
|
|
||||||
endforeach ( i )
|
|
||||||
|
|
||||||
else ( PKGCONFIG_LIBUSB_FOUND )
|
|
||||||
find_path ( LIBUSB_INCLUDE_DIRS
|
|
||||||
NAMES
|
|
||||||
usb.h
|
|
||||||
PATHS
|
|
||||||
$ENV{ProgramFiles}/LibUSB-Win32
|
|
||||||
$ENV{LibUSB_ROOT_DIR}
|
|
||||||
PATH_SUFFIXES
|
|
||||||
include
|
|
||||||
)
|
|
||||||
mark_as_advanced ( LIBUSB_INCLUDE_DIRS )
|
|
||||||
# message ( STATUS "LibUSB include dir: ${LIBUSB_INCLUDE_DIRS}" )
|
|
||||||
|
|
||||||
if ( ${CMAKE_SYSTEM_NAME} STREQUAL "Windows" )
|
|
||||||
# LibUSB-Win32 binary distribution contains several libs.
|
|
||||||
# Use the lib that got compiled with the same compiler.
|
|
||||||
if ( MSVC )
|
|
||||||
if ( WIN32 )
|
|
||||||
set ( LibUSB_LIBRARY_PATH_SUFFIX lib/msvc )
|
|
||||||
else ( WIN32 )
|
|
||||||
set ( LibUSB_LIBRARY_PATH_SUFFIX lib/msvc_x64 )
|
|
||||||
endif ( WIN32 )
|
|
||||||
elseif ( BORLAND )
|
|
||||||
set ( LibUSB_LIBRARY_PATH_SUFFIX lib/bcc )
|
|
||||||
elseif ( CMAKE_COMPILER_IS_GNUCC )
|
|
||||||
set ( LibUSB_LIBRARY_PATH_SUFFIX lib/gcc )
|
|
||||||
endif ( MSVC )
|
|
||||||
endif ( ${CMAKE_SYSTEM_NAME} STREQUAL "Windows" )
|
|
||||||
|
|
||||||
find_library ( usb_LIBRARY
|
|
||||||
NAMES
|
|
||||||
libusb usb
|
|
||||||
PATHS
|
|
||||||
$ENV{ProgramFiles}/LibUSB-Win32
|
|
||||||
$ENV{LibUSB_ROOT_DIR}
|
|
||||||
PATH_SUFFIXES
|
|
||||||
${LibUSB_LIBRARY_PATH_SUFFIX}
|
|
||||||
)
|
|
||||||
mark_as_advanced ( usb_LIBRARY )
|
|
||||||
if ( usb_LIBRARY )
|
|
||||||
set ( LIBUSB_LIBRARIES ${usb_LIBRARY} )
|
|
||||||
endif ( usb_LIBRARY )
|
|
||||||
|
|
||||||
if ( LIBUSB_INCLUDE_DIRS AND LIBUSB_LIBRARIES )
|
|
||||||
set ( LIBUSB_FOUND true )
|
|
||||||
endif ( LIBUSB_INCLUDE_DIRS AND LIBUSB_LIBRARIES )
|
|
||||||
endif ( PKGCONFIG_LIBUSB_FOUND )
|
|
||||||
|
|
||||||
if ( LIBUSB_FOUND )
|
|
||||||
set ( CMAKE_REQUIRED_INCLUDES "${LIBUSB_INCLUDE_DIRS}" )
|
|
||||||
check_include_file ( usb.h LIBUSB_FOUND )
|
|
||||||
# message ( STATUS "LibUSB: usb.h is usable: ${LIBUSB_FOUND}" )
|
|
||||||
endif ( LIBUSB_FOUND )
|
|
||||||
if ( LIBUSB_FOUND )
|
|
||||||
check_library_exists ( "${LIBUSB_LIBRARIES}" usb_open "" LIBUSB_FOUND )
|
|
||||||
# message ( STATUS "LibUSB: library is usable: ${LIBUSB_FOUND}" )
|
|
||||||
endif ( LIBUSB_FOUND )
|
|
||||||
|
|
||||||
if ( NOT LIBUSB_FOUND )
|
|
||||||
if ( NOT LibUSB_FIND_QUIETLY )
|
|
||||||
message ( STATUS "LibUSB not found, try setting LibUSB_ROOT_DIR environment variable." )
|
|
||||||
endif ( NOT LibUSB_FIND_QUIETLY )
|
|
||||||
if ( LibUSB_FIND_REQUIRED )
|
|
||||||
message ( FATAL_ERROR "" )
|
|
||||||
endif ( LibUSB_FIND_REQUIRED )
|
|
||||||
endif ( NOT LIBUSB_FOUND )
|
|
||||||
#message ( STATUS "LibUSB: ${LIBUSB_FOUND}" )
|
|
||||||
@@ -338,11 +338,6 @@ elseif(LINUX OR BSD)
|
|||||||
|
|
||||||
set(OpenGL_GL_PREFERENCE GLVND)
|
set(OpenGL_GL_PREFERENCE GLVND)
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
|
|
||||||
find_package(Libusb)
|
|
||||||
if(NOT LIBUSB_FOUND)
|
|
||||||
message(FATAL_ERROR "libusb was not found.")
|
|
||||||
endif()
|
|
||||||
endif(WIN32) # LINUX OR BSD, APPLE
|
endif(WIN32) # LINUX OR BSD, APPLE
|
||||||
|
|
||||||
configure_file("${SM_SRC_DIR}/config.in.hpp"
|
configure_file("${SM_SRC_DIR}/config.in.hpp"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ FROM ubuntu:18.04
|
|||||||
RUN apt-get update
|
RUN apt-get update
|
||||||
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y curl g++ gcc git make nasm
|
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y curl g++ gcc git make nasm
|
||||||
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y libgtk-3-dev
|
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y libgtk-3-dev
|
||||||
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y libasound2-dev libgl1-mesa-dev libglu1-mesa-dev libjack-dev libpulse-dev libssl-dev libudev-dev libva-dev libxinerama-dev libxrandr-dev libxtst-dev libusb-dev
|
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y libasound2-dev libgl1-mesa-dev libglu1-mesa-dev libjack-dev libpulse-dev libssl-dev libudev-dev libva-dev libxinerama-dev libxrandr-dev libxtst-dev
|
||||||
|
|
||||||
RUN cd ~ && curl -L -o cmake.sh https://github.com/Kitware/CMake/releases/download/v3.23.2/cmake-3.23.2-linux-x86_64.sh && sh cmake.sh --skip-license --prefix=/usr/local && rm cmake.sh
|
RUN cd ~ && curl -L -o cmake.sh https://github.com/Kitware/CMake/releases/download/v3.23.2/cmake-3.23.2-linux-x86_64.sh && sh cmake.sh --skip-license --prefix=/usr/local && rm cmake.sh
|
||||||
|
|
||||||
|
|||||||
Vendored
+3
@@ -13,3 +13,6 @@ include(CMakeProject-tommath.cmake)
|
|||||||
include(CMakeProject-png.cmake)
|
include(CMakeProject-png.cmake)
|
||||||
include(CMakeProject-ixwebsocket.cmake)
|
include(CMakeProject-ixwebsocket.cmake)
|
||||||
include(CMakeProject-miniz.cmake)
|
include(CMakeProject-miniz.cmake)
|
||||||
|
|
||||||
|
# External projects
|
||||||
|
include(CMakeProject-libusb.cmake)
|
||||||
|
|||||||
Vendored
+21
@@ -0,0 +1,21 @@
|
|||||||
|
# Build and statically link libusb project
|
||||||
|
|
||||||
|
# libusb is currently used by Linux, but we need to test it under windows too
|
||||||
|
# and it should work
|
||||||
|
if(NOT LINUX)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(LIBUSB_SOURCE_DIR "${SM_EXTERN_DIR}/libusb")
|
||||||
|
|
||||||
|
include(ExternalProject)
|
||||||
|
ExternalProject_Add(
|
||||||
|
libusb
|
||||||
|
|
||||||
|
SOURCE_DIR "${LIBUSB_SOURCE_DIR}"
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
)
|
||||||
|
|
||||||
|
ExternalProject_Get_Property(libusb SOURCE_DIR BINARY_DIR)
|
||||||
|
set(LIBUSB_INCLUDE_DIR "${SOURCE_DIR}/libusb/libusb" CACHE INTERNAL "libusb include")
|
||||||
|
set(LIBUSB_LIBRARY "${BINARY_DIR}/libusb-1.0.a" CACHE INTERNAL "libusb library")
|
||||||
+1
Submodule extern/libusb added at cec1e49eec
+2
-2
@@ -438,7 +438,7 @@ else() # Unix / Linux TODO: Remember to find and locate the zip archive files.
|
|||||||
list(APPEND SMDATA_LINK_LIB ${LIBXTST_LIBRARY})
|
list(APPEND SMDATA_LINK_LIB ${LIBXTST_LIBRARY})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND SMDATA_LINK_LIB ${LIBUSB_LIBRARIES})
|
list(APPEND SMDATA_LINK_LIB ${LIBUSB_LIBRARY})
|
||||||
|
|
||||||
list(APPEND SMDATA_LINK_LIB ${XRANDR_LIBRARIES} ${XINERAMA_LIBRARIES})
|
list(APPEND SMDATA_LINK_LIB ${XRANDR_LIBRARIES} ${XINERAMA_LIBRARIES})
|
||||||
|
|
||||||
@@ -466,7 +466,7 @@ else()
|
|||||||
list(APPEND SM_INCLUDE_DIRS "${X11_INCLUDE_DIR}")
|
list(APPEND SM_INCLUDE_DIRS "${X11_INCLUDE_DIR}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND SM_INCLUDE_DIRS "${LIBUSB_INCLUDE_DIRS}")
|
list(APPEND SM_INCLUDE_DIRS "${LIBUSB_INCLUDE_DIR}")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
@@ -6,277 +6,262 @@
|
|||||||
#include "LightsDriver_LinuxPacDrive.h"
|
#include "LightsDriver_LinuxPacDrive.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <libusb.h>
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <usb.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
REGISTER_LIGHTS_DRIVER_CLASS( LinuxPacDrive );
|
REGISTER_LIGHTS_DRIVER_CLASS( LinuxPacDrive );
|
||||||
|
|
||||||
#define USB_DIR_OUT 0x00
|
// HID Class-Specific Requests values. See section 7.2 of the HID specifications
|
||||||
#define USB_DIR_IN 0x80
|
#define HID_GET_REPORT 0x01
|
||||||
|
#define HID_GET_IDLE 0x02
|
||||||
|
#define HID_GET_PROTOCOL 0x03
|
||||||
|
#define HID_SET_REPORT 0x09
|
||||||
|
#define HID_SET_IDLE 0x0A
|
||||||
|
#define HID_SET_PROTOCOL 0x0B
|
||||||
|
#define HID_REPORT_TYPE_INPUT 0x01
|
||||||
|
#define HID_REPORT_TYPE_OUTPUT 0x02
|
||||||
|
#define HID_REPORT_TYPE_FEATURE 0x03
|
||||||
|
|
||||||
#define USB_TYPE_STANDARD (0x00 << 5)
|
#define HID_IFACE_IN 256
|
||||||
#define USB_TYPE_CLASS (0x01 << 5)
|
#define HID_IFACE_OUT 512
|
||||||
#define USB_TYPE_VENDOR (0x02 << 5)
|
|
||||||
#define USB_TYPE_RESERVED (0x03 << 5)
|
|
||||||
|
|
||||||
#define USB_RECIP_DEVICE 0x00
|
// PacDrives have PIDs 1500 - 1507, but we'll handle that later.
|
||||||
#define USB_RECIP_INTERFACE 0x01
|
const unsigned PACDRIVE_TIMEOUT = 10000;
|
||||||
#define USB_RECIP_ENDPOINT 0x02
|
|
||||||
#define USB_RECIP_OTHER 0x03
|
|
||||||
|
|
||||||
#define HID_GET_REPORT 0x01
|
|
||||||
#define HID_SET_REPORT 0x09
|
|
||||||
#define HID_IFACE_IN 256
|
|
||||||
#define HID_IFACE_OUT 512
|
|
||||||
|
|
||||||
|
|
||||||
/* PacDrives have PIDs 1500 - 1507, but we'll handle that later. */
|
|
||||||
const int PACDRIVE_VENDOR_ID = 0xD209;
|
const int PACDRIVE_VENDOR_ID = 0xD209;
|
||||||
const int PACDRIVE_PRODUCT_ID = 0x1500;
|
const int PACDRIVE_PRODUCT_ID = 0x1500;
|
||||||
|
|
||||||
/* I/O request timeout, in microseconds (so, 10 ms) */
|
|
||||||
const unsigned PACDRIVE_TIMEOUT = 10000;
|
|
||||||
|
|
||||||
/* static struct to ensure the USB subsystem is initialized on start */
|
|
||||||
struct USBInit
|
|
||||||
{
|
|
||||||
USBInit() { usb_init(); usb_find_busses(); usb_find_devices(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct USBInit g_USBInit;
|
|
||||||
|
|
||||||
//Adds new preference to allow for different light wiring setups
|
//Adds new preference to allow for different light wiring setups
|
||||||
static Preference<RString> g_sPacDriveLightOrdering("PacDriveLightOrdering", "openitg");
|
static Preference<RString> g_sPacDriveLightOrdering("PacDriveLightOrdering", "openitg");
|
||||||
int iLightingOrder = 0;
|
int iLightingOrder = 0;
|
||||||
|
|
||||||
LightsDriver_LinuxPacDrive::LightsDriver_LinuxPacDrive()
|
LightsDriver_LinuxPacDrive::LightsDriver_LinuxPacDrive()
|
||||||
{
|
{
|
||||||
Device = NULL;
|
DeviceHandle = NULL;
|
||||||
DeviceHandle = NULL;
|
|
||||||
|
|
||||||
FindDevice();
|
OpenDevice();
|
||||||
OpenDevice();
|
|
||||||
|
|
||||||
// clear all lights
|
// clear all lights
|
||||||
WriteDevice( 0 );
|
WriteDevice( 0 );
|
||||||
|
|
||||||
RString lightOrder = g_sPacDriveLightOrdering.Get();
|
RString lightOrder = g_sPacDriveLightOrdering.Get();
|
||||||
if (lightOrder.CompareNoCase("lumenar") == 0 || lightOrder.CompareNoCase("openitg") == 0) {
|
if (lightOrder.CompareNoCase("lumenar") == 0 || lightOrder.CompareNoCase("openitg") == 0) {
|
||||||
iLightingOrder = 1;
|
iLightingOrder = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LightsDriver_LinuxPacDrive::~LightsDriver_LinuxPacDrive()
|
LightsDriver_LinuxPacDrive::~LightsDriver_LinuxPacDrive()
|
||||||
{
|
{
|
||||||
// clear all lights and close the connection
|
// clear all lights and close the connection
|
||||||
WriteDevice( 0 );
|
WriteDevice( 0 );
|
||||||
CloseDevice();
|
CloseDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightsDriver_LinuxPacDrive::Set( const LightsState *ls )
|
void LightsDriver_LinuxPacDrive::Set( const LightsState *ls )
|
||||||
{
|
{
|
||||||
if ( !DeviceHandle ) return;
|
if ( !DeviceHandle ) return;
|
||||||
|
|
||||||
uint16_t outb = 0;
|
uint16_t outb = 0;
|
||||||
|
|
||||||
switch (iLightingOrder) {
|
switch (iLightingOrder) {
|
||||||
case 1:
|
case 1:
|
||||||
//Sets the cabinet light values to follow LumenAR/OpenITG wiring standards
|
//Sets the cabinet light values to follow LumenAR/OpenITG wiring standards
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OpenITG PacDrive Order:
|
* OpenITG PacDrive Order:
|
||||||
* Taken from LightsDriver_PacDrive::SetLightsMappings() in openitg.
|
* Taken from LightsDriver_PacDrive::SetLightsMappings() in openitg.
|
||||||
*
|
*
|
||||||
* 0: Marquee UL
|
* 0: Marquee UL
|
||||||
* 1: Marquee UR
|
* 1: Marquee UR
|
||||||
* 2: Marquee DL
|
* 2: Marquee DL
|
||||||
* 3: Marquee DR
|
* 3: Marquee DR
|
||||||
*
|
*
|
||||||
* 4: P1 Button
|
* 4: P1 Button
|
||||||
* 5: P2 Button
|
* 5: P2 Button
|
||||||
*
|
*
|
||||||
* 6: Bass Left
|
* 6: Bass Left
|
||||||
* 7: Bass Right
|
* 7: Bass Right
|
||||||
*
|
*
|
||||||
* 8,9,10,11: P1 L R U D
|
* 8,9,10,11: P1 L R U D
|
||||||
* 12,13,14,15: P2 L R U D
|
* 12,13,14,15: P2 L R U D
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (ls->m_bCabinetLights[LIGHT_MARQUEE_UP_LEFT]) outb |= BIT(0);
|
if (ls->m_bCabinetLights[LIGHT_MARQUEE_UP_LEFT]) outb |= BIT(0);
|
||||||
if (ls->m_bCabinetLights[LIGHT_MARQUEE_UP_RIGHT]) outb |= BIT(1);
|
if (ls->m_bCabinetLights[LIGHT_MARQUEE_UP_RIGHT]) outb |= BIT(1);
|
||||||
if (ls->m_bCabinetLights[LIGHT_MARQUEE_LR_LEFT]) outb |= BIT(2);
|
if (ls->m_bCabinetLights[LIGHT_MARQUEE_LR_LEFT]) outb |= BIT(2);
|
||||||
if (ls->m_bCabinetLights[LIGHT_MARQUEE_LR_RIGHT]) outb |= BIT(3);
|
if (ls->m_bCabinetLights[LIGHT_MARQUEE_LR_RIGHT]) outb |= BIT(3);
|
||||||
|
|
||||||
if (ls->m_bGameButtonLights[GameController_1][GAME_BUTTON_START]) outb |= BIT(4);
|
if (ls->m_bGameButtonLights[GameController_1][GAME_BUTTON_START]) outb |= BIT(4);
|
||||||
if (ls->m_bGameButtonLights[GameController_2][GAME_BUTTON_START]) outb |= BIT(5);
|
if (ls->m_bGameButtonLights[GameController_2][GAME_BUTTON_START]) outb |= BIT(5);
|
||||||
|
|
||||||
//Most PacDrive/Cabinet setups only have *one* bass light, so mux them together here.
|
//Most PacDrive/Cabinet setups only have *one* bass light, so mux them together here.
|
||||||
if (ls->m_bCabinetLights[LIGHT_BASS_LEFT] || ls->m_bCabinetLights[LIGHT_BASS_RIGHT]) outb |= BIT(6);
|
if (ls->m_bCabinetLights[LIGHT_BASS_LEFT] || ls->m_bCabinetLights[LIGHT_BASS_RIGHT]) outb |= BIT(6);
|
||||||
if (ls->m_bCabinetLights[LIGHT_BASS_LEFT] || ls->m_bCabinetLights[LIGHT_BASS_RIGHT]) outb |= BIT(7);
|
if (ls->m_bCabinetLights[LIGHT_BASS_LEFT] || ls->m_bCabinetLights[LIGHT_BASS_RIGHT]) outb |= BIT(7);
|
||||||
|
|
||||||
if (ls->m_bGameButtonLights[GameController_1][DANCE_BUTTON_LEFT]) outb |= BIT(8);
|
if (ls->m_bGameButtonLights[GameController_1][DANCE_BUTTON_LEFT]) outb |= BIT(8);
|
||||||
if (ls->m_bGameButtonLights[GameController_1][DANCE_BUTTON_RIGHT]) outb |= BIT(9);
|
if (ls->m_bGameButtonLights[GameController_1][DANCE_BUTTON_RIGHT]) outb |= BIT(9);
|
||||||
if (ls->m_bGameButtonLights[GameController_1][DANCE_BUTTON_UP]) outb |= BIT(10);
|
if (ls->m_bGameButtonLights[GameController_1][DANCE_BUTTON_UP]) outb |= BIT(10);
|
||||||
if (ls->m_bGameButtonLights[GameController_1][DANCE_BUTTON_DOWN]) outb |= BIT(11);
|
if (ls->m_bGameButtonLights[GameController_1][DANCE_BUTTON_DOWN]) outb |= BIT(11);
|
||||||
|
|
||||||
if (ls->m_bGameButtonLights[GameController_2][DANCE_BUTTON_LEFT]) outb |= BIT(12);
|
if (ls->m_bGameButtonLights[GameController_2][DANCE_BUTTON_LEFT]) outb |= BIT(12);
|
||||||
if (ls->m_bGameButtonLights[GameController_2][DANCE_BUTTON_RIGHT]) outb |= BIT(13);
|
if (ls->m_bGameButtonLights[GameController_2][DANCE_BUTTON_RIGHT]) outb |= BIT(13);
|
||||||
if (ls->m_bGameButtonLights[GameController_2][DANCE_BUTTON_UP]) outb |= BIT(14);
|
if (ls->m_bGameButtonLights[GameController_2][DANCE_BUTTON_UP]) outb |= BIT(14);
|
||||||
if (ls->m_bGameButtonLights[GameController_2][DANCE_BUTTON_DOWN]) outb |= BIT(15);
|
if (ls->m_bGameButtonLights[GameController_2][DANCE_BUTTON_DOWN]) outb |= BIT(15);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
default:
|
default:
|
||||||
//If all else fails, falls back to original order
|
//If all else fails, falls back to original order
|
||||||
//reference page 7
|
//reference page 7
|
||||||
//http://www.peeweepower.com/stepmania/sm509pacdriveinfo.pdf
|
//http://www.peeweepower.com/stepmania/sm509pacdriveinfo.pdf
|
||||||
|
|
||||||
if (ls->m_bCabinetLights[LIGHT_MARQUEE_UP_LEFT]) outb |= BIT(0);
|
if (ls->m_bCabinetLights[LIGHT_MARQUEE_UP_LEFT]) outb |= BIT(0);
|
||||||
if (ls->m_bCabinetLights[LIGHT_MARQUEE_UP_RIGHT]) outb |= BIT(1);
|
if (ls->m_bCabinetLights[LIGHT_MARQUEE_UP_RIGHT]) outb |= BIT(1);
|
||||||
if (ls->m_bCabinetLights[LIGHT_MARQUEE_LR_LEFT]) outb |= BIT(2);
|
if (ls->m_bCabinetLights[LIGHT_MARQUEE_LR_LEFT]) outb |= BIT(2);
|
||||||
if (ls->m_bCabinetLights[LIGHT_MARQUEE_LR_RIGHT]) outb |= BIT(3);
|
if (ls->m_bCabinetLights[LIGHT_MARQUEE_LR_RIGHT]) outb |= BIT(3);
|
||||||
|
|
||||||
if (ls->m_bCabinetLights[LIGHT_BASS_LEFT] || ls->m_bCabinetLights[LIGHT_BASS_RIGHT]) outb |= BIT(4);
|
if (ls->m_bCabinetLights[LIGHT_BASS_LEFT] || ls->m_bCabinetLights[LIGHT_BASS_RIGHT]) outb |= BIT(4);
|
||||||
|
|
||||||
if (ls->m_bGameButtonLights[GameController_1][DANCE_BUTTON_LEFT]) outb |= BIT(5);
|
if (ls->m_bGameButtonLights[GameController_1][DANCE_BUTTON_LEFT]) outb |= BIT(5);
|
||||||
if (ls->m_bGameButtonLights[GameController_1][DANCE_BUTTON_RIGHT]) outb |= BIT(6);
|
if (ls->m_bGameButtonLights[GameController_1][DANCE_BUTTON_RIGHT]) outb |= BIT(6);
|
||||||
if (ls->m_bGameButtonLights[GameController_1][DANCE_BUTTON_UP]) outb |= BIT(7);
|
if (ls->m_bGameButtonLights[GameController_1][DANCE_BUTTON_UP]) outb |= BIT(7);
|
||||||
if (ls->m_bGameButtonLights[GameController_1][DANCE_BUTTON_DOWN]) outb |= BIT(8);
|
if (ls->m_bGameButtonLights[GameController_1][DANCE_BUTTON_DOWN]) outb |= BIT(8);
|
||||||
if (ls->m_bGameButtonLights[GameController_1][GAME_BUTTON_START]) outb |= BIT(9);
|
if (ls->m_bGameButtonLights[GameController_1][GAME_BUTTON_START]) outb |= BIT(9);
|
||||||
|
|
||||||
if (ls->m_bGameButtonLights[GameController_2][DANCE_BUTTON_LEFT]) outb |= BIT(10);
|
if (ls->m_bGameButtonLights[GameController_2][DANCE_BUTTON_LEFT]) outb |= BIT(10);
|
||||||
if (ls->m_bGameButtonLights[GameController_2][DANCE_BUTTON_RIGHT]) outb |= BIT(11);
|
if (ls->m_bGameButtonLights[GameController_2][DANCE_BUTTON_RIGHT]) outb |= BIT(11);
|
||||||
if (ls->m_bGameButtonLights[GameController_2][DANCE_BUTTON_UP]) outb |= BIT(12);
|
if (ls->m_bGameButtonLights[GameController_2][DANCE_BUTTON_UP]) outb |= BIT(12);
|
||||||
if (ls->m_bGameButtonLights[GameController_2][DANCE_BUTTON_DOWN]) outb |= BIT(13);
|
if (ls->m_bGameButtonLights[GameController_2][DANCE_BUTTON_DOWN]) outb |= BIT(13);
|
||||||
if (ls->m_bGameButtonLights[GameController_2][GAME_BUTTON_START]) outb |= BIT(14);
|
if (ls->m_bGameButtonLights[GameController_2][GAME_BUTTON_START]) outb |= BIT(14);
|
||||||
//Bit index 15 is unused.
|
//Bit index 15 is unused.
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WriteDevice(outb);
|
||||||
WriteDevice(outb);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LightsDriver_LinuxPacDrive::FindDevice()
|
|
||||||
{
|
|
||||||
if ( usb_find_busses() < 0 )
|
|
||||||
{
|
|
||||||
LOG->Warn( "libusb: usb_find_busses: %s", usb_strerror() );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( usb_find_devices() < 0 )
|
|
||||||
{
|
|
||||||
LOG->Warn( "libusb: usb_find_devices: %s", usb_strerror() );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( usb_bus *bus = usb_get_busses(); bus; bus = bus->next )
|
|
||||||
for ( struct usb_device *dev = bus->devices; dev; dev = dev->next )
|
|
||||||
if ( PACDRIVE_VENDOR_ID == dev->descriptor.idVendor &&
|
|
||||||
PACDRIVE_PRODUCT_ID <= dev->descriptor.idProduct &&
|
|
||||||
PACDRIVE_PRODUCT_ID + 8 > dev->descriptor.idProduct ) {
|
|
||||||
Device = dev;
|
|
||||||
LOG->Info( "PacDrive device was found vid: 0x%04x pid: 0x%04x", dev->descriptor.idVendor, dev->descriptor.idProduct );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG->Warn( "PacDrive was not found!" );
|
|
||||||
Device = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightsDriver_LinuxPacDrive::OpenDevice()
|
void LightsDriver_LinuxPacDrive::OpenDevice()
|
||||||
{
|
{
|
||||||
CloseDevice();
|
libusb_device **devs;
|
||||||
|
libusb_device *dev = NULL;
|
||||||
|
ssize_t result;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
if ( !Device ) return;
|
CloseDevice(); // Ensure any previously opened device is closed first to prevent conflicts
|
||||||
|
|
||||||
DeviceHandle = usb_open( Device );
|
libusb_context* context = USBContext::getInstance().getContext();
|
||||||
|
if (!context)
|
||||||
|
{
|
||||||
|
LOG->Warn("libusb: Failed to initialize context");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ( DeviceHandle == NULL ) {
|
libusb_set_option(context, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO);
|
||||||
LOG->Warn( "libusb: usb_open: %s", usb_strerror() );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The device may be claimed by a kernel driver. Attempt to reclaim it.
|
result = libusb_get_device_list(context, &devs);
|
||||||
for ( unsigned iface = 0; iface < Device->config->bNumInterfaces; iface++ )
|
if (result < 0)
|
||||||
{
|
{
|
||||||
int result = usb_detach_kernel_driver_np( DeviceHandle, iface );
|
LOG->Warn("libusb_get_device_list failed: %s", libusb_error_name(result));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// device doesn't understand message, no attached driver, no error -- ignore these
|
while ((dev = devs[i++]) != NULL)
|
||||||
if( result == -EINVAL || result == -ENODATA || result == 0 )
|
{
|
||||||
continue;
|
libusb_device_descriptor desc;
|
||||||
|
// Note since libusb-1.0.16, LIBUSBX_API_VERSION >= 0x01000102, this function always succeeds:
|
||||||
|
libusb_get_device_descriptor(dev, &desc);
|
||||||
|
|
||||||
/* we have an error we can't handle; try and get more info. */
|
if (PACDRIVE_VENDOR_ID == desc.idVendor &&
|
||||||
LOG->Warn( "usb_detach_kernel_driver_np: %s\n", usb_strerror() );
|
PACDRIVE_PRODUCT_ID <= desc.idProduct &&
|
||||||
|
PACDRIVE_PRODUCT_ID + 8 > desc.idProduct)
|
||||||
|
{
|
||||||
|
LOG->Info("PacDrive device was found vid: 0x%04x pid: 0x%04x", desc.idVendor, desc.idProduct);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// on EPERM, a driver exists and we can't detach - report which one
|
if (!dev)
|
||||||
if ( result == -EPERM )
|
{
|
||||||
{
|
LOG->Warn("PacDrive was not found");
|
||||||
char szDriverName[16];
|
libusb_free_device_list(devs, 1);
|
||||||
strcpy( szDriverName, "(unknown)" );
|
return;
|
||||||
usb_get_driver_np(DeviceHandle, iface, szDriverName, 16);
|
}
|
||||||
|
|
||||||
LOG->Warn( "(cannot detach kernel driver \"%s\")", szDriverName );
|
result = libusb_open(dev, &DeviceHandle);
|
||||||
}
|
if (result < 0)
|
||||||
|
{
|
||||||
|
LOG->Warn("libusb_open failed: %s", libusb_error_name(result));
|
||||||
|
DeviceHandle = NULL;
|
||||||
|
libusb_free_device_list(devs, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CloseDevice();
|
libusb_free_device_list(devs, 1);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( usb_set_configuration( DeviceHandle, Device->config->bConfigurationValue) ) {
|
if (libusb_kernel_driver_active(DeviceHandle, 0) == 1)
|
||||||
LOG->Warn( "libusb: usb_set_configuration: %s", usb_strerror() );
|
{
|
||||||
CloseDevice();
|
LOG->Warn("Kernel Driver Active");
|
||||||
return;
|
if (libusb_detach_kernel_driver(DeviceHandle, 0) == 0)
|
||||||
}
|
LOG->Warn("Kernel Driver Detached!");
|
||||||
|
}
|
||||||
|
|
||||||
// attempt to claim all interfaces for this device
|
result = libusb_claim_interface(DeviceHandle, 0);
|
||||||
for ( unsigned i = 0; i < Device->config->bNumInterfaces; i++ )
|
if (result < 0)
|
||||||
{
|
{
|
||||||
if ( usb_claim_interface( DeviceHandle, i ) ) {
|
LOG->Warn("libusb_claim_interface: cannot claim interface: %s", libusb_error_name(result));
|
||||||
LOG->Warn( "Libusb: usb_claim_interface(%i): %s", i, usb_strerror() );
|
libusb_close(DeviceHandle);
|
||||||
CloseDevice();
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LightsDriver_LinuxPacDrive::WriteDevice(uint16_t out)
|
LOG->Info("Device claimed");
|
||||||
{
|
|
||||||
if ( !DeviceHandle ) return;
|
|
||||||
|
|
||||||
// output is within the first 16 bits - accept a
|
|
||||||
// 16-bit arg and cast it, for simplicity's sake.
|
|
||||||
uint32_t data = (out << 16);
|
|
||||||
int expected = sizeof(data);
|
|
||||||
|
|
||||||
int result = usb_control_msg( DeviceHandle, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
|
|
||||||
HID_SET_REPORT, HID_IFACE_OUT, 0, (char *)&data, expected,
|
|
||||||
PACDRIVE_TIMEOUT );
|
|
||||||
|
|
||||||
if( result != expected ) {
|
|
||||||
LOG->Warn( "PacDrive writing failed: %i (%s)\n", result, usb_strerror() );
|
|
||||||
CloseDevice();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightsDriver_LinuxPacDrive::CloseDevice()
|
void LightsDriver_LinuxPacDrive::CloseDevice()
|
||||||
{
|
{
|
||||||
if ( !DeviceHandle )
|
if (!DeviceHandle)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
usb_set_altinterface( DeviceHandle, 0 );
|
ssize_t result;
|
||||||
usb_reset( DeviceHandle );
|
|
||||||
usb_close( DeviceHandle );
|
result = libusb_release_interface(DeviceHandle, 0);
|
||||||
DeviceHandle = NULL;
|
if (result != 0)
|
||||||
|
{
|
||||||
|
LOG->Warn("libusb_release_interface: %s", libusb_error_name(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
libusb_close(DeviceHandle);
|
||||||
|
DeviceHandle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LightsDriver_LinuxPacDrive::WriteDevice(uint16_t out)
|
||||||
|
{
|
||||||
|
if (!DeviceHandle) return;
|
||||||
|
|
||||||
|
// output is within the first 16 bits - accept a
|
||||||
|
// 16-bit arg and cast it, for simplicity's sake.
|
||||||
|
uint32_t data = (out << 16);
|
||||||
|
int expected = sizeof(data);
|
||||||
|
|
||||||
|
ssize_t result = libusb_control_transfer(DeviceHandle,
|
||||||
|
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
|
||||||
|
HID_SET_REPORT,
|
||||||
|
HID_IFACE_OUT,
|
||||||
|
0,
|
||||||
|
(unsigned char*)&data,
|
||||||
|
expected,
|
||||||
|
PACDRIVE_TIMEOUT);
|
||||||
|
|
||||||
|
if(result != expected) {
|
||||||
|
LOG->Warn("PacDrive writing failed: %li (%s)\n", result, libusb_error_name(result));
|
||||||
|
CloseDevice();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008 BoXoRRoXoRs
|
* Rewritten for libusb 1.0 2024 sirex
|
||||||
|
* Rewritten for libusb 1.0 2024 sukibaby
|
||||||
|
* Original libusb 0.1 file Copyright (c) 2008 BoXoRRoXoRs
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
|||||||
@@ -4,13 +4,47 @@
|
|||||||
#include "LightsDriver.h"
|
#include "LightsDriver.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <libusb.h>
|
||||||
extern "C" {
|
|
||||||
#include <usb.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BIT(i) (1<<(i))
|
#define BIT(i) (1<<(i))
|
||||||
|
|
||||||
|
class USBContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static USBContext& getInstance()
|
||||||
|
{
|
||||||
|
static USBContext instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
libusb_context* getContext() { return context; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
USBContext()
|
||||||
|
{
|
||||||
|
int result = libusb_init_context(&context, NULL, 0);
|
||||||
|
if (result < 0)
|
||||||
|
{
|
||||||
|
// initialization error
|
||||||
|
context = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~USBContext()
|
||||||
|
{
|
||||||
|
if (context)
|
||||||
|
{
|
||||||
|
libusb_exit(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
libusb_context* context;
|
||||||
|
|
||||||
|
// prevent copying
|
||||||
|
USBContext(const USBContext&) = delete;
|
||||||
|
USBContext& operator=(const USBContext&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
class LightsDriver_LinuxPacDrive: public LightsDriver
|
class LightsDriver_LinuxPacDrive: public LightsDriver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -20,13 +54,11 @@ public:
|
|||||||
void Set( const LightsState *ls );
|
void Set( const LightsState *ls );
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void FindDevice();
|
|
||||||
void OpenDevice();
|
void OpenDevice();
|
||||||
void WriteDevice(uint16_t out);
|
void WriteDevice(uint16_t out);
|
||||||
void CloseDevice();
|
void CloseDevice();
|
||||||
|
|
||||||
struct usb_device *Device;
|
libusb_device_handle *DeviceHandle;
|
||||||
usb_dev_handle *DeviceHandle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LIGHTSDRIVER_LINUXPACDRIVE_H
|
#endif // LIGHTSDRIVER_LINUXPACDRIVE_H
|
||||||
|
|||||||
Reference in New Issue
Block a user