mirror of https://github.com/PCSX2/pcsx2.git
Highly experimental DS3 support added. Use newly added features at your own risk. Requires libusb installed and DS3 set up as per instructions at http://forums.pcsx2.net/thread-7582.html. Doesn't require sixaxis64.exe/sixaxis.exe, but might have to fool around with starting/stopping Pcsx2 or LilyPad's test device screen and the PS button on your controller until the "1" light turns on.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1810 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
179054c1a0
commit
73cace2e54
|
@ -14,6 +14,7 @@
|
|||
#include "InputManager.h"
|
||||
#include "KeyboardQueue.h"
|
||||
#include "WndProcEater.h"
|
||||
#include "DualShock3.h"
|
||||
|
||||
// Needed to know if raw input is available. It requires XP or higher.
|
||||
#include "RawInput.h"
|
||||
|
@ -48,6 +49,7 @@ const GeneralSettingsBool BoolOptionsInfo[] = {
|
|||
|
||||
{L"DirectInput Game Devices", IDC_G_DI, 1},
|
||||
{L"XInput", IDC_G_XI, 1},
|
||||
{L"DualShock 3", IDC_G_DS3, 0},
|
||||
|
||||
{L"Multitap 1", IDC_MULTITAP1, 0},
|
||||
{L"Multitap 2", IDC_MULTITAP2, 0},
|
||||
|
@ -151,8 +153,15 @@ void RefreshEnabledDevices(int updateDeviceList) {
|
|||
(dev->type == MOUSE && dev->api == config.mouseApi) ||
|
||||
(dev->type == OTHER &&
|
||||
((dev->api == DI && config.gameApis.directInput) ||
|
||||
(dev->api == DS3 && config.gameApis.dualShock3) ||
|
||||
(dev->api == XINPUT && config.gameApis.xInput)))) {
|
||||
dm->EnableDevice(i);
|
||||
if (config.gameApis.dualShock3 && dev->api == DI && dev->displayName &&
|
||||
!wcsnicmp(dev->displayName+3, L"PLAYSTATION(R)3", 15)) {
|
||||
dm->DisableDevice(i);
|
||||
}
|
||||
else {
|
||||
dm->EnableDevice(i);
|
||||
}
|
||||
}
|
||||
else
|
||||
dm->DisableDevice(i);
|
||||
|
@ -1485,6 +1494,9 @@ INT_PTR CALLBACK DialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM l
|
|||
}
|
||||
dm->Update(&info);
|
||||
dm->PostRead();
|
||||
Sleep(150);
|
||||
dm->Update(&info);
|
||||
dm->PostRead();
|
||||
dev->SetEffect(ffb, 255);
|
||||
SetTimer(hWnd, 1, 3000, 0);
|
||||
}
|
||||
|
@ -1712,6 +1724,11 @@ INT_PTR CALLBACK GeneralDialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, L
|
|||
RefreshEnabledDevicesAndDisplay(0, hWnd, 0);
|
||||
UpdatePadList(hWnd);
|
||||
|
||||
if (!DualShock3Possible()) {
|
||||
config.gameApis.dualShock3 = 0;
|
||||
EnableWindow(GetDlgItem(hWnd, IDC_G_DS3), 0);
|
||||
}
|
||||
|
||||
for (int j=0; j<sizeof(BoolOptionsInfo)/sizeof(BoolOptionsInfo[0]); j++) {
|
||||
CheckDlgButton(hWnd, BoolOptionsInfo[j].ControlId, BST_CHECKED * config.bools[j]);
|
||||
}
|
||||
|
@ -1819,6 +1836,21 @@ INT_PTR CALLBACK GeneralDialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, L
|
|||
|
||||
int mtap = config.multitap[0] + 2*config.multitap[1];
|
||||
|
||||
if (IsDlgButtonChecked(hWnd, IDC_G_DS3) && !config.gameApis.dualShock3) {
|
||||
if (IDOK !=
|
||||
MessageBoxA(hWnd,
|
||||
"This open will attempt to connect directly to any connected\n"
|
||||
"DualShock 3 devices. It is completely experimental, and based\n"
|
||||
"on no published specs.\n"
|
||||
"Furthermore, It uses libusb to Initialize DS3 pads. Libusb can\n"
|
||||
"do odd things to USB and non-USB devices when it enumerates them.\n"
|
||||
"I have no idea if it works with bluetooth or not.\n"
|
||||
"Are you sure you wish to continue?", "Warning", MB_OKCANCEL | MB_ICONWARNING)) {
|
||||
CheckDlgButton(hWnd, IDC_G_DS3, BST_UNCHECKED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (int j=0; j<sizeof(BoolOptionsInfo)/sizeof(BoolOptionsInfo[0]); j++) {
|
||||
config.bools[j] = (IsDlgButtonChecked(hWnd, BoolOptionsInfo[j].ControlId) == BST_CHECKED);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ public:
|
|||
struct {
|
||||
u8 directInput;
|
||||
u8 xInput;
|
||||
u8 dualShock3;
|
||||
} gameApis;
|
||||
|
||||
u8 multitap[2];
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "KeyboardHook.h"
|
||||
#include "RawInput.h"
|
||||
#include "XInput.h"
|
||||
#include "HidDevice.h"
|
||||
#include "DualShock3.h"
|
||||
|
||||
void EnumDevices(int hideDXXinput) {
|
||||
// Needed for enumeration of some device types.
|
||||
|
@ -13,6 +15,7 @@ void EnumDevices(int hideDXXinput) {
|
|||
InputDeviceManager *oldDm = dm;
|
||||
dm = new InputDeviceManager();
|
||||
|
||||
EnumDualShock3s();
|
||||
EnumHookDevices();
|
||||
EnumWindowsMessagingDevices();
|
||||
EnumRawInputDevices();
|
||||
|
|
|
@ -243,7 +243,7 @@ public:
|
|||
memset(&dieffect, 0, sizeof(dieffect));
|
||||
dieffect.dwSize = sizeof(dieffect);
|
||||
dieffect.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTIDS;
|
||||
dieffect.dwDuration = 2000000;
|
||||
dieffect.dwDuration = 1000000;
|
||||
dieffect.dwGain = 10000;
|
||||
dieffect.dwTriggerButton = DIEB_NOTRIGGER;
|
||||
union {
|
||||
|
|
|
@ -0,0 +1,390 @@
|
|||
#include "Global.h"
|
||||
#include <time.h>
|
||||
#include "usb.h"
|
||||
#include "HidDevice.h"
|
||||
#include "InputManager.h"
|
||||
|
||||
#define VID 0x054c
|
||||
#define PID 0x0268
|
||||
|
||||
#define CHECK_DELAY 5
|
||||
time_t lastDS3Check = 0;
|
||||
|
||||
typedef void (__cdecl *_usb_init)(void);
|
||||
typedef int (__cdecl *_usb_close)(usb_dev_handle *dev);
|
||||
typedef int (__cdecl *_usb_get_string_simple)(usb_dev_handle *dev, int index, char *buf, size_t buflen);
|
||||
typedef usb_dev_handle *(__cdecl *_usb_open)(struct usb_device *dev);
|
||||
typedef int (__cdecl *_usb_find_busses)(void);
|
||||
typedef int (__cdecl *_usb_find_devices)(void);
|
||||
typedef struct usb_bus *(__cdecl *_usb_get_busses)(void);
|
||||
typedef usb_dev_handle *(__cdecl *_usb_open)(struct usb_device *dev);
|
||||
typedef int (__cdecl *_usb_control_msg)(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout);
|
||||
|
||||
_usb_init pusb_init;
|
||||
_usb_close pusb_close;
|
||||
_usb_get_string_simple pusb_get_string_simple;
|
||||
_usb_open pusb_open;
|
||||
_usb_find_busses pusb_find_busses;
|
||||
_usb_find_devices pusb_find_devices;
|
||||
_usb_get_busses pusb_get_busses;
|
||||
_usb_control_msg pusb_control_msg;
|
||||
|
||||
HMODULE hModLibusb = 0;
|
||||
|
||||
int DualShock3Possible();
|
||||
void EnumDualShock3s();
|
||||
|
||||
|
||||
void UninitLibUsb() {
|
||||
if (hModLibusb) {
|
||||
FreeLibrary(hModLibusb);
|
||||
hModLibusb = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void TryInitDS3(usb_device *dev) {
|
||||
while (dev) {
|
||||
if (dev->descriptor.idVendor == VID && dev->descriptor.idProduct == PID) {
|
||||
usb_dev_handle *handle = pusb_open(dev);
|
||||
if (handle) {
|
||||
char junk[20];
|
||||
pusb_control_msg(handle, 0xa1, 1, 0x03f2, 0, junk, 17, 1000);
|
||||
pusb_close(handle);
|
||||
}
|
||||
}
|
||||
if (dev->num_children) {
|
||||
for (int i=0; i<dev->num_children; i++) {
|
||||
TryInitDS3(dev->children[i]);
|
||||
}
|
||||
}
|
||||
dev = dev->next;
|
||||
}
|
||||
}
|
||||
|
||||
void DS3Check() {
|
||||
pusb_find_busses();
|
||||
pusb_find_devices();
|
||||
usb_bus *bus = pusb_get_busses();
|
||||
while (bus) {
|
||||
TryInitDS3(bus->devices);
|
||||
bus = bus->next;
|
||||
}
|
||||
lastDS3Check = time(0);
|
||||
}
|
||||
|
||||
int InitLibUsb() {
|
||||
if (hModLibusb) {
|
||||
return 1;
|
||||
}
|
||||
hModLibusb = LoadLibraryA("C:\\windows\\system32\\libusb0.dll");
|
||||
if (hModLibusb) {
|
||||
if ((pusb_init = (_usb_init) GetProcAddress(hModLibusb, "usb_init")) &&
|
||||
(pusb_close = (_usb_close) GetProcAddress(hModLibusb, "usb_close")) &&
|
||||
(pusb_get_string_simple = (_usb_get_string_simple) GetProcAddress(hModLibusb, "usb_get_string_simple")) &&
|
||||
(pusb_open = (_usb_open) GetProcAddress(hModLibusb, "usb_open")) &&
|
||||
(pusb_find_busses = (_usb_find_busses) GetProcAddress(hModLibusb, "usb_find_busses")) &&
|
||||
(pusb_find_devices = (_usb_find_devices) GetProcAddress(hModLibusb, "usb_find_devices")) &&
|
||||
(pusb_get_busses = (_usb_get_busses) GetProcAddress(hModLibusb, "usb_get_busses")) &&
|
||||
(pusb_control_msg = (_usb_control_msg) GetProcAddress(hModLibusb, "usb_control_msg"))) {
|
||||
pusb_init();
|
||||
return 1;
|
||||
}
|
||||
UninitLibUsb();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DualShock3Possible() {
|
||||
return InitLibUsb();
|
||||
}
|
||||
|
||||
#include <pshpack1.h>
|
||||
|
||||
struct MotorState {
|
||||
unsigned char duration;
|
||||
unsigned char force;
|
||||
};
|
||||
|
||||
struct LightState {
|
||||
// 0xFF makes it stay on.
|
||||
unsigned char duration;
|
||||
// Have to make one or the other non-zero to turn on light.
|
||||
unsigned char dunno[2];
|
||||
// 0 is fully lit.
|
||||
unsigned char dimness;
|
||||
// Have to make non-zero to turn on light.
|
||||
unsigned char on;
|
||||
};
|
||||
|
||||
// Data sent to DS3 to set state.
|
||||
struct DS3Command {
|
||||
unsigned char id;
|
||||
unsigned char unsure;
|
||||
// Big is first, then small.
|
||||
MotorState motors[2];
|
||||
unsigned char noClue[4];
|
||||
// 2 is pad 1 light, 4 is pad 2, 8 is pad 3, 16 is pad 4. No clue about the others.
|
||||
unsigned char lightFlags;
|
||||
// Lights are in reverse order. pad 1 is last.
|
||||
LightState lights[4];
|
||||
unsigned char dunno[18];
|
||||
};
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
int CharToAxis(unsigned char c) {
|
||||
int v = (int)c + ((unsigned int)c >> 7);
|
||||
return ((c-128) * FULLY_DOWN)>>7;
|
||||
}
|
||||
|
||||
int CharToButton(unsigned char c) {
|
||||
int v = (int)c + ((unsigned int)c >> 7);
|
||||
return (v * FULLY_DOWN)>>8;
|
||||
}
|
||||
|
||||
class DualShock3Device : public Device {
|
||||
// Cached last vibration values by pad and motor.
|
||||
// Need this, as only one value is changed at a time.
|
||||
int ps2Vibration[2][4][2];
|
||||
int vibration[2];
|
||||
public:
|
||||
int index;
|
||||
HANDLE hFile;
|
||||
DS3Command sendState;
|
||||
unsigned char getState[49];
|
||||
OVERLAPPED readop;
|
||||
OVERLAPPED writeop;
|
||||
|
||||
int writeQueued;
|
||||
int StartRead() {
|
||||
readop.Offset = readop.OffsetHigh = 0;
|
||||
int res = ReadFile(hFile, &getState, sizeof(getState), 0, &readop);
|
||||
return (res || GetLastError() == ERROR_IO_PENDING);
|
||||
}
|
||||
int StartWrite() {
|
||||
writeop.Offset = writeop.OffsetHigh = 0;
|
||||
for (int i=0; i<2; i++) {
|
||||
if (vibration[i]) {
|
||||
sendState.motors[i].duration = 0x7F;
|
||||
int force = vibration[i] * 256/FULLY_DOWN;
|
||||
if (force > 255) force = 255;
|
||||
sendState.motors[i].force = (unsigned char) force;
|
||||
}
|
||||
else {
|
||||
sendState.motors[i].force = 0;
|
||||
sendState.motors[i].duration = 0;
|
||||
}
|
||||
}
|
||||
int res = WriteFile(hFile, &sendState, sizeof(sendState), 0, &writeop);
|
||||
return (res || GetLastError() == ERROR_IO_PENDING);
|
||||
}
|
||||
|
||||
DualShock3Device(int index, wchar_t *name, wchar_t *path) : Device(DS3, OTHER, name, path) {
|
||||
memset(&readop, 0, sizeof(readop));
|
||||
memset(&writeop, 0, sizeof(writeop));
|
||||
memset(&sendState, 0, sizeof(sendState));
|
||||
sendState.id = 1;
|
||||
int temp = (index&4);
|
||||
sendState.lightFlags = (1 << (temp+1));
|
||||
sendState.lights[3-temp].duration = 0xFF;
|
||||
sendState.lights[3-temp].dunno[0] = 1;
|
||||
sendState.lights[3-temp].on = 1;
|
||||
memset(ps2Vibration, 0, sizeof(ps2Vibration));
|
||||
writeQueued = 0;
|
||||
vibration[0] = vibration[1] = 0;
|
||||
this->index = index;
|
||||
int i;
|
||||
for (i=0; i<16; i++) {
|
||||
AddPhysicalControl(PSHBTN, i, 0);
|
||||
}
|
||||
for (; i<20; i++) {
|
||||
AddPhysicalControl(ABSAXIS, i, 0);
|
||||
}
|
||||
AddFFAxis(L"Slow Motor", 0);
|
||||
AddFFAxis(L"Fast Motor", 1);
|
||||
AddFFEffectType(L"Constant Effect", L"Constant", EFFECT_CONSTANT);
|
||||
hFile = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
wchar_t *GetPhysicalControlName(PhysicalControl *c) {
|
||||
const static wchar_t *names[] = {
|
||||
L"Square",
|
||||
L"Cross",
|
||||
L"Circle",
|
||||
L"Triangle",
|
||||
L"R1",
|
||||
L"L1",
|
||||
L"R2",
|
||||
L"L2",
|
||||
L"R3",
|
||||
L"L3",
|
||||
L"Left",
|
||||
L"Down",
|
||||
L"Right",
|
||||
L"Up",
|
||||
L"Start",
|
||||
L"Select",
|
||||
L"Left Thumb X",
|
||||
L"Left Thumb Y",
|
||||
L"Right Thumb X",
|
||||
L"Right Thumb Y",
|
||||
};
|
||||
unsigned int i = (unsigned int) (c - physicalControls);
|
||||
if (i < 20) {
|
||||
return (wchar_t*)names[i];
|
||||
}
|
||||
return Device::GetPhysicalControlName(c);
|
||||
}
|
||||
|
||||
int Activate(void *d) {
|
||||
if (!lastDS3Check) {
|
||||
DS3Check();
|
||||
}
|
||||
else {
|
||||
lastDS3Check = time(0) - CHECK_DELAY+3;
|
||||
}
|
||||
if (active) Deactivate();
|
||||
readop.hEvent = CreateEvent(0, 0, 0, 0);
|
||||
writeop.hEvent = CreateEvent(0, 0, 0, 0);
|
||||
hFile = CreateFileW(instanceID, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
|
||||
if (!readop.hEvent || !writeop.hEvent || hFile == INVALID_HANDLE_VALUE ||
|
||||
!StartRead() || !StartWrite()) {
|
||||
Deactivate();
|
||||
return 0;
|
||||
}
|
||||
writeQueued = 1;
|
||||
active = 1;
|
||||
AllocState();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Update() {
|
||||
if (!active) return 0;
|
||||
HANDLE h[2] = {
|
||||
readop.hEvent,
|
||||
writeop.hEvent
|
||||
};
|
||||
while (1) {
|
||||
DWORD res = WaitForMultipleObjects(2, h, 0, 0);
|
||||
if (res == WAIT_OBJECT_0) {
|
||||
// Do stuff.
|
||||
if (!StartRead()) {
|
||||
Deactivate();
|
||||
return 0;
|
||||
}
|
||||
physicalControlState[0] = CharToButton(getState[25]);
|
||||
physicalControlState[1] = CharToButton(getState[24]);
|
||||
physicalControlState[2] = CharToButton(getState[23]);
|
||||
physicalControlState[3] = CharToButton(getState[22]);
|
||||
physicalControlState[4] = CharToButton(getState[21]);
|
||||
physicalControlState[5] = CharToButton(getState[20]);
|
||||
physicalControlState[6] = CharToButton(getState[19]);
|
||||
physicalControlState[7] = CharToButton(getState[18]);
|
||||
physicalControlState[10] = CharToButton(getState[17]);
|
||||
physicalControlState[11] = CharToButton(getState[16]);
|
||||
physicalControlState[12] = CharToButton(getState[15]);
|
||||
physicalControlState[13] = CharToButton(getState[14]);
|
||||
physicalControlState[8] = ((getState[2]&4)/4) * FULLY_DOWN;
|
||||
physicalControlState[9] = ((getState[2]&2)/2) * FULLY_DOWN;
|
||||
physicalControlState[15] = ((getState[2]&1)/1) * FULLY_DOWN;
|
||||
physicalControlState[14] = ((getState[2]&8)/8) * FULLY_DOWN;
|
||||
physicalControlState[16] = CharToAxis(getState[6]);
|
||||
physicalControlState[17] = CharToAxis(getState[7]);
|
||||
physicalControlState[18] = CharToAxis(getState[8]);
|
||||
physicalControlState[19] = CharToAxis(getState[9]);
|
||||
continue;
|
||||
}
|
||||
else if (res == WAIT_OBJECT_0+1) {
|
||||
writeQueued--;
|
||||
if (writeQueued) {
|
||||
if (!StartWrite()) {
|
||||
Deactivate();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
time_t test = time(0);
|
||||
if (test - lastDS3Check >= CHECK_DELAY) {
|
||||
DS3Check();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force) {
|
||||
ps2Vibration[port][slot][motor] = force;
|
||||
vibration[0] = vibration[1] = 0;
|
||||
for (int p=0; p<2; p++) {
|
||||
for (int s=0; s<4; s++) {
|
||||
for (int i=0; i<pads[p][s].numFFBindings; i++) {
|
||||
// Technically should also be a *65535/BASE_SENSITIVITY, but that's close enough to 1 for me.
|
||||
ForceFeedbackBinding *ffb = &pads[p][s].ffBindings[i];
|
||||
vibration[0] += (int)((ffb->axes[0].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255);
|
||||
vibration[1] += (int)((ffb->axes[1].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!writeQueued) {
|
||||
StartWrite();
|
||||
}
|
||||
if (writeQueued<2) {
|
||||
writeQueued++;
|
||||
}
|
||||
}
|
||||
|
||||
void SetEffect(ForceFeedbackBinding *binding, unsigned char force) {
|
||||
PadBindings pBackup = pads[0][0];
|
||||
pads[0][0].ffBindings = binding;
|
||||
pads[0][0].numFFBindings = 1;
|
||||
SetEffects(0, 0, binding->motor, 255);
|
||||
pads[0][0] = pBackup;
|
||||
}
|
||||
|
||||
void Deactivate() {
|
||||
if (hFile != INVALID_HANDLE_VALUE) {
|
||||
CancelIo(hFile);
|
||||
CloseHandle(hFile);
|
||||
hFile = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
if (readop.hEvent) {
|
||||
CloseHandle(readop.hEvent);
|
||||
}
|
||||
if (writeop.hEvent) {
|
||||
CloseHandle(writeop.hEvent);
|
||||
}
|
||||
writeQueued = 0;
|
||||
memset(ps2Vibration, 0, sizeof(ps2Vibration));
|
||||
vibration[0] = vibration[1] = 0;
|
||||
|
||||
FreeState();
|
||||
active = 0;
|
||||
}
|
||||
|
||||
~DualShock3Device() {
|
||||
}
|
||||
};
|
||||
|
||||
void EnumDualShock3s() {
|
||||
if (!InitLibUsb()) return;
|
||||
|
||||
HidDeviceInfo *foundDevs = 0;
|
||||
|
||||
int numDevs = FindHids(&foundDevs, VID, PID);
|
||||
if (!numDevs) return;
|
||||
int index = 0;
|
||||
for (int i=0; i<numDevs; i++) {
|
||||
if (foundDevs[i].caps.FeatureReportByteLength == 49 &&
|
||||
foundDevs[i].caps.InputReportByteLength == 49 &&
|
||||
foundDevs[i].caps.OutputReportByteLength == 49) {
|
||||
wchar_t temp[100];
|
||||
wsprintfW(temp, L"DualShock 3 #%i", index+1);
|
||||
dm->AddDevice(new DualShock3Device(index, temp, foundDevs[i].path));
|
||||
index++;
|
||||
}
|
||||
free(foundDevs[i].path);
|
||||
}
|
||||
free(foundDevs);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
int DualShock3Possible();
|
||||
void EnumDualShock3s();
|
||||
#include "InputManager.h"
|
||||
|
||||
// May move elsewhere in the future.
|
||||
int InitLibUsb();
|
||||
void UninitLibUsb();
|
|
@ -20,6 +20,8 @@ typedef void (__stdcall *_HidD_GetHidGuid) (GUID* HidGuid);
|
|||
typedef BOOLEAN (__stdcall *_HidD_GetPreparsedData) (HANDLE HidDeviceObject, HIDP_PREPARSED_DATA **PreparsedData);
|
||||
typedef NTSTATUS (__stdcall *_HidP_GetCaps) (HIDP_PREPARSED_DATA* PreparsedData, HIDP_CAPS *caps);
|
||||
typedef BOOLEAN (__stdcall *_HidD_FreePreparsedData) (HIDP_PREPARSED_DATA *PreparsedData);
|
||||
typedef BOOLEAN (__stdcall *_HidD_GetFeature) (HANDLE HidDeviceObject, PVOID ReportBuffer, ULONG ReportBufferLength);
|
||||
typedef BOOLEAN (__stdcall *_HidD_SetFeature) (HANDLE HidDeviceObject, PVOID ReportBuffer, ULONG ReportBufferLength);
|
||||
|
||||
GUID GUID_DEVINTERFACE_HID;
|
||||
_HidD_GetHidGuid pHidD_GetHidGuid;
|
||||
|
@ -27,6 +29,8 @@ _HidD_GetAttributes pHidD_GetAttributes;
|
|||
_HidD_GetPreparsedData pHidD_GetPreparsedData;
|
||||
_HidP_GetCaps pHidP_GetCaps;
|
||||
_HidD_FreePreparsedData pHidD_FreePreparsedData;
|
||||
_HidD_GetFeature pHidD_GetFeature;
|
||||
_HidD_SetFeature pHidD_SetFeature;
|
||||
|
||||
HMODULE hModHid = 0;
|
||||
|
||||
|
@ -40,7 +44,9 @@ int InitHid() {
|
|||
(pHidD_GetAttributes = (_HidD_GetAttributes) GetProcAddress(hModHid, "HidD_GetAttributes")) &&
|
||||
(pHidD_GetPreparsedData = (_HidD_GetPreparsedData) GetProcAddress(hModHid, "HidD_GetPreparsedData")) &&
|
||||
(pHidP_GetCaps = (_HidP_GetCaps) GetProcAddress(hModHid, "HidP_GetCaps")) &&
|
||||
(pHidD_FreePreparsedData = (_HidD_FreePreparsedData) GetProcAddress(hModHid, "HidD_FreePreparsedData"))) {
|
||||
(pHidD_FreePreparsedData = (_HidD_FreePreparsedData) GetProcAddress(hModHid, "HidD_FreePreparsedData")) &&
|
||||
(pHidD_GetFeature = (_HidD_GetFeature) GetProcAddress(hModHid, "HidD_GetFeature")) &&
|
||||
(pHidD_SetFeature = (_HidD_SetFeature) GetProcAddress(hModHid, "HidD_SetFeature"))) {
|
||||
pHidD_GetHidGuid(&GUID_DEVINTERFACE_HID);
|
||||
return 1;
|
||||
}
|
||||
|
@ -82,7 +88,7 @@ int FindHids(HidDeviceInfo **foundDevs, int vid, int pid) {
|
|||
if (pHidD_GetPreparsedData(hfile, &pData)) {
|
||||
if (HIDP_STATUS_SUCCESS == pHidP_GetCaps(pData, &caps)) {
|
||||
if (numFoundDevs % 32 == 0) {
|
||||
*foundDevs = (HidDeviceInfo*) realloc(foundDevs, sizeof(HidDeviceInfo) * (32 + numFoundDevs));
|
||||
*foundDevs = (HidDeviceInfo*) realloc(*foundDevs, sizeof(HidDeviceInfo) * (32 + numFoundDevs));
|
||||
}
|
||||
HidDeviceInfo *dev = &foundDevs[0][numFoundDevs++];
|
||||
dev->caps = caps;
|
||||
|
|
|
@ -35,5 +35,6 @@ struct HidDeviceInfo {
|
|||
};
|
||||
|
||||
void UninitHid();
|
||||
int FindHids(HidDeviceInfo **foundDevs, int vid, int pid);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -97,12 +97,13 @@ enum DeviceAPI {
|
|||
WM = 2,
|
||||
RAW = 3,
|
||||
XINPUT = 4,
|
||||
DS3 = 5,
|
||||
// Not currently used.
|
||||
LLHOOK = 5,
|
||||
LLHOOK = 6,
|
||||
// Not a real API, obviously. Only used with keyboards,
|
||||
// to ignore individual buttons. Wrapper itself takes care
|
||||
// of ignoring bound keys. Otherwise, works normally.
|
||||
IGNORE_KEYBOARD = 6,
|
||||
IGNORE_KEYBOARD = 7,
|
||||
};
|
||||
|
||||
enum DeviceType {
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#include "KeyboardQueue.h"
|
||||
#include "svnrev.h"
|
||||
#include "resource.h"
|
||||
#include "DualShock3.h"
|
||||
#include "HidDevice.h"
|
||||
|
||||
#ifdef PCSX2_DEBUG
|
||||
#include "crtdbg.h"
|
||||
|
@ -260,6 +262,8 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, void* lpvReserved) {
|
|||
while (openCount)
|
||||
PADclose();
|
||||
PADshutdown();
|
||||
UninitHid();
|
||||
UninitLibUsb();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -969,20 +973,20 @@ u8 CALLBACK PADpoll(u8 value) {
|
|||
|
||||
u8 b1 = 0xFF, b2 = 0xFF;
|
||||
for (i = 0; i<4; i++) {
|
||||
b1 -= (sum->buttons[i]>=0xF0) << i;
|
||||
b1 -= (sum->buttons[i]>=0x30) << i;
|
||||
}
|
||||
for (i = 0; i<8; i++) {
|
||||
b2 -= (sum->buttons[i+4]>=0xF0) << i;
|
||||
b2 -= (sum->buttons[i+4]>=0x30) << i;
|
||||
}
|
||||
if (config.padConfigs[query.port][query.slot].type == GuitarPad && !config.GH2) {
|
||||
sum->sticks[0].horiz = -255;
|
||||
// Not sure about this. Forces wammy to be from 0 to 0x7F.
|
||||
// if (sum->sticks[2].vert > 0) sum->sticks[2].vert = 0;
|
||||
}
|
||||
b1 -= ((sum->sticks[0].vert<=-0xF0) << 4);
|
||||
b1 -= ((sum->sticks[0].horiz>=0xF0) << 5);
|
||||
b1 -= ((sum->sticks[0].vert>=0xF0) << 6);
|
||||
b1 -= ((sum->sticks[0].horiz<=-0xF0) << 7);
|
||||
b1 -= ((sum->sticks[0].vert<=-0x30) << 4);
|
||||
b1 -= ((sum->sticks[0].horiz>=0x30) << 5);
|
||||
b1 -= ((sum->sticks[0].vert>=0x30) << 6);
|
||||
b1 -= ((sum->sticks[0].horiz<=-0x30) << 7);
|
||||
query.response[3] = b1;
|
||||
query.response[4] = b2;
|
||||
|
||||
|
|
|
@ -27,18 +27,18 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include <winres.h>\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
|
@ -198,21 +198,22 @@ BEGIN
|
|||
PUSHBUTTON "Small Motor",ID_SMALL_MOTOR,347,291,64,14
|
||||
END
|
||||
|
||||
IDD_GENERAL DIALOGEX 0, 0, 424, 318
|
||||
IDD_GENERAL DIALOGEX 0, 0, 424, 327
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION
|
||||
FONT 8, "MS Shell Dlg", 0, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Input APIs",IDC_STATIC,7,6,410,131
|
||||
GROUPBOX "Input APIs",IDC_STATIC,7,6,410,141
|
||||
GROUPBOX "Keyboard API",IDC_STATIC,16,16,192,61
|
||||
CONTROL "Windows messaging (Recommended)",IDC_KB_WM,"Button",BS_AUTORADIOBUTTON | WS_GROUP,22,28,134,10
|
||||
CONTROL "Raw input (XP and later only)",IDC_KB_RAW,"Button",BS_AUTORADIOBUTTON,22,40,112,10
|
||||
CONTROL "DirectInput",IDC_KB_DI,"Button",BS_AUTORADIOBUTTON,22,52,112,10
|
||||
CONTROL "Disable (Intended for use with other pad plugins)",IDC_KB_DISABLE,
|
||||
"Button",BS_AUTORADIOBUTTON,22,64,175,10
|
||||
GROUPBOX "Game Device APIs",IDC_STATIC,16,81,191,49
|
||||
CONTROL "DirectInput",IDC_G_DI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,92,65,10
|
||||
CONTROL "XInput (Xbox 360 controllers only)",IDC_G_XI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,104,125,10
|
||||
CONTROL "Monitor when in background",IDC_BACKGROUND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,116,106,10
|
||||
GROUPBOX "Game Device APIs",IDC_STATIC,16,79,191,61
|
||||
CONTROL "DirectInput",IDC_G_DI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,91,65,10
|
||||
CONTROL "XInput (Xbox 360 controllers only)",IDC_G_XI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,103,125,10
|
||||
CONTROL "DualShock 3 (Requires libusb)",IDC_G_DS3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,115,110,10
|
||||
CONTROL "Monitor when in background",IDC_BACKGROUND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,127,106,10
|
||||
GROUPBOX "Mouse API",IDC_STATIC,216,16,192,85
|
||||
CONTROL "Windows messaging (Recommended)",IDC_M_WM,"Button",BS_AUTORADIOBUTTON | WS_GROUP,223,27,134,10
|
||||
CONTROL "Raw input (XP and later only)",IDC_M_RAW,"Button",BS_AUTORADIOBUTTON,223,39,112,10
|
||||
|
@ -220,34 +221,34 @@ BEGIN
|
|||
CONTROL "Disable",IDC_M_DISABLE,"Button",BS_AUTORADIOBUTTON,223,63,39,10
|
||||
CONTROL "Start without mouse focus",IDC_MOUSE_UNFOCUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,75,97,10
|
||||
CONTROL "Always hide cursor",IDC_FORCE_HIDE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,87,71,10
|
||||
GROUPBOX "Advanced",IDC_STATIC,216,105,192,25
|
||||
GROUPBOX "Advanced",IDC_STATIC,216,111,192,28
|
||||
CONTROL "Allow binding multiple PS2 controls to one PC control",IDC_MULTIPLE_BINDING,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,116,182,10
|
||||
GROUPBOX "Pads",IDC_STATIC,7,140,410,67
|
||||
CONTROL "Port 1 Multitap",IDC_MULTITAP1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,152,63,10
|
||||
CONTROL "Port 2 Multitap",IDC_MULTITAP2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,164,63,10
|
||||
CONTROL "",IDC_PAD_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_TABSTOP,81,151,183,50,WS_EX_CLIENTEDGE
|
||||
COMBOBOX IDC_PAD_TYPE,270,152,140,41,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,124,182,10
|
||||
GROUPBOX "Pads",IDC_STATIC,7,150,410,67
|
||||
CONTROL "Port 1 Multitap",IDC_MULTITAP1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,162,63,10
|
||||
CONTROL "Port 2 Multitap",IDC_MULTITAP2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,174,63,10
|
||||
CONTROL "",IDC_PAD_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_TABSTOP,81,161,183,50,WS_EX_CLIENTEDGE
|
||||
COMBOBOX IDC_PAD_TYPE,270,162,140,41,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
CONTROL "Use analog mode whenever possible",IDC_ANALOG_START1,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,270,169,132,10
|
||||
GROUPBOX "Device Diagnostics",IDC_STATIC,7,211,201,99
|
||||
CONTROL "",IDC_LIST,"SysListView32",LVS_LIST | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_VSCROLL | WS_TABSTOP,15,224,185,61,WS_EX_CLIENTEDGE
|
||||
PUSHBUTTON "Test Device",ID_TEST,86,289,57,15
|
||||
PUSHBUTTON "Refresh",ID_REFRESH,152,289,48,15
|
||||
GROUPBOX "Miscellaneous",IDC_STATIC,216,211,201,34
|
||||
CONTROL "Use GS thread",IDC_GS_THREAD_INPUT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,221,221,62,10
|
||||
CONTROL "Disable screensaver",IDC_DISABLE_SCREENSAVER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,221,232,80,10
|
||||
CONTROL "Local volume control",IDC_VISTA_VOLUME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,221,77,10
|
||||
CONTROL "Enable logging",IDC_DEBUG_FILE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,232,62,10
|
||||
GROUPBOX "Hacks",IDC_STATIC,216,247,201,45
|
||||
CONTROL "Send escape on window close",IDC_CLOSE_HACK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,257,113,10
|
||||
CONTROL "Exit emulator on window close",IDC_CLOSE_HACK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,268,112,10
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,270,179,132,10
|
||||
GROUPBOX "Device Diagnostics",IDC_STATIC,7,221,201,99
|
||||
CONTROL "",IDC_LIST,"SysListView32",LVS_LIST | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_VSCROLL | WS_TABSTOP,15,234,185,61,WS_EX_CLIENTEDGE
|
||||
PUSHBUTTON "Test Device",ID_TEST,86,299,57,15
|
||||
PUSHBUTTON "Refresh",ID_REFRESH,152,299,48,15
|
||||
GROUPBOX "Miscellaneous",IDC_STATIC,216,221,201,34
|
||||
CONTROL "Use GS thread",IDC_GS_THREAD_INPUT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,221,231,62,10
|
||||
CONTROL "Disable screensaver",IDC_DISABLE_SCREENSAVER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,221,242,80,10
|
||||
CONTROL "Local volume control",IDC_VISTA_VOLUME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,231,77,10
|
||||
CONTROL "Enable logging",IDC_DEBUG_FILE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,242,62,10
|
||||
GROUPBOX "Hacks",IDC_STATIC,216,257,201,45
|
||||
CONTROL "Send escape on window close",IDC_CLOSE_HACK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,267,113,10
|
||||
CONTROL "Exit emulator on window close",IDC_CLOSE_HACK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,278,112,10
|
||||
CONTROL "Safe fullscreen exit on escape",IDC_ESCAPE_FULLSCREEN_HACK,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,279,112,10
|
||||
CONTROL "Save state # in title",IDC_SAVE_STATE_TITLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,257,79,10
|
||||
CONTROL "Guitar Hero 2 Hack",IDC_GH2_HACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,268,76,10
|
||||
PUSHBUTTON "Load Bindings",ID_LOAD,283,295,62,15
|
||||
PUSHBUTTON "Save Bindings",ID_SAVE,355,295,62,15
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,289,112,10
|
||||
CONTROL "Save state # in title",IDC_SAVE_STATE_TITLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,267,79,10
|
||||
CONTROL "Guitar Hero 2 Hack",IDC_GH2_HACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,278,76,10
|
||||
PUSHBUTTON "Load Bindings",ID_LOAD,283,305,62,15
|
||||
PUSHBUTTON "Save Bindings",ID_SAVE,355,305,62,15
|
||||
END
|
||||
|
||||
IDD_ABOUT DIALOGEX 0, 0, 108, 66
|
||||
|
@ -275,7 +276,7 @@ END
|
|||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_CONFIG, DIALOG
|
||||
BEGIN
|
||||
|
@ -298,7 +299,7 @@ BEGIN
|
|||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 417
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 310
|
||||
BOTTOMMARGIN, 319
|
||||
END
|
||||
|
||||
IDD_ABOUT, DIALOG
|
||||
|
|
|
@ -608,6 +608,14 @@
|
|||
RelativePath=".\DirectInput.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\DualShock3.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\DualShock3.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\HidDevice.cpp"
|
||||
>
|
||||
|
@ -640,6 +648,10 @@
|
|||
RelativePath=".\RawInput.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\usb.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\WindowsKeyboard.cpp"
|
||||
>
|
||||
|
|
|
@ -543,6 +543,14 @@
|
|||
RelativePath=".\DirectInput.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\DualShock3.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\DualShock3.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\HidDevice.cpp"
|
||||
>
|
||||
|
@ -575,6 +583,10 @@
|
|||
RelativePath=".\RawInput.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\usb.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\WindowsKeyboard.cpp"
|
||||
>
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
#include "Global.h"
|
||||
#include "VKey.h"
|
||||
#include "DirectInput.h"
|
||||
#include <xinput.h>
|
||||
#include "InputManager.h"
|
||||
#include "DeviceEnumerator.h"
|
||||
|
||||
// This way, I don't require that XInput junk be installed.
|
||||
typedef void (CALLBACK *_XInputEnable)(BOOL enable);
|
||||
|
|
|
@ -1,3 +1 @@
|
|||
#include "InputManager.h"
|
||||
|
||||
void EnumXInputDevices();
|
||||
|
|
|
@ -23,7 +23,8 @@
|
|||
#define IDC_M_RAW 1109
|
||||
#define IDC_G_XI 1110
|
||||
#define IDC_G_DI 1111
|
||||
#define IDC_CLOSE_HACK2 1112
|
||||
#define IDC_G_DS3 1112
|
||||
#define IDC_CLOSE_HACK2 1113
|
||||
#define IDC_DEBUG_FILE 1114
|
||||
#define IDC_GUITAR1 1115
|
||||
#define IDC_ANALOG_START1 1117
|
||||
|
@ -137,7 +138,7 @@
|
|||
#define IDC_FF_AXIS8_SCALE 0x1383
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 112
|
||||
|
|
|
@ -0,0 +1,397 @@
|
|||
// Note: From libusb.
|
||||
|
||||
#ifndef __USB_H__
|
||||
#define __USB_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
|
||||
/*
|
||||
* 'interface' is defined somewhere in the Windows header files. This macro
|
||||
* is deleted here to avoid conflicts and compile errors.
|
||||
*/
|
||||
|
||||
#ifdef interface
|
||||
#undef interface
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PATH_MAX from limits.h can't be used on Windows if the dll and
|
||||
* import libraries are build/used by different compilers
|
||||
*/
|
||||
|
||||
#define LIBUSB_PATH_MAX 512
|
||||
|
||||
|
||||
/*
|
||||
* USB spec information
|
||||
*
|
||||
* This is all stuff grabbed from various USB specs and is pretty much
|
||||
* not subject to change
|
||||
*/
|
||||
|
||||
/*
|
||||
* Device and/or Interface Class codes
|
||||
*/
|
||||
#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */
|
||||
#define USB_CLASS_AUDIO 1
|
||||
#define USB_CLASS_COMM 2
|
||||
#define USB_CLASS_HID 3
|
||||
#define USB_CLASS_PRINTER 7
|
||||
#define USB_CLASS_MASS_STORAGE 8
|
||||
#define USB_CLASS_HUB 9
|
||||
#define USB_CLASS_DATA 10
|
||||
#define USB_CLASS_VENDOR_SPEC 0xff
|
||||
|
||||
/*
|
||||
* Descriptor types
|
||||
*/
|
||||
#define USB_DT_DEVICE 0x01
|
||||
#define USB_DT_CONFIG 0x02
|
||||
#define USB_DT_STRING 0x03
|
||||
#define USB_DT_INTERFACE 0x04
|
||||
#define USB_DT_ENDPOINT 0x05
|
||||
|
||||
#define USB_DT_HID 0x21
|
||||
#define USB_DT_REPORT 0x22
|
||||
#define USB_DT_PHYSICAL 0x23
|
||||
#define USB_DT_HUB 0x29
|
||||
|
||||
/*
|
||||
* Descriptor sizes per descriptor type
|
||||
*/
|
||||
#define USB_DT_DEVICE_SIZE 18
|
||||
#define USB_DT_CONFIG_SIZE 9
|
||||
#define USB_DT_INTERFACE_SIZE 9
|
||||
#define USB_DT_ENDPOINT_SIZE 7
|
||||
#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
|
||||
#define USB_DT_HUB_NONVAR_SIZE 7
|
||||
|
||||
|
||||
/* ensure byte-packed structures */
|
||||
#include <pshpack1.h>
|
||||
|
||||
|
||||
/* All standard descriptors have these 2 fields in common */
|
||||
struct usb_descriptor_header {
|
||||
unsigned char bLength;
|
||||
unsigned char bDescriptorType;
|
||||
};
|
||||
|
||||
/* String descriptor */
|
||||
struct usb_string_descriptor {
|
||||
unsigned char bLength;
|
||||
unsigned char bDescriptorType;
|
||||
unsigned short wData[1];
|
||||
};
|
||||
|
||||
/* HID descriptor */
|
||||
struct usb_hid_descriptor {
|
||||
unsigned char bLength;
|
||||
unsigned char bDescriptorType;
|
||||
unsigned short bcdHID;
|
||||
unsigned char bCountryCode;
|
||||
unsigned char bNumDescriptors;
|
||||
};
|
||||
|
||||
/* Endpoint descriptor */
|
||||
#define USB_MAXENDPOINTS 32
|
||||
struct usb_endpoint_descriptor {
|
||||
unsigned char bLength;
|
||||
unsigned char bDescriptorType;
|
||||
unsigned char bEndpointAddress;
|
||||
unsigned char bmAttributes;
|
||||
unsigned short wMaxPacketSize;
|
||||
unsigned char bInterval;
|
||||
unsigned char bRefresh;
|
||||
unsigned char bSynchAddress;
|
||||
|
||||
unsigned char *extra; /* Extra descriptors */
|
||||
int extralen;
|
||||
};
|
||||
|
||||
#define USB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */
|
||||
#define USB_ENDPOINT_DIR_MASK 0x80
|
||||
|
||||
#define USB_ENDPOINT_TYPE_MASK 0x03 /* in bmAttributes */
|
||||
#define USB_ENDPOINT_TYPE_CONTROL 0
|
||||
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 1
|
||||
#define USB_ENDPOINT_TYPE_BULK 2
|
||||
#define USB_ENDPOINT_TYPE_INTERRUPT 3
|
||||
|
||||
/* Interface descriptor */
|
||||
#define USB_MAXINTERFACES 32
|
||||
struct usb_interface_descriptor {
|
||||
unsigned char bLength;
|
||||
unsigned char bDescriptorType;
|
||||
unsigned char bInterfaceNumber;
|
||||
unsigned char bAlternateSetting;
|
||||
unsigned char bNumEndpoints;
|
||||
unsigned char bInterfaceClass;
|
||||
unsigned char bInterfaceSubClass;
|
||||
unsigned char bInterfaceProtocol;
|
||||
unsigned char iInterface;
|
||||
|
||||
struct usb_endpoint_descriptor *endpoint;
|
||||
|
||||
unsigned char *extra; /* Extra descriptors */
|
||||
int extralen;
|
||||
};
|
||||
|
||||
#define USB_MAXALTSETTING 128 /* Hard limit */
|
||||
|
||||
struct usb_interface {
|
||||
struct usb_interface_descriptor *altsetting;
|
||||
|
||||
int num_altsetting;
|
||||
};
|
||||
|
||||
/* Configuration descriptor information.. */
|
||||
#define USB_MAXCONFIG 8
|
||||
struct usb_config_descriptor {
|
||||
unsigned char bLength;
|
||||
unsigned char bDescriptorType;
|
||||
unsigned short wTotalLength;
|
||||
unsigned char bNumInterfaces;
|
||||
unsigned char bConfigurationValue;
|
||||
unsigned char iConfiguration;
|
||||
unsigned char bmAttributes;
|
||||
unsigned char MaxPower;
|
||||
|
||||
struct usb_interface *interface;
|
||||
|
||||
unsigned char *extra; /* Extra descriptors */
|
||||
int extralen;
|
||||
};
|
||||
|
||||
/* Device descriptor */
|
||||
struct usb_device_descriptor {
|
||||
unsigned char bLength;
|
||||
unsigned char bDescriptorType;
|
||||
unsigned short bcdUSB;
|
||||
unsigned char bDeviceClass;
|
||||
unsigned char bDeviceSubClass;
|
||||
unsigned char bDeviceProtocol;
|
||||
unsigned char bMaxPacketSize0;
|
||||
unsigned short idVendor;
|
||||
unsigned short idProduct;
|
||||
unsigned short bcdDevice;
|
||||
unsigned char iManufacturer;
|
||||
unsigned char iProduct;
|
||||
unsigned char iSerialNumber;
|
||||
unsigned char bNumConfigurations;
|
||||
};
|
||||
|
||||
struct usb_ctrl_setup {
|
||||
unsigned char bRequestType;
|
||||
unsigned char bRequest;
|
||||
unsigned short wValue;
|
||||
unsigned short wIndex;
|
||||
unsigned short wLength;
|
||||
};
|
||||
|
||||
/*
|
||||
* Standard requests
|
||||
*/
|
||||
#define USB_REQ_GET_STATUS 0x00
|
||||
#define USB_REQ_CLEAR_FEATURE 0x01
|
||||
/* 0x02 is reserved */
|
||||
#define USB_REQ_SET_FEATURE 0x03
|
||||
/* 0x04 is reserved */
|
||||
#define USB_REQ_SET_ADDRESS 0x05
|
||||
#define USB_REQ_GET_DESCRIPTOR 0x06
|
||||
#define USB_REQ_SET_DESCRIPTOR 0x07
|
||||
#define USB_REQ_GET_CONFIGURATION 0x08
|
||||
#define USB_REQ_SET_CONFIGURATION 0x09
|
||||
#define USB_REQ_GET_INTERFACE 0x0A
|
||||
#define USB_REQ_SET_INTERFACE 0x0B
|
||||
#define USB_REQ_SYNCH_FRAME 0x0C
|
||||
|
||||
#define USB_TYPE_STANDARD (0x00 << 5)
|
||||
#define USB_TYPE_CLASS (0x01 << 5)
|
||||
#define USB_TYPE_VENDOR (0x02 << 5)
|
||||
#define USB_TYPE_RESERVED (0x03 << 5)
|
||||
|
||||
#define USB_RECIP_DEVICE 0x00
|
||||
#define USB_RECIP_INTERFACE 0x01
|
||||
#define USB_RECIP_ENDPOINT 0x02
|
||||
#define USB_RECIP_OTHER 0x03
|
||||
|
||||
/*
|
||||
* Various libusb API related stuff
|
||||
*/
|
||||
|
||||
#define USB_ENDPOINT_IN 0x80
|
||||
#define USB_ENDPOINT_OUT 0x00
|
||||
|
||||
/* Error codes */
|
||||
#define USB_ERROR_BEGIN 500000
|
||||
|
||||
/*
|
||||
* This is supposed to look weird. This file is generated from autoconf
|
||||
* and I didn't want to make this too complicated.
|
||||
*/
|
||||
#define USB_LE16_TO_CPU(x)
|
||||
|
||||
/* Data types */
|
||||
/* struct usb_device; */
|
||||
/* struct usb_bus; */
|
||||
|
||||
struct usb_device {
|
||||
struct usb_device *next, *prev;
|
||||
|
||||
char filename[LIBUSB_PATH_MAX];
|
||||
|
||||
struct usb_bus *bus;
|
||||
|
||||
struct usb_device_descriptor descriptor;
|
||||
struct usb_config_descriptor *config;
|
||||
|
||||
void *dev; /* Darwin support */
|
||||
|
||||
unsigned char devnum;
|
||||
|
||||
unsigned char num_children;
|
||||
struct usb_device **children;
|
||||
};
|
||||
|
||||
struct usb_bus {
|
||||
struct usb_bus *next, *prev;
|
||||
|
||||
char dirname[LIBUSB_PATH_MAX];
|
||||
|
||||
struct usb_device *devices;
|
||||
unsigned long location;
|
||||
|
||||
struct usb_device *root_dev;
|
||||
};
|
||||
|
||||
/* Version information, Windows specific */
|
||||
struct usb_version {
|
||||
struct {
|
||||
int major;
|
||||
int minor;
|
||||
int micro;
|
||||
int nano;
|
||||
} dll;
|
||||
struct {
|
||||
int major;
|
||||
int minor;
|
||||
int micro;
|
||||
int nano;
|
||||
} driver;
|
||||
};
|
||||
|
||||
|
||||
struct usb_dev_handle;
|
||||
typedef struct usb_dev_handle usb_dev_handle;
|
||||
|
||||
/* Variables */
|
||||
#ifndef __USB_C__
|
||||
#define usb_busses usb_get_busses()
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
#ifdef GOAT
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Function prototypes */
|
||||
|
||||
/* usb.c */
|
||||
usb_dev_handle *usb_open(struct usb_device *dev);
|
||||
int usb_close(usb_dev_handle *dev);
|
||||
int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf,
|
||||
size_t buflen);
|
||||
int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf,
|
||||
size_t buflen);
|
||||
|
||||
/* descriptors.c */
|
||||
int usb_get_descriptor_by_endpoint(usb_dev_handle *udev, int ep,
|
||||
unsigned char type, unsigned char index,
|
||||
void *buf, int size);
|
||||
int usb_get_descriptor(usb_dev_handle *udev, unsigned char type,
|
||||
unsigned char index, void *buf, int size);
|
||||
|
||||
/* <arch>.c */
|
||||
int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size,
|
||||
int timeout);
|
||||
int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size,
|
||||
int timeout);
|
||||
int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size,
|
||||
int timeout);
|
||||
int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size,
|
||||
int timeout);
|
||||
int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
|
||||
int value, int index, char *bytes, int size,
|
||||
int timeout);
|
||||
int usb_set_configuration(usb_dev_handle *dev, int configuration);
|
||||
int usb_claim_interface(usb_dev_handle *dev, int interface);
|
||||
int usb_release_interface(usb_dev_handle *dev, int interface);
|
||||
int usb_set_altinterface(usb_dev_handle *dev, int alternate);
|
||||
int usb_resetep(usb_dev_handle *dev, unsigned int ep);
|
||||
int usb_clear_halt(usb_dev_handle *dev, unsigned int ep);
|
||||
int usb_reset(usb_dev_handle *dev);
|
||||
|
||||
char *usb_strerror(void);
|
||||
|
||||
void usb_init(void);
|
||||
void usb_set_debug(int level);
|
||||
int usb_find_busses(void);
|
||||
int usb_find_devices(void);
|
||||
struct usb_device *usb_device(usb_dev_handle *dev);
|
||||
struct usb_bus *usb_get_busses(void);
|
||||
|
||||
|
||||
/* Windows specific functions */
|
||||
|
||||
#define LIBUSB_HAS_INSTALL_SERVICE_NP 1
|
||||
int usb_install_service_np(void);
|
||||
void CALLBACK usb_install_service_np_rundll(HWND wnd, HINSTANCE instance,
|
||||
LPSTR cmd_line, int cmd_show);
|
||||
|
||||
#define LIBUSB_HAS_UNINSTALL_SERVICE_NP 1
|
||||
int usb_uninstall_service_np(void);
|
||||
void CALLBACK usb_uninstall_service_np_rundll(HWND wnd, HINSTANCE instance,
|
||||
LPSTR cmd_line, int cmd_show);
|
||||
|
||||
#define LIBUSB_HAS_INSTALL_DRIVER_NP 1
|
||||
int usb_install_driver_np(const char *inf_file);
|
||||
void CALLBACK usb_install_driver_np_rundll(HWND wnd, HINSTANCE instance,
|
||||
LPSTR cmd_line, int cmd_show);
|
||||
|
||||
#define LIBUSB_HAS_TOUCH_INF_FILE_NP 1
|
||||
int usb_touch_inf_file_np(const char *inf_file);
|
||||
void CALLBACK usb_touch_inf_file_np_rundll(HWND wnd, HINSTANCE instance,
|
||||
LPSTR cmd_line, int cmd_show);
|
||||
|
||||
#define LIBUSB_HAS_INSTALL_NEEDS_RESTART_NP 1
|
||||
int usb_install_needs_restart_np(void);
|
||||
|
||||
const struct usb_version *usb_get_version(void);
|
||||
|
||||
int usb_isochronous_setup_async(usb_dev_handle *dev, void **context,
|
||||
unsigned char ep, int pktsize);
|
||||
int usb_bulk_setup_async(usb_dev_handle *dev, void **context,
|
||||
unsigned char ep);
|
||||
int usb_interrupt_setup_async(usb_dev_handle *dev, void **context,
|
||||
unsigned char ep);
|
||||
|
||||
int usb_submit_async(void *context, char *bytes, int size);
|
||||
int usb_reap_async(void *context, int timeout);
|
||||
int usb_reap_async_nocancel(void *context, int timeout);
|
||||
int usb_cancel_async(void *context);
|
||||
int usb_free_async(void **context);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* __USB_H__ */
|
||||
|
Loading…
Reference in New Issue