mirror of https://github.com/PCSX2/pcsx2.git
PAD: windows: clang-format
This commit is contained in:
parent
9cdc963c97
commit
8067a480c7
|
@ -34,23 +34,23 @@
|
|||
|
||||
void EnumDevices(int hideDXXinput)
|
||||
{
|
||||
// Needed for enumeration of some device types.
|
||||
dm->ReleaseInput();
|
||||
InputDeviceManager *oldDm = dm;
|
||||
dm = new InputDeviceManager();
|
||||
// Needed for enumeration of some device types.
|
||||
dm->ReleaseInput();
|
||||
InputDeviceManager* oldDm = dm;
|
||||
dm = new InputDeviceManager();
|
||||
|
||||
#ifdef _MSC_VER
|
||||
EnumWindowsMessagingDevices();
|
||||
EnumRawInputDevices();
|
||||
EnumDualShock3s();
|
||||
EnumXInputDevices();
|
||||
EnumDirectInputDevices(hideDXXinput);
|
||||
EnumWindowsMessagingDevices();
|
||||
EnumRawInputDevices();
|
||||
EnumDualShock3s();
|
||||
EnumXInputDevices();
|
||||
EnumDirectInputDevices(hideDXXinput);
|
||||
#else
|
||||
EnumLnx();
|
||||
EnumJoystickEvdev();
|
||||
EnumLnx();
|
||||
EnumJoystickEvdev();
|
||||
#endif
|
||||
|
||||
dm->CopyBindings(oldDm->numDevices, oldDm->devices);
|
||||
dm->CopyBindings(oldDm->numDevices, oldDm->devices);
|
||||
|
||||
delete oldDm;
|
||||
delete oldDm;
|
||||
}
|
||||
|
|
|
@ -22,123 +22,142 @@
|
|||
#include "InputManager.h"
|
||||
#include "WndProcEater.h"
|
||||
|
||||
Device *dev;
|
||||
Device* dev;
|
||||
|
||||
INT_PTR CALLBACK DiagDialog(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
int i;
|
||||
HWND hWndList = GetDlgItem(hWnd, IDC_DIAG_LIST);
|
||||
static int fullRefresh;
|
||||
if (dev) {
|
||||
switch (uMsg) {
|
||||
case WM_INITDIALOG: {
|
||||
fullRefresh = 1;
|
||||
SetWindowText(hWnd, dev->displayName);
|
||||
LVCOLUMNW c;
|
||||
c.mask = LVCF_TEXT | LVCF_WIDTH;
|
||||
c.cx = 151;
|
||||
c.pszText = L"Control";
|
||||
ListView_InsertColumn(hWndList, 0, &c);
|
||||
c.cx = 90;
|
||||
c.pszText = L"Value";
|
||||
ListView_InsertColumn(hWndList, 1, &c);
|
||||
ListView_DeleteAllItems(hWndList);
|
||||
LVITEM item;
|
||||
item.mask = LVIF_TEXT;
|
||||
item.iSubItem = 0;
|
||||
for (i = 0; i < dev->numVirtualControls; i++) {
|
||||
item.pszText = dev->GetVirtualControlName(dev->virtualControls + i);
|
||||
item.iItem = i;
|
||||
ListView_InsertItem(hWndList, &item);
|
||||
}
|
||||
SetTimer(hWnd, 1, 200, 0);
|
||||
}
|
||||
//break;
|
||||
case WM_TIMER: {
|
||||
hWndButtonProc.SetWndHandle(hWndList);
|
||||
InitInfo info = {0, 1, hWnd, &hWndButtonProc};
|
||||
dm->Update(&info);
|
||||
LVITEMW item;
|
||||
item.mask = LVIF_TEXT;
|
||||
item.iSubItem = 1;
|
||||
//ShowWindow(hWndList, 0);
|
||||
//LockWindowUpdate(hWndList);
|
||||
if (!dev->active) {
|
||||
item.pszText = L"N/A";
|
||||
for (i = 0; i < dev->numVirtualControls; i++) {
|
||||
item.iItem = i;
|
||||
ListView_SetItem(hWndList, &item);
|
||||
}
|
||||
fullRefresh = 1;
|
||||
} else {
|
||||
for (i = 0; i < dev->numVirtualControls; i++) {
|
||||
if (fullRefresh || dev->virtualControlState[i] != dev->oldVirtualControlState[i]) {
|
||||
int i;
|
||||
HWND hWndList = GetDlgItem(hWnd, IDC_DIAG_LIST);
|
||||
static int fullRefresh;
|
||||
if (dev)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
fullRefresh = 1;
|
||||
SetWindowText(hWnd, dev->displayName);
|
||||
LVCOLUMNW c;
|
||||
c.mask = LVCF_TEXT | LVCF_WIDTH;
|
||||
c.cx = 151;
|
||||
c.pszText = L"Control";
|
||||
ListView_InsertColumn(hWndList, 0, &c);
|
||||
c.cx = 90;
|
||||
c.pszText = L"Value";
|
||||
ListView_InsertColumn(hWndList, 1, &c);
|
||||
ListView_DeleteAllItems(hWndList);
|
||||
LVITEM item;
|
||||
item.mask = LVIF_TEXT;
|
||||
item.iSubItem = 0;
|
||||
for (i = 0; i < dev->numVirtualControls; i++)
|
||||
{
|
||||
item.pszText = dev->GetVirtualControlName(dev->virtualControls + i);
|
||||
item.iItem = i;
|
||||
ListView_InsertItem(hWndList, &item);
|
||||
}
|
||||
SetTimer(hWnd, 1, 200, 0);
|
||||
}
|
||||
//break;
|
||||
case WM_TIMER:
|
||||
{
|
||||
hWndButtonProc.SetWndHandle(hWndList);
|
||||
InitInfo info = {0, 1, hWnd, &hWndButtonProc};
|
||||
dm->Update(&info);
|
||||
LVITEMW item;
|
||||
item.mask = LVIF_TEXT;
|
||||
item.iSubItem = 1;
|
||||
//ShowWindow(hWndList, 0);
|
||||
//LockWindowUpdate(hWndList);
|
||||
if (!dev->active)
|
||||
{
|
||||
item.pszText = L"N/A";
|
||||
for (i = 0; i < dev->numVirtualControls; i++)
|
||||
{
|
||||
item.iItem = i;
|
||||
ListView_SetItem(hWndList, &item);
|
||||
}
|
||||
fullRefresh = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < dev->numVirtualControls; i++)
|
||||
{
|
||||
if (fullRefresh || dev->virtualControlState[i] != dev->oldVirtualControlState[i])
|
||||
{
|
||||
|
||||
VirtualControl *c = dev->virtualControls + i;
|
||||
wchar_t temp[50];
|
||||
int val = dev->virtualControlState[i];
|
||||
if (c->uid & (UID_POV)) {
|
||||
wsprintfW(temp, L"%i", val);
|
||||
} else {
|
||||
wchar_t *sign = L"";
|
||||
if (val < 0) {
|
||||
sign = L"-";
|
||||
val = -val;
|
||||
}
|
||||
if ((c->uid & UID_AXIS) && val) {
|
||||
val = val;
|
||||
}
|
||||
val = (int)floor(0.5 + val * 1000.0 / (double)FULLY_DOWN);
|
||||
wsprintfW(temp, L"%s%i.%03i", sign, val / 1000, val % 1000);
|
||||
}
|
||||
item.pszText = temp;
|
||||
item.iItem = i;
|
||||
ListView_SetItem(hWndList, &item);
|
||||
}
|
||||
}
|
||||
dm->PostRead();
|
||||
fullRefresh = 0;
|
||||
}
|
||||
//LockWindowUpdate(0);
|
||||
//ShowWindow(hWndList, 1);
|
||||
//UpdateWindow(hWnd);
|
||||
} break;
|
||||
case WM_NOTIFY: {
|
||||
NMLVKEYDOWN *n = (NMLVKEYDOWN *)lParam;
|
||||
// Don't always get the notification when testing DirectInput non-keyboard devices.
|
||||
// Don't get it (Or want it) when testing keyboards.
|
||||
if (n->hdr.idFrom != IDC_DIAG_LIST || n->hdr.code != LVN_KEYDOWN || n->wVKey != VK_ESCAPE)
|
||||
break;
|
||||
}
|
||||
case WM_ACTIVATE:
|
||||
if (uMsg == WM_ACTIVATE && wParam != WA_INACTIVE)
|
||||
break;
|
||||
break;
|
||||
case WM_CLOSE:
|
||||
KillTimer(hWnd, 1);
|
||||
dm->ReleaseInput();
|
||||
// Prevents reaching this branch again.
|
||||
dev = 0;
|
||||
EndDialog(hWnd, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
VirtualControl* c = dev->virtualControls + i;
|
||||
wchar_t temp[50];
|
||||
int val = dev->virtualControlState[i];
|
||||
if (c->uid & (UID_POV))
|
||||
{
|
||||
wsprintfW(temp, L"%i", val);
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t* sign = L"";
|
||||
if (val < 0)
|
||||
{
|
||||
sign = L"-";
|
||||
val = -val;
|
||||
}
|
||||
if ((c->uid & UID_AXIS) && val)
|
||||
{
|
||||
val = val;
|
||||
}
|
||||
val = (int)floor(0.5 + val * 1000.0 / (double)FULLY_DOWN);
|
||||
wsprintfW(temp, L"%s%i.%03i", sign, val / 1000, val % 1000);
|
||||
}
|
||||
item.pszText = temp;
|
||||
item.iItem = i;
|
||||
ListView_SetItem(hWndList, &item);
|
||||
}
|
||||
}
|
||||
dm->PostRead();
|
||||
fullRefresh = 0;
|
||||
}
|
||||
//LockWindowUpdate(0);
|
||||
//ShowWindow(hWndList, 1);
|
||||
//UpdateWindow(hWnd);
|
||||
}
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
NMLVKEYDOWN* n = (NMLVKEYDOWN*)lParam;
|
||||
// Don't always get the notification when testing DirectInput non-keyboard devices.
|
||||
// Don't get it (Or want it) when testing keyboards.
|
||||
if (n->hdr.idFrom != IDC_DIAG_LIST || n->hdr.code != LVN_KEYDOWN || n->wVKey != VK_ESCAPE)
|
||||
break;
|
||||
}
|
||||
case WM_ACTIVATE:
|
||||
if (uMsg == WM_ACTIVATE && wParam != WA_INACTIVE)
|
||||
break;
|
||||
break;
|
||||
case WM_CLOSE:
|
||||
KillTimer(hWnd, 1);
|
||||
dm->ReleaseInput();
|
||||
// Prevents reaching this branch again.
|
||||
dev = 0;
|
||||
EndDialog(hWnd, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Diagnose(int id, HWND hWnd)
|
||||
{
|
||||
// init = 0;
|
||||
dev = dm->devices[id];
|
||||
for (int i = 0; i < dm->numDevices; i++) {
|
||||
if (i != id)
|
||||
dm->DisableDevice(i);
|
||||
// Shouldn't be needed.
|
||||
else
|
||||
dm->EnableDevice(i);
|
||||
}
|
||||
DialogBox(hInst, MAKEINTRESOURCE(IDD_DIAG), hWnd, DiagDialog);
|
||||
ClearKeyQueue();
|
||||
// init = 0;
|
||||
dev = dm->devices[id];
|
||||
for (int i = 0; i < dm->numDevices; i++)
|
||||
{
|
||||
if (i != id)
|
||||
dm->DisableDevice(i);
|
||||
// Shouldn't be needed.
|
||||
else
|
||||
dm->EnableDevice(i);
|
||||
}
|
||||
DialogBox(hInst, MAKEINTRESOURCE(IDD_DIAG), hWnd, DiagDialog);
|
||||
ClearKeyQueue();
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -41,15 +41,15 @@
|
|||
unsigned int lastDS3Check = 0;
|
||||
unsigned int lastDS3Enum = 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);
|
||||
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;
|
||||
|
@ -64,434 +64,477 @@ HMODULE hModLibusb = 0;
|
|||
|
||||
void UninitLibUsb()
|
||||
{
|
||||
if (hModLibusb) {
|
||||
FreeLibrary(hModLibusb);
|
||||
hModLibusb = 0;
|
||||
}
|
||||
if (hModLibusb)
|
||||
{
|
||||
FreeLibrary(hModLibusb);
|
||||
hModLibusb = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void TryInitDS3(usb_device *dev)
|
||||
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];
|
||||
// This looks like HidD_GetFeature with a feature report id of 0xF2 to me and a length of 17.
|
||||
// That doesn't work, however, and 17 is shorter than the report length.
|
||||
pusb_control_msg(handle, 0xa1, 1, 0x03f2, dev->config->interface->altsetting->bInterfaceNumber, 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;
|
||||
}
|
||||
while (dev)
|
||||
{
|
||||
if (dev->descriptor.idVendor == VID && dev->descriptor.idProduct == PID)
|
||||
{
|
||||
usb_dev_handle* handle = pusb_open(dev);
|
||||
if (handle)
|
||||
{
|
||||
char junk[20];
|
||||
// This looks like HidD_GetFeature with a feature report id of 0xF2 to me and a length of 17.
|
||||
// That doesn't work, however, and 17 is shorter than the report length.
|
||||
pusb_control_msg(handle, 0xa1, 1, 0x03f2, dev->config->interface->altsetting->bInterfaceNumber, 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 DS3Enum(unsigned int time)
|
||||
{
|
||||
if (time - lastDS3Enum < DOUBLE_ENUM_DELAY) {
|
||||
return;
|
||||
}
|
||||
lastDS3Enum = time;
|
||||
pusb_find_busses();
|
||||
pusb_find_devices();
|
||||
if (time - lastDS3Enum < DOUBLE_ENUM_DELAY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
lastDS3Enum = time;
|
||||
pusb_find_busses();
|
||||
pusb_find_devices();
|
||||
}
|
||||
|
||||
void DS3Check(unsigned int time)
|
||||
{
|
||||
if (time - lastDS3Check < DOUBLE_CHECK_DELAY) {
|
||||
return;
|
||||
}
|
||||
if (!lastDS3Check) {
|
||||
DS3Enum(time);
|
||||
}
|
||||
lastDS3Check = time;
|
||||
if (time - lastDS3Check < DOUBLE_CHECK_DELAY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!lastDS3Check)
|
||||
{
|
||||
DS3Enum(time);
|
||||
}
|
||||
lastDS3Check = time;
|
||||
|
||||
usb_bus *bus = pusb_get_busses();
|
||||
while (bus) {
|
||||
TryInitDS3(bus->devices);
|
||||
bus = bus->next;
|
||||
}
|
||||
usb_bus* bus = pusb_get_busses();
|
||||
while (bus)
|
||||
{
|
||||
TryInitDS3(bus->devices);
|
||||
bus = bus->next;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
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();
|
||||
return InitLibUsb();
|
||||
}
|
||||
|
||||
#include <pshpack1.h>
|
||||
|
||||
struct MotorState
|
||||
{
|
||||
unsigned char duration;
|
||||
unsigned char force;
|
||||
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;
|
||||
// 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;
|
||||
// Small is first, then big.
|
||||
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];
|
||||
unsigned char id;
|
||||
unsigned char unsure;
|
||||
// Small is first, then big.
|
||||
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 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;
|
||||
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];
|
||||
// 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 writeCount;
|
||||
int lastWrite;
|
||||
int index;
|
||||
HANDLE hFile;
|
||||
DS3Command sendState;
|
||||
unsigned char getState[49];
|
||||
OVERLAPPED readop;
|
||||
OVERLAPPED writeop;
|
||||
int writeCount;
|
||||
int lastWrite;
|
||||
|
||||
unsigned int dataLastReceived;
|
||||
unsigned int dataLastReceived;
|
||||
|
||||
int writeQueued;
|
||||
int writing;
|
||||
int writeQueued;
|
||||
int writing;
|
||||
|
||||
int StartRead()
|
||||
{
|
||||
int res = ReadFile(hFile, &getState, sizeof(getState), 0, &readop);
|
||||
return (res || GetLastError() == ERROR_IO_PENDING);
|
||||
}
|
||||
int StartRead()
|
||||
{
|
||||
int res = ReadFile(hFile, &getState, sizeof(getState), 0, &readop);
|
||||
return (res || GetLastError() == ERROR_IO_PENDING);
|
||||
}
|
||||
|
||||
void QueueWrite()
|
||||
{
|
||||
// max of 2 queued writes allowed, one for either motor.
|
||||
if (writeQueued < 2) {
|
||||
writeQueued++;
|
||||
StartWrite();
|
||||
}
|
||||
}
|
||||
void QueueWrite()
|
||||
{
|
||||
// max of 2 queued writes allowed, one for either motor.
|
||||
if (writeQueued < 2)
|
||||
{
|
||||
writeQueued++;
|
||||
StartWrite();
|
||||
}
|
||||
}
|
||||
|
||||
int StartWrite()
|
||||
{
|
||||
if (!writing && writeQueued) {
|
||||
lastWrite = GetTickCount();
|
||||
writing++;
|
||||
writeQueued--;
|
||||
sendState.motors[0].duration = 0x50;
|
||||
sendState.motors[1].duration = 0x50;
|
||||
int StartWrite()
|
||||
{
|
||||
if (!writing && writeQueued)
|
||||
{
|
||||
lastWrite = GetTickCount();
|
||||
writing++;
|
||||
writeQueued--;
|
||||
sendState.motors[0].duration = 0x50;
|
||||
sendState.motors[1].duration = 0x50;
|
||||
|
||||
int bigForce = vibration[0] * 256 / FULLY_DOWN;
|
||||
if (bigForce > 255)
|
||||
bigForce = 255;
|
||||
sendState.motors[1].force = (unsigned char)bigForce;
|
||||
sendState.motors[0].force = (unsigned char)(vibration[1] >= FULLY_DOWN / 2);
|
||||
// Can't seem to have them both non-zero at once.
|
||||
if (sendState.motors[writeCount & 1].force) {
|
||||
sendState.motors[(writeCount & 1) ^ 1].force = 0;
|
||||
sendState.motors[(writeCount & 1) ^ 1].duration = 0;
|
||||
}
|
||||
int bigForce = vibration[0] * 256 / FULLY_DOWN;
|
||||
if (bigForce > 255)
|
||||
bigForce = 255;
|
||||
sendState.motors[1].force = (unsigned char)bigForce;
|
||||
sendState.motors[0].force = (unsigned char)(vibration[1] >= FULLY_DOWN / 2);
|
||||
// Can't seem to have them both non-zero at once.
|
||||
if (sendState.motors[writeCount & 1].force)
|
||||
{
|
||||
sendState.motors[(writeCount & 1) ^ 1].force = 0;
|
||||
sendState.motors[(writeCount & 1) ^ 1].duration = 0;
|
||||
}
|
||||
|
||||
writeCount++;
|
||||
int res = WriteFile(hFile, &sendState, sizeof(sendState), 0, &writeop);
|
||||
return (res || GetLastError() == ERROR_IO_PENDING);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
writeCount++;
|
||||
int res = WriteFile(hFile, &sendState, sizeof(sendState), 0, &writeop);
|
||||
return (res || GetLastError() == ERROR_IO_PENDING);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
DualShock3Device(int index, wchar_t *name, wchar_t *path)
|
||||
: Device(DS3, OTHER, name, path, L"DualShock 3")
|
||||
{
|
||||
writeCount = 0;
|
||||
writing = 0;
|
||||
writeQueued = 0;
|
||||
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));
|
||||
vibration[0] = vibration[1] = 0;
|
||||
this->index = index;
|
||||
int i;
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (i != 14 && i != 15 && i != 8 && i != 9) {
|
||||
AddPhysicalControl(PRESSURE_BTN, i, 0);
|
||||
} else {
|
||||
AddPhysicalControl(PSHBTN, i, 0);
|
||||
}
|
||||
}
|
||||
for (; i < 23; i++) {
|
||||
AddPhysicalControl(ABSAXIS, i, 0);
|
||||
}
|
||||
AddFFAxis(L"Big Motor", 0);
|
||||
AddFFAxis(L"Small Motor", 1);
|
||||
AddFFEffectType(L"Constant Effect", L"Constant", EFFECT_CONSTANT);
|
||||
hFile = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
DualShock3Device(int index, wchar_t* name, wchar_t* path)
|
||||
: Device(DS3, OTHER, name, path, L"DualShock 3")
|
||||
{
|
||||
writeCount = 0;
|
||||
writing = 0;
|
||||
writeQueued = 0;
|
||||
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));
|
||||
vibration[0] = vibration[1] = 0;
|
||||
this->index = index;
|
||||
int i;
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if (i != 14 && i != 15 && i != 8 && i != 9)
|
||||
{
|
||||
AddPhysicalControl(PRESSURE_BTN, i, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddPhysicalControl(PSHBTN, i, 0);
|
||||
}
|
||||
}
|
||||
for (; i < 23; i++)
|
||||
{
|
||||
AddPhysicalControl(ABSAXIS, i, 0);
|
||||
}
|
||||
AddFFAxis(L"Big Motor", 0);
|
||||
AddFFAxis(L"Small 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"L-Stick X",
|
||||
L"L-Stick Y",
|
||||
L"R-Stick X",
|
||||
L"R-Stick Y",
|
||||
L"Left/Right Tilt",
|
||||
L"Forward/Back Tilt",
|
||||
L"???",
|
||||
};
|
||||
unsigned int i = (unsigned int)(c - physicalControls);
|
||||
if (i < sizeof(names) / sizeof(names[0])) {
|
||||
return (wchar_t *)names[i];
|
||||
}
|
||||
return Device::GetPhysicalControlName(c);
|
||||
}
|
||||
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"L-Stick X",
|
||||
L"L-Stick Y",
|
||||
L"R-Stick X",
|
||||
L"R-Stick Y",
|
||||
L"Left/Right Tilt",
|
||||
L"Forward/Back Tilt",
|
||||
L"???",
|
||||
};
|
||||
unsigned int i = (unsigned int)(c - physicalControls);
|
||||
if (i < sizeof(names) / sizeof(names[0]))
|
||||
{
|
||||
return (wchar_t*)names[i];
|
||||
}
|
||||
return Device::GetPhysicalControlName(c);
|
||||
}
|
||||
|
||||
int Activate(InitInfo *initInfo)
|
||||
{
|
||||
if (active)
|
||||
Deactivate();
|
||||
// Give grace period before get mad.
|
||||
lastWrite = dataLastReceived = GetTickCount();
|
||||
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()) {
|
||||
Deactivate();
|
||||
return 0;
|
||||
}
|
||||
active = 1;
|
||||
AllocState();
|
||||
return 1;
|
||||
}
|
||||
int Activate(InitInfo* initInfo)
|
||||
{
|
||||
if (active)
|
||||
Deactivate();
|
||||
// Give grace period before get mad.
|
||||
lastWrite = dataLastReceived = GetTickCount();
|
||||
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())
|
||||
{
|
||||
Deactivate();
|
||||
return 0;
|
||||
}
|
||||
active = 1;
|
||||
AllocState();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Update()
|
||||
{
|
||||
if (!active)
|
||||
return 0;
|
||||
HANDLE h[2] = {
|
||||
readop.hEvent,
|
||||
writeop.hEvent};
|
||||
unsigned int time = GetTickCount();
|
||||
if (time - lastWrite > UPDATE_INTERVAL) {
|
||||
QueueWrite();
|
||||
}
|
||||
while (1) {
|
||||
DWORD res = WaitForMultipleObjects(2, h, 0, 0);
|
||||
if (res == WAIT_OBJECT_0) {
|
||||
dataLastReceived = time;
|
||||
if (!StartRead()) {
|
||||
Deactivate();
|
||||
return 0;
|
||||
}
|
||||
int Update()
|
||||
{
|
||||
if (!active)
|
||||
return 0;
|
||||
HANDLE h[2] = {
|
||||
readop.hEvent,
|
||||
writeop.hEvent};
|
||||
unsigned int time = GetTickCount();
|
||||
if (time - lastWrite > UPDATE_INTERVAL)
|
||||
{
|
||||
QueueWrite();
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
DWORD res = WaitForMultipleObjects(2, h, 0, 0);
|
||||
if (res == WAIT_OBJECT_0)
|
||||
{
|
||||
dataLastReceived = time;
|
||||
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]);
|
||||
physicalControlState[20] = CharToAxis(getState[42] + 128);
|
||||
physicalControlState[21] = CharToAxis(getState[44] + 128);
|
||||
physicalControlState[22] = CharToAxis(getState[46] + 128);
|
||||
continue;
|
||||
} else if (res == WAIT_OBJECT_0 + 1) {
|
||||
writing = 0;
|
||||
if (!writeQueued && (vibration[0] | vibration[1])) {
|
||||
QueueWrite();
|
||||
}
|
||||
if (!StartWrite()) {
|
||||
Deactivate();
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (time - dataLastReceived >= DEVICE_CHECK_DELAY) {
|
||||
if (time - dataLastReceived >= DEVICE_ENUM_DELAY) {
|
||||
DS3Enum(time);
|
||||
}
|
||||
DS3Check(time);
|
||||
QueueWrite();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
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]);
|
||||
physicalControlState[20] = CharToAxis(getState[42] + 128);
|
||||
physicalControlState[21] = CharToAxis(getState[44] + 128);
|
||||
physicalControlState[22] = CharToAxis(getState[46] + 128);
|
||||
continue;
|
||||
}
|
||||
else if (res == WAIT_OBJECT_0 + 1)
|
||||
{
|
||||
writing = 0;
|
||||
if (!writeQueued && (vibration[0] | vibration[1]))
|
||||
{
|
||||
QueueWrite();
|
||||
}
|
||||
if (!StartWrite())
|
||||
{
|
||||
Deactivate();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (time - dataLastReceived >= DEVICE_CHECK_DELAY)
|
||||
{
|
||||
if (time - dataLastReceived >= DEVICE_ENUM_DELAY)
|
||||
{
|
||||
DS3Enum(time);
|
||||
}
|
||||
DS3Check(time);
|
||||
QueueWrite();
|
||||
}
|
||||
}
|
||||
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++) {
|
||||
int padtype = config.padConfigs[p][s].type;
|
||||
for (int i = 0; i < pads[p][s][padtype].numFFBindings; i++) {
|
||||
// Technically should also be a *65535/BASE_SENSITIVITY, but that's close enough to 1 for me.
|
||||
ForceFeedbackBinding *ffb = &pads[p][s][padtype].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);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Make sure at least 2 writes are queued, to update both motors.
|
||||
QueueWrite();
|
||||
QueueWrite();
|
||||
}
|
||||
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++)
|
||||
{
|
||||
int padtype = config.padConfigs[p][s].type;
|
||||
for (int i = 0; i < pads[p][s][padtype].numFFBindings; i++)
|
||||
{
|
||||
// Technically should also be a *65535/BASE_SENSITIVITY, but that's close enough to 1 for me.
|
||||
ForceFeedbackBinding* ffb = &pads[p][s][padtype].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);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Make sure at least 2 writes are queued, to update both motors.
|
||||
QueueWrite();
|
||||
QueueWrite();
|
||||
}
|
||||
|
||||
void SetEffect(ForceFeedbackBinding *binding, unsigned char force)
|
||||
{
|
||||
PadBindings pBackup = pads[0][0][0];
|
||||
pads[0][0][0].ffBindings = binding;
|
||||
pads[0][0][0].numFFBindings = 1;
|
||||
SetEffects(0, 0, binding->motor, 255);
|
||||
pads[0][0][0] = pBackup;
|
||||
}
|
||||
void SetEffect(ForceFeedbackBinding* binding, unsigned char force)
|
||||
{
|
||||
PadBindings pBackup = pads[0][0][0];
|
||||
pads[0][0][0].ffBindings = binding;
|
||||
pads[0][0][0].numFFBindings = 1;
|
||||
SetEffects(0, 0, binding->motor, 255);
|
||||
pads[0][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);
|
||||
}
|
||||
writing = 0;
|
||||
writeQueued = 0;
|
||||
memset(ps2Vibration, 0, sizeof(ps2Vibration));
|
||||
vibration[0] = vibration[1] = 0;
|
||||
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);
|
||||
}
|
||||
writing = 0;
|
||||
writeQueued = 0;
|
||||
memset(ps2Vibration, 0, sizeof(ps2Vibration));
|
||||
vibration[0] = vibration[1] = 0;
|
||||
|
||||
FreeState();
|
||||
active = 0;
|
||||
}
|
||||
FreeState();
|
||||
active = 0;
|
||||
}
|
||||
|
||||
~DualShock3Device()
|
||||
{
|
||||
}
|
||||
~DualShock3Device()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
void EnumDualShock3s()
|
||||
{
|
||||
if (!InitLibUsb())
|
||||
return;
|
||||
if (!InitLibUsb())
|
||||
return;
|
||||
|
||||
HidDeviceInfo *foundDevs = 0;
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -45,40 +45,40 @@ typedef int64_t __int64;
|
|||
#include <cstdarg>
|
||||
|
||||
template <typename Array>
|
||||
void wsprintfW(Array &buf, const wchar_t *format, ...)
|
||||
void wsprintfW(Array& buf, const wchar_t* format, ...)
|
||||
{
|
||||
va_list a;
|
||||
va_start(a, format);
|
||||
va_list a;
|
||||
va_start(a, format);
|
||||
|
||||
vswprintf(buf, sizeof(buf) / sizeof(buf[0]), format, a);
|
||||
vswprintf(buf, sizeof(buf) / sizeof(buf[0]), format, a);
|
||||
|
||||
va_end(a);
|
||||
va_end(a);
|
||||
}
|
||||
|
||||
template <typename Array>
|
||||
void wsprintf(Array &buf, const wchar_t *format, ...)
|
||||
void wsprintf(Array& buf, const wchar_t* format, ...)
|
||||
{
|
||||
va_list a;
|
||||
va_start(a, format);
|
||||
va_list a;
|
||||
va_start(a, format);
|
||||
|
||||
vswprintf(buf, sizeof(buf) / sizeof(buf[0]), format, a);
|
||||
vswprintf(buf, sizeof(buf) / sizeof(buf[0]), format, a);
|
||||
|
||||
va_end(a);
|
||||
va_end(a);
|
||||
}
|
||||
|
||||
static inline int wcsicmp(const wchar_t *w1, const wchar_t *w2)
|
||||
static inline int wcsicmp(const wchar_t* w1, const wchar_t* w2)
|
||||
{
|
||||
// I didn't find a way to put ignore case ...
|
||||
return wcscmp(w1, w2);
|
||||
// I didn't find a way to put ignore case ...
|
||||
return wcscmp(w1, w2);
|
||||
}
|
||||
|
||||
#include <sys/time.h>
|
||||
static inline unsigned int timeGetTime()
|
||||
{
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
uint64_t ms = (now.tv_usec / 1000) + ((uint64_t)now.tv_sec * 1000);
|
||||
return (ms & 0xFFFFFFFF); // MS code is u32 ...
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
uint64_t ms = (now.tv_usec / 1000) + ((uint64_t)now.tv_sec * 1000);
|
||||
return (ms & 0xFFFFFFFF); // MS code is u32 ...
|
||||
}
|
||||
|
||||
#include "Utilities/Dependencies.h"
|
||||
|
@ -87,7 +87,7 @@ static inline unsigned int timeGetTime()
|
|||
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
extern Display *GSdsp;
|
||||
extern Display* GSdsp;
|
||||
extern Window GSwin;
|
||||
|
||||
#endif
|
||||
|
@ -134,4 +134,4 @@ extern Window GSwin;
|
|||
extern HINSTANCE hInst;
|
||||
#endif
|
||||
// Needed for config screen
|
||||
void GetNameAndVersionString(wchar_t *out);
|
||||
void GetNameAndVersionString(wchar_t* out);
|
|
@ -19,61 +19,69 @@
|
|||
#include <setupapi.h>
|
||||
#include <hidsdi.h>
|
||||
|
||||
int FindHids(HidDeviceInfo **foundDevs, int vid, int pid)
|
||||
int FindHids(HidDeviceInfo** foundDevs, int vid, int pid)
|
||||
{
|
||||
GUID GUID_DEVINTERFACE_HID;
|
||||
int numFoundDevs = 0;
|
||||
*foundDevs = 0;
|
||||
HidD_GetHidGuid(&GUID_DEVINTERFACE_HID);
|
||||
HDEVINFO hdev = SetupDiGetClassDevs(&GUID_DEVINTERFACE_HID, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||||
if (hdev != INVALID_HANDLE_VALUE) {
|
||||
SP_DEVICE_INTERFACE_DATA devInterfaceData;
|
||||
devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
|
||||
for (int i = 0; SetupDiEnumDeviceInterfaces(hdev, 0, &GUID_DEVINTERFACE_HID, i, &devInterfaceData); i++) {
|
||||
GUID GUID_DEVINTERFACE_HID;
|
||||
int numFoundDevs = 0;
|
||||
*foundDevs = 0;
|
||||
HidD_GetHidGuid(&GUID_DEVINTERFACE_HID);
|
||||
HDEVINFO hdev = SetupDiGetClassDevs(&GUID_DEVINTERFACE_HID, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||||
if (hdev != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SP_DEVICE_INTERFACE_DATA devInterfaceData;
|
||||
devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
|
||||
for (int i = 0; SetupDiEnumDeviceInterfaces(hdev, 0, &GUID_DEVINTERFACE_HID, i, &devInterfaceData); i++)
|
||||
{
|
||||
|
||||
DWORD size = 0;
|
||||
SetupDiGetDeviceInterfaceDetail(hdev, &devInterfaceData, 0, 0, &size, 0);
|
||||
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER || !size)
|
||||
continue;
|
||||
SP_DEVICE_INTERFACE_DETAIL_DATA *devInterfaceDetails = (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(size);
|
||||
if (!devInterfaceDetails)
|
||||
continue;
|
||||
DWORD size = 0;
|
||||
SetupDiGetDeviceInterfaceDetail(hdev, &devInterfaceData, 0, 0, &size, 0);
|
||||
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER || !size)
|
||||
continue;
|
||||
SP_DEVICE_INTERFACE_DETAIL_DATA* devInterfaceDetails = (SP_DEVICE_INTERFACE_DETAIL_DATA*)malloc(size);
|
||||
if (!devInterfaceDetails)
|
||||
continue;
|
||||
|
||||
devInterfaceDetails->cbSize = sizeof(*devInterfaceDetails);
|
||||
SP_DEVINFO_DATA devInfoData;
|
||||
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
|
||||
devInterfaceDetails->cbSize = sizeof(*devInterfaceDetails);
|
||||
SP_DEVINFO_DATA devInfoData;
|
||||
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
|
||||
|
||||
if (!SetupDiGetDeviceInterfaceDetail(hdev, &devInterfaceData, devInterfaceDetails, size, &size, &devInfoData))
|
||||
continue;
|
||||
if (!SetupDiGetDeviceInterfaceDetail(hdev, &devInterfaceData, devInterfaceDetails, size, &size, &devInfoData))
|
||||
continue;
|
||||
|
||||
HANDLE hfile = CreateFile(devInterfaceDetails->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
|
||||
if (hfile != INVALID_HANDLE_VALUE) {
|
||||
HIDD_ATTRIBUTES attributes;
|
||||
attributes.Size = sizeof(attributes);
|
||||
if (HidD_GetAttributes(hfile, &attributes)) {
|
||||
if (attributes.VendorID == vid && attributes.ProductID == pid) {
|
||||
PHIDP_PREPARSED_DATA pData;
|
||||
HIDP_CAPS caps;
|
||||
if (HidD_GetPreparsedData(hfile, &pData)) {
|
||||
if (HidP_GetCaps(pData, &caps) == HIDP_STATUS_SUCCESS) {
|
||||
if (numFoundDevs % 32 == 0) {
|
||||
*foundDevs = (HidDeviceInfo *)realloc(*foundDevs, sizeof(HidDeviceInfo) * (32 + numFoundDevs));
|
||||
}
|
||||
HidDeviceInfo *dev = &foundDevs[0][numFoundDevs++];
|
||||
dev->caps = caps;
|
||||
dev->vid = attributes.VendorID;
|
||||
dev->pid = attributes.ProductID;
|
||||
dev->path = wcsdup(devInterfaceDetails->DevicePath);
|
||||
}
|
||||
HidD_FreePreparsedData(pData);
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(hfile);
|
||||
}
|
||||
free(devInterfaceDetails);
|
||||
}
|
||||
SetupDiDestroyDeviceInfoList(hdev);
|
||||
}
|
||||
return numFoundDevs;
|
||||
HANDLE hfile = CreateFile(devInterfaceDetails->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
|
||||
if (hfile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
HIDD_ATTRIBUTES attributes;
|
||||
attributes.Size = sizeof(attributes);
|
||||
if (HidD_GetAttributes(hfile, &attributes))
|
||||
{
|
||||
if (attributes.VendorID == vid && attributes.ProductID == pid)
|
||||
{
|
||||
PHIDP_PREPARSED_DATA pData;
|
||||
HIDP_CAPS caps;
|
||||
if (HidD_GetPreparsedData(hfile, &pData))
|
||||
{
|
||||
if (HidP_GetCaps(pData, &caps) == HIDP_STATUS_SUCCESS)
|
||||
{
|
||||
if (numFoundDevs % 32 == 0)
|
||||
{
|
||||
*foundDevs = (HidDeviceInfo*)realloc(*foundDevs, sizeof(HidDeviceInfo) * (32 + numFoundDevs));
|
||||
}
|
||||
HidDeviceInfo* dev = &foundDevs[0][numFoundDevs++];
|
||||
dev->caps = caps;
|
||||
dev->vid = attributes.VendorID;
|
||||
dev->pid = attributes.ProductID;
|
||||
dev->path = wcsdup(devInterfaceDetails->DevicePath);
|
||||
}
|
||||
HidD_FreePreparsedData(pData);
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(hfile);
|
||||
}
|
||||
free(devInterfaceDetails);
|
||||
}
|
||||
SetupDiDestroyDeviceInfoList(hdev);
|
||||
}
|
||||
return numFoundDevs;
|
||||
}
|
||||
|
|
|
@ -20,12 +20,12 @@
|
|||
|
||||
struct HidDeviceInfo
|
||||
{
|
||||
HIDP_CAPS caps;
|
||||
wchar_t *path;
|
||||
unsigned short vid;
|
||||
unsigned short pid;
|
||||
HIDP_CAPS caps;
|
||||
wchar_t* path;
|
||||
unsigned short vid;
|
||||
unsigned short pid;
|
||||
};
|
||||
|
||||
int FindHids(HidDeviceInfo **foundDevs, int vid, int pid);
|
||||
int FindHids(HidDeviceInfo** foundDevs, int vid, int pid);
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -31,42 +31,44 @@
|
|||
* Still more effort than it's worth to port to Linux, however.
|
||||
*/
|
||||
|
||||
enum PadType {
|
||||
DisabledPad,
|
||||
Dualshock2Pad,
|
||||
GuitarPad,
|
||||
PopnPad,
|
||||
MousePad,
|
||||
neGconPad,
|
||||
numPadTypes // total number of PadTypes. Add new PadType above this line.
|
||||
enum PadType
|
||||
{
|
||||
DisabledPad,
|
||||
Dualshock2Pad,
|
||||
GuitarPad,
|
||||
PopnPad,
|
||||
MousePad,
|
||||
neGconPad,
|
||||
numPadTypes // total number of PadTypes. Add new PadType above this line.
|
||||
};
|
||||
|
||||
// Mostly match DirectInput8 values. Note that these are for physical controls.
|
||||
// One physical axis maps to 3 virtual ones, and one physical POV control maps to
|
||||
// 4 virtual ones.
|
||||
enum ControlType {
|
||||
NO_CONTROL = 0,
|
||||
// Axes are ints. Relative axes are for mice, mice wheels, etc,
|
||||
// and are always reported relative to their last value.
|
||||
// Absolute axes range from -65536 to 65536 and are absolute positions,
|
||||
// like for joysticks and pressure sensitive buttons.
|
||||
RELAXIS = 1,
|
||||
ABSAXIS = 2,
|
||||
enum ControlType
|
||||
{
|
||||
NO_CONTROL = 0,
|
||||
// Axes are ints. Relative axes are for mice, mice wheels, etc,
|
||||
// and are always reported relative to their last value.
|
||||
// Absolute axes range from -65536 to 65536 and are absolute positions,
|
||||
// like for joysticks and pressure sensitive buttons.
|
||||
RELAXIS = 1,
|
||||
ABSAXIS = 2,
|
||||
|
||||
// Buttons range from 0 to 65536.
|
||||
PSHBTN = 4,
|
||||
TGLBTN = 8,
|
||||
// Buttons range from 0 to 65536.
|
||||
PSHBTN = 4,
|
||||
TGLBTN = 8,
|
||||
|
||||
// POV controls are ints, values range from -1 to 36000.
|
||||
// -1 means not pressed, otherwise it's an angle.
|
||||
// For easy DirectInput compatibility, anything outside.
|
||||
// that range is treated as -1 (Though 36000-37000 is treated
|
||||
// like 0 to 1000, just in case).
|
||||
POV = 16,
|
||||
// POV controls are ints, values range from -1 to 36000.
|
||||
// -1 means not pressed, otherwise it's an angle.
|
||||
// For easy DirectInput compatibility, anything outside.
|
||||
// that range is treated as -1 (Though 36000-37000 is treated
|
||||
// like 0 to 1000, just in case).
|
||||
POV = 16,
|
||||
|
||||
// Pressure sensitive buttons. Only a different type because
|
||||
// they have configurable dead zones, unlike push or toggle buttons.
|
||||
PRESSURE_BTN = 32,
|
||||
// Pressure sensitive buttons. Only a different type because
|
||||
// they have configurable dead zones, unlike push or toggle buttons.
|
||||
PRESSURE_BTN = 32,
|
||||
};
|
||||
|
||||
// Masks to determine button type. Don't need one for POV.
|
||||
|
@ -76,12 +78,12 @@ enum ControlType {
|
|||
|
||||
struct Binding
|
||||
{
|
||||
int controlIndex;
|
||||
int command;
|
||||
int sensitivity;
|
||||
int deadZone;
|
||||
int skipDeadZone;
|
||||
unsigned char rapidFire;
|
||||
int controlIndex;
|
||||
int command;
|
||||
int sensitivity;
|
||||
int deadZone;
|
||||
int skipDeadZone;
|
||||
unsigned char rapidFire;
|
||||
};
|
||||
|
||||
#define UID_AXIS (1U << 31)
|
||||
|
@ -101,13 +103,13 @@ struct Binding
|
|||
// all directions are assigned individually.
|
||||
struct VirtualControl
|
||||
{
|
||||
// Unique id for control, given device. Based on source control's id,
|
||||
// source control type, axis/pov flags if it's a pov/axis (Rather than
|
||||
// a button or a pov/axis control's individual button), and an index,
|
||||
// if the control is split.
|
||||
unsigned int uid;
|
||||
// virtual key code. 0 if none.
|
||||
int physicalControlIndex;
|
||||
// Unique id for control, given device. Based on source control's id,
|
||||
// source control type, axis/pov flags if it's a pov/axis (Rather than
|
||||
// a button or a pov/axis control's individual button), and an index,
|
||||
// if the control is split.
|
||||
unsigned int uid;
|
||||
// virtual key code. 0 if none.
|
||||
int physicalControlIndex;
|
||||
};
|
||||
|
||||
// Need one for each button, axis, and pov control.
|
||||
|
@ -117,48 +119,51 @@ struct VirtualControl
|
|||
// needed.
|
||||
struct PhysicalControl
|
||||
{
|
||||
// index of the first virtual control corresponding to this.
|
||||
// Buttons have 1 virtual control, axes 3, and povs 5, all
|
||||
// in a row.
|
||||
int baseVirtualControlIndex;
|
||||
ControlType type;
|
||||
// id. Must be unique for control type.
|
||||
// short so can be combined with other values to get
|
||||
// uid for virtual controls.
|
||||
unsigned short id;
|
||||
unsigned short vkey;
|
||||
wchar_t *name;
|
||||
// index of the first virtual control corresponding to this.
|
||||
// Buttons have 1 virtual control, axes 3, and povs 5, all
|
||||
// in a row.
|
||||
int baseVirtualControlIndex;
|
||||
ControlType type;
|
||||
// id. Must be unique for control type.
|
||||
// short so can be combined with other values to get
|
||||
// uid for virtual controls.
|
||||
unsigned short id;
|
||||
unsigned short vkey;
|
||||
wchar_t* name;
|
||||
};
|
||||
|
||||
enum DeviceAPI {
|
||||
NO_API = 0,
|
||||
DI = 1,
|
||||
WM = 2,
|
||||
RAW = 3,
|
||||
XINPUT = 4,
|
||||
DS3 = 5,
|
||||
// Not currently used.
|
||||
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 = 7,
|
||||
// XXX
|
||||
LNX_KEYBOARD = 16,
|
||||
LNX_JOY = 17,
|
||||
enum DeviceAPI
|
||||
{
|
||||
NO_API = 0,
|
||||
DI = 1,
|
||||
WM = 2,
|
||||
RAW = 3,
|
||||
XINPUT = 4,
|
||||
DS3 = 5,
|
||||
// Not currently used.
|
||||
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 = 7,
|
||||
// XXX
|
||||
LNX_KEYBOARD = 16,
|
||||
LNX_JOY = 17,
|
||||
};
|
||||
|
||||
enum DeviceType {
|
||||
NO_DEVICE = 0,
|
||||
KEYBOARD = 1,
|
||||
MOUSE = 2,
|
||||
OTHER = 3
|
||||
enum DeviceType
|
||||
{
|
||||
NO_DEVICE = 0,
|
||||
KEYBOARD = 1,
|
||||
MOUSE = 2,
|
||||
OTHER = 3
|
||||
};
|
||||
|
||||
enum EffectType {
|
||||
EFFECT_CONSTANT,
|
||||
EFFECT_PERIODIC,
|
||||
EFFECT_RAMP
|
||||
enum EffectType
|
||||
{
|
||||
EFFECT_CONSTANT,
|
||||
EFFECT_PERIODIC,
|
||||
EFFECT_RAMP
|
||||
};
|
||||
|
||||
// force range sfrom -BASE_SENSITIVITY to BASE_SENSITIVITY.
|
||||
|
@ -167,32 +172,32 @@ enum EffectType {
|
|||
// the axis with minimum force (Possibly 0 force), if applicable.
|
||||
struct AxisEffectInfo
|
||||
{
|
||||
int force;
|
||||
int force;
|
||||
};
|
||||
|
||||
struct ForceFeedbackBinding
|
||||
{
|
||||
AxisEffectInfo *axes;
|
||||
int effectIndex;
|
||||
unsigned char motor;
|
||||
AxisEffectInfo* axes;
|
||||
int effectIndex;
|
||||
unsigned char motor;
|
||||
};
|
||||
|
||||
// Bindings listed by effect, so I don't have to bother with
|
||||
// indexing effects.
|
||||
struct ForceFeedbackEffectType
|
||||
{
|
||||
wchar_t *displayName;
|
||||
// Because I'm lazy, can only have ASCII characters and no spaces.
|
||||
wchar_t *effectID;
|
||||
// constant, ramp, or periodic
|
||||
EffectType type;
|
||||
wchar_t* displayName;
|
||||
// Because I'm lazy, can only have ASCII characters and no spaces.
|
||||
wchar_t* effectID;
|
||||
// constant, ramp, or periodic
|
||||
EffectType type;
|
||||
};
|
||||
|
||||
|
||||
struct ForceFeedbackAxis
|
||||
{
|
||||
wchar_t *displayName;
|
||||
int id;
|
||||
wchar_t* displayName;
|
||||
int id;
|
||||
};
|
||||
|
||||
// Used both for active devices and for sets of settings for devices.
|
||||
|
@ -203,32 +208,32 @@ struct ForceFeedbackAxis
|
|||
|
||||
struct PadBindings
|
||||
{
|
||||
Binding *bindings;
|
||||
int numBindings;
|
||||
ForceFeedbackBinding *ffBindings;
|
||||
int numFFBindings;
|
||||
Binding* bindings;
|
||||
int numBindings;
|
||||
ForceFeedbackBinding* ffBindings;
|
||||
int numFFBindings;
|
||||
};
|
||||
|
||||
class WndProcEater;
|
||||
|
||||
struct InitInfo
|
||||
{
|
||||
// 1 when binding key to ignore.
|
||||
int bindingIgnore;
|
||||
// 1 when binding.
|
||||
int binding;
|
||||
// 1 when binding key to ignore.
|
||||
int bindingIgnore;
|
||||
// 1 when binding.
|
||||
int binding;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
HWND hWndTop;
|
||||
HWND hWndTop;
|
||||
|
||||
// For config screen, need to eat button's message handling.
|
||||
//HWND hWndButton;
|
||||
// For config screen, need to eat button's message handling.
|
||||
//HWND hWndButton;
|
||||
|
||||
WndProcEater *hWndProc;
|
||||
WndProcEater* hWndProc;
|
||||
#else
|
||||
// Linux equivalent to HWND
|
||||
Display *GSdsp;
|
||||
Window GSwin;
|
||||
// Linux equivalent to HWND
|
||||
Display* GSdsp;
|
||||
Window GSwin;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -238,165 +243,165 @@ struct InitInfo
|
|||
class Device
|
||||
{
|
||||
public:
|
||||
DeviceAPI api;
|
||||
DeviceType type;
|
||||
char active;
|
||||
char attached;
|
||||
// Based on input modes.
|
||||
char enabled;
|
||||
DeviceAPI api;
|
||||
DeviceType type;
|
||||
char active;
|
||||
char attached;
|
||||
// Based on input modes.
|
||||
char enabled;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// Not all devices need to subclass the windproc, but most do so might as well
|
||||
// put it here... --air
|
||||
WndProcEater *hWndProc;
|
||||
// Not all devices need to subclass the windproc, but most do so might as well
|
||||
// put it here... --air
|
||||
WndProcEater* hWndProc;
|
||||
#endif
|
||||
|
||||
union
|
||||
{
|
||||
// Allows for one loop to compare all 3 in order.
|
||||
wchar_t *IDs[3];
|
||||
struct
|
||||
{
|
||||
// Same as DisplayName, when not given. Absolutely must be unique.
|
||||
// Used for loading/saving controls. If matches, all other strings
|
||||
// are ignored, so must be unique.
|
||||
wchar_t *instanceID;
|
||||
// Not required. Used when a device's instance id changes, doesn't have to
|
||||
// be unique. For devices that can only have one instance, not needed.
|
||||
wchar_t *productID;
|
||||
union
|
||||
{
|
||||
// Allows for one loop to compare all 3 in order.
|
||||
wchar_t* IDs[3];
|
||||
struct
|
||||
{
|
||||
// Same as DisplayName, when not given. Absolutely must be unique.
|
||||
// Used for loading/saving controls. If matches, all other strings
|
||||
// are ignored, so must be unique.
|
||||
wchar_t* instanceID;
|
||||
// Not required. Used when a device's instance id changes, doesn't have to
|
||||
// be unique. For devices that can only have one instance, not needed.
|
||||
wchar_t* productID;
|
||||
|
||||
wchar_t *displayName;
|
||||
};
|
||||
};
|
||||
wchar_t* displayName;
|
||||
};
|
||||
};
|
||||
|
||||
PadBindings pads[2][4][numPadTypes];
|
||||
PadBindings pads[2][4][numPadTypes];
|
||||
|
||||
// Virtual controls. All basically act like pressure sensitivity buttons, with
|
||||
// values between 0 and 2^16. 2^16 is fully down, 0 is up. Larger values
|
||||
// are allowed, but *only* for absolute axes (Which don't support the flip checkbox).
|
||||
// Each control on a device must have a unique id, used for binding.
|
||||
VirtualControl *virtualControls;
|
||||
int numVirtualControls;
|
||||
// Virtual controls. All basically act like pressure sensitivity buttons, with
|
||||
// values between 0 and 2^16. 2^16 is fully down, 0 is up. Larger values
|
||||
// are allowed, but *only* for absolute axes (Which don't support the flip checkbox).
|
||||
// Each control on a device must have a unique id, used for binding.
|
||||
VirtualControl* virtualControls;
|
||||
int numVirtualControls;
|
||||
|
||||
int *virtualControlState;
|
||||
int *oldVirtualControlState;
|
||||
int* virtualControlState;
|
||||
int* oldVirtualControlState;
|
||||
|
||||
PhysicalControl *physicalControls;
|
||||
int numPhysicalControls;
|
||||
int *physicalControlState;
|
||||
PhysicalControl* physicalControls;
|
||||
int numPhysicalControls;
|
||||
int* physicalControlState;
|
||||
|
||||
ForceFeedbackEffectType *ffEffectTypes;
|
||||
int numFFEffectTypes;
|
||||
ForceFeedbackAxis *ffAxes;
|
||||
int numFFAxes;
|
||||
void AddFFAxis(const wchar_t *displayName, int id);
|
||||
void AddFFEffectType(const wchar_t *displayName, const wchar_t *effectID, EffectType type);
|
||||
ForceFeedbackEffectType* ffEffectTypes;
|
||||
int numFFEffectTypes;
|
||||
ForceFeedbackAxis* ffAxes;
|
||||
int numFFAxes;
|
||||
void AddFFAxis(const wchar_t* displayName, int id);
|
||||
void AddFFEffectType(const wchar_t* displayName, const wchar_t* effectID, EffectType type);
|
||||
|
||||
Device(DeviceAPI, DeviceType, const wchar_t *displayName, const wchar_t *instanceID = 0, const wchar_t *deviceID = 0);
|
||||
virtual ~Device();
|
||||
Device(DeviceAPI, DeviceType, const wchar_t* displayName, const wchar_t* instanceID = 0, const wchar_t* deviceID = 0);
|
||||
virtual ~Device();
|
||||
|
||||
// Allocates memory for old and new state, sets everything to 0.
|
||||
// all old states are in one array, buttons, axes, and then POVs.
|
||||
// start of each section is int aligned. This makes it DirectInput
|
||||
// compatible.
|
||||
void AllocState();
|
||||
// Allocates memory for old and new state, sets everything to 0.
|
||||
// all old states are in one array, buttons, axes, and then POVs.
|
||||
// start of each section is int aligned. This makes it DirectInput
|
||||
// compatible.
|
||||
void AllocState();
|
||||
|
||||
// Doesn't actually flip. Copies current state to old state.
|
||||
void FlipState();
|
||||
// Doesn't actually flip. Copies current state to old state.
|
||||
void FlipState();
|
||||
|
||||
// Frees state variables.
|
||||
void FreeState();
|
||||
// Frees state variables.
|
||||
void FreeState();
|
||||
|
||||
ForceFeedbackEffectType *GetForcefeedbackEffect(wchar_t *id);
|
||||
ForceFeedbackAxis *GetForceFeedbackAxis(int id);
|
||||
ForceFeedbackEffectType* GetForcefeedbackEffect(wchar_t* id);
|
||||
ForceFeedbackAxis* GetForceFeedbackAxis(int id);
|
||||
|
||||
VirtualControl *GetVirtualControl(unsigned int uid);
|
||||
VirtualControl* GetVirtualControl(unsigned int uid);
|
||||
|
||||
PhysicalControl *AddPhysicalControl(ControlType type, unsigned short id, unsigned short vkey, const wchar_t *name = 0);
|
||||
VirtualControl *AddVirtualControl(unsigned int uid, int physicalControlIndex);
|
||||
PhysicalControl* AddPhysicalControl(ControlType type, unsigned short id, unsigned short vkey, const wchar_t* name = 0);
|
||||
VirtualControl* AddVirtualControl(unsigned int uid, int physicalControlIndex);
|
||||
|
||||
virtual wchar_t *GetVirtualControlName(VirtualControl *c);
|
||||
virtual wchar_t *GetPhysicalControlName(PhysicalControl *c);
|
||||
virtual wchar_t* GetVirtualControlName(VirtualControl* c);
|
||||
virtual wchar_t* GetPhysicalControlName(PhysicalControl* c);
|
||||
|
||||
void CalcVirtualState();
|
||||
void CalcVirtualState();
|
||||
|
||||
virtual int Activate(InitInfo *args)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
virtual int Activate(InitInfo* args)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline virtual void Deactivate()
|
||||
{
|
||||
FreeState();
|
||||
active = 0;
|
||||
}
|
||||
inline virtual void Deactivate()
|
||||
{
|
||||
FreeState();
|
||||
active = 0;
|
||||
}
|
||||
|
||||
// Default update proc. All that's needed for post-based APIs.
|
||||
inline virtual int Update()
|
||||
{
|
||||
return active;
|
||||
}
|
||||
// Default update proc. All that's needed for post-based APIs.
|
||||
inline virtual int Update()
|
||||
{
|
||||
return active;
|
||||
}
|
||||
|
||||
// force is from -FULLY_DOWN to FULLY_DOWN.
|
||||
// Either function can be overridden. Second one by default calls the first
|
||||
// for every bound effect that's affected.
|
||||
// force is from -FULLY_DOWN to FULLY_DOWN.
|
||||
// Either function can be overridden. Second one by default calls the first
|
||||
// for every bound effect that's affected.
|
||||
|
||||
// Note: Only used externally for binding, so if override the other one, can assume
|
||||
// all other forces are currently 0.
|
||||
inline virtual void SetEffect(ForceFeedbackBinding *binding, unsigned char force) {}
|
||||
virtual void SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force);
|
||||
// Note: Only used externally for binding, so if override the other one, can assume
|
||||
// all other forces are currently 0.
|
||||
inline virtual void SetEffect(ForceFeedbackBinding* binding, unsigned char force) {}
|
||||
virtual void SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force);
|
||||
|
||||
// Called after reading. Basically calls FlipState().
|
||||
// Some device types (Those that don't incrementally update)
|
||||
// could call FlipState elsewhere, but this makes it simpler to ignore
|
||||
// while binding.
|
||||
virtual void PostRead();
|
||||
// Called after reading. Basically calls FlipState().
|
||||
// Some device types (Those that don't incrementally update)
|
||||
// could call FlipState elsewhere, but this makes it simpler to ignore
|
||||
// while binding.
|
||||
virtual void PostRead();
|
||||
};
|
||||
|
||||
class InputDeviceManager
|
||||
{
|
||||
public:
|
||||
Device **devices;
|
||||
int numDevices;
|
||||
Device** devices;
|
||||
int numDevices;
|
||||
|
||||
void ClearDevices();
|
||||
void ClearDevices();
|
||||
|
||||
// When refreshing devices, back up old devices, then
|
||||
// populate this with new devices, then call copy bindings.
|
||||
// All old bindings are copied to matching devices.
|
||||
// When refreshing devices, back up old devices, then
|
||||
// populate this with new devices, then call copy bindings.
|
||||
// All old bindings are copied to matching devices.
|
||||
|
||||
// When old devices are missing, I do a slightly more careful search
|
||||
// using productIDs and then (in desperation) displayName.
|
||||
// Finally create new dummy devices if no matches found.
|
||||
void CopyBindings(int numDevices, Device **devices);
|
||||
// When old devices are missing, I do a slightly more careful search
|
||||
// using productIDs and then (in desperation) displayName.
|
||||
// Finally create new dummy devices if no matches found.
|
||||
void CopyBindings(int numDevices, Device** devices);
|
||||
|
||||
|
||||
InputDeviceManager();
|
||||
~InputDeviceManager();
|
||||
InputDeviceManager();
|
||||
~InputDeviceManager();
|
||||
|
||||
void AddDevice(Device *d);
|
||||
Device *GetActiveDevice(InitInfo *info, unsigned int *uid, int *index, int *value);
|
||||
void Update(InitInfo *initInfo);
|
||||
void AddDevice(Device* d);
|
||||
Device* GetActiveDevice(InitInfo* info, unsigned int* uid, int* index, int* value);
|
||||
void Update(InitInfo* initInfo);
|
||||
|
||||
// Called after reading state, after Update().
|
||||
void PostRead();
|
||||
// Called after reading state, after Update().
|
||||
void PostRead();
|
||||
|
||||
void SetEffect(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force);
|
||||
void SetEffect(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force);
|
||||
|
||||
// Update does this as needed.
|
||||
// void GetInput(void *v);
|
||||
void ReleaseInput();
|
||||
// Update does this as needed.
|
||||
// void GetInput(void *v);
|
||||
void ReleaseInput();
|
||||
|
||||
void DisableDevice(int index);
|
||||
inline void EnableDevice(int i)
|
||||
{
|
||||
devices[i]->enabled = 1;
|
||||
}
|
||||
void DisableDevice(int index);
|
||||
inline void EnableDevice(int i)
|
||||
{
|
||||
devices[i]->enabled = 1;
|
||||
}
|
||||
|
||||
void EnableDevices(DeviceType type, DeviceAPI api);
|
||||
void DisableAllDevices();
|
||||
void EnableDevices(DeviceType type, DeviceAPI api);
|
||||
void DisableAllDevices();
|
||||
};
|
||||
|
||||
extern InputDeviceManager *dm;
|
||||
extern InputDeviceManager* dm;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -36,65 +36,70 @@ static keyEvent queuedEvents[EVENT_QUEUE_LEN];
|
|||
void QueueKeyEvent(int key, int event)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
if (!csInitialized) {
|
||||
csInitialized = 1;
|
||||
InitializeCriticalSection(&cSection);
|
||||
}
|
||||
EnterCriticalSection(&cSection);
|
||||
if (!csInitialized)
|
||||
{
|
||||
csInitialized = 1;
|
||||
InitializeCriticalSection(&cSection);
|
||||
}
|
||||
EnterCriticalSection(&cSection);
|
||||
#else
|
||||
std::lock_guard<std::mutex> lock(cSection);
|
||||
std::lock_guard<std::mutex> lock(cSection);
|
||||
#endif
|
||||
|
||||
// Don't queue events if escape is on top of queue. This is just for safety
|
||||
// purposes when a game is killing the emulator for whatever reason.
|
||||
if (nextQueuedEvent == lastQueuedEvent ||
|
||||
queuedEvents[nextQueuedEvent].key != VK_ESCAPE ||
|
||||
queuedEvents[nextQueuedEvent].evt != KEYPRESS) {
|
||||
// Clear queue on escape down, bringing escape to front. May do something
|
||||
// with shift/ctrl/alt and F-keys, later.
|
||||
if (event == KEYPRESS && key == VK_ESCAPE) {
|
||||
nextQueuedEvent = lastQueuedEvent;
|
||||
}
|
||||
// Don't queue events if escape is on top of queue. This is just for safety
|
||||
// purposes when a game is killing the emulator for whatever reason.
|
||||
if (nextQueuedEvent == lastQueuedEvent ||
|
||||
queuedEvents[nextQueuedEvent].key != VK_ESCAPE ||
|
||||
queuedEvents[nextQueuedEvent].evt != KEYPRESS)
|
||||
{
|
||||
// Clear queue on escape down, bringing escape to front. May do something
|
||||
// with shift/ctrl/alt and F-keys, later.
|
||||
if (event == KEYPRESS && key == VK_ESCAPE)
|
||||
{
|
||||
nextQueuedEvent = lastQueuedEvent;
|
||||
}
|
||||
|
||||
queuedEvents[lastQueuedEvent].key = key;
|
||||
queuedEvents[lastQueuedEvent].evt = event;
|
||||
queuedEvents[lastQueuedEvent].key = key;
|
||||
queuedEvents[lastQueuedEvent].evt = event;
|
||||
|
||||
lastQueuedEvent = (lastQueuedEvent + 1) % EVENT_QUEUE_LEN;
|
||||
// If queue wrapped around, remove last element.
|
||||
if (nextQueuedEvent == lastQueuedEvent) {
|
||||
nextQueuedEvent = (nextQueuedEvent + 1) % EVENT_QUEUE_LEN;
|
||||
}
|
||||
}
|
||||
lastQueuedEvent = (lastQueuedEvent + 1) % EVENT_QUEUE_LEN;
|
||||
// If queue wrapped around, remove last element.
|
||||
if (nextQueuedEvent == lastQueuedEvent)
|
||||
{
|
||||
nextQueuedEvent = (nextQueuedEvent + 1) % EVENT_QUEUE_LEN;
|
||||
}
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
LeaveCriticalSection(&cSection);
|
||||
LeaveCriticalSection(&cSection);
|
||||
#endif
|
||||
}
|
||||
|
||||
int GetQueuedKeyEvent(keyEvent *event)
|
||||
int GetQueuedKeyEvent(keyEvent* event)
|
||||
{
|
||||
if (lastQueuedEvent == nextQueuedEvent)
|
||||
return 0;
|
||||
if (lastQueuedEvent == nextQueuedEvent)
|
||||
return 0;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
EnterCriticalSection(&cSection);
|
||||
EnterCriticalSection(&cSection);
|
||||
#else
|
||||
std::lock_guard<std::mutex> lock(cSection);
|
||||
std::lock_guard<std::mutex> lock(cSection);
|
||||
#endif
|
||||
*event = queuedEvents[nextQueuedEvent];
|
||||
nextQueuedEvent = (nextQueuedEvent + 1) % EVENT_QUEUE_LEN;
|
||||
*event = queuedEvents[nextQueuedEvent];
|
||||
nextQueuedEvent = (nextQueuedEvent + 1) % EVENT_QUEUE_LEN;
|
||||
#ifdef _MSC_VER
|
||||
LeaveCriticalSection(&cSection);
|
||||
LeaveCriticalSection(&cSection);
|
||||
#endif
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ClearKeyQueue()
|
||||
{
|
||||
lastQueuedEvent = nextQueuedEvent;
|
||||
lastQueuedEvent = nextQueuedEvent;
|
||||
#ifdef _MSC_VER
|
||||
if (csInitialized) {
|
||||
DeleteCriticalSection(&cSection);
|
||||
csInitialized = 0;
|
||||
}
|
||||
if (csInitialized)
|
||||
{
|
||||
DeleteCriticalSection(&cSection);
|
||||
csInitialized = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -18,13 +18,13 @@
|
|||
// but takes little enough effort to be safe...
|
||||
|
||||
void QueueKeyEvent(int key, int event);
|
||||
int GetQueuedKeyEvent(keyEvent *event);
|
||||
int GetQueuedKeyEvent(keyEvent* event);
|
||||
|
||||
// Cleans up as well as clears queue.
|
||||
void ClearKeyQueue();
|
||||
|
||||
#ifdef __linux__
|
||||
void R_QueueKeyEvent(const keyEvent &event);
|
||||
int R_GetQueuedKeyEvent(keyEvent *event);
|
||||
void R_QueueKeyEvent(const keyEvent& event);
|
||||
int R_GetQueuedKeyEvent(keyEvent* event);
|
||||
void R_ClearKeyQueue();
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -16,63 +16,63 @@
|
|||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
extern const wchar_t *padTypes[numPadTypes];
|
||||
extern const wchar_t* padTypes[numPadTypes];
|
||||
|
||||
struct PadConfig
|
||||
{
|
||||
PadType type;
|
||||
PadType type;
|
||||
};
|
||||
|
||||
struct GeneralConfig
|
||||
{
|
||||
public:
|
||||
PadConfig padConfigs[2][4];
|
||||
PadConfig padConfigs[2][4];
|
||||
|
||||
int deviceSelect[2][4];
|
||||
int deviceSelect[2][4];
|
||||
|
||||
DeviceAPI keyboardApi;
|
||||
DeviceAPI mouseApi;
|
||||
DeviceAPI keyboardApi;
|
||||
DeviceAPI mouseApi;
|
||||
|
||||
// Derived value, calculated by GetInput().
|
||||
u8 configureOnBind;
|
||||
bool bind;
|
||||
// Derived value, calculated by GetInput().
|
||||
u8 configureOnBind;
|
||||
bool bind;
|
||||
|
||||
bool specialInputs[2][4];
|
||||
bool specialInputs[2][4];
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u8 forceHide;
|
||||
u8 mouseUnfocus;
|
||||
u8 background;
|
||||
u8 multipleBinding;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u8 forceHide;
|
||||
u8 mouseUnfocus;
|
||||
u8 background;
|
||||
u8 multipleBinding;
|
||||
|
||||
struct
|
||||
{
|
||||
u8 directInput;
|
||||
u8 xInput;
|
||||
u8 dualShock3;
|
||||
} gameApis;
|
||||
struct
|
||||
{
|
||||
u8 directInput;
|
||||
u8 xInput;
|
||||
u8 dualShock3;
|
||||
} gameApis;
|
||||
|
||||
u8 multitap[2];
|
||||
u8 multitap[2];
|
||||
|
||||
u8 debug;
|
||||
u8 debug;
|
||||
|
||||
u8 GH2;
|
||||
};
|
||||
u8 bools[15];
|
||||
};
|
||||
u8 GH2;
|
||||
};
|
||||
u8 bools[15];
|
||||
};
|
||||
|
||||
wchar_t lastSaveConfigPath[MAX_PATH + 1];
|
||||
wchar_t lastSaveConfigFileName[MAX_PATH + 1];
|
||||
wchar_t lastSaveConfigPath[MAX_PATH + 1];
|
||||
wchar_t lastSaveConfigFileName[MAX_PATH + 1];
|
||||
};
|
||||
|
||||
extern GeneralConfig config;
|
||||
|
||||
void UnloadConfigs();
|
||||
|
||||
int LoadSettings(int force = 0, wchar_t *file = 0);
|
||||
int LoadSettings(int force = 0, wchar_t* file = 0);
|
||||
|
||||
// Refreshes the set of enabled devices.
|
||||
void RefreshEnabledDevices(int updateDeviceList = 0);
|
||||
|
|
|
@ -23,50 +23,50 @@
|
|||
#include "WindowsKeyboard.h"
|
||||
#include "WindowsMouse.h"
|
||||
|
||||
ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output);
|
||||
ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* output);
|
||||
|
||||
int GetRawKeyboards(HWND hWnd)
|
||||
{
|
||||
RAWINPUTDEVICE Rid;
|
||||
Rid.hwndTarget = hWnd;
|
||||
RAWINPUTDEVICE Rid;
|
||||
Rid.hwndTarget = hWnd;
|
||||
|
||||
Rid.dwFlags = 0;
|
||||
Rid.usUsagePage = 0x01;
|
||||
Rid.usUsage = 0x06;
|
||||
return RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
|
||||
Rid.dwFlags = 0;
|
||||
Rid.usUsagePage = 0x01;
|
||||
Rid.usUsage = 0x06;
|
||||
return RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
|
||||
}
|
||||
|
||||
void ReleaseRawKeyboards()
|
||||
{
|
||||
RAWINPUTDEVICE Rid;
|
||||
Rid.hwndTarget = 0;
|
||||
RAWINPUTDEVICE Rid;
|
||||
Rid.hwndTarget = 0;
|
||||
|
||||
Rid.dwFlags = RIDEV_REMOVE;
|
||||
Rid.usUsagePage = 0x01;
|
||||
Rid.usUsage = 0x06;
|
||||
RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
|
||||
Rid.dwFlags = RIDEV_REMOVE;
|
||||
Rid.usUsagePage = 0x01;
|
||||
Rid.usUsage = 0x06;
|
||||
RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
|
||||
}
|
||||
|
||||
int GetRawMice(HWND hWnd)
|
||||
{
|
||||
RAWINPUTDEVICE Rid;
|
||||
Rid.hwndTarget = hWnd;
|
||||
RAWINPUTDEVICE Rid;
|
||||
Rid.hwndTarget = hWnd;
|
||||
|
||||
Rid.dwFlags = RIDEV_NOLEGACY | RIDEV_CAPTUREMOUSE;
|
||||
Rid.usUsagePage = 0x01;
|
||||
Rid.usUsage = 0x02;
|
||||
return RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
|
||||
Rid.dwFlags = RIDEV_NOLEGACY | RIDEV_CAPTUREMOUSE;
|
||||
Rid.usUsagePage = 0x01;
|
||||
Rid.usUsage = 0x02;
|
||||
return RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
|
||||
}
|
||||
|
||||
void ReleaseRawMice()
|
||||
{
|
||||
RAWINPUTDEVICE Rid;
|
||||
Rid.hwndTarget = 0;
|
||||
RAWINPUTDEVICE Rid;
|
||||
Rid.hwndTarget = 0;
|
||||
|
||||
Rid.dwFlags = RIDEV_REMOVE;
|
||||
Rid.usUsagePage = 0x01;
|
||||
Rid.usUsage = 0x02;
|
||||
RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
|
||||
Rid.dwFlags = RIDEV_REMOVE;
|
||||
Rid.usUsagePage = 0x01;
|
||||
Rid.usUsage = 0x02;
|
||||
RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
|
||||
}
|
||||
|
||||
// Count of active raw keyboard devices.
|
||||
|
@ -78,253 +78,290 @@ static int rawMouseActivatedCount = 0;
|
|||
class RawInputKeyboard : public WindowsKeyboard
|
||||
{
|
||||
public:
|
||||
HANDLE hDevice;
|
||||
HANDLE hDevice;
|
||||
|
||||
RawInputKeyboard(HANDLE hDevice, wchar_t *name, wchar_t *instanceID = 0)
|
||||
: WindowsKeyboard(RAW, name, instanceID)
|
||||
{
|
||||
this->hDevice = hDevice;
|
||||
}
|
||||
RawInputKeyboard(HANDLE hDevice, wchar_t* name, wchar_t* instanceID = 0)
|
||||
: WindowsKeyboard(RAW, name, instanceID)
|
||||
{
|
||||
this->hDevice = hDevice;
|
||||
}
|
||||
|
||||
int Activate(InitInfo *initInfo)
|
||||
{
|
||||
Deactivate();
|
||||
int Activate(InitInfo* initInfo)
|
||||
{
|
||||
Deactivate();
|
||||
|
||||
hWndProc = initInfo->hWndProc;
|
||||
hWndProc = initInfo->hWndProc;
|
||||
|
||||
active = 1;
|
||||
if (!rawKeyboardActivatedCount++) {
|
||||
if (!rawMouseActivatedCount)
|
||||
hWndProc->Eat(RawInputWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES);
|
||||
active = 1;
|
||||
if (!rawKeyboardActivatedCount++)
|
||||
{
|
||||
if (!rawMouseActivatedCount)
|
||||
hWndProc->Eat(RawInputWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES);
|
||||
|
||||
if (!GetRawKeyboards(hWndProc->hWndEaten)) {
|
||||
Deactivate();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (!GetRawKeyboards(hWndProc->hWndEaten))
|
||||
{
|
||||
Deactivate();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
InitState();
|
||||
return 1;
|
||||
}
|
||||
InitState();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Deactivate()
|
||||
{
|
||||
FreeState();
|
||||
if (active) {
|
||||
active = 0;
|
||||
rawKeyboardActivatedCount--;
|
||||
if (!rawKeyboardActivatedCount) {
|
||||
ReleaseRawKeyboards();
|
||||
if (!rawMouseActivatedCount)
|
||||
hWndProc->ReleaseExtraProc(RawInputWndProc);
|
||||
}
|
||||
}
|
||||
}
|
||||
void Deactivate()
|
||||
{
|
||||
FreeState();
|
||||
if (active)
|
||||
{
|
||||
active = 0;
|
||||
rawKeyboardActivatedCount--;
|
||||
if (!rawKeyboardActivatedCount)
|
||||
{
|
||||
ReleaseRawKeyboards();
|
||||
if (!rawMouseActivatedCount)
|
||||
hWndProc->ReleaseExtraProc(RawInputWndProc);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class RawInputMouse : public WindowsMouse
|
||||
{
|
||||
public:
|
||||
HANDLE hDevice;
|
||||
HANDLE hDevice;
|
||||
|
||||
RawInputMouse(HANDLE hDevice, wchar_t *name, wchar_t *instanceID = 0, wchar_t *productID = 0)
|
||||
: WindowsMouse(RAW, 0, name, instanceID, productID)
|
||||
{
|
||||
this->hDevice = hDevice;
|
||||
}
|
||||
RawInputMouse(HANDLE hDevice, wchar_t* name, wchar_t* instanceID = 0, wchar_t* productID = 0)
|
||||
: WindowsMouse(RAW, 0, name, instanceID, productID)
|
||||
{
|
||||
this->hDevice = hDevice;
|
||||
}
|
||||
|
||||
int Activate(InitInfo *initInfo)
|
||||
{
|
||||
Deactivate();
|
||||
int Activate(InitInfo* initInfo)
|
||||
{
|
||||
Deactivate();
|
||||
|
||||
hWndProc = initInfo->hWndProc;
|
||||
hWndProc = initInfo->hWndProc;
|
||||
|
||||
active = 1;
|
||||
active = 1;
|
||||
|
||||
// Have to be careful with order. At worst, one unmatched call to ReleaseRawMice on
|
||||
// EatWndProc fail. In all other cases, no unmatched initialization/cleanup
|
||||
// lines.
|
||||
if (!rawMouseActivatedCount++) {
|
||||
GetMouseCapture(hWndProc->hWndEaten);
|
||||
if (!rawKeyboardActivatedCount)
|
||||
hWndProc->Eat(RawInputWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES);
|
||||
// Have to be careful with order. At worst, one unmatched call to ReleaseRawMice on
|
||||
// EatWndProc fail. In all other cases, no unmatched initialization/cleanup
|
||||
// lines.
|
||||
if (!rawMouseActivatedCount++)
|
||||
{
|
||||
GetMouseCapture(hWndProc->hWndEaten);
|
||||
if (!rawKeyboardActivatedCount)
|
||||
hWndProc->Eat(RawInputWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES);
|
||||
|
||||
if (!GetRawMice(hWndProc->hWndEaten)) {
|
||||
Deactivate();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (!GetRawMice(hWndProc->hWndEaten))
|
||||
{
|
||||
Deactivate();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
AllocState();
|
||||
return 1;
|
||||
}
|
||||
AllocState();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Deactivate()
|
||||
{
|
||||
FreeState();
|
||||
if (active) {
|
||||
active = 0;
|
||||
rawMouseActivatedCount--;
|
||||
if (!rawMouseActivatedCount) {
|
||||
ReleaseRawMice();
|
||||
ReleaseMouseCapture();
|
||||
if (!rawKeyboardActivatedCount) {
|
||||
hWndProc->ReleaseExtraProc(RawInputWndProc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void Deactivate()
|
||||
{
|
||||
FreeState();
|
||||
if (active)
|
||||
{
|
||||
active = 0;
|
||||
rawMouseActivatedCount--;
|
||||
if (!rawMouseActivatedCount)
|
||||
{
|
||||
ReleaseRawMice();
|
||||
ReleaseMouseCapture();
|
||||
if (!rawKeyboardActivatedCount)
|
||||
{
|
||||
hWndProc->ReleaseExtraProc(RawInputWndProc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output)
|
||||
ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* output)
|
||||
{
|
||||
if (uMsg == WM_INPUT) {
|
||||
if (GET_RAWINPUT_CODE_WPARAM(wParam) == RIM_INPUT) {
|
||||
RAWINPUT in;
|
||||
unsigned int size = sizeof(RAWINPUT);
|
||||
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, &in, &size, sizeof(RAWINPUTHEADER)) > 0) {
|
||||
for (int i = 0; i < dm->numDevices; i++) {
|
||||
Device *dev = dm->devices[i];
|
||||
if (dev->api != RAW || !dev->active)
|
||||
continue;
|
||||
if (in.header.dwType == RIM_TYPEKEYBOARD && dev->type == KEYBOARD) {
|
||||
RawInputKeyboard *rik = (RawInputKeyboard *)dev;
|
||||
if (rik->hDevice != in.header.hDevice)
|
||||
continue;
|
||||
if (uMsg == WM_INPUT)
|
||||
{
|
||||
if (GET_RAWINPUT_CODE_WPARAM(wParam) == RIM_INPUT)
|
||||
{
|
||||
RAWINPUT in;
|
||||
unsigned int size = sizeof(RAWINPUT);
|
||||
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, &in, &size, sizeof(RAWINPUTHEADER)) > 0)
|
||||
{
|
||||
for (int i = 0; i < dm->numDevices; i++)
|
||||
{
|
||||
Device* dev = dm->devices[i];
|
||||
if (dev->api != RAW || !dev->active)
|
||||
continue;
|
||||
if (in.header.dwType == RIM_TYPEKEYBOARD && dev->type == KEYBOARD)
|
||||
{
|
||||
RawInputKeyboard* rik = (RawInputKeyboard*)dev;
|
||||
if (rik->hDevice != in.header.hDevice)
|
||||
continue;
|
||||
|
||||
u32 uMsg = in.data.keyboard.Message;
|
||||
if (!(in.data.keyboard.VKey >> 8))
|
||||
rik->UpdateKey((u8)in.data.keyboard.VKey, (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN));
|
||||
} else if (in.header.dwType == RIM_TYPEMOUSE && dev->type == MOUSE) {
|
||||
RawInputMouse *rim = (RawInputMouse *)dev;
|
||||
if (rim->hDevice != in.header.hDevice)
|
||||
continue;
|
||||
if (in.data.mouse.usFlags) {
|
||||
// Never been set for me, and specs on what most of them
|
||||
// actually mean is sorely lacking. Also, specs erroneously
|
||||
// indicate MOUSE_MOVE_RELATIVE is a flag, when it's really
|
||||
// 0...
|
||||
continue;
|
||||
}
|
||||
u32 uMsg = in.data.keyboard.Message;
|
||||
if (!(in.data.keyboard.VKey >> 8))
|
||||
rik->UpdateKey((u8)in.data.keyboard.VKey, (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN));
|
||||
}
|
||||
else if (in.header.dwType == RIM_TYPEMOUSE && dev->type == MOUSE)
|
||||
{
|
||||
RawInputMouse* rim = (RawInputMouse*)dev;
|
||||
if (rim->hDevice != in.header.hDevice)
|
||||
continue;
|
||||
if (in.data.mouse.usFlags)
|
||||
{
|
||||
// Never been set for me, and specs on what most of them
|
||||
// actually mean is sorely lacking. Also, specs erroneously
|
||||
// indicate MOUSE_MOVE_RELATIVE is a flag, when it's really
|
||||
// 0...
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned short buttons = in.data.mouse.usButtonFlags & 0x3FF;
|
||||
int button = 0;
|
||||
while (buttons) {
|
||||
if (buttons & 3) {
|
||||
// 2 is up, 1 is down. Up takes precedence over down.
|
||||
rim->UpdateButton(button, !(buttons & 2));
|
||||
}
|
||||
button++;
|
||||
buttons >>= 2;
|
||||
}
|
||||
if (in.data.mouse.usButtonFlags & RI_MOUSE_WHEEL) {
|
||||
rim->UpdateAxis(2, ((short)in.data.mouse.usButtonData) / WHEEL_DELTA);
|
||||
}
|
||||
if (in.data.mouse.lLastX || in.data.mouse.lLastY) {
|
||||
rim->UpdateAxis(0, in.data.mouse.lLastX);
|
||||
rim->UpdateAxis(1, in.data.mouse.lLastY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (uMsg == WM_ACTIVATE) {
|
||||
for (int i = 0; i < dm->numDevices; i++) {
|
||||
Device *dev = dm->devices[i];
|
||||
if (dev->api != RAW || dev->physicalControlState == 0)
|
||||
continue;
|
||||
memset(dev->physicalControlState, 0, sizeof(int) * dev->numPhysicalControls);
|
||||
}
|
||||
} else if (uMsg == WM_SIZE && rawMouseActivatedCount) {
|
||||
// Doesn't really matter for raw mice, as I disable legacy stuff, but shouldn't hurt.
|
||||
WindowsMouse::WindowResized(hWnd);
|
||||
}
|
||||
unsigned short buttons = in.data.mouse.usButtonFlags & 0x3FF;
|
||||
int button = 0;
|
||||
while (buttons)
|
||||
{
|
||||
if (buttons & 3)
|
||||
{
|
||||
// 2 is up, 1 is down. Up takes precedence over down.
|
||||
rim->UpdateButton(button, !(buttons & 2));
|
||||
}
|
||||
button++;
|
||||
buttons >>= 2;
|
||||
}
|
||||
if (in.data.mouse.usButtonFlags & RI_MOUSE_WHEEL)
|
||||
{
|
||||
rim->UpdateAxis(2, ((short)in.data.mouse.usButtonData) / WHEEL_DELTA);
|
||||
}
|
||||
if (in.data.mouse.lLastX || in.data.mouse.lLastY)
|
||||
{
|
||||
rim->UpdateAxis(0, in.data.mouse.lLastX);
|
||||
rim->UpdateAxis(1, in.data.mouse.lLastY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (uMsg == WM_ACTIVATE)
|
||||
{
|
||||
for (int i = 0; i < dm->numDevices; i++)
|
||||
{
|
||||
Device* dev = dm->devices[i];
|
||||
if (dev->api != RAW || dev->physicalControlState == 0)
|
||||
continue;
|
||||
memset(dev->physicalControlState, 0, sizeof(int) * dev->numPhysicalControls);
|
||||
}
|
||||
}
|
||||
else if (uMsg == WM_SIZE && rawMouseActivatedCount)
|
||||
{
|
||||
// Doesn't really matter for raw mice, as I disable legacy stuff, but shouldn't hurt.
|
||||
WindowsMouse::WindowResized(hWnd);
|
||||
}
|
||||
|
||||
return CONTINUE_BLISSFULLY;
|
||||
return CONTINUE_BLISSFULLY;
|
||||
}
|
||||
|
||||
void EnumRawInputDevices()
|
||||
{
|
||||
int count = 0;
|
||||
if (GetRawInputDeviceList(0, (unsigned int *)&count, sizeof(RAWINPUTDEVICELIST)) != (UINT)-1 && count > 0) {
|
||||
wchar_t *instanceID = (wchar_t *)malloc(41000 * sizeof(wchar_t));
|
||||
wchar_t *keyName = instanceID + 11000;
|
||||
wchar_t *displayName = keyName + 10000;
|
||||
wchar_t *productID = displayName + 10000;
|
||||
int count = 0;
|
||||
if (GetRawInputDeviceList(0, (unsigned int*)&count, sizeof(RAWINPUTDEVICELIST)) != (UINT)-1 && count > 0)
|
||||
{
|
||||
wchar_t* instanceID = (wchar_t*)malloc(41000 * sizeof(wchar_t));
|
||||
wchar_t* keyName = instanceID + 11000;
|
||||
wchar_t* displayName = keyName + 10000;
|
||||
wchar_t* productID = displayName + 10000;
|
||||
|
||||
RAWINPUTDEVICELIST *list = (RAWINPUTDEVICELIST *)malloc(sizeof(RAWINPUTDEVICELIST) * count);
|
||||
int keyboardCount = 1;
|
||||
int mouseCount = 1;
|
||||
count = GetRawInputDeviceList(list, (unsigned int *)&count, sizeof(RAWINPUTDEVICELIST));
|
||||
RAWINPUTDEVICELIST* list = (RAWINPUTDEVICELIST*)malloc(sizeof(RAWINPUTDEVICELIST) * count);
|
||||
int keyboardCount = 1;
|
||||
int mouseCount = 1;
|
||||
count = GetRawInputDeviceList(list, (unsigned int*)&count, sizeof(RAWINPUTDEVICELIST));
|
||||
|
||||
// Not necessary, but reminder that count is -1 on failure.
|
||||
if (count > 0) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (list[i].dwType != RIM_TYPEKEYBOARD && list[i].dwType != RIM_TYPEMOUSE)
|
||||
continue;
|
||||
// Not necessary, but reminder that count is -1 on failure.
|
||||
if (count > 0)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (list[i].dwType != RIM_TYPEKEYBOARD && list[i].dwType != RIM_TYPEMOUSE)
|
||||
continue;
|
||||
|
||||
UINT bufferLen = 10000;
|
||||
int nameLen = GetRawInputDeviceInfo(list[i].hDevice, RIDI_DEVICENAME, instanceID, &bufferLen);
|
||||
if (nameLen >= 4) {
|
||||
// nameLen includes terminating null.
|
||||
nameLen--;
|
||||
UINT bufferLen = 10000;
|
||||
int nameLen = GetRawInputDeviceInfo(list[i].hDevice, RIDI_DEVICENAME, instanceID, &bufferLen);
|
||||
if (nameLen >= 4)
|
||||
{
|
||||
// nameLen includes terminating null.
|
||||
nameLen--;
|
||||
|
||||
// Strip out GUID parts of instanceID to make it a generic product id,
|
||||
// and reformat it to point to registry entry containing device description.
|
||||
wcscpy(productID, instanceID);
|
||||
wchar_t *temp = 0;
|
||||
for (int j = 0; j < 3; j++) {
|
||||
wchar_t *s = wcschr(productID, '#');
|
||||
if (!s)
|
||||
break;
|
||||
*s = '\\';
|
||||
if (j == 2) {
|
||||
*s = 0;
|
||||
}
|
||||
if (j == 1)
|
||||
temp = s;
|
||||
}
|
||||
// Strip out GUID parts of instanceID to make it a generic product id,
|
||||
// and reformat it to point to registry entry containing device description.
|
||||
wcscpy(productID, instanceID);
|
||||
wchar_t* temp = 0;
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
wchar_t* s = wcschr(productID, '#');
|
||||
if (!s)
|
||||
break;
|
||||
*s = '\\';
|
||||
if (j == 2)
|
||||
{
|
||||
*s = 0;
|
||||
}
|
||||
if (j == 1)
|
||||
temp = s;
|
||||
}
|
||||
|
||||
wsprintfW(keyName, L"SYSTEM\\CurrentControlSet\\Enum%s", productID + 3);
|
||||
if (temp)
|
||||
*temp = 0;
|
||||
int haveDescription = 0;
|
||||
HKEY hKey;
|
||||
if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName, 0, KEY_QUERY_VALUE, &hKey)) {
|
||||
DWORD type;
|
||||
DWORD len = 10000 * sizeof(wchar_t);
|
||||
if (ERROR_SUCCESS == RegQueryValueExW(hKey, L"DeviceDesc", 0, &type, (BYTE *)displayName, &len) &&
|
||||
len && type == REG_SZ) {
|
||||
wchar_t *temp2 = wcsrchr(displayName, ';');
|
||||
if (!temp2)
|
||||
temp2 = displayName;
|
||||
else
|
||||
temp2++;
|
||||
// Could do without this, but more effort than it's worth.
|
||||
wcscpy(keyName, temp2);
|
||||
haveDescription = 1;
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
if (list[i].dwType == RIM_TYPEKEYBOARD) {
|
||||
if (!haveDescription)
|
||||
wsprintfW(displayName, L"Raw Keyboard %i", keyboardCount++);
|
||||
else
|
||||
wsprintfW(displayName, L"Raw KB: %s", keyName);
|
||||
dm->AddDevice(new RawInputKeyboard(list[i].hDevice, displayName, instanceID));
|
||||
} else if (list[i].dwType == RIM_TYPEMOUSE) {
|
||||
if (!haveDescription)
|
||||
wsprintfW(displayName, L"Raw Mouse %i", mouseCount++);
|
||||
else
|
||||
wsprintfW(displayName, L"Raw MS: %s", keyName);
|
||||
dm->AddDevice(new RawInputMouse(list[i].hDevice, displayName, instanceID, productID));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(list);
|
||||
free(instanceID);
|
||||
dm->AddDevice(new RawInputKeyboard(0, L"Simulated Keyboard"));
|
||||
dm->AddDevice(new RawInputMouse(0, L"Simulated Mouse"));
|
||||
}
|
||||
wsprintfW(keyName, L"SYSTEM\\CurrentControlSet\\Enum%s", productID + 3);
|
||||
if (temp)
|
||||
*temp = 0;
|
||||
int haveDescription = 0;
|
||||
HKEY hKey;
|
||||
if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName, 0, KEY_QUERY_VALUE, &hKey))
|
||||
{
|
||||
DWORD type;
|
||||
DWORD len = 10000 * sizeof(wchar_t);
|
||||
if (ERROR_SUCCESS == RegQueryValueExW(hKey, L"DeviceDesc", 0, &type, (BYTE*)displayName, &len) &&
|
||||
len && type == REG_SZ)
|
||||
{
|
||||
wchar_t* temp2 = wcsrchr(displayName, ';');
|
||||
if (!temp2)
|
||||
temp2 = displayName;
|
||||
else
|
||||
temp2++;
|
||||
// Could do without this, but more effort than it's worth.
|
||||
wcscpy(keyName, temp2);
|
||||
haveDescription = 1;
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
if (list[i].dwType == RIM_TYPEKEYBOARD)
|
||||
{
|
||||
if (!haveDescription)
|
||||
wsprintfW(displayName, L"Raw Keyboard %i", keyboardCount++);
|
||||
else
|
||||
wsprintfW(displayName, L"Raw KB: %s", keyName);
|
||||
dm->AddDevice(new RawInputKeyboard(list[i].hDevice, displayName, instanceID));
|
||||
}
|
||||
else if (list[i].dwType == RIM_TYPEMOUSE)
|
||||
{
|
||||
if (!haveDescription)
|
||||
wsprintfW(displayName, L"Raw Mouse %i", mouseCount++);
|
||||
else
|
||||
wsprintfW(displayName, L"Raw MS: %s", keyName);
|
||||
dm->AddDevice(new RawInputMouse(list[i].hDevice, displayName, instanceID, productID));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(list);
|
||||
free(instanceID);
|
||||
dm->AddDevice(new RawInputKeyboard(0, L"Simulated Keyboard"));
|
||||
dm->AddDevice(new RawInputMouse(0, L"Simulated Mouse"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,112 +17,113 @@
|
|||
#include "Global.h"
|
||||
#include "resource_pad.h"
|
||||
|
||||
LPWSTR dialog_message(int ID, bool *updateText)
|
||||
LPWSTR dialog_message(int ID, bool* updateText)
|
||||
{
|
||||
if (updateText)
|
||||
*updateText = true;
|
||||
switch (ID) {
|
||||
// General tab
|
||||
case IDC_M_WM:
|
||||
case IDC_M_RAW:
|
||||
case IDC_M_DI:
|
||||
return L"Enables mouse inputs to be used as pad controls.\n\n"
|
||||
L"The mouse needs to be in focus to be used for playing. By default this is not the case as the \"Start without mouse focus\" checkbox is enabled. "
|
||||
L"Either disable this checkbox or enable/disable the mouse while playing by assigning a key to the \"Mouse\" button on the Pad tabs.\n\n"
|
||||
L"Note 1: By default PCSX2 uses a double-click by the left mouse button to toggle fullscreen mode, this makes the left mouse button unusable as an input."
|
||||
L"To disable this option in PCSX2 go to Config > Emulation Settings > GS Window tab, and disable the \"Double-click toggles fullscreen mode\" checkbox.\n\n"
|
||||
L"Note 2: This does not enable the mouse to function as an in-game mouse in PS2 games that support a USB mouse or lightgun."
|
||||
L"This requires a USB plugin, while LilyPad is a PAD plugin(PAD means it emulates devices that are to be plugged into the PlayStation controller port that connects the DualShock 2 controller).";
|
||||
case IDC_MOUSE_UNFOCUS:
|
||||
return L"Enabled: Mouse is unfocused and can be used for emulation and outside it.\n\n"
|
||||
L"Disabled: Mouse is focused and can be used for emulation.";
|
||||
case IDC_MULTIPLE_BINDING:
|
||||
return L"Allows binding multiple PS2 controls to one PC control, and binding conflicting controls on opposing ports and/or slots.\n\n"
|
||||
L"Also enables swapping different kinds of pad types(for example, between DS2 and Guitar) when right-clicking in the pad list.";
|
||||
case IDC_PAD_LIST:
|
||||
return L"Left-click on one of the available pads to enable the pad specific options on the right."
|
||||
L"These options include being able to select the pad type(DS2, Guitar, etc.) and enabling automatic analog mode for PS1 emulation.\n\n"
|
||||
L"Right-click to show a pop-up menu that allows for swapping all the settings and bindings, or just the bindings of individual pad types,"
|
||||
L"between the selected pad and one of other active pads, and clearing all the settings and bindings from the selected pad or just the bindings from a selected pad type.\n\n"
|
||||
L"Note: To allow swapping different kinds of pad types(like DS2 to Guitar), the \"Allow binding multiple PS2 Controls...\" option needs to be enabled as well.";
|
||||
case IDC_PAD_TYPE:
|
||||
return L"\"Unplugged\" disables the controller and removes the corresponding pad tab.\n\n"
|
||||
L"\"Dualshock 2\" emulates the default PS2 controller for use in both PS1 and PS2 games.\n\n"
|
||||
L"\"Guitar\" emulates a PS2 controller used in the Guitar Hero and Rock Band series of games.\n\n"
|
||||
L"\"Pop'n Music controller\" emulates a PS2 controller used exclusively in the Japanese Pop'n Music series of games.\n\n"
|
||||
L"\"PS1 Mouse\" emulates the PlayStation Mouse. This controller can only be used in a number of PS1 games like \"Command & Conquer: Red Alert\" and \"Myst\".\n\n"
|
||||
L"\"neGcon\" emulates a controller that can be used in a number of PS1 games and PS2 games like the \"Ridge Racer\" and \"Ace Combat\" series.";
|
||||
case IDC_DIAG_LIST:
|
||||
return L"Shows a list of currently available input devices.\n\n"
|
||||
L"Double-click a device in the list or right-click it and select \"Test Device\" to display a continuously updated list of the state of all inputs on the selected device.\n"
|
||||
L"Use this option to check if all the inputs on a controller function properly.\n\n"
|
||||
L"Right-click and select \"Refresh\" to update the list of devices in case a recently connected device has not shown up yet.";
|
||||
case IDC_G_DI:
|
||||
return L"(Legacy) Enable this if your gamepad doesn't support Xinput.\n\n"
|
||||
L"Disable for DualShock 4 (PS4 controllers) and probably others.";
|
||||
case IDC_G_XI:
|
||||
return L"For Xbox 360/ Xbox One controllers (or devices supporting Xinput).\n\n"
|
||||
L"If it doesn't support Xinput then running through Steam as a non-Steam game might be required for the controllers to work properly.\n\n"
|
||||
L"https://gamepad-tester.com/ to test your controller and check if it only says 'Xinput' on top.";
|
||||
case ID_RESTORE_DEFAULTS:
|
||||
return L"Restores the default contents of LilyPad.ini, undoing all settings changes and bindings that have been set up.";
|
||||
// Pad tabs
|
||||
case IDC_BINDINGS_LIST:
|
||||
return L"Shows a list of currently bound inputs of the selected Pad.\n\n"
|
||||
L"Left-click on one of the bindings in the list to configure it.\n\n"
|
||||
L"Right-click and select \"Delete Selected\" to remove the selected input from the list.\n\n"
|
||||
L"Right-click and select \"Clear All\" to remove all the inputs from the list.\n\n"
|
||||
L"Note: Use Shift/Ctrl + Left-click to select multiple bindings. Changing the displayed configuration will now copy it to all selected bindings.";
|
||||
case IDC_DEVICE_SELECT:
|
||||
return L"Select a single device to hide the bindings from other devices in the bindings list, and to only be able to add new bindings for the selected device.\n\n"
|
||||
L"This can also avoid input conflict issues when one controller is recognized as several devices through different APIs.";
|
||||
case IDC_CONFIGURE_ON_BIND:
|
||||
return L"Immediately go to the configuration setup when you create a new binding.";
|
||||
case ID_MOUSE:
|
||||
return L"Bind a key that releases or captures the mouse.\n\n"
|
||||
L"Pressing the assigned button when the mouse is in focus, it releases the mouse from use in-game and makes the cursor visible so it can move/resize the emulator window.\n\n"
|
||||
L"Alt-tabbing to another application also makes the cursor visible, but focusing the emulation window hides it again.\n\n"
|
||||
L"Pressing the button when the mouse is out of focus and visible, it captures the mouse so that it can be used as a controller again.\n\n"
|
||||
L"Note 1: Though the binding appears on the page of a specific pad, pressing the button affects all mice.\n\n"
|
||||
L"Note 2: By default PCSX2 uses a double-click by the left mouse button to toggle fullscreen mode, this makes the left mouse button unusable as an input."
|
||||
L"To disable this option in PCSX2 go to Config > Emulation Settings > GS Window tab, and disable the \"Double-click toggles fullscreen mode\" checkbox.";
|
||||
case ID_ANALOG:
|
||||
return L"Bind a keys that switches the pad from digital mode to analog mode and vice versa.\n\n"
|
||||
L"This option is useful when analog mode is enabled in a game that does not support it, as this causes the game to not recognise any input or to not even detect a controller.\n\n"
|
||||
L"This option can also be used to enable analog mode in games that support, but do not automatically enable analog mode.\n\n"
|
||||
L"Note: Analog mode enables the analog sticks to function on a DualShock controller, while in digital mode it behaves as an original PlayStation controller.\n\n";
|
||||
case ID_TURBO_KEY:
|
||||
return L"Sets a key to send a TAB press to the emulator, which toggles Turbo mode(200% speed) in PCSX2.";
|
||||
case ID_EXCLUDE:
|
||||
return L"Disables an input so it will be ignored when trying to bind another input.\n\n"
|
||||
L"This is helpful when binding controls for a device with an input that's difficult to center like an accelerator, or just always active like a faulty button or analog stick.";
|
||||
case ID_LOCK_ALL_INPUT:
|
||||
return L"Locks the current state of the pad. Any further input is handled normally, but the initial pad state is the locked state instead of a state with no buttons pressed. "
|
||||
L"Pressing it again releases the old pad state, if the old pad state had any keys pressed. Otherwise, it's released automatically.";
|
||||
case ID_LOCK_DIRECTION:
|
||||
return L"Locks the current state of the d-pad and analog sticks. Pressing this when all input is locked unlocks only the pad and sticks."
|
||||
L"Pressing it again will lock them again, keeping the buttons locked.";
|
||||
case ID_LOCK_BUTTONS:
|
||||
return L"Locks the current state of the buttons. Pressing this when all input is locked unlocks only the buttons. "
|
||||
L"Pressing it again will lock them again, keeping the d-pad and analog sticks locked.";
|
||||
case IDC_RAPID_FIRE:
|
||||
return L"Automatically presses/releases the input every other time the button is polled.";
|
||||
case IDC_FLIP:
|
||||
return L"Inverts a button or axis, making down up and up down.";
|
||||
case IDC_SLIDER_DEADZONE:
|
||||
return L"Decreases or increases the range of an input where no input is recognised.\n\n"
|
||||
L"Increasing the dead zone requires the input to be pressed harder or moved more before it is applied, decreasing it makes it recognise a softer press or a shorter movement.";
|
||||
case IDC_SLIDER_SKIP_DEADZONE:
|
||||
return L"Skips and avoids the dead zone to detect input earlier.\n\n"
|
||||
L"Note: This is useful when a controller input requires too much movement/pressure before there's a corresponding action in-game.";
|
||||
case IDC_SLIDER_SENSITIVITY:
|
||||
return L"Sets how hard an axis or button is pressed.\n\n"
|
||||
L"Note 1: What the default sensitivity value of \"1.00\" means depends on the device itself. The default is high enough that relative axes (which are primarily used by mice) are generally either considered fully up or down."
|
||||
L"For absolute axes (and force feedback devices), which are used by most game devices, a value of 1.0 should map the device's extreme values to the extreme values of a stick/pad.\n\n"
|
||||
L"Note 2: Setting the sensitivity of PC button bindings only really has an effect for PS2 analog sticks or when playing a game with full DS2 pressure sensitivity support.";
|
||||
default:
|
||||
if (updateText)
|
||||
*updateText = false;
|
||||
return L"";
|
||||
}
|
||||
if (updateText)
|
||||
*updateText = true;
|
||||
switch (ID)
|
||||
{
|
||||
// General tab
|
||||
case IDC_M_WM:
|
||||
case IDC_M_RAW:
|
||||
case IDC_M_DI:
|
||||
return L"Enables mouse inputs to be used as pad controls.\n\n"
|
||||
L"The mouse needs to be in focus to be used for playing. By default this is not the case as the \"Start without mouse focus\" checkbox is enabled. "
|
||||
L"Either disable this checkbox or enable/disable the mouse while playing by assigning a key to the \"Mouse\" button on the Pad tabs.\n\n"
|
||||
L"Note 1: By default PCSX2 uses a double-click by the left mouse button to toggle fullscreen mode, this makes the left mouse button unusable as an input."
|
||||
L"To disable this option in PCSX2 go to Config > Emulation Settings > GS Window tab, and disable the \"Double-click toggles fullscreen mode\" checkbox.\n\n"
|
||||
L"Note 2: This does not enable the mouse to function as an in-game mouse in PS2 games that support a USB mouse or lightgun."
|
||||
L"This requires a USB plugin, while LilyPad is a PAD plugin(PAD means it emulates devices that are to be plugged into the PlayStation controller port that connects the DualShock 2 controller).";
|
||||
case IDC_MOUSE_UNFOCUS:
|
||||
return L"Enabled: Mouse is unfocused and can be used for emulation and outside it.\n\n"
|
||||
L"Disabled: Mouse is focused and can be used for emulation.";
|
||||
case IDC_MULTIPLE_BINDING:
|
||||
return L"Allows binding multiple PS2 controls to one PC control, and binding conflicting controls on opposing ports and/or slots.\n\n"
|
||||
L"Also enables swapping different kinds of pad types(for example, between DS2 and Guitar) when right-clicking in the pad list.";
|
||||
case IDC_PAD_LIST:
|
||||
return L"Left-click on one of the available pads to enable the pad specific options on the right."
|
||||
L"These options include being able to select the pad type(DS2, Guitar, etc.) and enabling automatic analog mode for PS1 emulation.\n\n"
|
||||
L"Right-click to show a pop-up menu that allows for swapping all the settings and bindings, or just the bindings of individual pad types,"
|
||||
L"between the selected pad and one of other active pads, and clearing all the settings and bindings from the selected pad or just the bindings from a selected pad type.\n\n"
|
||||
L"Note: To allow swapping different kinds of pad types(like DS2 to Guitar), the \"Allow binding multiple PS2 Controls...\" option needs to be enabled as well.";
|
||||
case IDC_PAD_TYPE:
|
||||
return L"\"Unplugged\" disables the controller and removes the corresponding pad tab.\n\n"
|
||||
L"\"Dualshock 2\" emulates the default PS2 controller for use in both PS1 and PS2 games.\n\n"
|
||||
L"\"Guitar\" emulates a PS2 controller used in the Guitar Hero and Rock Band series of games.\n\n"
|
||||
L"\"Pop'n Music controller\" emulates a PS2 controller used exclusively in the Japanese Pop'n Music series of games.\n\n"
|
||||
L"\"PS1 Mouse\" emulates the PlayStation Mouse. This controller can only be used in a number of PS1 games like \"Command & Conquer: Red Alert\" and \"Myst\".\n\n"
|
||||
L"\"neGcon\" emulates a controller that can be used in a number of PS1 games and PS2 games like the \"Ridge Racer\" and \"Ace Combat\" series.";
|
||||
case IDC_DIAG_LIST:
|
||||
return L"Shows a list of currently available input devices.\n\n"
|
||||
L"Double-click a device in the list or right-click it and select \"Test Device\" to display a continuously updated list of the state of all inputs on the selected device.\n"
|
||||
L"Use this option to check if all the inputs on a controller function properly.\n\n"
|
||||
L"Right-click and select \"Refresh\" to update the list of devices in case a recently connected device has not shown up yet.";
|
||||
case IDC_G_DI:
|
||||
return L"(Legacy) Enable this if your gamepad doesn't support Xinput.\n\n"
|
||||
L"Disable for DualShock 4 (PS4 controllers) and probably others.";
|
||||
case IDC_G_XI:
|
||||
return L"For Xbox 360/ Xbox One controllers (or devices supporting Xinput).\n\n"
|
||||
L"If it doesn't support Xinput then running through Steam as a non-Steam game might be required for the controllers to work properly.\n\n"
|
||||
L"https://gamepad-tester.com/ to test your controller and check if it only says 'Xinput' on top.";
|
||||
case ID_RESTORE_DEFAULTS:
|
||||
return L"Restores the default contents of LilyPad.ini, undoing all settings changes and bindings that have been set up.";
|
||||
// Pad tabs
|
||||
case IDC_BINDINGS_LIST:
|
||||
return L"Shows a list of currently bound inputs of the selected Pad.\n\n"
|
||||
L"Left-click on one of the bindings in the list to configure it.\n\n"
|
||||
L"Right-click and select \"Delete Selected\" to remove the selected input from the list.\n\n"
|
||||
L"Right-click and select \"Clear All\" to remove all the inputs from the list.\n\n"
|
||||
L"Note: Use Shift/Ctrl + Left-click to select multiple bindings. Changing the displayed configuration will now copy it to all selected bindings.";
|
||||
case IDC_DEVICE_SELECT:
|
||||
return L"Select a single device to hide the bindings from other devices in the bindings list, and to only be able to add new bindings for the selected device.\n\n"
|
||||
L"This can also avoid input conflict issues when one controller is recognized as several devices through different APIs.";
|
||||
case IDC_CONFIGURE_ON_BIND:
|
||||
return L"Immediately go to the configuration setup when you create a new binding.";
|
||||
case ID_MOUSE:
|
||||
return L"Bind a key that releases or captures the mouse.\n\n"
|
||||
L"Pressing the assigned button when the mouse is in focus, it releases the mouse from use in-game and makes the cursor visible so it can move/resize the emulator window.\n\n"
|
||||
L"Alt-tabbing to another application also makes the cursor visible, but focusing the emulation window hides it again.\n\n"
|
||||
L"Pressing the button when the mouse is out of focus and visible, it captures the mouse so that it can be used as a controller again.\n\n"
|
||||
L"Note 1: Though the binding appears on the page of a specific pad, pressing the button affects all mice.\n\n"
|
||||
L"Note 2: By default PCSX2 uses a double-click by the left mouse button to toggle fullscreen mode, this makes the left mouse button unusable as an input."
|
||||
L"To disable this option in PCSX2 go to Config > Emulation Settings > GS Window tab, and disable the \"Double-click toggles fullscreen mode\" checkbox.";
|
||||
case ID_ANALOG:
|
||||
return L"Bind a keys that switches the pad from digital mode to analog mode and vice versa.\n\n"
|
||||
L"This option is useful when analog mode is enabled in a game that does not support it, as this causes the game to not recognise any input or to not even detect a controller.\n\n"
|
||||
L"This option can also be used to enable analog mode in games that support, but do not automatically enable analog mode.\n\n"
|
||||
L"Note: Analog mode enables the analog sticks to function on a DualShock controller, while in digital mode it behaves as an original PlayStation controller.\n\n";
|
||||
case ID_TURBO_KEY:
|
||||
return L"Sets a key to send a TAB press to the emulator, which toggles Turbo mode(200% speed) in PCSX2.";
|
||||
case ID_EXCLUDE:
|
||||
return L"Disables an input so it will be ignored when trying to bind another input.\n\n"
|
||||
L"This is helpful when binding controls for a device with an input that's difficult to center like an accelerator, or just always active like a faulty button or analog stick.";
|
||||
case ID_LOCK_ALL_INPUT:
|
||||
return L"Locks the current state of the pad. Any further input is handled normally, but the initial pad state is the locked state instead of a state with no buttons pressed. "
|
||||
L"Pressing it again releases the old pad state, if the old pad state had any keys pressed. Otherwise, it's released automatically.";
|
||||
case ID_LOCK_DIRECTION:
|
||||
return L"Locks the current state of the d-pad and analog sticks. Pressing this when all input is locked unlocks only the pad and sticks."
|
||||
L"Pressing it again will lock them again, keeping the buttons locked.";
|
||||
case ID_LOCK_BUTTONS:
|
||||
return L"Locks the current state of the buttons. Pressing this when all input is locked unlocks only the buttons. "
|
||||
L"Pressing it again will lock them again, keeping the d-pad and analog sticks locked.";
|
||||
case IDC_RAPID_FIRE:
|
||||
return L"Automatically presses/releases the input every other time the button is polled.";
|
||||
case IDC_FLIP:
|
||||
return L"Inverts a button or axis, making down up and up down.";
|
||||
case IDC_SLIDER_DEADZONE:
|
||||
return L"Decreases or increases the range of an input where no input is recognised.\n\n"
|
||||
L"Increasing the dead zone requires the input to be pressed harder or moved more before it is applied, decreasing it makes it recognise a softer press or a shorter movement.";
|
||||
case IDC_SLIDER_SKIP_DEADZONE:
|
||||
return L"Skips and avoids the dead zone to detect input earlier.\n\n"
|
||||
L"Note: This is useful when a controller input requires too much movement/pressure before there's a corresponding action in-game.";
|
||||
case IDC_SLIDER_SENSITIVITY:
|
||||
return L"Sets how hard an axis or button is pressed.\n\n"
|
||||
L"Note 1: What the default sensitivity value of \"1.00\" means depends on the device itself. The default is high enough that relative axes (which are primarily used by mice) are generally either considered fully up or down."
|
||||
L"For absolute axes (and force feedback devices), which are used by most game devices, a value of 1.0 should map the device's extreme values to the extreme values of a stick/pad.\n\n"
|
||||
L"Note 2: Setting the sensitivity of PC button bindings only really has an effect for PS2 analog sticks or when playing a game with full DS2 pressure sensitivity support.";
|
||||
default:
|
||||
if (updateText)
|
||||
*updateText = false;
|
||||
return L"";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,6 @@
|
|||
|
||||
#include "Global.h"
|
||||
|
||||
LPWSTR dialog_message(int ID, bool *updateText = false);
|
||||
LPWSTR dialog_message(int ID, bool* updateText = false);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,91 +17,95 @@
|
|||
#include "Global.h"
|
||||
#include "VKey.h"
|
||||
|
||||
wchar_t *GetVKStringW(unsigned char vk)
|
||||
wchar_t* GetVKStringW(unsigned char vk)
|
||||
{
|
||||
int flag;
|
||||
static wchar_t t[20];
|
||||
switch (vk) {
|
||||
case 0x0C:
|
||||
return L"Clear";
|
||||
case 0x13:
|
||||
return L"Pause";
|
||||
int flag;
|
||||
static wchar_t t[20];
|
||||
switch (vk)
|
||||
{
|
||||
case 0x0C:
|
||||
return L"Clear";
|
||||
case 0x13:
|
||||
return L"Pause";
|
||||
|
||||
case 0x21: // return "Page Up";
|
||||
case 0x22: // return "Page Down";
|
||||
case 0x23: // return "End";
|
||||
case 0x24: // return "Home";
|
||||
case 0x25: // return "Left";
|
||||
case 0x26: // return "Up";
|
||||
case 0x27: // return "Right";
|
||||
case 0x28: // return "Down";
|
||||
case 0x2D: // return "Insert";
|
||||
case 0x2E: // return "Delete";
|
||||
case 0x5B: // return "Left Windows";
|
||||
case 0x5C: // return "Right Windows";
|
||||
case 0x5D: // return "Application";
|
||||
case 0x6F: // return "Num /";
|
||||
flag = 1 << 24;
|
||||
break;
|
||||
case 0x21: // return "Page Up";
|
||||
case 0x22: // return "Page Down";
|
||||
case 0x23: // return "End";
|
||||
case 0x24: // return "Home";
|
||||
case 0x25: // return "Left";
|
||||
case 0x26: // return "Up";
|
||||
case 0x27: // return "Right";
|
||||
case 0x28: // return "Down";
|
||||
case 0x2D: // return "Insert";
|
||||
case 0x2E: // return "Delete";
|
||||
case 0x5B: // return "Left Windows";
|
||||
case 0x5C: // return "Right Windows";
|
||||
case 0x5D: // return "Application";
|
||||
case 0x6F: // return "Num /";
|
||||
flag = 1 << 24;
|
||||
break;
|
||||
|
||||
case 0x29:
|
||||
return L"Select";
|
||||
case 0x2A:
|
||||
return L"Print";
|
||||
case 0x2B:
|
||||
return L"Execute";
|
||||
case 0x2C:
|
||||
return L"Prnt Scrn";
|
||||
case 0x2F:
|
||||
return L"Help";
|
||||
case 0x29:
|
||||
return L"Select";
|
||||
case 0x2A:
|
||||
return L"Print";
|
||||
case 0x2B:
|
||||
return L"Execute";
|
||||
case 0x2C:
|
||||
return L"Prnt Scrn";
|
||||
case 0x2F:
|
||||
return L"Help";
|
||||
|
||||
case 0x6C:
|
||||
return L"|";
|
||||
case 0x90:
|
||||
return L"Num Lock";
|
||||
case 0x6C:
|
||||
return L"|";
|
||||
case 0x90:
|
||||
return L"Num Lock";
|
||||
|
||||
case 0xA0:
|
||||
return L"Left Shift";
|
||||
case 0xA1:
|
||||
return L"Right Shift";
|
||||
case 0xA2:
|
||||
return L"Left Ctrl";
|
||||
case 0xA3:
|
||||
return L"Right Ctrl";
|
||||
case 0xA4:
|
||||
return L"Left Alt";
|
||||
case 0xA5:
|
||||
return L"Right Alt";
|
||||
case 0xA0:
|
||||
return L"Left Shift";
|
||||
case 0xA1:
|
||||
return L"Right Shift";
|
||||
case 0xA2:
|
||||
return L"Left Ctrl";
|
||||
case 0xA3:
|
||||
return L"Right Ctrl";
|
||||
case 0xA4:
|
||||
return L"Left Alt";
|
||||
case 0xA5:
|
||||
return L"Right Alt";
|
||||
|
||||
case 0xA6:
|
||||
return L"Back";
|
||||
case 0xA7:
|
||||
return L"Forward";
|
||||
case 0xA8:
|
||||
return L"Refresh";
|
||||
case 0xA9:
|
||||
return L"Stop";
|
||||
case 0xAA:
|
||||
return L"Search";
|
||||
case 0xAB:
|
||||
return L"Favorites";
|
||||
case 0xAC:
|
||||
return L"Browser";
|
||||
case 0xA6:
|
||||
return L"Back";
|
||||
case 0xA7:
|
||||
return L"Forward";
|
||||
case 0xA8:
|
||||
return L"Refresh";
|
||||
case 0xA9:
|
||||
return L"Stop";
|
||||
case 0xAA:
|
||||
return L"Search";
|
||||
case 0xAB:
|
||||
return L"Favorites";
|
||||
case 0xAC:
|
||||
return L"Browser";
|
||||
|
||||
case 0xFA:
|
||||
return L"Play";
|
||||
case 0xFB:
|
||||
return L"Zoom";
|
||||
default:
|
||||
flag = 0;
|
||||
break;
|
||||
}
|
||||
int res = MapVirtualKey(vk, MAPVK_VK_TO_VSC);
|
||||
if (res && GetKeyNameText((res << 16) | flag, t, 20)) {
|
||||
// don't trust windows
|
||||
t[19] = 0;
|
||||
} else {
|
||||
wsprintfW(t, L"Key %i", vk);
|
||||
}
|
||||
return t;
|
||||
case 0xFA:
|
||||
return L"Play";
|
||||
case 0xFB:
|
||||
return L"Zoom";
|
||||
default:
|
||||
flag = 0;
|
||||
break;
|
||||
}
|
||||
int res = MapVirtualKey(vk, MAPVK_VK_TO_VSC);
|
||||
if (res && GetKeyNameText((res << 16) | flag, t, 20))
|
||||
{
|
||||
// don't trust windows
|
||||
t[19] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
wsprintfW(t, L"Key %i", vk);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
|
|
@ -14,4 +14,4 @@
|
|||
*/
|
||||
|
||||
// Maps virtual key codes to strings.
|
||||
wchar_t *GetVKStringW(unsigned char vk);
|
||||
wchar_t* GetVKStringW(unsigned char vk);
|
||||
|
|
|
@ -20,51 +20,58 @@
|
|||
#include "WindowsKeyboard.h"
|
||||
#include "KeyboardQueue.h"
|
||||
|
||||
WindowsKeyboard::WindowsKeyboard(DeviceAPI api, wchar_t *displayName, wchar_t *instanceID, wchar_t *deviceID)
|
||||
: Device(api, KEYBOARD, displayName, instanceID, deviceID)
|
||||
WindowsKeyboard::WindowsKeyboard(DeviceAPI api, wchar_t* displayName, wchar_t* instanceID, wchar_t* deviceID)
|
||||
: Device(api, KEYBOARD, displayName, instanceID, deviceID)
|
||||
{
|
||||
for (int i = 0; i < 256; i++) {
|
||||
AddPhysicalControl(PSHBTN, i, i);
|
||||
}
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
AddPhysicalControl(PSHBTN, i, i);
|
||||
}
|
||||
}
|
||||
|
||||
wchar_t *WindowsKeyboard::GetPhysicalControlName(PhysicalControl *control)
|
||||
wchar_t* WindowsKeyboard::GetPhysicalControlName(PhysicalControl* control)
|
||||
{
|
||||
int id = control->id;
|
||||
if (control->type == PSHBTN && id >= 0 && id < 256) {
|
||||
wchar_t *w = GetVKStringW(id);
|
||||
if (w)
|
||||
return w;
|
||||
}
|
||||
return Device::GetPhysicalControlName(control);
|
||||
int id = control->id;
|
||||
if (control->type == PSHBTN && id >= 0 && id < 256)
|
||||
{
|
||||
wchar_t* w = GetVKStringW(id);
|
||||
if (w)
|
||||
return w;
|
||||
}
|
||||
return Device::GetPhysicalControlName(control);
|
||||
}
|
||||
|
||||
void WindowsKeyboard::UpdateKey(int vkey, int state)
|
||||
{
|
||||
if (vkey > 7 && vkey < 256) {
|
||||
int newState = state * FULLY_DOWN;
|
||||
if (newState != physicalControlState[vkey]) {
|
||||
// Check for alt-F4 to avoid toggling skip mode incorrectly.
|
||||
if (vkey != VK_F4 || !(physicalControlState[VK_MENU] || physicalControlState[VK_RMENU] || physicalControlState[VK_LMENU])) {
|
||||
int event = KEYPRESS;
|
||||
if (!newState)
|
||||
event = KEYRELEASE;
|
||||
QueueKeyEvent(vkey, event);
|
||||
}
|
||||
}
|
||||
physicalControlState[vkey] = newState;
|
||||
}
|
||||
if (vkey > 7 && vkey < 256)
|
||||
{
|
||||
int newState = state * FULLY_DOWN;
|
||||
if (newState != physicalControlState[vkey])
|
||||
{
|
||||
// Check for alt-F4 to avoid toggling skip mode incorrectly.
|
||||
if (vkey != VK_F4 || !(physicalControlState[VK_MENU] || physicalControlState[VK_RMENU] || physicalControlState[VK_LMENU]))
|
||||
{
|
||||
int event = KEYPRESS;
|
||||
if (!newState)
|
||||
event = KEYRELEASE;
|
||||
QueueKeyEvent(vkey, event);
|
||||
}
|
||||
}
|
||||
physicalControlState[vkey] = newState;
|
||||
}
|
||||
}
|
||||
|
||||
void WindowsKeyboard::InitState()
|
||||
{
|
||||
AllocState();
|
||||
for (int vkey = 5; vkey < 256; vkey++) {
|
||||
int value = (unsigned short)(((short)GetAsyncKeyState(vkey)) >> 15);
|
||||
value += value & 1;
|
||||
if (vkey == VK_CONTROL || vkey == VK_MENU || vkey == VK_SHIFT) {
|
||||
value = 0;
|
||||
}
|
||||
physicalControlState[vkey] = value;
|
||||
}
|
||||
AllocState();
|
||||
for (int vkey = 5; vkey < 256; vkey++)
|
||||
{
|
||||
int value = (unsigned short)(((short)GetAsyncKeyState(vkey)) >> 15);
|
||||
value += value & 1;
|
||||
if (vkey == VK_CONTROL || vkey == VK_MENU || vkey == VK_SHIFT)
|
||||
{
|
||||
value = 0;
|
||||
}
|
||||
physicalControlState[vkey] = value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
class WindowsKeyboard : public Device
|
||||
{
|
||||
public:
|
||||
WindowsKeyboard(DeviceAPI api, wchar_t *displayName, wchar_t *instanceID = 0, wchar_t *deviceID = 0);
|
||||
wchar_t *GetPhysicalControlName(PhysicalControl *control);
|
||||
void UpdateKey(int vkey, int state);
|
||||
// Calls AllocState() and initializes to current keyboard state using
|
||||
// GetAsyncKeyState().
|
||||
void InitState();
|
||||
WindowsKeyboard(DeviceAPI api, wchar_t* displayName, wchar_t* instanceID = 0, wchar_t* deviceID = 0);
|
||||
wchar_t* GetPhysicalControlName(PhysicalControl* control);
|
||||
void UpdateKey(int vkey, int state);
|
||||
// Calls AllocState() and initializes to current keyboard state using
|
||||
// GetAsyncKeyState().
|
||||
void InitState();
|
||||
};
|
||||
|
|
|
@ -23,170 +23,200 @@
|
|||
#include "WindowsKeyboard.h"
|
||||
#include "WindowsMouse.h"
|
||||
|
||||
ExtraWndProcResult WindowsMessagingWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output);
|
||||
ExtraWndProcResult WindowsMessagingWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* output);
|
||||
|
||||
class WindowsMessagingKeyboard;
|
||||
class WindowsMessagingMouse;
|
||||
|
||||
static WindowsMessagingKeyboard *wmk = 0;
|
||||
static WindowsMessagingMouse *wmm = 0;
|
||||
static WindowsMessagingKeyboard* wmk = 0;
|
||||
static WindowsMessagingMouse* wmm = 0;
|
||||
|
||||
class WindowsMessagingKeyboard : public WindowsKeyboard
|
||||
{
|
||||
public:
|
||||
WindowsMessagingKeyboard()
|
||||
: WindowsKeyboard(WM, L"WM Keyboard")
|
||||
{
|
||||
}
|
||||
WindowsMessagingKeyboard()
|
||||
: WindowsKeyboard(WM, L"WM Keyboard")
|
||||
{
|
||||
}
|
||||
|
||||
int Activate(InitInfo *initInfo)
|
||||
{
|
||||
// Redundant. Should match the next line.
|
||||
// Deactivate();
|
||||
if (wmk)
|
||||
wmk->Deactivate();
|
||||
int Activate(InitInfo* initInfo)
|
||||
{
|
||||
// Redundant. Should match the next line.
|
||||
// Deactivate();
|
||||
if (wmk)
|
||||
wmk->Deactivate();
|
||||
|
||||
hWndProc = initInfo->hWndProc;
|
||||
hWndProc = initInfo->hWndProc;
|
||||
|
||||
if (!wmm)
|
||||
hWndProc->Eat(WindowsMessagingWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES);
|
||||
if (!wmm)
|
||||
hWndProc->Eat(WindowsMessagingWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES);
|
||||
|
||||
wmk = this;
|
||||
InitState();
|
||||
wmk = this;
|
||||
InitState();
|
||||
|
||||
active = 1;
|
||||
return 1;
|
||||
}
|
||||
active = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Deactivate()
|
||||
{
|
||||
if (active) {
|
||||
if (!wmm)
|
||||
hWndProc->ReleaseExtraProc(WindowsMessagingWndProc);
|
||||
wmk = 0;
|
||||
active = 0;
|
||||
FreeState();
|
||||
}
|
||||
}
|
||||
void Deactivate()
|
||||
{
|
||||
if (active)
|
||||
{
|
||||
if (!wmm)
|
||||
hWndProc->ReleaseExtraProc(WindowsMessagingWndProc);
|
||||
wmk = 0;
|
||||
active = 0;
|
||||
FreeState();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CheckKey(int vkey)
|
||||
{
|
||||
UpdateKey(vkey, 1 & (((unsigned short)GetAsyncKeyState(vkey)) >> 15));
|
||||
}
|
||||
void CheckKey(int vkey)
|
||||
{
|
||||
UpdateKey(vkey, 1 & (((unsigned short)GetAsyncKeyState(vkey)) >> 15));
|
||||
}
|
||||
};
|
||||
|
||||
class WindowsMessagingMouse : public WindowsMouse
|
||||
{
|
||||
public:
|
||||
WindowsMessagingMouse()
|
||||
: WindowsMouse(WM, 1, L"WM Mouse")
|
||||
{
|
||||
}
|
||||
WindowsMessagingMouse()
|
||||
: WindowsMouse(WM, 1, L"WM Mouse")
|
||||
{
|
||||
}
|
||||
|
||||
int Activate(InitInfo *initInfo)
|
||||
{
|
||||
// Redundant. Should match the next line.
|
||||
// Deactivate();
|
||||
if (wmm)
|
||||
wmm->Deactivate();
|
||||
hWndProc = initInfo->hWndProc;
|
||||
int Activate(InitInfo* initInfo)
|
||||
{
|
||||
// Redundant. Should match the next line.
|
||||
// Deactivate();
|
||||
if (wmm)
|
||||
wmm->Deactivate();
|
||||
hWndProc = initInfo->hWndProc;
|
||||
|
||||
if (!wmk)
|
||||
hWndProc->Eat(WindowsMessagingWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES);
|
||||
if (!wmk)
|
||||
hWndProc->Eat(WindowsMessagingWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES);
|
||||
|
||||
GetMouseCapture(hWndProc->hWndEaten);
|
||||
GetMouseCapture(hWndProc->hWndEaten);
|
||||
|
||||
active = 1;
|
||||
active = 1;
|
||||
|
||||
wmm = this;
|
||||
AllocState();
|
||||
wmm = this;
|
||||
AllocState();
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Deactivate()
|
||||
{
|
||||
if (active) {
|
||||
if (!wmk)
|
||||
hWndProc->ReleaseExtraProc(WindowsMessagingWndProc);
|
||||
ReleaseMouseCapture();
|
||||
wmm = 0;
|
||||
active = 0;
|
||||
FreeState();
|
||||
}
|
||||
}
|
||||
void Deactivate()
|
||||
{
|
||||
if (active)
|
||||
{
|
||||
if (!wmk)
|
||||
hWndProc->ReleaseExtraProc(WindowsMessagingWndProc);
|
||||
ReleaseMouseCapture();
|
||||
wmm = 0;
|
||||
active = 0;
|
||||
FreeState();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ExtraWndProcResult WindowsMessagingWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output)
|
||||
ExtraWndProcResult WindowsMessagingWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* output)
|
||||
{
|
||||
if (wmk) {
|
||||
if (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN || uMsg == WM_KEYUP || uMsg == WM_SYSKEYUP) {
|
||||
if (wParam == VK_SHIFT) {
|
||||
wmk->CheckKey(VK_RSHIFT);
|
||||
wmk->CheckKey(VK_LSHIFT);
|
||||
} else if (wParam == VK_CONTROL) {
|
||||
wmk->CheckKey(VK_RCONTROL);
|
||||
wmk->CheckKey(VK_LCONTROL);
|
||||
} else if (wParam == VK_MENU) {
|
||||
wmk->CheckKey(VK_RMENU);
|
||||
wmk->CheckKey(VK_LMENU);
|
||||
} else
|
||||
wmk->UpdateKey(wParam, (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN));
|
||||
return NO_WND_PROC;
|
||||
}
|
||||
// Needed to prevent default handling of keys in some situations.
|
||||
else if (uMsg == WM_CHAR || uMsg == WM_UNICHAR) {
|
||||
return NO_WND_PROC;
|
||||
} else if (uMsg == WM_ACTIVATE) {
|
||||
// Not really needed, but doesn't hurt.
|
||||
memset(wmk->physicalControlState, 0, sizeof(int) * wmk->numPhysicalControls);
|
||||
}
|
||||
}
|
||||
if (wmm) {
|
||||
if (uMsg == WM_MOUSEMOVE) {
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
// Need check to prevent cursor movement cascade.
|
||||
if (p.x != wmm->center.x || p.y != wmm->center.y) {
|
||||
wmm->UpdateAxis(0, p.x - wmm->center.x);
|
||||
wmm->UpdateAxis(1, p.y - wmm->center.y);
|
||||
if (wmk)
|
||||
{
|
||||
if (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN || uMsg == WM_KEYUP || uMsg == WM_SYSKEYUP)
|
||||
{
|
||||
if (wParam == VK_SHIFT)
|
||||
{
|
||||
wmk->CheckKey(VK_RSHIFT);
|
||||
wmk->CheckKey(VK_LSHIFT);
|
||||
}
|
||||
else if (wParam == VK_CONTROL)
|
||||
{
|
||||
wmk->CheckKey(VK_RCONTROL);
|
||||
wmk->CheckKey(VK_LCONTROL);
|
||||
}
|
||||
else if (wParam == VK_MENU)
|
||||
{
|
||||
wmk->CheckKey(VK_RMENU);
|
||||
wmk->CheckKey(VK_LMENU);
|
||||
}
|
||||
else
|
||||
wmk->UpdateKey(wParam, (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN));
|
||||
return NO_WND_PROC;
|
||||
}
|
||||
// Needed to prevent default handling of keys in some situations.
|
||||
else if (uMsg == WM_CHAR || uMsg == WM_UNICHAR)
|
||||
{
|
||||
return NO_WND_PROC;
|
||||
}
|
||||
else if (uMsg == WM_ACTIVATE)
|
||||
{
|
||||
// Not really needed, but doesn't hurt.
|
||||
memset(wmk->physicalControlState, 0, sizeof(int) * wmk->numPhysicalControls);
|
||||
}
|
||||
}
|
||||
if (wmm)
|
||||
{
|
||||
if (uMsg == WM_MOUSEMOVE)
|
||||
{
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
// Need check to prevent cursor movement cascade.
|
||||
if (p.x != wmm->center.x || p.y != wmm->center.y)
|
||||
{
|
||||
wmm->UpdateAxis(0, p.x - wmm->center.x);
|
||||
wmm->UpdateAxis(1, p.y - wmm->center.y);
|
||||
|
||||
SetCursorPos(wmm->center.x, wmm->center.y);
|
||||
}
|
||||
return NO_WND_PROC;
|
||||
} else if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP) {
|
||||
wmm->UpdateButton(0, uMsg == WM_LBUTTONDOWN);
|
||||
return NO_WND_PROC;
|
||||
} else if (uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONUP) {
|
||||
wmm->UpdateButton(1, uMsg == WM_RBUTTONDOWN);
|
||||
return NO_WND_PROC;
|
||||
} else if (uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP) {
|
||||
wmm->UpdateButton(2, uMsg == WM_MBUTTONDOWN);
|
||||
return NO_WND_PROC;
|
||||
} else if (uMsg == WM_XBUTTONDOWN || uMsg == WM_XBUTTONUP) {
|
||||
wmm->UpdateButton(3 + ((wParam >> 16) == XBUTTON2), uMsg == WM_XBUTTONDOWN);
|
||||
return NO_WND_PROC;
|
||||
} else if (uMsg == WM_MOUSEWHEEL) {
|
||||
wmm->UpdateAxis(2, ((int)wParam >> 16) / WHEEL_DELTA);
|
||||
return NO_WND_PROC;
|
||||
} else if (uMsg == WM_MOUSEHWHEEL) {
|
||||
wmm->UpdateAxis(3, ((int)wParam >> 16) / WHEEL_DELTA);
|
||||
return NO_WND_PROC;
|
||||
} else if (uMsg == WM_SIZE && wmm->active) {
|
||||
WindowsMouse::WindowResized(hWnd);
|
||||
}
|
||||
// Taken care of elsewhere. When binding, killing focus means stop reading input.
|
||||
// When running PCSX2, I release all mouse and keyboard input elsewhere.
|
||||
/*else if (uMsg == WM_KILLFOCUS) {
|
||||
SetCursorPos(wmm->center.x, wmm->center.y);
|
||||
}
|
||||
return NO_WND_PROC;
|
||||
}
|
||||
else if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP)
|
||||
{
|
||||
wmm->UpdateButton(0, uMsg == WM_LBUTTONDOWN);
|
||||
return NO_WND_PROC;
|
||||
}
|
||||
else if (uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONUP)
|
||||
{
|
||||
wmm->UpdateButton(1, uMsg == WM_RBUTTONDOWN);
|
||||
return NO_WND_PROC;
|
||||
}
|
||||
else if (uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP)
|
||||
{
|
||||
wmm->UpdateButton(2, uMsg == WM_MBUTTONDOWN);
|
||||
return NO_WND_PROC;
|
||||
}
|
||||
else if (uMsg == WM_XBUTTONDOWN || uMsg == WM_XBUTTONUP)
|
||||
{
|
||||
wmm->UpdateButton(3 + ((wParam >> 16) == XBUTTON2), uMsg == WM_XBUTTONDOWN);
|
||||
return NO_WND_PROC;
|
||||
}
|
||||
else if (uMsg == WM_MOUSEWHEEL)
|
||||
{
|
||||
wmm->UpdateAxis(2, ((int)wParam >> 16) / WHEEL_DELTA);
|
||||
return NO_WND_PROC;
|
||||
}
|
||||
else if (uMsg == WM_MOUSEHWHEEL)
|
||||
{
|
||||
wmm->UpdateAxis(3, ((int)wParam >> 16) / WHEEL_DELTA);
|
||||
return NO_WND_PROC;
|
||||
}
|
||||
else if (uMsg == WM_SIZE && wmm->active)
|
||||
{
|
||||
WindowsMouse::WindowResized(hWnd);
|
||||
}
|
||||
// Taken care of elsewhere. When binding, killing focus means stop reading input.
|
||||
// When running PCSX2, I release all mouse and keyboard input elsewhere.
|
||||
/*else if (uMsg == WM_KILLFOCUS) {
|
||||
wmm->Deactivate();
|
||||
}//*/
|
||||
}
|
||||
return CONTINUE_BLISSFULLY;
|
||||
}
|
||||
return CONTINUE_BLISSFULLY;
|
||||
}
|
||||
|
||||
void EnumWindowsMessagingDevices()
|
||||
{
|
||||
dm->AddDevice(new WindowsMessagingKeyboard());
|
||||
dm->AddDevice(new WindowsMessagingMouse());
|
||||
dm->AddDevice(new WindowsMessagingKeyboard());
|
||||
dm->AddDevice(new WindowsMessagingMouse());
|
||||
}
|
||||
|
|
|
@ -22,80 +22,82 @@
|
|||
POINT WindowsMouse::origCursorPos;
|
||||
POINT WindowsMouse::center;
|
||||
|
||||
WindowsMouse::WindowsMouse(DeviceAPI api, int hWheel, wchar_t *displayName, wchar_t *instanceID, wchar_t *deviceID)
|
||||
: Device(api, MOUSE, displayName, instanceID, deviceID)
|
||||
WindowsMouse::WindowsMouse(DeviceAPI api, int hWheel, wchar_t* displayName, wchar_t* instanceID, wchar_t* deviceID)
|
||||
: Device(api, MOUSE, displayName, instanceID, deviceID)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 5; i++) {
|
||||
AddPhysicalControl(PSHBTN, i, i);
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
AddPhysicalControl(PSHBTN, i, i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 3 + hWheel; i++) {
|
||||
AddPhysicalControl(RELAXIS, i + 5, i + 5);
|
||||
}
|
||||
for (i = 0; i < 3 + hWheel; i++)
|
||||
{
|
||||
AddPhysicalControl(RELAXIS, i + 5, i + 5);
|
||||
}
|
||||
}
|
||||
|
||||
wchar_t *WindowsMouse::GetPhysicalControlName(PhysicalControl *control)
|
||||
wchar_t* WindowsMouse::GetPhysicalControlName(PhysicalControl* control)
|
||||
{
|
||||
wchar_t *names[9] = {
|
||||
L"L Button",
|
||||
L"R Button",
|
||||
L"M Button",
|
||||
L"Mouse 4",
|
||||
L"Mouse 5",
|
||||
L"X Axis",
|
||||
L"Y Axis",
|
||||
L"Y Wheel",
|
||||
L"X Wheel"};
|
||||
if (control->id < 9)
|
||||
return names[control->id];
|
||||
return Device::GetPhysicalControlName(control);
|
||||
wchar_t* names[9] = {
|
||||
L"L Button",
|
||||
L"R Button",
|
||||
L"M Button",
|
||||
L"Mouse 4",
|
||||
L"Mouse 5",
|
||||
L"X Axis",
|
||||
L"Y Axis",
|
||||
L"Y Wheel",
|
||||
L"X Wheel"};
|
||||
if (control->id < 9)
|
||||
return names[control->id];
|
||||
return Device::GetPhysicalControlName(control);
|
||||
}
|
||||
|
||||
void WindowsMouse::UpdateButton(unsigned int button, int state)
|
||||
{
|
||||
if (button > 4)
|
||||
return;
|
||||
physicalControlState[button] = (state << 16);
|
||||
if (button > 4)
|
||||
return;
|
||||
physicalControlState[button] = (state << 16);
|
||||
}
|
||||
|
||||
void WindowsMouse::UpdateAxis(unsigned int axis, int delta)
|
||||
{
|
||||
if (axis > 3)
|
||||
return;
|
||||
// 1 mouse pixel = 1/8th way down.
|
||||
physicalControlState[5 + axis] += (delta << (16 - 3 * (axis < 2)));
|
||||
if (axis > 3)
|
||||
return;
|
||||
// 1 mouse pixel = 1/8th way down.
|
||||
physicalControlState[5 + axis] += (delta << (16 - 3 * (axis < 2)));
|
||||
}
|
||||
|
||||
void WindowsMouse::WindowResized(HWND hWnd)
|
||||
{
|
||||
RECT r;
|
||||
GetWindowRect(hWnd, &r);
|
||||
ClipCursor(&r);
|
||||
center.x = (r.left + r.right) / 2;
|
||||
center.y = (r.top + r.bottom) / 2;
|
||||
SetCursorPos(center.x, center.y);
|
||||
RECT r;
|
||||
GetWindowRect(hWnd, &r);
|
||||
ClipCursor(&r);
|
||||
center.x = (r.left + r.right) / 2;
|
||||
center.y = (r.top + r.bottom) / 2;
|
||||
SetCursorPos(center.x, center.y);
|
||||
}
|
||||
|
||||
void WindowsMouse::GetMouseCapture(HWND hWnd)
|
||||
{
|
||||
SetCapture(hWnd);
|
||||
ShowCursor(0);
|
||||
SetCapture(hWnd);
|
||||
ShowCursor(0);
|
||||
|
||||
GetCursorPos(&origCursorPos);
|
||||
GetCursorPos(&origCursorPos);
|
||||
|
||||
RECT r;
|
||||
GetWindowRect(hWnd, &r);
|
||||
ClipCursor(&r);
|
||||
center.x = (r.left + r.right) / 2;
|
||||
center.y = (r.top + r.bottom) / 2;
|
||||
SetCursorPos(center.x, center.y);
|
||||
RECT r;
|
||||
GetWindowRect(hWnd, &r);
|
||||
ClipCursor(&r);
|
||||
center.x = (r.left + r.right) / 2;
|
||||
center.y = (r.top + r.bottom) / 2;
|
||||
SetCursorPos(center.x, center.y);
|
||||
}
|
||||
|
||||
void WindowsMouse::ReleaseMouseCapture()
|
||||
{
|
||||
ClipCursor(0);
|
||||
ReleaseCapture();
|
||||
ShowCursor(1);
|
||||
SetCursorPos(origCursorPos.x, origCursorPos.y);
|
||||
ClipCursor(0);
|
||||
ReleaseCapture();
|
||||
ShowCursor(1);
|
||||
SetCursorPos(origCursorPos.x, origCursorPos.y);
|
||||
}
|
||||
|
|
|
@ -17,24 +17,24 @@
|
|||
class WindowsMouse : public Device
|
||||
{
|
||||
public:
|
||||
// Used by GetMouseCapture()/ReleaseMouseCapture()
|
||||
// Static because can have multiple raw mice active at once,
|
||||
// and only get/release capture once.
|
||||
static POINT origCursorPos;
|
||||
static POINT center;
|
||||
// Used by GetMouseCapture()/ReleaseMouseCapture()
|
||||
// Static because can have multiple raw mice active at once,
|
||||
// and only get/release capture once.
|
||||
static POINT origCursorPos;
|
||||
static POINT center;
|
||||
|
||||
static void GetMouseCapture(HWND hWnd);
|
||||
static void WindowResized(HWND hWnd);
|
||||
static void ReleaseMouseCapture();
|
||||
static void GetMouseCapture(HWND hWnd);
|
||||
static void WindowResized(HWND hWnd);
|
||||
static void ReleaseMouseCapture();
|
||||
|
||||
// hWheel variable lets me display no horizontal wheel for raw input, just to make it clear
|
||||
// that it's not supported.
|
||||
WindowsMouse(DeviceAPI api, int hWheel, wchar_t *displayName, wchar_t *instanceID = 0, wchar_t *deviceID = 0);
|
||||
wchar_t *GetPhysicalControlName(PhysicalControl *control);
|
||||
// State is 0 for up, 1 for down.
|
||||
void UpdateButton(unsigned int button, int state);
|
||||
// 0/1 are x/y. 2 is vert wheel, 3 is horiz wheel.
|
||||
// Delta is in my micro units. change of (1<<16) is 1 full unit, with
|
||||
// the default sensitivity.
|
||||
void UpdateAxis(unsigned int axis, int delta);
|
||||
// hWheel variable lets me display no horizontal wheel for raw input, just to make it clear
|
||||
// that it's not supported.
|
||||
WindowsMouse(DeviceAPI api, int hWheel, wchar_t* displayName, wchar_t* instanceID = 0, wchar_t* deviceID = 0);
|
||||
wchar_t* GetPhysicalControlName(PhysicalControl* control);
|
||||
// State is 0 for up, 1 for down.
|
||||
void UpdateButton(unsigned int button, int state);
|
||||
// 0/1 are x/y. 2 is vert wheel, 3 is horiz wheel.
|
||||
// Delta is in my micro units. change of (1<<16) is 1 full unit, with
|
||||
// the default sensitivity.
|
||||
void UpdateAxis(unsigned int axis, int delta);
|
||||
};
|
||||
|
|
|
@ -19,136 +19,148 @@
|
|||
|
||||
WndProcEater::WndProcEater()
|
||||
{
|
||||
hWndEaten = 0;
|
||||
eatenWndProc = 0;
|
||||
hWndEaten = 0;
|
||||
eatenWndProc = 0;
|
||||
|
||||
extraProcs = 0;
|
||||
numExtraProcs = 0;
|
||||
extraProcs = 0;
|
||||
numExtraProcs = 0;
|
||||
|
||||
hMutex = CreateMutex(0, 0, L"LilyPad");
|
||||
hMutex = CreateMutex(0, 0, L"LilyPad");
|
||||
}
|
||||
|
||||
WndProcEater::~WndProcEater() throw()
|
||||
{
|
||||
if (hMutex) {
|
||||
ReleaseMutex(hMutex);
|
||||
CloseHandle(hMutex);
|
||||
}
|
||||
if (hMutex)
|
||||
{
|
||||
ReleaseMutex(hMutex);
|
||||
CloseHandle(hMutex);
|
||||
}
|
||||
}
|
||||
|
||||
void WndProcEater::ReleaseExtraProc(ExtraWndProc proc)
|
||||
{
|
||||
// Probably isn't needed, but just in case...
|
||||
if (hMutex)
|
||||
WaitForSingleObject(hMutex, 100);
|
||||
// Probably isn't needed, but just in case...
|
||||
if (hMutex)
|
||||
WaitForSingleObject(hMutex, 100);
|
||||
|
||||
//printf( "(Lilypad) Regurgitating! -> 0x%x\n", proc );
|
||||
//printf( "(Lilypad) Regurgitating! -> 0x%x\n", proc );
|
||||
|
||||
for (int i = 0; i < numExtraProcs; i++) {
|
||||
if (extraProcs[i].proc == proc) {
|
||||
extraProcs[i] = extraProcs[--numExtraProcs];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!numExtraProcs && eatenWndProc) {
|
||||
free(extraProcs);
|
||||
extraProcs = 0;
|
||||
// As numExtraProcs is 0, won't cause recursion if called from Release().
|
||||
Release();
|
||||
}
|
||||
for (int i = 0; i < numExtraProcs; i++)
|
||||
{
|
||||
if (extraProcs[i].proc == proc)
|
||||
{
|
||||
extraProcs[i] = extraProcs[--numExtraProcs];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!numExtraProcs && eatenWndProc)
|
||||
{
|
||||
free(extraProcs);
|
||||
extraProcs = 0;
|
||||
// As numExtraProcs is 0, won't cause recursion if called from Release().
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
||||
void WndProcEater::Release()
|
||||
{
|
||||
while (numExtraProcs)
|
||||
ReleaseExtraProc(extraProcs[0].proc);
|
||||
if (hWndEaten && IsWindow(hWndEaten)) {
|
||||
RemoveProp(hWndEaten, L"LilyHaxxor");
|
||||
SetWindowLongPtr(hWndEaten, GWLP_WNDPROC, (LONG_PTR)eatenWndProc);
|
||||
hWndEaten = 0;
|
||||
eatenWndProc = 0;
|
||||
}
|
||||
while (numExtraProcs)
|
||||
ReleaseExtraProc(extraProcs[0].proc);
|
||||
if (hWndEaten && IsWindow(hWndEaten))
|
||||
{
|
||||
RemoveProp(hWndEaten, L"LilyHaxxor");
|
||||
SetWindowLongPtr(hWndEaten, GWLP_WNDPROC, (LONG_PTR)eatenWndProc);
|
||||
hWndEaten = 0;
|
||||
eatenWndProc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT WndProcEater::_OverrideWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (hWnd != hWndEaten)
|
||||
fprintf(stderr, "Totally mismatched window handles on OverrideWndProc!\n");
|
||||
if (hWnd != hWndEaten)
|
||||
fprintf(stderr, "Totally mismatched window handles on OverrideWndProc!\n");
|
||||
|
||||
ExtraWndProcResult res = CONTINUE_BLISSFULLY;
|
||||
LRESULT out = 0;
|
||||
// Here because want it for binding, even when no keyboard mode is selected.
|
||||
if (uMsg == WM_GETDLGCODE) {
|
||||
return DLGC_WANTALLKEYS | CallWindowProc(eatenWndProc, hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
ExtraWndProcResult res = CONTINUE_BLISSFULLY;
|
||||
LRESULT out = 0;
|
||||
// Here because want it for binding, even when no keyboard mode is selected.
|
||||
if (uMsg == WM_GETDLGCODE)
|
||||
{
|
||||
return DLGC_WANTALLKEYS | CallWindowProc(eatenWndProc, hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
for (int i = 0; i < numExtraProcs; i++) {
|
||||
// Note: Second bit of deviceUpdateQueued is only set when I receive a device change
|
||||
// notification, which is handled in the GS thread in one of the extraProcs, so this
|
||||
// is all I need to prevent bad things from happening while updating devices. No mutex needed.
|
||||
// if ((deviceUpdateQueued&2) && (extraProcs[i].flags & EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES)) continue;
|
||||
for (int i = 0; i < numExtraProcs; i++)
|
||||
{
|
||||
// Note: Second bit of deviceUpdateQueued is only set when I receive a device change
|
||||
// notification, which is handled in the GS thread in one of the extraProcs, so this
|
||||
// is all I need to prevent bad things from happening while updating devices. No mutex needed.
|
||||
// if ((deviceUpdateQueued&2) && (extraProcs[i].flags & EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES)) continue;
|
||||
|
||||
ExtraWndProcResult res2 = extraProcs[i].proc(hWnd, uMsg, wParam, lParam, &out);
|
||||
if (res2 != res) {
|
||||
if (res2 == CONTINUE_BLISSFULLY_AND_RELEASE_PROC) {
|
||||
ReleaseExtraProc(extraProcs[i].proc);
|
||||
i--;
|
||||
} else if (res2 > res)
|
||||
res = res2;
|
||||
}
|
||||
}
|
||||
ExtraWndProcResult res2 = extraProcs[i].proc(hWnd, uMsg, wParam, lParam, &out);
|
||||
if (res2 != res)
|
||||
{
|
||||
if (res2 == CONTINUE_BLISSFULLY_AND_RELEASE_PROC)
|
||||
{
|
||||
ReleaseExtraProc(extraProcs[i].proc);
|
||||
i--;
|
||||
}
|
||||
else if (res2 > res)
|
||||
res = res2;
|
||||
}
|
||||
}
|
||||
|
||||
if (res != NO_WND_PROC) {
|
||||
if (out == WM_DESTROY) {
|
||||
Release();
|
||||
}
|
||||
if (res == CONTINUE_BLISSFULLY)
|
||||
out = CallWindowProc(eatenWndProc, hWnd, uMsg, wParam, lParam);
|
||||
else if (res == USE_DEFAULT_WND_PROC)
|
||||
out = DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
return out;
|
||||
if (res != NO_WND_PROC)
|
||||
{
|
||||
if (out == WM_DESTROY)
|
||||
{
|
||||
Release();
|
||||
}
|
||||
if (res == CONTINUE_BLISSFULLY)
|
||||
out = CallWindowProc(eatenWndProc, hWnd, uMsg, wParam, lParam);
|
||||
else if (res == USE_DEFAULT_WND_PROC)
|
||||
out = DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK OverrideWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
WndProcEater *obj = (WndProcEater *)GetProp(hWnd, L"LilyHaxxor");
|
||||
return (obj == NULL) ?
|
||||
DefWindowProc(hWnd, uMsg, wParam, lParam) :
|
||||
obj->_OverrideWndProc(hWnd, uMsg, wParam, lParam);
|
||||
WndProcEater* obj = (WndProcEater*)GetProp(hWnd, L"LilyHaxxor");
|
||||
return (obj == NULL) ?
|
||||
DefWindowProc(hWnd, uMsg, wParam, lParam) :
|
||||
obj->_OverrideWndProc(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
bool WndProcEater::SetWndHandle(HWND hWnd)
|
||||
{
|
||||
if (hWnd == hWndEaten)
|
||||
return true;
|
||||
if (hWnd == hWndEaten)
|
||||
return true;
|
||||
|
||||
//printf( "(Lilypad) (Re)-Setting window handle! -> this=0x%08x, hWnd=0x%08x\n", this, hWnd );
|
||||
//printf( "(Lilypad) (Re)-Setting window handle! -> this=0x%08x, hWnd=0x%08x\n", this, hWnd );
|
||||
|
||||
Release();
|
||||
SetProp(hWnd, L"LilyHaxxor", (HANDLE) this);
|
||||
Release();
|
||||
SetProp(hWnd, L"LilyHaxxor", (HANDLE)this);
|
||||
|
||||
eatenWndProc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)OverrideWndProc);
|
||||
hWndEaten = (eatenWndProc) ? hWnd : 0;
|
||||
eatenWndProc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)OverrideWndProc);
|
||||
hWndEaten = (eatenWndProc) ? hWnd : 0;
|
||||
|
||||
return !!hWndEaten;
|
||||
return !!hWndEaten;
|
||||
}
|
||||
|
||||
void WndProcEater::Eat(ExtraWndProc proc, DWORD flags)
|
||||
{
|
||||
|
||||
// check if Subclassing failed to init during SetWndHandle
|
||||
if (!hWndEaten)
|
||||
return;
|
||||
// check if Subclassing failed to init during SetWndHandle
|
||||
if (!hWndEaten)
|
||||
return;
|
||||
|
||||
// Probably isn't needed, but just in case...
|
||||
if (hMutex)
|
||||
WaitForSingleObject(hMutex, 100);
|
||||
// Probably isn't needed, but just in case...
|
||||
if (hMutex)
|
||||
WaitForSingleObject(hMutex, 100);
|
||||
|
||||
//printf( "(Lilypad) EatingWndProc! -> 0x%x\n", proc );
|
||||
//printf( "(Lilypad) EatingWndProc! -> 0x%x\n", proc );
|
||||
|
||||
extraProcs = (ExtraWndProcInfo *)realloc(extraProcs, sizeof(ExtraWndProcInfo) * (numExtraProcs + 1));
|
||||
extraProcs[numExtraProcs].proc = proc;
|
||||
extraProcs[numExtraProcs].flags = flags;
|
||||
numExtraProcs++;
|
||||
extraProcs = (ExtraWndProcInfo*)realloc(extraProcs, sizeof(ExtraWndProcInfo) * (numExtraProcs + 1));
|
||||
extraProcs[numExtraProcs].proc = proc;
|
||||
extraProcs[numExtraProcs].flags = flags;
|
||||
numExtraProcs++;
|
||||
}
|
||||
|
|
|
@ -17,42 +17,43 @@
|
|||
|
||||
/* Need this to let window be subclassed multiple times but still clean up nicely.
|
||||
*/
|
||||
enum ExtraWndProcResult {
|
||||
CONTINUE_BLISSFULLY,
|
||||
// Calls ReleaseExtraProc without messing up order.
|
||||
CONTINUE_BLISSFULLY_AND_RELEASE_PROC,
|
||||
USE_DEFAULT_WND_PROC,
|
||||
NO_WND_PROC
|
||||
enum ExtraWndProcResult
|
||||
{
|
||||
CONTINUE_BLISSFULLY,
|
||||
// Calls ReleaseExtraProc without messing up order.
|
||||
CONTINUE_BLISSFULLY_AND_RELEASE_PROC,
|
||||
USE_DEFAULT_WND_PROC,
|
||||
NO_WND_PROC
|
||||
};
|
||||
|
||||
typedef ExtraWndProcResult (*ExtraWndProc)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *out);
|
||||
typedef ExtraWndProcResult (*ExtraWndProc)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* out);
|
||||
|
||||
struct ExtraWndProcInfo
|
||||
{
|
||||
ExtraWndProc proc;
|
||||
DWORD flags;
|
||||
ExtraWndProc proc;
|
||||
DWORD flags;
|
||||
};
|
||||
|
||||
class WndProcEater
|
||||
{
|
||||
public:
|
||||
HWND hWndEaten;
|
||||
WNDPROC eatenWndProc;
|
||||
ExtraWndProcInfo *extraProcs;
|
||||
int numExtraProcs;
|
||||
HWND hWndEaten;
|
||||
WNDPROC eatenWndProc;
|
||||
ExtraWndProcInfo* extraProcs;
|
||||
int numExtraProcs;
|
||||
|
||||
HANDLE hMutex;
|
||||
HANDLE hMutex;
|
||||
|
||||
public:
|
||||
WndProcEater();
|
||||
virtual ~WndProcEater() throw();
|
||||
WndProcEater();
|
||||
virtual ~WndProcEater() throw();
|
||||
|
||||
bool SetWndHandle(HWND hWnd);
|
||||
void Eat(ExtraWndProc proc, DWORD flags);
|
||||
void ReleaseExtraProc(ExtraWndProc proc);
|
||||
void Release();
|
||||
bool SetWndHandle(HWND hWnd);
|
||||
void Eat(ExtraWndProc proc, DWORD flags);
|
||||
void ReleaseExtraProc(ExtraWndProc proc);
|
||||
void Release();
|
||||
|
||||
LRESULT _OverrideWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT _OverrideWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
};
|
||||
|
||||
extern WndProcEater hWndGSProc;
|
||||
|
|
|
@ -27,43 +27,43 @@
|
|||
|
||||
typedef struct
|
||||
{
|
||||
float SCP_UP;
|
||||
float SCP_RIGHT;
|
||||
float SCP_DOWN;
|
||||
float SCP_LEFT;
|
||||
float SCP_UP;
|
||||
float SCP_RIGHT;
|
||||
float SCP_DOWN;
|
||||
float SCP_LEFT;
|
||||
|
||||
float SCP_LX;
|
||||
float SCP_LY;
|
||||
float SCP_LX;
|
||||
float SCP_LY;
|
||||
|
||||
float SCP_L1;
|
||||
float SCP_L2;
|
||||
float SCP_L3;
|
||||
float SCP_L1;
|
||||
float SCP_L2;
|
||||
float SCP_L3;
|
||||
|
||||
float SCP_RX;
|
||||
float SCP_RY;
|
||||
float SCP_RX;
|
||||
float SCP_RY;
|
||||
|
||||
float SCP_R1;
|
||||
float SCP_R2;
|
||||
float SCP_R3;
|
||||
float SCP_R1;
|
||||
float SCP_R2;
|
||||
float SCP_R3;
|
||||
|
||||
float SCP_T;
|
||||
float SCP_C;
|
||||
float SCP_X;
|
||||
float SCP_S;
|
||||
float SCP_T;
|
||||
float SCP_C;
|
||||
float SCP_X;
|
||||
float SCP_S;
|
||||
|
||||
float SCP_SELECT;
|
||||
float SCP_START;
|
||||
float SCP_SELECT;
|
||||
float SCP_START;
|
||||
|
||||
float SCP_PS;
|
||||
float SCP_PS;
|
||||
|
||||
} SCP_EXTN;
|
||||
|
||||
|
||||
// This way, I don't require that XInput junk be installed.
|
||||
typedef void(CALLBACK *_XInputEnable)(BOOL enable);
|
||||
typedef DWORD(CALLBACK *_XInputGetStateEx)(DWORD dwUserIndex, XINPUT_STATE *pState);
|
||||
typedef DWORD(CALLBACK *_XInputGetExtended)(DWORD dwUserIndex, SCP_EXTN *pPressure);
|
||||
typedef DWORD(CALLBACK *_XInputSetState)(DWORD dwUserIndex, XINPUT_VIBRATION *pVibration);
|
||||
typedef void(CALLBACK* _XInputEnable)(BOOL enable);
|
||||
typedef DWORD(CALLBACK* _XInputGetStateEx)(DWORD dwUserIndex, XINPUT_STATE* pState);
|
||||
typedef DWORD(CALLBACK* _XInputGetExtended)(DWORD dwUserIndex, SCP_EXTN* pPressure);
|
||||
typedef DWORD(CALLBACK* _XInputSetState)(DWORD dwUserIndex, XINPUT_VIBRATION* pVibration);
|
||||
|
||||
_XInputEnable pXInputEnable = 0;
|
||||
_XInputGetStateEx pXInputGetStateEx = 0;
|
||||
|
@ -76,229 +76,253 @@ static int xInputActiveCount = 0;
|
|||
// Completely unncessary, really.
|
||||
__forceinline int ShortToAxis(int v)
|
||||
{
|
||||
// If positive and at least 1 << 14, increment.
|
||||
v += (!((v >> 15) & 1)) & ((v >> 14) & 1);
|
||||
// Just double.
|
||||
return v * 2;
|
||||
// If positive and at least 1 << 14, increment.
|
||||
v += (!((v >> 15) & 1)) & ((v >> 14) & 1);
|
||||
// Just double.
|
||||
return v * 2;
|
||||
}
|
||||
|
||||
class XInputDevice : 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];
|
||||
// Minor optimization - cache last set vibration values
|
||||
// When there's no change, no need to do anything.
|
||||
XINPUT_VIBRATION xInputVibration;
|
||||
// Cached last vibration values by pad and motor.
|
||||
// Need this, as only one value is changed at a time.
|
||||
int ps2Vibration[2][4][2];
|
||||
// Minor optimization - cache last set vibration values
|
||||
// When there's no change, no need to do anything.
|
||||
XINPUT_VIBRATION xInputVibration;
|
||||
|
||||
public:
|
||||
int index;
|
||||
int index;
|
||||
|
||||
XInputDevice(int index, wchar_t *displayName)
|
||||
: Device(XINPUT, OTHER, displayName)
|
||||
{
|
||||
memset(ps2Vibration, 0, sizeof(ps2Vibration));
|
||||
memset(&xInputVibration, 0, sizeof(xInputVibration));
|
||||
this->index = index;
|
||||
int i;
|
||||
for (i = 0; i < 17; i++) { // Skip empty bit
|
||||
AddPhysicalControl(PRESSURE_BTN, i + (i > 10), 0);
|
||||
}
|
||||
for (; i < 21; i++) {
|
||||
AddPhysicalControl(ABSAXIS, i + 2, 0);
|
||||
}
|
||||
AddFFAxis(L"Slow Motor", 0);
|
||||
AddFFAxis(L"Fast Motor", 1);
|
||||
AddFFEffectType(L"Constant Effect", L"Constant", EFFECT_CONSTANT);
|
||||
}
|
||||
XInputDevice(int index, wchar_t* displayName)
|
||||
: Device(XINPUT, OTHER, displayName)
|
||||
{
|
||||
memset(ps2Vibration, 0, sizeof(ps2Vibration));
|
||||
memset(&xInputVibration, 0, sizeof(xInputVibration));
|
||||
this->index = index;
|
||||
int i;
|
||||
for (i = 0; i < 17; i++)
|
||||
{ // Skip empty bit
|
||||
AddPhysicalControl(PRESSURE_BTN, i + (i > 10), 0);
|
||||
}
|
||||
for (; i < 21; i++)
|
||||
{
|
||||
AddPhysicalControl(ABSAXIS, i + 2, 0);
|
||||
}
|
||||
AddFFAxis(L"Slow Motor", 0);
|
||||
AddFFAxis(L"Fast Motor", 1);
|
||||
AddFFEffectType(L"Constant Effect", L"Constant", EFFECT_CONSTANT);
|
||||
}
|
||||
|
||||
wchar_t *GetPhysicalControlName(PhysicalControl *c)
|
||||
{
|
||||
const static wchar_t *names[] = {
|
||||
L"D-pad Up",
|
||||
L"D-pad Down",
|
||||
L"D-pad Left",
|
||||
L"D-pad Right",
|
||||
L"Start",
|
||||
L"Back",
|
||||
L"Left Thumb",
|
||||
L"Right Thumb",
|
||||
L"Left Shoulder",
|
||||
L"Right Shoulder",
|
||||
L"Guide",
|
||||
L"A",
|
||||
L"B",
|
||||
L"X",
|
||||
L"Y",
|
||||
L"Left Trigger",
|
||||
L"Right Trigger",
|
||||
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 < 21) {
|
||||
return (wchar_t *)names[i];
|
||||
}
|
||||
return Device::GetPhysicalControlName(c);
|
||||
}
|
||||
wchar_t* GetPhysicalControlName(PhysicalControl* c)
|
||||
{
|
||||
const static wchar_t* names[] = {
|
||||
L"D-pad Up",
|
||||
L"D-pad Down",
|
||||
L"D-pad Left",
|
||||
L"D-pad Right",
|
||||
L"Start",
|
||||
L"Back",
|
||||
L"Left Thumb",
|
||||
L"Right Thumb",
|
||||
L"Left Shoulder",
|
||||
L"Right Shoulder",
|
||||
L"Guide",
|
||||
L"A",
|
||||
L"B",
|
||||
L"X",
|
||||
L"Y",
|
||||
L"Left Trigger",
|
||||
L"Right Trigger",
|
||||
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 < 21)
|
||||
{
|
||||
return (wchar_t*)names[i];
|
||||
}
|
||||
return Device::GetPhysicalControlName(c);
|
||||
}
|
||||
|
||||
int Activate(InitInfo *initInfo)
|
||||
{
|
||||
if (active)
|
||||
Deactivate();
|
||||
if (!xInputActiveCount) {
|
||||
pXInputEnable(1);
|
||||
}
|
||||
xInputActiveCount++;
|
||||
active = 1;
|
||||
AllocState();
|
||||
return 1;
|
||||
}
|
||||
int Activate(InitInfo* initInfo)
|
||||
{
|
||||
if (active)
|
||||
Deactivate();
|
||||
if (!xInputActiveCount)
|
||||
{
|
||||
pXInputEnable(1);
|
||||
}
|
||||
xInputActiveCount++;
|
||||
active = 1;
|
||||
AllocState();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Update()
|
||||
{
|
||||
if (!active)
|
||||
return 0;
|
||||
SCP_EXTN pressure;
|
||||
if (!pXInputGetExtended || (ERROR_SUCCESS != pXInputGetExtended(index, &pressure))) {
|
||||
XINPUT_STATE state;
|
||||
if (ERROR_SUCCESS != pXInputGetStateEx(index, &state)) {
|
||||
Deactivate();
|
||||
return 0;
|
||||
}
|
||||
int Update()
|
||||
{
|
||||
if (!active)
|
||||
return 0;
|
||||
SCP_EXTN pressure;
|
||||
if (!pXInputGetExtended || (ERROR_SUCCESS != pXInputGetExtended(index, &pressure)))
|
||||
{
|
||||
XINPUT_STATE state;
|
||||
if (ERROR_SUCCESS != pXInputGetStateEx(index, &state))
|
||||
{
|
||||
Deactivate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int buttons = state.Gamepad.wButtons;
|
||||
for (int i = 0; i < 15; i++) {
|
||||
physicalControlState[i] = ((buttons >> physicalControls[i].id) & 1) << 16;
|
||||
}
|
||||
physicalControlState[15] = (int)(state.Gamepad.bLeftTrigger * 257.005);
|
||||
physicalControlState[16] = (int)(state.Gamepad.bRightTrigger * 257.005);
|
||||
physicalControlState[17] = ShortToAxis(state.Gamepad.sThumbLX);
|
||||
physicalControlState[18] = ShortToAxis(state.Gamepad.sThumbLY);
|
||||
physicalControlState[19] = ShortToAxis(state.Gamepad.sThumbRX);
|
||||
physicalControlState[20] = ShortToAxis(state.Gamepad.sThumbRY);
|
||||
} else {
|
||||
physicalControlState[0] = (int)(pressure.SCP_UP * FULLY_DOWN);
|
||||
physicalControlState[1] = (int)(pressure.SCP_DOWN * FULLY_DOWN);
|
||||
physicalControlState[2] = (int)(pressure.SCP_LEFT * FULLY_DOWN);
|
||||
physicalControlState[3] = (int)(pressure.SCP_RIGHT * FULLY_DOWN);
|
||||
physicalControlState[4] = (int)(pressure.SCP_START * FULLY_DOWN);
|
||||
physicalControlState[5] = (int)(pressure.SCP_SELECT * FULLY_DOWN);
|
||||
physicalControlState[6] = (int)(pressure.SCP_L3 * FULLY_DOWN);
|
||||
physicalControlState[7] = (int)(pressure.SCP_R3 * FULLY_DOWN);
|
||||
physicalControlState[8] = (int)(pressure.SCP_L1 * FULLY_DOWN);
|
||||
physicalControlState[9] = (int)(pressure.SCP_R1 * FULLY_DOWN);
|
||||
physicalControlState[10] = (int)(pressure.SCP_PS * FULLY_DOWN);
|
||||
physicalControlState[11] = (int)(pressure.SCP_X * FULLY_DOWN);
|
||||
physicalControlState[12] = (int)(pressure.SCP_C * FULLY_DOWN);
|
||||
physicalControlState[13] = (int)(pressure.SCP_S * FULLY_DOWN);
|
||||
physicalControlState[14] = (int)(pressure.SCP_T * FULLY_DOWN);
|
||||
physicalControlState[15] = (int)(pressure.SCP_L2 * FULLY_DOWN);
|
||||
physicalControlState[16] = (int)(pressure.SCP_R2 * FULLY_DOWN);
|
||||
physicalControlState[17] = (int)(pressure.SCP_LX * FULLY_DOWN);
|
||||
physicalControlState[18] = (int)(pressure.SCP_LY * FULLY_DOWN);
|
||||
physicalControlState[19] = (int)(pressure.SCP_RX * FULLY_DOWN);
|
||||
physicalControlState[20] = (int)(pressure.SCP_RY * FULLY_DOWN);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
int buttons = state.Gamepad.wButtons;
|
||||
for (int i = 0; i < 15; i++)
|
||||
{
|
||||
physicalControlState[i] = ((buttons >> physicalControls[i].id) & 1) << 16;
|
||||
}
|
||||
physicalControlState[15] = (int)(state.Gamepad.bLeftTrigger * 257.005);
|
||||
physicalControlState[16] = (int)(state.Gamepad.bRightTrigger * 257.005);
|
||||
physicalControlState[17] = ShortToAxis(state.Gamepad.sThumbLX);
|
||||
physicalControlState[18] = ShortToAxis(state.Gamepad.sThumbLY);
|
||||
physicalControlState[19] = ShortToAxis(state.Gamepad.sThumbRX);
|
||||
physicalControlState[20] = ShortToAxis(state.Gamepad.sThumbRY);
|
||||
}
|
||||
else
|
||||
{
|
||||
physicalControlState[0] = (int)(pressure.SCP_UP * FULLY_DOWN);
|
||||
physicalControlState[1] = (int)(pressure.SCP_DOWN * FULLY_DOWN);
|
||||
physicalControlState[2] = (int)(pressure.SCP_LEFT * FULLY_DOWN);
|
||||
physicalControlState[3] = (int)(pressure.SCP_RIGHT * FULLY_DOWN);
|
||||
physicalControlState[4] = (int)(pressure.SCP_START * FULLY_DOWN);
|
||||
physicalControlState[5] = (int)(pressure.SCP_SELECT * FULLY_DOWN);
|
||||
physicalControlState[6] = (int)(pressure.SCP_L3 * FULLY_DOWN);
|
||||
physicalControlState[7] = (int)(pressure.SCP_R3 * FULLY_DOWN);
|
||||
physicalControlState[8] = (int)(pressure.SCP_L1 * FULLY_DOWN);
|
||||
physicalControlState[9] = (int)(pressure.SCP_R1 * FULLY_DOWN);
|
||||
physicalControlState[10] = (int)(pressure.SCP_PS * FULLY_DOWN);
|
||||
physicalControlState[11] = (int)(pressure.SCP_X * FULLY_DOWN);
|
||||
physicalControlState[12] = (int)(pressure.SCP_C * FULLY_DOWN);
|
||||
physicalControlState[13] = (int)(pressure.SCP_S * FULLY_DOWN);
|
||||
physicalControlState[14] = (int)(pressure.SCP_T * FULLY_DOWN);
|
||||
physicalControlState[15] = (int)(pressure.SCP_L2 * FULLY_DOWN);
|
||||
physicalControlState[16] = (int)(pressure.SCP_R2 * FULLY_DOWN);
|
||||
physicalControlState[17] = (int)(pressure.SCP_LX * FULLY_DOWN);
|
||||
physicalControlState[18] = (int)(pressure.SCP_LY * FULLY_DOWN);
|
||||
physicalControlState[19] = (int)(pressure.SCP_RX * FULLY_DOWN);
|
||||
physicalControlState[20] = (int)(pressure.SCP_RY * FULLY_DOWN);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force)
|
||||
{
|
||||
ps2Vibration[port][slot][motor] = force;
|
||||
int newVibration[2] = {0, 0};
|
||||
for (int p = 0; p < 2; p++) {
|
||||
for (int s = 0; s < 4; s++) {
|
||||
int padtype = config.padConfigs[p][s].type;
|
||||
for (int i = 0; i < pads[p][s][padtype].numFFBindings; i++) {
|
||||
// Technically should also be a *65535/BASE_SENSITIVITY, but that's close enough to 1 for me.
|
||||
ForceFeedbackBinding *ffb = &pads[p][s][padtype].ffBindings[i];
|
||||
newVibration[0] += (int)((ffb->axes[0].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255);
|
||||
newVibration[1] += (int)((ffb->axes[1].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
newVibration[0] = abs(newVibration[0]);
|
||||
if (newVibration[0] > 65535) {
|
||||
newVibration[0] = 65535;
|
||||
}
|
||||
newVibration[1] = abs(newVibration[1]);
|
||||
if (newVibration[1] > 65535) {
|
||||
newVibration[1] = 65535;
|
||||
}
|
||||
if (newVibration[0] || newVibration[1] || newVibration[0] != xInputVibration.wLeftMotorSpeed || newVibration[1] != xInputVibration.wRightMotorSpeed) {
|
||||
XINPUT_VIBRATION newv = {(WORD)newVibration[0], (WORD)newVibration[1]};
|
||||
if (ERROR_SUCCESS == pXInputSetState(index, &newv)) {
|
||||
xInputVibration = newv;
|
||||
}
|
||||
}
|
||||
}
|
||||
void SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force)
|
||||
{
|
||||
ps2Vibration[port][slot][motor] = force;
|
||||
int newVibration[2] = {0, 0};
|
||||
for (int p = 0; p < 2; p++)
|
||||
{
|
||||
for (int s = 0; s < 4; s++)
|
||||
{
|
||||
int padtype = config.padConfigs[p][s].type;
|
||||
for (int i = 0; i < pads[p][s][padtype].numFFBindings; i++)
|
||||
{
|
||||
// Technically should also be a *65535/BASE_SENSITIVITY, but that's close enough to 1 for me.
|
||||
ForceFeedbackBinding* ffb = &pads[p][s][padtype].ffBindings[i];
|
||||
newVibration[0] += (int)((ffb->axes[0].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255);
|
||||
newVibration[1] += (int)((ffb->axes[1].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
newVibration[0] = abs(newVibration[0]);
|
||||
if (newVibration[0] > 65535)
|
||||
{
|
||||
newVibration[0] = 65535;
|
||||
}
|
||||
newVibration[1] = abs(newVibration[1]);
|
||||
if (newVibration[1] > 65535)
|
||||
{
|
||||
newVibration[1] = 65535;
|
||||
}
|
||||
if (newVibration[0] || newVibration[1] || newVibration[0] != xInputVibration.wLeftMotorSpeed || newVibration[1] != xInputVibration.wRightMotorSpeed)
|
||||
{
|
||||
XINPUT_VIBRATION newv = {(WORD)newVibration[0], (WORD)newVibration[1]};
|
||||
if (ERROR_SUCCESS == pXInputSetState(index, &newv))
|
||||
{
|
||||
xInputVibration = newv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetEffect(ForceFeedbackBinding *binding, unsigned char force)
|
||||
{
|
||||
PadBindings pBackup = pads[0][0][0];
|
||||
pads[0][0][0].ffBindings = binding;
|
||||
pads[0][0][0].numFFBindings = 1;
|
||||
SetEffects(0, 0, binding->motor, 255);
|
||||
pads[0][0][0] = pBackup;
|
||||
}
|
||||
void SetEffect(ForceFeedbackBinding* binding, unsigned char force)
|
||||
{
|
||||
PadBindings pBackup = pads[0][0][0];
|
||||
pads[0][0][0].ffBindings = binding;
|
||||
pads[0][0][0].numFFBindings = 1;
|
||||
SetEffects(0, 0, binding->motor, 255);
|
||||
pads[0][0][0] = pBackup;
|
||||
}
|
||||
|
||||
void Deactivate()
|
||||
{
|
||||
memset(&xInputVibration, 0, sizeof(xInputVibration));
|
||||
memset(ps2Vibration, 0, sizeof(ps2Vibration));
|
||||
pXInputSetState(index, &xInputVibration);
|
||||
void Deactivate()
|
||||
{
|
||||
memset(&xInputVibration, 0, sizeof(xInputVibration));
|
||||
memset(ps2Vibration, 0, sizeof(ps2Vibration));
|
||||
pXInputSetState(index, &xInputVibration);
|
||||
|
||||
FreeState();
|
||||
if (active) {
|
||||
if (!--xInputActiveCount) {
|
||||
pXInputEnable(0);
|
||||
}
|
||||
active = 0;
|
||||
}
|
||||
}
|
||||
FreeState();
|
||||
if (active)
|
||||
{
|
||||
if (!--xInputActiveCount)
|
||||
{
|
||||
pXInputEnable(0);
|
||||
}
|
||||
active = 0;
|
||||
}
|
||||
}
|
||||
|
||||
~XInputDevice()
|
||||
{
|
||||
}
|
||||
~XInputDevice()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
void EnumXInputDevices()
|
||||
{
|
||||
wchar_t temp[30];
|
||||
if (!pXInputSetState) {
|
||||
// XInput not installed, so don't repeatedly try to load it.
|
||||
if (xinputNotInstalled)
|
||||
return;
|
||||
wchar_t temp[30];
|
||||
if (!pXInputSetState)
|
||||
{
|
||||
// XInput not installed, so don't repeatedly try to load it.
|
||||
if (xinputNotInstalled)
|
||||
return;
|
||||
|
||||
// Prefer XInput 1.3 since SCP only has an XInput 1.3 wrapper right now.
|
||||
// Also use LoadLibrary and not LoadLibraryEx for XInput 1.3, since some
|
||||
// Windows 7 systems have issues with it.
|
||||
// FIXME: Missing FreeLibrary call.
|
||||
HMODULE hMod = LoadLibrary(L"xinput1_3.dll");
|
||||
if (hMod == nullptr && IsWindows8OrGreater()) {
|
||||
hMod = LoadLibraryEx(L"XInput1_4.dll", nullptr, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
}
|
||||
// Prefer XInput 1.3 since SCP only has an XInput 1.3 wrapper right now.
|
||||
// Also use LoadLibrary and not LoadLibraryEx for XInput 1.3, since some
|
||||
// Windows 7 systems have issues with it.
|
||||
// FIXME: Missing FreeLibrary call.
|
||||
HMODULE hMod = LoadLibrary(L"xinput1_3.dll");
|
||||
if (hMod == nullptr && IsWindows8OrGreater())
|
||||
{
|
||||
hMod = LoadLibraryEx(L"XInput1_4.dll", nullptr, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
}
|
||||
|
||||
if (hMod) {
|
||||
if ((pXInputEnable = (_XInputEnable)GetProcAddress(hMod, "XInputEnable")) &&
|
||||
((pXInputGetStateEx = (_XInputGetStateEx)GetProcAddress(hMod, (LPCSTR)100)) || // Try Ex version first
|
||||
(pXInputGetStateEx = (_XInputGetStateEx)GetProcAddress(hMod, "XInputGetState")))) {
|
||||
pXInputGetExtended = (_XInputGetExtended)GetProcAddress(hMod, "XInputGetExtended");
|
||||
pXInputSetState = (_XInputSetState)GetProcAddress(hMod, "XInputSetState");
|
||||
}
|
||||
}
|
||||
if (!pXInputSetState) {
|
||||
xinputNotInstalled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
pXInputEnable(1);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
wsprintfW(temp, L"XInput Pad %i", i);
|
||||
dm->AddDevice(new XInputDevice(i, temp));
|
||||
}
|
||||
pXInputEnable(0);
|
||||
if (hMod)
|
||||
{
|
||||
if ((pXInputEnable = (_XInputEnable)GetProcAddress(hMod, "XInputEnable")) &&
|
||||
((pXInputGetStateEx = (_XInputGetStateEx)GetProcAddress(hMod, (LPCSTR)100)) || // Try Ex version first
|
||||
(pXInputGetStateEx = (_XInputGetStateEx)GetProcAddress(hMod, "XInputGetState"))))
|
||||
{
|
||||
pXInputGetExtended = (_XInputGetExtended)GetProcAddress(hMod, "XInputGetExtended");
|
||||
pXInputSetState = (_XInputSetState)GetProcAddress(hMod, "XInputSetState");
|
||||
}
|
||||
}
|
||||
if (!pXInputSetState)
|
||||
{
|
||||
xinputNotInstalled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
pXInputEnable(1);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
wsprintfW(temp, L"XInput Pad %i", i);
|
||||
dm->AddDevice(new XInputDevice(i, temp));
|
||||
}
|
||||
pXInputEnable(0);
|
||||
}
|
||||
|
|
|
@ -2,155 +2,155 @@
|
|||
// fichier Include Microsoft Visual C++.
|
||||
// Utilis<69> par PAD.rc
|
||||
//
|
||||
#define IDD_GENERAL 0x366
|
||||
#define IDD_CONFIG 0x369
|
||||
#define IDD_CONFIG_GUITAR 0x36A
|
||||
#define IDD_PROPPAGE_LARGE 0x36B
|
||||
#define IDC_CURSOR1 0x36C
|
||||
#define IDD_DIAG 0x36D
|
||||
#define IDR_INI1 0x36E
|
||||
#define IDD_CONFIG_POPN 0x36F
|
||||
#define IDD_CONFIG_PS1_MOUSE 0x370
|
||||
#define IDD_CONFIG_NEGCON 0x371
|
||||
#define IDC_KB_DISABLE 0x344C
|
||||
#define IDC_KB_DI 0x344D
|
||||
#define IDC_KB_WM 0x344E
|
||||
#define IDC_KB_RAW 0x344F
|
||||
#define IDC_DISABLE_PAD1 0x3450
|
||||
#define IDC_M_DISABLE 0x3451
|
||||
#define IDC_M_DI 0x3452
|
||||
#define IDC_M_WM 0x3453
|
||||
#define IDC_M_RAW 0x3454
|
||||
#define IDC_G_XI 0x3455
|
||||
#define IDC_G_DI 0x3456
|
||||
#define IDC_G_DS3 0x3457
|
||||
#define IDC_DEBUG_FILE 0x3458
|
||||
#define IDC_GUITAR1 0x3459
|
||||
#define IDC_MULTITAP1 0x345A
|
||||
#define IDC_MOUSE_UNFOCUS 0x345B
|
||||
#define IDC_AXIS_BUTTONS 0x345C
|
||||
#define IDC_MULTITAP2 0x345D
|
||||
#define IDC_BACKGROUND 0x345E
|
||||
#define IDC_MULTIPLE_BINDING 0x345F
|
||||
#define IDC_FORCE_HIDE 0x3460
|
||||
#define IDC_GH2_HACK 0x3461
|
||||
#define IDC_PAD_LIST 0x3462
|
||||
#define IDC_COMBO1 0x3463
|
||||
#define IDC_PAD_TYPE 0x3464
|
||||
#define IDC_DIAG_LIST 0x3465
|
||||
#define ID_SAVE 0x3466
|
||||
#define ID_LOAD 0x3467
|
||||
#define ID_RESTORE_DEFAULTS 0x3468
|
||||
#define IDC_BINDINGS_LIST 0x3F00
|
||||
#define IDC_SLIDER_SENSITIVITY 0x4000
|
||||
#define IDC_FLIP 0x4001
|
||||
#define IDC_AXIS_DIRECTION 0x4002
|
||||
#define IDC_AXIS_CONTROL 0x4003
|
||||
#define IDC_AXIS_SENSITIVITY 0x4004
|
||||
#define IDC_RAPID_FIRE 0x4005
|
||||
#define IDC_AXIS_DEVICE 0x4006
|
||||
#define ID_SENSITIVITY 0x4007
|
||||
#define IDC_SLIDER_DEADZONE 0x4008
|
||||
#define IDC_AXIS_DEADZONE 0x4009
|
||||
#define IDC_LABEL_SENSITIVITY 0x400A
|
||||
#define IDC_LABEL_DEADZONE 0x400B
|
||||
#define IDC_LABEL_SKIP_DEADZONE 0x400C
|
||||
#define IDC_SKIP_DEADZONE_OFF 0x400D
|
||||
#define IDC_SLIDER_SKIP_DEADZONE 0x400E
|
||||
#define IDC_AXIS_SKIP_DEADZONE 0x400F
|
||||
#define IDC_DPAD 0x40D0
|
||||
#define IDC_LSTICK 0x40D1
|
||||
#define IDC_RSTICK 0x40D2
|
||||
#define IDC_FACE 0x40D3
|
||||
#define IDC_SHOULDER 0x40D4
|
||||
#define IDC_FACE_ANALOG 0x40D5
|
||||
#define ID_MOUSE 0x40FF
|
||||
#define ID_SELECT 0x4100
|
||||
#define ID_L3 0x4101
|
||||
#define ID_R3 0x4102
|
||||
#define ID_START 0x4103
|
||||
#define ID_DPAD_UP 0x4104
|
||||
#define ID_DPAD_RIGHT 0x4105
|
||||
#define ID_DPAD_DOWN 0x4106
|
||||
#define ID_DPAD_LEFT 0x4107
|
||||
#define ID_L2 0x4108
|
||||
#define ID_R2 0x4109
|
||||
#define ID_L1 0x410A
|
||||
#define ID_R1 0x410B
|
||||
#define ID_TRIANGLE 0x410C
|
||||
#define ID_CIRCLE 0x410D
|
||||
#define ID_CROSS 0x410E
|
||||
#define ID_SQUARE 0x410F
|
||||
#define ID_LSTICK_UP 0x4110
|
||||
#define ID_LSTICK_RIGHT 0x4111
|
||||
#define ID_LSTICK_DOWN 0x4112
|
||||
#define ID_LSTICK_LEFT 0x4113
|
||||
#define ID_RSTICK_UP 0x4114
|
||||
#define ID_RSTICK_RIGHT 0x4115
|
||||
#define ID_RSTICK_DOWN 0x4116
|
||||
#define ID_RSTICK_LEFT 0x4117
|
||||
#define ID_ANALOG 0x4118
|
||||
#define ID_EXCLUDE 0x4119
|
||||
#define ID_LOCK_BUTTONS 0x411A
|
||||
#define ID_LOCK_ALL_INPUT 0x411B
|
||||
#define ID_LOCK_DIRECTION 0x411C
|
||||
#define ID_TURBO_KEY 0x411D
|
||||
#define ID_QUICK_SETUP 0x411E
|
||||
#define IDC_QUICK_SETUP_TEXT 0x411F
|
||||
#define IDC_FORCEFEEDBACK 0x4200
|
||||
#define IDC_FORCEFEEDBACK_FUNCTION 0x4201
|
||||
#define ID_BIG_MOTOR 0x4202
|
||||
#define ID_SMALL_MOTOR 0x4203
|
||||
#define ID_FORCEFEEDBACK_BOX 0x4204
|
||||
#define IDC_CONFIGURE_ON_BIND 0x4230
|
||||
#define IDC_DEVICE_SELECT 0x4231
|
||||
#define ID_CLEAR 0x4232
|
||||
#define ID_SPECIAL_INPUTS 0x4233
|
||||
#define ID_TEST 0x4300
|
||||
#define ID_FF 0x4301
|
||||
#define IDC_FF_EFFECT 0x4302
|
||||
#define IDC_FF_AXIS1_ENABLED 0x4310
|
||||
#define IDC_FF_AXIS1 0x4311
|
||||
#define IDC_FF_AXIS1_FLIP 0x4312
|
||||
#define IDC_FF_AXIS1_SCALE 0x4313
|
||||
#define IDC_FF_AXIS2_ENABLED 0x4320
|
||||
#define IDC_FF_AXIS2 0x4321
|
||||
#define IDC_FF_AXIS2_FLIP 0x4322
|
||||
#define IDC_FF_AXIS2_SCALE 0x4323
|
||||
#define IDC_FF_AXIS3_ENABLED 0x4330
|
||||
#define IDC_FF_AXIS3 0x4331
|
||||
#define IDC_FF_AXIS3_FLIP 0x4332
|
||||
#define IDC_FF_AXIS3_SCALE 0x4333
|
||||
#define IDC_FF_AXIS4_ENABLED 0x4340
|
||||
#define IDC_FF_AXIS4 0x4341
|
||||
#define IDC_FF_AXIS4_FLIP 0x4342
|
||||
#define IDC_FF_AXIS4_SCALE 0x4343
|
||||
#define IDC_FF_AXIS5_ENABLED 0x4350
|
||||
#define IDC_FF_AXIS5 0x4351
|
||||
#define IDC_FF_AXIS5_FLIP 0x4352
|
||||
#define IDC_FF_AXIS5_SCALE 0x4353
|
||||
#define IDC_FF_AXIS6_ENABLED 0x4360
|
||||
#define IDC_FF_AXIS6 0x4361
|
||||
#define IDC_FF_AXIS6_FLIP 0x4362
|
||||
#define IDC_FF_AXIS6_SCALE 0x4363
|
||||
#define IDC_FF_AXIS7_ENABLED 0x4370
|
||||
#define IDC_FF_AXIS7 0x4371
|
||||
#define IDC_FF_AXIS7_FLIP 0x4372
|
||||
#define IDC_FF_AXIS7_SCALE 0x4373
|
||||
#define IDC_FF_AXIS8_ENABLED 0x4380
|
||||
#define IDC_FF_AXIS8 0x4381
|
||||
#define IDC_FF_AXIS8_FLIP 0x4382
|
||||
#define IDC_FF_AXIS8_SCALE 0x4383
|
||||
#define ID_CONTROLS 0x4390
|
||||
#define ID_RESET_CONFIG 0x4391
|
||||
#define IDD_GENERAL 0x366
|
||||
#define IDD_CONFIG 0x369
|
||||
#define IDD_CONFIG_GUITAR 0x36A
|
||||
#define IDD_PROPPAGE_LARGE 0x36B
|
||||
#define IDC_CURSOR1 0x36C
|
||||
#define IDD_DIAG 0x36D
|
||||
#define IDR_INI1 0x36E
|
||||
#define IDD_CONFIG_POPN 0x36F
|
||||
#define IDD_CONFIG_PS1_MOUSE 0x370
|
||||
#define IDD_CONFIG_NEGCON 0x371
|
||||
#define IDC_KB_DISABLE 0x344C
|
||||
#define IDC_KB_DI 0x344D
|
||||
#define IDC_KB_WM 0x344E
|
||||
#define IDC_KB_RAW 0x344F
|
||||
#define IDC_DISABLE_PAD1 0x3450
|
||||
#define IDC_M_DISABLE 0x3451
|
||||
#define IDC_M_DI 0x3452
|
||||
#define IDC_M_WM 0x3453
|
||||
#define IDC_M_RAW 0x3454
|
||||
#define IDC_G_XI 0x3455
|
||||
#define IDC_G_DI 0x3456
|
||||
#define IDC_G_DS3 0x3457
|
||||
#define IDC_DEBUG_FILE 0x3458
|
||||
#define IDC_GUITAR1 0x3459
|
||||
#define IDC_MULTITAP1 0x345A
|
||||
#define IDC_MOUSE_UNFOCUS 0x345B
|
||||
#define IDC_AXIS_BUTTONS 0x345C
|
||||
#define IDC_MULTITAP2 0x345D
|
||||
#define IDC_BACKGROUND 0x345E
|
||||
#define IDC_MULTIPLE_BINDING 0x345F
|
||||
#define IDC_FORCE_HIDE 0x3460
|
||||
#define IDC_GH2_HACK 0x3461
|
||||
#define IDC_PAD_LIST 0x3462
|
||||
#define IDC_COMBO1 0x3463
|
||||
#define IDC_PAD_TYPE 0x3464
|
||||
#define IDC_DIAG_LIST 0x3465
|
||||
#define ID_SAVE 0x3466
|
||||
#define ID_LOAD 0x3467
|
||||
#define ID_RESTORE_DEFAULTS 0x3468
|
||||
#define IDC_BINDINGS_LIST 0x3F00
|
||||
#define IDC_SLIDER_SENSITIVITY 0x4000
|
||||
#define IDC_FLIP 0x4001
|
||||
#define IDC_AXIS_DIRECTION 0x4002
|
||||
#define IDC_AXIS_CONTROL 0x4003
|
||||
#define IDC_AXIS_SENSITIVITY 0x4004
|
||||
#define IDC_RAPID_FIRE 0x4005
|
||||
#define IDC_AXIS_DEVICE 0x4006
|
||||
#define ID_SENSITIVITY 0x4007
|
||||
#define IDC_SLIDER_DEADZONE 0x4008
|
||||
#define IDC_AXIS_DEADZONE 0x4009
|
||||
#define IDC_LABEL_SENSITIVITY 0x400A
|
||||
#define IDC_LABEL_DEADZONE 0x400B
|
||||
#define IDC_LABEL_SKIP_DEADZONE 0x400C
|
||||
#define IDC_SKIP_DEADZONE_OFF 0x400D
|
||||
#define IDC_SLIDER_SKIP_DEADZONE 0x400E
|
||||
#define IDC_AXIS_SKIP_DEADZONE 0x400F
|
||||
#define IDC_DPAD 0x40D0
|
||||
#define IDC_LSTICK 0x40D1
|
||||
#define IDC_RSTICK 0x40D2
|
||||
#define IDC_FACE 0x40D3
|
||||
#define IDC_SHOULDER 0x40D4
|
||||
#define IDC_FACE_ANALOG 0x40D5
|
||||
#define ID_MOUSE 0x40FF
|
||||
#define ID_SELECT 0x4100
|
||||
#define ID_L3 0x4101
|
||||
#define ID_R3 0x4102
|
||||
#define ID_START 0x4103
|
||||
#define ID_DPAD_UP 0x4104
|
||||
#define ID_DPAD_RIGHT 0x4105
|
||||
#define ID_DPAD_DOWN 0x4106
|
||||
#define ID_DPAD_LEFT 0x4107
|
||||
#define ID_L2 0x4108
|
||||
#define ID_R2 0x4109
|
||||
#define ID_L1 0x410A
|
||||
#define ID_R1 0x410B
|
||||
#define ID_TRIANGLE 0x410C
|
||||
#define ID_CIRCLE 0x410D
|
||||
#define ID_CROSS 0x410E
|
||||
#define ID_SQUARE 0x410F
|
||||
#define ID_LSTICK_UP 0x4110
|
||||
#define ID_LSTICK_RIGHT 0x4111
|
||||
#define ID_LSTICK_DOWN 0x4112
|
||||
#define ID_LSTICK_LEFT 0x4113
|
||||
#define ID_RSTICK_UP 0x4114
|
||||
#define ID_RSTICK_RIGHT 0x4115
|
||||
#define ID_RSTICK_DOWN 0x4116
|
||||
#define ID_RSTICK_LEFT 0x4117
|
||||
#define ID_ANALOG 0x4118
|
||||
#define ID_EXCLUDE 0x4119
|
||||
#define ID_LOCK_BUTTONS 0x411A
|
||||
#define ID_LOCK_ALL_INPUT 0x411B
|
||||
#define ID_LOCK_DIRECTION 0x411C
|
||||
#define ID_TURBO_KEY 0x411D
|
||||
#define ID_QUICK_SETUP 0x411E
|
||||
#define IDC_QUICK_SETUP_TEXT 0x411F
|
||||
#define IDC_FORCEFEEDBACK 0x4200
|
||||
#define IDC_FORCEFEEDBACK_FUNCTION 0x4201
|
||||
#define ID_BIG_MOTOR 0x4202
|
||||
#define ID_SMALL_MOTOR 0x4203
|
||||
#define ID_FORCEFEEDBACK_BOX 0x4204
|
||||
#define IDC_CONFIGURE_ON_BIND 0x4230
|
||||
#define IDC_DEVICE_SELECT 0x4231
|
||||
#define ID_CLEAR 0x4232
|
||||
#define ID_SPECIAL_INPUTS 0x4233
|
||||
#define ID_TEST 0x4300
|
||||
#define ID_FF 0x4301
|
||||
#define IDC_FF_EFFECT 0x4302
|
||||
#define IDC_FF_AXIS1_ENABLED 0x4310
|
||||
#define IDC_FF_AXIS1 0x4311
|
||||
#define IDC_FF_AXIS1_FLIP 0x4312
|
||||
#define IDC_FF_AXIS1_SCALE 0x4313
|
||||
#define IDC_FF_AXIS2_ENABLED 0x4320
|
||||
#define IDC_FF_AXIS2 0x4321
|
||||
#define IDC_FF_AXIS2_FLIP 0x4322
|
||||
#define IDC_FF_AXIS2_SCALE 0x4323
|
||||
#define IDC_FF_AXIS3_ENABLED 0x4330
|
||||
#define IDC_FF_AXIS3 0x4331
|
||||
#define IDC_FF_AXIS3_FLIP 0x4332
|
||||
#define IDC_FF_AXIS3_SCALE 0x4333
|
||||
#define IDC_FF_AXIS4_ENABLED 0x4340
|
||||
#define IDC_FF_AXIS4 0x4341
|
||||
#define IDC_FF_AXIS4_FLIP 0x4342
|
||||
#define IDC_FF_AXIS4_SCALE 0x4343
|
||||
#define IDC_FF_AXIS5_ENABLED 0x4350
|
||||
#define IDC_FF_AXIS5 0x4351
|
||||
#define IDC_FF_AXIS5_FLIP 0x4352
|
||||
#define IDC_FF_AXIS5_SCALE 0x4353
|
||||
#define IDC_FF_AXIS6_ENABLED 0x4360
|
||||
#define IDC_FF_AXIS6 0x4361
|
||||
#define IDC_FF_AXIS6_FLIP 0x4362
|
||||
#define IDC_FF_AXIS6_SCALE 0x4363
|
||||
#define IDC_FF_AXIS7_ENABLED 0x4370
|
||||
#define IDC_FF_AXIS7 0x4371
|
||||
#define IDC_FF_AXIS7_FLIP 0x4372
|
||||
#define IDC_FF_AXIS7_SCALE 0x4373
|
||||
#define IDC_FF_AXIS8_ENABLED 0x4380
|
||||
#define IDC_FF_AXIS8 0x4381
|
||||
#define IDC_FF_AXIS8_FLIP 0x4382
|
||||
#define IDC_FF_AXIS8_SCALE 0x4383
|
||||
#define ID_CONTROLS 0x4390
|
||||
#define ID_RESET_CONFIG 0x4391
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 116
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 5010
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#define _APS_NEXT_RESOURCE_VALUE 116
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 5010
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -85,43 +85,43 @@
|
|||
/* All standard descriptors have these 2 fields in common */
|
||||
struct usb_descriptor_header
|
||||
{
|
||||
unsigned char bLength;
|
||||
unsigned char bDescriptorType;
|
||||
unsigned char bLength;
|
||||
unsigned char bDescriptorType;
|
||||
};
|
||||
|
||||
/* String descriptor */
|
||||
struct usb_string_descriptor
|
||||
{
|
||||
unsigned char bLength;
|
||||
unsigned char bDescriptorType;
|
||||
unsigned short wData[1];
|
||||
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;
|
||||
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 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;
|
||||
unsigned char* extra; /* Extra descriptors */
|
||||
int extralen;
|
||||
};
|
||||
|
||||
#define USB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */
|
||||
|
@ -137,76 +137,76 @@ struct usb_endpoint_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;
|
||||
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;
|
||||
struct usb_endpoint_descriptor* endpoint;
|
||||
|
||||
unsigned char *extra; /* Extra descriptors */
|
||||
int extralen;
|
||||
unsigned char* extra; /* Extra descriptors */
|
||||
int extralen;
|
||||
};
|
||||
|
||||
#define USB_MAXALTSETTING 128 /* Hard limit */
|
||||
|
||||
struct usb_interface
|
||||
{
|
||||
struct usb_interface_descriptor *altsetting;
|
||||
struct usb_interface_descriptor* altsetting;
|
||||
|
||||
int num_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;
|
||||
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;
|
||||
struct usb_interface* interface;
|
||||
|
||||
unsigned char *extra; /* Extra descriptors */
|
||||
int extralen;
|
||||
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;
|
||||
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;
|
||||
unsigned char bRequestType;
|
||||
unsigned char bRequest;
|
||||
unsigned short wValue;
|
||||
unsigned short wIndex;
|
||||
unsigned short wLength;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -258,52 +258,52 @@ struct usb_ctrl_setup
|
|||
|
||||
struct usb_device
|
||||
{
|
||||
struct usb_device *next, *prev;
|
||||
struct usb_device *next, *prev;
|
||||
|
||||
char filename[LIBUSB_PATH_MAX];
|
||||
char filename[LIBUSB_PATH_MAX];
|
||||
|
||||
struct usb_bus *bus;
|
||||
struct usb_bus* bus;
|
||||
|
||||
struct usb_device_descriptor descriptor;
|
||||
struct usb_config_descriptor *config;
|
||||
struct usb_device_descriptor descriptor;
|
||||
struct usb_config_descriptor* config;
|
||||
|
||||
void *dev; /* Darwin support */
|
||||
void* dev; /* Darwin support */
|
||||
|
||||
unsigned char devnum;
|
||||
unsigned char devnum;
|
||||
|
||||
unsigned char num_children;
|
||||
struct usb_device **children;
|
||||
unsigned char num_children;
|
||||
struct usb_device** children;
|
||||
};
|
||||
|
||||
struct usb_bus
|
||||
{
|
||||
struct usb_bus *next, *prev;
|
||||
struct usb_bus *next, *prev;
|
||||
|
||||
char dirname[LIBUSB_PATH_MAX];
|
||||
char dirname[LIBUSB_PATH_MAX];
|
||||
|
||||
struct usb_device *devices;
|
||||
unsigned long location;
|
||||
struct usb_device* devices;
|
||||
unsigned long location;
|
||||
|
||||
struct usb_device *root_dev;
|
||||
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
|
||||
{
|
||||
int major;
|
||||
int minor;
|
||||
int micro;
|
||||
int nano;
|
||||
} dll;
|
||||
struct
|
||||
{
|
||||
int major;
|
||||
int minor;
|
||||
int micro;
|
||||
int nano;
|
||||
} driver;
|
||||
};
|
||||
|
||||
|
||||
|
@ -327,48 +327,48 @@ extern "C" {
|
|||
/* 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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
struct usb_device* usb_device(usb_dev_handle* dev);
|
||||
struct usb_bus* usb_get_busses(void);
|
||||
|
||||
|
||||
/* Windows specific functions */
|
||||
|
@ -376,40 +376,40 @@ struct usb_bus *usb_get_busses(void);
|
|||
#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);
|
||||
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);
|
||||
LPSTR cmd_line, int cmd_show);
|
||||
|
||||
#define LIBUSB_HAS_INSTALL_DRIVER_NP 1
|
||||
int usb_install_driver_np(const char *inf_file);
|
||||
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);
|
||||
LPSTR cmd_line, int cmd_show);
|
||||
|
||||
#define LIBUSB_HAS_TOUCH_INF_FILE_NP 1
|
||||
int usb_touch_inf_file_np(const char *inf_file);
|
||||
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);
|
||||
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);
|
||||
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_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);
|
||||
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
|
||||
|
|
|
@ -950,9 +950,6 @@
|
|||
<ItemGroup>
|
||||
<Manifest Include="..\PCSX2.manifest" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="..\..\PAD\Windows\frog.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
</Project>
|
|
@ -2185,9 +2185,4 @@
|
|||
<Filter>AppHost\Resources</Filter>
|
||||
</Manifest>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="..\..\PAD\Windows\frog.ico">
|
||||
<Filter>System\Ps2\PAD</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue