From 567e1c533f1a31f12d1345ab952cd0b573a9b185 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Wed, 19 Mar 2003 20:34:40 +0000 Subject: [PATCH] move USB handling into a separate file --- .../InputHandler/InputHandler_Win32_Pump.cpp | 173 +----------------- .../InputHandler/InputHandler_Win32_Pump.h | 13 +- stepmania/src/archutils/Win32/USB.cpp | 157 ++++++++++++++++ stepmania/src/archutils/Win32/USB.h | 25 +++ 4 files changed, 199 insertions(+), 169 deletions(-) create mode 100644 stepmania/src/archutils/Win32/USB.cpp create mode 100644 stepmania/src/archutils/Win32/USB.h diff --git a/stepmania/src/arch/InputHandler/InputHandler_Win32_Pump.cpp b/stepmania/src/arch/InputHandler/InputHandler_Win32_Pump.cpp index 377de3bacf..4a6aee25d5 100644 --- a/stepmania/src/arch/InputHandler/InputHandler_Win32_Pump.cpp +++ b/stepmania/src/arch/InputHandler/InputHandler_Win32_Pump.cpp @@ -2,139 +2,19 @@ #include "InputHandler_Win32_Pump.h" #include "RageLog.h" -#include "RageUtil.h" #include "RageInputDevice.h" #include "InputFilter.h" - -//----------------------------------------------------------------------------- -// In-line Links -//----------------------------------------------------------------------------- -#pragma comment(lib, "ddk/setupapi.lib") -#pragma comment(lib, "ddk/hid.lib") - -struct InputHandler_Win32_Pump::dev_t { - dev_t(); - ~dev_t(); - HANDLE h; - OVERLAPPED ov; - long buf; - bool pending; - int GetPadEvent(); -}; - - -namespace USB { - char *GetUSBDevicePath (int num); - HANDLE OpenUSB (int VID, int PID, int num); -}; - -extern "C" { -#include "ddk/setupapi.h" -/* Quiet header warning: */ -#pragma warning( push ) -#pragma warning (disable : 4201) -#include "ddk/hidsdi.h" -#pragma warning( pop ) -} - -char *USB::GetUSBDevicePath (int num) -{ - GUID guid; - HidD_GetHidGuid(&guid); - - HDEVINFO DeviceInfo = SetupDiGetClassDevs (&guid, - NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); - - SP_DEVICE_INTERFACE_DATA DeviceInterface; - DeviceInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); - - char *ret = NULL; - PSP_INTERFACE_DEVICE_DETAIL_DATA DeviceDetail = NULL; - - if (!SetupDiEnumDeviceInterfaces (DeviceInfo, - NULL, &guid, num, &DeviceInterface)) - goto err; - - unsigned long size; - SetupDiGetDeviceInterfaceDetail (DeviceInfo, &DeviceInterface, NULL, 0, &size, 0); - - DeviceDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA) malloc(size); - DeviceDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); - - if (SetupDiGetDeviceInterfaceDetail (DeviceInfo, &DeviceInterface, - DeviceDetail, size, &size, NULL)) - { - ret = strdup(DeviceDetail->DevicePath); - } - -err: - SetupDiDestroyDeviceInfoList (DeviceInfo); - free (DeviceDetail); - return ret; -} - -HANDLE USB::OpenUSB (int VID, int PID, int num) -{ - DWORD index = 0; - - char *path; - HANDLE h = INVALID_HANDLE_VALUE; - - while ((path = GetUSBDevicePath (index++)) != NULL) - { - if(h != INVALID_HANDLE_VALUE) - CloseHandle (h); - - h = CreateFile (path, GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); - - free(path); - - if(h == INVALID_HANDLE_VALUE) - continue; - - HIDD_ATTRIBUTES attr; - if (!HidD_GetAttributes (h, &attr)) - continue; - - if ((VID != -1 && attr.VendorID != VID) && - (PID != -1 && attr.ProductID != PID)) - continue; /* This isn't it. */ - - /* The VID and PID match. */ - if(num-- == 0) - return h; - } - if(h != INVALID_HANDLE_VALUE) - CloseHandle (h); - - return INVALID_HANDLE_VALUE; -} - - -InputHandler_Win32_Pump::dev_t::dev_t() -{ - ZeroMemory( &ov, sizeof(ov) ); - pending=false; - h = INVALID_HANDLE_VALUE; -} - -InputHandler_Win32_Pump::dev_t::~dev_t() -{ - if(h != INVALID_HANDLE_VALUE) - CloseHandle(h); -} +#include "archutils/Win32/USB.h" InputHandler_Win32_Pump::InputHandler_Win32_Pump() { const int pump_usb_vid = 0x0d2f, pump_usb_pid = 0x0001; - dev = new dev_t[NUM_PUMPS]; + dev = new USBDevice[NUM_PUMPS]; for(int i = 0; i < NUM_PUMPS; ++i) { - dev[i].h = USB::OpenUSB (pump_usb_vid, pump_usb_pid, i); - if(dev[i].h != INVALID_HANDLE_VALUE) + if(dev[i].Open(pump_usb_vid, pump_usb_pid, i)) LOG->Info("Found Pump pad %i", i); } } @@ -144,47 +24,6 @@ InputHandler_Win32_Pump::~InputHandler_Win32_Pump() delete[] dev; } -int InputHandler_Win32_Pump::dev_t::GetPadEvent() -{ - if(h == INVALID_HANDLE_VALUE) - return -1; - - int ret; - - if(!pending) - { - /* Request feedback from the device. */ - unsigned long r; - ret = ReadFile(h, &buf, sizeof(buf), &r, &ov); - pending=true; - } - - /* See if we have a response for our request (which we may - * have made on a previous call): */ - if(WaitForSingleObjectEx(h, 0, TRUE) == WAIT_TIMEOUT) - return -1; - - /* We do; get the result. It'll go into the original &buf - * we supplied on the original call; that's why buf is a - * member instead of a local. */ - unsigned long cnt; - ret = GetOverlappedResult(h, &ov, &cnt, FALSE); - pending=false; - - if(ret == 0 && (GetLastError() == ERROR_IO_PENDING || GetLastError() == ERROR_IO_INCOMPLETE)) - return -1; - - if(ret == 0) { - // this prints too much info in Win98 - // See if it's fixed--h should be INVALID_HANDLE_VALUE if - // the pad isn't there. -glenn - LOG->Warn(werr_ssprintf(GetLastError(), "Error reading Pump pad")); - return -1; - } - - return buf; -} - void InputHandler_Win32_Pump::Update(float fDeltaTime) { static const int bits[] = { @@ -207,3 +46,9 @@ void InputHandler_Win32_Pump::Update(float fDeltaTime) } } +/* +----------------------------------------------------------------------------- + Copyright (c) 2002-2003 by the person(s) listed below. All rights reserved. + Glenn Maynard +----------------------------------------------------------------------------- +*/ diff --git a/stepmania/src/arch/InputHandler/InputHandler_Win32_Pump.h b/stepmania/src/arch/InputHandler/InputHandler_Win32_Pump.h index a236d8a68f..6bfbcadf15 100644 --- a/stepmania/src/arch/InputHandler/InputHandler_Win32_Pump.h +++ b/stepmania/src/arch/InputHandler/InputHandler_Win32_Pump.h @@ -3,11 +3,10 @@ #include "InputHandler.h" +class USBDevice; class InputHandler_Win32_Pump: public InputHandler { - struct dev_t; /* MYOB */ - - dev_t *dev; + USBDevice *dev; public: void Update(float fDeltaTime); @@ -15,6 +14,10 @@ public: ~InputHandler_Win32_Pump(); }; - - #endif +/* +----------------------------------------------------------------------------- + Copyright (c) 2002-2003 by the person(s) listed below. All rights reserved. + Glenn Maynard +----------------------------------------------------------------------------- +*/ diff --git a/stepmania/src/archutils/Win32/USB.cpp b/stepmania/src/archutils/Win32/USB.cpp new file mode 100644 index 0000000000..678ef111b1 --- /dev/null +++ b/stepmania/src/archutils/Win32/USB.cpp @@ -0,0 +1,157 @@ +#include "global.h" +#include "USB.h" +#include "RageLog.h" +#include "RageUtil.h" + +#pragma comment(lib, "ddk/setupapi.lib") +#pragma comment(lib, "ddk/hid.lib") + +extern "C" { +#include "ddk/setupapi.h" +/* Quiet header warning: */ +#pragma warning( push ) +#pragma warning (disable : 4201) +#include "ddk/hidsdi.h" +#pragma warning( pop ) +} + +static char *GetUSBDevicePath (int num) +{ + GUID guid; + HidD_GetHidGuid(&guid); + + HDEVINFO DeviceInfo = SetupDiGetClassDevs (&guid, + NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); + + SP_DEVICE_INTERFACE_DATA DeviceInterface; + DeviceInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + + char *ret = NULL; + PSP_INTERFACE_DEVICE_DETAIL_DATA DeviceDetail = NULL; + + if (!SetupDiEnumDeviceInterfaces (DeviceInfo, + NULL, &guid, num, &DeviceInterface)) + goto err; + + unsigned long size; + SetupDiGetDeviceInterfaceDetail (DeviceInfo, &DeviceInterface, NULL, 0, &size, 0); + + DeviceDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA) malloc(size); + DeviceDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); + + if (SetupDiGetDeviceInterfaceDetail (DeviceInfo, &DeviceInterface, + DeviceDetail, size, &size, NULL)) + { + ret = strdup(DeviceDetail->DevicePath); + } + +err: + SetupDiDestroyDeviceInfoList (DeviceInfo); + free (DeviceDetail); + return ret; +} + +static HANDLE OpenUSB (int VID, int PID, int num) +{ + DWORD index = 0; + + char *path; + HANDLE h = INVALID_HANDLE_VALUE; + + while ((path = GetUSBDevicePath (index++)) != NULL) + { + if(h != INVALID_HANDLE_VALUE) + CloseHandle (h); + + h = CreateFile (path, GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + + free(path); + + if(h == INVALID_HANDLE_VALUE) + continue; + + HIDD_ATTRIBUTES attr; + if (!HidD_GetAttributes (h, &attr)) + continue; + + if ((VID != -1 && attr.VendorID != VID) && + (PID != -1 && attr.ProductID != PID)) + continue; /* This isn't it. */ + + /* The VID and PID match. */ + if(num-- == 0) + return h; + } + if(h != INVALID_HANDLE_VALUE) + CloseHandle (h); + + return INVALID_HANDLE_VALUE; +} + +USBDevice::USBDevice() +{ + ZeroMemory( &ov, sizeof(ov) ); + pending=false; + h = INVALID_HANDLE_VALUE; +} + +USBDevice::~USBDevice() +{ + if(h != INVALID_HANDLE_VALUE) + CloseHandle(h); +} + +bool USBDevice::Open(int VID, int PID, int num) +{ + h = OpenUSB (VID, PID, num); + return h != INVALID_HANDLE_VALUE; +} + +int USBDevice::GetPadEvent() +{ + if(h == INVALID_HANDLE_VALUE) + return -1; + + int ret; + + if(!pending) + { + /* Request feedback from the device. */ + unsigned long r; + ret = ReadFile(h, &buf, sizeof(buf), &r, &ov); + pending=true; + } + + /* See if we have a response for our request (which we may + * have made on a previous call): */ + if(WaitForSingleObjectEx(h, 0, TRUE) == WAIT_TIMEOUT) + return -1; + + /* We do; get the result. It'll go into the original &buf + * we supplied on the original call; that's why buf is a + * member instead of a local. */ + unsigned long cnt; + ret = GetOverlappedResult(h, &ov, &cnt, FALSE); + pending=false; + + if(ret == 0 && (GetLastError() == ERROR_IO_PENDING || GetLastError() == ERROR_IO_INCOMPLETE)) + return -1; + + if(ret == 0) { + // this prints too much info in Win98 + // See if it's fixed--h should be INVALID_HANDLE_VALUE if + // the pad isn't there. -glenn + LOG->Warn(werr_ssprintf(GetLastError(), "Error reading Pump pad")); + return -1; + } + + return buf; +} + +/* +----------------------------------------------------------------------------- + Copyright (c) 2002-2003 by the person(s) listed below. All rights reserved. + Glenn Maynard +----------------------------------------------------------------------------- +*/ diff --git a/stepmania/src/archutils/Win32/USB.h b/stepmania/src/archutils/Win32/USB.h new file mode 100644 index 0000000000..e58d95507f --- /dev/null +++ b/stepmania/src/archutils/Win32/USB.h @@ -0,0 +1,25 @@ +#ifndef WIN32_USB_H +#define WIN32_USB_H + +class USBDevice +{ +public: + USBDevice(); + ~USBDevice(); + int GetPadEvent(); + bool Open(int VID, int PID, int num); + +private: + HANDLE h; + OVERLAPPED ov; + long buf; + bool pending; +}; + +#endif +/* +----------------------------------------------------------------------------- + Copyright (c) 2002-2003 by the person(s) listed below. All rights reserved. + Glenn Maynard +----------------------------------------------------------------------------- +*/